mirror of https://github.com/upx/upx.git
CI updates
This commit is contained in:
parent
0192b0b7e4
commit
57ad6bc37d
|
@ -12,8 +12,8 @@ env:
|
||||||
CMAKE_REQUIRED_QUIET: OFF
|
CMAKE_REQUIRED_QUIET: OFF
|
||||||
DEBIAN_FRONTEND: noninteractive
|
DEBIAN_FRONTEND: noninteractive
|
||||||
UPX_CMAKE_BUILD_FLAGS: --verbose
|
UPX_CMAKE_BUILD_FLAGS: --verbose
|
||||||
# 2023-09-05
|
# 2023-09-10
|
||||||
ZIG_DIST_VERSION: 0.12.0-dev.280+64d03faae
|
ZIG_DIST_VERSION: 0.12.0-dev.294+4d1432299
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
job-rebuild-and-verify-stubs:
|
job-rebuild-and-verify-stubs:
|
||||||
|
|
|
@ -14,7 +14,7 @@ jobs:
|
||||||
strategy:
|
strategy:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix: {container: ['alpine:3.16','alpine:3.17','alpine:3.18','alpine:edge','i386/alpine:edge']}
|
matrix: {container: ['alpine:3.16','alpine:3.17','alpine:3.18','alpine:edge','i386/alpine:edge']}
|
||||||
name: ${{ format('Analyze {0}', matrix.container) }}
|
name: ${{ format('Analyze clang-analyzer {0}', matrix.container) }}
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
container: ${{ matrix.container }}
|
container: ${{ matrix.container }}
|
||||||
steps:
|
steps:
|
||||||
|
|
|
@ -8,13 +8,14 @@ on:
|
||||||
env:
|
env:
|
||||||
CMAKE_REQUIRED_QUIET: OFF
|
CMAKE_REQUIRED_QUIET: OFF
|
||||||
DEBIAN_FRONTEND: noninteractive
|
DEBIAN_FRONTEND: noninteractive
|
||||||
|
VERBOSE: 1
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
job-alpine-by-hand: # uses a POSIX-compliant shell
|
job-alpine-by-hand: # uses a POSIX-compliant shell
|
||||||
# ...and also uses a subdirectory "upx with space" in order to detect possible quoting issues
|
# ...and also uses a subdirectory "upx with space" in order to detect possible quoting issues
|
||||||
# ...and also uses ccache as we are running the same build-script again and again
|
# ...and also uses ccache as we are running the same build-script again and again
|
||||||
if: github.repository_owner == 'upx'
|
if: github.repository_owner == 'upx'
|
||||||
strategy: { matrix: { container: ['alpine:3.9','alpine:3.18','alpine:edge'] } }
|
strategy: { matrix: { container: ['alpine:3.9','alpine:3.18','alpine:edge','i386/alpine:edge'] } }
|
||||||
name: ${{ format('gcc by-hand {0}', matrix.container) }}
|
name: ${{ format('gcc by-hand {0}', matrix.container) }}
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
container: ${{ matrix.container }}
|
container: ${{ matrix.container }}
|
||||||
|
@ -28,15 +29,17 @@ jobs:
|
||||||
esac
|
esac
|
||||||
echo "installing shells: $shells"
|
echo "installing shells: $shells"
|
||||||
apk update && apk upgrade && apk add ccache g++ git $shells
|
apk update && apk upgrade && apk add ccache g++ git $shells
|
||||||
# enable ccache
|
# enable ccache and some warnings
|
||||||
echo -e "CC=ccache gcc\nCXX=ccache g++ -std=gnu++17" >> $GITHUB_ENV
|
warn="-Wall -Wextra -Werror"
|
||||||
|
echo -e "CC=ccache gcc $warn\nCXX=ccache g++ -std=gnu++17 $warn" >> $GITHUB_ENV
|
||||||
# this seems to be needed when running in a container (beause of UID mismatch??)
|
# this seems to be needed when running in a container (beause of UID mismatch??)
|
||||||
git config --global --add safe.directory '*'
|
git config --global --add safe.directory '*'
|
||||||
- name: 'Check out code'
|
# create user upx:upx 2000:2000 for file system tests below ("sudo")
|
||||||
uses: actions/checkout@v4
|
adduser upx -u 2000 -D && cd /home/upx && chmod 00700 . && chown -R upx:upx .
|
||||||
with:
|
- name: ${{ format('Check out UPX {0} source code', github.ref_name) }}
|
||||||
submodules: true
|
run: |
|
||||||
path: 'upx with space'
|
git clone --branch "$GITHUB_REF_NAME" --depth 1 https://github.com/upx/upx "upx with space"
|
||||||
|
git -C "upx with space" submodule update --init
|
||||||
- name: 'Build by-hand with bash'
|
- name: 'Build by-hand with bash'
|
||||||
run: 'bash "./upx with space/misc/scripts/build_upx_by_hand.sh"'
|
run: 'bash "./upx with space/misc/scripts/build_upx_by_hand.sh"'
|
||||||
- name: 'Build by-hand with bash --posix'
|
- name: 'Build by-hand with bash --posix'
|
||||||
|
@ -81,3 +84,17 @@ jobs:
|
||||||
run: |
|
run: |
|
||||||
ccache -s
|
ccache -s
|
||||||
ccache -p
|
ccache -p
|
||||||
|
- name: 'Run file system test suite (busybox)'
|
||||||
|
run: |
|
||||||
|
apk add bash sudo
|
||||||
|
testsuite="$(readlink -fn "upx with space"/misc/testsuite/test_symlinks.sh)"
|
||||||
|
cd "upx with space"/build/by-hand
|
||||||
|
# IMPORTANT: do NOT run as user root!
|
||||||
|
chmod a+w . && sudo -u upx bash "$testsuite"
|
||||||
|
- name: 'Run file system test suite (coreutils)'
|
||||||
|
run: |
|
||||||
|
apk add bash coreutils sudo
|
||||||
|
testsuite="$(readlink -fn "upx with space"/misc/testsuite/test_symlinks.sh)"
|
||||||
|
cd "upx with space"/build/by-hand
|
||||||
|
# IMPORTANT: do NOT run as user root!
|
||||||
|
chmod a+w . && sudo -u upx bash "$testsuite"
|
||||||
|
|
|
@ -37,6 +37,8 @@ jobs:
|
||||||
# clang-dev is needed on older Alpine versions for clang headers like <emmintrin.h>
|
# clang-dev is needed on older Alpine versions for clang headers like <emmintrin.h>
|
||||||
*:3.[0-9]|*:3.10|*:3.11) apk add clang-dev ;;
|
*:3.[0-9]|*:3.10|*:3.11) apk add clang-dev ;;
|
||||||
esac
|
esac
|
||||||
|
# create user upx:upx 2000:2000 for file system tests below ("sudo")
|
||||||
|
adduser upx -u 2000 -D && cd /home/upx && chmod 00700 . && chown -R upx:upx .
|
||||||
- name: ${{ format('Check out UPX {0} source code', github.ref_name) }}
|
- name: ${{ format('Check out UPX {0} source code', github.ref_name) }}
|
||||||
run: |
|
run: |
|
||||||
git clone --branch "$GITHUB_REF_NAME" --depth 1 https://github.com/upx/upx "upx with space"
|
git clone --branch "$GITHUB_REF_NAME" --depth 1 https://github.com/upx/upx "upx with space"
|
||||||
|
@ -63,55 +65,55 @@ jobs:
|
||||||
|
|
||||||
# build with C17 and C++20 on alpine:edge
|
# build with C17 and C++20 on alpine:edge
|
||||||
- name: ${{ format('Build clang C++20 Release with {0}', env.clang_package) }}
|
- name: ${{ format('Build clang C++20 Release with {0}', env.clang_package) }}
|
||||||
if: ${{ contains(matrix.container, ':edge') }}
|
if: endsWith(matrix.container, ':edge')
|
||||||
run: |
|
run: |
|
||||||
make -C "upx with space" 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) }}
|
- name: ${{ format('Build clang C++20 Debug with {0}', env.clang_package) }}
|
||||||
if: ${{ contains(matrix.container, ':edge') }}
|
if: endsWith(matrix.container, ':edge')
|
||||||
run: |
|
run: |
|
||||||
make -C "upx with space" 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) }}
|
- name: ${{ format('Build gcc C++20 Release with {0}', env.gcc_package) }}
|
||||||
if: ${{ contains(matrix.container, ':edge') }}
|
if: endsWith(matrix.container, ':edge')
|
||||||
run: |
|
run: |
|
||||||
make -C "upx with space" 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) }}
|
- name: ${{ format('Build gcc C++20 Debug with {0}', env.gcc_package) }}
|
||||||
if: ${{ contains(matrix.container, ':edge') }}
|
if: endsWith(matrix.container, ':edge')
|
||||||
run: |
|
run: |
|
||||||
make -C "upx with space" 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
|
# build with C23 and C++23 on alpine:edge
|
||||||
- name: ${{ format('Build clang C++23 Release with {0}', env.clang_package) }}
|
- name: ${{ format('Build clang C++23 Release with {0}', env.clang_package) }}
|
||||||
if: ${{ contains(matrix.container, ':edge') }}
|
if: endsWith(matrix.container, ':edge')
|
||||||
run: |
|
run: |
|
||||||
make -C "upx with space" 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) }}
|
- name: ${{ format('Build clang C++23 Debug with {0}', env.clang_package) }}
|
||||||
if: ${{ contains(matrix.container, ':edge') }}
|
if: endsWith(matrix.container, ':edge')
|
||||||
run: |
|
run: |
|
||||||
make -C "upx with space" 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) }}
|
- name: ${{ format('Build gcc C++23 Release with {0}', env.gcc_package) }}
|
||||||
if: ${{ contains(matrix.container, ':edge') }}
|
if: endsWith(matrix.container, ':edge')
|
||||||
run: |
|
run: |
|
||||||
make -C "upx with space" 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) }}
|
- name: ${{ format('Build gcc C++23 Debug with {0}', env.gcc_package) }}
|
||||||
if: ${{ contains(matrix.container, ':edge') }}
|
if: endsWith(matrix.container, ':edge')
|
||||||
run: |
|
run: |
|
||||||
make -C "upx with space" 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
|
||||||
|
|
||||||
# build with -flto=auto on alpine:edge
|
# build with -flto=auto on alpine:edge
|
||||||
- name: ${{ format('Build clang LTO Release with {0}', env.clang_package) }}
|
- name: ${{ format('Build clang LTO Release with {0}', env.clang_package) }}
|
||||||
if: ${{ contains(matrix.container, ':edge') }}
|
if: endsWith(matrix.container, ':edge')
|
||||||
run: |
|
run: |
|
||||||
make -C "upx with space" UPX_XTARGET=clang-cxxlto-static CC="clang -flto=auto -static" CXX="clang++ -flto=auto -static"
|
make -C "upx with space" UPX_XTARGET=clang-cxxlto-static CC="clang -flto=auto -static" CXX="clang++ -flto=auto -static"
|
||||||
- name: ${{ format('Build clang LTO Debug with {0}', env.clang_package) }}
|
- name: ${{ format('Build clang LTO Debug with {0}', env.clang_package) }}
|
||||||
if: ${{ contains(matrix.container, ':edge') }}
|
if: endsWith(matrix.container, ':edge')
|
||||||
run: |
|
run: |
|
||||||
make -C "upx with space" UPX_XTARGET=clang-cxxlto-static CC="clang -flto=auto -static" CXX="clang++ -flto=auto -static" xtarget/debug
|
make -C "upx with space" UPX_XTARGET=clang-cxxlto-static CC="clang -flto=auto -static" CXX="clang++ -flto=auto -static" xtarget/debug
|
||||||
- name: ${{ format('Build gcc LTO Release with {0}', env.gcc_package) }}
|
- name: ${{ format('Build gcc LTO Release with {0}', env.gcc_package) }}
|
||||||
if: ${{ contains(matrix.container, ':edge') }}
|
if: endsWith(matrix.container, ':edge')
|
||||||
run: |
|
run: |
|
||||||
make -C "upx with space" UPX_XTARGET=gcc-cxxlto-static CC="gcc -flto=auto -static" CXX="g++ -flto=auto -static"
|
make -C "upx with space" UPX_XTARGET=gcc-cxxlto-static CC="gcc -flto=auto -static" CXX="g++ -flto=auto -static"
|
||||||
- name: ${{ format('Build gcc LTO Debug with {0}', env.gcc_package) }}
|
- name: ${{ format('Build gcc LTO Debug with {0}', env.gcc_package) }}
|
||||||
if: ${{ contains(matrix.container, ':edge') }}
|
if: endsWith(matrix.container, ':edge')
|
||||||
run: |
|
run: |
|
||||||
make -C "upx with space" UPX_XTARGET=gcc-cxxlto-static CC="gcc -flto=auto -static" CXX="g++ -flto=auto -static" xtarget/debug
|
make -C "upx with space" UPX_XTARGET=gcc-cxxlto-static CC="gcc -flto=auto -static" CXX="g++ -flto=auto -static" xtarget/debug
|
||||||
|
|
||||||
|
@ -129,7 +131,7 @@ jobs:
|
||||||
- { name: 'Run basic tests gcc Release', run: 'make -C "upx with space"/build/xtarget/gcc-static/release 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 gcc Debug', run: 'make -C "upx with space"/build/xtarget/gcc-static/debug test' }
|
||||||
- name: 'Run basic tests C++20, C++23 and LTO'
|
- name: 'Run basic tests C++20, C++23 and LTO'
|
||||||
if: ${{ contains(matrix.container, ':edge') }}
|
if: endsWith(matrix.container, ':edge')
|
||||||
run: |
|
run: |
|
||||||
for dir in "upx with space"/build/xtarget/*-cxx*/*; do
|
for dir in "upx with space"/build/xtarget/*-cxx*/*; do
|
||||||
echo "===== $dir"
|
echo "===== $dir"
|
||||||
|
@ -152,7 +154,7 @@ jobs:
|
||||||
testsuite="$(readlink -fn "upx with space"/misc/testsuite/test_symlinks.sh)"
|
testsuite="$(readlink -fn "upx with space"/misc/testsuite/test_symlinks.sh)"
|
||||||
cd "upx with space"/build/xtarget/gcc-static/release
|
cd "upx with space"/build/xtarget/gcc-static/release
|
||||||
# IMPORTANT: do NOT run as user root!
|
# IMPORTANT: do NOT run as user root!
|
||||||
chmod a+w . && sudo -u operator bash "$testsuite"
|
chmod a+w . && sudo -u upx bash "$testsuite"
|
||||||
|
|
||||||
# test suite
|
# test suite
|
||||||
- name: ${{ format('Run test suite level {0}', env.UPX_TESTSUITE_LEVEL) }}
|
- name: ${{ format('Run test suite level {0}', env.UPX_TESTSUITE_LEVEL) }}
|
||||||
|
@ -171,4 +173,4 @@ jobs:
|
||||||
testsuite="$(readlink -fn "upx with space"/misc/testsuite/test_symlinks.sh)"
|
testsuite="$(readlink -fn "upx with space"/misc/testsuite/test_symlinks.sh)"
|
||||||
cd "upx with space"/build/xtarget/gcc-static/release
|
cd "upx with space"/build/xtarget/gcc-static/release
|
||||||
# IMPORTANT: do NOT run as user root!
|
# IMPORTANT: do NOT run as user root!
|
||||||
chmod a+w . && sudo -u operator bash "$testsuite"
|
chmod a+w . && sudo -u upx bash "$testsuite"
|
||||||
|
|
|
@ -24,12 +24,12 @@ jobs:
|
||||||
- name: llvm-mingw-20230614-ucrt
|
- name: llvm-mingw-20230614-ucrt
|
||||||
llvm_version: 16.0.6
|
llvm_version: 16.0.6
|
||||||
url: 'https://github.com/mstorsjo/llvm-mingw/releases/download/20230614/llvm-mingw-20230614-ucrt-ubuntu-20.04-x86_64.tar.xz'
|
url: 'https://github.com/mstorsjo/llvm-mingw/releases/download/20230614/llvm-mingw-20230614-ucrt-ubuntu-20.04-x86_64.tar.xz'
|
||||||
- name: llvm-mingw-20230822-msvcrt
|
- name: llvm-mingw-20230905-msvcrt
|
||||||
llvm_version: 17.0.0rc3
|
llvm_version: 17.0.0rc4
|
||||||
url: 'https://github.com/mstorsjo/llvm-mingw/releases/download/20230822/llvm-mingw-20230822-msvcrt-ubuntu-20.04-x86_64.tar.xz'
|
url: 'https://github.com/mstorsjo/llvm-mingw/releases/download/20230905/llvm-mingw-20230905-msvcrt-ubuntu-20.04-x86_64.tar.xz'
|
||||||
- name: llvm-mingw-20230822-ucrt
|
- name: llvm-mingw-20230905-ucrt
|
||||||
llvm_version: 17.0.0rc3
|
llvm_version: 17.0.0rc4
|
||||||
url: 'https://github.com/mstorsjo/llvm-mingw/releases/download/20230822/llvm-mingw-20230822-ucrt-ubuntu-20.04-x86_64.tar.xz'
|
url: 'https://github.com/mstorsjo/llvm-mingw/releases/download/20230905/llvm-mingw-20230905-ucrt-ubuntu-20.04-x86_64.tar.xz'
|
||||||
name: ${{ format('{0} {1}', matrix.name, matrix.llvm_version) }}
|
name: ${{ format('{0} {1}', matrix.name, matrix.llvm_version) }}
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
|
|
|
@ -10,8 +10,8 @@ on:
|
||||||
env:
|
env:
|
||||||
CMAKE_REQUIRED_QUIET: OFF
|
CMAKE_REQUIRED_QUIET: OFF
|
||||||
DEBIAN_FRONTEND: noninteractive
|
DEBIAN_FRONTEND: noninteractive
|
||||||
# 2023-09-05
|
# 2023-09-10
|
||||||
ZIG_DIST_VERSION: 0.12.0-dev.280+64d03faae
|
ZIG_DIST_VERSION: 0.12.0-dev.294+4d1432299
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
job-linux-zigcc: # uses cmake + make
|
job-linux-zigcc: # uses cmake + make
|
||||||
|
|
|
@ -99,5 +99,5 @@ jobs:
|
||||||
export upx_exe_runner="valgrind --error-exitcode=1 --quiet"
|
export upx_exe_runner="valgrind --error-exitcode=1 --quiet"
|
||||||
# on current GitHub CI, takes about 30 minutes for release and 80 minutes for debug builds
|
# on current GitHub CI, takes about 30 minutes for release and 80 minutes for debug builds
|
||||||
# reduce time for debug builds to about 30 minutes
|
# reduce time for debug builds to about 30 minutes
|
||||||
test $release = debug && export UPX_TESTSUITE_LEVEL=4
|
test "$release" = "debug" && export UPX_TESTSUITE_LEVEL=4
|
||||||
env -C build/xtarget/clang-static/$release "$PWD"/misc/testsuite/upx_testsuite_1.sh
|
env -C build/xtarget/clang-static/$release "$PWD"/misc/testsuite/upx_testsuite_1.sh
|
||||||
|
|
|
@ -8,7 +8,7 @@ set -e
|
||||||
# Copyright (C) Markus Franz Xaver Johannes Oberhumer
|
# Copyright (C) Markus Franz Xaver Johannes Oberhumer
|
||||||
#
|
#
|
||||||
|
|
||||||
# uses optional environment variables: AR, CC, CXX, OPTIMIZE, top_srcdir
|
# uses optional environment variables: AR, CC, CXX, OPTIMIZE, VERBOSE, top_srcdir
|
||||||
|
|
||||||
# shell init
|
# shell init
|
||||||
### set -x # enable logging
|
### set -x # enable logging
|
||||||
|
@ -62,7 +62,12 @@ run() {
|
||||||
fi
|
fi
|
||||||
# print short info and run command
|
# print short info and run command
|
||||||
test "x$1" != "x" && test "x$1" != "x+" && echo "$1"
|
test "x$1" != "x" && test "x$1" != "x+" && echo "$1"
|
||||||
shift; "$@"
|
shift
|
||||||
|
if test "x$VERBOSE" != "x" && test "x$VERBOSE" != "x0"; then
|
||||||
|
# print full command
|
||||||
|
echo " $@"
|
||||||
|
fi
|
||||||
|
"$@"
|
||||||
}
|
}
|
||||||
|
|
||||||
# helper function
|
# helper function
|
||||||
|
|
|
@ -8,12 +8,13 @@ argv0=$0; argv0abs=$(readlink -fn "$argv0"); argv0dir=$(dirname "$argv0abs")
|
||||||
umask 0022
|
umask 0022
|
||||||
|
|
||||||
id || true
|
id || true
|
||||||
|
echo "PWD='$PWD'"
|
||||||
if [[ $UID == 0 || $EUID == 0 ]]; then
|
if [[ $UID == 0 || $EUID == 0 ]]; then
|
||||||
echo "ERROR: do not run as root: UID=$UID EUID=$EUID"
|
echo "ERROR: do not run as root: UID=$UID EUID=$EUID"
|
||||||
exit 91
|
exit 91
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# test behaviour with symlinks; requires:
|
# test file system behaviour with symlinks; requires:
|
||||||
# $upx_exe (required, but with convenience fallback "./upx")
|
# $upx_exe (required, but with convenience fallback "./upx")
|
||||||
# optional settings:
|
# optional settings:
|
||||||
# $upx_exe_runner (e.g. "qemu-x86_64 -cpu Westmere" or "valgrind")
|
# $upx_exe_runner (e.g. "qemu-x86_64 -cpu Westmere" or "valgrind")
|
||||||
|
@ -39,15 +40,19 @@ fi
|
||||||
upx_run+=( "$upx_exe" )
|
upx_run+=( "$upx_exe" )
|
||||||
echo "upx_run='${upx_run[*]}'"
|
echo "upx_run='${upx_run[*]}'"
|
||||||
|
|
||||||
# upx_run check, part1
|
# upx_run check
|
||||||
if ! "${upx_run[@]}" --version-short >/dev/null; then echo "UPX-ERROR: FATAL: upx --version-short FAILED"; exit 1; fi
|
if ! "${upx_run[@]}" --version-short >/dev/null; then echo "UPX-ERROR: FATAL: upx --version-short FAILED"; exit 1; fi
|
||||||
if ! "${upx_run[@]}" -L >/dev/null 2>&1; then echo "UPX-ERROR: FATAL: upx -L FAILED"; exit 1; fi
|
if ! "${upx_run[@]}" -L >/dev/null 2>&1; then echo "UPX-ERROR: FATAL: upx -L FAILED"; exit 1; fi
|
||||||
if ! "${upx_run[@]}" --help >/dev/null; then echo "UPX-ERROR: FATAL: upx --help FAILED"; exit 1; fi
|
if ! "${upx_run[@]}" --help >/dev/null; then echo "UPX-ERROR: FATAL: upx --help FAILED"; exit 1; fi
|
||||||
|
|
||||||
#***********************************************************************
|
#***********************************************************************
|
||||||
#
|
# util
|
||||||
#***********************************************************************
|
#***********************************************************************
|
||||||
|
|
||||||
|
exit_code=0
|
||||||
|
num_errors=0
|
||||||
|
all_errors=
|
||||||
|
|
||||||
failed() {
|
failed() {
|
||||||
####exit $1
|
####exit $1
|
||||||
# log error and keep going
|
# log error and keep going
|
||||||
|
@ -97,6 +102,7 @@ assert_symlink_dangling() {
|
||||||
|
|
||||||
create_files() {
|
create_files() {
|
||||||
# clean
|
# clean
|
||||||
|
local d
|
||||||
for d in z_dir_1 z_dir_2 z_dir_3 z_dir_4; do
|
for d in z_dir_1 z_dir_2 z_dir_3 z_dir_4; do
|
||||||
if [[ -d $d ]]; then
|
if [[ -d $d ]]; then
|
||||||
chmod -R +w "./$d"
|
chmod -R +w "./$d"
|
||||||
|
@ -137,16 +143,13 @@ create_files() {
|
||||||
#
|
#
|
||||||
#***********************************************************************
|
#***********************************************************************
|
||||||
|
|
||||||
|
#set -x # debug
|
||||||
|
|
||||||
export UPX="--prefer-ucl --no-color --no-progress"
|
export UPX="--prefer-ucl --no-color --no-progress"
|
||||||
export UPX_DEBUG_DISABLE_GITREV_WARNING=1
|
export UPX_DEBUG_DISABLE_GITREV_WARNING=1
|
||||||
export UPX_DEBUG_DOCTEST_VERBOSE=0
|
export UPX_DEBUG_DOCTEST_VERBOSE=0
|
||||||
export NO_COLOR=1
|
export NO_COLOR=1
|
||||||
|
|
||||||
#set -x # debug
|
|
||||||
exit_code=0
|
|
||||||
num_errors=0
|
|
||||||
all_errors=
|
|
||||||
|
|
||||||
testsuite_header() {
|
testsuite_header() {
|
||||||
local x='==========='; x="$x$x$x$x$x$x$x"
|
local x='==========='; x="$x$x$x$x$x$x$x"
|
||||||
echo -e "\n${x}\n${1}\n${x}\n"
|
echo -e "\n${x}\n${1}\n${x}\n"
|
||||||
|
|
|
@ -71,9 +71,8 @@
|
||||||
FileBase::~FileBase() may_throw {
|
FileBase::~FileBase() may_throw {
|
||||||
#if 0 && defined(__GNUC__) // debug
|
#if 0 && defined(__GNUC__) // debug
|
||||||
if (isOpen())
|
if (isOpen())
|
||||||
fprintf(stderr,"%s: %s\n", _name, __PRETTY_FUNCTION__);
|
fprintf(stderr, "%s: %s\n", _name, __PRETTY_FUNCTION__);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (std::uncaught_exceptions() == 0)
|
if (std::uncaught_exceptions() == 0)
|
||||||
closex(); // may_throw
|
closex(); // may_throw
|
||||||
else
|
else
|
||||||
|
|
|
@ -49,7 +49,7 @@ ACC_COMPILE_TIME_ASSERT_HEADER(UPX_RSIZE_MAX_MEM == UPX_RSIZE_MAX)
|
||||||
ACC_COMPILE_TIME_ASSERT_HEADER(UPX_RSIZE_MAX_STR <= UPX_RSIZE_MAX / 256)
|
ACC_COMPILE_TIME_ASSERT_HEADER(UPX_RSIZE_MAX_STR <= UPX_RSIZE_MAX / 256)
|
||||||
ACC_COMPILE_TIME_ASSERT_HEADER(2ull * UPX_RSIZE_MAX * 9 / 8 + 256 * 1024 * 1024 < INT_MAX)
|
ACC_COMPILE_TIME_ASSERT_HEADER(2ull * UPX_RSIZE_MAX * 9 / 8 + 256 * 1024 * 1024 < INT_MAX)
|
||||||
ACC_COMPILE_TIME_ASSERT_HEADER(2ull * UPX_RSIZE_MAX * 10 / 8 + 128 * 1024 * 1024 <= INT_MAX + 1u)
|
ACC_COMPILE_TIME_ASSERT_HEADER(2ull * UPX_RSIZE_MAX * 10 / 8 + 128 * 1024 * 1024 <= INT_MAX + 1u)
|
||||||
ACC_COMPILE_TIME_ASSERT_HEADER(5ull * UPX_RSIZE_MAX < UINT_MAX)
|
ACC_COMPILE_TIME_ASSERT_HEADER(5ull * UPX_RSIZE_MAX < UINT_MAX) // IMPORTANT overflow protection
|
||||||
ACC_COMPILE_TIME_ASSERT_HEADER(UPX_RSIZE_MAX >= 8192 * 65536)
|
ACC_COMPILE_TIME_ASSERT_HEADER(UPX_RSIZE_MAX >= 8192 * 65536)
|
||||||
ACC_COMPILE_TIME_ASSERT_HEADER(UPX_RSIZE_MAX_STR >= 1024)
|
ACC_COMPILE_TIME_ASSERT_HEADER(UPX_RSIZE_MAX_STR >= 1024)
|
||||||
|
|
||||||
|
@ -264,12 +264,12 @@ void *upx_calloc(size_t n, size_t element_size) {
|
||||||
// simple unoptimized memswap()
|
// simple unoptimized memswap()
|
||||||
void upx_memswap(void *a, void *b, size_t n) {
|
void upx_memswap(void *a, void *b, size_t n) {
|
||||||
if (a != b && n != 0) {
|
if (a != b && n != 0) {
|
||||||
char *x = (char *) a;
|
byte *x = (byte *) a;
|
||||||
char *y = (char *) b;
|
byte *y = (byte *) b;
|
||||||
do {
|
do {
|
||||||
// strange clang-analyzer-15 false positive when compiling in Debug mode
|
// strange clang-analyzer-15 false positive when compiling in Debug mode
|
||||||
// clang-analyzer-core.uninitialized.Assign
|
// clang-analyzer-core.uninitialized.Assign
|
||||||
char tmp = *x; // NOLINT(*core.uninitialized.Assign) // bogus clang-analyzer warning
|
byte tmp = *x; // NOLINT(*core.uninitialized.Assign) // bogus clang-analyzer warning
|
||||||
*x++ = *y;
|
*x++ = *y;
|
||||||
*y++ = tmp;
|
*y++ = tmp;
|
||||||
} while (--n != 0);
|
} while (--n != 0);
|
||||||
|
@ -277,12 +277,12 @@ void upx_memswap(void *a, void *b, size_t n) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// much better memswap(), optimized for our use case in sort functions below
|
// much better memswap(), optimized for our use case in sort functions below
|
||||||
static void memswap_no_overlap(char *a, char *b, size_t n) {
|
static void memswap_no_overlap(byte *a, byte *b, size_t n) {
|
||||||
#if defined(__clang__) && __clang_major__ < 15
|
#if defined(__clang__) && __clang_major__ < 15
|
||||||
// work around a clang < 15 ICE (Internal Compiler Error)
|
// work around a clang < 15 ICE (Internal Compiler Error)
|
||||||
upx_memswap(a, b, n);
|
upx_memswap(a, b, n);
|
||||||
#else // clang bug
|
#else // clang bug
|
||||||
upx_alignas_max char tmp_buf[16];
|
upx_alignas_max byte tmp_buf[16];
|
||||||
#define SWAP(x) \
|
#define SWAP(x) \
|
||||||
ACC_BLOCK_BEGIN \
|
ACC_BLOCK_BEGIN \
|
||||||
upx_memcpy_inline(tmp_buf, a, x); \
|
upx_memcpy_inline(tmp_buf, a, x); \
|
||||||
|
@ -301,7 +301,7 @@ static void memswap_no_overlap(char *a, char *b, size_t n) {
|
||||||
if (n & 2)
|
if (n & 2)
|
||||||
SWAP(2);
|
SWAP(2);
|
||||||
if (n & 1) {
|
if (n & 1) {
|
||||||
char tmp = *a;
|
byte tmp = *a;
|
||||||
*a = *b;
|
*a = *b;
|
||||||
*b = tmp;
|
*b = tmp;
|
||||||
}
|
}
|
||||||
|
@ -313,7 +313,7 @@ static void memswap_no_overlap(char *a, char *b, size_t n) {
|
||||||
// WARNING: O(n^2) and thus very inefficient for large n
|
// WARNING: O(n^2) and thus very inefficient for large n
|
||||||
void upx_gnomesort(void *array, size_t n, size_t element_size, upx_compare_func_t compare) {
|
void upx_gnomesort(void *array, size_t n, size_t element_size, upx_compare_func_t compare) {
|
||||||
for (size_t i = 1; i < n; i++) {
|
for (size_t i = 1; i < n; i++) {
|
||||||
char *a = (char *) array + element_size * i; // a := &array[i]
|
byte *a = (byte *) array + element_size * i; // a := &array[i]
|
||||||
if (i != 0 && compare(a - element_size, a) > 0) { // if a[-1] > a[0] then
|
if (i != 0 && compare(a - element_size, a) > 0) { // if a[-1] > a[0] then
|
||||||
memswap_no_overlap(a - element_size, a, element_size); // swap elements a[-1] <=> a[0]
|
memswap_no_overlap(a - element_size, a, element_size); // swap elements a[-1] <=> a[0]
|
||||||
i -= 2; // and decrease i
|
i -= 2; // and decrease i
|
||||||
|
@ -330,22 +330,22 @@ void upx_shellsort_memswap(void *array, size_t n, size_t element_size, upx_compa
|
||||||
gap = gap * 3 + 1;
|
gap = gap * 3 + 1;
|
||||||
for (; gap > 0; gap = (gap - 1) / 3) {
|
for (; gap > 0; gap = (gap - 1) / 3) {
|
||||||
const size_t gap_bytes = element_size * gap;
|
const size_t gap_bytes = element_size * gap;
|
||||||
char *p = (char *) array + gap_bytes;
|
byte *p = (byte *) array + gap_bytes;
|
||||||
for (size_t i = gap; i < n; i += gap, p += gap_bytes) // invariant: p == &array[i]
|
for (size_t i = gap; i < n; i += gap, p += gap_bytes) // invariant: p == &array[i]
|
||||||
for (char *a = p; a != array && compare(a - gap_bytes, a) > 0; a -= gap_bytes)
|
for (byte *a = p; a != array && compare(a - gap_bytes, a) > 0; a -= gap_bytes)
|
||||||
memswap_no_overlap(a - gap_bytes, a, element_size);
|
memswap_no_overlap(a - gap_bytes, a, element_size);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// simple Shell sort using Knuth's gap; NOT stable; uses memcpy()
|
// simple Shell sort using Knuth's gap; NOT stable; uses memcpy()
|
||||||
// should be faster than memswap() in theory, but benchmarks are inconsistent
|
// should be faster than memswap() version in theory, but benchmarks are inconsistent
|
||||||
void upx_shellsort_memcpy(void *array, size_t n, size_t element_size, upx_compare_func_t compare) {
|
void upx_shellsort_memcpy(void *array, size_t n, size_t element_size, upx_compare_func_t compare) {
|
||||||
mem_size_assert(element_size, n); // check size
|
mem_size_assert(element_size, n); // check size
|
||||||
constexpr size_t MAX_INLINE_ELEMENT_SIZE = 256;
|
constexpr size_t MAX_INLINE_ELEMENT_SIZE = 256;
|
||||||
upx_alignas_max char tmp_buf[MAX_INLINE_ELEMENT_SIZE]; // buffer for one element
|
upx_alignas_max byte tmp_buf[MAX_INLINE_ELEMENT_SIZE]; // buffer for one element
|
||||||
char *tmp = tmp_buf;
|
byte *tmp = tmp_buf;
|
||||||
if (element_size > MAX_INLINE_ELEMENT_SIZE) {
|
if (element_size > MAX_INLINE_ELEMENT_SIZE) {
|
||||||
tmp = (char *) malloc(element_size);
|
tmp = (byte *) malloc(element_size);
|
||||||
assert(tmp != nullptr);
|
assert(tmp != nullptr);
|
||||||
}
|
}
|
||||||
size_t gap = 0; // 0, 1, 4, 13, 40, 121, 364, 1093, ...
|
size_t gap = 0; // 0, 1, 4, 13, 40, 121, 364, 1093, ...
|
||||||
|
@ -353,10 +353,10 @@ void upx_shellsort_memcpy(void *array, size_t n, size_t element_size, upx_compar
|
||||||
gap = gap * 3 + 1;
|
gap = gap * 3 + 1;
|
||||||
for (; gap > 0; gap = (gap - 1) / 3) {
|
for (; gap > 0; gap = (gap - 1) / 3) {
|
||||||
const size_t gap_bytes = element_size * gap;
|
const size_t gap_bytes = element_size * gap;
|
||||||
char *p = (char *) array + gap_bytes;
|
byte *p = (byte *) array + gap_bytes;
|
||||||
for (size_t i = gap; i < n; i += gap, p += gap_bytes) // invariant: p == &array[i]
|
for (size_t i = gap; i < n; i += gap, p += gap_bytes) // invariant: p == &array[i]
|
||||||
if (compare(p - gap_bytes, p) > 0) {
|
if (compare(p - gap_bytes, p) > 0) {
|
||||||
char *a = p;
|
byte *a = p;
|
||||||
memcpy(tmp, a, element_size);
|
memcpy(tmp, a, element_size);
|
||||||
do {
|
do {
|
||||||
memcpy(a, a - gap_bytes, element_size);
|
memcpy(a, a - gap_bytes, element_size);
|
||||||
|
@ -378,7 +378,7 @@ void upx_std_stable_sort(void *array, size_t n, upx_compare_func_t compare) {
|
||||||
// just for testing
|
// just for testing
|
||||||
upx_gnomesort(array, n, ElementSize, compare);
|
upx_gnomesort(array, n, ElementSize, compare);
|
||||||
#else
|
#else
|
||||||
struct alignas(1) element_type { char data[ElementSize]; };
|
struct alignas(1) element_type { byte data[ElementSize]; };
|
||||||
static_assert(sizeof(element_type) == ElementSize);
|
static_assert(sizeof(element_type) == ElementSize);
|
||||||
static_assert(alignof(element_type) == 1);
|
static_assert(alignof(element_type) == 1);
|
||||||
auto cmp = [compare](const element_type &a, const element_type &b) -> bool {
|
auto cmp = [compare](const element_type &a, const element_type &b) -> bool {
|
||||||
|
|
|
@ -69,7 +69,7 @@ static constexpr int get_open_flags(OpenMode om) noexcept {
|
||||||
if (om == WO_CREATE_OR_TRUNCATE)
|
if (om == WO_CREATE_OR_TRUNCATE)
|
||||||
return wo_flags | O_CREAT | O_TRUNC; // create if not exists, otherwise truncate
|
return wo_flags | O_CREAT | O_TRUNC; // create if not exists, otherwise truncate
|
||||||
// RO_MUST_EXIST
|
// RO_MUST_EXIST
|
||||||
return O_RDONLY | O_BINARY;
|
return O_RDONLY | O_BINARY; // will cause an error if file does not exist
|
||||||
}
|
}
|
||||||
|
|
||||||
static void copy_file_contents(const char *iname, const char *oname, OpenMode om) may_throw {
|
static void copy_file_contents(const char *iname, const char *oname, OpenMode om) may_throw {
|
||||||
|
@ -127,6 +127,7 @@ static void copy_file_attributes(const struct stat *st, const char *oname, bool
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
// maybe unused
|
// maybe unused
|
||||||
|
UNUSED(st);
|
||||||
UNUSED(oname);
|
UNUSED(oname);
|
||||||
UNUSED(preserve_mode);
|
UNUSED(preserve_mode);
|
||||||
UNUSED(preserve_ownership);
|
UNUSED(preserve_ownership);
|
||||||
|
@ -221,7 +222,7 @@ void do_one_file(const char *const iname, char *const oname) may_throw {
|
||||||
if (!maketempname(tname, sizeof(tname), iname, ".upx"))
|
if (!maketempname(tname, sizeof(tname), iname, ".upx"))
|
||||||
throwIOException("could not create a temporary file name");
|
throwIOException("could not create a temporary file name");
|
||||||
}
|
}
|
||||||
int flags = get_open_flags(WO_MUST_CREATE);
|
int flags = get_open_flags(WO_MUST_CREATE); // don't overwrite files by default
|
||||||
if (opt->output_name && preserve_link) {
|
if (opt->output_name && preserve_link) {
|
||||||
flags = get_open_flags(WO_CREATE_OR_TRUNCATE);
|
flags = get_open_flags(WO_CREATE_OR_TRUNCATE);
|
||||||
#if HAVE_LSTAT
|
#if HAVE_LSTAT
|
||||||
|
@ -289,8 +290,8 @@ void do_one_file(const char *const iname, char *const oname) may_throw {
|
||||||
}
|
}
|
||||||
|
|
||||||
// close files
|
// close files
|
||||||
fo.closex();
|
|
||||||
fi.closex();
|
fi.closex();
|
||||||
|
fo.closex();
|
||||||
|
|
||||||
// rename or copy files
|
// rename or copy files
|
||||||
if (oname[0] && !opt->output_name) {
|
if (oname[0] && !opt->output_name) {
|
||||||
|
|
Loading…
Reference in New Issue