Compare commits

..

156 Commits

Author SHA1 Message Date
Markus F.X.J. Oberhumer 8779113131 all: prepare for release 2023-08-08 10:38:12 +02:00
Markus F.X.J. Oberhumer 26cfd0a616 all: minor cleanups 2023-08-08 10:34:12 +02:00
John Reiser 75e153dd99 More care in ::forward_Shdrs() and ::pack4()
Also, de-compressing arm64 shlib restores .init_array[0],
although supposedly *_RELATIVE relocation should overwrite.

https://github.com/upx/upx/issues/693
	modified:   p_lx_elf.cpp
	modified:   p_lx_elf.h
2023-08-04 11:52:58 -07:00
Markus F.X.J. Oberhumer fa364d6ea3 all: final cleanups in preparation for release 2023-08-03 14:20:35 +02:00
Markus F.X.J. Oberhumer 13e5c13695 Fix functional change in commit 905bfacf44 2023-08-02 17:45:17 +02:00
John Reiser 43b3b54197 spell check typos
modified:   p_lx_exc.cpp
	modified:   p_mach.cpp
	modified:   stub/src/amd64-linux.elf-so_main.c
	modified:   stub/src/i386-linux.elf-so_main.c
	modified:   stub/src/arch/mips/r3000/bits.ash
	modified:   stub/src/arm.v4a-linux.elf-fold.S
	modified:   stub/src/arm.v4a-linux.shlib-init.S
	modified:   stub/src/arm64-linux.shlib-init.S
	modified:   stub/src/i386-linux.elf-main.c
	modified:   stub/src/mipsel.r3000-linux.elf-entry.S
2023-07-31 09:05:32 -07:00
John Reiser 3a16d4a12e Spell check; No-Functional-Change
modified:   p_lx_elf.cpp
2023-07-31 06:06:31 -07:00
Markus F.X.J. Oberhumer 50fc9235de misc: update podman test-qemu 2023-08-01 07:24:10 +02:00
Markus F.X.J. Oberhumer 70287d3c49 clang-tidy 2023-07-31 14:49:48 +02:00
John Reiser 41e9f7985f forward_Shdrs: elfout for main, lowmem for shlib
Especially Android.
https://github.com/upx/upx/issues/680
	modified:   p_lx_elf.cpp
	modified:   p_lx_elf.h
2023-07-29 13:43:33 -07:00
John Reiser c3327977da Pwrite:
modified:   stub/src/amd64-linux.elf-so_fold.S

	modified:   stub/amd64-linux.elf-so_fold.h
	modified:   stub/tmp/amd64-linux.elf-so_fold.bin.dump
2023-07-29 13:42:20 -07:00
John Reiser 905bfacf44 Pacify clang-tidy 2023-07-26 17:21:39 -07:00
Markus F.X.J. Oberhumer 053e95033f all: improve C++ static analyzers 2023-07-26 22:28:47 +02:00
Markus F.X.J. Oberhumer 5a1203be0d submodules: update for new versions 2023-07-26 18:13:25 +02:00
John Reiser 745fef7425 fpad4, fpad8, and _Shdr hacking should guard against (!fo)
Also pacify some clang scan-build complaints.
	modified:   p_lx_elf.cpp
2023-07-26 07:27:12 -07:00
John Reiser c9d625a237 Use 'elfout' for changing ElfXX_Ehdr
https://github.com/upx/upx/issues/688
	modified:   p_lx_elf.cpp
2023-07-26 07:15:22 +02:00
John Reiser 334731f56b Sync stubs for powerpc64le-linux.elf/upx-3.95
How did this mismatch happen?
	modified:   ../misc/testsuite/upx_testsuite_1-expected_sha256sums.sh
	modified:   stub/arm64-linux.elf-so_entry.h
	modified:   stub/powerpc64-linux.elf-fold.h
	modified:   stub/powerpc64le-linux.elf-fold.h
2023-07-26 07:15:22 +02:00
John Reiser d5e7672a45 De-activate "bkpt" at entry
modified:   arm64-linux.elf-so_entry.S
2023-07-26 07:15:22 +02:00
Markus F.X.J. Oberhumer e702aa0252 Review 2023-07-26 07:15:22 +02:00
John Reiser 2684e815e0 Fix use of memfd_create for shlib stubs, espcially Android
Also relocation of init_array[0] for Elf32 shlib.
        https://github.com/upx/upx/issues/220
        https://github.com/upx/upx/issues/609
        https://github.com/upx/upx/issues/680

	modified:   stub/src/amd64-linux.elf-so_main.c
	modified:   stub/src/i386-linux.elf-so_main.c
	modified:   p_lx_elf.cpp

	modified:   stub/src/arm.v4a-linux.elf-so_fold.S
	modified:   stub/src/arm64-linux.elf-so_entry.S
	modified:   stub/src/arm64-linux.elf-so_fold.S
	modified:   stub/src/i386-linux.elf-so_fold.S

	modified:   stub/amd64-linux.elf-so_fold.h
	modified:   stub/arm.v4a-linux.elf-so_fold.h
	modified:   stub/arm.v5a-linux.elf-so_fold.h
	modified:   stub/arm64-linux.elf-so_entry.h
	modified:   stub/arm64-linux.elf-so_fold.h
	modified:   stub/i386-linux.elf-so_fold.h
	modified:   stub/tmp/amd64-linux.elf-so_fold.bin.dump
2023-07-26 07:15:22 +02:00
John Reiser efbc93229a Un-debug amd64-linux.elf-so_main.c
modified:   stub/src/amd64-linux.elf-so_main.c

	modified:   stub/amd64-linux.elf-so_fold.h
	modified:   stub/arm64-linux.elf-so_fold.h
	modified:   stub/tmp/amd64-linux.elf-so_fold.bin.dump
2023-07-26 07:15:22 +02:00
John Reiser 05539ad5b6 Fix stubs for shlib with only 2 PT_LOAD 2023-07-26 07:15:22 +02:00
John Reiser 670aae2e11 Check /proc/self/auxv exists
modified:   stub/src/amd64-linux.elf-so_main.c
	modified:   stub/src/i386-linux.elf-so_main.c

	modified:   stub/amd64-linux.elf-so_fold.h
	modified:   stub/arm.v4a-linux.elf-so_fold.h
	modified:   stub/arm.v5a-linux.elf-so_fold.h
	modified:   stub/arm64-linux.elf-so_fold.h
	modified:   stub/tmp/amd64-linux.elf-so_fold.bin.dump
2023-07-26 07:15:22 +02:00
John Reiser e6ff68dc2c Turn on DEBUG for 64-bit shlib
modified:   src/stub/src/amd64-linux.elf-so_main.c

	modified:   src/stub/amd64-linux.elf-so_fold.h
	modified:   src/stub/arm64-linux.elf-so_fold.h
	modified:   src/stub/tmp/amd64-linux.elf-so_fold.bin.dump
2023-07-26 07:15:22 +02:00
Markus F.X.J. Oberhumer 641b116f04 Update .gitattributes. 2023-07-25 12:18:33 +02:00
Markus F.X.J. Oberhumer f81f7194ed submodules: update for new versions 2023-07-25 12:05:14 +02:00
Markus F.X.J. Oberhumer 161d20e614 CI: update 2023-07-24 14:47:32 +02:00
Markus F.X.J. Oberhumer fc4dcd46db CI and build updates 2023-07-22 16:12:13 +02:00
Markus F.X.J. Oberhumer 891dc87064 misc: upx_testsuite; move podman directories into subdirectory 2023-07-22 00:19:11 +02:00
Markus F.X.J. Oberhumer b866631448 misc: improve upx_testsuite; cmake update 2023-07-19 20:12:20 +02:00
John Reiser 672d69c68a Fix unpacking of upx-3.94-armeb_linux/upx
Getting past the code of the stub must deal with variances
between released versions.
	modified:   p_lx_elf.cpp
2023-07-18 16:56:39 -07:00
Markus F.X.J. Oberhumer 507c31ec14 CI and cmake updates 2023-07-18 07:21:51 +02:00
John Reiser 65cc40bdda Align escape hatch in powerpc64 main program
modified:   stub/src/amd64-linux.elf-main.c
	modified:   ../misc/testsuite/upx_testsuite_1-expected_sha256sums.sh

	modified:   stub/powerpc64-linux.elf-fold.h
	modified:   stub/powerpc64le-linux.elf-fold.h
	modified:   stub/tmp/powerpc64-linux.elf-fold.map
	modified:   stub/tmp/powerpc64le-linux.elf-fold.map
2023-07-17 15:58:01 -07:00
John Reiser 067895fa5f Fix brk+munmap in folded stubs for main programs
qemu emulating a compressed ET_EXEC revealed an access to ElfXX_Phdr
on the discarded side of brk() during cleanup. qemu was more aggressive
than the Linux kernel implementation of brk().
        https://github.com/upx/upx/issues/683

	modified:   stub/src/i386-linux.elf-main.c
	modified:   stub/src/include/linux.h

	modified:   ../misc/testsuite/upx_testsuite_1-expected_sha256sums.sh

	modified:   stub/src/amd64-linux.elf-fold.S
	modified:   stub/src/arm.v4a-linux.elf-fold.S
	modified:   stub/src/arm64-linux.elf-fold.S
	modified:   stub/src/i386-linux.elf-fold.S
	modified:   stub/src/mipsel.r3000-linux.elf-fold.S
	modified:   stub/src/powerpc-linux.elf-fold.S
	modified:   stub/src/powerpc64le-linux.elf-fold.S

	modified:   stub/amd64-linux.elf-fold.h
	modified:   stub/arm.v4a-linux.elf-fold.h
	modified:   stub/arm.v5a-linux.elf-fold.h
	modified:   stub/arm64-linux.elf-fold.h
	modified:   stub/armeb.v4a-linux.elf-fold.h
	modified:   stub/i386-linux.elf-fold.h
	modified:   stub/mips.r3000-linux.elf-fold.h
	modified:   stub/mipsel.r3000-linux.elf-fold.h
	modified:   stub/powerpc-linux.elf-fold.h
	modified:   stub/powerpc64-linux.elf-fold.h
	modified:   stub/powerpc64le-linux.elf-fold.h

	modified:   stub/tmp/amd64-linux.elf-fold.map
	modified:   stub/tmp/arm.v4a-linux.elf-fold.map
	modified:   stub/tmp/arm.v5a-linux.elf-fold.map
	modified:   stub/tmp/arm64-linux.elf-fold.map
	modified:   stub/tmp/armeb.v4a-linux.elf-fold.map
	modified:   stub/tmp/i386-linux.elf-fold.map
	modified:   stub/tmp/mips.r3000-linux.elf-fold.map
	modified:   stub/tmp/mipsel.r3000-linux.elf-fold.map
	modified:   stub/tmp/powerpc-linux.elf-fold.map
	modified:   stub/tmp/powerpc64-linux.elf-fold.map
	modified:   stub/tmp/powerpc64le-linux.elf-fold.map
2023-07-17 07:21:56 +02:00
Markus F.X.J. Oberhumer 3f7f26c74b CI: update 2023-07-16 21:28:26 +02:00
Markus F.X.J. Oberhumer 9a6b5940cf CI: update 2023-07-16 15:14:19 +02:00
Markus F.X.J. Oberhumer 828f4a63bf src: add some "explicit"; cleanups 2023-07-16 07:37:31 +02:00
John Reiser 707fb55625 A fuzzer attacked i386-dos32.watcom.le 2023-07-06 20:25:14 -07:00
Markus F.X.J. Oberhumer 8d41ae09c8 all: misc updates 2023-07-12 18:59:08 +02:00
Markus F.X.J. Oberhumer 7ec0faca1e all: misc and noexcept updates 2023-07-09 17:36:24 +02:00
Markus F.X.J. Oberhumer 300fa29446 CI: update 2023-07-08 21:28:29 +02:00
Markus F.X.J. Oberhumer 6981f7b3ae misc: add misc/test-qemu-with-podman 2023-07-08 18:14:41 +02:00
Markus F.X.J. Oberhumer 682a1e97e4 src: add assert_noexcept() 2023-07-08 12:06:27 +02:00
Markus F.X.J. Oberhumer 1d71dd3851 all: clang-tidy updates 2023-07-08 10:51:02 +02:00
Markus F.X.J. Oberhumer 5edfda46e5 all: clang-tidy updates 2023-07-08 09:59:41 +02:00
Markus F.X.J. Oberhumer d7754a97c7 all: add support for clang-tidy 2023-07-07 23:13:08 +02:00
Markus F.X.J. Oberhumer c79aa6ad8a all: cosmetic updates 2023-07-06 18:03:37 +02:00
Markus F.X.J. Oberhumer 525e091472 src/console: disable win32 screen driver when running under Wine 2023-07-06 10:09:38 +02:00
Markus F.X.J. Oberhumer 16f6de677d misc: podman updates 2023-07-06 10:09:38 +02:00
John Reiser 12c36bab6c Linux EINVAL for zero-length mmap: mmap(, 0, ,,,)
https://github.com/upx/upx/issues/681
	modified:   stub/src/amd64-linux.elf-main.c
	modified:   stub/src/i386-linux.elf-main.c

	modified:   stub/src/i386-bsd.elf-main.c
	modified:   stub/src/i386-openbsd.elf-main.c

	modified:   ../misc/testsuite/upx_testsuite_1-expected_sha256sums.sh

	modified:   stub/amd64-linux.elf-fold.h
	modified:   stub/arm64-linux.elf-fold.h
	modified:   stub/i386-bsd.elf-fold.h
	modified:   stub/i386-linux.elf-fold.h
	modified:   stub/i386-netbsd.elf-fold.h
	modified:   stub/i386-openbsd.elf-fold.h
	modified:   stub/mips.r3000-linux.elf-fold.h
	modified:   stub/mipsel.r3000-linux.elf-fold.h
	modified:   stub/powerpc-linux.elf-fold.h
	modified:   stub/powerpc64-linux.elf-fold.h
	modified:   stub/powerpc64le-linux.elf-fold.h
	modified:   stub/tmp/amd64-linux.elf-fold.map
	modified:   stub/tmp/arm64-linux.elf-fold.map
	modified:   stub/tmp/i386-bsd.elf-fold.map
	modified:   stub/tmp/i386-linux.elf-fold.map
	modified:   stub/tmp/i386-netbsd.elf-fold.map
	modified:   stub/tmp/i386-openbsd.elf-fold.map
	modified:   stub/tmp/mips.r3000-linux.elf-fold.map
	modified:   stub/tmp/mipsel.r3000-linux.elf-fold.map
	modified:   stub/tmp/powerpc-linux.elf-fold.map
	modified:   stub/tmp/powerpc64-linux.elf-fold.map
	modified:   stub/tmp/powerpc64le-linux.elf-fold.map
2023-07-06 10:09:07 +02:00
John Reiser c429859cbf Placate Android dlopen() some more.
https://github.com/upx/upx/issues/680
	modified:   p_lx_elf.cpp
2023-07-06 10:08:41 +02:00
John Reiser dc76b2af97 info(Android_penalty)
modified:   p_lx_elf.cpp
2023-06-26 09:09:47 -07:00
Markus F.X.J. Oberhumer b75e7687f4 all: CI and misc updates 2023-06-30 01:20:48 +02:00
Markus F.X.J. Oberhumer ece5af2895 CI: make sure that directories which contain whitespace do work 2023-06-28 18:18:36 +02:00
Markus F.X.J. Oberhumer 1aaa33552e all: move testsuite to misc/testsuite; CI updates 2023-06-27 14:27:19 +02:00
Markus F.X.J. Oberhumer f622871eb0 src: fix building under freebsd; updates 2023-06-27 12:59:24 +02:00
Markus F.X.J. Oberhumer 060b01260d CI: yet more updates 2023-06-25 19:40:09 +02:00
Markus F.X.J. Oberhumer 871f8a4793 src: new ACC version 2023-06-25 14:30:00 +02:00
Markus F.X.J. Oberhumer c54e03d0f2 CI: ongoing cleanups 2023-06-25 03:27:51 +02:00
Markus F.X.J. Oberhumer aaf3f75990 CI and cmake updates 2023-06-25 01:55:06 +02:00
Markus F.X.J. Oberhumer 512a26cee4 CI: update 2023-06-24 10:16:43 +02:00
John Reiser b4a793ed26 Make ::forward_Shdrs more friendly to Android dlopen()
https://github.com/upx/upx/issues/220
https://github.com/upx/upx/issues/609
2023-06-22 10:16:25 -07:00
Markus F.X.J. Oberhumer 5d2c74008e all: cmake and noexcept updates 2023-06-23 14:13:08 +02:00
Markus F.X.J. Oberhumer 7fafc68940 CI: update 2023-06-19 14:28:12 +02:00
Markus F.X.J. Oberhumer d1af2af499 all: yet more misc updates 2023-06-15 19:42:54 +02:00
Markus F.X.J. Oberhumer a5206eb696 CI: cleanups 2023-06-14 07:40:14 +02:00
Markus F.X.J. Oberhumer 1ff0d137ab all: misc updates 2023-06-13 16:42:14 +02:00
John Reiser 07aa65b55e Sync stubs
Dependency processing does not propagate this one:
src/stub/src/arm.v5a-darwin.macho-main.c:
   #include "amd64-darwin.macho-main.c"
	modified:   arm.v5a-darwin.macho-fold.h
	modified:   tmp/arm.v5a-darwin.macho-fold.map
2023-06-13 16:29:13 +02:00
John Reiser 0fadddec65 Force 'bkpt' on arm.v5a and below
fixup  https://github.com/upx/upx/issues/612
	modified:   stub/src/amd64-darwin.macho-main.c
2023-06-13 16:29:13 +02:00
John Reiser 1bebe53cef Allow more bytes for Mach_headers in /usr/lib/dyld on MacOS 13
Fixes initial complaint (HelloUPX4) in https://github.com/upx/upx/issues/612
	modified:   stub/amd64-darwin.macho-fold.h
	modified:   stub/arm64-darwin.macho-fold.h
	modified:   stub/src/amd64-darwin.macho-fold.S
	modified:   stub/src/amd64-darwin.macho-main.c
	modified:   stub/tmp/amd64-darwin.macho-fold.map
	modified:   stub/tmp/arm64-darwin.macho-fold.map
2023-06-13 16:29:13 +02:00
John Reiser 43019c744c Document requirement for 'homebrew' when developing on MacOS
... else testsuite fails for "readlink -en" and 'sha256sum'
https://github.com/upx/upx/issues/676
	modified:   README.SRC
2023-06-13 16:29:13 +02:00
Markus F.X.J. Oberhumer c585774162 CI: disable self-test on macos-13 2023-06-10 11:02:19 +02:00
Markus F.X.J. Oberhumer 75e87a58da src: rework mem_clear() 2023-06-09 18:20:06 +02:00
Markus F.X.J. Oberhumer 19e84fea62 all: yet more minor updates 2023-06-09 14:12:05 +02:00
Markus F.X.J. Oberhumer db39f9c4dc all: CI and misc updates 2023-06-06 23:16:28 +02:00
Markus F.X.J. Oberhumer dae45ae0d4 all: bump version; cleanups 2023-05-28 14:06:11 +02:00
Markus F.X.J. Oberhumer efeffc6e01 submodules: update for new versions 2023-05-28 13:58:27 +02:00
Markus F.X.J. Oberhumer ebf0f2f68a all: more minor cleanups 2023-05-27 22:58:07 +02:00
Markus F.X.J. Oberhumer 09bd1d8c40 all: misc updates 2023-05-19 13:21:26 +02:00
Markus F.X.J. Oberhumer 40653e40a4 all: minor cleanups 2023-05-14 09:36:10 +02:00
Markus F.X.J. Oberhumer b3e4efbabe all: misc updates 2023-05-13 16:28:44 +02:00
John Reiser 279101d464 Fix checksum of non-compressible extents
https://github.com/upx/upx/issues/673
	modified:   src/p_unix.cpp
2023-05-13 16:28:22 +02:00
Markus F.X.J. Oberhumer f571feee72 CI: use gcc -static for macos builds 2023-05-10 20:42:26 +02:00
Markus F.X.J. Oberhumer 900afd1c8c all: minor updates 2023-05-10 20:20:39 +02:00
Markus F.X.J. Oberhumer 08a72d5251 Fix whitespace. 2023-05-10 20:19:22 +02:00
John Reiser 736a6cd955 Catch amd64 ET_EXEC with .e_entry < 0x400000
https://github.com/upx/upx/issues/673
	modified:   p_lx_elf.cpp
2023-05-10 20:17:22 +02:00
John Reiser 75ce5e5df3 Fix SIGSEGV due to name confusion in ::forward_Shdrs
https://github.com/upx/upx/issues/671
	modified:   p_lx_elf.cpp
2023-05-10 20:17:22 +02:00
Markus F.X.J. Oberhumer eaf2143162 CI: add macos-13 2023-05-03 10:06:22 +02:00
Markus F.X.J. Oberhumer f0bdb8dea1 submodules: update for new versions 2023-05-03 09:49:20 +02:00
John Reiser 60093cfff6 Merge branch 'devel4' of https://github.com/upx/upx into devel4 2023-04-30 15:19:44 -07:00
John Reiser 56bb7b53cb Synch *.h stub headers and testcase checksums
Shared libraries for amd64, i386, arm64, and arm should be
compatible with SELinux: no complaints of execmod or execmem.

https://github.com/upx/upx/issues/609
https://github.com/upx/upx/issues/220
	modified:   ../.github/travis_testsuite_1-expected_sha256sums.sh
	modified:   stub/amd64-linux.elf-so_entry.h
	modified:   stub/amd64-linux.elf-so_fold.h
	modified:   stub/arm.v4a-linux.elf-so_entry.h
	modified:   stub/arm.v4a-linux.elf-so_fold.h
	modified:   stub/arm.v5a-linux.elf-entry.h
	modified:   stub/arm.v5a-linux.elf-fold.h
	modified:   stub/arm.v5a-linux.elf-so_entry.h
	modified:   stub/arm.v5a-linux.elf-so_fold.h
	modified:   stub/arm64-linux.elf-so_entry.h
	modified:   stub/arm64-linux.elf-so_fold.h
	modified:   stub/i386-linux.elf-so_entry.h
	modified:   stub/i386-linux.elf-so_fold.h
	modified:   stub/tmp/amd64-linux.elf-so_entry.bin.dump
	modified:   stub/tmp/amd64-linux.elf-so_fold.bin.dump
	modified:   stub/tmp/arm.v5a-linux.elf-entry.bin.dump
	modified:   stub/tmp/arm.v5a-linux.elf-fold.map
2023-04-30 15:12:29 -07:00
John Reiser 0cffeca102 arm32 shlib works with SELinux
modified:   stub/src/arch/arm/v4a/macros.S
	modified:   stub/src/arm.v4a-linux.elf-so_entry.S
	modified:   stub/src/arm.v4a-linux.elf-so_fold.S
	modified:   stub/src/arm64-linux.elf-so_entry.S
	modified:   stub/src/i386-linux.elf-so_main.c
2023-04-28 13:52:26 -07:00
John Reiser 937d4462ca SELinux for i386 shlib stub
modified:   stub/src/i386-linux.elf-so_entry.S
	modified:   stub/src/i386-linux.elf-so_fold.S
	modified:   stub/src/i386-linux.elf-so_main.c
	modified:   stub/src/include/linux.h
2023-04-27 18:49:35 -07:00
John Reiser db5a39572c Change stub for arm64 shlib to work with SELinux
modified:   stub/src/arm64-linux.elf-so_entry.S
	modified:   stub/src/arm64-linux.elf-so_fold.S
2023-04-27 10:44:13 -07:00
John Reiser ecc9c67e1f Check return value from syscalls; leave debugging hint if error
modified:   stub/src/amd64-linux.elf-so_entry.S
2023-04-27 10:42:56 -07:00
John Reiser 0901ce1b68 amd64-linux.elf shlib now fully-SELinux compliant
modified:   stub/src/amd64-linux.elf-so_entry.S
	modified:   stub/src/amd64-linux.elf-so_fold.S
2023-04-26 13:06:48 -07:00
John Reiser be6e77379a SELinux forces memfd_create for .so on amd64, arm64
More coming for .so: so_entry.S, powerpc64, 32-bit
	modified:   stub/src/amd64-linux.elf-so_main.c
	modified:   stub/src/arm64-linux.elf-so_entry.S
	modified:   stub/src/arm64-linux.elf-so_fold.S
2023-04-26 08:30:55 -07:00
Markus F.X.J. Oberhumer 726f5de778 src: minor cleanups 2023-04-26 08:13:32 +02:00
John Reiser 98b835e0a7 WIP: SELinux is expensive: +2KB in stub
Needs make_hatch()
	modified:   stub/src/amd64-linux.elf-so_main.c
	modified:   stub/src/amd64-linux.elf-so_fold.S

	modified:   stub/amd64-linux.elf-so_fold.h
	modified:   stub/arm64-linux.elf-so_fold.h
	modified:   stub/src/arm.v4a-linux.elf-so_fold.S
	modified:   stub/tmp/amd64-linux.elf-so_fold.bin.dump
2023-04-24 19:40:57 -07:00
John Reiser 04ffb641a6 Compilers generate junk .sh_info
modified:   p_lx_elf.cpp
2023-04-24 19:37:25 -07:00
John Reiser 1b7233b673 whitespace
modified:   stub/src/amd64-expand.S
2023-04-24 19:35:52 -07:00
John Reiser eaa0f33473 Fix call to unfilter from amd64-expand
modified:   stub/src/amd64-expand.S

	modified:   stub/amd64-linux.elf-fold.h
	modified:   stub/amd64-linux.elf-so_fold.h
	modified:   stub/tmp/amd64-linux.elf-fold.map
	modified:   stub/tmp/amd64-linux.elf-so_fold.bin.dump
2023-04-21 08:57:10 -07:00
Markus F.X.J. Oberhumer c03b382d61 src: some more "noexcept" 2023-04-20 20:58:19 +02:00
Markus F.X.J. Oberhumer e633694255 cmake: use MSVC_FRONTEND 2023-04-20 20:10:12 +02:00
Markus F.X.J. Oberhumer 278b25bad2 cmake: check CMAKE_C_COMPILER_FRONTEND_VARIANT 2023-04-20 14:54:14 +02:00
Markus F.X.J. Oberhumer f89f0838dc src: change UPX_CONFIG logic to permissive defaults 2023-04-20 14:13:36 +02:00
Markus F.X.J. Oberhumer b1729e3bcf src: cleanup MAX_ELF_HDR 2023-04-19 23:23:46 +02:00
Markus F.X.J. Oberhumer d1ab85a1a6 src: cleanup linker.h 2023-04-19 23:19:45 +02:00
John Reiser 7f5b64c91a Merge branch 'devel4' of https://github.com/upx/upx into devel4 2023-04-19 14:00:43 -07:00
John Reiser 78b68283c4 Fix .e_entry for PowerPC64
https://github.com/upx/upx/issues/668
	modified:   p_lx_elf.cpp
2023-04-19 13:58:52 -07:00
Markus F.X.J. Oberhumer 9e3b1c9f8a src: enable TE checks in packer.h; add some "noexcept" 2023-04-18 17:56:28 +02:00
Markus F.X.J. Oberhumer 5dc54c7adc Merge branch 'devel' into devel4 2023-04-18 17:15:57 +02:00
Markus F.X.J. Oberhumer 320e5b850f all: yet more cleanups
Changes include:
  - use standard names for PE constants
  - add some more "noexcept"
  - improve upx_is_integral type-trait
  - introduce is_same_all and is_same_any type-traits
  - prepare TE-size checks in packer.h
  - CI updates
2023-04-18 17:02:13 +02:00
John Reiser d8395d8c42 Fix usage of _te32/_te64/_te16 for Elf classes
How did it ever work?  UPX_RSIZE_MAX_MEM of 768MiB, Elf32_Off of only
32-bits, and preponderance of little-endian and small positive integers
hides many mis-uses of _te64/_te32.
ELF does not help: e_phnum, e_shnum, Elf32_Section, Elf64_Section are all
16-bit, but sh_info and sh_link are 32-bit.
Templatizing p_elf.h (following the example of p_mach.h) failed
because of complexity.  (Plus too many special cases of ELF where 32-bit
and 64-bit are not parallel.)
	modified:   p_lx_elf.cpp
	modified:   p_lx_sh.cpp
	modified:   p_mach.cpp
2023-04-17 13:19:06 -07:00
John Reiser a20c5a1e7f Align 64-bit forward_Shdr
//github.com/upx/upx/issues/220
	modified:   p_lx_elf.cpp
2023-04-12 14:54:49 -07:00
John Reiser 3bdfcaa541 Try to placate Android crapware, which cannot deal with null strings
From https://github.com/upx/upx/issues/220 :

Phone:
04-10 16:07:52.862 E/AndroidRuntime( 5178): java.lang.UnsatisfiedLinkError: dlopen failed: \
"/data/app/~~Nwb-iR6LHpHyrT37xe8HNg==/com.android.support-y0YbcwLn1b4sBRD09JGVAw==/lib/arm64/libMyLibName.so" \
has unsupported e_shentsize: 0x0 (expected 0x40)

Emulator:
04-10 09:57:38.746 E/AndroidRuntime( 6403): java.lang.UnsatisfiedLinkError: dlopen failed: \
"/data/app/~~sBBMDvh36TxwO4muxOJ3Bg==/com.android.support-8Lc6r2dLzTIW7SEHXLI0XQ==/lib/arm64/libMyLibName.so" \
has no section headers

	modified:   p_lx_elf.cpp
2023-04-11 13:41:54 -07:00
John Reiser 7b2faf2016 Elf64_Rela for shlib DT_INIT_ARRAY
Also allow PT_PHDR in shlibs.
Also page align lo end of mmap, like mprotect.
        https://github.com/upx/upx/issues/664
	modified:   p_lx_elf.cpp
	modified:   stub/src/amd64-linux.elf-so_main.c
	modified:   stub/src/i386-linux.elf-so_main.c

	modified:   stub/src/amd64-linux.elf-so_fold.S
	modified:   stub/src/arm.v4a-linux.elf-fold.S
	modified:   stub/src/arm.v4a-linux.elf-so_fold.S
	modified:   stub/src/arm64-linux.elf-fold.S
	modified:   stub/src/arm64-linux.elf-so_fold.S
	modified:   stub/src/i386-linux.elf-so_fold.S

	modified:   stub/amd64-linux.elf-so_fold.h
	modified:   stub/arm.v4a-linux.elf-fold.h
	modified:   stub/arm.v4a-linux.elf-so_fold.h
	modified:   stub/arm.v5a-linux.elf-fold.h
	modified:   stub/arm.v5a-linux.elf-so_fold.h
	modified:   stub/arm64-linux.elf-fold.h
	modified:   stub/arm64-linux.elf-so_fold.h
	modified:   stub/armeb.v4a-linux.elf-fold.h
	modified:   stub/i386-linux.elf-so_fold.h

	modified:   stub/tmp/amd64-linux.elf-so_fold.bin.dump
	modified:   stub/tmp/arm.v4a-linux.elf-fold.map
	modified:   stub/tmp/arm.v5a-linux.elf-fold.map
	modified:   stub/tmp/arm64-linux.elf-fold.map
	modified:   stub/tmp/armeb.v4a-linux.elf-fold.map

	modified:   stub/src/arch/mips/r3000/macros.ash
	modified:   ../.github/travis_testsuite_1-expected_sha256sums.sh
2023-04-11 11:00:48 -07:00
John Reiser 42902dabac 64-bit shlib with DT_INIT_ARRAY but no DT_INIT
https://github.com/upx/upx/issues/664
	modified:   p_elf_enum.h
	modified:   p_lx_elf.cpp
2023-04-10 18:01:39 -07:00
John Reiser 14521eb6dd Allow pre-linking when compressing shared libraries
Such as Wine kernel32.dll etc.
https://github.com/upx/upx/issues/660
	modified:   stub/amd64-linux.elf-so_fold.h
	modified:   stub/arm.v4a-linux.elf-so_fold.h
	modified:   stub/arm.v5a-linux.elf-so_fold.h
	modified:   stub/arm64-linux.elf-so_fold.h
	modified:   stub/i386-linux.elf-so_fold.h
	modified:   stub/src/amd64-linux.elf-so_main.c
	modified:   stub/src/i386-linux.elf-so_main.c
	modified:   stub/tmp/amd64-linux.elf-so_fold.bin.dump
2023-04-03 13:18:21 -07:00
John Reiser b9533f409c Sync testsuite checksums
modified:   ../.github/travis_testsuite_1-expected_sha256sums.sh
2023-03-29 16:11:08 -07:00
John Reiser 4df68aafd2 Pprotect: mprotect but enlarge the interval to start on page boundary
https://github.com/upx/upx/issues/609
	modified:   src/stub/src/amd64-linux.elf-fold.S
	modified:   src/stub/src/amd64-linux.elf-main.c
	modified:   src/stub/src/amd64-linux.elf-so_fold.S
	modified:   src/stub/src/amd64-linux.elf-so_main.c
	modified:   src/stub/src/arm.v4a-linux.elf-fold.S
	modified:   src/stub/src/arm.v4a-linux.elf-so_fold.S
	modified:   src/stub/src/arm64-linux.elf-fold.S
	modified:   src/stub/src/arm64-linux.elf-so_fold.S
	modified:   src/stub/src/i386-linux.elf-fold.S
	modified:   src/stub/src/i386-linux.elf-main.c
	modified:   src/stub/src/i386-linux.elf-so_fold.S
	modified:   src/stub/src/i386-linux.elf-so_main.c
	modified:   src/stub/src/mipsel.r3000-linux.elf-fold.S
	modified:   src/stub/src/powerpc-linux.elf-fold.S
	modified:   src/stub/src/powerpc64le-linux.elf-fold.S

	modified:   src/stub/amd64-linux.elf-fold.h
	modified:   src/stub/amd64-linux.elf-so_fold.h
	modified:   src/stub/arm.v4a-linux.elf-fold.h
	modified:   src/stub/arm.v4a-linux.elf-so_fold.h
	modified:   src/stub/arm.v5a-linux.elf-fold.h
	modified:   src/stub/arm.v5a-linux.elf-so_fold.h
	modified:   src/stub/arm64-linux.elf-fold.h
	modified:   src/stub/arm64-linux.elf-so_fold.h
	modified:   src/stub/armeb.v4a-linux.elf-fold.h
	modified:   src/stub/i386-linux.elf-fold.h
	modified:   src/stub/i386-linux.elf-so_fold.h
	modified:   src/stub/mips.r3000-linux.elf-fold.h
	modified:   src/stub/mipsel.r3000-linux.elf-fold.h
	modified:   src/stub/powerpc-linux.elf-fold.h
	modified:   src/stub/powerpc64-linux.elf-fold.h
	modified:   src/stub/powerpc64le-linux.elf-fold.h

	modified:   src/stub/tmp/amd64-linux.elf-fold.map
	modified:   src/stub/tmp/amd64-linux.elf-so_fold.bin.dump
	modified:   src/stub/tmp/arm.v4a-linux.elf-fold.map
	modified:   src/stub/tmp/arm.v5a-linux.elf-fold.map
	modified:   src/stub/tmp/arm64-linux.elf-fold.map
	modified:   src/stub/tmp/armeb.v4a-linux.elf-fold.map
	modified:   src/stub/tmp/i386-linux.elf-fold.map
	modified:   src/stub/tmp/mips.r3000-linux.elf-fold.map
	modified:   src/stub/tmp/mipsel.r3000-linux.elf-fold.map
	modified:   src/stub/tmp/powerpc-linux.elf-fold.map
	modified:   src/stub/tmp/powerpc64-linux.elf-fold.map
	modified:   src/stub/tmp/powerpc64le-linux.elf-fold.map
2023-03-29 15:46:58 -07:00
John Reiser c72ceaa979 MSVC
modified:   p_lx_elf.cpp
2023-03-26 11:29:19 -07:00
John Reiser 8ac79ca0ad whitespce
modified:   p_lx_elf.cpp
2023-03-26 11:16:36 -07:00
John Reiser e0bfaf1028 Merge branch 'devel4' of https://github.com/upx/upx into devel4 2023-03-26 11:06:22 -07:00
John Reiser b361b91ec7 Try to appease Android runtime loader; _Shdr vs _Phdr offsets
JNI FalalError called: Unable to load library:
    [dlopen failed: "/lib/arm/libunity.so"
    .dynamic section has invalid offset: 0x6d3e58,
    expected to match PT_DYNAMIC offset: 0x441e58]
https://github.com/upx/upx/issues/609
	modified:   p_elf_enum.h
	modified:   p_lx_elf.cpp
2023-03-26 10:53:30 -07:00
John Reiser b5d1eba4c1 mprotect() requires page-aligned address
modified:   stub/amd64-linux.elf-so_fold.h
	modified:   stub/arm.v4a-linux.elf-so_fold.h
	modified:   stub/arm.v5a-linux.elf-so_fold.h
	modified:   stub/arm64-linux.elf-so_fold.h
	modified:   stub/i386-linux.elf-so_fold.h
	modified:   stub/src/amd64-linux.elf-so_fold.S
	modified:   stub/src/arm.v4a-linux.elf-so_entry.S
	modified:   stub/src/arm.v4a-linux.elf-so_fold.S
	modified:   stub/src/arm64-linux.elf-so_fold.S
	modified:   stub/src/i386-linux.elf-so_fold.S
	modified:   stub/tmp/amd64-linux.elf-so_fold.bin.dump
2023-03-26 07:26:53 -07:00
John Reiser ba447344d6 New strategy for de-compression stub for shared libraries
modified:   stub/src/amd64-linux.elf-so_main.c
	modified:   stub/src/i386-linux.elf-so_main.c
2023-03-26 07:25:32 -07:00
John Reiser 7b68aa7bdc Fix de-comression of shared libraries
modified:   p_elf_enum.h
	modified:   p_lx_elf.cpp
	modified:   p_lx_elf.h
2023-03-26 07:23:08 -07:00
John Reiser 5d15e57294 De-compression for 32-bit shared libraries on i686, ARM
https://github.com/upx/upx/issues/609
	modified:   p_lx_elf.cpp
	modified:   p_lx_elf.h
2023-03-23 16:29:25 -07:00
John Reiser 0bf8ff151e Un-debug stubs for 32-bit shared libraries
modified:   stub/arm.v4a-linux.elf-so_fold.h
	modified:   stub/arm.v5a-linux.elf-so_fold.h
	modified:   stub/i386-linux.elf-so_fold.h
	modified:   stub/src/arm.v4a-linux.elf-so_entry.S
2023-03-23 16:27:44 -07:00
John Reiser 06fae05910 32-bit ARM Android shlib: DT_INIT_ARRAY without DT_INIT
De-compressor needs to catch up.
	modified:   p_elf_enum.h
	modified:   p_lx_elf.cpp
	modified:   p_lx_elf.h
	modified:   stub/src/i386-linux.elf-so_main.c
2023-03-22 10:44:17 -07:00
Markus F.X.J. Oberhumer f68ac8155b Merge branch 'devel' into devel4 2023-03-18 21:52:17 +01:00
Markus F.X.J. Oberhumer 15484aa296 all: more cleanups
Changes include:
  - extract headers.h from conf.h
  - use "byte" in some more places
  - unify "const" coding style
  - pefile.cpp: make sort order deterministic
  - simplify some other pefile.cpp code
  - CI updates
2023-03-18 21:27:34 +01:00
John Reiser 5b113a5041 Merge branch 'devel4' of https://github.com/upx/upx into devel4 2023-03-16 08:51:29 -07:00
John Reiser 1320e3efdb PackLinuxElf32::canPackOSABI() isolates canPack() from OSABI weirdness
modified:   p_lx_elf.cpp
	modified:   p_lx_elf.h
2023-03-16 08:30:06 -07:00
Markus F.X.J. Oberhumer d32f447bda Merge branch 'devel' into devel4 2023-03-15 22:34:05 +01:00
John Reiser b74c4e4ac1 Picky, picky static analyzer
https://github.com/upx/upx/actions/runs/4422867763/jobs/7755057541
	modified:   p_lx_elf.cpp
2023-03-15 09:05:02 -07:00
John Reiser 35333403ef Zero ElfXX_Ehdr.e_sh* info when removing ElfXX_Shdr
The aim is less confusion by static linkers: the _Shdr are gone!
https://github.com/upx/upx/issues/659
	modified:   p_lx_elf.cpp
2023-03-15 08:44:59 -07:00
Markus F.X.J. Oberhumer a627648249 all: assorted cleanups and updates
Changes include:
  - add a bunch of "noexcept", mostly to operators and forceinline
  - use "uchar"
  - use "charptr"
  - rename options_t to Options
  - add ptr_check_no_overlap()
  - rewrite p_exe.cpp, NFCI
  - clang-format help.cpp
  - spelling fixes
2023-03-15 00:19:55 +01:00
Markus F.X.J. Oberhumer 127fd095e7 CI: add spell-check.yml 2023-03-11 03:11:19 +01:00
John Reiser f8934c09ff F*ck MSVC
warning C4245: 'return': conversion from 'int' to 'unsigned int', signed/unsigned mismatch
    return ~0;  // in function declared as returning 'unsigned'.  The bits are the same!
	modified:   p_lx_elf.cpp
2023-03-09 12:00:56 -08:00
John Reiser 7a09c88e30 CI convention sucks
renamed:    MAX_ELF_HDR.cpp -> MAX_ELF_HDR.h
	modified:   p_lx_elf.cpp
2023-03-09 11:44:22 -08:00
John Reiser 17526d1132 Make it easier to change MAX_ELF_HDR consistently
https://github.com/upx/upx/issues/655

	new file:   MAX_ELF_HDR.cpp
	new file:   stub/src/MAX_ELF_HDR.S
	new file:   stub/src/MAX_ELF_HDR.c

	modified:   p_lx_elf.cpp
	modified:   stub/arm.v4a-linux.elf-fold.h
	modified:   stub/arm64-linux.elf-fold.h
	modified:   stub/src/amd64-linux.elf-fold.S
	modified:   stub/src/amd64-linux.elf-main.c
	modified:   stub/src/amd64-linux.elf-so_main.c
	modified:   stub/src/arm.v4a-linux.elf-fold.S
	modified:   stub/src/arm.v4a-linux.elf-so_fold.S
	modified:   stub/src/arm64-linux.elf-fold.S
	modified:   stub/src/arm64-linux.elf-so_fold.S
	modified:   stub/src/i386-bsd.elf-fold.S
	modified:   stub/src/i386-bsd.elf-main.c
	modified:   stub/src/i386-linux.elf-fold.S
	modified:   stub/src/i386-linux.elf-main.c
	modified:   stub/src/i386-linux.elf-so_main.c
	modified:   stub/src/i386-linux.elf.interp-fold.S
	modified:   stub/src/i386-linux.elf.interp-main.c
	modified:   stub/src/i386-linux.elf.shell-fold.S
	modified:   stub/src/i386-linux.elf.shell-main.c
	modified:   stub/src/i386-openbsd.elf-fold.S
	modified:   stub/src/i386-openbsd.elf-main.c
	modified:   stub/src/mipsel.r3000-linux.elf-fold.S
	modified:   ../.github/travis_testsuite_1-expected_sha256sums.sh
2023-03-09 10:06:13 -08:00
John Reiser ff7939c1c0 invert_pt_dynamic, sort_DTxx_offsets, elf_find_table_size
https://github.com/upx/upx/issues/655
        modified:   p_lx_elf.cpp
        modified:   p_lx_elf.h
2023-03-09 09:24:35 -08:00
John Reiser 96c196b1be Final ph.u_len and ph.c_len reflect multiple compressed extents
https://github.com/upx/upx/issues/655
	modified:   ../.github/travis_testsuite_1-expected_sha256sums.sh
	modified:   p_lx_elf.cpp
2023-03-09 09:06:06 -08:00
John Reiser adb0ca8250 Many changes for ELF shared libraries on Linux and Android
Handling more than 2 PT_LOAD (and thus more than 1 executable PT_LOAD)
required extensive changes.  But the bonus is the infrastructure
to support a different (de-)compression algorithm for each PT_LOAD.

https://github.com/upx/upx/issues/341   i386 .so decompression
https://github.com/upx/upx/issues/609   armv7 .so on Android
https://github.com/upx/upx/issues/625   amd64 .so execution
https://github.com/upx/upx/issues/654   armv7 .exe
Not yet: .so on MIPS, PowerPC, PowerPC64
2023-03-04 17:37:25 -08:00
Markus F.X.J. Oberhumer fa56a1d9cd submodules: update for new versions 2023-02-24 10:59:32 +01:00
Markus F.X.J. Oberhumer 3d691645a4 src: pefile: add checkMachine() 2023-02-21 20:33:40 +01:00
Markus F.X.J. Oberhumer e1edc5f50a src: use 'byte' instead of 'upx_byte'; NFCI 2023-02-21 19:27:23 +01:00
Markus F.X.J. Oberhumer 4a8efd2e2f src: rework optimizeReloc handling; cleanups 2023-02-21 15:19:24 +01:00
Markus F.X.J. Oberhumer 8d364c82e2 CI: add build for windows arm64ec 2023-02-12 19:27:56 +01:00
Markus F.X.J. Oberhumer c5059231dc all: rename win32/arm back to wince/arm 2023-02-12 18:58:11 +01:00
Markus F.X.J. Oberhumer f584c91386 all: canonicalize win32 and win64 file names 2023-02-10 09:49:29 +01:00
Markus F.X.J. Oberhumer b8d9c2b755 all: assorted updates and cleanups 2023-02-05 17:20:32 +01:00
Markus F.X.J. Oberhumer 163377d1a0 testsuite: update checksums caused by version bump 2023-01-30 13:44:18 +01:00
Markus F.X.J. Oberhumer 8944e90175 all: post-release version bump 2023-01-30 13:39:49 +01:00
325 changed files with 33174 additions and 14710 deletions
+6 -1
View File
@@ -16,10 +16,15 @@ AttributeMacros:
- __acc_cdecl_sighandler - __acc_cdecl_sighandler
- __acc_forceinline - __acc_forceinline
- __acc_noinline - __acc_noinline
- __acc_static_noinline
- __acc_static_forceinline - __acc_static_forceinline
- __acc_static_noinline
- DELETED_FUNCTION
- XSPAN_DELETED_FUNCTION
- forceinline - forceinline
- may_throw
- noinline - noinline
- static_forceinline
- static_noinline
EmptyLineBeforeAccessModifier: Leave EmptyLineBeforeAccessModifier: Leave
SortIncludes: false SortIncludes: false
SpaceAfterCStyleCast: true SpaceAfterCStyleCast: true
+30
View File
@@ -0,0 +1,30 @@
# for clang-tidy-16 from https://clang.llvm.org/extra/clang-tidy/
---
Checks: >
-*,
bugprone-*,
-bugprone-assignment-in-if-condition,
-bugprone-branch-clone,
-bugprone-easily-swappable-parameters,
-bugprone-empty-catch,
-bugprone-implicit-widening-of-multiplication-result,
-bugprone-macro-parentheses,
-bugprone-narrowing-conversions,
-bugprone-reserved-identifier,
-bugprone-sizeof-expression,
-bugprone-suspicious-include,
-bugprone-suspicious-memory-comparison,
-bugprone-suspicious-string-compare,
-bugprone-switch-missing-default-case,
clang-analyzer-*,
-clang-analyzer-optin.performance.Padding,
-clang-analyzer-security.insecureAPI.DeprecatedOrUnsafeBufferHandling,
-clang-analyzer-security.insecureAPI.strcpy,
clang-diagnostics-*',
performance-*,
-performance-avoid-endl,
-performance-unnecessary-value-param,
FormatStyle: file
HeaderFilterRegex: '.*'
InheritParentConfig: false
...
+25 -7
View File
@@ -1,10 +1,28 @@
# make GitHub language detection more accurate, see https://github.com/github/linguist # see https://github.com/github-linguist/linguist
#
# HINT: check settings with
# git ls-files | git check-attr --stdin --all
src/*.h linguist-language=C++ #
src/*/*.h linguist-language=C++ # tell diff tools that these files are generated automatically
#
src/stub/**/*.ash linguist-language=Assembly /doc/upx.1 linguist-generated
src/stub/**/*.asm linguist-language=Assembly /doc/upx-doc.* linguist-generated
src/stub/**/*.S linguist-language=Assembly
src/stub/tmp/** linguist-vendored /src/stub/*.h linguist-generated
/src/stub/src/arch/**/lzma_d_c[fns].S linguist-generated
/src/stub/tmp/** linguist-generated
#
# make GitHub language detection more accurate
#
/src/*.h linguist-language=C++
/src/*/*.h linguist-language=C++
/src/stub/**/*.ash linguist-language=Assembly
/src/stub/**/*.asm linguist-language=Assembly
/src/stub/**/*.S linguist-language=Assembly
/src/stub/tmp/** linguist-vendored
+11
View File
@@ -0,0 +1,11 @@
* @markus-oberhumer @jreiser
/src/p_elf* @jreiser
/src/p_lx_* @jreiser
/src/p_mach* @jreiser
/src/p_unix* @jreiser
/src/p_vmlin* @jreiser
/src/stub/src/*bsd.* @jreiser
/src/stub/src/*darwin.* @jreiser
/src/stub/src/*linux.* @jreiser
+3 -2
View File
@@ -4,5 +4,6 @@ updates:
- package-ecosystem: 'github-actions' - package-ecosystem: 'github-actions'
directory: '/' directory: '/'
schedule: schedule:
# Check for updates to GitHub Actions every weekday # Check for updates to GitHub Actions every Wednesday
interval: 'daily' interval: 'weekly'
day: 'wednesday'
@@ -1,209 +0,0 @@
########## begin .sha256sums.recreate
expected_sha256sums__t010_decompressed="\
24158f78c34c4ef94bb7773a6dda7231d289be76c2f5f60e8b9ddb3f800c100e *amd64-linux.elf/upx-3.91
24808d572483f4cd713d66894b3da406755038737007a78b076528e6407e3132 *amd64-linux.elf/upx-3.95
d88eaad0528bcecec9f51cbe015a117c8cf350a3f6d8308f2b0517d4fd19d189 *amd64-win64.pe/upx-3.95.exe
f7279729eb975e4238f8b8ee56fefa41ccbeb35ef0ffe4c34f8047baab78fff5 *arm-linux.elf/upx-3.95
e09df2a69f88c692138447f274ba7f99cdd11f8696c71ac8d3761606c95ab5c5 *arm-wince.pe/upx-3.91.exe
ce81113f8a4ff1cd806811cb80ab8bea5c9c6fbced47451c7f07e50700f9817b *arm64-linux.elf/upx-3.95
b1c1c38d50007616aaf8e942839648c80a6111023e0b411e5fa7a06c543aeb4a *armeb-linux.elf/upx-3.91
84b90eb0d617571fe4885639925b35ca6a61060cb2616bb5bf729b4d701653e4 *armeb-linux.elf/upx-3.95
bcac77a287289301a45fde9a75e4e6c9ad7f8d57856bae6eafaae12ae4445a34 *i386-dos32.djgpp2.coff/upx-3.91.exe
7d331e508449497f64cd47abdd3f00f70307f508ad3fd692d333feb97beccead *i386-dos32.djgpp2.coff/upx-3.95.exe
730a513b72a094697f827e4ac1a4f8ef58a614fc7a7ad448fa58d60cd89af7ed *i386-linux.elf/upx-3.91
a1f3e5ffa7b2cfebe1e475ac1f4c7683b1b8b4e292aa0d04386cc0314dd162c9 *i386-linux.elf/upx-3.95
e90fb09a808334c2674996760d42c82f8352e3f671f6b66c11481e772785c4d2 *i386-win32.pe/upx-3.91.exe
07bd50c1d80f6ff651228e6fc0ba3a583a472915772244f232696b34156a9d27 *i386-win32.pe/upx-3.95.exe
8e5333ea040f5594d3e67d5b09e005d52b3a52ef55099a7c11d7e39ead38e66d *m68k-atari.tos/upx-3.91.ttp
8902f38ec3d95d8e077e3ab5fdbb5bad408859913a35deb87041f4f053cd6605 *mips-linux.elf/upx-3.95
c3f44b4d00a87384c03a6f9e7aec809c1addfe3e271244d38a474f296603088c *mipsel-linux.elf/upx-3.91
dd1496bc4e9c32a5d5dd47e3eaabf7b134ca001d48807eebfd3d5e28c8a2ab58 *mipsel-linux.elf/upx-3.95
b8c35fa2956da17ca505956e9f5017bb5f3a746322647e24ccb8ff28059cafa4 *powerpc-linux.elf/upx-3.91
2bc00a51daa0bada19a8fa1bd2c227a8596844fa1b0aa3611087f195072700e2 *powerpc-linux.elf/upx-3.95
a0950546dc17fca9437219431d8ddb0249ce5b08e899e0c799a87ac982adee70 *powerpc64le-linux.elf/upx-3.95
"
expected_sha256sums__t020_canonicalized="\
24158f78c34c4ef94bb7773a6dda7231d289be76c2f5f60e8b9ddb3f800c100e *amd64-linux.elf/upx-3.91
24808d572483f4cd713d66894b3da406755038737007a78b076528e6407e3132 *amd64-linux.elf/upx-3.95
d88eaad0528bcecec9f51cbe015a117c8cf350a3f6d8308f2b0517d4fd19d189 *amd64-win64.pe/upx-3.95.exe
f7279729eb975e4238f8b8ee56fefa41ccbeb35ef0ffe4c34f8047baab78fff5 *arm-linux.elf/upx-3.95
e09df2a69f88c692138447f274ba7f99cdd11f8696c71ac8d3761606c95ab5c5 *arm-wince.pe/upx-3.91.exe
ce81113f8a4ff1cd806811cb80ab8bea5c9c6fbced47451c7f07e50700f9817b *arm64-linux.elf/upx-3.95
b1c1c38d50007616aaf8e942839648c80a6111023e0b411e5fa7a06c543aeb4a *armeb-linux.elf/upx-3.91
84b90eb0d617571fe4885639925b35ca6a61060cb2616bb5bf729b4d701653e4 *armeb-linux.elf/upx-3.95
bcac77a287289301a45fde9a75e4e6c9ad7f8d57856bae6eafaae12ae4445a34 *i386-dos32.djgpp2.coff/upx-3.91.exe
7d331e508449497f64cd47abdd3f00f70307f508ad3fd692d333feb97beccead *i386-dos32.djgpp2.coff/upx-3.95.exe
730a513b72a094697f827e4ac1a4f8ef58a614fc7a7ad448fa58d60cd89af7ed *i386-linux.elf/upx-3.91
a1f3e5ffa7b2cfebe1e475ac1f4c7683b1b8b4e292aa0d04386cc0314dd162c9 *i386-linux.elf/upx-3.95
e90fb09a808334c2674996760d42c82f8352e3f671f6b66c11481e772785c4d2 *i386-win32.pe/upx-3.91.exe
07bd50c1d80f6ff651228e6fc0ba3a583a472915772244f232696b34156a9d27 *i386-win32.pe/upx-3.95.exe
8e5333ea040f5594d3e67d5b09e005d52b3a52ef55099a7c11d7e39ead38e66d *m68k-atari.tos/upx-3.91.ttp
8902f38ec3d95d8e077e3ab5fdbb5bad408859913a35deb87041f4f053cd6605 *mips-linux.elf/upx-3.95
c3f44b4d00a87384c03a6f9e7aec809c1addfe3e271244d38a474f296603088c *mipsel-linux.elf/upx-3.91
dd1496bc4e9c32a5d5dd47e3eaabf7b134ca001d48807eebfd3d5e28c8a2ab58 *mipsel-linux.elf/upx-3.95
b8c35fa2956da17ca505956e9f5017bb5f3a746322647e24ccb8ff28059cafa4 *powerpc-linux.elf/upx-3.91
2bc00a51daa0bada19a8fa1bd2c227a8596844fa1b0aa3611087f195072700e2 *powerpc-linux.elf/upx-3.95
a0950546dc17fca9437219431d8ddb0249ce5b08e899e0c799a87ac982adee70 *powerpc64le-linux.elf/upx-3.95
"
expected_sha256sums__t110_compress_ucl_nrv2b_3_no_filter="\
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="\
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="\
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="\
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="\
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="\
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="\
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
+42
View File
@@ -0,0 +1,42 @@
# see https://github.com/crate-ci/typos
# a generic spell-checker that works on source code is quite
# tricky, so some false positives are fine
[files]
extend-exclude = ["LICENSE", "misc/*/packages.txt", "misc/*/*/packages.txt"]
[default.extend-identifiers]
# misc variable names & symbols
acc_spawnve = "acc_spawnve"
ba = "ba"
fo = "fo"
fof = "fof"
O_WRONLY = "O_WRONLY"
# clang-analyzer-optin.cplusplus
optin = "optin"
sidelen = "sidelen"
tpos = "tpos"
# assembly sources
CArry = "CArry"
hda = "hda"
Larg = "Larg"
pard = "pard"
suble = "suble"
# identifiers are intelligently split into words and then checked again
[default.extend-words]
delt = "delt"
FO = "FO"
fo = "fo"
# parm is used like param
PARM = "PARM"
parm = "parm"
# rela: ELF relocations
RELA = "RELA"
rela = "rela"
# siz is used for size
siz = "siz"
# SEH: Structured Exception Handling
SEH = "SEH"
seh = "seh"
+122 -71
View File
@@ -1,4 +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 # note: GitHub Actions runner images are frequently updated, and
# unfortunately this sometimes breaks builds in mysterious ways... # unfortunately this sometimes breaks builds in mysterious ways...
@@ -9,8 +9,11 @@ name: 'CI'
on: [push, workflow_dispatch] on: [push, workflow_dispatch]
env: env:
CMAKE_REQUIRED_QUIET: OFF
DEBIAN_FRONTEND: noninteractive DEBIAN_FRONTEND: noninteractive
UPX_CMAKE_BUILD_FLAGS: --verbose UPX_CMAKE_BUILD_FLAGS: --verbose
# 2023-07-30
ZIG_DIST_VERSION: 0.11.0-dev.4320+6f0a613b6
jobs: jobs:
job-rebuild-and-verify-stubs: job-rebuild-and-verify-stubs:
@@ -21,14 +24,21 @@ jobs:
run: | run: |
uname -a; pwd; id; umask uname -a; pwd; id; umask
mkdir ../deps; cd ../deps; mkdir packages mkdir ../deps; cd ../deps; mkdir packages
# for ubuntu-22.04: install python2-minimal if ! test -e /usr/bin/python2; then
##sudo apt-get update && sudo apt-get install -y --no-install-recommends python2-minimal ####sudo apt-get update && sudo apt-get install -y --no-install-recommends python2-minimal
# manually install compat libs from Ubuntu 16.04 # install python2-minimal packages from Debian-11
wget -q 'http://archive.kernel.org/ubuntu-archive/ubuntu/pool/main/m/mpfr4/libmpfr4_3.1.6-1_amd64.deb' wget -q 'https://ftp.debian.org/debian/pool/main/p/python2.7/libpython2.7-minimal_2.7.18-8_amd64.deb'
wget -q 'https://ftp.debian.org/debian/pool/main/p/python2.7/python2.7-minimal_2.7.18-8_amd64.deb'
sudo dpkg -i ./*python2*.deb && rm ./*python2*.deb && sudo ldconfig
sudo ln -s -v python2.7 /usr/bin/python2
fi
# manually unpack and install compat libs from Ubuntu-16.04
wget -q 'https://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 for f in ./*.deb; do dpkg -x $f ./packages; done
sudo mv -v -n ./packages/usr/lib/x86_64-linux-gnu/lib* /usr/lib/x86_64-linux-gnu/ sudo mv -v -n ./packages/usr/lib/x86_64-linux-gnu/lib* /usr/lib/x86_64-linux-gnu/
rm -rf ./*.deb ./packages rm -rf ./*.deb ./packages
sudo ldconfig sudo ldconfig
# install upx-stubtools
wget -q -O - https://github.com/upx/upx-stubtools/releases/download/v20221212/bin-upx-20221212.tar.xz | tar -xJ wget -q -O - https://github.com/upx/upx-stubtools/releases/download/v20221212/bin-upx-20221212.tar.xz | tar -xJ
- name: 'Check out code' - name: 'Check out code'
uses: actions/checkout@v3 uses: actions/checkout@v3
@@ -46,7 +56,8 @@ jobs:
UPX_CLANG_FORMAT="$PWD/../deps/bin-upx-20221212/clang-format-15.0.6" make -C src clang-format UPX_CLANG_FORMAT="$PWD/../deps/bin-upx-20221212/clang-format-15.0.6" make -C src clang-format
if ! git diff --quiet; then git diff; exit 1; fi if ! git diff --quiet; then git diff; exit 1; fi
job-linux-cmake: job-linux-cmake: # uses cmake + make
if: ${{ true }}
needs: [ job-rebuild-and-verify-stubs ] needs: [ job-rebuild-and-verify-stubs ]
name: ${{ format('{0} cmake', matrix.os) }} name: ${{ format('{0} cmake', matrix.os) }}
runs-on: ${{ matrix.os }} runs-on: ${{ matrix.os }}
@@ -55,7 +66,7 @@ jobs:
matrix: matrix:
include: include:
- { os: ubuntu-22.04, use_m32: true } - { os: ubuntu-22.04, use_m32: true }
- { os: ubuntu-20.04, use_m32: false } - { os: ubuntu-20.04, use_m32: false } # use_m32 also works here, but save some CI time
steps: steps:
- name: 'Install extra 32-bit and Windows packages' - name: 'Install extra 32-bit and Windows packages'
if: ${{ matrix.use_m32 }} if: ${{ matrix.use_m32 }}
@@ -90,7 +101,7 @@ jobs:
run: 'make build/extra/cross-windows-mingw64/release' run: 'make build/extra/cross-windows-mingw64/release'
- name: 'Make artifact' - name: 'Make artifact'
run: | run: |
N=upx-${GITHUB_REF_NAME}-${GITHUB_SHA:0:7}-${{ matrix.os }} N=$(echo "upx-${GITHUB_REF_NAME}-${GITHUB_SHA:0:7}-${{ matrix.os }}" | sed 's/[^0-9a-zA-Z_.-]/-/g')
mkdir -p "tmp/artifact/$N" mkdir -p "tmp/artifact/$N"
(cd build && shopt -s nullglob && cp -ai --parents */upx{,.exe} */*/*/upx{,.exe} "../tmp/artifact/$N") (cd build && shopt -s nullglob && cp -ai --parents */upx{,.exe} */*/*/upx{,.exe} "../tmp/artifact/$N")
(cd tmp/artifact && tar --sort=name -czf "$N.tar.gz" "$N" && rm -rf "./$N") (cd tmp/artifact && tar --sort=name -czf "$N.tar.gz" "$N" && rm -rf "./$N")
@@ -101,6 +112,10 @@ jobs:
with: with:
name: ${{ env.artifact_name }} name: ${{ env.artifact_name }}
path: tmp/artifact path: tmp/artifact
- name: 'Run install tests'
run: |
(cd build/extra/gcc/release && DESTDIR=$PWD/Install-with-cmake cmake --install .)
(cd build/extra/gcc/release && DESTDIR=$PWD/Install-with-make make install)
- name: 'Run basic tests' - name: 'Run basic tests'
run: | run: |
make -C build/extra/gcc/debug test make -C build/extra/gcc/debug test
@@ -115,10 +130,11 @@ jobs:
- name: 'Run test suite build/extra/gcc/release' - name: 'Run test suite build/extra/gcc/release'
run: | run: |
export upx_testsuite_SRCDIR="$(readlink -en ../deps/upx-testsuite)" export upx_testsuite_SRCDIR="$(readlink -en ../deps/upx-testsuite)"
testsuite_1=$(readlink -en ./.github/travis_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" 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 ] needs: [ job-rebuild-and-verify-stubs ]
name: ${{ format('{0} cmake', matrix.os) }} name: ${{ format('{0} cmake', matrix.os) }}
runs-on: ${{ matrix.os }} runs-on: ${{ matrix.os }}
@@ -128,12 +144,17 @@ jobs:
include: include:
- { os: macos-11, gcc: gcc-10, gxx: 'g++-10', testsuite: true } - { os: macos-11, gcc: gcc-10, gxx: 'g++-10', testsuite: true }
- { os: macos-12, gcc: gcc-11, gxx: 'g++-11', testsuite: true } - { os: macos-12, gcc: gcc-11, gxx: 'g++-11', testsuite: true }
- { os: macos-13, gcc: gcc-12, gxx: 'g++-12', testsuite: true }
steps: steps:
- name: 'Install brew packages' - name: 'Install brew packages'
if: ${{ matrix.testsuite }} if: ${{ matrix.testsuite }}
run: | run: |
brew update # testsuite needs working "readlink -en" and "sha256sum -b"
brew install coreutils if ! test -e /usr/local/opt/coreutils/libexec/gnubin/readlink; then
echo "===== brew leaves:"; brew leaves; echo "===== brew list:"; brew list
# only run "brew update" if needed
if ! brew install coreutils; then brew update && brew install coreutils; fi
fi
- name: 'Check out code' - name: 'Check out code'
uses: actions/checkout@v3 uses: actions/checkout@v3
with: { submodules: true } with: { submodules: true }
@@ -146,10 +167,10 @@ jobs:
run: 'make build/extra/clang/release' run: 'make build/extra/clang/release'
- name: 'Build cmake extra/gcc/debug' - name: 'Build cmake extra/gcc/debug'
if: ${{ matrix.gcc != '' }} if: ${{ matrix.gcc != '' }}
run: 'make build/extra/gcc/debug CC=${{ matrix.gcc }} CXX=${{ matrix.gxx }}' run: 'make build/extra/gcc/debug CC="${{ matrix.gcc }} -static-libgcc" CXX="${{ matrix.gxx }} -static-libgcc -static-libstdc++"'
- name: 'Build cmake extra/gcc/release' - name: 'Build cmake extra/gcc/release'
if: ${{ matrix.gcc != '' }} if: ${{ matrix.gcc != '' }}
run: 'make build/extra/gcc/release CC=${{ matrix.gcc }} CXX=${{ matrix.gxx }}' run: 'make build/extra/gcc/release CC="${{ matrix.gcc }} -static-libgcc" CXX="${{ matrix.gxx }} -static-libgcc -static-libstdc++"'
- name: 'Build cmake xtarget/cross-darwin-arm64/debug' - name: 'Build cmake xtarget/cross-darwin-arm64/debug'
run: | run: |
CC="clang -target arm64-apple-darwin" CXX="clang++ -target arm64-apple-darwin" \ CC="clang -target arm64-apple-darwin" CXX="clang++ -target arm64-apple-darwin" \
@@ -160,7 +181,7 @@ jobs:
make UPX_XTARGET=cross-darwin-arm64 xtarget/release make UPX_XTARGET=cross-darwin-arm64 xtarget/release
- name: 'Make artifact' - name: 'Make artifact'
run: | run: |
N=upx-${GITHUB_REF_NAME}-${GITHUB_SHA:0:7}-${{ matrix.os }} N=$(echo "upx-${GITHUB_REF_NAME}-${GITHUB_SHA:0:7}-${{ matrix.os }}" | sed 's/[^0-9a-zA-Z_.-]/-/g')
mkdir -p "tmp/artifact/$N" mkdir -p "tmp/artifact/$N"
(cd build && rsync -R -a */*/*/upx "../tmp/artifact/$N/") (cd build && rsync -R -a */*/*/upx "../tmp/artifact/$N/")
(cd tmp/artifact && gtar --sort=name -czf "$N.tar.gz" "$N" && rm -rf "./$N") (cd tmp/artifact && gtar --sort=name -czf "$N.tar.gz" "$N" && rm -rf "./$N")
@@ -171,7 +192,12 @@ jobs:
with: with:
name: ${{ env.artifact_name }} name: ${{ env.artifact_name }}
path: tmp/artifact path: tmp/artifact
- name: 'Run install tests'
run: |
(cd build/extra/clang/release && DESTDIR=$PWD/Install-with-cmake cmake --install .)
(cd build/extra/clang/release && DESTDIR=$PWD/Install-with-make make install)
- name: 'Run basic tests' - name: 'Run basic tests'
if: ${{ !contains(matrix.os, 'macos-13') }} # FIXME: UPX on macos-13 is broken => disable self-test for now
run: | run: |
make -C build/extra/clang/debug test make -C build/extra/clang/debug test
make -C build/extra/clang/release test make -C build/extra/clang/release test
@@ -180,12 +206,13 @@ jobs:
run: | run: |
export PATH="/usr/local/opt/coreutils/libexec/gnubin:$PATH" export PATH="/usr/local/opt/coreutils/libexec/gnubin:$PATH"
export upx_testsuite_SRCDIR="$(readlink -en ../deps/upx-testsuite)" export upx_testsuite_SRCDIR="$(readlink -en ../deps/upx-testsuite)"
testsuite_1=$(readlink -en ./.github/travis_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" 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 ] needs: [ job-rebuild-and-verify-stubs ]
name: ${{ format('{0} cmake', matrix.os) }} name: ${{ format('{0} cmake', matrix.name) }}
runs-on: ${{ matrix.os }} runs-on: ${{ matrix.os }}
strategy: strategy:
fail-fast: false fail-fast: false
@@ -194,22 +221,19 @@ jobs:
# windows-2019 used to work but got broken with the 20220821.1 runner-image # 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 # update; we cannot download that image for inspection, and debugging the
# remote image is painful, so disable for now # remote image is painful, so disable for now
# see https://github.com/actions/runner-images.git ####- { name: windows-2019-amd64, os: windows-2019, vsversion: 2019, arch: amd64 }
####- { os: windows-2019 } - { name: windows-2022-amd64, os: windows-2022, vsversion: 2022, arch: amd64 }
- { os: windows-2022 }
steps: steps:
- name: 'Check out code' - name: 'Check out code'
uses: actions/checkout@v3 uses: actions/checkout@v3
with: { submodules: true } with: { submodules: true }
- name: 'Check out test suite' - name: 'Check out test suite'
run: 'git clone --depth=1 https://github.com/upx/upx-testsuite ../deps/upx-testsuite' run: 'git clone --depth=1 https://github.com/upx/upx-testsuite ../deps/upx-testsuite'
- name: 'Inspect runner-image settings' - name: 'Set up Developer Command Prompt'
# debug remote image; also see https://github.com/actions/runner-images.git uses: ilammy/msvc-dev-cmd@v1
if: ${{ false }} with:
run: | vsversion: ${{ matrix.vsversion }}
Get-Command bash; Get-Command cmake; Get-Command make arch: ${{ matrix.arch }}
bash --version; cmake --version; make --version
Get-Command cl -ErrorAction SilentlyContinue
- name: 'Build cmake debug' - name: 'Build cmake debug'
run: 'make build/debug' run: 'make build/debug'
- name: 'Build cmake release' - name: 'Build cmake release'
@@ -217,7 +241,7 @@ jobs:
- name: 'Make artifact' - name: 'Make artifact'
shell: bash shell: bash
run: | run: |
N=upx-${GITHUB_REF_NAME}-${GITHUB_SHA:0:7}-${{ matrix.os }} N=$(echo "upx-${GITHUB_REF_NAME}-${GITHUB_SHA:0:7}-${{ matrix.os }}" | sed 's/[^0-9a-zA-Z_.-]/-/g')
mkdir -p "tmp/artifact/$N" mkdir -p "tmp/artifact/$N"
(cd build && cp -ai --parents */*/upx.exe "../tmp/artifact/$N") (cd build && cp -ai --parents */*/upx.exe "../tmp/artifact/$N")
# GitHub Actions magic: set "artifact_name" environment value for use in next step # GitHub Actions magic: set "artifact_name" environment value for use in next step
@@ -228,34 +252,39 @@ jobs:
name: ${{ env.artifact_name }} name: ${{ env.artifact_name }}
path: tmp/artifact path: tmp/artifact
- name: 'Run basic tests' - name: 'Run basic tests'
if: ${{ matrix.arch != 'amd64_arm64' }}
run: | run: |
cmake --build build/debug --config Debug --target RUN_TESTS ctest --test-dir build/debug -C Debug
cmake --build build/release --config Release --target RUN_TESTS ctest --test-dir build/release -C Release
- name: 'Run test suite build/release' - name: 'Run test suite build/release'
if: ${{ matrix.arch != 'amd64_arm64' }}
shell: bash shell: bash
run: | run: |
export upx_testsuite_SRCDIR="$(readlink -en ../deps/upx-testsuite)" export upx_testsuite_SRCDIR="$(readlink -en ../deps/upx-testsuite)"
testsuite_1=$(readlink -en ./.github/travis_testsuite_1.sh) testsuite_1="$(readlink -en ./misc/testsuite/upx_testsuite_1.sh)"
env -C build/release/Release upx_exe=./upx bash "$testsuite_1" 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 ] needs: [ job-rebuild-and-verify-stubs ]
name: ${{ format('windows {0}', matrix.name) }} name: ${{ format('windows {0}', matrix.name) }}
runs-on: ${{ matrix.os }} runs-on: ${{ matrix.os }}
env: env:
C: ${{ matrix.C }} C: ${{ matrix.name }}
B: release B: release
H: 'd:\a\upx\upx' H: 'd:\a\upx\upx'
strategy: strategy:
fail-fast: false fail-fast: false
matrix: matrix:
include: include:
- { name: amd64-win64-vs2019, os: windows-2019, C: msvc-14.2-x64, arch: amd64 } - { name: amd64-win64-vs2019, os: windows-2019, vsversion: 2019, arch: amd64 }
- { name: amd64-win64-vs2022, os: windows-2022, C: msvc-14.3-x64, arch: amd64 } - { name: amd64-win64-vs2022, os: windows-2022, vsversion: 2022, arch: amd64 }
- { name: arm64-win64-vs2019, os: windows-2019, C: msvc-14.2-x64, arch: amd64_arm64 } - { name: arm64-win64-vs2019, os: windows-2019, vsversion: 2019, arch: amd64_arm64 }
- { name: arm64-win64-vs2022, os: windows-2022, C: msvc-14.3-x64, arch: amd64_arm64 } - { name: arm64-win64-vs2022, os: windows-2022, vsversion: 2022, arch: amd64_arm64 }
- { name: i386-win32-vs2019, os: windows-2019, C: msvc-14.2-x86, arch: amd64_x86 } - { name: arm64ec-win64-vs2022, os: windows-2022, vsversion: 2022, arch: amd64_arm64, cl_machine_flags: -arm64EC, link_machine_flags: '/machine:arm64ec' }
- { name: i386-win32-vs2022, os: windows-2022, C: msvc-14.3-x86, arch: amd64_x86 } # { name: arm64x-win64-vs2022, os: windows-2022, vsversion: 2022, arch: amd64_arm64, cl_machine_flags: -arm64EC, link_machine_flags: '/machine:arm64x' }
- { name: i386-win32-vs2019, os: windows-2019, vsversion: 2019, arch: amd64_x86 }
- { name: i386-win32-vs2022, os: windows-2022, vsversion: 2022, arch: amd64_x86 }
steps: steps:
- name: 'Check out code' - name: 'Check out code'
uses: actions/checkout@v3 uses: actions/checkout@v3
@@ -263,47 +292,55 @@ jobs:
- name: 'Prepare sources and Check out test suite' - name: 'Prepare sources and Check out test suite'
shell: bash shell: bash
run: | run: |
git config --global core.autocrlf input
git --version && bash --version
git clone --depth=1 https://github.com/upx/upx-testsuite ../deps/upx-testsuite git clone --depth=1 https://github.com/upx/upx-testsuite ../deps/upx-testsuite
mkdir -p -v build/$C/$B/{ucl,upx,zlib,zstd} mkdir -p -v build/$C/$B/{bzip2,ucl,upx,zlib,zstd}
- name: 'Set up Developer Command Prompt' - name: 'Set up Developer Command Prompt'
uses: ilammy/msvc-dev-cmd@v1 uses: ilammy/msvc-dev-cmd@v1
with: with:
vsversion: ${{ matrix.vsversion }}
arch: ${{ matrix.arch }} arch: ${{ matrix.arch }}
- name: 'Build' - name: 'Build by hand'
shell: cmd shell: cmd
run: | run: |
@REM setup directories @REM ===== set vars =====
where cl & where link where cl & where link
set BDIR=%H%\build\%C%\%B% set RUN_CL=cl ${{ matrix.cl_machine_flags }} -MT
set RUN_LIB=link -lib ${{ matrix.link_machine_flags }}
set DEFS=-D_CRT_NONSTDC_NO_WARNINGS -D_CRT_SECURE_NO_WARNINGS set DEFS=-D_CRT_NONSTDC_NO_WARNINGS -D_CRT_SECURE_NO_WARNINGS
set BDIR=%H%\build\%C%\%B%
git rev-parse --short=12 HEAD > %BDIR%\upx\.GITREV.txt git rev-parse --short=12 HEAD > %BDIR%\upx\.GITREV.txt
@REM ===== build bzip2 =====
cd %BDIR%\bzip2
@rem %RUN_CL% -J -O2 -W4 -wd4127 -wd4244 -wd4267 -WX %DEFS% -c %H%\vendor\bzip2\*.c
@rem %RUN_LIB% -out:bzip2.lib *.obj
@REM ===== build UCL ===== @REM ===== build UCL =====
cd %BDIR%\ucl cd %BDIR%\ucl
set s=%H%\vendor\ucl set s=%H%\vendor\ucl
cl -MT -J -O2 -W4 -WX %DEFS% -I%s%\include -I%s% -c %s%\src\*.c %RUN_CL% -J -O2 -W4 -WX %DEFS% -I%s%\include -I%s% -c %s%\src\*.c
link -lib -out:ucl.lib *.obj %RUN_LIB% -out:ucl.lib *.obj
@REM ===== build zlib ===== @REM ===== build zlib =====
cd %BDIR%\zlib cd %BDIR%\zlib
cl -MT -J -O2 -W3 -WX %DEFS% -c %H%\vendor\zlib\*.c %RUN_CL% -J -O2 -W3 -WX %DEFS% -DHAVE_VSNPRINTF -c %H%\vendor\zlib\*.c
link -lib -out:zlib.lib *.obj %RUN_LIB% -out:zlib.lib *.obj
@REM ===== build zstd ===== @REM ===== build zstd =====
@rem cd %BDIR%\zstd cd %BDIR%\zstd
@rem set s=%H%\vendor\zstd\lib 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 %RUN_CL% -J -O2 -W4 -WX %DEFS% -DDYNAMIC_BMI2=0 -DZSTD_DISABLE_ASM -c %s%\common\*.c %s%\compress\*.c %s%\decompress\*.c
@rem link -lib -out:zstd.lib *.obj @rem %RUN_LIB% -out:zstd.lib *.obj
@REM ===== build UPX ===== @REM ===== build UPX =====
cd %BDIR%\upx cd %BDIR%\upx
set s=%H%\src set s=%H%\src
cat .GITREV.txt cat .GITREV.txt
set /p GITREV=<.GITREV.txt set /p GITREV=<.GITREV.txt
set UPX_DEFS=-DUPX_CONFIG_DISABLE_WSTRICT=0 -DUPX_CONFIG_DISABLE_WERROR=0 -DWITH_BZIP2=0 -DWITH_ZSTD=0
set UPX_LIBS=%BDIR%\ucl\ucl.lib %BDIR%\zlib\zlib.lib
@rem set UPX_LIBS=%BDIR%\bzip2\bzip2.lib %BDIR%\ucl\ucl.lib %BDIR%\zlib\zlib.lib %BDIR%\zstd\zstd.lib
set sources=%s%\*.cpp %s%\check\*.cpp %s%\compress\*.cpp %s%\console\*.cpp %s%\filter\*.cpp %s%\util\*.cpp 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 %RUN_CL% -J -O2 -W4 -WX -std:c++17 -Zc:__cplusplus -EHsc -DUPX_VERSION_GITREV="""%GITREV%""" %DEFS% %UPX_DEFS% -I%H%\vendor -Feupx.exe %sources% %UPX_LIBS% /link ${{ matrix.link_machine_flags }} setargv.obj
- name: 'Make artifact' - name: 'Make artifact'
shell: bash shell: bash
run: | run: |
N=upx-${GITHUB_REF_NAME}-${GITHUB_SHA:0:7}-windows-${{ matrix.name }} N=$(echo "upx-${GITHUB_REF_NAME}-${GITHUB_SHA:0:7}-windows-${{ matrix.name }}" | sed 's/[^0-9a-zA-Z_.-]/-/g')
mkdir -p "tmp/artifact/$N/$B" mkdir -p "tmp/artifact/$N/$B"
cp -ai build/$C/$B/upx/upx*.exe "tmp/artifact/$N/$B" cp -ai build/$C/$B/upx/upx*.exe "tmp/artifact/$N/$B"
# GitHub Actions magic: set "artifact_name" environment value for use in next step # GitHub Actions magic: set "artifact_name" environment value for use in next step
@@ -331,35 +368,44 @@ jobs:
shell: bash shell: bash
run: | run: |
export upx_testsuite_SRCDIR="$(readlink -en ../deps/upx-testsuite)" export upx_testsuite_SRCDIR="$(readlink -en ../deps/upx-testsuite)"
testsuite_1=$(readlink -en ./.github/travis_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" env -C build/$C/$B/upx upx_exe=./upx.exe bash "$testsuite_1"
job-linux-zigcc: job-linux-zigcc: # uses cmake + make
if: ${{ true }} if: ${{ true }}
needs: [ job-rebuild-and-verify-stubs ] needs: [ job-rebuild-and-verify-stubs ]
name: ${{ format('zigcc {0} {1}', matrix.zig_target, matrix.zig_pic) }} name: ${{ format('zigcc {0} {1}', matrix.zig_target, matrix.zig_pic) }}
runs-on: ubuntu-latest runs-on: ubuntu-latest
##container: alpine:3.17 # older versions such as alpine:3.12 also work; no-container also works container: 'alpine:3.18' # older versions such as alpine:3.12 also work; no-container also works
strategy: strategy:
fail-fast: false fail-fast: false
matrix: matrix:
include: include:
# only build a few targets => more targets are tested in the Weekly CI
- { zig_target: aarch64-linux-musl } - { zig_target: aarch64-linux-musl }
- { zig_target: aarch64-macos.11-none } # { zig_target: aarch64-linux-musl, zig_pic: -fPIE }
- { zig_target: aarch64-macos.12-none } # { zig_target: aarch64-macos-none }
- { zig_target: aarch64-macos.13-none } - { zig_target: aarch64-macos.11.0-none }
# { zig_target: aarch64-macos.12.0-none }
# { zig_target: aarch64-macos.13.0-none }
- { zig_target: aarch64-windows-gnu } - { zig_target: aarch64-windows-gnu }
- { zig_target: i386-linux-musl } - { zig_target: arm-linux-musleabihf }
# { zig_target: arm-linux-musleabihf, zig_pic: -fPIE }
# { zig_target: i386-linux-musl }
- { zig_target: i386-windows-gnu } - { zig_target: i386-windows-gnu }
# { zig_target: mips-linux-musl }
# { zig_target: mipsel-linux-musl }
# { zig_target: powerpc-linux-musl }
# { zig_target: powerpc64-linux-musl }
# { zig_target: powerpc64le-linux-musl }
- { zig_target: x86_64-linux-musl } - { zig_target: x86_64-linux-musl }
- { zig_target: x86_64-linux-musl, zig_pic: -fPIE } # { zig_target: x86_64-linux-musl, zig_pic: -fPIE }
- { zig_target: x86_64-macos.11-none } # { zig_target: x86_64-macos-none }
- { zig_target: x86_64-macos.12-none } - { zig_target: x86_64-macos.11.0-none }
- { zig_target: x86_64-macos.13-none } # { zig_target: x86_64-macos.12.0-none }
# { zig_target: x86_64-macos.13.0-none }
- { zig_target: x86_64-windows-gnu } - { zig_target: x86_64-windows-gnu }
env: env:
# 2023-01-30
ZIG_DIST_VERSION: 0.11.0-dev.1491+2b27bc2c6
# for zig-cc wrapper scripts (see below): # for zig-cc wrapper scripts (see below):
ZIG_CPPFLAGS: -DUPX_DOCTEST_CONFIG_MULTITHREADING ZIG_CPPFLAGS: -DUPX_DOCTEST_CONFIG_MULTITHREADING
ZIG_FLAGS: ${{ matrix.zig_flags }} ZIG_FLAGS: ${{ matrix.zig_flags }}
@@ -391,7 +437,7 @@ jobs:
mkdir -p -v ~/.local/bin mkdir -p -v ~/.local/bin
cd ~/.local/bin cd ~/.local/bin
ZIG_DIST_NAME=zig-linux-x86_64-${ZIG_DIST_VERSION} ZIG_DIST_NAME=zig-linux-x86_64-${ZIG_DIST_VERSION}
wget -q 'https://ziglang.org/builds/'${ZIG_DIST_NAME}.tar.xz wget -q https://ziglang.org/builds/${ZIG_DIST_NAME}.tar.xz
ls -l ${ZIG_DIST_NAME}.tar.xz ls -l ${ZIG_DIST_NAME}.tar.xz
tar -xoJf ${ZIG_DIST_NAME}.tar.xz tar -xoJf ${ZIG_DIST_NAME}.tar.xz
rm ${ZIG_DIST_NAME}.tar.xz rm ${ZIG_DIST_NAME}.tar.xz
@@ -422,7 +468,7 @@ jobs:
- name: ${{ format('Make artifact from upx-{0}-{1}', github.ref_name, env.UPX_GITREV_SHORT) }} - name: ${{ format('Make artifact from upx-{0}-{1}', github.ref_name, env.UPX_GITREV_SHORT) }}
shell: bash shell: bash
run: | run: |
N=upx-${GITHUB_REF_NAME}-${GITHUB_SHA:0:7}-zigcc-${{ matrix.zig_target }}${ZIG_PIC} N=$(echo "upx-${GITHUB_REF_NAME}-${GITHUB_SHA:0:7}-zigcc-${{ matrix.zig_target }}${ZIG_PIC}" | sed 's/[^0-9a-zA-Z_.-]/-/g')
mkdir -p "tmp/artifact/$N" mkdir -p "tmp/artifact/$N"
(cd build && shopt -s nullglob && cp -ai --parents */upx{,.exe} */*/*/upx{,.exe} "../tmp/artifact/$N") (cd build && shopt -s nullglob && cp -ai --parents */upx{,.exe} */*/*/upx{,.exe} "../tmp/artifact/$N")
(cd tmp/artifact && tar --sort=name -czf "$N.tar.gz" "$N" && rm -rf "./$N") (cd tmp/artifact && tar --sort=name -czf "$N.tar.gz" "$N" && rm -rf "./$N")
@@ -433,5 +479,10 @@ jobs:
with: with:
name: ${{ env.artifact_name }} name: ${{ env.artifact_name }}
path: tmp/artifact path: tmp/artifact
- name: 'Run install tests'
if: ${{ contains(matrix.zig_target, '-linux') }}
run: |
(cd build/zig/${ZIG_TARGET}${ZIG_PIC}/release && DESTDIR=$PWD/Install-with-cmake cmake --install .)
(cd build/zig/${ZIG_TARGET}${ZIG_PIC}/release && DESTDIR=$PWD/Install-with-make make install)
# vim:set ts=2 sw=2 et: # vim:set ts=2 sw=2 et:
@@ -1,3 +1,5 @@
# Copyright (C) Markus Franz Xaver Johannes Oberhumer
# see https://docs.github.com/en/actions/managing-issues-and-pull-requests/closing-inactive-issues # see https://docs.github.com/en/actions/managing-issues-and-pull-requests/closing-inactive-issues
# see https://github.com/actions/stale # see https://github.com/actions/stale
@@ -12,8 +14,7 @@
name: 'GitHub - Close inactive issues' name: 'GitHub - Close inactive issues'
on: on:
schedule: schedule: [cron: '50 3 * * 3'] # run weekly Wednesday 03:50 UTC
- cron: '30 6 * * 4'
workflow_dispatch: workflow_dispatch:
jobs: jobs:
close-issues: close-issues:
@@ -23,11 +24,11 @@ jobs:
issues: write issues: write
pull-requests: write pull-requests: write
steps: steps:
- uses: actions/stale@v7 - uses: actions/stale@v8
with: with:
operations-per-run: 300 operations-per-run: 300
exempt-all-milestones: true exempt-all-milestones: true
exempt-issue-labels: 'blocker,enhancement,regression' exempt-issue-labels: 'blocker,bug,enhancement,help wanted,regression'
days-before-stale: 60 days-before-stale: 60
days-before-close: 30 days-before-close: 30
stale-issue-message: 'This issue is stale because it has been open 60 days with no activity. Please remove the stale label or add a comment or this issue will be closed in 30 days.' stale-issue-message: 'This issue is stale because it has been open 60 days with no activity. Please remove the stale label or add a comment or this issue will be closed in 30 days.'
@@ -1,3 +1,4 @@
# Copyright (C) Markus Franz Xaver Johannes Oberhumer
name: 'GitHub - Close pull requests' name: 'GitHub - Close pull requests'
on: on:
#pull_request: #pull_request:
-29
View File
@@ -1,29 +0,0 @@
# 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' }
+19
View File
@@ -0,0 +1,19 @@
# Copyright (C) Markus Franz Xaver Johannes Oberhumer
# see https://github.com/crate-ci/typos
name: 'Misc - Spell check'
on:
workflow_dispatch:
env:
DEBIAN_FRONTEND: noninteractive
jobs:
job-spell-check:
name: 'Spell check'
runs-on: ubuntu-latest
steps:
- name: 'Check out code'
uses: actions/checkout@v3
with: { submodules: false }
- name: 'Spell check with crate-ci/typos'
uses: crate-ci/typos@master
with: { config: ./.github/typos_config.toml }
-22
View File
@@ -1,22 +0,0 @@
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'
@@ -0,0 +1,30 @@
# Copyright (C) Markus Franz Xaver Johannes Oberhumer
name: 'Static Analyzer - clang-analyzer'
on:
schedule: [cron: '10 5 * * 3'] # run weekly Wednesday 05:10 UTC
workflow_dispatch:
env:
CMAKE_REQUIRED_QUIET: OFF
DEBIAN_FRONTEND: noninteractive
jobs:
job-analyze-clang-analyzer: # uses cmake + make
strategy:
fail-fast: false
matrix: {container: ['alpine:3.16','alpine:3.17','alpine:3.18','alpine:edge','i386/alpine:edge']}
name: ${{ format('Analyze {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 clang clang-analyzer cmake g++ git make'
- 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
- name: 'Perform clang-analyzer scan-build Analysis Debug'
run: 'make -C upx build/analyze/clang-analyzer/debug'
- name: 'Perform clang-analyzer scan-build Analysis Release'
if: success() || failure() # run this step even if the previous step failed
run: 'make -C upx build/analyze/clang-analyzer/release'
@@ -0,0 +1,30 @@
# Copyright (C) Markus Franz Xaver Johannes Oberhumer
name: 'Static Analyzer - clang-tidy'
on:
schedule: [cron: '30 5 * * 3'] # run weekly Wednesday 05:30 UTC
workflow_dispatch:
env:
CMAKE_REQUIRED_QUIET: OFF
DEBIAN_FRONTEND: noninteractive
jobs:
job-analyze-clang-tidy: # uses cmake + make
strategy:
fail-fast: false
matrix: {container: ['alpine:edge','i386/alpine:edge']}
name: ${{ format('Analyze clang-tidy {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 clang clang-extra-tools cmake g++ git make python3'
- 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
- name: 'Perform clang-tidy Analysis Debug'
run: 'make -k -C upx build/analyze/clang-tidy/debug'
- name: 'Perform clang-tidy Analysis Release'
if: success() || failure() # run this step even if the previous step failed
run: 'make -k -C upx build/analyze/clang-tidy/release'
@@ -1,29 +1,25 @@
name: 'Static Analyzer - CodeQL' # Copyright (C) Markus Franz Xaver Johannes Oberhumer
name: 'Static Analyzer - CodeQL'
on: on:
# push: schedule: [cron: '50 5 * * 3'] # run weekly Wednesday 05:50 UTC
# 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: workflow_dispatch:
env:
CMAKE_REQUIRED_QUIET: OFF
DEBIAN_FRONTEND: noninteractive
jobs: jobs:
analyze: job-analyze-codeql:
name: Analyze name: Analyze
runs-on: ubuntu-latest runs-on: ubuntu-latest
permissions: permissions:
actions: read actions: read
contents: read contents: read
security-events: write security-events: write
strategy: strategy:
fail-fast: false fail-fast: false
matrix: matrix:
language: [ 'cpp' ] language: [ 'cpp' ]
steps: steps:
- name: Checkout repository - name: Checkout repository
uses: actions/checkout@v3 uses: actions/checkout@v3
+135
View File
@@ -0,0 +1,135 @@
# Copyright (C) Markus Franz Xaver Johannes Oberhumer
# test minimal number of packages required for building UPX under Alpine Linux
# clang: apk add clang cmake make
# gcc: apk add cmake g++ make
name: 'Test - Minimal Alpine build'
on: [workflow_dispatch]
env:
CMAKE_REQUIRED_QUIET: OFF
DEBIAN_FRONTEND: noninteractive
jobs:
job-alpine-clang: # uses cmake + make
strategy: { matrix: { container: ['alpine:edge','i386/alpine:edge'] } }
name: ${{ format('clang {0}', matrix.container) }}
runs-on: ubuntu-latest
container: ${{ matrix.container }}
steps:
- name: ${{ format('Build clang {0}', matrix.container) }}
run: |
apk update && apk upgrade && apk add clang cmake make
wget https://github.com/upx/upx/releases/download/v4.0.2/upx-4.0.2-src.tar.xz
tar -xoaf upx-*-src.tar.xz
cd upx-*-src
make build/debug CC="clang -static" CXX="clang++ -static"
make build/release CC="clang -static" CXX="clang++ -static"
make -C build/debug test
make -C build/release test
make -C build/release install DESTDIR="$PWD/Install"
N=$(echo "upx-test-alpine-linux-clang-${{ matrix.container }}" | sed 's/[^0-9a-zA-Z_.-]/-/g')
echo "artifact_name=$N" >> $GITHUB_ENV
- 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'
job-alpine-gcc: # uses cmake + make
strategy: { matrix: { container: ['alpine:edge','i386/alpine:edge'] } }
name: ${{ format('gcc {0}', matrix.container) }}
runs-on: ubuntu-latest
container: ${{ matrix.container }}
steps:
- name: ${{ format('Build gcc {0}', matrix.container) }}
run: |
apk update && apk upgrade && apk add cmake g++ make
wget https://github.com/upx/upx/releases/download/v4.0.2/upx-4.0.2-src.tar.xz
tar -xoaf upx-*-src.tar.xz
cd upx-*-src
make build/debug CC="gcc -static" CXX="g++ -static"
make build/release CC="gcc -static" CXX="g++ -static"
make -C build/debug test
make -C build/release test
make -C build/release install DESTDIR="$PWD/Install"
N=$(echo "upx-test-alpine-linux-gcc-${{ matrix.container }}" | sed 's/[^0-9a-zA-Z_.-]/-/g')
echo "artifact_name=$N" >> $GITHUB_ENV
- 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'
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 ccache as we are running the same build-script again and again
if: ${{ true }}
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: |
# install ccache, g++, git and various POSIX shells
shells="bash dash loksh mksh zsh"
case ${{ matrix.container }} in
*:edge) shells="$shells oksh yash" ;;
esac
echo "installing shells: $shells"
apk update && apk upgrade && apk add ccache g++ git $shells
# enable ccache
echo -e "CC=ccache gcc\nCXX=ccache g++ -std=gnu++17" >> $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
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 bash --posix'
run: 'bash --posix "./upx with space/misc/scripts/build_upx_by_hand.sh"'
- name: 'Build by-hand with busybox ash'
run: 'busybox ash "./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 loksh'
run: 'ksh "./upx with space/misc/scripts/build_upx_by_hand.sh"'
- name: 'Build by-hand with loksh -o posix'
run: 'ksh -o posix "./upx with space/misc/scripts/build_upx_by_hand.sh"'
- name: 'Build by-hand with loksh -o sh'
run: 'ksh -o sh "./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 mksh -o posix'
run: 'mksh -o posix "./upx with space/misc/scripts/build_upx_by_hand.sh"'
- name: 'Build by-hand with mksh -o sh'
run: 'mksh -o sh "./upx with space/misc/scripts/build_upx_by_hand.sh"'
- name: 'Build by-hand with oksh'
if: ${{ contains(matrix.container, ':edge') }}
run: 'oksh "./upx with space/misc/scripts/build_upx_by_hand.sh"'
- name: 'Build by-hand with oksh -o posix'
if: ${{ contains(matrix.container, ':edge') }}
run: 'oksh -o posix "./upx with space/misc/scripts/build_upx_by_hand.sh"'
- name: 'Build by-hand with oksh -o sh'
if: ${{ contains(matrix.container, ':edge') }}
run: 'oksh -o sh "./upx with space/misc/scripts/build_upx_by_hand.sh"'
- name: 'Build by-hand with yash'
if: ${{ contains(matrix.container, ':edge') }}
run: 'yash "./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"'
- name: 'Build by-hand with zsh --emulate ksh'
run: 'zsh --emulate ksh "./upx with space/misc/scripts/build_upx_by_hand.sh"'
- name: 'Build by-hand with zsh --emulate sh'
run: 'zsh --emulate sh "./upx with space/misc/scripts/build_upx_by_hand.sh"'
- name: 'Show ccache stats'
run: |
ccache -s
ccache -p
+132
View File
@@ -0,0 +1,132 @@
# Copyright (C) Markus Franz Xaver Johannes Oberhumer
name: 'Test - CMake default build type'
on: [workflow_dispatch]
env:
CMAKE_REQUIRED_QUIET: OFF
DEBIAN_FRONTEND: noninteractive
jobs:
#
# single-config generators - these use and respect CMAKE_BUILD_TYPE
#
cmake-make:
runs-on: ubuntu-latest
steps:
- name: 'Check out code'
uses: actions/checkout@v3
with: { submodules: true }
- name: 'Config, build, test and install'
run: |
cmake -S . -B build/default -G "Unix Makefiles"
cmake --build build/default --parallel --verbose
ctest --test-dir build/default
(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
cmake-ninja:
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
cmake --build build/default --parallel --verbose
ctest --test-dir build/default
(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
cmake-nmake:
runs-on: windows-2022
steps:
- name: 'Check out code'
uses: actions/checkout@v3
with: { submodules: true }
- name: 'Set up Developer Command Prompt'
uses: ilammy/msvc-dev-cmd@v1
with:
vsversion: 2022
arch: amd64
- name: 'Config, build, test and install'
run: |
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
# "nmake install" also works
env -C build/default DESTDIR=./Install-with-nmake nmake install
#
# 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'
uses: actions/checkout@v3
with: { submodules: true }
- name: 'Set up Developer Command Prompt'
uses: ilammy/msvc-dev-cmd@v1
with:
vsversion: 2022
arch: amd64
- name: 'Config, build and test'
run: |
cmake -S . -B build/default
cmake --build build/default --parallel --verbose
# multi-config: ctest NEEDS a config
ctest --test-dir build/default -C Debug
# TODO: does cmake --install work?
# 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'
uses: actions/checkout@v3
with: { submodules: true }
- name: 'Config, build, test and install'
run: |
cmake -S . -B build/default -G Xcode
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" !!
(cd build/default && DESTDIR=$PWD/Install-default cmake --install . --config Debug)
@@ -0,0 +1,156 @@
# Copyright (C) Markus Franz Xaver Johannes Oberhumer
# Build under various Alpine Linux versions with clang and gcc, and
# also test building with C++20 and C++23.
# And 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
name: 'Weekly CI - Alpine Linux'
on:
schedule: [cron: '05 4 * * 3'] # run weekly Wednesday 04:05 UTC
workflow_dispatch:
env:
CMAKE_REQUIRED_QUIET: OFF
DEBIAN_FRONTEND: noninteractive
UPX_TESTSUITE_LEVEL: 2
jobs:
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'] }
name: ${{ format('container {0}', matrix.container) }}
runs-on: ubuntu-latest
container: ${{ matrix.container }}
env: { UPX_CMAKE_CONFIG_FLAGS: '-DCMAKE_VERBOSE_MAKEFILE=ON' }
steps:
- name: ${{ format('Install packages {0}', matrix.container) }}
run: |
apk update && apk upgrade && apk add clang cmake g++ git make
case ${{ matrix.container }} in
# 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 ;;
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 "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')
echo "artifact_name=$N" >> $GITHUB_ENV
# build with default C11 and C++17
- name: ${{ format('Build clang Release with {0}', env.clang_package) }}
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 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 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 with space" UPX_XTARGET=gcc-static CC="gcc -static" CXX="g++ -static" xtarget/debug'
- name: 'Update environment'
run: |
echo "UPX_CONFIG_DISABLE_C_STANDARD=ON" >> $GITHUB_ENV
echo "UPX_CONFIG_DISABLE_CXX_STANDARD=ON" >> $GITHUB_ENV
# build with C17 and C++20 on alpine:edge
- name: ${{ format('Build clang C++20 Release with {0}', env.clang_package) }}
if: ${{ contains(matrix.container, ':edge') }}
run: |
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 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 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 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 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 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 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 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
- name: ${{ format('Build clang LTO Release with {0}', env.clang_package) }}
if: ${{ contains(matrix.container, ':edge') }}
run: |
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) }}
if: ${{ contains(matrix.container, ':edge') }}
run: |
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) }}
if: ${{ contains(matrix.container, ':edge') }}
run: |
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) }}
if: ${{ contains(matrix.container, ':edge') }}
run: |
make -C "upx with space" UPX_XTARGET=gcc-cxxlto-static CC="gcc -flto=auto -static" CXX="g++ -flto=auto -static" xtarget/debug
- { 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 with space*/build/*/*/*/upx'
- { 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, C++23 and LTO'
if: ${{ contains(matrix.container, ':edge') }}
run: |
for dir in "upx with space"/build/xtarget/*-cxx*/*; do
echo "===== $dir"
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)
# test suite
- name: ${{ format('Run test suite level {0}', env.UPX_TESTSUITE_LEVEL) }}
run: |
# use a directory that contains whitespace to detect possible quoting issues
git clone --depth=1 https://github.com/upx/upx-testsuite "upx-testsuite with space"
export upx_testsuite_SRCDIR="$(readlink -fn "upx-testsuite with space")"
testsuite_1="$(readlink -fn "upx with space"/misc/testsuite/upx_testsuite_1.sh)"
# testsuite needs bash and working "readlink -en" and "sha256sum -b"
apk add bash coreutils
(cd "upx with space"/build/xtarget/gcc-static/release && upx_exe=./upx bash "$testsuite_1")
# vim:set ts=2 sw=2 et:
@@ -0,0 +1,54 @@
# Copyright (C) Markus Franz Xaver Johannes Oberhumer
# build with 'cmake -G Xcode'
name: 'Weekly CI - cmake macOS Xcode'
on:
schedule: [cron: '20 4 * * 3'] # run weekly Wednesday 04:20 UTC
workflow_dispatch:
env:
CMAKE_REQUIRED_QUIET: OFF
DEBIAN_FRONTEND: noninteractive
jobs:
job-cmake-macos-xcode: # uses cmake + xcodebuild
name: ${{ format('{0} cmake Xcode', matrix.os) }}
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
include:
- { os: macos-11, run_test: true }
- { os: macos-12, run_test: true }
- { os: macos-13, run_test: false } # TODO: enable once UPX fully works on macos-13
steps:
- name: 'Check out code'
uses: actions/checkout@v3
with: { submodules: true }
- { name: 'Config cmake Xcode', run: 'cmake -S . -B build/xcode -G Xcode' }
- { name: 'Build cmake Xcode default', run: 'cmake --build build/xcode' }
- { name: 'Build cmake Xcode Debug', run: 'cmake --build build/xcode --config Debug' }
- { name: 'Build cmake Xcode Release', run: 'cmake --build build/xcode --config Release' }
- name: 'Make artifact'
run: |
N=$(echo "upx-${GITHUB_REF_NAME}-${GITHUB_SHA:0:7}-weekly-ci-xcode-${{ matrix.os }}" | sed 's/[^0-9a-zA-Z_.-]/-/g')
mkdir -p "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
- name: ${{ format('Upload artifact {0}', env.artifact_name) }}
uses: actions/upload-artifact@v3
with:
name: ${{ env.artifact_name }}
path: tmp/artifact
- name: 'Run basic tests'
if: ${{ matrix.run_test }}
run: |
ctest --test-dir build/xcode -C Debug
ctest --test-dir build/xcode -C Release
- name: 'Run install tests'
run: |
(cd build/xcode && DESTDIR=$PWD/Install-default cmake --install .)
(cd build/xcode && DESTDIR=$PWD/Install-debug cmake --install . --config Debug)
(cd build/xcode && DESTDIR=$PWD/Install-release cmake --install . --config Release)
ls -l build/xcode/Install-*/usr/local/bin/upx
@@ -0,0 +1,76 @@
# Copyright (C) Markus Franz Xaver Johannes Oberhumer
# build with 'cmake -G "NMake Makefiles"'
name: 'Weekly CI - cmake Windows NMake'
on:
schedule: [cron: '30 4 * * 3'] # run weekly Wednesday 04:30 UTC
workflow_dispatch:
env:
CMAKE_REQUIRED_QUIET: OFF
DEBIAN_FRONTEND: noninteractive
jobs:
job-cmake-windows-nmake: # uses cmake + nmake
name: ${{ format('vs{0} {1} {2}', matrix.vsversion, matrix.arch, matrix.clang_cl && 'clang-cl' || '') }}
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
include:
# msvc
- { os: windows-2019, vsversion: 2019, arch: amd64 }
- { os: windows-2019, vsversion: 2019, arch: amd64_arm64 }
- { os: windows-2019, vsversion: 2019, arch: amd64_x86 }
- { os: windows-2022, vsversion: 2022, arch: amd64 }
- { os: windows-2022, vsversion: 2022, arch: amd64_arm64 }
- { os: windows-2022, vsversion: 2022, arch: amd64_x86 }
# clang-cl
- { os: windows-2022, vsversion: 2022, arch: amd64, clang_cl: true }
steps:
- name: 'Check out code'
uses: actions/checkout@v3
with: { submodules: true }
- name: 'Set up Developer Command Prompt'
uses: ilammy/msvc-dev-cmd@v1
with:
vsversion: ${{ matrix.vsversion }}
arch: ${{ matrix.arch }}
- name: 'Build cmake NMake Debug'
shell: cmd
run: |
set X=${{ matrix.clang_cl && '-DCMAKE_C_COMPILER=clang-cl -DCMAKE_CXX_COMPILER=clang-cl' || '' }}
cmake -S . -B build/debug -G "NMake Makefiles" -DCMAKE_VERBOSE_MAKEFILE=ON -DCMAKE_BUILD_TYPE=Debug %X%
cd build/debug
nmake
dir *.exe
- name: 'Build cmake NMake Release'
shell: cmd
run: |
set X=${{ matrix.clang_cl && '-DCMAKE_C_COMPILER=clang-cl -DCMAKE_CXX_COMPILER=clang-cl' || '' }}
cmake -S . -B build/release -G "NMake Makefiles" -DCMAKE_VERBOSE_MAKEFILE=ON %X%
cd build/release
nmake
dir *.exe
- name: 'Make artifact'
shell: bash
run: |
X="${{ matrix.clang_cl && '-clang-cl' || '' }}"
N=$(echo "upx-${GITHUB_REF_NAME}-${GITHUB_SHA:0:7}-weekly-ci-nmake-vs${{ matrix.vsversion }}-${{ matrix.arch }}$X" | sed 's/[^0-9a-zA-Z_.-]/-/g')
mkdir -p "tmp/artifact/$N"
(cd build && cp -ai --parents */upx.exe "../tmp/artifact/$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
- name: 'Run basic tests'
if: ${{ matrix.arch != 'amd64_arm64' }}
run: |
ctest --test-dir build/debug
ctest --test-dir build/release
- name: 'Run install tests'
run: |
env DESTDIR=./Install-debug cmake --install build/debug
env DESTDIR=./Install-release cmake --install build/release
+126
View File
@@ -0,0 +1,126 @@
# Copyright (C) Markus Franz Xaver Johannes Oberhumer
# build with "zig cc"; see https://ziglang.org/download/
name: 'Weekly CI - zigcc'
on:
schedule: [cron: '40 4 * * 3'] # run weekly Wednesday 04:40 UTC
workflow_dispatch:
env:
CMAKE_REQUIRED_QUIET: OFF
DEBIAN_FRONTEND: noninteractive
# 2023-07-30
ZIG_DIST_VERSION: 0.11.0-dev.4320+6f0a613b6
jobs:
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
strategy:
fail-fast: false
matrix:
include:
- { zig_target: aarch64-linux-musl }
- { zig_target: aarch64-linux-musl, zig_pic: -fPIE }
- { zig_target: aarch64-macos-none }
- { zig_target: aarch64-macos.11.0-none }
- { zig_target: aarch64-macos.12.0-none }
- { zig_target: aarch64-macos.13.0-none }
- { zig_target: aarch64-windows-gnu }
- { zig_target: arm-linux-musleabihf }
- { zig_target: arm-linux-musleabihf, zig_pic: -fPIE }
- { zig_target: i386-linux-musl }
- { zig_target: i386-windows-gnu }
- { zig_target: mips-linux-musl }
- { zig_target: mipsel-linux-musl }
- { zig_target: powerpc-linux-musl }
- { zig_target: powerpc64-linux-musl }
- { zig_target: powerpc64le-linux-musl }
- { zig_target: x86_64-linux-musl }
- { zig_target: x86_64-linux-musl, zig_pic: -fPIE }
- { zig_target: x86_64-macos-none }
- { zig_target: x86_64-macos.11.0-none }
- { zig_target: x86_64-macos.12.0-none }
- { zig_target: x86_64-macos.13.0-none }
- { zig_target: x86_64-windows-gnu }
env:
# 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=$(echo "upx-${GITHUB_REF_NAME}-${GITHUB_SHA:0:7}-weekly-ci-zigcc-${{ matrix.zig_target }}${ZIG_PIC}" | sed 's/[^0-9a-zA-Z_.-]/-/g')
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
- name: 'Run install tests'
if: ${{ contains(matrix.zig_target, '-linux') }}
run: |
(cd build/zig/${ZIG_TARGET}${ZIG_PIC}/release && DESTDIR=$PWD/Install-with-cmake cmake --install .)
(cd build/zig/${ZIG_TARGET}${ZIG_PIC}/release && DESTDIR=$PWD/Install-with-make make install)
# vim:set ts=2 sw=2 et:
+12
View File
@@ -1,6 +1,7 @@
/.hg* /.hg*
/.vscode* /.vscode*
/Makevars.global* /Makevars.global*
/Testing*
/build* /build*
/maint* /maint*
/vendor* /vendor*
@@ -8,21 +9,32 @@
GNUmakefile GNUmakefile
MMakefile MMakefile
Makevars.local* Makevars.local*
compile_flags.txt
Tmp*
tmp* tmp*
*.a *.a
*.bz2
*.d *.d
*.dll *.dll
*.dylib
*.exe *.exe
*.gz
*.lib *.lib
*.map *.map
*.o *.o
*.obj *.obj
*.out *.out
*.patch
*.py[cdo] *.py[cdo]
*.rar
*.so *.so
*.swp *.swp
*.tmp
*.ttp *.ttp
*.xz
*.zip
*.zst
doc/*.man doc/*.man
doc/*.ps doc/*.ps
+308 -121
View File
@@ -1,21 +1,37 @@
cmake_minimum_required(VERSION 3.8.0 FATAL_ERROR) #
# UPX "CMake" build file; see https://cmake.org/
# Copyright (C) Markus Franz Xaver Johannes Oberhumer
#
# Build requirements:
# A C++ compiler that fully implements 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)
# CMake version check; using a somewhat current CMake version is highly recommended
if(DEFINED UPX_CONFIG_CMAKE_MINIMUM_REQUIRED_VERSION)
cmake_minimum_required(VERSION "${UPX_CONFIG_CMAKE_MINIMUM_REQUIRED_VERSION}" FATAL_ERROR)
else()
cmake_minimum_required(VERSION 3.8.0 FATAL_ERROR) # CMake >= 3.8 is needed for CXX_STANDARD 17
endif()
# compilation config options # compilation config options
if(NOT IS_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/.git") if(NOT IS_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/.git")
# permissive config defaults when building from source code tarball # 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_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_SANITIZE "Do not compile with default sanitize options." ON)
option(UPX_CONFIG_DISABLE_WSTRICT "Do not compile with strict compiler warnings." ON)
option(UPX_CONFIG_DISABLE_WERROR "Do not compile with default -Werror option." ON) option(UPX_CONFIG_DISABLE_WERROR "Do not compile with default -Werror option." ON)
else() else()
# strict config defaults for devel builds # strict config defaults for Git developer builds
message(STATUS "===== UPX info: strict config defaults enabled") 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_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_SANITIZE "Do not compile with default sanitize options." OFF)
option(UPX_CONFIG_DISABLE_WSTRICT "Do not compile with strict compiler warnings." OFF)
option(UPX_CONFIG_DISABLE_WERROR "Do not compile with default -Werror option." OFF) option(UPX_CONFIG_DISABLE_WERROR "Do not compile with default -Werror option." OFF)
endif() endif()
# test config options (see below) # 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) option(UPX_CONFIG_DISABLE_SELF_PACK_TEST "Do not test packing UPX with itself" OFF)
#*********************************************************************** #***********************************************************************
@@ -24,23 +40,65 @@ option(UPX_CONFIG_DISABLE_SELF_PACK_TEST "Do not test packing UPX with itself" O
# Disallow in-source builds. Note that you will still have to manually # Disallow in-source builds. Note that you will still have to manually
# clean up a few files if you accidentally try an in-source build. # clean up a few files if you accidentally try an in-source build.
if(NOT MSVC_IDE) if(IS_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/.git")
set(CMAKE_DISABLE_IN_SOURCE_BUILD ON) set(CMAKE_DISABLE_IN_SOURCE_BUILD ON)
set(CMAKE_DISABLE_SOURCE_CHANGES ON) set(CMAKE_DISABLE_SOURCE_CHANGES ON)
if(",${CMAKE_CURRENT_SOURCE_DIR}," STREQUAL ",${CMAKE_CURRENT_BINARY_DIR},") 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.") message(FATAL_ERROR "ERROR: In-source builds are not allowed, please use an extra build dir.")
endif() endif()
endif() endif()
set(CMAKE_C_STANDARD_REQUIRED ON)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
# determine git revision # useful for CI jobs: allow settings via environment and cache result
function(upx_cache_bool_vars)
set(default_value "${ARGV0}")
list(REMOVE_AT ARGV 0)
foreach(var ${ARGV})
set(value ${default_value})
if(DEFINED UPX_CACHE_${var})
set(value "${UPX_CACHE_${var}}")
elseif(DEFINED ${var})
set(value "${${var}}")
elseif("$ENV{${var}}" MATCHES "^(0|1|OFF|ON|FALSE|TRUE)$")
set(value "$ENV{${var}}")
set(UPX_CACHE_ORIGIN_FROM_ENV_${var} TRUE CACHE INTERNAL "" FORCE)
endif()
if(value)
set(value ON)
else()
set(value OFF)
endif()
if(UPX_CACHE_ORIGIN_FROM_ENV_${var})
message(STATUS "setting from environment: ${var} = ${value}")
endif()
set(${var} "${value}" PARENT_SCOPE)
set(UPX_CACHE_${var} "${value}" CACHE INTERNAL "" FORCE)
endforeach()
endfunction()
# global settings
if(${CMAKE_VERSION} VERSION_GREATER "3.14.7" AND NOT DEFINED CMAKE_MSVC_RUNTIME_LIBRARY)
set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded")
cmake_policy(SET CMP0091 NEW)
endif()
# global CMake settings that default to ON
upx_cache_bool_vars(ON
CMAKE_C_STANDARD_REQUIRED CMAKE_CXX_STANDARD_REQUIRED
CMAKE_EXPORT_COMPILE_COMMANDS CMAKE_REQUIRED_QUIET
)
# internal UPX settings that default to OFF
upx_cache_bool_vars(OFF
UPX_CONFIG_CMAKE_DISABLE_TEST UPX_CONFIG_CMAKE_DISABLE_INSTALL
UPX_CONFIG_CMAKE_DISABLE_PRINT_INFO UPX_CONFIG_CMAKE_DISABLE_PLATFORM_CHECK
UPX_CONFIG_DISABLE_C_STANDARD UPX_CONFIG_DISABLE_CXX_STANDARD
)
# determine Git revision
set(GITREV_SHORT "") set(GITREV_SHORT "")
set(GITREV_PLUS "") set(GITREV_PLUS "")
set(GIT_DESCRIBE "") set(GIT_DESCRIBE "")
find_package(Git) if(IS_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/.git" AND NOT UPX_CONFIG_DISABLE_GITREV)
if(Git_FOUND AND NOT UPX_CONFIG_DISABLE_GITREV) find_package(Git)
if(Git_FOUND)
execute_process( execute_process(
COMMAND "${GIT_EXECUTABLE}" rev-parse --short=12 HEAD COMMAND "${GIT_EXECUTABLE}" rev-parse --short=12 HEAD
RESULT_VARIABLE result ERROR_QUIET RESULT_VARIABLE result ERROR_QUIET
@@ -63,9 +121,7 @@ if(Git_FOUND AND NOT UPX_CONFIG_DISABLE_GITREV)
if(GIT_DESCRIBE MATCHES "^v?([0-9]+\\.[0-9]+\\.[0-9]+)-([0-9]+)-g(.+)$") 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}") set(GIT_DESCRIBE "${CMAKE_MATCH_1}-devel.${CMAKE_MATCH_2}+git-${CMAKE_MATCH_3}")
endif() endif()
endif() endif()
if(NOT IS_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/.git") # extra check
set(GITREV_SHORT "")
endif() endif()
if(GITREV_SHORT) if(GITREV_SHORT)
message(STATUS "UPX_VERSION_GITREV = \"${GITREV_SHORT}${GITREV_PLUS}\"") message(STATUS "UPX_VERSION_GITREV = \"${GITREV_SHORT}${GITREV_PLUS}\"")
@@ -78,153 +134,266 @@ else()
message(STATUS "UPX_VERSION_GITREV: not set") message(STATUS "UPX_VERSION_GITREV: not set")
endif() endif()
# CMake init # set the default build type to "Release"
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) get_property(is_multi_config GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG)
if(NOT is_multi_config AND NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE "Release" CACHE STRING "Choose the type of build." FORCE)
endif()
# CMake init
project(upx VERSION 4.1.0 LANGUAGES C CXX)
# set the default multi-config build type to "Release"
if(is_multi_config) if(is_multi_config)
set(c "${CMAKE_CONFIGURATION_TYPES}") set(c "${CMAKE_CONFIGURATION_TYPES}")
list(INSERT c 0 "Release") list(INSERT c 0 "Release")
list(INSERT c 1 "Debug") list(INSERT c 1 "Debug")
if (CMAKE_BUILD_TYPE) if(CMAKE_BUILD_TYPE)
list(INSERT c 0 "${CMAKE_BUILD_TYPE}") list(INSERT c 0 "${CMAKE_BUILD_TYPE}")
endif() endif()
list(REMOVE_DUPLICATES c) list(REMOVE_DUPLICATES c)
set(CMAKE_CONFIGURATION_TYPES "${c}" CACHE STRING "List of supported configuration types." FORCE) set(CMAKE_CONFIGURATION_TYPES "${c}" CACHE STRING "List of supported configuration types." FORCE)
elseif(NOT CMAKE_BUILD_TYPE) endif()
set(CMAKE_BUILD_TYPE "Release" CACHE STRING "Choose the type of build." FORCE)
# set MSVC_FRONTEND
set(MSVC_FRONTEND 0)
if(MSVC OR CMAKE_C_COMPILER_FRONTEND_VARIANT MATCHES "^MSVC")
set(MSVC_FRONTEND 1)
endif() endif()
#*********************************************************************** #***********************************************************************
# targets and compilation flags # common compilation flags
#*********************************************************************** #***********************************************************************
#find_package(Threads) # multithreading is currently not used; maybe in UPX version 5 include(CheckCCompilerFlag)
set(UPX_CONFIG_DISABLE_ZSTD ON) # zstd is currently not used; maybe in UPX version 5
file(GLOB ucl_SOURCES "vendor/ucl/src/*.c") if(UPX_CONFIG_DISABLE_WSTRICT)
list(SORT ucl_SOURCES) # enable all basic warnings
add_library(upx_vendor_ucl STATIC ${ucl_SOURCES}) set(warn_Wall -Wall)
set_property(TARGET upx_vendor_ucl PROPERTY C_STANDARD 11) set(warn_WN -W3)
else()
file(GLOB zlib_SOURCES "vendor/zlib/*.c") # enable all basic warnings, and enable lots of strict warnings
list(SORT zlib_SOURCES) set(warn_Wall -Wall -Wextra -Wcast-align -Wcast-qual -Wmissing-declarations -Wpointer-arith -Wshadow -Wvla -Wwrite-strings)
add_library(upx_vendor_zlib STATIC ${zlib_SOURCES}) set(warn_WN -W4)
set_property(TARGET upx_vendor_zlib PROPERTY C_STANDARD 11)
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})
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() endif()
if(UPX_CONFIG_DISABLE_WERROR) if(UPX_CONFIG_DISABLE_WERROR)
# warnings are just warnings
set(warn_Werror "") set(warn_Werror "")
set(warn_WX "") set(warn_WX "")
else() else()
# warnings are fatal errors; annoy developers to keep the source code warning-free
set(warn_Werror -Werror) set(warn_Werror -Werror)
set(warn_WX -WX) set(warn_WX -WX)
endif() endif()
if(NOT MSVC) function(upx_add_definitions_with_prefix)
set(flag_prefix "${ARGV0}")
if(flag_prefix MATCHES "^dummy$") # need dummy to work around bug in old CMake versions
set(flag_prefix "")
endif()
list(REMOVE_AT ARGV 0)
set(failed "")
foreach(f ${ARGV})
set(flag "${flag_prefix}${f}")
string(REGEX REPLACE "[^0-9a-zA-Z_]" "_" cache_var "HAVE_CFLAG_${flag}")
check_c_compiler_flag("${flag}" ${cache_var})
if(${cache_var})
#message(STATUS "add_definitions: ${flag}")
add_definitions("${flag}")
else()
list(APPEND failed "${f}")
endif()
endforeach()
set(failed_flags "${failed}" PARENT_SCOPE) # return value
endfunction()
function(upx_add_definitions)
set(failed_flags "")
if(MSVC_FRONTEND AND CMAKE_C_COMPILER_ID MATCHES "Clang")
# for clang-cl try "-clang:" flag prefix first
upx_add_definitions_with_prefix("-clang:" ${ARGV})
upx_add_definitions_with_prefix("dummy" ${failed_flags})
else()
upx_add_definitions_with_prefix("dummy" ${ARGV})
endif()
endfunction()
if(NOT CMAKE_C_COMPILER_ID MATCHES "^MSVC")
# use -O2 instead of -O3 to reduce code size # use -O2 instead of -O3 to reduce code size
string(REGEX REPLACE "(^| )-O3( |$$)" "\\1-O2\\2" a "${CMAKE_C_FLAGS_RELEASE}") string(REGEX REPLACE "(^| )-O3( |$$)" "\\1-O2\\2" a "${CMAKE_C_FLAGS_RELEASE}")
string(REGEX REPLACE "(^| )-O3( |$$)" "\\1-O2\\2" b "${CMAKE_CXX_FLAGS_RELEASE}") string(REGEX REPLACE "(^| )-O3( |$$)" "\\1-O2\\2" b "${CMAKE_CXX_FLAGS_RELEASE}")
set(CMAKE_C_FLAGS_RELEASE "${a}" CACHE STRING "Flags used by the C compiler during RELEASE builds." FORCE) set(CMAKE_C_FLAGS_RELEASE "${a}" CACHE STRING "Flags used by the C compiler during RELEASE builds." FORCE)
set(CMAKE_CXX_FLAGS_RELEASE "${b}" CACHE STRING "Flags used by the CXX compiler during RELEASE builds." FORCE) set(CMAKE_CXX_FLAGS_RELEASE "${b}" CACHE STRING "Flags used by the CXX compiler during RELEASE builds." FORCE)
endif() endif()
if(MSVC_FRONTEND)
if(MSVC)
# disable silly warnings about using "deprecated" POSIX functions like fopen() # disable silly warnings about using "deprecated" POSIX functions like fopen()
add_definitions(-D_CRT_NONSTDC_NO_DEPRECATE) add_definitions(-D_CRT_NONSTDC_NO_DEPRECATE)
add_definitions(-D_CRT_NONSTDC_NO_WARNINGS) add_definitions(-D_CRT_NONSTDC_NO_WARNINGS)
add_definitions(-D_CRT_SECURE_NO_DEPRECATE) add_definitions(-D_CRT_SECURE_NO_DEPRECATE)
add_definitions(-D_CRT_SECURE_NO_WARNINGS) add_definitions(-D_CRT_SECURE_NO_WARNINGS)
# set __cplusplus according to selected C++ standard; use new preprocessor # use -funsigned-char; set __cplusplus according to selected C++ standard
add_definitions(-Zc:__cplusplus -Zc:preprocessor) add_definitions(-J -Zc:__cplusplus)
else() if(CMAKE_C_COMPILER_ID MATCHES "^MSVC")
# protect against security threats caused by misguided compiler "optimizations" upx_add_definitions(-Zc:preprocessor) # use new preprocessor
if (CMAKE_C_COMPILER_ID STREQUAL "GNU")
add_definitions(-fno-delete-null-pointer-checks -fno-lifetime-dse)
endif() endif()
add_definitions(-fno-strict-aliasing -fno-strict-overflow -funsigned-char) endif()
if(NOT CMAKE_C_COMPILER_ID MATCHES "^MSVC")
# protect against security threats caused by misguided compiler "optimizations"
upx_add_definitions(-fno-delete-null-pointer-checks -fno-lifetime-dse)
upx_add_definitions(-fno-strict-aliasing -fno-strict-overflow -funsigned-char)
# disable overambitious auto-vectorization until this actually gains something # disable overambitious auto-vectorization until this actually gains something
add_definitions(-fno-tree-vectorize) upx_add_definitions(-fno-tree-vectorize)
# disable annoying clang warnings which get added by the macOS Xcode cmake generator
if(CMAKE_GENERATOR MATCHES "Xcode")
upx_add_definitions(-Wno-shorten-64-to-32)
endif()
endif() endif()
# compile a target with -O2 in Debug build # compile a target with -O2 even in Debug build
function(upx_compile_target_debug_with_O2 t) function(upx_compile_target_debug_with_O2)
if(MSVC) foreach(t ${ARGV})
# msvc uses some Debug compile options like -RTC1 that are incompatible with -O2 if(MSVC_FRONTEND)
# MSVC uses some Debug compilation options like -RTC1 that are incompatible with -O2
else() else()
target_compile_options(${t} PRIVATE $<$<CONFIG:Debug>:-O2>) target_compile_options(${t} PRIVATE $<$<CONFIG:Debug>:-O2>)
endif() endif()
endforeach()
endfunction() endfunction()
function(upx_sanitize_target t) # sanitize a target
if(NOT UPX_CONFIG_DISABLE_SANITIZE AND NOT MSVC) function(upx_sanitize_target)
if(CMAKE_C_PLATFORM_ID MATCHES "^MinGW" OR MINGW OR CYGWIN) foreach(t ${ARGV})
if(UPX_CONFIG_DISABLE_SANITIZE)
# no-op
elseif(MSVC_FRONTEND)
# MSVC uses -GS (similar to -fstack-protector) by default
elseif(CMAKE_C_PLATFORM_ID MATCHES "^MinGW" OR MINGW OR CYGWIN)
# avoid link errors with current MinGW-w64 versions # avoid link errors with current MinGW-w64 versions
# see https://www.mingw-w64.org/contribute/#sanitizers-asan-tsan-usan # see https://www.mingw-w64.org/contribute/#sanitizers-asan-tsan-usan
else() else()
# default sanitizer for Debug builds # default sanitizer for Debug builds
target_compile_options(${t} PRIVATE $<$<CONFIG:Debug>:-fsanitize=undefined -fsanitize-undefined-trap-on-error -fstack-protector-all>) target_compile_options(${t} PRIVATE $<$<CONFIG:Debug>:-fsanitize=undefined -fsanitize-undefined-trap-on-error -fstack-protector-all>)
# default sanitizer for Release builds # default sanitizer for Release builds
target_compile_options(${t} PRIVATE $<$<CONFIG:MinSizeRel>:-fstack-protector>)
target_compile_options(${t} PRIVATE $<$<CONFIG:Release>:-fstack-protector>) target_compile_options(${t} PRIVATE $<$<CONFIG:Release>:-fstack-protector>)
target_compile_options(${t} PRIVATE $<$<CONFIG:RelWithDebInfo>:-fstack-protector>)
endif() endif()
endif() endforeach()
endfunction() endfunction()
#***********************************************************************
# targets
#***********************************************************************
# internal settings
set(UPX_CONFIG_DISABLE_THREADS ON) # multithreading is currently not used; maybe in UPX version 5
set(UPX_CONFIG_DISABLE_BZIP2 ON) # bzip2 is currently not used; we might need it to decompress linux kernels
set(UPX_CONFIG_DISABLE_ZSTD ON) # zstd is currently not used; maybe in UPX version 5
if(NOT UPX_CONFIG_DISABLE_THREADS)
find_package(Threads)
endif()
if(NOT UPX_CONFIG_DISABLE_BZIP2)
file(GLOB bzip2_SOURCES "vendor/bzip2/*.c")
list(SORT bzip2_SOURCES)
add_library(upx_vendor_bzip2 STATIC ${bzip2_SOURCES})
if(NOT UPX_CONFIG_DISABLE_C_STANDARD)
set_property(TARGET upx_vendor_bzip2 PROPERTY C_STANDARD 11)
endif()
endif() # UPX_CONFIG_DISABLE_BZIP2
file(GLOB ucl_SOURCES "vendor/ucl/src/*.c")
list(SORT ucl_SOURCES)
add_library(upx_vendor_ucl STATIC ${ucl_SOURCES})
if(NOT UPX_CONFIG_DISABLE_C_STANDARD)
set_property(TARGET upx_vendor_ucl PROPERTY C_STANDARD 11)
endif()
file(GLOB zlib_SOURCES "vendor/zlib/*.c")
list(SORT zlib_SOURCES)
add_library(upx_vendor_zlib STATIC ${zlib_SOURCES})
if(NOT UPX_CONFIG_DISABLE_C_STANDARD)
set_property(TARGET upx_vendor_zlib PROPERTY C_STANDARD 11)
endif()
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})
if(NOT UPX_CONFIG_DISABLE_C_STANDARD)
set_property(TARGET upx_vendor_zstd PROPERTY C_STANDARD 11)
endif()
endif() # UPX_CONFIG_DISABLE_ZSTD
file(GLOB upx_SOURCES "src/*.cpp" "src/[cfu]*/*.cpp")
list(SORT upx_SOURCES)
add_executable(upx ${upx_SOURCES})
if(NOT UPX_CONFIG_DISABLE_CXX_STANDARD)
set_property(TARGET upx PROPERTY CXX_STANDARD 17)
endif()
target_link_libraries(upx upx_vendor_ucl upx_vendor_zlib)
if(NOT UPX_CONFIG_DISABLE_BZIP2)
target_link_libraries(upx upx_vendor_bzip2)
endif()
if(NOT UPX_CONFIG_DISABLE_ZSTD)
target_link_libraries(upx upx_vendor_zstd)
endif()
if(Threads_FOUND)
target_link_libraries(upx Threads::Threads)
endif()
#***********************************************************************
# target compilation flags
#***********************************************************************
if(NOT UPX_CONFIG_DISABLE_BZIP2)
set(t upx_vendor_bzip2)
upx_compile_target_debug_with_O2(${t})
upx_sanitize_target(${t})
if(MSVC_FRONTEND)
target_compile_options(${t} PRIVATE ${warn_WN} -wd4127 -wd4244 -wd4267 ${warn_WX})
else()
target_compile_options(${t} PRIVATE ${warn_Wall} -Wno-implicit-fallthrough ${warn_Werror})
endif()
endif() # UPX_CONFIG_DISABLE_BZIP2
set(t upx_vendor_ucl) set(t upx_vendor_ucl)
target_include_directories(${t} PRIVATE vendor/ucl/include vendor/ucl) target_include_directories(${t} PRIVATE vendor/ucl/include vendor/ucl)
upx_compile_target_debug_with_O2(${t}) upx_compile_target_debug_with_O2(${t})
upx_sanitize_target(${t}) upx_sanitize_target(${t})
if(MSVC) if(MSVC_FRONTEND)
target_compile_options(${t} PRIVATE -J -W4 ${warn_WX}) target_compile_options(${t} PRIVATE ${warn_WN} ${warn_WX})
else() else()
target_compile_options(${t} PRIVATE ${warn_strict} ${warn_Werror}) target_compile_options(${t} PRIVATE ${warn_Wall} ${warn_Werror})
endif() endif()
set(t upx_vendor_zlib) set(t upx_vendor_zlib)
upx_compile_target_debug_with_O2(${t}) upx_compile_target_debug_with_O2(${t})
upx_sanitize_target(${t}) upx_sanitize_target(${t})
if(MSVC) target_compile_definitions(${t} PRIVATE HAVE_VSNPRINTF=1)
target_compile_options(${t} PRIVATE -DHAVE_STDARG_H -DHAVE_VSNPRINTF -J -W3 ${warn_WX}) if(MSVC_FRONTEND)
target_compile_options(${t} PRIVATE -W3 ${warn_WX})
else() else()
target_compile_options(${t} PRIVATE -DHAVE_STDARG_H -DHAVE_UNISTD_H -DHAVE_VSNPRINTF) target_compile_definitions(${t} PRIVATE HAVE_UNISTD_H=1)
# clang-15: -Wno-strict-prototypes is needed to silence the new -Wdeprecated-non-prototype warning target_compile_options(${t} PRIVATE -Wall ${warn_Werror})
target_compile_options(${t} PRIVATE -Wall -Wextra -Wvla -Wno-strict-prototypes ${warn_Werror}) ##target_compile_options(${t} PRIVATE ${warn_Wall} -Wno-cast-align -Wno-cast-qual ${warn_Werror})
endif() endif()
if(NOT UPX_CONFIG_DISABLE_ZSTD) if(NOT UPX_CONFIG_DISABLE_ZSTD)
set(t upx_vendor_zstd) set(t upx_vendor_zstd)
upx_compile_target_debug_with_O2(${t}) upx_compile_target_debug_with_O2(${t})
upx_sanitize_target(${t}) upx_sanitize_target(${t})
target_compile_options(${t} PRIVATE -DDYNAMIC_BMI2=0 -DZSTD_DISABLE_ASM) target_compile_definitions(${t} PRIVATE DYNAMIC_BMI2=0 ZSTD_DISABLE_ASM=1)
if(MSVC) if(MSVC_FRONTEND)
target_compile_options(${t} PRIVATE -J -W4 ${warn_WX}) target_compile_options(${t} PRIVATE ${warn_WN} ${warn_WX})
else() else()
target_compile_options(${t} PRIVATE ${warn_strict} ${warn_Werror}) target_compile_options(${t} PRIVATE ${warn_Wall} ${warn_Werror})
endif()
endif() endif()
endif() # UPX_CONFIG_DISABLE_ZSTD
set(t upx) set(t upx)
target_include_directories(${t} PRIVATE vendor vendor/boost-pfr/include) target_include_directories(${t} PRIVATE vendor)
target_compile_definitions(${t} PRIVATE $<$<CONFIG:Debug>:DEBUG=1>) target_compile_definitions(${t} PRIVATE $<$<CONFIG:Debug>:DEBUG=1>)
if(GITREV_SHORT) if(GITREV_SHORT)
target_compile_definitions(${t} PRIVATE UPX_VERSION_GITREV="${GITREV_SHORT}${GITREV_PLUS}") target_compile_definitions(${t} PRIVATE UPX_VERSION_GITREV="${GITREV_SHORT}${GITREV_PLUS}")
@@ -232,22 +401,33 @@ if(GITREV_SHORT)
target_compile_definitions(${t} PRIVATE UPX_VERSION_GIT_DESCRIBE="${GIT_DESCRIBE}") target_compile_definitions(${t} PRIVATE UPX_VERSION_GIT_DESCRIBE="${GIT_DESCRIBE}")
endif() endif()
endif() endif()
#upx_compile_target_debug_with_O2(${t}) if(Threads_FOUND)
upx_sanitize_target(${t}) target_compile_definitions(${t} PRIVATE WITH_THREADS=1)
if(MSVC) endif()
target_compile_options(${t} PRIVATE -EHsc -J -W4 ${warn_WX}) if(NOT UPX_CONFIG_DISABLE_WSTRICT)
else() target_compile_definitions(${t} PRIVATE UPX_CONFIG_DISABLE_WSTRICT=0)
target_compile_options(${t} PRIVATE ${warn_strict} ${warn_Werror}) endif()
if(NOT UPX_CONFIG_DISABLE_WERROR)
target_compile_definitions(${t} PRIVATE UPX_CONFIG_DISABLE_WERROR=0)
endif()
if(NOT UPX_CONFIG_DISABLE_BZIP2)
target_compile_definitions(${t} PRIVATE WITH_BZIP2=0) # FIXME TODO
endif() endif()
if(NOT UPX_CONFIG_DISABLE_ZSTD) if(NOT UPX_CONFIG_DISABLE_ZSTD)
target_compile_definitions(${t} PRIVATE WITH_ZSTD=1) target_compile_definitions(${t} PRIVATE WITH_ZSTD=1)
target_link_libraries(upx upx_vendor_zstd) endif()
#upx_compile_target_debug_with_O2(${t})
upx_sanitize_target(${t})
if(MSVC_FRONTEND)
target_compile_options(${t} PRIVATE -EHsc ${warn_WN} ${warn_WX})
else()
target_compile_options(${t} PRIVATE ${warn_Wall} ${warn_Werror})
endif() endif()
#*********************************************************************** #***********************************************************************
# "ctest" # ctest
# "make test" # make test
# "ninja test" # ninja test
#*********************************************************************** #***********************************************************************
if(NOT UPX_CONFIG_CMAKE_DISABLE_TEST) if(NOT UPX_CONFIG_CMAKE_DISABLE_TEST)
@@ -258,21 +438,21 @@ if(NOT CMAKE_CROSSCOMPILING)
add_test(NAME upx-help COMMAND upx --help) add_test(NAME upx-help COMMAND upx --help)
endif() endif()
if(NOT CMAKE_CROSSCOMPILING AND NOT UPX_CONFIG_DISABLE_SELF_PACK_TEST) 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) function(upx_add_test)
set(name ${ARGV0}) set(name "${ARGV0}")
list(REMOVE_AT ARGV 0) list(REMOVE_AT ARGV 0)
add_test(NAME ${name} COMMAND ${ARGV}) add_test(NAME "${name}" COMMAND ${ARGV})
set_tests_properties(${name} PROPERTIES RUN_SERIAL TRUE) # run these tests sequentially set_tests_properties("${name}" PROPERTIES RUN_SERIAL TRUE) # run these tests sequentially
endfunction() endfunction()
set(exe ${CMAKE_EXECUTABLE_SUFFIX}) set(exe ${CMAKE_EXECUTABLE_SUFFIX})
set(upx_self_exe "$<TARGET_FILE:upx>") set(upx_self_exe "$<TARGET_FILE:upx>")
set(fo "--force-overwrite") 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 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-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-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-n2e upx -3 --nrv2e "${upx_self_exe}" ${fo} -o upx-packed-n2e${exe})
upx_add_test(upx-self-pack-lzma upx -3 --lzma ${upx_self_exe} ${fo} -o upx-packed-lzma${exe}) upx_add_test(upx-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-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-fileinfo upx --fileinfo upx-packed${exe} upx-packed-n2b${exe} upx-packed-n2d${exe} upx-packed-n2e${exe} upx-packed-lzma${exe})
upx_add_test(upx-test upx -t upx-packed${exe} upx-packed-n2b${exe} upx-packed-n2d${exe} upx-packed-n2e${exe} upx-packed-lzma${exe}) upx_add_test(upx-test upx -t upx-packed${exe} upx-packed-n2b${exe} upx-packed-n2d${exe} upx-packed-n2e${exe} upx-packed-lzma${exe})
@@ -284,17 +464,17 @@ endif()
endif() # UPX_CONFIG_CMAKE_DISABLE_TEST endif() # UPX_CONFIG_CMAKE_DISABLE_TEST
#*********************************************************************** #***********************************************************************
# "cmake --install ." # cmake --install .
# "make install" # make install
# "ninja install" # ninja install
#*********************************************************************** #***********************************************************************
if(NOT UPX_CONFIG_CMAKE_DISABLE_INSTALL) if(NOT UPX_CONFIG_CMAKE_DISABLE_INSTALL)
# installation prefix and directories # installation prefix and directories
if(NOT CMAKE_INSTALL_PREFIX) if(NOT CMAKE_INSTALL_PREFIX)
#message(FATAL_ERROR "ERROR: CMAKE_INSTALL_PREFIX is not defined.") #message(FATAL_ERROR "ERROR: CMAKE_INSTALL_PREFIX is not defined")
message(WARNING "WARNING: CMAKE_INSTALL_PREFIX is not defined.") message(WARNING "WARNING: CMAKE_INSTALL_PREFIX is not defined")
endif() endif()
if(CMAKE_INSTALL_PREFIX) if(CMAKE_INSTALL_PREFIX)
include(GNUInstallDirs) include(GNUInstallDirs)
@@ -302,7 +482,7 @@ endif()
if(CMAKE_INSTALL_PREFIX AND DEFINED CMAKE_INSTALL_FULL_BINDIR) if(CMAKE_INSTALL_PREFIX AND DEFINED CMAKE_INSTALL_FULL_BINDIR)
install(TARGETS upx DESTINATION "${CMAKE_INSTALL_FULL_BINDIR}") install(TARGETS upx DESTINATION "${CMAKE_INSTALL_FULL_BINDIR}")
install(FILES install(FILES
COPYING LICENSE NEWS README THANKS doc/upx-doc.html doc/upx-doc.txt COPYING LICENSE NEWS README doc/THANKS.txt doc/upx-doc.html doc/upx-doc.txt
DESTINATION "${CMAKE_INSTALL_FULL_DOCDIR}" DESTINATION "${CMAKE_INSTALL_FULL_DOCDIR}"
) )
install(FILES doc/upx.1 DESTINATION "${CMAKE_INSTALL_FULL_MANDIR}/man1") install(FILES doc/upx.1 DESTINATION "${CMAKE_INSTALL_FULL_MANDIR}/man1")
@@ -314,36 +494,43 @@ endif() # UPX_CONFIG_CMAKE_DISABLE_INSTALL
# finally print some info about the build configuration # finally print some info about the build configuration
#*********************************************************************** #***********************************************************************
function(print_var)
foreach(var ${ARGV})
if(${var})
message(STATUS "${var} = ${${var}}")
endif()
endforeach()
endfunction()
if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/maint/make/CMakeLists.maint.txt") if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/maint/make/CMakeLists.maint.txt")
include("${CMAKE_CURRENT_SOURCE_DIR}/maint/make/CMakeLists.maint.txt") include("${CMAKE_CURRENT_SOURCE_DIR}/maint/make/CMakeLists.maint.txt")
endif() endif()
function(print_var) print_var(CMAKE_VERSION UPX_CONFIG_CMAKE_MINIMUM_REQUIRED_VERSION CMAKE_GENERATOR)
foreach(v ${ARGV})
if(${v})
message(STATUS "${v} = ${${v}}")
endif()
endforeach()
endfunction()
if(NOT UPX_CONFIG_CMAKE_DISABLE_PRINT_INFO) if(NOT UPX_CONFIG_CMAKE_DISABLE_PRINT_INFO)
print_var(CMAKE_HOST_SYSTEM_NAME CMAKE_HOST_SYSTEM_VERSION) print_var(CMAKE_HOST_SYSTEM_NAME CMAKE_HOST_SYSTEM_VERSION)
print_var(CMAKE_SYSTEM_NAME CMAKE_SYSTEM_VERSION CMAKE_CROSSCOMPILING) 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_C_COMPILER_ID CMAKE_C_COMPILER_VERSION CMAKE_C_COMPILER_FRONTEND_VARIANT 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) print_var(CMAKE_CXX_COMPILER_ID CMAKE_CXX_COMPILER_VERSION CMAKE_CXX_COMPILER_FRONTEND_VARIANT CMAKE_CXX_COMPILER_ARCHITECTURE_ID CMAKE_CXX_PLATFORM_ID CMAKE_CXX_COMPILER_ABI)
print_var(CMAKE_POSITION_INDEPENDENT_CODE)
print_var(CYGWIN GNUC MINGW MSVC MSVC_FRONTEND MSVC_IDE WIN32 WIN64)
endif() # UPX_CONFIG_CMAKE_DISABLE_PRINT_INFO endif() # UPX_CONFIG_CMAKE_DISABLE_PRINT_INFO
print_var(CMAKE_INSTALL_PREFIX CMAKE_CONFIGURATION_TYPES CMAKE_BUILD_TYPE) print_var(CMAKE_INSTALL_PREFIX CMAKE_CONFIGURATION_TYPES CMAKE_BUILD_TYPE)
if (CMAKE_BUILD_TYPE AND NOT CMAKE_BUILD_TYPE MATCHES "^(Debug|Release)$") if(CMAKE_BUILD_TYPE AND NOT CMAKE_BUILD_TYPE MATCHES "^(Debug|None|Release)$")
message(WARNING "WARNING: unsupported CMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}; please use \"Debug\" or \"Release\"") message(WARNING "WARNING: unsupported CMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}; please use \"Debug\" or \"Release\"")
endif() endif()
if(NOT UPX_CONFIG_CMAKE_DISABLE_PLATFORM_CHECK)
# extra sanity checks to detect incompatible C vs CXX settings # extra sanity checks to detect incompatible C vs CXX settings
if(NOT UPX_CONFIG_CMAKE_DISABLE_PLATFORM_CHECK)
if(NOT ",${CMAKE_C_PLATFORM_ID}," STREQUAL ",${CMAKE_CXX_PLATFORM_ID},") if(NOT ",${CMAKE_C_PLATFORM_ID}," STREQUAL ",${CMAKE_CXX_PLATFORM_ID},")
message(FATAL_ERROR "ERROR: CMAKE_C_PLATFORM_ID CMAKE_CXX_PLATFORM_ID mismatch") message(FATAL_ERROR "ERROR: CMAKE_C_PLATFORM_ID CMAKE_CXX_PLATFORM_ID mismatch")
endif() endif()
if(NOT ",${CMAKE_C_COMPILER_ABI}," STREQUAL ",${CMAKE_CXX_COMPILER_ABI},") if(NOT ",${CMAKE_C_COMPILER_ABI}," STREQUAL ",${CMAKE_CXX_COMPILER_ABI},")
message(FATAL_ERROR "ERROR: CMAKE_C_COMPILER_ABI CMAKE_CXX_COMPILER_ABI mismatch") message(FATAL_ERROR "ERROR: CMAKE_C_COMPILER_ABI CMAKE_CXX_COMPILER_ABI mismatch")
endif() endif()
if(NOT ",${CMAKE_C_COMPILER_FRONTEND_VARIANT}," STREQUAL ",${CMAKE_CXX_COMPILER_FRONTEND_VARIANT},")
message(FATAL_ERROR "ERROR: CMAKE_C_COMPILER_FRONTEND_VARIANT CMAKE_CXX_COMPILER_FRONTEND_VARIANT mismatch")
endif()
endif() # UPX_CONFIG_CMAKE_DISABLE_PLATFORM_CHECK endif() # UPX_CONFIG_CMAKE_DISABLE_PLATFORM_CHECK
# vim:set ft=cmake ts=4 sw=4 tw=0 et: # vim:set ft=cmake ts=4 sw=4 tw=0 et:
+72 -27
View File
@@ -1,10 +1,11 @@
# #
# UPX top-level Makefile - needs GNU make and CMake >= 3.13 # UPX top-level Makefile - needs GNU make and CMake >= 3.13
# Copyright (C) Markus Franz Xaver Johannes Oberhumer
# #
# INFO: this Makefile is just a convenience wrapper for calling CMake # 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: # HINT: if you only have an older CMake 3.x then you can invoke cmake manually like this:
# mkdir -p build/release # mkdir -p build/release
# cd build/release # cd build/release
# cmake ../.. # cmake ../..
@@ -13,7 +14,8 @@
CMAKE = cmake CMAKE = cmake
UPX_CMAKE_BUILD_FLAGS += --parallel UPX_CMAKE_BUILD_FLAGS += --parallel
ifneq ($(VERBOSE),) ifneq ($(VERBOSE),)
UPX_CMAKE_BUILD_FLAGS += --verbose #UPX_CMAKE_BUILD_FLAGS += --verbose # requires CMake >= 3.14
UPX_CMAKE_CONFIG_FLAGS += -DCMAKE_VERBOSE_MAKEFILE=ON
endif endif
# enable this if you prefer Ninja for the actual builds: # enable this if you prefer Ninja for the actual builds:
#UPX_CMAKE_CONFIG_FLAGS += -G Ninja #UPX_CMAKE_CONFIG_FLAGS += -G Ninja
@@ -43,11 +45,14 @@ all: build/debug build/release
debug: build/debug debug: build/debug
release: build/release release: build/release
.PHONY: PHONY
.NOTPARALLEL: # because the actual builds use "cmake --parallel" .NOTPARALLEL: # because the actual builds use "cmake --parallel"
.PHONY: PHONY
.SECONDEXPANSION:
.SUFFIXES: .SUFFIXES:
#
# END of Makefile; extra stuff follows # END of Makefile; extra stuff follows
#
#*********************************************************************** #***********************************************************************
# extra builds: some pre-defined build configurations # extra builds: some pre-defined build configurations
@@ -82,6 +87,12 @@ 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 CC = clang -m64
build/extra/clang-m64/%: export CXX = clang++ -m64 build/extra/clang-m64/%: export CXX = clang++ -m64
# force building with clang/clang++ -static
build/extra/clang-static/debug: PHONY; $(call run_config_and_build,$@,Debug)
build/extra/clang-static/release: PHONY; $(call run_config_and_build,$@,Release)
build/extra/clang-static/%: export CC = clang -static
build/extra/clang-static/%: export CXX = clang++ -static
# force building with gcc/g++ # force building with gcc/g++
build/extra/gcc/debug: PHONY; $(call run_config_and_build,$@,Debug) 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/release: PHONY; $(call run_config_and_build,$@,Release)
@@ -106,49 +117,83 @@ 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 CC = gcc -m64
build/extra/gcc-m64/%: export CXX = g++ -m64 build/extra/gcc-m64/%: export CXX = g++ -m64
# force building with clang Static Analyzer (scan-build) # force building with gcc/g++ -static
build/extra/scan-build/debug: PHONY; $(call run_config_and_build,$@,Debug) build/extra/gcc-static/debug: PHONY; $(call run_config_and_build,$@,Debug)
build/extra/scan-build/release: PHONY; $(call run_config_and_build,$@,Release) build/extra/gcc-static/release: PHONY; $(call run_config_and_build,$@,Release)
build/extra/scan-build/%: CMAKE := scan-build $(CMAKE) build/extra/gcc-static/%: export CC = gcc -static
build/extra/scan-build/%: export CCC_CC ?= clang build/extra/gcc-static/%: export CXX = g++ -static
build/extra/scan-build/%: export CCC_CXX ?= clang++
# cross compiler: Linux glibc aarch64-linux-gnu # cross compiler: Linux glibc aarch64-linux-gnu (arm64)
build/extra/cross-linux-aarch64/debug: PHONY; $(call run_config_and_build,$@,Debug) build/extra/cross-linux-gnu-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-gnu-aarch64/release: PHONY; $(call run_config_and_build,$@,Release)
build/extra/cross-linux-aarch64/%: export CC = aarch64-linux-gnu-gcc build/extra/cross-linux-gnu-aarch64/%: export CC = aarch64-linux-gnu-gcc
build/extra/cross-linux-aarch64/%: export CXX = aarch64-linux-gnu-g++ build/extra/cross-linux-gnu-aarch64/%: export CXX = aarch64-linux-gnu-g++
# cross compiler: Linux glibc arm-linux-gnueabihf # cross compiler: Linux glibc arm-linux-gnueabihf
build/extra/cross-linux-arm/debug: PHONY; $(call run_config_and_build,$@,Debug) build/extra/cross-linux-gnu-arm-eabihf/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-gnu-arm-eabihf/release: PHONY; $(call run_config_and_build,$@,Release)
build/extra/cross-linux-arm/%: export CC = arm-linux-gnueabihf-gcc build/extra/cross-linux-gnu-arm-eabihf/%: export CC = arm-linux-gnueabihf-gcc
build/extra/cross-linux-arm/%: export CXX = arm-linux-gnueabihf-g++ -Wno-psabi build/extra/cross-linux-gnu-arm-eabihf/%: export CXX = arm-linux-gnueabihf-g++ -Wno-psabi
# cross compiler: Windows x86 win32 MinGW # cross compiler: Windows x86 win32 MinGW (i386)
build/extra/cross-windows-mingw32/debug: PHONY; $(call run_config_and_build,$@,Debug) 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/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 CC = i686-w64-mingw32-gcc -static
build/extra/cross-windows-mingw32/%: export CXX = i686-w64-mingw32-g++ build/extra/cross-windows-mingw32/%: export CXX = i686-w64-mingw32-g++ -static
# cross compiler: Windows x64 win64 MinGW # cross compiler: Windows x64 win64 MinGW (amd64)
build/extra/cross-windows-mingw64/debug: PHONY; $(call run_config_and_build,$@,Debug) 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/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 CC = x86_64-w64-mingw32-gcc -static
build/extra/cross-windows-mingw64/%: export CXX = x86_64-w64-mingw32-g++ build/extra/cross-windows-mingw64/%: export CXX = x86_64-w64-mingw32-g++ -static
# cross compiler: macOS arm64 # cross compiler: macOS arm64 (aarch64)
build/extra/cross-darwin-arm64/debug: PHONY; $(call run_config_and_build,$@,Debug) 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/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 CC = clang -target arm64-apple-darwin
build/extra/cross-darwin-arm64/%: export CXX = clang++ -target arm64-apple-darwin build/extra/cross-darwin-arm64/%: export CXX = clang++ -target arm64-apple-darwin
# cross compiler: macOS x86_64 # cross compiler: macOS x86_64 (amd64)
build/extra/cross-darwin-x86_64/debug: PHONY; $(call run_config_and_build,$@,Debug) 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/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 CC = clang -target x86_64-apple-darwin
build/extra/cross-darwin-x86_64/%: export CXX = clang++ -target x86_64-apple-darwin build/extra/cross-darwin-x86_64/%: export CXX = clang++ -target x86_64-apple-darwin
#***********************************************************************
# C/C++ static analyzers
#***********************************************************************
# force building with clang Static Analyzer (scan-build)
build/analyze/clang-analyzer/debug: PHONY; $(call run_config_and_build,$@,Debug)
build/analyze/clang-analyzer/release: PHONY; $(call run_config_and_build,$@,Release)
build/analyze/clang-analyzer/%: CMAKE := scan-build $(CMAKE)
build/analyze/clang-analyzer/%: export CCC_CC ?= clang
build/analyze/clang-analyzer/%: export CCC_CXX ?= clang++
# run clang-tidy: uses file compile_commands.json from an existing clang build
# does not create any actual files, so purely PHONY
RUN_CLANG_TIDY = time python3 ./misc/analyze/clang-tidy/run-clang-tidy.py -p $<
RUN_CLANG_TIDY_WERROR = $(RUN_CLANG_TIDY) '-warnings-as-errors=*'
build/analyze/clang-tidy-upx/debug build/analyze/clang-tidy-upx/release: build/extra/clang/$$(notdir $$@) PHONY
$(RUN_CLANG_TIDY_WERROR) -config-file ./.clang-tidy '/src/.*\.cpp'
build/analyze/clang-tidy-bzip2/debug build/analyze/clang-tidy-bzip2/release: build/extra/clang/$$(notdir $$@) PHONY
$(RUN_CLANG_TIDY) -config-file ./misc/analyze/clang-tidy/clang-tidy-bzip2.yml /vendor/bzip2/
build/analyze/clang-tidy-ucl/debug build/analyze/clang-tidy-ucl/release: build/extra/clang/$$(notdir $$@) PHONY
$(RUN_CLANG_TIDY_WERROR) -config-file ./misc/analyze/clang-tidy/clang-tidy-ucl.yml /vendor/ucl/
build/analyze/clang-tidy-zlib/debug build/analyze/clang-tidy-zlib/release: build/extra/clang/$$(notdir $$@) PHONY
$(RUN_CLANG_TIDY_WERROR) -config-file ./misc/analyze/clang-tidy/clang-tidy-zlib.yml /vendor/zlib/
build/analyze/clang-tidy-zstd/debug build/analyze/clang-tidy-zstd/release: build/extra/clang/$$(notdir $$@) PHONY
$(RUN_CLANG_TIDY) -config-file ./misc/analyze/clang-tidy/clang-tidy-zstd.yml /vendor/zstd/
build/analyze/clang-tidy/debug build/analyze/clang-tidy/release: build/analyze/clang-tidy-upx/$$(notdir $$@)
build/analyze/clang-tidy/debug build/analyze/clang-tidy/release: build/analyze/clang-tidy-bzip2/$$(notdir $$@)
build/analyze/clang-tidy/debug build/analyze/clang-tidy/release: build/analyze/clang-tidy-ucl/$$(notdir $$@)
build/analyze/clang-tidy/debug build/analyze/clang-tidy/release: build/analyze/clang-tidy-zlib/$$(notdir $$@)
build/analyze/clang-tidy/debug build/analyze/clang-tidy/release: build/analyze/clang-tidy-zstd/$$(notdir $$@)
# OLD names
build/extra/scan-build/debug: build/analyze/clang-analyzer/debug
build/extra/scan-build/release: build/analyze/clang-analyzer/release
#*********************************************************************** #***********************************************************************
# advanced: generic extra target # advanced: generic extra target
#*********************************************************************** #***********************************************************************
@@ -183,4 +228,4 @@ endif
SUBMODULES = doctest lzma-sdk ucl valgrind zlib SUBMODULES = doctest lzma-sdk ucl valgrind zlib
dummy := $(foreach m,$(SUBMODULES),$(if $(wildcard vendor/$m/[CL]*),$m,\ dummy := $(foreach m,$(SUBMODULES),$(if $(wildcard vendor/$m/[CL]*),$m,\
$(error ERROR: missing git submodule $m; run 'git submodule update --init'))) $(error ERROR: missing git submodule '$m'; run 'git submodule update --init')))
+12 -9
View File
@@ -2,6 +2,10 @@
User visible changes for UPX User visible changes for UPX
================================================================== ==================================================================
Changes in 4.1.0 (08 Aug 2023):
* ELF: handle shared libraries with more than 2 PT_LOAD segments
* bug fixes - see https://github.com/upx/upx/milestone/11
Changes in 4.0.2 (30 Jan 2023): Changes in 4.0.2 (30 Jan 2023):
* bug fixes - see https://github.com/upx/upx/milestone/9 * bug fixes - see https://github.com/upx/upx/milestone/9
@@ -75,7 +79,7 @@ Changes in 3.08 (12 Dec 2011):
* Compress shared library on ELF i386 only [ld.so threatens even this case]. * Compress shared library on ELF i386 only [ld.so threatens even this case].
* Attempt to support ELF on QNX 6.3.0 for armel (experimental). * Attempt to support ELF on QNX 6.3.0 for armel (experimental).
* Better diagnostic when ELF -fPIC is needed. * Better diagnostic when ELF -fPIC is needed.
* PT_NOTE improvements for *BSD. * PT_NOTE improvements for BSD.
* Preserve more ELF .e_flags on ARM. * Preserve more ELF .e_flags on ARM.
* Minor code improvements for ELF stubs. * Minor code improvements for ELF stubs.
* Defend against another flavor of corrupt PE header. * Defend against another flavor of corrupt PE header.
@@ -149,7 +153,7 @@ Changes in 2.92 beta (23 Jan 2007):
Changes in 2.91 beta (29 Nov 2006): Changes in 2.91 beta (29 Nov 2006):
* assorted bug fixes * assorted bug fixes
* arm/pe: fix "missing" icon & version info resource problem for wince 5 * wince/arm: fix "missing" icon & version info resource problem for WinCE 5
* win32/pe & arm/pe: added option --compress-icons=3 to compress all icons * win32/pe & arm/pe: added option --compress-icons=3 to compress all icons
Changes in 2.90 beta (08 Oct 2006): Changes in 2.90 beta (08 Oct 2006):
@@ -203,7 +207,7 @@ Changes in 1.95 beta (09 Apr 2006):
* win32/pe: really worked around R6002 runtime errors * win32/pe: really worked around R6002 runtime errors
Changes in 1.94 beta (11 Mar 2006): Changes in 1.94 beta (11 Mar 2006):
* new format: added support for arm/pe (ARM executables running on WinCE) * new format: added support for wince/arm (ARM executables running on WinCE)
* new format: added support for linux elf/amd64 * new format: added support for linux elf/amd64
* new format: added support for linux elf/ppc32 * new format: added support for linux elf/ppc32
* new format: added support for mach/ppc32 (Apple Mac OS X) * new format: added support for mach/ppc32 (Apple Mac OS X)
@@ -255,7 +259,7 @@ Changes in 1.11 beta (20 Dec 2000):
================================================================== ==================================================================
Changes in 1.25 (29 Jun 2004) Changes in 1.25 (29 Jun 2004)
* INFO: http://upx.sourceforge.net is the permanent UPX home page * INFO: http://upx.sourceforge.net is the new UPX home page
* watcom/le: don't crash on files without relocations * watcom/le: don't crash on files without relocations
* win32/pe: stricter checks of some PE values * win32/pe: stricter checks of some PE values
* source code: much improved portability using ACC, the * source code: much improved portability using ACC, the
@@ -520,12 +524,12 @@ Changes in 0.40 (05 Oct 1998)
* fixed a small but fatal bug in dos/sys introduced in 0.30 * fixed a small but fatal bug in dos/sys introduced in 0.30
* fixed a rare bug in dos/exe * fixed a rare bug in dos/exe
* worked around a bug in djgpp's strip 2.8 * worked around a bug in djgpp's strip 2.8
* djgpp/coff: Allegro packfile support should work now * djgpp2/coff: Allegro packfile support should work now
* added dos/exeh compression method (works on 386+) * added dos/exeh compression method (works on 386+)
Changes in 0.30 (27 Jul 1998) Changes in 0.30 (27 Jul 1998)
* fixed a serious bug in the 32-bit compressors - please don't use * fixed a serious bug in the 32-bit compressors - please don't use
djgpp/coff and watcom/le compressed files from previous versions, djgpp2/coff and watcom/le compressed files from previous versions,
some of them are possibly damaged ! some of them are possibly damaged !
* the 16-bit uncompressors are a little bit shorter & faster * the 16-bit uncompressors are a little bit shorter & faster
* fixed progress indicator for VESA and SVGA text modes * fixed progress indicator for VESA and SVGA text modes
@@ -536,6 +540,5 @@ Changes in 0.20 (05 Jul 1998)
Changes in 0.05 (26 May 1998) Changes in 0.05 (26 May 1998)
* first public beta release * first public beta release
* based on experience gained from our previous packers DJP (djgpp2/coff, 1996),
lzop (1996) and mfxpak (atari/tos, 1990)
# vim:set syntax=off tw=0 ts=4 sw=4 et: -*- coding: utf-8 -*-
+36 -2
View File
@@ -44,7 +44,7 @@ Short overview
Tools needed to build/modify the UPX sources Tools needed to build/modify the UPX sources
-------------------------------------------- --------------------------------------------
- A C++ compiler that supports C++ 17: clang-5, gcc-8 or msvc-2019 16.11 - A C++ compiler that fully implements 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) (older or other compilers may work but are unsupported, use at your own risk)
- GNU make - GNU make
@@ -61,7 +61,7 @@ To compile the packer sources
If you want to modify the stub sources you'll also need If you want to modify the stub sources you'll also need
------------------------------------------------------- -------------------------------------------------------
- Podman/Docker: see misc/rebuild-stubs-with-podman - this - Podman/Docker: see misc/podman/rebuild-stubs - this
is the preferred way of rebuilding the stubs is the preferred way of rebuilding the stubs
- otherwise you will need: - otherwise you will need:
@@ -71,6 +71,40 @@ If you want to modify the stub sources you'll also need
https://github.com/upx/upx-stubtools/releases https://github.com/upx/upx-stubtools/releases
Developer quick start
---------------------
1) $ mkdir my-upx; cd my-upx # new directory for safety and convenience
2) $ git clone https://github.com/upx/upx.git
3) $ git clone https://github.com/upx/upx-testsuite.git
4) # Optional for re-building stubs:
4a) $ pushd upx/src/stub # my-upx/upx/src/stub
4b) $ wget https://github.com/upx/upx-stubtools/releases/download/v20221212/bin-upx-20221212.tar.xz
# Extract to $HOME/bin/bin-upx or $HOME/local/bin/bin-upx.
# See directions in: https://github.com/upx/upx-stubtools
4c) $ make clean; make # verify that you can re-build stubs
4d) $ popd # my-upx
5) $ cd upx # my-upx/upx
6) $ git submodule update --init # compression algorithms, etc.
# DO NOT TOUCH vendor/...
# After a git merge/pull/etc, then use "git status"
# to check whether the vendor directory is clean;
# if not, then update via "git submodule update".
# If stuck, then reset via "rm -rf vendor; git submodule update --init".
7) $ mkdir -p build/debug build/release
8) $ pushd build/debug # my-upx/upx/build/debug
9) $ cmake ../.. # configure cmake
10) $ cmake --build . --verbose # optional "--verbose"
# This relies on stub/*.h, which YOU must re-build if necessary.
# When in doubt, then use "cd src/stub; make clean; make".
11) $ popd # my-upx/upx
12) $ cd src # my-upx/upx/src
12a) On MacOS: install homebrew (https:://brew.sh), then "brew install coreutils"
and put <some_prefix>/opt/coreutils/libexec/gnubin into PATH so that
"readlink -en" and "sha256sum -b" work.
13) $ make run-testsuite 2>&1 | tee testsuite.log
Misc. notes Misc. notes
----------- -----------
-5
View File
@@ -1,5 +0,0 @@
-std=gnu++17
-Ivendor
-fno-strict-aliasing
-fno-strict-overflow
-funsigned-char
+3 -1
View File
@@ -41,12 +41,14 @@ Joergen Ibsen <jibz@hotmail.com> and d'b
for the relocation & address optimization ideas for the relocation & address optimization ideas
John S. Fine <johnfine@erols.com> John S. Fine <johnfine@erols.com>
for the new version of the dos/exe decompressor for the new version of the dos/exe decompressor
Kornel Pal
for the EFI support
Lukundoo <Lukundoo@softhome.net> Lukundoo <Lukundoo@softhome.net>
for beta testing for beta testing
Michael Devore Michael Devore
for initial dos/exe device driver support for initial dos/exe device driver support
Oleg V. Volkov <rover@lglobus.ru> Oleg V. Volkov <rover@lglobus.ru>
for various FreeBSD specific informations for various FreeBSD specific information
The Owl & G-RoM The Owl & G-RoM
for the --compress-icons fix for the --compress-icons fix
Ralph Roth <RalphRoth@gmx.net> Ralph Roth <RalphRoth@gmx.net>
+1 -1
View File
@@ -160,7 +160,7 @@ Copyright (c) 1996-2023 Markus Oberhumer, Laszlo Molnar &amp; John Reiser
<p>Info: An &quot;overlay&quot; means auxiliary data attached after the logical end of an executable, and it often contains application specific data (this is a common practice to avoid an extra data file, though it would be better to use resource sections).</p> <p>Info: An &quot;overlay&quot; means auxiliary data attached after the logical end of an executable, and it often contains application specific data (this is a common practice to avoid an extra data file, though it would be better to use resource sections).</p>
<p><b>UPX</b> handles overlays like many other executable packers do: it simply copies the overlay after the compressed image. This works with some files, but doesn&#39;t work with others, depending on how an application actually accesses this overlayed data.</p> <p><b>UPX</b> handles overlays like many other executable packers do: it simply copies the overlay after the compressed image. This works with some files, but doesn&#39;t work with others, depending on how an application actually accesses this overlaid data.</p>
<pre><code>--overlay=copy Copy any extra data attached to the file. [DEFAULT] <pre><code>--overlay=copy Copy any extra data attached to the file. [DEFAULT]
+1 -1
View File
@@ -153,7 +153,7 @@ OVERLAY HANDLING OPTIONS
UPX handles overlays like many other executable packers do: it simply UPX handles overlays like many other executable packers do: it simply
copies the overlay after the compressed image. This works with some copies the overlay after the compressed image. This works with some
files, but doesn't work with others, depending on how an application files, but doesn't work with others, depending on how an application
actually accesses this overlayed data. actually accesses this overlaid data.
--overlay=copy Copy any extra data attached to the file. [DEFAULT] --overlay=copy Copy any extra data attached to the file. [DEFAULT]
Generated
+2 -2
View File
@@ -133,7 +133,7 @@
.\" ======================================================================== .\" ========================================================================
.\" .\"
.IX Title "UPX 1" .IX Title "UPX 1"
.TH UPX 1 "2023-01-30" "upx 4.0.2" " " .TH UPX 1 "2023-08-08" "upx 4.1.0" " "
.\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents. .\" way too many mistakes in technical documents.
.if n .ad l .if n .ad l
@@ -296,7 +296,7 @@ it would be better to use resource sections).
\&\fB\s-1UPX\s0\fR handles overlays like many other executable packers do: it simply \&\fB\s-1UPX\s0\fR handles overlays like many other executable packers do: it simply
copies the overlay after the compressed image. This works with some copies the overlay after the compressed image. This works with some
files, but doesn't work with others, depending on how an application files, but doesn't work with others, depending on how an application
actually accesses this overlayed data. actually accesses this overlaid data.
.PP .PP
.Vb 1 .Vb 1
\& \-\-overlay=copy Copy any extra data attached to the file. [DEFAULT] \& \-\-overlay=copy Copy any extra data attached to the file. [DEFAULT]
+1 -1
View File
@@ -208,7 +208,7 @@ it would be better to use resource sections).
B<UPX> handles overlays like many other executable packers do: it simply B<UPX> handles overlays like many other executable packers do: it simply
copies the overlay after the compressed image. This works with some copies the overlay after the compressed image. This works with some
files, but doesn't work with others, depending on how an application files, but doesn't work with others, depending on how an application
actually accesses this overlayed data. actually accesses this overlaid data.
--overlay=copy Copy any extra data attached to the file. [DEFAULT] --overlay=copy Copy any extra data attached to the file. [DEFAULT]
@@ -0,0 +1,22 @@
# for clang-tidy-16 from https://clang.llvm.org/extra/clang-tidy/
---
Checks: >
-*,
bugprone-*,
-bugprone-branch-clone,
-bugprone-easily-swappable-parameters,
-bugprone-implicit-widening-of-multiplication-result,
-bugprone-macro-parentheses,
-bugprone-narrowing-conversions,
-bugprone-reserved-identifier,
-bugprone-switch-missing-default-case,
clang-analyzer-*,
-clang-analyzer-core.UndefinedBinaryOperatorResult,
-clang-analyzer-core.uninitialized.Assign,
-clang-analyzer-security.insecureAPI.strcpy,
clang-diagnostics-*',
performance-*,
FormatStyle: file
HeaderFilterRegex: '.*'
InheritParentConfig: false
...
@@ -0,0 +1,20 @@
# for clang-tidy-16 from https://clang.llvm.org/extra/clang-tidy/
---
Checks: >
-*,
bugprone-*,
-bugprone-assignment-in-if-condition,
-bugprone-easily-swappable-parameters,
-bugprone-implicit-widening-of-multiplication-result,
-bugprone-macro-parentheses,
-bugprone-reserved-identifier,
-bugprone-sizeof-expression,
-bugprone-suspicious-include,
clang-analyzer-*,
-clang-analyzer-security.insecureAPI.DeprecatedOrUnsafeBufferHandling,
clang-diagnostics-*',
performance-*,
FormatStyle: file
HeaderFilterRegex: '.*'
InheritParentConfig: false
...
@@ -0,0 +1,21 @@
# for clang-tidy-16 from https://clang.llvm.org/extra/clang-tidy/
---
Checks: >
-*,
bugprone-*,
-bugprone-assignment-in-if-condition,
-bugprone-easily-swappable-parameters,
-bugprone-implicit-widening-of-multiplication-result,
-bugprone-macro-parentheses,
-bugprone-narrowing-conversions,
-bugprone-reserved-identifier,
-bugprone-switch-missing-default-case,
clang-analyzer-*,
-clang-analyzer-optin.performance.Padding,
-clang-analyzer-security.insecureAPI.DeprecatedOrUnsafeBufferHandling,
clang-diagnostics-*',
performance-*,
FormatStyle: file
HeaderFilterRegex: '.*'
InheritParentConfig: false
...
@@ -0,0 +1,25 @@
# for clang-tidy-16 from https://clang.llvm.org/extra/clang-tidy/
---
Checks: >
-*,
bugprone-*,
-bugprone-assignment-in-if-condition,
-bugprone-branch-clone,
-bugprone-easily-swappable-parameters,
-bugprone-implicit-widening-of-multiplication-result,
-bugprone-macro-parentheses,
-bugprone-misplaced-widening-cast,
-bugprone-narrowing-conversions,
-bugprone-reserved-identifier,
-bugprone-switch-missing-default-case,
clang-analyzer-*,
-clang-analyzer-core.UndefinedBinaryOperatorResult,
-clang-analyzer-deadcode.DeadStores,
-clang-analyzer-security.insecureAPI.DeprecatedOrUnsafeBufferHandling,
clang-diagnostics-*',
performance-*,
-performance-no-int-to-ptr,
FormatStyle: file
HeaderFilterRegex: '.*'
InheritParentConfig: false
...
+515
View File
@@ -0,0 +1,515 @@
#!/usr/bin/env python3
#
# ===- run-clang-tidy.py - Parallel clang-tidy runner --------*- python -*--===#
#
# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
# See https://llvm.org/LICENSE.txt for license information.
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
#
# ===-----------------------------------------------------------------------===#
# FIXME: Integrate with clang-tidy-diff.py
"""
Parallel clang-tidy runner
==========================
Runs clang-tidy over all files in a compilation database. Requires clang-tidy
and clang-apply-replacements in $PATH.
Example invocations.
- Run clang-tidy on all files in the current working directory with a default
set of checks and show warnings in the cpp files and all project headers.
run-clang-tidy.py $PWD
- Fix all header guards.
run-clang-tidy.py -fix -checks=-*,llvm-header-guard
- Fix all header guards included from clang-tidy and header guards
for clang-tidy headers.
run-clang-tidy.py -fix -checks=-*,llvm-header-guard extra/clang-tidy \
-header-filter=extra/clang-tidy
Compilation database setup:
http://clang.llvm.org/docs/HowToSetupToolingForLLVM.html
"""
from __future__ import print_function
import argparse
import glob
import json
import multiprocessing
import os
import queue
import re
import shutil
import subprocess
import sys
import tempfile
import threading
import traceback
try:
import yaml
except ImportError:
yaml = None
def strtobool(val):
"""Convert a string representation of truth to a bool following LLVM's CLI argument parsing."""
val = val.lower()
if val in ["", "true", "1"]:
return True
elif val in ["false", "0"]:
return False
# Return ArgumentTypeError so that argparse does not substitute its own error message
raise argparse.ArgumentTypeError(
"'{}' is invalid value for boolean argument! Try 0 or 1.".format(val)
)
def find_compilation_database(path):
"""Adjusts the directory until a compilation database is found."""
result = os.path.realpath("./")
while not os.path.isfile(os.path.join(result, path)):
parent = os.path.dirname(result)
if result == parent:
print("Error: could not find compilation database.")
sys.exit(1)
result = parent
return result
def make_absolute(f, directory):
if os.path.isabs(f):
return f
return os.path.normpath(os.path.join(directory, f))
def get_tidy_invocation(
f,
clang_tidy_binary,
checks,
tmpdir,
build_path,
header_filter,
allow_enabling_alpha_checkers,
extra_arg,
extra_arg_before,
quiet,
config_file_path,
config,
line_filter,
use_color,
plugins,
warnings_as_errors,
):
"""Gets a command line for clang-tidy."""
start = [clang_tidy_binary]
if allow_enabling_alpha_checkers:
start.append("-allow-enabling-analyzer-alpha-checkers")
if header_filter is not None:
start.append("-header-filter=" + header_filter)
if line_filter is not None:
start.append("-line-filter=" + line_filter)
if use_color is not None:
if use_color:
start.append("--use-color")
else:
start.append("--use-color=false")
if checks:
start.append("-checks=" + checks)
if tmpdir is not None:
start.append("-export-fixes")
# Get a temporary file. We immediately close the handle so clang-tidy can
# overwrite it.
(handle, name) = tempfile.mkstemp(suffix=".yaml", dir=tmpdir)
os.close(handle)
start.append(name)
for arg in extra_arg:
start.append("-extra-arg=%s" % arg)
for arg in extra_arg_before:
start.append("-extra-arg-before=%s" % arg)
start.append("-p=" + build_path)
if quiet:
start.append("-quiet")
if config_file_path:
start.append("--config-file=" + config_file_path)
elif config:
start.append("-config=" + config)
for plugin in plugins:
start.append("-load=" + plugin)
if warnings_as_errors:
start.append("--warnings-as-errors=" + warnings_as_errors)
start.append(f)
return start
def merge_replacement_files(tmpdir, mergefile):
"""Merge all replacement files in a directory into a single file"""
# The fixes suggested by clang-tidy >= 4.0.0 are given under
# the top level key 'Diagnostics' in the output yaml files
mergekey = "Diagnostics"
merged = []
for replacefile in glob.iglob(os.path.join(tmpdir, "*.yaml")):
content = yaml.safe_load(open(replacefile, "r"))
if not content:
continue # Skip empty files.
merged.extend(content.get(mergekey, []))
if merged:
# MainSourceFile: The key is required by the definition inside
# include/clang/Tooling/ReplacementsYaml.h, but the value
# is actually never used inside clang-apply-replacements,
# so we set it to '' here.
output = {"MainSourceFile": "", mergekey: merged}
with open(mergefile, "w") as out:
yaml.safe_dump(output, out)
else:
# Empty the file:
open(mergefile, "w").close()
def find_binary(arg, name, build_path):
"""Get the path for a binary or exit"""
if arg:
if shutil.which(arg):
return arg
else:
raise SystemExit(
"error: passed binary '{}' was not found or is not executable".format(
arg
)
)
built_path = os.path.join(build_path, "bin", name)
binary = shutil.which(name) or shutil.which(built_path)
if binary:
return binary
else:
raise SystemExit(
"error: failed to find {} in $PATH or at {}".format(name, built_path)
)
def apply_fixes(args, clang_apply_replacements_binary, tmpdir):
"""Calls clang-apply-fixes on a given directory."""
invocation = [clang_apply_replacements_binary]
invocation.append("-ignore-insert-conflict")
if args.format:
invocation.append("-format")
if args.style:
invocation.append("-style=" + args.style)
invocation.append(tmpdir)
subprocess.call(invocation)
def run_tidy(args, clang_tidy_binary, tmpdir, build_path, queue, lock, failed_files):
"""Takes filenames out of queue and runs clang-tidy on them."""
while True:
name = queue.get()
invocation = get_tidy_invocation(
name,
clang_tidy_binary,
args.checks,
tmpdir,
build_path,
args.header_filter,
args.allow_enabling_alpha_checkers,
args.extra_arg,
args.extra_arg_before,
args.quiet,
args.config_file,
args.config,
args.line_filter,
args.use_color,
args.plugins,
args.warnings_as_errors,
)
proc = subprocess.Popen(
invocation, stdout=subprocess.PIPE, stderr=subprocess.PIPE
)
output, err = proc.communicate()
if proc.returncode != 0:
if proc.returncode < 0:
msg = "%s: terminated by signal %d\n" % (name, -proc.returncode)
err += msg.encode("utf-8")
failed_files.append(name)
with lock:
sys.stdout.write(" ".join(invocation) + "\n" + output.decode("utf-8"))
if len(err) > 0:
sys.stdout.flush()
sys.stderr.write(err.decode("utf-8"))
queue.task_done()
def main():
parser = argparse.ArgumentParser(
description="Runs clang-tidy over all files "
"in a compilation database. Requires "
"clang-tidy and clang-apply-replacements in "
"$PATH or in your build directory."
)
parser.add_argument(
"-allow-enabling-alpha-checkers",
action="store_true",
help="allow alpha checkers from " "clang-analyzer.",
)
parser.add_argument(
"-clang-tidy-binary", metavar="PATH", help="path to clang-tidy binary"
)
parser.add_argument(
"-clang-apply-replacements-binary",
metavar="PATH",
help="path to clang-apply-replacements binary",
)
parser.add_argument(
"-checks",
default=None,
help="checks filter, when not specified, use clang-tidy " "default",
)
config_group = parser.add_mutually_exclusive_group()
config_group.add_argument(
"-config",
default=None,
help="Specifies a configuration in YAML/JSON format: "
" -config=\"{Checks: '*', "
' CheckOptions: {x: y}}" '
"When the value is empty, clang-tidy will "
"attempt to find a file named .clang-tidy for "
"each source file in its parent directories.",
)
config_group.add_argument(
"-config-file",
default=None,
help="Specify the path of .clang-tidy or custom config "
"file: e.g. -config-file=/some/path/myTidyConfigFile. "
"This option internally works exactly the same way as "
"-config option after reading specified config file. "
"Use either -config-file or -config, not both.",
)
parser.add_argument(
"-header-filter",
default=None,
help="regular expression matching the names of the "
"headers to output diagnostics from. Diagnostics from "
"the main file of each translation unit are always "
"displayed.",
)
parser.add_argument(
"-line-filter",
default=None,
help="List of files with line ranges to filter the" "warnings.",
)
if yaml:
parser.add_argument(
"-export-fixes",
metavar="filename",
dest="export_fixes",
help="Create a yaml file to store suggested fixes in, "
"which can be applied with clang-apply-replacements.",
)
parser.add_argument(
"-j",
type=int,
default=0,
help="number of tidy instances to be run in parallel.",
)
parser.add_argument(
"files", nargs="*", default=[".*"], help="files to be processed (regex on path)"
)
parser.add_argument("-fix", action="store_true", help="apply fix-its")
parser.add_argument(
"-format", action="store_true", help="Reformat code " "after applying fixes"
)
parser.add_argument(
"-style",
default="file",
help="The style of reformat " "code after applying fixes",
)
parser.add_argument(
"-use-color",
type=strtobool,
nargs="?",
const=True,
help="Use colors in diagnostics, overriding clang-tidy's"
" default behavior. This option overrides the 'UseColor"
"' option in .clang-tidy file, if any.",
)
parser.add_argument(
"-p", dest="build_path", help="Path used to read a compile command database."
)
parser.add_argument(
"-extra-arg",
dest="extra_arg",
action="append",
default=[],
help="Additional argument to append to the compiler " "command line.",
)
parser.add_argument(
"-extra-arg-before",
dest="extra_arg_before",
action="append",
default=[],
help="Additional argument to prepend to the compiler " "command line.",
)
parser.add_argument(
"-quiet", action="store_true", help="Run clang-tidy in quiet mode"
)
parser.add_argument(
"-load",
dest="plugins",
action="append",
default=[],
help="Load the specified plugin in clang-tidy.",
)
parser.add_argument(
"-warnings-as-errors",
default=None,
help="Upgrades warnings to errors. Same format as " "'-checks'",
)
args = parser.parse_args()
db_path = "compile_commands.json"
if args.build_path is not None:
build_path = args.build_path
else:
# Find our database
build_path = find_compilation_database(db_path)
clang_tidy_binary = find_binary(args.clang_tidy_binary, "clang-tidy", build_path)
tmpdir = None
if args.fix:
clang_apply_replacements_binary = find_binary(
args.clang_apply_replacements_binary, "clang-apply-replacements", build_path
)
tmpdir = tempfile.mkdtemp()
# Load the database and extract all files.
database = json.load(open(os.path.join(build_path, db_path)))
files = set(
[make_absolute(entry["file"], entry["directory"]) for entry in database]
)
# Build up a big regexy filter from all command line arguments.
file_name_re = re.compile("|".join(args.files))
# filter files with mo.group(0), and sort files
matched_files = []
for name in files:
mo = file_name_re.search(name)
if mo and mo.group(0):
matched_files.append(name)
files = sorted(matched_files)
if not files:
if tmpdir:
shutil.rmtree(tmpdir)
sys.exit(0)
try:
invocation = get_tidy_invocation(
"",
clang_tidy_binary,
args.checks,
None,
build_path,
args.header_filter,
args.allow_enabling_alpha_checkers,
args.extra_arg,
args.extra_arg_before,
args.quiet,
args.config_file,
args.config,
args.line_filter,
args.use_color,
args.plugins,
args.warnings_as_errors,
)
invocation.append("-list-checks")
invocation.append("-")
if args.quiet:
# Even with -quiet we still want to check if we can call clang-tidy.
with open(os.devnull, "w") as dev_null:
subprocess.check_call(invocation, stdout=dev_null)
else:
subprocess.check_call(invocation)
except:
print("Unable to run clang-tidy.", file=sys.stderr)
sys.exit(1)
max_task = args.j
if max_task == 0:
max_task = multiprocessing.cpu_count()
return_code = 0
try:
# Spin up a bunch of tidy-launching threads.
task_queue = queue.Queue(max_task)
# List of files with a non-zero return code.
failed_files = []
lock = threading.Lock()
for _ in range(max_task):
t = threading.Thread(
target=run_tidy,
args=(
args,
clang_tidy_binary,
tmpdir,
build_path,
task_queue,
lock,
failed_files,
),
)
t.daemon = True
t.start()
# Fill the queue with files.
for name in files:
if file_name_re.search(name):
task_queue.put(name)
# Wait for all threads to be done.
task_queue.join()
if len(failed_files):
return_code = 1
except KeyboardInterrupt:
# This is a sad hack. Unfortunately subprocess goes
# bonkers with ctrl-c and we start forking merrily.
print("\nCtrl-C detected, goodbye.")
if tmpdir:
shutil.rmtree(tmpdir)
os.kill(0, 9)
if yaml and args.export_fixes:
print("Writing fixes to " + args.export_fixes + " ...")
try:
merge_replacement_files(tmpdir, args.export_fixes)
except:
print("Error exporting fixes.\n", file=sys.stderr)
traceback.print_exc()
return_code = 1
if args.fix:
print("Applying fixes ...")
try:
apply_fixes(args, clang_apply_replacements_binary, tmpdir)
except:
print("Error applying fixes.\n", file=sys.stderr)
traceback.print_exc()
return_code = 1
if tmpdir:
shutil.rmtree(tmpdir)
sys.exit(return_code)
if __name__ == "__main__":
main()
@@ -6,12 +6,14 @@ argv0=$0; argv0abs="$(readlink -fn "$argv0")"; argv0dir="$(dirname "$argv0abs")"
# create the image from Dockerfile # create the image from Dockerfile
# using a rootless Podman container # using a rootless Podman container
# NOTE: this image is based on rebuild-stubs-with-podman/upx-stubtools-20221212-v4, # NOTE: this image is based on rebuild-stubs/upx-stubtools-20221212-v6,
# so you have to create that image first # so you have to create that image first
# WARNING: we install many packages, so the resulting image needs A LOT of disk space! # WARNING: we install many packages, so the resulting image needs A LOT of disk space!
image=upx-cross-compile-20230115-v2 image=upx-cross-compile-ubuntu2204-20230721-v1
[[ $1 == --print-image ]] && echo "$image" && exit 0
podman build -t "$image" -f "$argv0dir/Dockerfile" "$argv0dir" podman build -t "$image" -f "$argv0dir/Dockerfile" "$argv0dir"
podman image list "$image" podman image list "$image"
echo
podman image tree "$image" podman image tree "$image"
+40
View File
@@ -0,0 +1,40 @@
#! /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")"
# list all system packages that are installed in the image
# using a rootless Podman container
image="$("$argv0dir/10-create-image.sh" --print-image)"
podman image list "$image"
echo
podman image tree "$image"
echo 'Packages:'
flags=( --read-only --rm --pull=never )
flags+=( --cap-drop=all ) # drop all capabilities
flags+=( --network=none ) # no network needed
podman run "${flags[@]}" "$image" bash -c $'dpkg -l | sed \'s/ *$//\' | LC_ALL=C sort'
echo
echo 'Packages sorted by Installed-Size:'
podman run "${flags[@]}" "$image" bash -c $'awk \'
BEGIN {
arch = "UNKNOWN"; size = 0; package = "UNKNOWN";
}
{
if ($1 == "Architecture:") arch = $2;
if ($1 == "Installed-Size:") size = $2;
if ($1 == "Package:") package = $2;
if ($1 == "") {
printf("%9d %-40s %s\\n", size, package, arch);
count += 1; total += size;
arch = "UNKNOWN"; size = 0; package = "UNKNOWN";
}
}
END {
printf("%9d ===== TOTAL (%d packages)\\n", total, count);
}
\' /var/lib/dpkg/status | LC_ALL=C sort -rn'
@@ -6,12 +6,12 @@ argv0=$0; argv0abs="$(readlink -fn "$argv0")"; argv0dir="$(dirname "$argv0abs")"
# run an interactive shell in the image # run an interactive shell in the image
# using a rootless Podman container # using a rootless Podman container
image=upx-cross-compile-20230115-v2 image="$("$argv0dir/10-create-image.sh" --print-image)"
flags=( -ti --read-only --rm ) flags=( --read-only --rm --pull=never )
flags+=( --cap-drop=all ) # drop all capabilities flags+=( --cap-drop=all ) # drop all capabilities
flags+=( --network=none ) # no network needed flags+=( --network=none ) # no network needed
flags+=( -e TERM="$TERM" ) # pass $TERM flags+=( -ti -e TERM="$TERM" ) # allocate an interactive pseudo-tty and pass $TERM
if [[ 1 == 1 ]]; then if [[ 1 == 1 ]]; then
# run as user upx 2000:2000 # run as user upx 2000:2000
flags+=( --user 2000 ) flags+=( --user 2000 )
@@ -21,8 +21,10 @@ if [[ 1 == 1 ]]; then
flags+=( --gidmap=0:1:1000 --gidmap=2000:0:1 ) flags+=( --gidmap=0:1:1000 --gidmap=2000:0:1 )
# NOTE: we mount the upx top-level directory read-write under /home/upx/src/upx # NOTE: we mount the upx top-level directory read-write under /home/upx/src/upx
# INFO: SELinux users *may* have to add ":z" to the volume mount flags; check the docs! # INFO: SELinux users *may* have to add ":z" to the volume mount flags; check the docs!
flags+=( -v "${argv0dir}/../..:/home/upx/src/upx" ) flags+=( -v "${argv0dir}/../../..:/home/upx/src/upx" )
flags+=( -w /home/upx/src/upx ) # set working directory flags+=( -w /home/upx/src/upx ) # set working directory
flags+=( --tmpfs /home/upx/.cache:rw,exec ) # mount a writeable tmpfs
flags+=( --tmpfs /home/upx/.local:rw,exec ) # mount a writeable tmpfs
else else
# run as user root 0:0 # run as user root 0:0
# ONLY FOR DEBUGGING THE IMAGE # ONLY FOR DEBUGGING THE IMAGE
@@ -30,7 +32,11 @@ else
flags+=( --user 0 ) flags+=( --user 0 )
fi fi
podman run "${flags[@]}" "$image" bash -l if [[ $# == 0 ]]; then
podman run "${flags[@]}" "$image" bash -l
else
podman run "${flags[@]}" "$image" "$@"
fi
# now we can cross-compile UPX for Windows: # now we can cross-compile UPX for Windows:
# cd /home/upx/src/upx # cd /home/upx/src/upx
@@ -44,10 +50,11 @@ podman run "${flags[@]}" "$image" bash -l
# and lots of other cross-compilers are installed; see "ls /usr/bin/*g++*" # 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 # and finally see
# ./misc/podman/cross-compile-upx-ubuntu/build-all-inside-container.sh
# after running that script we can do cool things like: # 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 # cd /home/upx/src/upx/build/cross-compile-upx-ubuntu2204/alpha-linux-gnu/debug
# qemu-alpha -L /usr/alpha-linux-gnu upx --version # qemu-alpha -L /usr/alpha-linux-gnu ./upx --version
# cd /home/upx/src/upx/build/cross-compile-upx-with-podman/hppa-linux-gnu/debug # cd /home/upx/src/upx/build/cross-compile-upx-ubuntu2204/hppa-linux-gnu/debug
# qemu-hppa -L /usr/hppa-linux-gnu upx --version # qemu-hppa -L /usr/hppa-linux-gnu ./upx --version
# (similar for many other architectures/builds) # (similar for many other architectures/builds)
@@ -1,8 +1,8 @@
# NOTE: this image is based on rebuild-stubs-with-podman/upx-stubtools-20221212-v4, # NOTE: this image is based on rebuild-stubs/upx-stubtools-20221212-v6,
# so you have to create that image first # so you have to create that image first
# WARNING: we install many packages, so the resulting image needs A LOT of disk space! # WARNING: we install many packages, so the resulting image needs A LOT of disk space!
FROM localhost/upx-stubtools-20221212-v4 FROM localhost/upx-stubtools-20221212-v6
ENV UPX_CONTAINER_IMAGE_NAME=upx-cross-compile-20230115-v2 ENV UPX_CONTAINER_IMAGE_NAME=upx-cross-compile-ubuntu2204-20230721-v1
ARG DEBIAN_FRONTEND=noninteractive ARG DEBIAN_FRONTEND=noninteractive
USER root USER root
@@ -39,7 +39,7 @@ RUN apt-get install -y \
# clang-14 and tools # clang-14 and tools
clang-14 clang-format-14 clang-tidy-14 clang-tools-14 lldb-14 llvm-14 \ clang-14 clang-format-14 clang-tidy-14 clang-tools-14 lldb-14 llvm-14 \
# QEMU and Wine # QEMU and Wine
qemu-system qemu-user wine wine32 \ qemu-system qemu-user wine wine32:i386 wine64 \
# misc # misc
gdb lsb-release valgrind \ gdb lsb-release valgrind \
&& true && true
@@ -50,5 +50,5 @@ RUN cd /usr/bin \
&& ln -s -v ../../bin/yaml2obj-14 /usr/local/bin/llvm-yaml2obj \ && ln -s -v ../../bin/yaml2obj-14 /usr/local/bin/llvm-yaml2obj \
&& true && true
# switch back to default user upx 2000:2000 # switch back to default user upx:upx 2000:2000
USER upx USER upx
@@ -13,9 +13,10 @@ if [[ $UPX_CONTAINER_IMAGE_NAME != upx-cross-compile-* ]]; then
fi fi
# go to upx top-level directory # go to upx top-level directory
cd "$argv0dir/../.." || exit 1 cd "$argv0dir/../../.." || exit 1
pwd pwd
[[ -f src/version.h ]] || exit 1 # sanity check test -f doc/upx.pod || exit 1 # sanity check
test -f src/version.h || exit 1 # sanity check
function run_config_and_build { function run_config_and_build {
# requires: AR CC CXX RANLIB # requires: AR CC CXX RANLIB
@@ -27,9 +28,13 @@ function run_config_and_build {
# these old architectures do not support sanitize # these old architectures do not support sanitize
alpha-linux-gnu) cmake_config_flags=-DUPX_CONFIG_DISABLE_SANITIZE=ON ;; alpha-linux-gnu) cmake_config_flags=-DUPX_CONFIG_DISABLE_SANITIZE=ON ;;
hppa-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 # avoid sanitize link errors with current MinGW-w64 versions; link libstdc++ statically
i686-w64-mingw32) cmake_config_flags=-DUPX_CONFIG_DISABLE_SANITIZE=ON ;; i686-w64-mingw32)
x86_64-w64-mingw32) cmake_config_flags=-DUPX_CONFIG_DISABLE_SANITIZE=ON ;; cmake_config_flags=-DUPX_CONFIG_DISABLE_SANITIZE=ON
CC="$CC -static"; CXX="$CXX -static" ;;
x86_64-w64-mingw32)
cmake_config_flags=-DUPX_CONFIG_DISABLE_SANITIZE=ON
CC="$CC -static"; CXX="$CXX -static" ;;
# avoid warnings about arm libstdc++ ABI change in gcc-7 # avoid warnings about arm libstdc++ ABI change in gcc-7
arm-linux-*) CXX="$CXX -Wno-psabi" ;; arm-linux-*) CXX="$CXX -Wno-psabi" ;;
esac esac
@@ -39,14 +44,15 @@ function run_config_and_build {
fi fi
# for all build types # for all build types
for build_type in Debug Release; do for build_type in Debug Release; do
bdir=build/cross-compile-upx-with-podman/$toolchain/${build_type,,} bdir="build/cross-compile-upx-ubuntu2204/$toolchain/${build_type,,}"
mkdir -p $bdir mkdir -p "$bdir"
# run_config # run_config
if [[ ! -f $bdir/CMakeCache.txt ]]; then if [[ ! -f $bdir/CMakeCache.txt ]]; then
cmake -S . -B $bdir -DCMAKE_BUILD_TYPE=$build_type -DCMAKE_AR=$AR -DCMAKE_RANLIB=$RANLIB $cmake_config_flags export CMAKE_REQUIRED_QUIET=OFF
cmake -S . -B "$bdir" -DCMAKE_BUILD_TYPE=$build_type -DCMAKE_AR=$AR -DCMAKE_RANLIB=$RANLIB $cmake_config_flags
fi fi
# run_build # run_build
cmake --build $bdir --config $build_type --parallel cmake --build "$bdir" --config $build_type --parallel
done done
} }
File diff suppressed because it is too large Load Diff
@@ -6,9 +6,11 @@ argv0=$0; argv0abs="$(readlink -fn "$argv0")"; argv0dir="$(dirname "$argv0abs")"
# create the image from Dockerfile # create the image from Dockerfile
# using a rootless Podman container # using a rootless Podman container
image=upx-stubtools-20221212-v4 image=upx-stubtools-20221212-v6
[[ $1 == --print-image ]] && echo "$image" && exit 0
podman build -t "$image" -f "$argv0dir/Dockerfile" "$argv0dir" podman build -t "$image" -f "$argv0dir/Dockerfile" "$argv0dir"
podman image list "$image" podman image list "$image"
echo
podman image tree "$image" podman image tree "$image"
+40
View File
@@ -0,0 +1,40 @@
#! /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")"
# list all system packages that are installed in the image
# using a rootless Podman container
image="$("$argv0dir/10-create-image.sh" --print-image)"
podman image list "$image"
echo
podman image tree "$image"
echo 'Packages:'
flags=( --read-only --rm --pull=never )
flags+=( --cap-drop=all ) # drop all capabilities
flags+=( --network=none ) # no network needed
podman run "${flags[@]}" "$image" bash -c $'dpkg -l | sed \'s/ *$//\' | LC_ALL=C sort'
echo
echo 'Packages sorted by Installed-Size:'
podman run "${flags[@]}" "$image" bash -c $'awk \'
BEGIN {
arch = "UNKNOWN"; size = 0; package = "UNKNOWN";
}
{
if ($1 == "Architecture:") arch = $2;
if ($1 == "Installed-Size:") size = $2;
if ($1 == "Package:") package = $2;
if ($1 == "") {
printf("%9d %-40s %s\\n", size, package, arch);
count += 1; total += size;
arch = "UNKNOWN"; size = 0; package = "UNKNOWN";
}
}
END {
printf("%9d ===== TOTAL (%d packages)\\n", total, count);
}
\' /var/lib/dpkg/status | LC_ALL=C sort -rn'
@@ -6,12 +6,12 @@ argv0=$0; argv0abs="$(readlink -fn "$argv0")"; argv0dir="$(dirname "$argv0abs")"
# run an interactive shell in the image # run an interactive shell in the image
# using a rootless Podman container # using a rootless Podman container
image=upx-stubtools-20221212-v4 image="$("$argv0dir/10-create-image.sh" --print-image)"
flags=( -ti --read-only --rm ) flags=( --read-only --rm --pull=never )
flags+=( --cap-drop=all ) # drop all capabilities flags+=( --cap-drop=all ) # drop all capabilities
flags+=( --network=none ) # no network needed flags+=( --network=none ) # no network needed
flags+=( -e TERM="$TERM" ) # pass $TERM flags+=( -ti -e TERM="$TERM" ) # allocate an interactive pseudo-tty and pass $TERM
if [[ 1 == 1 ]]; then if [[ 1 == 1 ]]; then
# run as user upx 2000:2000 # run as user upx 2000:2000
flags+=( --user 2000 ) flags+=( --user 2000 )
@@ -21,8 +21,10 @@ if [[ 1 == 1 ]]; then
flags+=( --gidmap=0:1:1000 --gidmap=2000:0:1 ) flags+=( --gidmap=0:1:1000 --gidmap=2000:0:1 )
# NOTE: we mount the upx top-level directory read-write under /home/upx/src/upx # NOTE: we mount the upx top-level directory read-write under /home/upx/src/upx
# INFO: SELinux users *may* have to add ":z" to the volume mount flags; check the docs! # INFO: SELinux users *may* have to add ":z" to the volume mount flags; check the docs!
flags+=( -v "${argv0dir}/../..:/home/upx/src/upx" ) flags+=( -v "${argv0dir}/../../..:/home/upx/src/upx" )
flags+=( -w /home/upx/src/upx ) # set working directory flags+=( -w /home/upx/src/upx ) # set working directory
flags+=( --tmpfs /home/upx/.cache:rw,exec ) # mount a writeable tmpfs
flags+=( --tmpfs /home/upx/.local:rw,exec ) # mount a writeable tmpfs
else else
# run as user root 0:0 # run as user root 0:0
# ONLY FOR DEBUGGING THE IMAGE # ONLY FOR DEBUGGING THE IMAGE
@@ -30,7 +32,11 @@ else
flags+=( --user 0 ) flags+=( --user 0 )
fi fi
podman run "${flags[@]}" "$image" bash -l if [[ $# == 0 ]]; then
podman run "${flags[@]}" "$image" bash -l
else
podman run "${flags[@]}" "$image" "$@"
fi
# now we can rebuild the UPX stubs: # now we can rebuild the UPX stubs:
# cd /home/upx/src/upx/src/stub # cd /home/upx/src/upx/src/stub
+64
View File
@@ -0,0 +1,64 @@
FROM docker.io/library/ubuntu:22.04
ENV UPX_CONTAINER_IMAGE_NAME=upx-stubtools-20221212-v6
ARG DEBIAN_FRONTEND=noninteractive
ENV LANG=C.UTF-8
# install system packages
RUN dpkg --add-architecture i386 \
&& apt-get update && apt-get upgrade -y \
&& apt-get install -y --no-install-recommends \
aria2 bash bash-completion ca-certificates dash git less libmpc3 libncurses5 \
make ncurses-term perl-base python2-minimal time wget xz-utils \
libc6:i386 zlib1g: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 bfs busybox bzip2 cabextract ccache chrpath cmake cpio curl elfutils fd-find file fzf \
g++ gawk gdb gojq ht htop hyperfine jq libzstd-dev lsb-release lz4 lzip lzop \
mksh moreutils ninja-build p7zip parallel patch patchelf pax-utils paxctl \
re2c ripgrep rsync screen universal-ctags unzip vim yash zip zlib1g-dev zsh zstd \
# extra packages for compiling with "gcc -m32" and and "gcc -mx32":
g++-multilib gcc-multilib \
&& true
# manually unpack and install compat libs from Ubuntu-16.04; REQUIRED
RUN cd /root \
&& aria2c --checksum=sha-256=de22baf3dd851a10e16fbf66a243e70149ca46e06b2939fdc79429196cefc090 \
'https://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/ \
&& rm -rf ./*.deb ./packages \
&& ldconfig \
&& true
# install upx-stubtools into /usr/local/bin/bin-upx-20221212; REQUIRED
RUN cd /root \
&& 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-20221212.tar.xz \
&& rm /root/bin-upx-20221212.tar.xz \
&& true
# 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 \
&& for v in 3.92 3.93 3.94 3.95 3.96 4.0.0 4.0.1 4.0.2 4.1.0; 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 \
&& for v in 3.91 3.92 3.93 3.94 3.95 3.96 4.0.0 4.0.1 4.0.2 4.1.0; 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:upx 2000:2000
RUN useradd upx -U --uid 2000 --shell /bin/bash -m \
&& cd /home/upx && chmod 00700 . \
# prepare ~/.cache and ~/.local for possible tmpfs mounts
&& mkdir -p .cache/tmp .local/bin src/upx \
&& for d in ccache fontconfig go-build mesa_shader_cache tmp wine zig; do mkdir -p .cache/$d; done \
&& for d in bin include lib share state; do mkdir -p .local/$d; done \
&& ln -s .cache/wine .wine && ln -s .cache/tmp tmp \
&& ln -s /usr/local/bin/bin-upx-20221212 .local/bin/bin-upx \
&& chown -R upx:upx . \
&& true
USER upx
+651
View File
@@ -0,0 +1,651 @@
Packages:
+++-===========================-=======================================-============-================================================================================
Desired=Unknown/Install/Remove/Purge/Hold
ii 7zip 21.07+dfsg-4 amd64 7-Zip file archiver with a high compression ratio
ii adduser 3.118ubuntu5 all add and remove users and groups
ii apt 2.4.9 amd64 commandline package manager
ii aria2 1.36.0-1 amd64 High speed download utility
ii base-files 12ubuntu4.3 amd64 Debian base system miscellaneous files
ii base-passwd 3.5.52build1 amd64 Debian base system master password and group files
ii bash 5.1-6ubuntu1 amd64 GNU Bourne Again SHell
ii bash-completion 1:2.11-5ubuntu1 all programmable completion for the bash shell
ii bfs 2.3.1-1 amd64 Breadth-first version of find(1)
ii binutils 2.38-4ubuntu2.2 amd64 GNU assembler, linker and binary utilities
ii binutils-common:amd64 2.38-4ubuntu2.2 amd64 Common files for the GNU assembler, linker and binary utilities
ii binutils-x86-64-linux-gnu 2.38-4ubuntu2.2 amd64 GNU binary utilities, for x86-64-linux-gnu target
ii bsdutils 1:2.37.2-4ubuntu3 amd64 basic utilities from 4.4BSD-Lite
ii busybox 1:1.30.1-7ubuntu3 amd64 Tiny utilities for small and embedded systems
ii bzip2 1.0.8-5build1 amd64 high-quality block-sorting file compressor - utilities
ii ca-certificates 20230311ubuntu0.22.04.1 all Common CA certificates
ii cabextract 1.9-3 amd64 Microsoft Cabinet file unpacker
ii ccache 4.5.1-1 amd64 Compiler cache for fast recompilation of C/C++ code
ii chrpath 0.16-2 amd64 Tool to edit the rpath in ELF binaries
ii cmake 3.22.1-1ubuntu1.22.04.1 amd64 cross-platform, open-source make system
ii cmake-data 3.22.1-1ubuntu1.22.04.1 all CMake data files (modules, templates and documentation)
ii coreutils 8.32-4.1ubuntu1 amd64 GNU core utilities
ii cpio 2.13+dfsg-7 amd64 GNU cpio -- a program to manage archives of files
ii cpp 4:11.2.0-1ubuntu1 amd64 GNU C preprocessor (cpp)
ii cpp-11 11.3.0-1ubuntu1~22.04.1 amd64 GNU C preprocessor
ii curl 7.81.0-1ubuntu1.13 amd64 command line tool for transferring data with URL syntax
ii dash 0.5.11+git20210903+057cd650a4ed-3build1 amd64 POSIX-compliant shell
ii debconf 1.5.79ubuntu1 all Debian configuration management system
ii debianutils 5.5-1ubuntu2 amd64 Miscellaneous utilities specific to Debian
ii dh-elpa-helper 2.0.9ubuntu1 all helper package for emacs lisp extensions
ii diffutils 1:3.8-0ubuntu2 amd64 File comparison utilities
ii distro-info-data 0.52ubuntu0.4 all information about the distributions' releases (data files)
ii dpkg 1.21.1ubuntu2.2 amd64 Debian package management system
ii e2fsprogs 1.46.5-2ubuntu1.1 amd64 ext2/ext3/ext4 file system utilities
ii elfutils 0.186-1build1 amd64 collection of utilities to handle ELF objects
ii emacsen-common 3.0.4 all Common facilities for all emacsen
ii fd-find 8.3.1-1ubuntu0.1 amd64 Simple, fast and user-friendly alternative to find
ii file 1:5.41-3 amd64 Recognize the type of data in a file using "magic" numbers
ii findutils 4.8.0-1ubuntu3 amd64 utilities for finding files--find, xargs
ii fzf 0.29.0-1 amd64 general-purpose command-line fuzzy finder
ii g++ 4:11.2.0-1ubuntu1 amd64 GNU C++ compiler
ii g++-11 11.3.0-1ubuntu1~22.04.1 amd64 GNU C++ compiler
ii g++-11-multilib 11.3.0-1ubuntu1~22.04.1 amd64 GNU C++ compiler (multilib support)
ii g++-multilib 4:11.2.0-1ubuntu1 amd64 GNU C++ compiler (multilib files)
ii gawk 1:5.1.0-1build3 amd64 GNU awk, a pattern scanning and processing language
ii gcc 4:11.2.0-1ubuntu1 amd64 GNU C compiler
ii gcc-11 11.3.0-1ubuntu1~22.04.1 amd64 GNU C compiler
ii gcc-11-base:amd64 11.3.0-1ubuntu1~22.04.1 amd64 GCC, the GNU Compiler Collection (base package)
ii gcc-11-multilib 11.3.0-1ubuntu1~22.04.1 amd64 GNU C compiler (multilib support)
ii gcc-12-base:amd64 12.1.0-2ubuntu1~22.04 amd64 GCC, the GNU Compiler Collection (base package)
ii gcc-12-base:i386 12.1.0-2ubuntu1~22.04 i386 GCC, the GNU Compiler Collection (base package)
ii gcc-multilib 4:11.2.0-1ubuntu1 amd64 GNU C compiler (multilib files)
ii gdb 12.1-0ubuntu1~22.04 amd64 GNU Debugger
ii git 1:2.34.1-1ubuntu1.9 amd64 fast, scalable, distributed revision control system
ii git-man 1:2.34.1-1ubuntu1.9 all fast, scalable, distributed revision control system (manual pages)
ii gojq 0.12.6-1 amd64 pure Go implementation of jq (program)
ii gpgv 2.2.27-3ubuntu2.1 amd64 GNU privacy guard - signature verification tool
ii grep 3.7-1build1 amd64 GNU grep, egrep and fgrep
ii gzip 1.10-4ubuntu4.1 amd64 GNU compression utilities
ii hostname 3.23ubuntu2 amd64 utility to set/show the host name or domain name
ii ht 2.1.0+repack1-5 amd64 Viewer/editor/analyser (mostly) for executables
ii htop 3.0.5-7build2 amd64 interactive processes viewer
ii hyperfine 1.12.0-3ubuntu0.1 amd64 Command-line benchmarking tool
ii init-system-helpers 1.62 all helper tools for all init systems
ii jq 1.6-2.1ubuntu3 amd64 lightweight and flexible command-line JSON processor
ii less 590-1ubuntu0.22.04.1 amd64 pager program similar to more
ii lib32asan6 11.3.0-1ubuntu1~22.04.1 amd64 AddressSanitizer -- a fast memory error detector (32bit)
ii lib32atomic1 12.1.0-2ubuntu1~22.04 amd64 support library providing __atomic built-in functions (32bit)
ii lib32gcc-11-dev 11.3.0-1ubuntu1~22.04.1 amd64 GCC support library (32 bit development files)
ii lib32gcc-s1 12.1.0-2ubuntu1~22.04 amd64 GCC support library (32 bit Version)
ii lib32gomp1 12.1.0-2ubuntu1~22.04 amd64 GCC OpenMP (GOMP) support library (32bit)
ii lib32itm1 12.1.0-2ubuntu1~22.04 amd64 GNU Transactional Memory Library (32bit)
ii lib32quadmath0 12.1.0-2ubuntu1~22.04 amd64 GCC Quad-Precision Math Library (32bit)
ii lib32stdc++-11-dev 11.3.0-1ubuntu1~22.04.1 amd64 GNU Standard C++ Library v3 (development files)
ii lib32stdc++6 12.1.0-2ubuntu1~22.04 amd64 GNU Standard C++ Library v3 (32 bit Version)
ii lib32ubsan1 12.1.0-2ubuntu1~22.04 amd64 UBSan -- undefined behaviour sanitizer (32bit)
ii libacl1:amd64 2.3.1-1 amd64 access control list - shared library
ii libapt-pkg6.0:amd64 2.4.9 amd64 package management runtime library
ii libarchive13:amd64 3.6.0-1ubuntu1 amd64 Multi-format archive and compression library (shared library)
ii libaria2-0:amd64 1.36.0-1 amd64 C++ library interface to aria2
ii libasan6:amd64 11.3.0-1ubuntu1~22.04.1 amd64 AddressSanitizer -- a fast memory error detector
ii libasm1:amd64 0.186-1build1 amd64 library with a programmable assembler interface
ii libatomic1:amd64 12.1.0-2ubuntu1~22.04 amd64 support library providing __atomic built-in functions
ii libattr1:amd64 1:2.5.1-1build1 amd64 extended attribute handling - shared library
ii libaudit-common 1:3.0.7-1build1 all Dynamic library for security auditing - common files
ii libaudit1:amd64 1:3.0.7-1build1 amd64 Dynamic library for security auditing
ii libbabeltrace1:amd64 1.5.8-2build1 amd64 Babeltrace conversion libraries
ii libbinutils:amd64 2.38-4ubuntu2.2 amd64 GNU binary utilities (private shared library)
ii libblkid1:amd64 2.37.2-4ubuntu3 amd64 block device ID library
ii libboost-regex1.74.0:amd64 1.74.0-14ubuntu3 amd64 regular expression library for C++
ii libbrotli1:amd64 1.0.9-2build6 amd64 library implementing brotli encoder and decoder (shared libraries)
ii libbsd0:amd64 0.11.5-1 amd64 utility functions from BSD systems - shared library
ii libbz2-1.0:amd64 1.0.8-5build1 amd64 high-quality block-sorting file compressor library - runtime
ii libc-ares2:amd64 1.18.1-1ubuntu0.22.04.2 amd64 asynchronous name resolver
ii libc-bin 2.35-0ubuntu3.1 amd64 GNU C Library: Binaries
ii libc-dev-bin 2.35-0ubuntu3.1 amd64 GNU C Library: Development binaries
ii libc6-dev-i386 2.35-0ubuntu3.1 amd64 GNU C Library: 32-bit development libraries for AMD64
ii libc6-dev-x32 2.35-0ubuntu3.1 amd64 GNU C Library: X32 ABI Development Libraries for AMD64
ii libc6-dev:amd64 2.35-0ubuntu3.1 amd64 GNU C Library: Development Libraries and Header Files
ii libc6-i386 2.35-0ubuntu3.1 amd64 GNU C Library: 32-bit shared libraries for AMD64
ii libc6-x32 2.35-0ubuntu3.1 amd64 GNU C Library: X32 ABI Shared libraries for AMD64
ii libc6:amd64 2.35-0ubuntu3.1 amd64 GNU C Library: Shared libraries
ii libc6:i386 2.35-0ubuntu3.1 i386 GNU C Library: Shared libraries
ii libcap-ng0:amd64 0.7.9-2.2build3 amd64 An alternate POSIX capabilities library
ii libcap2:amd64 1:2.44-1ubuntu0.22.04.1 amd64 POSIX 1003.1e capabilities (library)
ii libcc1-0:amd64 12.1.0-2ubuntu1~22.04 amd64 GCC cc1 plugin for GDB
ii libcom-err2:amd64 1.46.5-2ubuntu1.1 amd64 common error description library
ii libcrypt-dev:amd64 1:4.4.27-1 amd64 libcrypt development files
ii libcrypt1:amd64 1:4.4.27-1 amd64 libcrypt shared library
ii libcrypt1:i386 1:4.4.27-1 i386 libcrypt shared library
ii libctf-nobfd0:amd64 2.38-4ubuntu2.2 amd64 Compact C Type Format library (runtime, no BFD dependency)
ii libctf0:amd64 2.38-4ubuntu2.2 amd64 Compact C Type Format library (runtime, BFD dependency)
ii libcurl3-gnutls:amd64 7.81.0-1ubuntu1.13 amd64 easy-to-use client-side URL transfer library (GnuTLS flavour)
ii libcurl4:amd64 7.81.0-1ubuntu1.13 amd64 easy-to-use client-side URL transfer library (OpenSSL flavour)
ii libdb5.3:amd64 5.3.28+dfsg1-0.8ubuntu3 amd64 Berkeley v5.3 Database Libraries [runtime]
ii libdebconfclient0:amd64 0.261ubuntu1 amd64 Debian Configuration Management System (C-implementation library)
ii libdebuginfod-common 0.186-1build1 all configuration to enable the Debian debug info server
ii libdebuginfod1:amd64 0.186-1build1 amd64 library to interact with debuginfod (development files)
ii libdw1:amd64 0.186-1build1 amd64 library that provides access to the DWARF debug information
ii libelf1:amd64 0.186-1build1 amd64 library to read and write ELF files
ii liberror-perl 0.17029-1 all Perl module for error/exception handling in an OO-ish way
ii libexpat1:amd64 2.4.7-1ubuntu0.2 amd64 XML parsing C library - runtime library
ii libext2fs2:amd64 1.46.5-2ubuntu1.1 amd64 ext2/ext3/ext4 file system libraries
ii libffi8:amd64 3.4.2-4 amd64 Foreign Function Interface library runtime
ii libgcc-11-dev:amd64 11.3.0-1ubuntu1~22.04.1 amd64 GCC support library (development files)
ii libgcc-s1:amd64 12.1.0-2ubuntu1~22.04 amd64 GCC support library
ii libgcc-s1:i386 12.1.0-2ubuntu1~22.04 i386 GCC support library
ii libgcrypt20:amd64 1.9.4-3ubuntu3 amd64 LGPL Crypto library - runtime library
ii libgdbm-compat4:amd64 1.23-1 amd64 GNU dbm database routines (legacy support runtime version)
ii libgdbm6:amd64 1.23-1 amd64 GNU dbm database routines (runtime version)
ii libglib2.0-0:amd64 2.72.4-0ubuntu2.2 amd64 GLib library of C routines
ii libgmp10:amd64 2:6.2.1+dfsg-3ubuntu1 amd64 Multiprecision arithmetic library
ii libgnutls30:amd64 3.7.3-4ubuntu1.2 amd64 GNU TLS library - main runtime library
ii libgomp1:amd64 12.1.0-2ubuntu1~22.04 amd64 GCC OpenMP (GOMP) support library
ii libgpg-error0:amd64 1.43-3 amd64 GnuPG development runtime library
ii libgpm2:amd64 1.20.7-10build1 amd64 General Purpose Mouse - shared library
ii libgssapi-krb5-2:amd64 1.19.2-2ubuntu0.2 amd64 MIT Kerberos runtime libraries - krb5 GSS-API Mechanism
ii libhiredis0.14:amd64 0.14.1-2 amd64 minimalistic C client library for Redis
ii libhogweed6:amd64 3.7.3-1build2 amd64 low level cryptographic library (public-key cryptos)
ii libicu70:amd64 70.1-2 amd64 International Components for Unicode
ii libidn2-0:amd64 2.3.2-2build1 amd64 Internationalized domain names (IDNA2008/TR46) library
ii libio-pty-perl 1:1.15-2build2 amd64 Perl module for pseudo tty IO
ii libipc-run-perl 20200505.0-1 all Perl module for running processes
ii libipt2 2.0.5-1 amd64 Intel Processor Trace Decoder Library
ii libisl23:amd64 0.24-2build1 amd64 manipulating sets and relations of integer points bounded by linear constraints
ii libitm1:amd64 12.1.0-2ubuntu1~22.04 amd64 GNU Transactional Memory Library
ii libjansson4:amd64 2.13.1-1.1build3 amd64 C library for encoding, decoding and manipulating JSON data
ii libjq1:amd64 1.6-2.1ubuntu3 amd64 lightweight and flexible command-line JSON processor - shared library
ii libjsoncpp25:amd64 1.9.5-3 amd64 library for reading and writing JSON for C++
ii libk5crypto3:amd64 1.19.2-2ubuntu0.2 amd64 MIT Kerberos runtime libraries - Crypto Library
ii libkeyutils1:amd64 1.6.1-2ubuntu3 amd64 Linux Key Management Utilities (library)
ii libkrb5-3:amd64 1.19.2-2ubuntu0.2 amd64 MIT Kerberos runtime libraries
ii libkrb5support0:amd64 1.19.2-2ubuntu0.2 amd64 MIT Kerberos runtime libraries - Support library
ii libldap-2.5-0:amd64 2.5.14+dfsg-0ubuntu0.22.04.2 amd64 OpenLDAP libraries
ii liblsan0:amd64 12.1.0-2ubuntu1~22.04 amd64 LeakSanitizer -- a memory leak detector (runtime)
ii liblz4-1:amd64 1.9.3-2build2 amd64 Fast LZ compression algorithm library - runtime
ii liblzma5:amd64 5.2.5-2ubuntu1 amd64 XZ-format compression library
ii liblzo2-2:amd64 2.10-2build3 amd64 data compression library
ii libmagic-mgc 1:5.41-3 amd64 File type determination library using "magic" numbers (compiled magic file)
ii libmagic1:amd64 1:5.41-3 amd64 Recognize the type of data in a file using "magic" numbers - library
ii libmd0:amd64 1.0.4-1build1 amd64 message digest functions from BSD systems - shared library
ii libmount1:amd64 2.37.2-4ubuntu3 amd64 device mounting library
ii libmpc3:amd64 1.2.1-2build1 amd64 multiple precision complex floating-point library
ii libmpdec3:amd64 2.5.1-2build2 amd64 library for decimal floating point arithmetic (runtime library)
ii libmpfr6:amd64 4.1.0-3build3 amd64 multiple precision floating-point computation
ii libmspack0:amd64 0.10.1-2build2 amd64 library for Microsoft compression formats (shared library)
ii libncurses5:amd64 6.3-2ubuntu0.1 amd64 shared libraries for terminal handling (legacy version)
ii libncurses6:amd64 6.3-2ubuntu0.1 amd64 shared libraries for terminal handling
ii libncursesw6:amd64 6.3-2ubuntu0.1 amd64 shared libraries for terminal handling (wide character support)
ii libnettle8:amd64 3.7.3-1build2 amd64 low level cryptographic library (symmetric and one-way cryptos)
ii libnghttp2-14:amd64 1.43.0-1build3 amd64 library implementing HTTP/2 protocol (shared library)
ii libnl-3-200:amd64 3.5.0-0.1 amd64 library for dealing with netlink sockets
ii libnl-genl-3-200:amd64 3.5.0-0.1 amd64 library for dealing with netlink sockets - generic netlink
ii libnsl-dev:amd64 1.3.0-2build2 amd64 libnsl development files
ii libnsl2:amd64 1.3.0-2build2 amd64 Public client interface for NIS(YP) and NIS+
ii libonig5:amd64 6.9.7.1-2build1 amd64 regular expressions library
ii libp11-kit0:amd64 0.24.0-6build1 amd64 library for loading and coordinating access to PKCS#11 modules - runtime
ii libpam-modules-bin 1.4.0-11ubuntu2.3 amd64 Pluggable Authentication Modules for PAM - helper binaries
ii libpam-modules:amd64 1.4.0-11ubuntu2.3 amd64 Pluggable Authentication Modules for PAM
ii libpam-runtime 1.4.0-11ubuntu2.3 all Runtime support for the PAM library
ii libpam0g:amd64 1.4.0-11ubuntu2.3 amd64 Pluggable Authentication Modules library
ii libpcre2-8-0:amd64 10.39-3ubuntu0.1 amd64 New Perl Compatible Regular Expression Library- 8 bit runtime files
ii libpcre3:amd64 2:8.39-13ubuntu0.22.04.1 amd64 Old Perl 5 Compatible Regular Expression Library - runtime files
ii libperl5.34:amd64 5.34.0-3ubuntu1.2 amd64 shared Perl library
ii libpopt0:amd64 1.18-3build1 amd64 lib for parsing cmdline parameters
ii libprocps8:amd64 2:3.3.17-6ubuntu2 amd64 library for accessing process information from /proc
ii libpsl5:amd64 0.21.0-1.2build2 amd64 Library for Public Suffix List (shared libraries)
ii libpython2.7-minimal:amd64 2.7.18-13ubuntu1.1 amd64 Minimal subset of the Python language (version 2.7)
ii libpython3-stdlib:amd64 3.10.6-1~22.04 amd64 interactive high-level object-oriented language (default python3 version)
ii libpython3.10-minimal:amd64 3.10.6-1~22.04.2ubuntu1.1 amd64 Minimal subset of the Python language (version 3.10)
ii libpython3.10-stdlib:amd64 3.10.6-1~22.04.2ubuntu1.1 amd64 Interactive high-level object-oriented language (standard library, version 3.10)
ii libpython3.10:amd64 3.10.6-1~22.04.2ubuntu1.1 amd64 Shared Python runtime library (version 3.10)
ii libquadmath0:amd64 12.1.0-2ubuntu1~22.04 amd64 GCC Quad-Precision Math Library
ii libreadline8:amd64 8.1.2-1 amd64 GNU readline and history libraries, run-time libraries
ii librhash0:amd64 1.4.2-1ubuntu1 amd64 shared library for hash functions computing
ii librtmp1:amd64 2.4+20151223.gitfa8646d.1-2build4 amd64 toolkit for RTMP streams (shared library)
ii libsasl2-2:amd64 2.1.27+dfsg2-3ubuntu1.2 amd64 Cyrus SASL - authentication abstraction library
ii libsasl2-modules-db:amd64 2.1.27+dfsg2-3ubuntu1.2 amd64 Cyrus SASL - pluggable authentication modules (DB)
ii libseccomp2:amd64 2.5.3-2ubuntu2 amd64 high level interface to Linux seccomp filter
ii libselinux1:amd64 3.3-1build2 amd64 SELinux runtime shared libraries
ii libsemanage-common 3.3-1build2 all Common files for SELinux policy management libraries
ii libsemanage2:amd64 3.3-1build2 amd64 SELinux policy management library
ii libsensors-config 1:3.6.0-7ubuntu1 all lm-sensors configuration files
ii libsensors5:amd64 1:3.6.0-7ubuntu1 amd64 library to read temperature/voltage/fan sensors
ii libsepol2:amd64 3.3-1build1 amd64 SELinux library for manipulating binary security policies
ii libsigsegv2:amd64 2.13-1ubuntu3 amd64 Library for handling page faults in a portable way
ii libsmartcols1:amd64 2.37.2-4ubuntu3 amd64 smart column output alignment library
ii libsodium23:amd64 1.0.18-1build2 amd64 Network communication, cryptography and signaturing library
ii libsource-highlight-common 3.1.9-4.1build2 all architecture-independent files for source highlighting library
ii libsource-highlight4v5 3.1.9-4.1build2 amd64 source highlighting library
ii libsqlite3-0:amd64 3.37.2-2ubuntu0.1 amd64 SQLite 3 shared library
ii libss2:amd64 1.46.5-2ubuntu1.1 amd64 command-line interface parsing library
ii libssh-4:amd64 0.9.6-2ubuntu0.22.04.1 amd64 tiny C SSH library (OpenSSL flavor)
ii libssh2-1:amd64 1.10.0-3 amd64 SSH2 client-side library
ii libssl3:amd64 3.0.2-0ubuntu1.10 amd64 Secure Sockets Layer toolkit - shared libraries
ii libstdc++-11-dev:amd64 11.3.0-1ubuntu1~22.04.1 amd64 GNU Standard C++ Library v3 (development files)
ii libstdc++6:amd64 12.1.0-2ubuntu1~22.04 amd64 GNU Standard C++ Library v3
ii libsystemd0:amd64 249.11-0ubuntu3.9 amd64 systemd utility library
ii libtasn1-6:amd64 4.18.0-4build1 amd64 Manage ASN.1 structures (runtime)
ii libtime-duration-perl 1.21-1 all module for rounded or exact English expression of durations
ii libtimedate-perl 2.3300-2 all collection of modules to manipulate date/time information
ii libtinfo5:amd64 6.3-2ubuntu0.1 amd64 shared low-level terminfo library (legacy version)
ii libtinfo6:amd64 6.3-2ubuntu0.1 amd64 shared low-level terminfo library for terminal handling
ii libtirpc-common 1.3.2-2ubuntu0.1 all transport-independent RPC library - common files
ii libtirpc-dev:amd64 1.3.2-2ubuntu0.1 amd64 transport-independent RPC library - development files
ii libtirpc3:amd64 1.3.2-2ubuntu0.1 amd64 transport-independent RPC library
ii libtsan0:amd64 11.3.0-1ubuntu1~22.04.1 amd64 ThreadSanitizer -- a Valgrind-based detector of data races (runtime)
ii libubsan1:amd64 12.1.0-2ubuntu1~22.04 amd64 UBSan -- undefined behaviour sanitizer (runtime)
ii libudev1:amd64 249.11-0ubuntu3.9 amd64 libudev shared library
ii libunistring2:amd64 1.0-1 amd64 Unicode string library for C
ii libutempter0:amd64 1.2.1-2build2 amd64 privileged helper for utmp/wtmp updates (runtime)
ii libuuid1:amd64 2.37.2-4ubuntu3 amd64 Universally Unique ID library
ii libuv1:amd64 1.43.0-1 amd64 asynchronous event notification library - runtime library
ii libx11-6:amd64 2:1.7.5-1ubuntu0.2 amd64 X11 client-side library
ii libx11-data 2:1.7.5-1ubuntu0.2 all X11 client-side library
ii libx32asan6 11.3.0-1ubuntu1~22.04.1 amd64 AddressSanitizer -- a fast memory error detector (x32)
ii libx32atomic1 12.1.0-2ubuntu1~22.04 amd64 support library providing __atomic built-in functions (x32)
ii libx32gcc-11-dev 11.3.0-1ubuntu1~22.04.1 amd64 GCC support library (x32 development files)
ii libx32gcc-s1 12.1.0-2ubuntu1~22.04 amd64 GCC support library (x32)
ii libx32gomp1 12.1.0-2ubuntu1~22.04 amd64 GCC OpenMP (GOMP) support library (x32)
ii libx32itm1 12.1.0-2ubuntu1~22.04 amd64 GNU Transactional Memory Library (x32)
ii libx32quadmath0 12.1.0-2ubuntu1~22.04 amd64 GCC Quad-Precision Math Library (x32)
ii libx32stdc++-11-dev 11.3.0-1ubuntu1~22.04.1 amd64 GNU Standard C++ Library v3 (development files)
ii libx32stdc++6 12.1.0-2ubuntu1~22.04 amd64 GNU Standard C++ Library v3 (x32)
ii libx32ubsan1 12.1.0-2ubuntu1~22.04 amd64 UBSan -- undefined behaviour sanitizer (x32)
ii libxau6:amd64 1:1.0.9-1build5 amd64 X11 authorisation library
ii libxcb1:amd64 1.14-3ubuntu3 amd64 X C Binding
ii libxdmcp6:amd64 1:1.1.3-0ubuntu5 amd64 X11 Display Manager Control Protocol library
ii libxml2:amd64 2.9.13+dfsg-1ubuntu0.3 amd64 GNOME XML library
ii libxxhash0:amd64 0.8.1-1 amd64 shared library for xxhash
ii libyaml-0-2:amd64 0.2.2-1build2 amd64 Fast YAML 1.1 parser and emitter library
ii libzstd-dev:amd64 1.4.8+dfsg-3build1 amd64 fast lossless compression algorithm -- development files
ii libzstd1:amd64 1.4.8+dfsg-3build1 amd64 fast lossless compression algorithm
ii linux-libc-dev:amd64 5.15.0-76.83 amd64 Linux Kernel Headers for development
ii login 1:4.8.1-2ubuntu2.1 amd64 system login tools
ii logsave 1.46.5-2ubuntu1.1 amd64 save the output of a command in a log file
ii lsb-base 11.1.0ubuntu4 all Linux Standard Base init script functionality
ii lsb-release 11.1.0ubuntu4 all Linux Standard Base version reporting utility
ii lz4 1.9.3-2build2 amd64 Fast LZ compression algorithm library - tool
ii lzip 1.23-1 amd64 lossless data compressor based on the LZMA algorithm
ii lzop 1.04-2build2 amd64 fast compression program
ii make 4.3-4.1build1 amd64 utility for directing compilation
ii mawk 1.3.4.20200120-3 amd64 Pattern scanning and text processing language
ii media-types 7.0.0 all List of standard media types and their usual file extension
ii mksh 59c-16 amd64 MirBSD Korn Shell
ii moreutils 0.66-1 amd64 additional Unix utilities
ii mount 2.37.2-4ubuntu3 amd64 tools for mounting and manipulating filesystems
ii ncurses-base 6.3-2ubuntu0.1 all basic terminal type definitions
ii ncurses-bin 6.3-2ubuntu0.1 amd64 terminal-related programs and man pages
ii ncurses-term 6.3-2ubuntu0.1 all additional terminal type definitions
ii ninja-build 1.10.1-1 amd64 small build system closest in spirit to Make
ii openssl 3.0.2-0ubuntu1.10 amd64 Secure Sockets Layer toolkit - cryptographic utility
ii p7zip 16.02+dfsg-8 amd64 7zr file archiver with high compression ratio
ii parallel 20210822+ds-2 all build and execute command lines from standard input in parallel
ii passwd 1:4.8.1-2ubuntu2.1 amd64 change and administer password and group data
ii patch 2.7.6-7build2 amd64 Apply a diff file to an original
ii patchelf 0.14.3-1 amd64 modify properties of ELF executables
ii pax-utils 1.2.9-1 amd64 Security-focused ELF files checking tool
ii paxctl 0.9-1build1 amd64 new PaX control program for using the PT_PAX_FLAGS marking
ii perl 5.34.0-3ubuntu1.2 amd64 Larry Wall's Practical Extraction and Report Language
ii perl-base 5.34.0-3ubuntu1.2 amd64 minimal Perl system
ii perl-modules-5.34 5.34.0-3ubuntu1.2 all Core Perl modules
ii procps 2:3.3.17-6ubuntu2 amd64 /proc file system utilities
ii python2-minimal 2.7.18-3 amd64 minimal subset of the Python2 language
ii python2.7-minimal 2.7.18-13ubuntu1.1 amd64 Minimal subset of the Python language (version 2.7)
ii python3 3.10.6-1~22.04 amd64 interactive high-level object-oriented language (default python3 version)
ii python3-minimal 3.10.6-1~22.04 amd64 minimal subset of the Python language (default python3 version)
ii python3.10 3.10.6-1~22.04.2ubuntu1.1 amd64 Interactive high-level object-oriented language (version 3.10)
ii python3.10-minimal 3.10.6-1~22.04.2ubuntu1.1 amd64 Minimal subset of the Python language (version 3.10)
ii re2c 3.0-1 amd64 lexer generator for C, C++, Go and Rust
ii readline-common 8.1.2-1 all GNU readline and history libraries, common files
ii ripgrep 13.0.0-2ubuntu0.1 amd64 Recursively searches directories for a regex pattern
ii rpcsvc-proto 1.4.2-0ubuntu6 amd64 RPC protocol compiler and definitions
ii rsync 3.2.7-0ubuntu0.22.04.2 amd64 fast, versatile, remote (and local) file-copying tool
ii screen 4.9.0-1 amd64 terminal multiplexer with VT100/ANSI terminal emulation
ii sed 4.8-1ubuntu2 amd64 GNU stream editor for filtering/transforming text
ii sensible-utils 0.0.17 all Utilities for sensible alternative selection
ii sysstat 12.5.2-2ubuntu0.2 amd64 system performance tools for Linux
ii sysvinit-utils 3.01-1ubuntu1 amd64 System-V-like utilities
ii tar 1.34+dfsg-1ubuntu0.1.22.04.1 amd64 GNU version of the tar archiving utility
ii time 1.9-0.1build2 amd64 GNU time program for measuring CPU resource usage
ii ubuntu-keyring 2021.03.26 all GnuPG keys of the Ubuntu archive
ii ucf 3.0043 all Update Configuration File(s): preserve user changes to config files
ii universal-ctags 5.9.20210829.0-1 amd64 build tag file indexes of source code definitions
ii unzip 6.0-26ubuntu3.1 amd64 De-archiver for .zip files
ii usrmerge 25ubuntu2 all Convert the system to the merged /usr directories scheme
ii util-linux 2.37.2-4ubuntu3 amd64 miscellaneous system utilities
ii vim 2:8.2.3995-1ubuntu2.9 amd64 Vi IMproved - enhanced vi editor
ii vim-common 2:8.2.3995-1ubuntu2.9 all Vi IMproved - Common files
ii vim-runtime 2:8.2.3995-1ubuntu2.9 all Vi IMproved - Runtime files
ii wget 1.21.2-2ubuntu1 amd64 retrieves files from the web
ii xxd 2:8.2.3995-1ubuntu2.9 amd64 tool to make (or reverse) a hex dump
ii xz-utils 5.2.5-2ubuntu1 amd64 XZ-format compression utilities
ii yash 2.51-1 amd64 yet another shell
ii zip 3.0-12build2 amd64 Archiver for .zip files
ii zlib1g-dev:amd64 1:1.2.11.dfsg-2ubuntu9.2 amd64 compression library - development
ii zlib1g:amd64 1:1.2.11.dfsg-2ubuntu9.2 amd64 compression library - runtime
ii zlib1g:i386 1:1.2.11.dfsg-2ubuntu9.2 i386 compression library - runtime
ii zsh 5.8.1-1 amd64 shell with lots of features
ii zsh-common 5.8.1-1 all architecture independent files for Zsh
ii zstd 1.4.8+dfsg-3build1 amd64 fast lossless compression algorithm -- CLI tool
| Status=Not/Inst/Conf-files/Unpacked/halF-conf/Half-inst/trig-aWait/Trig-pend
|/ Err?=(none)/Reinst-required (Status,Err: uppercase=bad)
||/ Name Version Architecture Description
Packages sorted by Installed-Size:
748809 ===== TOTAL (321 packages)
52577 gcc-11 amd64
34444 libicu70 amd64
32780 vim-runtime all
28795 g++-11 amd64
28441 libperl5.34 amd64
26212 cpp-11 amd64
20742 cmake amd64
18721 libstdc++-11-dev amd64
18468 git amd64
17671 perl-modules-5.34 all
15293 zsh-common all
13894 libgcc-11-dev amd64
13592 libc6 amd64
13037 libc6-dev amd64
12561 libc6-x32 amd64
12479 libc6 i386
12200 libc6-i386 amd64
11311 gdb amd64
10876 lib32stdc++-11-dev amd64
10439 binutils-x86-64-linux-gnu amd64
10391 libx32stdc++-11-dev amd64
9866 cmake-data all
8248 libc6-dev-x32 amd64
8040 libpython3.10-stdlib amd64
7947 lib32gcc-11-dev amd64
7730 perl-base amd64
7518 libasan6 amd64
7261 libc6-dev-i386 amd64
7255 libtsan0 amd64
7127 libmagic-mgc amd64
7112 coreutils amd64
6988 libx32gcc-11-dev amd64
6734 linux-libc-dev amd64
6733 dpkg amd64
6659 lib32asan6 amd64
6570 libx32asan6 amd64
5902 python3.10-minimal amd64
5824 libssl3 amd64
5780 libpython3.10 amd64
5093 libpython3.10-minimal amd64
4249 ncurses-term all
4156 apt amd64
4147 ripgrep amd64
4082 libglib2.0-0 amd64
3923 vim amd64
3643 python2.7-minimal amd64
3506 re2c amd64
3487 gojq amd64
3405 libmpfr6 amd64
3399 util-linux amd64
3347 libaria2-0 amd64
3181 libapt-pkg6.0 amd64
3013 libboost-regex1.74.0 amd64
2961 liblsan0 amd64
2943 parallel all
2801 elfutils amd64
2784 libpython2.7-minimal amd64
2776 libbinutils amd64
2746 libstdc++6 amd64
2675 libubsan1 amd64
2662 lib32stdc++6 amd64
2537 libc-bin amd64
2518 libx32ubsan1 amd64
2510 fd-find amd64
2500 lib32ubsan1 amd64
2468 zsh amd64
2438 libx32stdc++6 amd64
2428 fzf amd64
2396 7zip amd64
2325 passwd amd64
2284 libgnutls30 amd64
2191 ht amd64
2159 libisl23 amd64
2097 libxml2 amd64
2053 openssl amd64
2009 universal-ctags amd64
1959 git-man all
1864 bash amd64
1854 aria2 amd64
1750 libdb5.3 amd64
1746 libunistring2 amd64
1680 gawk amd64
1655 zstd amd64
1602 libsqlite3-0 amd64
1516 e2fsprogs amd64
1508 mksh amd64
1472 sysstat amd64
1464 bash-completion all
1445 hyperfine amd64
1429 yash amd64
1429 libx11-data all
1388 procps amd64
1386 libx11-6 amd64
1354 libgcrypt20 amd64
1343 ccache amd64
1328 libzstd-dev amd64
1292 libp11-kit0 amd64
1138 libpam-modules amd64
1052 libkrb5-3 amd64
1005 screen amd64
995 libsystemd0 amd64
990 p7zip amd64
984 wget amd64
960 tar amd64
888 login amd64
876 libarchive13 amd64
846 libzstd1 amd64
794 rsync amd64
791 busybox amd64
787 libcurl4 amd64
784 libbrotli1 amd64
771 libcurl3-gnutls amd64
735 libsepol2 amd64
729 libdw1 amd64
720 libtirpc-dev amd64
717 perl amd64
686 lib32quadmath0 amd64
683 libpcre3 amd64
646 ncurses-bin amd64
621 libpcre2-8-0 amd64
620 python3.10 amd64
620 findutils amd64
615 libonig5 amd64
610 libsource-highlight4v5 amd64
608 adduser all
592 zlib1g-dev amd64
574 libext2fs2 amd64
565 libldap-2.5-0 amd64
558 libtinfo6 amd64
544 libtinfo5 amd64
544 libgmp10 amd64
531 zip amd64
512 debconf all
504 binutils-common amd64
502 libbabeltrace1 amd64
496 grep amd64
486 libssh-4 amd64
461 libreadline8 amd64
455 libgssapi-krb5-2 amd64
443 curl amd64
433 libexpat1 amd64
424 diffutils amd64
422 libncursesw6 amd64
416 make amd64
402 libsodium23 amd64
394 base-files amd64
393 ncurses-base all
390 ca-certificates all
389 mount amd64
382 libmount1 amd64
379 vim-common all
376 unzip amd64
372 xz-utils amd64
368 libssh2-1 amd64
356 libnettle8 amd64
350 ninja-build amd64
347 libudev1 amd64
347 libnsl-dev amd64
347 libjq1 amd64
336 libhogweed6 amd64
334 lib32gomp1 amd64
334 htop amd64
334 bsdutils amd64
329 libncurses6 amd64
328 sed amd64
324 gpgv amd64
324 cpio amd64
323 libblkid1 amd64
321 less amd64
320 libgomp1 amd64
320 libcrypt-dev amd64
318 libncurses5 amd64
312 libpam-runtime all
312 libctf-nobfd0 amd64
307 libsource-highlight-common all
306 libx32gomp1 amd64
300 libsemanage2 amd64
298 libc-dev-bin amd64
296 libquadmath0 amd64
292 libk5crypto3 amd64
291 libx32quadmath0 amd64
290 pax-utils amd64
290 liblzma5 amd64
277 xxd amd64
271 gcc-11-base amd64
266 gcc-12-base i386
266 gcc-12-base amd64
252 libuv1 amd64
252 libipc-run-perl all
252 libcrypt1 i386
250 libmpdec3 amd64
248 libpam-modules-bin amd64
245 rpcsvc-proto amd64
243 debianutils amd64
243 base-passwd amd64
240 moreutils amd64
240 gzip amd64
239 libctf0 amd64
235 libpam0g amd64
235 libjsoncpp25 amd64
232 ucf all
230 lz4 amd64
229 patch amd64
229 mawk amd64
228 libmagic1 amd64
225 libcrypt1 amd64
221 bfs amd64
220 libidn2-0 amd64
219 libtirpc3 amd64
219 librhash0 amd64
214 dash amd64
209 libsmartcols1 amd64
207 libselinux1 amd64
206 libxcb1 amd64
203 libnghttp2-14 amd64
200 usrmerge all
192 libelf1 amd64
189 libgpg-error0 amd64
182 patchelf amd64
180 libnl-3-200 amd64
171 zlib1g i386
170 libsasl2-2 amd64
167 libgcc-s1 i386
164 zlib1g amd64
164 libkrb5support0 amd64
163 lib32gcc-s1 amd64
161 lzip amd64
159 lzop amd64
159 liblzo2-2 amd64
156 libaudit1 amd64
145 libseccomp2 amd64
145 liblz4-1 amd64
144 libyaml-0-2 amd64
144 libcc1-0 amd64
141 librtmp1 amd64
140 libgcc-s1 amd64
136 libbsd0 amd64
135 libx32gcc-s1 amd64
134 libuuid1 amd64
133 libtasn1-6 amd64
133 init-system-helpers all
132 libipt2 amd64
131 libprocps8 amd64
126 time amd64
125 libmpc3 amd64
123 libtimedate-perl all
123 libnsl2 amd64
122 python3-minimal amd64
120 libpopt0 amd64
115 libitm1 amd64
114 bzip2 amd64
113 libss2 amd64
113 lib32itm1 amd64
112 libc-ares2 amd64
112 binutils amd64
110 libio-pty-perl amd64
105 python2-minimal amd64
105 libx32itm1 amd64
101 libcom-err2 amd64
100 libgdbm6 amd64
100 libbz2-1.0 amd64
100 jq amd64
97 media-types all
97 logsave amd64
97 libxxhash0 amd64
96 libsensors5 amd64
96 libmspack0 amd64
95 libpsl5 amd64
93 libsasl2-modules-db amd64
92 libhiredis0.14 amd64
91 libjansson4 amd64
90 python3 amd64
83 sysvinit-utils amd64
83 file amd64
82 cabextract amd64
80 readline-common all
79 libdebconfclient0 amd64
74 libasm1 amd64
71 libmd0 amd64
71 liberror-perl all
69 libffi8 amd64
67 libacl1 amd64
67 cpp amd64
66 lsb-release all
65 libgpm2 amd64
65 libdebuginfod1 amd64
65 libcap2 amd64
62 emacsen-common all
61 libnl-genl-3-200 amd64
59 sensible-utils all
58 lsb-base all
57 libattr1 amd64
51 libutempter0 amd64
51 hostname amd64
50 gcc amd64
49 libsigsegv2 amd64
47 libkeyutils1 amd64
45 libgdbm-compat4 amd64
45 libcap-ng0 amd64
45 libatomic1 amd64
43 libxdmcp6 amd64
43 libx32atomic1 amd64
42 libsensors-config all
41 ubuntu-keyring all
41 libdebuginfod-common all
39 libpython3-stdlib amd64
39 lib32atomic1 amd64
37 libsemanage-common all
37 chrpath amd64
35 libxau6 amd64
35 libtime-duration-perl all
32 libtirpc-common all
30 paxctl amd64
27 dh-elpa-helper all
23 libaudit-common all
20 distro-info-data all
16 g++ amd64
8 gcc-multilib amd64
6 gcc-11-multilib amd64
6 g++-multilib amd64
6 g++-11-multilib amd64
-58
View File
@@ -1,58 +0,0 @@
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
# install system packages
RUN dpkg --add-architecture i386 \
&& apt-get update && apt-get upgrade -y \
&& apt-get install -y --no-install-recommends \
aria2 ca-certificates git less libmpc3 libncurses5 make \
ncurses-term perl-base python2-minimal wget xz-utils \
libc6:i386 zlib1g: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 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=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/ \
&& rm -rf ./*.deb ./packages \
&& ldconfig \
&& true
# install upx-stubtools into /usr/local/bin/bin-upx-20221212; REQUIRED
RUN cd /root \
&& 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-20221212.tar.xz \
&& rm /root/bin-upx-20221212.tar.xz \
&& true
# 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 \
&& 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 \
&& 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/.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
+127
View File
@@ -0,0 +1,127 @@
#! /bin/sh
## vim:set ts=4 sw=4 et:
set -e
#
# build UPX "by hand", using a POSIX-compliant shell and
# a minimal number of compilation flags
# Copyright (C) Markus Franz Xaver Johannes Oberhumer
#
# uses optional environment variables: AR, CC, CXX, OPTIMIZE, top_srcdir
# shell init
### set -x # enable logging
DUALCASE=1; export DUALCASE # for MKS sh
test -n "${ZSH_VERSION+set}" && emulate sh # for zsh
my_argv0="$0"
# toolchain settings and compilation flags
AR="${AR:-ar}"
CC="${CC:-cc}"
CXX="${CXX:-c++ -std=gnu++17}"
# 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"
if test "x$OPTIMIZE" != "x" && test "x$OPTIMIZE" != "x0"; then
# not mandatory and not minimal, but usually a good idea:
mandatory_flags="-Wall -O2 $mandatory_flags"
fi
CC="$CC $mandatory_flags"
CXX="$CXX $mandatory_flags"
# go to upx top-level directory
# HINT: set "top_srcdir" manually if your system does not have "readlink"
if test "x$top_srcdir" = "x"; then
my_argv0abs="$(readlink -fn "$my_argv0")"
test "x$my_argv0abs" = "x" && exit 1
my_argv0dir="$(dirname "$my_argv0abs")"
test "x$my_argv0dir" = "x" && exit 1
cd "$my_argv0dir/../.." || exit 1
else
cd "$top_srcdir" || exit 1
fi
top_srcdir="$(pwd)" # absolute
rel_top_srcdir=. # relative top_srcdir
echo "# current directory: '$(pwd)'"
test -f doc/upx.pod || exit 1 # sanity check
test -f src/version.h || exit 1 # sanity check
rm -rf ./build/by-hand # WARNING: existing build-directory gets deleted!
# helper function
run() {
if test 0 = 1; then
# DEBUG dry-run: print command, but don't actually run unless $1 is "+"
if test "x$1" = "x+"; then
shift; echo "$@"; "$@"; return
fi
shift; echo "$@"; return
fi
# print short info and run command
test "x$1" != "x" && test "x$1" != "x+" && echo "$1"
shift; "$@"
}
# helper function
check_submodule() {
#local ff # "local" seems unsupported by some versions of ksh
for ff in COPYING LICENSE LICENSE.txt; do
if test -f "$rel_top_srcdir/vendor/$1/$ff"; then
# create and enter build directory; updates global $rel_top_srcdir
run "+" cd "$rel_top_srcdir" || exit 1
rel_top_srcdir=.
echo "#==== build $1 ====="
run "+" mkdir "build/by-hand/$1"
run "+" cd "build/by-hand/$1" || exit 1
rel_top_srcdir=../../..
return 0
fi
done
return 1
}
# build
run "+" mkdir -p "build/by-hand"
if check_submodule bzip2; then
for f in "$rel_top_srcdir"/vendor/bzip2/*.c; do
run "CC $f" $CC -c "$f"
done
fi
if check_submodule ucl; then
for f in "$rel_top_srcdir"/vendor/ucl/src/*.c; do
run "CC $f" $CC -I"$rel_top_srcdir"/vendor/ucl/include -I"$rel_top_srcdir"/vendor/ucl -c "$f"
done
fi
if check_submodule zlib; then
for f in "$rel_top_srcdir"/vendor/zlib/*.c; do
run "CC $f" $CC -DHAVE_UNISTD_H -DHAVE_VSNPRINTF -c "$f"
done
fi
if check_submodule zstd; then
for f in "$rel_top_srcdir"/vendor/zstd/lib/*/*.c; do
run "CC $f" $CC -DDYNAMIC_BMI2=0 -DZSTD_DISABLE_ASM -c "$f"
done
fi
run "+" cd "$rel_top_srcdir" || exit 1
rel_top_srcdir=.
echo "#==== build UPX ====="
run "+" cd "build/by-hand" || exit 1
rel_top_srcdir=../..
for f in "$rel_top_srcdir"/src/*.cpp "$rel_top_srcdir"/src/*/*.cpp; do
run "CXX $f" $CXX -I"$rel_top_srcdir"/vendor -c "$f"
done
# echo "#==== link UPX ====="
if test "x$AR" = "x"; then
# link without using $AR
run "CXX upx" $CXX -o upx *.o */*.o
else
run "AR libupx" $AR rcs libupx_submodules.a */*.o
run "CXX upx" $CXX -o upx *.o -L. -lupx_submodules
fi
echo "# current directory: '$(pwd)'"
ls -l upx*
echo "# All done."
@@ -0,0 +1,209 @@
########## begin .sha256sums.recreate
expected_sha256sums__t010_decompressed="\
24158f78c34c4ef94bb7773a6dda7231d289be76c2f5f60e8b9ddb3f800c100e *amd64-linux.elf/upx-3.91
24808d572483f4cd713d66894b3da406755038737007a78b076528e6407e3132 *amd64-linux.elf/upx-3.95
d88eaad0528bcecec9f51cbe015a117c8cf350a3f6d8308f2b0517d4fd19d189 *amd64-win64.pe/upx-3.95.exe
f7279729eb975e4238f8b8ee56fefa41ccbeb35ef0ffe4c34f8047baab78fff5 *arm-linux.elf/upx-3.95
e09df2a69f88c692138447f274ba7f99cdd11f8696c71ac8d3761606c95ab5c5 *arm-wince.pe/upx-3.91.exe
ce81113f8a4ff1cd806811cb80ab8bea5c9c6fbced47451c7f07e50700f9817b *arm64-linux.elf/upx-3.95
b1c1c38d50007616aaf8e942839648c80a6111023e0b411e5fa7a06c543aeb4a *armeb-linux.elf/upx-3.91
84b90eb0d617571fe4885639925b35ca6a61060cb2616bb5bf729b4d701653e4 *armeb-linux.elf/upx-3.95
bcac77a287289301a45fde9a75e4e6c9ad7f8d57856bae6eafaae12ae4445a34 *i386-dos32.djgpp2.coff/upx-3.91.exe
7d331e508449497f64cd47abdd3f00f70307f508ad3fd692d333feb97beccead *i386-dos32.djgpp2.coff/upx-3.95.exe
730a513b72a094697f827e4ac1a4f8ef58a614fc7a7ad448fa58d60cd89af7ed *i386-linux.elf/upx-3.91
a1f3e5ffa7b2cfebe1e475ac1f4c7683b1b8b4e292aa0d04386cc0314dd162c9 *i386-linux.elf/upx-3.95
e90fb09a808334c2674996760d42c82f8352e3f671f6b66c11481e772785c4d2 *i386-win32.pe/upx-3.91.exe
07bd50c1d80f6ff651228e6fc0ba3a583a472915772244f232696b34156a9d27 *i386-win32.pe/upx-3.95.exe
8e5333ea040f5594d3e67d5b09e005d52b3a52ef55099a7c11d7e39ead38e66d *m68k-atari.tos/upx-3.91.ttp
8902f38ec3d95d8e077e3ab5fdbb5bad408859913a35deb87041f4f053cd6605 *mips-linux.elf/upx-3.95
c3f44b4d00a87384c03a6f9e7aec809c1addfe3e271244d38a474f296603088c *mipsel-linux.elf/upx-3.91
dd1496bc4e9c32a5d5dd47e3eaabf7b134ca001d48807eebfd3d5e28c8a2ab58 *mipsel-linux.elf/upx-3.95
b8c35fa2956da17ca505956e9f5017bb5f3a746322647e24ccb8ff28059cafa4 *powerpc-linux.elf/upx-3.91
2bc00a51daa0bada19a8fa1bd2c227a8596844fa1b0aa3611087f195072700e2 *powerpc-linux.elf/upx-3.95
a0950546dc17fca9437219431d8ddb0249ce5b08e899e0c799a87ac982adee70 *powerpc64le-linux.elf/upx-3.95
"
expected_sha256sums__t020_canonicalized="\
24158f78c34c4ef94bb7773a6dda7231d289be76c2f5f60e8b9ddb3f800c100e *amd64-linux.elf/upx-3.91
24808d572483f4cd713d66894b3da406755038737007a78b076528e6407e3132 *amd64-linux.elf/upx-3.95
d88eaad0528bcecec9f51cbe015a117c8cf350a3f6d8308f2b0517d4fd19d189 *amd64-win64.pe/upx-3.95.exe
f7279729eb975e4238f8b8ee56fefa41ccbeb35ef0ffe4c34f8047baab78fff5 *arm-linux.elf/upx-3.95
e09df2a69f88c692138447f274ba7f99cdd11f8696c71ac8d3761606c95ab5c5 *arm-wince.pe/upx-3.91.exe
ce81113f8a4ff1cd806811cb80ab8bea5c9c6fbced47451c7f07e50700f9817b *arm64-linux.elf/upx-3.95
b1c1c38d50007616aaf8e942839648c80a6111023e0b411e5fa7a06c543aeb4a *armeb-linux.elf/upx-3.91
84b90eb0d617571fe4885639925b35ca6a61060cb2616bb5bf729b4d701653e4 *armeb-linux.elf/upx-3.95
bcac77a287289301a45fde9a75e4e6c9ad7f8d57856bae6eafaae12ae4445a34 *i386-dos32.djgpp2.coff/upx-3.91.exe
7d331e508449497f64cd47abdd3f00f70307f508ad3fd692d333feb97beccead *i386-dos32.djgpp2.coff/upx-3.95.exe
730a513b72a094697f827e4ac1a4f8ef58a614fc7a7ad448fa58d60cd89af7ed *i386-linux.elf/upx-3.91
a1f3e5ffa7b2cfebe1e475ac1f4c7683b1b8b4e292aa0d04386cc0314dd162c9 *i386-linux.elf/upx-3.95
e90fb09a808334c2674996760d42c82f8352e3f671f6b66c11481e772785c4d2 *i386-win32.pe/upx-3.91.exe
07bd50c1d80f6ff651228e6fc0ba3a583a472915772244f232696b34156a9d27 *i386-win32.pe/upx-3.95.exe
8e5333ea040f5594d3e67d5b09e005d52b3a52ef55099a7c11d7e39ead38e66d *m68k-atari.tos/upx-3.91.ttp
8902f38ec3d95d8e077e3ab5fdbb5bad408859913a35deb87041f4f053cd6605 *mips-linux.elf/upx-3.95
c3f44b4d00a87384c03a6f9e7aec809c1addfe3e271244d38a474f296603088c *mipsel-linux.elf/upx-3.91
dd1496bc4e9c32a5d5dd47e3eaabf7b134ca001d48807eebfd3d5e28c8a2ab58 *mipsel-linux.elf/upx-3.95
b8c35fa2956da17ca505956e9f5017bb5f3a746322647e24ccb8ff28059cafa4 *powerpc-linux.elf/upx-3.91
2bc00a51daa0bada19a8fa1bd2c227a8596844fa1b0aa3611087f195072700e2 *powerpc-linux.elf/upx-3.95
a0950546dc17fca9437219431d8ddb0249ce5b08e899e0c799a87ac982adee70 *powerpc64le-linux.elf/upx-3.95
"
expected_sha256sums__t110_compress_ucl_nrv2b_3_no_filter="\
d0b9b8a5bdbbc2f037e7e7b7a9fd2acd7b434ac03d7c59b4f2779c8621eed95e *amd64-linux.elf/upx-3.91
d36bff9e6f49c93e4c37ab50e109bd6378128017555f8f819080f02235d48d7e *amd64-linux.elf/upx-3.95
9c312f13ddd40a62fed7ee9f6a21fff15cae7517d4ddf55f493101b22d8e43f1 *amd64-win64.pe/upx-3.95.exe
b138d38c3955697ee0302332c031c996bacacf5e17eea8fce3282c4ea88f7299 *arm-linux.elf/upx-3.95
e0436401972603f7fad6c693e96c89c37370113e75b8bdb4d4ecd14dda4cd8fe *arm-wince.pe/upx-3.91.exe
22107e27f63c5509f5d1c1312cb8ea1e116811695ee7f4deb765f0aa53b25a51 *arm64-linux.elf/upx-3.95
beae687a0575a65cec981e7cc63fd562d212d7ed64befe5dde2f0b7f92e4838e *armeb-linux.elf/upx-3.91
55391ffd6bccd2be4e423466d327b9f345371f9941dbb30c003e677b984e8a5e *armeb-linux.elf/upx-3.95
a467edf8758a5b3e219bc193a9d143cb880f7d1a94771367cda7117129b34cfc *i386-dos32.djgpp2.coff/upx-3.91.exe
934593ba98f2dfff94197885894e7e56ff452da02a234e70734e2445b27ae8aa *i386-dos32.djgpp2.coff/upx-3.95.exe
f26697e9a9fceca98b10c1ab6a834fa6b2bd2826a2285deaafe8cd1c754a2f61 *i386-linux.elf/upx-3.91
f23467fde1af895827e7ad7c46c372802820143620fef2abe657aa8b6e7bdb26 *i386-linux.elf/upx-3.95
9dd14ff1328b0d501aca10d36623b2b76c754e9677cc0bdd0c5ded740796cecf *i386-win32.pe/upx-3.91.exe
5320b28b44ae1a50ea435ccabf7fe94c8031be7375c425ed618cb1f9a649442f *i386-win32.pe/upx-3.95.exe
d30bf134c5231317ae2182059034842f58d906b9dc49546bbb552f4e0411085f *m68k-atari.tos/upx-3.91.ttp
9d0fca1d248d11ec8e96801dae3978c959a26e372e05836c15b56cfc0b4aa077 *mips-linux.elf/upx-3.95
d68a073cb1c222515502a3a0e8f91f424cb8cedb0d849d247531c2955fa5399a *mipsel-linux.elf/upx-3.91
48919a0e564866d59ae1efae06269cea2cf7ebb5e3fda4a9ce70f9f1092a7e59 *mipsel-linux.elf/upx-3.95
93f04183b21f077d6423c23efee62f0c920cd63463b0932ac6200e966e423763 *powerpc-linux.elf/upx-3.91
9ef05193c11073f477606ff2c8654f11c370951ff5a7902ba0cab31598751029 *powerpc-linux.elf/upx-3.95
1c04d45914809449337f22c93bf645703c6c6aa499e789ff9d2dd787be257e96 *powerpc64le-linux.elf/upx-3.95
"
expected_sha256sums__t120_compress_ucl_nrv2d_3_no_filter="\
89369823c5f2316f00f4a8af2e810a94050e28254669a2a2547a73b166178db2 *amd64-linux.elf/upx-3.91
a267b53b2de081c414ef82351a5e88431cafdd86f8202e48929d637bf6af9192 *amd64-linux.elf/upx-3.95
1f40d3e26e266b7c305e01a0e480f936746d1c54df32826f5f6f16fbbe58f20b *amd64-win64.pe/upx-3.95.exe
3d1ac6e85dfa79f8aa36d2d73073181c5cf7dd6c3e83da3b9248fa990c535d2a *arm-linux.elf/upx-3.95
856d307362db229387d3d33ad8478a8cba45c71d67d5bbf2d9794154a755722f *arm-wince.pe/upx-3.91.exe
2fdec54995bf5367991ef64a7582a3a0e3724a71d89e77fdbe8c5bb67071d65e *arm64-linux.elf/upx-3.95
ddde64e009beff80e2e185b03dbe1b966ffa4c5db18fcd80c409b52233d4bb81 *armeb-linux.elf/upx-3.91
08aece1b25973a84bedb155c2976ca08e4ce1334e21659e5583f17a0e9e3bc3c *armeb-linux.elf/upx-3.95
ee07e1e15ff7a467f9ad262daa12886211f107886cae154795651d3cdba6fba3 *i386-dos32.djgpp2.coff/upx-3.91.exe
f73ac819d5f7f81b7cf62198381a51273df6a697d5429a144f42fabef0bcc327 *i386-dos32.djgpp2.coff/upx-3.95.exe
3b9e78245b5fa3108d2e69c22764e8204d24089f6661790edbdb88a508923191 *i386-linux.elf/upx-3.91
6a9aa8025e9389cbbe81a04926d12e120fd57b9909de4ee934e878a04fcf6169 *i386-linux.elf/upx-3.95
7a667cc2b566ae2f8836cc3c21d55e45bf35d61beca22ec2a806d6bcbfa1f082 *i386-win32.pe/upx-3.91.exe
cdd58a31c4914bdde47f03d81b988ffc9aa2af482de775c88cae144b4ff04293 *i386-win32.pe/upx-3.95.exe
02b969917d52c4bd07e49e4ad589db8a1e4fa27984eac2eede03bc1abf73c376 *m68k-atari.tos/upx-3.91.ttp
722ac1505bdaed421b6cce390608661be7236d4108429853485b8354b3c59347 *mips-linux.elf/upx-3.95
7309ee902e2c41ae72cc111c185d34e355e3892566e826698780fe69845174ad *mipsel-linux.elf/upx-3.91
fec12c58da7886a1eaf4702b2b0c710e2b72c4179070b04691b963d1c503c73b *mipsel-linux.elf/upx-3.95
13ad283bc0e4f37f9f06eddb8c384faa4a2e66e045496aa79dfde0ae59f14a95 *powerpc-linux.elf/upx-3.91
812550c5b65c39e347648e6ab9d51b2466919205a8b0928ef941ab3160151471 *powerpc-linux.elf/upx-3.95
0e651fdc257be7b3143ad06559a137be6c87f7b7ec721d1f727dc138465b219d *powerpc64le-linux.elf/upx-3.95
"
expected_sha256sums__t130_compress_ucl_nrv2e_3_no_filter="\
5ee77141a1fdf1af31f3f9be97e60446873e659e341993a3bbceacb655618aa5 *amd64-linux.elf/upx-3.91
b94c4603c372400a06c2ae7838ed9f41e6e9393d81e091a0ceed39c861e3443f *amd64-linux.elf/upx-3.95
c9230d017885d7727ca766cb7933d0681a93ef21856c39fbf807899b734172c0 *amd64-win64.pe/upx-3.95.exe
6ae717a2a7ebe99f6d1c3af8c83939f5efe2144670806c336640ad88c29a9d90 *arm-linux.elf/upx-3.95
6dbd0442d9e45c82d113463eb592d117c6761fd073e942342516fb0339d935e7 *arm-wince.pe/upx-3.91.exe
6f12e95d71382a7960b9712c75a897974f29561d2a8e774b7e984c9fba380aea *arm64-linux.elf/upx-3.95
94dbeae5763e5c86d865e9c6e473aafdb200b1ed06bfd5981728e0fa5cc6dcc6 *armeb-linux.elf/upx-3.91
cab852c4a69042aca4337869edce3af5f5aab8bf562a626ab755da0a5517bd73 *armeb-linux.elf/upx-3.95
dc6d412f41101e334f9e09c52e63f513e2b0bd047064283c0f7389276dd6d28b *i386-dos32.djgpp2.coff/upx-3.91.exe
0ab8e2454b1f5bfed09a8d0c231f4c595c7445b09077387ebb9348292206be59 *i386-dos32.djgpp2.coff/upx-3.95.exe
7b6efd3d82b503f4d0ea3a111e80b0a1b785a2766ddea9f4090a7de190f811be *i386-linux.elf/upx-3.91
c1ede9406344f8b0d5fb08777c31c62016e36f54f3ff69fc03ffbc09d5b40a0e *i386-linux.elf/upx-3.95
728c6dc0c02d9ea3f7a0c86595fd64423f5545651b3a7bbc9e708759d8eec157 *i386-win32.pe/upx-3.91.exe
8569f6942377259c5a92acfe5bf0b2874f6ef3af40177947a8055e7641a776ef *i386-win32.pe/upx-3.95.exe
c4753f47328d70823f85b5d378502556388ee0a9ea6bf100cd6c73651126b3fb *m68k-atari.tos/upx-3.91.ttp
a918b7825fd5bf50097a62177b4638abee5aeb864e06ce1624042cace8a9a922 *mips-linux.elf/upx-3.95
4b5cddac9a79b5e7aa99b7589d7e862bfbe026da44c2fed2a1f396883b072442 *mipsel-linux.elf/upx-3.91
cc1be3f4d27d3ab5f6073f38c47ca72f4ba47121b14b7e60a4906a6d04af4e9c *mipsel-linux.elf/upx-3.95
cedc2def9464f839e9aab153dfe93dda0d37d0da43e8c600ef366f6adf17b64b *powerpc-linux.elf/upx-3.91
748a4a2481b73ff2881b6de39749f1672b8b8d7f1d66a6453374caf6d840777d *powerpc-linux.elf/upx-3.95
f07f45141bf199db4847fd11ff56f496790efc3b7cff248a93c4ca45ca76a71a *powerpc64le-linux.elf/upx-3.95
"
expected_sha256sums__t140_compress_lzma_2_no_filter="\
f553659c34a772cbdaf571d83d9c8173b75f1e2deecf7c590d38e34b46cab43b *amd64-linux.elf/upx-3.91
9464896ca0082d41cf7e51159e7cd58a637b0a9d7a9151930e81746f1f43898b *amd64-linux.elf/upx-3.95
255ef236a7fe03865dd300ce447c57754aef05de537564f38715eef64285c6fa *amd64-win64.pe/upx-3.95.exe
88ae278afa54ac766f1940f3607c91d4915cdd492988dafac9be274dbda6fd5b *arm-linux.elf/upx-3.95
14f77ebb33e788aa8f9a9ad608232c3f9047dc6dfd55ceb02244a36cac9aea25 *arm-wince.pe/upx-3.91.exe
a79b9a7fc7e8a5e0b42fdf342fe44aae827e63809b0797d3deefd4b9f184388c *arm64-linux.elf/upx-3.95
17603d9f6b48e10b438d65c70e8afbf87a82f84a6ee12e96ac66371663d4f18f *armeb-linux.elf/upx-3.91
5162fcc6f1327c76c2221d7a5f9668d05dd828f7a6d4dbbc732005d244947805 *armeb-linux.elf/upx-3.95
3a94cec95fd3eac557bf929b372b20b155e8d331e44e47eb3486b048ebb36c9f *i386-dos32.djgpp2.coff/upx-3.91.exe
632b63bce916203d52d997d191728667d1091694a5cfc1a2ed327b540357e7e9 *i386-dos32.djgpp2.coff/upx-3.95.exe
04edc6bc3ec1a4217461ee6b81b0ea29fb25a62721c92ea62ab0dfaa147412b1 *i386-linux.elf/upx-3.91
36f47959198dace24777e95c3dcff64940ce514dc62b9cb794e957e969f07bae *i386-linux.elf/upx-3.95
cf3c0f31aca86f30edb45e4bd945997d7acca9c2d54acfc427936fe4ff2ba355 *i386-win32.pe/upx-3.91.exe
c774fb5e3dcc0a00fa58ce223c30d7805f2f96606d9dddda30075c6a6c35a639 *i386-win32.pe/upx-3.95.exe
3be124d31c578530d8aa4da4ad53346a6fd62c8d4f3a9b1d068d5f912d9117ee *m68k-atari.tos/upx-3.91.ttp
0ed619426db38bdbb783e2f47a1ce36c4b6831e00be8626f560cdf968b61f8a1 *mips-linux.elf/upx-3.95
9b83be53c444ad4dda60b8fa3faf9a7ae4ffb1f99027364a2af52e6c12e64462 *mipsel-linux.elf/upx-3.91
e405854a04fc1ebf272e57ffc74580e387ce8860ec460d77e660c829d30d9153 *mipsel-linux.elf/upx-3.95
f876a78a55939bf5ec990aaa3ece0a8a69d0a70eb7b00422d44ee1f0fa9ec6ea *powerpc-linux.elf/upx-3.91
8e65ca7e13e26b18c5ee93ab2c1a06f244dd7fff72da4523de3225feed9a4002 *powerpc-linux.elf/upx-3.95
07c6d83eeb6c664674df125fa9711c76140ccec562022f8d1334c761c00e787e *powerpc64le-linux.elf/upx-3.95
"
expected_sha256sums__t150_compress_ucl_2_all_filters="\
c41d2eb5d32c57b1302ceb17bb18b3cf7f611f8e31478f47e188cc39870b0e8d *amd64-linux.elf/upx-3.91
0dd8f6812aed9accea975c855dc2b4ae48fa2d03554614484de1d0335364e370 *amd64-linux.elf/upx-3.95
8cf83b49aab1a366318591fe69d87408ec1f7b36c3470a9cee82fd1fc39d7899 *amd64-win64.pe/upx-3.95.exe
b4b25da30e8f5da864bd8319d1c9b193eff9cf20f365d768763a2972a02d4c0f *arm-linux.elf/upx-3.95
040117965a54878b7665b7f8155230e0f171a7749c961a1dca26eb76719b3b97 *arm-wince.pe/upx-3.91.exe
2b790cb0fe0b83ade980b1014e4b2f9336557f4f3ae469b94a32757ea88a281c *arm64-linux.elf/upx-3.95
aa7ad6e9b537ab8a17d4bee539d220b39ec0fded7e9924178e3be786c6cc6907 *armeb-linux.elf/upx-3.91
66b161bdb4f9c94518f04acb385ddcaa180913f62bafc060d9f723f2bde40bdb *armeb-linux.elf/upx-3.95
1584cbffe0037e9e3c441aeac8fc2ef226ee78d0430d4298070c7258a5de650e *i386-dos32.djgpp2.coff/upx-3.91.exe
da37d160c4c185dfb7c0754637278a512503ecc396741678adfda38423eaae44 *i386-dos32.djgpp2.coff/upx-3.95.exe
39d8526dfd19d6fa8753731dc4dd362ede4a360f834f41f7d320f3e5ac1aa083 *i386-linux.elf/upx-3.91
3a86c29348f68ec5b99dad6b739a66c36f64bf35adcc7defa950e3140c99e11d *i386-linux.elf/upx-3.95
6cc7deccbafc7c5a658a017ca18613b004d3b9b21e2a4e08343f92fbb82587fb *i386-win32.pe/upx-3.91.exe
43c04b1eef6ea89821dc8689f09865008784fcb2152cbc59a3be7c091a56a536 *i386-win32.pe/upx-3.95.exe
d0ccb6fa3cb2557923c494a5d41615e2ba6687960144a98ae575761d20ff29d6 *m68k-atari.tos/upx-3.91.ttp
9a217e5a233b523a1d031819f8e9acb00d5be03e8e8b718dc18a8819b5b04a3a *mips-linux.elf/upx-3.95
a5e18b41cad43cc4583cbb49248c3608d64df760a8deb302aaed5f96d3f9a46b *mipsel-linux.elf/upx-3.91
b799dbcfc4fde1cdfa572a0143a4513d83636ea0883eec320761ae57a7c36ccd *mipsel-linux.elf/upx-3.95
ce42a8aad4bbed730e7bcd7970efa170040eef22c9ecad4a993b81d2f6780329 *powerpc-linux.elf/upx-3.91
6c812174a92107ac598a6b36b2e14cad82109813e14c436a2aa9d517bdea107b *powerpc-linux.elf/upx-3.95
047a4063962c372bce50aed451404d06e3f00a4f8a535acf0f92895ebc47ba0a *powerpc64le-linux.elf/upx-3.95
"
expected_sha256sums__t160_compress_all_methods_1_no_filter="\
848eff62a732dce17b36fa34277727cdbe68637dd169c0d4fa831a8085369c6c *amd64-linux.elf/upx-3.91
9a7a1df07d95f17b64a9c714a444b61baf790a3a3378b53c1f0f7752c5ef7aa3 *amd64-linux.elf/upx-3.95
ff5f4d665a04bfa1bddabf9853686626aea828a8e542006ef7d76d49b549d9d5 *amd64-win64.pe/upx-3.95.exe
a1f0f5df99eeed2009cdf2d253c824335b7010d91458297718bd257a2c2bc464 *arm-linux.elf/upx-3.95
8b236855f4df2df1072a93d3bd1f7203c3d43801830a38679afc354250c6a7be *arm-wince.pe/upx-3.91.exe
e0644a18614e3ff48c3a8c306ab0c057a3ef58fab7015e522a6ef7a9aeb28970 *arm64-linux.elf/upx-3.95
bffe4754c49568fcc9cf67e973ecb9a48e8119bab4b03d9ebae436192fbfe76b *armeb-linux.elf/upx-3.91
e69f6fc17db59b12c6910af45704c33387079492c24b1659038433e4211a8898 *armeb-linux.elf/upx-3.95
14133daa854c4355b25e58803ad9b5e4bfb5e665fdbf12489f8b7c29ef6646a3 *i386-dos32.djgpp2.coff/upx-3.91.exe
1a903afd11b866820a1814c6ee8a68431727e5c570045169295a425a6198a273 *i386-dos32.djgpp2.coff/upx-3.95.exe
86a466a5d4568b225216cce95738fc63457b065b36590ca4d204108768ca8f78 *i386-linux.elf/upx-3.91
79077dc8b999ee25171ee721e8ca56880c6d0b486f88747861ef437370075504 *i386-linux.elf/upx-3.95
58b93bd7d162f89c2ea187590c515192649831ab94435b87b27d47a9e74379e4 *i386-win32.pe/upx-3.91.exe
34c4260a53579a6859668cf3eb6c069cf5db82c00ad605bfdc8b2f1e0450aa16 *i386-win32.pe/upx-3.95.exe
8495d281bf4a8f193a204b5a56d49b3c645370049e8e83db4154db3e02d55543 *m68k-atari.tos/upx-3.91.ttp
388b013a17b84b1068502fb01b13a78a17bec5f1bd7953ec127ee3c952a7da1c *mips-linux.elf/upx-3.95
466da371ef3123d18c61e2a094d7a609e16dd005f0ea8a46d813690405e1d616 *mipsel-linux.elf/upx-3.91
36bed2f441c3abc918b46cfb80ff1bd31c82b264c3f69dcf0c1c28521fd53128 *mipsel-linux.elf/upx-3.95
0b988e12ea324ce2c6ba9506209bbb80c10bb6a02ff8949887e810f44d710338 *powerpc-linux.elf/upx-3.91
94981cf2f48631c476da88f8e5dcecf3ee68772ce12b189d33aaf871ef7a9536 *powerpc-linux.elf/upx-3.95
616a829f2d1324fad2863481a5cba088f2a51c38de866c20fe9d9d7a75df3dfc *powerpc64le-linux.elf/upx-3.95
"
expected_sha256sums__t170_compress_all_methods_no_lzma_5_no_filter="\
55046a0c623116f9d6c78e62d7f3fb781e3aa8d8a03e987f49f0705ee3a7840b *amd64-linux.elf/upx-3.91
a9ca57293b43b093fb9582a81a2ad2877f7c2546a536541bf3766452a9faa4aa *amd64-linux.elf/upx-3.95
3247a637f6cc56219bc2d6a3b16237226e1ba97ac1d0fce012657e23bfe256c3 *amd64-win64.pe/upx-3.95.exe
d43683421216236ab6e90f4f7d6ad69f3b1d18e53bc5dd57b5dcea2916fe480f *arm-linux.elf/upx-3.95
387787098a33b61637b39d7d015972d18e687771d8596b74286764ac73ee9286 *arm-wince.pe/upx-3.91.exe
e2e476b9ccfd13f14940f28240b8e6f85ce0e21f6cc5b619cc2972b9238b5bd2 *arm64-linux.elf/upx-3.95
538eef066d7deb4b6c07de4a50ffaf24a759278beeee9204e4d6c642aa382de3 *armeb-linux.elf/upx-3.91
9349eca3e551ce1d2ab95735b8898efc54439c3d87395f2c0bddbe88fbc35cbc *armeb-linux.elf/upx-3.95
ce768b3be6ffeb84d0558a937a9a5778427ce56898a9b3ef9490e7e5ba6ce688 *i386-dos32.djgpp2.coff/upx-3.91.exe
849e285cb39e5609f384559398c47f5e34d2067711c58aacc5ed1c97495b8da0 *i386-dos32.djgpp2.coff/upx-3.95.exe
6a0b78c2af8d68faac587531b32679a3a264fa86f524cf801db31a41a231becb *i386-linux.elf/upx-3.91
e524ee0c3058ba4a44073ec29d67982bc39721865b33e6881dffbe2329a79279 *i386-linux.elf/upx-3.95
06d281a60d5ed815f74052e3e133915739e58c3a563a2e914186e85114687a12 *i386-win32.pe/upx-3.91.exe
a1c3256670c4f55d3aea58063c4689d122c605d079537a27b1952eeab8d5d6ad *i386-win32.pe/upx-3.95.exe
b866f184c6fe911b410afa8080acd1c7fddc11131d15bd272eb8adbca20439d2 *m68k-atari.tos/upx-3.91.ttp
197d7dace27bbeba5627868b7a333b4580673ffe38353f3a11bd2d65b4216470 *mips-linux.elf/upx-3.95
9b13d57d59a97313e20a0d3e02641045fddd5eb3bcbbcf7772181d5d87c4b3bf *mipsel-linux.elf/upx-3.91
6f671511e19d9719c0bc7c2344d65cbf13a04da1c9bae9e55d2ca83ba9dede0a *mipsel-linux.elf/upx-3.95
4ec415399f04f546d9831758a3cfedb00f20b06cb7e1c2eb38354aff3b6d3004 *powerpc-linux.elf/upx-3.91
20e31a1df4eb5f6a930b34707b591265c6b5609ee2b2cdd5f504009284d1afc9 *powerpc-linux.elf/upx-3.95
fe4dd9c59e6ae76ff23d6b4df27ca0df4289f6d13c8e3dc8d82c22982639ddd9 *powerpc64le-linux.elf/upx-3.95
"
########## end .sha256sums.recreate
+148 -109
View File
@@ -1,35 +1,130 @@
#! /bin/bash #! /usr/bin/env bash
## vim:set ts=4 sw=4 et: ## vim:set ts=4 sw=4 et:
set -e; set -o pipefail set -e; set -o pipefail
argv0=$0; argv0abs=$(readlink -en -- "$0"); argv0dir=$(dirname "$argv0abs") argv0=$0; argv0abs=$(readlink -fn "$argv0"); argv0dir=$(dirname "$argv0abs")
# very first version of the upx-testsuite; requires: # very first version of the upx-testsuite; requires:
# $upx_exe # $upx_exe (required, but with convenience fallback "./upx")
# $upx_testsuite_SRCDIR # $upx_testsuite_SRCDIR (required, but with convenience fallback)
# $upx_testsuite_BUILDDIR (optional) # $upx_testsuite_BUILDDIR (optional)
# $BM_T (optional) #
# optional settings:
# $upx_exe_runner (e.g. "qemu-x86_64 -cpu Westmere" or "valgrind")
# $UPX_TESTSUITE_VERBOSE
# $UPX_TESTSUITE_LEVEL
#
# see https://github.com/upx/upx-testsuite.git
# convenience # /***********************************************************************
[[ -z $upx_testsuite_BUILDDIR ]] && upx_testsuite_BUILDDIR=./tmp-upx-testsuite # // init & checks
[[ -f $upx_exe ]] && upx_exe=$(readlink -en -- "$upx_exe") # ************************************************************************/
# make dirs absolute # upx_exe
upx_testsuite_SRCDIR=$(readlink -en -- "$upx_testsuite_SRCDIR") [[ -z $upx_exe && -f ./upx && -x ./upx ]] && upx_exe=./upx # convenience fallback
if [[ -z $upx_exe ]]; then echo "UPX-ERROR: please set \$upx_exe"; exit 1; fi
if [[ ! -f $upx_exe ]]; then echo "UPX-ERROR: file '$upx_exe' does not exist"; exit 1; fi
upx_exe=$(readlink -fn "$upx_exe") # make absolute
[[ -f $upx_exe ]] || exit 1
upx_run=()
if [[ -n $upx_exe_runner ]]; then
# usage examples:
# export upx_exe_runner="qemu-x86_64 -cpu Westmere"
# export upx_exe_runner="valgrind --leak-check=no --error-exitcode=1 --quiet"
# export upx_exe_runner="wine"
IFS=' ' read -r -a upx_run <<< "$upx_exe_runner" # split at spaces into array
fi
upx_run+=( "$upx_exe" )
echo "upx_run='${upx_run[*]}'"
# upx_run check, part1
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[@]}" --help >/dev/null; then echo "UPX-ERROR: FATAL: upx --help FAILED"; exit 1; fi
# upx_testsuite_SRCDIR
if [[ -z $upx_testsuite_SRCDIR ]]; then
# convenience fallback: search standard locations below upx top-level directory
if [[ -d "$argv0dir/../../../upx--upx-testsuite.git/files/packed" ]]; then
upx_testsuite_SRCDIR="$argv0dir/../../../upx--upx-testsuite.git"
elif [[ -d "$argv0dir/../../../upx-testsuite.git/files/packed" ]]; then
upx_testsuite_SRCDIR="$argv0dir/../../../upx-testsuite.git"
elif [[ -d "$argv0dir/../../../upx-testsuite/files/packed" ]]; then
upx_testsuite_SRCDIR="$argv0dir/../../../upx-testsuite"
fi
fi
if [[ ! -d "$upx_testsuite_SRCDIR/files/packed" ]]; then if [[ ! -d "$upx_testsuite_SRCDIR/files/packed" ]]; then
echo 'invalid or missing $upx_testsuite_SRCDIR:' echo "invalid or missing \$upx_testsuite_SRCDIR:"
echo ' please git clone https://github.com/upx/upx-testsuite' echo " please git clone https://github.com/upx/upx-testsuite.git"
echo ' and set (export) the envvar upx_testsuite_SRCDIR to the local file path' echo " and set (export) the envvar upx_testsuite_SRCDIR to the local file path"
exit 1 exit 1
fi fi
mkdir -p "$upx_testsuite_BUILDDIR" upx_testsuite_SRCDIR=$(readlink -fn "$upx_testsuite_SRCDIR") # make absolute
upx_testsuite_BUILDDIR=$(readlink -en -- "$upx_testsuite_BUILDDIR") [[ -d $upx_testsuite_SRCDIR ]] || exit 1
# upx_testsuite_BUILDDIR
if [[ -z $upx_testsuite_BUILDDIR ]]; then
upx_testsuite_BUILDDIR="./tmp-upx-testsuite"
fi
mkdir -p "$upx_testsuite_BUILDDIR" || exit 1
upx_testsuite_BUILDDIR=$(readlink -fn "$upx_testsuite_BUILDDIR") # make absolute
[[ -d $upx_testsuite_BUILDDIR ]] || exit 1
cd / && cd "$upx_testsuite_BUILDDIR" || exit 1 cd / && cd "$upx_testsuite_BUILDDIR" || exit 1
: > ./.mfxnobackup
# upx_run check, part2
if ! "${upx_run[@]}" --version-short >/dev/null; then
echo "UPX-ERROR: FATAL: upx --version-short FAILED"
echo "please make sure that \$upx_exe contains ABSOLUTE file paths and can be run from any directory"
echo "INFO: upx_run='${upx_run[*]}'"
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
case $UPX_TESTSUITE_LEVEL in
[0-8]) ;;
*) UPX_TESTSUITE_LEVEL=999 ;;
esac
if [[ $UPX_TESTSUITE_LEVEL == 0 ]]; then
echo "UPX testsuite SKIPPED."
exit 0
fi
# /***********************************************************************
# // setup
# ************************************************************************/
#set -x # debug
exit_code=0
num_errors=0
all_errors=
export UPX="--prefer-ucl --no-color --no-progress"
export UPX_DEBUG_DISABLE_GITREV_WARNING=1
export UPX_DEBUG_DOCTEST_VERBOSE=0
rm -rf ./testsuite_1
mkdir testsuite_1 || exit 1
cd testsuite_1 || exit 1
# /*********************************************************************** # /***********************************************************************
# // support functions # // support functions
# ************************************************************************/ # ************************************************************************/
run_upx() {
local ec=0
if [[ $UPX_TESTSUITE_VERBOSE == 1 ]]; then
echo "LOG: '${upx_run[*]}' $*"
fi
"${upx_run[@]}" "$@" || ec=$?
if [[ $ec != 0 ]]; then
echo "FATAL: '${upx_run[*]}' $*"
echo " (exit code was $ec)"
exit 42
fi
}
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"
@@ -41,12 +136,12 @@ testsuite_split_f() {
fsubdir=$(basename "$fd") fsubdir=$(basename "$fd")
# sanity checks # sanity checks
if [[ ! -f $1 || -z $fsubdir || -z $fb ]]; then if [[ ! -f $1 || -z $fsubdir || -z $fb ]]; then
fd= fb= fsubdir= fd=''; fb=''; fsubdir=''
fi fi
} }
testsuite_check_sha() { testsuite_check_sha() {
(cd "$1" && sha256sum -b */* | LC_ALL=C sort -k2) > $1/.sha256sums.current (cd "$1" && sha256sum -b [0-9a-zA-Z]*/* | LC_ALL=C sort -k2) > $1/.sha256sums.current
echo echo
cat $1/.sha256sums.current cat $1/.sha256sums.current
if ! cmp -s $1/.sha256sums.expected $1/.sha256sums.current; then if ! cmp -s $1/.sha256sums.expected $1/.sha256sums.current; then
@@ -61,7 +156,7 @@ testsuite_check_sha() {
} }
testsuite_check_sha_decompressed() { testsuite_check_sha_decompressed() {
(cd "$1" && sha256sum -b */* | LC_ALL=C sort -k2) > $1/.sha256sums.current (cd "$1" && sha256sum -b [0-9a-zA-Z]*/* | LC_ALL=C sort -k2) > $1/.sha256sums.current
if ! cmp -s $1/.sha256sums.expected $1/.sha256sums.current; then if ! cmp -s $1/.sha256sums.expected $1/.sha256sums.current; then
cat $1/.sha256sums.current cat $1/.sha256sums.current
echo "UPX-ERROR: FATAL: $1 FAILED: decompressed checksum mismatch" echo "UPX-ERROR: FATAL: $1 FAILED: decompressed checksum mismatch"
@@ -75,22 +170,22 @@ testsuite_run_compress() {
testsuite_header $testdir testsuite_header $testdir
local files f local files f
if [[ $testsuite_use_canonicalized == 1 ]]; then if [[ $testsuite_use_canonicalized == 1 ]]; then
files=t020_canonicalized/*/* files='t020_canonicalized/*/*'
else else
files=t010_decompressed/*/* files='t010_decompressed/*/*'
fi fi
for f in $files; do for f in $files; do
testsuite_split_f $f testsuite_split_f "$f"
[[ -z $fb ]] && continue [[ -z $fb ]] && continue
echo "# $f" echo "# $f"
mkdir -p $testdir/$fsubdir $testdir/.decompressed/$fsubdir mkdir -p "$testdir/$fsubdir" "$testdir/.decompressed/$fsubdir"
$upx_run -qq --prefer-ucl "$@" $f -o $testdir/$fsubdir/$fb run_upx -qq --prefer-ucl "$@" "$f" -o "$testdir/$fsubdir/$fb"
$upx_run -qq -d $testdir/$fsubdir/$fb -o $testdir/.decompressed/$fsubdir/$fb run_upx -qq -d "$testdir/$fsubdir/$fb" -o "$testdir/.decompressed/$fsubdir/$fb"
done done
testsuite_check_sha $testdir testsuite_check_sha $testdir
$upx_run -qq -l $testdir/*/* run_upx -qq -l "$testdir"/*/*
$upx_run -qq --file-info $testdir/*/* run_upx -qq --file-info "$testdir"/*/*
$upx_run -q -t $testdir/*/* run_upx -q -t "$testdir"/*/*
if [[ $testsuite_use_canonicalized == 1 ]]; then if [[ $testsuite_use_canonicalized == 1 ]]; then
# check that after decompression the file matches the canonicalized version # check that after decompression the file matches the canonicalized version
cp t020_canonicalized/.sha256sums.expected $testdir/.decompressed/ cp t020_canonicalized/.sha256sums.expected $testdir/.decompressed/
@@ -108,10 +203,10 @@ testsuite_run_compress() {
# ************************************************************************/ # ************************************************************************/
recreate_expected_sha256sums() { recreate_expected_sha256sums() {
local o=$1 local o="$1"
local files f d local files f d
echo "########## begin .sha256sums.recreate" > "$o" echo "########## begin .sha256sums.recreate" > "$o"
files=*/.sha256sums.current files='*/.sha256sums.current'
for f in $files; do for f in $files; do
d=$(dirname "$f") d=$(dirname "$f")
echo "expected_sha256sums__${d}="'"\' >> "$o" echo "expected_sha256sums__${d}="'"\' >> "$o"
@@ -121,53 +216,7 @@ recreate_expected_sha256sums() {
echo "########## end .sha256sums.recreate" >> "$o" echo "########## end .sha256sums.recreate" >> "$o"
} }
source "$argv0dir/travis_testsuite_1-expected_sha256sums.sh" || exit 1 source "$argv0dir/upx_testsuite_1-expected_sha256sums.sh" || exit 1
# /***********************************************************************
# // init
# ************************************************************************/
#set -x # debug
exit_code=0
num_errors=0
all_errors=
if [[ $BM_T =~ (^|\+)ALLOW_FAIL($|\+) ]]; then
echo "ALLOW_FAIL"
set +e
fi
if [[ -z $upx_exe ]]; then exit 1; fi
upx_run=$upx_exe
if [[ $BM_T =~ (^|\+)qemu($|\+) && -n $upx_qemu ]]; then
upx_run="$upx_qemu $upx_qemu_flags -- $upx_exe"
fi
if [[ $BM_T =~ (^|\+)wine($|\+) && -n $upx_wine ]]; then
upx_run="$upx_wine $upx_wine_flags $upx_exe"
fi
if [[ $BM_T =~ (^|\+)valgrind($|\+) ]]; then
if [[ -z $upx_valgrind ]]; then
upx_valgrind="valgrind"
fi
if [[ -z $upx_valgrind_flags ]]; then
#upx_valgrind_flags="--leak-check=full --show-reachable=yes"
#upx_valgrind_flags="-q --leak-check=no --error-exitcode=1"
upx_valgrind_flags="--leak-check=no --error-exitcode=1"
fi
upx_run="$upx_valgrind $upx_valgrind_flags $upx_exe"
fi
export UPX="--prefer-ucl --no-color --no-progress"
export UPX_DEBUG_DISABLE_GITREV_WARNING=1
export UPX_DEBUG_DOCTEST_VERBOSE=0
# let's go
if ! $upx_run --version-short; 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 --help >/dev/null; then echo "UPX-ERROR: FATAL: upx --help FAILED"; exit 1; fi
rm -rf ./testsuite_1
mkdir testsuite_1
cd testsuite_1 || exit 1
# /*********************************************************************** # /***********************************************************************
# // decompression tests # // decompression tests
@@ -177,12 +226,12 @@ testdir=t010_decompressed
mkdir $testdir; v=expected_sha256sums__$testdir; echo -n "${!v}" >$testdir/.sha256sums.expected mkdir $testdir; v=expected_sha256sums__$testdir; echo -n "${!v}" >$testdir/.sha256sums.expected
testsuite_header $testdir testsuite_header $testdir
for f in $upx_testsuite_SRCDIR/files/packed/*/upx-3.9[15]*; do for f in "$upx_testsuite_SRCDIR"/files/packed/*/upx-3.9[15]*; do
testsuite_split_f $f testsuite_split_f "$f"
[[ -z $fb ]] && continue [[ -z $fb ]] && continue
echo "# $f" echo "# $f"
mkdir -p $testdir/$fsubdir mkdir -p "$testdir/$fsubdir"
$upx_run -qq -d $f -o $testdir/$fsubdir/$fb run_upx -qq -d "$f" -o "$testdir/$fsubdir/$fb"
done done
testsuite_check_sha $testdir testsuite_check_sha $testdir
@@ -192,12 +241,12 @@ mkdir $testdir; v=expected_sha256sums__$testdir; echo -n "${!v}" >$testdir/.sha2
testsuite_header $testdir testsuite_header $testdir
for f in t010_decompressed/*/*; do for f in t010_decompressed/*/*; do
testsuite_split_f $f testsuite_split_f "$f"
[[ -z $fb ]] && continue [[ -z $fb ]] && continue
echo "# $f" echo "# $f"
mkdir -p $testdir/$fsubdir/.packed mkdir -p "$testdir/$fsubdir/.packed"
$upx_run -qq --prefer-ucl -1 $f -o $testdir/$fsubdir/.packed/$fb run_upx -qq --prefer-ucl -1 "$f" -o "$testdir/$fsubdir/.packed/$fb"
$upx_run -qq -d $testdir/$fsubdir/.packed/$fb -o $testdir/$fsubdir/$fb run_upx -qq -d "$testdir/$fsubdir/.packed/$fb" -o "$testdir/$fsubdir/$fb"
done done
testsuite_check_sha $testdir testsuite_check_sha $testdir
@@ -207,48 +256,43 @@ testsuite_check_sha $testdir
# // test UPX and not the compression libraries # // test UPX and not the compression libraries
# ************************************************************************/ # ************************************************************************/
case $UPX_TESTSUITE_FAST in if [[ $UPX_TESTSUITE_LEVEL -ge 2 ]]; then
[0-7]) ;;
*) UPX_TESTSUITE_FAST=999 ;;
esac
if [[ $UPX_TESTSUITE_FAST -ge 1 ]]; then
testdir=t110_compress_ucl_nrv2b_3_no_filter testdir=t110_compress_ucl_nrv2b_3_no_filter
mkdir $testdir; v=expected_sha256sums__$testdir; echo -n "${!v}" >$testdir/.sha256sums.expected mkdir $testdir; v=expected_sha256sums__$testdir; echo -n "${!v}" >$testdir/.sha256sums.expected
time testsuite_run_compress --nrv2b -3 --no-filter time testsuite_run_compress --nrv2b -3 --no-filter
fi fi
if [[ $UPX_TESTSUITE_FAST -ge 2 ]]; then if [[ $UPX_TESTSUITE_LEVEL -ge 3 ]]; then
testdir=t120_compress_ucl_nrv2d_3_no_filter testdir=t120_compress_ucl_nrv2d_3_no_filter
mkdir $testdir; v=expected_sha256sums__$testdir; echo -n "${!v}" >$testdir/.sha256sums.expected mkdir $testdir; v=expected_sha256sums__$testdir; echo -n "${!v}" >$testdir/.sha256sums.expected
time testsuite_run_compress --nrv2d -3 --no-filter time testsuite_run_compress --nrv2d -3 --no-filter
fi fi
if [[ $UPX_TESTSUITE_FAST -ge 3 ]]; then if [[ $UPX_TESTSUITE_LEVEL -ge 4 ]]; then
testdir=t130_compress_ucl_nrv2e_3_no_filter testdir=t130_compress_ucl_nrv2e_3_no_filter
mkdir $testdir; v=expected_sha256sums__$testdir; echo -n "${!v}" >$testdir/.sha256sums.expected mkdir $testdir; v=expected_sha256sums__$testdir; echo -n "${!v}" >$testdir/.sha256sums.expected
time testsuite_run_compress --nrv2e -3 --no-filter time testsuite_run_compress --nrv2e -3 --no-filter
fi fi
if [[ $UPX_TESTSUITE_FAST -ge 4 ]]; then if [[ $UPX_TESTSUITE_LEVEL -ge 5 ]]; then
testdir=t140_compress_lzma_2_no_filter testdir=t140_compress_lzma_2_no_filter
mkdir $testdir; v=expected_sha256sums__$testdir; echo -n "${!v}" >$testdir/.sha256sums.expected mkdir $testdir; v=expected_sha256sums__$testdir; echo -n "${!v}" >$testdir/.sha256sums.expected
time testsuite_run_compress --lzma -2 --no-filter time testsuite_run_compress --lzma -2 --no-filter
fi fi
if [[ $UPX_TESTSUITE_FAST -ge 5 ]]; then if [[ $UPX_TESTSUITE_LEVEL -ge 6 ]]; then
testdir=t150_compress_ucl_2_all_filters testdir=t150_compress_ucl_2_all_filters
mkdir $testdir; v=expected_sha256sums__$testdir; echo -n "${!v}" >$testdir/.sha256sums.expected mkdir $testdir; v=expected_sha256sums__$testdir; echo -n "${!v}" >$testdir/.sha256sums.expected
time testsuite_run_compress -2 --all-filters time testsuite_run_compress -2 --all-filters
fi fi
if [[ $UPX_TESTSUITE_FAST -ge 6 ]]; then if [[ $UPX_TESTSUITE_LEVEL -ge 7 ]]; then
testdir=t160_compress_all_methods_1_no_filter testdir=t160_compress_all_methods_1_no_filter
mkdir $testdir; v=expected_sha256sums__$testdir; echo -n "${!v}" >$testdir/.sha256sums.expected mkdir $testdir; v=expected_sha256sums__$testdir; echo -n "${!v}" >$testdir/.sha256sums.expected
time testsuite_run_compress --all-methods -1 --no-filter time testsuite_run_compress --all-methods -1 --no-filter
fi fi
if [[ $UPX_TESTSUITE_FAST -ge 7 ]]; then if [[ $UPX_TESTSUITE_LEVEL -ge 8 ]]; then
testdir=t170_compress_all_methods_no_lzma_5_no_filter testdir=t170_compress_all_methods_no_lzma_5_no_filter
mkdir $testdir; v=expected_sha256sums__$testdir; echo -n "${!v}" >$testdir/.sha256sums.expected mkdir $testdir; v=expected_sha256sums__$testdir; echo -n "${!v}" >$testdir/.sha256sums.expected
time testsuite_run_compress --all-methods --no-lzma -5 --no-filter time testsuite_run_compress --all-methods --no-lzma -5 --no-filter
@@ -261,25 +305,20 @@ fi
# recreate checksums from current version for an easy update in case of changes # recreate checksums from current version for an easy update in case of changes
recreate_expected_sha256sums .sha256sums.recreate recreate_expected_sha256sums .sha256sums.recreate
testsuite_header "UPX testsuite summary" testsuite_header "UPX testsuite summary: level $UPX_TESTSUITE_LEVEL"
if ! $upx_run --version-short; then run_upx --version-short
echo "UPX-ERROR: upx --version-short FAILED"
exit 1
fi
echo echo
echo "upx_exe='$upx_exe'" echo "upx_exe='$upx_exe'"
if [[ $upx_run != "$upx_exe" ]]; then ls -l "$upx_exe"
echo "upx_run='$upx_run'" if command -v file >/dev/null; then
fi
if [[ -f $upx_exe ]]; then
ls -l "$upx_exe"
file "$upx_exe" || true file "$upx_exe" || true
fi fi
echo "upx_run='${upx_run[*]}'"
echo "upx_testsuite_SRCDIR='$upx_testsuite_SRCDIR'" echo "upx_testsuite_SRCDIR='$upx_testsuite_SRCDIR'"
echo "upx_testsuite_BUILDDIR='$upx_testsuite_BUILDDIR'" echo "upx_testsuite_BUILDDIR='$upx_testsuite_BUILDDIR'"
echo ".sha256sums.{expected,current}:" echo ".sha256sums.{expected,current} counts:"
cat */.sha256sums.expected | LC_ALL=C sort | wc cat ./*/.sha256sums.expected | LC_ALL=C sort | wc
cat */.sha256sums.current | LC_ALL=C sort | wc cat ./*/.sha256sums.current | LC_ALL=C sort | wc
echo echo
if [[ $exit_code == 0 ]]; then if [[ $exit_code == 0 ]]; then
echo "UPX testsuite passed. All done." echo "UPX testsuite passed. All done."
+20 -16
View File
@@ -1,12 +1,13 @@
# #
# UPX Makefile - needs GNU make # UPX src Makefile - needs GNU make and CMake >= 3.13
# Copyright (C) Markus Franz Xaver Johannes Oberhumer
# #
# IMPORTANT NOTE: this Makefile is deprecated - please # NOTE: this Makefile is deprecated - please directly use the CMake build
# directly use the CMake build instead! # instead. And see the top-level Makefile for some pre-defined CMake
# build configurations.
MAKEFLAGS += -r MAKEFLAGS += -r
.SUFFIXES:
export SHELL = /bin/sh export SHELL = /bin/sh
ifndef srcdir ifndef srcdir
@@ -21,6 +22,7 @@ endif
# redirect to top-level CMake build # redirect to top-level CMake build
# #
# NOTE that top-level Makefile .DEFAULT_GOAL is build/release
.DEFAULT_GOAL = build/debug .DEFAULT_GOAL = build/debug
build/debug: $(top_srcdir)/build/debug/upx build/debug: $(top_srcdir)/build/debug/upx
@@ -35,11 +37,14 @@ $(top_srcdir)/build/debug/upx: PHONY
$(top_srcdir)/build/release/upx: PHONY $(top_srcdir)/build/release/upx: PHONY
$(MAKE) -C $(top_srcdir) build/release $(MAKE) -C $(top_srcdir) build/release
.NOTPARALLEL: # because the actual builds use "cmake --parallel"
.PHONY: PHONY .PHONY: PHONY
.NOTPARALLEL: .SECONDEXPANSION:
.SUFFIXES:
# #
# "make run-testsuite" # "make run-testsuite"
# see https://github.com/upx/upx-testsuite.git
# #
# search for the UPX testsuite -- git clone https://github.com/upx/upx-testsuite.git # search for the UPX testsuite -- git clone https://github.com/upx/upx-testsuite.git
@@ -56,19 +61,19 @@ endif
endif endif
# run the UPX testsuite # run the UPX testsuite
# The expected (old) checksums are in $(top_srcdir)/.github/travis_testsuite_1-expected_sha256sums.sh # The expected (old) checksums are in $(top_srcdir)/misc/testsuite/upx_testsuite_1-expected_sha256sums.sh
# The actual (new) checksums are in ./tmp-testsuite/testsuite_1/.sha256sums.recreate # The actual (new) checksums are in ./tmp-upx-testsuite/testsuite_1/.sha256sums.recreate
ifneq ($(wildcard $(upx_testsuite_SRCDIR)/files/packed/.),) ifneq ($(wildcard $(upx_testsuite_SRCDIR)/files/packed/.),)
ifneq ($(wildcard $(top_srcdir)/.github/travis_testsuite_1.sh),) ifneq ($(wildcard $(top_srcdir)/misc/testsuite/upx_testsuite_1.sh),)
run-testsuite: run-testsuite-release run-testsuite: run-testsuite-release
run-testsuite-%: export upx_testsuite_SRCDIR := $(upx_testsuite_SRCDIR) run-testsuite-%: export upx_testsuite_SRCDIR := $(upx_testsuite_SRCDIR)
run-testsuite-%: export upx_testsuite_BUILDDIR := ./tmp-testsuite run-testsuite-%: export upx_testsuite_BUILDDIR := ./tmp-upx-testsuite
run-testsuite-debug: export upx_exe := $(top_srcdir)/build/debug/upx run-testsuite-debug: export upx_exe := $(top_srcdir)/build/debug/upx
run-testsuite-debug: PHONY $(top_srcdir)/build/debug/upx run-testsuite-debug: PHONY $(top_srcdir)/build/debug/upx
time -p bash $(top_srcdir)/.github/travis_testsuite_1.sh time -p bash $(top_srcdir)/misc/testsuite/upx_testsuite_1.sh
run-testsuite-release: export upx_exe := $(top_srcdir)/build/release/upx run-testsuite-release: export upx_exe := $(top_srcdir)/build/release/upx
run-testsuite-release: PHONY $(top_srcdir)/build/release/upx run-testsuite-release: PHONY $(top_srcdir)/build/release/upx
time -p bash $(top_srcdir)/.github/travis_testsuite_1.sh time -p bash $(top_srcdir)/misc/testsuite/upx_testsuite_1.sh
endif endif
endif endif
@@ -79,15 +84,14 @@ endif
# automatically format some C++ source code files # automatically format some C++ source code files
ifeq ($(shell uname),Linux) ifeq ($(shell uname),Linux)
# Markus loves clang-format, but John hates it; find a compromise # 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 += conf.h miniacc.h version.h packer_c.cpp
CLANG_FORMAT_EXCLUDE_FILES += p_elf.h p_elf_enum.h p_lx_% p_mach% p_unix% p_vmli% CLANG_FORMAT_EXCLUDE_FILES += p_elf.h p_elf_enum.h p_lx_% p_mach% p_unix% p_vmlin%
CLANG_FORMAT_EXCLUDE_FILES += packer_c.cpp packer_f.cpp
CLANG_FORMAT_EXCLUDE_FILES += compress/compress.h filter/filter_impl.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 := $(sort $(wildcard *.[ch]* ../maint/src/*.[ch]* [cu]*/*.[ch]*))
CLANG_FORMAT_FILES := $(filter-out $(CLANG_FORMAT_EXCLUDE_FILES),$(CLANG_FORMAT_FILES)) CLANG_FORMAT_FILES := $(filter-out $(CLANG_FORMAT_EXCLUDE_FILES),$(CLANG_FORMAT_FILES))
clang-format: PHONY $(CLANG_FORMAT_FILES) clang-format: PHONY $(CLANG_FORMAT_FILES)
@echo "running upx-clang-format" @echo "running upx-clang-format"
@$(top_srcdir)/misc/scripts/upx-clang-format -i $(CLANG_FORMAT_FILES) @$(top_srcdir)/misc/scripts/upx-clang-format.sh -i $(CLANG_FORMAT_FILES)
endif endif
# #
@@ -100,7 +104,7 @@ CHECK_WHITESPACE = $(top_srcdir)/misc/scripts/check_whitespace.sh $(top_srcdir)
ifneq ($(wildcard $(top_srcdir)/.git/.),) ifneq ($(wildcard $(top_srcdir)/.git/.),)
CHECK_WHITESPACE = $(top_srcdir)/misc/scripts/check_whitespace_git.sh $(top_srcdir) CHECK_WHITESPACE = $(top_srcdir)/misc/scripts/check_whitespace_git.sh $(top_srcdir)
endif endif
check-whitespace : PHONY ; $(CHECK_WHITESPACE) check-whitespace: PHONY; $(CHECK_WHITESPACE)
endif endif
# vim:set ts=8 sw=8 noet: # vim:set ts=8 sw=8 noet:
+233 -181
View File
@@ -26,47 +26,55 @@
*/ */
#pragma once #pragma once
#ifndef UPX_BELE_H__
#define UPX_BELE_H__ 1
// BE - Big Endian // BE - Big Endian
// LE - Little Endian // LE - Little Endian
// NE - Native Endianness (aka host endianness) // NE - Native Endianness (aka Host Endianness aka CPU Endianness)
// TE - Target Endianness (not used here, see various packers) // TE - Target Endianness (not used here, see various packers)
#if 1
// some platforms may provide their own system bswapXX() functions, so rename to avoid conflicts
#undef bswap16
#undef bswap32
#undef bswap64
#define bswap16 upx_bswap16
#define bswap32 upx_bswap32
#define bswap64 upx_bswap64
#endif
/************************************************************************* /*************************************************************************
// core - NE // core - NE
**************************************************************************/ **************************************************************************/
static forceinline unsigned get_ne16(const void *p) { static forceinline unsigned get_ne16(const void *p) noexcept {
upx_uint16_t v = 0; upx_uint16_t v = 0;
upx_memcpy_inline(&v, p, sizeof(v)); upx_memcpy_inline(&v, p, sizeof(v));
return v; return v;
} }
static forceinline unsigned get_ne32(const void *p) { static forceinline unsigned get_ne32(const void *p) noexcept {
upx_uint32_t v = 0; upx_uint32_t v = 0;
upx_memcpy_inline(&v, p, sizeof(v)); upx_memcpy_inline(&v, p, sizeof(v));
return v; return v;
} }
static forceinline upx_uint64_t get_ne64(const void *p) { static forceinline upx_uint64_t get_ne64(const void *p) noexcept {
upx_uint64_t v = 0; upx_uint64_t v = 0;
upx_memcpy_inline(&v, p, sizeof(v)); upx_memcpy_inline(&v, p, sizeof(v));
return v; return v;
} }
static forceinline void set_ne16(void *p, unsigned vv) { static forceinline void set_ne16(void *p, unsigned vv) noexcept {
upx_uint16_t v = (upx_uint16_t) (vv & 0xffff); upx_uint16_t v = (upx_uint16_t) (vv & 0xffff);
upx_memcpy_inline(p, &v, sizeof(v)); upx_memcpy_inline(p, &v, sizeof(v));
} }
static forceinline void set_ne32(void *p, unsigned vv) { static forceinline void set_ne32(void *p, unsigned vv) noexcept {
upx_uint32_t v = vv; upx_uint32_t v = vv;
upx_memcpy_inline(p, &v, sizeof(v)); upx_memcpy_inline(p, &v, sizeof(v));
} }
static forceinline void set_ne64(void *p, upx_uint64_t vv) { static forceinline void set_ne64(void *p, upx_uint64_t vv) noexcept {
upx_uint64_t v = vv; upx_uint64_t v = vv;
upx_memcpy_inline(p, &v, sizeof(v)); upx_memcpy_inline(p, &v, sizeof(v));
} }
@@ -79,31 +87,36 @@ static forceinline void set_ne64(void *p, upx_uint64_t vv) {
ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(long) == 4) ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(long) == 4)
// unfortunately *not* constexpr with MSVC // unfortunately *not* constexpr with current MSVC
static forceinline unsigned bswap16(unsigned v) { return (unsigned) _byteswap_ulong(v << 16); } static forceinline unsigned bswap16(unsigned v) noexcept {
static forceinline unsigned bswap32(unsigned v) { return (unsigned) _byteswap_ulong(v); } return (unsigned) _byteswap_ulong(v << 16);
static forceinline upx_uint64_t bswap64(upx_uint64_t v) { return _byteswap_uint64(v); } }
static forceinline unsigned bswap32(unsigned v) noexcept { return (unsigned) _byteswap_ulong(v); }
static forceinline upx_uint64_t bswap64(upx_uint64_t v) noexcept { return _byteswap_uint64(v); }
#else #else
static forceinline constexpr unsigned bswap16(unsigned v) { static forceinline constexpr unsigned bswap16(unsigned v) noexcept {
// return __builtin_bswap16((upx_uint16_t) (v & 0xffff)); // return __builtin_bswap16((upx_uint16_t) (v & 0xffff));
// return (unsigned) __builtin_bswap64((upx_uint64_t) v << 48); // return (unsigned) __builtin_bswap64((upx_uint64_t) v << 48);
return __builtin_bswap32(v << 16); return __builtin_bswap32(v << 16);
} }
static forceinline constexpr unsigned bswap32(unsigned v) { static forceinline constexpr unsigned bswap32(unsigned v) noexcept {
// return (unsigned) __builtin_bswap64((upx_uint64_t) v << 32); // return (unsigned) __builtin_bswap64((upx_uint64_t) v << 32);
return __builtin_bswap32(v); return __builtin_bswap32(v);
} }
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) noexcept {
return __builtin_bswap64(v);
}
#endif #endif
static forceinline constexpr unsigned no_bswap16(unsigned v) { static forceinline constexpr unsigned no_bswap16(unsigned v) noexcept {
return v & 0xffff; // needed so that this is equivalent to bswap16() above // mask is needed so that for all v: bswap16(bswap16(v)) == no_bswap16(v)
return v & 0xffff;
} }
static forceinline constexpr unsigned no_bswap32(unsigned v) { return v; } static forceinline constexpr unsigned no_bswap32(unsigned v) noexcept { return v; }
static forceinline constexpr upx_uint64_t no_bswap64(upx_uint64_t v) { return v; } static forceinline constexpr upx_uint64_t no_bswap64(upx_uint64_t v) noexcept { return v; }
#if (ACC_ABI_BIG_ENDIAN) #if (ACC_ABI_BIG_ENDIAN)
#define ne16_to_be16(v) no_bswap16(v) #define ne16_to_be16(v) no_bswap16(v)
@@ -125,114 +138,119 @@ static forceinline constexpr upx_uint64_t no_bswap64(upx_uint64_t v) { return v;
// get/set 16/32/64 // get/set 16/32/64
**************************************************************************/ **************************************************************************/
inline unsigned get_be16(const void *p) { return ne16_to_be16(get_ne16(p)); } inline unsigned get_be16(const void *p) noexcept { return ne16_to_be16(get_ne16(p)); }
inline unsigned get_be32(const void *p) { return ne32_to_be32(get_ne32(p)); } inline unsigned get_be32(const void *p) noexcept { return ne32_to_be32(get_ne32(p)); }
inline upx_uint64_t get_be64(const void *p) { return ne64_to_be64(get_ne64(p)); } inline upx_uint64_t get_be64(const void *p) noexcept { return ne64_to_be64(get_ne64(p)); }
inline unsigned get_le16(const void *p) { return ne16_to_le16(get_ne16(p)); } inline unsigned get_le16(const void *p) noexcept { return ne16_to_le16(get_ne16(p)); }
inline unsigned get_le32(const void *p) { return ne32_to_le32(get_ne32(p)); } inline unsigned get_le32(const void *p) noexcept { return ne32_to_le32(get_ne32(p)); }
inline upx_uint64_t get_le64(const void *p) { return ne64_to_le64(get_ne64(p)); } inline upx_uint64_t get_le64(const void *p) noexcept { return ne64_to_le64(get_ne64(p)); }
inline void set_be16(void *p, unsigned v) { set_ne16(p, ne16_to_be16(v)); } inline void set_be16(void *p, unsigned v) noexcept { set_ne16(p, ne16_to_be16(v)); }
inline void set_be32(void *p, unsigned v) { set_ne32(p, ne32_to_be32(v)); } inline void set_be32(void *p, unsigned v) noexcept { set_ne32(p, ne32_to_be32(v)); }
inline void set_be64(void *p, upx_uint64_t v) { set_ne64(p, ne64_to_be64(v)); } inline void set_be64(void *p, upx_uint64_t v) noexcept { set_ne64(p, ne64_to_be64(v)); }
inline void set_le16(void *p, unsigned v) { set_ne16(p, ne16_to_le16(v)); } inline void set_le16(void *p, unsigned v) noexcept { set_ne16(p, ne16_to_le16(v)); }
inline void set_le32(void *p, unsigned v) { set_ne32(p, ne32_to_le32(v)); } inline void set_le32(void *p, unsigned v) noexcept { set_ne32(p, ne32_to_le32(v)); }
inline void set_le64(void *p, upx_uint64_t v) { set_ne64(p, ne64_to_le64(v)); } inline void set_le64(void *p, upx_uint64_t v) noexcept { set_ne64(p, ne64_to_le64(v)); }
/************************************************************************* /*************************************************************************
// get/set 24/26 // get/set 24/26
**************************************************************************/ **************************************************************************/
inline unsigned get_be24(const void *p) { inline unsigned get_be24(const void *p) noexcept {
const unsigned char *b = ACC_CCAST(const unsigned char *, p); const byte *b = ACC_CCAST(const byte *, p);
return (b[0] << 16) | (b[1] << 8) | (b[2] << 0); return (b[0] << 16) | (b[1] << 8) | (b[2] << 0);
} }
inline unsigned get_le24(const void *p) { inline unsigned get_le24(const void *p) noexcept {
const unsigned char *b = ACC_CCAST(const unsigned char *, p); const byte *b = ACC_CCAST(const byte *, p);
return (b[0] << 0) | (b[1] << 8) | (b[2] << 16); return (b[0] << 0) | (b[1] << 8) | (b[2] << 16);
} }
inline void set_be24(void *p, unsigned v) { inline void set_be24(void *p, unsigned v) noexcept {
unsigned char *b = ACC_PCAST(unsigned char *, p); byte *b = ACC_PCAST(byte *, p);
b[0] = ACC_ICONV(unsigned char, (v >> 16) & 0xff); b[0] = ACC_ICONV(byte, (v >> 16) & 0xff);
b[1] = ACC_ICONV(unsigned char, (v >> 8) & 0xff); b[1] = ACC_ICONV(byte, (v >> 8) & 0xff);
b[2] = ACC_ICONV(unsigned char, (v >> 0) & 0xff); b[2] = ACC_ICONV(byte, (v >> 0) & 0xff);
} }
inline void set_le24(void *p, unsigned v) { inline void set_le24(void *p, unsigned v) noexcept {
unsigned char *b = ACC_PCAST(unsigned char *, p); byte *b = ACC_PCAST(byte *, p);
b[0] = ACC_ICONV(unsigned char, (v >> 0) & 0xff); b[0] = ACC_ICONV(byte, (v >> 0) & 0xff);
b[1] = ACC_ICONV(unsigned char, (v >> 8) & 0xff); b[1] = ACC_ICONV(byte, (v >> 8) & 0xff);
b[2] = ACC_ICONV(unsigned char, (v >> 16) & 0xff); b[2] = ACC_ICONV(byte, (v >> 16) & 0xff);
} }
inline unsigned get_le26(const void *p) { return get_le32(p) & 0x03ffffff; } inline unsigned get_le26(const void *p) noexcept { return get_le32(p) & 0x03ffffff; }
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) { inline void set_le26(void *p, unsigned v) noexcept {
// preserve the top 6 bits // preserve the top 6 bits
#if 0 // set_le32(p, (get_le32(p) & 0xfc000000) | (v & 0x03ffffff));
set_le32(p, (get_le32(p) & 0xfc000000) | (v & 0x03ffffff));
#else
// optimized version, saving a runtime bswap32 // optimized version, saving a runtime bswap32
set_ne32(p, (get_ne32(p) & ne32_to_le32(0xfc000000)) | set_ne32(p, (get_ne32(p) & ne32_to_le32(0xfc000000)) |
(ne32_to_le32(v) & ne32_to_le32(0x03ffffff))); (ne32_to_le32(v) & ne32_to_le32(0x03ffffff)));
#endif }
inline void set_le19_5(void *p, unsigned v) noexcept {
set_le32(p, (get_le32(p) & 0xff00001f) | ((v & 0x0007ffff) << 5));
}
inline void set_le14_5(void *p, unsigned v) noexcept {
set_le32(p, (get_le32(p) & 0xfff8001f) | ((v & 0x00003fff) << 5));
} }
/************************************************************************* /*************************************************************************
// get signed values // get signed values
**************************************************************************/ **************************************************************************/
static forceinline int sign_extend(unsigned v, unsigned bits) { static forceinline int sign_extend(unsigned v, unsigned bits) noexcept {
const unsigned sign_bit = 1u << (bits - 1); const unsigned sign_bit = 1u << (bits - 1);
v &= sign_bit | (sign_bit - 1); v &= sign_bit | (sign_bit - 1);
v |= 0 - (v & sign_bit); v |= 0u - (v & sign_bit);
return ACC_ICAST(int, v); return ACC_ICAST(int, v);
} }
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) noexcept {
const upx_uint64_t sign_bit = 1ull << (bits - 1); const upx_uint64_t sign_bit = 1ull << (bits - 1);
v &= sign_bit | (sign_bit - 1); v &= sign_bit | (sign_bit - 1);
v |= 0 - (v & sign_bit); v |= 0ull - (v & sign_bit);
return ACC_ICAST(upx_int64_t, v); return ACC_ICAST(upx_int64_t, v);
} }
inline int get_be16_signed(const void *p) { inline int get_be16_signed(const void *p) noexcept {
unsigned v = get_be16(p); unsigned v = get_be16(p);
return sign_extend(v, 16); return sign_extend(v, 16);
} }
inline int get_be24_signed(const void *p) { inline int get_be24_signed(const void *p) noexcept {
unsigned v = get_be24(p); unsigned v = get_be24(p);
return sign_extend(v, 24); return sign_extend(v, 24);
} }
inline int get_be32_signed(const void *p) { inline int get_be32_signed(const void *p) noexcept {
unsigned v = get_be32(p); unsigned v = get_be32(p);
return sign_extend(v, 32); return sign_extend(v, 32);
} }
inline upx_int64_t get_be64_signed(const void *p) { inline upx_int64_t get_be64_signed(const void *p) noexcept {
upx_uint64_t v = get_be64(p); upx_uint64_t v = get_be64(p);
return sign_extend(v, 64); return sign_extend(v, 64);
} }
inline int get_le16_signed(const void *p) { inline int get_le16_signed(const void *p) noexcept {
unsigned v = get_le16(p); unsigned v = get_le16(p);
return sign_extend(v, 16); return sign_extend(v, 16);
} }
inline int get_le24_signed(const void *p) { inline int get_le24_signed(const void *p) noexcept {
unsigned v = get_le24(p); unsigned v = get_le24(p);
return sign_extend(v, 24); return sign_extend(v, 24);
} }
inline int get_le32_signed(const void *p) { inline int get_le32_signed(const void *p) noexcept {
unsigned v = get_le32(p); unsigned v = get_le32(p);
return sign_extend(v, 32); return sign_extend(v, 32);
} }
inline upx_int64_t get_le64_signed(const void *p) { inline upx_int64_t get_le64_signed(const void *p) noexcept {
upx_uint64_t v = get_le64(p); upx_uint64_t v = get_le64(p);
return sign_extend(v, 64); return sign_extend(v, 64);
} }
@@ -248,363 +266,358 @@ inline upx_int64_t get_le64_signed(const void *p) {
// to have gcc bug 17519 fixed - see http://gcc.gnu.org/PR17519 ] // to have gcc bug 17519 fixed - see http://gcc.gnu.org/PR17519 ]
**************************************************************************/ **************************************************************************/
struct alignas(1) BE16 { struct alignas(1) BE16 final {
typedef unsigned integral_conversion_type; // automatic conversion to unsigned typedef unsigned integral_conversion_type; // automatic conversion to unsigned
unsigned char d[2]; byte d[2];
BE16 &operator=(unsigned v) { forceinline operator unsigned() const noexcept { return get_be16(d); }
forceinline BE16 &operator=(unsigned v) noexcept {
set_be16(d, v); set_be16(d, v);
return *this; return *this;
} }
BE16 &operator+=(unsigned v) { BE16 &operator+=(unsigned v) noexcept {
set_be16(d, get_be16(d) + v); set_be16(d, get_be16(d) + v);
return *this; return *this;
} }
BE16 &operator-=(unsigned v) { BE16 &operator-=(unsigned v) noexcept {
set_be16(d, get_be16(d) - v); set_be16(d, get_be16(d) - v);
return *this; return *this;
} }
BE16 &operator*=(unsigned v) { BE16 &operator*=(unsigned v) noexcept {
set_be16(d, get_be16(d) * v); set_be16(d, get_be16(d) * v);
return *this; return *this;
} }
BE16 &operator/=(unsigned v) { BE16 &operator/=(unsigned v) noexcept {
set_be16(d, get_be16(d) / v); set_be16(d, get_be16(d) / v);
return *this; return *this;
} }
BE16 &operator&=(unsigned v) { BE16 &operator&=(unsigned v) noexcept {
set_be16(d, get_be16(d) & v); set_be16(d, get_be16(d) & v);
return *this; return *this;
} }
BE16 &operator|=(unsigned v) { BE16 &operator|=(unsigned v) noexcept {
set_be16(d, get_be16(d) | v); set_be16(d, get_be16(d) | v);
return *this; return *this;
} }
BE16 &operator^=(unsigned v) { BE16 &operator^=(unsigned v) noexcept {
set_be16(d, get_be16(d) ^ v); set_be16(d, get_be16(d) ^ v);
return *this; return *this;
} }
BE16 &operator<<=(unsigned v) { BE16 &operator<<=(unsigned v) noexcept {
set_be16(d, get_be16(d) << v); set_be16(d, get_be16(d) << v);
return *this; return *this;
} }
BE16 &operator>>=(unsigned v) { BE16 &operator>>=(unsigned v) noexcept {
set_be16(d, get_be16(d) >> v); set_be16(d, get_be16(d) >> v);
return *this; return *this;
} }
operator unsigned() const { return get_be16(d); } bool operator==(const BE16 &x) const noexcept { return memcmp(d, x.d, sizeof(d)) == 0; }
bool operator<(const BE16 &x) const noexcept { return unsigned(*this) < unsigned(x); }
bool operator<(const BE16 &v) const { return unsigned(*this) < unsigned(v); }
}; };
struct alignas(1) BE32 { struct alignas(1) BE32 final {
typedef unsigned integral_conversion_type; // automatic conversion to unsigned typedef unsigned integral_conversion_type; // automatic conversion to unsigned
unsigned char d[4]; byte d[4];
BE32 &operator=(unsigned v) { forceinline operator unsigned() const noexcept { return get_be32(d); }
forceinline BE32 &operator=(unsigned v) noexcept {
set_be32(d, v); set_be32(d, v);
return *this; return *this;
} }
BE32 &operator+=(unsigned v) { BE32 &operator+=(unsigned v) noexcept {
set_be32(d, get_be32(d) + v); set_be32(d, get_be32(d) + v);
return *this; return *this;
} }
BE32 &operator-=(unsigned v) { BE32 &operator-=(unsigned v) noexcept {
set_be32(d, get_be32(d) - v); set_be32(d, get_be32(d) - v);
return *this; return *this;
} }
BE32 &operator*=(unsigned v) { BE32 &operator*=(unsigned v) noexcept {
set_be32(d, get_be32(d) * v); set_be32(d, get_be32(d) * v);
return *this; return *this;
} }
BE32 &operator/=(unsigned v) { BE32 &operator/=(unsigned v) noexcept {
set_be32(d, get_be32(d) / v); set_be32(d, get_be32(d) / v);
return *this; return *this;
} }
BE32 &operator&=(unsigned v) { BE32 &operator&=(unsigned v) noexcept {
set_be32(d, get_be32(d) & v); set_be32(d, get_be32(d) & v);
return *this; return *this;
} }
BE32 &operator|=(unsigned v) { BE32 &operator|=(unsigned v) noexcept {
set_be32(d, get_be32(d) | v); set_be32(d, get_be32(d) | v);
return *this; return *this;
} }
BE32 &operator^=(unsigned v) { BE32 &operator^=(unsigned v) noexcept {
set_be32(d, get_be32(d) ^ v); set_be32(d, get_be32(d) ^ v);
return *this; return *this;
} }
BE32 &operator<<=(unsigned v) { BE32 &operator<<=(unsigned v) noexcept {
set_be32(d, get_be32(d) << v); set_be32(d, get_be32(d) << v);
return *this; return *this;
} }
BE32 &operator>>=(unsigned v) { BE32 &operator>>=(unsigned v) noexcept {
set_be32(d, get_be32(d) >> v); set_be32(d, get_be32(d) >> v);
return *this; return *this;
} }
operator unsigned() const { return get_be32(d); } bool operator==(const BE32 &x) const noexcept { return memcmp(d, x.d, sizeof(d)) == 0; }
bool operator<(const BE32 &x) const noexcept { return unsigned(*this) < unsigned(x); }
bool operator<(const BE32 &v) const { return unsigned(*this) < unsigned(v); }
}; };
struct alignas(1) BE64 { struct alignas(1) BE64 final {
typedef upx_uint64_t integral_conversion_type; // automatic conversion to upx_uint64_t typedef upx_uint64_t integral_conversion_type; // automatic conversion to upx_uint64_t
unsigned char d[8]; byte d[8];
BE64 &operator=(upx_uint64_t v) { forceinline operator upx_uint64_t() const noexcept { return get_be64(d); }
forceinline BE64 &operator=(upx_uint64_t v) noexcept {
set_be64(d, v); set_be64(d, v);
return *this; return *this;
} }
BE64 &operator+=(upx_uint64_t v) { BE64 &operator+=(upx_uint64_t v) noexcept {
set_be64(d, get_be64(d) + v); set_be64(d, get_be64(d) + v);
return *this; return *this;
} }
BE64 &operator-=(upx_uint64_t v) { BE64 &operator-=(upx_uint64_t v) noexcept {
set_be64(d, get_be64(d) - v); set_be64(d, get_be64(d) - v);
return *this; return *this;
} }
BE64 &operator*=(upx_uint64_t v) { BE64 &operator*=(upx_uint64_t v) noexcept {
set_be64(d, get_be64(d) * v); set_be64(d, get_be64(d) * v);
return *this; return *this;
} }
BE64 &operator/=(upx_uint64_t v) { BE64 &operator/=(upx_uint64_t v) noexcept {
set_be64(d, get_be64(d) / v); set_be64(d, get_be64(d) / v);
return *this; return *this;
} }
BE64 &operator&=(upx_uint64_t v) { BE64 &operator&=(upx_uint64_t v) noexcept {
set_be64(d, get_be64(d) & v); set_be64(d, get_be64(d) & v);
return *this; return *this;
} }
BE64 &operator|=(upx_uint64_t v) { BE64 &operator|=(upx_uint64_t v) noexcept {
set_be64(d, get_be64(d) | v); set_be64(d, get_be64(d) | v);
return *this; return *this;
} }
BE64 &operator^=(upx_uint64_t v) { BE64 &operator^=(upx_uint64_t v) noexcept {
set_be64(d, get_be64(d) ^ v); set_be64(d, get_be64(d) ^ v);
return *this; return *this;
} }
BE64 &operator<<=(unsigned v) { BE64 &operator<<=(unsigned v) noexcept {
set_be64(d, get_be64(d) << v); set_be64(d, get_be64(d) << v);
return *this; return *this;
} }
BE64 &operator>>=(unsigned v) { BE64 &operator>>=(unsigned v) noexcept {
set_be64(d, get_be64(d) >> v); set_be64(d, get_be64(d) >> v);
return *this; return *this;
} }
operator upx_uint64_t() const { return get_be64(d); } bool operator==(const BE64 &x) const noexcept { return memcmp(d, x.d, sizeof(d)) == 0; }
bool operator<(const BE64 &x) const noexcept { return upx_uint64_t(*this) < upx_uint64_t(x); }
bool operator<(const BE64 &v) const { return upx_uint64_t(*this) < upx_uint64_t(v); }
}; };
struct alignas(1) LE16 { struct alignas(1) LE16 final {
typedef unsigned integral_conversion_type; // automatic conversion to unsigned typedef unsigned integral_conversion_type; // automatic conversion to unsigned
unsigned char d[2]; byte d[2];
LE16 &operator=(unsigned v) { forceinline operator unsigned() const noexcept { return get_le16(d); }
forceinline LE16 &operator=(unsigned v) noexcept {
set_le16(d, v); set_le16(d, v);
return *this; return *this;
} }
LE16 &operator+=(unsigned v) { LE16 &operator+=(unsigned v) noexcept {
set_le16(d, get_le16(d) + v); set_le16(d, get_le16(d) + v);
return *this; return *this;
} }
LE16 &operator-=(unsigned v) { LE16 &operator-=(unsigned v) noexcept {
set_le16(d, get_le16(d) - v); set_le16(d, get_le16(d) - v);
return *this; return *this;
} }
LE16 &operator*=(unsigned v) { LE16 &operator*=(unsigned v) noexcept {
set_le16(d, get_le16(d) * v); set_le16(d, get_le16(d) * v);
return *this; return *this;
} }
LE16 &operator/=(unsigned v) { LE16 &operator/=(unsigned v) noexcept {
set_le16(d, get_le16(d) / v); set_le16(d, get_le16(d) / v);
return *this; return *this;
} }
LE16 &operator&=(unsigned v) { LE16 &operator&=(unsigned v) noexcept {
set_le16(d, get_le16(d) & v); set_le16(d, get_le16(d) & v);
return *this; return *this;
} }
LE16 &operator|=(unsigned v) { LE16 &operator|=(unsigned v) noexcept {
set_le16(d, get_le16(d) | v); set_le16(d, get_le16(d) | v);
return *this; return *this;
} }
LE16 &operator^=(unsigned v) { LE16 &operator^=(unsigned v) noexcept {
set_le16(d, get_le16(d) ^ v); set_le16(d, get_le16(d) ^ v);
return *this; return *this;
} }
LE16 &operator<<=(unsigned v) { LE16 &operator<<=(unsigned v) noexcept {
set_le16(d, get_le16(d) << v); set_le16(d, get_le16(d) << v);
return *this; return *this;
} }
LE16 &operator>>=(unsigned v) { LE16 &operator>>=(unsigned v) noexcept {
set_le16(d, get_le16(d) >> v); set_le16(d, get_le16(d) >> v);
return *this; return *this;
} }
operator unsigned() const { return get_le16(d); } bool operator==(const LE16 &x) const noexcept { return memcmp(d, x.d, sizeof(d)) == 0; }
bool operator<(const LE16 &x) const noexcept { return unsigned(*this) < unsigned(x); }
bool operator<(const LE16 &v) const { return unsigned(*this) < unsigned(v); }
}; };
struct alignas(1) LE32 { struct alignas(1) LE32 final {
typedef unsigned integral_conversion_type; // automatic conversion to unsigned typedef unsigned integral_conversion_type; // automatic conversion to unsigned
unsigned char d[4]; byte d[4];
LE32 &operator=(unsigned v) { forceinline operator unsigned() const noexcept { return get_le32(d); }
forceinline LE32 &operator=(unsigned v) noexcept {
set_le32(d, v); set_le32(d, v);
return *this; return *this;
} }
LE32 &operator+=(unsigned v) { LE32 &operator+=(unsigned v) noexcept {
set_le32(d, get_le32(d) + v); set_le32(d, get_le32(d) + v);
return *this; return *this;
} }
LE32 &operator-=(unsigned v) { LE32 &operator-=(unsigned v) noexcept {
set_le32(d, get_le32(d) - v); set_le32(d, get_le32(d) - v);
return *this; return *this;
} }
LE32 &operator*=(unsigned v) { LE32 &operator*=(unsigned v) noexcept {
set_le32(d, get_le32(d) * v); set_le32(d, get_le32(d) * v);
return *this; return *this;
} }
LE32 &operator/=(unsigned v) { LE32 &operator/=(unsigned v) noexcept {
set_le32(d, get_le32(d) / v); set_le32(d, get_le32(d) / v);
return *this; return *this;
} }
LE32 &operator&=(unsigned v) { LE32 &operator&=(unsigned v) noexcept {
set_le32(d, get_le32(d) & v); set_le32(d, get_le32(d) & v);
return *this; return *this;
} }
LE32 &operator|=(unsigned v) { LE32 &operator|=(unsigned v) noexcept {
set_le32(d, get_le32(d) | v); set_le32(d, get_le32(d) | v);
return *this; return *this;
} }
LE32 &operator^=(unsigned v) { LE32 &operator^=(unsigned v) noexcept {
set_le32(d, get_le32(d) ^ v); set_le32(d, get_le32(d) ^ v);
return *this; return *this;
} }
LE32 &operator<<=(unsigned v) { LE32 &operator<<=(unsigned v) noexcept {
set_le32(d, get_le32(d) << v); set_le32(d, get_le32(d) << v);
return *this; return *this;
} }
LE32 &operator>>=(unsigned v) { LE32 &operator>>=(unsigned v) noexcept {
set_le32(d, get_le32(d) >> v); set_le32(d, get_le32(d) >> v);
return *this; return *this;
} }
operator unsigned() const { return get_le32(d); } bool operator==(const LE32 &x) const noexcept { return memcmp(d, x.d, sizeof(d)) == 0; }
bool operator<(const LE32 &x) const noexcept { return unsigned(*this) < unsigned(x); }
bool operator<(const LE32 &v) const { return unsigned(*this) < unsigned(v); }
}; };
struct alignas(1) LE64 { struct alignas(1) LE64 final {
typedef upx_uint64_t integral_conversion_type; // automatic conversion to upx_uint64_t typedef upx_uint64_t integral_conversion_type; // automatic conversion to upx_uint64_t
unsigned char d[8]; byte d[8];
LE64 &operator=(upx_uint64_t v) { forceinline operator upx_uint64_t() const noexcept { return get_le64(d); }
forceinline LE64 &operator=(upx_uint64_t v) noexcept {
set_le64(d, v); set_le64(d, v);
return *this; return *this;
} }
LE64 &operator+=(upx_uint64_t v) { LE64 &operator+=(upx_uint64_t v) noexcept {
set_le64(d, get_le64(d) + v); set_le64(d, get_le64(d) + v);
return *this; return *this;
} }
LE64 &operator-=(upx_uint64_t v) { LE64 &operator-=(upx_uint64_t v) noexcept {
set_le64(d, get_le64(d) - v); set_le64(d, get_le64(d) - v);
return *this; return *this;
} }
LE64 &operator*=(upx_uint64_t v) { LE64 &operator*=(upx_uint64_t v) noexcept {
set_le64(d, get_le64(d) * v); set_le64(d, get_le64(d) * v);
return *this; return *this;
} }
LE64 &operator/=(upx_uint64_t v) { LE64 &operator/=(upx_uint64_t v) noexcept {
set_le64(d, get_le64(d) / v); set_le64(d, get_le64(d) / v);
return *this; return *this;
} }
LE64 &operator&=(upx_uint64_t v) { LE64 &operator&=(upx_uint64_t v) noexcept {
set_le64(d, get_le64(d) & v); set_le64(d, get_le64(d) & v);
return *this; return *this;
} }
LE64 &operator|=(upx_uint64_t v) { LE64 &operator|=(upx_uint64_t v) noexcept {
set_le64(d, get_le64(d) | v); set_le64(d, get_le64(d) | v);
return *this; return *this;
} }
LE64 &operator^=(upx_uint64_t v) { LE64 &operator^=(upx_uint64_t v) noexcept {
set_le64(d, get_le64(d) ^ v); set_le64(d, get_le64(d) ^ v);
return *this; return *this;
} }
LE64 &operator<<=(unsigned v) { LE64 &operator<<=(unsigned v) noexcept {
set_le64(d, get_le64(d) << v); set_le64(d, get_le64(d) << v);
return *this; return *this;
} }
LE64 &operator>>=(unsigned v) { LE64 &operator>>=(unsigned v) noexcept {
set_le64(d, get_le64(d) >> v); set_le64(d, get_le64(d) >> v);
return *this; return *this;
} }
operator upx_uint64_t() const { return get_le64(d); } bool operator==(const LE64 &x) const noexcept { return memcmp(d, x.d, sizeof(d)) == 0; }
bool operator<(const LE64 &x) const noexcept { return upx_uint64_t(*this) < upx_uint64_t(x); }
bool operator<(const LE64 &v) const { return upx_uint64_t(*this) < upx_uint64_t(v); }
}; };
// native types
#if (ACC_ABI_BIG_ENDIAN)
typedef BE16 NE16;
typedef BE32 NE32;
typedef BE64 NE64;
#else
typedef LE16 NE16;
typedef LE32 NE32;
typedef LE64 NE64;
#endif
/************************************************************************* /*************************************************************************
// global operators (pointer addition/subtraction) // global operators (pointer addition/subtraction)
**************************************************************************/ **************************************************************************/
template <class T> template <class T>
inline T *operator+(T *ptr, const BE16 &v) { inline T *operator+(T *ptr, const BE16 &v) noexcept {
return ptr + unsigned(v); return ptr + unsigned(v);
} }
template <class T> template <class T>
inline T *operator-(T *ptr, const BE16 &v) { inline T *operator-(T *ptr, const BE16 &v) noexcept {
return ptr - unsigned(v); return ptr - unsigned(v);
} }
template <class T> template <class T>
inline T *operator+(T *ptr, const BE32 &v) { inline T *operator+(T *ptr, const BE32 &v) noexcept {
return ptr + unsigned(v); return ptr + unsigned(v);
} }
template <class T> template <class T>
inline T *operator-(T *ptr, const BE32 &v) { inline T *operator-(T *ptr, const BE32 &v) noexcept {
return ptr - unsigned(v); return ptr - unsigned(v);
} }
template <class T> template <class T>
inline T *operator+(T *ptr, const LE16 &v) { inline T *operator+(T *ptr, const LE16 &v) noexcept {
return ptr + unsigned(v); return ptr + unsigned(v);
} }
template <class T> template <class T>
inline T *operator-(T *ptr, const LE16 &v) { inline T *operator-(T *ptr, const LE16 &v) noexcept {
return ptr - unsigned(v); return ptr - unsigned(v);
} }
template <class T> template <class T>
inline T *operator+(T *ptr, const LE32 &v) { inline T *operator+(T *ptr, const LE32 &v) noexcept {
return ptr + unsigned(v); return ptr + unsigned(v);
} }
template <class T> template <class T>
inline T *operator-(T *ptr, const LE32 &v) { inline T *operator-(T *ptr, const LE32 &v) noexcept {
return ptr - unsigned(v); return ptr - unsigned(v);
} }
// these are not implemented on purpose and will cause errors // these are not implemented on purpose and will cause errors
template <class T> template <class T>
T *operator+(T *ptr, const BE64 &v) DELETED_FUNCTION; T *operator+(T *ptr, const BE64 &v) noexcept DELETED_FUNCTION;
template <class T> template <class T>
T *operator-(T *ptr, const BE64 &v) DELETED_FUNCTION; T *operator-(T *ptr, const BE64 &v) noexcept DELETED_FUNCTION;
template <class T> template <class T>
T *operator+(T *ptr, const LE64 &v) DELETED_FUNCTION; T *operator+(T *ptr, const LE64 &v) noexcept DELETED_FUNCTION;
template <class T> template <class T>
T *operator-(T *ptr, const LE64 &v) DELETED_FUNCTION; T *operator-(T *ptr, const LE64 &v) noexcept DELETED_FUNCTION;
/************************************************************************* /*************************************************************************
// global overloads // global overloads
@@ -644,6 +657,47 @@ inline unsigned UPX_MIN(const LE32 &a, unsigned b) { return UPX_MIN(unsigned(a),
// misc support // misc support
**************************************************************************/ **************************************************************************/
// native types
#if (ACC_ABI_BIG_ENDIAN)
typedef BE16 NE16;
typedef BE32 NE32;
typedef BE64 NE64;
#define ne16_compare be16_compare
#define ne32_compare be32_compare
#define ne64_compare be64_compare
#define ne16_compare_signed be16_compare_signed
#define ne32_compare_signed be32_compare_signed
#define ne64_compare_signed be64_compare_signed
#else
typedef LE16 NE16;
typedef LE32 NE32;
typedef LE64 NE64;
#define ne16_compare le16_compare
#define ne32_compare le32_compare
#define ne64_compare le64_compare
#define ne16_compare_signed le16_compare_signed
#define ne32_compare_signed le32_compare_signed
#define ne64_compare_signed le64_compare_signed
#endif
// <type_traits> upx_is_integral
#define TT_IS_INTEGRAL(T) \
template <> \
struct upx_is_integral<T> : public std::true_type {}; \
template <> \
struct upx_is_integral<const T> : public std::true_type {}; \
template <> \
struct upx_is_integral<volatile T> : public std::true_type {}; \
template <> \
struct upx_is_integral<const volatile T> : public std::true_type {}
TT_IS_INTEGRAL(BE16);
TT_IS_INTEGRAL(BE32);
TT_IS_INTEGRAL(BE64);
TT_IS_INTEGRAL(LE16);
TT_IS_INTEGRAL(LE32);
TT_IS_INTEGRAL(LE64);
#undef TT_IS_INTEGRAL
// for use with qsort() // for use with qsort()
extern "C" { extern "C" {
int __acc_cdecl_qsort be16_compare(const void *, const void *); int __acc_cdecl_qsort be16_compare(const void *, const void *);
@@ -700,14 +754,12 @@ namespace N_BELE_RTP {
// util // util
namespace N_BELE_CTP { namespace N_BELE_CTP {
inline const N_BELE_RTP::AbstractPolicy *getRTP(const BEPolicy * /*dummy*/) { inline const N_BELE_RTP::AbstractPolicy *getRTP(const BEPolicy * /*dummy*/) noexcept {
return &N_BELE_RTP::be_policy; return &N_BELE_RTP::be_policy;
} }
inline const N_BELE_RTP::AbstractPolicy *getRTP(const LEPolicy * /*dummy*/) { inline const N_BELE_RTP::AbstractPolicy *getRTP(const LEPolicy * /*dummy*/) noexcept {
return &N_BELE_RTP::le_policy; return &N_BELE_RTP::le_policy;
} }
} // namespace N_BELE_CTP } // namespace N_BELE_CTP
#endif /* already included */
/* vim:set ts=4 sw=4 et: */ /* vim:set ts=4 sw=4 et: */
+26 -41
View File
@@ -25,9 +25,7 @@
<markus@oberhumer.com> <ezerotven+github@gmail.com> <markus@oberhumer.com> <ezerotven+github@gmail.com>
*/ */
#ifndef UPX_BELE_H__ // this is an internal include file private to bele.h
#error "this is an internal include file"
#endif
/************************************************************************* /*************************************************************************
// //
@@ -37,20 +35,20 @@
// CTP - Compile-Time Polymorphism (templates) // CTP - Compile-Time Polymorphism (templates)
#define V static inline #define V static inline
#define S static int __acc_cdecl_qsort #define S static int __acc_cdecl_qsort
#define C /*empty*/ #define C noexcept
#elif defined(BELE_RTP) #elif defined(BELE_RTP)
// RTP - Run-Time Polymorphism (virtual functions) // RTP - Run-Time Polymorphism (virtual functions)
#define V virtual #define V virtual
#define S virtual int #define S virtual int
#define C const #define C const noexcept
#else #else
#error #error
#endif #endif
#if defined(BELE_RTP) #if defined(BELE_RTP)
struct AbstractPolicy { struct AbstractPolicy {
inline AbstractPolicy() {} explicit inline AbstractPolicy() noexcept {}
virtual inline ~AbstractPolicy() {} virtual inline ~AbstractPolicy() noexcept {}
V bool isBE() C = 0; V bool isBE() C = 0;
V bool isLE() C = 0; V bool isLE() C = 0;
@@ -80,10 +78,11 @@ struct AbstractPolicy {
S u64_compare_signed(const void *a, const void *b) C = 0; S u64_compare_signed(const void *a, const void *b) C = 0;
private: private:
// disable copy, assignment and move assignment // disable copy and move
AbstractPolicy(const AbstractPolicy &) = delete; AbstractPolicy(const AbstractPolicy &) DELETED_FUNCTION;
AbstractPolicy &operator=(const AbstractPolicy &) = delete; AbstractPolicy &operator=(const AbstractPolicy &) DELETED_FUNCTION;
AbstractPolicy &operator=(AbstractPolicy &&) = delete; AbstractPolicy(AbstractPolicy &&) noexcept DELETED_FUNCTION;
AbstractPolicy &operator=(AbstractPolicy &&) noexcept DELETED_FUNCTION;
// disable dynamic allocation // disable dynamic allocation
ACC_CXX_DISABLE_NEW_DELETE ACC_CXX_DISABLE_NEW_DELETE
}; };
@@ -91,7 +90,7 @@ private:
#if defined(BELE_RTP) #if defined(BELE_RTP)
#undef C #undef C
#define C const override #define C const noexcept override
#endif #endif
struct BEPolicy struct BEPolicy
@@ -99,7 +98,7 @@ struct BEPolicy
final : public AbstractPolicy final : public AbstractPolicy
#endif #endif
{ {
inline BEPolicy() {} explicit inline BEPolicy() noexcept {}
#if defined(BELE_CTP) #if defined(BELE_CTP)
typedef N_BELE_RTP::BEPolicy RTP_Policy; typedef N_BELE_RTP::BEPolicy RTP_Policy;
#elif defined(BELE_RTP) #elif defined(BELE_RTP)
@@ -147,10 +146,11 @@ struct BEPolicy
} }
private: private:
// disable copy, assignment and move assignment // disable copy and move
BEPolicy(const BEPolicy &) = delete; BEPolicy(const BEPolicy &) DELETED_FUNCTION;
BEPolicy &operator=(const BEPolicy &) = delete; BEPolicy &operator=(const BEPolicy &) DELETED_FUNCTION;
BEPolicy &operator=(BEPolicy &&) = delete; BEPolicy(BEPolicy &&) noexcept DELETED_FUNCTION;
BEPolicy &operator=(BEPolicy &&) noexcept DELETED_FUNCTION;
// disable dynamic allocation // disable dynamic allocation
ACC_CXX_DISABLE_NEW_DELETE ACC_CXX_DISABLE_NEW_DELETE
}; };
@@ -160,7 +160,7 @@ struct LEPolicy
final : public AbstractPolicy final : public AbstractPolicy
#endif #endif
{ {
inline LEPolicy() {} explicit inline LEPolicy() noexcept {}
#if defined(BELE_CTP) #if defined(BELE_CTP)
typedef N_BELE_RTP::LEPolicy RTP_Policy; typedef N_BELE_RTP::LEPolicy RTP_Policy;
#elif defined(BELE_RTP) #elif defined(BELE_RTP)
@@ -208,41 +208,26 @@ struct LEPolicy
} }
private: private:
// disable copy, assignment and move assignment // disable copy and move
LEPolicy(const LEPolicy &) = delete; LEPolicy(const LEPolicy &) DELETED_FUNCTION;
LEPolicy &operator=(const LEPolicy &) = delete; LEPolicy &operator=(const LEPolicy &) DELETED_FUNCTION;
LEPolicy &operator=(LEPolicy &&) = delete; LEPolicy(LEPolicy &&) noexcept DELETED_FUNCTION;
LEPolicy &operator=(LEPolicy &&) noexcept DELETED_FUNCTION;
// disable dynamic allocation // disable dynamic allocation
ACC_CXX_DISABLE_NEW_DELETE ACC_CXX_DISABLE_NEW_DELETE
}; };
// native policy (aka host policy) // Native Endianness policy (aka host policy)
#if (ACC_ABI_BIG_ENDIAN) #if (ACC_ABI_BIG_ENDIAN)
typedef BEPolicy NEPolicy;
typedef BEPolicy HostPolicy; typedef BEPolicy HostPolicy;
#elif (ACC_ABI_LITTLE_ENDIAN) #elif (ACC_ABI_LITTLE_ENDIAN)
typedef LEPolicy NEPolicy;
typedef LEPolicy HostPolicy; typedef LEPolicy HostPolicy;
#else #else
#error "ACC_ABI_ENDIAN" #error "ACC_ABI_ENDIAN"
#endif #endif
#if 0 /* UNUSED */
struct HostAlignedPolicy {
#if defined(BELE_CTP)
enum { isBE = HostPolicy::isBE, isLE = HostPolicy::isLE };
#endif
typedef upx_uint16_t U16;
typedef upx_uint32_t U32;
typedef upx_uint64_t U64;
static void compileTimeAssertions() {
COMPILE_TIME_ASSERT(sizeof(U16) == 2)
COMPILE_TIME_ASSERT(sizeof(U32) == 4)
COMPILE_TIME_ASSERT(sizeof(U64) == 8)
}
};
#endif
#undef V #undef V
#undef S #undef S
#undef C #undef C
+333 -130
View File
@@ -28,6 +28,12 @@
/************************************************************************* /*************************************************************************
// upx_doctest_check() // upx_doctest_check()
//
// honors environment variables:
// UPX_DEBUG_DOCTEST_DISABLE
// UPX_DEBUG_DOCTEST_VERBOSE
//
// HINT: set "UPX_DEBUG_DOCTEST_DISABLE=1" for improved debugging experience
**************************************************************************/ **************************************************************************/
int upx_doctest_check(int argc, char **argv) { int upx_doctest_check(int argc, char **argv) {
@@ -39,20 +45,24 @@ int upx_doctest_check(int argc, char **argv) {
const char *e = getenv("UPX_DEBUG_DOCTEST_DISABLE"); const char *e = getenv("UPX_DEBUG_DOCTEST_DISABLE");
if (e && e[0] && strcmp(e, "0") != 0) if (e && e[0] && strcmp(e, "0") != 0)
return 0; return 0;
bool minimal = true; // only show failing tests bool minimal = true; // don't show summary
bool duration = false; // show timings bool duration = false; // don't show timings
bool success = false; // show all tests bool success = false; // don't show all succeeding tests
#if DEBUG #if DEBUG
// default for debug builds: do show the [doctest] summary
minimal = false; minimal = false;
#endif #endif
e = getenv("UPX_DEBUG_DOCTEST_VERBOSE"); e = getenv("UPX_DEBUG_DOCTEST_VERBOSE");
if (e && e[0]) { if (e && e[0]) {
minimal = false;
if (strcmp(e, "0") == 0) { if (strcmp(e, "0") == 0) {
minimal = true; minimal = true;
} else if (strcmp(e, "1") == 0) {
minimal = false;
} else if (strcmp(e, "2") == 0) { } else if (strcmp(e, "2") == 0) {
minimal = false;
duration = true; duration = true;
} else if (strcmp(e, "3") == 0) { } else if (strcmp(e, "3") == 0) {
minimal = false;
duration = true; duration = true;
success = true; success = true;
} }
@@ -82,6 +92,7 @@ int upx_doctest_check() { return upx_doctest_check(0, nullptr); }
// compile-time checks // compile-time checks
**************************************************************************/ **************************************************************************/
// need extra parenthesis because the C preprocessor does not understand C++ templates
ACC_COMPILE_TIME_ASSERT_HEADER((std::is_same<short, upx_int16_t>::value)) ACC_COMPILE_TIME_ASSERT_HEADER((std::is_same<short, upx_int16_t>::value))
ACC_COMPILE_TIME_ASSERT_HEADER((std::is_same<unsigned short, upx_uint16_t>::value)) ACC_COMPILE_TIME_ASSERT_HEADER((std::is_same<unsigned short, upx_uint16_t>::value))
ACC_COMPILE_TIME_ASSERT_HEADER((std::is_same<int, upx_int32_t>::value)) ACC_COMPILE_TIME_ASSERT_HEADER((std::is_same<int, upx_int32_t>::value))
@@ -89,17 +100,49 @@ ACC_COMPILE_TIME_ASSERT_HEADER((std::is_same<unsigned, upx_uint32_t>::value))
ACC_COMPILE_TIME_ASSERT_HEADER((std::is_same<long long, upx_int64_t>::value)) ACC_COMPILE_TIME_ASSERT_HEADER((std::is_same<long long, upx_int64_t>::value))
ACC_COMPILE_TIME_ASSERT_HEADER((std::is_same<unsigned long long, upx_uint64_t>::value)) ACC_COMPILE_TIME_ASSERT_HEADER((std::is_same<unsigned long long, upx_uint64_t>::value))
ACC_COMPILE_TIME_ASSERT_HEADER((is_same_all_v<int>) )
ACC_COMPILE_TIME_ASSERT_HEADER((is_same_all_v<int, int>) )
ACC_COMPILE_TIME_ASSERT_HEADER((is_same_all_v<int, int, int>) )
ACC_COMPILE_TIME_ASSERT_HEADER((!is_same_all_v<int, char>) )
ACC_COMPILE_TIME_ASSERT_HEADER((!is_same_all_v<int, char, int>) )
ACC_COMPILE_TIME_ASSERT_HEADER((!is_same_all_v<int, int, char>) )
ACC_COMPILE_TIME_ASSERT_HEADER((!is_same_any_v<int>) )
ACC_COMPILE_TIME_ASSERT_HEADER((is_same_any_v<int, int>) )
ACC_COMPILE_TIME_ASSERT_HEADER((is_same_any_v<int, char, int>) )
ACC_COMPILE_TIME_ASSERT_HEADER((is_same_any_v<int, int, char>) )
ACC_COMPILE_TIME_ASSERT_HEADER((!is_same_any_v<int, char>) )
ACC_COMPILE_TIME_ASSERT_HEADER((!is_same_any_v<int, char, char>) )
ACC_COMPILE_TIME_ASSERT_HEADER((!is_same_any_v<int, char, long>) )
ACC_COMPILE_TIME_ASSERT_HEADER(no_bswap16(0x04030201) == 0x0201) ACC_COMPILE_TIME_ASSERT_HEADER(no_bswap16(0x04030201) == 0x0201)
ACC_COMPILE_TIME_ASSERT_HEADER(no_bswap32(0x04030201) == 0x04030201) ACC_COMPILE_TIME_ASSERT_HEADER(no_bswap32(0x04030201) == 0x04030201)
ACC_COMPILE_TIME_ASSERT_HEADER(no_bswap64(0x0807060504030201ull) == 0x0807060504030201ull) ACC_COMPILE_TIME_ASSERT_HEADER(no_bswap64(0x0807060504030201ull) == 0x0807060504030201ull)
#if !(ACC_CC_MSC) #if !(ACC_CC_MSC) // unfortunately *not* constexpr with current MSVC
ACC_COMPILE_TIME_ASSERT_HEADER(bswap16(0x04030201) == 0x0102) ACC_COMPILE_TIME_ASSERT_HEADER(bswap16(0x04030201) == 0x0102)
ACC_COMPILE_TIME_ASSERT_HEADER(bswap32(0x04030201) == 0x01020304) ACC_COMPILE_TIME_ASSERT_HEADER(bswap32(0x04030201) == 0x01020304)
ACC_COMPILE_TIME_ASSERT_HEADER(bswap64(0x0807060504030201ull) == 0x0102030405060708ull) 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 #endif
ACC_COMPILE_TIME_ASSERT_HEADER(usizeof(int) == sizeof(int))
ACC_COMPILE_TIME_ASSERT_HEADER(usizeof('a') == sizeof(char))
ACC_COMPILE_TIME_ASSERT_HEADER(usizeof("") == 1)
ACC_COMPILE_TIME_ASSERT_HEADER(usizeof("a") == 2)
ACC_COMPILE_TIME_ASSERT_HEADER(usizeof(0) == sizeof(int))
ACC_COMPILE_TIME_ASSERT_HEADER(usizeof(0L) == sizeof(long))
ACC_COMPILE_TIME_ASSERT_HEADER(usizeof(0LL) == sizeof(long long))
ACC_COMPILE_TIME_ASSERT_HEADER(usizeof(nullptr) == sizeof(void *))
ACC_COMPILE_TIME_ASSERT_HEADER(usizeof(sizeof(0)) == sizeof(size_t))
ACC_COMPILE_TIME_ASSERT_HEADER(usizeof(usizeof(0)) == sizeof(unsigned))
ACC_COMPILE_TIME_ASSERT_HEADER(compile_time::string_len("") == 0) ACC_COMPILE_TIME_ASSERT_HEADER(compile_time::string_len("") == 0)
ACC_COMPILE_TIME_ASSERT_HEADER(compile_time::string_len("a") == 1) ACC_COMPILE_TIME_ASSERT_HEADER(compile_time::string_len("a") == 1)
ACC_COMPILE_TIME_ASSERT_HEADER(compile_time::string_len("ab") == 2)
ACC_COMPILE_TIME_ASSERT_HEADER(compile_time::string_len("abc") == 3)
ACC_COMPILE_TIME_ASSERT_HEADER(compile_time::string_eq("", "")) ACC_COMPILE_TIME_ASSERT_HEADER(compile_time::string_eq("", ""))
ACC_COMPILE_TIME_ASSERT_HEADER(!compile_time::string_eq("a", "")) ACC_COMPILE_TIME_ASSERT_HEADER(!compile_time::string_eq("a", ""))
@@ -139,92 +182,167 @@ ACC_COMPILE_TIME_ASSERT_HEADER((wchar_t) -1 > 0)
/************************************************************************* /*************************************************************************
// upx_compiler_sanity_check() // upx_compiler_sanity_check()
// assert a sane architecture and compiler // assert a sane architecture and compiler
// (modern compilers will optimize away most of this code)
**************************************************************************/ **************************************************************************/
namespace { namespace {
template <class T> template <class T>
struct TestBELE { struct CheckIntegral {
__acc_static_noinline bool test(void) { struct TestT {
// POD checks T a;
T x[2];
};
template <class U>
struct TestU {
U a = {};
const U b = {};
static constexpr U c = {};
U x[2] = {};
const U y[2] = {};
static constexpr U z[2] = {};
};
template <class U>
static void checkU(void) noexcept {
{ {
COMPILE_TIME_ASSERT(std::is_standard_layout<T>::value) U a = {};
COMPILE_TIME_ASSERT(std::is_trivial<T>::value) const U b = {};
// extra checks, these are probably implied by std::is_trivial: constexpr U c = {};
COMPILE_TIME_ASSERT(std::is_nothrow_default_constructible<T>::value) U x[2] = {};
COMPILE_TIME_ASSERT(std::is_trivially_copyable<T>::value) const U y[2] = {};
COMPILE_TIME_ASSERT(std::is_trivially_default_constructible<T>::value) constexpr U z[2] = {};
assert_noexcept(a == 0);
assert_noexcept(b == 0);
assert_noexcept(c == 0);
assert_noexcept(x[0] == 0 && x[1] == 0);
assert_noexcept(y[0] == 0 && y[1] == 0);
assert_noexcept(z[0] == 0 && z[1] == 0);
} }
// alignment checks
{ {
TestU<U> t;
assert_noexcept(t.a == 0);
assert_noexcept(t.b == 0);
assert_noexcept(t.c == 0);
assert_noexcept(t.x[0] == 0 && t.x[1] == 0);
assert_noexcept(t.y[0] == 0 && t.y[1] == 0);
assert_noexcept(t.z[0] == 0 && t.z[1] == 0);
}
#if __cplusplus < 202002L
COMPILE_TIME_ASSERT(std::is_pod<U>::value) // std::is_pod is deprecated in C++20
#endif
COMPILE_TIME_ASSERT(std::is_standard_layout<U>::value)
COMPILE_TIME_ASSERT(std::is_trivial<U>::value)
// more checks, these are probably implied by std::is_trivial
COMPILE_TIME_ASSERT(std::is_nothrow_default_constructible<U>::value)
COMPILE_TIME_ASSERT(std::is_nothrow_destructible<U>::value)
COMPILE_TIME_ASSERT(std::is_trivially_copyable<U>::value)
COMPILE_TIME_ASSERT(std::is_trivially_default_constructible<U>::value)
// UPX extras
COMPILE_TIME_ASSERT(upx_is_integral<U>::value)
COMPILE_TIME_ASSERT(upx_is_integral_v<U>)
}
static void check(void) noexcept {
{
TestT t = {};
assert_noexcept(t.a == 0);
assert_noexcept(t.x[0] == 0 && t.x[1] == 0);
}
{
const TestT t = {};
assert_noexcept(t.a == 0);
assert_noexcept(t.x[0] == 0 && t.x[1] == 0);
}
{
constexpr TestT t = {};
assert_noexcept(t.a == 0);
assert_noexcept(t.x[0] == 0 && t.x[1] == 0);
}
{
TestT t;
mem_clear(&t);
assert_noexcept(t.a == 0);
assert_noexcept(t.x[0] == 0 && t.x[1] == 0);
}
checkU<T>();
checkU<typename std::add_const<T>::type>();
}
};
template <class T>
struct CheckAlignment {
static void check(void) noexcept {
COMPILE_TIME_ASSERT_ALIGNED1(T) COMPILE_TIME_ASSERT_ALIGNED1(T)
struct alignas(1) test1_t { struct alignas(1) Test1 {
char a; char a;
T b; T b;
}; };
struct alignas(1) test2_t { struct alignas(1) Test2 {
char a; char a;
T b[3]; T b[3];
}; };
COMPILE_TIME_ASSERT_ALIGNED1(test1_t) COMPILE_TIME_ASSERT_ALIGNED1(Test1)
COMPILE_TIME_ASSERT_ALIGNED1(test2_t) COMPILE_TIME_ASSERT_ALIGNED1(Test2)
test1_t t1[7]; Test1 t1[7];
test2_t t2[7]; Test2 t2[7];
COMPILE_TIME_ASSERT(sizeof(test1_t) == 1 + sizeof(T)) COMPILE_TIME_ASSERT(sizeof(Test1) == 1 + sizeof(T))
COMPILE_TIME_ASSERT(sizeof(t1) == 7 + 7 * sizeof(T)) COMPILE_TIME_ASSERT(sizeof(t1) == 7 + 7 * sizeof(T))
COMPILE_TIME_ASSERT(sizeof(test2_t) == 1 + 3 * sizeof(T)) COMPILE_TIME_ASSERT(sizeof(Test2) == 1 + 3 * sizeof(T))
COMPILE_TIME_ASSERT(sizeof(t2) == 7 + 21 * sizeof(T)) COMPILE_TIME_ASSERT(sizeof(t2) == 7 + 21 * sizeof(T))
UNUSED(t1); UNUSED(t1);
UNUSED(t2); UNUSED(t2);
} }
#if 1 };
template <class T>
struct TestBELE {
static noinline bool test(void) noexcept {
CheckIntegral<T>::check();
CheckAlignment<T>::check();
// arithmetic checks // arithmetic checks
{ T allbits = {};
T allbits; assert_noexcept(allbits == 0);
allbits = 0;
allbits += 1; allbits += 1;
allbits -= 2; allbits -= 2;
T v1; T v1;
v1 = 1; v1 = 1;
v1 *= 2; v1 *= 4;
v1 /= 2;
v1 -= 1; v1 -= 1;
T v2; T v2;
v2 = 1; v2 = 1;
assert((v1 == v2)); assert_noexcept((v1 == v2));
assert(!(v1 != v2)); assert_noexcept(!(v1 != v2));
assert((v1 <= v2)); assert_noexcept((v1 <= v2));
assert((v1 >= v2)); assert_noexcept((v1 >= v2));
assert(!(v1 < v2)); assert_noexcept(!(v1 < v2));
assert(!(v1 > v2)); assert_noexcept(!(v1 > v2));
v2 ^= allbits; v2 ^= allbits;
assert(!(v1 == v2)); assert_noexcept(!(v1 == v2));
assert((v1 != v2)); assert_noexcept((v1 != v2));
assert((v1 <= v2)); assert_noexcept((v1 <= v2));
assert(!(v1 >= v2)); assert_noexcept(!(v1 >= v2));
assert((v1 < v2)); assert_noexcept((v1 < v2));
assert(!(v1 > v2)); assert_noexcept(!(v1 > v2));
v2 += 2; v2 += 2;
assert(v1 == 1); assert_noexcept(v1 == 1);
assert(v2 == 0); assert_noexcept(v2 == 0);
v1 <<= 1; v1 <<= 1;
v1 |= v2; v1 |= v2;
v1 >>= 1; v1 >>= 1;
v2 &= v1; v2 &= v1;
v2 /= v1; v2 /= v1;
v2 *= v1; v2 *= v1;
assert(v1 == 1); v1 += v2;
assert(v2 == 0); v1 -= v2;
assert_noexcept(v1 == 1);
assert_noexcept(v2 == 0);
if ((v1 ^ v2) != 1) if ((v1 ^ v2) != 1)
return false; return false;
}
#endif
return true; return true;
} }
}; };
template <class A, class B> template <class A, class B>
struct TestNoAliasingStruct { struct TestNoAliasingStruct {
__acc_static_noinline bool test(A *a, B *b) { static noinline bool test(A *a, B *b) noexcept {
*a = 0; *a = 0;
*b = 0; *b = 0;
*b -= 3; *b -= 3;
@@ -232,22 +350,51 @@ struct TestNoAliasingStruct {
} }
}; };
template <class A, class B> template <class A, class B>
__acc_static_forceinline bool testNoAliasing(A *a, B *b) { static forceinline bool testNoAliasing(A *a, B *b) noexcept {
return TestNoAliasingStruct<A, B>::test(a, b); return TestNoAliasingStruct<A, B>::test(a, b);
} }
template <class T> template <class T>
struct TestIntegerWrap { struct TestIntegerWrap {
static inline bool inc(T x) { return x + 1 > x; } static inline bool inc_gt(const T x) noexcept { return x + 1 > x; }
static inline bool dec(T x) { return x - 1 < x; } static inline bool dec_lt(const T x) noexcept { return x - 1 < x; }
static inline bool neg_eq(const T x) noexcept { return T(0) - x == x; }
}; };
static noinline void throwSomeValue(int x) {
if (x < 0)
throw int(x);
else
throw size_t(x);
}
static noinline void check_basic_cxx_exception_handling(void (*func)(int)) noexcept {
bool cxx_exception_handling_works = false;
try {
func(42);
} catch (const size_t &e) {
if (e == 42)
cxx_exception_handling_works = true;
} catch (...) {
}
assert_noexcept(cxx_exception_handling_works);
}
} // namespace } // namespace
#define ACC_WANT_ACC_CHK_CH 1 #define ACC_WANT_ACC_CHK_CH 1
#undef ACCCHK_ASSERT #undef ACCCHK_ASSERT
#include "../miniacc.h" #include "../miniacc.h"
void upx_compiler_sanity_check(void) { void upx_compiler_sanity_check(void) noexcept {
const char *e = getenv("UPX_DEBUG_DOCTEST_DISABLE");
if (e && e[0] && strcmp(e, "0") != 0) {
// If UPX_DEBUG_DOCTEST_DISABLE is set then we don't want to throw any
// exceptions in order to improve debugging experience.
} else {
// check working C++ exception handling to catch toolchain/qemu/wine/etc problems
check_basic_cxx_exception_handling(throwSomeValue);
}
#define ACC_WANT_ACC_CHK_CH 1 #define ACC_WANT_ACC_CHK_CH 1
#undef ACCCHK_ASSERT #undef ACCCHK_ASSERT
#define ACCCHK_ASSERT(expr) ACC_COMPILE_TIME_ASSERT(expr) #define ACCCHK_ASSERT(expr) ACC_COMPILE_TIME_ASSERT(expr)
@@ -274,100 +421,117 @@ void upx_compiler_sanity_check(void) {
COMPILE_TIME_ASSERT_ALIGNED1(LE32) COMPILE_TIME_ASSERT_ALIGNED1(LE32)
COMPILE_TIME_ASSERT_ALIGNED1(LE64) COMPILE_TIME_ASSERT_ALIGNED1(LE64)
CheckIntegral<char>::check();
CheckIntegral<signed char>::check();
CheckIntegral<unsigned char>::check();
CheckIntegral<short>::check();
CheckIntegral<int>::check();
CheckIntegral<long>::check();
CheckIntegral<long long>::check();
CheckIntegral<ptrdiff_t>::check();
CheckIntegral<size_t>::check();
CheckIntegral<upx_off_t>::check();
CheckIntegral<upx_uintptr_t>::check();
COMPILE_TIME_ASSERT(sizeof(upx_charptr_unit_type) == 1)
COMPILE_TIME_ASSERT_ALIGNED1(upx_charptr_unit_type)
COMPILE_TIME_ASSERT(sizeof(*((charptr) nullptr)) == 1)
COMPILE_TIME_ASSERT(sizeof(UPX_VERSION_STRING4) == 4 + 1) COMPILE_TIME_ASSERT(sizeof(UPX_VERSION_STRING4) == 4 + 1)
assert(strlen(UPX_VERSION_STRING4) == 4); assert_noexcept(strlen(UPX_VERSION_STRING4) == 4);
COMPILE_TIME_ASSERT(sizeof(UPX_VERSION_YEAR) == 4 + 1) COMPILE_TIME_ASSERT(sizeof(UPX_VERSION_YEAR) == 4 + 1)
assert(strlen(UPX_VERSION_YEAR) == 4); assert_noexcept(strlen(UPX_VERSION_YEAR) == 4);
assert(memcmp(UPX_VERSION_DATE_ISO, UPX_VERSION_YEAR, 4) == 0); assert_noexcept(memcmp(UPX_VERSION_DATE_ISO, UPX_VERSION_YEAR, 4) == 0);
assert(memcmp(&UPX_VERSION_DATE[sizeof(UPX_VERSION_DATE) - 1 - 4], UPX_VERSION_YEAR, 4) == 0); assert_noexcept(
memcmp(&UPX_VERSION_DATE[sizeof(UPX_VERSION_DATE) - 1 - 4], UPX_VERSION_YEAR, 4) == 0);
if (gitrev[0]) { if (gitrev[0]) {
size_t revlen = strlen(gitrev); size_t revlen = strlen(gitrev);
if (strncmp(gitrev, "ERROR", 5) == 0) { if (strncmp(gitrev, "ERROR", 5) == 0) {
assert(revlen == 5 || revlen == 6); assert_noexcept(revlen == 5 || revlen == 6);
} else { } else {
assert(revlen == 12 || revlen == 13); assert_noexcept(revlen == 12 || revlen == 13);
} }
if (revlen == 6 || revlen == 13) { if (revlen == 6 || revlen == 13) {
assert(gitrev[revlen - 1] == '+'); assert_noexcept(gitrev[revlen - 1] == '+');
} }
} }
assert(UPX_RSIZE_MAX_MEM == 805306368); assert_noexcept(UPX_RSIZE_MAX_MEM == 805306368);
#if 1 #if DEBUG || 1
assert(TestBELE<LE16>::test()); assert_noexcept(TestBELE<LE16>::test());
assert(TestBELE<LE32>::test()); assert_noexcept(TestBELE<LE32>::test());
assert(TestBELE<LE64>::test()); assert_noexcept(TestBELE<LE64>::test());
assert(TestBELE<BE16>::test()); assert_noexcept(TestBELE<BE16>::test());
assert(TestBELE<BE32>::test()); assert_noexcept(TestBELE<BE32>::test());
assert(TestBELE<BE64>::test()); assert_noexcept(TestBELE<BE64>::test());
{ {
alignas(16) static const unsigned char dd[32] = { alignas(16) static const byte dd[32] = {
0, 0, 0, 0, 0, 0, 0, 0xff, 0xfe, 0xfd, 0xfc, 0xfb, 0xfa, 0xf9, 0xf8, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xfe, 0xfd, 0xfc, 0xfb, 0xfa, 0xf9, 0xf8, 0,
0, 0, 0, 0x7f, 0x7e, 0x7d, 0x7c, 0x7b, 0x7a, 0x79, 0x78, 0, 0, 0, 0, 0}; 0, 0, 0, 0x7f, 0x7e, 0x7d, 0x7c, 0x7b, 0x7a, 0x79, 0x78, 0, 0, 0, 0, 0};
const unsigned char *d; const byte *d;
const N_BELE_RTP::AbstractPolicy *bele; const N_BELE_RTP::AbstractPolicy *bele;
d = dd + 7; d = dd + 7;
assert(upx_adler32(d, 4) == 0x09f003f7); assert_noexcept(upx_adler32(d, 4) == 0x09f003f7);
assert(upx_adler32(d, 4, 0) == 0x09ec03f6); assert_noexcept(upx_adler32(d, 4, 0) == 0x09ec03f6);
assert(upx_adler32(d, 4, 1) == 0x09f003f7); assert_noexcept(upx_adler32(d, 4, 1) == 0x09f003f7);
bele = &N_BELE_RTP::be_policy; bele = &N_BELE_RTP::be_policy;
assert(get_be16(d) == 0xfffe); assert_noexcept(get_be16(d) == 0xfffe);
assert(bele->get16(d) == 0xfffe); assert_noexcept(bele->get16(d) == 0xfffe);
assert(get_be16_signed(d) == -2); assert_noexcept(get_be16_signed(d) == -2);
assert(get_be24(d) == 0xfffefd); assert_noexcept(get_be24(d) == 0xfffefd);
assert(bele->get24(d) == 0xfffefd); assert_noexcept(bele->get24(d) == 0xfffefd);
assert(get_be24_signed(d) == -259); assert_noexcept(get_be24_signed(d) == -259);
assert(get_be32(d) == 0xfffefdfc); assert_noexcept(get_be32(d) == 0xfffefdfc);
assert(bele->get32(d) == 0xfffefdfc); assert_noexcept(bele->get32(d) == 0xfffefdfc);
assert(get_be32_signed(d) == -66052); assert_noexcept(get_be32_signed(d) == -66052);
bele = &N_BELE_RTP::le_policy; bele = &N_BELE_RTP::le_policy;
assert(get_le16(d) == 0xfeff); assert_noexcept(get_le16(d) == 0xfeff);
assert(bele->get16(d) == 0xfeff); assert_noexcept(bele->get16(d) == 0xfeff);
assert(get_le16_signed(d) == -257); assert_noexcept(get_le16_signed(d) == -257);
assert(get_le24(d) == 0xfdfeff); assert_noexcept(get_le24(d) == 0xfdfeff);
assert(bele->get24(d) == 0xfdfeff); assert_noexcept(bele->get24(d) == 0xfdfeff);
assert(get_le24_signed(d) == -131329); assert_noexcept(get_le24_signed(d) == -131329);
assert(get_le32(d) == 0xfcfdfeff); assert_noexcept(get_le32(d) == 0xfcfdfeff);
assert(bele->get32(d) == 0xfcfdfeff); assert_noexcept(bele->get32(d) == 0xfcfdfeff);
assert(get_le32_signed(d) == -50462977); assert_noexcept(get_le32_signed(d) == -50462977);
assert(get_le64_signed(d) == -506097522914230529LL); assert_noexcept(get_le64_signed(d) == -506097522914230529LL);
assert(find_be16(d, 2, 0xfffe) == 0); assert_noexcept(find_be16(d, 2, 0xfffe) == 0);
assert(find_le16(d, 2, 0xfeff) == 0); assert_noexcept(find_le16(d, 2, 0xfeff) == 0);
assert(find_be32(d, 4, 0xfffefdfc) == 0); assert_noexcept(find_be32(d, 4, 0xfffefdfc) == 0);
assert(find_le32(d, 4, 0xfcfdfeff) == 0); assert_noexcept(find_le32(d, 4, 0xfcfdfeff) == 0);
d += 12; d += 12;
assert(get_be16_signed(d) == 32638); assert_noexcept(get_be16_signed(d) == 32638);
assert(get_be24_signed(d) == 8355453); assert_noexcept(get_be24_signed(d) == 8355453);
assert(get_be32_signed(d) == 2138996092); assert_noexcept(get_be32_signed(d) == 2138996092);
assert(get_be64_signed(d) == 9186918263483431288LL); assert_noexcept(get_be64_signed(d) == 9186918263483431288LL);
} }
{ {
unsigned dd; unsigned dd;
void *const d = &dd; void *const d = &dd;
dd = ne32_to_le32(0xf7f6f5f4); dd = ne32_to_le32(0xf7f6f5f4);
assert(get_le26(d) == 0x03f6f5f4); assert_noexcept(get_le26(d) == 0x03f6f5f4);
set_le26(d, 0); set_le26(d, 0);
assert(get_le26(d) == 0); assert_noexcept(get_le26(d) == 0);
assert(dd == ne32_to_le32(0xf4000000)); assert_noexcept(dd == ne32_to_le32(0xf4000000));
set_le26(d, 0xff020304); set_le26(d, 0xff020304);
assert(get_le26(d) == 0x03020304); assert_noexcept(get_le26(d) == 0x03020304);
assert(dd == ne32_to_le32(0xf7020304)); assert_noexcept(dd == ne32_to_le32(0xf7020304));
} }
{ {
upx_uint16_t a; upx_uint16_t a = 0;
upx_uint32_t b; upx_uint32_t b = 0;
upx_uint64_t c; upx_uint64_t c = 0;
set_ne16(&a, 0x04030201); // ignore upper bits set_ne16(&a, 0x04030201); // ignore upper bits
set_ne32(&b, 0x04030201); set_ne32(&b, 0x04030201);
set_ne64(&c, 0x0807060504030201ull); set_ne64(&c, 0x0807060504030201ull);
assert(a == 0x0201); assert_noexcept(a == 0x0201);
assert(b == 0x04030201); assert_noexcept(b == 0x04030201);
assert(c == 0x0807060504030201ull); assert_noexcept(c == 0x0807060504030201ull);
assert(get_ne16(&a) == 0x0201); assert_noexcept(get_ne16(&a) == 0x0201);
assert(get_ne32(&b) == 0x04030201); assert_noexcept(get_ne32(&b) == 0x04030201);
assert(get_ne64(&c) == 0x0807060504030201ull); assert_noexcept(get_ne64(&c) == 0x0807060504030201ull);
} }
#endif #endif // DEBUG
union { union {
short v_short; short v_short;
int v_int; int v_int;
@@ -380,31 +544,70 @@ void upx_compiler_sanity_check(void) {
LE32 l32; LE32 l32;
LE64 l64; LE64 l64;
} u; } u;
assert(testNoAliasing(&u.v_short, &u.b32)); assert_noexcept(testNoAliasing(&u.v_short, &u.b32));
assert(testNoAliasing(&u.v_short, &u.l32)); assert_noexcept(testNoAliasing(&u.v_short, &u.l32));
assert(testNoAliasing(&u.v_int, &u.b64)); assert_noexcept(testNoAliasing(&u.v_int, &u.b64));
assert(testNoAliasing(&u.v_int, &u.l64)); assert_noexcept(testNoAliasing(&u.v_int, &u.l64));
// check working -fno-strict-aliasing // check working -fno-strict-aliasing
assert(testNoAliasing(&u.v_short, &u.v_int)); assert_noexcept(testNoAliasing(&u.v_short, &u.v_int));
assert(testNoAliasing(&u.v_int, &u.v_long)); assert_noexcept(testNoAliasing(&u.v_int, &u.v_long));
assert(testNoAliasing(&u.v_int, &u.v_llong)); assert_noexcept(testNoAliasing(&u.v_int, &u.v_llong));
assert(testNoAliasing(&u.v_long, &u.v_llong)); assert_noexcept(testNoAliasing(&u.v_long, &u.v_llong));
assert(TestIntegerWrap<unsigned>::inc(0)); assert_noexcept(TestIntegerWrap<unsigned>::inc_gt(0));
assert(!TestIntegerWrap<unsigned>::inc(UINT_MAX)); assert_noexcept(!TestIntegerWrap<unsigned>::inc_gt(UINT_MAX));
assert(TestIntegerWrap<unsigned>::dec(1)); assert_noexcept(TestIntegerWrap<unsigned>::dec_lt(1));
assert(!TestIntegerWrap<unsigned>::dec(0)); assert_noexcept(!TestIntegerWrap<unsigned>::dec_lt(0));
assert_noexcept(TestIntegerWrap<unsigned>::neg_eq(0));
assert_noexcept(!TestIntegerWrap<unsigned>::neg_eq(1));
assert_noexcept(!TestIntegerWrap<unsigned>::neg_eq(UINT_MAX));
// check working -fno-strict-overflow // check working -fno-strict-overflow
assert(TestIntegerWrap<int>::inc(0)); assert_noexcept(TestIntegerWrap<int>::inc_gt(0));
assert(!TestIntegerWrap<int>::inc(INT_MAX)); assert_noexcept(!TestIntegerWrap<int>::inc_gt(INT_MAX));
assert(TestIntegerWrap<int>::dec(0)); assert_noexcept(TestIntegerWrap<int>::dec_lt(0));
assert(!TestIntegerWrap<int>::dec(INT_MIN)); assert_noexcept(!TestIntegerWrap<int>::dec_lt(INT_MIN));
assert_noexcept(TestIntegerWrap<int>::neg_eq(0));
assert_noexcept(!TestIntegerWrap<int>::neg_eq(1));
assert_noexcept(!TestIntegerWrap<int>::neg_eq(INT_MAX));
assert_noexcept(TestIntegerWrap<int>::neg_eq(INT_MIN)); // special case
} }
/************************************************************************* /*************************************************************************
// some doctest test cases // some doctest test cases
**************************************************************************/ **************************************************************************/
TEST_CASE("assert_noexcept") {
// just to make sure that our own assert macros don't generate any warnings
byte dummy = 0;
byte *ptr1 = &dummy;
const byte *const ptr2 = &dummy;
void *ptr3 = nullptr;
assert(true);
assert(1);
assert(ptr1);
assert(ptr2);
assert(!ptr3);
assert_noexcept(true);
assert_noexcept(1);
assert_noexcept(ptr1);
assert_noexcept(ptr2);
assert_noexcept(!ptr3);
}
TEST_CASE("noncopyable") {
struct Test : private noncopyable {
int v = 1;
};
Test t = {};
CHECK(t.v == 1);
#if (ACC_CC_MSC) // MSVC thinks that Test is not std::is_trivially_copyable; true or compiler bug?
t.v = 0;
#else
mem_clear(&t);
#endif
CHECK(t.v == 0);
}
TEST_CASE("acc_vget") { TEST_CASE("acc_vget") {
CHECK_EQ(acc_vget_int(0, 0), 0); CHECK_EQ(acc_vget_int(0, 0), 0);
CHECK_EQ(acc_vget_long(1, -1), 1); CHECK_EQ(acc_vget_long(1, -1), 1);
@@ -454,7 +657,7 @@ TEST_CASE("working -fno-strict-overflow") {
} }
TEST_CASE("libc snprintf") { TEST_CASE("libc snprintf") {
// runtime check that Win32/MinGW <stdio.h> works as expected // runtime check that Windows/MinGW <stdio.h> works as expected
char buf[64]; char buf[64];
long long ll = acc_vget_int(-1, 0); long long ll = acc_vget_int(-1, 0);
unsigned long long llu = (unsigned long long) ll; unsigned long long llu = (unsigned long long) ll;
+14 -6
View File
@@ -29,23 +29,31 @@
**************************************************************************/ **************************************************************************/
#define DOCTEST_CONFIG_IMPLEMENT #define DOCTEST_CONFIG_IMPLEMENT
#if !defined(UPX_DOCTEST_CONFIG_MULTITHREADING) #define DOCTEST_CONFIG_NO_UNPREFIXED_OPTIONS
#define DOCTEST_CONFIG_NO_MULTITHREADING
#endif #if !defined(DOCTEST_CONFIG_DISABLE)
#if defined(__i386__) && defined(__MSDOS__) && defined(__DJGPP__) && defined(__GNUC__) #if defined(__i386__) && defined(__MSDOS__) && defined(__DJGPP__) && defined(__GNUC__)
#define DOCTEST_CONFIG_NO_MULTITHREADING
#define DOCTEST_CONFIG_NO_POSIX_SIGNALS #define DOCTEST_CONFIG_NO_POSIX_SIGNALS
#elif defined(__m68k__) && defined(__atarist__) && defined(__GNUC__) #elif defined(__m68k__) && defined(__atarist__) && defined(__GNUC__)
#define DOCTEST_CONFIG_COLORS_NONE #define DOCTEST_CONFIG_COLORS_NONE
#define DOCTEST_CONFIG_NO_MULTITHREADING
#define DOCTEST_CONFIG_NO_POSIX_SIGNALS #define DOCTEST_CONFIG_NO_POSIX_SIGNALS
#pragma GCC diagnostic ignored "-Wshadow" #pragma GCC diagnostic ignored "-Wshadow"
#endif #endif
#define DOCTEST_CONFIG_NO_UNPREFIXED_OPTIONS
#if !defined(DOCTEST_CONFIG_DISABLE) #if !defined(UPX_DOCTEST_CONFIG_MULTITHREADING)
#define DOCTEST_CONFIG_NO_MULTITHREADING
#endif
#if defined(__clang__) && defined(__FAST_MATH__) && defined(__INTEL_LLVM_COMPILER) #if defined(__clang__) && defined(__FAST_MATH__) && defined(__INTEL_LLVM_COMPILER)
// warning: comparison with NaN always evaluates to false in fast floating point modes // warning: comparison with NaN always evaluates to false in fast floating point modes
#pragma clang diagnostic ignored "-Wtautological-constant-compare" #pragma clang diagnostic ignored "-Wtautological-constant-compare"
#endif #endif
#include <doctest/doctest/parts/doctest.cpp> #include <doctest/doctest/parts/doctest.cpp>
#endif
#endif // DOCTEST_CONFIG_DISABLE
/* vim:set ts=4 sw=4 et: */ /* vim:set ts=4 sw=4 et: */
+75 -20
View File
@@ -91,6 +91,17 @@ TEST_CASE("basic xspan usage") {
CHECK_NOTHROW(raw_bytes(a0, 0)); CHECK_NOTHROW(raw_bytes(a0, 0));
CHECK_THROWS(raw_bytes(a0, 1)); CHECK_THROWS(raw_bytes(a0, 1));
CHECK_THROWS(raw_index_bytes(a0, 0, 0)); CHECK_THROWS(raw_index_bytes(a0, 0, 0));
CHECK(raw_bytes(b0, 0) == buf);
CHECK(raw_bytes(bp, 0) == buf);
// info: these will fail if we ever add an overload for bounded-arrays
#if WITH_XSPAN >= 2
CHECK(b0.raw_size_in_bytes() == 0u);
CHECK(bp.raw_size_in_bytes() == 0u);
#endif
CHECK(raw_bytes(b0, 999999) == buf);
CHECK(raw_bytes(bp, 999999) == buf);
CHECK(raw_bytes(c0, 4) == buf); CHECK(raw_bytes(c0, 4) == buf);
CHECK(raw_index_bytes(c0, 1, 3) == buf + 1); CHECK(raw_index_bytes(c0, 1, 3) == buf + 1);
CHECK(raw_bytes(cp, 4) == buf); CHECK(raw_bytes(cp, 4) == buf);
@@ -104,8 +115,6 @@ TEST_CASE("basic xspan usage") {
} }
SUBCASE("XSPAN_x_VAR") { SUBCASE("XSPAN_x_VAR") {
XSPAN_0_VAR(char, a0, nullptr);
XSPAN_0_VAR(char, b0, buf); XSPAN_0_VAR(char, b0, buf);
XSPAN_P_VAR(char, bp, buf); XSPAN_P_VAR(char, bp, buf);
@@ -124,7 +133,6 @@ TEST_CASE("basic xspan usage") {
XSPAN_0_VAR(const char, const z0p, yp); XSPAN_0_VAR(const char, const z0p, yp);
XSPAN_0_VAR(const char, const z0s, xs); XSPAN_0_VAR(const char, const z0s, xs);
CHECK((a0 == nullptr));
CHECK(c0 == b0); CHECK(c0 == b0);
CHECK(cp == bp); CHECK(cp == bp);
CHECK(cs == bp); CHECK(cs == bp);
@@ -133,9 +141,24 @@ TEST_CASE("basic xspan usage") {
CHECK(x0 == z0p); CHECK(x0 == z0p);
CHECK(xp == z0s); CHECK(xp == z0s);
#if WITH_XSPAN >= 1 || __cplusplus >= 201103L
XSPAN_0_VAR(char, a0, nullptr);
CHECK((a0 == nullptr));
CHECK_NOTHROW(raw_bytes(a0, 0)); CHECK_NOTHROW(raw_bytes(a0, 0));
CHECK_THROWS(raw_bytes(a0, 1)); CHECK_THROWS(raw_bytes(a0, 1));
CHECK_THROWS(raw_index_bytes(a0, 0, 0)); CHECK_THROWS(raw_index_bytes(a0, 0, 0));
#endif
CHECK(raw_bytes(b0, 0) == buf);
CHECK(raw_bytes(bp, 0) == buf);
// info: these will fail if we ever add an overload for bounded-arrays
#if WITH_XSPAN >= 2
CHECK(b0.raw_size_in_bytes() == 0u);
CHECK(bp.raw_size_in_bytes() == 0u);
#endif
CHECK(raw_bytes(b0, 999999) == buf);
CHECK(raw_bytes(bp, 999999) == buf);
CHECK(raw_bytes(c0, 4) == buf); CHECK(raw_bytes(c0, 4) == buf);
CHECK(raw_index_bytes(c0, 1, 3) == buf + 1); CHECK(raw_index_bytes(c0, 1, 3) == buf + 1);
CHECK(raw_bytes(cp, 4) == buf); CHECK(raw_bytes(cp, 4) == buf);
@@ -592,6 +615,8 @@ TEST_CASE("Span subspan") {
TEST_CASE("Span constness") { TEST_CASE("Span constness") {
static char buf[4] = {0, 1, 2, 3}; static char buf[4] = {0, 1, 2, 3};
// NOLINTBEGIN(performance-unnecessary-copy-initialization)
XSPAN_0(char) b0(buf, 4); XSPAN_0(char) b0(buf, 4);
XSPAN_P(char) bp(buf, 4); XSPAN_P(char) bp(buf, 4);
XSPAN_S(char) bs(buf, 4); XSPAN_S(char) bs(buf, 4);
@@ -612,6 +637,8 @@ TEST_CASE("Span constness") {
XSPAN_P(const char) xpc(bp); XSPAN_P(const char) xpc(bp);
XSPAN_S(const char) xsc(bs); XSPAN_S(const char) xsc(bs);
// NOLINTEND(performance-unnecessary-copy-initialization)
CHECK(ptr_diff_bytes(b0, buf) == 0); CHECK(ptr_diff_bytes(b0, buf) == 0);
CHECK(ptr_diff_bytes(bp, buf) == 0); CHECK(ptr_diff_bytes(bp, buf) == 0);
CHECK(ptr_diff_bytes(bs, buf) == 0); CHECK(ptr_diff_bytes(bs, buf) == 0);
@@ -720,30 +747,52 @@ TEST_CASE("PtrOrSpan char") {
} }
TEST_CASE("PtrOrSpan int") { TEST_CASE("PtrOrSpan int") {
int buf[8] = {0, 1, 2, 3, 4, 5, 6, 7}; int buf[8] = {0, 11, 22, 33, 44, 55, 66, 77};
XSPAN_P(int) a(buf, XSpanCount(8)); XSPAN_P(const int) a(buf, XSpanCount(8));
CHECK(a.raw_size_in_bytes() == 8 * sizeof(int)); CHECK(a.raw_size_in_bytes() == 8 * sizeof(int));
XSPAN_P(int) b = a.subspan(0, 7); XSPAN_P(const int) b = a.subspan(0, 7);
CHECK(b.raw_size_in_bytes() == 7 * sizeof(int)); CHECK(b.raw_size_in_bytes() == 7 * sizeof(int));
XSPAN_P(int) c = (b + 1).subspan(0, 6); XSPAN_P(const int) c = (b + 1).subspan(0, 6);
CHECK(c.raw_size_in_bytes() == 6 * sizeof(int)); CHECK(c.raw_size_in_bytes() == 6 * sizeof(int));
a += 1; a += 1;
CHECK(*a == 1); CHECK(a == buf + 1);
CHECK(*a++ == 1); CHECK(*a == 11);
CHECK(*++a == 3); CHECK(*a++ == 11);
CHECK(--*a == 2); CHECK(a == buf + 2);
CHECK(*a-- == 2); CHECK(*a == 22);
CHECK(*++a == 33);
CHECK(a == buf + 3);
CHECK(*a == 33);
CHECK(*--a == 22);
CHECK(a == buf + 2);
CHECK(*a == 22);
CHECK(*a-- == 22);
CHECK(a == buf + 1);
CHECK(*a == 11);
CHECK(*b == 0); CHECK(*b == 0);
CHECK(*c == 1); CHECK(*c == 11);
a = buf + 7; a -= 1;
a += 7;
#ifdef UPX_VERSION_HEX #ifdef UPX_VERSION_HEX
CHECK(get_le32(a) == ne32_to_le32(7)); CHECK(get_le32(a) == ne32_to_le32(77));
#endif #endif
a++; a++;
#ifdef UPX_VERSION_HEX #ifdef UPX_VERSION_HEX
CHECK_THROWS(get_le32(a)); CHECK_THROWS(get_le32(a));
#endif #endif
CHECK_THROWS(raw_bytes(a, 1)); CHECK_THROWS(raw_bytes(a, 1));
CHECK_THROWS(a++);
CHECK_THROWS(++a);
CHECK_THROWS(a += 1);
CHECK(a == buf + 8);
a = buf;
CHECK_THROWS(a--);
CHECK_THROWS(--a);
CHECK_THROWS(a -= 1);
CHECK_THROWS(a += 9);
CHECK(a == buf);
a += 8;
CHECK(a == buf + 8);
} }
/************************************************************************* /*************************************************************************
@@ -758,6 +807,9 @@ __acc_static_noinline int foo(T p) {
r += *++p; r += *++p;
p += 3; p += 3;
r += *p; r += *p;
r += *--p;
r += *p--;
r += *p;
return r; return r;
} }
@@ -779,11 +831,14 @@ make_span_s(T *ptr, size_t count) {
} // namespace } // namespace
TEST_CASE("Span codegen") { TEST_CASE("Span codegen") {
char buf[8] = {0, 1, 2, 3, 4, 5, 6, 7}; upx_uint8_t buf[8] = {0, 1, 2, 3, 4, 5, 6, 7};
CHECK(foo(buf) == 0 + 2 + 5); CHECK(foo(buf) == 0 + 2 + 5 + 4 + 4 + 3);
CHECK(foo(make_span_0(buf, 8)) == 0 + 2 + 5); CHECK(foo(make_span_0(buf, 8)) == 0 + 2 + 5 + 4 + 4 + 3);
CHECK(foo(make_span_p(buf, 8)) == 0 + 2 + 5); CHECK(foo(make_span_p(buf, 8)) == 0 + 2 + 5 + 4 + 4 + 3);
CHECK(foo(make_span_s(buf, 8)) == 0 + 2 + 5); CHECK(foo(make_span_s(buf, 8)) == 0 + 2 + 5 + 4 + 4 + 3);
CHECK(foo(XSPAN_0_MAKE(upx_uint8_t, buf, 8)) == 0 + 2 + 5 + 4 + 4 + 3);
CHECK(foo(XSPAN_P_MAKE(upx_uint8_t, buf, 8)) == 0 + 2 + 5 + 4 + 4 + 3);
CHECK(foo(XSPAN_S_MAKE(upx_uint8_t, buf, 8)) == 0 + 2 + 5 + 4 + 4 + 3);
} }
#endif // WITH_XSPAN >= 2 #endif // WITH_XSPAN >= 2
+2 -2
View File
@@ -78,12 +78,12 @@ int upx_compress(const upx_bytep src, unsigned src_len, upx_bytep dst, unsigned
// force users to provide *dst_len // force users to provide *dst_len
assert(*dst_len != 0); assert(*dst_len != 0);
#endif #endif
// for UPX, we always require a reasonably sized outbut buffer // for UPX, we always require a reasonably sized output buffer
assert(*dst_len >= MemBuffer::getSizeForCompression(src_len)); assert(*dst_len >= MemBuffer::getSizeForCompression(src_len));
if (!cresult) if (!cresult)
cresult = &cresult_buffer; cresult = &cresult_buffer;
memset(cresult, 0, sizeof(*cresult)); cresult->reset();
#if 1 #if 1
// debugging aid // debugging aid
cresult->debug.method = method; cresult->debug.method = method;
+26 -18
View File
@@ -41,7 +41,7 @@
#pragma warning(disable : 4127) // warning C4127: conditional expression is constant #pragma warning(disable : 4127) // warning C4127: conditional expression is constant
#endif #endif
void lzma_compress_config_t::reset() { void lzma_compress_config_t::reset() noexcept {
pos_bits.reset(); pos_bits.reset();
lit_pos_bits.reset(); lit_pos_bits.reset();
lit_context_bits.reset(); lit_context_bits.reset();
@@ -116,7 +116,7 @@ static bool prepare_result(lzma_compress_result_t *res, unsigned src_len, int me
res->lit_context_bits = (method >> 8) & 15; res->lit_context_bits = (method >> 8) & 15;
} }
#if 0 #if 0
// DEBUG - set sizes so that we use a maxmimum amount of stack. // DEBUG - set sizes so that we use a maximum amount of stack.
// These settings cause res->num_probs == 3147574, i.e. we will // These settings cause res->num_probs == 3147574, i.e. we will
// need about 6 MiB of stack during runtime decompression. // need about 6 MiB of stack during runtime decompression.
res->lit_pos_bits = 4; res->lit_pos_bits = 4;
@@ -194,8 +194,8 @@ static bool prepare_result(lzma_compress_result_t *res, unsigned src_len, int me
lzma_compress_config_t::num_fast_bytes_t::assertValue(res->num_fast_bytes); lzma_compress_config_t::num_fast_bytes_t::assertValue(res->num_fast_bytes);
res->num_probs = 1846 + (768u << (res->lit_context_bits + res->lit_pos_bits)); res->num_probs = 1846 + (768u << (res->lit_context_bits + res->lit_pos_bits));
// printf("\nlzma_compress config: %u %u %u %u %u\n", res->pos_bits, res->lit_pos_bits, NO_printf("\nlzma_compress config: %u %u %u %u %u\n", res->pos_bits, res->lit_pos_bits,
// res->lit_context_bits, res->dict_size, res->num_probs); res->lit_context_bits, res->dict_size, res->num_probs);
return true; return true;
error: error:
@@ -206,14 +206,23 @@ error:
// compress - cruft because of pseudo-COM layer // compress - cruft because of pseudo-COM layer
**************************************************************************/ **************************************************************************/
// ensure proper nullptr usage
// TODO later: examine why we need this in the first place
#undef NULL
// NOLINTBEGIN(clang-analyzer-optin.cplusplus.*)
#define NULL nullptr
// NOLINTEND(clang-analyzer-optin.cplusplus.*)
#if defined(__GNUC__)
#undef __null
#define __null nullptr
#endif
#undef MSDOS #undef MSDOS
#undef OS2 #undef OS2
#undef _WIN32 #undef _WIN32
#undef _WIN32_WCE #undef _WIN32_WCE
#undef COMPRESS_MF_MT #undef COMPRESS_MF_MT
#undef _NO_EXCEPTIONS #undef _NO_EXCEPTIONS
#undef NULL
#define NULL nullptr
#include <lzma-sdk/C/Common/MyInitGuid.h> #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> #include <lzma-sdk/C/7zip/Compress/LZMA/LZMAEncoder.h>
@@ -375,7 +384,7 @@ int upx_lzma_compress(const upx_bytep src, unsigned src_len, upx_bytep dst, unsi
// UPX extra stuff in first byte: 5 high bits convenience for stub decompressor // UPX extra stuff in first byte: 5 high bits convenience for stub decompressor
unsigned t = res->lit_context_bits + res->lit_pos_bits; unsigned t = res->lit_context_bits + res->lit_pos_bits;
os.WriteByte(Byte((t << 3) | res->pos_bits)); os.WriteByte(Byte((t << 3) | res->pos_bits));
os.WriteByte(Byte((res->lit_pos_bits << 4) | (res->lit_context_bits))); os.WriteByte(Byte((res->lit_pos_bits << 4) | res->lit_context_bits));
// compress // compress
rh = enc.Code(&is, &os, nullptr, nullptr, &progress); rh = enc.Code(&is, &os, nullptr, nullptr, &progress);
@@ -399,10 +408,10 @@ int upx_lzma_compress(const upx_bytep src, unsigned src_len, upx_bytep dst, unsi
error: error:
*dst_len = (unsigned) os.b_pos; *dst_len = (unsigned) os.b_pos;
// printf("\nlzma_compress: %d: %u %u %u %u %u, %u - > %u\n", r, res->pos_bits, NO_printf("\nlzma_compress: %d: %u %u %u %u %u, %u - > %u\n", r, res->pos_bits,
// res->lit_pos_bits, res->lit_pos_bits, res->lit_context_bits, res->dict_size, res->num_probs, src_len,
// res->lit_context_bits, res->dict_size, res->num_probs, src_len, *dst_len); *dst_len);
// printf("%u %u %u\n", is.__m_RefCount, os.__m_RefCount, progress.__m_RefCount); NO_printf("%u %u %u\n", is.__m_RefCount, os.__m_RefCount, progress.__m_RefCount);
return r; return r;
} }
@@ -426,7 +435,7 @@ int upx_lzma_decompress(const upx_bytep src, unsigned src_len, upx_bytep dst, un
COMPILE_TIME_ASSERT(LZMA_LIT_SIZE == 768) COMPILE_TIME_ASSERT(LZMA_LIT_SIZE == 768)
CLzmaDecoderState s; CLzmaDecoderState s;
memset(&s, 0, sizeof(s)); mem_clear(&s);
SizeT src_out = 0, dst_out = 0; SizeT src_out = 0, dst_out = 0;
int r = UPX_E_ERROR; int r = UPX_E_ERROR;
int rh; int rh;
@@ -458,8 +467,8 @@ int upx_lzma_decompress(const upx_bytep src, unsigned src_len, upx_bytep dst, un
assert(cresult->result_lzma.lit_context_bits == (unsigned) s.Properties.lc); assert(cresult->result_lzma.lit_context_bits == (unsigned) s.Properties.lc);
assert(cresult->result_lzma.num_probs == (unsigned) LzmaGetNumProbs(&s.Properties)); assert(cresult->result_lzma.num_probs == (unsigned) LzmaGetNumProbs(&s.Properties));
const lzma_compress_result_t *res = &cresult->result_lzma; const lzma_compress_result_t *res = &cresult->result_lzma;
// printf("\nlzma_decompress config: %u %u %u %u %u\n", res->pos_bits, res->lit_pos_bits, NO_printf("\nlzma_decompress config: %u %u %u %u %u\n", res->pos_bits, res->lit_pos_bits,
// res->lit_context_bits, res->dict_size, res->num_probs); res->lit_context_bits, res->dict_size, res->num_probs);
UNUSED(res); UNUSED(res);
} }
s.Probs = (CProb *) malloc(sizeof(CProb) * LzmaGetNumProbs(&s.Properties)); s.Probs = (CProb *) malloc(sizeof(CProb) * LzmaGetNumProbs(&s.Properties));
@@ -524,13 +533,12 @@ const char *upx_lzma_version_string(void) { return "4.43"; }
**************************************************************************/ **************************************************************************/
TEST_CASE("upx_lzma_decompress") { TEST_CASE("upx_lzma_decompress") {
typedef const upx_byte C; const byte *c_data;
C *c_data; byte d_buf[16];
upx_byte d_buf[16];
unsigned d_len; unsigned d_len;
int r; int r;
c_data = (C *) "\x1a\x03\x00\x7f\xed\x3c\x00\x00\x00"; c_data = (const byte *) "\x1a\x03\x00\x7f\xed\x3c\x00\x00\x00";
d_len = 16; d_len = 16;
r = upx_lzma_decompress(c_data, 9, d_buf, &d_len, M_LZMA, nullptr); r = upx_lzma_decompress(c_data, 9, d_buf, &d_len, M_LZMA, nullptr);
CHECK((r == 0 && d_len == 16)); CHECK((r == 0 && d_len == 16));
+11 -10
View File
@@ -56,6 +56,8 @@ static int convert_errno_from_ucl(int r) {
// UCL extra: // UCL extra:
case UCL_E_OVERLAP_OVERRUN: case UCL_E_OVERLAP_OVERRUN:
return UPX_E_ERROR; return UPX_E_ERROR;
default:
break;
} }
return UPX_E_ERROR; return UPX_E_ERROR;
} }
@@ -113,14 +115,14 @@ int upx_ucl_compress(const upx_bytep src, unsigned src_len, upx_bytep dst, unsig
cconf.bb_endian = 0; cconf.bb_endian = 0;
cconf.bb_size = 0; cconf.bb_size = 0;
if (method >= M_NRV2B_LE32 && method <= M_NRV2E_LE16) { if (method >= M_NRV2B_LE32 && method <= M_NRV2E_LE16) {
static const unsigned char sizes[3] = {32, 8, 16}; static const upx_uint8_t sizes[3] = {32, 8, 16};
cconf.bb_size = sizes[(method - M_NRV2B_LE32) % 3]; cconf.bb_size = sizes[(method - M_NRV2B_LE32) % 3];
} else { } else {
throwInternalError("unknown compression method"); throwInternalError("unknown compression method");
return UPX_E_ERROR; return UPX_E_ERROR;
} }
// optimize compression parms // optimize compression params
if (level <= 3 && cconf.max_offset == UCL_UINT_MAX) if (level <= 3 && cconf.max_offset == UCL_UINT_MAX)
cconf.max_offset = 8 * 1024 - 1; cconf.max_offset = 8 * 1024 - 1;
else if (level == 4 && cconf.max_offset == UCL_UINT_MAX) else if (level == 4 && cconf.max_offset == UCL_UINT_MAX)
@@ -241,9 +243,9 @@ int upx_ucl_test_overlap(const upx_bytep buf, const upx_bytep tbuf, unsigned src
**************************************************************************/ **************************************************************************/
extern "C" { extern "C" {
static ucl_voidp __UCL_CDECL my_malloc(ucl_uint n) { return calloc(1, n); } static ucl_voidp __UCL_CDECL my_malloc(ucl_uint n) { return upx_calloc(n, 1); }
static void __UCL_CDECL my_free(ucl_voidp p) { free(p); } static void __UCL_CDECL my_free(ucl_voidp p) { free(p); }
} } // extern "C"
int upx_ucl_init(void) { int upx_ucl_init(void) {
if (ucl_init() != UCL_E_OK) if (ucl_init() != UCL_E_OK)
@@ -327,13 +329,12 @@ TEST_CASE("compress_ucl") {
#endif // DEBUG #endif // DEBUG
TEST_CASE("upx_ucl_decompress") { TEST_CASE("upx_ucl_decompress") {
typedef const upx_byte C; const byte *c_data;
C *c_data; byte d_buf[16];
upx_byte d_buf[16];
unsigned d_len; unsigned d_len;
int r; int r;
c_data = (C *) "\x92\xff\x10\x00\x00\x00\x00\x00\x48\xff"; c_data = (const byte *) "\x92\xff\x10\x00\x00\x00\x00\x00\x48\xff";
d_len = 16; d_len = 16;
r = upx_ucl_decompress(c_data, 10, d_buf, &d_len, M_NRV2B_8, nullptr); r = upx_ucl_decompress(c_data, 10, d_buf, &d_len, M_NRV2B_8, nullptr);
CHECK((r == 0 && d_len == 16)); CHECK((r == 0 && d_len == 16));
@@ -343,7 +344,7 @@ TEST_CASE("upx_ucl_decompress") {
r = upx_ucl_decompress(c_data, 10, d_buf, &d_len, M_NRV2B_8, nullptr); r = upx_ucl_decompress(c_data, 10, d_buf, &d_len, M_NRV2B_8, nullptr);
CHECK(r == UPX_E_OUTPUT_OVERRUN); CHECK(r == UPX_E_OUTPUT_OVERRUN);
c_data = (C *) "\x92\xff\x10\x92\x49\x24\x92\xa0\xff"; c_data = (const byte *) "\x92\xff\x10\x92\x49\x24\x92\xa0\xff";
d_len = 16; d_len = 16;
r = upx_ucl_decompress(c_data, 9, d_buf, &d_len, M_NRV2D_8, nullptr); r = upx_ucl_decompress(c_data, 9, d_buf, &d_len, M_NRV2D_8, nullptr);
CHECK((r == 0 && d_len == 16)); CHECK((r == 0 && d_len == 16));
@@ -353,7 +354,7 @@ TEST_CASE("upx_ucl_decompress") {
r = upx_ucl_decompress(c_data, 9, d_buf, &d_len, M_NRV2D_8, nullptr); r = upx_ucl_decompress(c_data, 9, d_buf, &d_len, M_NRV2D_8, nullptr);
CHECK(r == UPX_E_OUTPUT_OVERRUN); CHECK(r == UPX_E_OUTPUT_OVERRUN);
c_data = (C *) "\x90\xff\xb0\x92\x49\x24\x92\xa0\xff"; c_data = (const byte *) "\x90\xff\xb0\x92\x49\x24\x92\xa0\xff";
d_len = 16; d_len = 16;
r = upx_ucl_decompress(c_data, 9, d_buf, &d_len, M_NRV2E_8, nullptr); r = upx_ucl_decompress(c_data, 9, d_buf, &d_len, M_NRV2E_8, nullptr);
CHECK((r == 0 && d_len == 16)); CHECK((r == 0 && d_len == 16));
+12 -9
View File
@@ -27,12 +27,14 @@
#include "../conf.h" #include "../conf.h"
#include "compress.h" #include "compress.h"
#include "../util/membuffer.h" #include "../util/membuffer.h"
// NOLINTBEGIN(clang-analyzer-optin.performance.Padding)
#define ZLIB_CONST 1
#include <zlib/zlib.h> #include <zlib/zlib.h>
#include <zlib/deflate.h> #include <zlib/deflate.h>
// NOLINTEND(clang-analyzer-optin.performance.Padding)
void zlib_compress_config_t::reset() { void zlib_compress_config_t::reset() noexcept {
mem_clear(this, sizeof(*this)); mem_clear(this);
mem_level.reset(); mem_level.reset();
window_bits.reset(); window_bits.reset();
strategy.reset(); strategy.reset();
@@ -62,6 +64,8 @@ static int convert_errno_from_zlib(int zr) {
return UPX_E_ERROR; return UPX_E_ERROR;
case -7: // UPX extra case -7: // UPX extra
return UPX_E_INPUT_OVERRUN; return UPX_E_INPUT_OVERRUN;
default:
break;
} }
return UPX_E_ERROR; return UPX_E_ERROR;
} }
@@ -100,7 +104,7 @@ int upx_zlib_compress(const upx_bytep src, unsigned src_len, upx_bytep dst, unsi
z_stream s; z_stream s;
s.zalloc = (alloc_func) nullptr; s.zalloc = (alloc_func) nullptr;
s.zfree = (free_func) nullptr; s.zfree = (free_func) nullptr;
s.next_in = ACC_UNCONST_CAST(upx_bytep, src); s.next_in = src;
s.avail_in = src_len; s.avail_in = src_len;
s.next_out = dst; s.next_out = dst;
s.avail_out = *dst_len; s.avail_out = *dst_len;
@@ -149,7 +153,7 @@ int upx_zlib_decompress(const upx_bytep src, unsigned src_len, upx_bytep dst, un
z_stream s; z_stream s;
s.zalloc = (alloc_func) nullptr; s.zalloc = (alloc_func) nullptr;
s.zfree = (free_func) nullptr; s.zfree = (free_func) nullptr;
s.next_in = ACC_UNCONST_CAST(upx_bytep, src); s.next_in = src;
s.avail_in = src_len; s.avail_in = src_len;
s.next_out = dst; s.next_out = dst;
s.avail_out = *dst_len; s.avail_out = *dst_len;
@@ -287,13 +291,12 @@ TEST_CASE("compress_zlib") {
#endif // DEBUG #endif // DEBUG
TEST_CASE("upx_zlib_decompress") { TEST_CASE("upx_zlib_decompress") {
typedef const upx_byte C; const byte *c_data;
C *c_data; byte d_buf[16];
upx_byte d_buf[16];
unsigned d_len; unsigned d_len;
int r; int r;
c_data = (C *) "\xfb\xff\x1f\x15\x00\x00"; c_data = (const byte *) "\xfb\xff\x1f\x15\x00\x00";
d_len = 16; d_len = 16;
r = upx_zlib_decompress(c_data, 6, d_buf, &d_len, M_DEFLATE, nullptr); r = upx_zlib_decompress(c_data, 6, d_buf, &d_len, M_DEFLATE, nullptr);
CHECK((r == 0 && d_len == 16)); CHECK((r == 0 && d_len == 16));
+4 -5
View File
@@ -26,7 +26,7 @@
#include "../conf.h" #include "../conf.h"
void zstd_compress_config_t::reset() { mem_clear(this, sizeof(*this)); } void zstd_compress_config_t::reset() noexcept { mem_clear(this); }
#if WITH_ZSTD #if WITH_ZSTD
#include "compress.h" #include "compress.h"
@@ -207,13 +207,12 @@ TEST_CASE("compress_zstd") {
#endif // DEBUG #endif // DEBUG
TEST_CASE("upx_zstd_decompress") { TEST_CASE("upx_zstd_decompress") {
typedef const upx_byte C; const byte *c_data;
C *c_data; byte d_buf[32];
upx_byte d_buf[32];
unsigned d_len; unsigned d_len;
int r; int r;
c_data = (C *) "\x28\xb5\x2f\xfd\x20\x20\x3d\x00\x00\x08\xff\x01\x00\x34\x4e\x08"; c_data = (const byte *) "\x28\xb5\x2f\xfd\x20\x20\x3d\x00\x00\x08\xff\x01\x00\x34\x4e\x08";
d_len = 32; d_len = 32;
r = upx_zstd_decompress(c_data, 16, d_buf, &d_len, M_ZSTD, nullptr); r = upx_zstd_decompress(c_data, 16, d_buf, &d_len, M_ZSTD, nullptr);
CHECK((r == 0 && d_len == 32)); CHECK((r == 0 && d_len == 32));
+224 -248
View File
@@ -26,43 +26,14 @@
*/ */
#pragma once #pragma once
#ifndef UPX_CONF_H__
#define UPX_CONF_H__ 1
#if !(__cplusplus+0 >= 201703L)
# error "C++ 17 is required"
#endif
#include "version.h"
#if !defined(_FILE_OFFSET_BITS)
# define _FILE_OFFSET_BITS 64
#endif
#if defined(_WIN32) && defined(__MINGW32__) && defined(__GNUC__)
# if !defined(_USE_MINGW_ANSI_STDIO)
# define _USE_MINGW_ANSI_STDIO 1
# endif
#endif
/************************************************************************* /*************************************************************************
// ACC and system includes // init
**************************************************************************/ **************************************************************************/
#ifndef ACC_CFG_USE_NEW_STYLE_CASTS #include "headers.h"
#define ACC_CFG_USE_NEW_STYLE_CASTS 1 #include "version.h"
#endif
#define ACC_CFG_PREFER_TYPEOF_ACC_INT32E_T ACC_TYPEOF_INT
#define ACC_CFG_PREFER_TYPEOF_ACC_INT64E_T ACC_TYPEOF_LONG_LONG
#include "miniacc.h"
#if !(ACC_CC_CLANG || ACC_CC_GNUC || ACC_CC_MSC)
// other compilers may work, but we're NOT interested into supporting them
# error "only clang, gcc and msvc are officially supported"
#endif
// UPX sanity checks for a sane compiler
#if !defined(UINT_MAX) || (UINT_MAX != 0xffffffffL)
# error "UINT_MAX"
#endif
ACC_COMPILE_TIME_ASSERT_HEADER(CHAR_BIT == 8) ACC_COMPILE_TIME_ASSERT_HEADER(CHAR_BIT == 8)
ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(short) == 2) ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(short) == 2)
ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(int) == 4) ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(int) == 4)
@@ -76,94 +47,88 @@ ACC_COMPILE_TIME_ASSERT_HEADER((-1) >> 31 == -1) // arithmetic right shift
ACC_COMPILE_TIME_ASSERT_HEADER(CHAR_MAX == 255) // -funsigned-char ACC_COMPILE_TIME_ASSERT_HEADER(CHAR_MAX == 255) // -funsigned-char
ACC_COMPILE_TIME_ASSERT_HEADER((char)(-1) == 255) // -funsigned-char ACC_COMPILE_TIME_ASSERT_HEADER((char)(-1) == 255) // -funsigned-char
// enable/disable some warnings // enable some more strict warnings for Git developer builds
#if defined(UPX_CONFIG_DISABLE_WSTRICT) && (UPX_CONFIG_DISABLE_WSTRICT + 0 == 0)
#if defined(UPX_CONFIG_DISABLE_WERROR) && (UPX_CONFIG_DISABLE_WERROR + 0 == 0)
#if (ACC_CC_CLANG >= 0x0b0000) #if (ACC_CC_CLANG >= 0x0b0000)
# pragma clang diagnostic error "-Wsuggest-override" # pragma clang diagnostic error "-Wsuggest-override"
#elif (ACC_CC_GNUC >= 0x0a0000) #elif (ACC_CC_GNUC >= 0x0a0000)
// don't enable before gcc-10 because of gcc bug #78010 // don't enable before gcc-10 because of gcc bug #78010
# pragma GCC diagnostic error "-Wsuggest-override" # pragma GCC diagnostic error "-Wsuggest-override"
#endif #endif
#if (ACC_CC_CLANG >= 0x080000)
// don't enable before clang-8 because of stddef.h issues
# pragma clang diagnostic error "-Wzero-as-null-pointer-constant"
#elif (ACC_CC_GNUC >= 0x040700) && defined(__GLIBC__)
// Some non-GLIBC toolchains do not use 'nullptr' everywhere when C++: // 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/ // 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: // toolchain-x86_64_gcc-11.2.0_musl/include/fortify/stdlib.h:
// 51:32: error: zero as null pointer constant // 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__)
# pragma GCC diagnostic error "-Wzero-as-null-pointer-constant" # pragma GCC diagnostic error "-Wzero-as-null-pointer-constant"
#endif #endif
#endif // UPX_CONFIG_DISABLE_WERROR
#endif // UPX_CONFIG_DISABLE_WSTRICT
#if (ACC_CC_MSC) // multithreading (UPX currently does not use multithreading)
# pragma warning(error: 4127) #if (WITH_THREADS)
# pragma warning(error: 4146) #define upx_thread_local thread_local
# pragma warning(error: 4319)
# pragma warning(error: 4805)
# pragma warning(disable: 4244) // -Wconversion
# pragma warning(disable: 4267) // -Wconversion
# pragma warning(disable: 4820) // padding added after data member
#endif
#undef snprintf
#undef vsnprintf
#define HAVE_STDINT_H 1
#define ACC_WANT_ACC_INCD_H 1
#define ACC_WANT_ACC_INCE_H 1
#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
// 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> #define upx_std_atomic(Type) std::atomic<Type>
#endif #define upx_std_once_flag std::once_flag
#define upx_std_call_once std::call_once
#else
#define upx_thread_local /*empty*/
#define upx_std_atomic(Type) Type
#define upx_std_once_flag upx_std_atomic(size_t)
template <class NoexceptCallable>
inline void upx_std_call_once(upx_std_once_flag &flag, NoexceptCallable &&f) {
if (__acc_unlikely(!flag)) { flag = 1; f(); }
}
#endif // WITH_THREADS
// C++ submodule headers // <type_traits> upx_std_is_bounded_array: same as C++20 std::is_bounded_array
#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> template <class T>
struct std_is_bounded_array : public std::false_type {}; struct upx_std_is_bounded_array : public std::false_type {};
template <class T, size_t N> template <class T, size_t N>
struct std_is_bounded_array<T[N]> : public std::true_type {}; struct upx_std_is_bounded_array<T[N]> : public std::true_type {};
template <class T>
inline constexpr bool upx_std_is_bounded_array_v = upx_std_is_bounded_array<T>::value;
// <type_traits> upx_is_integral is overloaded for BE16 & friends; see bele.h
template <class T>
struct upx_is_integral : public std::is_integral<T> {};
template <class T>
inline constexpr bool upx_is_integral_v = upx_is_integral<T>::value;
// <type_traits> util: is_same_all and is_same_any means std::is_same for multiple types
template <class T, class... Ts>
struct is_same_all : public std::conjunction<std::is_same<T, Ts>...> {};
template <class T, class... Ts>
inline constexpr bool is_same_all_v = is_same_all<T, Ts...>::value;
template <class T, class... Ts>
struct is_same_any : public std::disjunction<std::is_same<T, Ts>...> {};
template <class T, class... Ts>
inline constexpr bool is_same_any_v = is_same_any<T, Ts...>::value;
#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__(x) upx_fake_alignas_ ## x
#define alignas(x) upx_fake_alignas__(x)
#endif
/************************************************************************* /*************************************************************************
// core // core
**************************************************************************/ **************************************************************************/
// intergral types // protect against integer overflows and malicious header fields
// see C 11 standard, Annex K
typedef size_t upx_rsize_t;
#define UPX_RSIZE_MAX UPX_RSIZE_MAX_MEM
#define UPX_RSIZE_MAX_MEM (768 * 1024 * 1024) // DO NOT CHANGE !!!
#define UPX_RSIZE_MAX_STR (256 * 1024)
// integral types
typedef acc_int8_t upx_int8_t; typedef acc_int8_t upx_int8_t;
typedef acc_uint8_t upx_uint8_t; typedef acc_uint8_t upx_uint8_t;
typedef acc_int16_t upx_int16_t; typedef acc_int16_t upx_int16_t;
@@ -174,21 +139,23 @@ typedef acc_int64_t upx_int64_t;
typedef acc_uint64_t upx_uint64_t; typedef acc_uint64_t upx_uint64_t;
typedef acc_uintptr_t upx_uintptr_t; typedef acc_uintptr_t upx_uintptr_t;
typedef unsigned char upx_byte; // convention: use "byte" when dealing with data; use "char/uchar" when dealing
#define upx_bytep upx_byte * // with strings; use "upx_uint8_t" when dealing with small integers
typedef unsigned char byte;
// protect against integer overflows and malicious header fields #define upx_byte byte
// see C 11 standard, Annex K #define upx_bytep byte *
typedef size_t upx_rsize_t; typedef unsigned char uchar;
#define UPX_RSIZE_MAX UPX_RSIZE_MAX_MEM // convention: use "charptr" when dealing with abstract pointer arithmetics
#define UPX_RSIZE_MAX_MEM (768 * 1024 * 1024) // DO NOT CHANGE !!! #define charptr upx_charptr_unit_type *
#define UPX_RSIZE_MAX_STR (1024 * 1024) // upx_charptr_unit_type is some opaque type with sizeof(type) == 1
struct alignas(1) upx_charptr_unit_type { char hidden__; };
ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(upx_charptr_unit_type) == 1)
// using the system off_t was a bad idea even back in 199x... // using the system off_t was a bad idea even back in 199x...
typedef upx_int64_t upx_off_t; typedef upx_int64_t upx_off_t;
#undef off_t #undef off_t
#if 0 #if 0
// at some future point we can do this... // TODO cleanup: at some future point we can do this:
#define off_t DO_NOT_USE_off_t #define off_t DO_NOT_USE_off_t
#else #else
#define off_t upx_off_t #define off_t upx_off_t
@@ -207,6 +174,7 @@ typedef upx_int64_t upx_off_t;
#define unlikely __acc_unlikely #define unlikely __acc_unlikely
#define very_likely __acc_very_likely #define very_likely __acc_very_likely
#define very_unlikely __acc_very_unlikely #define very_unlikely __acc_very_unlikely
#define may_throw noexcept(false)
#define COMPILE_TIME_ASSERT(e) ACC_COMPILE_TIME_ASSERT(e) #define COMPILE_TIME_ASSERT(e) ACC_COMPILE_TIME_ASSERT(e)
#define DELETED_FUNCTION = delete #define DELETED_FUNCTION = delete
@@ -231,8 +199,13 @@ typedef upx_int64_t upx_off_t;
#endif #endif
#if (ACC_OS_DOS32) && defined(__DJGPP__) #if (ACC_OS_DOS32) && defined(__DJGPP__)
# undef sopen # undef sopen
# undef __unix__
# undef __unix # undef __unix
# undef __unix__
#endif
#if defined(HAVE_DUP) && (HAVE_DUP + 0 == 0)
# undef dup
# define dup(x) (-1)
#endif #endif
#ifndef STDIN_FILENO #ifndef STDIN_FILENO
@@ -291,7 +264,7 @@ typedef upx_int64_t upx_off_t;
# endif # endif
#endif #endif
// avoid warnings about shadowing global functions // avoid warnings about shadowing global symbols
#undef _base #undef _base
#undef basename #undef basename
#undef index #undef index
@@ -345,10 +318,11 @@ typedef upx_int64_t upx_off_t;
# define attribute_format(a,b) /*empty*/ # define attribute_format(a,b) /*empty*/
#endif #endif
inline void NO_printf(const char *, ...) attribute_format(1, 2); // for no-op debug output
inline void NO_fprintf(FILE *, const char *, ...) attribute_format(2, 3); inline void NO_printf(const char *, ...) noexcept attribute_format(1, 2);
inline void NO_printf(const char *, ...) {} inline void NO_fprintf(FILE *, const char *, ...) noexcept attribute_format(2, 3);
inline void NO_fprintf(FILE *, const char *, ...) {} inline void NO_printf(const char *, ...) noexcept {}
inline void NO_fprintf(FILE *, const char *, ...) noexcept {}
#if !defined(__has_builtin) #if !defined(__has_builtin)
# define __has_builtin(x) 0 # define __has_builtin(x) 0
@@ -374,18 +348,10 @@ inline void NO_fprintf(FILE *, const char *, ...) {}
# define upx_return_address() nullptr # define upx_return_address() nullptr
#endif #endif
// TODO cleanup: we now require C++14, so remove all __packed_struct usage // TODO cleanup: we now require C++17, so remove all __packed_struct usage
#define __packed_struct(s) struct alignas(1) s { #define __packed_struct(s) struct alignas(1) s {
#define __packed_struct_end() }; #define __packed_struct_end() };
#if (ACC_ARCH_M68K && ACC_OS_TOS && ACC_CC_GNUC) && defined(__MINT__)
// horrible hack for broken compiler
#define upx_fake_alignas_1 __attribute__((__aligned__(1),__packed__))
#define upx_fake_alignas_16 __attribute__((__aligned__(2))) // object file maximum 2 ???
#define upx_fake_alignas__(a) upx_fake_alignas_ ## a
#define alignas(x) upx_fake_alignas__(x)
#endif
#define COMPILE_TIME_ASSERT_ALIGNOF_USING_SIZEOF__(a,b) { \ #define COMPILE_TIME_ASSERT_ALIGNOF_USING_SIZEOF__(a,b) { \
typedef a acc_tmp_a_t; typedef b acc_tmp_b_t; \ typedef a acc_tmp_a_t; typedef b acc_tmp_b_t; \
struct alignas(1) acc_tmp_t { acc_tmp_b_t x; acc_tmp_a_t y; acc_tmp_b_t z; }; \ struct alignas(1) acc_tmp_t { acc_tmp_b_t x; acc_tmp_a_t y; acc_tmp_b_t z; }; \
@@ -413,35 +379,63 @@ inline const T& UPX_MAX(const T& a, const T& b) { if (a < b) return b; return a;
template <class T> template <class T>
inline const T& UPX_MIN(const T& a, const T& b) { if (a < b) return a; return b; } inline const T& UPX_MIN(const T& a, const T& b) { if (a < b) return a; return b; }
template <size_t TypeSize> template <size_t Size>
struct USizeOfTypeImpl { struct UnsignedSizeOf {
static forceinline constexpr unsigned value() { static_assert(Size >= 1 && Size <= UPX_RSIZE_MAX_MEM);
COMPILE_TIME_ASSERT(TypeSize >= 1 && TypeSize <= 64 * 1024); // arbitrary limit static constexpr unsigned value = unsigned(Size);
return ACC_ICONV(unsigned, TypeSize);
}
}; };
#define usizeof(type) (USizeOfTypeImpl<sizeof(type)>::value()) #define usizeof(expr) (UnsignedSizeOf<sizeof(expr)>::value)
ACC_COMPILE_TIME_ASSERT_HEADER(usizeof(int) == 4)
template <class T>
inline void mem_clear(T *object) noexcept {
static_assert(std::is_class_v<T>); // UPX convention
static_assert(std::is_standard_layout_v<T>);
static_assert(std::is_trivially_copyable_v<T>);
constexpr size_t size = sizeof(*object);
static_assert(size >= 1 && size <= UPX_RSIZE_MAX_MEM);
memset((void *) object, 0, size);
}
#if defined(__clang__) || __GNUC__ != 7
template <class T>
inline void mem_clear(T (&array)[]) noexcept DELETED_FUNCTION;
#endif
template <class T, size_t N>
inline void mem_clear(T (&array)[N]) noexcept DELETED_FUNCTION;
// An Array allocates memory on the heap, and automatically // An Array allocates memory on the heap, and automatically
// gets destructed when leaving scope or on exceptions. // gets destructed when leaving scope or on exceptions.
#define Array(type, var, size) \ #define Array(type, var, n) \
MemBuffer var ## _membuf(mem_size(sizeof(type), size)); \ MemBuffer var ## _membuf(mem_size(sizeof(type), (n))); \
type * const var = ACC_STATIC_CAST(type *, var ## _membuf.getVoidPtr()) type * const var = ACC_STATIC_CAST(type *, var ## _membuf.getVoidPtr())
#define ByteArray(var, size) Array(unsigned char, var, size) #define ByteArray(var, n) Array(byte, var, (n))
// assert_noexcept()
noinline void assertFailed(const char *expr, const char *file, int line, const char *func) noexcept;
noinline void throwAssertFailed(const char *expr, const char *file, int line, const char *func);
#if defined(__GNUC__)
#undef assert
#if DEBUG || 0
// generate a warning if assert() is used inside a "noexcept" context
#define assert(e) ((void)(__acc_cte(e) || (assertFailed(#e, __FILE__, __LINE__, __func__), throw 1, 0)))
#else
// turn assertion failures into exceptions
#define assert(e) ((void)(__acc_cte(e) || (throwAssertFailed(#e, __FILE__, __LINE__, __func__), throw 1, 0)))
#endif
#define assert_noexcept(e) ((void)(__acc_cte(e) || (assertFailed(#e, __FILE__, __LINE__, __func__), 0)))
#else
#define assert_noexcept assert
#endif
class noncopyable class noncopyable {
{
protected: protected:
inline noncopyable() {} inline noncopyable() noexcept {}
inline ~noncopyable() {} inline ~noncopyable() noexcept = default;
private: private:
noncopyable(const noncopyable &) DELETED_FUNCTION; // copy constuctor noncopyable(const noncopyable &) noexcept DELETED_FUNCTION; // copy constructor
noncopyable& operator=(const noncopyable &) DELETED_FUNCTION; // copy assignment noncopyable& operator=(const noncopyable &) noexcept DELETED_FUNCTION; // copy assignment
noncopyable(noncopyable &&) DELETED_FUNCTION; // move constructor noncopyable(noncopyable &&) noexcept DELETED_FUNCTION; // move constructor
noncopyable& operator=(noncopyable &&) DELETED_FUNCTION; // move assignment noncopyable& operator=(noncopyable &&) noexcept DELETED_FUNCTION; // move assignment
}; };
@@ -453,7 +447,7 @@ constexpr bool string_eq(const char *a, const char *b) {
return *a == *b && (*a == '\0' || string_eq(a + 1, b + 1)); return *a == *b && (*a == '\0' || string_eq(a + 1, b + 1));
} }
constexpr bool string_lt(const char *a, const char *b) { constexpr bool string_lt(const char *a, const char *b) {
return (unsigned char)*a < (unsigned char)*b || (*a != '\0' && *a == *b && string_lt(a + 1, b + 1)); return (uchar)*a < (uchar)*b || (*a != '\0' && *a == *b && string_lt(a + 1, b + 1));
} }
constexpr bool string_ne(const char *a, const char *b) { constexpr bool string_ne(const char *a, const char *b) {
return !string_eq(a, b); return !string_eq(a, b);
@@ -467,7 +461,7 @@ constexpr bool string_le(const char *a, const char *b) {
constexpr bool string_ge(const char *a, const char *b) { constexpr bool string_ge(const char *a, const char *b) {
return !string_lt(a, b); return !string_lt(a, b);
} }
} } // namespace compile_time
/************************************************************************* /*************************************************************************
// constants // constants
@@ -506,7 +500,7 @@ constexpr bool string_ge(const char *a, const char *b) {
#define UPX_E_INVALID_ARGUMENT (-10) #define UPX_E_INVALID_ARGUMENT (-10)
// Executable formats. Note: big endian types are >= 128. // Executable formats (info: big endian types are >= 128); DO NOT CHANGE
#define UPX_F_DOS_COM 1 #define UPX_F_DOS_COM 1
#define UPX_F_DOS_SYS 2 #define UPX_F_DOS_SYS 2
#define UPX_F_DOS_EXE 3 #define UPX_F_DOS_EXE 3
@@ -515,7 +509,7 @@ constexpr bool string_ge(const char *a, const char *b) {
//#define UPX_F_VXD_LE 6 // NOT IMPLEMENTED //#define UPX_F_VXD_LE 6 // NOT IMPLEMENTED
#define UPX_F_DOS_EXEH 7 // OBSOLETE #define UPX_F_DOS_EXEH 7 // OBSOLETE
#define UPX_F_TMT_ADAM 8 #define UPX_F_TMT_ADAM 8
#define UPX_F_WIN32_PE 9 #define UPX_F_W32PE_I386 9
#define UPX_F_LINUX_i386 10 #define UPX_F_LINUX_i386 10
//#define UPX_F_WIN16_NE 11 // NOT IMPLEMENTED //#define UPX_F_WIN16_NE 11 // NOT IMPLEMENTED
#define UPX_F_LINUX_ELF_i386 12 #define UPX_F_LINUX_ELF_i386 12
@@ -527,52 +521,47 @@ constexpr bool string_ge(const char *a, const char *b) {
#define UPX_F_PS1_EXE 18 #define UPX_F_PS1_EXE 18
#define UPX_F_VMLINUX_i386 19 #define UPX_F_VMLINUX_i386 19
#define UPX_F_LINUX_ELFI_i386 20 #define UPX_F_LINUX_ELFI_i386 20
#define UPX_F_WINCE_ARM_PE 21 #define UPX_F_WINCE_ARM 21 // Windows CE
#define UPX_F_LINUX_ELF64_AMD 22 #define UPX_F_LINUX_ELF64_AMD64 22
#define UPX_F_LINUX_ELF32_ARMEL 23 #define UPX_F_LINUX_ELF32_ARM 23
#define UPX_F_BSD_i386 24 #define UPX_F_BSD_i386 24
#define UPX_F_BSD_ELF_i386 25 #define UPX_F_BSD_ELF_i386 25
#define UPX_F_BSD_SH_i386 26 #define UPX_F_BSD_SH_i386 26
#define UPX_F_VMLINUX_AMD64 27 #define UPX_F_VMLINUX_AMD64 27
#define UPX_F_VMLINUX_ARMEL 28 #define UPX_F_VMLINUX_ARM 28
#define UPX_F_MACH_i386 29 #define UPX_F_MACH_i386 29
#define UPX_F_LINUX_ELF32_MIPSEL 30 #define UPX_F_LINUX_ELF32_MIPSEL 30
#define UPX_F_VMLINUZ_ARMEL 31 #define UPX_F_VMLINUZ_ARM 31
#define UPX_F_MACH_ARMEL 32 #define UPX_F_MACH_ARM 32
#define UPX_F_DYLIB_i386 33 #define UPX_F_DYLIB_i386 33
#define UPX_F_MACH_AMD64 34 #define UPX_F_MACH_AMD64 34
#define UPX_F_DYLIB_AMD64 35 #define UPX_F_DYLIB_AMD64 35
#define UPX_F_W64PE_AMD64 36
#define UPX_F_WIN64_PEP 36 #define UPX_F_MACH_ARM64 37
#define UPX_F_MACH_ARM64EL 37
//#define UPX_F_MACH_PPC64LE 38 // DOES NOT EXIST //#define UPX_F_MACH_PPC64LE 38 // DOES NOT EXIST
#define UPX_F_LINUX_ELFPPC64LE 39 #define UPX_F_LINUX_ELF64_PPC64LE 39
#define UPX_F_VMLINUX_PPC64LE 40 #define UPX_F_VMLINUX_PPC64LE 40
//#define UPX_F_DYLIB_PPC64LE 41 // DOES NOT EXIST //#define UPX_F_DYLIB_PPC64LE 41 // DOES NOT EXIST
#define UPX_F_LINUX_ELF64_ARM64 42
#define UPX_F_LINUX_ELF64_ARM 42 #define UPX_F_W64PE_ARM64 43 // NOT YET IMPLEMENTED
#define UPX_F_W64PE_ARM64EC 44 // NOT YET IMPLEMENTED
#define UPX_F_ATARI_TOS 129 #define UPX_F_ATARI_TOS 129
//#define UPX_F_SOLARIS_SPARC 130 // NOT IMPLEMENTED //#define UPX_F_SOLARIS_SPARC 130 // NOT IMPLEMENTED
#define UPX_F_MACH_PPC32 131 #define UPX_F_MACH_PPC32 131
#define UPX_F_LINUX_ELFPPC32 132 #define UPX_F_LINUX_ELF32_PPC32 132
#define UPX_F_LINUX_ELF32_ARMEB 133 #define UPX_F_LINUX_ELF32_ARMEB 133
#define UPX_F_MACH_FAT 134 #define UPX_F_MACH_FAT 134
#define UPX_F_VMLINUX_ARMEB 135 #define UPX_F_VMLINUX_ARMEB 135
#define UPX_F_VMLINUX_PPC32 136 #define UPX_F_VMLINUX_PPC32 136
#define UPX_F_LINUX_ELF32_MIPSEB 137 #define UPX_F_LINUX_ELF32_MIPS 137
#define UPX_F_DYLIB_PPC32 138 #define UPX_F_DYLIB_PPC32 138
#define UPX_F_MACH_PPC64 139 #define UPX_F_MACH_PPC64 139
#define UPX_F_LINUX_ELFPPC64 140 #define UPX_F_LINUX_ELF64_PPC64 140
#define UPX_F_VMLINUX_PPC64 141 #define UPX_F_VMLINUX_PPC64 141
#define UPX_F_DYLIB_PPC64 142 #define UPX_F_DYLIB_PPC64 142
// compression methods - DO NOT CHANGE // compression methods; DO NOT CHANGE
#define M_NRV2B_LE32 2 #define M_NRV2B_LE32 2
#define M_NRV2B_8 3 #define M_NRV2B_8 3
#define M_NRV2B_LE16 4 #define M_NRV2B_LE16 4
@@ -604,7 +593,7 @@ constexpr bool string_ge(const char *a, const char *b) {
#define M_IS_ZSTD(x) ((x) == M_ZSTD) #define M_IS_ZSTD(x) ((x) == M_ZSTD)
// filters // filters internal usage
#define FT_END (-1) #define FT_END (-1)
#define FT_NONE (-2) #define FT_NONE (-2)
#define FT_SKIP (-3) #define FT_SKIP (-3)
@@ -631,12 +620,11 @@ typedef upx_callback_t *upx_callback_p;
typedef void (__acc_cdecl *upx_progress_func_t) typedef void (__acc_cdecl *upx_progress_func_t)
(upx_callback_p, unsigned, unsigned); (upx_callback_p, unsigned, unsigned);
struct upx_callback_t struct upx_callback_t {
{
upx_progress_func_t nprogress; upx_progress_func_t nprogress;
void *user; void *user;
void reset() { memset(this, 0, sizeof(*this)); } void reset() noexcept { mem_clear(this); }
}; };
@@ -645,33 +633,34 @@ struct upx_callback_t
**************************************************************************/ **************************************************************************/
template <class T, T default_value_, T min_value_, T max_value_> template <class T, T default_value_, T min_value_, T max_value_>
struct OptVar struct OptVar final {
{ static_assert(std::is_integral_v<T>);
typedef T value_type; typedef T value_type;
static const T default_value = default_value_; static constexpr T default_value = default_value_;
static const T min_value = min_value_; static constexpr T min_value = min_value_;
static const T max_value = max_value_; static constexpr T max_value = max_value_;
static_assert(min_value <= default_value && default_value <= max_value);
static void assertValue(const T &v) { static void assertValue(const T &v) noexcept {
// info: this generates annoying warnings "unsigned >= 0 is always true" // info: this generates annoying warnings "unsigned >= 0 is always true"
//assert(v >= min_value); //assert_noexcept(v >= min_value);
assert(v == min_value || v >= min_value + 1); assert_noexcept(v == min_value || v >= min_value + 1);
assert(v <= max_value); assert_noexcept(v <= max_value);
} }
void assertValue() const { void assertValue() const noexcept {
assertValue(v); assertValue(v);
} }
OptVar() : v(default_value), is_set(false) { } OptVar() noexcept : v(default_value), is_set(false) { }
OptVar& operator= (const T &other) { OptVar& operator= (const T &other) noexcept {
assertValue(other); assertValue(other);
v = other; v = other;
is_set = true; is_set = true;
return *this; return *this;
} }
void reset() { v = default_value; is_set = false; } void reset() noexcept { v = default_value; is_set = false; }
operator T () const { return v; } operator T () const noexcept { return v; }
T v; T v;
bool is_set; bool is_set;
@@ -680,17 +669,16 @@ struct OptVar
// optional assignments // optional assignments
template <class T, T a, T b, T c> template <class T, T a, T b, T c>
inline void oassign(OptVar<T,a,b,c> &self, const OptVar<T,a,b,c> &other) { inline void oassign(OptVar<T,a,b,c> &self, const OptVar<T,a,b,c> &other) noexcept {
if (other.is_set) { self.v = other.v; self.is_set = true; } if (other.is_set) { self.v = other.v; self.is_set = true; }
} }
template <class T, T a, T b, T c> template <class T, T a, T b, T c>
inline void oassign(T &v, const OptVar<T,a,b,c> &other) { inline void oassign(T &v, const OptVar<T,a,b,c> &other) noexcept {
if (other.is_set) { v = other.v; } if (other.is_set) { v = other.v; }
} }
struct lzma_compress_config_t struct lzma_compress_config_t {
{
typedef OptVar<unsigned, 2u, 0u, 4u> pos_bits_t; // pb typedef OptVar<unsigned, 2u, 0u, 4u> pos_bits_t; // pb
typedef OptVar<unsigned, 0u, 0u, 4u> lit_pos_bits_t; // lp typedef OptVar<unsigned, 0u, 0u, 4u> lit_pos_bits_t; // lp
typedef OptVar<unsigned, 3u, 0u, 8u> lit_context_bits_t; // lc typedef OptVar<unsigned, 3u, 0u, 8u> lit_context_bits_t; // lc
@@ -707,16 +695,14 @@ struct lzma_compress_config_t
unsigned max_num_probs; unsigned max_num_probs;
void reset(); void reset() noexcept;
}; };
struct ucl_compress_config_t : public REAL_ucl_compress_config_t struct ucl_compress_config_t : public REAL_ucl_compress_config_t {
{ void reset() noexcept { memset(this, 0xff, sizeof(*this)); }
void reset() { memset(this, 0xff, sizeof(*this)); }
}; };
struct zlib_compress_config_t struct zlib_compress_config_t {
{
typedef OptVar<unsigned, 8u, 1u, 9u> mem_level_t; // ml typedef OptVar<unsigned, 8u, 1u, 9u> mem_level_t; // ml
typedef OptVar<unsigned, 15u, 9u, 15u> window_bits_t; // wb typedef OptVar<unsigned, 15u, 9u, 15u> window_bits_t; // wb
typedef OptVar<unsigned, 0u, 0u, 4u> strategy_t; // st typedef OptVar<unsigned, 0u, 0u, 4u> strategy_t; // st
@@ -725,23 +711,22 @@ struct zlib_compress_config_t
window_bits_t window_bits; // wb window_bits_t window_bits; // wb
strategy_t strategy; // st strategy_t strategy; // st
void reset(); void reset() noexcept;
}; };
struct zstd_compress_config_t struct zstd_compress_config_t {
{
unsigned dummy; unsigned dummy;
void reset(); void reset() noexcept;
}; };
struct upx_compress_config_t struct upx_compress_config_t {
{
lzma_compress_config_t conf_lzma; lzma_compress_config_t conf_lzma;
ucl_compress_config_t conf_ucl; ucl_compress_config_t conf_ucl;
zlib_compress_config_t conf_zlib; zlib_compress_config_t conf_zlib;
zstd_compress_config_t conf_zstd; zstd_compress_config_t conf_zstd;
void reset() { conf_lzma.reset(); conf_ucl.reset(); conf_zlib.reset(); conf_zstd.reset(); }
void reset() noexcept { conf_lzma.reset(); conf_ucl.reset(); conf_zlib.reset(); conf_zstd.reset(); }
}; };
#define NULL_cconf ((upx_compress_config_t *) nullptr) #define NULL_cconf ((upx_compress_config_t *) nullptr)
@@ -751,8 +736,7 @@ struct upx_compress_config_t
// compression - result_t // compression - result_t
**************************************************************************/ **************************************************************************/
struct lzma_compress_result_t struct lzma_compress_result_t {
{
unsigned pos_bits; // pb unsigned pos_bits; // pb
unsigned lit_pos_bits; // lp unsigned lit_pos_bits; // lp
unsigned lit_context_bits; // lc unsigned lit_context_bits; // lc
@@ -762,45 +746,43 @@ struct lzma_compress_result_t
unsigned match_finder_cycles; unsigned match_finder_cycles;
unsigned num_probs; // (computed result) unsigned num_probs; // (computed result)
void reset() { memset(this, 0, sizeof(*this)); } void reset() noexcept { mem_clear(this); }
}; };
struct ucl_compress_result_t struct ucl_compress_result_t {
{
ucl_uint result[16]; ucl_uint result[16];
void reset() { memset(this, 0, sizeof(*this)); } void reset() noexcept { mem_clear(this); }
}; };
struct zlib_compress_result_t struct zlib_compress_result_t {
{
unsigned dummy; unsigned dummy;
void reset() { memset(this, 0, sizeof(*this)); } void reset() noexcept { mem_clear(this); }
}; };
struct zstd_compress_result_t struct zstd_compress_result_t {
{
unsigned dummy; unsigned dummy;
void reset() { memset(this, 0, sizeof(*this)); } void reset() noexcept { mem_clear(this); }
}; };
struct upx_compress_result_t struct upx_compress_result_t {
{
// debugging aid // debugging aid
struct { struct Debug {
int method, level; int method, level;
unsigned u_len, c_len; unsigned u_len, c_len;
} debug; void reset() noexcept { mem_clear(this); }
};
Debug debug;
lzma_compress_result_t result_lzma; lzma_compress_result_t result_lzma;
ucl_compress_result_t result_ucl; ucl_compress_result_t result_ucl;
zlib_compress_result_t result_zlib; zlib_compress_result_t result_zlib;
zstd_compress_result_t result_zstd; zstd_compress_result_t result_zstd;
void reset() { void reset() noexcept {
memset(&this->debug, 0, sizeof(this->debug)); debug.reset();
result_lzma.reset(); result_ucl.reset(); result_zlib.reset(); result_zstd.reset(); result_lzma.reset(); result_ucl.reset(); result_zlib.reset(); result_zstd.reset();
} }
}; };
@@ -810,29 +792,20 @@ struct upx_compress_result_t
// globals // globals
**************************************************************************/ **************************************************************************/
#include "util/snprintf.h" // must get included first!
#include "options.h"
#include "except.h"
#include "bele.h"
#include "console/console.h"
#include "util/util.h"
// classes // classes
class ElfLinker; class ElfLinker;
typedef ElfLinker Linker; typedef ElfLinker Linker;
class Throwable;
// util/membuffer.h // util/membuffer.h
class MemBuffer; class MemBuffer;
void *membuffer_get_void_ptr(MemBuffer &mb); void *membuffer_get_void_ptr(MemBuffer &mb) noexcept;
unsigned membuffer_get_size(MemBuffer &mb); unsigned membuffer_get_size(MemBuffer &mb) noexcept;
// xspan
#include "util/xspan.h"
// util/dt_check.cpp // util/dt_check.cpp
void upx_compiler_sanity_check(); noinline void upx_compiler_sanity_check() noexcept;
noinline int upx_doctest_check(int argc, char **argv);
int upx_doctest_check(); int upx_doctest_check();
int upx_doctest_check(int argc, char **argv);
// main.cpp // main.cpp
extern const char *progname; extern const char *progname;
@@ -842,18 +815,18 @@ void main_get_envoptions();
int upx_main(int argc, char *argv[]); int upx_main(int argc, char *argv[]);
// msg.cpp // msg.cpp
void printSetNl(int need_nl); void printSetNl(int need_nl) noexcept;
void printClearLine(FILE *f = nullptr); void printClearLine(FILE *f = nullptr) noexcept;
void printErr(const char *iname, const Throwable *e); void printErr(const char *iname, const Throwable &e) noexcept;
void printUnhandledException(const char *iname, const std::exception *e); void printUnhandledException(const char *iname, const std::exception *e) noexcept;
void printErr(const char *iname, const char *format, ...) attribute_format(2, 3); void printErr(const char *iname, const char *format, ...) noexcept attribute_format(2, 3);
void printWarn(const char *iname, const char *format, ...) attribute_format(2, 3); void printWarn(const char *iname, const char *format, ...) noexcept attribute_format(2, 3);
void infoWarning(const char *format, ...) attribute_format(1, 2); void infoWarning(const char *format, ...) attribute_format(1, 2);
void infoHeader(const char *format, ...) attribute_format(1, 2); void infoHeader(const char *format, ...) attribute_format(1, 2);
void info(const char *format, ...) attribute_format(1, 2); void info(const char *format, ...) attribute_format(1, 2);
void infoHeader(); void infoHeader();
void infoWriting(const char *what, long size); void infoWriting(const char *what, upx_int64_t size);
// work.cpp // work.cpp
void do_one_file(const char *iname, char *oname); void do_one_file(const char *iname, char *oname);
@@ -861,7 +834,7 @@ int do_files(int i, int argc, char *argv[]);
// help.cpp // help.cpp
extern const char gitrev[]; extern const char gitrev[];
void show_head(); void show_header();
void show_help(int verbose=0); void show_help(int verbose=0);
void show_license(); void show_license();
void show_usage(); void show_usage();
@@ -889,12 +862,15 @@ int upx_test_overlap ( const upx_bytep buf,
const upx_compress_result_t *cresult ); const upx_compress_result_t *cresult );
#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) #include "util/snprintf.h" // must get included first!
# if defined(INVALID_HANDLE_VALUE) || defined(MAKEWORD) || defined(RT_CURSOR) #include "options.h"
# error "something pulled in <windows.h>" #include "except.h"
# endif #include "bele.h"
#endif #include "console/console.h"
#include "util/util.h"
// xspan
#include "util/raw_bytes.h"
#include "util/xspan.h"
#endif /* already included */
/* vim:set ts=4 sw=4 et: */ /* vim:set ts=4 sw=4 et: */
+16
View File
@@ -266,6 +266,22 @@ static int init(screen_t *this, int fd) {
#endif #endif
#endif #endif
#if 1
// check if we are running under Wine
// (this rather direct Win32 screen driver maps poorly to Unix terminals)
// ntdll.dll wine_get_version() was added in wine-0.9.59 (Apr 2008)
HMODULE ntdll = GetModuleHandleA("ntdll.dll");
if (ntdll != nullptr) {
typedef const char *(CDECL * wine_get_version_func_t)(void);
wine_get_version_func_t wine_get_version;
wine_get_version =
(wine_get_version_func_t) (void *) GetProcAddress(ntdll, "wine_get_version");
if (wine_get_version != nullptr) {
return -1;
}
}
#endif
this->data->cursor_x = csbi->dwCursorPosition.X; this->data->cursor_x = csbi->dwCursorPosition.X;
this->data->cursor_y = csbi->dwCursorPosition.Y; this->data->cursor_y = csbi->dwCursorPosition.Y;
+48 -8
View File
@@ -31,7 +31,7 @@
// //
**************************************************************************/ **************************************************************************/
unsigned long Throwable::counter = 0; /*static*/ upx_std_atomic(size_t) Throwable::debug_counter;
Throwable::Throwable(const char *m, int e, bool w) noexcept : super(), Throwable::Throwable(const char *m, int e, bool w) noexcept : super(),
msg(nullptr), msg(nullptr),
@@ -40,8 +40,8 @@ Throwable::Throwable(const char *m, int e, bool w) noexcept : super(),
if (m) if (m)
msg = strdup(m); msg = strdup(m);
#if 0 #if 0
fprintf(stderr, "construct exception: %s %lu\n", msg, counter); fprintf(stderr, "construct exception: %s %zu\n", msg, debug_counter);
counter++; debug_counter += 1;
#endif #endif
} }
@@ -52,15 +52,15 @@ Throwable::Throwable(const Throwable &other) noexcept : super(other),
if (other.msg) if (other.msg)
msg = strdup(other.msg); msg = strdup(other.msg);
#if 0 #if 0
fprintf(stderr, "copy exception: %s %lu\n", msg, counter); fprintf(stderr, "copy exception: %s %zu\n", msg, debug_counter);
counter++; debug_counter += 1;
#endif #endif
} }
Throwable::~Throwable() noexcept { Throwable::~Throwable() noexcept {
#if 0 #if 0
counter--; debug_counter -= 1;
fprintf(stderr, "destruct exception: %s %lu\n", msg, counter); fprintf(stderr, "destruct exception: %s %zu\n", msg, debug_counter);
#endif #endif
if (msg) if (msg)
free(msg); free(msg);
@@ -72,7 +72,9 @@ Throwable::~Throwable() noexcept {
void throwCantPack(const char *msg) { void throwCantPack(const char *msg) {
// UGLY, but makes things easier // UGLY, but makes things easier
if (opt->cmd == CMD_COMPRESS) if (opt->cmd == CMD_NONE)
throw CantPackException(msg);
else if (opt->cmd == CMD_COMPRESS)
throw CantPackException(msg); throw CantPackException(msg);
else if (opt->cmd == CMD_FILEINFO) else if (opt->cmd == CMD_FILEINFO)
throw CantPackException(msg); throw CantPackException(msg);
@@ -143,6 +145,44 @@ void throwEOFException(const char *msg, int e) {
// //
**************************************************************************/ **************************************************************************/
template <>
void throwCantPack(const char *format, ...) {
char msg[1024];
va_list ap;
va_start(ap, format);
(void) upx_safe_vsnprintf(msg, sizeof(msg), format, ap);
va_end(ap);
throwCantPack(msg);
}
template <>
void throwCantUnpack(const char *format, ...) {
char msg[1024];
va_list ap;
va_start(ap, format);
(void) upx_safe_vsnprintf(msg, sizeof(msg), format, ap);
va_end(ap);
throwCantUnpack(msg);
}
/*************************************************************************
//
**************************************************************************/
void assertFailed(const char *expr, const char *file, int line, const char *func) noexcept {
fflush(stdout);
fprintf(stderr, "Assertion failed: %s (%s: %s: %d)\n", expr, file, func, line);
std::terminate();
}
void throwAssertFailed(const char *expr, const char *file, int line, const char *func) {
if (opt->debug.debug_level >= 1) {
throwCantPack("corrupted file; details: %s (%s: %s: %d)", expr, file, func, line);
} else {
throwCantPack("corrupted file; try '--debug' for more details");
}
}
const char *prettyName(const char *n) noexcept { const char *prettyName(const char *n) noexcept {
if (n == nullptr) if (n == nullptr)
return "(null)"; return "(null)";
+35 -41
View File
@@ -26,13 +26,12 @@
*/ */
#pragma once #pragma once
#ifndef UPX_EXCEPT_H__
#define UPX_EXCEPT_H__ 1
#ifdef __cplusplus
const char *prettyName(const char *n) noexcept; const char *prettyName(const char *n) noexcept;
noinline void assertFailed(const char *expr, const char *file, int line, const char *func) noexcept;
noinline void throwAssertFailed(const char *expr, const char *file, int line, const char *func);
/************************************************************************* /*************************************************************************
// exceptions // exceptions
**************************************************************************/ **************************************************************************/
@@ -53,24 +52,27 @@ public:
private: private:
char *msg = nullptr; char *msg = nullptr;
int err = 0; int err = 0;
protected: protected:
bool is_warning = false; // can be set by subclasses bool is_warning = false; // can be set by subclasses
private: private:
// disable assignment // disable copy assignment and move
Throwable &operator=(const Throwable &) = delete; Throwable &operator=(const Throwable &) DELETED_FUNCTION;
Throwable(Throwable &&) noexcept DELETED_FUNCTION;
Throwable &operator=(Throwable &&) noexcept DELETED_FUNCTION;
// disable dynamic allocation => force throwing by value // disable dynamic allocation => force throwing by value
ACC_CXX_DISABLE_NEW_DELETE ACC_CXX_DISABLE_NEW_DELETE
// disable taking the address => force passing by reference
// [I'm not too sure about this design decision, but we can always allow it if needed]
Throwable *operator&() const noexcept DELETED_FUNCTION;
private: private:
static unsigned long counter; // for debugging static upx_std_atomic(size_t) debug_counter; // for debugging
}; };
// Exceptions can/should be caught // Exceptions can/should be caught
class Exception : public Throwable { class Exception : public Throwable {
typedef Throwable super; typedef Throwable super;
public: public:
Exception(const char *m = nullptr, int e = 0, bool w = false) noexcept : super(m, e, w) {} Exception(const char *m = nullptr, int e = 0, bool w = false) noexcept : super(m, e, w) {}
}; };
@@ -78,7 +80,6 @@ public:
// Errors should not be caught (or re-thrown) // Errors should not be caught (or re-thrown)
class Error : public Throwable { class Error : public Throwable {
typedef Throwable super; typedef Throwable super;
public: public:
Error(const char *m = nullptr, int e = 0) noexcept : super(m, e) {} Error(const char *m = nullptr, int e = 0) noexcept : super(m, e) {}
}; };
@@ -87,37 +88,32 @@ public:
// system exception // system exception
**************************************************************************/ **************************************************************************/
class OutOfMemoryException : public Exception { class OutOfMemoryException final : public Exception {
typedef Exception super; typedef Exception super;
public: public:
OutOfMemoryException(const char *m = nullptr, int e = 0) noexcept : super(m, e) {} OutOfMemoryException(const char *m = nullptr, int e = 0) noexcept : super(m, e) {}
}; };
class IOException : public Exception { class IOException /*not_final*/ : public Exception {
typedef Exception super; typedef Exception super;
public: public:
IOException(const char *m = nullptr, int e = 0) noexcept : super(m, e) {} IOException(const char *m = nullptr, int e = 0) noexcept : super(m, e) {}
}; };
class EOFException : public IOException { class EOFException final : public IOException {
typedef IOException super; typedef IOException super;
public: public:
EOFException(const char *m = nullptr, int e = 0) noexcept : super(m, e) {} EOFException(const char *m = nullptr, int e = 0) noexcept : super(m, e) {}
}; };
class FileNotFoundException : public IOException { class FileNotFoundException final : public IOException {
typedef IOException super; typedef IOException super;
public: public:
FileNotFoundException(const char *m = nullptr, int e = 0) noexcept : super(m, e) {} FileNotFoundException(const char *m = nullptr, int e = 0) noexcept : super(m, e) {}
}; };
class FileAlreadyExistsException : public IOException { class FileAlreadyExistsException final : public IOException {
typedef IOException super; typedef IOException super;
public: public:
FileAlreadyExistsException(const char *m = nullptr, int e = 0) noexcept : super(m, e) {} FileAlreadyExistsException(const char *m = nullptr, int e = 0) noexcept : super(m, e) {}
}; };
@@ -126,52 +122,45 @@ public:
// application exceptions // application exceptions
**************************************************************************/ **************************************************************************/
class OverlayException : public Exception { class OverlayException final : public Exception {
typedef Exception super; typedef Exception super;
public: public:
OverlayException(const char *m = nullptr, bool w = false) noexcept : super(m, 0, w) {} OverlayException(const char *m = nullptr, bool w = false) noexcept : super(m, 0, w) {}
}; };
class CantPackException : public Exception { class CantPackException /*not_final*/ : public Exception {
typedef Exception super; typedef Exception super;
public: public:
CantPackException(const char *m = nullptr, bool w = false) noexcept : super(m, 0, w) {} CantPackException(const char *m = nullptr, bool w = false) noexcept : super(m, 0, w) {}
}; };
class UnknownExecutableFormatException : public CantPackException { class UnknownExecutableFormatException : public CantPackException {
typedef CantPackException super; typedef CantPackException super;
public: public:
UnknownExecutableFormatException(const char *m = nullptr, bool w = false) noexcept UnknownExecutableFormatException(const char *m = nullptr, bool w = false) noexcept
: super(m, w) {} : super(m, w) {}
}; };
class AlreadyPackedException : public CantPackException { class AlreadyPackedException final : public CantPackException {
typedef CantPackException super; typedef CantPackException super;
public: public:
AlreadyPackedException(const char *m = nullptr) noexcept : super(m) { is_warning = true; } AlreadyPackedException(const char *m = nullptr) noexcept : super(m) { is_warning = true; }
}; };
class NotCompressibleException : public CantPackException { class NotCompressibleException final : public CantPackException {
typedef CantPackException super; typedef CantPackException super;
public: public:
NotCompressibleException(const char *m = nullptr) noexcept : super(m) {} NotCompressibleException(const char *m = nullptr) noexcept : super(m) {}
}; };
class CantUnpackException : public Exception { class CantUnpackException /*not_final*/ : public Exception {
typedef Exception super; typedef Exception super;
public: public:
CantUnpackException(const char *m = nullptr, bool w = false) noexcept : super(m, 0, w) {} CantUnpackException(const char *m = nullptr, bool w = false) noexcept : super(m, 0, w) {}
}; };
class NotPackedException : public CantUnpackException { class NotPackedException final : public CantUnpackException {
typedef CantUnpackException super; typedef CantUnpackException super;
public: public:
NotPackedException(const char *m = nullptr) noexcept : super(m, true) {} NotPackedException(const char *m = nullptr) noexcept : super(m, true) {}
}; };
@@ -180,9 +169,8 @@ public:
// errors // errors
**************************************************************************/ **************************************************************************/
class InternalError : public Error { class InternalError final : public Error {
typedef Error super; typedef Error super;
public: public:
InternalError(const char *m = nullptr) noexcept : super(m, 0) {} InternalError(const char *m = nullptr) noexcept : super(m, 0) {}
}; };
@@ -193,9 +181,9 @@ public:
#undef NORET #undef NORET
#if 1 && defined(__GNUC__) #if 1 && defined(__GNUC__)
#define NORET __acc_noinline __attribute__((__noreturn__)) #define NORET noinline __attribute__((__noreturn__))
#else #else
#define NORET __acc_noinline #define NORET noinline
#endif #endif
NORET void throwCantPack(const char *msg); NORET void throwCantPack(const char *msg);
@@ -215,10 +203,16 @@ NORET void throwOutOfMemoryException(const char *msg = nullptr);
NORET void throwIOException(const char *msg = nullptr, int e = 0); NORET void throwIOException(const char *msg = nullptr, int e = 0);
NORET void throwEOFException(const char *msg = nullptr, int e = 0); NORET void throwEOFException(const char *msg = nullptr, int e = 0);
// some C++ template wizardry is needed to overload throwCantPack() for varargs
template <class T>
void throwCantPack(const T *, ...) DELETED_FUNCTION;
template <>
NORET void throwCantPack(const char *format, ...) attribute_format(1, 2);
template <class T>
void throwCantUnpack(const T *, ...) DELETED_FUNCTION;
template <>
NORET void throwCantUnpack(const char *format, ...) attribute_format(1, 2);
#undef NORET #undef NORET
#endif /* __cplusplus */
#endif /* already included */
/* vim:set ts=4 sw=4 et: */ /* vim:set ts=4 sw=4 et: */
+52 -35
View File
@@ -29,11 +29,11 @@
#include "file.h" #include "file.h"
/************************************************************************* /*************************************************************************
// static functions // static file-related util functions; will throw on error
**************************************************************************/ **************************************************************************/
void FileBase::chmod(const char *name, int mode) { /*static*/ void FileBase::chmod(const char *name, int mode) {
#if (HAVE_CHMOD) #if HAVE_CHMOD
if (::chmod(name, mode) != 0) if (::chmod(name, mode) != 0)
throwIOException(name, errno); throwIOException(name, errno);
#else #else
@@ -42,7 +42,7 @@ void FileBase::chmod(const char *name, int mode) {
#endif #endif
} }
void FileBase::rename(const char *old_, const char *new_) { /*static*/ void FileBase::rename(const char *old_, const char *new_) {
#if (ACC_OS_DOS32) && defined(__DJGPP__) #if (ACC_OS_DOS32) && defined(__DJGPP__)
if (::_rename(old_, new_) != 0) if (::_rename(old_, new_) != 0)
#else #else
@@ -51,7 +51,7 @@ void FileBase::rename(const char *old_, const char *new_) {
throwIOException("rename error", errno); throwIOException("rename error", errno);
} }
void FileBase::unlink(const char *name) { /*static*/ void FileBase::unlink(const char *name) {
if (::unlink(name) != 0) if (::unlink(name) != 0)
throwIOException(name, errno); throwIOException(name, errno);
} }
@@ -60,12 +60,7 @@ void FileBase::unlink(const char *name) {
// //
**************************************************************************/ **************************************************************************/
FileBase::FileBase() FileBase::~FileBase() may_throw {
: _fd(-1), _flags(0), _shflags(0), _mode(0), _name(nullptr), _offset(0), _length(0) {
memset(&st, 0, sizeof(st));
}
FileBase::~FileBase() {
#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__);
@@ -98,7 +93,7 @@ bool FileBase::do_sopen() {
return true; return true;
} }
bool FileBase::close() { bool FileBase::close() noexcept {
bool ok = true; bool ok = true;
if (isOpen() && _fd != STDIN_FILENO && _fd != STDOUT_FILENO && _fd != STDERR_FILENO) if (isOpen() && _fd != STDIN_FILENO && _fd != STDOUT_FILENO && _fd != STDERR_FILENO)
if (::close(_fd) == -1) if (::close(_fd) == -1)
@@ -112,7 +107,7 @@ bool FileBase::close() {
return ok; return ok;
} }
void FileBase::closex() { void FileBase::closex() may_throw {
if (!close()) if (!close())
throwIOException("close failed", errno); throwIOException("close failed", errno);
} }
@@ -134,10 +129,10 @@ upx_off_t FileBase::seek(upx_off_t off, int whence) {
whence = SEEK_SET; whence = SEEK_SET;
} }
// SEEK_CUR falls through to here // SEEK_CUR falls through to here
upx_off_t rv = ::lseek(_fd, off, whence); upx_off_t l = ::lseek(_fd, off, whence);
if (rv < 0) if (l < 0)
throwIOException("seek error", errno); throwIOException("seek error", errno);
return rv - _offset; return l - _offset;
} }
upx_off_t FileBase::tell() const { upx_off_t FileBase::tell() const {
@@ -160,8 +155,6 @@ upx_off_t FileBase::st_size() const { return _length; }
// //
**************************************************************************/ **************************************************************************/
InputFile::InputFile() {}
void InputFile::sopen(const char *name, int flags, int shflags) { void InputFile::sopen(const char *name, int flags, int shflags) {
close(); close();
_name = name; _name = name;
@@ -181,10 +174,10 @@ void InputFile::sopen(const char *name, int flags, int shflags) {
_length_orig = _length; _length_orig = _length;
} }
int InputFile::read(SPAN_P(void) buf, int len) { int InputFile::read(SPAN_P(void) buf, upx_int64_t blen) {
if (!isOpen() || len < 0) if (!isOpen() || blen < 0)
throwIOException("bad read"); throwIOException("bad read");
mem_size_assert(1, len); // sanity check int len = (int) mem_size(1, blen); // sanity check
errno = 0; errno = 0;
long l = acc_safe_hread(_fd, raw_bytes(buf, len), len); long l = acc_safe_hread(_fd, raw_bytes(buf, len), len);
if (errno) if (errno)
@@ -192,9 +185,9 @@ int InputFile::read(SPAN_P(void) buf, int len) {
return (int) l; return (int) l;
} }
int InputFile::readx(SPAN_P(void) buf, int len) { int InputFile::readx(SPAN_P(void) buf, upx_int64_t blen) {
int l = this->read(buf, len); int l = this->read(buf, blen);
if (l != len) if (l != blen)
throwEOFException(); throwEOFException();
return l; return l;
} }
@@ -212,8 +205,6 @@ upx_off_t InputFile::st_size_orig() const { return _length_orig; }
// //
**************************************************************************/ **************************************************************************/
OutputFile::OutputFile() : bytes_written(0) {}
void OutputFile::sopen(const char *name, int flags, int shflags, int mode) { void OutputFile::sopen(const char *name, int flags, int shflags, int mode) {
close(); close();
_name = name; _name = name;
@@ -253,22 +244,33 @@ bool OutputFile::openStdout(int flags, bool force) {
return true; return true;
} }
void OutputFile::write(SPAN_0(const void) buf, int len) { void OutputFile::write(SPAN_0(const void) buf, upx_int64_t blen) {
if (!isOpen() || len < 0) if (!isOpen() || blen < 0)
throwIOException("bad write"); throwIOException("bad write");
// allow nullptr if len == 0 // allow nullptr if blen == 0
if (len == 0) if (blen == 0)
return; return;
mem_size_assert(1, len); // sanity check int len = (int) mem_size(1, blen); // sanity check
errno = 0; errno = 0;
#if 0 #if WITH_XSPAN >= 2
fprintf(stderr, "write %p %zd (%p) %d\n", buf.raw_ptr(), buf.raw_size_in_bytes(), NO_fprintf(stderr, "write %p %zd (%p) %d\n", buf.raw_ptr(), buf.raw_size_in_bytes(),
buf.raw_base(), len); buf.raw_base(), len);
#endif #endif
long l = acc_safe_hwrite(_fd, raw_bytes(buf, len), len); long l = acc_safe_hwrite(_fd, raw_bytes(buf, len), len);
if (l != len) if (l != len)
throwIOException("write error", errno); throwIOException("write error", errno);
bytes_written += len; bytes_written += len;
#if TESTING && 0
static upx_std_atomic(bool) dumping;
if (!dumping) {
dumping = true;
char fn[64];
static int part = 0;
snprintf(fn, sizeof(fn), "upx-dump-%04d.data", part++);
OutputFile::dump(fn, buf, len);
dumping = false;
}
#endif
} }
upx_off_t OutputFile::st_size() const { upx_off_t OutputFile::st_size() const {
@@ -319,7 +321,7 @@ upx_off_t OutputFile::seek(upx_off_t off, int whence) {
void OutputFile::set_extent(upx_off_t offset, upx_off_t length) { void OutputFile::set_extent(upx_off_t offset, upx_off_t length) {
super::set_extent(offset, length); super::set_extent(offset, length);
bytes_written = 0; bytes_written = 0;
if (0 == offset && (upx_off_t) ~0u == length) { if (0 == offset && 0xffffffffLL == length) { // TODO: check all callers of this method
if (::fstat(_fd, &st) != 0) if (::fstat(_fd, &st) != 0)
throwIOException(_name, errno); throwIOException(_name, errno);
_length = st.st_size - offset; _length = st.st_size - offset;
@@ -336,7 +338,7 @@ upx_off_t OutputFile::unset_extent() {
return _length; return _length;
} }
void OutputFile::dump(const char *name, SPAN_P(const void) buf, int len, int flags) { /*static*/ void OutputFile::dump(const char *name, SPAN_P(const void) buf, int len, int flags) {
if (flags < 0) if (flags < 0)
flags = O_CREAT | O_TRUNC; flags = O_CREAT | O_TRUNC;
flags |= O_WRONLY | O_BINARY; flags |= O_WRONLY | O_BINARY;
@@ -346,4 +348,19 @@ void OutputFile::dump(const char *name, SPAN_P(const void) buf, int len, int fla
f.closex(); f.closex();
} }
/*************************************************************************
//
**************************************************************************/
TEST_CASE("file") {
InputFile fi;
CHECK(!fi.isOpen());
CHECK(fi.getFd() == -1);
CHECK(fi.st_size() == 0);
OutputFile fo;
CHECK(!fo.isOpen());
CHECK(fo.getFd() == -1);
CHECK(fo.getBytesWritten() == 0);
}
/* vim:set ts=4 sw=4 et: */ /* vim:set ts=4 sw=4 et: */
+12 -18
View File
@@ -26,8 +26,6 @@
*/ */
#pragma once #pragma once
#ifndef UPX_FILE_H__
#define UPX_FILE_H__ 1
/************************************************************************* /*************************************************************************
// //
@@ -35,12 +33,12 @@
class FileBase { class FileBase {
protected: protected:
FileBase(); explicit FileBase() noexcept = default;
virtual ~FileBase(); virtual ~FileBase() may_throw;
public: public:
bool close(); bool close() noexcept;
void closex(); void closex() may_throw;
bool isOpen() const { return _fd >= 0; } bool isOpen() const { return _fd >= 0; }
int getFd() const { return _fd; } int getFd() const { return _fd; }
const char *getName() const { return _name; } const char *getName() const { return _name; }
@@ -51,7 +49,7 @@ public:
virtual void set_extent(upx_off_t offset, upx_off_t length); virtual void set_extent(upx_off_t offset, upx_off_t length);
public: public:
// static file-related util functions // static file-related util functions; will throw on error
static void chmod(const char *name, int mode); static void chmod(const char *name, int mode);
static void rename(const char *old_, const char *new_); static void rename(const char *old_, const char *new_);
static void unlink(const char *name); static void unlink(const char *name);
@@ -78,14 +76,13 @@ class InputFile final : public FileBase {
typedef FileBase super; typedef FileBase super;
public: public:
InputFile(); explicit InputFile() noexcept = default;
virtual ~InputFile() {}
void sopen(const char *name, int flags, int shflags); void sopen(const char *name, int flags, int shflags);
void open(const char *name, int flags) { sopen(name, flags, -1); } void open(const char *name, int flags) { sopen(name, flags, -1); }
int read(SPAN_P(void) buf, int len); int read(SPAN_P(void) buf, upx_int64_t blen);
int readx(SPAN_P(void) buf, int len); int readx(SPAN_P(void) buf, upx_int64_t blen);
virtual upx_off_t seek(upx_off_t off, int whence) override; virtual upx_off_t seek(upx_off_t off, int whence) override;
upx_off_t st_size_orig() const; upx_off_t st_size_orig() const;
@@ -102,15 +99,14 @@ class OutputFile final : public FileBase {
typedef FileBase super; typedef FileBase super;
public: public:
OutputFile(); explicit OutputFile() noexcept = default;
virtual ~OutputFile() {}
void sopen(const char *name, int flags, int shflags, int mode); void sopen(const char *name, int flags, int shflags, int mode);
void open(const char *name, int flags, int mode) { sopen(name, flags, -1, mode); } void open(const char *name, int flags, int mode) { sopen(name, flags, -1, mode); }
bool openStdout(int flags = 0, bool force = false); bool openStdout(int flags = 0, bool force = false);
// info: allow nullptr if len == 0 // info: allow nullptr if blen == 0
void write(SPAN_0(const void) buf, int len); void write(SPAN_0(const void) buf, upx_int64_t blen);
virtual upx_off_t seek(upx_off_t off, int whence) override; virtual upx_off_t seek(upx_off_t off, int whence) override;
virtual upx_off_t st_size() const override; // { return _length; } virtual upx_off_t st_size() const override; // { return _length; }
@@ -119,7 +115,7 @@ public:
upx_off_t getBytesWritten() const { return bytes_written; } upx_off_t getBytesWritten() const { return bytes_written; }
// FIXME - these won't work when using the '--stdout' option // FIXME - this won't work when using the '--stdout' option
void rewrite(SPAN_P(const void) buf, int len); void rewrite(SPAN_P(const void) buf, int len);
// util // util
@@ -129,6 +125,4 @@ protected:
upx_off_t bytes_written = 0; upx_off_t bytes_written = 0;
}; };
#endif
/* vim:set ts=4 sw=4 et: */ /* vim:set ts=4 sw=4 et: */
+24 -20
View File
@@ -33,7 +33,7 @@
// util // util
**************************************************************************/ **************************************************************************/
static void initFilter(Filter *f, upx_byte *buf, unsigned buf_len) { static void initFilter(Filter *f, byte *buf, unsigned buf_len) noexcept {
f->buf = buf; f->buf = buf;
f->buf_len = buf_len; f->buf_len = buf_len;
// clear output parameters // clear output parameters
@@ -44,38 +44,37 @@ static void initFilter(Filter *f, upx_byte *buf, unsigned buf_len) {
// get a FilterEntry // get a FilterEntry
**************************************************************************/ **************************************************************************/
const FilterImpl::FilterEntry *FilterImpl::getFilter(int id) { /*static*/ const FilterImpl::FilterEntry *FilterImpl::getFilter(int id) {
static bool done = false; static upx_uint8_t filter_map[256];
static unsigned char filter_map[256]; static upx_std_once_flag init_done;
if (!done) { upx_std_call_once(init_done, []() noexcept {
// init the filter_map[] // init the filter_map[] (using a lambda function)
assert(n_filters <= 254); // as 0xff means "empty slot" assert_noexcept(n_filters <= 254); // as 0xff means "empty slot"
memset(filter_map, 0xff, sizeof(filter_map)); memset(filter_map, 0xff, sizeof(filter_map));
for (int i = 0; i < n_filters; i++) { for (int i = 0; i < n_filters; i++) {
int filter_id = filters[i].id; int filter_id = filters[i].id;
assert(filter_id >= 0 && filter_id <= 255); assert_noexcept(filter_id >= 0 && filter_id <= 255);
assert(filter_map[filter_id] == 0xff); assert_noexcept(filter_map[filter_id] == 0xff);
filter_map[filter_id] = (unsigned char) i; filter_map[filter_id] = (upx_uint8_t) i;
}
done = true;
} }
});
if (id < 0 || id > 255) if (id < 0 || id > 255)
return nullptr; return nullptr;
unsigned index = filter_map[id]; unsigned index = filter_map[id];
if (index == 0xff) // empty slot if (index == 0xff) // empty slot
return nullptr; return nullptr;
assert(filters[index].id == id); assert_noexcept(filters[index].id == id);
return &filters[index]; return &filters[index];
} }
bool Filter::isValidFilter(int filter_id) { /*static*/ bool Filter::isValidFilter(int filter_id) {
const FilterImpl::FilterEntry *const fe = FilterImpl::getFilter(filter_id); const FilterImpl::FilterEntry *const fe = FilterImpl::getFilter(filter_id);
return fe != nullptr; return fe != nullptr;
} }
bool Filter::isValidFilter(int filter_id, const int *allowed_filters) { /*static*/ bool Filter::isValidFilter(int filter_id, const int *allowed_filters) {
if (!isValidFilter(filter_id)) if (!isValidFilter(filter_id))
return false; return false;
if (filter_id == 0) if (filter_id == 0)
@@ -92,7 +91,9 @@ bool Filter::isValidFilter(int filter_id, const int *allowed_filters) {
// high level API // high level API
**************************************************************************/ **************************************************************************/
void Filter::init(int id_, unsigned addvalue_) { Filter::Filter(int level) noexcept : clevel(level) { init(); }
void Filter::init(int id_, unsigned addvalue_) noexcept {
this->id = id_; this->id = id_;
initFilter(this, nullptr, 0); initFilter(this, nullptr, 0);
// clear input parameters // clear input parameters
@@ -103,7 +104,8 @@ void Filter::init(int id_, unsigned addvalue_) {
this->n_mru = 0; this->n_mru = 0;
} }
bool Filter::filter(upx_byte *buf_, unsigned buf_len_) { bool Filter::filter(SPAN_0(byte) xbuf, unsigned buf_len_) {
byte *const buf_ = raw_bytes(xbuf, buf_len_);
initFilter(this, buf_, buf_len_); initFilter(this, buf_, buf_len_);
const FilterImpl::FilterEntry *const fe = FilterImpl::getFilter(id); const FilterImpl::FilterEntry *const fe = FilterImpl::getFilter(id);
@@ -134,7 +136,8 @@ bool Filter::filter(upx_byte *buf_, unsigned buf_len_) {
return false; return false;
} }
void Filter::unfilter(upx_byte *buf_, unsigned buf_len_, bool verify_checksum) { void Filter::unfilter(SPAN_0(byte) xbuf, unsigned buf_len_, bool verify_checksum) {
byte *const buf_ = raw_bytes(xbuf, buf_len_);
initFilter(this, buf_, buf_len_); initFilter(this, buf_, buf_len_);
const FilterImpl::FilterEntry *const fe = FilterImpl::getFilter(id); const FilterImpl::FilterEntry *const fe = FilterImpl::getFilter(id);
@@ -178,10 +181,11 @@ void Filter::verifyUnfilter() {
unfilter(this->buf, this->buf_len, true); unfilter(this->buf, this->buf_len, true);
} }
bool Filter::scan(const upx_byte *buf_, unsigned buf_len_) { bool Filter::scan(SPAN_0(const byte) xbuf, unsigned buf_len_) {
const byte *const buf_ = raw_bytes(xbuf, buf_len_);
// Note: must use const_cast here. This is fine as the scan // Note: must use const_cast here. This is fine as the scan
// implementations (fe->do_scan) actually don't change the buffer. // implementations (fe->do_scan) actually don't change the buffer.
upx_byte *b = const_cast<upx_byte *>(buf_); byte *const b = const_cast<byte *>(buf_);
initFilter(this, b, buf_len_); initFilter(this, b, buf_len_);
const FilterImpl::FilterEntry *const fe = FilterImpl::getFilter(id); const FilterImpl::FilterEntry *const fe = FilterImpl::getFilter(id);
+10 -15
View File
@@ -26,8 +26,6 @@
*/ */
#pragma once #pragma once
#ifndef UPX_FILTER_H__
#define UPX_FILTER_H__ 1
/************************************************************************* /*************************************************************************
// A filter is a reversible operation that modifies a given // A filter is a reversible operation that modifies a given
@@ -46,18 +44,15 @@
// to absolute addresses so that the buffer compresses better. // to absolute addresses so that the buffer compresses better.
**************************************************************************/ **************************************************************************/
class Filter { class Filter final {
public: public:
Filter(int level) { explicit Filter(int level) noexcept;
clevel = level; void init(int id = 0, unsigned addvalue = 0) noexcept;
init();
}
void init(int id = 0, unsigned addvalue = 0);
bool filter(upx_byte *buf, unsigned buf_len); bool filter(SPAN_0(byte) buf, unsigned buf_len);
void unfilter(upx_byte *buf, unsigned buf_len, bool verify_checksum = false); void unfilter(SPAN_0(byte) buf, unsigned buf_len, bool verify_checksum = false);
void verifyUnfilter(); void verifyUnfilter();
bool scan(const upx_byte *buf, unsigned buf_len); bool scan(SPAN_0(const byte) buf, unsigned buf_len);
static bool isValidFilter(int filter_id); static bool isValidFilter(int filter_id);
static bool isValidFilter(int filter_id, const int *allowed_filters); static bool isValidFilter(int filter_id, const int *allowed_filters);
@@ -65,7 +60,7 @@ public:
public: public:
// Will be set by each call to filter()/unfilter(). // Will be set by each call to filter()/unfilter().
// Read-only afterwards. // Read-only afterwards.
upx_byte *buf = nullptr; byte *buf = nullptr;
unsigned buf_len = 0; unsigned buf_len = 0;
// Checksum of the buffer before applying the filter // Checksum of the buffer before applying the filter
@@ -77,7 +72,7 @@ public:
const int *preferred_ctos = nullptr; const int *preferred_ctos = nullptr;
// Input/output parameters used by various filters // Input/output parameters used by various filters
unsigned char cto; // call trick offset byte cto; // call trick offset
// Output used by various filters. Read only. // Output used by various filters. Read only.
unsigned calls; unsigned calls;
@@ -105,6 +100,8 @@ class FilterImpl {
friend class Filter; friend class Filter;
private: private:
explicit FilterImpl() noexcept DELETED_FUNCTION;
struct FilterEntry { struct FilterEntry {
int id; // 0 .. 255 int id; // 0 .. 255
unsigned min_buf_len; unsigned min_buf_len;
@@ -123,6 +120,4 @@ private:
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: */ /* vim:set ts=4 sw=4 et: */
+61 -11
View File
@@ -32,8 +32,8 @@
**************************************************************************/ **************************************************************************/
#define CT16(f, cond, addvalue, get, set) \ #define CT16(f, cond, addvalue, get, set) \
upx_byte *b = f->buf; \ byte *b = f->buf; \
upx_byte *b_end = b + f->buf_len - 3; \ byte *b_end = b + f->buf_len - 3; \
do { \ do { \
if (cond) \ if (cond) \
{ \ { \
@@ -211,8 +211,8 @@ static int s_ct16_e8e9_bswap_be(Filter *f)
**************************************************************************/ **************************************************************************/
#define CT32(f, cond, addvalue, get, set) \ #define CT32(f, cond, addvalue, get, set) \
upx_byte *b = f->buf; \ byte *b = f->buf; \
upx_byte *b_end = b + f->buf_len - 5; \ byte *b_end = b + f->buf_len - 5; \
do { \ do { \
if (cond) \ if (cond) \
{ \ { \
@@ -388,8 +388,8 @@ static int s_ct32_e8e9_bswap_be(Filter *f)
**************************************************************************/ **************************************************************************/
#define CT24ARM_LE(f, cond, addvalue, get, set) \ #define CT24ARM_LE(f, cond, addvalue, get, set) \
upx_byte *b = f->buf; \ byte *b = f->buf; \
upx_byte *b_end = b + f->buf_len - 4; \ byte *b_end = b + f->buf_len - 4; \
do { \ do { \
if (cond) \ if (cond) \
{ \ { \
@@ -424,8 +424,8 @@ static int s_ct24arm_le(Filter *f)
#undef CT24ARM_LE #undef CT24ARM_LE
#define CT24ARM_BE(f, cond, addvalue, get, set) \ #define CT24ARM_BE(f, cond, addvalue, get, set) \
upx_byte *b = f->buf; \ byte *b = f->buf; \
upx_byte *b_end = b + f->buf_len - 4; \ byte *b_end = b + f->buf_len - 4; \
do { \ do { \
if (cond) \ if (cond) \
{ \ { \
@@ -463,9 +463,10 @@ static int s_ct24arm_be(Filter *f)
// 26-bit ARM calltrick ("naive") // 26-bit ARM calltrick ("naive")
**************************************************************************/ **************************************************************************/
#if 1 //{ old reliable
#define CT26ARM_LE(f, cond, addvalue, get, set) \ #define CT26ARM_LE(f, cond, addvalue, get, set) \
upx_byte *b = f->buf; \ byte *b = f->buf; \
upx_byte *b_end = b + f->buf_len - 4; \ byte *b_end = b + f->buf_len - 4; \
do { \ do { \
if (cond) \ if (cond) \
{ \ { \
@@ -479,7 +480,6 @@ static int s_ct24arm_be(Filter *f)
if (f->lastcall) f->lastcall += 4; \ if (f->lastcall) f->lastcall += 4; \
return 0; return 0;
#define ARMCT_COND (((b[3] & 0x7C) == 0x14)) #define ARMCT_COND (((b[3] & 0x7C) == 0x14))
static int f_ct26arm_le(Filter *f) static int f_ct26arm_le(Filter *f)
@@ -497,6 +497,56 @@ static int s_ct26arm_le(Filter *f)
CT26ARM_LE(f, ARMCT_COND, a + f->addvalue, get_le26, set_dummy) CT26ARM_LE(f, ARMCT_COND, a + f->addvalue, get_le26, set_dummy)
} }
#else //}{ new enhanced but DIFFERENT; need new filter type!
static int CTarm64(Filter *f, int dir) // dir: 1, 0, -1
{
upx_byte *b = f->buf; // will be incremented
upx_byte *const b_end = b + f->buf_len - 4;
do {
unsigned const a = b - f->buf;
int const d = dir * (f->addvalue + (a >> 2));
unsigned const v = get_le32(f->buf); // the 32-bit instruction
if (0x05 == (0x1f & (v >> 26))) { // b, bl
f->lastcall = a;
if (dir) set_le26(b, v + d);
f->calls++;
}
else if ( (0x54 == (v >> 24) ) // b.cond
|| (0x1a == ((v >> 25) & 0x3f)) // cb{z,nz}
) {
f->lastcall = a;
if (dir) set_le19_5(b, (v >> 5) + d);
f->calls++;
}
else if (0x1b == ((v >> 25) & 0x3f)) { // tb{z,nz}
f->lastcall = a;
if (dir) set_le14_5(b, (v >> 5) + d);
f->calls++;
}
b += 4;
} while (b < b_end);
if (f->lastcall) f->lastcall += 4;
return 0;
}
static int f_CTarm64_le(Filter *f)
{
return CTarm64(f, 1);
}
static int u_CTarm64_le(Filter *f)
{
return CTarm64(f, -1);
}
static int s_CTarm64_le(Filter *f)
{
return CTarm64(f, 0);
}
#endif //}
#undef CT26ARM_LE #undef CT26ARM_LE
#undef ARMCT_COND #undef ARMCT_COND
+3 -3
View File
@@ -35,10 +35,10 @@ static int F(Filter *f)
{ {
#ifdef U #ifdef U
// filter // filter
upx_byte *b = f->buf; byte *b = f->buf;
#else #else
// scan // scan
const upx_byte *b = f->buf; const byte *b = f->buf;
#endif #endif
const unsigned addvalue = f->addvalue; const unsigned addvalue = f->addvalue;
const unsigned size = f->buf_len; const unsigned size = f->buf_len;
@@ -141,7 +141,7 @@ static int F(Filter *f)
#ifdef U #ifdef U
static int U(Filter *f) static int U(Filter *f)
{ {
upx_byte *b = f->buf; byte *b = f->buf;
const unsigned size5 = f->buf_len - 5; const unsigned size5 = f->buf_len - 5;
const unsigned addvalue = f->addvalue; const unsigned addvalue = f->addvalue;
const unsigned cto = (unsigned)f->cto << 24; const unsigned cto = (unsigned)f->cto << 24;
+3 -3
View File
@@ -39,10 +39,10 @@ static int F(Filter *f)
{ {
#ifdef U #ifdef U
// filter // filter
upx_byte *b = f->buf; byte *b = f->buf;
#else #else
// scan // scan
const upx_byte *b = f->buf; const byte *b = f->buf;
#endif #endif
const unsigned addvalue = f->addvalue; const unsigned addvalue = f->addvalue;
const unsigned size = f->buf_len; const unsigned size = f->buf_len;
@@ -140,7 +140,7 @@ static int F(Filter *f)
#ifdef U #ifdef U
static int U(Filter *f) static int U(Filter *f)
{ {
upx_byte *b = f->buf; byte *b = f->buf;
const unsigned size5 = f->buf_len - 5; const unsigned size5 = f->buf_len - 5;
const unsigned addvalue = f->addvalue; const unsigned addvalue = f->addvalue;
const unsigned cto = (unsigned)f->cto << 24; const unsigned cto = (unsigned)f->cto << 24;
+13 -13
View File
@@ -67,8 +67,8 @@ f80_jcc2(Filter const *f)
// Adaptively remember recent destinations. // Adaptively remember recent destinations.
static void static void
update_mru( update_mru(
unsigned const jc, // destination address const unsigned jc, // destination address
int const kh, // mru[kh] is slot where found const int kh, // mru[kh] is slot where found
unsigned mru[N_MRU], // circular buffer of most recent destinations unsigned mru[N_MRU], // circular buffer of most recent destinations
int &hand, // mru[hand] is most recent destination int &hand, // mru[hand] is most recent destination
int &tail // mru[tail] is beyond oldest destination ("cold cache" startup) int &tail // mru[tail] is beyond oldest destination ("cold cache" startup)
@@ -77,7 +77,7 @@ update_mru(
if (0 > --hand) { if (0 > --hand) {
hand = N_MRU -1; hand = N_MRU -1;
} }
unsigned const t = mru[hand]; // entry which will be overwritten by jc const unsigned t = mru[hand]; // entry which will be overwritten by jc
if (0!=t) { // have seen at least N_MRU destinations if (0!=t) { // have seen at least N_MRU destinations
mru[kh] = t; mru[kh] = t;
} }
@@ -85,7 +85,7 @@ update_mru(
if (0 > --tail) { if (0 > --tail) {
tail = N_MRU -1; tail = N_MRU -1;
} }
unsigned const t2 = mru[tail]; const unsigned t2 = mru[tail];
mru[tail] = 0; mru[tail] = 0;
mru[kh] = t2; mru[kh] = t2;
} }
@@ -98,10 +98,10 @@ static int F(Filter *f)
{ {
#ifdef U #ifdef U
// filter // filter
upx_byte *const b = f->buf; byte *const b = f->buf;
#else #else
// scan // scan
const upx_byte *b = f->buf; const byte *b = f->buf;
#endif #endif
const unsigned size = f->buf_len; const unsigned size = f->buf_len;
@@ -111,9 +111,9 @@ static int F(Filter *f)
unsigned wtally[3]; memset(wtally, 0, sizeof(wtally)); unsigned wtally[3]; memset(wtally, 0, sizeof(wtally));
#ifdef U //{ #ifdef U //{
unsigned const f_call = f80_call(f); const unsigned f_call = f80_call(f);
unsigned const f_jmp1 = f80_jmp1(f); const unsigned f_jmp1 = f80_jmp1(f);
unsigned const f_jcc2 = f80_jcc2(f); const unsigned f_jcc2 = f80_jcc2(f);
int hand = 0, tail = 0; int hand = 0, tail = 0;
unsigned mru[N_MRU]; unsigned mru[N_MRU];
@@ -268,14 +268,14 @@ static int U(Filter *f)
{ {
unsigned ic, jc; unsigned ic, jc;
upx_byte *const b = f->buf; byte *const b = f->buf;
const unsigned size5 = f->buf_len - 5; const unsigned size5 = f->buf_len - 5;
const unsigned cto = (unsigned)f->cto << 24; const unsigned cto = (unsigned)f->cto << 24;
unsigned lastcall = 0; unsigned lastcall = 0;
int hand = 0, tail = 0; int hand = 0, tail = 0;
unsigned const f_call = f80_call(f); const unsigned f_call = f80_call(f);
unsigned const f_jmp1 = f80_jmp1(f); const unsigned f_jmp1 = f80_jmp1(f);
unsigned const f_jcc2 = f80_jcc2(f); const unsigned f_jcc2 = f80_jcc2(f);
unsigned mru[N_MRU]; unsigned mru[N_MRU];
memset(&mru[0], 0, sizeof(mru)); memset(&mru[0], 0, sizeof(mru));
+5 -5
View File
@@ -39,14 +39,14 @@ static int F(Filter *f)
{ {
#ifdef U #ifdef U
// filter // filter
upx_byte *b = f->buf; byte *b = f->buf;
#else #else
// scan // scan
const upx_byte *b = f->buf; const byte *b = f->buf;
#endif #endif
const unsigned addvalue = f->addvalue; const unsigned addvalue = f->addvalue;
const unsigned size = f->buf_len; const unsigned size = f->buf_len;
unsigned const id = f->id; const unsigned id = f->id;
unsigned ic, jc, kc; unsigned ic, jc, kc;
unsigned calls = 0, noncalls = 0, noncalls2 = 0; unsigned calls = 0, noncalls = 0, noncalls2 = 0;
@@ -141,11 +141,11 @@ static int F(Filter *f)
#ifdef U #ifdef U
static int U(Filter *f) static int U(Filter *f)
{ {
upx_byte *b = f->buf; byte *b = f->buf;
const unsigned size5 = f->buf_len - 5; const unsigned size5 = f->buf_len - 5;
const unsigned addvalue = f->addvalue; const unsigned addvalue = f->addvalue;
const unsigned cto = (unsigned)f->cto << 24; const unsigned cto = (unsigned)f->cto << 24;
unsigned const id = f->id; const unsigned id = f->id;
unsigned lastcall = 0; unsigned lastcall = 0;
unsigned ic, jc; unsigned ic, jc;
+4 -4
View File
@@ -32,8 +32,8 @@
**************************************************************************/ **************************************************************************/
#define CTSW16(f, cond1, cond2, addvalue, get, set) \ #define CTSW16(f, cond1, cond2, addvalue, get, set) \
upx_byte *b = f->buf; \ byte *b = f->buf; \
upx_byte *b_end = b + f->buf_len - 3; \ byte *b_end = b + f->buf_len - 3; \
do { \ do { \
if (cond1) \ if (cond1) \
{ \ { \
@@ -102,8 +102,8 @@ static int s_ctsw16_e9_e8(Filter *f)
**************************************************************************/ **************************************************************************/
#define CTSW32(f, cond1, cond2, addvalue, get, set) \ #define CTSW32(f, cond1, cond2, addvalue, get, set) \
upx_byte *b = f->buf; \ byte *b = f->buf; \
upx_byte *b_end = b + f->buf_len - 5; \ byte *b_end = b + f->buf_len - 5; \
do { \ do { \
if (cond1) \ if (cond1) \
{ \ { \
+8 -3
View File
@@ -30,7 +30,7 @@
#include "../filter.h" #include "../filter.h"
static unsigned static unsigned
umin(unsigned const a, unsigned const b) umin(const unsigned a, const unsigned b)
{ {
return (a<=b) ? a : b; return (a<=b) ? a : b;
} }
@@ -168,7 +168,7 @@ umin(unsigned const a, unsigned const b)
// database for use in class Filter // database for use in class Filter
**************************************************************************/ **************************************************************************/
const FilterImpl::FilterEntry FilterImpl::filters[] = { /*static*/ const FilterImpl::FilterEntry FilterImpl::filters[] = {
// no filter // no filter
{ 0x00, 0, 0, nullptr, nullptr, nullptr }, { 0x00, 0, 0, nullptr, nullptr, nullptr },
@@ -228,8 +228,13 @@ const FilterImpl::FilterEntry FilterImpl::filters[] = {
{ 0x50, 8, 0x01ffffff, f_ct24arm_le, u_ct24arm_le, s_ct24arm_le }, { 0x50, 8, 0x01ffffff, f_ct24arm_le, u_ct24arm_le, s_ct24arm_le },
{ 0x51, 8, 0x01ffffff, f_ct24arm_be, u_ct24arm_be, s_ct24arm_be }, { 0x51, 8, 0x01ffffff, f_ct24arm_be, u_ct24arm_be, s_ct24arm_be },
#if 1 //{ old reliable
// 26-bit calltrick for arm64 // 26-bit calltrick for arm64
{ 0x52, 8, 0x03ffffff, f_ct26arm_le, u_ct26arm_le, s_ct26arm_le }, { 0x52, 8, 0x03ffffff, f_ct26arm_le, u_ct26arm_le, s_ct26arm_le },
#else //}{ new enhanced, but needs new filter id
// 26-bit calltrick for arm64; also 19-bit and 14-bit
{ 0x52, 8, 0x03ffffff, f_CTarm64_le, u_CTarm64_le, s_CTarm64_le },
#endif //}
// 32-bit cto calltrick with jmp and jcc(swap 0x0f/0x8Y) and relative renumbering // 32-bit cto calltrick with jmp and jcc(swap 0x0f/0x8Y) and relative renumbering
{ 0x80, 8, 0x00ffffff, f_ctojr32_e8e9_bswap_le, u_ctojr32_e8e9_bswap_le, s_ctojr32_e8e9_bswap_le }, { 0x80, 8, 0x00ffffff, f_ctojr32_e8e9_bswap_le, u_ctojr32_e8e9_bswap_le, s_ctojr32_e8e9_bswap_le },
@@ -261,6 +266,6 @@ const FilterImpl::FilterEntry FilterImpl::filters[] = {
{ 0xd0, 8, 0, f_ppcbxx, u_ppcbxx, s_ppcbxx }, { 0xd0, 8, 0, f_ppcbxx, u_ppcbxx, s_ppcbxx },
}; };
const int FilterImpl::n_filters = TABLESIZE(filters); /*static*/ const int FilterImpl::n_filters = TABLESIZE(filters);
/* vim:set ts=4 sw=4 et: */ /* vim:set ts=4 sw=4 et: */
+2 -2
View File
@@ -31,7 +31,7 @@
// //
**************************************************************************/ **************************************************************************/
static int getcto(Filter *f, const unsigned char *buf, const int n=256) static int getcto(Filter *f, const byte *buf, const int n=256)
{ {
int ic = n; int ic = n;
@@ -63,7 +63,7 @@ static int getcto(Filter *f, const unsigned char *buf, const int n=256)
//throwCantPack("call trick problem"); //throwCantPack("call trick problem");
return -1; return -1;
f->cto = (unsigned char) ic; f->cto = (byte) ic;
return ic; return ic;
} }
+3 -3
View File
@@ -41,11 +41,11 @@ static int F(Filter *f)
{ {
#ifdef U #ifdef U
// filter // filter
upx_byte *b = f->buf; byte *b = f->buf;
const unsigned addvalue = f->addvalue; const unsigned addvalue = f->addvalue;
#else #else
// scan // scan
const upx_byte *b = f->buf; const byte *b = f->buf;
#endif #endif
const unsigned size = umin(f->buf_len, 0u - (~0u<<(32 - (6+ W_CTO)))); const unsigned size = umin(f->buf_len, 0u - (~0u<<(32 - (6+ W_CTO))));
const unsigned size4 = size -4; const unsigned size4 = size -4;
@@ -125,7 +125,7 @@ static int F(Filter *f)
#ifdef U #ifdef U
static int U(Filter *f) static int U(Filter *f)
{ {
upx_byte *b = f->buf; byte *b = f->buf;
const unsigned size4 = umin(f->buf_len - 4, 0u - (~0u<<(32 - (6+ W_CTO)))); const unsigned size4 = umin(f->buf_len - 4, 0u - (~0u<<(32 - (6+ W_CTO))));
const unsigned addvalue = f->addvalue; const unsigned addvalue = f->addvalue;
+2 -2
View File
@@ -32,7 +32,7 @@
**************************************************************************/ **************************************************************************/
#define SUB(f, N, T, get, set) \ #define SUB(f, N, T, get, set) \
upx_byte *b = f->buf; \ byte *b = f->buf; \
unsigned l = f->buf_len / sizeof(T); \ unsigned l = f->buf_len / sizeof(T); \
int i; \ int i; \
T d[N]; \ T d[N]; \
@@ -54,7 +54,7 @@
#define ADD(f, N, T, get, set) \ #define ADD(f, N, T, get, set) \
upx_byte *b = f->buf; \ byte *b = f->buf; \
unsigned l = f->buf_len / sizeof(T); \ unsigned l = f->buf_len / sizeof(T); \
int i; \ int i; \
T d[N]; \ T d[N]; \
+4 -4
View File
@@ -32,8 +32,8 @@
**************************************************************************/ **************************************************************************/
#define SW16(f, cond, get, set) \ #define SW16(f, cond, get, set) \
upx_byte *b = f->buf; \ byte *b = f->buf; \
upx_byte *b_end = b + f->buf_len - 3; \ byte *b_end = b + f->buf_len - 3; \
do { \ do { \
if (cond) \ if (cond) \
{ \ { \
@@ -110,8 +110,8 @@ static int s_sw16_e8e9(Filter *f)
**************************************************************************/ **************************************************************************/
#define SW32(f, cond, get, set) \ #define SW32(f, cond, get, set) \
upx_byte *b = f->buf; \ byte *b = f->buf; \
upx_byte *b_end = b + f->buf_len - 5; \ byte *b_end = b + f->buf_len - 5; \
do { \ do { \
if (cond) \ if (cond) \
{ \ { \
+142
View File
@@ -0,0 +1,142 @@
/* headers.h -- include system headers
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>
*/
#pragma once
#if !(__cplusplus + 0 >= 201703L)
#error "C++17 is required"
#endif
// sanity check
#if defined(__ILP32) || defined(__ILP32__)
static_assert(sizeof(int) == 4);
static_assert(sizeof(long) == 4);
static_assert(sizeof(void *) == 4);
#endif
#if defined(__LP64) || defined(__LP64__)
static_assert(sizeof(int) == 4);
static_assert(sizeof(long) == 8);
static_assert(sizeof(void *) == 8);
#endif
#if defined(_WIN32)
static_assert(sizeof(int) == 4);
static_assert(sizeof(long) == 4);
#if !defined(_WIN64)
static_assert(sizeof(void *) == 4);
#endif
#endif
#if defined(_WIN64)
static_assert(sizeof(int) == 4);
static_assert(sizeof(long) == 4);
static_assert(sizeof(void *) == 8);
#endif
#if !defined(_FILE_OFFSET_BITS)
#define _FILE_OFFSET_BITS 64
#endif
#if defined(_WIN32) && defined(__MINGW32__) && defined(__GNUC__)
#if !defined(_USE_MINGW_ANSI_STDIO)
#define _USE_MINGW_ANSI_STDIO 1
#endif
#endif
// ACC and C system headers
#ifndef ACC_CFG_USE_NEW_STYLE_CASTS
#define ACC_CFG_USE_NEW_STYLE_CASTS 1
#endif
#define ACC_CFG_PREFER_TYPEOF_ACC_INT32E_T ACC_TYPEOF_INT
#define ACC_CFG_PREFER_TYPEOF_ACC_INT64E_T ACC_TYPEOF_LONG_LONG
#include "miniacc.h"
// disable some pedantic warnings
#if (ACC_CC_MSC)
#pragma warning(disable : 4127) // W4: conditional expression is constant
#pragma warning(disable : 4244) // W3: conversion from 'type1' to 'type2', possible loss of data
#pragma warning(disable : 4267) // W3: conversion from 'size_t' to 'type', possible loss of data
#pragma warning(disable : 4820) // W4: padding added after data member
#endif
#undef snprintf
#undef vsnprintf
#define HAVE_STDINT_H 1
#define ACC_WANT_ACC_INCD_H 1
#define ACC_WANT_ACC_INCE_H 1
#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
// C++ system headers
#include <cstddef>
#include <exception>
#include <new>
#include <type_traits>
// C++ multithreading (UPX currently does not use multithreading)
#ifndef WITH_THREADS
#define WITH_THREADS 0
#endif
#if __STDC_NO_ATOMICS__
#undef WITH_THREADS
#endif
#if WITH_THREADS
#include <atomic>
#include <mutex>
#endif
// UPX vendor git 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>
#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)
#error "something pulled in <windows.h>"
#endif
#endif
/* vim:set ts=4 sw=4 et: */
+126 -141
View File
@@ -25,36 +25,34 @@
<markus@oberhumer.com> <ezerotven+github@gmail.com> <markus@oberhumer.com> <ezerotven+github@gmail.com>
*/ */
#include "conf.h" #include "conf.h"
#include "packmast.h"
#include "packer.h"
#include "compress/compress.h" // upx_ucl_version_string() #include "compress/compress.h" // upx_ucl_version_string()
// for list_all_packers():
#include "packer.h"
#include "packmast.h" // PackMaster::visitAllPackers
/************************************************************************* /*************************************************************************
// // header
**************************************************************************/ **************************************************************************/
static bool head_done = 0;
// also see UPX_CONFIG_DISABLE_GITREV in CMakeLists.txt // also see UPX_CONFIG_DISABLE_GITREV in CMakeLists.txt
#if defined(UPX_VERSION_GITREV) #if defined(UPX_VERSION_GITREV)
const char gitrev[] = UPX_VERSION_GITREV; const char gitrev[] = UPX_VERSION_GITREV;
#else #else
const char gitrev[1] = { 0 }; const char gitrev[1] = {0};
#endif #endif
void show_head(void) void show_header(void) {
{
FILE *f = con_term; FILE *f = con_term;
int fg; int fg;
if (head_done) static bool header_done;
if (header_done)
return; return;
head_done = 1; header_done = true;
fg = con_fg(f,FG_GREEN); fg = con_fg(f, FG_GREEN);
// clang-format off
con_fprintf(f, con_fprintf(f,
" Ultimate Packer for eXecutables\n" " Ultimate Packer for eXecutables\n"
" Copyright (C) 1996 - " UPX_VERSION_YEAR "\n" " Copyright (C) 1996 - " UPX_VERSION_YEAR "\n"
@@ -71,22 +69,19 @@ void show_head(void)
UPX_VERSION_STRING, UPX_VERSION_STRING,
#endif #endif
UPX_VERSION_DATE); UPX_VERSION_DATE);
fg = con_fg(f,fg); // clang-format on
#undef V fg = con_fg(f, fg);
UNUSED(fg); UNUSED(fg);
} }
/************************************************************************* /*************************************************************************
// // usage
**************************************************************************/ **************************************************************************/
void show_usage(void) void show_usage(void) {
{
FILE *f = con_term; FILE *f = con_term;
con_fprintf(f,"Usage: %s [-123456789dlthVL] [-qvfk] [-o file] %sfile..\n", progname, con_fprintf(f, "Usage: %s [-123456789dlthVL] [-qvfk] [-o file] %sfile..\n", progname,
#if (ACC_OS_DOS32) && defined(__DJGPP__) #if (ACC_OS_DOS32) && defined(__DJGPP__)
"[@]"); "[@]");
#else #else
@@ -94,34 +89,30 @@ void show_usage(void)
#endif #endif
} }
/************************************************************************* /*************************************************************************
// // list_all_packers()
**************************************************************************/ **************************************************************************/
struct PackerNames namespace {
{ struct PackerNames {
struct Entry { struct Entry {
const char* fname; const char *fname;
const char* sname; const char *sname;
}; };
Entry names[64]; Entry names[64];
size_t names_count; size_t names_count;
const options_t *o; const Options *o;
PackerNames() : names_count(0), o(nullptr) { } PackerNames() : names_count(0), o(nullptr) {}
void add(const Packer *p) void add(const Packer *packer) {
{
p->assertPacker();
assert(names_count < 64); assert(names_count < 64);
names[names_count].fname = p->getFullName(o); names[names_count].fname = packer->getFullName(o);
names[names_count].sname = p->getName(); names[names_count].sname = packer->getName();
names_count++; names_count++;
} }
static Packer* visit(Packer *p, void *user) static Packer *visit(Packer *packer, void *user) {
{
PackerNames *self = (PackerNames *) user; PackerNames *self = (PackerNames *) user;
self->add(p); self->add(packer);
delete p; p = nullptr; delete packer;
return nullptr; return nullptr;
} }
static int __acc_cdecl_qsort cmp_fname(const void *a, const void *b) { static int __acc_cdecl_qsort cmp_fname(const void *a, const void *b) {
@@ -131,24 +122,22 @@ struct PackerNames
return strcmp(((const Entry *) a)->sname, ((const Entry *) b)->sname); return strcmp(((const Entry *) a)->sname, ((const Entry *) b)->sname);
} }
}; };
} // namespace
static void show_all_packers(FILE *f, int verbose) static void list_all_packers(FILE *f, int verbose) {
{ Options o;
options_t o; o.reset(); o.reset();
PackerNames pn; pn.o = &o; PackerNames pn;
pn.o = &o;
PackMaster::visitAllPackers(PackerNames::visit, nullptr, &o, &pn); PackMaster::visitAllPackers(PackerNames::visit, nullptr, &o, &pn);
qsort(pn.names, pn.names_count, sizeof(PackerNames::Entry), PackerNames::cmp_fname); qsort(pn.names, pn.names_count, sizeof(PackerNames::Entry), PackerNames::cmp_fname);
size_t pos = 0; size_t pos = 0;
for (size_t i = 0; i < pn.names_count; ++i) for (size_t i = 0; i < pn.names_count; ++i) {
{
const char *fn = pn.names[i].fname; const char *fn = pn.names[i].fname;
const char *sn = pn.names[i].sname; const char *sn = pn.names[i].sname;
if (verbose > 0) if (verbose > 0) {
{
con_fprintf(f, " %-36s %s\n", fn, sn); con_fprintf(f, " %-36s %s\n", fn, sn);
} } else {
else
{
size_t fl = strlen(fn); size_t fl = strlen(fn);
if (pos == 0) { if (pos == 0) {
con_fprintf(f, " %s", fn); con_fprintf(f, " %s", fn);
@@ -166,22 +155,21 @@ static void show_all_packers(FILE *f, int verbose)
con_fprintf(f, "\n"); con_fprintf(f, "\n");
} }
/************************************************************************* /*************************************************************************
// // help
**************************************************************************/ **************************************************************************/
void show_help(int verbose) void show_help(int verbose) {
{
FILE *f = con_term; FILE *f = con_term;
int fg; int fg;
show_head(); show_header();
show_usage(); show_usage();
fg = con_fg(f,FG_YELLOW); // clang-format off
con_fprintf(f,"\nCommands:\n"); fg = con_fg(f, FG_YELLOW);
fg = con_fg(f,fg); con_fprintf(f, "\nCommands:\n");
fg = con_fg(f, fg);
con_fprintf(f, con_fprintf(f,
" -1 compress faster -9 compress better\n" " -1 compress faster -9 compress better\n"
"%s" "%s"
@@ -191,9 +179,9 @@ void show_help(int verbose)
verbose == 0 ? "" : " --best compress best (can be slow for big files)\n", verbose == 0 ? "" : " --best compress best (can be slow for big files)\n",
verbose == 0 ? "more" : "this", verbose == 0 ? "" : "\n"); verbose == 0 ? "more" : "this", verbose == 0 ? "" : "\n");
fg = con_fg(f,FG_YELLOW); fg = con_fg(f, FG_YELLOW);
con_fprintf(f,"Options:\n"); con_fprintf(f, "Options:\n");
fg = con_fg(f,fg); fg = con_fg(f, fg);
con_fprintf(f, con_fprintf(f,
" -q be quiet -v be verbose\n" " -q be quiet -v be verbose\n"
@@ -211,72 +199,72 @@ void show_help(int verbose)
if (verbose > 0) if (verbose > 0)
{ {
fg = con_fg(f,FG_YELLOW); fg = con_fg(f, FG_YELLOW);
con_fprintf(f,"\nCompression tuning options:\n"); con_fprintf(f, "\nCompression tuning options:\n");
fg = con_fg(f,fg); fg = con_fg(f, fg);
con_fprintf(f, con_fprintf(f,
" --lzma try LZMA [slower but tighter than NRV]\n" " --lzma try LZMA [slower but tighter than NRV]\n"
" --brute try all available compression methods & filters [slow]\n" " --brute try all available compression methods & filters [slow]\n"
" --ultra-brute try even more compression variants [very slow]\n" " --ultra-brute try even more compression variants [very slow]\n"
"\n"); "\n");
fg = con_fg(f,FG_YELLOW); fg = con_fg(f, FG_YELLOW);
con_fprintf(f,"Backup options:\n"); con_fprintf(f, "Backup options:\n");
fg = con_fg(f,fg); fg = con_fg(f, fg);
con_fprintf(f, con_fprintf(f,
" -k, --backup keep backup files\n" " -k, --backup keep backup files\n"
" --no-backup no backup files [default]\n" " --no-backup no backup files [default]\n"
"\n"); "\n");
fg = con_fg(f,FG_YELLOW); fg = con_fg(f, FG_YELLOW);
con_fprintf(f,"Overlay options:\n"); con_fprintf(f, "Overlay options:\n");
fg = con_fg(f,fg); fg = con_fg(f, fg);
con_fprintf(f, con_fprintf(f,
" --overlay=copy copy any extra data attached to the file [default]\n" " --overlay=copy copy any extra data attached to the file [default]\n"
" --overlay=strip strip any extra data attached to the file [DANGEROUS]\n" " --overlay=strip strip any extra data attached to the file [DANGEROUS]\n"
" --overlay=skip don't compress a file with an overlay\n" " --overlay=skip don't compress a file with an overlay\n"
"\n"); "\n");
fg = con_fg(f,FG_YELLOW); fg = con_fg(f, FG_YELLOW);
con_fprintf(f,"Options for djgpp2/coff:\n"); con_fprintf(f, "Options for djgpp2/coff:\n");
fg = con_fg(f,fg); fg = con_fg(f, fg);
con_fprintf(f, con_fprintf(f,
" --coff produce COFF output [default: EXE]\n" " --coff produce COFF output [default: EXE]\n"
"\n"); "\n");
fg = con_fg(f,FG_YELLOW); fg = con_fg(f, FG_YELLOW);
con_fprintf(f,"Options for dos/com:\n"); con_fprintf(f, "Options for dos/com:\n");
fg = con_fg(f,fg); fg = con_fg(f, fg);
con_fprintf(f, con_fprintf(f,
" --8086 make compressed com work on any 8086\n" " --8086 make compressed com work on any 8086\n"
"\n"); "\n");
fg = con_fg(f,FG_YELLOW); fg = con_fg(f, FG_YELLOW);
con_fprintf(f,"Options for dos/exe:\n"); con_fprintf(f, "Options for dos/exe:\n");
fg = con_fg(f,fg); fg = con_fg(f, fg);
con_fprintf(f, con_fprintf(f,
" --8086 make compressed exe work on any 8086\n" " --8086 make compressed exe work on any 8086\n"
" --no-reloc put no relocations in to the exe header\n" " --no-reloc put no relocations in to the exe header\n"
"\n"); "\n");
fg = con_fg(f,FG_YELLOW); fg = con_fg(f, FG_YELLOW);
con_fprintf(f,"Options for dos/sys:\n"); con_fprintf(f, "Options for dos/sys:\n");
fg = con_fg(f,fg); fg = con_fg(f, fg);
con_fprintf(f, con_fprintf(f,
" --8086 make compressed sys work on any 8086\n" " --8086 make compressed sys work on any 8086\n"
"\n"); "\n");
fg = con_fg(f,FG_YELLOW); fg = con_fg(f, FG_YELLOW);
con_fprintf(f,"Options for ps1/exe:\n"); con_fprintf(f, "Options for ps1/exe:\n");
fg = con_fg(f,fg); fg = con_fg(f, fg);
con_fprintf(f, con_fprintf(f,
" --8-bit uses 8 bit size compression [default: 32 bit]\n" " --8-bit uses 8 bit size compression [default: 32 bit]\n"
" --8mib-ram 8 megabyte memory limit [default: 2 MiB]\n" " --8mib-ram 8 megabyte memory limit [default: 2 MiB]\n"
" --boot-only disables client/host transfer compatibility\n" " --boot-only disables client/host transfer compatibility\n"
" --no-align don't align to 2048 bytes [enables: --console-run]\n" " --no-align don't align to 2048 bytes [enables: --console-run]\n"
"\n"); "\n");
fg = con_fg(f,FG_YELLOW); fg = con_fg(f, FG_YELLOW);
con_fprintf(f,"Options for watcom/le:\n"); con_fprintf(f, "Options for watcom/le:\n");
fg = con_fg(f,fg); fg = con_fg(f, fg);
con_fprintf(f, con_fprintf(f,
" --le produce LE output [default: EXE]\n" " --le produce LE output [default: EXE]\n"
"\n"); "\n");
fg = con_fg(f,FG_YELLOW); fg = con_fg(f, FG_YELLOW);
con_fprintf(f,"Options for win32/pe, win64/pe, rtm32/pe & arm/pe:\n"); con_fprintf(f, "Options for win32/pe, win64/pe & rtm32/pe:\n");
fg = con_fg(f,fg); fg = con_fg(f, fg);
con_fprintf(f, con_fprintf(f,
" --compress-exports=0 do not compress the export section\n" " --compress-exports=0 do not compress the export section\n"
" --compress-exports=1 compress the export section [default]\n" " --compress-exports=1 compress the export section [default]\n"
@@ -289,35 +277,32 @@ void show_help(int verbose)
" --strip-relocs=0 do not strip relocations\n" " --strip-relocs=0 do not strip relocations\n"
" --strip-relocs=1 strip relocations [default]\n" " --strip-relocs=1 strip relocations [default]\n"
"\n"); "\n");
fg = con_fg(f,FG_YELLOW); fg = con_fg(f, FG_YELLOW);
con_fprintf(f,"Options for linux/elf:\n"); con_fprintf(f, "Options for linux/elf:\n");
fg = con_fg(f,fg); fg = con_fg(f, fg);
con_fprintf(f, con_fprintf(f,
" --preserve-build-id copy .gnu.note.build-id to compressed output\n" " --preserve-build-id copy .gnu.note.build-id to compressed output\n"
"\n"); "\n");
} }
// clang-format on
con_fprintf(f, "file.. executables to (de)compress\n"); con_fprintf(f, "file.. executables to (de)compress\n");
if (verbose > 0) if (verbose > 0) {
{ fg = con_fg(f, FG_YELLOW);
fg = con_fg(f,FG_YELLOW); con_fprintf(f, "\nThis version supports:\n");
con_fprintf(f,"\nThis version supports:\n"); fg = con_fg(f, fg);
fg = con_fg(f,fg); list_all_packers(f, verbose);
show_all_packers(f, verbose); } else {
} con_fprintf(f, "\nType '%s --help' for more detailed help.\n", progname);
else
{
con_fprintf(f,"\nType '%s --help' for more detailed help.\n", progname);
} }
con_fprintf(f,"\nUPX comes with ABSOLUTELY NO WARRANTY; for details visit https://upx.github.io\n" con_fprintf(f, "\nUPX comes with ABSOLUTELY NO WARRANTY; "
// "\nUPX comes with ABSOLUTELY NO WARRANTY; for details type 'upx -L'.\n" "for details visit https://upx.github.io\n");
"");
#if DEBUG || TESTING #if DEBUG || TESTING
fg = con_fg(f,FG_RED); fg = con_fg(f, FG_RED);
con_fprintf(f,"\nWARNING: this version is compiled with" con_fprintf(f, "\nWARNING: this version is compiled with"
#if DEBUG #if DEBUG
" -DDEBUG" " -DDEBUG"
#endif #endif
@@ -325,23 +310,22 @@ void show_help(int verbose)
" -DTESTING" " -DTESTING"
#endif #endif
"\n"); "\n");
fg = con_fg(f,fg); fg = con_fg(f, fg);
#endif #endif
UNUSED(fg); UNUSED(fg);
} }
/************************************************************************* /*************************************************************************
// // license
**************************************************************************/ **************************************************************************/
void show_license(void) void show_license(void) {
{
FILE *f = con_term; FILE *f = con_term;
show_head(); show_header();
// clang-format off
con_fprintf(f, con_fprintf(f,
" This program may be used freely, and you are welcome to\n" " This program may be used freely, and you are welcome to\n"
" redistribute it under certain conditions.\n" " redistribute it under certain conditions.\n"
@@ -356,87 +340,88 @@ void show_license(void)
" If not, visit one of the following pages:\n" " If not, visit one of the following pages:\n"
"\n" "\n"
); );
int fg = con_fg(f,FG_CYAN); int fg = con_fg(f, FG_CYAN);
con_fprintf(f, con_fprintf(f,
" https://upx.github.io\n" " https://upx.github.io\n"
" https://www.oberhumer.com/opensource/upx/\n" " https://www.oberhumer.com/opensource/upx/\n"
); );
(void)con_fg(f,FG_ORANGE); (void) con_fg(f, FG_ORANGE);
con_fprintf(f, con_fprintf(f,
"\n" "\n"
" Markus F.X.J. Oberhumer Laszlo Molnar\n" " Markus F.X.J. Oberhumer Laszlo Molnar\n"
" <markus@oberhumer.com> <ezerotven+github@gmail.com>\n" " <markus@oberhumer.com> <ezerotven+github@gmail.com>\n"
); );
fg = con_fg(f,fg); // clang-format on
fg = con_fg(f, fg);
UNUSED(fg); UNUSED(fg);
} }
/************************************************************************* /*************************************************************************
// // version
**************************************************************************/ **************************************************************************/
void show_version(bool one_line) void show_version(bool one_line) {
{ FILE *f = stdout;
FILE *fp = stdout;
const char *v; const char *v;
#if defined(UPX_VERSION_GIT_DESCRIBE) #if defined(UPX_VERSION_GIT_DESCRIBE)
fprintf(fp, "upx %s\n", UPX_VERSION_GIT_DESCRIBE); fprintf(f, "upx %s\n", UPX_VERSION_GIT_DESCRIBE);
#elif defined(UPX_VERSION_GITREV) #elif defined(UPX_VERSION_GITREV)
fprintf(fp, "upx %s\n", UPX_VERSION_STRING "-git-" UPX_VERSION_GITREV); fprintf(f, "upx %s\n", UPX_VERSION_STRING "-git-" UPX_VERSION_GITREV);
#else #else
fprintf(fp, "upx %s\n", UPX_VERSION_STRING); fprintf(f, "upx %s\n", UPX_VERSION_STRING);
#endif #endif
if (one_line) if (one_line)
return; return;
#if (WITH_NRV) #if (WITH_NRV)
v = upx_nrv_version_string(); v = upx_nrv_version_string();
if (v != nullptr && v[0]) if (v != nullptr && v[0])
fprintf(fp, "NRV data compression library %s\n", v); fprintf(f, "NRV data compression library %s\n", v);
#endif #endif
#if (WITH_UCL) #if (WITH_UCL)
v = upx_ucl_version_string(); v = upx_ucl_version_string();
if (v != nullptr && v[0]) if (v != nullptr && v[0])
fprintf(fp, "UCL data compression library %s\n", v); fprintf(f, "UCL data compression library %s\n", v);
#endif #endif
#if (WITH_ZLIB) #if (WITH_ZLIB)
v = upx_zlib_version_string(); v = upx_zlib_version_string();
if (v != nullptr && v[0]) if (v != nullptr && v[0])
fprintf(fp, "zlib data compression library %s\n", v); fprintf(f, "zlib data compression library %s\n", v);
#endif #endif
#if (WITH_LZMA) #if (WITH_LZMA)
v = upx_lzma_version_string(); v = upx_lzma_version_string();
if (v != nullptr && v[0]) if (v != nullptr && v[0])
fprintf(fp, "LZMA SDK version %s\n", v); fprintf(f, "LZMA SDK version %s\n", v);
#endif #endif
#if (WITH_ZSTD) #if (WITH_ZSTD)
v = upx_zstd_version_string(); v = upx_zstd_version_string();
if (v != nullptr && v[0]) if (v != nullptr && v[0])
fprintf(fp, "zstd data compression library %s\n", v); fprintf(f, "zstd data compression library %s\n", v);
#endif #endif
#if !defined(DOCTEST_CONFIG_DISABLE) #if !defined(DOCTEST_CONFIG_DISABLE)
fprintf(fp, "doctest C++ testing framework version %s\n", DOCTEST_VERSION_STR); fprintf(f, "doctest C++ testing framework version %s\n", DOCTEST_VERSION_STR);
#endif #endif
fprintf(fp, "Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer\n"); // clang-format off
fprintf(fp, "Copyright (C) 1996-2023 Laszlo Molnar\n"); fprintf(f, "Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer\n");
fprintf(fp, "Copyright (C) 2000-2023 John F. Reiser\n"); fprintf(f, "Copyright (C) 1996-2023 Laszlo Molnar\n");
fprintf(fp, "Copyright (C) 2002-2023 Jens Medoch\n"); fprintf(f, "Copyright (C) 2000-2023 John F. Reiser\n");
fprintf(f, "Copyright (C) 2002-2023 Jens Medoch\n");
#if (WITH_ZLIB) #if (WITH_ZLIB)
fprintf(fp, "Copyright (C) 1995" "-2022 Jean-loup Gailly and Mark Adler\n"); fprintf(f, "Copyright (C) 1995" "-2023 Jean-loup Gailly and Mark Adler\n");
#endif #endif
#if (WITH_LZMA) #if (WITH_LZMA)
fprintf(fp, "Copyright (C) 1999" "-2006 Igor Pavlov\n"); fprintf(f, "Copyright (C) 1999" "-2006 Igor Pavlov\n");
#endif #endif
#if (WITH_ZSTD) #if (WITH_ZSTD)
// see vendor/zstd/LICENSE; main author is Yann Collet // see vendor/zstd/LICENSE; main author is Yann Collet
fprintf(fp, "Copyright (C) 2015" "-2023 Meta Platforms, Inc. and affiliates\n"); fprintf(f, "Copyright (C) 2015" "-2023 Meta Platforms, Inc. and affiliates\n");
#endif #endif
#if !defined(DOCTEST_CONFIG_DISABLE) #if !defined(DOCTEST_CONFIG_DISABLE)
fprintf(fp, "Copyright (C) 2016" "-2021 Viktor Kirilov\n"); fprintf(f, "Copyright (C) 2016" "-2023 Viktor Kirilov\n");
#endif #endif
fprintf(fp, "UPX comes with ABSOLUTELY NO WARRANTY; for details type '%s -L'.\n", progname); fprintf(f, "UPX comes with ABSOLUTELY NO WARRANTY; for details type '%s -L'.\n", progname);
// clang-format on
} }
/* vim:set ts=4 sw=4 et: */ /* vim:set ts=4 sw=4 et: */
+22 -16
View File
@@ -27,18 +27,17 @@
#include "conf.h" #include "conf.h"
#include "file.h" #include "file.h"
#include "util/membuffer.h"
#include "lefile.h" #include "lefile.h"
LeFile::LeFile(InputFile *f) : fif(f), fof(nullptr), le_offset(0), exe_offset(0) { LeFile::LeFile(InputFile *f) noexcept : fif(f) {
COMPILE_TIME_ASSERT(sizeof(le_header_t) == 196) COMPILE_TIME_ASSERT(sizeof(le_header_t) == 196)
COMPILE_TIME_ASSERT(sizeof(le_object_table_entry_t) == 24) COMPILE_TIME_ASSERT(sizeof(le_object_table_entry_t) == 24)
COMPILE_TIME_ASSERT(sizeof(le_pagemap_entry_t) == 4) COMPILE_TIME_ASSERT(sizeof(le_pagemap_entry_t) == 4)
memset(&ih, 0, sizeof ih); mem_clear(&ih);
memset(&oh, 0, sizeof oh); mem_clear(&oh);
} }
LeFile::~LeFile() { LeFile::~LeFile() noexcept {
delete[] iobject_table; delete[] iobject_table;
delete[] oobject_table; delete[] oobject_table;
delete[] ifpage_table; delete[] ifpage_table;
@@ -89,7 +88,7 @@ void LeFile::writePageMap() {
void LeFile::readResidentNames() { void LeFile::readResidentNames() {
sores_names = ih.entry_table_offset - ih.resident_names_offset; sores_names = ih.entry_table_offset - ih.resident_names_offset;
ires_names = New(upx_byte, sores_names); ires_names = New(byte, sores_names);
fif->seek(le_offset + ih.resident_names_offset, SEEK_SET); fif->seek(le_offset + ih.resident_names_offset, SEEK_SET);
fif->readx(ires_names, sores_names); fif->readx(ires_names, sores_names);
} }
@@ -102,7 +101,7 @@ void LeFile::writeResidentNames() {
void LeFile::readEntryTable() { void LeFile::readEntryTable() {
soentries = ih.fixup_page_table_offset - ih.entry_table_offset; soentries = ih.fixup_page_table_offset - ih.entry_table_offset;
fif->seek(le_offset + ih.entry_table_offset, SEEK_SET); fif->seek(le_offset + ih.entry_table_offset, SEEK_SET);
ientries = New(upx_byte, soentries); ientries = New(byte, soentries);
fif->readx(ientries, soentries); fif->readx(ientries, soentries);
} }
@@ -125,7 +124,7 @@ void LeFile::writeFixupPageTable() {
void LeFile::readFixups() { void LeFile::readFixups() {
sofixups = get_le32(ifpage_table + pages) - get_le32(ifpage_table); sofixups = get_le32(ifpage_table + pages) - get_le32(ifpage_table);
ifixups = New(upx_byte, sofixups); ifixups = New(byte, sofixups);
fif->seek(le_offset + ih.fixup_record_table_offset, SEEK_SET); fif->seek(le_offset + ih.fixup_record_table_offset, SEEK_SET);
fif->readx(ifixups, sofixups); fif->readx(ifixups, sofixups);
} }
@@ -146,9 +145,11 @@ unsigned LeFile::getImageSize() const {
void LeFile::readImage() { void LeFile::readImage() {
soimage = pages * mps; soimage = pages * mps;
if (!soimage) // late detection, but protect against .alloc(0)
throwCantPack("no soimage");
mb_iimage.alloc(soimage); mb_iimage.alloc(soimage);
mb_iimage.clear(); mb_iimage.clear();
iimage = mb_iimage; iimage = mb_iimage; // => now a SPAN_S
unsigned ic, jc; unsigned ic, jc;
for (ic = jc = 0; ic < pages; ic++) { for (ic = jc = 0; ic < pages; ic++) {
@@ -157,7 +158,7 @@ void LeFile::readImage() {
(ipm_entries[ic].m * 0x100 + ipm_entries[ic].l - 1) * mps, (ipm_entries[ic].m * 0x100 + ipm_entries[ic].l - 1) * mps,
SEEK_SET); SEEK_SET);
auto bytes = ic != pages - 1 ? mps : ih.bytes_on_last_page; auto bytes = ic != pages - 1 ? mps : ih.bytes_on_last_page;
fif->readx(raw_bytes(iimage + jc, bytes), bytes); fif->readx(iimage + jc, bytes);
} }
jc += mps; jc += mps;
} }
@@ -165,13 +166,13 @@ void LeFile::readImage() {
void LeFile::writeImage() { void LeFile::writeImage() {
if (fof && oimage != nullptr) if (fof && oimage != nullptr)
fof->write(raw_bytes(oimage, soimage), soimage); fof->write(oimage, soimage);
} }
void LeFile::readNonResidentNames() { void LeFile::readNonResidentNames() {
if (ih.non_resident_name_table_length) { if (ih.non_resident_name_table_length) {
sononres_names = ih.non_resident_name_table_length; sononres_names = ih.non_resident_name_table_length;
inonres_names = New(upx_byte, sononres_names); inonres_names = New(byte, sononres_names);
fif->seek(exe_offset + ih.non_resident_name_table_offset, SEEK_SET); fif->seek(exe_offset + ih.non_resident_name_table_offset, SEEK_SET);
fif->readx(inonres_names, sononres_names); fif->readx(inonres_names, sononres_names);
} }
@@ -184,7 +185,7 @@ void LeFile::writeNonResidentNames() {
bool LeFile::readFileHeader() { bool LeFile::readFileHeader() {
#define H(x) get_le16(header + 2 * (x)) #define H(x) get_le16(header + 2 * (x))
upx_byte header[0x40]; byte header[0x40];
le_offset = exe_offset = 0; le_offset = exe_offset = 0;
int ic; int ic;
@@ -217,6 +218,11 @@ bool LeFile::readFileHeader() {
return false; return false;
fif->seek(le_offset, SEEK_SET); fif->seek(le_offset, SEEK_SET);
fif->readx(&ih, sizeof(ih)); fif->readx(&ih, sizeof(ih));
if (mps < 512 || mps > 2097152 || (mps & (mps - 1)) != 0)
throwCantPack("file header invalid page size");
if (ih.bytes_on_last_page > mps || pages == 0)
throwCantPack("bad file header");
(void) mem_size(mps, pages); // assert size
return true; return true;
#undef H #undef H
} }
@@ -224,7 +230,7 @@ bool LeFile::readFileHeader() {
void LeFile::writeFile(OutputFile *f, bool le) { void LeFile::writeFile(OutputFile *f, bool le) {
fof = f; fof = f;
memcpy(&oh, &ih, memcpy(&oh, &ih,
(char *) &oh.memory_pages - (char *) &oh); // copy some members of the orig. header (charptr) &oh.memory_pages - (charptr) &oh); // copy some members of the orig. header
oh.memory_page_size = mps; oh.memory_page_size = mps;
oh.object_table_offset = sizeof(oh); oh.object_table_offset = sizeof(oh);
oh.object_table_entries = soobject_table; oh.object_table_entries = soobject_table;
@@ -257,12 +263,12 @@ void LeFile::writeFile(OutputFile *f, bool le) {
void LeFile::countFixups(unsigned *counts) const { void LeFile::countFixups(unsigned *counts) const {
const unsigned o = objects; const unsigned o = objects;
memset(counts, 0, sizeof(unsigned) * (o + 2)); memset(counts, 0, mem_size(sizeof(unsigned), o + 2));
// counts[0..objects-1] - # of 32-bit offset relocations in for that objects // counts[0..objects-1] - # of 32-bit offset relocations in for that objects
// counts[objects] - # of selector fixups // counts[objects] - # of selector fixups
// counts[objects+1] - # of self-relative fixups // counts[objects+1] - # of self-relative fixups
const upx_byte *fix = ifixups; const byte *fix = ifixups;
const unsigned sfixups = get_le32(ifpage_table + pages); const unsigned sfixups = get_le32(ifpage_table + pages);
unsigned ll; unsigned ll;
+46 -46
View File
@@ -26,8 +26,8 @@
*/ */
#pragma once #pragma once
#ifndef UPX_LEFILE_H__
#define UPX_LEFILE_H__ 1 #include "util/membuffer.h"
class InputFile; class InputFile;
class OutputFile; class OutputFile;
@@ -38,8 +38,8 @@ class OutputFile;
class LeFile { class LeFile {
protected: protected:
LeFile(InputFile *); explicit LeFile(InputFile *) noexcept;
virtual ~LeFile(); virtual ~LeFile() noexcept;
virtual bool readFileHeader(); virtual bool readFileHeader();
virtual void writeFile(OutputFile *, bool); virtual void writeFile(OutputFile *, bool);
@@ -49,13 +49,13 @@ protected:
struct alignas(1) le_header_t { struct alignas(1) le_header_t {
// 0x00 // 0x00
char _[2]; // signature: 'LE' || 'LX' byte _[2]; // signature: 'LE' || 'LX'
char byte_order; // 0 little endian byte byte_order; // 0 little endian
char word_order; // 0 little endian byte word_order; // 0 little endian
LE32 exe_format_level; // 0 LE32 exe_format_level; // 0
LE16 cpu_type; // 1->286..4->586 LE16 cpu_type; // 1->286..4->586
LE16 target_os; // 1->OS2 LE16 target_os; // 1->OS2
char _0[4]; // module_version = 0 byte _0[4]; // module_version = 0
// 0x10 // 0x10
LE32 module_type; // 0x200->compatible with PM windowing LE32 module_type; // 0x200->compatible with PM windowing
LE32 memory_pages; LE32 memory_pages;
@@ -68,21 +68,21 @@ protected:
LE32 bytes_on_last_page; LE32 bytes_on_last_page;
// 0x30 // 0x30
LE32 fixup_size; LE32 fixup_size;
char _1[4]; // fixup_checksum = 0 byte _1[4]; // fixup_checksum = 0
LE32 loader_size; LE32 loader_size;
char _2[4]; // loader_checksum = 0 byte _2[4]; // loader_checksum = 0
// 0x40 // 0x40
LE32 object_table_offset; LE32 object_table_offset;
LE32 object_table_entries; LE32 object_table_entries;
LE32 object_pagemap_offset; LE32 object_pagemap_offset;
LE32 object_iterate_data_map_offset; LE32 object_iterate_data_map_offset;
// 0x50 // 0x50
char _3[4]; // resource_offset byte _3[4]; // resource_offset
LE32 resource_entries; LE32 resource_entries;
LE32 resident_names_offset; LE32 resident_names_offset;
LE32 entry_table_offset; LE32 entry_table_offset;
// 0x60 // 0x60
char _4[4]; // module_directives_table_offset = 0 byte _4[4]; // module_directives_table_offset = 0
LE32 module_directives_entries; LE32 module_directives_entries;
LE32 fixup_page_table_offset; LE32 fixup_page_table_offset;
LE32 fixup_record_table_offset; LE32 fixup_record_table_offset;
@@ -90,17 +90,17 @@ protected:
LE32 imported_modules_name_table_offset; LE32 imported_modules_name_table_offset;
LE32 imported_modules_count; LE32 imported_modules_count;
LE32 imported_procedures_name_table_offset; LE32 imported_procedures_name_table_offset;
char _5[4]; // per_page_checksum_table_offset = 0 byte _5[4]; // per_page_checksum_table_offset = 0
// 0x80 // 0x80
LE32 data_pages_offset; LE32 data_pages_offset;
char _6[4]; // preload_page_count = 0 byte _6[4]; // preload_page_count = 0
LE32 non_resident_name_table_offset; LE32 non_resident_name_table_offset;
LE32 non_resident_name_table_length; LE32 non_resident_name_table_length;
// 0x90 // 0x90
char _7[4]; // non_resident_names_checksum byte _7[4]; // non_resident_names_checksum
LE32 automatic_data_object; LE32 automatic_data_object;
#if 1 #if 1
char _8[44]; byte _8[44];
#else #else
LE32 debug_info_offset; LE32 debug_info_offset;
LE32 debug_info_length; LE32 debug_info_length;
@@ -108,7 +108,7 @@ protected:
LE32 preload_instance_pages; LE32 preload_instance_pages;
LE32 demand_instance_pages; LE32 demand_instance_pages;
LE32 extra_heap_alloc; LE32 extra_heap_alloc;
char reserved[12]; byte reserved[12];
LE32 versioninfo; LE32 versioninfo;
LE32 unknown; LE32 unknown;
// 0xC0 // 0xC0
@@ -127,10 +127,10 @@ protected:
}; };
struct alignas(1) le_pagemap_entry_t { struct alignas(1) le_pagemap_entry_t {
unsigned char h; byte h;
unsigned char m; byte m;
unsigned char l; byte l;
unsigned char type; // 0x00-legal;0x40-iterated;0x80-invalid;0xC0-zeroed byte type; // 0x00-legal;0x40-iterated;0x80-invalid;0xC0-zeroed
}; };
virtual void readObjectTable(); virtual void readObjectTable();
@@ -187,8 +187,8 @@ protected:
InputFile *fif = nullptr; InputFile *fif = nullptr;
OutputFile *fof = nullptr; OutputFile *fof = nullptr;
unsigned le_offset; unsigned le_offset = 0;
unsigned exe_offset; unsigned exe_offset = 0;
le_header_t ih; le_header_t ih;
le_header_t oh; le_header_t oh;
@@ -199,34 +199,34 @@ protected:
unsigned *ofpage_table = nullptr; unsigned *ofpage_table = nullptr;
le_pagemap_entry_t *ipm_entries = nullptr; le_pagemap_entry_t *ipm_entries = nullptr;
le_pagemap_entry_t *opm_entries = nullptr; le_pagemap_entry_t *opm_entries = nullptr;
upx_byte *ires_names = nullptr; byte *ires_names = nullptr;
upx_byte *ores_names = nullptr; byte *ores_names = nullptr;
upx_byte *ifixups = nullptr; byte *ifixups = nullptr;
upx_byte *ofixups = nullptr; byte *ofixups = nullptr;
upx_byte *inonres_names = nullptr; byte *inonres_names = nullptr;
upx_byte *ononres_names = nullptr; byte *ononres_names = nullptr;
MemBuffer mb_iimage; MemBuffer mb_iimage;
SPAN_0(upx_byte) iimage = nullptr; SPAN_0(byte) iimage = nullptr;
MemBuffer mb_oimage; MemBuffer mb_oimage;
SPAN_0(upx_byte) oimage = nullptr; SPAN_0(byte) oimage = nullptr;
upx_byte *ientries = nullptr; byte *ientries = nullptr;
upx_byte *oentries = nullptr; byte *oentries = nullptr;
unsigned soobject_table; unsigned soobject_table = 0;
unsigned sofpage_table; unsigned sofpage_table = 0;
unsigned sopm_entries; unsigned sopm_entries = 0;
unsigned sores_names; unsigned sores_names = 0;
unsigned sofixups; unsigned sofixups = 0;
unsigned sononres_names; unsigned sononres_names = 0;
unsigned soimage; unsigned soimage = 0;
unsigned soentries; unsigned soentries = 0;
private: private:
// disable copy and assignment // disable copy and move
LeFile(const LeFile &) = delete; LeFile(const LeFile &) DELETED_FUNCTION;
LeFile &operator=(const LeFile &) = delete; LeFile &operator=(const LeFile &) DELETED_FUNCTION;
LeFile(LeFile &&) noexcept DELETED_FUNCTION;
LeFile &operator=(LeFile &&) noexcept DELETED_FUNCTION;
}; };
#endif /* already included */
/* vim:set ts=4 sw=4 et: */ /* vim:set ts=4 sw=4 et: */
+36 -38
View File
@@ -28,7 +28,7 @@
#include "conf.h" #include "conf.h"
#include "linker.h" #include "linker.h"
static unsigned hex(unsigned char c) { return (c & 0xf) + (c > '9' ? 9 : 0); } static unsigned hex(uchar c) { return (c & 0xf) + (c > '9' ? 9 : 0); }
static bool update_capacity(unsigned size, unsigned *capacity) { static bool update_capacity(unsigned size, unsigned *capacity) {
if (size < *capacity) if (size < *capacity)
@@ -62,12 +62,14 @@ ElfLinker::Section::Section(const char *n, const void *i, unsigned s, unsigned a
assert(name != nullptr); assert(name != nullptr);
input = malloc(s + 1); input = malloc(s + 1);
assert(input != nullptr); assert(input != nullptr);
if (s != 0) if (s != 0) {
assert(i != nullptr);
memcpy(input, i, s); memcpy(input, i, s);
}
((char *) input)[s] = 0; ((char *) input)[s] = 0;
} }
ElfLinker::Section::~Section() { ElfLinker::Section::~Section() noexcept {
free(name); free(name);
free(input); free(input);
} }
@@ -83,7 +85,7 @@ ElfLinker::Symbol::Symbol(const char *n, Section *s, upx_uint64_t o)
assert(section != nullptr); assert(section != nullptr);
} }
ElfLinker::Symbol::~Symbol() { free(name); } ElfLinker::Symbol::~Symbol() noexcept { free(name); }
/************************************************************************* /*************************************************************************
// Relocation // Relocation
@@ -99,13 +101,9 @@ ElfLinker::Relocation::Relocation(const Section *s, unsigned o, const char *t, c
// ElfLinker // ElfLinker
**************************************************************************/ **************************************************************************/
ElfLinker::ElfLinker() ElfLinker::ElfLinker(const N_BELE_RTP::AbstractPolicy *b) noexcept : bele(b) {}
: bele(&N_BELE_RTP::le_policy), input(nullptr), output(nullptr), head(nullptr), tail(nullptr),
sections(nullptr), symbols(nullptr), relocations(nullptr), nsections(0),
nsections_capacity(0), nsymbols(0), nsymbols_capacity(0), nrelocations(0),
nrelocations_capacity(0), reloc_done(false) {}
ElfLinker::~ElfLinker() { ElfLinker::~ElfLinker() noexcept {
delete[] input; delete[] input;
delete[] output; delete[] output;
@@ -122,7 +120,7 @@ ElfLinker::~ElfLinker() {
} }
void ElfLinker::init(const void *pdata_v, int plen, unsigned pxtra) { void ElfLinker::init(const void *pdata_v, int plen, unsigned pxtra) {
const upx_byte *pdata = (const upx_byte *) pdata_v; const byte *pdata = (const byte *) pdata_v;
if (plen >= 16 && memcmp(pdata, "UPX#", 4) == 0) { if (plen >= 16 && memcmp(pdata, "UPX#", 4) == 0) {
// decompress pre-compressed stub-loader // decompress pre-compressed stub-loader
int method; int method;
@@ -142,7 +140,7 @@ void ElfLinker::init(const void *pdata_v, int plen, unsigned pxtra) {
} }
assert((unsigned) plen < u_len); assert((unsigned) plen < u_len);
inputlen = u_len; inputlen = u_len;
input = new upx_byte[inputlen + 1]; input = New(byte, inputlen + 1);
unsigned new_len = u_len; unsigned new_len = u_len;
int r = upx_decompress(pdata, c_len, input, &new_len, method, nullptr); int r = upx_decompress(pdata, c_len, input, &new_len, method, nullptr);
if (r == UPX_E_OUT_OF_MEMORY) if (r == UPX_E_OUT_OF_MEMORY)
@@ -151,7 +149,7 @@ void ElfLinker::init(const void *pdata_v, int plen, unsigned pxtra) {
throwBadLoader(); throwBadLoader();
} else { } else {
inputlen = plen; inputlen = plen;
input = new upx_byte[inputlen + 1]; input = New(byte, inputlen + 1);
if (inputlen) if (inputlen)
memcpy(input, pdata, inputlen); memcpy(input, pdata, inputlen);
} }
@@ -159,7 +157,7 @@ void ElfLinker::init(const void *pdata_v, int plen, unsigned pxtra) {
output_capacity = (inputlen ? (inputlen + pxtra) : 0x4000); output_capacity = (inputlen ? (inputlen + pxtra) : 0x4000);
assert(output_capacity <= (1 << 16)); // LE16 l_info.l_size assert(output_capacity <= (1 << 16)); // LE16 l_info.l_size
output = new upx_byte[output_capacity]; output = New(byte, output_capacity);
outputlen = 0; outputlen = 0;
NO_printf("\nElfLinker::init %d @%p\n", output_capacity, output); NO_printf("\nElfLinker::init %d @%p\n", output_capacity, output);
@@ -197,7 +195,7 @@ void ElfLinker::preprocessSections(char *start, char const *end) {
unsigned offset, size, align; unsigned offset, size, align;
char name[1024]; char name[1024];
if (sscanf(start, "%*d %1023s %x %*d %*d %x 2**%d", name, &size, &offset, &align) == 4) { if (sscanf(start, "%*d %1023s %x %*x %*x %x 2**%d", name, &size, &offset, &align) == 4) {
char *n = strstr(start, name); char *n = strstr(start, name);
n[strlen(name)] = 0; n[strlen(name)] = 0;
addSection(n, input + offset, size, align); addSection(n, input + offset, size, align);
@@ -404,8 +402,8 @@ int ElfLinker::addLoader(const char *sname) {
assert(tail); assert(tail);
assert(tail != section); assert(tail != section);
// .p2align must be < 32 // .p2align must be < 32
unsigned const v = ~0u << section->p2align; const unsigned v = ~0u << section->p2align;
if (unsigned const l = ~v & (0u - (unsigned) (tail->offset + tail->size))) { if (const unsigned l = ~v & (0u - (unsigned) (tail->offset + tail->size))) {
alignCode(l); alignCode(l);
tail->size += l; tail->size += l;
} }
@@ -456,7 +454,7 @@ int ElfLinker::getSectionSize(const char *sname) const {
return section->size; return section->size;
} }
upx_byte *ElfLinker::getLoader(int *llen) const { byte *ElfLinker::getLoader(int *llen) const {
if (llen) if (llen)
*llen = outputlen; *llen = outputlen;
return output; return output;
@@ -482,7 +480,7 @@ void ElfLinker::relocate() {
else { else {
value = rel->value->section->offset + rel->value->offset + rel->add; value = rel->value->section->offset + rel->value->offset + rel->add;
} }
upx_byte *location = rel->section->output + rel->offset; byte *location = rel->section->output + rel->offset;
NO_printf("%-28s %-28s %-10s %#16llx %#16llx\n", rel->section->name, rel->value->name, NO_printf("%-28s %-28s %-10s %#16llx %#16llx\n", rel->section->name, rel->value->name,
rel->type, (long long) value, rel->type, (long long) value,
(long long) value - rel->section->offset - rel->offset); (long long) value - rel->section->offset - rel->offset);
@@ -548,23 +546,23 @@ upx_uint64_t ElfLinker::getSymbolOffset(const char *name) const {
return symbol->section->offset + symbol->offset; return symbol->section->offset + symbol->offset;
} }
void ElfLinker::alignWithByte(unsigned len, unsigned char b) { void ElfLinker::alignWithByte(unsigned len, byte b) {
memset(output + outputlen, b, len); memset(output + outputlen, b, len);
outputlen += len; outputlen += len;
} }
void ElfLinker::relocate1(const Relocation *rel, upx_byte *, upx_uint64_t, const char *) { void ElfLinker::relocate1(const Relocation *rel, byte *, upx_uint64_t, const char *) {
internal_error("unknown relocation type '%s\n'", rel->type); internal_error("unknown relocation type '%s\n'", rel->type);
} }
/************************************************************************* /*************************************************************************
// ElfLinker arch subclasses // ElfLinker arch subclasses
// FIXME: add more displacment overflow checks // FIXME: add more displacement overflow checks
// FIXME: add support for our special "ignore_reloc_overflow" section // FIXME: add support for our special "ignore_reloc_overflow" section
**************************************************************************/ **************************************************************************/
#if 0 // FIXME #if 0 // FIXME
static void check8(const Relocation *rel, const upx_byte *location, int v, int d) static void check8(const Relocation *rel, const byte *location, int v, int d)
{ {
if (v < -128 || v > 127) if (v < -128 || v > 127)
internal_error("value out of range (%d) in reloc %s:%x\n", internal_error("value out of range (%d) in reloc %s:%x\n",
@@ -575,7 +573,7 @@ static void check8(const Relocation *rel, const upx_byte *location, int v, int d
} }
#endif #endif
void ElfLinkerAMD64::relocate1(const Relocation *rel, upx_byte *location, upx_uint64_t value, void ElfLinkerAMD64::relocate1(const Relocation *rel, byte *location, upx_uint64_t value,
const char *type) { const char *type) {
if (strncmp(type, "R_X86_64_", 9)) if (strncmp(type, "R_X86_64_", 9))
return super::relocate1(rel, location, value, type); return super::relocate1(rel, location, value, type);
@@ -608,7 +606,7 @@ void ElfLinkerAMD64::relocate1(const Relocation *rel, upx_byte *location, upx_ui
super::relocate1(rel, location, value, type); super::relocate1(rel, location, value, type);
} }
void ElfLinkerArmBE::relocate1(const Relocation *rel, upx_byte *location, upx_uint64_t value, void ElfLinkerArmBE::relocate1(const Relocation *rel, byte *location, upx_uint64_t value,
const char *type) { const char *type) {
if (!strcmp(type, "R_ARM_PC24") || !strcmp(type, "R_ARM_CALL") || if (!strcmp(type, "R_ARM_PC24") || !strcmp(type, "R_ARM_CALL") ||
!strcmp(type, "R_ARM_JUMP24")) { !strcmp(type, "R_ARM_JUMP24")) {
@@ -633,7 +631,7 @@ void ElfLinkerArmBE::relocate1(const Relocation *rel, upx_byte *location, upx_ui
super::relocate1(rel, location, value, type); super::relocate1(rel, location, value, type);
} }
void ElfLinkerArmLE::relocate1(const Relocation *rel, upx_byte *location, upx_uint64_t value, void ElfLinkerArmLE::relocate1(const Relocation *rel, byte *location, upx_uint64_t value,
const char *type) { const char *type) {
if (!strcmp(type, "R_ARM_PC24") || !strcmp(type, "R_ARM_CALL") || if (!strcmp(type, "R_ARM_PC24") || !strcmp(type, "R_ARM_CALL") ||
!strcmp(type, "R_ARM_JUMP24")) { !strcmp(type, "R_ARM_JUMP24")) {
@@ -658,7 +656,7 @@ void ElfLinkerArmLE::relocate1(const Relocation *rel, upx_byte *location, upx_ui
super::relocate1(rel, location, value, type); super::relocate1(rel, location, value, type);
} }
void ElfLinkerArm64LE::relocate1(const Relocation *rel, upx_byte *location, upx_uint64_t value, void ElfLinkerArm64LE::relocate1(const Relocation *rel, byte *location, upx_uint64_t value,
const char *type) { const char *type) {
if (strncmp(type, "R_AARCH64_", 10)) if (strncmp(type, "R_AARCH64_", 10))
return super::relocate1(rel, location, value, type); return super::relocate1(rel, location, value, type);
@@ -706,7 +704,7 @@ void ElfLinkerM68k::alignCode(unsigned len) {
outputlen += len; outputlen += len;
} }
void ElfLinkerM68k::relocate1(const Relocation *rel, upx_byte *location, upx_uint64_t value, void ElfLinkerM68k::relocate1(const Relocation *rel, byte *location, upx_uint64_t value,
const char *type) { const char *type) {
if (strncmp(type, "R_68K_", 6)) if (strncmp(type, "R_68K_", 6))
return super::relocate1(rel, location, value, type); return super::relocate1(rel, location, value, type);
@@ -726,7 +724,7 @@ void ElfLinkerM68k::relocate1(const Relocation *rel, upx_byte *location, upx_uin
super::relocate1(rel, location, value, type); super::relocate1(rel, location, value, type);
} }
void ElfLinkerMipsBE::relocate1(const Relocation *rel, upx_byte *location, upx_uint64_t value, void ElfLinkerMipsBE::relocate1(const Relocation *rel, byte *location, upx_uint64_t value,
const char *type) { const char *type) {
#define MIPS_HI(a) (((a) >> 16) + (((a) &0x8000) >> 15)) #define MIPS_HI(a) (((a) >> 16) + (((a) &0x8000) >> 15))
#define MIPS_LO(a) ((a) &0xffff) #define MIPS_LO(a) ((a) &0xffff)
@@ -753,7 +751,7 @@ void ElfLinkerMipsBE::relocate1(const Relocation *rel, upx_byte *location, upx_u
#undef MIPS_PC26 #undef MIPS_PC26
} }
void ElfLinkerMipsLE::relocate1(const Relocation *rel, upx_byte *location, upx_uint64_t value, void ElfLinkerMipsLE::relocate1(const Relocation *rel, byte *location, upx_uint64_t value,
const char *type) { const char *type) {
#define MIPS_HI(a) (((a) >> 16) + (((a) &0x8000) >> 15)) #define MIPS_HI(a) (((a) >> 16) + (((a) &0x8000) >> 15))
#define MIPS_LO(a) ((a) &0xffff) #define MIPS_LO(a) ((a) &0xffff)
@@ -780,7 +778,7 @@ void ElfLinkerMipsLE::relocate1(const Relocation *rel, upx_byte *location, upx_u
#undef MIPS_PC26 #undef MIPS_PC26
} }
void ElfLinkerPpc32::relocate1(const Relocation *rel, upx_byte *location, upx_uint64_t value, void ElfLinkerPpc32::relocate1(const Relocation *rel, byte *location, upx_uint64_t value,
const char *type) { const char *type) {
if (strncmp(type, "R_PPC_", 6)) if (strncmp(type, "R_PPC_", 6))
return super::relocate1(rel, location, value, type); return super::relocate1(rel, location, value, type);
@@ -801,19 +799,19 @@ void ElfLinkerPpc32::relocate1(const Relocation *rel, upx_byte *location, upx_ui
// Note that original (*location).displ is ignored. // Note that original (*location).displ is ignored.
if (strcmp(type, "24") == 0) { if (strcmp(type, "24") == 0) {
if (3 & value) if (3 & value)
internal_error("unaligned word diplacement"); internal_error("unaligned word displacement");
// FIXME: displacment overflow? // FIXME: displacement overflow?
set_be32(location, (0xfc000003 & get_be32(location)) + (0x03fffffc & value)); set_be32(location, (0xfc000003 & get_be32(location)) + (0x03fffffc & value));
} else if (strcmp(type, "14") == 0) { } else if (strcmp(type, "14") == 0) {
if (3 & value) if (3 & value)
internal_error("unaligned word diplacement"); internal_error("unaligned word displacement");
// FIXME: displacment overflow? // FIXME: displacement overflow?
set_be32(location, (0xffff0003 & get_be32(location)) + (0x0000fffc & value)); set_be32(location, (0xffff0003 & get_be32(location)) + (0x0000fffc & value));
} else } else
super::relocate1(rel, location, value, type); super::relocate1(rel, location, value, type);
} }
void ElfLinkerPpc64le::relocate1(const Relocation *rel, upx_byte *location, upx_uint64_t value, void ElfLinkerPpc64le::relocate1(const Relocation *rel, byte *location, upx_uint64_t value,
const char *type) { const char *type) {
if (!strcmp(type, "R_PPC64_ADDR64")) { if (!strcmp(type, "R_PPC64_ADDR64")) {
set_le64(location, get_le64(location) + value); set_le64(location, get_le64(location) + value);
@@ -856,7 +854,7 @@ void ElfLinkerPpc64le::relocate1(const Relocation *rel, upx_byte *location, upx_
super::relocate1(rel, location, value, type); super::relocate1(rel, location, value, type);
} }
void ElfLinkerPpc64::relocate1(const Relocation *rel, upx_byte *location, upx_uint64_t value, void ElfLinkerPpc64::relocate1(const Relocation *rel, byte *location, upx_uint64_t value,
const char *type) { const char *type) {
if (!strcmp(type, "R_PPC64_ADDR32")) { if (!strcmp(type, "R_PPC64_ADDR32")) {
set_be32(location, get_be32(location) + value); set_be32(location, get_be32(location) + value);
@@ -886,7 +884,7 @@ void ElfLinkerPpc64::relocate1(const Relocation *rel, upx_byte *location, upx_ui
super::relocate1(rel, location, value, type); super::relocate1(rel, location, value, type);
} }
void ElfLinkerX86::relocate1(const Relocation *rel, upx_byte *location, upx_uint64_t value, void ElfLinkerX86::relocate1(const Relocation *rel, byte *location, upx_uint64_t value,
const char *type) { const char *type) {
if (strncmp(type, "R_386_", 6)) if (strncmp(type, "R_386_", 6))
return super::relocate1(rel, location, value, type); return super::relocate1(rel, location, value, type);
+53 -87
View File
@@ -25,8 +25,7 @@
<markus@oberhumer.com> <ezerotven+github@gmail.com> <markus@oberhumer.com> <ezerotven+github@gmail.com>
*/ */
#ifndef __UPX_LINKER_H #pragma once
#define __UPX_LINKER_H 1
/************************************************************************* /*************************************************************************
// ElfLinker // ElfLinker
@@ -36,15 +35,15 @@ class ElfLinker : private noncopyable {
friend class Packer; friend class Packer;
public: public:
const N_BELE_RTP::AbstractPolicy *bele = nullptr; // target endianness const N_BELE_RTP::AbstractPolicy *const bele; // target endianness
protected: protected:
struct Section; struct Section;
struct Symbol; struct Symbol;
struct Relocation; struct Relocation;
upx_byte *input = nullptr; byte *input = nullptr;
int inputlen = 0; int inputlen = 0;
upx_byte *output = nullptr; byte *output = nullptr;
int outputlen = 0; int outputlen = 0;
unsigned output_capacity = 0; unsigned output_capacity = 0;
@@ -76,8 +75,8 @@ protected:
const char *symbol, upx_uint64_t add); const char *symbol, upx_uint64_t add);
public: public:
ElfLinker(); explicit ElfLinker(const N_BELE_RTP::AbstractPolicy *b = &N_BELE_RTP::le_policy) noexcept;
virtual ~ElfLinker(); virtual ~ElfLinker() noexcept;
void init(const void *pdata, int plen, unsigned pxtra = 0); void init(const void *pdata, int plen, unsigned pxtra = 0);
// virtual void setLoaderAlignOffset(int phase); // virtual void setLoaderAlignOffset(int phase);
@@ -91,14 +90,14 @@ public:
Section *addSection(const char *sname, const void *sdata, int slen, unsigned p2align); Section *addSection(const char *sname, const void *sdata, int slen, unsigned p2align);
int getSection(const char *sname, int *slen = nullptr) const; int getSection(const char *sname, int *slen = nullptr) const;
int getSectionSize(const char *sname) const; int getSectionSize(const char *sname) const;
upx_byte *getLoader(int *llen = nullptr) const; byte *getLoader(int *llen = nullptr) const;
void defineSymbol(const char *name, upx_uint64_t value); void defineSymbol(const char *name, upx_uint64_t value);
upx_uint64_t getSymbolOffset(const char *) const; upx_uint64_t getSymbolOffset(const char *) const;
void dumpSymbol(const Symbol *, unsigned flags, FILE *fp) const; void dumpSymbol(const Symbol *, unsigned flags, FILE *fp) const;
void dumpSymbols(unsigned flags = 0, FILE *fp = nullptr) const; void dumpSymbols(unsigned flags = 0, FILE *fp = nullptr) const;
void alignWithByte(unsigned len, unsigned char b); void alignWithByte(unsigned len, byte b);
virtual void alignCode(unsigned len) { alignWithByte(len, 0); } virtual void alignCode(unsigned len) { alignWithByte(len, 0); }
virtual void alignData(unsigned len) { alignWithByte(len, 0); } virtual void alignData(unsigned len) { alignWithByte(len, 0); }
@@ -111,29 +110,21 @@ public:
protected: protected:
void relocate(); void relocate();
virtual void relocate1(const Relocation *, upx_byte *location, upx_uint64_t value, virtual void relocate1(const Relocation *, byte *location, upx_uint64_t value,
const char *type); const char *type);
// target endianness abstraction
unsigned get_te16(const void *p) const { return bele->get16(p); }
unsigned get_te32(const void *p) const { return bele->get32(p); }
upx_uint64_t get_te64(const void *p) const { return bele->get64(p); }
void set_te16(void *p, unsigned v) const { bele->set16(p, v); }
void set_te32(void *p, unsigned v) const { bele->set32(p, v); }
void set_te64(void *p, upx_uint64_t v) const { bele->set64(p, v); }
}; };
struct ElfLinker::Section : private noncopyable { struct ElfLinker::Section : private noncopyable {
char *name = nullptr; char *name = nullptr;
void *input = nullptr; void *input = nullptr;
upx_byte *output = nullptr; byte *output = nullptr;
unsigned size = 0; unsigned size = 0;
upx_uint64_t offset = 0; upx_uint64_t offset = 0;
unsigned p2align = 0; // log2 unsigned p2align = 0; // log2
Section *next = nullptr; Section *next = nullptr;
Section(const char *n, const void *i, unsigned s, unsigned a = 0); explicit Section(const char *n, const void *i, unsigned s, unsigned a = 0);
~Section(); ~Section() noexcept;
}; };
struct ElfLinker::Symbol : private noncopyable { struct ElfLinker::Symbol : private noncopyable {
@@ -141,8 +132,8 @@ struct ElfLinker::Symbol : private noncopyable {
Section *section = nullptr; Section *section = nullptr;
upx_uint64_t offset = 0; upx_uint64_t offset = 0;
Symbol(const char *n, Section *s, upx_uint64_t o); explicit Symbol(const char *n, Section *s, upx_uint64_t o);
~Symbol(); ~Symbol() noexcept;
}; };
struct ElfLinker::Relocation : private noncopyable { struct ElfLinker::Relocation : private noncopyable {
@@ -152,128 +143,103 @@ struct ElfLinker::Relocation : private noncopyable {
const Symbol *value = nullptr; const Symbol *value = nullptr;
upx_uint64_t add; // used in .rela relocations upx_uint64_t add; // used in .rela relocations
Relocation(const Section *s, unsigned o, const char *t, const Symbol *v, upx_uint64_t a); explicit Relocation(const Section *s, unsigned o, const char *t, const Symbol *v,
upx_uint64_t a);
~Relocation() noexcept {}
}; };
/************************************************************************* /*************************************************************************
// ElfLinker arch subclasses // ElfLinker arch subclasses
**************************************************************************/ **************************************************************************/
class ElfLinkerAMD64 : public ElfLinker { class ElfLinkerAMD64 /*not_final*/ : public ElfLinker {
typedef ElfLinker super; typedef ElfLinker super;
protected: protected:
virtual void alignCode(unsigned len) override { alignWithByte(len, 0x90); } virtual void alignCode(unsigned len) override { alignWithByte(len, 0x90); }
virtual void relocate1(const Relocation *, upx_byte *location, upx_uint64_t value, virtual void relocate1(const Relocation *, byte *location, upx_uint64_t value,
const char *type) override;
};
class ElfLinkerARM64 final : public ElfLinker {
typedef ElfLinker super;
protected:
virtual void alignCode(unsigned len) override { alignWithByte(len, 0x90); }
virtual void relocate1(const Relocation *, upx_byte *location, upx_uint64_t value,
const char *type) override;
};
class ElfLinkerArmBE final : public ElfLinker {
typedef ElfLinker super;
public:
ElfLinkerArmBE() { bele = &N_BELE_RTP::be_policy; }
protected:
virtual void relocate1(const Relocation *, upx_byte *location, upx_uint64_t value,
const char *type) override;
};
class ElfLinkerArmLE final : public ElfLinker {
typedef ElfLinker super;
protected:
virtual void relocate1(const Relocation *, upx_byte *location, upx_uint64_t value,
const char *type) override; const char *type) override;
}; };
class ElfLinkerArm64LE final : public ElfLinker { class ElfLinkerArm64LE final : public ElfLinker {
typedef ElfLinker super; typedef ElfLinker super;
protected: protected:
virtual void relocate1(const Relocation *, upx_byte *location, upx_uint64_t value, virtual void relocate1(const Relocation *, byte *location, upx_uint64_t value,
const char *type) override;
};
class ElfLinkerArmBE final : public ElfLinker {
typedef ElfLinker super;
public:
explicit ElfLinkerArmBE() noexcept : super(&N_BELE_RTP::be_policy) {}
protected:
virtual void relocate1(const Relocation *, byte *location, upx_uint64_t value,
const char *type) override;
};
class ElfLinkerArmLE final : public ElfLinker {
typedef ElfLinker super;
protected:
virtual void relocate1(const Relocation *, byte *location, upx_uint64_t value,
const char *type) override; const char *type) override;
}; };
class ElfLinkerM68k final : public ElfLinker { class ElfLinkerM68k final : public ElfLinker {
typedef ElfLinker super; typedef ElfLinker super;
public: public:
ElfLinkerM68k() { bele = &N_BELE_RTP::be_policy; } explicit ElfLinkerM68k() noexcept : super(&N_BELE_RTP::be_policy) {}
protected: protected:
virtual void alignCode(unsigned len) override; virtual void alignCode(unsigned len) override;
virtual void relocate1(const Relocation *, upx_byte *location, upx_uint64_t value, virtual void relocate1(const Relocation *, byte *location, upx_uint64_t value,
const char *type) override; const char *type) override;
}; };
class ElfLinkerMipsBE final : public ElfLinker { class ElfLinkerMipsBE final : public ElfLinker {
typedef ElfLinker super; typedef ElfLinker super;
public: public:
ElfLinkerMipsBE() { bele = &N_BELE_RTP::be_policy; } explicit ElfLinkerMipsBE() noexcept : super(&N_BELE_RTP::be_policy) {}
protected: protected:
virtual void relocate1(const Relocation *, upx_byte *location, upx_uint64_t value, virtual void relocate1(const Relocation *, byte *location, upx_uint64_t value,
const char *type) override; const char *type) override;
}; };
class ElfLinkerMipsLE final : public ElfLinker { class ElfLinkerMipsLE final : public ElfLinker {
typedef ElfLinker super; typedef ElfLinker super;
protected: protected:
virtual void relocate1(const Relocation *, upx_byte *location, upx_uint64_t value, virtual void relocate1(const Relocation *, byte *location, upx_uint64_t value,
const char *type) override; const char *type) override;
}; };
class ElfLinkerPpc32 final : public ElfLinker { class ElfLinkerPpc32 final : public ElfLinker {
typedef ElfLinker super; typedef ElfLinker super;
public: public:
ElfLinkerPpc32() { bele = &N_BELE_RTP::be_policy; } explicit ElfLinkerPpc32() noexcept : super(&N_BELE_RTP::be_policy) {}
protected: protected:
virtual void relocate1(const Relocation *, upx_byte *location, upx_uint64_t value, virtual void relocate1(const Relocation *, byte *location, upx_uint64_t value,
const char *type) override;
};
class ElfLinkerPpc64le final : public ElfLinker {
typedef ElfLinker super;
protected:
virtual void relocate1(const Relocation *, upx_byte *location, upx_uint64_t value,
const char *type) override; const char *type) override;
}; };
class ElfLinkerPpc64 final : public ElfLinker { class ElfLinkerPpc64 final : public ElfLinker {
typedef ElfLinker super; typedef ElfLinker super;
public: public:
ElfLinkerPpc64() { bele = &N_BELE_RTP::be_policy; } explicit ElfLinkerPpc64() noexcept : super(&N_BELE_RTP::be_policy) {}
protected: protected:
virtual void relocate1(const Relocation *, upx_byte *location, upx_uint64_t value, virtual void relocate1(const Relocation *, byte *location, upx_uint64_t value,
const char *type) override;
};
class ElfLinkerPpc64le final : public ElfLinker {
typedef ElfLinker super;
protected:
virtual void relocate1(const Relocation *, byte *location, upx_uint64_t value,
const char *type) override; const char *type) override;
}; };
class ElfLinkerX86 final : public ElfLinker { class ElfLinkerX86 final : public ElfLinker {
typedef ElfLinker super; typedef ElfLinker super;
protected: protected:
virtual void alignCode(unsigned len) override { alignWithByte(len, 0x90); } virtual void alignCode(unsigned len) override { alignWithByte(len, 0x90); }
virtual void relocate1(const Relocation *, upx_byte *location, upx_uint64_t value, virtual void relocate1(const Relocation *, byte *location, upx_uint64_t value,
const char *type) override; const char *type) override;
}; };
#endif /* already included */
/* vim:set ts=4 sw=4 et: */ /* vim:set ts=4 sw=4 et: */
+48 -51
View File
@@ -28,9 +28,8 @@
// main entry, mostly boring stuff; see work.cpp for actual action // main entry, mostly boring stuff; see work.cpp for actual action
#include "conf.h" #include "conf.h"
#include "file.h" #include "packer.h" // Packer::isValidCompressionMethod()
#include "packer.h" #include "p_elf.h" // ELFOSABI_xxx
#include "p_elf.h"
#include "compress/compress.h" // upx_ucl_init() #include "compress/compress.h" // upx_ucl_init()
/************************************************************************* /*************************************************************************
@@ -42,7 +41,7 @@
#endif #endif
static const char *argv0 = ""; static const char *argv0 = "";
const char *progname = ""; const char *progname = "upx";
static acc_getopt_t mfx_getopt; static acc_getopt_t mfx_getopt;
#define mfx_optarg mfx_getopt.optarg #define mfx_optarg mfx_getopt.optarg
@@ -88,8 +87,9 @@ static void do_exit(void) {
static bool set_eec(int ec, int *eec) { static bool set_eec(int ec, int *eec) {
if (ec == EXIT_FATAL) { if (ec == EXIT_FATAL) {
*eec = EXIT_ERROR; *eec = EXIT_ERROR;
return 1; return true;
} else if (ec < 0 || ec == EXIT_ERROR) { }
if (ec < 0 || ec == EXIT_ERROR) {
*eec = EXIT_ERROR; *eec = EXIT_ERROR;
} else if (ec == EXIT_WARN) { } else if (ec == EXIT_WARN) {
if (!opt->ignorewarn) if (!opt->ignorewarn)
@@ -100,7 +100,7 @@ static bool set_eec(int ec, int *eec) {
} else { } else {
assert(0); assert(0);
} }
return 0; return false;
} }
bool main_set_exit_code(int ec) { return set_eec(ec, &exit_code); } bool main_set_exit_code(int ec) { return set_eec(ec, &exit_code); }
@@ -119,16 +119,6 @@ __acc_static_noinline void e_usage(void) {
e_exit(EXIT_USAGE); e_exit(EXIT_USAGE);
} }
#if 0 // UNUSED
static void e_memory(void)
{
show_head();
fflush(con_term);
fprintf(stderr,"%s: out of memory\n", argv0);
e_exit(EXIT_MEMORY);
}
#endif // UNUSED
static void e_method(int m, int l) { static void e_method(int m, int l) {
fflush(con_term); fflush(con_term);
fprintf(stderr, "%s: illegal method option -- %d/%d\n", argv0, m, l); fprintf(stderr, "%s: illegal method option -- %d/%d\n", argv0, m, l);
@@ -159,22 +149,13 @@ static void e_envopt(const char *n) {
} }
#endif /* defined(OPTIONS_VAR) */ #endif /* defined(OPTIONS_VAR) */
#if 0 // UNUSED
static void __acc_cdecl_sighandler e_sighandler(int signum)
{
UNUSED(signum);
e_exit(EXIT_FATAL);
}
#endif // UNUSED
/************************************************************************* /*************************************************************************
// check options // check options
**************************************************************************/ **************************************************************************/
static void check_not_both(bool e1, bool e2, const char *c1, const char *c2) { static void check_not_both(bool e1, bool e2, const char *c1, const char *c2) {
if (e1 && e2) { if (e1 && e2) {
fprintf(stderr, "%s: ", argv0); fprintf(stderr, "%s: cannot use both '%s' and '%s'\n", argv0, c1, c2);
fprintf(stderr, "cannot use both '%s' and '%s'\n", c1, c2);
e_usage(); e_usage();
} }
} }
@@ -317,9 +298,9 @@ static char *prepare_shortopts(char *buf, const char *n, const struct mfx_option
template <class T> template <class T>
static int getoptvar(T *var, const T min_value, const T max_value, const char *arg_fatal) { static int getoptvar(T *var, const T min_value, const T max_value, const char *arg_fatal) {
const char *p = mfx_optarg; const char *p = mfx_optarg;
char *endptr; char *endptr = nullptr;
int r = 0; int r = 0;
long n; long long n;
T v; T v;
if (!p || !p[0]) { if (!p || !p[0]) {
@@ -329,20 +310,16 @@ static int getoptvar(T *var, const T min_value, const T max_value, const char *a
// avoid interpretation as octal value // avoid interpretation as octal value
while (p[0] == '0' && isdigit(p[1])) while (p[0] == '0' && isdigit(p[1]))
p++; p++;
n = strtol(p, &endptr, 0); n = strtoll(p, &endptr, 0);
if (*endptr != '\0') { if (*endptr != '\0') {
r = -2; r = -2;
goto error; goto error;
} }
v = (T) n; v = (T) n;
if (v < min_value) { if ((long long) v != n || v < min_value || v > max_value) {
r = -3; r = -3;
goto error; goto error;
} }
if (v > max_value) {
r = -4;
goto error;
}
*var = v; *var = v;
goto done; goto done;
error: error:
@@ -521,6 +498,12 @@ static int do_option(int optc, const char *arg) {
case 545: case 545:
opt->debug.disable_random_id = true; opt->debug.disable_random_id = true;
break; break;
case 546:
opt->debug.use_random_method = true;
break;
case 547:
opt->debug.use_random_filter = true;
break;
// misc // misc
case 512: case 512:
@@ -626,7 +609,7 @@ static int do_option(int optc, const char *arg) {
opt->backup = 1; opt->backup = 1;
break; break;
case 541: case 541:
if (opt->backup != 1) // do not overide '--backup' if (opt->backup != 1) // do not override '--backup'
opt->backup = 0; opt->backup = 0;
break; break;
// overlay // overlay
@@ -652,22 +635,22 @@ static int do_option(int optc, const char *arg) {
// CPU // CPU
case 560: case 560:
if (mfx_optarg && strcmp(mfx_optarg, "8086") == 0) if (mfx_optarg && strcmp(mfx_optarg, "8086") == 0)
opt->cpu = opt->CPU_8086; opt->cpu_x86 = opt->CPU_8086;
else if (mfx_optarg && strcmp(mfx_optarg, "386") == 0) else if (mfx_optarg && strcmp(mfx_optarg, "386") == 0)
opt->cpu = opt->CPU_386; opt->cpu_x86 = opt->CPU_386;
else if (mfx_optarg && strcmp(mfx_optarg, "486") == 0) else if (mfx_optarg && strcmp(mfx_optarg, "486") == 0)
opt->cpu = opt->CPU_486; opt->cpu_x86 = opt->CPU_486;
else else
e_optarg(arg); e_optarg(arg);
break; break;
case 561: case 561:
opt->cpu = opt->CPU_8086; opt->cpu_x86 = opt->CPU_8086;
break; break;
case 563: case 563:
opt->cpu = opt->CPU_386; opt->cpu_x86 = opt->CPU_386;
break; break;
case 564: case 564:
opt->cpu = opt->CPU_486; opt->cpu_x86 = opt->CPU_486;
break; break;
// //
case 600: case 600:
@@ -832,7 +815,9 @@ int main_get_options(int argc, char **argv) {
{"dump-stub-loader", 0x31, N, 544}, // for internal debugging {"dump-stub-loader", 0x31, N, 544}, // for internal debugging
{"fake-stub-version", 0x31, N, 542}, // for internal debugging {"fake-stub-version", 0x31, N, 542}, // for internal debugging
{"fake-stub-year", 0x31, N, 543}, // for internal debugging {"fake-stub-year", 0x31, N, 543}, // for internal debugging
{"disable-random-id", 0x10, N, 545}, // for internal debugging {"disable-random-id", 0x90, N, 545}, // for internal debugging
{"debug-use-random-method", 0x90, N, 546}, // for internal debugging
{"debug-use-random-filter", 0x90, N, 547}, // for internal debugging
// backup options // backup options
{"backup", 0x10, N, 'k'}, {"backup", 0x10, N, 'k'},
@@ -974,11 +959,10 @@ int main_get_options(int argc, char **argv) {
int optc, longind; int optc, longind;
char shortopts[256]; char shortopts[256];
prepare_shortopts(shortopts, "123456789hH?V", longopts), prepare_shortopts(shortopts, "123456789hH?V", longopts);
acc_getopt_init(&mfx_getopt, 1, argc, argv); acc_getopt_init(&mfx_getopt, 1, argc, argv);
mfx_getopt.progname = progname; mfx_getopt.progname = progname;
mfx_getopt.opterr = handle_opterr; mfx_getopt.opterr = handle_opterr;
opt->o_unix.osabi0 = Elf32_Ehdr::ELFOSABI_LINUX;
while ((optc = acc_getopt(&mfx_getopt, shortopts, longopts, &longind)) >= 0) { while ((optc = acc_getopt(&mfx_getopt, shortopts, longopts, &longind)) >= 0) {
if (do_option(optc, argv[mfx_optind - 1]) != 0) if (do_option(optc, argv[mfx_optind - 1]) != 0)
e_usage(); e_usage();
@@ -1008,7 +992,7 @@ void main_get_envoptions() {
{"verbose", 0, N, 'v'}, // verbose mode {"verbose", 0, N, 'v'}, // verbose mode
// debug options // debug options
{"disable-random-id", 0x10, N, 545}, // for internal debugging {"disable-random-id", 0x90, N, 545}, // for internal debugging
// backup options // backup options
{"backup", 0x10, N, 'k'}, {"backup", 0x10, N, 'k'},
@@ -1088,7 +1072,7 @@ void main_get_envoptions() {
/* alloc temp argv */ /* alloc temp argv */
if (targc > 1) if (targc > 1)
targv = (const char **) calloc(targc + 1, sizeof(char *)); targv = (const char **) upx_calloc(targc + 1, sizeof(char *));
if (targv == nullptr) { if (targv == nullptr) {
free(env); free(env);
return; return;
@@ -1174,7 +1158,7 @@ int upx_main(int argc, char *argv[]) {
if (dt_res == 2) if (dt_res == 2)
fprintf(stderr, "%s: doctest requested program exit; Stop.\n", argv0); fprintf(stderr, "%s: doctest requested program exit; Stop.\n", argv0);
else else
fprintf(stderr, "%s: internal error: doctest failed\n", argv0); fprintf(stderr, "%s: internal error: doctest check failed\n", argv0);
e_exit(EXIT_INIT); e_exit(EXIT_INIT);
} }
@@ -1188,7 +1172,7 @@ int upx_main(int argc, char *argv[]) {
char *p; char *p;
bool allupper = true; bool allupper = true;
for (p = prog; *p; p++) for (p = prog; *p; p++)
if (islower((unsigned char) *p)) if (islower((uchar) *p))
allupper = false; allupper = false;
if (allupper) if (allupper)
fn_strlwr(prog); fn_strlwr(prog);
@@ -1256,7 +1240,7 @@ int upx_main(int argc, char *argv[]) {
e_exit(EXIT_OK); e_exit(EXIT_OK);
break; break;
default: default:
/* ??? */ assert(false); // should not happen
break; break;
} }
@@ -1333,10 +1317,23 @@ int __acc_cdecl_main main(int argc, char *argv[]) {
// srand((int) time(nullptr)); // srand((int) time(nullptr));
srand((int) clock()); srand((int) clock());
// info: main() is implicitly "noexcept", so we need a try block
#if 0
int r = upx_main(argc, argv); int r = upx_main(argc, argv);
#else
int r;
try {
r = upx_main(argc, argv);
} catch (const Throwable &e) {
printErr("unknown", e);
std::terminate();
} catch (...) {
std::terminate();
}
#endif
#if 0 && defined(__GLIBC__) #if 0 && defined(__GLIBC__)
//malloc_stats(); // malloc_stats();
#endif #endif
return r; return r;
} }
+21 -3
View File
@@ -27,7 +27,7 @@
#ifndef __ACC_H_INCLUDED #ifndef __ACC_H_INCLUDED
#define __ACC_H_INCLUDED 1 #define __ACC_H_INCLUDED 1
#define ACC_VERSION 20230104L #define ACC_VERSION 20230625L
#if defined(__CYGWIN32__) && !defined(__CYGWIN__) #if defined(__CYGWIN32__) && !defined(__CYGWIN__)
# define __CYGWIN__ __CYGWIN32__ # define __CYGWIN__ __CYGWIN32__
#endif #endif
@@ -2563,11 +2563,11 @@ ACC_COMPILE_TIME_ASSERT_HEADER(ACC_SIZEOF_PTRDIFF_T == sizeof(ptrdiff_t))
# define ACC_ABI_LITTLE_ENDIAN 1 # define ACC_ABI_LITTLE_ENDIAN 1
#elif (ACC_ARCH_ALPHA) && (ACC_ARCH_CRAY_MPP) #elif (ACC_ARCH_ALPHA) && (ACC_ARCH_CRAY_MPP)
# define ACC_ABI_BIG_ENDIAN 1 # define ACC_ABI_BIG_ENDIAN 1
#elif (ACC_ARCH_IA64) && (ACC_OS_POSIX_LINUX || ACC_OS_WIN64) #elif (ACC_ARCH_IA64) && (ACC_OS_POSIX_FREEBSD || ACC_OS_POSIX_LINUX || ACC_OS_WIN64)
# define ACC_ABI_LITTLE_ENDIAN 1 # define ACC_ABI_LITTLE_ENDIAN 1
#elif (ACC_ARCH_ALPHA || ACC_ARCH_AMD64 || ACC_ARCH_BLACKFIN || ACC_ARCH_CRIS || ACC_ARCH_I086 || ACC_ARCH_I386 || ACC_ARCH_MSP430 || ACC_ARCH_RISCV) #elif (ACC_ARCH_ALPHA || ACC_ARCH_AMD64 || ACC_ARCH_BLACKFIN || ACC_ARCH_CRIS || ACC_ARCH_I086 || ACC_ARCH_I386 || ACC_ARCH_MSP430 || ACC_ARCH_RISCV)
# define ACC_ABI_LITTLE_ENDIAN 1 # define ACC_ABI_LITTLE_ENDIAN 1
#elif (ACC_ARCH_AVR32 || ACC_ARCH_M68K || ACC_ARCH_S390 || ACC_ARCH_SPU) #elif (ACC_ARCH_AVR32 || ACC_ARCH_M68K || ACC_ARCH_S390 || ACC_ARCH_SPARC || ACC_ARCH_SPU)
# define ACC_ABI_BIG_ENDIAN 1 # define ACC_ABI_BIG_ENDIAN 1
#elif 1 && defined(__IAR_SYSTEMS_ICC__) && defined(__LITTLE_ENDIAN__) #elif 1 && defined(__IAR_SYSTEMS_ICC__) && defined(__LITTLE_ENDIAN__)
# if (__LITTLE_ENDIAN__ == 1) # if (__LITTLE_ENDIAN__ == 1)
@@ -3637,13 +3637,23 @@ ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(acc_int_fast64_t) == sizeof(acc_uint_fast6
# define HAVE_MEMSET 1 # define HAVE_MEMSET 1
# define HAVE_SETJMP 1 # define HAVE_SETJMP 1
#else #else
#ifndef HAVE_ACCESS
#define HAVE_ACCESS 1 #define HAVE_ACCESS 1
#endif
#ifndef HAVE_ALLOCA
#define HAVE_ALLOCA 1 #define HAVE_ALLOCA 1
#endif
#ifndef HAVE_ATEXIT
#define HAVE_ATEXIT 1 #define HAVE_ATEXIT 1
#endif
#define HAVE_ATOI 1 #define HAVE_ATOI 1
#define HAVE_ATOL 1 #define HAVE_ATOL 1
#ifndef HAVE_CHMOD
#define HAVE_CHMOD 1 #define HAVE_CHMOD 1
#endif
#ifndef HAVE_CHOWN
#define HAVE_CHOWN 1 #define HAVE_CHOWN 1
#endif
#define HAVE_CTIME 1 #define HAVE_CTIME 1
#define HAVE_DIFFTIME 1 #define HAVE_DIFFTIME 1
#define HAVE_FILENO 1 #define HAVE_FILENO 1
@@ -3653,7 +3663,9 @@ ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(acc_int_fast64_t) == sizeof(acc_uint_fast6
#define HAVE_GMTIME 1 #define HAVE_GMTIME 1
#define HAVE_ISATTY 1 #define HAVE_ISATTY 1
#define HAVE_LOCALTIME 1 #define HAVE_LOCALTIME 1
#ifndef HAVE_LONGJMP
#define HAVE_LONGJMP 1 #define HAVE_LONGJMP 1
#endif
#define HAVE_LSTAT 1 #define HAVE_LSTAT 1
#define HAVE_MEMCMP 1 #define HAVE_MEMCMP 1
#define HAVE_MEMCPY 1 #define HAVE_MEMCPY 1
@@ -3662,10 +3674,16 @@ ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(acc_int_fast64_t) == sizeof(acc_uint_fast6
#define HAVE_MKDIR 1 #define HAVE_MKDIR 1
#define HAVE_MKTIME 1 #define HAVE_MKTIME 1
#define HAVE_QSORT 1 #define HAVE_QSORT 1
#ifndef HAVE_RAISE
#define HAVE_RAISE 1 #define HAVE_RAISE 1
#endif
#define HAVE_RMDIR 1 #define HAVE_RMDIR 1
#ifndef HAVE_SETJMP
#define HAVE_SETJMP 1 #define HAVE_SETJMP 1
#endif
#ifndef HAVE_SIGNAL
#define HAVE_SIGNAL 1 #define HAVE_SIGNAL 1
#endif
#define HAVE_SNPRINTF 1 #define HAVE_SNPRINTF 1
#define HAVE_STAT 1 #define HAVE_STAT 1
#define HAVE_STRCHR 1 #define HAVE_STRCHR 1
+22 -23
View File
@@ -25,18 +25,19 @@
<markus@oberhumer.com> <ezerotven+github@gmail.com> <markus@oberhumer.com> <ezerotven+github@gmail.com>
*/ */
#include "headers.h"
#include <typeinfo> // typeid()
#include "conf.h" #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 ?
**************************************************************************/ **************************************************************************/
static int pr_need_nl = 0; static int pr_need_nl = 0;
void printSetNl(int need_nl) { pr_need_nl = need_nl; } void printSetNl(int need_nl) noexcept { pr_need_nl = need_nl; }
void printClearLine(FILE *f) { void printClearLine(FILE *f) noexcept {
static char clear_line_msg[1 + 79 + 1 + 1]; static char clear_line_msg[1 + 79 + 1 + 1];
if (!clear_line_msg[0]) { if (!clear_line_msg[0]) {
char *msg = clear_line_msg; char *msg = clear_line_msg;
@@ -55,14 +56,14 @@ void printClearLine(FILE *f) {
printSetNl(0); printSetNl(0);
} }
static void pr_print(bool c, const char *msg) { static void pr_print(bool c, const char *msg) noexcept {
if (c && !opt->to_stdout) if (c && !opt->to_stdout)
con_fprintf(stderr, "%s", msg); con_fprintf(stderr, "%s", msg);
else else
fprintf(stderr, "%s", msg); fprintf(stderr, "%s", msg);
} }
static void pr_error(const char *iname, const char *msg, bool is_warning) { static void pr_error(const char *iname, const char *msg, bool is_warning) noexcept {
fflush(stdout); fflush(stdout);
fflush(stderr); fflush(stderr);
char buf[1024]; char buf[1024];
@@ -97,29 +98,29 @@ static void pr_error(const char *iname, const char *msg, bool is_warning) {
UNUSED(fg); UNUSED(fg);
} }
void printErr(const char *iname, const Throwable *e) { void printErr(const char *iname, const Throwable &e) noexcept {
char buf[1024]; char buf[1024];
size_t l; size_t l;
snprintf(buf, sizeof(buf), "%s", prettyName(typeid(*e).name())); snprintf(buf, sizeof(buf), "%s", prettyName(typeid(e).name()));
l = strlen(buf); l = strlen(buf);
if (l < sizeof(buf) && e->getMsg()) 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); l = strlen(buf);
if (l < sizeof(buf) && e->getErrno()) { 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 #if 1
// some compilers (e.g. Borland C++) put a trailing '\n' // some compilers (e.g. Borland C++) put a trailing '\n'
// into strerror() result // into the strerror() result
l = strlen(buf); l = strlen(buf);
while (l-- > 0 && (buf[l] == '\n' || buf[l] == ' ')) while (l-- > 0 && (buf[l] == '\n' || buf[l] == ' '))
buf[l] = 0; buf[l] = 0;
#endif #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, ...) noexcept {
va_list args; va_list args;
char buf[1024]; char buf[1024];
@@ -130,7 +131,7 @@ void printErr(const char *iname, const char *format, ...) {
pr_error(iname, buf, false); pr_error(iname, buf, false);
} }
void printWarn(const char *iname, const char *format, ...) { void printWarn(const char *iname, const char *format, ...) noexcept {
va_list args; va_list args;
char buf[1024]; char buf[1024];
@@ -141,7 +142,7 @@ void printWarn(const char *iname, const char *format, ...) {
pr_error(iname, buf, true); pr_error(iname, buf, true);
} }
void printUnhandledException(const char *iname, const std::exception *e) { void printUnhandledException(const char *iname, const std::exception *e) noexcept {
if (e) if (e)
printErr(iname, "unhandled exception: %s\n", prettyName(e->what())); printErr(iname, "unhandled exception: %s\n", prettyName(e->what()));
else else
@@ -152,7 +153,7 @@ void printUnhandledException(const char *iname, const std::exception *e) {
} }
/************************************************************************* /*************************************************************************
// FIXME: should use colors and a consistent layout here // info
**************************************************************************/ **************************************************************************/
static int info_header = 0; static int info_header = 0;
@@ -200,10 +201,8 @@ void info(const char *format, ...) {
} }
void infoWarning(const char *format, ...) { void infoWarning(const char *format, ...) {
if (opt->info_mode <= 0) { if (opt->info_mode <= 0)
// FIXME - should still print something here
return; return;
}
va_list args; va_list args;
char buf[1024]; char buf[1024];
va_start(args, format); va_start(args, format);
@@ -212,10 +211,10 @@ void infoWarning(const char *format, ...) {
info("[WARNING] %s\n", buf); info("[WARNING] %s\n", buf);
} }
void infoWriting(const char *what, long size) { void infoWriting(const char *what, upx_int64_t size) {
if (opt->info_mode <= 0) if (opt->info_mode <= 0)
return; return;
info("Writing %s: %ld bytes", what, size); info("Writing %s: %lld bytes", what, size);
} }
/* vim:set ts=4 sw=4 et: */ /* vim:set ts=4 sw=4 et: */
+22 -11
View File
@@ -27,16 +27,20 @@
#include "conf.h" #include "conf.h"
static options_t global_options; static Options global_options;
options_t *opt = &global_options; // also see class PackMaster Options *opt = &global_options; // also see class PackMaster
#if WITH_THREADS
std::mutex opt_lock_mutex;
#endif
/************************************************************************* /*************************************************************************
// reset // reset
**************************************************************************/ **************************************************************************/
void options_t::reset() { void Options::reset() noexcept {
options_t *o = this; Options *const o = this;
mem_clear(o, sizeof(*o)); mem_clear(o);
o->crp.reset(); o->crp.reset();
o->cmd = CMD_NONE; o->cmd = CMD_NONE;
@@ -65,7 +69,7 @@ void options_t::reset() {
o->win32_pe.compress_exports = 1; o->win32_pe.compress_exports = 1;
o->win32_pe.compress_icons = 2; o->win32_pe.compress_icons = 2;
o->win32_pe.compress_resources = -1; o->win32_pe.compress_resources = -1;
for (unsigned i = 0; i < TABLESIZE(o->win32_pe.compress_rt); i++) for (size_t i = 0; i < TABLESIZE(o->win32_pe.compress_rt); i++)
o->win32_pe.compress_rt[i] = -1; o->win32_pe.compress_rt[i] = -1;
o->win32_pe.compress_rt[24] = false; // 24 == RT_MANIFEST o->win32_pe.compress_rt[24] = false; // 24 == RT_MANIFEST
o->win32_pe.strip_relocs = -1; o->win32_pe.strip_relocs = -1;
@@ -76,9 +80,13 @@ void options_t::reset() {
// doctest checks // doctest checks
**************************************************************************/ **************************************************************************/
TEST_CASE("options_t::reset") { TEST_CASE("Options::reset") {
options_t local_options; COMPILE_TIME_ASSERT(std::is_standard_layout<Options>::value)
options_t *o = &local_options; COMPILE_TIME_ASSERT(std::is_nothrow_default_constructible<Options>::value)
COMPILE_TIME_ASSERT(std::is_trivially_copyable<Options>::value)
Options local_options;
Options *o = &local_options;
o->reset(); o->reset();
CHECK(o->o_unix.osabi0 == 3); CHECK(o->o_unix.osabi0 == 3);
} }
@@ -89,8 +97,11 @@ static inline void test_options(const char *(&a)[N]) {
} }
TEST_CASE("getopt") { TEST_CASE("getopt") {
options_t *const saved_opt = opt; #if WITH_THREADS
options_t local_options; std::lock_guard<std::mutex> lock(opt_lock_mutex);
#endif
Options *const saved_opt = opt;
Options local_options;
opt = &local_options; opt = &local_options;
opt->reset(); opt->reset();
opt->debug.getopt_throw_instead_of_exit = true; opt->debug.getopt_throw_instead_of_exit = true;
+22 -18
View File
@@ -26,14 +26,20 @@
*/ */
#pragma once #pragma once
#ifndef UPX_OPTIONS_H__
#define UPX_OPTIONS_H__ 1 struct Options;
extern Options *opt; // global options, see class PackMaster for per-file local options
#define options_t Options // old name
#if WITH_THREADS
extern std::mutex opt_lock_mutex;
#endif
/************************************************************************* /*************************************************************************
// globals // command line options
**************************************************************************/ **************************************************************************/
// options - command // main command
enum { enum {
CMD_NONE, CMD_NONE,
CMD_COMPRESS, CMD_COMPRESS,
@@ -46,7 +52,7 @@ enum {
CMD_VERSION, CMD_VERSION,
}; };
struct options_t final { struct Options final {
int cmd; int cmd;
// compression options // compression options
@@ -89,7 +95,9 @@ struct options_t final {
const char *dump_stub_loader; const char *dump_stub_loader;
char fake_stub_version[4 + 1]; // for internal debugging char fake_stub_version[4 + 1]; // for internal debugging
char fake_stub_year[4 + 1]; // for internal debugging char fake_stub_year[4 + 1]; // for internal debugging
bool getopt_throw_instead_of_exit; // for doctest bool getopt_throw_instead_of_exit; // for internal doctest checks
bool use_random_method; // for internal debugging
bool use_random_filter; // for internal debugging
} debug; } debug;
// overlay handling // overlay handling
@@ -97,20 +105,20 @@ struct options_t final {
int overlay; int overlay;
// CRP - Compression Runtime Parameters (undocumented and subject to change) // CRP - Compression Runtime Parameters (undocumented and subject to change)
// see struct XXX_compress_config_t struct {
struct crp_t {
lzma_compress_config_t crp_lzma; lzma_compress_config_t crp_lzma;
ucl_compress_config_t crp_ucl; ucl_compress_config_t crp_ucl;
zlib_compress_config_t crp_zlib; zlib_compress_config_t crp_zlib;
void reset() { zstd_compress_config_t crp_zstd;
void reset() noexcept {
crp_lzma.reset(); crp_lzma.reset();
crp_ucl.reset(); crp_ucl.reset();
crp_zlib.reset(); crp_zlib.reset();
crp_zstd.reset();
} }
}; } crp;
crp_t crp;
// CPU // CPU options for i086/i386
enum { enum {
CPU_DEFAULT = 0, CPU_DEFAULT = 0,
CPU_8086 = 1, CPU_8086 = 1,
@@ -118,7 +126,7 @@ struct options_t final {
CPU_386 = 3, CPU_386 = 3,
CPU_486 = 4, CPU_486 = 4,
}; };
int cpu; int cpu_x86;
// options for various executable formats // options for various executable formats
struct { struct {
@@ -161,11 +169,7 @@ struct options_t final {
const char *keep_resource; const char *keep_resource;
} win32_pe; } win32_pe;
void reset(); void reset() noexcept;
}; };
extern struct options_t *opt;
#endif /* already included */
/* vim:set ts=4 sw=4 et: */ /* vim:set ts=4 sw=4 et: */
+62 -53
View File
@@ -1,4 +1,4 @@
/* p_com.cpp -- /* p_com.cpp -- dos/com executable format
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
@@ -35,23 +35,21 @@
static const CLANG_FORMAT_DUMMY_STATEMENT static const CLANG_FORMAT_DUMMY_STATEMENT
#include "stub/i086-dos16.com.h" #include "stub/i086-dos16.com.h"
// #define TESTING 1
/************************************************************************* /*************************************************************************
// //
**************************************************************************/ **************************************************************************/
Linker *PackCom::newLinker() const { return new ElfLinkerX86(); }
const int *PackCom::getCompressionMethods(int method, int level) const { const int *PackCom::getCompressionMethods(int method, int level) const {
static const int m_nrv2b[] = {M_NRV2B_LE16, M_END}; static const int m_nrv2b[] = {M_NRV2B_LE16, M_END};
#if 0
static const int m_nrv2d[] = { M_NRV2D_LE16, M_END };
#endif
UNUSED(method); UNUSED(method);
UNUSED(level); UNUSED(level);
return m_nrv2b; return m_nrv2b;
} }
const int *PackCom::getFilters() const { const int *PackCom::getFilters() const {
// see class FilterImpl
static const int filters[] = {0x06, 0x03, 0x04, 0x01, 0x05, 0x02, FT_END}; static const int filters[] = {0x06, 0x03, 0x04, 0x01, 0x05, 0x02, FT_END};
return filters; return filters;
} }
@@ -61,19 +59,20 @@ const int *PackCom::getFilters() const {
**************************************************************************/ **************************************************************************/
bool PackCom::canPack() { bool PackCom::canPack() {
unsigned char buf[128]; byte buf[128];
fi->readx(buf, sizeof(buf)); fi->readx(buf, sizeof(buf));
if (memcmp(buf, "MZ", 2) == 0 || memcmp(buf, "ZM", 2) == 0 // .exe if (memcmp(buf, "MZ", 2) == 0 || memcmp(buf, "ZM", 2) == 0) // .exe
|| memcmp(buf, "\xff\xff\xff\xff", 4) == 0) // .sys
return false; return false;
if (!fn_has_ext(fi->getName(), "com")) if (memcmp(buf, "\xff\xff\xff\xff", 4) == 0) // .sys
return false;
if (!fn_has_ext(fi->getName(), "com")) // query file name
return false; return false;
checkAlreadyPacked(buf, sizeof(buf)); checkAlreadyPacked(buf, sizeof(buf));
if (file_size < 1024) if (file_size < 1024)
throwCantPack("file is too small"); throwCantPack("file is too small for dos/com");
if (file_size > 0xFF00) if (file_size > 0xFF00)
throwCantPack("file is too big for dos/com"); throwCantPack("file is too large for dos/com");
return true; return true;
} }
@@ -81,7 +80,50 @@ bool PackCom::canPack() {
// //
**************************************************************************/ **************************************************************************/
void PackCom::patchLoader(OutputFile *fo, upx_byte *loader, int lsize, unsigned calls) { void PackCom::addFilter16(int filter_id) {
assert(filter_id > 0);
assert(isValidFilter(filter_id));
if (filter_id % 3 == 0) {
// clang-format off
addLoader("CALLTR16",
filter_id < 4 ? "CT16SUB0" : "",
filter_id < 4 ? "" : (opt->cpu_x86 == opt->CPU_8086 ? "CT16I086" : "CT16I286,CT16SUB0"),
"CALLTRI2",
getFormat() == UPX_F_DOS_COM ? "CORETURN" : "");
// clang-format on
} else {
// clang-format off
addLoader(filter_id % 3 == 1 ? "CT16E800" : "CT16E900",
"CALLTRI5",
getFormat() == UPX_F_DOS_COM ? "CT16JEND" : "CT16JUL2",
filter_id < 4 ? "CT16SUB1" : "",
filter_id < 4 ? "" : (opt->cpu_x86 == opt->CPU_8086 ? "CT16I087" : "CT16I287,CT16SUB1"),
"CALLTRI6");
// clang-format on
}
}
void PackCom::buildLoader(const Filter *ft) {
initLoader(stub_i086_dos16_com, sizeof(stub_i086_dos16_com));
// clang-format off
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");
// clang-format on
if (ft->id) {
assert(ft->calls > 0);
addFilter16(ft->id);
}
}
void PackCom::patchLoader(OutputFile *fo, byte *loader, int lsize, unsigned calls) {
const int e_len = getLoaderSectionStart("COMCUTPO"); const int e_len = getLoaderSectionStart("COMCUTPO");
const int d_len = lsize - e_len; const int d_len = lsize - e_len;
assert(e_len > 0 && e_len < 128); assert(e_len > 0 && e_len < 128);
@@ -92,7 +134,7 @@ void PackCom::patchLoader(OutputFile *fo, upx_byte *loader, int lsize, unsigned
if (upper_end + stacksize > 0xfffe) if (upper_end + stacksize > 0xfffe)
stacksize = 0x56; stacksize = 0x56;
if (upper_end + stacksize > 0xfffe) if (upper_end + stacksize > 0xfffe)
throwCantPack("file is too big for dos/com"); throwCantPack("file is too large for dos/com");
linker->defineSymbol("calltrick_calls", calls); linker->defineSymbol("calltrick_calls", calls);
linker->defineSymbol("sp_limit", upper_end + stacksize); linker->defineSymbol("sp_limit", upper_end + stacksize);
@@ -105,46 +147,15 @@ void PackCom::patchLoader(OutputFile *fo, upx_byte *loader, int lsize, unsigned
relocateLoader(); relocateLoader();
loader = getLoader(); loader = getLoader();
// some day we could use the relocation stuff for patchPackHeader too // some day we could use the relocation stuff for patchPackHeader too..
patchPackHeader(loader, e_len); patchPackHeader(loader, e_len);
// write loader + compressed file // write loader + compressed file
fo->write(loader, e_len); // entry fo->write(loader, e_len); // entry
fo->write(obuf, ph.c_len); fo->write(obuf, ph.c_len); // compressed
fo->write(loader + e_len, d_len); // decompressor fo->write(loader + e_len, d_len); // decompressor
#if 0 NO_printf("%-13s: entry : %8u bytes\n", getName(), e_len);
printf("%-13s: entry : %8ld bytes\n", getName(), (long) e_len); NO_printf("%-13s: compressed : %8u bytes\n", getName(), ph.c_len);
printf("%-13s: compressed : %8ld bytes\n", getName(), (long) ph.c_len); NO_printf("%-13s: decompressor : %8u bytes\n", getName(), d_len);
printf("%-13s: decompressor : %8ld bytes\n", getName(), (long) d_len);
#endif
}
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) {
assert(ft->calls > 0);
addFilter16(ft->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);
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);
} }
/************************************************************************* /*************************************************************************
@@ -187,7 +198,7 @@ void PackCom::pack(OutputFile *fo) {
**************************************************************************/ **************************************************************************/
int PackCom::canUnpack() { int PackCom::canUnpack() {
if (!readPackHeader(128)) if (!readPackHeader(128)) // read "ph"
return false; return false;
if (file_size_u <= ph.c_len) if (file_size_u <= ph.c_len)
return false; return false;
@@ -224,6 +235,4 @@ void PackCom::unpack(OutputFile *fo) {
fo->write(obuf, ph.u_len); fo->write(obuf, ph.u_len);
} }
Linker *PackCom::newLinker() const { return new ElfLinkerX86(); }
/* vim:set ts=4 sw=4 et: */ /* vim:set ts=4 sw=4 et: */
+7 -12
View File
@@ -1,4 +1,4 @@
/* p_com.h -- /* p_com.h -- dos/com executable format
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
@@ -26,8 +26,6 @@
*/ */
#pragma once #pragma once
#ifndef UPX_P_COM_H__
#define UPX_P_COM_H__ 1
/************************************************************************* /*************************************************************************
// dos/com // dos/com
@@ -37,11 +35,11 @@ class PackCom : public Packer {
typedef Packer super; typedef Packer super;
public: public:
PackCom(InputFile *f) : super(f) { bele = &N_BELE_RTP::le_policy; } explicit PackCom(InputFile *f) : super(f) { bele = &N_BELE_RTP::le_policy; }
virtual int getVersion() const override { return 13; } virtual int getVersion() const override { return 13; }
virtual int getFormat() const override { return UPX_F_DOS_COM; } virtual int getFormat() const override { return UPX_F_DOS_COM; }
virtual const char *getName() const override { return "dos/com"; } virtual const char *getName() const override { return "dos/com"; }
virtual const char *getFullName(const options_t *) const override { return "i086-dos16.com"; } virtual const char *getFullName(const Options *) const override { return "i086-dos16.com"; }
virtual const int *getCompressionMethods(int method, int level) const override; virtual const int *getCompressionMethods(int method, int level) const override;
virtual const int *getFilters() const override; virtual const int *getFilters() const override;
@@ -52,15 +50,12 @@ public:
virtual int canUnpack() override; virtual int canUnpack() override;
protected: protected:
virtual unsigned getCallTrickOffset() const { return 0x100; }
virtual Linker *newLinker() const override; virtual Linker *newLinker() const override;
void addFilter16(int filter_id);
protected: // dos/sys will override these:
virtual unsigned getCallTrickOffset() const { return 0x100; }
virtual void buildLoader(const Filter *ft) override; virtual void buildLoader(const Filter *ft) override;
virtual void patchLoader(OutputFile *fo, upx_byte *, int, unsigned); virtual void patchLoader(OutputFile *fo, byte *, int, unsigned);
virtual void addFilter16(int filter_id);
}; };
#endif /* already included */
/* vim:set ts=4 sw=4 et: */ /* vim:set ts=4 sw=4 et: */
+28 -25
View File
@@ -54,6 +54,8 @@ PackDjgpp2::PackDjgpp2(InputFile *f) : super(f), coff_offset(0) {
// assert(upx_adler32(stubify_stub, sizeof(stubify_stub)) == STUBIFY_STUB_ADLER32); // assert(upx_adler32(stubify_stub, sizeof(stubify_stub)) == STUBIFY_STUB_ADLER32);
} }
Linker *PackDjgpp2::newLinker() const { return new ElfLinkerX86; }
const int *PackDjgpp2::getCompressionMethods(int method, int level) const { const int *PackDjgpp2::getCompressionMethods(int method, int level) const {
return Packer::getDefaultCompressionMethods_le32(method, level); return Packer::getDefaultCompressionMethods_le32(method, level);
} }
@@ -64,28 +66,26 @@ const int *PackDjgpp2::getFilters() const {
return filters; return filters;
} }
unsigned PackDjgpp2::findOverlapOverhead(const upx_bytep buf, const upx_bytep tbuf, unsigned range, unsigned PackDjgpp2::findOverlapOverhead(const byte *buf, const byte *tbuf, unsigned range,
unsigned upper_limit) const { unsigned upper_limit) const {
unsigned o = super::findOverlapOverhead(buf, tbuf, range, upper_limit); unsigned o = super::findOverlapOverhead(buf, tbuf, range, upper_limit);
o = (o + 0x3ff) & ~0x1ff; o = (o + 0x3ff) & ~0x1ff;
return o; return o;
} }
Linker *PackDjgpp2::newLinker() const { return new ElfLinkerX86; }
void PackDjgpp2::buildLoader(const Filter *ft) { void PackDjgpp2::buildLoader(const Filter *ft) {
// prepare loader // prepare loader
initLoader(stub_i386_dos32_djgpp2, sizeof(stub_i386_dos32_djgpp2)); initLoader(stub_i386_dos32_djgpp2, sizeof(stub_i386_dos32_djgpp2));
addLoader("IDENTSTR,DJ2MAIN1", ft->id ? "DJCALLT1" : "", addLoader("IDENTSTR,DJ2MAIN1", ft->id ? "DJCALLT1" : "",
ph.first_offset_found == 1 ? "DJ2MAIN2" : "", ph.first_offset_found == 1 ? "DJ2MAIN2" : "",
M_IS_LZMA(ph.method) ? "LZMA_INIT_STACK" : "", getDecompressorSections(), M_IS_LZMA(ph.method) ? "LZMA_INIT_STACK" : "", getDecompressorSections(),
M_IS_LZMA(ph.method) ? "LZMA_DONE_STACK" : "", "DJ2BSS00", nullptr); M_IS_LZMA(ph.method) ? "LZMA_DONE_STACK" : "", "DJ2BSS00");
if (ft->id) { if (ft->id) {
assert(ft->calls > 0); assert(ft->calls > 0);
addLoader("DJCALLT2", nullptr); addLoader("DJCALLT2");
addFilter32(ft->id); addFilter32(ft->id);
} }
addLoader("DJRETURN,+40C,UPX1HEAD", nullptr); addLoader("DJRETURN,+40C,UPX1HEAD");
} }
/************************************************************************* /*************************************************************************
@@ -99,14 +99,14 @@ void PackDjgpp2::handleStub(OutputFile *fo) {
Packer::handleStub(fi, fo, coff_offset); Packer::handleStub(fi, fo, coff_offset);
} else { } else {
// "stubify" stub // "stubify" stub
info("Adding stub: %ld bytes", (long) sizeof(stub_i386_dos32_djgpp2_stubify)); info("Adding stub: %zd bytes", sizeof(stub_i386_dos32_djgpp2_stubify));
fo->write(stub_i386_dos32_djgpp2_stubify, sizeof(stub_i386_dos32_djgpp2_stubify)); fo->write(stub_i386_dos32_djgpp2_stubify, sizeof(stub_i386_dos32_djgpp2_stubify));
} }
} }
} }
static bool is_dlm(InputFile *fi, unsigned coff_offset) { static bool is_dlm(InputFile *fi, unsigned coff_offset) {
unsigned char buf[4]; byte buf[4];
unsigned off; unsigned off;
try { try {
@@ -125,7 +125,7 @@ static bool is_dlm(InputFile *fi, unsigned coff_offset) {
} }
static void handle_allegropak(InputFile *fi, OutputFile *fo) { static void handle_allegropak(InputFile *fi, OutputFile *fo) {
unsigned char b[8]; byte b[8];
int pfsize = 0; int pfsize = 0;
try { try {
@@ -150,8 +150,8 @@ static void handle_allegropak(InputFile *fi, OutputFile *fo) {
} }
int PackDjgpp2::readFileHeader() { int PackDjgpp2::readFileHeader() {
unsigned char hdr[0x1c]; byte hdr[0x1c];
unsigned char magic[8]; byte magic[8];
fi->seek(0, SEEK_SET); fi->seek(0, SEEK_SET);
fi->readx(hdr, sizeof(hdr)); fi->readx(hdr, sizeof(hdr));
@@ -179,9 +179,9 @@ int PackDjgpp2::readFileHeader() {
return 0; return 0;
// FIXME: check for Linux etc. // FIXME: check for Linux etc.
text = coff_hdr.sh; text = &coff_hdr.sh[0];
data = text + 1; data = &coff_hdr.sh[1];
bss = data + 1; bss = &coff_hdr.sh[2];
return UPX_F_DJGPP2_COFF; return UPX_F_DJGPP2_COFF;
} }
@@ -242,7 +242,7 @@ void PackDjgpp2::pack(OutputFile *fo) {
// read file // read file
const unsigned size = text->size + data->size; const unsigned size = text->size + data->size;
const unsigned tpos = text->scnptr; const unsigned tpos = text->scnptr;
const unsigned hdrsize = 20 + 28 + sizeof(external_scnhdr_t) * coff_hdr.f_nscns; const unsigned hdrsize = 20 + 28 + mem_size(sizeof(external_scnhdr_t), coff_hdr.f_nscns);
const unsigned usize = size + hdrsize; const unsigned usize = size + hdrsize;
if (hdrsize < sizeof(coff_hdr) || hdrsize > tpos) if (hdrsize < sizeof(coff_hdr) || hdrsize > tpos)
throwCantPack("coff header error"); throwCantPack("coff header error");
@@ -325,9 +325,9 @@ void PackDjgpp2::pack(OutputFile *fo) {
OutputFile::dump(opt->debug.dump_stub_loader, loader, lsize); OutputFile::dump(opt->debug.dump_stub_loader, loader, lsize);
fo->write(obuf, data->size); fo->write(obuf, data->size);
#if 0 #if 0
printf("%-13s: coff hdr : %8ld bytes\n", getName(), (long) sizeof(coff_hdr)); printf("%-13s: coff hdr : %8d bytes\n", getName(), (int) sizeof(coff_hdr));
printf("%-13s: loader : %8ld bytes\n", getName(), (long) lsize); printf("%-13s: loader : %8d bytes\n", getName(), (int) lsize);
printf("%-13s: compressed : %8ld bytes\n", getName(), (long) data->size); printf("%-13s: compressed : %8d bytes\n", getName(), (int) data->size);
#endif #endif
// verify // verify
@@ -371,11 +371,14 @@ void PackDjgpp2::unpack(OutputFile *fo) {
// decompress // decompress
decompress(ibuf, obuf); decompress(ibuf, obuf);
coff_header_t *chdr = (coff_header_t *) obuf.getVoidPtr(); coff_header_t *const chdr = (coff_header_t *) raw_bytes(obuf, sizeof(coff_header_t));
text = chdr->sh; text = &chdr->sh[0];
data = text + 1; data = &chdr->sh[1];
bss = &chdr->sh[2];
const unsigned hdrsize = 20 + 28 + sizeof(external_scnhdr_t) * chdr->f_nscns; const unsigned hdrsize = 20 + 28 + mem_size(sizeof(external_scnhdr_t), chdr->f_nscns);
if (hdrsize < sizeof(coff_hdr) || hdrsize > text->scnptr || hdrsize > ph.u_len)
throwCantUnpack("coff header error");
unsigned addvalue; unsigned addvalue;
if (ph.version >= 14) if (ph.version >= 14)
@@ -387,11 +390,11 @@ void PackDjgpp2::unpack(OutputFile *fo) {
if (ph.filter) { if (ph.filter) {
Filter ft(ph.level); Filter ft(ph.level);
ft.init(ph.filter, addvalue); ft.init(ph.filter, addvalue);
ft.cto = (unsigned char) ph.filter_cto; ft.cto = (byte) ph.filter_cto;
if (ph.version < 11) { if (ph.version < 11) {
unsigned char ctobuf[4]; byte ctobuf[4];
fi->readx(ctobuf, 4); fi->readx(ctobuf, 4);
ft.cto = (unsigned char) (get_le32(ctobuf) >> 24); ft.cto = (byte) (get_le32(ctobuf) >> 24);
} }
ft.unfilter(obuf, ph.u_len - data->size); ft.unfilter(obuf, ph.u_len - data->size);
} }
+14 -13
View File
@@ -37,11 +37,11 @@ class PackDjgpp2 final : public Packer {
typedef Packer super; typedef Packer super;
public: public:
PackDjgpp2(InputFile *f); explicit PackDjgpp2(InputFile *f);
virtual int getVersion() const override { return 14; } virtual int getVersion() const override { return 14; }
virtual int getFormat() const override { return UPX_F_DJGPP2_COFF; } virtual int getFormat() const override { return UPX_F_DJGPP2_COFF; }
virtual const char *getName() const override { return "djgpp2/coff"; } virtual const char *getName() const override { return "djgpp2/coff"; }
virtual const char *getFullName(const options_t *) const override { virtual const char *getFullName(const Options *) const override {
return "i386-dos32.djgpp2.coff"; return "i386-dos32.djgpp2.coff";
} }
virtual const int *getCompressionMethods(int method, int level) const override; virtual const int *getCompressionMethods(int method, int level) const override;
@@ -57,8 +57,7 @@ protected:
void handleStub(OutputFile *fo); void handleStub(OutputFile *fo);
int readFileHeader(); int readFileHeader();
virtual unsigned findOverlapOverhead(const upx_bytep buf, const upx_bytep tbuf, virtual unsigned findOverlapOverhead(const byte *buf, const byte *tbuf, unsigned range = 0,
unsigned range = 0,
unsigned upper_limit = ~0u) const override; unsigned upper_limit = ~0u) const override;
virtual void buildLoader(const Filter *ft) override; virtual void buildLoader(const Filter *ft) override;
virtual Linker *newLinker() const override; virtual Linker *newLinker() const override;
@@ -66,39 +65,41 @@ protected:
unsigned coff_offset; unsigned coff_offset;
struct alignas(1) external_scnhdr_t { struct alignas(1) external_scnhdr_t {
char _[12]; // name, paddr byte _[12]; // name, paddr
LE32 vaddr; LE32 vaddr;
LE32 size; LE32 size;
LE32 scnptr; LE32 scnptr;
char misc[12]; // relptr, lnnoptr, nreloc, nlnno byte misc[12]; // relptr, lnnoptr, nreloc, nlnno
char __[4]; // flags byte __[4]; // flags
}; };
struct alignas(1) coff_header_t { struct alignas(1) coff_header_t {
// ext_file_hdr // ext_file_hdr
LE16 f_magic; LE16 f_magic;
LE16 f_nscns; LE16 f_nscns;
char _[4]; // f_timdat byte _[4]; // f_timdat
LE32 f_symptr; LE32 f_symptr;
LE32 f_nsyms; LE32 f_nsyms;
char __[2]; // f_opthdr byte __[2]; // f_opthdr
LE16 f_flags; LE16 f_flags;
// aout_hdr // aout_hdr
LE16 a_magic; LE16 a_magic;
char ___[2]; // a_vstamp byte ___[2]; // a_vstamp
LE32 a_tsize; LE32 a_tsize;
LE32 a_dsize; LE32 a_dsize;
char ____[4]; // a_bsize byte ____[4]; // a_bsize
LE32 a_entry; LE32 a_entry;
char _____[8]; // a_text_start a_data_start byte _____[8]; // a_text_start a_data_start
// section headers // section headers
external_scnhdr_t sh[3]; external_scnhdr_t sh[3];
}; };
coff_header_t coff_hdr; coff_header_t coff_hdr;
external_scnhdr_t *text, *data, *bss; external_scnhdr_t *text = nullptr;
external_scnhdr_t *data = nullptr;
external_scnhdr_t *bss = nullptr;
void stripDebug(); void stripDebug();
}; };
+5 -7
View File
@@ -25,10 +25,7 @@
<markus@oberhumer.com> <ezerotven+github@gmail.com> <markus@oberhumer.com> <ezerotven+github@gmail.com>
*/ */
#pragma once
#ifndef __UPX_P_ELF_H
#define __UPX_P_ELF_H 1
/************************************************************************* /*************************************************************************
// N_Elf // N_Elf
@@ -314,6 +311,7 @@ struct ElfClass_32
COMPILE_TIME_ASSERT(sizeof(Rel) == 8) COMPILE_TIME_ASSERT(sizeof(Rel) == 8)
COMPILE_TIME_ASSERT(sizeof(Rela) == 12) COMPILE_TIME_ASSERT(sizeof(Rela) == 12)
COMPILE_TIME_ASSERT(sizeof(Sym) == 16) COMPILE_TIME_ASSERT(sizeof(Sym) == 16)
COMPILE_TIME_ASSERT(sizeof(External_Note) == 12)
COMPILE_TIME_ASSERT_ALIGNED1(Ehdr) COMPILE_TIME_ASSERT_ALIGNED1(Ehdr)
COMPILE_TIME_ASSERT_ALIGNED1(Phdr) COMPILE_TIME_ASSERT_ALIGNED1(Phdr)
COMPILE_TIME_ASSERT_ALIGNED1(Shdr) COMPILE_TIME_ASSERT_ALIGNED1(Shdr)
@@ -321,6 +319,7 @@ struct ElfClass_32
COMPILE_TIME_ASSERT_ALIGNED1(Rel) COMPILE_TIME_ASSERT_ALIGNED1(Rel)
COMPILE_TIME_ASSERT_ALIGNED1(Rela) COMPILE_TIME_ASSERT_ALIGNED1(Rela)
COMPILE_TIME_ASSERT_ALIGNED1(Sym) COMPILE_TIME_ASSERT_ALIGNED1(Sym)
COMPILE_TIME_ASSERT_ALIGNED1(External_Note)
} }
}; };
@@ -355,6 +354,7 @@ struct ElfClass_64
COMPILE_TIME_ASSERT(sizeof(Rel) == 16) COMPILE_TIME_ASSERT(sizeof(Rel) == 16)
COMPILE_TIME_ASSERT(sizeof(Rela) == 24) COMPILE_TIME_ASSERT(sizeof(Rela) == 24)
COMPILE_TIME_ASSERT(sizeof(Sym) == 24) COMPILE_TIME_ASSERT(sizeof(Sym) == 24)
COMPILE_TIME_ASSERT(sizeof(External_Note) == 12)
COMPILE_TIME_ASSERT_ALIGNED1(Ehdr) COMPILE_TIME_ASSERT_ALIGNED1(Ehdr)
COMPILE_TIME_ASSERT_ALIGNED1(Phdr) COMPILE_TIME_ASSERT_ALIGNED1(Phdr)
COMPILE_TIME_ASSERT_ALIGNED1(Shdr) COMPILE_TIME_ASSERT_ALIGNED1(Shdr)
@@ -362,6 +362,7 @@ struct ElfClass_64
COMPILE_TIME_ASSERT_ALIGNED1(Rel) COMPILE_TIME_ASSERT_ALIGNED1(Rel)
COMPILE_TIME_ASSERT_ALIGNED1(Rela) COMPILE_TIME_ASSERT_ALIGNED1(Rela)
COMPILE_TIME_ASSERT_ALIGNED1(Sym) COMPILE_TIME_ASSERT_ALIGNED1(Sym)
COMPILE_TIME_ASSERT_ALIGNED1(External_Note)
} }
}; };
@@ -435,7 +436,4 @@ typedef ElfClass_LE64::Rela Elf_LE64_Rela;
typedef ElfClass_LE64::Sym Elf_LE64_Sym; typedef ElfClass_LE64::Sym Elf_LE64_Sym;
typedef ElfClass_LE64::External_Note Elf_LE64_External_Note; typedef ElfClass_LE64::External_Note Elf_LE64_External_Note;
#endif /* already included */
/* vim:set ts=4 sw=4 et: */ /* vim:set ts=4 sw=4 et: */

Some files were not shown because too many files have changed in this diff Show More