Compare commits
100 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 |
+34
-19
@@ -1,29 +1,44 @@
|
||||
# "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
|
||||
AccessModifierOffset: -4
|
||||
#AlignConsecutiveAssignments: true
|
||||
AlwaysBreakTemplateDeclarations: true
|
||||
ColumnLimit: 100
|
||||
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
|
||||
SpaceAfterCStyleCast: true
|
||||
Standard: Cpp03
|
||||
StatementMacros: [
|
||||
ACCCHK_ASSERT,
|
||||
ACCCHK_ASSERT_IS_SIGNED_T,
|
||||
ACCCHK_ASSERT_IS_UNSIGNED_T,
|
||||
ACCCHK_ASSERT_SIGN_T,
|
||||
ACC_BLOCK_BEGIN,
|
||||
ACC_COMPILE_TIME_ASSERT,
|
||||
ACC_COMPILE_TIME_ASSERT_HEADER,
|
||||
ACC_CXX_DISABLE_NEW_DELETE,
|
||||
ACC_CXX_TRIGGER_FUNCTION,
|
||||
ACC_CXX_TRIGGER_FUNCTION_IMPL,
|
||||
CLANG_FORMAT_DUMMY_STATEMENT,
|
||||
COMPILE_TIME_ASSERT,
|
||||
COMPILE_TIME_ASSERT_ALIGNED1,
|
||||
]
|
||||
StatementMacros:
|
||||
- ACCCHK_ASSERT
|
||||
- ACCCHK_ASSERT_IS_SIGNED_T
|
||||
- ACCCHK_ASSERT_IS_UNSIGNED_T
|
||||
- ACCCHK_ASSERT_SIGN_T
|
||||
- ACC_BLOCK_BEGIN
|
||||
- ACC_COMPILE_TIME_ASSERT
|
||||
- ACC_COMPILE_TIME_ASSERT_HEADER
|
||||
- ACC_CXX_DISABLE_NEW_DELETE
|
||||
- ACC_CXX_TRIGGER_FUNCTION
|
||||
- ACC_CXX_TRIGGER_FUNCTION_IMPL
|
||||
- CLANG_FORMAT_DUMMY_STATEMENT
|
||||
- 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
|
||||
"
|
||||
expected_sha256sums__t110_compress_ucl_nrv2b_3_no_filter="\
|
||||
60cf1528ad264c8f4d766443fae02fd0a7bf46247c896c53a19bbd90b800e918 *amd64-linux.elf/upx-3.91
|
||||
a4aa078f2dbb381a6132b85ba53df5ac9ede069a43adc542aec25263ffb21ce0 *amd64-linux.elf/upx-3.95
|
||||
4af65a302afd863073401a11c37246965d7b4ba101edb57d6e3547216ac3c8f7 *amd64-win64.pe/upx-3.95.exe
|
||||
fef37f59ada02f3d3555c2393fcd0fa12f644c4a57e98d0859fa4f919c243ce3 *arm-linux.elf/upx-3.95
|
||||
ee4878808c92fc90867775ed1fccb4da94097d8e493c771ed75dffab6da6b167 *arm-wince.pe/upx-3.91.exe
|
||||
911f5f56fa4f208d047eb00f9b5686993e7011d5bc17c90fab06b42b470583b0 *arm64-linux.elf/upx-3.95
|
||||
c0a2eb27fbd6507a047d2f08f668c07d54a277d16394e437105f2b27dde434c1 *armeb-linux.elf/upx-3.91
|
||||
e149178f6ce710ee151c2b11b8d2d6d8e99d65c1c640147f3e7aa1df60f0b438 *armeb-linux.elf/upx-3.95
|
||||
badd40b58323cf5825fbd6627fe27a1ee2f1e787ea59b28e7795aa3b2799b887 *i386-dos32.djgpp2.coff/upx-3.91.exe
|
||||
52b2d1bd52747bc14784dea187159c424ee58a02758fa4f7548cfb6dff80d699 *i386-dos32.djgpp2.coff/upx-3.95.exe
|
||||
b4bbba7e71afc2986b6cb9f17a0e14929b68f83345045bf30dc2c5761b91bda8 *i386-linux.elf/upx-3.91
|
||||
faa00110c0a70a7fe455e61cdb97a9483cf6e578cb13033e8995d887543db69b *i386-linux.elf/upx-3.95
|
||||
055135feb800114b4c2bdd9de28e845611f1390a1668ef3e20897d23d1fa8614 *i386-win32.pe/upx-3.91.exe
|
||||
59748c9f0eb3eef2b54a54dbf274459cb28b5e9b12ba69993a6250c869f5ea89 *i386-win32.pe/upx-3.95.exe
|
||||
84158c951fa65d6c53c9dcced158f8cd1b566e83f2109aeac7d6247338c48098 *m68k-atari.tos/upx-3.91.ttp
|
||||
7522c07537da37c370c0dd925fc1b93eb53e329219dd6e21259281a871767779 *mips-linux.elf/upx-3.95
|
||||
7b9258b0c97f733ca602d8f4ea08619ee430fd8802d046051f10ae68576c7756 *mipsel-linux.elf/upx-3.91
|
||||
75c1c61ce3c53888525a9bf5b3e51b86f1fcbdc91151e6b4b19041b15dc1e5c8 *mipsel-linux.elf/upx-3.95
|
||||
782df126832daeba48f8c86f0ca12626e4257a57b0bdfaa7439f3607f3954b33 *powerpc-linux.elf/upx-3.91
|
||||
743a676ec7aac4d51e0473911a67b711987d0ec0fda8668a6f0808edcb906343 *powerpc-linux.elf/upx-3.95
|
||||
b5dd587c58d013dcdf7551f8a2b8427cbd37f6e76c54e735baf68ee2a49fba9a *powerpc64le-linux.elf/upx-3.95
|
||||
693102863358cc906bce946afec10dd0e15d0effc6ceb462d9beaaba25967304 *amd64-linux.elf/upx-3.91
|
||||
4aa9e1868d7797b50768cf1ae0ab0e93cc2eff81f3abaf36f2fdb5faf673f7b7 *amd64-linux.elf/upx-3.95
|
||||
996dc60b7b6aa8c4c55b4fbec9b1ad3e2f82f9986fd1cdcd2cb41ab01877d5a9 *amd64-win64.pe/upx-3.95.exe
|
||||
bb6cd600a28de3abc86c618125d72231d3d4b40de0260d2da7393970859723dd *arm-linux.elf/upx-3.95
|
||||
bc945bc3f64a318a00ecbfde2e4a4bac2d298f753e5a8dbdc6a972bcabfce6eb *arm-wince.pe/upx-3.91.exe
|
||||
19bdd27706f3476dfd46e5cdde782908af5bf9d068bf337ad8a26024d51ede8f *arm64-linux.elf/upx-3.95
|
||||
3b6e5e9eeb660859e35d9d3e005fb51a8163bfe548d8be6525660a30d1ea5c37 *armeb-linux.elf/upx-3.91
|
||||
2f2d916ee977e06b07429e563aeab0d052b7ba359dd61a7d767e2a7ef7fa049d *armeb-linux.elf/upx-3.95
|
||||
1e8cded938d4ee16bcc66fb5462650733a8862a1c9fab264a77a22e7958b36a7 *i386-dos32.djgpp2.coff/upx-3.91.exe
|
||||
6f439d62cdb735570c6c5e941924b6d2819024cad6c3453db020edc1e9e0d66b *i386-dos32.djgpp2.coff/upx-3.95.exe
|
||||
f6a8a76b9af29272722be6785242a9822ce6b2ca3483cd953c2c34e4d85e1cf4 *i386-linux.elf/upx-3.91
|
||||
7eead732dddffdb1db5e5002babe112f8589eeb8251cb23e0b6f29dacfad3817 *i386-linux.elf/upx-3.95
|
||||
2c41d77ae9ac810cde23a222046d05b57a272c90aa75b127e0697a586be1ce1f *i386-win32.pe/upx-3.91.exe
|
||||
0218c00a3686363148a2bbe7d89634d54a2d7840beeab7f5fef2f269e56d517e *i386-win32.pe/upx-3.95.exe
|
||||
44034fc9a3609538d8edfbe3996aa3946b1745e537d1ea2ca14181c177b98034 *m68k-atari.tos/upx-3.91.ttp
|
||||
55c6151325fdf1638584f0fa5ee228547445e239bb0c8f4c6f31c30945e114b1 *mips-linux.elf/upx-3.95
|
||||
b6905f55277b3abc8ad10eb1ca95135ce9f2a5d87c992f7de78ca8e69d8e819e *mipsel-linux.elf/upx-3.91
|
||||
3a5eb4b01cb334e4a30a0ebb1c7d9f85f2035e6e5989acc296beb3ff34c98152 *mipsel-linux.elf/upx-3.95
|
||||
df4157e8e613f62fb26b1965b1c22dc44bf18f4aec4611283afadb9889d267d4 *powerpc-linux.elf/upx-3.91
|
||||
054a126aa7e17c6c5b8a00f608c4bf98f252ec4ab9ca2c03aebf9c92e30bda4f *powerpc-linux.elf/upx-3.95
|
||||
4667d37cb2474a30b184cd4d7ca8ba071650c396ebe9f1f9a39172c924676090 *powerpc64le-linux.elf/upx-3.95
|
||||
"
|
||||
expected_sha256sums__t120_compress_ucl_nrv2d_3_no_filter="\
|
||||
b8185a6b0ec81e5e0a3f741fe49c5635934f45a84e2154147100410496c9a880 *amd64-linux.elf/upx-3.91
|
||||
8977f05b4b52c5ce1bdf32dee5c5d790640d79ea42ad83401826c261d9249866 *amd64-linux.elf/upx-3.95
|
||||
bcd8749ba0c502fa7b21bcec9e531f3b7a178cb8757407d6b682d4ff1952d2a0 *amd64-win64.pe/upx-3.95.exe
|
||||
f32239666d98211182580a9badf1cab01197b51d8a3a358c26e3fa248a0ef776 *arm-linux.elf/upx-3.95
|
||||
8261c22417294e3f0506d8f41154945e3f0b7d2a67e532af318d5795cd8f9c22 *arm-wince.pe/upx-3.91.exe
|
||||
6e60054ace6510309426893dcf683b4c6da88f3fbd97e7149e23bc4bf8c88003 *arm64-linux.elf/upx-3.95
|
||||
52496fee0654d4a46e778a01c3bc17f4f25f885291241f5237f0824f5b9a0cb3 *armeb-linux.elf/upx-3.91
|
||||
48434abf0b96e57f421db5a9c45b04eebf105420a500656859d6fdbd3c5d99bf *armeb-linux.elf/upx-3.95
|
||||
0d7c87e490dff9a41a9c3b317e2529f2d1b1926844a47c48b42ef8bd7d212a4d *i386-dos32.djgpp2.coff/upx-3.91.exe
|
||||
75f42a83bddfc1923e32a6725a153219b1a37ecf4fd30876599341fd77de321d *i386-dos32.djgpp2.coff/upx-3.95.exe
|
||||
2c50b4a2649ea7d4c1ca7d5c541107b878942ab61ef850ce5bdbb7bc6da8d777 *i386-linux.elf/upx-3.91
|
||||
134dfa566532c1432be87a45d7d28333e79e7fbbe12b5c27fb02e24a550eb9c5 *i386-linux.elf/upx-3.95
|
||||
3d04162e902e0f311493955df2dd60fa018b60003d4394d638abda22fa88a7fb *i386-win32.pe/upx-3.91.exe
|
||||
1972dca6a741124271a291565d001af92cfb379d11a7efa54680a3f96d5f02b4 *i386-win32.pe/upx-3.95.exe
|
||||
9751dfa351aa5076523c6bac013cf48b34267947fd1f057109fe141ead815d52 *m68k-atari.tos/upx-3.91.ttp
|
||||
b80bc9585ccb586c3adc6c712110838366e61cefaf41a36a54e4eef8351d43c4 *mips-linux.elf/upx-3.95
|
||||
4b87450050446b03f2d88c79efe2cf87e403f82e9f1f47cb3e99a82b1678f91a *mipsel-linux.elf/upx-3.91
|
||||
0fcf1b3c72d4af95562dec2e2588816199b2a5086d848548bd9648456c64200d *mipsel-linux.elf/upx-3.95
|
||||
7fc8fa7a67899917fbeffade2e7bfb32c6a395e781274901230cfca51ce33516 *powerpc-linux.elf/upx-3.91
|
||||
ce6d87922a0d203fba0ff90e263e80237379dbf8daf3ae83d7d0cd9eb19c3360 *powerpc-linux.elf/upx-3.95
|
||||
204cf8575465fb406dfd0520cc6bc103988074676123c2255e36952ab8d5c82f *powerpc64le-linux.elf/upx-3.95
|
||||
f3cfc0be5885525965fbd3e56f5a4083a727414978bb4c018b4b0355c5b06921 *amd64-linux.elf/upx-3.91
|
||||
06f933cf1c5e42f2f00ffb6a5312fa687846b6a566d372459208f8cad34e34bb *amd64-linux.elf/upx-3.95
|
||||
db33236e886947a74c766e632ded0249166e2e5f74a3d03cda37cc07901cd1b1 *amd64-win64.pe/upx-3.95.exe
|
||||
3564858c026c2b0637e3c8e41a972fabc609ccc69c7ddd0ae457dd4ba7a62008 *arm-linux.elf/upx-3.95
|
||||
dceda960aa7b15b13a06bf88d1512d52e7e460d85a81207b6b5407bdbb51ffe8 *arm-wince.pe/upx-3.91.exe
|
||||
52b93b549591081ef72d19fe09d4588d7f2bc736f2ad50a32be03fb7fcd70e95 *arm64-linux.elf/upx-3.95
|
||||
1877be1f5f5333f1ee7c77bfb020f35f5c125e7f6b661a92a6918b468c02484f *armeb-linux.elf/upx-3.91
|
||||
a4d1f01a3dc748e92dd33e1377885ef2955c2c35fd379474c6622ce67267fac2 *armeb-linux.elf/upx-3.95
|
||||
d5d3cf6ecf1a89f5871bcfef9c59794f249b9f7ca12afdf15b79d343a18ddefc *i386-dos32.djgpp2.coff/upx-3.91.exe
|
||||
eca16dec497e1a9f334fd4d806f035cafcd3438749d25b494e95f4935760ae4f *i386-dos32.djgpp2.coff/upx-3.95.exe
|
||||
1ab8d00e13d149f6e74187eadaacd1d8cfa4777ce7489cef88fba4cbde9bcdee *i386-linux.elf/upx-3.91
|
||||
dd3169256039f7df2db15a86114818b275c03bd96c3ee828d724131b98fcc6f2 *i386-linux.elf/upx-3.95
|
||||
17a97d24ebbdaa3bd8f7ec9633e38bca1754c8af2d79250aaa5472499a98e0ec *i386-win32.pe/upx-3.91.exe
|
||||
1bb873ed8a8cbb11238f98c3f616ec6a34f4765a6021e10d9686158f382458f0 *i386-win32.pe/upx-3.95.exe
|
||||
13b0b57643342d0e08fe084cbf799f518b3d44ac9f39edda7db3e6b6c36386cc *m68k-atari.tos/upx-3.91.ttp
|
||||
91145a85e926495a536661d4e842a7b5b259707ef6accf5f08d13adcec173f13 *mips-linux.elf/upx-3.95
|
||||
8090533000872748b70c761d5581d78fde421d66884ab238527ca41d1446c2ae *mipsel-linux.elf/upx-3.91
|
||||
f82e7b166647f157c981af92eaeec63bf080609591a5d13f76f84cd49c8e7495 *mipsel-linux.elf/upx-3.95
|
||||
ae312cc5d34fd889ed9582a928ab03c589c0caddb111aceade7e072f928c6361 *powerpc-linux.elf/upx-3.91
|
||||
fd28cb894be895afb8aec675739b276810e7a35c5212016c3f7acde853d8c763 *powerpc-linux.elf/upx-3.95
|
||||
e299bb500c34d2f90b2b35a7186a0b24fb5ac80e56d4a2d80f9c8bd32cf2be62 *powerpc64le-linux.elf/upx-3.95
|
||||
"
|
||||
expected_sha256sums__t130_compress_ucl_nrv2e_3_no_filter="\
|
||||
8a7ec7f638e95156177a29a32c5a6a3cad2e3e970ca031bc28a55991428bab46 *amd64-linux.elf/upx-3.91
|
||||
a1e9f15306809e6a65952d49163d50e11fc8dbe1094847e487c1509c5d642883 *amd64-linux.elf/upx-3.95
|
||||
6a557025f93fbf869be7cae692959f96f250a5675195c53f26c17ef0d95246e7 *amd64-win64.pe/upx-3.95.exe
|
||||
b2a5d5cd936205a1d2c87019cfd1ead7d22268acc8be08963b358c807f7b0b2d *arm-linux.elf/upx-3.95
|
||||
3be544b1ae2bdd70c764eb6f3424e83e49dc70991f21cd1bbb4aa892a706dfcd *arm-wince.pe/upx-3.91.exe
|
||||
046e3639cff25a8d5d9c817aa314f0885667ccd71eaf17ebc87574dfdd1e0020 *arm64-linux.elf/upx-3.95
|
||||
cc38f1ee23b97e107a2da9ec87358345b35e9bdb222791929b24f21838bffd03 *armeb-linux.elf/upx-3.91
|
||||
1fa4a8c3eca8dfdc5464d1f020ea3eec75fedb037a3dd73a343655479464717b *armeb-linux.elf/upx-3.95
|
||||
1c777079d1b35fa3ee68cb4e36822091fdbf4ea4c7ed149da1c34424b082b39d *i386-dos32.djgpp2.coff/upx-3.91.exe
|
||||
d65c3d9c8850802bb66d51b26fdd905beaf1b72b7ba8550ec11788b7136b0204 *i386-dos32.djgpp2.coff/upx-3.95.exe
|
||||
f2511747fac635a1d70b2364dfcdc91da517aec2c87d8d017557738e87d84061 *i386-linux.elf/upx-3.91
|
||||
e74cdd10bf5f37249278634bf1055adaa0527bbe4735c4cdf7a54663b67db985 *i386-linux.elf/upx-3.95
|
||||
4d21e45a321a78de433d96170a3e39daeee2ab18c646f2fca0ae1367b356ea63 *i386-win32.pe/upx-3.91.exe
|
||||
3e1a705b3c6859d7812e4d8b42fd6201563356614b7f0ec16718cddb8bec1e82 *i386-win32.pe/upx-3.95.exe
|
||||
9a812916dfa09e821f9b3233b98b6740d39751ed0dc63e8edfd8b59f262b4218 *m68k-atari.tos/upx-3.91.ttp
|
||||
eea25f8bec855536168c1e9f1b960c807ce46f9758878fdff2d23065d8007d14 *mips-linux.elf/upx-3.95
|
||||
e37c0ce8513131e4e1ebeaaa999d258be95bde655b60fc9c575b3648a0b07c14 *mipsel-linux.elf/upx-3.91
|
||||
c46b272e068276601d8ebc3a7765f2e3cafd279b3f5aff6fb4af4d4869afd387 *mipsel-linux.elf/upx-3.95
|
||||
390eba4b44e6e3e3e5b726ca7d087eee4a90af0c194d6cb7633da5e0e5d8dec5 *powerpc-linux.elf/upx-3.91
|
||||
b21ed94586b7254c96fcd64034e73ce8cb8851c92bb27d4d5eb377cf16c56aa2 *powerpc-linux.elf/upx-3.95
|
||||
52f53a9d7fa0b38ce1276101bb8be59d31f54a959ca0ae0a2708dd3083d0483c *powerpc64le-linux.elf/upx-3.95
|
||||
eea59d6755beed52bff26941d31362f28097d029d4f61a2f9065dcc63cd628fb *amd64-linux.elf/upx-3.91
|
||||
b89f4ca39165071a7a5eb107ed9b7c6c77b7c7ad90acdb2b073314571aacc23a *amd64-linux.elf/upx-3.95
|
||||
6af6bc4f2d4bdb1e7694f44ce695c54d181011b734f159018d5e2c515d14a47c *amd64-win64.pe/upx-3.95.exe
|
||||
9ae22ad9af331ec8c08ab22b0a8e0e0ff849512a6d11257c55fe7c423c0b7937 *arm-linux.elf/upx-3.95
|
||||
8605ddb612a1a3e096e272cb876e7777585804fa000f338f2164437a6da3de9a *arm-wince.pe/upx-3.91.exe
|
||||
2ab36b41db84e6e3002420ec397d79abed451869a7a8b703ab3b81f79c487753 *arm64-linux.elf/upx-3.95
|
||||
38879c80525760492a95de9bfcbce49997c5bff30bb43a6bb173b1978d21f248 *armeb-linux.elf/upx-3.91
|
||||
72e3bf259bf1304235a7ebe600f5b37be21297b8552f2fbdf47e28e3aa19e807 *armeb-linux.elf/upx-3.95
|
||||
3af56cb84be62f4078ae39be3370ef68061b094c62b3cbcd5d38e99e0e91df7f *i386-dos32.djgpp2.coff/upx-3.91.exe
|
||||
224b882b4dcebc1112ced3df1b468ea8dc58083dac4893fa0061dc50ce6abf7c *i386-dos32.djgpp2.coff/upx-3.95.exe
|
||||
59e3a1d456036bed175056978d12484a64405f356b1a1fa480866e7e31c9543b *i386-linux.elf/upx-3.91
|
||||
9662deb5f74b23c5b63d09457442895091f4b6cfd619f7bd6ffc27ec75f08682 *i386-linux.elf/upx-3.95
|
||||
3c585a745cd105073bb7324f2183731be84cfc4669f2bab1ef20c9bff909d2fc *i386-win32.pe/upx-3.91.exe
|
||||
fc796dad77cb6cb99bcb5700c3ff0a7b185c1fe8b129a293dd0e45d0903b13e6 *i386-win32.pe/upx-3.95.exe
|
||||
da41cb691775b8b0ef969954ea272262ed77e83b57257b2ba0ba19427a2ab991 *m68k-atari.tos/upx-3.91.ttp
|
||||
ea6ff916a226e39a5e67b2118fc3ceb0dbc69d8d473051a5df19af14e03ae25e *mips-linux.elf/upx-3.95
|
||||
0cbc8eaecb2aa7dcc2e9d7b11ba0c0e26193f1328a35107cf1069a8c5f9e63be *mipsel-linux.elf/upx-3.91
|
||||
7b112c59fccf3e5f3d4ec253fdb25761e47705a1c5d3a0103249b1747bbbe7d9 *mipsel-linux.elf/upx-3.95
|
||||
de8354fbeaf0623f3d08c3945dcdb5a8f0c078fe3e8082a13767979e841e6677 *powerpc-linux.elf/upx-3.91
|
||||
403c26bc1dda0cbf23032bc5ec5ac42ed8537a640a077c4332446227c8a3eb7b *powerpc-linux.elf/upx-3.95
|
||||
093a7fdbb555c8aea8728b4d6240ed3b723ee9007c5f6ea40a8daf2d1eb63f54 *powerpc64le-linux.elf/upx-3.95
|
||||
"
|
||||
expected_sha256sums__t140_compress_lzma_2_no_filter="\
|
||||
804324e788c9cafe63899ec5a63d77e3a51cce3b0750b1c8b34998b67a748fe4 *amd64-linux.elf/upx-3.91
|
||||
289966c134b6a8205ab24985ece406825e752f585cde562dd89e5dfd6b85d685 *amd64-linux.elf/upx-3.95
|
||||
85334ab36776fbc83d7f9b323e398045709a84227cc060ec1b11416e47b7d670 *amd64-win64.pe/upx-3.95.exe
|
||||
662c325309248481d6badea5e1f029199e016805e71493f293b4cc1ddaaf7312 *arm-linux.elf/upx-3.95
|
||||
6702553672b3c82c5202568995e147ff0add3d313cf947c11715e28619e0d8a4 *arm-wince.pe/upx-3.91.exe
|
||||
18911ee9b594bd26afc0e8613cf7b2ea1c94a7802e34f7cc8f73219ce073b549 *arm64-linux.elf/upx-3.95
|
||||
8406d036dbd9cdccaad665b6ef1a7c2dd19444e68cc22356862981f8bb887705 *armeb-linux.elf/upx-3.91
|
||||
88309cf1e9ced304ae7075a1936fe5ca36252b02778122b7c68a945552e5d985 *armeb-linux.elf/upx-3.95
|
||||
97333fc14e57dfa8e1e5253d5e1fef192be15ab244c8f8fcb085df6df84a6af9 *i386-dos32.djgpp2.coff/upx-3.91.exe
|
||||
35695a112da8561ce23421e143a175b208cbfb111147d0d1b66076204eccb786 *i386-dos32.djgpp2.coff/upx-3.95.exe
|
||||
18573567330d45620d03eb4f429ef961237e699d4f3e6996b821a4b06b41cfaa *i386-linux.elf/upx-3.91
|
||||
e29d386a052212dec3c772afc82a082935c45f2082f534a703cac1a3df526624 *i386-linux.elf/upx-3.95
|
||||
41bdbc2c6a81afbd84bd76c0f86aefbe2910e9d134ad7f4d8546d75faf0bb9f2 *i386-win32.pe/upx-3.91.exe
|
||||
86d64438184889bed06efcb58acb4474ca0a5f9e6f68b13454dc0c3769994953 *i386-win32.pe/upx-3.95.exe
|
||||
3a5d8cc9d5614d78739b1b3eaf2f5fce1607fb27c9229da88580faedd48a1e32 *m68k-atari.tos/upx-3.91.ttp
|
||||
621d84c8fb8f51d97846d6db10b42cf761fffc33f5ed62a30a4c1ce12a7581ab *mips-linux.elf/upx-3.95
|
||||
9de8d51d185935276faa5aea301d6cb027acad0eb61061a0e9c21aacc931b045 *mipsel-linux.elf/upx-3.91
|
||||
0f8fb6ae0e8a62cc1d349ced9beb18be5eaf82fd90960250eea8c184d0cc8140 *mipsel-linux.elf/upx-3.95
|
||||
577584395dc5cc88a5302b69d5492a10da5eb2712bb22f4ad09b222af287f401 *powerpc-linux.elf/upx-3.91
|
||||
1287341561dde2168d79165e0ebb15bfd5e404b28f2defd5163e7b658bb1b9eb *powerpc-linux.elf/upx-3.95
|
||||
132c287fa13771b9a251d02d007fb5606acc298afc8defb556eafe05c4a6eea5 *powerpc64le-linux.elf/upx-3.95
|
||||
6dd472386ff2a9683d75fe4cc8d0d40be223681f4d7305a51a7aacf25501e60f *amd64-linux.elf/upx-3.91
|
||||
4bbb96b109ae2b8b43b957bc66c3cdc2cfcf3a692377153ef912d09a495c876c *amd64-linux.elf/upx-3.95
|
||||
510fc860ac393abcfdbb547e999c12a6c6e928ead026607a6879fa7ca1e2d568 *amd64-win64.pe/upx-3.95.exe
|
||||
a54c0e5b61257154c56f076460f64efbb4216c913c846073d0a695ac3c0ddffd *arm-linux.elf/upx-3.95
|
||||
9182294f2e31db89b138294cbbc6f6d03ea39a00565adf0e052ed3d21491e1b5 *arm-wince.pe/upx-3.91.exe
|
||||
fde8face710b6a479a96d7d2d40a29ac8894d5483403e33acbf4a5d6f9cdb29d *arm64-linux.elf/upx-3.95
|
||||
0a92af3f6034487034ea062bc44c93bba74219fa5fdcbb34d1643a95f7daa9ed *armeb-linux.elf/upx-3.91
|
||||
2c11ec89ad145e9f82c3cbbd63ed1e1eca2b0d3c3081fce3e0500ed33c05a623 *armeb-linux.elf/upx-3.95
|
||||
13cbcb06079492a21b7440b981250f84ff2be48a69daa168d95cee798f8fbf77 *i386-dos32.djgpp2.coff/upx-3.91.exe
|
||||
adfdcd033340a7b14945c9a60da036e25d44c8b1ee0811ac0a4ef1cbca423cc5 *i386-dos32.djgpp2.coff/upx-3.95.exe
|
||||
e5fff5b965da26349311c0513d09086600c3b466f1d53e42d6e35d6b4656168e *i386-linux.elf/upx-3.91
|
||||
cf8df3858bbb1c92a06e57ce1b971e11bbf280954f2fc1dc7e5b5a4641d72819 *i386-linux.elf/upx-3.95
|
||||
ddc4952ef008b7f31e69bf53310d6f03b36a959ebb1cd3c3985d560efcbd4296 *i386-win32.pe/upx-3.91.exe
|
||||
99b0b637b562798a440ba605d44e34cf7d4ff995b04dc2e54ebee288ed5180b4 *i386-win32.pe/upx-3.95.exe
|
||||
89a5de403a012256afefff0f88e1cff4696dee611946e326ad15416dbdba7d13 *m68k-atari.tos/upx-3.91.ttp
|
||||
eac695bc19163050c5bee9271393156a195bfef9c3c76f5aaf3aaef00f5602eb *mips-linux.elf/upx-3.95
|
||||
b1331b88421cdf8ef73f8ef1a2c86045fc56a495c08d06d83018c88f5f3934de *mipsel-linux.elf/upx-3.91
|
||||
9644118e26647d489e811ebe3bfd320e2976dbe26621e994fe979b0f9d175818 *mipsel-linux.elf/upx-3.95
|
||||
64a4a31815e4bf43e2ea866faa494c69a4209ed53055f16562d0d2d6ba7fd927 *powerpc-linux.elf/upx-3.91
|
||||
dec559bf9cbd4d1745e8f3bf2cedf016a72f443d037f75eab0d2baab191f0ae1 *powerpc-linux.elf/upx-3.95
|
||||
f10b8afa319b1056a82f24dd52d13003c5cf005fc3cc3481dad1e58ef33e973f *powerpc64le-linux.elf/upx-3.95
|
||||
"
|
||||
expected_sha256sums__t150_compress_ucl_2_all_filters="\
|
||||
c5bc7dc605b6d6fad71e796260d9b533a4a39ff2664bc1164d1e33a4f52bcd8d *amd64-linux.elf/upx-3.91
|
||||
543e5484080f84ca511d4d7a3ff86a6b06aeaefc17c5dd65dff859c1d15d5c1f *amd64-linux.elf/upx-3.95
|
||||
16b7f3c5b0aa1854edecc1519b9b8b9fb8869f7b8b295aa6a42f684750f641b9 *amd64-win64.pe/upx-3.95.exe
|
||||
b4919e7441869d45b98454abd935cd5dbef06bb3a0382f852f3552e6f8ba9768 *arm-linux.elf/upx-3.95
|
||||
32f7fd369c33f4c70fcb7e6ece14f3cb532845a2410af8fa9d6e23b380428a3a *arm-wince.pe/upx-3.91.exe
|
||||
6a91fb2df9366591530bd4d4e240e7cb0316de19bc437b93adb00dec26fa9227 *arm64-linux.elf/upx-3.95
|
||||
839dca66684e5fe8da1a81507c427b450d3af00014a06cf1e728091b412d4439 *armeb-linux.elf/upx-3.91
|
||||
98fc09fded3e4c4e377ad7b1cb109d0115ce34c215762ef85810841b2b1c6973 *armeb-linux.elf/upx-3.95
|
||||
765d81de304b2e60ee51da124677ba3d762da34df2f0e7989c8e967aa130754c *i386-dos32.djgpp2.coff/upx-3.91.exe
|
||||
2d4429efc2161399e07e7bafd94b0e8631f8afdc2dc27f823b8983ad9cc74ffd *i386-dos32.djgpp2.coff/upx-3.95.exe
|
||||
e9c041cdf4da72fabba9a402eaffe35a2ffd59caaa629580a6fdf61a3810ec01 *i386-linux.elf/upx-3.91
|
||||
a6905f887a7f9c28657b9afe62121b2c2e4372594654b75fe3f6c77c2fe608dc *i386-linux.elf/upx-3.95
|
||||
f0e2972e405a0d72c09fca7e63a56bb5c3658af558253151234431a7f7be4df0 *i386-win32.pe/upx-3.91.exe
|
||||
1dd5519f77e84d824b97d480fcc3ce03c9302411af4bfedc720970f0da42511f *i386-win32.pe/upx-3.95.exe
|
||||
eb475239ee1e22b9fde001334f2e4b9198e69e5cbf1dad4799e9689ee3f4b4a3 *m68k-atari.tos/upx-3.91.ttp
|
||||
c7b5aa7015d3aebfb26dbfc07cccaf27c95635eb3059bbe3b63ea4464d348ca0 *mips-linux.elf/upx-3.95
|
||||
1665df73de7d6295054a6586f36a3539d04970036ed589a13d15889bac0531dc *mipsel-linux.elf/upx-3.91
|
||||
dd6725bcff72b27b292670eef5e165e5150916c11147a782b648e954cdfb0951 *mipsel-linux.elf/upx-3.95
|
||||
68fe23ad35bb80fe99d3d83ca5856aabe5816fe415f70ac9e94a241283972088 *powerpc-linux.elf/upx-3.91
|
||||
bc2ae2af43c3e07b3877b0f9c569db3a11b4b5fe593bdd86702ff6e9e5bbf26a *powerpc-linux.elf/upx-3.95
|
||||
9081f42953e76c5c2985dc5ed4eb6db8569ac9cac1935181031d06251c9e2b75 *powerpc64le-linux.elf/upx-3.95
|
||||
2e89a5b8192957b066d5a5ee39e47663518f49c1e7811f6806e21d938201d5b6 *amd64-linux.elf/upx-3.91
|
||||
d1cfdda4b93d697211c052f3d85cd745e533261f05cc06c2869a8561c07b4f57 *amd64-linux.elf/upx-3.95
|
||||
c7381363e31af6789111f58ca590b0d751956c322684efa1914f1d918ecc23ce *amd64-win64.pe/upx-3.95.exe
|
||||
4dc8ba75edd4b1c3d890c9deeb033d9abf08fb65054eddb4f34138d34503c21d *arm-linux.elf/upx-3.95
|
||||
36f744d6dca6ecb8c60ee456859ac6a1ac241d12ababa20a5e2d0d79551d53aa *arm-wince.pe/upx-3.91.exe
|
||||
72d3de2abdc3985c790d833a9535054683e2b3feaa6b96778e55ea8f448846a3 *arm64-linux.elf/upx-3.95
|
||||
233d4f130995bb7155064ce6f651b9f6ac61268c8698ccc90a8ea3b2e297cb39 *armeb-linux.elf/upx-3.91
|
||||
a107428a7675181974a8efc359d39da74510098d8307347865f7bcdd707e28ad *armeb-linux.elf/upx-3.95
|
||||
bd57c1e3844310c2a864384f2b83a5781933a5beb05a5eb748a6094e37621166 *i386-dos32.djgpp2.coff/upx-3.91.exe
|
||||
1a13debece417ada4e18d5ec02efa7ef1c354ddfa4674b5717e0aa6bc90c16e3 *i386-dos32.djgpp2.coff/upx-3.95.exe
|
||||
f7b56af17d3d8402310387d1e82f90fa670dfa058feb3fe413ac81c01a1efbb1 *i386-linux.elf/upx-3.91
|
||||
fe9162fbfe8f4eb1c9f286df68107c08f25592d2edaaf5707540c81f709e29ac *i386-linux.elf/upx-3.95
|
||||
aaa267d824bd0520c016edcc1a6642d4898030760879e1da883b8211cf071350 *i386-win32.pe/upx-3.91.exe
|
||||
d178699c0ed805829e457987ea5da21f4e37cf1eb74529235d9b1275bf3122f6 *i386-win32.pe/upx-3.95.exe
|
||||
8376ba3954c4fd9cd5e5e8e38923759db005a4048c3d86dc76476e9f3d92a07d *m68k-atari.tos/upx-3.91.ttp
|
||||
65a0227127b7952a42216c79a8431d1bbe7f04c9efdc81f72095d095a969cb80 *mips-linux.elf/upx-3.95
|
||||
c2bd45b55980bfbc5e568a640643772e3e82bc02cd2c7559cb1c57fc0809d01e *mipsel-linux.elf/upx-3.91
|
||||
74e25daba42baeaaffadab00bacca56b1de5f151a00160592077288a678f41f2 *mipsel-linux.elf/upx-3.95
|
||||
904310944bec344897fc6b7a61dfe8ee639d136c555a950c736059cbc6cac8be *powerpc-linux.elf/upx-3.91
|
||||
5304a95cdcdbdcb76cfac2b93e254f601fb73f68be0a44ed282096aec8d55ae8 *powerpc-linux.elf/upx-3.95
|
||||
7ebd0be91bc9f60e22304103b3543b16a0fd128aa22f11474e31aecc97703e43 *powerpc64le-linux.elf/upx-3.95
|
||||
"
|
||||
expected_sha256sums__t160_compress_all_methods_1_no_filter="\
|
||||
31ebcdb8bc47adecd530ed4856fd980d2d1f9634223633e881c0bada9df5833e *amd64-linux.elf/upx-3.91
|
||||
f68db730964b5616e18166679e5f145f284153c3fb60ca6c5221565b73496fed *amd64-linux.elf/upx-3.95
|
||||
fb77031bf3378bf36f8e5578f613ef270469b45b3092115302cfa5f0263f3ea2 *amd64-win64.pe/upx-3.95.exe
|
||||
51056aab220ba9f8d8e1cba1493d1ffb06276b6528a6ea17f6a53592c0e2b918 *arm-linux.elf/upx-3.95
|
||||
1cd0e34cd590faaad5e315b0a6b2005b1af4cbc198804ee985407cabe9593d5f *arm-wince.pe/upx-3.91.exe
|
||||
80de1405d287740715346529a8d28110d79ad6ddac7d22e53b03f0b9e2b5b494 *arm64-linux.elf/upx-3.95
|
||||
8f6baca1ba513b7bcc0ddea296567955232deeee17033e4b556c742415aef820 *armeb-linux.elf/upx-3.91
|
||||
39e0c345678d189a792e4abbfda523c5447eb272a66744cade79981c146e9539 *armeb-linux.elf/upx-3.95
|
||||
98ef45954db27ffa8acbabb7a8abe8ecc61027e62dd0f7d94fb1af4c4a0fa8b8 *i386-dos32.djgpp2.coff/upx-3.91.exe
|
||||
b0b518e4e34c87812550eae4aa19717a571337bae3839d132188ccb20f6f7752 *i386-dos32.djgpp2.coff/upx-3.95.exe
|
||||
5c4ca76139f3206c8f5902f2c5f02cd510df5275dbf857a6ad323316eea77ed4 *i386-linux.elf/upx-3.91
|
||||
edf9302620e1c640dd7614305fbe8e897dbfa29805b674390448ee4d88f3f9ee *i386-linux.elf/upx-3.95
|
||||
4b766a3851c2452be06e937a85e8bcd482d8c57e929552abe7276f550f57009a *i386-win32.pe/upx-3.91.exe
|
||||
71efdedb51745d68fa20b533dd5a19a21ec92a6a07fa9fcb8e052f474b513cc1 *i386-win32.pe/upx-3.95.exe
|
||||
0a1bbeeac1a56ac01fe6528e36822793b723bed1b578a922a7ad37a16549fec6 *m68k-atari.tos/upx-3.91.ttp
|
||||
721a41418323ff67c2a90f61eab8c7f0ee45a5fa2a4a4d83d0240b487b045ea3 *mips-linux.elf/upx-3.95
|
||||
38c129ba9a0d7f8909070532901aa70dc19d58890ca1dbbd3ec7419a401cc9f0 *mipsel-linux.elf/upx-3.91
|
||||
1ec691975942533d9bb288948fc283cfe57e0e09853bd02149af63b9788b6be5 *mipsel-linux.elf/upx-3.95
|
||||
daee5df21ce65551309573a121db90255b6f034eac7988c4cb34bed6834086ce *powerpc-linux.elf/upx-3.91
|
||||
d27dffec68b530d2a8ffb5d440ec9ebe3772d45aaa699329dbb4b0a850cbbfff *powerpc-linux.elf/upx-3.95
|
||||
b021e58ff550aa160c83c122e03b63c1baf28808a584a9aefac4268a77095bec *powerpc64le-linux.elf/upx-3.95
|
||||
4d8069614af5721c7878daf10ee1d30a6bffc5446532963e2ff0e6cb6f1feecd *amd64-linux.elf/upx-3.91
|
||||
f1971902f7d8f840fdc70ad9edbf5587db556ba046947f5ee7b4130e9ba7de5a *amd64-linux.elf/upx-3.95
|
||||
0198a6cfd468f7ec7cd32294333400a4c97bf1cac32602594681db8f08c87700 *amd64-win64.pe/upx-3.95.exe
|
||||
d46340dcd209cce0f1d65d6a50754ea3246cdbba730199765b2c2ac40957bd55 *arm-linux.elf/upx-3.95
|
||||
aa03361a7dae633d5b6c8b4164726c99bfc28fcf4f1ac8ebea6fc44e90c03244 *arm-wince.pe/upx-3.91.exe
|
||||
aa0a3dda3e2f073eb36d6614c02f4af79590876a23437623ea6c231be8e070fa *arm64-linux.elf/upx-3.95
|
||||
578547a4d527655c7fd661148dfcf0f7dc9585dfb08063c13b116364a881bf15 *armeb-linux.elf/upx-3.91
|
||||
0034809b31b0105631b0e4c0a4378cfd26a80dfca2016228e8084f410025f091 *armeb-linux.elf/upx-3.95
|
||||
55b9b578a97a7b8637a9041a222269f2563a4e1f75c329c533f83432c8f9652c *i386-dos32.djgpp2.coff/upx-3.91.exe
|
||||
98a9f601d095f910c68bbf35ff50f19e3e851ef5dae78fc0e9ef4462dd8a314d *i386-dos32.djgpp2.coff/upx-3.95.exe
|
||||
45f714365212b31419986016b5b730ca77523036469e28242543bfde4dc44678 *i386-linux.elf/upx-3.91
|
||||
e45f6ae7ad7b9e719e5080bfbd04e7c961242473bb8f1574cb625bc8a1abd201 *i386-linux.elf/upx-3.95
|
||||
0b5d940059fc6f2a3d5664eadd0781399210c306be99411beeb8f6f02ea85762 *i386-win32.pe/upx-3.91.exe
|
||||
0f5b50dfe0db34ae07f113871a39c64624f964ed16dc8d49922e6a891c17a3bd *i386-win32.pe/upx-3.95.exe
|
||||
56fd999694feb66cdc2272daf86bb91b3c66b857867f3e0c071f3e70624760f4 *m68k-atari.tos/upx-3.91.ttp
|
||||
2d8d2e02bedad8ba1e7d69a89888b173b9be48ee154e2461c205ba4eae6ececa *mips-linux.elf/upx-3.95
|
||||
c478c21ecabe91910cf861ebc6b6d38deeb31545e5ae44eaf826dafb477bbfba *mipsel-linux.elf/upx-3.91
|
||||
4d66e1b32ca6b1d399616de5643ee5d1c54a7bf1eca761055570450f56efe4f9 *mipsel-linux.elf/upx-3.95
|
||||
72c85b48afb30cc191483af41f797a397225cfaaa44e2eaf7a9d59d9033335e1 *powerpc-linux.elf/upx-3.91
|
||||
c0ed0c72fd6a6e0bfb4444b8c358018246f80cbc732388a22bd2492fd9fdc59c *powerpc-linux.elf/upx-3.95
|
||||
070f4c2ca60717abedda0ab4030d546cca8a75b9872038a414e2946b8d8f93e7 *powerpc64le-linux.elf/upx-3.95
|
||||
"
|
||||
expected_sha256sums__t170_compress_all_methods_no_lzma_5_no_filter="\
|
||||
0ad79f9b86da588e67877e59921cc501ca515dc50d27c077f73ef3fb2c303ecb *amd64-linux.elf/upx-3.91
|
||||
5e46d16f080ce4f7b7f317cd3c76b513a70fab1fafb10fbdb72c01d3006b2369 *amd64-linux.elf/upx-3.95
|
||||
8610b878784b51dfcab58e33536e9812cc69951a8d22c3fad9d4c2583f6bb6ac *amd64-win64.pe/upx-3.95.exe
|
||||
cd02bf210f1d183bdc53f4442a36114b7385b165130b74bcce830703f8c7d9d7 *arm-linux.elf/upx-3.95
|
||||
d4a6895180ebaaecff91374a58101370db5a8817c1ad1f99876cec02aab6c561 *arm-wince.pe/upx-3.91.exe
|
||||
1ea76b4fe1cb058d3e0fade6139fe3c5d2745eb3becf0eddf557194e500648e6 *arm64-linux.elf/upx-3.95
|
||||
4f7d97f65cecd626654d3fc34201da60899905b826d395fc6dee7bd6d742363c *armeb-linux.elf/upx-3.91
|
||||
c5bbe69225f5d75e88ab176a91e148e9ed3733530d0ee9ed22a85aae201d7231 *armeb-linux.elf/upx-3.95
|
||||
11130e38b33a063737685110740a16f95f30661480c0f8bf582e4b7fa751f5b7 *i386-dos32.djgpp2.coff/upx-3.91.exe
|
||||
6f613b3b96147068eb8e1d577537cc8a16011600b79a80d3584c6c115de8b063 *i386-dos32.djgpp2.coff/upx-3.95.exe
|
||||
a1529b3e26fe8d101dbcb12338de0b9fc31324614fa5020e0807e3fdad5e9ad4 *i386-linux.elf/upx-3.91
|
||||
d8e019fff654dcffc9c55bcf171dd932f166fb401dd5884cf69e7db253740a60 *i386-linux.elf/upx-3.95
|
||||
264093035fbddf27a4e5c9d612ddc60fa7466c8b2254df56a28dded096afd438 *i386-win32.pe/upx-3.91.exe
|
||||
159918923abe10dd3a63aaf5c1c5a6a048a4a97a278587ec9ba6f72aa12b8d45 *i386-win32.pe/upx-3.95.exe
|
||||
38262d29ae5c51b6dc18d6b992f041ee602b0b8c601003ef423e4f8693eb1ad0 *m68k-atari.tos/upx-3.91.ttp
|
||||
6c543e309067db3bbd45d219b0d7c9ebc0df9c5db851530877031edc8a8b62dc *mips-linux.elf/upx-3.95
|
||||
ba36e7b3566e666d3b381b8b52068a93525d411df7ef2ec8a8073c942c0a5d95 *mipsel-linux.elf/upx-3.91
|
||||
ada7b5da780d7ee3c0e5339dcdebb1d2cf989f19b2b5728f10685563061291de *mipsel-linux.elf/upx-3.95
|
||||
efdd95af6a52c517ec00d0f16555ed3b1fe96ab3156219c58b62a1259585efd8 *powerpc-linux.elf/upx-3.91
|
||||
adbb1cecaa29295f2c1433fc95d2a0c610b62a5d3fe153a59c6b908597771014 *powerpc-linux.elf/upx-3.95
|
||||
6201d061df42316e2550e0848343b595708e75cebcc8cd03c272a5b0def610c1 *powerpc64le-linux.elf/upx-3.95
|
||||
223bcdc5f11daa4d0258090e967d4e0b5986d764d6b21fcfadba7212676396f2 *amd64-linux.elf/upx-3.91
|
||||
a3e5f1a20bd9db4ae920c5c7e7f1707a63fa3f557f9db50b5e1004b706e3a52c *amd64-linux.elf/upx-3.95
|
||||
355011427a4d433ccef5060e4cbebc59b0ecc38a430566cdb684330388ea0812 *amd64-win64.pe/upx-3.95.exe
|
||||
1e0a8363b539953181dc95283a1e3100bacce961f49e875c8f430b18d0e6672d *arm-linux.elf/upx-3.95
|
||||
e281362e2172468d20ea2c7171c847f47e01a63d912cafacf977236655708521 *arm-wince.pe/upx-3.91.exe
|
||||
7f3497c67e816b3f2af6642f09ba809166f8a0a65f52936cfb2e3d9756d7bd44 *arm64-linux.elf/upx-3.95
|
||||
7d9d52959a64c5dd19ea343c8c2bdd4d70fd0644d13c62924760407515fd74ba *armeb-linux.elf/upx-3.91
|
||||
e05ad251ec24e2f788de71c4c8cf7c8880a8eb7d8a516ca8d6ab94c715c2f77d *armeb-linux.elf/upx-3.95
|
||||
00a030d8967c5145b955eba17d84edd44b21c93b570f80a44e894a10a3ebf99f *i386-dos32.djgpp2.coff/upx-3.91.exe
|
||||
b4b0e3c774dbf3940af777d28e1ba7c62bfedaa710e3376e81259218779eae56 *i386-dos32.djgpp2.coff/upx-3.95.exe
|
||||
f903265140b193e672c4dd2bc28e68b9f822d73517f0b339fc715ad781a49fab *i386-linux.elf/upx-3.91
|
||||
6253062e41c4619bb3aeb807665a2925b1f01095d000c614c443b81d44112a1d *i386-linux.elf/upx-3.95
|
||||
7664ed4ce00b962a21ca5654993c4c4cb2ec1afcf9dc921cd90862f8412572cc *i386-win32.pe/upx-3.91.exe
|
||||
6ef354d0b2dffc71c32fc33f3f89b0b8ae7035e43e8a684a12d6ce2c53caf706 *i386-win32.pe/upx-3.95.exe
|
||||
5890050fe690bb93bf70693f1bef0e6ea708029836c7d8aa57de02b6aefe4239 *m68k-atari.tos/upx-3.91.ttp
|
||||
2bce2082ae39dedcc21a1a6c83e954073b368e9172ee0c7f2a3f13b3447a7898 *mips-linux.elf/upx-3.95
|
||||
d5b88d291a8a2141d9d9f07a6a21e11522e510c6520ba0c36ebf94d089962607 *mipsel-linux.elf/upx-3.91
|
||||
ff42d564999e02346c86d4156266f423edd55b3887aadf76d81a8c355e3b175d *mipsel-linux.elf/upx-3.95
|
||||
f33205ad8252524d8c48d18cdb03bba507e29c9cc931f94327a5a46480f70843 *powerpc-linux.elf/upx-3.91
|
||||
011683a891e30ea346efe9ba5c1488fb50f143e4090bd2be07537c696d6167db *powerpc-linux.elf/upx-3.95
|
||||
9d919460b0ceec4b880cdf14850fea8096d6796c2457467b3cc9b2ce954cc6de *powerpc64le-linux.elf/upx-3.95
|
||||
"
|
||||
########## end .sha256sums.recreate
|
||||
|
||||
@@ -1,40 +1,29 @@
|
||||
#! /bin/bash
|
||||
## vim:set ts=4 sw=4 et:
|
||||
set -e; set -o pipefail
|
||||
argv0=$0; argv0abs=$(readlink -en -- "$0"); argv0dir=$(dirname "$argv0abs")
|
||||
|
||||
# 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")
|
||||
fi
|
||||
source "$argv0dir/travis_init.sh" || exit 1
|
||||
|
||||
if [[ $BM_T =~ (^|\+)SKIP($|\+) ]]; then
|
||||
echo "UPX testsuite SKIPPED."
|
||||
exit 0
|
||||
fi
|
||||
if [[ $BM_X == rebuild-stubs ]]; then
|
||||
exit 0
|
||||
fi
|
||||
# very first version of the upx-testsuite; requires:
|
||||
# $upx_exe
|
||||
# $upx_testsuite_SRCDIR
|
||||
# $upx_testsuite_BUILDDIR (optional)
|
||||
# $BM_T (optional)
|
||||
|
||||
# convenience
|
||||
[[ -z $upx_testsuite_BUILDDIR ]] && upx_testsuite_BUILDDIR=./tmp-upx-testsuite
|
||||
[[ -f $upx_exe ]] && upx_exe=$(readlink -en -- "$upx_exe")
|
||||
|
||||
# create dirs
|
||||
cd / || exit 1
|
||||
# make dirs absolute
|
||||
upx_testsuite_SRCDIR=$(readlink -en -- "$upx_testsuite_SRCDIR")
|
||||
if [[ ! -d "$upx_testsuite_SRCDIR/files/packed" ]]; then
|
||||
echo 'invalid or missing $upx_testsuite_SRCDIR:'
|
||||
echo ' please git clone https://github.com/upx/upx-testsuite'
|
||||
echo ' and set (export) the envvar upx_testsuite_SRCDIR to the local file path'
|
||||
exit 1
|
||||
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
|
||||
|
||||
# /***********************************************************************
|
||||
@@ -148,8 +137,6 @@ if [[ $BM_T =~ (^|\+)ALLOW_FAIL($|\+) ]]; then
|
||||
set +e
|
||||
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
|
||||
upx_run=$upx_exe
|
||||
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"
|
||||
fi
|
||||
|
||||
if [[ $BM_B =~ (^|\+)coverage($|\+) ]]; then
|
||||
(cd / && cd "$upx_BUILDDIR" && lcov -d . --zerocounters)
|
||||
fi
|
||||
|
||||
export UPX="--prefer-ucl --no-color --no-progress"
|
||||
export UPX_DEBUG_DISABLE_GITREV_WARNING=1
|
||||
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 --help >/dev/null; then echo "UPX-ERROR: FATAL: upx --help FAILED"; exit 1; fi
|
||||
rm -rf ./testsuite_1
|
||||
mkbuilddirs testsuite_1
|
||||
mkdir testsuite_1
|
||||
cd testsuite_1 || exit 1
|
||||
|
||||
# /***********************************************************************
|
||||
|
||||
+242
-76
@@ -1,5 +1,4 @@
|
||||
# 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
|
||||
# unfortunately this sometimes breaks builds in mysterious ways...
|
||||
@@ -7,16 +6,10 @@
|
||||
|
||||
name: 'CI'
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- '*'
|
||||
- '!appveyor*'
|
||||
- '!gitlab*'
|
||||
- '!travis*'
|
||||
workflow_dispatch:
|
||||
on: [push, workflow_dispatch]
|
||||
|
||||
env:
|
||||
DEBIAN_FRONTEND: noninteractive
|
||||
UPX_CMAKE_BUILD_FLAGS: --verbose
|
||||
|
||||
jobs:
|
||||
@@ -27,27 +20,30 @@ jobs:
|
||||
- name: 'Install extra packages'
|
||||
run: |
|
||||
uname -a; pwd; id; umask
|
||||
cd ..; mkdir -p deps; cd deps; mkdir packages
|
||||
# for ubuntu-22.04: install python2
|
||||
##export DEBIAN_FRONTEND=noninteractive
|
||||
##sudo apt-get install -y --no-install-recommends python2-minimal
|
||||
mkdir ../deps; cd ../deps; mkdir packages
|
||||
# for ubuntu-22.04: install python2-minimal
|
||||
##sudo apt-get update && sudo apt-get install -y --no-install-recommends python2-minimal
|
||||
# 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://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
|
||||
wget -q 'http://archive.kernel.org/ubuntu-archive/ubuntu/pool/main/m/mpfr4/libmpfr4_3.1.6-1_amd64.deb'
|
||||
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/
|
||||
rm -rf ./*.deb ./packages
|
||||
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'
|
||||
uses: actions/checkout@v3
|
||||
with: { submodules: true }
|
||||
- name: 'Rebuild and verify stubs'
|
||||
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'
|
||||
run: |
|
||||
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
|
||||
|
||||
job-linux-cmake:
|
||||
@@ -58,25 +54,45 @@ jobs:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- { os: ubuntu-20.04 }
|
||||
- { os: ubuntu-22.04 }
|
||||
- { os: ubuntu-22.04, use_m32: true }
|
||||
- { os: ubuntu-20.04, use_m32: false }
|
||||
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'
|
||||
uses: actions/checkout@v3
|
||||
with: { submodules: true }
|
||||
- name: 'Build cmake debug-gcc'
|
||||
run: 'make build/debug-gcc'
|
||||
- name: 'Build cmake release-gcc'
|
||||
run: 'make build/release-gcc'
|
||||
- name: 'Build cmake debug-clang'
|
||||
run: 'make build/debug-clang'
|
||||
- name: 'Build cmake release-clang'
|
||||
run: 'make build/release-clang'
|
||||
- name: 'Check out test suite'
|
||||
run: 'git clone --depth=1 https://github.com/upx/upx-testsuite ../deps/upx-testsuite'
|
||||
- name: 'Build cmake extra/gcc/debug'
|
||||
run: 'make build/extra/gcc/debug'
|
||||
- name: 'Build cmake extra/gcc/release'
|
||||
run: 'make build/extra/gcc/release'
|
||||
- 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-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'
|
||||
run: |
|
||||
N=upx-${GITHUB_REF_NAME}-${GITHUB_SHA:0:7}-${{ matrix.os }}
|
||||
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")
|
||||
# GitHub Actions magic: set "artifact_name" environment value for use in next step
|
||||
echo "artifact_name=$N" >> $GITHUB_ENV
|
||||
@@ -87,10 +103,20 @@ jobs:
|
||||
path: tmp/artifact
|
||||
- name: 'Run basic tests'
|
||||
run: |
|
||||
make -C build/debug-gcc test
|
||||
make -C build/release-gcc test
|
||||
make -C build/debug-clang test
|
||||
make -C build/release-clang test
|
||||
make -C build/extra/gcc/debug test
|
||||
make -C build/extra/gcc/release test
|
||||
make -C build/extra/clang/debug 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:
|
||||
needs: [ job-rebuild-and-verify-stubs ]
|
||||
@@ -100,28 +126,43 @@ jobs:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- { os: macos-11, gcc: gcc-10, gxx: 'g++-10' }
|
||||
# { os: macos-12, gcc: gcc-11, gxx: 'g++-11' } # disable gcc - XCode 14.0 ld bug
|
||||
- { os: macos-12 }
|
||||
- { os: macos-11, gcc: gcc-10, gxx: 'g++-10', testsuite: true }
|
||||
- { os: macos-12, gcc: gcc-11, gxx: 'g++-11', testsuite: true }
|
||||
steps:
|
||||
- name: 'Install brew packages'
|
||||
if: ${{ matrix.testsuite }}
|
||||
run: |
|
||||
brew update
|
||||
brew install coreutils
|
||||
- name: 'Check out code'
|
||||
uses: actions/checkout@v3
|
||||
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 != '' }}
|
||||
run: 'make build/debug-gcc CC=${{ matrix.gcc }} CXX=${{ matrix.gxx }}'
|
||||
- name: 'Build cmake release-gcc'
|
||||
run: 'make build/extra/gcc/debug CC=${{ matrix.gcc }} CXX=${{ matrix.gxx }}'
|
||||
- name: 'Build cmake extra/gcc/release'
|
||||
if: ${{ matrix.gcc != '' }}
|
||||
run: 'make build/release-gcc CC=${{ matrix.gcc }} CXX=${{ matrix.gxx }}'
|
||||
- name: 'Build cmake debug-clang'
|
||||
run: 'make build/debug-clang'
|
||||
- name: 'Build cmake release-clang'
|
||||
run: 'make build/release-clang'
|
||||
run: 'make build/extra/gcc/release CC=${{ matrix.gcc }} CXX=${{ matrix.gxx }}'
|
||||
- name: 'Build cmake xtarget/cross-darwin-arm64/debug'
|
||||
run: |
|
||||
CC="clang -target arm64-apple-darwin" CXX="clang++ -target arm64-apple-darwin" \
|
||||
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'
|
||||
run: |
|
||||
N=upx-${GITHUB_REF_NAME}-${GITHUB_SHA:0:7}-${{ matrix.os }}
|
||||
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")
|
||||
# GitHub Actions magic: set "artifact_name" environment value for use in next step
|
||||
echo "artifact_name=$N" >> $GITHUB_ENV
|
||||
@@ -132,8 +173,15 @@ jobs:
|
||||
path: tmp/artifact
|
||||
- name: 'Run basic tests'
|
||||
run: |
|
||||
make -C build/debug-clang test
|
||||
make -C build/release-clang test
|
||||
make -C build/extra/clang/debug 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:
|
||||
needs: [ job-rebuild-and-verify-stubs ]
|
||||
@@ -143,8 +191,9 @@ jobs:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
# windows-2019 used to work but got broken with the 20220821.1
|
||||
# runner-image update; disable for now
|
||||
# windows-2019 used to work but got broken with the 20220821.1 runner-image
|
||||
# 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
|
||||
####- { os: windows-2019 }
|
||||
- { os: windows-2022 }
|
||||
@@ -152,8 +201,10 @@ jobs:
|
||||
- name: 'Check out code'
|
||||
uses: actions/checkout@v3
|
||||
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'
|
||||
# see https://github.com/actions/runner-images.git
|
||||
# debug remote image; also see https://github.com/actions/runner-images.git
|
||||
if: ${{ false }}
|
||||
run: |
|
||||
Get-Command bash; Get-Command cmake; Get-Command make
|
||||
@@ -180,71 +231,81 @@ jobs:
|
||||
run: |
|
||||
cmake --build build/debug --config Debug --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:
|
||||
needs: [ job-rebuild-and-verify-stubs ]
|
||||
name: ${{ matrix.name }}
|
||||
name: ${{ format('windows {0}', matrix.name) }}
|
||||
runs-on: ${{ matrix.os }}
|
||||
env:
|
||||
C: ${{ matrix.C }}
|
||||
B: release
|
||||
H: 'd:\a\upx'
|
||||
H: 'd:\a\upx\upx'
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- { name: amd64-win64-msvc-14.2, os: windows-2019, C: msvc-14.2-x64, A: x64 }
|
||||
- { name: amd64-win64-msvc-14.3, os: windows-2022, C: msvc-14.3-x64, A: x64 }
|
||||
- { name: i386-win32-msvc-14.2, os: windows-2019, C: msvc-14.2-x86, A: x86 }
|
||||
- { name: i386-win32-msvc-14.3, os: windows-2022, C: msvc-14.3-x86, A: x86 }
|
||||
- { name: amd64-win64-vs2019, os: windows-2019, C: msvc-14.2-x64, arch: amd64 }
|
||||
- { name: amd64-win64-vs2022, os: windows-2022, C: msvc-14.3-x64, arch: amd64 }
|
||||
- { name: arm64-win64-vs2019, os: windows-2019, C: msvc-14.2-x64, arch: amd64_arm64 }
|
||||
- { 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:
|
||||
- name: 'Check out code'
|
||||
uses: actions/checkout@v3
|
||||
with: { submodules: true }
|
||||
- name: 'Prepare sources'
|
||||
shell: cmd
|
||||
- name: 'Prepare sources and Check out test suite'
|
||||
shell: bash
|
||||
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 --version & bash --version
|
||||
cd %H%
|
||||
md build build\%C% deps
|
||||
cd deps
|
||||
git clone --depth=1 https://github.com/upx/upx-testsuite
|
||||
git --version && bash --version
|
||||
git clone --depth=1 https://github.com/upx/upx-testsuite ../deps/upx-testsuite
|
||||
mkdir -p -v build/$C/$B/{ucl,upx,zlib,zstd}
|
||||
- name: 'Set up Developer Command Prompt'
|
||||
uses: ilammy/msvc-dev-cmd@v1
|
||||
with:
|
||||
arch: ${{ matrix.A }}
|
||||
arch: ${{ matrix.arch }}
|
||||
- name: 'Build'
|
||||
shell: cmd
|
||||
run: |
|
||||
@REM setup directories following the VPATH build in travis_build.sh
|
||||
@REM setup directories
|
||||
where cl & where link
|
||||
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
|
||||
git rev-parse --short=12 HEAD > %BDIR%\upx\.GITREV.txt
|
||||
@REM ===== build UCL =====
|
||||
cd %BDIR%\ucl
|
||||
set s=%H%\upx\vendor\ucl
|
||||
cl -MT -J -O2 -W4 %DEFS% -I%s%\include -I%s% -c %s%\src\*.c
|
||||
set s=%H%\vendor\ucl
|
||||
cl -MT -J -O2 -W4 -WX %DEFS% -I%s%\include -I%s% -c %s%\src\*.c
|
||||
link -lib -out:ucl.lib *.obj
|
||||
@REM ===== build 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
|
||||
@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 =====
|
||||
cd %BDIR%\upx
|
||||
set s=%H%\upx\src
|
||||
set s=%H%\src
|
||||
cat .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'
|
||||
shell: bash
|
||||
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"
|
||||
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
|
||||
echo "artifact_name=$N" >> $GITHUB_ENV
|
||||
- name: ${{ format('Upload artifact {0}', env.artifact_name) }}
|
||||
@@ -253,6 +314,7 @@ jobs:
|
||||
name: ${{ env.artifact_name }}
|
||||
path: tmp/artifact
|
||||
- name: 'Run basic tests'
|
||||
if: ${{ matrix.arch != 'amd64_arm64' }}
|
||||
run: |
|
||||
$ErrorActionPreference = 'stop'
|
||||
$ErrorView = 'NormalView'
|
||||
@@ -265,7 +327,111 @@ jobs:
|
||||
.\upx.exe -t upx_packed.exe
|
||||
.\upx_packed.exe --version
|
||||
- name: 'Run test suite'
|
||||
if: ${{ matrix.arch != 'amd64_arm64' }}
|
||||
shell: bash
|
||||
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:
|
||||
|
||||
@@ -10,10 +10,10 @@
|
||||
# Abandoned Issues and Pull Request".
|
||||
# https://igorwiese.com/images/papers/Paper_BotSE_19.pdf
|
||||
|
||||
name: 'Close inactive issues'
|
||||
name: 'GitHub - Close inactive issues'
|
||||
on:
|
||||
schedule:
|
||||
- cron: "30 6 * * 4"
|
||||
- cron: '30 6 * * 4'
|
||||
workflow_dispatch:
|
||||
jobs:
|
||||
close-issues:
|
||||
@@ -23,11 +23,11 @@ jobs:
|
||||
issues: write
|
||||
pull-requests: write
|
||||
steps:
|
||||
- uses: actions/stale@v6
|
||||
- uses: actions/stale@v7
|
||||
with:
|
||||
operations-per-run: 300
|
||||
exempt-all-milestones: true
|
||||
exempt-issue-labels: 'blocker,enhancement'
|
||||
exempt-issue-labels: 'blocker,enhancement,regression'
|
||||
days-before-stale: 60
|
||||
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.'
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
name: "CodeQL"
|
||||
name: 'Static Analyzer - CodeQL'
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ "devel", "devel4", "devel5", "master" ]
|
||||
pull_request:
|
||||
# The branches below must be a subset of the branches above
|
||||
branches: [ "devel", "devel4", "devel5" ]
|
||||
# push:
|
||||
# branches: [ 'devel', 'devel4', 'devel5', 'master' ]
|
||||
# pull_request:
|
||||
# # The branches below must be a subset of the branches above
|
||||
# branches: [ 'devel', 'devel4', 'devel5' ]
|
||||
schedule:
|
||||
- cron: '20 1 * * 3'
|
||||
workflow_dispatch:
|
||||
@@ -25,14 +25,14 @@ jobs:
|
||||
language: [ 'cpp' ]
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v3
|
||||
with: { submodules: true }
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@v2
|
||||
with:
|
||||
languages: ${{ matrix.language }}
|
||||
- name: Autobuild
|
||||
uses: github/codeql-action/autobuild@v2
|
||||
- name: Perform CodeQL Analysis
|
||||
uses: github/codeql-action/analyze@v2
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v3
|
||||
with: { submodules: true }
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@v2
|
||||
with:
|
||||
languages: ${{ matrix.language }}
|
||||
- name: Autobuild
|
||||
uses: github/codeql-action/autobuild@v2
|
||||
- name: Perform CodeQL Analysis
|
||||
uses: github/codeql-action/analyze@v2
|
||||
|
||||
@@ -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:
|
||||
#pull_request:
|
||||
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*
|
||||
/vendor*
|
||||
|
||||
.depend
|
||||
GNUmakefile
|
||||
MMakefile
|
||||
Makevars.local*
|
||||
tmp-testsuite*
|
||||
tmp*
|
||||
|
||||
*.a
|
||||
*.d
|
||||
@@ -30,20 +29,14 @@ doc/*.ps
|
||||
doc/*.tex
|
||||
|
||||
src/stub/**/.*-stamp
|
||||
src/stub/**/MMakefile
|
||||
src/stub/tmp*/*.bin
|
||||
src/stub/tmp*/*.bin.bindump
|
||||
src/stub/tmp*/*.bin.disasm
|
||||
src/stub/tmp*/*.d
|
||||
src/stub/tmp*/*.o
|
||||
src/stub/tmp*/*.o.disasm
|
||||
src/stub/tmp*/mips.r3000-*.[is]
|
||||
src/stub/tmp*/mipsel.r3000-*.[is]
|
||||
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/i386-linux-sstrip
|
||||
src/stub/tools/sstrip/sstrip
|
||||
|
||||
@@ -13,6 +13,11 @@
|
||||
url = https://github.com/upx/upx-vendor-ucl.git
|
||||
branch = upx-vendor
|
||||
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"]
|
||||
path = vendor/zlib
|
||||
url = https://github.com/upx/upx-vendor-zlib.git
|
||||
|
||||
+138
-61
@@ -1,11 +1,22 @@
|
||||
cmake_minimum_required(VERSION 3.10 FATAL_ERROR)
|
||||
cmake_minimum_required(VERSION 3.8.0 FATAL_ERROR)
|
||||
|
||||
# compilation config options
|
||||
option(UPX_CONFIG_DISABLE_GITREV "Do not compile with default Git version info.")
|
||||
option(UPX_CONFIG_DISABLE_SANITIZE "Do not compile with default sanitize options.")
|
||||
option(UPX_CONFIG_DISABLE_WERROR "Do not compile with default -Werror option.")
|
||||
# test config options
|
||||
option(UPX_CONFIG_DISABLE_SELF_PACK_TEST "Do not test packing UPX with itself") # see below
|
||||
if(NOT IS_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/.git")
|
||||
# permissive config defaults when building from source code tarball
|
||||
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
|
||||
@@ -13,27 +24,27 @@ option(UPX_CONFIG_DISABLE_SELF_PACK_TEST "Do not test packing UPX with itself")
|
||||
|
||||
# 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.
|
||||
set(CMAKE_DISABLE_IN_SOURCE_BUILD ON)
|
||||
set(CMAKE_DISABLE_SOURCE_CHANGES ON)
|
||||
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
|
||||
if(",${CMAKE_SOURCE_DIR}," STREQUAL ",${CMAKE_BINARY_DIR},")
|
||||
message(FATAL_ERROR "ERROR: In-source builds are not allowed, please use an extra build dir.")
|
||||
if(NOT MSVC_IDE)
|
||||
set(CMAKE_DISABLE_IN_SOURCE_BUILD ON)
|
||||
set(CMAKE_DISABLE_SOURCE_CHANGES ON)
|
||||
if(",${CMAKE_CURRENT_SOURCE_DIR}," STREQUAL ",${CMAKE_CURRENT_BINARY_DIR},")
|
||||
message(FATAL_ERROR "ERROR: In-source builds are not allowed, please use an extra build dir.")
|
||||
endif()
|
||||
endif()
|
||||
set(CMAKE_C_STANDARD_REQUIRED ON)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
set(CMAKE_C_STANDARD_REQUIRED ON)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
|
||||
|
||||
# determine git revision
|
||||
set(GITREV_SHORT "")
|
||||
set(GITREV_PLUS "")
|
||||
set(GIT_DESCRIBE "")
|
||||
find_package(Git)
|
||||
if(GIT_FOUND AND NOT UPX_CONFIG_DISABLE_GITREV)
|
||||
if(Git_FOUND AND NOT UPX_CONFIG_DISABLE_GITREV)
|
||||
execute_process(
|
||||
RESULT_VARIABLE result
|
||||
COMMAND "${GIT_EXECUTABLE}" rev-parse --short=12 HEAD
|
||||
ERROR_QUIET
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||
OUTPUT_VARIABLE GITREV_SHORT
|
||||
RESULT_VARIABLE result ERROR_QUIET
|
||||
OUTPUT_VARIABLE GITREV_SHORT OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||
)
|
||||
string(LENGTH "${GITREV_SHORT}" l)
|
||||
if(${result} EQUAL 0 AND ${l} EQUAL 12)
|
||||
@@ -45,11 +56,9 @@ if(GIT_FOUND AND NOT UPX_CONFIG_DISABLE_GITREV)
|
||||
set(GITREV_SHORT "")
|
||||
endif()
|
||||
execute_process(
|
||||
RESULT_VARIABLE result
|
||||
COMMAND "${GIT_EXECUTABLE}" describe --match "v*.*.*" --tags --dirty
|
||||
ERROR_QUIET
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||
OUTPUT_VARIABLE GIT_DESCRIBE
|
||||
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}")
|
||||
@@ -69,7 +78,8 @@ else()
|
||||
message(STATUS "UPX_VERSION_GITREV: not set")
|
||||
endif()
|
||||
|
||||
project(upx VERSION 4.0.1 LANGUAGES C CXX)
|
||||
# CMake init
|
||||
project(upx VERSION 4.0.2 LANGUAGES C CXX)
|
||||
|
||||
# set default build type to "Release"
|
||||
get_property(is_multi_config GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG)
|
||||
@@ -90,6 +100,9 @@ endif()
|
||||
# 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")
|
||||
list(SORT ucl_SOURCES)
|
||||
add_library(upx_vendor_ucl STATIC ${ucl_SOURCES})
|
||||
@@ -100,13 +113,26 @@ list(SORT zlib_SOURCES)
|
||||
add_library(upx_vendor_zlib STATIC ${zlib_SOURCES})
|
||||
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)
|
||||
add_executable(upx ${upx_SOURCES})
|
||||
#target_compile_features(upx PRIVATE cxx_std_14)
|
||||
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)
|
||||
|
||||
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)
|
||||
set(warn_Werror "")
|
||||
set(warn_WX "")
|
||||
@@ -129,35 +155,53 @@ if(MSVC)
|
||||
add_definitions(-D_CRT_NONSTDC_NO_WARNINGS)
|
||||
add_definitions(-D_CRT_SECURE_NO_DEPRECATE)
|
||||
add_definitions(-D_CRT_SECURE_NO_WARNINGS)
|
||||
# set __cplusplus according to selected C++ standard; use new preprocessor
|
||||
add_definitions(-Zc:__cplusplus -Zc:preprocessor)
|
||||
else()
|
||||
# protect against security threats caused by misguided compiler "optimizations"
|
||||
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()
|
||||
add_definitions(-fno-strict-aliasing -fno-strict-overflow -funsigned-char)
|
||||
# disable overambitious auto-vectorization until this actually gains something
|
||||
add_definitions(-fno-tree-vectorize)
|
||||
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)
|
||||
# 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>)
|
||||
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)
|
||||
target_include_directories(${t} PRIVATE vendor/ucl/include vendor/ucl)
|
||||
upx_compile_target_debug_with_O2(${t})
|
||||
upx_sanitize_target(${t})
|
||||
if(MSVC)
|
||||
target_compile_options(${t} PRIVATE -J -W4 ${warn_WX})
|
||||
else()
|
||||
target_compile_options(${t} PRIVATE -Wall -Wextra -Wvla ${warn_Werror})
|
||||
target_compile_options(${t} PRIVATE ${warn_strict} ${warn_Werror})
|
||||
endif()
|
||||
|
||||
set(t upx_vendor_zlib)
|
||||
upx_compile_target_debug_with_O2(${t})
|
||||
upx_sanitize_target(${t})
|
||||
if(MSVC)
|
||||
target_compile_options(${t} PRIVATE -DHAVE_STDARG_H -DHAVE_VSNPRINTF -J -W3 ${warn_WX})
|
||||
@@ -167,8 +211,20 @@ else()
|
||||
target_compile_options(${t} PRIVATE -Wall -Wextra -Wvla -Wno-strict-prototypes ${warn_Werror})
|
||||
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)
|
||||
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>)
|
||||
if(GITREV_SHORT)
|
||||
target_compile_definitions(${t} PRIVATE UPX_VERSION_GITREV="${GITREV_SHORT}${GITREV_PLUS}")
|
||||
@@ -176,20 +232,26 @@ if(GITREV_SHORT)
|
||||
target_compile_definitions(${t} PRIVATE UPX_VERSION_GIT_DESCRIBE="${GIT_DESCRIBE}")
|
||||
endif()
|
||||
endif()
|
||||
#upx_compile_target_debug_with_O2(${t})
|
||||
upx_sanitize_target(${t})
|
||||
if(MSVC)
|
||||
target_compile_options(${t} PRIVATE -EHsc -J -W4 ${warn_WX})
|
||||
else()
|
||||
target_compile_options(${t} PRIVATE
|
||||
-Wall -Wextra -Wcast-align -Wcast-qual -Wmissing-declarations -Wpointer-arith
|
||||
-Wshadow -Wvla -Wwrite-strings ${warn_Werror}
|
||||
)
|
||||
target_compile_options(${t} PRIVATE ${warn_strict} ${warn_Werror})
|
||||
endif()
|
||||
if(NOT UPX_CONFIG_DISABLE_ZSTD)
|
||||
target_compile_definitions(${t} PRIVATE WITH_ZSTD=1)
|
||||
target_link_libraries(upx upx_vendor_zstd)
|
||||
endif()
|
||||
|
||||
#***********************************************************************
|
||||
# "ctest"
|
||||
# "make test"
|
||||
# "ninja test"
|
||||
#***********************************************************************
|
||||
|
||||
if(NOT UPX_CONFIG_CMAKE_DISABLE_TEST)
|
||||
|
||||
include(CTest)
|
||||
if(NOT CMAKE_CROSSCOMPILING)
|
||||
add_test(NAME upx-version COMMAND upx --version)
|
||||
@@ -219,17 +281,25 @@ if(NOT CMAKE_CROSSCOMPILING AND NOT UPX_CONFIG_DISABLE_SELF_PACK_TEST)
|
||||
upx_add_test(upx-run-packed ./upx-packed${exe} --version-short)
|
||||
endif()
|
||||
|
||||
endif() # UPX_CONFIG_CMAKE_DISABLE_TEST
|
||||
|
||||
#***********************************************************************
|
||||
# "cmake --install ."
|
||||
# "make install"
|
||||
# "ninja install"
|
||||
#***********************************************************************
|
||||
|
||||
if(NOT UPX_CONFIG_CMAKE_DISABLE_INSTALL)
|
||||
|
||||
# installation prefix and directories
|
||||
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()
|
||||
include(GNUInstallDirs)
|
||||
|
||||
if(DEFINED CMAKE_INSTALL_FULL_BINDIR)
|
||||
if(CMAKE_INSTALL_PREFIX)
|
||||
include(GNUInstallDirs)
|
||||
endif()
|
||||
if(CMAKE_INSTALL_PREFIX AND DEFINED CMAKE_INSTALL_FULL_BINDIR)
|
||||
install(TARGETS upx DESTINATION "${CMAKE_INSTALL_FULL_BINDIR}")
|
||||
install(FILES
|
||||
COPYING LICENSE NEWS README THANKS doc/upx-doc.html doc/upx-doc.txt
|
||||
@@ -238,35 +308,42 @@ if(DEFINED CMAKE_INSTALL_FULL_BINDIR)
|
||||
install(FILES doc/upx.1 DESTINATION "${CMAKE_INSTALL_FULL_MANDIR}/man1")
|
||||
endif()
|
||||
|
||||
endif() # UPX_CONFIG_CMAKE_DISABLE_INSTALL
|
||||
|
||||
#***********************************************************************
|
||||
# finally print some info about the build configuration
|
||||
#***********************************************************************
|
||||
|
||||
if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/maint/src/CMakeLists.extra.txt")
|
||||
include("${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/make/CMakeLists.maint.txt")
|
||||
endif()
|
||||
|
||||
function(print_var v)
|
||||
if(${v})
|
||||
message(STATUS "${v} = ${${v}}")
|
||||
endif()
|
||||
function(print_var)
|
||||
foreach(v ${ARGV})
|
||||
if(${v})
|
||||
message(STATUS "${v} = ${${v}}")
|
||||
endif()
|
||||
endforeach()
|
||||
endfunction()
|
||||
print_var(CMAKE_BUILD_TYPE)
|
||||
print_var(CMAKE_CONFIGURATION_TYPES)
|
||||
print_var(CMAKE_INSTALL_PREFIX)
|
||||
print_var(CMAKE_CROSSCOMPILING)
|
||||
print_var(CMAKE_C_COMPILER_ID)
|
||||
print_var(CMAKE_C_COMPILER_VERSION)
|
||||
print_var(CMAKE_C_COMPILER_ARCHITECTURE_ID)
|
||||
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(NOT UPX_CONFIG_CMAKE_DISABLE_PRINT_INFO)
|
||||
print_var(CMAKE_HOST_SYSTEM_NAME CMAKE_HOST_SYSTEM_VERSION)
|
||||
print_var(CMAKE_SYSTEM_NAME CMAKE_SYSTEM_VERSION 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_CXX_COMPILER_ID CMAKE_CXX_COMPILER_VERSION CMAKE_CXX_COMPILER_ARCHITECTURE_ID CMAKE_CXX_PLATFORM_ID CMAKE_CXX_COMPILER_ABI)
|
||||
endif() # UPX_CONFIG_CMAKE_DISABLE_PRINT_INFO
|
||||
print_var(CMAKE_INSTALL_PREFIX CMAKE_CONFIGURATION_TYPES CMAKE_BUILD_TYPE)
|
||||
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\"")
|
||||
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:
|
||||
|
||||
@@ -2,39 +2,31 @@
|
||||
# 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
|
||||
# cd build/release
|
||||
# cmake ../..
|
||||
# cmake --build .
|
||||
# make -j (or use "cmake --build . --parallel")
|
||||
|
||||
CMAKE = cmake
|
||||
UPX_CMAKE_BUILD_FLAGS += --parallel
|
||||
ifneq ($(VERBOSE),)
|
||||
UPX_CMAKE_BUILD_FLAGS += --verbose
|
||||
endif
|
||||
|
||||
# check git submodules
|
||||
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
|
||||
# enable this if you prefer Ninja for the actual builds:
|
||||
#UPX_CMAKE_CONFIG_FLAGS += -G Ninja
|
||||
|
||||
#***********************************************************************
|
||||
# default
|
||||
#***********************************************************************
|
||||
|
||||
__check_cache = $(if $(wildcard $1/CMakeCache.txt),@true,)
|
||||
run_config = $(call __check_cache,$1) $(CMAKE) -S . -B $1 $(UPX_CMAKE_CONFIG_FLAGS) -DCMAKE_BUILD_TYPE=$2
|
||||
run_build = $(CMAKE) --build $1 $(UPX_CMAKE_BUILD_FLAGS) --config $2
|
||||
run_cmake_config = $(CMAKE) -S . -B $1 $(UPX_CMAKE_CONFIG_FLAGS) -DCMAKE_BUILD_TYPE=$2
|
||||
run_cmake_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_GOAL = build/release
|
||||
|
||||
@@ -47,43 +39,148 @@ build/release: PHONY
|
||||
$(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++
|
||||
build/%-gcc: export CC=gcc
|
||||
build/%-gcc: export CXX=g++
|
||||
build/debug-gcc: PHONY
|
||||
$(call run_config,$@,Debug)
|
||||
$(call run_build,$@,Debug)
|
||||
build/release-gcc: PHONY
|
||||
$(call run_config,$@,Release)
|
||||
$(call run_build,$@,Release)
|
||||
define run_config_and_build
|
||||
$(call run_config,$1,$2)
|
||||
$(call run_build,$1,$2)
|
||||
endef
|
||||
|
||||
# force building with clang/clang++
|
||||
build/%-clang: export CC=clang
|
||||
build/%-clang: export CXX=clang++
|
||||
build/debug-clang: PHONY
|
||||
$(call run_config,$@,Debug)
|
||||
$(call run_build,$@,Debug)
|
||||
build/release-clang: PHONY
|
||||
$(call run_config,$@,Release)
|
||||
$(call run_build,$@,Release)
|
||||
build/extra/clang/debug: PHONY; $(call run_config_and_build,$@,Debug)
|
||||
build/extra/clang/release: PHONY; $(call run_config_and_build,$@,Release)
|
||||
build/extra/clang/%: export CC = clang
|
||||
build/extra/clang/%: export CXX = clang++
|
||||
|
||||
# cross compiler: Windows mingw-w64
|
||||
build/%-cross-mingw64: export CC=x86_64-w64-mingw32-gcc
|
||||
build/%-cross-mingw64: export CXX=x86_64-w64-mingw32-g++
|
||||
# disable sanitize to avoid link errors on GitHub CI
|
||||
build/%-cross-mingw64: UPX_CMAKE_CONFIG_FLAGS += -DUPX_CONFIG_DISABLE_SANITIZE=1
|
||||
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)
|
||||
# force building with clang/clang++ -m32
|
||||
build/extra/clang-m32/debug: PHONY; $(call run_config_and_build,$@,Debug)
|
||||
build/extra/clang-m32/release: PHONY; $(call run_config_and_build,$@,Release)
|
||||
build/extra/clang-m32/%: export CC = clang -m32
|
||||
build/extra/clang-m32/%: export CXX = clang++ -m32
|
||||
|
||||
.PHONY: 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,9 @@
|
||||
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
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
|
||||
|
||||
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
|
||||
|
||||
|
||||
@@ -85,9 +85,9 @@ THE FUTURE
|
||||
COPYRIGHT
|
||||
=========
|
||||
|
||||
Copyright (C) 1996-2022 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2022 Laszlo Molnar
|
||||
Copyright (C) 2000-2022 John F. Reiser
|
||||
Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2023 Laszlo Molnar
|
||||
Copyright (C) 2000-2023 John F. Reiser
|
||||
|
||||
UPX is distributed with full source code under the terms of the
|
||||
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
|
||||
--------------------------------------------
|
||||
|
||||
- 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
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
|
||||
|
||||
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
|
||||
|
||||
|
||||
@@ -55,6 +55,6 @@ Salvador Eduardo Tropea
|
||||
for beta testing
|
||||
Stefan Widmann
|
||||
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
|
||||
Natascha
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
-std=gnu++17
|
||||
-Ivendor
|
||||
-fno-strict-aliasing
|
||||
-fno-strict-overflow
|
||||
|
||||
+1
-1
@@ -8,7 +8,7 @@
|
||||
|
||||
|
||||
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
|
||||
|
||||
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
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:
|
||||
<elf.h> definitions for the ELF file format
|
||||
|
||||
+5
-5
@@ -22,7 +22,7 @@
|
||||
<h1 id="ABSTRACT">ABSTRACT</h1>
|
||||
|
||||
<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>
|
||||
|
||||
<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>
|
||||
|
||||
<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>
|
||||
|
||||
|
||||
+5
-5
@@ -6,7 +6,7 @@ SYNOPSIS
|
||||
|
||||
ABSTRACT
|
||||
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
|
||||
|
||||
UPX is a portable, extendable, high-performance executable packer for
|
||||
@@ -818,13 +818,13 @@ AUTHORS
|
||||
Jens Medoch <jssg@users.sourceforge.net>
|
||||
|
||||
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
|
||||
General Public License v2+; either under the pure GPLv2+ (see the file
|
||||
|
||||
@@ -133,7 +133,7 @@
|
||||
.\" ========================================================================
|
||||
.\"
|
||||
.IX Title "UPX 1"
|
||||
.TH UPX 1 "2022-11-16" "upx 4.0.1" " "
|
||||
.TH UPX 1 "2023-01-30" "upx 4.0.2" " "
|
||||
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
|
||||
.\" way too many mistakes in technical documents.
|
||||
.if n .ad l
|
||||
@@ -147,7 +147,7 @@ upx \- compress or expand executable files
|
||||
.IX Header "ABSTRACT"
|
||||
.Vb 3
|
||||
\& 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
|
||||
.Ve
|
||||
.PP
|
||||
@@ -1019,13 +1019,13 @@ Please report all bugs immediately to the authors.
|
||||
.Ve
|
||||
.SH "COPYRIGHT"
|
||||
.IX Header "COPYRIGHT"
|
||||
Copyright (C) 1996\-2022 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996\-2023 Markus Franz Xaver Johannes Oberhumer
|
||||
.PP
|
||||
Copyright (C) 1996\-2022 Laszlo Molnar
|
||||
Copyright (C) 1996\-2023 Laszlo Molnar
|
||||
.PP
|
||||
Copyright (C) 2000\-2022 John F. Reiser
|
||||
Copyright (C) 2000\-2023 John F. Reiser
|
||||
.PP
|
||||
Copyright (C) 2002\-2022 Jens Medoch
|
||||
Copyright (C) 2002\-2023 Jens Medoch
|
||||
.PP
|
||||
\&\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
|
||||
|
||||
+5
-5
@@ -13,7 +13,7 @@ B<upx> S<[ I<command> ]> S<[ I<options> ]> I<filename>...
|
||||
=head1 ABSTRACT
|
||||
|
||||
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
|
||||
|
||||
|
||||
@@ -932,13 +932,13 @@ Please report all bugs immediately to the authors.
|
||||
|
||||
=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
|
||||
GNU General Public License v2+; either under the pure GPLv2+ (see
|
||||
|
||||
@@ -6,10 +6,10 @@ 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-upx/upx-stubtools-20210104-vX,
|
||||
# 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-20221108-v7
|
||||
image=upx-cross-compile-20230115-v2
|
||||
|
||||
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
|
||||
# using a rootless Podman container
|
||||
|
||||
image=upx-cross-compile-20221108-v7
|
||||
image=upx-cross-compile-20230115-v2
|
||||
|
||||
flags=( -ti --read-only --rm )
|
||||
flags+=( --cap-drop=all ) # drop all capabilities
|
||||
@@ -34,7 +34,20 @@ podman run "${flags[@]}" "$image" bash -l
|
||||
|
||||
# now we can cross-compile UPX for Windows:
|
||||
# cd /home/upx/src/upx
|
||||
# rm -rf ./build/release-cross-mingw64
|
||||
# make build/release-cross-mingw64
|
||||
# rm -rf ./build/extra/cross-windows-mingw64/release
|
||||
# make build/extra/cross-windows-mingw64/release
|
||||
|
||||
# lots of other cross-compilers are installed; see "ls /usr/bin/*g++*"
|
||||
# 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)
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
# NOTE: this image is based on rebuild-stubs-with-upx/upx-stubtools-20210104-vX,
|
||||
# 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-20210104-v7
|
||||
FROM localhost/upx-stubtools-20221212-v4
|
||||
ENV UPX_CONTAINER_IMAGE_NAME=upx-cross-compile-20230115-v2
|
||||
ARG DEBIAN_FRONTEND=noninteractive
|
||||
|
||||
USER root
|
||||
@@ -9,7 +10,7 @@ USER root
|
||||
# Ubuntu 22.04
|
||||
RUN apt-get update && apt-get upgrade -y \
|
||||
&& apt-get install -y \
|
||||
# Linux cross compilers
|
||||
# Linux glibc cross compilers
|
||||
g++-aarch64-linux-gnu \
|
||||
g++-alpha-linux-gnu \
|
||||
g++-arm-linux-gnueabi \
|
||||
@@ -28,7 +29,7 @@ RUN apt-get update && apt-get upgrade -y \
|
||||
g++-s390x-linux-gnu \
|
||||
g++-sh4-linux-gnu \
|
||||
g++-sparc64-linux-gnu \
|
||||
# Linux cross compilers - ILP32 on 64-bit CPUs
|
||||
# Linux glibc cross compilers - ILP32 on 64-bit CPUs
|
||||
g++-x86-64-linux-gnux32 \
|
||||
# Windows cross compilers
|
||||
g++-mingw-w64-i686 \
|
||||
@@ -42,6 +43,12 @@ RUN apt-get install -y \
|
||||
# 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
|
||||
# using a rootless Podman container
|
||||
|
||||
image=upx-stubtools-20210104-v7
|
||||
image=upx-stubtools-20221212-v4
|
||||
|
||||
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
|
||||
# using a rootless Podman container
|
||||
|
||||
image=upx-stubtools-20210104-v7
|
||||
image=upx-stubtools-20221212-v4
|
||||
|
||||
flags=( -ti --read-only --rm )
|
||||
flags+=( --cap-drop=all ) # drop all capabilities
|
||||
@@ -37,24 +37,40 @@ podman run "${flags[@]}" "$image" bash -l
|
||||
# # make sure that git is clean:
|
||||
# git status .
|
||||
# # remove stub files and make sure that they got deleted:
|
||||
# make maintainer-clean
|
||||
# make maintainer-clean extra-clean
|
||||
# git status .
|
||||
# # rebuild
|
||||
# make all
|
||||
# make extra-all all
|
||||
# # make sure that the stub files did rebuild correctly:
|
||||
# git status .
|
||||
# git diff .
|
||||
|
||||
# we can also build UPX in the container:
|
||||
# cd /home/upx/src/upx
|
||||
# rm -rf ./build/release
|
||||
# make build/release
|
||||
# rm -rf ./build/extra/gcc/release
|
||||
# make build/extra/gcc/release
|
||||
# # run tests
|
||||
# ./build/release/upx --version
|
||||
# make -C build/release test
|
||||
# ./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
|
||||
# make -C doc clean all
|
||||
# git status doc
|
||||
# git diff doc
|
||||
# cd /home/upx/src/upx/doc
|
||||
# make clean all
|
||||
# git status .
|
||||
# git diff .
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
FROM docker.io/library/ubuntu:22.04
|
||||
ENV UPX_CONTAINER_IMAGE_NAME=upx-stubtools-20221212-v4
|
||||
ARG DEBIAN_FRONTEND=noninteractive
|
||||
ENV LANG=C.UTF-8
|
||||
|
||||
@@ -12,16 +13,17 @@ RUN dpkg --add-architecture i386 \
|
||||
# the following packages are not required for rebuilding the stubs, but
|
||||
# they do make the image much more convenient and also allow building
|
||||
# the full UPX binary inside the container via CMake:
|
||||
7zip bzip2 cmake elfutils file g++ htop libzstd-dev lzip lzop ninja-build \
|
||||
p7zip patch patchelf pax-utils rsync unzip vim zip zlib1g-dev zsh zstd \
|
||||
7zip bfs bzip2 cmake curl elfutils fd-find file fzf g++ gdb gojq htop hyperfine \
|
||||
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
|
||||
|
||||
# manually install compat libs from Ubuntu 16.04; REQUIRED
|
||||
RUN cd /root \
|
||||
&& aria2c --checksum=sha-256=2605f43f8047fc972855bb909f1dd7af761bbfd35ae559ad689b0d55a4236d69 \
|
||||
'http://mirror.enzu.com/ubuntu/pool/main/g/gmp/libgmp10_6.1.0+dfsg-2_amd64.deb' \
|
||||
&& aria2c --checksum=sha-256=3973a97387bbe0e8a775995c22861d8478edee2a594e8117970f635de25b2c8a \
|
||||
'http://mirror.enzu.com/ubuntu/pool/main/m/mpfr4/libmpfr4_3.1.4-1_amd64.deb' \
|
||||
&& aria2c --checksum=sha-256=de22baf3dd851a10e16fbf66a243e70149ca46e06b2939fdc79429196cefc090 \
|
||||
'http://archive.kernel.org/ubuntu-archive/ubuntu/pool/main/m/mpfr4/libmpfr4_3.1.6-1_amd64.deb' \
|
||||
&& mkdir packages \
|
||||
&& 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/ \
|
||||
@@ -29,40 +31,28 @@ RUN cd /root \
|
||||
&& ldconfig \
|
||||
&& true
|
||||
|
||||
# install upx-stubtools into /usr/local/bin/bin-upx-20210104; REQUIRED
|
||||
# install upx-stubtools into /usr/local/bin/bin-upx-20221212; REQUIRED
|
||||
RUN cd /root \
|
||||
&& aria2c --checksum=sha-256=abcd8337cc656fe68d7bbb2ffe0f1e5ddce618688aa0e18c1ebcc40072843884 \
|
||||
'https://github.com/upx/upx-stubtools/releases/download/v20210104/bin-upx-20210104.tar.xz' \
|
||||
&& aria2c --checksum=sha-256=509e06639118a79d8e79489a400e134c6d3ca36bad2c6ec29648d7c1e5b81afa \
|
||||
'https://github.com/upx/upx-stubtools/releases/download/v20221212/bin-upx-20221212.tar.xz' \
|
||||
&& cd /usr/local/bin \
|
||||
&& tar -xoaf /root/bin-upx-20210104.tar.xz \
|
||||
&& rm /root/bin-upx-20210104.tar.xz \
|
||||
&& tar -xoaf /root/bin-upx-20221212.tar.xz \
|
||||
&& rm /root/bin-upx-20221212.tar.xz \
|
||||
&& true
|
||||
|
||||
# install pre-built binary UPX versions into /usr/local/bin; not required but convenient for testing
|
||||
# install official UPX release binaries into /usr/local/bin; not required but convenient for testing
|
||||
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.92/upx-3.92-amd64_linux.tar.xz \
|
||||
&& 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 \
|
||||
&& wget -q https://github.com/upx/upx/releases/download/v4.0.0/upx-4.0.0-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 \
|
||||
&& for f in ./upx-*.tar.*; do tar -xoaf $f; done \
|
||||
&& rm ./upx-*.tar.* \
|
||||
&& d=upx-3.91-amd64_linux; ./$d/upx -d $d/upx -o /usr/local/bin/upx-3.91 \
|
||||
&& 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 \
|
||||
&& d=upx-4.0.0-amd64_linux; ./$d/upx -d $d/upx -o /usr/local/bin/upx-4.0.0 \
|
||||
&& rm -rf ./upx-*linux \
|
||||
&& 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 \
|
||||
&& rm -r ./upx-*.tar.* ./upx-*linux \
|
||||
&& true
|
||||
|
||||
# create default user upx 2000:2000
|
||||
RUN useradd upx -U --uid 2000 --shell /bin/bash -m \
|
||||
&& mkdir -p /home/upx/.local/bin /home/upx/src/upx \
|
||||
&& ln -s /usr/local/bin/bin-upx-20210104 /home/upx/.local/bin/bin-upx \
|
||||
&& mkdir -p /home/upx/.cache/zig /home/upx/.local/bin /home/upx/src/upx \
|
||||
&& ln -s /usr/local/bin/bin-upx-20221212 /home/upx/.local/bin/bin-upx \
|
||||
&& chown -R upx:upx /home/upx \
|
||||
&& true
|
||||
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
|
||||
|
||||
# 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
|
||||
|
||||
# NOTE: we use .clang-format config from upx.git/.clang-format
|
||||
|
||||
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
|
||||
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
|
||||
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
|
||||
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"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
+20
-17
@@ -36,6 +36,7 @@ $(top_srcdir)/build/release/upx: PHONY
|
||||
$(MAKE) -C $(top_srcdir) build/release
|
||||
|
||||
.PHONY: PHONY
|
||||
.NOTPARALLEL:
|
||||
|
||||
#
|
||||
# "make run-testsuite"
|
||||
@@ -56,13 +57,17 @@ endif
|
||||
|
||||
# run the UPX testsuite
|
||||
# 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 $(top_srcdir)/.github/travis_testsuite_1.sh),)
|
||||
run-testsuite: export upx_exe := $(top_srcdir)/build/release/upx
|
||||
run-testsuite: export upx_testsuite_SRCDIR := $(upx_testsuite_SRCDIR)
|
||||
run-testsuite: export upx_testsuite_BUILDDIR := ./tmp-testsuite
|
||||
run-testsuite: $(top_srcdir)/build/release/upx PHONY
|
||||
run-testsuite: run-testsuite-release
|
||||
run-testsuite-%: export upx_testsuite_SRCDIR := $(upx_testsuite_SRCDIR)
|
||||
run-testsuite-%: export upx_testsuite_BUILDDIR := ./tmp-testsuite
|
||||
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
|
||||
endif
|
||||
endif
|
||||
@@ -73,18 +78,16 @@ endif
|
||||
|
||||
# automatically format some C++ source code files
|
||||
ifeq ($(shell uname),Linux)
|
||||
CLANG_FORMAT_FILES += bele.h bele_policy.h
|
||||
CLANG_FORMAT_FILES += compress_lzma.cpp compress_ucl.cpp compress_zlib.cpp
|
||||
CLANG_FORMAT_FILES += except.cpp except.h
|
||||
CLANG_FORMAT_FILES += file.cpp file.h
|
||||
CLANG_FORMAT_FILES += linker.cpp linker.h packhead.cpp packmast.cpp packmast.h
|
||||
CLANG_FORMAT_FILES += main.cpp options.cpp options.h packer.cpp packer.h
|
||||
CLANG_FORMAT_FILES += p_tos.cpp p_tos.h
|
||||
CLANG_FORMAT_FILES += s_djgpp2.cpp s_object.cpp s_vcsa.cpp s_win32.cpp screen.h
|
||||
CLANG_FORMAT_FILES += ui.cpp ui.h work.cpp
|
||||
CLANG_FORMAT_FILES += $(wildcard util/[a-ln-z]*.[ch]* util/mem*.[ch]*)
|
||||
clang-format: PHONY
|
||||
$(top_srcdir)/misc/scripts/upx-clang-format -i $(addprefix $(top_srcdir)/src/,$(sort $(CLANG_FORMAT_FILES)))
|
||||
# Markus loves clang-format, but John hates it; find a compromise
|
||||
CLANG_FORMAT_EXCLUDE_FILES += conf.h miniacc.h version.h help.cpp
|
||||
CLANG_FORMAT_EXCLUDE_FILES += p_elf.h p_elf_enum.h p_lx_% p_mach% p_unix% p_vmli%
|
||||
CLANG_FORMAT_EXCLUDE_FILES += packer_c.cpp packer_f.cpp
|
||||
CLANG_FORMAT_EXCLUDE_FILES += compress/compress.h filter/filter_impl.cpp
|
||||
CLANG_FORMAT_FILES := $(sort $(wildcard *.[ch]* ../maint/src/*.[ch]* [cu]*/*.[ch]*))
|
||||
CLANG_FORMAT_FILES := $(filter-out $(CLANG_FORMAT_EXCLUDE_FILES),$(CLANG_FORMAT_FILES))
|
||||
clang-format: PHONY $(CLANG_FORMAT_FILES)
|
||||
@echo "running upx-clang-format"
|
||||
@$(top_srcdir)/misc/scripts/upx-clang-format -i $(CLANG_FORMAT_FILES)
|
||||
endif
|
||||
|
||||
#
|
||||
|
||||
+38
-39
@@ -2,8 +2,8 @@
|
||||
|
||||
This file is part of the UPX executable compressor.
|
||||
|
||||
Copyright (C) 1996-2022 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2022 Laszlo Molnar
|
||||
Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2023 Laszlo Molnar
|
||||
All Rights Reserved.
|
||||
|
||||
UPX and the UCL library are free software; you can redistribute them
|
||||
@@ -38,35 +38,35 @@
|
||||
// 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_memcpy_inline(&v, p, sizeof(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_memcpy_inline(&v, p, sizeof(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_memcpy_inline(&v, p, sizeof(v));
|
||||
return v;
|
||||
}
|
||||
|
||||
__acc_static_forceinline void set_ne16(void *p, unsigned vv) {
|
||||
upx_uint16_t v = (upx_uint16_t)(vv & 0xffff);
|
||||
static forceinline void set_ne16(void *p, unsigned vv) {
|
||||
upx_uint16_t v = (upx_uint16_t) (vv & 0xffff);
|
||||
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_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_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_static_forceinline unsigned bswap16(unsigned v) {
|
||||
return (unsigned) _byteswap_ulong(v << 16);
|
||||
}
|
||||
__acc_static_forceinline unsigned bswap32(unsigned v) { return (unsigned) _byteswap_ulong(v); }
|
||||
__acc_static_forceinline upx_uint64_t bswap64(upx_uint64_t v) { return _byteswap_uint64(v); }
|
||||
// unfortunately *not* constexpr with MSVC
|
||||
static forceinline unsigned bswap16(unsigned v) { return (unsigned) _byteswap_ulong(v << 16); }
|
||||
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); }
|
||||
|
||||
#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 (unsigned) __builtin_bswap64((upx_uint64_t) v << 48);
|
||||
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 __builtin_bswap32(v);
|
||||
}
|
||||
__acc_static_forceinline constexpr upx_uint64_t bswap64(upx_uint64_t v) {
|
||||
return __builtin_bswap64(v);
|
||||
}
|
||||
static forceinline constexpr upx_uint64_t bswap64(upx_uint64_t v) { return __builtin_bswap64(v); }
|
||||
|
||||
#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
|
||||
}
|
||||
|
||||
__acc_static_forceinline constexpr unsigned no_bswap32(unsigned v) { return v; }
|
||||
|
||||
__acc_static_forceinline constexpr upx_uint64_t no_bswap64(upx_uint64_t v) { return v; }
|
||||
static forceinline constexpr unsigned no_bswap32(unsigned v) { return v; }
|
||||
static forceinline constexpr upx_uint64_t no_bswap64(upx_uint64_t v) { return v; }
|
||||
|
||||
#if (ACC_ABI_BIG_ENDIAN)
|
||||
#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) {
|
||||
// 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
|
||||
set_ne32(p, (get_ne32(p) & ne32_to_le32(0xfc000000)) |
|
||||
(ne32_to_le32(v) & ne32_to_le32(0x03ffffff)));
|
||||
#endif
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
// 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);
|
||||
v &= sign_bit | (sign_bit - 1);
|
||||
v |= 0 - (v & sign_bit);
|
||||
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);
|
||||
v &= sign_bit | (sign_bit - 1);
|
||||
v |= 0 - (v & sign_bit);
|
||||
@@ -251,6 +249,7 @@ inline upx_int64_t get_le64_signed(const void *p) {
|
||||
**************************************************************************/
|
||||
|
||||
struct alignas(1) BE16 {
|
||||
typedef unsigned integral_conversion_type; // automatic conversion to unsigned
|
||||
unsigned char d[2];
|
||||
|
||||
BE16 &operator=(unsigned v) {
|
||||
@@ -300,6 +299,7 @@ struct alignas(1) BE16 {
|
||||
};
|
||||
|
||||
struct alignas(1) BE32 {
|
||||
typedef unsigned integral_conversion_type; // automatic conversion to unsigned
|
||||
unsigned char d[4];
|
||||
|
||||
BE32 &operator=(unsigned v) {
|
||||
@@ -349,6 +349,7 @@ struct alignas(1) BE32 {
|
||||
};
|
||||
|
||||
struct alignas(1) BE64 {
|
||||
typedef upx_uint64_t integral_conversion_type; // automatic conversion to upx_uint64_t
|
||||
unsigned char d[8];
|
||||
|
||||
BE64 &operator=(upx_uint64_t v) {
|
||||
@@ -398,6 +399,7 @@ struct alignas(1) BE64 {
|
||||
};
|
||||
|
||||
struct alignas(1) LE16 {
|
||||
typedef unsigned integral_conversion_type; // automatic conversion to unsigned
|
||||
unsigned char d[2];
|
||||
|
||||
LE16 &operator=(unsigned v) {
|
||||
@@ -447,6 +449,7 @@ struct alignas(1) LE16 {
|
||||
};
|
||||
|
||||
struct alignas(1) LE32 {
|
||||
typedef unsigned integral_conversion_type; // automatic conversion to unsigned
|
||||
unsigned char d[4];
|
||||
|
||||
LE32 &operator=(unsigned v) {
|
||||
@@ -496,6 +499,7 @@ struct alignas(1) LE32 {
|
||||
};
|
||||
|
||||
struct alignas(1) LE64 {
|
||||
typedef upx_uint64_t integral_conversion_type; // automatic conversion to upx_uint64_t
|
||||
unsigned char d[8];
|
||||
|
||||
LE64 &operator=(upx_uint64_t v) {
|
||||
@@ -567,7 +571,6 @@ template <class T>
|
||||
inline T *operator-(T *ptr, const BE16 &v) {
|
||||
return ptr - unsigned(v);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline T *operator+(T *ptr, const BE32 &v) {
|
||||
return ptr + unsigned(v);
|
||||
@@ -576,13 +579,6 @@ template <class T>
|
||||
inline T *operator-(T *ptr, const BE32 &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>
|
||||
inline T *operator+(T *ptr, const LE16 &v) {
|
||||
return ptr + unsigned(v);
|
||||
@@ -591,7 +587,6 @@ template <class T>
|
||||
inline T *operator-(T *ptr, const LE16 &v) {
|
||||
return ptr - unsigned(v);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline T *operator+(T *ptr, const LE32 &v) {
|
||||
return ptr + unsigned(v);
|
||||
@@ -601,11 +596,15 @@ inline T *operator-(T *ptr, const LE32 &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>
|
||||
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);
|
||||
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
|
||||
|
||||
+2
-2
@@ -2,8 +2,8 @@
|
||||
|
||||
This file is part of the UPX executable compressor.
|
||||
|
||||
Copyright (C) 1996-2022 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2022 Laszlo Molnar
|
||||
Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2023 Laszlo Molnar
|
||||
All Rights Reserved.
|
||||
|
||||
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.
|
||||
|
||||
Copyright (C) 1996-2022 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2022 Laszlo Molnar
|
||||
Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer
|
||||
All Rights Reserved.
|
||||
|
||||
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.,
|
||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
Markus F.X.J. Oberhumer Laszlo Molnar
|
||||
<markus@oberhumer.com> <ezerotven+github@gmail.com>
|
||||
Markus F.X.J. Oberhumer
|
||||
<markus@oberhumer.com>
|
||||
*/
|
||||
|
||||
#include "../conf.h"
|
||||
@@ -123,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_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()
|
||||
// assert a sane architecture and compiler
|
||||
@@ -133,62 +146,77 @@ namespace {
|
||||
template <class T>
|
||||
struct TestBELE {
|
||||
__acc_static_noinline bool test(void) {
|
||||
COMPILE_TIME_ASSERT_ALIGNED1(T)
|
||||
struct alignas(1) test1_t {
|
||||
char a;
|
||||
T b;
|
||||
};
|
||||
struct alignas(1) test2_t {
|
||||
char a;
|
||||
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(sizeof(t1) == 7 + 7 * 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))
|
||||
// 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)
|
||||
struct alignas(1) test1_t {
|
||||
char a;
|
||||
T b;
|
||||
};
|
||||
struct alignas(1) test2_t {
|
||||
char a;
|
||||
T b[3];
|
||||
};
|
||||
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(test2_t) == 1 + 3 * sizeof(T))
|
||||
COMPILE_TIME_ASSERT(sizeof(t2) == 7 + 21 * sizeof(T))
|
||||
UNUSED(t1);
|
||||
UNUSED(t2);
|
||||
}
|
||||
#if 1
|
||||
T allbits;
|
||||
allbits = 0;
|
||||
allbits += 1;
|
||||
allbits -= 2;
|
||||
T v1;
|
||||
v1 = 1;
|
||||
v1 *= 2;
|
||||
v1 -= 1;
|
||||
T v2;
|
||||
v2 = 1;
|
||||
assert((v1 == v2));
|
||||
assert(!(v1 != v2));
|
||||
assert((v1 <= v2));
|
||||
assert((v1 >= v2));
|
||||
assert(!(v1 < v2));
|
||||
assert(!(v1 > v2));
|
||||
v2 ^= allbits;
|
||||
assert(!(v1 == v2));
|
||||
assert((v1 != v2));
|
||||
assert((v1 <= v2));
|
||||
assert(!(v1 >= v2));
|
||||
assert((v1 < v2));
|
||||
assert(!(v1 > v2));
|
||||
v2 += 2;
|
||||
assert(v1 == 1);
|
||||
assert(v2 == 0);
|
||||
v1 <<= 1;
|
||||
v1 |= v2;
|
||||
v1 >>= 1;
|
||||
v2 &= v1;
|
||||
v2 /= v1;
|
||||
v2 *= v1;
|
||||
assert(v1 == 1);
|
||||
assert(v2 == 0);
|
||||
if ((v1 ^ v2) != 1)
|
||||
return false;
|
||||
// arithmetic checks
|
||||
{
|
||||
T allbits;
|
||||
allbits = 0;
|
||||
allbits += 1;
|
||||
allbits -= 2;
|
||||
T v1;
|
||||
v1 = 1;
|
||||
v1 *= 2;
|
||||
v1 -= 1;
|
||||
T v2;
|
||||
v2 = 1;
|
||||
assert((v1 == v2));
|
||||
assert(!(v1 != v2));
|
||||
assert((v1 <= v2));
|
||||
assert((v1 >= v2));
|
||||
assert(!(v1 < v2));
|
||||
assert(!(v1 > v2));
|
||||
v2 ^= allbits;
|
||||
assert(!(v1 == v2));
|
||||
assert((v1 != v2));
|
||||
assert((v1 <= v2));
|
||||
assert(!(v1 >= v2));
|
||||
assert((v1 < v2));
|
||||
assert(!(v1 > v2));
|
||||
v2 += 2;
|
||||
assert(v1 == 1);
|
||||
assert(v2 == 0);
|
||||
v1 <<= 1;
|
||||
v1 |= v2;
|
||||
v1 >>= 1;
|
||||
v2 &= v1;
|
||||
v2 /= v1;
|
||||
v2 *= v1;
|
||||
assert(v1 == 1);
|
||||
assert(v2 == 0);
|
||||
if ((v1 ^ v2) != 1)
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
@@ -325,6 +353,20 @@ void upx_compiler_sanity_check(void) {
|
||||
assert(get_le26(d) == 0x03020304);
|
||||
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
|
||||
union {
|
||||
short v_short;
|
||||
@@ -2,8 +2,7 @@
|
||||
|
||||
This file is part of the UPX executable compressor.
|
||||
|
||||
Copyright (C) 1996-2022 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2022 Laszlo Molnar
|
||||
Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer
|
||||
All Rights Reserved.
|
||||
|
||||
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.,
|
||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
Markus F.X.J. Oberhumer Laszlo Molnar
|
||||
<markus@oberhumer.com> <ezerotven+github@gmail.com>
|
||||
Markus F.X.J. Oberhumer
|
||||
<markus@oberhumer.com>
|
||||
*/
|
||||
|
||||
/*************************************************************************
|
||||
@@ -33,11 +32,19 @@
|
||||
#if !defined(UPX_DOCTEST_CONFIG_MULTITHREADING)
|
||||
#define DOCTEST_CONFIG_NO_MULTITHREADING
|
||||
#endif
|
||||
#if defined(__MSDOS__) && defined(__DJGPP__)
|
||||
#if defined(__i386__) && defined(__MSDOS__) && defined(__DJGPP__) && defined(__GNUC__)
|
||||
#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
|
||||
#define DOCTEST_CONFIG_NO_UNPREFIXED_OPTIONS
|
||||
#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>
|
||||
#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.
|
||||
|
||||
Copyright (C) 1996-2022 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2022 Laszlo Molnar
|
||||
Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer
|
||||
All Rights Reserved.
|
||||
|
||||
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.,
|
||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
Markus F.X.J. Oberhumer Laszlo Molnar
|
||||
<markus@oberhumer.com> <ezerotven+github@gmail.com>
|
||||
Markus F.X.J. Oberhumer
|
||||
<markus@oberhumer.com>
|
||||
*/
|
||||
|
||||
|
||||
#include "conf.h"
|
||||
#include "../conf.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)
|
||||
return adler;
|
||||
assert(buf != nullptr);
|
||||
@@ -47,8 +43,7 @@ unsigned upx_adler32(const void *buf, unsigned len, unsigned adler)
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
#if 0 /* UNUSED */
|
||||
#if 0 // UNUSED
|
||||
unsigned upx_crc32(const void *buf, unsigned len, unsigned crc)
|
||||
{
|
||||
if (len == 0)
|
||||
@@ -60,24 +55,20 @@ unsigned upx_crc32(const void *buf, unsigned len, unsigned crc)
|
||||
return upx_zlib_crc32(buf, len, crc);
|
||||
#endif
|
||||
}
|
||||
#endif /* UNUSED */
|
||||
|
||||
#endif // UNUSED
|
||||
|
||||
/*************************************************************************
|
||||
//
|
||||
**************************************************************************/
|
||||
|
||||
int upx_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_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 r = UPX_E_ERROR;
|
||||
upx_compress_result_t cresult_buffer;
|
||||
|
||||
assert(method > 0); assert(level > 0);
|
||||
assert(method > 0);
|
||||
assert(level > 0);
|
||||
|
||||
#if 1
|
||||
// set available bytes in dst
|
||||
@@ -94,60 +85,57 @@ int upx_compress( const upx_bytep src, unsigned src_len,
|
||||
cresult = &cresult_buffer;
|
||||
memset(cresult, 0, sizeof(*cresult));
|
||||
#if 1
|
||||
// debug
|
||||
cresult->method = method;
|
||||
cresult->level = level;
|
||||
cresult->u_len = src_len;
|
||||
cresult->c_len = 0;
|
||||
// debugging aid
|
||||
cresult->debug.method = method;
|
||||
cresult->debug.level = level;
|
||||
cresult->debug.u_len = src_len;
|
||||
cresult->debug.c_len = 0;
|
||||
#endif
|
||||
|
||||
if __acc_cte(0) {
|
||||
if (__acc_cte(false)) {
|
||||
}
|
||||
#if (WITH_LZMA)
|
||||
else if (M_IS_LZMA(method))
|
||||
r = upx_lzma_compress(src, src_len, dst, dst_len,
|
||||
cb, method, level, cconf, cresult);
|
||||
r = upx_lzma_compress(src, src_len, dst, dst_len, cb, method, level, cconf, cresult);
|
||||
#endif
|
||||
#if (WITH_NRV)
|
||||
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,
|
||||
cb, method, level, cconf, cresult);
|
||||
r = upx_nrv_compress(src, src_len, dst, dst_len, cb, method, level, cconf, cresult);
|
||||
#endif
|
||||
#if (WITH_UCL)
|
||||
else if (M_IS_NRV2B(method) || M_IS_NRV2D(method) || M_IS_NRV2E(method))
|
||||
r = upx_ucl_compress(src, src_len, dst, dst_len,
|
||||
cb, method, level, cconf, cresult);
|
||||
r = upx_ucl_compress(src, src_len, dst, dst_len, 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
|
||||
else {
|
||||
throwInternalError("unknown compression method");
|
||||
}
|
||||
|
||||
#if 1
|
||||
// debug
|
||||
cresult->c_len = *dst_len;
|
||||
// debugging aid
|
||||
cresult->debug.c_len = *dst_len;
|
||||
#endif
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
//
|
||||
**************************************************************************/
|
||||
|
||||
int upx_decompress(const upx_bytep src, unsigned src_len,
|
||||
upx_bytep dst, unsigned* dst_len,
|
||||
int method,
|
||||
const upx_compress_result_t *cresult )
|
||||
{
|
||||
int upx_decompress(const upx_bytep src, unsigned src_len, upx_bytep dst, unsigned *dst_len,
|
||||
int method, const upx_compress_result_t *cresult) {
|
||||
int r = UPX_E_ERROR;
|
||||
|
||||
assert(*dst_len > 0);
|
||||
assert(src_len < *dst_len); // must be compressed
|
||||
|
||||
if (cresult && cresult->method == 0)
|
||||
if (cresult && cresult->debug.method == 0)
|
||||
cresult = nullptr;
|
||||
|
||||
if __acc_cte(0) {
|
||||
if (__acc_cte(false)) {
|
||||
}
|
||||
#if (WITH_LZMA)
|
||||
else if (M_IS_LZMA(method))
|
||||
@@ -164,6 +152,10 @@ int upx_decompress(const upx_bytep src, unsigned src_len,
|
||||
#if (WITH_ZLIB)
|
||||
else if (M_IS_DEFLATE(method))
|
||||
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
|
||||
else {
|
||||
throwInternalError("unknown decompression method");
|
||||
@@ -172,29 +164,23 @@ int upx_decompress(const upx_bytep src, unsigned src_len,
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
//
|
||||
**************************************************************************/
|
||||
|
||||
int upx_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 upx_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 = UPX_E_ERROR;
|
||||
|
||||
if (cresult && cresult->method == 0)
|
||||
if (cresult && cresult->debug.method == 0)
|
||||
cresult = nullptr;
|
||||
|
||||
assert(*dst_len > 0);
|
||||
assert(src_len < *dst_len); // must be compressed
|
||||
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)
|
||||
else if (M_IS_LZMA(method))
|
||||
@@ -207,6 +193,10 @@ int upx_test_overlap( const upx_bytep buf,
|
||||
#if (WITH_UCL)
|
||||
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);
|
||||
#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
|
||||
else {
|
||||
throwInternalError("unknown decompression method");
|
||||
@@ -2,8 +2,7 @@
|
||||
|
||||
This file is part of the UPX executable compressor.
|
||||
|
||||
Copyright (C) 1996-2022 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2022 Laszlo Molnar
|
||||
Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer
|
||||
All Rights Reserved.
|
||||
|
||||
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.,
|
||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
Markus F.X.J. Oberhumer Laszlo Molnar
|
||||
<markus@oberhumer.com> <ezerotven+github@gmail.com>
|
||||
Markus F.X.J. Oberhumer
|
||||
<markus@oberhumer.com>
|
||||
*/
|
||||
|
||||
|
||||
#ifndef __UPX_COMPRESS_H
|
||||
#define __UPX_COMPRESS_H 1
|
||||
|
||||
#pragma once
|
||||
#ifndef UPX_COMPRESS_H__
|
||||
#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)
|
||||
int upx_lzma_init(void);
|
||||
const char *upx_lzma_version_string(void);
|
||||
@@ -126,6 +146,28 @@ unsigned upx_zlib_crc32 (const void *buf, unsigned len, unsigned crc);
|
||||
#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 */
|
||||
|
||||
/* vim:set ts=4 sw=4 et: */
|
||||
@@ -2,8 +2,7 @@
|
||||
|
||||
This file is part of the UPX executable compressor.
|
||||
|
||||
Copyright (C) 1996-2022 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2022 Laszlo Molnar
|
||||
Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer
|
||||
All Rights Reserved.
|
||||
|
||||
UPX and the UCL library are free software; you can redistribute them
|
||||
@@ -21,13 +20,13 @@
|
||||
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>
|
||||
Markus F.X.J. Oberhumer
|
||||
<markus@oberhumer.com>
|
||||
*/
|
||||
|
||||
#include "conf.h"
|
||||
#include "../conf.h"
|
||||
#include "compress.h"
|
||||
#include "util/membuffer.h"
|
||||
#include "../util/membuffer.h"
|
||||
|
||||
#if (ACC_CC_CLANG)
|
||||
#pragma clang diagnostic ignored "-Wshadow"
|
||||
@@ -216,7 +215,7 @@ error:
|
||||
#undef NULL
|
||||
#define NULL nullptr
|
||||
#include <lzma-sdk/C/Common/MyInitGuid.h>
|
||||
//#include <lzma-sdk/C/7zip/Compress/LZMA/LZMADecoder.h>
|
||||
// #include <lzma-sdk/C/7zip/Compress/LZMA/LZMADecoder.h>
|
||||
#include <lzma-sdk/C/7zip/Compress/LZMA/LZMAEncoder.h>
|
||||
|
||||
namespace MyLzma {
|
||||
@@ -298,12 +297,12 @@ STDMETHODIMP ProgressInfo::SetRatioInfo(const UInt64 *inSize, const UInt64 *outS
|
||||
|
||||
#include <lzma-sdk/C/Common/Alloc.cpp>
|
||||
#include <lzma-sdk/C/Common/CRC.cpp>
|
||||
//#include <lzma-sdk/C/7zip/Common/InBuffer.cpp>
|
||||
// #include <lzma-sdk/C/7zip/Common/InBuffer.cpp>
|
||||
#include <lzma-sdk/C/7zip/Common/OutBuffer.cpp>
|
||||
#include <lzma-sdk/C/7zip/Common/StreamUtils.cpp>
|
||||
#include <lzma-sdk/C/7zip/Compress/LZ/LZInWindow.cpp>
|
||||
//#include <lzma-sdk/C/7zip/Compress/LZ/LZOutWindow.cpp>
|
||||
//#include <lzma-sdk/C/7zip/Compress/LZMA/LZMADecoder.cpp>
|
||||
// #include <lzma-sdk/C/7zip/Compress/LZ/LZOutWindow.cpp>
|
||||
// #include <lzma-sdk/C/7zip/Compress/LZMA/LZMADecoder.cpp>
|
||||
#include <lzma-sdk/C/7zip/Compress/LZMA/LZMAEncoder.cpp>
|
||||
#include <lzma-sdk/C/7zip/Compress/RangeCoder/RangeCoderBit.cpp>
|
||||
#undef RC_NORMALIZE
|
||||
@@ -453,7 +452,7 @@ int upx_lzma_decompress(const upx_bytep src, unsigned src_len, upx_bytep dst, un
|
||||
src_len -= 2;
|
||||
|
||||
if (cresult) {
|
||||
assert(cresult->method == method);
|
||||
assert(cresult->debug.method == method);
|
||||
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_context_bits == (unsigned) s.Properties.lc);
|
||||
@@ -518,14 +517,7 @@ int upx_lzma_test_overlap(const upx_bytep buf, const upx_bytep tbuf, unsigned sr
|
||||
|
||||
int upx_lzma_init(void) { return 0; }
|
||||
|
||||
const char *upx_lzma_version_string(void) {
|
||||
#if (WITH_LZMA == 0x443)
|
||||
return "4.43";
|
||||
#else
|
||||
#error "unknown WITH_LZMA version"
|
||||
return nullptr;
|
||||
#endif
|
||||
}
|
||||
const char *upx_lzma_version_string(void) { return "4.43"; }
|
||||
|
||||
/*************************************************************************
|
||||
// doctest checks
|
||||
@@ -2,8 +2,7 @@
|
||||
|
||||
This file is part of the UPX executable compressor.
|
||||
|
||||
Copyright (C) 1996-2022 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2022 Laszlo Molnar
|
||||
Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer
|
||||
All Rights Reserved.
|
||||
|
||||
UPX and the UCL library are free software; you can redistribute them
|
||||
@@ -21,11 +20,11 @@
|
||||
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>
|
||||
Markus F.X.J. Oberhumer
|
||||
<markus@oberhumer.com>
|
||||
*/
|
||||
|
||||
#include "conf.h"
|
||||
#include "../conf.h"
|
||||
#include "compress.h"
|
||||
|
||||
/*************************************************************************
|
||||
@@ -261,7 +260,7 @@ unsigned upx_ucl_adler32(const void *buf, unsigned len, unsigned adler) {
|
||||
return ucl_adler32(adler, (const ucl_bytep) buf, len);
|
||||
}
|
||||
|
||||
#if 0 /* UNUSED */
|
||||
#if 0 // UNUSED
|
||||
unsigned upx_ucl_crc32(const void *buf, unsigned len, unsigned crc) {
|
||||
return ucl_crc32(crc, (const ucl_bytep) buf, len);
|
||||
}
|
||||
@@ -271,9 +270,9 @@ unsigned upx_ucl_crc32(const void *buf, unsigned len, unsigned crc) {
|
||||
// doctest checks
|
||||
**************************************************************************/
|
||||
|
||||
#if DEBUG && 1
|
||||
#if DEBUG && !defined(DOCTEST_CONFIG_DISABLE) && 1
|
||||
|
||||
#include "util/membuffer.h"
|
||||
#include "../util/membuffer.h"
|
||||
|
||||
static bool check_ucl(const int method, const unsigned expected_c_len) {
|
||||
const unsigned u_len = 16384;
|
||||
@@ -2,8 +2,7 @@
|
||||
|
||||
This file is part of the UPX executable compressor.
|
||||
|
||||
Copyright (C) 1996-2022 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2022 Laszlo Molnar
|
||||
Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer
|
||||
All Rights Reserved.
|
||||
|
||||
UPX and the UCL library are free software; you can redistribute them
|
||||
@@ -21,13 +20,13 @@
|
||||
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>
|
||||
Markus F.X.J. Oberhumer
|
||||
<markus@oberhumer.com>
|
||||
*/
|
||||
|
||||
#include "conf.h"
|
||||
#include "../conf.h"
|
||||
#include "compress.h"
|
||||
#include "util/membuffer.h"
|
||||
#include "../util/membuffer.h"
|
||||
#include <zlib/zlib.h>
|
||||
#include <zlib/deflate.h>
|
||||
|
||||
@@ -224,13 +223,13 @@ int upx_zlib_init(void) {
|
||||
|
||||
const char *upx_zlib_version_string(void) { return zlibVersion(); }
|
||||
|
||||
#if 0 /* UNUSED */
|
||||
#if 0 // UNUSED
|
||||
unsigned upx_zlib_adler32(const void *buf, unsigned len, unsigned adler) {
|
||||
return adler32(adler, (const Bytef *) buf, len);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if 0 /* UNUSED */
|
||||
#if 0 // UNUSED
|
||||
unsigned upx_zlib_crc32(const void *buf, unsigned len, unsigned crc) {
|
||||
return crc32(crc, (const Bytef *) buf, len);
|
||||
}
|
||||
@@ -240,9 +239,7 @@ unsigned upx_zlib_crc32(const void *buf, unsigned len, unsigned crc) {
|
||||
// doctest checks
|
||||
**************************************************************************/
|
||||
|
||||
#if DEBUG && 1
|
||||
|
||||
#include "util/membuffer.h"
|
||||
#if DEBUG && !defined(DOCTEST_CONFIG_DISABLE) && 1
|
||||
|
||||
static bool check_zlib(const int method, const int level, const unsigned expected_c_len) {
|
||||
const unsigned u_len = 16384;
|
||||
@@ -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: */
|
||||
+202
-140
@@ -2,8 +2,8 @@
|
||||
|
||||
This file is part of the UPX executable compressor.
|
||||
|
||||
Copyright (C) 1996-2022 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2022 Laszlo Molnar
|
||||
Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2023 Laszlo Molnar
|
||||
All Rights Reserved.
|
||||
|
||||
UPX and the UCL library are free software; you can redistribute them
|
||||
@@ -29,12 +29,8 @@
|
||||
#ifndef UPX_CONF_H__
|
||||
#define UPX_CONF_H__ 1
|
||||
|
||||
#if defined(__cplusplus)
|
||||
# if (__cplusplus >= 201402L)
|
||||
# elif defined(_MSC_VER) && defined(_MSVC_LANG) && (_MSVC_LANG+0 >= 201402L)
|
||||
# else
|
||||
# error "C++ 14 is required"
|
||||
# endif
|
||||
#if !(__cplusplus+0 >= 201703L)
|
||||
# error "C++ 17 is required"
|
||||
#endif
|
||||
|
||||
#include "version.h"
|
||||
@@ -48,11 +44,9 @@
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#undef NDEBUG
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
// ACC
|
||||
// ACC and system includes
|
||||
**************************************************************************/
|
||||
|
||||
#ifndef ACC_CFG_USE_NEW_STYLE_CASTS
|
||||
@@ -89,10 +83,10 @@ ACC_COMPILE_TIME_ASSERT_HEADER((char)(-1) == 255) // -funsigned-char
|
||||
// don't enable before gcc-10 because of gcc bug #78010
|
||||
# pragma GCC diagnostic error "-Wsuggest-override"
|
||||
#endif
|
||||
// Some non-GLIBC toolchains do not use 'nullptr' everywhere when C++:
|
||||
// openwrt-sdk-x86-64_gcc-11.2.0_musl.Linux-x86_64/staging_dir/
|
||||
// toolchain-x86_64_gcc-11.2.0_musl/include/fortify/stdlib.h:
|
||||
// 51:32: error: zero as null pointer constant
|
||||
// Some non-GLIBC toolchains do not use 'nullptr' everywhere when C++:
|
||||
// openwrt-sdk-x86-64_gcc-11.2.0_musl.Linux-x86_64/staging_dir/
|
||||
// toolchain-x86_64_gcc-11.2.0_musl/include/fortify/stdlib.h:
|
||||
// 51:32: error: zero as null pointer constant
|
||||
#if (ACC_CC_CLANG >= 0x050000)
|
||||
# pragma clang diagnostic error "-Wzero-as-null-pointer-constant"
|
||||
#elif (ACC_CC_GNUC >= 0x040700) && defined(__GLIBC__)
|
||||
@@ -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_CXX_H 1
|
||||
#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_uint8_t upx_uint8_t;
|
||||
typedef acc_int16_t upx_int16_t;
|
||||
@@ -132,59 +177,6 @@ typedef acc_uintptr_t upx_uintptr_t;
|
||||
typedef unsigned char 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
|
||||
// see C 11 standard, Annex K
|
||||
typedef size_t upx_rsize_t;
|
||||
@@ -202,11 +194,47 @@ typedef upx_int64_t upx_off_t;
|
||||
#define off_t upx_off_t
|
||||
#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
|
||||
**************************************************************************/
|
||||
|
||||
// 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
|
||||
# define STDIN_FILENO (fileno(stdin))
|
||||
#endif
|
||||
@@ -264,12 +292,14 @@ typedef upx_int64_t upx_off_t;
|
||||
#endif
|
||||
|
||||
// avoid warnings about shadowing global functions
|
||||
#undef _base
|
||||
#undef basename
|
||||
#undef index
|
||||
#undef outp
|
||||
#define basename upx_basename
|
||||
#define index upx_index
|
||||
#define outp upx_outp
|
||||
#define _base upx_renamed__base
|
||||
#define basename upx_renamed_basename
|
||||
#define index upx_renamed_index
|
||||
#define outp upx_renamed_outp
|
||||
|
||||
#undef PAGE_MASK
|
||||
#undef PAGE_SIZE
|
||||
@@ -283,17 +313,30 @@ typedef upx_int64_t upx_off_t;
|
||||
# define O_BINARY 0
|
||||
#endif
|
||||
|
||||
#ifndef OPTIONS_VAR
|
||||
# define OPTIONS_VAR "UPX"
|
||||
#endif
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
//
|
||||
// util
|
||||
**************************************************************************/
|
||||
|
||||
#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__)
|
||||
# define attribute_format(a,b) __attribute__((__format__(__gnu_printf__,a,b)))
|
||||
#elif (ACC_CC_CLANG || ACC_CC_GNUC)
|
||||
@@ -321,13 +364,28 @@ inline void NO_fprintf(FILE *, const char *, ...) {}
|
||||
# define upx_memcpy_inline memcpy
|
||||
#endif
|
||||
|
||||
#define UNUSED(var) ACC_UNUSED(var)
|
||||
#define COMPILE_TIME_ASSERT(e) ACC_COMPILE_TIME_ASSERT(e)
|
||||
#if __has_builtin(__builtin_return_address)
|
||||
# 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
|
||||
#define __packed_struct(s) struct alignas(1) s {
|
||||
#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) { \
|
||||
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; }; \
|
||||
@@ -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>
|
||||
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
|
||||
// gets destructed when leaving scope or on exceptions.
|
||||
@@ -371,8 +438,10 @@ protected:
|
||||
inline noncopyable() {}
|
||||
inline ~noncopyable() {}
|
||||
private:
|
||||
noncopyable(const noncopyable &); // undefined
|
||||
const noncopyable& operator=(const noncopyable &); // undefined
|
||||
noncopyable(const noncopyable &) DELETED_FUNCTION; // copy constuctor
|
||||
noncopyable& operator=(const noncopyable &) DELETED_FUNCTION; // copy assignment
|
||||
noncopyable(noncopyable &&) DELETED_FUNCTION; // move constructor
|
||||
noncopyable& operator=(noncopyable &&) DELETED_FUNCTION; // move assignment
|
||||
};
|
||||
|
||||
|
||||
@@ -443,14 +512,14 @@ constexpr bool string_ge(const char *a, const char *b) {
|
||||
#define UPX_F_DOS_EXE 3
|
||||
#define UPX_F_DJGPP2_COFF 4
|
||||
#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_TMT_ADAM 8
|
||||
#define UPX_F_WIN32_PE 9
|
||||
#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_SEP_i386 13 // NOT IMPLEMENTED
|
||||
//#define UPX_F_LINUX_SEP_i386 13 // NOT IMPLEMENTED
|
||||
#define UPX_F_LINUX_SH_i386 14
|
||||
#define UPX_F_VMLINUZ_i386 15
|
||||
#define UPX_F_BVMLINUZ_i386 16
|
||||
@@ -488,7 +557,7 @@ constexpr bool string_ge(const char *a, const char *b) {
|
||||
#define UPX_F_LINUX_ELF64_ARM 42
|
||||
|
||||
#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_LINUX_ELFPPC32 132
|
||||
#define UPX_F_LINUX_ELF32_ARMEB 133
|
||||
@@ -517,7 +586,8 @@ constexpr bool string_ge(const char *a, const char *b) {
|
||||
//#define M_CL1B_8 12
|
||||
//#define M_CL1B_LE16 13
|
||||
#define M_LZMA 14
|
||||
#define M_DEFLATE 15 /* zlib */
|
||||
#define M_DEFLATE 15 // zlib
|
||||
#define M_ZSTD 16
|
||||
// compression methods internal usage
|
||||
#define M_ALL (-1)
|
||||
#define M_END (-2)
|
||||
@@ -531,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_LZMA(x) (((x) & 255) == M_LZMA)
|
||||
#define M_IS_DEFLATE(x) ((x) == M_DEFLATE)
|
||||
#define M_IS_ZSTD(x) ((x) == M_ZSTD)
|
||||
|
||||
|
||||
// filters
|
||||
@@ -541,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;
|
||||
typedef upx_callback_t *upx_callback_p;
|
||||
typedef void (__acc_cdecl *upx_progress_func_t)
|
||||
@@ -580,25 +662,26 @@ struct OptVar
|
||||
assertValue(v);
|
||||
}
|
||||
|
||||
OptVar() : v(default_value), is_set(0) { }
|
||||
OptVar() : v(default_value), is_set(false) { }
|
||||
OptVar& operator= (const T &other) {
|
||||
v = other; is_set = 1;
|
||||
assertValue();
|
||||
assertValue(other);
|
||||
v = other;
|
||||
is_set = true;
|
||||
return *this;
|
||||
}
|
||||
|
||||
void reset() { v = default_value; is_set = 0; }
|
||||
void reset() { v = default_value; is_set = false; }
|
||||
operator T () const { return v; }
|
||||
|
||||
T v;
|
||||
unsigned is_set;
|
||||
bool is_set;
|
||||
};
|
||||
|
||||
|
||||
// optional assignments
|
||||
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) {
|
||||
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>
|
||||
inline void oassign(T &v, const OptVar<T,a,b,c> &other) {
|
||||
@@ -627,13 +710,11 @@ struct lzma_compress_config_t
|
||||
void reset();
|
||||
};
|
||||
|
||||
|
||||
struct ucl_compress_config_t : public REAL_ucl_compress_config_t
|
||||
{
|
||||
void reset() { memset(this, 0xff, sizeof(*this)); }
|
||||
};
|
||||
|
||||
|
||||
struct zlib_compress_config_t
|
||||
{
|
||||
typedef OptVar<unsigned, 8u, 1u, 9u> mem_level_t; // ml
|
||||
@@ -647,13 +728,20 @@ struct zlib_compress_config_t
|
||||
void reset();
|
||||
};
|
||||
|
||||
struct zstd_compress_config_t
|
||||
{
|
||||
unsigned dummy;
|
||||
|
||||
void reset();
|
||||
};
|
||||
|
||||
struct upx_compress_config_t
|
||||
{
|
||||
lzma_compress_config_t conf_lzma;
|
||||
ucl_compress_config_t conf_ucl;
|
||||
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)
|
||||
@@ -677,7 +765,6 @@ struct lzma_compress_result_t
|
||||
void reset() { memset(this, 0, sizeof(*this)); }
|
||||
};
|
||||
|
||||
|
||||
struct ucl_compress_result_t
|
||||
{
|
||||
ucl_uint result[16];
|
||||
@@ -685,7 +772,6 @@ struct ucl_compress_result_t
|
||||
void reset() { memset(this, 0, sizeof(*this)); }
|
||||
};
|
||||
|
||||
|
||||
struct zlib_compress_result_t
|
||||
{
|
||||
unsigned dummy;
|
||||
@@ -693,20 +779,29 @@ struct zlib_compress_result_t
|
||||
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
|
||||
{
|
||||
// debug
|
||||
int method, level;
|
||||
unsigned u_len, c_len;
|
||||
// debugging aid
|
||||
struct {
|
||||
int method, level;
|
||||
unsigned u_len, c_len;
|
||||
} debug;
|
||||
|
||||
lzma_compress_result_t result_lzma;
|
||||
ucl_compress_result_t result_ucl;
|
||||
zlib_compress_result_t result_zlib;
|
||||
zstd_compress_result_t result_zstd;
|
||||
|
||||
void reset() {
|
||||
memset(this, 0, sizeof(*this));
|
||||
result_lzma.reset(); result_ucl.reset(); result_zlib.reset();
|
||||
memset(&this->debug, 0, sizeof(this->debug));
|
||||
result_lzma.reset(); result_ucl.reset(); result_zlib.reset(); result_zstd.reset();
|
||||
}
|
||||
};
|
||||
|
||||
@@ -716,16 +811,10 @@ struct upx_compress_result_t
|
||||
**************************************************************************/
|
||||
|
||||
#include "util/snprintf.h" // must get included first!
|
||||
|
||||
#include <exception>
|
||||
#include <new>
|
||||
#include <type_traits>
|
||||
#include <typeinfo>
|
||||
|
||||
#include "options.h"
|
||||
#include "except.h"
|
||||
#include "bele.h"
|
||||
#include "console.h"
|
||||
#include "console/console.h"
|
||||
#include "util/util.h"
|
||||
|
||||
// classes
|
||||
@@ -737,11 +826,9 @@ class MemBuffer;
|
||||
void *membuffer_get_void_ptr(MemBuffer &mb);
|
||||
unsigned membuffer_get_size(MemBuffer &mb);
|
||||
|
||||
// xspan
|
||||
#include "util/xspan.h"
|
||||
|
||||
//#define DOCTEST_CONFIG_DISABLE 1
|
||||
#include <doctest/doctest/parts/doctest_fwd.h>
|
||||
|
||||
// util/dt_check.cpp
|
||||
void upx_compiler_sanity_check();
|
||||
int upx_doctest_check();
|
||||
@@ -780,9 +867,9 @@ void show_license();
|
||||
void show_usage();
|
||||
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_crc32(const void *buf, unsigned len, unsigned crc=0);
|
||||
unsigned upx_crc32 (const void *buf, unsigned len, unsigned crc=0);
|
||||
|
||||
int upx_compress ( const upx_bytep src, unsigned src_len,
|
||||
upx_bytep dst, unsigned* dst_len,
|
||||
@@ -801,31 +888,6 @@ int upx_test_overlap ( const upx_bytep buf,
|
||||
int method,
|
||||
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;
|
||||
}
|
||||
|
||||
// default: for any regular pointer, raw_index_bytes() is just "pointer + index"
|
||||
// NOTE: index == number of elements, *NOT* size in bytes!
|
||||
template <class T>
|
||||
inline T *raw_index_bytes(T *ptr, size_t index, size_t size_in_bytes) {
|
||||
typedef T element_type;
|
||||
return raw_bytes(ptr, mem_size(sizeof(element_type), index, size_in_bytes)) + index;
|
||||
}
|
||||
|
||||
#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)
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
|
||||
This file is part of the UPX executable compressor.
|
||||
|
||||
Copyright (C) 1996-2022 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2022 Laszlo Molnar
|
||||
Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2023 Laszlo Molnar
|
||||
All Rights Reserved.
|
||||
|
||||
UPX and the UCL library are free software; you can redistribute them
|
||||
@@ -25,8 +25,7 @@
|
||||
<markus@oberhumer.com> <ezerotven+github@gmail.com>
|
||||
*/
|
||||
|
||||
|
||||
#include "conf.h"
|
||||
#include "../conf.h"
|
||||
|
||||
#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(o);
|
||||
UNUSED(now);
|
||||
return CON_FILE;
|
||||
}
|
||||
|
||||
|
||||
static int set_fg(FILE *f, int fg)
|
||||
{
|
||||
static int set_fg(FILE *f, int fg) {
|
||||
UNUSED(f);
|
||||
UNUSED(fg);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
static void print0(FILE *f, const char *s)
|
||||
{
|
||||
static void print0(FILE *f, const char *s) {
|
||||
#if 1
|
||||
fputs(s,f);
|
||||
fputs(s, f);
|
||||
#else
|
||||
/* filter out all ANSI sequences */
|
||||
int c;
|
||||
while ((c = *s++) != 0)
|
||||
{
|
||||
if (c == '\033' && *s == ']')
|
||||
{
|
||||
while ((c = *s++) != 0) {
|
||||
if (c == '\033' && *s == ']') {
|
||||
while (*s && *s != 'm')
|
||||
s++;
|
||||
}
|
||||
else
|
||||
fputc(c,f);
|
||||
} else
|
||||
fputc(c, f);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
static bool intro(FILE *f)
|
||||
{
|
||||
static bool intro(FILE *f) {
|
||||
UNUSED(f);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
console_t console_file =
|
||||
{
|
||||
init,
|
||||
set_fg,
|
||||
print0,
|
||||
intro
|
||||
};
|
||||
console_t console_file = {init, set_fg, print0, intro};
|
||||
|
||||
#endif /* USE_CONSOLE */
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
|
||||
This file is part of the UPX executable compressor.
|
||||
|
||||
Copyright (C) 1996-2022 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2022 Laszlo Molnar
|
||||
Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2023 Laszlo Molnar
|
||||
All Rights Reserved.
|
||||
|
||||
UPX and the UCL library are free software; you can redistribute them
|
||||
@@ -25,8 +25,7 @@
|
||||
<markus@oberhumer.com> <ezerotven+github@gmail.com>
|
||||
*/
|
||||
|
||||
|
||||
#include "conf.h"
|
||||
#include "../conf.h"
|
||||
|
||||
FILE *con_term = nullptr;
|
||||
|
||||
@@ -36,19 +35,17 @@ FILE *con_term = nullptr;
|
||||
//
|
||||
**************************************************************************/
|
||||
|
||||
static console_t * const me = &console_init;
|
||||
console_t * con = &console_init;
|
||||
static console_t *const me = &console_init;
|
||||
console_t *con = &console_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;
|
||||
|
||||
assert(c);
|
||||
assert(c->init);
|
||||
k = c->init(f,opt->console,con_mode);
|
||||
k = c->init(f, opt->console, con_mode);
|
||||
if (k == CON_INIT)
|
||||
return;
|
||||
#if 0
|
||||
@@ -56,8 +53,7 @@ static void try_init(console_t *c, FILE *f)
|
||||
if (k != opt->console)
|
||||
return;
|
||||
#endif
|
||||
if (k > con_mode)
|
||||
{
|
||||
if (k > con_mode) {
|
||||
con_mode = k;
|
||||
con = c;
|
||||
con->init = nullptr;
|
||||
@@ -70,41 +66,37 @@ 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);
|
||||
|
||||
try_init(&console_none,f);
|
||||
try_init(&console_none, f);
|
||||
assert(con != me);
|
||||
assert(con == &console_none);
|
||||
if (opt->console == CON_NONE || opt->to_stdout)
|
||||
return con_mode;
|
||||
try_init(&console_file,f);
|
||||
try_init(&console_file, f);
|
||||
if (!acc_isatty(STDIN_FILENO) || !acc_isatty(STDOUT_FILENO) || !acc_isatty(STDERR_FILENO))
|
||||
return con_mode;
|
||||
|
||||
#if (USE_ANSI)
|
||||
try_init(&console_ansi_mono,f);
|
||||
try_init(&console_ansi_color,f);
|
||||
try_init(&console_ansi_mono, f);
|
||||
try_init(&console_ansi_color, f);
|
||||
#endif
|
||||
#if (USE_SCREEN)
|
||||
try_init(&console_screen,f);
|
||||
try_init(&console_screen, f);
|
||||
#endif
|
||||
#if (USE_AALIB)
|
||||
try_init(&console_aalib,f);
|
||||
try_init(&console_aalib, f);
|
||||
#endif
|
||||
|
||||
return con_mode;
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
//
|
||||
**************************************************************************/
|
||||
|
||||
static int init(FILE *f, int o, int now)
|
||||
{
|
||||
static int init(FILE *f, int o, int now) {
|
||||
if (con != me)
|
||||
return con_mode;
|
||||
assert(o == -1);
|
||||
@@ -114,47 +106,34 @@ static int init(FILE *f, int o, int now)
|
||||
return do_init(f);
|
||||
}
|
||||
|
||||
|
||||
static int set_fg(FILE *f, int fg)
|
||||
{
|
||||
static int set_fg(FILE *f, int fg) {
|
||||
if (con == me)
|
||||
init(f,-1,-1);
|
||||
init(f, -1, -1);
|
||||
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)
|
||||
init(f,-1,-1);
|
||||
init(f, -1, -1);
|
||||
assert(con != me);
|
||||
return con->intro(f);
|
||||
}
|
||||
|
||||
console_t console_init = {init, set_fg, nullptr, intro};
|
||||
|
||||
console_t console_init =
|
||||
{
|
||||
init,
|
||||
set_fg,
|
||||
nullptr,
|
||||
intro
|
||||
};
|
||||
|
||||
|
||||
void con_fprintf(FILE *f, const char *format, ...)
|
||||
{
|
||||
void con_fprintf(FILE *f, const char *format, ...) {
|
||||
va_list args;
|
||||
char buf[80*25];
|
||||
char buf[80 * 25];
|
||||
|
||||
va_start(args, format);
|
||||
upx_safe_vsnprintf(buf, sizeof(buf), format,args);
|
||||
upx_safe_vsnprintf(buf, sizeof(buf), format, args);
|
||||
va_end(args);
|
||||
|
||||
if (con == me)
|
||||
init(f,-1,-1);
|
||||
init(f, -1, -1);
|
||||
assert(con != me);
|
||||
con->print0(f,buf);
|
||||
con->print0(f, buf);
|
||||
}
|
||||
|
||||
#endif /* USE_CONSOLE */
|
||||
@@ -2,8 +2,8 @@
|
||||
|
||||
This file is part of the UPX executable compressor.
|
||||
|
||||
Copyright (C) 1996-2022 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2022 Laszlo Molnar
|
||||
Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2023 Laszlo Molnar
|
||||
All Rights Reserved.
|
||||
|
||||
UPX and the UCL library are free software; you can redistribute them
|
||||
@@ -25,8 +25,7 @@
|
||||
<markus@oberhumer.com> <ezerotven+github@gmail.com>
|
||||
*/
|
||||
|
||||
|
||||
#include "conf.h"
|
||||
#include "../conf.h"
|
||||
|
||||
#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(o);
|
||||
UNUSED(now);
|
||||
return CON_NONE;
|
||||
}
|
||||
|
||||
|
||||
static int set_fg(FILE *f, int fg)
|
||||
{
|
||||
static int set_fg(FILE *f, int fg) {
|
||||
UNUSED(f);
|
||||
UNUSED(fg);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
static void print0(FILE *f, const char *s)
|
||||
{
|
||||
static void print0(FILE *f, const char *s) {
|
||||
UNUSED(f);
|
||||
UNUSED(s);
|
||||
}
|
||||
|
||||
|
||||
static bool intro(FILE *f)
|
||||
{
|
||||
static bool intro(FILE *f) {
|
||||
UNUSED(f);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
console_t console_none =
|
||||
{
|
||||
init,
|
||||
set_fg,
|
||||
print0,
|
||||
intro
|
||||
};
|
||||
console_t console_none = {init, set_fg, print0, intro};
|
||||
|
||||
#endif /* USE_CONSOLE */
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
|
||||
This file is part of the UPX executable compressor.
|
||||
|
||||
Copyright (C) 1996-2022 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2022 Laszlo Molnar
|
||||
Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2023 Laszlo Molnar
|
||||
All Rights Reserved.
|
||||
|
||||
UPX and the UCL library are free software; you can redistribute them
|
||||
@@ -25,8 +25,7 @@
|
||||
<markus@oberhumer.com> <ezerotven+github@gmail.com>
|
||||
*/
|
||||
|
||||
|
||||
#include "conf.h"
|
||||
#include "../conf.h"
|
||||
|
||||
#if (USE_SCREEN)
|
||||
|
||||
@@ -35,16 +34,14 @@
|
||||
#define mask_fg 0x0f
|
||||
#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;
|
||||
|
||||
if (s->init(s,fd) != 0)
|
||||
if (s->init(s, fd) != 0)
|
||||
return -1;
|
||||
|
||||
if (s->getCols(s) < 80 || s->getCols(s) > 256)
|
||||
@@ -59,39 +56,32 @@ static int do_init(screen_t *s, int fd)
|
||||
if (fg == (bg >> 4))
|
||||
return -1;
|
||||
if (bg != BG_BLACK)
|
||||
if (!s->isMono(s))
|
||||
{
|
||||
/* return 0; */ /* we could emulate ANSI mono */
|
||||
if (!s->isMono(s)) {
|
||||
/* return 0; */ /* we could emulate ANSI mono */
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static screen_t *do_construct(screen_t *s, int fd)
|
||||
{
|
||||
static screen_t *do_construct(screen_t *s, int fd) {
|
||||
if (!s)
|
||||
return nullptr;
|
||||
if (do_init(s,fd) != 0)
|
||||
{
|
||||
if (do_init(s, fd) != 0) {
|
||||
s->destroy(s);
|
||||
return nullptr;
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
//
|
||||
**************************************************************************/
|
||||
|
||||
static screen_t *screen = nullptr;
|
||||
|
||||
static void __acc_cdecl_atexit do_destroy(void)
|
||||
{
|
||||
if (screen)
|
||||
{
|
||||
static void __acc_cdecl_atexit do_destroy(void) {
|
||||
if (screen) {
|
||||
if (screen->atExit)
|
||||
screen->atExit();
|
||||
screen->destroy(screen);
|
||||
@@ -99,16 +89,13 @@ static void __acc_cdecl_atexit do_destroy(void)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static int mode = -1;
|
||||
static int init_fg = -1;
|
||||
static int init_bg = -1;
|
||||
static int cur_fg = -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 n;
|
||||
|
||||
@@ -117,30 +104,30 @@ static int init(FILE *f, int o, int now)
|
||||
|
||||
if (o == CON_SCREEN)
|
||||
n = CON_SCREEN;
|
||||
else if (o == CON_INIT) /* use by default */
|
||||
else if (o == CON_INIT) /* use by default */
|
||||
n = CON_SCREEN;
|
||||
else if (o == CON_ANSI_COLOR) /* can emulate ANSI color */
|
||||
else if (o == CON_ANSI_COLOR) /* can emulate ANSI color */
|
||||
n = CON_ANSI_COLOR;
|
||||
else if (o == CON_ANSI_MONO) /* can emulate ANSI mono */
|
||||
else if (o == CON_ANSI_MONO) /* can emulate ANSI mono */
|
||||
n = CON_ANSI_MONO;
|
||||
else
|
||||
return CON_INIT;
|
||||
|
||||
#if (ACC_OS_DOS32) && defined(__DJGPP__)
|
||||
if (!screen)
|
||||
screen = do_construct(screen_djgpp2_construct(),fd);
|
||||
screen = do_construct(screen_djgpp2_construct(), fd);
|
||||
#endif
|
||||
#if (USE_SCREEN_WIN32)
|
||||
if (!screen)
|
||||
screen = do_construct(screen_win32_construct(),fd);
|
||||
screen = do_construct(screen_win32_construct(), fd);
|
||||
#endif
|
||||
#if (USE_SCREEN_VCSA)
|
||||
if (!screen)
|
||||
screen = do_construct(screen_vcsa_construct(),fd);
|
||||
screen = do_construct(screen_vcsa_construct(), fd);
|
||||
#endif
|
||||
#if (USE_SCREEN_CURSES)
|
||||
if (!screen && o == CON_SCREEN)
|
||||
screen = do_construct(screen_curses_construct(),fd);
|
||||
screen = do_construct(screen_curses_construct(), fd);
|
||||
#endif
|
||||
if (!screen)
|
||||
return CON_INIT;
|
||||
@@ -155,19 +142,16 @@ static int init(FILE *f, int o, int now)
|
||||
return n;
|
||||
}
|
||||
|
||||
|
||||
static int set_fg(FILE *f, int fg)
|
||||
{
|
||||
static int set_fg(FILE *f, int fg) {
|
||||
const int last_fg = cur_fg;
|
||||
int f1 = fg & mask_fg;
|
||||
int f2 = init_fg & mask_fg;
|
||||
|
||||
UNUSED(f);
|
||||
cur_fg = fg;
|
||||
if (screen->isMono(screen))
|
||||
{
|
||||
if (screen->isMono(screen)) {
|
||||
const int b = (init_bg & mask_bg) >> 4;
|
||||
if (fg == -1) /* restore startup fg */
|
||||
if (fg == -1) /* restore startup fg */
|
||||
f1 = f2;
|
||||
else if (b == 0)
|
||||
f1 = (f2 <= 8) ? 15 : 8;
|
||||
@@ -175,19 +159,15 @@ static int set_fg(FILE *f, int fg)
|
||||
f1 = (f2 == 0) ? 15 : 0;
|
||||
else
|
||||
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;
|
||||
}
|
||||
|
||||
screen->setFg(screen,f1 & mask_fg);
|
||||
screen->setFg(screen, f1 & mask_fg);
|
||||
return last_fg;
|
||||
}
|
||||
|
||||
|
||||
static void print0(FILE *f, const char *ss)
|
||||
{
|
||||
static void print0(FILE *f, const char *ss) {
|
||||
int cx, cy;
|
||||
int old_cx = 0, old_cy = 0;
|
||||
const int sx = screen->getCols(screen);
|
||||
@@ -199,57 +179,47 @@ static void print0(FILE *f, const char *ss)
|
||||
// scrollUp() under Win32 is *extremely* slow.
|
||||
UNUSED(f);
|
||||
|
||||
screen->getCursor(screen,&old_cx,&old_cy);
|
||||
cx = old_cx; cy = old_cy;
|
||||
screen->getCursor(screen, &old_cx, &old_cy);
|
||||
cx = old_cx;
|
||||
cy = old_cy;
|
||||
|
||||
for (pass = 0; pass < 2; pass++)
|
||||
{
|
||||
for (pass = 0; pass < 2; pass++) {
|
||||
const char *s = ss;
|
||||
// char buffer for pass 2
|
||||
char p[256+1];
|
||||
char p[256 + 1];
|
||||
int pi = 0, px = 0, py = 0;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
for (;;) {
|
||||
// walk over whitespace
|
||||
for (;;)
|
||||
{
|
||||
if (*s == '\n')
|
||||
{
|
||||
for (;;) {
|
||||
if (*s == '\n') {
|
||||
cx = 0;
|
||||
cy++;
|
||||
}
|
||||
else if (*s == '\r')
|
||||
{
|
||||
} else if (*s == '\r') {
|
||||
cx = 0;
|
||||
if (pass > 0 && cy < sy)
|
||||
screen->clearLine(screen,cy);
|
||||
}
|
||||
else
|
||||
screen->clearLine(screen, cy);
|
||||
} else
|
||||
break;
|
||||
s++;
|
||||
}
|
||||
// adjust cursor
|
||||
if (cx >= sx)
|
||||
{
|
||||
if (cx >= sx) {
|
||||
cx = 0;
|
||||
cy++;
|
||||
}
|
||||
if (pass > 0)
|
||||
{
|
||||
if (pass > 0) {
|
||||
// check if we should print something
|
||||
if (pi > 0 && (*s == 0 || py != cy))
|
||||
{
|
||||
if (pi > 0 && (*s == 0 || py != cy)) {
|
||||
p[pi] = 0;
|
||||
screen->putString(screen,p,px,py);
|
||||
screen->putString(screen, p, px, py);
|
||||
pi = 0;
|
||||
}
|
||||
// check if we should scroll even more (this can happen
|
||||
// if the string is longer than sy lines)
|
||||
if (cy >= sy)
|
||||
{
|
||||
if (cy >= sy) {
|
||||
int scroll_y = cy - sy + 1;
|
||||
screen->scrollUp(screen,scroll_y);
|
||||
screen->scrollUp(screen, scroll_y);
|
||||
cy -= scroll_y;
|
||||
if (cy < 0)
|
||||
cy = 0;
|
||||
@@ -258,11 +228,9 @@ static void print0(FILE *f, const char *ss)
|
||||
// done ?
|
||||
if (*s == 0)
|
||||
break;
|
||||
if (pass > 0)
|
||||
{
|
||||
if (pass > 0) {
|
||||
// store current char
|
||||
if (pi == 0)
|
||||
{
|
||||
if (pi == 0) {
|
||||
px = cx;
|
||||
py = cy;
|
||||
}
|
||||
@@ -273,47 +241,34 @@ static void print0(FILE *f, const char *ss)
|
||||
s++;
|
||||
}
|
||||
|
||||
if (pass == 0)
|
||||
{
|
||||
if (pass == 0) {
|
||||
// end of pass 1 - scroll up, restore cursor
|
||||
if (cy >= sy)
|
||||
{
|
||||
if (cy >= sy) {
|
||||
int scroll_y = cy - sy + 1;
|
||||
screen->scrollUp(screen,scroll_y);
|
||||
screen->scrollUp(screen, scroll_y);
|
||||
cy = old_cy - scroll_y;
|
||||
if (cy < 0)
|
||||
cy = 0;
|
||||
}
|
||||
else
|
||||
} else
|
||||
cy = old_cy;
|
||||
cx = old_cx;
|
||||
}
|
||||
}
|
||||
|
||||
screen->setCursor(screen,cx,cy);
|
||||
screen->setCursor(screen, cx, cy);
|
||||
screen->refresh(screen);
|
||||
}
|
||||
|
||||
|
||||
static bool intro(FILE *f)
|
||||
{
|
||||
static bool intro(FILE *f) {
|
||||
UNUSED(f);
|
||||
#if (USE_FRAMES)
|
||||
if (screen->intro)
|
||||
return screen->intro(screen,screen_show_frames);
|
||||
return screen->intro(screen, screen_show_frames);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
console_t console_screen =
|
||||
{
|
||||
init,
|
||||
set_fg,
|
||||
print0,
|
||||
intro
|
||||
};
|
||||
|
||||
console_t console_screen = {init, set_fg, print0, intro};
|
||||
|
||||
#endif /* USE_SCREEN */
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
|
||||
This file is part of the UPX executable compressor.
|
||||
|
||||
Copyright (C) 1996-2022 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2022 Laszlo Molnar
|
||||
Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2023 Laszlo Molnar
|
||||
All Rights Reserved.
|
||||
|
||||
UPX and the UCL library are free software; you can redistribute them
|
||||
@@ -25,7 +25,7 @@
|
||||
<markus@oberhumer.com> <ezerotven+github@gmail.com>
|
||||
*/
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
/*************************************************************************
|
||||
//
|
||||
@@ -40,120 +40,105 @@
|
||||
#undef USE_FRAMES
|
||||
|
||||
#if 1 && (WITH_GUI) && !defined(NO_CONSOLE)
|
||||
# define NO_CONSOLE 1
|
||||
#define NO_CONSOLE 1
|
||||
#endif
|
||||
|
||||
#if 1 && defined(__linux__)
|
||||
# define USE_SCREEN 1
|
||||
# define USE_SCREEN_VCSA 1
|
||||
# if !(HAVE_LINUX_KD_H)
|
||||
# undef USE_SCREEN
|
||||
# undef USE_SCREEN_VCSA
|
||||
# endif
|
||||
# if !(HAVE_LINUX_KDEV_T_H) || !(HAVE_LINUX_MAJOR_H)
|
||||
# undef USE_SCREEN
|
||||
# undef USE_SCREEN_VCSA
|
||||
# endif
|
||||
#define USE_SCREEN 1
|
||||
#define USE_SCREEN_VCSA 1
|
||||
#if !(HAVE_LINUX_KD_H)
|
||||
#undef USE_SCREEN
|
||||
#undef USE_SCREEN_VCSA
|
||||
#endif
|
||||
#if !(HAVE_LINUX_KDEV_T_H) || !(HAVE_LINUX_MAJOR_H)
|
||||
#undef USE_SCREEN
|
||||
#undef USE_SCREEN_VCSA
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if 1 && (ACC_OS_DOS32) && defined(__DJGPP__)
|
||||
# define USE_SCREEN 1
|
||||
#define USE_SCREEN 1
|
||||
#elif 1 && (ACC_OS_CYGWIN || ACC_OS_WIN32 || ACC_OS_WIN64)
|
||||
# define USE_SCREEN 1
|
||||
# define USE_SCREEN_WIN32 1
|
||||
#define USE_SCREEN 1
|
||||
#define USE_SCREEN_WIN32 1
|
||||
#elif 1 && (ACC_OS_EMX && defined(__RSXNT__))
|
||||
# define USE_SCREEN 1
|
||||
# define USE_SCREEN_WIN32 1
|
||||
#define USE_SCREEN 1
|
||||
#define USE_SCREEN_WIN32 1
|
||||
#elif 1 && (ACC_ARCH_M68K && ACC_OS_TOS)
|
||||
#define NO_CONSOLE 1
|
||||
#endif
|
||||
|
||||
|
||||
#if 0 || (NO_ANSI)
|
||||
# undef USE_ANSI
|
||||
#undef USE_ANSI
|
||||
#endif
|
||||
#if 0 || (NO_SCREEN)
|
||||
# undef USE_SCREEN
|
||||
#undef USE_SCREEN
|
||||
#endif
|
||||
#if 0 || (NO_FRAMES) || !(USE_SCREEN)
|
||||
# undef USE_FRAMES
|
||||
#undef USE_FRAMES
|
||||
#endif
|
||||
#if 1
|
||||
# undef USE_FRAMES
|
||||
#undef USE_FRAMES
|
||||
#endif
|
||||
|
||||
|
||||
#if 0 || (USE_ANSI) || (USE_SCREEN)
|
||||
# define USE_CONSOLE 1
|
||||
#define USE_CONSOLE 1
|
||||
#endif
|
||||
|
||||
#if 0 || (NO_CONSOLE) || !(USE_CONSOLE)
|
||||
# undef USE_CONSOLE
|
||||
# undef USE_ANSI
|
||||
# undef USE_SCREEN
|
||||
# undef USE_SCREEN_VCSA
|
||||
# undef USE_SCREEN_CURSES
|
||||
# undef USE_FRAMES
|
||||
#undef USE_CONSOLE
|
||||
#undef USE_ANSI
|
||||
#undef USE_SCREEN
|
||||
#undef USE_SCREEN_VCSA
|
||||
#undef USE_SCREEN_CURSES
|
||||
#undef USE_FRAMES
|
||||
#endif
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
//
|
||||
**************************************************************************/
|
||||
|
||||
enum {
|
||||
CON_INIT,
|
||||
CON_NONE,
|
||||
CON_FILE,
|
||||
CON_ANSI_MONO,
|
||||
CON_ANSI_COLOR,
|
||||
CON_SCREEN,
|
||||
CON_UNUSED
|
||||
};
|
||||
|
||||
enum { CON_INIT, CON_NONE, CON_FILE, CON_ANSI_MONO, CON_ANSI_COLOR, CON_SCREEN, CON_UNUSED };
|
||||
|
||||
#if (USE_CONSOLE)
|
||||
|
||||
typedef struct
|
||||
{
|
||||
typedef struct {
|
||||
int (*init)(FILE *f, int, int);
|
||||
int (*set_fg)(FILE *f, int fg);
|
||||
void (*print0)(FILE *f, const char *s);
|
||||
bool (*intro)(FILE *f);
|
||||
}
|
||||
console_t;
|
||||
|
||||
} console_t;
|
||||
|
||||
void con_fprintf(FILE *f, const char *format, ...) attribute_format(2, 3);
|
||||
|
||||
|
||||
#define FG_BLACK 0x00
|
||||
#define FG_BLUE 0x01
|
||||
#define FG_GREEN 0x02
|
||||
#define FG_CYAN 0x03
|
||||
#define FG_RED 0x04
|
||||
#define FG_VIOLET 0x05
|
||||
#define FG_ORANGE 0x06
|
||||
#define FG_LTGRAY 0x07
|
||||
#define FG_DKGRAY 0x08
|
||||
#define FG_BRTBLUE 0x09
|
||||
#define FG_BRTGREEN 0x0a
|
||||
#define FG_BRTCYAN 0x0b
|
||||
#define FG_BRTRED 0x0c
|
||||
#define FG_BLACK 0x00
|
||||
#define FG_BLUE 0x01
|
||||
#define FG_GREEN 0x02
|
||||
#define FG_CYAN 0x03
|
||||
#define FG_RED 0x04
|
||||
#define FG_VIOLET 0x05
|
||||
#define FG_ORANGE 0x06
|
||||
#define FG_LTGRAY 0x07
|
||||
#define FG_DKGRAY 0x08
|
||||
#define FG_BRTBLUE 0x09
|
||||
#define FG_BRTGREEN 0x0a
|
||||
#define FG_BRTCYAN 0x0b
|
||||
#define FG_BRTRED 0x0c
|
||||
#define FG_BRTVIOLET 0x0d
|
||||
#define FG_YELLOW 0x0e
|
||||
#define FG_WHITE 0x0f
|
||||
#define FG_YELLOW 0x0e
|
||||
#define FG_WHITE 0x0f
|
||||
|
||||
#define BG_BLACK 0x00
|
||||
#define BG_BLUE 0x10
|
||||
#define BG_GREEN 0x20
|
||||
#define BG_CYAN 0x30
|
||||
#define BG_RED 0x40
|
||||
#define BG_VIOLET 0x50
|
||||
#define BG_ORANGE 0x60
|
||||
#define BG_WHITE 0x70
|
||||
#define BG_BLACK 0x00
|
||||
#define BG_BLUE 0x10
|
||||
#define BG_GREEN 0x20
|
||||
#define BG_CYAN 0x30
|
||||
#define BG_RED 0x40
|
||||
#define BG_VIOLET 0x50
|
||||
#define BG_ORANGE 0x60
|
||||
#define BG_WHITE 0x70
|
||||
|
||||
#endif /* USE_CONSOLE */
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
//
|
||||
**************************************************************************/
|
||||
@@ -172,13 +157,12 @@ extern console_t console_ansi_mono;
|
||||
extern console_t console_ansi_color;
|
||||
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
|
||||
|
||||
#define con_fg(f,x) 0
|
||||
#define con_fprintf fprintf
|
||||
#define con_fg(f, x) 0
|
||||
#define con_fprintf fprintf
|
||||
|
||||
#endif /* USE_CONSOLE */
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
|
||||
This file is part of the UPX executable compressor.
|
||||
|
||||
Copyright (C) 1996-2022 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2022 Laszlo Molnar
|
||||
Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2023 Laszlo Molnar
|
||||
All Rights Reserved.
|
||||
|
||||
UPX and the UCL library are free software; you can redistribute them
|
||||
@@ -25,7 +25,7 @@
|
||||
<markus@oberhumer.com> <ezerotven+github@gmail.com>
|
||||
*/
|
||||
|
||||
#include "conf.h"
|
||||
#include "../conf.h"
|
||||
|
||||
#if (USE_SCREEN) && (ACC_OS_DOS32) && defined(__DJGPP__)
|
||||
#if (ACC_CC_GNUC >= 0x040300ul)
|
||||
@@ -81,7 +81,9 @@ struct screen_data_t {
|
||||
};
|
||||
|
||||
/* atExit information */
|
||||
static struct { int cursor_shape; } ae = {-1};
|
||||
static struct {
|
||||
int cursor_shape;
|
||||
} ae = {-1};
|
||||
|
||||
#if USE_SCROLLBACK
|
||||
static __inline__ void sb_add(screen_t *this, int *val, int inc) {
|
||||
@@ -107,7 +109,7 @@ static void refresh(screen_t *this) { UNUSED(this); }
|
||||
|
||||
static __inline__ Cell make_cell(screen_t *this, int ch, int attr) {
|
||||
UNUSED(this);
|
||||
return (Cell)(((attr & 0xff) << 8) | (ch & 0xff));
|
||||
return (Cell) (((attr & 0xff) << 8) | (ch & 0xff));
|
||||
}
|
||||
|
||||
static int getMode(const screen_t *this) {
|
||||
@@ -2,8 +2,8 @@
|
||||
|
||||
This file is part of the UPX executable compressor.
|
||||
|
||||
Copyright (C) 1996-2022 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2022 Laszlo Molnar
|
||||
Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2023 Laszlo Molnar
|
||||
All Rights Reserved.
|
||||
|
||||
UPX and the UCL library are free software; you can redistribute them
|
||||
@@ -25,7 +25,7 @@
|
||||
<markus@oberhumer.com> <ezerotven+github@gmail.com>
|
||||
*/
|
||||
|
||||
#include "conf.h"
|
||||
#include "../conf.h"
|
||||
|
||||
#if (USE_SCREEN)
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
|
||||
This file is part of the UPX executable compressor.
|
||||
|
||||
Copyright (C) 1996-2022 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2022 Laszlo Molnar
|
||||
Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2023 Laszlo Molnar
|
||||
All Rights Reserved.
|
||||
|
||||
UPX and the UCL library are free software; you can redistribute them
|
||||
@@ -25,7 +25,7 @@
|
||||
<markus@oberhumer.com> <ezerotven+github@gmail.com>
|
||||
*/
|
||||
|
||||
#include "conf.h"
|
||||
#include "../conf.h"
|
||||
|
||||
#if (USE_SCREEN) && (USE_SCREEN_VCSA)
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
|
||||
This file is part of the UPX executable compressor.
|
||||
|
||||
Copyright (C) 1996-2022 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2022 Laszlo Molnar
|
||||
Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2023 Laszlo Molnar
|
||||
All Rights Reserved.
|
||||
|
||||
UPX and the UCL library are free software; you can redistribute them
|
||||
@@ -25,7 +25,7 @@
|
||||
<markus@oberhumer.com> <ezerotven+github@gmail.com>
|
||||
*/
|
||||
|
||||
#include "conf.h"
|
||||
#include "../conf.h"
|
||||
|
||||
#if (USE_SCREEN_WIN32)
|
||||
|
||||
@@ -76,7 +76,7 @@ struct screen_data_t {
|
||||
CHAR_INFO empty_line[256];
|
||||
};
|
||||
|
||||
#define P(x) ((SHORT)(x))
|
||||
#define P(x) ((SHORT) (x))
|
||||
|
||||
static const COORD pos00 = {0, 0};
|
||||
static const COORD size11 = {1, 1};
|
||||
@@ -111,12 +111,12 @@ static int getFg(const screen_t *this) { return this->data->attr & mask_fg; }
|
||||
static int getBg(const screen_t *this) { return this->data->attr & mask_bg; }
|
||||
|
||||
static void setFg(screen_t *this, int fg) {
|
||||
this->data->attr = (WORD)((this->data->attr & mask_bg) | (fg & mask_fg));
|
||||
this->data->attr = (WORD) ((this->data->attr & mask_bg) | (fg & mask_fg));
|
||||
SetConsoleTextAttribute(this->data->ho, this->data->attr);
|
||||
}
|
||||
|
||||
static void setBg(screen_t *this, int bg) {
|
||||
this->data->attr = (WORD)((this->data->attr & mask_fg) | (bg & mask_bg));
|
||||
this->data->attr = (WORD) ((this->data->attr & mask_fg) | (bg & mask_bg));
|
||||
SetConsoleTextAttribute(this->data->ho, this->data->attr);
|
||||
}
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
|
||||
This file is part of the UPX executable compressor.
|
||||
|
||||
Copyright (C) 1996-2022 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2022 Laszlo Molnar
|
||||
Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2023 Laszlo Molnar
|
||||
All Rights Reserved.
|
||||
|
||||
UPX and the UCL library are free software; you can redistribute them
|
||||
@@ -25,8 +25,9 @@
|
||||
<markus@oberhumer.com> <ezerotven+github@gmail.com>
|
||||
*/
|
||||
|
||||
#ifndef __UPX_SCREEN_H
|
||||
#define __UPX_SCREEN_H 1
|
||||
#pragma once
|
||||
#ifndef UPX_SCREEN_H__
|
||||
#define UPX_SCREEN_H__ 1
|
||||
|
||||
#if (USE_SCREEN)
|
||||
|
||||
+2
-2
@@ -2,8 +2,8 @@
|
||||
|
||||
This file is part of the UPX executable compressor.
|
||||
|
||||
Copyright (C) 1996-2022 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2022 Laszlo Molnar
|
||||
Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2023 Laszlo Molnar
|
||||
All Rights Reserved.
|
||||
|
||||
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.
|
||||
|
||||
Copyright (C) 1996-2022 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2022 Laszlo Molnar
|
||||
Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2023 Laszlo Molnar
|
||||
All Rights Reserved.
|
||||
|
||||
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.
|
||||
|
||||
Copyright (C) 1996-2022 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2022 Laszlo Molnar
|
||||
Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2023 Laszlo Molnar
|
||||
All Rights Reserved.
|
||||
|
||||
UPX and the UCL library are free software; you can redistribute them
|
||||
@@ -117,6 +117,7 @@ void FileBase::closex() {
|
||||
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) {
|
||||
if (!isOpen())
|
||||
throwIOException("bad seek 1");
|
||||
@@ -132,9 +133,11 @@ upx_off_t FileBase::seek(upx_off_t off, int whence) {
|
||||
off += _offset + _length;
|
||||
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);
|
||||
return off - _offset;
|
||||
return rv - _offset;
|
||||
}
|
||||
|
||||
upx_off_t FileBase::tell() const {
|
||||
|
||||
+2
-2
@@ -2,8 +2,8 @@
|
||||
|
||||
This file is part of the UPX executable compressor.
|
||||
|
||||
Copyright (C) 1996-2022 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2022 Laszlo Molnar
|
||||
Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2023 Laszlo Molnar
|
||||
All Rights Reserved.
|
||||
|
||||
UPX and the UCL library are free software; you can redistribute them
|
||||
|
||||
+29
-51
@@ -2,8 +2,8 @@
|
||||
|
||||
This file is part of the UPX executable compressor.
|
||||
|
||||
Copyright (C) 1996-2022 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2022 Laszlo Molnar
|
||||
Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2023 Laszlo Molnar
|
||||
All Rights Reserved.
|
||||
|
||||
UPX and the UCL library are free software; you can redistribute them
|
||||
@@ -25,42 +25,34 @@
|
||||
<markus@oberhumer.com> <ezerotven+github@gmail.com>
|
||||
*/
|
||||
|
||||
|
||||
#include "conf.h"
|
||||
#include "filter.h"
|
||||
#include "file.h"
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
// util
|
||||
**************************************************************************/
|
||||
|
||||
static //inline
|
||||
void initFilter(Filter *f, upx_byte *buf, unsigned buf_len)
|
||||
{
|
||||
static void initFilter(Filter *f, upx_byte *buf, unsigned buf_len) {
|
||||
f->buf = buf;
|
||||
f->buf_len = buf_len;
|
||||
// clear output parameters
|
||||
f->calls = f->wrongcalls = f->noncalls = f->firstcall = f->lastcall = 0;
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
// get a FilterEntry
|
||||
**************************************************************************/
|
||||
|
||||
const FilterImp::FilterEntry *FilterImp::getFilter(int id)
|
||||
{
|
||||
const FilterImpl::FilterEntry *FilterImpl::getFilter(int id) {
|
||||
static bool done = false;
|
||||
static unsigned char filter_map[256];
|
||||
|
||||
if (!done)
|
||||
{
|
||||
if (!done) {
|
||||
// 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));
|
||||
for (int i = 0; i < n_filters; i++)
|
||||
{
|
||||
for (int i = 0; i < n_filters; i++) {
|
||||
int filter_id = filters[i].id;
|
||||
assert(filter_id >= 0 && filter_id <= 255);
|
||||
assert(filter_map[filter_id] == 0xff);
|
||||
@@ -72,21 +64,18 @@ const FilterImp::FilterEntry *FilterImp::getFilter(int id)
|
||||
if (id < 0 || id > 255)
|
||||
return nullptr;
|
||||
unsigned index = filter_map[id];
|
||||
if (index == 0xff) // empty slot
|
||||
if (index == 0xff) // empty slot
|
||||
return nullptr;
|
||||
assert(filters[index].id == id);
|
||||
return &filters[index];
|
||||
}
|
||||
|
||||
|
||||
bool Filter::isValidFilter(int filter_id)
|
||||
{
|
||||
const FilterImp::FilterEntry * const fe = FilterImp::getFilter(filter_id);
|
||||
bool Filter::isValidFilter(int filter_id) {
|
||||
const FilterImpl::FilterEntry *const fe = FilterImpl::getFilter(filter_id);
|
||||
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))
|
||||
return false;
|
||||
if (filter_id == 0)
|
||||
@@ -99,13 +88,11 @@ bool Filter::isValidFilter(int filter_id, const int *allowed_filters)
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
// high level API
|
||||
**************************************************************************/
|
||||
|
||||
void Filter::init(int id_, unsigned addvalue_)
|
||||
{
|
||||
void Filter::init(int id_, unsigned addvalue_) {
|
||||
this->id = id_;
|
||||
initFilter(this, nullptr, 0);
|
||||
// clear input parameters
|
||||
@@ -116,12 +103,10 @@ void Filter::init(int id_, unsigned addvalue_)
|
||||
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_);
|
||||
|
||||
const FilterImp::FilterEntry * const fe = FilterImp::getFilter(id);
|
||||
const FilterImpl::FilterEntry *const fe = FilterImpl::getFilter(id);
|
||||
if (fe == nullptr)
|
||||
throwInternalError("filter-1");
|
||||
if (fe->id == 0)
|
||||
@@ -138,10 +123,10 @@ bool Filter::filter(upx_byte *buf_, unsigned buf_len_)
|
||||
if (clevel != 1)
|
||||
this->adler = upx_adler32(this->buf, this->buf_len);
|
||||
|
||||
//printf("filter: %02x %p %d\n", this->id, this->buf, this->buf_len);
|
||||
//OutputFile::dump("filter.dat", buf, buf_len);
|
||||
NO_printf("filter: %02x %p %d\n", this->id, this->buf, this->buf_len);
|
||||
// OutputFile::dump("filter.dat", buf, buf_len);
|
||||
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)
|
||||
throwFilterException();
|
||||
if (r == 0)
|
||||
@@ -149,12 +134,10 @@ bool Filter::filter(upx_byte *buf_, unsigned buf_len_)
|
||||
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_);
|
||||
|
||||
const FilterImp::FilterEntry * const fe = FilterImp::getFilter(id);
|
||||
const FilterImpl::FilterEntry *const fe = FilterImpl::getFilter(id);
|
||||
if (fe == nullptr)
|
||||
throwInternalError("unfilter-1");
|
||||
if (fe->id == 0)
|
||||
@@ -166,24 +149,21 @@ void Filter::unfilter(upx_byte *buf_, unsigned buf_len_, bool verify_checksum)
|
||||
if (!fe->do_unfilter)
|
||||
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);
|
||||
//printf("unfilter: %02x %d\n", fe->id, r);
|
||||
NO_printf("unfilter: %02x %d\n", fe->id, r);
|
||||
if (r != 0)
|
||||
throwInternalError("unfilter-3");
|
||||
//OutputFile::dump("unfilter.dat", buf, buf_len);
|
||||
// OutputFile::dump("unfilter.dat", buf, buf_len);
|
||||
|
||||
// verify checksum
|
||||
if (verify_checksum && clevel != 1)
|
||||
{
|
||||
if (verify_checksum && clevel != 1) {
|
||||
if (this->adler != upx_adler32(this->buf, this->buf_len))
|
||||
throwInternalError("unfilter-4");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Filter::verifyUnfilter()
|
||||
{
|
||||
void Filter::verifyUnfilter() {
|
||||
// Note:
|
||||
// This verify is just because of complete paranoia that there
|
||||
// could be a hidden bug in the filter implementation, and
|
||||
@@ -193,20 +173,18 @@ void Filter::verifyUnfilter()
|
||||
// See also:
|
||||
// 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)
|
||||
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
|
||||
// implementations (fe->do_scan) actually don't change the buffer.
|
||||
upx_byte *b = const_cast<upx_byte *>(buf_);
|
||||
initFilter(this, b, buf_len_);
|
||||
|
||||
const FilterImp::FilterEntry * const fe = FilterImp::getFilter(id);
|
||||
const FilterImpl::FilterEntry *const fe = FilterImpl::getFilter(id);
|
||||
if (fe == nullptr)
|
||||
throwInternalError("scan-1");
|
||||
if (fe->id == 0)
|
||||
@@ -218,9 +196,9 @@ bool Filter::scan(const upx_byte *buf_, unsigned buf_len_)
|
||||
if (!fe->do_scan)
|
||||
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);
|
||||
//printf("filter: %02x %d\n", fe->id, r);
|
||||
NO_printf("filter: %02x %d\n", fe->id, r);
|
||||
if (r > 0)
|
||||
throwFilterException();
|
||||
if (r == 0)
|
||||
|
||||
+22
-28
@@ -2,8 +2,8 @@
|
||||
|
||||
This file is part of the UPX executable compressor.
|
||||
|
||||
Copyright (C) 1996-2022 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2022 Laszlo Molnar
|
||||
Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2023 Laszlo Molnar
|
||||
All Rights Reserved.
|
||||
|
||||
UPX and the UCL library are free software; you can redistribute them
|
||||
@@ -25,13 +25,9 @@
|
||||
<markus@oberhumer.com> <ezerotven+github@gmail.com>
|
||||
*/
|
||||
|
||||
|
||||
#ifndef __UPX_FILTER_H
|
||||
#define __UPX_FILTER_H 1
|
||||
|
||||
class Filter;
|
||||
class FilterImp;
|
||||
|
||||
#pragma once
|
||||
#ifndef UPX_FILTER_H__
|
||||
#define UPX_FILTER_H__ 1
|
||||
|
||||
/*************************************************************************
|
||||
// A filter is a reversible operation that modifies a given
|
||||
@@ -50,14 +46,16 @@ class FilterImp;
|
||||
// to absolute addresses so that the buffer compresses better.
|
||||
**************************************************************************/
|
||||
|
||||
class Filter
|
||||
{
|
||||
class Filter {
|
||||
public:
|
||||
Filter(int level) { clevel = level; init(); }
|
||||
void init(int id=0, unsigned addvalue=0);
|
||||
Filter(int level) {
|
||||
clevel = level;
|
||||
init();
|
||||
}
|
||||
void init(int id = 0, unsigned addvalue = 0);
|
||||
|
||||
bool filter(upx_byte *buf, unsigned buf_len);
|
||||
void unfilter(upx_byte *buf, unsigned buf_len, bool verify_checksum=false);
|
||||
void unfilter(upx_byte *buf, unsigned buf_len, bool verify_checksum = false);
|
||||
void verifyUnfilter();
|
||||
bool scan(const upx_byte *buf, unsigned buf_len);
|
||||
|
||||
@@ -79,7 +77,7 @@ public:
|
||||
const int *preferred_ctos = nullptr;
|
||||
|
||||
// Input/output parameters used by various filters
|
||||
unsigned char cto; // call trick offset
|
||||
unsigned char cto; // call trick offset
|
||||
|
||||
// Output used by various filters. Read only.
|
||||
unsigned calls;
|
||||
@@ -87,16 +85,15 @@ public:
|
||||
unsigned wrongcalls;
|
||||
unsigned firstcall;
|
||||
unsigned lastcall;
|
||||
unsigned n_mru; // ctojr only
|
||||
unsigned n_mru; // ctojr only
|
||||
|
||||
// Read only.
|
||||
int id;
|
||||
|
||||
private:
|
||||
int clevel; // compression level
|
||||
int clevel; // compression level
|
||||
};
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
// We don't want a full OO interface here because of
|
||||
// certain implementation speed reasons.
|
||||
@@ -104,19 +101,17 @@ private:
|
||||
// This class is private to Filter - don't look.
|
||||
**************************************************************************/
|
||||
|
||||
class FilterImp
|
||||
{
|
||||
class FilterImpl {
|
||||
friend class Filter;
|
||||
|
||||
private:
|
||||
struct FilterEntry
|
||||
{
|
||||
int id; // 0 .. 255
|
||||
struct FilterEntry {
|
||||
int id; // 0 .. 255
|
||||
unsigned min_buf_len;
|
||||
unsigned max_buf_len;
|
||||
int (*do_filter)(Filter *); // filter a buffer
|
||||
int (*do_unfilter)(Filter *); // unfilter a buffer
|
||||
int (*do_scan)(Filter *); // scan a buffer
|
||||
int (*do_filter)(Filter *); // filter a buffer
|
||||
int (*do_unfilter)(Filter *); // unfilter a buffer
|
||||
int (*do_scan)(Filter *); // scan a buffer
|
||||
};
|
||||
|
||||
// get a specific filter entry
|
||||
@@ -125,10 +120,9 @@ private:
|
||||
private:
|
||||
// strictly private filter database
|
||||
static const FilterEntry filters[];
|
||||
static const int n_filters; // number of filters[]
|
||||
static const int n_filters; // number of filters[]
|
||||
};
|
||||
|
||||
|
||||
#endif /* already included */
|
||||
|
||||
/* vim:set ts=4 sw=4 et: */
|
||||
|
||||
+2
-2
@@ -2,8 +2,8 @@
|
||||
|
||||
This file is part of the UPX executable compressor.
|
||||
|
||||
Copyright (C) 1996-2022 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2022 Laszlo Molnar
|
||||
Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2023 Laszlo Molnar
|
||||
All Rights Reserved.
|
||||
|
||||
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.
|
||||
|
||||
Copyright (C) 1996-2022 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2022 Laszlo Molnar
|
||||
Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2023 Laszlo Molnar
|
||||
All Rights Reserved.
|
||||
|
||||
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.
|
||||
|
||||
Copyright (C) 1996-2022 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2022 Laszlo Molnar
|
||||
Copyright (C) 2000-2022 John F. Reiser
|
||||
Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2023 Laszlo Molnar
|
||||
Copyright (C) 2000-2023 John F. Reiser
|
||||
All Rights Reserved.
|
||||
|
||||
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.
|
||||
|
||||
Copyright (C) 1996-2022 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2022 Laszlo Molnar
|
||||
Copyright (C) 2000-2022 John F. Reiser
|
||||
Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2023 Laszlo Molnar
|
||||
Copyright (C) 2000-2023 John F. Reiser
|
||||
All Rights Reserved.
|
||||
|
||||
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.
|
||||
|
||||
Copyright (C) 1996-2022 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2022 Laszlo Molnar
|
||||
Copyright (C) 2000-2022 John F. Reiser
|
||||
Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2023 Laszlo Molnar
|
||||
Copyright (C) 2000-2023 John F. Reiser
|
||||
All Rights Reserved.
|
||||
|
||||
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.
|
||||
|
||||
Copyright (C) 1996-2022 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2022 Laszlo Molnar
|
||||
Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2023 Laszlo Molnar
|
||||
All Rights Reserved.
|
||||
|
||||
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.
|
||||
|
||||
Copyright (C) 1996-2022 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2022 Laszlo Molnar
|
||||
Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2023 Laszlo Molnar
|
||||
All Rights Reserved.
|
||||
|
||||
UPX and the UCL library are free software; you can redistribute them
|
||||
@@ -26,8 +26,8 @@
|
||||
*/
|
||||
|
||||
|
||||
#include "conf.h"
|
||||
#include "filter.h"
|
||||
#include "../conf.h"
|
||||
#include "../filter.h"
|
||||
|
||||
static unsigned
|
||||
umin(unsigned const a, unsigned const b)
|
||||
@@ -45,20 +45,20 @@ umin(unsigned const a, unsigned const b)
|
||||
// util
|
||||
**************************************************************************/
|
||||
|
||||
#include "filter/getcto.h"
|
||||
#include "getcto.h"
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
// simple filters: calltrick / swaptrick / delta / ...
|
||||
**************************************************************************/
|
||||
|
||||
#include "filter/ct.h"
|
||||
#include "filter/sw.h"
|
||||
#include "filter/ctsw.h"
|
||||
#include "ct.h"
|
||||
#include "sw.h"
|
||||
#include "ctsw.h"
|
||||
|
||||
#include "filter/sub8.h"
|
||||
#include "filter/sub16.h"
|
||||
#include "filter/sub32.h"
|
||||
#include "sub8.h"
|
||||
#include "sub16.h"
|
||||
#include "sub32.h"
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
@@ -68,25 +68,25 @@ umin(unsigned const a, unsigned const b)
|
||||
#define COND(b,x) (b[x] == 0xe8)
|
||||
#define F f_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
|
||||
#include "filter/cto.h"
|
||||
#include "cto.h"
|
||||
#undef COND
|
||||
|
||||
#define COND(b,x) (b[x] == 0xe9)
|
||||
#define F f_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
|
||||
#include "filter/cto.h"
|
||||
#include "cto.h"
|
||||
#undef COND
|
||||
|
||||
#define COND(b,x) (b[x] == 0xe8 || b[x] == 0xe9)
|
||||
#define F f_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
|
||||
#include "filter/cto.h"
|
||||
#include "cto.h"
|
||||
#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 F f_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
|
||||
#include "filter/ctoj.h"
|
||||
#include "ctoj.h"
|
||||
#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 F f_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
|
||||
#include "filter/ctok.h"
|
||||
#include "ctok.h"
|
||||
#undef COND
|
||||
#undef COND2
|
||||
#undef COND1
|
||||
@@ -138,9 +138,9 @@ umin(unsigned const a, unsigned const b)
|
||||
|
||||
#define F f_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
|
||||
#include "filter/ctojr.h"
|
||||
#include "ctojr.h"
|
||||
|
||||
#undef CONDU
|
||||
#undef CONDF
|
||||
@@ -158,9 +158,9 @@ umin(unsigned const a, unsigned const b)
|
||||
#define COND(b,x) (18==(get_be32(b+x)>>26))
|
||||
#define F f_ppcbxx
|
||||
#define U u_ppcbxx
|
||||
#include "filter/ppcbxx.h"
|
||||
#include "ppcbxx.h"
|
||||
#define F s_ppcbxx
|
||||
#include "filter/ppcbxx.h"
|
||||
#include "ppcbxx.h"
|
||||
#undef COND
|
||||
|
||||
|
||||
@@ -168,7 +168,7 @@ umin(unsigned const a, unsigned const b)
|
||||
// database for use in class Filter
|
||||
**************************************************************************/
|
||||
|
||||
const FilterImp::FilterEntry FilterImp::filters[] = {
|
||||
const FilterImpl::FilterEntry FilterImpl::filters[] = {
|
||||
// no filter
|
||||
{ 0x00, 0, 0, nullptr, nullptr, nullptr },
|
||||
|
||||
@@ -261,6 +261,6 @@ const FilterImp::FilterEntry FilterImp::filters[] = {
|
||||
{ 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: */
|
||||
+2
-2
@@ -2,8 +2,8 @@
|
||||
|
||||
This file is part of the UPX executable compressor.
|
||||
|
||||
Copyright (C) 1996-2022 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2022 Laszlo Molnar
|
||||
Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2023 Laszlo Molnar
|
||||
All Rights Reserved.
|
||||
|
||||
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.
|
||||
|
||||
Copyright (C) 1996-2022 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2022 Laszlo Molnar
|
||||
Copyright (C) 2004-2022 John F. Reiser
|
||||
Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2023 Laszlo Molnar
|
||||
Copyright (C) 2004-2023 John F. Reiser
|
||||
All Rights Reserved.
|
||||
|
||||
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.
|
||||
|
||||
Copyright (C) 1996-2022 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2022 Laszlo Molnar
|
||||
Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2023 Laszlo Molnar
|
||||
All Rights Reserved.
|
||||
|
||||
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.
|
||||
|
||||
Copyright (C) 1996-2022 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2022 Laszlo Molnar
|
||||
Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2023 Laszlo Molnar
|
||||
All Rights Reserved.
|
||||
|
||||
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.
|
||||
|
||||
Copyright (C) 1996-2022 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2022 Laszlo Molnar
|
||||
Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2023 Laszlo Molnar
|
||||
All Rights Reserved.
|
||||
|
||||
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.
|
||||
|
||||
Copyright (C) 1996-2022 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2022 Laszlo Molnar
|
||||
Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2023 Laszlo Molnar
|
||||
All Rights Reserved.
|
||||
|
||||
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.
|
||||
|
||||
Copyright (C) 1996-2022 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2022 Laszlo Molnar
|
||||
Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2023 Laszlo Molnar
|
||||
All Rights Reserved.
|
||||
|
||||
UPX and the UCL library are free software; you can redistribute them
|
||||
|
||||
+16
-7
@@ -2,8 +2,8 @@
|
||||
|
||||
This file is part of the UPX executable compressor.
|
||||
|
||||
Copyright (C) 1996-2022 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2022 Laszlo Molnar
|
||||
Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2023 Laszlo Molnar
|
||||
All Rights Reserved.
|
||||
|
||||
UPX and the UCL library are free software; you can redistribute them
|
||||
@@ -27,9 +27,9 @@
|
||||
|
||||
|
||||
#include "conf.h"
|
||||
#include "compress.h"
|
||||
#include "packmast.h"
|
||||
#include "packer.h"
|
||||
#include "compress/compress.h" // upx_ucl_version_string()
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
@@ -411,19 +411,28 @@ void show_version(bool one_line)
|
||||
if (v != nullptr && v[0])
|
||||
fprintf(fp, "LZMA SDK version %s\n", v);
|
||||
#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)
|
||||
fprintf(fp, "doctest C++ testing framework version %s\n", DOCTEST_VERSION_STR);
|
||||
#endif
|
||||
fprintf(fp, "Copyright (C) 1996-2022 Markus Franz Xaver Johannes Oberhumer\n");
|
||||
fprintf(fp, "Copyright (C) 1996-2022 Laszlo Molnar\n");
|
||||
fprintf(fp, "Copyright (C) 2000-2022 John F. Reiser\n");
|
||||
fprintf(fp, "Copyright (C) 2002-2022 Jens Medoch\n");
|
||||
fprintf(fp, "Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer\n");
|
||||
fprintf(fp, "Copyright (C) 1996-2023 Laszlo Molnar\n");
|
||||
fprintf(fp, "Copyright (C) 2000-2023 John F. Reiser\n");
|
||||
fprintf(fp, "Copyright (C) 2002-2023 Jens Medoch\n");
|
||||
#if (WITH_ZLIB)
|
||||
fprintf(fp, "Copyright (C) 1995" "-2022 Jean-loup Gailly and Mark Adler\n");
|
||||
#endif
|
||||
#if (WITH_LZMA)
|
||||
fprintf(fp, "Copyright (C) 1999" "-2006 Igor Pavlov\n");
|
||||
#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)
|
||||
fprintf(fp, "Copyright (C) 2016" "-2021 Viktor Kirilov\n");
|
||||
#endif
|
||||
|
||||
+134
-197
@@ -2,8 +2,8 @@
|
||||
|
||||
This file is part of the UPX executable compressor.
|
||||
|
||||
Copyright (C) 1996-2022 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2022 Laszlo Molnar
|
||||
Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2023 Laszlo Molnar
|
||||
All Rights Reserved.
|
||||
|
||||
UPX and the UCL library are free software; you can redistribute them
|
||||
@@ -25,285 +25,226 @@
|
||||
<markus@oberhumer.com> <ezerotven+github@gmail.com>
|
||||
*/
|
||||
|
||||
|
||||
#include "conf.h"
|
||||
#include "file.h"
|
||||
#include "util/membuffer.h"
|
||||
#include "lefile.h"
|
||||
|
||||
|
||||
LeFile::LeFile(InputFile *f) :
|
||||
fif(f), fof(nullptr),
|
||||
le_offset(0), exe_offset(0)
|
||||
{
|
||||
LeFile::LeFile(InputFile *f) : fif(f), fof(nullptr), le_offset(0), exe_offset(0) {
|
||||
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(&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;
|
||||
memset(&ih, 0, sizeof ih);
|
||||
memset(&oh, 0, sizeof oh);
|
||||
}
|
||||
|
||||
|
||||
LeFile::~LeFile()
|
||||
{
|
||||
delete [] iobject_table;
|
||||
delete [] oobject_table;
|
||||
delete [] ifpage_table;
|
||||
delete [] ofpage_table;
|
||||
delete [] ipm_entries;
|
||||
delete [] opm_entries;
|
||||
delete [] ires_names;
|
||||
delete [] ores_names;
|
||||
delete [] ifixups;
|
||||
delete [] ofixups;
|
||||
delete [] inonres_names;
|
||||
delete [] ononres_names;
|
||||
delete [] ientries;
|
||||
delete [] oentries;
|
||||
LeFile::~LeFile() {
|
||||
delete[] iobject_table;
|
||||
delete[] oobject_table;
|
||||
delete[] ifpage_table;
|
||||
delete[] ofpage_table;
|
||||
delete[] ipm_entries;
|
||||
delete[] opm_entries;
|
||||
delete[] ires_names;
|
||||
delete[] ores_names;
|
||||
delete[] ifixups;
|
||||
delete[] ofixups;
|
||||
delete[] inonres_names;
|
||||
delete[] ononres_names;
|
||||
delete[] ientries;
|
||||
delete[] oentries;
|
||||
}
|
||||
|
||||
|
||||
#define objects ih.object_table_entries
|
||||
#define pages ih.memory_pages
|
||||
#define mps ih.memory_page_size
|
||||
#define pages ih.memory_pages
|
||||
#define mps ih.memory_page_size
|
||||
|
||||
|
||||
void LeFile::readObjectTable()
|
||||
{
|
||||
void LeFile::readObjectTable() {
|
||||
soobject_table = objects;
|
||||
iobject_table = New(le_object_table_entry_t, soobject_table);
|
||||
fif->seek(le_offset + ih.object_table_offset,SEEK_SET);
|
||||
fif->readx(iobject_table,sizeof(*iobject_table)*objects);
|
||||
fif->seek(le_offset + ih.object_table_offset, SEEK_SET);
|
||||
fif->readx(iobject_table, sizeof(*iobject_table) * objects);
|
||||
}
|
||||
|
||||
|
||||
void LeFile::writeObjectTable()
|
||||
{
|
||||
void LeFile::writeObjectTable() {
|
||||
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;
|
||||
ipm_entries = New(le_pagemap_entry_t, sopm_entries);
|
||||
fif->seek(le_offset + ih.object_pagemap_offset,SEEK_SET);
|
||||
fif->readx(ipm_entries,sizeof(*ipm_entries)*pages);
|
||||
fif->seek(le_offset + ih.object_pagemap_offset, SEEK_SET);
|
||||
fif->readx(ipm_entries, sizeof(*ipm_entries) * pages);
|
||||
|
||||
for (unsigned ic = 0; ic < pages; ic++)
|
||||
if ((ipm_entries[ic].type & 0xC0) != 0 && (ipm_entries[ic].type & 0xC0) != 0xC0)
|
||||
throwCantPack("unexpected value in page map table");
|
||||
}
|
||||
|
||||
|
||||
void LeFile::writePageMap()
|
||||
{
|
||||
void LeFile::writePageMap() {
|
||||
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;
|
||||
ires_names = New(upx_byte, sores_names);
|
||||
fif->seek(le_offset+ih.resident_names_offset,SEEK_SET);
|
||||
fif->readx(ires_names,sores_names);
|
||||
fif->seek(le_offset + ih.resident_names_offset, SEEK_SET);
|
||||
fif->readx(ires_names, sores_names);
|
||||
}
|
||||
|
||||
|
||||
void LeFile::writeResidentNames()
|
||||
{
|
||||
void LeFile::writeResidentNames() {
|
||||
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;
|
||||
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);
|
||||
fif->readx(ientries,soentries);
|
||||
fif->readx(ientries, soentries);
|
||||
}
|
||||
|
||||
|
||||
void LeFile::writeEntryTable()
|
||||
{
|
||||
void LeFile::writeEntryTable() {
|
||||
if (fof && oentries)
|
||||
fof->write(oentries,soentries);
|
||||
fof->write(oentries, soentries);
|
||||
}
|
||||
|
||||
|
||||
void LeFile::readFixupPageTable()
|
||||
{
|
||||
sofpage_table = 1+pages;
|
||||
void LeFile::readFixupPageTable() {
|
||||
sofpage_table = 1 + pages;
|
||||
ifpage_table = New(unsigned, sofpage_table);
|
||||
fif->seek(le_offset + ih.fixup_page_table_offset,SEEK_SET);
|
||||
fif->readx(ifpage_table,4*sofpage_table);
|
||||
fif->seek(le_offset + ih.fixup_page_table_offset, SEEK_SET);
|
||||
fif->readx(ifpage_table, 4 * sofpage_table);
|
||||
}
|
||||
|
||||
|
||||
void LeFile::writeFixupPageTable()
|
||||
{
|
||||
void LeFile::writeFixupPageTable() {
|
||||
if (fof && ofpage_table)
|
||||
fof->write(ofpage_table,4*sofpage_table);
|
||||
fof->write(ofpage_table, 4 * sofpage_table);
|
||||
}
|
||||
|
||||
|
||||
void LeFile::readFixups()
|
||||
{
|
||||
sofixups = get_le32(ifpage_table+pages)-get_le32(ifpage_table);
|
||||
void LeFile::readFixups() {
|
||||
sofixups = get_le32(ifpage_table + pages) - get_le32(ifpage_table);
|
||||
ifixups = New(upx_byte, sofixups);
|
||||
fif->seek(le_offset + ih.fixup_record_table_offset,SEEK_SET);
|
||||
fif->readx(ifixups,sofixups);
|
||||
fif->seek(le_offset + ih.fixup_record_table_offset, SEEK_SET);
|
||||
fif->readx(ifixups, sofixups);
|
||||
}
|
||||
|
||||
|
||||
void LeFile::writeFixups()
|
||||
{
|
||||
void LeFile::writeFixups() {
|
||||
if (fof && ofixups)
|
||||
fof->write(ofixups,sofixups);
|
||||
fof->write(ofixups, sofixups);
|
||||
}
|
||||
|
||||
|
||||
unsigned LeFile::getImageSize() const
|
||||
{
|
||||
unsigned LeFile::getImageSize() const {
|
||||
unsigned n = 0;
|
||||
if (ih.memory_pages > 0)
|
||||
{
|
||||
if (ih.memory_pages > 0) {
|
||||
n = (ih.memory_pages - 1) * ih.memory_page_size;
|
||||
n += ih.bytes_on_last_page;
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
|
||||
void LeFile::readImage()
|
||||
{
|
||||
soimage = pages*mps;
|
||||
void LeFile::readImage() {
|
||||
soimage = pages * mps;
|
||||
mb_iimage.alloc(soimage);
|
||||
mb_iimage.clear();
|
||||
iimage = mb_iimage;
|
||||
|
||||
unsigned ic,jc;
|
||||
for (ic = jc = 0; ic < pages; ic++)
|
||||
{
|
||||
if ((ipm_entries[ic].type & 0xC0) == 0)
|
||||
{
|
||||
unsigned ic, jc;
|
||||
for (ic = jc = 0; ic < pages; ic++) {
|
||||
if ((ipm_entries[ic].type & 0xC0) == 0) {
|
||||
fif->seek(ih.data_pages_offset + exe_offset +
|
||||
(ipm_entries[ic].m*0x100 + ipm_entries[ic].l-1) * mps,SEEK_SET);
|
||||
auto bytes = ic != pages-1 ? mps : ih.bytes_on_last_page;
|
||||
fif->readx(raw_bytes(iimage+jc, bytes), bytes);
|
||||
(ipm_entries[ic].m * 0x100 + ipm_entries[ic].l - 1) * mps,
|
||||
SEEK_SET);
|
||||
auto bytes = ic != pages - 1 ? mps : ih.bytes_on_last_page;
|
||||
fif->readx(raw_bytes(iimage + jc, bytes), bytes);
|
||||
}
|
||||
jc += mps;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void LeFile::writeImage()
|
||||
{
|
||||
void LeFile::writeImage() {
|
||||
if (fof && oimage != nullptr)
|
||||
fof->write(raw_bytes(oimage, soimage), soimage);
|
||||
}
|
||||
|
||||
|
||||
void LeFile::readNonResidentNames()
|
||||
{
|
||||
if (ih.non_resident_name_table_length)
|
||||
{
|
||||
void LeFile::readNonResidentNames() {
|
||||
if (ih.non_resident_name_table_length) {
|
||||
sononres_names = ih.non_resident_name_table_length;
|
||||
inonres_names = New(upx_byte, sononres_names);
|
||||
fif->seek(exe_offset+ih.non_resident_name_table_offset,SEEK_SET);
|
||||
fif->readx(inonres_names,sononres_names);
|
||||
fif->seek(exe_offset + ih.non_resident_name_table_offset, SEEK_SET);
|
||||
fif->readx(inonres_names, sononres_names);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void LeFile::writeNonResidentNames()
|
||||
{
|
||||
void LeFile::writeNonResidentNames() {
|
||||
if (fof && ononres_names)
|
||||
fof->write(ononres_names,sononres_names);
|
||||
fof->write(ononres_names, sononres_names);
|
||||
}
|
||||
|
||||
|
||||
bool LeFile::readFileHeader()
|
||||
{
|
||||
#define H(x) get_le16(header+2*(x))
|
||||
bool LeFile::readFileHeader() {
|
||||
#define H(x) get_le16(header + 2 * (x))
|
||||
upx_byte header[0x40];
|
||||
le_offset = exe_offset = 0;
|
||||
int ic;
|
||||
|
||||
for (ic = 0; ic < 20; ic++)
|
||||
{
|
||||
fif->seek(le_offset,SEEK_SET);
|
||||
fif->readx(header,sizeof(header));
|
||||
for (ic = 0; ic < 20; ic++) {
|
||||
fif->seek(le_offset, SEEK_SET);
|
||||
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;
|
||||
if (H(0x18/2) >= 0x40
|
||||
&& memcmp(header+0x19,"TIPPACH",7)) // new format exe
|
||||
le_offset += H(0x3c/2)+H(0x3e/2)*65536;
|
||||
else
|
||||
{
|
||||
le_offset += H(2)*512+H(1);
|
||||
if (H(0x18 / 2) >= 0x40 && memcmp(header + 0x19, "TIPPACH", 7)) // new format exe
|
||||
le_offset += H(0x3c / 2) + H(0x3e / 2) * 65536;
|
||||
else {
|
||||
le_offset += H(2) * 512 + H(1);
|
||||
if (H(1))
|
||||
le_offset -= 512;
|
||||
else if (H(2) == 0)
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else if (memcmp(header,"BW",2) == 0) // used in dos4gw.exe
|
||||
le_offset += H(2)*512+H(1);
|
||||
else if (memcmp(header,"LE",2) == 0)
|
||||
} else if (memcmp(header, "BW", 2) == 0) // used in dos4gw.exe
|
||||
le_offset += H(2) * 512 + H(1);
|
||||
else if (memcmp(header, "LE", 2) == 0)
|
||||
break;
|
||||
else if (memcmp(header,"PMW1",4) == 0)
|
||||
else if (memcmp(header, "PMW1", 4) == 0)
|
||||
throwCantPack("already packed with PMWLITE");
|
||||
else
|
||||
return false;
|
||||
}
|
||||
if (ic == 20)
|
||||
return false;
|
||||
fif->seek(le_offset,SEEK_SET);
|
||||
fif->readx(&ih,sizeof(ih));
|
||||
fif->seek(le_offset, SEEK_SET);
|
||||
fif->readx(&ih, sizeof(ih));
|
||||
return true;
|
||||
#undef H
|
||||
}
|
||||
|
||||
|
||||
void LeFile::writeFile(OutputFile *f, bool le)
|
||||
{
|
||||
void LeFile::writeFile(OutputFile *f, bool le) {
|
||||
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.object_table_offset = sizeof(oh);
|
||||
oh.object_table_entries = soobject_table;
|
||||
oh.object_pagemap_offset = oh.object_table_offset + soobject_table*sizeof(*iobject_table);
|
||||
oh.resident_names_offset = oh.object_pagemap_offset + sopm_entries*sizeof(*ipm_entries);
|
||||
oh.object_pagemap_offset = oh.object_table_offset + soobject_table * sizeof(*iobject_table);
|
||||
oh.resident_names_offset = oh.object_pagemap_offset + sopm_entries * sizeof(*ipm_entries);
|
||||
oh.entry_table_offset = oh.resident_names_offset + sores_names;
|
||||
oh.fixup_page_table_offset = oh.entry_table_offset + soentries;
|
||||
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_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);
|
||||
if (ih.non_resident_name_table_length)
|
||||
{
|
||||
oh.data_pages_offset =
|
||||
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_length = sononres_names;
|
||||
}
|
||||
oh.fixup_size = sofixups + 4*sofpage_table;
|
||||
oh.fixup_size = sofixups + 4 * sofpage_table;
|
||||
oh.loader_size = oh.fixup_size + oh.fixup_page_table_offset - sizeof(oh);
|
||||
|
||||
fof->write(&oh,sizeof(oh));
|
||||
fof->write(&oh, sizeof(oh));
|
||||
writeObjectTable();
|
||||
writePageMap();
|
||||
writeResidentNames();
|
||||
@@ -314,57 +255,53 @@ void LeFile::writeFile(OutputFile *f, bool le)
|
||||
writeNonResidentNames();
|
||||
}
|
||||
|
||||
|
||||
void LeFile::countFixups(unsigned *counts) const
|
||||
{
|
||||
void LeFile::countFixups(unsigned *counts) const {
|
||||
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[objects] - # of selector fixups
|
||||
// counts[objects+1] - # of self-relative fixups
|
||||
|
||||
const upx_byte *fix = ifixups;
|
||||
const unsigned sfixups = get_le32(ifpage_table+pages);
|
||||
const unsigned sfixups = get_le32(ifpage_table + pages);
|
||||
unsigned ll;
|
||||
|
||||
while ((unsigned)(fix - ifixups) < sfixups)
|
||||
{
|
||||
while (ptr_udiff_bytes(fix, ifixups) < sfixups) {
|
||||
if ((fix[1] & ~0x10) != 0)
|
||||
throwCantPack("unsupported fixup record");
|
||||
switch (*fix)
|
||||
{
|
||||
case 2: // selector fixup
|
||||
counts[o] += 9;
|
||||
fix += 5;
|
||||
break;
|
||||
case 0x12: // alias selector
|
||||
throwCantPack("16-bit selector alias fixup not yet supported");
|
||||
case 5: // 16-bit offset
|
||||
fix += (fix[1] & 0x10) ? 9 : 7;
|
||||
break;
|
||||
case 6: // 16:32 pointer
|
||||
counts[o] += 9;
|
||||
// fall through
|
||||
case 7: // 32-bit offset
|
||||
counts[fix[4]-1] += 4;
|
||||
fix += (fix[1] & 0x10) ? 9 : 7;
|
||||
break;
|
||||
case 0x27: // 32-bit offset list
|
||||
ll = fix[2];
|
||||
counts[fix[3]-1] += ll*4;
|
||||
fix += (fix[1] & 0x10) ? 6 : 4;
|
||||
fix += ll*2;
|
||||
break;
|
||||
case 8: // 32-bit self relative fixup
|
||||
counts[o+1] += 4;
|
||||
fix += (fix[1] & 0x10) ? 9 : 7;
|
||||
break;
|
||||
default:
|
||||
throwCantPack("unsupported fixup record");
|
||||
switch (*fix) {
|
||||
case 2: // selector fixup
|
||||
counts[o] += 9;
|
||||
fix += 5;
|
||||
break;
|
||||
case 0x12: // alias selector
|
||||
throwCantPack("16-bit selector alias fixup not yet supported");
|
||||
case 5: // 16-bit offset
|
||||
fix += (fix[1] & 0x10) ? 9 : 7;
|
||||
break;
|
||||
case 6: // 16:32 pointer
|
||||
counts[o] += 9;
|
||||
// fall through
|
||||
case 7: // 32-bit offset
|
||||
counts[fix[4] - 1] += 4;
|
||||
fix += (fix[1] & 0x10) ? 9 : 7;
|
||||
break;
|
||||
case 0x27: // 32-bit offset list
|
||||
ll = fix[2];
|
||||
counts[fix[3] - 1] += ll * 4;
|
||||
fix += (fix[1] & 0x10) ? 6 : 4;
|
||||
fix += ll * 2;
|
||||
break;
|
||||
case 8: // 32-bit self relative fixup
|
||||
counts[o + 1] += 4;
|
||||
fix += (fix[1] & 0x10) ? 9 : 7;
|
||||
break;
|
||||
default:
|
||||
throwCantPack("unsupported fixup record");
|
||||
}
|
||||
}
|
||||
counts[o]++; // extra space for 'ret'
|
||||
counts[o+1] += 4; // extra space for 0xFFFFFFFF
|
||||
counts[o]++; // extra space for 'ret'
|
||||
counts[o + 1] += 4; // extra space for 0xFFFFFFFF
|
||||
}
|
||||
|
||||
/* vim:set ts=4 sw=4 et: */
|
||||
|
||||
+113
-107
@@ -2,8 +2,8 @@
|
||||
|
||||
This file is part of the UPX executable compressor.
|
||||
|
||||
Copyright (C) 1996-2022 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2022 Laszlo Molnar
|
||||
Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2023 Laszlo Molnar
|
||||
All Rights Reserved.
|
||||
|
||||
UPX and the UCL library are free software; you can redistribute them
|
||||
@@ -25,20 +25,18 @@
|
||||
<markus@oberhumer.com> <ezerotven+github@gmail.com>
|
||||
*/
|
||||
|
||||
|
||||
#ifndef __UPX_LEFILE_H
|
||||
#define __UPX_LEFILE_H 1
|
||||
#pragma once
|
||||
#ifndef UPX_LEFILE_H__
|
||||
#define UPX_LEFILE_H__ 1
|
||||
|
||||
class InputFile;
|
||||
class OutputFile;
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
//
|
||||
**************************************************************************/
|
||||
|
||||
class LeFile
|
||||
{
|
||||
class LeFile {
|
||||
protected:
|
||||
LeFile(InputFile *);
|
||||
virtual ~LeFile();
|
||||
@@ -49,161 +47,170 @@ protected:
|
||||
protected:
|
||||
enum { FIXUP_EXTRA = 3 };
|
||||
|
||||
__packed_struct(le_header_t)
|
||||
struct alignas(1) le_header_t {
|
||||
// 0x00
|
||||
char _[2]; // signature: 'LE' || 'LX'
|
||||
char byte_order; // 0 little endian
|
||||
char word_order; // 0 little endian
|
||||
LE32 exe_format_level; // 0
|
||||
LE16 cpu_type; // 1->286..4->586
|
||||
LE16 target_os; // 1->OS2
|
||||
char _0[4]; // module_version = 0
|
||||
char _[2]; // signature: 'LE' || 'LX'
|
||||
char byte_order; // 0 little endian
|
||||
char word_order; // 0 little endian
|
||||
LE32 exe_format_level; // 0
|
||||
LE16 cpu_type; // 1->286..4->586
|
||||
LE16 target_os; // 1->OS2
|
||||
char _0[4]; // module_version = 0
|
||||
// 0x10
|
||||
LE32 module_type; // 0x200->compatible with PM windowing
|
||||
LE32 memory_pages;
|
||||
LE32 init_cs_object;
|
||||
LE32 init_eip_offset;
|
||||
LE32 module_type; // 0x200->compatible with PM windowing
|
||||
LE32 memory_pages;
|
||||
LE32 init_cs_object;
|
||||
LE32 init_eip_offset;
|
||||
// 0x20
|
||||
LE32 init_ss_object;
|
||||
LE32 init_esp_offset;
|
||||
LE32 memory_page_size;
|
||||
LE32 bytes_on_last_page;
|
||||
LE32 init_ss_object;
|
||||
LE32 init_esp_offset;
|
||||
LE32 memory_page_size;
|
||||
LE32 bytes_on_last_page;
|
||||
// 0x30
|
||||
LE32 fixup_size;
|
||||
char _1[4]; // fixup_checksum = 0
|
||||
LE32 loader_size;
|
||||
char _2[4]; // loader_checksum = 0
|
||||
LE32 fixup_size;
|
||||
char _1[4]; // fixup_checksum = 0
|
||||
LE32 loader_size;
|
||||
char _2[4]; // loader_checksum = 0
|
||||
// 0x40
|
||||
LE32 object_table_offset;
|
||||
LE32 object_table_entries;
|
||||
LE32 object_pagemap_offset;
|
||||
LE32 object_iterate_data_map_offset;
|
||||
LE32 object_table_offset;
|
||||
LE32 object_table_entries;
|
||||
LE32 object_pagemap_offset;
|
||||
LE32 object_iterate_data_map_offset;
|
||||
// 0x50
|
||||
char _3[4]; // resource_offset
|
||||
LE32 resource_entries;
|
||||
LE32 resident_names_offset;
|
||||
LE32 entry_table_offset;
|
||||
char _3[4]; // resource_offset
|
||||
LE32 resource_entries;
|
||||
LE32 resident_names_offset;
|
||||
LE32 entry_table_offset;
|
||||
// 0x60
|
||||
char _4[4]; // module_directives_table_offset = 0
|
||||
LE32 module_directives_entries;
|
||||
LE32 fixup_page_table_offset;
|
||||
LE32 fixup_record_table_offset;
|
||||
char _4[4]; // module_directives_table_offset = 0
|
||||
LE32 module_directives_entries;
|
||||
LE32 fixup_page_table_offset;
|
||||
LE32 fixup_record_table_offset;
|
||||
// 0x70
|
||||
LE32 imported_modules_name_table_offset;
|
||||
LE32 imported_modules_count;
|
||||
LE32 imported_procedures_name_table_offset;
|
||||
char _5[4]; // per_page_checksum_table_offset = 0
|
||||
LE32 imported_modules_name_table_offset;
|
||||
LE32 imported_modules_count;
|
||||
LE32 imported_procedures_name_table_offset;
|
||||
char _5[4]; // per_page_checksum_table_offset = 0
|
||||
// 0x80
|
||||
LE32 data_pages_offset;
|
||||
char _6[4]; // preload_page_count = 0
|
||||
LE32 non_resident_name_table_offset;
|
||||
LE32 non_resident_name_table_length;
|
||||
LE32 data_pages_offset;
|
||||
char _6[4]; // preload_page_count = 0
|
||||
LE32 non_resident_name_table_offset;
|
||||
LE32 non_resident_name_table_length;
|
||||
// 0x90
|
||||
char _7[4]; //non_resident_names_checksum
|
||||
LE32 automatic_data_object;
|
||||
char _7[4]; // non_resident_names_checksum
|
||||
LE32 automatic_data_object;
|
||||
#if 1
|
||||
char _8[44];
|
||||
char _8[44];
|
||||
#else
|
||||
LE32 debug_info_offset;
|
||||
LE32 debug_info_length;
|
||||
LE32 debug_info_offset;
|
||||
LE32 debug_info_length;
|
||||
// 0xA0
|
||||
LE32 preload_instance_pages;
|
||||
LE32 demand_instance_pages;
|
||||
LE32 extra_heap_alloc;
|
||||
char reserved[12];
|
||||
LE32 versioninfo;
|
||||
LE32 unknown;
|
||||
LE32 preload_instance_pages;
|
||||
LE32 demand_instance_pages;
|
||||
LE32 extra_heap_alloc;
|
||||
char reserved[12];
|
||||
LE32 versioninfo;
|
||||
LE32 unknown;
|
||||
// 0xC0
|
||||
LE16 device_id;
|
||||
LE16 ddk_version;
|
||||
LE16 device_id;
|
||||
LE16 ddk_version;
|
||||
#endif
|
||||
__packed_struct_end()
|
||||
};
|
||||
|
||||
__packed_struct(le_object_table_entry_t)
|
||||
LE32 virtual_size;
|
||||
LE32 base_address;
|
||||
LE32 flags;
|
||||
LE32 pagemap_index;
|
||||
LE32 npages;
|
||||
LE32 reserved;
|
||||
__packed_struct_end()
|
||||
struct alignas(1) le_object_table_entry_t {
|
||||
LE32 virtual_size;
|
||||
LE32 base_address;
|
||||
LE32 flags;
|
||||
LE32 pagemap_index;
|
||||
LE32 npages;
|
||||
LE32 reserved;
|
||||
};
|
||||
|
||||
__packed_struct(le_pagemap_entry_t)
|
||||
struct alignas(1) le_pagemap_entry_t {
|
||||
unsigned char h;
|
||||
unsigned char m;
|
||||
unsigned char l;
|
||||
unsigned char type; // 0x00-legal;0x40-iterated;0x80-invalid;0xC0-zeroed
|
||||
__packed_struct_end()
|
||||
unsigned char type; // 0x00-legal;0x40-iterated;0x80-invalid;0xC0-zeroed
|
||||
};
|
||||
|
||||
virtual void readObjectTable();
|
||||
virtual void writeObjectTable();
|
||||
//virtual void encodeObjectTable(){oobject_table = iobject_table; iobject_table = nullptr;}
|
||||
//virtual void decodeObjectTable(){encodeObjectTable();}
|
||||
// virtual void encodeObjectTable(){oobject_table = iobject_table; iobject_table = nullptr;}
|
||||
// virtual void decodeObjectTable(){encodeObjectTable();}
|
||||
|
||||
virtual void readFixupPageTable();
|
||||
virtual void writeFixupPageTable();
|
||||
//virtual void encodeFixupPageTable(){ofpage_table = ifpage_table; ifpage_table = nullptr;}
|
||||
//virtual void decodeFixupPageTable(){encodeFixupPageTable();}
|
||||
// virtual void encodeFixupPageTable(){ofpage_table = ifpage_table; ifpage_table = nullptr;}
|
||||
// virtual void decodeFixupPageTable(){encodeFixupPageTable();}
|
||||
|
||||
virtual void readPageMap();
|
||||
virtual void writePageMap();
|
||||
virtual void encodePageMap(){opm_entries = ipm_entries; ipm_entries = nullptr;}
|
||||
virtual void decodePageMap(){encodePageMap();}
|
||||
virtual void encodePageMap() {
|
||||
opm_entries = ipm_entries;
|
||||
ipm_entries = nullptr;
|
||||
}
|
||||
virtual void decodePageMap() { encodePageMap(); }
|
||||
|
||||
virtual void readResidentNames();
|
||||
virtual void writeResidentNames();
|
||||
virtual void encodeResidentNames(){ores_names = ires_names; ires_names = nullptr;}
|
||||
virtual void decodeResidentNames(){encodeResidentNames();}
|
||||
virtual void encodeResidentNames() {
|
||||
ores_names = ires_names;
|
||||
ires_names = nullptr;
|
||||
}
|
||||
virtual void decodeResidentNames() { encodeResidentNames(); }
|
||||
|
||||
virtual void readNonResidentNames();
|
||||
virtual void writeNonResidentNames();
|
||||
virtual void encodeNonResidentNames(){ononres_names = inonres_names; inonres_names = nullptr;}
|
||||
virtual void decodeNonResidentNames(){encodeNonResidentNames();}
|
||||
virtual void encodeNonResidentNames() {
|
||||
ononres_names = inonres_names;
|
||||
inonres_names = nullptr;
|
||||
}
|
||||
virtual void decodeNonResidentNames() { encodeNonResidentNames(); }
|
||||
|
||||
virtual void readEntryTable();
|
||||
virtual void writeEntryTable();
|
||||
//virtual void encodeEntryTable(){oentries = ientries; ientries = nullptr;}
|
||||
//virtual void decodeEntryTable(){encodeEntryTable();}
|
||||
// virtual void encodeEntryTable(){oentries = ientries; ientries = nullptr;}
|
||||
// virtual void decodeEntryTable(){encodeEntryTable();}
|
||||
|
||||
virtual void readFixups();
|
||||
virtual void writeFixups();
|
||||
//virtual void encodeFixups(){ofixups = ifixups; ifixups = nullptr;}
|
||||
//virtual void decodeFixups(){encodeFixups();}
|
||||
// virtual void encodeFixups(){ofixups = ifixups; ifixups = nullptr;}
|
||||
// virtual void decodeFixups(){encodeFixups();}
|
||||
|
||||
virtual void readImage();
|
||||
virtual void writeImage();
|
||||
//virtual void encodeImage(){oimage = iimage; iimage = nullptr;}
|
||||
//virtual void decodeImage(){encodeImage();}
|
||||
// virtual void encodeImage(){oimage = iimage; iimage = nullptr;}
|
||||
// virtual void decodeImage(){encodeImage();}
|
||||
|
||||
void countFixups(unsigned *) const;
|
||||
unsigned getImageSize() const;
|
||||
|
||||
InputFile *fif;
|
||||
OutputFile *fof;
|
||||
InputFile *fif = nullptr;
|
||||
OutputFile *fof = nullptr;
|
||||
unsigned le_offset;
|
||||
unsigned exe_offset;
|
||||
|
||||
le_header_t ih;
|
||||
le_header_t oh;
|
||||
|
||||
le_object_table_entry_t *iobject_table;
|
||||
le_object_table_entry_t *oobject_table;
|
||||
unsigned *ifpage_table;
|
||||
unsigned *ofpage_table;
|
||||
le_pagemap_entry_t *ipm_entries;
|
||||
le_pagemap_entry_t *opm_entries;
|
||||
upx_byte *ires_names;
|
||||
upx_byte *ores_names;
|
||||
upx_byte *ifixups;
|
||||
upx_byte *ofixups;
|
||||
upx_byte *inonres_names;
|
||||
upx_byte *ononres_names;
|
||||
le_object_table_entry_t *iobject_table = nullptr;
|
||||
le_object_table_entry_t *oobject_table = nullptr;
|
||||
unsigned *ifpage_table = nullptr;
|
||||
unsigned *ofpage_table = nullptr;
|
||||
le_pagemap_entry_t *ipm_entries = nullptr;
|
||||
le_pagemap_entry_t *opm_entries = nullptr;
|
||||
upx_byte *ires_names = nullptr;
|
||||
upx_byte *ores_names = nullptr;
|
||||
upx_byte *ifixups = nullptr;
|
||||
upx_byte *ofixups = nullptr;
|
||||
upx_byte *inonres_names = nullptr;
|
||||
upx_byte *ononres_names = nullptr;
|
||||
MemBuffer mb_iimage;
|
||||
SPAN_0(upx_byte) iimage = nullptr;
|
||||
MemBuffer mb_oimage;
|
||||
SPAN_0(upx_byte) oimage = nullptr;
|
||||
upx_byte *ientries;
|
||||
upx_byte *oentries;
|
||||
upx_byte *ientries = nullptr;
|
||||
upx_byte *oentries = nullptr;
|
||||
|
||||
unsigned soobject_table;
|
||||
unsigned sofpage_table;
|
||||
@@ -217,10 +224,9 @@ protected:
|
||||
private:
|
||||
// disable copy and assignment
|
||||
LeFile(const LeFile &) = delete;
|
||||
LeFile& operator= (const LeFile &) = delete;
|
||||
LeFile &operator=(const LeFile &) = delete;
|
||||
};
|
||||
|
||||
|
||||
#endif /* already included */
|
||||
|
||||
/* vim:set ts=4 sw=4 et: */
|
||||
|
||||
+37
-28
@@ -2,8 +2,8 @@
|
||||
|
||||
This file is part of the UPX executable compressor.
|
||||
|
||||
Copyright (C) 1996-2022 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2022 Laszlo Molnar
|
||||
Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2023 Laszlo Molnar
|
||||
All Rights Reserved.
|
||||
|
||||
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
|
||||
|
||||
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;
|
||||
NO_printf("\nElfLinker::init %d @%p\n", output_capacity, output);
|
||||
|
||||
// FIXME: bad compare when either symbols or relocs are absent
|
||||
if ((int) strlen("Sections:\n"
|
||||
@@ -198,8 +201,7 @@ void ElfLinker::preprocessSections(char *start, char const *end) {
|
||||
char *n = strstr(start, name);
|
||||
n[strlen(name)] = 0;
|
||||
addSection(n, input + offset, size, align);
|
||||
|
||||
// printf("section %s preprocessed\n", n);
|
||||
NO_printf("section %s preprocessed\n", n);
|
||||
}
|
||||
}
|
||||
addSection("*ABS*", nullptr, 0, 0);
|
||||
@@ -224,21 +226,21 @@ void ElfLinker::preprocessSymbols(char *start, char const *end) {
|
||||
assert(offset == 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
|
||||
// work around broken scanf() implementations
|
||||
// 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
|
||||
&offset, section, symbol) == 3)
|
||||
{
|
||||
char *s = strstr(start, symbol);
|
||||
s[strlen(symbol)] = 0;
|
||||
if (strcmp(section, "*UND*") == 0)
|
||||
offset = 0xdeaddead;
|
||||
assert(strcmp(section, "*ABS*") != 0);
|
||||
addSymbol(s, section, offset);
|
||||
}
|
||||
char *s = strstr(start, symbol);
|
||||
s[strlen(symbol)] = 0;
|
||||
if (strcmp(section, "*UND*") == 0)
|
||||
offset = 0xdeaddead;
|
||||
assert(strcmp(section, "*ABS*") != 0);
|
||||
addSymbol(s, section, offset);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -290,8 +292,8 @@ void ElfLinker::preprocessRelocations(char *start, char const *end) {
|
||||
|
||||
if (section) {
|
||||
addRelocation(section->name, offset, t, symbol, add);
|
||||
// printf("relocation %s %s %x %llu preprocessed\n", section->name, symbol, offset,
|
||||
// (unsigned long long) add);
|
||||
NO_printf("relocation %s %s %x %llu preprocessed\n", section->name, symbol, offset,
|
||||
(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,
|
||||
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)))
|
||||
return nullptr;
|
||||
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,
|
||||
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))
|
||||
symbols = static_cast<Symbol **>(realloc(symbols, nsymbols_capacity * sizeof(Symbol *)));
|
||||
assert(symbols != nullptr);
|
||||
@@ -363,7 +365,7 @@ ElfLinker::Relocation *ElfLinker::addRelocation(const char *section, unsigned of
|
||||
void ElfLinker::setLoaderAlignOffset(int phase)
|
||||
{
|
||||
//assert(phase & 0);
|
||||
printf("\nFIXME: ElfLinker::setLoaderAlignOffset %d\n", phase);
|
||||
NO_printf("\nFIXME: ElfLinker::setLoaderAlignOffset %d\n", phase);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -408,9 +410,11 @@ int ElfLinker::addLoader(const char *sname) {
|
||||
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);
|
||||
section->output = output + outputlen;
|
||||
// printf("section added: 0x%04x %3d %s\n", outputlen, section->size, section->name);
|
||||
section->output = output + outputlen; // FIXME: INVALIDATED by realloc()
|
||||
NO_printf("section added: 0x%04x %3d %s\n", outputlen, section->size, section->name);
|
||||
outputlen += section->size;
|
||||
|
||||
if (head) {
|
||||
@@ -479,11 +483,12 @@ void ElfLinker::relocate() {
|
||||
value = rel->value->section->offset + rel->value->offset + rel->add;
|
||||
}
|
||||
upx_byte *location = rel->section->output + rel->offset;
|
||||
// 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);
|
||||
// printf(" %llx %d %llx %d %llx : %d\n", (long long) value,
|
||||
// (int)rel->value->section->offset,
|
||||
// rel->value->offset, rel->offset, (long long) rel->add, *location);
|
||||
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);
|
||||
NO_printf(" %llx %d %llx %d %llx :%d\n", (long long) value,
|
||||
(int) rel->value->section->offset, rel->value->offset, rel->offset,
|
||||
(long long) rel->add, *location);
|
||||
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;
|
||||
if (strncmp(type, "PC", 2) == 0) {
|
||||
value -= rel->section->offset + rel->offset;
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
+3
-2
@@ -2,8 +2,8 @@
|
||||
|
||||
This file is part of the UPX executable compressor.
|
||||
|
||||
Copyright (C) 1996-2022 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2022 Laszlo Molnar
|
||||
Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2023 Laszlo Molnar
|
||||
All Rights Reserved.
|
||||
|
||||
UPX and the UCL library are free software; you can redistribute them
|
||||
@@ -46,6 +46,7 @@ protected:
|
||||
int inputlen = 0;
|
||||
upx_byte *output = nullptr;
|
||||
int outputlen = 0;
|
||||
unsigned output_capacity = 0;
|
||||
|
||||
Section *head = nullptr;
|
||||
Section *tail = nullptr;
|
||||
|
||||
+19
-7
@@ -2,8 +2,8 @@
|
||||
|
||||
This file is part of the UPX executable compressor.
|
||||
|
||||
Copyright (C) 1996-2022 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2022 Laszlo Molnar
|
||||
Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2023 Laszlo Molnar
|
||||
All Rights Reserved.
|
||||
|
||||
UPX and the UCL library are free software; you can redistribute them
|
||||
@@ -25,16 +25,22 @@
|
||||
<markus@oberhumer.com> <ezerotven+github@gmail.com>
|
||||
*/
|
||||
|
||||
// main entry, mostly boring stuff; see work.cpp for actual action
|
||||
|
||||
#include "conf.h"
|
||||
#include "compress.h"
|
||||
#include "file.h"
|
||||
#include "packer.h"
|
||||
#include "p_elf.h"
|
||||
#include "compress/compress.h" // upx_ucl_init()
|
||||
|
||||
/*************************************************************************
|
||||
// options
|
||||
**************************************************************************/
|
||||
|
||||
#ifndef OPTIONS_VAR
|
||||
#define OPTIONS_VAR "UPX"
|
||||
#endif
|
||||
|
||||
static const char *argv0 = "";
|
||||
const char *progname = "";
|
||||
|
||||
@@ -569,7 +575,7 @@ static int do_option(int optc, const char *arg) {
|
||||
case 525: // --exact
|
||||
opt->exact = true;
|
||||
break;
|
||||
// compression runtime parameters
|
||||
// CRP - Compression Runtime Parameters (undocumented and subject to change)
|
||||
case 801:
|
||||
getoptvar(&opt->crp.crp_ucl.c_flags, 0, 3, arg);
|
||||
break;
|
||||
@@ -866,7 +872,7 @@ int main_get_options(int argc, char **argv) {
|
||||
{"filter", 0x31, N, 521}, // --filter=
|
||||
{"no-filter", 0x10, N, 522},
|
||||
{"small", 0x10, N, 520},
|
||||
// compression runtime parameters
|
||||
// CRP - Compression Runtime Parameters (undocumented and subject to change)
|
||||
{"crp-nrv-cf", 0x31, N, 801},
|
||||
{"crp-nrv-sl", 0x31, N, 802},
|
||||
{"crp-nrv-hl", 0x31, N, 803},
|
||||
@@ -1201,12 +1207,18 @@ int upx_main(int argc, char *argv[]) {
|
||||
|
||||
set_term(stderr);
|
||||
|
||||
#if (WITH_BZIP2)
|
||||
assert(upx_bzip2_init() == 0);
|
||||
#endif
|
||||
assert(upx_lzma_init() == 0);
|
||||
assert(upx_ucl_init() == 0);
|
||||
assert(upx_zlib_init() == 0);
|
||||
#if (WITH_NRV)
|
||||
assert(upx_nrv_init() == 0);
|
||||
#endif
|
||||
assert(upx_ucl_init() == 0);
|
||||
assert(upx_zlib_init() == 0);
|
||||
#if (WITH_ZSTD)
|
||||
assert(upx_zstd_init() == 0);
|
||||
#endif
|
||||
|
||||
/* get options */
|
||||
first_options(argc, argv);
|
||||
|
||||
+36
-62
@@ -2,7 +2,7 @@
|
||||
|
||||
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.
|
||||
|
||||
UPX and the UCL library are free software; you can redistribute them
|
||||
@@ -27,7 +27,7 @@
|
||||
|
||||
#ifndef __ACC_H_INCLUDED
|
||||
#define __ACC_H_INCLUDED 1
|
||||
#define ACC_VERSION 20220904L
|
||||
#define ACC_VERSION 20230104L
|
||||
#if defined(__CYGWIN32__) && !defined(__CYGWIN__)
|
||||
# define __CYGWIN__ __CYGWIN32__
|
||||
#endif
|
||||
@@ -1561,7 +1561,7 @@ extern "C" {
|
||||
#endif
|
||||
#if !defined(ACC_BLOCK_BEGIN)
|
||||
# define ACC_BLOCK_BEGIN do {
|
||||
# define ACC_BLOCK_END } while __acc_cte(0)
|
||||
# define ACC_BLOCK_END } while (__acc_cte(0))
|
||||
#endif
|
||||
#if !defined(ACC_UNUSED)
|
||||
# if (ACC_CC_BORLANDC && (__BORLANDC__ >= 0x0600))
|
||||
@@ -1608,7 +1608,7 @@ extern "C" {
|
||||
# if (ACC_CC_CLANG >= 0x020800ul)
|
||||
# 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)
|
||||
# define ACC_UNUSED_LABEL(l) if __acc_cte(0) goto l
|
||||
# define ACC_UNUSED_LABEL(l) if (__acc_cte(0)) goto l
|
||||
# else
|
||||
# define ACC_UNUSED_LABEL(l) switch (0) case 1:goto l
|
||||
# endif
|
||||
@@ -2047,7 +2047,7 @@ extern "C" {
|
||||
# if (ACC_CC_IBMC)
|
||||
# define __acc_loop_forever() ACC_BLOCK_BEGIN for (;;) { ; } ACC_BLOCK_END
|
||||
# else
|
||||
# define __acc_loop_forever() do { ; } while __acc_cte(1)
|
||||
# define __acc_loop_forever() do { ; } while (__acc_cte(1))
|
||||
# endif
|
||||
#endif
|
||||
#if !defined(__acc_unreachable)
|
||||
@@ -2079,11 +2079,11 @@ extern "C" {
|
||||
# define acc_unused_funcs_impl(r,f) __acc_static_forceinline r f
|
||||
# endif
|
||||
#endif
|
||||
#ifndef __ACC_CTA_NAME
|
||||
#ifndef ACC_CTA_INTERNAL_NAME__
|
||||
#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
|
||||
# define __ACC_CTA_NAME(a) ACC_PP_ECONCAT2(a,__LINE__)
|
||||
# define ACC_CTA_INTERNAL_NAME__(a) ACC_PP_ECONCAT2(a,__LINE__)
|
||||
#endif
|
||||
#endif
|
||||
#if !defined(ACC_COMPILE_TIME_ASSERT_HEADER)
|
||||
@@ -2092,17 +2092,17 @@ extern "C" {
|
||||
# elif (ACC_LANG_C >= 201112L)
|
||||
# define ACC_COMPILE_TIME_ASSERT_HEADER(e) _Static_assert(e, #e);
|
||||
# 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)
|
||||
# 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))
|
||||
# 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)
|
||||
# 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__)
|
||||
# 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
|
||||
# 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
|
||||
#if !defined(ACC_COMPILE_TIME_ASSERT)
|
||||
@@ -2111,23 +2111,23 @@ extern "C" {
|
||||
# elif (ACC_LANG_C >= 201112L)
|
||||
# define ACC_COMPILE_TIME_ASSERT(e) {_Static_assert(e, #e);}
|
||||
# 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))
|
||||
# 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)
|
||||
# define ACC_COMPILE_TIME_ASSERT(e) switch(0) case 1:case !(e):break;
|
||||
# elif (ACC_CC_GNUC) && defined(__CHECKER__) && defined(__SPARSE_CHECKER__)
|
||||
# define ACC_COMPILE_TIME_ASSERT(e) {(void) (0/!!(e));}
|
||||
# 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)
|
||||
# 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))
|
||||
# define ACC_COMPILE_TIME_ASSERT(e) switch(0) case 1:case !(e):break;
|
||||
# elif (ACC_CC_TURBOC && (__TURBOC__ == 0x0295))
|
||||
# define ACC_COMPILE_TIME_ASSERT(e) switch(0) case 1:case !(e):break;
|
||||
# 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
|
||||
#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_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
|
||||
#elif (ACC_ARCH_IA64) && (ACC_OS_POSIX_LINUX || ACC_OS_WIN64)
|
||||
# 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
|
||||
# endif
|
||||
#elif (ACC_ARCH_ARM)
|
||||
# if defined(__ARM_FEATURE_UNALIGNED)
|
||||
# if ((__ARM_FEATURE_UNALIGNED)+0)
|
||||
# if defined(__ARM_FEATURE_UNALIGNED) && (__ARM_FEATURE_UNALIGNED+0)
|
||||
# ifndef ACC_OPT_UNALIGNED16
|
||||
# define ACC_OPT_UNALIGNED16 1
|
||||
# endif
|
||||
# ifndef ACC_OPT_UNALIGNED32
|
||||
# define ACC_OPT_UNALIGNED32 1
|
||||
# endif
|
||||
# endif
|
||||
# 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))
|
||||
# elif defined(__TARGET_FEATURE_UNALIGNED) && (__TARGET_FEATURE_UNALIGNED+0)
|
||||
# ifndef ACC_OPT_UNALIGNED16
|
||||
# define ACC_OPT_UNALIGNED16 1
|
||||
# endif
|
||||
@@ -2822,34 +2803,21 @@ ACC_COMPILE_TIME_ASSERT_HEADER(ACC_SIZEOF_PTRDIFF_T == sizeof(ptrdiff_t))
|
||||
#elif (ACC_ARCH_POWERPC)
|
||||
# define ACC_OPT_PREFER_PREINC 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
|
||||
# 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_RISCV)
|
||||
# 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_RISCV)
|
||||
# define ACC_OPT_AVOID_UINT_INDEX 1
|
||||
#elif (ACC_ARCH_S390)
|
||||
# ifndef ACC_OPT_UNALIGNED16
|
||||
# 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
|
||||
#elif (ACC_LIBC_MOSTLY_FREESTANDING)
|
||||
# define HAVE_LIMITS_H 1
|
||||
# ifndef HAVE_SETJMP_H
|
||||
# define HAVE_SETJMP_H 1
|
||||
# endif
|
||||
# define HAVE_STDARG_H 1
|
||||
# define HAVE_STDDEF_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_MALLOC_H 1
|
||||
#define HAVE_MEMORY_H 1
|
||||
#ifndef HAVE_SETJMP_H
|
||||
#define HAVE_SETJMP_H 1
|
||||
#endif
|
||||
#ifndef HAVE_SIGNAL_H
|
||||
#define HAVE_SIGNAL_H 1
|
||||
#endif
|
||||
#define HAVE_STDARG_H 1
|
||||
#define HAVE_STDDEF_H 1
|
||||
#define HAVE_STDIO_H 1
|
||||
@@ -4804,7 +4778,7 @@ typedef long acc_fallback_ptrdiff_t;
|
||||
#if defined(__SIZE_TYPE__)
|
||||
typedef __SIZE_TYPE__ acc_fallback_size_t;
|
||||
#elif defined(_WIN64)
|
||||
typedef unsigned long long acc_fallback_ptrdiff_t;
|
||||
typedef unsigned long long acc_fallback_size_t;
|
||||
#elif defined(__MIPS_PSX2__)
|
||||
typedef unsigned acc_fallback_size_t;
|
||||
#else
|
||||
|
||||
+59
-94
@@ -2,8 +2,8 @@
|
||||
|
||||
This file is part of the UPX executable compressor.
|
||||
|
||||
Copyright (C) 1996-2022 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2022 Laszlo Molnar
|
||||
Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2023 Laszlo Molnar
|
||||
All Rights Reserved.
|
||||
|
||||
UPX and the UCL library are free software; you can redistribute them
|
||||
@@ -25,10 +25,8 @@
|
||||
<markus@oberhumer.com> <ezerotven+github@gmail.com>
|
||||
*/
|
||||
|
||||
|
||||
#include "conf.h"
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
// FIXME: if stdout is redirected to a file and stderr is not, should
|
||||
// we write all error messages to both stderr and stdout ?
|
||||
@@ -36,25 +34,20 @@
|
||||
|
||||
static int pr_need_nl = 0;
|
||||
|
||||
void printSetNl(int need_nl) { pr_need_nl = need_nl; }
|
||||
|
||||
void printSetNl(int need_nl)
|
||||
{
|
||||
pr_need_nl = need_nl;
|
||||
}
|
||||
|
||||
void printClearLine(FILE *f)
|
||||
{
|
||||
static char clear_line_msg[1+79+1+1];
|
||||
if (!clear_line_msg[0])
|
||||
{
|
||||
void printClearLine(FILE *f) {
|
||||
static char clear_line_msg[1 + 79 + 1 + 1];
|
||||
if (!clear_line_msg[0]) {
|
||||
char *msg = clear_line_msg;
|
||||
msg[0] = '\r';
|
||||
memset(msg+1,' ',79);
|
||||
memset(msg + 1, ' ', 79);
|
||||
msg[80] = '\r';
|
||||
msg[81] = 0;
|
||||
}
|
||||
|
||||
fflush(stdout); fflush(stderr);
|
||||
fflush(stdout);
|
||||
fflush(stderr);
|
||||
if (f == nullptr)
|
||||
f = stdout;
|
||||
con_fprintf(f, "%s", clear_line_msg);
|
||||
@@ -62,24 +55,21 @@ void printClearLine(FILE *f)
|
||||
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)
|
||||
con_fprintf(stderr, "%s", msg);
|
||||
else
|
||||
fprintf(stderr, "%s", msg);
|
||||
}
|
||||
|
||||
static void pr_error(const char *iname, const char *msg, bool is_warning)
|
||||
{
|
||||
fflush(stdout); fflush(stderr);
|
||||
static void pr_error(const char *iname, const char *msg, bool is_warning) {
|
||||
fflush(stdout);
|
||||
fflush(stderr);
|
||||
char buf[1024];
|
||||
buf[0] = 0;
|
||||
if (pr_need_nl == 2)
|
||||
printClearLine(stdout);
|
||||
else if (pr_need_nl)
|
||||
{
|
||||
else if (pr_need_nl) {
|
||||
buf[0] = '\n';
|
||||
buf[1] = 0;
|
||||
printSetNl(0);
|
||||
@@ -90,35 +80,34 @@ static void pr_error(const char *iname, const char *msg, bool is_warning)
|
||||
// At least I can use some colors then...
|
||||
bool c = acc_isatty(STDERR_FILENO) ? 1 : 0;
|
||||
|
||||
int fg = con_fg(stderr,FG_BRTRED);
|
||||
snprintf(buf+strlen(buf),sizeof(buf)-strlen(buf),"%s: ", progname);
|
||||
pr_print(c,buf);
|
||||
int fg = con_fg(stderr, FG_BRTRED);
|
||||
snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "%s: ", progname);
|
||||
pr_print(c, buf);
|
||||
//(void)con_fg(stderr,FG_RED);
|
||||
snprintf(buf,sizeof(buf),"%s: ", iname);
|
||||
pr_print(c,buf);
|
||||
snprintf(buf, sizeof(buf), "%s: ", iname);
|
||||
pr_print(c, buf);
|
||||
//(void)con_fg(stderr,FG_BRTRED);
|
||||
pr_print(c,msg);
|
||||
pr_print(c,"\n");
|
||||
fflush(stdout); fflush(stderr);
|
||||
fg = con_fg(stderr,fg);
|
||||
pr_print(c, msg);
|
||||
pr_print(c, "\n");
|
||||
fflush(stdout);
|
||||
fflush(stderr);
|
||||
fg = con_fg(stderr, fg);
|
||||
|
||||
UNUSED(is_warning);
|
||||
UNUSED(fg);
|
||||
}
|
||||
|
||||
|
||||
void printErr(const char *iname, const Throwable *e)
|
||||
{
|
||||
void printErr(const char *iname, const Throwable *e) {
|
||||
char buf[1024];
|
||||
size_t l;
|
||||
|
||||
snprintf(buf, sizeof(buf), "%s", prettyName(typeid(*e).name()));
|
||||
l = strlen(buf);
|
||||
if (l < sizeof(buf) && e->getMsg())
|
||||
snprintf(buf+l, sizeof(buf)-l, ": %s", e->getMsg());
|
||||
snprintf(buf + l, sizeof(buf) - l, ": %s", e->getMsg());
|
||||
l = strlen(buf);
|
||||
if (l < sizeof(buf) && e->getErrno()) {
|
||||
snprintf(buf+l, sizeof(buf)-l, ": %s", strerror(e->getErrno()));
|
||||
snprintf(buf + l, sizeof(buf) - l, ": %s", strerror(e->getErrno()));
|
||||
#if 1
|
||||
// some compilers (e.g. Borland C++) put a trailing '\n'
|
||||
// into strerror() result
|
||||
@@ -127,127 +116,103 @@ void printErr(const char *iname, const Throwable *e)
|
||||
buf[l] = 0;
|
||||
#endif
|
||||
}
|
||||
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;
|
||||
char buf[1024];
|
||||
|
||||
va_start(args,format);
|
||||
upx_safe_vsnprintf(buf,sizeof(buf),format,args);
|
||||
va_start(args, format);
|
||||
upx_safe_vsnprintf(buf, sizeof(buf), format, args);
|
||||
va_end(args);
|
||||
|
||||
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;
|
||||
char buf[1024];
|
||||
|
||||
va_start(args,format);
|
||||
upx_safe_vsnprintf(buf,sizeof(buf),format,args);
|
||||
va_start(args, format);
|
||||
upx_safe_vsnprintf(buf, sizeof(buf), format, args);
|
||||
va_end(args);
|
||||
|
||||
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)
|
||||
printErr(iname,"unhandled exception: %s\n", prettyName(e->what()));
|
||||
printErr(iname, "unhandled exception: %s\n", prettyName(e->what()));
|
||||
else
|
||||
printErr(iname,"internal error: unhandled exception!\n");
|
||||
if (opt->cmd != CMD_COMPRESS)
|
||||
{
|
||||
printErr(iname," this file has possibly been modified/hacked; take care!\n");
|
||||
printErr(iname, "internal error: unhandled exception!\n");
|
||||
if (opt->cmd != CMD_COMPRESS) {
|
||||
printErr(iname, " this file has possibly been modified/hacked; take care!\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
// FIXME: should use colors and a consistent layout here
|
||||
**************************************************************************/
|
||||
|
||||
static int info_header = 0;
|
||||
|
||||
|
||||
static void info_print(const char *msg)
|
||||
{
|
||||
static void info_print(const char *msg) {
|
||||
if (opt->info_mode <= 0)
|
||||
return;
|
||||
FILE *f = opt->to_stdout ? stderr : stdout;
|
||||
if (pr_need_nl)
|
||||
{
|
||||
if (pr_need_nl) {
|
||||
printClearLine(f);
|
||||
con_fprintf(f,"%s\n",msg);
|
||||
}
|
||||
else if (pr_need_nl)
|
||||
con_fprintf(f,"\n%s\n",msg);
|
||||
con_fprintf(f, "%s\n", msg);
|
||||
} else if (pr_need_nl)
|
||||
con_fprintf(f, "\n%s\n", msg);
|
||||
else
|
||||
con_fprintf(f,"%s\n",msg);
|
||||
con_fprintf(f, "%s\n", msg);
|
||||
fflush(f);
|
||||
printSetNl(0);
|
||||
}
|
||||
|
||||
void infoHeader() { info_header = 0; }
|
||||
|
||||
void infoHeader()
|
||||
{
|
||||
info_header = 0;
|
||||
}
|
||||
|
||||
void infoHeader(const char *format, ...)
|
||||
{
|
||||
void infoHeader(const char *format, ...) {
|
||||
if (opt->info_mode <= 0)
|
||||
return;
|
||||
va_list args;
|
||||
char buf[1024];
|
||||
va_start(args,format);
|
||||
upx_safe_vsnprintf(buf,sizeof(buf),format,args);
|
||||
va_start(args, format);
|
||||
upx_safe_vsnprintf(buf, sizeof(buf), format, args);
|
||||
va_end(args);
|
||||
info_print(buf);
|
||||
info_header = 1;
|
||||
}
|
||||
|
||||
|
||||
void info(const char *format, ...)
|
||||
{
|
||||
void info(const char *format, ...) {
|
||||
if (opt->info_mode <= 0)
|
||||
return;
|
||||
va_list args;
|
||||
char buf[1024];
|
||||
const int n = 4 * info_header;
|
||||
memset(buf, ' ', n);
|
||||
va_start(args,format);
|
||||
upx_safe_vsnprintf(buf+n,sizeof(buf)-n,format,args);
|
||||
va_start(args, format);
|
||||
upx_safe_vsnprintf(buf + n, sizeof(buf) - n, format, args);
|
||||
va_end(args);
|
||||
info_print(buf);
|
||||
}
|
||||
|
||||
|
||||
void infoWarning(const char *format, ...)
|
||||
{
|
||||
if (opt->info_mode <= 0)
|
||||
{
|
||||
void infoWarning(const char *format, ...) {
|
||||
if (opt->info_mode <= 0) {
|
||||
// FIXME - should still print something here
|
||||
return;
|
||||
}
|
||||
va_list args;
|
||||
char buf[1024];
|
||||
va_start(args,format);
|
||||
upx_safe_vsnprintf(buf,sizeof(buf),format,args);
|
||||
va_start(args, format);
|
||||
upx_safe_vsnprintf(buf, sizeof(buf), format, args);
|
||||
va_end(args);
|
||||
info("[WARNING] %s\n", buf);
|
||||
}
|
||||
|
||||
|
||||
void infoWriting(const char *what, long size)
|
||||
{
|
||||
void infoWriting(const char *what, long size) {
|
||||
if (opt->info_mode <= 0)
|
||||
return;
|
||||
info("Writing %s: %ld bytes", what, size);
|
||||
|
||||
+16
-9
@@ -2,8 +2,8 @@
|
||||
|
||||
This file is part of the UPX executable compressor.
|
||||
|
||||
Copyright (C) 1996-2022 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2022 Laszlo Molnar
|
||||
Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2023 Laszlo Molnar
|
||||
All Rights Reserved.
|
||||
|
||||
UPX and the UCL library are free software; you can redistribute them
|
||||
@@ -27,8 +27,11 @@
|
||||
|
||||
#include "conf.h"
|
||||
|
||||
static options_t global_options;
|
||||
options_t *opt = &global_options; // also see class PackMaster
|
||||
|
||||
/*************************************************************************
|
||||
// options
|
||||
// reset
|
||||
**************************************************************************/
|
||||
|
||||
void options_t::reset() {
|
||||
@@ -57,7 +60,7 @@ void options_t::reset() {
|
||||
#endif
|
||||
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_icons = 2;
|
||||
@@ -69,20 +72,24 @@ void options_t::reset() {
|
||||
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>
|
||||
static inline void test_options(const char *(&a)[N]) {
|
||||
(void) main_get_options((int) (N - 1), ACC_UNCONST_CAST(char **, a));
|
||||
}
|
||||
|
||||
TEST_CASE("getopt") {
|
||||
options_t *saved_opt = opt;
|
||||
options_t *const saved_opt = opt;
|
||||
options_t local_options;
|
||||
opt = &local_options;
|
||||
opt->reset();
|
||||
|
||||
+12
-13
@@ -2,8 +2,8 @@
|
||||
|
||||
This file is part of the UPX executable compressor.
|
||||
|
||||
Copyright (C) 1996-2022 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2022 Laszlo Molnar
|
||||
Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2023 Laszlo Molnar
|
||||
All Rights Reserved.
|
||||
|
||||
UPX and the UCL library are free software; you can redistribute them
|
||||
@@ -43,10 +43,10 @@ enum {
|
||||
CMD_FILEINFO,
|
||||
CMD_HELP,
|
||||
CMD_LICENSE,
|
||||
CMD_VERSION
|
||||
CMD_VERSION,
|
||||
};
|
||||
|
||||
struct options_t {
|
||||
struct options_t final {
|
||||
int cmd;
|
||||
|
||||
// compression options
|
||||
@@ -96,7 +96,8 @@ struct options_t {
|
||||
enum { SKIP_OVERLAY = 0, COPY_OVERLAY = 1, STRIP_OVERLAY = 2 };
|
||||
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 {
|
||||
lzma_compress_config_t crp_lzma;
|
||||
ucl_compress_config_t crp_ucl;
|
||||
@@ -116,8 +117,6 @@ struct options_t {
|
||||
CPU_286 = 2,
|
||||
CPU_386 = 3,
|
||||
CPU_486 = 4,
|
||||
CPU_586 = 5,
|
||||
CPU_686 = 6
|
||||
};
|
||||
int cpu;
|
||||
|
||||
@@ -132,12 +131,6 @@ struct options_t {
|
||||
bool force_stub;
|
||||
bool no_reloc;
|
||||
} dos_exe;
|
||||
struct {
|
||||
bool boot_only;
|
||||
bool no_align;
|
||||
bool do_8bit;
|
||||
bool do_8mib;
|
||||
} ps1_exe;
|
||||
struct {
|
||||
unsigned blocksize;
|
||||
bool force_execve; // force the linux/386 execve format
|
||||
@@ -150,6 +143,12 @@ struct options_t {
|
||||
bool android_shlib; // keep some ElfXX_Shdr for dlopen()
|
||||
bool force_pie; // choose DF_1_PIE instead of is_shlib
|
||||
} o_unix;
|
||||
struct {
|
||||
bool boot_only;
|
||||
bool no_align;
|
||||
bool do_8bit;
|
||||
bool do_8mib;
|
||||
} ps1_exe;
|
||||
struct {
|
||||
bool le;
|
||||
} watcom_le;
|
||||
|
||||
+49
-83
@@ -2,8 +2,8 @@
|
||||
|
||||
This file is part of the UPX executable compressor.
|
||||
|
||||
Copyright (C) 1996-2022 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2022 Laszlo Molnar
|
||||
Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2023 Laszlo Molnar
|
||||
All Rights Reserved.
|
||||
|
||||
UPX and the UCL library are free software; you can redistribute them
|
||||
@@ -25,7 +25,6 @@
|
||||
<markus@oberhumer.com> <ezerotven+github@gmail.com>
|
||||
*/
|
||||
|
||||
|
||||
#include "conf.h"
|
||||
#include "file.h"
|
||||
#include "filter.h"
|
||||
@@ -34,55 +33,45 @@
|
||||
#include "p_armpe.h"
|
||||
#include "linker.h"
|
||||
|
||||
static const
|
||||
static const CLANG_FORMAT_DUMMY_STATEMENT
|
||||
#include "stub/arm.v4a-wince.pe.h"
|
||||
static const
|
||||
static const CLANG_FORMAT_DUMMY_STATEMENT
|
||||
#include "stub/arm.v4t-wince.pe.h"
|
||||
|
||||
/*************************************************************************
|
||||
//
|
||||
**************************************************************************/
|
||||
|
||||
PackArmPe::PackArmPe(InputFile *f) : super(f)
|
||||
{
|
||||
use_thumb_stub = false;
|
||||
}
|
||||
PackArmPe::PackArmPe(InputFile *f) : super(f) {}
|
||||
|
||||
PackArmPe::~PackArmPe() {}
|
||||
|
||||
PackArmPe::~PackArmPe()
|
||||
{}
|
||||
|
||||
|
||||
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_lzma[] = { M_LZMA, M_END };
|
||||
static const int m_nrv2b[] = { M_NRV2B_8, M_END };
|
||||
static const int m_nrv2e[] = { M_NRV2E_8, M_END };
|
||||
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_lzma[] = {M_LZMA, M_END};
|
||||
static const int m_nrv2b[] = {M_NRV2B_8, M_END};
|
||||
static const int m_nrv2e[] = {M_NRV2E_8, M_END};
|
||||
|
||||
if (!use_thumb_stub)
|
||||
return getDefaultCompressionMethods_8(method, level);
|
||||
|
||||
if (method == M_ALL) return m_all;
|
||||
if (M_IS_LZMA(method)) return m_lzma;
|
||||
if (M_IS_NRV2B(method)) return m_nrv2b;
|
||||
if (M_IS_NRV2E(method)) return m_nrv2e;
|
||||
if (method == M_ALL)
|
||||
return m_all;
|
||||
if (M_IS_LZMA(method))
|
||||
return m_lzma;
|
||||
if (M_IS_NRV2B(method))
|
||||
return m_nrv2b;
|
||||
if (M_IS_NRV2E(method))
|
||||
return m_nrv2e;
|
||||
return m_nrv2e;
|
||||
}
|
||||
|
||||
|
||||
const int *PackArmPe::getFilters() const
|
||||
{
|
||||
static const int filters[] = { 0x50, FT_END };
|
||||
const int *PackArmPe::getFilters() const {
|
||||
static const int filters[] = {0x50, FT_END};
|
||||
return filters;
|
||||
}
|
||||
|
||||
|
||||
Linker* PackArmPe::newLinker() const
|
||||
{
|
||||
return new ElfLinkerArmLE;
|
||||
}
|
||||
|
||||
Linker *PackArmPe::newLinker() const { return new ElfLinkerArmLE; }
|
||||
|
||||
/*************************************************************************
|
||||
// import handling
|
||||
@@ -93,17 +82,14 @@ void PackArmPe::processImports2(unsigned myimport, unsigned iat_off) // pass 2
|
||||
PeFile::processImports2(myimport, iat_off);
|
||||
|
||||
// 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;
|
||||
bool is_coredll = strcasecmp(kernelDll(), (char*) oimpdlls +
|
||||
im->dllname - myimport) == 0;
|
||||
bool is_coredll = strcasecmp(kernelDll(), oimpdlls + (im->dllname - myimport)) == 0;
|
||||
im->iat = is_coredll ? iat_off : iat_off + 12;
|
||||
}
|
||||
}
|
||||
|
||||
void PackArmPe::addStubImports()
|
||||
{
|
||||
void PackArmPe::addStubImports() {
|
||||
// the order of procedure names below should match the
|
||||
// assumptions of the assembly stubs
|
||||
// WARNING! these names are sorted alphanumerically by the ImportLinker
|
||||
@@ -114,20 +100,18 @@ void PackArmPe::addStubImports()
|
||||
|
||||
void PackArmPe::processTls(Interval *) // pass 1
|
||||
{
|
||||
if ((sotls = ALIGN_UP(IDSIZE(PEDIR_TLS),4u)) == 0)
|
||||
if ((sotls = ALIGN_UP(IDSIZE(PEDIR_TLS), 4u)) == 0)
|
||||
return;
|
||||
|
||||
// never should happen on wince
|
||||
throwCantPack("Static TLS entries found. Send a report please.");
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
// pack
|
||||
**************************************************************************/
|
||||
|
||||
bool PackArmPe::canPack()
|
||||
{
|
||||
bool PackArmPe::canPack() {
|
||||
if (!readFileHeader() || (ih.cpu != 0x1c0 && ih.cpu != 0x1c2))
|
||||
return false;
|
||||
use_thumb_stub |= ih.cpu == 0x1c2 || (ih.entry & 1) == 1;
|
||||
@@ -135,9 +119,7 @@ bool PackArmPe::canPack()
|
||||
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;
|
||||
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))
|
||||
addLoader("+40C,CallLZMA", nullptr);
|
||||
|
||||
|
||||
if (ft->id == 0x50)
|
||||
addLoader("+40C,Unfilter_0x50", nullptr);
|
||||
|
||||
@@ -179,48 +160,38 @@ void PackArmPe::buildLoader(const Filter *ft)
|
||||
addLoader("IDENTSTR,UPX1HEAD", nullptr);
|
||||
}
|
||||
|
||||
bool PackArmPe::handleForceOption()
|
||||
{
|
||||
return (ih.cpu != 0x1c0 && ih.cpu != 0x1c2)
|
||||
|| (ih.opthdrsize != 0xe0)
|
||||
|| ((ih.flags & EXECUTABLE) == 0)
|
||||
|| (ih.entry == 0 /*&& !isdll*/)
|
||||
|| (ih.ddirsentries != 16)
|
||||
// || IDSIZE(PEDIR_EXCEPTION) // is this used on arm?
|
||||
// || IDSIZE(PEDIR_COPYRIGHT)
|
||||
;
|
||||
bool PackArmPe::handleForceOption() {
|
||||
return (ih.cpu != 0x1c0 && ih.cpu != 0x1c2) || (ih.opthdrsize != 0xe0) ||
|
||||
((ih.flags & EXECUTABLE) == 0) || (ih.entry == 0 /*&& !isdll*/) ||
|
||||
(ih.ddirsentries != 16);
|
||||
// || IDSIZE(PEDIR_EXCEPTION) // is this used on arm?
|
||||
// || 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
|
||||
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
|
||||
compressWithFilters(&ft, 2048, &cconf, filter_strategy,
|
||||
ih_codebase, rvamin, 0, nullptr, 0);
|
||||
compressWithFilters(&ft, 2048, &cconf, filter_strategy, ih_codebase, rvamin, 0, nullptr, 0);
|
||||
}
|
||||
|
||||
void PackArmPe::addNewRelocations(Reloc &rel, unsigned upxsection)
|
||||
{
|
||||
static const char* symbols_to_relocate[] = {
|
||||
"ONAM", "BIMP", "BREL", "FIBE", "FIBS", "ENTR", "DST0", "SRC0"
|
||||
};
|
||||
for (unsigned s2r = 0; s2r < TABLESIZE(symbols_to_relocate); s2r++)
|
||||
{
|
||||
void PackArmPe::addNewRelocations(Reloc &rel, unsigned upxsection) {
|
||||
static const char *const symbols_to_relocate[] = {"ONAM", "BIMP", "BREL", "FIBE",
|
||||
"FIBS", "ENTR", "DST0", "SRC0"};
|
||||
for (unsigned s2r = 0; s2r < TABLESIZE(symbols_to_relocate); s2r++) {
|
||||
unsigned off = linker->getSymbolOffset(symbols_to_relocate[s2r]);
|
||||
if (off != 0xdeaddead)
|
||||
rel.add(off + upxsection, 3);
|
||||
}
|
||||
}
|
||||
|
||||
unsigned PackArmPe::getProcessImportParam(unsigned upxsection)
|
||||
{
|
||||
unsigned PackArmPe::getProcessImportParam(unsigned upxsection) {
|
||||
return linker->getSymbolOffset("IATT") + upxsection;
|
||||
}
|
||||
|
||||
void PackArmPe::defineSymbols(unsigned ncsection, unsigned, unsigned,
|
||||
unsigned ic, unsigned s1addr)
|
||||
{
|
||||
void PackArmPe::defineSymbols(unsigned ncsection, unsigned, unsigned, unsigned ic,
|
||||
unsigned s1addr) {
|
||||
const unsigned onam = ncsection + soxrelocs + ih.imagebase;
|
||||
linker->defineSymbol("start_of_dll_names", onam);
|
||||
linker->defineSymbol("start_of_imports", ih.imagebase + rvamin + cimports);
|
||||
@@ -235,19 +206,14 @@ void PackArmPe::defineSymbols(unsigned ncsection, unsigned, unsigned,
|
||||
defineDecompressorSymbols();
|
||||
}
|
||||
|
||||
void PackArmPe::setOhDataBase(const pe_section_t *osection)
|
||||
{
|
||||
oh.database = osection[2].vaddr;
|
||||
}
|
||||
void PackArmPe::setOhDataBase(const pe_section_t *osection) { 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;
|
||||
}
|
||||
|
||||
void PackArmPe::pack(OutputFile *fo)
|
||||
{
|
||||
super::pack0(fo, (1u<<IMAGE_SUBSYSTEM_WINDOWS_CE_GUI), 0x10000, true);
|
||||
void PackArmPe::pack(OutputFile *fo) {
|
||||
super::pack0(fo, (1u << IMAGE_SUBSYSTEM_WINDOWS_CE_GUI), 0x10000, true);
|
||||
}
|
||||
|
||||
/* vim:set ts=4 sw=4 et: */
|
||||
|
||||
+10
-14
@@ -2,8 +2,8 @@
|
||||
|
||||
This file is part of the UPX executable compressor.
|
||||
|
||||
Copyright (C) 1996-2022 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2022 Laszlo Molnar
|
||||
Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2023 Laszlo Molnar
|
||||
All Rights Reserved.
|
||||
|
||||
UPX and the UCL library are free software; you can redistribute them
|
||||
@@ -25,17 +25,15 @@
|
||||
<markus@oberhumer.com> <ezerotven+github@gmail.com>
|
||||
*/
|
||||
|
||||
|
||||
#ifndef __UPX_P_ARMPE_H
|
||||
#define __UPX_P_ARMPE_H 1
|
||||
|
||||
#pragma once
|
||||
#ifndef UPX_P_ARMPE_H__
|
||||
#define UPX_P_ARMPE_H__ 1
|
||||
|
||||
/*************************************************************************
|
||||
// arm/pe
|
||||
**************************************************************************/
|
||||
|
||||
class PackArmPe : public PeFile32
|
||||
{
|
||||
class PackArmPe final : public PeFile32 {
|
||||
typedef PeFile32 super;
|
||||
|
||||
public:
|
||||
@@ -51,9 +49,8 @@ public:
|
||||
virtual bool handleForceOption() override;
|
||||
virtual void callCompressWithFilters(Filter &, int filter_strategy,
|
||||
unsigned ih_codebase) override;
|
||||
virtual void defineSymbols(unsigned ncsection, unsigned upxsection,
|
||||
unsigned sizeof_oh, unsigned isize_isplit,
|
||||
unsigned s1addr) override;
|
||||
virtual void defineSymbols(unsigned ncsection, unsigned upxsection, unsigned sizeof_oh,
|
||||
unsigned isize_isplit, unsigned s1addr) override;
|
||||
virtual void addNewRelocations(Reloc &, unsigned upxsection) override;
|
||||
virtual unsigned getProcessImportParam(unsigned upxsection) override;
|
||||
virtual void setOhDataBase(const pe_section_t *osection) override;
|
||||
@@ -64,7 +61,7 @@ public:
|
||||
|
||||
protected:
|
||||
virtual void buildLoader(const Filter *ft) override;
|
||||
virtual Linker* newLinker() const override;
|
||||
virtual Linker *newLinker() const override;
|
||||
|
||||
virtual const char *kernelDll() const override { return "COREDLL.dll"; }
|
||||
virtual void processImports2(unsigned, unsigned) override;
|
||||
@@ -72,10 +69,9 @@ protected:
|
||||
|
||||
virtual void processTls(Interval *) override;
|
||||
|
||||
bool use_thumb_stub;
|
||||
bool use_thumb_stub = false;
|
||||
};
|
||||
|
||||
|
||||
#endif /* already included */
|
||||
|
||||
/* vim:set ts=4 sw=4 et: */
|
||||
|
||||
+47
-87
@@ -2,8 +2,8 @@
|
||||
|
||||
This file is part of the UPX executable compressor.
|
||||
|
||||
Copyright (C) 1996-2022 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2022 Laszlo Molnar
|
||||
Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2023 Laszlo Molnar
|
||||
All Rights Reserved.
|
||||
|
||||
UPX and the UCL library are free software; you can redistribute them
|
||||
@@ -25,7 +25,6 @@
|
||||
<markus@oberhumer.com> <ezerotven+github@gmail.com>
|
||||
*/
|
||||
|
||||
|
||||
#include "conf.h"
|
||||
#include "file.h"
|
||||
#include "filter.h"
|
||||
@@ -33,49 +32,42 @@
|
||||
#include "p_com.h"
|
||||
#include "linker.h"
|
||||
|
||||
static const
|
||||
static const CLANG_FORMAT_DUMMY_STATEMENT
|
||||
#include "stub/i086-dos16.com.h"
|
||||
|
||||
//#define TESTING 1
|
||||
|
||||
// #define TESTING 1
|
||||
|
||||
/*************************************************************************
|
||||
//
|
||||
**************************************************************************/
|
||||
|
||||
const int *PackCom::getCompressionMethods(int method, int level) const
|
||||
{
|
||||
static const int m_nrv2b[] = { M_NRV2B_LE16, M_END };
|
||||
const int *PackCom::getCompressionMethods(int method, int level) const {
|
||||
static const int m_nrv2b[] = {M_NRV2B_LE16, M_END};
|
||||
#if 0
|
||||
static const int m_nrv2d[] = { M_NRV2D_LE16, M_END };
|
||||
#endif
|
||||
UNUSED(method); UNUSED(level);
|
||||
UNUSED(method);
|
||||
UNUSED(level);
|
||||
return m_nrv2b;
|
||||
}
|
||||
|
||||
|
||||
const int *PackCom::getFilters() const
|
||||
{
|
||||
static const int filters[] = {
|
||||
0x06, 0x03, 0x04, 0x01, 0x05, 0x02,
|
||||
FT_END };
|
||||
const int *PackCom::getFilters() const {
|
||||
static const int filters[] = {0x06, 0x03, 0x04, 0x01, 0x05, 0x02, FT_END};
|
||||
return filters;
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
//
|
||||
**************************************************************************/
|
||||
|
||||
bool PackCom::canPack()
|
||||
{
|
||||
bool PackCom::canPack() {
|
||||
unsigned char buf[128];
|
||||
|
||||
fi->readx(buf, sizeof(buf));
|
||||
if (memcmp(buf,"MZ",2) == 0 || memcmp(buf,"ZM",2) == 0 // .exe
|
||||
|| memcmp (buf,"\xff\xff\xff\xff",4) == 0) // .sys
|
||||
if (memcmp(buf, "MZ", 2) == 0 || memcmp(buf, "ZM", 2) == 0 // .exe
|
||||
|| memcmp(buf, "\xff\xff\xff\xff", 4) == 0) // .sys
|
||||
return false;
|
||||
if (!fn_has_ext(fi->getName(),"com"))
|
||||
if (!fn_has_ext(fi->getName(), "com"))
|
||||
return false;
|
||||
checkAlreadyPacked(buf, sizeof(buf));
|
||||
if (file_size < 1024)
|
||||
@@ -85,15 +77,11 @@ bool PackCom::canPack()
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
//
|
||||
**************************************************************************/
|
||||
|
||||
void PackCom::patchLoader(OutputFile *fo,
|
||||
upx_byte *loader, int lsize,
|
||||
unsigned calls)
|
||||
{
|
||||
void PackCom::patchLoader(OutputFile *fo, upx_byte *loader, int lsize, unsigned calls) {
|
||||
const int e_len = getLoaderSectionStart("COMCUTPO");
|
||||
const int d_len = lsize - e_len;
|
||||
assert(e_len > 0 && e_len < 128);
|
||||
@@ -118,11 +106,11 @@ void PackCom::patchLoader(OutputFile *fo,
|
||||
loader = getLoader();
|
||||
|
||||
// some day we could use the relocation stuff for patchPackHeader too
|
||||
patchPackHeader(loader,e_len);
|
||||
patchPackHeader(loader, e_len);
|
||||
// write loader + compressed file
|
||||
fo->write(loader,e_len); // entry
|
||||
fo->write(obuf,ph.c_len);
|
||||
fo->write(loader+e_len,d_len); // decompressor
|
||||
fo->write(loader, e_len); // entry
|
||||
fo->write(obuf, ph.c_len);
|
||||
fo->write(loader + e_len, d_len); // decompressor
|
||||
#if 0
|
||||
printf("%-13s: entry : %8ld bytes\n", getName(), (long) e_len);
|
||||
printf("%-13s: compressed : %8ld bytes\n", getName(), (long) ph.c_len);
|
||||
@@ -130,65 +118,45 @@ void PackCom::patchLoader(OutputFile *fo,
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void PackCom::buildLoader(const Filter *ft)
|
||||
{
|
||||
void PackCom::buildLoader(const Filter *ft) {
|
||||
initLoader(stub_i086_dos16_com, sizeof(stub_i086_dos16_com));
|
||||
addLoader("COMMAIN1",
|
||||
ph.first_offset_found == 1 ? "COMSBBBP" : "",
|
||||
"COMPSHDI",
|
||||
ft->id ? "COMCALLT" : "",
|
||||
"COMMAIN2,UPX1HEAD,COMCUTPO,NRV2B160",
|
||||
ft->id ? "NRVDDONE" : "NRVDRETU",
|
||||
"NRVDECO1",
|
||||
ph.max_offset_found <= 0xd00 ? "NRVLED00" : "NRVGTD00",
|
||||
"NRVDECO2",
|
||||
nullptr
|
||||
);
|
||||
if (ft->id)
|
||||
{
|
||||
addLoader("COMMAIN1", ph.first_offset_found == 1 ? "COMSBBBP" : "", "COMPSHDI",
|
||||
ft->id ? "COMCALLT" : "", "COMMAIN2,UPX1HEAD,COMCUTPO,NRV2B160",
|
||||
ft->id ? "NRVDDONE" : "NRVDRETU", "NRVDECO1",
|
||||
ph.max_offset_found <= 0xd00 ? "NRVLED00" : "NRVGTD00", "NRVDECO2", nullptr);
|
||||
if (ft->id) {
|
||||
assert(ft->calls > 0);
|
||||
addFilter16(ft->id);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void PackCom::addFilter16(int filter_id)
|
||||
{
|
||||
void PackCom::addFilter16(int filter_id) {
|
||||
assert(filter_id > 0);
|
||||
assert(isValidFilter(filter_id));
|
||||
|
||||
if (filter_id % 3 == 0)
|
||||
addLoader("CALLTR16",
|
||||
filter_id < 4 ? "CT16SUB0" : "",
|
||||
filter_id < 4 ? "" : (opt->cpu == opt->CPU_8086 ? "CT16I086" : "CT16I286,CT16SUB0"),
|
||||
"CALLTRI2",
|
||||
getFormat() == UPX_F_DOS_COM ? "CORETURN" : "",
|
||||
nullptr
|
||||
);
|
||||
addLoader("CALLTR16", filter_id < 4 ? "CT16SUB0" : "",
|
||||
filter_id < 4 ? ""
|
||||
: (opt->cpu == opt->CPU_8086 ? "CT16I086" : "CT16I286,CT16SUB0"),
|
||||
"CALLTRI2", getFormat() == UPX_F_DOS_COM ? "CORETURN" : "", nullptr);
|
||||
else
|
||||
addLoader(filter_id%3 == 1 ? "CT16E800" : "CT16E900",
|
||||
"CALLTRI5",
|
||||
getFormat() == UPX_F_DOS_COM ? "CT16JEND" : "CT16JUL2",
|
||||
filter_id < 4 ? "CT16SUB1" : "",
|
||||
filter_id < 4 ? "" : (opt->cpu == opt->CPU_8086 ? "CT16I087" : "CT16I287,CT16SUB1"),
|
||||
"CALLTRI6",
|
||||
nullptr
|
||||
);
|
||||
addLoader(
|
||||
filter_id % 3 == 1 ? "CT16E800" : "CT16E900", "CALLTRI5",
|
||||
getFormat() == UPX_F_DOS_COM ? "CT16JEND" : "CT16JUL2", filter_id < 4 ? "CT16SUB1" : "",
|
||||
filter_id < 4 ? "" : (opt->cpu == opt->CPU_8086 ? "CT16I087" : "CT16I287,CT16SUB1"),
|
||||
"CALLTRI6", nullptr);
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
//
|
||||
**************************************************************************/
|
||||
|
||||
void PackCom::pack(OutputFile *fo)
|
||||
{
|
||||
void PackCom::pack(OutputFile *fo) {
|
||||
// read file
|
||||
ibuf.alloc(file_size);
|
||||
obuf.allocForCompression(file_size);
|
||||
fi->seek(0,SEEK_SET);
|
||||
fi->readx(ibuf,file_size);
|
||||
fi->seek(0, SEEK_SET);
|
||||
fi->readx(ibuf, file_size);
|
||||
|
||||
// prepare packheader
|
||||
ph.u_len = file_size;
|
||||
@@ -201,7 +169,7 @@ void PackCom::pack(OutputFile *fo)
|
||||
|
||||
const int lsize = getLoaderSize();
|
||||
MemBuffer loader(lsize);
|
||||
memcpy(loader,getLoader(),lsize);
|
||||
memcpy(loader, getLoader(), lsize);
|
||||
|
||||
const unsigned calls = ft.id % 3 ? ft.lastcall - 2 * ft.calls : ft.calls;
|
||||
patchLoader(fo, loader, lsize, calls);
|
||||
@@ -214,13 +182,11 @@ void PackCom::pack(OutputFile *fo)
|
||||
throwNotCompressible();
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
//
|
||||
**************************************************************************/
|
||||
|
||||
int PackCom::canUnpack()
|
||||
{
|
||||
int PackCom::canUnpack() {
|
||||
if (!readPackHeader(128))
|
||||
return false;
|
||||
if (file_size_u <= ph.c_len)
|
||||
@@ -228,19 +194,17 @@ int PackCom::canUnpack()
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
//
|
||||
**************************************************************************/
|
||||
|
||||
void PackCom::unpack(OutputFile *fo)
|
||||
{
|
||||
void PackCom::unpack(OutputFile *fo) {
|
||||
ibuf.alloc(file_size);
|
||||
obuf.allocForDecompression(ph.u_len);
|
||||
|
||||
// read whole file
|
||||
fi->seek(0,SEEK_SET);
|
||||
fi->readx(ibuf,file_size);
|
||||
fi->seek(0, SEEK_SET);
|
||||
fi->readx(ibuf, file_size);
|
||||
|
||||
// get compressed data offset
|
||||
unsigned e_len = ph.buf_offset + ph.getPackHeaderSize();
|
||||
@@ -248,22 +212,18 @@ void PackCom::unpack(OutputFile *fo)
|
||||
throwCantUnpack("file damaged");
|
||||
|
||||
// decompress
|
||||
decompress(ibuf+e_len,obuf);
|
||||
decompress(ibuf + e_len, obuf);
|
||||
|
||||
// unfilter
|
||||
Filter ft(ph.level);
|
||||
ft.init(ph.filter, getCallTrickOffset());
|
||||
ft.unfilter(obuf,ph.u_len);
|
||||
ft.unfilter(obuf, ph.u_len);
|
||||
|
||||
// write decompressed file
|
||||
if (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: */
|
||||
|
||||
+8
-11
@@ -2,8 +2,8 @@
|
||||
|
||||
This file is part of the UPX executable compressor.
|
||||
|
||||
Copyright (C) 1996-2022 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2022 Laszlo Molnar
|
||||
Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2023 Laszlo Molnar
|
||||
All Rights Reserved.
|
||||
|
||||
UPX and the UCL library are free software; you can redistribute them
|
||||
@@ -25,24 +25,22 @@
|
||||
<markus@oberhumer.com> <ezerotven+github@gmail.com>
|
||||
*/
|
||||
|
||||
|
||||
#ifndef __UPX_P_COM_H
|
||||
#define __UPX_P_COM_H 1
|
||||
|
||||
#pragma once
|
||||
#ifndef UPX_P_COM_H__
|
||||
#define UPX_P_COM_H__ 1
|
||||
|
||||
/*************************************************************************
|
||||
// dos/com
|
||||
**************************************************************************/
|
||||
|
||||
class PackCom : public Packer
|
||||
{
|
||||
class PackCom : public Packer {
|
||||
typedef Packer super;
|
||||
|
||||
public:
|
||||
PackCom(InputFile *f) : super(f) { bele = &N_BELE_RTP::le_policy; }
|
||||
virtual int getVersion() const override { return 13; }
|
||||
virtual int getFormat() const override { return UPX_F_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 int *getCompressionMethods(int method, int level) const override;
|
||||
virtual const int *getFilters() const override;
|
||||
@@ -55,7 +53,7 @@ public:
|
||||
|
||||
protected:
|
||||
virtual unsigned getCallTrickOffset() const { return 0x100; }
|
||||
virtual Linker* newLinker() const override;
|
||||
virtual Linker *newLinker() const override;
|
||||
|
||||
protected:
|
||||
virtual void buildLoader(const Filter *ft) override;
|
||||
@@ -63,7 +61,6 @@ protected:
|
||||
virtual void addFilter16(int filter_id);
|
||||
};
|
||||
|
||||
|
||||
#endif /* already included */
|
||||
|
||||
/* vim:set ts=4 sw=4 et: */
|
||||
|
||||
+71
-131
@@ -2,8 +2,8 @@
|
||||
|
||||
This file is part of the UPX executable compressor.
|
||||
|
||||
Copyright (C) 1996-2022 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2022 Laszlo Molnar
|
||||
Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2023 Laszlo Molnar
|
||||
All Rights Reserved.
|
||||
|
||||
UPX and the UCL library are free software; you can redistribute them
|
||||
@@ -25,7 +25,6 @@
|
||||
<markus@oberhumer.com> <ezerotven+github@gmail.com>
|
||||
*/
|
||||
|
||||
|
||||
#include "conf.h"
|
||||
#include "file.h"
|
||||
#include "filter.h"
|
||||
@@ -33,19 +32,16 @@
|
||||
#include "p_djgpp2.h"
|
||||
#include "linker.h"
|
||||
|
||||
static const
|
||||
static const CLANG_FORMAT_DUMMY_STATEMENT
|
||||
#include "stub/i386-dos32.djgpp2.h"
|
||||
static const
|
||||
static const CLANG_FORMAT_DUMMY_STATEMENT
|
||||
#include "stub/i386-dos32.djgpp2-stubify.h"
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
//
|
||||
**************************************************************************/
|
||||
|
||||
PackDjgpp2::PackDjgpp2(InputFile *f) :
|
||||
super(f), coff_offset(0)
|
||||
{
|
||||
PackDjgpp2::PackDjgpp2(InputFile *f) : super(f), coff_offset(0) {
|
||||
bele = &N_BELE_RTP::le_policy;
|
||||
COMPILE_TIME_ASSERT(sizeof(external_scnhdr_t) == 40)
|
||||
COMPILE_TIME_ASSERT(sizeof(coff_header_t) == 0xa8)
|
||||
@@ -53,60 +49,38 @@ PackDjgpp2::PackDjgpp2(InputFile *f) :
|
||||
COMPILE_TIME_ASSERT_ALIGNED1(coff_header_t)
|
||||
COMPILE_TIME_ASSERT(sizeof(stub_i386_dos32_djgpp2_stubify) == 2048)
|
||||
COMPILE_TIME_ASSERT(STUB_I386_DOS32_DJGPP2_STUBIFY_ADLER32 == 0xbf689ba8)
|
||||
COMPILE_TIME_ASSERT(STUB_I386_DOS32_DJGPP2_STUBIFY_CRC32 == 0x2ae982b2)
|
||||
//printf("0x%08x\n", upx_adler32(stubify_stub, sizeof(stubify_stub)));
|
||||
//assert(upx_adler32(stubify_stub, sizeof(stubify_stub)) == STUBIFY_STUB_ADLER32);
|
||||
COMPILE_TIME_ASSERT(STUB_I386_DOS32_DJGPP2_STUBIFY_CRC32 == 0x2ae982b2)
|
||||
// printf("0x%08x\n", upx_adler32(stubify_stub, sizeof(stubify_stub)));
|
||||
// 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);
|
||||
}
|
||||
|
||||
|
||||
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 };
|
||||
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};
|
||||
return filters;
|
||||
}
|
||||
|
||||
|
||||
unsigned PackDjgpp2::findOverlapOverhead(const upx_bytep buf,
|
||||
const upx_bytep tbuf,
|
||||
unsigned range,
|
||||
unsigned upper_limit) const
|
||||
{
|
||||
unsigned PackDjgpp2::findOverlapOverhead(const upx_bytep buf, const upx_bytep tbuf, unsigned range,
|
||||
unsigned upper_limit) const {
|
||||
unsigned o = super::findOverlapOverhead(buf, tbuf, range, upper_limit);
|
||||
o = (o + 0x3ff) &~ 0x1ff;
|
||||
o = (o + 0x3ff) & ~0x1ff;
|
||||
return o;
|
||||
}
|
||||
|
||||
Linker *PackDjgpp2::newLinker() const { return new ElfLinkerX86; }
|
||||
|
||||
Linker* PackDjgpp2::newLinker() const
|
||||
{
|
||||
return new ElfLinkerX86;
|
||||
}
|
||||
|
||||
|
||||
void PackDjgpp2::buildLoader(const Filter *ft)
|
||||
{
|
||||
void PackDjgpp2::buildLoader(const Filter *ft) {
|
||||
// prepare loader
|
||||
initLoader(stub_i386_dos32_djgpp2, sizeof(stub_i386_dos32_djgpp2));
|
||||
addLoader("IDENTSTR,DJ2MAIN1",
|
||||
ft->id ? "DJCALLT1" : "",
|
||||
addLoader("IDENTSTR,DJ2MAIN1", ft->id ? "DJCALLT1" : "",
|
||||
ph.first_offset_found == 1 ? "DJ2MAIN2" : "",
|
||||
M_IS_LZMA(ph.method) ? "LZMA_INIT_STACK" : "",
|
||||
getDecompressorSections(),
|
||||
M_IS_LZMA(ph.method) ? "LZMA_DONE_STACK" : "",
|
||||
"DJ2BSS00",
|
||||
nullptr
|
||||
);
|
||||
if (ft->id)
|
||||
{
|
||||
M_IS_LZMA(ph.method) ? "LZMA_INIT_STACK" : "", getDecompressorSections(),
|
||||
M_IS_LZMA(ph.method) ? "LZMA_DONE_STACK" : "", "DJ2BSS00", nullptr);
|
||||
if (ft->id) {
|
||||
assert(ft->calls > 0);
|
||||
addLoader("DJCALLT2", nullptr);
|
||||
addFilter32(ft->id);
|
||||
@@ -114,32 +88,24 @@ void PackDjgpp2::buildLoader(const Filter *ft)
|
||||
addLoader("DJRETURN,+40C,UPX1HEAD", nullptr);
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
// util
|
||||
**************************************************************************/
|
||||
|
||||
void PackDjgpp2::handleStub(OutputFile *fo)
|
||||
{
|
||||
if (fo && !opt->djgpp2_coff.coff)
|
||||
{
|
||||
if (coff_offset > 0)
|
||||
{
|
||||
void PackDjgpp2::handleStub(OutputFile *fo) {
|
||||
if (fo && !opt->djgpp2_coff.coff) {
|
||||
if (coff_offset > 0) {
|
||||
// copy stub from exe
|
||||
Packer::handleStub(fi, fo, coff_offset);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
// "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));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static bool is_dlm(InputFile *fi, unsigned coff_offset)
|
||||
{
|
||||
static bool is_dlm(InputFile *fi, unsigned coff_offset) {
|
||||
unsigned char buf[4];
|
||||
unsigned off;
|
||||
|
||||
@@ -153,14 +119,12 @@ static bool is_dlm(InputFile *fi, unsigned coff_offset)
|
||||
fi->readx(buf, 4);
|
||||
if (memcmp(buf, "DLMF", 4) == 0)
|
||||
return true;
|
||||
} catch (const IOException&) {
|
||||
} catch (const IOException &) {
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
static void handle_allegropak(InputFile *fi, OutputFile *fo)
|
||||
{
|
||||
static void handle_allegropak(InputFile *fi, OutputFile *fo) {
|
||||
unsigned char b[8];
|
||||
int pfsize = 0;
|
||||
|
||||
@@ -169,80 +133,71 @@ static void handle_allegropak(InputFile *fi, OutputFile *fo)
|
||||
fi->readx(b, 8);
|
||||
if (memcmp(b, "slh+", 4) != 0)
|
||||
return;
|
||||
pfsize = get_be32_signed(b+4);
|
||||
pfsize = get_be32_signed(b + 4);
|
||||
if (pfsize <= 8 || pfsize >= fi->st.st_size)
|
||||
return;
|
||||
fi->seek(-pfsize, SEEK_END);
|
||||
} catch (const IOException&) {
|
||||
} catch (const IOException &) {
|
||||
return;
|
||||
}
|
||||
MemBuffer buf(0x4000);
|
||||
while (pfsize > 0)
|
||||
{
|
||||
const int len = UPX_MIN(pfsize, (int)buf.getSize());
|
||||
while (pfsize > 0) {
|
||||
const int len = UPX_MIN(pfsize, (int) buf.getSize());
|
||||
fi->readx(buf, len);
|
||||
fo->write(buf, len);
|
||||
pfsize -= len;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int PackDjgpp2::readFileHeader()
|
||||
{
|
||||
int PackDjgpp2::readFileHeader() {
|
||||
unsigned char hdr[0x1c];
|
||||
unsigned char magic[8];
|
||||
|
||||
fi->seek(0, SEEK_SET);
|
||||
fi->readx(hdr, sizeof(hdr));
|
||||
if (get_le16(hdr) == 0x5a4d) // MZ exe signature, stubbed?
|
||||
if (get_le16(hdr) == 0x5a4d) // MZ exe signature, stubbed?
|
||||
{
|
||||
coff_offset = 512 * get_le16(hdr+4);
|
||||
if (get_le16(hdr+2) != 0)
|
||||
coff_offset += get_le16(hdr+2) - 512;
|
||||
coff_offset = 512 * get_le16(hdr + 4);
|
||||
if (get_le16(hdr + 2) != 0)
|
||||
coff_offset += get_le16(hdr + 2) - 512;
|
||||
fi->seek(512, SEEK_SET);
|
||||
fi->readx(magic, 8);
|
||||
if (memcmp("go32stub", magic, 8) != 0)
|
||||
return 0; // not V2 image
|
||||
return 0; // not V2 image
|
||||
fi->seek(coff_offset, SEEK_SET);
|
||||
if (fi->read(&coff_hdr, sizeof(coff_hdr)) != sizeof(coff_hdr))
|
||||
throwCantPack("skipping djgpp symlink");
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
fi->seek(coff_offset, SEEK_SET);
|
||||
fi->readx(&coff_hdr, 0xa8);
|
||||
}
|
||||
if (coff_hdr.f_magic != 0x014c) // I386MAGIC
|
||||
if (coff_hdr.f_magic != 0x014c) // I386MAGIC
|
||||
return 0;
|
||||
if ((coff_hdr.f_flags & 2) == 0) // F_EXEC - COFF executable
|
||||
if ((coff_hdr.f_flags & 2) == 0) // F_EXEC - COFF executable
|
||||
return 0;
|
||||
if (coff_hdr.a_magic != 0413) // ZMAGIC - demand load format
|
||||
if (coff_hdr.a_magic != 0413) // ZMAGIC - demand load format
|
||||
return 0;
|
||||
// FIXME: check for Linux etc.
|
||||
|
||||
text = coff_hdr.sh;
|
||||
data = text + 1;
|
||||
bss = data + 1;
|
||||
bss = data + 1;
|
||||
return UPX_F_DJGPP2_COFF;
|
||||
}
|
||||
|
||||
|
||||
// "strip" debug info
|
||||
void PackDjgpp2::stripDebug()
|
||||
{
|
||||
void PackDjgpp2::stripDebug() {
|
||||
coff_hdr.f_symptr = 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);
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
//
|
||||
**************************************************************************/
|
||||
|
||||
bool PackDjgpp2::canPack()
|
||||
{
|
||||
bool PackDjgpp2::canPack() {
|
||||
if (!readFileHeader())
|
||||
return false;
|
||||
if (is_dlm(fi, coff_offset))
|
||||
@@ -253,38 +208,32 @@ bool PackDjgpp2::canPack()
|
||||
throwAlreadyPacked();
|
||||
|
||||
// Check for gap in vaddr between text and data, or between data and bss.
|
||||
if (text->vaddr + text->size != data->vaddr
|
||||
|| data->vaddr + data->size != bss->vaddr)
|
||||
{
|
||||
if (text->vaddr + text->size != data->vaddr || data->vaddr + data->size != bss->vaddr) {
|
||||
// "Non-standard" layout of text,data,bss: not contiguous in vaddr.
|
||||
// But should be OK if no overlap.
|
||||
|
||||
// Check for no overlap of text and data:
|
||||
// neither by vaddr, nor by image data
|
||||
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)
|
||||
// Hack: enlarge text image data to eliminate the gap.
|
||||
text->size = coff_hdr.a_tsize = data->scnptr - text->scnptr;
|
||||
// But complain if this causes overlap in vaddr
|
||||
if (text->vaddr + text->size > data->vaddr)
|
||||
throwAlreadyPacked();
|
||||
}
|
||||
else
|
||||
} else
|
||||
throwAlreadyPacked();
|
||||
}
|
||||
// FIXME: check for Linux etc.
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
//
|
||||
**************************************************************************/
|
||||
|
||||
void PackDjgpp2::pack(OutputFile *fo)
|
||||
{
|
||||
void PackDjgpp2::pack(OutputFile *fo) {
|
||||
handleStub(fo);
|
||||
|
||||
// patch coff header #1: "strip" debug info
|
||||
@@ -302,7 +251,7 @@ void PackDjgpp2::pack(OutputFile *fo)
|
||||
obuf.allocForCompression(usize);
|
||||
|
||||
fi->seek(coff_offset, SEEK_SET);
|
||||
fi->readx(ibuf, hdrsize); // orig. coff header
|
||||
fi->readx(ibuf, hdrsize); // orig. coff header
|
||||
fi->seek(coff_offset + tpos, SEEK_SET);
|
||||
fi->readx(ibuf + hdrsize, size);
|
||||
|
||||
@@ -313,7 +262,8 @@ void PackDjgpp2::pack(OutputFile *fo)
|
||||
ft.buf_len = usize - data->size;
|
||||
ft.addvalue = text->vaddr - hdrsize;
|
||||
// compress
|
||||
upx_compress_config_t cconf; cconf.reset();
|
||||
upx_compress_config_t cconf;
|
||||
cconf.reset();
|
||||
// limit stack size needed for runtime decompression
|
||||
cconf.conf_lzma.max_num_probs = 1846 + (768 << 4); // ushort: ~28 KiB stack
|
||||
compressWithFilters(&ft, 512, &cconf);
|
||||
@@ -321,24 +271,25 @@ void PackDjgpp2::pack(OutputFile *fo)
|
||||
// patch coff header #2
|
||||
const unsigned lsize = getLoaderSize();
|
||||
assert(lsize % 4 == 0);
|
||||
text->size = lsize; // new size of .text
|
||||
data->size = ph.c_len; // new size of .data
|
||||
text->size = lsize; // new size of .text
|
||||
data->size = ph.c_len; // new size of .data
|
||||
|
||||
unsigned stack = 1024 + ph.overlap_overhead + getDecompressorWrkmemSize();
|
||||
stack = ALIGN_UP(stack, 16u);
|
||||
if (bss->size < stack) // give it a .bss
|
||||
if (bss->size < stack) // give it a .bss
|
||||
bss->size = stack;
|
||||
|
||||
text->scnptr = sizeof(coff_hdr);
|
||||
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;
|
||||
|
||||
linker->defineSymbol("original_entry", coff_hdr.a_entry);
|
||||
linker->defineSymbol("length_of_bss", ph.overlap_overhead / 4);
|
||||
defineDecompressorSymbols();
|
||||
// Just need no overlap; non-contiguous (gap length > 0)) is OK
|
||||
assert(bss->vaddr >= ((size + 0x1ff) &~ 0x1ff) + (text->vaddr &~ 0x1ff));
|
||||
assert(bss->vaddr >= ((size + 0x1ff) & ~0x1ff) + (text->vaddr & ~0x1ff));
|
||||
linker->defineSymbol("stack_for_lzma", bss->vaddr + bss->size);
|
||||
linker->defineSymbol("start_of_uncompressed", text->vaddr - hdrsize);
|
||||
linker->defineSymbol("start_of_compressed", data->vaddr);
|
||||
@@ -356,7 +307,7 @@ void PackDjgpp2::pack(OutputFile *fo)
|
||||
bss->size -= ph.overlap_overhead;
|
||||
|
||||
// because of a feature (bug?) in stub.asm we need some padding
|
||||
memcpy(obuf+data->size, "UPX", 3);
|
||||
memcpy(obuf + data->size, "UPX", 3);
|
||||
data->size = ALIGN_UP(data->size, 4u);
|
||||
|
||||
linker->defineSymbol("DJ2MAIN1", coff_hdr.a_entry);
|
||||
@@ -391,13 +342,11 @@ void PackDjgpp2::pack(OutputFile *fo)
|
||||
throwNotCompressible();
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
//
|
||||
**************************************************************************/
|
||||
|
||||
int PackDjgpp2::canUnpack()
|
||||
{
|
||||
int PackDjgpp2::canUnpack() {
|
||||
if (!readFileHeader())
|
||||
return false;
|
||||
if (is_dlm(fi, coff_offset))
|
||||
@@ -406,13 +355,11 @@ int PackDjgpp2::canUnpack()
|
||||
return readPackHeader(4096) ? 1 : -1;
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
//
|
||||
**************************************************************************/
|
||||
|
||||
void PackDjgpp2::unpack(OutputFile *fo)
|
||||
{
|
||||
void PackDjgpp2::unpack(OutputFile *fo) {
|
||||
handleStub(fo);
|
||||
|
||||
ibuf.alloc(ph.c_len);
|
||||
@@ -424,27 +371,24 @@ void PackDjgpp2::unpack(OutputFile *fo)
|
||||
// decompress
|
||||
decompress(ibuf, obuf);
|
||||
|
||||
coff_header_t *chdr = (coff_header_t*) obuf.getVoidPtr();
|
||||
coff_header_t *chdr = (coff_header_t *) obuf.getVoidPtr();
|
||||
text = chdr->sh;
|
||||
data = text + 1;
|
||||
|
||||
const unsigned hdrsize = 20 + 28
|
||||
+ sizeof(external_scnhdr_t) * chdr->f_nscns;
|
||||
const unsigned hdrsize = 20 + 28 + sizeof(external_scnhdr_t) * chdr->f_nscns;
|
||||
|
||||
unsigned addvalue;
|
||||
if (ph.version >= 14)
|
||||
addvalue = text->vaddr - hdrsize;
|
||||
else
|
||||
addvalue = text->vaddr &~ 0x1ff; // for old versions
|
||||
addvalue = text->vaddr & ~0x1ff; // for old versions
|
||||
|
||||
// unfilter
|
||||
if (ph.filter)
|
||||
{
|
||||
if (ph.filter) {
|
||||
Filter ft(ph.level);
|
||||
ft.init(ph.filter, addvalue);
|
||||
ft.cto = (unsigned char) ph.filter_cto;
|
||||
if (ph.version < 11)
|
||||
{
|
||||
if (ph.version < 11) {
|
||||
unsigned char ctobuf[4];
|
||||
fi->readx(ctobuf, 4);
|
||||
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);
|
||||
}
|
||||
|
||||
if (ph.version < 14)
|
||||
{
|
||||
if (ph.version < 14) {
|
||||
// fixup for the aligning bug in strip 2.8+
|
||||
text->scnptr &= 0x1ff;
|
||||
data->scnptr = text->scnptr + text->size;
|
||||
// write decompressed file
|
||||
if (fo)
|
||||
fo->write(obuf, ph.u_len);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
// write the header
|
||||
// some padding might be required between the end
|
||||
// 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;
|
||||
ibuf.clear(0, padding);
|
||||
|
||||
if (fo)
|
||||
{
|
||||
if (fo) {
|
||||
fo->write(obuf, hdrsize);
|
||||
fo->write(ibuf, padding);
|
||||
fo->write(obuf + hdrsize, ph.u_len - hdrsize);
|
||||
|
||||
+36
-38
@@ -2,8 +2,8 @@
|
||||
|
||||
This file is part of the UPX executable compressor.
|
||||
|
||||
Copyright (C) 1996-2022 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2022 Laszlo Molnar
|
||||
Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2023 Laszlo Molnar
|
||||
All Rights Reserved.
|
||||
|
||||
UPX and the UCL library are free software; you can redistribute them
|
||||
@@ -25,17 +25,15 @@
|
||||
<markus@oberhumer.com> <ezerotven+github@gmail.com>
|
||||
*/
|
||||
|
||||
|
||||
#ifndef __UPX_P_DJGPP2_H
|
||||
#define __UPX_P_DJGPP2_H 1
|
||||
|
||||
#pragma once
|
||||
#ifndef UPX_P_DJGPP2_H__
|
||||
#define UPX_P_DJGPP2_H__ 1
|
||||
|
||||
/*************************************************************************
|
||||
// djgpp2/coff
|
||||
**************************************************************************/
|
||||
|
||||
class PackDjgpp2 final : public Packer
|
||||
{
|
||||
class PackDjgpp2 final : public Packer {
|
||||
typedef Packer super;
|
||||
|
||||
public:
|
||||
@@ -43,7 +41,9 @@ public:
|
||||
virtual int getVersion() const override { return 14; }
|
||||
virtual int getFormat() const override { return UPX_F_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 *getFilters() const override;
|
||||
|
||||
@@ -57,54 +57,52 @@ protected:
|
||||
void handleStub(OutputFile *fo);
|
||||
int readFileHeader();
|
||||
|
||||
virtual unsigned findOverlapOverhead(const upx_bytep buf,
|
||||
const upx_bytep tbuf,
|
||||
virtual unsigned findOverlapOverhead(const upx_bytep buf, const upx_bytep tbuf,
|
||||
unsigned range = 0,
|
||||
unsigned upper_limit = ~0u) const override;
|
||||
virtual void buildLoader(const Filter *ft) override;
|
||||
virtual Linker* newLinker() const override;
|
||||
virtual Linker *newLinker() const override;
|
||||
|
||||
unsigned coff_offset;
|
||||
|
||||
__packed_struct(external_scnhdr_t)
|
||||
char _[12]; // name, paddr
|
||||
LE32 vaddr;
|
||||
LE32 size;
|
||||
LE32 scnptr;
|
||||
char misc[12]; // relptr, lnnoptr, nreloc, nlnno
|
||||
char __[4]; // flags
|
||||
__packed_struct_end()
|
||||
struct alignas(1) external_scnhdr_t {
|
||||
char _[12]; // name, paddr
|
||||
LE32 vaddr;
|
||||
LE32 size;
|
||||
LE32 scnptr;
|
||||
char misc[12]; // relptr, lnnoptr, nreloc, nlnno
|
||||
char __[4]; // flags
|
||||
};
|
||||
|
||||
__packed_struct(coff_header_t)
|
||||
struct alignas(1) coff_header_t {
|
||||
// ext_file_hdr
|
||||
LE16 f_magic;
|
||||
LE16 f_nscns;
|
||||
char _[4]; // f_timdat
|
||||
LE32 f_symptr;
|
||||
LE32 f_nsyms;
|
||||
char __[2]; // f_opthdr
|
||||
LE16 f_flags;
|
||||
LE16 f_magic;
|
||||
LE16 f_nscns;
|
||||
char _[4]; // f_timdat
|
||||
LE32 f_symptr;
|
||||
LE32 f_nsyms;
|
||||
char __[2]; // f_opthdr
|
||||
LE16 f_flags;
|
||||
|
||||
// aout_hdr
|
||||
LE16 a_magic;
|
||||
char ___[2]; // a_vstamp
|
||||
LE32 a_tsize;
|
||||
LE32 a_dsize;
|
||||
char ____[4]; // a_bsize
|
||||
LE32 a_entry;
|
||||
char _____[8]; // a_text_start a_data_start
|
||||
LE16 a_magic;
|
||||
char ___[2]; // a_vstamp
|
||||
LE32 a_tsize;
|
||||
LE32 a_dsize;
|
||||
char ____[4]; // a_bsize
|
||||
LE32 a_entry;
|
||||
char _____[8]; // a_text_start a_data_start
|
||||
|
||||
// section headers
|
||||
external_scnhdr_t sh[3];
|
||||
__packed_struct_end()
|
||||
};
|
||||
|
||||
coff_header_t coff_hdr;
|
||||
external_scnhdr_t *text,*data,*bss;
|
||||
external_scnhdr_t *text, *data, *bss;
|
||||
|
||||
void stripDebug();
|
||||
};
|
||||
|
||||
|
||||
#endif /* already included */
|
||||
|
||||
/* vim:set ts=4 sw=4 et: */
|
||||
|
||||
+2
-2
@@ -2,8 +2,8 @@
|
||||
|
||||
This file is part of the UPX executable compressor.
|
||||
|
||||
Copyright (C) 1996-2022 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2022 Laszlo Molnar
|
||||
Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2023 Laszlo Molnar
|
||||
All Rights Reserved.
|
||||
|
||||
UPX and the UCL library are free software; you can redistribute them
|
||||
|
||||
+37
-36
@@ -2,8 +2,8 @@
|
||||
|
||||
This file is part of the UPX executable compressor.
|
||||
|
||||
Copyright (C) 1996-2022 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2022 Laszlo Molnar
|
||||
Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2023 Laszlo Molnar
|
||||
All Rights Reserved.
|
||||
|
||||
UPX and the UCL library are free software; you can redistribute them
|
||||
@@ -41,15 +41,15 @@
|
||||
EI_DATA = 5, /* Data encoding */
|
||||
EI_VERSION = 6,
|
||||
EI_OSABI = 7,
|
||||
EI_ABIVERSION = 8
|
||||
EI_ABIVERSION = 8,
|
||||
};
|
||||
enum { // e_ident[EI_CLASS]
|
||||
ELFCLASS32 = 1, /* 32-bit objects */
|
||||
ELFCLASS64 = 2 /* 64-bit objects */
|
||||
ELFCLASS64 = 2, /* 64-bit objects */
|
||||
};
|
||||
enum { // e_ident[EI_DATA]
|
||||
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]
|
||||
ELFOSABI_NONE = 0, // == ELFOSABI_SYSV
|
||||
@@ -57,28 +57,28 @@
|
||||
ELFOSABI_LINUX = 3,
|
||||
ELFOSABI_FREEBSD = 9,
|
||||
ELFOSABI_OPENBSD = 12,
|
||||
ELFOSABI_ARM = 97
|
||||
ELFOSABI_ARM = 97,
|
||||
};
|
||||
enum { // e_type
|
||||
ET_NONE = 0, /* No file type */
|
||||
ET_REL = 1, /* Relocatable file */
|
||||
ET_EXEC = 2, /* Executable file */
|
||||
ET_DYN = 3, /* Shared object file */
|
||||
ET_CORE = 4 /* Core file */
|
||||
ET_CORE = 4, /* Core file */
|
||||
};
|
||||
enum { // e_machine
|
||||
EM_386 = 3,
|
||||
EM_MIPS = 8,
|
||||
EM_MIPS_RS3_LE = 10, /* MIPS R3000 little-endian */
|
||||
EM_MIPS_RS3_LE = 10, /* MIPS R3000 little-endian */
|
||||
EM_PPC = 20,
|
||||
EM_PPC64 = 21,
|
||||
EM_ARM = 40,
|
||||
EM_X86_64 = 62,
|
||||
EM_AARCH64 = 183
|
||||
EM_AARCH64 = 183,
|
||||
|
||||
};
|
||||
enum { // e_version
|
||||
EV_CURRENT = 1
|
||||
EV_CURRENT = 1,
|
||||
};
|
||||
#endif
|
||||
|
||||
@@ -91,15 +91,16 @@
|
||||
PT_DYNAMIC = 2, /* Dynamic linking information */
|
||||
PT_INTERP = 3, /* Name of program interpreter */
|
||||
PT_NOTE = 4, /* Auxiliary information (esp. OpenBSD) */
|
||||
PT_PHDR = 6 /* Entry for header table itself */
|
||||
, PT_NUM = 8 /* Number of defined types in low range */
|
||||
, PT_GNU_STACK = 0x6474e551 /* Indicates stack executability */
|
||||
PT_PHDR = 6, /* Entry for header table itself */
|
||||
PT_NUM = 8, /* Number of defined types in low range */
|
||||
PT_GNU_STACK = 0x6474e551, /* Indicates stack executability */
|
||||
PT_GNU_RELRO = 0x6474e552, /* Read-only after relocation */
|
||||
};
|
||||
|
||||
enum { // p_flags
|
||||
PF_X = 1, /* Segment is executable */
|
||||
PF_W = 2, /* Segment is writable */
|
||||
PF_R = 4 /* Segment is readable */
|
||||
PF_R = 4, /* Segment is readable */
|
||||
};
|
||||
#endif
|
||||
|
||||
@@ -125,12 +126,12 @@
|
||||
SHT_PREINIT_ARRAY = 16, /* Array of pre-constructors */
|
||||
SHT_GROUP = 17, /* Section group */
|
||||
SHT_SYMTAB_SHNDX = 18, /* Extended section indeces */
|
||||
SHT_GNU_LIBLIST = 0x6ffffff7 /* Prelink library list */
|
||||
, SHT_GNU_HASH = 0x6ffffff6 /* GNU-style hash table. */
|
||||
SHT_GNU_LIBLIST = 0x6ffffff7, /* Prelink library list */
|
||||
SHT_GNU_HASH = 0x6ffffff6, /* GNU-style hash table. */
|
||||
|
||||
, SHT_LOOS = 0x60000000 /* LOcal OS; SHT_ANDROID_REL{,A} is +1, +2 */
|
||||
, SHT_LOPROC = 0x70000000/* Start of processor-specific */
|
||||
, SHT_ARM_ATTRIBUTES = (SHT_LOPROC + 3) /* ARM attributes section. */
|
||||
SHT_LOOS = 0x60000000, /* LOcal OS; SHT_ANDROID_REL{,A} is +1, +2 */
|
||||
SHT_LOPROC = 0x70000000, /* Start of processor-specific */
|
||||
SHT_ARM_ATTRIBUTES = (SHT_LOPROC + 3), /* ARM attributes section. */
|
||||
};
|
||||
|
||||
enum { // sh_flags
|
||||
@@ -140,7 +141,7 @@
|
||||
SHF_MERGE = (1 << 4), /* Might be merged */
|
||||
SHF_STRINGS = (1 << 5), /* Contains nul-terminated strings */
|
||||
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
|
||||
|
||||
@@ -182,11 +183,11 @@
|
||||
DT_VERSYM = 0x6ffffff0, /* version[] for each symbol */
|
||||
DT_FLAGS_1 = 0x6ffffffb, /* DF_1_* */
|
||||
DT_VERDEF = 0x6ffffffc, /* version definitions[] */
|
||||
DT_VERNEED = 0x6ffffffe /* version[] needed */
|
||||
DT_VERNEED = 0x6ffffffe, /* version[] needed */
|
||||
};
|
||||
enum { // DT_FLAGS_1
|
||||
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
|
||||
|
||||
@@ -196,7 +197,7 @@
|
||||
enum { // st_bind (high 4 bits of st_info)
|
||||
STB_LOCAL = 0, /* Local 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)
|
||||
@@ -206,20 +207,20 @@
|
||||
STT_SECTION = 3, /* Symbol associated with a section */
|
||||
STT_FILE = 4, /* Symbol's name is file name */
|
||||
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)
|
||||
STV_DEFAULT = 0, /* Default symbol visibility rules */
|
||||
STV_INTERNAL = 1, /* Processor specific hidden class */
|
||||
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
|
||||
SHN_UNDEF = 0, /* Undefined section */
|
||||
SHN_ABS = 0xfff1, /* Associated symbol is absolute */
|
||||
SHN_COMMON = 0xfff2 /* Associated symbol is common */
|
||||
SHN_COMMON = 0xfff2, /* Associated symbol is common */
|
||||
};
|
||||
#endif
|
||||
|
||||
@@ -246,13 +247,13 @@
|
||||
R_ARM_JUMP_SLOT = 22,
|
||||
R_PPC_JMP_SLOT = 21,
|
||||
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_GLOB_DAT = 21
|
||||
R_ARM_ABS32 = 2,
|
||||
R_ARM_GLOB_DAT = 21,
|
||||
|
||||
, R_AARCH64_ABS64 = 257
|
||||
, R_AARCH64_GLOB_DAT = 1025
|
||||
R_AARCH64_ABS64 = 257,
|
||||
R_AARCH64_GLOB_DAT = 1025,
|
||||
|
||||
};
|
||||
#endif //}
|
||||
@@ -271,7 +272,7 @@
|
||||
#define ELF_NOTE_NETBSD_NAME "NetBSD\0"
|
||||
NHDR_NETBSD_TAG = 1,
|
||||
NHDR_CHECKSUM_TAG = 2,
|
||||
NHDR_PAX_TAG = 3
|
||||
NHDR_PAX_TAG = 3,
|
||||
};
|
||||
|
||||
enum { // descsz descriptor sizes
|
||||
@@ -279,20 +280,20 @@
|
||||
NETBSD_DESCSZ = 4, // major_ver * (10**8) + minor
|
||||
OPENBSD_DESCSZ = 4, // 32-bit zero
|
||||
// CHECKSUM_DESCSZ is 2*sizeof(short) + sizeof(checksum)
|
||||
PAX_DESCSZ = 4 // 32-bit mask
|
||||
PAX_DESCSZ = 4, // 32-bit mask
|
||||
};
|
||||
|
||||
enum { // GNU OS/version
|
||||
GNU_OS_LINUX = 0,
|
||||
GNU_OS_HURD = 1,
|
||||
GNU_OS_SOLARIS = 2
|
||||
GNU_OS_SOLARIS = 2,
|
||||
};
|
||||
|
||||
enum { // NetBSD checksum methods
|
||||
CHECKSUM_CRC32 = 1,
|
||||
CHECKSUM_MD5 = 2,
|
||||
CHECKSUM_SHA1 = 3,
|
||||
CHECKSUM_SHA256 = 4
|
||||
CHECKSUM_SHA256 = 4,
|
||||
};
|
||||
|
||||
#define ELF_NOTE_PAX_NAME "PaX\0"
|
||||
@@ -302,7 +303,7 @@
|
||||
PAX_GUARD = (1<<2), /* force enable SEGVguard */
|
||||
PAX_NOGUARD = (1<<3), /* force disable SEGVguard */
|
||||
PAX_ASLR = (1<<4), /* force enable ASLR */
|
||||
PAX_NOASLR = (1<<5) /* force disable ASLR */
|
||||
PAX_NOASLR = (1<<5), /* force disable ASLR */
|
||||
};
|
||||
#endif
|
||||
|
||||
|
||||
+207
-307
@@ -2,8 +2,8 @@
|
||||
|
||||
This file is part of the UPX executable compressor.
|
||||
|
||||
Copyright (C) 1996-2022 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2022 Laszlo Molnar
|
||||
Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2023 Laszlo Molnar
|
||||
All Rights Reserved.
|
||||
|
||||
UPX and the UCL library are free software; you can redistribute them
|
||||
@@ -25,7 +25,6 @@
|
||||
<markus@oberhumer.com> <ezerotven+github@gmail.com>
|
||||
*/
|
||||
|
||||
|
||||
#include "conf.h"
|
||||
#include "file.h"
|
||||
#include "filter.h"
|
||||
@@ -33,23 +32,20 @@
|
||||
#include "p_exe.h"
|
||||
#include "linker.h"
|
||||
|
||||
static const
|
||||
static const CLANG_FORMAT_DUMMY_STATEMENT
|
||||
#include "stub/i086-dos16.exe.h"
|
||||
|
||||
#define RSFCRI 4096 // Reserved Space For Compressed Relocation Info
|
||||
#define MAXMATCH 0x2000
|
||||
#define MAXRELOCS (0x8000-MAXMATCH)
|
||||
|
||||
#define DI_LIMIT 0xff00 // see the assembly why
|
||||
#define RSFCRI 4096 // Reserved Space For Compressed Relocation Info
|
||||
#define MAXMATCH 0x2000
|
||||
#define MAXRELOCS (0x8000 - MAXMATCH)
|
||||
|
||||
#define DI_LIMIT 0xff00 // see the assembly why
|
||||
|
||||
/*************************************************************************
|
||||
//
|
||||
**************************************************************************/
|
||||
|
||||
PackExe::PackExe(InputFile *f) :
|
||||
super(f)
|
||||
{
|
||||
PackExe::PackExe(InputFile *f) : super(f) {
|
||||
bele = &N_BELE_RTP::le_policy;
|
||||
COMPILE_TIME_ASSERT(sizeof(exe_header_t) == 32)
|
||||
COMPILE_TIME_ASSERT_ALIGNED1(exe_header_t)
|
||||
@@ -58,10 +54,8 @@ PackExe::PackExe(InputFile *f) :
|
||||
use_clear_dirty_stack = false;
|
||||
}
|
||||
|
||||
|
||||
const int *PackExe::getCompressionMethods(int method, int level) const
|
||||
{
|
||||
bool small = ih_imagesize <= 256*1024;
|
||||
const int *PackExe::getCompressionMethods(int method, int level) const {
|
||||
bool small = ih_imagesize <= 256 * 1024;
|
||||
// disable lzma for "--brute" unless explicitly given "--lzma"
|
||||
// WARNING: this side effect may persists for later files;
|
||||
// but note that class PackMaster creates per-file local options
|
||||
@@ -70,16 +64,10 @@ const int *PackExe::getCompressionMethods(int method, int level) const
|
||||
return Packer::getDefaultCompressionMethods_8(method, level, small);
|
||||
}
|
||||
|
||||
const int *PackExe::getFilters() const { return nullptr; }
|
||||
|
||||
const int *PackExe::getFilters() const
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
||||
int PackExe::fillExeHeader(struct exe_header_t *eh) const
|
||||
{
|
||||
#define oh (*eh)
|
||||
int PackExe::fillExeHeader(struct exe_header_t *eh) const {
|
||||
#define oh (*eh)
|
||||
// fill new exe header
|
||||
int flag = 0;
|
||||
if (!opt->dos_exe.no_reloc && !M_IS_LZMA(ph.method))
|
||||
@@ -87,7 +75,7 @@ int PackExe::fillExeHeader(struct exe_header_t *eh) const
|
||||
if (ih.relocs == 0)
|
||||
flag |= NORELOC;
|
||||
|
||||
memset(&oh,0,sizeof(oh));
|
||||
memset(&oh, 0, sizeof(oh));
|
||||
oh.ident = 'M' + 'Z' * 256;
|
||||
oh.headsize16 = 2;
|
||||
|
||||
@@ -103,11 +91,10 @@ int PackExe::fillExeHeader(struct exe_header_t *eh) const
|
||||
oh.sp = minsp;
|
||||
|
||||
unsigned destpara = (ph.u_len + ph.overlap_overhead - ph.c_len + 31) / 16;
|
||||
oh.ss = ph.c_len/16 + destpara;
|
||||
if (ih.ss*16 + ih.sp < 0x100000 && ih.ss > oh.ss && ih.sp > 0x200)
|
||||
oh.ss = ph.c_len / 16 + destpara;
|
||||
if (ih.ss * 16 + ih.sp < 0x100000 && ih.ss > oh.ss && ih.sp > 0x200)
|
||||
oh.ss = ih.ss;
|
||||
if (oh.ss*16 + 0x50 < ih.ss*16 + ih.sp
|
||||
&& oh.ss*16 + 0x200 > 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 += 0x20;
|
||||
|
||||
if (oh.ss != ih.ss)
|
||||
@@ -118,58 +105,38 @@ int PackExe::fillExeHeader(struct exe_header_t *eh) const
|
||||
#undef oh
|
||||
}
|
||||
|
||||
void PackExe::addLoaderEpilogue(int flag)
|
||||
{
|
||||
void PackExe::addLoaderEpilogue(int flag) {
|
||||
addLoader("EXEMAIN5", nullptr);
|
||||
if (relocsize)
|
||||
addLoader(ph.u_len <= DI_LIMIT || (ph.u_len & 0x7fff) >= relocsize ? "EXENOADJ" : "EXEADJUS",
|
||||
"EXERELO1",
|
||||
has_9a ? "EXEREL9A" : "",
|
||||
"EXERELO2",
|
||||
ih_exesize > 0xFE00 ? "EXEREBIG" : "",
|
||||
"EXERELO3",
|
||||
nullptr
|
||||
);
|
||||
addLoader("EXEMAIN8",
|
||||
device_driver ? "DEVICEEND" : "",
|
||||
(flag & SS) ? "EXESTACK" : "",
|
||||
(flag & SP) ? "EXESTASP" : "",
|
||||
(flag & USEJUMP) ? "EXEJUMPF" : "",
|
||||
nullptr
|
||||
);
|
||||
addLoader(ph.u_len <= DI_LIMIT || (ph.u_len & 0x7fff) >= relocsize ? "EXENOADJ"
|
||||
: "EXEADJUS",
|
||||
"EXERELO1", has_9a ? "EXEREL9A" : "", "EXERELO2",
|
||||
ih_exesize > 0xFE00 ? "EXEREBIG" : "", "EXERELO3", nullptr);
|
||||
addLoader("EXEMAIN8", device_driver ? "DEVICEEND" : "", (flag & SS) ? "EXESTACK" : "",
|
||||
(flag & SP) ? "EXESTASP" : "", (flag & USEJUMP) ? "EXEJUMPF" : "", nullptr);
|
||||
if (!(flag & USEJUMP))
|
||||
addLoader(ih.cs ? "EXERCSPO" : "",
|
||||
"EXERETIP",
|
||||
nullptr
|
||||
);
|
||||
addLoader(ih.cs ? "EXERCSPO" : "", "EXERETIP", nullptr);
|
||||
|
||||
linker->defineSymbol("original_cs", ih.cs);
|
||||
linker->defineSymbol("original_ip", ih.ip);
|
||||
linker->defineSymbol("original_sp", ih.sp);
|
||||
linker->defineSymbol("original_ss", ih.ss);
|
||||
linker->defineSymbol("reloc_size",
|
||||
(ph.u_len <= DI_LIMIT || (ph.u_len & 0x7fff)
|
||||
>= relocsize ? 0 : MAXRELOCS) - relocsize);
|
||||
linker->defineSymbol(
|
||||
"reloc_size",
|
||||
(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
|
||||
exe_header_t dummy_oh;
|
||||
int flag = fillExeHeader(&dummy_oh);
|
||||
|
||||
initLoader(stub_i086_dos16_exe, sizeof(stub_i086_dos16_exe));
|
||||
|
||||
if (M_IS_LZMA(ph.method))
|
||||
{
|
||||
addLoader("LZMA_DEC00",
|
||||
opt->small ? "LZMA_DEC10" : "LZMA_DEC20",
|
||||
"LZMA_DEC30",
|
||||
use_clear_dirty_stack ? "LZMA_DEC31" : "",
|
||||
"LZMA_DEC32",
|
||||
ph.u_len > 0xffff ? "LZMA_DEC33" : "",
|
||||
nullptr
|
||||
);
|
||||
if (M_IS_LZMA(ph.method)) {
|
||||
addLoader("LZMA_DEC00", opt->small ? "LZMA_DEC10" : "LZMA_DEC20", "LZMA_DEC30",
|
||||
use_clear_dirty_stack ? "LZMA_DEC31" : "", "LZMA_DEC32",
|
||||
ph.u_len > 0xffff ? "LZMA_DEC33" : "", nullptr);
|
||||
|
||||
addLoaderEpilogue(flag);
|
||||
defineDecompressorSymbols();
|
||||
@@ -196,9 +163,10 @@ void PackExe::buildLoader(const Filter *)
|
||||
MemBuffer compressed_lzma;
|
||||
compressed_lzma.allocForCompression(lsize);
|
||||
unsigned c_len_lzma = MemBuffer::getSizeForCompression(lsize);
|
||||
int r = upx_compress(loader, lsize, compressed_lzma, &c_len_lzma,
|
||||
nullptr, M_NRV2B_LE16, 9, nullptr, nullptr);
|
||||
assert(r == UPX_E_OK); assert(c_len_lzma < lsize);
|
||||
int r = upx_compress(loader, lsize, compressed_lzma, &c_len_lzma, nullptr, M_NRV2B_LE16, 9,
|
||||
nullptr, nullptr);
|
||||
assert(r == UPX_E_OK);
|
||||
assert(c_len_lzma < lsize);
|
||||
|
||||
info("lzma+relocator code compressed: %u -> %u", lsize, c_len_lzma);
|
||||
// reinit the loader
|
||||
@@ -208,61 +176,33 @@ void PackExe::buildLoader(const Filter *)
|
||||
addLoader("DEVICEENTRY,LZMADEVICE,DEVICEENTRY2", nullptr);
|
||||
|
||||
linker->addSection("COMPRESSED_LZMA", compressed_lzma, c_len_lzma, 0);
|
||||
addLoader("LZMAENTRY,NRV2B160,NRVDDONE,NRVDECO1,NRVGTD00,NRVDECO2",
|
||||
nullptr);
|
||||
addLoader("LZMAENTRY,NRV2B160,NRVDDONE,NRVDECO1,NRVGTD00,NRVDECO2", nullptr);
|
||||
|
||||
}
|
||||
else if (device_driver)
|
||||
} else if (device_driver)
|
||||
addLoader("DEVICEENTRY,DEVICEENTRY2", nullptr);
|
||||
|
||||
addLoader("EXEENTRY",
|
||||
M_IS_LZMA(ph.method) && device_driver ? "LONGSUB" : "SHORTSUB",
|
||||
"JNCDOCOPY",
|
||||
relocsize ? "EXERELPU" : "",
|
||||
"EXEMAIN4",
|
||||
M_IS_LZMA(ph.method) ? "" : "EXEMAIN4B",
|
||||
"EXEMAIN4C",
|
||||
addLoader("EXEENTRY", M_IS_LZMA(ph.method) && device_driver ? "LONGSUB" : "SHORTSUB",
|
||||
"JNCDOCOPY", relocsize ? "EXERELPU" : "", "EXEMAIN4",
|
||||
M_IS_LZMA(ph.method) ? "" : "EXEMAIN4B", "EXEMAIN4C",
|
||||
M_IS_LZMA(ph.method) ? "COMPRESSED_LZMA_START,COMPRESSED_LZMA" : "",
|
||||
"+G5DXXXX,UPX1HEAD,EXECUTPO",
|
||||
nullptr
|
||||
);
|
||||
"+G5DXXXX,UPX1HEAD,EXECUTPO", nullptr);
|
||||
if (ph.method == M_NRV2B_8)
|
||||
addLoader("NRV2B16S", // decompressor
|
||||
ph.u_len > DI_LIMIT ? "N2B64K01" : "",
|
||||
"NRV2BEX1",
|
||||
opt->cpu == opt->CPU_8086 ? "N2BX8601" : "N2B28601",
|
||||
"NRV2BEX2",
|
||||
opt->cpu == opt->CPU_8086 ? "N2BX8602" : "N2B28602",
|
||||
"NRV2BEX3",
|
||||
ph.c_len > 0xffff ? "N2B64K02" : "",
|
||||
"NRV2BEX9",
|
||||
nullptr
|
||||
);
|
||||
addLoader("NRV2B16S", // decompressor
|
||||
ph.u_len > DI_LIMIT ? "N2B64K01" : "", "NRV2BEX1",
|
||||
opt->cpu == opt->CPU_8086 ? "N2BX8601" : "N2B28601", "NRV2BEX2",
|
||||
opt->cpu == opt->CPU_8086 ? "N2BX8602" : "N2B28602", "NRV2BEX3",
|
||||
ph.c_len > 0xffff ? "N2B64K02" : "", "NRV2BEX9", nullptr);
|
||||
else if (ph.method == M_NRV2D_8)
|
||||
addLoader("NRV2D16S",
|
||||
ph.u_len > DI_LIMIT ? "N2D64K01" : "",
|
||||
"NRV2DEX1",
|
||||
opt->cpu == opt->CPU_8086 ? "N2DX8601" : "N2D28601",
|
||||
"NRV2DEX2",
|
||||
opt->cpu == opt->CPU_8086 ? "N2DX8602" : "N2D28602",
|
||||
"NRV2DEX3",
|
||||
ph.c_len > 0xffff ? "N2D64K02" : "",
|
||||
"NRV2DEX9",
|
||||
nullptr
|
||||
);
|
||||
addLoader("NRV2D16S", ph.u_len > DI_LIMIT ? "N2D64K01" : "", "NRV2DEX1",
|
||||
opt->cpu == opt->CPU_8086 ? "N2DX8601" : "N2D28601", "NRV2DEX2",
|
||||
opt->cpu == opt->CPU_8086 ? "N2DX8602" : "N2D28602", "NRV2DEX3",
|
||||
ph.c_len > 0xffff ? "N2D64K02" : "", "NRV2DEX9", nullptr);
|
||||
else if (ph.method == M_NRV2E_8)
|
||||
addLoader("NRV2E16S",
|
||||
ph.u_len > DI_LIMIT ? "N2E64K01" : "",
|
||||
"NRV2EEX1",
|
||||
opt->cpu == opt->CPU_8086 ? "N2EX8601" : "N2E28601",
|
||||
"NRV2EEX2",
|
||||
opt->cpu == opt->CPU_8086 ? "N2EX8602" : "N2E28602",
|
||||
"NRV2EEX3",
|
||||
ph.c_len > 0xffff ? "N2E64K02" : "",
|
||||
"NRV2EEX9",
|
||||
nullptr
|
||||
);
|
||||
else if M_IS_LZMA(ph.method)
|
||||
addLoader("NRV2E16S", ph.u_len > DI_LIMIT ? "N2E64K01" : "", "NRV2EEX1",
|
||||
opt->cpu == opt->CPU_8086 ? "N2EX8601" : "N2E28601", "NRV2EEX2",
|
||||
opt->cpu == opt->CPU_8086 ? "N2EX8602" : "N2E28602", "NRV2EEX3",
|
||||
ph.c_len > 0xffff ? "N2E64K02" : "", "NRV2EEX9", nullptr);
|
||||
else if M_IS_LZMA (ph.method)
|
||||
return;
|
||||
else
|
||||
throwInternalError("unknown compression method");
|
||||
@@ -270,25 +210,22 @@ void PackExe::buildLoader(const Filter *)
|
||||
addLoaderEpilogue(flag);
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
//
|
||||
**************************************************************************/
|
||||
|
||||
int PackExe::readFileHeader()
|
||||
{
|
||||
int PackExe::readFileHeader() {
|
||||
ih_exesize = ih_imagesize = ih_overlay = 0;
|
||||
fi->readx(&ih,sizeof(ih));
|
||||
if (ih.ident != 'M' + 'Z'*256 && ih.ident != 'Z' + 'M'*256)
|
||||
fi->readx(&ih, sizeof(ih));
|
||||
if (ih.ident != 'M' + 'Z' * 256 && ih.ident != 'Z' + 'M' * 256)
|
||||
return 0;
|
||||
ih_exesize = ih.m512 + ih.p512*512 - (ih.m512 ? 512 : 0);
|
||||
ih_exesize = ih.m512 + ih.p512 * 512 - (ih.m512 ? 512 : 0);
|
||||
if (!ih_exesize) {
|
||||
ih_exesize = file_size;
|
||||
}
|
||||
ih_imagesize = ih_exesize - ih.headsize16*16;
|
||||
ih_imagesize = ih_exesize - ih.headsize16 * 16;
|
||||
ih_overlay = file_size - ih_exesize;
|
||||
if (file_size_u < sizeof(ih)
|
||||
|| ((ih.m512 | ih.p512) && ih.m512+ih.p512*512u < sizeof (ih)))
|
||||
if (file_size_u < sizeof(ih) || ((ih.m512 | ih.p512) && ih.m512 + ih.p512 * 512u < sizeof(ih)))
|
||||
throwCantPack("illegal exe header");
|
||||
if (file_size_u < ih_exesize || ih_imagesize <= 0 || ih_imagesize > ih_exesize)
|
||||
throwCantPack("exe header corrupted");
|
||||
@@ -298,20 +235,17 @@ int PackExe::readFileHeader()
|
||||
return UPX_F_DOS_EXE;
|
||||
}
|
||||
|
||||
|
||||
bool PackExe::canPack()
|
||||
{
|
||||
if (fn_has_ext(fi->getName(),"sys"))
|
||||
bool PackExe::canPack() {
|
||||
if (fn_has_ext(fi->getName(), "sys"))
|
||||
return false;
|
||||
if (!readFileHeader())
|
||||
return false;
|
||||
if (file_size < 1024)
|
||||
throwCantPack("file is too small");
|
||||
fi->seek(0x3c,SEEK_SET);
|
||||
fi->seek(0x3c, SEEK_SET);
|
||||
LE32 offs;
|
||||
fi->readx(&offs,sizeof (offs));
|
||||
if (ih.relocoffs >= 0x40 && offs)
|
||||
{
|
||||
fi->readx(&offs, sizeof(offs));
|
||||
if (ih.relocoffs >= 0x40 && offs) {
|
||||
if (opt->dos_exe.force_stub)
|
||||
opt->overlay = opt->COPY_OVERLAY;
|
||||
else
|
||||
@@ -320,20 +254,16 @@ bool PackExe::canPack()
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
//
|
||||
**************************************************************************/
|
||||
|
||||
static
|
||||
unsigned optimize_relocs(upx_byte *b, const unsigned size,
|
||||
const upx_byte *relocs, const unsigned nrelocs,
|
||||
upx_byte *crel, bool *has_9a)
|
||||
{
|
||||
static unsigned optimize_relocs(upx_byte *b, const unsigned size, const upx_byte *relocs,
|
||||
const unsigned nrelocs, upx_byte *crel, bool *has_9a) {
|
||||
if (opt->exact)
|
||||
throwCantPackExact();
|
||||
|
||||
upx_byte * const crel_save = crel;
|
||||
upx_byte *const crel_save = crel;
|
||||
unsigned i;
|
||||
unsigned seg_high = 0;
|
||||
#if 0
|
||||
@@ -345,14 +275,12 @@ unsigned optimize_relocs(upx_byte *b, const unsigned size,
|
||||
#endif
|
||||
|
||||
// pass 1 - find 0x9a bounds
|
||||
for (i = 0; i < nrelocs; i++)
|
||||
{
|
||||
unsigned addr = get_le32(relocs+4*i);
|
||||
for (i = 0; i < nrelocs; i++) {
|
||||
unsigned addr = get_le32(relocs + 4 * i);
|
||||
if (addr >= size - 1)
|
||||
throwCantPack("unexpected relocation 1");
|
||||
if (addr >= 3 && b[addr-3] == 0x9a)
|
||||
{
|
||||
unsigned seg = get_le16(b+addr);
|
||||
if (addr >= 3 && b[addr - 3] == 0x9a) {
|
||||
unsigned seg = get_le16(b + addr);
|
||||
if (seg > seg_high)
|
||||
seg_high = seg;
|
||||
#if 0
|
||||
@@ -371,10 +299,9 @@ unsigned optimize_relocs(upx_byte *b, const unsigned size,
|
||||
#endif
|
||||
}
|
||||
}
|
||||
//printf("%d %d\n", seg_low, seg_high);
|
||||
//printf("%d %d\n", off_low, off_high);
|
||||
//printf("%d %d\n", linear_low, linear_high);
|
||||
|
||||
// printf("%d %d\n", seg_low, seg_high);
|
||||
// printf("%d %d\n", off_low, off_high);
|
||||
// printf("%d %d\n", linear_low, linear_high);
|
||||
|
||||
// pass 2 - reloc
|
||||
|
||||
@@ -383,37 +310,30 @@ unsigned optimize_relocs(upx_byte *b, const unsigned size,
|
||||
unsigned ones = 0;
|
||||
unsigned es = 0, di, t;
|
||||
i = 0;
|
||||
do
|
||||
{
|
||||
unsigned addr = get_le32(relocs+4*i);
|
||||
set_le16(crel,di = addr & 0x0f);
|
||||
set_le16(crel+2,(addr >> 4) - es);
|
||||
do {
|
||||
unsigned addr = get_le32(relocs + 4 * i);
|
||||
set_le16(crel, di = addr & 0x0f);
|
||||
set_le16(crel + 2, (addr >> 4) - es);
|
||||
es = addr >> 4;
|
||||
crel += 4;
|
||||
|
||||
for (++i; i < nrelocs; i++)
|
||||
{
|
||||
addr = get_le32(relocs+4*i);
|
||||
//printf ("%x\n",es*16+di);
|
||||
if ((addr - es*16 > 0xfffe)
|
||||
|| (i == nrelocs - 1 && addr - es * 16 > 0xff00)
|
||||
)
|
||||
{
|
||||
for (++i; i < nrelocs; i++) {
|
||||
addr = get_le32(relocs + 4 * i);
|
||||
// printf ("%x\n",es*16+di);
|
||||
if ((addr - es * 16 > 0xfffe) || (i == nrelocs - 1 && addr - es * 16 > 0xff00)) {
|
||||
// segment change
|
||||
t = 1+(0xffff-di)/254;
|
||||
memset(crel,1,t);
|
||||
t = 1 + (0xffff - di) / 254;
|
||||
memset(crel, 1, t);
|
||||
crel += t;
|
||||
ones += t-1; // -1 is used to help the assembly stuff
|
||||
ones += t - 1; // -1 is used to help the assembly stuff
|
||||
break;
|
||||
}
|
||||
unsigned offs = addr - es*16;
|
||||
if (offs >= 3 && b[es*16 + offs-3] == 0x9a && offs > di + 3)
|
||||
{
|
||||
for (t = di; t < offs-3; t++)
|
||||
if (b[es*16+t] == 0x9a && get_le16(b+es*16+t+3) <= seg_high)
|
||||
unsigned offs = addr - es * 16;
|
||||
if (offs >= 3 && b[es * 16 + offs - 3] == 0x9a && offs > di + 3) {
|
||||
for (t = di; t < offs - 3; t++)
|
||||
if (b[es * 16 + t] == 0x9a && get_le16(b + es * 16 + t + 3) <= seg_high)
|
||||
break;
|
||||
if (t == offs-3)
|
||||
{
|
||||
if (t == offs - 3) {
|
||||
// code 0: search for 0x9a
|
||||
*crel++ = 0;
|
||||
di = offs;
|
||||
@@ -425,8 +345,7 @@ unsigned optimize_relocs(upx_byte *b, const unsigned size,
|
||||
if (t < 2)
|
||||
throwCantPack("unexpected relocation 2");
|
||||
|
||||
while (t >= 256)
|
||||
{
|
||||
while (t >= 256) {
|
||||
// code 1: add 254, don't reloc
|
||||
*crel++ = 1;
|
||||
t -= 254;
|
||||
@@ -438,20 +357,18 @@ unsigned optimize_relocs(upx_byte *b, const unsigned size,
|
||||
} while (i < nrelocs);
|
||||
*crel++ = 1;
|
||||
ones++;
|
||||
set_le16 (crel_save,ones);
|
||||
set_le16 (crel_save+2,seg_high);
|
||||
set_le16(crel_save, ones);
|
||||
set_le16(crel_save + 2, seg_high);
|
||||
|
||||
//OutputFile::dump("x.rel", crel_save, crel - crel_save);
|
||||
// OutputFile::dump("x.rel", crel_save, crel - crel_save);
|
||||
return (unsigned) (crel - crel_save);
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
//
|
||||
**************************************************************************/
|
||||
|
||||
void PackExe::pack(OutputFile *fo)
|
||||
{
|
||||
void PackExe::pack(OutputFile *fo) {
|
||||
unsigned ic;
|
||||
|
||||
if (ih.relocs > MAXRELOCS)
|
||||
@@ -459,13 +376,13 @@ void PackExe::pack(OutputFile *fo)
|
||||
checkOverlay(ih_overlay);
|
||||
|
||||
// alloc buffers
|
||||
relocsize = RSFCRI + 4*ih.relocs;
|
||||
ibuf.alloc(ih_imagesize+16+relocsize+2);
|
||||
obuf.allocForCompression(ih_imagesize+16+relocsize+2);
|
||||
relocsize = RSFCRI + 4 * ih.relocs;
|
||||
ibuf.alloc(ih_imagesize + 16 + relocsize + 2);
|
||||
obuf.allocForCompression(ih_imagesize + 16 + relocsize + 2);
|
||||
|
||||
// read image
|
||||
fi->seek(ih.headsize16*16,SEEK_SET);
|
||||
fi->readx(ibuf,ih_imagesize);
|
||||
fi->seek(ih.headsize16 * 16, SEEK_SET);
|
||||
fi->readx(ibuf, ih_imagesize);
|
||||
|
||||
checkAlreadyPacked(ibuf, UPX_MIN(ih_imagesize, 127u));
|
||||
|
||||
@@ -474,21 +391,19 @@ void PackExe::pack(OutputFile *fo)
|
||||
// relocations
|
||||
has_9a = false;
|
||||
upx_byte *w = ibuf + ih_imagesize;
|
||||
if (ih.relocs)
|
||||
{
|
||||
if (ih.relocs) {
|
||||
upx_byte *wr = w + RSFCRI;
|
||||
|
||||
fi->seek(ih.relocoffs,SEEK_SET);
|
||||
fi->readx(wr,4*ih.relocs);
|
||||
fi->seek(ih.relocoffs, SEEK_SET);
|
||||
fi->readx(wr, 4 * ih.relocs);
|
||||
|
||||
for (ic = 0; ic < ih.relocs; ic++)
|
||||
{
|
||||
unsigned jc = get_le32(wr+4*ic);
|
||||
set_le32(wr+4*ic, ((jc>>16)*16+(jc&0xffff)) & 0xfffff);
|
||||
for (ic = 0; ic < ih.relocs; ic++) {
|
||||
unsigned jc = get_le32(wr + 4 * ic);
|
||||
set_le32(wr + 4 * ic, ((jc >> 16) * 16 + (jc & 0xffff)) & 0xfffff);
|
||||
}
|
||||
qsort(wr,ih.relocs,4,le32_compare);
|
||||
qsort(wr, ih.relocs, 4, le32_compare);
|
||||
relocsize = optimize_relocs(ibuf, ih_imagesize, wr, ih.relocs, w, &has_9a);
|
||||
set_le16(w+relocsize, relocsize+2);
|
||||
set_le16(w + relocsize, relocsize + 2);
|
||||
relocsize += 2;
|
||||
if (relocsize > MAXRELOCS)
|
||||
throwCantPack("too many relocations");
|
||||
@@ -499,9 +414,7 @@ void PackExe::pack(OutputFile *fo)
|
||||
ucl_nrv2b_99_compress(w, in_len, out, &out_len, nullptr, 9, nullptr, nullptr);
|
||||
printf("reloc compress: %d -> %d\n", in_len, out_len);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
relocsize = 0;
|
||||
}
|
||||
|
||||
@@ -510,7 +423,8 @@ void PackExe::pack(OutputFile *fo)
|
||||
// prepare filter
|
||||
Filter ft(ph.level);
|
||||
// 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_lzma.max_num_probs = 1846 + (768 << 4); // ushort: ~28 KiB stack
|
||||
compressWithFilters(&ft, 32, &cconf);
|
||||
@@ -520,13 +434,11 @@ void PackExe::pack(OutputFile *fo)
|
||||
throwCantPack("decompressor limit exceeded, send a bugreport");
|
||||
|
||||
#if TESTING
|
||||
if (opt->debug.debug_level)
|
||||
{
|
||||
printf("image+relocs %d -> %d\n",ih_imagesize+relocsize,ph.c_len);
|
||||
printf("offsets: %d - %d\nmatches: %d - %d\nruns: %d - %d\n",
|
||||
0/*ph.min_offset_found*/,ph.max_offset_found,
|
||||
0/*ph.min_match_found*/,ph.max_match_found,
|
||||
0/*ph.min_run_found*/,ph.max_run_found);
|
||||
if (opt->debug.debug_level) {
|
||||
printf("image+relocs %d -> %d\n", ih_imagesize + relocsize, ph.c_len);
|
||||
printf("offsets: %d - %d\nmatches: %d - %d\nruns: %d - %d\n", 0 /*ph.min_offset_found*/,
|
||||
ph.max_offset_found, 0 /*ph.min_match_found*/, ph.max_match_found,
|
||||
0 /*ph.min_run_found*/, ph.max_run_found);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -534,22 +446,22 @@ void PackExe::pack(OutputFile *fo)
|
||||
|
||||
const unsigned lsize = getLoaderSize();
|
||||
MemBuffer loader(lsize);
|
||||
memcpy(loader,getLoader(),lsize);
|
||||
//OutputFile::dump("xxloader.dat", loader, lsize);
|
||||
memcpy(loader, getLoader(), lsize);
|
||||
// OutputFile::dump("xxloader.dat", loader, lsize);
|
||||
|
||||
// patch loader
|
||||
const unsigned packedsize = ph.c_len;
|
||||
const unsigned e_len = getLoaderSectionStart("EXECUTPO");
|
||||
const unsigned d_len = lsize - e_len;
|
||||
assert((e_len&15) == 0);
|
||||
assert((e_len & 15) == 0);
|
||||
|
||||
const unsigned copysize = (1+packedsize+d_len) & ~1;
|
||||
const unsigned firstcopy = copysize%0x10000 ? copysize%0x10000 : 0x10000;
|
||||
const unsigned copysize = (1 + packedsize + d_len) & ~1;
|
||||
const unsigned firstcopy = copysize % 0x10000 ? copysize % 0x10000 : 0x10000;
|
||||
|
||||
// set oh.min & oh.max
|
||||
ic = ih.min*16 + ih_imagesize;
|
||||
if (ic < oh.ss*16u + oh.sp)
|
||||
ic = oh.ss*16u + oh.sp;
|
||||
ic = ih.min * 16 + ih_imagesize;
|
||||
if (ic < oh.ss * 16u + oh.sp)
|
||||
ic = oh.ss * 16u + oh.sp;
|
||||
oh.min = (ic - (packedsize + lsize)) / 16;
|
||||
ic = oh.min + (ih.max - ih.min);
|
||||
oh.max = ic < 0xffff && ih.max != 0xffff ? ic : 0xffff;
|
||||
@@ -557,27 +469,23 @@ void PackExe::pack(OutputFile *fo)
|
||||
// set extra info
|
||||
unsigned char extra_info[9];
|
||||
unsigned eisize = 0;
|
||||
if (oh.ss != ih.ss)
|
||||
{
|
||||
set_le16(extra_info+eisize,ih.ss);
|
||||
if (oh.ss != ih.ss) {
|
||||
set_le16(extra_info + eisize, ih.ss);
|
||||
eisize += 2;
|
||||
assert((flag & SS) != 0); // set in fillExeHeader()
|
||||
assert((flag & SS) != 0); // set in fillExeHeader()
|
||||
}
|
||||
if (oh.sp != ih.sp)
|
||||
{
|
||||
set_le16(extra_info+eisize,ih.sp);
|
||||
if (oh.sp != ih.sp) {
|
||||
set_le16(extra_info + eisize, ih.sp);
|
||||
eisize += 2;
|
||||
assert((flag & SP) != 0); // set in fillExeHeader()
|
||||
assert((flag & SP) != 0); // set in fillExeHeader()
|
||||
}
|
||||
if (ih.min != oh.min)
|
||||
{
|
||||
set_le16(extra_info+eisize,ih.min);
|
||||
if (ih.min != oh.min) {
|
||||
set_le16(extra_info + eisize, ih.min);
|
||||
eisize += 2;
|
||||
flag |= MINMEM;
|
||||
}
|
||||
if (ih.max != oh.max)
|
||||
{
|
||||
set_le16(extra_info+eisize,ih.max);
|
||||
if (ih.max != oh.max) {
|
||||
set_le16(extra_info + eisize, ih.max);
|
||||
eisize += 2;
|
||||
flag |= MAXMEM;
|
||||
}
|
||||
@@ -592,28 +500,25 @@ void PackExe::pack(OutputFile *fo)
|
||||
linker->defineSymbol("decompressor_entry", decompressor_entry);
|
||||
|
||||
// patch loader
|
||||
if (flag & USEJUMP)
|
||||
{
|
||||
if (flag & USEJUMP) {
|
||||
// I use a relocation entry to set the original cs
|
||||
unsigned n = getLoaderSectionStart("EXEJUMPF") + 1;
|
||||
n += packedsize + 2;
|
||||
oh.relocs = 1;
|
||||
oh.firstreloc = (n & 0xf) + ((n >> 4) << 16);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
oh.relocs = 0;
|
||||
oh.firstreloc = ih.cs * 0x10000 + ih.ip;
|
||||
}
|
||||
|
||||
// g++ 3.1 does not like the following line...
|
||||
oh.relocoffs = offsetof(exe_header_t, firstreloc);
|
||||
//oh.relocoffs = ptr_udiff_bytes(&oh.firstreloc, &oh);
|
||||
// oh.relocoffs = ptr_udiff_bytes(&oh.firstreloc, &oh);
|
||||
|
||||
linker->defineSymbol("destination_segment", oh.ss - ph.c_len / 16 - e_len / 16);
|
||||
linker->defineSymbol("source_segment", e_len / 16 + (copysize - firstcopy) / 16);
|
||||
linker->defineSymbol("copy_offset", firstcopy - 2);
|
||||
linker->defineSymbol("words_to_copy",firstcopy / 2);
|
||||
linker->defineSymbol("words_to_copy", firstcopy / 2);
|
||||
|
||||
linker->defineSymbol("exe_stack_sp", oh.sp);
|
||||
linker->defineSymbol("exe_stack_ss", oh.ss);
|
||||
@@ -621,7 +526,7 @@ void PackExe::pack(OutputFile *fo)
|
||||
linker->defineSymbol("attribute", get_le16(ibuf + 4));
|
||||
linker->defineSymbol("orig_strategy", get_le16(ibuf + 6));
|
||||
|
||||
const unsigned outputlen = sizeof(oh)+lsize+packedsize+eisize;
|
||||
const unsigned outputlen = sizeof(oh) + lsize + packedsize + eisize;
|
||||
oh.m512 = outputlen & 511;
|
||||
oh.p512 = (outputlen + 511) >> 9;
|
||||
|
||||
@@ -631,20 +536,22 @@ void PackExe::pack(OutputFile *fo)
|
||||
defineDecompressorSymbols();
|
||||
relocateLoader();
|
||||
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
|
||||
#if TESTING
|
||||
if (opt->debug.debug_level)
|
||||
printf("\n%d %d %d %d\n",(int)sizeof(oh),e_len,packedsize,d_len);
|
||||
printf("\n%d %d %d %d\n", (int) sizeof(oh), e_len, packedsize, d_len);
|
||||
#endif
|
||||
fo->write(&oh,sizeof(oh));
|
||||
fo->write(loader,e_len); // entry
|
||||
fo->write(obuf,packedsize);
|
||||
fo->write(loader+e_len,d_len); // decompressor
|
||||
fo->write(extra_info,eisize);
|
||||
fo->write(&oh, sizeof(oh));
|
||||
fo->write(loader, e_len); // entry
|
||||
fo->write(obuf, packedsize);
|
||||
fo->write(loader + e_len, d_len); // decompressor
|
||||
fo->write(extra_info, eisize);
|
||||
assert(eisize <= 9);
|
||||
#if 0
|
||||
printf("%-13s: program hdr : %8ld bytes\n", getName(), (long) sizeof(oh));
|
||||
@@ -659,20 +566,18 @@ void PackExe::pack(OutputFile *fo)
|
||||
|
||||
// copy the overlay
|
||||
copyOverlay(fo, ih_overlay, obuf);
|
||||
//fprintf (stderr,"%x %x\n",relocsize,ph.u_len);
|
||||
// fprintf (stderr,"%x %x\n",relocsize,ph.u_len);
|
||||
|
||||
// finally check the compression ratio
|
||||
if (!checkFinalCompressionRatio(fo))
|
||||
throwNotCompressible();
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
//
|
||||
**************************************************************************/
|
||||
|
||||
int PackExe::canUnpack()
|
||||
{
|
||||
int PackExe::canUnpack() {
|
||||
if (!readFileHeader())
|
||||
return false;
|
||||
const unsigned off = ih.headsize16 * 16;
|
||||
@@ -681,19 +586,17 @@ int PackExe::canUnpack()
|
||||
return b && (off + ph.c_len <= file_size_u);
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
//
|
||||
**************************************************************************/
|
||||
|
||||
void PackExe::unpack(OutputFile *fo)
|
||||
{
|
||||
void PackExe::unpack(OutputFile *fo) {
|
||||
ibuf.alloc(file_size);
|
||||
obuf.allocForDecompression(ph.u_len);
|
||||
|
||||
// read the file
|
||||
fi->seek(ih.headsize16*16,SEEK_SET);
|
||||
fi->readx(ibuf,ih_imagesize);
|
||||
fi->seek(ih.headsize16 * 16, SEEK_SET);
|
||||
fi->readx(ibuf, ih_imagesize);
|
||||
|
||||
// get compressed data offset
|
||||
unsigned e_len = ph.buf_offset + ph.getPackHeaderSize();
|
||||
@@ -703,7 +606,7 @@ void PackExe::unpack(OutputFile *fo)
|
||||
checkOverlay(ih_overlay);
|
||||
|
||||
// decompress
|
||||
decompress(ibuf+e_len,obuf);
|
||||
decompress(ibuf + e_len, obuf);
|
||||
|
||||
unsigned imagesize = ih_imagesize;
|
||||
imagesize--;
|
||||
@@ -712,83 +615,84 @@ void PackExe::unpack(OutputFile *fo)
|
||||
unsigned relocn = 0;
|
||||
SPAN_S_VAR(upx_byte, relocs, obuf + ph.u_len, obuf);
|
||||
|
||||
MemBuffer wrkmem;
|
||||
if (!(flag & NORELOC))
|
||||
{
|
||||
relocs -= get_le16(obuf+ph.u_len-2);
|
||||
MemBuffer mb_wrkmem;
|
||||
SPAN_0_VAR(upx_byte, wrkmem, nullptr);
|
||||
if (!(flag & NORELOC)) {
|
||||
relocs -= get_le16(obuf + (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);
|
||||
const unsigned seghi = get_le16(relocs+2);
|
||||
const unsigned seghi = get_le16(relocs + 2);
|
||||
SPAN_S_VAR(const upx_byte, p, relocs + 4);
|
||||
|
||||
while (ones)
|
||||
{
|
||||
while (ones) {
|
||||
unsigned di = get_le16(p);
|
||||
es += get_le16(p+2);
|
||||
es += get_le16(p + 2);
|
||||
bool dorel = true;
|
||||
for (p += 4; ones && di < 0x10000; p++)
|
||||
{
|
||||
if (dorel)
|
||||
{
|
||||
set_le16(wrkmem+4*relocn,di);
|
||||
set_le16(wrkmem+2+4*relocn++,es);
|
||||
//printf ("%x\n",es*16+di);
|
||||
for (p += 4; ones && di < 0x10000; p++) {
|
||||
if (dorel) {
|
||||
set_le16(wrkmem + (4 * relocn), di);
|
||||
set_le16(wrkmem + (2 + 4 * relocn++), es);
|
||||
NO_printf("%x\n", es * 16 + di);
|
||||
}
|
||||
dorel = true;
|
||||
if (*p == 0)
|
||||
{
|
||||
if (*p == 0) {
|
||||
SPAN_S_VAR(const upx_byte, q, obuf);
|
||||
|
||||
for (q = obuf+es*16+di; !(*q == 0x9a && get_le16(q+3) <= seghi); q++)
|
||||
;
|
||||
di = ptr_diff_bytes(q, obuf+es*16) + 3;
|
||||
}
|
||||
else if (*p == 1)
|
||||
{
|
||||
for (q = obuf + (es * 16 + di); !(*q == 0x9a && get_le16(q + 3) <= seghi);
|
||||
q++) {
|
||||
}
|
||||
di = ptr_diff_bytes(q, obuf + (es * 16)) + 3;
|
||||
} else if (*p == 1) {
|
||||
di += 254;
|
||||
if (di < 0x10000)
|
||||
ones--;
|
||||
dorel = false;
|
||||
}
|
||||
else
|
||||
} else
|
||||
di += *p;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// fill new exe header
|
||||
memset(&oh,0,sizeof(oh));
|
||||
oh.ident = 'M' + 'Z'*256;
|
||||
memset(&oh, 0, sizeof(oh));
|
||||
oh.ident = 'M' + 'Z' * 256;
|
||||
|
||||
if (relocn)
|
||||
{
|
||||
if (relocn) {
|
||||
oh.relocs = relocn;
|
||||
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;
|
||||
oh.m512 = outputlen & 511;
|
||||
oh.p512 = (outputlen + 511) >> 9;
|
||||
oh.headsize16 = 2+relocn/4;
|
||||
oh.headsize16 = 2 + relocn / 4;
|
||||
|
||||
oh.max = ih.max;
|
||||
oh.min = ih.min;
|
||||
oh.sp = ih.sp;
|
||||
oh.ss = ih.ss;
|
||||
|
||||
if (flag & MAXMEM)
|
||||
{ imagesize -= 2; oh.max = get_le16(ibuf+imagesize); }
|
||||
if (flag & MINMEM)
|
||||
{ imagesize -= 2; oh.min = 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); }
|
||||
if (flag & MAXMEM) {
|
||||
imagesize -= 2;
|
||||
oh.max = get_le16(ibuf + imagesize);
|
||||
}
|
||||
if (flag & MINMEM) {
|
||||
imagesize -= 2;
|
||||
oh.min = 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.cs = ip >> 16;
|
||||
|
||||
@@ -798,20 +702,16 @@ void PackExe::unpack(OutputFile *fo)
|
||||
return;
|
||||
|
||||
// write header + relocations + uncompressed file
|
||||
fo->write(&oh,sizeof(oh));
|
||||
fo->write(&oh, sizeof(oh));
|
||||
if (relocn)
|
||||
fo->write(wrkmem,relocn*4);
|
||||
fo->write(obuf, ptr_diff_bytes(relocs, obuf));
|
||||
fo->write(wrkmem, relocn * 4);
|
||||
fo->write(obuf, ptr_udiff_bytes(relocs, obuf));
|
||||
|
||||
// copy the overlay
|
||||
copyOverlay(fo, ih_overlay, obuf);
|
||||
}
|
||||
|
||||
|
||||
Linker* PackExe::newLinker() const
|
||||
{
|
||||
return new ElfLinkerX86();
|
||||
}
|
||||
Linker *PackExe::newLinker() const { return new ElfLinkerX86(); }
|
||||
|
||||
/*
|
||||
|
||||
|
||||
+16
-28
@@ -2,8 +2,8 @@
|
||||
|
||||
This file is part of the UPX executable compressor.
|
||||
|
||||
Copyright (C) 1996-2022 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2022 Laszlo Molnar
|
||||
Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2023 Laszlo Molnar
|
||||
All Rights Reserved.
|
||||
|
||||
UPX and the UCL library are free software; you can redistribute them
|
||||
@@ -25,24 +25,22 @@
|
||||
<markus@oberhumer.com> <ezerotven+github@gmail.com>
|
||||
*/
|
||||
|
||||
|
||||
#ifndef __UPX_P_EXE_H
|
||||
#define __UPX_P_EXE_H 1
|
||||
|
||||
#pragma once
|
||||
#ifndef UPX_P_EXE_H__
|
||||
#define UPX_P_EXE_H__ 1
|
||||
|
||||
/*************************************************************************
|
||||
// dos/exe
|
||||
**************************************************************************/
|
||||
|
||||
class PackExe final : public Packer
|
||||
{
|
||||
class PackExe final : public Packer {
|
||||
typedef Packer super;
|
||||
|
||||
public:
|
||||
PackExe(InputFile *f);
|
||||
virtual int getVersion() const override { return 13; }
|
||||
virtual int getFormat() const override { return UPX_F_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 int *getCompressionMethods(int method, int level) const override;
|
||||
virtual const int *getFilters() const override;
|
||||
@@ -54,13 +52,11 @@ public:
|
||||
virtual int canUnpack() override;
|
||||
|
||||
// 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)
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -71,10 +67,10 @@ protected:
|
||||
|
||||
virtual int fillExeHeader(struct exe_header_t *) const;
|
||||
virtual void buildLoader(const Filter *ft) override;
|
||||
virtual Linker* newLinker() const override;
|
||||
virtual Linker *newLinker() const override;
|
||||
void addLoaderEpilogue(int flag);
|
||||
|
||||
__packed_struct(exe_header_t)
|
||||
struct alignas(1) exe_header_t {
|
||||
LE16 ident;
|
||||
LE16 m512;
|
||||
LE16 p512;
|
||||
@@ -84,13 +80,13 @@ protected:
|
||||
LE16 max;
|
||||
LE16 ss;
|
||||
LE16 sp;
|
||||
char _[2]; // checksum
|
||||
char _[2]; // checksum
|
||||
LE16 ip;
|
||||
LE16 cs;
|
||||
LE16 relocoffs;
|
||||
char __[2]; // overlnum
|
||||
char __[2]; // overlnum
|
||||
LE32 firstreloc;
|
||||
__packed_struct_end()
|
||||
};
|
||||
|
||||
exe_header_t ih, oh;
|
||||
|
||||
@@ -102,20 +98,12 @@ protected:
|
||||
bool has_9a;
|
||||
bool device_driver;
|
||||
|
||||
enum {
|
||||
NORELOC = 1,
|
||||
USEJUMP = 2,
|
||||
SS = 4,
|
||||
SP = 8,
|
||||
MINMEM = 16,
|
||||
MAXMEM = 32
|
||||
};
|
||||
enum { 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;
|
||||
};
|
||||
|
||||
|
||||
#endif /* already included */
|
||||
|
||||
/* vim:set ts=4 sw=4 et: */
|
||||
|
||||
+505
-243
File diff suppressed because it is too large
Load Diff
+15
-12
@@ -2,9 +2,9 @@
|
||||
|
||||
This file is part of the UPX executable compressor.
|
||||
|
||||
Copyright (C) 1996-2022 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2022 Laszlo Molnar
|
||||
Copyright (C) 2000-2022 John F. Reiser
|
||||
Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2023 Laszlo Molnar
|
||||
Copyright (C) 2000-2023 John F. Reiser
|
||||
All Rights Reserved.
|
||||
|
||||
UPX and the UCL library are free software; you can redistribute them
|
||||
@@ -61,7 +61,7 @@ protected:
|
||||
unsigned const brka
|
||||
) = 0;
|
||||
virtual void defineSymbols(Filter const *);
|
||||
virtual void addStubEntrySections(Filter const *);
|
||||
virtual void addStubEntrySections(Filter const *, unsigned m_decompr);
|
||||
virtual void unpack(OutputFile *fo) override;
|
||||
unsigned old_data_off, old_data_len; // un_shlib
|
||||
|
||||
@@ -84,6 +84,7 @@ protected:
|
||||
unsigned lg2_page; // log2(PAGE_SIZE)
|
||||
unsigned page_size; // 1u<<lg2_page
|
||||
bool is_pie; // is Position-Independent-Executable (ET_DYN main program)
|
||||
unsigned is_asl; // is Android Shared Library
|
||||
unsigned xct_off; // shared library: file offset of SHT_EXECINSTR
|
||||
unsigned hatch_off; // file offset of escape hatch
|
||||
unsigned o_binfo; // offset to first b_info
|
||||
@@ -91,6 +92,7 @@ protected:
|
||||
upx_uint64_t xct_va; // minimum SHT_EXECINSTR virtual address
|
||||
upx_uint64_t jni_onload_va; // runtime &JNI_OnLoad
|
||||
upx_uint64_t user_init_va;
|
||||
upx_uint64_t plt_va, plt_off;
|
||||
unsigned user_init_off; // within file_image
|
||||
unsigned linfo_off;
|
||||
unsigned loader_offset; // during de-compression
|
||||
@@ -99,6 +101,7 @@ protected:
|
||||
unsigned char ei_class;
|
||||
unsigned char ei_data;
|
||||
unsigned char ei_osabi;
|
||||
unsigned char prev_method;
|
||||
char const *osabi_note;
|
||||
unsigned upx_dt_init; // DT_INIT, DT_PREINIT_ARRAY, DT_INIT_ARRAY
|
||||
static unsigned const DT_NUM = 34; // elf.h
|
||||
@@ -106,6 +109,7 @@ protected:
|
||||
|
||||
MemBuffer mb_shstrtab; // via ElfXX_Shdr
|
||||
char const *shstrtab;
|
||||
MemBuffer jump_slots; // is_asl de-compression fixing
|
||||
MemBuffer buildid_data;
|
||||
MemBuffer note_body; // concatenated contents of PT_NOTEs, if any
|
||||
unsigned note_size; // total size of PT_NOTEs
|
||||
@@ -269,11 +273,12 @@ protected:
|
||||
virtual int canUnpack() override; // bool, except -1: format known, but not packed
|
||||
|
||||
virtual void pack1(OutputFile *, Filter &) override; // generate executable header
|
||||
virtual void asl_pack2_Shdrs(OutputFile *); // AndroidSharedLibrary processes Shdrs
|
||||
virtual void asl_pack2_Shdrs(OutputFile *, unsigned pre_xct_top); // AndroidSharedLibrary processes Shdrs
|
||||
virtual int pack2(OutputFile *, Filter &) override; // append compressed data
|
||||
virtual off_t pack3(OutputFile *, Filter &) override; // append loader
|
||||
virtual void pack4(OutputFile *, Filter &) override; // append pack header
|
||||
virtual void unpack(OutputFile *fo) override;
|
||||
virtual void un_asl_dynsym(unsigned orig_file_size, OutputFile *);
|
||||
virtual void un_shlib_1(
|
||||
OutputFile *const fo,
|
||||
MemBuffer &o_elfhdrs,
|
||||
@@ -287,12 +292,10 @@ protected:
|
||||
unsigned old_dtinit,
|
||||
Elf64_Phdr const *phdro,
|
||||
Elf64_Phdr const *dynhdr, // in phdri
|
||||
OutputFile *fo,
|
||||
unsigned is_asl
|
||||
OutputFile *fo
|
||||
);
|
||||
virtual void unRela64(upx_uint64_t dt_rela, Elf64_Rela *rela0, unsigned relasz,
|
||||
MemBuffer &membuf, upx_uint64_t const load_off, upx_uint64_t const old_dtinit,
|
||||
OutputFile *fo);
|
||||
upx_uint64_t const old_dtinit, OutputFile *fo);
|
||||
|
||||
virtual void generateElfHdr(
|
||||
OutputFile *,
|
||||
@@ -319,13 +322,14 @@ protected:
|
||||
Elf64_Phdr const *elf_find_ptype(unsigned type, Elf64_Phdr const *phdr0, unsigned phnum);
|
||||
Elf64_Shdr const *elf_find_section_name(char const *) const;
|
||||
Elf64_Shdr const *elf_find_section_type(unsigned) const;
|
||||
int is_LOAD64(Elf64_Phdr const *phdr) const; // beware confusion with (1+ LO_PROC)
|
||||
upx_uint64_t check_pt_load(Elf64_Phdr const *);
|
||||
upx_uint64_t check_pt_dynamic(Elf64_Phdr const *);
|
||||
void invert_pt_dynamic(Elf64_Dyn const *, upx_uint64_t dt_filesz);
|
||||
void const *elf_find_dynamic(unsigned) const;
|
||||
Elf64_Dyn const *elf_has_dynamic(unsigned) const;
|
||||
virtual upx_uint64_t elf_unsigned_dynamic(unsigned) const override;
|
||||
virtual int adjABS(Elf64_Sym *sym, unsigned delta);
|
||||
virtual int adjABS(Elf64_Sym *sym, unsigned long delta);
|
||||
|
||||
char const *get_str_name(unsigned st_name, unsigned symnum) const;
|
||||
char const *get_dynsym_name(unsigned symnum, unsigned relnum) const;
|
||||
@@ -340,7 +344,6 @@ protected:
|
||||
upx_uint64_t sz_dynseg; // PT_DYNAMIC.p_memsz
|
||||
upx_uint64_t so_slide;
|
||||
unsigned n_jmp_slot;
|
||||
upx_uint64_t plt_off;
|
||||
upx_uint64_t page_mask; // AND clears the offset-within-page
|
||||
|
||||
Elf64_Dyn const *dynseg; // from PT_DYNAMIC
|
||||
@@ -565,7 +568,7 @@ protected:
|
||||
virtual void pack1(OutputFile *, Filter &) override; // generate executable header
|
||||
|
||||
virtual void buildLoader(const Filter *) override;
|
||||
virtual void addStubEntrySections(Filter const *) override;
|
||||
virtual void addStubEntrySections(Filter const *, unsigned m_decompr) override;
|
||||
virtual Linker* newLinker() const override;
|
||||
virtual void defineSymbols(Filter const *) override;
|
||||
};
|
||||
|
||||
+3
-5
@@ -2,9 +2,9 @@
|
||||
|
||||
This file is part of the UPX executable compressor.
|
||||
|
||||
Copyright (C) 1996-2022 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2022 Laszlo Molnar
|
||||
Copyright (C) 2001-2022 John F. Reiser
|
||||
Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2023 Laszlo Molnar
|
||||
Copyright (C) 2001-2023 John F. Reiser
|
||||
All Rights Reserved.
|
||||
|
||||
UPX and the UCL library are free software; you can redistribute them
|
||||
@@ -49,8 +49,6 @@
|
||||
#define DT_STRSZ Elf32_Dyn::DT_STRSZ
|
||||
#endif
|
||||
|
||||
#define usizeof(x) ((unsigned) sizeof(x))
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
// linux/386 (generic "execve" format)
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user