Compare commits
138 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 33cdcb0e82 | |||
| ec870a5aeb | |||
| 0653bb5a72 | |||
| 43b6ff29e3 | |||
| a444a8a704 | |||
| 3fa18c1799 | |||
| 19147963b9 | |||
| 5056215a1f | |||
| 340b7614e2 | |||
| 8a1bd67a20 | |||
| a094df7b55 | |||
| cc893dfc11 | |||
| 8ef17da082 | |||
| 7993e619cd | |||
| 1ab8d5fb3f | |||
| 213ac3ac73 | |||
| 0a8876443a | |||
| f37a3bb9bb | |||
| 2632342f44 | |||
| 8efcf6f099 | |||
| 58343fc78d | |||
| 6c41a4c9c8 | |||
| 334be287fc | |||
| aa050e0001 | |||
| cc994326a0 | |||
| 58de07629e | |||
| 9f830e0c41 | |||
| c52d302f07 | |||
| 44049ecf30 | |||
| e1b5904196 | |||
| 88e692791a | |||
| f00667ad7d | |||
| 696d0eec64 | |||
| 513b00a30e | |||
| 0cb0dbf6d8 | |||
| 9f00515da4 | |||
| 72f31787f6 | |||
| cd686cb1d9 | |||
| d9657e9831 | |||
| 72f3e9b25a | |||
| 811b15a5b3 | |||
| ab00825f37 | |||
| e86d9179aa | |||
| 26d8e9c4c5 | |||
| 5f3ebc8a7f | |||
| 425b1b44bc | |||
| 39442e6282 | |||
| 99575e1010 | |||
| 64aa7540e2 | |||
| 3ff5dbd179 | |||
| e25d04fb12 | |||
| dd1d5a92d2 | |||
| c6e0aad40b | |||
| 99b795ceaa | |||
| 33dc60df26 | |||
| 619aeb54ff | |||
| 77ba43328b | |||
| 01a30752c7 | |||
| e56b748435 | |||
| bb4cbdff44 | |||
| 0b47e474a7 | |||
| 8e85680eb4 | |||
| fefce0d5c4 | |||
| 0ac3cb2329 | |||
| 708ab1dcd7 | |||
| 9b87ddb621 | |||
| 5dc4eb4b03 | |||
| a203c72281 | |||
| 6cf85cee6e | |||
| 1eb6a40fdd | |||
| 1bed77e4d3 | |||
| f2a68023fa | |||
| 8ccffc40e3 | |||
| dd8c1d0441 | |||
| f9f28ff176 | |||
| 3649041195 | |||
| c23c7a9379 | |||
| 9934e33b99 | |||
| 9e75fdda66 | |||
| d873a26f41 | |||
| 91aa5b55ab | |||
| 3f460a76ce | |||
| 7256ea3b32 | |||
| 4cdf77e16f | |||
| d89813e911 | |||
| 7c57b10cae | |||
| 8d1a98e03b | |||
| 65a2da4b40 | |||
| 02f6786b2a | |||
| 9da4f7a6dc | |||
| 510505a85c | |||
| 741cb3a136 | |||
| 9f5d67e27c | |||
| 93c6496ba8 | |||
| 779b648c5f | |||
| 9d5e06232d | |||
| b221c44466 | |||
| 665296f7cf | |||
| 39778d5f47 | |||
| 0af9bbb623 | |||
| fdec47a83d | |||
| 7ff913bbd2 | |||
| 94775bef9f | |||
| 3cf102334f | |||
| 627e733a30 | |||
| d31b80da5b | |||
| eb231b65f3 | |||
| 59e3b1f98d | |||
| 8b174bb272 | |||
| 4199a44bef | |||
| 777392c0fe | |||
| ede1fec5e7 | |||
| 16de3e78a5 | |||
| d7508d8c09 | |||
| 2a136c1c1d | |||
| 2578102be9 | |||
| dadee7acfb | |||
| 28f0bb4e11 | |||
| 824c8a8efb | |||
| 37f27a1262 | |||
| 2b8a7a492a | |||
| db56bbb11b | |||
| 82d26f04a4 | |||
| 5045f7eb42 | |||
| 82a6ccac4d | |||
| 2d74298001 | |||
| ce21254ed2 | |||
| 874250fe49 | |||
| c8a3acbba8 | |||
| 81e11987a2 | |||
| 668cefec2f | |||
| 212bc04257 | |||
| db401fd05e | |||
| bebe72481c | |||
| 2b9e83256d | |||
| 5763518cce | |||
| 3e4c5bab72 | |||
| bce109ab54 |
+34
-18
@@ -1,28 +1,44 @@
|
|||||||
# "Gofmt's style is nobody's favourite, but gofmt is everybody's favourite." --Rob Pike
|
# "Gofmt's style is nobody's favourite, but gofmt is everybody's favourite." --Rob Pike
|
||||||
#
|
#
|
||||||
# for clang-format-10.0.1 from https://github.com/upx/upx-stubtools/releases
|
# for clang-format-15.0.6 from https://github.com/upx/upx-stubtools/releases
|
||||||
---
|
---
|
||||||
BasedOnStyle: LLVM
|
BasedOnStyle: LLVM
|
||||||
AccessModifierOffset: -4
|
|
||||||
#AlignConsecutiveAssignments: true
|
|
||||||
AlwaysBreakTemplateDeclarations: true
|
|
||||||
ColumnLimit: 100
|
ColumnLimit: 100
|
||||||
IndentWidth: 4
|
IndentWidth: 4
|
||||||
|
---
|
||||||
|
Language: Cpp
|
||||||
|
AccessModifierOffset: -4
|
||||||
|
AlwaysBreakTemplateDeclarations: true
|
||||||
|
AttributeMacros:
|
||||||
|
- __acc_cdecl
|
||||||
|
- __acc_cdecl_atexit
|
||||||
|
- __acc_cdecl_qsort
|
||||||
|
- __acc_cdecl_sighandler
|
||||||
|
- __acc_forceinline
|
||||||
|
- __acc_noinline
|
||||||
|
- __acc_static_noinline
|
||||||
|
- __acc_static_forceinline
|
||||||
|
- forceinline
|
||||||
|
- noinline
|
||||||
|
EmptyLineBeforeAccessModifier: Leave
|
||||||
SortIncludes: false
|
SortIncludes: false
|
||||||
SpaceAfterCStyleCast: true
|
SpaceAfterCStyleCast: true
|
||||||
Standard: Cpp03
|
Standard: Cpp03
|
||||||
StatementMacros: [
|
StatementMacros:
|
||||||
ACCCHK_ASSERT,
|
- ACCCHK_ASSERT
|
||||||
ACCCHK_ASSERT_IS_SIGNED_T,
|
- ACCCHK_ASSERT_IS_SIGNED_T
|
||||||
ACCCHK_ASSERT_IS_UNSIGNED_T,
|
- ACCCHK_ASSERT_IS_UNSIGNED_T
|
||||||
ACCCHK_ASSERT_SIGN_T,
|
- ACCCHK_ASSERT_SIGN_T
|
||||||
ACC_COMPILE_TIME_ASSERT,
|
- ACC_BLOCK_BEGIN
|
||||||
ACC_COMPILE_TIME_ASSERT_HEADER,
|
- ACC_COMPILE_TIME_ASSERT
|
||||||
ACC_CXX_DISABLE_NEW_DELETE,
|
- ACC_COMPILE_TIME_ASSERT_HEADER
|
||||||
ACC_CXX_TRIGGER_FUNCTION,
|
- ACC_CXX_DISABLE_NEW_DELETE
|
||||||
ACC_CXX_TRIGGER_FUNCTION_IMPL,
|
- ACC_CXX_TRIGGER_FUNCTION
|
||||||
CLANG_FORMAT_DUMMY_STATEMENT,
|
- ACC_CXX_TRIGGER_FUNCTION_IMPL
|
||||||
COMPILE_TIME_ASSERT,
|
- CLANG_FORMAT_DUMMY_STATEMENT
|
||||||
COMPILE_TIME_ASSERT_ALIGNED1,
|
- COMPILE_TIME_ASSERT
|
||||||
]
|
- COMPILE_TIME_ASSERT_ALIGNED1
|
||||||
|
WhitespaceSensitiveMacros:
|
||||||
|
- ACC_PP_MACRO_EXPAND
|
||||||
|
- ACC_PP_STRINGIZE
|
||||||
...
|
...
|
||||||
|
|||||||
@@ -1,93 +0,0 @@
|
|||||||
#! /bin/bash
|
|
||||||
## vim:set ts=4 sw=4 et:
|
|
||||||
set -e; set -o pipefail
|
|
||||||
|
|
||||||
# Copyright (C) Markus Franz Xaver Johannes Oberhumer
|
|
||||||
|
|
||||||
# ...lots of outdated/unneeded stuff from the old Travis/Circle/AppVeyor CI days...
|
|
||||||
|
|
||||||
if [[ $TRAVIS_OS_NAME == osx ]]; then
|
|
||||||
argv0=$0; argv0abs=$(greadlink -en -- "$0"); argv0dir=$(dirname "$argv0abs")
|
|
||||||
else
|
|
||||||
argv0=$0; argv0abs=$(readlink -en -- "$0"); argv0dir=$(dirname "$argv0abs")
|
|
||||||
fi
|
|
||||||
source "$argv0dir/travis_init.sh" || exit 1
|
|
||||||
|
|
||||||
# create dirs
|
|
||||||
cd / || exit 1
|
|
||||||
mkbuilddirs $upx_BUILDDIR $ucl_BUILDDIR $upx_testsuite_BUILDDIR $zlib_BUILDDIR
|
|
||||||
cd / && cd "$upx_SRCDIR" || exit 1
|
|
||||||
|
|
||||||
echo
|
|
||||||
print_settings
|
|
||||||
echo
|
|
||||||
echo "$CC --version"; $CC --version
|
|
||||||
echo "$CXX --version"; $CXX --version
|
|
||||||
echo
|
|
||||||
|
|
||||||
# check whitespace
|
|
||||||
if [[ $TRAVIS_OS_NAME == linux ]]; then
|
|
||||||
cd / && cd $upx_SRCDIR || exit 1
|
|
||||||
echo "Checking source code for whitespace violations..."
|
|
||||||
bash ./misc/scripts/check_whitespace.sh || exit 1
|
|
||||||
echo " Passed."
|
|
||||||
fi # linux
|
|
||||||
|
|
||||||
set -x
|
|
||||||
|
|
||||||
#
|
|
||||||
# rebuild UPX stubs (needs upx-stubtools)
|
|
||||||
#
|
|
||||||
|
|
||||||
if [[ $BM_X =~ (^|\+)rebuild-stubs($|\+) ]]; then
|
|
||||||
if [[ -f "$HOME/local/bin/bin-upx/upx-stubtools-check-version" ]]; then
|
|
||||||
bin_upx=$(readlink -en -- "$HOME/local/bin/bin-upx")
|
|
||||||
elif [[ -f "$HOME/.local/bin/bin-upx/upx-stubtools-check-version" ]]; then
|
|
||||||
bin_upx=$(readlink -en -- "$HOME/.local/bin/bin-upx")
|
|
||||||
else
|
|
||||||
bin_upx=$(readlink -en -- "$upx_SRCDIR/../deps/bin-upx-20210104")
|
|
||||||
fi
|
|
||||||
cd / && cd "$upx_SRCDIR" || exit 1
|
|
||||||
extra_subdirs=()
|
|
||||||
extra_subdirs+=( src/stub/src/arch/amd64 )
|
|
||||||
extra_subdirs+=( src/stub/src/arch/arm/v4a )
|
|
||||||
extra_subdirs+=( src/stub/src/arch/arm/v4t )
|
|
||||||
extra_subdirs+=( src/stub/src/arch/arm64/v8 )
|
|
||||||
extra_subdirs+=( src/stub/src/arch/i386 )
|
|
||||||
extra_subdirs+=( src/stub/src/arch/m68k/m68000 )
|
|
||||||
extra_subdirs+=( src/stub/src/arch/m68k/m68020 )
|
|
||||||
extra_subdirs+=( src/stub/src/arch/mips/r3000 )
|
|
||||||
extra_subdirs+=( src/stub/src/arch/powerpc/32 )
|
|
||||||
extra_subdirs+=( src/stub/src/arch/powerpc/64 )
|
|
||||||
extra_subdirs+=( src/stub/src/arch/powerpc/64le )
|
|
||||||
make -C src/stub maintainer-clean
|
|
||||||
for d in ${extra_subdirs[@]}; do
|
|
||||||
make -C $d -f Makefile.extra maintainer-clean
|
|
||||||
git status $d || true
|
|
||||||
done
|
|
||||||
git status src/stub/src || true
|
|
||||||
git status || true
|
|
||||||
failed=0
|
|
||||||
for d in ${extra_subdirs[@]}; do
|
|
||||||
PATH="$bin_upx:$PATH" make -C $d -f Makefile.extra || failed=1
|
|
||||||
done
|
|
||||||
PATH="$bin_upx:$PATH" make -C src/stub all || failed=1
|
|
||||||
if [[ $failed != 0 ]]; then
|
|
||||||
echo "UPX-ERROR: FATAL: rebuild-stubs failed"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
if ! git diff --quiet; then
|
|
||||||
git status || true
|
|
||||||
git diff || true
|
|
||||||
echo "UPX-ERROR: FATAL: rebuild-stubs git status mismatch. See log file."
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
git status
|
|
||||||
if [[ $BM_X == rebuild-stubs ]]; then
|
|
||||||
echo "X=rebuild-stubs done. Exiting."
|
|
||||||
exit 0
|
|
||||||
fi
|
|
||||||
unset bin_upx extra_subdirs d failed
|
|
||||||
fi
|
|
||||||
|
|
||||||
exit 1
|
|
||||||
@@ -1,273 +0,0 @@
|
|||||||
## vim:set ts=4 sw=4 et:
|
|
||||||
|
|
||||||
# Copyright (C) Markus Franz Xaver Johannes Oberhumer
|
|
||||||
|
|
||||||
# ...lots of outdated/unneeded stuff from the old Travis/Circle/AppVeyor CI days...
|
|
||||||
|
|
||||||
#set -x # debug
|
|
||||||
umask 022
|
|
||||||
export GIT_PAGER=
|
|
||||||
|
|
||||||
# rename short variables to more readable Build-Matrix BM_ names
|
|
||||||
# C is COMPILER
|
|
||||||
# B is BUILD_OPTIONS
|
|
||||||
# T is TESTSUITE_OPTIONS
|
|
||||||
# X is EXTRA_OPTIONS
|
|
||||||
BM_CROSS=$CROSS; BM_C=$C; BM_B=$B; BM_T=$T; BM_X=$X
|
|
||||||
unset CROSS C B T X
|
|
||||||
[[ -z $BM_C ]] && BM_C=gcc
|
|
||||||
[[ -z $BM_B ]] && BM_B=release
|
|
||||||
|
|
||||||
# just in case, unset variable for passing extra UPX options
|
|
||||||
export UPX=
|
|
||||||
# un-export some vars
|
|
||||||
declare +x UPX_AUTOMATIC_BUILDS_SSL_KEY UPX_AUTOMATIC_BUILDS_SSL_IV
|
|
||||||
|
|
||||||
# compatibility wrappers
|
|
||||||
if [[ $TRAVIS_OS_NAME == osx ]]; then
|
|
||||||
# use GNU coreutils ("brew install coreutils")
|
|
||||||
chmod() {
|
|
||||||
gchmod "$@"
|
|
||||||
}
|
|
||||||
date() {
|
|
||||||
gdate "$@"
|
|
||||||
}
|
|
||||||
readlink() {
|
|
||||||
greadlink "$@"
|
|
||||||
}
|
|
||||||
sha256sum() {
|
|
||||||
gsha256sum "$@"
|
|
||||||
}
|
|
||||||
fi
|
|
||||||
if [[ -n $APPVEYOR_JOB_ID ]]; then
|
|
||||||
openssl() {
|
|
||||||
/usr/bin/openssl "$@"
|
|
||||||
}
|
|
||||||
sort() {
|
|
||||||
/usr/bin/sort "$@"
|
|
||||||
}
|
|
||||||
fi
|
|
||||||
|
|
||||||
# set CC and CXX from BM_C and BM_CROSS
|
|
||||||
if [[ -z $CC_OVERRIDE ]]; then
|
|
||||||
CC=false CXX=false SCAN_BUILD=false
|
|
||||||
AR=ar SIZE=size
|
|
||||||
if [[ -n $APPVEYOR_JOB_ID ]]; then
|
|
||||||
BUILD_LOCAL_UCL=1
|
|
||||||
BUILD_LOCAL_ZLIB=1
|
|
||||||
if [[ $BM_C =~ (^|\-)(clang|gcc)($|\-) ]]; then
|
|
||||||
export upx_EXTRA_LDFLAGS="-static-libgcc -static-libstdc++"
|
|
||||||
fi
|
|
||||||
upx_exeext=.exe
|
|
||||||
# dir c:\cygwin
|
|
||||||
case $BM_C in
|
|
||||||
gcc-m32 | gcc-4.9-m32)
|
|
||||||
x=i686-w64-mingw32; AR="$x-ar"; CC="$x-gcc -m32"; CXX="$x-g++ -m32" ;;
|
|
||||||
gcc-m64 | gcc-4.9-m64)
|
|
||||||
x=x86_64-w64-mingw32; AR="$x-ar"; CC="$x-gcc -m64"; CXX="$x-g++ -m64" ;;
|
|
||||||
msvc | msvc-*)
|
|
||||||
AR="link -lib"; CC="cl"; CXX="cl" ;; # standard system compiler
|
|
||||||
esac
|
|
||||||
fi # APPVEYOR_JOB_ID
|
|
||||||
if [[ -n $BM_CROSS ]]; then
|
|
||||||
BUILD_LOCAL_UCL=1
|
|
||||||
BUILD_LOCAL_ZLIB=1
|
|
||||||
if [[ $BM_C =~ (^|\-)(clang|gcc)($|\-) ]]; then
|
|
||||||
export upx_EXTRA_LDFLAGS="-static-libgcc -static-libstdc++"
|
|
||||||
fi
|
|
||||||
cat /etc/os-release || true
|
|
||||||
if grep -E -q '^PRETTY_NAME="?Ubuntu .*12\.04' /etc/os-release; then
|
|
||||||
case $BM_CROSS-$BM_C in
|
|
||||||
arm-linux-gnueabi-gcc | arm-linux-gnueabi-gcc-4.6)
|
|
||||||
[[ -z $upx_qemu ]] && upx_qemu="qemu-arm -L /usr/arm-linux-gnueabi"
|
|
||||||
x=arm-linux-gnueabi; AR="$x-ar"; CC="$x-gcc"; CXX="$x-g++" ;;
|
|
||||||
arm-linux-gnueabihf-gcc | arm-linux-gnueabihf-gcc-4.6)
|
|
||||||
[[ -z $upx_qemu ]] && upx_qemu="qemu-arm -L /usr/arm-linux-gnueabihf"
|
|
||||||
x=arm-linux-gnueabihf; AR="$x-ar"; CC="$x-gcc"; CXX="$x-g++" ;;
|
|
||||||
i[36]86-w64-mingw32-gcc | i[36]86-w64-mingw32-gcc-4.6)
|
|
||||||
upx_exeext=.exe
|
|
||||||
[[ -z $upx_wine ]] && upx_wine="wine"
|
|
||||||
x=i686-w64-mingw32; AR="$x-ar"; CC="$x-gcc -m32"; CXX="$x-g++ -m32" ;;
|
|
||||||
x86_64-w64-mingw32-gcc | x86_64-w64-mingw32-gcc-4.6)
|
|
||||||
upx_exeext=.exe
|
|
||||||
[[ -z $upx_wine ]] && upx_wine="wine"
|
|
||||||
x=x86_64-w64-mingw32; AR="$x-ar"; CC="$x-gcc -m64"; CXX="$x-g++ -m64" ;;
|
|
||||||
esac
|
|
||||||
elif grep -E -q '^PRETTY_NAME="?Ubuntu 16\.04' /etc/os-release; then
|
|
||||||
case $BM_CROSS-$BM_C in
|
|
||||||
aarch64-linux-gnu-gcc-5)
|
|
||||||
[[ -z $upx_qemu ]] && upx_qemu="qemu-aarch64 -L /usr/aarch64-linux-gnu"
|
|
||||||
x=aarch64-linux-gnu; AR="$x-ar"; CC="$x-gcc-5"; CXX="$x-g++-5" ;;
|
|
||||||
arm-linux-gnueabi-gcc-5)
|
|
||||||
[[ -z $upx_qemu ]] && upx_qemu="qemu-arm -L /usr/arm-linux-gnueabi"
|
|
||||||
x=arm-linux-gnueabi; AR="$x-ar"; CC="$x-gcc-5"; CXX="$x-g++-5" ;;
|
|
||||||
arm-linux-gnueabihf-gcc-5)
|
|
||||||
[[ -z $upx_qemu ]] && upx_qemu="qemu-arm -L /usr/arm-linux-gnueabihf"
|
|
||||||
x=arm-linux-gnueabihf; AR="$x-ar"; CC="$x-gcc-5"; CXX="$x-g++-5" ;;
|
|
||||||
i[36]86-w64-mingw32-gcc-5)
|
|
||||||
upx_exeext=.exe
|
|
||||||
[[ -z $upx_wine ]] && upx_wine="wine"
|
|
||||||
x=i686-w64-mingw32; AR="$x-ar"; CC="$x-gcc -m32"; CXX="$x-g++ -m32" ;;
|
|
||||||
mips-linux-gnu-gcc-5)
|
|
||||||
[[ -z $upx_qemu ]] && upx_qemu="qemu-mips -L /usr/mips-linux-gnu"
|
|
||||||
x=mips-linux-gnu; AR="$x-ar"; CC="$x-gcc-5"; CXX="$x-g++-5" ;;
|
|
||||||
mipsel-linux-gnu-gcc-5)
|
|
||||||
[[ -z $upx_qemu ]] && upx_qemu="qemu-mipsel -L /usr/mipsel-linux-gnu"
|
|
||||||
x=mipsel-linux-gnu; AR="$x-ar"; CC="$x-gcc-5"; CXX="$x-g++-5" ;;
|
|
||||||
powerpc-linux-gnu-gcc-5)
|
|
||||||
[[ -z $upx_qemu ]] && upx_qemu="qemu-ppc -L /usr/powerpc-linux-gnu"
|
|
||||||
x=powerpc-linux-gnu; AR="$x-ar"; CC="$x-gcc-5"; CXX="$x-g++-5" ;;
|
|
||||||
powerpc64-linux-gnu-gcc-5)
|
|
||||||
[[ -z $upx_qemu ]] && upx_qemu="qemu-ppc64 -L /usr/powerpc64-linux-gnu"
|
|
||||||
x=powerpc64-linux-gnu; AR="$x-ar"; CC="$x-gcc-5"; CXX="$x-g++-5" ;;
|
|
||||||
powerpc64le-linux-gnu-gcc-5)
|
|
||||||
[[ -z $upx_qemu ]] && upx_qemu="qemu-ppc64le -L /usr/powerpc64le-linux-gnu"
|
|
||||||
x=powerpc64le-linux-gnu; AR="$x-ar"; CC="$x-gcc-5"; CXX="$x-g++-5" ;;
|
|
||||||
s390x-linux-gnu-gcc-5)
|
|
||||||
[[ -z $upx_qemu ]] && upx_qemu="qemu-s390x -L /usr/s390x-linux-gnu"
|
|
||||||
x=s390x-linux-gnu; AR="$x-ar"; CC="$x-gcc-5"; CXX="$x-g++-5" ;;
|
|
||||||
x86_64-w64-mingw32-gcc-5)
|
|
||||||
upx_exeext=.exe
|
|
||||||
[[ -z $upx_wine ]] && upx_wine="wine"
|
|
||||||
x=x86_64-w64-mingw32; AR="$x-ar"; CC="$x-gcc -m64"; CXX="$x-g++ -m64" ;;
|
|
||||||
esac
|
|
||||||
elif grep -E -q '^PRETTY_NAME="?Ubuntu 20\.04' /etc/os-release; then
|
|
||||||
case $BM_CROSS-$BM_C in
|
|
||||||
x86_64-w64-mingw32-gcc-9)
|
|
||||||
export upx_EXTRA_CPPFLAGS="-D__USE_MINGW_ANSI_STDIO=1"
|
|
||||||
export upx_EXTRA_LDFLAGS="-static"
|
|
||||||
upx_exeext=.exe
|
|
||||||
[[ -z $upx_wine ]] && upx_wine="wine64"
|
|
||||||
x=x86_64-w64-mingw32; AR="$x-ar"; CC="$x-gcc -m64"; CXX="$x-g++ -m64" ;;
|
|
||||||
esac
|
|
||||||
fi
|
|
||||||
fi # BM_CROSS
|
|
||||||
if [[ $CC == "false" ]]; then # generic
|
|
||||||
if [[ -z $BM_CROSS ]]; then
|
|
||||||
if [[ $TRAVIS_OS_NAME == osx ]]; then
|
|
||||||
case $BM_C in
|
|
||||||
clang | clang-m?? | clang-[6789][0-9][0-9]-m?? | clang-1[0-1][0-9][0-9]-m??)
|
|
||||||
CC="clang"; CXX="clang++" ;; # standard system compiler
|
|
||||||
esac
|
|
||||||
else
|
|
||||||
case $BM_C in
|
|
||||||
clang | clang-m?? | clang-3.4-m??)
|
|
||||||
CC="clang"; CXX="clang++" ;; # standard system compiler
|
|
||||||
clang-[3456].[0-9]-m??)
|
|
||||||
v=${BM_C:6:3}; CC="clang-$v"; CXX="clang++-$v"; SCAN_BUILD="scan-build-$v" ;;
|
|
||||||
clang-[789]-m??)
|
|
||||||
v=${BM_C:6:1}; CC="clang-$v"; CXX="clang++-$v"; SCAN_BUILD="scan-build-$v" ;;
|
|
||||||
clang-1[0-9]-m??)
|
|
||||||
v=${BM_C:6:2}; CC="clang-$v"; CXX="clang++-$v"; SCAN_BUILD="scan-build-$v" ;;
|
|
||||||
gcc | gcc-m?? | gcc-mx32)
|
|
||||||
CC="gcc"; CXX="g++" ;; # standard system compiler
|
|
||||||
gcc-[34].[0-9]-m?? | gcc-[34].[0-9]-mx32)
|
|
||||||
v=${BM_C:4:3}; CC="gcc-$v"; CXX="g++-$v" ;;
|
|
||||||
gcc-[56789]-m?? | gcc-[56789]-mx32)
|
|
||||||
v=${BM_C:4:1}; CC="gcc-$v"; CXX="g++-$v" ;;
|
|
||||||
gcc-1[0-9]-m?? | gcc-1[0-9]-mx32)
|
|
||||||
v=${BM_C:4:2}; CC="gcc-$v"; CXX="g++-$v" ;;
|
|
||||||
esac
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
fi # generic
|
|
||||||
case $BM_C in
|
|
||||||
clang*-m32) CC="$CC -m32"; CXX="$CXX -m32" ;;
|
|
||||||
clang*-m64) CC="$CC -m64"; CXX="$CXX -m64" ;;
|
|
||||||
gcc*-m32) CC="$CC -m32"; CXX="$CXX -m32" ;;
|
|
||||||
gcc*-m64) CC="$CC -m64"; CXX="$CXX -m64" ;;
|
|
||||||
gcc*-mx32) CC="$CC -mx32"; CXX="$CXX -mx32"; BUILD_LOCAL_UCL=1; BUILD_LOCAL_ZLIB=1 ;;
|
|
||||||
esac
|
|
||||||
if [[ $BM_C =~ (^|\-)(clang|gcc)($|\-) ]]; then
|
|
||||||
CC="$CC -std=gnu89"
|
|
||||||
fi
|
|
||||||
unset v x
|
|
||||||
export AR CC CXX
|
|
||||||
fi # CC_OVERRIDE
|
|
||||||
|
|
||||||
# source dirs
|
|
||||||
[[ -z $upx_SRCDIR ]] && upx_SRCDIR=$(readlink -mn -- $argv0dir/..)
|
|
||||||
[[ -z $ucl_SRCDIR ]] && ucl_SRCDIR=$(readlink -mn -- $upx_SRCDIR/../deps/ucl-1.03)
|
|
||||||
[[ -z $upx_testsuite_SRCDIR ]] && upx_testsuite_SRCDIR=$(readlink -mn -- $upx_SRCDIR/../deps/upx-testsuite)
|
|
||||||
[[ -z $zlib_SRCDIR ]] && zlib_SRCDIR=$(readlink -mn -- $upx_SRCDIR/../deps/zlib-1.2.11)
|
|
||||||
|
|
||||||
# build dirs
|
|
||||||
mkbuilddirs() {
|
|
||||||
local d
|
|
||||||
for d in "$@"; do
|
|
||||||
mkdir -p -v "$d" || exit 1
|
|
||||||
[[ -f "$d/.mfxnobackup" ]] || touch "$d/.mfxnobackup"
|
|
||||||
done
|
|
||||||
}
|
|
||||||
# search for an existing $toptop_builddir
|
|
||||||
if [[ -z $toptop_builddir ]]; then
|
|
||||||
for d in . ..; do
|
|
||||||
for subdir in "local" appveyor circle github gitlab travis .; do
|
|
||||||
dd=$d/build/$subdir
|
|
||||||
if [[ -d $dd ]]; then
|
|
||||||
toptop_builddir=$(readlink -en -- "$dd")
|
|
||||||
break 2
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
done
|
|
||||||
unset d subdir dd
|
|
||||||
fi
|
|
||||||
[[ -z $toptop_builddir ]] && toptop_builddir=$(readlink -mn -- ./build)
|
|
||||||
[[ -z $toptop_bdir ]] && toptop_bdir=$(readlink -mn -- "$toptop_builddir/${BM_CROSS:+$BM_CROSS-}$BM_C/$BM_B")
|
|
||||||
[[ -z $upx_BUILDDIR ]] && upx_BUILDDIR=$(readlink -mn -- "$toptop_bdir/upx")
|
|
||||||
[[ -z $ucl_BUILDDIR ]] && ucl_BUILDDIR=$(readlink -mn -- "$toptop_bdir/ucl-1.03")
|
|
||||||
[[ -z $upx_testsuite_BUILDDIR ]] && upx_testsuite_BUILDDIR=$(readlink -mn -- "$toptop_bdir/upx-testsuite")
|
|
||||||
[[ -z $zlib_BUILDDIR ]] && zlib_BUILDDIR=$(readlink -mn -- "$toptop_bdir/zlib-1.2.11")
|
|
||||||
[[ -z $lcov_OUTPUTDIR ]] && lcov_OUTPUTDIR=$(readlink -mn -- "$toptop_bdir/.lcov-results")
|
|
||||||
unset toptop_builddir toptop_bdir
|
|
||||||
|
|
||||||
# ensure absolute directories
|
|
||||||
make_absolute() {
|
|
||||||
local d
|
|
||||||
while [[ $# -gt 0 ]]; do
|
|
||||||
if [[ -n ${!1} ]]; then
|
|
||||||
d=$(readlink -mn -- "${!1}")
|
|
||||||
eval $1="$d"
|
|
||||||
fi
|
|
||||||
shift
|
|
||||||
done
|
|
||||||
}
|
|
||||||
for var_prefix in ucl upx upx_testsuite zlib; do
|
|
||||||
for var_suffix in _BUILDDIR _SRCDIR; do
|
|
||||||
make_absolute ${var_prefix}${var_suffix}
|
|
||||||
done
|
|
||||||
done
|
|
||||||
make_absolute lcov_OUTPUTDIR
|
|
||||||
unset var_prefix var_suffix
|
|
||||||
|
|
||||||
print_header() {
|
|
||||||
local x='==========='; x="$x$x$x$x$x$x$x"
|
|
||||||
echo -e "\n${x}\n${1}\n${x}\n"
|
|
||||||
}
|
|
||||||
|
|
||||||
print_settings() {
|
|
||||||
local v var_prefix var_suffix
|
|
||||||
# Build Matrix
|
|
||||||
for v in TRAVIS_OS_NAME BM_CROSS BM_C BM_B BM_T; do
|
|
||||||
[[ -n ${!v} ]] && echo "${v}='${!v}'"
|
|
||||||
done
|
|
||||||
# BM_C related
|
|
||||||
for v in AR CC CXX CPPFLAGS CFLAGS CXXFLAGS LDFLAGS LIBS SCAN_BUILD; do
|
|
||||||
[[ -n ${!v} ]] && echo "${v}='${!v}'"
|
|
||||||
v=EXTRA_${v}
|
|
||||||
[[ -n ${!v} ]] && echo "${v}='${!v}'"
|
|
||||||
done
|
|
||||||
# directories and other info
|
|
||||||
for v in TRAVIS_XCODE_SDK UPX_UCLDIR lcov_OUTPUTDIR; do
|
|
||||||
[[ -n ${!v} ]] && echo "${v}='${!v}'"
|
|
||||||
done
|
|
||||||
for var_prefix in ucl upx upx_testsuite zlib; do
|
|
||||||
for var_suffix in _BUILDDIR _SRCDIR; do
|
|
||||||
v=${var_prefix}${var_suffix}
|
|
||||||
[[ -n ${!v} ]] && echo "${v}='${!v}'"
|
|
||||||
done
|
|
||||||
done
|
|
||||||
##env | LC_ALL=C sort
|
|
||||||
}
|
|
||||||
|
|
||||||
true
|
|
||||||
@@ -46,164 +46,164 @@ b8c35fa2956da17ca505956e9f5017bb5f3a746322647e24ccb8ff28059cafa4 *powerpc-linux.
|
|||||||
a0950546dc17fca9437219431d8ddb0249ce5b08e899e0c799a87ac982adee70 *powerpc64le-linux.elf/upx-3.95
|
a0950546dc17fca9437219431d8ddb0249ce5b08e899e0c799a87ac982adee70 *powerpc64le-linux.elf/upx-3.95
|
||||||
"
|
"
|
||||||
expected_sha256sums__t110_compress_ucl_nrv2b_3_no_filter="\
|
expected_sha256sums__t110_compress_ucl_nrv2b_3_no_filter="\
|
||||||
e697578691a81e9d4bae7d32ea1f2e83c48956d6910d0306761e484dc3c07e18 *amd64-linux.elf/upx-3.91
|
693102863358cc906bce946afec10dd0e15d0effc6ceb462d9beaaba25967304 *amd64-linux.elf/upx-3.91
|
||||||
6b54df3465da21601619d973b618cf45f695e8511f8d9c88d65f8efc1e347512 *amd64-linux.elf/upx-3.95
|
4aa9e1868d7797b50768cf1ae0ab0e93cc2eff81f3abaf36f2fdb5faf673f7b7 *amd64-linux.elf/upx-3.95
|
||||||
939e9058b5abec32f27588474ad334d8d05a9a8515e75dc417d397c6de74d02a *amd64-win64.pe/upx-3.95.exe
|
996dc60b7b6aa8c4c55b4fbec9b1ad3e2f82f9986fd1cdcd2cb41ab01877d5a9 *amd64-win64.pe/upx-3.95.exe
|
||||||
290cf727b3944db22fb1618d0e36d06659126d759a06fd0a5ffb397927d34f31 *arm-linux.elf/upx-3.95
|
bb6cd600a28de3abc86c618125d72231d3d4b40de0260d2da7393970859723dd *arm-linux.elf/upx-3.95
|
||||||
4c488f100a589aace7e52a1f49982b618662ed2227e66a1e8c9699c9969ccedc *arm-wince.pe/upx-3.91.exe
|
bc945bc3f64a318a00ecbfde2e4a4bac2d298f753e5a8dbdc6a972bcabfce6eb *arm-wince.pe/upx-3.91.exe
|
||||||
b5da1b05cfe70c4d8dc169d8e27bfd8d95f92cc2c7307f907a7bc561e3523dab *arm64-linux.elf/upx-3.95
|
19bdd27706f3476dfd46e5cdde782908af5bf9d068bf337ad8a26024d51ede8f *arm64-linux.elf/upx-3.95
|
||||||
56abe47901f0e4fb207c3c19d21334664229081391d6df7e5e5c81b97c57419e *armeb-linux.elf/upx-3.91
|
3b6e5e9eeb660859e35d9d3e005fb51a8163bfe548d8be6525660a30d1ea5c37 *armeb-linux.elf/upx-3.91
|
||||||
d0712d61d08a6e7161a9ff2dc933888199705fcf194c9a96350d75774c5a6a62 *armeb-linux.elf/upx-3.95
|
2f2d916ee977e06b07429e563aeab0d052b7ba359dd61a7d767e2a7ef7fa049d *armeb-linux.elf/upx-3.95
|
||||||
bb56e464921ad806bc72308f85d42ea1b4f6715983ecdb9415b1d525f5e3ec9c *i386-dos32.djgpp2.coff/upx-3.91.exe
|
1e8cded938d4ee16bcc66fb5462650733a8862a1c9fab264a77a22e7958b36a7 *i386-dos32.djgpp2.coff/upx-3.91.exe
|
||||||
7adf07236d7a36099122edeba72534944f7f0cab36f110169f3b5755f48bad76 *i386-dos32.djgpp2.coff/upx-3.95.exe
|
6f439d62cdb735570c6c5e941924b6d2819024cad6c3453db020edc1e9e0d66b *i386-dos32.djgpp2.coff/upx-3.95.exe
|
||||||
590b4b75ad6fc076440bf7afc9261ff1e5e3efeec84c5cd81243aec2b0b5274d *i386-linux.elf/upx-3.91
|
f6a8a76b9af29272722be6785242a9822ce6b2ca3483cd953c2c34e4d85e1cf4 *i386-linux.elf/upx-3.91
|
||||||
0dfda4fbe5bd260f1592649eb564bb28ee768413e1c7fe3a678d8d7b025edcea *i386-linux.elf/upx-3.95
|
7eead732dddffdb1db5e5002babe112f8589eeb8251cb23e0b6f29dacfad3817 *i386-linux.elf/upx-3.95
|
||||||
e3f98f4c2d0473b11fedd966e2fa184c0cf7e49a46fcbd5705387f9f2b191106 *i386-win32.pe/upx-3.91.exe
|
2c41d77ae9ac810cde23a222046d05b57a272c90aa75b127e0697a586be1ce1f *i386-win32.pe/upx-3.91.exe
|
||||||
38c37ec2351783a48d4cce3f240bbf6a31331f9d9bd86f77cee468ff179cf58c *i386-win32.pe/upx-3.95.exe
|
0218c00a3686363148a2bbe7d89634d54a2d7840beeab7f5fef2f269e56d517e *i386-win32.pe/upx-3.95.exe
|
||||||
ac331450fd0609f0f47a5012156a13d06dcabdc8ba58d5a7810dee6f17fda123 *m68k-atari.tos/upx-3.91.ttp
|
44034fc9a3609538d8edfbe3996aa3946b1745e537d1ea2ca14181c177b98034 *m68k-atari.tos/upx-3.91.ttp
|
||||||
7483078331cbfc32f6150929c244f4cc0a34282f60332da37bcfdbe41c1014cb *mips-linux.elf/upx-3.95
|
55c6151325fdf1638584f0fa5ee228547445e239bb0c8f4c6f31c30945e114b1 *mips-linux.elf/upx-3.95
|
||||||
23fe3c6320f3cebce8027ec5597c228b9f160407e1e0e8a810e2ae6be8dc0d43 *mipsel-linux.elf/upx-3.91
|
b6905f55277b3abc8ad10eb1ca95135ce9f2a5d87c992f7de78ca8e69d8e819e *mipsel-linux.elf/upx-3.91
|
||||||
3279bdf38a14623c7a939df871f0efa5aafa4d4ed6a28c779a5d5213e6dfb7a1 *mipsel-linux.elf/upx-3.95
|
3a5eb4b01cb334e4a30a0ebb1c7d9f85f2035e6e5989acc296beb3ff34c98152 *mipsel-linux.elf/upx-3.95
|
||||||
5fe46128190a2553c6219f6f998b31ff007a5692f44585bcec27566eb6bf6640 *powerpc-linux.elf/upx-3.91
|
df4157e8e613f62fb26b1965b1c22dc44bf18f4aec4611283afadb9889d267d4 *powerpc-linux.elf/upx-3.91
|
||||||
c5ce8e7076d542a92205f98c8017fc9b6f97541a1e082ca2239c1138104001ef *powerpc-linux.elf/upx-3.95
|
054a126aa7e17c6c5b8a00f608c4bf98f252ec4ab9ca2c03aebf9c92e30bda4f *powerpc-linux.elf/upx-3.95
|
||||||
21268d593853c2e724037ca0e0c832b89414c3c41e2a0cc9c5038ab162be710b *powerpc64le-linux.elf/upx-3.95
|
4667d37cb2474a30b184cd4d7ca8ba071650c396ebe9f1f9a39172c924676090 *powerpc64le-linux.elf/upx-3.95
|
||||||
"
|
"
|
||||||
expected_sha256sums__t120_compress_ucl_nrv2d_3_no_filter="\
|
expected_sha256sums__t120_compress_ucl_nrv2d_3_no_filter="\
|
||||||
b8e4d487f79a5c097244793f0535b2cfc4587449f9cbc9a7e19f5171a7a05f8c *amd64-linux.elf/upx-3.91
|
f3cfc0be5885525965fbd3e56f5a4083a727414978bb4c018b4b0355c5b06921 *amd64-linux.elf/upx-3.91
|
||||||
ab4972d2fd8369c43337aa636060b881c65ca18942d46d7ea24392a771b07b30 *amd64-linux.elf/upx-3.95
|
06f933cf1c5e42f2f00ffb6a5312fa687846b6a566d372459208f8cad34e34bb *amd64-linux.elf/upx-3.95
|
||||||
f5380d57da37b4d5e1258f0d36e329a936c3976ac7f684baa20899c9cfc5f167 *amd64-win64.pe/upx-3.95.exe
|
db33236e886947a74c766e632ded0249166e2e5f74a3d03cda37cc07901cd1b1 *amd64-win64.pe/upx-3.95.exe
|
||||||
024b27a1edf93da0efc93190c4b6d2003d76e43a80065b24a1aa5bf0143feb06 *arm-linux.elf/upx-3.95
|
3564858c026c2b0637e3c8e41a972fabc609ccc69c7ddd0ae457dd4ba7a62008 *arm-linux.elf/upx-3.95
|
||||||
0c588526f42f3f0931731fb01e1e257780c9a87a1701b2c3f4a7605b6911f618 *arm-wince.pe/upx-3.91.exe
|
dceda960aa7b15b13a06bf88d1512d52e7e460d85a81207b6b5407bdbb51ffe8 *arm-wince.pe/upx-3.91.exe
|
||||||
2c12d439d9a24c532b6c41decd9b01d2774d03e34692129ee17b8448e3436e3e *arm64-linux.elf/upx-3.95
|
52b93b549591081ef72d19fe09d4588d7f2bc736f2ad50a32be03fb7fcd70e95 *arm64-linux.elf/upx-3.95
|
||||||
eb7436b949fd646500bf42f14abe2ea6d466cbda5cbfff36a4e71693611d6c9f *armeb-linux.elf/upx-3.91
|
1877be1f5f5333f1ee7c77bfb020f35f5c125e7f6b661a92a6918b468c02484f *armeb-linux.elf/upx-3.91
|
||||||
3e0db5fc130ac5b08d9b4df0cdf0fb9a40fa299cd5e28b2550277845500fa729 *armeb-linux.elf/upx-3.95
|
a4d1f01a3dc748e92dd33e1377885ef2955c2c35fd379474c6622ce67267fac2 *armeb-linux.elf/upx-3.95
|
||||||
fb7d8645e851534e4050efac23aff3fc0557f217d4fe2bb3715f8771845f5759 *i386-dos32.djgpp2.coff/upx-3.91.exe
|
d5d3cf6ecf1a89f5871bcfef9c59794f249b9f7ca12afdf15b79d343a18ddefc *i386-dos32.djgpp2.coff/upx-3.91.exe
|
||||||
12d2e9029826966caa38cf719757a055298c86d46e6bea7eef7a20a77a6902a9 *i386-dos32.djgpp2.coff/upx-3.95.exe
|
eca16dec497e1a9f334fd4d806f035cafcd3438749d25b494e95f4935760ae4f *i386-dos32.djgpp2.coff/upx-3.95.exe
|
||||||
b10d190bb8c2aee25ed264051b1527649c5f6fa3f8dde46c7ddd9fb3caae8e94 *i386-linux.elf/upx-3.91
|
1ab8d00e13d149f6e74187eadaacd1d8cfa4777ce7489cef88fba4cbde9bcdee *i386-linux.elf/upx-3.91
|
||||||
b6c3402266a0d798ffbdf5ed3c6bbd80cc25999cddf178ce65c8e5917cb60cd9 *i386-linux.elf/upx-3.95
|
dd3169256039f7df2db15a86114818b275c03bd96c3ee828d724131b98fcc6f2 *i386-linux.elf/upx-3.95
|
||||||
1a353bff5e90a73664fb1366fcab3ddde11f9309a59cf0e58a9f6deb40170bff *i386-win32.pe/upx-3.91.exe
|
17a97d24ebbdaa3bd8f7ec9633e38bca1754c8af2d79250aaa5472499a98e0ec *i386-win32.pe/upx-3.91.exe
|
||||||
9fd5633d06eae78f683857fc90ebda7cad60395cc46751101190086f069e55c1 *i386-win32.pe/upx-3.95.exe
|
1bb873ed8a8cbb11238f98c3f616ec6a34f4765a6021e10d9686158f382458f0 *i386-win32.pe/upx-3.95.exe
|
||||||
2df5dd59cabcd7c09293982cc4638a608c424e515f8040aa70473d30fd7373db *m68k-atari.tos/upx-3.91.ttp
|
13b0b57643342d0e08fe084cbf799f518b3d44ac9f39edda7db3e6b6c36386cc *m68k-atari.tos/upx-3.91.ttp
|
||||||
771ee01c165aa0dac865f946dd4207680a723ef822f2ceda27c6c442978cb898 *mips-linux.elf/upx-3.95
|
91145a85e926495a536661d4e842a7b5b259707ef6accf5f08d13adcec173f13 *mips-linux.elf/upx-3.95
|
||||||
f99b2e97c49e86cbe8141160de3b5196e78fe85776a159b745a78144c7fd29a9 *mipsel-linux.elf/upx-3.91
|
8090533000872748b70c761d5581d78fde421d66884ab238527ca41d1446c2ae *mipsel-linux.elf/upx-3.91
|
||||||
bad98328d8666b5f92b7210fa22920947fbfb38a86e788f1bcbb8ce1c8e64bcc *mipsel-linux.elf/upx-3.95
|
f82e7b166647f157c981af92eaeec63bf080609591a5d13f76f84cd49c8e7495 *mipsel-linux.elf/upx-3.95
|
||||||
fc671351debd86f347f874e5a1cace099bbf388fd19f8ec2ac226ab22c84e46e *powerpc-linux.elf/upx-3.91
|
ae312cc5d34fd889ed9582a928ab03c589c0caddb111aceade7e072f928c6361 *powerpc-linux.elf/upx-3.91
|
||||||
cb248465ee6fbf2aff427c9c015de65c547bab7ac3b84b5243980d707c3514ea *powerpc-linux.elf/upx-3.95
|
fd28cb894be895afb8aec675739b276810e7a35c5212016c3f7acde853d8c763 *powerpc-linux.elf/upx-3.95
|
||||||
49e84bc28d7d80d828cf9298101468730dc1badc6e2f710884e2afc34d669391 *powerpc64le-linux.elf/upx-3.95
|
e299bb500c34d2f90b2b35a7186a0b24fb5ac80e56d4a2d80f9c8bd32cf2be62 *powerpc64le-linux.elf/upx-3.95
|
||||||
"
|
"
|
||||||
expected_sha256sums__t130_compress_ucl_nrv2e_3_no_filter="\
|
expected_sha256sums__t130_compress_ucl_nrv2e_3_no_filter="\
|
||||||
037e9867bc52669e8f4869d64a41a8faaca3e57f6b226b79a894aa8854f0d73b *amd64-linux.elf/upx-3.91
|
eea59d6755beed52bff26941d31362f28097d029d4f61a2f9065dcc63cd628fb *amd64-linux.elf/upx-3.91
|
||||||
54b9d627cbb8bf19a8b7e299af33fcfbf45287ee41de1fc3b7806f45cc9f0c4f *amd64-linux.elf/upx-3.95
|
b89f4ca39165071a7a5eb107ed9b7c6c77b7c7ad90acdb2b073314571aacc23a *amd64-linux.elf/upx-3.95
|
||||||
c76b656a4e5c9d3f691d186b488e89401246395e05a4c571d8384826ec1afd7a *amd64-win64.pe/upx-3.95.exe
|
6af6bc4f2d4bdb1e7694f44ce695c54d181011b734f159018d5e2c515d14a47c *amd64-win64.pe/upx-3.95.exe
|
||||||
1099f092f803371ae60fe45d1210ed000fa011026a6e3a339119d30e7b533a3d *arm-linux.elf/upx-3.95
|
9ae22ad9af331ec8c08ab22b0a8e0e0ff849512a6d11257c55fe7c423c0b7937 *arm-linux.elf/upx-3.95
|
||||||
0fd539a9cf015e60f55cfe9a2cb735c39abcec4097a1d9dad14133817322f149 *arm-wince.pe/upx-3.91.exe
|
8605ddb612a1a3e096e272cb876e7777585804fa000f338f2164437a6da3de9a *arm-wince.pe/upx-3.91.exe
|
||||||
f74bcbafa912d4b60431744347562551efb3a4c738b33b54788702c9a04a2755 *arm64-linux.elf/upx-3.95
|
2ab36b41db84e6e3002420ec397d79abed451869a7a8b703ab3b81f79c487753 *arm64-linux.elf/upx-3.95
|
||||||
2159088afb2481c20bd3e46b22f135ea9a71fccf84cf8e3cd5288012bf499efb *armeb-linux.elf/upx-3.91
|
38879c80525760492a95de9bfcbce49997c5bff30bb43a6bb173b1978d21f248 *armeb-linux.elf/upx-3.91
|
||||||
a4e1fb939ffd0dd4fba8d96332406475220439ee368c4445b715d723c14257f7 *armeb-linux.elf/upx-3.95
|
72e3bf259bf1304235a7ebe600f5b37be21297b8552f2fbdf47e28e3aa19e807 *armeb-linux.elf/upx-3.95
|
||||||
7832f40d5a2f4208c5a765a90758a75b8208ac5b4c01a78c276be2ff74d6be13 *i386-dos32.djgpp2.coff/upx-3.91.exe
|
3af56cb84be62f4078ae39be3370ef68061b094c62b3cbcd5d38e99e0e91df7f *i386-dos32.djgpp2.coff/upx-3.91.exe
|
||||||
e6bde12bead66eff48502e7944fe44a557db3f236b6d0155be5b9bf891c6beff *i386-dos32.djgpp2.coff/upx-3.95.exe
|
224b882b4dcebc1112ced3df1b468ea8dc58083dac4893fa0061dc50ce6abf7c *i386-dos32.djgpp2.coff/upx-3.95.exe
|
||||||
8306fa054b3281547f545b2ec1c5a059f0f29414fdeb4a5572f07c25bc8deff2 *i386-linux.elf/upx-3.91
|
59e3a1d456036bed175056978d12484a64405f356b1a1fa480866e7e31c9543b *i386-linux.elf/upx-3.91
|
||||||
75f6be5e52b89ac19f822ba9ed598c050078d9ec5530dd73144b5f0748dfe6e7 *i386-linux.elf/upx-3.95
|
9662deb5f74b23c5b63d09457442895091f4b6cfd619f7bd6ffc27ec75f08682 *i386-linux.elf/upx-3.95
|
||||||
61ea92bd711bcbf8c74e33054f320ab214dc1b2570e814a5d1f65001f7e1e507 *i386-win32.pe/upx-3.91.exe
|
3c585a745cd105073bb7324f2183731be84cfc4669f2bab1ef20c9bff909d2fc *i386-win32.pe/upx-3.91.exe
|
||||||
ed5db8134d10a59b0dc1b973339823d20104ac3c1be0332fb55b1f2e220110c5 *i386-win32.pe/upx-3.95.exe
|
fc796dad77cb6cb99bcb5700c3ff0a7b185c1fe8b129a293dd0e45d0903b13e6 *i386-win32.pe/upx-3.95.exe
|
||||||
d381ff2c7115e3100daa567e49dbf36bd42ea7544039d8e7fb66ecc5009f88c0 *m68k-atari.tos/upx-3.91.ttp
|
da41cb691775b8b0ef969954ea272262ed77e83b57257b2ba0ba19427a2ab991 *m68k-atari.tos/upx-3.91.ttp
|
||||||
6aa24a6661d322f60805406b87a5be605a5aee52d33e798328b7d118dfba4862 *mips-linux.elf/upx-3.95
|
ea6ff916a226e39a5e67b2118fc3ceb0dbc69d8d473051a5df19af14e03ae25e *mips-linux.elf/upx-3.95
|
||||||
04a1492fad74bc942216721a9e538638c9dc14f64272c5d90b54dc5a38c98b4d *mipsel-linux.elf/upx-3.91
|
0cbc8eaecb2aa7dcc2e9d7b11ba0c0e26193f1328a35107cf1069a8c5f9e63be *mipsel-linux.elf/upx-3.91
|
||||||
31f6814a6964c9d5e44f1cc842742036747e95df2bdc4f4dddc8f05d4d9eac1a *mipsel-linux.elf/upx-3.95
|
7b112c59fccf3e5f3d4ec253fdb25761e47705a1c5d3a0103249b1747bbbe7d9 *mipsel-linux.elf/upx-3.95
|
||||||
5b1121a963ecec3e221e0b475f6cde7aad14d5cdd8cba43a4516dbdb92eb5a66 *powerpc-linux.elf/upx-3.91
|
de8354fbeaf0623f3d08c3945dcdb5a8f0c078fe3e8082a13767979e841e6677 *powerpc-linux.elf/upx-3.91
|
||||||
c4f35cda7fdf64d9195115a82c806f084e2dbce0f80a31b34a882138d6d159c1 *powerpc-linux.elf/upx-3.95
|
403c26bc1dda0cbf23032bc5ec5ac42ed8537a640a077c4332446227c8a3eb7b *powerpc-linux.elf/upx-3.95
|
||||||
ce70def8c58def3d548aa04f502c8279392eadcdb2c3d3cac8466cfcd3a6b7ab *powerpc64le-linux.elf/upx-3.95
|
093a7fdbb555c8aea8728b4d6240ed3b723ee9007c5f6ea40a8daf2d1eb63f54 *powerpc64le-linux.elf/upx-3.95
|
||||||
"
|
"
|
||||||
expected_sha256sums__t140_compress_lzma_2_no_filter="\
|
expected_sha256sums__t140_compress_lzma_2_no_filter="\
|
||||||
38b58e0702763bd421f8940479a8545f39a2a8f27d90d2c276dc677d8a99846c *amd64-linux.elf/upx-3.91
|
6dd472386ff2a9683d75fe4cc8d0d40be223681f4d7305a51a7aacf25501e60f *amd64-linux.elf/upx-3.91
|
||||||
5b34c95e9d636903b85b79b299d28f2aa6bd8d3a3d1696acf308d8cf8bfe99d4 *amd64-linux.elf/upx-3.95
|
4bbb96b109ae2b8b43b957bc66c3cdc2cfcf3a692377153ef912d09a495c876c *amd64-linux.elf/upx-3.95
|
||||||
dd10984767f9fe67900b64d63699ccaf858b9072272eef5ca373a7701d5057bb *amd64-win64.pe/upx-3.95.exe
|
510fc860ac393abcfdbb547e999c12a6c6e928ead026607a6879fa7ca1e2d568 *amd64-win64.pe/upx-3.95.exe
|
||||||
4aff8b057429fcdac4f4b3691278c87280e247879ef07ea0291a1c56f999750d *arm-linux.elf/upx-3.95
|
a54c0e5b61257154c56f076460f64efbb4216c913c846073d0a695ac3c0ddffd *arm-linux.elf/upx-3.95
|
||||||
9e5ad415bb42155a3c527fd259ac7ca1534a14bec888cb1ee8a7cc8e2ca0019c *arm-wince.pe/upx-3.91.exe
|
9182294f2e31db89b138294cbbc6f6d03ea39a00565adf0e052ed3d21491e1b5 *arm-wince.pe/upx-3.91.exe
|
||||||
65facbcdbf7f79d88fce4af18629f8489510134005b3e490eb42fa112603e18e *arm64-linux.elf/upx-3.95
|
fde8face710b6a479a96d7d2d40a29ac8894d5483403e33acbf4a5d6f9cdb29d *arm64-linux.elf/upx-3.95
|
||||||
78d94d8209a443ae3c05f360c1086fe8bcad109e3a7d5267c571ad53ad38702e *armeb-linux.elf/upx-3.91
|
0a92af3f6034487034ea062bc44c93bba74219fa5fdcbb34d1643a95f7daa9ed *armeb-linux.elf/upx-3.91
|
||||||
37242e5eb6ef64ed6dc862a791643d62cfc9c3b98a6f88556216a002101ef73f *armeb-linux.elf/upx-3.95
|
2c11ec89ad145e9f82c3cbbd63ed1e1eca2b0d3c3081fce3e0500ed33c05a623 *armeb-linux.elf/upx-3.95
|
||||||
99209d2c5e6e7bf9edad472b181318f135a619f10d19ecde37158a80e186658b *i386-dos32.djgpp2.coff/upx-3.91.exe
|
13cbcb06079492a21b7440b981250f84ff2be48a69daa168d95cee798f8fbf77 *i386-dos32.djgpp2.coff/upx-3.91.exe
|
||||||
f713b061cc6171d6fd467f6041618bf5c61179c406ccf6b79acb378e7fa1f3dd *i386-dos32.djgpp2.coff/upx-3.95.exe
|
adfdcd033340a7b14945c9a60da036e25d44c8b1ee0811ac0a4ef1cbca423cc5 *i386-dos32.djgpp2.coff/upx-3.95.exe
|
||||||
48b554af082672ed3c5dab9ef5d78f561215f23ab98eb49904766e2801b70799 *i386-linux.elf/upx-3.91
|
e5fff5b965da26349311c0513d09086600c3b466f1d53e42d6e35d6b4656168e *i386-linux.elf/upx-3.91
|
||||||
9c1f8e34110030920684ee1276033bcaaa3cd2917d4cc001dad6efd865e8f2e8 *i386-linux.elf/upx-3.95
|
cf8df3858bbb1c92a06e57ce1b971e11bbf280954f2fc1dc7e5b5a4641d72819 *i386-linux.elf/upx-3.95
|
||||||
6d08ec9ab29b1d85bfcaebac1adeec1a5155c8b37a5c979e40f4e0fcae12cb45 *i386-win32.pe/upx-3.91.exe
|
ddc4952ef008b7f31e69bf53310d6f03b36a959ebb1cd3c3985d560efcbd4296 *i386-win32.pe/upx-3.91.exe
|
||||||
1754e33c11034d09076c6a534532d5d9a13e967e4206221cc8a0c6d904bb6edc *i386-win32.pe/upx-3.95.exe
|
99b0b637b562798a440ba605d44e34cf7d4ff995b04dc2e54ebee288ed5180b4 *i386-win32.pe/upx-3.95.exe
|
||||||
d044c35793adedbba31dee6adb4dbd1fcde183f2299d11b17e15aca83500217e *m68k-atari.tos/upx-3.91.ttp
|
89a5de403a012256afefff0f88e1cff4696dee611946e326ad15416dbdba7d13 *m68k-atari.tos/upx-3.91.ttp
|
||||||
f555a0e2444ec2d859609236c66f45b9984cbfcd9668d16dea5de0feb86a94ea *mips-linux.elf/upx-3.95
|
eac695bc19163050c5bee9271393156a195bfef9c3c76f5aaf3aaef00f5602eb *mips-linux.elf/upx-3.95
|
||||||
8a96d7674eb6754235d0e7cc2e72bae241a166e2d232e70ee97bd0382c5dba9f *mipsel-linux.elf/upx-3.91
|
b1331b88421cdf8ef73f8ef1a2c86045fc56a495c08d06d83018c88f5f3934de *mipsel-linux.elf/upx-3.91
|
||||||
40ddb03c43e5740b634aa05a915fbe5ec2fb1f7076b7a3553d236498f4830964 *mipsel-linux.elf/upx-3.95
|
9644118e26647d489e811ebe3bfd320e2976dbe26621e994fe979b0f9d175818 *mipsel-linux.elf/upx-3.95
|
||||||
262cf98e2533c38008b2a2273f5ee3ccdfb753b854c8afb836be5f1b1af56710 *powerpc-linux.elf/upx-3.91
|
64a4a31815e4bf43e2ea866faa494c69a4209ed53055f16562d0d2d6ba7fd927 *powerpc-linux.elf/upx-3.91
|
||||||
20513f3e3f675b167ce74707f9b31c4e4885f5d7c3d8b050a4a7ea7221b1b6f2 *powerpc-linux.elf/upx-3.95
|
dec559bf9cbd4d1745e8f3bf2cedf016a72f443d037f75eab0d2baab191f0ae1 *powerpc-linux.elf/upx-3.95
|
||||||
b8aca35fce8a1ceea2c7ba4f11cfcbb3549ac0e93b955a0c390f6a7063e865e3 *powerpc64le-linux.elf/upx-3.95
|
f10b8afa319b1056a82f24dd52d13003c5cf005fc3cc3481dad1e58ef33e973f *powerpc64le-linux.elf/upx-3.95
|
||||||
"
|
"
|
||||||
expected_sha256sums__t150_compress_ucl_2_all_filters="\
|
expected_sha256sums__t150_compress_ucl_2_all_filters="\
|
||||||
5033deb9509be51229a7fb9fff629547797bfff7046e413a3450892ab459c58e *amd64-linux.elf/upx-3.91
|
2e89a5b8192957b066d5a5ee39e47663518f49c1e7811f6806e21d938201d5b6 *amd64-linux.elf/upx-3.91
|
||||||
d92a21d5b25c4b367142859eb3f29d9754d54b151058475a81e5bda6e5093dcd *amd64-linux.elf/upx-3.95
|
d1cfdda4b93d697211c052f3d85cd745e533261f05cc06c2869a8561c07b4f57 *amd64-linux.elf/upx-3.95
|
||||||
870083b25a88a2ff5cb49dfa109e55fc082b11af39c352740bab65c551b40282 *amd64-win64.pe/upx-3.95.exe
|
c7381363e31af6789111f58ca590b0d751956c322684efa1914f1d918ecc23ce *amd64-win64.pe/upx-3.95.exe
|
||||||
152fbbeabd01c771d526a887ae6a8d92bc5a9dd92ad0779d9a40a036f4760309 *arm-linux.elf/upx-3.95
|
4dc8ba75edd4b1c3d890c9deeb033d9abf08fb65054eddb4f34138d34503c21d *arm-linux.elf/upx-3.95
|
||||||
f88d160e5a3e7e323623dc5f1f6edabd6ed0ac477beb168bf754047c04531097 *arm-wince.pe/upx-3.91.exe
|
36f744d6dca6ecb8c60ee456859ac6a1ac241d12ababa20a5e2d0d79551d53aa *arm-wince.pe/upx-3.91.exe
|
||||||
379a8eec659fd1a1bced32342b45e146333b3a257942d66f7a1062f9cba88f9c *arm64-linux.elf/upx-3.95
|
72d3de2abdc3985c790d833a9535054683e2b3feaa6b96778e55ea8f448846a3 *arm64-linux.elf/upx-3.95
|
||||||
86f5d6d3f7b738e4e30157fb011720fbae61f52a6296e3dfeb445afeceb91e32 *armeb-linux.elf/upx-3.91
|
233d4f130995bb7155064ce6f651b9f6ac61268c8698ccc90a8ea3b2e297cb39 *armeb-linux.elf/upx-3.91
|
||||||
7cb7f1a18d00631decbbd73d56d4cb54a5402cb3784607406c258ce5af3f51ca *armeb-linux.elf/upx-3.95
|
a107428a7675181974a8efc359d39da74510098d8307347865f7bcdd707e28ad *armeb-linux.elf/upx-3.95
|
||||||
4b34e1f0553937c3fb6b98b4cad7beff510d5f0c9bbfd2fd2cc6986bc569d579 *i386-dos32.djgpp2.coff/upx-3.91.exe
|
bd57c1e3844310c2a864384f2b83a5781933a5beb05a5eb748a6094e37621166 *i386-dos32.djgpp2.coff/upx-3.91.exe
|
||||||
41332641b361c584763bfc149d3762bb4c337fe979af85f4b6cc03c3318ac9a9 *i386-dos32.djgpp2.coff/upx-3.95.exe
|
1a13debece417ada4e18d5ec02efa7ef1c354ddfa4674b5717e0aa6bc90c16e3 *i386-dos32.djgpp2.coff/upx-3.95.exe
|
||||||
e3c7e93cddce54b2c044b23b2ce239e2373134212cd930ad700ab93178785941 *i386-linux.elf/upx-3.91
|
f7b56af17d3d8402310387d1e82f90fa670dfa058feb3fe413ac81c01a1efbb1 *i386-linux.elf/upx-3.91
|
||||||
14827578a5bbcebcf02ab9754145a290cb06d0c2dc3d9c34da182c3a22071cb6 *i386-linux.elf/upx-3.95
|
fe9162fbfe8f4eb1c9f286df68107c08f25592d2edaaf5707540c81f709e29ac *i386-linux.elf/upx-3.95
|
||||||
f10fb96a4db81cde3f76f3499710c16accfb7c7b30bc3e5532ea3b0b5aa57d54 *i386-win32.pe/upx-3.91.exe
|
aaa267d824bd0520c016edcc1a6642d4898030760879e1da883b8211cf071350 *i386-win32.pe/upx-3.91.exe
|
||||||
a83278c357fa81f565ee1f95edbfc0156318b9638a5934421ee9f2f1bae5479a *i386-win32.pe/upx-3.95.exe
|
d178699c0ed805829e457987ea5da21f4e37cf1eb74529235d9b1275bf3122f6 *i386-win32.pe/upx-3.95.exe
|
||||||
f29d9bb67de28a5eddbd3153c616f8b840d019bed48dfc6cf99ffc0bc6146390 *m68k-atari.tos/upx-3.91.ttp
|
8376ba3954c4fd9cd5e5e8e38923759db005a4048c3d86dc76476e9f3d92a07d *m68k-atari.tos/upx-3.91.ttp
|
||||||
356630562c9b017d18e09373ca71e19e870ae10b25ffa7a0d6e3e5c1fb948d73 *mips-linux.elf/upx-3.95
|
65a0227127b7952a42216c79a8431d1bbe7f04c9efdc81f72095d095a969cb80 *mips-linux.elf/upx-3.95
|
||||||
336a1795b3675a8ee76fff35f6c9ea9c7fc8f48dd53224a990f1191b1cbbab65 *mipsel-linux.elf/upx-3.91
|
c2bd45b55980bfbc5e568a640643772e3e82bc02cd2c7559cb1c57fc0809d01e *mipsel-linux.elf/upx-3.91
|
||||||
dbebbc932fc3caec6be1fe92d21eed379ed3bf7e55293c10c54dfba9c37229a9 *mipsel-linux.elf/upx-3.95
|
74e25daba42baeaaffadab00bacca56b1de5f151a00160592077288a678f41f2 *mipsel-linux.elf/upx-3.95
|
||||||
adb8d16a5a635cdb3ca12346c5317ce16431cc8ecb9a54a856ee9c2586f7911a *powerpc-linux.elf/upx-3.91
|
904310944bec344897fc6b7a61dfe8ee639d136c555a950c736059cbc6cac8be *powerpc-linux.elf/upx-3.91
|
||||||
286c92ba6bb88c13c01fc932d1a742a2cc0d01b4c59731d72c7a91d0c7c6c9ef *powerpc-linux.elf/upx-3.95
|
5304a95cdcdbdcb76cfac2b93e254f601fb73f68be0a44ed282096aec8d55ae8 *powerpc-linux.elf/upx-3.95
|
||||||
9102d4d31572fc5b5244a6f7643e1d001cc3044836a25c6211f3117d4c2b1dac *powerpc64le-linux.elf/upx-3.95
|
7ebd0be91bc9f60e22304103b3543b16a0fd128aa22f11474e31aecc97703e43 *powerpc64le-linux.elf/upx-3.95
|
||||||
"
|
"
|
||||||
expected_sha256sums__t160_compress_all_methods_1_no_filter="\
|
expected_sha256sums__t160_compress_all_methods_1_no_filter="\
|
||||||
407f350965205d7ef3d860cd89ff1dbee74082a7a6777363deb64ac5676ef495 *amd64-linux.elf/upx-3.91
|
4d8069614af5721c7878daf10ee1d30a6bffc5446532963e2ff0e6cb6f1feecd *amd64-linux.elf/upx-3.91
|
||||||
8d391e5a14922113c7b72a16728f497553fc834b02971c0ffe65a1efe461f240 *amd64-linux.elf/upx-3.95
|
f1971902f7d8f840fdc70ad9edbf5587db556ba046947f5ee7b4130e9ba7de5a *amd64-linux.elf/upx-3.95
|
||||||
867627ab2c87ffe1d82d5f131c0b05f73fc73d1e0a0011e369adb543be3b0deb *amd64-win64.pe/upx-3.95.exe
|
0198a6cfd468f7ec7cd32294333400a4c97bf1cac32602594681db8f08c87700 *amd64-win64.pe/upx-3.95.exe
|
||||||
f9f39f443c419ffaf2a5d95f00144d56de4ca66f21d919272345cf360c947694 *arm-linux.elf/upx-3.95
|
d46340dcd209cce0f1d65d6a50754ea3246cdbba730199765b2c2ac40957bd55 *arm-linux.elf/upx-3.95
|
||||||
9394653a9f6ca77c82916f06d402af45639815edc1eb06ba01e67510927f9d34 *arm-wince.pe/upx-3.91.exe
|
aa03361a7dae633d5b6c8b4164726c99bfc28fcf4f1ac8ebea6fc44e90c03244 *arm-wince.pe/upx-3.91.exe
|
||||||
e22d64d16fe071c70e62e3c97701632a88a1568d8146e197df89f1bcc003041a *arm64-linux.elf/upx-3.95
|
aa0a3dda3e2f073eb36d6614c02f4af79590876a23437623ea6c231be8e070fa *arm64-linux.elf/upx-3.95
|
||||||
61a18df8b91461fb6ffd9fbfff3d24549abe5a64ca512a063a9c09f2d8dbbf64 *armeb-linux.elf/upx-3.91
|
578547a4d527655c7fd661148dfcf0f7dc9585dfb08063c13b116364a881bf15 *armeb-linux.elf/upx-3.91
|
||||||
6866f745d8bfd1f60d3f7fb68e39238f80371e4dec6f42ee08193db13eb2c04e *armeb-linux.elf/upx-3.95
|
0034809b31b0105631b0e4c0a4378cfd26a80dfca2016228e8084f410025f091 *armeb-linux.elf/upx-3.95
|
||||||
d8a099f8e4fd380b70f0cf8ef56cbebf232ea0c127529593c15fc34af7df32e7 *i386-dos32.djgpp2.coff/upx-3.91.exe
|
55b9b578a97a7b8637a9041a222269f2563a4e1f75c329c533f83432c8f9652c *i386-dos32.djgpp2.coff/upx-3.91.exe
|
||||||
5b8d383bbd3594016b09f923f3e3d472649e3854abf9a4d695d67524d57debde *i386-dos32.djgpp2.coff/upx-3.95.exe
|
98a9f601d095f910c68bbf35ff50f19e3e851ef5dae78fc0e9ef4462dd8a314d *i386-dos32.djgpp2.coff/upx-3.95.exe
|
||||||
7116ee5cce8865154ab815eaf717f39b82265c5f88320799d01bea2d92799a3c *i386-linux.elf/upx-3.91
|
45f714365212b31419986016b5b730ca77523036469e28242543bfde4dc44678 *i386-linux.elf/upx-3.91
|
||||||
4f29bc1c53e9cd7047929b8ceb92cc9022cede80fd80afa1c23f48152789d4c7 *i386-linux.elf/upx-3.95
|
e45f6ae7ad7b9e719e5080bfbd04e7c961242473bb8f1574cb625bc8a1abd201 *i386-linux.elf/upx-3.95
|
||||||
65e85f6944b98df0ac16d50af98f501f3f87b35c0432edc17244e768f0850a3a *i386-win32.pe/upx-3.91.exe
|
0b5d940059fc6f2a3d5664eadd0781399210c306be99411beeb8f6f02ea85762 *i386-win32.pe/upx-3.91.exe
|
||||||
6414e7ed0bb0aedc4b027030f42d5d2e49f10cd9d98b9250015be88d708fa4eb *i386-win32.pe/upx-3.95.exe
|
0f5b50dfe0db34ae07f113871a39c64624f964ed16dc8d49922e6a891c17a3bd *i386-win32.pe/upx-3.95.exe
|
||||||
1dc02f7ab54cd23da1ba3efaa3e3ca275cc23bcdcb2f5131bc9c643c87076d0d *m68k-atari.tos/upx-3.91.ttp
|
56fd999694feb66cdc2272daf86bb91b3c66b857867f3e0c071f3e70624760f4 *m68k-atari.tos/upx-3.91.ttp
|
||||||
6b9269ee5709fd2a2bda88fa4d9198e4f163ee067cbd1faca12d17f906c5a2e0 *mips-linux.elf/upx-3.95
|
2d8d2e02bedad8ba1e7d69a89888b173b9be48ee154e2461c205ba4eae6ececa *mips-linux.elf/upx-3.95
|
||||||
4424522044277c9ecfd3869c3746d4ac760b272a58157a8a7b49c1bc8bed6bbd *mipsel-linux.elf/upx-3.91
|
c478c21ecabe91910cf861ebc6b6d38deeb31545e5ae44eaf826dafb477bbfba *mipsel-linux.elf/upx-3.91
|
||||||
673f459fd6024a433d6a86245b569557d523f4f33a2bd1a31ff5ca590a19c663 *mipsel-linux.elf/upx-3.95
|
4d66e1b32ca6b1d399616de5643ee5d1c54a7bf1eca761055570450f56efe4f9 *mipsel-linux.elf/upx-3.95
|
||||||
1e6d47f288f6e9ccdfee98bd3700771dd9cad47115909ec9192f10d7a87440a9 *powerpc-linux.elf/upx-3.91
|
72c85b48afb30cc191483af41f797a397225cfaaa44e2eaf7a9d59d9033335e1 *powerpc-linux.elf/upx-3.91
|
||||||
203a33bb365a745a317a9292562cd80e0f82c7dbafb810fddb8a752d06159dcb *powerpc-linux.elf/upx-3.95
|
c0ed0c72fd6a6e0bfb4444b8c358018246f80cbc732388a22bd2492fd9fdc59c *powerpc-linux.elf/upx-3.95
|
||||||
6bea6492b66df759ed13748b53b3d5058a1d3b9debf0b209c8b450e76e5fd29e *powerpc64le-linux.elf/upx-3.95
|
070f4c2ca60717abedda0ab4030d546cca8a75b9872038a414e2946b8d8f93e7 *powerpc64le-linux.elf/upx-3.95
|
||||||
"
|
"
|
||||||
expected_sha256sums__t170_compress_all_methods_no_lzma_5_no_filter="\
|
expected_sha256sums__t170_compress_all_methods_no_lzma_5_no_filter="\
|
||||||
257a9f44da07e6eb423e651a8323a2b79d38c5d599a4ec1de8f62a7c103eedf4 *amd64-linux.elf/upx-3.91
|
223bcdc5f11daa4d0258090e967d4e0b5986d764d6b21fcfadba7212676396f2 *amd64-linux.elf/upx-3.91
|
||||||
4adc3488e71c834f28a0d9955b3959d7db19ff375720c02c433aae63ec847b67 *amd64-linux.elf/upx-3.95
|
a3e5f1a20bd9db4ae920c5c7e7f1707a63fa3f557f9db50b5e1004b706e3a52c *amd64-linux.elf/upx-3.95
|
||||||
47165d0a33de56cdcf5788773f3630b698bbdc68b8f2a383b348d4264406536b *amd64-win64.pe/upx-3.95.exe
|
355011427a4d433ccef5060e4cbebc59b0ecc38a430566cdb684330388ea0812 *amd64-win64.pe/upx-3.95.exe
|
||||||
4038aad4341b884dbe34aac6055391a78af540f368370b5b61bb45c40905160a *arm-linux.elf/upx-3.95
|
1e0a8363b539953181dc95283a1e3100bacce961f49e875c8f430b18d0e6672d *arm-linux.elf/upx-3.95
|
||||||
4f3f1dbdd225a72d37555d5f60a2eb8308b87ad1e641285f3f693e91cb430985 *arm-wince.pe/upx-3.91.exe
|
e281362e2172468d20ea2c7171c847f47e01a63d912cafacf977236655708521 *arm-wince.pe/upx-3.91.exe
|
||||||
3c7b8a6813a446b05d6ea1d5b81155ac216fd847a3b456d01a5cdbe30a6b686d *arm64-linux.elf/upx-3.95
|
7f3497c67e816b3f2af6642f09ba809166f8a0a65f52936cfb2e3d9756d7bd44 *arm64-linux.elf/upx-3.95
|
||||||
13c966e3377bac700e3e84d725dd8ff9ca949fb74d1ca7774a00af71112dfb7d *armeb-linux.elf/upx-3.91
|
7d9d52959a64c5dd19ea343c8c2bdd4d70fd0644d13c62924760407515fd74ba *armeb-linux.elf/upx-3.91
|
||||||
2d542d14c90a530cf812c713740a0f1b2d73a81b91ef7efbc037c8d3507a714c *armeb-linux.elf/upx-3.95
|
e05ad251ec24e2f788de71c4c8cf7c8880a8eb7d8a516ca8d6ab94c715c2f77d *armeb-linux.elf/upx-3.95
|
||||||
9ea810301eda67e45eee400500d1c88969cd63bda1224446c86eef8a75657748 *i386-dos32.djgpp2.coff/upx-3.91.exe
|
00a030d8967c5145b955eba17d84edd44b21c93b570f80a44e894a10a3ebf99f *i386-dos32.djgpp2.coff/upx-3.91.exe
|
||||||
688efbc1826e6bd0ccceb0462325d5e384f38b7d05dfa3b7901fa18536b6ea68 *i386-dos32.djgpp2.coff/upx-3.95.exe
|
b4b0e3c774dbf3940af777d28e1ba7c62bfedaa710e3376e81259218779eae56 *i386-dos32.djgpp2.coff/upx-3.95.exe
|
||||||
294d5099c4794a2de49d264c0bd4bdf80c866041b7caac7f8420ed003ee18180 *i386-linux.elf/upx-3.91
|
f903265140b193e672c4dd2bc28e68b9f822d73517f0b339fc715ad781a49fab *i386-linux.elf/upx-3.91
|
||||||
8c40b35f36c8850aa481de5ab13a5cb0fbc8fc9593977dd438c08d55dadfa9fc *i386-linux.elf/upx-3.95
|
6253062e41c4619bb3aeb807665a2925b1f01095d000c614c443b81d44112a1d *i386-linux.elf/upx-3.95
|
||||||
b5d3bbd9c5f3d376be43c75a32374b022adfb6566feeef14d30420c819566082 *i386-win32.pe/upx-3.91.exe
|
7664ed4ce00b962a21ca5654993c4c4cb2ec1afcf9dc921cd90862f8412572cc *i386-win32.pe/upx-3.91.exe
|
||||||
aa9d18c47e60a814d383a6778cf26654a2bea6a097520e7177d3c546a1421159 *i386-win32.pe/upx-3.95.exe
|
6ef354d0b2dffc71c32fc33f3f89b0b8ae7035e43e8a684a12d6ce2c53caf706 *i386-win32.pe/upx-3.95.exe
|
||||||
4ea046a2c8be33ed14531e30ccbd3440b9569e68abd76932a8837abf4abba553 *m68k-atari.tos/upx-3.91.ttp
|
5890050fe690bb93bf70693f1bef0e6ea708029836c7d8aa57de02b6aefe4239 *m68k-atari.tos/upx-3.91.ttp
|
||||||
eeb7ae0de5b423611989f948585a4fdb18926161927c8f99e137cb4ad5f464b0 *mips-linux.elf/upx-3.95
|
2bce2082ae39dedcc21a1a6c83e954073b368e9172ee0c7f2a3f13b3447a7898 *mips-linux.elf/upx-3.95
|
||||||
5f4433586e45651bacd01bca156090f06fa48e95a78077cc93d1b6bc9965e8d5 *mipsel-linux.elf/upx-3.91
|
d5b88d291a8a2141d9d9f07a6a21e11522e510c6520ba0c36ebf94d089962607 *mipsel-linux.elf/upx-3.91
|
||||||
d17b7488d441269f0427cf567fc6f5c43fbe32398860f0099d361b9d4672a2dc *mipsel-linux.elf/upx-3.95
|
ff42d564999e02346c86d4156266f423edd55b3887aadf76d81a8c355e3b175d *mipsel-linux.elf/upx-3.95
|
||||||
eca17f5f26c878c3f5ffee569ce5eb3af19127685ceb0bf7a419d13537e774a2 *powerpc-linux.elf/upx-3.91
|
f33205ad8252524d8c48d18cdb03bba507e29c9cc931f94327a5a46480f70843 *powerpc-linux.elf/upx-3.91
|
||||||
2ea98117f051c4f05292e2c5b71e9a1252ab32fe2dbb03e4f1106c765913cc4f *powerpc-linux.elf/upx-3.95
|
011683a891e30ea346efe9ba5c1488fb50f143e4090bd2be07537c696d6167db *powerpc-linux.elf/upx-3.95
|
||||||
fecfda8d1c58bfe2fe7a0d9d3806258129e449b25e5bf65418c364758c693e94 *powerpc64le-linux.elf/upx-3.95
|
9d919460b0ceec4b880cdf14850fea8096d6796c2457467b3cc9b2ce954cc6de *powerpc64le-linux.elf/upx-3.95
|
||||||
"
|
"
|
||||||
########## end .sha256sums.recreate
|
########## end .sha256sums.recreate
|
||||||
|
|||||||
@@ -1,40 +1,29 @@
|
|||||||
#! /bin/bash
|
#! /bin/bash
|
||||||
## vim:set ts=4 sw=4 et:
|
## vim:set ts=4 sw=4 et:
|
||||||
set -e; set -o pipefail
|
set -e; set -o pipefail
|
||||||
|
|
||||||
# Copyright (C) Markus Franz Xaver Johannes Oberhumer
|
|
||||||
|
|
||||||
#
|
|
||||||
# very first version of the upx-testsuite
|
|
||||||
#
|
|
||||||
|
|
||||||
if [[ $TRAVIS_OS_NAME == osx ]]; then
|
|
||||||
argv0=$0; argv0abs=$(greadlink -en -- "$0"); argv0dir=$(dirname "$argv0abs")
|
|
||||||
else
|
|
||||||
argv0=$0; argv0abs=$(readlink -en -- "$0"); argv0dir=$(dirname "$argv0abs")
|
argv0=$0; argv0abs=$(readlink -en -- "$0"); argv0dir=$(dirname "$argv0abs")
|
||||||
fi
|
|
||||||
source "$argv0dir/travis_init.sh" || exit 1
|
|
||||||
|
|
||||||
if [[ $BM_T =~ (^|\+)SKIP($|\+) ]]; then
|
# very first version of the upx-testsuite; requires:
|
||||||
echo "UPX testsuite SKIPPED."
|
# $upx_exe
|
||||||
exit 0
|
# $upx_testsuite_SRCDIR
|
||||||
fi
|
# $upx_testsuite_BUILDDIR (optional)
|
||||||
if [[ $BM_X == rebuild-stubs ]]; then
|
# $BM_T (optional)
|
||||||
exit 0
|
|
||||||
fi
|
|
||||||
|
|
||||||
# convenience
|
# convenience
|
||||||
|
[[ -z $upx_testsuite_BUILDDIR ]] && upx_testsuite_BUILDDIR=./tmp-upx-testsuite
|
||||||
[[ -f $upx_exe ]] && upx_exe=$(readlink -en -- "$upx_exe")
|
[[ -f $upx_exe ]] && upx_exe=$(readlink -en -- "$upx_exe")
|
||||||
|
|
||||||
# create dirs
|
# make dirs absolute
|
||||||
cd / || exit 1
|
upx_testsuite_SRCDIR=$(readlink -en -- "$upx_testsuite_SRCDIR")
|
||||||
if [[ ! -d "$upx_testsuite_SRCDIR/files/packed" ]]; then
|
if [[ ! -d "$upx_testsuite_SRCDIR/files/packed" ]]; then
|
||||||
echo 'invalid or missing $upx_testsuite_SRCDIR:'
|
echo 'invalid or missing $upx_testsuite_SRCDIR:'
|
||||||
echo ' please git clone https://github.com/upx/upx-testsuite'
|
echo ' please git clone https://github.com/upx/upx-testsuite'
|
||||||
echo ' and set (export) the envvar upx_testsuite_SRCDIR to the local file path'
|
echo ' and set (export) the envvar upx_testsuite_SRCDIR to the local file path'
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
mkbuilddirs "$upx_testsuite_BUILDDIR"
|
mkdir -p "$upx_testsuite_BUILDDIR"
|
||||||
|
upx_testsuite_BUILDDIR=$(readlink -en -- "$upx_testsuite_BUILDDIR")
|
||||||
|
|
||||||
cd / && cd "$upx_testsuite_BUILDDIR" || exit 1
|
cd / && cd "$upx_testsuite_BUILDDIR" || exit 1
|
||||||
|
|
||||||
# /***********************************************************************
|
# /***********************************************************************
|
||||||
@@ -148,8 +137,6 @@ if [[ $BM_T =~ (^|\+)ALLOW_FAIL($|\+) ]]; then
|
|||||||
set +e
|
set +e
|
||||||
fi
|
fi
|
||||||
|
|
||||||
[[ -z $upx_exe && -f $upx_BUILDDIR/upx.out ]] && upx_exe=$upx_BUILDDIR/upx.out
|
|
||||||
[[ -z $upx_exe && -f $upx_BUILDDIR/upx.exe ]] && upx_exe=$upx_BUILDDIR/upx.exe
|
|
||||||
if [[ -z $upx_exe ]]; then exit 1; fi
|
if [[ -z $upx_exe ]]; then exit 1; fi
|
||||||
upx_run=$upx_exe
|
upx_run=$upx_exe
|
||||||
if [[ $BM_T =~ (^|\+)qemu($|\+) && -n $upx_qemu ]]; then
|
if [[ $BM_T =~ (^|\+)qemu($|\+) && -n $upx_qemu ]]; then
|
||||||
@@ -170,10 +157,6 @@ if [[ $BM_T =~ (^|\+)valgrind($|\+) ]]; then
|
|||||||
upx_run="$upx_valgrind $upx_valgrind_flags $upx_exe"
|
upx_run="$upx_valgrind $upx_valgrind_flags $upx_exe"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [[ $BM_B =~ (^|\+)coverage($|\+) ]]; then
|
|
||||||
(cd / && cd "$upx_BUILDDIR" && lcov -d . --zerocounters)
|
|
||||||
fi
|
|
||||||
|
|
||||||
export UPX="--prefer-ucl --no-color --no-progress"
|
export UPX="--prefer-ucl --no-color --no-progress"
|
||||||
export UPX_DEBUG_DISABLE_GITREV_WARNING=1
|
export UPX_DEBUG_DISABLE_GITREV_WARNING=1
|
||||||
export UPX_DEBUG_DOCTEST_VERBOSE=0
|
export UPX_DEBUG_DOCTEST_VERBOSE=0
|
||||||
@@ -183,7 +166,7 @@ if ! $upx_run --version-short; then echo "UPX-ERROR: FATAL: upx --version-sho
|
|||||||
if ! $upx_run -L >/dev/null 2>&1; then echo "UPX-ERROR: FATAL: upx -L FAILED"; exit 1; fi
|
if ! $upx_run -L >/dev/null 2>&1; then echo "UPX-ERROR: FATAL: upx -L FAILED"; exit 1; fi
|
||||||
if ! $upx_run --help >/dev/null; then echo "UPX-ERROR: FATAL: upx --help FAILED"; exit 1; fi
|
if ! $upx_run --help >/dev/null; then echo "UPX-ERROR: FATAL: upx --help FAILED"; exit 1; fi
|
||||||
rm -rf ./testsuite_1
|
rm -rf ./testsuite_1
|
||||||
mkbuilddirs testsuite_1
|
mkdir testsuite_1
|
||||||
cd testsuite_1 || exit 1
|
cd testsuite_1 || exit 1
|
||||||
|
|
||||||
# /***********************************************************************
|
# /***********************************************************************
|
||||||
|
|||||||
+242
-76
@@ -1,5 +1,4 @@
|
|||||||
# Support for GitHub Actions -- https://github.com/features/actions
|
# Support for GitHub Actions -- https://github.com/features/actions
|
||||||
# Copyright (C) Markus Franz Xaver Johannes Oberhumer
|
|
||||||
|
|
||||||
# note: GitHub Actions runner images are frequently updated, and
|
# note: GitHub Actions runner images are frequently updated, and
|
||||||
# unfortunately this sometimes breaks builds in mysterious ways...
|
# unfortunately this sometimes breaks builds in mysterious ways...
|
||||||
@@ -7,16 +6,10 @@
|
|||||||
|
|
||||||
name: 'CI'
|
name: 'CI'
|
||||||
|
|
||||||
on:
|
on: [push, workflow_dispatch]
|
||||||
push:
|
|
||||||
branches:
|
|
||||||
- '*'
|
|
||||||
- '!appveyor*'
|
|
||||||
- '!gitlab*'
|
|
||||||
- '!travis*'
|
|
||||||
workflow_dispatch:
|
|
||||||
|
|
||||||
env:
|
env:
|
||||||
|
DEBIAN_FRONTEND: noninteractive
|
||||||
UPX_CMAKE_BUILD_FLAGS: --verbose
|
UPX_CMAKE_BUILD_FLAGS: --verbose
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
@@ -27,27 +20,30 @@ jobs:
|
|||||||
- name: 'Install extra packages'
|
- name: 'Install extra packages'
|
||||||
run: |
|
run: |
|
||||||
uname -a; pwd; id; umask
|
uname -a; pwd; id; umask
|
||||||
cd ..; mkdir -p deps; cd deps; mkdir packages
|
mkdir ../deps; cd ../deps; mkdir packages
|
||||||
# for ubuntu-22.04: install python2
|
# for ubuntu-22.04: install python2-minimal
|
||||||
##export DEBIAN_FRONTEND=noninteractive
|
##sudo apt-get update && sudo apt-get install -y --no-install-recommends python2-minimal
|
||||||
##sudo apt-get install -y --no-install-recommends python2-minimal
|
|
||||||
# manually install compat libs from Ubuntu 16.04
|
# manually install compat libs from Ubuntu 16.04
|
||||||
wget -q 'http://mirror.enzu.com/ubuntu/pool/main/g/gmp/libgmp10_6.1.0+dfsg-2_amd64.deb'
|
wget -q 'http://archive.kernel.org/ubuntu-archive/ubuntu/pool/main/m/mpfr4/libmpfr4_3.1.6-1_amd64.deb'
|
||||||
wget -q 'http://mirror.enzu.com/ubuntu/pool/main/m/mpfr4/libmpfr4_3.1.4-1_amd64.deb'
|
for f in ./*.deb; do dpkg -x $f ./packages; done
|
||||||
for f in *.deb; do dpkg -x $f ./packages; done
|
|
||||||
sudo mv -v -n ./packages/usr/lib/x86_64-linux-gnu/lib* /usr/lib/x86_64-linux-gnu/
|
sudo mv -v -n ./packages/usr/lib/x86_64-linux-gnu/lib* /usr/lib/x86_64-linux-gnu/
|
||||||
|
rm -rf ./*.deb ./packages
|
||||||
sudo ldconfig
|
sudo ldconfig
|
||||||
wget -q -O - https://github.com/upx/upx-stubtools/releases/download/v20210104/bin-upx-20210104.tar.xz | tar -xJ
|
wget -q -O - https://github.com/upx/upx-stubtools/releases/download/v20221212/bin-upx-20221212.tar.xz | tar -xJ
|
||||||
- name: 'Check out code'
|
- name: 'Check out code'
|
||||||
uses: actions/checkout@v3
|
uses: actions/checkout@v3
|
||||||
with: { submodules: true }
|
with: { submodules: true }
|
||||||
- name: 'Rebuild and verify stubs'
|
- name: 'Rebuild and verify stubs'
|
||||||
run: |
|
run: |
|
||||||
env C=gcc X=rebuild-stubs TRAVIS_OS_NAME=linux bash ./.github/travis_build.sh
|
export PATH="$(readlink -en ../deps/bin-upx-20221212):$PATH"
|
||||||
|
make -C src/stub maintainer-clean extra-clean
|
||||||
|
git status || true
|
||||||
|
make -C src/stub extra-all all
|
||||||
|
if ! git diff --quiet; then git diff; exit 1; fi
|
||||||
- name: 'Check source code formatting'
|
- name: 'Check source code formatting'
|
||||||
run: |
|
run: |
|
||||||
bash ./misc/scripts/check_whitespace_git.sh
|
bash ./misc/scripts/check_whitespace_git.sh
|
||||||
env UPX_CLANG_FORMAT="$PWD/../deps/bin-upx-20210104/clang-format-10.0.1" make -C src clang-format
|
UPX_CLANG_FORMAT="$PWD/../deps/bin-upx-20221212/clang-format-15.0.6" make -C src clang-format
|
||||||
if ! git diff --quiet; then git diff; exit 1; fi
|
if ! git diff --quiet; then git diff; exit 1; fi
|
||||||
|
|
||||||
job-linux-cmake:
|
job-linux-cmake:
|
||||||
@@ -58,25 +54,45 @@ jobs:
|
|||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
include:
|
include:
|
||||||
- { os: ubuntu-20.04 }
|
- { os: ubuntu-22.04, use_m32: true }
|
||||||
- { os: ubuntu-22.04 }
|
- { os: ubuntu-20.04, use_m32: false }
|
||||||
steps:
|
steps:
|
||||||
|
- name: 'Install extra 32-bit and Windows packages'
|
||||||
|
if: ${{ matrix.use_m32 }}
|
||||||
|
run: |
|
||||||
|
sudo dpkg --add-architecture i386
|
||||||
|
sudo apt-get update
|
||||||
|
sudo apt-get install -y g++-multilib g++-mingw-w64-i686 g++-mingw-w64-x86-64
|
||||||
- name: 'Check out code'
|
- name: 'Check out code'
|
||||||
uses: actions/checkout@v3
|
uses: actions/checkout@v3
|
||||||
with: { submodules: true }
|
with: { submodules: true }
|
||||||
- name: 'Build cmake debug-gcc'
|
- name: 'Check out test suite'
|
||||||
run: 'make build/debug-gcc'
|
run: 'git clone --depth=1 https://github.com/upx/upx-testsuite ../deps/upx-testsuite'
|
||||||
- name: 'Build cmake release-gcc'
|
- name: 'Build cmake extra/gcc/debug'
|
||||||
run: 'make build/release-gcc'
|
run: 'make build/extra/gcc/debug'
|
||||||
- name: 'Build cmake debug-clang'
|
- name: 'Build cmake extra/gcc/release'
|
||||||
run: 'make build/debug-clang'
|
run: 'make build/extra/gcc/release'
|
||||||
- name: 'Build cmake release-clang'
|
- name: 'Build cmake extra/clang/debug'
|
||||||
run: 'make build/release-clang'
|
run: 'make build/extra/clang/debug'
|
||||||
|
- name: 'Build cmake extra/clang/release'
|
||||||
|
run: 'make build/extra/clang/release'
|
||||||
|
- name: 'Build cmake extra/gcc-m32/debug'
|
||||||
|
if: ${{ matrix.use_m32 }}
|
||||||
|
run: 'make build/extra/gcc-m32/debug'
|
||||||
|
- name: 'Build cmake extra/gcc-m32/release'
|
||||||
|
if: ${{ matrix.use_m32 }}
|
||||||
|
run: 'make build/extra/gcc-m32/release'
|
||||||
|
- name: 'Build cmake extra/cross-windows-mingw32/release'
|
||||||
|
if: ${{ matrix.use_m32 }}
|
||||||
|
run: 'make build/extra/cross-windows-mingw32/release'
|
||||||
|
- name: 'Build cmake extra/cross-windows-mingw64/release'
|
||||||
|
if: ${{ matrix.use_m32 }}
|
||||||
|
run: 'make build/extra/cross-windows-mingw64/release'
|
||||||
- name: 'Make artifact'
|
- name: 'Make artifact'
|
||||||
run: |
|
run: |
|
||||||
N=upx-${GITHUB_REF_NAME}-${GITHUB_SHA:0:7}-${{ matrix.os }}
|
N=upx-${GITHUB_REF_NAME}-${GITHUB_SHA:0:7}-${{ matrix.os }}
|
||||||
mkdir -p "tmp/artifact/$N"
|
mkdir -p "tmp/artifact/$N"
|
||||||
(cd build && cp -ai --parents */upx "../tmp/artifact/$N")
|
(cd build && shopt -s nullglob && cp -ai --parents */upx{,.exe} */*/*/upx{,.exe} "../tmp/artifact/$N")
|
||||||
(cd tmp/artifact && tar --sort=name -czf "$N.tar.gz" "$N" && rm -rf "./$N")
|
(cd tmp/artifact && tar --sort=name -czf "$N.tar.gz" "$N" && rm -rf "./$N")
|
||||||
# GitHub Actions magic: set "artifact_name" environment value for use in next step
|
# GitHub Actions magic: set "artifact_name" environment value for use in next step
|
||||||
echo "artifact_name=$N" >> $GITHUB_ENV
|
echo "artifact_name=$N" >> $GITHUB_ENV
|
||||||
@@ -87,10 +103,20 @@ jobs:
|
|||||||
path: tmp/artifact
|
path: tmp/artifact
|
||||||
- name: 'Run basic tests'
|
- name: 'Run basic tests'
|
||||||
run: |
|
run: |
|
||||||
make -C build/debug-gcc test
|
make -C build/extra/gcc/debug test
|
||||||
make -C build/release-gcc test
|
make -C build/extra/gcc/release test
|
||||||
make -C build/debug-clang test
|
make -C build/extra/clang/debug test
|
||||||
make -C build/release-clang test
|
make -C build/extra/clang/release test
|
||||||
|
- name: 'Run basic tests 32-bit'
|
||||||
|
if: ${{ matrix.use_m32 }}
|
||||||
|
run: |
|
||||||
|
make -C build/extra/gcc-m32/debug test
|
||||||
|
make -C build/extra/gcc-m32/release test
|
||||||
|
- name: 'Run test suite build/extra/gcc/release'
|
||||||
|
run: |
|
||||||
|
export upx_testsuite_SRCDIR="$(readlink -en ../deps/upx-testsuite)"
|
||||||
|
testsuite_1=$(readlink -en ./.github/travis_testsuite_1.sh)
|
||||||
|
env -C build/extra/gcc/release upx_exe=./upx bash "$testsuite_1"
|
||||||
|
|
||||||
job-macos-cmake:
|
job-macos-cmake:
|
||||||
needs: [ job-rebuild-and-verify-stubs ]
|
needs: [ job-rebuild-and-verify-stubs ]
|
||||||
@@ -100,28 +126,43 @@ jobs:
|
|||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
include:
|
include:
|
||||||
- { os: macos-11, gcc: gcc-10, gxx: 'g++-10' }
|
- { os: macos-11, gcc: gcc-10, gxx: 'g++-10', testsuite: true }
|
||||||
# { os: macos-12, gcc: gcc-11, gxx: 'g++-11' } # disable gcc - XCode 14.0 ld bug
|
- { os: macos-12, gcc: gcc-11, gxx: 'g++-11', testsuite: true }
|
||||||
- { os: macos-12 }
|
|
||||||
steps:
|
steps:
|
||||||
|
- name: 'Install brew packages'
|
||||||
|
if: ${{ matrix.testsuite }}
|
||||||
|
run: |
|
||||||
|
brew update
|
||||||
|
brew install coreutils
|
||||||
- name: 'Check out code'
|
- name: 'Check out code'
|
||||||
uses: actions/checkout@v3
|
uses: actions/checkout@v3
|
||||||
with: { submodules: true }
|
with: { submodules: true }
|
||||||
- name: 'Build cmake debug-gcc'
|
- name: 'Check out test suite'
|
||||||
|
if: ${{ matrix.testsuite }}
|
||||||
|
run: 'git clone --depth=1 https://github.com/upx/upx-testsuite ../deps/upx-testsuite'
|
||||||
|
- name: 'Build cmake extra/clang/debug'
|
||||||
|
run: 'make build/extra/clang/debug'
|
||||||
|
- name: 'Build cmake extra/clang/release'
|
||||||
|
run: 'make build/extra/clang/release'
|
||||||
|
- name: 'Build cmake extra/gcc/debug'
|
||||||
if: ${{ matrix.gcc != '' }}
|
if: ${{ matrix.gcc != '' }}
|
||||||
run: 'make build/debug-gcc CC=${{ matrix.gcc }} CXX=${{ matrix.gxx }}'
|
run: 'make build/extra/gcc/debug CC=${{ matrix.gcc }} CXX=${{ matrix.gxx }}'
|
||||||
- name: 'Build cmake release-gcc'
|
- name: 'Build cmake extra/gcc/release'
|
||||||
if: ${{ matrix.gcc != '' }}
|
if: ${{ matrix.gcc != '' }}
|
||||||
run: 'make build/release-gcc CC=${{ matrix.gcc }} CXX=${{ matrix.gxx }}'
|
run: 'make build/extra/gcc/release CC=${{ matrix.gcc }} CXX=${{ matrix.gxx }}'
|
||||||
- name: 'Build cmake debug-clang'
|
- name: 'Build cmake xtarget/cross-darwin-arm64/debug'
|
||||||
run: 'make build/debug-clang'
|
run: |
|
||||||
- name: 'Build cmake release-clang'
|
CC="clang -target arm64-apple-darwin" CXX="clang++ -target arm64-apple-darwin" \
|
||||||
run: 'make build/release-clang'
|
make UPX_XTARGET=cross-darwin-arm64 xtarget/debug
|
||||||
|
- name: 'Build cmake xtarget/cross-darwin-arm64/release'
|
||||||
|
run: |
|
||||||
|
CC="clang -target arm64-apple-darwin" CXX="clang++ -target arm64-apple-darwin" \
|
||||||
|
make UPX_XTARGET=cross-darwin-arm64 xtarget/release
|
||||||
- name: 'Make artifact'
|
- name: 'Make artifact'
|
||||||
run: |
|
run: |
|
||||||
N=upx-${GITHUB_REF_NAME}-${GITHUB_SHA:0:7}-${{ matrix.os }}
|
N=upx-${GITHUB_REF_NAME}-${GITHUB_SHA:0:7}-${{ matrix.os }}
|
||||||
mkdir -p "tmp/artifact/$N"
|
mkdir -p "tmp/artifact/$N"
|
||||||
(cd build && rsync -R -a */upx "../tmp/artifact/$N/")
|
(cd build && rsync -R -a */*/*/upx "../tmp/artifact/$N/")
|
||||||
(cd tmp/artifact && gtar --sort=name -czf "$N.tar.gz" "$N" && rm -rf "./$N")
|
(cd tmp/artifact && gtar --sort=name -czf "$N.tar.gz" "$N" && rm -rf "./$N")
|
||||||
# GitHub Actions magic: set "artifact_name" environment value for use in next step
|
# GitHub Actions magic: set "artifact_name" environment value for use in next step
|
||||||
echo "artifact_name=$N" >> $GITHUB_ENV
|
echo "artifact_name=$N" >> $GITHUB_ENV
|
||||||
@@ -132,8 +173,15 @@ jobs:
|
|||||||
path: tmp/artifact
|
path: tmp/artifact
|
||||||
- name: 'Run basic tests'
|
- name: 'Run basic tests'
|
||||||
run: |
|
run: |
|
||||||
make -C build/debug-clang test
|
make -C build/extra/clang/debug test
|
||||||
make -C build/release-clang test
|
make -C build/extra/clang/release test
|
||||||
|
- name: 'Run test suite build/extra/clang/release'
|
||||||
|
if: ${{ matrix.testsuite }}
|
||||||
|
run: |
|
||||||
|
export PATH="/usr/local/opt/coreutils/libexec/gnubin:$PATH"
|
||||||
|
export upx_testsuite_SRCDIR="$(readlink -en ../deps/upx-testsuite)"
|
||||||
|
testsuite_1=$(readlink -en ./.github/travis_testsuite_1.sh)
|
||||||
|
env -C build/extra/clang/release upx_exe=./upx bash "$testsuite_1"
|
||||||
|
|
||||||
job-windows-cmake:
|
job-windows-cmake:
|
||||||
needs: [ job-rebuild-and-verify-stubs ]
|
needs: [ job-rebuild-and-verify-stubs ]
|
||||||
@@ -143,8 +191,9 @@ jobs:
|
|||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
include:
|
include:
|
||||||
# windows-2019 used to work but got broken with the 20220821.1
|
# windows-2019 used to work but got broken with the 20220821.1 runner-image
|
||||||
# runner-image update; disable for now
|
# update; we cannot download that image for inspection, and debugging the
|
||||||
|
# remote image is painful, so disable for now
|
||||||
# see https://github.com/actions/runner-images.git
|
# see https://github.com/actions/runner-images.git
|
||||||
####- { os: windows-2019 }
|
####- { os: windows-2019 }
|
||||||
- { os: windows-2022 }
|
- { os: windows-2022 }
|
||||||
@@ -152,8 +201,10 @@ jobs:
|
|||||||
- name: 'Check out code'
|
- name: 'Check out code'
|
||||||
uses: actions/checkout@v3
|
uses: actions/checkout@v3
|
||||||
with: { submodules: true }
|
with: { submodules: true }
|
||||||
|
- name: 'Check out test suite'
|
||||||
|
run: 'git clone --depth=1 https://github.com/upx/upx-testsuite ../deps/upx-testsuite'
|
||||||
- name: 'Inspect runner-image settings'
|
- name: 'Inspect runner-image settings'
|
||||||
# see https://github.com/actions/runner-images.git
|
# debug remote image; also see https://github.com/actions/runner-images.git
|
||||||
if: ${{ false }}
|
if: ${{ false }}
|
||||||
run: |
|
run: |
|
||||||
Get-Command bash; Get-Command cmake; Get-Command make
|
Get-Command bash; Get-Command cmake; Get-Command make
|
||||||
@@ -180,71 +231,81 @@ jobs:
|
|||||||
run: |
|
run: |
|
||||||
cmake --build build/debug --config Debug --target RUN_TESTS
|
cmake --build build/debug --config Debug --target RUN_TESTS
|
||||||
cmake --build build/release --config Release --target RUN_TESTS
|
cmake --build build/release --config Release --target RUN_TESTS
|
||||||
|
- name: 'Run test suite build/release'
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
export upx_testsuite_SRCDIR="$(readlink -en ../deps/upx-testsuite)"
|
||||||
|
testsuite_1=$(readlink -en ./.github/travis_testsuite_1.sh)
|
||||||
|
env -C build/release/Release upx_exe=./upx bash "$testsuite_1"
|
||||||
|
|
||||||
job-windows-toolchains:
|
job-windows-toolchains:
|
||||||
needs: [ job-rebuild-and-verify-stubs ]
|
needs: [ job-rebuild-and-verify-stubs ]
|
||||||
name: ${{ matrix.name }}
|
name: ${{ format('windows {0}', matrix.name) }}
|
||||||
runs-on: ${{ matrix.os }}
|
runs-on: ${{ matrix.os }}
|
||||||
env:
|
env:
|
||||||
C: ${{ matrix.C }}
|
C: ${{ matrix.C }}
|
||||||
B: release
|
B: release
|
||||||
H: 'd:\a\upx'
|
H: 'd:\a\upx\upx'
|
||||||
strategy:
|
strategy:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
include:
|
include:
|
||||||
- { name: amd64-win64-msvc-14.2, os: windows-2019, C: msvc-14.2-x64, A: x64 }
|
- { name: amd64-win64-vs2019, os: windows-2019, C: msvc-14.2-x64, arch: amd64 }
|
||||||
- { name: amd64-win64-msvc-14.3, os: windows-2022, C: msvc-14.3-x64, A: x64 }
|
- { name: amd64-win64-vs2022, os: windows-2022, C: msvc-14.3-x64, arch: amd64 }
|
||||||
- { name: i386-win32-msvc-14.2, os: windows-2019, C: msvc-14.2-x86, A: x86 }
|
- { name: arm64-win64-vs2019, os: windows-2019, C: msvc-14.2-x64, arch: amd64_arm64 }
|
||||||
- { name: i386-win32-msvc-14.3, os: windows-2022, C: msvc-14.3-x86, A: x86 }
|
- { name: arm64-win64-vs2022, os: windows-2022, C: msvc-14.3-x64, arch: amd64_arm64 }
|
||||||
|
- { name: i386-win32-vs2019, os: windows-2019, C: msvc-14.2-x86, arch: amd64_x86 }
|
||||||
|
- { name: i386-win32-vs2022, os: windows-2022, C: msvc-14.3-x86, arch: amd64_x86 }
|
||||||
steps:
|
steps:
|
||||||
- name: 'Check out code'
|
- name: 'Check out code'
|
||||||
uses: actions/checkout@v3
|
uses: actions/checkout@v3
|
||||||
with: { submodules: true }
|
with: { submodules: true }
|
||||||
- name: 'Prepare sources'
|
- name: 'Prepare sources and Check out test suite'
|
||||||
shell: cmd
|
shell: bash
|
||||||
run: |
|
run: |
|
||||||
where bash & where cat & where chmod & where cmp & where cp & where curl & where date & where file & where git & where gzip & where mkdir & where mv & where openssl & where readlink & where rm & where rmdir & where sed & where sha256sum & where sort & where ssh & where ssh-add & where ssh-agent & where ssh-keyscan & where tar & where touch
|
|
||||||
git config --global core.autocrlf input
|
git config --global core.autocrlf input
|
||||||
git --version & bash --version
|
git --version && bash --version
|
||||||
cd %H%
|
git clone --depth=1 https://github.com/upx/upx-testsuite ../deps/upx-testsuite
|
||||||
md build build\%C% deps
|
mkdir -p -v build/$C/$B/{ucl,upx,zlib,zstd}
|
||||||
cd deps
|
|
||||||
git clone --depth=1 https://github.com/upx/upx-testsuite
|
|
||||||
- name: 'Set up Developer Command Prompt'
|
- name: 'Set up Developer Command Prompt'
|
||||||
uses: ilammy/msvc-dev-cmd@v1
|
uses: ilammy/msvc-dev-cmd@v1
|
||||||
with:
|
with:
|
||||||
arch: ${{ matrix.A }}
|
arch: ${{ matrix.arch }}
|
||||||
- name: 'Build'
|
- name: 'Build'
|
||||||
shell: cmd
|
shell: cmd
|
||||||
run: |
|
run: |
|
||||||
@REM setup directories following the VPATH build in travis_build.sh
|
@REM setup directories
|
||||||
where cl & where link
|
where cl & where link
|
||||||
set BDIR=%H%\build\%C%\%B%
|
set BDIR=%H%\build\%C%\%B%
|
||||||
md %BDIR% %BDIR%\ucl %BDIR%\upx %BDIR%\upx-testsuite %BDIR%\zlib
|
|
||||||
set DEFS=-D_CRT_NONSTDC_NO_WARNINGS -D_CRT_SECURE_NO_WARNINGS
|
set DEFS=-D_CRT_NONSTDC_NO_WARNINGS -D_CRT_SECURE_NO_WARNINGS
|
||||||
git rev-parse --short=12 HEAD > %BDIR%\upx\.GITREV.txt
|
git rev-parse --short=12 HEAD > %BDIR%\upx\.GITREV.txt
|
||||||
@REM ===== build UCL =====
|
@REM ===== build UCL =====
|
||||||
cd %BDIR%\ucl
|
cd %BDIR%\ucl
|
||||||
set s=%H%\upx\vendor\ucl
|
set s=%H%\vendor\ucl
|
||||||
cl -MT -J -O2 -W4 %DEFS% -I%s%\include -I%s% -c %s%\src\*.c
|
cl -MT -J -O2 -W4 -WX %DEFS% -I%s%\include -I%s% -c %s%\src\*.c
|
||||||
link -lib -out:ucl.lib *.obj
|
link -lib -out:ucl.lib *.obj
|
||||||
@REM ===== build zlib =====
|
@REM ===== build zlib =====
|
||||||
cd %BDIR%\zlib
|
cd %BDIR%\zlib
|
||||||
cl -MT -J -O2 -W3 %DEFS% -c %H%\upx\vendor\zlib\*.c
|
cl -MT -J -O2 -W3 -WX %DEFS% -c %H%\vendor\zlib\*.c
|
||||||
link -lib -out:zlib.lib *.obj
|
link -lib -out:zlib.lib *.obj
|
||||||
|
@REM ===== build zstd =====
|
||||||
|
@rem cd %BDIR%\zstd
|
||||||
|
@rem set s=%H%\vendor\zstd\lib
|
||||||
|
@rem cl -MT -J -O2 -W4 -WX -DDYNAMIC_BMI2=0 -DZSTD_DISABLE_ASM %DEFS% -c %s%\common\*.c %s%\compress\*.c %s%\decompress\*.c
|
||||||
|
@rem link -lib -out:zstd.lib *.obj
|
||||||
@REM ===== build UPX =====
|
@REM ===== build UPX =====
|
||||||
cd %BDIR%\upx
|
cd %BDIR%\upx
|
||||||
set s=%H%\upx\src
|
set s=%H%\src
|
||||||
cat .GITREV.txt
|
cat .GITREV.txt
|
||||||
set /p GITREV=<.GITREV.txt
|
set /p GITREV=<.GITREV.txt
|
||||||
cl -MT -EHsc -J -O2 -W4 -WX -DUPX_VERSION_GITREV="""%GITREV%""" %DEFS% -I%H%\upx\vendor -Feupx.exe %s%\*.cpp %s%\util\*.cpp %BDIR%\ucl\ucl.lib %BDIR%\zlib\zlib.lib /link setargv.obj
|
set sources=%s%\*.cpp %s%\check\*.cpp %s%\compress\*.cpp %s%\console\*.cpp %s%\filter\*.cpp %s%\util\*.cpp
|
||||||
|
cl -MT -std:c++17 -Zc:__cplusplus -EHsc -J -O2 -W4 -WX -DUPX_VERSION_GITREV="""%GITREV%""" -DWITH_ZSTD=0 %DEFS% -I%H%\vendor -I%H%\vendor\boost-pfr\include -Feupx.exe %sources% %BDIR%\ucl\ucl.lib %BDIR%\zlib\zlib.lib /link setargv.obj
|
||||||
- name: 'Make artifact'
|
- name: 'Make artifact'
|
||||||
shell: bash
|
shell: bash
|
||||||
run: |
|
run: |
|
||||||
N=upx-${GITHUB_REF_NAME}-${GITHUB_SHA:0:7}-${{ matrix.name }}
|
N=upx-${GITHUB_REF_NAME}-${GITHUB_SHA:0:7}-windows-${{ matrix.name }}
|
||||||
mkdir -p "tmp/artifact/$N/$B"
|
mkdir -p "tmp/artifact/$N/$B"
|
||||||
cp -ai ../build/$C/$B/upx/upx*.exe "tmp/artifact/$N/$B"
|
cp -ai build/$C/$B/upx/upx*.exe "tmp/artifact/$N/$B"
|
||||||
# GitHub Actions magic: set "artifact_name" environment value for use in next step
|
# GitHub Actions magic: set "artifact_name" environment value for use in next step
|
||||||
echo "artifact_name=$N" >> $GITHUB_ENV
|
echo "artifact_name=$N" >> $GITHUB_ENV
|
||||||
- name: ${{ format('Upload artifact {0}', env.artifact_name) }}
|
- name: ${{ format('Upload artifact {0}', env.artifact_name) }}
|
||||||
@@ -253,6 +314,7 @@ jobs:
|
|||||||
name: ${{ env.artifact_name }}
|
name: ${{ env.artifact_name }}
|
||||||
path: tmp/artifact
|
path: tmp/artifact
|
||||||
- name: 'Run basic tests'
|
- name: 'Run basic tests'
|
||||||
|
if: ${{ matrix.arch != 'amd64_arm64' }}
|
||||||
run: |
|
run: |
|
||||||
$ErrorActionPreference = 'stop'
|
$ErrorActionPreference = 'stop'
|
||||||
$ErrorView = 'NormalView'
|
$ErrorView = 'NormalView'
|
||||||
@@ -265,7 +327,111 @@ jobs:
|
|||||||
.\upx.exe -t upx_packed.exe
|
.\upx.exe -t upx_packed.exe
|
||||||
.\upx_packed.exe --version
|
.\upx_packed.exe --version
|
||||||
- name: 'Run test suite'
|
- name: 'Run test suite'
|
||||||
|
if: ${{ matrix.arch != 'amd64_arm64' }}
|
||||||
|
shell: bash
|
||||||
run: |
|
run: |
|
||||||
bash ./.github/travis_testsuite_1.sh
|
export upx_testsuite_SRCDIR="$(readlink -en ../deps/upx-testsuite)"
|
||||||
|
testsuite_1=$(readlink -en ./.github/travis_testsuite_1.sh)
|
||||||
|
env -C build/$C/$B/upx upx_exe=./upx.exe bash "$testsuite_1"
|
||||||
|
|
||||||
|
job-linux-zigcc:
|
||||||
|
if: ${{ true }}
|
||||||
|
needs: [ job-rebuild-and-verify-stubs ]
|
||||||
|
name: ${{ format('zigcc {0} {1}', matrix.zig_target, matrix.zig_pic) }}
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
##container: alpine:3.17 # older versions such as alpine:3.12 also work; no-container also works
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
include:
|
||||||
|
- { zig_target: aarch64-linux-musl }
|
||||||
|
- { zig_target: aarch64-macos.11-none }
|
||||||
|
- { zig_target: aarch64-macos.12-none }
|
||||||
|
- { zig_target: aarch64-macos.13-none }
|
||||||
|
- { zig_target: aarch64-windows-gnu }
|
||||||
|
- { zig_target: i386-linux-musl }
|
||||||
|
- { zig_target: i386-windows-gnu }
|
||||||
|
- { zig_target: x86_64-linux-musl }
|
||||||
|
- { zig_target: x86_64-linux-musl, zig_pic: -fPIE }
|
||||||
|
- { zig_target: x86_64-macos.11-none }
|
||||||
|
- { zig_target: x86_64-macos.12-none }
|
||||||
|
- { zig_target: x86_64-macos.13-none }
|
||||||
|
- { zig_target: x86_64-windows-gnu }
|
||||||
|
env:
|
||||||
|
# 2023-01-30
|
||||||
|
ZIG_DIST_VERSION: 0.11.0-dev.1491+2b27bc2c6
|
||||||
|
# for zig-cc wrapper scripts (see below):
|
||||||
|
ZIG_CPPFLAGS: -DUPX_DOCTEST_CONFIG_MULTITHREADING
|
||||||
|
ZIG_FLAGS: ${{ matrix.zig_flags }}
|
||||||
|
ZIG_PIC: ${{ matrix.zig_pic }}
|
||||||
|
ZIG_TARGET: ${{ matrix.zig_target }}
|
||||||
|
steps:
|
||||||
|
- name: 'Install Alpine Linux container packages'
|
||||||
|
if: ${{ job.container }}
|
||||||
|
shell: sh
|
||||||
|
run: |
|
||||||
|
apk update && apk upgrade && apk add bash cmake file git make tar xz
|
||||||
|
# set PATH like in Ubuntu
|
||||||
|
echo "PATH=$HOME/.local/bin:$PATH" >> $GITHUB_ENV
|
||||||
|
# this seems to be needed when running in a container (beause of UID mismatch??)
|
||||||
|
git config --global --add safe.directory '*'
|
||||||
|
- name: 'Check out code'
|
||||||
|
uses: actions/checkout@v3
|
||||||
|
with: { submodules: true }
|
||||||
|
- name: ${{ format('Install Zig {0}', env.ZIG_DIST_VERSION) }}
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
# GitHub Actions magic: set "UPX_GITREV_SHORT" environment value for use in steps below
|
||||||
|
rev=$(git rev-parse --short=7 HEAD)
|
||||||
|
echo "UPX_GITREV_SHORT=$rev" >> $GITHUB_ENV
|
||||||
|
# update ZIG_TARGET (i386 => x86)
|
||||||
|
ZIG_TARGET=${ZIG_TARGET/i386-/x86-}
|
||||||
|
echo "ZIG_TARGET=$ZIG_TARGET" >> $GITHUB_ENV
|
||||||
|
# install zig; note that ~/.local/bin is included in the default $PATH on Ubuntu
|
||||||
|
mkdir -p -v ~/.local/bin
|
||||||
|
cd ~/.local/bin
|
||||||
|
ZIG_DIST_NAME=zig-linux-x86_64-${ZIG_DIST_VERSION}
|
||||||
|
wget -q 'https://ziglang.org/builds/'${ZIG_DIST_NAME}.tar.xz
|
||||||
|
ls -l ${ZIG_DIST_NAME}.tar.xz
|
||||||
|
tar -xoJf ${ZIG_DIST_NAME}.tar.xz
|
||||||
|
rm ${ZIG_DIST_NAME}.tar.xz
|
||||||
|
ln -s -v ${ZIG_DIST_NAME}/zig zig
|
||||||
|
#echo "PATH=$PATH" && which zig
|
||||||
|
echo -n 'zig version: '; zig version
|
||||||
|
# create wrapper scripts (needed for CMake)
|
||||||
|
echo -e '#!/bin/sh\nexec zig ar "$@"' > zig-ar
|
||||||
|
echo -e '#!/bin/sh\nexec zig cc -target $ZIG_TARGET $ZIG_PIC $ZIG_FLAGS $ZIG_CPPFLAGS $ZIG_CFLAGS "$@"' > zig-cc
|
||||||
|
echo -e '#!/bin/sh\nexec zig c++ -target $ZIG_TARGET $ZIG_PIC $ZIG_FLAGS $ZIG_CPPFLAGS $ZIG_CXXFLAGS "$@"' > zig-cxx
|
||||||
|
echo -e '#!/bin/sh\nexec zig ranlib "$@"' > zig-ranlib
|
||||||
|
chmod +x zig-ar zig-cc zig-cxx zig-ranlib
|
||||||
|
ls -la; head zig-ar zig-cc zig-cxx zig-ranlib
|
||||||
|
- name: ${{ format('Build Release with zig-cc -target {0} {1}', env.ZIG_TARGET, env.ZIG_PIC) }}
|
||||||
|
run: |
|
||||||
|
mkdir -p build/zig/${ZIG_TARGET}${ZIG_PIC}/release
|
||||||
|
cd build/zig/${ZIG_TARGET}${ZIG_PIC}/release
|
||||||
|
cmake ../../../.. -DCMAKE_BUILD_TYPE=Release -DCMAKE_AR=$HOME/.local/bin/zig-ar -DCMAKE_C_COMPILER=zig-cc -DCMAKE_CXX_COMPILER=zig-cxx -DCMAKE_RANLIB=$HOME/.local/bin/zig-ranlib $EXTRA_CMAKE_CONFIG_FLAGS_RELEASE
|
||||||
|
cmake --build . --config Release --parallel --verbose
|
||||||
|
file ./upx*
|
||||||
|
- name: ${{ format('Build Debug with zig-cc -target {0} {1}', env.ZIG_TARGET, env.ZIG_PIC) }}
|
||||||
|
run: |
|
||||||
|
mkdir -p build/zig/${ZIG_TARGET}${ZIG_PIC}/debug
|
||||||
|
cd build/zig/${ZIG_TARGET}${ZIG_PIC}/debug
|
||||||
|
cmake ../../../.. -DCMAKE_BUILD_TYPE=Debug -DCMAKE_AR=$HOME/.local/bin/zig-ar -DCMAKE_C_COMPILER=zig-cc -DCMAKE_CXX_COMPILER=zig-cxx -DCMAKE_RANLIB=$HOME/.local/bin/zig-ranlib $EXTRA_CMAKE_CONFIG_FLAGS_DEBUG
|
||||||
|
cmake --build . --config Debug --parallel --verbose
|
||||||
|
file ./upx*
|
||||||
|
- name: ${{ format('Make artifact from upx-{0}-{1}', github.ref_name, env.UPX_GITREV_SHORT) }}
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
N=upx-${GITHUB_REF_NAME}-${GITHUB_SHA:0:7}-zigcc-${{ matrix.zig_target }}${ZIG_PIC}
|
||||||
|
mkdir -p "tmp/artifact/$N"
|
||||||
|
(cd build && shopt -s nullglob && cp -ai --parents */upx{,.exe} */*/*/upx{,.exe} "../tmp/artifact/$N")
|
||||||
|
(cd tmp/artifact && tar --sort=name -czf "$N.tar.gz" "$N" && rm -rf "./$N")
|
||||||
|
# GitHub Actions magic: set "artifact_name" environment value for use in next step
|
||||||
|
echo "artifact_name=$N" >> $GITHUB_ENV
|
||||||
|
- name: ${{ format('Upload artifact {0}', env.artifact_name) }}
|
||||||
|
uses: actions/upload-artifact@v3
|
||||||
|
with:
|
||||||
|
name: ${{ env.artifact_name }}
|
||||||
|
path: tmp/artifact
|
||||||
|
|
||||||
# vim:set ts=2 sw=2 et:
|
# vim:set ts=2 sw=2 et:
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
# see https://docs.github.com/en/actions/managing-issues-and-pull-requests/closing-inactive-issues
|
# see https://docs.github.com/en/actions/managing-issues-and-pull-requests/closing-inactive-issues
|
||||||
# see https://github.com/actions/stale
|
# see https://github.com/actions/stale
|
||||||
|
|
||||||
# Automatically closing issues is far from perfect, but then we only have
|
# Automatically closing issues is far from perfect, but then we only
|
||||||
# limited resources and this approach favors issues that people
|
# have limited resources and this approach favors issues that people
|
||||||
# actually care about.
|
# actually care about.
|
||||||
#
|
#
|
||||||
# also see:
|
# also see:
|
||||||
@@ -10,10 +10,10 @@
|
|||||||
# Abandoned Issues and Pull Request".
|
# Abandoned Issues and Pull Request".
|
||||||
# https://igorwiese.com/images/papers/Paper_BotSE_19.pdf
|
# https://igorwiese.com/images/papers/Paper_BotSE_19.pdf
|
||||||
|
|
||||||
name: 'Close inactive issues'
|
name: 'GitHub - Close inactive issues'
|
||||||
on:
|
on:
|
||||||
schedule:
|
schedule:
|
||||||
- cron: "30 6 * * 4"
|
- cron: '30 6 * * 4'
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
jobs:
|
jobs:
|
||||||
close-issues:
|
close-issues:
|
||||||
@@ -23,9 +23,11 @@ jobs:
|
|||||||
issues: write
|
issues: write
|
||||||
pull-requests: write
|
pull-requests: write
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/stale@v6
|
- uses: actions/stale@v7
|
||||||
with:
|
with:
|
||||||
# operations-per-run: 300
|
operations-per-run: 300
|
||||||
|
exempt-all-milestones: true
|
||||||
|
exempt-issue-labels: 'blocker,enhancement,regression'
|
||||||
days-before-stale: 60
|
days-before-stale: 60
|
||||||
days-before-close: 30
|
days-before-close: 30
|
||||||
stale-issue-message: 'This issue is stale because it has been open 60 days with no activity. Please remove the stale label or add a comment or this issue will be closed in 30 days.'
|
stale-issue-message: 'This issue is stale because it has been open 60 days with no activity. Please remove the stale label or add a comment or this issue will be closed in 30 days.'
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
name: "CodeQL"
|
name: 'Static Analyzer - CodeQL'
|
||||||
|
|
||||||
on:
|
on:
|
||||||
push:
|
# push:
|
||||||
branches: [ "devel", "devel4", "devel5", "master" ]
|
# branches: [ 'devel', 'devel4', 'devel5', 'master' ]
|
||||||
pull_request:
|
# pull_request:
|
||||||
# The branches below must be a subset of the branches above
|
# # The branches below must be a subset of the branches above
|
||||||
branches: [ "devel", "devel4", "devel5" ]
|
# branches: [ 'devel', 'devel4', 'devel5' ]
|
||||||
schedule:
|
schedule:
|
||||||
- cron: '20 1 * * 3'
|
- cron: '20 1 * * 3'
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
|
|||||||
@@ -0,0 +1,29 @@
|
|||||||
|
# minimal GitHub CI building UPX with clang and gcc in an Alpine Linux container
|
||||||
|
|
||||||
|
name: 'CI - Minimal CI with Alpine Linux'
|
||||||
|
|
||||||
|
on: { workflow_dispatch: }
|
||||||
|
jobs:
|
||||||
|
job-alpine-cmake:
|
||||||
|
strategy: {matrix: {container: ['alpine:3.12','alpine:3.17','alpine:edge']}}
|
||||||
|
name: ${{ format('container {0}', matrix.container) }}
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
container: ${{ matrix.container }}
|
||||||
|
steps:
|
||||||
|
- name: ${{ format('Install packages {0}', matrix.container) }}
|
||||||
|
run: 'apk update && apk upgrade && apk add bash clang cmake g++ git make'
|
||||||
|
- name: ${{ format('Check out code upx-{0}', github.ref_name) }}
|
||||||
|
run: |
|
||||||
|
git clone --branch "$GITHUB_REF_NAME" --depth 1 https://github.com/upx/upx
|
||||||
|
git -C upx submodule update --init
|
||||||
|
echo "artifact_name=upx-${GITHUB_REF_NAME}-${GITHUB_SHA:0:7}-minimal-ci-${{ matrix.container }}" | sed 's/[:,; ]/-/g' >> $GITHUB_ENV
|
||||||
|
- { name: 'Build clang', run: 'make -C upx UPX_XTARGET=clang-static CC="clang -static" CXX="clang++ -static"' }
|
||||||
|
- { name: 'Build gcc', run: 'make -C upx UPX_XTARGET=gcc-static CC="gcc -static" CXX="g++ -static"' }
|
||||||
|
- { name: 'Strip release binaries', run: 'strip -p --strip-unneeded upx/build/*/*/release/upx' }
|
||||||
|
- name: ${{ format('Upload artifact {0}', env.artifact_name) }}
|
||||||
|
uses: actions/upload-artifact@v3
|
||||||
|
with:
|
||||||
|
name: ${{ env.artifact_name }}
|
||||||
|
path: 'upx*/build/*/*/*/upx'
|
||||||
|
- { name: 'Run basic tests clang', run: 'make -C upx/build/xtarget/clang-static/release test' }
|
||||||
|
- { name: 'Run basic tests gcc', run: 'make -C upx/build/xtarget/gcc-static/release test' }
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
name: 'Close pull requests'
|
name: 'GitHub - Close pull requests'
|
||||||
on:
|
on:
|
||||||
#pull_request:
|
#pull_request:
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
|
|||||||
@@ -0,0 +1,22 @@
|
|||||||
|
name: 'Static Analyzer - scan-build'
|
||||||
|
|
||||||
|
on:
|
||||||
|
schedule:
|
||||||
|
- cron: '40 1 * * 3'
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
analyze:
|
||||||
|
name: Analyze
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
container: 'alpine:edge'
|
||||||
|
steps:
|
||||||
|
- name: 'Install packages'
|
||||||
|
run: 'apk update && apk upgrade && apk add bash clang clang-analyzer cmake g++ git make'
|
||||||
|
- name: 'Check out code'
|
||||||
|
uses: actions/checkout@v3
|
||||||
|
with: { submodules: true }
|
||||||
|
- name: 'Perform scan-build Analysis Debug'
|
||||||
|
run: 'make build/extra/scan-build/debug'
|
||||||
|
- name: 'Perform scan-build Analysis Release'
|
||||||
|
run: 'make build/extra/scan-build/release'
|
||||||
+1
-8
@@ -5,11 +5,10 @@
|
|||||||
/maint*
|
/maint*
|
||||||
/vendor*
|
/vendor*
|
||||||
|
|
||||||
.depend
|
|
||||||
GNUmakefile
|
GNUmakefile
|
||||||
MMakefile
|
MMakefile
|
||||||
Makevars.local*
|
Makevars.local*
|
||||||
tmp-testsuite*
|
tmp*
|
||||||
|
|
||||||
*.a
|
*.a
|
||||||
*.d
|
*.d
|
||||||
@@ -30,20 +29,14 @@ doc/*.ps
|
|||||||
doc/*.tex
|
doc/*.tex
|
||||||
|
|
||||||
src/stub/**/.*-stamp
|
src/stub/**/.*-stamp
|
||||||
src/stub/**/MMakefile
|
|
||||||
src/stub/tmp*/*.bin
|
src/stub/tmp*/*.bin
|
||||||
src/stub/tmp*/*.bin.bindump
|
src/stub/tmp*/*.bin.bindump
|
||||||
src/stub/tmp*/*.bin.disasm
|
src/stub/tmp*/*.bin.disasm
|
||||||
src/stub/tmp*/*.d
|
|
||||||
src/stub/tmp*/*.o
|
|
||||||
src/stub/tmp*/*.o.disasm
|
src/stub/tmp*/*.o.disasm
|
||||||
src/stub/tmp*/mips.r3000-*.[is]
|
src/stub/tmp*/mips.r3000-*.[is]
|
||||||
src/stub/tmp*/mipsel.r3000-*.[is]
|
src/stub/tmp*/mipsel.r3000-*.[is]
|
||||||
src/stub/src/**/tmp*/*
|
src/stub/src/**/tmp*/*
|
||||||
|
|
||||||
src/stub/tools/armpe/armpe_tester.exe
|
|
||||||
src/stub/tools/armpe/armpe_tester.out
|
|
||||||
|
|
||||||
src/stub/tools/sstrip/amd64-linux-sstrip
|
src/stub/tools/sstrip/amd64-linux-sstrip
|
||||||
src/stub/tools/sstrip/i386-linux-sstrip
|
src/stub/tools/sstrip/i386-linux-sstrip
|
||||||
src/stub/tools/sstrip/sstrip
|
src/stub/tools/sstrip/sstrip
|
||||||
|
|||||||
@@ -13,6 +13,11 @@
|
|||||||
url = https://github.com/upx/upx-vendor-ucl.git
|
url = https://github.com/upx/upx-vendor-ucl.git
|
||||||
branch = upx-vendor
|
branch = upx-vendor
|
||||||
shallow = true
|
shallow = true
|
||||||
|
[submodule "vendor/valgrind"]
|
||||||
|
path = vendor/valgrind
|
||||||
|
url = https://github.com/upx/upx-vendor-valgrind.git
|
||||||
|
branch = upx-vendor
|
||||||
|
shallow = true
|
||||||
[submodule "vendor/zlib"]
|
[submodule "vendor/zlib"]
|
||||||
path = vendor/zlib
|
path = vendor/zlib
|
||||||
url = https://github.com/upx/upx-vendor-zlib.git
|
url = https://github.com/upx/upx-vendor-zlib.git
|
||||||
|
|||||||
+178
-63
@@ -1,9 +1,22 @@
|
|||||||
cmake_minimum_required(VERSION 3.10 FATAL_ERROR)
|
cmake_minimum_required(VERSION 3.8.0 FATAL_ERROR)
|
||||||
|
|
||||||
# config options
|
# compilation config options
|
||||||
option(UPX_CONFIG_DISABLE_GITREV "Do not compile with default Git version info.")
|
if(NOT IS_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/.git")
|
||||||
option(UPX_CONFIG_DISABLE_SANITIZE "Do not compile with default sanitize options.")
|
# permissive config defaults when building from source code tarball
|
||||||
option(UPX_CONFIG_DISABLE_WERROR "Do not compile with default -Werror option.")
|
option(UPX_CONFIG_DISABLE_GITREV "Do not compile with default Git version info." ON)
|
||||||
|
option(UPX_CONFIG_DISABLE_SANITIZE "Do not compile with default sanitize options." ON)
|
||||||
|
option(UPX_CONFIG_DISABLE_WERROR "Do not compile with default -Werror option." ON)
|
||||||
|
else()
|
||||||
|
# strict config defaults for devel builds
|
||||||
|
message(STATUS "===== UPX info: strict config defaults enabled")
|
||||||
|
option(UPX_CONFIG_DISABLE_GITREV "Do not compile with default Git version info." OFF)
|
||||||
|
option(UPX_CONFIG_DISABLE_SANITIZE "Do not compile with default sanitize options." OFF)
|
||||||
|
option(UPX_CONFIG_DISABLE_WERROR "Do not compile with default -Werror option." OFF)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# test config options (see below)
|
||||||
|
# NOTE: self-pack test can only work if the host executable format is supported by UPX!
|
||||||
|
option(UPX_CONFIG_DISABLE_SELF_PACK_TEST "Do not test packing UPX with itself" OFF)
|
||||||
|
|
||||||
#***********************************************************************
|
#***********************************************************************
|
||||||
# init
|
# init
|
||||||
@@ -11,24 +24,27 @@ option(UPX_CONFIG_DISABLE_WERROR "Do not compile with default -Werror option."
|
|||||||
|
|
||||||
# Disallow in-source builds. Note that you will still have to manually
|
# Disallow in-source builds. Note that you will still have to manually
|
||||||
# clean up a few files if you accidentally try an in-source build.
|
# clean up a few files if you accidentally try an in-source build.
|
||||||
|
if(NOT MSVC_IDE)
|
||||||
set(CMAKE_DISABLE_IN_SOURCE_BUILD ON)
|
set(CMAKE_DISABLE_IN_SOURCE_BUILD ON)
|
||||||
set(CMAKE_DISABLE_SOURCE_CHANGES ON)
|
set(CMAKE_DISABLE_SOURCE_CHANGES ON)
|
||||||
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
|
if(",${CMAKE_CURRENT_SOURCE_DIR}," STREQUAL ",${CMAKE_CURRENT_BINARY_DIR},")
|
||||||
if(",${CMAKE_SOURCE_DIR}," STREQUAL ",${CMAKE_BINARY_DIR},")
|
|
||||||
message(FATAL_ERROR "ERROR: In-source builds are not allowed, please use an extra build dir.")
|
message(FATAL_ERROR "ERROR: In-source builds are not allowed, please use an extra build dir.")
|
||||||
endif()
|
endif()
|
||||||
|
endif()
|
||||||
|
set(CMAKE_C_STANDARD_REQUIRED ON)
|
||||||
|
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||||
|
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
|
||||||
|
|
||||||
# determine git revision
|
# determine git revision
|
||||||
set(GITREV_SHORT "")
|
set(GITREV_SHORT "")
|
||||||
set(GITREV_PLUS "")
|
set(GITREV_PLUS "")
|
||||||
|
set(GIT_DESCRIBE "")
|
||||||
find_package(Git)
|
find_package(Git)
|
||||||
if(GIT_FOUND AND NOT UPX_CONFIG_DISABLE_GITREV)
|
if(Git_FOUND AND NOT UPX_CONFIG_DISABLE_GITREV)
|
||||||
execute_process(
|
execute_process(
|
||||||
RESULT_VARIABLE result
|
|
||||||
COMMAND "${GIT_EXECUTABLE}" rev-parse --short=12 HEAD
|
COMMAND "${GIT_EXECUTABLE}" rev-parse --short=12 HEAD
|
||||||
ERROR_QUIET
|
RESULT_VARIABLE result ERROR_QUIET
|
||||||
OUTPUT_STRIP_TRAILING_WHITESPACE
|
OUTPUT_VARIABLE GITREV_SHORT OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||||
OUTPUT_VARIABLE GITREV_SHORT
|
|
||||||
)
|
)
|
||||||
string(LENGTH "${GITREV_SHORT}" l)
|
string(LENGTH "${GITREV_SHORT}" l)
|
||||||
if(${result} EQUAL 0 AND ${l} EQUAL 12)
|
if(${result} EQUAL 0 AND ${l} EQUAL 12)
|
||||||
@@ -39,17 +55,31 @@ if(GIT_FOUND AND NOT UPX_CONFIG_DISABLE_GITREV)
|
|||||||
else()
|
else()
|
||||||
set(GITREV_SHORT "")
|
set(GITREV_SHORT "")
|
||||||
endif()
|
endif()
|
||||||
|
execute_process(
|
||||||
|
COMMAND "${GIT_EXECUTABLE}" describe --match "v*.*.*" --tags --dirty
|
||||||
|
RESULT_VARIABLE result ERROR_QUIET
|
||||||
|
OUTPUT_VARIABLE GIT_DESCRIBE OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||||
|
)
|
||||||
|
if(GIT_DESCRIBE MATCHES "^v?([0-9]+\\.[0-9]+\\.[0-9]+)-([0-9]+)-g(.+)$")
|
||||||
|
set(GIT_DESCRIBE "${CMAKE_MATCH_1}-devel.${CMAKE_MATCH_2}+git-${CMAKE_MATCH_3}")
|
||||||
|
endif()
|
||||||
endif()
|
endif()
|
||||||
if(NOT IS_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/.git") # extra check
|
if(NOT IS_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/.git") # extra check
|
||||||
set(GITREV_SHORT "")
|
set(GITREV_SHORT "")
|
||||||
endif()
|
endif()
|
||||||
if(GITREV_SHORT)
|
if(GITREV_SHORT)
|
||||||
message(STATUS "UPX_VERSION_GITREV = \"${GITREV_SHORT}${GITREV_PLUS}\"")
|
message(STATUS "UPX_VERSION_GITREV = \"${GITREV_SHORT}${GITREV_PLUS}\"")
|
||||||
|
if(GIT_DESCRIBE)
|
||||||
|
message(STATUS "UPX_VERSION_GIT_DESCRIBE = \"${GIT_DESCRIBE}\"")
|
||||||
|
endif()
|
||||||
|
elseif(UPX_CONFIG_DISABLE_GITREV)
|
||||||
|
message(STATUS "UPX_VERSION_GITREV: disabled")
|
||||||
else()
|
else()
|
||||||
message(STATUS "UPX_VERSION_GITREV: not set")
|
message(STATUS "UPX_VERSION_GITREV: not set")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
project(upx VERSION 4.0.0 LANGUAGES C CXX)
|
# CMake init
|
||||||
|
project(upx VERSION 4.0.2 LANGUAGES C CXX)
|
||||||
|
|
||||||
# set default build type to "Release"
|
# set default build type to "Release"
|
||||||
get_property(is_multi_config GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG)
|
get_property(is_multi_config GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG)
|
||||||
@@ -70,6 +100,9 @@ endif()
|
|||||||
# targets and compilation flags
|
# targets and compilation flags
|
||||||
#***********************************************************************
|
#***********************************************************************
|
||||||
|
|
||||||
|
#find_package(Threads) # multithreading is currently not used; maybe in UPX version 5
|
||||||
|
set(UPX_CONFIG_DISABLE_ZSTD ON) # zstd is currently not used; maybe in UPX version 5
|
||||||
|
|
||||||
file(GLOB ucl_SOURCES "vendor/ucl/src/*.c")
|
file(GLOB ucl_SOURCES "vendor/ucl/src/*.c")
|
||||||
list(SORT ucl_SOURCES)
|
list(SORT ucl_SOURCES)
|
||||||
add_library(upx_vendor_ucl STATIC ${ucl_SOURCES})
|
add_library(upx_vendor_ucl STATIC ${ucl_SOURCES})
|
||||||
@@ -80,12 +113,26 @@ list(SORT zlib_SOURCES)
|
|||||||
add_library(upx_vendor_zlib STATIC ${zlib_SOURCES})
|
add_library(upx_vendor_zlib STATIC ${zlib_SOURCES})
|
||||||
set_property(TARGET upx_vendor_zlib PROPERTY C_STANDARD 11)
|
set_property(TARGET upx_vendor_zlib PROPERTY C_STANDARD 11)
|
||||||
|
|
||||||
file(GLOB upx_SOURCES "src/*.cpp" "src/util/*.cpp")
|
if(NOT UPX_CONFIG_DISABLE_ZSTD)
|
||||||
|
file(GLOB zstd_SOURCES "vendor/zstd/lib/*/*.c")
|
||||||
|
list(SORT zstd_SOURCES)
|
||||||
|
add_library(upx_vendor_zstd STATIC ${zstd_SOURCES})
|
||||||
|
set_property(TARGET upx_vendor_zstd PROPERTY C_STANDARD 11)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
file(GLOB upx_SOURCES "src/*.cpp" "src/[cfu]*/*.cpp")
|
||||||
list(SORT upx_SOURCES)
|
list(SORT upx_SOURCES)
|
||||||
add_executable(upx ${upx_SOURCES})
|
add_executable(upx ${upx_SOURCES})
|
||||||
set_property(TARGET upx PROPERTY CXX_STANDARD 14)
|
set_property(TARGET upx PROPERTY CXX_STANDARD 17)
|
||||||
target_link_libraries(upx upx_vendor_ucl upx_vendor_zlib)
|
target_link_libraries(upx upx_vendor_ucl upx_vendor_zlib)
|
||||||
|
|
||||||
|
if(NOT MSVC)
|
||||||
|
# rather strict default compilation warnings
|
||||||
|
set(warn_strict
|
||||||
|
-Wall -Wextra -Wcast-align -Wcast-qual -Wmissing-declarations
|
||||||
|
-Wpointer-arith -Wshadow -Wvla -Wwrite-strings
|
||||||
|
)
|
||||||
|
endif()
|
||||||
if(UPX_CONFIG_DISABLE_WERROR)
|
if(UPX_CONFIG_DISABLE_WERROR)
|
||||||
set(warn_Werror "")
|
set(warn_Werror "")
|
||||||
set(warn_WX "")
|
set(warn_WX "")
|
||||||
@@ -108,25 +155,54 @@ if(MSVC)
|
|||||||
add_definitions(-D_CRT_NONSTDC_NO_WARNINGS)
|
add_definitions(-D_CRT_NONSTDC_NO_WARNINGS)
|
||||||
add_definitions(-D_CRT_SECURE_NO_DEPRECATE)
|
add_definitions(-D_CRT_SECURE_NO_DEPRECATE)
|
||||||
add_definitions(-D_CRT_SECURE_NO_WARNINGS)
|
add_definitions(-D_CRT_SECURE_NO_WARNINGS)
|
||||||
|
# set __cplusplus according to selected C++ standard; use new preprocessor
|
||||||
|
add_definitions(-Zc:__cplusplus -Zc:preprocessor)
|
||||||
else()
|
else()
|
||||||
# protect against security threats caused by misguided compiler "optimizations"
|
# protect against security threats caused by misguided compiler "optimizations"
|
||||||
if (CMAKE_C_COMPILER_ID STREQUAL "GNU")
|
if (CMAKE_C_COMPILER_ID STREQUAL "GNU")
|
||||||
add_definitions(-fno-delete-null-pointer-checks)
|
add_definitions(-fno-delete-null-pointer-checks -fno-lifetime-dse)
|
||||||
endif()
|
endif()
|
||||||
add_definitions(-fno-strict-aliasing -fno-strict-overflow -funsigned-char)
|
add_definitions(-fno-strict-aliasing -fno-strict-overflow -funsigned-char)
|
||||||
# disable overambitious auto-vectorization until this actually gains something
|
# disable overambitious auto-vectorization until this actually gains something
|
||||||
add_definitions(-fno-tree-vectorize)
|
add_definitions(-fno-tree-vectorize)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
# compile a target with -O2 in Debug build
|
||||||
|
function(upx_compile_target_debug_with_O2 t)
|
||||||
|
if(MSVC)
|
||||||
|
# msvc uses some Debug compile options like -RTC1 that are incompatible with -O2
|
||||||
|
else()
|
||||||
|
target_compile_options(${t} PRIVATE $<$<CONFIG:Debug>:-O2>)
|
||||||
|
endif()
|
||||||
|
endfunction()
|
||||||
|
|
||||||
|
function(upx_sanitize_target t)
|
||||||
|
if(NOT UPX_CONFIG_DISABLE_SANITIZE AND NOT MSVC)
|
||||||
|
if(CMAKE_C_PLATFORM_ID MATCHES "^MinGW" OR MINGW OR CYGWIN)
|
||||||
|
# avoid link errors with current MinGW-w64 versions
|
||||||
|
# see https://www.mingw-w64.org/contribute/#sanitizers-asan-tsan-usan
|
||||||
|
else()
|
||||||
|
# default sanitizer for Debug builds
|
||||||
|
target_compile_options(${t} PRIVATE $<$<CONFIG:Debug>:-fsanitize=undefined -fsanitize-undefined-trap-on-error -fstack-protector-all>)
|
||||||
|
# default sanitizer for Release builds
|
||||||
|
target_compile_options(${t} PRIVATE $<$<CONFIG:Release>:-fstack-protector>)
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
endfunction()
|
||||||
|
|
||||||
set(t upx_vendor_ucl)
|
set(t upx_vendor_ucl)
|
||||||
target_include_directories(${t} PRIVATE vendor/ucl/include vendor/ucl)
|
target_include_directories(${t} PRIVATE vendor/ucl/include vendor/ucl)
|
||||||
|
upx_compile_target_debug_with_O2(${t})
|
||||||
|
upx_sanitize_target(${t})
|
||||||
if(MSVC)
|
if(MSVC)
|
||||||
target_compile_options(${t} PRIVATE -J -W4 ${warn_WX})
|
target_compile_options(${t} PRIVATE -J -W4 ${warn_WX})
|
||||||
else()
|
else()
|
||||||
target_compile_options(${t} PRIVATE -Wall -Wextra -Wvla ${warn_Werror})
|
target_compile_options(${t} PRIVATE ${warn_strict} ${warn_Werror})
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
set(t upx_vendor_zlib)
|
set(t upx_vendor_zlib)
|
||||||
|
upx_compile_target_debug_with_O2(${t})
|
||||||
|
upx_sanitize_target(${t})
|
||||||
if(MSVC)
|
if(MSVC)
|
||||||
target_compile_options(${t} PRIVATE -DHAVE_STDARG_H -DHAVE_VSNPRINTF -J -W3 ${warn_WX})
|
target_compile_options(${t} PRIVATE -DHAVE_STDARG_H -DHAVE_VSNPRINTF -J -W3 ${warn_WX})
|
||||||
else()
|
else()
|
||||||
@@ -135,100 +211,139 @@ else()
|
|||||||
target_compile_options(${t} PRIVATE -Wall -Wextra -Wvla -Wno-strict-prototypes ${warn_Werror})
|
target_compile_options(${t} PRIVATE -Wall -Wextra -Wvla -Wno-strict-prototypes ${warn_Werror})
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
if(NOT UPX_CONFIG_DISABLE_ZSTD)
|
||||||
|
set(t upx_vendor_zstd)
|
||||||
|
upx_compile_target_debug_with_O2(${t})
|
||||||
|
upx_sanitize_target(${t})
|
||||||
|
target_compile_options(${t} PRIVATE -DDYNAMIC_BMI2=0 -DZSTD_DISABLE_ASM)
|
||||||
|
if(MSVC)
|
||||||
|
target_compile_options(${t} PRIVATE -J -W4 ${warn_WX})
|
||||||
|
else()
|
||||||
|
target_compile_options(${t} PRIVATE ${warn_strict} ${warn_Werror})
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
set(t upx)
|
set(t upx)
|
||||||
target_include_directories(${t} PRIVATE vendor)
|
target_include_directories(${t} PRIVATE vendor vendor/boost-pfr/include)
|
||||||
target_compile_definitions(${t} PRIVATE $<$<CONFIG:Debug>:DEBUG=1>)
|
target_compile_definitions(${t} PRIVATE $<$<CONFIG:Debug>:DEBUG=1>)
|
||||||
if(GITREV_SHORT)
|
if(GITREV_SHORT)
|
||||||
target_compile_definitions(${t} PRIVATE UPX_VERSION_GITREV="${GITREV_SHORT}${GITREV_PLUS}")
|
target_compile_definitions(${t} PRIVATE UPX_VERSION_GITREV="${GITREV_SHORT}${GITREV_PLUS}")
|
||||||
|
if(GIT_DESCRIBE)
|
||||||
|
target_compile_definitions(${t} PRIVATE UPX_VERSION_GIT_DESCRIBE="${GIT_DESCRIBE}")
|
||||||
endif()
|
endif()
|
||||||
if(NOT UPX_CONFIG_DISABLE_SANITIZE AND NOT MSVC)
|
|
||||||
# default sanitizer for Debug builds
|
|
||||||
target_compile_options(${t} PRIVATE $<$<CONFIG:Debug>:-fsanitize=undefined -fsanitize-undefined-trap-on-error -fstack-protector-all>)
|
|
||||||
# default sanitizer for Release builds
|
|
||||||
target_compile_options(${t} PRIVATE $<$<CONFIG:Release>:-fstack-protector>)
|
|
||||||
endif()
|
endif()
|
||||||
|
#upx_compile_target_debug_with_O2(${t})
|
||||||
|
upx_sanitize_target(${t})
|
||||||
if(MSVC)
|
if(MSVC)
|
||||||
target_compile_options(${t} PRIVATE -EHsc -J -W4 ${warn_WX})
|
target_compile_options(${t} PRIVATE -EHsc -J -W4 ${warn_WX})
|
||||||
else()
|
else()
|
||||||
target_compile_options(${t} PRIVATE
|
target_compile_options(${t} PRIVATE ${warn_strict} ${warn_Werror})
|
||||||
-Wall -Wextra -Wcast-align -Wcast-qual -Wmissing-declarations -Wpointer-arith
|
endif()
|
||||||
-Wshadow -Wvla -Wwrite-strings ${warn_Werror}
|
if(NOT UPX_CONFIG_DISABLE_ZSTD)
|
||||||
)
|
target_compile_definitions(${t} PRIVATE WITH_ZSTD=1)
|
||||||
|
target_link_libraries(upx upx_vendor_zstd)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
#***********************************************************************
|
#***********************************************************************
|
||||||
|
# "ctest"
|
||||||
# "make test"
|
# "make test"
|
||||||
|
# "ninja test"
|
||||||
#***********************************************************************
|
#***********************************************************************
|
||||||
|
|
||||||
if(NOT CMAKE_CROSSCOMPILING)
|
if(NOT UPX_CONFIG_CMAKE_DISABLE_TEST)
|
||||||
|
|
||||||
include(CTest)
|
include(CTest)
|
||||||
set(exe ${CMAKE_EXECUTABLE_SUFFIX})
|
if(NOT CMAKE_CROSSCOMPILING)
|
||||||
set(upx_self_exe "$<TARGET_FILE:upx>")
|
|
||||||
add_test(NAME upx-test-cleanup COMMAND rm -f ./upx.packed${exe} ./upx.unpacked${exe})
|
|
||||||
add_test(NAME upx-version COMMAND upx --version)
|
add_test(NAME upx-version COMMAND upx --version)
|
||||||
add_test(NAME upx-help COMMAND upx --help)
|
add_test(NAME upx-help COMMAND upx --help)
|
||||||
add_test(NAME upx-self-pack COMMAND upx -3 ${upx_self_exe} -o upx.packed${exe})
|
endif()
|
||||||
add_test(NAME upx-list COMMAND upx -l upx.packed${exe})
|
if(NOT CMAKE_CROSSCOMPILING AND NOT UPX_CONFIG_DISABLE_SELF_PACK_TEST)
|
||||||
add_test(NAME upx-fileinfo COMMAND upx --fileinfo upx.packed${exe})
|
# NOTE: these tests can only work if the host executable format is supported by UPX!
|
||||||
add_test(NAME upx-test COMMAND upx -t upx.packed${exe})
|
function(upx_add_test)
|
||||||
add_test(NAME upx-unpack COMMAND upx -d upx.packed${exe} -o upx.unpacked${exe})
|
set(name ${ARGV0})
|
||||||
add_test(NAME upx-run-unpacked COMMAND ./upx.unpacked${exe} --version)
|
list(REMOVE_AT ARGV 0)
|
||||||
add_test(NAME upx-run-packed COMMAND ./upx.packed${exe} --version)
|
add_test(NAME ${name} COMMAND ${ARGV})
|
||||||
|
set_tests_properties(${name} PROPERTIES RUN_SERIAL TRUE) # run these tests sequentially
|
||||||
|
endfunction()
|
||||||
|
set(exe ${CMAKE_EXECUTABLE_SUFFIX})
|
||||||
|
set(upx_self_exe "$<TARGET_FILE:upx>")
|
||||||
|
set(fo "--force-overwrite")
|
||||||
|
upx_add_test(upx-self-pack upx -3 ${upx_self_exe} ${fo} -o upx-packed${exe})
|
||||||
|
upx_add_test(upx-self-pack-n2b upx -3 --nrv2b ${upx_self_exe} ${fo} -o upx-packed-n2b${exe})
|
||||||
|
upx_add_test(upx-self-pack-n2d upx -3 --nrv2d ${upx_self_exe} ${fo} -o upx-packed-n2d${exe})
|
||||||
|
upx_add_test(upx-self-pack-n2e upx -3 --nrv2e ${upx_self_exe} ${fo} -o upx-packed-n2e${exe})
|
||||||
|
upx_add_test(upx-self-pack-lzma upx -3 --lzma ${upx_self_exe} ${fo} -o upx-packed-lzma${exe})
|
||||||
|
upx_add_test(upx-list upx -l upx-packed${exe} upx-packed-n2b${exe} upx-packed-n2d${exe} upx-packed-n2e${exe} upx-packed-lzma${exe})
|
||||||
|
upx_add_test(upx-fileinfo upx --fileinfo upx-packed${exe} upx-packed-n2b${exe} upx-packed-n2d${exe} upx-packed-n2e${exe} upx-packed-lzma${exe})
|
||||||
|
upx_add_test(upx-test upx -t upx-packed${exe} upx-packed-n2b${exe} upx-packed-n2d${exe} upx-packed-n2e${exe} upx-packed-lzma${exe})
|
||||||
|
upx_add_test(upx-unpack upx -d upx-packed${exe} ${fo} -o upx-unpacked${exe})
|
||||||
|
upx_add_test(upx-run-unpacked ./upx-unpacked${exe} --version-short)
|
||||||
|
upx_add_test(upx-run-packed ./upx-packed${exe} --version-short)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# TODO: could add some more explicit test programs; but then, the integrated
|
endif() # UPX_CONFIG_CMAKE_DISABLE_TEST
|
||||||
# "doctest" is quite convenient and already covers a number of basic
|
|
||||||
# checks - and more complex cases better should be handled by an
|
|
||||||
# external test suite.
|
|
||||||
|
|
||||||
#***********************************************************************
|
#***********************************************************************
|
||||||
|
# "cmake --install ."
|
||||||
# "make install"
|
# "make install"
|
||||||
|
# "ninja install"
|
||||||
#***********************************************************************
|
#***********************************************************************
|
||||||
|
|
||||||
|
if(NOT UPX_CONFIG_CMAKE_DISABLE_INSTALL)
|
||||||
|
|
||||||
# installation prefix and directories
|
# installation prefix and directories
|
||||||
if(NOT CMAKE_INSTALL_PREFIX)
|
if(NOT CMAKE_INSTALL_PREFIX)
|
||||||
message(FATAL_ERROR "ERROR: CMAKE_INSTALL_PREFIX is not defined.")
|
#message(FATAL_ERROR "ERROR: CMAKE_INSTALL_PREFIX is not defined.")
|
||||||
|
message(WARNING "WARNING: CMAKE_INSTALL_PREFIX is not defined.")
|
||||||
endif()
|
endif()
|
||||||
|
if(CMAKE_INSTALL_PREFIX)
|
||||||
include(GNUInstallDirs)
|
include(GNUInstallDirs)
|
||||||
|
endif()
|
||||||
if(DEFINED CMAKE_INSTALL_FULL_BINDIR)
|
if(CMAKE_INSTALL_PREFIX AND DEFINED CMAKE_INSTALL_FULL_BINDIR)
|
||||||
install(TARGETS upx DESTINATION "${CMAKE_INSTALL_FULL_BINDIR}")
|
install(TARGETS upx DESTINATION "${CMAKE_INSTALL_FULL_BINDIR}")
|
||||||
install(FILES
|
install(FILES
|
||||||
COPYING LICENSE NEWS README doc/upx-doc.html doc/upx-doc.txt
|
COPYING LICENSE NEWS README THANKS doc/upx-doc.html doc/upx-doc.txt
|
||||||
DESTINATION "${CMAKE_INSTALL_FULL_DOCDIR}"
|
DESTINATION "${CMAKE_INSTALL_FULL_DOCDIR}"
|
||||||
)
|
)
|
||||||
install(FILES doc/upx.1 DESTINATION "${CMAKE_INSTALL_FULL_MANDIR}/man1")
|
install(FILES doc/upx.1 DESTINATION "${CMAKE_INSTALL_FULL_MANDIR}/man1")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
endif() # UPX_CONFIG_CMAKE_DISABLE_INSTALL
|
||||||
|
|
||||||
#***********************************************************************
|
#***********************************************************************
|
||||||
# finally print some info about the build configuration
|
# finally print some info about the build configuration
|
||||||
#***********************************************************************
|
#***********************************************************************
|
||||||
|
|
||||||
if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/maint/src/CMakeLists.extra.txt")
|
if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/maint/make/CMakeLists.maint.txt")
|
||||||
include("${CMAKE_CURRENT_SOURCE_DIR}/maint/src/CMakeLists.extra.txt")
|
include("${CMAKE_CURRENT_SOURCE_DIR}/maint/make/CMakeLists.maint.txt")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
function(print_var v)
|
function(print_var)
|
||||||
|
foreach(v ${ARGV})
|
||||||
if(${v})
|
if(${v})
|
||||||
message(STATUS "${v} = ${${v}}")
|
message(STATUS "${v} = ${${v}}")
|
||||||
endif()
|
endif()
|
||||||
|
endforeach()
|
||||||
endfunction()
|
endfunction()
|
||||||
print_var(CMAKE_BUILD_TYPE)
|
if(NOT UPX_CONFIG_CMAKE_DISABLE_PRINT_INFO)
|
||||||
print_var(CMAKE_CONFIGURATION_TYPES)
|
print_var(CMAKE_HOST_SYSTEM_NAME CMAKE_HOST_SYSTEM_VERSION)
|
||||||
print_var(CMAKE_INSTALL_PREFIX)
|
print_var(CMAKE_SYSTEM_NAME CMAKE_SYSTEM_VERSION CMAKE_CROSSCOMPILING)
|
||||||
print_var(CMAKE_CROSSCOMPILING)
|
print_var(CMAKE_C_COMPILER_ID CMAKE_C_COMPILER_VERSION CMAKE_C_COMPILER_ARCHITECTURE_ID CMAKE_C_PLATFORM_ID CMAKE_C_COMPILER_ABI)
|
||||||
print_var(CMAKE_C_COMPILER_ID)
|
print_var(CMAKE_CXX_COMPILER_ID CMAKE_CXX_COMPILER_VERSION CMAKE_CXX_COMPILER_ARCHITECTURE_ID CMAKE_CXX_PLATFORM_ID CMAKE_CXX_COMPILER_ABI)
|
||||||
print_var(CMAKE_C_COMPILER_VERSION)
|
endif() # UPX_CONFIG_CMAKE_DISABLE_PRINT_INFO
|
||||||
print_var(CMAKE_C_COMPILER_ARCHITECTURE_ID)
|
print_var(CMAKE_INSTALL_PREFIX CMAKE_CONFIGURATION_TYPES CMAKE_BUILD_TYPE)
|
||||||
print_var(CMAKE_C_PLATFORM_ID)
|
|
||||||
print_var(CMAKE_C_COMPILER_ABI)
|
|
||||||
print_var(CMAKE_CXX_COMPILER_ID)
|
|
||||||
print_var(CMAKE_CXX_COMPILER_VERSION)
|
|
||||||
print_var(CMAKE_CXX_COMPILER_ARCHITECTURE_ID)
|
|
||||||
print_var(CMAKE_CXX_PLATFORM_ID)
|
|
||||||
print_var(CMAKE_CXX_COMPILER_ABI)
|
|
||||||
if (CMAKE_BUILD_TYPE AND NOT CMAKE_BUILD_TYPE MATCHES "^(Debug|Release)$")
|
if (CMAKE_BUILD_TYPE AND NOT CMAKE_BUILD_TYPE MATCHES "^(Debug|Release)$")
|
||||||
message(WARNING "WARNING: unsupported CMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}; please use \"Debug\" or \"Release\"")
|
message(WARNING "WARNING: unsupported CMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}; please use \"Debug\" or \"Release\"")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
if(NOT UPX_CONFIG_CMAKE_DISABLE_PLATFORM_CHECK)
|
||||||
|
# extra sanity checks to detect incompatible C vs CXX settings
|
||||||
|
if(NOT ",${CMAKE_C_PLATFORM_ID}," STREQUAL ",${CMAKE_CXX_PLATFORM_ID},")
|
||||||
|
message(FATAL_ERROR "ERROR: CMAKE_C_PLATFORM_ID CMAKE_CXX_PLATFORM_ID mismatch")
|
||||||
|
endif()
|
||||||
|
if(NOT ",${CMAKE_C_COMPILER_ABI}," STREQUAL ",${CMAKE_CXX_COMPILER_ABI},")
|
||||||
|
message(FATAL_ERROR "ERROR: CMAKE_C_COMPILER_ABI CMAKE_CXX_COMPILER_ABI mismatch")
|
||||||
|
endif()
|
||||||
|
endif() # UPX_CONFIG_CMAKE_DISABLE_PLATFORM_CHECK
|
||||||
|
|
||||||
# vim:set ft=cmake ts=4 sw=4 tw=0 et:
|
# vim:set ft=cmake ts=4 sw=4 tw=0 et:
|
||||||
|
|||||||
@@ -2,41 +2,33 @@
|
|||||||
# UPX top-level Makefile - needs GNU make and CMake >= 3.13
|
# UPX top-level Makefile - needs GNU make and CMake >= 3.13
|
||||||
#
|
#
|
||||||
|
|
||||||
# NOTE: if you only have CMake 3.10 then you can invoke cmake manually like this:
|
# INFO: this Makefile is just a convenience wrapper for calling CMake
|
||||||
|
|
||||||
|
# NOTE: if you only have an older CMake 3.x then you can invoke cmake manually like this:
|
||||||
# mkdir -p build/release
|
# mkdir -p build/release
|
||||||
# cd build/release
|
# cd build/release
|
||||||
# cmake ../..
|
# cmake ../..
|
||||||
# cmake --build .
|
# make -j (or use "cmake --build . --parallel")
|
||||||
|
|
||||||
CMAKE = cmake
|
CMAKE = cmake
|
||||||
UPX_CMAKE_BUILD_FLAGS += --parallel
|
UPX_CMAKE_BUILD_FLAGS += --parallel
|
||||||
ifneq ($(VERBOSE),)
|
ifneq ($(VERBOSE),)
|
||||||
UPX_CMAKE_BUILD_FLAGS += --verbose
|
UPX_CMAKE_BUILD_FLAGS += --verbose
|
||||||
endif
|
endif
|
||||||
|
# enable this if you prefer Ninja for the actual builds:
|
||||||
# check git submodules
|
#UPX_CMAKE_CONFIG_FLAGS += -G Ninja
|
||||||
ifeq ($(wildcard ./vendor/doctest/doctest/.),)
|
|
||||||
$(error ERROR: missing git submodule; run 'git submodule update --init')
|
|
||||||
endif
|
|
||||||
ifeq ($(wildcard ./vendor/lzma-sdk/C/.),)
|
|
||||||
$(error ERROR: missing git submodule; run 'git submodule update --init')
|
|
||||||
endif
|
|
||||||
ifeq ($(wildcard ./vendor/ucl/include/.),)
|
|
||||||
$(error ERROR: missing git submodule; run 'git submodule update --init')
|
|
||||||
endif
|
|
||||||
ifeq ($(wildcard ./vendor/zlib/crc32.c),)
|
|
||||||
$(error ERROR: missing git submodule; run 'git submodule update --init')
|
|
||||||
endif
|
|
||||||
|
|
||||||
#***********************************************************************
|
#***********************************************************************
|
||||||
# default
|
# default
|
||||||
#***********************************************************************
|
#***********************************************************************
|
||||||
|
|
||||||
__check_cache = $(if $(wildcard $1/CMakeCache.txt),@true,)
|
run_cmake_config = $(CMAKE) -S . -B $1 $(UPX_CMAKE_CONFIG_FLAGS) -DCMAKE_BUILD_TYPE=$2
|
||||||
run_config = $(call __check_cache,$1) $(CMAKE) -S . -B $1 $(UPX_CMAKE_CONFIG_FLAGS) -DCMAKE_BUILD_TYPE=$2
|
run_cmake_build = $(CMAKE) --build $1 $(UPX_CMAKE_BUILD_FLAGS) --config $2
|
||||||
run_build = $(CMAKE) --build $1 $(UPX_CMAKE_BUILD_FLAGS) --config $2
|
# avoid re-running run_cmake_config if CMakeCache.txt already exists
|
||||||
|
run_config = $(if $(wildcard $1/CMakeCache.txt),,$(call run_cmake_config,$1,$2))
|
||||||
|
run_build = $(call run_cmake_build,$1,$2)
|
||||||
|
|
||||||
default: build/release
|
.DEFAULT_GOAL = build/release
|
||||||
|
|
||||||
build/debug: PHONY
|
build/debug: PHONY
|
||||||
$(call run_config,$@,Debug)
|
$(call run_config,$@,Debug)
|
||||||
@@ -46,40 +38,149 @@ build/release: PHONY
|
|||||||
$(call run_config,$@,Release)
|
$(call run_config,$@,Release)
|
||||||
$(call run_build,$@,Release)
|
$(call run_build,$@,Release)
|
||||||
|
|
||||||
|
# shortcuts
|
||||||
|
all: build/debug build/release
|
||||||
|
debug: build/debug
|
||||||
|
release: build/release
|
||||||
|
|
||||||
|
.PHONY: PHONY
|
||||||
|
.NOTPARALLEL: # because the actual builds use "cmake --parallel"
|
||||||
|
.SUFFIXES:
|
||||||
|
|
||||||
|
# END of Makefile; extra stuff follows
|
||||||
|
|
||||||
#***********************************************************************
|
#***********************************************************************
|
||||||
# some pre-defined build configurations
|
# extra builds: some pre-defined build configurations
|
||||||
#***********************************************************************
|
#***********************************************************************
|
||||||
|
|
||||||
# force building with gcc/g++
|
define run_config_and_build
|
||||||
build/%-gcc: export CC=gcc
|
$(call run_config,$1,$2)
|
||||||
build/%-gcc: export CXX=g++
|
$(call run_build,$1,$2)
|
||||||
build/debug-gcc: PHONY
|
endef
|
||||||
$(call run_config,$@,Debug)
|
|
||||||
$(call run_build,$@,Debug)
|
|
||||||
build/release-gcc: PHONY
|
|
||||||
$(call run_config,$@,Release)
|
|
||||||
$(call run_build,$@,Release)
|
|
||||||
|
|
||||||
# force building with clang/clang++
|
# force building with clang/clang++
|
||||||
build/%-clang: export CC=clang
|
build/extra/clang/debug: PHONY; $(call run_config_and_build,$@,Debug)
|
||||||
build/%-clang: export CXX=clang++
|
build/extra/clang/release: PHONY; $(call run_config_and_build,$@,Release)
|
||||||
build/debug-clang: PHONY
|
build/extra/clang/%: export CC = clang
|
||||||
$(call run_config,$@,Debug)
|
build/extra/clang/%: export CXX = clang++
|
||||||
$(call run_build,$@,Debug)
|
|
||||||
build/release-clang: PHONY
|
|
||||||
$(call run_config,$@,Release)
|
|
||||||
$(call run_build,$@,Release)
|
|
||||||
|
|
||||||
# cross compiler: Windows mingw-w64
|
# force building with clang/clang++ -m32
|
||||||
build/%-cross-mingw64: export CC=x86_64-w64-mingw32-gcc
|
build/extra/clang-m32/debug: PHONY; $(call run_config_and_build,$@,Debug)
|
||||||
build/%-cross-mingw64: export CXX=x86_64-w64-mingw32-g++
|
build/extra/clang-m32/release: PHONY; $(call run_config_and_build,$@,Release)
|
||||||
# disable sanitize to avoid link errors on GitHub CI
|
build/extra/clang-m32/%: export CC = clang -m32
|
||||||
build/%-cross-mingw64: UPX_CMAKE_CONFIG_FLAGS += -DUPX_CONFIG_DISABLE_SANITIZE=1
|
build/extra/clang-m32/%: export CXX = clang++ -m32
|
||||||
build/debug-cross-mingw64: PHONY
|
|
||||||
$(call run_config,$@,Debug)
|
|
||||||
$(call run_build,$@,Debug)
|
|
||||||
build/release-cross-mingw64: PHONY
|
|
||||||
$(call run_config,$@,Release)
|
|
||||||
$(call run_build,$@,Release)
|
|
||||||
|
|
||||||
.PHONY: default PHONY
|
# force building with clang/clang++ -mx32
|
||||||
|
build/extra/clang-mx32/debug: PHONY; $(call run_config_and_build,$@,Debug)
|
||||||
|
build/extra/clang-mx32/release: PHONY; $(call run_config_and_build,$@,Release)
|
||||||
|
build/extra/clang-mx32/%: export CC = clang -mx32
|
||||||
|
build/extra/clang-mx32/%: export CXX = clang++ -mx32
|
||||||
|
|
||||||
|
# force building with clang/clang++ -m64
|
||||||
|
build/extra/clang-m64/debug: PHONY; $(call run_config_and_build,$@,Debug)
|
||||||
|
build/extra/clang-m64/release: PHONY; $(call run_config_and_build,$@,Release)
|
||||||
|
build/extra/clang-m64/%: export CC = clang -m64
|
||||||
|
build/extra/clang-m64/%: export CXX = clang++ -m64
|
||||||
|
|
||||||
|
# force building with gcc/g++
|
||||||
|
build/extra/gcc/debug: PHONY; $(call run_config_and_build,$@,Debug)
|
||||||
|
build/extra/gcc/release: PHONY; $(call run_config_and_build,$@,Release)
|
||||||
|
build/extra/gcc/%: export CC = gcc
|
||||||
|
build/extra/gcc/%: export CXX = g++
|
||||||
|
|
||||||
|
# force building with gcc/g++ -m32
|
||||||
|
build/extra/gcc-m32/debug: PHONY; $(call run_config_and_build,$@,Debug)
|
||||||
|
build/extra/gcc-m32/release: PHONY; $(call run_config_and_build,$@,Release)
|
||||||
|
build/extra/gcc-m32/%: export CC = gcc -m32
|
||||||
|
build/extra/gcc-m32/%: export CXX = g++ -m32
|
||||||
|
|
||||||
|
# force building with gcc/g++ -mx32
|
||||||
|
build/extra/gcc-mx32/debug: PHONY; $(call run_config_and_build,$@,Debug)
|
||||||
|
build/extra/gcc-mx32/release: PHONY; $(call run_config_and_build,$@,Release)
|
||||||
|
build/extra/gcc-mx32/%: export CC = gcc -mx32
|
||||||
|
build/extra/gcc-mx32/%: export CXX = g++ -mx32
|
||||||
|
|
||||||
|
# force building with gcc/g++ -m64
|
||||||
|
build/extra/gcc-m64/debug: PHONY; $(call run_config_and_build,$@,Debug)
|
||||||
|
build/extra/gcc-m64/release: PHONY; $(call run_config_and_build,$@,Release)
|
||||||
|
build/extra/gcc-m64/%: export CC = gcc -m64
|
||||||
|
build/extra/gcc-m64/%: export CXX = g++ -m64
|
||||||
|
|
||||||
|
# force building with clang Static Analyzer (scan-build)
|
||||||
|
build/extra/scan-build/debug: PHONY; $(call run_config_and_build,$@,Debug)
|
||||||
|
build/extra/scan-build/release: PHONY; $(call run_config_and_build,$@,Release)
|
||||||
|
build/extra/scan-build/%: CMAKE := scan-build $(CMAKE)
|
||||||
|
build/extra/scan-build/%: export CCC_CC ?= clang
|
||||||
|
build/extra/scan-build/%: export CCC_CXX ?= clang++
|
||||||
|
|
||||||
|
# cross compiler: Linux glibc aarch64-linux-gnu
|
||||||
|
build/extra/cross-linux-aarch64/debug: PHONY; $(call run_config_and_build,$@,Debug)
|
||||||
|
build/extra/cross-linux-aarch64/release: PHONY; $(call run_config_and_build,$@,Release)
|
||||||
|
build/extra/cross-linux-aarch64/%: export CC = aarch64-linux-gnu-gcc
|
||||||
|
build/extra/cross-linux-aarch64/%: export CXX = aarch64-linux-gnu-g++
|
||||||
|
|
||||||
|
# cross compiler: Linux glibc arm-linux-gnueabihf
|
||||||
|
build/extra/cross-linux-arm/debug: PHONY; $(call run_config_and_build,$@,Debug)
|
||||||
|
build/extra/cross-linux-arm/release: PHONY; $(call run_config_and_build,$@,Release)
|
||||||
|
build/extra/cross-linux-arm/%: export CC = arm-linux-gnueabihf-gcc
|
||||||
|
build/extra/cross-linux-arm/%: export CXX = arm-linux-gnueabihf-g++ -Wno-psabi
|
||||||
|
|
||||||
|
# cross compiler: Windows x86 win32 MinGW
|
||||||
|
build/extra/cross-windows-mingw32/debug: PHONY; $(call run_config_and_build,$@,Debug)
|
||||||
|
build/extra/cross-windows-mingw32/release: PHONY; $(call run_config_and_build,$@,Release)
|
||||||
|
build/extra/cross-windows-mingw32/%: export CC = i686-w64-mingw32-gcc
|
||||||
|
build/extra/cross-windows-mingw32/%: export CXX = i686-w64-mingw32-g++
|
||||||
|
|
||||||
|
# cross compiler: Windows x64 win64 MinGW
|
||||||
|
build/extra/cross-windows-mingw64/debug: PHONY; $(call run_config_and_build,$@,Debug)
|
||||||
|
build/extra/cross-windows-mingw64/release: PHONY; $(call run_config_and_build,$@,Release)
|
||||||
|
build/extra/cross-windows-mingw64/%: export CC = x86_64-w64-mingw32-gcc
|
||||||
|
build/extra/cross-windows-mingw64/%: export CXX = x86_64-w64-mingw32-g++
|
||||||
|
|
||||||
|
# cross compiler: macOS arm64
|
||||||
|
build/extra/cross-darwin-arm64/debug: PHONY; $(call run_config_and_build,$@,Debug)
|
||||||
|
build/extra/cross-darwin-arm64/release: PHONY; $(call run_config_and_build,$@,Release)
|
||||||
|
build/extra/cross-darwin-arm64/%: export CC = clang -target arm64-apple-darwin
|
||||||
|
build/extra/cross-darwin-arm64/%: export CXX = clang++ -target arm64-apple-darwin
|
||||||
|
|
||||||
|
# cross compiler: macOS x86_64
|
||||||
|
build/extra/cross-darwin-x86_64/debug: PHONY; $(call run_config_and_build,$@,Debug)
|
||||||
|
build/extra/cross-darwin-x86_64/release: PHONY; $(call run_config_and_build,$@,Release)
|
||||||
|
build/extra/cross-darwin-x86_64/%: export CC = clang -target x86_64-apple-darwin
|
||||||
|
build/extra/cross-darwin-x86_64/%: export CXX = clang++ -target x86_64-apple-darwin
|
||||||
|
|
||||||
|
#***********************************************************************
|
||||||
|
# advanced: generic extra target
|
||||||
|
#***********************************************************************
|
||||||
|
|
||||||
|
# usage:
|
||||||
|
# make UPX_XTARGET=my-target CC="my-cc -flags" CXX="my-cxx -flags"
|
||||||
|
# make UPX_XTARGET=my-target CC="my-cc -flags" CXX="my-cxx -flags" xtarget/debug
|
||||||
|
|
||||||
|
ifneq ($(UPX_XTARGET),)
|
||||||
|
ifneq ($(CC),)
|
||||||
|
ifneq ($(CXX),)
|
||||||
|
|
||||||
|
UPX_XTARGET := $(UPX_XTARGET)
|
||||||
|
build/xtarget/$(UPX_XTARGET)/debug: PHONY; $(call run_config_and_build,$@,Debug)
|
||||||
|
build/xtarget/$(UPX_XTARGET)/release: PHONY; $(call run_config_and_build,$@,Release)
|
||||||
|
build/xtarget/$(UPX_XTARGET)/%: export CC
|
||||||
|
build/xtarget/$(UPX_XTARGET)/%: export CXX
|
||||||
|
# shortcuts
|
||||||
|
xtarget/debug: build/xtarget/$(UPX_XTARGET)/debug
|
||||||
|
xtarget/release: build/xtarget/$(UPX_XTARGET)/release
|
||||||
|
# set new default
|
||||||
|
.DEFAULT_GOAL = xtarget/release
|
||||||
|
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
|
#***********************************************************************
|
||||||
|
# check git submodules
|
||||||
|
#***********************************************************************
|
||||||
|
|
||||||
|
SUBMODULES = doctest lzma-sdk ucl valgrind zlib
|
||||||
|
|
||||||
|
dummy := $(foreach m,$(SUBMODULES),$(if $(wildcard vendor/$m/[CL]*),$m,\
|
||||||
|
$(error ERROR: missing git submodule $m; run 'git submodule update --init')))
|
||||||
|
|||||||
@@ -2,6 +2,12 @@
|
|||||||
User visible changes for UPX
|
User visible changes for UPX
|
||||||
==================================================================
|
==================================================================
|
||||||
|
|
||||||
|
Changes in 4.0.2 (30 Jan 2023):
|
||||||
|
* bug fixes - see https://github.com/upx/upx/milestone/9
|
||||||
|
|
||||||
|
Changes in 4.0.1 (16 Nov 2022):
|
||||||
|
* bug fixes - see https://github.com/upx/upx/milestone/8
|
||||||
|
|
||||||
Changes in 4.0.0 (28 Oct 2022):
|
Changes in 4.0.0 (28 Oct 2022):
|
||||||
* Switch to semantic versioning
|
* Switch to semantic versioning
|
||||||
* SECURITY NOTES: emphasize the security context in the docs
|
* SECURITY NOTES: emphasize the security context in the docs
|
||||||
@@ -9,6 +15,7 @@ Changes in 4.0.0 (28 Oct 2022):
|
|||||||
* Support easy rebuilding the stubs from source with Podman/Docker
|
* Support easy rebuilding the stubs from source with Podman/Docker
|
||||||
* Add integrated doctest C++ testing framework
|
* Add integrated doctest C++ testing framework
|
||||||
* Add support for EFI files (PE x86; Kornel Pal)
|
* Add support for EFI files (PE x86; Kornel Pal)
|
||||||
|
* win32/pe and win64/pe: set correct SizeOfHeaders in the PE header
|
||||||
* bug fixes - see https://github.com/upx/upx/milestone/6
|
* bug fixes - see https://github.com/upx/upx/milestone/6
|
||||||
* bug fixes - see https://github.com/upx/upx/milestone/7
|
* bug fixes - see https://github.com/upx/upx/milestone/7
|
||||||
|
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
|
|
||||||
|
|
||||||
The Ultimate Packer for eXecutables
|
The Ultimate Packer for eXecutables
|
||||||
Copyright (c) 1996-2022 Markus Oberhumer, Laszlo Molnar & John Reiser
|
Copyright (c) 1996-2023 Markus Oberhumer, Laszlo Molnar & John Reiser
|
||||||
https://upx.github.io
|
https://upx.github.io
|
||||||
|
|
||||||
|
|
||||||
@@ -85,9 +85,9 @@ THE FUTURE
|
|||||||
COPYRIGHT
|
COPYRIGHT
|
||||||
=========
|
=========
|
||||||
|
|
||||||
Copyright (C) 1996-2022 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2022 Laszlo Molnar
|
Copyright (C) 1996-2023 Laszlo Molnar
|
||||||
Copyright (C) 2000-2022 John F. Reiser
|
Copyright (C) 2000-2023 John F. Reiser
|
||||||
|
|
||||||
UPX is distributed with full source code under the terms of the
|
UPX is distributed with full source code under the terms of the
|
||||||
GNU General Public License v2+; either under the pure GPLv2+ (see
|
GNU General Public License v2+; either under the pure GPLv2+ (see
|
||||||
|
|||||||
+2
-1
@@ -44,7 +44,8 @@ Short overview
|
|||||||
Tools needed to build/modify the UPX sources
|
Tools needed to build/modify the UPX sources
|
||||||
--------------------------------------------
|
--------------------------------------------
|
||||||
|
|
||||||
- A C++ compiler that supports C++ 14: clang, gcc or msvc
|
- A C++ compiler that supports C++ 17: clang-5, gcc-8 or msvc-2019 16.11
|
||||||
|
(older or other compilers may work but are unsupported, use at your own risk)
|
||||||
|
|
||||||
- GNU make
|
- GNU make
|
||||||
|
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
|
|
||||||
|
|
||||||
The Ultimate Packer for eXecutables
|
The Ultimate Packer for eXecutables
|
||||||
Copyright (c) 1996-2022 Markus Oberhumer, Laszlo Molnar & John Reiser
|
Copyright (c) 1996-2023 Markus Oberhumer, Laszlo Molnar & John Reiser
|
||||||
https://upx.github.io
|
https://upx.github.io
|
||||||
|
|
||||||
|
|
||||||
@@ -55,6 +55,6 @@ Salvador Eduardo Tropea
|
|||||||
for beta testing
|
for beta testing
|
||||||
Stefan Widmann
|
Stefan Widmann
|
||||||
for the win32/pe TLS callback support
|
for the win32/pe TLS callback support
|
||||||
The WINE project (http://www.winehq.com/)
|
The WINE project (https://www.winehq.com/)
|
||||||
for lots of useful information found in their PE loader sources
|
for lots of useful information found in their PE loader sources
|
||||||
Natascha
|
Natascha
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
-std=gnu++17
|
||||||
-Ivendor
|
-Ivendor
|
||||||
-fno-strict-aliasing
|
-fno-strict-aliasing
|
||||||
-fno-strict-overflow
|
-fno-strict-overflow
|
||||||
|
|||||||
+1
-1
@@ -8,7 +8,7 @@
|
|||||||
|
|
||||||
|
|
||||||
The Ultimate Packer for eXecutables
|
The Ultimate Packer for eXecutables
|
||||||
Copyright (c) 1996-2022 Markus Oberhumer, Laszlo Molnar & John Reiser
|
Copyright (c) 1996-2023 Markus Oberhumer, Laszlo Molnar & John Reiser
|
||||||
https://upx.github.io
|
https://upx.github.io
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+24
-35
@@ -1,21 +1,8 @@
|
|||||||
#
|
#
|
||||||
# UPX doc Makefile - needs GNU make
|
# UPX doc Makefile - needs GNU make, pod2html, pod2man and pod2text
|
||||||
#
|
#
|
||||||
|
|
||||||
MAKEFLAGS += -rR
|
BUILT_SOURCES = upx.1 upx-doc.html upx-doc.txt
|
||||||
.SUFFIXES:
|
|
||||||
SHELL = /bin/sh
|
|
||||||
|
|
||||||
# internal make variables
|
|
||||||
comma := ,
|
|
||||||
empty :=
|
|
||||||
space := $(empty) $(empty)
|
|
||||||
tab := $(empty) $(empty)
|
|
||||||
|
|
||||||
|
|
||||||
# /***********************************************************************
|
|
||||||
# //
|
|
||||||
# ************************************************************************/
|
|
||||||
|
|
||||||
top_srcdir ?= ..
|
top_srcdir ?= ..
|
||||||
|
|
||||||
@@ -23,28 +10,31 @@ PACKAGE = upx
|
|||||||
VERSION_DATE := $(shell sed -n 's/^.*UPX_VERSION_DATE_ISO .*"\(.*\)".*/\1/p' $(top_srcdir)/src/version.h)
|
VERSION_DATE := $(shell sed -n 's/^.*UPX_VERSION_DATE_ISO .*"\(.*\)".*/\1/p' $(top_srcdir)/src/version.h)
|
||||||
VERSION := $(shell sed -n 's/^.*UPX_VERSION_STRING .*"\(.*\)".*/\1/p' $(top_srcdir)/src/version.h)
|
VERSION := $(shell sed -n 's/^.*UPX_VERSION_STRING .*"\(.*\)".*/\1/p' $(top_srcdir)/src/version.h)
|
||||||
|
|
||||||
|
# internal make variables
|
||||||
|
comma := ,
|
||||||
|
empty :=
|
||||||
|
space := $(empty) $(empty)
|
||||||
|
tab := $(empty) $(empty)
|
||||||
|
|
||||||
RTRIM := sed -e 's/[ $(tab)]*$$//'
|
RTRIM := sed -e 's/[ $(tab)]*$$//'
|
||||||
DETAB2 := sed -e 's/$(tab)/ /g'
|
DETAB2 := sed -e 's/$(tab)/ /g'
|
||||||
|
|
||||||
BUILT_SOURCES = upx.1 upx-doc.html upx-doc.txt
|
#***********************************************************************
|
||||||
|
# targets
|
||||||
|
#***********************************************************************
|
||||||
|
|
||||||
|
.DEFAULT_GOAL = all
|
||||||
|
|
||||||
###
|
all: $(BUILT_SOURCES) PHONY
|
||||||
### targets
|
|
||||||
###
|
|
||||||
|
|
||||||
all: $(BUILT_SOURCES)
|
mostlyclean clean distclean maintainer-clean: PHONY
|
||||||
|
rm -f $(BUILT_SOURCES) ./pod2htm*
|
||||||
|
|
||||||
mostlyclean clean distclean maintainer-clean:
|
#***********************************************************************
|
||||||
rm -f $(BUILT_SOURCES) pod2htm*
|
# rules
|
||||||
|
#***********************************************************************
|
||||||
.PHONY: all mostlyclean clean distclean maintainer-clean
|
|
||||||
|
|
||||||
|
|
||||||
###
|
|
||||||
### rules
|
|
||||||
###
|
|
||||||
|
|
||||||
|
.SUFFIXES:
|
||||||
.SUFFIXES: .1 .html .man .pod .ps .tex .txt
|
.SUFFIXES: .1 .html .man .pod .ps .tex .txt
|
||||||
|
|
||||||
%.1 : %.pod
|
%.1 : %.pod
|
||||||
@@ -53,7 +43,7 @@ mostlyclean clean distclean maintainer-clean:
|
|||||||
|
|
||||||
%-doc.html : %.pod
|
%-doc.html : %.pod
|
||||||
pod2html --noindex $< | $(RTRIM) | $(DETAB2) > $@
|
pod2html --noindex $< | $(RTRIM) | $(DETAB2) > $@
|
||||||
@rm -f pod2htm*
|
@rm -f ./pod2htm*
|
||||||
test -s $@
|
test -s $@
|
||||||
|
|
||||||
%.man : %.1
|
%.man : %.1
|
||||||
@@ -72,11 +62,10 @@ mostlyclean clean distclean maintainer-clean:
|
|||||||
pod2text < $< | $(RTRIM) > $@
|
pod2text < $< | $(RTRIM) > $@
|
||||||
test -s $@
|
test -s $@
|
||||||
|
|
||||||
|
#***********************************************************************
|
||||||
###
|
# dependencies
|
||||||
### dependencies
|
#***********************************************************************
|
||||||
###
|
|
||||||
|
|
||||||
$(BUILT_SOURCES): $(top_srcdir)/src/version.h $(MAKEFILE_LIST)
|
$(BUILT_SOURCES): $(top_srcdir)/src/version.h $(MAKEFILE_LIST)
|
||||||
.DELETE_ON_ERROR: $(BUILT_SOURCES)
|
.DELETE_ON_ERROR: $(BUILT_SOURCES)
|
||||||
|
.PHONY: PHONY
|
||||||
|
|||||||
+1
-1
@@ -1,5 +1,5 @@
|
|||||||
Decompressing ELF Directly to Memory on Linux/x86
|
Decompressing ELF Directly to Memory on Linux/x86
|
||||||
Copyright (C) 2000-2022 John F. Reiser jreiser@BitWagon.com
|
Copyright (C) 2000-2023 John F. Reiser jreiser@BitWagon.com
|
||||||
|
|
||||||
References:
|
References:
|
||||||
<elf.h> definitions for the ELF file format
|
<elf.h> definitions for the ELF file format
|
||||||
|
|||||||
+5
-5
@@ -22,7 +22,7 @@
|
|||||||
<h1 id="ABSTRACT">ABSTRACT</h1>
|
<h1 id="ABSTRACT">ABSTRACT</h1>
|
||||||
|
|
||||||
<pre><code> The Ultimate Packer for eXecutables
|
<pre><code> The Ultimate Packer for eXecutables
|
||||||
Copyright (c) 1996-2022 Markus Oberhumer, Laszlo Molnar & John Reiser
|
Copyright (c) 1996-2023 Markus Oberhumer, Laszlo Molnar & John Reiser
|
||||||
https://upx.github.io</code></pre>
|
https://upx.github.io</code></pre>
|
||||||
|
|
||||||
<p><b>UPX</b> is a portable, extendable, high-performance executable packer for several different executable formats. It achieves an excellent compression ratio and offers <i>*very*</i> fast decompression. Your executables suffer no memory overhead or other drawbacks for most of the formats supported, because of in-place decompression.</p>
|
<p><b>UPX</b> is a portable, extendable, high-performance executable packer for several different executable formats. It achieves an excellent compression ratio and offers <i>*very*</i> fast decompression. Your executables suffer no memory overhead or other drawbacks for most of the formats supported, because of in-place decompression.</p>
|
||||||
@@ -785,13 +785,13 @@ Jens Medoch <jssg@users.sourceforge.net></code></pre>
|
|||||||
|
|
||||||
<h1 id="COPYRIGHT">COPYRIGHT</h1>
|
<h1 id="COPYRIGHT">COPYRIGHT</h1>
|
||||||
|
|
||||||
<p>Copyright (C) 1996-2022 Markus Franz Xaver Johannes Oberhumer</p>
|
<p>Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer</p>
|
||||||
|
|
||||||
<p>Copyright (C) 1996-2022 Laszlo Molnar</p>
|
<p>Copyright (C) 1996-2023 Laszlo Molnar</p>
|
||||||
|
|
||||||
<p>Copyright (C) 2000-2022 John F. Reiser</p>
|
<p>Copyright (C) 2000-2023 John F. Reiser</p>
|
||||||
|
|
||||||
<p>Copyright (C) 2002-2022 Jens Medoch</p>
|
<p>Copyright (C) 2002-2023 Jens Medoch</p>
|
||||||
|
|
||||||
<p><b>UPX</b> is distributed with full source code under the terms of the GNU General Public License v2+; either under the pure GPLv2+ (see the file COPYING), or (at your option) under the GPLv+2 with special exceptions and restrictions granting the free usage for all binaries including commercial programs (see the file LICENSE).</p>
|
<p><b>UPX</b> is distributed with full source code under the terms of the GNU General Public License v2+; either under the pure GPLv2+ (see the file COPYING), or (at your option) under the GPLv+2 with special exceptions and restrictions granting the free usage for all binaries including commercial programs (see the file LICENSE).</p>
|
||||||
|
|
||||||
|
|||||||
+5
-5
@@ -6,7 +6,7 @@ SYNOPSIS
|
|||||||
|
|
||||||
ABSTRACT
|
ABSTRACT
|
||||||
The Ultimate Packer for eXecutables
|
The Ultimate Packer for eXecutables
|
||||||
Copyright (c) 1996-2022 Markus Oberhumer, Laszlo Molnar & John Reiser
|
Copyright (c) 1996-2023 Markus Oberhumer, Laszlo Molnar & John Reiser
|
||||||
https://upx.github.io
|
https://upx.github.io
|
||||||
|
|
||||||
UPX is a portable, extendable, high-performance executable packer for
|
UPX is a portable, extendable, high-performance executable packer for
|
||||||
@@ -818,13 +818,13 @@ AUTHORS
|
|||||||
Jens Medoch <jssg@users.sourceforge.net>
|
Jens Medoch <jssg@users.sourceforge.net>
|
||||||
|
|
||||||
COPYRIGHT
|
COPYRIGHT
|
||||||
Copyright (C) 1996-2022 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer
|
||||||
|
|
||||||
Copyright (C) 1996-2022 Laszlo Molnar
|
Copyright (C) 1996-2023 Laszlo Molnar
|
||||||
|
|
||||||
Copyright (C) 2000-2022 John F. Reiser
|
Copyright (C) 2000-2023 John F. Reiser
|
||||||
|
|
||||||
Copyright (C) 2002-2022 Jens Medoch
|
Copyright (C) 2002-2023 Jens Medoch
|
||||||
|
|
||||||
UPX is distributed with full source code under the terms of the GNU
|
UPX is distributed with full source code under the terms of the GNU
|
||||||
General Public License v2+; either under the pure GPLv2+ (see the file
|
General Public License v2+; either under the pure GPLv2+ (see the file
|
||||||
|
|||||||
@@ -133,7 +133,7 @@
|
|||||||
.\" ========================================================================
|
.\" ========================================================================
|
||||||
.\"
|
.\"
|
||||||
.IX Title "UPX 1"
|
.IX Title "UPX 1"
|
||||||
.TH UPX 1 "2022-10-28" "upx 4.0.0" " "
|
.TH UPX 1 "2023-01-30" "upx 4.0.2" " "
|
||||||
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
|
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
|
||||||
.\" way too many mistakes in technical documents.
|
.\" way too many mistakes in technical documents.
|
||||||
.if n .ad l
|
.if n .ad l
|
||||||
@@ -147,7 +147,7 @@ upx \- compress or expand executable files
|
|||||||
.IX Header "ABSTRACT"
|
.IX Header "ABSTRACT"
|
||||||
.Vb 3
|
.Vb 3
|
||||||
\& The Ultimate Packer for eXecutables
|
\& The Ultimate Packer for eXecutables
|
||||||
\& Copyright (c) 1996\-2022 Markus Oberhumer, Laszlo Molnar & John Reiser
|
\& Copyright (c) 1996\-2023 Markus Oberhumer, Laszlo Molnar & John Reiser
|
||||||
\& https://upx.github.io
|
\& https://upx.github.io
|
||||||
.Ve
|
.Ve
|
||||||
.PP
|
.PP
|
||||||
@@ -1019,13 +1019,13 @@ Please report all bugs immediately to the authors.
|
|||||||
.Ve
|
.Ve
|
||||||
.SH "COPYRIGHT"
|
.SH "COPYRIGHT"
|
||||||
.IX Header "COPYRIGHT"
|
.IX Header "COPYRIGHT"
|
||||||
Copyright (C) 1996\-2022 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996\-2023 Markus Franz Xaver Johannes Oberhumer
|
||||||
.PP
|
.PP
|
||||||
Copyright (C) 1996\-2022 Laszlo Molnar
|
Copyright (C) 1996\-2023 Laszlo Molnar
|
||||||
.PP
|
.PP
|
||||||
Copyright (C) 2000\-2022 John F. Reiser
|
Copyright (C) 2000\-2023 John F. Reiser
|
||||||
.PP
|
.PP
|
||||||
Copyright (C) 2002\-2022 Jens Medoch
|
Copyright (C) 2002\-2023 Jens Medoch
|
||||||
.PP
|
.PP
|
||||||
\&\fB\s-1UPX\s0\fR is distributed with full source code under the terms of the
|
\&\fB\s-1UPX\s0\fR is distributed with full source code under the terms of the
|
||||||
\&\s-1GNU\s0 General Public License v2+; either under the pure GPLv2+ (see
|
\&\s-1GNU\s0 General Public License v2+; either under the pure GPLv2+ (see
|
||||||
|
|||||||
+5
-5
@@ -13,7 +13,7 @@ B<upx> S<[ I<command> ]> S<[ I<options> ]> I<filename>...
|
|||||||
=head1 ABSTRACT
|
=head1 ABSTRACT
|
||||||
|
|
||||||
The Ultimate Packer for eXecutables
|
The Ultimate Packer for eXecutables
|
||||||
Copyright (c) 1996-2022 Markus Oberhumer, Laszlo Molnar & John Reiser
|
Copyright (c) 1996-2023 Markus Oberhumer, Laszlo Molnar & John Reiser
|
||||||
https://upx.github.io
|
https://upx.github.io
|
||||||
|
|
||||||
|
|
||||||
@@ -932,13 +932,13 @@ Please report all bugs immediately to the authors.
|
|||||||
|
|
||||||
=head1 COPYRIGHT
|
=head1 COPYRIGHT
|
||||||
|
|
||||||
Copyright (C) 1996-2022 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer
|
||||||
|
|
||||||
Copyright (C) 1996-2022 Laszlo Molnar
|
Copyright (C) 1996-2023 Laszlo Molnar
|
||||||
|
|
||||||
Copyright (C) 2000-2022 John F. Reiser
|
Copyright (C) 2000-2023 John F. Reiser
|
||||||
|
|
||||||
Copyright (C) 2002-2022 Jens Medoch
|
Copyright (C) 2002-2023 Jens Medoch
|
||||||
|
|
||||||
B<UPX> is distributed with full source code under the terms of the
|
B<UPX> is distributed with full source code under the terms of the
|
||||||
GNU General Public License v2+; either under the pure GPLv2+ (see
|
GNU General Public License v2+; either under the pure GPLv2+ (see
|
||||||
|
|||||||
+17
@@ -0,0 +1,17 @@
|
|||||||
|
#! /usr/bin/env bash
|
||||||
|
## vim:set ts=4 sw=4 et:
|
||||||
|
set -e; set -o pipefail
|
||||||
|
argv0=$0; argv0abs="$(readlink -fn "$argv0")"; argv0dir="$(dirname "$argv0abs")"
|
||||||
|
|
||||||
|
# create the image from Dockerfile
|
||||||
|
# using a rootless Podman container
|
||||||
|
|
||||||
|
# NOTE: this image is based on rebuild-stubs-with-podman/upx-stubtools-20221212-v4,
|
||||||
|
# so you have to create that image first
|
||||||
|
# WARNING: we install many packages, so the resulting image needs A LOT of disk space!
|
||||||
|
image=upx-cross-compile-20230115-v2
|
||||||
|
|
||||||
|
podman build -t "$image" -f "$argv0dir/Dockerfile" "$argv0dir"
|
||||||
|
|
||||||
|
podman image list "$image"
|
||||||
|
podman image tree "$image"
|
||||||
@@ -0,0 +1,53 @@
|
|||||||
|
#! /usr/bin/env bash
|
||||||
|
## vim:set ts=4 sw=4 et:
|
||||||
|
set -e; set -o pipefail
|
||||||
|
argv0=$0; argv0abs="$(readlink -fn "$argv0")"; argv0dir="$(dirname "$argv0abs")"
|
||||||
|
|
||||||
|
# run an interactive shell in the image
|
||||||
|
# using a rootless Podman container
|
||||||
|
|
||||||
|
image=upx-cross-compile-20230115-v2
|
||||||
|
|
||||||
|
flags=( -ti --read-only --rm )
|
||||||
|
flags+=( --cap-drop=all ) # drop all capabilities
|
||||||
|
flags+=( --network=none ) # no network needed
|
||||||
|
flags+=( -e TERM="$TERM" ) # pass $TERM
|
||||||
|
if [[ 1 == 1 ]]; then
|
||||||
|
# run as user upx 2000:2000
|
||||||
|
flags+=( --user 2000 )
|
||||||
|
# map container users 0..999 to subuid-users 1..1000, and map container user 2000 to current host user
|
||||||
|
flags+=( --uidmap=0:1:1000 --uidmap=2000:0:1 )
|
||||||
|
# map container groups 0..999 to subgid-groups 1..1000, and map container group 2000 to current host group
|
||||||
|
flags+=( --gidmap=0:1:1000 --gidmap=2000:0:1 )
|
||||||
|
# NOTE: we mount the upx top-level directory read-write under /home/upx/src/upx
|
||||||
|
# INFO: SELinux users *may* have to add ":z" to the volume mount flags; check the docs!
|
||||||
|
flags+=( -v "${argv0dir}/../..:/home/upx/src/upx" )
|
||||||
|
flags+=( -w /home/upx/src/upx ) # set working directory
|
||||||
|
else
|
||||||
|
# run as user root 0:0
|
||||||
|
# ONLY FOR DEBUGGING THE IMAGE
|
||||||
|
# map container user/group 0 to current host user/group
|
||||||
|
flags+=( --user 0 )
|
||||||
|
fi
|
||||||
|
|
||||||
|
podman run "${flags[@]}" "$image" bash -l
|
||||||
|
|
||||||
|
# now we can cross-compile UPX for Windows:
|
||||||
|
# cd /home/upx/src/upx
|
||||||
|
# rm -rf ./build/extra/cross-windows-mingw64/release
|
||||||
|
# make build/extra/cross-windows-mingw64/release
|
||||||
|
|
||||||
|
# and we can run the clang Static Analyzer (scan-build)
|
||||||
|
# cd /home/upx/src/upx
|
||||||
|
# rm -rf ./build/extra/scan-build/release
|
||||||
|
# make build/extra/scan-build/release
|
||||||
|
|
||||||
|
# and lots of other cross-compilers are installed; see "ls /usr/bin/*g++*"
|
||||||
|
|
||||||
|
# and finally see misc/cross-compile-upx-with-podman/build-all-inside-container.sh
|
||||||
|
# after running that script we can do cool things like:
|
||||||
|
# cd /home/upx/src/upx/build/cross-compile-upx-with-podman/alpha-linux-gnu/debug
|
||||||
|
# qemu-alpha -L /usr/alpha-linux-gnu upx --version
|
||||||
|
# cd /home/upx/src/upx/build/cross-compile-upx-with-podman/hppa-linux-gnu/debug
|
||||||
|
# qemu-hppa -L /usr/hppa-linux-gnu upx --version
|
||||||
|
# (similar for many other architectures/builds)
|
||||||
@@ -0,0 +1,54 @@
|
|||||||
|
# NOTE: this image is based on rebuild-stubs-with-podman/upx-stubtools-20221212-v4,
|
||||||
|
# so you have to create that image first
|
||||||
|
# WARNING: we install many packages, so the resulting image needs A LOT of disk space!
|
||||||
|
FROM localhost/upx-stubtools-20221212-v4
|
||||||
|
ENV UPX_CONTAINER_IMAGE_NAME=upx-cross-compile-20230115-v2
|
||||||
|
ARG DEBIAN_FRONTEND=noninteractive
|
||||||
|
|
||||||
|
USER root
|
||||||
|
|
||||||
|
# Ubuntu 22.04
|
||||||
|
RUN apt-get update && apt-get upgrade -y \
|
||||||
|
&& apt-get install -y \
|
||||||
|
# Linux glibc cross compilers
|
||||||
|
g++-aarch64-linux-gnu \
|
||||||
|
g++-alpha-linux-gnu \
|
||||||
|
g++-arm-linux-gnueabi \
|
||||||
|
g++-arm-linux-gnueabihf \
|
||||||
|
g++-hppa-linux-gnu \
|
||||||
|
g++-i686-linux-gnu \
|
||||||
|
g++-m68k-linux-gnu \
|
||||||
|
g++-mips-linux-gnu \
|
||||||
|
g++-mipsel-linux-gnu \
|
||||||
|
g++-mips64-linux-gnuabi64 \
|
||||||
|
g++-mips64el-linux-gnuabi64 \
|
||||||
|
g++-powerpc-linux-gnu \
|
||||||
|
g++-powerpc64-linux-gnu \
|
||||||
|
g++-powerpc64le-linux-gnu \
|
||||||
|
g++-riscv64-linux-gnu \
|
||||||
|
g++-s390x-linux-gnu \
|
||||||
|
g++-sh4-linux-gnu \
|
||||||
|
g++-sparc64-linux-gnu \
|
||||||
|
# Linux glibc cross compilers - ILP32 on 64-bit CPUs
|
||||||
|
g++-x86-64-linux-gnux32 \
|
||||||
|
# Windows cross compilers
|
||||||
|
g++-mingw-w64-i686 \
|
||||||
|
g++-mingw-w64-x86-64 \
|
||||||
|
&& true
|
||||||
|
RUN apt-get install -y \
|
||||||
|
# clang-14 and tools
|
||||||
|
clang-14 clang-format-14 clang-tidy-14 clang-tools-14 lldb-14 llvm-14 \
|
||||||
|
# QEMU and Wine
|
||||||
|
qemu-system qemu-user wine wine32 \
|
||||||
|
# misc
|
||||||
|
gdb lsb-release valgrind \
|
||||||
|
&& true
|
||||||
|
RUN cd /usr/bin \
|
||||||
|
# create unversioned clang symlinks in /usr/local/bin
|
||||||
|
&& for f in clang*-14 llvm-*-14 scan-*-14; do ln -s -v ../../bin/$f /usr/local/bin/${f%-14}; done \
|
||||||
|
&& ln -s -v ../../bin/obj2yaml-14 /usr/local/bin/llvm-obj2yaml \
|
||||||
|
&& ln -s -v ../../bin/yaml2obj-14 /usr/local/bin/llvm-yaml2obj \
|
||||||
|
&& true
|
||||||
|
|
||||||
|
# switch back to default user upx 2000:2000
|
||||||
|
USER upx
|
||||||
@@ -0,0 +1,93 @@
|
|||||||
|
#! /usr/bin/env bash
|
||||||
|
## vim:set ts=4 sw=4 et:
|
||||||
|
set -e; set -o pipefail
|
||||||
|
argv0=$0; argv0abs="$(readlink -fn "$argv0")"; argv0dir="$(dirname "$argv0abs")"
|
||||||
|
|
||||||
|
# build UPX for 21 targets; must be run inside the container!
|
||||||
|
# using a rootless Podman container
|
||||||
|
|
||||||
|
# simple sanity check that we are indeed running inside the container
|
||||||
|
if [[ $UPX_CONTAINER_IMAGE_NAME != upx-cross-compile-* ]]; then
|
||||||
|
echo "$argv0: NOTE: please run this script *inside* the container"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# go to upx top-level directory
|
||||||
|
cd "$argv0dir/../.." || exit 1
|
||||||
|
pwd
|
||||||
|
[[ -f src/version.h ]] || exit 1 # sanity check
|
||||||
|
|
||||||
|
function run_config_and_build {
|
||||||
|
# requires: AR CC CXX RANLIB
|
||||||
|
local toolchain=$1
|
||||||
|
local cmake_config_flags build_type bdir
|
||||||
|
# cmake flags
|
||||||
|
cmake_config_flags=
|
||||||
|
case $toolchain in
|
||||||
|
# these old architectures do not support sanitize
|
||||||
|
alpha-linux-gnu) cmake_config_flags=-DUPX_CONFIG_DISABLE_SANITIZE=ON ;;
|
||||||
|
hppa-linux-gnu) cmake_config_flags=-DUPX_CONFIG_DISABLE_SANITIZE=ON ;;
|
||||||
|
# avoid link errors with current MinGW-w64 versions
|
||||||
|
i686-w64-mingw32) cmake_config_flags=-DUPX_CONFIG_DISABLE_SANITIZE=ON ;;
|
||||||
|
x86_64-w64-mingw32) cmake_config_flags=-DUPX_CONFIG_DISABLE_SANITIZE=ON ;;
|
||||||
|
# avoid warnings about arm libstdc++ ABI change in gcc-7
|
||||||
|
arm-linux-*) CXX="$CXX -Wno-psabi" ;;
|
||||||
|
esac
|
||||||
|
if [[ 1 == 1 ]]; then
|
||||||
|
# prefer building with Ninja (ninja-build)
|
||||||
|
cmake_config_flags="$cmake_config_flags -G Ninja -DUPX_CONFIG_CMAKE_DISABLE_INSTALL=ON"
|
||||||
|
fi
|
||||||
|
# for all build types
|
||||||
|
for build_type in Debug Release; do
|
||||||
|
bdir=build/cross-compile-upx-with-podman/$toolchain/${build_type,,}
|
||||||
|
mkdir -p $bdir
|
||||||
|
# run_config
|
||||||
|
if [[ ! -f $bdir/CMakeCache.txt ]]; then
|
||||||
|
cmake -S . -B $bdir -DCMAKE_BUILD_TYPE=$build_type -DCMAKE_AR=$AR -DCMAKE_RANLIB=$RANLIB $cmake_config_flags
|
||||||
|
fi
|
||||||
|
# run_build
|
||||||
|
cmake --build $bdir --config $build_type --parallel
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
# see Dockerfile for packages
|
||||||
|
for package in \
|
||||||
|
g++-aarch64-linux-gnu \
|
||||||
|
g++-alpha-linux-gnu \
|
||||||
|
g++-arm-linux-gnueabi \
|
||||||
|
g++-arm-linux-gnueabihf \
|
||||||
|
g++-hppa-linux-gnu \
|
||||||
|
g++-i686-linux-gnu \
|
||||||
|
g++-m68k-linux-gnu \
|
||||||
|
g++-mips-linux-gnu \
|
||||||
|
g++-mipsel-linux-gnu \
|
||||||
|
g++-mips64-linux-gnuabi64 \
|
||||||
|
g++-mips64el-linux-gnuabi64 \
|
||||||
|
g++-powerpc-linux-gnu \
|
||||||
|
g++-powerpc64-linux-gnu \
|
||||||
|
g++-powerpc64le-linux-gnu \
|
||||||
|
g++-riscv64-linux-gnu \
|
||||||
|
g++-s390x-linux-gnu \
|
||||||
|
g++-sh4-linux-gnu \
|
||||||
|
g++-sparc64-linux-gnu \
|
||||||
|
g++-x86-64-linux-gnux32 \
|
||||||
|
g++-mingw-w64-i686 \
|
||||||
|
g++-mingw-w64-x86-64
|
||||||
|
do
|
||||||
|
# setup toolchain and environment variables
|
||||||
|
toolchain=$package
|
||||||
|
toolchain=${toolchain/-x86-64/-x86_64}
|
||||||
|
toolchain=${toolchain/g++-/}
|
||||||
|
case $toolchain in
|
||||||
|
mingw-w64-i686) toolchain=i686-w64-mingw32 ;;
|
||||||
|
mingw-w64-x86_64) toolchain=x86_64-w64-mingw32 ;;
|
||||||
|
esac
|
||||||
|
echo "========== $toolchain"
|
||||||
|
export AR=/usr/bin/${toolchain}-ar
|
||||||
|
export CC=/usr/bin/${toolchain}-gcc
|
||||||
|
export CXX=/usr/bin/${toolchain}-g++
|
||||||
|
export RANLIB=/usr/bin/${toolchain}-ranlib
|
||||||
|
ls -l $AR $CC $CXX $RANLIB
|
||||||
|
run_config_and_build $toolchain
|
||||||
|
unset AR CC CXX RANLIB
|
||||||
|
done
|
||||||
@@ -6,7 +6,7 @@ argv0=$0; argv0abs="$(readlink -fn "$argv0")"; argv0dir="$(dirname "$argv0abs")"
|
|||||||
# create the image from Dockerfile
|
# create the image from Dockerfile
|
||||||
# using a rootless Podman container
|
# using a rootless Podman container
|
||||||
|
|
||||||
image=upx-stubtools-20210104-v5
|
image=upx-stubtools-20221212-v4
|
||||||
|
|
||||||
podman build -t "$image" -f "$argv0dir/Dockerfile" "$argv0dir"
|
podman build -t "$image" -f "$argv0dir/Dockerfile" "$argv0dir"
|
||||||
|
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ argv0=$0; argv0abs="$(readlink -fn "$argv0")"; argv0dir="$(dirname "$argv0abs")"
|
|||||||
# run an interactive shell in the image
|
# run an interactive shell in the image
|
||||||
# using a rootless Podman container
|
# using a rootless Podman container
|
||||||
|
|
||||||
image=upx-stubtools-20210104-v5
|
image=upx-stubtools-20221212-v4
|
||||||
|
|
||||||
flags=( -ti --read-only --rm )
|
flags=( -ti --read-only --rm )
|
||||||
flags+=( --cap-drop=all ) # drop all capabilities
|
flags+=( --cap-drop=all ) # drop all capabilities
|
||||||
@@ -15,14 +15,14 @@ flags+=( -e TERM="$TERM" ) # pass $TERM
|
|||||||
if [[ 1 == 1 ]]; then
|
if [[ 1 == 1 ]]; then
|
||||||
# run as user upx 2000:2000
|
# run as user upx 2000:2000
|
||||||
flags+=( --user 2000 )
|
flags+=( --user 2000 )
|
||||||
# map container user 0 to subuid-user 1, and map container user 2000 to current host user
|
# map container users 0..999 to subuid-users 1..1000, and map container user 2000 to current host user
|
||||||
flags+=( --uidmap=0:1:1 --uidmap=2000:0:1 )
|
flags+=( --uidmap=0:1:1000 --uidmap=2000:0:1 )
|
||||||
# map container group 0 to subgid-group 1, and map container group 2000 to current host group
|
# map container groups 0..999 to subgid-groups 1..1000, and map container group 2000 to current host group
|
||||||
flags+=( --gidmap=0:1:1 --gidmap=2000:0:1 )
|
flags+=( --gidmap=0:1:1000 --gidmap=2000:0:1 )
|
||||||
# NOTE: we mount the upx top-level directory read-write under /home/upx/src/upx
|
# NOTE: we mount the upx top-level directory read-write under /home/upx/src/upx
|
||||||
# INFO: SELinux users *may* have to add ":z" to the volume mount flags; check the docs!
|
# INFO: SELinux users *may* have to add ":z" to the volume mount flags; check the docs!
|
||||||
flags+=( -v "${argv0dir}/../..:/home/upx/src/upx" )
|
flags+=( -v "${argv0dir}/../..:/home/upx/src/upx" )
|
||||||
flags+=( -w /home/upx/src/upx ) # working directory
|
flags+=( -w /home/upx/src/upx ) # set working directory
|
||||||
else
|
else
|
||||||
# run as user root 0:0
|
# run as user root 0:0
|
||||||
# ONLY FOR DEBUGGING THE IMAGE
|
# ONLY FOR DEBUGGING THE IMAGE
|
||||||
@@ -37,10 +37,40 @@ podman run "${flags[@]}" "$image" bash -l
|
|||||||
# # make sure that git is clean:
|
# # make sure that git is clean:
|
||||||
# git status .
|
# git status .
|
||||||
# # remove stub files and make sure that they got deleted:
|
# # remove stub files and make sure that they got deleted:
|
||||||
# make maintainer-clean
|
# make maintainer-clean extra-clean
|
||||||
# git status .
|
# git status .
|
||||||
# # rebuild
|
# # rebuild
|
||||||
# make all
|
# make extra-all all
|
||||||
# # make sure that the stub files did rebuild correctly:
|
# # make sure that the stub files did rebuild correctly:
|
||||||
# git status .
|
# git status .
|
||||||
# git diff .
|
# git diff .
|
||||||
|
|
||||||
|
# we can also build UPX in the container:
|
||||||
|
# cd /home/upx/src/upx
|
||||||
|
# rm -rf ./build/extra/gcc/release
|
||||||
|
# make build/extra/gcc/release
|
||||||
|
# # run tests
|
||||||
|
# ./build/extra/gcc/release/upx --version
|
||||||
|
# make -C build/extra/gcc/release test
|
||||||
|
|
||||||
|
# and we can also build UPX with -m32:
|
||||||
|
# cd /home/upx/src/upx
|
||||||
|
# rm -rf ./build/extra/gcc-m32/release
|
||||||
|
# make build/extra/gcc-m32/release
|
||||||
|
# # run tests
|
||||||
|
# ./build/extra/gcc-m32/release/upx --version
|
||||||
|
# make -C build/extra/gcc-m32/release test
|
||||||
|
|
||||||
|
# and we can also build UPX with -mx32: (NOTE: needs CONFIG_X86_X32_ABI on host kernel!)
|
||||||
|
# cd /home/upx/src/upx
|
||||||
|
# rm -rf ./build/extra/gcc-mx32/release
|
||||||
|
# make build/extra/gcc-mx32/release
|
||||||
|
# # run tests (needs CONFIG_X86_X32_ABI on host kernel)
|
||||||
|
# ./build/extra/gcc-mx32/release/upx --version
|
||||||
|
# make -C build/extra/gcc-mx32/release test
|
||||||
|
|
||||||
|
# and we can also rebuild the UPX docs the container:
|
||||||
|
# cd /home/upx/src/upx/doc
|
||||||
|
# make clean all
|
||||||
|
# git status .
|
||||||
|
# git diff .
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
FROM docker.io/library/ubuntu:22.04
|
FROM docker.io/library/ubuntu:22.04
|
||||||
|
ENV UPX_CONTAINER_IMAGE_NAME=upx-stubtools-20221212-v4
|
||||||
ARG DEBIAN_FRONTEND=noninteractive
|
ARG DEBIAN_FRONTEND=noninteractive
|
||||||
ENV LANG=C.UTF-8
|
ENV LANG=C.UTF-8
|
||||||
|
|
||||||
@@ -9,19 +10,20 @@ RUN dpkg --add-architecture i386 \
|
|||||||
aria2 ca-certificates git less libmpc3 libncurses5 make \
|
aria2 ca-certificates git less libmpc3 libncurses5 make \
|
||||||
ncurses-term perl-base python2-minimal wget xz-utils \
|
ncurses-term perl-base python2-minimal wget xz-utils \
|
||||||
libc6:i386 zlib1g:i386 \
|
libc6:i386 zlib1g:i386 \
|
||||||
# the following packages are not required for rebuilding the stubs,
|
# the following packages are not required for rebuilding the stubs, but
|
||||||
# but they do make the image more convenient and also allow building
|
# they do make the image much more convenient and also allow building
|
||||||
# the full UPX binary inside the container via CMake:
|
# the full UPX binary inside the container via CMake:
|
||||||
bzip2 cmake elfutils file g++ libzstd-dev lzop ninja-build patch \
|
7zip bfs bzip2 cmake curl elfutils fd-find file fzf g++ gdb gojq htop hyperfine \
|
||||||
patchelf pax-utils rsync unzip vim zip zlib1g-dev zsh zstd \
|
jq libzstd-dev lsb-release lzip lzop ninja-build p7zip patch patchelf pax-utils \
|
||||||
|
ripgrep rsync screen universal-ctags unzip vim zip zlib1g-dev zsh zstd \
|
||||||
|
# extra packages for compiling with "gcc -m32" and and "gcc -mx32":
|
||||||
|
gcc-multilib g++-multilib \
|
||||||
&& true
|
&& true
|
||||||
|
|
||||||
# manually install compat libs from Ubuntu 16.04
|
# manually install compat libs from Ubuntu 16.04; REQUIRED
|
||||||
RUN cd /root \
|
RUN cd /root \
|
||||||
&& aria2c --checksum=sha-256=2605f43f8047fc972855bb909f1dd7af761bbfd35ae559ad689b0d55a4236d69 \
|
&& aria2c --checksum=sha-256=de22baf3dd851a10e16fbf66a243e70149ca46e06b2939fdc79429196cefc090 \
|
||||||
'http://mirror.enzu.com/ubuntu/pool/main/g/gmp/libgmp10_6.1.0+dfsg-2_amd64.deb' \
|
'http://archive.kernel.org/ubuntu-archive/ubuntu/pool/main/m/mpfr4/libmpfr4_3.1.6-1_amd64.deb' \
|
||||||
&& aria2c --checksum=sha-256=3973a97387bbe0e8a775995c22861d8478edee2a594e8117970f635de25b2c8a \
|
|
||||||
'http://mirror.enzu.com/ubuntu/pool/main/m/mpfr4/libmpfr4_3.1.4-1_amd64.deb' \
|
|
||||||
&& mkdir packages \
|
&& mkdir packages \
|
||||||
&& for f in ./*.deb; do dpkg -x $f ./packages; done \
|
&& for f in ./*.deb; do dpkg -x $f ./packages; done \
|
||||||
&& mv -v -n ./packages/usr/lib/x86_64-linux-gnu/lib* /usr/lib/x86_64-linux-gnu/ \
|
&& mv -v -n ./packages/usr/lib/x86_64-linux-gnu/lib* /usr/lib/x86_64-linux-gnu/ \
|
||||||
@@ -29,38 +31,28 @@ RUN cd /root \
|
|||||||
&& ldconfig \
|
&& ldconfig \
|
||||||
&& true
|
&& true
|
||||||
|
|
||||||
# install upx-stubtools into /usr/local/bin/bin-upx-20210104
|
# install upx-stubtools into /usr/local/bin/bin-upx-20221212; REQUIRED
|
||||||
RUN cd /root \
|
RUN cd /root \
|
||||||
&& aria2c --checksum=sha-256=abcd8337cc656fe68d7bbb2ffe0f1e5ddce618688aa0e18c1ebcc40072843884 \
|
&& aria2c --checksum=sha-256=509e06639118a79d8e79489a400e134c6d3ca36bad2c6ec29648d7c1e5b81afa \
|
||||||
'https://github.com/upx/upx-stubtools/releases/download/v20210104/bin-upx-20210104.tar.xz' \
|
'https://github.com/upx/upx-stubtools/releases/download/v20221212/bin-upx-20221212.tar.xz' \
|
||||||
&& cd /usr/local/bin \
|
&& cd /usr/local/bin \
|
||||||
&& tar -xoaf /root/bin-upx-20210104.tar.xz \
|
&& tar -xoaf /root/bin-upx-20221212.tar.xz \
|
||||||
&& rm /root/bin-upx-20210104.tar.xz \
|
&& rm /root/bin-upx-20221212.tar.xz \
|
||||||
&& true
|
&& true
|
||||||
|
|
||||||
# install previous UPX versions into /usr/local/bin
|
# install official UPX release binaries into /usr/local/bin; not required but convenient for testing
|
||||||
RUN cd /root \
|
RUN cd /root \
|
||||||
&& wget -q https://github.com/upx/upx/releases/download/v3.91/upx-3.91-amd64_linux.tar.bz2 \
|
&& wget -q https://github.com/upx/upx/releases/download/v3.91/upx-3.91-amd64_linux.tar.bz2 \
|
||||||
&& wget -q https://github.com/upx/upx/releases/download/v3.92/upx-3.92-amd64_linux.tar.xz \
|
&& for v in 3.92 3.93 3.94 3.95 3.96 4.0.0 4.0.1 4.0.2; do wget -q https://github.com/upx/upx/releases/download/v${v}/upx-${v}-amd64_linux.tar.xz; done \
|
||||||
&& wget -q https://github.com/upx/upx/releases/download/v3.93/upx-3.93-amd64_linux.tar.xz \
|
|
||||||
&& wget -q https://github.com/upx/upx/releases/download/v3.94/upx-3.94-amd64_linux.tar.xz \
|
|
||||||
&& wget -q https://github.com/upx/upx/releases/download/v3.95/upx-3.95-amd64_linux.tar.xz \
|
|
||||||
&& wget -q https://github.com/upx/upx/releases/download/v3.96/upx-3.96-amd64_linux.tar.xz \
|
|
||||||
&& for f in ./upx-*.tar.*; do tar -xoaf $f; done \
|
&& for f in ./upx-*.tar.*; do tar -xoaf $f; done \
|
||||||
&& rm ./upx-*.tar.* \
|
&& for v in 3.91 3.92 3.93 3.94 3.95 3.96 4.0.0 4.0.1 4.0.2; do d=upx-${v}-amd64_linux; ./$d/upx -qq -d $d/upx -o /usr/local/bin/upx-${v}; done \
|
||||||
&& d=upx-3.91-amd64_linux; ./$d/upx -d $d/upx -o /usr/local/bin/upx-3.91 \
|
&& rm -r ./upx-*.tar.* ./upx-*linux \
|
||||||
&& d=upx-3.92-amd64_linux; ./$d/upx -d $d/upx -o /usr/local/bin/upx-3.92 \
|
|
||||||
&& d=upx-3.93-amd64_linux; ./$d/upx -d $d/upx -o /usr/local/bin/upx-3.93 \
|
|
||||||
&& d=upx-3.94-amd64_linux; ./$d/upx -d $d/upx -o /usr/local/bin/upx-3.94 \
|
|
||||||
&& d=upx-3.95-amd64_linux; ./$d/upx -d $d/upx -o /usr/local/bin/upx-3.95 \
|
|
||||||
&& d=upx-3.96-amd64_linux; ./$d/upx -d $d/upx -o /usr/local/bin/upx-3.96 \
|
|
||||||
&& rm -rf ./upx-*linux \
|
|
||||||
&& true
|
&& true
|
||||||
|
|
||||||
# create default user upx 2000:2000
|
# create default user upx 2000:2000
|
||||||
RUN useradd upx -U --uid 2000 --shell /bin/bash -m \
|
RUN useradd upx -U --uid 2000 --shell /bin/bash -m \
|
||||||
&& mkdir -p /home/upx/.local/bin /home/upx/src/upx \
|
&& mkdir -p /home/upx/.cache/zig /home/upx/.local/bin /home/upx/src/upx \
|
||||||
&& ln -s /usr/local/bin/bin-upx-20210104 /home/upx/.local/bin/bin-upx \
|
&& ln -s /usr/local/bin/bin-upx-20221212 /home/upx/.local/bin/bin-upx \
|
||||||
&& chown -R upx:upx /home/upx \
|
&& chown -R upx:upx /home/upx \
|
||||||
&& true
|
&& true
|
||||||
USER upx
|
USER upx
|
||||||
|
|||||||
@@ -4,22 +4,22 @@ set -e; set -o pipefail
|
|||||||
|
|
||||||
# "Gofmt's style is nobody's favourite, but gofmt is everybody's favourite." --Rob Pike
|
# "Gofmt's style is nobody's favourite, but gofmt is everybody's favourite." --Rob Pike
|
||||||
|
|
||||||
# NOTE: we are using clang-format-10.0.1 from upx-stubtools
|
# NOTE: we are using clang-format-15.0.6 from upx-stubtools
|
||||||
# see https://github.com/upx/upx-stubtools/releases
|
# see https://github.com/upx/upx-stubtools/releases
|
||||||
|
|
||||||
# NOTE: we use .clang-format config from upx.git/.clang-format
|
# NOTE: we use .clang-format config from upx.git/.clang-format
|
||||||
|
|
||||||
if [[ ! -f $UPX_CLANG_FORMAT ]]; then
|
if [[ ! -f $UPX_CLANG_FORMAT ]]; then
|
||||||
UPX_CLANG_FORMAT="$HOME/local/bin/bin-upx/clang-format-10.0.1"
|
UPX_CLANG_FORMAT="$HOME/local/bin/bin-upx/clang-format-15.0.6"
|
||||||
fi
|
fi
|
||||||
if [[ ! -f $UPX_CLANG_FORMAT ]]; then
|
if [[ ! -f $UPX_CLANG_FORMAT ]]; then
|
||||||
UPX_CLANG_FORMAT="$HOME/.local/bin/bin-upx/clang-format-10.0.1"
|
UPX_CLANG_FORMAT="$HOME/.local/bin/bin-upx/clang-format-15.0.6"
|
||||||
fi
|
fi
|
||||||
if [[ ! -f $UPX_CLANG_FORMAT ]]; then
|
if [[ ! -f $UPX_CLANG_FORMAT ]]; then
|
||||||
UPX_CLANG_FORMAT="$HOME/bin/bin-upx/clang-format-10.0.1"
|
UPX_CLANG_FORMAT="$HOME/bin/bin-upx/clang-format-15.0.6"
|
||||||
fi
|
fi
|
||||||
if [[ ! -f $UPX_CLANG_FORMAT ]]; then
|
if [[ ! -f $UPX_CLANG_FORMAT ]]; then
|
||||||
echo "ERROR: $0: cannot find clang-format-10.0.1"
|
echo "ERROR: $0: cannot find clang-format-15.0.6"
|
||||||
echo "ERROR: $0: please visit https://github.com/upx/upx-stubtools"
|
echo "ERROR: $0: please visit https://github.com/upx/upx-stubtools"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|||||||
+32
-29
@@ -21,19 +21,22 @@ endif
|
|||||||
# redirect to top-level CMake build
|
# redirect to top-level CMake build
|
||||||
#
|
#
|
||||||
|
|
||||||
default: debug
|
.DEFAULT_GOAL = build/debug
|
||||||
all: debug release
|
|
||||||
debug: $(top_srcdir)/build/debug/upx
|
|
||||||
release: $(top_srcdir)/build/release/upx
|
|
||||||
|
|
||||||
$(top_srcdir)/build/debug/upx:
|
build/debug: $(top_srcdir)/build/debug/upx
|
||||||
|
build/release: $(top_srcdir)/build/release/upx
|
||||||
|
# shortcuts
|
||||||
|
all: build/debug build/release
|
||||||
|
debug: build/debug
|
||||||
|
release: build/release
|
||||||
|
|
||||||
|
$(top_srcdir)/build/debug/upx: PHONY
|
||||||
$(MAKE) -C $(top_srcdir) build/debug
|
$(MAKE) -C $(top_srcdir) build/debug
|
||||||
$(top_srcdir)/build/release/upx:
|
$(top_srcdir)/build/release/upx: PHONY
|
||||||
$(MAKE) -C $(top_srcdir) build/release
|
$(MAKE) -C $(top_srcdir) build/release
|
||||||
|
|
||||||
.PHONY: default all debug release
|
.PHONY: PHONY
|
||||||
.PHONY: $(top_srcdir)/build/debug/upx
|
.NOTPARALLEL:
|
||||||
.PHONY: $(top_srcdir)/build/release/upx
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# "make run-testsuite"
|
# "make run-testsuite"
|
||||||
@@ -54,15 +57,18 @@ endif
|
|||||||
|
|
||||||
# run the UPX testsuite
|
# run the UPX testsuite
|
||||||
# The expected (old) checksums are in $(top_srcdir)/.github/travis_testsuite_1-expected_sha256sums.sh
|
# The expected (old) checksums are in $(top_srcdir)/.github/travis_testsuite_1-expected_sha256sums.sh
|
||||||
# The actual (new) checksums are in tmp-testsuite/testsuite_1/.sha256sums.recreate
|
# The actual (new) checksums are in ./tmp-testsuite/testsuite_1/.sha256sums.recreate
|
||||||
ifneq ($(wildcard $(upx_testsuite_SRCDIR)/files/packed/.),)
|
ifneq ($(wildcard $(upx_testsuite_SRCDIR)/files/packed/.),)
|
||||||
ifneq ($(wildcard $(top_srcdir)/.github/travis_testsuite_1.sh),)
|
ifneq ($(wildcard $(top_srcdir)/.github/travis_testsuite_1.sh),)
|
||||||
run-testsuite: export upx_exe := $(top_srcdir)/build/release/upx
|
run-testsuite: run-testsuite-release
|
||||||
run-testsuite: export upx_testsuite_SRCDIR := $(upx_testsuite_SRCDIR)
|
run-testsuite-%: export upx_testsuite_SRCDIR := $(upx_testsuite_SRCDIR)
|
||||||
run-testsuite: export upx_testsuite_BUILDDIR := ./tmp-testsuite
|
run-testsuite-%: export upx_testsuite_BUILDDIR := ./tmp-testsuite
|
||||||
run-testsuite: $(top_srcdir)/build/release/upx
|
run-testsuite-debug: export upx_exe := $(top_srcdir)/build/debug/upx
|
||||||
|
run-testsuite-debug: PHONY $(top_srcdir)/build/debug/upx
|
||||||
|
time -p bash $(top_srcdir)/.github/travis_testsuite_1.sh
|
||||||
|
run-testsuite-release: export upx_exe := $(top_srcdir)/build/release/upx
|
||||||
|
run-testsuite-release: PHONY $(top_srcdir)/build/release/upx
|
||||||
time -p bash $(top_srcdir)/.github/travis_testsuite_1.sh
|
time -p bash $(top_srcdir)/.github/travis_testsuite_1.sh
|
||||||
.PHONY: run-testsuite
|
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
||||||
@@ -72,18 +78,16 @@ endif
|
|||||||
|
|
||||||
# automatically format some C++ source code files
|
# automatically format some C++ source code files
|
||||||
ifeq ($(shell uname),Linux)
|
ifeq ($(shell uname),Linux)
|
||||||
CLANG_FORMAT_FILES += bele.h bele_policy.h
|
# Markus loves clang-format, but John hates it; find a compromise
|
||||||
CLANG_FORMAT_FILES += except.cpp except.h
|
CLANG_FORMAT_EXCLUDE_FILES += conf.h miniacc.h version.h help.cpp
|
||||||
CLANG_FORMAT_FILES += file.cpp file.h
|
CLANG_FORMAT_EXCLUDE_FILES += p_elf.h p_elf_enum.h p_lx_% p_mach% p_unix% p_vmli%
|
||||||
CLANG_FORMAT_FILES += linker.cpp linker.h packhead.cpp packmast.cpp packmast.h
|
CLANG_FORMAT_EXCLUDE_FILES += packer_c.cpp packer_f.cpp
|
||||||
CLANG_FORMAT_FILES += main.cpp options.cpp options.h packer.cpp packer.h
|
CLANG_FORMAT_EXCLUDE_FILES += compress/compress.h filter/filter_impl.cpp
|
||||||
CLANG_FORMAT_FILES += p_tos.cpp p_tos.h
|
CLANG_FORMAT_FILES := $(sort $(wildcard *.[ch]* ../maint/src/*.[ch]* [cu]*/*.[ch]*))
|
||||||
CLANG_FORMAT_FILES += s_djgpp2.cpp s_object.cpp s_vcsa.cpp s_win32.cpp screen.h
|
CLANG_FORMAT_FILES := $(filter-out $(CLANG_FORMAT_EXCLUDE_FILES),$(CLANG_FORMAT_FILES))
|
||||||
CLANG_FORMAT_FILES += ui.cpp ui.h work.cpp
|
clang-format: PHONY $(CLANG_FORMAT_FILES)
|
||||||
CLANG_FORMAT_FILES += $(wildcard util/[a-ln-z]*.[ch]* util/mem*.[ch]*)
|
@echo "running upx-clang-format"
|
||||||
clang-format:
|
@$(top_srcdir)/misc/scripts/upx-clang-format -i $(CLANG_FORMAT_FILES)
|
||||||
$(top_srcdir)/misc/scripts/upx-clang-format -i $(addprefix $(top_srcdir)/src/,$(sort $(CLANG_FORMAT_FILES)))
|
|
||||||
.PHONY: clang-format
|
|
||||||
endif
|
endif
|
||||||
|
|
||||||
#
|
#
|
||||||
@@ -96,8 +100,7 @@ CHECK_WHITESPACE = $(top_srcdir)/misc/scripts/check_whitespace.sh $(top_srcdir)
|
|||||||
ifneq ($(wildcard $(top_srcdir)/.git/.),)
|
ifneq ($(wildcard $(top_srcdir)/.git/.),)
|
||||||
CHECK_WHITESPACE = $(top_srcdir)/misc/scripts/check_whitespace_git.sh $(top_srcdir)
|
CHECK_WHITESPACE = $(top_srcdir)/misc/scripts/check_whitespace_git.sh $(top_srcdir)
|
||||||
endif
|
endif
|
||||||
check-whitespace : ; $(CHECK_WHITESPACE)
|
check-whitespace : PHONY ; $(CHECK_WHITESPACE)
|
||||||
endif
|
endif
|
||||||
.PHONY: check-whitespace
|
|
||||||
|
|
||||||
# vim:set ts=8 sw=8 noet:
|
# vim:set ts=8 sw=8 noet:
|
||||||
|
|||||||
+37
-38
@@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
This file is part of the UPX executable compressor.
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
Copyright (C) 1996-2022 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2022 Laszlo Molnar
|
Copyright (C) 1996-2023 Laszlo Molnar
|
||||||
All Rights Reserved.
|
All Rights Reserved.
|
||||||
|
|
||||||
UPX and the UCL library are free software; you can redistribute them
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
@@ -38,35 +38,35 @@
|
|||||||
// core - NE
|
// core - NE
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
__acc_static_forceinline unsigned get_ne16(const void *p) {
|
static forceinline unsigned get_ne16(const void *p) {
|
||||||
upx_uint16_t v = 0;
|
upx_uint16_t v = 0;
|
||||||
upx_memcpy_inline(&v, p, sizeof(v));
|
upx_memcpy_inline(&v, p, sizeof(v));
|
||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
|
|
||||||
__acc_static_forceinline unsigned get_ne32(const void *p) {
|
static forceinline unsigned get_ne32(const void *p) {
|
||||||
upx_uint32_t v = 0;
|
upx_uint32_t v = 0;
|
||||||
upx_memcpy_inline(&v, p, sizeof(v));
|
upx_memcpy_inline(&v, p, sizeof(v));
|
||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
|
|
||||||
__acc_static_forceinline upx_uint64_t get_ne64(const void *p) {
|
static forceinline upx_uint64_t get_ne64(const void *p) {
|
||||||
upx_uint64_t v = 0;
|
upx_uint64_t v = 0;
|
||||||
upx_memcpy_inline(&v, p, sizeof(v));
|
upx_memcpy_inline(&v, p, sizeof(v));
|
||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
|
|
||||||
__acc_static_forceinline void set_ne16(void *p, unsigned vv) {
|
static forceinline void set_ne16(void *p, unsigned vv) {
|
||||||
upx_uint16_t v = (upx_uint16_t) (vv & 0xffff);
|
upx_uint16_t v = (upx_uint16_t) (vv & 0xffff);
|
||||||
upx_memcpy_inline(p, &v, sizeof(v));
|
upx_memcpy_inline(p, &v, sizeof(v));
|
||||||
}
|
}
|
||||||
|
|
||||||
__acc_static_forceinline void set_ne32(void *p, unsigned vv) {
|
static forceinline void set_ne32(void *p, unsigned vv) {
|
||||||
upx_uint32_t v = vv;
|
upx_uint32_t v = vv;
|
||||||
upx_memcpy_inline(p, &v, sizeof(v));
|
upx_memcpy_inline(p, &v, sizeof(v));
|
||||||
}
|
}
|
||||||
|
|
||||||
__acc_static_forceinline void set_ne64(void *p, upx_uint64_t vv) {
|
static forceinline void set_ne64(void *p, upx_uint64_t vv) {
|
||||||
upx_uint64_t v = vv;
|
upx_uint64_t v = vv;
|
||||||
upx_memcpy_inline(p, &v, sizeof(v));
|
upx_memcpy_inline(p, &v, sizeof(v));
|
||||||
}
|
}
|
||||||
@@ -79,36 +79,31 @@ __acc_static_forceinline void set_ne64(void *p, upx_uint64_t vv) {
|
|||||||
|
|
||||||
ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(long) == 4)
|
ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(long) == 4)
|
||||||
|
|
||||||
__acc_static_forceinline unsigned bswap16(unsigned v) {
|
// unfortunately *not* constexpr with MSVC
|
||||||
return (unsigned) _byteswap_ulong(v << 16);
|
static forceinline unsigned bswap16(unsigned v) { return (unsigned) _byteswap_ulong(v << 16); }
|
||||||
}
|
static forceinline unsigned bswap32(unsigned v) { return (unsigned) _byteswap_ulong(v); }
|
||||||
__acc_static_forceinline unsigned bswap32(unsigned v) { return (unsigned) _byteswap_ulong(v); }
|
static forceinline upx_uint64_t bswap64(upx_uint64_t v) { return _byteswap_uint64(v); }
|
||||||
__acc_static_forceinline upx_uint64_t bswap64(upx_uint64_t v) { return _byteswap_uint64(v); }
|
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
__acc_static_forceinline constexpr unsigned bswap16(unsigned v) {
|
static forceinline constexpr unsigned bswap16(unsigned v) {
|
||||||
// return __builtin_bswap16((upx_uint16_t) (v & 0xffff));
|
// return __builtin_bswap16((upx_uint16_t) (v & 0xffff));
|
||||||
// return (unsigned) __builtin_bswap64((upx_uint64_t) v << 48);
|
// return (unsigned) __builtin_bswap64((upx_uint64_t) v << 48);
|
||||||
return __builtin_bswap32(v << 16);
|
return __builtin_bswap32(v << 16);
|
||||||
}
|
}
|
||||||
__acc_static_forceinline constexpr unsigned bswap32(unsigned v) {
|
static forceinline constexpr unsigned bswap32(unsigned v) {
|
||||||
// return (unsigned) __builtin_bswap64((upx_uint64_t) v << 32);
|
// return (unsigned) __builtin_bswap64((upx_uint64_t) v << 32);
|
||||||
return __builtin_bswap32(v);
|
return __builtin_bswap32(v);
|
||||||
}
|
}
|
||||||
__acc_static_forceinline constexpr upx_uint64_t bswap64(upx_uint64_t v) {
|
static forceinline constexpr upx_uint64_t bswap64(upx_uint64_t v) { return __builtin_bswap64(v); }
|
||||||
return __builtin_bswap64(v);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
__acc_static_forceinline constexpr unsigned no_bswap16(unsigned v) {
|
static forceinline constexpr unsigned no_bswap16(unsigned v) {
|
||||||
return v & 0xffff; // needed so that this is equivalent to bswap16() above
|
return v & 0xffff; // needed so that this is equivalent to bswap16() above
|
||||||
}
|
}
|
||||||
|
static forceinline constexpr unsigned no_bswap32(unsigned v) { return v; }
|
||||||
__acc_static_forceinline constexpr unsigned no_bswap32(unsigned v) { return v; }
|
static forceinline constexpr upx_uint64_t no_bswap64(upx_uint64_t v) { return v; }
|
||||||
|
|
||||||
__acc_static_forceinline constexpr upx_uint64_t no_bswap64(upx_uint64_t v) { return v; }
|
|
||||||
|
|
||||||
#if (ACC_ABI_BIG_ENDIAN)
|
#if (ACC_ABI_BIG_ENDIAN)
|
||||||
#define ne16_to_be16(v) no_bswap16(v)
|
#define ne16_to_be16(v) no_bswap16(v)
|
||||||
@@ -175,24 +170,27 @@ inline unsigned get_le26(const void *p) { return get_le32(p) & 0x03ffffff; }
|
|||||||
|
|
||||||
inline void set_le26(void *p, unsigned v) {
|
inline void set_le26(void *p, unsigned v) {
|
||||||
// preserve the top 6 bits
|
// preserve the top 6 bits
|
||||||
// set_le32(p, (get_le32(p) & 0xfc000000) | (v & 0x03ffffff));
|
#if 0
|
||||||
|
set_le32(p, (get_le32(p) & 0xfc000000) | (v & 0x03ffffff));
|
||||||
|
#else
|
||||||
// optimized version, saving a runtime bswap32
|
// optimized version, saving a runtime bswap32
|
||||||
set_ne32(p, (get_ne32(p) & ne32_to_le32(0xfc000000)) |
|
set_ne32(p, (get_ne32(p) & ne32_to_le32(0xfc000000)) |
|
||||||
(ne32_to_le32(v) & ne32_to_le32(0x03ffffff)));
|
(ne32_to_le32(v) & ne32_to_le32(0x03ffffff)));
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
// get signed values
|
// get signed values
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
__acc_static_forceinline int sign_extend(unsigned v, unsigned bits) {
|
static forceinline int sign_extend(unsigned v, unsigned bits) {
|
||||||
const unsigned sign_bit = 1u << (bits - 1);
|
const unsigned sign_bit = 1u << (bits - 1);
|
||||||
v &= sign_bit | (sign_bit - 1);
|
v &= sign_bit | (sign_bit - 1);
|
||||||
v |= 0 - (v & sign_bit);
|
v |= 0 - (v & sign_bit);
|
||||||
return ACC_ICAST(int, v);
|
return ACC_ICAST(int, v);
|
||||||
}
|
}
|
||||||
|
|
||||||
__acc_static_forceinline upx_int64_t sign_extend(upx_uint64_t v, unsigned bits) {
|
static forceinline upx_int64_t sign_extend(upx_uint64_t v, unsigned bits) {
|
||||||
const upx_uint64_t sign_bit = 1ull << (bits - 1);
|
const upx_uint64_t sign_bit = 1ull << (bits - 1);
|
||||||
v &= sign_bit | (sign_bit - 1);
|
v &= sign_bit | (sign_bit - 1);
|
||||||
v |= 0 - (v & sign_bit);
|
v |= 0 - (v & sign_bit);
|
||||||
@@ -251,6 +249,7 @@ inline upx_int64_t get_le64_signed(const void *p) {
|
|||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
struct alignas(1) BE16 {
|
struct alignas(1) BE16 {
|
||||||
|
typedef unsigned integral_conversion_type; // automatic conversion to unsigned
|
||||||
unsigned char d[2];
|
unsigned char d[2];
|
||||||
|
|
||||||
BE16 &operator=(unsigned v) {
|
BE16 &operator=(unsigned v) {
|
||||||
@@ -300,6 +299,7 @@ struct alignas(1) BE16 {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct alignas(1) BE32 {
|
struct alignas(1) BE32 {
|
||||||
|
typedef unsigned integral_conversion_type; // automatic conversion to unsigned
|
||||||
unsigned char d[4];
|
unsigned char d[4];
|
||||||
|
|
||||||
BE32 &operator=(unsigned v) {
|
BE32 &operator=(unsigned v) {
|
||||||
@@ -349,6 +349,7 @@ struct alignas(1) BE32 {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct alignas(1) BE64 {
|
struct alignas(1) BE64 {
|
||||||
|
typedef upx_uint64_t integral_conversion_type; // automatic conversion to upx_uint64_t
|
||||||
unsigned char d[8];
|
unsigned char d[8];
|
||||||
|
|
||||||
BE64 &operator=(upx_uint64_t v) {
|
BE64 &operator=(upx_uint64_t v) {
|
||||||
@@ -398,6 +399,7 @@ struct alignas(1) BE64 {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct alignas(1) LE16 {
|
struct alignas(1) LE16 {
|
||||||
|
typedef unsigned integral_conversion_type; // automatic conversion to unsigned
|
||||||
unsigned char d[2];
|
unsigned char d[2];
|
||||||
|
|
||||||
LE16 &operator=(unsigned v) {
|
LE16 &operator=(unsigned v) {
|
||||||
@@ -447,6 +449,7 @@ struct alignas(1) LE16 {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct alignas(1) LE32 {
|
struct alignas(1) LE32 {
|
||||||
|
typedef unsigned integral_conversion_type; // automatic conversion to unsigned
|
||||||
unsigned char d[4];
|
unsigned char d[4];
|
||||||
|
|
||||||
LE32 &operator=(unsigned v) {
|
LE32 &operator=(unsigned v) {
|
||||||
@@ -496,6 +499,7 @@ struct alignas(1) LE32 {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct alignas(1) LE64 {
|
struct alignas(1) LE64 {
|
||||||
|
typedef upx_uint64_t integral_conversion_type; // automatic conversion to upx_uint64_t
|
||||||
unsigned char d[8];
|
unsigned char d[8];
|
||||||
|
|
||||||
LE64 &operator=(upx_uint64_t v) {
|
LE64 &operator=(upx_uint64_t v) {
|
||||||
@@ -567,7 +571,6 @@ template <class T>
|
|||||||
inline T *operator-(T *ptr, const BE16 &v) {
|
inline T *operator-(T *ptr, const BE16 &v) {
|
||||||
return ptr - unsigned(v);
|
return ptr - unsigned(v);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
inline T *operator+(T *ptr, const BE32 &v) {
|
inline T *operator+(T *ptr, const BE32 &v) {
|
||||||
return ptr + unsigned(v);
|
return ptr + unsigned(v);
|
||||||
@@ -576,13 +579,6 @@ template <class T>
|
|||||||
inline T *operator-(T *ptr, const BE32 &v) {
|
inline T *operator-(T *ptr, const BE32 &v) {
|
||||||
return ptr - unsigned(v);
|
return ptr - unsigned(v);
|
||||||
}
|
}
|
||||||
|
|
||||||
// these are not implemented on purpose and will cause link-time errors
|
|
||||||
template <class T>
|
|
||||||
T *operator+(T *ptr, const BE64 &v);
|
|
||||||
template <class T>
|
|
||||||
T *operator-(T *ptr, const BE64 &v);
|
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
inline T *operator+(T *ptr, const LE16 &v) {
|
inline T *operator+(T *ptr, const LE16 &v) {
|
||||||
return ptr + unsigned(v);
|
return ptr + unsigned(v);
|
||||||
@@ -591,7 +587,6 @@ template <class T>
|
|||||||
inline T *operator-(T *ptr, const LE16 &v) {
|
inline T *operator-(T *ptr, const LE16 &v) {
|
||||||
return ptr - unsigned(v);
|
return ptr - unsigned(v);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
inline T *operator+(T *ptr, const LE32 &v) {
|
inline T *operator+(T *ptr, const LE32 &v) {
|
||||||
return ptr + unsigned(v);
|
return ptr + unsigned(v);
|
||||||
@@ -601,11 +596,15 @@ inline T *operator-(T *ptr, const LE32 &v) {
|
|||||||
return ptr - unsigned(v);
|
return ptr - unsigned(v);
|
||||||
}
|
}
|
||||||
|
|
||||||
// these are not implemented on purpose and will cause link-time errors
|
// these are not implemented on purpose and will cause errors
|
||||||
template <class T>
|
template <class T>
|
||||||
T *operator+(T *ptr, const LE64 &v);
|
T *operator+(T *ptr, const BE64 &v) DELETED_FUNCTION;
|
||||||
template <class T>
|
template <class T>
|
||||||
T *operator-(T *ptr, const LE64 &v);
|
T *operator-(T *ptr, const BE64 &v) DELETED_FUNCTION;
|
||||||
|
template <class T>
|
||||||
|
T *operator+(T *ptr, const LE64 &v) DELETED_FUNCTION;
|
||||||
|
template <class T>
|
||||||
|
T *operator-(T *ptr, const LE64 &v) DELETED_FUNCTION;
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
// global overloads
|
// global overloads
|
||||||
|
|||||||
+2
-2
@@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
This file is part of the UPX executable compressor.
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
Copyright (C) 1996-2022 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2022 Laszlo Molnar
|
Copyright (C) 1996-2023 Laszlo Molnar
|
||||||
All Rights Reserved.
|
All Rights Reserved.
|
||||||
|
|
||||||
UPX and the UCL library are free software; you can redistribute them
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
|
|||||||
@@ -2,8 +2,7 @@
|
|||||||
|
|
||||||
This file is part of the UPX executable compressor.
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
Copyright (C) 1996-2022 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2022 Laszlo Molnar
|
|
||||||
All Rights Reserved.
|
All Rights Reserved.
|
||||||
|
|
||||||
UPX and the UCL library are free software; you can redistribute them
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
@@ -21,8 +20,8 @@
|
|||||||
If not, write to the Free Software Foundation, Inc.,
|
If not, write to the Free Software Foundation, Inc.,
|
||||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
Markus F.X.J. Oberhumer Laszlo Molnar
|
Markus F.X.J. Oberhumer
|
||||||
<markus@oberhumer.com> <ezerotven+github@gmail.com>
|
<markus@oberhumer.com>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "../conf.h"
|
#include "../conf.h"
|
||||||
@@ -35,6 +34,7 @@ int upx_doctest_check(int argc, char **argv) {
|
|||||||
#if defined(DOCTEST_CONFIG_DISABLE)
|
#if defined(DOCTEST_CONFIG_DISABLE)
|
||||||
UNUSED(argc);
|
UNUSED(argc);
|
||||||
UNUSED(argv);
|
UNUSED(argv);
|
||||||
|
return 0;
|
||||||
#else
|
#else
|
||||||
const char *e = getenv("UPX_DEBUG_DOCTEST_DISABLE");
|
const char *e = getenv("UPX_DEBUG_DOCTEST_DISABLE");
|
||||||
if (e && e[0] && strcmp(e, "0") != 0)
|
if (e && e[0] && strcmp(e, "0") != 0)
|
||||||
@@ -72,8 +72,8 @@ int upx_doctest_check(int argc, char **argv) {
|
|||||||
return 1;
|
return 1;
|
||||||
if (context.shouldExit())
|
if (context.shouldExit())
|
||||||
return 2;
|
return 2;
|
||||||
#endif // DOCTEST_CONFIG_DISABLE
|
|
||||||
return 0;
|
return 0;
|
||||||
|
#endif // DOCTEST_CONFIG_DISABLE
|
||||||
}
|
}
|
||||||
|
|
||||||
int upx_doctest_check() { return upx_doctest_check(0, nullptr); }
|
int upx_doctest_check() { return upx_doctest_check(0, nullptr); }
|
||||||
@@ -98,6 +98,9 @@ ACC_COMPILE_TIME_ASSERT_HEADER(bswap32(0x04030201) == 0x01020304)
|
|||||||
ACC_COMPILE_TIME_ASSERT_HEADER(bswap64(0x0807060504030201ull) == 0x0102030405060708ull)
|
ACC_COMPILE_TIME_ASSERT_HEADER(bswap64(0x0807060504030201ull) == 0x0102030405060708ull)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER(compile_time::string_len("") == 0)
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER(compile_time::string_len("a") == 1)
|
||||||
|
|
||||||
ACC_COMPILE_TIME_ASSERT_HEADER(compile_time::string_eq("", ""))
|
ACC_COMPILE_TIME_ASSERT_HEADER(compile_time::string_eq("", ""))
|
||||||
ACC_COMPILE_TIME_ASSERT_HEADER(!compile_time::string_eq("a", ""))
|
ACC_COMPILE_TIME_ASSERT_HEADER(!compile_time::string_eq("a", ""))
|
||||||
ACC_COMPILE_TIME_ASSERT_HEADER(!compile_time::string_eq("", "a"))
|
ACC_COMPILE_TIME_ASSERT_HEADER(!compile_time::string_eq("", "a"))
|
||||||
@@ -119,6 +122,20 @@ ACC_COMPILE_TIME_ASSERT_HEADER(!compile_time::string_gt("abc", "abz"))
|
|||||||
ACC_COMPILE_TIME_ASSERT_HEADER(!compile_time::string_ge("abc", "abz"))
|
ACC_COMPILE_TIME_ASSERT_HEADER(!compile_time::string_ge("abc", "abz"))
|
||||||
ACC_COMPILE_TIME_ASSERT_HEADER(compile_time::string_le("abc", "abz"))
|
ACC_COMPILE_TIME_ASSERT_HEADER(compile_time::string_le("abc", "abz"))
|
||||||
|
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER(CHAR_BIT == 8)
|
||||||
|
#if 0 // does not work with MSVC
|
||||||
|
#if '\0' - 1 < 0
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER(CHAR_MAX == 127)
|
||||||
|
#else
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER(CHAR_MAX == 255)
|
||||||
|
#endif
|
||||||
|
#if L'\0' - 1 < 0
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER((wchar_t) -1 < 0)
|
||||||
|
#else
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER((wchar_t) -1 > 0)
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
// upx_compiler_sanity_check()
|
// upx_compiler_sanity_check()
|
||||||
// assert a sane architecture and compiler
|
// assert a sane architecture and compiler
|
||||||
@@ -129,6 +146,17 @@ namespace {
|
|||||||
template <class T>
|
template <class T>
|
||||||
struct TestBELE {
|
struct TestBELE {
|
||||||
__acc_static_noinline bool test(void) {
|
__acc_static_noinline bool test(void) {
|
||||||
|
// POD checks
|
||||||
|
{
|
||||||
|
COMPILE_TIME_ASSERT(std::is_standard_layout<T>::value)
|
||||||
|
COMPILE_TIME_ASSERT(std::is_trivial<T>::value)
|
||||||
|
// extra checks, these are probably implied by std::is_trivial:
|
||||||
|
COMPILE_TIME_ASSERT(std::is_nothrow_default_constructible<T>::value)
|
||||||
|
COMPILE_TIME_ASSERT(std::is_trivially_copyable<T>::value)
|
||||||
|
COMPILE_TIME_ASSERT(std::is_trivially_default_constructible<T>::value)
|
||||||
|
}
|
||||||
|
// alignment checks
|
||||||
|
{
|
||||||
COMPILE_TIME_ASSERT_ALIGNED1(T)
|
COMPILE_TIME_ASSERT_ALIGNED1(T)
|
||||||
struct alignas(1) test1_t {
|
struct alignas(1) test1_t {
|
||||||
char a;
|
char a;
|
||||||
@@ -138,17 +166,20 @@ struct TestBELE {
|
|||||||
char a;
|
char a;
|
||||||
T b[3];
|
T b[3];
|
||||||
};
|
};
|
||||||
test1_t t1[7];
|
|
||||||
UNUSED(t1);
|
|
||||||
test2_t t2[7];
|
|
||||||
UNUSED(t2);
|
|
||||||
COMPILE_TIME_ASSERT(sizeof(test1_t) == 1 + sizeof(T))
|
|
||||||
COMPILE_TIME_ASSERT_ALIGNED1(test1_t)
|
COMPILE_TIME_ASSERT_ALIGNED1(test1_t)
|
||||||
|
COMPILE_TIME_ASSERT_ALIGNED1(test2_t)
|
||||||
|
test1_t t1[7];
|
||||||
|
test2_t t2[7];
|
||||||
|
COMPILE_TIME_ASSERT(sizeof(test1_t) == 1 + sizeof(T))
|
||||||
COMPILE_TIME_ASSERT(sizeof(t1) == 7 + 7 * sizeof(T))
|
COMPILE_TIME_ASSERT(sizeof(t1) == 7 + 7 * sizeof(T))
|
||||||
COMPILE_TIME_ASSERT(sizeof(test2_t) == 1 + 3 * sizeof(T))
|
COMPILE_TIME_ASSERT(sizeof(test2_t) == 1 + 3 * sizeof(T))
|
||||||
COMPILE_TIME_ASSERT_ALIGNED1(test2_t)
|
|
||||||
COMPILE_TIME_ASSERT(sizeof(t2) == 7 + 21 * sizeof(T))
|
COMPILE_TIME_ASSERT(sizeof(t2) == 7 + 21 * sizeof(T))
|
||||||
|
UNUSED(t1);
|
||||||
|
UNUSED(t2);
|
||||||
|
}
|
||||||
#if 1
|
#if 1
|
||||||
|
// arithmetic checks
|
||||||
|
{
|
||||||
T allbits;
|
T allbits;
|
||||||
allbits = 0;
|
allbits = 0;
|
||||||
allbits += 1;
|
allbits += 1;
|
||||||
@@ -185,6 +216,7 @@ struct TestBELE {
|
|||||||
assert(v2 == 0);
|
assert(v2 == 0);
|
||||||
if ((v1 ^ v2) != 1)
|
if ((v1 ^ v2) != 1)
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -321,6 +353,20 @@ void upx_compiler_sanity_check(void) {
|
|||||||
assert(get_le26(d) == 0x03020304);
|
assert(get_le26(d) == 0x03020304);
|
||||||
assert(dd == ne32_to_le32(0xf7020304));
|
assert(dd == ne32_to_le32(0xf7020304));
|
||||||
}
|
}
|
||||||
|
{
|
||||||
|
upx_uint16_t a;
|
||||||
|
upx_uint32_t b;
|
||||||
|
upx_uint64_t c;
|
||||||
|
set_ne16(&a, 0x04030201); // ignore upper bits
|
||||||
|
set_ne32(&b, 0x04030201);
|
||||||
|
set_ne64(&c, 0x0807060504030201ull);
|
||||||
|
assert(a == 0x0201);
|
||||||
|
assert(b == 0x04030201);
|
||||||
|
assert(c == 0x0807060504030201ull);
|
||||||
|
assert(get_ne16(&a) == 0x0201);
|
||||||
|
assert(get_ne32(&b) == 0x04030201);
|
||||||
|
assert(get_ne64(&c) == 0x0807060504030201ull);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
union {
|
union {
|
||||||
short v_short;
|
short v_short;
|
||||||
@@ -2,8 +2,7 @@
|
|||||||
|
|
||||||
This file is part of the UPX executable compressor.
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
Copyright (C) 1996-2022 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2022 Laszlo Molnar
|
|
||||||
All Rights Reserved.
|
All Rights Reserved.
|
||||||
|
|
||||||
UPX and the UCL library are free software; you can redistribute them
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
@@ -21,8 +20,8 @@
|
|||||||
If not, write to the Free Software Foundation, Inc.,
|
If not, write to the Free Software Foundation, Inc.,
|
||||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
Markus F.X.J. Oberhumer Laszlo Molnar
|
Markus F.X.J. Oberhumer
|
||||||
<markus@oberhumer.com> <ezerotven+github@gmail.com>
|
<markus@oberhumer.com>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
@@ -33,11 +32,19 @@
|
|||||||
#if !defined(UPX_DOCTEST_CONFIG_MULTITHREADING)
|
#if !defined(UPX_DOCTEST_CONFIG_MULTITHREADING)
|
||||||
#define DOCTEST_CONFIG_NO_MULTITHREADING
|
#define DOCTEST_CONFIG_NO_MULTITHREADING
|
||||||
#endif
|
#endif
|
||||||
#if defined(__MSDOS__) && defined(__DJGPP__)
|
#if defined(__i386__) && defined(__MSDOS__) && defined(__DJGPP__) && defined(__GNUC__)
|
||||||
#define DOCTEST_CONFIG_NO_POSIX_SIGNALS
|
#define DOCTEST_CONFIG_NO_POSIX_SIGNALS
|
||||||
|
#elif defined(__m68k__) && defined(__atarist__) && defined(__GNUC__)
|
||||||
|
#define DOCTEST_CONFIG_COLORS_NONE
|
||||||
|
#define DOCTEST_CONFIG_NO_POSIX_SIGNALS
|
||||||
|
#pragma GCC diagnostic ignored "-Wshadow"
|
||||||
#endif
|
#endif
|
||||||
#define DOCTEST_CONFIG_NO_UNPREFIXED_OPTIONS
|
#define DOCTEST_CONFIG_NO_UNPREFIXED_OPTIONS
|
||||||
#if !defined(DOCTEST_CONFIG_DISABLE)
|
#if !defined(DOCTEST_CONFIG_DISABLE)
|
||||||
|
#if defined(__clang__) && defined(__FAST_MATH__) && defined(__INTEL_LLVM_COMPILER)
|
||||||
|
// warning: comparison with NaN always evaluates to false in fast floating point modes
|
||||||
|
#pragma clang diagnostic ignored "-Wtautological-constant-compare"
|
||||||
|
#endif
|
||||||
#include <doctest/doctest/parts/doctest.cpp>
|
#include <doctest/doctest/parts/doctest.cpp>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -0,0 +1,791 @@
|
|||||||
|
/* xspan -- a minimally invasive checked memory smart pointer
|
||||||
|
|
||||||
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
|
Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer
|
||||||
|
All Rights Reserved.
|
||||||
|
|
||||||
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
|
and/or modify them under the terms of the GNU General Public License as
|
||||||
|
published by the Free Software Foundation; either version 2 of
|
||||||
|
the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; see the file COPYING.
|
||||||
|
If not, write to the Free Software Foundation, Inc.,
|
||||||
|
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
|
Markus F.X.J. Oberhumer
|
||||||
|
<markus@oberhumer.com>
|
||||||
|
*/
|
||||||
|
|
||||||
|
// lots of tests (and probably quite a number of redundant tests)
|
||||||
|
|
||||||
|
#include "../conf.h"
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
// raw_bytes
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
TEST_CASE("raw_bytes ptr") {
|
||||||
|
upx_uint16_t *ptr = nullptr;
|
||||||
|
CHECK_NOTHROW(raw_bytes(ptr, 0));
|
||||||
|
CHECK_THROWS(raw_bytes(ptr, 1));
|
||||||
|
CHECK_THROWS(raw_index_bytes(ptr, 0, 0));
|
||||||
|
CHECK_THROWS(raw_index_bytes(ptr, 1, 0));
|
||||||
|
CHECK_THROWS(raw_index_bytes(ptr, 0, 1));
|
||||||
|
upx_uint16_t buf[4];
|
||||||
|
ptr = buf;
|
||||||
|
CHECK(ptr_udiff_bytes(raw_index_bytes(ptr, 1, 1), ptr) == 2u);
|
||||||
|
CHECK(ptr_udiff_bytes(raw_index_bytes(ptr, 4, 0), ptr) == 8u);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("raw_bytes bounded array") {
|
||||||
|
upx_uint16_t buf[4];
|
||||||
|
CHECK_NOTHROW(raw_bytes(buf, 8));
|
||||||
|
CHECK_THROWS(raw_bytes(buf, 9));
|
||||||
|
CHECK_NOTHROW(raw_index_bytes(buf, 4, 0));
|
||||||
|
CHECK_THROWS(raw_index_bytes(buf, 4, 1));
|
||||||
|
CHECK_NOTHROW(raw_index_bytes(buf, 3, 2));
|
||||||
|
CHECK_THROWS(raw_index_bytes(buf, 3, 3));
|
||||||
|
CHECK(ptr_udiff_bytes(raw_index_bytes(buf, 1, 1), buf) == 2u);
|
||||||
|
CHECK(ptr_udiff_bytes(raw_index_bytes(buf, 4, 0), buf) == 8u);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
// basic xspan
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
TEST_CASE("basic xspan usage") {
|
||||||
|
char buf[4] = {0, 1, 2, 3};
|
||||||
|
|
||||||
|
SUBCASE("XSPAN_x") {
|
||||||
|
XSPAN_0(char) a0 = nullptr;
|
||||||
|
|
||||||
|
XSPAN_0(char) b0 = buf;
|
||||||
|
XSPAN_P(char) bp = buf;
|
||||||
|
|
||||||
|
XSPAN_0(char) c0 = XSPAN_0_MAKE(char, buf);
|
||||||
|
XSPAN_P(char) cp = XSPAN_P_MAKE(char, buf);
|
||||||
|
XSPAN_S(char) cs = XSPAN_S_MAKE(char, buf, sizeof(buf));
|
||||||
|
|
||||||
|
XSPAN_0(const char) const x0 = XSPAN_0_MAKE(const char, buf);
|
||||||
|
XSPAN_P(const char) const xp = XSPAN_P_MAKE(const char, buf);
|
||||||
|
XSPAN_S(const char) const xs = XSPAN_S_MAKE(const char, buf, sizeof(buf));
|
||||||
|
XSPAN_P(const char) const yp = xs;
|
||||||
|
XSPAN_0(const char) const z0p = yp;
|
||||||
|
XSPAN_0(const char) const z0s = xs;
|
||||||
|
|
||||||
|
CHECK((a0 == nullptr));
|
||||||
|
CHECK(c0 == b0);
|
||||||
|
CHECK(cp == bp);
|
||||||
|
CHECK(cs == bp);
|
||||||
|
CHECK(x0 == z0p);
|
||||||
|
CHECK(xp == z0s);
|
||||||
|
|
||||||
|
CHECK_NOTHROW(raw_bytes(a0, 0));
|
||||||
|
CHECK_THROWS(raw_bytes(a0, 1));
|
||||||
|
CHECK_THROWS(raw_index_bytes(a0, 0, 0));
|
||||||
|
CHECK(raw_bytes(c0, 4) == buf);
|
||||||
|
CHECK(raw_index_bytes(c0, 1, 3) == buf + 1);
|
||||||
|
CHECK(raw_bytes(cp, 4) == buf);
|
||||||
|
CHECK(raw_index_bytes(cp, 1, 3) == buf + 1);
|
||||||
|
CHECK(raw_bytes(cs, 4) == buf);
|
||||||
|
CHECK(raw_index_bytes(cs, 1, 3) == buf + 1);
|
||||||
|
#if WITH_XSPAN >= 2
|
||||||
|
CHECK_THROWS(raw_bytes(cs, 5));
|
||||||
|
CHECK_THROWS(raw_index_bytes(cs, 1, 4));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
SUBCASE("XSPAN_x_VAR") {
|
||||||
|
XSPAN_0_VAR(char, a0, nullptr);
|
||||||
|
|
||||||
|
XSPAN_0_VAR(char, b0, buf);
|
||||||
|
XSPAN_P_VAR(char, bp, buf);
|
||||||
|
|
||||||
|
XSPAN_0_VAR(char, c0, buf, sizeof(buf));
|
||||||
|
XSPAN_P_VAR(char, cp, buf, sizeof(buf));
|
||||||
|
XSPAN_S_VAR(char, cs, buf, sizeof(buf));
|
||||||
|
|
||||||
|
XSPAN_0_VAR(char, d0, buf + 1, sizeof(buf), buf);
|
||||||
|
XSPAN_P_VAR(char, dp, buf + 1, sizeof(buf), buf);
|
||||||
|
XSPAN_S_VAR(char, ds, buf + 1, sizeof(buf), buf);
|
||||||
|
|
||||||
|
XSPAN_0_VAR(const char, const x0, buf, sizeof(buf));
|
||||||
|
XSPAN_P_VAR(const char, const xp, buf, sizeof(buf));
|
||||||
|
XSPAN_S_VAR(const char, const xs, buf, sizeof(buf));
|
||||||
|
XSPAN_P_VAR(const char, const yp, xs);
|
||||||
|
XSPAN_0_VAR(const char, const z0p, yp);
|
||||||
|
XSPAN_0_VAR(const char, const z0s, xs);
|
||||||
|
|
||||||
|
CHECK((a0 == nullptr));
|
||||||
|
CHECK(c0 == b0);
|
||||||
|
CHECK(cp == bp);
|
||||||
|
CHECK(cs == bp);
|
||||||
|
CHECK(d0 == dp);
|
||||||
|
CHECK(d0 == ds);
|
||||||
|
CHECK(x0 == z0p);
|
||||||
|
CHECK(xp == z0s);
|
||||||
|
|
||||||
|
CHECK_NOTHROW(raw_bytes(a0, 0));
|
||||||
|
CHECK_THROWS(raw_bytes(a0, 1));
|
||||||
|
CHECK_THROWS(raw_index_bytes(a0, 0, 0));
|
||||||
|
CHECK(raw_bytes(c0, 4) == buf);
|
||||||
|
CHECK(raw_index_bytes(c0, 1, 3) == buf + 1);
|
||||||
|
CHECK(raw_bytes(cp, 4) == buf);
|
||||||
|
CHECK(raw_index_bytes(cp, 1, 3) == buf + 1);
|
||||||
|
CHECK(raw_bytes(cs, 4) == buf);
|
||||||
|
CHECK(raw_index_bytes(cs, 1, 3) == buf + 1);
|
||||||
|
#if WITH_XSPAN >= 2
|
||||||
|
CHECK_THROWS(raw_bytes(cs, 5));
|
||||||
|
CHECK_THROWS(raw_index_bytes(cs, 1, 4));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
SUBCASE("xspan in class") {
|
||||||
|
struct MyType {
|
||||||
|
XSPAN_0(char) s0;
|
||||||
|
XSPAN_P(char) sp;
|
||||||
|
XSPAN_S(char) ss;
|
||||||
|
#if __cplusplus >= 201103L
|
||||||
|
XSPAN_0(char) x0 = nullptr;
|
||||||
|
#endif
|
||||||
|
#if WITH_XSPAN >= 2
|
||||||
|
// much nicer syntax when using fully checked xspan:
|
||||||
|
MyType(char *b, size_t n, bool) : s0(b, n), sp(b, n), ss(b, n) {}
|
||||||
|
#endif
|
||||||
|
MyType(char *b, size_t n)
|
||||||
|
: s0(XSPAN_0_MAKE(char, b, n)), sp(XSPAN_P_MAKE(char, b, n)),
|
||||||
|
ss(XSPAN_S_MAKE(char, b, n)) {
|
||||||
|
UNUSED(n);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
MyType x(buf, sizeof(buf));
|
||||||
|
MyType y = MyType(buf, sizeof(buf));
|
||||||
|
CHECK(x.s0 == y.sp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
//
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
#if (WITH_XSPAN >= 2) && DEBUG
|
||||||
|
|
||||||
|
TEST_CASE("PtrOrSpanOrNull") {
|
||||||
|
char real_buf[2 + 6 + 2] = {126, 127, 0, 1, 2, 3, 4, 5, 124, 125};
|
||||||
|
char *base_buf = real_buf + 2;
|
||||||
|
char *const my_null = nullptr;
|
||||||
|
typedef PtrOrSpanOrNull<char> Span0;
|
||||||
|
|
||||||
|
// basic nullptr
|
||||||
|
CHECK_NOTHROW(Span0(base_buf, 4, base_buf) = my_null);
|
||||||
|
CHECK_NOTHROW(Span0(base_buf, 4, base_buf).assign(my_null));
|
||||||
|
// basic range checking
|
||||||
|
CHECK_NOTHROW(Span0(base_buf, 4, base_buf));
|
||||||
|
CHECK_NOTHROW(Span0(base_buf, 0, base_buf));
|
||||||
|
CHECK_NOTHROW(Span0(base_buf, 0, base_buf) - 0);
|
||||||
|
CHECK_THROWS(Span0(base_buf, 0, base_buf) + 1);
|
||||||
|
CHECK_THROWS(Span0(base_buf, 0, base_buf) - 1);
|
||||||
|
CHECK_NOTHROW(Span0(base_buf, 4, base_buf) + 4);
|
||||||
|
CHECK_THROWS(Span0(base_buf, 4, base_buf) + 5);
|
||||||
|
CHECK_THROWS(Span0(base_buf - 1, 4, base_buf));
|
||||||
|
CHECK_THROWS(Span0(base_buf + 1, 0, base_buf));
|
||||||
|
// basic same base
|
||||||
|
CHECK_NOTHROW(Span0(base_buf, 4, base_buf) = Span0(base_buf + 1, 3, base_buf));
|
||||||
|
CHECK_NOTHROW(Span0(base_buf, 4, base_buf) = Span0(base_buf + 1, 1, base_buf));
|
||||||
|
CHECK_NOTHROW(Span0(base_buf, 4, base_buf) = Span0(base_buf + 1, 5, base_buf));
|
||||||
|
CHECK_THROWS(Span0(base_buf, 4, base_buf) = Span0(base_buf + 1, 3, base_buf + 1));
|
||||||
|
|
||||||
|
Span0 a1(nullptr);
|
||||||
|
assert(a1 == nullptr);
|
||||||
|
assert(a1.raw_ptr() == nullptr);
|
||||||
|
assert(a1.raw_base() == nullptr);
|
||||||
|
assert(a1.raw_size_in_bytes() == 0u);
|
||||||
|
CHECK_THROWS(*a1);
|
||||||
|
CHECK_THROWS(a1[0]);
|
||||||
|
|
||||||
|
Span0 a2 = nullptr;
|
||||||
|
assert(a2 == nullptr);
|
||||||
|
assert(a2.raw_ptr() == nullptr);
|
||||||
|
assert(a2.raw_base() == nullptr);
|
||||||
|
assert(a2.raw_size_in_bytes() == 0u);
|
||||||
|
CHECK_THROWS(*a2);
|
||||||
|
CHECK_THROWS(a2[0]);
|
||||||
|
|
||||||
|
Span0 base0(nullptr, 4, base_buf);
|
||||||
|
assert(base0.raw_ptr() == nullptr);
|
||||||
|
assert(base0.raw_base() == base_buf);
|
||||||
|
assert(base0.raw_size_in_bytes() == 4u);
|
||||||
|
CHECK_THROWS(*base0); // nullptr
|
||||||
|
CHECK_THROWS(base0[0]); // nullptr
|
||||||
|
CHECK_THROWS(base0 + 1); // nullptr
|
||||||
|
|
||||||
|
Span0 base4(base_buf, 4);
|
||||||
|
assert(base4.raw_ptr() == base_buf);
|
||||||
|
assert(base4.raw_base() == base_buf);
|
||||||
|
assert(base4.raw_size_in_bytes() == 4u);
|
||||||
|
|
||||||
|
a1 = base_buf;
|
||||||
|
a1 = base0;
|
||||||
|
assert(a1 == nullptr);
|
||||||
|
assert(a1.raw_ptr() == nullptr);
|
||||||
|
assert(a1.raw_base() == base_buf);
|
||||||
|
assert(a1.raw_size_in_bytes() == 4u);
|
||||||
|
a1 = base4;
|
||||||
|
assert(a1 == base_buf);
|
||||||
|
assert(a1.raw_ptr() == base_buf);
|
||||||
|
assert(a1.raw_base() == base_buf);
|
||||||
|
assert(a1.raw_size_in_bytes() == 4u);
|
||||||
|
|
||||||
|
a1 = base_buf;
|
||||||
|
assert(a1 != nullptr);
|
||||||
|
a1 = base_buf + 1;
|
||||||
|
CHECK(*a1++ == 1);
|
||||||
|
CHECK(*++a1 == 3);
|
||||||
|
CHECK(*a1 == 3);
|
||||||
|
a1 = base_buf + 4; // at the end of buffer
|
||||||
|
CHECK_THROWS(*a1);
|
||||||
|
CHECK_THROWS(a1 = base_buf + 5); // range error
|
||||||
|
assert(a1 == base_buf + 4);
|
||||||
|
CHECK(a1[-4] == 0);
|
||||||
|
CHECK_THROWS(a1[-5]); // range error
|
||||||
|
a1 = base_buf;
|
||||||
|
CHECK(*a1 == 0);
|
||||||
|
|
||||||
|
Span0 new_base4(base_buf + 2, 4);
|
||||||
|
CHECK_THROWS(a1 = new_base4); // not same base
|
||||||
|
a2 = new_base4;
|
||||||
|
CHECK_THROWS(a2 = base4); // not same base
|
||||||
|
|
||||||
|
Span0 s0_no_base(nullptr);
|
||||||
|
Span0 s0_with_base(nullptr, 4, base_buf);
|
||||||
|
s0_no_base = nullptr;
|
||||||
|
s0_with_base = nullptr;
|
||||||
|
s0_with_base = s0_no_base;
|
||||||
|
assert(s0_no_base.raw_base() == nullptr);
|
||||||
|
assert(s0_with_base.raw_base() == base_buf);
|
||||||
|
s0_no_base = s0_with_base;
|
||||||
|
assert(s0_no_base.raw_base() == base_buf);
|
||||||
|
assert(s0_no_base.raw_ptr() == nullptr);
|
||||||
|
assert(s0_with_base.raw_ptr() == nullptr);
|
||||||
|
s0_no_base = my_null;
|
||||||
|
s0_with_base = my_null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
//
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
TEST_CASE("PtrOrSpan") {
|
||||||
|
char real_buf[2 + 6 + 2] = {126, 127, 0, 1, 2, 3, 4, 5, 124, 125};
|
||||||
|
char *base_buf = real_buf + 2;
|
||||||
|
char *const my_null = nullptr;
|
||||||
|
typedef PtrOrSpan<char> SpanP;
|
||||||
|
|
||||||
|
// basic nullptr
|
||||||
|
CHECK_THROWS(SpanP(base_buf, 4, base_buf) = my_null);
|
||||||
|
CHECK_THROWS(SpanP(base_buf, 4, base_buf).assign(my_null));
|
||||||
|
// basic range checking
|
||||||
|
CHECK_NOTHROW(SpanP(base_buf, 4, base_buf));
|
||||||
|
CHECK_NOTHROW(SpanP(base_buf, 0, base_buf));
|
||||||
|
CHECK_NOTHROW(SpanP(base_buf, 0, base_buf) - 0);
|
||||||
|
CHECK_THROWS(SpanP(base_buf, 0, base_buf) + 1);
|
||||||
|
CHECK_THROWS(SpanP(base_buf, 0, base_buf) - 1);
|
||||||
|
CHECK_NOTHROW(SpanP(base_buf, 4, base_buf) + 4);
|
||||||
|
CHECK_THROWS(SpanP(base_buf, 4, base_buf) + 5);
|
||||||
|
CHECK_THROWS(SpanP(base_buf - 1, 4, base_buf));
|
||||||
|
CHECK_THROWS(SpanP(base_buf + 1, 0, base_buf));
|
||||||
|
// basic same base
|
||||||
|
CHECK_NOTHROW(SpanP(base_buf, 4, base_buf) = SpanP(base_buf + 1, 3, base_buf));
|
||||||
|
CHECK_NOTHROW(SpanP(base_buf, 4, base_buf) = SpanP(base_buf + 1, 1, base_buf));
|
||||||
|
CHECK_NOTHROW(SpanP(base_buf, 4, base_buf) = SpanP(base_buf + 1, 5, base_buf));
|
||||||
|
CHECK_THROWS(SpanP(base_buf, 4, base_buf) = SpanP(base_buf + 1, 3, base_buf + 1));
|
||||||
|
|
||||||
|
SpanP x1(base_buf, 0);
|
||||||
|
assert(x1 != nullptr);
|
||||||
|
assert(x1.raw_ptr() == base_buf);
|
||||||
|
assert(x1.raw_base() == base_buf);
|
||||||
|
assert(x1.raw_size_in_bytes() == 0u);
|
||||||
|
CHECK_THROWS(*x1);
|
||||||
|
CHECK_THROWS(x1[0]);
|
||||||
|
|
||||||
|
SpanP a2 = base_buf;
|
||||||
|
assert(a2 != nullptr);
|
||||||
|
assert(a2.raw_ptr() == base_buf);
|
||||||
|
assert(a2.raw_base() == nullptr);
|
||||||
|
assert(a2.raw_size_in_bytes() == 0u);
|
||||||
|
CHECK(*a2 == 0);
|
||||||
|
CHECK(a2[1] == 1);
|
||||||
|
|
||||||
|
SpanP base0(base_buf, 4, base_buf);
|
||||||
|
assert(base0.raw_ptr() == base_buf);
|
||||||
|
assert(base0.raw_base() == base_buf);
|
||||||
|
assert(base0.raw_size_in_bytes() == 4u);
|
||||||
|
|
||||||
|
SpanP base4(base_buf, 4);
|
||||||
|
assert(base4.raw_ptr() == base_buf);
|
||||||
|
assert(base4.raw_base() == base_buf);
|
||||||
|
assert(base4.raw_size_in_bytes() == 4u);
|
||||||
|
|
||||||
|
SpanP a1(base_buf, 4);
|
||||||
|
a1 = base_buf;
|
||||||
|
a1 = base0;
|
||||||
|
assert(a1 == base0);
|
||||||
|
assert(a1 != nullptr);
|
||||||
|
assert(a1.raw_ptr() == base0.raw_ptr());
|
||||||
|
assert(a1.raw_base() == base_buf);
|
||||||
|
assert(a1.raw_size_in_bytes() == 4u);
|
||||||
|
a1 = base4;
|
||||||
|
assert(a1 == base_buf);
|
||||||
|
assert(a1.raw_ptr() == base_buf);
|
||||||
|
assert(a1.raw_base() == base_buf);
|
||||||
|
assert(a1.raw_size_in_bytes() == 4u);
|
||||||
|
|
||||||
|
a1 = base_buf;
|
||||||
|
a1 = base_buf + 1;
|
||||||
|
CHECK(*a1++ == 1);
|
||||||
|
CHECK(*++a1 == 3);
|
||||||
|
CHECK(*a1 == 3);
|
||||||
|
a1 = base_buf + 4; // at the end of buffer
|
||||||
|
CHECK_THROWS(*a1);
|
||||||
|
CHECK_THROWS(a1 = base_buf + 5); // range error
|
||||||
|
assert(a1 == base_buf + 4);
|
||||||
|
CHECK(a1[-4] == 0);
|
||||||
|
CHECK_THROWS(a1[-5]); // range error
|
||||||
|
a1 = base_buf;
|
||||||
|
CHECK(*a1 == 0);
|
||||||
|
|
||||||
|
SpanP new_base4(base_buf + 2, 4);
|
||||||
|
CHECK_THROWS(a1 = new_base4); // not same base
|
||||||
|
a2 = new_base4;
|
||||||
|
CHECK_THROWS(a2 = base4); // not same base
|
||||||
|
|
||||||
|
SpanP sp_no_base(base_buf);
|
||||||
|
SpanP sp_with_base(base_buf, 4, base_buf);
|
||||||
|
assert(sp_no_base.raw_base() == nullptr);
|
||||||
|
assert(sp_with_base.raw_base() == base_buf);
|
||||||
|
CHECK_THROWS(sp_no_base = my_null); // nullptr assignment
|
||||||
|
CHECK_THROWS(sp_with_base = my_null); // nullptr assignment
|
||||||
|
#if XSPAN_CONFIG_ENABLE_SPAN_CONVERSION
|
||||||
|
typedef PtrOrSpanOrNull<char> Span0;
|
||||||
|
Span0 s0_no_base(nullptr);
|
||||||
|
Span0 s0_with_base(nullptr, 4, base_buf);
|
||||||
|
CHECK_THROWS(sp_no_base = s0_no_base); // nullptr assignment
|
||||||
|
CHECK_THROWS(sp_no_base = s0_with_base); // nullptr assignment
|
||||||
|
CHECK_THROWS(sp_with_base = s0_no_base); // nullptr assignment
|
||||||
|
CHECK_THROWS(sp_with_base = s0_with_base); // nullptr assignment
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
//
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
TEST_CASE("Span") {
|
||||||
|
char real_buf[2 + 6 + 2] = {126, 127, 0, 1, 2, 3, 4, 5, 124, 125};
|
||||||
|
char *base_buf = real_buf + 2;
|
||||||
|
char *const my_null = nullptr;
|
||||||
|
typedef Span<char> SpanS;
|
||||||
|
|
||||||
|
// basic nullptr
|
||||||
|
CHECK_THROWS(SpanS(base_buf, 4, base_buf) = my_null);
|
||||||
|
CHECK_THROWS(SpanS(base_buf, 4, base_buf).assign(my_null));
|
||||||
|
// basic range checking
|
||||||
|
CHECK_NOTHROW(SpanS(base_buf, 4, base_buf));
|
||||||
|
CHECK_NOTHROW(SpanS(base_buf, 0, base_buf));
|
||||||
|
CHECK_NOTHROW(SpanS(base_buf, 0, base_buf) - 0);
|
||||||
|
CHECK_THROWS(SpanS(base_buf, 0, base_buf) + 1);
|
||||||
|
CHECK_THROWS(SpanS(base_buf, 0, base_buf) - 1);
|
||||||
|
CHECK_NOTHROW(SpanS(base_buf, 4, base_buf) + 4);
|
||||||
|
CHECK_THROWS(SpanS(base_buf, 4, base_buf) + 5);
|
||||||
|
CHECK_THROWS(SpanS(base_buf - 1, 4, base_buf));
|
||||||
|
CHECK_THROWS(SpanS(base_buf + 1, 0, base_buf));
|
||||||
|
// basic same base
|
||||||
|
CHECK_NOTHROW(SpanS(base_buf, 4, base_buf) = SpanS(base_buf + 1, 3, base_buf));
|
||||||
|
CHECK_NOTHROW(SpanS(base_buf, 4, base_buf) = SpanS(base_buf + 1, 1, base_buf));
|
||||||
|
CHECK_NOTHROW(SpanS(base_buf, 4, base_buf) = SpanS(base_buf + 1, 5, base_buf));
|
||||||
|
CHECK_THROWS(SpanS(base_buf, 4, base_buf) = SpanS(base_buf + 1, 3, base_buf + 1));
|
||||||
|
|
||||||
|
SpanS x1(base_buf, 0);
|
||||||
|
assert(x1 != nullptr);
|
||||||
|
assert(x1.raw_ptr() == base_buf);
|
||||||
|
assert(x1.raw_base() == base_buf);
|
||||||
|
assert(x1.raw_size_in_bytes() == 0u);
|
||||||
|
CHECK_THROWS(*x1);
|
||||||
|
CHECK_THROWS(x1[0]);
|
||||||
|
|
||||||
|
SpanS a2(base_buf, 4);
|
||||||
|
assert(a2 != nullptr);
|
||||||
|
assert(a2.raw_ptr() == base_buf);
|
||||||
|
assert(a2.raw_base() == base_buf);
|
||||||
|
assert(a2.raw_size_in_bytes() == 4u);
|
||||||
|
CHECK(*a2 == 0);
|
||||||
|
CHECK(a2[1] == 1);
|
||||||
|
|
||||||
|
SpanS base0(base_buf, 4, base_buf);
|
||||||
|
assert(base0.raw_ptr() == base_buf);
|
||||||
|
assert(base0.raw_base() == base_buf);
|
||||||
|
assert(base0.raw_size_in_bytes() == 4u);
|
||||||
|
|
||||||
|
SpanS base4(base_buf, 4);
|
||||||
|
assert(base4.raw_ptr() == base_buf);
|
||||||
|
assert(base4.raw_base() == base_buf);
|
||||||
|
assert(base4.raw_size_in_bytes() == 4u);
|
||||||
|
|
||||||
|
SpanS a1(base_buf, 4);
|
||||||
|
a1 = base_buf;
|
||||||
|
a1 = base0;
|
||||||
|
assert(a1 == base0);
|
||||||
|
assert(a1 != nullptr);
|
||||||
|
assert(a1.raw_ptr() == base0.raw_ptr());
|
||||||
|
assert(a1.raw_base() == base_buf);
|
||||||
|
assert(a1.raw_size_in_bytes() == 4u);
|
||||||
|
a1 = base4;
|
||||||
|
assert(a1 == base_buf);
|
||||||
|
assert(a1.raw_ptr() == base_buf);
|
||||||
|
assert(a1.raw_base() == base_buf);
|
||||||
|
assert(a1.raw_size_in_bytes() == 4u);
|
||||||
|
|
||||||
|
a1 = base_buf;
|
||||||
|
a1 = base_buf + 1;
|
||||||
|
CHECK(*a1++ == 1);
|
||||||
|
CHECK(*++a1 == 3);
|
||||||
|
CHECK(*a1 == 3);
|
||||||
|
a1 = base_buf + 4; // at the end of buffer
|
||||||
|
CHECK_THROWS(*a1);
|
||||||
|
CHECK_THROWS(a1 = base_buf + 5); // range error
|
||||||
|
assert(a1 == base_buf + 4);
|
||||||
|
CHECK(a1[-4] == 0);
|
||||||
|
CHECK_THROWS(a1[-5]); // range error
|
||||||
|
a1 = base_buf;
|
||||||
|
CHECK(*a1 == 0);
|
||||||
|
|
||||||
|
SpanS new_base4(base_buf + 2, 4);
|
||||||
|
CHECK_THROWS(a1 = new_base4); // not same base
|
||||||
|
CHECK_THROWS(a2 = new_base4); // not same base
|
||||||
|
|
||||||
|
SpanS ss_with_base(base_buf, 4, base_buf);
|
||||||
|
assert(ss_with_base.raw_base() == base_buf);
|
||||||
|
CHECK_THROWS(ss_with_base = my_null); // nullptr assignment
|
||||||
|
#if XSPAN_CONFIG_ENABLE_SPAN_CONVERSION
|
||||||
|
{
|
||||||
|
typedef PtrOrSpanOrNull<char> Span0;
|
||||||
|
// v0 nullptr, b0 base, b1 base + 1
|
||||||
|
const Span0 v0_v0(nullptr);
|
||||||
|
const Span0 v0_b0(nullptr, 4, base_buf);
|
||||||
|
const Span0 v0_b1(nullptr, 3, base_buf + 1);
|
||||||
|
const Span0 b0_v0(base_buf);
|
||||||
|
const Span0 b0_b0(base_buf, 4, base_buf);
|
||||||
|
CHECK_THROWS(XSPAN_0_MAKE(char, base_buf, 3, base_buf + 1)); // b0_b1
|
||||||
|
const Span0 b1_v0(base_buf + 1);
|
||||||
|
const Span0 b1_b0(base_buf + 1, 4, base_buf);
|
||||||
|
const Span0 b1_b1(base_buf + 1, 3, base_buf + 1);
|
||||||
|
CHECK_THROWS(ss_with_base = v0_v0); // nullptr assignment
|
||||||
|
CHECK_THROWS(ss_with_base = v0_b0); // nullptr assignment
|
||||||
|
CHECK_THROWS(ss_with_base = v0_b1); // nullptr assignment
|
||||||
|
CHECK_NOTHROW(ss_with_base = b0_v0);
|
||||||
|
CHECK_NOTHROW(ss_with_base = b0_b0);
|
||||||
|
CHECK_NOTHROW(ss_with_base = b1_v0);
|
||||||
|
CHECK_NOTHROW(ss_with_base = b1_b0);
|
||||||
|
CHECK_THROWS(ss_with_base = b1_b1); // different base
|
||||||
|
CHECK_THROWS(XSPAN_S_MAKE(char, v0_v0));
|
||||||
|
CHECK_THROWS(XSPAN_S_MAKE(char, v0_b0));
|
||||||
|
CHECK_THROWS(XSPAN_S_MAKE(char, v0_b1));
|
||||||
|
CHECK_THROWS(XSPAN_S_MAKE(char, b0_v0));
|
||||||
|
CHECK_NOTHROW(XSPAN_S_MAKE(char, b0_b0));
|
||||||
|
CHECK_THROWS(XSPAN_S_MAKE(char, b1_v0));
|
||||||
|
CHECK_NOTHROW(XSPAN_S_MAKE(char, b1_b0));
|
||||||
|
CHECK_NOTHROW(XSPAN_S_MAKE(char, b1_b1));
|
||||||
|
//
|
||||||
|
CHECK((XSPAN_S_MAKE(char, b0_b0).raw_base() == base_buf));
|
||||||
|
CHECK((XSPAN_S_MAKE(char, b1_b0).raw_base() == base_buf));
|
||||||
|
CHECK((XSPAN_S_MAKE(char, b1_b1).raw_base() == base_buf + 1));
|
||||||
|
}
|
||||||
|
{
|
||||||
|
typedef PtrOrSpan<char> SpanP;
|
||||||
|
// v0 nullptr, b0 base, b1 base + 1
|
||||||
|
const SpanP b0_v0(base_buf);
|
||||||
|
const SpanP b0_b0(base_buf, 4, base_buf);
|
||||||
|
CHECK_THROWS(XSPAN_P_MAKE(char, base_buf, 3, base_buf + 1)); // b0_b1
|
||||||
|
const SpanP b1_v0(base_buf + 1);
|
||||||
|
const SpanP b1_b0(base_buf + 1, 4, base_buf);
|
||||||
|
const SpanP b1_b1(base_buf + 1, 3, base_buf + 1);
|
||||||
|
CHECK_NOTHROW(ss_with_base = b0_v0);
|
||||||
|
CHECK_NOTHROW(ss_with_base = b0_b0);
|
||||||
|
CHECK_NOTHROW(ss_with_base = b1_v0);
|
||||||
|
CHECK_NOTHROW(ss_with_base = b1_b0);
|
||||||
|
CHECK_THROWS(ss_with_base = b1_b1); // different base
|
||||||
|
CHECK_THROWS(XSPAN_S_MAKE(char, b0_v0));
|
||||||
|
CHECK_NOTHROW(XSPAN_S_MAKE(char, b0_b0));
|
||||||
|
CHECK_THROWS(XSPAN_S_MAKE(char, b1_v0));
|
||||||
|
CHECK_NOTHROW(XSPAN_S_MAKE(char, b1_b0));
|
||||||
|
CHECK_NOTHROW(XSPAN_S_MAKE(char, b1_b1));
|
||||||
|
//
|
||||||
|
CHECK((XSPAN_S_MAKE(char, b0_b0).raw_base() == base_buf));
|
||||||
|
CHECK((XSPAN_S_MAKE(char, b1_b0).raw_base() == base_buf));
|
||||||
|
CHECK((XSPAN_S_MAKE(char, b1_b1).raw_base() == base_buf + 1));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
//
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
TEST_CASE("Span void ptr") {
|
||||||
|
static char a[4] = {0, 1, 2, 3};
|
||||||
|
XSPAN_0(void) a0(a, 4);
|
||||||
|
XSPAN_P(void) ap(a, 4);
|
||||||
|
XSPAN_S(void) as(a, 4);
|
||||||
|
XSPAN_0(const void) c0(a, 4);
|
||||||
|
XSPAN_P(const void) cp(a, 4);
|
||||||
|
XSPAN_S(const void) cs(a, 4);
|
||||||
|
static const char b[4] = {0, 1, 2, 3};
|
||||||
|
XSPAN_0(const void) b0(b, 4);
|
||||||
|
XSPAN_P(const void) bp(b, 4);
|
||||||
|
XSPAN_S(const void) bs(b, 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("Span deref/array/arrow") {
|
||||||
|
static char real_a[2 + 4 + 2] = {126, 127, 0, 1, 2, 3, 124, 125};
|
||||||
|
static char *a = real_a + 2;
|
||||||
|
XSPAN_0(char) a0(a, 4);
|
||||||
|
XSPAN_P(char) ap(a, 4);
|
||||||
|
XSPAN_S(char) as(a, 4);
|
||||||
|
CHECK_THROWS(a0[4]);
|
||||||
|
CHECK_THROWS(a0[-1]);
|
||||||
|
CHECK_THROWS(a0[-2]);
|
||||||
|
a0 += 2;
|
||||||
|
CHECK(*a0 == 2);
|
||||||
|
CHECK(a0[-1] == 1);
|
||||||
|
CHECK(a0[0] == 2);
|
||||||
|
CHECK(a0[1] == 3);
|
||||||
|
ap += 2;
|
||||||
|
CHECK(*ap == 2);
|
||||||
|
CHECK(ap[-1] == 1);
|
||||||
|
CHECK(ap[0] == 2);
|
||||||
|
CHECK(ap[1] == 3);
|
||||||
|
as += 2;
|
||||||
|
CHECK(*as == 2);
|
||||||
|
CHECK(as[-1] == 1);
|
||||||
|
CHECK(as[0] == 2);
|
||||||
|
CHECK(as[1] == 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("Span subspan") {
|
||||||
|
static char buf[4] = {0, 1, 2, 3};
|
||||||
|
XSPAN_S(char) as(buf, 4);
|
||||||
|
CHECK(as.subspan(1, 1)[0] == 1);
|
||||||
|
CHECK((as + 1).subspan(1, 1)[0] == 2);
|
||||||
|
CHECK((as + 2).subspan(0, -2)[0] == 0);
|
||||||
|
CHECK_THROWS(as.subspan(1, 0)[0]);
|
||||||
|
CHECK_THROWS(as.subspan(1, 1)[-1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("Span constness") {
|
||||||
|
static char buf[4] = {0, 1, 2, 3};
|
||||||
|
|
||||||
|
XSPAN_0(char) b0(buf, 4);
|
||||||
|
XSPAN_P(char) bp(buf, 4);
|
||||||
|
XSPAN_S(char) bs(buf, 4);
|
||||||
|
|
||||||
|
XSPAN_0(char) s0(b0);
|
||||||
|
XSPAN_P(char) sp(bp);
|
||||||
|
XSPAN_S(char) ss(bs);
|
||||||
|
|
||||||
|
XSPAN_0(const char) b0c(buf, 4);
|
||||||
|
XSPAN_P(const char) bpc(buf, 4);
|
||||||
|
XSPAN_S(const char) bsc(buf, 4);
|
||||||
|
|
||||||
|
XSPAN_0(const char) s0c(b0c);
|
||||||
|
XSPAN_P(const char) spc(bpc);
|
||||||
|
XSPAN_S(const char) ssc(bsc);
|
||||||
|
|
||||||
|
XSPAN_0(const char) x0c(b0);
|
||||||
|
XSPAN_P(const char) xpc(bp);
|
||||||
|
XSPAN_S(const char) xsc(bs);
|
||||||
|
|
||||||
|
CHECK(ptr_diff_bytes(b0, buf) == 0);
|
||||||
|
CHECK(ptr_diff_bytes(bp, buf) == 0);
|
||||||
|
CHECK(ptr_diff_bytes(bs, buf) == 0);
|
||||||
|
CHECK(ptr_diff_bytes(s0, buf) == 0);
|
||||||
|
CHECK(ptr_diff_bytes(sp, buf) == 0);
|
||||||
|
CHECK(ptr_diff_bytes(bs, buf) == 0);
|
||||||
|
//
|
||||||
|
CHECK(ptr_diff_bytes(s0, bp) == 0);
|
||||||
|
CHECK(ptr_diff_bytes(s0, sp) == 0);
|
||||||
|
CHECK(ptr_diff_bytes(s0, ss) == 0);
|
||||||
|
//
|
||||||
|
CHECK(ptr_diff_bytes(s0c, b0c) == 0);
|
||||||
|
CHECK(ptr_diff_bytes(spc, bpc) == 0);
|
||||||
|
CHECK(ptr_diff_bytes(ssc, bsc) == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
//
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
#if !defined(DOCTEST_CONFIG_DISABLE)
|
||||||
|
namespace {
|
||||||
|
int my_memcmp_v1(XSPAN_P(const void) a, XSPAN_0(const void) b, size_t n) {
|
||||||
|
if (b == nullptr)
|
||||||
|
return -2;
|
||||||
|
XSPAN_0(const void) x(a);
|
||||||
|
return memcmp(x, b, n);
|
||||||
|
}
|
||||||
|
int my_memcmp_v2(XSPAN_P(const char) a, XSPAN_0(const char) b, size_t n) {
|
||||||
|
if (a == b)
|
||||||
|
return 0;
|
||||||
|
if (b == nullptr)
|
||||||
|
return -2;
|
||||||
|
a += 1;
|
||||||
|
b -= 1;
|
||||||
|
XSPAN_0(const char) x(a);
|
||||||
|
XSPAN_0(const char) y = b;
|
||||||
|
return memcmp(x, y, n);
|
||||||
|
}
|
||||||
|
} // namespace
|
||||||
|
#endif
|
||||||
|
|
||||||
|
TEST_CASE("PtrOrSpan") {
|
||||||
|
static const char buf[4] = {0, 1, 2, 3};
|
||||||
|
CHECK(my_memcmp_v1(buf, nullptr, 4) == -2);
|
||||||
|
CHECK(my_memcmp_v2(buf + 4, buf + 4, 999) == 0);
|
||||||
|
CHECK(my_memcmp_v2(buf, buf + 2, 3) == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
//
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
TEST_CASE("PtrOrSpan char") {
|
||||||
|
char real_buf[2 + 8 + 2] = {126, 127, 0, 1, 2, 3, 4, 5, 6, 7, 124, 125};
|
||||||
|
char *buf = real_buf + 2;
|
||||||
|
XSPAN_P(char) a(buf, XSpanSizeInBytes(8));
|
||||||
|
XSPAN_P(char) b = a.subspan(0, 7);
|
||||||
|
XSPAN_P(char) c = (b + 1).subspan(0, 6);
|
||||||
|
a += 1;
|
||||||
|
CHECK(*a == 1);
|
||||||
|
*a++ += 1;
|
||||||
|
*b++ = 1;
|
||||||
|
CHECK(a == buf + 2);
|
||||||
|
CHECK(b == buf + 1);
|
||||||
|
CHECK(c == buf + 1);
|
||||||
|
CHECK(*b == 2);
|
||||||
|
CHECK(*c == 2);
|
||||||
|
CHECK(a.raw_size_in_bytes() == 8u);
|
||||||
|
CHECK(b.raw_size_in_bytes() == 7u);
|
||||||
|
CHECK(c.raw_size_in_bytes() == 6u);
|
||||||
|
CHECK(a.raw_base() == buf);
|
||||||
|
CHECK(b.raw_base() == buf);
|
||||||
|
CHECK(c.raw_base() == buf + 1);
|
||||||
|
#ifdef UPX_VERSION_HEX
|
||||||
|
CHECK(get_le32(a) != 0);
|
||||||
|
#endif
|
||||||
|
++c;
|
||||||
|
c++;
|
||||||
|
#ifdef UPX_VERSION_HEX
|
||||||
|
CHECK(get_le32(c) != 0);
|
||||||
|
#endif
|
||||||
|
++c;
|
||||||
|
#ifdef UPX_VERSION_HEX
|
||||||
|
CHECK_THROWS(get_le32(c));
|
||||||
|
#endif
|
||||||
|
++b;
|
||||||
|
b++;
|
||||||
|
b += 4;
|
||||||
|
CHECK(b.raw_ptr() == buf + 7);
|
||||||
|
CHECK_THROWS(*b);
|
||||||
|
CHECK(a.raw_size_in_bytes() == 8u);
|
||||||
|
a = b;
|
||||||
|
CHECK(a.raw_size_in_bytes() == 8u);
|
||||||
|
CHECK(a.raw_ptr() == buf + 7);
|
||||||
|
a++;
|
||||||
|
CHECK_THROWS(*a);
|
||||||
|
CHECK_THROWS(raw_bytes(a, 1));
|
||||||
|
a = b;
|
||||||
|
CHECK_THROWS(a = c);
|
||||||
|
*a = 0;
|
||||||
|
a = buf;
|
||||||
|
#ifdef UPX_VERSION_HEX
|
||||||
|
CHECK(upx_safe_strlen(a) == 7u);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("PtrOrSpan int") {
|
||||||
|
int buf[8] = {0, 1, 2, 3, 4, 5, 6, 7};
|
||||||
|
XSPAN_P(int) a(buf, XSpanCount(8));
|
||||||
|
CHECK(a.raw_size_in_bytes() == 8 * sizeof(int));
|
||||||
|
XSPAN_P(int) b = a.subspan(0, 7);
|
||||||
|
CHECK(b.raw_size_in_bytes() == 7 * sizeof(int));
|
||||||
|
XSPAN_P(int) c = (b + 1).subspan(0, 6);
|
||||||
|
CHECK(c.raw_size_in_bytes() == 6 * sizeof(int));
|
||||||
|
a += 1;
|
||||||
|
CHECK(*a == 1);
|
||||||
|
CHECK(*a++ == 1);
|
||||||
|
CHECK(*++a == 3);
|
||||||
|
CHECK(--*a == 2);
|
||||||
|
CHECK(*a-- == 2);
|
||||||
|
CHECK(*b == 0);
|
||||||
|
CHECK(*c == 1);
|
||||||
|
a = buf + 7;
|
||||||
|
#ifdef UPX_VERSION_HEX
|
||||||
|
CHECK(get_le32(a) == ne32_to_le32(7));
|
||||||
|
#endif
|
||||||
|
a++;
|
||||||
|
#ifdef UPX_VERSION_HEX
|
||||||
|
CHECK_THROWS(get_le32(a));
|
||||||
|
#endif
|
||||||
|
CHECK_THROWS(raw_bytes(a, 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
// codegen
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
template <class T>
|
||||||
|
__acc_static_noinline int foo(T p) {
|
||||||
|
unsigned r = 0;
|
||||||
|
r += *p++;
|
||||||
|
r += *++p;
|
||||||
|
p += 3;
|
||||||
|
r += *p;
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
XSPAN_0(T)
|
||||||
|
make_span_0(T *ptr, size_t count) {
|
||||||
|
return PtrOrSpanOrNull<T>(ptr, count);
|
||||||
|
}
|
||||||
|
template <class T>
|
||||||
|
XSPAN_P(T)
|
||||||
|
make_span_p(T *ptr, size_t count) {
|
||||||
|
return PtrOrSpan<T>(ptr, count);
|
||||||
|
}
|
||||||
|
template <class T>
|
||||||
|
XSPAN_S(T)
|
||||||
|
make_span_s(T *ptr, size_t count) {
|
||||||
|
return Span<T>(ptr, count);
|
||||||
|
}
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
TEST_CASE("Span codegen") {
|
||||||
|
char buf[8] = {0, 1, 2, 3, 4, 5, 6, 7};
|
||||||
|
CHECK(foo(buf) == 0 + 2 + 5);
|
||||||
|
CHECK(foo(make_span_0(buf, 8)) == 0 + 2 + 5);
|
||||||
|
CHECK(foo(make_span_p(buf, 8)) == 0 + 2 + 5);
|
||||||
|
CHECK(foo(make_span_s(buf, 8)) == 0 + 2 + 5);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // WITH_XSPAN >= 2
|
||||||
|
|
||||||
|
/* vim:set ts=4 sw=4 et: */
|
||||||
@@ -2,8 +2,7 @@
|
|||||||
|
|
||||||
This file is part of the UPX executable compressor.
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
Copyright (C) 1996-2022 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2022 Laszlo Molnar
|
|
||||||
All Rights Reserved.
|
All Rights Reserved.
|
||||||
|
|
||||||
UPX and the UCL library are free software; you can redistribute them
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
@@ -21,22 +20,19 @@
|
|||||||
If not, write to the Free Software Foundation, Inc.,
|
If not, write to the Free Software Foundation, Inc.,
|
||||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
Markus F.X.J. Oberhumer Laszlo Molnar
|
Markus F.X.J. Oberhumer
|
||||||
<markus@oberhumer.com> <ezerotven+github@gmail.com>
|
<markus@oberhumer.com>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include "../conf.h"
|
||||||
#include "conf.h"
|
|
||||||
#include "compress.h"
|
#include "compress.h"
|
||||||
#include "util/membuffer.h"
|
#include "../util/membuffer.h"
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
//
|
//
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
unsigned upx_adler32(const void *buf, unsigned len, unsigned adler)
|
unsigned upx_adler32(const void *buf, unsigned len, unsigned adler) {
|
||||||
{
|
|
||||||
if (len == 0)
|
if (len == 0)
|
||||||
return adler;
|
return adler;
|
||||||
assert(buf != nullptr);
|
assert(buf != nullptr);
|
||||||
@@ -47,8 +43,7 @@ unsigned upx_adler32(const void *buf, unsigned len, unsigned adler)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if 0 // UNUSED
|
||||||
#if 0 /* UNUSED */
|
|
||||||
unsigned upx_crc32(const void *buf, unsigned len, unsigned crc)
|
unsigned upx_crc32(const void *buf, unsigned len, unsigned crc)
|
||||||
{
|
{
|
||||||
if (len == 0)
|
if (len == 0)
|
||||||
@@ -60,24 +55,20 @@ unsigned upx_crc32(const void *buf, unsigned len, unsigned crc)
|
|||||||
return upx_zlib_crc32(buf, len, crc);
|
return upx_zlib_crc32(buf, len, crc);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
#endif /* UNUSED */
|
#endif // UNUSED
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
//
|
//
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
int upx_compress( const upx_bytep src, unsigned src_len,
|
int upx_compress(const upx_bytep src, unsigned src_len, upx_bytep dst, unsigned *dst_len,
|
||||||
upx_bytep dst, unsigned* dst_len,
|
upx_callback_p cb, int method, int level, const upx_compress_config_t *cconf,
|
||||||
upx_callback_p cb,
|
upx_compress_result_t *cresult) {
|
||||||
int method, int level,
|
|
||||||
const upx_compress_config_t *cconf,
|
|
||||||
upx_compress_result_t *cresult )
|
|
||||||
{
|
|
||||||
int r = UPX_E_ERROR;
|
int r = UPX_E_ERROR;
|
||||||
upx_compress_result_t cresult_buffer;
|
upx_compress_result_t cresult_buffer;
|
||||||
|
|
||||||
assert(method > 0); assert(level > 0);
|
assert(method > 0);
|
||||||
|
assert(level > 0);
|
||||||
|
|
||||||
#if 1
|
#if 1
|
||||||
// set available bytes in dst
|
// set available bytes in dst
|
||||||
@@ -94,60 +85,57 @@ int upx_compress( const upx_bytep src, unsigned src_len,
|
|||||||
cresult = &cresult_buffer;
|
cresult = &cresult_buffer;
|
||||||
memset(cresult, 0, sizeof(*cresult));
|
memset(cresult, 0, sizeof(*cresult));
|
||||||
#if 1
|
#if 1
|
||||||
// debug
|
// debugging aid
|
||||||
cresult->method = method;
|
cresult->debug.method = method;
|
||||||
cresult->level = level;
|
cresult->debug.level = level;
|
||||||
cresult->u_len = src_len;
|
cresult->debug.u_len = src_len;
|
||||||
cresult->c_len = 0;
|
cresult->debug.c_len = 0;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if __acc_cte(0) {
|
if (__acc_cte(false)) {
|
||||||
}
|
}
|
||||||
#if (WITH_LZMA)
|
#if (WITH_LZMA)
|
||||||
else if (M_IS_LZMA(method))
|
else if (M_IS_LZMA(method))
|
||||||
r = upx_lzma_compress(src, src_len, dst, dst_len,
|
r = upx_lzma_compress(src, src_len, dst, dst_len, cb, method, level, cconf, cresult);
|
||||||
cb, method, level, cconf, cresult);
|
|
||||||
#endif
|
#endif
|
||||||
#if (WITH_NRV)
|
#if (WITH_NRV)
|
||||||
else if ((M_IS_NRV2B(method) || M_IS_NRV2D(method) || M_IS_NRV2E(method)) && !opt->prefer_ucl)
|
else if ((M_IS_NRV2B(method) || M_IS_NRV2D(method) || M_IS_NRV2E(method)) && !opt->prefer_ucl)
|
||||||
r = upx_nrv_compress(src, src_len, dst, dst_len,
|
r = upx_nrv_compress(src, src_len, dst, dst_len, cb, method, level, cconf, cresult);
|
||||||
cb, method, level, cconf, cresult);
|
|
||||||
#endif
|
#endif
|
||||||
#if (WITH_UCL)
|
#if (WITH_UCL)
|
||||||
else if (M_IS_NRV2B(method) || M_IS_NRV2D(method) || M_IS_NRV2E(method))
|
else if (M_IS_NRV2B(method) || M_IS_NRV2D(method) || M_IS_NRV2E(method))
|
||||||
r = upx_ucl_compress(src, src_len, dst, dst_len,
|
r = upx_ucl_compress(src, src_len, dst, dst_len, cb, method, level, cconf, cresult);
|
||||||
cb, method, level, cconf, cresult);
|
#endif
|
||||||
|
#if (WITH_ZSTD)
|
||||||
|
else if (M_IS_ZSTD(method))
|
||||||
|
r = upx_zstd_compress(src, src_len, dst, dst_len, cb, method, level, cconf, cresult);
|
||||||
#endif
|
#endif
|
||||||
else {
|
else {
|
||||||
throwInternalError("unknown compression method");
|
throwInternalError("unknown compression method");
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 1
|
#if 1
|
||||||
// debug
|
// debugging aid
|
||||||
cresult->c_len = *dst_len;
|
cresult->debug.c_len = *dst_len;
|
||||||
#endif
|
#endif
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
//
|
//
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
int upx_decompress(const upx_bytep src, unsigned src_len,
|
int upx_decompress(const upx_bytep src, unsigned src_len, upx_bytep dst, unsigned *dst_len,
|
||||||
upx_bytep dst, unsigned* dst_len,
|
int method, const upx_compress_result_t *cresult) {
|
||||||
int method,
|
|
||||||
const upx_compress_result_t *cresult )
|
|
||||||
{
|
|
||||||
int r = UPX_E_ERROR;
|
int r = UPX_E_ERROR;
|
||||||
|
|
||||||
assert(*dst_len > 0);
|
assert(*dst_len > 0);
|
||||||
assert(src_len < *dst_len); // must be compressed
|
assert(src_len < *dst_len); // must be compressed
|
||||||
|
|
||||||
if (cresult && cresult->method == 0)
|
if (cresult && cresult->debug.method == 0)
|
||||||
cresult = nullptr;
|
cresult = nullptr;
|
||||||
|
|
||||||
if __acc_cte(0) {
|
if (__acc_cte(false)) {
|
||||||
}
|
}
|
||||||
#if (WITH_LZMA)
|
#if (WITH_LZMA)
|
||||||
else if (M_IS_LZMA(method))
|
else if (M_IS_LZMA(method))
|
||||||
@@ -164,6 +152,10 @@ int upx_decompress(const upx_bytep src, unsigned src_len,
|
|||||||
#if (WITH_ZLIB)
|
#if (WITH_ZLIB)
|
||||||
else if (M_IS_DEFLATE(method))
|
else if (M_IS_DEFLATE(method))
|
||||||
r = upx_zlib_decompress(src, src_len, dst, dst_len, method, cresult);
|
r = upx_zlib_decompress(src, src_len, dst, dst_len, method, cresult);
|
||||||
|
#endif
|
||||||
|
#if (WITH_ZSTD)
|
||||||
|
else if (M_IS_ZSTD(method))
|
||||||
|
r = upx_zstd_decompress(src, src_len, dst, dst_len, method, cresult);
|
||||||
#endif
|
#endif
|
||||||
else {
|
else {
|
||||||
throwInternalError("unknown decompression method");
|
throwInternalError("unknown decompression method");
|
||||||
@@ -172,21 +164,15 @@ int upx_decompress(const upx_bytep src, unsigned src_len,
|
|||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
//
|
//
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
int upx_test_overlap( const upx_bytep buf,
|
int upx_test_overlap(const upx_bytep buf, const upx_bytep tbuf, unsigned src_off, unsigned src_len,
|
||||||
const upx_bytep tbuf,
|
unsigned *dst_len, int method, const upx_compress_result_t *cresult) {
|
||||||
unsigned src_off, unsigned src_len,
|
|
||||||
unsigned* dst_len,
|
|
||||||
int method,
|
|
||||||
const upx_compress_result_t *cresult )
|
|
||||||
{
|
|
||||||
int r = UPX_E_ERROR;
|
int r = UPX_E_ERROR;
|
||||||
|
|
||||||
if (cresult && cresult->method == 0)
|
if (cresult && cresult->debug.method == 0)
|
||||||
cresult = nullptr;
|
cresult = nullptr;
|
||||||
|
|
||||||
assert(*dst_len > 0);
|
assert(*dst_len > 0);
|
||||||
@@ -194,7 +180,7 @@ int upx_test_overlap( const upx_bytep buf,
|
|||||||
unsigned overlap_overhead = src_off + src_len - *dst_len;
|
unsigned overlap_overhead = src_off + src_len - *dst_len;
|
||||||
assert((int) overlap_overhead > 0);
|
assert((int) overlap_overhead > 0);
|
||||||
|
|
||||||
if __acc_cte(0) {
|
if (__acc_cte(false)) {
|
||||||
}
|
}
|
||||||
#if (WITH_LZMA)
|
#if (WITH_LZMA)
|
||||||
else if (M_IS_LZMA(method))
|
else if (M_IS_LZMA(method))
|
||||||
@@ -207,6 +193,10 @@ int upx_test_overlap( const upx_bytep buf,
|
|||||||
#if (WITH_UCL)
|
#if (WITH_UCL)
|
||||||
else if (M_IS_NRV2B(method) || M_IS_NRV2D(method) || M_IS_NRV2E(method))
|
else if (M_IS_NRV2B(method) || M_IS_NRV2D(method) || M_IS_NRV2E(method))
|
||||||
r = upx_ucl_test_overlap(buf, tbuf, src_off, src_len, dst_len, method, cresult);
|
r = upx_ucl_test_overlap(buf, tbuf, src_off, src_len, dst_len, method, cresult);
|
||||||
|
#endif
|
||||||
|
#if (WITH_ZSTD)
|
||||||
|
else if (M_IS_ZSTD(method))
|
||||||
|
r = upx_zstd_test_overlap(buf, tbuf, src_off, src_len, dst_len, method, cresult);
|
||||||
#endif
|
#endif
|
||||||
else {
|
else {
|
||||||
throwInternalError("unknown decompression method");
|
throwInternalError("unknown decompression method");
|
||||||
@@ -2,8 +2,7 @@
|
|||||||
|
|
||||||
This file is part of the UPX executable compressor.
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
Copyright (C) 1996-2022 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2022 Laszlo Molnar
|
|
||||||
All Rights Reserved.
|
All Rights Reserved.
|
||||||
|
|
||||||
UPX and the UCL library are free software; you can redistribute them
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
@@ -21,19 +20,40 @@
|
|||||||
If not, write to the Free Software Foundation, Inc.,
|
If not, write to the Free Software Foundation, Inc.,
|
||||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
Markus F.X.J. Oberhumer Laszlo Molnar
|
Markus F.X.J. Oberhumer
|
||||||
<markus@oberhumer.com> <ezerotven+github@gmail.com>
|
<markus@oberhumer.com>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
#ifndef __UPX_COMPRESS_H
|
#ifndef UPX_COMPRESS_H__
|
||||||
#define __UPX_COMPRESS_H 1
|
#define UPX_COMPRESS_H__ 1
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
//
|
//
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
|
#if (WITH_BZIP2)
|
||||||
|
int upx_bzip2_init(void);
|
||||||
|
const char *upx_bzip2_version_string(void);
|
||||||
|
int upx_bzip2_compress ( const upx_bytep src, unsigned src_len,
|
||||||
|
upx_bytep dst, unsigned* dst_len,
|
||||||
|
upx_callback_p cb,
|
||||||
|
int method, int level,
|
||||||
|
const upx_compress_config_t *cconf,
|
||||||
|
upx_compress_result_t *cresult );
|
||||||
|
int upx_bzip2_decompress ( const upx_bytep src, unsigned src_len,
|
||||||
|
upx_bytep dst, unsigned* dst_len,
|
||||||
|
int method,
|
||||||
|
const upx_compress_result_t *cresult );
|
||||||
|
int upx_bzip2_test_overlap ( const upx_bytep buf,
|
||||||
|
const upx_bytep tbuf,
|
||||||
|
unsigned src_off, unsigned src_len,
|
||||||
|
unsigned* dst_len,
|
||||||
|
int method,
|
||||||
|
const upx_compress_result_t *cresult );
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#if (WITH_LZMA)
|
#if (WITH_LZMA)
|
||||||
int upx_lzma_init(void);
|
int upx_lzma_init(void);
|
||||||
const char *upx_lzma_version_string(void);
|
const char *upx_lzma_version_string(void);
|
||||||
@@ -126,6 +146,28 @@ unsigned upx_zlib_crc32 (const void *buf, unsigned len, unsigned crc);
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#if (WITH_ZSTD)
|
||||||
|
int upx_zstd_init(void);
|
||||||
|
const char *upx_zstd_version_string(void);
|
||||||
|
int upx_zstd_compress ( const upx_bytep src, unsigned src_len,
|
||||||
|
upx_bytep dst, unsigned* dst_len,
|
||||||
|
upx_callback_p cb,
|
||||||
|
int method, int level,
|
||||||
|
const upx_compress_config_t *cconf,
|
||||||
|
upx_compress_result_t *cresult );
|
||||||
|
int upx_zstd_decompress ( const upx_bytep src, unsigned src_len,
|
||||||
|
upx_bytep dst, unsigned* dst_len,
|
||||||
|
int method,
|
||||||
|
const upx_compress_result_t *cresult );
|
||||||
|
int upx_zstd_test_overlap ( const upx_bytep buf,
|
||||||
|
const upx_bytep tbuf,
|
||||||
|
unsigned src_off, unsigned src_len,
|
||||||
|
unsigned* dst_len,
|
||||||
|
int method,
|
||||||
|
const upx_compress_result_t *cresult );
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#endif /* already included */
|
#endif /* already included */
|
||||||
|
|
||||||
/* vim:set ts=4 sw=4 et: */
|
/* vim:set ts=4 sw=4 et: */
|
||||||
@@ -2,8 +2,7 @@
|
|||||||
|
|
||||||
This file is part of the UPX executable compressor.
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
Copyright (C) 1996-2022 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2022 Laszlo Molnar
|
|
||||||
All Rights Reserved.
|
All Rights Reserved.
|
||||||
|
|
||||||
UPX and the UCL library are free software; you can redistribute them
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
@@ -21,14 +20,13 @@
|
|||||||
If not, write to the Free Software Foundation, Inc.,
|
If not, write to the Free Software Foundation, Inc.,
|
||||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
Markus F.X.J. Oberhumer Laszlo Molnar
|
Markus F.X.J. Oberhumer
|
||||||
<markus@oberhumer.com> <ezerotven+github@gmail.com>
|
<markus@oberhumer.com>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include "../conf.h"
|
||||||
#include "conf.h"
|
|
||||||
#include "compress.h"
|
#include "compress.h"
|
||||||
#include "util/membuffer.h"
|
#include "../util/membuffer.h"
|
||||||
|
|
||||||
#if (ACC_CC_CLANG)
|
#if (ACC_CC_CLANG)
|
||||||
#pragma clang diagnostic ignored "-Wshadow"
|
#pragma clang diagnostic ignored "-Wshadow"
|
||||||
@@ -42,13 +40,8 @@
|
|||||||
#if (ACC_CC_MSC && (_MSC_VER < 1900))
|
#if (ACC_CC_MSC && (_MSC_VER < 1900))
|
||||||
#pragma warning(disable : 4127) // warning C4127: conditional expression is constant
|
#pragma warning(disable : 4127) // warning C4127: conditional expression is constant
|
||||||
#endif
|
#endif
|
||||||
#if (ACC_CC_INTELC_GNUC)
|
|
||||||
# pragma warning(error: 424) // #424: extra ";" ignored
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
void lzma_compress_config_t::reset() {
|
||||||
void lzma_compress_config_t::reset()
|
|
||||||
{
|
|
||||||
pos_bits.reset();
|
pos_bits.reset();
|
||||||
lit_pos_bits.reset();
|
lit_pos_bits.reset();
|
||||||
lit_context_bits.reset();
|
lit_context_bits.reset();
|
||||||
@@ -60,7 +53,6 @@ void lzma_compress_config_t::reset()
|
|||||||
max_num_probs = 0;
|
max_num_probs = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// INFO: the LZMA SDK is covered by a permissive license which allows
|
// INFO: the LZMA SDK is covered by a permissive license which allows
|
||||||
// using unmodified LZMA source code in UPX and the UPX stubs.
|
// using unmodified LZMA source code in UPX and the UPX stubs.
|
||||||
// See SPECIAL EXCEPTION below.
|
// See SPECIAL EXCEPTION below.
|
||||||
@@ -97,21 +89,18 @@ void lzma_compress_config_t::reset()
|
|||||||
// SPECIAL EXCEPTION allows you to use LZMA SDK in applications with closed code,
|
// SPECIAL EXCEPTION allows you to use LZMA SDK in applications with closed code,
|
||||||
// while you keep LZMA SDK code unmodified.
|
// while you keep LZMA SDK code unmodified.
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
// compress defaults
|
// compress defaults
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
static int prepare(lzma_compress_result_t *res,
|
static bool prepare_result(lzma_compress_result_t *res, unsigned src_len, int method, int level,
|
||||||
unsigned src_len, int method, int level,
|
const lzma_compress_config_t *lcconf) {
|
||||||
const lzma_compress_config_t *lcconf)
|
|
||||||
{
|
|
||||||
// setup defaults
|
// setup defaults
|
||||||
res->pos_bits = 2; // 0 .. 4
|
res->pos_bits = 2; // 0 .. 4
|
||||||
res->lit_pos_bits = 0; // 0 .. 4
|
res->lit_pos_bits = 0; // 0 .. 4
|
||||||
res->lit_context_bits = 3; // 0 .. 8
|
res->lit_context_bits = 3; // 0 .. 8
|
||||||
res->dict_size = 4 * 1024 * 1024; // 1 .. 2**30
|
res->dict_size = 4 * 1024 * 1024; // 1 .. 2**30
|
||||||
res->fast_mode = 2;
|
res->fast_mode = 2; // 0 .. 2
|
||||||
res->num_fast_bytes = 64; // 5 .. 273
|
res->num_fast_bytes = 64; // 5 .. 273
|
||||||
res->match_finder_cycles = 0;
|
res->match_finder_cycles = 0;
|
||||||
// UPX overrides
|
// UPX overrides
|
||||||
@@ -135,8 +124,7 @@ static int prepare(lzma_compress_result_t *res,
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
// TODO: tune these settings according to level
|
// TODO: tune these settings according to level
|
||||||
switch (level)
|
switch (level) {
|
||||||
{
|
|
||||||
case 1:
|
case 1:
|
||||||
res->dict_size = 256 * 1024;
|
res->dict_size = 256 * 1024;
|
||||||
res->fast_mode = 0;
|
res->fast_mode = 0;
|
||||||
@@ -169,8 +157,7 @@ static int prepare(lzma_compress_result_t *res,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// cconf overrides
|
// cconf overrides
|
||||||
if (lcconf)
|
if (lcconf) {
|
||||||
{
|
|
||||||
oassign(res->pos_bits, lcconf->pos_bits);
|
oassign(res->pos_bits, lcconf->pos_bits);
|
||||||
oassign(res->lit_pos_bits, lcconf->lit_pos_bits);
|
oassign(res->lit_pos_bits, lcconf->lit_pos_bits);
|
||||||
oassign(res->lit_context_bits, lcconf->lit_context_bits);
|
oassign(res->lit_context_bits, lcconf->lit_context_bits);
|
||||||
@@ -183,21 +170,16 @@ static int prepare(lzma_compress_result_t *res,
|
|||||||
res->dict_size = src_len;
|
res->dict_size = src_len;
|
||||||
|
|
||||||
// limit num_probs
|
// limit num_probs
|
||||||
if (lcconf && lcconf->max_num_probs)
|
if (lcconf && lcconf->max_num_probs) {
|
||||||
{
|
for (;;) {
|
||||||
for (;;)
|
|
||||||
{
|
|
||||||
unsigned n = 1846 + (768u << (res->lit_context_bits + res->lit_pos_bits));
|
unsigned n = 1846 + (768u << (res->lit_context_bits + res->lit_pos_bits));
|
||||||
if (n <= lcconf->max_num_probs)
|
if (n <= lcconf->max_num_probs)
|
||||||
break;
|
break;
|
||||||
if (res->lit_pos_bits > res->lit_context_bits)
|
if (res->lit_pos_bits > res->lit_context_bits) {
|
||||||
{
|
|
||||||
if (res->lit_pos_bits == 0)
|
if (res->lit_pos_bits == 0)
|
||||||
goto error;
|
goto error;
|
||||||
res->lit_pos_bits -= 1;
|
res->lit_pos_bits -= 1;
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
if (res->lit_context_bits == 0)
|
if (res->lit_context_bits == 0)
|
||||||
goto error;
|
goto error;
|
||||||
res->lit_context_bits -= 1;
|
res->lit_context_bits -= 1;
|
||||||
@@ -212,14 +194,14 @@ static int prepare(lzma_compress_result_t *res,
|
|||||||
lzma_compress_config_t::num_fast_bytes_t::assertValue(res->num_fast_bytes);
|
lzma_compress_config_t::num_fast_bytes_t::assertValue(res->num_fast_bytes);
|
||||||
|
|
||||||
res->num_probs = 1846 + (768u << (res->lit_context_bits + res->lit_pos_bits));
|
res->num_probs = 1846 + (768u << (res->lit_context_bits + res->lit_pos_bits));
|
||||||
//printf("\nlzma_compress config: %u %u %u %u %u\n", res->pos_bits, res->lit_pos_bits, res->lit_context_bits, res->dict_size, res->num_probs);
|
// printf("\nlzma_compress config: %u %u %u %u %u\n", res->pos_bits, res->lit_pos_bits,
|
||||||
return 0;
|
// res->lit_context_bits, res->dict_size, res->num_probs);
|
||||||
|
return true;
|
||||||
|
|
||||||
error:
|
error:
|
||||||
return -1;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
// compress - cruft because of pseudo-COM layer
|
// compress - cruft because of pseudo-COM layer
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
@@ -238,69 +220,80 @@ error:
|
|||||||
|
|
||||||
namespace MyLzma {
|
namespace MyLzma {
|
||||||
|
|
||||||
struct InStream: public ISequentialInStream, public CMyUnknownImp
|
struct InStream final : public ISequentialInStream, public CMyUnknownImp {
|
||||||
{
|
|
||||||
virtual ~InStream() {}
|
virtual ~InStream() {}
|
||||||
MY_UNKNOWN_IMP
|
MY_UNKNOWN_IMP
|
||||||
const Byte *b_buf; size_t b_size; size_t b_pos;
|
const Byte *b_buf = nullptr;
|
||||||
|
size_t b_size;
|
||||||
|
size_t b_pos;
|
||||||
void Init(const Byte *data, size_t size) {
|
void Init(const Byte *data, size_t size) {
|
||||||
b_buf = data; b_size = size; b_pos = 0;
|
b_buf = data;
|
||||||
|
b_size = size;
|
||||||
|
b_pos = 0;
|
||||||
}
|
}
|
||||||
STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize) override;
|
STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
STDMETHODIMP InStream::Read(void *data, UInt32 size, UInt32 *processedSize)
|
STDMETHODIMP InStream::Read(void *data, UInt32 size, UInt32 *processedSize) {
|
||||||
{
|
|
||||||
size_t remain = b_size - b_pos;
|
size_t remain = b_size - b_pos;
|
||||||
if (size > remain) size = (UInt32) remain;
|
if (size > remain)
|
||||||
|
size = (UInt32) remain;
|
||||||
memmove(data, b_buf + b_pos, size);
|
memmove(data, b_buf + b_pos, size);
|
||||||
b_pos += size;
|
b_pos += size;
|
||||||
if (processedSize != nullptr) *processedSize = size;
|
if (processedSize != nullptr)
|
||||||
|
*processedSize = size;
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct OutStream : public ISequentialOutStream, public CMyUnknownImp
|
struct OutStream final : public ISequentialOutStream, public CMyUnknownImp {
|
||||||
{
|
|
||||||
virtual ~OutStream() {}
|
virtual ~OutStream() {}
|
||||||
MY_UNKNOWN_IMP
|
MY_UNKNOWN_IMP
|
||||||
Byte *b_buf; size_t b_size; size_t b_pos; bool overflow;
|
Byte *b_buf = nullptr;
|
||||||
|
size_t b_size;
|
||||||
|
size_t b_pos;
|
||||||
|
bool overflow;
|
||||||
void Init(Byte *data, size_t size) {
|
void Init(Byte *data, size_t size) {
|
||||||
b_buf = data; b_size = size; b_pos = 0; overflow = false;
|
b_buf = data;
|
||||||
|
b_size = size;
|
||||||
|
b_pos = 0;
|
||||||
|
overflow = false;
|
||||||
}
|
}
|
||||||
HRESULT WriteByte(Byte c) {
|
HRESULT WriteByte(Byte c) {
|
||||||
if (b_pos >= b_size) { overflow = true; return E_FAIL; }
|
if (b_pos >= b_size) {
|
||||||
|
overflow = true;
|
||||||
|
return E_FAIL;
|
||||||
|
}
|
||||||
b_buf[b_pos++] = c;
|
b_buf[b_pos++] = c;
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize) override;
|
STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
STDMETHODIMP OutStream::Write(const void *data, UInt32 size, UInt32 *processedSize)
|
STDMETHODIMP OutStream::Write(const void *data, UInt32 size, UInt32 *processedSize) {
|
||||||
{
|
|
||||||
size_t remain = b_size - b_pos;
|
size_t remain = b_size - b_pos;
|
||||||
if (size > remain) size = (UInt32) remain, overflow = true;
|
if (size > remain)
|
||||||
|
size = (UInt32) remain, overflow = true;
|
||||||
memmove(b_buf + b_pos, data, size);
|
memmove(b_buf + b_pos, data, size);
|
||||||
b_pos += size;
|
b_pos += size;
|
||||||
if (processedSize != nullptr) *processedSize = size;
|
if (processedSize != nullptr)
|
||||||
|
*processedSize = size;
|
||||||
return overflow ? E_FAIL : S_OK;
|
return overflow ? E_FAIL : S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct ProgressInfo : public ICompressProgressInfo, public CMyUnknownImp
|
struct ProgressInfo final : public ICompressProgressInfo, public CMyUnknownImp {
|
||||||
{
|
|
||||||
virtual ~ProgressInfo() {}
|
virtual ~ProgressInfo() {}
|
||||||
MY_UNKNOWN_IMP
|
MY_UNKNOWN_IMP
|
||||||
STDMETHOD(SetRatioInfo)(const UInt64 *inSize, const UInt64 *outSize) override;
|
STDMETHOD(SetRatioInfo)(const UInt64 *inSize, const UInt64 *outSize) override;
|
||||||
upx_callback_p cb;
|
upx_callback_p cb = nullptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
STDMETHODIMP ProgressInfo::SetRatioInfo(const UInt64 *inSize, const UInt64 *outSize)
|
STDMETHODIMP ProgressInfo::SetRatioInfo(const UInt64 *inSize, const UInt64 *outSize) {
|
||||||
{
|
|
||||||
if (cb && cb->nprogress)
|
if (cb && cb->nprogress)
|
||||||
cb->nprogress(cb, (unsigned) *inSize, (unsigned) *outSize);
|
cb->nprogress(cb, (unsigned) *inSize, (unsigned) *outSize);
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace MyLzma
|
||||||
|
|
||||||
#include <lzma-sdk/C/Common/Alloc.cpp>
|
#include <lzma-sdk/C/Common/Alloc.cpp>
|
||||||
#include <lzma-sdk/C/Common/CRC.cpp>
|
#include <lzma-sdk/C/Common/CRC.cpp>
|
||||||
@@ -314,29 +307,27 @@ STDMETHODIMP ProgressInfo::SetRatioInfo(const UInt64 *inSize, const UInt64 *outS
|
|||||||
#include <lzma-sdk/C/7zip/Compress/RangeCoder/RangeCoderBit.cpp>
|
#include <lzma-sdk/C/7zip/Compress/RangeCoder/RangeCoderBit.cpp>
|
||||||
#undef RC_NORMALIZE
|
#undef RC_NORMALIZE
|
||||||
|
|
||||||
|
int upx_lzma_compress(const upx_bytep src, unsigned src_len, upx_bytep dst, unsigned *dst_len,
|
||||||
int upx_lzma_compress ( const upx_bytep src, unsigned src_len,
|
upx_callback_p cb, int method, int level,
|
||||||
upx_bytep dst, unsigned* dst_len,
|
const upx_compress_config_t *cconf_parm, upx_compress_result_t *cresult) {
|
||||||
upx_callback_p cb,
|
|
||||||
int method, int level,
|
|
||||||
const upx_compress_config_t *cconf_parm,
|
|
||||||
upx_compress_result_t *cresult )
|
|
||||||
{
|
|
||||||
assert(M_IS_LZMA(method));
|
assert(M_IS_LZMA(method));
|
||||||
assert(level > 0); assert(cresult != nullptr);
|
assert(level > 0);
|
||||||
|
assert(cresult != nullptr);
|
||||||
|
|
||||||
int r = UPX_E_ERROR;
|
int r = UPX_E_ERROR;
|
||||||
HRESULT rh;
|
HRESULT rh;
|
||||||
const lzma_compress_config_t *lcconf = cconf_parm ? &cconf_parm->conf_lzma : nullptr;
|
const lzma_compress_config_t *const lcconf = cconf_parm ? &cconf_parm->conf_lzma : nullptr;
|
||||||
lzma_compress_result_t *res = &cresult->result_lzma;
|
lzma_compress_result_t *const res = &cresult->result_lzma;
|
||||||
|
|
||||||
MyLzma::InStream is; is.AddRef();
|
MyLzma::InStream is;
|
||||||
MyLzma::OutStream os; os.AddRef();
|
is.AddRef();
|
||||||
is.Init(src, src_len);
|
is.Init(src, src_len);
|
||||||
|
MyLzma::OutStream os;
|
||||||
|
os.AddRef();
|
||||||
os.Init(dst, *dst_len);
|
os.Init(dst, *dst_len);
|
||||||
|
MyLzma::ProgressInfo progress;
|
||||||
MyLzma::ProgressInfo progress; progress.AddRef();
|
progress.AddRef();
|
||||||
progress.cb = cb;
|
progress.cb = cb; // progress.Init()
|
||||||
|
|
||||||
NCompress::NLZMA::CEncoder enc;
|
NCompress::NLZMA::CEncoder enc;
|
||||||
const PROPID propIDs[8] = {
|
const PROPID propIDs[8] = {
|
||||||
@@ -351,13 +342,10 @@ int upx_lzma_compress ( const upx_bytep src, unsigned src_len,
|
|||||||
};
|
};
|
||||||
PROPVARIANT pr[8];
|
PROPVARIANT pr[8];
|
||||||
const unsigned nprops = 8;
|
const unsigned nprops = 8;
|
||||||
static const wchar_t matchfinder[] = L"BT4";
|
if (!prepare_result(res, src_len, method, level, lcconf))
|
||||||
assert(NCompress::NLZMA::FindMatchFinder(matchfinder) >= 0);
|
|
||||||
pr[7].vt = VT_BSTR; pr[7].bstrVal = ACC_PCAST(BSTR, ACC_UNCONST_CAST(wchar_t *, matchfinder));
|
|
||||||
pr[0].vt = pr[1].vt = pr[2].vt = pr[3].vt = VT_UI4;
|
|
||||||
pr[4].vt = pr[5].vt = pr[6].vt = VT_UI4;
|
|
||||||
if (prepare(res, src_len, method, level, lcconf) != 0)
|
|
||||||
goto error;
|
goto error;
|
||||||
|
pr[0].vt = pr[1].vt = pr[2].vt = pr[3].vt = pr[4].vt = pr[5].vt = pr[6].vt = VT_UI4;
|
||||||
|
pr[7].vt = VT_BSTR;
|
||||||
pr[0].uintVal = res->pos_bits;
|
pr[0].uintVal = res->pos_bits;
|
||||||
pr[1].uintVal = res->lit_pos_bits;
|
pr[1].uintVal = res->lit_pos_bits;
|
||||||
pr[2].uintVal = res->lit_context_bits;
|
pr[2].uintVal = res->lit_context_bits;
|
||||||
@@ -365,11 +353,14 @@ int upx_lzma_compress ( const upx_bytep src, unsigned src_len,
|
|||||||
pr[4].uintVal = res->fast_mode;
|
pr[4].uintVal = res->fast_mode;
|
||||||
pr[5].uintVal = res->num_fast_bytes;
|
pr[5].uintVal = res->num_fast_bytes;
|
||||||
pr[6].uintVal = res->match_finder_cycles;
|
pr[6].uintVal = res->match_finder_cycles;
|
||||||
|
static const wchar_t matchfinder[] = L"BT4";
|
||||||
|
assert(NCompress::NLZMA::FindMatchFinder(matchfinder) >= 0);
|
||||||
|
pr[7].bstrVal = ACC_PCAST(BSTR, ACC_UNCONST_CAST(wchar_t *, matchfinder));
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|
||||||
if (enc.SetCoderProperties(propIDs, pr, nprops) != S_OK)
|
if (enc.SetCoderProperties(propIDs, pr, nprops) != S_OK)
|
||||||
goto error;
|
goto error;
|
||||||
|
// encode properties in LZMA-style (5 bytes)
|
||||||
if (enc.WriteCoderProperties(&os) != S_OK)
|
if (enc.WriteCoderProperties(&os) != S_OK)
|
||||||
goto error;
|
goto error;
|
||||||
if (os.overflow) {
|
if (os.overflow) {
|
||||||
@@ -378,12 +369,15 @@ int upx_lzma_compress ( const upx_bytep src, unsigned src_len,
|
|||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
assert(os.b_pos == 5);
|
assert(os.b_pos == 5);
|
||||||
|
|
||||||
|
// reset and encode properties in UPX-style (2 bytes)
|
||||||
os.b_pos = 0;
|
os.b_pos = 0;
|
||||||
// extra stuff in first byte: 5 high bits convenience for stub decompressor
|
// UPX extra stuff in first byte: 5 high bits convenience for stub decompressor
|
||||||
unsigned t = res->lit_context_bits + res->lit_pos_bits;
|
unsigned t = res->lit_context_bits + res->lit_pos_bits;
|
||||||
os.WriteByte(Byte((t << 3) | res->pos_bits));
|
os.WriteByte(Byte((t << 3) | res->pos_bits));
|
||||||
os.WriteByte(Byte((res->lit_pos_bits << 4) | (res->lit_context_bits)));
|
os.WriteByte(Byte((res->lit_pos_bits << 4) | (res->lit_context_bits)));
|
||||||
|
|
||||||
|
// compress
|
||||||
rh = enc.Code(&is, &os, nullptr, nullptr, &progress);
|
rh = enc.Code(&is, &os, nullptr, nullptr, &progress);
|
||||||
|
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
@@ -394,26 +388,24 @@ int upx_lzma_compress ( const upx_bytep src, unsigned src_len,
|
|||||||
assert(os.b_pos <= *dst_len);
|
assert(os.b_pos <= *dst_len);
|
||||||
if (rh == E_OUTOFMEMORY)
|
if (rh == E_OUTOFMEMORY)
|
||||||
r = UPX_E_OUT_OF_MEMORY;
|
r = UPX_E_OUT_OF_MEMORY;
|
||||||
else if (os.overflow)
|
else if (os.overflow) {
|
||||||
{
|
|
||||||
assert(os.b_pos == *dst_len);
|
assert(os.b_pos == *dst_len);
|
||||||
// r = UPX_E_OUTPUT_OVERRUN;
|
// r = UPX_E_OUTPUT_OVERRUN;
|
||||||
r = UPX_E_NOT_COMPRESSIBLE;
|
r = UPX_E_NOT_COMPRESSIBLE;
|
||||||
}
|
} else if (rh == S_OK) {
|
||||||
else if (rh == S_OK)
|
|
||||||
{
|
|
||||||
assert(is.b_pos == src_len);
|
assert(is.b_pos == src_len);
|
||||||
r = UPX_E_OK;
|
r = UPX_E_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
error:
|
error:
|
||||||
*dst_len = (unsigned) os.b_pos;
|
*dst_len = (unsigned) os.b_pos;
|
||||||
//printf("\nlzma_compress: %d: %u %u %u %u %u, %u - > %u\n", r, res->pos_bits, res->lit_pos_bits, res->lit_context_bits, res->dict_size, res->num_probs, src_len, *dst_len);
|
// printf("\nlzma_compress: %d: %u %u %u %u %u, %u - > %u\n", r, res->pos_bits,
|
||||||
|
// res->lit_pos_bits,
|
||||||
|
// res->lit_context_bits, res->dict_size, res->num_probs, src_len, *dst_len);
|
||||||
// printf("%u %u %u\n", is.__m_RefCount, os.__m_RefCount, progress.__m_RefCount);
|
// printf("%u %u %u\n", is.__m_RefCount, os.__m_RefCount, progress.__m_RefCount);
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
// decompress
|
// decompress
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
@@ -425,60 +417,67 @@ error:
|
|||||||
#include <lzma-sdk/C/7zip/Compress/LZMA_C/LzmaDecode.h>
|
#include <lzma-sdk/C/7zip/Compress/LZMA_C/LzmaDecode.h>
|
||||||
#include <lzma-sdk/C/7zip/Compress/LZMA_C/LzmaDecode.c>
|
#include <lzma-sdk/C/7zip/Compress/LZMA_C/LzmaDecode.c>
|
||||||
|
|
||||||
int upx_lzma_decompress ( const upx_bytep src, unsigned src_len,
|
int upx_lzma_decompress(const upx_bytep src, unsigned src_len, upx_bytep dst, unsigned *dst_len,
|
||||||
upx_bytep dst, unsigned* dst_len,
|
int method, const upx_compress_result_t *cresult) {
|
||||||
int method,
|
|
||||||
const upx_compress_result_t *cresult )
|
|
||||||
{
|
|
||||||
assert(M_IS_LZMA(method));
|
assert(M_IS_LZMA(method));
|
||||||
// see res->num_probs above
|
// see res->num_probs above
|
||||||
COMPILE_TIME_ASSERT(sizeof(CProb) == 2)
|
COMPILE_TIME_ASSERT(sizeof(CProb) == 2)
|
||||||
COMPILE_TIME_ASSERT(LZMA_BASE_SIZE == 1846)
|
COMPILE_TIME_ASSERT(LZMA_BASE_SIZE == 1846)
|
||||||
COMPILE_TIME_ASSERT(LZMA_LIT_SIZE == 768)
|
COMPILE_TIME_ASSERT(LZMA_LIT_SIZE == 768)
|
||||||
|
|
||||||
CLzmaDecoderState s; memset(&s, 0, sizeof(s));
|
CLzmaDecoderState s;
|
||||||
|
memset(&s, 0, sizeof(s));
|
||||||
SizeT src_out = 0, dst_out = 0;
|
SizeT src_out = 0, dst_out = 0;
|
||||||
int r = UPX_E_ERROR;
|
int r = UPX_E_ERROR;
|
||||||
int rh;
|
int rh;
|
||||||
|
|
||||||
if (src_len < 3)
|
// decode UPX-style properties (2 bytes)
|
||||||
|
if (src_len < 3) {
|
||||||
|
r = UPX_E_INPUT_OVERRUN;
|
||||||
goto error;
|
goto error;
|
||||||
|
}
|
||||||
s.Properties.pb = src[0] & 7;
|
s.Properties.pb = src[0] & 7;
|
||||||
s.Properties.lp = (src[1] >> 4);
|
s.Properties.lp = (src[1] >> 4);
|
||||||
s.Properties.lc = src[1] & 15;
|
s.Properties.lc = src[1] & 15;
|
||||||
if (s.Properties.pb >= 5) goto error;
|
if (s.Properties.pb >= 5)
|
||||||
if (s.Properties.lp >= 5) goto error;
|
goto error;
|
||||||
if (s.Properties.lc >= 9) goto error;
|
if (s.Properties.lp >= 5)
|
||||||
// extra
|
goto error;
|
||||||
if ((src[0] >> 3) != s.Properties.lc + s.Properties.lp) goto error;
|
if (s.Properties.lc >= 9)
|
||||||
src += 2; src_len -= 2;
|
goto error;
|
||||||
|
// UPX extra stuff in first byte: 5 high bits convenience for stub decompressor
|
||||||
|
if ((src[0] >> 3) != s.Properties.lc + s.Properties.lp)
|
||||||
|
goto error;
|
||||||
|
src += 2;
|
||||||
|
src_len -= 2;
|
||||||
|
|
||||||
if (cresult)
|
if (cresult) {
|
||||||
{
|
assert(cresult->debug.method == method);
|
||||||
assert(cresult->method == method);
|
|
||||||
assert(cresult->result_lzma.pos_bits == (unsigned) s.Properties.pb);
|
assert(cresult->result_lzma.pos_bits == (unsigned) s.Properties.pb);
|
||||||
assert(cresult->result_lzma.lit_pos_bits == (unsigned) s.Properties.lp);
|
assert(cresult->result_lzma.lit_pos_bits == (unsigned) s.Properties.lp);
|
||||||
assert(cresult->result_lzma.lit_context_bits == (unsigned) s.Properties.lc);
|
assert(cresult->result_lzma.lit_context_bits == (unsigned) s.Properties.lc);
|
||||||
assert(cresult->result_lzma.num_probs == (unsigned) LzmaGetNumProbs(&s.Properties));
|
assert(cresult->result_lzma.num_probs == (unsigned) LzmaGetNumProbs(&s.Properties));
|
||||||
const lzma_compress_result_t *res = &cresult->result_lzma;
|
const lzma_compress_result_t *res = &cresult->result_lzma;
|
||||||
|
// printf("\nlzma_decompress config: %u %u %u %u %u\n", res->pos_bits, res->lit_pos_bits,
|
||||||
|
// res->lit_context_bits, res->dict_size, res->num_probs);
|
||||||
UNUSED(res);
|
UNUSED(res);
|
||||||
//printf("\nlzma_decompress config: %u %u %u %u %u\n", res->pos_bits, res->lit_pos_bits, res->lit_context_bits, res->dict_size, res->num_probs);
|
|
||||||
}
|
}
|
||||||
s.Probs = (CProb *) malloc(sizeof(CProb) * LzmaGetNumProbs(&s.Properties));
|
s.Probs = (CProb *) malloc(sizeof(CProb) * LzmaGetNumProbs(&s.Properties));
|
||||||
if (!s.Probs)
|
if (!s.Probs) {
|
||||||
{
|
|
||||||
r = UPX_E_OUT_OF_MEMORY;
|
r = UPX_E_OUT_OF_MEMORY;
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
rh = LzmaDecode(&s, src, src_len, &src_out, dst, *dst_len, &dst_out);
|
rh = LzmaDecode(&s, src, src_len, &src_out, dst, *dst_len, &dst_out);
|
||||||
assert(src_out <= src_len);
|
assert(src_out <= src_len);
|
||||||
assert(dst_out <= *dst_len);
|
assert(dst_out <= *dst_len);
|
||||||
if (rh == 0)
|
if (rh == 0) {
|
||||||
{
|
|
||||||
r = UPX_E_OK;
|
r = UPX_E_OK;
|
||||||
if (src_out != src_len)
|
if (src_out != src_len)
|
||||||
r = UPX_E_INPUT_NOT_CONSUMED;
|
r = UPX_E_INPUT_NOT_CONSUMED;
|
||||||
}
|
} else if (rh == LZMA_RESULT_INPUT_OVERRUN)
|
||||||
|
r = UPX_E_INPUT_OVERRUN;
|
||||||
|
else if (rh == LZMA_RESULT_OUTPUT_OVERRUN)
|
||||||
|
r = UPX_E_OUTPUT_OVERRUN;
|
||||||
|
|
||||||
error:
|
error:
|
||||||
*dst_len = dst_out;
|
*dst_len = dst_out;
|
||||||
@@ -486,24 +485,20 @@ error:
|
|||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
// test_overlap - see <ucl/ucl.h> for semantics
|
// test_overlap - see <ucl/ucl.h> for semantics
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
int upx_lzma_test_overlap ( const upx_bytep buf,
|
int upx_lzma_test_overlap(const upx_bytep buf, const upx_bytep tbuf, unsigned src_off,
|
||||||
const upx_bytep tbuf,
|
unsigned src_len, unsigned *dst_len, int method,
|
||||||
unsigned src_off, unsigned src_len,
|
const upx_compress_result_t *cresult) {
|
||||||
unsigned* dst_len,
|
|
||||||
int method,
|
|
||||||
const upx_compress_result_t *cresult )
|
|
||||||
{
|
|
||||||
assert(M_IS_LZMA(method));
|
assert(M_IS_LZMA(method));
|
||||||
|
|
||||||
MemBuffer b(src_off + src_len);
|
MemBuffer b(src_off + src_len);
|
||||||
memcpy(b + src_off, buf + src_off, src_len);
|
memcpy(b + src_off, buf + src_off, src_len);
|
||||||
unsigned saved_dst_len = *dst_len;
|
unsigned saved_dst_len = *dst_len;
|
||||||
int r = upx_lzma_decompress(b + src_off, src_len, b, dst_len, method, cresult);
|
int r = upx_lzma_decompress(raw_index_bytes(b, src_off, src_len), src_len,
|
||||||
|
raw_bytes(b, *dst_len), dst_len, method, cresult);
|
||||||
if (r != UPX_E_OK)
|
if (r != UPX_E_OK)
|
||||||
return r;
|
return r;
|
||||||
if (*dst_len != saved_dst_len)
|
if (*dst_len != saved_dst_len)
|
||||||
@@ -516,25 +511,34 @@ int upx_lzma_test_overlap ( const upx_bytep buf,
|
|||||||
return UPX_E_OK;
|
return UPX_E_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
// misc
|
// misc
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
int upx_lzma_init(void)
|
int upx_lzma_init(void) { return 0; }
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
const char *upx_lzma_version_string(void)
|
const char *upx_lzma_version_string(void) { return "4.43"; }
|
||||||
{
|
|
||||||
#if (WITH_LZMA == 0x443)
|
|
||||||
return "4.43";
|
|
||||||
#else
|
|
||||||
# error "unknown WITH_LZMA version"
|
|
||||||
return nullptr;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
// doctest checks
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
TEST_CASE("upx_lzma_decompress") {
|
||||||
|
typedef const upx_byte C;
|
||||||
|
C *c_data;
|
||||||
|
upx_byte d_buf[16];
|
||||||
|
unsigned d_len;
|
||||||
|
int r;
|
||||||
|
|
||||||
|
c_data = (C *) "\x1a\x03\x00\x7f\xed\x3c\x00\x00\x00";
|
||||||
|
d_len = 16;
|
||||||
|
r = upx_lzma_decompress(c_data, 9, d_buf, &d_len, M_LZMA, nullptr);
|
||||||
|
CHECK((r == 0 && d_len == 16));
|
||||||
|
r = upx_lzma_decompress(c_data, 8, d_buf, &d_len, M_LZMA, nullptr);
|
||||||
|
CHECK(r == UPX_E_INPUT_OVERRUN);
|
||||||
|
d_len = 15;
|
||||||
|
r = upx_lzma_decompress(c_data, 9, d_buf, &d_len, M_LZMA, nullptr);
|
||||||
|
CHECK(r == UPX_E_OUTPUT_OVERRUN);
|
||||||
|
}
|
||||||
|
|
||||||
/* vim:set ts=4 sw=4 et: */
|
/* vim:set ts=4 sw=4 et: */
|
||||||
@@ -0,0 +1,367 @@
|
|||||||
|
/* compress_ucl.cpp --
|
||||||
|
|
||||||
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
|
Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer
|
||||||
|
All Rights Reserved.
|
||||||
|
|
||||||
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
|
and/or modify them under the terms of the GNU General Public License as
|
||||||
|
published by the Free Software Foundation; either version 2 of
|
||||||
|
the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; see the file COPYING.
|
||||||
|
If not, write to the Free Software Foundation, Inc.,
|
||||||
|
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
|
Markus F.X.J. Oberhumer
|
||||||
|
<markus@oberhumer.com>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "../conf.h"
|
||||||
|
#include "compress.h"
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
//
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
static int convert_errno_from_ucl(int r) {
|
||||||
|
switch (r) {
|
||||||
|
case UCL_E_OK:
|
||||||
|
return UPX_E_OK;
|
||||||
|
case UCL_E_ERROR:
|
||||||
|
return UPX_E_ERROR;
|
||||||
|
case UCL_E_OUT_OF_MEMORY:
|
||||||
|
return UPX_E_OUT_OF_MEMORY;
|
||||||
|
case UCL_E_NOT_COMPRESSIBLE:
|
||||||
|
return UPX_E_NOT_COMPRESSIBLE;
|
||||||
|
case UCL_E_INPUT_OVERRUN:
|
||||||
|
return UPX_E_INPUT_OVERRUN;
|
||||||
|
case UCL_E_OUTPUT_OVERRUN:
|
||||||
|
return UPX_E_OUTPUT_OVERRUN;
|
||||||
|
case UCL_E_LOOKBEHIND_OVERRUN:
|
||||||
|
return UPX_E_LOOKBEHIND_OVERRUN;
|
||||||
|
case UCL_E_EOF_NOT_FOUND:
|
||||||
|
return UPX_E_EOF_NOT_FOUND;
|
||||||
|
case UCL_E_INPUT_NOT_CONSUMED:
|
||||||
|
return UPX_E_INPUT_NOT_CONSUMED;
|
||||||
|
case UCL_E_INVALID_ARGUMENT:
|
||||||
|
return UPX_E_INVALID_ARGUMENT;
|
||||||
|
// UCL extra:
|
||||||
|
case UCL_E_OVERLAP_OVERRUN:
|
||||||
|
return UPX_E_ERROR;
|
||||||
|
}
|
||||||
|
return UPX_E_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
static void __UCL_CDECL wrap_nprogress_ucl(ucl_uint a, ucl_uint b, int state, ucl_voidp user) {
|
||||||
|
if (state != -1 && state != 3)
|
||||||
|
return;
|
||||||
|
upx_callback_p cb = (upx_callback_p) user;
|
||||||
|
if (cb && cb->nprogress)
|
||||||
|
cb->nprogress(cb, a, b);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
//
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
int upx_ucl_compress(const upx_bytep src, unsigned src_len, upx_bytep dst, unsigned *dst_len,
|
||||||
|
upx_callback_p cb_parm, int method, int level,
|
||||||
|
const upx_compress_config_t *cconf_parm, upx_compress_result_t *cresult) {
|
||||||
|
int r;
|
||||||
|
assert(level > 0);
|
||||||
|
assert(cresult != nullptr);
|
||||||
|
|
||||||
|
COMPILE_TIME_ASSERT(sizeof(ucl_compress_config_t) == sizeof(REAL_ucl_compress_config_t))
|
||||||
|
|
||||||
|
ucl_progress_callback_t cb;
|
||||||
|
cb.callback = nullptr;
|
||||||
|
cb.user = nullptr;
|
||||||
|
if (cb_parm && cb_parm->nprogress) {
|
||||||
|
cb.callback = wrap_nprogress_ucl;
|
||||||
|
cb.user = cb_parm;
|
||||||
|
}
|
||||||
|
|
||||||
|
ucl_compress_config_t cconf;
|
||||||
|
cconf.reset();
|
||||||
|
if (cconf_parm) {
|
||||||
|
// cconf = cconf_parm->conf_ucl; // struct copy
|
||||||
|
memcpy(&cconf, &cconf_parm->conf_ucl, sizeof(cconf));
|
||||||
|
}
|
||||||
|
|
||||||
|
ucl_uint *const res = cresult->result_ucl.result;
|
||||||
|
// assume no info available - fill in worst case results
|
||||||
|
// res[0] = 1; // min_offset_found - NOT USED
|
||||||
|
res[1] = src_len - 1; // max_offset_found
|
||||||
|
// res[2] = 2; // min_match_found - NOT USED
|
||||||
|
res[3] = src_len - 1; // max_match_found
|
||||||
|
// res[4] = 1; // min_run_found - NOT USED
|
||||||
|
res[5] = src_len; // max_run_found
|
||||||
|
res[6] = 1; // first_offset_found
|
||||||
|
// res[7] = 999999; // same_match_offsets_found - NOT USED
|
||||||
|
|
||||||
|
// prepare bit-buffer settings
|
||||||
|
cconf.bb_endian = 0;
|
||||||
|
cconf.bb_size = 0;
|
||||||
|
if (method >= M_NRV2B_LE32 && method <= M_NRV2E_LE16) {
|
||||||
|
static const unsigned char sizes[3] = {32, 8, 16};
|
||||||
|
cconf.bb_size = sizes[(method - M_NRV2B_LE32) % 3];
|
||||||
|
} else {
|
||||||
|
throwInternalError("unknown compression method");
|
||||||
|
return UPX_E_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
// optimize compression parms
|
||||||
|
if (level <= 3 && cconf.max_offset == UCL_UINT_MAX)
|
||||||
|
cconf.max_offset = 8 * 1024 - 1;
|
||||||
|
else if (level == 4 && cconf.max_offset == UCL_UINT_MAX)
|
||||||
|
cconf.max_offset = 32 * 1024 - 1;
|
||||||
|
|
||||||
|
if M_IS_NRV2B (method)
|
||||||
|
r = ucl_nrv2b_99_compress(src, src_len, dst, dst_len, &cb, level, &cconf, res);
|
||||||
|
else if M_IS_NRV2D (method)
|
||||||
|
r = ucl_nrv2d_99_compress(src, src_len, dst, dst_len, &cb, level, &cconf, res);
|
||||||
|
else if M_IS_NRV2E (method)
|
||||||
|
r = ucl_nrv2e_99_compress(src, src_len, dst, dst_len, &cb, level, &cconf, res);
|
||||||
|
else {
|
||||||
|
throwInternalError("unknown compression method");
|
||||||
|
return UPX_E_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
// make sure first_offset_found is set
|
||||||
|
if (res[6] == 0)
|
||||||
|
res[6] = 1;
|
||||||
|
|
||||||
|
return convert_errno_from_ucl(r);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
//
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
int upx_ucl_decompress(const upx_bytep src, unsigned src_len, upx_bytep dst, unsigned *dst_len,
|
||||||
|
int method, const upx_compress_result_t *cresult) {
|
||||||
|
int r;
|
||||||
|
|
||||||
|
switch (method) {
|
||||||
|
case M_NRV2B_8:
|
||||||
|
r = ucl_nrv2b_decompress_safe_8(src, src_len, dst, dst_len, nullptr);
|
||||||
|
break;
|
||||||
|
case M_NRV2B_LE16:
|
||||||
|
r = ucl_nrv2b_decompress_safe_le16(src, src_len, dst, dst_len, nullptr);
|
||||||
|
break;
|
||||||
|
case M_NRV2B_LE32:
|
||||||
|
r = ucl_nrv2b_decompress_safe_le32(src, src_len, dst, dst_len, nullptr);
|
||||||
|
break;
|
||||||
|
case M_NRV2D_8:
|
||||||
|
r = ucl_nrv2d_decompress_safe_8(src, src_len, dst, dst_len, nullptr);
|
||||||
|
break;
|
||||||
|
case M_NRV2D_LE16:
|
||||||
|
r = ucl_nrv2d_decompress_safe_le16(src, src_len, dst, dst_len, nullptr);
|
||||||
|
break;
|
||||||
|
case M_NRV2D_LE32:
|
||||||
|
r = ucl_nrv2d_decompress_safe_le32(src, src_len, dst, dst_len, nullptr);
|
||||||
|
break;
|
||||||
|
case M_NRV2E_8:
|
||||||
|
r = ucl_nrv2e_decompress_safe_8(src, src_len, dst, dst_len, nullptr);
|
||||||
|
break;
|
||||||
|
case M_NRV2E_LE16:
|
||||||
|
r = ucl_nrv2e_decompress_safe_le16(src, src_len, dst, dst_len, nullptr);
|
||||||
|
break;
|
||||||
|
case M_NRV2E_LE32:
|
||||||
|
r = ucl_nrv2e_decompress_safe_le32(src, src_len, dst, dst_len, nullptr);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throwInternalError("unknown decompression method");
|
||||||
|
return UPX_E_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
UNUSED(cresult);
|
||||||
|
return convert_errno_from_ucl(r);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
//
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
int upx_ucl_test_overlap(const upx_bytep buf, const upx_bytep tbuf, unsigned src_off,
|
||||||
|
unsigned src_len, unsigned *dst_len, int method,
|
||||||
|
const upx_compress_result_t *cresult) {
|
||||||
|
int r;
|
||||||
|
UNUSED(tbuf); // not needed for UCL
|
||||||
|
|
||||||
|
switch (method) {
|
||||||
|
case M_NRV2B_8:
|
||||||
|
r = ucl_nrv2b_test_overlap_8(buf, src_off, src_len, dst_len, nullptr);
|
||||||
|
break;
|
||||||
|
case M_NRV2B_LE16:
|
||||||
|
r = ucl_nrv2b_test_overlap_le16(buf, src_off, src_len, dst_len, nullptr);
|
||||||
|
break;
|
||||||
|
case M_NRV2B_LE32:
|
||||||
|
r = ucl_nrv2b_test_overlap_le32(buf, src_off, src_len, dst_len, nullptr);
|
||||||
|
break;
|
||||||
|
case M_NRV2D_8:
|
||||||
|
r = ucl_nrv2d_test_overlap_8(buf, src_off, src_len, dst_len, nullptr);
|
||||||
|
break;
|
||||||
|
case M_NRV2D_LE16:
|
||||||
|
r = ucl_nrv2d_test_overlap_le16(buf, src_off, src_len, dst_len, nullptr);
|
||||||
|
break;
|
||||||
|
case M_NRV2D_LE32:
|
||||||
|
r = ucl_nrv2d_test_overlap_le32(buf, src_off, src_len, dst_len, nullptr);
|
||||||
|
break;
|
||||||
|
case M_NRV2E_8:
|
||||||
|
r = ucl_nrv2e_test_overlap_8(buf, src_off, src_len, dst_len, nullptr);
|
||||||
|
break;
|
||||||
|
case M_NRV2E_LE16:
|
||||||
|
r = ucl_nrv2e_test_overlap_le16(buf, src_off, src_len, dst_len, nullptr);
|
||||||
|
break;
|
||||||
|
case M_NRV2E_LE32:
|
||||||
|
r = ucl_nrv2e_test_overlap_le32(buf, src_off, src_len, dst_len, nullptr);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throwInternalError("unknown decompression method");
|
||||||
|
return UPX_E_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
UNUSED(cresult);
|
||||||
|
return convert_errno_from_ucl(r);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
// misc
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
static ucl_voidp __UCL_CDECL my_malloc(ucl_uint n) { return calloc(1, n); }
|
||||||
|
static void __UCL_CDECL my_free(ucl_voidp p) { free(p); }
|
||||||
|
}
|
||||||
|
|
||||||
|
int upx_ucl_init(void) {
|
||||||
|
if (ucl_init() != UCL_E_OK)
|
||||||
|
return -1;
|
||||||
|
if (UCL_VERSION != ucl_version() || strcmp(UCL_VERSION_STRING, ucl_version_string()) != 0)
|
||||||
|
return -2;
|
||||||
|
ucl_set_malloc_hooks(my_malloc, my_free);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *upx_ucl_version_string(void) { return ucl_version_string(); }
|
||||||
|
|
||||||
|
unsigned upx_ucl_adler32(const void *buf, unsigned len, unsigned adler) {
|
||||||
|
return ucl_adler32(adler, (const ucl_bytep) buf, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
#if 0 // UNUSED
|
||||||
|
unsigned upx_ucl_crc32(const void *buf, unsigned len, unsigned crc) {
|
||||||
|
return ucl_crc32(crc, (const ucl_bytep) buf, len);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
// doctest checks
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
#if DEBUG && !defined(DOCTEST_CONFIG_DISABLE) && 1
|
||||||
|
|
||||||
|
#include "../util/membuffer.h"
|
||||||
|
|
||||||
|
static bool check_ucl(const int method, const unsigned expected_c_len) {
|
||||||
|
const unsigned u_len = 16384;
|
||||||
|
const unsigned c_extra = 4096;
|
||||||
|
MemBuffer u_buf, c_buf, d_buf;
|
||||||
|
unsigned c_len, d_len;
|
||||||
|
upx_compress_result_t cresult;
|
||||||
|
int r;
|
||||||
|
const int level = 3; // don't waste time
|
||||||
|
|
||||||
|
u_buf.alloc(u_len);
|
||||||
|
memset(u_buf, 0, u_len);
|
||||||
|
c_buf.allocForCompression(u_len, c_extra);
|
||||||
|
d_buf.allocForDecompression(u_len);
|
||||||
|
|
||||||
|
c_len = c_buf.getSize() - c_extra;
|
||||||
|
r = upx_ucl_compress(raw_bytes(u_buf, u_len), u_len, raw_index_bytes(c_buf, c_extra, c_len),
|
||||||
|
&c_len, nullptr, method, level, NULL_cconf, &cresult);
|
||||||
|
if (r != 0 || c_len != expected_c_len)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
d_len = d_buf.getSize();
|
||||||
|
r = upx_ucl_decompress(raw_index_bytes(c_buf, c_extra, c_len), c_len, raw_bytes(d_buf, d_len),
|
||||||
|
&d_len, method, nullptr);
|
||||||
|
if (r != 0 || d_len != u_len || memcmp(u_buf, d_buf, u_len) != 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
d_len = u_len - 1;
|
||||||
|
r = upx_ucl_decompress(raw_index_bytes(c_buf, c_extra, c_len), c_len, raw_bytes(d_buf, d_len),
|
||||||
|
&d_len, method, nullptr);
|
||||||
|
if (r == 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// TODO: rewrite Packer::findOverlapOverhead() so that we can test it here
|
||||||
|
// unsigned x_len = d_len;
|
||||||
|
// r = upx_ucl_test_overlap(c_buf, u_buf, c_extra, c_len, &x_len, method, nullptr);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("compress_ucl") {
|
||||||
|
CHECK(check_ucl(M_NRV2B_8, 34));
|
||||||
|
CHECK(check_ucl(M_NRV2B_LE16, 34));
|
||||||
|
CHECK(check_ucl(M_NRV2B_LE32, 34));
|
||||||
|
CHECK(check_ucl(M_NRV2D_8, 32));
|
||||||
|
CHECK(check_ucl(M_NRV2D_LE16, 32));
|
||||||
|
CHECK(check_ucl(M_NRV2D_LE32, 34));
|
||||||
|
CHECK(check_ucl(M_NRV2E_8, 32));
|
||||||
|
CHECK(check_ucl(M_NRV2E_LE16, 32));
|
||||||
|
CHECK(check_ucl(M_NRV2E_LE32, 34));
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // DEBUG
|
||||||
|
|
||||||
|
TEST_CASE("upx_ucl_decompress") {
|
||||||
|
typedef const upx_byte C;
|
||||||
|
C *c_data;
|
||||||
|
upx_byte d_buf[16];
|
||||||
|
unsigned d_len;
|
||||||
|
int r;
|
||||||
|
|
||||||
|
c_data = (C *) "\x92\xff\x10\x00\x00\x00\x00\x00\x48\xff";
|
||||||
|
d_len = 16;
|
||||||
|
r = upx_ucl_decompress(c_data, 10, d_buf, &d_len, M_NRV2B_8, nullptr);
|
||||||
|
CHECK((r == 0 && d_len == 16));
|
||||||
|
r = upx_ucl_decompress(c_data, 9, d_buf, &d_len, M_NRV2B_8, nullptr);
|
||||||
|
CHECK(r == UPX_E_INPUT_OVERRUN);
|
||||||
|
d_len = 15;
|
||||||
|
r = upx_ucl_decompress(c_data, 10, d_buf, &d_len, M_NRV2B_8, nullptr);
|
||||||
|
CHECK(r == UPX_E_OUTPUT_OVERRUN);
|
||||||
|
|
||||||
|
c_data = (C *) "\x92\xff\x10\x92\x49\x24\x92\xa0\xff";
|
||||||
|
d_len = 16;
|
||||||
|
r = upx_ucl_decompress(c_data, 9, d_buf, &d_len, M_NRV2D_8, nullptr);
|
||||||
|
CHECK((r == 0 && d_len == 16));
|
||||||
|
r = upx_ucl_decompress(c_data, 8, d_buf, &d_len, M_NRV2D_8, nullptr);
|
||||||
|
CHECK(r == UPX_E_INPUT_OVERRUN);
|
||||||
|
d_len = 15;
|
||||||
|
r = upx_ucl_decompress(c_data, 9, d_buf, &d_len, M_NRV2D_8, nullptr);
|
||||||
|
CHECK(r == UPX_E_OUTPUT_OVERRUN);
|
||||||
|
|
||||||
|
c_data = (C *) "\x90\xff\xb0\x92\x49\x24\x92\xa0\xff";
|
||||||
|
d_len = 16;
|
||||||
|
r = upx_ucl_decompress(c_data, 9, d_buf, &d_len, M_NRV2E_8, nullptr);
|
||||||
|
CHECK((r == 0 && d_len == 16));
|
||||||
|
r = upx_ucl_decompress(c_data, 8, d_buf, &d_len, M_NRV2E_8, nullptr);
|
||||||
|
CHECK(r == UPX_E_INPUT_OVERRUN);
|
||||||
|
d_len = 15;
|
||||||
|
r = upx_ucl_decompress(c_data, 9, d_buf, &d_len, M_NRV2E_8, nullptr);
|
||||||
|
CHECK(r == UPX_E_OUTPUT_OVERRUN);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* vim:set ts=4 sw=4 et: */
|
||||||
@@ -2,8 +2,7 @@
|
|||||||
|
|
||||||
This file is part of the UPX executable compressor.
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
Copyright (C) 1996-2022 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2022 Laszlo Molnar
|
|
||||||
All Rights Reserved.
|
All Rights Reserved.
|
||||||
|
|
||||||
UPX and the UCL library are free software; you can redistribute them
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
@@ -21,20 +20,17 @@
|
|||||||
If not, write to the Free Software Foundation, Inc.,
|
If not, write to the Free Software Foundation, Inc.,
|
||||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
Markus F.X.J. Oberhumer Laszlo Molnar
|
Markus F.X.J. Oberhumer
|
||||||
<markus@oberhumer.com> <ezerotven+github@gmail.com>
|
<markus@oberhumer.com>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include "../conf.h"
|
||||||
#include "conf.h"
|
|
||||||
#include "compress.h"
|
#include "compress.h"
|
||||||
#include "util/membuffer.h"
|
#include "../util/membuffer.h"
|
||||||
#include <zlib/zlib.h>
|
#include <zlib/zlib.h>
|
||||||
#include <zlib/deflate.h>
|
#include <zlib/deflate.h>
|
||||||
|
|
||||||
|
void zlib_compress_config_t::reset() {
|
||||||
void zlib_compress_config_t::reset()
|
|
||||||
{
|
|
||||||
mem_clear(this, sizeof(*this));
|
mem_clear(this, sizeof(*this));
|
||||||
|
|
||||||
mem_level.reset();
|
mem_level.reset();
|
||||||
@@ -42,37 +38,49 @@ void zlib_compress_config_t::reset()
|
|||||||
strategy.reset();
|
strategy.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int convert_errno_from_zlib(int zr) {
|
||||||
static int convert_errno_from_zlib(int zr)
|
switch (zr) {
|
||||||
{
|
case Z_OK:
|
||||||
switch (zr)
|
return UPX_E_OK;
|
||||||
{
|
// positive values
|
||||||
case Z_OK: return UPX_E_OK;
|
case Z_STREAM_END:
|
||||||
case Z_DATA_ERROR: return UPX_E_ERROR;
|
return UPX_E_ERROR;
|
||||||
case Z_NEED_DICT: return UPX_E_ERROR;
|
case Z_NEED_DICT:
|
||||||
|
return UPX_E_ERROR;
|
||||||
|
// negative values
|
||||||
|
case Z_ERRNO:
|
||||||
|
return UPX_E_ERROR;
|
||||||
|
case Z_STREAM_ERROR:
|
||||||
|
return UPX_E_ERROR;
|
||||||
|
case Z_DATA_ERROR:
|
||||||
|
return UPX_E_ERROR;
|
||||||
|
case Z_MEM_ERROR:
|
||||||
|
return UPX_E_OUT_OF_MEMORY;
|
||||||
|
case Z_BUF_ERROR:
|
||||||
|
return UPX_E_OUTPUT_OVERRUN;
|
||||||
|
case Z_VERSION_ERROR:
|
||||||
|
return UPX_E_ERROR;
|
||||||
|
case -7: // UPX extra
|
||||||
|
return UPX_E_INPUT_OVERRUN;
|
||||||
}
|
}
|
||||||
return UPX_E_ERROR;
|
return UPX_E_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
//
|
//
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
int upx_zlib_compress ( const upx_bytep src, unsigned src_len,
|
int upx_zlib_compress(const upx_bytep src, unsigned src_len, upx_bytep dst, unsigned *dst_len,
|
||||||
upx_bytep dst, unsigned* dst_len,
|
upx_callback_p cb_parm, int method, int level,
|
||||||
upx_callback_p cb_parm,
|
const upx_compress_config_t *cconf_parm, upx_compress_result_t *cresult) {
|
||||||
int method, int level,
|
|
||||||
const upx_compress_config_t *cconf_parm,
|
|
||||||
upx_compress_result_t *cresult )
|
|
||||||
{
|
|
||||||
assert(method == M_DEFLATE);
|
assert(method == M_DEFLATE);
|
||||||
assert(level > 0); assert(cresult != nullptr);
|
assert(level > 0);
|
||||||
|
assert(cresult != nullptr);
|
||||||
UNUSED(cb_parm);
|
UNUSED(cb_parm);
|
||||||
int r = UPX_E_ERROR;
|
int r = UPX_E_ERROR;
|
||||||
int zr;
|
int zr;
|
||||||
const zlib_compress_config_t *lcconf = cconf_parm ? &cconf_parm->conf_zlib : nullptr;
|
const zlib_compress_config_t *const lcconf = cconf_parm ? &cconf_parm->conf_zlib : nullptr;
|
||||||
zlib_compress_result_t *res = &cresult->result_zlib;
|
zlib_compress_result_t *const res = &cresult->result_zlib;
|
||||||
|
|
||||||
if (level == 10)
|
if (level == 10)
|
||||||
level = 9;
|
level = 9;
|
||||||
@@ -81,8 +89,7 @@ int upx_zlib_compress ( const upx_bytep src, unsigned src_len,
|
|||||||
zlib_compress_config_t::window_bits_t window_bits;
|
zlib_compress_config_t::window_bits_t window_bits;
|
||||||
zlib_compress_config_t::strategy_t strategy;
|
zlib_compress_config_t::strategy_t strategy;
|
||||||
// cconf overrides
|
// cconf overrides
|
||||||
if (lcconf)
|
if (lcconf) {
|
||||||
{
|
|
||||||
oassign(mem_level, lcconf->mem_level);
|
oassign(mem_level, lcconf->mem_level);
|
||||||
oassign(window_bits, lcconf->window_bits);
|
oassign(window_bits, lcconf->window_bits);
|
||||||
oassign(strategy, lcconf->strategy);
|
oassign(strategy, lcconf->strategy);
|
||||||
@@ -99,8 +106,7 @@ int upx_zlib_compress ( const upx_bytep src, unsigned src_len,
|
|||||||
s.avail_out = *dst_len;
|
s.avail_out = *dst_len;
|
||||||
s.total_in = s.total_out = 0;
|
s.total_in = s.total_out = 0;
|
||||||
|
|
||||||
zr = (int)deflateInit2(&s, level, Z_DEFLATED, 0 - (int)window_bits,
|
zr = (int) deflateInit2(&s, level, Z_DEFLATED, 0 - (int) window_bits, mem_level, strategy);
|
||||||
mem_level, strategy);
|
|
||||||
if (zr != Z_OK)
|
if (zr != Z_OK)
|
||||||
goto error;
|
goto error;
|
||||||
assert(s.state->level == level);
|
assert(s.state->level == level);
|
||||||
@@ -118,8 +124,7 @@ error:
|
|||||||
if (r == UPX_E_OK)
|
if (r == UPX_E_OK)
|
||||||
r = UPX_E_ERROR;
|
r = UPX_E_ERROR;
|
||||||
done:
|
done:
|
||||||
if (r == UPX_E_OK)
|
if (r == UPX_E_OK) {
|
||||||
{
|
|
||||||
if (s.avail_in != 0 || s.total_in != src_len)
|
if (s.avail_in != 0 || s.total_in != src_len)
|
||||||
r = UPX_E_ERROR;
|
r = UPX_E_ERROR;
|
||||||
}
|
}
|
||||||
@@ -129,16 +134,12 @@ done:
|
|||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
//
|
//
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
int upx_zlib_decompress ( const upx_bytep src, unsigned src_len,
|
int upx_zlib_decompress(const upx_bytep src, unsigned src_len, upx_bytep dst, unsigned *dst_len,
|
||||||
upx_bytep dst, unsigned* dst_len,
|
int method, const upx_compress_result_t *cresult) {
|
||||||
int method,
|
|
||||||
const upx_compress_result_t *cresult )
|
|
||||||
{
|
|
||||||
assert(method == M_DEFLATE);
|
assert(method == M_DEFLATE);
|
||||||
UNUSED(method);
|
UNUSED(method);
|
||||||
UNUSED(cresult);
|
UNUSED(cresult);
|
||||||
@@ -158,8 +159,11 @@ int upx_zlib_decompress ( const upx_bytep src, unsigned src_len,
|
|||||||
if (zr != Z_OK)
|
if (zr != Z_OK)
|
||||||
goto error;
|
goto error;
|
||||||
zr = inflate(&s, Z_FINISH);
|
zr = inflate(&s, Z_FINISH);
|
||||||
if (zr != Z_STREAM_END)
|
if (zr != Z_STREAM_END) {
|
||||||
|
if (zr == Z_BUF_ERROR && s.avail_in == 0)
|
||||||
|
zr = -7; // UPX extra
|
||||||
goto error;
|
goto error;
|
||||||
|
}
|
||||||
zr = inflateEnd(&s);
|
zr = inflateEnd(&s);
|
||||||
if (zr != Z_OK)
|
if (zr != Z_OK)
|
||||||
goto error;
|
goto error;
|
||||||
@@ -171,8 +175,7 @@ error:
|
|||||||
if (r == UPX_E_OK)
|
if (r == UPX_E_OK)
|
||||||
r = UPX_E_ERROR;
|
r = UPX_E_ERROR;
|
||||||
done:
|
done:
|
||||||
if (r == UPX_E_OK)
|
if (r == UPX_E_OK) {
|
||||||
{
|
|
||||||
if (s.avail_in != 0 || s.total_in != src_len)
|
if (s.avail_in != 0 || s.total_in != src_len)
|
||||||
r = UPX_E_INPUT_NOT_CONSUMED;
|
r = UPX_E_INPUT_NOT_CONSUMED;
|
||||||
}
|
}
|
||||||
@@ -182,24 +185,20 @@ done:
|
|||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
// test_overlap - see <ucl/ucl.h> for semantics
|
// test_overlap - see <ucl/ucl.h> for semantics
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
int upx_zlib_test_overlap ( const upx_bytep buf,
|
int upx_zlib_test_overlap(const upx_bytep buf, const upx_bytep tbuf, unsigned src_off,
|
||||||
const upx_bytep tbuf,
|
unsigned src_len, unsigned *dst_len, int method,
|
||||||
unsigned src_off, unsigned src_len,
|
const upx_compress_result_t *cresult) {
|
||||||
unsigned* dst_len,
|
|
||||||
int method,
|
|
||||||
const upx_compress_result_t *cresult )
|
|
||||||
{
|
|
||||||
assert(method == M_DEFLATE);
|
assert(method == M_DEFLATE);
|
||||||
|
|
||||||
MemBuffer b(src_off + src_len);
|
MemBuffer b(src_off + src_len);
|
||||||
memcpy(b + src_off, buf + src_off, src_len);
|
memcpy(b + src_off, buf + src_off, src_len);
|
||||||
unsigned saved_dst_len = *dst_len;
|
unsigned saved_dst_len = *dst_len;
|
||||||
int r = upx_zlib_decompress(b + src_off, src_len, b, dst_len, method, cresult);
|
int r = upx_zlib_decompress(raw_index_bytes(b, src_off, src_len), src_len,
|
||||||
|
raw_bytes(b, *dst_len), dst_len, method, cresult);
|
||||||
if (r != UPX_E_OK)
|
if (r != UPX_E_OK)
|
||||||
return r;
|
return r;
|
||||||
if (*dst_len != saved_dst_len)
|
if (*dst_len != saved_dst_len)
|
||||||
@@ -212,44 +211,35 @@ int upx_zlib_test_overlap ( const upx_bytep buf,
|
|||||||
return UPX_E_OK;
|
return UPX_E_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
// misc
|
// misc
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
int upx_zlib_init(void)
|
int upx_zlib_init(void) {
|
||||||
{
|
|
||||||
if (strcmp(ZLIB_VERSION, zlibVersion()) != 0)
|
if (strcmp(ZLIB_VERSION, zlibVersion()) != 0)
|
||||||
return -2;
|
return -2;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *upx_zlib_version_string(void)
|
const char *upx_zlib_version_string(void) { return zlibVersion(); }
|
||||||
{
|
|
||||||
return zlibVersion();
|
|
||||||
}
|
|
||||||
|
|
||||||
#if 0 /* UNUSED */
|
#if 0 // UNUSED
|
||||||
unsigned upx_zlib_adler32(const void *buf, unsigned len, unsigned adler)
|
unsigned upx_zlib_adler32(const void *buf, unsigned len, unsigned adler) {
|
||||||
{
|
|
||||||
return adler32(adler, (const Bytef *) buf, len);
|
return adler32(adler, (const Bytef *) buf, len);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if 0 /* UNUSED */
|
#if 0 // UNUSED
|
||||||
unsigned upx_zlib_crc32(const void *buf, unsigned len, unsigned crc)
|
unsigned upx_zlib_crc32(const void *buf, unsigned len, unsigned crc) {
|
||||||
{
|
|
||||||
return crc32(crc, (const Bytef *) buf, len);
|
return crc32(crc, (const Bytef *) buf, len);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
// Debug checks
|
// doctest checks
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
#if DEBUG && 1
|
#if DEBUG && !defined(DOCTEST_CONFIG_DISABLE) && 1
|
||||||
|
|
||||||
#include "util/membuffer.h"
|
|
||||||
|
|
||||||
static bool check_zlib(const int method, const int level, const unsigned expected_c_len) {
|
static bool check_zlib(const int method, const int level, const unsigned expected_c_len) {
|
||||||
const unsigned u_len = 16384;
|
const unsigned u_len = 16384;
|
||||||
@@ -265,17 +255,22 @@ static bool check_zlib(const int method, const int level, const unsigned expecte
|
|||||||
d_buf.allocForDecompression(u_len);
|
d_buf.allocForDecompression(u_len);
|
||||||
|
|
||||||
c_len = c_buf.getSize() - c_extra;
|
c_len = c_buf.getSize() - c_extra;
|
||||||
r = upx_zlib_compress(u_buf, u_len, c_buf + c_extra, &c_len, nullptr, method, level, NULL_cconf, &cresult);
|
r = upx_zlib_compress(raw_bytes(u_buf, u_len), u_len, raw_index_bytes(c_buf, c_extra, c_len),
|
||||||
if (r != 0 || c_len != expected_c_len) return false;
|
&c_len, nullptr, method, level, NULL_cconf, &cresult);
|
||||||
|
if (r != 0 || c_len != expected_c_len)
|
||||||
|
return false;
|
||||||
|
|
||||||
d_len = d_buf.getSize();
|
d_len = d_buf.getSize();
|
||||||
r = upx_zlib_decompress(c_buf + c_extra, c_len, d_buf, &d_len, method, nullptr);
|
r = upx_zlib_decompress(raw_index_bytes(c_buf, c_extra, c_len), c_len, raw_bytes(d_buf, d_len),
|
||||||
if (r != 0 || d_len != u_len) return false;
|
&d_len, method, nullptr);
|
||||||
if (memcmp(u_buf, d_buf, u_len) != 0) return false;
|
if (r != 0 || d_len != u_len || memcmp(u_buf, d_buf, u_len) != 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
d_len = u_len - 1;
|
d_len = u_len - 1;
|
||||||
r = upx_zlib_decompress(c_buf + c_extra, c_len, d_buf, &d_len, method, nullptr);
|
r = upx_zlib_decompress(raw_index_bytes(c_buf, c_extra, c_len), c_len, raw_bytes(d_buf, d_len),
|
||||||
if (r == 0) return false;
|
&d_len, method, nullptr);
|
||||||
|
if (r == 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
// TODO: rewrite Packer::findOverlapOverhead() so that we can test it here
|
// TODO: rewrite Packer::findOverlapOverhead() so that we can test it here
|
||||||
// unsigned x_len = d_len;
|
// unsigned x_len = d_len;
|
||||||
@@ -291,5 +286,22 @@ TEST_CASE("compress_zlib") {
|
|||||||
|
|
||||||
#endif // DEBUG
|
#endif // DEBUG
|
||||||
|
|
||||||
|
TEST_CASE("upx_zlib_decompress") {
|
||||||
|
typedef const upx_byte C;
|
||||||
|
C *c_data;
|
||||||
|
upx_byte d_buf[16];
|
||||||
|
unsigned d_len;
|
||||||
|
int r;
|
||||||
|
|
||||||
|
c_data = (C *) "\xfb\xff\x1f\x15\x00\x00";
|
||||||
|
d_len = 16;
|
||||||
|
r = upx_zlib_decompress(c_data, 6, d_buf, &d_len, M_DEFLATE, nullptr);
|
||||||
|
CHECK((r == 0 && d_len == 16));
|
||||||
|
r = upx_zlib_decompress(c_data, 5, d_buf, &d_len, M_DEFLATE, nullptr);
|
||||||
|
CHECK(r == UPX_E_INPUT_OVERRUN);
|
||||||
|
d_len = 15;
|
||||||
|
r = upx_zlib_decompress(c_data, 6, d_buf, &d_len, M_DEFLATE, nullptr);
|
||||||
|
CHECK(r == UPX_E_OUTPUT_OVERRUN);
|
||||||
|
}
|
||||||
|
|
||||||
/* vim:set ts=4 sw=4 et: */
|
/* vim:set ts=4 sw=4 et: */
|
||||||
@@ -0,0 +1,229 @@
|
|||||||
|
/* compress_zstd.cpp --
|
||||||
|
|
||||||
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
|
Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer
|
||||||
|
All Rights Reserved.
|
||||||
|
|
||||||
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
|
and/or modify them under the terms of the GNU General Public License as
|
||||||
|
published by the Free Software Foundation; either version 2 of
|
||||||
|
the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; see the file COPYING.
|
||||||
|
If not, write to the Free Software Foundation, Inc.,
|
||||||
|
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
|
Markus F.X.J. Oberhumer
|
||||||
|
<markus@oberhumer.com>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "../conf.h"
|
||||||
|
|
||||||
|
void zstd_compress_config_t::reset() { mem_clear(this, sizeof(*this)); }
|
||||||
|
|
||||||
|
#if WITH_ZSTD
|
||||||
|
#include "compress.h"
|
||||||
|
#include "../util/membuffer.h"
|
||||||
|
#include <zstd/lib/zstd.h>
|
||||||
|
#include <zstd/lib/zstd_errors.h>
|
||||||
|
#include <zstd/lib/compress/hist.h>
|
||||||
|
|
||||||
|
static int convert_errno_from_zstd(size_t zr) {
|
||||||
|
const ZSTD_ErrorCode ze = ZSTD_getErrorCode(zr);
|
||||||
|
switch (ze) {
|
||||||
|
case ZSTD_error_memory_allocation:
|
||||||
|
return UPX_E_OUT_OF_MEMORY;
|
||||||
|
case ZSTD_error_srcSize_wrong:
|
||||||
|
return UPX_E_INPUT_OVERRUN;
|
||||||
|
case ZSTD_error_dstSize_tooSmall:
|
||||||
|
return UPX_E_OUTPUT_OVERRUN;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return UPX_E_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
// TODO later: use advanced compression API for compression finetuning
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
int upx_zstd_compress(const upx_bytep src, unsigned src_len, upx_bytep dst, unsigned *dst_len,
|
||||||
|
upx_callback_p cb_parm, int method, int level,
|
||||||
|
const upx_compress_config_t *cconf_parm, upx_compress_result_t *cresult) {
|
||||||
|
assert(method == M_ZSTD);
|
||||||
|
assert(level > 0);
|
||||||
|
assert(cresult != nullptr);
|
||||||
|
UNUSED(cb_parm);
|
||||||
|
int r = UPX_E_ERROR;
|
||||||
|
size_t zr;
|
||||||
|
const zstd_compress_config_t *const lcconf = cconf_parm ? &cconf_parm->conf_zstd : nullptr;
|
||||||
|
zstd_compress_result_t *const res = &cresult->result_zstd;
|
||||||
|
|
||||||
|
// TODO later: map level 1..10 to zstd-level 1..22
|
||||||
|
if (level == 10)
|
||||||
|
level = 22;
|
||||||
|
|
||||||
|
// cconf overrides
|
||||||
|
if (lcconf) {
|
||||||
|
UNUSED(lcconf);
|
||||||
|
}
|
||||||
|
|
||||||
|
res->dummy = 0;
|
||||||
|
|
||||||
|
zr = ZSTD_compress(dst, *dst_len, src, src_len, level);
|
||||||
|
if (ZSTD_isError(zr)) {
|
||||||
|
*dst_len = 0; // TODO ???
|
||||||
|
r = convert_errno_from_zstd(zr);
|
||||||
|
assert(r != UPX_E_OK);
|
||||||
|
} else {
|
||||||
|
assert(zr <= *dst_len);
|
||||||
|
*dst_len = (unsigned) zr;
|
||||||
|
r = UPX_E_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
//
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
int upx_zstd_decompress(const upx_bytep src, unsigned src_len, upx_bytep dst, unsigned *dst_len,
|
||||||
|
int method, const upx_compress_result_t *cresult) {
|
||||||
|
assert(method == M_ZSTD);
|
||||||
|
UNUSED(method);
|
||||||
|
UNUSED(cresult);
|
||||||
|
int r = UPX_E_ERROR;
|
||||||
|
size_t zr;
|
||||||
|
|
||||||
|
zr = ZSTD_decompress(dst, *dst_len, src, src_len);
|
||||||
|
if (ZSTD_isError(zr)) {
|
||||||
|
*dst_len = 0; // TODO ???
|
||||||
|
r = convert_errno_from_zstd(zr);
|
||||||
|
assert(r != UPX_E_OK);
|
||||||
|
} else {
|
||||||
|
assert(zr <= *dst_len);
|
||||||
|
*dst_len = (unsigned) zr;
|
||||||
|
r = UPX_E_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
// test_overlap - see <ucl/ucl.h> for semantics
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
int upx_zstd_test_overlap(const upx_bytep buf, const upx_bytep tbuf, unsigned src_off,
|
||||||
|
unsigned src_len, unsigned *dst_len, int method,
|
||||||
|
const upx_compress_result_t *cresult) {
|
||||||
|
assert(method == M_ZSTD);
|
||||||
|
|
||||||
|
MemBuffer b(src_off + src_len);
|
||||||
|
memcpy(b + src_off, buf + src_off, src_len);
|
||||||
|
unsigned saved_dst_len = *dst_len;
|
||||||
|
int r = upx_zstd_decompress(raw_index_bytes(b, src_off, src_len), src_len,
|
||||||
|
raw_bytes(b, *dst_len), dst_len, method, cresult);
|
||||||
|
if (r != UPX_E_OK)
|
||||||
|
return r;
|
||||||
|
if (*dst_len != saved_dst_len)
|
||||||
|
return UPX_E_ERROR;
|
||||||
|
// NOTE: there is a very tiny possibility that decompression has
|
||||||
|
// succeeded but the data is not restored correctly because of
|
||||||
|
// in-place buffer overlapping, so we use an extra memcmp().
|
||||||
|
if (tbuf != nullptr && memcmp(tbuf, b, *dst_len) != 0)
|
||||||
|
return UPX_E_ERROR;
|
||||||
|
return UPX_E_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
// misc
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
int upx_zstd_init(void) {
|
||||||
|
if (strcmp(ZSTD_VERSION_STRING, ZSTD_versionString()) != 0)
|
||||||
|
return -2;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *upx_zstd_version_string(void) { return ZSTD_VERSION_STRING; }
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
// doctest checks
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
#if DEBUG && !defined(DOCTEST_CONFIG_DISABLE) && 1
|
||||||
|
|
||||||
|
static bool check_zstd(const int method, const int level, const unsigned expected_c_len) {
|
||||||
|
const unsigned u_len = 16384;
|
||||||
|
const unsigned c_extra = 4096;
|
||||||
|
MemBuffer u_buf, c_buf, d_buf;
|
||||||
|
unsigned c_len, d_len;
|
||||||
|
upx_compress_result_t cresult;
|
||||||
|
int r;
|
||||||
|
|
||||||
|
u_buf.alloc(u_len);
|
||||||
|
memset(u_buf, 0, u_len);
|
||||||
|
c_buf.allocForCompression(u_len, c_extra);
|
||||||
|
d_buf.allocForDecompression(u_len);
|
||||||
|
|
||||||
|
c_len = c_buf.getSize() - c_extra;
|
||||||
|
r = upx_zstd_compress(raw_bytes(u_buf, u_len), u_len, raw_index_bytes(c_buf, c_extra, c_len),
|
||||||
|
&c_len, nullptr, method, level, NULL_cconf, &cresult);
|
||||||
|
if (r != 0 || c_len != expected_c_len)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
d_len = d_buf.getSize();
|
||||||
|
r = upx_zstd_decompress(raw_index_bytes(c_buf, c_extra, c_len), c_len, raw_bytes(d_buf, d_len),
|
||||||
|
&d_len, method, nullptr);
|
||||||
|
if (r != 0 || d_len != u_len || memcmp(u_buf, d_buf, u_len) != 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
d_len = u_len - 1;
|
||||||
|
r = upx_zstd_decompress(raw_index_bytes(c_buf, c_extra, c_len), c_len, raw_bytes(d_buf, d_len),
|
||||||
|
&d_len, method, nullptr);
|
||||||
|
if (r == 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// TODO: rewrite Packer::findOverlapOverhead() so that we can test it here
|
||||||
|
// unsigned x_len = d_len;
|
||||||
|
// r = upx_zstd_test_overlap(c_buf, u_buf, c_extra, c_len, &x_len, method, nullptr);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("compress_zstd") {
|
||||||
|
CHECK(check_zstd(M_ZSTD, 1, 19));
|
||||||
|
CHECK(check_zstd(M_ZSTD, 3, 19));
|
||||||
|
CHECK(check_zstd(M_ZSTD, 5, 19));
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // DEBUG
|
||||||
|
|
||||||
|
TEST_CASE("upx_zstd_decompress") {
|
||||||
|
typedef const upx_byte C;
|
||||||
|
C *c_data;
|
||||||
|
upx_byte d_buf[32];
|
||||||
|
unsigned d_len;
|
||||||
|
int r;
|
||||||
|
|
||||||
|
c_data = (C *) "\x28\xb5\x2f\xfd\x20\x20\x3d\x00\x00\x08\xff\x01\x00\x34\x4e\x08";
|
||||||
|
d_len = 32;
|
||||||
|
r = upx_zstd_decompress(c_data, 16, d_buf, &d_len, M_ZSTD, nullptr);
|
||||||
|
CHECK((r == 0 && d_len == 32));
|
||||||
|
r = upx_zstd_decompress(c_data, 15, d_buf, &d_len, M_ZSTD, nullptr);
|
||||||
|
CHECK(r == UPX_E_INPUT_OVERRUN);
|
||||||
|
d_len = 31;
|
||||||
|
r = upx_zstd_decompress(c_data, 16, d_buf, &d_len, M_ZSTD, nullptr);
|
||||||
|
CHECK(r == UPX_E_OUTPUT_OVERRUN);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // WITH_ZSTD
|
||||||
|
|
||||||
|
/* vim:set ts=4 sw=4 et: */
|
||||||
@@ -1,344 +0,0 @@
|
|||||||
/* compress_ucl.cpp --
|
|
||||||
|
|
||||||
This file is part of the UPX executable compressor.
|
|
||||||
|
|
||||||
Copyright (C) 1996-2022 Markus Franz Xaver Johannes Oberhumer
|
|
||||||
Copyright (C) 1996-2022 Laszlo Molnar
|
|
||||||
All Rights Reserved.
|
|
||||||
|
|
||||||
UPX and the UCL library are free software; you can redistribute them
|
|
||||||
and/or modify them under the terms of the GNU General Public License as
|
|
||||||
published by the Free Software Foundation; either version 2 of
|
|
||||||
the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with this program; see the file COPYING.
|
|
||||||
If not, write to the Free Software Foundation, Inc.,
|
|
||||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
||||||
|
|
||||||
Markus F.X.J. Oberhumer Laszlo Molnar
|
|
||||||
<markus@oberhumer.com> <ezerotven+github@gmail.com>
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#include "conf.h"
|
|
||||||
#include "compress.h"
|
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
|
||||||
//
|
|
||||||
**************************************************************************/
|
|
||||||
|
|
||||||
static int convert_errno_from_ucl(int r)
|
|
||||||
{
|
|
||||||
switch (r)
|
|
||||||
{
|
|
||||||
case UCL_E_OK: return UPX_E_OK;
|
|
||||||
case UCL_E_ERROR: return UPX_E_ERROR;
|
|
||||||
case UCL_E_OUT_OF_MEMORY: return UPX_E_OUT_OF_MEMORY;
|
|
||||||
case UCL_E_NOT_COMPRESSIBLE: return UPX_E_NOT_COMPRESSIBLE;
|
|
||||||
case UCL_E_INPUT_OVERRUN: return UPX_E_INPUT_OVERRUN;
|
|
||||||
case UCL_E_OUTPUT_OVERRUN: return UPX_E_OUTPUT_OVERRUN;
|
|
||||||
case UCL_E_LOOKBEHIND_OVERRUN: return UPX_E_LOOKBEHIND_OVERRUN;
|
|
||||||
case UCL_E_EOF_NOT_FOUND: return UPX_E_EOF_NOT_FOUND;
|
|
||||||
case UCL_E_INPUT_NOT_CONSUMED: return UPX_E_INPUT_NOT_CONSUMED;
|
|
||||||
// case UCL_E_NOT_YET_IMPLEMENTED: return UPX_E_NOT_YET_IMPLEMENTED;
|
|
||||||
case UCL_E_INVALID_ARGUMENT: return UPX_E_INVALID_ARGUMENT;
|
|
||||||
// UCL extra:
|
|
||||||
case UCL_E_OVERLAP_OVERRUN: return UPX_E_ERROR;
|
|
||||||
}
|
|
||||||
return UPX_E_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
extern "C" {
|
|
||||||
static void __UCL_CDECL wrap_nprogress_ucl(ucl_uint a, ucl_uint b, int state, ucl_voidp user)
|
|
||||||
{
|
|
||||||
if (state != -1 && state != 3) return;
|
|
||||||
upx_callback_p cb = (upx_callback_p) user;
|
|
||||||
if (cb && cb->nprogress)
|
|
||||||
cb->nprogress(cb, a, b);
|
|
||||||
}}
|
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
|
||||||
//
|
|
||||||
**************************************************************************/
|
|
||||||
|
|
||||||
int upx_ucl_compress ( const upx_bytep src, unsigned src_len,
|
|
||||||
upx_bytep dst, unsigned* dst_len,
|
|
||||||
upx_callback_p cb_parm,
|
|
||||||
int method, int level,
|
|
||||||
const upx_compress_config_t *cconf_parm,
|
|
||||||
upx_compress_result_t *cresult )
|
|
||||||
{
|
|
||||||
int r;
|
|
||||||
assert(level > 0); assert(cresult != nullptr);
|
|
||||||
|
|
||||||
COMPILE_TIME_ASSERT(sizeof(ucl_compress_config_t) == sizeof(REAL_ucl_compress_config_t))
|
|
||||||
|
|
||||||
ucl_progress_callback_t cb;
|
|
||||||
cb.callback = nullptr;
|
|
||||||
cb.user = nullptr;
|
|
||||||
if (cb_parm && cb_parm->nprogress) {
|
|
||||||
cb.callback = wrap_nprogress_ucl;
|
|
||||||
cb.user = cb_parm;
|
|
||||||
}
|
|
||||||
|
|
||||||
ucl_compress_config_t cconf; cconf.reset();
|
|
||||||
if (cconf_parm)
|
|
||||||
memcpy(&cconf, &cconf_parm->conf_ucl, sizeof(cconf)); // cconf = cconf_parm->conf_ucl; // struct copy
|
|
||||||
|
|
||||||
ucl_uint *res = cresult->result_ucl.result;
|
|
||||||
// assume no info available - fill in worst case results
|
|
||||||
//res[0] = 1; // min_offset_found - NOT USED
|
|
||||||
res[1] = src_len - 1; // max_offset_found
|
|
||||||
//res[2] = 2; // min_match_found - NOT USED
|
|
||||||
res[3] = src_len - 1; // max_match_found
|
|
||||||
//res[4] = 1; // min_run_found - NOT USED
|
|
||||||
res[5] = src_len; // max_run_found
|
|
||||||
res[6] = 1; // first_offset_found
|
|
||||||
//res[7] = 999999; // same_match_offsets_found - NOT USED
|
|
||||||
|
|
||||||
// prepare bit-buffer settings
|
|
||||||
cconf.bb_endian = 0;
|
|
||||||
cconf.bb_size = 0;
|
|
||||||
if (method >= M_NRV2B_LE32 && method <= M_NRV2E_LE16)
|
|
||||||
{
|
|
||||||
static const unsigned char sizes[3] = {32, 8, 16};
|
|
||||||
cconf.bb_size = sizes[(method - M_NRV2B_LE32) % 3];
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
throwInternalError("unknown compression method");
|
|
||||||
return UPX_E_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
// optimize compression parms
|
|
||||||
if (level <= 3 && cconf.max_offset == UCL_UINT_MAX)
|
|
||||||
cconf.max_offset = 8*1024-1;
|
|
||||||
else if (level == 4 && cconf.max_offset == UCL_UINT_MAX)
|
|
||||||
cconf.max_offset = 32*1024-1;
|
|
||||||
|
|
||||||
if M_IS_NRV2B(method)
|
|
||||||
r = ucl_nrv2b_99_compress(src, src_len, dst, dst_len,
|
|
||||||
&cb, level, &cconf, res);
|
|
||||||
else if M_IS_NRV2D(method)
|
|
||||||
r = ucl_nrv2d_99_compress(src, src_len, dst, dst_len,
|
|
||||||
&cb, level, &cconf, res);
|
|
||||||
else if M_IS_NRV2E(method)
|
|
||||||
r = ucl_nrv2e_99_compress(src, src_len, dst, dst_len,
|
|
||||||
&cb, level, &cconf, res);
|
|
||||||
else {
|
|
||||||
throwInternalError("unknown compression method");
|
|
||||||
return UPX_E_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
// make sure first_offset_found is set
|
|
||||||
if (res[6] == 0)
|
|
||||||
res[6] = 1;
|
|
||||||
|
|
||||||
return convert_errno_from_ucl(r);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
|
||||||
//
|
|
||||||
**************************************************************************/
|
|
||||||
|
|
||||||
int upx_ucl_decompress ( const upx_bytep src, unsigned src_len,
|
|
||||||
upx_bytep dst, unsigned* dst_len,
|
|
||||||
int method,
|
|
||||||
const upx_compress_result_t *cresult )
|
|
||||||
{
|
|
||||||
int r;
|
|
||||||
|
|
||||||
switch (method)
|
|
||||||
{
|
|
||||||
case M_NRV2B_8:
|
|
||||||
r = ucl_nrv2b_decompress_safe_8(src,src_len,dst,dst_len,nullptr);
|
|
||||||
break;
|
|
||||||
case M_NRV2B_LE16:
|
|
||||||
r = ucl_nrv2b_decompress_safe_le16(src,src_len,dst,dst_len,nullptr);
|
|
||||||
break;
|
|
||||||
case M_NRV2B_LE32:
|
|
||||||
r = ucl_nrv2b_decompress_safe_le32(src,src_len,dst,dst_len,nullptr);
|
|
||||||
break;
|
|
||||||
case M_NRV2D_8:
|
|
||||||
r = ucl_nrv2d_decompress_safe_8(src,src_len,dst,dst_len,nullptr);
|
|
||||||
break;
|
|
||||||
case M_NRV2D_LE16:
|
|
||||||
r = ucl_nrv2d_decompress_safe_le16(src,src_len,dst,dst_len,nullptr);
|
|
||||||
break;
|
|
||||||
case M_NRV2D_LE32:
|
|
||||||
r = ucl_nrv2d_decompress_safe_le32(src,src_len,dst,dst_len,nullptr);
|
|
||||||
break;
|
|
||||||
case M_NRV2E_8:
|
|
||||||
r = ucl_nrv2e_decompress_safe_8(src,src_len,dst,dst_len,nullptr);
|
|
||||||
break;
|
|
||||||
case M_NRV2E_LE16:
|
|
||||||
r = ucl_nrv2e_decompress_safe_le16(src,src_len,dst,dst_len,nullptr);
|
|
||||||
break;
|
|
||||||
case M_NRV2E_LE32:
|
|
||||||
r = ucl_nrv2e_decompress_safe_le32(src,src_len,dst,dst_len,nullptr);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
throwInternalError("unknown decompression method");
|
|
||||||
return UPX_E_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
UNUSED(cresult);
|
|
||||||
return convert_errno_from_ucl(r);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
|
||||||
//
|
|
||||||
**************************************************************************/
|
|
||||||
|
|
||||||
int upx_ucl_test_overlap ( const upx_bytep buf,
|
|
||||||
const upx_bytep tbuf,
|
|
||||||
unsigned src_off, unsigned src_len,
|
|
||||||
unsigned* dst_len,
|
|
||||||
int method,
|
|
||||||
const upx_compress_result_t *cresult )
|
|
||||||
{
|
|
||||||
int r;
|
|
||||||
UNUSED(tbuf); // not needed for UCL
|
|
||||||
|
|
||||||
switch (method)
|
|
||||||
{
|
|
||||||
case M_NRV2B_8:
|
|
||||||
r = ucl_nrv2b_test_overlap_8(buf,src_off,src_len,dst_len,nullptr);
|
|
||||||
break;
|
|
||||||
case M_NRV2B_LE16:
|
|
||||||
r = ucl_nrv2b_test_overlap_le16(buf,src_off,src_len,dst_len,nullptr);
|
|
||||||
break;
|
|
||||||
case M_NRV2B_LE32:
|
|
||||||
r = ucl_nrv2b_test_overlap_le32(buf,src_off,src_len,dst_len,nullptr);
|
|
||||||
break;
|
|
||||||
case M_NRV2D_8:
|
|
||||||
r = ucl_nrv2d_test_overlap_8(buf,src_off,src_len,dst_len,nullptr);
|
|
||||||
break;
|
|
||||||
case M_NRV2D_LE16:
|
|
||||||
r = ucl_nrv2d_test_overlap_le16(buf,src_off,src_len,dst_len,nullptr);
|
|
||||||
break;
|
|
||||||
case M_NRV2D_LE32:
|
|
||||||
r = ucl_nrv2d_test_overlap_le32(buf,src_off,src_len,dst_len,nullptr);
|
|
||||||
break;
|
|
||||||
case M_NRV2E_8:
|
|
||||||
r = ucl_nrv2e_test_overlap_8(buf,src_off,src_len,dst_len,nullptr);
|
|
||||||
break;
|
|
||||||
case M_NRV2E_LE16:
|
|
||||||
r = ucl_nrv2e_test_overlap_le16(buf,src_off,src_len,dst_len,nullptr);
|
|
||||||
break;
|
|
||||||
case M_NRV2E_LE32:
|
|
||||||
r = ucl_nrv2e_test_overlap_le32(buf,src_off,src_len,dst_len,nullptr);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
throwInternalError("unknown decompression method");
|
|
||||||
return UPX_E_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
UNUSED(cresult);
|
|
||||||
return convert_errno_from_ucl(r);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
|
||||||
// misc
|
|
||||||
**************************************************************************/
|
|
||||||
|
|
||||||
extern "C" {
|
|
||||||
static ucl_voidp __UCL_CDECL my_malloc(ucl_uint n) { return calloc(1, n); }
|
|
||||||
static void __UCL_CDECL my_free(ucl_voidp p) { free(p); }
|
|
||||||
}
|
|
||||||
|
|
||||||
int upx_ucl_init(void)
|
|
||||||
{
|
|
||||||
if (ucl_init() != UCL_E_OK)
|
|
||||||
return -1;
|
|
||||||
if (UCL_VERSION != ucl_version() || strcmp(UCL_VERSION_STRING, ucl_version_string()) != 0)
|
|
||||||
return -2;
|
|
||||||
ucl_set_malloc_hooks(my_malloc, my_free);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
const char *upx_ucl_version_string(void)
|
|
||||||
{
|
|
||||||
return ucl_version_string();
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned upx_ucl_adler32(const void *buf, unsigned len, unsigned adler)
|
|
||||||
{
|
|
||||||
return ucl_adler32(adler, (const ucl_bytep) buf, len);
|
|
||||||
}
|
|
||||||
|
|
||||||
#if 0 /* UNUSED */
|
|
||||||
unsigned upx_ucl_crc32(const void *buf, unsigned len, unsigned crc)
|
|
||||||
{
|
|
||||||
return ucl_crc32(crc, (const ucl_bytep) buf, len);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*************************************************************************
|
|
||||||
// Debug checks
|
|
||||||
**************************************************************************/
|
|
||||||
|
|
||||||
#if DEBUG && 1
|
|
||||||
|
|
||||||
#include "util/membuffer.h"
|
|
||||||
|
|
||||||
static bool check_ucl(const int method, const unsigned expected_c_len) {
|
|
||||||
const unsigned u_len = 16384;
|
|
||||||
const unsigned c_extra = 4096;
|
|
||||||
MemBuffer u_buf, c_buf, d_buf;
|
|
||||||
unsigned c_len, d_len;
|
|
||||||
upx_compress_result_t cresult;
|
|
||||||
int r;
|
|
||||||
const int level = 3; // don't waste time
|
|
||||||
|
|
||||||
u_buf.alloc(u_len);
|
|
||||||
memset(u_buf, 0, u_len);
|
|
||||||
c_buf.allocForCompression(u_len, c_extra);
|
|
||||||
d_buf.allocForDecompression(u_len);
|
|
||||||
|
|
||||||
c_len = c_buf.getSize() - c_extra;
|
|
||||||
r = upx_ucl_compress(u_buf, u_len, c_buf + c_extra, &c_len, nullptr, method, level, NULL_cconf, &cresult);
|
|
||||||
if (r != 0 || c_len != expected_c_len) return false;
|
|
||||||
|
|
||||||
d_len = d_buf.getSize();
|
|
||||||
r = upx_ucl_decompress(c_buf + c_extra, c_len, d_buf, &d_len, method, nullptr);
|
|
||||||
if (r != 0 || d_len != u_len) return false;
|
|
||||||
if (memcmp(u_buf, d_buf, u_len) != 0) return false;
|
|
||||||
|
|
||||||
d_len = u_len - 1;
|
|
||||||
r = upx_ucl_decompress(c_buf + c_extra, c_len, d_buf, &d_len, method, nullptr);
|
|
||||||
if (r == 0) return false;
|
|
||||||
|
|
||||||
// TODO: rewrite Packer::findOverlapOverhead() so that we can test it here
|
|
||||||
//unsigned x_len = d_len;
|
|
||||||
//r = upx_ucl_test_overlap(c_buf, u_buf, c_extra, c_len, &x_len, method, nullptr);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_CASE("compress_ucl") {
|
|
||||||
CHECK(check_ucl(M_NRV2B_8, 34));
|
|
||||||
CHECK(check_ucl(M_NRV2B_LE16, 34));
|
|
||||||
CHECK(check_ucl(M_NRV2B_LE32, 34));
|
|
||||||
CHECK(check_ucl(M_NRV2D_8, 32));
|
|
||||||
CHECK(check_ucl(M_NRV2D_LE16, 32));
|
|
||||||
CHECK(check_ucl(M_NRV2D_LE32, 34));
|
|
||||||
CHECK(check_ucl(M_NRV2E_8, 32));
|
|
||||||
CHECK(check_ucl(M_NRV2E_LE16, 32));
|
|
||||||
CHECK(check_ucl(M_NRV2E_LE32, 34));
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // DEBUG
|
|
||||||
|
|
||||||
|
|
||||||
/* vim:set ts=4 sw=4 et: */
|
|
||||||
+200
-128
@@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
This file is part of the UPX executable compressor.
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
Copyright (C) 1996-2022 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2022 Laszlo Molnar
|
Copyright (C) 1996-2023 Laszlo Molnar
|
||||||
All Rights Reserved.
|
All Rights Reserved.
|
||||||
|
|
||||||
UPX and the UCL library are free software; you can redistribute them
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
@@ -29,12 +29,8 @@
|
|||||||
#ifndef UPX_CONF_H__
|
#ifndef UPX_CONF_H__
|
||||||
#define UPX_CONF_H__ 1
|
#define UPX_CONF_H__ 1
|
||||||
|
|
||||||
#if defined(__cplusplus)
|
#if !(__cplusplus+0 >= 201703L)
|
||||||
# if (__cplusplus >= 201402L)
|
# error "C++ 17 is required"
|
||||||
# elif defined(_MSC_VER) && defined(_MSVC_LANG) && (_MSVC_LANG+0 >= 201402L)
|
|
||||||
# else
|
|
||||||
# error "C++ 14 is required"
|
|
||||||
# endif
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "version.h"
|
#include "version.h"
|
||||||
@@ -48,11 +44,9 @@
|
|||||||
# endif
|
# endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#undef NDEBUG
|
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
// ACC
|
// ACC and system includes
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
#ifndef ACC_CFG_USE_NEW_STYLE_CASTS
|
#ifndef ACC_CFG_USE_NEW_STYLE_CASTS
|
||||||
@@ -117,8 +111,59 @@ ACC_COMPILE_TIME_ASSERT_HEADER((char)(-1) == 255) // -funsigned-char
|
|||||||
#define ACC_WANT_ACC_LIB_H 1
|
#define ACC_WANT_ACC_LIB_H 1
|
||||||
#define ACC_WANT_ACC_CXX_H 1
|
#define ACC_WANT_ACC_CXX_H 1
|
||||||
#include "miniacc.h"
|
#include "miniacc.h"
|
||||||
|
#if (ACC_CC_MSC)
|
||||||
|
# include <intrin.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
/* intergral types */
|
// C++ system headers
|
||||||
|
#include <exception>
|
||||||
|
#include <new>
|
||||||
|
#include <type_traits>
|
||||||
|
#include <typeinfo>
|
||||||
|
#if __STDC_NO_ATOMICS__ || 1
|
||||||
|
// UPX currently does not use multithreading
|
||||||
|
#define upx_std_atomic(Type) Type
|
||||||
|
//#define upx_std_atomic(Type) typename std::add_volatile<Type>::type
|
||||||
|
#else
|
||||||
|
#include <atomic>
|
||||||
|
#define upx_std_atomic(Type) std::atomic<Type>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// C++ submodule headers
|
||||||
|
#include <doctest/doctest/parts/doctest_fwd.h>
|
||||||
|
#if WITH_BOOST_PFR
|
||||||
|
# include <sstream>
|
||||||
|
# include <boost/pfr/io.hpp>
|
||||||
|
#endif
|
||||||
|
#if WITH_RANGELESS_FN
|
||||||
|
# include <rangeless/include/fn.hpp>
|
||||||
|
#endif
|
||||||
|
#ifndef WITH_VALGRIND
|
||||||
|
# define WITH_VALGRIND 1
|
||||||
|
#endif
|
||||||
|
#if defined(__SANITIZE_ADDRESS__) || defined(_WIN32) || !defined(__GNUC__)
|
||||||
|
# undef WITH_VALGRIND
|
||||||
|
#endif
|
||||||
|
#if (WITH_VALGRIND)
|
||||||
|
# include <valgrind/include/valgrind/memcheck.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// IMPORTANT: unconditionally enable assertions
|
||||||
|
#undef NDEBUG
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
|
// <type_traits> C++20 std::is_bounded_array
|
||||||
|
template <class T>
|
||||||
|
struct std_is_bounded_array : public std::false_type {};
|
||||||
|
template <class T, size_t N>
|
||||||
|
struct std_is_bounded_array<T[N]> : public std::true_type {};
|
||||||
|
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
// core
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
// intergral types
|
||||||
typedef acc_int8_t upx_int8_t;
|
typedef acc_int8_t upx_int8_t;
|
||||||
typedef acc_uint8_t upx_uint8_t;
|
typedef acc_uint8_t upx_uint8_t;
|
||||||
typedef acc_int16_t upx_int16_t;
|
typedef acc_int16_t upx_int16_t;
|
||||||
@@ -132,59 +177,6 @@ typedef acc_uintptr_t upx_uintptr_t;
|
|||||||
typedef unsigned char upx_byte;
|
typedef unsigned char upx_byte;
|
||||||
#define upx_bytep upx_byte *
|
#define upx_bytep upx_byte *
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
|
||||||
//
|
|
||||||
**************************************************************************/
|
|
||||||
|
|
||||||
#if defined(__linux__) && !defined(__unix__)
|
|
||||||
# define __unix__ 1
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// just in case
|
|
||||||
#undef _
|
|
||||||
#undef __
|
|
||||||
#undef ___
|
|
||||||
#undef dos
|
|
||||||
#undef linux
|
|
||||||
#undef small
|
|
||||||
#undef tos
|
|
||||||
#undef unix
|
|
||||||
#if (ACC_OS_DOS32) && defined(__DJGPP__)
|
|
||||||
# undef sopen
|
|
||||||
# undef __unix__
|
|
||||||
# undef __unix
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define WITH_LZMA 0x443
|
|
||||||
#define WITH_UCL 1
|
|
||||||
#define WITH_ZLIB 1
|
|
||||||
#if (WITH_UCL)
|
|
||||||
# define ucl_compress_config_t REAL_ucl_compress_config_t
|
|
||||||
# include <ucl/include/ucl/uclconf.h>
|
|
||||||
# include <ucl/include/ucl/ucl.h>
|
|
||||||
# undef ucl_compress_config_t
|
|
||||||
# undef ucl_compress_config_p
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// malloc debuggers
|
|
||||||
#if (WITH_VALGRIND)
|
|
||||||
# include <valgrind/memcheck.h>
|
|
||||||
#endif
|
|
||||||
#if !defined(VALGRIND_MAKE_MEM_DEFINED)
|
|
||||||
# define VALGRIND_MAKE_MEM_DEFINED(addr,len) 0
|
|
||||||
#endif
|
|
||||||
#if !defined(VALGRIND_MAKE_MEM_NOACCESS)
|
|
||||||
# define VALGRIND_MAKE_MEM_NOACCESS(addr,len) 0
|
|
||||||
#endif
|
|
||||||
#if !defined(VALGRIND_MAKE_MEM_UNDEFINED)
|
|
||||||
# define VALGRIND_MAKE_MEM_UNDEFINED(addr,len) 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// IMPORTANT: unconditionally enable assertions
|
|
||||||
#undef NDEBUG
|
|
||||||
#include <assert.h>
|
|
||||||
|
|
||||||
// protect against integer overflows and malicious header fields
|
// protect against integer overflows and malicious header fields
|
||||||
// see C 11 standard, Annex K
|
// see C 11 standard, Annex K
|
||||||
typedef size_t upx_rsize_t;
|
typedef size_t upx_rsize_t;
|
||||||
@@ -202,11 +194,47 @@ typedef upx_int64_t upx_off_t;
|
|||||||
#define off_t upx_off_t
|
#define off_t upx_off_t
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// shortcuts
|
||||||
|
#define forceinline __acc_forceinline
|
||||||
|
#if _MSC_VER
|
||||||
|
#define noinline __declspec(noinline)
|
||||||
|
#undef __acc_noinline
|
||||||
|
#define __acc_noinline noinline
|
||||||
|
#else
|
||||||
|
#define noinline __acc_noinline
|
||||||
|
#endif
|
||||||
|
#define likely __acc_likely
|
||||||
|
#define unlikely __acc_unlikely
|
||||||
|
#define very_likely __acc_very_likely
|
||||||
|
#define very_unlikely __acc_very_unlikely
|
||||||
|
|
||||||
|
#define COMPILE_TIME_ASSERT(e) ACC_COMPILE_TIME_ASSERT(e)
|
||||||
|
#define DELETED_FUNCTION = delete
|
||||||
|
#define UNUSED(var) ACC_UNUSED(var)
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
// portab
|
// portab
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
|
// just in case
|
||||||
|
#undef _
|
||||||
|
#undef __
|
||||||
|
#undef ___
|
||||||
|
#undef dos
|
||||||
|
#undef linux
|
||||||
|
#undef small
|
||||||
|
#undef tos
|
||||||
|
#undef unix
|
||||||
|
#if defined(__linux__) && !defined(__unix__)
|
||||||
|
# define __unix__ 1
|
||||||
|
#endif
|
||||||
|
#if (ACC_OS_DOS32) && defined(__DJGPP__)
|
||||||
|
# undef sopen
|
||||||
|
# undef __unix__
|
||||||
|
# undef __unix
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef STDIN_FILENO
|
#ifndef STDIN_FILENO
|
||||||
# define STDIN_FILENO (fileno(stdin))
|
# define STDIN_FILENO (fileno(stdin))
|
||||||
#endif
|
#endif
|
||||||
@@ -264,12 +292,14 @@ typedef upx_int64_t upx_off_t;
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
// avoid warnings about shadowing global functions
|
// avoid warnings about shadowing global functions
|
||||||
|
#undef _base
|
||||||
#undef basename
|
#undef basename
|
||||||
#undef index
|
#undef index
|
||||||
#undef outp
|
#undef outp
|
||||||
#define basename upx_basename
|
#define _base upx_renamed__base
|
||||||
#define index upx_index
|
#define basename upx_renamed_basename
|
||||||
#define outp upx_outp
|
#define index upx_renamed_index
|
||||||
|
#define outp upx_renamed_outp
|
||||||
|
|
||||||
#undef PAGE_MASK
|
#undef PAGE_MASK
|
||||||
#undef PAGE_SIZE
|
#undef PAGE_SIZE
|
||||||
@@ -283,21 +313,34 @@ typedef upx_int64_t upx_off_t;
|
|||||||
# define O_BINARY 0
|
# define O_BINARY 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef OPTIONS_VAR
|
|
||||||
# define OPTIONS_VAR "UPX"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
//
|
// util
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
#define CLANG_FORMAT_DUMMY_STATEMENT /*empty*/
|
#define CLANG_FORMAT_DUMMY_STATEMENT /*empty*/
|
||||||
|
|
||||||
|
// malloc debuggers
|
||||||
|
#if !defined(VALGRIND_CHECK_MEM_IS_ADDRESSABLE)
|
||||||
|
# define VALGRIND_CHECK_MEM_IS_ADDRESSABLE(addr,len) 0
|
||||||
|
#endif
|
||||||
|
#if !defined(VALGRIND_CHECK_MEM_IS_DEFINED)
|
||||||
|
# define VALGRIND_CHECK_MEM_IS_DEFINED(addr,len) 0
|
||||||
|
#endif
|
||||||
|
#if !defined(VALGRIND_MAKE_MEM_DEFINED)
|
||||||
|
# define VALGRIND_MAKE_MEM_DEFINED(addr,len) 0
|
||||||
|
#endif
|
||||||
|
#if !defined(VALGRIND_MAKE_MEM_NOACCESS)
|
||||||
|
# define VALGRIND_MAKE_MEM_NOACCESS(addr,len) 0
|
||||||
|
#endif
|
||||||
|
#if !defined(VALGRIND_MAKE_MEM_UNDEFINED)
|
||||||
|
# define VALGRIND_MAKE_MEM_UNDEFINED(addr,len) 0
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined(_WIN32) && defined(__MINGW32__) && defined(__GNUC__) && !defined(__clang__)
|
#if defined(_WIN32) && defined(__MINGW32__) && defined(__GNUC__) && !defined(__clang__)
|
||||||
# define attribute_format(a,b) __attribute__((__format__(__gnu_printf__,a,b)));
|
# define attribute_format(a,b) __attribute__((__format__(__gnu_printf__,a,b)))
|
||||||
#elif (ACC_CC_CLANG || ACC_CC_GNUC)
|
#elif (ACC_CC_CLANG || ACC_CC_GNUC)
|
||||||
# define attribute_format(a,b) __attribute__((__format__(__printf__,a,b)));
|
# define attribute_format(a,b) __attribute__((__format__(__printf__,a,b)))
|
||||||
#else
|
#else
|
||||||
# define attribute_format(a,b) /*empty*/
|
# define attribute_format(a,b) /*empty*/
|
||||||
#endif
|
#endif
|
||||||
@@ -321,13 +364,28 @@ inline void NO_fprintf(FILE *, const char *, ...) {}
|
|||||||
# define upx_memcpy_inline memcpy
|
# define upx_memcpy_inline memcpy
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define UNUSED(var) ACC_UNUSED(var)
|
#if __has_builtin(__builtin_return_address)
|
||||||
#define COMPILE_TIME_ASSERT(e) ACC_COMPILE_TIME_ASSERT(e)
|
# define upx_return_address() __builtin_return_address(0)
|
||||||
|
#elif defined(__GNUC__)
|
||||||
|
# define upx_return_address() __builtin_return_address(0)
|
||||||
|
#elif (ACC_CC_MSC)
|
||||||
|
# define upx_return_address() _ReturnAddress()
|
||||||
|
#else
|
||||||
|
# define upx_return_address() nullptr
|
||||||
|
#endif
|
||||||
|
|
||||||
// TODO cleanup: we now require C++14, so remove all __packed_struct usage
|
// TODO cleanup: we now require C++14, so remove all __packed_struct usage
|
||||||
#define __packed_struct(s) struct alignas(1) s {
|
#define __packed_struct(s) struct alignas(1) s {
|
||||||
#define __packed_struct_end() };
|
#define __packed_struct_end() };
|
||||||
|
|
||||||
|
#if (ACC_ARCH_M68K && ACC_OS_TOS && ACC_CC_GNUC) && defined(__MINT__)
|
||||||
|
// horrible hack for broken compiler
|
||||||
|
#define upx_fake_alignas_1 __attribute__((__aligned__(1),__packed__))
|
||||||
|
#define upx_fake_alignas_16 __attribute__((__aligned__(2))) // object file maximum 2 ???
|
||||||
|
#define upx_fake_alignas__(a) upx_fake_alignas_ ## a
|
||||||
|
#define alignas(x) upx_fake_alignas__(x)
|
||||||
|
#endif
|
||||||
|
|
||||||
#define COMPILE_TIME_ASSERT_ALIGNOF_USING_SIZEOF__(a,b) { \
|
#define COMPILE_TIME_ASSERT_ALIGNOF_USING_SIZEOF__(a,b) { \
|
||||||
typedef a acc_tmp_a_t; typedef b acc_tmp_b_t; \
|
typedef a acc_tmp_a_t; typedef b acc_tmp_b_t; \
|
||||||
struct alignas(1) acc_tmp_t { acc_tmp_b_t x; acc_tmp_a_t y; acc_tmp_b_t z; }; \
|
struct alignas(1) acc_tmp_t { acc_tmp_b_t x; acc_tmp_a_t y; acc_tmp_b_t z; }; \
|
||||||
@@ -355,6 +413,15 @@ inline const T& UPX_MAX(const T& a, const T& b) { if (a < b) return b; return a;
|
|||||||
template <class T>
|
template <class T>
|
||||||
inline const T& UPX_MIN(const T& a, const T& b) { if (a < b) return a; return b; }
|
inline const T& UPX_MIN(const T& a, const T& b) { if (a < b) return a; return b; }
|
||||||
|
|
||||||
|
template <size_t TypeSize>
|
||||||
|
struct USizeOfTypeImpl {
|
||||||
|
static forceinline constexpr unsigned value() {
|
||||||
|
COMPILE_TIME_ASSERT(TypeSize >= 1 && TypeSize <= 64 * 1024); // arbitrary limit
|
||||||
|
return ACC_ICONV(unsigned, TypeSize);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
#define usizeof(type) (USizeOfTypeImpl<sizeof(type)>::value())
|
||||||
|
ACC_COMPILE_TIME_ASSERT_HEADER(usizeof(int) == 4)
|
||||||
|
|
||||||
// An Array allocates memory on the heap, and automatically
|
// An Array allocates memory on the heap, and automatically
|
||||||
// gets destructed when leaving scope or on exceptions.
|
// gets destructed when leaving scope or on exceptions.
|
||||||
@@ -371,12 +438,17 @@ protected:
|
|||||||
inline noncopyable() {}
|
inline noncopyable() {}
|
||||||
inline ~noncopyable() {}
|
inline ~noncopyable() {}
|
||||||
private:
|
private:
|
||||||
noncopyable(const noncopyable &); // undefined
|
noncopyable(const noncopyable &) DELETED_FUNCTION; // copy constuctor
|
||||||
const noncopyable& operator=(const noncopyable &); // undefined
|
noncopyable& operator=(const noncopyable &) DELETED_FUNCTION; // copy assignment
|
||||||
|
noncopyable(noncopyable &&) DELETED_FUNCTION; // move constructor
|
||||||
|
noncopyable& operator=(noncopyable &&) DELETED_FUNCTION; // move assignment
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
namespace compile_time {
|
namespace compile_time {
|
||||||
|
constexpr size_t string_len(const char *a) {
|
||||||
|
return *a == '\0' ? 0 : 1 + string_len(a + 1);
|
||||||
|
}
|
||||||
constexpr bool string_eq(const char *a, const char *b) {
|
constexpr bool string_eq(const char *a, const char *b) {
|
||||||
return *a == *b && (*a == '\0' || string_eq(a + 1, b + 1));
|
return *a == *b && (*a == '\0' || string_eq(a + 1, b + 1));
|
||||||
}
|
}
|
||||||
@@ -440,14 +512,14 @@ constexpr bool string_ge(const char *a, const char *b) {
|
|||||||
#define UPX_F_DOS_EXE 3
|
#define UPX_F_DOS_EXE 3
|
||||||
#define UPX_F_DJGPP2_COFF 4
|
#define UPX_F_DJGPP2_COFF 4
|
||||||
#define UPX_F_WATCOM_LE 5
|
#define UPX_F_WATCOM_LE 5
|
||||||
#define UPX_F_VXD_LE 6 // NOT IMPLEMENTED
|
//#define UPX_F_VXD_LE 6 // NOT IMPLEMENTED
|
||||||
#define UPX_F_DOS_EXEH 7 // OBSOLETE
|
#define UPX_F_DOS_EXEH 7 // OBSOLETE
|
||||||
#define UPX_F_TMT_ADAM 8
|
#define UPX_F_TMT_ADAM 8
|
||||||
#define UPX_F_WIN32_PE 9
|
#define UPX_F_WIN32_PE 9
|
||||||
#define UPX_F_LINUX_i386 10
|
#define UPX_F_LINUX_i386 10
|
||||||
#define UPX_F_WIN16_NE 11 // NOT IMPLEMENTED
|
//#define UPX_F_WIN16_NE 11 // NOT IMPLEMENTED
|
||||||
#define UPX_F_LINUX_ELF_i386 12
|
#define UPX_F_LINUX_ELF_i386 12
|
||||||
#define UPX_F_LINUX_SEP_i386 13 // NOT IMPLEMENTED
|
//#define UPX_F_LINUX_SEP_i386 13 // NOT IMPLEMENTED
|
||||||
#define UPX_F_LINUX_SH_i386 14
|
#define UPX_F_LINUX_SH_i386 14
|
||||||
#define UPX_F_VMLINUZ_i386 15
|
#define UPX_F_VMLINUZ_i386 15
|
||||||
#define UPX_F_BVMLINUZ_i386 16
|
#define UPX_F_BVMLINUZ_i386 16
|
||||||
@@ -485,7 +557,7 @@ constexpr bool string_ge(const char *a, const char *b) {
|
|||||||
#define UPX_F_LINUX_ELF64_ARM 42
|
#define UPX_F_LINUX_ELF64_ARM 42
|
||||||
|
|
||||||
#define UPX_F_ATARI_TOS 129
|
#define UPX_F_ATARI_TOS 129
|
||||||
#define UPX_F_SOLARIS_SPARC 130 // NOT IMPLEMENTED
|
//#define UPX_F_SOLARIS_SPARC 130 // NOT IMPLEMENTED
|
||||||
#define UPX_F_MACH_PPC32 131
|
#define UPX_F_MACH_PPC32 131
|
||||||
#define UPX_F_LINUX_ELFPPC32 132
|
#define UPX_F_LINUX_ELFPPC32 132
|
||||||
#define UPX_F_LINUX_ELF32_ARMEB 133
|
#define UPX_F_LINUX_ELF32_ARMEB 133
|
||||||
@@ -514,7 +586,8 @@ constexpr bool string_ge(const char *a, const char *b) {
|
|||||||
//#define M_CL1B_8 12
|
//#define M_CL1B_8 12
|
||||||
//#define M_CL1B_LE16 13
|
//#define M_CL1B_LE16 13
|
||||||
#define M_LZMA 14
|
#define M_LZMA 14
|
||||||
#define M_DEFLATE 15 /* zlib */
|
#define M_DEFLATE 15 // zlib
|
||||||
|
#define M_ZSTD 16
|
||||||
// compression methods internal usage
|
// compression methods internal usage
|
||||||
#define M_ALL (-1)
|
#define M_ALL (-1)
|
||||||
#define M_END (-2)
|
#define M_END (-2)
|
||||||
@@ -528,6 +601,7 @@ constexpr bool string_ge(const char *a, const char *b) {
|
|||||||
//#define M_IS_CL1B(x) ((x) >= M_CL1B_LE32 && (x) <= M_CL1B_LE16)
|
//#define M_IS_CL1B(x) ((x) >= M_CL1B_LE32 && (x) <= M_CL1B_LE16)
|
||||||
#define M_IS_LZMA(x) (((x) & 255) == M_LZMA)
|
#define M_IS_LZMA(x) (((x) & 255) == M_LZMA)
|
||||||
#define M_IS_DEFLATE(x) ((x) == M_DEFLATE)
|
#define M_IS_DEFLATE(x) ((x) == M_DEFLATE)
|
||||||
|
#define M_IS_ZSTD(x) ((x) == M_ZSTD)
|
||||||
|
|
||||||
|
|
||||||
// filters
|
// filters
|
||||||
@@ -538,9 +612,20 @@ constexpr bool string_ge(const char *a, const char *b) {
|
|||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
// compression - callback_t
|
// compression - setup and callback_t
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
|
#define WITH_LZMA 1
|
||||||
|
#define WITH_UCL 1
|
||||||
|
#define WITH_ZLIB 1
|
||||||
|
#if (WITH_UCL)
|
||||||
|
# define ucl_compress_config_t REAL_ucl_compress_config_t
|
||||||
|
# include <ucl/include/ucl/uclconf.h>
|
||||||
|
# include <ucl/include/ucl/ucl.h>
|
||||||
|
# undef ucl_compress_config_t
|
||||||
|
# undef ucl_compress_config_p
|
||||||
|
#endif
|
||||||
|
|
||||||
struct upx_callback_t;
|
struct upx_callback_t;
|
||||||
typedef upx_callback_t *upx_callback_p;
|
typedef upx_callback_t *upx_callback_p;
|
||||||
typedef void (__acc_cdecl *upx_progress_func_t)
|
typedef void (__acc_cdecl *upx_progress_func_t)
|
||||||
@@ -577,25 +662,26 @@ struct OptVar
|
|||||||
assertValue(v);
|
assertValue(v);
|
||||||
}
|
}
|
||||||
|
|
||||||
OptVar() : v(default_value), is_set(0) { }
|
OptVar() : v(default_value), is_set(false) { }
|
||||||
OptVar& operator= (const T &other) {
|
OptVar& operator= (const T &other) {
|
||||||
v = other; is_set = 1;
|
assertValue(other);
|
||||||
assertValue();
|
v = other;
|
||||||
|
is_set = true;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
void reset() { v = default_value; is_set = 0; }
|
void reset() { v = default_value; is_set = false; }
|
||||||
operator T () const { return v; }
|
operator T () const { return v; }
|
||||||
|
|
||||||
T v;
|
T v;
|
||||||
unsigned is_set;
|
bool is_set;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// optional assignments
|
// optional assignments
|
||||||
template <class T, T a, T b, T c>
|
template <class T, T a, T b, T c>
|
||||||
inline void oassign(OptVar<T,a,b,c> &self, const OptVar<T,a,b,c> &other) {
|
inline void oassign(OptVar<T,a,b,c> &self, const OptVar<T,a,b,c> &other) {
|
||||||
if (other.is_set) { self.v = other.v; self.is_set = 1; }
|
if (other.is_set) { self.v = other.v; self.is_set = true; }
|
||||||
}
|
}
|
||||||
template <class T, T a, T b, T c>
|
template <class T, T a, T b, T c>
|
||||||
inline void oassign(T &v, const OptVar<T,a,b,c> &other) {
|
inline void oassign(T &v, const OptVar<T,a,b,c> &other) {
|
||||||
@@ -624,13 +710,11 @@ struct lzma_compress_config_t
|
|||||||
void reset();
|
void reset();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
struct ucl_compress_config_t : public REAL_ucl_compress_config_t
|
struct ucl_compress_config_t : public REAL_ucl_compress_config_t
|
||||||
{
|
{
|
||||||
void reset() { memset(this, 0xff, sizeof(*this)); }
|
void reset() { memset(this, 0xff, sizeof(*this)); }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
struct zlib_compress_config_t
|
struct zlib_compress_config_t
|
||||||
{
|
{
|
||||||
typedef OptVar<unsigned, 8u, 1u, 9u> mem_level_t; // ml
|
typedef OptVar<unsigned, 8u, 1u, 9u> mem_level_t; // ml
|
||||||
@@ -644,13 +728,20 @@ struct zlib_compress_config_t
|
|||||||
void reset();
|
void reset();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct zstd_compress_config_t
|
||||||
|
{
|
||||||
|
unsigned dummy;
|
||||||
|
|
||||||
|
void reset();
|
||||||
|
};
|
||||||
|
|
||||||
struct upx_compress_config_t
|
struct upx_compress_config_t
|
||||||
{
|
{
|
||||||
lzma_compress_config_t conf_lzma;
|
lzma_compress_config_t conf_lzma;
|
||||||
ucl_compress_config_t conf_ucl;
|
ucl_compress_config_t conf_ucl;
|
||||||
zlib_compress_config_t conf_zlib;
|
zlib_compress_config_t conf_zlib;
|
||||||
void reset() { conf_lzma.reset(); conf_ucl.reset(); conf_zlib.reset(); }
|
zstd_compress_config_t conf_zstd;
|
||||||
|
void reset() { conf_lzma.reset(); conf_ucl.reset(); conf_zlib.reset(); conf_zstd.reset(); }
|
||||||
};
|
};
|
||||||
|
|
||||||
#define NULL_cconf ((upx_compress_config_t *) nullptr)
|
#define NULL_cconf ((upx_compress_config_t *) nullptr)
|
||||||
@@ -674,7 +765,6 @@ struct lzma_compress_result_t
|
|||||||
void reset() { memset(this, 0, sizeof(*this)); }
|
void reset() { memset(this, 0, sizeof(*this)); }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
struct ucl_compress_result_t
|
struct ucl_compress_result_t
|
||||||
{
|
{
|
||||||
ucl_uint result[16];
|
ucl_uint result[16];
|
||||||
@@ -682,7 +772,6 @@ struct ucl_compress_result_t
|
|||||||
void reset() { memset(this, 0, sizeof(*this)); }
|
void reset() { memset(this, 0, sizeof(*this)); }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
struct zlib_compress_result_t
|
struct zlib_compress_result_t
|
||||||
{
|
{
|
||||||
unsigned dummy;
|
unsigned dummy;
|
||||||
@@ -690,20 +779,29 @@ struct zlib_compress_result_t
|
|||||||
void reset() { memset(this, 0, sizeof(*this)); }
|
void reset() { memset(this, 0, sizeof(*this)); }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct zstd_compress_result_t
|
||||||
|
{
|
||||||
|
unsigned dummy;
|
||||||
|
|
||||||
|
void reset() { memset(this, 0, sizeof(*this)); }
|
||||||
|
};
|
||||||
|
|
||||||
struct upx_compress_result_t
|
struct upx_compress_result_t
|
||||||
{
|
{
|
||||||
// debug
|
// debugging aid
|
||||||
|
struct {
|
||||||
int method, level;
|
int method, level;
|
||||||
unsigned u_len, c_len;
|
unsigned u_len, c_len;
|
||||||
|
} debug;
|
||||||
|
|
||||||
lzma_compress_result_t result_lzma;
|
lzma_compress_result_t result_lzma;
|
||||||
ucl_compress_result_t result_ucl;
|
ucl_compress_result_t result_ucl;
|
||||||
zlib_compress_result_t result_zlib;
|
zlib_compress_result_t result_zlib;
|
||||||
|
zstd_compress_result_t result_zstd;
|
||||||
|
|
||||||
void reset() {
|
void reset() {
|
||||||
memset(this, 0, sizeof(*this));
|
memset(&this->debug, 0, sizeof(this->debug));
|
||||||
result_lzma.reset(); result_ucl.reset(); result_zlib.reset();
|
result_lzma.reset(); result_ucl.reset(); result_zlib.reset(); result_zstd.reset();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -713,16 +811,10 @@ struct upx_compress_result_t
|
|||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
#include "util/snprintf.h" // must get included first!
|
#include "util/snprintf.h" // must get included first!
|
||||||
|
|
||||||
#include <exception>
|
|
||||||
#include <new>
|
|
||||||
#include <type_traits>
|
|
||||||
#include <typeinfo>
|
|
||||||
|
|
||||||
#include "options.h"
|
#include "options.h"
|
||||||
#include "except.h"
|
#include "except.h"
|
||||||
#include "bele.h"
|
#include "bele.h"
|
||||||
#include "console.h"
|
#include "console/console.h"
|
||||||
#include "util/util.h"
|
#include "util/util.h"
|
||||||
|
|
||||||
// classes
|
// classes
|
||||||
@@ -734,11 +826,9 @@ class MemBuffer;
|
|||||||
void *membuffer_get_void_ptr(MemBuffer &mb);
|
void *membuffer_get_void_ptr(MemBuffer &mb);
|
||||||
unsigned membuffer_get_size(MemBuffer &mb);
|
unsigned membuffer_get_size(MemBuffer &mb);
|
||||||
|
|
||||||
|
// xspan
|
||||||
#include "util/xspan.h"
|
#include "util/xspan.h"
|
||||||
|
|
||||||
//#define DOCTEST_CONFIG_DISABLE 1
|
|
||||||
#include <doctest/doctest/parts/doctest_fwd.h>
|
|
||||||
|
|
||||||
// util/dt_check.cpp
|
// util/dt_check.cpp
|
||||||
void upx_compiler_sanity_check();
|
void upx_compiler_sanity_check();
|
||||||
int upx_doctest_check();
|
int upx_doctest_check();
|
||||||
@@ -777,7 +867,7 @@ void show_license();
|
|||||||
void show_usage();
|
void show_usage();
|
||||||
void show_version(bool one_line=false);
|
void show_version(bool one_line=false);
|
||||||
|
|
||||||
// compress.cpp
|
// compress/compress.cpp
|
||||||
unsigned upx_adler32(const void *buf, unsigned len, unsigned adler=1);
|
unsigned upx_adler32(const void *buf, unsigned len, unsigned adler=1);
|
||||||
unsigned upx_crc32 (const void *buf, unsigned len, unsigned crc=0);
|
unsigned upx_crc32 (const void *buf, unsigned len, unsigned crc=0);
|
||||||
|
|
||||||
@@ -798,24 +888,6 @@ int upx_test_overlap ( const upx_bytep buf,
|
|||||||
int method,
|
int method,
|
||||||
const upx_compress_result_t *cresult );
|
const upx_compress_result_t *cresult );
|
||||||
|
|
||||||
/*************************************************************************
|
|
||||||
// raw_bytes() - get underlying memory from checked buffers/pointers.
|
|
||||||
// This is overloaded by various utility classes like BoundedPtr,
|
|
||||||
// MemBuffer and Span.
|
|
||||||
//
|
|
||||||
// Note that the pointer type is retained, the "_bytes" hints size_in_bytes
|
|
||||||
**************************************************************************/
|
|
||||||
|
|
||||||
// default: for any regular pointer, raw_bytes() is just the pointer itself
|
|
||||||
template <class T>
|
|
||||||
inline T *raw_bytes(T *ptr, size_t size_in_bytes) {
|
|
||||||
if (size_in_bytes > 0) {
|
|
||||||
if __acc_very_unlikely (ptr == nullptr)
|
|
||||||
throwInternalError("raw_bytes unexpected NULL ptr");
|
|
||||||
}
|
|
||||||
return ptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#if (ACC_OS_CYGWIN || ACC_OS_DOS16 || ACC_OS_DOS32 || ACC_OS_EMX || ACC_OS_OS2 || ACC_OS_OS216 || ACC_OS_WIN16 || ACC_OS_WIN32 || ACC_OS_WIN64)
|
#if (ACC_OS_CYGWIN || ACC_OS_DOS16 || ACC_OS_DOS32 || ACC_OS_EMX || ACC_OS_OS2 || ACC_OS_OS216 || ACC_OS_WIN16 || ACC_OS_WIN32 || ACC_OS_WIN64)
|
||||||
# if defined(INVALID_HANDLE_VALUE) || defined(MAKEWORD) || defined(RT_CURSOR)
|
# if defined(INVALID_HANDLE_VALUE) || defined(MAKEWORD) || defined(RT_CURSOR)
|
||||||
|
|||||||
@@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
This file is part of the UPX executable compressor.
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
Copyright (C) 1996-2022 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2022 Laszlo Molnar
|
Copyright (C) 1996-2023 Laszlo Molnar
|
||||||
All Rights Reserved.
|
All Rights Reserved.
|
||||||
|
|
||||||
UPX and the UCL library are free software; you can redistribute them
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
@@ -25,8 +25,7 @@
|
|||||||
<markus@oberhumer.com> <ezerotven+github@gmail.com>
|
<markus@oberhumer.com> <ezerotven+github@gmail.com>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include "../conf.h"
|
||||||
#include "conf.h"
|
|
||||||
|
|
||||||
#if (USE_CONSOLE)
|
#if (USE_CONSOLE)
|
||||||
|
|
||||||
@@ -34,58 +33,41 @@
|
|||||||
//
|
//
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
static int init(FILE *f, int o, int now)
|
static int init(FILE *f, int o, int now) {
|
||||||
{
|
|
||||||
UNUSED(f);
|
UNUSED(f);
|
||||||
UNUSED(o);
|
UNUSED(o);
|
||||||
UNUSED(now);
|
UNUSED(now);
|
||||||
return CON_FILE;
|
return CON_FILE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int set_fg(FILE *f, int fg) {
|
||||||
static int set_fg(FILE *f, int fg)
|
|
||||||
{
|
|
||||||
UNUSED(f);
|
UNUSED(f);
|
||||||
UNUSED(fg);
|
UNUSED(fg);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void print0(FILE *f, const char *s) {
|
||||||
static void print0(FILE *f, const char *s)
|
|
||||||
{
|
|
||||||
#if 1
|
#if 1
|
||||||
fputs(s, f);
|
fputs(s, f);
|
||||||
#else
|
#else
|
||||||
/* filter out all ANSI sequences */
|
/* filter out all ANSI sequences */
|
||||||
int c;
|
int c;
|
||||||
while ((c = *s++) != 0)
|
while ((c = *s++) != 0) {
|
||||||
{
|
if (c == '\033' && *s == ']') {
|
||||||
if (c == '\033' && *s == ']')
|
|
||||||
{
|
|
||||||
while (*s && *s != 'm')
|
while (*s && *s != 'm')
|
||||||
s++;
|
s++;
|
||||||
}
|
} else
|
||||||
else
|
|
||||||
fputc(c, f);
|
fputc(c, f);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool intro(FILE *f) {
|
||||||
static bool intro(FILE *f)
|
|
||||||
{
|
|
||||||
UNUSED(f);
|
UNUSED(f);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
console_t console_file = {init, set_fg, print0, intro};
|
||||||
console_t console_file =
|
|
||||||
{
|
|
||||||
init,
|
|
||||||
set_fg,
|
|
||||||
print0,
|
|
||||||
intro
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif /* USE_CONSOLE */
|
#endif /* USE_CONSOLE */
|
||||||
|
|
||||||
@@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
This file is part of the UPX executable compressor.
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
Copyright (C) 1996-2022 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2022 Laszlo Molnar
|
Copyright (C) 1996-2023 Laszlo Molnar
|
||||||
All Rights Reserved.
|
All Rights Reserved.
|
||||||
|
|
||||||
UPX and the UCL library are free software; you can redistribute them
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
@@ -25,8 +25,7 @@
|
|||||||
<markus@oberhumer.com> <ezerotven+github@gmail.com>
|
<markus@oberhumer.com> <ezerotven+github@gmail.com>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include "../conf.h"
|
||||||
#include "conf.h"
|
|
||||||
|
|
||||||
FILE *con_term = nullptr;
|
FILE *con_term = nullptr;
|
||||||
|
|
||||||
@@ -41,9 +40,7 @@ console_t * con = &console_init;
|
|||||||
|
|
||||||
int con_mode = CON_INIT;
|
int con_mode = CON_INIT;
|
||||||
|
|
||||||
|
static void try_init(console_t *c, FILE *f) {
|
||||||
static void try_init(console_t *c, FILE *f)
|
|
||||||
{
|
|
||||||
int k;
|
int k;
|
||||||
|
|
||||||
assert(c);
|
assert(c);
|
||||||
@@ -56,8 +53,7 @@ static void try_init(console_t *c, FILE *f)
|
|||||||
if (k != opt->console)
|
if (k != opt->console)
|
||||||
return;
|
return;
|
||||||
#endif
|
#endif
|
||||||
if (k > con_mode)
|
if (k > con_mode) {
|
||||||
{
|
|
||||||
con_mode = k;
|
con_mode = k;
|
||||||
con = c;
|
con = c;
|
||||||
con->init = nullptr;
|
con->init = nullptr;
|
||||||
@@ -70,9 +66,7 @@ static void try_init(console_t *c, FILE *f)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int do_init(FILE *f) {
|
||||||
static int do_init(FILE *f)
|
|
||||||
{
|
|
||||||
assert(con_mode == CON_INIT);
|
assert(con_mode == CON_INIT);
|
||||||
|
|
||||||
try_init(&console_none, f);
|
try_init(&console_none, f);
|
||||||
@@ -98,13 +92,11 @@ static int do_init(FILE *f)
|
|||||||
return con_mode;
|
return con_mode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
//
|
//
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
static int init(FILE *f, int o, int now)
|
static int init(FILE *f, int o, int now) {
|
||||||
{
|
|
||||||
if (con != me)
|
if (con != me)
|
||||||
return con_mode;
|
return con_mode;
|
||||||
assert(o == -1);
|
assert(o == -1);
|
||||||
@@ -114,36 +106,23 @@ static int init(FILE *f, int o, int now)
|
|||||||
return do_init(f);
|
return do_init(f);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int set_fg(FILE *f, int fg) {
|
||||||
static int set_fg(FILE *f, int fg)
|
|
||||||
{
|
|
||||||
if (con == me)
|
if (con == me)
|
||||||
init(f, -1, -1);
|
init(f, -1, -1);
|
||||||
assert(con != me);
|
assert(con != me);
|
||||||
return con->set_fg(f, fg);
|
return con->set_fg(f, fg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool intro(FILE *f) {
|
||||||
static bool intro(FILE *f)
|
|
||||||
{
|
|
||||||
if (con == me)
|
if (con == me)
|
||||||
init(f, -1, -1);
|
init(f, -1, -1);
|
||||||
assert(con != me);
|
assert(con != me);
|
||||||
return con->intro(f);
|
return con->intro(f);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
console_t console_init = {init, set_fg, nullptr, intro};
|
||||||
|
|
||||||
console_t console_init =
|
void con_fprintf(FILE *f, const char *format, ...) {
|
||||||
{
|
|
||||||
init,
|
|
||||||
set_fg,
|
|
||||||
nullptr,
|
|
||||||
intro
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
void con_fprintf(FILE *f, const char *format, ...)
|
|
||||||
{
|
|
||||||
va_list args;
|
va_list args;
|
||||||
char buf[80 * 25];
|
char buf[80 * 25];
|
||||||
|
|
||||||
@@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
This file is part of the UPX executable compressor.
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
Copyright (C) 1996-2022 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2022 Laszlo Molnar
|
Copyright (C) 1996-2023 Laszlo Molnar
|
||||||
All Rights Reserved.
|
All Rights Reserved.
|
||||||
|
|
||||||
UPX and the UCL library are free software; you can redistribute them
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
@@ -25,8 +25,7 @@
|
|||||||
<markus@oberhumer.com> <ezerotven+github@gmail.com>
|
<markus@oberhumer.com> <ezerotven+github@gmail.com>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include "../conf.h"
|
||||||
#include "conf.h"
|
|
||||||
|
|
||||||
#if (USE_CONSOLE)
|
#if (USE_CONSOLE)
|
||||||
|
|
||||||
@@ -34,44 +33,30 @@
|
|||||||
//
|
//
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
static int init(FILE *f, int o, int now)
|
static int init(FILE *f, int o, int now) {
|
||||||
{
|
|
||||||
UNUSED(f);
|
UNUSED(f);
|
||||||
UNUSED(o);
|
UNUSED(o);
|
||||||
UNUSED(now);
|
UNUSED(now);
|
||||||
return CON_NONE;
|
return CON_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int set_fg(FILE *f, int fg) {
|
||||||
static int set_fg(FILE *f, int fg)
|
|
||||||
{
|
|
||||||
UNUSED(f);
|
UNUSED(f);
|
||||||
UNUSED(fg);
|
UNUSED(fg);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void print0(FILE *f, const char *s) {
|
||||||
static void print0(FILE *f, const char *s)
|
|
||||||
{
|
|
||||||
UNUSED(f);
|
UNUSED(f);
|
||||||
UNUSED(s);
|
UNUSED(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool intro(FILE *f) {
|
||||||
static bool intro(FILE *f)
|
|
||||||
{
|
|
||||||
UNUSED(f);
|
UNUSED(f);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
console_t console_none = {init, set_fg, print0, intro};
|
||||||
console_t console_none =
|
|
||||||
{
|
|
||||||
init,
|
|
||||||
set_fg,
|
|
||||||
print0,
|
|
||||||
intro
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif /* USE_CONSOLE */
|
#endif /* USE_CONSOLE */
|
||||||
|
|
||||||
@@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
This file is part of the UPX executable compressor.
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
Copyright (C) 1996-2022 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2022 Laszlo Molnar
|
Copyright (C) 1996-2023 Laszlo Molnar
|
||||||
All Rights Reserved.
|
All Rights Reserved.
|
||||||
|
|
||||||
UPX and the UCL library are free software; you can redistribute them
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
@@ -25,8 +25,7 @@
|
|||||||
<markus@oberhumer.com> <ezerotven+github@gmail.com>
|
<markus@oberhumer.com> <ezerotven+github@gmail.com>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include "../conf.h"
|
||||||
#include "conf.h"
|
|
||||||
|
|
||||||
#if (USE_SCREEN)
|
#if (USE_SCREEN)
|
||||||
|
|
||||||
@@ -35,13 +34,11 @@
|
|||||||
#define mask_fg 0x0f
|
#define mask_fg 0x0f
|
||||||
#define mask_bg 0xf0
|
#define mask_bg 0xf0
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
//
|
//
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
static int do_init(screen_t *s, int fd)
|
static int do_init(screen_t *s, int fd) {
|
||||||
{
|
|
||||||
int fg, bg;
|
int fg, bg;
|
||||||
|
|
||||||
if (s->init(s, fd) != 0)
|
if (s->init(s, fd) != 0)
|
||||||
@@ -59,8 +56,7 @@ static int do_init(screen_t *s, int fd)
|
|||||||
if (fg == (bg >> 4))
|
if (fg == (bg >> 4))
|
||||||
return -1;
|
return -1;
|
||||||
if (bg != BG_BLACK)
|
if (bg != BG_BLACK)
|
||||||
if (!s->isMono(s))
|
if (!s->isMono(s)) {
|
||||||
{
|
|
||||||
/* return 0; */ /* we could emulate ANSI mono */
|
/* return 0; */ /* we could emulate ANSI mono */
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@@ -68,30 +64,24 @@ static int do_init(screen_t *s, int fd)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static screen_t *do_construct(screen_t *s, int fd) {
|
||||||
static screen_t *do_construct(screen_t *s, int fd)
|
|
||||||
{
|
|
||||||
if (!s)
|
if (!s)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
if (do_init(s,fd) != 0)
|
if (do_init(s, fd) != 0) {
|
||||||
{
|
|
||||||
s->destroy(s);
|
s->destroy(s);
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
//
|
//
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
static screen_t *screen = nullptr;
|
static screen_t *screen = nullptr;
|
||||||
|
|
||||||
static void __acc_cdecl_atexit do_destroy(void)
|
static void __acc_cdecl_atexit do_destroy(void) {
|
||||||
{
|
if (screen) {
|
||||||
if (screen)
|
|
||||||
{
|
|
||||||
if (screen->atExit)
|
if (screen->atExit)
|
||||||
screen->atExit();
|
screen->atExit();
|
||||||
screen->destroy(screen);
|
screen->destroy(screen);
|
||||||
@@ -99,16 +89,13 @@ static void __acc_cdecl_atexit do_destroy(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int mode = -1;
|
static int mode = -1;
|
||||||
static int init_fg = -1;
|
static int init_fg = -1;
|
||||||
static int init_bg = -1;
|
static int init_bg = -1;
|
||||||
static int cur_fg = -1;
|
static int cur_fg = -1;
|
||||||
static int cur_bg = -1;
|
static int cur_bg = -1;
|
||||||
|
|
||||||
|
static int init(FILE *f, int o, int now) {
|
||||||
static int init(FILE *f, int o, int now)
|
|
||||||
{
|
|
||||||
int fd = fileno(f);
|
int fd = fileno(f);
|
||||||
int n;
|
int n;
|
||||||
|
|
||||||
@@ -155,17 +142,14 @@ static int init(FILE *f, int o, int now)
|
|||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int set_fg(FILE *f, int fg) {
|
||||||
static int set_fg(FILE *f, int fg)
|
|
||||||
{
|
|
||||||
const int last_fg = cur_fg;
|
const int last_fg = cur_fg;
|
||||||
int f1 = fg & mask_fg;
|
int f1 = fg & mask_fg;
|
||||||
int f2 = init_fg & mask_fg;
|
int f2 = init_fg & mask_fg;
|
||||||
|
|
||||||
UNUSED(f);
|
UNUSED(f);
|
||||||
cur_fg = fg;
|
cur_fg = fg;
|
||||||
if (screen->isMono(screen))
|
if (screen->isMono(screen)) {
|
||||||
{
|
|
||||||
const int b = (init_bg & mask_bg) >> 4;
|
const int b = (init_bg & mask_bg) >> 4;
|
||||||
if (fg == -1) /* restore startup fg */
|
if (fg == -1) /* restore startup fg */
|
||||||
f1 = f2;
|
f1 = f2;
|
||||||
@@ -175,9 +159,7 @@ static int set_fg(FILE *f, int fg)
|
|||||||
f1 = (f2 == 0) ? 15 : 0;
|
f1 = (f2 == 0) ? 15 : 0;
|
||||||
else
|
else
|
||||||
f1 = (f2 == 0) ? 8 : 0;
|
f1 = (f2 == 0) ? 8 : 0;
|
||||||
}
|
} else if (con_mode == CON_ANSI_MONO && f1 != f2) {
|
||||||
else if (con_mode == CON_ANSI_MONO && f1 != f2)
|
|
||||||
{
|
|
||||||
f1 = f2 ^ 0x08;
|
f1 = f2 ^ 0x08;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -185,9 +167,7 @@ static int set_fg(FILE *f, int fg)
|
|||||||
return last_fg;
|
return last_fg;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void print0(FILE *f, const char *ss) {
|
||||||
static void print0(FILE *f, const char *ss)
|
|
||||||
{
|
|
||||||
int cx, cy;
|
int cx, cy;
|
||||||
int old_cx = 0, old_cy = 0;
|
int old_cx = 0, old_cy = 0;
|
||||||
const int sx = screen->getCols(screen);
|
const int sx = screen->getCols(screen);
|
||||||
@@ -200,54 +180,44 @@ static void print0(FILE *f, const char *ss)
|
|||||||
UNUSED(f);
|
UNUSED(f);
|
||||||
|
|
||||||
screen->getCursor(screen, &old_cx, &old_cy);
|
screen->getCursor(screen, &old_cx, &old_cy);
|
||||||
cx = old_cx; cy = old_cy;
|
cx = old_cx;
|
||||||
|
cy = old_cy;
|
||||||
|
|
||||||
for (pass = 0; pass < 2; pass++)
|
for (pass = 0; pass < 2; pass++) {
|
||||||
{
|
|
||||||
const char *s = ss;
|
const char *s = ss;
|
||||||
// char buffer for pass 2
|
// char buffer for pass 2
|
||||||
char p[256 + 1];
|
char p[256 + 1];
|
||||||
int pi = 0, px = 0, py = 0;
|
int pi = 0, px = 0, py = 0;
|
||||||
|
|
||||||
for (;;)
|
for (;;) {
|
||||||
{
|
|
||||||
// walk over whitespace
|
// walk over whitespace
|
||||||
for (;;)
|
for (;;) {
|
||||||
{
|
if (*s == '\n') {
|
||||||
if (*s == '\n')
|
|
||||||
{
|
|
||||||
cx = 0;
|
cx = 0;
|
||||||
cy++;
|
cy++;
|
||||||
}
|
} else if (*s == '\r') {
|
||||||
else if (*s == '\r')
|
|
||||||
{
|
|
||||||
cx = 0;
|
cx = 0;
|
||||||
if (pass > 0 && cy < sy)
|
if (pass > 0 && cy < sy)
|
||||||
screen->clearLine(screen, cy);
|
screen->clearLine(screen, cy);
|
||||||
}
|
} else
|
||||||
else
|
|
||||||
break;
|
break;
|
||||||
s++;
|
s++;
|
||||||
}
|
}
|
||||||
// adjust cursor
|
// adjust cursor
|
||||||
if (cx >= sx)
|
if (cx >= sx) {
|
||||||
{
|
|
||||||
cx = 0;
|
cx = 0;
|
||||||
cy++;
|
cy++;
|
||||||
}
|
}
|
||||||
if (pass > 0)
|
if (pass > 0) {
|
||||||
{
|
|
||||||
// check if we should print something
|
// check if we should print something
|
||||||
if (pi > 0 && (*s == 0 || py != cy))
|
if (pi > 0 && (*s == 0 || py != cy)) {
|
||||||
{
|
|
||||||
p[pi] = 0;
|
p[pi] = 0;
|
||||||
screen->putString(screen, p, px, py);
|
screen->putString(screen, p, px, py);
|
||||||
pi = 0;
|
pi = 0;
|
||||||
}
|
}
|
||||||
// check if we should scroll even more (this can happen
|
// check if we should scroll even more (this can happen
|
||||||
// if the string is longer than sy lines)
|
// if the string is longer than sy lines)
|
||||||
if (cy >= sy)
|
if (cy >= sy) {
|
||||||
{
|
|
||||||
int scroll_y = cy - sy + 1;
|
int scroll_y = cy - sy + 1;
|
||||||
screen->scrollUp(screen, scroll_y);
|
screen->scrollUp(screen, scroll_y);
|
||||||
cy -= scroll_y;
|
cy -= scroll_y;
|
||||||
@@ -258,11 +228,9 @@ static void print0(FILE *f, const char *ss)
|
|||||||
// done ?
|
// done ?
|
||||||
if (*s == 0)
|
if (*s == 0)
|
||||||
break;
|
break;
|
||||||
if (pass > 0)
|
if (pass > 0) {
|
||||||
{
|
|
||||||
// store current char
|
// store current char
|
||||||
if (pi == 0)
|
if (pi == 0) {
|
||||||
{
|
|
||||||
px = cx;
|
px = cx;
|
||||||
py = cy;
|
py = cy;
|
||||||
}
|
}
|
||||||
@@ -273,18 +241,15 @@ static void print0(FILE *f, const char *ss)
|
|||||||
s++;
|
s++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pass == 0)
|
if (pass == 0) {
|
||||||
{
|
|
||||||
// end of pass 1 - scroll up, restore cursor
|
// end of pass 1 - scroll up, restore cursor
|
||||||
if (cy >= sy)
|
if (cy >= sy) {
|
||||||
{
|
|
||||||
int scroll_y = cy - sy + 1;
|
int scroll_y = cy - sy + 1;
|
||||||
screen->scrollUp(screen, scroll_y);
|
screen->scrollUp(screen, scroll_y);
|
||||||
cy = old_cy - scroll_y;
|
cy = old_cy - scroll_y;
|
||||||
if (cy < 0)
|
if (cy < 0)
|
||||||
cy = 0;
|
cy = 0;
|
||||||
}
|
} else
|
||||||
else
|
|
||||||
cy = old_cy;
|
cy = old_cy;
|
||||||
cx = old_cx;
|
cx = old_cx;
|
||||||
}
|
}
|
||||||
@@ -294,9 +259,7 @@ static void print0(FILE *f, const char *ss)
|
|||||||
screen->refresh(screen);
|
screen->refresh(screen);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool intro(FILE *f) {
|
||||||
static bool intro(FILE *f)
|
|
||||||
{
|
|
||||||
UNUSED(f);
|
UNUSED(f);
|
||||||
#if (USE_FRAMES)
|
#if (USE_FRAMES)
|
||||||
if (screen->intro)
|
if (screen->intro)
|
||||||
@@ -305,15 +268,7 @@ static bool intro(FILE *f)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
console_t console_screen = {init, set_fg, print0, intro};
|
||||||
console_t console_screen =
|
|
||||||
{
|
|
||||||
init,
|
|
||||||
set_fg,
|
|
||||||
print0,
|
|
||||||
intro
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
#endif /* USE_SCREEN */
|
#endif /* USE_SCREEN */
|
||||||
|
|
||||||
@@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
This file is part of the UPX executable compressor.
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
Copyright (C) 1996-2022 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2022 Laszlo Molnar
|
Copyright (C) 1996-2023 Laszlo Molnar
|
||||||
All Rights Reserved.
|
All Rights Reserved.
|
||||||
|
|
||||||
UPX and the UCL library are free software; you can redistribute them
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
@@ -25,7 +25,7 @@
|
|||||||
<markus@oberhumer.com> <ezerotven+github@gmail.com>
|
<markus@oberhumer.com> <ezerotven+github@gmail.com>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
//
|
//
|
||||||
@@ -64,9 +64,10 @@
|
|||||||
#elif 1 && (ACC_OS_EMX && defined(__RSXNT__))
|
#elif 1 && (ACC_OS_EMX && defined(__RSXNT__))
|
||||||
#define USE_SCREEN 1
|
#define USE_SCREEN 1
|
||||||
#define USE_SCREEN_WIN32 1
|
#define USE_SCREEN_WIN32 1
|
||||||
|
#elif 1 && (ACC_ARCH_M68K && ACC_OS_TOS)
|
||||||
|
#define NO_CONSOLE 1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#if 0 || (NO_ANSI)
|
#if 0 || (NO_ANSI)
|
||||||
#undef USE_ANSI
|
#undef USE_ANSI
|
||||||
#endif
|
#endif
|
||||||
@@ -80,7 +81,6 @@
|
|||||||
#undef USE_FRAMES
|
#undef USE_FRAMES
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#if 0 || (USE_ANSI) || (USE_SCREEN)
|
#if 0 || (USE_ANSI) || (USE_SCREEN)
|
||||||
#define USE_CONSOLE 1
|
#define USE_CONSOLE 1
|
||||||
#endif
|
#endif
|
||||||
@@ -94,37 +94,23 @@
|
|||||||
#undef USE_FRAMES
|
#undef USE_FRAMES
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
//
|
//
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
enum {
|
enum { CON_INIT, CON_NONE, CON_FILE, CON_ANSI_MONO, CON_ANSI_COLOR, CON_SCREEN, CON_UNUSED };
|
||||||
CON_INIT,
|
|
||||||
CON_NONE,
|
|
||||||
CON_FILE,
|
|
||||||
CON_ANSI_MONO,
|
|
||||||
CON_ANSI_COLOR,
|
|
||||||
CON_SCREEN,
|
|
||||||
CON_UNUSED
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
#if (USE_CONSOLE)
|
#if (USE_CONSOLE)
|
||||||
|
|
||||||
typedef struct
|
typedef struct {
|
||||||
{
|
|
||||||
int (*init)(FILE *f, int, int);
|
int (*init)(FILE *f, int, int);
|
||||||
int (*set_fg)(FILE *f, int fg);
|
int (*set_fg)(FILE *f, int fg);
|
||||||
void (*print0)(FILE *f, const char *s);
|
void (*print0)(FILE *f, const char *s);
|
||||||
bool (*intro)(FILE *f);
|
bool (*intro)(FILE *f);
|
||||||
}
|
} console_t;
|
||||||
console_t;
|
|
||||||
|
|
||||||
|
|
||||||
void con_fprintf(FILE *f, const char *format, ...) attribute_format(2, 3);
|
void con_fprintf(FILE *f, const char *format, ...) attribute_format(2, 3);
|
||||||
|
|
||||||
|
|
||||||
#define FG_BLACK 0x00
|
#define FG_BLACK 0x00
|
||||||
#define FG_BLUE 0x01
|
#define FG_BLUE 0x01
|
||||||
#define FG_GREEN 0x02
|
#define FG_GREEN 0x02
|
||||||
@@ -153,7 +139,6 @@ void con_fprintf(FILE *f, const char *format, ...) attribute_format(2, 3);
|
|||||||
|
|
||||||
#endif /* USE_CONSOLE */
|
#endif /* USE_CONSOLE */
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
//
|
//
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
@@ -172,7 +157,6 @@ extern console_t console_ansi_mono;
|
|||||||
extern console_t console_ansi_color;
|
extern console_t console_ansi_color;
|
||||||
extern console_t console_screen;
|
extern console_t console_screen;
|
||||||
|
|
||||||
|
|
||||||
#define con_fg(f, x) con->set_fg(f, x)
|
#define con_fg(f, x) con->set_fg(f, x)
|
||||||
|
|
||||||
#else
|
#else
|
||||||
@@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
This file is part of the UPX executable compressor.
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
Copyright (C) 1996-2022 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2022 Laszlo Molnar
|
Copyright (C) 1996-2023 Laszlo Molnar
|
||||||
All Rights Reserved.
|
All Rights Reserved.
|
||||||
|
|
||||||
UPX and the UCL library are free software; you can redistribute them
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
@@ -25,7 +25,7 @@
|
|||||||
<markus@oberhumer.com> <ezerotven+github@gmail.com>
|
<markus@oberhumer.com> <ezerotven+github@gmail.com>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "conf.h"
|
#include "../conf.h"
|
||||||
|
|
||||||
#if (USE_SCREEN) && (ACC_OS_DOS32) && defined(__DJGPP__)
|
#if (USE_SCREEN) && (ACC_OS_DOS32) && defined(__DJGPP__)
|
||||||
#if (ACC_CC_GNUC >= 0x040300ul)
|
#if (ACC_CC_GNUC >= 0x040300ul)
|
||||||
@@ -81,7 +81,9 @@ struct screen_data_t {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/* atExit information */
|
/* atExit information */
|
||||||
static struct { int cursor_shape; } ae = {-1};
|
static struct {
|
||||||
|
int cursor_shape;
|
||||||
|
} ae = {-1};
|
||||||
|
|
||||||
#if USE_SCROLLBACK
|
#if USE_SCROLLBACK
|
||||||
static __inline__ void sb_add(screen_t *this, int *val, int inc) {
|
static __inline__ void sb_add(screen_t *this, int *val, int inc) {
|
||||||
@@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
This file is part of the UPX executable compressor.
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
Copyright (C) 1996-2022 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2022 Laszlo Molnar
|
Copyright (C) 1996-2023 Laszlo Molnar
|
||||||
All Rights Reserved.
|
All Rights Reserved.
|
||||||
|
|
||||||
UPX and the UCL library are free software; you can redistribute them
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
@@ -25,7 +25,7 @@
|
|||||||
<markus@oberhumer.com> <ezerotven+github@gmail.com>
|
<markus@oberhumer.com> <ezerotven+github@gmail.com>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "conf.h"
|
#include "../conf.h"
|
||||||
|
|
||||||
#if (USE_SCREEN)
|
#if (USE_SCREEN)
|
||||||
|
|
||||||
@@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
This file is part of the UPX executable compressor.
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
Copyright (C) 1996-2022 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2022 Laszlo Molnar
|
Copyright (C) 1996-2023 Laszlo Molnar
|
||||||
All Rights Reserved.
|
All Rights Reserved.
|
||||||
|
|
||||||
UPX and the UCL library are free software; you can redistribute them
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
@@ -25,7 +25,7 @@
|
|||||||
<markus@oberhumer.com> <ezerotven+github@gmail.com>
|
<markus@oberhumer.com> <ezerotven+github@gmail.com>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "conf.h"
|
#include "../conf.h"
|
||||||
|
|
||||||
#if (USE_SCREEN) && (USE_SCREEN_VCSA)
|
#if (USE_SCREEN) && (USE_SCREEN_VCSA)
|
||||||
|
|
||||||
@@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
This file is part of the UPX executable compressor.
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
Copyright (C) 1996-2022 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2022 Laszlo Molnar
|
Copyright (C) 1996-2023 Laszlo Molnar
|
||||||
All Rights Reserved.
|
All Rights Reserved.
|
||||||
|
|
||||||
UPX and the UCL library are free software; you can redistribute them
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
@@ -25,7 +25,7 @@
|
|||||||
<markus@oberhumer.com> <ezerotven+github@gmail.com>
|
<markus@oberhumer.com> <ezerotven+github@gmail.com>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "conf.h"
|
#include "../conf.h"
|
||||||
|
|
||||||
#if (USE_SCREEN_WIN32)
|
#if (USE_SCREEN_WIN32)
|
||||||
|
|
||||||
@@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
This file is part of the UPX executable compressor.
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
Copyright (C) 1996-2022 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2022 Laszlo Molnar
|
Copyright (C) 1996-2023 Laszlo Molnar
|
||||||
All Rights Reserved.
|
All Rights Reserved.
|
||||||
|
|
||||||
UPX and the UCL library are free software; you can redistribute them
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
@@ -25,8 +25,9 @@
|
|||||||
<markus@oberhumer.com> <ezerotven+github@gmail.com>
|
<markus@oberhumer.com> <ezerotven+github@gmail.com>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __UPX_SCREEN_H
|
#pragma once
|
||||||
#define __UPX_SCREEN_H 1
|
#ifndef UPX_SCREEN_H__
|
||||||
|
#define UPX_SCREEN_H__ 1
|
||||||
|
|
||||||
#if (USE_SCREEN)
|
#if (USE_SCREEN)
|
||||||
|
|
||||||
+2
-2
@@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
This file is part of the UPX executable compressor.
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
Copyright (C) 1996-2022 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2022 Laszlo Molnar
|
Copyright (C) 1996-2023 Laszlo Molnar
|
||||||
All Rights Reserved.
|
All Rights Reserved.
|
||||||
|
|
||||||
UPX and the UCL library are free software; you can redistribute them
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
|
|||||||
+2
-2
@@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
This file is part of the UPX executable compressor.
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
Copyright (C) 1996-2022 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2022 Laszlo Molnar
|
Copyright (C) 1996-2023 Laszlo Molnar
|
||||||
All Rights Reserved.
|
All Rights Reserved.
|
||||||
|
|
||||||
UPX and the UCL library are free software; you can redistribute them
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
|
|||||||
+7
-4
@@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
This file is part of the UPX executable compressor.
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
Copyright (C) 1996-2022 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2022 Laszlo Molnar
|
Copyright (C) 1996-2023 Laszlo Molnar
|
||||||
All Rights Reserved.
|
All Rights Reserved.
|
||||||
|
|
||||||
UPX and the UCL library are free software; you can redistribute them
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
@@ -117,6 +117,7 @@ void FileBase::closex() {
|
|||||||
throwIOException("close failed", errno);
|
throwIOException("close failed", errno);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Return value of ::seek is the resulting file offset (same as ::tell())
|
||||||
upx_off_t FileBase::seek(upx_off_t off, int whence) {
|
upx_off_t FileBase::seek(upx_off_t off, int whence) {
|
||||||
if (!isOpen())
|
if (!isOpen())
|
||||||
throwIOException("bad seek 1");
|
throwIOException("bad seek 1");
|
||||||
@@ -132,9 +133,11 @@ upx_off_t FileBase::seek(upx_off_t off, int whence) {
|
|||||||
off += _offset + _length;
|
off += _offset + _length;
|
||||||
whence = SEEK_SET;
|
whence = SEEK_SET;
|
||||||
}
|
}
|
||||||
if (::lseek(_fd, off, whence) < 0)
|
// SEEK_CUR falls through to here
|
||||||
|
upx_off_t rv = ::lseek(_fd, off, whence);
|
||||||
|
if (rv < 0)
|
||||||
throwIOException("seek error", errno);
|
throwIOException("seek error", errno);
|
||||||
return off - _offset;
|
return rv - _offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
upx_off_t FileBase::tell() const {
|
upx_off_t FileBase::tell() const {
|
||||||
|
|||||||
+2
-2
@@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
This file is part of the UPX executable compressor.
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
Copyright (C) 1996-2022 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2022 Laszlo Molnar
|
Copyright (C) 1996-2023 Laszlo Molnar
|
||||||
All Rights Reserved.
|
All Rights Reserved.
|
||||||
|
|
||||||
UPX and the UCL library are free software; you can redistribute them
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
|
|||||||
+25
-47
@@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
This file is part of the UPX executable compressor.
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
Copyright (C) 1996-2022 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2022 Laszlo Molnar
|
Copyright (C) 1996-2023 Laszlo Molnar
|
||||||
All Rights Reserved.
|
All Rights Reserved.
|
||||||
|
|
||||||
UPX and the UCL library are free software; you can redistribute them
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
@@ -25,42 +25,34 @@
|
|||||||
<markus@oberhumer.com> <ezerotven+github@gmail.com>
|
<markus@oberhumer.com> <ezerotven+github@gmail.com>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#include "conf.h"
|
#include "conf.h"
|
||||||
#include "filter.h"
|
#include "filter.h"
|
||||||
#include "file.h"
|
#include "file.h"
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
// util
|
// util
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
static //inline
|
static void initFilter(Filter *f, upx_byte *buf, unsigned buf_len) {
|
||||||
void initFilter(Filter *f, upx_byte *buf, unsigned buf_len)
|
|
||||||
{
|
|
||||||
f->buf = buf;
|
f->buf = buf;
|
||||||
f->buf_len = buf_len;
|
f->buf_len = buf_len;
|
||||||
// clear output parameters
|
// clear output parameters
|
||||||
f->calls = f->wrongcalls = f->noncalls = f->firstcall = f->lastcall = 0;
|
f->calls = f->wrongcalls = f->noncalls = f->firstcall = f->lastcall = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
// get a FilterEntry
|
// get a FilterEntry
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
const FilterImp::FilterEntry *FilterImp::getFilter(int id)
|
const FilterImpl::FilterEntry *FilterImpl::getFilter(int id) {
|
||||||
{
|
|
||||||
static bool done = false;
|
static bool done = false;
|
||||||
static unsigned char filter_map[256];
|
static unsigned char filter_map[256];
|
||||||
|
|
||||||
if (!done)
|
if (!done) {
|
||||||
{
|
|
||||||
// init the filter_map[]
|
// init the filter_map[]
|
||||||
assert(n_filters <= 254); // as 0xff means "empty slot"
|
assert(n_filters <= 254); // as 0xff means "empty slot"
|
||||||
memset(filter_map, 0xff, sizeof(filter_map));
|
memset(filter_map, 0xff, sizeof(filter_map));
|
||||||
for (int i = 0; i < n_filters; i++)
|
for (int i = 0; i < n_filters; i++) {
|
||||||
{
|
|
||||||
int filter_id = filters[i].id;
|
int filter_id = filters[i].id;
|
||||||
assert(filter_id >= 0 && filter_id <= 255);
|
assert(filter_id >= 0 && filter_id <= 255);
|
||||||
assert(filter_map[filter_id] == 0xff);
|
assert(filter_map[filter_id] == 0xff);
|
||||||
@@ -78,15 +70,12 @@ const FilterImp::FilterEntry *FilterImp::getFilter(int id)
|
|||||||
return &filters[index];
|
return &filters[index];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Filter::isValidFilter(int filter_id) {
|
||||||
bool Filter::isValidFilter(int filter_id)
|
const FilterImpl::FilterEntry *const fe = FilterImpl::getFilter(filter_id);
|
||||||
{
|
|
||||||
const FilterImp::FilterEntry * const fe = FilterImp::getFilter(filter_id);
|
|
||||||
return fe != nullptr;
|
return fe != nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Filter::isValidFilter(int filter_id, const int *allowed_filters)
|
bool Filter::isValidFilter(int filter_id, const int *allowed_filters) {
|
||||||
{
|
|
||||||
if (!isValidFilter(filter_id))
|
if (!isValidFilter(filter_id))
|
||||||
return false;
|
return false;
|
||||||
if (filter_id == 0)
|
if (filter_id == 0)
|
||||||
@@ -99,13 +88,11 @@ bool Filter::isValidFilter(int filter_id, const int *allowed_filters)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
// high level API
|
// high level API
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
void Filter::init(int id_, unsigned addvalue_)
|
void Filter::init(int id_, unsigned addvalue_) {
|
||||||
{
|
|
||||||
this->id = id_;
|
this->id = id_;
|
||||||
initFilter(this, nullptr, 0);
|
initFilter(this, nullptr, 0);
|
||||||
// clear input parameters
|
// clear input parameters
|
||||||
@@ -116,12 +103,10 @@ void Filter::init(int id_, unsigned addvalue_)
|
|||||||
this->n_mru = 0;
|
this->n_mru = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Filter::filter(upx_byte *buf_, unsigned buf_len_) {
|
||||||
bool Filter::filter(upx_byte *buf_, unsigned buf_len_)
|
|
||||||
{
|
|
||||||
initFilter(this, buf_, buf_len_);
|
initFilter(this, buf_, buf_len_);
|
||||||
|
|
||||||
const FilterImp::FilterEntry * const fe = FilterImp::getFilter(id);
|
const FilterImpl::FilterEntry *const fe = FilterImpl::getFilter(id);
|
||||||
if (fe == nullptr)
|
if (fe == nullptr)
|
||||||
throwInternalError("filter-1");
|
throwInternalError("filter-1");
|
||||||
if (fe->id == 0)
|
if (fe->id == 0)
|
||||||
@@ -138,10 +123,10 @@ bool Filter::filter(upx_byte *buf_, unsigned buf_len_)
|
|||||||
if (clevel != 1)
|
if (clevel != 1)
|
||||||
this->adler = upx_adler32(this->buf, this->buf_len);
|
this->adler = upx_adler32(this->buf, this->buf_len);
|
||||||
|
|
||||||
//printf("filter: %02x %p %d\n", this->id, this->buf, this->buf_len);
|
NO_printf("filter: %02x %p %d\n", this->id, this->buf, this->buf_len);
|
||||||
// OutputFile::dump("filter.dat", buf, buf_len);
|
// OutputFile::dump("filter.dat", buf, buf_len);
|
||||||
int r = (*fe->do_filter)(this);
|
int r = (*fe->do_filter)(this);
|
||||||
//printf("filter: %02x %d\n", fe->id, r);
|
NO_printf("filter: %02x %d\n", fe->id, r);
|
||||||
if (r > 0)
|
if (r > 0)
|
||||||
throwFilterException();
|
throwFilterException();
|
||||||
if (r == 0)
|
if (r == 0)
|
||||||
@@ -149,12 +134,10 @@ bool Filter::filter(upx_byte *buf_, unsigned buf_len_)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Filter::unfilter(upx_byte *buf_, unsigned buf_len_, bool verify_checksum) {
|
||||||
void Filter::unfilter(upx_byte *buf_, unsigned buf_len_, bool verify_checksum)
|
|
||||||
{
|
|
||||||
initFilter(this, buf_, buf_len_);
|
initFilter(this, buf_, buf_len_);
|
||||||
|
|
||||||
const FilterImp::FilterEntry * const fe = FilterImp::getFilter(id);
|
const FilterImpl::FilterEntry *const fe = FilterImpl::getFilter(id);
|
||||||
if (fe == nullptr)
|
if (fe == nullptr)
|
||||||
throwInternalError("unfilter-1");
|
throwInternalError("unfilter-1");
|
||||||
if (fe->id == 0)
|
if (fe->id == 0)
|
||||||
@@ -166,24 +149,21 @@ void Filter::unfilter(upx_byte *buf_, unsigned buf_len_, bool verify_checksum)
|
|||||||
if (!fe->do_unfilter)
|
if (!fe->do_unfilter)
|
||||||
throwInternalError("unfilter-2");
|
throwInternalError("unfilter-2");
|
||||||
|
|
||||||
//printf("unfilter: %02x %p %d\n", this->id, this->buf, this->buf_len);
|
NO_printf("unfilter: %02x %p %d\n", this->id, this->buf, this->buf_len);
|
||||||
int r = (*fe->do_unfilter)(this);
|
int r = (*fe->do_unfilter)(this);
|
||||||
//printf("unfilter: %02x %d\n", fe->id, r);
|
NO_printf("unfilter: %02x %d\n", fe->id, r);
|
||||||
if (r != 0)
|
if (r != 0)
|
||||||
throwInternalError("unfilter-3");
|
throwInternalError("unfilter-3");
|
||||||
// OutputFile::dump("unfilter.dat", buf, buf_len);
|
// OutputFile::dump("unfilter.dat", buf, buf_len);
|
||||||
|
|
||||||
// verify checksum
|
// verify checksum
|
||||||
if (verify_checksum && clevel != 1)
|
if (verify_checksum && clevel != 1) {
|
||||||
{
|
|
||||||
if (this->adler != upx_adler32(this->buf, this->buf_len))
|
if (this->adler != upx_adler32(this->buf, this->buf_len))
|
||||||
throwInternalError("unfilter-4");
|
throwInternalError("unfilter-4");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Filter::verifyUnfilter() {
|
||||||
void Filter::verifyUnfilter()
|
|
||||||
{
|
|
||||||
// Note:
|
// Note:
|
||||||
// This verify is just because of complete paranoia that there
|
// This verify is just because of complete paranoia that there
|
||||||
// could be a hidden bug in the filter implementation, and
|
// could be a hidden bug in the filter implementation, and
|
||||||
@@ -193,20 +173,18 @@ void Filter::verifyUnfilter()
|
|||||||
// See also:
|
// See also:
|
||||||
// Packer::verifyOverlappingDecompression()
|
// Packer::verifyOverlappingDecompression()
|
||||||
|
|
||||||
//printf("verifyUnfilter: %02x %p %d\n", this->id, this->buf, this->buf_len);
|
NO_printf("verifyUnfilter: %02x %p %d\n", this->id, this->buf, this->buf_len);
|
||||||
if (clevel != 1)
|
if (clevel != 1)
|
||||||
unfilter(this->buf, this->buf_len, true);
|
unfilter(this->buf, this->buf_len, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Filter::scan(const upx_byte *buf_, unsigned buf_len_) {
|
||||||
bool Filter::scan(const upx_byte *buf_, unsigned buf_len_)
|
|
||||||
{
|
|
||||||
// Note: must use const_cast here. This is fine as the scan
|
// Note: must use const_cast here. This is fine as the scan
|
||||||
// implementations (fe->do_scan) actually don't change the buffer.
|
// implementations (fe->do_scan) actually don't change the buffer.
|
||||||
upx_byte *b = const_cast<upx_byte *>(buf_);
|
upx_byte *b = const_cast<upx_byte *>(buf_);
|
||||||
initFilter(this, b, buf_len_);
|
initFilter(this, b, buf_len_);
|
||||||
|
|
||||||
const FilterImp::FilterEntry * const fe = FilterImp::getFilter(id);
|
const FilterImpl::FilterEntry *const fe = FilterImpl::getFilter(id);
|
||||||
if (fe == nullptr)
|
if (fe == nullptr)
|
||||||
throwInternalError("scan-1");
|
throwInternalError("scan-1");
|
||||||
if (fe->id == 0)
|
if (fe->id == 0)
|
||||||
@@ -218,9 +196,9 @@ bool Filter::scan(const upx_byte *buf_, unsigned buf_len_)
|
|||||||
if (!fe->do_scan)
|
if (!fe->do_scan)
|
||||||
throwInternalError("scan-2");
|
throwInternalError("scan-2");
|
||||||
|
|
||||||
//printf("filter: %02x %p %d\n", this->id, this->buf, this->buf_len);
|
NO_printf("filter: %02x %p %d\n", this->id, this->buf, this->buf_len);
|
||||||
int r = (*fe->do_scan)(this);
|
int r = (*fe->do_scan)(this);
|
||||||
//printf("filter: %02x %d\n", fe->id, r);
|
NO_printf("filter: %02x %d\n", fe->id, r);
|
||||||
if (r > 0)
|
if (r > 0)
|
||||||
throwFilterException();
|
throwFilterException();
|
||||||
if (r == 0)
|
if (r == 0)
|
||||||
|
|||||||
+12
-18
@@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
This file is part of the UPX executable compressor.
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
Copyright (C) 1996-2022 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2022 Laszlo Molnar
|
Copyright (C) 1996-2023 Laszlo Molnar
|
||||||
All Rights Reserved.
|
All Rights Reserved.
|
||||||
|
|
||||||
UPX and the UCL library are free software; you can redistribute them
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
@@ -25,13 +25,9 @@
|
|||||||
<markus@oberhumer.com> <ezerotven+github@gmail.com>
|
<markus@oberhumer.com> <ezerotven+github@gmail.com>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
#ifndef __UPX_FILTER_H
|
#ifndef UPX_FILTER_H__
|
||||||
#define __UPX_FILTER_H 1
|
#define UPX_FILTER_H__ 1
|
||||||
|
|
||||||
class Filter;
|
|
||||||
class FilterImp;
|
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
// A filter is a reversible operation that modifies a given
|
// A filter is a reversible operation that modifies a given
|
||||||
@@ -50,10 +46,12 @@ class FilterImp;
|
|||||||
// to absolute addresses so that the buffer compresses better.
|
// to absolute addresses so that the buffer compresses better.
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
class Filter
|
class Filter {
|
||||||
{
|
|
||||||
public:
|
public:
|
||||||
Filter(int level) { clevel = level; init(); }
|
Filter(int level) {
|
||||||
|
clevel = level;
|
||||||
|
init();
|
||||||
|
}
|
||||||
void init(int id = 0, unsigned addvalue = 0);
|
void init(int id = 0, unsigned addvalue = 0);
|
||||||
|
|
||||||
bool filter(upx_byte *buf, unsigned buf_len);
|
bool filter(upx_byte *buf, unsigned buf_len);
|
||||||
@@ -96,7 +94,6 @@ private:
|
|||||||
int clevel; // compression level
|
int clevel; // compression level
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
// We don't want a full OO interface here because of
|
// We don't want a full OO interface here because of
|
||||||
// certain implementation speed reasons.
|
// certain implementation speed reasons.
|
||||||
@@ -104,13 +101,11 @@ private:
|
|||||||
// This class is private to Filter - don't look.
|
// This class is private to Filter - don't look.
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
class FilterImp
|
class FilterImpl {
|
||||||
{
|
|
||||||
friend class Filter;
|
friend class Filter;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct FilterEntry
|
struct FilterEntry {
|
||||||
{
|
|
||||||
int id; // 0 .. 255
|
int id; // 0 .. 255
|
||||||
unsigned min_buf_len;
|
unsigned min_buf_len;
|
||||||
unsigned max_buf_len;
|
unsigned max_buf_len;
|
||||||
@@ -128,7 +123,6 @@ private:
|
|||||||
static const int n_filters; // number of filters[]
|
static const int n_filters; // number of filters[]
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
#endif /* already included */
|
#endif /* already included */
|
||||||
|
|
||||||
/* vim:set ts=4 sw=4 et: */
|
/* vim:set ts=4 sw=4 et: */
|
||||||
|
|||||||
+2
-2
@@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
This file is part of the UPX executable compressor.
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
Copyright (C) 1996-2022 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2022 Laszlo Molnar
|
Copyright (C) 1996-2023 Laszlo Molnar
|
||||||
All Rights Reserved.
|
All Rights Reserved.
|
||||||
|
|
||||||
UPX and the UCL library are free software; you can redistribute them
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
|
|||||||
+2
-2
@@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
This file is part of the UPX executable compressor.
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
Copyright (C) 1996-2022 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2022 Laszlo Molnar
|
Copyright (C) 1996-2023 Laszlo Molnar
|
||||||
All Rights Reserved.
|
All Rights Reserved.
|
||||||
|
|
||||||
UPX and the UCL library are free software; you can redistribute them
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
|
|||||||
+3
-3
@@ -2,9 +2,9 @@
|
|||||||
|
|
||||||
This file is part of the UPX executable compressor.
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
Copyright (C) 1996-2022 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2022 Laszlo Molnar
|
Copyright (C) 1996-2023 Laszlo Molnar
|
||||||
Copyright (C) 2000-2022 John F. Reiser
|
Copyright (C) 2000-2023 John F. Reiser
|
||||||
All Rights Reserved.
|
All Rights Reserved.
|
||||||
|
|
||||||
UPX and the UCL library are free software; you can redistribute them
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
|
|||||||
+3
-3
@@ -2,9 +2,9 @@
|
|||||||
|
|
||||||
This file is part of the UPX executable compressor.
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
Copyright (C) 1996-2022 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2022 Laszlo Molnar
|
Copyright (C) 1996-2023 Laszlo Molnar
|
||||||
Copyright (C) 2000-2022 John F. Reiser
|
Copyright (C) 2000-2023 John F. Reiser
|
||||||
All Rights Reserved.
|
All Rights Reserved.
|
||||||
|
|
||||||
UPX and the UCL library are free software; you can redistribute them
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
|
|||||||
+3
-3
@@ -2,9 +2,9 @@
|
|||||||
|
|
||||||
This file is part of the UPX executable compressor.
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
Copyright (C) 1996-2022 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2022 Laszlo Molnar
|
Copyright (C) 1996-2023 Laszlo Molnar
|
||||||
Copyright (C) 2000-2022 John F. Reiser
|
Copyright (C) 2000-2023 John F. Reiser
|
||||||
All Rights Reserved.
|
All Rights Reserved.
|
||||||
|
|
||||||
UPX and the UCL library are free software; you can redistribute them
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
|
|||||||
+2
-2
@@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
This file is part of the UPX executable compressor.
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
Copyright (C) 1996-2022 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2022 Laszlo Molnar
|
Copyright (C) 1996-2023 Laszlo Molnar
|
||||||
All Rights Reserved.
|
All Rights Reserved.
|
||||||
|
|
||||||
UPX and the UCL library are free software; you can redistribute them
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
/* filteri.cpp -- filter implementation (low-level)
|
/* filter_impl.cpp -- filter implementation (low-level)
|
||||||
|
|
||||||
This file is part of the UPX executable compressor.
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
Copyright (C) 1996-2022 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2022 Laszlo Molnar
|
Copyright (C) 1996-2023 Laszlo Molnar
|
||||||
All Rights Reserved.
|
All Rights Reserved.
|
||||||
|
|
||||||
UPX and the UCL library are free software; you can redistribute them
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
@@ -26,8 +26,8 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#include "conf.h"
|
#include "../conf.h"
|
||||||
#include "filter.h"
|
#include "../filter.h"
|
||||||
|
|
||||||
static unsigned
|
static unsigned
|
||||||
umin(unsigned const a, unsigned const b)
|
umin(unsigned const a, unsigned const b)
|
||||||
@@ -45,20 +45,20 @@ umin(unsigned const a, unsigned const b)
|
|||||||
// util
|
// util
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
#include "filter/getcto.h"
|
#include "getcto.h"
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
// simple filters: calltrick / swaptrick / delta / ...
|
// simple filters: calltrick / swaptrick / delta / ...
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
#include "filter/ct.h"
|
#include "ct.h"
|
||||||
#include "filter/sw.h"
|
#include "sw.h"
|
||||||
#include "filter/ctsw.h"
|
#include "ctsw.h"
|
||||||
|
|
||||||
#include "filter/sub8.h"
|
#include "sub8.h"
|
||||||
#include "filter/sub16.h"
|
#include "sub16.h"
|
||||||
#include "filter/sub32.h"
|
#include "sub32.h"
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
@@ -68,25 +68,25 @@ umin(unsigned const a, unsigned const b)
|
|||||||
#define COND(b,x) (b[x] == 0xe8)
|
#define COND(b,x) (b[x] == 0xe8)
|
||||||
#define F f_cto32_e8_bswap_le
|
#define F f_cto32_e8_bswap_le
|
||||||
#define U u_cto32_e8_bswap_le
|
#define U u_cto32_e8_bswap_le
|
||||||
#include "filter/cto.h"
|
#include "cto.h"
|
||||||
#define F s_cto32_e8_bswap_le
|
#define F s_cto32_e8_bswap_le
|
||||||
#include "filter/cto.h"
|
#include "cto.h"
|
||||||
#undef COND
|
#undef COND
|
||||||
|
|
||||||
#define COND(b,x) (b[x] == 0xe9)
|
#define COND(b,x) (b[x] == 0xe9)
|
||||||
#define F f_cto32_e9_bswap_le
|
#define F f_cto32_e9_bswap_le
|
||||||
#define U u_cto32_e9_bswap_le
|
#define U u_cto32_e9_bswap_le
|
||||||
#include "filter/cto.h"
|
#include "cto.h"
|
||||||
#define F s_cto32_e9_bswap_le
|
#define F s_cto32_e9_bswap_le
|
||||||
#include "filter/cto.h"
|
#include "cto.h"
|
||||||
#undef COND
|
#undef COND
|
||||||
|
|
||||||
#define COND(b,x) (b[x] == 0xe8 || b[x] == 0xe9)
|
#define COND(b,x) (b[x] == 0xe8 || b[x] == 0xe9)
|
||||||
#define F f_cto32_e8e9_bswap_le
|
#define F f_cto32_e8e9_bswap_le
|
||||||
#define U u_cto32_e8e9_bswap_le
|
#define U u_cto32_e8e9_bswap_le
|
||||||
#include "filter/cto.h"
|
#include "cto.h"
|
||||||
#define F s_cto32_e8e9_bswap_le
|
#define F s_cto32_e8e9_bswap_le
|
||||||
#include "filter/cto.h"
|
#include "cto.h"
|
||||||
#undef COND
|
#undef COND
|
||||||
|
|
||||||
|
|
||||||
@@ -97,9 +97,9 @@ umin(unsigned const a, unsigned const b)
|
|||||||
#define COND(b,x,lastcall) (b[x] == 0xe8 || b[x] == 0xe9)
|
#define COND(b,x,lastcall) (b[x] == 0xe8 || b[x] == 0xe9)
|
||||||
#define F f_ctoj32_e8e9_bswap_le
|
#define F f_ctoj32_e8e9_bswap_le
|
||||||
#define U u_ctoj32_e8e9_bswap_le
|
#define U u_ctoj32_e8e9_bswap_le
|
||||||
#include "filter/ctoj.h"
|
#include "ctoj.h"
|
||||||
#define F s_ctoj32_e8e9_bswap_le
|
#define F s_ctoj32_e8e9_bswap_le
|
||||||
#include "filter/ctoj.h"
|
#include "ctoj.h"
|
||||||
#undef COND
|
#undef COND
|
||||||
|
|
||||||
|
|
||||||
@@ -112,9 +112,9 @@ umin(unsigned const a, unsigned const b)
|
|||||||
#define COND(b,x,lc,id) (COND1(b,x) || ((9<=(0xf&(id))) && COND2(b,x,lc)))
|
#define COND(b,x,lc,id) (COND1(b,x) || ((9<=(0xf&(id))) && COND2(b,x,lc)))
|
||||||
#define F f_ctok32_e8e9_bswap_le
|
#define F f_ctok32_e8e9_bswap_le
|
||||||
#define U u_ctok32_e8e9_bswap_le
|
#define U u_ctok32_e8e9_bswap_le
|
||||||
#include "filter/ctok.h"
|
#include "ctok.h"
|
||||||
#define F s_ctok32_e8e9_bswap_le
|
#define F s_ctok32_e8e9_bswap_le
|
||||||
#include "filter/ctok.h"
|
#include "ctok.h"
|
||||||
#undef COND
|
#undef COND
|
||||||
#undef COND2
|
#undef COND2
|
||||||
#undef COND1
|
#undef COND1
|
||||||
@@ -138,9 +138,9 @@ umin(unsigned const a, unsigned const b)
|
|||||||
|
|
||||||
#define F f_ctojr32_e8e9_bswap_le
|
#define F f_ctojr32_e8e9_bswap_le
|
||||||
#define U u_ctojr32_e8e9_bswap_le
|
#define U u_ctojr32_e8e9_bswap_le
|
||||||
#include "filter/ctojr.h"
|
#include "ctojr.h"
|
||||||
#define F s_ctojr32_e8e9_bswap_le
|
#define F s_ctojr32_e8e9_bswap_le
|
||||||
#include "filter/ctojr.h"
|
#include "ctojr.h"
|
||||||
|
|
||||||
#undef CONDU
|
#undef CONDU
|
||||||
#undef CONDF
|
#undef CONDF
|
||||||
@@ -158,9 +158,9 @@ umin(unsigned const a, unsigned const b)
|
|||||||
#define COND(b,x) (18==(get_be32(b+x)>>26))
|
#define COND(b,x) (18==(get_be32(b+x)>>26))
|
||||||
#define F f_ppcbxx
|
#define F f_ppcbxx
|
||||||
#define U u_ppcbxx
|
#define U u_ppcbxx
|
||||||
#include "filter/ppcbxx.h"
|
#include "ppcbxx.h"
|
||||||
#define F s_ppcbxx
|
#define F s_ppcbxx
|
||||||
#include "filter/ppcbxx.h"
|
#include "ppcbxx.h"
|
||||||
#undef COND
|
#undef COND
|
||||||
|
|
||||||
|
|
||||||
@@ -168,7 +168,7 @@ umin(unsigned const a, unsigned const b)
|
|||||||
// database for use in class Filter
|
// database for use in class Filter
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
const FilterImp::FilterEntry FilterImp::filters[] = {
|
const FilterImpl::FilterEntry FilterImpl::filters[] = {
|
||||||
// no filter
|
// no filter
|
||||||
{ 0x00, 0, 0, nullptr, nullptr, nullptr },
|
{ 0x00, 0, 0, nullptr, nullptr, nullptr },
|
||||||
|
|
||||||
@@ -261,6 +261,6 @@ const FilterImp::FilterEntry FilterImp::filters[] = {
|
|||||||
{ 0xd0, 8, 0, f_ppcbxx, u_ppcbxx, s_ppcbxx },
|
{ 0xd0, 8, 0, f_ppcbxx, u_ppcbxx, s_ppcbxx },
|
||||||
};
|
};
|
||||||
|
|
||||||
const int FilterImp::n_filters = TABLESIZE(filters);
|
const int FilterImpl::n_filters = TABLESIZE(filters);
|
||||||
|
|
||||||
/* vim:set ts=4 sw=4 et: */
|
/* vim:set ts=4 sw=4 et: */
|
||||||
+2
-2
@@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
This file is part of the UPX executable compressor.
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
Copyright (C) 1996-2022 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2022 Laszlo Molnar
|
Copyright (C) 1996-2023 Laszlo Molnar
|
||||||
All Rights Reserved.
|
All Rights Reserved.
|
||||||
|
|
||||||
UPX and the UCL library are free software; you can redistribute them
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
|
|||||||
+3
-3
@@ -2,9 +2,9 @@
|
|||||||
|
|
||||||
This file is part of the UPX executable compressor.
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
Copyright (C) 1996-2022 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2022 Laszlo Molnar
|
Copyright (C) 1996-2023 Laszlo Molnar
|
||||||
Copyright (C) 2004-2022 John F. Reiser
|
Copyright (C) 2004-2023 John F. Reiser
|
||||||
All Rights Reserved.
|
All Rights Reserved.
|
||||||
|
|
||||||
UPX and the UCL library are free software; you can redistribute them
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
|
|||||||
+2
-2
@@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
This file is part of the UPX executable compressor.
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
Copyright (C) 1996-2022 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2022 Laszlo Molnar
|
Copyright (C) 1996-2023 Laszlo Molnar
|
||||||
All Rights Reserved.
|
All Rights Reserved.
|
||||||
|
|
||||||
UPX and the UCL library are free software; you can redistribute them
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
|
|||||||
+2
-2
@@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
This file is part of the UPX executable compressor.
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
Copyright (C) 1996-2022 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2022 Laszlo Molnar
|
Copyright (C) 1996-2023 Laszlo Molnar
|
||||||
All Rights Reserved.
|
All Rights Reserved.
|
||||||
|
|
||||||
UPX and the UCL library are free software; you can redistribute them
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
|
|||||||
+2
-2
@@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
This file is part of the UPX executable compressor.
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
Copyright (C) 1996-2022 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2022 Laszlo Molnar
|
Copyright (C) 1996-2023 Laszlo Molnar
|
||||||
All Rights Reserved.
|
All Rights Reserved.
|
||||||
|
|
||||||
UPX and the UCL library are free software; you can redistribute them
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
|
|||||||
+2
-2
@@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
This file is part of the UPX executable compressor.
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
Copyright (C) 1996-2022 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2022 Laszlo Molnar
|
Copyright (C) 1996-2023 Laszlo Molnar
|
||||||
All Rights Reserved.
|
All Rights Reserved.
|
||||||
|
|
||||||
UPX and the UCL library are free software; you can redistribute them
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
|
|||||||
+2
-2
@@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
This file is part of the UPX executable compressor.
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
Copyright (C) 1996-2022 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2022 Laszlo Molnar
|
Copyright (C) 1996-2023 Laszlo Molnar
|
||||||
All Rights Reserved.
|
All Rights Reserved.
|
||||||
|
|
||||||
UPX and the UCL library are free software; you can redistribute them
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
|
|||||||
+23
-11
@@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
This file is part of the UPX executable compressor.
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
Copyright (C) 1996-2022 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2022 Laszlo Molnar
|
Copyright (C) 1996-2023 Laszlo Molnar
|
||||||
All Rights Reserved.
|
All Rights Reserved.
|
||||||
|
|
||||||
UPX and the UCL library are free software; you can redistribute them
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
@@ -27,9 +27,9 @@
|
|||||||
|
|
||||||
|
|
||||||
#include "conf.h"
|
#include "conf.h"
|
||||||
#include "compress.h"
|
|
||||||
#include "packmast.h"
|
#include "packmast.h"
|
||||||
#include "packer.h"
|
#include "packer.h"
|
||||||
|
#include "compress/compress.h" // upx_ucl_version_string()
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
@@ -38,6 +38,7 @@
|
|||||||
|
|
||||||
static bool head_done = 0;
|
static bool head_done = 0;
|
||||||
|
|
||||||
|
// also see UPX_CONFIG_DISABLE_GITREV in CMakeLists.txt
|
||||||
#if defined(UPX_VERSION_GITREV)
|
#if defined(UPX_VERSION_GITREV)
|
||||||
const char gitrev[] = UPX_VERSION_GITREV;
|
const char gitrev[] = UPX_VERSION_GITREV;
|
||||||
#else
|
#else
|
||||||
@@ -381,11 +382,13 @@ void show_version(bool one_line)
|
|||||||
FILE *fp = stdout;
|
FILE *fp = stdout;
|
||||||
const char *v;
|
const char *v;
|
||||||
|
|
||||||
fprintf(fp, "upx %s\n", UPX_VERSION_STRING
|
#if defined(UPX_VERSION_GIT_DESCRIBE)
|
||||||
#if defined(UPX_VERSION_GITREV)
|
fprintf(fp, "upx %s\n", UPX_VERSION_GIT_DESCRIBE);
|
||||||
"-git-" UPX_VERSION_GITREV
|
#elif defined(UPX_VERSION_GITREV)
|
||||||
|
fprintf(fp, "upx %s\n", UPX_VERSION_STRING "-git-" UPX_VERSION_GITREV);
|
||||||
|
#else
|
||||||
|
fprintf(fp, "upx %s\n", UPX_VERSION_STRING);
|
||||||
#endif
|
#endif
|
||||||
);
|
|
||||||
if (one_line)
|
if (one_line)
|
||||||
return;
|
return;
|
||||||
#if (WITH_NRV)
|
#if (WITH_NRV)
|
||||||
@@ -408,19 +411,28 @@ void show_version(bool one_line)
|
|||||||
if (v != nullptr && v[0])
|
if (v != nullptr && v[0])
|
||||||
fprintf(fp, "LZMA SDK version %s\n", v);
|
fprintf(fp, "LZMA SDK version %s\n", v);
|
||||||
#endif
|
#endif
|
||||||
|
#if (WITH_ZSTD)
|
||||||
|
v = upx_zstd_version_string();
|
||||||
|
if (v != nullptr && v[0])
|
||||||
|
fprintf(fp, "zstd data compression library %s\n", v);
|
||||||
|
#endif
|
||||||
#if !defined(DOCTEST_CONFIG_DISABLE)
|
#if !defined(DOCTEST_CONFIG_DISABLE)
|
||||||
fprintf(fp, "doctest C++ testing framework version %s\n", DOCTEST_VERSION_STR);
|
fprintf(fp, "doctest C++ testing framework version %s\n", DOCTEST_VERSION_STR);
|
||||||
#endif
|
#endif
|
||||||
fprintf(fp, "Copyright (C) 1996-2022 Markus Franz Xaver Johannes Oberhumer\n");
|
fprintf(fp, "Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer\n");
|
||||||
fprintf(fp, "Copyright (C) 1996-2022 Laszlo Molnar\n");
|
fprintf(fp, "Copyright (C) 1996-2023 Laszlo Molnar\n");
|
||||||
fprintf(fp, "Copyright (C) 2000-2022 John F. Reiser\n");
|
fprintf(fp, "Copyright (C) 2000-2023 John F. Reiser\n");
|
||||||
fprintf(fp, "Copyright (C) 2002-2022 Jens Medoch\n");
|
fprintf(fp, "Copyright (C) 2002-2023 Jens Medoch\n");
|
||||||
#if (WITH_ZLIB)
|
#if (WITH_ZLIB)
|
||||||
fprintf(fp, "Copyright (C) 1995" "-2022 Jean-loup Gailly and Mark Adler\n");
|
fprintf(fp, "Copyright (C) 1995" "-2022 Jean-loup Gailly and Mark Adler\n");
|
||||||
#endif
|
#endif
|
||||||
#if (WITH_LZMA)
|
#if (WITH_LZMA)
|
||||||
fprintf(fp, "Copyright (C) 1999" "-2006 Igor Pavlov\n");
|
fprintf(fp, "Copyright (C) 1999" "-2006 Igor Pavlov\n");
|
||||||
#endif
|
#endif
|
||||||
|
#if (WITH_ZSTD)
|
||||||
|
// see vendor/zstd/LICENSE; main author is Yann Collet
|
||||||
|
fprintf(fp, "Copyright (C) 2015" "-2023 Meta Platforms, Inc. and affiliates\n");
|
||||||
|
#endif
|
||||||
#if !defined(DOCTEST_CONFIG_DISABLE)
|
#if !defined(DOCTEST_CONFIG_DISABLE)
|
||||||
fprintf(fp, "Copyright (C) 2016" "-2021 Viktor Kirilov\n");
|
fprintf(fp, "Copyright (C) 2016" "-2021 Viktor Kirilov\n");
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
+44
-107
@@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
This file is part of the UPX executable compressor.
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
Copyright (C) 1996-2022 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2022 Laszlo Molnar
|
Copyright (C) 1996-2023 Laszlo Molnar
|
||||||
All Rights Reserved.
|
All Rights Reserved.
|
||||||
|
|
||||||
UPX and the UCL library are free software; you can redistribute them
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
@@ -25,34 +25,20 @@
|
|||||||
<markus@oberhumer.com> <ezerotven+github@gmail.com>
|
<markus@oberhumer.com> <ezerotven+github@gmail.com>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#include "conf.h"
|
#include "conf.h"
|
||||||
#include "file.h"
|
#include "file.h"
|
||||||
#include "util/membuffer.h"
|
#include "util/membuffer.h"
|
||||||
#include "lefile.h"
|
#include "lefile.h"
|
||||||
|
|
||||||
|
LeFile::LeFile(InputFile *f) : fif(f), fof(nullptr), le_offset(0), exe_offset(0) {
|
||||||
LeFile::LeFile(InputFile *f) :
|
COMPILE_TIME_ASSERT(sizeof(le_header_t) == 196)
|
||||||
fif(f), fof(nullptr),
|
COMPILE_TIME_ASSERT(sizeof(le_object_table_entry_t) == 24)
|
||||||
le_offset(0), exe_offset(0)
|
COMPILE_TIME_ASSERT(sizeof(le_pagemap_entry_t) == 4)
|
||||||
{
|
|
||||||
COMPILE_TIME_ASSERT(sizeof(le_header_t) == 196);
|
|
||||||
COMPILE_TIME_ASSERT(sizeof(le_object_table_entry_t) == 24);
|
|
||||||
COMPILE_TIME_ASSERT(sizeof(le_pagemap_entry_t) == 4);
|
|
||||||
memset(&ih, 0, sizeof ih);
|
memset(&ih, 0, sizeof ih);
|
||||||
memset(&oh, 0, sizeof oh);
|
memset(&oh, 0, sizeof oh);
|
||||||
iobject_table = oobject_table = nullptr;
|
|
||||||
ifpage_table = ofpage_table = nullptr;
|
|
||||||
ipm_entries = opm_entries = nullptr;
|
|
||||||
ires_names = ores_names = nullptr;
|
|
||||||
ifixups = ofixups = nullptr;
|
|
||||||
inonres_names = ononres_names = nullptr;
|
|
||||||
ientries = oentries = nullptr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LeFile::~LeFile() {
|
||||||
LeFile::~LeFile()
|
|
||||||
{
|
|
||||||
delete[] iobject_table;
|
delete[] iobject_table;
|
||||||
delete[] oobject_table;
|
delete[] oobject_table;
|
||||||
delete[] ifpage_table;
|
delete[] ifpage_table;
|
||||||
@@ -69,30 +55,23 @@ LeFile::~LeFile()
|
|||||||
delete[] oentries;
|
delete[] oentries;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#define objects ih.object_table_entries
|
#define objects ih.object_table_entries
|
||||||
#define pages ih.memory_pages
|
#define pages ih.memory_pages
|
||||||
#define mps ih.memory_page_size
|
#define mps ih.memory_page_size
|
||||||
|
|
||||||
|
void LeFile::readObjectTable() {
|
||||||
void LeFile::readObjectTable()
|
|
||||||
{
|
|
||||||
soobject_table = objects;
|
soobject_table = objects;
|
||||||
iobject_table = New(le_object_table_entry_t, soobject_table);
|
iobject_table = New(le_object_table_entry_t, soobject_table);
|
||||||
fif->seek(le_offset + ih.object_table_offset, SEEK_SET);
|
fif->seek(le_offset + ih.object_table_offset, SEEK_SET);
|
||||||
fif->readx(iobject_table, sizeof(*iobject_table) * objects);
|
fif->readx(iobject_table, sizeof(*iobject_table) * objects);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void LeFile::writeObjectTable() {
|
||||||
void LeFile::writeObjectTable()
|
|
||||||
{
|
|
||||||
if (fof && oobject_table)
|
if (fof && oobject_table)
|
||||||
fof->write(oobject_table, sizeof(*iobject_table) * soobject_table);
|
fof->write(oobject_table, sizeof(*iobject_table) * soobject_table);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void LeFile::readPageMap() {
|
||||||
void LeFile::readPageMap()
|
|
||||||
{
|
|
||||||
sopm_entries = pages;
|
sopm_entries = pages;
|
||||||
ipm_entries = New(le_pagemap_entry_t, sopm_entries);
|
ipm_entries = New(le_pagemap_entry_t, sopm_entries);
|
||||||
fif->seek(le_offset + ih.object_pagemap_offset, SEEK_SET);
|
fif->seek(le_offset + ih.object_pagemap_offset, SEEK_SET);
|
||||||
@@ -103,104 +82,80 @@ void LeFile::readPageMap()
|
|||||||
throwCantPack("unexpected value in page map table");
|
throwCantPack("unexpected value in page map table");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void LeFile::writePageMap() {
|
||||||
void LeFile::writePageMap()
|
|
||||||
{
|
|
||||||
if (fof && opm_entries)
|
if (fof && opm_entries)
|
||||||
fof->write(opm_entries, sizeof(*ipm_entries) * sopm_entries);
|
fof->write(opm_entries, sizeof(*ipm_entries) * sopm_entries);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void LeFile::readResidentNames() {
|
||||||
void LeFile::readResidentNames()
|
|
||||||
{
|
|
||||||
sores_names = ih.entry_table_offset - ih.resident_names_offset;
|
sores_names = ih.entry_table_offset - ih.resident_names_offset;
|
||||||
ires_names = New(upx_byte, sores_names);
|
ires_names = New(upx_byte, sores_names);
|
||||||
fif->seek(le_offset + ih.resident_names_offset, SEEK_SET);
|
fif->seek(le_offset + ih.resident_names_offset, SEEK_SET);
|
||||||
fif->readx(ires_names, sores_names);
|
fif->readx(ires_names, sores_names);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void LeFile::writeResidentNames() {
|
||||||
void LeFile::writeResidentNames()
|
|
||||||
{
|
|
||||||
if (fof && ores_names)
|
if (fof && ores_names)
|
||||||
fof->write(ores_names, sores_names);
|
fof->write(ores_names, sores_names);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void LeFile::readEntryTable() {
|
||||||
void LeFile::readEntryTable()
|
|
||||||
{
|
|
||||||
soentries = ih.fixup_page_table_offset - ih.entry_table_offset;
|
soentries = ih.fixup_page_table_offset - ih.entry_table_offset;
|
||||||
fif->seek(le_offset + ih.entry_table_offset, SEEK_SET);
|
fif->seek(le_offset + ih.entry_table_offset, SEEK_SET);
|
||||||
ientries = New(upx_byte, soentries);
|
ientries = New(upx_byte, soentries);
|
||||||
fif->readx(ientries, soentries);
|
fif->readx(ientries, soentries);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void LeFile::writeEntryTable() {
|
||||||
void LeFile::writeEntryTable()
|
|
||||||
{
|
|
||||||
if (fof && oentries)
|
if (fof && oentries)
|
||||||
fof->write(oentries, soentries);
|
fof->write(oentries, soentries);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void LeFile::readFixupPageTable() {
|
||||||
void LeFile::readFixupPageTable()
|
|
||||||
{
|
|
||||||
sofpage_table = 1 + pages;
|
sofpage_table = 1 + pages;
|
||||||
ifpage_table = New(unsigned, sofpage_table);
|
ifpage_table = New(unsigned, sofpage_table);
|
||||||
fif->seek(le_offset + ih.fixup_page_table_offset, SEEK_SET);
|
fif->seek(le_offset + ih.fixup_page_table_offset, SEEK_SET);
|
||||||
fif->readx(ifpage_table, 4 * sofpage_table);
|
fif->readx(ifpage_table, 4 * sofpage_table);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void LeFile::writeFixupPageTable() {
|
||||||
void LeFile::writeFixupPageTable()
|
|
||||||
{
|
|
||||||
if (fof && ofpage_table)
|
if (fof && ofpage_table)
|
||||||
fof->write(ofpage_table, 4 * sofpage_table);
|
fof->write(ofpage_table, 4 * sofpage_table);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void LeFile::readFixups() {
|
||||||
void LeFile::readFixups()
|
|
||||||
{
|
|
||||||
sofixups = get_le32(ifpage_table + pages) - get_le32(ifpage_table);
|
sofixups = get_le32(ifpage_table + pages) - get_le32(ifpage_table);
|
||||||
ifixups = New(upx_byte, sofixups);
|
ifixups = New(upx_byte, sofixups);
|
||||||
fif->seek(le_offset + ih.fixup_record_table_offset, SEEK_SET);
|
fif->seek(le_offset + ih.fixup_record_table_offset, SEEK_SET);
|
||||||
fif->readx(ifixups, sofixups);
|
fif->readx(ifixups, sofixups);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void LeFile::writeFixups() {
|
||||||
void LeFile::writeFixups()
|
|
||||||
{
|
|
||||||
if (fof && ofixups)
|
if (fof && ofixups)
|
||||||
fof->write(ofixups, sofixups);
|
fof->write(ofixups, sofixups);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsigned LeFile::getImageSize() const {
|
||||||
unsigned LeFile::getImageSize() const
|
|
||||||
{
|
|
||||||
unsigned n = 0;
|
unsigned n = 0;
|
||||||
if (ih.memory_pages > 0)
|
if (ih.memory_pages > 0) {
|
||||||
{
|
|
||||||
n = (ih.memory_pages - 1) * ih.memory_page_size;
|
n = (ih.memory_pages - 1) * ih.memory_page_size;
|
||||||
n += ih.bytes_on_last_page;
|
n += ih.bytes_on_last_page;
|
||||||
}
|
}
|
||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void LeFile::readImage() {
|
||||||
void LeFile::readImage()
|
|
||||||
{
|
|
||||||
soimage = pages * mps;
|
soimage = pages * mps;
|
||||||
mb_iimage.alloc(soimage);
|
mb_iimage.alloc(soimage);
|
||||||
mb_iimage.clear();
|
mb_iimage.clear();
|
||||||
iimage = mb_iimage;
|
iimage = mb_iimage;
|
||||||
|
|
||||||
unsigned ic, jc;
|
unsigned ic, jc;
|
||||||
for (ic = jc = 0; ic < pages; ic++)
|
for (ic = jc = 0; ic < pages; ic++) {
|
||||||
{
|
if ((ipm_entries[ic].type & 0xC0) == 0) {
|
||||||
if ((ipm_entries[ic].type & 0xC0) == 0)
|
|
||||||
{
|
|
||||||
fif->seek(ih.data_pages_offset + exe_offset +
|
fif->seek(ih.data_pages_offset + exe_offset +
|
||||||
(ipm_entries[ic].m*0x100 + ipm_entries[ic].l-1) * mps,SEEK_SET);
|
(ipm_entries[ic].m * 0x100 + ipm_entries[ic].l - 1) * mps,
|
||||||
|
SEEK_SET);
|
||||||
auto bytes = ic != pages - 1 ? mps : ih.bytes_on_last_page;
|
auto bytes = ic != pages - 1 ? mps : ih.bytes_on_last_page;
|
||||||
fif->readx(raw_bytes(iimage + jc, bytes), bytes);
|
fif->readx(raw_bytes(iimage + jc, bytes), bytes);
|
||||||
}
|
}
|
||||||
@@ -208,18 +163,13 @@ void LeFile::readImage()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void LeFile::writeImage() {
|
||||||
void LeFile::writeImage()
|
|
||||||
{
|
|
||||||
if (fof && oimage != nullptr)
|
if (fof && oimage != nullptr)
|
||||||
fof->write(raw_bytes(oimage, soimage), soimage);
|
fof->write(raw_bytes(oimage, soimage), soimage);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void LeFile::readNonResidentNames() {
|
||||||
void LeFile::readNonResidentNames()
|
if (ih.non_resident_name_table_length) {
|
||||||
{
|
|
||||||
if (ih.non_resident_name_table_length)
|
|
||||||
{
|
|
||||||
sononres_names = ih.non_resident_name_table_length;
|
sononres_names = ih.non_resident_name_table_length;
|
||||||
inonres_names = New(upx_byte, sononres_names);
|
inonres_names = New(upx_byte, sononres_names);
|
||||||
fif->seek(exe_offset + ih.non_resident_name_table_offset, SEEK_SET);
|
fif->seek(exe_offset + ih.non_resident_name_table_offset, SEEK_SET);
|
||||||
@@ -227,42 +177,34 @@ void LeFile::readNonResidentNames()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void LeFile::writeNonResidentNames() {
|
||||||
void LeFile::writeNonResidentNames()
|
|
||||||
{
|
|
||||||
if (fof && ononres_names)
|
if (fof && ononres_names)
|
||||||
fof->write(ononres_names, sononres_names);
|
fof->write(ononres_names, sononres_names);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool LeFile::readFileHeader() {
|
||||||
bool LeFile::readFileHeader()
|
|
||||||
{
|
|
||||||
#define H(x) get_le16(header + 2 * (x))
|
#define H(x) get_le16(header + 2 * (x))
|
||||||
upx_byte header[0x40];
|
upx_byte header[0x40];
|
||||||
le_offset = exe_offset = 0;
|
le_offset = exe_offset = 0;
|
||||||
int ic;
|
int ic;
|
||||||
|
|
||||||
for (ic = 0; ic < 20; ic++)
|
for (ic = 0; ic < 20; ic++) {
|
||||||
{
|
|
||||||
fif->seek(le_offset, SEEK_SET);
|
fif->seek(le_offset, SEEK_SET);
|
||||||
fif->readx(header, sizeof(header));
|
fif->readx(header, sizeof(header));
|
||||||
|
|
||||||
if (memcmp(header, "MZ", 2) == 0) // normal dos exe
|
if (memcmp(header, "MZ", 2) == 0) // normal dos exe
|
||||||
{
|
{
|
||||||
exe_offset = le_offset;
|
exe_offset = le_offset;
|
||||||
if (H(0x18/2) >= 0x40
|
if (H(0x18 / 2) >= 0x40 && memcmp(header + 0x19, "TIPPACH", 7)) // new format exe
|
||||||
&& memcmp(header+0x19,"TIPPACH",7)) // new format exe
|
|
||||||
le_offset += H(0x3c / 2) + H(0x3e / 2) * 65536;
|
le_offset += H(0x3c / 2) + H(0x3e / 2) * 65536;
|
||||||
else
|
else {
|
||||||
{
|
|
||||||
le_offset += H(2) * 512 + H(1);
|
le_offset += H(2) * 512 + H(1);
|
||||||
if (H(1))
|
if (H(1))
|
||||||
le_offset -= 512;
|
le_offset -= 512;
|
||||||
else if (H(2) == 0)
|
else if (H(2) == 0)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
} else if (memcmp(header, "BW", 2) == 0) // used in dos4gw.exe
|
||||||
else if (memcmp(header,"BW",2) == 0) // used in dos4gw.exe
|
|
||||||
le_offset += H(2) * 512 + H(1);
|
le_offset += H(2) * 512 + H(1);
|
||||||
else if (memcmp(header, "LE", 2) == 0)
|
else if (memcmp(header, "LE", 2) == 0)
|
||||||
break;
|
break;
|
||||||
@@ -279,11 +221,10 @@ bool LeFile::readFileHeader()
|
|||||||
#undef H
|
#undef H
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void LeFile::writeFile(OutputFile *f, bool le) {
|
||||||
void LeFile::writeFile(OutputFile *f, bool le)
|
|
||||||
{
|
|
||||||
fof = f;
|
fof = f;
|
||||||
memcpy (&oh,&ih,(char*)&oh.memory_pages-(char*)&oh); // copy some members of the orig. header
|
memcpy(&oh, &ih,
|
||||||
|
(char *) &oh.memory_pages - (char *) &oh); // copy some members of the orig. header
|
||||||
oh.memory_page_size = mps;
|
oh.memory_page_size = mps;
|
||||||
oh.object_table_offset = sizeof(oh);
|
oh.object_table_offset = sizeof(oh);
|
||||||
oh.object_table_entries = soobject_table;
|
oh.object_table_entries = soobject_table;
|
||||||
@@ -294,9 +235,9 @@ void LeFile::writeFile(OutputFile *f, bool le)
|
|||||||
oh.fixup_record_table_offset = oh.fixup_page_table_offset + sofpage_table * 4;
|
oh.fixup_record_table_offset = oh.fixup_page_table_offset + sofpage_table * 4;
|
||||||
oh.imported_modules_name_table_offset = oh.fixup_record_table_offset + sofixups - FIXUP_EXTRA;
|
oh.imported_modules_name_table_offset = oh.fixup_record_table_offset + sofixups - FIXUP_EXTRA;
|
||||||
oh.imported_procedures_name_table_offset = oh.imported_modules_name_table_offset;
|
oh.imported_procedures_name_table_offset = oh.imported_modules_name_table_offset;
|
||||||
oh.data_pages_offset = oh.fixup_record_table_offset + sofixups + (le ? 0 : le_offset-exe_offset);
|
oh.data_pages_offset =
|
||||||
if (ih.non_resident_name_table_length)
|
oh.fixup_record_table_offset + sofixups + (le ? 0 : le_offset - exe_offset);
|
||||||
{
|
if (ih.non_resident_name_table_length) {
|
||||||
oh.non_resident_name_table_offset = oh.data_pages_offset + soimage;
|
oh.non_resident_name_table_offset = oh.data_pages_offset + soimage;
|
||||||
oh.non_resident_name_table_length = sononres_names;
|
oh.non_resident_name_table_length = sononres_names;
|
||||||
}
|
}
|
||||||
@@ -314,9 +255,7 @@ void LeFile::writeFile(OutputFile *f, bool le)
|
|||||||
writeNonResidentNames();
|
writeNonResidentNames();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void LeFile::countFixups(unsigned *counts) const {
|
||||||
void LeFile::countFixups(unsigned *counts) const
|
|
||||||
{
|
|
||||||
const unsigned o = objects;
|
const unsigned o = objects;
|
||||||
memset(counts, 0, sizeof(unsigned) * (o + 2));
|
memset(counts, 0, sizeof(unsigned) * (o + 2));
|
||||||
// counts[0..objects-1] - # of 32-bit offset relocations in for that objects
|
// counts[0..objects-1] - # of 32-bit offset relocations in for that objects
|
||||||
@@ -327,12 +266,10 @@ void LeFile::countFixups(unsigned *counts) const
|
|||||||
const unsigned sfixups = get_le32(ifpage_table + pages);
|
const unsigned sfixups = get_le32(ifpage_table + pages);
|
||||||
unsigned ll;
|
unsigned ll;
|
||||||
|
|
||||||
while ((unsigned)(fix - ifixups) < sfixups)
|
while (ptr_udiff_bytes(fix, ifixups) < sfixups) {
|
||||||
{
|
|
||||||
if ((fix[1] & ~0x10) != 0)
|
if ((fix[1] & ~0x10) != 0)
|
||||||
throwCantPack("unsupported fixup record");
|
throwCantPack("unsupported fixup record");
|
||||||
switch (*fix)
|
switch (*fix) {
|
||||||
{
|
|
||||||
case 2: // selector fixup
|
case 2: // selector fixup
|
||||||
counts[o] += 9;
|
counts[o] += 9;
|
||||||
fix += 5;
|
fix += 5;
|
||||||
|
|||||||
+40
-34
@@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
This file is part of the UPX executable compressor.
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
Copyright (C) 1996-2022 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2022 Laszlo Molnar
|
Copyright (C) 1996-2023 Laszlo Molnar
|
||||||
All Rights Reserved.
|
All Rights Reserved.
|
||||||
|
|
||||||
UPX and the UCL library are free software; you can redistribute them
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
@@ -25,20 +25,18 @@
|
|||||||
<markus@oberhumer.com> <ezerotven+github@gmail.com>
|
<markus@oberhumer.com> <ezerotven+github@gmail.com>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
#ifndef __UPX_LEFILE_H
|
#ifndef UPX_LEFILE_H__
|
||||||
#define __UPX_LEFILE_H 1
|
#define UPX_LEFILE_H__ 1
|
||||||
|
|
||||||
class InputFile;
|
class InputFile;
|
||||||
class OutputFile;
|
class OutputFile;
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
//
|
//
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
class LeFile
|
class LeFile {
|
||||||
{
|
|
||||||
protected:
|
protected:
|
||||||
LeFile(InputFile *);
|
LeFile(InputFile *);
|
||||||
virtual ~LeFile();
|
virtual ~LeFile();
|
||||||
@@ -49,7 +47,7 @@ protected:
|
|||||||
protected:
|
protected:
|
||||||
enum { FIXUP_EXTRA = 3 };
|
enum { FIXUP_EXTRA = 3 };
|
||||||
|
|
||||||
__packed_struct(le_header_t)
|
struct alignas(1) le_header_t {
|
||||||
// 0x00
|
// 0x00
|
||||||
char _[2]; // signature: 'LE' || 'LX'
|
char _[2]; // signature: 'LE' || 'LX'
|
||||||
char byte_order; // 0 little endian
|
char byte_order; // 0 little endian
|
||||||
@@ -117,23 +115,23 @@ protected:
|
|||||||
LE16 device_id;
|
LE16 device_id;
|
||||||
LE16 ddk_version;
|
LE16 ddk_version;
|
||||||
#endif
|
#endif
|
||||||
__packed_struct_end()
|
};
|
||||||
|
|
||||||
__packed_struct(le_object_table_entry_t)
|
struct alignas(1) le_object_table_entry_t {
|
||||||
LE32 virtual_size;
|
LE32 virtual_size;
|
||||||
LE32 base_address;
|
LE32 base_address;
|
||||||
LE32 flags;
|
LE32 flags;
|
||||||
LE32 pagemap_index;
|
LE32 pagemap_index;
|
||||||
LE32 npages;
|
LE32 npages;
|
||||||
LE32 reserved;
|
LE32 reserved;
|
||||||
__packed_struct_end()
|
};
|
||||||
|
|
||||||
__packed_struct(le_pagemap_entry_t)
|
struct alignas(1) le_pagemap_entry_t {
|
||||||
unsigned char h;
|
unsigned char h;
|
||||||
unsigned char m;
|
unsigned char m;
|
||||||
unsigned char l;
|
unsigned char l;
|
||||||
unsigned char type; // 0x00-legal;0x40-iterated;0x80-invalid;0xC0-zeroed
|
unsigned char type; // 0x00-legal;0x40-iterated;0x80-invalid;0xC0-zeroed
|
||||||
__packed_struct_end()
|
};
|
||||||
|
|
||||||
virtual void readObjectTable();
|
virtual void readObjectTable();
|
||||||
virtual void writeObjectTable();
|
virtual void writeObjectTable();
|
||||||
@@ -147,17 +145,26 @@ protected:
|
|||||||
|
|
||||||
virtual void readPageMap();
|
virtual void readPageMap();
|
||||||
virtual void writePageMap();
|
virtual void writePageMap();
|
||||||
virtual void encodePageMap(){opm_entries = ipm_entries; ipm_entries = nullptr;}
|
virtual void encodePageMap() {
|
||||||
|
opm_entries = ipm_entries;
|
||||||
|
ipm_entries = nullptr;
|
||||||
|
}
|
||||||
virtual void decodePageMap() { encodePageMap(); }
|
virtual void decodePageMap() { encodePageMap(); }
|
||||||
|
|
||||||
virtual void readResidentNames();
|
virtual void readResidentNames();
|
||||||
virtual void writeResidentNames();
|
virtual void writeResidentNames();
|
||||||
virtual void encodeResidentNames(){ores_names = ires_names; ires_names = nullptr;}
|
virtual void encodeResidentNames() {
|
||||||
|
ores_names = ires_names;
|
||||||
|
ires_names = nullptr;
|
||||||
|
}
|
||||||
virtual void decodeResidentNames() { encodeResidentNames(); }
|
virtual void decodeResidentNames() { encodeResidentNames(); }
|
||||||
|
|
||||||
virtual void readNonResidentNames();
|
virtual void readNonResidentNames();
|
||||||
virtual void writeNonResidentNames();
|
virtual void writeNonResidentNames();
|
||||||
virtual void encodeNonResidentNames(){ononres_names = inonres_names; inonres_names = nullptr;}
|
virtual void encodeNonResidentNames() {
|
||||||
|
ononres_names = inonres_names;
|
||||||
|
inonres_names = nullptr;
|
||||||
|
}
|
||||||
virtual void decodeNonResidentNames() { encodeNonResidentNames(); }
|
virtual void decodeNonResidentNames() { encodeNonResidentNames(); }
|
||||||
|
|
||||||
virtual void readEntryTable();
|
virtual void readEntryTable();
|
||||||
@@ -178,32 +185,32 @@ protected:
|
|||||||
void countFixups(unsigned *) const;
|
void countFixups(unsigned *) const;
|
||||||
unsigned getImageSize() const;
|
unsigned getImageSize() const;
|
||||||
|
|
||||||
InputFile *fif;
|
InputFile *fif = nullptr;
|
||||||
OutputFile *fof;
|
OutputFile *fof = nullptr;
|
||||||
unsigned le_offset;
|
unsigned le_offset;
|
||||||
unsigned exe_offset;
|
unsigned exe_offset;
|
||||||
|
|
||||||
le_header_t ih;
|
le_header_t ih;
|
||||||
le_header_t oh;
|
le_header_t oh;
|
||||||
|
|
||||||
le_object_table_entry_t *iobject_table;
|
le_object_table_entry_t *iobject_table = nullptr;
|
||||||
le_object_table_entry_t *oobject_table;
|
le_object_table_entry_t *oobject_table = nullptr;
|
||||||
unsigned *ifpage_table;
|
unsigned *ifpage_table = nullptr;
|
||||||
unsigned *ofpage_table;
|
unsigned *ofpage_table = nullptr;
|
||||||
le_pagemap_entry_t *ipm_entries;
|
le_pagemap_entry_t *ipm_entries = nullptr;
|
||||||
le_pagemap_entry_t *opm_entries;
|
le_pagemap_entry_t *opm_entries = nullptr;
|
||||||
upx_byte *ires_names;
|
upx_byte *ires_names = nullptr;
|
||||||
upx_byte *ores_names;
|
upx_byte *ores_names = nullptr;
|
||||||
upx_byte *ifixups;
|
upx_byte *ifixups = nullptr;
|
||||||
upx_byte *ofixups;
|
upx_byte *ofixups = nullptr;
|
||||||
upx_byte *inonres_names;
|
upx_byte *inonres_names = nullptr;
|
||||||
upx_byte *ononres_names;
|
upx_byte *ononres_names = nullptr;
|
||||||
MemBuffer mb_iimage;
|
MemBuffer mb_iimage;
|
||||||
SPAN_0(upx_byte) iimage = nullptr;
|
SPAN_0(upx_byte) iimage = nullptr;
|
||||||
MemBuffer mb_oimage;
|
MemBuffer mb_oimage;
|
||||||
SPAN_0(upx_byte) oimage = nullptr;
|
SPAN_0(upx_byte) oimage = nullptr;
|
||||||
upx_byte *ientries;
|
upx_byte *ientries = nullptr;
|
||||||
upx_byte *oentries;
|
upx_byte *oentries = nullptr;
|
||||||
|
|
||||||
unsigned soobject_table;
|
unsigned soobject_table;
|
||||||
unsigned sofpage_table;
|
unsigned sofpage_table;
|
||||||
@@ -220,7 +227,6 @@ private:
|
|||||||
LeFile &operator=(const LeFile &) = delete;
|
LeFile &operator=(const LeFile &) = delete;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
#endif /* already included */
|
#endif /* already included */
|
||||||
|
|
||||||
/* vim:set ts=4 sw=4 et: */
|
/* vim:set ts=4 sw=4 et: */
|
||||||
|
|||||||
+30
-21
@@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
This file is part of the UPX executable compressor.
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
Copyright (C) 1996-2022 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2022 Laszlo Molnar
|
Copyright (C) 1996-2023 Laszlo Molnar
|
||||||
All Rights Reserved.
|
All Rights Reserved.
|
||||||
|
|
||||||
UPX and the UCL library are free software; you can redistribute them
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
@@ -157,8 +157,11 @@ void ElfLinker::init(const void *pdata_v, int plen, unsigned pxtra) {
|
|||||||
}
|
}
|
||||||
input[inputlen] = 0; // NUL terminate
|
input[inputlen] = 0; // NUL terminate
|
||||||
|
|
||||||
output = new upx_byte[inputlen ? (inputlen + pxtra) : 0x4000];
|
output_capacity = (inputlen ? (inputlen + pxtra) : 0x4000);
|
||||||
|
assert(output_capacity <= (1 << 16)); // LE16 l_info.l_size
|
||||||
|
output = new upx_byte[output_capacity];
|
||||||
outputlen = 0;
|
outputlen = 0;
|
||||||
|
NO_printf("\nElfLinker::init %d @%p\n", output_capacity, output);
|
||||||
|
|
||||||
// FIXME: bad compare when either symbols or relocs are absent
|
// FIXME: bad compare when either symbols or relocs are absent
|
||||||
if ((int) strlen("Sections:\n"
|
if ((int) strlen("Sections:\n"
|
||||||
@@ -198,8 +201,7 @@ void ElfLinker::preprocessSections(char *start, char const *end) {
|
|||||||
char *n = strstr(start, name);
|
char *n = strstr(start, name);
|
||||||
n[strlen(name)] = 0;
|
n[strlen(name)] = 0;
|
||||||
addSection(n, input + offset, size, align);
|
addSection(n, input + offset, size, align);
|
||||||
|
NO_printf("section %s preprocessed\n", n);
|
||||||
// printf("section %s preprocessed\n", n);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
addSection("*ABS*", nullptr, 0, 0);
|
addSection("*ABS*", nullptr, 0, 0);
|
||||||
@@ -224,13 +226,13 @@ void ElfLinker::preprocessSymbols(char *start, char const *end) {
|
|||||||
assert(offset == 0);
|
assert(offset == 0);
|
||||||
}
|
}
|
||||||
#if 0
|
#if 0
|
||||||
else if (sscanf(start, "%x%*8c %1023s %*x %1023s",
|
else if (sscanf(start, "%x%*8c %1023s %*x %1023s", &offset, section, symbol) == 3)
|
||||||
#else
|
#else
|
||||||
// work around broken scanf() implementations
|
// work around broken scanf() implementations
|
||||||
// http://bugs.winehq.org/show_bug.cgi?id=10401 (fixed in Wine 0.9.58)
|
// http://bugs.winehq.org/show_bug.cgi?id=10401 (fixed in Wine 0.9.58)
|
||||||
else if (sscanf(start, "%x%*c%*c%*c%*c%*c%*c%*c%*c %1023s %*x %1023s",
|
else if (sscanf(start, "%x%*c%*c%*c%*c%*c%*c%*c%*c %1023s %*x %1023s", &offset, section,
|
||||||
|
symbol) == 3)
|
||||||
#endif
|
#endif
|
||||||
&offset, section, symbol) == 3)
|
|
||||||
{
|
{
|
||||||
char *s = strstr(start, symbol);
|
char *s = strstr(start, symbol);
|
||||||
s[strlen(symbol)] = 0;
|
s[strlen(symbol)] = 0;
|
||||||
@@ -290,8 +292,8 @@ void ElfLinker::preprocessRelocations(char *start, char const *end) {
|
|||||||
|
|
||||||
if (section) {
|
if (section) {
|
||||||
addRelocation(section->name, offset, t, symbol, add);
|
addRelocation(section->name, offset, t, symbol, add);
|
||||||
// printf("relocation %s %s %x %llu preprocessed\n", section->name, symbol, offset,
|
NO_printf("relocation %s %s %x %llu preprocessed\n", section->name, symbol, offset,
|
||||||
// (unsigned long long) add);
|
(unsigned long long) add);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -317,7 +319,7 @@ ElfLinker::Symbol *ElfLinker::findSymbol(const char *name, bool fatal) const {
|
|||||||
|
|
||||||
ElfLinker::Section *ElfLinker::addSection(const char *sname, const void *sdata, int slen,
|
ElfLinker::Section *ElfLinker::addSection(const char *sname, const void *sdata, int slen,
|
||||||
unsigned p2align) {
|
unsigned p2align) {
|
||||||
// printf("addSection: %s len=%d align=%d\n", sname, slen, p2align);
|
NO_printf("addSection: %s len=%d align=%d\n", sname, slen, p2align);
|
||||||
if (!sdata && (!strcmp("ABS*", sname) || !strcmp("UND*", sname)))
|
if (!sdata && (!strcmp("ABS*", sname) || !strcmp("UND*", sname)))
|
||||||
return nullptr;
|
return nullptr;
|
||||||
if (update_capacity(nsections, &nsections_capacity))
|
if (update_capacity(nsections, &nsections_capacity))
|
||||||
@@ -335,7 +337,7 @@ ElfLinker::Section *ElfLinker::addSection(const char *sname, const void *sdata,
|
|||||||
|
|
||||||
ElfLinker::Symbol *ElfLinker::addSymbol(const char *name, const char *section,
|
ElfLinker::Symbol *ElfLinker::addSymbol(const char *name, const char *section,
|
||||||
upx_uint64_t offset) {
|
upx_uint64_t offset) {
|
||||||
// printf("addSymbol: %s %s 0x%x\n", name, section, offset);
|
NO_printf("addSymbol: %s %s 0x%llx\n", name, section, offset);
|
||||||
if (update_capacity(nsymbols, &nsymbols_capacity))
|
if (update_capacity(nsymbols, &nsymbols_capacity))
|
||||||
symbols = static_cast<Symbol **>(realloc(symbols, nsymbols_capacity * sizeof(Symbol *)));
|
symbols = static_cast<Symbol **>(realloc(symbols, nsymbols_capacity * sizeof(Symbol *)));
|
||||||
assert(symbols != nullptr);
|
assert(symbols != nullptr);
|
||||||
@@ -363,7 +365,7 @@ ElfLinker::Relocation *ElfLinker::addRelocation(const char *section, unsigned of
|
|||||||
void ElfLinker::setLoaderAlignOffset(int phase)
|
void ElfLinker::setLoaderAlignOffset(int phase)
|
||||||
{
|
{
|
||||||
//assert(phase & 0);
|
//assert(phase & 0);
|
||||||
printf("\nFIXME: ElfLinker::setLoaderAlignOffset %d\n", phase);
|
NO_printf("\nFIXME: ElfLinker::setLoaderAlignOffset %d\n", phase);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -408,9 +410,11 @@ int ElfLinker::addLoader(const char *sname) {
|
|||||||
tail->size += l;
|
tail->size += l;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// Section->output is not relocatable, and C++ has no realloc() anyway.
|
||||||
|
assert((section->size + outputlen) <= output_capacity);
|
||||||
memcpy(output + outputlen, section->input, section->size);
|
memcpy(output + outputlen, section->input, section->size);
|
||||||
section->output = output + outputlen;
|
section->output = output + outputlen; // FIXME: INVALIDATED by realloc()
|
||||||
// printf("section added: 0x%04x %3d %s\n", outputlen, section->size, section->name);
|
NO_printf("section added: 0x%04x %3d %s\n", outputlen, section->size, section->name);
|
||||||
outputlen += section->size;
|
outputlen += section->size;
|
||||||
|
|
||||||
if (head) {
|
if (head) {
|
||||||
@@ -479,11 +483,12 @@ void ElfLinker::relocate() {
|
|||||||
value = rel->value->section->offset + rel->value->offset + rel->add;
|
value = rel->value->section->offset + rel->value->offset + rel->add;
|
||||||
}
|
}
|
||||||
upx_byte *location = rel->section->output + rel->offset;
|
upx_byte *location = rel->section->output + rel->offset;
|
||||||
// printf("%-28s %-28s %-10s %#16llx %#16llx\n", rel->section->name, rel->value->name,
|
NO_printf("%-28s %-28s %-10s %#16llx %#16llx\n", rel->section->name, rel->value->name,
|
||||||
// rel->type, (long long) value, (long long) value - rel->section->offset - rel->offset);
|
rel->type, (long long) value,
|
||||||
// printf(" %llx %d %llx %d %llx : %d\n", (long long) value,
|
(long long) value - rel->section->offset - rel->offset);
|
||||||
// (int)rel->value->section->offset,
|
NO_printf(" %llx %d %llx %d %llx :%d\n", (long long) value,
|
||||||
// rel->value->offset, rel->offset, (long long) rel->add, *location);
|
(int) rel->value->section->offset, rel->value->offset, rel->offset,
|
||||||
|
(long long) rel->add, *location);
|
||||||
relocate1(rel, location, value, rel->type);
|
relocate1(rel, location, value, rel->type);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -578,8 +583,12 @@ void ElfLinkerAMD64::relocate1(const Relocation *rel, upx_byte *location, upx_ui
|
|||||||
|
|
||||||
bool range_check = false;
|
bool range_check = false;
|
||||||
if (strncmp(type, "PC", 2) == 0) {
|
if (strncmp(type, "PC", 2) == 0) {
|
||||||
value -= rel->section->offset + rel->offset;
|
|
||||||
type += 2;
|
type += 2;
|
||||||
|
value -= rel->section->offset + rel->offset;
|
||||||
|
range_check = true;
|
||||||
|
} else if (strncmp(type, "PLT", 3) == 0) {
|
||||||
|
type += 3;
|
||||||
|
value -= rel->section->offset + rel->offset;
|
||||||
range_check = true;
|
range_check = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+3
-2
@@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
This file is part of the UPX executable compressor.
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
Copyright (C) 1996-2022 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2022 Laszlo Molnar
|
Copyright (C) 1996-2023 Laszlo Molnar
|
||||||
All Rights Reserved.
|
All Rights Reserved.
|
||||||
|
|
||||||
UPX and the UCL library are free software; you can redistribute them
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
@@ -46,6 +46,7 @@ protected:
|
|||||||
int inputlen = 0;
|
int inputlen = 0;
|
||||||
upx_byte *output = nullptr;
|
upx_byte *output = nullptr;
|
||||||
int outputlen = 0;
|
int outputlen = 0;
|
||||||
|
unsigned output_capacity = 0;
|
||||||
|
|
||||||
Section *head = nullptr;
|
Section *head = nullptr;
|
||||||
Section *tail = nullptr;
|
Section *tail = nullptr;
|
||||||
|
|||||||
+29
-12
@@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
This file is part of the UPX executable compressor.
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
Copyright (C) 1996-2022 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2022 Laszlo Molnar
|
Copyright (C) 1996-2023 Laszlo Molnar
|
||||||
All Rights Reserved.
|
All Rights Reserved.
|
||||||
|
|
||||||
UPX and the UCL library are free software; you can redistribute them
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
@@ -25,16 +25,22 @@
|
|||||||
<markus@oberhumer.com> <ezerotven+github@gmail.com>
|
<markus@oberhumer.com> <ezerotven+github@gmail.com>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
// main entry, mostly boring stuff; see work.cpp for actual action
|
||||||
|
|
||||||
#include "conf.h"
|
#include "conf.h"
|
||||||
#include "compress.h"
|
|
||||||
#include "file.h"
|
#include "file.h"
|
||||||
#include "packer.h"
|
#include "packer.h"
|
||||||
#include "p_elf.h"
|
#include "p_elf.h"
|
||||||
|
#include "compress/compress.h" // upx_ucl_init()
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
// options
|
// options
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
|
#ifndef OPTIONS_VAR
|
||||||
|
#define OPTIONS_VAR "UPX"
|
||||||
|
#endif
|
||||||
|
|
||||||
static const char *argv0 = "";
|
static const char *argv0 = "";
|
||||||
const char *progname = "";
|
const char *progname = "";
|
||||||
|
|
||||||
@@ -375,6 +381,9 @@ static int do_option(int optc, const char *arg) {
|
|||||||
case 'f':
|
case 'f':
|
||||||
opt->force++;
|
opt->force++;
|
||||||
break;
|
break;
|
||||||
|
case 529:
|
||||||
|
opt->force_overwrite = true;
|
||||||
|
break;
|
||||||
case 909:
|
case 909:
|
||||||
set_cmd(CMD_FILEINFO);
|
set_cmd(CMD_FILEINFO);
|
||||||
break;
|
break;
|
||||||
@@ -566,7 +575,7 @@ static int do_option(int optc, const char *arg) {
|
|||||||
case 525: // --exact
|
case 525: // --exact
|
||||||
opt->exact = true;
|
opt->exact = true;
|
||||||
break;
|
break;
|
||||||
// compression runtime parameters
|
// CRP - Compression Runtime Parameters (undocumented and subject to change)
|
||||||
case 801:
|
case 801:
|
||||||
getoptvar(&opt->crp.crp_ucl.c_flags, 0, 3, arg);
|
getoptvar(&opt->crp.crp_ucl.c_flags, 0, 3, arg);
|
||||||
break;
|
break;
|
||||||
@@ -801,6 +810,7 @@ int main_get_options(int argc, char **argv) {
|
|||||||
// options
|
// options
|
||||||
{"force", 0, N, 'f'}, // force overwrite of output files
|
{"force", 0, N, 'f'}, // force overwrite of output files
|
||||||
{"force-compress", 0, N, 'f'}, // and compression of suspicious files
|
{"force-compress", 0, N, 'f'}, // and compression of suspicious files
|
||||||
|
{"force-overwrite", 0x90, N, 529}, // force overwrite of output files
|
||||||
{"info", 0, N, 'i'}, // info mode
|
{"info", 0, N, 'i'}, // info mode
|
||||||
{"no-env", 0x10, N, 519}, // no environment var
|
{"no-env", 0x10, N, 519}, // no environment var
|
||||||
{"no-mode", 0x10, N, 526}, // do not preserve mode (permissions)
|
{"no-mode", 0x10, N, 526}, // do not preserve mode (permissions)
|
||||||
@@ -862,7 +872,7 @@ int main_get_options(int argc, char **argv) {
|
|||||||
{"filter", 0x31, N, 521}, // --filter=
|
{"filter", 0x31, N, 521}, // --filter=
|
||||||
{"no-filter", 0x10, N, 522},
|
{"no-filter", 0x10, N, 522},
|
||||||
{"small", 0x10, N, 520},
|
{"small", 0x10, N, 520},
|
||||||
// compression runtime parameters
|
// CRP - Compression Runtime Parameters (undocumented and subject to change)
|
||||||
{"crp-nrv-cf", 0x31, N, 801},
|
{"crp-nrv-cf", 0x31, N, 801},
|
||||||
{"crp-nrv-sl", 0x31, N, 802},
|
{"crp-nrv-sl", 0x31, N, 802},
|
||||||
{"crp-nrv-hl", 0x31, N, 803},
|
{"crp-nrv-hl", 0x31, N, 803},
|
||||||
@@ -897,7 +907,7 @@ int main_get_options(int argc, char **argv) {
|
|||||||
// dos/sys
|
// dos/sys
|
||||||
// unix
|
// unix
|
||||||
{"blocksize", 0x31, N, 660}, // --blocksize=
|
{"blocksize", 0x31, N, 660}, // --blocksize=
|
||||||
{"force-execve", 0x10, N, 661}, // force linux/386 execve format
|
{"force-execve", 0x90, N, 661}, // force linux/386 execve format
|
||||||
{"is_ptinterp", 0x10, N, 663}, // linux/elf386 PT_INTERP program
|
{"is_ptinterp", 0x10, N, 663}, // linux/elf386 PT_INTERP program
|
||||||
{"use_ptinterp", 0x10, N, 664}, // linux/elf386 PT_INTERP program
|
{"use_ptinterp", 0x10, N, 664}, // linux/elf386 PT_INTERP program
|
||||||
{"make_ptinterp", 0x10, N, 665}, // linux/elf386 PT_INTERP program
|
{"make_ptinterp", 0x10, N, 665}, // linux/elf386 PT_INTERP program
|
||||||
@@ -912,7 +922,7 @@ int main_get_options(int argc, char **argv) {
|
|||||||
{"unmap-all-pages", 0x10, N, 674}, // linux /proc/self/exe vanishes
|
{"unmap-all-pages", 0x10, N, 674}, // linux /proc/self/exe vanishes
|
||||||
{"preserve-build-id", 0, N, 675},
|
{"preserve-build-id", 0, N, 675},
|
||||||
{"android-shlib", 0, N, 676},
|
{"android-shlib", 0, N, 676},
|
||||||
{"force-pie", 0, N, 677},
|
{"force-pie", 0x90, N, 677},
|
||||||
// watcom/le
|
// watcom/le
|
||||||
{"le", 0x10, N, 620}, // produce LE output
|
{"le", 0x10, N, 620}, // produce LE output
|
||||||
// win32/pe
|
// win32/pe
|
||||||
@@ -1197,12 +1207,18 @@ int upx_main(int argc, char *argv[]) {
|
|||||||
|
|
||||||
set_term(stderr);
|
set_term(stderr);
|
||||||
|
|
||||||
|
#if (WITH_BZIP2)
|
||||||
|
assert(upx_bzip2_init() == 0);
|
||||||
|
#endif
|
||||||
assert(upx_lzma_init() == 0);
|
assert(upx_lzma_init() == 0);
|
||||||
assert(upx_ucl_init() == 0);
|
|
||||||
assert(upx_zlib_init() == 0);
|
|
||||||
#if (WITH_NRV)
|
#if (WITH_NRV)
|
||||||
assert(upx_nrv_init() == 0);
|
assert(upx_nrv_init() == 0);
|
||||||
#endif
|
#endif
|
||||||
|
assert(upx_ucl_init() == 0);
|
||||||
|
assert(upx_zlib_init() == 0);
|
||||||
|
#if (WITH_ZSTD)
|
||||||
|
assert(upx_zstd_init() == 0);
|
||||||
|
#endif
|
||||||
|
|
||||||
/* get options */
|
/* get options */
|
||||||
first_options(argc, argv);
|
first_options(argc, argv);
|
||||||
@@ -1263,11 +1279,12 @@ int upx_main(int argc, char *argv[]) {
|
|||||||
return exit_code;
|
return exit_code;
|
||||||
|
|
||||||
if (gitrev[0]) {
|
if (gitrev[0]) {
|
||||||
bool warn = true;
|
// also see UPX_CONFIG_DISABLE_GITREV in CMakeLists.txt
|
||||||
|
bool warn_gitrev = true;
|
||||||
const char *ee = getenv("UPX_DEBUG_DISABLE_GITREV_WARNING");
|
const char *ee = getenv("UPX_DEBUG_DISABLE_GITREV_WARNING");
|
||||||
if (ee && ee[0] && strcmp(ee, "1") == 0)
|
if (ee && ee[0] && strcmp(ee, "1") == 0)
|
||||||
warn = false;
|
warn_gitrev = false;
|
||||||
if (warn) {
|
if (warn_gitrev) {
|
||||||
FILE *f = stdout;
|
FILE *f = stdout;
|
||||||
int fg = con_fg(f, FG_RED);
|
int fg = con_fg(f, FG_RED);
|
||||||
con_fprintf(
|
con_fprintf(
|
||||||
|
|||||||
+35
-61
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
This file is part of the UPX executable compressor.
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
Copyright (C) 1996-2022 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer
|
||||||
All Rights Reserved.
|
All Rights Reserved.
|
||||||
|
|
||||||
UPX and the UCL library are free software; you can redistribute them
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
@@ -27,7 +27,7 @@
|
|||||||
|
|
||||||
#ifndef __ACC_H_INCLUDED
|
#ifndef __ACC_H_INCLUDED
|
||||||
#define __ACC_H_INCLUDED 1
|
#define __ACC_H_INCLUDED 1
|
||||||
#define ACC_VERSION 20220904L
|
#define ACC_VERSION 20230104L
|
||||||
#if defined(__CYGWIN32__) && !defined(__CYGWIN__)
|
#if defined(__CYGWIN32__) && !defined(__CYGWIN__)
|
||||||
# define __CYGWIN__ __CYGWIN32__
|
# define __CYGWIN__ __CYGWIN32__
|
||||||
#endif
|
#endif
|
||||||
@@ -1561,7 +1561,7 @@ extern "C" {
|
|||||||
#endif
|
#endif
|
||||||
#if !defined(ACC_BLOCK_BEGIN)
|
#if !defined(ACC_BLOCK_BEGIN)
|
||||||
# define ACC_BLOCK_BEGIN do {
|
# define ACC_BLOCK_BEGIN do {
|
||||||
# define ACC_BLOCK_END } while __acc_cte(0)
|
# define ACC_BLOCK_END } while (__acc_cte(0))
|
||||||
#endif
|
#endif
|
||||||
#if !defined(ACC_UNUSED)
|
#if !defined(ACC_UNUSED)
|
||||||
# if (ACC_CC_BORLANDC && (__BORLANDC__ >= 0x0600))
|
# if (ACC_CC_BORLANDC && (__BORLANDC__ >= 0x0600))
|
||||||
@@ -1608,7 +1608,7 @@ extern "C" {
|
|||||||
# if (ACC_CC_CLANG >= 0x020800ul)
|
# if (ACC_CC_CLANG >= 0x020800ul)
|
||||||
# define ACC_UNUSED_LABEL(l) (__acc_gnuc_extension__ ((void) ACC_STATIC_CAST(const void *, &&l)))
|
# define ACC_UNUSED_LABEL(l) (__acc_gnuc_extension__ ((void) ACC_STATIC_CAST(const void *, &&l)))
|
||||||
# elif (ACC_CC_ARMCC || ACC_CC_CLANG || ACC_CC_INTELC || ACC_CC_WATCOMC)
|
# elif (ACC_CC_ARMCC || ACC_CC_CLANG || ACC_CC_INTELC || ACC_CC_WATCOMC)
|
||||||
# define ACC_UNUSED_LABEL(l) if __acc_cte(0) goto l
|
# define ACC_UNUSED_LABEL(l) if (__acc_cte(0)) goto l
|
||||||
# else
|
# else
|
||||||
# define ACC_UNUSED_LABEL(l) switch (0) case 1:goto l
|
# define ACC_UNUSED_LABEL(l) switch (0) case 1:goto l
|
||||||
# endif
|
# endif
|
||||||
@@ -2047,7 +2047,7 @@ extern "C" {
|
|||||||
# if (ACC_CC_IBMC)
|
# if (ACC_CC_IBMC)
|
||||||
# define __acc_loop_forever() ACC_BLOCK_BEGIN for (;;) { ; } ACC_BLOCK_END
|
# define __acc_loop_forever() ACC_BLOCK_BEGIN for (;;) { ; } ACC_BLOCK_END
|
||||||
# else
|
# else
|
||||||
# define __acc_loop_forever() do { ; } while __acc_cte(1)
|
# define __acc_loop_forever() do { ; } while (__acc_cte(1))
|
||||||
# endif
|
# endif
|
||||||
#endif
|
#endif
|
||||||
#if !defined(__acc_unreachable)
|
#if !defined(__acc_unreachable)
|
||||||
@@ -2079,11 +2079,11 @@ extern "C" {
|
|||||||
# define acc_unused_funcs_impl(r,f) __acc_static_forceinline r f
|
# define acc_unused_funcs_impl(r,f) __acc_static_forceinline r f
|
||||||
# endif
|
# endif
|
||||||
#endif
|
#endif
|
||||||
#ifndef __ACC_CTA_NAME
|
#ifndef ACC_CTA_INTERNAL_NAME__
|
||||||
#if (ACC_CFG_USE_COUNTER)
|
#if (ACC_CFG_USE_COUNTER)
|
||||||
# define __ACC_CTA_NAME(a) ACC_PP_ECONCAT2(a,__COUNTER__)
|
# define ACC_CTA_INTERNAL_NAME__(a) ACC_PP_ECONCAT2(a,__COUNTER__)
|
||||||
#else
|
#else
|
||||||
# define __ACC_CTA_NAME(a) ACC_PP_ECONCAT2(a,__LINE__)
|
# define ACC_CTA_INTERNAL_NAME__(a) ACC_PP_ECONCAT2(a,__LINE__)
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
#if !defined(ACC_COMPILE_TIME_ASSERT_HEADER)
|
#if !defined(ACC_COMPILE_TIME_ASSERT_HEADER)
|
||||||
@@ -2092,17 +2092,17 @@ extern "C" {
|
|||||||
# elif (ACC_LANG_C >= 201112L)
|
# elif (ACC_LANG_C >= 201112L)
|
||||||
# define ACC_COMPILE_TIME_ASSERT_HEADER(e) _Static_assert(e, #e);
|
# define ACC_COMPILE_TIME_ASSERT_HEADER(e) _Static_assert(e, #e);
|
||||||
# elif (ACC_CC_AZTECC || ACC_CC_ZORTECHC)
|
# elif (ACC_CC_AZTECC || ACC_CC_ZORTECHC)
|
||||||
# define ACC_COMPILE_TIME_ASSERT_HEADER(e) ACC_EXTERN_C_BEGIN extern int __ACC_CTA_NAME(acc_cta__)[1-!(e)]; ACC_EXTERN_C_END
|
# define ACC_COMPILE_TIME_ASSERT_HEADER(e) ACC_EXTERN_C_BEGIN extern int ACC_CTA_INTERNAL_NAME__(acc_cta__)[1-!(e)]; ACC_EXTERN_C_END
|
||||||
# elif (ACC_CC_DMC || ACC_CC_SYMANTECC)
|
# elif (ACC_CC_DMC || ACC_CC_SYMANTECC)
|
||||||
# define ACC_COMPILE_TIME_ASSERT_HEADER(e) ACC_EXTERN_C_BEGIN extern int __ACC_CTA_NAME(acc_cta__)[1u-2*!(e)]; ACC_EXTERN_C_END
|
# define ACC_COMPILE_TIME_ASSERT_HEADER(e) ACC_EXTERN_C_BEGIN extern int ACC_CTA_INTERNAL_NAME__(acc_cta__)[1u-2*!(e)]; ACC_EXTERN_C_END
|
||||||
# elif (ACC_CC_TURBOC && (__TURBOC__ == 0x0295))
|
# elif (ACC_CC_TURBOC && (__TURBOC__ == 0x0295))
|
||||||
# define ACC_COMPILE_TIME_ASSERT_HEADER(e) ACC_EXTERN_C_BEGIN extern int __ACC_CTA_NAME(acc_cta__)[1-!(e)]; ACC_EXTERN_C_END
|
# define ACC_COMPILE_TIME_ASSERT_HEADER(e) ACC_EXTERN_C_BEGIN extern int ACC_CTA_INTERNAL_NAME__(acc_cta__)[1-!(e)]; ACC_EXTERN_C_END
|
||||||
# elif (ACC_CC_CLANG && (ACC_CC_CLANG < 0x020900ul)) && defined(__cplusplus)
|
# elif (ACC_CC_CLANG && (ACC_CC_CLANG < 0x020900ul)) && defined(__cplusplus)
|
||||||
# define ACC_COMPILE_TIME_ASSERT_HEADER(e) ACC_EXTERN_C_BEGIN int __ACC_CTA_NAME(acc_cta_f__)(int [1-2*!(e)]); ACC_EXTERN_C_END
|
# define ACC_COMPILE_TIME_ASSERT_HEADER(e) ACC_EXTERN_C_BEGIN int ACC_CTA_INTERNAL_NAME__(acc_cta_f__)(int [1-2*!(e)]); ACC_EXTERN_C_END
|
||||||
# elif (ACC_CC_GNUC) && defined(__CHECKER__) && defined(__SPARSE_CHECKER__)
|
# elif (ACC_CC_GNUC) && defined(__CHECKER__) && defined(__SPARSE_CHECKER__)
|
||||||
# define ACC_COMPILE_TIME_ASSERT_HEADER(e) ACC_EXTERN_C_BEGIN enum {__ACC_CTA_NAME(acc_cta_e__)=1/!!(e)} __attribute__((__unused__)); ACC_EXTERN_C_END
|
# define ACC_COMPILE_TIME_ASSERT_HEADER(e) ACC_EXTERN_C_BEGIN enum {ACC_CTA_INTERNAL_NAME__(acc_cta_e__)=1/!!(e)} __attribute__((__unused__)); ACC_EXTERN_C_END
|
||||||
# else
|
# else
|
||||||
# define ACC_COMPILE_TIME_ASSERT_HEADER(e) ACC_EXTERN_C_BEGIN extern int __ACC_CTA_NAME(acc_cta__)[1-2*!(e)]; ACC_EXTERN_C_END
|
# define ACC_COMPILE_TIME_ASSERT_HEADER(e) ACC_EXTERN_C_BEGIN extern int ACC_CTA_INTERNAL_NAME__(acc_cta__)[1-2*!(e)]; ACC_EXTERN_C_END
|
||||||
# endif
|
# endif
|
||||||
#endif
|
#endif
|
||||||
#if !defined(ACC_COMPILE_TIME_ASSERT)
|
#if !defined(ACC_COMPILE_TIME_ASSERT)
|
||||||
@@ -2111,23 +2111,23 @@ extern "C" {
|
|||||||
# elif (ACC_LANG_C >= 201112L)
|
# elif (ACC_LANG_C >= 201112L)
|
||||||
# define ACC_COMPILE_TIME_ASSERT(e) {_Static_assert(e, #e);}
|
# define ACC_COMPILE_TIME_ASSERT(e) {_Static_assert(e, #e);}
|
||||||
# elif (ACC_CC_AZTECC)
|
# elif (ACC_CC_AZTECC)
|
||||||
# define ACC_COMPILE_TIME_ASSERT(e) {typedef int __ACC_CTA_NAME(acc_cta_t__)[1-!(e)];}
|
# define ACC_COMPILE_TIME_ASSERT(e) {typedef int ACC_CTA_INTERNAL_NAME__(acc_cta_t__)[1-!(e)];}
|
||||||
# elif (ACC_CC_CLANG && (ACC_CC_CLANG >= 0x030000ul))
|
# elif (ACC_CC_CLANG && (ACC_CC_CLANG >= 0x030000ul))
|
||||||
# define ACC_COMPILE_TIME_ASSERT(e) {typedef int __ACC_CTA_NAME(acc_cta_t__)[1-2*!(e)] __attribute__((__unused__));}
|
# define ACC_COMPILE_TIME_ASSERT(e) {typedef int ACC_CTA_INTERNAL_NAME__(acc_cta_t__)[1-2*!(e)] __attribute__((__unused__));}
|
||||||
# elif (ACC_CC_DMC || ACC_CC_PACIFICC || ACC_CC_SYMANTECC || ACC_CC_ZORTECHC)
|
# elif (ACC_CC_DMC || ACC_CC_PACIFICC || ACC_CC_SYMANTECC || ACC_CC_ZORTECHC)
|
||||||
# define ACC_COMPILE_TIME_ASSERT(e) switch(0) case 1:case !(e):break;
|
# define ACC_COMPILE_TIME_ASSERT(e) switch(0) case 1:case !(e):break;
|
||||||
# elif (ACC_CC_GNUC) && defined(__CHECKER__) && defined(__SPARSE_CHECKER__)
|
# elif (ACC_CC_GNUC) && defined(__CHECKER__) && defined(__SPARSE_CHECKER__)
|
||||||
# define ACC_COMPILE_TIME_ASSERT(e) {(void) (0/!!(e));}
|
# define ACC_COMPILE_TIME_ASSERT(e) {(void) (0/!!(e));}
|
||||||
# elif (ACC_CC_GNUC >= 0x040700ul) && (ACC_CFG_USE_COUNTER) && defined(__cplusplus)
|
# elif (ACC_CC_GNUC >= 0x040700ul) && (ACC_CFG_USE_COUNTER) && defined(__cplusplus)
|
||||||
# define ACC_COMPILE_TIME_ASSERT(e) {enum {__ACC_CTA_NAME(acc_cta_e__)=1/!!(e)} __attribute__((__unused__));}
|
# define ACC_COMPILE_TIME_ASSERT(e) {enum {ACC_CTA_INTERNAL_NAME__(acc_cta_e__)=1/!!(e)} __attribute__((__unused__));}
|
||||||
# elif (ACC_CC_GNUC >= 0x040700ul)
|
# elif (ACC_CC_GNUC >= 0x040700ul)
|
||||||
# define ACC_COMPILE_TIME_ASSERT(e) {typedef int __ACC_CTA_NAME(acc_cta_t__)[1-2*!(e)] __attribute__((__unused__));}
|
# define ACC_COMPILE_TIME_ASSERT(e) {typedef int ACC_CTA_INTERNAL_NAME__(acc_cta_t__)[1-2*!(e)] __attribute__((__unused__));}
|
||||||
# elif (ACC_CC_MSC && (_MSC_VER < 900))
|
# elif (ACC_CC_MSC && (_MSC_VER < 900))
|
||||||
# define ACC_COMPILE_TIME_ASSERT(e) switch(0) case 1:case !(e):break;
|
# define ACC_COMPILE_TIME_ASSERT(e) switch(0) case 1:case !(e):break;
|
||||||
# elif (ACC_CC_TURBOC && (__TURBOC__ == 0x0295))
|
# elif (ACC_CC_TURBOC && (__TURBOC__ == 0x0295))
|
||||||
# define ACC_COMPILE_TIME_ASSERT(e) switch(0) case 1:case !(e):break;
|
# define ACC_COMPILE_TIME_ASSERT(e) switch(0) case 1:case !(e):break;
|
||||||
# else
|
# else
|
||||||
# define ACC_COMPILE_TIME_ASSERT(e) {typedef int __ACC_CTA_NAME(acc_cta_t__)[1-2*!(e)];}
|
# define ACC_COMPILE_TIME_ASSERT(e) {typedef int ACC_CTA_INTERNAL_NAME__(acc_cta_t__)[1-2*!(e)];}
|
||||||
# endif
|
# endif
|
||||||
#endif
|
#endif
|
||||||
#if (ACC_LANG_ASSEMBLER)
|
#if (ACC_LANG_ASSEMBLER)
|
||||||
@@ -2557,7 +2557,11 @@ ACC_COMPILE_TIME_ASSERT_HEADER(ACC_SIZEOF_PTRDIFF_T == sizeof(ptrdiff_t))
|
|||||||
# undef ACC_ABI_BIG_ENDIAN
|
# undef ACC_ABI_BIG_ENDIAN
|
||||||
# undef ACC_ABI_LITTLE_ENDIAN
|
# undef ACC_ABI_LITTLE_ENDIAN
|
||||||
#elif !(ACC_ABI_BIG_ENDIAN) && !(ACC_ABI_LITTLE_ENDIAN)
|
#elif !(ACC_ABI_BIG_ENDIAN) && !(ACC_ABI_LITTLE_ENDIAN)
|
||||||
#if (ACC_ARCH_ALPHA) && (ACC_ARCH_CRAY_MPP)
|
#if defined(__ORDER_BIG_ENDIAN__) && defined(__ORDER_LITTLE_ENDIAN__) && (__ORDER_BIG_ENDIAN__+0 != 0) && (__ORDER_LITTLE_ENDIAN__+0 != 0) && (__ORDER_BIG_ENDIAN__ != __ORDER_LITTLE_ENDIAN__) && defined(__BYTE_ORDER__) && (__BYTE_ORDER__+0 == __ORDER_BIG_ENDIAN__)
|
||||||
|
# define ACC_ABI_BIG_ENDIAN 1
|
||||||
|
#elif defined(__ORDER_BIG_ENDIAN__) && defined(__ORDER_LITTLE_ENDIAN__) && (__ORDER_BIG_ENDIAN__+0 != 0) && (__ORDER_LITTLE_ENDIAN__+0 != 0) && (__ORDER_BIG_ENDIAN__ != __ORDER_LITTLE_ENDIAN__) && defined(__BYTE_ORDER__) && (__BYTE_ORDER__+0 == __ORDER_LITTLE_ENDIAN__)
|
||||||
|
# define ACC_ABI_LITTLE_ENDIAN 1
|
||||||
|
#elif (ACC_ARCH_ALPHA) && (ACC_ARCH_CRAY_MPP)
|
||||||
# define ACC_ABI_BIG_ENDIAN 1
|
# define ACC_ABI_BIG_ENDIAN 1
|
||||||
#elif (ACC_ARCH_IA64) && (ACC_OS_POSIX_LINUX || ACC_OS_WIN64)
|
#elif (ACC_ARCH_IA64) && (ACC_OS_POSIX_LINUX || ACC_OS_WIN64)
|
||||||
# define ACC_ABI_LITTLE_ENDIAN 1
|
# define ACC_ABI_LITTLE_ENDIAN 1
|
||||||
@@ -2733,37 +2737,14 @@ ACC_COMPILE_TIME_ASSERT_HEADER(ACC_SIZEOF_PTRDIFF_T == sizeof(ptrdiff_t))
|
|||||||
# define ACC_OPT_UNALIGNED64 1
|
# define ACC_OPT_UNALIGNED64 1
|
||||||
# endif
|
# endif
|
||||||
#elif (ACC_ARCH_ARM)
|
#elif (ACC_ARCH_ARM)
|
||||||
# if defined(__ARM_FEATURE_UNALIGNED)
|
# if defined(__ARM_FEATURE_UNALIGNED) && (__ARM_FEATURE_UNALIGNED+0)
|
||||||
# if ((__ARM_FEATURE_UNALIGNED)+0)
|
|
||||||
# ifndef ACC_OPT_UNALIGNED16
|
# ifndef ACC_OPT_UNALIGNED16
|
||||||
# define ACC_OPT_UNALIGNED16 1
|
# define ACC_OPT_UNALIGNED16 1
|
||||||
# endif
|
# endif
|
||||||
# ifndef ACC_OPT_UNALIGNED32
|
# ifndef ACC_OPT_UNALIGNED32
|
||||||
# define ACC_OPT_UNALIGNED32 1
|
# define ACC_OPT_UNALIGNED32 1
|
||||||
# endif
|
# endif
|
||||||
# endif
|
# elif defined(__TARGET_FEATURE_UNALIGNED) && (__TARGET_FEATURE_UNALIGNED+0)
|
||||||
# elif 1 && (ACC_ARCH_ARM_THUMB2)
|
|
||||||
# ifndef ACC_OPT_UNALIGNED16
|
|
||||||
# define ACC_OPT_UNALIGNED16 1
|
|
||||||
# endif
|
|
||||||
# ifndef ACC_OPT_UNALIGNED32
|
|
||||||
# define ACC_OPT_UNALIGNED32 1
|
|
||||||
# endif
|
|
||||||
# elif 1 && defined(__ARM_ARCH) && ((__ARM_ARCH)+0 >= 7)
|
|
||||||
# ifndef ACC_OPT_UNALIGNED16
|
|
||||||
# define ACC_OPT_UNALIGNED16 1
|
|
||||||
# endif
|
|
||||||
# ifndef ACC_OPT_UNALIGNED32
|
|
||||||
# define ACC_OPT_UNALIGNED32 1
|
|
||||||
# endif
|
|
||||||
# elif 1 && defined(__TARGET_ARCH_ARM) && ((__TARGET_ARCH_ARM)+0 >= 7)
|
|
||||||
# ifndef ACC_OPT_UNALIGNED16
|
|
||||||
# define ACC_OPT_UNALIGNED16 1
|
|
||||||
# endif
|
|
||||||
# ifndef ACC_OPT_UNALIGNED32
|
|
||||||
# define ACC_OPT_UNALIGNED32 1
|
|
||||||
# endif
|
|
||||||
# elif 1 && defined(__TARGET_ARCH_ARM) && ((__TARGET_ARCH_ARM)+0 >= 6) && (defined(__TARGET_PROFILE_A) || defined(__TARGET_PROFILE_R))
|
|
||||||
# ifndef ACC_OPT_UNALIGNED16
|
# ifndef ACC_OPT_UNALIGNED16
|
||||||
# define ACC_OPT_UNALIGNED16 1
|
# define ACC_OPT_UNALIGNED16 1
|
||||||
# endif
|
# endif
|
||||||
@@ -2822,34 +2803,21 @@ ACC_COMPILE_TIME_ASSERT_HEADER(ACC_SIZEOF_PTRDIFF_T == sizeof(ptrdiff_t))
|
|||||||
#elif (ACC_ARCH_POWERPC)
|
#elif (ACC_ARCH_POWERPC)
|
||||||
# define ACC_OPT_PREFER_PREINC 1
|
# define ACC_OPT_PREFER_PREINC 1
|
||||||
# define ACC_OPT_PREFER_PREDEC 1
|
# define ACC_OPT_PREFER_PREDEC 1
|
||||||
# if (ACC_ABI_BIG_ENDIAN) || (ACC_WORDSIZE == 8)
|
# if (ACC_WORDSIZE == 8) || (ACC_ABI_BIG_ENDIAN)
|
||||||
# ifndef ACC_OPT_UNALIGNED16
|
# ifndef ACC_OPT_UNALIGNED16
|
||||||
# define ACC_OPT_UNALIGNED16 1
|
# define ACC_OPT_UNALIGNED16 1
|
||||||
# endif
|
# endif
|
||||||
# ifndef ACC_OPT_UNALIGNED32
|
# ifndef ACC_OPT_UNALIGNED32
|
||||||
# define ACC_OPT_UNALIGNED32 1
|
# define ACC_OPT_UNALIGNED32 1
|
||||||
# endif
|
# endif
|
||||||
|
# endif
|
||||||
# if (ACC_WORDSIZE == 8)
|
# if (ACC_WORDSIZE == 8)
|
||||||
# ifndef ACC_OPT_UNALIGNED64
|
# ifndef ACC_OPT_UNALIGNED64
|
||||||
# define ACC_OPT_UNALIGNED64 1
|
# define ACC_OPT_UNALIGNED64 1
|
||||||
# endif
|
# endif
|
||||||
# endif
|
# endif
|
||||||
# endif
|
|
||||||
#elif (ACC_ARCH_RISCV)
|
#elif (ACC_ARCH_RISCV)
|
||||||
# define ACC_OPT_AVOID_UINT_INDEX 1
|
# define ACC_OPT_AVOID_UINT_INDEX 1
|
||||||
# if 0
|
|
||||||
# ifndef ACC_OPT_UNALIGNED16
|
|
||||||
# define ACC_OPT_UNALIGNED16 1
|
|
||||||
# endif
|
|
||||||
# ifndef ACC_OPT_UNALIGNED32
|
|
||||||
# define ACC_OPT_UNALIGNED32 1
|
|
||||||
# endif
|
|
||||||
# if (ACC_WORDSIZE == 8)
|
|
||||||
# ifndef ACC_OPT_UNALIGNED64
|
|
||||||
# define ACC_OPT_UNALIGNED64 1
|
|
||||||
# endif
|
|
||||||
# endif
|
|
||||||
# endif
|
|
||||||
#elif (ACC_ARCH_S390)
|
#elif (ACC_ARCH_S390)
|
||||||
# ifndef ACC_OPT_UNALIGNED16
|
# ifndef ACC_OPT_UNALIGNED16
|
||||||
# define ACC_OPT_UNALIGNED16 1
|
# define ACC_OPT_UNALIGNED16 1
|
||||||
@@ -3404,7 +3372,9 @@ ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(acc_int_fast64_t) == sizeof(acc_uint_fast6
|
|||||||
# define HAVE_STDDEF_H 1
|
# define HAVE_STDDEF_H 1
|
||||||
#elif (ACC_LIBC_MOSTLY_FREESTANDING)
|
#elif (ACC_LIBC_MOSTLY_FREESTANDING)
|
||||||
# define HAVE_LIMITS_H 1
|
# define HAVE_LIMITS_H 1
|
||||||
|
# ifndef HAVE_SETJMP_H
|
||||||
# define HAVE_SETJMP_H 1
|
# define HAVE_SETJMP_H 1
|
||||||
|
# endif
|
||||||
# define HAVE_STDARG_H 1
|
# define HAVE_STDARG_H 1
|
||||||
# define HAVE_STDDEF_H 1
|
# define HAVE_STDDEF_H 1
|
||||||
# define HAVE_STDIO_H 1
|
# define HAVE_STDIO_H 1
|
||||||
@@ -3420,8 +3390,12 @@ ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(acc_int_fast64_t) == sizeof(acc_uint_fast6
|
|||||||
#define HAVE_LIMITS_H 1
|
#define HAVE_LIMITS_H 1
|
||||||
#define HAVE_MALLOC_H 1
|
#define HAVE_MALLOC_H 1
|
||||||
#define HAVE_MEMORY_H 1
|
#define HAVE_MEMORY_H 1
|
||||||
|
#ifndef HAVE_SETJMP_H
|
||||||
#define HAVE_SETJMP_H 1
|
#define HAVE_SETJMP_H 1
|
||||||
|
#endif
|
||||||
|
#ifndef HAVE_SIGNAL_H
|
||||||
#define HAVE_SIGNAL_H 1
|
#define HAVE_SIGNAL_H 1
|
||||||
|
#endif
|
||||||
#define HAVE_STDARG_H 1
|
#define HAVE_STDARG_H 1
|
||||||
#define HAVE_STDDEF_H 1
|
#define HAVE_STDDEF_H 1
|
||||||
#define HAVE_STDIO_H 1
|
#define HAVE_STDIO_H 1
|
||||||
@@ -4804,7 +4778,7 @@ typedef long acc_fallback_ptrdiff_t;
|
|||||||
#if defined(__SIZE_TYPE__)
|
#if defined(__SIZE_TYPE__)
|
||||||
typedef __SIZE_TYPE__ acc_fallback_size_t;
|
typedef __SIZE_TYPE__ acc_fallback_size_t;
|
||||||
#elif defined(_WIN64)
|
#elif defined(_WIN64)
|
||||||
typedef unsigned long long acc_fallback_ptrdiff_t;
|
typedef unsigned long long acc_fallback_size_t;
|
||||||
#elif defined(__MIPS_PSX2__)
|
#elif defined(__MIPS_PSX2__)
|
||||||
typedef unsigned acc_fallback_size_t;
|
typedef unsigned acc_fallback_size_t;
|
||||||
#else
|
#else
|
||||||
|
|||||||
+28
-63
@@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
This file is part of the UPX executable compressor.
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
Copyright (C) 1996-2022 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2022 Laszlo Molnar
|
Copyright (C) 1996-2023 Laszlo Molnar
|
||||||
All Rights Reserved.
|
All Rights Reserved.
|
||||||
|
|
||||||
UPX and the UCL library are free software; you can redistribute them
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
@@ -25,10 +25,8 @@
|
|||||||
<markus@oberhumer.com> <ezerotven+github@gmail.com>
|
<markus@oberhumer.com> <ezerotven+github@gmail.com>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#include "conf.h"
|
#include "conf.h"
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
// FIXME: if stdout is redirected to a file and stderr is not, should
|
// FIXME: if stdout is redirected to a file and stderr is not, should
|
||||||
// we write all error messages to both stderr and stdout ?
|
// we write all error messages to both stderr and stdout ?
|
||||||
@@ -36,17 +34,11 @@
|
|||||||
|
|
||||||
static int pr_need_nl = 0;
|
static int pr_need_nl = 0;
|
||||||
|
|
||||||
|
void printSetNl(int need_nl) { pr_need_nl = need_nl; }
|
||||||
|
|
||||||
void printSetNl(int need_nl)
|
void printClearLine(FILE *f) {
|
||||||
{
|
|
||||||
pr_need_nl = need_nl;
|
|
||||||
}
|
|
||||||
|
|
||||||
void printClearLine(FILE *f)
|
|
||||||
{
|
|
||||||
static char clear_line_msg[1 + 79 + 1 + 1];
|
static char clear_line_msg[1 + 79 + 1 + 1];
|
||||||
if (!clear_line_msg[0])
|
if (!clear_line_msg[0]) {
|
||||||
{
|
|
||||||
char *msg = clear_line_msg;
|
char *msg = clear_line_msg;
|
||||||
msg[0] = '\r';
|
msg[0] = '\r';
|
||||||
memset(msg + 1, ' ', 79);
|
memset(msg + 1, ' ', 79);
|
||||||
@@ -54,7 +46,8 @@ void printClearLine(FILE *f)
|
|||||||
msg[81] = 0;
|
msg[81] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
fflush(stdout); fflush(stderr);
|
fflush(stdout);
|
||||||
|
fflush(stderr);
|
||||||
if (f == nullptr)
|
if (f == nullptr)
|
||||||
f = stdout;
|
f = stdout;
|
||||||
con_fprintf(f, "%s", clear_line_msg);
|
con_fprintf(f, "%s", clear_line_msg);
|
||||||
@@ -62,24 +55,21 @@ void printClearLine(FILE *f)
|
|||||||
printSetNl(0);
|
printSetNl(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void pr_print(bool c, const char *msg) {
|
||||||
static void pr_print(bool c, const char *msg)
|
|
||||||
{
|
|
||||||
if (c && !opt->to_stdout)
|
if (c && !opt->to_stdout)
|
||||||
con_fprintf(stderr, "%s", msg);
|
con_fprintf(stderr, "%s", msg);
|
||||||
else
|
else
|
||||||
fprintf(stderr, "%s", msg);
|
fprintf(stderr, "%s", msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void pr_error(const char *iname, const char *msg, bool is_warning)
|
static void pr_error(const char *iname, const char *msg, bool is_warning) {
|
||||||
{
|
fflush(stdout);
|
||||||
fflush(stdout); fflush(stderr);
|
fflush(stderr);
|
||||||
char buf[1024];
|
char buf[1024];
|
||||||
buf[0] = 0;
|
buf[0] = 0;
|
||||||
if (pr_need_nl == 2)
|
if (pr_need_nl == 2)
|
||||||
printClearLine(stdout);
|
printClearLine(stdout);
|
||||||
else if (pr_need_nl)
|
else if (pr_need_nl) {
|
||||||
{
|
|
||||||
buf[0] = '\n';
|
buf[0] = '\n';
|
||||||
buf[1] = 0;
|
buf[1] = 0;
|
||||||
printSetNl(0);
|
printSetNl(0);
|
||||||
@@ -99,16 +89,15 @@ static void pr_error(const char *iname, const char *msg, bool is_warning)
|
|||||||
//(void)con_fg(stderr,FG_BRTRED);
|
//(void)con_fg(stderr,FG_BRTRED);
|
||||||
pr_print(c, msg);
|
pr_print(c, msg);
|
||||||
pr_print(c, "\n");
|
pr_print(c, "\n");
|
||||||
fflush(stdout); fflush(stderr);
|
fflush(stdout);
|
||||||
|
fflush(stderr);
|
||||||
fg = con_fg(stderr, fg);
|
fg = con_fg(stderr, fg);
|
||||||
|
|
||||||
UNUSED(is_warning);
|
UNUSED(is_warning);
|
||||||
UNUSED(fg);
|
UNUSED(fg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void printErr(const char *iname, const Throwable *e) {
|
||||||
void printErr(const char *iname, const Throwable *e)
|
|
||||||
{
|
|
||||||
char buf[1024];
|
char buf[1024];
|
||||||
size_t l;
|
size_t l;
|
||||||
|
|
||||||
@@ -130,9 +119,7 @@ void printErr(const char *iname, const Throwable *e)
|
|||||||
pr_error(iname, buf, e->isWarning());
|
pr_error(iname, buf, e->isWarning());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void printErr(const char *iname, const char *format, ...) {
|
||||||
void printErr(const char *iname, const char *format, ...)
|
|
||||||
{
|
|
||||||
va_list args;
|
va_list args;
|
||||||
char buf[1024];
|
char buf[1024];
|
||||||
|
|
||||||
@@ -143,9 +130,7 @@ void printErr(const char *iname, const char *format, ...)
|
|||||||
pr_error(iname, buf, false);
|
pr_error(iname, buf, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void printWarn(const char *iname, const char *format, ...) {
|
||||||
void printWarn(const char *iname, const char *format, ...)
|
|
||||||
{
|
|
||||||
va_list args;
|
va_list args;
|
||||||
char buf[1024];
|
char buf[1024];
|
||||||
|
|
||||||
@@ -156,38 +141,30 @@ void printWarn(const char *iname, const char *format, ...)
|
|||||||
pr_error(iname, buf, true);
|
pr_error(iname, buf, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void printUnhandledException(const char *iname, const std::exception *e) {
|
||||||
void printUnhandledException(const char *iname, const std::exception *e)
|
|
||||||
{
|
|
||||||
if (e)
|
if (e)
|
||||||
printErr(iname, "unhandled exception: %s\n", prettyName(e->what()));
|
printErr(iname, "unhandled exception: %s\n", prettyName(e->what()));
|
||||||
else
|
else
|
||||||
printErr(iname, "internal error: unhandled exception!\n");
|
printErr(iname, "internal error: unhandled exception!\n");
|
||||||
if (opt->cmd != CMD_COMPRESS)
|
if (opt->cmd != CMD_COMPRESS) {
|
||||||
{
|
|
||||||
printErr(iname, " this file has possibly been modified/hacked; take care!\n");
|
printErr(iname, " this file has possibly been modified/hacked; take care!\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
// FIXME: should use colors and a consistent layout here
|
// FIXME: should use colors and a consistent layout here
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
static int info_header = 0;
|
static int info_header = 0;
|
||||||
|
|
||||||
|
static void info_print(const char *msg) {
|
||||||
static void info_print(const char *msg)
|
|
||||||
{
|
|
||||||
if (opt->info_mode <= 0)
|
if (opt->info_mode <= 0)
|
||||||
return;
|
return;
|
||||||
FILE *f = opt->to_stdout ? stderr : stdout;
|
FILE *f = opt->to_stdout ? stderr : stdout;
|
||||||
if (pr_need_nl)
|
if (pr_need_nl) {
|
||||||
{
|
|
||||||
printClearLine(f);
|
printClearLine(f);
|
||||||
con_fprintf(f, "%s\n", msg);
|
con_fprintf(f, "%s\n", msg);
|
||||||
}
|
} else if (pr_need_nl)
|
||||||
else if (pr_need_nl)
|
|
||||||
con_fprintf(f, "\n%s\n", msg);
|
con_fprintf(f, "\n%s\n", msg);
|
||||||
else
|
else
|
||||||
con_fprintf(f, "%s\n", msg);
|
con_fprintf(f, "%s\n", msg);
|
||||||
@@ -195,14 +172,9 @@ static void info_print(const char *msg)
|
|||||||
printSetNl(0);
|
printSetNl(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void infoHeader() { info_header = 0; }
|
||||||
|
|
||||||
void infoHeader()
|
void infoHeader(const char *format, ...) {
|
||||||
{
|
|
||||||
info_header = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void infoHeader(const char *format, ...)
|
|
||||||
{
|
|
||||||
if (opt->info_mode <= 0)
|
if (opt->info_mode <= 0)
|
||||||
return;
|
return;
|
||||||
va_list args;
|
va_list args;
|
||||||
@@ -214,9 +186,7 @@ void infoHeader(const char *format, ...)
|
|||||||
info_header = 1;
|
info_header = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void info(const char *format, ...) {
|
||||||
void info(const char *format, ...)
|
|
||||||
{
|
|
||||||
if (opt->info_mode <= 0)
|
if (opt->info_mode <= 0)
|
||||||
return;
|
return;
|
||||||
va_list args;
|
va_list args;
|
||||||
@@ -229,11 +199,8 @@ void info(const char *format, ...)
|
|||||||
info_print(buf);
|
info_print(buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void infoWarning(const char *format, ...) {
|
||||||
void infoWarning(const char *format, ...)
|
if (opt->info_mode <= 0) {
|
||||||
{
|
|
||||||
if (opt->info_mode <= 0)
|
|
||||||
{
|
|
||||||
// FIXME - should still print something here
|
// FIXME - should still print something here
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -245,9 +212,7 @@ void infoWarning(const char *format, ...)
|
|||||||
info("[WARNING] %s\n", buf);
|
info("[WARNING] %s\n", buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void infoWriting(const char *what, long size) {
|
||||||
void infoWriting(const char *what, long size)
|
|
||||||
{
|
|
||||||
if (opt->info_mode <= 0)
|
if (opt->info_mode <= 0)
|
||||||
return;
|
return;
|
||||||
info("Writing %s: %ld bytes", what, size);
|
info("Writing %s: %ld bytes", what, size);
|
||||||
|
|||||||
+16
-9
@@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
This file is part of the UPX executable compressor.
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
Copyright (C) 1996-2022 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2022 Laszlo Molnar
|
Copyright (C) 1996-2023 Laszlo Molnar
|
||||||
All Rights Reserved.
|
All Rights Reserved.
|
||||||
|
|
||||||
UPX and the UCL library are free software; you can redistribute them
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
@@ -27,8 +27,11 @@
|
|||||||
|
|
||||||
#include "conf.h"
|
#include "conf.h"
|
||||||
|
|
||||||
|
static options_t global_options;
|
||||||
|
options_t *opt = &global_options; // also see class PackMaster
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
// options
|
// reset
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
void options_t::reset() {
|
void options_t::reset() {
|
||||||
@@ -57,7 +60,7 @@ void options_t::reset() {
|
|||||||
#endif
|
#endif
|
||||||
o->verbose = 2;
|
o->verbose = 2;
|
||||||
|
|
||||||
opt->o_unix.osabi0 = 3; // 3 == ELFOSABI_LINUX
|
o->o_unix.osabi0 = 3; // 3 == ELFOSABI_LINUX
|
||||||
|
|
||||||
o->win32_pe.compress_exports = 1;
|
o->win32_pe.compress_exports = 1;
|
||||||
o->win32_pe.compress_icons = 2;
|
o->win32_pe.compress_icons = 2;
|
||||||
@@ -69,20 +72,24 @@ void options_t::reset() {
|
|||||||
o->win32_pe.keep_resource = "";
|
o->win32_pe.keep_resource = "";
|
||||||
}
|
}
|
||||||
|
|
||||||
static options_t global_options;
|
|
||||||
options_t *opt = &global_options;
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
//
|
// doctest checks
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
|
TEST_CASE("options_t::reset") {
|
||||||
|
options_t local_options;
|
||||||
|
options_t *o = &local_options;
|
||||||
|
o->reset();
|
||||||
|
CHECK(o->o_unix.osabi0 == 3);
|
||||||
|
}
|
||||||
|
|
||||||
template <size_t N>
|
template <size_t N>
|
||||||
static inline void test_options(const char *(&a)[N]) {
|
static inline void test_options(const char *(&a)[N]) {
|
||||||
(void) main_get_options((int) (N - 1), ACC_UNCONST_CAST(char **, a));
|
(void) main_get_options((int) (N - 1), ACC_UNCONST_CAST(char **, a));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("getopt") {
|
TEST_CASE("getopt") {
|
||||||
options_t *saved_opt = opt;
|
options_t *const saved_opt = opt;
|
||||||
options_t local_options;
|
options_t local_options;
|
||||||
opt = &local_options;
|
opt = &local_options;
|
||||||
opt->reset();
|
opt->reset();
|
||||||
|
|||||||
+13
-13
@@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
This file is part of the UPX executable compressor.
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
Copyright (C) 1996-2022 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2022 Laszlo Molnar
|
Copyright (C) 1996-2023 Laszlo Molnar
|
||||||
All Rights Reserved.
|
All Rights Reserved.
|
||||||
|
|
||||||
UPX and the UCL library are free software; you can redistribute them
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
@@ -43,10 +43,10 @@ enum {
|
|||||||
CMD_FILEINFO,
|
CMD_FILEINFO,
|
||||||
CMD_HELP,
|
CMD_HELP,
|
||||||
CMD_LICENSE,
|
CMD_LICENSE,
|
||||||
CMD_VERSION
|
CMD_VERSION,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct options_t {
|
struct options_t final {
|
||||||
int cmd;
|
int cmd;
|
||||||
|
|
||||||
// compression options
|
// compression options
|
||||||
@@ -69,6 +69,7 @@ struct options_t {
|
|||||||
int backup;
|
int backup;
|
||||||
int console;
|
int console;
|
||||||
int force;
|
int force;
|
||||||
|
bool force_overwrite;
|
||||||
int info_mode;
|
int info_mode;
|
||||||
bool ignorewarn;
|
bool ignorewarn;
|
||||||
bool no_env;
|
bool no_env;
|
||||||
@@ -95,7 +96,8 @@ struct options_t {
|
|||||||
enum { SKIP_OVERLAY = 0, COPY_OVERLAY = 1, STRIP_OVERLAY = 2 };
|
enum { SKIP_OVERLAY = 0, COPY_OVERLAY = 1, STRIP_OVERLAY = 2 };
|
||||||
int overlay;
|
int overlay;
|
||||||
|
|
||||||
// compression runtime parameters - see struct XXX_compress_config_t
|
// CRP - Compression Runtime Parameters (undocumented and subject to change)
|
||||||
|
// see struct XXX_compress_config_t
|
||||||
struct crp_t {
|
struct crp_t {
|
||||||
lzma_compress_config_t crp_lzma;
|
lzma_compress_config_t crp_lzma;
|
||||||
ucl_compress_config_t crp_ucl;
|
ucl_compress_config_t crp_ucl;
|
||||||
@@ -115,8 +117,6 @@ struct options_t {
|
|||||||
CPU_286 = 2,
|
CPU_286 = 2,
|
||||||
CPU_386 = 3,
|
CPU_386 = 3,
|
||||||
CPU_486 = 4,
|
CPU_486 = 4,
|
||||||
CPU_586 = 5,
|
|
||||||
CPU_686 = 6
|
|
||||||
};
|
};
|
||||||
int cpu;
|
int cpu;
|
||||||
|
|
||||||
@@ -131,12 +131,6 @@ struct options_t {
|
|||||||
bool force_stub;
|
bool force_stub;
|
||||||
bool no_reloc;
|
bool no_reloc;
|
||||||
} dos_exe;
|
} dos_exe;
|
||||||
struct {
|
|
||||||
bool boot_only;
|
|
||||||
bool no_align;
|
|
||||||
bool do_8bit;
|
|
||||||
bool do_8mib;
|
|
||||||
} ps1_exe;
|
|
||||||
struct {
|
struct {
|
||||||
unsigned blocksize;
|
unsigned blocksize;
|
||||||
bool force_execve; // force the linux/386 execve format
|
bool force_execve; // force the linux/386 execve format
|
||||||
@@ -149,6 +143,12 @@ struct options_t {
|
|||||||
bool android_shlib; // keep some ElfXX_Shdr for dlopen()
|
bool android_shlib; // keep some ElfXX_Shdr for dlopen()
|
||||||
bool force_pie; // choose DF_1_PIE instead of is_shlib
|
bool force_pie; // choose DF_1_PIE instead of is_shlib
|
||||||
} o_unix;
|
} o_unix;
|
||||||
|
struct {
|
||||||
|
bool boot_only;
|
||||||
|
bool no_align;
|
||||||
|
bool do_8bit;
|
||||||
|
bool do_8mib;
|
||||||
|
} ps1_exe;
|
||||||
struct {
|
struct {
|
||||||
bool le;
|
bool le;
|
||||||
} watcom_le;
|
} watcom_le;
|
||||||
|
|||||||
+40
-74
@@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
This file is part of the UPX executable compressor.
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
Copyright (C) 1996-2022 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2022 Laszlo Molnar
|
Copyright (C) 1996-2023 Laszlo Molnar
|
||||||
All Rights Reserved.
|
All Rights Reserved.
|
||||||
|
|
||||||
UPX and the UCL library are free software; you can redistribute them
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
@@ -25,7 +25,6 @@
|
|||||||
<markus@oberhumer.com> <ezerotven+github@gmail.com>
|
<markus@oberhumer.com> <ezerotven+github@gmail.com>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#include "conf.h"
|
#include "conf.h"
|
||||||
#include "file.h"
|
#include "file.h"
|
||||||
#include "filter.h"
|
#include "filter.h"
|
||||||
@@ -34,27 +33,20 @@
|
|||||||
#include "p_armpe.h"
|
#include "p_armpe.h"
|
||||||
#include "linker.h"
|
#include "linker.h"
|
||||||
|
|
||||||
static const
|
static const CLANG_FORMAT_DUMMY_STATEMENT
|
||||||
#include "stub/arm.v4a-wince.pe.h"
|
#include "stub/arm.v4a-wince.pe.h"
|
||||||
static const
|
static const CLANG_FORMAT_DUMMY_STATEMENT
|
||||||
#include "stub/arm.v4t-wince.pe.h"
|
#include "stub/arm.v4t-wince.pe.h"
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
//
|
//
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
PackArmPe::PackArmPe(InputFile *f) : super(f)
|
PackArmPe::PackArmPe(InputFile *f) : super(f) {}
|
||||||
{
|
|
||||||
use_thumb_stub = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
PackArmPe::~PackArmPe() {}
|
||||||
|
|
||||||
PackArmPe::~PackArmPe()
|
const int *PackArmPe::getCompressionMethods(int method, int level) const {
|
||||||
{}
|
|
||||||
|
|
||||||
|
|
||||||
const int *PackArmPe::getCompressionMethods(int method, int level) const
|
|
||||||
{
|
|
||||||
static const int m_all[] = {M_NRV2B_8, M_NRV2E_8, M_LZMA, M_END};
|
static const int m_all[] = {M_NRV2B_8, M_NRV2E_8, M_LZMA, M_END};
|
||||||
static const int m_lzma[] = {M_LZMA, M_END};
|
static const int m_lzma[] = {M_LZMA, M_END};
|
||||||
static const int m_nrv2b[] = {M_NRV2B_8, M_END};
|
static const int m_nrv2b[] = {M_NRV2B_8, M_END};
|
||||||
@@ -63,26 +55,23 @@ const int *PackArmPe::getCompressionMethods(int method, int level) const
|
|||||||
if (!use_thumb_stub)
|
if (!use_thumb_stub)
|
||||||
return getDefaultCompressionMethods_8(method, level);
|
return getDefaultCompressionMethods_8(method, level);
|
||||||
|
|
||||||
if (method == M_ALL) return m_all;
|
if (method == M_ALL)
|
||||||
if (M_IS_LZMA(method)) return m_lzma;
|
return m_all;
|
||||||
if (M_IS_NRV2B(method)) return m_nrv2b;
|
if (M_IS_LZMA(method))
|
||||||
if (M_IS_NRV2E(method)) return m_nrv2e;
|
return m_lzma;
|
||||||
|
if (M_IS_NRV2B(method))
|
||||||
|
return m_nrv2b;
|
||||||
|
if (M_IS_NRV2E(method))
|
||||||
|
return m_nrv2e;
|
||||||
return m_nrv2e;
|
return m_nrv2e;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const int *PackArmPe::getFilters() const {
|
||||||
const int *PackArmPe::getFilters() const
|
|
||||||
{
|
|
||||||
static const int filters[] = {0x50, FT_END};
|
static const int filters[] = {0x50, FT_END};
|
||||||
return filters;
|
return filters;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Linker *PackArmPe::newLinker() const { return new ElfLinkerArmLE; }
|
||||||
Linker* PackArmPe::newLinker() const
|
|
||||||
{
|
|
||||||
return new ElfLinkerArmLE;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
// import handling
|
// import handling
|
||||||
@@ -93,17 +82,14 @@ void PackArmPe::processImports2(unsigned myimport, unsigned iat_off) // pass 2
|
|||||||
PeFile::processImports2(myimport, iat_off);
|
PeFile::processImports2(myimport, iat_off);
|
||||||
|
|
||||||
// adjust import data
|
// adjust import data
|
||||||
for (import_desc *im = (import_desc*) oimpdlls; im->dllname; im++)
|
for (import_desc *im = (import_desc *) oimpdlls; im->dllname; im++) {
|
||||||
{
|
|
||||||
im->oft = im->iat;
|
im->oft = im->iat;
|
||||||
bool is_coredll = strcasecmp(kernelDll(), (char*) oimpdlls +
|
bool is_coredll = strcasecmp(kernelDll(), oimpdlls + (im->dllname - myimport)) == 0;
|
||||||
im->dllname - myimport) == 0;
|
|
||||||
im->iat = is_coredll ? iat_off : iat_off + 12;
|
im->iat = is_coredll ? iat_off : iat_off + 12;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void PackArmPe::addStubImports()
|
void PackArmPe::addStubImports() {
|
||||||
{
|
|
||||||
// the order of procedure names below should match the
|
// the order of procedure names below should match the
|
||||||
// assumptions of the assembly stubs
|
// assumptions of the assembly stubs
|
||||||
// WARNING! these names are sorted alphanumerically by the ImportLinker
|
// WARNING! these names are sorted alphanumerically by the ImportLinker
|
||||||
@@ -121,13 +107,11 @@ void PackArmPe::processTls(Interval *) // pass 1
|
|||||||
throwCantPack("Static TLS entries found. Send a report please.");
|
throwCantPack("Static TLS entries found. Send a report please.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
// pack
|
// pack
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
bool PackArmPe::canPack()
|
bool PackArmPe::canPack() {
|
||||||
{
|
|
||||||
if (!readFileHeader() || (ih.cpu != 0x1c0 && ih.cpu != 0x1c2))
|
if (!readFileHeader() || (ih.cpu != 0x1c0 && ih.cpu != 0x1c2))
|
||||||
return false;
|
return false;
|
||||||
use_thumb_stub |= ih.cpu == 0x1c2 || (ih.entry & 1) == 1;
|
use_thumb_stub |= ih.cpu == 0x1c2 || (ih.entry & 1) == 1;
|
||||||
@@ -135,9 +119,7 @@ bool PackArmPe::canPack()
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PackArmPe::buildLoader(const Filter *ft) {
|
||||||
void PackArmPe::buildLoader(const Filter *ft)
|
|
||||||
{
|
|
||||||
const unsigned char *loader = use_thumb_stub ? stub_arm_v4t_wince_pe : stub_arm_v4a_wince_pe;
|
const unsigned char *loader = use_thumb_stub ? stub_arm_v4t_wince_pe : stub_arm_v4a_wince_pe;
|
||||||
unsigned size = use_thumb_stub ? sizeof(stub_arm_v4t_wince_pe) : sizeof(stub_arm_v4a_wince_pe);
|
unsigned size = use_thumb_stub ? sizeof(stub_arm_v4t_wince_pe) : sizeof(stub_arm_v4a_wince_pe);
|
||||||
|
|
||||||
@@ -157,7 +139,6 @@ void PackArmPe::buildLoader(const Filter *ft)
|
|||||||
else if (M_IS_LZMA(ph.method))
|
else if (M_IS_LZMA(ph.method))
|
||||||
addLoader("+40C,CallLZMA", nullptr);
|
addLoader("+40C,CallLZMA", nullptr);
|
||||||
|
|
||||||
|
|
||||||
if (ft->id == 0x50)
|
if (ft->id == 0x50)
|
||||||
addLoader("+40C,Unfilter_0x50", nullptr);
|
addLoader("+40C,Unfilter_0x50", nullptr);
|
||||||
|
|
||||||
@@ -179,48 +160,38 @@ void PackArmPe::buildLoader(const Filter *ft)
|
|||||||
addLoader("IDENTSTR,UPX1HEAD", nullptr);
|
addLoader("IDENTSTR,UPX1HEAD", nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool PackArmPe::handleForceOption()
|
bool PackArmPe::handleForceOption() {
|
||||||
{
|
return (ih.cpu != 0x1c0 && ih.cpu != 0x1c2) || (ih.opthdrsize != 0xe0) ||
|
||||||
return (ih.cpu != 0x1c0 && ih.cpu != 0x1c2)
|
((ih.flags & EXECUTABLE) == 0) || (ih.entry == 0 /*&& !isdll*/) ||
|
||||||
|| (ih.opthdrsize != 0xe0)
|
(ih.ddirsentries != 16);
|
||||||
|| ((ih.flags & EXECUTABLE) == 0)
|
|
||||||
|| (ih.entry == 0 /*&& !isdll*/)
|
|
||||||
|| (ih.ddirsentries != 16)
|
|
||||||
// || IDSIZE(PEDIR_EXCEPTION) // is this used on arm?
|
// || IDSIZE(PEDIR_EXCEPTION) // is this used on arm?
|
||||||
// || IDSIZE(PEDIR_COPYRIGHT)
|
// || IDSIZE(PEDIR_COPYRIGHT)
|
||||||
;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void PackArmPe::callCompressWithFilters(Filter &ft, int filter_strategy, unsigned ih_codebase)
|
void PackArmPe::callCompressWithFilters(Filter &ft, int filter_strategy, unsigned ih_codebase) {
|
||||||
{
|
|
||||||
// limit stack size needed for runtime decompression
|
// limit stack size needed for runtime decompression
|
||||||
upx_compress_config_t cconf; cconf.reset();
|
upx_compress_config_t cconf;
|
||||||
|
cconf.reset();
|
||||||
cconf.conf_lzma.max_num_probs = 1846 + (768 << 4); // ushort: ~28 KiB stack
|
cconf.conf_lzma.max_num_probs = 1846 + (768 << 4); // ushort: ~28 KiB stack
|
||||||
compressWithFilters(&ft, 2048, &cconf, filter_strategy,
|
compressWithFilters(&ft, 2048, &cconf, filter_strategy, ih_codebase, rvamin, 0, nullptr, 0);
|
||||||
ih_codebase, rvamin, 0, nullptr, 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void PackArmPe::addNewRelocations(Reloc &rel, unsigned upxsection)
|
void PackArmPe::addNewRelocations(Reloc &rel, unsigned upxsection) {
|
||||||
{
|
static const char *const symbols_to_relocate[] = {"ONAM", "BIMP", "BREL", "FIBE",
|
||||||
static const char* symbols_to_relocate[] = {
|
"FIBS", "ENTR", "DST0", "SRC0"};
|
||||||
"ONAM", "BIMP", "BREL", "FIBE", "FIBS", "ENTR", "DST0", "SRC0"
|
for (unsigned s2r = 0; s2r < TABLESIZE(symbols_to_relocate); s2r++) {
|
||||||
};
|
|
||||||
for (unsigned s2r = 0; s2r < TABLESIZE(symbols_to_relocate); s2r++)
|
|
||||||
{
|
|
||||||
unsigned off = linker->getSymbolOffset(symbols_to_relocate[s2r]);
|
unsigned off = linker->getSymbolOffset(symbols_to_relocate[s2r]);
|
||||||
if (off != 0xdeaddead)
|
if (off != 0xdeaddead)
|
||||||
rel.add(off + upxsection, 3);
|
rel.add(off + upxsection, 3);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned PackArmPe::getProcessImportParam(unsigned upxsection)
|
unsigned PackArmPe::getProcessImportParam(unsigned upxsection) {
|
||||||
{
|
|
||||||
return linker->getSymbolOffset("IATT") + upxsection;
|
return linker->getSymbolOffset("IATT") + upxsection;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PackArmPe::defineSymbols(unsigned ncsection, unsigned, unsigned,
|
void PackArmPe::defineSymbols(unsigned ncsection, unsigned, unsigned, unsigned ic,
|
||||||
unsigned ic, unsigned s1addr)
|
unsigned s1addr) {
|
||||||
{
|
|
||||||
const unsigned onam = ncsection + soxrelocs + ih.imagebase;
|
const unsigned onam = ncsection + soxrelocs + ih.imagebase;
|
||||||
linker->defineSymbol("start_of_dll_names", onam);
|
linker->defineSymbol("start_of_dll_names", onam);
|
||||||
linker->defineSymbol("start_of_imports", ih.imagebase + rvamin + cimports);
|
linker->defineSymbol("start_of_imports", ih.imagebase + rvamin + cimports);
|
||||||
@@ -235,18 +206,13 @@ void PackArmPe::defineSymbols(unsigned ncsection, unsigned, unsigned,
|
|||||||
defineDecompressorSymbols();
|
defineDecompressorSymbols();
|
||||||
}
|
}
|
||||||
|
|
||||||
void PackArmPe::setOhDataBase(const pe_section_t *osection)
|
void PackArmPe::setOhDataBase(const pe_section_t *osection) { oh.database = osection[2].vaddr; }
|
||||||
{
|
|
||||||
oh.database = osection[2].vaddr;
|
|
||||||
}
|
|
||||||
|
|
||||||
void PackArmPe::setOhHeaderSize(const pe_section_t *osection)
|
void PackArmPe::setOhHeaderSize(const pe_section_t *osection) {
|
||||||
{
|
|
||||||
oh.headersize = osection[1].rawdataptr;
|
oh.headersize = osection[1].rawdataptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PackArmPe::pack(OutputFile *fo)
|
void PackArmPe::pack(OutputFile *fo) {
|
||||||
{
|
|
||||||
super::pack0(fo, (1u << IMAGE_SUBSYSTEM_WINDOWS_CE_GUI), 0x10000, true);
|
super::pack0(fo, (1u << IMAGE_SUBSYSTEM_WINDOWS_CE_GUI), 0x10000, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+9
-13
@@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
This file is part of the UPX executable compressor.
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
Copyright (C) 1996-2022 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2022 Laszlo Molnar
|
Copyright (C) 1996-2023 Laszlo Molnar
|
||||||
All Rights Reserved.
|
All Rights Reserved.
|
||||||
|
|
||||||
UPX and the UCL library are free software; you can redistribute them
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
@@ -25,17 +25,15 @@
|
|||||||
<markus@oberhumer.com> <ezerotven+github@gmail.com>
|
<markus@oberhumer.com> <ezerotven+github@gmail.com>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
#ifndef __UPX_P_ARMPE_H
|
#ifndef UPX_P_ARMPE_H__
|
||||||
#define __UPX_P_ARMPE_H 1
|
#define UPX_P_ARMPE_H__ 1
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
// arm/pe
|
// arm/pe
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
class PackArmPe : public PeFile32
|
class PackArmPe final : public PeFile32 {
|
||||||
{
|
|
||||||
typedef PeFile32 super;
|
typedef PeFile32 super;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
@@ -51,9 +49,8 @@ public:
|
|||||||
virtual bool handleForceOption() override;
|
virtual bool handleForceOption() override;
|
||||||
virtual void callCompressWithFilters(Filter &, int filter_strategy,
|
virtual void callCompressWithFilters(Filter &, int filter_strategy,
|
||||||
unsigned ih_codebase) override;
|
unsigned ih_codebase) override;
|
||||||
virtual void defineSymbols(unsigned ncsection, unsigned upxsection,
|
virtual void defineSymbols(unsigned ncsection, unsigned upxsection, unsigned sizeof_oh,
|
||||||
unsigned sizeof_oh, unsigned isize_isplit,
|
unsigned isize_isplit, unsigned s1addr) override;
|
||||||
unsigned s1addr) override;
|
|
||||||
virtual void addNewRelocations(Reloc &, unsigned upxsection) override;
|
virtual void addNewRelocations(Reloc &, unsigned upxsection) override;
|
||||||
virtual unsigned getProcessImportParam(unsigned upxsection) override;
|
virtual unsigned getProcessImportParam(unsigned upxsection) override;
|
||||||
virtual void setOhDataBase(const pe_section_t *osection) override;
|
virtual void setOhDataBase(const pe_section_t *osection) override;
|
||||||
@@ -72,10 +69,9 @@ protected:
|
|||||||
|
|
||||||
virtual void processTls(Interval *) override;
|
virtual void processTls(Interval *) override;
|
||||||
|
|
||||||
bool use_thumb_stub;
|
bool use_thumb_stub = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
#endif /* already included */
|
#endif /* already included */
|
||||||
|
|
||||||
/* vim:set ts=4 sw=4 et: */
|
/* vim:set ts=4 sw=4 et: */
|
||||||
|
|||||||
+29
-69
@@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
This file is part of the UPX executable compressor.
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
Copyright (C) 1996-2022 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2022 Laszlo Molnar
|
Copyright (C) 1996-2023 Laszlo Molnar
|
||||||
All Rights Reserved.
|
All Rights Reserved.
|
||||||
|
|
||||||
UPX and the UCL library are free software; you can redistribute them
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
@@ -25,7 +25,6 @@
|
|||||||
<markus@oberhumer.com> <ezerotven+github@gmail.com>
|
<markus@oberhumer.com> <ezerotven+github@gmail.com>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#include "conf.h"
|
#include "conf.h"
|
||||||
#include "file.h"
|
#include "file.h"
|
||||||
#include "filter.h"
|
#include "filter.h"
|
||||||
@@ -33,42 +32,35 @@
|
|||||||
#include "p_com.h"
|
#include "p_com.h"
|
||||||
#include "linker.h"
|
#include "linker.h"
|
||||||
|
|
||||||
static const
|
static const CLANG_FORMAT_DUMMY_STATEMENT
|
||||||
#include "stub/i086-dos16.com.h"
|
#include "stub/i086-dos16.com.h"
|
||||||
|
|
||||||
// #define TESTING 1
|
// #define TESTING 1
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
//
|
//
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
const int *PackCom::getCompressionMethods(int method, int level) const
|
const int *PackCom::getCompressionMethods(int method, int level) const {
|
||||||
{
|
|
||||||
static const int m_nrv2b[] = {M_NRV2B_LE16, M_END};
|
static const int m_nrv2b[] = {M_NRV2B_LE16, M_END};
|
||||||
#if 0
|
#if 0
|
||||||
static const int m_nrv2d[] = { M_NRV2D_LE16, M_END };
|
static const int m_nrv2d[] = { M_NRV2D_LE16, M_END };
|
||||||
#endif
|
#endif
|
||||||
UNUSED(method); UNUSED(level);
|
UNUSED(method);
|
||||||
|
UNUSED(level);
|
||||||
return m_nrv2b;
|
return m_nrv2b;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const int *PackCom::getFilters() const {
|
||||||
const int *PackCom::getFilters() const
|
static const int filters[] = {0x06, 0x03, 0x04, 0x01, 0x05, 0x02, FT_END};
|
||||||
{
|
|
||||||
static const int filters[] = {
|
|
||||||
0x06, 0x03, 0x04, 0x01, 0x05, 0x02,
|
|
||||||
FT_END };
|
|
||||||
return filters;
|
return filters;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
//
|
//
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
bool PackCom::canPack()
|
bool PackCom::canPack() {
|
||||||
{
|
|
||||||
unsigned char buf[128];
|
unsigned char buf[128];
|
||||||
|
|
||||||
fi->readx(buf, sizeof(buf));
|
fi->readx(buf, sizeof(buf));
|
||||||
@@ -85,15 +77,11 @@ bool PackCom::canPack()
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
//
|
//
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
void PackCom::patchLoader(OutputFile *fo,
|
void PackCom::patchLoader(OutputFile *fo, upx_byte *loader, int lsize, unsigned calls) {
|
||||||
upx_byte *loader, int lsize,
|
|
||||||
unsigned calls)
|
|
||||||
{
|
|
||||||
const int e_len = getLoaderSectionStart("COMCUTPO");
|
const int e_len = getLoaderSectionStart("COMCUTPO");
|
||||||
const int d_len = lsize - e_len;
|
const int d_len = lsize - e_len;
|
||||||
assert(e_len > 0 && e_len < 128);
|
assert(e_len > 0 && e_len < 128);
|
||||||
@@ -130,60 +118,40 @@ void PackCom::patchLoader(OutputFile *fo,
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PackCom::buildLoader(const Filter *ft) {
|
||||||
void PackCom::buildLoader(const Filter *ft)
|
|
||||||
{
|
|
||||||
initLoader(stub_i086_dos16_com, sizeof(stub_i086_dos16_com));
|
initLoader(stub_i086_dos16_com, sizeof(stub_i086_dos16_com));
|
||||||
addLoader("COMMAIN1",
|
addLoader("COMMAIN1", ph.first_offset_found == 1 ? "COMSBBBP" : "", "COMPSHDI",
|
||||||
ph.first_offset_found == 1 ? "COMSBBBP" : "",
|
ft->id ? "COMCALLT" : "", "COMMAIN2,UPX1HEAD,COMCUTPO,NRV2B160",
|
||||||
"COMPSHDI",
|
ft->id ? "NRVDDONE" : "NRVDRETU", "NRVDECO1",
|
||||||
ft->id ? "COMCALLT" : "",
|
ph.max_offset_found <= 0xd00 ? "NRVLED00" : "NRVGTD00", "NRVDECO2", nullptr);
|
||||||
"COMMAIN2,UPX1HEAD,COMCUTPO,NRV2B160",
|
if (ft->id) {
|
||||||
ft->id ? "NRVDDONE" : "NRVDRETU",
|
|
||||||
"NRVDECO1",
|
|
||||||
ph.max_offset_found <= 0xd00 ? "NRVLED00" : "NRVGTD00",
|
|
||||||
"NRVDECO2",
|
|
||||||
nullptr
|
|
||||||
);
|
|
||||||
if (ft->id)
|
|
||||||
{
|
|
||||||
assert(ft->calls > 0);
|
assert(ft->calls > 0);
|
||||||
addFilter16(ft->id);
|
addFilter16(ft->id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PackCom::addFilter16(int filter_id) {
|
||||||
void PackCom::addFilter16(int filter_id)
|
|
||||||
{
|
|
||||||
assert(filter_id > 0);
|
assert(filter_id > 0);
|
||||||
assert(isValidFilter(filter_id));
|
assert(isValidFilter(filter_id));
|
||||||
|
|
||||||
if (filter_id % 3 == 0)
|
if (filter_id % 3 == 0)
|
||||||
addLoader("CALLTR16",
|
addLoader("CALLTR16", filter_id < 4 ? "CT16SUB0" : "",
|
||||||
filter_id < 4 ? "CT16SUB0" : "",
|
filter_id < 4 ? ""
|
||||||
filter_id < 4 ? "" : (opt->cpu == opt->CPU_8086 ? "CT16I086" : "CT16I286,CT16SUB0"),
|
: (opt->cpu == opt->CPU_8086 ? "CT16I086" : "CT16I286,CT16SUB0"),
|
||||||
"CALLTRI2",
|
"CALLTRI2", getFormat() == UPX_F_DOS_COM ? "CORETURN" : "", nullptr);
|
||||||
getFormat() == UPX_F_DOS_COM ? "CORETURN" : "",
|
|
||||||
nullptr
|
|
||||||
);
|
|
||||||
else
|
else
|
||||||
addLoader(filter_id%3 == 1 ? "CT16E800" : "CT16E900",
|
addLoader(
|
||||||
"CALLTRI5",
|
filter_id % 3 == 1 ? "CT16E800" : "CT16E900", "CALLTRI5",
|
||||||
getFormat() == UPX_F_DOS_COM ? "CT16JEND" : "CT16JUL2",
|
getFormat() == UPX_F_DOS_COM ? "CT16JEND" : "CT16JUL2", filter_id < 4 ? "CT16SUB1" : "",
|
||||||
filter_id < 4 ? "CT16SUB1" : "",
|
|
||||||
filter_id < 4 ? "" : (opt->cpu == opt->CPU_8086 ? "CT16I087" : "CT16I287,CT16SUB1"),
|
filter_id < 4 ? "" : (opt->cpu == opt->CPU_8086 ? "CT16I087" : "CT16I287,CT16SUB1"),
|
||||||
"CALLTRI6",
|
"CALLTRI6", nullptr);
|
||||||
nullptr
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
//
|
//
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
void PackCom::pack(OutputFile *fo)
|
void PackCom::pack(OutputFile *fo) {
|
||||||
{
|
|
||||||
// read file
|
// read file
|
||||||
ibuf.alloc(file_size);
|
ibuf.alloc(file_size);
|
||||||
obuf.allocForCompression(file_size);
|
obuf.allocForCompression(file_size);
|
||||||
@@ -214,13 +182,11 @@ void PackCom::pack(OutputFile *fo)
|
|||||||
throwNotCompressible();
|
throwNotCompressible();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
//
|
//
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
int PackCom::canUnpack()
|
int PackCom::canUnpack() {
|
||||||
{
|
|
||||||
if (!readPackHeader(128))
|
if (!readPackHeader(128))
|
||||||
return false;
|
return false;
|
||||||
if (file_size_u <= ph.c_len)
|
if (file_size_u <= ph.c_len)
|
||||||
@@ -228,13 +194,11 @@ int PackCom::canUnpack()
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
//
|
//
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
void PackCom::unpack(OutputFile *fo)
|
void PackCom::unpack(OutputFile *fo) {
|
||||||
{
|
|
||||||
ibuf.alloc(file_size);
|
ibuf.alloc(file_size);
|
||||||
obuf.allocForDecompression(ph.u_len);
|
obuf.allocForDecompression(ph.u_len);
|
||||||
|
|
||||||
@@ -260,10 +224,6 @@ void PackCom::unpack(OutputFile *fo)
|
|||||||
fo->write(obuf, ph.u_len);
|
fo->write(obuf, ph.u_len);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Linker *PackCom::newLinker() const { return new ElfLinkerX86(); }
|
||||||
Linker* PackCom::newLinker() const
|
|
||||||
{
|
|
||||||
return new ElfLinkerX86();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* vim:set ts=4 sw=4 et: */
|
/* vim:set ts=4 sw=4 et: */
|
||||||
|
|||||||
+7
-10
@@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
This file is part of the UPX executable compressor.
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
Copyright (C) 1996-2022 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2022 Laszlo Molnar
|
Copyright (C) 1996-2023 Laszlo Molnar
|
||||||
All Rights Reserved.
|
All Rights Reserved.
|
||||||
|
|
||||||
UPX and the UCL library are free software; you can redistribute them
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
@@ -25,24 +25,22 @@
|
|||||||
<markus@oberhumer.com> <ezerotven+github@gmail.com>
|
<markus@oberhumer.com> <ezerotven+github@gmail.com>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
#ifndef __UPX_P_COM_H
|
#ifndef UPX_P_COM_H__
|
||||||
#define __UPX_P_COM_H 1
|
#define UPX_P_COM_H__ 1
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
// dos/com
|
// dos/com
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
class PackCom : public Packer
|
class PackCom : public Packer {
|
||||||
{
|
|
||||||
typedef Packer super;
|
typedef Packer super;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
PackCom(InputFile *f) : super(f) { bele = &N_BELE_RTP::le_policy; }
|
PackCom(InputFile *f) : super(f) { bele = &N_BELE_RTP::le_policy; }
|
||||||
virtual int getVersion() const override { return 13; }
|
virtual int getVersion() const override { return 13; }
|
||||||
virtual int getFormat() const override { return UPX_F_DOS_COM; }
|
virtual int getFormat() const override { return UPX_F_DOS_COM; }
|
||||||
virtual const char *getName() const override { return "dos/com"; }
|
virtual const char *getName() const override { return "dos/com"; }
|
||||||
//virtual const char *getFullName(const options_t *o) const override { return o && o->cpu == o->CPU_8086 ? "i086-dos16.com" : "i286-dos16.com"; }
|
|
||||||
virtual const char *getFullName(const options_t *) const override { return "i086-dos16.com"; }
|
virtual const char *getFullName(const options_t *) const override { return "i086-dos16.com"; }
|
||||||
virtual const int *getCompressionMethods(int method, int level) const override;
|
virtual const int *getCompressionMethods(int method, int level) const override;
|
||||||
virtual const int *getFilters() const override;
|
virtual const int *getFilters() const override;
|
||||||
@@ -63,7 +61,6 @@ protected:
|
|||||||
virtual void addFilter16(int filter_id);
|
virtual void addFilter16(int filter_id);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
#endif /* already included */
|
#endif /* already included */
|
||||||
|
|
||||||
/* vim:set ts=4 sw=4 et: */
|
/* vim:set ts=4 sw=4 et: */
|
||||||
|
|||||||
+44
-104
@@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
This file is part of the UPX executable compressor.
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
Copyright (C) 1996-2022 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2022 Laszlo Molnar
|
Copyright (C) 1996-2023 Laszlo Molnar
|
||||||
All Rights Reserved.
|
All Rights Reserved.
|
||||||
|
|
||||||
UPX and the UCL library are free software; you can redistribute them
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
@@ -25,7 +25,6 @@
|
|||||||
<markus@oberhumer.com> <ezerotven+github@gmail.com>
|
<markus@oberhumer.com> <ezerotven+github@gmail.com>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#include "conf.h"
|
#include "conf.h"
|
||||||
#include "file.h"
|
#include "file.h"
|
||||||
#include "filter.h"
|
#include "filter.h"
|
||||||
@@ -33,19 +32,16 @@
|
|||||||
#include "p_djgpp2.h"
|
#include "p_djgpp2.h"
|
||||||
#include "linker.h"
|
#include "linker.h"
|
||||||
|
|
||||||
static const
|
static const CLANG_FORMAT_DUMMY_STATEMENT
|
||||||
#include "stub/i386-dos32.djgpp2.h"
|
#include "stub/i386-dos32.djgpp2.h"
|
||||||
static const
|
static const CLANG_FORMAT_DUMMY_STATEMENT
|
||||||
#include "stub/i386-dos32.djgpp2-stubify.h"
|
#include "stub/i386-dos32.djgpp2-stubify.h"
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
//
|
//
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
PackDjgpp2::PackDjgpp2(InputFile *f) :
|
PackDjgpp2::PackDjgpp2(InputFile *f) : super(f), coff_offset(0) {
|
||||||
super(f), coff_offset(0)
|
|
||||||
{
|
|
||||||
bele = &N_BELE_RTP::le_policy;
|
bele = &N_BELE_RTP::le_policy;
|
||||||
COMPILE_TIME_ASSERT(sizeof(external_scnhdr_t) == 40)
|
COMPILE_TIME_ASSERT(sizeof(external_scnhdr_t) == 40)
|
||||||
COMPILE_TIME_ASSERT(sizeof(coff_header_t) == 0xa8)
|
COMPILE_TIME_ASSERT(sizeof(coff_header_t) == 0xa8)
|
||||||
@@ -58,55 +54,33 @@ PackDjgpp2::PackDjgpp2(InputFile *f) :
|
|||||||
// assert(upx_adler32(stubify_stub, sizeof(stubify_stub)) == STUBIFY_STUB_ADLER32);
|
// assert(upx_adler32(stubify_stub, sizeof(stubify_stub)) == STUBIFY_STUB_ADLER32);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const int *PackDjgpp2::getCompressionMethods(int method, int level) const {
|
||||||
const int *PackDjgpp2::getCompressionMethods(int method, int level) const
|
|
||||||
{
|
|
||||||
return Packer::getDefaultCompressionMethods_le32(method, level);
|
return Packer::getDefaultCompressionMethods_le32(method, level);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const int *PackDjgpp2::getFilters() const {
|
||||||
const int *PackDjgpp2::getFilters() const
|
static const int filters[] = {0x26, 0x24, 0x49, 0x46, 0x16, 0x13, 0x14,
|
||||||
{
|
0x11, FT_ULTRA_BRUTE, 0x25, 0x15, 0x12, FT_END};
|
||||||
static const int filters[] = {
|
|
||||||
0x26, 0x24, 0x49, 0x46, 0x16, 0x13, 0x14, 0x11,
|
|
||||||
FT_ULTRA_BRUTE, 0x25, 0x15, 0x12,
|
|
||||||
FT_END };
|
|
||||||
return filters;
|
return filters;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsigned PackDjgpp2::findOverlapOverhead(const upx_bytep buf, const upx_bytep tbuf, unsigned range,
|
||||||
unsigned PackDjgpp2::findOverlapOverhead(const upx_bytep buf,
|
unsigned upper_limit) const {
|
||||||
const upx_bytep tbuf,
|
|
||||||
unsigned range,
|
|
||||||
unsigned upper_limit) const
|
|
||||||
{
|
|
||||||
unsigned o = super::findOverlapOverhead(buf, tbuf, range, upper_limit);
|
unsigned o = super::findOverlapOverhead(buf, tbuf, range, upper_limit);
|
||||||
o = (o + 0x3ff) & ~0x1ff;
|
o = (o + 0x3ff) & ~0x1ff;
|
||||||
return o;
|
return o;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Linker *PackDjgpp2::newLinker() const { return new ElfLinkerX86; }
|
||||||
|
|
||||||
Linker* PackDjgpp2::newLinker() const
|
void PackDjgpp2::buildLoader(const Filter *ft) {
|
||||||
{
|
|
||||||
return new ElfLinkerX86;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void PackDjgpp2::buildLoader(const Filter *ft)
|
|
||||||
{
|
|
||||||
// prepare loader
|
// prepare loader
|
||||||
initLoader(stub_i386_dos32_djgpp2, sizeof(stub_i386_dos32_djgpp2));
|
initLoader(stub_i386_dos32_djgpp2, sizeof(stub_i386_dos32_djgpp2));
|
||||||
addLoader("IDENTSTR,DJ2MAIN1",
|
addLoader("IDENTSTR,DJ2MAIN1", ft->id ? "DJCALLT1" : "",
|
||||||
ft->id ? "DJCALLT1" : "",
|
|
||||||
ph.first_offset_found == 1 ? "DJ2MAIN2" : "",
|
ph.first_offset_found == 1 ? "DJ2MAIN2" : "",
|
||||||
M_IS_LZMA(ph.method) ? "LZMA_INIT_STACK" : "",
|
M_IS_LZMA(ph.method) ? "LZMA_INIT_STACK" : "", getDecompressorSections(),
|
||||||
getDecompressorSections(),
|
M_IS_LZMA(ph.method) ? "LZMA_DONE_STACK" : "", "DJ2BSS00", nullptr);
|
||||||
M_IS_LZMA(ph.method) ? "LZMA_DONE_STACK" : "",
|
if (ft->id) {
|
||||||
"DJ2BSS00",
|
|
||||||
nullptr
|
|
||||||
);
|
|
||||||
if (ft->id)
|
|
||||||
{
|
|
||||||
assert(ft->calls > 0);
|
assert(ft->calls > 0);
|
||||||
addLoader("DJCALLT2", nullptr);
|
addLoader("DJCALLT2", nullptr);
|
||||||
addFilter32(ft->id);
|
addFilter32(ft->id);
|
||||||
@@ -114,22 +88,16 @@ void PackDjgpp2::buildLoader(const Filter *ft)
|
|||||||
addLoader("DJRETURN,+40C,UPX1HEAD", nullptr);
|
addLoader("DJRETURN,+40C,UPX1HEAD", nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
// util
|
// util
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
void PackDjgpp2::handleStub(OutputFile *fo)
|
void PackDjgpp2::handleStub(OutputFile *fo) {
|
||||||
{
|
if (fo && !opt->djgpp2_coff.coff) {
|
||||||
if (fo && !opt->djgpp2_coff.coff)
|
if (coff_offset > 0) {
|
||||||
{
|
|
||||||
if (coff_offset > 0)
|
|
||||||
{
|
|
||||||
// copy stub from exe
|
// copy stub from exe
|
||||||
Packer::handleStub(fi, fo, coff_offset);
|
Packer::handleStub(fi, fo, coff_offset);
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
// "stubify" stub
|
// "stubify" stub
|
||||||
info("Adding stub: %ld bytes", (long) sizeof(stub_i386_dos32_djgpp2_stubify));
|
info("Adding stub: %ld bytes", (long) sizeof(stub_i386_dos32_djgpp2_stubify));
|
||||||
fo->write(stub_i386_dos32_djgpp2_stubify, sizeof(stub_i386_dos32_djgpp2_stubify));
|
fo->write(stub_i386_dos32_djgpp2_stubify, sizeof(stub_i386_dos32_djgpp2_stubify));
|
||||||
@@ -137,9 +105,7 @@ void PackDjgpp2::handleStub(OutputFile *fo)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool is_dlm(InputFile *fi, unsigned coff_offset) {
|
||||||
static bool is_dlm(InputFile *fi, unsigned coff_offset)
|
|
||||||
{
|
|
||||||
unsigned char buf[4];
|
unsigned char buf[4];
|
||||||
unsigned off;
|
unsigned off;
|
||||||
|
|
||||||
@@ -158,9 +124,7 @@ static bool is_dlm(InputFile *fi, unsigned coff_offset)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void handle_allegropak(InputFile *fi, OutputFile *fo) {
|
||||||
static void handle_allegropak(InputFile *fi, OutputFile *fo)
|
|
||||||
{
|
|
||||||
unsigned char b[8];
|
unsigned char b[8];
|
||||||
int pfsize = 0;
|
int pfsize = 0;
|
||||||
|
|
||||||
@@ -177,8 +141,7 @@ static void handle_allegropak(InputFile *fi, OutputFile *fo)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
MemBuffer buf(0x4000);
|
MemBuffer buf(0x4000);
|
||||||
while (pfsize > 0)
|
while (pfsize > 0) {
|
||||||
{
|
|
||||||
const int len = UPX_MIN(pfsize, (int) buf.getSize());
|
const int len = UPX_MIN(pfsize, (int) buf.getSize());
|
||||||
fi->readx(buf, len);
|
fi->readx(buf, len);
|
||||||
fo->write(buf, len);
|
fo->write(buf, len);
|
||||||
@@ -186,9 +149,7 @@ static void handle_allegropak(InputFile *fi, OutputFile *fo)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int PackDjgpp2::readFileHeader() {
|
||||||
int PackDjgpp2::readFileHeader()
|
|
||||||
{
|
|
||||||
unsigned char hdr[0x1c];
|
unsigned char hdr[0x1c];
|
||||||
unsigned char magic[8];
|
unsigned char magic[8];
|
||||||
|
|
||||||
@@ -206,9 +167,7 @@ int PackDjgpp2::readFileHeader()
|
|||||||
fi->seek(coff_offset, SEEK_SET);
|
fi->seek(coff_offset, SEEK_SET);
|
||||||
if (fi->read(&coff_hdr, sizeof(coff_hdr)) != sizeof(coff_hdr))
|
if (fi->read(&coff_hdr, sizeof(coff_hdr)) != sizeof(coff_hdr))
|
||||||
throwCantPack("skipping djgpp symlink");
|
throwCantPack("skipping djgpp symlink");
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
fi->seek(coff_offset, SEEK_SET);
|
fi->seek(coff_offset, SEEK_SET);
|
||||||
fi->readx(&coff_hdr, 0xa8);
|
fi->readx(&coff_hdr, 0xa8);
|
||||||
}
|
}
|
||||||
@@ -226,23 +185,19 @@ int PackDjgpp2::readFileHeader()
|
|||||||
return UPX_F_DJGPP2_COFF;
|
return UPX_F_DJGPP2_COFF;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// "strip" debug info
|
// "strip" debug info
|
||||||
void PackDjgpp2::stripDebug()
|
void PackDjgpp2::stripDebug() {
|
||||||
{
|
|
||||||
coff_hdr.f_symptr = 0;
|
coff_hdr.f_symptr = 0;
|
||||||
coff_hdr.f_nsyms = 0;
|
coff_hdr.f_nsyms = 0;
|
||||||
coff_hdr.f_flags = 0x10f; // 0x100: "32 bit machine: LSB first"
|
coff_hdr.f_flags = 0x10f; // 0x100: "32 bit machine: LSB first"
|
||||||
memset(text->misc, 0, 12);
|
memset(text->misc, 0, 12);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
//
|
//
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
bool PackDjgpp2::canPack()
|
bool PackDjgpp2::canPack() {
|
||||||
{
|
|
||||||
if (!readFileHeader())
|
if (!readFileHeader())
|
||||||
return false;
|
return false;
|
||||||
if (is_dlm(fi, coff_offset))
|
if (is_dlm(fi, coff_offset))
|
||||||
@@ -253,38 +208,32 @@ bool PackDjgpp2::canPack()
|
|||||||
throwAlreadyPacked();
|
throwAlreadyPacked();
|
||||||
|
|
||||||
// Check for gap in vaddr between text and data, or between data and bss.
|
// Check for gap in vaddr between text and data, or between data and bss.
|
||||||
if (text->vaddr + text->size != data->vaddr
|
if (text->vaddr + text->size != data->vaddr || data->vaddr + data->size != bss->vaddr) {
|
||||||
|| data->vaddr + data->size != bss->vaddr)
|
|
||||||
{
|
|
||||||
// "Non-standard" layout of text,data,bss: not contiguous in vaddr.
|
// "Non-standard" layout of text,data,bss: not contiguous in vaddr.
|
||||||
// But should be OK if no overlap.
|
// But should be OK if no overlap.
|
||||||
|
|
||||||
// Check for no overlap of text and data:
|
// Check for no overlap of text and data:
|
||||||
// neither by vaddr, nor by image data
|
// neither by vaddr, nor by image data
|
||||||
if (text->vaddr + text->size <= data->vaddr &&
|
if (text->vaddr + text->size <= data->vaddr &&
|
||||||
data->scnptr - text->scnptr <= data->vaddr - text->vaddr)
|
data->scnptr - text->scnptr <= data->vaddr - text->vaddr) {
|
||||||
{
|
|
||||||
// Examples: Quake1; FreePascal(DOS) install.exe (github-issue45)
|
// Examples: Quake1; FreePascal(DOS) install.exe (github-issue45)
|
||||||
// Hack: enlarge text image data to eliminate the gap.
|
// Hack: enlarge text image data to eliminate the gap.
|
||||||
text->size = coff_hdr.a_tsize = data->scnptr - text->scnptr;
|
text->size = coff_hdr.a_tsize = data->scnptr - text->scnptr;
|
||||||
// But complain if this causes overlap in vaddr
|
// But complain if this causes overlap in vaddr
|
||||||
if (text->vaddr + text->size > data->vaddr)
|
if (text->vaddr + text->size > data->vaddr)
|
||||||
throwAlreadyPacked();
|
throwAlreadyPacked();
|
||||||
}
|
} else
|
||||||
else
|
|
||||||
throwAlreadyPacked();
|
throwAlreadyPacked();
|
||||||
}
|
}
|
||||||
// FIXME: check for Linux etc.
|
// FIXME: check for Linux etc.
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
//
|
//
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
void PackDjgpp2::pack(OutputFile *fo)
|
void PackDjgpp2::pack(OutputFile *fo) {
|
||||||
{
|
|
||||||
handleStub(fo);
|
handleStub(fo);
|
||||||
|
|
||||||
// patch coff header #1: "strip" debug info
|
// patch coff header #1: "strip" debug info
|
||||||
@@ -313,7 +262,8 @@ void PackDjgpp2::pack(OutputFile *fo)
|
|||||||
ft.buf_len = usize - data->size;
|
ft.buf_len = usize - data->size;
|
||||||
ft.addvalue = text->vaddr - hdrsize;
|
ft.addvalue = text->vaddr - hdrsize;
|
||||||
// compress
|
// compress
|
||||||
upx_compress_config_t cconf; cconf.reset();
|
upx_compress_config_t cconf;
|
||||||
|
cconf.reset();
|
||||||
// limit stack size needed for runtime decompression
|
// limit stack size needed for runtime decompression
|
||||||
cconf.conf_lzma.max_num_probs = 1846 + (768 << 4); // ushort: ~28 KiB stack
|
cconf.conf_lzma.max_num_probs = 1846 + (768 << 4); // ushort: ~28 KiB stack
|
||||||
compressWithFilters(&ft, 512, &cconf);
|
compressWithFilters(&ft, 512, &cconf);
|
||||||
@@ -331,7 +281,8 @@ void PackDjgpp2::pack(OutputFile *fo)
|
|||||||
|
|
||||||
text->scnptr = sizeof(coff_hdr);
|
text->scnptr = sizeof(coff_hdr);
|
||||||
data->scnptr = text->scnptr + text->size;
|
data->scnptr = text->scnptr + text->size;
|
||||||
data->vaddr = bss->vaddr + ((data->scnptr + data->size) & 0x1ff) - data->size + ph.overlap_overhead - 0x200;
|
data->vaddr = bss->vaddr + ((data->scnptr + data->size) & 0x1ff) - data->size +
|
||||||
|
ph.overlap_overhead - 0x200;
|
||||||
coff_hdr.f_nscns = 3;
|
coff_hdr.f_nscns = 3;
|
||||||
|
|
||||||
linker->defineSymbol("original_entry", coff_hdr.a_entry);
|
linker->defineSymbol("original_entry", coff_hdr.a_entry);
|
||||||
@@ -391,13 +342,11 @@ void PackDjgpp2::pack(OutputFile *fo)
|
|||||||
throwNotCompressible();
|
throwNotCompressible();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
//
|
//
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
int PackDjgpp2::canUnpack()
|
int PackDjgpp2::canUnpack() {
|
||||||
{
|
|
||||||
if (!readFileHeader())
|
if (!readFileHeader())
|
||||||
return false;
|
return false;
|
||||||
if (is_dlm(fi, coff_offset))
|
if (is_dlm(fi, coff_offset))
|
||||||
@@ -406,13 +355,11 @@ int PackDjgpp2::canUnpack()
|
|||||||
return readPackHeader(4096) ? 1 : -1;
|
return readPackHeader(4096) ? 1 : -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
//
|
//
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
void PackDjgpp2::unpack(OutputFile *fo)
|
void PackDjgpp2::unpack(OutputFile *fo) {
|
||||||
{
|
|
||||||
handleStub(fo);
|
handleStub(fo);
|
||||||
|
|
||||||
ibuf.alloc(ph.c_len);
|
ibuf.alloc(ph.c_len);
|
||||||
@@ -428,8 +375,7 @@ void PackDjgpp2::unpack(OutputFile *fo)
|
|||||||
text = chdr->sh;
|
text = chdr->sh;
|
||||||
data = text + 1;
|
data = text + 1;
|
||||||
|
|
||||||
const unsigned hdrsize = 20 + 28
|
const unsigned hdrsize = 20 + 28 + sizeof(external_scnhdr_t) * chdr->f_nscns;
|
||||||
+ sizeof(external_scnhdr_t) * chdr->f_nscns;
|
|
||||||
|
|
||||||
unsigned addvalue;
|
unsigned addvalue;
|
||||||
if (ph.version >= 14)
|
if (ph.version >= 14)
|
||||||
@@ -438,13 +384,11 @@ void PackDjgpp2::unpack(OutputFile *fo)
|
|||||||
addvalue = text->vaddr & ~0x1ff; // for old versions
|
addvalue = text->vaddr & ~0x1ff; // for old versions
|
||||||
|
|
||||||
// unfilter
|
// unfilter
|
||||||
if (ph.filter)
|
if (ph.filter) {
|
||||||
{
|
|
||||||
Filter ft(ph.level);
|
Filter ft(ph.level);
|
||||||
ft.init(ph.filter, addvalue);
|
ft.init(ph.filter, addvalue);
|
||||||
ft.cto = (unsigned char) ph.filter_cto;
|
ft.cto = (unsigned char) ph.filter_cto;
|
||||||
if (ph.version < 11)
|
if (ph.version < 11) {
|
||||||
{
|
|
||||||
unsigned char ctobuf[4];
|
unsigned char ctobuf[4];
|
||||||
fi->readx(ctobuf, 4);
|
fi->readx(ctobuf, 4);
|
||||||
ft.cto = (unsigned char) (get_le32(ctobuf) >> 24);
|
ft.cto = (unsigned char) (get_le32(ctobuf) >> 24);
|
||||||
@@ -452,17 +396,14 @@ void PackDjgpp2::unpack(OutputFile *fo)
|
|||||||
ft.unfilter(obuf, ph.u_len - data->size);
|
ft.unfilter(obuf, ph.u_len - data->size);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ph.version < 14)
|
if (ph.version < 14) {
|
||||||
{
|
|
||||||
// fixup for the aligning bug in strip 2.8+
|
// fixup for the aligning bug in strip 2.8+
|
||||||
text->scnptr &= 0x1ff;
|
text->scnptr &= 0x1ff;
|
||||||
data->scnptr = text->scnptr + text->size;
|
data->scnptr = text->scnptr + text->size;
|
||||||
// write decompressed file
|
// write decompressed file
|
||||||
if (fo)
|
if (fo)
|
||||||
fo->write(obuf, ph.u_len);
|
fo->write(obuf, ph.u_len);
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
// write the header
|
// write the header
|
||||||
// some padding might be required between the end
|
// some padding might be required between the end
|
||||||
// of the header and the start of the .text section
|
// of the header and the start of the .text section
|
||||||
@@ -470,8 +411,7 @@ void PackDjgpp2::unpack(OutputFile *fo)
|
|||||||
const unsigned padding = text->scnptr - hdrsize;
|
const unsigned padding = text->scnptr - hdrsize;
|
||||||
ibuf.clear(0, padding);
|
ibuf.clear(0, padding);
|
||||||
|
|
||||||
if (fo)
|
if (fo) {
|
||||||
{
|
|
||||||
fo->write(obuf, hdrsize);
|
fo->write(obuf, hdrsize);
|
||||||
fo->write(ibuf, padding);
|
fo->write(ibuf, padding);
|
||||||
fo->write(obuf + hdrsize, ph.u_len - hdrsize);
|
fo->write(obuf + hdrsize, ph.u_len - hdrsize);
|
||||||
|
|||||||
+14
-16
@@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
This file is part of the UPX executable compressor.
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
Copyright (C) 1996-2022 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2022 Laszlo Molnar
|
Copyright (C) 1996-2023 Laszlo Molnar
|
||||||
All Rights Reserved.
|
All Rights Reserved.
|
||||||
|
|
||||||
UPX and the UCL library are free software; you can redistribute them
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
@@ -25,17 +25,15 @@
|
|||||||
<markus@oberhumer.com> <ezerotven+github@gmail.com>
|
<markus@oberhumer.com> <ezerotven+github@gmail.com>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
#ifndef __UPX_P_DJGPP2_H
|
#ifndef UPX_P_DJGPP2_H__
|
||||||
#define __UPX_P_DJGPP2_H 1
|
#define UPX_P_DJGPP2_H__ 1
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
// djgpp2/coff
|
// djgpp2/coff
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
class PackDjgpp2 final : public Packer
|
class PackDjgpp2 final : public Packer {
|
||||||
{
|
|
||||||
typedef Packer super;
|
typedef Packer super;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
@@ -43,7 +41,9 @@ public:
|
|||||||
virtual int getVersion() const override { return 14; }
|
virtual int getVersion() const override { return 14; }
|
||||||
virtual int getFormat() const override { return UPX_F_DJGPP2_COFF; }
|
virtual int getFormat() const override { return UPX_F_DJGPP2_COFF; }
|
||||||
virtual const char *getName() const override { return "djgpp2/coff"; }
|
virtual const char *getName() const override { return "djgpp2/coff"; }
|
||||||
virtual const char *getFullName(const options_t *) const override { return "i386-dos32.djgpp2.coff"; }
|
virtual const char *getFullName(const options_t *) const override {
|
||||||
|
return "i386-dos32.djgpp2.coff";
|
||||||
|
}
|
||||||
virtual const int *getCompressionMethods(int method, int level) const override;
|
virtual const int *getCompressionMethods(int method, int level) const override;
|
||||||
virtual const int *getFilters() const override;
|
virtual const int *getFilters() const override;
|
||||||
|
|
||||||
@@ -57,8 +57,7 @@ protected:
|
|||||||
void handleStub(OutputFile *fo);
|
void handleStub(OutputFile *fo);
|
||||||
int readFileHeader();
|
int readFileHeader();
|
||||||
|
|
||||||
virtual unsigned findOverlapOverhead(const upx_bytep buf,
|
virtual unsigned findOverlapOverhead(const upx_bytep buf, const upx_bytep tbuf,
|
||||||
const upx_bytep tbuf,
|
|
||||||
unsigned range = 0,
|
unsigned range = 0,
|
||||||
unsigned upper_limit = ~0u) const override;
|
unsigned upper_limit = ~0u) const override;
|
||||||
virtual void buildLoader(const Filter *ft) override;
|
virtual void buildLoader(const Filter *ft) override;
|
||||||
@@ -66,16 +65,16 @@ protected:
|
|||||||
|
|
||||||
unsigned coff_offset;
|
unsigned coff_offset;
|
||||||
|
|
||||||
__packed_struct(external_scnhdr_t)
|
struct alignas(1) external_scnhdr_t {
|
||||||
char _[12]; // name, paddr
|
char _[12]; // name, paddr
|
||||||
LE32 vaddr;
|
LE32 vaddr;
|
||||||
LE32 size;
|
LE32 size;
|
||||||
LE32 scnptr;
|
LE32 scnptr;
|
||||||
char misc[12]; // relptr, lnnoptr, nreloc, nlnno
|
char misc[12]; // relptr, lnnoptr, nreloc, nlnno
|
||||||
char __[4]; // flags
|
char __[4]; // flags
|
||||||
__packed_struct_end()
|
};
|
||||||
|
|
||||||
__packed_struct(coff_header_t)
|
struct alignas(1) coff_header_t {
|
||||||
// ext_file_hdr
|
// ext_file_hdr
|
||||||
LE16 f_magic;
|
LE16 f_magic;
|
||||||
LE16 f_nscns;
|
LE16 f_nscns;
|
||||||
@@ -96,7 +95,7 @@ protected:
|
|||||||
|
|
||||||
// section headers
|
// section headers
|
||||||
external_scnhdr_t sh[3];
|
external_scnhdr_t sh[3];
|
||||||
__packed_struct_end()
|
};
|
||||||
|
|
||||||
coff_header_t coff_hdr;
|
coff_header_t coff_hdr;
|
||||||
external_scnhdr_t *text, *data, *bss;
|
external_scnhdr_t *text, *data, *bss;
|
||||||
@@ -104,7 +103,6 @@ protected:
|
|||||||
void stripDebug();
|
void stripDebug();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
#endif /* already included */
|
#endif /* already included */
|
||||||
|
|
||||||
/* vim:set ts=4 sw=4 et: */
|
/* vim:set ts=4 sw=4 et: */
|
||||||
|
|||||||
+2
-2
@@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
This file is part of the UPX executable compressor.
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
Copyright (C) 1996-2022 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2022 Laszlo Molnar
|
Copyright (C) 1996-2023 Laszlo Molnar
|
||||||
All Rights Reserved.
|
All Rights Reserved.
|
||||||
|
|
||||||
UPX and the UCL library are free software; you can redistribute them
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
|
|||||||
+36
-35
@@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
This file is part of the UPX executable compressor.
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
Copyright (C) 1996-2022 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2022 Laszlo Molnar
|
Copyright (C) 1996-2023 Laszlo Molnar
|
||||||
All Rights Reserved.
|
All Rights Reserved.
|
||||||
|
|
||||||
UPX and the UCL library are free software; you can redistribute them
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
@@ -41,15 +41,15 @@
|
|||||||
EI_DATA = 5, /* Data encoding */
|
EI_DATA = 5, /* Data encoding */
|
||||||
EI_VERSION = 6,
|
EI_VERSION = 6,
|
||||||
EI_OSABI = 7,
|
EI_OSABI = 7,
|
||||||
EI_ABIVERSION = 8
|
EI_ABIVERSION = 8,
|
||||||
};
|
};
|
||||||
enum { // e_ident[EI_CLASS]
|
enum { // e_ident[EI_CLASS]
|
||||||
ELFCLASS32 = 1, /* 32-bit objects */
|
ELFCLASS32 = 1, /* 32-bit objects */
|
||||||
ELFCLASS64 = 2 /* 64-bit objects */
|
ELFCLASS64 = 2, /* 64-bit objects */
|
||||||
};
|
};
|
||||||
enum { // e_ident[EI_DATA]
|
enum { // e_ident[EI_DATA]
|
||||||
ELFDATA2LSB = 1, /* 2's complement, little endian */
|
ELFDATA2LSB = 1, /* 2's complement, little endian */
|
||||||
ELFDATA2MSB = 2 /* 2's complement, big endian */
|
ELFDATA2MSB = 2, /* 2's complement, big endian */
|
||||||
};
|
};
|
||||||
enum { // e_ident[EI_OSABI]
|
enum { // e_ident[EI_OSABI]
|
||||||
ELFOSABI_NONE = 0, // == ELFOSABI_SYSV
|
ELFOSABI_NONE = 0, // == ELFOSABI_SYSV
|
||||||
@@ -57,14 +57,14 @@
|
|||||||
ELFOSABI_LINUX = 3,
|
ELFOSABI_LINUX = 3,
|
||||||
ELFOSABI_FREEBSD = 9,
|
ELFOSABI_FREEBSD = 9,
|
||||||
ELFOSABI_OPENBSD = 12,
|
ELFOSABI_OPENBSD = 12,
|
||||||
ELFOSABI_ARM = 97
|
ELFOSABI_ARM = 97,
|
||||||
};
|
};
|
||||||
enum { // e_type
|
enum { // e_type
|
||||||
ET_NONE = 0, /* No file type */
|
ET_NONE = 0, /* No file type */
|
||||||
ET_REL = 1, /* Relocatable file */
|
ET_REL = 1, /* Relocatable file */
|
||||||
ET_EXEC = 2, /* Executable file */
|
ET_EXEC = 2, /* Executable file */
|
||||||
ET_DYN = 3, /* Shared object file */
|
ET_DYN = 3, /* Shared object file */
|
||||||
ET_CORE = 4 /* Core file */
|
ET_CORE = 4, /* Core file */
|
||||||
};
|
};
|
||||||
enum { // e_machine
|
enum { // e_machine
|
||||||
EM_386 = 3,
|
EM_386 = 3,
|
||||||
@@ -74,11 +74,11 @@
|
|||||||
EM_PPC64 = 21,
|
EM_PPC64 = 21,
|
||||||
EM_ARM = 40,
|
EM_ARM = 40,
|
||||||
EM_X86_64 = 62,
|
EM_X86_64 = 62,
|
||||||
EM_AARCH64 = 183
|
EM_AARCH64 = 183,
|
||||||
|
|
||||||
};
|
};
|
||||||
enum { // e_version
|
enum { // e_version
|
||||||
EV_CURRENT = 1
|
EV_CURRENT = 1,
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -91,15 +91,16 @@
|
|||||||
PT_DYNAMIC = 2, /* Dynamic linking information */
|
PT_DYNAMIC = 2, /* Dynamic linking information */
|
||||||
PT_INTERP = 3, /* Name of program interpreter */
|
PT_INTERP = 3, /* Name of program interpreter */
|
||||||
PT_NOTE = 4, /* Auxiliary information (esp. OpenBSD) */
|
PT_NOTE = 4, /* Auxiliary information (esp. OpenBSD) */
|
||||||
PT_PHDR = 6 /* Entry for header table itself */
|
PT_PHDR = 6, /* Entry for header table itself */
|
||||||
, PT_NUM = 8 /* Number of defined types in low range */
|
PT_NUM = 8, /* Number of defined types in low range */
|
||||||
, PT_GNU_STACK = 0x6474e551 /* Indicates stack executability */
|
PT_GNU_STACK = 0x6474e551, /* Indicates stack executability */
|
||||||
|
PT_GNU_RELRO = 0x6474e552, /* Read-only after relocation */
|
||||||
};
|
};
|
||||||
|
|
||||||
enum { // p_flags
|
enum { // p_flags
|
||||||
PF_X = 1, /* Segment is executable */
|
PF_X = 1, /* Segment is executable */
|
||||||
PF_W = 2, /* Segment is writable */
|
PF_W = 2, /* Segment is writable */
|
||||||
PF_R = 4 /* Segment is readable */
|
PF_R = 4, /* Segment is readable */
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -125,12 +126,12 @@
|
|||||||
SHT_PREINIT_ARRAY = 16, /* Array of pre-constructors */
|
SHT_PREINIT_ARRAY = 16, /* Array of pre-constructors */
|
||||||
SHT_GROUP = 17, /* Section group */
|
SHT_GROUP = 17, /* Section group */
|
||||||
SHT_SYMTAB_SHNDX = 18, /* Extended section indeces */
|
SHT_SYMTAB_SHNDX = 18, /* Extended section indeces */
|
||||||
SHT_GNU_LIBLIST = 0x6ffffff7 /* Prelink library list */
|
SHT_GNU_LIBLIST = 0x6ffffff7, /* Prelink library list */
|
||||||
, SHT_GNU_HASH = 0x6ffffff6 /* GNU-style hash table. */
|
SHT_GNU_HASH = 0x6ffffff6, /* GNU-style hash table. */
|
||||||
|
|
||||||
, SHT_LOOS = 0x60000000 /* LOcal OS; SHT_ANDROID_REL{,A} is +1, +2 */
|
SHT_LOOS = 0x60000000, /* LOcal OS; SHT_ANDROID_REL{,A} is +1, +2 */
|
||||||
, SHT_LOPROC = 0x70000000/* Start of processor-specific */
|
SHT_LOPROC = 0x70000000, /* Start of processor-specific */
|
||||||
, SHT_ARM_ATTRIBUTES = (SHT_LOPROC + 3) /* ARM attributes section. */
|
SHT_ARM_ATTRIBUTES = (SHT_LOPROC + 3), /* ARM attributes section. */
|
||||||
};
|
};
|
||||||
|
|
||||||
enum { // sh_flags
|
enum { // sh_flags
|
||||||
@@ -140,7 +141,7 @@
|
|||||||
SHF_MERGE = (1 << 4), /* Might be merged */
|
SHF_MERGE = (1 << 4), /* Might be merged */
|
||||||
SHF_STRINGS = (1 << 5), /* Contains nul-terminated strings */
|
SHF_STRINGS = (1 << 5), /* Contains nul-terminated strings */
|
||||||
SHF_INFO_LINK = (1 << 6), /* 'sh_info' contains SHT index */
|
SHF_INFO_LINK = (1 << 6), /* 'sh_info' contains SHT index */
|
||||||
SHF_LINK_ORDER = (1 << 7) /* Preserve order after combining */
|
SHF_LINK_ORDER = (1 << 7), /* Preserve order after combining */
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -182,11 +183,11 @@
|
|||||||
DT_VERSYM = 0x6ffffff0, /* version[] for each symbol */
|
DT_VERSYM = 0x6ffffff0, /* version[] for each symbol */
|
||||||
DT_FLAGS_1 = 0x6ffffffb, /* DF_1_* */
|
DT_FLAGS_1 = 0x6ffffffb, /* DF_1_* */
|
||||||
DT_VERDEF = 0x6ffffffc, /* version definitions[] */
|
DT_VERDEF = 0x6ffffffc, /* version definitions[] */
|
||||||
DT_VERNEED = 0x6ffffffe /* version[] needed */
|
DT_VERNEED = 0x6ffffffe, /* version[] needed */
|
||||||
};
|
};
|
||||||
enum { // DT_FLAGS_1
|
enum { // DT_FLAGS_1
|
||||||
DF_1_NOW = 0x00000001, /* Set RTLD_NOW for this object. */
|
DF_1_NOW = 0x00000001, /* Set RTLD_NOW for this object. */
|
||||||
DF_1_PIE = 0x08000000 // Position-Independent Executable (main program)
|
DF_1_PIE = 0x08000000, // Position-Independent Executable (main program)
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -196,7 +197,7 @@
|
|||||||
enum { // st_bind (high 4 bits of st_info)
|
enum { // st_bind (high 4 bits of st_info)
|
||||||
STB_LOCAL = 0, /* Local symbol */
|
STB_LOCAL = 0, /* Local symbol */
|
||||||
STB_GLOBAL = 1, /* Global symbol */
|
STB_GLOBAL = 1, /* Global symbol */
|
||||||
STB_WEAK = 2 /* Weak symbol */
|
STB_WEAK = 2, /* Weak symbol */
|
||||||
};
|
};
|
||||||
|
|
||||||
enum { // st_type (low 4 bits of st_info)
|
enum { // st_type (low 4 bits of st_info)
|
||||||
@@ -206,20 +207,20 @@
|
|||||||
STT_SECTION = 3, /* Symbol associated with a section */
|
STT_SECTION = 3, /* Symbol associated with a section */
|
||||||
STT_FILE = 4, /* Symbol's name is file name */
|
STT_FILE = 4, /* Symbol's name is file name */
|
||||||
STT_COMMON = 5, /* Symbol is a common data object */
|
STT_COMMON = 5, /* Symbol is a common data object */
|
||||||
STT_TLS = 6 /* Symbol is thread-local data object*/
|
STT_TLS = 6, /* Symbol is thread-local data object*/
|
||||||
};
|
};
|
||||||
|
|
||||||
enum { // st_other (visibility)
|
enum { // st_other (visibility)
|
||||||
STV_DEFAULT = 0, /* Default symbol visibility rules */
|
STV_DEFAULT = 0, /* Default symbol visibility rules */
|
||||||
STV_INTERNAL = 1, /* Processor specific hidden class */
|
STV_INTERNAL = 1, /* Processor specific hidden class */
|
||||||
STV_HIDDEN = 2, /* Sym unavailable in other modules */
|
STV_HIDDEN = 2, /* Sym unavailable in other modules */
|
||||||
STV_PROTECTED= 3 /* Not preemptible, not exported */
|
STV_PROTECTED= 3, /* Not preemptible, not exported */
|
||||||
};
|
};
|
||||||
|
|
||||||
enum { // st_shndx
|
enum { // st_shndx
|
||||||
SHN_UNDEF = 0, /* Undefined section */
|
SHN_UNDEF = 0, /* Undefined section */
|
||||||
SHN_ABS = 0xfff1, /* Associated symbol is absolute */
|
SHN_ABS = 0xfff1, /* Associated symbol is absolute */
|
||||||
SHN_COMMON = 0xfff2 /* Associated symbol is common */
|
SHN_COMMON = 0xfff2, /* Associated symbol is common */
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -246,13 +247,13 @@
|
|||||||
R_ARM_JUMP_SLOT = 22,
|
R_ARM_JUMP_SLOT = 22,
|
||||||
R_PPC_JMP_SLOT = 21,
|
R_PPC_JMP_SLOT = 21,
|
||||||
R_PPC64_JMP_SLOT = R_PPC_JMP_SLOT,
|
R_PPC64_JMP_SLOT = R_PPC_JMP_SLOT,
|
||||||
R_X86_64_JUMP_SLOT = 7
|
R_X86_64_JUMP_SLOT = 7,
|
||||||
|
|
||||||
, R_ARM_ABS32 = 2
|
R_ARM_ABS32 = 2,
|
||||||
, R_ARM_GLOB_DAT = 21
|
R_ARM_GLOB_DAT = 21,
|
||||||
|
|
||||||
, R_AARCH64_ABS64 = 257
|
R_AARCH64_ABS64 = 257,
|
||||||
, R_AARCH64_GLOB_DAT = 1025
|
R_AARCH64_GLOB_DAT = 1025,
|
||||||
|
|
||||||
};
|
};
|
||||||
#endif //}
|
#endif //}
|
||||||
@@ -271,7 +272,7 @@
|
|||||||
#define ELF_NOTE_NETBSD_NAME "NetBSD\0"
|
#define ELF_NOTE_NETBSD_NAME "NetBSD\0"
|
||||||
NHDR_NETBSD_TAG = 1,
|
NHDR_NETBSD_TAG = 1,
|
||||||
NHDR_CHECKSUM_TAG = 2,
|
NHDR_CHECKSUM_TAG = 2,
|
||||||
NHDR_PAX_TAG = 3
|
NHDR_PAX_TAG = 3,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum { // descsz descriptor sizes
|
enum { // descsz descriptor sizes
|
||||||
@@ -279,20 +280,20 @@
|
|||||||
NETBSD_DESCSZ = 4, // major_ver * (10**8) + minor
|
NETBSD_DESCSZ = 4, // major_ver * (10**8) + minor
|
||||||
OPENBSD_DESCSZ = 4, // 32-bit zero
|
OPENBSD_DESCSZ = 4, // 32-bit zero
|
||||||
// CHECKSUM_DESCSZ is 2*sizeof(short) + sizeof(checksum)
|
// CHECKSUM_DESCSZ is 2*sizeof(short) + sizeof(checksum)
|
||||||
PAX_DESCSZ = 4 // 32-bit mask
|
PAX_DESCSZ = 4, // 32-bit mask
|
||||||
};
|
};
|
||||||
|
|
||||||
enum { // GNU OS/version
|
enum { // GNU OS/version
|
||||||
GNU_OS_LINUX = 0,
|
GNU_OS_LINUX = 0,
|
||||||
GNU_OS_HURD = 1,
|
GNU_OS_HURD = 1,
|
||||||
GNU_OS_SOLARIS = 2
|
GNU_OS_SOLARIS = 2,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum { // NetBSD checksum methods
|
enum { // NetBSD checksum methods
|
||||||
CHECKSUM_CRC32 = 1,
|
CHECKSUM_CRC32 = 1,
|
||||||
CHECKSUM_MD5 = 2,
|
CHECKSUM_MD5 = 2,
|
||||||
CHECKSUM_SHA1 = 3,
|
CHECKSUM_SHA1 = 3,
|
||||||
CHECKSUM_SHA256 = 4
|
CHECKSUM_SHA256 = 4,
|
||||||
};
|
};
|
||||||
|
|
||||||
#define ELF_NOTE_PAX_NAME "PaX\0"
|
#define ELF_NOTE_PAX_NAME "PaX\0"
|
||||||
@@ -302,7 +303,7 @@
|
|||||||
PAX_GUARD = (1<<2), /* force enable SEGVguard */
|
PAX_GUARD = (1<<2), /* force enable SEGVguard */
|
||||||
PAX_NOGUARD = (1<<3), /* force disable SEGVguard */
|
PAX_NOGUARD = (1<<3), /* force disable SEGVguard */
|
||||||
PAX_ASLR = (1<<4), /* force enable ASLR */
|
PAX_ASLR = (1<<4), /* force enable ASLR */
|
||||||
PAX_NOASLR = (1<<5) /* force disable ASLR */
|
PAX_NOASLR = (1<<5), /* force disable ASLR */
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
+118
-218
@@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
This file is part of the UPX executable compressor.
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
Copyright (C) 1996-2022 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2022 Laszlo Molnar
|
Copyright (C) 1996-2023 Laszlo Molnar
|
||||||
All Rights Reserved.
|
All Rights Reserved.
|
||||||
|
|
||||||
UPX and the UCL library are free software; you can redistribute them
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
@@ -25,7 +25,6 @@
|
|||||||
<markus@oberhumer.com> <ezerotven+github@gmail.com>
|
<markus@oberhumer.com> <ezerotven+github@gmail.com>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#include "conf.h"
|
#include "conf.h"
|
||||||
#include "file.h"
|
#include "file.h"
|
||||||
#include "filter.h"
|
#include "filter.h"
|
||||||
@@ -33,7 +32,7 @@
|
|||||||
#include "p_exe.h"
|
#include "p_exe.h"
|
||||||
#include "linker.h"
|
#include "linker.h"
|
||||||
|
|
||||||
static const
|
static const CLANG_FORMAT_DUMMY_STATEMENT
|
||||||
#include "stub/i086-dos16.exe.h"
|
#include "stub/i086-dos16.exe.h"
|
||||||
|
|
||||||
#define RSFCRI 4096 // Reserved Space For Compressed Relocation Info
|
#define RSFCRI 4096 // Reserved Space For Compressed Relocation Info
|
||||||
@@ -42,14 +41,11 @@ static const
|
|||||||
|
|
||||||
#define DI_LIMIT 0xff00 // see the assembly why
|
#define DI_LIMIT 0xff00 // see the assembly why
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
//
|
//
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
PackExe::PackExe(InputFile *f) :
|
PackExe::PackExe(InputFile *f) : super(f) {
|
||||||
super(f)
|
|
||||||
{
|
|
||||||
bele = &N_BELE_RTP::le_policy;
|
bele = &N_BELE_RTP::le_policy;
|
||||||
COMPILE_TIME_ASSERT(sizeof(exe_header_t) == 32)
|
COMPILE_TIME_ASSERT(sizeof(exe_header_t) == 32)
|
||||||
COMPILE_TIME_ASSERT_ALIGNED1(exe_header_t)
|
COMPILE_TIME_ASSERT_ALIGNED1(exe_header_t)
|
||||||
@@ -58,9 +54,7 @@ PackExe::PackExe(InputFile *f) :
|
|||||||
use_clear_dirty_stack = false;
|
use_clear_dirty_stack = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const int *PackExe::getCompressionMethods(int method, int level) const {
|
||||||
const int *PackExe::getCompressionMethods(int method, int level) const
|
|
||||||
{
|
|
||||||
bool small = ih_imagesize <= 256 * 1024;
|
bool small = ih_imagesize <= 256 * 1024;
|
||||||
// disable lzma for "--brute" unless explicitly given "--lzma"
|
// disable lzma for "--brute" unless explicitly given "--lzma"
|
||||||
// WARNING: this side effect may persists for later files;
|
// WARNING: this side effect may persists for later files;
|
||||||
@@ -70,15 +64,9 @@ const int *PackExe::getCompressionMethods(int method, int level) const
|
|||||||
return Packer::getDefaultCompressionMethods_8(method, level, small);
|
return Packer::getDefaultCompressionMethods_8(method, level, small);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const int *PackExe::getFilters() const { return nullptr; }
|
||||||
|
|
||||||
const int *PackExe::getFilters() const
|
int PackExe::fillExeHeader(struct exe_header_t *eh) const {
|
||||||
{
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int PackExe::fillExeHeader(struct exe_header_t *eh) const
|
|
||||||
{
|
|
||||||
#define oh (*eh)
|
#define oh (*eh)
|
||||||
// fill new exe header
|
// fill new exe header
|
||||||
int flag = 0;
|
int flag = 0;
|
||||||
@@ -106,8 +94,7 @@ int PackExe::fillExeHeader(struct exe_header_t *eh) const
|
|||||||
oh.ss = ph.c_len / 16 + destpara;
|
oh.ss = ph.c_len / 16 + destpara;
|
||||||
if (ih.ss * 16 + ih.sp < 0x100000 && ih.ss > oh.ss && ih.sp > 0x200)
|
if (ih.ss * 16 + ih.sp < 0x100000 && ih.ss > oh.ss && ih.sp > 0x200)
|
||||||
oh.ss = ih.ss;
|
oh.ss = ih.ss;
|
||||||
if (oh.ss*16 + 0x50 < ih.ss*16 + ih.sp
|
if (oh.ss * 16 + 0x50 < ih.ss * 16 + ih.sp && oh.ss * 16 + 0x200 > ih.ss * 16 + ih.sp)
|
||||||
&& oh.ss*16 + 0x200 > ih.ss*16 + ih.sp)
|
|
||||||
oh.ss += 0x20;
|
oh.ss += 0x20;
|
||||||
|
|
||||||
if (oh.ss != ih.ss)
|
if (oh.ss != ih.ss)
|
||||||
@@ -118,58 +105,38 @@ int PackExe::fillExeHeader(struct exe_header_t *eh) const
|
|||||||
#undef oh
|
#undef oh
|
||||||
}
|
}
|
||||||
|
|
||||||
void PackExe::addLoaderEpilogue(int flag)
|
void PackExe::addLoaderEpilogue(int flag) {
|
||||||
{
|
|
||||||
addLoader("EXEMAIN5", nullptr);
|
addLoader("EXEMAIN5", nullptr);
|
||||||
if (relocsize)
|
if (relocsize)
|
||||||
addLoader(ph.u_len <= DI_LIMIT || (ph.u_len & 0x7fff) >= relocsize ? "EXENOADJ" : "EXEADJUS",
|
addLoader(ph.u_len <= DI_LIMIT || (ph.u_len & 0x7fff) >= relocsize ? "EXENOADJ"
|
||||||
"EXERELO1",
|
: "EXEADJUS",
|
||||||
has_9a ? "EXEREL9A" : "",
|
"EXERELO1", has_9a ? "EXEREL9A" : "", "EXERELO2",
|
||||||
"EXERELO2",
|
ih_exesize > 0xFE00 ? "EXEREBIG" : "", "EXERELO3", nullptr);
|
||||||
ih_exesize > 0xFE00 ? "EXEREBIG" : "",
|
addLoader("EXEMAIN8", device_driver ? "DEVICEEND" : "", (flag & SS) ? "EXESTACK" : "",
|
||||||
"EXERELO3",
|
(flag & SP) ? "EXESTASP" : "", (flag & USEJUMP) ? "EXEJUMPF" : "", nullptr);
|
||||||
nullptr
|
|
||||||
);
|
|
||||||
addLoader("EXEMAIN8",
|
|
||||||
device_driver ? "DEVICEEND" : "",
|
|
||||||
(flag & SS) ? "EXESTACK" : "",
|
|
||||||
(flag & SP) ? "EXESTASP" : "",
|
|
||||||
(flag & USEJUMP) ? "EXEJUMPF" : "",
|
|
||||||
nullptr
|
|
||||||
);
|
|
||||||
if (!(flag & USEJUMP))
|
if (!(flag & USEJUMP))
|
||||||
addLoader(ih.cs ? "EXERCSPO" : "",
|
addLoader(ih.cs ? "EXERCSPO" : "", "EXERETIP", nullptr);
|
||||||
"EXERETIP",
|
|
||||||
nullptr
|
|
||||||
);
|
|
||||||
|
|
||||||
linker->defineSymbol("original_cs", ih.cs);
|
linker->defineSymbol("original_cs", ih.cs);
|
||||||
linker->defineSymbol("original_ip", ih.ip);
|
linker->defineSymbol("original_ip", ih.ip);
|
||||||
linker->defineSymbol("original_sp", ih.sp);
|
linker->defineSymbol("original_sp", ih.sp);
|
||||||
linker->defineSymbol("original_ss", ih.ss);
|
linker->defineSymbol("original_ss", ih.ss);
|
||||||
linker->defineSymbol("reloc_size",
|
linker->defineSymbol(
|
||||||
(ph.u_len <= DI_LIMIT || (ph.u_len & 0x7fff)
|
"reloc_size",
|
||||||
>= relocsize ? 0 : MAXRELOCS) - relocsize);
|
(ph.u_len <= DI_LIMIT || (ph.u_len & 0x7fff) >= relocsize ? 0 : MAXRELOCS) - relocsize);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PackExe::buildLoader(const Filter *)
|
void PackExe::buildLoader(const Filter *) {
|
||||||
{
|
|
||||||
// get flag
|
// get flag
|
||||||
exe_header_t dummy_oh;
|
exe_header_t dummy_oh;
|
||||||
int flag = fillExeHeader(&dummy_oh);
|
int flag = fillExeHeader(&dummy_oh);
|
||||||
|
|
||||||
initLoader(stub_i086_dos16_exe, sizeof(stub_i086_dos16_exe));
|
initLoader(stub_i086_dos16_exe, sizeof(stub_i086_dos16_exe));
|
||||||
|
|
||||||
if (M_IS_LZMA(ph.method))
|
if (M_IS_LZMA(ph.method)) {
|
||||||
{
|
addLoader("LZMA_DEC00", opt->small ? "LZMA_DEC10" : "LZMA_DEC20", "LZMA_DEC30",
|
||||||
addLoader("LZMA_DEC00",
|
use_clear_dirty_stack ? "LZMA_DEC31" : "", "LZMA_DEC32",
|
||||||
opt->small ? "LZMA_DEC10" : "LZMA_DEC20",
|
ph.u_len > 0xffff ? "LZMA_DEC33" : "", nullptr);
|
||||||
"LZMA_DEC30",
|
|
||||||
use_clear_dirty_stack ? "LZMA_DEC31" : "",
|
|
||||||
"LZMA_DEC32",
|
|
||||||
ph.u_len > 0xffff ? "LZMA_DEC33" : "",
|
|
||||||
nullptr
|
|
||||||
);
|
|
||||||
|
|
||||||
addLoaderEpilogue(flag);
|
addLoaderEpilogue(flag);
|
||||||
defineDecompressorSymbols();
|
defineDecompressorSymbols();
|
||||||
@@ -196,9 +163,10 @@ void PackExe::buildLoader(const Filter *)
|
|||||||
MemBuffer compressed_lzma;
|
MemBuffer compressed_lzma;
|
||||||
compressed_lzma.allocForCompression(lsize);
|
compressed_lzma.allocForCompression(lsize);
|
||||||
unsigned c_len_lzma = MemBuffer::getSizeForCompression(lsize);
|
unsigned c_len_lzma = MemBuffer::getSizeForCompression(lsize);
|
||||||
int r = upx_compress(loader, lsize, compressed_lzma, &c_len_lzma,
|
int r = upx_compress(loader, lsize, compressed_lzma, &c_len_lzma, nullptr, M_NRV2B_LE16, 9,
|
||||||
nullptr, M_NRV2B_LE16, 9, nullptr, nullptr);
|
nullptr, nullptr);
|
||||||
assert(r == UPX_E_OK); assert(c_len_lzma < lsize);
|
assert(r == UPX_E_OK);
|
||||||
|
assert(c_len_lzma < lsize);
|
||||||
|
|
||||||
info("lzma+relocator code compressed: %u -> %u", lsize, c_len_lzma);
|
info("lzma+relocator code compressed: %u -> %u", lsize, c_len_lzma);
|
||||||
// reinit the loader
|
// reinit the loader
|
||||||
@@ -208,60 +176,32 @@ void PackExe::buildLoader(const Filter *)
|
|||||||
addLoader("DEVICEENTRY,LZMADEVICE,DEVICEENTRY2", nullptr);
|
addLoader("DEVICEENTRY,LZMADEVICE,DEVICEENTRY2", nullptr);
|
||||||
|
|
||||||
linker->addSection("COMPRESSED_LZMA", compressed_lzma, c_len_lzma, 0);
|
linker->addSection("COMPRESSED_LZMA", compressed_lzma, c_len_lzma, 0);
|
||||||
addLoader("LZMAENTRY,NRV2B160,NRVDDONE,NRVDECO1,NRVGTD00,NRVDECO2",
|
addLoader("LZMAENTRY,NRV2B160,NRVDDONE,NRVDECO1,NRVGTD00,NRVDECO2", nullptr);
|
||||||
nullptr);
|
|
||||||
|
|
||||||
}
|
} else if (device_driver)
|
||||||
else if (device_driver)
|
|
||||||
addLoader("DEVICEENTRY,DEVICEENTRY2", nullptr);
|
addLoader("DEVICEENTRY,DEVICEENTRY2", nullptr);
|
||||||
|
|
||||||
addLoader("EXEENTRY",
|
addLoader("EXEENTRY", M_IS_LZMA(ph.method) && device_driver ? "LONGSUB" : "SHORTSUB",
|
||||||
M_IS_LZMA(ph.method) && device_driver ? "LONGSUB" : "SHORTSUB",
|
"JNCDOCOPY", relocsize ? "EXERELPU" : "", "EXEMAIN4",
|
||||||
"JNCDOCOPY",
|
M_IS_LZMA(ph.method) ? "" : "EXEMAIN4B", "EXEMAIN4C",
|
||||||
relocsize ? "EXERELPU" : "",
|
|
||||||
"EXEMAIN4",
|
|
||||||
M_IS_LZMA(ph.method) ? "" : "EXEMAIN4B",
|
|
||||||
"EXEMAIN4C",
|
|
||||||
M_IS_LZMA(ph.method) ? "COMPRESSED_LZMA_START,COMPRESSED_LZMA" : "",
|
M_IS_LZMA(ph.method) ? "COMPRESSED_LZMA_START,COMPRESSED_LZMA" : "",
|
||||||
"+G5DXXXX,UPX1HEAD,EXECUTPO",
|
"+G5DXXXX,UPX1HEAD,EXECUTPO", nullptr);
|
||||||
nullptr
|
|
||||||
);
|
|
||||||
if (ph.method == M_NRV2B_8)
|
if (ph.method == M_NRV2B_8)
|
||||||
addLoader("NRV2B16S", // decompressor
|
addLoader("NRV2B16S", // decompressor
|
||||||
ph.u_len > DI_LIMIT ? "N2B64K01" : "",
|
ph.u_len > DI_LIMIT ? "N2B64K01" : "", "NRV2BEX1",
|
||||||
"NRV2BEX1",
|
opt->cpu == opt->CPU_8086 ? "N2BX8601" : "N2B28601", "NRV2BEX2",
|
||||||
opt->cpu == opt->CPU_8086 ? "N2BX8601" : "N2B28601",
|
opt->cpu == opt->CPU_8086 ? "N2BX8602" : "N2B28602", "NRV2BEX3",
|
||||||
"NRV2BEX2",
|
ph.c_len > 0xffff ? "N2B64K02" : "", "NRV2BEX9", nullptr);
|
||||||
opt->cpu == opt->CPU_8086 ? "N2BX8602" : "N2B28602",
|
|
||||||
"NRV2BEX3",
|
|
||||||
ph.c_len > 0xffff ? "N2B64K02" : "",
|
|
||||||
"NRV2BEX9",
|
|
||||||
nullptr
|
|
||||||
);
|
|
||||||
else if (ph.method == M_NRV2D_8)
|
else if (ph.method == M_NRV2D_8)
|
||||||
addLoader("NRV2D16S",
|
addLoader("NRV2D16S", ph.u_len > DI_LIMIT ? "N2D64K01" : "", "NRV2DEX1",
|
||||||
ph.u_len > DI_LIMIT ? "N2D64K01" : "",
|
opt->cpu == opt->CPU_8086 ? "N2DX8601" : "N2D28601", "NRV2DEX2",
|
||||||
"NRV2DEX1",
|
opt->cpu == opt->CPU_8086 ? "N2DX8602" : "N2D28602", "NRV2DEX3",
|
||||||
opt->cpu == opt->CPU_8086 ? "N2DX8601" : "N2D28601",
|
ph.c_len > 0xffff ? "N2D64K02" : "", "NRV2DEX9", nullptr);
|
||||||
"NRV2DEX2",
|
|
||||||
opt->cpu == opt->CPU_8086 ? "N2DX8602" : "N2D28602",
|
|
||||||
"NRV2DEX3",
|
|
||||||
ph.c_len > 0xffff ? "N2D64K02" : "",
|
|
||||||
"NRV2DEX9",
|
|
||||||
nullptr
|
|
||||||
);
|
|
||||||
else if (ph.method == M_NRV2E_8)
|
else if (ph.method == M_NRV2E_8)
|
||||||
addLoader("NRV2E16S",
|
addLoader("NRV2E16S", ph.u_len > DI_LIMIT ? "N2E64K01" : "", "NRV2EEX1",
|
||||||
ph.u_len > DI_LIMIT ? "N2E64K01" : "",
|
opt->cpu == opt->CPU_8086 ? "N2EX8601" : "N2E28601", "NRV2EEX2",
|
||||||
"NRV2EEX1",
|
opt->cpu == opt->CPU_8086 ? "N2EX8602" : "N2E28602", "NRV2EEX3",
|
||||||
opt->cpu == opt->CPU_8086 ? "N2EX8601" : "N2E28601",
|
ph.c_len > 0xffff ? "N2E64K02" : "", "NRV2EEX9", nullptr);
|
||||||
"NRV2EEX2",
|
|
||||||
opt->cpu == opt->CPU_8086 ? "N2EX8602" : "N2E28602",
|
|
||||||
"NRV2EEX3",
|
|
||||||
ph.c_len > 0xffff ? "N2E64K02" : "",
|
|
||||||
"NRV2EEX9",
|
|
||||||
nullptr
|
|
||||||
);
|
|
||||||
else if M_IS_LZMA (ph.method)
|
else if M_IS_LZMA (ph.method)
|
||||||
return;
|
return;
|
||||||
else
|
else
|
||||||
@@ -270,13 +210,11 @@ void PackExe::buildLoader(const Filter *)
|
|||||||
addLoaderEpilogue(flag);
|
addLoaderEpilogue(flag);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
//
|
//
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
int PackExe::readFileHeader()
|
int PackExe::readFileHeader() {
|
||||||
{
|
|
||||||
ih_exesize = ih_imagesize = ih_overlay = 0;
|
ih_exesize = ih_imagesize = ih_overlay = 0;
|
||||||
fi->readx(&ih, sizeof(ih));
|
fi->readx(&ih, sizeof(ih));
|
||||||
if (ih.ident != 'M' + 'Z' * 256 && ih.ident != 'Z' + 'M' * 256)
|
if (ih.ident != 'M' + 'Z' * 256 && ih.ident != 'Z' + 'M' * 256)
|
||||||
@@ -287,8 +225,7 @@ int PackExe::readFileHeader()
|
|||||||
}
|
}
|
||||||
ih_imagesize = ih_exesize - ih.headsize16 * 16;
|
ih_imagesize = ih_exesize - ih.headsize16 * 16;
|
||||||
ih_overlay = file_size - ih_exesize;
|
ih_overlay = file_size - ih_exesize;
|
||||||
if (file_size_u < sizeof(ih)
|
if (file_size_u < sizeof(ih) || ((ih.m512 | ih.p512) && ih.m512 + ih.p512 * 512u < sizeof(ih)))
|
||||||
|| ((ih.m512 | ih.p512) && ih.m512+ih.p512*512u < sizeof (ih)))
|
|
||||||
throwCantPack("illegal exe header");
|
throwCantPack("illegal exe header");
|
||||||
if (file_size_u < ih_exesize || ih_imagesize <= 0 || ih_imagesize > ih_exesize)
|
if (file_size_u < ih_exesize || ih_imagesize <= 0 || ih_imagesize > ih_exesize)
|
||||||
throwCantPack("exe header corrupted");
|
throwCantPack("exe header corrupted");
|
||||||
@@ -298,9 +235,7 @@ int PackExe::readFileHeader()
|
|||||||
return UPX_F_DOS_EXE;
|
return UPX_F_DOS_EXE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool PackExe::canPack() {
|
||||||
bool PackExe::canPack()
|
|
||||||
{
|
|
||||||
if (fn_has_ext(fi->getName(), "sys"))
|
if (fn_has_ext(fi->getName(), "sys"))
|
||||||
return false;
|
return false;
|
||||||
if (!readFileHeader())
|
if (!readFileHeader())
|
||||||
@@ -310,8 +245,7 @@ bool PackExe::canPack()
|
|||||||
fi->seek(0x3c, SEEK_SET);
|
fi->seek(0x3c, SEEK_SET);
|
||||||
LE32 offs;
|
LE32 offs;
|
||||||
fi->readx(&offs, sizeof(offs));
|
fi->readx(&offs, sizeof(offs));
|
||||||
if (ih.relocoffs >= 0x40 && offs)
|
if (ih.relocoffs >= 0x40 && offs) {
|
||||||
{
|
|
||||||
if (opt->dos_exe.force_stub)
|
if (opt->dos_exe.force_stub)
|
||||||
opt->overlay = opt->COPY_OVERLAY;
|
opt->overlay = opt->COPY_OVERLAY;
|
||||||
else
|
else
|
||||||
@@ -320,16 +254,12 @@ bool PackExe::canPack()
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
//
|
//
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
static
|
static unsigned optimize_relocs(upx_byte *b, const unsigned size, const upx_byte *relocs,
|
||||||
unsigned optimize_relocs(upx_byte *b, const unsigned size,
|
const unsigned nrelocs, upx_byte *crel, bool *has_9a) {
|
||||||
const upx_byte *relocs, const unsigned nrelocs,
|
|
||||||
upx_byte *crel, bool *has_9a)
|
|
||||||
{
|
|
||||||
if (opt->exact)
|
if (opt->exact)
|
||||||
throwCantPackExact();
|
throwCantPackExact();
|
||||||
|
|
||||||
@@ -345,13 +275,11 @@ unsigned optimize_relocs(upx_byte *b, const unsigned size,
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
// pass 1 - find 0x9a bounds
|
// pass 1 - find 0x9a bounds
|
||||||
for (i = 0; i < nrelocs; i++)
|
for (i = 0; i < nrelocs; i++) {
|
||||||
{
|
|
||||||
unsigned addr = get_le32(relocs + 4 * i);
|
unsigned addr = get_le32(relocs + 4 * i);
|
||||||
if (addr >= size - 1)
|
if (addr >= size - 1)
|
||||||
throwCantPack("unexpected relocation 1");
|
throwCantPack("unexpected relocation 1");
|
||||||
if (addr >= 3 && b[addr-3] == 0x9a)
|
if (addr >= 3 && b[addr - 3] == 0x9a) {
|
||||||
{
|
|
||||||
unsigned seg = get_le16(b + addr);
|
unsigned seg = get_le16(b + addr);
|
||||||
if (seg > seg_high)
|
if (seg > seg_high)
|
||||||
seg_high = seg;
|
seg_high = seg;
|
||||||
@@ -375,7 +303,6 @@ unsigned optimize_relocs(upx_byte *b, const unsigned size,
|
|||||||
// printf("%d %d\n", off_low, off_high);
|
// printf("%d %d\n", off_low, off_high);
|
||||||
// printf("%d %d\n", linear_low, linear_high);
|
// printf("%d %d\n", linear_low, linear_high);
|
||||||
|
|
||||||
|
|
||||||
// pass 2 - reloc
|
// pass 2 - reloc
|
||||||
|
|
||||||
crel += 4; // to be filled in later
|
crel += 4; // to be filled in later
|
||||||
@@ -383,22 +310,17 @@ unsigned optimize_relocs(upx_byte *b, const unsigned size,
|
|||||||
unsigned ones = 0;
|
unsigned ones = 0;
|
||||||
unsigned es = 0, di, t;
|
unsigned es = 0, di, t;
|
||||||
i = 0;
|
i = 0;
|
||||||
do
|
do {
|
||||||
{
|
|
||||||
unsigned addr = get_le32(relocs + 4 * i);
|
unsigned addr = get_le32(relocs + 4 * i);
|
||||||
set_le16(crel, di = addr & 0x0f);
|
set_le16(crel, di = addr & 0x0f);
|
||||||
set_le16(crel + 2, (addr >> 4) - es);
|
set_le16(crel + 2, (addr >> 4) - es);
|
||||||
es = addr >> 4;
|
es = addr >> 4;
|
||||||
crel += 4;
|
crel += 4;
|
||||||
|
|
||||||
for (++i; i < nrelocs; i++)
|
for (++i; i < nrelocs; i++) {
|
||||||
{
|
|
||||||
addr = get_le32(relocs + 4 * i);
|
addr = get_le32(relocs + 4 * i);
|
||||||
// printf ("%x\n",es*16+di);
|
// printf ("%x\n",es*16+di);
|
||||||
if ((addr - es*16 > 0xfffe)
|
if ((addr - es * 16 > 0xfffe) || (i == nrelocs - 1 && addr - es * 16 > 0xff00)) {
|
||||||
|| (i == nrelocs - 1 && addr - es * 16 > 0xff00)
|
|
||||||
)
|
|
||||||
{
|
|
||||||
// segment change
|
// segment change
|
||||||
t = 1 + (0xffff - di) / 254;
|
t = 1 + (0xffff - di) / 254;
|
||||||
memset(crel, 1, t);
|
memset(crel, 1, t);
|
||||||
@@ -407,13 +329,11 @@ unsigned optimize_relocs(upx_byte *b, const unsigned size,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
unsigned offs = addr - es * 16;
|
unsigned offs = addr - es * 16;
|
||||||
if (offs >= 3 && b[es*16 + offs-3] == 0x9a && offs > di + 3)
|
if (offs >= 3 && b[es * 16 + offs - 3] == 0x9a && offs > di + 3) {
|
||||||
{
|
|
||||||
for (t = di; t < offs - 3; t++)
|
for (t = di; t < offs - 3; t++)
|
||||||
if (b[es * 16 + t] == 0x9a && get_le16(b + es * 16 + t + 3) <= seg_high)
|
if (b[es * 16 + t] == 0x9a && get_le16(b + es * 16 + t + 3) <= seg_high)
|
||||||
break;
|
break;
|
||||||
if (t == offs-3)
|
if (t == offs - 3) {
|
||||||
{
|
|
||||||
// code 0: search for 0x9a
|
// code 0: search for 0x9a
|
||||||
*crel++ = 0;
|
*crel++ = 0;
|
||||||
di = offs;
|
di = offs;
|
||||||
@@ -425,8 +345,7 @@ unsigned optimize_relocs(upx_byte *b, const unsigned size,
|
|||||||
if (t < 2)
|
if (t < 2)
|
||||||
throwCantPack("unexpected relocation 2");
|
throwCantPack("unexpected relocation 2");
|
||||||
|
|
||||||
while (t >= 256)
|
while (t >= 256) {
|
||||||
{
|
|
||||||
// code 1: add 254, don't reloc
|
// code 1: add 254, don't reloc
|
||||||
*crel++ = 1;
|
*crel++ = 1;
|
||||||
t -= 254;
|
t -= 254;
|
||||||
@@ -445,13 +364,11 @@ unsigned optimize_relocs(upx_byte *b, const unsigned size,
|
|||||||
return (unsigned) (crel - crel_save);
|
return (unsigned) (crel - crel_save);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
//
|
//
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
void PackExe::pack(OutputFile *fo)
|
void PackExe::pack(OutputFile *fo) {
|
||||||
{
|
|
||||||
unsigned ic;
|
unsigned ic;
|
||||||
|
|
||||||
if (ih.relocs > MAXRELOCS)
|
if (ih.relocs > MAXRELOCS)
|
||||||
@@ -474,15 +391,13 @@ void PackExe::pack(OutputFile *fo)
|
|||||||
// relocations
|
// relocations
|
||||||
has_9a = false;
|
has_9a = false;
|
||||||
upx_byte *w = ibuf + ih_imagesize;
|
upx_byte *w = ibuf + ih_imagesize;
|
||||||
if (ih.relocs)
|
if (ih.relocs) {
|
||||||
{
|
|
||||||
upx_byte *wr = w + RSFCRI;
|
upx_byte *wr = w + RSFCRI;
|
||||||
|
|
||||||
fi->seek(ih.relocoffs, SEEK_SET);
|
fi->seek(ih.relocoffs, SEEK_SET);
|
||||||
fi->readx(wr, 4 * ih.relocs);
|
fi->readx(wr, 4 * ih.relocs);
|
||||||
|
|
||||||
for (ic = 0; ic < ih.relocs; ic++)
|
for (ic = 0; ic < ih.relocs; ic++) {
|
||||||
{
|
|
||||||
unsigned jc = get_le32(wr + 4 * ic);
|
unsigned jc = get_le32(wr + 4 * ic);
|
||||||
set_le32(wr + 4 * ic, ((jc >> 16) * 16 + (jc & 0xffff)) & 0xfffff);
|
set_le32(wr + 4 * ic, ((jc >> 16) * 16 + (jc & 0xffff)) & 0xfffff);
|
||||||
}
|
}
|
||||||
@@ -499,9 +414,7 @@ void PackExe::pack(OutputFile *fo)
|
|||||||
ucl_nrv2b_99_compress(w, in_len, out, &out_len, nullptr, 9, nullptr, nullptr);
|
ucl_nrv2b_99_compress(w, in_len, out, &out_len, nullptr, 9, nullptr, nullptr);
|
||||||
printf("reloc compress: %d -> %d\n", in_len, out_len);
|
printf("reloc compress: %d -> %d\n", in_len, out_len);
|
||||||
#endif
|
#endif
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
relocsize = 0;
|
relocsize = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -510,7 +423,8 @@ void PackExe::pack(OutputFile *fo)
|
|||||||
// prepare filter
|
// prepare filter
|
||||||
Filter ft(ph.level);
|
Filter ft(ph.level);
|
||||||
// compress (max_match = 8192)
|
// compress (max_match = 8192)
|
||||||
upx_compress_config_t cconf; cconf.reset();
|
upx_compress_config_t cconf;
|
||||||
|
cconf.reset();
|
||||||
cconf.conf_ucl.max_match = MAXMATCH;
|
cconf.conf_ucl.max_match = MAXMATCH;
|
||||||
cconf.conf_lzma.max_num_probs = 1846 + (768 << 4); // ushort: ~28 KiB stack
|
cconf.conf_lzma.max_num_probs = 1846 + (768 << 4); // ushort: ~28 KiB stack
|
||||||
compressWithFilters(&ft, 32, &cconf);
|
compressWithFilters(&ft, 32, &cconf);
|
||||||
@@ -520,12 +434,10 @@ void PackExe::pack(OutputFile *fo)
|
|||||||
throwCantPack("decompressor limit exceeded, send a bugreport");
|
throwCantPack("decompressor limit exceeded, send a bugreport");
|
||||||
|
|
||||||
#if TESTING
|
#if TESTING
|
||||||
if (opt->debug.debug_level)
|
if (opt->debug.debug_level) {
|
||||||
{
|
|
||||||
printf("image+relocs %d -> %d\n", ih_imagesize + relocsize, ph.c_len);
|
printf("image+relocs %d -> %d\n", ih_imagesize + relocsize, ph.c_len);
|
||||||
printf("offsets: %d - %d\nmatches: %d - %d\nruns: %d - %d\n",
|
printf("offsets: %d - %d\nmatches: %d - %d\nruns: %d - %d\n", 0 /*ph.min_offset_found*/,
|
||||||
0/*ph.min_offset_found*/,ph.max_offset_found,
|
ph.max_offset_found, 0 /*ph.min_match_found*/, ph.max_match_found,
|
||||||
0/*ph.min_match_found*/,ph.max_match_found,
|
|
||||||
0 /*ph.min_run_found*/, ph.max_run_found);
|
0 /*ph.min_run_found*/, ph.max_run_found);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@@ -557,26 +469,22 @@ void PackExe::pack(OutputFile *fo)
|
|||||||
// set extra info
|
// set extra info
|
||||||
unsigned char extra_info[9];
|
unsigned char extra_info[9];
|
||||||
unsigned eisize = 0;
|
unsigned eisize = 0;
|
||||||
if (oh.ss != ih.ss)
|
if (oh.ss != ih.ss) {
|
||||||
{
|
|
||||||
set_le16(extra_info + eisize, ih.ss);
|
set_le16(extra_info + eisize, ih.ss);
|
||||||
eisize += 2;
|
eisize += 2;
|
||||||
assert((flag & SS) != 0); // set in fillExeHeader()
|
assert((flag & SS) != 0); // set in fillExeHeader()
|
||||||
}
|
}
|
||||||
if (oh.sp != ih.sp)
|
if (oh.sp != ih.sp) {
|
||||||
{
|
|
||||||
set_le16(extra_info + eisize, ih.sp);
|
set_le16(extra_info + eisize, ih.sp);
|
||||||
eisize += 2;
|
eisize += 2;
|
||||||
assert((flag & SP) != 0); // set in fillExeHeader()
|
assert((flag & SP) != 0); // set in fillExeHeader()
|
||||||
}
|
}
|
||||||
if (ih.min != oh.min)
|
if (ih.min != oh.min) {
|
||||||
{
|
|
||||||
set_le16(extra_info + eisize, ih.min);
|
set_le16(extra_info + eisize, ih.min);
|
||||||
eisize += 2;
|
eisize += 2;
|
||||||
flag |= MINMEM;
|
flag |= MINMEM;
|
||||||
}
|
}
|
||||||
if (ih.max != oh.max)
|
if (ih.max != oh.max) {
|
||||||
{
|
|
||||||
set_le16(extra_info + eisize, ih.max);
|
set_le16(extra_info + eisize, ih.max);
|
||||||
eisize += 2;
|
eisize += 2;
|
||||||
flag |= MAXMEM;
|
flag |= MAXMEM;
|
||||||
@@ -592,16 +500,13 @@ void PackExe::pack(OutputFile *fo)
|
|||||||
linker->defineSymbol("decompressor_entry", decompressor_entry);
|
linker->defineSymbol("decompressor_entry", decompressor_entry);
|
||||||
|
|
||||||
// patch loader
|
// patch loader
|
||||||
if (flag & USEJUMP)
|
if (flag & USEJUMP) {
|
||||||
{
|
|
||||||
// I use a relocation entry to set the original cs
|
// I use a relocation entry to set the original cs
|
||||||
unsigned n = getLoaderSectionStart("EXEJUMPF") + 1;
|
unsigned n = getLoaderSectionStart("EXEJUMPF") + 1;
|
||||||
n += packedsize + 2;
|
n += packedsize + 2;
|
||||||
oh.relocs = 1;
|
oh.relocs = 1;
|
||||||
oh.firstreloc = (n & 0xf) + ((n >> 4) << 16);
|
oh.firstreloc = (n & 0xf) + ((n >> 4) << 16);
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
oh.relocs = 0;
|
oh.relocs = 0;
|
||||||
oh.firstreloc = ih.cs * 0x10000 + ih.ip;
|
oh.firstreloc = ih.cs * 0x10000 + ih.ip;
|
||||||
}
|
}
|
||||||
@@ -633,7 +538,9 @@ void PackExe::pack(OutputFile *fo)
|
|||||||
memcpy(loader, getLoader(), lsize);
|
memcpy(loader, getLoader(), lsize);
|
||||||
patchPackHeader(loader, e_len);
|
patchPackHeader(loader, e_len);
|
||||||
|
|
||||||
//fprintf(stderr,"\ne_len=%x d_len=%x c_len=%x oo=%x ulen=%x destp=%x copys=%x images=%x",e_len,d_len,packedsize,ph.overlap_overhead,ph.u_len,destpara,copysize,ih_imagesize);
|
NO_fprintf(stderr, "\ne_len=%x d_len=%x c_len=%x oo=%x ulen=%x destp=%x copys=%x images=%x",
|
||||||
|
e_len, d_len, packedsize, ph.overlap_overhead, ph.u_len, /*destpara*/ 0, copysize,
|
||||||
|
ih_imagesize);
|
||||||
|
|
||||||
// write header + write loader + compressed file
|
// write header + write loader + compressed file
|
||||||
#if TESTING
|
#if TESTING
|
||||||
@@ -666,13 +573,11 @@ void PackExe::pack(OutputFile *fo)
|
|||||||
throwNotCompressible();
|
throwNotCompressible();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
//
|
//
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
int PackExe::canUnpack()
|
int PackExe::canUnpack() {
|
||||||
{
|
|
||||||
if (!readFileHeader())
|
if (!readFileHeader())
|
||||||
return false;
|
return false;
|
||||||
const unsigned off = ih.headsize16 * 16;
|
const unsigned off = ih.headsize16 * 16;
|
||||||
@@ -681,13 +586,11 @@ int PackExe::canUnpack()
|
|||||||
return b && (off + ph.c_len <= file_size_u);
|
return b && (off + ph.c_len <= file_size_u);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
//
|
//
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
void PackExe::unpack(OutputFile *fo)
|
void PackExe::unpack(OutputFile *fo) {
|
||||||
{
|
|
||||||
ibuf.alloc(file_size);
|
ibuf.alloc(file_size);
|
||||||
obuf.allocForDecompression(ph.u_len);
|
obuf.allocForDecompression(ph.u_len);
|
||||||
|
|
||||||
@@ -712,47 +615,41 @@ void PackExe::unpack(OutputFile *fo)
|
|||||||
unsigned relocn = 0;
|
unsigned relocn = 0;
|
||||||
SPAN_S_VAR(upx_byte, relocs, obuf + ph.u_len, obuf);
|
SPAN_S_VAR(upx_byte, relocs, obuf + ph.u_len, obuf);
|
||||||
|
|
||||||
MemBuffer wrkmem;
|
MemBuffer mb_wrkmem;
|
||||||
if (!(flag & NORELOC))
|
SPAN_0_VAR(upx_byte, wrkmem, nullptr);
|
||||||
{
|
if (!(flag & NORELOC)) {
|
||||||
relocs -= get_le16(obuf+ph.u_len-2);
|
relocs -= get_le16(obuf + (ph.u_len - 2));
|
||||||
ph.u_len -= 2;
|
ph.u_len -= 2;
|
||||||
|
|
||||||
wrkmem.alloc(4*MAXRELOCS);
|
mb_wrkmem.alloc(4 * MAXRELOCS);
|
||||||
|
wrkmem = mb_wrkmem; // => now a SPAN_S
|
||||||
unsigned es = 0, ones = get_le16(relocs);
|
unsigned es = 0, ones = get_le16(relocs);
|
||||||
const unsigned seghi = get_le16(relocs + 2);
|
const unsigned seghi = get_le16(relocs + 2);
|
||||||
SPAN_S_VAR(const upx_byte, p, relocs + 4);
|
SPAN_S_VAR(const upx_byte, p, relocs + 4);
|
||||||
|
|
||||||
while (ones)
|
while (ones) {
|
||||||
{
|
|
||||||
unsigned di = get_le16(p);
|
unsigned di = get_le16(p);
|
||||||
es += get_le16(p + 2);
|
es += get_le16(p + 2);
|
||||||
bool dorel = true;
|
bool dorel = true;
|
||||||
for (p += 4; ones && di < 0x10000; p++)
|
for (p += 4; ones && di < 0x10000; p++) {
|
||||||
{
|
if (dorel) {
|
||||||
if (dorel)
|
set_le16(wrkmem + (4 * relocn), di);
|
||||||
{
|
set_le16(wrkmem + (2 + 4 * relocn++), es);
|
||||||
set_le16(wrkmem+4*relocn,di);
|
NO_printf("%x\n", es * 16 + di);
|
||||||
set_le16(wrkmem+2+4*relocn++,es);
|
|
||||||
//printf ("%x\n",es*16+di);
|
|
||||||
}
|
}
|
||||||
dorel = true;
|
dorel = true;
|
||||||
if (*p == 0)
|
if (*p == 0) {
|
||||||
{
|
|
||||||
SPAN_S_VAR(const upx_byte, q, obuf);
|
SPAN_S_VAR(const upx_byte, q, obuf);
|
||||||
|
for (q = obuf + (es * 16 + di); !(*q == 0x9a && get_le16(q + 3) <= seghi);
|
||||||
for (q = obuf+es*16+di; !(*q == 0x9a && get_le16(q+3) <= seghi); q++)
|
q++) {
|
||||||
;
|
|
||||||
di = ptr_diff_bytes(q, obuf+es*16) + 3;
|
|
||||||
}
|
}
|
||||||
else if (*p == 1)
|
di = ptr_diff_bytes(q, obuf + (es * 16)) + 3;
|
||||||
{
|
} else if (*p == 1) {
|
||||||
di += 254;
|
di += 254;
|
||||||
if (di < 0x10000)
|
if (di < 0x10000)
|
||||||
ones--;
|
ones--;
|
||||||
dorel = false;
|
dorel = false;
|
||||||
}
|
} else
|
||||||
else
|
|
||||||
di += *p;
|
di += *p;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -762,11 +659,10 @@ void PackExe::unpack(OutputFile *fo)
|
|||||||
memset(&oh, 0, sizeof(oh));
|
memset(&oh, 0, sizeof(oh));
|
||||||
oh.ident = 'M' + 'Z' * 256;
|
oh.ident = 'M' + 'Z' * 256;
|
||||||
|
|
||||||
if (relocn)
|
if (relocn) {
|
||||||
{
|
|
||||||
oh.relocs = relocn;
|
oh.relocs = relocn;
|
||||||
while (relocn & 3)
|
while (relocn & 3)
|
||||||
set_le32(wrkmem+4*relocn++,0);
|
set_le32(wrkmem + (4 * relocn++), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned outputlen = ptr_udiff_bytes(relocs, obuf) + sizeof(oh) + relocn * 4;
|
unsigned outputlen = ptr_udiff_bytes(relocs, obuf) + sizeof(oh) + relocn * 4;
|
||||||
@@ -779,14 +675,22 @@ void PackExe::unpack(OutputFile *fo)
|
|||||||
oh.sp = ih.sp;
|
oh.sp = ih.sp;
|
||||||
oh.ss = ih.ss;
|
oh.ss = ih.ss;
|
||||||
|
|
||||||
if (flag & MAXMEM)
|
if (flag & MAXMEM) {
|
||||||
{ imagesize -= 2; oh.max = get_le16(ibuf+imagesize); }
|
imagesize -= 2;
|
||||||
if (flag & MINMEM)
|
oh.max = get_le16(ibuf + imagesize);
|
||||||
{ imagesize -= 2; oh.min = get_le16(ibuf+imagesize); }
|
}
|
||||||
if (flag & SP)
|
if (flag & MINMEM) {
|
||||||
{ imagesize -= 2; oh.sp = get_le16(ibuf+imagesize); }
|
imagesize -= 2;
|
||||||
if (flag & SS)
|
oh.min = get_le16(ibuf + imagesize);
|
||||||
{ imagesize -= 2; oh.ss = get_le16(ibuf+imagesize); }
|
}
|
||||||
|
if (flag & SP) {
|
||||||
|
imagesize -= 2;
|
||||||
|
oh.sp = get_le16(ibuf + imagesize);
|
||||||
|
}
|
||||||
|
if (flag & SS) {
|
||||||
|
imagesize -= 2;
|
||||||
|
oh.ss = get_le16(ibuf + imagesize);
|
||||||
|
}
|
||||||
|
|
||||||
unsigned ip = (flag & USEJUMP) ? get_le32(ibuf + imagesize - 4) : (unsigned) ih.firstreloc;
|
unsigned ip = (flag & USEJUMP) ? get_le32(ibuf + imagesize - 4) : (unsigned) ih.firstreloc;
|
||||||
oh.ip = ip & 0xffff;
|
oh.ip = ip & 0xffff;
|
||||||
@@ -801,17 +705,13 @@ void PackExe::unpack(OutputFile *fo)
|
|||||||
fo->write(&oh, sizeof(oh));
|
fo->write(&oh, sizeof(oh));
|
||||||
if (relocn)
|
if (relocn)
|
||||||
fo->write(wrkmem, relocn * 4);
|
fo->write(wrkmem, relocn * 4);
|
||||||
fo->write(obuf, ptr_diff_bytes(relocs, obuf));
|
fo->write(obuf, ptr_udiff_bytes(relocs, obuf));
|
||||||
|
|
||||||
// copy the overlay
|
// copy the overlay
|
||||||
copyOverlay(fo, ih_overlay, obuf);
|
copyOverlay(fo, ih_overlay, obuf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Linker *PackExe::newLinker() const { return new ElfLinkerX86(); }
|
||||||
Linker* PackExe::newLinker() const
|
|
||||||
{
|
|
||||||
return new ElfLinkerX86();
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
||||||
|
|||||||
+12
-24
@@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
This file is part of the UPX executable compressor.
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
Copyright (C) 1996-2022 Markus Franz Xaver Johannes Oberhumer
|
Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer
|
||||||
Copyright (C) 1996-2022 Laszlo Molnar
|
Copyright (C) 1996-2023 Laszlo Molnar
|
||||||
All Rights Reserved.
|
All Rights Reserved.
|
||||||
|
|
||||||
UPX and the UCL library are free software; you can redistribute them
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
@@ -25,24 +25,22 @@
|
|||||||
<markus@oberhumer.com> <ezerotven+github@gmail.com>
|
<markus@oberhumer.com> <ezerotven+github@gmail.com>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
#ifndef __UPX_P_EXE_H
|
#ifndef UPX_P_EXE_H__
|
||||||
#define __UPX_P_EXE_H 1
|
#define UPX_P_EXE_H__ 1
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
// dos/exe
|
// dos/exe
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
class PackExe final : public Packer
|
class PackExe final : public Packer {
|
||||||
{
|
|
||||||
typedef Packer super;
|
typedef Packer super;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
PackExe(InputFile *f);
|
PackExe(InputFile *f);
|
||||||
virtual int getVersion() const override { return 13; }
|
virtual int getVersion() const override { return 13; }
|
||||||
virtual int getFormat() const override { return UPX_F_DOS_EXE; }
|
virtual int getFormat() const override { return UPX_F_DOS_EXE; }
|
||||||
virtual const char *getName() const override { return "dos/exe"; }
|
virtual const char *getName() const override { return "dos/exe"; }
|
||||||
//virtual const char *getFullName(const options_t *o) const { return o && o->cpu == o->CPU_8086 ? "i086-dos16.exe" : "i286-dos16.exe"; }
|
|
||||||
virtual const char *getFullName(const options_t *) const override { return "i086-dos16.exe"; }
|
virtual const char *getFullName(const options_t *) const override { return "i086-dos16.exe"; }
|
||||||
virtual const int *getCompressionMethods(int method, int level) const override;
|
virtual const int *getCompressionMethods(int method, int level) const override;
|
||||||
virtual const int *getFilters() const override;
|
virtual const int *getFilters() const override;
|
||||||
@@ -54,13 +52,11 @@ public:
|
|||||||
virtual int canUnpack() override;
|
virtual int canUnpack() override;
|
||||||
|
|
||||||
// unpacker capabilities
|
// unpacker capabilities
|
||||||
virtual bool canUnpackVersion(int version) const override
|
virtual bool canUnpackVersion(int version) const override {
|
||||||
{
|
|
||||||
// NOTE: could adapt p_exe.cpp to support (version >= 8)
|
// NOTE: could adapt p_exe.cpp to support (version >= 8)
|
||||||
return (version >= 10);
|
return (version >= 10);
|
||||||
}
|
}
|
||||||
virtual bool canUnpackFormat(int format) const override
|
virtual bool canUnpackFormat(int format) const override {
|
||||||
{
|
|
||||||
return (format == UPX_F_DOS_EXE || format == UPX_F_DOS_EXEH);
|
return (format == UPX_F_DOS_EXE || format == UPX_F_DOS_EXEH);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -74,7 +70,7 @@ protected:
|
|||||||
virtual Linker *newLinker() const override;
|
virtual Linker *newLinker() const override;
|
||||||
void addLoaderEpilogue(int flag);
|
void addLoaderEpilogue(int flag);
|
||||||
|
|
||||||
__packed_struct(exe_header_t)
|
struct alignas(1) exe_header_t {
|
||||||
LE16 ident;
|
LE16 ident;
|
||||||
LE16 m512;
|
LE16 m512;
|
||||||
LE16 p512;
|
LE16 p512;
|
||||||
@@ -90,7 +86,7 @@ protected:
|
|||||||
LE16 relocoffs;
|
LE16 relocoffs;
|
||||||
char __[2]; // overlnum
|
char __[2]; // overlnum
|
||||||
LE32 firstreloc;
|
LE32 firstreloc;
|
||||||
__packed_struct_end()
|
};
|
||||||
|
|
||||||
exe_header_t ih, oh;
|
exe_header_t ih, oh;
|
||||||
|
|
||||||
@@ -102,20 +98,12 @@ protected:
|
|||||||
bool has_9a;
|
bool has_9a;
|
||||||
bool device_driver;
|
bool device_driver;
|
||||||
|
|
||||||
enum {
|
enum { NORELOC = 1, USEJUMP = 2, SS = 4, SP = 8, MINMEM = 16, MAXMEM = 32 };
|
||||||
NORELOC = 1,
|
|
||||||
USEJUMP = 2,
|
|
||||||
SS = 4,
|
|
||||||
SP = 8,
|
|
||||||
MINMEM = 16,
|
|
||||||
MAXMEM = 32
|
|
||||||
};
|
|
||||||
|
|
||||||
unsigned stack_for_lzma; // stack size required for lzma
|
unsigned stack_for_lzma; // stack size required for lzma
|
||||||
bool use_clear_dirty_stack;
|
bool use_clear_dirty_stack;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
#endif /* already included */
|
#endif /* already included */
|
||||||
|
|
||||||
/* vim:set ts=4 sw=4 et: */
|
/* vim:set ts=4 sw=4 et: */
|
||||||
|
|||||||
+502
-237
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user