Compare commits

...

194 Commits

Author SHA1 Message Date
Markus F.X.J. Oberhumer 3757579ffc all: prepare for release 2024-05-09 12:03:12 +02:00
Markus F.X.J. Oberhumer 2962dc351b CI updates 2024-05-09 10:21:39 +02:00
Markus F.X.J. Oberhumer c04c685469 src: restrict upx::atomic_exchange to pointer-size for now 2024-05-08 23:08:33 +02:00
Markus F.X.J. Oberhumer 72c9769953 src: avoid warnings when compiling with llvm-mingw-nightly 2024-05-08 22:22:13 +02:00
Markus F.X.J. Oberhumer 42759b94bd all: more clang-tidy cleanups 2024-05-08 15:12:57 +02:00
Markus F.X.J. Oberhumer aa9e69f03e submodules: update for new versions 2024-05-08 15:09:56 +02:00
Markus F.X.J. Oberhumer 0f3939df15 src: pacify clang-tidy 2024-05-07 14:46:02 +02:00
RainRat 62265a1bc9 fix typos 2024-05-07 01:41:41 -07:00
Markus F.X.J. Oberhumer 76b2cec8ee src: fix compilation with clang 2024-05-07 12:33:55 +02:00
Markus F.X.J. Oberhumer 3d82f0cfe1 src: introduce upx::atomic_exchange; cleanups 2024-05-07 10:05:44 +02:00
John Reiser e5546bc8b0 32-bit ELF escape hatch when no fit on last executable page
... about 1/1000 (4/PAGE_SIZE) chance
	modified:   src/stub/src/i386-linux.elf-main.c
	modified:   misc/testsuite/upx_testsuite_1-expected_sha256sums.sh
   plus all 32-bit elf-fold.h, elf-fold.map
2024-05-06 09:42:13 -07:00
Markus F.X.J. Oberhumer 6fc0a00ac8 all: update for clang-tidy-18 2024-05-06 05:40:22 +02:00
Markus F.X.J. Oberhumer 3e5ba5c064 CI updates 2024-05-05 09:35:35 +02:00
John Reiser 4c32a8e3d4 Fix attempted recovery from corrupted b_info
https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=66271&q=label%3AProj-upx
	modified:   p_lx_elf.cpp
2024-05-04 10:35:39 -07:00
John Reiser 2ea316d754 Detect sizeofcmds too small
https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=66330&q=label%3AProj-upx
	modified:   p_mach.cpp
2024-05-04 10:10:37 -07:00
John Reiser 548227a55b mb_dt_offsets.clear() prevents undef from corrupted input
https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=66344&q=label%3AProj-upx
	modified:   p_lx_elf.cpp
2024-05-04 09:56:34 -07:00
John Reiser a831a20910 unpackExtent detects corrupted compression method
https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=66338&q=label%3AProj-upx
	modified:   p_unix.cpp
2024-05-04 09:43:47 -07:00
John Reiser 811f66de84 Check gnu_shift during unpack
https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=66273&q=label%3AProj-upx
	modified:   p_lx_elf.cpp
2024-05-04 09:05:48 -07:00
Markus F.X.J. Oberhumer 84d806328b CI updates 2024-05-02 23:31:10 +02:00
Markus F.X.J. Oberhumer 285d4c4c65 submodules: update for new versions 2024-05-02 19:41:50 +02:00
Markus F.X.J. Oberhumer 8506f5b17c testsuite: update checksums caused by version change 2024-05-02 19:38:46 +02:00
Markus F.X.J. Oberhumer a87fd56b3e all: update version 2024-05-02 18:51:55 +02:00
Markus F.X.J. Oberhumer f0cb30e2b9 all: minor cleanups 2024-05-02 18:50:23 +02:00
Markus F.X.J. Oberhumer 038743c694 CI updates 2024-05-02 03:21:27 +02:00
John Reiser 0e6cef99a0 Guard against empty PT_NOTE
https://github.com/upx/upx/issues/817
	modified:   p_lx_elf.cpp
2024-05-01 10:09:52 -07:00
John Reiser 92c925fe95 New i386/lzma-multi_d.S enables unpacking more than one block
Used by p_lx_exe.cpp; others keep old i386/lzma_d.S
which allows only one block, but avoids trouble with
anti-virus utilities for some OS.
	modified:   misc/testsuite/upx_testsuite_1-expected_sha256sums.sh
	new file:   src/stub/src/arch/i386/lzma-multi_d.S
	modified:   src/stub/src/arch/i386/lzma_d.S
	modified:   src/stub/src/i386-bsd.elf.execve-entry.S
	modified:   src/stub/src/i386-linux.elf.execve-entry.S
    plus stub/*.h, *.dump

    Notable:
	modified:   src/stub/i386-dos32.djgpp2.h
	modified:   src/stub/i386-dos32.tmt.h
	modified:   src/stub/i386-dos32.watcom.le.h
	modified:   src/stub/i386-win32.pe.h
2024-05-01 10:09:52 -07:00
John Reiser 4562d5459d Some non-ELF --lzma stubs assumed only one block, and <= 0.5MiB
Fixed for p_lx_exc.cpp; others remain a mystery.
https://github.com/upx/upx/issues/816
2024-05-01 10:09:52 -07:00
Markus F.X.J. Oberhumer 8393ded1b3 CI updates 2024-05-01 13:11:12 +02:00
Markus F.X.J. Oberhumer b0dc483165 CI updates 2024-04-29 07:53:21 +02:00
Markus F.X.J. Oberhumer 3c0ca81311 CI updates 2024-04-29 06:24:45 +02:00
Markus F.X.J. Oberhumer 157a63a023 CI updates 2024-04-28 22:18:47 +02:00
John Reiser 80e22a7e38 Fix --preserve-build-id
https://github.com/upx/upx/issues/815
	modified:   p_lx_elf.cpp
2024-04-27 08:21:48 -07:00
Markus F.X.J. Oberhumer ddf2da3d76 cmake: run tests in parallel; misc/podman: add 30-rebuild-stubs.sh 2024-04-26 10:36:01 +02:00
Markus F.X.J. Oberhumer 0e6478a60f submodules: update for new versions 2024-04-26 09:51:10 +02:00
Markus F.X.J. Oberhumer aed2c085b8 misc: update mimic_ctest.sh 2024-04-25 10:56:24 +02:00
Markus F.X.J. Oberhumer a7592b2ca2 all: enhance tests 2024-04-25 03:19:59 +02:00
John Reiser 265c100845 PowerPC64 nrv2d decompressor
https://github.com/upx/upx/issues/813
	modified:   misc/testsuite/upx_testsuite_1-expected_sha256sums.sh
	modified:   src/stub/src/arch/powerpc/64le/nrv2d_d.S

	modified:   src/stub/powerpc64-darwin.dylib-entry.h
	modified:   src/stub/powerpc64-darwin.macho-entry.h
	modified:   src/stub/powerpc64-linux.elf-entry.h
	modified:   src/stub/powerpc64le-linux.elf-entry.h
	modified:   src/stub/powerpc64le-linux.kernel.vmlinux.h
2024-04-24 14:37:09 -07:00
John Reiser 84e8288f61 Propagate yesterday's fix to stub decoding on PowerPC
https://github.com/upx/upx/issues/813
	modified:   misc/testsuite/upx_testsuite_1-expected_sha256sums.sh
	modified:   src/stub/src/arch/powerpc/32/nrv2d_d.S
	modified:   src/stub/src/arch/powerpc/32/nrv2e_d.S
	modified:   src/stub/src/arch/powerpc/64le/nrv2b_d.S
	modified:   src/stub/src/arch/powerpc/64le/nrv2d_d.S

	modified:   src/stub/powerpc-darwin.dylib-entry.h
	modified:   src/stub/powerpc-darwin.macho-entry.h
	modified:   src/stub/powerpc-linux.elf-entry.h
	modified:   src/stub/powerpc-linux.kernel.vmlinux.h
	modified:   src/stub/powerpc64-darwin.dylib-entry.h
	modified:   src/stub/powerpc64-darwin.macho-entry.h
	modified:   src/stub/powerpc64-linux.elf-entry.h
	modified:   src/stub/powerpc64le-linux.elf-entry.h
	modified:   src/stub/powerpc64le-linux.kernel.vmlinux.h
	modified:   src/stub/tmp/powerpc-darwin.dylib-entry.bin.dump
	modified:   src/stub/tmp/powerpc-darwin.macho-entry.bin.dump
	modified:   src/stub/tmp/powerpc-linux.elf-entry.bin.dump
	modified:   src/stub/tmp/powerpc-linux.kernel.vmlinux.bin.dump
	modified:   src/stub/tmp/powerpc64-darwin.dylib-entry.bin.dump
	modified:   src/stub/tmp/powerpc64-darwin.macho-entry.bin.dump
	modified:   src/stub/tmp/powerpc64-linux.elf-entry.bin.dump
	modified:   src/stub/tmp/powerpc64le-linux.elf-entry.bin.dump
	modified:   src/stub/tmp/powerpc64le-linux.kernel.vmlinux.bin.dump
2024-04-24 10:36:55 -07:00
Markus F.X.J. Oberhumer c69b4561fb src: initialize some fields to suppress harmless valgrind errors 2024-04-24 12:36:22 +02:00
John Reiser 6db0af8d04 PowerPC cannot branch on CArry; requires contortions
https://github.com/upx/upx/issues/813
	modified:   src/stub/src/arch/powerpc/32/nrv2b_d.S
	modified:   misc/testsuite/upx_testsuite_1-expected_sha256sums.sh

	modified:   src/stub/powerpc-darwin.dylib-entry.h
	modified:   src/stub/powerpc-darwin.macho-entry.h
	modified:   src/stub/powerpc-linux.elf-entry.h
	modified:   src/stub/powerpc-linux.kernel.vmlinux.h
	modified:   src/stub/src/i386-linux.elf-main.c
	modified:   src/stub/tmp/powerpc-darwin.dylib-entry.bin.dump
	modified:   src/stub/tmp/powerpc-darwin.macho-entry.bin.dump
	modified:   src/stub/tmp/powerpc-linux.elf-entry.bin.dump
	modified:   src/stub/tmp/powerpc-linux.kernel.vmlinux.bin.dump
2024-04-23 17:40:07 -07:00
Markus F.X.J. Oberhumer 842d2cbb0d testsuite: update checksums 2024-04-21 19:46:05 -07:00
John Reiser 9fb64ded10 Syscall on powerpc linux wipes arg registers, unlike x86_64
Also squeaky-clean 'get_page_mask' for I/D cache consistency.
https://github.com/upx/upx/issues/813

	modified:   stub/powerpc-linux.elf-entry.h
	modified:   stub/powerpc-linux.elf-fold.h
	modified:   stub/src/powerpc-linux.elf-entry.S
	modified:   stub/src/powerpc-linux.elf-fold.S
	modified:   stub/tmp/powerpc-linux.elf-entry.bin.dump
	modified:   stub/tmp/powerpc-linux.elf-fold.map
2024-04-21 19:46:05 -07:00
Markus F.X.J. Oberhumer 9d26713b1a Add experimental (and undocumented) --help-verbose and --help-short options. 2024-04-21 14:20:18 +02:00
Markus F.X.J. Oberhumer eb3c55b5cb all: add more tests 2024-04-21 12:17:38 +02:00
Markus F.X.J. Oberhumer 896596f672 cmake update 2024-04-20 21:08:09 +02:00
Markus F.X.J. Oberhumer e4de14612f CI updates 2024-04-20 12:29:32 +02:00
Markus F.X.J. Oberhumer 1d2b276425 all: improve tests 2024-04-16 15:20:56 +02:00
Markus F.X.J. Oberhumer 35c6a200ad CI updates 2024-04-14 02:15:26 +02:00
Markus F.X.J. Oberhumer 90a7faa15e CI updates 2024-04-10 10:52:48 +02:00
John Reiser 91f5fe1c0e arm64 --nrv2d instruction confusion
https://github.com/upx/upx/issues/806

ARM Architecture Reference Manual
    ARMv8, for ARMv8-A architecture profile
Section C6.2.47, page C6-595 (note the 'invert'!)
    CINC <Wd>, <Wn>, <cond>
    is equivalent to
    CSINC <Wd>, <Wn>, <Wn>, invert(<cond>)

	modified:   src/stub/src/arch/arm64/v8/nrv2d_d32.S
	modified:   misc/testsuite/upx_testsuite_1-expected_sha256sums.sh

	modified:   src/stub/arm64-darwin.macho-entry.h
	modified:   src/stub/arm64-linux.elf-entry.h
	modified:   src/stub/arm64-linux.elf-so_fold.h
	modified:   src/stub/arm64-linux.shlib-init.h
	modified:   src/stub/arm64-win64.pe.h
2024-04-07 14:01:19 -07:00
John Reiser d48a7d303d Sync checksums for testsuite_1 (-release)
modified:   misc/testsuite/upx_testsuite_1-expected_sha256sums.sh
2024-04-06 18:37:34 -07:00
John Reiser bb816f0c74 arm64 --nrv2d preserve sign when decoding offset
https://github.com/upx/upx/issues/806
	modified:   src/stub/arm64-darwin.macho-entry.h
	modified:   src/stub/arm64-linux.elf-entry.h
	modified:   src/stub/arm64-linux.elf-so_fold.h
	modified:   src/stub/arm64-linux.shlib-init.h
	modified:   src/stub/arm64-win64.pe.h
	modified:   src/stub/src/arch/arm64/v8/nrv2d_d32.S
2024-04-06 16:16:28 -07:00
John Reiser 93abe97ea5 powerpc64le --nrv2d register conflict
modified:   stub/powerpc64-darwin.dylib-entry.h
	modified:   stub/powerpc64-darwin.macho-entry.h
	modified:   stub/powerpc64-linux.elf-entry.h
	modified:   stub/powerpc64le-linux.elf-entry.h
	modified:   stub/powerpc64le-linux.kernel.vmlinux.h
	modified:   stub/src/arch/powerpc/64le/nrv2d_d.S
	modified:   stub/src/arch/powerpc/64le/nrv2e_d.S

https://github.com/upx/upx/issues/806
2024-04-06 16:16:28 -07:00
Markus F.X.J. Oberhumer 97cf29ffbb all: enhance CMake tests; assorted updates 2024-04-06 15:47:46 +02:00
Markus F.X.J. Oberhumer ed35613d64 misc/podman/rebuild-stubs: upgrade to ubuntu-24.04 2024-04-05 20:04:23 +02:00
Markus F.X.J. Oberhumer f5ec8363b4 CI updates 2024-04-05 18:16:29 +02:00
Markus F.X.J. Oberhumer 87956de092 CI updates 2024-04-04 03:01:03 +02:00
Markus F.X.J. Oberhumer 0f9315383c cmake: only enable UBSAN for clang versions >= 9 2024-04-02 09:21:56 +02:00
Markus F.X.J. Oberhumer 3538d796a7 CI updates 2024-04-02 08:05:43 +02:00
Markus F.X.J. Oberhumer 24f3824524 CI updates and minor cleanups 2024-04-01 20:31:05 +02:00
Markus F.X.J. Oberhumer 70b20d7d89 CI updates 2024-03-29 12:11:41 +01:00
Markus F.X.J. Oberhumer 7b21a0620b CI updates 2024-03-28 20:21:11 +01:00
John Reiser 3949af6d3c Unpacking detects and defends against malicious ELF 2024-03-28 07:48:55 -07:00
Markus F.X.J. Oberhumer d1f62e3ab4 testsuite: update checksums caused by version bump 2024-03-28 19:51:57 +01:00
Markus F.X.J. Oberhumer 6e644fa480 all: post-release version bump 2024-03-28 19:47:04 +01:00
Markus F.X.J. Oberhumer 5bef968068 all: prepare for release 2024-03-27 13:57:30 +01:00
Markus F.X.J. Oberhumer 543cfe0a73 submodules: update for new versions 2024-03-26 15:46:48 +01:00
Markus F.X.J. Oberhumer 3ba91b8072 cmake update 2024-03-26 15:38:20 +01:00
Markus F.X.J. Oberhumer a27a9e6000 all: and yet more cleanups; NFCI 2024-03-25 11:07:40 +01:00
Markus F.X.J. Oberhumer 7e839e6962 all: more cleanups; NFCI 2024-03-23 20:18:28 +01:00
Markus F.X.J. Oberhumer 809a1b3dae submodules: update for new versions 2024-03-22 01:40:51 +01:00
Markus F.X.J. Oberhumer 9b80628f84 src/pefile.cpp: support relocs of large files
Use 5-byte entries instead of 4-byte entries to fully preserve "pos".

And add some symbolic constants.

Partially based on a patch by John.
2024-03-22 00:46:17 +01:00
Markus F.X.J. Oberhumer a21a006fe9 all: yet more minor cleanups 2024-03-19 16:03:37 +01:00
Markus F.X.J. Oberhumer 54d16a458a CI updates; cleanups 2024-03-16 17:46:40 +01:00
Markus F.X.J. Oberhumer cfc5f42ef2 testsuite: update checksums caused by version change 2024-03-12 18:16:52 +01:00
Markus F.X.J. Oberhumer e3d24238e4 all: update version 2024-03-12 18:12:43 +01:00
Markus F.X.J. Oberhumer 56e7b36959 src: new ACC version 2024-03-12 18:11:46 +01:00
Markus F.X.J. Oberhumer f29791470f all: yet more cleanups 2024-03-10 16:23:06 +01:00
Markus F.X.J. Oberhumer 52d9b53b74 all: minor cleanups 2024-03-08 11:52:44 +01:00
Markus F.X.J. Oberhumer 839a78f2e0 Better fix for previous commit to avoid out-of-bounds pointer. 2024-02-27 11:20:29 +01:00
John Reiser 680ce0a7af find_dt_ndx defends against overrun
https://github.com/upx/upx/issues/790
https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=66344&q=label%3AProj-upx
	modified:   p_lx_elf.cpp
2024-02-26 14:32:02 -08:00
Markus F.X.J. Oberhumer 06b0de9c77 CI: work-around zig cc mips bad codegen for hard-float 2024-02-17 16:34:11 +01:00
Markus F.X.J. Oberhumer 76b0b7b1ae all: clang-format 2024-02-14 21:29:51 +01:00
John Reiser fabda4df3a R_PPC64_REL24 is reallly "PC-rel. 26 bit, word aligned:
Just like R_PPC_REL24
	modified:   linker.cpp
2024-02-14 11:43:20 -08:00
Markus F.X.J. Oberhumer fdcdaf596a all: pacify clang-tidy, CI and cmake updates 2024-02-14 15:14:47 +01:00
Markus F.X.J. Oberhumer be44cefbe7 CI updates 2024-02-13 18:29:07 +01:00
Markus F.X.J. Oberhumer c1050e624b submodules: update for new versions 2024-02-13 16:49:08 +01:00
Markus F.X.J. Oberhumer ae6d3b9bff all: more assorted cleanups 2024-02-09 14:48:47 +01:00
John Reiser 25aa0e2e46 un_asl_dynsym() should skip when !dynstr
https://github.com/upx/upx/issues/785
https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=66302
	modified:   p_lx_elf.cpp
2024-02-08 19:32:03 -08:00
Markus F.X.J. Oberhumer 8f7578eef1 CI: enable valgrind 2024-02-04 13:54:37 +01:00
Markus F.X.J. Oberhumer 29ce4807fb all: minor updates 2024-02-04 13:37:00 +01:00
John Reiser 41f6945be1 Fix auxv_up() to avoid SIGSEGV under valgrind
https://github.com/upx/upx/issues/784
	modified:   stub/src/amd64-linux.elf-main.c
	modified:   stub/src/i386-linux.elf-main.c
	modified:   ../misc/testsuite/upx_testsuite_1-expected_sha256sums.sh
           plus all generated stub/*-linux.elf-fold.{h,map}
2024-02-03 13:58:53 -08:00
Markus F.X.J. Oberhumer 718ec468ff all: more assorted cleanups; NFCI 2024-02-02 10:17:16 +01:00
John Reiser d429801498 Avoid &file_image[file_size] because some Standards object
modified:   p_lx_elf.cpp
2024-02-01 11:41:04 -08:00
Markus F.X.J. Oberhumer 024091e6b5 src: fix previous bounds checking commit 2024-01-31 20:52:19 +01:00
Markus F.X.J. Oberhumer d849e9de98 src: add some bounds checking to MemBufferBase 2024-01-31 16:48:55 +01:00
John Reiser c0e40da2ab more checking of Mach_header when unpacking for MachOS
https://github.com/upx/upx/issues/783
https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=65532
	modified:   p_mach.cpp
2024-01-27 14:16:53 -08:00
John Reiser dff3766501 Detect too-large bit-shift in elf_lookup of DT_GNUHASH
https://github.com/upx/upx/issues/782
https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=65776
	modified:   p_lx_elf.cpp
2024-01-27 13:38:25 -08:00
John Reiser 2767ec54e1 more checking of PackUnix::p_info at unpack
https://github.com/upx/upx/issues/781
https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=65864
	modified:   p_unix.cpp
2024-01-27 13:06:59 -08:00
John Reiser ac72c02793 check nbucket earlier in DT_HASH on ELF
https://github.com/upx/upx/issues/780
https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=66079
	modified:   p_lx_elf.cpp
2024-01-27 11:42:25 -08:00
John Reiser 69c51eee4d better checking of DT_STRSZ for ELF
https://github.com/upx/upx/issues/779
https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=66064
	modified:   p_lx_elf.cpp
	modified:   p_lx_elf.h
2024-01-27 11:11:07 -08:00
John Reiser ff5a4eeb96 ELF versus --brute: addStubEntrySections() needs ph_forced_method()
https://github.com/upx/upx/issues/770
	modified:   p_lx_elf.cpp
2024-01-25 17:17:32 -08:00
John Reiser b48f870701 Detect circular DT_HASH and DT_GNUHASH lookup
https://github.com/upx/upx/issues/775
https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=65811&q=label%3AProj-upx
https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=65840&q=label%3AProj-upx
2024-01-25 15:05:53 -08:00
John Reiser 10807ebdc2 Unpack 8-byte b_info only if (ph.version <= 11): 2001 or earlier
*x86 only: .e_entry too low
https://github.com/upx/upx/issues/774
	modified:   p_lx_elf.cpp
2024-01-25 09:06:46 -08:00
Markus F.X.J. Oberhumer 5d649f83ec all: assorted cleanups 2024-01-24 20:53:14 +01:00
Markus F.X.J. Oberhumer 65b25adceb submodules: update for new versions 2024-01-24 20:49:33 +01:00
John Reiser d615985b8a elf_find_table_size() did not check for empty table
https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=65765&q=label%3AProj-upx
https://github.com/upx/upx/issues/771
	modified:   p_lx_elf.cpp
2024-01-18 19:11:12 -08:00
Markus F.X.J. Oberhumer b019440980 testsuite: update checksums caused by version year bump 2024-01-13 20:08:08 +01:00
John Reiser 38ed4b2017 arm32, arm64 ABI for -static must preserve register 0
Also arm32 forgot to unmap the expanded de-compressor via the escape hatch.

https://github.com/upx/upx/issues/758
https://github.com/upx/upx/issues/768
	modified:   ../misc/testsuite/upx_testsuite_1-expected_sha256sums.sh
	modified:   stub/src/arm.v4a-linux.elf-entry.S
	modified:   stub/src/arm.v4a-linux.elf-fold.S
	modified:   stub/src/arm64-linux.elf-entry.S
	modified:   stub/src/arm64-linux.elf-fold.S
	modified:   stub/src/i386-linux.elf-main.c
	modified:   stub/src/amd64-linux.elf-main.c
          plus associated *.h *.map *.dump
2024-01-12 15:39:18 -08:00
John Reiser 2ad0d51226 PeFile::rebuildImports(): Allow strlen() up to the very end of a logical block
https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=65650
https://github.com/upx/upx/issues/769
	modified:   pefile.cpp
2024-01-11 09:57:57 -08:00
John Reiser e4a611bcae PeFile ::readPeHeader should check ih.subsystem.
https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=65526
https://github.com/upx/upx/issues/767
	modified:   pefile.cpp
2024-01-10 16:28:17 -08:00
John Reiser f3728d99b9 Check ph.method in PackMachBase::unpack
https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=65553
https://github.com/upx/upx/issues/766
	modified:   p_mach.cpp
2024-01-10 16:04:08 -08:00
John Reiser b87f60a917 Check Mach_fat_arch.align
https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=65558
https://github.com/upx/upx/issues/765
	modified:   p_mach.cpp
2024-01-10 15:31:37 -08:00
John Reiser 28f26da6ab Need more care in PackMachBase::canUnpack()
https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=65532
https://github.com/upx/upx/issues/764
	modified:   p_mach.cpp
2024-01-10 15:14:54 -08:00
John Reiser d3e780d617 Unpacking ELF requires e_phnum at least 2
https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=65535
https://github.com/upx/upx/issues/763
	modified:   p_lx_elf.cpp
2024-01-10 14:07:58 -08:00
John Reiser d549c2b5c9 More care when recovering from slid b_info
https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=65531
https://github.com/upx/upx/issues/762
	modified:   p_lx_elf.cpp
2024-01-10 13:38:18 -08:00
John Reiser f310ce376e Beware fuzzer setting compressed size too small
https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=65519
https://github.com/upx/upx/issues/761
	modified:   p_unix.cpp
2024-01-10 11:20:47 -08:00
John Reiser 553fc9b1fb invert_pt_dynamic: Compilers differ, unsigned vs. signed
modified:   p_lx_elf.cpp
2024-01-10 10:33:33 -08:00
John Reiser 6dde9f7dc0 find_overlay_offset() did not check carefully enough
https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=65518
https://github.com/upx/upx/issues/760
	modified:   p_unix.cpp
2024-01-10 10:05:28 -08:00
John Reiser 3dca1175e5 invert_pt_dynamic() needs better checking for malformed input
https://github.com/upx/upx/issues/759
https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=65510
	modified:   p_lx_elf.cpp
2024-01-10 09:41:12 -08:00
John Reiser 09c5e38322 arm64-linux.elf ABI owns x0 at execve()?
https://github.com/upx/upx/issues/758
	modified:   ../misc/testsuite/upx_testsuite_1-expected_sha256sums.sh
	modified:   stub/arm64-linux.elf-fold.h
	modified:   stub/src/amd64-linux.elf-main.c
	modified:   stub/src/arm64-linux.elf-fold.S
	modified:   stub/tmp/arm64-linux.elf-fold.map
2024-01-09 12:17:01 -08:00
John Reiser fe6f1f0bb6 arm64-linux.elf-fold.S typo (eyesight)
https://github.com/upx/upx/issues/743
	modified:   misc/testsuite/upx_testsuite_1-expected_sha256sums.sh
	modified:   src/stub/arm64-linux.elf-fold.h
	modified:   src/stub/src/arm64-linux.elf-fold.S
2024-01-09 10:01:07 -08:00
Markus F.X.J. Oberhumer 250c656b9e testsuite: update checksums caused by version bump 2024-01-04 03:18:19 +01:00
Markus F.X.J. Oberhumer 9a0b5b65b8 all: remove unused scripts 2024-01-04 03:09:48 +01:00
Markus F.X.J. Oberhumer 57b2fb4c62 all: post-release version bump 2024-01-04 02:52:22 +01:00
Markus F.X.J. Oberhumer 099c3d829e all: prepare for release. 2024-01-03 18:43:18 +01:00
Markus F.X.J. Oberhumer a1a6d02b6f all: tired of CI updates 2024-01-03 18:01:56 +01:00
Markus F.X.J. Oberhumer f2ad7fb9c4 testsuite: update checksums caused by version bump 2024-01-03 18:00:07 +01:00
Markus F.X.J. Oberhumer 1bcf709fcf all: bump version date 2024-01-03 17:54:43 +01:00
Markus F.X.J. Oberhumer 47fc230893 all: welcome 2024 2024-01-03 17:47:25 +01:00
Markus F.X.J. Oberhumer be05d85570 submodules: update for new versions 2024-01-03 17:44:57 +01:00
Markus F.X.J. Oberhumer f598fa13a9 clang-format 2024-01-03 17:36:43 +01:00
Markus F.X.J. Oberhumer 568859d16f CI updates 2024-01-03 17:31:16 +01:00
Markus F.X.J. Oberhumer b5ed0a637b CI updates 2023-12-29 10:02:46 +01:00
Markus F.X.J. Oberhumer 17eff0aed4 CI updates 2023-12-29 05:45:00 +01:00
Markus F.X.J. Oberhumer 0a3f048eed CI updates 2023-12-29 05:14:03 +01:00
Markus F.X.J. Oberhumer 3cde897557 Improve testsuite. 2023-12-28 21:44:53 +01:00
Markus F.X.J. Oberhumer 0500e7d016 CI updates; cxxlib.h cleanups 2023-12-28 04:42:41 +01:00
Markus F.X.J. Oberhumer 778663ae69 CI updates 2023-12-21 23:01:52 +01:00
Markus F.X.J. Oberhumer 636cefb9f3 cmake update 2023-12-20 18:49:34 +01:00
Markus F.X.J. Oberhumer 1236776aa2 cmake update 2023-12-20 12:16:25 +01:00
Markus F.X.J. Oberhumer 51a6a5cca5 src: rename ptr_reinterpret_cast to ptr_static_cast; misc cleanups 2023-12-20 11:44:01 +01:00
Markus F.X.J. Oberhumer 3326c86e91 cmake update 2023-12-19 16:11:23 +01:00
Markus F.X.J. Oberhumer b0dbc3fe39 submodules: update for new versions 2023-12-19 16:10:32 +01:00
Markus F.X.J. Oberhumer decc1efb74 CI updates 2023-12-17 07:35:39 +01:00
Markus F.X.J. Oberhumer 2cf1c32d18 CI updates 2023-12-13 18:52:55 +01:00
Markus F.X.J. Oberhumer fc6e3840b7 CI updates 2023-12-09 08:52:25 +01:00
Markus F.X.J. Oberhumer 5e85c1a11b submodules: update for new versions 2023-12-09 08:34:48 +01:00
Markus F.X.J. Oberhumer 468bfce599 submodules: update for new versions 2023-12-02 01:52:32 +01:00
Markus F.X.J. Oberhumer 1e6e4043ed CI updates and minor cleanups. 2023-12-02 01:48:26 +01:00
John Reiser 67564513d2 Update because of age and evolution.
modified:   elf-to-mem.txt
2023-11-30 11:10:24 -08:00
John Reiser ed2633bf95 Honor .p_align <= 64K; else assume 4K is also available
https://github.com/upx/upx/issues/737
	modified:   p_lx_elf.cpp
2023-11-26 11:46:12 -08:00
Markus F.X.J. Oberhumer 3e70021406 all: more minor cleanups 2023-11-26 18:30:47 +01:00
Markus F.X.J. Oberhumer bf8dd31914 all: minor cleanups 2023-11-21 20:29:54 +01:00
John Reiser d4e94f5086 Fix varying page size on arm64
https://github.com/upx/upx/issues/734
	modified:   stub/src/amd64-linux.elf-fold.S
	modified:   stub/src/amd64-linux.elf-main.c
	modified:   stub/src/arm64-linux.elf-entry.S
	modified:   stub/src/arm64-linux.elf-fold.S
	modified:   ../misc/testsuite/upx_testsuite_1-expected_sha256sums.sh
          ... plus associated stub/*.h etc
2023-11-17 15:10:31 -08:00
John Reiser ae77fd60bb initial headway is limited by both file_size and mhcmdi.sizeofcmds
https://github.com/upx/upx/issues/732
	modified:   p_mach.cpp
2023-11-17 07:28:21 -08:00
Markus F.X.J. Oberhumer e79c790264 CI updates 2023-11-17 11:50:52 +01:00
Markus F.X.J. Oberhumer 46029bb8a0 CI updates 2023-11-15 13:06:29 +01:00
Markus F.X.J. Oberhumer f74c225338 CI updates 2023-11-14 19:15:34 +01:00
Markus F.X.J. Oberhumer c479fe32b3 cmake update 2023-11-13 11:29:17 +01:00
Markus F.X.J. Oberhumer dc23ee0ad2 submodules: update for new versions 2023-11-08 11:48:39 +01:00
Markus F.X.J. Oberhumer a5c32db01b CI updates 2023-11-08 11:25:23 +01:00
Markus F.X.J. Oberhumer d7142312c9 CI updates 2023-11-08 10:08:19 +01:00
Markus F.X.J. Oberhumer 283ab0e7ea CI updates and assorted cleanups 2023-11-06 19:29:40 +01:00
Markus F.X.J. Oberhumer b6dd61cea8 CI updates 2023-11-05 09:03:38 +01:00
Markus F.X.J. Oberhumer 11970d276d CI updates 2023-11-04 06:30:07 +01:00
Markus F.X.J. Oberhumer d618716ec1 Minify .clang-format
Remove all settings that currently do not have any effect.
2023-11-03 17:56:12 +01:00
Markus F.X.J. Oberhumer 4f0f977f04 CI updates and cleanups 2023-11-03 17:52:46 +01:00
Markus F.X.J. Oberhumer 2c4b1d8a8c submodules: update for new versions 2023-11-03 16:46:57 +01:00
Markus F.X.J. Oberhumer b2810c6deb testsuite: update checksums caused by version bump 2023-11-01 15:12:39 +01:00
Markus F.X.J. Oberhumer ceb2b56b71 all: post-release version bump 2023-11-01 15:07:18 +01:00
Markus F.X.J. Oberhumer d14fa5f8a4 all: prepare for release 2023-11-01 12:00:03 +01:00
Markus F.X.J. Oberhumer 79263a52ac submodules: update for new versions 2023-11-01 11:40:28 +01:00
Markus F.X.J. Oberhumer ecb3f83e83 CI updates 2023-11-01 11:28:35 +01:00
Markus F.X.J. Oberhumer f6aedb35ce CI updates 2023-11-01 10:06:27 +01:00
Markus F.X.J. Oberhumer 3b7d25ac49 CI updates 2023-11-01 08:48:27 +01:00
Markus F.X.J. Oberhumer e964d4acf3 src/util: change TriBool logic to use a bool template parameter 2023-10-31 12:24:44 +01:00
Markus F.X.J. Oberhumer e306085b81 CI updates 2023-10-31 11:49:18 +01:00
Markus F.X.J. Oberhumer b094ad4f2b CI updates 2023-10-31 10:34:55 +01:00
Markus F.X.J. Oberhumer 19c6b969ab src/options: fix bad TriBool ThirdValue for pefile compress_resources 2023-10-30 21:36:36 +01:00
Markus F.X.J. Oberhumer acfda848cd src/check: add some more tribool checks 2023-10-30 20:29:05 +01:00
John Reiser 52400e2561 /proc/self/exe now is optional
... for the benefit of 'unshare', 'chroot', etc.
If not present, then upx run-time stub unmaps all pages of original main program.
https://github.com/upx/upx/issues/721

	modified:   stub/src/amd64-linux.elf-entry.S
	modified:   stub/src/amd64-linux.elf-fold.S
	modified:   stub/src/arm.v4a-linux.elf-entry.S
	modified:   stub/src/arm.v4a-linux.elf-fold.S
	modified:   stub/src/arm64-linux.elf-entry.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:   ../misc/testsuite/upx_testsuite_1-expected_sha256sums.sh

           ... plus all associaed *.h, *.map, *.dump in stub/
2023-10-30 08:23:52 -07:00
Markus F.X.J. Oberhumer f62576a2be CI updates and minor cleanups 2023-10-30 14:15:35 +01:00
Markus F.X.J. Oberhumer 19bf9f59e9 src: clang-format stub/tools/armpe/armpe_tester.c 2023-10-30 13:07:20 +01:00
Markus F.X.J. Oberhumer fadf7cfc7b src: work on packed_struct cleanup 2023-10-30 12:55:07 +01:00
Markus F.X.J. Oberhumer ec0c9399fa src: clang-format conf.h 2023-10-30 12:30:58 +01:00
Markus F.X.J. Oberhumer 37b923245d all: various cleanups 2023-10-30 12:17:51 +01:00
Markus F.X.J. Oberhumer 38a676f6f7 src: introduce upx::ptr_reinterpret_cast 2023-10-29 16:52:24 +01:00
Markus F.X.J. Oberhumer cd1df6f6b1 all: update version 2023-10-29 15:37:13 +01:00
Markus F.X.J. Oberhumer 4a24fe8c53 CI updates and cleanups 2023-10-29 15:12:33 +01:00
Markus F.X.J. Oberhumer 6dac3dd248 CI updates 2023-10-27 09:24:06 +02:00
Markus F.X.J. Oberhumer 37d393cbc8 src: prefer using SetFileTime() on Windows 2023-10-27 06:58:14 +02:00
Markus F.X.J. Oberhumer 27f155374a testsuite: update checksums caused by version bump 2023-10-26 12:28:52 +02:00
Markus F.X.J. Oberhumer 8102137ad7 all: post-release version bump 2023-10-26 12:25:13 +02:00
550 changed files with 23708 additions and 24950 deletions
+6 -29
View File
@@ -1,50 +1,27 @@
# "Gofmt's style is nobody's favourite, but gofmt is everybody's favourite." --Rob Pike # vim:set ft=yaml ts=2 sw=2 et:
# # Copyright (C) Markus Franz Xaver Johannes Oberhumer
# for clang-format-15.0.6 from https://github.com/upx/upx-stubtools/releases # for clang-format-15.0.6 from https://github.com/upx/upx-stubtools/releases
#
# "Gofmt's style is nobody's favourite, but gofmt is everybody's favourite." --Rob Pike
--- ---
BasedOnStyle: LLVM BasedOnStyle: LLVM
ColumnLimit: 100 ColumnLimit: 100
IndentWidth: 4 IndentWidth: 4
--- ---
# settings for C and C++
Language: Cpp Language: Cpp
AccessModifierOffset: -4 AccessModifierOffset: -4
AlignConsecutiveMacros: AcrossComments AlignConsecutiveMacros: AcrossComments
AlwaysBreakTemplateDeclarations: true AlwaysBreakTemplateDeclarations: true
AttributeMacros: AttributeMacros:
- __acc_cdecl
- __acc_cdecl_atexit
- __acc_cdecl_qsort
- __acc_cdecl_sighandler
- __acc_forceinline
- __acc_noinline
- __acc_static_forceinline
- __acc_static_noinline
- DELETED_FUNCTION - DELETED_FUNCTION
- XSPAN_DELETED_FUNCTION - XSPAN_DELETED_FUNCTION
- forceinline
- may_throw - may_throw
- noinline
- static_forceinline
- static_noinline
EmptyLineBeforeAccessModifier: Leave EmptyLineBeforeAccessModifier: Leave
# IndentPPDirectives: AfterHash # TODO later
SortIncludes: false SortIncludes: false
SpaceAfterCStyleCast: true SpaceAfterCStyleCast: true
Standard: Cpp03 Standard: Cpp03
StatementMacros: StatementMacros:
- ACCCHK_ASSERT
- ACCCHK_ASSERT_IS_SIGNED_T
- ACCCHK_ASSERT_IS_UNSIGNED_T
- ACCCHK_ASSERT_SIGN_T
- ACC_BLOCK_BEGIN
- ACC_COMPILE_TIME_ASSERT
- ACC_COMPILE_TIME_ASSERT_HEADER
- ACC_CXX_DISABLE_NEW_DELETE
- ACC_CXX_TRIGGER_FUNCTION
- ACC_CXX_TRIGGER_FUNCTION_IMPL
- CLANG_FORMAT_DUMMY_STATEMENT - CLANG_FORMAT_DUMMY_STATEMENT
- COMPILE_TIME_ASSERT
- COMPILE_TIME_ASSERT_ALIGNED1
WhitespaceSensitiveMacros:
- ACC_PP_MACRO_EXPAND
- ACC_PP_STRINGIZE
... ...
+9 -2
View File
@@ -1,13 +1,17 @@
# for clang-tidy-16 from https://clang.llvm.org/extra/clang-tidy/ # vim:set ft=yaml ts=2 sw=2 et:
# Copyright (C) Markus Franz Xaver Johannes Oberhumer
# for clang-tidy from https://clang.llvm.org/extra/clang-tidy/
--- ---
Checks: > Checks: >
-*, -*,
bugprone-*, bugprone-*,
-bugprone-assignment-in-if-condition, -bugprone-assignment-in-if-condition,
-bugprone-branch-clone, -bugprone-branch-clone,
-bugprone-casting-through-void,
-bugprone-easily-swappable-parameters, -bugprone-easily-swappable-parameters,
-bugprone-empty-catch, -bugprone-empty-catch,
-bugprone-implicit-widening-of-multiplication-result, -bugprone-implicit-widening-of-multiplication-result,
-bugprone-inc-dec-in-conditions,
-bugprone-macro-parentheses, -bugprone-macro-parentheses,
-bugprone-narrowing-conversions, -bugprone-narrowing-conversions,
-bugprone-reserved-identifier, -bugprone-reserved-identifier,
@@ -19,10 +23,13 @@ Checks: >
clang-analyzer-*, clang-analyzer-*,
-clang-analyzer-optin.performance.Padding, -clang-analyzer-optin.performance.Padding,
-clang-analyzer-security.insecureAPI.DeprecatedOrUnsafeBufferHandling, -clang-analyzer-security.insecureAPI.DeprecatedOrUnsafeBufferHandling,
-clang-analyzer-security.insecureAPI.rand,
-clang-analyzer-security.insecureAPI.strcpy, -clang-analyzer-security.insecureAPI.strcpy,
clang-diagnostics-*', clang-diagnostic-*,
performance-*, performance-*,
-performance-avoid-endl, -performance-avoid-endl,
-performance-enum-size,
-performance-no-int-to-ptr,
-performance-unnecessary-value-param, -performance-unnecessary-value-param,
FormatStyle: file FormatStyle: file
HeaderFilterRegex: '.*' HeaderFilterRegex: '.*'
+44
View File
@@ -0,0 +1,44 @@
# vim:set ft=yaml ts=2 sw=2 et:
# Copyright (C) Markus Franz Xaver Johannes Oberhumer
# for clangd from https://clangd.llvm.org/
---
# treat *.h files as C++ source code
If:
PathMatch: src/.*\.h
PathExclude: vendor/.*
CompileFlags:
Add:
- -xc++
---
# C++ flags
If:
PathMatch: [ src/.*\.h, src/.*\.cpp ]
PathExclude: vendor/.*
CompileFlags:
Add:
- -std=gnu++17
# -std=gnu++20 # requires clangd >= 11.0
# -std=gnu++23 # requires clangd >= 18.0
---
# common flags for all C/C++ files
If:
PathMatch: [ src/.*\.h, src/.*\.c, src/.*\.cpp ]
PathExclude: vendor/.*
CompileFlags:
Add:
# see https://github.com/clangd/clangd/issues/1038 : Support deterministic relative include path
- -Ivendor
- -I../vendor
- -I../../vendor
- -DDEBUG
- -fno-strict-aliasing
- -fno-strict-overflow
- -funsigned-char
Diagnostics:
Includes:
# IgnoreHeader: A list of regexes. Include Cleaner will not produce diagnostics
# for headers whose path is a suffix match for any of these.
IgnoreHeader:
- src/.*\.h
UnusedIncludes: None
...
+3 -2
View File
@@ -1,3 +1,4 @@
# Copyright (C) Markus Franz Xaver Johannes Oberhumer
# see https://editorconfig.org/ # see https://editorconfig.org/
root = true root = true
@@ -14,8 +15,8 @@ trim_trailing_whitespace = true
indent_size = 8 indent_size = 8
indent_style = tab indent_style = tab
[*.S] [{*.asm,*.S}]
indent_size = 8 indent_size = 8
[*.yml] [{*.yaml,*.yml}]
indent_size = 2 indent_size = 2
+8
View File
@@ -1,7 +1,12 @@
# Copyright (C) Markus Franz Xaver Johannes Oberhumer
# see https://github.com/github-linguist/linguist # see https://github.com/github-linguist/linguist
# #
# HINT: check settings with # HINT: check settings with
# git ls-files | git check-attr --stdin --all # git ls-files | git check-attr --stdin --all
# git ls-files --eol
# disable all line ending conversions
* -text
# #
# tell diff tools that these files are generated automatically # tell diff tools that these files are generated automatically
@@ -14,6 +19,9 @@
/src/stub/src/arch/**/lzma_d_c[fns].S linguist-generated /src/stub/src/arch/**/lzma_d_c[fns].S linguist-generated
/src/stub/tmp/** linguist-generated /src/stub/tmp/** linguist-generated
/misc/podman/*/packages*.txt linguist-generated
/misc/testsuite/*expected_sha256sums* linguist-generated
# #
# make GitHub language detection more accurate # make GitHub language detection more accurate
# #
-1
View File
@@ -1,6 +1,5 @@
* @markus-oberhumer @jreiser * @markus-oberhumer @jreiser
/src/p_elf* @jreiser
/src/p_lx_* @jreiser /src/p_lx_* @jreiser
/src/p_mach* @jreiser /src/p_mach* @jreiser
/src/p_unix* @jreiser /src/p_unix* @jreiser
-9
View File
@@ -1,9 +0,0 @@
version: 2
updates:
- package-ecosystem: 'github-actions'
directory: '/'
schedule:
# Check for updates to GitHub Actions every Wednesday
interval: 'weekly'
day: 'wednesday'
-43
View File
@@ -1,43 +0,0 @@
# 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/*podman*/*/packages.txt"]
# misc variable names & symbols
[default.extend-identifiers]
acc_spawnve = "acc_spawnve"
ba = "ba"
fo = "fo"
fof = "fof"
O_WRONLY = "O_WRONLY"
# optin: clang-analyzer-optin.cplusplus
optin = "optin"
sidelen = "sidelen"
# macOS 11 "Big Sur"
Sur = "Sur"
tpos = "tpos"
# assembly sources
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"
+332 -240
View File
@@ -4,325 +4,375 @@
# unfortunately this sometimes breaks builds in mysterious ways... # unfortunately this sometimes breaks builds in mysterious ways...
# see https://github.com/actions/runner-images.git # see https://github.com/actions/runner-images.git
name: 'CI' name: CI
on: [push, workflow_dispatch] on: [push, workflow_dispatch]
env: env:
CMAKE_REQUIRED_QUIET: "OFF" CMAKE_REQUIRED_QUIET: 'OFF'
CTEST_OUTPUT_ON_FAILURE: "ON" CMAKE_VERBOSE_MAKEFILE: 'ON'
CTEST_OUTPUT_ON_FAILURE: 'ON'
DEBIAN_FRONTEND: noninteractive DEBIAN_FRONTEND: noninteractive
UPX_CMAKE_BUILD_FLAGS: --verbose UPX_CMAKE_BUILD_FLAGS: --verbose
# 2023-10-24 UPX_CMAKE_CONFIG_FLAGS: -Wdev --warn-uninitialized
ZIG_DIST_VERSION: 0.12.0-dev.1245+a07f288eb UPX_DEBUG_TEST_FLOAT_DIVISION_BY_ZERO: 1
UPX_DEBUG_TEST_LIBC_QSORT: 1
# 2024-04-20
ZIG_DIST_VERSION: 0.12.0
jobs: jobs:
job-rebuild-and-verify-stubs: job-rebuild-and-verify-stubs:
name: 'Rebuild stubs' name: Rebuild stubs
runs-on: ubuntu-20.04 runs-on: ubuntu-latest
container: ubuntu:24.04 # glibc-2.39
#container: debian:12-slim # also works; glibc-2.36
#container: debian:testing-slim # also works
steps: steps:
- name: 'Install extra packages' - name: Install packages
run: | run: |
uname -a; pwd; id; umask uname -a; pwd; id; umask
mkdir ../deps; cd ../deps; mkdir packages dpkg --add-architecture i386
if ! test -e /usr/bin/python2; then apt-get update && apt-get upgrade -y
####sudo apt-get update && sudo apt-get install -y --no-install-recommends python2-minimal # install system packages
apt-get install -y --no-install-recommends bash ca-certificates curl git libmpc3 make perl-base xz-utils libc6:i386 zlib1g:i386
# install python2-minimal packages from Debian-11 # install python2-minimal packages from Debian-11
wget -q 'https://ftp.debian.org/debian/pool/main/p/python2.7/libpython2.7-minimal_2.7.18-8_amd64.deb' mkdir ../deps; cd ../deps; mkdir packages
wget -q 'https://ftp.debian.org/debian/pool/main/p/python2.7/python2.7-minimal_2.7.18-8_amd64.deb' curl -sS -L -O https://ftp.debian.org/debian/pool/main/p/python2.7/libpython2.7-minimal_2.7.18-8+deb11u1_amd64.deb
sudo dpkg -i ./*python2*.deb && rm ./*python2*.deb && sudo ldconfig curl -sS -L -O https://ftp.debian.org/debian/pool/main/p/python2.7/python2.7-minimal_2.7.18-8+deb11u1_amd64.deb
sudo ln -s -v python2.7 /usr/bin/python2 dpkg -i ./*python2*.deb && rm ./*python2*.deb && ldconfig
fi ln -s -v python2.7 /usr/bin/python2
# manually unpack and install compat libs from Ubuntu-16.04 # 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' curl -sS -L -O 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/ 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 && ldconfig
sudo ldconfig
# install upx-stubtools # install upx-stubtools
wget -q -O - https://github.com/upx/upx-stubtools/releases/download/v20221212/bin-upx-20221212.tar.xz | tar -xJ curl -sS -L 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@v4 run: |
with: { submodules: true } git config --global --add safe.directory '*' # needed when running in a container
- name: 'Rebuild and verify stubs' git clone --branch "$GITHUB_REF_NAME" --depth 1 "$GITHUB_SERVER_URL/$GITHUB_REPOSITORY" .
git submodule update --init -- vendor/lzma-sdk
- name: Rebuild and verify stubs
run: | run: |
export PATH="$(readlink -en ../deps/bin-upx-20221212):$PATH" export PATH="$(readlink -en ../deps/bin-upx-20221212):$PATH"
make -C src/stub maintainer-clean extra-clean make -C src/stub maintainer-clean extra-clean
git status || true git status || true
make -C src/stub extra-all all make -C src/stub extra-all all
if ! git diff --quiet; then git diff; exit 1; fi if ! git diff --quiet; then git diff; exit 1; fi
- name: 'Check source code formatting' - run: bash ./misc/scripts/check_whitespace_git.sh
- name: Check source code formatting
run: | run: |
bash ./misc/scripts/check_whitespace_git.sh export UPX_CLANG_FORMAT="$PWD/../deps/bin-upx-20221212/clang-format-15.0.6"
UPX_CLANG_FORMAT="$PWD/../deps/bin-upx-20221212/clang-format-15.0.6" make -C src clang-format 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
- name: Rebuild docs
run: |
make -C doc clean all
if ! git diff --quiet; then git diff || true; fi # ignore diff error
job-linux-cmake: # uses cmake + make job-linux-cmake: # uses cmake + make
if: true if: true
needs: [ job-rebuild-and-verify-stubs ] needs: [ job-rebuild-and-verify-stubs ]
name: ${{ format('{0} cmake', matrix.os) }} name: ${{ format('{0}', matrix.os) }}
runs-on: ${{ matrix.os }} runs-on: ${{ matrix.os }}
strategy: strategy:
fail-fast: false fail-fast: false
matrix: matrix:
include: include:
- { os: ubuntu-22.04, use_m32: true } - { os: ubuntu-22.04, use_extra: true, use_wine: true }
- { os: ubuntu-20.04, use_m32: false } # use_m32 also works here, but save some CI time - { os: ubuntu-20.04, use_extra: true }
steps: steps:
- name: 'Install extra 32-bit and Windows packages' - name: Install extra 32-bit and MinGW packages
if: ${{ matrix.use_m32 }} if: ${{ matrix.use_extra }}
run: | run: |
sudo dpkg --add-architecture i386 sudo dpkg --add-architecture i386
sudo apt-get update sudo apt-get update && sudo apt-get upgrade -y
sudo apt-get install -y g++-multilib g++-mingw-w64-i686 g++-mingw-w64-x86-64 sudo apt-get install -y g++-multilib g++-mingw-w64-i686 g++-mingw-w64-x86-64
- name: 'Check out code' # make sure that we use posix-threads (pthread/winpthreads) and NOT win32-threads
uses: actions/checkout@v4 for f in i686-w64-mingw32-g++ i686-w64-mingw32-gcc x86_64-w64-mingw32-g++ x86_64-w64-mingw32-gcc; do
if test -f /usr/bin/$f-posix; then sudo update-alternatives --set $f /usr/bin/$f-posix; fi
ls -l /usr/bin/${f}*
done
ls -l /etc/alternatives/*mingw* || true
sudo apt-get install -y libc6-dbg:i386 valgrind
- name: Install Wine
if: ${{ matrix.use_extra && matrix.use_wine }}
run: |
sudo apt-get install -y wine wine32:i386 wine64
ls -l /usr/bin/wine*
mkdir -p -v ~/.wine && wineboot --init
- uses: actions/checkout@v4
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: 'Build cmake extra/gcc/debug' - run: make build/extra/gcc/all
run: 'make build/extra/gcc/debug' - run: make build/extra/clang/all
- name: 'Build cmake extra/gcc/release' - run: make build/extra/gcc-m32/all
run: 'make build/extra/gcc/release' if: ${{ matrix.use_extra }}
- name: 'Build cmake extra/clang/debug' - run: make build/extra/gcc-mx32/all
run: 'make build/extra/clang/debug' if: ${{ matrix.use_extra }}
- name: 'Build cmake extra/clang/release' - run: make build/extra/cross-windows-mingw32/all
run: 'make build/extra/clang/release' if: ${{ matrix.use_extra }}
- name: 'Build cmake extra/gcc-m32/debug' - run: make build/extra/cross-windows-mingw64/all
if: ${{ matrix.use_m32 }} if: ${{ matrix.use_extra }}
run: 'make build/extra/gcc-m32/debug' - name: Make artifact
- name: 'Build cmake extra/gcc-m32/release'
if: ${{ matrix.use_m32 }}
run: 'make build/extra/gcc-m32/release'
- name: 'Build cmake extra/cross-windows-mingw32/release'
if: ${{ matrix.use_m32 }}
run: 'make build/extra/cross-windows-mingw32/release'
- name: 'Build cmake extra/cross-windows-mingw64/release'
if: ${{ matrix.use_m32 }}
run: 'make build/extra/cross-windows-mingw64/release'
- name: 'Make artifact'
run: | run: |
N=$(echo "upx-${GITHUB_REF_NAME}-${GITHUB_SHA:0:7}-${{ matrix.os }}" | sed 's/[^0-9a-zA-Z_.-]/-/g') 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")
# GitHub Actions magic: set "artifact_name" environment value for use in next step
echo "artifact_name=$N" >> $GITHUB_ENV echo "artifact_name=$N" >> $GITHUB_ENV
- name: ${{ format('Upload artifact {0}', env.artifact_name) }} - name: ${{ format('Upload artifact {0}', env.artifact_name) }}
uses: actions/upload-artifact@v3 uses: actions/upload-artifact@v4
with: with: { name: '${{ env.artifact_name }}', path: tmp/artifact }
name: ${{ env.artifact_name }} - name: Run install tests
path: tmp/artifact
- name: 'Run install tests'
run: | run: |
(cd build/extra/gcc/release && DESTDIR=$PWD/Install-with-cmake cmake --install .) (cd build/extra/gcc/release && DESTDIR="$PWD/Install with cmake" cmake --install .)
(cd build/extra/gcc/release && DESTDIR=$PWD/Install-with-make make install) (cd build/extra/gcc/release && DESTDIR="$PWD/Install with make" make install)
- name: 'Run basic tests' - name: Run ctest tests
run: | run: |
make -C build/extra/gcc/debug test jobs="gcc/debug gcc/release clang/debug clang/release"
make -C build/extra/gcc/release test test "${{ matrix.use_extra }}" = "true" && jobs="$jobs gcc-m32/debug gcc-m32/release"
make -C build/extra/clang/debug test command -v wine >/dev/null && jobs="$jobs cross-windows-mingw32/debug cross-windows-mingw32/release"
make -C build/extra/clang/release test command -v wine >/dev/null && jobs="$jobs cross-windows-mingw64/debug cross-windows-mingw64/release"
- name: 'Run basic tests 32-bit' echo "===== parallel jobs: $jobs"
if: ${{ matrix.use_m32 }} CTEST_JOBS=2 parallel -kv --lb 'make build/extra/{}+test' ::: $jobs
- name: Mimic ctest tests
run: | run: |
make -C build/extra/gcc-m32/debug test jobs="gcc/debug gcc/release clang/debug clang/release"
make -C build/extra/gcc-m32/release test test "${{ matrix.use_extra }}" = "true" && jobs="$jobs gcc-m32/debug gcc-m32/release"
- name: 'Run file system test suite' echo "===== parallel jobs: $jobs"
parallel -kv --lb 'cd build/extra/{} && bash ../../../../misc/testsuite/mimic_ctest.sh' ::: $jobs
- name: Mimic ctest tests with Valgrind
if: true # note: valgrind is SLOW
run: | run: |
env -C build/extra/gcc/release bash "$PWD"/misc/testsuite/test_symlinks.sh if command -v valgrind >/dev/null; then
- name: 'Run test suite build/extra/gcc/release' export UPX_CONFIG_DISABLE_EXHAUSTIVE_TESTS=ON # valgrind is SLOW
export upx_exe_runner="valgrind --leak-check=no --error-exitcode=1 --quiet --gen-suppressions=all"
# clang/debug does not work before valgrind-3.20, see https://bugs.kde.org/show_bug.cgi?id=452758
jobs="gcc/debug gcc/release clang/release"
test "${{ matrix.use_extra }}" = "true" && jobs="$jobs gcc-m32/debug gcc-m32/release"
echo "===== parallel jobs: $jobs"
parallel -kv --lb 'cd build/extra/{} && bash ../../../../misc/testsuite/mimic_ctest.sh' ::: $jobs
fi
- name: Run file system test suite
run: |
jobs="gcc/debug gcc/release clang/debug clang/release"
test "${{ matrix.use_extra }}" = "true" && jobs="$jobs gcc-m32/debug gcc-m32/release"
echo "===== parallel jobs: $jobs"
parallel -kv --lb 'cd build/extra/{} && bash ../../../../misc/testsuite/test_symlinks.sh' ::: $jobs
- name: Run file system test suite with Valgrind
if: false # note: valgrind is SLOW
run: |
if command -v valgrind >/dev/null; then
export upx_exe_runner="valgrind --leak-check=no --error-exitcode=1 --quiet --gen-suppressions=all"
# clang/debug does not work before valgrind-3.20, see https://bugs.kde.org/show_bug.cgi?id=452758
jobs="gcc/debug gcc/release clang/release"
test "${{ matrix.use_extra }}" = "true" && jobs="$jobs gcc-m32/debug gcc-m32/release"
echo "===== parallel jobs: $jobs"
parallel -kv --lb 'cd build/extra/{} && bash ../../../../misc/testsuite/test_symlinks.sh' ::: $jobs
fi
- name: Run test suite
run: | run: |
export upx_testsuite_SRCDIR="$(readlink -en ../deps/upx-testsuite)" export upx_testsuite_SRCDIR="$(readlink -en ../deps/upx-testsuite)"
testsuite_1="$(readlink -en ./misc/testsuite/upx_testsuite_1.sh)" jobs="gcc/debug gcc/release clang/debug clang/release"
env -C build/extra/gcc/release upx_exe=./upx bash "$testsuite_1" test "${{ matrix.use_extra }}" = "true" && jobs="$jobs gcc-m32/debug gcc-m32/release"
echo "===== parallel jobs: $jobs"
parallel -kv --lb 'cd build/extra/{} && bash ../../../../misc/testsuite/upx_testsuite_1.sh' ::: $jobs
job-macos-cmake: # uses cmake + make job-macos-cmake: # uses cmake + make
if: true if: true
needs: [ job-rebuild-and-verify-stubs ] needs: [ job-rebuild-and-verify-stubs ]
name: ${{ format('{0} cmake', matrix.os) }} name: ${{ format('{0} {1}{2}', matrix.os, matrix.xcode_version && 'xcode-' || '', matrix.xcode_version) }}
runs-on: ${{ matrix.os }} runs-on: ${{ matrix.os }}
strategy: strategy:
fail-fast: false fail-fast: false
matrix: matrix:
include: include:
# NOTE: macos does not have "env -C"; only with coreutils # NOTE: macos does not have "env -C"; only with brew coreutils
# NOTE: macos-11 does not have "readlink -f"; only on macos >= 12 or with coreutils # NOTE: macos-11 does not have "readlink -f"; only on macos >= 12 or with brew coreutils
- { 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 } - { os: macos-13, testsuite: true } # use default Xcode-15; NOTE: gcc-12 on macos-13 does not work with Xcode-15
- { os: macos-13, gcc: gcc-12, gxx: g++-12, testsuite: true, xcode_version: 14.3.1 }
# { os: macos-14, gcc: gcc-13, gxx: g++-13, testsuite: true } # gcc-13: INTERNAL ERROR in ld64
# { os: macos-14, gcc: gcc-13, gxx: g++-13, testsuite: true, xcode_version: 14.3.1 } # gcc-13: MISSING HEADER FILES
- { os: macos-14, gcc: gcc-12, gxx: g++-12, testsuite: true } # => use gcc-12 for now
steps: steps:
- name: 'Install brew packages' - uses: maxim-lobanov/setup-xcode@v1
if: ${{ matrix.xcode_version }}
with: { xcode-version: '${{ matrix.xcode_version }}' }
- name: Install brew packages
if: ${{ matrix.testsuite }} if: ${{ matrix.testsuite }}
run: | run: |
test -z "$HOMEBREW_PREFIX" && HOMEBREW_PREFIX="$(brew --prefix)"
echo "HOMEBREW_PREFIX=$HOMEBREW_PREFIX" >> $GITHUB_ENV
# testsuite needs working "readlink -en" and "sha256sum -b" # testsuite needs working "readlink -en" and "sha256sum -b"
if ! test -e /usr/local/opt/coreutils/libexec/gnubin/readlink; then packages="ninja parallel"
echo "===== brew leaves:"; brew leaves; echo "===== brew list:"; brew list test -e "$HOMEBREW_PREFIX/opt/coreutils/libexec/gnubin/readlink" || packages="$packages coreutils"
if test -n "$packages"; then
echo "===== brew leaves:"; brew leaves; echo "===== brew list:"; brew list --versions
# only run "brew update" if needed # only run "brew update" if needed
if ! brew install coreutils; then brew update && brew install coreutils; fi if ! brew install $packages; then brew update && brew install $packages; fi
fi fi
- name: 'Check out code' mkdir -p ~/.parallel && : > ~/.parallel/$(echo 6305-4721 | tr 0-7 leticlwi)
uses: actions/checkout@v4 echo "UPX_DEBUG_FORCE_PACK_MACOS=1" >> $GITHUB_ENV
case "${{ matrix.os }}" in
# TODO FIXME: UPX on macos-13+ is broken => disable run-packed for now
macos-13 | macos-14) echo "UPX_CONFIG_DISABLE_RUN_PACKED_TEST=ON" >> $GITHUB_ENV ;;
esac
- uses: actions/checkout@v4
with: { submodules: true } with: { submodules: true }
- name: 'Check out test suite' - name: Check out test suite
if: ${{ matrix.testsuite }} if: ${{ matrix.testsuite }}
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: 'Build cmake extra/clang/debug' - run: make build/extra/clang/all
run: 'make build/extra/clang/debug' - name: Build extra/gcc/all
- name: 'Build cmake extra/clang/release' if: ${{ matrix.gcc }}
run: 'make build/extra/clang/release' run: make build/extra/gcc/all CC="${{ matrix.gcc }} -static-libgcc" CXX="${{ matrix.gxx }} -static-libgcc -static-libstdc++"
- name: 'Build cmake extra/gcc/debug' - name: Build xtarget/cross-darwin-arm64/all
if: ${{ matrix.gcc != '' }}
run: 'make build/extra/gcc/debug CC="${{ matrix.gcc }} -static-libgcc" CXX="${{ matrix.gxx }} -static-libgcc -static-libstdc++"'
- name: 'Build cmake extra/gcc/release'
if: ${{ matrix.gcc != '' }}
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'
run: | run: |
CC="clang -target arm64-apple-darwin" CXX="clang++ -target arm64-apple-darwin" \ make UPX_XTARGET=xtarget/cross-darwin-arm64 xtarget/all \
make UPX_XTARGET=cross-darwin-arm64 xtarget/debug CC="clang -target arm64-apple-darwin" CXX="clang++ -target arm64-apple-darwin"
- name: 'Build cmake xtarget/cross-darwin-arm64/release' - name: Make artifact
run: | run: |
CC="clang -target arm64-apple-darwin" CXX="clang++ -target arm64-apple-darwin" \ X="${{ matrix.xcode_version }}"; test -n "$X" && X="-xcode-$X"
make UPX_XTARGET=cross-darwin-arm64 xtarget/release N=$(echo "upx-${GITHUB_REF_NAME}-${GITHUB_SHA:0:7}-${{ matrix.os }}$X" | sed 's/[^0-9a-zA-Z_.-]/-/g')
- name: 'Make artifact'
run: |
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")
# GitHub Actions magic: set "artifact_name" environment value for use in next step
echo "artifact_name=$N" >> $GITHUB_ENV echo "artifact_name=$N" >> $GITHUB_ENV
- name: ${{ format('Upload artifact {0}', env.artifact_name) }} - name: ${{ format('Upload artifact {0}', env.artifact_name) }}
uses: actions/upload-artifact@v3 uses: actions/upload-artifact@v4
with: with: { name: '${{ env.artifact_name }}', path: tmp/artifact }
name: ${{ env.artifact_name }} - name: Run install tests
path: tmp/artifact
- name: 'Run install tests'
run: | run: |
(cd build/extra/clang/release && DESTDIR=$PWD/Install-with-cmake cmake --install .) (cd build/extra/clang/release && DESTDIR="$PWD/Install with cmake" cmake --install .)
(cd build/extra/clang/release && DESTDIR=$PWD/Install-with-make make install) (cd build/extra/clang/release && DESTDIR="$PWD/Install with make" make install)
- name: 'Run basic tests' - name: Run ctest 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 for f in ./build/extra/*/*/upx; do file $f; done
# make -C build/extra/clang/release test jobs="clang/debug clang/release"
- name: 'Run file system test suite' test -n "${{ matrix.gcc }}" && jobs="$jobs gcc/debug gcc/release"
echo "===== parallel jobs: $jobs"
CTEST_JOBS=2 parallel -kv --lb 'make build/extra/{}+test' ::: $jobs
- name: Mimic ctest tests
run: |
export PATH="$HOMEBREW_PREFIX/opt/coreutils/libexec/gnubin:$PATH"
jobs="clang/debug clang/release"
test -n "${{ matrix.gcc }}" && jobs="$jobs gcc/debug gcc/release"
echo "===== parallel jobs: $jobs"
parallel -kv --lb 'cd build/extra/{} && bash ../../../../misc/testsuite/mimic_ctest.sh' ::: $jobs
- name: Run file system test suite
if: ${{ matrix.testsuite }} # for coreutils readlink if: ${{ matrix.testsuite }} # for coreutils readlink
run: | run: |
## macos-11 does not have "readlink -f" export PATH="$HOMEBREW_PREFIX/opt/coreutils/libexec/gnubin:$PATH"
## testsuite="$(readlink -fn ./misc/testsuite/test_symlinks.sh)" export upx_test_file="$PWD"/build/extra/clang/release/upx
## (cd build/extra/clang/release && upx_exe=./upx bash "$testsuite") jobs="clang/debug clang/release"
export PATH="/usr/local/opt/coreutils/libexec/gnubin:$PATH" test -n "${{ matrix.gcc }}" && jobs="$jobs gcc/debug gcc/release"
env -C build/extra/clang/release bash "$PWD"/misc/testsuite/test_symlinks.sh echo "===== parallel jobs: $jobs"
- name: 'Run test suite build/extra/clang/release' parallel -kv --lb 'cd build/extra/{} && bash ../../../../misc/testsuite/test_symlinks.sh' ::: $jobs
- name: Run test suite
if: ${{ matrix.testsuite }} if: ${{ matrix.testsuite }}
run: | run: |
export PATH="/usr/local/opt/coreutils/libexec/gnubin:$PATH" export PATH="$HOMEBREW_PREFIX/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 ./misc/testsuite/upx_testsuite_1.sh)" jobs="clang/debug clang/release"
env -C build/extra/clang/release upx_exe=./upx bash "$testsuite_1" test -n "${{ matrix.gcc }}" && jobs="$jobs gcc/debug gcc/release"
echo "===== parallel jobs: $jobs"
parallel -kv --lb 'cd build/extra/{} && bash ../../../../misc/testsuite/upx_testsuite_1.sh' ::: $jobs
job-windows-cmake: # uses cmake + msbuild job-windows-cmake: # uses cmake + msbuild
if: true if: true
needs: [ job-rebuild-and-verify-stubs ] needs: [ job-rebuild-and-verify-stubs ]
name: ${{ format('{0} cmake', matrix.name) }} name: ${{ format('{0}', matrix.name) }}
runs-on: ${{ matrix.os }} runs-on: ${{ matrix.os }}
strategy: strategy:
fail-fast: false fail-fast: false
matrix: matrix:
include: include:
- { name: windows-2019-amd64, os: windows-2019, vsversion: 2019, arch: amd64 } - { name: windows-2019-amd64, os: windows-2019, vsversion: 2019, vsarch: amd64 }
- { name: windows-2022-amd64, os: windows-2022, vsversion: 2022, arch: amd64 } - { name: windows-2022-amd64, os: windows-2022, vsversion: 2022, vsarch: amd64 }
steps: steps:
- name: 'Check out code' - run: git config --global core.autocrlf false
uses: actions/checkout@v4 - uses: actions/checkout@v4
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: 'Set up Developer Command Prompt' - uses: ilammy/msvc-dev-cmd@v1
uses: ilammy/msvc-dev-cmd@cec98b9d092141f74527d0afa6feb2af698cfe89 # v1.12.1 with: { vsversion: '${{ matrix.vsversion }}', arch: '${{ matrix.vsarch }}' }
with: - run: make build/debug
vsversion: ${{ matrix.vsversion }} - run: make build/release
arch: ${{ matrix.arch }} - name: Make artifact
- name: 'Build cmake debug'
run: 'make build/debug'
- name: 'Build cmake release'
run: 'make build/release'
- name: 'Make artifact'
shell: bash shell: bash
run: | run: |
N=$(echo "upx-${GITHUB_REF_NAME}-${GITHUB_SHA:0:7}-${{ matrix.os }}" | sed 's/[^0-9a-zA-Z_.-]/-/g') 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
echo "artifact_name=$N" >> $GITHUB_ENV echo "artifact_name=$N" >> $GITHUB_ENV
- name: ${{ format('Upload artifact {0}', env.artifact_name) }} - name: ${{ format('Upload artifact {0}', env.artifact_name) }}
uses: actions/upload-artifact@v3 uses: actions/upload-artifact@v4
with: with: { name: '${{ env.artifact_name }}', path: tmp/artifact }
name: ${{ env.artifact_name }} - name: Run ctest tests
path: tmp/artifact if: ${{ matrix.vsarch != 'amd64_arm64' }}
- name: 'Run basic tests'
if: ${{ matrix.arch != 'amd64_arm64' }}
run: | run: |
ctest --test-dir build/debug -C Debug ctest --test-dir build/debug --parallel 8 -C Debug
ctest --test-dir build/release -C Release ctest --test-dir build/release --parallel 8 -C Release
- name: 'Run test suite build/release' - name: Run test suite build/release
if: ${{ matrix.arch != 'amd64_arm64' }} if: ${{ matrix.vsarch != '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 ./misc/testsuite/upx_testsuite_1.sh)" env -C build/release/Release bash "$PWD"/misc/testsuite/upx_testsuite_1.sh
env -C build/release/Release upx_exe=./upx bash "$testsuite_1"
job-windows-toolchains: # build "by hand" using cmd.exe job-windows-toolchains: # build "by hand" using cmd.exe
if: true if: github.repository_owner == 'upx'
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.name }} C: ${{ matrix.name }}
B: release B: release
H: 'd:\a\upx\upx'
strategy: strategy:
fail-fast: false fail-fast: false
matrix: matrix:
include: include:
- { name: amd64-win64-vs2019, os: windows-2019, vsversion: 2019, arch: amd64 } - { name: amd64-win64-vs2019, os: windows-2019, vsversion: 2019, vsarch: amd64 }
- { name: amd64-win64-vs2022, os: windows-2022, vsversion: 2022, arch: amd64 } - { name: amd64-win64-vs2022, os: windows-2022, vsversion: 2022, vsarch: amd64 }
- { name: arm64-win64-vs2019, os: windows-2019, vsversion: 2019, arch: amd64_arm64 } - { name: arm64-win64-vs2019, os: windows-2019, vsversion: 2019, vsarch: amd64_arm64 }
- { name: arm64-win64-vs2022, os: windows-2022, vsversion: 2022, arch: amd64_arm64 } - { name: arm64-win64-vs2022, os: windows-2022, vsversion: 2022, vsarch: amd64_arm64 }
- { name: arm64ec-win64-vs2022, os: windows-2022, vsversion: 2022, arch: amd64_arm64, cl_machine_flags: -arm64EC, link_machine_flags: '/machine:arm64ec' } - { name: arm64ec-win64-vs2022, os: windows-2022, vsversion: 2022, vsarch: amd64_arm64, cl_machine_flags: -arm64EC, link_machine_flags: '/machine:arm64ec' }
# { name: arm64x-win64-vs2022, os: windows-2022, vsversion: 2022, arch: amd64_arm64, cl_machine_flags: -arm64EC, link_machine_flags: '/machine:arm64x' } # { name: arm64x-win64-vs2022, os: windows-2022, vsversion: 2022, vsarch: 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-vs2019, os: windows-2019, vsversion: 2019, vsarch: amd64_x86 }
- { name: i386-win32-vs2022, os: windows-2022, vsversion: 2022, arch: amd64_x86 } - { name: i386-win32-vs2022, os: windows-2022, vsversion: 2022, vsarch: amd64_x86 }
steps: steps:
- name: 'Check out code' - run: git config --global core.autocrlf false
uses: actions/checkout@v4 - uses: actions/checkout@v4
with: { submodules: true } with: { submodules: true }
- name: 'Prepare sources and Check out test suite' - name: Prepare sources and Check out test suite
shell: bash shell: bash
run: | run: |
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/{bzip2,ucl,upx,zlib,zstd} mkdir -p -v build/$C/$B/{bzip2,ucl,upx,zlib,zstd}
- name: 'Set up Developer Command Prompt' repository_name="${GITHUB_REPOSITORY##*/}" # basename
uses: ilammy/msvc-dev-cmd@cec98b9d092141f74527d0afa6feb2af698cfe89 # v1.12.1 echo "H=d:\\a\\$repository_name\\$repository_name" >> $GITHUB_ENV
with: - uses: ilammy/msvc-dev-cmd@v1
vsversion: ${{ matrix.vsversion }} with: { vsversion: '${{ matrix.vsversion }}', arch: '${{ matrix.vsarch }}' }
arch: ${{ matrix.arch }} - name: Build by hand
- name: 'Build by hand'
shell: cmd shell: cmd
run: | run: |
@REM ===== set vars ===== @REM ===== set vars =====
where cl & where link where cl & where link
set RUN_CL=cl ${{ matrix.cl_machine_flags }} -MT set RUN_CL=cl ${{ matrix.cl_machine_flags }} -MT
set RUN_LIB=link -lib ${{ matrix.link_machine_flags }} set RUN_LIB=link -lib ${{ matrix.link_machine_flags }}
set DEFS=-D_CRT_NONSTDC_NO_WARNINGS -D_CRT_SECURE_NO_WARNINGS -DWIN32_LEAN_AND_MEAN @rem UPX only uses the very basic Windows API
set DEFS=-D_CRT_NONSTDC_NO_WARNINGS -D_CRT_SECURE_NO_WARNINGS -DWIN32_LEAN_AND_MEAN -D_WIN32_WINNT=0x0501
set BDIR=%H%\build\%C%\%B% 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 ===== @REM ===== build bzip2 =====
cd %BDIR%\bzip2 cd %BDIR%\bzip2
@rem %RUN_CL% -J -O2 -W4 -wd4127 -wd4244 -wd4267 -WX %DEFS% -c %H%\vendor\bzip2\*.c @rem %RUN_CL% -J -O2 -W4 -wd4127 -wd4244 -wd4267 -WX %DEFS% -DBZ_NO_STDIO -c %H%\vendor\bzip2\*.c
@rem %RUN_LIB% -out:bzip2.lib *.obj @rem %RUN_LIB% -out:bzip2.lib *.obj
@REM ===== build UCL ===== @REM ===== build UCL =====
cd %BDIR%\ucl cd %BDIR%\ucl
@@ -343,105 +393,111 @@ jobs:
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_DEFS=-DUPX_CONFIG_DISABLE_WSTRICT=0 -DUPX_CONFIG_DISABLE_WERROR=0 -DWITH_THREADS=0 -DWITH_BZIP2=0 -DWITH_ZSTD=0
set UPX_LIBS=%BDIR%\ucl\ucl.lib %BDIR%\zlib\zlib.lib 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 @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
%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 %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=$(echo "upx-${GITHUB_REF_NAME}-${GITHUB_SHA:0:7}-windows-${{ matrix.name }}" | sed 's/[^0-9a-zA-Z_.-]/-/g') 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
echo "artifact_name=$N" >> $GITHUB_ENV echo "artifact_name=$N" >> $GITHUB_ENV
- name: ${{ format('Upload artifact {0}', env.artifact_name) }} - name: ${{ format('Upload artifact {0}', env.artifact_name) }}
uses: actions/upload-artifact@v3 uses: actions/upload-artifact@v4
with: with: { name: '${{ env.artifact_name }}', path: tmp/artifact }
name: ${{ env.artifact_name }} - name: Run basic tests
path: tmp/artifact if: ${{ matrix.vsarch != 'amd64_arm64' }}
- name: 'Run basic tests'
if: ${{ matrix.arch != 'amd64_arm64' }}
run: | run: |
$ErrorActionPreference = 'stop' $ErrorActionPreference = 'stop'
$ErrorView = 'NormalView' $ErrorView = 'NormalView'
cd $Env:H\build\$Env:C\$Env:B\upx cd $Env:H\build\$Env:C\$Env:B\upx
$Env:UPX = "--no-color --no-progress" $Env:UPX = "--no-color --no-progress"
.\upx.exe --version .\upx.exe --version
.\upx.exe --sysinfo -v
.\upx.exe upx.exe -o upx_packed.exe .\upx.exe upx.exe -o upx_packed.exe
dir *.exe dir *.exe
.\upx.exe -l upx_packed.exe .\upx.exe -l upx_packed.exe
.\upx.exe -t upx_packed.exe .\upx.exe -t upx_packed.exe
.\upx_packed.exe --version .\upx_packed.exe --version
- name: 'Run test suite' - name: Run test suite
if: ${{ matrix.arch != 'amd64_arm64' }} if: ${{ matrix.vsarch != '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 ./misc/testsuite/upx_testsuite_1.sh)" env -C build/$C/$B/upx upx_exe=./upx.exe bash "$PWD"/misc/testsuite/upx_testsuite_1.sh
env -C build/$C/$B/upx upx_exe=./upx.exe bash "$testsuite_1"
job-linux-zigcc: # uses cmake + make job-linux-zigcc: # uses cmake + make
if: github.repository_owner == 'upx' if: github.repository_owner == 'upx'
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.18' # older versions such as alpine:3.12 also work; no-container also works container: alpine:3.19
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 # only build a few targets => more targets are tested in the Weekly CI
- { zig_target: aarch64-linux-musl } - { zig_target: aarch64-linux-musl, qemu: qemu-aarch64 }
# { zig_target: aarch64-linux-musl, zig_pic: -fPIE } # { zig_target: aarch64-linux-musl, qemu: qemu-aarch64, zig_pic: -fPIE }
# { zig_target: aarch64-macos-none } # { zig_target: aarch64-macos-none }
- { zig_target: aarch64-macos.11.0-none } - { zig_target: aarch64-macos.11.0-none }
# { zig_target: aarch64-macos.12.0-none } # { zig_target: aarch64-macos.12.0-none }
# { zig_target: aarch64-macos.13.0-none } # { zig_target: aarch64-macos.13.0-none }
- { zig_target: aarch64-windows-gnu } - { zig_target: aarch64-windows-gnu }
- { zig_target: arm-linux-musleabihf } - { zig_target: arm-linux-musleabihf, qemu: qemu-arm }
# { zig_target: arm-linux-musleabihf, zig_pic: -fPIE } # { zig_target: arm-linux-musleabihf, qemu: qemu-arm, zig_pic: -fPIE }
# { zig_target: i386-linux-musl } - { zig_target: i386-linux-gnu.2.3.4, zig_flags: -march=i586 }
# { zig_target: i386-linux-musl, zig_pic: -fPIE } - { zig_target: i386-linux-musl, zig_flags: -march=i586, qemu: qemu-i386 }
# { zig_target: i386-linux-musl, zig_flags: -march=i586, qemu: qemu-i386, zig_pic: -fPIE }
- { zig_target: i386-windows-gnu } - { zig_target: i386-windows-gnu }
# { zig_target: mips-linux-musl } # mips and mipsel: bad hard-float code generation(??); or QEMU bug; or UPX bug; see https://github.com/upx/upx/issues/788
# { zig_target: mipsel-linux-musl } - { zig_target: mips-linux-musl, zig_flags: -msoft-float, qemu: qemu-mips }
# { zig_target: powerpc-linux-musl } - { zig_target: mipsel-linux-musl, zig_flags: -msoft-float, qemu: qemu-mipsel }
# { zig_target: powerpc64-linux-musl } - { zig_target: powerpc-linux-musl, qemu: qemu-ppc }
# { zig_target: powerpc64le-linux-musl } # powerpc64: obscure problem with C++ exceptions in UPX doctest checks; use -fPIC to work-around
- { zig_target: x86_64-linux-musl } - { zig_target: powerpc64-linux-musl, zig_flags: -fPIC, qemu: qemu-ppc64 }
# { zig_target: x86_64-linux-musl, zig_pic: -fPIE } - { zig_target: powerpc64le-linux-musl, qemu: qemu-ppc64le }
- { zig_target: x86_64-linux-gnu.2.3.4, qemu: qemu-x86_64 } # can use QEMU because of gcompat
- { zig_target: x86_64-linux-musl, qemu: qemu-x86_64 }
# { zig_target: x86_64-linux-musl, qemu: qemu-x86_64, zig_pic: -fPIE }
# { zig_target: x86_64-macos-none } # { zig_target: x86_64-macos-none }
- { zig_target: x86_64-macos.11.0-none } - { zig_target: x86_64-macos.11.0-none }
# { zig_target: x86_64-macos.12.0-none } # { zig_target: x86_64-macos.12.0-none }
# { zig_target: x86_64-macos.13.0-none } # { zig_target: x86_64-macos.13.0-none }
- { zig_target: x86_64-windows-gnu } - { zig_target: x86_64-windows-gnu }
env: env:
# zig is currently missing winpthreads; see https://github.com/ziglang/zig/issues/10989
UPX_CONFIG_EXPECT_THREADS: ${{ contains(matrix.zig_target, '-windows-') && 'OFF' || 'ON' }}
# 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 }}
ZIG_PIC: ${{ matrix.zig_pic }} ZIG_PIC: ${{ matrix.zig_pic }}
ZIG_TARGET: ${{ matrix.zig_target }} ZIG_TARGET: ${{ matrix.zig_target }}
steps: steps:
- name: 'Install Alpine Linux container packages' - name: Install Alpine Linux container packages
if: ${{ job.container }} if: ${{ job.container }}
shell: sh shell: sh
run: | run: |
apk update && apk upgrade && apk add bash cmake file git make tar xz apk update && apk upgrade && apk add bash cmake curl file git make parallel tar xz
mkdir -p ~/.parallel && : > ~/.parallel/$(echo 6305-4721 | tr 0-7 leticlwi)
# set PATH like in Ubuntu # set PATH like in Ubuntu
echo "PATH=$HOME/.local/bin:$PATH" >> $GITHUB_ENV 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 '*' # needed when running in a container
git config --global --add safe.directory '*' - uses: actions/checkout@v4
- name: 'Check out code'
uses: actions/checkout@v4
with: { submodules: true } with: { submodules: true }
- name: ${{ format('Install Zig {0}', env.ZIG_DIST_VERSION) }} - name: ${{ format('Install Zig {0}', env.ZIG_DIST_VERSION) }}
shell: bash shell: bash
run: | run: |
# GitHub Actions magic: set "UPX_GITREV_SHORT" environment value for use in steps below
rev=$(git rev-parse --short=7 HEAD) rev=$(git rev-parse --short=7 HEAD)
echo "UPX_GITREV_SHORT=$rev" >> $GITHUB_ENV echo "UPX_GITREV_SHORT=$rev" >> $GITHUB_ENV
if [[ "${{ matrix.zig_target }}" == x86_64-linux-gnu.2.3.4 ]]; then
echo "NEED_GCOMPAT=1" >> $GITHUB_ENV
# TODO FIXME: problem with self-packed upx and musl+gcompat: "Not a valid dynamic program"
echo "UPX_CONFIG_DISABLE_RUN_PACKED_TEST=ON" >> $GITHUB_ENV
fi
# update ZIG_TARGET (i386 => x86) # update ZIG_TARGET (i386 => x86)
ZIG_TARGET=${ZIG_TARGET/i386-/x86-} ZIG_TARGET=${ZIG_TARGET/i386-/x86-}
echo "ZIG_TARGET=$ZIG_TARGET" >> $GITHUB_ENV echo "ZIG_TARGET=$ZIG_TARGET" >> $GITHUB_ENV
@@ -449,7 +505,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 curl -sS -L -O 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
@@ -465,18 +521,14 @@ jobs:
ls -la; head 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) }} - name: ${{ format('Build Release with zig-cc -target {0} {1}', env.ZIG_TARGET, env.ZIG_PIC) }}
run: | run: |
mkdir -p build/zig/${ZIG_TARGET}${ZIG_PIC}/release make UPX_XTARGET=zig/${ZIG_TARGET}${ZIG_PIC} xtarget/release \
cd build/zig/${ZIG_TARGET}${ZIG_PIC}/release CC="zig-cc" CXX="zig-cxx" CMAKE_AR="$HOME/.local/bin/zig-ar" CMAKE_RANLIB="$HOME/.local/bin/zig-ranlib"
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 file build/zig/${ZIG_TARGET}${ZIG_PIC}/release/upx*
cmake --build . --config Release --parallel --verbose
file ./upx*
- name: ${{ format('Build Debug with zig-cc -target {0} {1}', env.ZIG_TARGET, env.ZIG_PIC) }} - name: ${{ format('Build Debug with zig-cc -target {0} {1}', env.ZIG_TARGET, env.ZIG_PIC) }}
run: | run: |
mkdir -p build/zig/${ZIG_TARGET}${ZIG_PIC}/debug make UPX_XTARGET=zig/${ZIG_TARGET}${ZIG_PIC} xtarget/debug \
cd build/zig/${ZIG_TARGET}${ZIG_PIC}/debug CC="zig-cc" CXX="zig-cxx" CMAKE_AR="$HOME/.local/bin/zig-ar" CMAKE_RANLIB="$HOME/.local/bin/zig-ranlib"
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 file build/zig/${ZIG_TARGET}${ZIG_PIC}/debug/upx*
cmake --build . --config Debug --parallel --verbose
file ./upx*
- 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: |
@@ -484,15 +536,55 @@ jobs:
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")
# GitHub Actions magic: set "artifact_name" environment value for use in next step
echo "artifact_name=$N" >> $GITHUB_ENV echo "artifact_name=$N" >> $GITHUB_ENV
- name: ${{ format('Upload artifact {0}', env.artifact_name) }} - name: ${{ format('Upload artifact {0}', env.artifact_name) }}
uses: actions/upload-artifact@v3 uses: actions/upload-artifact@v4
with: with: { name: '${{ env.artifact_name }}', path: tmp/artifact }
name: ${{ env.artifact_name }} - name: Run install tests
path: tmp/artifact
- name: 'Run install tests'
if: ${{ contains(matrix.zig_target, '-linux') }} if: ${{ contains(matrix.zig_target, '-linux') }}
run: | 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 cmake" cmake --install .)
(cd build/zig/${ZIG_TARGET}${ZIG_PIC}/release && DESTDIR=$PWD/Install-with-make make install) (cd build/zig/${ZIG_TARGET}${ZIG_PIC}/release && DESTDIR="$PWD/Install with make" make install)
- name: Run ctest tests
if: ${{ matrix.zig_target == 'i386-linux-musl' || matrix.zig_target == 'x86_64-linux-musl' || matrix.zig_target == 'x86_64-linux-gnu.2.3.4' }}
run: |
test -n "$NEED_GCOMPAT" && apk add gcompat
jobs="${ZIG_TARGET}${ZIG_PIC}/debug ${ZIG_TARGET}${ZIG_PIC}/release"
echo "===== parallel jobs: $jobs"
parallel -kv --lb 'make build/zig/{}+test' ::: $jobs
- name: Mimic ctest tests
if: ${{ matrix.zig_target == 'i386-linux-musl' || matrix.zig_target == 'x86_64-linux-musl' || matrix.zig_target == 'x86_64-linux-gnu.2.3.4' }}
run: |
test -n "$NEED_GCOMPAT" && apk add gcompat
jobs="${ZIG_TARGET}${ZIG_PIC}/debug ${ZIG_TARGET}${ZIG_PIC}/release"
echo "===== parallel jobs: $jobs"
parallel -kv --lb 'cd build/zig/{} && bash ../../../../misc/testsuite/mimic_ctest.sh' ::: $jobs
- name: ${{ format('Mimic ctest tests with QEMU {0}', matrix.qemu) }}
if: ${{ matrix.qemu }}
run: |
qemu="${{ matrix.qemu }}"
apk add coreutils "${qemu%% *}"
test -n "$NEED_GCOMPAT" && apk add gcompat
export upx_exe_runner="$qemu"
jobs="${ZIG_TARGET}${ZIG_PIC}/debug ${ZIG_TARGET}${ZIG_PIC}/release"
echo "===== parallel jobs: $jobs"
parallel -kv --lb 'cd build/zig/{} && bash ../../../../misc/testsuite/mimic_ctest.sh' ::: $jobs
- name: Mimic ctest tests with Valgrind
if: ${{ matrix.zig_target == 'x86_64-linux-musl' || matrix.zig_target == 'x86_64-linux-gnu.2.3.4' }}
run: |
export UPX_CONFIG_DISABLE_EXHAUSTIVE_TESTS=ON # valgrind is SLOW
apk add coreutils valgrind
test -n "$NEED_GCOMPAT" && apk add gcompat
export upx_exe_runner="valgrind --leak-check=no --error-exitcode=1 --quiet --gen-suppressions=all"
upx_exe_runner="$upx_exe_runner --suppressions=$PWD/misc/valgrind/musl.supp"
jobs="${ZIG_TARGET}${ZIG_PIC}/debug ${ZIG_TARGET}${ZIG_PIC}/release"
echo "===== parallel jobs: $jobs"
parallel -kv --lb 'cd build/zig/{} && bash ../../../../misc/testsuite/mimic_ctest.sh' ::: $jobs
- name: Run file system test suite
if: ${{ matrix.zig_target == 'i386-linux-musl' || matrix.zig_target == 'x86_64-linux-musl' || matrix.zig_target == 'x86_64-linux-gnu.2.3.4' }}
run: |
apk add coreutils sudo
test -n "$NEED_GCOMPAT" && apk add gcompat
jobs="${ZIG_TARGET}${ZIG_PIC}/debug ${ZIG_TARGET}${ZIG_PIC}/release"
echo "===== parallel jobs: $jobs"
parallel -kv --lb 'cd build/zig/{} && chmod a+w . && sudo -u nobody bash ../../../../misc/testsuite/test_symlinks.sh' ::: $jobs
@@ -1,18 +0,0 @@
# Copyright (C) Markus Franz Xaver Johannes Oberhumer
name: 'GitHub - Close pull requests'
on:
#pull_request:
workflow_dispatch:
jobs:
job-close-pull-requests:
if: github.repository_owner == 'upx'
name: 'Close pull requests'
runs-on: ubuntu-latest
permissions:
pull-requests: write
steps:
- name: 'Close pull requests'
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
gh pr list --repo='${{ github.repository }}' --state=open --json=number | jq '.[].number' | xargs -r -n1 -- gh pr close --repo='${{ github.repository }}'
@@ -12,28 +12,28 @@
# Abandoned Issues and Pull Request". # Abandoned Issues and Pull Request".
# https://igorwiese.com/images/papers/Paper_BotSE_19.pdf # https://igorwiese.com/images/papers/Paper_BotSE_19.pdf
name: 'GitHub - Close inactive issues' name: GitHub - Close stale issues
on: on:
schedule: [cron: '50 0 * * 3'] # run weekly Wednesday 00:50 UTC schedule: [cron: "50 0 * * 1"] # run weekly Monday 00:50 UTC
workflow_dispatch: workflow_dispatch:
jobs: jobs:
job-close-inactive-issues: job-close-stale-issues:
if: github.repository_owner == 'upx' if: github.repository_owner == 'upx' && github.repository == 'upx/upx'
name: 'Close inactive issues' name: Close stale issues
runs-on: ubuntu-latest runs-on: ubuntu-latest
permissions: permissions:
issues: write issues: write
pull-requests: write pull-requests: write
steps: steps:
- uses: actions/stale@v8 - uses: actions/stale@v9
with: with:
operations-per-run: 300 operations-per-run: 300
exempt-all-milestones: true exempt-all-milestones: true
exempt-issue-labels: 'blocker,bug,enhancement,help wanted,regression' exempt-issue-labels: 'blocker,bug,enhancement,help wanted,regression'
days-before-stale: 60 days-before-stale: 90
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 for 90 days with no activity. Please remove the stale label or add a comment or this issue will be closed in 30 days.'
stale-pr-message: 'This PR is stale because it has been open 60 days with no activity. Please remove the stale label or add a comment or this PR will be closed in 30 days.' stale-pr-message: 'This PR is stale because it has been open for 90 days with no activity. Please remove the stale label or add a comment or this PR will be closed in 30 days.'
close-issue-message: 'This issue was closed because it has been stalled for 30 days with no activity. Please feel free to reopen.' close-issue-message: 'This issue was closed because it has been stalled for 30 days with no activity. Please feel free to reopen.'
close-pr-message: 'This PR was closed because it has been stalled for 30 days with no activity. Please feel free to reopen.' close-pr-message: 'This PR was closed because it has been stalled for 30 days with no activity. Please feel free to reopen.'
repo-token: ${{ secrets.GITHUB_TOKEN }} repo-token: ${{ secrets.GITHUB_TOKEN }}
-21
View File
@@ -1,21 +0,0 @@
# Copyright (C) Markus Franz Xaver Johannes Oberhumer
# see https://github.com/crate-ci/typos
name: 'Misc - Spell check'
on:
schedule: [cron: '55 0 * * 3'] # run weekly Wednesday 00:55 UTC
workflow_dispatch:
env:
DEBIAN_FRONTEND: noninteractive
jobs:
job-spell-check:
if: github.repository_owner == 'upx'
name: 'Spell check'
runs-on: ubuntu-latest
steps:
- name: 'Check out code'
uses: actions/checkout@v4
with: { submodules: false }
- name: 'Spell check with crate-ci/typos'
uses: crate-ci/typos@c004e98018d8621614d1ca516eed8ca2d04b365a # v1.16.20
with: { config: ./.github/typos_config.toml }
@@ -1,34 +0,0 @@
# Copyright (C) Markus Franz Xaver Johannes Oberhumer
name: 'Static Analyzer - clang-analyzer'
on:
schedule: [cron: '10 4 * * 3'] # run weekly Wednesday 04:10 UTC
workflow_dispatch:
env:
CMAKE_REQUIRED_QUIET: "OFF"
CTEST_OUTPUT_ON_FAILURE: "ON"
DEBIAN_FRONTEND: noninteractive
jobs:
job-analyze-clang-analyzer: # uses cmake + make
if: github.repository_owner == 'upx'
strategy:
fail-fast: false
matrix: {container: ['alpine:3.16','alpine:3.17','alpine:3.18','alpine:edge','i386/alpine:edge']}
name: ${{ format('Analyze clang-analyzer {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: |
# this seems to be needed when running in a container (beause of UID mismatch??)
git config --global --add safe.directory '*'
git clone --branch "$GITHUB_REF_NAME" --depth 1 https://github.com/upx/upx .
git submodule update --init
- name: 'Perform clang-analyzer scan-build Analysis Debug'
run: 'make 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 build/analyze/clang-analyzer/release'
@@ -1,34 +0,0 @@
# Copyright (C) Markus Franz Xaver Johannes Oberhumer
name: 'Static Analyzer - clang-tidy'
on:
schedule: [cron: '30 4 * * 3'] # run weekly Wednesday 04:30 UTC
workflow_dispatch:
env:
CMAKE_REQUIRED_QUIET: "OFF"
CTEST_OUTPUT_ON_FAILURE: "ON"
DEBIAN_FRONTEND: noninteractive
jobs:
job-analyze-clang-tidy: # uses cmake + make
if: github.repository_owner == 'upx'
strategy:
fail-fast: false
matrix: {container: ['alpine:3.18','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: |
# this seems to be needed when running in a container (beause of UID mismatch??)
git config --global --add safe.directory '*'
git clone --branch "$GITHUB_REF_NAME" --depth 1 https://github.com/upx/upx .
git submodule update --init
- name: 'Perform clang-tidy Analysis Debug'
run: 'make -k 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 build/analyze/clang-tidy/release'
@@ -1,36 +0,0 @@
# Copyright (C) Markus Franz Xaver Johannes Oberhumer
name: 'Static Analyzer - CodeQL'
on:
schedule: [cron: '50 4 * * 3'] # run weekly Wednesday 04:50 UTC
workflow_dispatch:
env:
CMAKE_REQUIRED_QUIET: "OFF"
CTEST_OUTPUT_ON_FAILURE: "ON"
DEBIAN_FRONTEND: noninteractive
jobs:
job-analyze-codeql:
if: github.repository_owner == 'upx'
name: Analyze
runs-on: ubuntu-latest
permissions:
actions: read
contents: read
security-events: write
strategy:
fail-fast: false
matrix:
language: [ 'cpp' ]
steps:
- name: Checkout repository
uses: actions/checkout@v4
with: { submodules: true }
- name: Initialize CodeQL
uses: github/codeql-action/init@v2
with:
languages: ${{ matrix.language }}
- name: Autobuild
uses: github/codeql-action/autobuild@v2
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v2
-66
View File
@@ -1,66 +0,0 @@
# 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"
CTEST_OUTPUT_ON_FAILURE: "ON"
DEBIAN_FRONTEND: noninteractive
jobs:
job-alpine-clang: # uses cmake + make
if: true
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.1.0/upx-4.1.0-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
if: true
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.1.0/upx-4.1.0-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'
-133
View File
@@ -1,133 +0,0 @@
# Copyright (C) Markus Franz Xaver Johannes Oberhumer
name: 'Test - CMake default build type'
on: [workflow_dispatch]
env:
CMAKE_REQUIRED_QUIET: "OFF"
CTEST_OUTPUT_ON_FAILURE: "ON"
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@v4
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@v4
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@v4
with: { submodules: true }
- name: 'Set up Developer Command Prompt'
uses: ilammy/msvc-dev-cmd@cec98b9d092141f74527d0afa6feb2af698cfe89 # v1.12.1
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@v4
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@v4
with: { submodules: true }
- name: 'Set up Developer Command Prompt'
uses: ilammy/msvc-dev-cmd@cec98b9d092141f74527d0afa6feb2af698cfe89 # v1.12.1
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@v4
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)
-16
View File
@@ -1,16 +0,0 @@
# Copyright (C) Markus Franz Xaver Johannes Oberhumer
name: 'Test - Unused'
on: [workflow_dispatch]
env:
CMAKE_REQUIRED_QUIET: "OFF"
CTEST_OUTPUT_ON_FAILURE: "ON"
DEBIAN_FRONTEND: noninteractive
jobs:
job-unused: # uses cmake + make
if: true
runs-on: ubuntu-latest
steps:
- run: |
true
-154
View File
@@ -1,154 +0,0 @@
# Copyright (C) Markus Franz Xaver Johannes Oberhumer
# BS BuildSystem: build "by hand" using a POSIX-compliant shell
name: 'Weekly CI BS - By Hand'
on:
schedule: [cron: '00 1 * * 3'] # run weekly Wednesday 01:00 UTC
workflow_dispatch:
env:
CMAKE_REQUIRED_QUIET: "OFF"
CTEST_OUTPUT_ON_FAILURE: "ON"
DEBIAN_FRONTEND: noninteractive
VERBOSE: 1
jobs:
job-by-hand-alpine-linux-gcc: # 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: github.repository_owner == 'upx'
strategy: { matrix: { container: ['alpine:3.9','alpine:3.18','alpine:edge','i386/alpine:edge'] } }
name: ${{ format('by-hand gcc {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
*:3.18 | *:edge) shells="$shells oksh yash" ;;
esac
echo "installing shells: $shells"
apk update && apk upgrade && apk add ccache g++ git $shells
# enable ccache and some warnings
xflags="-static -Wall -Wextra -Werror"
echo -e "CC=ccache gcc $xflags\nCXX=ccache g++ -std=gnu++17 $xflags" >> $GITHUB_ENV
# this seems to be needed when running in a container (beause of UID mismatch??)
git config --global --add safe.directory '*'
# create user upx:upx 2000:2000 for file system tests below ("sudo")
adduser upx -u 2000 -D && cd /home/upx && chmod 00700 . && chown -R upx:upx .
- name: ${{ format('Check out UPX {0} source code', github.ref_name) }}
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
- name: 'Build by-hand with /bin/sh'
run: '/bin/sh "./upx with space/misc/scripts/build_upx_by_hand.sh"'
- 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: endsWith(matrix.container, ':3.18') || endsWith(matrix.container, ':edge')
run: 'oksh "./upx with space/misc/scripts/build_upx_by_hand.sh"'
- name: 'Build by-hand with oksh -o posix'
if: endsWith(matrix.container, ':3.18') || endsWith(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: endsWith(matrix.container, ':3.18') || endsWith(matrix.container, ':edge')
run: 'oksh -o sh "./upx with space/misc/scripts/build_upx_by_hand.sh"'
- name: 'Build by-hand with yash'
if: endsWith(matrix.container, ':3.18') || endsWith(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
- name: 'Run file system test suite (busybox)'
run: |
apk add bash sudo
testsuite="$(readlink -fn "upx with space"/misc/testsuite/test_symlinks.sh)"
cd "upx with space"/build/by-hand
# IMPORTANT: do NOT run as user root!
chmod a+w . && sudo -u upx bash "$testsuite"
- name: 'Run file system test suite (coreutils)'
run: |
apk add bash coreutils sudo
testsuite="$(readlink -fn "upx with space"/misc/testsuite/test_symlinks.sh)"
cd "upx with space"/build/by-hand
# IMPORTANT: do NOT run as user root!
chmod a+w . && sudo -u upx bash "$testsuite"
job-by-hand-macos: # uses a POSIX-compliant shell
# ...and also uses a subdirectory "upx with space" in order to detect possible quoting issues
if: github.repository_owner == 'upx'
strategy:
fail-fast: false
matrix:
include:
- { os: macos-11, run_fs_test: false } # macos-11 does not have "readlink -f"
- { os: macos-12, run_fs_test: true }
- { os: macos-13, run_fs_test: true }
name: ${{ format('by-hand cc {0}', matrix.os) }}
runs-on: ${{ matrix.os }}
steps:
- 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
- name: 'Build by-hand with /bin/sh'
run: 'top_srcdir="$PWD/upx with space" /bin/sh "./upx with space/misc/scripts/build_upx_by_hand.sh"'
- name: 'Build by-hand with bash'
run: 'top_srcdir="$PWD/upx with space" bash "./upx with space/misc/scripts/build_upx_by_hand.sh"'
- name: 'Run file system test suite'
if: ${{ matrix.run_fs_test }}
run: |
testsuite="$(readlink -fn "upx with space"/misc/testsuite/test_symlinks.sh)"
cd "upx with space"/build/by-hand
bash "$testsuite"
job-by-hand-windows-gcc: # uses a POSIX-compliant shell
# ...and also uses a subdirectory "upx with space" in order to detect possible quoting issues
if: github.repository_owner == 'upx'
strategy:
fail-fast: false
matrix:
include:
- { os: windows-2019 }
- { os: windows-2022 }
name: ${{ format('by-hand gcc {0}', matrix.os) }}
runs-on: ${{ matrix.os }}
steps:
- name: ${{ format('Check out UPX {0} source code', github.ref_name) }}
shell: bash
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
- name: 'Build by-hand with bash'
shell: bash
run: |
xflags="-static -Wall -Wextra -Werror"
CC="gcc $xflags" CXX="g++ -std=gnu++17 $xflags" bash "./upx with space/misc/scripts/build_upx_by_hand.sh"
@@ -1,56 +0,0 @@
# Copyright (C) Markus Franz Xaver Johannes Oberhumer
# BS BuildSystem: build on macOS with 'cmake -G Xcode'
name: 'Weekly CI BS - cmake macOS Xcode'
on:
schedule: [cron: '10 1 * * 3'] # run weekly Wednesday 01:10 UTC
workflow_dispatch:
env:
CMAKE_REQUIRED_QUIET: "OFF"
CTEST_OUTPUT_ON_FAILURE: "ON"
DEBIAN_FRONTEND: noninteractive
jobs:
job-cmake-macos-xcode: # uses cmake + xcodebuild
if: github.repository_owner == 'upx'
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
name: ${{ format('{0} cmake Xcode', matrix.os) }}
runs-on: ${{ matrix.os }}
steps:
- name: 'Check out code'
uses: actions/checkout@v4
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
@@ -1,92 +0,0 @@
# Copyright (C) Markus Franz Xaver Johannes Oberhumer
# BS BuildSystem: build on Windows with 'cmake -G "Unix Makefiles"'
name: 'Weekly CI BS - cmake Windows make'
on:
schedule: [cron: '20 1 * * 3'] # run weekly Wednesday 01:20 UTC
workflow_dispatch:
env:
CMAKE_REQUIRED_QUIET: "OFF"
CTEST_OUTPUT_ON_FAILURE: "ON"
DEBIAN_FRONTEND: noninteractive
UPX_CMAKE_BUILD_FLAGS: --verbose
UPX_CMAKE_CONFIG_FLAGS: -G "Unix Makefiles"
jobs:
job-cmake-windows-make: # uses cmake + make
if: github.repository_owner == 'upx'
strategy:
fail-fast: false
matrix:
include:
# INFO: the following don't work with GNU make (probably some quoting problems with spaces or backslashes)
# => use Ninja generator instead; see weekly-ci-bs-cmake-windows-ninja.yml
# # cl (msvc)
# - { os: windows-2019, cc: cl, cxx: cl, vsversion: 2019, arch: amd64 }
# - { os: windows-2019, cc: cl, cxx: cl, vsversion: 2019, arch: amd64_arm64 }
# - { os: windows-2019, cc: cl, cxx: cl, vsversion: 2019, arch: amd64_x86 }
# - { os: windows-2022, cc: cl, cxx: cl, vsversion: 2022, arch: amd64 }
# - { os: windows-2022, cc: cl, cxx: cl, vsversion: 2022, arch: amd64_arm64 }
# - { os: windows-2022, cc: cl, cxx: cl, vsversion: 2022, arch: amd64_x86 }
# # clang-cl
# - { os: windows-2022, cc: clang-cl, cxx: clang-cl, vsversion: 2022, arch: amd64 }
# clang
- { os: windows-2022, cc: clang, cxx: 'clang++', arch: amd64, xflags: '-static' }
# gcc (mingw-gcc)
- { os: windows-2022, cc: gcc, cxx: 'g++', arch: amd64, xflags: '-static' }
env:
CC: ${{ matrix.cc }} ${{ matrix.xflags }}
CXX: ${{ matrix.cxx }} ${{ matrix.xflags }}
name: ${{ format('{0} {1} {2}', matrix.cc, matrix.vsversion, matrix.arch) }}
runs-on: ${{ matrix.os }}
steps:
- name: 'Check out code'
uses: actions/checkout@v4
with: { submodules: true }
- name: 'Set up Developer Command Prompt'
if: matrix.vsversion
uses: ilammy/msvc-dev-cmd@cec98b9d092141f74527d0afa6feb2af698cfe89 # v1.12.1
with:
vsversion: ${{ matrix.vsversion }}
arch: ${{ matrix.arch }}
- name: 'Init environment'
shell: bash
run: |
xtarget="windows-make-${{ matrix.cc }}-${{ matrix.vsversion }}-${{ matrix.arch}}"
echo "xtarget=$xtarget" >> $GITHUB_ENV
- name: 'Build cmake Make Debug'
shell: bash
run: |
make UPX_XTARGET=$xtarget xtarget/debug
ls -l build/xtarget/$xtarget/debug/upx.exe
file build/xtarget/$xtarget/debug/upx.exe || true
- name: 'Build cmake Make Release'
shell: bash
run: |
make UPX_XTARGET=$xtarget xtarget/release
ls -l build/xtarget/$xtarget/release/upx.exe
file build/xtarget/$xtarget/release/upx.exe || true
- name: 'Make artifact'
shell: bash
run: |
N=$(echo "upx-${GITHUB_REF_NAME}-${GITHUB_SHA:0:7}-weekly-ci-make-${xtarget}" | sed 's/[^0-9a-zA-Z_.-]/-/g')
mkdir -p "tmp/artifact/$N"
(cd build && cp -ai --parents xtarget/*/*/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' }}
shell: bash
run: |
ctest --test-dir build/xtarget/$xtarget/debug
ctest --test-dir build/xtarget/$xtarget/release
- name: 'Run install tests'
shell: bash
run: |
env DESTDIR=./Install-debug cmake --install build/xtarget/$xtarget/debug
env DESTDIR=./Install-release cmake --install build/xtarget/$xtarget/release
@@ -1,91 +0,0 @@
# Copyright (C) Markus Franz Xaver Johannes Oberhumer
# BS BuildSystem: build on Windows with 'cmake -G Ninja'
name: 'Weekly CI BS - cmake Windows Ninja'
on:
schedule: [cron: '30 1 * * 3'] # run weekly Wednesday 01:30 UTC
workflow_dispatch:
env:
CMAKE_REQUIRED_QUIET: "OFF"
CTEST_OUTPUT_ON_FAILURE: "ON"
DEBIAN_FRONTEND: noninteractive
UPX_CMAKE_BUILD_FLAGS: --verbose
UPX_CMAKE_CONFIG_FLAGS: -G Ninja
jobs:
job-cmake-windows-ninja: # uses cmake + ninja
if: github.repository_owner == 'upx'
strategy:
fail-fast: false
matrix:
include:
# cl (msvc)
- { os: windows-2019, cc: cl, cxx: cl, vsversion: 2019, arch: amd64 }
- { os: windows-2019, cc: cl, cxx: cl, vsversion: 2019, arch: amd64_arm64 }
- { os: windows-2019, cc: cl, cxx: cl, vsversion: 2019, arch: amd64_x86 }
- { os: windows-2022, cc: cl, cxx: cl, vsversion: 2022, arch: amd64 }
- { os: windows-2022, cc: cl, cxx: cl, vsversion: 2022, arch: amd64_arm64 }
- { os: windows-2022, cc: cl, cxx: cl, vsversion: 2022, arch: amd64_x86 }
# clang-cl
- { os: windows-2022, cc: clang-cl, cxx: clang-cl, vsversion: 2022, arch: amd64 }
# clang
- { os: windows-2022, cc: clang, cxx: 'clang++', arch: amd64, xflags: '-static' }
# gcc (mingw-gcc)
- { os: windows-2022, cc: gcc, cxx: 'g++', arch: amd64, xflags: '-static' }
env:
CC: ${{ matrix.cc }} ${{ matrix.xflags }}
CXX: ${{ matrix.cxx }} ${{ matrix.xflags }}
name: ${{ format('{0} {1} {2}', matrix.cc, matrix.vsversion, matrix.arch) }}
runs-on: ${{ matrix.os }}
steps:
- name: 'Check out code'
uses: actions/checkout@v4
with: { submodules: true }
- name: 'Set up Developer Command Prompt'
if: matrix.vsversion
uses: ilammy/msvc-dev-cmd@cec98b9d092141f74527d0afa6feb2af698cfe89 # v1.12.1
with:
vsversion: ${{ matrix.vsversion }}
arch: ${{ matrix.arch }}
- name: 'Init environment'
shell: bash
run: |
command -v ninja >/dev/null || choco install -y --no-progress ninja
xtarget="windows-ninja-${{ matrix.cc }}-${{ matrix.vsversion }}-${{ matrix.arch}}"
echo "xtarget=$xtarget" >> $GITHUB_ENV
- name: 'Build cmake Ninja Debug'
shell: bash
run: |
make UPX_XTARGET=$xtarget xtarget/debug
ls -l build/xtarget/$xtarget/debug/upx.exe
file build/xtarget/$xtarget/debug/upx.exe || true
- name: 'Build cmake Ninja Release'
shell: bash
run: |
make UPX_XTARGET=$xtarget xtarget/release
ls -l build/xtarget/$xtarget/release/upx.exe
file build/xtarget/$xtarget/release/upx.exe || true
- name: 'Make artifact'
shell: bash
run: |
N=$(echo "upx-${GITHUB_REF_NAME}-${GITHUB_SHA:0:7}-weekly-ci-ninja-${xtarget}" | sed 's/[^0-9a-zA-Z_.-]/-/g')
mkdir -p "tmp/artifact/$N"
(cd build && cp -ai --parents xtarget/*/*/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' }}
shell: bash
run: |
ctest --test-dir build/xtarget/$xtarget/debug
ctest --test-dir build/xtarget/$xtarget/release
- name: 'Run install tests'
shell: bash
run: |
env DESTDIR=./Install-debug cmake --install build/xtarget/$xtarget/debug
env DESTDIR=./Install-release cmake --install build/xtarget/$xtarget/release
@@ -1,78 +0,0 @@
# Copyright (C) Markus Franz Xaver Johannes Oberhumer
# BS BuildSystem: build on Windows with 'cmake -G "NMake Makefiles"'
name: 'Weekly CI BS - cmake Windows NMake'
on:
schedule: [cron: '40 1 * * 3'] # run weekly Wednesday 01:40 UTC
workflow_dispatch:
env:
CMAKE_REQUIRED_QUIET: "OFF"
CTEST_OUTPUT_ON_FAILURE: "ON"
DEBIAN_FRONTEND: noninteractive
jobs:
job-cmake-windows-nmake: # uses cmake + nmake
if: github.repository_owner == 'upx'
strategy:
fail-fast: false
matrix:
include:
# clang-cl
- { os: windows-2022, vsversion: 2022, arch: amd64, clang_cl: true }
# 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 }
name: ${{ format('vs{0} {1} {2}', matrix.vsversion, matrix.arch, matrix.clang_cl && 'clang-cl' || '') }}
runs-on: ${{ matrix.os }}
steps:
- name: 'Check out code'
uses: actions/checkout@v4
with: { submodules: true }
- name: 'Set up Developer Command Prompt'
uses: ilammy/msvc-dev-cmd@cec98b9d092141f74527d0afa6feb2af698cfe89 # v1.12.1
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
@@ -1,204 +0,0 @@
# Copyright (C) Markus Franz Xaver Johannes Oberhumer
# CC CompilationCheck: test various clang and gcc versions
# Build under various Alpine Linux versions with clang and gcc, and
# also test building with C++20, C++23 and LTO.
# And also uses a subdirectory "upx with space" that contains whitespace in order
# to detect possible quoting issues.
# info: Alpine Linux 3.9 (released Jan 2019) has clang-5, cmake-3.13.0
# and gcc-8, which nicely matches our minimal build requirements
name: 'Weekly CI CC - Alpine Linux C++23'
on:
schedule: [cron: '00 2 * * 3'] # run weekly Wednesday 02:00 UTC
workflow_dispatch:
env:
CMAKE_REQUIRED_QUIET: "OFF"
CTEST_OUTPUT_ON_FAILURE: "ON"
DEBIAN_FRONTEND: noninteractive
UPX_CMAKE_CONFIG_FLAGS: -DCMAKE_VERBOSE_MAKEFILE=ON
UPX_TESTSUITE_LEVEL: 4
jobs:
job-alpine-cmake: # uses cmake + make
if: github.repository_owner == 'upx'
strategy:
fail-fast: false
matrix:
include:
- { container: 'alpine:3.9' , use_cxx20: 0, use_cxx2b: 0, use_lto: 0 } # Jan 2019: C++17; clang-5 & gcc-8
- { container: 'alpine:3.10', use_cxx20: 0, use_cxx2b: 0, use_lto: 0 }
- { container: 'alpine:3.11', use_cxx20: 0, use_cxx2b: 0, use_lto: 0 }
- { container: 'alpine:3.12', use_cxx20: 0, use_cxx2b: 0, use_lto: 0 }
- { container: 'alpine:3.13', use_cxx20: 1, use_cxx2b: 0, use_lto: 0 } # Jan 2021: C++20; clang-10 & gcc-10
- { container: 'alpine:3.14', use_cxx20: 1, use_cxx2b: 0, use_lto: 0 }
- { container: 'alpine:3.15', use_cxx20: 1, use_cxx2b: 0, use_lto: 1 } # Nov 2021: LTO; clang-12 & gcc-10 & binutils-2.37
- { container: 'alpine:3.16', use_cxx20: 1, use_cxx2b: 1, use_lto: 1 } # May 2022: C++2b; clang-13 & gcc-11
- { container: 'alpine:3.17', use_cxx20: 1, use_cxx2b: 1, use_lto: 1 }
- { container: 'alpine:3.18', use_cxx20: 1, use_cxx2b: 1, use_lto: 1 }
- { container: 'alpine:edge', use_cxx20: 1, use_cxx2b: 1, use_lto: 1 }
- { container: 'i386/alpine:edge', use_cxx20: 1, use_cxx2b: 1, use_lto: 1 }
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 clang cmake g++ git make
case ${{ matrix.container }} in
# clang-dev is needed on Alpine versions <= 3.11 for clang headers like <emmintrin.h>
*:3.[0-9] | *:3.1[0-1]) apk add clang-dev ;;
esac
case ${{ matrix.container }}-${{ matrix.use_lto }} in
# llvm-dev is needed on Alpine versions <= 3.18 for -flto
*:3.[0-9]-1 | *:3.1[0-8]-1) apk add llvm-dev ;;
esac
# set environment vars
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
# create user upx:upx 2000:2000 for file system tests below ("sudo")
adduser upx -u 2000 -D && cd /home/upx && chmod 00700 . && chown -R upx:upx .
- name: ${{ format('Check out UPX {0} source code', github.ref_name) }}
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
# 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'
# build with C17 and C++20
- name: ${{ format('Build clang C++20 Release with {0}', env.clang_package) }}
if: matrix.use_cxx20
run: |
export UPX_CONFIG_DISABLE_C_STANDARD=ON UPX_CONFIG_DISABLE_CXX_STANDARD=ON
make -C "upx with space" UPX_XTARGET=clang-static-cxx20 CC="clang -static -std=gnu17" CXX="clang++ -static -std=gnu++20"
- name: ${{ format('Build clang C++20 Debug with {0}', env.clang_package) }}
if: matrix.use_cxx20
run: |
export UPX_CONFIG_DISABLE_C_STANDARD=ON UPX_CONFIG_DISABLE_CXX_STANDARD=ON
make -C "upx with space" UPX_XTARGET=clang-static-cxx20 CC="clang -static -std=gnu17" CXX="clang++ -static -std=gnu++20" xtarget/debug
- name: ${{ format('Build gcc C++20 Release with {0}', env.gcc_package) }}
if: matrix.use_cxx20
run: |
export UPX_CONFIG_DISABLE_C_STANDARD=ON UPX_CONFIG_DISABLE_CXX_STANDARD=ON
make -C "upx with space" UPX_XTARGET=gcc-static-cxx20 CC="gcc -static -std=gnu17" CXX="g++ -static -std=gnu++20"
- name: ${{ format('Build gcc C++20 Debug with {0}', env.gcc_package) }}
if: matrix.use_cxx20
run: |
export UPX_CONFIG_DISABLE_C_STANDARD=ON UPX_CONFIG_DISABLE_CXX_STANDARD=ON
make -C "upx with space" UPX_XTARGET=gcc-static-cxx20 CC="gcc -static -std=gnu17" CXX="g++ -static -std=gnu++20" xtarget/debug
# build with C23 and C++23
- name: ${{ format('Build clang C++23 Release with {0}', env.clang_package) }}
if: matrix.use_cxx23 || matrix.use_cxx2b
run: |
export UPX_CONFIG_DISABLE_C_STANDARD=ON UPX_CONFIG_DISABLE_CXX_STANDARD=ON
a=gnu23; b=gnu++23; if test "X${{ matrix.use_cxx2b }}" = X1; then a=gnu2x; b=gnu++2b; fi
make -C "upx with space" UPX_XTARGET=clang-static-cxx23 CC="clang -static -std=$a" CXX="clang++ -static -std=$b"
- name: ${{ format('Build clang C++23 Debug with {0}', env.clang_package) }}
if: matrix.use_cxx23 || matrix.use_cxx2b
run: |
export UPX_CONFIG_DISABLE_C_STANDARD=ON UPX_CONFIG_DISABLE_CXX_STANDARD=ON
a=gnu23; b=gnu++23; if test "X${{ matrix.use_cxx2b }}" = X1; then a=gnu2x; b=gnu++2b; fi
make -C "upx with space" UPX_XTARGET=clang-static-cxx23 CC="clang -static -std=$a" CXX="clang++ -static -std=$b" xtarget/debug
- name: ${{ format('Build gcc C++23 Release with {0}', env.gcc_package) }}
if: matrix.use_cxx23 || matrix.use_cxx2b
run: |
export UPX_CONFIG_DISABLE_C_STANDARD=ON UPX_CONFIG_DISABLE_CXX_STANDARD=ON
a=gnu23; b=gnu++23; if test "X${{ matrix.use_cxx2b }}" = X1; then a=gnu2x; b=gnu++2b; fi
make -C "upx with space" UPX_XTARGET=gcc-static-cxx23 CC="gcc -static -std=$a" CXX="g++ -static -std=$b"
- name: ${{ format('Build gcc C++23 Debug with {0}', env.gcc_package) }}
if: matrix.use_cxx23 || matrix.use_cxx2b
run: |
export UPX_CONFIG_DISABLE_C_STANDARD=ON UPX_CONFIG_DISABLE_CXX_STANDARD=ON
a=gnu23; b=gnu++23; if test "X${{ matrix.use_cxx2b }}" = X1; then a=gnu2x; b=gnu++2b; fi
make -C "upx with space" UPX_XTARGET=gcc-static-cxx23 CC="gcc -static -std=$a" CXX="g++ -static -std=$b" xtarget/debug
# build with -flto
- name: ${{ format('Build clang LTO Release with {0}', env.clang_package) }}
if: matrix.use_lto
run: |
make -C "upx with space" UPX_XTARGET=clang-static-cxxlto CC="clang -static -flto" CXX="clang++ -static -flto"
- name: ${{ format('Build clang LTO Debug with {0}', env.clang_package) }}
if: matrix.use_lto
run: |
make -C "upx with space" UPX_XTARGET=clang-static-cxxlto CC="clang -static -flto" CXX="clang++ -static -flto" xtarget/debug
- name: ${{ format('Build gcc LTO Release with {0}', env.gcc_package) }}
if: matrix.use_lto
run: |
make -C "upx with space" UPX_XTARGET=gcc-static-cxxlto CC="gcc -static -flto" CXX="g++ -static -flto"
- name: ${{ format('Build gcc LTO Debug with {0}', env.gcc_package) }}
if: matrix.use_lto
run: |
make -C "upx with space" UPX_XTARGET=gcc-static-cxxlto CC="gcc -static -flto" CXX="g++ -static -flto" 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 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)
- { name: 'Run basic tests clang Debug', run: 'make -C "upx with space"/build/xtarget/clang-static/debug test' }
- { name: 'Run basic tests clang Release', run: 'make -C "upx with space"/build/xtarget/clang-static/release test' }
- { name: 'Run basic tests gcc Debug', run: 'make -C "upx with space"/build/xtarget/gcc-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 C++20, C++23 and LTO'
if: matrix.use_cxx20 || matrix.use_cxx23 || matrix.use_cxx2b || matrix.use_lto
run: |
for dir in "upx with space"/build/xtarget/*-cxx*/*; do
echo "===== $dir"
make -C "$dir" test
done
- name: 'Run file system test suite (busybox)'
run: |
apk add bash sudo
testsuite="$(readlink -fn "upx with space"/misc/testsuite/test_symlinks.sh)"
cd "upx with space"/build/xtarget/gcc-static/release
# IMPORTANT: do NOT run as user root!
chmod a+w . && sudo -u upx bash "$testsuite"
# test suite
- name: ${{ format('Run test suite level {0}', env.UPX_TESTSUITE_LEVEL) }}
run: |
# testsuite needs bash and working "readlink -en" and "sha256sum -b"
apk add bash coreutils
# 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)"
(cd "upx with space"/build/xtarget/gcc-static/release && upx_exe=./upx bash "$testsuite_1")
- name: 'Run file system test suite (coreutils)'
run: |
apk add bash coreutils sudo
testsuite="$(readlink -fn "upx with space"/misc/testsuite/test_symlinks.sh)"
cd "upx with space"/build/xtarget/gcc-static/release
# IMPORTANT: do NOT run as user root!
chmod a+w . && sudo -u upx bash "$testsuite"
@@ -1,174 +0,0 @@
# Copyright (C) Markus Franz Xaver Johannes Oberhumer
# CC CompilationCheck: compile with various mingw-gcc versions and run tests under Wine
name: 'Weekly CI CC - Alpine Linux MinGW'
on:
schedule: [cron: '20 2 * * 3'] # run weekly Wednesday 02:20 UTC
workflow_dispatch:
env:
CMAKE_REQUIRED_QUIET: "OFF"
CTEST_OUTPUT_ON_FAILURE: "ON"
DEBIAN_FRONTEND: noninteractive
UPX_CMAKE_CONFIG_FLAGS: -DCMAKE_VERBOSE_MAKEFILE=ON
jobs:
job-alpine-mingw: # uses cmake + make
if: github.repository_owner == 'upx'
strategy:
fail-fast: false
matrix:
include:
- { container: 'alpine:3.11', wine: false, i686_mingw: false } # skip Wine testsuite; TODO: internal error: doctest check failed
- { container: 'alpine:3.12', wine: false, i686_mingw: false } # skip Wine testsuite; TODO: internal error: doctest check failed
- { container: 'alpine:3.13', wine: true, i686_mingw: false } # wine-4.0.3
- { container: 'alpine:3.14', wine: true, i686_mingw: false } # wine-6.18
- { container: 'alpine:3.15', wine: true, i686_mingw: false } # wine-6.23
- { container: 'alpine:3.16', wine: true, i686_mingw: false } # wine-7.8
- { container: 'alpine:3.17', wine: true, i686_mingw: false } # wine-7.21
# Wine >= 8.0 can run i686 32-bit programs in WOW64 mode on pure 64-bit systems
- { container: 'alpine:3.18', wine: true, i686_mingw: true } # wine-8.13
- { container: 'alpine:edge', wine: true, i686_mingw: true } # wine-8.17
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 cmake coreutils file git make tar xz
apk add mingw-w64-gcc
test "${{ matrix.i686_mingw }}" = "true" && apk add i686-mingw-w64-gcc
test "${{ matrix.wine }}" = "true" && apk add wine
true
- name: ${{ format('Check out UPX {0} source code', github.ref_name) }}
run: |
# this seems to be needed for Wine when running in a container (beause of UID mismatch??)
mkdir -p -v ~/.wine
# this seems to be needed when running in a container (beause of UID mismatch??)
git config --global --add safe.directory '*'
git clone --branch "$GITHUB_REF_NAME" --depth 1 https://github.com/upx/upx .
git submodule update --init
- name: 'Build cmake extra/cross-windows-mingw32/debug'
if: ${{ matrix.i686_mingw }}
run: 'make build/extra/cross-windows-mingw32/debug'
- name: 'Build cmake extra/cross-windows-mingw32/release'
if: ${{ matrix.i686_mingw }}
run: 'make build/extra/cross-windows-mingw32/release'
- name: 'Build cmake extra/cross-windows-mingw64/debug'
run: |
# on Alpine 3.11 and 3.12 CMake does not find AR; Alpine >= 3.13 (with CMake 3.18.4) works
X=
case ${{ matrix.container }} in
*:3.1[12]) X="CMAKE_AR=/usr/bin/x86_64-w64-mingw32-ar" ;;
esac
make build/extra/cross-windows-mingw64/debug $X
- name: 'Build cmake extra/cross-windows-mingw64/release'
run: |
# on Alpine 3.11 and 3.12 CMake does not find AR; Alpine >= 3.13 (with CMake 3.18.4) works
X=
case ${{ matrix.container }} in
*:3.1[12]) X="CMAKE_AR=/usr/bin/x86_64-w64-mingw32-ar" ;;
esac
make build/extra/cross-windows-mingw64/release $X
- name: 'Make artifact'
shell: bash
run: |
N=$(echo "upx-${GITHUB_REF_NAME}-${GITHUB_SHA:0:7}-weekly-ci-alpine-mingw-${{ matrix.container }}" | 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: ${{ format('Run test suite under Wine') }}
if: ${{ matrix.wine }}
run: |
git clone --depth=1 https://github.com/upx/upx-testsuite ../upx-testsuite
testsuite_1="$(readlink -fn ./misc/testsuite/upx_testsuite_1.sh)"
export upx_exe_runner="wine64"
if test "${{ matrix.i686_mingw }}" = "true"; then
UPX_TESTSUITE_LEVEL=2 \
env -C build/extra/cross-windows-mingw32/debug upx_exe=./upx.exe bash "$testsuite_1"
UPX_TESTSUITE_LEVEL=4 \
env -C build/extra/cross-windows-mingw32/release upx_exe=./upx.exe bash "$testsuite_1"
fi
UPX_TESTSUITE_LEVEL=2 \
env -C build/extra/cross-windows-mingw64/debug upx_exe=./upx.exe bash "$testsuite_1"
UPX_TESTSUITE_LEVEL=4 \
env -C build/extra/cross-windows-mingw64/release upx_exe=./upx.exe bash "$testsuite_1"
- name: 'Run basic tests under Wine - mingw32/debug'
if: ${{ matrix.wine && matrix.i686_mingw }}
shell: bash
run: |
set -ex -o pipefail
cd build/extra/cross-windows-mingw32/debug
[[ -f upx && ! -f upx.exe ]] && mv -i -v upx upx.exe
pwd; file ./upx.exe
wine=wine64
tt='./upx.exe'
$wine ./upx.exe --version-short
$wine ./upx.exe -3 $tt -o tt.packed.exe
$wine ./upx.exe -l tt.packed.exe
$wine ./upx.exe -t tt.packed.exe
$wine ./upx.exe -d tt.packed.exe -o tt.unpacked.exe
$wine ./tt.packed.exe --version-short
$wine ./tt.unpacked.exe --version-short
- name: 'Run basic tests under Wine - mingw32/release'
if: ${{ matrix.wine && matrix.i686_mingw }}
shell: bash
run: |
set -ex -o pipefail
cd build/extra/cross-windows-mingw32/release
[[ -f upx && ! -f upx.exe ]] && mv -i -v upx upx.exe
pwd; file ./upx.exe
wine=wine64
tt='./upx.exe'
$wine ./upx.exe --version-short
$wine ./upx.exe -3 $tt -o tt.packed.exe
$wine ./upx.exe -l tt.packed.exe
$wine ./upx.exe -t tt.packed.exe
$wine ./upx.exe -d tt.packed.exe -o tt.unpacked.exe
$wine ./tt.packed.exe --version-short
$wine ./tt.unpacked.exe --version-short
- name: 'Run basic tests under Wine - mingw64/debug'
if: ${{ matrix.wine }}
shell: bash
run: |
set -ex -o pipefail
cd build/extra/cross-windows-mingw64/debug
[[ -f upx && ! -f upx.exe ]] && mv -i -v upx upx.exe
pwd; file ./upx.exe
wine=wine64
tt='./upx.exe'
$wine ./upx.exe --version-short
$wine ./upx.exe -3 $tt -o tt.packed.exe
$wine ./upx.exe -l tt.packed.exe
$wine ./upx.exe -t tt.packed.exe
$wine ./upx.exe -d tt.packed.exe -o tt.unpacked.exe
$wine ./tt.packed.exe --version-short
$wine ./tt.unpacked.exe --version-short
- name: 'Run basic tests under Wine - mingw64/release'
if: ${{ matrix.wine }}
shell: bash
run: |
set -ex -o pipefail
cd build/extra/cross-windows-mingw64/release
[[ -f upx && ! -f upx.exe ]] && mv -i -v upx upx.exe
pwd; file ./upx.exe
wine=wine64
tt='./upx.exe'
$wine ./upx.exe --version-short
$wine ./upx.exe -3 $tt -o tt.packed.exe
$wine ./upx.exe -l tt.packed.exe
$wine ./upx.exe -t tt.packed.exe
$wine ./upx.exe -d tt.packed.exe -o tt.unpacked.exe
$wine ./tt.packed.exe --version-short
$wine ./tt.unpacked.exe --version-short
@@ -1,78 +0,0 @@
# Copyright (C) Markus Franz Xaver Johannes Oberhumer
# CC CompilationCheck: test llvm-mingw
# see https://github.com/mstorsjo/llvm-mingw
name: 'Weekly CI CC - llvm-mingw'
on:
schedule: [cron: '30 2 * * 3'] # run weekly Wednesday 02:30 UTC
workflow_dispatch:
env:
CMAKE_REQUIRED_QUIET: "OFF"
CTEST_OUTPUT_ON_FAILURE: "ON"
DEBIAN_FRONTEND: noninteractive
jobs:
job-llvm-mingw: # uses cmake + make
if: github.repository_owner == 'upx'
strategy:
fail-fast: false
matrix:
include:
- name: llvm-mingw-20230614-msvcrt
llvm_version: 16.0.6
url: 'https://github.com/mstorsjo/llvm-mingw/releases/download/20230614/llvm-mingw-20230614-msvcrt-ubuntu-20.04-x86_64.tar.xz'
- name: llvm-mingw-20230614-ucrt
llvm_version: 16.0.6
url: 'https://github.com/mstorsjo/llvm-mingw/releases/download/20230614/llvm-mingw-20230614-ucrt-ubuntu-20.04-x86_64.tar.xz'
- name: llvm-mingw-20231017-msvcrt
llvm_version: 17.0.3
url: 'https://github.com/mstorsjo/llvm-mingw/releases/download/20231017/llvm-mingw-20231017-msvcrt-ubuntu-20.04-x86_64.tar.xz'
- name: llvm-mingw-20231017-ucrt
llvm_version: 17.0.3
url: 'https://github.com/mstorsjo/llvm-mingw/releases/download/20231017/llvm-mingw-20231017-ucrt-ubuntu-20.04-x86_64.tar.xz'
name: ${{ format('{0} {1}', matrix.name, matrix.llvm_version) }}
runs-on: ubuntu-latest
steps:
- name: 'Check out code'
uses: actions/checkout@v4
with: { submodules: true }
- name: ${{ format('Install {0} {1}', matrix.name, matrix.llvm_version) }}
run: |
mkdir -p -v ~/.local/bin
cd ~/.local/bin
wget -q '${{ matrix.url }}'
ls -l ./llvm-mingw*.tar.*
tar -xoaf ./llvm-mingw*.tar.*
rm ./llvm-mingw*.tar.*
# update PATH
cd ./llvm-mingw*/bin
echo "PATH=$PWD:$PATH" >> $GITHUB_ENV
- name: 'Build clang aarch64'
run: |
export CC="aarch64-w64-mingw32-clang -static" CXX="aarch64-w64-mingw32-clang++ -static"
make UPX_XTARGET=aarch64-w64-mingw32-clang xtarget/debug xtarget/release
- name: 'Build clang armv7'
run: |
export CC="armv7-w64-mingw32-clang -static" CXX="armv7-w64-mingw32-clang++ -static"
make UPX_XTARGET=armv7-w64-mingw32-clang xtarget/debug xtarget/release
- name: 'Build clang i686'
run: |
export CC="i686-w64-mingw32-clang -static" CXX="i686-w64-mingw32-clang++ -static"
make UPX_XTARGET=i686-w64-mingw32-clang xtarget/debug xtarget/release
- name: 'Build clang x86_64'
run: |
export CC="x86_64-w64-mingw32-clang -static" CXX="x86_64-w64-mingw32-clang++ -static"
make UPX_XTARGET=x86_64-w64-mingw32-clang xtarget/debug xtarget/release
- name: 'Make artifact'
run: |
N=$(echo "upx-${GITHUB_REF_NAME}-${GITHUB_SHA:0:7}-weekly-ci-${{ matrix.name }}-${{ matrix.llvm_version }}" | 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
-129
View File
@@ -1,129 +0,0 @@
# Copyright (C) Markus Franz Xaver Johannes Oberhumer
# CC CompilationCheck: test zigcc
# build with "zig cc"; see https://ziglang.org/download/
name: 'Weekly CI CC - zigcc'
on:
schedule: [cron: '40 2 * * 3'] # run weekly Wednesday 02:40 UTC
workflow_dispatch:
env:
CMAKE_REQUIRED_QUIET: "OFF"
CTEST_OUTPUT_ON_FAILURE: "ON"
DEBIAN_FRONTEND: noninteractive
# 2023-10-24
ZIG_DIST_VERSION: 0.12.0-dev.1245+a07f288eb
jobs:
job-linux-zigcc: # uses cmake + make
if: github.repository_owner == 'upx'
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-linux-musl, zig_pic: -fPIE }
- { 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 }
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
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@v4
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)
-116
View File
@@ -1,116 +0,0 @@
# Copyright (C) Markus Franz Xaver Johannes Oberhumer
# RT RunTime checks
# runs ASAN, MSAN, qemu and valgrind checkers; slow!
name: 'Weekly CI RT - ASAN MSAN Valgrind'
on:
schedule: [cron: '00 3 * * 3'] # run weekly Wednesday 03:00 UTC
workflow_dispatch:
env:
CMAKE_REQUIRED_QUIET: "OFF"
CTEST_OUTPUT_ON_FAILURE: "ON"
DEBIAN_FRONTEND: noninteractive
jobs:
job-runtime-checkers: # uses cmake + make
if: github.repository_owner == 'upx'
strategy:
fail-fast: false
matrix:
include:
- container: 'alpine:3.18'
release: debug
qemu: 'qemu-x86_64 -cpu Westmere'
- container: 'alpine:3.18'
release: release
qemu: 'qemu-x86_64 -cpu Westmere'
- container: 'alpine:edge'
release: release
qemu: 'qemu-x86_64 -cpu Westmere'
- container: 'i386/alpine:edge'
release: release
qemu: 'qemu-i386'
name: ${{ format('{0} {1}', matrix.container, matrix.release) }}
runs-on: ubuntu-latest
container: ${{ matrix.container }}
env:
release: ${{ matrix.release }}
steps:
- name: ${{ format('Install packages {0} {1}', matrix.container, matrix.release) }}
run: |
apk update && apk upgrade
apk add bash clang cmake compiler-rt coreutils g++ git make qemu-i386 qemu-x86_64 tar valgrind
# this seems to be needed when running in a container (beause of UID mismatch??)
git config --global --add safe.directory '*'
- 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 submodule update --init
git clone --depth=1 https://github.com/upx/upx-testsuite ../upx-testsuite
- name: 'Build clang-static'
run: |
export CC="clang -static" CXX="clang++ -static"
make UPX_XTARGET=clang-static xtarget/$release
- name: 'Build clang-asan'
if: ${{ !startsWith(matrix.container, 'i386/') }} # i386: ASAN not supported
run: |
# unfortunately ASAN does not support static linking
flags="-fsanitize=address -fsanitize=pointer-compare -fsanitize=pointer-subtract -fsanitize=undefined -fno-omit-frame-pointer"
export CC="clang $flags" CXX="clang++ $flags"
make UPX_XTARGET=clang-asan xtarget/$release
- name: 'Build clang-msan'
if: ${{ !startsWith(matrix.container, 'i386/') }} # i386: MSAN not supported
run: |
# unfortunately MSAN does not support static linking
flags="-fsanitize=memory -fsanitize=undefined -fno-omit-frame-pointer -DDOCTEST_CONFIG_DISABLE=1"
export CC="clang $flags" CXX="clang++ $flags"
make UPX_XTARGET=clang-msan xtarget/$release
- name: 'Make artifact'
run: |
N=$(echo "upx-${GITHUB_REF_NAME}-${GITHUB_SHA:0:7}-weekly-ci-runtime-checkers-${{ matrix.container }}-${{ matrix.release }}" | sed 's/[^0-9a-zA-Z_.-]/-/g')
mkdir -p "tmp/artifact/$N"
(cd build && cp -ai --parents */*/*/upx "../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) }}
if: ${{ !startsWith(matrix.container, 'i386/') }} # i386: missing nodejs on host
uses: actions/upload-artifact@v3
with:
name: ${{ env.artifact_name }}
path: tmp/artifact
- name: 'Run basic tests clang-static'
run: 'make -C build/xtarget/clang-static/$release test'
- name: 'Run basic tests clang-asan'
if: ${{ !startsWith(matrix.container, 'i386/') }} # i386: ASAN not supported
run: 'make -C build/xtarget/clang-asan/$release test'
- name: 'Run basic tests clang-msan'
if: ${{ !startsWith(matrix.container, 'i386/') }} # i386: MSAN not supported
run: 'make -C build/xtarget/clang-msan/$release test'
- name: 'Run testsuite clang-asan'
if: ${{ !startsWith(matrix.container, 'i386/') }} # i386: ASAN not supported
run: |
export ASAN_OPTIONS="detect_invalid_pointer_pairs=2"
env -C build/xtarget/clang-asan/$release "$PWD"/misc/testsuite/upx_testsuite_1.sh
- name: 'Run testsuite clang-msan'
if: ${{ !startsWith(matrix.container, 'i386/') }} # i386: MSAN not supported
run: |
env -C build/xtarget/clang-msan/$release "$PWD"/misc/testsuite/upx_testsuite_1.sh
- name: 'Run testsuite clang-static - QEMU'
if: ${{ matrix.qemu }}
run: |
export upx_exe_runner="${{ matrix.qemu }}"
env -C build/xtarget/clang-static/$release "$PWD"/misc/testsuite/upx_testsuite_1.sh
- name: 'Run testsuite clang-static - Valgrind'
if: true # very slow
run: |
export upx_exe_runner="valgrind --error-exitcode=1 --quiet"
# on current GitHub CI, takes about 30 minutes for release and 80 minutes for debug builds
# reduce time for debug builds to about 30 minutes
test "$release" = "debug" && export UPX_TESTSUITE_LEVEL=4
env -C build/xtarget/clang-static/$release "$PWD"/misc/testsuite/upx_testsuite_1.sh
+3 -2
View File
@@ -1,6 +1,6 @@
/.hg* /.hg*
/.vscode* /.vscode*
/Makevars.global* /Makevars[.-]global*
/Testing* /Testing*
/build* /build*
/maint* /maint*
@@ -8,7 +8,7 @@
GNUmakefile* GNUmakefile*
MMakefile* MMakefile*
Makevars.local* Makevars[.-]local*
compile_flags*.txt compile_flags*.txt
Tmp* Tmp*
tmp* tmp*
@@ -16,6 +16,7 @@ tmp*
*.a *.a
*.bz2 *.bz2
*.d *.d
*.diff
*.dll *.dll
*.dylib *.dylib
*.exe *.exe
+145 -233
View File
@@ -7,76 +7,70 @@
# A C++ compiler that fully implements 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)
# Sections of this CMakeLists.txt:
# - options
# - init
# - common compilation flags
# - targets
# - target compilation flags
# - test
# - install
# - print summary
# CMake version check; using a somewhat current CMake version is highly recommended # CMake version check; using a somewhat current CMake version is highly recommended
file(REMOVE "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/.upx_cmake_config_done.txt")
if(DEFINED UPX_CONFIG_CMAKE_MINIMUM_REQUIRED_VERSION) if(DEFINED UPX_CONFIG_CMAKE_MINIMUM_REQUIRED_VERSION)
cmake_minimum_required(VERSION "${UPX_CONFIG_CMAKE_MINIMUM_REQUIRED_VERSION}" FATAL_ERROR) cmake_minimum_required(VERSION "${UPX_CONFIG_CMAKE_MINIMUM_REQUIRED_VERSION}" FATAL_ERROR)
else() else()
cmake_minimum_required(VERSION 3.8 FATAL_ERROR) # CMake >= 3.8 is needed for CXX_STANDARD 17 cmake_minimum_required(VERSION "3.8" FATAL_ERROR) # CMake >= 3.8 is needed for CXX_STANDARD 17
endif() endif()
# support functions and some utility
include("${CMAKE_CURRENT_SOURCE_DIR}/misc/cmake/functions.cmake")
#***********************************************************************
# options
#***********************************************************************
upx_cmake_include_hook(1_options)
# compilation config options # compilation config options
if(NOT IS_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/.git") if(NOT USE_STRICT_DEFAULTS)
# 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 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 sanitize options." ON)
option(UPX_CONFIG_DISABLE_WERROR "Do not compile with -Werror option." ON)
option(UPX_CONFIG_DISABLE_WSTRICT "Do not compile with strict compiler warnings." 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)
else() else()
# strict config defaults for Git developer 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 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 sanitize options." OFF)
option(UPX_CONFIG_DISABLE_WERROR "Do not compile with -Werror option." OFF)
option(UPX_CONFIG_DISABLE_WSTRICT "Do not compile with strict compiler warnings." 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)
endif() endif()
# test config options (see below) # test config options (see below)
# IMPORTANT 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)
option(UPX_CONFIG_DISABLE_EXHAUSTIVE_TESTS "Do not run exhaustive tests" OFF)
#*********************************************************************** #***********************************************************************
# init # init
#*********************************************************************** #***********************************************************************
# Disallow in-source builds. Note that you will still have to manually set(UPX_VERSION_STRING "4.2.4") # this should match src/version.h
upx_cmake_include_hook(2_init)
# Disallow in-source build. 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(IS_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/.git") if(IS_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/.git")
set(CMAKE_DISABLE_IN_SOURCE_BUILD ON) upx_disallow_in_source_build()
set(CMAKE_DISABLE_SOURCE_CHANGES ON)
if(",${CMAKE_CURRENT_SOURCE_DIR}," STREQUAL ",${CMAKE_CURRENT_BINARY_DIR},")
message(FATAL_ERROR "ERROR: In-source builds are not allowed, please use an extra build dir.")
endif()
endif() endif()
# 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}) # cached
set(value "${UPX_CACHE_${var}}")
elseif(DEFINED ${var}) # defined via "cmake -DXXX=YYY"
set(value "${${var}}")
elseif("$ENV{${var}}" MATCHES "^(0|1|OFF|ON|FALSE|TRUE)$") # environment
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 # global settings
if(${CMAKE_VERSION} VERSION_GREATER "3.14.7" AND NOT DEFINED CMAKE_MSVC_RUNTIME_LIBRARY) if(${CMAKE_VERSION} VERSION_GREATER "3.14.99" AND NOT DEFINED CMAKE_MSVC_RUNTIME_LIBRARY)
set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded") set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded")
cmake_policy(SET CMP0091 NEW) cmake_policy(SET CMP0091 NEW)
endif() endif()
@@ -85,12 +79,16 @@ upx_cache_bool_vars(ON
CMAKE_C_STANDARD_REQUIRED CMAKE_CXX_STANDARD_REQUIRED CMAKE_C_STANDARD_REQUIRED CMAKE_CXX_STANDARD_REQUIRED
CMAKE_EXPORT_COMPILE_COMMANDS CMAKE_REQUIRED_QUIET CMAKE_EXPORT_COMPILE_COMMANDS CMAKE_REQUIRED_QUIET
) )
# internal UPX settings that default to OFF # internal UPX settings
upx_cache_bool_vars(OFF upx_cache_bool_vars(OFF
UPX_CONFIG_CMAKE_DISABLE_TEST UPX_CONFIG_CMAKE_DISABLE_INSTALL UPX_CONFIG_CMAKE_DISABLE_TEST UPX_CONFIG_CMAKE_DISABLE_INSTALL
UPX_CONFIG_CMAKE_DISABLE_PRINT_INFO UPX_CONFIG_CMAKE_DISABLE_PLATFORM_CHECK UPX_CONFIG_CMAKE_DISABLE_PRINT_INFO UPX_CONFIG_CMAKE_DISABLE_PLATFORM_CHECK
UPX_CONFIG_DISABLE_C_STANDARD UPX_CONFIG_DISABLE_CXX_STANDARD UPX_CONFIG_DISABLE_C_STANDARD UPX_CONFIG_DISABLE_CXX_STANDARD
UPX_CONFIG_DISABLE_RUN_UNPACKED_TEST UPX_CONFIG_DISABLE_RUN_PACKED_TEST
UPX_CONFIG_REQUIRE_THREADS
) )
upx_cache_bool_vars(ON UPX_CONFIG_EXPECT_THREADS)
upx_print_env_var(CC CXX)
# determine Git revision # determine Git revision
set(GITREV_SHORT "") set(GITREV_SHORT "")
@@ -134,30 +132,16 @@ else()
message(STATUS "UPX_VERSION_GITREV: not set") message(STATUS "UPX_VERSION_GITREV: not set")
endif() endif()
# set the default build type to "Release"
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 # CMake init
project(upx VERSION 4.2.0 LANGUAGES C CXX) upx_set_default_build_type(Release) # default is CMAKE_BUILD_TYPE=Release
project(upx VERSION "${UPX_VERSION_STRING}" LANGUAGES C CXX)
upx_apply_build_type()
# set the default multi-config build type to "Release" # set MSVC_FRONTEND, GNU_FRONTEND and MINGW
if(is_multi_config)
set(c "${CMAKE_CONFIGURATION_TYPES}")
list(INSERT c 0 "Release")
list(INSERT c 1 "Debug")
if(CMAKE_BUILD_TYPE)
list(INSERT c 0 "${CMAKE_BUILD_TYPE}")
endif()
list(REMOVE_DUPLICATES c)
set(CMAKE_CONFIGURATION_TYPES "${c}" CACHE STRING "List of supported configuration types." FORCE)
endif()
# set MSVC_FRONTEND and MINGW
if(NOT DEFINED MSVC_FRONTEND AND (MSVC OR CMAKE_C_COMPILER_FRONTEND_VARIANT MATCHES "^MSVC")) if(NOT DEFINED MSVC_FRONTEND AND (MSVC OR CMAKE_C_COMPILER_FRONTEND_VARIANT MATCHES "^MSVC"))
set(MSVC_FRONTEND 1) set(MSVC_FRONTEND 1)
elseif (NOT DEFINED GNU_FRONTEND AND (CMAKE_C_COMPILER_FRONTEND_VARIANT MATCHES "^GNU" OR CMAKE_C_COMPILER_ID MATCHES "(Clang|GNU)"))
set(GNU_FRONTEND 1)
endif() endif()
if(NOT DEFINED MINGW AND CMAKE_C_PLATFORM_ID MATCHES "^MinGW") if(NOT DEFINED MINGW AND CMAKE_C_PLATFORM_ID MATCHES "^MinGW")
set(MINGW 1) set(MINGW 1)
@@ -173,17 +157,20 @@ include(CheckIncludeFile)
include(CheckStructHasMember) include(CheckStructHasMember)
include(CheckSymbolExists) include(CheckSymbolExists)
upx_cmake_include_hook(3_common_compilation_flags)
if(NOT DEFINED HAVE_UNISTD_H) if(NOT DEFINED HAVE_UNISTD_H)
check_include_file("unistd.h" HAVE_UNISTD_H) check_include_file("unistd.h" HAVE_UNISTD_H)
endif() endif()
if(NOT DEFINED HAVE_UTIMENSAT) if(NOT DEFINED HAVE_UTIMENSAT)
# proper checking for utimensat() is somewhat messy
check_function_exists(utimensat HAVE_UTIMENSAT_FUNCTION__) check_function_exists(utimensat HAVE_UTIMENSAT_FUNCTION__)
if(HAVE_UTIMENSAT_FUNCTION__) if(HAVE_UTIMENSAT_FUNCTION__)
check_symbol_exists(utimensat "sys/types.h;fcntl.h;sys/stat.h" HAVE_UTIMENSAT_SYMBOL__) check_symbol_exists(utimensat "sys/types.h;fcntl.h;sys/stat.h" HAVE_UTIMENSAT_SYMBOL__)
if(HAVE_UTIMENSAT_SYMBOL__) if(HAVE_UTIMENSAT_SYMBOL__)
CHECK_STRUCT_HAS_MEMBER("struct stat" "st_mtim.tv_nsec" "sys/types.h;fcntl.h;sys/stat.h" HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC) CHECK_STRUCT_HAS_MEMBER("struct stat" "st_mtim.tv_nsec" "sys/types.h;fcntl.h;sys/stat.h" HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC) # POSIX.1-2008
if(NOT HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC) if(NOT HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC)
CHECK_STRUCT_HAS_MEMBER("struct stat" "st_mtimespec.tv_nsec" "sys/types.h;fcntl.h;sys/stat.h" HAVE_STRUCT_STAT_ST_MTIMESPEC_TV_NSEC) CHECK_STRUCT_HAS_MEMBER("struct stat" "st_mtimespec.tv_nsec" "sys/types.h;fcntl.h;sys/stat.h" HAVE_STRUCT_STAT_ST_MTIMESPEC_TV_NSEC) # macOS
endif() endif()
if(HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC OR HAVE_STRUCT_STAT_ST_MTIMESPEC_TV_NSEC) if(HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC OR HAVE_STRUCT_STAT_ST_MTIMESPEC_TV_NSEC)
set(HAVE_UTIMENSAT 1) set(HAVE_UTIMENSAT 1)
@@ -215,38 +202,6 @@ if(MSVC_FRONTEND)
set(warn_WX -wd5105 ${warn_WX}) set(warn_WX -wd5105 ${warn_WX})
endif() endif()
function(upx_add_definitions_with_prefix)
set(flag_prefix "${ARGV0}")
if(flag_prefix MATCHES "^empty$") # need "empty" 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("empty" ${failed_flags})
else()
upx_add_definitions_with_prefix("empty" ${ARGV})
endif()
endfunction()
if(NOT CMAKE_C_COMPILER_ID MATCHES "^MSVC") 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}")
@@ -261,6 +216,7 @@ if(MSVC_FRONTEND OR WIN32 OR MINGW OR CYGWIN)
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)
add_definitions(-DWIN32_LEAN_AND_MEAN) add_definitions(-DWIN32_LEAN_AND_MEAN)
add_definitions(-D__USE_MINGW_ANSI_STDIO)
endif() endif()
if(MSVC_FRONTEND) if(MSVC_FRONTEND)
# use -funsigned-char; set __cplusplus according to selected C++ standard # use -funsigned-char; set __cplusplus according to selected C++ standard
@@ -281,65 +237,11 @@ if(NOT CMAKE_C_COMPILER_ID MATCHES "^MSVC")
endif() endif()
endif() endif()
# compile a source file with -O2 even in Debug build # examine compiler configuration
function(upx_compile_source_debug_with_O2) if(NOT UPX_CONFIG_CMAKE_DISABLE_PRINT_INFO)
set(flags "$<$<CONFIG:Debug>:-O2>") upx_print_common_symbols()
if (CMAKE_VERSION VERSION_LESS 3.8) upx_print_mingw_symbols()
# 3.8: The COMPILE_FLAGS source file property learned to support generator expressions endif()
if (is_multi_config OR NOT CMAKE_BUILD_TYPE MATCHES "^Debug$")
return()
endif()
set(flags "-O2")
endif()
if(CMAKE_GENERATOR MATCHES "Xcode") # multi-config
# NOTE: Xcode does not support per-config per-source COMPILE_FLAGS (as of CMake 3.27.7)
return()
endif()
foreach(t ${ARGV})
if(MSVC_FRONTEND)
# MSVC uses some Debug compilation options like -RTC1 that are incompatible with -O2
else()
get_source_file_property(prop ${t} COMPILE_FLAGS)
if(prop MATCHES "^(NOTFOUND)?$")
set_source_files_properties(${t} PROPERTIES COMPILE_FLAGS "${flags}")
else()
set_source_files_properties(${t} PROPERTIES COMPILE_FLAGS "${prop} ${flags}")
endif()
endif()
endforeach()
endfunction()
# compile a target with -O2 even in Debug build
function(upx_compile_target_debug_with_O2)
foreach(t ${ARGV})
if(MSVC_FRONTEND)
# MSVC uses some Debug compilation options like -RTC1 that are incompatible with -O2
else()
target_compile_options(${t} PRIVATE $<$<CONFIG:Debug>:-O2>)
endif()
endforeach()
endfunction()
# sanitize a target
function(upx_sanitize_target)
foreach(t ${ARGV})
if(UPX_CONFIG_DISABLE_SANITIZE)
# no-op
elseif(MSVC_FRONTEND)
# MSVC uses -GS (similar to -fstack-protector) by default
elseif(MINGW OR CYGWIN)
# avoid link errors with current MinGW-w64 versions
# see https://www.mingw-w64.org/contribute/#sanitizers-asan-tsan-usan
else()
# default sanitizer for Debug builds
target_compile_options(${t} PRIVATE $<$<CONFIG:Debug>:-fsanitize=undefined -fsanitize-undefined-trap-on-error -fstack-protector-all>)
# default sanitizer for Release builds
target_compile_options(${t} PRIVATE $<$<CONFIG:MinSizeRel>:-fstack-protector>)
target_compile_options(${t} PRIVATE $<$<CONFIG:Release>:-fstack-protector>)
target_compile_options(${t} PRIVATE $<$<CONFIG:RelWithDebInfo>:-fstack-protector>)
endif()
endforeach()
endfunction()
#*********************************************************************** #***********************************************************************
# targets # targets
@@ -350,44 +252,62 @@ set(UPX_CONFIG_DISABLE_THREADS ON) # multithreading is currently not used; maybe
set(UPX_CONFIG_DISABLE_BZIP2 ON) # bzip2 is currently not used; we might need it to decompress linux kernels 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 set(UPX_CONFIG_DISABLE_ZSTD ON) # zstd is currently not used; maybe in UPX version 5
upx_cmake_include_hook(4_targets)
if(NOT UPX_CONFIG_DISABLE_THREADS) if(NOT UPX_CONFIG_DISABLE_THREADS)
find_package(Threads) find_package(Threads)
endif() endif()
# make sure that threads are indeed fully supported in C++
if(Threads_FOUND)
foreach(f std_lock_guard.cpp types_abi.cpp)
set(CMAKE_TRY_COMPILE_TARGET_TYPE "EXECUTABLE")
if(NOT UPX_CONFIG_DISABLE_CXX_STANDARD)
try_compile(result "${CMAKE_CURRENT_BINARY_DIR}"
"${CMAKE_CURRENT_SOURCE_DIR}/misc/cmake/try_compile/${f}"
OUTPUT_VARIABLE output CXX_STANDARD 17)
else()
try_compile(result "${CMAKE_CURRENT_BINARY_DIR}"
"${CMAKE_CURRENT_SOURCE_DIR}/misc/cmake/try_compile/${f}"
OUTPUT_VARIABLE output)
endif()
if(NOT result)
# failed; under MinGW be sure to use the posix-threads and NOT the win32-threads version
#message(STATUS "Threads FAILED ${f}: ${output}") # debug output from try_compile
set(Threads_FOUND OFF)
break()
endif()
endforeach()
endif()
if(NOT UPX_CONFIG_DISABLE_BZIP2) if(NOT UPX_CONFIG_DISABLE_BZIP2)
file(GLOB bzip2_SOURCES "vendor/bzip2/*.c") upx_add_glob_files(bzip2_SOURCES "vendor/bzip2/*.c")
list(SORT bzip2_SOURCES)
add_library(upx_vendor_bzip2 STATIC ${bzip2_SOURCES}) add_library(upx_vendor_bzip2 STATIC ${bzip2_SOURCES})
if(NOT UPX_CONFIG_DISABLE_C_STANDARD) if(NOT UPX_CONFIG_DISABLE_C_STANDARD)
set_property(TARGET upx_vendor_bzip2 PROPERTY C_STANDARD 11) set_property(TARGET upx_vendor_bzip2 PROPERTY C_STANDARD 11)
endif() endif()
endif() # UPX_CONFIG_DISABLE_BZIP2 endif() # UPX_CONFIG_DISABLE_BZIP2
file(GLOB ucl_SOURCES "vendor/ucl/src/*.c") upx_add_glob_files(ucl_SOURCES "vendor/ucl/src/*.c")
list(SORT ucl_SOURCES)
add_library(upx_vendor_ucl STATIC ${ucl_SOURCES}) add_library(upx_vendor_ucl STATIC ${ucl_SOURCES})
if(NOT UPX_CONFIG_DISABLE_C_STANDARD) if(NOT UPX_CONFIG_DISABLE_C_STANDARD)
set_property(TARGET upx_vendor_ucl PROPERTY C_STANDARD 11) set_property(TARGET upx_vendor_ucl PROPERTY C_STANDARD 11)
endif() endif()
file(GLOB zlib_SOURCES "vendor/zlib/*.c") upx_add_glob_files(zlib_SOURCES "vendor/zlib/*.c")
list(SORT zlib_SOURCES)
add_library(upx_vendor_zlib STATIC ${zlib_SOURCES}) add_library(upx_vendor_zlib STATIC ${zlib_SOURCES})
if(NOT UPX_CONFIG_DISABLE_C_STANDARD) if(NOT UPX_CONFIG_DISABLE_C_STANDARD)
set_property(TARGET upx_vendor_zlib PROPERTY C_STANDARD 11) set_property(TARGET upx_vendor_zlib PROPERTY C_STANDARD 11)
endif() endif()
if(NOT UPX_CONFIG_DISABLE_ZSTD) if(NOT UPX_CONFIG_DISABLE_ZSTD)
file(GLOB zstd_SOURCES "vendor/zstd/lib/*/*.c") upx_add_glob_files(zstd_SOURCES "vendor/zstd/lib/*/*.c")
list(SORT zstd_SOURCES)
add_library(upx_vendor_zstd STATIC ${zstd_SOURCES}) add_library(upx_vendor_zstd STATIC ${zstd_SOURCES})
if(NOT UPX_CONFIG_DISABLE_C_STANDARD) if(NOT UPX_CONFIG_DISABLE_C_STANDARD)
set_property(TARGET upx_vendor_zstd PROPERTY C_STANDARD 11) set_property(TARGET upx_vendor_zstd PROPERTY C_STANDARD 11)
endif() endif()
endif() # UPX_CONFIG_DISABLE_ZSTD endif() # UPX_CONFIG_DISABLE_ZSTD
file(GLOB upx_SOURCES "src/*.cpp" "src/[cfu]*/*.cpp") upx_add_glob_files(upx_SOURCES "src/*.cpp" "src/[cfu]*/*.cpp")
list(SORT upx_SOURCES)
add_executable(upx ${upx_SOURCES}) add_executable(upx ${upx_SOURCES})
if(NOT UPX_CONFIG_DISABLE_CXX_STANDARD) if(NOT UPX_CONFIG_DISABLE_CXX_STANDARD)
set_property(TARGET upx PROPERTY CXX_STANDARD 17) set_property(TARGET upx PROPERTY CXX_STANDARD 17)
@@ -407,15 +327,19 @@ endif()
# target compilation flags # target compilation flags
#*********************************************************************** #***********************************************************************
upx_cmake_include_hook(5_target_compilation_flags)
if(NOT UPX_CONFIG_DISABLE_BZIP2) if(NOT UPX_CONFIG_DISABLE_BZIP2)
set(t upx_vendor_bzip2) set(t upx_vendor_bzip2)
upx_compile_target_debug_with_O2(${t}) upx_compile_target_debug_with_O2(${t})
upx_sanitize_target(${t}) upx_sanitize_target(${t})
target_compile_definitions(${t} PRIVATE BZ_NO_STDIO=1)
if(MSVC_FRONTEND) if(MSVC_FRONTEND)
target_compile_options(${t} PRIVATE ${warn_WN} -wd4127 -wd4244 -wd4267 ${warn_WX}) target_compile_options(${t} PRIVATE ${warn_WN} -wd4127 -wd4244 -wd4267 ${warn_WX})
else() elseif(GNU_FRONTEND)
target_compile_options(${t} PRIVATE ${warn_Wall} -Wno-implicit-fallthrough ${warn_Werror}) target_compile_options(${t} PRIVATE ${warn_Wall} ${warn_Werror})
endif() endif()
upx_add_target_extra_compile_options(${t} UPX_CONFIG_EXTRA_COMPILE_OPTIONS_BZIP2)
endif() # UPX_CONFIG_DISABLE_BZIP2 endif() # UPX_CONFIG_DISABLE_BZIP2
set(t upx_vendor_ucl) set(t upx_vendor_ucl)
@@ -424,9 +348,10 @@ upx_compile_target_debug_with_O2(${t})
upx_sanitize_target(${t}) upx_sanitize_target(${t})
if(MSVC_FRONTEND) if(MSVC_FRONTEND)
target_compile_options(${t} PRIVATE ${warn_WN} ${warn_WX}) target_compile_options(${t} PRIVATE ${warn_WN} ${warn_WX})
else() elseif(GNU_FRONTEND)
target_compile_options(${t} PRIVATE ${warn_Wall} ${warn_Werror}) target_compile_options(${t} PRIVATE ${warn_Wall} ${warn_Werror})
endif() endif()
upx_add_target_extra_compile_options(${t} UPX_CONFIG_EXTRA_COMPILE_OPTIONS_UCL)
set(t upx_vendor_zlib) set(t upx_vendor_zlib)
upx_compile_target_debug_with_O2(${t}) upx_compile_target_debug_with_O2(${t})
@@ -437,10 +362,10 @@ if(HAVE_UNISTD_H)
endif() endif()
if(MSVC_FRONTEND) if(MSVC_FRONTEND)
target_compile_options(${t} PRIVATE -W3 ${warn_WX}) target_compile_options(${t} PRIVATE -W3 ${warn_WX})
else() elseif(GNU_FRONTEND)
target_compile_options(${t} PRIVATE -Wall ${warn_Werror}) target_compile_options(${t} PRIVATE ${warn_Wall} -Wno-cast-align -Wno-cast-qual ${warn_Werror})
##target_compile_options(${t} PRIVATE ${warn_Wall} -Wno-cast-align -Wno-cast-qual ${warn_Werror})
endif() endif()
upx_add_target_extra_compile_options(${t} UPX_CONFIG_EXTRA_COMPILE_OPTIONS_ZLIB)
if(NOT UPX_CONFIG_DISABLE_ZSTD) if(NOT UPX_CONFIG_DISABLE_ZSTD)
set(t upx_vendor_zstd) set(t upx_vendor_zstd)
@@ -449,9 +374,10 @@ upx_sanitize_target(${t})
target_compile_definitions(${t} PRIVATE DYNAMIC_BMI2=0 ZSTD_DISABLE_ASM=1) target_compile_definitions(${t} PRIVATE DYNAMIC_BMI2=0 ZSTD_DISABLE_ASM=1)
if(MSVC_FRONTEND) if(MSVC_FRONTEND)
target_compile_options(${t} PRIVATE ${warn_WN} ${warn_WX}) target_compile_options(${t} PRIVATE ${warn_WN} ${warn_WX})
else() elseif(GNU_FRONTEND)
target_compile_options(${t} PRIVATE ${warn_Wall} ${warn_Werror}) target_compile_options(${t} PRIVATE ${warn_Wall} ${warn_Werror})
endif() endif()
upx_add_target_extra_compile_options(${t} UPX_CONFIG_EXTRA_COMPILE_OPTIONS_ZSTD)
endif() # UPX_CONFIG_DISABLE_ZSTD endif() # UPX_CONFIG_DISABLE_ZSTD
set(t upx) set(t upx)
@@ -473,7 +399,7 @@ if(NOT UPX_CONFIG_DISABLE_WERROR)
target_compile_definitions(${t} PRIVATE UPX_CONFIG_DISABLE_WERROR=0) target_compile_definitions(${t} PRIVATE UPX_CONFIG_DISABLE_WERROR=0)
endif() endif()
if(NOT UPX_CONFIG_DISABLE_BZIP2) if(NOT UPX_CONFIG_DISABLE_BZIP2)
target_compile_definitions(${t} PRIVATE WITH_BZIP2=0) # FIXME TODO target_compile_definitions(${t} PRIVATE WITH_BZIP2=1)
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)
@@ -484,63 +410,58 @@ if(HAVE_UTIMENSAT)
target_compile_definitions(${t} PRIVATE HAVE_STRUCT_STAT_ST_MTIMESPEC_TV_NSEC=1) target_compile_definitions(${t} PRIVATE HAVE_STRUCT_STAT_ST_MTIMESPEC_TV_NSEC=1)
endif() endif()
endif() endif()
# improve speed of the debug versions # improve speed of the Debug versions
upx_compile_source_debug_with_O2(src/compress/compress_lzma.cpp) upx_compile_source_debug_with_O2(src/compress/compress_lzma.cpp)
upx_compile_source_debug_with_O2(src/filter/filter_impl.cpp) upx_compile_source_debug_with_O2(src/filter/filter_impl.cpp)
#upx_compile_target_debug_with_O2(${t}) #upx_compile_target_debug_with_O2(${t})
upx_sanitize_target(${t}) upx_sanitize_target(${t})
if(MSVC_FRONTEND) if(MSVC_FRONTEND)
target_compile_options(${t} PRIVATE -EHsc ${warn_WN} ${warn_WX}) target_compile_options(${t} PRIVATE -EHsc ${warn_WN} ${warn_WX})
else() elseif(GNU_FRONTEND)
target_compile_options(${t} PRIVATE ${warn_Wall} ${warn_Werror}) target_compile_options(${t} PRIVATE ${warn_Wall} ${warn_Werror})
endif() endif()
upx_add_target_extra_compile_options(${t} UPX_CONFIG_EXTRA_COMPILE_OPTIONS_UPX)
#*********************************************************************** #***********************************************************************
# test
# ctest # ctest
# make test # make test
# ninja test # ninja test
#*********************************************************************** #***********************************************************************
upx_cmake_include_hook(6_test)
if(NOT UPX_CONFIG_CMAKE_DISABLE_TEST) if(NOT UPX_CONFIG_CMAKE_DISABLE_TEST)
include(CTest) include(CTest)
# TODO later: check CMAKE_CROSSCOMPILING_EMULATOR if(NOT CMAKE_CROSSCOMPILING OR CMAKE_CROSSCOMPILING_EMULATOR)
if(NOT CMAKE_CROSSCOMPILING) upx_add_test(upx-version upx --version)
add_test(NAME upx-version COMMAND upx --version) upx_add_test(upx-version-short upx --version-short)
add_test(NAME upx-help COMMAND upx --help) upx_add_test(upx-license upx --license)
endif() upx_add_test(upx-help-1 upx --help)
if(NOT CMAKE_CROSSCOMPILING AND NOT UPX_CONFIG_DISABLE_SELF_PACK_TEST) upx_add_test(upx-help-2 upx --help-short)
# IMPORTANT NOTE: these tests can only work if the host executable format is supported by UPX! upx_add_test(upx-help-3 upx --help-verbose)
function(upx_add_test) upx_add_test(upx-sysinfo-1 upx --sysinfo)
set(name "${ARGV0}") upx_add_test(upx-sysinfo-2 upx --sysinfo -v)
list(REMOVE_AT ARGV 0) upx_add_test(upx-sysinfo-3 upx --sysinfo -vv)
add_test(NAME "${name}" COMMAND ${ARGV}) if(NOT UPX_CONFIG_DISABLE_SELF_PACK_TEST)
set_tests_properties("${name}" PROPERTIES RUN_SERIAL TRUE) # run these tests sequentially # IMPORTANT NOTE: these tests can only work if the host executable format
endfunction() # is supported by UPX!
set(exe ${CMAKE_EXECUTABLE_SUFFIX}) include("${CMAKE_CURRENT_SOURCE_DIR}/misc/cmake/self_pack_test.cmake")
set(upx_self_exe "$<TARGET_FILE:upx>") endif()
set(fo "--force-overwrite")
upx_add_test(upx-self-pack upx -3 "${upx_self_exe}" ${fo} -o upx-packed${exe})
upx_add_test(upx-self-pack-n2b upx -3 --nrv2b "${upx_self_exe}" ${fo} -o upx-packed-n2b${exe})
upx_add_test(upx-self-pack-n2d upx -3 --nrv2d "${upx_self_exe}" ${fo} -o upx-packed-n2d${exe})
upx_add_test(upx-self-pack-n2e upx -3 --nrv2e "${upx_self_exe}" ${fo} -o upx-packed-n2e${exe})
upx_add_test(upx-self-pack-lzma upx -1 --lzma "${upx_self_exe}" ${fo} -o upx-packed-lzma${exe})
upx_add_test(upx-list upx -l upx-packed${exe} upx-packed-n2b${exe} upx-packed-n2d${exe} upx-packed-n2e${exe} upx-packed-lzma${exe})
upx_add_test(upx-fileinfo upx --fileinfo upx-packed${exe} upx-packed-n2b${exe} upx-packed-n2d${exe} upx-packed-n2e${exe} upx-packed-lzma${exe})
upx_add_test(upx-test upx -t upx-packed${exe} upx-packed-n2b${exe} upx-packed-n2d${exe} upx-packed-n2e${exe} upx-packed-lzma${exe})
upx_add_test(upx-unpack upx -d upx-packed${exe} ${fo} -o upx-unpacked${exe})
upx_add_test(upx-run-unpacked ./upx-unpacked${exe} --version-short)
upx_add_test(upx-run-packed ./upx-packed${exe} --version-short)
endif() endif()
endif() # UPX_CONFIG_CMAKE_DISABLE_TEST endif() # UPX_CONFIG_CMAKE_DISABLE_TEST
#*********************************************************************** #***********************************************************************
# install
# cmake --install . # cmake --install .
# make install # make install
# ninja install # ninja install
#*********************************************************************** #***********************************************************************
upx_cmake_include_hook(7_install)
if(NOT UPX_CONFIG_CMAKE_DISABLE_INSTALL) if(NOT UPX_CONFIG_CMAKE_DISABLE_INSTALL)
# installation prefix and directories # installation prefix and directories
@@ -551,6 +472,7 @@ endif()
if(CMAKE_INSTALL_PREFIX) if(CMAKE_INSTALL_PREFIX)
include(GNUInstallDirs) include(GNUInstallDirs)
endif() endif()
# install files
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
@@ -563,46 +485,36 @@ endif()
endif() # UPX_CONFIG_CMAKE_DISABLE_INSTALL endif() # UPX_CONFIG_CMAKE_DISABLE_INSTALL
#*********************************************************************** #***********************************************************************
# finally print some info about the build configuration # summary
# print some info about the build configuration
#*********************************************************************** #***********************************************************************
function(print_var) upx_cmake_include_hook(8_summary)
foreach(var ${ARGV})
if(${var})
message(STATUS "${var} = ${${var}}")
endif()
endforeach()
endfunction()
if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/maint/make/CMakeLists.maint.txt") upx_print_var(CMAKE_VERSION UPX_CONFIG_CMAKE_MINIMUM_REQUIRED_VERSION CMAKE_GENERATOR)
include("${CMAKE_CURRENT_SOURCE_DIR}/maint/make/CMakeLists.maint.txt")
endif()
print_var(CMAKE_VERSION UPX_CONFIG_CMAKE_MINIMUM_REQUIRED_VERSION CMAKE_GENERATOR)
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) include("${CMAKE_CURRENT_SOURCE_DIR}/misc/cmake/print_info.cmake")
print_var(CMAKE_SYSTEM_NAME CMAKE_SYSTEM_VERSION CMAKE_CROSSCOMPILING) endif()
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) upx_print_var(CMAKE_INSTALL_PREFIX CMAKE_CONFIGURATION_TYPES CMAKE_TRY_COMPILE_CONFIGURATION CMAKE_BUILD_TYPE)
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) if(Threads_FOUND)
print_var(CMAKE_POSITION_INDEPENDENT_CODE) message(STATUS "WITH_THREADS = 1")
print_var(CYGWIN GNUC MINGW MSVC MSVC_FRONTEND MSVC_IDE WIN32 WIN64) elseif(UPX_CONFIG_REQUIRE_THREADS)
endif() # UPX_CONFIG_CMAKE_DISABLE_PRINT_INFO message(FATAL_ERROR "ERROR: WITH_THREADS required")
print_var(CMAKE_INSTALL_PREFIX CMAKE_CONFIGURATION_TYPES CMAKE_BUILD_TYPE) elseif(UPX_CONFIG_EXPECT_THREADS AND NOT UPX_CONFIG_DISABLE_THREADS)
message(FATAL_ERROR "ERROR: WITH_THREADS expected; set UPX_CONFIG_EXPECT_THREADS=OFF")
endif()
if(CMAKE_BUILD_TYPE AND NOT CMAKE_BUILD_TYPE MATCHES "^(Debug|None|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()
# 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 UPX_CONFIG_CMAKE_DISABLE_PLATFORM_CHECK)
if(NOT ",${CMAKE_C_PLATFORM_ID}," STREQUAL ",${CMAKE_CXX_PLATFORM_ID},") upx_platform_check_mismatch(CMAKE_C_PLATFORM_ID CMAKE_CXX_PLATFORM_ID)
message(FATAL_ERROR "ERROR: CMAKE_C_PLATFORM_ID CMAKE_CXX_PLATFORM_ID mismatch") upx_platform_check_mismatch(CMAKE_C_COMPILER_ABI CMAKE_CXX_COMPILER_ABI)
upx_platform_check_mismatch(CMAKE_C_COMPILER_FRONTEND_VARIANT CMAKE_CXX_COMPILER_FRONTEND_VARIANT)
endif() endif()
if(NOT ",${CMAKE_C_COMPILER_ABI}," STREQUAL ",${CMAKE_CXX_COMPILER_ABI},")
message(FATAL_ERROR "ERROR: CMAKE_C_COMPILER_ABI CMAKE_CXX_COMPILER_ABI mismatch") upx_cmake_include_hook(9_finish)
endif() file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/.upx_cmake_config_done.txt" "")
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
# vim:set ft=cmake ts=4 sw=4 tw=0 et: # vim:set ft=cmake ts=4 sw=4 tw=0 et:
+33 -10
View File
@@ -24,14 +24,14 @@ endif
# default # default
#*********************************************************************** #***********************************************************************
.DEFAULT_GOAL = build/release
run_cmake_config = $(CMAKE) -S . -B $1 $(UPX_CMAKE_CONFIG_FLAGS) -DCMAKE_BUILD_TYPE=$2 run_cmake_config = $(CMAKE) -S . -B $1 $(UPX_CMAKE_CONFIG_FLAGS) -DCMAKE_BUILD_TYPE=$2
run_cmake_build = $(CMAKE) --build $1 $(UPX_CMAKE_BUILD_FLAGS) --config $2 run_cmake_build = $(CMAKE) --build $1 $(UPX_CMAKE_BUILD_FLAGS) --config $2
# avoid re-running run_cmake_config if CMakeCache.txt already exists # avoid re-running run_cmake_config if .upx_cmake_config_done.txt already exists
run_config = $(if $(wildcard $1/CMakeCache.txt),,$(call run_cmake_config,$1,$2)) run_config = $(if $(wildcard $1/CMakeFiles/.upx_cmake_config_done.txt),,$(call run_cmake_config,$1,$2))
run_build = $(call run_cmake_build,$1,$2) run_build = $(call run_cmake_build,$1,$2)
.DEFAULT_GOAL = build/release
build/debug: PHONY build/debug: PHONY
$(call run_config,$@,Debug) $(call run_config,$@,Debug)
$(call run_build,$@,Debug) $(call run_build,$@,Debug)
@@ -46,10 +46,31 @@ build/release: PHONY
.SUFFIXES: .SUFFIXES:
# shortcuts (all => debug + release) # shortcuts (all => debug + release)
debug: build/debug debug: build/debug PHONY
release: build/release release: build/release PHONY
all build/all: build/debug build/release all build/all: build/debug build/release PHONY
build/%/all: $$(dir $$@)debug $$(dir $$@)release ; build/%/all: $$(dir $$@)debug $$(dir $$@)release PHONY ;
#***********************************************************************
# test
#***********************************************************************
CTEST = ctest
CTEST_JOBS ?= 8
CTEST_FLAGS = --output-on-failure --parallel $(CTEST_JOBS)
build/debug+test: $$(dir $$@)debug PHONY; cd "$(dir $@)debug" && $(CTEST) $(CTEST_FLAGS) -C Debug
build/%/debug+test: $$(dir $$@)debug PHONY; cd "$(dir $@)debug" && $(CTEST) $(CTEST_FLAGS) -C Debug
build/release+test: $$(dir $$@)release PHONY; cd "$(dir $@)release" && $(CTEST) $(CTEST_FLAGS) -C Release
build/%/release+test: $$(dir $$@)release PHONY; cd "$(dir $@)release" && $(CTEST) $(CTEST_FLAGS) -C Release
build/%/all+test: $$(dir $$@)debug+test $$(dir $$@)release+test PHONY ;
# shortcuts
debug+test: build/debug+test PHONY
release+test: build/release+test PHONY
all+test build/all+test: build/debug+test build/release+test PHONY
test: $$(patsubst %+test,%,$$(.DEFAULT_GOAL))+test PHONY
# #
# END of Makefile # END of Makefile
@@ -59,7 +80,9 @@ build/%/all: $$(dir $$@)debug $$(dir $$@)release ;
include ./misc/make/Makefile-extra.mk include ./misc/make/Makefile-extra.mk
# developer convenience # developer convenience
ifneq ($(wildcard /usr/bin/env),) # needs bash, perl, xargs, etc. ifneq ($(wildcard /usr/bin/env),) # need Unix utils like bash, perl, sed, xargs, etc.
check-whitespace clang-format run-testsuite run-testsuite-debug run-testsuite-release: PHONY src/Makefile ifneq ($(wildcard ./misc/scripts/.),)
check-whitespace clang-format run-testsuite run-testsuite-all run-testsuite-debug run-testsuite-release: src/Makefile PHONY
$(MAKE) -C src $@ $(MAKE) -C src $@
endif endif
endif
+17
View File
@@ -2,11 +2,28 @@
User visible changes for UPX User visible changes for UPX
================================================================== ==================================================================
Changes in 4.2.4 (09 May 2024):
* bug fixes - see https://github.com/upx/upx/milestone/17
Changes in 4.2.3 (27 Mar 2024):
* bug fixes - see https://github.com/upx/upx/milestone/16
Changes in 4.2.2 (03 Jan 2024):
* bug fixes - see https://github.com/upx/upx/milestone/15
Changes in 4.2.1 (01 Nov 2023):
* linux: /proc/self/exe now is optional
* windows: use SetFileTime to preserve sub-second file timestamps
* official Windows builds: revert activeCodePage change introduced in 4.2.0
* bug fixes - see https://github.com/upx/upx/milestone/14
Changes in 4.2.0 (26 Oct 2023): Changes in 4.2.0 (26 Oct 2023):
* win32/pe and win64/pe: stricter relocation checks; please report regressions * win32/pe and win64/pe: stricter relocation checks; please report regressions
* unix: use utimensat to preserve sub-second file timestamps
* new option '--link' to preserve hard-links (Unix only; use with care) * new option '--link' to preserve hard-links (Unix only; use with care)
* add support for NO_COLOR env var; see https://no-color.org/ * add support for NO_COLOR env var; see https://no-color.org/
* disable macOS support until we fix compatibility with macOS 13+ * disable macOS support until we fix compatibility with macOS 13+
* official Windows builds: set activeCodePage to UTF-8
* bug fixes - see https://github.com/upx/upx/milestone/13 * bug fixes - see https://github.com/upx/upx/milestone/13
Changes in 4.1.0 (08 Aug 2023): Changes in 4.1.0 (08 Aug 2023):
+4 -4
View File
@@ -8,7 +8,7 @@
The Ultimate Packer for eXecutables The Ultimate Packer for eXecutables
Copyright (c) 1996-2023 Markus Oberhumer, Laszlo Molnar & John Reiser Copyright (c) 1996-2024 Markus Oberhumer, Laszlo Molnar & John Reiser
https://upx.github.io https://upx.github.io
@@ -85,9 +85,9 @@ THE FUTURE
COPYRIGHT COPYRIGHT
========= =========
Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer Copyright (C) 1996-2024 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2023 Laszlo Molnar Copyright (C) 1996-2024 Laszlo Molnar
Copyright (C) 2000-2023 John F. Reiser Copyright (C) 2000-2024 John F. Reiser
UPX is distributed with full source code under the terms of the UPX is distributed with full source code under the terms of the
GNU General Public License v2+; either under the pure GPLv2+ (see GNU General Public License v2+; either under the pure GPLv2+ (see
+1 -1
View File
@@ -8,7 +8,7 @@
The Ultimate Packer for eXecutables The Ultimate Packer for eXecutables
Copyright (c) 1996-2023 Markus Oberhumer, Laszlo Molnar & John Reiser Copyright (c) 1996-2024 Markus Oberhumer, Laszlo Molnar & John Reiser
https://upx.github.io https://upx.github.io
+9 -4
View File
@@ -1,8 +1,9 @@
# #
# UPX doc Makefile - needs GNU make, pod2html, pod2man and pod2text # UPX doc Makefile - needs GNU make, sed, pod2html, pod2man and pod2text
# Copyright (C) Markus Franz Xaver Johannes Oberhumer
# #
BUILT_SOURCES = upx.1 upx-doc.html upx-doc.txt BUILT_SOURCES := upx.1 upx-doc.html upx-doc.txt
top_srcdir ?= .. top_srcdir ?= ..
@@ -25,6 +26,10 @@ DETAB2 := sed -e 's/$(tab)/ /g'
.DEFAULT_GOAL = all .DEFAULT_GOAL = all
.PHONY: PHONY
.SECONDEXPANSION:
.SUFFIXES:
all: $(BUILT_SOURCES) PHONY all: $(BUILT_SOURCES) PHONY
mostlyclean clean distclean maintainer-clean: PHONY mostlyclean clean distclean maintainer-clean: PHONY
@@ -34,12 +39,13 @@ mostlyclean clean distclean maintainer-clean: PHONY
# rules # rules
#*********************************************************************** #***********************************************************************
.SUFFIXES:
.SUFFIXES: .1 .html .man .pod .ps .tex .txt .SUFFIXES: .1 .html .man .pod .ps .tex .txt
%.1 : %.pod %.1 : %.pod
pod2man --center=" " --release="$(PACKAGE) $(VERSION)" --date="$(VERSION_DATE)" $< | $(RTRIM) > $@ pod2man --center=" " --release="$(PACKAGE) $(VERSION)" --date="$(VERSION_DATE)" $< | $(RTRIM) > $@
test -s $@ test -s $@
# # strip version number from "Pod::Man" comment
sed -i -e 's/^\(\.\\" Automatically generated by Pod::Man\).*/\1/' $@
%-doc.html : %.pod %-doc.html : %.pod
pod2html --noindex $< | $(RTRIM) | $(DETAB2) > $@ pod2html --noindex $< | $(RTRIM) | $(DETAB2) > $@
@@ -68,4 +74,3 @@ mostlyclean clean distclean maintainer-clean: PHONY
$(BUILT_SOURCES): $(top_srcdir)/src/version.h $(MAKEFILE_LIST) $(BUILT_SOURCES): $(top_srcdir)/src/version.h $(MAKEFILE_LIST)
.DELETE_ON_ERROR: $(BUILT_SOURCES) .DELETE_ON_ERROR: $(BUILT_SOURCES)
.PHONY: PHONY
+3 -1
View File
@@ -8,7 +8,7 @@
The Ultimate Packer for eXecutables The Ultimate Packer for eXecutables
Copyright (c) 1996-2023 Markus Oberhumer, Laszlo Molnar & John Reiser Copyright (c) 1996-2024 Markus Oberhumer, Laszlo Molnar & John Reiser
https://upx.github.io https://upx.github.io
@@ -37,6 +37,8 @@ Charles W. Sandmann <sandmann@clio.rice.edu>
for the idea with the stubless decompressor in djgpp2/coff for the idea with the stubless decompressor in djgpp2/coff
Ice Ice
for debugging the PE headersize problem down for debugging the PE headersize problem down
Jens Medoch <jssg@users.sourceforge.net>
for the ps1/exe format
Joergen Ibsen <jibz@hotmail.com> and d'b 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>
+46 -44
View File
@@ -1,5 +1,5 @@
Decompressing ELF Directly to Memory on Linux/x86 Decompressing ELF Directly to Memory on Linux/x86
Copyright (C) 2000-2023 John F. Reiser jreiser@BitWagon.com Copyright (C) 2000-2024 John F. Reiser jreiser@BitWagon.com
References: References:
<elf.h> definitions for the ELF file format <elf.h> definitions for the ELF file format
@@ -15,7 +15,7 @@ the value that is manipulated by system call 45 (__NR_brk in
there will be no execve() except for the execve() of the decompressor there will be no execve() except for the execve() of the decompressor
program itself. So, the decompressor program (which contains the program itself. So, the decompressor program (which contains the
compressed version of the original executable) must have the same compressed version of the original executable) must have the same
brk() as the original executable. So, the second PT_LOAD brk() as the original executable. So, the first PT_LOAD
ELF "segment" of the compressed program is used only to set the brk(0). ELF "segment" of the compressed program is used only to set the brk(0).
See src/p_lx_elf.cpp, function PackLinuxElf32::generateElfHdr. See src/p_lx_elf.cpp, function PackLinuxElf32::generateElfHdr.
All of the decompressor's code, and all of the compressed image All of the decompressor's code, and all of the compressed image
@@ -25,35 +25,27 @@ decompressor program.
The decompressor program stub is just under 2K bytes when linked. The decompressor program stub is just under 2K bytes when linked.
After linking, the decompressor code is converted to an initialized After linking, the decompressor code is converted to an initialized
array, and #included into the compilation of the compressor; array, and #included into the compilation of the compressor;
see src/stub/l_le_n2b.h. To make self-contained compressed see stub/i386-linux.elf-entry.h. To make self-contained compressed
executables even smaller, the compressor also compresses all but the executables even smaller, the compressor also compresses all but the
startup and decompression subroutine of the decompressor itself, startup and decompression subroutine of the decompressor itself,
saving a few hundred bytes. The startup code first decompresses the saving a few hundred bytes. The startup code first decompresses the
rest of the decompressor, then jumps to it. A nonstandard linker rest of the decompressor, then jumps to it. A nonstandard linker
script src/stub/l_lx_elf86.lds places both the .text and .data script src/stub/src/i386-linux.elf-entry.lds arranges the SECTIONS
of the decompressor into the same PT_LOAD at 0x00401000. The so that PackLinuxElf32x86::buildLoader() and buildLinuxLoader()
compressor includes the compressed bytes of the original executable generate the desired stub code, which goes into PT_LOAD[1].
at the end of this first PT_LOAD.
At runtime, the decompressed stub lives at 0x00400000. In order for the At runtime, the decompressed stub lives close beyond the brk().
decompressed stub to work properly at an address that is different In order for the decompressed stub to work properly at an address
from its link-time address, the compiled code must contain no absolute that is different from its link-time address, the compiled code must
addresses. So, the data items in l_lx_elf.c must be only parameters contain no absolute addresses. So, the data items in stub code
and automatic (on-stack) local variables; no global data, no static data, must be only parameters and automatic (on-stack) local variables;
and no string constants. Use "size l_le_n2b.o l_6e_n2b.o" to check no global data, no static data, and no string constants. Also,
that both data and bss have length zero. Also, the '&' operator the '&' operator may not be used to take the address of a function.
may not be used to take the address of a function.
The address 0x00400000 was chosen to be out of the way of the usual
load address 0x08048000, and to minimize fragmentation in kernel
page tables; one page of page tables covers 4 MiB. The address
0x00401000 was chosen as 1 page up from a 64 KiB boundary, to
make the startup code and its constants smaller.
Decompression of the executable begins by decompressing the Elf32_Ehdr Decompression of the executable begins by decompressing the Elf32_Ehdr
and Elf32_Phdr, and then uses the Ehdr and Phdrs to control decompression and Elf32_Phdr, and then uses those Ehdr and Phdrs to control decompression
of the PT_LOAD segments. of the PT_LOAD segments. Subroutine do_xmap() of src/stub/src/
Subroutine do_xmap() of src/stub/l_lx_elf.c performs the i386-linux.elf-main.c performs the
"virtual execve()" using the compressed data as source, and stores "virtual execve()" using the compressed data as source, and stores
the decompressed bytes directly into the appropriate virtual addresses. the decompressed bytes directly into the appropriate virtual addresses.
@@ -74,22 +66,17 @@ expanding $ORIGIN in -rpath, or for application code that relies on
--unmap-all-pages to achieve that effect at run time. Upx-3.04 --unmap-all-pages to achieve that effect at run time. Upx-3.04
and previous versions did this by default with no option. However, and previous versions did this by default with no option. However,
too much other software erroneously assumes that /proc/self/exe too much other software erroneously assumes that /proc/self/exe
always exists. always exists. upx-4.3.0 made /proc/self/exe optional so that
chroot() and related environments can work.
For Elf formats, UPX adds an environment variable named " " [three
spaces] which saves the results of readlink("/proc/self/exe",,)
If /proc/self/exe is ENOENT, then the variable has the same value
as its name "/proc/self/exe".
On arm*-linux-elf there is no good address at which to retain one All of the above documentation refers to ET_EXEC main programs,
page of the compressed executable. Pages below the usual .p_vaddr which always use the same virtual addresses. An ET_DYN executable
0x8000 (32KiB) are rejected by the kernel. Using a page above the (main program or shared library) follows much the same scheme,
original uncompressed brk(0) would require placing the entire initial re-using the address space that the kernel chose originally.
compressed program above uncompressed brk(0), which would significantly
increase the running brk(0); but too many programs break if brk(0)
moves. Thus on arm*-linux-elf the compressed executable begins
with 0x8000==.p_vaddr, all pages mapped by execve() that are also
occupied by decompressed bytes are removed before overwriting, and
/proc/self/exe becomes a "(deleted)" symlink. It might be possible
to preserve /proc/self/exe if the original uncompressed executable
were created with 0x9000==.p_vaddr (one page higher than the usual
0x8000) so that the compressed page mapped at 0x8000 would linger.
[This has not been tested.]
Linux stores the pathname argument that was specified to execve() Linux stores the pathname argument that was specified to execve()
immediately after the '\0' which terminates the character string of the immediately after the '\0' which terminates the character string of the
@@ -99,9 +86,24 @@ records a pointer to that character string in Elf32_auxv[AT_EXECFN].
The pathname is not "bound" to the file as strongly as /proc/self/exe The pathname is not "bound" to the file as strongly as /proc/self/exe
(the file may be changed without affecting the pathname), but the (the file may be changed without affecting the pathname), but the
pathname does provide some information. The pathname may be relative pathname does provide some information. The pathname may be relative
to the working directory, so look before any chdir(). to the working directory, so look before performing any chdir().
The Elf formats for Linux add an environment variable named " " [three On any page, then SELinux in strictest enforcing mode prohibits
spaces] which saves the results of readlink("/proc/self/exe",,) before simultaneous PROT_EXEC and PROT_WRITE, and also prohibits adding
the runtime stub unmaps all its pages. As of 2006-10-03 this works PROT_EXEC if the kernel VMA struct (Virtual Memory Area struct)
for linux/elf386 and linux/ElfAMD. that manages that page ever has had PROT_WRITE. This implies that
the only way to get PROT_EXEC is to map the page directly from a file.
Therefore, in late 2023 the various decompression stubs are being
rewritten to "bounce" the decompressed data through pages in a
memory-resident file created by the memfd_create() system call,
and subsequently mapped PROT_EXEC. Actual copying of the pages
can be avoided by careful sequence mmap() modes, but the overhead
of an additional system call is required.
The not-as-strict "targeted enforcing" mode of
SELinux seems not to demand this extra work, except for executables
that run with elevated privileges, such as various system daemons.
So "ordinary" user-mode apps can run in current "targeted enforcing"
mode. But because the actual runtime mode of SELinux is unknown
at compression time, then the memfd_create method should be used
all the time.
+5 -9
View File
@@ -22,7 +22,7 @@
<h1 id="ABSTRACT">ABSTRACT</h1> <h1 id="ABSTRACT">ABSTRACT</h1>
<pre><code> The Ultimate Packer for eXecutables <pre><code> The Ultimate Packer for eXecutables
Copyright (c) 1996-2023 Markus Oberhumer, Laszlo Molnar &amp; John Reiser Copyright (c) 1996-2024 Markus Oberhumer, Laszlo Molnar &amp; John Reiser
https://upx.github.io</code></pre> https://upx.github.io</code></pre>
<p><b>UPX</b> is a portable, extendable, high-performance executable packer for several different executable formats. It achieves an excellent compression ratio and offers <i>*very*</i> fast decompression. Your executables suffer no memory overhead or other drawbacks for most of the formats supported, because of in-place decompression.</p> <p><b>UPX</b> is a portable, extendable, high-performance executable packer for several different executable formats. It achieves an excellent compression ratio and offers <i>*very*</i> fast decompression. Your executables suffer no memory overhead or other drawbacks for most of the formats supported, because of in-place decompression.</p>
@@ -779,19 +779,15 @@ http://www.oberhumer.com
Laszlo Molnar &lt;ezerotven+github@gmail.com&gt; Laszlo Molnar &lt;ezerotven+github@gmail.com&gt;
John F. Reiser &lt;jreiser@BitWagon.com&gt; John F. Reiser &lt;jreiser@BitWagon.com&gt;</code></pre>
Jens Medoch &lt;jssg@users.sourceforge.net&gt;</code></pre>
<h1 id="COPYRIGHT">COPYRIGHT</h1> <h1 id="COPYRIGHT">COPYRIGHT</h1>
<p>Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer</p> <p>Copyright (C) 1996-2024 Markus Franz Xaver Johannes Oberhumer</p>
<p>Copyright (C) 1996-2023 Laszlo Molnar</p> <p>Copyright (C) 1996-2024 Laszlo Molnar</p>
<p>Copyright (C) 2000-2023 John F. Reiser</p> <p>Copyright (C) 2000-2024 John F. Reiser</p>
<p>Copyright (C) 2002-2023 Jens Medoch</p>
<p><b>UPX</b> is distributed with full source code under the terms of the GNU General Public License v2+; either under the pure GPLv2+ (see the file COPYING), or (at your option) under the GPLv+2 with special exceptions and restrictions granting the free usage for all binaries including commercial programs (see the file LICENSE).</p> <p><b>UPX</b> is distributed with full source code under the terms of the GNU General Public License v2+; either under the pure GPLv2+ (see the file COPYING), or (at your option) under the GPLv+2 with special exceptions and restrictions granting the free usage for all binaries including commercial programs (see the file LICENSE).</p>
+4 -8
View File
@@ -6,7 +6,7 @@ SYNOPSIS
ABSTRACT ABSTRACT
The Ultimate Packer for eXecutables The Ultimate Packer for eXecutables
Copyright (c) 1996-2023 Markus Oberhumer, Laszlo Molnar & John Reiser Copyright (c) 1996-2024 Markus Oberhumer, Laszlo Molnar & John Reiser
https://upx.github.io https://upx.github.io
UPX is a portable, extendable, high-performance executable packer for UPX is a portable, extendable, high-performance executable packer for
@@ -815,16 +815,12 @@ AUTHORS
John F. Reiser <jreiser@BitWagon.com> John F. Reiser <jreiser@BitWagon.com>
Jens Medoch <jssg@users.sourceforge.net>
COPYRIGHT COPYRIGHT
Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer Copyright (C) 1996-2024 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2023 Laszlo Molnar Copyright (C) 1996-2024 Laszlo Molnar
Copyright (C) 2000-2023 John F. Reiser Copyright (C) 2000-2024 John F. Reiser
Copyright (C) 2002-2023 Jens Medoch
UPX is distributed with full source code under the terms of the GNU UPX is distributed with full source code under the terms of the GNU
General Public License v2+; either under the pure GPLv2+ (see the file General Public License v2+; either under the pure GPLv2+ (see the file
Generated
+102 -184
View File
@@ -1,4 +1,5 @@
.\" Automatically generated by Pod::Man 4.14 (Pod::Simple 3.42) .\" -*- mode: troff; coding: utf-8 -*-
.\" Automatically generated by Pod::Man
.\" .\"
.\" Standard preamble: .\" Standard preamble:
.\" ======================================================================== .\" ========================================================================
@@ -15,29 +16,12 @@
.ft R .ft R
.fi .fi
.. ..
.\" Set up some character translations and predefined strings. \*(-- will .\" \*(C` and \*(C' are quotes in nroff, nothing in troff, for use with C<>.
.\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left
.\" double quote, and \*(R" will give a right double quote. \*(C+ will
.\" give a nicer C++. Capital omega is used to do unbreakable dashes and
.\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff,
.\" nothing in troff, for use with C<>.
.tr \(*W-
.ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p'
.ie n \{\ .ie n \{\
. ds -- \(*W-
. ds PI pi
. if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch
. if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch
. ds L" ""
. ds R" ""
. ds C` "" . ds C` ""
. ds C' "" . ds C' ""
'br\} 'br\}
.el\{\ .el\{\
. ds -- \|\(em\|
. ds PI \(*p
. ds L" ``
. ds R" ''
. ds C` . ds C`
. ds C' . ds C'
'br\} 'br\}
@@ -68,110 +52,48 @@
. \} . \}
.\} .\}
.rr rF .rr rF
.\"
.\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2).
.\" Fear. Run. Save yourself. No user-serviceable parts.
. \" fudge factors for nroff and troff
.if n \{\
. ds #H 0
. ds #V .8m
. ds #F .3m
. ds #[ \f1
. ds #] \fP
.\}
.if t \{\
. ds #H ((1u-(\\\\n(.fu%2u))*.13m)
. ds #V .6m
. ds #F 0
. ds #[ \&
. ds #] \&
.\}
. \" simple accents for nroff and troff
.if n \{\
. ds ' \&
. ds ` \&
. ds ^ \&
. ds , \&
. ds ~ ~
. ds /
.\}
.if t \{\
. ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u"
. ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u'
. ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u'
. ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u'
. ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u'
. ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u'
.\}
. \" troff and (daisy-wheel) nroff accents
.ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V'
.ds 8 \h'\*(#H'\(*b\h'-\*(#H'
.ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#]
.ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H'
.ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u'
.ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#]
.ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#]
.ds ae a\h'-(\w'a'u*4/10)'e
.ds Ae A\h'-(\w'A'u*4/10)'E
. \" corrections for vroff
.if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u'
.if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u'
. \" for low resolution devices (crt and lpr)
.if \n(.H>23 .if \n(.V>19 \
\{\
. ds : e
. ds 8 ss
. ds o a
. ds d- d\h'-1'\(ga
. ds D- D\h'-1'\(hy
. ds th \o'bp'
. ds Th \o'LP'
. ds ae ae
. ds Ae AE
.\}
.rm #[ #] #H #V #F C
.\" ======================================================================== .\" ========================================================================
.\" .\"
.IX Title "UPX 1" .IX Title "UPX 1"
.TH UPX 1 "2023-10-26" "upx 4.2.0" " " .TH UPX 1 2024-05-09 "upx 4.2.4" " "
.\" 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
.nh .nh
.SH "NAME" .SH NAME
upx \- compress or expand executable files upx \- compress or expand executable files
.SH "SYNOPSIS" .SH SYNOPSIS
.IX Header "SYNOPSIS" .IX Header "SYNOPSIS"
\&\fBupx\fR [\ \fIcommand\fR\ ] [\ \fIoptions\fR\ ] \fIfilename\fR... \&\fBupx\fR [\ \fIcommand\fR\ ] [\ \fIoptions\fR\ ] \fIfilename\fR...
.SH "ABSTRACT" .SH ABSTRACT
.IX Header "ABSTRACT" .IX Header "ABSTRACT"
.Vb 3 .Vb 3
\& The Ultimate Packer for eXecutables \& The Ultimate Packer for eXecutables
\& Copyright (c) 1996\-2023 Markus Oberhumer, Laszlo Molnar & John Reiser \& Copyright (c) 1996\-2024 Markus Oberhumer, Laszlo Molnar & John Reiser
\& https://upx.github.io \& https://upx.github.io
.Ve .Ve
.PP .PP
\&\fB\s-1UPX\s0\fR is a portable, extendable, high-performance executable packer for \&\fBUPX\fR is a portable, extendable, high-performance executable packer for
several different executable formats. It achieves an excellent compression several different executable formats. It achieves an excellent compression
ratio and offers \fI*very*\fR fast decompression. Your executables suffer ratio and offers \fI*very*\fR fast decompression. Your executables suffer
no memory overhead or other drawbacks for most of the formats supported, no memory overhead or other drawbacks for most of the formats supported,
because of in-place decompression. because of in-place decompression.
.SH "DISCLAIMER" .SH DISCLAIMER
.IX Header "DISCLAIMER" .IX Header "DISCLAIMER"
\&\fB\s-1UPX\s0\fR comes with \s-1ABSOLUTELY NO WARRANTY\s0; for details see the file \s-1COPYING.\s0 \&\fBUPX\fR comes with ABSOLUTELY NO WARRANTY; for details see the file COPYING.
.PP .PP
Please report all problems or suggestions to the authors. Thanks. Please report all problems or suggestions to the authors. Thanks.
.SH "SECURITY CONTEXT" .SH "SECURITY CONTEXT"
.IX Header "SECURITY CONTEXT" .IX Header "SECURITY CONTEXT"
\&\s-1IMPORTANT NOTE:\s0 \fB\s-1UPX\s0\fR inherits the security context of any files it handles. IMPORTANT NOTE: \fBUPX\fR inherits the security context of any files it handles.
.PP .PP
This means that packing, unpacking, or even testing or listing a file requires This means that packing, unpacking, or even testing or listing a file requires
the same security considerations as actually executing the file. the same security considerations as actually executing the file.
.PP .PP
Use \fB\s-1UPX\s0\fR on trusted files only! Use \fBUPX\fR on trusted files only!
.SH "DESCRIPTION" .SH DESCRIPTION
.IX Header "DESCRIPTION" .IX Header "DESCRIPTION"
\&\fB\s-1UPX\s0\fR is a versatile executable packer with the following features: \&\fBUPX\fR is a versatile executable packer with the following features:
.PP .PP
.Vb 3 .Vb 3
\& \- secure: as UPX is documented Open Source since many years any relevant \& \- secure: as UPX is documented Open Source since many years any relevant
@@ -204,32 +126,32 @@ Use \fB\s-1UPX\s0\fR on trusted files only!
\& for commercial programs \& for commercial programs
.Ve .Ve
.PP .PP
You probably understand now why we call \fB\s-1UPX\s0\fR the "\fIultimate\fR" You probably understand now why we call \fBUPX\fR the "\fIultimate\fR"
executable packer. executable packer.
.SH "COMMANDS" .SH COMMANDS
.IX Header "COMMANDS" .IX Header "COMMANDS"
.SS "Compress" .SS Compress
.IX Subsection "Compress" .IX Subsection "Compress"
This is the default operation, eg. \fBupx yourfile.exe\fR will compress the file This is the default operation, eg. \fBupx yourfile.exe\fR will compress the file
specified on the command line. specified on the command line.
.SS "Decompress" .SS Decompress
.IX Subsection "Decompress" .IX Subsection "Decompress"
All \fB\s-1UPX\s0\fR supported file formats can be unpacked using the \fB\-d\fR switch, eg. All \fBUPX\fR supported file formats can be unpacked using the \fB\-d\fR switch, eg.
\&\fBupx \-d yourfile.exe\fR will uncompress the file you've just compressed. \&\fBupx \-d yourfile.exe\fR will uncompress the file you've just compressed.
.SS "Test" .SS Test
.IX Subsection "Test" .IX Subsection "Test"
The \fB\-t\fR command tests the integrity of the compressed and uncompressed The \fB\-t\fR command tests the integrity of the compressed and uncompressed
data, eg. \fBupx \-t yourfile.exe\fR check whether your file can be safely data, eg. \fBupx \-t yourfile.exe\fR check whether your file can be safely
decompressed. Note, that this command doesn't check the whole file, only decompressed. Note, that this command doesn't check the whole file, only
the part that will be uncompressed during program execution. This means the part that will be uncompressed during program execution. This means
that you should not use this command instead of a virus checker. that you should not use this command instead of a virus checker.
.SS "List" .SS List
.IX Subsection "List" .IX Subsection "List"
The \fB\-l\fR command prints out some information about the compressed files The \fB\-l\fR command prints out some information about the compressed files
specified on the command line as parameters, eg \fBupx \-l yourfile.exe\fR specified on the command line as parameters, eg \fBupx \-l yourfile.exe\fR
shows the compressed / uncompressed size and the compression ratio of shows the compressed / uncompressed size and the compression ratio of
\&\fIyourfile.exe\fR. \&\fIyourfile.exe\fR.
.SH "OPTIONS" .SH OPTIONS
.IX Header "OPTIONS" .IX Header "OPTIONS"
\&\fB\-q\fR: be quiet, suppress warnings \&\fB\-q\fR: be quiet, suppress warnings
.PP .PP
@@ -239,10 +161,10 @@ shows the compressed / uncompressed size and the compression ratio of
.PP .PP
\&\fB\-\-help\fR: prints the help \&\fB\-\-help\fR: prints the help
.PP .PP
\&\fB\-\-version\fR: print the version of \fB\s-1UPX\s0\fR \&\fB\-\-version\fR: print the version of \fBUPX\fR
.PP .PP
\&\fB\-\-exact\fR: when compressing, require to be able to get a byte-identical file \&\fB\-\-exact\fR: when compressing, require to be able to get a byte-identical file
after decompression with option \fB\-d\fR. [\s-1NOTE:\s0 this is work in progress and is after decompression with option \fB\-d\fR. [NOTE: this is work in progress and is
not supported for all formats yet. If you do care, as a workaround you can not supported for all formats yet. If you do care, as a workaround you can
compress and then decompress your program a first time \- any further compress and then decompress your program a first time \- any further
compress-decompress steps should then yield byte-identical results compress-decompress steps should then yield byte-identical results
@@ -255,16 +177,16 @@ as compared to the first decompressed version.]
[ ...more docs need to be written... \- type `\fBupx \-\-help\fR' for now ] [ ...more docs need to be written... \- type `\fBupx \-\-help\fR' for now ]
.SH "COMPRESSION LEVELS & TUNING" .SH "COMPRESSION LEVELS & TUNING"
.IX Header "COMPRESSION LEVELS & TUNING" .IX Header "COMPRESSION LEVELS & TUNING"
\&\fB\s-1UPX\s0\fR offers ten different compression levels from \fB\-1\fR to \fB\-9\fR, \&\fBUPX\fR offers ten different compression levels from \fB\-1\fR to \fB\-9\fR,
and \fB\-\-best\fR. The default compression level is \fB\-8\fR for files and \fB\-\-best\fR. The default compression level is \fB\-8\fR for files
smaller than 512 KiB, and \fB\-7\fR otherwise. smaller than 512 KiB, and \fB\-7\fR otherwise.
.IP "\(bu" 4 .IP \(bu 4
Compression levels 1, 2 and 3 are pretty fast. Compression levels 1, 2 and 3 are pretty fast.
.IP "\(bu" 4 .IP \(bu 4
Compression levels 4, 5 and 6 achieve a good time/ratio performance. Compression levels 4, 5 and 6 achieve a good time/ratio performance.
.IP "\(bu" 4 .IP \(bu 4
Compression levels 7, 8 and 9 favor compression ratio over speed. Compression levels 7, 8 and 9 favor compression ratio over speed.
.IP "\(bu" 4 .IP \(bu 4
Compression level \fB\-\-best\fR may take a long time. Compression level \fB\-\-best\fR may take a long time.
.PP .PP
Note that compression level \fB\-\-best\fR can be somewhat slow for large Note that compression level \fB\-\-best\fR can be somewhat slow for large
@@ -272,28 +194,28 @@ files, but you definitely should use it when releasing a final version
of your program. of your program.
.PP .PP
Quick info for achieving the best compression ratio: Quick info for achieving the best compression ratio:
.IP "\(bu" 4 .IP \(bu 4
Try \fBupx \-\-brute \-\-no\-lzma myfile.exe\fR or even Try \fBupx \-\-brute \-\-no\-lzma myfile.exe\fR or even
\&\fBupx \-\-ultra\-brute \-\-no\-lzma myfile.exe\fR. \&\fBupx \-\-ultra\-brute \-\-no\-lzma myfile.exe\fR.
.IP "\(bu" 4 .IP \(bu 4
The option \fB\-\-lzma\fR enables \s-1LZMA\s0 compression, which compresses better but The option \fB\-\-lzma\fR enables LZMA compression, which compresses better but
is *significantly slower* at decompression. You probably do not want is *significantly slower* at decompression. You probably do not want
to use it for large files. to use it for large files.
.Sp .Sp
(Note that \fB\-\-lzma\fR is automatically enabled by \fB\-\-all\-methods\fR and (Note that \fB\-\-lzma\fR is automatically enabled by \fB\-\-all\-methods\fR and
\&\fB\-\-brute\fR, use \fB\-\-no\-lzma\fR to override.) \&\fB\-\-brute\fR, use \fB\-\-no\-lzma\fR to override.)
.IP "\(bu" 4 .IP \(bu 4
Try if \fB\-\-overlay=strip\fR works. Try if \fB\-\-overlay=strip\fR works.
.IP "\(bu" 4 .IP \(bu 4
For win32/pe programs there's \fB\-\-strip\-relocs=0\fR. See notes below. For win32/pe programs there's \fB\-\-strip\-relocs=0\fR. See notes below.
.SH "OVERLAY HANDLING OPTIONS" .SH "OVERLAY HANDLING OPTIONS"
.IX Header "OVERLAY HANDLING OPTIONS" .IX Header "OVERLAY HANDLING OPTIONS"
Info: An \*(L"overlay\*(R" means auxiliary data attached after the logical end of Info: An "overlay" means auxiliary data attached after the logical end of
an executable, and it often contains application specific data an executable, and it often contains application specific data
(this is a common practice to avoid an extra data file, though (this is a common practice to avoid an extra data file, though
it would be better to use resource sections). it would be better to use resource sections).
.PP .PP
\&\fB\s-1UPX\s0\fR handles overlays like many other executable packers do: it simply \&\fBUPX\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 overlaid data. actually accesses this overlaid data.
@@ -309,8 +231,8 @@ actually accesses this overlaid data.
.Ve .Ve
.SH "ENVIRONMENT VARIABLE" .SH "ENVIRONMENT VARIABLE"
.IX Header "ENVIRONMENT VARIABLE" .IX Header "ENVIRONMENT VARIABLE"
The environment variable \fB\s-1UPX\s0\fR can hold a set of default The environment variable \fBUPX\fR can hold a set of default
options for \fB\s-1UPX\s0\fR. These options are interpreted first and options for \fBUPX\fR. These options are interpreted first and
can be overwritten by explicit command line parameters. can be overwritten by explicit command line parameters.
For example: For example:
.PP .PP
@@ -321,18 +243,18 @@ For example:
.Ve .Ve
.PP .PP
Under DOS/Windows you must use '#' instead of '=' when setting the Under DOS/Windows you must use '#' instead of '=' when setting the
environment variable because of a \s-1COMMAND.COM\s0 limitation. environment variable because of a COMMAND.COM limitation.
.PP .PP
Not all of the options are valid in the environment variable \- Not all of the options are valid in the environment variable \-
\&\fB\s-1UPX\s0\fR will tell you. \&\fBUPX\fR will tell you.
.PP .PP
You can explicitly use the \fB\-\-no\-env\fR option to ignore the You can explicitly use the \fB\-\-no\-env\fR option to ignore the
environment variable. environment variable.
.SH "NOTES FOR THE SUPPORTED EXECUTABLE FORMATS" .SH "NOTES FOR THE SUPPORTED EXECUTABLE FORMATS"
.IX Header "NOTES FOR THE SUPPORTED EXECUTABLE FORMATS" .IX Header "NOTES FOR THE SUPPORTED EXECUTABLE FORMATS"
.SS "\s-1NOTES FOR ATARI/TOS\s0" .SS "NOTES FOR ATARI/TOS"
.IX Subsection "NOTES FOR ATARI/TOS" .IX Subsection "NOTES FOR ATARI/TOS"
This is the executable format used by the Atari \s-1ST/TT,\s0 a Motorola 68000 This is the executable format used by the Atari ST/TT, a Motorola 68000
based personal computer which was popular in the late '80s. Support based personal computer which was popular in the late '80s. Support
of this format is only because of nostalgic feelings of one of of this format is only because of nostalgic feelings of one of
the authors and serves no practical purpose :\-). the authors and serves no practical purpose :\-).
@@ -349,12 +271,12 @@ Extra options available for this executable format:
\& the compression ratio in some cases, but usually \& the compression ratio in some cases, but usually
\& the default method gives the best results anyway. \& the default method gives the best results anyway.
.Ve .Ve
.SS "\s-1NOTES FOR BVMLINUZ/I386\s0" .SS "NOTES FOR BVMLINUZ/I386"
.IX Subsection "NOTES FOR BVMLINUZ/I386" .IX Subsection "NOTES FOR BVMLINUZ/I386"
Same as vmlinuz/i386. Same as vmlinuz/i386.
.SS "\s-1NOTES FOR DOS/COM\s0" .SS "NOTES FOR DOS/COM"
.IX Subsection "NOTES FOR DOS/COM" .IX Subsection "NOTES FOR DOS/COM"
Obviously \fB\s-1UPX\s0\fR won't work with executables that want to read data from Obviously \fBUPX\fR won't work with executables that want to read data from
themselves (like some commandline utilities that ship with Win95/98/ME). themselves (like some commandline utilities that ship with Win95/98/ME).
.PP .PP
Compressed programs only work on a 286+. Compressed programs only work on a 286+.
@@ -378,11 +300,11 @@ Extra options available for this executable format:
\& the compression ratio in some cases, but usually \& the compression ratio in some cases, but usually
\& the default filter gives the best results anyway. \& the default filter gives the best results anyway.
.Ve .Ve
.SS "\s-1NOTES FOR DOS/EXE\s0" .SS "NOTES FOR DOS/EXE"
.IX Subsection "NOTES FOR DOS/EXE" .IX Subsection "NOTES FOR DOS/EXE"
dos/exe stands for all \*(L"normal\*(R" 16\-bit \s-1DOS\s0 executables. dos/exe stands for all "normal" 16\-bit DOS executables.
.PP .PP
Obviously \fB\s-1UPX\s0\fR won't work with executables that want to read data from Obviously \fBUPX\fR won't work with executables that want to read data from
themselves (like some command line utilities that ship with Win95/98/ME). themselves (like some command line utilities that ship with Win95/98/ME).
.PP .PP
Compressed programs only work on a 286+. Compressed programs only work on a 286+.
@@ -399,7 +321,7 @@ Extra options available for this executable format:
\& the compression ratio in some cases, but usually \& the compression ratio in some cases, but usually
\& the default method gives the best results anyway. \& the default method gives the best results anyway.
.Ve .Ve
.SS "\s-1NOTES FOR DOS/SYS\s0" .SS "NOTES FOR DOS/SYS"
.IX Subsection "NOTES FOR DOS/SYS" .IX Subsection "NOTES FOR DOS/SYS"
Compressed programs only work on a 286+. Compressed programs only work on a 286+.
.PP .PP
@@ -422,20 +344,20 @@ Extra options available for this executable format:
\& the compression ratio in some cases, but usually \& the compression ratio in some cases, but usually
\& the default filter gives the best results anyway. \& the default filter gives the best results anyway.
.Ve .Ve
.SS "\s-1NOTES FOR DJGPP2/COFF\s0" .SS "NOTES FOR DJGPP2/COFF"
.IX Subsection "NOTES FOR DJGPP2/COFF" .IX Subsection "NOTES FOR DJGPP2/COFF"
First of all, it is recommended to use \fB\s-1UPX\s0\fR *instead* of \fBstrip\fR. strip has First of all, it is recommended to use \fBUPX\fR *instead* of \fBstrip\fR. strip has
the very bad habit of replacing your stub with its own (outdated) version. the very bad habit of replacing your stub with its own (outdated) version.
Additionally \fB\s-1UPX\s0\fR corrects a bug/feature in strip v2.8.x: it Additionally \fBUPX\fR corrects a bug/feature in strip v2.8.x: it
will fix the 4 KiB alignment of the stub. will fix the 4 KiB alignment of the stub.
.PP .PP
\&\fB\s-1UPX\s0\fR includes the full functionality of stubify. This means it will \&\fBUPX\fR includes the full functionality of stubify. This means it will
automatically stubify your \s-1COFF\s0 files. Use the option \fB\-\-coff\fR to automatically stubify your COFF files. Use the option \fB\-\-coff\fR to
disable this functionality (see below). disable this functionality (see below).
.PP .PP
\&\fB\s-1UPX\s0\fR automatically handles Allegro packfiles. \&\fBUPX\fR automatically handles Allegro packfiles.
.PP .PP
The \s-1DLM\s0 format (a rather exotic shared library extension) is not supported. The DLM format (a rather exotic shared library extension) is not supported.
.PP .PP
Packed programs will be byte-identical to the original after uncompression. Packed programs will be byte-identical to the original after uncompression.
All debug information and trailing garbage will be stripped, though. All debug information and trailing garbage will be stripped, though.
@@ -456,7 +378,7 @@ Extra options available for this executable format:
\& the compression ratio in some cases, but usually \& the compression ratio in some cases, but usually
\& the default filter gives the best results anyway. \& the default filter gives the best results anyway.
.Ve .Ve
.SS "\s-1NOTES FOR LINUX\s0 [general]" .SS "NOTES FOR LINUX [general]"
.IX Subsection "NOTES FOR LINUX [general]" .IX Subsection "NOTES FOR LINUX [general]"
Introduction Introduction
.PP .PP
@@ -593,15 +515,15 @@ General notes:
\& been modified after compression. \& been modified after compression.
\& Running \`strace \-o strace.log compressed_file\*(Aq will tell you more. \& Running \`strace \-o strace.log compressed_file\*(Aq will tell you more.
.Ve .Ve
.SS "\s-1NOTES FOR LINUX/ELF386\s0" .SS "NOTES FOR LINUX/ELF386"
.IX Subsection "NOTES FOR LINUX/ELF386" .IX Subsection "NOTES FOR LINUX/ELF386"
Please read the general Linux description first. Please read the general Linux description first.
.PP .PP
The linux/elf386 format decompresses directly into \s-1RAM,\s0 The linux/elf386 format decompresses directly into RAM,
uses only one exec, does not use space in /tmp, uses only one exec, does not use space in /tmp,
and does not use /proc. and does not use /proc.
.PP .PP
Linux/elf386 is automatically selected for Linux \s-1ELF\s0 executables. Linux/elf386 is automatically selected for Linux ELF executables.
.PP .PP
Packed programs will be byte-identical to the original after uncompression. Packed programs will be byte-identical to the original after uncompression.
.PP .PP
@@ -641,12 +563,12 @@ Extra options available for this executable format:
.Vb 1 .Vb 1
\& (none) \& (none)
.Ve .Ve
.SS "\s-1NOTES FOR LINUX/SH386\s0" .SS "NOTES FOR LINUX/SH386"
.IX Subsection "NOTES FOR LINUX/SH386" .IX Subsection "NOTES FOR LINUX/SH386"
Please read the general Linux description first. Please read the general Linux description first.
.PP .PP
Shell scripts where the underling shell accepts a ``\-c'' argument Shell scripts where the underling shell accepts a ``\-c'' argument
can use the Linux/sh386 format. \fB\s-1UPX\s0\fR decompresses the shell script can use the Linux/sh386 format. \fBUPX\fR decompresses the shell script
into low memory, then maps the shell and passes the entire text of the into low memory, then maps the shell and passes the entire text of the
script as an argument with a leading ``\-c''. script as an argument with a leading ``\-c''.
It does not use space in /tmp, and does not use /proc. It does not use space in /tmp, and does not use /proc.
@@ -691,7 +613,7 @@ Extra options available for this executable format:
.Vb 1 .Vb 1
\& (none) \& (none)
.Ve .Ve
.SS "\s-1NOTES FOR LINUX/386\s0" .SS "NOTES FOR LINUX/386"
.IX Subsection "NOTES FOR LINUX/386" .IX Subsection "NOTES FOR LINUX/386"
Please read the general Linux description first. Please read the general Linux description first.
.PP .PP
@@ -764,10 +686,10 @@ Extra options available for this executable format:
\& format, i.e. do not try the linux/elf386 and \& format, i.e. do not try the linux/elf386 and
\& linux/sh386 formats. \& linux/sh386 formats.
.Ve .Ve
.SS "\s-1NOTES FOR PS1/EXE\s0" .SS "NOTES FOR PS1/EXE"
.IX Subsection "NOTES FOR PS1/EXE" .IX Subsection "NOTES FOR PS1/EXE"
This is the executable format used by the Sony PlayStation (PSone), This is the executable format used by the Sony PlayStation (PSone),
a \s-1MIPS R3000\s0 based gaming console which is popular since the late '90s. a MIPS R3000 based gaming console which is popular since the late '90s.
Support of this format is very similar to the Atari one, because of Support of this format is very similar to the Atari one, because of
nostalgic feelings of one of the authors. nostalgic feelings of one of the authors.
.PP .PP
@@ -816,12 +738,12 @@ Extra options available for this executable format:
\& but the compressed executable will not boot from a CD. \& but the compressed executable will not boot from a CD.
\& Use it for console transfer only ! \& Use it for console transfer only !
.Ve .Ve
.SS "\s-1NOTES FOR RTM32/PE\s0 and \s-1ARM/PE\s0" .SS "NOTES FOR RTM32/PE and ARM/PE"
.IX Subsection "NOTES FOR RTM32/PE and ARM/PE" .IX Subsection "NOTES FOR RTM32/PE and ARM/PE"
Same as win32/pe. Same as win32/pe.
.SS "\s-1NOTES FOR TMT/ADAM\s0" .SS "NOTES FOR TMT/ADAM"
.IX Subsection "NOTES FOR TMT/ADAM" .IX Subsection "NOTES FOR TMT/ADAM"
This format is used by the \s-1TMT\s0 Pascal compiler \- see http://www.tmt.com/ . This format is used by the TMT Pascal compiler \- see http://www.tmt.com/ .
.PP .PP
Extra options available for this executable format: Extra options available for this executable format:
.PP .PP
@@ -836,11 +758,11 @@ Extra options available for this executable format:
\& the compression ratio in some cases, but usually \& the compression ratio in some cases, but usually
\& the default filter gives the best results anyway. \& the default filter gives the best results anyway.
.Ve .Ve
.SS "\s-1NOTES FOR VMLINUZ/386\s0" .SS "NOTES FOR VMLINUZ/386"
.IX Subsection "NOTES FOR VMLINUZ/386" .IX Subsection "NOTES FOR VMLINUZ/386"
The vmlinuz/386 and bvmlinuz/386 formats take a gzip-compressed The vmlinuz/386 and bvmlinuz/386 formats take a gzip-compressed
bootable Linux kernel image (\*(L"vmlinuz\*(R", \*(L"zImage\*(R", \*(L"bzImage\*(R"), bootable Linux kernel image ("vmlinuz", "zImage", "bzImage"),
gzip-decompress it and re-compress it with the \fB\s-1UPX\s0\fR compression method. gzip-decompress it and re-compress it with the \fBUPX\fR compression method.
.PP .PP
vmlinuz/386 is completely unrelated to the other Linux executable vmlinuz/386 is completely unrelated to the other Linux executable
formats, and it does not share any of their drawbacks. formats, and it does not share any of their drawbacks.
@@ -889,14 +811,14 @@ Extra options available for this executable format:
\& the compression ratio in some cases, but usually \& the compression ratio in some cases, but usually
\& the default filter gives the best results anyway. \& the default filter gives the best results anyway.
.Ve .Ve
.SS "\s-1NOTES FOR WATCOM/LE\s0" .SS "NOTES FOR WATCOM/LE"
.IX Subsection "NOTES FOR WATCOM/LE" .IX Subsection "NOTES FOR WATCOM/LE"
\&\fB\s-1UPX\s0\fR has been successfully tested with the following extenders: \&\fBUPX\fR has been successfully tested with the following extenders:
\s-1DOS4G, DOS4GW, PMODE/W,\s0 DOS32a, CauseWay. DOS4G, DOS4GW, PMODE/W, DOS32a, CauseWay.
The \s-1WDOS/X\s0 extender is partly supported (for details The WDOS/X extender is partly supported (for details
see the file bugs \s-1BUGS\s0). see the file bugs BUGS).
.PP .PP
DLLs and the \s-1LX\s0 format are not supported. DLLs and the LX format are not supported.
.PP .PP
Extra options available for this executable format: Extra options available for this executable format:
.PP .PP
@@ -904,12 +826,12 @@ Extra options available for this executable format:
\& \-\-le Produce an unbound LE output instead of \& \-\-le Produce an unbound LE output instead of
\& keeping the current stub. \& keeping the current stub.
.Ve .Ve
.SS "\s-1NOTES FOR WIN32/PE\s0" .SS "NOTES FOR WIN32/PE"
.IX Subsection "NOTES FOR WIN32/PE" .IX Subsection "NOTES FOR WIN32/PE"
The \s-1PE\s0 support in \fB\s-1UPX\s0\fR is quite stable now, but probably there are The PE support in \fBUPX\fR is quite stable now, but probably there are
still some incompatibilities with some files. still some incompatibilities with some files.
.PP .PP
Because of the way \fB\s-1UPX\s0\fR (and other packers for this format) works, you Because of the way \fBUPX\fR (and other packers for this format) works, you
can see increased memory usage of your compressed files because the whole can see increased memory usage of your compressed files because the whole
program is loaded into memory at startup. program is loaded into memory at startup.
If you start several instances of huge compressed programs you're If you start several instances of huge compressed programs you're
@@ -922,17 +844,17 @@ smaller, but it's still there.
If you're running executables from network, then compressed programs If you're running executables from network, then compressed programs
will load faster, and require less bandwidth during execution. will load faster, and require less bandwidth during execution.
.PP .PP
DLLs are supported. But \s-1UPX\s0 compressed DLLs can not share common data and DLLs are supported. But UPX compressed DLLs can not share common data and
code when they got used by multiple applications. So compressing msvcrt.dll code when they got used by multiple applications. So compressing msvcrt.dll
is a waste of memory, but compressing the dll plugins of a particular is a waste of memory, but compressing the dll plugins of a particular
application may be a better idea. application may be a better idea.
.PP .PP
Screensavers are supported, with the restriction that the filename Screensavers are supported, with the restriction that the filename
must end with \*(L".scr\*(R" (as screensavers are handled slightly different must end with ".scr" (as screensavers are handled slightly different
than normal exe files). than normal exe files).
.PP .PP
\&\s-1UPX\s0 compressed \s-1PE\s0 files have some minor memory overhead (usually in the UPX compressed PE files have some minor memory overhead (usually in the
10 \- 30 KiB range) which can be seen by specifying the \*(L"\-i\*(R" command 10 \- 30 KiB range) which can be seen by specifying the "\-i" command
line switch during compression. line switch during compression.
.PP .PP
Extra options available for this executable format: Extra options available for this executable format:
@@ -996,16 +918,16 @@ Extra options available for this executable format:
\& the compression ratio in some cases, but usually \& the compression ratio in some cases, but usually
\& the default filter gives the best results anyway. \& the default filter gives the best results anyway.
.Ve .Ve
.SH "DIAGNOSTICS" .SH DIAGNOSTICS
.IX Header "DIAGNOSTICS" .IX Header "DIAGNOSTICS"
Exit status is normally 0; if an error occurs, exit status Exit status is normally 0; if an error occurs, exit status
is 1. If a warning occurs, exit status is 2. is 1. If a warning occurs, exit status is 2.
.PP .PP
\&\fB\s-1UPX\s0\fR's diagnostics are intended to be self-explanatory. \&\fBUPX\fR's diagnostics are intended to be self-explanatory.
.SH "BUGS" .SH BUGS
.IX Header "BUGS" .IX Header "BUGS"
Please report all bugs immediately to the authors. Please report all bugs immediately to the authors.
.SH "AUTHORS" .SH AUTHORS
.IX Header "AUTHORS" .IX Header "AUTHORS"
.Vb 2 .Vb 2
\& Markus F.X.J. Oberhumer <markus@oberhumer.com> \& Markus F.X.J. Oberhumer <markus@oberhumer.com>
@@ -1014,29 +936,25 @@ Please report all bugs immediately to the authors.
\& Laszlo Molnar <ezerotven+github@gmail.com> \& Laszlo Molnar <ezerotven+github@gmail.com>
\& \&
\& John F. Reiser <jreiser@BitWagon.com> \& John F. Reiser <jreiser@BitWagon.com>
\&
\& Jens Medoch <jssg@users.sourceforge.net>
.Ve .Ve
.SH "COPYRIGHT" .SH COPYRIGHT
.IX Header "COPYRIGHT" .IX Header "COPYRIGHT"
Copyright (C) 1996\-2023 Markus Franz Xaver Johannes Oberhumer Copyright (C) 1996\-2024 Markus Franz Xaver Johannes Oberhumer
.PP .PP
Copyright (C) 1996\-2023 Laszlo Molnar Copyright (C) 1996\-2024 Laszlo Molnar
.PP .PP
Copyright (C) 2000\-2023 John F. Reiser Copyright (C) 2000\-2024 John F. Reiser
.PP .PP
Copyright (C) 2002\-2023 Jens Medoch \&\fBUPX\fR is distributed with full source code under the terms of the
.PP GNU General Public License v2+; either under the pure GPLv2+ (see
\&\fB\s-1UPX\s0\fR is distributed with full source code under the terms of the the file COPYING), or (at your option) under the GPLv+2 with special
\&\s-1GNU\s0 General Public License v2+; either under the pure GPLv2+ (see
the file \s-1COPYING\s0), or (at your option) under the GPLv+2 with special
exceptions and restrictions granting the free usage for all binaries exceptions and restrictions granting the free usage for all binaries
including commercial programs (see the file \s-1LICENSE\s0). including commercial programs (see the file LICENSE).
.PP .PP
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but \s-1WITHOUT ANY WARRANTY\s0; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
\&\s-1MERCHANTABILITY\s0 or \s-1FITNESS FOR A PARTICULAR PURPOSE.\s0 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
.PP .PP
You should have received a copy of the \s-1UPX\s0 License Agreements along You should have received a copy of the UPX License Agreements along
with this program; see the files \s-1COPYING\s0 and \s-1LICENSE.\s0 If not, with this program; see the files COPYING and LICENSE. If not,
visit the \s-1UPX\s0 home page. visit the UPX home page.
+4 -8
View File
@@ -13,7 +13,7 @@ B<upx> S<[ I<command> ]> S<[ I<options> ]> I<filename>...
=head1 ABSTRACT =head1 ABSTRACT
The Ultimate Packer for eXecutables The Ultimate Packer for eXecutables
Copyright (c) 1996-2023 Markus Oberhumer, Laszlo Molnar & John Reiser Copyright (c) 1996-2024 Markus Oberhumer, Laszlo Molnar & John Reiser
https://upx.github.io https://upx.github.io
@@ -926,19 +926,15 @@ Please report all bugs immediately to the authors.
John F. Reiser <jreiser@BitWagon.com> John F. Reiser <jreiser@BitWagon.com>
Jens Medoch <jssg@users.sourceforge.net>
=head1 COPYRIGHT =head1 COPYRIGHT
Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer Copyright (C) 1996-2024 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2023 Laszlo Molnar Copyright (C) 1996-2024 Laszlo Molnar
Copyright (C) 2000-2023 John F. Reiser Copyright (C) 2000-2024 John F. Reiser
Copyright (C) 2002-2023 Jens Medoch
B<UPX> is distributed with full source code under the terms of the B<UPX> is distributed with full source code under the terms of the
GNU General Public License v2+; either under the pure GPLv2+ (see GNU General Public License v2+; either under the pure GPLv2+ (see
+4 -2
View File
@@ -1,4 +1,6 @@
# for clang-tidy-16 from https://clang.llvm.org/extra/clang-tidy/ # vim:set ft=yaml ts=2 sw=2 et:
# Copyright (C) Markus Franz Xaver Johannes Oberhumer
# for clang-tidy from https://clang.llvm.org/extra/clang-tidy/
--- ---
Checks: > Checks: >
-*, -*,
@@ -14,7 +16,7 @@ Checks: >
-clang-analyzer-core.UndefinedBinaryOperatorResult, -clang-analyzer-core.UndefinedBinaryOperatorResult,
-clang-analyzer-core.uninitialized.Assign, -clang-analyzer-core.uninitialized.Assign,
-clang-analyzer-security.insecureAPI.strcpy, -clang-analyzer-security.insecureAPI.strcpy,
clang-diagnostics-*', clang-diagnostic-*,
performance-*, performance-*,
FormatStyle: file FormatStyle: file
HeaderFilterRegex: '.*' HeaderFilterRegex: '.*'
+6 -2
View File
@@ -1,18 +1,22 @@
# for clang-tidy-16 from https://clang.llvm.org/extra/clang-tidy/ # vim:set ft=yaml ts=2 sw=2 et:
# Copyright (C) Markus Franz Xaver Johannes Oberhumer
# for clang-tidy from https://clang.llvm.org/extra/clang-tidy/
--- ---
Checks: > Checks: >
-*, -*,
bugprone-*, bugprone-*,
-bugprone-assignment-in-if-condition, -bugprone-assignment-in-if-condition,
-bugprone-casting-through-void,
-bugprone-easily-swappable-parameters, -bugprone-easily-swappable-parameters,
-bugprone-implicit-widening-of-multiplication-result, -bugprone-implicit-widening-of-multiplication-result,
-bugprone-inc-dec-in-conditions,
-bugprone-macro-parentheses, -bugprone-macro-parentheses,
-bugprone-reserved-identifier, -bugprone-reserved-identifier,
-bugprone-sizeof-expression, -bugprone-sizeof-expression,
-bugprone-suspicious-include, -bugprone-suspicious-include,
clang-analyzer-*, clang-analyzer-*,
-clang-analyzer-security.insecureAPI.DeprecatedOrUnsafeBufferHandling, -clang-analyzer-security.insecureAPI.DeprecatedOrUnsafeBufferHandling,
clang-diagnostics-*', clang-diagnostic-*,
performance-*, performance-*,
FormatStyle: file FormatStyle: file
HeaderFilterRegex: '.*' HeaderFilterRegex: '.*'
+5 -2
View File
@@ -1,4 +1,6 @@
# for clang-tidy-16 from https://clang.llvm.org/extra/clang-tidy/ # vim:set ft=yaml ts=2 sw=2 et:
# Copyright (C) Markus Franz Xaver Johannes Oberhumer
# for clang-tidy from https://clang.llvm.org/extra/clang-tidy/
--- ---
Checks: > Checks: >
-*, -*,
@@ -6,6 +8,7 @@ Checks: >
-bugprone-assignment-in-if-condition, -bugprone-assignment-in-if-condition,
-bugprone-easily-swappable-parameters, -bugprone-easily-swappable-parameters,
-bugprone-implicit-widening-of-multiplication-result, -bugprone-implicit-widening-of-multiplication-result,
-bugprone-inc-dec-in-conditions,
-bugprone-macro-parentheses, -bugprone-macro-parentheses,
-bugprone-narrowing-conversions, -bugprone-narrowing-conversions,
-bugprone-reserved-identifier, -bugprone-reserved-identifier,
@@ -13,7 +16,7 @@ Checks: >
clang-analyzer-*, clang-analyzer-*,
-clang-analyzer-optin.performance.Padding, -clang-analyzer-optin.performance.Padding,
-clang-analyzer-security.insecureAPI.DeprecatedOrUnsafeBufferHandling, -clang-analyzer-security.insecureAPI.DeprecatedOrUnsafeBufferHandling,
clang-diagnostics-*', clang-diagnostic-*,
performance-*, performance-*,
FormatStyle: file FormatStyle: file
HeaderFilterRegex: '.*' HeaderFilterRegex: '.*'
+5 -2
View File
@@ -1,10 +1,13 @@
# for clang-tidy-16 from https://clang.llvm.org/extra/clang-tidy/ # vim:set ft=yaml ts=2 sw=2 et:
# Copyright (C) Markus Franz Xaver Johannes Oberhumer
# for clang-tidy from https://clang.llvm.org/extra/clang-tidy/
--- ---
Checks: > Checks: >
-*, -*,
bugprone-*, bugprone-*,
-bugprone-assignment-in-if-condition, -bugprone-assignment-in-if-condition,
-bugprone-branch-clone, -bugprone-branch-clone,
-bugprone-casting-through-void,
-bugprone-easily-swappable-parameters, -bugprone-easily-swappable-parameters,
-bugprone-implicit-widening-of-multiplication-result, -bugprone-implicit-widening-of-multiplication-result,
-bugprone-macro-parentheses, -bugprone-macro-parentheses,
@@ -16,7 +19,7 @@ Checks: >
-clang-analyzer-core.UndefinedBinaryOperatorResult, -clang-analyzer-core.UndefinedBinaryOperatorResult,
-clang-analyzer-deadcode.DeadStores, -clang-analyzer-deadcode.DeadStores,
-clang-analyzer-security.insecureAPI.DeprecatedOrUnsafeBufferHandling, -clang-analyzer-security.insecureAPI.DeprecatedOrUnsafeBufferHandling,
clang-diagnostics-*', clang-diagnostic-*,
performance-*, performance-*,
-performance-no-int-to-ptr, -performance-no-int-to-ptr,
FormatStyle: file FormatStyle: file
+8 -8
View File
@@ -257,7 +257,7 @@ def main():
parser.add_argument( parser.add_argument(
"-allow-enabling-alpha-checkers", "-allow-enabling-alpha-checkers",
action="store_true", action="store_true",
help="allow alpha checkers from " "clang-analyzer.", help="allow alpha checkers from clang-analyzer.",
) )
parser.add_argument( parser.add_argument(
"-clang-tidy-binary", metavar="PATH", help="path to clang-tidy binary" "-clang-tidy-binary", metavar="PATH", help="path to clang-tidy binary"
@@ -270,7 +270,7 @@ def main():
parser.add_argument( parser.add_argument(
"-checks", "-checks",
default=None, default=None,
help="checks filter, when not specified, use clang-tidy " "default", help="checks filter, when not specified, use clang-tidy default",
) )
config_group = parser.add_mutually_exclusive_group() config_group = parser.add_mutually_exclusive_group()
config_group.add_argument( config_group.add_argument(
@@ -303,7 +303,7 @@ def main():
parser.add_argument( parser.add_argument(
"-line-filter", "-line-filter",
default=None, default=None,
help="List of files with line ranges to filter the" "warnings.", help="List of files with line ranges to filter the warnings.",
) )
if yaml: if yaml:
parser.add_argument( parser.add_argument(
@@ -335,12 +335,12 @@ def main():
) )
parser.add_argument("-fix", action="store_true", help="apply fix-its") parser.add_argument("-fix", action="store_true", help="apply fix-its")
parser.add_argument( parser.add_argument(
"-format", action="store_true", help="Reformat code " "after applying fixes" "-format", action="store_true", help="Reformat code after applying fixes"
) )
parser.add_argument( parser.add_argument(
"-style", "-style",
default="file", default="file",
help="The style of reformat " "code after applying fixes", help="The style of reformat code after applying fixes",
) )
parser.add_argument( parser.add_argument(
"-use-color", "-use-color",
@@ -359,14 +359,14 @@ def main():
dest="extra_arg", dest="extra_arg",
action="append", action="append",
default=[], default=[],
help="Additional argument to append to the compiler " "command line.", help="Additional argument to append to the compiler command line.",
) )
parser.add_argument( parser.add_argument(
"-extra-arg-before", "-extra-arg-before",
dest="extra_arg_before", dest="extra_arg_before",
action="append", action="append",
default=[], default=[],
help="Additional argument to prepend to the compiler " "command line.", help="Additional argument to prepend to the compiler command line.",
) )
parser.add_argument( parser.add_argument(
"-quiet", action="store_true", help="Run clang-tidy in quiet mode" "-quiet", action="store_true", help="Run clang-tidy in quiet mode"
@@ -381,7 +381,7 @@ def main():
parser.add_argument( parser.add_argument(
"-warnings-as-errors", "-warnings-as-errors",
default=None, default=None,
help="Upgrades warnings to errors. Same format as " "'-checks'", help="Upgrades warnings to errors. Same format as '-checks'",
) )
args = parser.parse_args() args = parser.parse_args()
+382
View File
@@ -0,0 +1,382 @@
#
# UPX "CMake" build file; see https://cmake.org/
# Copyright (C) Markus Franz Xaver Johannes Oberhumer
#
# set USE_STRICT_DEFAULTS
if(NOT DEFINED USE_STRICT_DEFAULTS AND IS_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/.git")
include("${CMAKE_CURRENT_SOURCE_DIR}/misc/cmake/use_strict_defaults.cmake" OPTIONAL)
endif()
if(NOT DEFINED USE_STRICT_DEFAULTS)
# use permissive config defaults when building from source code tarball
set(USE_STRICT_DEFAULTS FALSE CACHE INTERNAL "" FORCE)
endif()
#***********************************************************************
# macros
#***********************************************************************
# support config hooks; developer convenience
macro(upx_cmake_include_hook section)
include("${CMAKE_CURRENT_SOURCE_DIR}/misc/cmake/hooks/CMakeLists.${section}.txt" OPTIONAL)
include("${CMAKE_CURRENT_SOURCE_DIR}/maint/make/CMakeLists.${section}.txt" OPTIONAL)
endmacro()
# Disallow in-source build. Note that you will still have to manually
# clean up a few files if you accidentally try an in-source build.
macro(upx_disallow_in_source_build)
set(CMAKE_DISABLE_IN_SOURCE_BUILD ON)
set(CMAKE_DISABLE_SOURCE_CHANGES ON)
if(",${CMAKE_CURRENT_SOURCE_DIR}," STREQUAL ",${CMAKE_CURRENT_BINARY_DIR},")
# try to clean up (does not work)
#file(REMOVE "${CMAKE_CURRENT_BINARY_DIR}/CMakeCache.txt")
#file(REMOVE "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/cmake.check_cache")
message(FATAL_ERROR "ERROR: In-source builds are not allowed, please use an extra build dir.")
endif()
endmacro()
# set the default build type; must be called before project() cmake init
macro(upx_set_default_build_type type)
set(upx_global_default_build_type "${type}")
get_property(upx_global_is_multi_config GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG)
if(NOT upx_global_is_multi_config AND NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE "${upx_global_default_build_type}" CACHE STRING "Choose the type of build." FORCE)
endif()
endmacro()
# set the default multi-config build type; must be called after project() cmake init
macro(upx_apply_build_type)
if(upx_global_is_multi_config)
set(c "${CMAKE_CONFIGURATION_TYPES}")
list(INSERT c 0 "${upx_global_default_build_type}")
if(CMAKE_BUILD_TYPE)
list(INSERT c 0 "${CMAKE_BUILD_TYPE}")
endif()
list(REMOVE_DUPLICATES c)
set(CMAKE_CONFIGURATION_TYPES "${c}" CACHE STRING "List of supported configuration types." FORCE)
endif()
# now also set the build type for use in try_compile()
if(NOT CMAKE_TRY_COMPILE_CONFIGURATION)
if(CMAKE_BUILD_TYPE)
set(CMAKE_TRY_COMPILE_CONFIGURATION "${CMAKE_BUILD_TYPE}")
else()
set(CMAKE_TRY_COMPILE_CONFIGURATION "${upx_global_default_build_type}")
endif()
endif()
endmacro()
# ternary conditional operator
macro(upx_ternary result_var_name condition true_value false_value)
if(${condition})
set(${result_var_name} "${true_value}")
else()
set(${result_var_name} "${false_value}")
endif()
endmacro()
#***********************************************************************
# util
#***********************************************************************
# convert to CMake bool
function(upx_make_bool_var result_var_name var_name default_value)
set(result "${default_value}")
# only query $var_name if it is defined and not empty
if(NOT ",${var_name}," STREQUAL ",,")
if(DEFINED ${var_name})
if(NOT ",${${var_name}}," STREQUAL ",,")
set(result "${${var_name}}")
endif()
endif()
endif()
if(${result})
set(result ON)
else()
set(result OFF)
endif()
set(${result_var_name} "${result}" PARENT_SCOPE) # return value
endfunction()
function(upx_print_var) # ARGV
foreach(var_name ${ARGV})
if(DEFINED ${var_name})
if(NOT ",${${var_name}}," STREQUAL ",,")
if(${var_name})
message(STATUS "${var_name} = ${${var_name}}")
endif()
endif()
endif()
endforeach()
endfunction()
function(upx_print_env_var) # ARGV
foreach(var_name ${ARGV})
if(DEFINED ENV{${var_name}})
if(NOT ",$ENV{${var_name}}," STREQUAL ",,")
message(STATUS "ENV{${var_name}} = '$ENV{${var_name}}'")
endif()
endif()
endforeach()
endfunction()
function(upx_print_have_symbol) # ARGV; needs include(CheckSymbolExists)
set(rq "${CMAKE_REQUIRED_QUIET}")
set(CMAKE_REQUIRED_QUIET ON)
foreach(symbol ${ARGV})
set(cache_var_name "HAVE_symbol_${symbol}")
check_symbol_exists("${symbol}" "limits.h;stddef.h;stdint.h" "${cache_var_name}")
if(${cache_var_name})
message(STATUS "HAVE_symbol ${symbol}")
endif()
endforeach()
set(CMAKE_REQUIRED_QUIET "${rq}")
endfunction()
# examine compiler configuration
function(upx_print_common_symbols)
upx_print_have_symbol(__FAST_MATH__)
upx_print_have_symbol(__PIC__ __pic__ __PIE__ __pie__)
endfunction()
# examine MinGW/Cygwin compiler configuration
function(upx_print_mingw_symbols)
if(WIN32 OR MINGW OR CYGWIN)
if(CMAKE_C_COMPILER_ID MATCHES "(Clang|GNU)")
# runtime library: msvcrt vs ucrt vs cygwin
upx_print_have_symbol(__CRTDLL__ __CYGWIN__ __CYGWIN32__ __CYGWIN64__ __MINGW32__ __MINGW64__ __MINGW64_VERSION_MAJOR __MSVCRT__ __MSVCRT_VERSION__ _UCRT _WIN32 _WIN32_WINNT _WIN64)
# exception handing: SJLJ (setjmp/longjmp) vs DWARF vs SEH
upx_print_have_symbol(__GCC_HAVE_DWARF2_CFI_ASM __SEH__ __USING_SJLJ_EXCEPTIONS__)
# threads: win32 vs posix/pthread/winpthreads vs mcfgthread
upx_print_have_symbol(_REENTRANT __USING_MCFGTHREAD__)
endif()
endif()
endfunction()
# add wildcard expansions to a variable
function(upx_add_glob_files) # ARGV
set(var_name ${ARGV0})
list(REMOVE_AT ARGV 0)
if(${CMAKE_VERSION} VERSION_LESS "3.3")
file(GLOB files ${ARGV})
else()
file(GLOB files LIST_DIRECTORIES false ${ARGV})
endif()
set(result "")
if(DEFINED ${var_name})
set(result "${${var_name}}")
endif()
list(APPEND result "${files}")
list(SORT result)
list(REMOVE_DUPLICATES result)
#message(STATUS "upx_add_glob_files: ${var_name} = ${result}")
set(${var_name} "${result}" PARENT_SCOPE) # return value
endfunction()
# remove wildcard expansions from a variable
function(upx_remove_glob_files) # ARGV
set(var_name ${ARGV0})
list(REMOVE_AT ARGV 0)
file(GLOB files ${ARGV})
set(result "")
if(DEFINED ${var_name})
set(result "${${var_name}}")
foreach(file ${files})
list(REMOVE_ITEM result "${file}")
endforeach()
list(SORT result)
list(REMOVE_DUPLICATES result)
endif()
#message(STATUS "upx_remove_glob_files: ${var_name} = ${result}")
set(${var_name} "${result}" PARENT_SCOPE) # return value
endfunction()
# useful for CI jobs: allow settings via environment and cache result
function(upx_cache_bool_vars) # ARGV
set(default_value "${ARGV0}")
list(REMOVE_AT ARGV 0)
foreach(var_name ${ARGV})
set(value ${default_value})
if(DEFINED UPX_CACHE_VALUE_${var_name}) # check cache
set(value "${UPX_CACHE_VALUE_${var_name}}")
elseif(DEFINED ${var_name}) # defined via "cmake -DXXX=YYY"
set(value "${${var_name}}")
elseif(DEFINED ENV{${var_name}}) # check environment
if("$ENV{${var_name}}" MATCHES "^(0|1|OFF|ON|FALSE|TRUE|off|on|false|true)$")
set(value "$ENV{${var_name}}")
set(UPX_CACHE_ORIGIN_FROM_ENV_${var_name} TRUE CACHE INTERNAL "" FORCE) # for status message below
endif()
endif()
# convert to bool
if(value)
set(value ON)
else()
set(value OFF)
endif()
# store result
if(UPX_CACHE_ORIGIN_FROM_ENV_${var_name})
message(STATUS "setting from environment: ${var_name} = ${value}")
endif()
set(${var_name} "${value}" PARENT_SCOPE) # store result
set(UPX_CACHE_VALUE_${var_name} "${value}" CACHE INTERNAL "" FORCE) # and store in cache
endforeach()
endfunction()
function(upx_platform_check_mismatch var_name_1 var_name_2)
if(DEFINED ${var_name_1} OR DEFINED ${var_name_2})
if(NOT ",${${var_name_1}}," STREQUAL ",${${var_name_2}},")
if(UPX_CONFIG_DISABLE_WERROR)
message(WARNING "WARNING: '${var_name_1}' '${var_name_2}' mismatch")
else()
message(FATAL_ERROR "FATAL ERROR: '${var_name_1}' '${var_name_2}' mismatch")
endif()
endif()
endif()
endfunction()
#***********************************************************************
# compilation flags
#***********************************************************************
function(upx_internal_add_definitions_with_prefix) # ARGV; needs include(CheckCCompilerFlag)
set(flag_prefix "${ARGV0}")
if("${flag_prefix}" MATCHES "^empty$") # need "empty" 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_name "HAVE_CFLAG_${flag}")
check_c_compiler_flag("${flag}" ${cache_var_name})
if(${cache_var_name})
#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) # ARGV; needs include(CheckCCompilerFlag)
set(failed_flags "")
if(MSVC_FRONTEND AND CMAKE_C_COMPILER_ID MATCHES "Clang")
# for clang-cl try "-clang:" flag prefix first
upx_internal_add_definitions_with_prefix("-clang:" ${ARGV})
upx_internal_add_definitions_with_prefix("empty" ${failed_flags})
else()
upx_internal_add_definitions_with_prefix("empty" ${ARGV})
endif()
endfunction()
# useful for CI jobs: allow target extra compile options
function(upx_add_target_extra_compile_options) # ARGV
set(t "${ARGV0}")
list(REMOVE_AT ARGV 0)
foreach(var_name ${ARGV})
if(NOT DEFINED ${var_name})
elseif(",${${var_name}}," STREQUAL ",,")
else()
set(flags "${${var_name}}")
if(NOT flags MATCHES ";") # NOTE: split into list from string only if not already a list
if(${CMAKE_VERSION} VERSION_GREATER "3.8.99")
separate_arguments(flags NATIVE_COMMAND "${flags}")
else()
separate_arguments(flags)
endif()
endif()
target_compile_options(${t} PRIVATE "${flags}")
endif()
endforeach()
endfunction()
# compile a target with -O2 optimization even in Debug build
function(upx_compile_target_debug_with_O2) # ARGV
foreach(t ${ARGV})
if(MSVC_FRONTEND)
# MSVC uses some Debug compilation options like -RTC1 that are incompatible with -O2
else()
target_compile_options(${t} PRIVATE $<$<CONFIG:Debug>:-O2>)
endif()
endforeach()
endfunction()
# compile a source file with -O2 optimization even in Debug build; messy because of CMake limitations
function(upx_compile_source_debug_with_O2) # ARGV
set(flags "$<$<CONFIG:Debug>:-O2>")
if(${CMAKE_VERSION} VERSION_LESS "3.8")
# 3.8: The COMPILE_FLAGS source file property learned to support generator expressions
if(upx_global_is_multi_config OR NOT CMAKE_BUILD_TYPE MATCHES "^Debug$")
return()
endif()
set(flags "-O2")
endif()
if(CMAKE_GENERATOR MATCHES "Xcode") # multi-config
# NOTE: Xcode does not support per-config per-source COMPILE_FLAGS (as of CMake 3.27.7)
return()
endif()
foreach(source ${ARGV})
if(MSVC_FRONTEND)
# MSVC uses some Debug compilation options like -RTC1 that are incompatible with -O2
else()
get_source_file_property(prop "${source}" COMPILE_FLAGS)
if("${prop}" MATCHES "^(NOTFOUND)?$")
set_source_files_properties("${source}" PROPERTIES COMPILE_FLAGS "${flags}")
else()
set_source_files_properties("${source}" PROPERTIES COMPILE_FLAGS "${prop} ${flags}")
endif()
endif()
endforeach()
endfunction()
# sanitize a target; note that this may require special run-time support libs from your toolchain
function(upx_sanitize_target) # ARGV
foreach(t ${ARGV})
if(UPX_CONFIG_DISABLE_SANITIZE)
# no-op
elseif(MSVC_FRONTEND)
# MSVC uses -GS (similar to -fstack-protector) by default
elseif(NOT GNU_FRONTEND)
# unknown compiler
elseif(MINGW OR CYGWIN)
# avoid link errors with current MinGW-w64 versions
# see https://www.mingw-w64.org/contribute/#sanitizers-asan-tsan-usan
elseif(CMAKE_C_COMPILER_ID MATCHES "^Clang$" AND CMAKE_C_COMPILER_VERSION VERSION_LESS "9.0")
# unreliable/broken sanitize implementation before clang-9 (Sep 2019)
message(WARNING "WARNING: ignoring SANITIZE for target '${t}'")
elseif(CMAKE_C_COMPILER_ID MATCHES "^GNU" AND CMAKE_C_COMPILER_VERSION VERSION_LESS "8.0")
# unsupported compiler; unreliable/broken sanitize implementation before gcc-8 (May 2018)
message(WARNING "WARNING: ignoring SANITIZE for target '${t}'")
else()
# default sanitizer for Debug builds
target_compile_options(${t} PRIVATE $<$<CONFIG:Debug>:-fsanitize=undefined -fsanitize-undefined-trap-on-error -fstack-protector-all>)
# default sanitizer for Release builds
target_compile_options(${t} PRIVATE $<$<CONFIG:MinSizeRel>:-fstack-protector>)
target_compile_options(${t} PRIVATE $<$<CONFIG:Release>:-fstack-protector>)
target_compile_options(${t} PRIVATE $<$<CONFIG:RelWithDebInfo>:-fstack-protector>)
endif()
endforeach()
endfunction()
#***********************************************************************
# test
#***********************************************************************
function(upx_add_test) # ARGV
set(name "${ARGV0}")
list(REMOVE_AT ARGV 0)
add_test(NAME "${name}" COMMAND ${ARGV})
endfunction()
function(upx_test_depends) # ARGV
set(name "${ARGV0}")
list(REMOVE_AT ARGV 0)
get_property(prop TEST "${name}" PROPERTY DEPENDS)
if("${prop}" MATCHES "^(NOTFOUND)?$")
set_tests_properties("${name}" PROPERTIES DEPENDS "${ARGV}")
else()
set_tests_properties("${name}" PROPERTIES DEPENDS "${prop};${ARGV}")
endif()
endfunction()
# vim:set ft=cmake ts=4 sw=4 tw=0 et:
+48
View File
@@ -0,0 +1,48 @@
#
# UPX "CMake" build file; see https://cmake.org/
# Copyright (C) Markus Franz Xaver Johannes Oberhumer
#
#***********************************************************************
# summary section
# print some info about the build configuration
#***********************************************************************
# generator
upx_print_var(CMAKE_GENERATOR_TOOLSET CMAKE_GENERATOR_PLATFORM)
# directories
if(NOT ",${CMAKE_BINARY_DIR}," STREQUAL ",${CMAKE_CURRENT_BINARY_DIR}," OR NOT ",${CMAKE_SOURCE_DIR}," STREQUAL ",${CMAKE_CURRENT_SOURCE_DIR},")
upx_print_var(CMAKE_BINARY_DIR CMAKE_SOURCE_DIR CMAKE_CURRENT_BINARY_DIR CMAKE_CURRENT_SOURCE_DIR)
endif()
# system
upx_print_var(CMAKE_HOST_SYSTEM_NAME CMAKE_HOST_SYSTEM_VERSION CMAKE_HOST_SYSTEM_PROCESSOR)
upx_print_var(CMAKE_SYSTEM_NAME CMAKE_SYSTEM_VERSION CMAKE_SYSTEM_PROCESSOR)
upx_print_var(CMAKE_ANDROID_NDK CMAKE_ANDROID_NDK_VERSION CMAKE_ANDROID_STANDALONE_TOOLCHAIN)
upx_print_var(CMAKE_APPLE_SILICON_PROCESSOR CMAKE_OSX_DEPLOYMENT_TARGET CMAKE_OSX_SYSROOT)
upx_print_Var(CMAKE_CROSSCOMPILING CMAKE_CROSSCOMPILING_EMULATOR)
# binutils
upx_print_var(CMAKE_AR CMAKE_RANLIB)
# compilers
foreach(lang IN ITEMS ASM C CXX)
upx_print_var(CMAKE_${lang}_COMPILER_LAUNCHER)
upx_print_var(CMAKE_${lang}_COMPILER)
upx_print_var(CMAKE_${lang}_COMPILER_ID)
upx_print_var(CMAKE_${lang}_COMPILER_VERSION)
upx_print_var(CMAKE_${lang}_COMPILER_FRONTEND_VARIANT )
upx_print_var(CMAKE_${lang}_COMPILER_ARCHITECTURE_ID)
upx_print_var(CMAKE_${lang}_PLATFORM_ID)
upx_print_var(CMAKE_${lang}_COMPILER_ABI)
upx_print_var(CMAKE_${lang}_COMPILER_TARGET)
endforeach()
# misc
upx_print_var(CMAKE_INTERPROCEDURAL_OPTIMIZATION CMAKE_POSITION_INDEPENDENT_CODE)
# shortcuts
upx_print_var(APPLE CLANG CYGWIN GNU_FRONTEND GNUC MINGW MSVC MSVC_FRONTEND MSVC_IDE MSVC_TOOLSET_VERSION MSVC_VERSION MSYS UNIX WIN32 WIN64)
# vim:set ft=cmake ts=4 sw=4 tw=0 et:
+148
View File
@@ -0,0 +1,148 @@
#
# UPX "CMake" build file; see https://cmake.org/
# Copyright (C) Markus Franz Xaver Johannes Oberhumer
#
#***********************************************************************
# test section: self-pack tests
#
# IMPORTANT NOTE: these tests can only work if the host executable format
# is supported by UPX!
#***********************************************************************
set(emu "")
if(DEFINED CMAKE_CROSSCOMPILING_EMULATOR)
set(emu "${CMAKE_CROSSCOMPILING_EMULATOR}")
endif()
set(exe "${CMAKE_EXECUTABLE_SUFFIX}")
set(upx_self_exe "$<TARGET_FILE:upx>")
set(fo "--force-overwrite")
#
# basic tests
#
upx_add_test(upx-self-pack upx -3 "${upx_self_exe}" ${fo} -o upx-packed${exe})
upx_add_test(upx-self-pack-fa upx -3 --all-filters "${upx_self_exe}" ${fo} -o upx-packed-fa${exe})
upx_add_test(upx-self-pack-fn upx -3 --no-filter "${upx_self_exe}" ${fo} -o upx-packed-fn${exe})
upx_add_test(upx-self-pack-fr upx -3 --all-filters --debug-use-random-filter "${upx_self_exe}" ${fo} -o upx-packed-fr${exe})
upx_add_test(upx-self-pack-nrv2b upx -3 --nrv2b "${upx_self_exe}" ${fo} -o upx-packed-nrv2b${exe})
upx_add_test(upx-self-pack-nrv2d upx -3 --nrv2d "${upx_self_exe}" ${fo} -o upx-packed-nrv2d${exe})
upx_add_test(upx-self-pack-nrv2e upx -3 --nrv2e "${upx_self_exe}" ${fo} -o upx-packed-nrv2e${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-fa${exe} upx-packed-fn${exe} upx-packed-fr${exe} upx-packed-nrv2b${exe} upx-packed-nrv2d${exe} upx-packed-nrv2e${exe} upx-packed-lzma${exe})
upx_add_test(upx-fileinfo upx --fileinfo upx-packed${exe} upx-packed-fa${exe} upx-packed-fn${exe} upx-packed-fr${exe} upx-packed-nrv2b${exe} upx-packed-nrv2d${exe} upx-packed-nrv2e${exe} upx-packed-lzma${exe})
upx_add_test(upx-test upx -t upx-packed${exe} upx-packed-fa${exe} upx-packed-fn${exe} upx-packed-fr${exe} upx-packed-nrv2b${exe} upx-packed-nrv2d${exe} upx-packed-nrv2e${exe} upx-packed-lzma${exe})
upx_add_test(upx-unpack upx -d upx-packed${exe} ${fo} -o upx-unpacked${exe})
upx_add_test(upx-unpack-fa upx -d upx-packed-fa${exe} ${fo} -o upx-unpacked-fa${exe})
upx_add_test(upx-unpack-fn upx -d upx-packed-fn${exe} ${fo} -o upx-unpacked-fn${exe})
upx_add_test(upx-unpack-fr upx -d upx-packed-fr${exe} ${fo} -o upx-unpacked-fr${exe})
upx_add_test(upx-unpack-nrv2b upx -d upx-packed-nrv2b${exe} ${fo} -o upx-unpacked-nrv2b${exe})
upx_add_test(upx-unpack-nrv2d upx -d upx-packed-nrv2d${exe} ${fo} -o upx-unpacked-nrv2d${exe})
upx_add_test(upx-unpack-nrv2e upx -d upx-packed-nrv2e${exe} ${fo} -o upx-unpacked-nrv2e${exe})
upx_add_test(upx-unpack-lzma upx -d upx-packed-lzma${exe} ${fo} -o upx-unpacked-lzma${exe})
# all unpacked files must be identical
upx_add_test(upx-compare-fa "${CMAKE_COMMAND}" -E compare_files upx-unpacked${exe} upx-unpacked-fa${exe})
upx_add_test(upx-compare-fn "${CMAKE_COMMAND}" -E compare_files upx-unpacked${exe} upx-unpacked-fn${exe})
upx_add_test(upx-compare-fr "${CMAKE_COMMAND}" -E compare_files upx-unpacked${exe} upx-unpacked-fr${exe})
upx_add_test(upx-compare-nrv2b "${CMAKE_COMMAND}" -E compare_files upx-unpacked${exe} upx-unpacked-nrv2b${exe})
upx_add_test(upx-compare-nrv2d "${CMAKE_COMMAND}" -E compare_files upx-unpacked${exe} upx-unpacked-nrv2d${exe})
upx_add_test(upx-compare-nrv2e "${CMAKE_COMMAND}" -E compare_files upx-unpacked${exe} upx-unpacked-nrv2e${exe})
upx_add_test(upx-compare-lzma "${CMAKE_COMMAND}" -E compare_files upx-unpacked${exe} upx-unpacked-lzma${exe})
# test dependencies
upx_test_depends(upx-list "upx-self-pack;upx-self-pack-fa;upx-self-pack-fn;upx-self-pack-fr;upx-self-pack-nrv2b;upx-self-pack-nrv2d;upx-self-pack-nrv2e;upx-self-pack-lzma")
upx_test_depends(upx-fileinfo "upx-self-pack;upx-self-pack-fa;upx-self-pack-fn;upx-self-pack-fr;upx-self-pack-nrv2b;upx-self-pack-nrv2d;upx-self-pack-nrv2e;upx-self-pack-lzma")
upx_test_depends(upx-test "upx-self-pack;upx-self-pack-fa;upx-self-pack-fn;upx-self-pack-fr;upx-self-pack-nrv2b;upx-self-pack-nrv2d;upx-self-pack-nrv2e;upx-self-pack-lzma")
upx_test_depends(upx-unpack upx-self-pack)
upx_test_depends(upx-unpack-fa upx-self-pack-fa)
upx_test_depends(upx-unpack-fn upx-self-pack-fn)
upx_test_depends(upx-unpack-fr upx-self-pack-fr)
upx_test_depends(upx-unpack-nrv2b upx-self-pack-nrv2b)
upx_test_depends(upx-unpack-nrv2d upx-self-pack-nrv2d)
upx_test_depends(upx-unpack-nrv2e upx-self-pack-nrv2e)
upx_test_depends(upx-unpack-lzma upx-self-pack-lzma)
upx_test_depends(upx-compare-fa "upx-unpack;upx-unpack-fa")
upx_test_depends(upx-compare-fn "upx-unpack;upx-unpack-fn")
upx_test_depends(upx-compare-fr "upx-unpack;upx-unpack-fr")
upx_test_depends(upx-compare-nrv2b "upx-unpack;upx-unpack-nrv2b")
upx_test_depends(upx-compare-nrv2d "upx-unpack;upx-unpack-nrv2d")
upx_test_depends(upx-compare-nrv2e "upx-unpack;upx-unpack-nrv2e")
upx_test_depends(upx-compare-lzma "upx-unpack;upx-unpack-lzma")
# tests with higher COST values will run first
set_tests_properties(upx-self-pack PROPERTIES COST 90)
set_tests_properties(upx-self-pack-fa PROPERTIES COST 20)
set_tests_properties(upx-self-pack-fn PROPERTIES COST 20)
set_tests_properties(upx-self-pack-fr PROPERTIES COST 20)
set_tests_properties(upx-self-pack-nrv2b PROPERTIES COST 20)
set_tests_properties(upx-self-pack-nrv2d PROPERTIES COST 20)
set_tests_properties(upx-self-pack-nrv2e PROPERTIES COST 20)
set_tests_properties(upx-self-pack-lzma PROPERTIES COST 30)
set_tests_properties(upx-unpack PROPERTIES COST 10)
if(NOT UPX_CONFIG_DISABLE_RUN_UNPACKED_TEST)
upx_add_test(upx-run-unpacked ${emu} ./upx-unpacked${exe} --version-short)
upx_test_depends(upx-run-unpacked upx-unpack)
endif()
if(NOT UPX_CONFIG_DISABLE_RUN_PACKED_TEST)
upx_add_test(upx-run-packed ${emu} ./upx-packed${exe} --version-short)
upx_add_test(upx-run-packed-fa ${emu} ./upx-packed-fa${exe} --version-short)
upx_add_test(upx-run-packed-fn ${emu} ./upx-packed-fn${exe} --version-short)
upx_add_test(upx-run-packed-fr ${emu} ./upx-packed-fr${exe} --version-short)
upx_add_test(upx-run-packed-nrv2b ${emu} ./upx-packed-nrv2b${exe} --version-short)
upx_add_test(upx-run-packed-nrv2d ${emu} ./upx-packed-nrv2d${exe} --version-short)
upx_add_test(upx-run-packed-nrv2e ${emu} ./upx-packed-nrv2e${exe} --version-short)
upx_add_test(upx-run-packed-lzma ${emu} ./upx-packed-lzma${exe} --version-short)
upx_test_depends(upx-run-packed upx-self-pack)
upx_test_depends(upx-run-packed-fa upx-self-pack-fa)
upx_test_depends(upx-run-packed-fn upx-self-pack-fn)
upx_test_depends(upx-run-packed-fr upx-self-pack-fr)
upx_test_depends(upx-run-packed-nrv2b upx-self-pack-nrv2b)
upx_test_depends(upx-run-packed-nrv2d upx-self-pack-nrv2d)
upx_test_depends(upx-run-packed-nrv2e upx-self-pack-nrv2e)
upx_test_depends(upx-run-packed-lzma upx-self-pack-lzma)
endif()
#
# exhaustive tests
#
if(NOT UPX_CONFIG_DISABLE_EXHAUSTIVE_TESTS)
foreach(method IN ITEMS nrv2b nrv2d nrv2e lzma)
foreach(level IN ITEMS 1 2 3 4 5 6 7)
set(s "${method}-${level}")
upx_add_test(upx-self-pack-${s} upx --${method} -${level} --all-filters --debug-use-random-filter "${upx_self_exe}" ${fo} -o upx-packed-${s}${exe})
upx_add_test(upx-list-${s} upx -l upx-packed-${s}${exe})
upx_add_test(upx-fileinfo-${s} upx --fileinfo upx-packed-${s}${exe})
upx_add_test(upx-test-${s} upx -t upx-packed-${s}${exe})
upx_add_test(upx-unpack-${s} upx -d upx-packed-${s}${exe} ${fo} -o upx-unpacked-${s}${exe})
upx_add_test(upx-compare-${s} "${CMAKE_COMMAND}" -E compare_files upx-unpacked${exe} upx-unpacked-${s}${exe})
upx_test_depends(upx-list-${s} upx-self-pack-${s})
upx_test_depends(upx-fileinfo-${s} upx-self-pack-${s})
upx_test_depends(upx-test-${s} upx-self-pack-${s})
upx_test_depends(upx-unpack-${s} upx-self-pack-${s})
upx_test_depends(upx-compare-${s} "upx-unpack;upx-unpack-${s}")
if(method MATCHES "lzma")
set_tests_properties(upx-self-pack-${s} PROPERTIES COST "3${level}")
else()
set_tests_properties(upx-self-pack-${s} PROPERTIES COST "2${level}")
endif()
if(NOT UPX_CONFIG_DISABLE_RUN_PACKED_TEST)
upx_add_test(upx-run-packed-${s} ${emu} ./upx-packed-${s}${exe} --version-short)
upx_test_depends(upx-run-packed-${s} upx-self-pack-${s})
endif()
endforeach()
endforeach()
endif () # UPX_CONFIG_DISABLE_EXHAUSTIVE_TESTS
# clean up
set(emu "")
set(exe "")
set(upx_self_exe "")
set(fo "")
# vim:set ft=cmake ts=4 sw=4 tw=0 et:
+10
View File
@@ -0,0 +1,10 @@
// Copyright (C) Markus Franz Xaver Johannes Oberhumer
#include <mutex>
static std::mutex lock_mutex;
int main() {
std::lock_guard<std::mutex> lock(lock_mutex);
return 0;
}
+22
View File
@@ -0,0 +1,22 @@
// Copyright (C) Markus Franz Xaver Johannes Oberhumer
#include <stddef.h>
#include <stdint.h>
// check ABI - require proper alignment of fundamental types for use in atomics
static_assert(alignof(char) == sizeof(char), "");
static_assert(alignof(signed char) == sizeof(signed char), "");
static_assert(alignof(unsigned char) == sizeof(unsigned char), "");
static_assert(alignof(short) == sizeof(short), "");
static_assert(alignof(unsigned short) == sizeof(unsigned short), "");
static_assert(alignof(int) == sizeof(int), "");
static_assert(alignof(unsigned int) == sizeof(unsigned int), "");
static_assert(alignof(long) == sizeof(long), "");
static_assert(alignof(unsigned long) == sizeof(unsigned long), "");
static_assert(alignof(ptrdiff_t) == sizeof(ptrdiff_t), "");
static_assert(alignof(size_t) == sizeof(size_t), "");
static_assert(alignof(intptr_t) == sizeof(intptr_t), "");
static_assert(alignof(uintptr_t) == sizeof(uintptr_t), "");
static_assert(alignof(void *) == sizeof(void *), "");
int main() { return 0; }
+122 -44
View File
@@ -3,10 +3,33 @@
# Copyright (C) Markus Franz Xaver Johannes Oberhumer # Copyright (C) Markus Franz Xaver Johannes Oberhumer
# #
ifeq ($(UPX_MAKEFILE_EXTRA_MK_INCLUDED),)
override UPX_MAKEFILE_EXTRA_MK_INCLUDED := 1
#***********************************************************************
# support functions
#***********************************************************************
override check_defined = $(foreach 1,$1,$(if $(filter undefined,$(origin $1)),$(error ERROR: variable '$1' is not defined),))
override check_undefined = $(foreach 1,$1,$(if $(filter undefined,$(origin $1)),,$(error ERROR: variable '$1' is already defined)))
# return "1" or empty-string
override eq = $(if $(subst x$1,,x$2)$(subst x$2,,x$1),,1)
override ne = $(if $(subst x$1,,x$2)$(subst x$2,,x$1),1,)
override tolower = $(subst A,a,$(subst B,b,$(subst C,c,$(subst D,d,$(subst E,e,$(subst F,f,$(subst G,g,$(subst H,h,$(subst I,i,$(subst J,j,$(subst K,k,$(subst L,l,$(subst M,m,$(subst N,n,$(subst O,o,$(subst P,p,$(subst Q,q,$(subst R,r,$(subst S,s,$(subst T,t,$(subst U,u,$(subst V,v,$(subst W,w,$(subst X,x,$(subst Y,y,$(subst Z,z,$1))))))))))))))))))))))))))
override toupper = $(subst a,A,$(subst b,B,$(subst c,C,$(subst d,D,$(subst e,E,$(subst f,F,$(subst g,G,$(subst h,H,$(subst i,I,$(subst j,J,$(subst k,K,$(subst l,L,$(subst m,M,$(subst n,N,$(subst o,O,$(subst p,P,$(subst q,Q,$(subst r,R,$(subst s,S,$(subst t,T,$(subst u,U,$(subst v,V,$(subst w,W,$(subst x,X,$(subst y,Y,$(subst z,Z,$1))))))))))))))))))))))))))
# canonicalize case of CMAKE_BUILD_TYPE to "Debug" and "Release"
override cm_build_type = $(if $(call eq,$1,),$(error EMPTY-build-type),$(if $(call eq,$(call tolower,$1),debug),Debug,$(if $(call eq,$(call tolower,$1),release),Release,$(if $(call eq,$(call tolower,$1),none),None,$1))))
#*********************************************************************** #***********************************************************************
# extra builds: some pre-defined build configurations # extra builds: some pre-defined build configurations
#*********************************************************************** #***********************************************************************
$(call check_defined,run_config run_build)
$(call check_undefined,run_config_and_build)
define run_config_and_build define run_config_and_build
$(call run_config,$1,$2) $(call run_config,$1,$2)
$(call run_build,$1,$2) $(call run_build,$1,$2)
@@ -42,6 +65,12 @@ 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 CC = clang -static
build/extra/clang-static/%: export CXX = clang++ -static build/extra/clang-static/%: export CXX = clang++ -static
# force building with clang/clang++ -static-pie
build/extra/clang-static-pie/debug: PHONY; $(call run_config_and_build,$@,Debug)
build/extra/clang-static-pie/release: PHONY; $(call run_config_and_build,$@,Release)
build/extra/clang-static-pie/%: export CC = clang -static-pie -fPIE -Wno-unused-command-line-argument
build/extra/clang-static-pie/%: export CXX = clang++ -static-pie -fPIE -Wno-unused-command-line-argument
# force building with clang/clang++ -static -flto # force building with clang/clang++ -static -flto
build/extra/clang-static-lto/debug: PHONY; $(call run_config_and_build,$@,Debug) build/extra/clang-static-lto/debug: PHONY; $(call run_config_and_build,$@,Debug)
build/extra/clang-static-lto/release: PHONY; $(call run_config_and_build,$@,Release) build/extra/clang-static-lto/release: PHONY; $(call run_config_and_build,$@,Release)
@@ -94,6 +123,12 @@ build/extra/gcc-static/release: PHONY; $(call run_config_and_build,$@,Release)
build/extra/gcc-static/%: export CC = gcc -static build/extra/gcc-static/%: export CC = gcc -static
build/extra/gcc-static/%: export CXX = g++ -static build/extra/gcc-static/%: export CXX = g++ -static
# force building with gcc/g++ -static-pie
build/extra/gcc-static-pie/debug: PHONY; $(call run_config_and_build,$@,Debug)
build/extra/gcc-static-pie/release: PHONY; $(call run_config_and_build,$@,Release)
build/extra/gcc-static-pie/%: export CC = gcc -static-pie -fPIE
build/extra/gcc-static-pie/%: export CXX = g++ -static-pie -fPIE
# force building with gcc/g++ -static -flto # force building with gcc/g++ -static -flto
build/extra/gcc-static-lto/debug: PHONY; $(call run_config_and_build,$@,Debug) build/extra/gcc-static-lto/debug: PHONY; $(call run_config_and_build,$@,Debug)
build/extra/gcc-static-lto/release: PHONY; $(call run_config_and_build,$@,Release) build/extra/gcc-static-lto/release: PHONY; $(call run_config_and_build,$@,Release)
@@ -112,7 +147,7 @@ build/extra/gcc-std-cxx20/%: export UPX_CONFIG_DISABLE_CXX_STANDARD=ON
build/extra/gcc-std-cxx23/debug: PHONY; $(call run_config_and_build,$@,Debug) build/extra/gcc-std-cxx23/debug: PHONY; $(call run_config_and_build,$@,Debug)
build/extra/gcc-std-cxx23/release: PHONY; $(call run_config_and_build,$@,Release) build/extra/gcc-std-cxx23/release: PHONY; $(call run_config_and_build,$@,Release)
build/extra/gcc-std-cxx23/%: export CC = gcc -std=gnu2x build/extra/gcc-std-cxx23/%: export CC = gcc -std=gnu2x
build/extra/gcc-std-cxx23/%: export CXX = g++ -std=gnu++23 build/extra/gcc-std-cxx23/%: export CXX = g++ -std=gnu++2b
build/extra/gcc-std-cxx23/%: export UPX_CONFIG_DISABLE_C_STANDARD=ON build/extra/gcc-std-cxx23/%: export UPX_CONFIG_DISABLE_C_STANDARD=ON
build/extra/gcc-std-cxx23/%: export UPX_CONFIG_DISABLE_CXX_STANDARD=ON build/extra/gcc-std-cxx23/%: export UPX_CONFIG_DISABLE_CXX_STANDARD=ON
@@ -121,36 +156,50 @@ build/extra/cross-linux-gnu-aarch64/debug: PHONY; $(call run_config_and_build,
build/extra/cross-linux-gnu-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-gnu-aarch64/%: export CC = aarch64-linux-gnu-gcc build/extra/cross-linux-gnu-aarch64/%: export CC = aarch64-linux-gnu-gcc
build/extra/cross-linux-gnu-aarch64/%: export CXX = aarch64-linux-gnu-g++ build/extra/cross-linux-gnu-aarch64/%: export CXX = aarch64-linux-gnu-g++
build/extra/cross-linux-gnu-aarch64/%: CMAKE_SYSTEM_NAME ?= Linux
build/extra/cross-linux-gnu-aarch64/%: CMAKE_CROSSCOMPILING_EMULATOR ?= qemu-aarch64
# cross compiler: Linux glibc arm-linux-gnueabihf # cross compiler: Linux glibc arm-linux-gnueabihf
build/extra/cross-linux-gnu-arm-eabihf/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-gnu-arm-eabihf/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-gnu-arm-eabihf/%: export CC = arm-linux-gnueabihf-gcc build/extra/cross-linux-gnu-arm-eabihf/%: export CC = arm-linux-gnueabihf-gcc
build/extra/cross-linux-gnu-arm-eabihf/%: export CXX = arm-linux-gnueabihf-g++ -Wno-psabi build/extra/cross-linux-gnu-arm-eabihf/%: export CXX = arm-linux-gnueabihf-g++ -Wno-psabi
build/extra/cross-linux-gnu-arm-eabihf/%: CMAKE_SYSTEM_NAME ?= Linux
build/extra/cross-linux-gnu-arm-eabihf/%: CMAKE_CROSSCOMPILING_EMULATOR ?= qemu-arm
# cross compiler: Windows x86 win32 MinGW (i386) # 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 -static build/extra/cross-windows-mingw32/%: export CC = i686-w64-mingw32-gcc -static -D_WIN32_WINNT=0x0501
build/extra/cross-windows-mingw32/%: export CXX = i686-w64-mingw32-g++ -static build/extra/cross-windows-mingw32/%: export CXX = i686-w64-mingw32-g++ -static -D_WIN32_WINNT=0x0501
build/extra/cross-windows-mingw32/%: CMAKE_SYSTEM_NAME ?= Windows
build/extra/cross-windows-mingw32/%: CMAKE_SYSTEM_PROCESSOR ?= X86
build/extra/cross-windows-mingw32/%: CMAKE_CROSSCOMPILING_EMULATOR ?= wine
# cross compiler: Windows x64 win64 MinGW (amd64) # 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 -static build/extra/cross-windows-mingw64/%: export CC = x86_64-w64-mingw32-gcc -static -D_WIN32_WINNT=0x0501
build/extra/cross-windows-mingw64/%: export CXX = x86_64-w64-mingw32-g++ -static build/extra/cross-windows-mingw64/%: export CXX = x86_64-w64-mingw32-g++ -static -D_WIN32_WINNT=0x0501
build/extra/cross-windows-mingw64/%: CMAKE_SYSTEM_NAME ?= Windows
build/extra/cross-windows-mingw64/%: CMAKE_SYSTEM_PROCESSOR ?= AMD64
build/extra/cross-windows-mingw64/%: CMAKE_CROSSCOMPILING_EMULATOR ?= wine
# cross compiler: macOS arm64 (aarch64) # 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
build/extra/cross-darwin-arm64/%: CMAKE_SYSTEM_NAME ?= Darwin
build/extra/cross-darwin-arm64/%: CMAKE_SYSTEM_PROCESSOR ?= arm64
# cross compiler: macOS x86_64 (amd64) # 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
build/extra/cross-darwin-x86_64/%: CMAKE_SYSTEM_NAME ?= Darwin
build/extra/cross-darwin-x86_64/%: CMAKE_SYSTEM_PROCESSOR ?= x86_64
#*********************************************************************** #***********************************************************************
# C/C++ static analyzers # C/C++ static analyzers
@@ -164,19 +213,20 @@ build/analyze/clang-analyzer/%: override CMAKE := $(SCAN_BUILD) $(CMAKE)
build/analyze/clang-analyzer/%: export CCC_CC ?= clang build/analyze/clang-analyzer/%: export CCC_CC ?= clang
build/analyze/clang-analyzer/%: export CCC_CXX ?= clang++ build/analyze/clang-analyzer/%: export CCC_CXX ?= clang++
# run clang-tidy: uses file compile_commands.json from an existing clang build # run clang-tidy: uses file compile_commands.json from an existing clang build;
# does not create any actual files, so purely PHONY # does not create any actual files, so purely PHONY
CLANG_TIDY_BUILD_BASE = build/extra/clang
RUN_CLANG_TIDY = time python3 ./misc/analyze/clang-tidy/run-clang-tidy.py -p $< RUN_CLANG_TIDY = time python3 ./misc/analyze/clang-tidy/run-clang-tidy.py -p $<
RUN_CLANG_TIDY_WERROR = $(RUN_CLANG_TIDY) '-warnings-as-errors=*' 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 build/analyze/clang-tidy-upx/debug build/analyze/clang-tidy-upx/release: $$(CLANG_TIDY_BUILD_BASE)/$$(notdir $$@) PHONY
$(RUN_CLANG_TIDY_WERROR) -config-file ./.clang-tidy '/src/.*\.cpp' $(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 build/analyze/clang-tidy-bzip2/debug build/analyze/clang-tidy-bzip2/release: $$(CLANG_TIDY_BUILD_BASE)/$$(notdir $$@) PHONY
$(RUN_CLANG_TIDY) -config-file ./misc/analyze/clang-tidy/clang-tidy-bzip2.yml /vendor/bzip2/ $(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 build/analyze/clang-tidy-ucl/debug build/analyze/clang-tidy-ucl/release: $$(CLANG_TIDY_BUILD_BASE)/$$(notdir $$@) PHONY
$(RUN_CLANG_TIDY_WERROR) -config-file ./misc/analyze/clang-tidy/clang-tidy-ucl.yml /vendor/ucl/ $(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 build/analyze/clang-tidy-zlib/debug build/analyze/clang-tidy-zlib/release: $$(CLANG_TIDY_BUILD_BASE)/$$(notdir $$@) PHONY
$(RUN_CLANG_TIDY_WERROR) -config-file ./misc/analyze/clang-tidy/clang-tidy-zlib.yml /vendor/zlib/ $(RUN_CLANG_TIDY) -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 build/analyze/clang-tidy-zstd/debug build/analyze/clang-tidy-zstd/release: $$(CLANG_TIDY_BUILD_BASE)/$$(notdir $$@) PHONY
$(RUN_CLANG_TIDY) -config-file ./misc/analyze/clang-tidy/clang-tidy-zstd.yml /vendor/zstd/ $(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-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-bzip2/$$(notdir $$@)
@@ -185,11 +235,11 @@ build/analyze/clang-tidy/debug build/analyze/clang-tidy/release: build/analyze/c
build/analyze/clang-tidy/debug build/analyze/clang-tidy/release: build/analyze/clang-tidy-zstd/$$(notdir $$@) build/analyze/clang-tidy/debug build/analyze/clang-tidy/release: build/analyze/clang-tidy-zstd/$$(notdir $$@)
# OLD names [deprecated] # OLD names [deprecated]
build/extra/scan-build/debug: build/analyze/clang-analyzer/debug build/extra/scan-build/debug: build/analyze/clang-analyzer/debug PHONY
build/extra/scan-build/release: build/analyze/clang-analyzer/release build/extra/scan-build/release: build/analyze/clang-analyzer/release PHONY
#*********************************************************************** #***********************************************************************
# advanced: generic extra target # advanced: generic eXtra target
#*********************************************************************** #***********************************************************************
# usage: # usage:
@@ -201,16 +251,19 @@ ifneq ($(CC),)
ifneq ($(CXX),) ifneq ($(CXX),)
UPX_XTARGET := $(UPX_XTARGET) UPX_XTARGET := $(UPX_XTARGET)
build/xtarget/$(UPX_XTARGET)/debug: PHONY; $(call run_config_and_build,$@,Debug) build/$(UPX_XTARGET)/debug: PHONY; $(call run_config_and_build,$@,Debug)
build/xtarget/$(UPX_XTARGET)/release: PHONY; $(call run_config_and_build,$@,Release) build/$(UPX_XTARGET)/release: PHONY; $(call run_config_and_build,$@,Release)
build/xtarget/$(UPX_XTARGET)/%: export CC build/$(UPX_XTARGET)/%: export CC := $(CC)
build/xtarget/$(UPX_XTARGET)/%: export CXX build/$(UPX_XTARGET)/%: export CXX := $(CXX)
# shortcuts # shortcuts
xtarget/all: xtarget/debug xtarget/release xtarget/all: xtarget/debug xtarget/release PHONY
xtarget/debug: build/xtarget/$(UPX_XTARGET)/debug xtarget/debug: build/$(UPX_XTARGET)/debug PHONY
xtarget/release: build/xtarget/$(UPX_XTARGET)/release xtarget/release: build/$(UPX_XTARGET)/release PHONY
xtarget/all+test: xtarget/debug+test xtarget/release+test PHONY
xtarget/debug+test: build/$(UPX_XTARGET)/debug+test PHONY
xtarget/release+test: build/$(UPX_XTARGET)/release+test PHONY
# set new default # set new default
.DEFAULT_GOAL = xtarget/release .DEFAULT_GOAL := build/$(UPX_XTARGET)/release
endif endif
endif endif
@@ -218,28 +271,51 @@ endif
#*********************************************************************** #***********************************************************************
# assemble cmake config flags; useful for CI jobs # assemble cmake config flags; useful for CI jobs
#*********************************************************************** #
ifneq ($(origin UPX_CMAKE_CONFIG_FLAGS),command line) # needed to work around a GNU make bug
# info: by default CMake only honors the CC and CXX environment variables; make # info: by default CMake only honors the CC and CXX environment variables; make
# it easy to set other variables like CMAKE_AR or CMAKE_RANLIB # it easy to set other variables like CMAKE_AR or CMAKE_RANLIB
__add_cmake_config = $(and $($1),-D$1="$($1)") #***********************************************************************
# pass common CMake settings from environment/make to cmake
build/%: UPX_CMAKE_CONFIG_FLAGS += $(call __add_cmake_config,CMAKE_AR)
build/%: UPX_CMAKE_CONFIG_FLAGS += $(call __add_cmake_config,CMAKE_NM)
build/%: UPX_CMAKE_CONFIG_FLAGS += $(call __add_cmake_config,CMAKE_RANLIB)
build/%: UPX_CMAKE_CONFIG_FLAGS += $(call __add_cmake_config,CMAKE_OBJCOPY)
build/%: UPX_CMAKE_CONFIG_FLAGS += $(call __add_cmake_config,CMAKE_OBJDUMP)
build/%: UPX_CMAKE_CONFIG_FLAGS += $(call __add_cmake_config,CMAKE_STRIP)
# pass UPX config options from environment/make to cmake; see CMakeLists.txt
build/%: UPX_CMAKE_CONFIG_FLAGS += $(call __add_cmake_config,UPX_CONFIG_DISABLE_GITREV)
build/%: UPX_CMAKE_CONFIG_FLAGS += $(call __add_cmake_config,UPX_CONFIG_DISABLE_SANITIZE)
build/%: UPX_CMAKE_CONFIG_FLAGS += $(call __add_cmake_config,UPX_CONFIG_DISABLE_WSTRICT)
build/%: UPX_CMAKE_CONFIG_FLAGS += $(call __add_cmake_config,UPX_CONFIG_DISABLE_WERROR)
build/%: UPX_CMAKE_CONFIG_FLAGS += $(call __add_cmake_config,UPX_CONFIG_DISABLE_SELF_PACK_TEST)
endif # bug work-around $(call check_undefined,__add_cmake_config)
# promote an environment or Make variable to a CMake cache entry:
__add_cmake_config = $(and $($1),-D$1="$($1)")
# pass common CMake settings
UPX_CMAKE_CONFIG_FLAGS += $(call __add_cmake_config,CMAKE_VERBOSE_MAKEFILE)
# pass common CMake toolchain settings
UPX_CMAKE_CONFIG_FLAGS += $(call __add_cmake_config,CMAKE_ADDR2LINE)
UPX_CMAKE_CONFIG_FLAGS += $(call __add_cmake_config,CMAKE_AR)
UPX_CMAKE_CONFIG_FLAGS += $(call __add_cmake_config,CMAKE_DLLTOOL)
UPX_CMAKE_CONFIG_FLAGS += $(call __add_cmake_config,CMAKE_LINKER)
UPX_CMAKE_CONFIG_FLAGS += $(call __add_cmake_config,CMAKE_NM)
UPX_CMAKE_CONFIG_FLAGS += $(call __add_cmake_config,CMAKE_OBJCOPY)
UPX_CMAKE_CONFIG_FLAGS += $(call __add_cmake_config,CMAKE_OBJDUMP)
UPX_CMAKE_CONFIG_FLAGS += $(call __add_cmake_config,CMAKE_RANLIB)
UPX_CMAKE_CONFIG_FLAGS += $(call __add_cmake_config,CMAKE_READELF)
UPX_CMAKE_CONFIG_FLAGS += $(call __add_cmake_config,CMAKE_STRIP)
UPX_CMAKE_CONFIG_FLAGS += $(call __add_cmake_config,CMAKE_TAPI)
# pass common CMake LTO toolchain settings
UPX_CMAKE_CONFIG_FLAGS += $(call __add_cmake_config,CMAKE_C_COMPILER_AR)
UPX_CMAKE_CONFIG_FLAGS += $(call __add_cmake_config,CMAKE_C_COMPILER_RANLIB)
UPX_CMAKE_CONFIG_FLAGS += $(call __add_cmake_config,CMAKE_CXX_COMPILER_AR)
UPX_CMAKE_CONFIG_FLAGS += $(call __add_cmake_config,CMAKE_CXX_COMPILER_RANLIB)
# pass common CMake cross compilation settings
UPX_CMAKE_CONFIG_FLAGS += $(call __add_cmake_config,CMAKE_SYSTEM_NAME)
UPX_CMAKE_CONFIG_FLAGS += $(call __add_cmake_config,CMAKE_SYSTEM_PROCESSOR)
UPX_CMAKE_CONFIG_FLAGS += $(call __add_cmake_config,CMAKE_CROSSCOMPILING_EMULATOR)
# pass UPX config options; see CMakeLists.txt
UPX_CMAKE_CONFIG_FLAGS += $(call __add_cmake_config,UPX_CONFIG_DISABLE_GITREV)
UPX_CMAKE_CONFIG_FLAGS += $(call __add_cmake_config,UPX_CONFIG_DISABLE_SANITIZE)
UPX_CMAKE_CONFIG_FLAGS += $(call __add_cmake_config,UPX_CONFIG_DISABLE_WERROR)
UPX_CMAKE_CONFIG_FLAGS += $(call __add_cmake_config,UPX_CONFIG_DISABLE_WSTRICT)
UPX_CMAKE_CONFIG_FLAGS += $(call __add_cmake_config,UPX_CONFIG_DISABLE_SELF_PACK_TEST)
UPX_CMAKE_CONFIG_FLAGS += $(call __add_cmake_config,UPX_CONFIG_DISABLE_EXHAUSTIVE_TESTS)
# pass UPX extra compile options; see CMakeLists.txt
UPX_CMAKE_CONFIG_FLAGS += $(call __add_cmake_config,UPX_CONFIG_EXTRA_COMPILE_OPTIONS_BZIP2)
UPX_CMAKE_CONFIG_FLAGS += $(call __add_cmake_config,UPX_CONFIG_EXTRA_COMPILE_OPTIONS_UCL)
UPX_CMAKE_CONFIG_FLAGS += $(call __add_cmake_config,UPX_CONFIG_EXTRA_COMPILE_OPTIONS_UPX)
UPX_CMAKE_CONFIG_FLAGS += $(call __add_cmake_config,UPX_CONFIG_EXTRA_COMPILE_OPTIONS_ZLIB)
UPX_CMAKE_CONFIG_FLAGS += $(call __add_cmake_config,UPX_CONFIG_EXTRA_COMPILE_OPTIONS_ZSTD)
#*********************************************************************** #***********************************************************************
# check git submodules # check git submodules
@@ -247,5 +323,7 @@ endif # bug work-around
SUBMODULES = doctest lzma-sdk ucl valgrind zlib SUBMODULES = doctest lzma-sdk ucl valgrind zlib
dummy := $(foreach m,$(SUBMODULES),$(if $(wildcard vendor/$m/[CL]*),$m,\ $(foreach 1,$(SUBMODULES),$(if $(wildcard vendor/$1/[CL]*),,\
$(error ERROR: missing git submodule '$m'; run 'git submodule update --init'))) $(error ERROR: missing git submodule '$1'; run 'git submodule update --init')))
endif # UPX_MAKEFILE_EXTRA_MK_INCLUDED
@@ -1,19 +0,0 @@
#! /usr/bin/env bash
## vim:set ts=4 sw=4 et:
set -e; set -o pipefail
argv0=$0; argv0abs="$(readlink -fn "$argv0")"; argv0dir="$(dirname "$argv0abs")"
# create the image from Dockerfile
# using a rootless Podman container
# NOTE: this image is based on rebuild-stubs/upx-stubtools-20221212-v6,
# so you have to create that image first
# WARNING: we install many packages, so the resulting image needs A LOT of disk space!
image=upx-cross-compile-ubuntu2204-20230721-v1
[[ $1 == --print-image ]] && echo "$image" && exit 0
podman build -t "$image" -f "$argv0dir/Dockerfile" "$argv0dir"
podman image list "$image"
echo
podman image tree "$image"
@@ -1,40 +0,0 @@
#! /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'
@@ -1,60 +0,0 @@
#! /usr/bin/env bash
## vim:set ts=4 sw=4 et:
set -e; set -o pipefail
argv0=$0; argv0abs="$(readlink -fn "$argv0")"; argv0dir="$(dirname "$argv0abs")"
# run an interactive shell in the image
# using a rootless Podman container
image="$("$argv0dir/10-create-image.sh" --print-image)"
flags=( --read-only --rm --pull=never )
flags+=( --cap-drop=all ) # drop all capabilities
flags+=( --network=none ) # no network needed
flags+=( -ti -e TERM="$TERM" ) # allocate an interactive pseudo-tty and pass $TERM
if [[ 1 == 1 ]]; then
# run as user upx 2000:2000
flags+=( --user 2000 )
# map container users 0..999 to subuid-users 1..1000, and map container user 2000 to current host user
flags+=( --uidmap=0:1:1000 --uidmap=2000:0:1 )
# map container groups 0..999 to subgid-groups 1..1000, and map container group 2000 to current host group
flags+=( --gidmap=0:1:1000 --gidmap=2000:0:1 )
# NOTE: we mount the upx top-level directory read-write under /home/upx/src/upx
# INFO: SELinux users *may* have to add ":z" to the volume mount flags; check the docs!
flags+=( -v "${argv0dir}/../../..:/home/upx/src/upx" )
flags+=( -w /home/upx/src/upx ) # set working directory
flags+=( --tmpfs /home/upx/.cache:rw,exec ) # mount a writeable tmpfs
flags+=( --tmpfs /home/upx/.local:rw,exec ) # mount a writeable tmpfs
else
# run as user root 0:0
# ONLY FOR DEBUGGING THE IMAGE
# map container user/group 0 to current host user/group
flags+=( --user 0 )
fi
if [[ $# == 0 ]]; then
podman run "${flags[@]}" "$image" bash -l
else
podman run "${flags[@]}" "$image" "$@"
fi
# now we can cross-compile UPX for Windows:
# cd /home/upx/src/upx
# rm -rf ./build/extra/cross-windows-mingw64/release
# make build/extra/cross-windows-mingw64/release
# and we can run the clang Static Analyzer (scan-build)
# cd /home/upx/src/upx
# rm -rf ./build/extra/scan-build/release
# make build/extra/scan-build/release
# and lots of other cross-compilers are installed; see "ls /usr/bin/*g++*"
# and finally see
# ./misc/podman/cross-compile-upx-ubuntu/build-all-inside-container.sh
# after running that script we can do cool things like:
# cd /home/upx/src/upx/build/cross-compile-upx-ubuntu2204/alpha-linux-gnu/debug
# qemu-alpha -L /usr/alpha-linux-gnu ./upx --version
# cd /home/upx/src/upx/build/cross-compile-upx-ubuntu2204/hppa-linux-gnu/debug
# qemu-hppa -L /usr/hppa-linux-gnu ./upx --version
# (similar for many other architectures/builds)
@@ -1,54 +0,0 @@
# NOTE: this image is based on rebuild-stubs/upx-stubtools-20221212-v6,
# so you have to create that image first
# WARNING: we install many packages, so the resulting image needs A LOT of disk space!
FROM localhost/upx-stubtools-20221212-v6
ENV UPX_CONTAINER_IMAGE_NAME=upx-cross-compile-ubuntu2204-20230721-v1
ARG DEBIAN_FRONTEND=noninteractive
USER root
# Ubuntu 22.04
RUN apt-get update && apt-get upgrade -y \
&& apt-get install -y \
# Linux glibc cross compilers
g++-aarch64-linux-gnu \
g++-alpha-linux-gnu \
g++-arm-linux-gnueabi \
g++-arm-linux-gnueabihf \
g++-hppa-linux-gnu \
g++-i686-linux-gnu \
g++-m68k-linux-gnu \
g++-mips-linux-gnu \
g++-mipsel-linux-gnu \
g++-mips64-linux-gnuabi64 \
g++-mips64el-linux-gnuabi64 \
g++-powerpc-linux-gnu \
g++-powerpc64-linux-gnu \
g++-powerpc64le-linux-gnu \
g++-riscv64-linux-gnu \
g++-s390x-linux-gnu \
g++-sh4-linux-gnu \
g++-sparc64-linux-gnu \
# Linux glibc cross compilers - ILP32 on 64-bit CPUs
g++-x86-64-linux-gnux32 \
# Windows cross compilers
g++-mingw-w64-i686 \
g++-mingw-w64-x86-64 \
&& true
RUN apt-get install -y \
# clang-14 and tools
clang-14 clang-format-14 clang-tidy-14 clang-tools-14 lldb-14 llvm-14 \
# QEMU and Wine
qemu-system qemu-user wine wine32:i386 wine64 \
# misc
gdb lsb-release valgrind \
&& true
RUN cd /usr/bin \
# create unversioned clang symlinks in /usr/local/bin
&& for f in clang*-14 llvm-*-14 scan-*-14; do ln -s -v ../../bin/$f /usr/local/bin/${f%-14}; done \
&& ln -s -v ../../bin/obj2yaml-14 /usr/local/bin/llvm-obj2yaml \
&& ln -s -v ../../bin/yaml2obj-14 /usr/local/bin/llvm-yaml2obj \
&& true
# switch back to default user upx:upx 2000:2000
USER upx
@@ -1,99 +0,0 @@
#! /usr/bin/env bash
## vim:set ts=4 sw=4 et:
set -e; set -o pipefail
argv0=$0; argv0abs="$(readlink -fn "$argv0")"; argv0dir="$(dirname "$argv0abs")"
# build UPX for 21 targets; must be run inside the container!
# using a rootless Podman container
# simple sanity check that we are indeed running inside the container
if [[ $UPX_CONTAINER_IMAGE_NAME != upx-cross-compile-* ]]; then
echo "$argv0: NOTE: please run this script *inside* the container"
exit 1
fi
# go to upx top-level directory
cd "$argv0dir/../../.." || exit 1
pwd
test -f doc/upx.pod || exit 1 # sanity check
test -f src/version.h || exit 1 # sanity check
function run_config_and_build {
# requires: AR CC CXX RANLIB
local toolchain=$1
local cmake_config_flags build_type bdir
# cmake flags
cmake_config_flags=
case $toolchain in
# these old architectures do not support sanitize
alpha-linux-gnu) cmake_config_flags=-DUPX_CONFIG_DISABLE_SANITIZE=ON ;;
hppa-linux-gnu) cmake_config_flags=-DUPX_CONFIG_DISABLE_SANITIZE=ON ;;
# avoid sanitize link errors with current MinGW-w64 versions; link libstdc++ statically
i686-w64-mingw32)
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
arm-linux-*) CXX="$CXX -Wno-psabi" ;;
esac
if [[ 1 == 1 ]]; then
# prefer building with Ninja (ninja-build)
cmake_config_flags="$cmake_config_flags -G Ninja -DUPX_CONFIG_CMAKE_DISABLE_INSTALL=ON"
fi
# for all build types
for build_type in Debug Release; do
bdir="build/cross-compile-upx-ubuntu2204/$toolchain/${build_type,,}"
mkdir -p "$bdir"
# run_config
if [[ ! -f $bdir/CMakeCache.txt ]]; then
export CMAKE_REQUIRED_QUIET=OFF
cmake -S . -B "$bdir" -DCMAKE_BUILD_TYPE=$build_type -DCMAKE_AR="$AR" -DCMAKE_RANLIB="$RANLIB" $cmake_config_flags
fi
# run_build
cmake --build "$bdir" --config $build_type --parallel
done
}
# see Dockerfile for packages
for package in \
g++-aarch64-linux-gnu \
g++-alpha-linux-gnu \
g++-arm-linux-gnueabi \
g++-arm-linux-gnueabihf \
g++-hppa-linux-gnu \
g++-i686-linux-gnu \
g++-m68k-linux-gnu \
g++-mips-linux-gnu \
g++-mipsel-linux-gnu \
g++-mips64-linux-gnuabi64 \
g++-mips64el-linux-gnuabi64 \
g++-powerpc-linux-gnu \
g++-powerpc64-linux-gnu \
g++-powerpc64le-linux-gnu \
g++-riscv64-linux-gnu \
g++-s390x-linux-gnu \
g++-sh4-linux-gnu \
g++-sparc64-linux-gnu \
g++-x86-64-linux-gnux32 \
g++-mingw-w64-i686 \
g++-mingw-w64-x86-64
do
# setup toolchain and environment variables
toolchain=$package
toolchain=${toolchain/-x86-64/-x86_64}
toolchain=${toolchain/g++-/}
case $toolchain in
mingw-w64-i686) toolchain=i686-w64-mingw32 ;;
mingw-w64-x86_64) toolchain=x86_64-w64-mingw32 ;;
esac
echo "========== $toolchain"
export AR=/usr/bin/${toolchain}-ar
export CC=/usr/bin/${toolchain}-gcc
export CXX=/usr/bin/${toolchain}-g++
export RANLIB=/usr/bin/${toolchain}-ranlib
ls -l "$AR" "$CC" "$CXX" "$RANLIB"
run_config_and_build $toolchain
unset AR CC CXX RANLIB
done
File diff suppressed because it is too large Load Diff
+2 -1
View File
@@ -5,8 +5,9 @@ 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
# Copyright (C) Markus Franz Xaver Johannes Oberhumer
image=upx-stubtools-20221212-v6 image=upx-stubtools-20240405-v1
[[ $1 == --print-image ]] && echo "$image" && exit 0 [[ $1 == --print-image ]] && echo "$image" && exit 0
podman build -t "$image" -f "$argv0dir/Dockerfile" "$argv0dir" podman build -t "$image" -f "$argv0dir/Dockerfile" "$argv0dir"
@@ -5,6 +5,7 @@ argv0=$0; argv0abs="$(readlink -fn "$argv0")"; argv0dir="$(dirname "$argv0abs")"
# list all system packages that are installed in the image # list all system packages that are installed in the image
# using a rootless Podman container # using a rootless Podman container
# Copyright (C) Markus Franz Xaver Johannes Oberhumer
image="$("$argv0dir/10-create-image.sh" --print-image)" image="$("$argv0dir/10-create-image.sh" --print-image)"
@@ -5,6 +5,7 @@ argv0=$0; argv0abs="$(readlink -fn "$argv0")"; argv0dir="$(dirname "$argv0abs")"
# run an interactive shell in the image # run an interactive shell in the image
# using a rootless Podman container # using a rootless Podman container
# Copyright (C) Markus Franz Xaver Johannes Oberhumer
image="$("$argv0dir/10-create-image.sh" --print-image)" image="$("$argv0dir/10-create-image.sh" --print-image)"
@@ -24,6 +25,7 @@ if [[ 1 == 1 ]]; then
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/.cache:rw,exec ) # mount a writeable tmpfs
flags+=( --tmpfs /home/upx/.config:rw,exec ) # mount a writeable tmpfs
flags+=( --tmpfs /home/upx/.local: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
+42
View File
@@ -0,0 +1,42 @@
#! /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")"
# rebuild stubs from source code
# (also see 20-image-run-shell.sh for more container usage examples)
# using a rootless Podman container
# Copyright (C) Markus Franz Xaver Johannes Oberhumer
image="$("$argv0dir/10-create-image.sh" --print-image)"
flags=( --read-only --rm --pull=never )
flags+=( --cap-drop=all ) # drop all capabilities
flags+=( --network=none ) # no network needed
if [[ 1 == 1 ]]; then
# run as user upx 2000:2000
flags+=( --user 2000 )
# map container users 0..999 to subuid-users 1..1000, and map container user 2000 to current host user
flags+=( --uidmap=0:1:1000 --uidmap=2000:0:1 )
# map container groups 0..999 to subgid-groups 1..1000, and map container group 2000 to current host group
flags+=( --gidmap=0:1:1000 --gidmap=2000:0:1 )
# NOTE: we mount the upx top-level directory read-write under /home/upx/src/upx
# INFO: SELinux users *may* have to add ":z" to the volume mount flags; check the docs!
flags+=( -v "${argv0dir}/../../..:/home/upx/src/upx" )
fi
podman run "${flags[@]}" "$image" bash -c $'
set -ex; set -o pipefail
cd /home/upx/src/upx
# check whitespace
[[ -d .git ]] && bash ./misc/scripts/check_whitespace_git.sh
# rebuild docs
make -C doc clean all
# rebuild stubs
cd /home/upx/src/upx/src/stub
make maintainer-clean extra-clean
git status . || true # make sure the stub files got deleted
make extra-all all
echo "===== Rebuilt stubs. All done. ====="
exit 0
'
+48 -15
View File
@@ -1,5 +1,6 @@
FROM docker.io/library/ubuntu:22.04 # Copyright (C) Markus Franz Xaver Johannes Oberhumer
ENV UPX_CONTAINER_IMAGE_NAME=upx-stubtools-20221212-v6 FROM docker.io/library/ubuntu:24.04
ENV UPX_CONTAINER_IMAGE_NAME=upx-stubtools-20240405-v1
ARG DEBIAN_FRONTEND=noninteractive ARG DEBIAN_FRONTEND=noninteractive
ENV LANG=C.UTF-8 ENV LANG=C.UTF-8
@@ -7,21 +8,35 @@ ENV LANG=C.UTF-8
RUN dpkg --add-architecture i386 \ RUN dpkg --add-architecture i386 \
&& apt-get update && apt-get upgrade -y \ && apt-get update && apt-get upgrade -y \
&& apt-get install -y --no-install-recommends \ && apt-get install -y --no-install-recommends \
aria2 bash bash-completion ca-certificates dash git less libmpc3 libncurses5 \ aria2 bash bash-completion ca-certificates curl git less libmpc3 \
make ncurses-term perl-base python2-minimal time wget xz-utils \ make ncurses-term perl-base tar time wget xz-utils \
libc6:i386 zlib1g:i386 \ libc6:i386 zlib1g:i386 \
# the following packages are not required for rebuilding the stubs, but # the following packages are not required for rebuilding the stubs, but
# they do make the image *much* more convenient and also allow building # they do make the image *much* more convenient and also allow building
# the full UPX binary inside the container via CMake: # the full UPX binary inside the container via CMake:
7zip bfs busybox bzip2 cabextract ccache chrpath cmake cpio curl elfutils fd-find file fzf \ 7zip bfs bubblewrap busybox bzip2 bzip3 cabextract ccache chrpath cmake cpio dash diffstat \
g++ gawk gdb gojq ht htop hyperfine jq libzstd-dev lsb-release lz4 lzip lzop \ elfutils execstack fd-find file fish fzf g++ gawk gdb gojq ht htop hyperfine jq ksh \
mksh moreutils ninja-build p7zip parallel patch patchelf pax-utils paxctl \ libzstd-dev lsb-release lz4 lzip lzop minify mksh moreutils musl neovim ninja-build \
python3 python3-pyasn1 python3-pycryptodome python3-zstd \ p7zip parallel patch patchelf patchutils pax-utils proot \
re2c ripgrep rsync screen universal-ctags unzip vim yash zip zlib1g-dev zsh zstd \ python3 python3-pyasn1 python3-pycryptodome python3-pycurl python3-toml python3-yaml python3-zstd \
# extra packages for compiling with "gcc -m32" and and "gcc -mx32": re2c ripgrep rsync screen strace universal-ctags unzip valgrind yash yq \
zip zlib1g-dev zoxide zsh zstd \
# extra packages for compiling with "gcc -m32" and "gcc -mx32":
g++-multilib gcc-multilib \ g++-multilib gcc-multilib \
&& true && true
# install python2-minimal packages from Debian-11; REQUIRED
RUN cd /root \
&& aria2c --checksum=sha-256=85833c92314011b89bbead6f9a5a7a360b5ee4f9b95e001225afead4ebf9f7d3 \
'https://ftp.debian.org/debian/pool/main/p/python2.7/libpython2.7-minimal_2.7.18-8+deb11u1_amd64.deb' \
&& aria2c --checksum=sha-256=44f0cdc1a343303d31c55fcb3a6402cfe326adf749ec30e375e6e0c0c5f7c1f7 \
'https://ftp.debian.org/debian/pool/main/p/python2.7/python2.7-minimal_2.7.18-8+deb11u1_amd64.deb' \
&& dpkg -i ./*.deb \
&& rm ./*.deb \
&& if ! test -f /usr/bin/python2; then ln -s -v python2.7 /usr/bin/python2; fi \
&& ldconfig \
&& true
# manually unpack and install compat libs from Ubuntu-16.04; REQUIRED # manually unpack and install compat libs from Ubuntu-16.04; REQUIRED
RUN cd /root \ RUN cd /root \
&& aria2c --checksum=sha-256=de22baf3dd851a10e16fbf66a243e70149ca46e06b2939fdc79429196cefc090 \ && aria2c --checksum=sha-256=de22baf3dd851a10e16fbf66a243e70149ca46e06b2939fdc79429196cefc090 \
@@ -45,21 +60,39 @@ RUN cd /root \
# install official UPX release binaries into /usr/local/bin; not required but convenient for testing # install official UPX release binaries into /usr/local/bin; not required but convenient for testing
RUN cd /root \ RUN cd /root \
&& wget -q https://github.com/upx/upx/releases/download/v3.91/upx-3.91-amd64_linux.tar.bz2 \ && wget -q https://github.com/upx/upx/releases/download/v3.91/upx-3.91-amd64_linux.tar.bz2 \
&& 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 4.2.0; do wget -q https://github.com/upx/upx/releases/download/v${v}/upx-${v}-amd64_linux.tar.xz; done \ && xzversions="3.92 3.93 3.94 3.95 3.96 4.0.0 4.0.1 4.0.2 4.1.0 4.2.0 4.2.1 4.2.2 4.2.3" \
&& for v in $xzversions; 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 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 4.2.0; do d=upx-${v}-amd64_linux; ./$d/upx -qq -d $d/upx -o /usr/local/bin/upx-${v}; done \ && for v in 3.91 $xzversions; 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 \ && rm -r ./upx-*.tar.* ./upx-*linux \
&& true && true
# create default user upx:upx 2000:2000 # create default container user upx:upx 2000:2000
RUN useradd upx -U --uid 2000 --shell /bin/bash -m \ RUN useradd upx -U --uid 2000 --shell /bin/bash -m \
&& cd /home/upx && chmod 00700 . \ && cd /home/upx && chmod 00700 . \
# prepare ~/.cache and ~/.local for possible tmpfs mounts # prepare ~/.cache, ~/.config and ~/.local for possible tmpfs mounts
&& mkdir -p .cache/tmp .local/bin src/upx \ && 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 ccache fontconfig go-build mesa_shader_cache parallel tmp wine zig; do mkdir -p .cache/$d; done \
&& for d in fish git helix kak nvim; do mkdir -p .config/$d; done \
&& for d in bin include lib share state; do mkdir -p .local/$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 .cache/wine .wine && ln -s .cache/tmp tmp \
# symlink upx-stubtools
&& ln -s /usr/local/bin/bin-upx-20221212 .local/bin/bin-upx \ && ln -s /usr/local/bin/bin-upx-20221212 .local/bin/bin-upx \
# some convenience settings according to upx developer preferences
&& echo "alias md=mkdir" >> .bashrc \
&& echo "alias rd=rmdir" >> .bashrc \
&& echo 'mdd() { mkdir "$1" && cd "$1"; }' >> .bashrc \
&& echo 'm() { make "$@"; }' >> .bashrc \
&& echo 'tn() { time nice "$@"; }' >> .bashrc \
&& echo 'tnm() { time nice make "$@"; }' >> .bashrc \
&& echo 'tnmm() { time nice make -j "$@"; }' >> .bashrc \
&& echo 'source /usr/share/bash-completion/completions/make' >> .bashrc \
&& echo 'complete -F _make m tnm tnmm' >> .bashrc \
&& echo 'eval "$(zoxide init bash)"' >> .bashrc \
&& echo "alias zz=zi\nalias y=z\nalias yy=zi" >> .bashrc \
&& echo "alias cd..='cd ..'" >> .bashrc \
&& echo "alias ..='cd ..'" >> .bashrc \
&& echo "alias .='cd ..'" >> .bashrc \
&& chown -R upx:upx . \ && chown -R upx:upx . \
&& true && true
USER upx USER upx
+692 -630
View File
File diff suppressed because it is too large Load Diff
-134
View File
@@ -1,134 +0,0 @@
#! /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, VERBOSE, 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"
# not mandatory but good practice when using <windows.h>:
mandatory_flags="$mandatory_flags -DWIN32_LEAN_AND_MEAN"
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
if test "x$VERBOSE" != "x" && test "x$VERBOSE" != "x0"; then
# print full command
echo " $@"
fi
"$@"
}
# 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."
+17
View File
@@ -0,0 +1,17 @@
#! /usr/bin/env python3
## vim:set ts=4 sw=4 et: -*- coding: utf-8 -*-
# simulate "readlink -en FILE"
# - result may differ from actual readlink(1) for edge cases
# - works with Python2 and Python3
#
# Copyright (C) Markus Franz Xaver Johannes Oberhumer
import os, sys
if len(sys.argv) != 2:
sys.exit(1)
real_path = os.path.realpath(sys.argv[1])
if not os.path.exists(real_path):
sys.exit(1)
sys.stdout.write(real_path)
sys.stdout.flush()
+15
View File
@@ -0,0 +1,15 @@
#! /usr/bin/env python3
## vim:set ts=4 sw=4 et: -*- coding: utf-8 -*-
# simulate "readlink -fn FILE" for systems that lack it (e.g. macOS-11)
# - result may differ from actual readlink(1) for edge cases
# - works with Python2 and Python3
#
# Copyright (C) Markus Franz Xaver Johannes Oberhumer
import os, sys
if len(sys.argv) != 2:
sys.exit(1)
real_path = os.path.realpath(sys.argv[1])
sys.stdout.write(real_path)
sys.stdout.flush()
+42
View File
@@ -0,0 +1,42 @@
#! /usr/bin/env bash
## vim:set ts=4 sw=4 et:
set -e; set -o pipefail
# Copyright (C) Markus Franz Xaver Johannes Oberhumer
# assemble cmake config flags; useful for CI jobs
# also see misc/make/Makefile-extra.mk
cmake_config_flags=()
# promote an environment variable to a CMake cache entry:
__add_cmake_config() {
[[ -z "${!1}" ]] || cmake_config_flags+=( -D$1="${!1}" )
}
# pass common CMake settings
for v in CMAKE_VERBOSE_MAKEFILE; do
__add_cmake_config $v
done
# pass common CMake toolchain settings
for v in CMAKE_ADDR2LINE CMAKE_AR CMAKE_DLLTOOL CMAKE_LINKER CMAKE_NM CMAKE_OBJCOPY CMAKE_OBJDUMP CMAKE_RANLIB CMAKE_READELF CMAKE_STRIP CMAKE_TAPI; do
__add_cmake_config $v
done
# pass common CMake LTO toolchain settings
for v in CMAKE_C_COMPILER_AR CMAKE_C_COMPILER_RANLIB CMAKE_CXX_COMPILER_AR CMAKE_CXX_COMPILER_RANLIB; do
__add_cmake_config $v
done
# pass common CMake cross compilation settings
for v in CMAKE_SYSTEM_NAME CMAKE_SYSTEM_PROCESSOR CMAKE_CROSSCOMPILING_EMULATOR; do
__add_cmake_config $v
done
# pass UPX config options; see CMakeLists.txt
for v in UPX_CONFIG_DISABLE_GITREV UPX_CONFIG_DISABLE_SANITIZE UPX_CONFIG_DISABLE_WERROR UPX_CONFIG_DISABLE_WSTRICT UPX_CONFIG_DISABLE_SELF_PACK_TEST UPX_CONFIG_DISABLE_EXHAUSTIVE_TESTS; do
__add_cmake_config $v
done
# pass UPX extra compile options; see CMakeLists.txt
for v in UPX_CONFIG_EXTRA_COMPILE_OPTIONS_BZIP2 UPX_CONFIG_EXTRA_COMPILE_OPTIONS_UCL UPX_CONFIG_EXTRA_COMPILE_OPTIONS_UPX UPX_CONFIG_EXTRA_COMPILE_OPTIONS_ZLIB UPX_CONFIG_EXTRA_COMPILE_OPTIONS_ZSTD; do
__add_cmake_config $v
done
exec "${CMAKE:-cmake}" $UPX_CMAKE_CONFIG_FLAGS "${cmake_config_flags[@]}" "$@"
exit 99
+8 -6
View File
@@ -2,21 +2,23 @@
## vim:set ts=4 sw=4 et: ## vim:set ts=4 sw=4 et:
set -e; set -o pipefail set -e; set -o pipefail
# Copyright (C) Markus Franz Xaver Johannes Oberhumer
#
# "Gofmt's style is nobody's favourite, but gofmt is everybody's favourite." --Rob Pike # "Gofmt's style is nobody's favourite, but gofmt is everybody's favourite." --Rob Pike
#
# NOTE: we are using clang-format-15.0.6 from upx-stubtools # NOTE: we are using clang-format-15.0.6 from upx-stubtools
# see https://github.com/upx/upx-stubtools/releases # see https://github.com/upx/upx-stubtools/releases
#
# NOTE: we use .clang-format config from upx.git/.clang-format # NOTE: we use .clang-format config from upx.git/.clang-format
if [[ ! -f $UPX_CLANG_FORMAT ]]; then if [[ ! -f $UPX_CLANG_FORMAT ]]; then
UPX_CLANG_FORMAT="$HOME/local/bin/bin-upx/clang-format-15.0.6" UPX_CLANG_FORMAT="$HOME/local/bin/bin-upx/clang-format-15.0.6"
fi fi
if [[ ! -f $UPX_CLANG_FORMAT ]]; then if [[ ! -f $UPX_CLANG_FORMAT ]]; then
UPX_CLANG_FORMAT="$HOME/.local/bin/bin-upx/clang-format-15.0.6" UPX_CLANG_FORMAT="$HOME/.local/bin/bin-upx/clang-format-15.0.6"
fi fi
if [[ ! -f $UPX_CLANG_FORMAT ]]; then if [[ ! -f $UPX_CLANG_FORMAT ]]; then
UPX_CLANG_FORMAT="$HOME/bin/bin-upx/clang-format-15.0.6" UPX_CLANG_FORMAT="$HOME/bin/bin-upx/clang-format-15.0.6"
fi fi
if [[ ! -f $UPX_CLANG_FORMAT ]]; then if [[ ! -f $UPX_CLANG_FORMAT ]]; then
echo "ERROR: $0: cannot find clang-format-15.0.6" echo "ERROR: $0: cannot find clang-format-15.0.6"
@@ -29,4 +31,4 @@ ulimit -v 1048576 || true
#echo $UPX_CLANG_FORMAT #echo $UPX_CLANG_FORMAT
exec "$UPX_CLANG_FORMAT" -style=file "$@" exec "$UPX_CLANG_FORMAT" -style=file "$@"
exit 1 exit 99
+166
View File
@@ -0,0 +1,166 @@
#! /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")
#
# Copyright (C) Markus Franz Xaver Johannes Oberhumer
#
# mimic running "ctest", i.e. the "test" section of CMakeLists.txt; does not redirect stdout
# (allows freely setting $upx_exe_runner, while CMake is restricted to configure-time settings)
#
# requires:
# $upx_exe (required, but with convenience fallback "./upx")
# optional settings:
# $upx_exe_runner (e.g. "qemu-x86_64 -cpu Nehalem" or "valgrind")
#
#***********************************************************************
# init & checks
#***********************************************************************
# upx_exe
[[ -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
# set emu and run_upx
emu=()
if [[ -n $upx_exe_runner ]]; then
# usage examples:
# export upx_exe_runner="qemu-x86_64 -cpu Nehalem"
# export upx_exe_runner="valgrind --leak-check=no --error-exitcode=1 --quiet"
# export upx_exe_runner="wine"
IFS=' ' read -r -a emu <<< "$upx_exe_runner" # split at spaces into array
elif [[ -n $CMAKE_CROSSCOMPILING_EMULATOR ]]; then
IFS=';' read -r -a emu <<< "$CMAKE_CROSSCOMPILING_EMULATOR" # split at semicolons into array
fi
run_upx=( "${emu[@]}" "$upx_exe" )
echo "run_upx='${run_upx[*]}'"
# run_upx sanity check
if ! "${run_upx[@]}" --version-short >/dev/null; then echo "UPX-ERROR: FATAL: upx --version-short FAILED"; exit 1; fi
if ! "${run_upx[@]}" -L >/dev/null 2>&1; then echo "UPX-ERROR: FATAL: upx -L FAILED"; exit 1; fi
if ! "${run_upx[@]}" --help >/dev/null; then echo "UPX-ERROR: FATAL: upx --help FAILED"; exit 1; fi
#***********************************************************************
# see CMakeLists.txt
#
# IDEA: create a Makefile and use "make -j" so that these tests can
# run in parallel much like "ctest --parallel 8"
#***********************************************************************
# similar to cmake function upx_cache_bool_vars()
set_cmake_bool_vars() {
local default_value="$1"; shift
local var_name
for var_name do
case "${!var_name}" in
0 | FALSE | OFF | false | off) eval "export $var_name=OFF" ;;
1 | TRUE | ON | true | on) eval "export $var_name=ON" ;;
*) eval "export $var_name=$default_value" ;;
esac
done
}
set -x
set_cmake_bool_vars OFF UPX_CONFIG_DISABLE_SELF_PACK_TEST
set_cmake_bool_vars OFF UPX_CONFIG_DISABLE_RUN_UNPACKED_TEST
set_cmake_bool_vars OFF UPX_CONFIG_DISABLE_RUN_PACKED_TEST
if [[ "${emu[0]}" == *valgrind* ]]; then # valgrind is SLOW
set_cmake_bool_vars ON UPX_CONFIG_DISABLE_EXHAUSTIVE_TESTS
else
set_cmake_bool_vars OFF UPX_CONFIG_DISABLE_EXHAUSTIVE_TESTS
fi
export UPX="--prefer-ucl --no-color --no-progress"
export UPX_DEBUG_DISABLE_GITREV_WARNING=1
export UPX_DEBUG_DOCTEST_DISABLE=1 # already checked above
"${run_upx[@]}" --version
"${run_upx[@]}" --version-short
"${run_upx[@]}" --license
"${run_upx[@]}" --help
"${run_upx[@]}" --help-short
"${run_upx[@]}" --help-verbose
"${run_upx[@]}" --sysinfo
"${run_upx[@]}" --sysinfo -v
"${run_upx[@]}" --sysinfo -vv
if [[ $UPX_CONFIG_DISABLE_SELF_PACK_TEST == ON ]]; then
echo "Self-pack test disabled. All done."; exit 0
fi
exe=".out"
upx_self_exe=$upx_exe
fo="--force-overwrite"
"${run_upx[@]}" -3 "${upx_self_exe}" ${fo} -o upx-packed${exe}
"${run_upx[@]}" -3 --all-filters "${upx_self_exe}" ${fo} -o upx-packed-fa${exe}
"${run_upx[@]}" -3 --no-filter "${upx_self_exe}" ${fo} -o upx-packed-fn${exe}
"${run_upx[@]}" -3 --all-filters --debug-use-random-filter "${upx_self_exe}" ${fo} -o upx-packed-fr${exe}
"${run_upx[@]}" -3 --nrv2b "${upx_self_exe}" ${fo} -o upx-packed-nrv2b${exe}
"${run_upx[@]}" -3 --nrv2d "${upx_self_exe}" ${fo} -o upx-packed-nrv2d${exe}
"${run_upx[@]}" -3 --nrv2e "${upx_self_exe}" ${fo} -o upx-packed-nrv2e${exe}
"${run_upx[@]}" -1 --lzma "${upx_self_exe}" ${fo} -o upx-packed-lzma${exe}
"${run_upx[@]}" -l upx-packed${exe} upx-packed-fa${exe} upx-packed-fn${exe} upx-packed-fr${exe} upx-packed-nrv2b${exe} upx-packed-nrv2d${exe} upx-packed-nrv2e${exe} upx-packed-lzma${exe}
"${run_upx[@]}" --fileinfo upx-packed${exe} upx-packed-fa${exe} upx-packed-fn${exe} upx-packed-fr${exe} upx-packed-nrv2b${exe} upx-packed-nrv2d${exe} upx-packed-nrv2e${exe} upx-packed-lzma${exe}
"${run_upx[@]}" -t upx-packed${exe} upx-packed-fa${exe} upx-packed-fn${exe} upx-packed-fr${exe} upx-packed-nrv2b${exe} upx-packed-nrv2d${exe} upx-packed-nrv2e${exe} upx-packed-lzma${exe}
"${run_upx[@]}" -d upx-packed${exe} ${fo} -o upx-unpacked${exe}
"${run_upx[@]}" -d upx-packed-fa${exe} ${fo} -o upx-unpacked-fa${exe}
"${run_upx[@]}" -d upx-packed-fn${exe} ${fo} -o upx-unpacked-fn${exe}
"${run_upx[@]}" -d upx-packed-fr${exe} ${fo} -o upx-unpacked-fr${exe}
"${run_upx[@]}" -d upx-packed-nrv2b${exe} ${fo} -o upx-unpacked-nrv2b${exe}
"${run_upx[@]}" -d upx-packed-nrv2d${exe} ${fo} -o upx-unpacked-nrv2d${exe}
"${run_upx[@]}" -d upx-packed-nrv2e${exe} ${fo} -o upx-unpacked-nrv2e${exe}
"${run_upx[@]}" -d upx-packed-lzma${exe} ${fo} -o upx-unpacked-lzma${exe}
# all unpacked files must be identical
cmp -s upx-unpacked${exe} upx-unpacked-fa${exe}
cmp -s upx-unpacked${exe} upx-unpacked-fn${exe}
cmp -s upx-unpacked${exe} upx-unpacked-fr${exe}
cmp -s upx-unpacked${exe} upx-unpacked-nrv2b${exe}
cmp -s upx-unpacked${exe} upx-unpacked-nrv2d${exe}
cmp -s upx-unpacked${exe} upx-unpacked-nrv2e${exe}
cmp -s upx-unpacked${exe} upx-unpacked-lzma${exe}
if [[ $UPX_CONFIG_DISABLE_RUN_UNPACKED_TEST != ON ]]; then
"${emu[@]}" ./upx-unpacked${exe} --version-short
fi
if [[ $UPX_CONFIG_DISABLE_RUN_PACKED_TEST != ON ]]; then
"${emu[@]}" ./upx-packed${exe} --version-short
"${emu[@]}" ./upx-packed-fa${exe} --version-short
"${emu[@]}" ./upx-packed-fn${exe} --version-short
"${emu[@]}" ./upx-packed-fr${exe} --version-short
"${emu[@]}" ./upx-packed-nrv2b${exe} --version-short
"${emu[@]}" ./upx-packed-nrv2d${exe} --version-short
"${emu[@]}" ./upx-packed-nrv2e${exe} --version-short
"${emu[@]}" ./upx-packed-lzma${exe} --version-short
fi
if [[ $UPX_CONFIG_DISABLE_EXHAUSTIVE_TESTS != ON ]]; then
set +x
for method in nrv2b nrv2d nrv2e lzma; do
for level in 1 2 3 4 5 6 7; do
s="${method}-${level}"
echo "========== $s =========="
"${run_upx[@]}" -qq --${method} -${level} --all-filters --debug-use-random-filter "${upx_self_exe}" ${fo} -o upx-packed-${s}${exe}
"${run_upx[@]}" -qq -l upx-packed-${s}${exe}
"${run_upx[@]}" -qq --fileinfo upx-packed-${s}${exe}
"${run_upx[@]}" -qq -t upx-packed-${s}${exe}
"${run_upx[@]}" -qq -d upx-packed-${s}${exe} ${fo} -o upx-unpacked-${s}${exe}
cmp -s upx-unpacked${exe} upx-unpacked-${s}${exe}
if [[ $UPX_CONFIG_DISABLE_RUN_PACKED_TEST != ON ]]; then
"${emu[@]}" ./upx-packed-${s}${exe} --version-short
fi
done
done
fi
echo "run_upx='${run_upx[*]}'"
echo "All done."
+186 -155
View File
@@ -3,16 +3,27 @@
set -e; set -o pipefail set -e; set -o pipefail
argv0=$0; argv0abs=$(readlink -fn "$argv0"); argv0dir=$(dirname "$argv0abs") argv0=$0; argv0abs=$(readlink -fn "$argv0"); argv0dir=$(dirname "$argv0abs")
#
# Copyright (C) Markus Franz Xaver Johannes Oberhumer
#
# test file system behaviour with symlinks; requires:
# $upx_exe (required, but with convenience fallback "./upx")
# optional settings:
# $upx_exe_runner (e.g. "qemu-x86_64 -cpu Nehalem" or "valgrind")
# $upx_test_file
#
# IMPORTANT NOTE: this script only works on Unix
# IMPORTANT NOTE: do NOT run as user root!
umask 0022
# disable on macOS for now, see https://github.com/upx/upx/issues/612 # disable on macOS for now, see https://github.com/upx/upx/issues/612
if [[ "$(uname)" == Darwin ]]; then if [[ "$(uname)" == Darwin ]]; then
echo "$0: SKIPPED" case "$UPX_DEBUG_FORCE_PACK_MACOS" in
exit 0 "" | "0") echo "$0: SKIPPED"; exit 0 ;;
esac
fi fi
# IMPORTANT NOTE: do NOT run as user root!!
# IMPORTANT NOTE: this script only works on Unix!!
umask 0022
id || true id || true
echo "PWD='$PWD'" echo "PWD='$PWD'"
if [[ $UID == 0 || $EUID == 0 ]]; then if [[ $UID == 0 || $EUID == 0 ]]; then
@@ -20,11 +31,6 @@ if [[ $UID == 0 || $EUID == 0 ]]; then
exit 91 exit 91
fi fi
# test file system behaviour with symlinks; requires:
# $upx_exe (required, but with convenience fallback "./upx")
# optional settings:
# $upx_exe_runner (e.g. "qemu-x86_64 -cpu Westmere" or "valgrind")
#*********************************************************************** #***********************************************************************
# init & checks # init & checks
#*********************************************************************** #***********************************************************************
@@ -35,24 +41,28 @@ 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 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 upx_exe=$(readlink -fn "$upx_exe") # make absolute
[[ -f $upx_exe ]] || exit 1 [[ -f $upx_exe ]] || exit 1
upx_run=()
# set emu and run_upx
emu=()
if [[ -n $upx_exe_runner ]]; then if [[ -n $upx_exe_runner ]]; then
# usage examples: # usage examples:
# export upx_exe_runner="qemu-x86_64 -cpu Westmere" # export upx_exe_runner="qemu-x86_64 -cpu Nehalem"
# export upx_exe_runner="valgrind --leak-check=no --error-exitcode=1 --quiet" # export upx_exe_runner="valgrind --leak-check=no --error-exitcode=1 --quiet"
# export upx_exe_runner="wine" # export upx_exe_runner="wine"
IFS=' ' read -r -a upx_run <<< "$upx_exe_runner" # split at spaces into array IFS=' ' read -r -a emu <<< "$upx_exe_runner" # split at spaces into array
elif [[ -n $CMAKE_CROSSCOMPILING_EMULATOR ]]; then
IFS=';' read -r -a emu <<< "$CMAKE_CROSSCOMPILING_EMULATOR" # split at semicolons into array
fi fi
upx_run+=( "$upx_exe" ) run_upx=( "${emu[@]}" "$upx_exe" )
echo "upx_run='${upx_run[*]}'" echo "run_upx='${run_upx[*]}'"
# upx_run check # run_upx sanity check
if ! "${upx_run[@]}" --version-short >/dev/null; then echo "UPX-ERROR: FATAL: upx --version-short FAILED"; exit 1; fi if ! "${run_upx[@]}" --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 ! "${run_upx[@]}" -L >/dev/null 2>&1; then echo "UPX-ERROR: FATAL: upx -L FAILED"; exit 1; fi
if ! "${upx_run[@]}" --help >/dev/null; then echo "UPX-ERROR: FATAL: upx --help FAILED"; exit 1; fi if ! "${run_upx[@]}" --help >/dev/null; then echo "UPX-ERROR: FATAL: upx --help FAILED"; exit 1; fi
#*********************************************************************** #***********************************************************************
# util # util functions
#*********************************************************************** #***********************************************************************
exit_code=0 exit_code=0
@@ -153,18 +163,7 @@ create_files() {
chmod -R a-w z_dir_4 chmod -R a-w z_dir_4
} }
#*********************************************************************** print_header() {
#
#***********************************************************************
#set -x # debug
export UPX="--prefer-ucl --no-color --no-progress"
export UPX_DEBUG_DISABLE_GITREV_WARNING=1
export UPX_DEBUG_DOCTEST_VERBOSE=0
export NO_COLOR=1
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"
} }
@@ -179,206 +178,238 @@ leave_dir() {
cd .. cd ..
} }
# create a tmpdir in current directory #***********************************************************************
# setup
#***********************************************************************
#set -x # debug
export UPX="--prefer-ucl --no-color --no-progress"
export UPX_DEBUG_DISABLE_GITREV_WARNING=1
export UPX_DEBUG_DOCTEST_DISABLE=1 # already checked above
# get $test_file
if [[ -f $upx_test_file ]]; then
test_file="$(readlink -fn "$upx_test_file")"
else
for test_file in /usr/bin/gmake /usr/bin/make /usr/bin/env /bin/ls; do
if [[ -f $test_file ]]; then
test_file="$(readlink -fn "$test_file")"
break
fi
done
fi
ls -l "$test_file"
file "$test_file" || true
# create and enter a tmpdir in the current directory
tmpdir="$(mktemp -d tmp-upx-test-XXXXXX)" tmpdir="$(mktemp -d tmp-upx-test-XXXXXX)"
cd "./$tmpdir" || exit 1 cd "./$tmpdir" || exit 1
if [[ -f /bin/ls ]]; then #***********************************************************************
test_file="$(readlink -fn /bin/ls)" # default
else #***********************************************************************
test_file="$(readlink -fn /usr/bin/env)"
fi
testsuite_header "default" print_header "default"
flags="-qq -1 --no-filter" flags="-qq -2 --no-filter"
mkdir default mkdir default
cd default cd default
create_files create_files
enter_dir z_dir_1 enter_dir z_dir_1
"${upx_run[@]}" $flags z_symlink_file && failed 10 "${run_upx[@]}" $flags z_symlink_file && failed 10
"${upx_run[@]}" $flags "$test_file" -o z_file_new || failed 11 "${run_upx[@]}" $flags "$test_file" -o z_file_new || failed 11
"${upx_run[@]}" $flags "$test_file" -o z_dir && failed 12 "${run_upx[@]}" $flags "$test_file" -o z_dir && failed 12
"${upx_run[@]}" $flags "$test_file" -o z_file && failed 13 "${run_upx[@]}" $flags "$test_file" -o z_file && failed 13
"${upx_run[@]}" $flags "$test_file" -o z_file_link_1 && failed 14 "${run_upx[@]}" $flags "$test_file" -o z_file_link_1 && failed 14
"${upx_run[@]}" $flags "$test_file" -o z_symlink_file && failed 15 "${run_upx[@]}" $flags "$test_file" -o z_symlink_file && failed 15
"${upx_run[@]}" $flags "$test_file" -o z_symlink_file_link && failed 16 "${run_upx[@]}" $flags "$test_file" -o z_symlink_file_link && failed 16
"${upx_run[@]}" $flags "$test_file" -o z_symlink_dir && failed 17 "${run_upx[@]}" $flags "$test_file" -o z_symlink_dir && failed 17
"${upx_run[@]}" $flags "$test_file" -o z_symlink_dangling && failed 18 "${run_upx[@]}" $flags "$test_file" -o z_symlink_dangling && failed 18
assert_symlink_to_file z_symlink_file z_symlink_file_link assert_symlink_to_file z_symlink_file z_symlink_file_link
assert_symlink_to_dir z_symlink_dir assert_symlink_to_dir z_symlink_dir
assert_symlink_dangling z_symlink_dangling assert_symlink_dangling z_symlink_dangling
leave_dir leave_dir
enter_dir z_dir_2 enter_dir z_dir_2
"${upx_run[@]}" $flags z_symlink_file && failed 10 "${run_upx[@]}" $flags z_symlink_file && failed 10
"${upx_run[@]}" $flags "$test_file" -o z_file_new || failed 11 "${run_upx[@]}" $flags "$test_file" -o z_file_new || failed 11
"${upx_run[@]}" $flags "$test_file" -o z_dir && failed 12 "${run_upx[@]}" $flags "$test_file" -o z_dir && failed 12
"${upx_run[@]}" $flags "$test_file" -o z_file && failed 13 "${run_upx[@]}" $flags "$test_file" -o z_file && failed 13
"${upx_run[@]}" $flags "$test_file" -o z_file_link_1 && failed 14 "${run_upx[@]}" $flags "$test_file" -o z_file_link_1 && failed 14
"${upx_run[@]}" $flags "$test_file" -o z_symlink_file && failed 15 "${run_upx[@]}" $flags "$test_file" -o z_symlink_file && failed 15
"${upx_run[@]}" $flags "$test_file" -o z_symlink_file_link && failed 16 "${run_upx[@]}" $flags "$test_file" -o z_symlink_file_link && failed 16
"${upx_run[@]}" $flags "$test_file" -o z_symlink_dir && failed 17 "${run_upx[@]}" $flags "$test_file" -o z_symlink_dir && failed 17
"${upx_run[@]}" $flags "$test_file" -o z_symlink_dangling && failed 18 "${run_upx[@]}" $flags "$test_file" -o z_symlink_dangling && failed 18
assert_symlink_to_file z_symlink_file z_symlink_file_link assert_symlink_to_file z_symlink_file z_symlink_file_link
assert_symlink_to_dir z_symlink_dir assert_symlink_to_dir z_symlink_dir
assert_symlink_dangling z_symlink_dangling assert_symlink_dangling z_symlink_dangling
leave_dir leave_dir
enter_dir z_dir_3 enter_dir z_dir_3
"${upx_run[@]}" $flags z_symlink_file && failed 10 "${run_upx[@]}" $flags z_symlink_file && failed 10
"${upx_run[@]}" $flags "$test_file" -o z_file_new && failed 11 "${run_upx[@]}" $flags "$test_file" -o z_file_new && failed 11
"${upx_run[@]}" $flags "$test_file" -o z_dir && failed 12 "${run_upx[@]}" $flags "$test_file" -o z_dir && failed 12
"${upx_run[@]}" $flags "$test_file" -o z_file && failed 13 "${run_upx[@]}" $flags "$test_file" -o z_file && failed 13
"${upx_run[@]}" $flags "$test_file" -o z_file_link_1 && failed 14 "${run_upx[@]}" $flags "$test_file" -o z_file_link_1 && failed 14
"${upx_run[@]}" $flags "$test_file" -o z_symlink_file && failed 15 "${run_upx[@]}" $flags "$test_file" -o z_symlink_file && failed 15
"${upx_run[@]}" $flags "$test_file" -o z_symlink_file_link && failed 16 "${run_upx[@]}" $flags "$test_file" -o z_symlink_file_link && failed 16
"${upx_run[@]}" $flags "$test_file" -o z_symlink_dir && failed 17 "${run_upx[@]}" $flags "$test_file" -o z_symlink_dir && failed 17
"${upx_run[@]}" $flags "$test_file" -o z_symlink_dangling && failed 18 "${run_upx[@]}" $flags "$test_file" -o z_symlink_dangling && failed 18
assert_symlink_to_file z_symlink_file z_symlink_file_link assert_symlink_to_file z_symlink_file z_symlink_file_link
assert_symlink_to_dir z_symlink_dir assert_symlink_to_dir z_symlink_dir
assert_symlink_dangling z_symlink_dangling assert_symlink_dangling z_symlink_dangling
leave_dir leave_dir
enter_dir z_dir_4 enter_dir z_dir_4
"${upx_run[@]}" $flags z_symlink_file && failed 10 "${run_upx[@]}" $flags z_symlink_file && failed 10
"${upx_run[@]}" $flags "$test_file" -o z_file_new && failed 11 "${run_upx[@]}" $flags "$test_file" -o z_file_new && failed 11
"${upx_run[@]}" $flags "$test_file" -o z_dir && failed 12 "${run_upx[@]}" $flags "$test_file" -o z_dir && failed 12
"${upx_run[@]}" $flags "$test_file" -o z_file && failed 13 "${run_upx[@]}" $flags "$test_file" -o z_file && failed 13
"${upx_run[@]}" $flags "$test_file" -o z_file_link_1 && failed 14 "${run_upx[@]}" $flags "$test_file" -o z_file_link_1 && failed 14
"${upx_run[@]}" $flags "$test_file" -o z_symlink_file && failed 15 "${run_upx[@]}" $flags "$test_file" -o z_symlink_file && failed 15
"${upx_run[@]}" $flags "$test_file" -o z_symlink_file_link && failed 16 "${run_upx[@]}" $flags "$test_file" -o z_symlink_file_link && failed 16
"${upx_run[@]}" $flags "$test_file" -o z_symlink_dir && failed 17 "${run_upx[@]}" $flags "$test_file" -o z_symlink_dir && failed 17
"${upx_run[@]}" $flags "$test_file" -o z_symlink_dangling && failed 18 "${run_upx[@]}" $flags "$test_file" -o z_symlink_dangling && failed 18
assert_symlink_to_file z_symlink_file z_symlink_file_link assert_symlink_to_file z_symlink_file z_symlink_file_link
assert_symlink_to_dir z_symlink_dir assert_symlink_to_dir z_symlink_dir
assert_symlink_dangling z_symlink_dangling assert_symlink_dangling z_symlink_dangling
leave_dir leave_dir
cd .. cd ..
testsuite_header "force-overwrite" #***********************************************************************
flags="-qq -1 --no-filter --force-overwrite" # force-overwrite
#***********************************************************************
print_header "force-overwrite"
flags="-qq -2 --no-filter --force-overwrite"
mkdir force-overwrite mkdir force-overwrite
cd force-overwrite cd force-overwrite
create_files create_files
enter_dir z_dir_1 enter_dir z_dir_1
"${upx_run[@]}" $flags z_symlink_file && failed 10 "${run_upx[@]}" $flags z_symlink_file && failed 10
"${upx_run[@]}" $flags "$test_file" -o z_file_new || failed 11 "${run_upx[@]}" $flags "$test_file" -o z_file_new || failed 11
"${upx_run[@]}" $flags "$test_file" -o z_dir && failed 12 "${run_upx[@]}" $flags "$test_file" -o z_dir && failed 12
"${upx_run[@]}" $flags "$test_file" -o z_file || failed 13 "${run_upx[@]}" $flags "$test_file" -o z_file || failed 13
"${upx_run[@]}" $flags "$test_file" -o z_file_link_1 || failed 14 "${run_upx[@]}" $flags "$test_file" -o z_file_link_1 || failed 14
"${upx_run[@]}" $flags "$test_file" -o z_symlink_file || failed 15 "${run_upx[@]}" $flags "$test_file" -o z_symlink_file || failed 15
"${upx_run[@]}" $flags "$test_file" -o z_symlink_file_link || failed 16 "${run_upx[@]}" $flags "$test_file" -o z_symlink_file_link || failed 16
"${upx_run[@]}" $flags "$test_file" -o z_symlink_dir || failed 17 "${run_upx[@]}" $flags "$test_file" -o z_symlink_dir || failed 17
"${upx_run[@]}" $flags "$test_file" -o z_symlink_dangling || failed 18 "${run_upx[@]}" $flags "$test_file" -o z_symlink_dangling || failed 18
assert_file z_symlink_file z_symlink_file_link assert_file z_symlink_file z_symlink_file_link
assert_file z_symlink_dir assert_file z_symlink_dir
assert_file z_symlink_dangling assert_file z_symlink_dangling
leave_dir leave_dir
enter_dir z_dir_2 enter_dir z_dir_2
"${upx_run[@]}" $flags z_symlink_file && failed 10 "${run_upx[@]}" $flags z_symlink_file && failed 10
"${upx_run[@]}" $flags "$test_file" -o z_file_new || failed 11 "${run_upx[@]}" $flags "$test_file" -o z_file_new || failed 11
"${upx_run[@]}" $flags "$test_file" -o z_dir && failed 12 "${run_upx[@]}" $flags "$test_file" -o z_dir && failed 12
"${upx_run[@]}" $flags "$test_file" -o z_file || failed 13 "${run_upx[@]}" $flags "$test_file" -o z_file || failed 13
"${upx_run[@]}" $flags "$test_file" -o z_file_link_1 || failed 14 "${run_upx[@]}" $flags "$test_file" -o z_file_link_1 || failed 14
"${upx_run[@]}" $flags "$test_file" -o z_symlink_file || failed 15 "${run_upx[@]}" $flags "$test_file" -o z_symlink_file || failed 15
"${upx_run[@]}" $flags "$test_file" -o z_symlink_file_link || failed 16 "${run_upx[@]}" $flags "$test_file" -o z_symlink_file_link || failed 16
"${upx_run[@]}" $flags "$test_file" -o z_symlink_dir || failed 17 "${run_upx[@]}" $flags "$test_file" -o z_symlink_dir || failed 17
"${upx_run[@]}" $flags "$test_file" -o z_symlink_dangling || failed 18 "${run_upx[@]}" $flags "$test_file" -o z_symlink_dangling || failed 18
assert_file z_symlink_file z_symlink_file_link assert_file z_symlink_file z_symlink_file_link
assert_file z_symlink_dir assert_file z_symlink_dir
assert_file z_symlink_dangling assert_file z_symlink_dangling
leave_dir leave_dir
enter_dir z_dir_3 enter_dir z_dir_3
"${upx_run[@]}" $flags z_symlink_file && failed 10 "${run_upx[@]}" $flags z_symlink_file && failed 10
"${upx_run[@]}" $flags "$test_file" -o z_file_new && failed 11 "${run_upx[@]}" $flags "$test_file" -o z_file_new && failed 11
"${upx_run[@]}" $flags "$test_file" -o z_dir && failed 12 "${run_upx[@]}" $flags "$test_file" -o z_dir && failed 12
"${upx_run[@]}" $flags "$test_file" -o z_file || failed 13 "${run_upx[@]}" $flags "$test_file" -o z_file || failed 13
"${upx_run[@]}" $flags "$test_file" -o z_file_link_1 || failed 14 "${run_upx[@]}" $flags "$test_file" -o z_file_link_1 || failed 14
"${upx_run[@]}" $flags "$test_file" -o z_symlink_file || failed 15 "${run_upx[@]}" $flags "$test_file" -o z_symlink_file || failed 15
"${upx_run[@]}" $flags "$test_file" -o z_symlink_file_link || failed 16 "${run_upx[@]}" $flags "$test_file" -o z_symlink_file_link || failed 16
"${upx_run[@]}" $flags "$test_file" -o z_symlink_dir && failed 17 "${run_upx[@]}" $flags "$test_file" -o z_symlink_dir && failed 17
"${upx_run[@]}" $flags "$test_file" -o z_symlink_dangling && failed 18 "${run_upx[@]}" $flags "$test_file" -o z_symlink_dangling && failed 18
assert_symlink_to_file z_symlink_file z_symlink_file_link assert_symlink_to_file z_symlink_file z_symlink_file_link
assert_symlink_to_dir z_symlink_dir assert_symlink_to_dir z_symlink_dir
assert_symlink_dangling z_symlink_dangling assert_symlink_dangling z_symlink_dangling
leave_dir leave_dir
enter_dir z_dir_4 enter_dir z_dir_4
"${upx_run[@]}" $flags z_symlink_file && failed 10 "${run_upx[@]}" $flags z_symlink_file && failed 10
"${upx_run[@]}" $flags "$test_file" -o z_file_new && failed 11 "${run_upx[@]}" $flags "$test_file" -o z_file_new && failed 11
"${upx_run[@]}" $flags "$test_file" -o z_dir && failed 12 "${run_upx[@]}" $flags "$test_file" -o z_dir && failed 12
"${upx_run[@]}" $flags "$test_file" -o z_file || failed 13 "${run_upx[@]}" $flags "$test_file" -o z_file || failed 13
"${upx_run[@]}" $flags "$test_file" -o z_file_link_1 || failed 14 "${run_upx[@]}" $flags "$test_file" -o z_file_link_1 || failed 14
"${upx_run[@]}" $flags "$test_file" -o z_symlink_file || failed 15 "${run_upx[@]}" $flags "$test_file" -o z_symlink_file || failed 15
"${upx_run[@]}" $flags "$test_file" -o z_symlink_file_link || failed 16 "${run_upx[@]}" $flags "$test_file" -o z_symlink_file_link || failed 16
"${upx_run[@]}" $flags "$test_file" -o z_symlink_dir && failed 17 "${run_upx[@]}" $flags "$test_file" -o z_symlink_dir && failed 17
"${upx_run[@]}" $flags "$test_file" -o z_symlink_dangling && failed 18 "${run_upx[@]}" $flags "$test_file" -o z_symlink_dangling && failed 18
assert_symlink_to_file z_symlink_file z_symlink_file_link assert_symlink_to_file z_symlink_file z_symlink_file_link
assert_symlink_to_dir z_symlink_dir assert_symlink_to_dir z_symlink_dir
assert_symlink_dangling z_symlink_dangling assert_symlink_dangling z_symlink_dangling
leave_dir leave_dir
cd .. cd ..
if [[ 1 == 1 ]]; then #***********************************************************************
testsuite_header "link" # link
flags="-qq -1 --no-filter --link" #***********************************************************************
print_header "link"
flags="-qq -2 --no-filter --link"
mkdir link mkdir link
cd link cd link
create_files create_files
enter_dir z_dir_1 enter_dir z_dir_1
"${upx_run[@]}" $flags z_symlink_file && failed 10 "${run_upx[@]}" $flags z_symlink_file && failed 10
"${upx_run[@]}" $flags "$test_file" -o z_file_new || failed 11 "${run_upx[@]}" $flags "$test_file" -o z_file_new || failed 11
"${upx_run[@]}" $flags "$test_file" -o z_dir && failed 12 "${run_upx[@]}" $flags "$test_file" -o z_dir && failed 12
"${upx_run[@]}" $flags "$test_file" -o z_file || failed 13 "${run_upx[@]}" $flags "$test_file" -o z_file || failed 13
"${upx_run[@]}" $flags "$test_file" -o z_file_link_1 || failed 14 "${run_upx[@]}" $flags "$test_file" -o z_file_link_1 || failed 14
"${upx_run[@]}" $flags "$test_file" -o z_symlink_file || failed 15 "${run_upx[@]}" $flags "$test_file" -o z_symlink_file || failed 15
"${upx_run[@]}" $flags "$test_file" -o z_symlink_file_link || failed 16 "${run_upx[@]}" $flags "$test_file" -o z_symlink_file_link || failed 16
"${upx_run[@]}" $flags "$test_file" -o z_symlink_dir || failed 17 "${run_upx[@]}" $flags "$test_file" -o z_symlink_dir || failed 17
"${upx_run[@]}" $flags "$test_file" -o z_symlink_dangling || failed 18 "${run_upx[@]}" $flags "$test_file" -o z_symlink_dangling || failed 18
assert_file z_symlink_file z_symlink_file_link assert_file z_symlink_file z_symlink_file_link
assert_file z_symlink_dir assert_file z_symlink_dir
assert_file z_symlink_dangling assert_file z_symlink_dangling
leave_dir leave_dir
enter_dir z_dir_2 enter_dir z_dir_2
"${upx_run[@]}" $flags z_symlink_file && failed 10 "${run_upx[@]}" $flags z_symlink_file && failed 10
"${upx_run[@]}" $flags "$test_file" -o z_file_new || failed 11 "${run_upx[@]}" $flags "$test_file" -o z_file_new || failed 11
"${upx_run[@]}" $flags "$test_file" -o z_dir && failed 12 "${run_upx[@]}" $flags "$test_file" -o z_dir && failed 12
"${upx_run[@]}" $flags "$test_file" -o z_file && failed 13 "${run_upx[@]}" $flags "$test_file" -o z_file && failed 13
"${upx_run[@]}" $flags "$test_file" -o z_file_link_1 && failed 14 "${run_upx[@]}" $flags "$test_file" -o z_file_link_1 && failed 14
"${upx_run[@]}" $flags "$test_file" -o z_symlink_file || failed 15 "${run_upx[@]}" $flags "$test_file" -o z_symlink_file || failed 15
"${upx_run[@]}" $flags "$test_file" -o z_symlink_file_link || failed 16 "${run_upx[@]}" $flags "$test_file" -o z_symlink_file_link || failed 16
"${upx_run[@]}" $flags "$test_file" -o z_symlink_dir || failed 17 "${run_upx[@]}" $flags "$test_file" -o z_symlink_dir || failed 17
"${upx_run[@]}" $flags "$test_file" -o z_symlink_dangling || failed 18 "${run_upx[@]}" $flags "$test_file" -o z_symlink_dangling || failed 18
assert_file z_symlink_file z_symlink_file_link assert_file z_symlink_file z_symlink_file_link
assert_file z_symlink_dir assert_file z_symlink_dir
assert_file z_symlink_dangling assert_file z_symlink_dangling
leave_dir leave_dir
enter_dir z_dir_3 enter_dir z_dir_3
"${upx_run[@]}" $flags z_symlink_file && failed 10 "${run_upx[@]}" $flags z_symlink_file && failed 10
"${upx_run[@]}" $flags "$test_file" -o z_file_new && failed 11 "${run_upx[@]}" $flags "$test_file" -o z_file_new && failed 11
"${upx_run[@]}" $flags "$test_file" -o z_dir && failed 12 "${run_upx[@]}" $flags "$test_file" -o z_dir && failed 12
"${upx_run[@]}" $flags "$test_file" -o z_file || failed 13 "${run_upx[@]}" $flags "$test_file" -o z_file || failed 13
"${upx_run[@]}" $flags "$test_file" -o z_file_link_1 || failed 14 "${run_upx[@]}" $flags "$test_file" -o z_file_link_1 || failed 14
"${upx_run[@]}" $flags "$test_file" -o z_symlink_file || failed 15 "${run_upx[@]}" $flags "$test_file" -o z_symlink_file || failed 15
"${upx_run[@]}" $flags "$test_file" -o z_symlink_file_link || failed 16 "${run_upx[@]}" $flags "$test_file" -o z_symlink_file_link || failed 16
"${upx_run[@]}" $flags "$test_file" -o z_symlink_dir && failed 17 "${run_upx[@]}" $flags "$test_file" -o z_symlink_dir && failed 17
"${upx_run[@]}" $flags "$test_file" -o z_symlink_dangling && failed 18 "${run_upx[@]}" $flags "$test_file" -o z_symlink_dangling && failed 18
assert_symlink_to_file z_symlink_file z_symlink_file_link assert_symlink_to_file z_symlink_file z_symlink_file_link
assert_symlink_to_dir z_symlink_dir assert_symlink_to_dir z_symlink_dir
assert_symlink_dangling z_symlink_dangling assert_symlink_dangling z_symlink_dangling
leave_dir leave_dir
enter_dir z_dir_4 enter_dir z_dir_4
"${upx_run[@]}" $flags z_symlink_file && failed 10 "${run_upx[@]}" $flags z_symlink_file && failed 10
"${upx_run[@]}" $flags "$test_file" -o z_file_new && failed 11 "${run_upx[@]}" $flags "$test_file" -o z_file_new && failed 11
"${upx_run[@]}" $flags "$test_file" -o z_dir && failed 12 "${run_upx[@]}" $flags "$test_file" -o z_dir && failed 12
"${upx_run[@]}" $flags "$test_file" -o z_file && failed 13 "${run_upx[@]}" $flags "$test_file" -o z_file && failed 13
"${upx_run[@]}" $flags "$test_file" -o z_file_link_1 && failed 14 "${run_upx[@]}" $flags "$test_file" -o z_file_link_1 && failed 14
"${upx_run[@]}" $flags "$test_file" -o z_symlink_file || failed 15 "${run_upx[@]}" $flags "$test_file" -o z_symlink_file || failed 15
"${upx_run[@]}" $flags "$test_file" -o z_symlink_file_link || failed 16 "${run_upx[@]}" $flags "$test_file" -o z_symlink_file_link || failed 16
"${upx_run[@]}" $flags "$test_file" -o z_symlink_dir && failed 17 "${run_upx[@]}" $flags "$test_file" -o z_symlink_dir && failed 17
"${upx_run[@]}" $flags "$test_file" -o z_symlink_dangling && failed 18 "${run_upx[@]}" $flags "$test_file" -o z_symlink_dangling && failed 18
assert_symlink_to_file z_symlink_file z_symlink_file_link assert_symlink_to_file z_symlink_file z_symlink_file_link
assert_symlink_to_dir z_symlink_dir assert_symlink_to_dir z_symlink_dir
assert_symlink_dangling z_symlink_dangling assert_symlink_dangling z_symlink_dangling
leave_dir leave_dir
cd .. cd ..
fi
#***********************************************************************
# done
#***********************************************************************
# clean up # clean up
cd .. cd ..
+147 -147
View File
@@ -46,164 +46,164 @@ b8c35fa2956da17ca505956e9f5017bb5f3a746322647e24ccb8ff28059cafa4 *powerpc-linux.
a0950546dc17fca9437219431d8ddb0249ce5b08e899e0c799a87ac982adee70 *powerpc64le-linux.elf/upx-3.95 a0950546dc17fca9437219431d8ddb0249ce5b08e899e0c799a87ac982adee70 *powerpc64le-linux.elf/upx-3.95
" "
expected_sha256sums__t110_compress_ucl_nrv2b_3_no_filter="\ expected_sha256sums__t110_compress_ucl_nrv2b_3_no_filter="\
fb458e6e7718ffd3f060fca911d069a024df8da7c75e34a0aea820a15ca03551 *amd64-linux.elf/upx-3.91 ef49d1c9617dbb3dc1bb36ab70df8a263cd816cc5e91ad28cc62f91ccc77afa7 *amd64-linux.elf/upx-3.91
8988a2556bff2da1a5de9a5a4c909a53ae99a825fcdc7699d4c504bc697f60df *amd64-linux.elf/upx-3.95 253b1542cdcd5d554eb442e263eb44e400f00e63cfd4d0d727eacec5fcdbbd00 *amd64-linux.elf/upx-3.95
b8bf6a29177bc7e9595d1c2a200f2c6431e12eee1ca2c8a64064a52c792b7b65 *amd64-win64.pe/upx-3.95.exe d96c42d14684e7248de5712310364eafa28b337695bc0d8c37f91d593b869250 *amd64-win64.pe/upx-3.95.exe
02c17f49a54f50a9ed453227b600feb4ba5574514552d1cb344b1b012265afb2 *arm-linux.elf/upx-3.95 c1d3b9ec3157f068097f5deffddce4fc4d3d95602daa539992e0accff6af0de8 *arm-linux.elf/upx-3.95
0006e29a124430722e691a05afab0a381d332c2ffe53c7f6a2cdf4cdea5349ce *arm-wince.pe/upx-3.91.exe 9ca862c0c92d7e4068145024486bb85a6031bf06f9a37c6af543234e08e8ab36 *arm-wince.pe/upx-3.91.exe
94a60c5859fc98db7671828decfb456e670a402a676d97cd4d66b5406c062f1f *arm64-linux.elf/upx-3.95 9173b4e4b1ac0b92e63dc51168dbd41d38208520b0f4c17b91d22e584ad55ae4 *arm64-linux.elf/upx-3.95
654a4e4cb325caddcf150ca90f2729c748bb0a3e99e703c6aad6a9dbc7d6d6e1 *armeb-linux.elf/upx-3.91 8c6c5f1678fb74d2f65a1e6c28e3089a4b99b49939fabac3ca1f71183bc73ffa *armeb-linux.elf/upx-3.91
c68172e589871dc76cc7dff5464c87cd83a8cf9178d3b340e166912bcf6c9a0a *armeb-linux.elf/upx-3.95 13caa682f323a0438a651f53768af9b7fb1208980d46d94c6fb984ecf4422599 *armeb-linux.elf/upx-3.95
ecc834183718c481c724754356977f4d63a58a07a2a308b9d2d669cf4d859b10 *i386-dos32.djgpp2.coff/upx-3.91.exe 55f30818e45da393628aa80c3518f3cf099666ae3af5014bded2196ea28ddaea *i386-dos32.djgpp2.coff/upx-3.91.exe
879bdb9fc4c2ff76688250b429281a0a196c3723aabb40657f61a256d271b407 *i386-dos32.djgpp2.coff/upx-3.95.exe 6b80b2be79ec38af3071fcaf8f0d0ec524e4523e7e52e2f10111862ab93ec793 *i386-dos32.djgpp2.coff/upx-3.95.exe
582e7d54ba02aa4133a82ed423fce85376a3e2435468c2275e6500895f80b62d *i386-linux.elf/upx-3.91 9bb71da401ae398ca42cde73afffe0c0db29fff24f22196c4116636ab6385170 *i386-linux.elf/upx-3.91
00501788b58d4523faad8e0d0a9832d1f743e33739f8190be19094e2aa002c77 *i386-linux.elf/upx-3.95 c2375a808f989c0f8290fcd9760db0033413323d8597deb796f182f8ac38afa2 *i386-linux.elf/upx-3.95
9b9c922a6ddd48cf92af8aaa99452c101d69eb65f83e5fed6870bfe5450ca66c *i386-win32.pe/upx-3.91.exe 892695e1abdc0fbbd110ee30c317fde56947f4a8b3dfe413507ee7665f109986 *i386-win32.pe/upx-3.91.exe
85a21b38b2c0ddf94bfd41b28c6a7af74accfa2246cb7f6c5881a0525cbbcdd0 *i386-win32.pe/upx-3.95.exe f76ec227836388da3174007e2c5e27fb6cb397a83297872e78befb298a65796d *i386-win32.pe/upx-3.95.exe
993eb24cdacd30fd0ad915c88ea523f19748e4f4b3c4f7302dc233ceec67501e *m68k-atari.tos/upx-3.91.ttp 8f7c5b3d67c78c117c02bec8b30ec5fca7baa79a35d250a4d981cb7137f8635d *m68k-atari.tos/upx-3.91.ttp
b48802d429cb7edab4d945a658a7f2aa65f67e48085ee9f40999e63cd164089b *mips-linux.elf/upx-3.95 745ac3afd263f3a653165bd229e35c817a58c9b894a8d6fbd4e5aaf6c38c1264 *mips-linux.elf/upx-3.95
aac26e3324c3a07d0cb41ee68dddc29891334e13ccd60bfb9138729a2f27742d *mipsel-linux.elf/upx-3.91 a11da76425bc3bb308de3c19e6df22f56bf12c95afcf96ee8c2d4aaeda07ac8a *mipsel-linux.elf/upx-3.91
85803d12a0262bb424c95efff414e7882dc1104164c245ab90dff27ee5bd41db *mipsel-linux.elf/upx-3.95 76c458e8e9b94eceb60d8c51f602a5dec44b2617886ea0b5b7b8802c61d962e9 *mipsel-linux.elf/upx-3.95
e1ec8a1d392e0493c9fd60f3327d85aec108815100ab01ae65210cd26c917888 *powerpc-linux.elf/upx-3.91 cec277d9e6e0cbf551f697c1d52e5d29b48533efbe4269df0aafbc12731a93ed *powerpc-linux.elf/upx-3.91
845aad9ec6cba72b3a83c9958e9718938fdfd3d18ac76170d81f57c1c86987a0 *powerpc-linux.elf/upx-3.95 92c6cec7bf40d1aa5a62a55fce95bb99d94c5b477edbea127ee0468471ddbdb3 *powerpc-linux.elf/upx-3.95
149efbda7f68c354d48771d838aca07cbdda503746bb83497ec8ab226dea4792 *powerpc64le-linux.elf/upx-3.95 df2f12597c901196e8f10782e72fb4c294955f03a66cc4e8bf3c24414929f717 *powerpc64le-linux.elf/upx-3.95
" "
expected_sha256sums__t120_compress_ucl_nrv2d_3_no_filter="\ expected_sha256sums__t120_compress_ucl_nrv2d_3_no_filter="\
3f1d7ad512df7cc6f1fa4fe4a37f21d92709764fc385e307504e12208c090df4 *amd64-linux.elf/upx-3.91 f7e51450a373cb49f88e3e17c268f4198429f7ad06bed57dda28161b5383196a *amd64-linux.elf/upx-3.91
a9291e95bc5c59193ae318c4bf13341ade909b8a6b42694c33cb3a9d1a084637 *amd64-linux.elf/upx-3.95 15c57828824d18604519fd43349f0340ccebfddf246ab355f8f30253123132ea *amd64-linux.elf/upx-3.95
968c6c681b99c6ad21f3100527da0d2f0ccc510885d6a23b1db613207aedc739 *amd64-win64.pe/upx-3.95.exe 728b2feceda3cfdd849aef4402d5d4e61aa6fa6d56266e7730b148dc66f4a7b0 *amd64-win64.pe/upx-3.95.exe
e06b57cd0013db94ba298bef4b30d904ad8eadafb7db6b4b4964de65f9fae0ad *arm-linux.elf/upx-3.95 188a3581ed2bac5fdfd50e08267e2e9cf4cf3ddbfc9f5ae15643298bda4bf11c *arm-linux.elf/upx-3.95
bf6c7ba2a464f7dfcdff230462a23f9bcfafaebddb7746f0021367076ede58ac *arm-wince.pe/upx-3.91.exe 0711f0b8531de9659f099f43f2a883d628bee8de67f927e7137c19c6d23a30bd *arm-wince.pe/upx-3.91.exe
053c60a4a376ddf3e5ac9b91933e483b86f184f02369c1df204b32acda2d72f7 *arm64-linux.elf/upx-3.95 ae6fa69b1242bdfe808d64b7bbefddfe9c1c96302627ee8c65fa2851102fc502 *arm64-linux.elf/upx-3.95
63bbc0b63ec9504650869e0b51a6941c9d8f6d472463e9f602e26e6a21c493fc *armeb-linux.elf/upx-3.91 7586b4029355eff2edf25141835ee2405ab9f936956e56420315c3d3fecc8bda *armeb-linux.elf/upx-3.91
f0b78117ac4a4671470cbff4b10907024d3811ee4197dcaa5cad0a84c98c8693 *armeb-linux.elf/upx-3.95 e37875b1a91ef3c88bdba113649a061b72239dbfe77b77077c51254037a982b6 *armeb-linux.elf/upx-3.95
86888d40e8b17fd59a1ed78264e075e1b04b57ca020c43768b37f916beb11649 *i386-dos32.djgpp2.coff/upx-3.91.exe 536e5a6bb18378f3eea81be12f218f4da60ea81eddf480434aaf418610e4e52d *i386-dos32.djgpp2.coff/upx-3.91.exe
57f916c1f0fb33746de4c65f232258fb48acb2aa266b59ffdeac0c654bc650ca *i386-dos32.djgpp2.coff/upx-3.95.exe 386f3037b26b8b2ce49a527028d738956e7ef649b29a0ef15e32acef4a3b291a *i386-dos32.djgpp2.coff/upx-3.95.exe
efc046cd508c647651fa6574b171fb44ebf2bf785d7bd9ec3fcc6b24b01db96b *i386-linux.elf/upx-3.91 5761d8e12b01163c2bf378bef813df9a621da08c4508773db992a1cce067c70c *i386-linux.elf/upx-3.91
279325e2cac136e24ec928eba687849c3359ab9ce76ad9502a64d3883029ee5c *i386-linux.elf/upx-3.95 8afc2b549e2f78987641045697afaac0378b48e84c3e946334c9e4f1a7e693fa *i386-linux.elf/upx-3.95
8b7aba7c9e733bb72844d797cb9f6a7225b4ce79ee62e38a9e424b4c5cc63ade *i386-win32.pe/upx-3.91.exe 1cc6663f3d9e847f9fec39a52c8efe38b39a66074c0ad77a880a84dde7c68d3f *i386-win32.pe/upx-3.91.exe
e966278db2d69913989bcfddf998e8f5b35fd8045c55b1e45065fc121c2452a0 *i386-win32.pe/upx-3.95.exe edf158ec6064e9b11b677a73239a70e414fa8c4f3b8950f74e81514ccb28ef4f *i386-win32.pe/upx-3.95.exe
475777e4b8284a57e61cec9fa61549b06b761f6fe77ffdf24e23997eefd87036 *m68k-atari.tos/upx-3.91.ttp faa36b6601743dcc5eaedb57187a893006652b6c68acecff179ce2cd123e6209 *m68k-atari.tos/upx-3.91.ttp
fd726e5be8f899cea4ce147beb23e7697953220f680b54d9ad12ecbbf6764fd9 *mips-linux.elf/upx-3.95 6c76928b5914b5c2e072bf2f90a2c95049cc41aec6b98b1f0b3c4f84df069f02 *mips-linux.elf/upx-3.95
36e40ec2e07cf2a095f6d1c58d5d454a486d24fa1406890ccc3dcaf3223b1ed3 *mipsel-linux.elf/upx-3.91 029c2a47f1f613c538d2f39674167489a9d1bbbb6649a06d51d2b5ea983b4924 *mipsel-linux.elf/upx-3.91
97a0b1e3744f4168905c6423778f9fef887a467e9f382677f1da785f2f3fd5ea *mipsel-linux.elf/upx-3.95 4d837edcaf344505ad1a3721ec8e5db35ddaa273a747201e460b946c0a89d6ea *mipsel-linux.elf/upx-3.95
1576fcc71df7ac816aa3b322b9c399df017f05e99b843b98ce02be15e5ef9148 *powerpc-linux.elf/upx-3.91 0e24a9e58939f7aacd3482db24e04bdac406a658dbb8d5e65d71d76d455e5aa5 *powerpc-linux.elf/upx-3.91
768a206b9dac7816bd9b1b5c86fbfdf1f5a6920fa2cbc35e50b19d58779b219e *powerpc-linux.elf/upx-3.95 04bd4885f37c77a34b39e76cca2fd363f794ed1611093d7fffe1ee19920ce1dd *powerpc-linux.elf/upx-3.95
287d53686422057d5c7ddad5c30ad2a3342424153b162f3769fe8fe717b48b91 *powerpc64le-linux.elf/upx-3.95 3b6be5bff0e435a8dbd8529562912c58dafdcb9694d75564238f3d086048abd2 *powerpc64le-linux.elf/upx-3.95
" "
expected_sha256sums__t130_compress_ucl_nrv2e_3_no_filter="\ expected_sha256sums__t130_compress_ucl_nrv2e_3_no_filter="\
3f04cc82752ee6c573e6ed22a44943caa1126503ad898def7452e25df14709ec *amd64-linux.elf/upx-3.91 715de64e0911c959d0ea208db13bf23a5e635e97e73feb9e04ac9d32117e6a3f *amd64-linux.elf/upx-3.91
7a3103783fb6c1e34b476e2cbeb7a5992c635dcd643d1ff37e5aeaf57f70f268 *amd64-linux.elf/upx-3.95 da805c93ffea03da2f0c0dbb1b313cf0d88ef2c0cb0ad77b0be792210106cd6c *amd64-linux.elf/upx-3.95
509be220b15f12853a26207f8c2fe361feed50203adb3af4e2bb03aab3467221 *amd64-win64.pe/upx-3.95.exe 213e6d3c80b4d741e8c78da915d32c1a2b74072d31e86ec46a10ac2535cf8f6f *amd64-win64.pe/upx-3.95.exe
e2e4dfb92a85a1e8d06d2d28778f63c3efec484b91c58236ce9df02cfe3e012e *arm-linux.elf/upx-3.95 3a66e868147347208935c042517b9f0e2e30d2dbb5c004ec8df6a9ab1e42ecd5 *arm-linux.elf/upx-3.95
18bf698a9ea039a0c3f1de9cab845dc1b51ad881e96daba4b7389adca830ecec *arm-wince.pe/upx-3.91.exe 8d295980b1e6a8240bf75b86a9b8e4561424cbabeab01246f51e553d84b40839 *arm-wince.pe/upx-3.91.exe
b2155656ba70f468cc21fe0125dd2a2a9b0bf4b5d802eb399565c15b2997f1f8 *arm64-linux.elf/upx-3.95 194947a439c1348570e45343e404c409be3f10feb70fdd87d9bca0addc772c44 *arm64-linux.elf/upx-3.95
4dab150e1309d643583ded5262dea6f5ffa82ef7e3533515d10ef3c95dc11ea5 *armeb-linux.elf/upx-3.91 a01384f43803428e0bfc5f8152304eb8618ef862e4e996a4a4fa4dd9c4576833 *armeb-linux.elf/upx-3.91
25b072a5a86ead3bd9ddc539c3f29d5fd2c9cceb010657ace5eec827f73cec93 *armeb-linux.elf/upx-3.95 f2fdba359d52bb82fbab093176a3fbf37b9cb13e8d297523ed57051c3bd401e3 *armeb-linux.elf/upx-3.95
d7d0d5c45297d81cf4de9256c43ebbe236d1a839daeb16c900ebb5c1503659f0 *i386-dos32.djgpp2.coff/upx-3.91.exe 582030394a570f92be2d31b3862ab7fb0a6f08982c793a4d41c1471d2cabb939 *i386-dos32.djgpp2.coff/upx-3.91.exe
262fa423a8cdd765156b9385f4f1fe2fc8bba4b7e9904281f6f99a7a867ecdd1 *i386-dos32.djgpp2.coff/upx-3.95.exe f60dc2f332f58b7fa08f551f8c33d645d71d9ee79e2a719130d10ea4091373ef *i386-dos32.djgpp2.coff/upx-3.95.exe
a74811a5f2b2bf26b1d64ff8e5ac5d9111bbc3022bea77b5389a2253a059c6e9 *i386-linux.elf/upx-3.91 13887e5466a7d0fc2652aedcef44e33e6ee9b8d6f0ac21dbc4ec90fcc0613bfa *i386-linux.elf/upx-3.91
b4c9632a18ac07b7351ea3a24e112ee32cba67eec194dc822f5211d793665d63 *i386-linux.elf/upx-3.95 636759f884399ff05e8493a759f60ea52cd4640eb5e9760f12fc25fbf730b1ed *i386-linux.elf/upx-3.95
b35b94f6f14e0795a3e30d04aa6cb9cb1fca6dc15a45cf99f9ce66646b438d74 *i386-win32.pe/upx-3.91.exe c4a5d27ce7d8f0f326e49489223eda188a9be61971a88758a559efb9f854611a *i386-win32.pe/upx-3.91.exe
11505bfed2b91ff3df360c3fcf5e701bce6c536f79f4743eff367bf4e16a686b *i386-win32.pe/upx-3.95.exe 4ca9a3dd0e0ec38cc1aa3720d9c666f86df4fbe9dcb87ef0dad56d0a47dc327a *i386-win32.pe/upx-3.95.exe
ac45ed125aa0e5f002556e9410d32e4007cb905cf71354df20e38785a90e0ea0 *m68k-atari.tos/upx-3.91.ttp f34a020e6325d213052d9f09c775c4d292c34c51380b1ab1b22c6663645167f0 *m68k-atari.tos/upx-3.91.ttp
773e144b638f23cfa2640e5c6760d6f847d477efa0c64c158e24be7efbdb765d *mips-linux.elf/upx-3.95 3006af1262a29173c46340f1ee4526fba41145f7476841d5bf6b499aa6dea0fd *mips-linux.elf/upx-3.95
bd53867507b9449dc8c12007d8ed16ef332b8c4d96b1749cbd8b731a61402215 *mipsel-linux.elf/upx-3.91 6af81d3c7cb6f1388925fe2d78ea96313d91d5e17249268739de4d56857f27bd *mipsel-linux.elf/upx-3.91
a72cffc63f3415f5c913a504c2d2af30cd533f849cd7866b65a8b4c91301c475 *mipsel-linux.elf/upx-3.95 9d3849cd0037ef550703c574e0ccb3032b0d27217ec02c90a0ad8592d2a229f1 *mipsel-linux.elf/upx-3.95
1c93b25a4846fce0d2242d753f0a6e662f018a8d63234236e88c7cf32e104d22 *powerpc-linux.elf/upx-3.91 704b6eb2033cf3eab30cbc53c35fc85bf0cb17f904528792de33967a1406091d *powerpc-linux.elf/upx-3.91
263f4d184edab2716accbcdda2749a348a0b3d055d3096fa8c85d975c66a2342 *powerpc-linux.elf/upx-3.95 b89b2f3b250ddd156cb857717c86a0c0325a26dd084717c64f3022277ad02be4 *powerpc-linux.elf/upx-3.95
9b04dbab6863895dd3df5b0fe50086eff57e401d853a55fd9cdd06c0794e7ce7 *powerpc64le-linux.elf/upx-3.95 d52f201ab041fa64a4ee4234bd0e443e883e402bb93ced9e22554bd3ef3cc9ab *powerpc64le-linux.elf/upx-3.95
" "
expected_sha256sums__t140_compress_lzma_2_no_filter="\ expected_sha256sums__t140_compress_lzma_2_no_filter="\
68ea7e46654a94a1c125e039b9167ee8724edf0762f5522e81cfbb94005af8fd *amd64-linux.elf/upx-3.91 af8536d70ecb8c0680c1c9dc45ef60dcb13fab99f0e4644d9f86216a9cf003e2 *amd64-linux.elf/upx-3.91
7adf842624efaa46a03b1861fee62dbc01c1e22387b29fa16f530d3c6aa4d295 *amd64-linux.elf/upx-3.95 004a705f4981a19f35767b33bdb70b942717a701ad8635bd56ba33e347c6ed69 *amd64-linux.elf/upx-3.95
77aa80d55f83afdfb3796dfbe972b79a2195b37f84e9bb87ff7d11e497927021 *amd64-win64.pe/upx-3.95.exe cf07c202497ab38417ec3ccb65cbb0eb9b87f6c6df40d7dc4b44616282c8e0f8 *amd64-win64.pe/upx-3.95.exe
16916c440d76231df63ae5260bcf28c65476d06319d51e084f1730ab83d279bc *arm-linux.elf/upx-3.95 da153c1747e0e242cc8b90c04362f67caa0aa638562bc12fcc7fe08ebb1b4fcb *arm-linux.elf/upx-3.95
fae27479b40010e1d0794fe28fcc619c64a6ff21888221089fee429135658580 *arm-wince.pe/upx-3.91.exe 9755110ebc951c9767e376155d9c6fee9789b009ce82ae47276664f5c832557e *arm-wince.pe/upx-3.91.exe
c7630be0a014dbef80053609329faf5bb55ca5f3abf80df26674ca311d3943ae *arm64-linux.elf/upx-3.95 bb9e92b577ace19da295032c294063d724655cf5b97d014053c3fb05ce478884 *arm64-linux.elf/upx-3.95
4efb05939371b23037e8a0b34a35ae181d2d101afac9d3e06457d191e59a5e76 *armeb-linux.elf/upx-3.91 a3c639403fd7b2f035315773c1aa3f68cc0532cf5cd075defd34fa44c4bbbb7a *armeb-linux.elf/upx-3.91
231d9a6e570615c2688befae04ad7ca88abe9655097e352e84cf0419190355db *armeb-linux.elf/upx-3.95 3f9604a69a945d86b93f2182ee82f754881331c7ef566d0cd4dc36d7acfa1aa0 *armeb-linux.elf/upx-3.95
9df0142609a0a61595c500f1b9b40efab6d8c179f83068a5f4507df9a9c66d18 *i386-dos32.djgpp2.coff/upx-3.91.exe e6518528d60861e37cb8429376628a7f3d1d5fc90f0933facd70b4e9e0b50709 *i386-dos32.djgpp2.coff/upx-3.91.exe
6bdf60b30d916a9b706c7c2563907758994350b372351d7e9b1fa6427d75a01a *i386-dos32.djgpp2.coff/upx-3.95.exe 53280a22c34ee1733007ccf858e1f5416c0f7043a4361799087e19a4b2a7eaf4 *i386-dos32.djgpp2.coff/upx-3.95.exe
a96cc162e2a2ce59c9199534ce3c067096b655ea426b8c1ce9c4d27f282481ef *i386-linux.elf/upx-3.91 a51ce8993b3577fc2ee45b52174aaadc66c2f90ff53a0148ed096a65d99d24a2 *i386-linux.elf/upx-3.91
25540046329ed7bb0b071a6686d301f5cd8d3722407088514a88044a7caddc3b *i386-linux.elf/upx-3.95 d018260f04d1efc2b46c8b7ff5b132358e58cb062c158b08a7179fbb561b0e48 *i386-linux.elf/upx-3.95
93a6093dac3cb679e85900bfd60d7cf26319958245d4dc92425856c742aa95af *i386-win32.pe/upx-3.91.exe 121e4acc3fbad4954cb2d2b957d229b042beaf4b68749c4f85ebfc60fcc80d43 *i386-win32.pe/upx-3.91.exe
e1cb547f4c11a58b245de0bb71e9fbedffa4d9c6f97a57ce679abbae71e0c0b9 *i386-win32.pe/upx-3.95.exe d604523130da29af35705d9008098ae8b4bb9e7d4743357674470252dd68b8d3 *i386-win32.pe/upx-3.95.exe
31ba49ef577fb0031130e00198b69afec95ff9cc90806ab04d607be0627d0d1a *m68k-atari.tos/upx-3.91.ttp 4d26f0be2b6b6c4802515a7f0dfd97998c6d23e696ae6c0393c9ac0893885a9b *m68k-atari.tos/upx-3.91.ttp
69d27ee81743163b3bd9a7a9721abec70606ee38716c72410dc82bf826e508ee *mips-linux.elf/upx-3.95 4d3b0c7b4dabb5a7a193a0a2899f086f5dfc555106188131389678ecc137378a *mips-linux.elf/upx-3.95
6ee9682486076ea670bdfa95c7b6dd98d0274e970f7dcc7bdabda8d07558abf5 *mipsel-linux.elf/upx-3.91 be2e9fb66c087f37b58f203b406b618526296dd8c9c53e73bb622740f1e377ba *mipsel-linux.elf/upx-3.91
b817e57dca45c26d93d2f293d77bf0a9ffa2a4232141d9e4f1a20b369c0b3bbb *mipsel-linux.elf/upx-3.95 9da821fac44f787875727cf001ca33ed87e02c5fe477f0ebb965c5e0eb62c26c *mipsel-linux.elf/upx-3.95
99337dd36736e46e2ae90fcb6990746577a135d4b465e69f7f421a218e245657 *powerpc-linux.elf/upx-3.91 98d7c0214663ae47f59244a90aabbb72a798a4ad0c74ce79d448013f5cad6893 *powerpc-linux.elf/upx-3.91
c1b63b66351e224cc53e33086daafefdeaf3c91a37b68426b08d2c709727f214 *powerpc-linux.elf/upx-3.95 c58266817c4e38982c66e4b75e0002c6e7a51710864f930987b8670ee121ee0b *powerpc-linux.elf/upx-3.95
9e28a8e6eb94549defc2a842ca24bc7a7496f581237378a118a0ee1792598ee1 *powerpc64le-linux.elf/upx-3.95 7fecab59271c9d4596bd79978e112a5fea72e33bd7c53c1985d187009d807724 *powerpc64le-linux.elf/upx-3.95
" "
expected_sha256sums__t150_compress_ucl_2_all_filters="\ expected_sha256sums__t150_compress_ucl_2_all_filters="\
7b164c03af75a33c19dfa45767e9f44a754fd2fecd56239609fff37244030593 *amd64-linux.elf/upx-3.91 977380191b474f5a7fa78e8015a279bfaa77626bc56d83185fec8761531b3029 *amd64-linux.elf/upx-3.91
f591bf4b34d2bdab707506ca9e7b2822b0d9bfa1dfd542b96512fcdfe18c77d3 *amd64-linux.elf/upx-3.95 4f94c9bee7a2f7deed245dc767c215654a41373be978123c3f1ef9074454c59d *amd64-linux.elf/upx-3.95
a80f6756fb9acb5ac4be3f0609c37042922c769a285eca34734eb62547ce4479 *amd64-win64.pe/upx-3.95.exe 00aa338efc865f720a901afb1c19064cf137abb71d361be9b19192b0ff8a9479 *amd64-win64.pe/upx-3.95.exe
2c249c4fd65bc53376984bfbe352d7732f49d7c601dd01773a6034c127a03416 *arm-linux.elf/upx-3.95 c1908a58fcc23a9a964f2cd5f76f805a7cc9ca39480d129c6bdb8db30033840b *arm-linux.elf/upx-3.95
f640a43f3e12d092a4a8e9f34d89cc02ca85d382b80e1efdeec4ecffb09aa680 *arm-wince.pe/upx-3.91.exe 78ffa99aa69e2f66f864dce88e787e3b1c0c056009e0f863986d65aabd186107 *arm-wince.pe/upx-3.91.exe
8d5df9081689113edd3cdd357535aa35e45df4339ad37479d496cbd6e873f38f *arm64-linux.elf/upx-3.95 245c6bb22ae2b39671503244329f1e4498277b06d600447ad81c7d41ebc872d6 *arm64-linux.elf/upx-3.95
0756666adb390b4330cf3f50eee92f73cc1d0afdbcecedd7cdf94fad29bf2c71 *armeb-linux.elf/upx-3.91 9e359728cdb9bf6ea21a864b2c9da56809eda27d6b88828b85ab815311bf77b6 *armeb-linux.elf/upx-3.91
7b8156540b234aec8f6bc4db8dcd9841afd0be1385d55b07bb6f918594dcde9d *armeb-linux.elf/upx-3.95 86edb5959b5cabad270d7c77e750bc710424b92cfb2ebaeedf3ba403382f4e93 *armeb-linux.elf/upx-3.95
23cc97a192c76ce849d17f5a902d178ed10918007b9667913395095db285b546 *i386-dos32.djgpp2.coff/upx-3.91.exe b65db2766ffdd45657a07edd57426c55acce2a73a1e3559ab43903ae77574131 *i386-dos32.djgpp2.coff/upx-3.91.exe
66ec810d94684cfa71980a1812ec158b4485b897aac52fa4617e097d69e4d10f *i386-dos32.djgpp2.coff/upx-3.95.exe e827d64700b14e8c19de2882e66d0df0fca4cda0255ae41a66810e4c86583a93 *i386-dos32.djgpp2.coff/upx-3.95.exe
9b004924ddc9e028e556c882366e10ed11cc8f69792f658e07b2d19d370bb102 *i386-linux.elf/upx-3.91 c95a7ad9a5015abb1b8a163afe46b4f1529c70ca4ef9353cfb6e5c7eef60245c *i386-linux.elf/upx-3.91
74453c23dba3e6f3818faf85f2dd34669839b34679da70201e071566a32df26c *i386-linux.elf/upx-3.95 21ef65f5c756f216c0f9db9475a7514e10b8e003c30bc22416ec8156cba65252 *i386-linux.elf/upx-3.95
e91a7748c9ebafe7987127431690ae1464d8f505267a8b3837edf5f17589534b *i386-win32.pe/upx-3.91.exe 6db34f6cdc626c4857fc7b188910562909e571eed3be2116448e244ca82eaa64 *i386-win32.pe/upx-3.91.exe
ba4c9b76016431ff30f1ead43b77a6b4ecce9757a438d05647ae3efaa33288fa *i386-win32.pe/upx-3.95.exe 68a08dd3995681af594c66df4b94559e5900f0a09fcf822e3fc2522c3133ad69 *i386-win32.pe/upx-3.95.exe
e6b493dff57c763d4feb49490353dd843b15b1a1c78c000af8bf48472e11f5ae *m68k-atari.tos/upx-3.91.ttp 1546ce426b3cfe38bdea18fafadee409253d5d2b452aae5476e073b29e17bb58 *m68k-atari.tos/upx-3.91.ttp
cdf64a07ffa09aab14f5f467da334c41b5b496b77f65034bfca94b8f917b71f6 *mips-linux.elf/upx-3.95 6ecc64d1fb9fb2a675980ce939b0b8142e802e7218b8ea45f2bb82205ed9242e *mips-linux.elf/upx-3.95
cf1e80d5575766df41fcc27e08e30e3aa2b3a318a0d9014e6a7241bed8fb1d75 *mipsel-linux.elf/upx-3.91 eb3c90f8f775e70cb2cc187b7e55d66a3bb28fa760e14a17353acd1130fd122a *mipsel-linux.elf/upx-3.91
5afd8fbe8bdb25a76dd4105dbb3e4695e4332ceec9837e0609a9850cebdc524a *mipsel-linux.elf/upx-3.95 b47964dbe65e9975d6bddfbfdd321a5e6c96b6eba79b30d0f94ec4323b796991 *mipsel-linux.elf/upx-3.95
c378615d5068a5c44cb751290c732a127f88d3534d47318be41f1827a43c41b5 *powerpc-linux.elf/upx-3.91 c32a2deaa707eafaed36a4ab8fb26bb8d8c63a9743b19ad207e305553d14c7fe *powerpc-linux.elf/upx-3.91
b4b3ebd20ee61a0ed47d481e7333cef42d1a23f832c5463aff6df640d5265e65 *powerpc-linux.elf/upx-3.95 c4dbfbd0f5021d50f1addc68273f20b49204bf26ae8c8896a0aacc7d2c5a2d47 *powerpc-linux.elf/upx-3.95
0283de59bd2bf8f9dc11e1b5ad69d666bfc7a2b2168585ae3874f758eb271336 *powerpc64le-linux.elf/upx-3.95 bb96ea8a29500893b729dad4afe90b09186641c32c42a70a3d2380a771f896d9 *powerpc64le-linux.elf/upx-3.95
" "
expected_sha256sums__t160_compress_all_methods_1_no_filter="\ expected_sha256sums__t160_compress_all_methods_1_no_filter="\
d2ebb0a3e77b766446b0076008c63e910b3286b72ba7c4cce03782f36c0c7396 *amd64-linux.elf/upx-3.91 de00c3bcb56d78c3fd1d1e633b3f64b884b3611abc305b9e79f4f14385178418 *amd64-linux.elf/upx-3.91
3de94645a9b15b723b21da216e26577f8e28d4d296ceb5b68eacf5ea4040525c *amd64-linux.elf/upx-3.95 eb5aea4d780711dd59e3f86d34a49f16d3669acc6569292bf9ea445d406c5c80 *amd64-linux.elf/upx-3.95
4106f280f30fff3c39fe72b10cf450cc514d3aa9e6769255f54606c4c09bf646 *amd64-win64.pe/upx-3.95.exe 2fae12ccc55eeac6c05ff2c6b27539c66816080647283ac2e1b22576242b6bb5 *amd64-win64.pe/upx-3.95.exe
db5838a8816241e57f3271ee217cbd99b80d2c5ec15f9c71e0b1da1cced372a3 *arm-linux.elf/upx-3.95 14120b8348172a08cd7651184941820ed1c69b7a8d859e375390eee529f5c94e *arm-linux.elf/upx-3.95
97a78c7aef6ab3eeb2807893c4edfb529565e36b27f9982456276dde46e34d90 *arm-wince.pe/upx-3.91.exe a6690508c1acdaa07ce97feec0f330182c24206d8e9133949d2a42fccc1cbf27 *arm-wince.pe/upx-3.91.exe
50c4a83017a143e386f8e8c4f1dc73827b059ffc4a94586ab949edd19f27d4b3 *arm64-linux.elf/upx-3.95 4f30adcd3d047fad15344bf6cf3cf4f91cfbacbb121af889df8634fa4c888247 *arm64-linux.elf/upx-3.95
dbf432c12845fe8cebb131995cd57cc637dee8e21e8b083ed05052a2839373d8 *armeb-linux.elf/upx-3.91 f85f0a70b024a050999d476420b9db88206e340b2ffff3781c491b538ae03e37 *armeb-linux.elf/upx-3.91
751ecfef4f02003f127d7dffe9fdf12af1a449bf4546e8a6dbc86d8885441746 *armeb-linux.elf/upx-3.95 e1b2dc75427212dc268c6921aa2059adf5709b21f230432a4725b16e1c64b238 *armeb-linux.elf/upx-3.95
da261516dc443ac3a9dfbe9e3353313042b72e8c1fa3f7c17bf32e0ff4221a12 *i386-dos32.djgpp2.coff/upx-3.91.exe fcf64cfce9e9762e03740d2bf9e2e86d873ade1b6f4a68eb07625f516426810d *i386-dos32.djgpp2.coff/upx-3.91.exe
a4eaa51e14b7bdecff560e4ed209888cda0fde955693a7005aca67361181c561 *i386-dos32.djgpp2.coff/upx-3.95.exe 9188a6f911b79fb8629880836b2f5787eb4d938872ba4f1a64c93e70cde9f428 *i386-dos32.djgpp2.coff/upx-3.95.exe
48c1959184334c5eeaddad5b2141103a0a5863a3c22f068d6d977e2fb0ed1711 *i386-linux.elf/upx-3.91 8369ff8112aeb55a1684ce0ec16e13e6bc524b734557b49b292f9aae60edccb6 *i386-linux.elf/upx-3.91
eeb2cf342f9dbb87440bd4aec0b81ea3218b300124f6348758ea4bf100318ec9 *i386-linux.elf/upx-3.95 c4e16cc1a64db618d9038ea9ba6032b7fe5aac05c0d7731b91373094a6a0f6e4 *i386-linux.elf/upx-3.95
28c742067136d6023720208131a5052553cae9cd5fa1b86ffc9d7b1338ab6466 *i386-win32.pe/upx-3.91.exe b21cf7756542b3bab5f4a59d4036cd3176e297dceb744dec96ac365be6568dcd *i386-win32.pe/upx-3.91.exe
11646ac069761715b45a78c0ad769ca69f3b2e22ff70a7068bcda7118bfc82fd *i386-win32.pe/upx-3.95.exe b1bc0d360918d51ca7b7f32f5083845e4566c7fa7a425d0451f4b10f227d1eac *i386-win32.pe/upx-3.95.exe
0e442a98a0e90716945ffe9addf9cb7079686e3cc0f968c5e557b52a36fe6ac8 *m68k-atari.tos/upx-3.91.ttp c40af5d1ba0531abb92587cbcbe604d4f562b685d6e7bbb40ec4d879fddf1267 *m68k-atari.tos/upx-3.91.ttp
71abe63b1bfe35d8ff9bbaab18dcf41881a94f7bcd12bd0c010205ecbee94f33 *mips-linux.elf/upx-3.95 0865d2f1d65e2693d801b3c28d64910a009707be65598772df655c640469a4e5 *mips-linux.elf/upx-3.95
acc0e3322b4f22aa8e5a79962cf92b1a8ad203755dfe5bab6d2a668d274e4aab *mipsel-linux.elf/upx-3.91 4cf108686c2419c6d82eecb2473a6d0ca0a0b47096cc01ea2b55113f84762cc7 *mipsel-linux.elf/upx-3.91
e875572d1be9999b9292122d2094ae54142b268d7fda4ab12544507aaf673fe3 *mipsel-linux.elf/upx-3.95 0a90a99e0ebb1e9c86e0bdf6a3eec6ca116e65b235ba1ee9029694b84cadc438 *mipsel-linux.elf/upx-3.95
62414bff8849020ea0e93c10595fbe10e30c5effa87d25fa8b67c77bc810ccb7 *powerpc-linux.elf/upx-3.91 4d8f85d254b1fd87bebe2fd732afd6214c98b869cda17ff0c4c566358446038a *powerpc-linux.elf/upx-3.91
5c59c4dc481c71a9b02dd39f8ac6e3aec24f6ca2864ad3ff1c7cc54ab567af9e *powerpc-linux.elf/upx-3.95 bbc6179756637db10b636d7383226cb1d685866e8e9191069107725365b42f38 *powerpc-linux.elf/upx-3.95
71863da15c4bd482c7ad6123895b555db86610b3cc35e7ab99897d7c9dbfcc9a *powerpc64le-linux.elf/upx-3.95 52d7db1d6d6611d4a064c036b57044fd93d4c5762452be07188ee2ff6b1e42bc *powerpc64le-linux.elf/upx-3.95
" "
expected_sha256sums__t170_compress_all_methods_no_lzma_5_no_filter="\ expected_sha256sums__t170_compress_all_methods_no_lzma_5_no_filter="\
6880572cb1b05e8b43af2cc0a56937ad4dc3fb32260092a1649164155b5e39de *amd64-linux.elf/upx-3.91 ee887f19ee6a5d5f0a0ce7116a41570e106c10bc0bb25acf7eb3ee254c1ed560 *amd64-linux.elf/upx-3.91
d6133ca17edfc370015f37182f5a6531830cefc688c127dbe0d45a7212838f0f *amd64-linux.elf/upx-3.95 9bd019e6442b219825f19082a20e4e73c49b24a4dee39e9e2cf0fc907ecdb46f *amd64-linux.elf/upx-3.95
027c3eb340c77f31bbc39bc05fb5ba56c2fc33529c445c288b6af26031172442 *amd64-win64.pe/upx-3.95.exe 382fe4b3e4f575322b746d7d45e4553ba3cf47cb4351b9900508fb52a00118ad *amd64-win64.pe/upx-3.95.exe
7b9ef1fd569242b03ca8b4c6dabf880271cb3755cd00c08d15a77dc00bc05f83 *arm-linux.elf/upx-3.95 ae71103c2e105099ab345a648abf109b9aec3039137c90af30710dd4a4b51736 *arm-linux.elf/upx-3.95
bbeb21e516bf50e7d35cffb364337c6f157a31ddcacc3d43a2b2dfda8b8da3be *arm-wince.pe/upx-3.91.exe 9150f49be3fcb03a5f23b209e5db443c9b96fa4d8e20d3730195f9eafff5d8e8 *arm-wince.pe/upx-3.91.exe
d8314cfd96fc2c9d83db69ea9746fdf5653fd3a6476f271d6c244976ab7ac9ff *arm64-linux.elf/upx-3.95 100d9cee849b7996cbde2dc82df766e5104ae030055ae9b286c53b60e9e51405 *arm64-linux.elf/upx-3.95
40c5647b8dbbc287e5686d1dc81e5adf8c68d35438039edac1f201b7f939977c *armeb-linux.elf/upx-3.91 43ded21db5b7b8355bc371e39cd3b1be05e91635e3cb6d64f9a8aea16127e157 *armeb-linux.elf/upx-3.91
047f325e6b0d3c1b0179b9574441957a64601ea67c55d53cf29dc830e34d7578 *armeb-linux.elf/upx-3.95 b0ac3a36871630af80bb9b6ba94604b3ebc1fe05fdb6d095a7c461916fb3d231 *armeb-linux.elf/upx-3.95
a1b89d28adae9b26d34d701acac3a32106fce77a380322ee0cbe4a852d692ce6 *i386-dos32.djgpp2.coff/upx-3.91.exe 36b6a947567386e325f1d3ff84a55ecbd37687e3264cfb0a57aa5e3be5ff85f9 *i386-dos32.djgpp2.coff/upx-3.91.exe
fd05d0899b87dd4019c10a01d04228aca83203b801c0f5ecd8c25c225a9ab9af *i386-dos32.djgpp2.coff/upx-3.95.exe ad02fcac751563d49cb0711d818231c1030bad9ef2b12fd54e60e2bc6510e9d6 *i386-dos32.djgpp2.coff/upx-3.95.exe
58fa03662e605039f73ade85c00f8bc630623e6b10b304379b1c374f4a4330a1 *i386-linux.elf/upx-3.91 d1b4e2c81a0baf4ad273dd96722783e9219e69049a78d536757f39761a7cfe8b *i386-linux.elf/upx-3.91
87d151c5e091586add28d63e08369692836db3cd1988edbf216a21370e01f0b5 *i386-linux.elf/upx-3.95 6e509d556ccd2af102d43924bd4eb1e9bed9d557e44387769032df4ede525f0d *i386-linux.elf/upx-3.95
4e8bf3046e35facf27e060277c7e577ea367d05f531ccee950c34c6e3a151d66 *i386-win32.pe/upx-3.91.exe 2138186fb26cc7983ec4a4ead290573f2e8226fea4a0b9b6d668d86fb21d1573 *i386-win32.pe/upx-3.91.exe
8f1209d612991ac464f534206b6ce5999c6e689213fc468b289dd990309c312b *i386-win32.pe/upx-3.95.exe 5f286eaf28bab252a0f4f069b7b88910b9ce62327c4d15837b91ce65e4f9030e *i386-win32.pe/upx-3.95.exe
6e7513be318b8e4ce2bb48a23bd47f0961ef745fd7f1e25d4439435334e62264 *m68k-atari.tos/upx-3.91.ttp 0ab25c2cd8cf53a31323464080991344479998f45fd9b215caba003f96e9e11c *m68k-atari.tos/upx-3.91.ttp
ea1abe9b33a31c5e27896eabf62a7a22640e91f03af336fc22a64366af196d8f *mips-linux.elf/upx-3.95 ba14b6b4e846d29bd4211fbcdb2a641f55f8a5700806af64c52182736b757f46 *mips-linux.elf/upx-3.95
f8ee354abac9eeb83c2d3a9101b35181bebbc2d9e9253960b7ccf96b6670d711 *mipsel-linux.elf/upx-3.91 40c23e16bfe68ec0a59f9651ac747db1e81f07deabc4c22a732e40e03e2b1100 *mipsel-linux.elf/upx-3.91
cfb11a2da4f598ad20f29a248ac8e28d45dea0a47984d47d075e24e63237ca07 *mipsel-linux.elf/upx-3.95 7d353d8381c3401c3c9765fa6091c634791ae9b7338ca5b769f63c38f8f418e7 *mipsel-linux.elf/upx-3.95
541188bdf23b4bf9513a6775ba186cf3d1cdf6a61a0c15177eb4111a51978397 *powerpc-linux.elf/upx-3.91 b43bd16efb19081fe0945948231486cdd1b1157d193ab7cbbd470594f46c57ca *powerpc-linux.elf/upx-3.91
cc98a7992d9fee0af3a32c0408213198f8d2d407a44ae25d228057dfce0ef3dc *powerpc-linux.elf/upx-3.95 7a8a24fa57d17f99b11133a0822a5e499681d09695525b80f8c61d90d06c4ac8 *powerpc-linux.elf/upx-3.95
20409135c1b03e9f2dcf50266db27a6b7a0259cc073d2bc47b4264c64342bf8c *powerpc64le-linux.elf/upx-3.95 0339ffc1d99f5b5ad12e8492b6a9dc707f705a120494a6bc453fb8617808d10a *powerpc64le-linux.elf/upx-3.95
" "
########## end .sha256sums.recreate ########## end .sha256sums.recreate
+39 -33
View File
@@ -3,17 +3,21 @@
set -e; set -o pipefail set -e; set -o pipefail
argv0=$0; argv0abs=$(readlink -fn "$argv0"); argv0dir=$(dirname "$argv0abs") argv0=$0; argv0abs=$(readlink -fn "$argv0"); argv0dir=$(dirname "$argv0abs")
#
# Copyright (C) Markus Franz Xaver Johannes Oberhumer
#
# very first version of the upx-testsuite; requires: # very first version of the upx-testsuite; requires:
# $upx_exe (required, but with convenience fallback "./upx") # $upx_exe (required, but with convenience fallback "./upx")
# $upx_testsuite_SRCDIR (required, but with convenience fallback) # $upx_testsuite_SRCDIR (required, but with convenience fallback)
# $upx_testsuite_BUILDDIR (optional) # $upx_testsuite_BUILDDIR (optional)
# #
# optional settings: # optional settings:
# $upx_exe_runner (e.g. "qemu-x86_64 -cpu Westmere" or "valgrind") # $upx_exe_runner (e.g. "qemu-x86_64 -cpu Nehalem" or "valgrind")
# $UPX_TESTSUITE_VERBOSE # $UPX_TESTSUITE_VERBOSE
# $UPX_TESTSUITE_LEVEL # $UPX_TESTSUITE_LEVEL
# #
# see https://github.com/upx/upx-testsuite.git # see https://github.com/upx/upx-testsuite.git
#
#*********************************************************************** #***********************************************************************
# init & checks # init & checks
@@ -25,21 +29,25 @@ 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 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 upx_exe=$(readlink -fn "$upx_exe") # make absolute
[[ -f $upx_exe ]] || exit 1 [[ -f $upx_exe ]] || exit 1
upx_run=()
# set emu and run_upx
emu=()
if [[ -n $upx_exe_runner ]]; then if [[ -n $upx_exe_runner ]]; then
# usage examples: # usage examples:
# export upx_exe_runner="qemu-x86_64 -cpu Westmere" # export upx_exe_runner="qemu-x86_64 -cpu Nehalem"
# export upx_exe_runner="valgrind --leak-check=no --error-exitcode=1 --quiet" # export upx_exe_runner="valgrind --leak-check=no --error-exitcode=1 --quiet"
# export upx_exe_runner="wine" # export upx_exe_runner="wine"
IFS=' ' read -r -a upx_run <<< "$upx_exe_runner" # split at spaces into array IFS=' ' read -r -a emu <<< "$upx_exe_runner" # split at spaces into array
elif [[ -n $CMAKE_CROSSCOMPILING_EMULATOR ]]; then
IFS=';' read -r -a emu <<< "$CMAKE_CROSSCOMPILING_EMULATOR" # split at semicolons into array
fi fi
upx_run+=( "$upx_exe" ) run_upx=( "${emu[@]}" "$upx_exe" )
echo "upx_run='${upx_run[*]}'" echo "run_upx='${run_upx[*]}'"
# upx_run check, part1 # run_upx sanity check
if ! "${upx_run[@]}" --version-short >/dev/null; then echo "UPX-ERROR: FATAL: upx --version-short FAILED"; exit 1; fi if ! "${run_upx[@]}" --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 ! "${run_upx[@]}" -L >/dev/null 2>&1; then echo "UPX-ERROR: FATAL: upx -L FAILED"; exit 1; fi
if ! "${upx_run[@]}" --help >/dev/null; then echo "UPX-ERROR: FATAL: upx --help FAILED"; exit 1; fi if ! "${run_upx[@]}" --help >/dev/null; then echo "UPX-ERROR: FATAL: upx --help FAILED"; exit 1; fi
# upx_testsuite_SRCDIR # upx_testsuite_SRCDIR
if [[ -z $upx_testsuite_SRCDIR ]]; then if [[ -z $upx_testsuite_SRCDIR ]]; then
@@ -68,19 +76,30 @@ fi
mkdir -p "$upx_testsuite_BUILDDIR" || exit 1 mkdir -p "$upx_testsuite_BUILDDIR" || exit 1
upx_testsuite_BUILDDIR=$(readlink -fn "$upx_testsuite_BUILDDIR") # make absolute upx_testsuite_BUILDDIR=$(readlink -fn "$upx_testsuite_BUILDDIR") # make absolute
[[ -d $upx_testsuite_BUILDDIR ]] || exit 1 [[ -d $upx_testsuite_BUILDDIR ]] || exit 1
cd / && cd "$upx_testsuite_BUILDDIR" || exit 1 cd / && cd "$upx_testsuite_BUILDDIR" || exit 1
: > ./.mfxnobackup : > ./.mfxnobackup
# upx_run check, part2 # run_upx sanity check after "cd"
if ! "${upx_run[@]}" --version-short >/dev/null; then if ! "${run_upx[@]}" --version-short >/dev/null; then
echo "UPX-ERROR: FATAL: upx --version-short FAILED" 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 "please make sure that \$upx_exe contains ABSOLUTE file paths and can be run from any directory"
echo "INFO: upx_run='${upx_run[*]}'" echo "INFO: run_upx='${run_upx[*]}'"
exit 1 exit 1
fi 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 #***********************************************************************
# 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_DISABLE=1 # already checked above
case $UPX_TESTSUITE_LEVEL in case $UPX_TESTSUITE_LEVEL in
[0-8]) ;; [0-8]) ;;
@@ -91,19 +110,6 @@ if [[ $UPX_TESTSUITE_LEVEL == 0 ]]; then
exit 0 exit 0
fi 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 rm -rf ./testsuite_1
mkdir testsuite_1 || exit 1 mkdir testsuite_1 || exit 1
cd testsuite_1 || exit 1 cd testsuite_1 || exit 1
@@ -115,11 +121,11 @@ cd testsuite_1 || exit 1
run_upx() { run_upx() {
local ec=0 local ec=0
if [[ $UPX_TESTSUITE_VERBOSE == 1 ]]; then if [[ $UPX_TESTSUITE_VERBOSE == 1 ]]; then
echo "LOG: '${upx_run[*]}' $*" echo "LOG: '${run_upx[*]}' $*"
fi fi
"${upx_run[@]}" "$@" || ec=$? "${run_upx[@]}" "$@" || ec=$?
if [[ $ec != 0 ]]; then if [[ $ec != 0 ]]; then
echo "FATAL: '${upx_run[*]}' $*" echo "FATAL: '${run_upx[*]}' $*"
echo " (exit code was $ec)" echo " (exit code was $ec)"
exit 42 exit 42
fi fi
@@ -313,7 +319,7 @@ ls -l "$upx_exe"
if command -v file >/dev/null; then if command -v file >/dev/null; then
file "$upx_exe" || true file "$upx_exe" || true
fi fi
echo "upx_run='${upx_run[*]}'" echo "run_upx='${run_upx[*]}'"
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} counts:" echo ".sha256sums.{expected,current} counts:"
+41
View File
@@ -0,0 +1,41 @@
#
# valgrind suppressions for musl libc
# Copyright (C) Markus Franz Xaver Johannes Oberhumer
#
# musl malloc
{
musl-malloc-enframe
Memcheck:Cond
fun:enframe
}
# these are only needed for older musl versions
{
musl-malloc-mal0_clear
Memcheck:Cond
fun:mal0_clear
fun:calloc
}
{
musl-string-memchr
Memcheck:Cond
fun:memchr
}
{
musl-string-stpcpy
Memcheck:Cond
fun:stpcpy
}
{
musl-string-strchrnul
Memcheck:Cond
fun:strchrnul
}
{
musl-string-strlen
Memcheck:Cond
fun:strlen
}
+49 -46
View File
@@ -3,9 +3,8 @@
# Copyright (C) Markus Franz Xaver Johannes Oberhumer # Copyright (C) Markus Franz Xaver Johannes Oberhumer
# #
# NOTE: this Makefile is deprecated - please directly use the CMake build # NOTE: this Makefile is intended for developers - please use
# instead. And see the top-level Makefile for some pre-defined CMake # the top-level Makefile instead
# build configurations.
ifndef srcdir ifndef srcdir
srcdir := $(patsubst %/,%,$(dir $(lastword $(MAKEFILE_LIST)))) srcdir := $(patsubst %/,%,$(dir $(lastword $(MAKEFILE_LIST))))
@@ -14,38 +13,32 @@ ifndef top_srcdir
top_srcdir := $(srcdir)/.. top_srcdir := $(srcdir)/..
endif endif
# #***********************************************************************
# redirect to top-level CMake build # redirect to top-level Makefile
# #***********************************************************************
# NOTE that top-level Makefile .DEFAULT_GOAL is build/release # NOTE that the top-level Makefile .DEFAULT_GOAL is build/release
.DEFAULT_GOAL = build/debug .DEFAULT_GOAL = build/all
build/debug: $(top_srcdir)/build/debug/upx
build/release: $(top_srcdir)/build/release/upx
.NOTPARALLEL: # because the actual builds use "cmake --parallel" .NOTPARALLEL: # because the actual builds use "cmake --parallel"
.PHONY: PHONY .PHONY: PHONY
.SECONDEXPANSION: .SECONDEXPANSION:
.SUFFIXES: .SUFFIXES:
# shortcuts (all => debug + release) build/debug build/release build/all: PHONY; $(MAKE) -C $(top_srcdir) $@
debug: build/debug build/debug+test build/release+test build/all+test: PHONY; $(MAKE) -C $(top_srcdir) $@
release: build/release # shortcuts
all build/all: build/debug build/release debug release all: PHONY; $(MAKE) -C $(top_srcdir) $@
debug+test release+test all+test: PHONY; $(MAKE) -C $(top_srcdir) $@
$(top_srcdir)/build/debug/upx: PHONY test: $$(patsubst %+test,%,$$(.DEFAULT_GOAL))+test PHONY
$(MAKE) -C $(top_srcdir) build/debug
$(top_srcdir)/build/release/upx: PHONY
$(MAKE) -C $(top_srcdir) build/release
# #***********************************************************************
# "make run-testsuite" # make run-testsuite
# see https://github.com/upx/upx-testsuite.git # git clone 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; you can override by setting "upx_testsuite_SRCDIR"
# you also can override upx_testsuite_SRCDIR
ifndef upx_testsuite_SRCDIR ifndef upx_testsuite_SRCDIR
# search standard locations below $(top_srcdir) # search standard locations below $(top_srcdir)
ifneq ($(wildcard $(top_srcdir)/../upx--upx-testsuite.git/files/packed/.),) ifneq ($(wildcard $(top_srcdir)/../upx--upx-testsuite.git/files/packed/.),)
@@ -59,47 +52,57 @@ endif
# run the UPX testsuite # run the UPX testsuite
# The expected (old) checksums are in $(top_srcdir)/misc/testsuite/upx_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-upx-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)/misc/testsuite/upx_testsuite_1.sh),) ifneq ($(wildcard $(top_srcdir)/misc/testsuite/upx_testsuite_1.sh),)
run-testsuite: run-testsuite-release run-testsuite: run-testsuite-release PHONY
run-testsuite-all: run-testsuite-debug run-testsuite-release PHONY
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-upx-testsuite run-testsuite-debug: export upx_testsuite_BUILDDIR := ./tmp-upx-testsuite-debug
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: build/debug PHONY
time -p bash $(top_srcdir)/misc/testsuite/upx_testsuite_1.sh time -p bash $(top_srcdir)/misc/testsuite/upx_testsuite_1.sh
run-testsuite-release: export upx_testsuite_BUILDDIR := ./tmp-upx-testsuite-release
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: build/release PHONY
time -p bash $(top_srcdir)/misc/testsuite/upx_testsuite_1.sh time -p bash $(top_srcdir)/misc/testsuite/upx_testsuite_1.sh
endif endif
endif endif
# #***********************************************************************
# "make check-whitespace" # make check-whitespace
# #***********************************************************************
ifneq ($(wildcard /usr/bin/env),) # needs bash, perl, xargs, etc. ifneq ($(wildcard /usr/bin/env),) # need Unix utils like bash, perl, sed, xargs, etc.
CHECK_WHITESPACE = $(top_srcdir)/misc/scripts/check_whitespace.sh $(top_srcdir)
CHECK_WHITESPACE = bash $(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 = bash $(top_srcdir)/misc/scripts/check_whitespace_git.sh $(top_srcdir)
endif endif
check-whitespace: PHONY; $(CHECK_WHITESPACE) check-whitespace: PHONY; $(CHECK_WHITESPACE)
endif
# endif # /usr/bin/env
# "make clang-format"
# #***********************************************************************
# make clang-format
#***********************************************************************
# automatically format some C++ source code files # automatically format some C++ source code files
ifneq ($(wildcard /usr/bin/env),)
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 stub/%.h CLANG_FORMAT_EXCLUDE_FILES += stub/%.h util/miniacc.h
CLANG_FORMAT_EXCLUDE_FILES += p_elf.h p_elf_enum.h p_lx_% p_mach% p_unix% p_vmlin% CLANG_FORMAT_EXCLUDE_FILES += p_lx_% p_mach% p_unix% p_vmlin%
CLANG_FORMAT_FILES := $(sort $(wildcard *.[ch]* ../maint/src/*.[ch]* */*.[ch]*)) CLANG_FORMAT_FILES := $(sort $(wildcard *.[ch]* ../maint/src/*.[ch]* */*.[ch]*))
CLANG_FORMAT_FILES := $(filter-out $(CLANG_FORMAT_EXCLUDE_FILES),$(CLANG_FORMAT_FILES)) CLANG_FORMAT_FILES += $(sort $(wildcard stub/tools/*/*.[ch]*))
clang-format: PHONY $(CLANG_FORMAT_FILES) CLANG_FORMAT_FILES += $(sort $(wildcard ../misc/cmake/try_compile/*.[ch]*))
CLANG_FORMAT_FILES := $(sort $(filter-out $(CLANG_FORMAT_EXCLUDE_FILES),$(CLANG_FORMAT_FILES)))
clang-format: $(CLANG_FORMAT_FILES) PHONY
@echo "running upx-clang-format" @echo "running upx-clang-format"
@$(top_srcdir)/misc/scripts/upx-clang-format.sh -i $(CLANG_FORMAT_FILES) @bash $(top_srcdir)/misc/scripts/upx-clang-format.sh -i $(CLANG_FORMAT_FILES)
endif
endif # Linux
endif # /usr/bin/env
# vim:set ts=8 sw=8 noet: # vim:set ts=8 sw=8 noet:
+101 -65
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer Copyright (C) 1996-2024 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2023 Laszlo Molnar Copyright (C) 1996-2024 Laszlo Molnar
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
@@ -47,8 +47,9 @@
// try to detect XX16 vs XX32 vs XX64 size mismatches // try to detect XX16 vs XX32 vs XX64 size mismatches
**************************************************************************/ **************************************************************************/
#if 0 // permissive version using "void *" #if !(DEBUG)
// permissive version using "void *"
#define REQUIRE_XE16 /*empty*/ #define REQUIRE_XE16 /*empty*/
#define REQUIRE_XE24 /*empty*/ #define REQUIRE_XE24 /*empty*/
#define REQUIRE_XE32 /*empty*/ #define REQUIRE_XE32 /*empty*/
@@ -68,20 +69,22 @@ struct LE16;
struct LE32; struct LE32;
struct LE64; struct LE64;
namespace bele_detail {
// Note: // Note:
// void is explicitly allowed (but there is no automatic pointer conversion because of template!) // void is explicitly allowed (but there is no automatic pointer conversion because of template!)
// char is explicitly allowed // char is explicitly allowed
// byte is explicitly allowed // byte is explicitly allowed
template <class T> template <class T>
static inline constexpr bool is_xe16_type = inline constexpr bool is_xe16_type =
upx::is_same_any_v<T, void, char, byte, upx_int16_t, upx_uint16_t, BE16, LE16>; upx::is_same_any_v<T, void, char, byte, upx_int16_t, upx_uint16_t, BE16, LE16>;
template <class T> template <class T>
static inline constexpr bool is_xe24_type = upx::is_same_any_v<T, void, char, byte>; inline constexpr bool is_xe24_type = upx::is_same_any_v<T, void, char, byte>;
template <class T> template <class T>
static inline constexpr bool is_xe32_type = inline constexpr bool is_xe32_type =
upx::is_same_any_v<T, void, char, byte, upx_int32_t, upx_uint32_t, BE32, LE32>; upx::is_same_any_v<T, void, char, byte, upx_int32_t, upx_uint32_t, BE32, LE32>;
template <class T> template <class T>
static inline constexpr bool is_xe64_type = inline constexpr bool is_xe64_type =
upx::is_same_any_v<T, void, char, byte, upx_int64_t, upx_uint64_t, BE64, LE64>; upx::is_same_any_v<T, void, char, byte, upx_int64_t, upx_uint64_t, BE64, LE64>;
template <class T> template <class T>
@@ -93,10 +96,12 @@ using enable_if_xe32 = std::enable_if_t<is_xe32_type<T>, T>;
template <class T> template <class T>
using enable_if_xe64 = std::enable_if_t<is_xe64_type<T>, T>; using enable_if_xe64 = std::enable_if_t<is_xe64_type<T>, T>;
#define REQUIRE_XE16 template <class XE16, class = enable_if_xe16<XE16> > } // namespace bele_detail
#define REQUIRE_XE24 template <class XE24, class = enable_if_xe24<XE24> >
#define REQUIRE_XE32 template <class XE32, class = enable_if_xe32<XE32> > #define REQUIRE_XE16 template <class XE16, class = bele_detail::enable_if_xe16<XE16> >
#define REQUIRE_XE64 template <class XE64, class = enable_if_xe64<XE64> > #define REQUIRE_XE24 template <class XE24, class = bele_detail::enable_if_xe24<XE24> >
#define REQUIRE_XE32 template <class XE32, class = bele_detail::enable_if_xe32<XE32> >
#define REQUIRE_XE64 template <class XE64, class = bele_detail::enable_if_xe64<XE64> >
#endif // permissive version #endif // permissive version
@@ -152,11 +157,15 @@ static forceinline void set_ne64(XE64 *p, upx_uint64_t vv) noexcept {
ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(long) == 4) ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(long) == 4)
// unfortunately *not* constexpr with current MSVC // unfortunately *not* constexpr with current MSVC
static forceinline unsigned bswap16(unsigned v) noexcept { static forceinline /*constexpr*/ unsigned bswap16(unsigned v) noexcept {
return (unsigned) _byteswap_ulong(v << 16); return (unsigned) _byteswap_ulong(v << 16);
} }
static forceinline unsigned bswap32(unsigned v) noexcept { return (unsigned) _byteswap_ulong(v); } static forceinline /*constexpr*/ unsigned bswap32(unsigned v) noexcept {
static forceinline upx_uint64_t bswap64(upx_uint64_t v) noexcept { return _byteswap_uint64(v); } return (unsigned) _byteswap_ulong(v);
}
static forceinline /*constexpr*/ upx_uint64_t bswap64(upx_uint64_t v) noexcept {
return _byteswap_uint64(v);
}
#else #else
@@ -266,21 +275,27 @@ inline void set_le24(XE24 *p, unsigned v) noexcept {
b[2] = ACC_ICONV(byte, (v >> 16) & 0xff); b[2] = ACC_ICONV(byte, (v >> 16) & 0xff);
} }
inline unsigned get_le26(const void *p) noexcept { return get_le32(p) & 0x03ffffff; } REQUIRE_XE32
inline unsigned get_le19_5(const void *p) noexcept { return (get_le32(p) >> 5) & 0x0007ffff; } inline unsigned get_le26(const XE32 *p) noexcept { return get_le32(p) & 0x03ffffff; }
inline unsigned get_le14_5(const void *p) noexcept { return (get_le32(p) >> 5) & 0x00003fff; } REQUIRE_XE32
inline unsigned get_le19_5(const XE32 *p) noexcept { return (get_le32(p) >> 5) & 0x0007ffff; }
REQUIRE_XE32
inline unsigned get_le14_5(const XE32 *p) noexcept { return (get_le32(p) >> 5) & 0x00003fff; }
inline void set_le26(void *p, unsigned v) noexcept { REQUIRE_XE32
inline void set_le26(XE32 *p, unsigned v) noexcept {
// preserve the top 6 bits // preserve the top 6 bits
// set_le32(p, (get_le32(p) & 0xfc000000) | (v & 0x03ffffff)); // set_le32(p, (get_le32(p) & 0xfc000000) | (v & 0x03ffffff));
// 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)));
} }
inline void set_le19_5(void *p, unsigned v) noexcept { REQUIRE_XE32
inline void set_le19_5(XE32 *p, unsigned v) noexcept {
set_le32(p, (get_le32(p) & 0xff00001f) | ((v & 0x0007ffff) << 5)); set_le32(p, (get_le32(p) & 0xff00001f) | ((v & 0x0007ffff) << 5));
} }
inline void set_le14_5(void *p, unsigned v) noexcept { REQUIRE_XE32
inline void set_le14_5(XE32 *p, unsigned v) noexcept {
set_le32(p, (get_le32(p) & 0xfff8001f) | ((v & 0x00003fff) << 5)); set_le32(p, (get_le32(p) & 0xfff8001f) | ((v & 0x00003fff) << 5));
} }
@@ -289,17 +304,21 @@ inline void set_le14_5(void *p, unsigned v) noexcept {
**************************************************************************/ **************************************************************************/
static forceinline constexpr int sign_extend(unsigned v, unsigned bits) noexcept { static forceinline constexpr int sign_extend(unsigned v, unsigned bits) noexcept {
#if (ACC_ARCH_M68K) // no barrel shifter
const unsigned sign_bit = 1u << (bits - 1); const unsigned sign_bit = 1u << (bits - 1);
v &= sign_bit | (sign_bit - 1); return ACC_ICAST(int, (v & (sign_bit - 1)) - (v & sign_bit));
v |= 0u - (v & sign_bit); #else
return ACC_ICAST(int, v); return ACC_ICAST(int, v << (32 - bits)) >> (32 - bits);
#endif
} }
static forceinline constexpr upx_int64_t sign_extend(upx_uint64_t v, unsigned bits) noexcept { static forceinline constexpr upx_int64_t sign_extend(upx_uint64_t v, unsigned bits) noexcept {
#if (ACC_ARCH_M68K) // no barrel shifter
const upx_uint64_t sign_bit = 1ull << (bits - 1); const upx_uint64_t sign_bit = 1ull << (bits - 1);
v &= sign_bit | (sign_bit - 1); return ACC_ICAST(upx_int64_t, (v & (sign_bit - 1)) - (v & sign_bit));
v |= 0ull - (v & sign_bit); #else
return ACC_ICAST(upx_int64_t, v); return ACC_ICAST(upx_int64_t, v << (64 - bits)) >> (64 - bits);
#endif
} }
REQUIRE_XE16 REQUIRE_XE16
@@ -714,10 +733,27 @@ T *operator+(T *ptr, const LE64 &v) noexcept DELETED_FUNCTION;
template <class T> template <class T>
T *operator-(T *ptr, const LE64 &v) noexcept DELETED_FUNCTION; T *operator-(T *ptr, const LE64 &v) noexcept DELETED_FUNCTION;
#if !ALLOW_INT_PLUS_MEMBUFFER
template <class T>
T *operator+(const BE16 &v, T *ptr) noexcept DELETED_FUNCTION;
template <class T>
T *operator+(const BE32 &v, T *ptr) noexcept DELETED_FUNCTION;
template <class T>
T *operator+(const LE16 &v, T *ptr) noexcept DELETED_FUNCTION;
template <class T>
T *operator+(const LE32 &v, T *ptr) noexcept DELETED_FUNCTION;
#endif // ALLOW_INT_PLUS_MEMBUFFER
template <class T>
T *operator+(const BE64 &v, T *ptr) noexcept DELETED_FUNCTION;
template <class T>
T *operator+(const LE64 &v, T *ptr) noexcept DELETED_FUNCTION;
/************************************************************************* /*************************************************************************
// global overloads // global overloads
**************************************************************************/ **************************************************************************/
// TODO later: move these to upx namespace in util/cxxlib.h; see conf.h
inline unsigned ALIGN_DOWN(unsigned a, const BE32 &b) { return ALIGN_DOWN(a, unsigned(b)); } inline unsigned ALIGN_DOWN(unsigned a, const BE32 &b) { return ALIGN_DOWN(a, unsigned(b)); }
inline unsigned ALIGN_DOWN(const BE32 &a, unsigned b) { return ALIGN_DOWN(unsigned(a), b); } inline unsigned ALIGN_DOWN(const BE32 &a, unsigned b) { return ALIGN_DOWN(unsigned(a), b); }
inline unsigned ALIGN_UP(unsigned a, const BE32 &b) { return ALIGN_UP(a, unsigned(b)); } inline unsigned ALIGN_UP(unsigned a, const BE32 &b) { return ALIGN_UP(a, unsigned(b)); }
@@ -728,7 +764,7 @@ inline unsigned ALIGN_DOWN(const LE32 &a, unsigned b) { return ALIGN_DOWN(unsign
inline unsigned ALIGN_UP(unsigned a, const LE32 &b) { return ALIGN_UP(a, unsigned(b)); } inline unsigned ALIGN_UP(unsigned a, const LE32 &b) { return ALIGN_UP(a, unsigned(b)); }
inline unsigned ALIGN_UP(const LE32 &a, unsigned b) { return ALIGN_UP(unsigned(a), b); } inline unsigned ALIGN_UP(const LE32 &a, unsigned b) { return ALIGN_UP(unsigned(a), b); }
// TODO: introduce upx::umax() and upx::umin() // TODO later: introduce upx::umax() and upx::umin()
inline unsigned UPX_MAX(unsigned a, const BE16 &b) { return UPX_MAX(a, unsigned(b)); } inline unsigned UPX_MAX(unsigned a, const BE16 &b) { return UPX_MAX(a, unsigned(b)); }
inline unsigned UPX_MAX(const BE16 &a, unsigned b) { return UPX_MAX(unsigned(a), b); } inline unsigned UPX_MAX(const BE16 &a, unsigned b) { return UPX_MAX(unsigned(a), b); }
inline unsigned UPX_MIN(unsigned a, const BE16 &b) { return UPX_MIN(a, unsigned(b)); } inline unsigned UPX_MIN(unsigned a, const BE16 &b) { return UPX_MIN(a, unsigned(b)); }
@@ -753,6 +789,44 @@ inline unsigned UPX_MIN(const LE32 &a, unsigned b) { return UPX_MIN(unsigned(a),
// misc support // misc support
**************************************************************************/ **************************************************************************/
// for use with qsort()
extern "C" {
int __acc_cdecl_qsort be16_compare(const void *, const void *);
int __acc_cdecl_qsort be24_compare(const void *, const void *);
int __acc_cdecl_qsort be32_compare(const void *, const void *);
int __acc_cdecl_qsort be64_compare(const void *, const void *);
int __acc_cdecl_qsort le16_compare(const void *, const void *);
int __acc_cdecl_qsort le24_compare(const void *, const void *);
int __acc_cdecl_qsort le32_compare(const void *, const void *);
int __acc_cdecl_qsort le64_compare(const void *, const void *);
int __acc_cdecl_qsort be16_compare_signed(const void *, const void *);
int __acc_cdecl_qsort be24_compare_signed(const void *, const void *);
int __acc_cdecl_qsort be32_compare_signed(const void *, const void *);
int __acc_cdecl_qsort be64_compare_signed(const void *, const void *);
int __acc_cdecl_qsort le16_compare_signed(const void *, const void *);
int __acc_cdecl_qsort le24_compare_signed(const void *, const void *);
int __acc_cdecl_qsort le32_compare_signed(const void *, const void *);
int __acc_cdecl_qsort le64_compare_signed(const void *, const void *);
} // extern "C"
// <type_traits> upx_is_integral; see conf.h
#define TT_UPX_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_UPX_IS_INTEGRAL(BE16);
TT_UPX_IS_INTEGRAL(BE32);
TT_UPX_IS_INTEGRAL(BE64);
TT_UPX_IS_INTEGRAL(LE16);
TT_UPX_IS_INTEGRAL(LE32);
TT_UPX_IS_INTEGRAL(LE64);
#undef TT_UPX_IS_INTEGRAL
// native types // native types
#if (ACC_ABI_BIG_ENDIAN) #if (ACC_ABI_BIG_ENDIAN)
typedef BE16 NE16; typedef BE16 NE16;
@@ -776,44 +850,6 @@ typedef LE64 NE64;
#define ne64_compare_signed le64_compare_signed #define ne64_compare_signed le64_compare_signed
#endif #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()
extern "C" {
int __acc_cdecl_qsort be16_compare(const void *, const void *);
int __acc_cdecl_qsort be24_compare(const void *, const void *);
int __acc_cdecl_qsort be32_compare(const void *, const void *);
int __acc_cdecl_qsort be64_compare(const void *, const void *);
int __acc_cdecl_qsort le16_compare(const void *, const void *);
int __acc_cdecl_qsort le24_compare(const void *, const void *);
int __acc_cdecl_qsort le32_compare(const void *, const void *);
int __acc_cdecl_qsort le64_compare(const void *, const void *);
int __acc_cdecl_qsort be16_compare_signed(const void *, const void *);
int __acc_cdecl_qsort be24_compare_signed(const void *, const void *);
int __acc_cdecl_qsort be32_compare_signed(const void *, const void *);
int __acc_cdecl_qsort be64_compare_signed(const void *, const void *);
int __acc_cdecl_qsort le16_compare_signed(const void *, const void *);
int __acc_cdecl_qsort le24_compare_signed(const void *, const void *);
int __acc_cdecl_qsort le32_compare_signed(const void *, const void *);
int __acc_cdecl_qsort le64_compare_signed(const void *, const void *);
} // extern "C"
/************************************************************************* /*************************************************************************
// Provide namespaces and classes to abstract endianness policies. // Provide namespaces and classes to abstract endianness policies.
// //
+19 -25
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer Copyright (C) 1996-2024 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2023 Laszlo Molnar Copyright (C) 1996-2024 Laszlo Molnar
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
@@ -34,11 +34,13 @@
#if defined(BELE_CTP) #if defined(BELE_CTP)
// CTP - Compile-Time Polymorphism (templates) // CTP - Compile-Time Polymorphism (templates)
#define V static inline #define V static inline
#define VV static forceinline_constexpr
#define S static int __acc_cdecl_qsort #define S static int __acc_cdecl_qsort
#define C noexcept #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 VV virtual
#define S virtual int #define S virtual int
#define C const noexcept #define C const noexcept
#else #else
@@ -79,12 +81,9 @@ struct AbstractPolicy {
private: private:
// disable copy and move // disable copy and move
AbstractPolicy(const AbstractPolicy &) DELETED_FUNCTION; UPX_CXX_DISABLE_COPY_MOVE(AbstractPolicy)
AbstractPolicy &operator=(const AbstractPolicy &) DELETED_FUNCTION;
AbstractPolicy(AbstractPolicy &&) noexcept DELETED_FUNCTION;
AbstractPolicy &operator=(AbstractPolicy &&) noexcept DELETED_FUNCTION;
// disable dynamic allocation // disable dynamic allocation
ACC_CXX_DISABLE_NEW_DELETE UPX_CXX_DISABLE_NEW_DELETE(AbstractPolicy)
}; };
#endif #endif
@@ -93,9 +92,9 @@ private:
#define C const noexcept override #define C const noexcept override
#endif #endif
struct BEPolicy struct BEPolicy final
#if defined(BELE_RTP) #if defined(BELE_RTP)
final : public AbstractPolicy : public AbstractPolicy
#endif #endif
{ {
explicit inline BEPolicy() noexcept {} explicit inline BEPolicy() noexcept {}
@@ -104,8 +103,8 @@ struct BEPolicy
#elif defined(BELE_RTP) #elif defined(BELE_RTP)
typedef N_BELE_CTP::BEPolicy CTP_Policy; typedef N_BELE_CTP::BEPolicy CTP_Policy;
#endif #endif
V bool isBE() C { return true; } VV bool isBE() C { return true; }
V bool isLE() C { return false; } VV bool isLE() C { return false; }
typedef BE16 U16; typedef BE16 U16;
typedef BE32 U32; typedef BE32 U32;
@@ -147,17 +146,14 @@ struct BEPolicy
private: private:
// disable copy and move // disable copy and move
BEPolicy(const BEPolicy &) DELETED_FUNCTION; UPX_CXX_DISABLE_COPY_MOVE(BEPolicy)
BEPolicy &operator=(const BEPolicy &) DELETED_FUNCTION;
BEPolicy(BEPolicy &&) noexcept DELETED_FUNCTION;
BEPolicy &operator=(BEPolicy &&) noexcept DELETED_FUNCTION;
// disable dynamic allocation // disable dynamic allocation
ACC_CXX_DISABLE_NEW_DELETE UPX_CXX_DISABLE_NEW_DELETE(BEPolicy)
}; };
struct LEPolicy struct LEPolicy final
#if defined(BELE_RTP) #if defined(BELE_RTP)
final : public AbstractPolicy : public AbstractPolicy
#endif #endif
{ {
explicit inline LEPolicy() noexcept {} explicit inline LEPolicy() noexcept {}
@@ -166,8 +162,8 @@ struct LEPolicy
#elif defined(BELE_RTP) #elif defined(BELE_RTP)
typedef N_BELE_CTP::LEPolicy CTP_Policy; typedef N_BELE_CTP::LEPolicy CTP_Policy;
#endif #endif
V bool isBE() C { return false; } VV bool isBE() C { return false; }
V bool isLE() C { return true; } VV bool isLE() C { return true; }
typedef LE16 U16; typedef LE16 U16;
typedef LE32 U32; typedef LE32 U32;
@@ -209,12 +205,9 @@ struct LEPolicy
private: private:
// disable copy and move // disable copy and move
LEPolicy(const LEPolicy &) DELETED_FUNCTION; UPX_CXX_DISABLE_COPY_MOVE(LEPolicy)
LEPolicy &operator=(const LEPolicy &) DELETED_FUNCTION;
LEPolicy(LEPolicy &&) noexcept DELETED_FUNCTION;
LEPolicy &operator=(LEPolicy &&) noexcept DELETED_FUNCTION;
// disable dynamic allocation // disable dynamic allocation
ACC_CXX_DISABLE_NEW_DELETE UPX_CXX_DISABLE_NEW_DELETE(LEPolicy)
}; };
// Native Endianness policy (aka host policy) // Native Endianness policy (aka host policy)
@@ -229,6 +222,7 @@ typedef LEPolicy HostPolicy;
#endif #endif
#undef V #undef V
#undef VV
#undef S #undef S
#undef C #undef C
+220 -37
View File
@@ -2,7 +2,7 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer Copyright (C) 1996-2024 Markus Franz Xaver Johannes Oberhumer
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
@@ -24,6 +24,11 @@
<markus@oberhumer.com> <markus@oberhumer.com>
*/ */
// doctest checks, and various tests to catch toolchain/qemu/sanitizer/valgrind/wine/etc
// problems; grown historically
#include "../util/system_headers.h"
#include <cmath> // std::isinf std::isnan
#include "../conf.h" #include "../conf.h"
/************************************************************************* /*************************************************************************
@@ -42,10 +47,7 @@ int upx_doctest_check(int argc, char **argv) {
UNUSED(argv); UNUSED(argv);
return 0; return 0;
#else #else
const char *e = getenv("UPX_DEBUG_DOCTEST_DISABLE"); if (is_envvar_true("UPX_DEBUG_DOCTEST_DISABLE", "UPX_DEBUG_DISABLE_DOCTEST"))
if (!e)
e = getenv("UPX_DEBUG_DISABLE_DOCTEST"); // allow alternate spelling
if (e && e[0] && strcmp(e, "0") != 0)
return 0; return 0;
bool minimal = true; // don't show summary bool minimal = true; // don't show summary
bool duration = false; // don't show timings bool duration = false; // don't show timings
@@ -54,7 +56,7 @@ int upx_doctest_check(int argc, char **argv) {
// default for debug builds: do show the [doctest] summary // default for debug builds: do show the [doctest] summary
minimal = false; minimal = false;
#endif #endif
e = getenv("UPX_DEBUG_DOCTEST_VERBOSE"); const char *e = upx_getenv("UPX_DEBUG_DOCTEST_VERBOSE");
if (e && e[0]) { if (e && e[0]) {
if (strcmp(e, "0") == 0) { if (strcmp(e, "0") == 0) {
minimal = true; minimal = true;
@@ -76,7 +78,7 @@ int upx_doctest_check(int argc, char **argv) {
context.setOption("dt-duration", true); context.setOption("dt-duration", true);
if (success) if (success)
context.setOption("dt-success", true); context.setOption("dt-success", true);
// this requires that main_get_options() understands "--dt-XXX" options // this requires that main_get_options() understands/ignores doctest "--dt-XXX" options
if (argc > 0 && argv != nullptr) if (argc > 0 && argv != nullptr)
context.applyCommandLine(argc, argv); context.applyCommandLine(argc, argv);
int r = context.run(); int r = context.run();
@@ -125,6 +127,8 @@ ACC_COMPILE_TIME_ASSERT_HEADER(sign_extend(0u + 257, 8) == 1)
ACC_COMPILE_TIME_ASSERT_HEADER(sign_extend(0u + 383, 8) == 127) ACC_COMPILE_TIME_ASSERT_HEADER(sign_extend(0u + 383, 8) == 127)
ACC_COMPILE_TIME_ASSERT_HEADER(sign_extend(0u + 384, 8) == -128) ACC_COMPILE_TIME_ASSERT_HEADER(sign_extend(0u + 384, 8) == -128)
ACC_COMPILE_TIME_ASSERT_HEADER(sign_extend(0u + 511, 8) == -1) ACC_COMPILE_TIME_ASSERT_HEADER(sign_extend(0u + 511, 8) == -1)
ACC_COMPILE_TIME_ASSERT_HEADER(sign_extend(0ull + 0, 1) == 0)
ACC_COMPILE_TIME_ASSERT_HEADER(sign_extend(0ull + 1, 1) == -1)
ACC_COMPILE_TIME_ASSERT_HEADER(CHAR_BIT == 8) ACC_COMPILE_TIME_ASSERT_HEADER(CHAR_BIT == 8)
#if 0 // does not work with MSVC #if 0 // does not work with MSVC
@@ -321,6 +325,17 @@ struct TestIntegerWrap {
static inline bool neg_eq(const T x) noexcept { return T(0) - x == x; } static inline bool neg_eq(const T x) noexcept { return T(0) - x == x; }
}; };
//
// basic exception handling checks to early catch toolchain/qemu/wine/etc problems
//
struct TestDestructor {
explicit TestDestructor(int *pp, int vv) noexcept : p(pp), v(vv) {}
virtual noinline ~TestDestructor() noexcept { *p = (*p << 2) + v; }
int *p;
int v;
};
static noinline void throwSomeValue(int x) may_throw { static noinline void throwSomeValue(int x) may_throw {
if (x < 0) if (x < 0)
throw int(x); throw int(x);
@@ -328,40 +343,129 @@ static noinline void throwSomeValue(int x) may_throw {
throw size_t(x); throw size_t(x);
} }
static noinline void check_exceptions_2(void (*func)(int), int *x) may_throw {
TestDestructor d(x, *x);
func(*x);
}
static noinline void check_basic_cxx_exception_handling(void (*func)(int)) noexcept { static noinline void check_basic_cxx_exception_handling(void (*func)(int)) noexcept {
bool cxx_exception_handling_works = false; bool cxx_exception_handling_works = false;
int x = 1;
try { try {
func(42); TestDestructor d(&x, 3);
check_exceptions_2(func, &x);
} catch (const size_t &e) { } catch (const size_t &e) {
if (e == 42) if (e == 1 && x == 23)
cxx_exception_handling_works = true; cxx_exception_handling_works = true;
} catch (...) { } catch (...) {
} }
assert_noexcept(cxx_exception_handling_works); assert_noexcept(cxx_exception_handling_works);
} }
//
// basic floating point checks to early catch toolchain/qemu/wine/etc problems
//
static noinline float i64_f32_add_div(upx_int64_t a, upx_int64_t b) { return (a + b) / 1000000.0f; }
static noinline float u64_f32_add_div(upx_uint64_t a, upx_uint64_t b) {
return (a + b) / 1000000.0f;
}
static noinline float i64_f32_sub_div(upx_int64_t a, upx_int64_t b) { return (a - b) / 1000000.0f; }
static noinline float u64_f32_sub_div(upx_uint64_t a, upx_uint64_t b) {
return (a - b) / 1000000.0f;
}
static noinline double i64_f64_add_div(upx_int64_t a, upx_int64_t b) { return (a + b) / 1000000.0; }
static noinline double u64_f64_add_div(upx_uint64_t a, upx_uint64_t b) {
return (a + b) / 1000000.0;
}
static noinline double i64_f64_sub_div(upx_int64_t a, upx_int64_t b) { return (a - b) / 1000000.0; }
static noinline double u64_f64_sub_div(upx_uint64_t a, upx_uint64_t b) {
return (a - b) / 1000000.0;
}
template <class Int, class Float>
struct TestFloat {
static constexpr Int X = 1000000;
static noinline Float div(Int a, Float f) { return a / f; }
static noinline Float add_div(Int a, Int b, Float f) { return Float(a + b) / f; }
static noinline Float sub_div(Int a, Int b, Float f) { return Float(a - b) / f; }
static noinline Float add_div_x(Int a, Int b) { return Float(a + b) / Float(X); }
static noinline Float sub_div_x(Int a, Int b) { return Float(a - b) / Float(X); }
static noinline void check() noexcept {
assert_noexcept(div(2 * X, Float(X)) == Float(2));
assert_noexcept(add_div(X, X, Float(X)) == Float(2));
assert_noexcept(add_div_x(X, X) == Float(2));
assert_noexcept(sub_div(3 * X, X, Float(X)) == Float(2));
assert_noexcept(sub_div_x(3 * X, X) == Float(2));
// extra debugging; floating point edge cases cause portability problems in practice
static const char envvar[] = "UPX_DEBUG_TEST_FLOAT_DIVISION_BY_ZERO";
if (is_envvar_true(envvar)) {
#if defined(__FAST_MATH__)
// warning: comparison with NaN always evaluates to false in fast floating point modes
fprintf(stderr, "upx: WARNING: ignoring %s: __FAST_MATH__\n", envvar);
#else
assert_noexcept(std::isnan(div(0, Float(0))));
assert_noexcept(std::isinf(div(1, Float(0))));
assert_noexcept(std::isinf(div(Int(-1), Float(0))));
#endif
}
}
};
static noinline void check_basic_floating_point(void) noexcept {
assert_noexcept(i64_f32_add_div(1000000, 1000000) == 2.0f);
assert_noexcept(u64_f32_add_div(1000000, 1000000) == 2.0f);
assert_noexcept(i64_f32_sub_div(3000000, 1000000) == 2.0f);
assert_noexcept(u64_f32_sub_div(3000000, 1000000) == 2.0f);
assert_noexcept(i64_f64_add_div(1000000, 1000000) == 2.0);
assert_noexcept(u64_f64_add_div(1000000, 1000000) == 2.0);
assert_noexcept(i64_f64_sub_div(3000000, 1000000) == 2.0);
assert_noexcept(u64_f64_sub_div(3000000, 1000000) == 2.0);
TestFloat<upx_int32_t, float>::check();
TestFloat<upx_uint32_t, float>::check();
TestFloat<upx_int64_t, float>::check();
TestFloat<upx_uint64_t, float>::check();
TestFloat<upx_int32_t, double>::check();
TestFloat<upx_uint32_t, double>::check();
TestFloat<upx_int64_t, double>::check();
TestFloat<upx_uint64_t, double>::check();
}
} // 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 "../util/miniacc.h"
void upx_compiler_sanity_check(void) noexcept { void upx_compiler_sanity_check(void) noexcept {
const char *e = getenv("UPX_DEBUG_DOCTEST_DISABLE"); check_basic_floating_point();
if (!e)
e = getenv("UPX_DEBUG_DISABLE_DOCTEST"); // allow alternate spelling if (is_envvar_true("UPX_DEBUG_DOCTEST_DISABLE", "UPX_DEBUG_DISABLE_DOCTEST")) {
if (e && e[0] && strcmp(e, "0") != 0) {
// If UPX_DEBUG_DOCTEST_DISABLE is set then we don't want to throw any // If UPX_DEBUG_DOCTEST_DISABLE is set then we don't want to throw any
// exceptions in order to improve debugging experience. // exceptions in order to improve debugging experience.
} else { } else {
// check working C++ exception handling to catch toolchain/qemu/wine/etc problems // check working C++ exception handling to early catch toolchain/qemu/wine/etc problems
check_basic_cxx_exception_handling(throwSomeValue); check_basic_cxx_exception_handling(throwSomeValue);
} }
// check_basic_decltype()
{
auto a = +0;
constexpr auto b = -0;
const auto &c = -1;
COMPILE_TIME_ASSERT((std::is_same<int, decltype(a)>::value))
COMPILE_TIME_ASSERT((std::is_same<const int, decltype(b)>::value))
COMPILE_TIME_ASSERT((std::is_same<const int &, decltype(c)>::value))
UNUSED(a);
UNUSED(b);
UNUSED(c);
}
#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)
#include "../miniacc.h" #include "../util/miniacc.h"
#undef ACCCHK_ASSERT #undef ACCCHK_ASSERT
COMPILE_TIME_ASSERT(sizeof(char) == 1) COMPILE_TIME_ASSERT(sizeof(char) == 1)
@@ -400,13 +504,25 @@ void upx_compiler_sanity_check(void) noexcept {
COMPILE_TIME_ASSERT_ALIGNED1(upx_charptr_unit_type) COMPILE_TIME_ASSERT_ALIGNED1(upx_charptr_unit_type)
COMPILE_TIME_ASSERT(sizeof(*((charptr) nullptr)) == 1) COMPILE_TIME_ASSERT(sizeof(*((charptr) nullptr)) == 1)
COMPILE_TIME_ASSERT(sizeof(UPX_VERSION_STRING4) == 4 + 1) // check UPX_VERSION_xxx
assert_noexcept(strlen(UPX_VERSION_STRING4) == 4); {
COMPILE_TIME_ASSERT(sizeof(UPX_VERSION_YEAR) == 4 + 1) using upx::compile_time::mem_eq;
assert_noexcept(strlen(UPX_VERSION_YEAR) == 4); using upx::compile_time::string_len;
assert_noexcept(memcmp(UPX_VERSION_DATE_ISO, UPX_VERSION_YEAR, 4) == 0); static_assert(string_len(UPX_VERSION_STRING4) == 4);
assert_noexcept( static_assert(string_len(UPX_VERSION_YEAR) == 4);
memcmp(&UPX_VERSION_DATE[sizeof(UPX_VERSION_DATE) - 1 - 4], UPX_VERSION_YEAR, 4) == 0); static_assert(string_len(UPX_VERSION_DATE_ISO) == 10);
static_assert(string_len(UPX_VERSION_DATE) == 12 || string_len(UPX_VERSION_DATE) == 13);
static_assert(mem_eq(UPX_VERSION_STRING4, UPX_VERSION_STRING, 3));
static_assert(mem_eq(UPX_VERSION_YEAR, UPX_VERSION_DATE_ISO, 4));
static_assert(mem_eq(UPX_VERSION_YEAR, &UPX_VERSION_DATE[sizeof(UPX_VERSION_DATE) - 5], 4));
char buf[16];
constexpr long long v = UPX_VERSION_HEX;
upx_safe_snprintf(buf, sizeof(buf), "%lld.%lld.%lld", (v >> 16), (v >> 8) & 255, v & 255);
assert_noexcept(strcmp(buf, UPX_VERSION_STRING) == 0);
upx_safe_snprintf(buf, sizeof(buf), "%lld.%lld%lld", (v >> 16), (v >> 8) & 255, v & 255);
assert_noexcept(strcmp(buf, UPX_VERSION_STRING4) == 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) {
@@ -468,6 +584,38 @@ void upx_compiler_sanity_check(void) noexcept {
assert_noexcept(get_be32_signed(d) == 2138996092); assert_noexcept(get_be32_signed(d) == 2138996092);
assert_noexcept(get_be64_signed(d) == 9186918263483431288LL); assert_noexcept(get_be64_signed(d) == 9186918263483431288LL);
} }
#if DEBUG >= 1
{
for (int i = 0; i < 256; i++) {
{
const unsigned u = i;
assert_noexcept(sign_extend(u, 1) == ((i & 1) ? -1 : 0));
assert_noexcept(sign_extend(u, 2) == ((i & 2) ? -2 + (i & 1) : (i & 1)));
assert_noexcept(sign_extend(u, 3) == ((i & 4) ? -4 + (i & 3) : (i & 3)));
assert_noexcept(sign_extend(u, 4) == ((i & 8) ? -8 + (i & 7) : (i & 7)));
assert_noexcept(sign_extend(u, 5) == ((i & 16) ? -16 + (i & 15) : (i & 15)));
assert_noexcept(sign_extend(u, 6) == ((i & 32) ? -32 + (i & 31) : (i & 31)));
assert_noexcept(sign_extend(u, 7) == ((i & 64) ? -64 + (i & 63) : (i & 63)));
assert_noexcept(sign_extend(u, 8) == ((i & 128) ? -128 + (i & 127) : (i & 127)));
assert_noexcept(sign_extend(u, 32) == i);
assert_noexcept(sign_extend(0u - u, 32) == -i);
}
{
const upx_uint64_t u = i;
assert_noexcept(sign_extend(u, 1) == ((i & 1) ? -1 : 0));
assert_noexcept(sign_extend(u, 2) == ((i & 2) ? -2 + (i & 1) : (i & 1)));
assert_noexcept(sign_extend(u, 3) == ((i & 4) ? -4 + (i & 3) : (i & 3)));
assert_noexcept(sign_extend(u, 4) == ((i & 8) ? -8 + (i & 7) : (i & 7)));
assert_noexcept(sign_extend(u, 5) == ((i & 16) ? -16 + (i & 15) : (i & 15)));
assert_noexcept(sign_extend(u, 6) == ((i & 32) ? -32 + (i & 31) : (i & 31)));
assert_noexcept(sign_extend(u, 7) == ((i & 64) ? -64 + (i & 63) : (i & 63)));
assert_noexcept(sign_extend(u, 8) == ((i & 128) ? -128 + (i & 127) : (i & 127)));
assert_noexcept(sign_extend(u, 64) == i);
assert_noexcept(sign_extend(0ull - u, 64) == -i);
}
}
}
#endif
{ {
unsigned dd; unsigned dd;
void *const d = &dd; void *const d = &dd;
@@ -540,7 +688,7 @@ void upx_compiler_sanity_check(void) noexcept {
**************************************************************************/ **************************************************************************/
TEST_CASE("assert_noexcept") { TEST_CASE("assert_noexcept") {
// just to make sure that our own assert() macros don't generate any warnings // just to make sure that our own assert() macros do not trigger any compiler warnings
byte dummy = 0; byte dummy = 0;
byte *ptr1 = &dummy; byte *ptr1 = &dummy;
const byte *const ptr2 = &dummy; const byte *const ptr2 = &dummy;
@@ -562,6 +710,25 @@ TEST_CASE("acc_vget") {
CHECK_EQ(acc_vget_long(1, -1), 1); CHECK_EQ(acc_vget_long(1, -1), 1);
CHECK_EQ(acc_vget_acc_int64l_t(2, 1), 2); CHECK_EQ(acc_vget_acc_int64l_t(2, 1), 2);
CHECK_EQ(acc_vget_acc_hvoid_p(nullptr, 0), nullptr); CHECK_EQ(acc_vget_acc_hvoid_p(nullptr, 0), nullptr);
if (acc_vget_int(1, 0) > 0)
return;
assert_noexcept(false);
}
TEST_CASE("ptr_invalidate_and_poison") {
int *ip = nullptr; // initialized
ptr_invalidate_and_poison(ip);
assert(ip != nullptr);
(void) ip;
double *dp; // not initialized
ptr_invalidate_and_poison(dp);
assert(dp != nullptr);
(void) dp;
}
TEST_CASE("upx_getenv") {
CHECK_EQ(upx_getenv(nullptr), nullptr);
CHECK_EQ(upx_getenv(""), nullptr);
} }
TEST_CASE("working -fno-strict-aliasing") { TEST_CASE("working -fno-strict-aliasing") {
@@ -624,13 +791,23 @@ TEST_CASE("libc snprintf") {
CHECK_EQ(strcmp(buf, "-6.0.0.0.0.0.0.0.6.ffffffffffffffff"), 0); CHECK_EQ(strcmp(buf, "-6.0.0.0.0.0.0.0.6.ffffffffffffffff"), 0);
snprintf(buf, sizeof(buf), "%d.%d.%d.%d.%d.%d.%d.%d.%d.%#jx", -7, 0, 0, 0, 0, 0, 0, 0, 7, um); snprintf(buf, sizeof(buf), "%d.%d.%d.%d.%d.%d.%d.%d.%d.%#jx", -7, 0, 0, 0, 0, 0, 0, 0, 7, um);
CHECK_EQ(strcmp(buf, "-7.0.0.0.0.0.0.0.7.0xffffffffffffffff"), 0); CHECK_EQ(strcmp(buf, "-7.0.0.0.0.0.0.0.7.0xffffffffffffffff"), 0);
snprintf(buf, sizeof(buf), "%#X %#lx %#llx", 26u, 27ul, 28ull);
CHECK_EQ(strcmp(buf, "0X1A 0x1b 0x1c"), 0);
snprintf(buf, sizeof(buf), "%#06x %#06lX %#06llx", 26u, 27ul, 28ull);
CHECK_EQ(strcmp(buf, "0x001a 0X001B 0x001c"), 0);
snprintf(buf, sizeof(buf), "%#6x %#6lx %#6llX", 26u, 27ul, 28ull);
CHECK_EQ(strcmp(buf, " 0x1a 0x1b 0X1C"), 0);
snprintf(buf, sizeof(buf), "%#-6X %#-6lx %#-6llx", 26u, 27ul, 28ull);
CHECK_EQ(strcmp(buf, "0X1A 0x1b 0x1c "), 0);
} }
#if 0
TEST_CASE("libc qsort") { TEST_CASE("libc qsort") {
// runtime check that libc qsort() never compares identical objects // runtime check that libc qsort() never compares identical objects
// UPDATE: while only poor implementations of qsort() would actually do // UPDATE: while only poor implementations of qsort() would actually do this
// this, it is probably allowed by the standard; so skip this test case // it is probably allowed by the standard, so skip this test by default
if (!is_envvar_true("UPX_DEBUG_TEST_LIBC_QSORT"))
return;
struct Elem { struct Elem {
upx_uint16_t id; upx_uint16_t id;
upx_uint16_t value; upx_uint16_t value;
@@ -640,35 +817,41 @@ TEST_CASE("libc qsort") {
assert_noexcept(a->id != b->id); // check not IDENTICAL assert_noexcept(a->id != b->id); // check not IDENTICAL
return a->value < b->value ? -1 : (a->value == b->value ? 0 : 1); return a->value < b->value ? -1 : (a->value == b->value ? 0 : 1);
} }
static bool check_sort(upx_sort_func_t sort, Elem *e, size_t n) { static noinline bool check_sort(upx_sort_func_t sort, Elem *e, size_t n, bool is_stable) {
upx_uint32_t x = 5381 + n + ((upx_uintptr_t) e & 0xff); upx_uint32_t x = 5381 + (upx_rand() & 255);
for (size_t i = 0; i < n; i++) { for (size_t i = 0; i < n; i++) {
e[i].id = (upx_uint16_t) i; e[i].id = (upx_uint16_t) i;
x = x * 33 + 1 + (i & 255); x = x * 33 + 1 + (i & 255);
e[i].value = (upx_uint16_t) x; e[i].value = (upx_uint16_t) ((x >> 4) & 15);
} }
sort(e, n, sizeof(Elem), Elem::compare); sort(e, n, sizeof(Elem), Elem::compare);
for (size_t i = 1; i < n; i++) // verify
for (size_t i = 1; i < n; i++) {
if very_unlikely (e[i - 1].value > e[i].value) if very_unlikely (e[i - 1].value > e[i].value)
return false; return false;
if (is_stable)
if very_unlikely (e[i - 1].value == e[i].value && e[i - 1].id >= e[i].id)
return false;
}
return true; return true;
} }
}; };
constexpr size_t N = 4096; constexpr size_t N = 4096;
Elem e[N]; Elem e[N];
for (size_t n = 0; n <= N; n = 2 * n + 1) { for (size_t n = 0; n <= N; n = 2 * n + 1) {
// CHECK(Elem::check_sort(qsort, e, n)); // libc qsort() // system sort functions
CHECK(Elem::check_sort(upx_gnomesort, e, n)); CHECK(Elem::check_sort(::qsort, e, n, false)); // libc qsort()
CHECK(Elem::check_sort(upx_shellsort_memswap, e, n));
CHECK(Elem::check_sort(upx_shellsort_memcpy, e, n));
#if UPX_CONFIG_USE_STABLE_SORT #if UPX_CONFIG_USE_STABLE_SORT
upx_sort_func_t wrap_stable_sort = [](void *aa, size_t nn, size_t, upx_compare_func_t cc) { upx_sort_func_t wrap_stable_sort = [](void *aa, size_t nn, size_t, upx_compare_func_t cc) {
upx_std_stable_sort<sizeof(Elem)>(aa, nn, cc); upx_std_stable_sort<sizeof(Elem)>(aa, nn, cc);
}; };
CHECK(Elem::check_sort(wrap_stable_sort, e, n)); CHECK(Elem::check_sort(wrap_stable_sort, e, n, true)); // std::stable_sort()
#endif #endif
// simple UPX sort functions
CHECK(Elem::check_sort(upx_gnomesort, e, n, true));
CHECK(Elem::check_sort(upx_shellsort_memswap, e, n, false));
CHECK(Elem::check_sort(upx_shellsort_memcpy, e, n, false));
} }
} }
#endif
/* vim:set ts=4 sw=4 et: */ /* vim:set ts=4 sw=4 et: */
+397 -50
View File
@@ -2,7 +2,7 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer Copyright (C) 1996-2024 Markus Franz Xaver Johannes Oberhumer
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
@@ -24,6 +24,11 @@
<markus@oberhumer.com> <markus@oberhumer.com>
*/ */
// lots of tests (and probably quite a number of redundant tests)
// modern compilers will optimize away much of this code
#include "../util/system_headers.h"
#include <vector> // std::vector
#include "../conf.h" #include "../conf.h"
/************************************************************************* /*************************************************************************
@@ -46,16 +51,32 @@ ACC_COMPILE_TIME_ASSERT_HEADER((!upx::is_same_any_v<int, char>) )
ACC_COMPILE_TIME_ASSERT_HEADER((!upx::is_same_any_v<int, char, char>) ) ACC_COMPILE_TIME_ASSERT_HEADER((!upx::is_same_any_v<int, char, char>) )
ACC_COMPILE_TIME_ASSERT_HEADER((!upx::is_same_any_v<int, char, long>) ) ACC_COMPILE_TIME_ASSERT_HEADER((!upx::is_same_any_v<int, char, long>) )
ACC_COMPILE_TIME_ASSERT_HEADER((upx::is_same_any_v<ptrdiff_t, int, long, long long>) )
ACC_COMPILE_TIME_ASSERT_HEADER(
(upx::is_same_any_v<size_t, unsigned, unsigned long, unsigned long long>) )
ACC_COMPILE_TIME_ASSERT_HEADER(
(upx::is_same_any_v<upx_uintptr_t, unsigned, unsigned long, unsigned long long>) )
ACC_COMPILE_TIME_ASSERT_HEADER(usizeof(int) == sizeof(int)) ACC_COMPILE_TIME_ASSERT_HEADER(usizeof(int) == sizeof(int))
ACC_COMPILE_TIME_ASSERT_HEADER(usizeof('a') == sizeof(char)) ACC_COMPILE_TIME_ASSERT_HEADER(usizeof('a') == sizeof(char))
ACC_COMPILE_TIME_ASSERT_HEADER(usizeof("") == 1) ACC_COMPILE_TIME_ASSERT_HEADER(usizeof("") == 1)
ACC_COMPILE_TIME_ASSERT_HEADER(usizeof("a") == 2) ACC_COMPILE_TIME_ASSERT_HEADER(usizeof("a") == 2)
ACC_COMPILE_TIME_ASSERT_HEADER(usizeof("ab") == 3)
ACC_COMPILE_TIME_ASSERT_HEADER(usizeof(L'a') == sizeof(wchar_t))
ACC_COMPILE_TIME_ASSERT_HEADER(usizeof(L"") == 1 * sizeof(wchar_t))
ACC_COMPILE_TIME_ASSERT_HEADER(usizeof(L"a") == 2 * sizeof(wchar_t))
ACC_COMPILE_TIME_ASSERT_HEADER(usizeof(L"ab") == 3 * sizeof(wchar_t))
ACC_COMPILE_TIME_ASSERT_HEADER(usizeof(0) == sizeof(int)) ACC_COMPILE_TIME_ASSERT_HEADER(usizeof(0) == sizeof(int))
ACC_COMPILE_TIME_ASSERT_HEADER(usizeof(0L) == sizeof(long)) 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(0LL) == sizeof(long long))
ACC_COMPILE_TIME_ASSERT_HEADER(usizeof(nullptr) == sizeof(void *)) 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(sizeof(0)) == sizeof(size_t))
ACC_COMPILE_TIME_ASSERT_HEADER(usizeof(usizeof(0)) == sizeof(unsigned)) ACC_COMPILE_TIME_ASSERT_HEADER(usizeof(usizeof(0)) == sizeof(unsigned))
#if 0
// works, but may trigger clang/gcc warnings "-Wunused-value"
ACC_COMPILE_TIME_ASSERT_HEADER(usizeof((1LL, 1)) == sizeof(int))
ACC_COMPILE_TIME_ASSERT_HEADER(usizeof((1, 1LL)) == sizeof(long long))
#endif
namespace compile_time = upx::compile_time; namespace compile_time = upx::compile_time;
ACC_COMPILE_TIME_ASSERT_HEADER(compile_time::string_len("") == 0) ACC_COMPILE_TIME_ASSERT_HEADER(compile_time::string_len("") == 0)
@@ -84,11 +105,298 @@ ACC_COMPILE_TIME_ASSERT_HEADER(!compile_time::string_gt("abc", "abz"))
ACC_COMPILE_TIME_ASSERT_HEADER(!compile_time::string_ge("abc", "abz")) ACC_COMPILE_TIME_ASSERT_HEADER(!compile_time::string_ge("abc", "abz"))
ACC_COMPILE_TIME_ASSERT_HEADER(compile_time::string_le("abc", "abz")) ACC_COMPILE_TIME_ASSERT_HEADER(compile_time::string_le("abc", "abz"))
ACC_COMPILE_TIME_ASSERT_HEADER(compile_time::mem_eq((const char *) nullptr, nullptr, 0))
ACC_COMPILE_TIME_ASSERT_HEADER(compile_time::mem_eq((const byte *) nullptr, nullptr, 0))
ACC_COMPILE_TIME_ASSERT_HEADER(compile_time::mem_eq("", "", 0))
ACC_COMPILE_TIME_ASSERT_HEADER(compile_time::mem_eq("abc", "abc", 3))
ACC_COMPILE_TIME_ASSERT_HEADER(!compile_time::mem_eq("abc", "abz", 3))
/*************************************************************************
//
**************************************************************************/
TEST_CASE("std::vector") {
constexpr size_t N = 16;
std::vector<int> v(N);
CHECK(v.end() - v.begin() == N);
CHECK(&v[0] == &(*(v.begin())));
// CHECK(&v[0] + N == &(*(v.end()))); // TODO later: is this legal??
// TODO later: make sure that this throws
#if defined(_LIBCPP_HARDENING_MODE_DEBUG) && \
(_LIBCPP_HARDENING_MODE == _LIBCPP_HARDENING_MODE_DEBUG)
CHECK_THROWS((void) &v[N]);
#endif
UNUSED(v);
}
/*************************************************************************
// UPX_CXX_DISABLE_xxx
**************************************************************************/
namespace {
template <class TA, class TB, int TC = 0>
struct MyType1 {
MyType1() noexcept {}
UPX_CXX_DISABLE_ADDRESS(MyType1)
UPX_CXX_DISABLE_COPY_MOVE(MyType1)
UPX_CXX_DISABLE_NEW_DELETE_NO_VIRTUAL(MyType1)
};
template <class TA, class TB, int TC = 0>
struct MyType2 {
MyType2() noexcept {}
UPX_CXX_DISABLE_COPY_MOVE(MyType2)
typedef MyType2<TA, TB, TC> Self;
UPX_CXX_DISABLE_ADDRESS(Self)
UPX_CXX_DISABLE_NEW_DELETE_NO_VIRTUAL(Self)
};
template <class TA, class TB, int TC = 0>
struct MyVType1 {
MyVType1() noexcept {}
virtual ~MyVType1() noexcept {}
UPX_CXX_DISABLE_ADDRESS(MyVType1)
UPX_CXX_DISABLE_COPY_MOVE(MyVType1)
UPX_CXX_DISABLE_NEW_DELETE(MyVType1)
};
template <class TA, class TB, int TC = 0>
struct MyVType2 {
MyVType2() noexcept {}
virtual ~MyVType2() noexcept {}
UPX_CXX_DISABLE_COPY_MOVE(MyVType2)
typedef MyVType2<TA, TB, TC> Self;
UPX_CXX_DISABLE_ADDRESS(Self)
UPX_CXX_DISABLE_NEW_DELETE(Self)
};
TEST_CASE("UPX_CXX_DISABLE_xxx") {
MyType1<char, int, 1> dummy1;
MyType2<char, int, 2> dummy2;
MyVType1<char, int, 1> vdummy1;
MyVType2<char, int, 2> vdummy2;
(void) dummy1;
(void) dummy2;
(void) vdummy1;
(void) vdummy2;
}
} // namespace
namespace test_disable_new_delete {
struct A1 {
int a;
};
struct A2 {
int a;
UPX_CXX_DISABLE_NEW_DELETE_NO_VIRTUAL(A2)
};
struct B1_A1 : public A1 {
int b;
};
struct B1_A2 : public A2 {
int b;
};
struct B2_A1 : public A1 {
int b;
UPX_CXX_DISABLE_NEW_DELETE_NO_VIRTUAL(B2_A1)
};
struct B2_A2 : public A2 {
int b;
UPX_CXX_DISABLE_NEW_DELETE_NO_VIRTUAL(B2_A2)
};
struct X1 {
virtual ~X1() noexcept {}
int x;
};
struct X2 {
virtual ~X2() noexcept {}
int x;
UPX_CXX_DISABLE_NEW_DELETE(X2)
};
struct Y1_X1 : public X1 {
int y;
};
struct Y1_X2 : public X2 {
int y;
};
struct Y2_X1 : public X1 {
int y;
UPX_CXX_DISABLE_NEW_DELETE(Y2_X1)
};
struct Y2_X2 : public X2 {
int y;
UPX_CXX_DISABLE_NEW_DELETE(Y2_X2)
};
struct Z1_X1 : public X1 {
virtual ~Z1_X1() noexcept {}
int z;
};
struct Z1_X2 : public X2 {
virtual ~Z1_X2() noexcept {}
int z;
};
struct Z2_X1 : public X1 {
virtual ~Z2_X1() noexcept {}
int z;
UPX_CXX_DISABLE_NEW_DELETE(Z2_X1)
};
struct Z2_X2 : public X2 {
virtual ~Z2_X2() noexcept {}
int z;
UPX_CXX_DISABLE_NEW_DELETE(Z2_X2)
};
} // namespace test_disable_new_delete
/************************************************************************* /*************************************************************************
// util // util
**************************************************************************/ **************************************************************************/
TEST_CASE("noncopyable") { #if WITH_THREADS
TEST_CASE("upx::ptr_std_atomic_cast") {
// pointer-size
CHECK_EQ(upx::ptr_std_atomic_cast((void **) nullptr), nullptr);
CHECK_EQ(upx::ptr_std_atomic_cast((uintptr_t *) nullptr), nullptr);
CHECK_EQ(upx::ptr_std_atomic_cast((upx_uintptr_t *) nullptr), nullptr);
#if 1
// more fundamental types
CHECK_EQ(upx::ptr_std_atomic_cast((char *) nullptr), nullptr);
CHECK_EQ(upx::ptr_std_atomic_cast((short *) nullptr), nullptr);
CHECK_EQ(upx::ptr_std_atomic_cast((int *) nullptr), nullptr);
CHECK_EQ(upx::ptr_std_atomic_cast((long *) nullptr), nullptr);
CHECK_EQ(upx::ptr_std_atomic_cast((ptrdiff_t *) nullptr), nullptr);
CHECK_EQ(upx::ptr_std_atomic_cast((size_t *) nullptr), nullptr);
CHECK_EQ(upx::ptr_std_atomic_cast((upx_int8_t *) nullptr), nullptr);
CHECK_EQ(upx::ptr_std_atomic_cast((upx_int16_t *) nullptr), nullptr);
CHECK_EQ(upx::ptr_std_atomic_cast((upx_int32_t *) nullptr), nullptr);
#endif
}
#endif
TEST_CASE("upx::atomic_exchange") {
{
upx_uintptr_t x = (upx_uintptr_t) 0 - 1;
upx_uintptr_t y = upx::atomic_exchange(&x, (upx_uintptr_t) 2);
CHECK_EQ(x, 2);
CHECK_EQ(y, (upx_uintptr_t) 0 - 1);
UNUSED(y);
}
{
const int buf[2] = {101, 202};
const int *ptr_array[2] = {&buf[0], &buf[1]};
assert_noexcept(*ptr_array[0] == 101 && *ptr_array[1] == 202);
const int *p = upx::atomic_exchange(&ptr_array[0], ptr_array[1]);
CHECK_EQ(p, buf + 0);
assert_noexcept(*ptr_array[0] == 202 && *ptr_array[1] == 202);
p = upx::atomic_exchange(&ptr_array[1], p);
CHECK_EQ(p, buf + 1);
assert_noexcept(*ptr_array[0] == 202 && *ptr_array[1] == 101);
UNUSED(p);
}
}
TEST_CASE("upx::ObjectDeleter 1") {
LE16 *o = nullptr; // object
LE32 *a = nullptr; // array
LE64 *m = nullptr; // malloc
{
auto o_deleter = upx::ObjectDeleter(&o, 1);
o = new LE16;
assert(o != nullptr);
auto a_deleter = upx::ArrayDeleter(&a, 1);
a = New(LE32, 1);
assert(a != nullptr);
auto m_deleter = upx::MallocDeleter(&m, 1);
m = (LE64 *) ::malloc(sizeof(LE64));
assert(m != nullptr);
}
assert(o == nullptr);
assert(a == nullptr);
assert(m == nullptr);
// test "const" versions
{
const auto o_deleter = upx::ObjectDeleter(&o, 1);
o = new LE16;
assert(o != nullptr);
const auto a_deleter = upx::ArrayDeleter(&a, 1);
a = New(LE32, 1);
assert(a != nullptr);
const auto m_deleter = upx::MallocDeleter(&m, 1);
m = (LE64 *) ::malloc(sizeof(LE64));
assert(m != nullptr);
}
assert(o == nullptr);
assert(a == nullptr);
assert(m == nullptr);
}
TEST_CASE("upx::ObjectDeleter 2") {
constexpr size_t N = 2;
BE16 *o[N]; // multiple objects
BE32 *a[N]; // multiple arrays
BE64 *m[N]; // multiple mallocs
{
auto o_deleter = upx::ObjectDeleter(o, 0);
auto a_deleter = upx::ArrayDeleter(a, 0);
auto m_deleter = upx::MallocDeleter(m, 0);
for (size_t i = 0; i < N; i++) {
o[i] = new BE16;
assert(o[i] != nullptr);
o_deleter.count += 1;
a[i] = New(BE32, 1 + i);
assert(a[i] != nullptr);
a_deleter.count += 1;
m[i] = (BE64 *) ::malloc(sizeof(BE64));
assert(m[i] != nullptr);
m_deleter.count += 1;
}
}
for (size_t i = 0; i < N; i++) {
assert(o[i] == nullptr);
assert(a[i] == nullptr);
assert(m[i] == nullptr);
}
}
TEST_CASE("upx::ptr_static_cast") {
// check that we do not trigger any -Wcast-align warnings
using upx::ptr_static_cast;
void *vp = nullptr;
byte *bp = nullptr;
int *ip = nullptr;
double *dp = nullptr;
assert((vp == ptr_static_cast<void *>(vp)));
assert((vp == ptr_static_cast<void *>(bp)));
assert((vp == ptr_static_cast<void *>(ip)));
assert((vp == ptr_static_cast<void *>(dp)));
assert((bp == ptr_static_cast<byte *>(vp)));
assert((bp == ptr_static_cast<byte *>(bp)));
assert((bp == ptr_static_cast<byte *>(ip)));
assert((bp == ptr_static_cast<byte *>(dp)));
assert((ip == ptr_static_cast<int *>(vp)));
assert((ip == ptr_static_cast<int *>(bp)));
assert((ip == ptr_static_cast<int *>(ip)));
assert((ip == ptr_static_cast<int *>(dp)));
assert((dp == ptr_static_cast<double *>(vp)));
assert((dp == ptr_static_cast<double *>(bp)));
assert((dp == ptr_static_cast<double *>(ip)));
assert((dp == ptr_static_cast<double *>(dp)));
const byte *bc = nullptr;
const int *ic = nullptr;
assert((bc == ptr_static_cast<byte *>(bp)));
assert((bc == ptr_static_cast<const byte *>(bc)));
assert((bc == ptr_static_cast<byte *>(ip)));
assert((bc == ptr_static_cast<const byte *>(ic)));
assert((ic == ptr_static_cast<int *>(bp)));
assert((ic == ptr_static_cast<const int *>(bc)));
assert((ic == ptr_static_cast<int *>(ip)));
assert((ic == ptr_static_cast<const int *>(ic)));
}
TEST_CASE("upx::noncopyable") {
struct Test : private upx::noncopyable { struct Test : private upx::noncopyable {
int v = 1; int v = 1;
}; };
@@ -106,13 +414,13 @@ TEST_CASE("noncopyable") {
} }
/************************************************************************* /*************************************************************************
// TriBool // TriBool checks
**************************************************************************/ **************************************************************************/
namespace { namespace {
template <class T> template <class T>
struct TestTriBool { struct TestTriBool {
static void test(bool expect_true, int x) noexcept { static noinline void test(bool expect_true) {
static_assert(std::is_class<T>::value); static_assert(std::is_class<T>::value);
static_assert(std::is_nothrow_default_constructible<T>::value); static_assert(std::is_nothrow_default_constructible<T>::value);
static_assert(std::is_nothrow_destructible<T>::value); static_assert(std::is_nothrow_destructible<T>::value);
@@ -120,12 +428,19 @@ struct TestTriBool {
static_assert(std::is_trivially_copyable<T>::value); static_assert(std::is_trivially_copyable<T>::value);
static_assert(sizeof(typename T::value_type) == sizeof(typename T::underlying_type)); static_assert(sizeof(typename T::value_type) == sizeof(typename T::underlying_type));
static_assert(alignof(typename T::value_type) == alignof(typename T::underlying_type)); static_assert(alignof(typename T::value_type) == alignof(typename T::underlying_type));
#if (ACC_ARCH_M68K && ACC_OS_TOS && ACC_CC_GNUC) && defined(__MINT__) #if defined(__m68k__) && defined(__atarist__) && defined(__GNUC__)
// broken compiler or broken ABI // broken compiler or broken ABI
#elif defined(__i386__) && defined(__GNUC__) && (__GNUC__ == 7) && !defined(__clang__)
static_assert(sizeof(T) == sizeof(typename T::underlying_type));
// i386: "long long" enum align bug/ABI problem on older compilers
static_assert(alignof(T) <= alignof(typename T::underlying_type));
#else #else
static_assert(sizeof(T) == sizeof(typename T::underlying_type)); static_assert(sizeof(T) == sizeof(typename T::underlying_type));
static_assert(alignof(T) == alignof(typename T::underlying_type)); static_assert(alignof(T) == alignof(typename T::underlying_type));
#endif #endif
static_assert(!bool(T(false)));
static_assert(bool(T(true)));
static_assert(bool(T(T::Third)) == T::is_third_true);
static_assert(T(false) == T::False); static_assert(T(false) == T::False);
static_assert(T(true) == T::True); static_assert(T(true) == T::True);
static_assert(T(T::False) == T::False); static_assert(T(T::False) == T::False);
@@ -145,63 +460,95 @@ struct TestTriBool {
static_assert(array[2].isThird()); static_assert(array[2].isThird());
static_assert(sizeof(array) == 3 * sizeof(T)); static_assert(sizeof(array) == 3 * sizeof(T));
T a; T a;
CHECK(!a); assert(a.getValue() == T::False);
CHECK(a.isStrictFalse()); assert(!a);
CHECK(!a.isStrictTrue()); assert(!bool(a));
CHECK(a.isStrictBool()); assert((!a ? true : false));
CHECK(!a.isThird()); assert(a.isStrictFalse());
assert(!a.isStrictTrue());
assert(a.isStrictBool());
assert(!a.isThird());
a = false; a = false;
CHECK(!a); assert(a.getValue() == T::False);
CHECK(a.isStrictFalse()); assert(!a);
CHECK(!a.isStrictTrue()); assert(!bool(a));
CHECK(a.isStrictBool()); assert((!a ? true : false));
CHECK(!a.isThird()); assert(a.isStrictFalse());
assert(!a.isStrictTrue());
assert(a.isStrictBool());
assert(!a.isThird());
a = true; a = true;
CHECK(a); assert(a.getValue() == T::True);
CHECK(!a.isStrictFalse()); assert(a);
CHECK(a.isStrictTrue()); assert(bool(a));
CHECK(a.isStrictBool()); assert((a ? true : false));
CHECK(!a.isThird()); assert(!a.isStrictFalse());
assert(a.isStrictTrue());
assert(a.isStrictBool());
assert(!a.isThird());
a = T::Third; a = T::Third;
if (expect_true) assert(a.getValue() == T::Third);
CHECK(a); assert(T::is_third_true == expect_true);
else if (expect_true) {
CHECK(!a); assert(a);
CHECK(!a.isStrictFalse()); assert(bool(a));
CHECK(!a.isStrictTrue()); assert((a ? true : false));
CHECK(!a.isStrictBool()); } else {
CHECK(a.isThird()); assert(!a);
a = x; assert(!bool(a));
if (expect_true) assert((!a ? true : false));
CHECK(a); }
else assert(!a.isStrictFalse());
CHECK(!a); assert(!a.isStrictTrue());
CHECK(!a.isStrictFalse()); assert(!a.isStrictBool());
CHECK(!a.isStrictTrue()); assert(a.isThird());
CHECK(!a.isStrictBool()); a = 99;
CHECK(a.isThird()); assert(a.getValue() == T::Third);
if (expect_true) {
assert(a);
assert(bool(a));
assert((a ? true : false));
assert((!a ? false : true));
} else {
assert(!a);
assert(!bool(a));
assert((a ? false : true));
assert((!a ? true : false));
}
assert(!a.isStrictFalse());
assert(!a.isStrictTrue());
assert(!a.isStrictBool());
assert(a.isThird());
mem_clear(&a); mem_clear(&a);
CHECK(a.isStrictFalse()); assert(a.isStrictFalse());
} }
}; };
} // namespace } // namespace
TEST_CASE("TriBool") { TEST_CASE("upx::TriBool") {
using upx::TriBool, upx::tribool; using upx::TriBool, upx::tribool;
//
static_assert(!tribool(false)); static_assert(!tribool(false));
static_assert(tribool(true)); static_assert(tribool(true));
static_assert(!tribool(tribool::Third)); static_assert(!tribool(tribool::Third));
TestTriBool<tribool>::test(false, -1); TestTriBool<tribool>::test(false);
// #if DEBUG || 1
TestTriBool<TriBool<upx_int8_t> >::test(false, -1); TestTriBool<TriBool<upx_int8_t> >::test(false);
TestTriBool<TriBool<upx_int64_t> >::test(false, -1); TestTriBool<TriBool<upx_uint8_t> >::test(false);
// TestTriBool<TriBool<upx_int16_t> >::test(false);
TestTriBool<TriBool<unsigned, 2> >::test(true, 2); TestTriBool<TriBool<upx_uint16_t> >::test(false);
TestTriBool<TriBool<upx_int8_t, 2> >::test(true, 2); TestTriBool<TriBool<upx_int32_t> >::test(false);
TestTriBool<TriBool<upx_uint8_t, 2> >::test(true, 2); TestTriBool<TriBool<upx_uint32_t> >::test(false);
TestTriBool<TriBool<upx_int64_t, 2> >::test(true, 2); TestTriBool<TriBool<upx_int64_t> >::test(false);
TestTriBool<TriBool<upx_uint64_t, 2> >::test(true, 2); TestTriBool<TriBool<upx_uint64_t> >::test(false);
TestTriBool<TriBool<upx_int8_t, true> >::test(true);
TestTriBool<TriBool<upx_uint8_t, true> >::test(true);
TestTriBool<TriBool<upx_int16_t, true> >::test(true);
TestTriBool<TriBool<upx_uint16_t, true> >::test(true);
TestTriBool<TriBool<upx_int32_t, true> >::test(true);
TestTriBool<TriBool<upx_uint32_t, true> >::test(true);
TestTriBool<TriBool<upx_int64_t, true> >::test(true);
TestTriBool<TriBool<upx_uint64_t, true> >::test(true);
#endif
} }
/* vim:set ts=4 sw=4 et: */ /* vim:set ts=4 sw=4 et: */
+12 -4
View File
@@ -2,7 +2,7 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer Copyright (C) 1996-2024 Markus Franz Xaver Johannes Oberhumer
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
@@ -24,6 +24,9 @@
<markus@oberhumer.com> <markus@oberhumer.com>
*/ */
#include "../util/system_defs.h"
#include "../util/system_features.h"
/************************************************************************* /*************************************************************************
// doctest support code implementation // doctest support code implementation
**************************************************************************/ **************************************************************************/
@@ -33,7 +36,10 @@
#if !defined(DOCTEST_CONFIG_DISABLE) #if !defined(DOCTEST_CONFIG_DISABLE)
#if defined(__i386__) && defined(__MSDOS__) && defined(__DJGPP__) && defined(__GNUC__) #if defined(__wasi__)
#define DOCTEST_CONFIG_NO_MULTITHREADING
#define DOCTEST_CONFIG_NO_POSIX_SIGNALS
#elif defined(__i386__) && defined(__MSDOS__) && defined(__DJGPP__) && defined(__GNUC__)
#define DOCTEST_CONFIG_NO_MULTITHREADING #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__)
@@ -43,11 +49,13 @@
#pragma GCC diagnostic ignored "-Wshadow" #pragma GCC diagnostic ignored "-Wshadow"
#endif #endif
#if !defined(UPX_DOCTEST_CONFIG_MULTITHREADING) #if !(WITH_THREADS) && !defined(UPX_DOCTEST_CONFIG_MULTITHREADING)
#ifndef DOCTEST_CONFIG_NO_MULTITHREADING
#define DOCTEST_CONFIG_NO_MULTITHREADING #define DOCTEST_CONFIG_NO_MULTITHREADING
#endif #endif
#endif
#if defined(__clang__) && defined(__FAST_MATH__) && defined(__INTEL_LLVM_COMPILER) #if defined(__FAST_MATH__) && defined(__clang__) && (__clang_major__ + 0 >= 6)
// 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
+33 -1
View File
@@ -2,7 +2,7 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer Copyright (C) 1996-2024 Markus Franz Xaver Johannes Oberhumer
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
@@ -241,6 +241,35 @@ TEST_CASE("basic xspan usage") {
} }
} }
TEST_CASE("xspan array access") {
const size_t N = 16;
char buf[N];
memset(buf, 0, sizeof(buf));
XSPAN_0_VAR(char, c0, buf, sizeof(buf));
XSPAN_P_VAR(char, cp, buf, sizeof(buf));
XSPAN_S_VAR(char, cs, buf, sizeof(buf));
for (size_t i = 0; i != N; ++i)
c0[i] += 1;
for (size_t i = 0; i != N; ++i)
cp[i] += 1;
for (size_t i = 0; i != N; ++i)
cs[i] += 1;
#if __cplusplus >= 201103L
for (auto ptr = c0; ptr != c0 + N; ++ptr)
*ptr += 1;
for (auto ptr = c0 + 0; ptr < c0 + N; ++ptr)
*ptr += 1;
for (auto ptr = cp; ptr != cp + N; ++ptr)
*ptr += 1;
for (auto ptr = cp + 0; ptr < cp + N; ++ptr)
*ptr += 1;
for (auto ptr = cs; ptr != cs + N; ++ptr)
*ptr += 1;
for (auto ptr = cs + 0; ptr < cs + N; ++ptr)
*ptr += 1;
#endif
}
/************************************************************************* /*************************************************************************
// //
**************************************************************************/ **************************************************************************/
@@ -658,6 +687,9 @@ TEST_CASE("Span subspan") {
CHECK((as + 2).subspan(0, -2)[0] == 0); CHECK((as + 2).subspan(0, -2)[0] == 0);
CHECK_THROWS(as.subspan(1, 0)[0]); CHECK_THROWS(as.subspan(1, 0)[0]);
CHECK_THROWS(as.subspan(1, 1)[-1]); CHECK_THROWS(as.subspan(1, 1)[-1]);
CHECK(as.subspan(1)[0] == 1);
CHECK(as.subspan(2)[0] == 2);
CHECK(as.subspan(3)[0] == 3);
} }
TEST_CASE("Span constness") { TEST_CASE("Span constness") {
+17 -5
View File
@@ -2,7 +2,7 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer Copyright (C) 1996-2024 Markus Franz Xaver Johannes Oberhumer
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
@@ -62,7 +62,7 @@ unsigned upx_crc32(const void *buf, unsigned len, unsigned crc)
**************************************************************************/ **************************************************************************/
int upx_compress(const upx_bytep src, unsigned src_len, upx_bytep dst, unsigned *dst_len, int upx_compress(const upx_bytep src, unsigned src_len, upx_bytep dst, unsigned *dst_len,
upx_callback_p cb, int method, int level, const upx_compress_config_t *cconf, upx_callback_t *cb, int method, int level, const upx_compress_config_t *cconf,
upx_compress_result_t *cresult) { upx_compress_result_t *cresult) {
int r = UPX_E_ERROR; int r = UPX_E_ERROR;
upx_compress_result_t cresult_buffer; upx_compress_result_t cresult_buffer;
@@ -95,6 +95,10 @@ int upx_compress(const upx_bytep src, unsigned src_len, upx_bytep dst, unsigned
const unsigned orig_dst_len = *dst_len; const unsigned orig_dst_len = *dst_len;
if (__acc_cte(false)) { if (__acc_cte(false)) {
} }
#if (WITH_BZIP2)
else if (M_IS_BZIP2(method))
r = upx_bzip2_compress(src, src_len, dst, dst_len, cb, method, level, cconf, cresult);
#endif
#if (WITH_LZMA) #if (WITH_LZMA)
else if (M_IS_LZMA(method)) else if (M_IS_LZMA(method))
r = upx_lzma_compress(src, src_len, dst, dst_len, cb, method, level, cconf, cresult); r = upx_lzma_compress(src, src_len, dst, dst_len, cb, method, level, cconf, cresult);
@@ -112,7 +116,7 @@ int upx_compress(const upx_bytep src, unsigned src_len, upx_bytep dst, unsigned
r = upx_zstd_compress(src, src_len, dst, dst_len, cb, method, level, cconf, cresult); r = upx_zstd_compress(src, src_len, dst, dst_len, cb, method, level, cconf, cresult);
#endif #endif
else { else {
throwInternalError("unknown compression method"); throwInternalError("unknown compression method %d", method);
} }
#if 1 #if 1
@@ -140,6 +144,10 @@ int upx_decompress(const upx_bytep src, unsigned src_len, upx_bytep dst, unsigne
const unsigned orig_dst_len = *dst_len; const unsigned orig_dst_len = *dst_len;
if (__acc_cte(false)) { if (__acc_cte(false)) {
} }
#if (WITH_BZIP2)
else if (M_IS_BZIP2(method))
r = upx_bzip2_decompress(src, src_len, dst, dst_len, method, cresult);
#endif
#if (WITH_LZMA) #if (WITH_LZMA)
else if (M_IS_LZMA(method)) else if (M_IS_LZMA(method))
r = upx_lzma_decompress(src, src_len, dst, dst_len, method, cresult); r = upx_lzma_decompress(src, src_len, dst, dst_len, method, cresult);
@@ -161,7 +169,7 @@ int upx_decompress(const upx_bytep src, unsigned src_len, upx_bytep dst, unsigne
r = upx_zstd_decompress(src, src_len, dst, dst_len, method, cresult); r = upx_zstd_decompress(src, src_len, dst, dst_len, method, cresult);
#endif #endif
else { else {
throwInternalError("unknown decompression method"); throwInternalError("unknown compression method %d", method);
} }
assert_noexcept(*dst_len <= orig_dst_len); assert_noexcept(*dst_len <= orig_dst_len);
@@ -187,6 +195,10 @@ int upx_test_overlap(const upx_bytep buf, const upx_bytep tbuf, unsigned src_off
const unsigned orig_dst_len = *dst_len; const unsigned orig_dst_len = *dst_len;
if (__acc_cte(false)) { if (__acc_cte(false)) {
} }
#if (WITH_BZIP2)
else if (M_IS_BZIP2(method))
r = upx_bzip2_test_overlap(buf, tbuf, src_off, src_len, dst_len, method, cresult);
#endif
#if (WITH_LZMA) #if (WITH_LZMA)
else if (M_IS_LZMA(method)) else if (M_IS_LZMA(method))
r = upx_lzma_test_overlap(buf, tbuf, src_off, src_len, dst_len, method, cresult); r = upx_lzma_test_overlap(buf, tbuf, src_off, src_len, dst_len, method, cresult);
@@ -204,7 +216,7 @@ int upx_test_overlap(const upx_bytep buf, const upx_bytep tbuf, unsigned src_off
r = upx_zstd_test_overlap(buf, tbuf, src_off, src_len, dst_len, method, cresult); r = upx_zstd_test_overlap(buf, tbuf, src_off, src_len, dst_len, method, cresult);
#endif #endif
else { else {
throwInternalError("unknown decompression method"); throwInternalError("unknown compression method %d", method);
} }
assert_noexcept(*dst_len <= orig_dst_len); assert_noexcept(*dst_len <= orig_dst_len);
+25 -25
View File
@@ -2,7 +2,7 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer Copyright (C) 1996-2024 Markus Franz Xaver Johannes Oberhumer
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
@@ -36,19 +36,19 @@
int upx_bzip2_init(void); int upx_bzip2_init(void);
const char *upx_bzip2_version_string(void); const char *upx_bzip2_version_string(void);
int upx_bzip2_compress ( const upx_bytep src, unsigned src_len, int upx_bzip2_compress ( const upx_bytep src, unsigned src_len,
upx_bytep dst, unsigned* dst_len, upx_bytep dst, unsigned *dst_len,
upx_callback_p cb, upx_callback_t *cb,
int method, int level, int method, int level,
const upx_compress_config_t *cconf, const upx_compress_config_t *cconf,
upx_compress_result_t *cresult ); upx_compress_result_t *cresult );
int upx_bzip2_decompress ( const upx_bytep src, unsigned src_len, int upx_bzip2_decompress ( const upx_bytep src, unsigned src_len,
upx_bytep dst, unsigned* dst_len, upx_bytep dst, unsigned *dst_len,
int method, int method,
const upx_compress_result_t *cresult ); const upx_compress_result_t *cresult );
int upx_bzip2_test_overlap ( const upx_bytep buf, int upx_bzip2_test_overlap ( const upx_bytep buf,
const upx_bytep tbuf, const upx_bytep tbuf,
unsigned src_off, unsigned src_len, unsigned src_off, unsigned src_len,
unsigned* dst_len, unsigned *dst_len,
int method, int method,
const upx_compress_result_t *cresult ); const upx_compress_result_t *cresult );
#endif #endif
@@ -57,19 +57,19 @@ int upx_bzip2_test_overlap ( const upx_bytep buf,
int upx_lzma_init(void); int upx_lzma_init(void);
const char *upx_lzma_version_string(void); const char *upx_lzma_version_string(void);
int upx_lzma_compress ( const upx_bytep src, unsigned src_len, int upx_lzma_compress ( const upx_bytep src, unsigned src_len,
upx_bytep dst, unsigned* dst_len, upx_bytep dst, unsigned *dst_len,
upx_callback_p cb, upx_callback_t *cb,
int method, int level, int method, int level,
const upx_compress_config_t *cconf, const upx_compress_config_t *cconf,
upx_compress_result_t *cresult ); upx_compress_result_t *cresult );
int upx_lzma_decompress ( const upx_bytep src, unsigned src_len, int upx_lzma_decompress ( const upx_bytep src, unsigned src_len,
upx_bytep dst, unsigned* dst_len, upx_bytep dst, unsigned *dst_len,
int method, int method,
const upx_compress_result_t *cresult ); const upx_compress_result_t *cresult );
int upx_lzma_test_overlap ( const upx_bytep buf, int upx_lzma_test_overlap ( const upx_bytep buf,
const upx_bytep tbuf, const upx_bytep tbuf,
unsigned src_off, unsigned src_len, unsigned src_off, unsigned src_len,
unsigned* dst_len, unsigned *dst_len,
int method, int method,
const upx_compress_result_t *cresult ); const upx_compress_result_t *cresult );
#endif #endif
@@ -78,19 +78,19 @@ int upx_lzma_test_overlap ( const upx_bytep buf,
int upx_nrv_init(void); int upx_nrv_init(void);
const char *upx_nrv_version_string(void); const char *upx_nrv_version_string(void);
int upx_nrv_compress ( const upx_bytep src, unsigned src_len, int upx_nrv_compress ( const upx_bytep src, unsigned src_len,
upx_bytep dst, unsigned* dst_len, upx_bytep dst, unsigned *dst_len,
upx_callback_p cb, upx_callback_t *cb,
int method, int level, int method, int level,
const upx_compress_config_t *cconf, const upx_compress_config_t *cconf,
upx_compress_result_t *cresult ); upx_compress_result_t *cresult );
int upx_nrv_decompress ( const upx_bytep src, unsigned src_len, int upx_nrv_decompress ( const upx_bytep src, unsigned src_len,
upx_bytep dst, unsigned* dst_len, upx_bytep dst, unsigned *dst_len,
int method, int method,
const upx_compress_result_t *cresult ); const upx_compress_result_t *cresult );
int upx_nrv_test_overlap ( const upx_bytep buf, int upx_nrv_test_overlap ( const upx_bytep buf,
const upx_bytep tbuf, const upx_bytep tbuf,
unsigned src_off, unsigned src_len, unsigned src_off, unsigned src_len,
unsigned* dst_len, unsigned *dst_len,
int method, int method,
const upx_compress_result_t *cresult ); const upx_compress_result_t *cresult );
#endif #endif
@@ -99,19 +99,19 @@ int upx_nrv_test_overlap ( const upx_bytep buf,
int upx_ucl_init(void); int upx_ucl_init(void);
const char *upx_ucl_version_string(void); const char *upx_ucl_version_string(void);
int upx_ucl_compress ( const upx_bytep src, unsigned src_len, int upx_ucl_compress ( const upx_bytep src, unsigned src_len,
upx_bytep dst, unsigned* dst_len, upx_bytep dst, unsigned *dst_len,
upx_callback_p cb, upx_callback_t *cb,
int method, int level, int method, int level,
const upx_compress_config_t *cconf, const upx_compress_config_t *cconf,
upx_compress_result_t *cresult ); upx_compress_result_t *cresult );
int upx_ucl_decompress ( const upx_bytep src, unsigned src_len, int upx_ucl_decompress ( const upx_bytep src, unsigned src_len,
upx_bytep dst, unsigned* dst_len, upx_bytep dst, unsigned *dst_len,
int method, int method,
const upx_compress_result_t *cresult ); const upx_compress_result_t *cresult );
int upx_ucl_test_overlap ( const upx_bytep buf, int upx_ucl_test_overlap ( const upx_bytep buf,
const upx_bytep tbuf, const upx_bytep tbuf,
unsigned src_off, unsigned src_len, unsigned src_off, unsigned src_len,
unsigned* dst_len, unsigned *dst_len,
int method, int method,
const upx_compress_result_t *cresult ); const upx_compress_result_t *cresult );
unsigned upx_ucl_adler32(const void *buf, unsigned len, unsigned adler); unsigned upx_ucl_adler32(const void *buf, unsigned len, unsigned adler);
@@ -122,19 +122,19 @@ unsigned upx_ucl_crc32 (const void *buf, unsigned len, unsigned crc);
int upx_zlib_init(void); int upx_zlib_init(void);
const char *upx_zlib_version_string(void); const char *upx_zlib_version_string(void);
int upx_zlib_compress ( const upx_bytep src, unsigned src_len, int upx_zlib_compress ( const upx_bytep src, unsigned src_len,
upx_bytep dst, unsigned* dst_len, upx_bytep dst, unsigned *dst_len,
upx_callback_p cb, upx_callback_t *cb,
int method, int level, int method, int level,
const upx_compress_config_t *cconf, const upx_compress_config_t *cconf,
upx_compress_result_t *cresult ); upx_compress_result_t *cresult );
int upx_zlib_decompress ( const upx_bytep src, unsigned src_len, int upx_zlib_decompress ( const upx_bytep src, unsigned src_len,
upx_bytep dst, unsigned* dst_len, upx_bytep dst, unsigned *dst_len,
int method, int method,
const upx_compress_result_t *cresult ); const upx_compress_result_t *cresult );
int upx_zlib_test_overlap ( const upx_bytep buf, int upx_zlib_test_overlap ( const upx_bytep buf,
const upx_bytep tbuf, const upx_bytep tbuf,
unsigned src_off, unsigned src_len, unsigned src_off, unsigned src_len,
unsigned* dst_len, unsigned *dst_len,
int method, int method,
const upx_compress_result_t *cresult ); const upx_compress_result_t *cresult );
unsigned upx_zlib_adler32(const void *buf, unsigned len, unsigned adler); unsigned upx_zlib_adler32(const void *buf, unsigned len, unsigned adler);
@@ -145,19 +145,19 @@ unsigned upx_zlib_crc32 (const void *buf, unsigned len, unsigned crc);
int upx_zstd_init(void); int upx_zstd_init(void);
const char *upx_zstd_version_string(void); const char *upx_zstd_version_string(void);
int upx_zstd_compress ( const upx_bytep src, unsigned src_len, int upx_zstd_compress ( const upx_bytep src, unsigned src_len,
upx_bytep dst, unsigned* dst_len, upx_bytep dst, unsigned *dst_len,
upx_callback_p cb, upx_callback_t *cb,
int method, int level, int method, int level,
const upx_compress_config_t *cconf, const upx_compress_config_t *cconf,
upx_compress_result_t *cresult ); upx_compress_result_t *cresult );
int upx_zstd_decompress ( const upx_bytep src, unsigned src_len, int upx_zstd_decompress ( const upx_bytep src, unsigned src_len,
upx_bytep dst, unsigned* dst_len, upx_bytep dst, unsigned *dst_len,
int method, int method,
const upx_compress_result_t *cresult ); const upx_compress_result_t *cresult );
int upx_zstd_test_overlap ( const upx_bytep buf, int upx_zstd_test_overlap ( const upx_bytep buf,
const upx_bytep tbuf, const upx_bytep tbuf,
unsigned src_off, unsigned src_len, unsigned src_off, unsigned src_len,
unsigned* dst_len, unsigned *dst_len,
int method, int method,
const upx_compress_result_t *cresult ); const upx_compress_result_t *cresult );
#endif #endif
+211
View File
@@ -0,0 +1,211 @@
/* compress_bzip2.cpp --
This file is part of the UPX executable compressor.
Copyright (C) 1996-2024 Markus Franz Xaver Johannes Oberhumer
All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them
and/or modify them under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of
the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; see the file COPYING.
If not, write to the Free Software Foundation, Inc.,
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
Markus F.X.J. Oberhumer
<markus@oberhumer.com>
*/
#include "../util/system_headers.h"
#if WITH_BZIP2
#include <bzip2/bzlib.h>
#endif
#include "../conf.h"
void bzip2_compress_config_t::reset() noexcept { mem_clear(this); }
#if WITH_BZIP2
#include "compress.h"
#include "../util/membuffer.h"
#if defined(BZ_NO_STDIO) || 1
// we need to supply bz_internal_error() when building with BZ_NO_STDIO
extern "C" {
extern void bz_internal_error(int);
void bz_internal_error(int errcode) { throwInternalError("bz_internal_error %d", errcode); }
}
#endif // BZ_NO_STDIO
static int convert_errno_from_bzip2(int r) {
switch (r) {
case BZ_OK:
return UPX_E_OK;
case BZ_MEM_ERROR:
return UPX_E_OUT_OF_MEMORY;
// TODO later: convert to UPX_E_INPUT_OVERRUN, UPX_E_OUTPUT_OVERRUN
default:
break;
}
return UPX_E_ERROR;
}
/*************************************************************************
//
**************************************************************************/
int upx_bzip2_compress(const upx_bytep src, unsigned src_len, upx_bytep dst, unsigned *dst_len,
upx_callback_t *cb_parm, int method, int level,
const upx_compress_config_t *cconf_parm, upx_compress_result_t *cresult) {
assert(method == M_BZIP2);
assert(level > 0);
assert(cresult != nullptr);
UNUSED(cb_parm);
int r = UPX_E_ERROR;
const bzip2_compress_config_t *const lcconf = cconf_parm ? &cconf_parm->conf_bzip2 : nullptr;
bzip2_compress_result_t *const res = &cresult->result_bzip2;
res->reset();
int blockSize100k = (src_len + 100000 - 1) / 100000;
if (blockSize100k < 1)
blockSize100k = 1;
if (blockSize100k > 9)
blockSize100k = 9;
// idea for later: could enhance lcconf to allow setting blockSize100k
UNUSED(lcconf);
if (level <= 3 && blockSize100k > level)
blockSize100k = level;
char *dest = (char *) dst;
char *source = (char *) const_cast<byte *>(src);
r = BZ2_bzBuffToBuffCompress(dest, dst_len, source, src_len, blockSize100k, 0, 0);
return convert_errno_from_bzip2(r);
}
/*************************************************************************
//
**************************************************************************/
int upx_bzip2_decompress(const upx_bytep src, unsigned src_len, upx_bytep dst, unsigned *dst_len,
int method, const upx_compress_result_t *cresult) {
assert(method == M_BZIP2);
UNUSED(method);
UNUSED(cresult);
char *dest = (char *) dst;
char *source = (char *) const_cast<byte *>(src);
int small = 0;
int r = BZ2_bzBuffToBuffDecompress(dest, dst_len, source, src_len, small, 0);
return convert_errno_from_bzip2(r);
}
/*************************************************************************
// test_overlap - see <ucl/ucl.h> for semantics
**************************************************************************/
int upx_bzip2_test_overlap(const upx_bytep buf, const upx_bytep tbuf, unsigned src_off,
unsigned src_len, unsigned *dst_len, int method,
const upx_compress_result_t *cresult) {
assert(method == M_BZIP2);
MemBuffer b(src_off + src_len);
memcpy(b + src_off, buf + src_off, src_len);
unsigned saved_dst_len = *dst_len;
int r = upx_bzip2_decompress(raw_index_bytes(b, src_off, src_len), src_len,
raw_bytes(b, *dst_len), dst_len, method, cresult);
if (r != UPX_E_OK)
return r;
if (*dst_len != saved_dst_len)
return UPX_E_ERROR;
// NOTE: there is a very tiny possibility that decompression has
// succeeded but the data is not restored correctly because of
// in-place buffer overlapping, so we use an extra memcmp().
if (tbuf != nullptr && memcmp(tbuf, b, *dst_len) != 0)
return UPX_E_ERROR;
return UPX_E_OK;
}
/*************************************************************************
// misc
**************************************************************************/
int upx_bzip2_init(void) { return 0; }
const char *upx_bzip2_version_string(void) { return BZ2_bzlibVersion(); }
/*************************************************************************
// doctest checks
**************************************************************************/
#if DEBUG && !defined(DOCTEST_CONFIG_DISABLE) && 1
static bool check_bzip2(const int method, const int level, const unsigned expected_c_len) {
const unsigned u_len = 16384;
const unsigned c_extra = 4096;
MemBuffer u_buf, c_buf, d_buf;
unsigned c_len, d_len;
upx_compress_result_t cresult;
int r;
u_buf.alloc(u_len);
memset(u_buf, 0, u_len);
c_buf.allocForCompression(u_len, c_extra);
d_buf.allocForDecompression(u_len);
c_len = c_buf.getSize() - c_extra;
r = upx_bzip2_compress(raw_bytes(u_buf, u_len), u_len, raw_index_bytes(c_buf, c_extra, c_len),
&c_len, nullptr, method, level, NULL_cconf, &cresult);
if (r != 0 || c_len != expected_c_len)
return false;
d_len = d_buf.getSize();
r = upx_bzip2_decompress(raw_index_bytes(c_buf, c_extra, c_len), c_len, raw_bytes(d_buf, d_len),
&d_len, method, nullptr);
if (r != 0 || d_len != u_len || memcmp(u_buf, d_buf, u_len) != 0)
return false;
d_len = u_len - 1;
r = upx_bzip2_decompress(raw_index_bytes(c_buf, c_extra, c_len), c_len, raw_bytes(d_buf, d_len),
&d_len, method, nullptr);
if (r == 0)
return false;
// TODO: rewrite Packer::findOverlapOverhead() so that we can test it here
// unsigned x_len = d_len;
// r = upx_bzip2_test_overlap(c_buf, u_buf, c_extra, c_len, &x_len, method, nullptr);
return true;
}
TEST_CASE("compress_bzip2") { CHECK(check_bzip2(M_BZIP2, 9, 46)); }
#endif // DEBUG
TEST_CASE("upx_bzip2_decompress") {
#if 0 // TODO later, see above
const byte *c_data;
byte d_buf[32];
unsigned d_len;
int r;
c_data = (const byte *) "\x28\xb5\x2f\xfd\x20\x20\x3d\x00\x00\x08\xff\x01\x00\x34\x4e\x08";
d_len = 32;
r = upx_bzip2_decompress(c_data, 16, d_buf, &d_len, M_BZIP2, nullptr);
CHECK((r == 0 && d_len == 32));
r = upx_bzip2_decompress(c_data, 15, d_buf, &d_len, M_BZIP2, nullptr);
CHECK(r == UPX_E_INPUT_OVERRUN);
d_len = 31;
r = upx_bzip2_decompress(c_data, 16, d_buf, &d_len, M_BZIP2, nullptr);
CHECK(r == UPX_E_OUTPUT_OVERRUN);
UNUSED(r);
#endif // TODO
}
#endif // WITH_BZIP2
/* vim:set ts=4 sw=4 et: */
+20 -19
View File
@@ -2,7 +2,7 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer Copyright (C) 1996-2024 Markus Franz Xaver Johannes Oberhumer
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
@@ -37,9 +37,6 @@
#if (ACC_CC_MSC) #if (ACC_CC_MSC)
#pragma warning(disable : 4456) // -Wno-shadow #pragma warning(disable : 4456) // -Wno-shadow
#endif #endif
#if (ACC_CC_MSC && (_MSC_VER < 1900))
#pragma warning(disable : 4127) // warning C4127: conditional expression is constant
#endif
void lzma_compress_config_t::reset() noexcept { void lzma_compress_config_t::reset() noexcept {
pos_bits.reset(); pos_bits.reset();
@@ -206,15 +203,12 @@ error:
// compress - cruft because of pseudo-COM layer // compress - cruft because of pseudo-COM layer
**************************************************************************/ **************************************************************************/
// ensure proper nullptr usage #if (ACC_CC_CLANG >= 0x080000)
// TODO later: examine why we need this in the first place #pragma clang diagnostic push
#undef NULL #pragma clang diagnostic ignored "-Wzero-as-null-pointer-constant"
// NOLINTBEGIN(clang-analyzer-optin.cplusplus.*) #elif (ACC_CC_GNUC >= 0x040700)
#define NULL nullptr #pragma GCC diagnostic push
// NOLINTEND(clang-analyzer-optin.cplusplus.*) #pragma GCC diagnostic ignored "-Wzero-as-null-pointer-constant"
#if defined(__GNUC__)
#undef __null
#define __null nullptr
#endif #endif
#undef MSDOS #undef MSDOS
@@ -293,7 +287,7 @@ struct ProgressInfo final : public ICompressProgressInfo, public CMyUnknownImp {
virtual ~ProgressInfo() {} virtual ~ProgressInfo() {}
MY_UNKNOWN_IMP MY_UNKNOWN_IMP
STDMETHOD(SetRatioInfo)(const UInt64 *inSize, const UInt64 *outSize) override; STDMETHOD(SetRatioInfo)(const UInt64 *inSize, const UInt64 *outSize) override;
upx_callback_p cb = nullptr; upx_callback_t *cb = nullptr;
}; };
STDMETHODIMP ProgressInfo::SetRatioInfo(const UInt64 *inSize, const UInt64 *outSize) { STDMETHODIMP ProgressInfo::SetRatioInfo(const UInt64 *inSize, const UInt64 *outSize) {
@@ -316,8 +310,14 @@ STDMETHODIMP ProgressInfo::SetRatioInfo(const UInt64 *inSize, const UInt64 *outS
#include <lzma-sdk/C/7zip/Compress/RangeCoder/RangeCoderBit.cpp> #include <lzma-sdk/C/7zip/Compress/RangeCoder/RangeCoderBit.cpp>
#undef RC_NORMALIZE #undef RC_NORMALIZE
#if (ACC_CC_CLANG >= 0x080000)
#pragma clang diagnostic pop
#elif (ACC_CC_GNUC >= 0x040700)
#pragma GCC diagnostic pop
#endif
int upx_lzma_compress(const upx_bytep src, unsigned src_len, upx_bytep dst, unsigned *dst_len, int upx_lzma_compress(const upx_bytep src, unsigned src_len, upx_bytep dst, unsigned *dst_len,
upx_callback_p cb, int method, int level, upx_callback_t *cb, int method, int level,
const upx_compress_config_t *cconf_parm, upx_compress_result_t *cresult) { const upx_compress_config_t *cconf_parm, upx_compress_result_t *cresult) {
assert(M_IS_LZMA(method)); assert(M_IS_LZMA(method));
assert(level > 0); assert(level > 0);
@@ -327,6 +327,7 @@ int upx_lzma_compress(const upx_bytep src, unsigned src_len, upx_bytep dst, unsi
HRESULT rh; HRESULT rh;
const lzma_compress_config_t *const lcconf = cconf_parm ? &cconf_parm->conf_lzma : nullptr; const lzma_compress_config_t *const lcconf = cconf_parm ? &cconf_parm->conf_lzma : nullptr;
lzma_compress_result_t *const res = &cresult->result_lzma; lzma_compress_result_t *const res = &cresult->result_lzma;
res->reset();
MyLzma::InStream is; MyLzma::InStream is;
is.AddRef(); is.AddRef();
@@ -339,7 +340,8 @@ int upx_lzma_compress(const upx_bytep src, unsigned src_len, upx_bytep dst, unsi
progress.cb = cb; // progress.Init() progress.cb = cb; // progress.Init()
NCompress::NLZMA::CEncoder enc; NCompress::NLZMA::CEncoder enc;
const PROPID propIDs[8] = { constexpr unsigned NPROPS = 8;
static const PROPID propIDs[NPROPS] = {
NCoderPropID::kPosStateBits, // 0 pb _posStateBits(2) NCoderPropID::kPosStateBits, // 0 pb _posStateBits(2)
NCoderPropID::kLitPosBits, // 1 lp _numLiteralPosStateBits(0) NCoderPropID::kLitPosBits, // 1 lp _numLiteralPosStateBits(0)
NCoderPropID::kLitContextBits, // 2 lc _numLiteralContextBits(3) NCoderPropID::kLitContextBits, // 2 lc _numLiteralContextBits(3)
@@ -349,8 +351,7 @@ int upx_lzma_compress(const upx_bytep src, unsigned src_len, upx_bytep dst, unsi
NCoderPropID::kMatchFinderCycles, // 6 mfc _matchFinderCycles, _cutValue NCoderPropID::kMatchFinderCycles, // 6 mfc _matchFinderCycles, _cutValue
NCoderPropID::kMatchFinder // 7 mf NCoderPropID::kMatchFinder // 7 mf
}; };
PROPVARIANT pr[8]; PROPVARIANT pr[NPROPS];
const unsigned nprops = 8;
if (!prepare_result(res, src_len, method, level, lcconf)) if (!prepare_result(res, src_len, method, level, lcconf))
goto error; goto error;
pr[0].vt = pr[1].vt = pr[2].vt = pr[3].vt = pr[4].vt = pr[5].vt = pr[6].vt = VT_UI4; pr[0].vt = pr[1].vt = pr[2].vt = pr[3].vt = pr[4].vt = pr[5].vt = pr[6].vt = VT_UI4;
@@ -367,7 +368,7 @@ int upx_lzma_compress(const upx_bytep src, unsigned src_len, upx_bytep dst, unsi
pr[7].bstrVal = ACC_PCAST(BSTR, ACC_UNCONST_CAST(wchar_t *, matchfinder)); pr[7].bstrVal = ACC_PCAST(BSTR, ACC_UNCONST_CAST(wchar_t *, matchfinder));
try { try {
if (enc.SetCoderProperties(propIDs, pr, nprops) != S_OK) if (enc.SetCoderProperties(propIDs, pr, NPROPS) != S_OK)
goto error; goto error;
// encode properties in LZMA-style (5 bytes) // encode properties in LZMA-style (5 bytes)
if (enc.WriteCoderProperties(&os) != S_OK) if (enc.WriteCoderProperties(&os) != S_OK)
+3 -3
View File
@@ -2,7 +2,7 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer Copyright (C) 1996-2024 Markus Franz Xaver Johannes Oberhumer
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
@@ -66,7 +66,7 @@ extern "C" {
static void __UCL_CDECL wrap_nprogress_ucl(ucl_uint a, ucl_uint b, int state, ucl_voidp user) { static void __UCL_CDECL wrap_nprogress_ucl(ucl_uint a, ucl_uint b, int state, ucl_voidp user) {
if (state != -1 && state != 3) if (state != -1 && state != 3)
return; return;
upx_callback_p cb = (upx_callback_p) user; upx_callback_t *cb = (upx_callback_t *) user;
if (cb && cb->nprogress) if (cb && cb->nprogress)
cb->nprogress(cb, a, b); cb->nprogress(cb, a, b);
} }
@@ -77,7 +77,7 @@ static void __UCL_CDECL wrap_nprogress_ucl(ucl_uint a, ucl_uint b, int state, uc
**************************************************************************/ **************************************************************************/
int upx_ucl_compress(const upx_bytep src, unsigned src_len, upx_bytep dst, unsigned *dst_len, int upx_ucl_compress(const upx_bytep src, unsigned src_len, upx_bytep dst, unsigned *dst_len,
upx_callback_p cb_parm, int method, int level, upx_callback_t *cb_parm, int method, int level,
const upx_compress_config_t *cconf_parm, upx_compress_result_t *cresult) { const upx_compress_config_t *cconf_parm, upx_compress_result_t *cresult) {
int r; int r;
assert(level > 0); assert(level > 0);
+3 -4
View File
@@ -2,7 +2,7 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer Copyright (C) 1996-2024 Markus Franz Xaver Johannes Oberhumer
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
@@ -75,7 +75,7 @@ static int convert_errno_from_zlib(int zr) {
**************************************************************************/ **************************************************************************/
int upx_zlib_compress(const upx_bytep src, unsigned src_len, upx_bytep dst, unsigned *dst_len, int upx_zlib_compress(const upx_bytep src, unsigned src_len, upx_bytep dst, unsigned *dst_len,
upx_callback_p cb_parm, int method, int level, upx_callback_t *cb_parm, int method, int level,
const upx_compress_config_t *cconf_parm, upx_compress_result_t *cresult) { const upx_compress_config_t *cconf_parm, upx_compress_result_t *cresult) {
assert(method == M_DEFLATE); assert(method == M_DEFLATE);
assert(level > 0); assert(level > 0);
@@ -85,6 +85,7 @@ int upx_zlib_compress(const upx_bytep src, unsigned src_len, upx_bytep dst, unsi
int zr; int zr;
const zlib_compress_config_t *const lcconf = cconf_parm ? &cconf_parm->conf_zlib : nullptr; const zlib_compress_config_t *const lcconf = cconf_parm ? &cconf_parm->conf_zlib : nullptr;
zlib_compress_result_t *const res = &cresult->result_zlib; zlib_compress_result_t *const res = &cresult->result_zlib;
res->reset();
if (level == 10) if (level == 10)
level = 9; level = 9;
@@ -99,8 +100,6 @@ int upx_zlib_compress(const upx_bytep src, unsigned src_len, upx_bytep dst, unsi
oassign(strategy, lcconf->strategy); oassign(strategy, lcconf->strategy);
} }
res->dummy = 0;
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;
+10 -7
View File
@@ -2,7 +2,7 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer Copyright (C) 1996-2024 Markus Franz Xaver Johannes Oberhumer
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
@@ -24,6 +24,12 @@
<markus@oberhumer.com> <markus@oberhumer.com>
*/ */
#include "../util/system_headers.h"
#if WITH_ZSTD
#include <zstd/lib/zstd.h>
#include <zstd/lib/zstd_errors.h>
#include <zstd/lib/compress/hist.h>
#endif
#include "../conf.h" #include "../conf.h"
void zstd_compress_config_t::reset() noexcept { mem_clear(this); } void zstd_compress_config_t::reset() noexcept { mem_clear(this); }
@@ -31,9 +37,6 @@ void zstd_compress_config_t::reset() noexcept { mem_clear(this); }
#if WITH_ZSTD #if WITH_ZSTD
#include "compress.h" #include "compress.h"
#include "../util/membuffer.h" #include "../util/membuffer.h"
#include <zstd/lib/zstd.h>
#include <zstd/lib/zstd_errors.h>
#include <zstd/lib/compress/hist.h>
static int convert_errno_from_zstd(size_t zr) { static int convert_errno_from_zstd(size_t zr) {
const ZSTD_ErrorCode ze = ZSTD_getErrorCode(zr); const ZSTD_ErrorCode ze = ZSTD_getErrorCode(zr);
@@ -55,7 +58,7 @@ static int convert_errno_from_zstd(size_t zr) {
**************************************************************************/ **************************************************************************/
int upx_zstd_compress(const upx_bytep src, unsigned src_len, upx_bytep dst, unsigned *dst_len, int upx_zstd_compress(const upx_bytep src, unsigned src_len, upx_bytep dst, unsigned *dst_len,
upx_callback_p cb_parm, int method, int level, upx_callback_t *cb_parm, int method, int level,
const upx_compress_config_t *cconf_parm, upx_compress_result_t *cresult) { const upx_compress_config_t *cconf_parm, upx_compress_result_t *cresult) {
assert(method == M_ZSTD); assert(method == M_ZSTD);
assert(level > 0); assert(level > 0);
@@ -65,6 +68,7 @@ int upx_zstd_compress(const upx_bytep src, unsigned src_len, upx_bytep dst, unsi
size_t zr; size_t zr;
const zstd_compress_config_t *const lcconf = cconf_parm ? &cconf_parm->conf_zstd : nullptr; const zstd_compress_config_t *const lcconf = cconf_parm ? &cconf_parm->conf_zstd : nullptr;
zstd_compress_result_t *const res = &cresult->result_zstd; zstd_compress_result_t *const res = &cresult->result_zstd;
res->reset();
// TODO later: map level 1..10 to zstd-level 1..22 // TODO later: map level 1..10 to zstd-level 1..22
if (level == 10) if (level == 10)
@@ -75,8 +79,6 @@ int upx_zstd_compress(const upx_bytep src, unsigned src_len, upx_bytep dst, unsi
UNUSED(lcconf); UNUSED(lcconf);
} }
res->dummy = 0;
zr = ZSTD_compress(dst, *dst_len, src, src_len, level); zr = ZSTD_compress(dst, *dst_len, src, src_len, level);
if (ZSTD_isError(zr)) { if (ZSTD_isError(zr)) {
*dst_len = 0; // TODO ??? *dst_len = 0; // TODO ???
@@ -221,6 +223,7 @@ TEST_CASE("upx_zstd_decompress") {
d_len = 31; d_len = 31;
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 == UPX_E_OUTPUT_OVERRUN); CHECK(r == UPX_E_OUTPUT_OVERRUN);
UNUSED(r);
} }
#endif // WITH_ZSTD #endif // WITH_ZSTD
+247 -184
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer Copyright (C) 1996-2024 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2023 Laszlo Molnar Copyright (C) 1996-2024 Laszlo Molnar
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
@@ -31,7 +31,7 @@
// init // init
**************************************************************************/ **************************************************************************/
#include "headers.h" #include "util/system_headers.h"
#include "version.h" #include "version.h"
#if !defined(__has_attribute) #if !defined(__has_attribute)
@@ -53,31 +53,31 @@ ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(int) == 4)
ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(long long) == 8) ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(long long) == 8)
// check sane compiler mandatory flags // check sane compiler mandatory flags
ACC_COMPILE_TIME_ASSERT_HEADER(-1 == ~0) // two's complement - see http://wg21.link/P0907R4 ACC_COMPILE_TIME_ASSERT_HEADER(-1 == ~0) // two's complement - see http://wg21.link/P0907R4
ACC_COMPILE_TIME_ASSERT_HEADER(0u-1 == ~0u) // two's complement - see http://wg21.link/P0907R4 ACC_COMPILE_TIME_ASSERT_HEADER(0u - 1 == ~0u) // two's complement - see http://wg21.link/P0907R4
ACC_COMPILE_TIME_ASSERT_HEADER((1u << 31) << 1 == 0) ACC_COMPILE_TIME_ASSERT_HEADER((1u << 31) << 1 == 0)
ACC_COMPILE_TIME_ASSERT_HEADER(((int)(1u << 31)) >> 31 == -1) // arithmetic right shift ACC_COMPILE_TIME_ASSERT_HEADER(((int) (1u << 31)) >> 31 == -1) // arithmetic right shift
ACC_COMPILE_TIME_ASSERT_HEADER((-1) >> 31 == -1) // arithmetic right shift 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)
// enable some more strict warnings for Git developer builds // 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_WSTRICT) && (UPX_CONFIG_DISABLE_WSTRICT + 0 == 0)
#if defined(UPX_CONFIG_DISABLE_WERROR) && (UPX_CONFIG_DISABLE_WERROR + 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) #if (ACC_CC_CLANG >= 0x080000)
// don't enable before clang-8 because of stddef.h issues // don't enable before clang-8 because of <stddef.h> issues
# pragma clang diagnostic error "-Wzero-as-null-pointer-constant" #pragma clang diagnostic error "-Wzero-as-null-pointer-constant"
#elif (ACC_CC_GNUC >= 0x040700) && defined(__GLIBC__) #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
# 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_WERROR
#endif // UPX_CONFIG_DISABLE_WSTRICT #endif // UPX_CONFIG_DISABLE_WSTRICT
@@ -94,7 +94,10 @@ ACC_COMPILE_TIME_ASSERT_HEADER((char)(-1) == 255) // -funsigned-char
#define upx_std_once_flag upx_std_atomic(size_t) #define upx_std_once_flag upx_std_atomic(size_t)
template <class NoexceptCallable> template <class NoexceptCallable>
inline void upx_std_call_once(upx_std_once_flag &flag, NoexceptCallable &&f) { inline void upx_std_call_once(upx_std_once_flag &flag, NoexceptCallable &&f) {
if (__acc_unlikely(!flag)) { flag = 1; f(); } if (__acc_unlikely(!flag)) {
flag = 1;
f();
}
} }
#endif // WITH_THREADS #endif // WITH_THREADS
@@ -106,11 +109,11 @@ inline constexpr bool upx_is_integral_v = upx_is_integral<T>::value;
#if (ACC_ARCH_M68K && ACC_OS_TOS && ACC_CC_GNUC) && defined(__MINT__) #if (ACC_ARCH_M68K && ACC_OS_TOS && ACC_CC_GNUC) && defined(__MINT__)
// horrible hack for broken compiler / ABI // horrible hack for broken compiler / ABI
#define upx_fake_alignas_1 __attribute__((__aligned__(1),__packed__)) #define upx_fake_alignas_1 __attribute__((__aligned__(1), __packed__))
#define upx_fake_alignas_2 __attribute__((__aligned__(2))) #define upx_fake_alignas_2 __attribute__((__aligned__(2)))
#define upx_fake_alignas_4 __attribute__((__aligned__(2))) // object file maximum 2 ??? #define upx_fake_alignas_4 __attribute__((__aligned__(2))) // object file maximum 2 ???
#define upx_fake_alignas_16 __attribute__((__aligned__(2))) // object file maximum 2 ??? #define upx_fake_alignas_16 __attribute__((__aligned__(2))) // object file maximum 2 ???
#define upx_fake_alignas__(x) upx_fake_alignas_ ## x #define upx_fake_alignas__(x) upx_fake_alignas_##x
#define alignas(x) upx_fake_alignas__(x) #define alignas(x) upx_fake_alignas__(x)
#define upx_alignas_max upx_fake_alignas_4 #define upx_alignas_max upx_fake_alignas_4
#endif #endif
@@ -118,7 +121,6 @@ inline constexpr bool upx_is_integral_v = upx_is_integral<T>::value;
#define upx_alignas_max alignas(std::max_align_t) #define upx_alignas_max alignas(std::max_align_t)
#endif #endif
/************************************************************************* /*************************************************************************
// core // core
**************************************************************************/ **************************************************************************/
@@ -143,23 +145,24 @@ 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;
// convention: use "byte" when dealing with data; use "char/uchar" when dealing // UPX convention: use "byte" when dealing with data; use "char/uchar" when dealing
// with strings; use "upx_uint8_t" when dealing with small integers // with strings; use "upx_uint8_t" when dealing with small integers
typedef unsigned char byte; typedef unsigned char byte;
#define upx_byte byte #define upx_byte byte
#define upx_bytep byte * #define upx_bytep byte *
typedef unsigned char uchar; typedef unsigned char uchar;
// convention: use "charptr" when dealing with abstract pointer arithmetics // UPX convention: use "charptr" when dealing with abstract pointer arithmetics
#define charptr upx_charptr_unit_type * #define charptr upx_charptr_unit_type *
// upx_charptr_unit_type is some opaque type with sizeof(type) == 1 // upx_charptr_unit_type is some opaque type with sizeof(type) == 1
struct alignas(1) upx_charptr_unit_type { char hidden__; }; //// typedef char upx_charptr_unit_type; // also works
struct alignas(1) upx_charptr_unit_type final { char hidden__; };
ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(upx_charptr_unit_type) == 1) 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
// TODO cleanup: at some future point we can do this: // TODO later 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
@@ -167,108 +170,120 @@ typedef upx_int64_t upx_off_t;
// shortcuts // shortcuts
#define forceinline __acc_forceinline #define forceinline __acc_forceinline
#if _MSC_VER #if (ACC_CC_MSC)
#define noinline __declspec(noinline) #define noinline __declspec(noinline)
#undef __acc_noinline #undef __acc_noinline
#define __acc_noinline noinline #define __acc_noinline noinline
#else #else
#define noinline __acc_noinline #define noinline __acc_noinline
#endif #endif
#if defined(__clang__) || defined(__GNUC__)
#define noreturn noinline __attribute__((__noreturn__))
#elif (ACC_CC_MSC)
// do not use, triggers annoying "warning C4702: unreachable code"
////#define noreturn noinline __declspec(noreturn)
#define noreturn noinline
#else
#define noreturn noinline
#endif
#define forceinline_constexpr forceinline constexpr #define forceinline_constexpr forceinline constexpr
#define likely __acc_likely #define likely __acc_likely
#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
// cosmetic: explicitly annotate some functions which may throw exceptions
// note that noexcept(false) is the default for all C++ functions anyway
#define may_throw noexcept(false) #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
#define UNUSED(var) ACC_UNUSED(var) #define UNUSED(var) ACC_UNUSED(var)
/************************************************************************* /*************************************************************************
// portab // portab
**************************************************************************/ **************************************************************************/
// just in case // some platform system headers may pre-define these, so undef to avoid conflicts
#undef _ #undef _
#undef __ #undef __
#undef ___ #undef ___
#undef dos #undef dos
#undef large
#undef linux #undef linux
#undef PAGE_MASK
#undef PAGE_SIZE
#undef small #undef small
#undef SP
#undef SS
#undef tos #undef tos
#undef unix #undef unix
#if (ACC_OS_POSIX) && !defined(__unix__) #if (ACC_OS_POSIX) && !defined(__unix__)
# define __unix__ 1 #define __unix__ 1
#endif #endif
#if (ACC_OS_CYGWIN || ACC_OS_DOS16 || ACC_OS_DOS32 || ACC_OS_EMX || ACC_OS_OS2 || ACC_OS_OS216 || ACC_OS_WIN16 || ACC_OS_WIN32 || ACC_OS_WIN64) #if (ACC_OS_CYGWIN || ACC_OS_DOS16 || ACC_OS_DOS32 || ACC_OS_EMX || ACC_OS_OS2 || ACC_OS_OS216 || \
# undef __unix ACC_OS_WIN16 || ACC_OS_WIN32 || ACC_OS_WIN64)
# undef __unix__ #undef __unix
#undef __unix__
#endif #endif
#if (ACC_OS_DOS32) && defined(__DJGPP__) #if (ACC_OS_DOS32) && defined(__DJGPP__)
# undef sopen #undef sopen
#endif
#if defined(HAVE_DUP) && (HAVE_DUP + 0 == 0)
# undef dup
# define dup(x) (-1)
#endif #endif
#ifndef STDIN_FILENO #ifndef STDIN_FILENO
# define STDIN_FILENO (fileno(stdin)) #define STDIN_FILENO (fileno(stdin))
#endif #endif
#ifndef STDOUT_FILENO #ifndef STDOUT_FILENO
# define STDOUT_FILENO (fileno(stdout)) #define STDOUT_FILENO (fileno(stdout))
#endif #endif
#ifndef STDERR_FILENO #ifndef STDERR_FILENO
# define STDERR_FILENO (fileno(stderr)) #define STDERR_FILENO (fileno(stderr))
#endif #endif
#if !(HAVE_STRCASECMP) && (HAVE_STRICMP) && !defined(strcasecmp) #if !(HAVE_STRCASECMP) && (HAVE_STRICMP) && !defined(strcasecmp)
# define strcasecmp stricmp #define strcasecmp stricmp
#endif #endif
#if !(HAVE_STRNCASECMP) && (HAVE_STRNICMP) && !defined(strncasecmp) #if !(HAVE_STRNCASECMP) && (HAVE_STRNICMP) && !defined(strncasecmp)
# define strncasecmp strnicmp #define strncasecmp strnicmp
#endif #endif
#if !defined(S_IWUSR) && defined(_S_IWUSR) #if !defined(S_IWUSR) && defined(_S_IWUSR)
# define S_IWUSR _S_IWUSR #define S_IWUSR _S_IWUSR
#elif !defined(S_IWUSR) && defined(_S_IWRITE) #elif !defined(S_IWUSR) && defined(_S_IWRITE)
# define S_IWUSR _S_IWRITE #define S_IWUSR _S_IWRITE
#endif #endif
#if !defined(S_IFMT) && defined(_S_IFMT) #if !defined(S_IFMT) && defined(_S_IFMT)
# define S_IFMT _S_IFMT #define S_IFMT _S_IFMT
#endif #endif
#if !defined(S_IFREG) && defined(_S_IFREG) #if !defined(S_IFREG) && defined(_S_IFREG)
# define S_IFREG _S_IFREG #define S_IFREG _S_IFREG
#endif #endif
#if !defined(S_IFDIR) && defined(_S_IFDIR) #if !defined(S_IFDIR) && defined(_S_IFDIR)
# define S_IFDIR _S_IFDIR #define S_IFDIR _S_IFDIR
#endif #endif
#if !defined(S_IFCHR) && defined(_S_IFCHR) #if !defined(S_IFCHR) && defined(_S_IFCHR)
# define S_IFCHR _S_IFCHR #define S_IFCHR _S_IFCHR
#endif #endif
#if !defined(S_ISREG) #if !defined(S_ISREG)
# if defined(S_IFMT) && defined(S_IFREG) #if defined(S_IFMT) && defined(S_IFREG)
# define S_ISREG(m) (((m) & S_IFMT) == S_IFREG) #define S_ISREG(m) (((m) &S_IFMT) == S_IFREG)
# else #else
# error "S_ISREG" #error "S_ISREG"
# endif #endif
#endif #endif
#if !defined(S_ISDIR) #if !defined(S_ISDIR)
# if defined(S_IFMT) && defined(S_IFDIR) #if defined(S_IFMT) && defined(S_IFDIR)
# define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR) #define S_ISDIR(m) (((m) &S_IFMT) == S_IFDIR)
# else #else
# error "S_ISDIR" #error "S_ISDIR"
# endif #endif
#endif #endif
#if !defined(S_ISCHR) #if !defined(S_ISCHR)
# if defined(S_IFMT) && defined(S_IFCHR) #if defined(S_IFMT) && defined(S_IFCHR)
# define S_ISCHR(m) (((m) & S_IFMT) == S_IFCHR) #define S_ISCHR(m) (((m) &S_IFMT) == S_IFCHR)
# endif #endif
#endif #endif
// avoid warnings about shadowing global symbols // avoid warnings about shadowing global symbols
@@ -281,19 +296,16 @@ typedef upx_int64_t upx_off_t;
#define index upx_renamed_index #define index upx_renamed_index
#define outp upx_renamed_outp #define outp upx_renamed_outp
#undef PAGE_MASK #if !defined(O_BINARY) || (O_BINARY + 0 == 0)
#undef PAGE_SIZE #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(O_BINARY) || (O_BINARY+0 == 0) #error "missing O_BINARY"
# 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) #endif
# error "missing O_BINARY"
# endif
#endif #endif
#if !defined(O_BINARY) #if !defined(O_BINARY)
# define O_BINARY 0 #define O_BINARY 0
#endif #endif
/************************************************************************* /*************************************************************************
// util // util
**************************************************************************/ **************************************************************************/
@@ -302,27 +314,28 @@ typedef upx_int64_t upx_off_t;
// malloc debuggers // malloc debuggers
#if !defined(VALGRIND_CHECK_MEM_IS_ADDRESSABLE) #if !defined(VALGRIND_CHECK_MEM_IS_ADDRESSABLE)
# define VALGRIND_CHECK_MEM_IS_ADDRESSABLE(addr,len) 0 #define VALGRIND_CHECK_MEM_IS_ADDRESSABLE(addr, len) 0
#endif #endif
#if !defined(VALGRIND_CHECK_MEM_IS_DEFINED) #if !defined(VALGRIND_CHECK_MEM_IS_DEFINED)
# define VALGRIND_CHECK_MEM_IS_DEFINED(addr,len) 0 #define VALGRIND_CHECK_MEM_IS_DEFINED(addr, len) 0
#endif #endif
#if !defined(VALGRIND_MAKE_MEM_DEFINED) #if !defined(VALGRIND_MAKE_MEM_DEFINED)
# define VALGRIND_MAKE_MEM_DEFINED(addr,len) 0 #define VALGRIND_MAKE_MEM_DEFINED(addr, len) 0
#endif #endif
#if !defined(VALGRIND_MAKE_MEM_NOACCESS) #if !defined(VALGRIND_MAKE_MEM_NOACCESS)
# define VALGRIND_MAKE_MEM_NOACCESS(addr,len) 0 #define VALGRIND_MAKE_MEM_NOACCESS(addr, len) 0
#endif #endif
#if !defined(VALGRIND_MAKE_MEM_UNDEFINED) #if !defined(VALGRIND_MAKE_MEM_UNDEFINED)
# define VALGRIND_MAKE_MEM_UNDEFINED(addr,len) 0 #define VALGRIND_MAKE_MEM_UNDEFINED(addr, len) 0
#endif #endif
// TODO later: check __MINGW_PRINTF_FORMAT
#if defined(_WIN32) && defined(__MINGW32__) && defined(__GNUC__) && !defined(__clang__) #if defined(_WIN32) && defined(__MINGW32__) && defined(__GNUC__) && !defined(__clang__)
# define attribute_format(a,b) __attribute__((__format__(__gnu_printf__,a,b))) #define attribute_format(a, b) __attribute__((__format__(__gnu_printf__, a, b)))
#elif (ACC_CC_CLANG || ACC_CC_GNUC) #elif defined(__clang__) || defined(__GNUC__)
# define attribute_format(a,b) __attribute__((__format__(__printf__,a,b))) #define attribute_format(a, b) __attribute__((__format__(__printf__, a, b)))
#else #else
# define attribute_format(a,b) /*empty*/ #define attribute_format(a, b) /*empty*/
#endif #endif
// for no-op debug output // for no-op debug output
@@ -332,55 +345,87 @@ inline void NO_printf(const char *, ...) noexcept {}
inline void NO_fprintf(FILE *, const char *, ...) noexcept {} inline void NO_fprintf(FILE *, const char *, ...) noexcept {}
#if __has_builtin(__builtin_memcpy_inline) #if __has_builtin(__builtin_memcpy_inline)
# define upx_memcpy_inline __builtin_memcpy_inline #define upx_memcpy_inline __builtin_memcpy_inline
#elif __has_builtin(__builtin_memcpy) #elif __has_builtin(__builtin_memcpy)
# define upx_memcpy_inline __builtin_memcpy #define upx_memcpy_inline __builtin_memcpy
#elif defined(__GNUC__) #elif defined(__clang__) || defined(__GNUC__)
# define upx_memcpy_inline __builtin_memcpy #define upx_memcpy_inline __builtin_memcpy
#else #else
# define upx_memcpy_inline memcpy #define upx_memcpy_inline memcpy
#endif #endif
#if __has_builtin(__builtin_return_address) #if defined(__wasi__)
# define upx_return_address() __builtin_return_address(0) #define upx_return_address() nullptr
#elif defined(__GNUC__) #elif __has_builtin(__builtin_return_address)
# define upx_return_address() __builtin_return_address(0) #define upx_return_address() __builtin_return_address(0)
#elif defined(__clang__) || defined(__GNUC__)
#define upx_return_address() __builtin_return_address(0)
#elif (ACC_CC_MSC) #elif (ACC_CC_MSC)
# define upx_return_address() _ReturnAddress() #define upx_return_address() _ReturnAddress()
#else #else
# define upx_return_address() nullptr #define upx_return_address() nullptr
#endif #endif
// TODO cleanup: we now require C++17, so remove all __packed_struct usage // TODO later 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 COMPILE_TIME_ASSERT_ALIGNOF_USING_SIZEOF__(a,b) { \ // TODO later cleanup: this was needed in the old days to catch compiler problems/bugs;
typedef a acc_tmp_a_t; typedef b acc_tmp_b_t; \ // we now require C++17, so remove this
struct alignas(1) acc_tmp_t { acc_tmp_b_t x; acc_tmp_a_t y; acc_tmp_b_t z; }; \ #define COMPILE_TIME_ASSERT_ALIGNOF_USING_SIZEOF__(a, b) \
COMPILE_TIME_ASSERT(sizeof(struct acc_tmp_t) == 2*sizeof(b)+sizeof(a)) \ { \
COMPILE_TIME_ASSERT(sizeof(((acc_tmp_t*)nullptr)->x)+sizeof(((acc_tmp_t*)nullptr)->y)+sizeof(((acc_tmp_t*)nullptr)->z) == 2*sizeof(b)+sizeof(a)) \ 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; \
}; \
COMPILE_TIME_ASSERT(sizeof(struct acc_tmp_t) == 2 * sizeof(b) + sizeof(a)) \
COMPILE_TIME_ASSERT(sizeof(((acc_tmp_t *) nullptr)->x) + \
sizeof(((acc_tmp_t *) nullptr)->y) + \
sizeof(((acc_tmp_t *) nullptr)->z) == \
2 * sizeof(b) + sizeof(a)) \
} }
#define COMPILE_TIME_ASSERT_ALIGNOF__(a,b) \ #define COMPILE_TIME_ASSERT_ALIGNOF__(a, b) \
COMPILE_TIME_ASSERT_ALIGNOF_USING_SIZEOF__(a,b) \ COMPILE_TIME_ASSERT_ALIGNOF_USING_SIZEOF__(a, b) \
COMPILE_TIME_ASSERT(__acc_alignof(a) == sizeof(b)) \ COMPILE_TIME_ASSERT(__acc_alignof(a) == sizeof(b)) \
COMPILE_TIME_ASSERT(alignof(a) == sizeof(b)) COMPILE_TIME_ASSERT(alignof(a) == sizeof(b))
#define COMPILE_TIME_ASSERT_ALIGNED1(a) COMPILE_TIME_ASSERT_ALIGNOF__(a,char) #define COMPILE_TIME_ASSERT_ALIGNED1(a) COMPILE_TIME_ASSERT_ALIGNOF__(a, char)
#define TABLESIZE(table) ((sizeof(table)/sizeof((table)[0]))) #define TABLESIZE(table) ((sizeof(table) / sizeof((table)[0])))
// TODO later: move these to upx namespace in util/cxxlib.h; also see bele.h
template <class T>
inline T ALIGN_DOWN(const T &a, const T &b) {
T r;
r = (a / b) * b;
return r;
}
template <class T>
inline T ALIGN_UP(const T &a, const T &b) {
T r;
r = ((a + b - 1) / b) * b;
return r;
}
template <class T>
inline T ALIGN_GAP(const T &a, const T &b) {
T r;
r = ALIGN_UP(a, b) - a;
return r;
}
template <class T> template <class T>
inline T ALIGN_DOWN(const T& a, const T& b) { T r; r = (a / b) * b; return r; } 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 T ALIGN_UP (const T& a, const T& b) { T r; r = ((a + b - 1) / b) * b; return r; } inline const T &UPX_MIN(const T &a, const T &b) {
template <class T> if (a < b)
inline T ALIGN_GAP (const T& a, const T& b) { T r; r = ALIGN_UP(a, b) - a; return r; } return a;
return b;
template <class T> }
inline const T& UPX_MAX(const T& a, const T& b) { if (a < b) return b; return a; }
template <class T>
inline const T& UPX_MIN(const T& a, const T& b) { if (a < b) return a; return b; }
template <class T> template <class T>
inline void mem_clear(T *object) noexcept { inline void mem_clear(T *object) noexcept {
@@ -391,6 +436,7 @@ inline void mem_clear(T *object) noexcept {
static_assert(size >= 1 && size <= UPX_RSIZE_MAX_MEM); static_assert(size >= 1 && size <= UPX_RSIZE_MAX_MEM);
memset((void *) object, 0, size); memset((void *) object, 0, size);
} }
// disable some overloads
#if defined(__clang__) || __GNUC__ != 7 #if defined(__clang__) || __GNUC__ != 7
template <class T> template <class T>
inline void mem_clear(T (&array)[]) noexcept DELETED_FUNCTION; inline void mem_clear(T (&array)[]) noexcept DELETED_FUNCTION;
@@ -401,36 +447,39 @@ 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, n) \ #define Array(type, var, n) \
MemBuffer var ## _membuf(mem_size(sizeof(type), (n))); \ 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, n) Array(byte, var, (n)) #define ByteArray(var, n) Array(byte, var, (n))
// assert_noexcept() // assert_noexcept()
noinline void assertFailed(const char *expr, const char *file, int line, const char *func) noexcept; noreturn 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); noreturn void throwAssertFailed(const char *expr, const char *file, int line, const char *func);
#if defined(__GNUC__) #if defined(__clang__) || defined(__GNUC__)
#undef assert #undef assert
#if DEBUG || 0 #if DEBUG || 0
// generate a warning if assert() is used inside a "noexcept" context // trigger 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))) #define assert(e) \
((void) (__acc_cte(e) || (assertFailed(#e, __FILE__, __LINE__, __func__), throw 1, 0)))
#else #else
// turn assertion failures into exceptions // turn assertion failures into exceptions
#define assert(e) ((void)(__acc_cte(e) || (throwAssertFailed(#e, __FILE__, __LINE__, __func__), throw 1, 0))) #define assert(e) \
((void) (__acc_cte(e) || (throwAssertFailed(#e, __FILE__, __LINE__, __func__), throw 1, 0)))
#endif #endif
#define assert_noexcept(e) ((void)(__acc_cte(e) || (assertFailed(#e, __FILE__, __LINE__, __func__), 0))) #define assert_noexcept(e) \
((void) (__acc_cte(e) || (assertFailed(#e, __FILE__, __LINE__, __func__), 0)))
#else #else
#define assert_noexcept assert #define assert_noexcept assert
#endif #endif
// C++ support library
#include "util/cxxlib.h" #include "util/cxxlib.h"
using upx::is_same_any_v; using upx::is_same_any_v;
using upx::noncopyable; using upx::noncopyable;
using upx::tribool;
using upx::OptVar; using upx::OptVar;
using upx::tribool;
#define usizeof(expr) (upx::UnsignedSizeOf<sizeof(expr)>::value) #define usizeof(expr) (upx::UnsignedSizeOf<sizeof(expr)>::value)
/************************************************************************* /*************************************************************************
// constants // constants
**************************************************************************/ **************************************************************************/
@@ -439,7 +488,7 @@ using upx::OptVar;
#define EXIT_OK 0 #define EXIT_OK 0
#define EXIT_ERROR 1 #define EXIT_ERROR 1
#define EXIT_WARN 2 #define EXIT_WARN 2
//
#define EXIT_USAGE 1 #define EXIT_USAGE 1
#define EXIT_FILE_READ 1 #define EXIT_FILE_READ 1
#define EXIT_FILE_WRITE 1 #define EXIT_FILE_WRITE 1
@@ -448,12 +497,10 @@ using upx::OptVar;
#define EXIT_INIT 1 #define EXIT_INIT 1
#define EXIT_INTERNAL 1 #define EXIT_INTERNAL 1
// magic constants for patching // magic constants for patching
#define UPX_MAGIC_LE32 0x21585055 /* "UPX!" */ #define UPX_MAGIC_LE32 0x21585055 /* "UPX!" */
#define UPX_MAGIC2_LE32 0xD5D0D8A1 #define UPX_MAGIC2_LE32 0xD5D0D8A1
// upx_compress() error codes // upx_compress() error codes
#define UPX_E_OK (0) #define UPX_E_OK (0)
#define UPX_E_ERROR (-1) #define UPX_E_ERROR (-1)
@@ -467,21 +514,20 @@ using upx::OptVar;
#define UPX_E_NOT_YET_IMPLEMENTED (-9) #define UPX_E_NOT_YET_IMPLEMENTED (-9)
#define UPX_E_INVALID_ARGUMENT (-10) #define UPX_E_INVALID_ARGUMENT (-10)
// Executable formats (info: big endian types are >= 128); DO NOT CHANGE // 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
#define UPX_F_DJGPP2_COFF 4 #define UPX_F_DJGPP2_COFF 4
#define UPX_F_WATCOM_LE 5 #define UPX_F_WATCOM_LE 5
//#define UPX_F_VXD_LE 6 // NOT IMPLEMENTED // #define UPX_F_VXD_LE 6 // NOT IMPLEMENTED
#define UPX_F_DOS_EXEH 7 // OBSOLETE #define UPX_F_DOS_EXEH 7 // OBSOLETE
#define UPX_F_TMT_ADAM 8 #define UPX_F_TMT_ADAM 8
#define UPX_F_W32PE_I386 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
//#define UPX_F_LINUX_SEP_i386 13 // NOT IMPLEMENTED // #define UPX_F_LINUX_SEP_i386 13 // NOT IMPLEMENTED
#define UPX_F_LINUX_SH_i386 14 #define UPX_F_LINUX_SH_i386 14
#define UPX_F_VMLINUZ_i386 15 #define UPX_F_VMLINUZ_i386 15
#define UPX_F_BVMLINUZ_i386 16 #define UPX_F_BVMLINUZ_i386 16
@@ -506,16 +552,16 @@ using upx::OptVar;
#define UPX_F_DYLIB_AMD64 35 #define UPX_F_DYLIB_AMD64 35
#define UPX_F_W64PE_AMD64 36 #define UPX_F_W64PE_AMD64 36
#define UPX_F_MACH_ARM64 37 #define UPX_F_MACH_ARM64 37
//#define UPX_F_MACH_PPC64LE 38 // DOES NOT EXIST // #define UPX_F_MACH_PPC64LE 38 // DOES NOT EXIST
#define UPX_F_LINUX_ELF64_PPC64LE 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_ARM64 42
#define UPX_F_W64PE_ARM64 43 // NOT YET IMPLEMENTED #define UPX_F_W64PE_ARM64 43 // NOT YET IMPLEMENTED
#define UPX_F_W64PE_ARM64EC 44 // 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_ELF32_PPC32 132 #define UPX_F_LINUX_ELF32_PPC32 132
#define UPX_F_LINUX_ELF32_ARMEB 133 #define UPX_F_LINUX_ELF32_ARMEB 133
@@ -539,12 +585,13 @@ using upx::OptVar;
#define M_NRV2E_LE32 8 #define M_NRV2E_LE32 8
#define M_NRV2E_8 9 #define M_NRV2E_8 9
#define M_NRV2E_LE16 10 #define M_NRV2E_LE16 10
//#define M_CL1B_LE32 11 // #define M_CL1B_LE32 11
//#define M_CL1B_8 12 // #define M_CL1B_8 12
//#define M_CL1B_LE16 13 // #define M_CL1B_LE16 13
#define M_LZMA 14 #define M_LZMA 14
#define M_DEFLATE 15 // zlib #define M_DEFLATE 15 // NOT YET USED
#define M_ZSTD 16 #define M_ZSTD 16 // NOT YET USED
#define M_BZIP2 17 // NOT YET USED
// compression methods internal usage // compression methods internal usage
#define M_ALL (-1) #define M_ALL (-1)
#define M_END (-2) #define M_END (-2)
@@ -555,11 +602,11 @@ using upx::OptVar;
#define M_IS_NRV2B(x) ((x) >= M_NRV2B_LE32 && (x) <= M_NRV2B_LE16) #define M_IS_NRV2B(x) ((x) >= M_NRV2B_LE32 && (x) <= M_NRV2B_LE16)
#define M_IS_NRV2D(x) ((x) >= M_NRV2D_LE32 && (x) <= M_NRV2D_LE16) #define M_IS_NRV2D(x) ((x) >= M_NRV2D_LE32 && (x) <= M_NRV2D_LE16)
#define M_IS_NRV2E(x) ((x) >= M_NRV2E_LE32 && (x) <= M_NRV2E_LE16) #define M_IS_NRV2E(x) ((x) >= M_NRV2E_LE32 && (x) <= M_NRV2E_LE16)
//#define M_IS_CL1B(x) ((x) >= M_CL1B_LE32 && (x) <= M_CL1B_LE16) // #define M_IS_CL1B(x) ((x) >= M_CL1B_LE32 && (x) <= M_CL1B_LE16)
#define M_IS_LZMA(x) (((x) & 255) == M_LZMA) #define M_IS_LZMA(x) (((x) &255) == M_LZMA)
#define M_IS_DEFLATE(x) ((x) == M_DEFLATE) #define M_IS_DEFLATE(x) ((x) == M_DEFLATE)
#define M_IS_ZSTD(x) ((x) == M_ZSTD) #define M_IS_ZSTD(x) ((x) == M_ZSTD)
#define M_IS_BZIP2(x) ((x) == M_BZIP2)
// filters internal usage // filters internal usage
#define FT_END (-1) #define FT_END (-1)
@@ -567,7 +614,6 @@ using upx::OptVar;
#define FT_SKIP (-3) #define FT_SKIP (-3)
#define FT_ULTRA_BRUTE (-4) #define FT_ULTRA_BRUTE (-4)
/************************************************************************* /*************************************************************************
// compression - setup and callback_t // compression - setup and callback_t
**************************************************************************/ **************************************************************************/
@@ -576,35 +622,38 @@ using upx::OptVar;
#define WITH_UCL 1 #define WITH_UCL 1
#define WITH_ZLIB 1 #define WITH_ZLIB 1
#if (WITH_UCL) #if (WITH_UCL)
# define ucl_compress_config_t REAL_ucl_compress_config_t #define ucl_compress_config_t REAL_ucl_compress_config_t
# include <ucl/include/ucl/uclconf.h> #include <ucl/include/ucl/uclconf.h>
# include <ucl/include/ucl/ucl.h> #include <ucl/include/ucl/ucl.h>
# undef ucl_compress_config_t #undef ucl_compress_config_t
# undef ucl_compress_config_p #undef ucl_compress_config_p
#endif #endif
struct upx_callback_t; struct upx_callback_t;
typedef upx_callback_t *upx_callback_p; typedef void(__acc_cdecl *upx_progress_func_t)(upx_callback_t *, unsigned, unsigned);
typedef void (__acc_cdecl *upx_progress_func_t)
(upx_callback_p, unsigned, unsigned);
struct upx_callback_t { struct upx_callback_t final {
upx_progress_func_t nprogress; upx_progress_func_t nprogress;
void *user; void *user;
void reset() noexcept { mem_clear(this); } void reset() noexcept { mem_clear(this); }
}; };
/************************************************************************* /*************************************************************************
// compression - config_t // compression - config_t
**************************************************************************/ **************************************************************************/
struct lzma_compress_config_t { struct bzip2_compress_config_t final {
unsigned dummy;
void reset() noexcept;
};
struct lzma_compress_config_t final {
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
typedef OptVar<unsigned, (1u<<22), 1u, (1u<<30) > dict_size_t; typedef OptVar<unsigned, (1u << 22), 1u, (1u << 30)> dict_size_t;
typedef OptVar<unsigned, 64u, 5u, 273u> num_fast_bytes_t; typedef OptVar<unsigned, 64u, 5u, 273u> num_fast_bytes_t;
pos_bits_t pos_bits; // pb pos_bits_t pos_bits; // pb
@@ -620,11 +669,11 @@ struct lzma_compress_config_t {
void reset() noexcept; void reset() noexcept;
}; };
struct ucl_compress_config_t : public REAL_ucl_compress_config_t { struct ucl_compress_config_t final : public REAL_ucl_compress_config_t {
void reset() noexcept { memset(this, 0xff, sizeof(*this)); } void reset() noexcept { memset(this, 0xff, sizeof(*this)); }
}; };
struct zlib_compress_config_t { struct zlib_compress_config_t final {
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
@@ -636,29 +685,41 @@ struct zlib_compress_config_t {
void reset() noexcept; void reset() noexcept;
}; };
struct zstd_compress_config_t { struct zstd_compress_config_t final {
unsigned dummy; unsigned dummy;
void reset() noexcept; void reset() noexcept;
}; };
struct upx_compress_config_t { struct upx_compress_config_t final {
bzip2_compress_config_t conf_bzip2;
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() noexcept { conf_lzma.reset(); conf_ucl.reset(); conf_zlib.reset(); conf_zstd.reset(); } void reset() noexcept {
conf_bzip2.reset();
conf_lzma.reset();
conf_ucl.reset();
conf_zlib.reset();
conf_zstd.reset();
}
}; };
#define NULL_cconf ((upx_compress_config_t *) nullptr) #define NULL_cconf ((const upx_compress_config_t *) nullptr)
/************************************************************************* /*************************************************************************
// compression - result_t // compression - result_t
**************************************************************************/ **************************************************************************/
struct lzma_compress_result_t { struct bzip2_compress_result_t final {
unsigned dummy;
void reset() noexcept { mem_clear(this); }
};
struct lzma_compress_result_t final {
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
@@ -671,25 +732,25 @@ struct lzma_compress_result_t {
void reset() noexcept { mem_clear(this); } void reset() noexcept { mem_clear(this); }
}; };
struct ucl_compress_result_t { struct ucl_compress_result_t final {
ucl_uint result[16]; ucl_uint result[16];
void reset() noexcept { mem_clear(this); } void reset() noexcept { mem_clear(this); }
}; };
struct zlib_compress_result_t { struct zlib_compress_result_t final {
unsigned dummy; unsigned dummy;
void reset() noexcept { mem_clear(this); } void reset() noexcept { mem_clear(this); }
}; };
struct zstd_compress_result_t { struct zstd_compress_result_t final {
unsigned dummy; unsigned dummy;
void reset() noexcept { mem_clear(this); } void reset() noexcept { mem_clear(this); }
}; };
struct upx_compress_result_t { struct upx_compress_result_t final {
// debugging aid // debugging aid
struct Debug { struct Debug {
int method, level; int method, level;
@@ -698,6 +759,7 @@ struct upx_compress_result_t {
}; };
Debug debug; Debug debug;
bzip2_compress_result_t result_bzip2;
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;
@@ -705,30 +767,33 @@ struct upx_compress_result_t {
void reset() noexcept { void reset() noexcept {
debug.reset(); debug.reset();
result_lzma.reset(); result_ucl.reset(); result_zlib.reset(); result_zstd.reset(); result_bzip2.reset();
result_lzma.reset();
result_ucl.reset();
result_zlib.reset();
result_zstd.reset();
} }
}; };
/************************************************************************* /*************************************************************************
// globals // globals
**************************************************************************/ **************************************************************************/
// classes // classes
class ElfLinker; class ElfLinker;
typedef ElfLinker Linker; typedef ElfLinker Linker; // shortcut
class Throwable; class Throwable;
// check/dt_check.cpp
noinline void upx_compiler_sanity_check() noexcept;
noinline int upx_doctest_check(int argc, char **argv);
int upx_doctest_check();
// util/membuffer.h // util/membuffer.h
class MemBuffer; class MemBuffer;
void *membuffer_get_void_ptr(MemBuffer &mb) noexcept; void *membuffer_get_void_ptr(MemBuffer &mb) noexcept;
unsigned membuffer_get_size(MemBuffer &mb) noexcept; unsigned membuffer_get_size(MemBuffer &mb) noexcept;
// util/dt_check.cpp
noinline void upx_compiler_sanity_check() noexcept;
noinline int upx_doctest_check(int argc, char **argv);
int upx_doctest_check();
// main.cpp // main.cpp
extern const char *progname; extern const char *progname;
bool main_set_exit_code(int ec); bool main_set_exit_code(int ec);
@@ -757,36 +822,35 @@ int do_files(int i, int argc, char *argv[]) may_throw;
// help.cpp // help.cpp
extern const char gitrev[]; extern const char gitrev[];
void show_header(); void show_header();
void show_help(int verbose=0); void show_help(int verbose);
void show_license(); void show_license();
void show_sysinfo(const char *options_var); void show_sysinfo(const char *options_var);
void show_usage(); void show_usage();
void show_version(bool one_line=false); void show_version(bool one_line = false);
// compress/compress.cpp // compress/compress.cpp
unsigned upx_adler32(const void *buf, unsigned len, unsigned adler=1);
unsigned upx_crc32 (const void *buf, unsigned len, unsigned crc=0);
// clang-format off // clang-format off
unsigned upx_adler32(const void *buf, unsigned len, unsigned adler = 1);
unsigned upx_crc32 (const void *buf, unsigned len, unsigned crc = 0);
int upx_compress ( const upx_bytep src, unsigned src_len, int upx_compress ( const upx_bytep src, unsigned src_len,
upx_bytep dst, unsigned* dst_len, upx_bytep dst, unsigned *dst_len,
upx_callback_p cb, upx_callback_t *cb,
int method, int level, int method, int level,
const upx_compress_config_t *cconf, const upx_compress_config_t *cconf,
upx_compress_result_t *cresult ); upx_compress_result_t *cresult );
int upx_decompress ( const upx_bytep src, unsigned src_len, int upx_decompress ( const upx_bytep src, unsigned src_len,
upx_bytep dst, unsigned* dst_len, upx_bytep dst, unsigned *dst_len,
int method, int method,
const upx_compress_result_t *cresult ); const upx_compress_result_t *cresult );
int upx_test_overlap ( const upx_bytep buf, int upx_test_overlap ( const upx_bytep buf,
const upx_bytep tbuf, const upx_bytep tbuf,
unsigned src_off, unsigned src_len, unsigned src_off, unsigned src_len,
unsigned* dst_len, unsigned *dst_len,
int method, int method,
const upx_compress_result_t *cresult ); const upx_compress_result_t *cresult );
// clang-format on // clang-format on
#include "util/snprintf.h" // must get included first! #include "util/snprintf.h" // must get included first!
#include "util/util.h" #include "util/util.h"
#include "options.h" #include "options.h"
@@ -797,5 +861,4 @@ int upx_test_overlap ( const upx_bytep buf,
#include "util/raw_bytes.h" #include "util/raw_bytes.h"
#include "util/xspan.h" #include "util/xspan.h"
/* vim:set ts=4 sw=4 et: */ /* vim:set ts=4 sw=4 et: */
+2 -2
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer Copyright (C) 1996-2024 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2023 Laszlo Molnar Copyright (C) 1996-2024 Laszlo Molnar
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
+2 -2
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer Copyright (C) 1996-2024 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2023 Laszlo Molnar Copyright (C) 1996-2024 Laszlo Molnar
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
+2 -2
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer Copyright (C) 1996-2024 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2023 Laszlo Molnar Copyright (C) 1996-2024 Laszlo Molnar
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
+2 -2
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer Copyright (C) 1996-2024 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2023 Laszlo Molnar Copyright (C) 1996-2024 Laszlo Molnar
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
+2 -2
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer Copyright (C) 1996-2024 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2023 Laszlo Molnar Copyright (C) 1996-2024 Laszlo Molnar
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
+2 -2
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer Copyright (C) 1996-2024 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2023 Laszlo Molnar Copyright (C) 1996-2024 Laszlo Molnar
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
+2 -2
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer Copyright (C) 1996-2024 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2023 Laszlo Molnar Copyright (C) 1996-2024 Laszlo Molnar
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
+2 -2
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer Copyright (C) 1996-2024 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2023 Laszlo Molnar Copyright (C) 1996-2024 Laszlo Molnar
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
+7 -7
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer Copyright (C) 1996-2024 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2023 Laszlo Molnar Copyright (C) 1996-2024 Laszlo Molnar
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
@@ -25,6 +25,11 @@
<markus@oberhumer.com> <ezerotven+github@gmail.com> <markus@oberhumer.com> <ezerotven+github@gmail.com>
*/ */
#define WANT_WINDOWS_LEAN_H 1
#include "../util/system_headers.h"
#if (HAVE_CONIO_H)
#include <conio.h>
#endif
#include "../conf.h" #include "../conf.h"
#if (USE_SCREEN_WIN32) #if (USE_SCREEN_WIN32)
@@ -33,11 +38,6 @@
// direct screen access // direct screen access
**************************************************************************/ **************************************************************************/
#include "../util/windows_lean.h"
#if (HAVE_CONIO_H)
#include <conio.h>
#endif
#include "screen.h" #include "screen.h"
#define this self #define this self
+2 -2
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer Copyright (C) 1996-2024 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2023 Laszlo Molnar Copyright (C) 1996-2024 Laszlo Molnar
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
+35 -23
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer Copyright (C) 1996-2024 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2023 Laszlo Molnar Copyright (C) 1996-2024 Laszlo Molnar
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
@@ -31,39 +31,41 @@
// //
**************************************************************************/ **************************************************************************/
/*static*/ upx_std_atomic(size_t) Throwable::debug_counter; /*static*/ Throwable::Stats Throwable::stats;
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),
err(e), err(e),
is_warning(w) { is_warning(w) {
if (m) if (m != nullptr) {
msg = strdup(m); msg = strdup(m);
#if 0 assert_noexcept(msg != nullptr);
fprintf(stderr, "construct exception: %s %zu\n", msg, debug_counter); }
debug_counter += 1; NO_fprintf(stderr, "construct exception: %zu %zu %s\n", size_t(stats.counter_current),
#endif size_t(stats.counter_total), (const char *) msg);
stats.counter_current += 1;
stats.counter_total += 1;
} }
Throwable::Throwable(const Throwable &other) noexcept : super(other), Throwable::Throwable(const Throwable &other) noexcept : super(other),
msg(nullptr), msg(nullptr),
err(other.err), err(other.err),
is_warning(other.is_warning) { is_warning(other.is_warning) {
if (other.msg) if (other.msg != nullptr) {
msg = strdup(other.msg); msg = strdup(other.msg);
#if 0 assert_noexcept(msg != nullptr);
fprintf(stderr, "copy exception: %s %zu\n", msg, debug_counter); }
debug_counter += 1; NO_fprintf(stderr, "copy construct exception: %zu %zu %s\n", size_t(stats.counter_current),
#endif size_t(stats.counter_total), (const char *) msg);
stats.counter_current += 1;
stats.counter_total += 1;
} }
Throwable::~Throwable() noexcept { Throwable::~Throwable() noexcept {
#if 0 stats.counter_current -= 1;
debug_counter -= 1; NO_fprintf(stderr, "destruct exception: %zu %zu %s\n", size_t(stats.counter_current),
fprintf(stderr, "destruct exception: %s %zu\n", msg, debug_counter); size_t(stats.counter_total), (const char *) msg);
#endif upx::owner_free(msg);
if (msg)
free(msg);
} }
/************************************************************************* /*************************************************************************
@@ -150,7 +152,7 @@ void throwCantPack(const char *format, ...) {
char msg[1024]; char msg[1024];
va_list ap; va_list ap;
va_start(ap, format); va_start(ap, format);
(void) upx_safe_vsnprintf(msg, sizeof(msg), format, ap); (void) upx_safe_vsnprintf_noexcept(msg, sizeof(msg), format, ap);
va_end(ap); va_end(ap);
throwCantPack(msg); throwCantPack(msg);
} }
@@ -160,7 +162,17 @@ void throwCantUnpack(const char *format, ...) {
char msg[1024]; char msg[1024];
va_list ap; va_list ap;
va_start(ap, format); va_start(ap, format);
(void) upx_safe_vsnprintf(msg, sizeof(msg), format, ap); (void) upx_safe_vsnprintf_noexcept(msg, sizeof(msg), format, ap);
va_end(ap);
throwCantUnpack(msg);
}
template <>
void throwInternalError(const char *format, ...) {
char msg[1024];
va_list ap;
va_start(ap, format);
(void) upx_safe_vsnprintf_noexcept(msg, sizeof(msg), format, ap);
va_end(ap); va_end(ap);
throwCantUnpack(msg); throwCantUnpack(msg);
} }
@@ -183,7 +195,7 @@ void throwAssertFailed(const char *expr, const char *file, int line, const char
} }
} }
const char *prettyName(const char *n) noexcept { const char *prettyExceptionName(const char *n) noexcept {
if (n == nullptr) if (n == nullptr)
return "(null)"; return "(null)";
while (*n) { while (*n) {
@@ -191,7 +203,7 @@ const char *prettyName(const char *n) noexcept {
n++; n++;
else if (*n == ' ') else if (*n == ' ')
n++; n++;
else if (strncmp(n, "class ", 6) == 0) // Visual C++ (msvc) else if (strncmp(n, "class ", 6) == 0) // Visual C++ (MSVC)
n += 6; n += 6;
else else
break; break;

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