diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 7f20b675..4be52be3 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -49,7 +49,7 @@ jobs: 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: + job-linux-cmake: # uses cmake + make if: ${{ true }} needs: [ job-rebuild-and-verify-stubs ] name: ${{ format('{0} cmake', matrix.os) }} @@ -123,10 +123,10 @@ jobs: - name: 'Run test suite build/extra/gcc/release' run: | export upx_testsuite_SRCDIR="$(readlink -en ../deps/upx-testsuite)" - testsuite_1=$(readlink -en ./misc/testsuite/upx_testsuite_1.sh) + testsuite_1="$(readlink -en ./misc/testsuite/upx_testsuite_1.sh)" env -C build/extra/gcc/release upx_exe=./upx bash "$testsuite_1" - job-macos-cmake: + job-macos-cmake: # uses cmake + make if: ${{ true }} needs: [ job-rebuild-and-verify-stubs ] name: ${{ format('{0} cmake', matrix.os) }} @@ -142,8 +142,11 @@ jobs: - name: 'Install brew packages' if: ${{ matrix.testsuite }} run: | - brew update - brew install coreutils + # testsuite needs working "readlink -en" and "sha256sum" + if ! test -e /usr/local/opt/coreutils/libexec/gnubin/readlink; then + brew update + brew install coreutils + fi - name: 'Check out code' uses: actions/checkout@v3 with: { submodules: true } @@ -195,10 +198,10 @@ jobs: run: | export PATH="/usr/local/opt/coreutils/libexec/gnubin:$PATH" export upx_testsuite_SRCDIR="$(readlink -en ../deps/upx-testsuite)" - testsuite_1=$(readlink -en ./misc/testsuite/upx_testsuite_1.sh) + testsuite_1="$(readlink -en ./misc/testsuite/upx_testsuite_1.sh)" env -C build/extra/clang/release upx_exe=./upx bash "$testsuite_1" - job-windows-cmake: + job-windows-cmake: # uses cmake + msbuild if: ${{ true }} needs: [ job-rebuild-and-verify-stubs ] name: ${{ format('{0} cmake', matrix.name) }} @@ -243,17 +246,17 @@ jobs: - name: 'Run basic tests' if: ${{ matrix.arch != 'amd64_arm64' }} run: | - cmake --build build/debug --config Debug --target RUN_TESTS - cmake --build build/release --config Release --target RUN_TESTS + ctest --test-dir build/debug -C Debug + ctest --test-dir build/release -C Release - name: 'Run test suite build/release' if: ${{ matrix.arch != 'amd64_arm64' }} shell: bash run: | export upx_testsuite_SRCDIR="$(readlink -en ../deps/upx-testsuite)" - testsuite_1=$(readlink -en ./misc/testsuite/upx_testsuite_1.sh) + testsuite_1="$(readlink -en ./misc/testsuite/upx_testsuite_1.sh)" env -C build/release/Release upx_exe=./upx bash "$testsuite_1" - job-windows-toolchains: + job-windows-toolchains: # build "by hand" using cmd.exe if: ${{ true }} needs: [ job-rebuild-and-verify-stubs ] name: ${{ format('windows {0}', matrix.name) }} @@ -290,7 +293,7 @@ jobs: with: vsversion: ${{ matrix.vsversion }} arch: ${{ matrix.arch }} - - name: 'Build' + - name: 'Build by hand' shell: cmd run: | @REM setup directories @@ -359,10 +362,10 @@ jobs: shell: bash run: | export upx_testsuite_SRCDIR="$(readlink -en ../deps/upx-testsuite)" - testsuite_1=$(readlink -en ./misc/testsuite/upx_testsuite_1.sh) + testsuite_1="$(readlink -en ./misc/testsuite/upx_testsuite_1.sh)" env -C build/$C/$B/upx upx_exe=./upx.exe bash "$testsuite_1" - job-linux-zigcc: + job-linux-zigcc: # uses cmake + make if: ${{ true }} needs: [ job-rebuild-and-verify-stubs ] name: ${{ format('zigcc {0} {1}', matrix.zig_target, matrix.zig_pic) }} diff --git a/.github/workflows/static-analyzer-clang.yml b/.github/workflows/static-analyzer-clang.yml index 74462355..1ffee67e 100644 --- a/.github/workflows/static-analyzer-clang.yml +++ b/.github/workflows/static-analyzer-clang.yml @@ -6,7 +6,7 @@ on: workflow_dispatch: jobs: - job-analyze-clang: + job-analyze-clang: # uses cmake + make strategy: fail-fast: false matrix: {container: ['alpine:3.16','alpine:3.17','alpine:3.18','alpine:edge','i386/alpine:edge']} diff --git a/.github/workflows/test-alpine-linux.yml b/.github/workflows/test-alpine-linux.yml index 31180f68..bb05b1e6 100644 --- a/.github/workflows/test-alpine-linux.yml +++ b/.github/workflows/test-alpine-linux.yml @@ -6,7 +6,7 @@ name: 'Test - Minimal Alpine build' on: [workflow_dispatch] jobs: - job-alpine-clang: + job-alpine-clang: # uses cmake + make strategy: { matrix: { container: ['alpine:edge','i386/alpine:edge'] } } name: ${{ format('clang {0}', matrix.container) }} runs-on: ubuntu-latest @@ -31,7 +31,8 @@ jobs: with: name: ${{ env.artifact_name }} path: 'upx*/build/*/upx' - job-alpine-gcc: + + job-alpine-gcc: # uses cmake + make strategy: { matrix: { container: ['alpine:edge','i386/alpine:edge'] } } name: ${{ format('gcc {0}', matrix.container) }} runs-on: ubuntu-latest @@ -56,3 +57,31 @@ jobs: with: name: ${{ env.artifact_name }} path: 'upx*/build/*/upx' + + job-alpine-by-hand: # uses shell + # and also uses a subdirectory "upx with space" in order to detect possible quoting issues + strategy: { matrix: { container: ['alpine:3.9','alpine:edge'] } } + name: ${{ format('gcc by-hand {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 dash g++ git mksh zsh + # 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 + path: 'upx with space' + - name: 'Build by-hand with bash' + run: 'bash "./upx with space/misc/scripts/build_upx_by_hand.sh"' + - name: 'Build by-hand with busybox sh' + run: 'busybox sh "./upx with space/misc/scripts/build_upx_by_hand.sh"' + - name: 'Build by-hand with dash' + run: 'dash "./upx with space/misc/scripts/build_upx_by_hand.sh"' + - name: 'Build by-hand with mksh' + run: 'mksh "./upx with space/misc/scripts/build_upx_by_hand.sh"' + - name: 'Build by-hand with zsh' + run: 'zsh "./upx with space/misc/scripts/build_upx_by_hand.sh"' diff --git a/.github/workflows/test-cmake-default.yml b/.github/workflows/test-cmake-default.yml index d25f2e1b..bbe297b8 100644 --- a/.github/workflows/test-cmake-default.yml +++ b/.github/workflows/test-cmake-default.yml @@ -1,10 +1,19 @@ # Copyright (C) Markus Franz Xaver Johannes Oberhumer name: 'Test - CMake default build type' + on: [workflow_dispatch] + +env: + DEBIAN_FRONTEND: noninteractive + jobs: - job-cmake-make: +# +# single-config generators - these use and respect CMAKE_BUILD_TYPE +# + + cmake-make: runs-on: ubuntu-latest steps: - name: 'Check out code' @@ -12,13 +21,16 @@ jobs: with: { submodules: true } - name: 'Config, build, test and install' run: | - cmake -S . -B build/default + cmake -S . -B build/default -G "Unix Makefiles" cmake --build build/default --parallel --verbose ctest --test-dir build/default - make -C build/default test (cd build/default && DESTDIR=$PWD/Install-default cmake --install .) + # "make test" also works + env -C build/default make test + # "make install" also works + env -C build/default DESTDIR=./Install-with-make make install - job-cmake-ninja: + cmake-ninja: runs-on: ubuntu-latest steps: - name: 'Check out code' @@ -26,30 +38,17 @@ jobs: with: { submodules: true } - name: 'Config, build, test and install' run: | - sudo apt-get install ninja-build + test -f /usr/bin/ninja || sudo apt-get install -y ninja-build cmake -S . -B build/default -G Ninja cmake --build build/default --parallel --verbose ctest --test-dir build/default - ninja -C build/default test (cd build/default && DESTDIR=$PWD/Install-default cmake --install .) + # "ninja test" also works + env -C build/default ninja test + # "ninja install" also works + env -C build/default DESTDIR=./Install-with-ninja ninja install - job-cmake-ninja-multi-config: - runs-on: ubuntu-latest - steps: - - name: 'Check out code' - uses: actions/checkout@v3 - with: { submodules: true } - - name: 'Config, build, test and install' - run: | - sudo apt-get install ninja-build - cmake -S . -B build/default -G "Ninja Multi-Config" - cmake --build build/default --parallel --verbose - # multi-config: ctest NEEDS a config - ctest --test-dir build/default -C Release - ninja -C build/default test - (cd build/default && DESTDIR=$PWD/Install-default cmake --install .) - - job-cmake-nmake: + cmake-nmake: runs-on: windows-2022 steps: - name: 'Check out code' @@ -65,10 +64,40 @@ jobs: cmake -S . -B build/default -G "NMake Makefiles" cmake --build build/default --parallel --verbose ctest --test-dir build/default + # "cmake --install" works on Windows as well, nice + env -C build/default DESTDIR=./Install-default cmake --install . + # "nmake test" also works env -C build/default nmake test - env DESTDIR=./Install-default cmake --install build/default + # "nmake install" also works + env -C build/default DESTDIR=./Install-with-nmake nmake install - job-cmake-vsstudio-multi-config: +# +# multi-config generators - these use CMAKE_CONFIGURATION_TYPES, but the defaults seem inconsistent +# => when using multi-config generators always explicitly pass the requested build-config +# + + # ninja-multi-config seems to use the *first* element of CMAKE_CONFIGURATION_TYPES; nice + cmake-ninja-multi-config: + runs-on: ubuntu-latest + steps: + - name: 'Check out code' + uses: actions/checkout@v3 + with: { submodules: true } + - name: 'Config, build, test and install' + run: | + test -f /usr/bin/ninja || sudo apt-get install -y ninja-build + cmake -S . -B build/default -G "Ninja Multi-Config" + cmake --build build/default --parallel --verbose + # multi-config: ctest NEEDS a config + ctest --test-dir build/default -C Release + (cd build/default && DESTDIR=$PWD/Install-default cmake --install .) + # "ninja test" also works with multi-config + env -C build/default ninja test + # "ninja install" also works with multi-config + env -C build/default DESTDIR=./Install-with-ninja ninja install + + # vsstudio-multi-config (msbuild) seems to use "Debug" by default + cmake-vsstudio-multi-config: runs-on: windows-2022 steps: - name: 'Check out code' @@ -85,8 +114,10 @@ jobs: cmake --build build/default --parallel --verbose # multi-config: ctest NEEDS a config ctest --test-dir build/default -C Debug + # TODO: does cmake --install work? - job-cmake-xcode-multi-config: + # xcode-multi-config (xcodebuild) seems to use "Debug" by default, except for "cmake --install" (BUG?) + cmake-xcode-multi-config: runs-on: macos-12 steps: - name: 'Check out code' @@ -98,5 +129,5 @@ jobs: cmake --build build/default --parallel --verbose # multi-config: ctest NEEDS a config ctest --test-dir build/default -C Debug - # BUG multi-config: cmake --install defaults to "Release" !! + # BUG(?) multi-config: cmake --install defaults to "Release" !! (cd build/default && DESTDIR=$PWD/Install-default cmake --install . --config Debug) diff --git a/.github/workflows/weekly-ci-alpine-linux.yml b/.github/workflows/weekly-ci-alpine-linux.yml index 957bd80b..3b5f393f 100644 --- a/.github/workflows/weekly-ci-alpine-linux.yml +++ b/.github/workflows/weekly-ci-alpine-linux.yml @@ -2,6 +2,9 @@ # build under various Alpine Linux versions with clang and gcc, and # also test building with C++20 and C++23 +# also uses a subdirectory "upx with space" that contains whitespace in order +# to detect possible quoting issues + # info: Alpine 3.9 has clang-5, cmake-3.13.0 and gcc-8, which nicely # matches our minimal build requirements @@ -12,7 +15,7 @@ on: workflow_dispatch: jobs: - job-alpine-cmake: + job-alpine-cmake: # uses cmake + make strategy: fail-fast: false matrix: { container: ['alpine:3.9','alpine:3.10','alpine:3.11','alpine:3.12','alpine:3.13','alpine:3.14','alpine:3.15','alpine:3.16','alpine:3.17','alpine:3.18','alpine:edge','i386/alpine:edge'] } @@ -30,8 +33,8 @@ jobs: esac - name: ${{ format('Check out UPX {0} source code', github.ref_name) }} run: | - git clone --branch "$GITHUB_REF_NAME" --depth 1 https://github.com/upx/upx - git -C upx submodule update --init + git clone --branch "$GITHUB_REF_NAME" --depth 1 https://github.com/upx/upx "upx with space" + git -C "upx with space" submodule update --init x="$(apk list -I "$(apk info -Wq "$(which clang)")")"; echo "clang_package=${x%% *}" >> $GITHUB_ENV x="$(apk list -I "$(apk info -Wq "$(which gcc)")")"; echo "gcc_package=${x%% *}" >> $GITHUB_ENV N=$(echo "upx-${GITHUB_REF_NAME}-${GITHUB_SHA:0:7}-weekly-ci-alpine-${{ matrix.container }}" | sed 's/[^0-9a-zA-Z_.-]/-/g') @@ -39,13 +42,13 @@ jobs: # build with default C11 and C++17 - name: ${{ format('Build clang Release with {0}', env.clang_package) }} - run: 'make -C upx UPX_XTARGET=clang-static CC="clang -static" CXX="clang++ -static"' + run: 'make -C "upx with space" UPX_XTARGET=clang-static CC="clang -static" CXX="clang++ -static"' - name: ${{ format('Build clang Debug with {0}', env.clang_package) }} - run: 'make -C upx UPX_XTARGET=clang-static CC="clang -static" CXX="clang++ -static" xtarget/debug' + run: 'make -C "upx with space" UPX_XTARGET=clang-static CC="clang -static" CXX="clang++ -static" xtarget/debug' - name: ${{ format('Build gcc Release with {0}', env.gcc_package) }} - run: 'make -C upx UPX_XTARGET=gcc-static CC="gcc -static" CXX="g++ -static"' + run: 'make -C "upx with space" UPX_XTARGET=gcc-static CC="gcc -static" CXX="g++ -static"' - name: ${{ format('Build gcc Debug with {0}', env.gcc_package) }} - run: 'make -C upx UPX_XTARGET=gcc-static CC="gcc -static" CXX="g++ -static" xtarget/debug' + run: 'make -C "upx with space" UPX_XTARGET=gcc-static CC="gcc -static" CXX="g++ -static" xtarget/debug' - name: 'Update environment' run: | @@ -55,54 +58,66 @@ jobs: - name: ${{ format('Build clang C++20 Release with {0}', env.clang_package) }} if: ${{ contains(matrix.container, ':edge') }} run: | - make -C upx UPX_XTARGET=clang-cxx20-static CC="clang -std=gnu17 -static" CXX="clang++ -std=gnu++20 -static" + make -C "upx with space" UPX_XTARGET=clang-cxx20-static CC="clang -std=gnu17 -static" CXX="clang++ -std=gnu++20 -static" - name: ${{ format('Build clang C++20 Debug with {0}', env.clang_package) }} if: ${{ contains(matrix.container, ':edge') }} run: | - make -C upx UPX_XTARGET=clang-cxx20-static CC="clang -std=gnu17 -static" CXX="clang++ -std=gnu++20 -static" xtarget/debug + make -C "upx with space" UPX_XTARGET=clang-cxx20-static CC="clang -std=gnu17 -static" CXX="clang++ -std=gnu++20 -static" xtarget/debug - name: ${{ format('Build gcc C++20 Release with {0}', env.gcc_package) }} if: ${{ contains(matrix.container, ':edge') }} run: | - make -C upx UPX_XTARGET=gcc-cxx20-static CC="gcc -std=gnu17 -static" CXX="g++ -std=gnu++20 -static" + make -C "upx with space" UPX_XTARGET=gcc-cxx20-static CC="gcc -std=gnu17 -static" CXX="g++ -std=gnu++20 -static" - name: ${{ format('Build gcc C++20 Debug with {0}', env.gcc_package) }} if: ${{ contains(matrix.container, ':edge') }} run: | - make -C upx UPX_XTARGET=gcc-cxx20-static CC="gcc -std=gnu17 -static" CXX="g++ -std=gnu++20 -static" xtarget/debug + make -C "upx with space" UPX_XTARGET=gcc-cxx20-static CC="gcc -std=gnu17 -static" CXX="g++ -std=gnu++20 -static" xtarget/debug # build with C23 and C++23 on alpine:edge - name: ${{ format('Build clang C++23 Release with {0}', env.clang_package) }} if: ${{ contains(matrix.container, ':edge') }} run: | - make -C upx UPX_XTARGET=clang-cxx23-static CC="clang -std=gnu2x -static" CXX="clang++ -std=gnu++2b -static" + make -C "upx with space" UPX_XTARGET=clang-cxx23-static CC="clang -std=gnu2x -static" CXX="clang++ -std=gnu++2b -static" - name: ${{ format('Build clang C++23 Debug with {0}', env.clang_package) }} if: ${{ contains(matrix.container, ':edge') }} run: | - make -C upx UPX_XTARGET=clang-cxx23-static CC="clang -std=gnu2x -static" CXX="clang++ -std=gnu++2b -static" xtarget/debug + make -C "upx with space" UPX_XTARGET=clang-cxx23-static CC="clang -std=gnu2x -static" CXX="clang++ -std=gnu++2b -static" xtarget/debug - name: ${{ format('Build gcc C++23 Release with {0}', env.gcc_package) }} if: ${{ contains(matrix.container, ':edge') }} run: | - make -C upx UPX_XTARGET=gcc-cxx23-static CC="gcc -std=gnu2x -static" CXX="g++ -std=gnu++23 -static" + make -C "upx with space" UPX_XTARGET=gcc-cxx23-static CC="gcc -std=gnu2x -static" CXX="g++ -std=gnu++23 -static" - name: ${{ format('Build gcc C++23 Debug with {0}', env.gcc_package) }} if: ${{ contains(matrix.container, ':edge') }} run: | - make -C upx UPX_XTARGET=gcc-cxx23-static CC="gcc -std=gnu2x -static" CXX="g++ -std=gnu++23 -static" xtarget/debug + make -C "upx with space" UPX_XTARGET=gcc-cxx23-static CC="gcc -std=gnu2x -static" CXX="g++ -std=gnu++23 -static" xtarget/debug - - { name: 'Strip release binaries', run: 'strip -p --strip-unneeded upx/build/*/*/release/upx' } + - { name: 'Strip release binaries', run: 'strip -p --strip-unneeded "upx with space"/build/*/*/release/upx' } - name: ${{ format('Upload artifact {0}', env.artifact_name) }} if: ${{ !startsWith(matrix.container, 'i386/') }} # i386: missing nodejs on host uses: actions/upload-artifact@v3 with: name: ${{ env.artifact_name }} - path: 'upx*/build/*/*/*/upx' + path: 'upx with space*/build/*/*/*/upx' - - { name: 'Run basic tests clang Release', run: 'make -C upx/build/xtarget/clang-static/release test' } - - { name: 'Run basic tests clang Debug', run: 'make -C upx/build/xtarget/clang-static/debug test' } - - { name: 'Run basic tests gcc Release', run: 'make -C upx/build/xtarget/gcc-static/release test' } - - { name: 'Run basic tests gcc Debug', run: 'make -C upx/build/xtarget/gcc-static/debug test' } + - { name: 'Run basic tests clang Release', run: 'make -C "upx with space"/build/xtarget/clang-static/release test' } + - { name: 'Run basic tests clang Debug', run: 'make -C "upx with space"/build/xtarget/clang-static/debug test' } + - { name: 'Run basic tests gcc Release', run: 'make -C "upx with space"/build/xtarget/gcc-static/release test' } + - { name: 'Run basic tests gcc Debug', run: 'make -C "upx with space"/build/xtarget/gcc-static/debug test' } - name: 'Run basic tests C++20 and C++23' if: ${{ contains(matrix.container, ':edge') }} run: | - for dir in upx/build/xtarget/*-cxx*/*; do + for dir in "upx with space"/build/xtarget/*-cxx*/*; do echo "===== $dir" - make -C $dir test + make -C "$dir" test done + - name: 'Run install tests' + run: | + (cd "upx with space"/build/xtarget/clang-static/debug && DESTDIR="$PWD/Install with cmake" cmake --install .) + (cd "upx with space"/build/xtarget/clang-static/debug && DESTDIR="$PWD/Install with make" make install) + (cd "upx with space"/build/xtarget/clang-static/release && DESTDIR="$PWD/Install with cmake" cmake --install .) + (cd "upx with space"/build/xtarget/clang-static/release && DESTDIR="$PWD/Install with make" make install) + (cd "upx with space"/build/xtarget/gcc-static/debug && DESTDIR="$PWD/Install with cmake" cmake --install .) + (cd "upx with space"/build/xtarget/gcc-static/debug && DESTDIR="$PWD/Install with make" make install) + (cd "upx with space"/build/xtarget/gcc-static/release && DESTDIR="$PWD/Install with cmake" cmake --install .) + (cd "upx with space"/build/xtarget/gcc-static/release && DESTDIR="$PWD/Install with make" make install) + +# vim:set ts=2 sw=2 et: diff --git a/.github/workflows/weekly-ci-cmake-macos-xcode.yml b/.github/workflows/weekly-ci-cmake-macos-xcode.yml index 36d382bd..5d5ad7d4 100644 --- a/.github/workflows/weekly-ci-cmake-macos-xcode.yml +++ b/.github/workflows/weekly-ci-cmake-macos-xcode.yml @@ -8,7 +8,7 @@ on: workflow_dispatch: jobs: - job-cmake-macos-xcode: + job-cmake-macos-xcode: # uses cmake + xcodebuild name: ${{ format('{0} cmake Xcode', matrix.os) }} runs-on: ${{ matrix.os }} strategy: diff --git a/.github/workflows/weekly-ci-cmake-windows-nmake.yml b/.github/workflows/weekly-ci-cmake-windows-nmake.yml index 5ef0b9d2..e028593e 100644 --- a/.github/workflows/weekly-ci-cmake-windows-nmake.yml +++ b/.github/workflows/weekly-ci-cmake-windows-nmake.yml @@ -8,7 +8,7 @@ on: workflow_dispatch: jobs: - job-cmake-windows-nmake: + job-cmake-windows-nmake: # uses cmake + nmake name: ${{ format('vs{0} {1}', matrix.vsversion, matrix.arch) }} runs-on: ${{ matrix.os }} strategy: diff --git a/.github/workflows/weekly-ci-zigcc.yml b/.github/workflows/weekly-ci-zigcc.yml index 50b5178b..526f2655 100644 --- a/.github/workflows/weekly-ci-zigcc.yml +++ b/.github/workflows/weekly-ci-zigcc.yml @@ -12,7 +12,7 @@ env: ZIG_DIST_VERSION: 0.11.0-dev.3859+88284c124 jobs: - job-linux-zigcc: + job-linux-zigcc: # uses cmake + make name: ${{ format('zigcc {0} {1}', matrix.zig_target, matrix.zig_pic) }} runs-on: ubuntu-latest container: 'alpine:3.18' # older versions such as alpine:3.12 also work; no-container also works diff --git a/CMakeLists.txt b/CMakeLists.txt index 82c30db6..177ad8b2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -31,7 +31,7 @@ else() endif() # test config options (see below) -# NOTE: self-pack test can only work if the host executable format is supported by UPX! +# IMPORTANT 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) #*********************************************************************** @@ -360,7 +360,7 @@ if(NOT CMAKE_CROSSCOMPILING) add_test(NAME upx-help COMMAND upx --help) endif() if(NOT CMAKE_CROSSCOMPILING AND NOT UPX_CONFIG_DISABLE_SELF_PACK_TEST) - # NOTE: these tests can only work if the host executable format is supported by UPX! + # IMPORTANT NOTE: these tests can only work if the host executable format is supported by UPX! function(upx_add_test) set(name ${ARGV0}) list(REMOVE_AT ARGV 0) @@ -370,11 +370,11 @@ if(NOT CMAKE_CROSSCOMPILING AND NOT UPX_CONFIG_DISABLE_SELF_PACK_TEST) set(exe ${CMAKE_EXECUTABLE_SUFFIX}) set(upx_self_exe "$") set(fo "--force-overwrite") - upx_add_test(upx-self-pack upx -3 ${upx_self_exe} ${fo} -o upx-packed${exe}) - upx_add_test(upx-self-pack-n2b upx -3 --nrv2b ${upx_self_exe} ${fo} -o upx-packed-n2b${exe}) - upx_add_test(upx-self-pack-n2d upx -3 --nrv2d ${upx_self_exe} ${fo} -o upx-packed-n2d${exe}) - upx_add_test(upx-self-pack-n2e upx -3 --nrv2e ${upx_self_exe} ${fo} -o upx-packed-n2e${exe}) - upx_add_test(upx-self-pack-lzma upx -1 --lzma ${upx_self_exe} ${fo} -o upx-packed-lzma${exe}) + upx_add_test(upx-self-pack upx -3 "${upx_self_exe}" ${fo} -o upx-packed${exe}) + upx_add_test(upx-self-pack-n2b upx -3 --nrv2b "${upx_self_exe}" ${fo} -o upx-packed-n2b${exe}) + upx_add_test(upx-self-pack-n2d upx -3 --nrv2d "${upx_self_exe}" ${fo} -o upx-packed-n2d${exe}) + upx_add_test(upx-self-pack-n2e upx -3 --nrv2e "${upx_self_exe}" ${fo} -o upx-packed-n2e${exe}) + upx_add_test(upx-self-pack-lzma upx -1 --lzma "${upx_self_exe}" ${fo} -o upx-packed-lzma${exe}) upx_add_test(upx-list upx -l upx-packed${exe} upx-packed-n2b${exe} upx-packed-n2d${exe} upx-packed-n2e${exe} upx-packed-lzma${exe}) upx_add_test(upx-fileinfo upx --fileinfo upx-packed${exe} upx-packed-n2b${exe} upx-packed-n2d${exe} upx-packed-n2e${exe} upx-packed-lzma${exe}) upx_add_test(upx-test upx -t upx-packed${exe} upx-packed-n2b${exe} upx-packed-n2d${exe} upx-packed-n2e${exe} upx-packed-lzma${exe}) diff --git a/misc/cross-compile-upx-with-podman/build-all-inside-container.sh b/misc/cross-compile-upx-with-podman/build-all-inside-container.sh index fea2226a..bd5ca62a 100755 --- a/misc/cross-compile-upx-with-podman/build-all-inside-container.sh +++ b/misc/cross-compile-upx-with-podman/build-all-inside-container.sh @@ -15,7 +15,7 @@ fi # go to upx top-level directory cd "$argv0dir/../.." || exit 1 pwd -[[ -f src/version.h ]] || exit 1 # sanity check +test -f src/version.h || exit 1 # sanity check function run_config_and_build { # requires: AR CC CXX RANLIB diff --git a/misc/scripts/build_upx_by_hand.sh b/misc/scripts/build_upx_by_hand.sh new file mode 100755 index 00000000..a06784a3 --- /dev/null +++ b/misc/scripts/build_upx_by_hand.sh @@ -0,0 +1,100 @@ +#! /bin/sh +## vim:set ts=4 sw=4 et: +set -e + +# +# build UPX "by hand", using POSIX shell and a minimal number of compilation flags +# Copyright (C) Markus Franz Xaver Johannes Oberhumer +# + +# shell init +### set -x # enable logging +DUALCASE=1; export DUALCASE # for MKS sh +test -n "${ZSH_VERSION+set}" && emulate sh # for zsh +argv0="$0"; argv0abs="$(readlink -fn "$argv0")"; argv0dir="$(dirname "$argv0abs")" +# HINT: set "argv0dir" manually if your system does not have "readlink" + +# toolchain settings and flags +CC="${CC:-cc}" +CXX="${CXX:-c++ -std=gnu++17}" +AR="${AR:-ar}" +# HINT: use "export AR=false" if "$AR rcs" does not work on your system; see below +if test "x$AR" = "x0" || test "x$AR" = "xfalse" || test "x$AR" = "x/bin/false"; then + AR="" # do not use $AR +fi +# protect against security threats caused by misguided compiler "optimizations" +mandatory_flags="-fno-strict-aliasing -fno-strict-overflow -funsigned-char" +# not mandatory and not minimal, but usually a good idea: +### mandatory_flags="-Wall -O2 $mandatory_flags" +CC="$CC $mandatory_flags" +CXX="$CXX $mandatory_flags" + +# go to upx top-level directory +cd "$argv0dir/../.." || exit 1 +pwd +test -f src/version.h || exit 1 # sanity check +top_srcdir="$PWD" +rm -rf ./build/by-hand # WARNING: existing build-directory gets deleted! +mkdir -p ./build/by-hand + +# helper function +check_submodule() { + local f + for f in COPYING LICENSE LICENSE.txt; do + if test -f "$top_srcdir/vendor/$1/$f"; then + # create and enter build directory + mkdir -p "$top_srcdir/build/by-hand/$1" + cd "$top_srcdir/build/by-hand/$1" || exit 1 + echo "===== build $1 =====" + return 0 + fi + done + return 1 +} + +# build +if check_submodule bzip2; then + for f in "$top_srcdir"/vendor/bzip2/*.c; do + echo "CC $f" + $CC -c "$f" + done +fi +if check_submodule ucl; then + for f in "$top_srcdir"/vendor/ucl/src/*.c; do + echo "CC $f" + $CC -I"$top_srcdir"/vendor/ucl/include -I"$top_srcdir"/vendor/ucl -c "$f" + done +fi +if check_submodule zlib; then + for f in "$top_srcdir"/vendor/zlib/*.c; do + echo "CC $f" + $CC -DHAVE_STDARG_H -DHAVE_VSNPRINTF -DHAVE_UNISTD_H -c "$f" + done +fi +if check_submodule zstd; then + for f in "$top_srcdir"/vendor/zstd/lib/*/*.c; do + echo "CC $f" + $CC -DDYNAMIC_BMI2=0 -DZSTD_DISABLE_ASM -c "$f" + done +fi +echo "===== build UPX =====" +cd "$top_srcdir"/build/by-hand || exit 1 +for f in "$top_srcdir"/src/*.cpp "$top_srcdir"/src/*/*.cpp; do + echo "CXX $f" + $CXX -I"$top_srcdir"/vendor -c "$f" +done +# echo "===== link UPX =====" +if test "x$AR" = "x"; then + # link without using $AR + echo "CXX upx" + $CXX -o upx *.o */*.o +else + echo "AR libupx" + $AR rcs libupx_submodules.a */*.o + echo "CXX upx" + $CXX -o upx *.o -L. -lupx_submodules +fi +pwd +ls -l upx* + +echo "All done." diff --git a/src/bele.h b/src/bele.h index 8234b207..fa5df6e3 100644 --- a/src/bele.h +++ b/src/bele.h @@ -179,8 +179,8 @@ inline void set_le24(void *p, unsigned v) noexcept { } inline unsigned get_le26(const void *p) noexcept { return get_le32(p) & 0x03ffffff; } -inline unsigned get_le19_5(const void *p) noexcept { return 0x0007ffff & (get_le32(p) >> 5); } -inline unsigned get_le14_5(const void *p) noexcept { return 0x00003fff & (get_le32(p) >> 5); } +inline unsigned get_le19_5(const void *p) noexcept { return (get_le32(p) >> 5) & 0x0007ffff; } +inline unsigned get_le14_5(const void *p) noexcept { return (get_le32(p) >> 5) & 0x00003fff; } inline void set_le26(void *p, unsigned v) noexcept { // preserve the top 6 bits diff --git a/src/check/dt_check.cpp b/src/check/dt_check.cpp index cd3337de..1d8a25ec 100644 --- a/src/check/dt_check.cpp +++ b/src/check/dt_check.cpp @@ -115,6 +115,10 @@ ACC_COMPILE_TIME_ASSERT_HEADER(no_bswap64(0x0807060504030201ull) == 0x0807060504 ACC_COMPILE_TIME_ASSERT_HEADER(bswap16(0x04030201) == 0x0102) ACC_COMPILE_TIME_ASSERT_HEADER(bswap32(0x04030201) == 0x01020304) ACC_COMPILE_TIME_ASSERT_HEADER(bswap64(0x0807060504030201ull) == 0x0102030405060708ull) +ACC_COMPILE_TIME_ASSERT_HEADER(bswap16(bswap16(0xf4f3f2f1)) == no_bswap16(0xf4f3f2f1)) +ACC_COMPILE_TIME_ASSERT_HEADER(bswap32(bswap32(0xf4f3f2f1)) == no_bswap32(0xf4f3f2f1)) +ACC_COMPILE_TIME_ASSERT_HEADER(bswap64(bswap64(0xf8f7f6f5f4f3f2f1ull)) == + no_bswap64(0xf8f7f6f5f4f3f2f1ull)) #endif ACC_COMPILE_TIME_ASSERT_HEADER(usizeof(int) == sizeof(int)) diff --git a/src/util/xspan.h b/src/util/xspan.h index 3293355f..4a991e41 100644 --- a/src/util/xspan.h +++ b/src/util/xspan.h @@ -118,15 +118,15 @@ using XSPAN_NAMESPACE_NAME::raw_index_bytes; // overloaded for all classes // helper for implicit pointer conversions and MemBuffer overloads template -inline R *xspan_make_helper__(R * /*dummy*/, T *first) { +inline R *xspan_make_helper__(R * /*dummy*/, T *first) /*may_throw*/ { return first; // IMPORTANT: no cast here to detect bad usage } template -inline R *xspan_make_helper__(R * /*dummy*/, std::nullptr_t /*first*/) { +inline R *xspan_make_helper__(R * /*dummy*/, std::nullptr_t /*first*/) noexcept { return nullptr; } template -inline R *xspan_make_helper__(R * /*dummy*/, MemBuffer &mb) { +inline R *xspan_make_helper__(R * /*dummy*/, MemBuffer &mb) noexcept { return (R *) membuffer_get_void_ptr(mb); }