Compare commits

..

112 Commits

Author SHA1 Message Date
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
Markus F.X.J. Oberhumer 9c46f4653f all: prepare for release 2023-10-26 11:09:48 +02:00
Markus F.X.J. Oberhumer 29b4752d0e src: add some noexcept 2023-10-26 00:28:36 +02:00
Markus F.X.J. Oberhumer 2724039c09 submodules: update for new versions 2023-10-26 00:23:57 +02:00
Markus F.X.J. Oberhumer 6ae4e88475 cmake: fix Xcode generator build 2023-10-25 06:47:09 +02:00
Markus F.X.J. Oberhumer facabd68d7 all: more minor cleanups 2023-10-24 23:56:55 +02:00
Markus F.X.J. Oberhumer 18f043015e all: minor cleanups 2023-10-24 22:54:54 +02:00
Markus F.X.J. Oberhumer ab259a1af9 src/pefile: try to clean up reloc handling 2023-10-24 11:47:23 +02:00
Markus F.X.J. Oberhumer 1dd96a7628 src/pefile: stricter reloc checks; cleanups 2023-10-23 14:26:37 +02:00
Markus F.X.J. Oberhumer 1ee7ecb1f0 all: prefer using utimensat() 2023-10-22 13:29:26 +02:00
Markus F.X.J. Oberhumer 67548a4d9a src: minor cleanups 2023-10-22 00:45:06 +02:00
Markus F.X.J. Oberhumer 9fbe95ad48 all: cleanups 2023-10-21 11:22:18 +02:00
dependabot[bot] 91c15b2475 build(deps): bump crate-ci/typos from 1.16.19 to 1.16.20
Bumps [crate-ci/typos](https://github.com/crate-ci/typos) from 1.16.19 to 1.16.20.
- [Release notes](https://github.com/crate-ci/typos/releases)
- [Changelog](https://github.com/crate-ci/typos/blob/master/CHANGELOG.md)
- [Commits](https://github.com/crate-ci/typos/compare/35a8bc67870d6c0b7407683319ae175577e24261...c004e98018d8621614d1ca516eed8ca2d04b365a)

---
updated-dependencies:
- dependency-name: crate-ci/typos
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-10-18 16:00:48 +00:00
Markus F.X.J. Oberhumer c9550b48d8 all: disable packing macOS binaries for now 2023-10-18 07:04:00 +02:00
Markus F.X.J. Oberhumer a1d090a6fd src/stub: add a "clang-format off" directive 2023-10-15 10:55:15 +02:00
Markus F.X.J. Oberhumer 4870765e1b all: disable packing macOS binaries for now 2023-10-15 10:15:46 +02:00
Markus F.X.J. Oberhumer d8be2ed276 src/pefile.cpp: cleanup reloc handling and add more checks 2023-10-14 19:24:44 +02:00
Markus F.X.J. Oberhumer 2b371e99bd src/util: minor xspan enhancements 2023-10-14 05:58:47 +02:00
Markus F.X.J. Oberhumer 005e39871b CI updates 2023-10-13 00:49:01 +02:00
Markus F.X.J. Oberhumer 96dd9eeb44 CI updates 2023-10-13 00:01:00 +02:00
John Reiser 65b06f6046 More LZMA inSize (srclen) defense
https://github.com/upx/upx/issues/717

	modified:   stub/src/amd64-darwin.dylib-entry.S  fixed
	modified:   stub/src/amd64-darwin.macho-entry.S  fixed
	modified:   stub/src/amd64-linux.elf-so_entry.S  comment-only
	modified:   stub/src/i386-linux.elf-so_entry.S  comment-only

	modified:   stub/amd64-darwin.dylib-entry.h
	modified:   stub/amd64-darwin.macho-entry.h
	modified:   stub/amd64-linux.elf-so_entry.h
	modified:   stub/tmp/amd64-darwin.dylib-entry.bin.dump
	modified:   stub/tmp/amd64-darwin.macho-entry.bin.dump
	modified:   stub/tmp/amd64-linux.elf-so_entry.bin.dump

Find+fix steps that were performed:
1. Find all 'add' instructions that compute "eof".
NRV run-time decompressors ignore srclen, so 'add' can be ignored for them.

$ cd upx-devel4/src/stub
$ grep -sr 'add.*eof' src  |  grep -v 'nrv2._d.*.S'  |  sort
src/amd64-darwin.dylib-entry.S:        addq src,lsrc; push lsrc  // &input_eof
src/amd64-darwin.macho-entry.S:        addq src,lsrc; push lsrc  // &input_eof
src/amd64-linux.elf-entry.S:        addq src,lsrc; push lsrc  // &input_eof
src/amd64-linux.elf-so_entry.S:        addq src,lsrc; push lsrc  // MATCH_05  &input_eof
src/amd64-linux.elf-so_main.c:            void *mfd_addr = Pmap(0, sizeof(code), PROT_READ|PROT_EXEC, MAP_PRIVATE, mfd, 0);
src/amd64-linux.shlib-init.S:        addq src,lsrc; push lsrc  // &input_eof
src/arch/amd64/lzma_d.S://      addq src,lsrc; push lsrc  // &input_eof
src/i386-expand.S:    add src,%ecx; push %ecx  // MATCH_52  eof_src
src/i386-linux.elf-so_entry.S:        add src,lsrc; push lsrc  // MATCH_05  &input_eof

2.  Case-by-case inspection

src/amd64-darwin.dylib-entry.S:        addq src,lsrc; push lsrc  // &input_eof
    restoring 'subq' is added in this commit

src/amd64-darwin.macho-entry.S:        addq src,lsrc; push lsrc  // &input_eof
    restoring 'subq' is added in this commit

src/amd64-linux.elf-entry.S:        addq src,lsrc; push lsrc  // &input_eof
    a restoring 'subq' is already next

src/amd64-linux.elf-so_entry.S:        addq src,lsrc; push lsrc  // MATCH_05  &input_eof
    lsrc is dead for inlined nrv2b

src/amd64-linux.elf-so_main.c:            void *mfd_addr = Pmap(0, sizeof(code), PROT_READ|PROT_EXEC, MAP_PRIVATE, mfd, 0);
    .c code

src/amd64-linux.shlib-init.S:        addq src,lsrc; push lsrc  // &input_eof
    restoring 'subq' is already next

src/arch/amd64/lzma_d.S://      addq src,lsrc; push lsrc  // &input_eof
    comment that explains preceding actions in ELFMAINX; a restoring 'subq' is already next

src/i386-expand.S:    add src,%ecx; push %ecx  // MATCH_52  eof_src
    %ecx is dead

src/i386-linux.elf-so_entry.S:        add src,lsrc; push lsrc  // MATCH_05  &input_eof
    lsrc is dead for inlined nrv2b
2023-10-12 10:41:13 -07:00
John Reiser 0515be4334 LZMA on AMD64 had bug in calling sequence, leading to random exit(127)
LzmaDecode randomly decided that the input had ended in the middle,
because of error in interface between ELFMAINX and the decoder.

Thanks to Kevin Gosse!
https://github.com/upx/upx/pull/716
https://github.com/MichalStrehovsky/PublishAotCompressed/issues/11
2023-10-06 14:14:32 -07:00
Markus F.X.J. Oberhumer e32de83758 CI updates 2023-10-05 12:23:17 +02:00
Markus F.X.J. Oberhumer e767461f65 src: more clang-format 2023-10-05 11:53:02 +02:00
Markus F.X.J. Oberhumer 632c7c4826 all: assorted cleanups; introduce undocumented '--sysinfo' option 2023-10-05 03:51:27 +02:00
Markus F.X.J. Oberhumer 7f9d381c7b CI updates 2023-09-30 10:46:39 +02:00
Markus F.X.J. Oberhumer 4d5d6661d5 submodules: update for new versions 2023-09-30 09:44:58 +02:00
John Reiser b0b87eda02 check-whitespace
modified:   stub/src/upxfd_android.c
2023-09-28 12:49:14 -07:00
John Reiser f63a673a8b Prepare to emulate memfd_create() on 32-bit Android (ARM and i386)
modified:   stub/src/include/linux.h
	new file:   stub/src/upxfd_android.c
	new file:   stub/src/upxfd_create.c
2023-09-28 12:44:49 -07:00
John Reiser 290dd0c5d2 Git straggler
modified:   src/stub/tmp/i386-linux.elf-entry.bin.dump
2023-09-28 12:09:32 -07:00
John Reiser 194bf2b852 Common prototypes for mmap and ftruncate
modified:   src/stub/src/include/linux.h
	modified:   src/stub/src/amd64-linux.elf-so_main.c
	modified:   src/stub/src/i386-linux.elf-so_main.c
	modified:   src/stub/src/i386-linux.elf.execve-main.c
	modified:   src/stub/src/i386-linux.elf.interp-main.c
	modified:   src/stub/src/i386-linux.elf.shell-main.c
2023-09-28 12:07:04 -07:00
John Reiser d6d5e7ae3d For Android emulator: align i386 LEXEC020 binfo
modified:   src/stub/src/i386-linux.elf-entry.S
	modified:   src/p_lx_elf.cpp

	modified:   src/stub/i386-linux.elf-entry.h
	modified:   misc/testsuite/upx_testsuite_1-expected_sha256sums.sh
2023-09-28 12:02:28 -07:00
Markus F.X.J. Oberhumer 39a6cc4b5f src: improve memory sanitizer handling 2023-09-26 15:15:55 +02:00
Markus F.X.J. Oberhumer a24de15060 submodules: update for new versions 2023-09-26 15:15:55 +02:00
Markus F.X.J. Oberhumer eb021accd1 CI updates 2023-09-25 13:47:43 +02:00
Markus F.X.J. Oberhumer 98a77dde00 CI updates 2023-09-22 17:33:22 +02:00
John Reiser 854988bc5f Detect AlreadyPacked even when trailing PackHeader has been lopped.
This is heuristic, but strong.
https://github.com/upx/upx/issues/712
	modified:   p_lx_elf.cpp
	modified:   p_unix.h
2023-09-21 14:12:18 -07:00
John Reiser bfeed2ab9a MAP_PRIVATE to capture memfd pages before closing the fd
https://github.com/upx/upx/issues/710

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

	modified:   stub/amd64-linux.elf-so_fold.h
	modified:   stub/arm.v4a-linux.elf-so_fold.h
	modified:   stub/arm.v5a-linux.elf-so_fold.h
	modified:   stub/arm64-linux.elf-so_fold.h
	modified:   stub/i386-linux.elf-so_fold.h
2023-09-20 13:12:04 -07:00
Markus F.X.J. Oberhumer d11fc71e79 CI updates 2023-09-20 11:24:55 +02:00
Markus F.X.J. Oberhumer f1703fa322 CI updates 2023-09-19 11:47:15 +02:00
Markus F.X.J. Oberhumer 06675acc67 all: cosmetic cleanups 2023-09-18 15:19:37 +02:00
Markus F.X.J. Oberhumer 57ad6bc37d CI updates 2023-09-11 06:52:57 +02:00
dependabot[bot] 0192b0b7e4 build(deps): bump actions/checkout from 3 to 4 (#707)
Bumps [actions/checkout](https://github.com/actions/checkout) from 3 to 4.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/checkout/compare/v3...v4)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-09-06 18:54:02 +02:00
Markus F.X.J. Oberhumer 3b098b845a CI updates 2023-09-06 12:48:30 +02:00
Markus F.X.J. Oberhumer ac398f1ffe CI updates 2023-09-06 01:48:20 +02:00
Markus F.X.J. Oberhumer 92dfb9c83c testsuite: add file system test suite test_symlinks.sh 2023-09-06 00:09:44 +02:00
Markus F.X.J. Oberhumer 38d6cb090c src/packer.cpp: fix bug in constructor introduced during cleanup
Introduced in 10e759f1f1
2023-09-05 21:09:17 +02:00
Markus F.X.J. Oberhumer e93172bd33 src/work.cpp: clean up get_open_flags() 2023-09-05 06:09:13 +02:00
Markus F.X.J. Oberhumer 30fcca4b64 src: optimize preserve_link: only if the file has actual link-count >= 2 2023-09-05 05:50:47 +02:00
Markus F.X.J. Oberhumer 4f6320d3aa src: add new option --link to preserve hard links; use with care 2023-09-04 22:34:21 +02:00
Markus F.X.J. Oberhumer 62dbf8485f src: sort cleanups 2023-09-04 07:28:48 +02:00
John Reiser 9331ed39d4 32-bit Android lacks memfd_create, and has varying __NR_ftruncate
https://github.com/upx/upx/issues/700
	modified:   stub/src/i386-linux.elf-so_main.c
	modified:   stub/src/arm.v4a-linux.elf-so_entry.S
	modified:   stub/src/arm.v4a-linux.elf-so_fold.S

	modified:   stub/arm.v4a-linux.elf-so_entry.h
	modified:   stub/arm.v4a-linux.elf-so_fold.h
	modified:   stub/arm.v5a-linux.elf-so_entry.h
	modified:   stub/arm.v5a-linux.elf-so_fold.h
2023-09-02 15:31:32 -07:00
Markus F.X.J. Oberhumer 35dd9cfd22 src: retract libc qsort() requirements 2023-09-02 16:15:57 +02:00
Markus F.X.J. Oberhumer 0ac6c36af2 src: add a check for libc qsort(); cleanups 2023-09-01 11:59:29 +02:00
Markus F.X.J. Oberhumer 3c4b959f78 all: update clang-format settings 2023-09-01 11:29:51 +02:00
Markus F.X.J. Oberhumer a00687b092 src/p_mach.cpp: make sort order deterministic 2023-09-01 11:11:00 +02:00
Markus F.X.J. Oberhumer bb6b087862 src: implement upx_shellsort() 2023-09-01 10:49:47 +02:00
John Reiser bfb438dc89 Sync stubs
modified:   stub/amd64-linux.elf-so_fold.h
	modified:   stub/arm.v4a-linux.elf-so_fold.h
	modified:   stub/arm.v5a-linux.elf-so_fold.h
	modified:   stub/arm64-linux.elf-so_fold.h
	modified:   stub/i386-linux.elf-so_fold.h
	modified:   stub/tmp/amd64-linux.elf-so_fold.bin.dump
2023-08-31 13:34:49 -07:00
John Reiser cd3f69c290 Explicit write() can subsume ftruncate()
modified:   stub/src/amd64-linux.elf-so_main.c
	modified:   stub/src/i386-linux.elf-so_main.c
2023-08-31 13:25:53 -07:00
Markus F.X.J. Oberhumer d54315392e src: add support for NO_COLOR environment variable 2023-08-31 12:31:31 +02:00
Markus F.X.J. Oberhumer cfa8107ab9 src: make sort order deterministic, next try
We cannot compare pointers as they may point to qsort-local objects.
And we must make sure that cmp(a,b) always agrees with cmp(b,a).
2023-08-30 16:41:59 +02:00
Markus F.X.J. Oberhumer f4e5b29708 src: make sort order deterministic 2023-08-28 02:08:34 +02:00
Markus F.X.J. Oberhumer d65fea1147 src/bele.h: try to detect possible size-mismatches 2023-08-28 00:23:53 +02:00
Markus F.X.J. Oberhumer 25a3c109c1 CI updates 2023-08-27 13:30:51 +02:00
John Reiser b526eed346 Detect "no Shdrs" earlier when already packed
https://github.com/upx/upx/issues/699
	modified:   p_lx_elf.cpp
2023-08-23 19:52:35 +02:00
John Reiser 59c6a71b72 More use of ph_forced_method()
modified:   p_lx_elf.cpp
2023-08-23 19:52:35 +02:00
John Reiser c7a2a0faa1 Document path to mach-o/loader.h on Apple CommandLineTools
modified:   p_mach_enum.h
2023-08-23 19:52:35 +02:00
John Reiser bfb5ea50a9 Temporary
modified:   p_lx_elf.cpp
2023-08-23 19:52:35 +02:00
John Reiser 149d84edca --brute versus forced_method(ph.method)
https://github.com/upx/upx/issues/694  (partial)
	modified:   p_lx_elf.cpp
2023-08-23 19:52:35 +02:00
Markus F.X.J. Oberhumer 7636abc158 CI updates 2023-08-22 11:12:48 +02:00
Markus F.X.J. Oberhumer 6eace187e7 src: add a famous quote 2023-08-22 00:37:45 +02:00
Markus F.X.J. Oberhumer dd1838a7eb src: minor cleanups 2023-08-21 22:41:42 +02:00
Markus F.X.J. Oberhumer dd928cf956 src: update MemBuffer::getSizeForCompression() 2023-08-21 22:32:28 +02:00
Markus F.X.J. Oberhumer 38be230467 submodules: update for new versions 2023-08-21 22:28:25 +02:00
Markus F.X.J. Oberhumer 1f747a28a9 all: spell check 2023-08-17 12:55:38 +02:00
Markus F.X.J. Oberhumer 1a7732b285 CI update: add ASAN/MSAN/valgrind checks 2023-08-17 12:07:19 +02:00
Markus F.X.J. Oberhumer f8ea416a4d src/pefile.cpp: fix a pedantic ASAN error 2023-08-17 00:08:03 +02:00
Markus F.X.J. Oberhumer b9bf81d548 src/p_lx_elf.cpp: init o_binfo to avoid crash with MSAN build
This should be double-checked by @jreiser
2023-08-16 22:23:28 +02:00
Markus F.X.J. Oberhumer 8975e2a6b5 src: create util/cxxlib.h 2023-08-16 10:05:59 +02:00
Markus F.X.J. Oberhumer 394cd77bec all: cleanups 2023-08-16 01:06:52 +02:00
Markus F.X.J. Oberhumer a9ac4b5e23 src: introduce type tribool 2023-08-15 14:44:50 +02:00
Markus F.X.J. Oberhumer 10e759f1f1 src: minor cleanups 2023-08-11 13:32:53 +02:00
Markus F.X.J. Oberhumer 777d4f5279 src: refactoring: create packhead.h and move some methods 2023-08-11 03:57:20 +02:00
Markus F.X.J. Oberhumer c65c882ecc src: class Packer decomposition, introduce PackerBase 2023-08-10 20:40:27 +02:00
Markus F.X.J. Oberhumer a66ee9fafd CI update 2023-08-09 21:08:04 +02:00
Markus F.X.J. Oberhumer 757401dd0c CI and spell checks 2023-08-09 13:08:38 +02:00
Markus F.X.J. Oberhumer 11e3770864 CI updates 2023-08-08 15:57:45 +02:00
Markus F.X.J. Oberhumer fbb317e9c8 submodules: update for new versions 2023-08-08 12:54:11 +02:00
Markus F.X.J. Oberhumer 9d7698a359 testsuite: update checksums caused by version bump 2023-08-08 12:46:17 +02:00
Markus F.X.J. Oberhumer 44fd11f4dd all: post-release version bump 2023-08-08 12:43:47 +02:00
326 changed files with 22209 additions and 19210 deletions
+1
View File
@@ -8,6 +8,7 @@ IndentWidth: 4
--- ---
Language: Cpp Language: Cpp
AccessModifierOffset: -4 AccessModifierOffset: -4
AlignConsecutiveMacros: AcrossComments
AlwaysBreakTemplateDeclarations: true AlwaysBreakTemplateDeclarations: true
AttributeMacros: AttributeMacros:
- __acc_cdecl - __acc_cdecl
-1
View File
@@ -1,5 +1,4 @@
version: 2 version: 2
updates: updates:
- package-ecosystem: 'github-actions' - package-ecosystem: 'github-actions'
directory: '/' directory: '/'
+5 -4
View File
@@ -4,21 +4,22 @@
# tricky, so some false positives are fine # tricky, so some false positives are fine
[files] [files]
extend-exclude = ["LICENSE", "misc/*/packages.txt", "misc/*/*/packages.txt"] extend-exclude = ["LICENSE", "misc/*podman*/*/packages.txt"]
[default.extend-identifiers]
# misc variable names & symbols # misc variable names & symbols
[default.extend-identifiers]
acc_spawnve = "acc_spawnve" acc_spawnve = "acc_spawnve"
ba = "ba" ba = "ba"
fo = "fo" fo = "fo"
fof = "fof" fof = "fof"
O_WRONLY = "O_WRONLY" O_WRONLY = "O_WRONLY"
# clang-analyzer-optin.cplusplus # optin: clang-analyzer-optin.cplusplus
optin = "optin" optin = "optin"
sidelen = "sidelen" sidelen = "sidelen"
# macOS 11 "Big Sur"
Sur = "Sur"
tpos = "tpos" tpos = "tpos"
# assembly sources # assembly sources
CArry = "CArry"
hda = "hda" hda = "hda"
Larg = "Larg" Larg = "Larg"
pard = "pard" pard = "pard"
+37 -26
View File
@@ -9,11 +9,12 @@ 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"
DEBIAN_FRONTEND: noninteractive DEBIAN_FRONTEND: noninteractive
UPX_CMAKE_BUILD_FLAGS: --verbose UPX_CMAKE_BUILD_FLAGS: --verbose
# 2023-07-30 # 2023-11-01
ZIG_DIST_VERSION: 0.11.0-dev.4320+6f0a613b6 ZIG_DIST_VERSION: 0.12.0-dev.1369+a09ba455c
jobs: jobs:
job-rebuild-and-verify-stubs: job-rebuild-and-verify-stubs:
@@ -27,8 +28,8 @@ jobs:
if ! test -e /usr/bin/python2; then if ! test -e /usr/bin/python2; then
####sudo apt-get update && sudo apt-get install -y --no-install-recommends python2-minimal ####sudo apt-get update && sudo apt-get install -y --no-install-recommends python2-minimal
# 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' wget -q 'https://ftp.debian.org/debian/pool/main/p/python2.7/libpython2.7-minimal_2.7.18-8+deb11u1_amd64.deb'
wget -q 'https://ftp.debian.org/debian/pool/main/p/python2.7/python2.7-minimal_2.7.18-8_amd64.deb' wget -q 'https://ftp.debian.org/debian/pool/main/p/python2.7/python2.7-minimal_2.7.18-8+deb11u1_amd64.deb'
sudo dpkg -i ./*python2*.deb && rm ./*python2*.deb && sudo ldconfig sudo dpkg -i ./*python2*.deb && rm ./*python2*.deb && sudo ldconfig
sudo ln -s -v python2.7 /usr/bin/python2 sudo ln -s -v python2.7 /usr/bin/python2
fi fi
@@ -41,7 +42,7 @@ jobs:
# 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 wget -q -O - https://github.com/upx/upx-stubtools/releases/download/v20221212/bin-upx-20221212.tar.xz | tar -xJ
- name: 'Check out code' - name: 'Check out code'
uses: actions/checkout@v3 uses: actions/checkout@v4
with: { submodules: true } with: { submodules: true }
- name: 'Rebuild and verify stubs' - name: 'Rebuild and verify stubs'
run: | run: |
@@ -57,7 +58,7 @@ jobs:
if ! git diff --quiet; then git diff; exit 1; fi if ! git diff --quiet; then git diff; exit 1; fi
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} cmake', matrix.os) }}
runs-on: ${{ matrix.os }} runs-on: ${{ matrix.os }}
@@ -75,7 +76,7 @@ jobs:
sudo apt-get update sudo apt-get update
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' - name: 'Check out code'
uses: actions/checkout@v3 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'
@@ -127,6 +128,9 @@ jobs:
run: | run: |
make -C build/extra/gcc-m32/debug test make -C build/extra/gcc-m32/debug test
make -C build/extra/gcc-m32/release test make -C build/extra/gcc-m32/release test
- name: 'Run file system test suite'
run: |
env -C build/extra/gcc/release bash "$PWD"/misc/testsuite/test_symlinks.sh
- name: 'Run test suite build/extra/gcc/release' - name: 'Run test suite build/extra/gcc/release'
run: | run: |
export upx_testsuite_SRCDIR="$(readlink -en ../deps/upx-testsuite)" export upx_testsuite_SRCDIR="$(readlink -en ../deps/upx-testsuite)"
@@ -134,7 +138,7 @@ jobs:
env -C build/extra/gcc/release upx_exe=./upx bash "$testsuite_1" env -C build/extra/gcc/release upx_exe=./upx bash "$testsuite_1"
job-macos-cmake: # 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} cmake', matrix.os) }}
runs-on: ${{ matrix.os }} runs-on: ${{ matrix.os }}
@@ -142,6 +146,8 @@ jobs:
fail-fast: false fail-fast: false
matrix: matrix:
include: include:
# NOTE: macos does not have "env -C"; only with coreutils
# NOTE: macos-11 does not have "readlink -f"; only on macos >= 12 or with 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, gcc: gcc-12, gxx: 'g++-12', testsuite: true }
@@ -156,7 +162,7 @@ jobs:
if ! brew install coreutils; then brew update && brew install coreutils; fi if ! brew install coreutils; then brew update && brew install coreutils; fi
fi fi
- name: 'Check out code' - name: 'Check out code'
uses: actions/checkout@v3 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 }}
@@ -200,7 +206,15 @@ jobs:
if: ${{ !contains(matrix.os, 'macos-13') }} # FIXME: UPX on macos-13 is broken => disable self-test for now if: ${{ !contains(matrix.os, 'macos-13') }} # FIXME: UPX on macos-13 is broken => disable self-test for now
run: | run: |
make -C build/extra/clang/debug test make -C build/extra/clang/debug test
make -C build/extra/clang/release test # make -C build/extra/clang/release test
- name: 'Run file system test suite'
if: ${{ matrix.testsuite }} # for coreutils readlink
run: |
## macos-11 does not have "readlink -f"
## testsuite="$(readlink -fn ./misc/testsuite/test_symlinks.sh)"
## (cd build/extra/clang/release && upx_exe=./upx bash "$testsuite")
export PATH="/usr/local/opt/coreutils/libexec/gnubin:$PATH"
env -C build/extra/clang/release bash "$PWD"/misc/testsuite/test_symlinks.sh
- name: 'Run test suite build/extra/clang/release' - name: 'Run test suite build/extra/clang/release'
if: ${{ matrix.testsuite }} if: ${{ matrix.testsuite }}
run: | run: |
@@ -210,7 +224,7 @@ jobs:
env -C build/extra/clang/release upx_exe=./upx bash "$testsuite_1" env -C build/extra/clang/release upx_exe=./upx bash "$testsuite_1"
job-windows-cmake: # 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} cmake', matrix.name) }}
runs-on: ${{ matrix.os }} runs-on: ${{ matrix.os }}
@@ -218,19 +232,16 @@ jobs:
fail-fast: false fail-fast: false
matrix: matrix:
include: include:
# windows-2019 used to work but got broken with the 20220821.1 runner-image - { name: windows-2019-amd64, os: windows-2019, vsversion: 2019, arch: amd64 }
# update; we cannot download that image for inspection, and debugging the
# remote image is painful, so disable for now
####- { name: windows-2019-amd64, os: windows-2019, vsversion: 2019, arch: amd64 }
- { name: windows-2022-amd64, os: windows-2022, vsversion: 2022, arch: amd64 } - { name: windows-2022-amd64, os: windows-2022, vsversion: 2022, arch: amd64 }
steps: steps:
- name: 'Check out code' - name: 'Check out code'
uses: actions/checkout@v3 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' - name: 'Set up Developer Command Prompt'
uses: ilammy/msvc-dev-cmd@v1 uses: ilammy/msvc-dev-cmd@cec98b9d092141f74527d0afa6feb2af698cfe89 # v1.12.1
with: with:
vsversion: ${{ matrix.vsversion }} vsversion: ${{ matrix.vsversion }}
arch: ${{ matrix.arch }} arch: ${{ matrix.arch }}
@@ -265,7 +276,7 @@ jobs:
env -C build/release/Release upx_exe=./upx bash "$testsuite_1" env -C build/release/Release upx_exe=./upx bash "$testsuite_1"
job-windows-toolchains: # build "by hand" using cmd.exe job-windows-toolchains: # build "by hand" using cmd.exe
if: ${{ true }} if: true
needs: [ job-rebuild-and-verify-stubs ] needs: [ job-rebuild-and-verify-stubs ]
name: ${{ format('windows {0}', matrix.name) }} name: ${{ format('windows {0}', matrix.name) }}
runs-on: ${{ matrix.os }} runs-on: ${{ matrix.os }}
@@ -287,7 +298,7 @@ jobs:
- { name: i386-win32-vs2022, os: windows-2022, vsversion: 2022, arch: amd64_x86 } - { name: i386-win32-vs2022, os: windows-2022, vsversion: 2022, arch: amd64_x86 }
steps: steps:
- name: 'Check out code' - name: 'Check out code'
uses: actions/checkout@v3 uses: actions/checkout@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
@@ -295,7 +306,7 @@ jobs:
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' - name: 'Set up Developer Command Prompt'
uses: ilammy/msvc-dev-cmd@v1 uses: ilammy/msvc-dev-cmd@cec98b9d092141f74527d0afa6feb2af698cfe89 # v1.12.1
with: with:
vsversion: ${{ matrix.vsversion }} vsversion: ${{ matrix.vsversion }}
arch: ${{ matrix.arch }} arch: ${{ matrix.arch }}
@@ -306,7 +317,8 @@ jobs:
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 @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=0x0400
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 =====
@@ -372,7 +384,7 @@ jobs:
env -C build/$C/$B/upx upx_exe=./upx.exe bash "$testsuite_1" env -C build/$C/$B/upx upx_exe=./upx.exe bash "$testsuite_1"
job-linux-zigcc: # uses cmake + make job-linux-zigcc: # uses cmake + make
if: ${{ true }} 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
@@ -392,6 +404,7 @@ jobs:
- { zig_target: arm-linux-musleabihf } - { zig_target: arm-linux-musleabihf }
# { zig_target: arm-linux-musleabihf, zig_pic: -fPIE } # { zig_target: arm-linux-musleabihf, zig_pic: -fPIE }
# { zig_target: i386-linux-musl } # { zig_target: i386-linux-musl }
# { zig_target: i386-linux-musl, zig_pic: -fPIE }
- { zig_target: i386-windows-gnu } - { zig_target: i386-windows-gnu }
# { zig_target: mips-linux-musl } # { zig_target: mips-linux-musl }
# { zig_target: mipsel-linux-musl } # { zig_target: mipsel-linux-musl }
@@ -422,7 +435,7 @@ jobs:
# this seems to be needed when running in a container (beause of UID mismatch??) # this seems to be needed when running in a container (beause of UID mismatch??)
git config --global --add safe.directory '*' git config --global --add safe.directory '*'
- name: 'Check out code' - name: 'Check out code'
uses: actions/checkout@v3 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
@@ -484,5 +497,3 @@ jobs:
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)
# vim:set ts=2 sw=2 et:
@@ -14,10 +14,11 @@
name: 'GitHub - Close inactive issues' name: 'GitHub - Close inactive issues'
on: on:
schedule: [cron: '50 3 * * 3'] # run weekly Wednesday 03:50 UTC schedule: [cron: '50 0 * * 3'] # run weekly Wednesday 00:50 UTC
workflow_dispatch: workflow_dispatch:
jobs: jobs:
close-issues: job-close-inactive-issues:
if: github.repository_owner == 'upx'
name: 'Close inactive issues' name: 'Close inactive issues'
runs-on: ubuntu-latest runs-on: ubuntu-latest
permissions: permissions:
@@ -4,7 +4,8 @@ on:
#pull_request: #pull_request:
workflow_dispatch: workflow_dispatch:
jobs: jobs:
close-pull-requests: job-close-pull-requests:
if: github.repository_owner == 'upx'
name: 'Close pull requests' name: 'Close pull requests'
runs-on: ubuntu-latest runs-on: ubuntu-latest
permissions: permissions:
+4 -2
View File
@@ -3,17 +3,19 @@
name: 'Misc - Spell check' name: 'Misc - Spell check'
on: on:
schedule: [cron: '55 0 * * 3'] # run weekly Wednesday 00:55 UTC
workflow_dispatch: workflow_dispatch:
env: env:
DEBIAN_FRONTEND: noninteractive DEBIAN_FRONTEND: noninteractive
jobs: jobs:
job-spell-check: job-spell-check:
if: github.repository_owner == 'upx'
name: 'Spell check' name: 'Spell check'
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: 'Check out code' - name: 'Check out code'
uses: actions/checkout@v3 uses: actions/checkout@v4
with: { submodules: false } with: { submodules: false }
- name: 'Spell check with crate-ci/typos' - name: 'Spell check with crate-ci/typos'
uses: crate-ci/typos@master uses: crate-ci/typos@47dd2976043bd5c76a33aa9300b328a176a1d6f7 # v1.16.21
with: { config: ./.github/typos_config.toml } with: { config: ./.github/typos_config.toml }
@@ -2,18 +2,27 @@
name: 'Static Analyzer - clang-analyzer' name: 'Static Analyzer - clang-analyzer'
on: on:
schedule: [cron: '10 5 * * 3'] # run weekly Wednesday 05:10 UTC schedule: [cron: '10 4 * * 3'] # run weekly Wednesday 04:10 UTC
workflow_dispatch: workflow_dispatch:
env: env:
CMAKE_REQUIRED_QUIET: OFF CMAKE_REQUIRED_QUIET: "OFF"
CTEST_OUTPUT_ON_FAILURE: "ON"
DEBIAN_FRONTEND: noninteractive DEBIAN_FRONTEND: noninteractive
jobs: jobs:
job-analyze-clang-analyzer: # uses cmake + make job-analyze-clang-analyzer: # uses cmake + make
if: github.repository_owner == 'upx'
strategy: strategy:
fail-fast: false fail-fast: false
matrix: {container: ['alpine:3.16','alpine:3.17','alpine:3.18','alpine:edge','i386/alpine:edge']} matrix:
name: ${{ format('Analyze {0}', matrix.container) }} include:
- container: 'alpine:3.16'
- container: 'alpine:3.17'
- container: 'alpine:3.18'
- container: 'alpine:edge'
- container: 'i386/alpine:3.18'
- container: 'i386/alpine:edge'
name: ${{ format('Analyze clang-analyzer {0}', matrix.container) }}
runs-on: ubuntu-latest runs-on: ubuntu-latest
container: ${{ matrix.container }} container: ${{ matrix.container }}
steps: steps:
@@ -21,10 +30,12 @@ jobs:
run: 'apk update && apk upgrade && apk add clang clang-analyzer cmake g++ git make' 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) }} - name: ${{ format('Check out UPX {0} source code', github.ref_name) }}
run: | run: |
git clone --branch "$GITHUB_REF_NAME" --depth 1 https://github.com/upx/upx # this seems to be needed when running in a container (beause of UID mismatch??)
git -C upx submodule update --init git config --global --add safe.directory '*'
git clone --branch "$GITHUB_REF_NAME" --depth 1 "$GITHUB_SERVER_URL/$GITHUB_REPOSITORY" .
git submodule update --init
- name: 'Perform clang-analyzer scan-build Analysis Debug' - name: 'Perform clang-analyzer scan-build Analysis Debug'
run: 'make -C upx build/analyze/clang-analyzer/debug' run: 'make build/analyze/clang-analyzer/debug'
- name: 'Perform clang-analyzer scan-build Analysis Release' - name: 'Perform clang-analyzer scan-build Analysis Release'
if: success() || failure() # run this step even if the previous step failed if: success() || failure() # run this step even if the previous step failed
run: 'make -C upx build/analyze/clang-analyzer/release' run: 'make build/analyze/clang-analyzer/release'
@@ -2,17 +2,24 @@
name: 'Static Analyzer - clang-tidy' name: 'Static Analyzer - clang-tidy'
on: on:
schedule: [cron: '30 5 * * 3'] # run weekly Wednesday 05:30 UTC schedule: [cron: '30 4 * * 3'] # run weekly Wednesday 04:30 UTC
workflow_dispatch: workflow_dispatch:
env: env:
CMAKE_REQUIRED_QUIET: OFF CMAKE_REQUIRED_QUIET: "OFF"
CTEST_OUTPUT_ON_FAILURE: "ON"
DEBIAN_FRONTEND: noninteractive DEBIAN_FRONTEND: noninteractive
jobs: jobs:
job-analyze-clang-tidy: # uses cmake + make job-analyze-clang-tidy: # uses cmake + make
if: github.repository_owner == 'upx'
strategy: strategy:
fail-fast: false fail-fast: false
matrix: {container: ['alpine:edge','i386/alpine:edge']} matrix:
include:
- container: 'alpine:3.18'
- container: 'alpine:edge'
- container: 'i386/alpine:3.18'
- container: 'i386/alpine:edge'
name: ${{ format('Analyze clang-tidy {0}', matrix.container) }} name: ${{ format('Analyze clang-tidy {0}', matrix.container) }}
runs-on: ubuntu-latest runs-on: ubuntu-latest
container: ${{ matrix.container }} container: ${{ matrix.container }}
@@ -21,10 +28,12 @@ jobs:
run: 'apk update && apk upgrade && apk add clang clang-extra-tools cmake g++ git make python3' 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) }} - name: ${{ format('Check out UPX {0} source code', github.ref_name) }}
run: | run: |
git clone --branch "$GITHUB_REF_NAME" --depth 1 https://github.com/upx/upx # this seems to be needed when running in a container (beause of UID mismatch??)
git -C upx submodule update --init git config --global --add safe.directory '*'
git clone --branch "$GITHUB_REF_NAME" --depth 1 "$GITHUB_SERVER_URL/$GITHUB_REPOSITORY" .
git submodule update --init
- name: 'Perform clang-tidy Analysis Debug' - name: 'Perform clang-tidy Analysis Debug'
run: 'make -k -C upx build/analyze/clang-tidy/debug' run: 'make -k build/analyze/clang-tidy/debug'
- name: 'Perform clang-tidy Analysis Release' - name: 'Perform clang-tidy Analysis Release'
if: success() || failure() # run this step even if the previous step failed if: success() || failure() # run this step even if the previous step failed
run: 'make -k -C upx build/analyze/clang-tidy/release' run: 'make -k build/analyze/clang-tidy/release'
+5 -3
View File
@@ -2,14 +2,16 @@
name: 'Static Analyzer - CodeQL' name: 'Static Analyzer - CodeQL'
on: on:
schedule: [cron: '50 5 * * 3'] # run weekly Wednesday 05:50 UTC schedule: [cron: '50 4 * * 3'] # run weekly Wednesday 04:50 UTC
workflow_dispatch: workflow_dispatch:
env: env:
CMAKE_REQUIRED_QUIET: OFF CMAKE_REQUIRED_QUIET: "OFF"
CTEST_OUTPUT_ON_FAILURE: "ON"
DEBIAN_FRONTEND: noninteractive DEBIAN_FRONTEND: noninteractive
jobs: jobs:
job-analyze-codeql: job-analyze-codeql:
if: github.repository_owner == 'upx'
name: Analyze name: Analyze
runs-on: ubuntu-latest runs-on: ubuntu-latest
permissions: permissions:
@@ -22,7 +24,7 @@ jobs:
language: [ 'cpp' ] language: [ 'cpp' ]
steps: steps:
- name: Checkout repository - name: Checkout repository
uses: actions/checkout@v3 uses: actions/checkout@v4
with: { submodules: true } with: { submodules: true }
- name: Initialize CodeQL - name: Initialize CodeQL
uses: github/codeql-action/init@v2 uses: github/codeql-action/init@v2
+6 -75
View File
@@ -6,11 +6,13 @@
name: 'Test - Minimal Alpine build' name: 'Test - Minimal Alpine build'
on: [workflow_dispatch] on: [workflow_dispatch]
env: env:
CMAKE_REQUIRED_QUIET: OFF CMAKE_REQUIRED_QUIET: "OFF"
CTEST_OUTPUT_ON_FAILURE: "ON"
DEBIAN_FRONTEND: noninteractive DEBIAN_FRONTEND: noninteractive
jobs: jobs:
job-alpine-clang: # uses cmake + make job-alpine-clang: # uses cmake + make
if: true
strategy: { matrix: { container: ['alpine:edge','i386/alpine:edge'] } } strategy: { matrix: { container: ['alpine:edge','i386/alpine:edge'] } }
name: ${{ format('clang {0}', matrix.container) }} name: ${{ format('clang {0}', matrix.container) }}
runs-on: ubuntu-latest runs-on: ubuntu-latest
@@ -19,7 +21,7 @@ jobs:
- name: ${{ format('Build clang {0}', matrix.container) }} - name: ${{ format('Build clang {0}', matrix.container) }}
run: | run: |
apk update && apk upgrade && apk add clang cmake make apk update && apk upgrade && apk add clang cmake make
wget https://github.com/upx/upx/releases/download/v4.0.2/upx-4.0.2-src.tar.xz wget https://github.com/upx/upx/releases/download/v4.2.0/upx-4.2.0-src.tar.xz
tar -xoaf upx-*-src.tar.xz tar -xoaf upx-*-src.tar.xz
cd upx-*-src cd upx-*-src
make build/debug CC="clang -static" CXX="clang++ -static" make build/debug CC="clang -static" CXX="clang++ -static"
@@ -37,6 +39,7 @@ jobs:
path: 'upx*/build/*/upx' path: 'upx*/build/*/upx'
job-alpine-gcc: # uses cmake + make job-alpine-gcc: # uses cmake + make
if: true
strategy: { matrix: { container: ['alpine:edge','i386/alpine:edge'] } } strategy: { matrix: { container: ['alpine:edge','i386/alpine:edge'] } }
name: ${{ format('gcc {0}', matrix.container) }} name: ${{ format('gcc {0}', matrix.container) }}
runs-on: ubuntu-latest runs-on: ubuntu-latest
@@ -45,7 +48,7 @@ jobs:
- name: ${{ format('Build gcc {0}', matrix.container) }} - name: ${{ format('Build gcc {0}', matrix.container) }}
run: | run: |
apk update && apk upgrade && apk add cmake g++ make apk update && apk upgrade && apk add cmake g++ make
wget https://github.com/upx/upx/releases/download/v4.0.2/upx-4.0.2-src.tar.xz wget https://github.com/upx/upx/releases/download/v4.2.0/upx-4.2.0-src.tar.xz
tar -xoaf upx-*-src.tar.xz tar -xoaf upx-*-src.tar.xz
cd upx-*-src cd upx-*-src
make build/debug CC="gcc -static" CXX="g++ -static" make build/debug CC="gcc -static" CXX="g++ -static"
@@ -61,75 +64,3 @@ jobs:
with: with:
name: ${{ env.artifact_name }} name: ${{ env.artifact_name }}
path: 'upx*/build/*/upx' path: 'upx*/build/*/upx'
job-alpine-by-hand: # uses a POSIX-compliant shell
# ...and also uses a subdirectory "upx with space" in order to detect possible quoting issues
# ...and also uses ccache as we are running the same build-script again and again
if: ${{ true }}
strategy: { matrix: { container: ['alpine:3.9','alpine:edge'] } }
name: ${{ format('gcc by-hand {0}', matrix.container) }}
runs-on: ubuntu-latest
container: ${{ matrix.container }}
steps:
- name: ${{ format('Install packages {0}', matrix.container) }}
run: |
# install ccache, g++, git and various POSIX shells
shells="bash dash loksh mksh zsh"
case ${{ matrix.container }} in
*:edge) shells="$shells oksh yash" ;;
esac
echo "installing shells: $shells"
apk update && apk upgrade && apk add ccache g++ git $shells
# enable ccache
echo -e "CC=ccache gcc\nCXX=ccache g++ -std=gnu++17" >> $GITHUB_ENV
# this seems to be needed when running in a container (beause of UID mismatch??)
git config --global --add safe.directory '*'
- name: 'Check out code'
uses: actions/checkout@v3
with:
submodules: true
path: 'upx with space'
- name: 'Build by-hand with bash'
run: 'bash "./upx with space/misc/scripts/build_upx_by_hand.sh"'
- name: 'Build by-hand with bash --posix'
run: 'bash --posix "./upx with space/misc/scripts/build_upx_by_hand.sh"'
- name: 'Build by-hand with busybox ash'
run: 'busybox ash "./upx with space/misc/scripts/build_upx_by_hand.sh"'
- name: 'Build by-hand with busybox sh'
run: 'busybox sh "./upx with space/misc/scripts/build_upx_by_hand.sh"'
- name: 'Build by-hand with dash'
run: 'dash "./upx with space/misc/scripts/build_upx_by_hand.sh"'
- name: 'Build by-hand with loksh'
run: 'ksh "./upx with space/misc/scripts/build_upx_by_hand.sh"'
- name: 'Build by-hand with loksh -o posix'
run: 'ksh -o posix "./upx with space/misc/scripts/build_upx_by_hand.sh"'
- name: 'Build by-hand with loksh -o sh'
run: 'ksh -o sh "./upx with space/misc/scripts/build_upx_by_hand.sh"'
- name: 'Build by-hand with mksh'
run: 'mksh "./upx with space/misc/scripts/build_upx_by_hand.sh"'
- name: 'Build by-hand with mksh -o posix'
run: 'mksh -o posix "./upx with space/misc/scripts/build_upx_by_hand.sh"'
- name: 'Build by-hand with mksh -o sh'
run: 'mksh -o sh "./upx with space/misc/scripts/build_upx_by_hand.sh"'
- name: 'Build by-hand with oksh'
if: ${{ contains(matrix.container, ':edge') }}
run: 'oksh "./upx with space/misc/scripts/build_upx_by_hand.sh"'
- name: 'Build by-hand with oksh -o posix'
if: ${{ contains(matrix.container, ':edge') }}
run: 'oksh -o posix "./upx with space/misc/scripts/build_upx_by_hand.sh"'
- name: 'Build by-hand with oksh -o sh'
if: ${{ contains(matrix.container, ':edge') }}
run: 'oksh -o sh "./upx with space/misc/scripts/build_upx_by_hand.sh"'
- name: 'Build by-hand with yash'
if: ${{ contains(matrix.container, ':edge') }}
run: 'yash "./upx with space/misc/scripts/build_upx_by_hand.sh"'
- name: 'Build by-hand with zsh'
run: 'zsh "./upx with space/misc/scripts/build_upx_by_hand.sh"'
- name: 'Build by-hand with zsh --emulate ksh'
run: 'zsh --emulate ksh "./upx with space/misc/scripts/build_upx_by_hand.sh"'
- name: 'Build by-hand with zsh --emulate sh'
run: 'zsh --emulate sh "./upx with space/misc/scripts/build_upx_by_hand.sh"'
- name: 'Show ccache stats'
run: |
ccache -s
ccache -p
+10 -9
View File
@@ -3,7 +3,8 @@
name: 'Test - CMake default build type' name: 'Test - CMake default build type'
on: [workflow_dispatch] on: [workflow_dispatch]
env: env:
CMAKE_REQUIRED_QUIET: OFF CMAKE_REQUIRED_QUIET: "OFF"
CTEST_OUTPUT_ON_FAILURE: "ON"
DEBIAN_FRONTEND: noninteractive DEBIAN_FRONTEND: noninteractive
jobs: jobs:
@@ -16,7 +17,7 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: 'Check out code' - name: 'Check out code'
uses: actions/checkout@v3 uses: actions/checkout@v4
with: { submodules: true } with: { submodules: true }
- name: 'Config, build, test and install' - name: 'Config, build, test and install'
run: | run: |
@@ -33,7 +34,7 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: 'Check out code' - name: 'Check out code'
uses: actions/checkout@v3 uses: actions/checkout@v4
with: { submodules: true } with: { submodules: true }
- name: 'Config, build, test and install' - name: 'Config, build, test and install'
run: | run: |
@@ -51,10 +52,10 @@ jobs:
runs-on: windows-2022 runs-on: windows-2022
steps: steps:
- name: 'Check out code' - name: 'Check out code'
uses: actions/checkout@v3 uses: actions/checkout@v4
with: { submodules: true } with: { submodules: true }
- name: 'Set up Developer Command Prompt' - name: 'Set up Developer Command Prompt'
uses: ilammy/msvc-dev-cmd@v1 uses: ilammy/msvc-dev-cmd@cec98b9d092141f74527d0afa6feb2af698cfe89 # v1.12.1
with: with:
vsversion: 2022 vsversion: 2022
arch: amd64 arch: amd64
@@ -80,7 +81,7 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: 'Check out code' - name: 'Check out code'
uses: actions/checkout@v3 uses: actions/checkout@v4
with: { submodules: true } with: { submodules: true }
- name: 'Config, build, test and install' - name: 'Config, build, test and install'
run: | run: |
@@ -100,10 +101,10 @@ jobs:
runs-on: windows-2022 runs-on: windows-2022
steps: steps:
- name: 'Check out code' - name: 'Check out code'
uses: actions/checkout@v3 uses: actions/checkout@v4
with: { submodules: true } with: { submodules: true }
- name: 'Set up Developer Command Prompt' - name: 'Set up Developer Command Prompt'
uses: ilammy/msvc-dev-cmd@v1 uses: ilammy/msvc-dev-cmd@cec98b9d092141f74527d0afa6feb2af698cfe89 # v1.12.1
with: with:
vsversion: 2022 vsversion: 2022
arch: amd64 arch: amd64
@@ -120,7 +121,7 @@ jobs:
runs-on: macos-12 runs-on: macos-12
steps: steps:
- name: 'Check out code' - name: 'Check out code'
uses: actions/checkout@v3 uses: actions/checkout@v4
with: { submodules: true } with: { submodules: true }
- name: 'Config, build, test and install' - name: 'Config, build, test and install'
run: | run: |
+16
View File
@@ -0,0 +1,16 @@
# 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
+48
View File
@@ -0,0 +1,48 @@
# Copyright (C) Markus Franz Xaver Johannes Oberhumer
name: 'Test - YAML check'
on: [workflow_dispatch]
env:
CMAKE_REQUIRED_QUIET: "OFF"
CTEST_OUTPUT_ON_FAILURE: "ON"
DEBIAN_FRONTEND: noninteractive
jobs:
job-yaml-check:
if: true
strategy:
fail-fast: false
matrix:
include:
- container: 'alpine:3.16'
- container: 'alpine:3.17'
- container: 'alpine:3.18'
- container: 'alpine:edge'
name: ${{ format('{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 git yq
case ${{ matrix.container }} in
*:edge) apk add -X http://dl-cdn.alpinelinux.org/alpine/edge/testing ytt ;;
esac
# 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: false }
- name: ${{ format('YAML check {0}', matrix.container) }}
shell: bash
run: |
for f in $(find . -type f -iname '*.yml' | LC_ALL=C sort); do
echo "===== checking file"
echo " yq $f"
yq < "$f" > /dev/null
if command -v ytt > /dev/null; then
echo " ytt $f"
ytt -f- < "$f" > /dev/null
fi
done
echo "All done."
@@ -1,156 +0,0 @@
# Copyright (C) Markus Franz Xaver Johannes Oberhumer
# Build under various Alpine Linux versions with clang and gcc, and
# also test building with C++20 and C++23.
# And also uses a subdirectory "upx with space" that contains whitespace in order
# to detect possible quoting issues.
# info: Alpine 3.9 has clang-5, cmake-3.13.0 and gcc-8, which nicely
# matches our minimal build requirements
name: 'Weekly CI - Alpine Linux'
on:
schedule: [cron: '05 4 * * 3'] # run weekly Wednesday 04:05 UTC
workflow_dispatch:
env:
CMAKE_REQUIRED_QUIET: OFF
DEBIAN_FRONTEND: noninteractive
UPX_TESTSUITE_LEVEL: 2
jobs:
job-alpine-cmake: # uses cmake + make
strategy:
fail-fast: false
matrix: { container: ['alpine:3.9','alpine:3.10','alpine:3.11','alpine:3.12','alpine:3.13','alpine:3.14','alpine:3.15','alpine:3.16','alpine:3.17','alpine:3.18','alpine:edge','i386/alpine:edge'] }
name: ${{ format('container {0}', matrix.container) }}
runs-on: ubuntu-latest
container: ${{ matrix.container }}
env: { UPX_CMAKE_CONFIG_FLAGS: '-DCMAKE_VERBOSE_MAKEFILE=ON' }
steps:
- name: ${{ format('Install packages {0}', matrix.container) }}
run: |
apk update && apk upgrade && apk add clang cmake g++ git make
case ${{ matrix.container }} in
# clang-dev is needed on older Alpine versions for clang headers like <emmintrin.h>
*:3.[0-9]|*:3.10|*:3.11) apk add clang-dev ;;
esac
- name: ${{ format('Check out UPX {0} source code', github.ref_name) }}
run: |
git clone --branch "$GITHUB_REF_NAME" --depth 1 https://github.com/upx/upx "upx with space"
git -C "upx with space" submodule update --init
x="$(apk list -I "$(apk info -Wq "$(which clang)")")"; echo "clang_package=${x%% *}" >> $GITHUB_ENV
x="$(apk list -I "$(apk info -Wq "$(which gcc)")")"; echo "gcc_package=${x%% *}" >> $GITHUB_ENV
N=$(echo "upx-${GITHUB_REF_NAME}-${GITHUB_SHA:0:7}-weekly-ci-alpine-${{ matrix.container }}" | sed 's/[^0-9a-zA-Z_.-]/-/g')
echo "artifact_name=$N" >> $GITHUB_ENV
# build with default C11 and C++17
- name: ${{ format('Build clang Release with {0}', env.clang_package) }}
run: 'make -C "upx with space" UPX_XTARGET=clang-static CC="clang -static" CXX="clang++ -static"'
- name: ${{ format('Build clang Debug with {0}', env.clang_package) }}
run: 'make -C "upx with space" UPX_XTARGET=clang-static CC="clang -static" CXX="clang++ -static" xtarget/debug'
- name: ${{ format('Build gcc Release with {0}', env.gcc_package) }}
run: 'make -C "upx with space" UPX_XTARGET=gcc-static CC="gcc -static" CXX="g++ -static"'
- name: ${{ format('Build gcc Debug with {0}', env.gcc_package) }}
run: 'make -C "upx with space" UPX_XTARGET=gcc-static CC="gcc -static" CXX="g++ -static" xtarget/debug'
- name: 'Update environment'
run: |
echo "UPX_CONFIG_DISABLE_C_STANDARD=ON" >> $GITHUB_ENV
echo "UPX_CONFIG_DISABLE_CXX_STANDARD=ON" >> $GITHUB_ENV
# build with C17 and C++20 on alpine:edge
- name: ${{ format('Build clang C++20 Release with {0}', env.clang_package) }}
if: ${{ contains(matrix.container, ':edge') }}
run: |
make -C "upx with space" UPX_XTARGET=clang-cxx20-static CC="clang -std=gnu17 -static" CXX="clang++ -std=gnu++20 -static"
- name: ${{ format('Build clang C++20 Debug with {0}', env.clang_package) }}
if: ${{ contains(matrix.container, ':edge') }}
run: |
make -C "upx with space" UPX_XTARGET=clang-cxx20-static CC="clang -std=gnu17 -static" CXX="clang++ -std=gnu++20 -static" xtarget/debug
- name: ${{ format('Build gcc C++20 Release with {0}', env.gcc_package) }}
if: ${{ contains(matrix.container, ':edge') }}
run: |
make -C "upx with space" UPX_XTARGET=gcc-cxx20-static CC="gcc -std=gnu17 -static" CXX="g++ -std=gnu++20 -static"
- name: ${{ format('Build gcc C++20 Debug with {0}', env.gcc_package) }}
if: ${{ contains(matrix.container, ':edge') }}
run: |
make -C "upx with space" UPX_XTARGET=gcc-cxx20-static CC="gcc -std=gnu17 -static" CXX="g++ -std=gnu++20 -static" xtarget/debug
# build with C23 and C++23 on alpine:edge
- name: ${{ format('Build clang C++23 Release with {0}', env.clang_package) }}
if: ${{ contains(matrix.container, ':edge') }}
run: |
make -C "upx with space" UPX_XTARGET=clang-cxx23-static CC="clang -std=gnu2x -static" CXX="clang++ -std=gnu++2b -static"
- name: ${{ format('Build clang C++23 Debug with {0}', env.clang_package) }}
if: ${{ contains(matrix.container, ':edge') }}
run: |
make -C "upx with space" UPX_XTARGET=clang-cxx23-static CC="clang -std=gnu2x -static" CXX="clang++ -std=gnu++2b -static" xtarget/debug
- name: ${{ format('Build gcc C++23 Release with {0}', env.gcc_package) }}
if: ${{ contains(matrix.container, ':edge') }}
run: |
make -C "upx with space" UPX_XTARGET=gcc-cxx23-static CC="gcc -std=gnu2x -static" CXX="g++ -std=gnu++23 -static"
- name: ${{ format('Build gcc C++23 Debug with {0}', env.gcc_package) }}
if: ${{ contains(matrix.container, ':edge') }}
run: |
make -C "upx with space" UPX_XTARGET=gcc-cxx23-static CC="gcc -std=gnu2x -static" CXX="g++ -std=gnu++23 -static" xtarget/debug
# build with -flto=auto on alpine:edge
- name: ${{ format('Build clang LTO Release with {0}', env.clang_package) }}
if: ${{ contains(matrix.container, ':edge') }}
run: |
make -C "upx with space" UPX_XTARGET=clang-cxxlto-static CC="clang -flto=auto -static" CXX="clang++ -flto=auto -static"
- name: ${{ format('Build clang LTO Debug with {0}', env.clang_package) }}
if: ${{ contains(matrix.container, ':edge') }}
run: |
make -C "upx with space" UPX_XTARGET=clang-cxxlto-static CC="clang -flto=auto -static" CXX="clang++ -flto=auto -static" xtarget/debug
- name: ${{ format('Build gcc LTO Release with {0}', env.gcc_package) }}
if: ${{ contains(matrix.container, ':edge') }}
run: |
make -C "upx with space" UPX_XTARGET=gcc-cxxlto-static CC="gcc -flto=auto -static" CXX="g++ -flto=auto -static"
- name: ${{ format('Build gcc LTO Debug with {0}', env.gcc_package) }}
if: ${{ contains(matrix.container, ':edge') }}
run: |
make -C "upx with space" UPX_XTARGET=gcc-cxxlto-static CC="gcc -flto=auto -static" CXX="g++ -flto=auto -static" xtarget/debug
- { name: 'Strip release binaries', run: 'strip -p --strip-unneeded "upx with space"/build/*/*/release/upx' }
- name: ${{ format('Upload artifact {0}', env.artifact_name) }}
if: ${{ !startsWith(matrix.container, 'i386/') }} # i386: missing nodejs on host
uses: actions/upload-artifact@v3
with:
name: ${{ env.artifact_name }}
path: 'upx with space*/build/*/*/*/upx'
- { name: 'Run basic tests clang Release', run: 'make -C "upx with space"/build/xtarget/clang-static/release test' }
- { name: 'Run basic tests clang Debug', run: 'make -C "upx with space"/build/xtarget/clang-static/debug test' }
- { name: 'Run basic tests gcc Release', run: 'make -C "upx with space"/build/xtarget/gcc-static/release test' }
- { name: 'Run basic tests gcc Debug', run: 'make -C "upx with space"/build/xtarget/gcc-static/debug test' }
- name: 'Run basic tests C++20, C++23 and LTO'
if: ${{ contains(matrix.container, ':edge') }}
run: |
for dir in "upx with space"/build/xtarget/*-cxx*/*; do
echo "===== $dir"
make -C "$dir" test
done
- name: 'Run install tests'
run: |
(cd "upx with space"/build/xtarget/clang-static/debug && DESTDIR="$PWD/Install with cmake" cmake --install .)
(cd "upx with space"/build/xtarget/clang-static/debug && DESTDIR="$PWD/Install with make" make install)
(cd "upx with space"/build/xtarget/clang-static/release && DESTDIR="$PWD/Install with cmake" cmake --install .)
(cd "upx with space"/build/xtarget/clang-static/release && DESTDIR="$PWD/Install with make" make install)
(cd "upx with space"/build/xtarget/gcc-static/debug && DESTDIR="$PWD/Install with cmake" cmake --install .)
(cd "upx with space"/build/xtarget/gcc-static/debug && DESTDIR="$PWD/Install with make" make install)
(cd "upx with space"/build/xtarget/gcc-static/release && DESTDIR="$PWD/Install with cmake" cmake --install .)
(cd "upx with space"/build/xtarget/gcc-static/release && DESTDIR="$PWD/Install with make" make install)
# test suite
- name: ${{ format('Run test suite level {0}', env.UPX_TESTSUITE_LEVEL) }}
run: |
# use a directory that contains whitespace to detect possible quoting issues
git clone --depth=1 https://github.com/upx/upx-testsuite "upx-testsuite with space"
export upx_testsuite_SRCDIR="$(readlink -fn "upx-testsuite with space")"
testsuite_1="$(readlink -fn "upx with space"/misc/testsuite/upx_testsuite_1.sh)"
# testsuite needs bash and working "readlink -en" and "sha256sum -b"
apk add bash coreutils
(cd "upx with space"/build/xtarget/gcc-static/release && upx_exe=./upx bash "$testsuite_1")
# vim:set ts=2 sw=2 et:
+165
View File
@@ -0,0 +1,165 @@
# 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 "$GITHUB_SERVER_URL/$GITHUB_REPOSITORY" "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-clang: # 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 clang {0}', matrix.os) }}
runs-on: ${{ matrix.os }}
steps:
- name: 'Install brew packages'
run: |
# install ccache
if ! command -v ccache > /dev/null; then
# only run "brew update" if needed
if ! brew install ccache; then brew update && brew install ccache; fi
fi
xflags="-Wall -Wextra -Werror"
echo -e "CC=ccache clang $xflags\nCXX=ccache clang++ -std=gnu++17 $xflags" >> $GITHUB_ENV
- name: ${{ format('Check out UPX {0} source code', github.ref_name) }}
run: |
git clone --branch "$GITHUB_REF_NAME" --depth 1 "$GITHUB_SERVER_URL/$GITHUB_REPOSITORY" "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: 'Build by-hand with zsh'
run: 'top_srcdir="$PWD/upx with space" zsh "./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 "$GITHUB_SERVER_URL/$GITHUB_REPOSITORY" "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,18 +1,18 @@
# Copyright (C) Markus Franz Xaver Johannes Oberhumer # Copyright (C) Markus Franz Xaver Johannes Oberhumer
# build with 'cmake -G Xcode' # BS BuildSystem: build on macOS with 'cmake -G Xcode'
name: 'Weekly CI - cmake macOS Xcode' name: 'Weekly CI BS - cmake macOS Xcode'
on: on:
schedule: [cron: '20 4 * * 3'] # run weekly Wednesday 04:20 UTC schedule: [cron: '10 1 * * 3'] # run weekly Wednesday 01:10 UTC
workflow_dispatch: workflow_dispatch:
env: env:
CMAKE_REQUIRED_QUIET: OFF CMAKE_REQUIRED_QUIET: "OFF"
CTEST_OUTPUT_ON_FAILURE: "ON"
DEBIAN_FRONTEND: noninteractive DEBIAN_FRONTEND: noninteractive
jobs: jobs:
job-cmake-macos-xcode: # uses cmake + xcodebuild job-cmake-macos-xcode: # uses cmake + xcodebuild
name: ${{ format('{0} cmake Xcode', matrix.os) }} if: github.repository_owner == 'upx'
runs-on: ${{ matrix.os }}
strategy: strategy:
fail-fast: false fail-fast: false
matrix: matrix:
@@ -20,14 +20,16 @@ jobs:
- { os: macos-11, run_test: true } - { os: macos-11, run_test: true }
- { os: macos-12, run_test: true } - { os: macos-12, run_test: true }
- { os: macos-13, run_test: false } # TODO: enable once UPX fully works on macos-13 - { 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: steps:
- name: 'Check out code' - name: 'Check out code'
uses: actions/checkout@v3 uses: actions/checkout@v4
with: { submodules: true } with: { submodules: true }
- { name: 'Config cmake Xcode', run: 'cmake -S . -B build/xcode -G Xcode' } - { 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 default', run: 'cmake --build build/xcode --parallel --verbose' }
- { name: 'Build cmake Xcode Debug', run: 'cmake --build build/xcode --config Debug' } - { name: 'Build cmake Xcode Debug', run: 'cmake --build build/xcode --parallel --verbose --config Debug' }
- { name: 'Build cmake Xcode Release', run: 'cmake --build build/xcode --config Release' } - { name: 'Build cmake Xcode Release', run: 'cmake --build build/xcode --parallel --verbose --config Release' }
- name: 'Make artifact' - name: 'Make artifact'
run: | run: |
N=$(echo "upx-${GITHUB_REF_NAME}-${GITHUB_SHA:0:7}-weekly-ci-xcode-${{ matrix.os }}" | sed 's/[^0-9a-zA-Z_.-]/-/g') N=$(echo "upx-${GITHUB_REF_NAME}-${GITHUB_SHA:0:7}-weekly-ci-xcode-${{ matrix.os }}" | sed 's/[^0-9a-zA-Z_.-]/-/g')
@@ -45,7 +47,7 @@ jobs:
if: ${{ matrix.run_test }} if: ${{ matrix.run_test }}
run: | run: |
ctest --test-dir build/xcode -C Debug ctest --test-dir build/xcode -C Debug
ctest --test-dir build/xcode -C Release # ctest --test-dir build/xcode -C Release
- name: 'Run install tests' - name: 'Run install tests'
run: | run: |
(cd build/xcode && DESTDIR=$PWD/Install-default cmake --install .) (cd build/xcode && DESTDIR=$PWD/Install-default cmake --install .)
@@ -0,0 +1,95 @@
# 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-2019, cc: clang-cl, cxx: clang-cl, vsversion: 2019, arch: amd64 }
# - { os: windows-2022, cc: clang-cl, cxx: clang-cl, vsversion: 2022, arch: amd64 }
# clang
- { os: windows-2019, cc: clang, cxx: 'clang++', arch: amd64, xflags: '-static' }
- { os: windows-2022, cc: clang, cxx: 'clang++', arch: amd64, xflags: '-static' }
# gcc (mingw-gcc)
- { os: windows-2019, cc: gcc, cxx: 'g++', arch: amd64, xflags: '-static' }
- { 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="${{ matrix.os }}-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
@@ -0,0 +1,94 @@
# 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-2019, cc: clang-cl, cxx: clang-cl, vsversion: 2019, arch: amd64 }
- { os: windows-2022, cc: clang-cl, cxx: clang-cl, vsversion: 2022, arch: amd64 }
# clang
- { os: windows-2019, cc: clang, cxx: 'clang++', arch: amd64, xflags: '-static' }
- { os: windows-2022, cc: clang, cxx: 'clang++', arch: amd64, xflags: '-static' }
# gcc (mingw-gcc)
- { os: windows-2019, cc: gcc, cxx: 'g++', arch: amd64, xflags: '-static' }
- { 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="${{ matrix.os }}-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,22 +1,24 @@
# Copyright (C) Markus Franz Xaver Johannes Oberhumer # Copyright (C) Markus Franz Xaver Johannes Oberhumer
# build with 'cmake -G "NMake Makefiles"' # BS BuildSystem: build on Windows with 'cmake -G "NMake Makefiles"'
name: 'Weekly CI - cmake Windows NMake' name: 'Weekly CI BS - cmake Windows NMake'
on: on:
schedule: [cron: '30 4 * * 3'] # run weekly Wednesday 04:30 UTC schedule: [cron: '40 1 * * 3'] # run weekly Wednesday 01:40 UTC
workflow_dispatch: workflow_dispatch:
env: env:
CMAKE_REQUIRED_QUIET: OFF CMAKE_REQUIRED_QUIET: "OFF"
CTEST_OUTPUT_ON_FAILURE: "ON"
DEBIAN_FRONTEND: noninteractive DEBIAN_FRONTEND: noninteractive
jobs: jobs:
job-cmake-windows-nmake: # uses cmake + nmake job-cmake-windows-nmake: # uses cmake + nmake
name: ${{ format('vs{0} {1} {2}', matrix.vsversion, matrix.arch, matrix.clang_cl && 'clang-cl' || '') }} if: github.repository_owner == 'upx'
runs-on: ${{ matrix.os }}
strategy: strategy:
fail-fast: false fail-fast: false
matrix: matrix:
include: include:
# clang-cl
- { os: windows-2022, vsversion: 2022, arch: amd64, clang_cl: true }
# msvc # msvc
- { os: windows-2019, vsversion: 2019, arch: amd64 } - { os: windows-2019, vsversion: 2019, arch: amd64 }
- { os: windows-2019, vsversion: 2019, arch: amd64_arm64 } - { os: windows-2019, vsversion: 2019, arch: amd64_arm64 }
@@ -24,14 +26,14 @@ jobs:
- { os: windows-2022, vsversion: 2022, arch: amd64 } - { os: windows-2022, vsversion: 2022, arch: amd64 }
- { os: windows-2022, vsversion: 2022, arch: amd64_arm64 } - { os: windows-2022, vsversion: 2022, arch: amd64_arm64 }
- { os: windows-2022, vsversion: 2022, arch: amd64_x86 } - { os: windows-2022, vsversion: 2022, arch: amd64_x86 }
# clang-cl name: ${{ format('vs{0} {1} {2}', matrix.vsversion, matrix.arch, matrix.clang_cl && 'clang-cl' || '') }}
- { os: windows-2022, vsversion: 2022, arch: amd64, clang_cl: true } runs-on: ${{ matrix.os }}
steps: steps:
- name: 'Check out code' - name: 'Check out code'
uses: actions/checkout@v3 uses: actions/checkout@v4
with: { submodules: true } with: { submodules: true }
- name: 'Set up Developer Command Prompt' - name: 'Set up Developer Command Prompt'
uses: ilammy/msvc-dev-cmd@v1 uses: ilammy/msvc-dev-cmd@cec98b9d092141f74527d0afa6feb2af698cfe89 # v1.12.1
with: with:
vsversion: ${{ matrix.vsversion }} vsversion: ${{ matrix.vsversion }}
arch: ${{ matrix.arch }} arch: ${{ matrix.arch }}
+110
View File
@@ -0,0 +1,110 @@
# Copyright (C) Markus Franz Xaver Johannes Oberhumer
# BS BuildSystem: build with misc flags
name: 'Weekly CI BS - Misc'
on:
schedule: [cron: '50 1 * * 3'] # run weekly Wednesday 01:50 UTC
workflow_dispatch:
env:
CMAKE_REQUIRED_QUIET: "OFF"
CTEST_OUTPUT_ON_FAILURE: "ON"
DEBIAN_FRONTEND: noninteractive
UPX_CMAKE_BUILD_FLAGS: --verbose
jobs:
BS0:
runs-on: ubuntu-latest
container: 'alpine:edge'
steps:
- name: 'Install packages'
run: |
apk update && apk upgrade && apk add bash git perl yq
git config --global --add safe.directory '*'
git clone --branch "$GITHUB_REF_NAME" --depth 1 "$GITHUB_SERVER_URL/$GITHUB_REPOSITORY" .
- name: 'Misc checks'
run: |
cat ./.github/*.yml | yq > /dev/null
cat ./.github/*/*.yml | yq > /dev/null
bash ./misc/scripts/check_whitespace_git.sh
echo "All done."
BS1: # uses cmake + make
if: github.repository_owner == 'upx'
strategy:
fail-fast: false
matrix:
container:
- 'alpine:edge'
- 'i386/alpine:edge'
cc:
- 'clang'
- 'gcc'
cppflags:
- '-DWITH_XSPAN=0'
- '-DWITH_XSPAN=1'
- '-DWITH_XSPAN=2'
- '-DDOCTEST_CONFIG_DISABLE'
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'
- name: ${{ format('Check out {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 "$GITHUB_SERVER_URL/$GITHUB_REPOSITORY" .
git submodule update --init
# prepare environment
xflags="-static ${{ matrix.cppflags }}"
case ${{ matrix.cc }} in
clang) CC="clang $xflags"; CXX="clang++ $xflags" ;;
gcc) CC="gcc $xflags"; CXX="g++ $xflags" ;;
*) exit 99 ;;
esac
echo -e "CC=$CC\nCXX=$CXX" >> $GITHUB_ENV
- name: 'Build and test Debug'
run: 'echo -e "CC=$CC;\nCXX=$CXX;" && make build/debug && ctest --test-dir build/debug'
- name: 'Build and test Release'
if: success() || failure() # run this step even if the previous step failed
run: 'echo -e "CC=$CC;\nCXX=$CXX;" && make build/release && ctest --test-dir build/release'
BS2: # uses cmake + make
if: github.repository_owner == 'upx'
strategy:
fail-fast: false
matrix:
container:
- 'alpine:edge'
cc:
- 'clang'
- 'gcc'
cxxflags:
- '-std=gnu++20'
- '-std=gnu++23'
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'
- name: ${{ format('Check out {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 "$GITHUB_SERVER_URL/$GITHUB_REPOSITORY" .
git submodule update --init
# prepare environment
xflags="-static"
case ${{ matrix.cc }} in
clang) CC="clang $xflags"; CXX="clang++ $xflags ${{ matrix.cxxflags }}" ;;
gcc) CC="gcc $xflags"; CXX="g++ $xflags ${{ matrix.cxxflags }}" ;;
*) exit 99 ;;
esac
echo -e "CC=$CC\nCXX=$CXX" >> $GITHUB_ENV
echo "UPX_CONFIG_DISABLE_C_STANDARD=ON" >> $GITHUB_ENV
echo "UPX_CONFIG_DISABLE_CXX_STANDARD=ON" >> $GITHUB_ENV
- name: 'Build and test Debug'
run: 'echo -e "CC=$CC;\nCXX=$CXX;" && make build/debug && ctest --test-dir build/debug'
- name: 'Build and test Release'
if: success() || failure() # run this step even if the previous step failed
run: 'echo -e "CC=$CC;\nCXX=$CXX;" && make build/release && ctest --test-dir build/release'
@@ -0,0 +1,215 @@
# 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 }
# more 32-bit i386 versions, just for testing
# { container: 'i386/alpine:3.9' } # clang-5, gcc-8; BROKEN: clang -m32 problem
- { container: 'i386/alpine:3.10' } # clang-8, gcc-8
- { container: 'i386/alpine:3.11' } # clang-9, gcc-9
- { container: 'i386/alpine:3.12' } # clang-10, gcc-9
- { container: 'i386/alpine:3.13' } # clang-10, gcc-10
- { container: 'i386/alpine:3.14' } # clang-11, gcc-10
- { container: 'i386/alpine:3.15' } # clang-12, gcc-10
- { container: 'i386/alpine:3.16' } # clang-13, gcc-11
- { container: 'i386/alpine:3.17' } # clang-15, gcc-12
- { container: 'i386/alpine:3.18' } # clang-16, gcc-12
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 "$GITHUB_SERVER_URL/$GITHUB_REPOSITORY" "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"
@@ -0,0 +1,174 @@
# 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 "$GITHUB_SERVER_URL/$GITHUB_REPOSITORY" .
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
@@ -0,0 +1,83 @@
# 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
UPX_CMAKE_CONFIG_FLAGS: -DCMAKE_VERBOSE_MAKEFILE=ON
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"
CC="$CC -D_WIN32_WINNT=0x0400"; CXX="$CXX -D_WIN32_WINNT=0x0400"
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"
CC="$CC -D_WIN32_WINNT=0x0400"; CXX="$CXX -D_WIN32_WINNT=0x0400"
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"
CC="$CC -D_WIN32_WINNT=0x0400"; CXX="$CXX -D_WIN32_WINNT=0x0400"
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"
CC="$CC -D_WIN32_WINNT=0x0400"; CXX="$CXX -D_WIN32_WINNT=0x0400"
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
@@ -1,35 +1,38 @@
# Copyright (C) Markus Franz Xaver Johannes Oberhumer # Copyright (C) Markus Franz Xaver Johannes Oberhumer
# CC CompilationCheck: test zigcc
# build with "zig cc"; see https://ziglang.org/download/ # build with "zig cc"; see https://ziglang.org/download/
name: 'Weekly CI - zigcc' name: 'Weekly CI CC - zigcc'
on: on:
schedule: [cron: '40 4 * * 3'] # run weekly Wednesday 04:40 UTC schedule: [cron: '40 2 * * 3'] # run weekly Wednesday 02:40 UTC
workflow_dispatch: workflow_dispatch:
env: env:
CMAKE_REQUIRED_QUIET: OFF CMAKE_REQUIRED_QUIET: "OFF"
CTEST_OUTPUT_ON_FAILURE: "ON"
DEBIAN_FRONTEND: noninteractive DEBIAN_FRONTEND: noninteractive
# 2023-07-30 # 2023-11-01
ZIG_DIST_VERSION: 0.11.0-dev.4320+6f0a613b6 ZIG_DIST_VERSION: 0.12.0-dev.1369+a09ba455c
jobs: jobs:
job-linux-zigcc: # uses cmake + make job-linux-zigcc: # uses cmake + make
name: ${{ format('zigcc {0} {1}', matrix.zig_target, matrix.zig_pic) }} if: github.repository_owner == 'upx'
runs-on: ubuntu-latest
container: 'alpine:3.18' # older versions such as alpine:3.12 also work; no-container also works
strategy: strategy:
fail-fast: false fail-fast: false
matrix: matrix:
include: include:
# zig BUG: -fPIE is currently broken
- { zig_target: aarch64-linux-musl } - { zig_target: aarch64-linux-musl }
- { zig_target: aarch64-linux-musl, zig_pic: -fPIE } # { zig_target: aarch64-linux-musl, 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 }
- { zig_target: arm-linux-musleabihf, zig_pic: -fPIE } # { zig_target: arm-linux-musleabihf, zig_pic: -fPIE }
- { zig_target: i386-linux-musl } - { zig_target: i386-linux-musl }
# { zig_target: i386-linux-musl, zig_pic: -fPIE }
- { zig_target: i386-windows-gnu } - { zig_target: i386-windows-gnu }
- { zig_target: mips-linux-musl } - { zig_target: mips-linux-musl }
- { zig_target: mipsel-linux-musl } - { zig_target: mipsel-linux-musl }
@@ -37,12 +40,15 @@ jobs:
- { zig_target: powerpc64-linux-musl } - { zig_target: powerpc64-linux-musl }
- { zig_target: powerpc64le-linux-musl } - { zig_target: powerpc64le-linux-musl }
- { zig_target: x86_64-linux-musl } - { zig_target: x86_64-linux-musl }
- { zig_target: x86_64-linux-musl, zig_pic: -fPIE } # { zig_target: x86_64-linux-musl, zig_pic: -fPIE }
- { zig_target: x86_64-macos-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 }
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: env:
# 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
@@ -60,7 +66,7 @@ jobs:
# this seems to be needed when running in a container (beause of UID mismatch??) # this seems to be needed when running in a container (beause of UID mismatch??)
git config --global --add safe.directory '*' git config --global --add safe.directory '*'
- name: 'Check out code' - name: 'Check out code'
uses: actions/checkout@v3 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
@@ -122,5 +128,3 @@ jobs:
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)
# vim:set ts=2 sw=2 et:
+108
View File
@@ -0,0 +1,108 @@
# 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 "$GITHUB_SERVER_URL/$GITHUB_REPOSITORY" .
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 -3
View File
@@ -6,10 +6,10 @@
/maint* /maint*
/vendor* /vendor*
GNUmakefile GNUmakefile*
MMakefile MMakefile*
Makevars.local* Makevars.local*
compile_flags.txt compile_flags*.txt
Tmp* Tmp*
tmp* tmp*
+117 -25
View File
@@ -11,9 +11,23 @@
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.0 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()
# Sections of this CMakeLists.txt:
# - options
# - init
# - common compilation flags
# - targets
# - target compilation flags
# - test
# - install
# - print summary
#***********************************************************************
# options
#***********************************************************************
# compilation config options # compilation config options
if(NOT IS_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/.git") if(NOT IS_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/.git")
# permissive config defaults when building from source code tarball # permissive config defaults when building from source code tarball
@@ -54,11 +68,11 @@ function(upx_cache_bool_vars)
list(REMOVE_AT ARGV 0) list(REMOVE_AT ARGV 0)
foreach(var ${ARGV}) foreach(var ${ARGV})
set(value ${default_value}) set(value ${default_value})
if(DEFINED UPX_CACHE_${var}) if(DEFINED UPX_CACHE_${var}) # cached
set(value "${UPX_CACHE_${var}}") set(value "${UPX_CACHE_${var}}")
elseif(DEFINED ${var}) elseif(DEFINED ${var}) # defined via "cmake -DXXX=YYY"
set(value "${${var}}") set(value "${${var}}")
elseif("$ENV{${var}}" MATCHES "^(0|1|OFF|ON|FALSE|TRUE)$") elseif("$ENV{${var}}" MATCHES "^(0|1|OFF|ON|FALSE|TRUE)$") # environment
set(value "$ENV{${var}}") set(value "$ENV{${var}}")
set(UPX_CACHE_ORIGIN_FROM_ENV_${var} TRUE CACHE INTERNAL "" FORCE) set(UPX_CACHE_ORIGIN_FROM_ENV_${var} TRUE CACHE INTERNAL "" FORCE)
endif() endif()
@@ -141,7 +155,7 @@ if(NOT is_multi_config AND NOT CMAKE_BUILD_TYPE)
endif() endif()
# CMake init # CMake init
project(upx VERSION 4.1.0 LANGUAGES C CXX) project(upx VERSION 4.2.1 LANGUAGES C CXX)
# set the default multi-config build type to "Release" # set the default multi-config build type to "Release"
if(is_multi_config) if(is_multi_config)
@@ -155,17 +169,43 @@ if(is_multi_config)
set(CMAKE_CONFIGURATION_TYPES "${c}" CACHE STRING "List of supported configuration types." FORCE) set(CMAKE_CONFIGURATION_TYPES "${c}" CACHE STRING "List of supported configuration types." FORCE)
endif() endif()
# set MSVC_FRONTEND # set MSVC_FRONTEND and MINGW
set(MSVC_FRONTEND 0) if(NOT DEFINED MSVC_FRONTEND AND (MSVC OR CMAKE_C_COMPILER_FRONTEND_VARIANT MATCHES "^MSVC"))
if(MSVC OR CMAKE_C_COMPILER_FRONTEND_VARIANT MATCHES "^MSVC")
set(MSVC_FRONTEND 1) set(MSVC_FRONTEND 1)
endif() endif()
if(NOT DEFINED MINGW AND CMAKE_C_PLATFORM_ID MATCHES "^MinGW")
set(MINGW 1)
endif()
#*********************************************************************** #***********************************************************************
# common compilation flags # common compilation flags
#*********************************************************************** #***********************************************************************
include(CheckCCompilerFlag) include(CheckCCompilerFlag)
include(CheckFunctionExists)
include(CheckIncludeFile)
include(CheckStructHasMember)
include(CheckSymbolExists)
if(NOT DEFINED HAVE_UNISTD_H)
check_include_file("unistd.h" HAVE_UNISTD_H)
endif()
if(NOT DEFINED HAVE_UTIMENSAT)
# proper checking for utimensat() is somewhat messy
check_function_exists(utimensat HAVE_UTIMENSAT_FUNCTION__)
if(HAVE_UTIMENSAT_FUNCTION__)
check_symbol_exists(utimensat "sys/types.h;fcntl.h;sys/stat.h" 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) # POSIX.1-2008
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) # macOS
endif()
if(HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC OR HAVE_STRUCT_STAT_ST_MTIMESPEC_TV_NSEC)
set(HAVE_UTIMENSAT 1)
endif()
endif()
endif()
endif()
if(UPX_CONFIG_DISABLE_WSTRICT) if(UPX_CONFIG_DISABLE_WSTRICT)
# enable all basic warnings # enable all basic warnings
@@ -185,10 +225,14 @@ else()
set(warn_Werror -Werror) set(warn_Werror -Werror)
set(warn_WX -WX) set(warn_WX -WX)
endif() endif()
if(MSVC_FRONTEND)
# disable warning C5105 which may get triggered by some older versions of <windows.h>
set(warn_WX -wd5105 ${warn_WX})
endif()
function(upx_add_definitions_with_prefix) function(upx_add_definitions_with_prefix)
set(flag_prefix "${ARGV0}") set(flag_prefix "${ARGV0}")
if(flag_prefix MATCHES "^dummy$") # need dummy to work around bug in old CMake versions if(flag_prefix MATCHES "^empty$") # need "empty" to work around bug in old CMake versions
set(flag_prefix "") set(flag_prefix "")
endif() endif()
list(REMOVE_AT ARGV 0) list(REMOVE_AT ARGV 0)
@@ -212,9 +256,9 @@ function(upx_add_definitions)
if(MSVC_FRONTEND AND CMAKE_C_COMPILER_ID MATCHES "Clang") if(MSVC_FRONTEND AND CMAKE_C_COMPILER_ID MATCHES "Clang")
# for clang-cl try "-clang:" flag prefix first # for clang-cl try "-clang:" flag prefix first
upx_add_definitions_with_prefix("-clang:" ${ARGV}) upx_add_definitions_with_prefix("-clang:" ${ARGV})
upx_add_definitions_with_prefix("dummy" ${failed_flags}) upx_add_definitions_with_prefix("empty" ${failed_flags})
else() else()
upx_add_definitions_with_prefix("dummy" ${ARGV}) upx_add_definitions_with_prefix("empty" ${ARGV})
endif() endif()
endfunction() endfunction()
@@ -225,12 +269,15 @@ if(NOT CMAKE_C_COMPILER_ID MATCHES "^MSVC")
set(CMAKE_C_FLAGS_RELEASE "${a}" CACHE STRING "Flags used by the C compiler during RELEASE builds." FORCE) set(CMAKE_C_FLAGS_RELEASE "${a}" CACHE STRING "Flags used by the C compiler during RELEASE builds." FORCE)
set(CMAKE_CXX_FLAGS_RELEASE "${b}" CACHE STRING "Flags used by the CXX compiler during RELEASE builds." FORCE) set(CMAKE_CXX_FLAGS_RELEASE "${b}" CACHE STRING "Flags used by the CXX compiler during RELEASE builds." FORCE)
endif() endif()
if(MSVC_FRONTEND) if(MSVC_FRONTEND OR WIN32 OR MINGW OR CYGWIN)
# disable silly warnings about using "deprecated" POSIX functions like fopen() # disable silly warnings about using "deprecated" POSIX functions like fopen()
add_definitions(-D_CRT_NONSTDC_NO_DEPRECATE) add_definitions(-D_CRT_NONSTDC_NO_DEPRECATE)
add_definitions(-D_CRT_NONSTDC_NO_WARNINGS) add_definitions(-D_CRT_NONSTDC_NO_WARNINGS)
add_definitions(-D_CRT_SECURE_NO_DEPRECATE) add_definitions(-D_CRT_SECURE_NO_DEPRECATE)
add_definitions(-D_CRT_SECURE_NO_WARNINGS) add_definitions(-D_CRT_SECURE_NO_WARNINGS)
add_definitions(-DWIN32_LEAN_AND_MEAN)
endif()
if(MSVC_FRONTEND)
# use -funsigned-char; set __cplusplus according to selected C++ standard # use -funsigned-char; set __cplusplus according to selected C++ standard
add_definitions(-J -Zc:__cplusplus) add_definitions(-J -Zc:__cplusplus)
if(CMAKE_C_COMPILER_ID MATCHES "^MSVC") if(CMAKE_C_COMPILER_ID MATCHES "^MSVC")
@@ -249,7 +296,7 @@ if(NOT CMAKE_C_COMPILER_ID MATCHES "^MSVC")
endif() endif()
endif() endif()
# compile a target with -O2 even in Debug build # compile a target with -O2 optimization even in Debug build
function(upx_compile_target_debug_with_O2) function(upx_compile_target_debug_with_O2)
foreach(t ${ARGV}) foreach(t ${ARGV})
if(MSVC_FRONTEND) if(MSVC_FRONTEND)
@@ -260,6 +307,34 @@ function(upx_compile_target_debug_with_O2)
endforeach() endforeach()
endfunction() endfunction()
# compile a source file with -O2 optimization even in Debug build; messy because of CMake limitations
function(upx_compile_source_debug_with_O2)
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(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()
# sanitize a target # sanitize a target
function(upx_sanitize_target) function(upx_sanitize_target)
foreach(t ${ARGV}) foreach(t ${ARGV})
@@ -267,7 +342,7 @@ function(upx_sanitize_target)
# no-op # no-op
elseif(MSVC_FRONTEND) elseif(MSVC_FRONTEND)
# MSVC uses -GS (similar to -fstack-protector) by default # MSVC uses -GS (similar to -fstack-protector) by default
elseif(CMAKE_C_PLATFORM_ID MATCHES "^MinGW" OR MINGW OR CYGWIN) elseif(MINGW OR CYGWIN)
# avoid link errors with current MinGW-w64 versions # avoid link errors with current MinGW-w64 versions
# see https://www.mingw-w64.org/contribute/#sanitizers-asan-tsan-usan # see https://www.mingw-w64.org/contribute/#sanitizers-asan-tsan-usan
else() else()
@@ -285,7 +360,7 @@ endfunction()
# targets # targets
#*********************************************************************** #***********************************************************************
# internal settings # internal settings; these may change in a future versions
set(UPX_CONFIG_DISABLE_THREADS ON) # multithreading is currently not used; maybe in UPX version 5 set(UPX_CONFIG_DISABLE_THREADS ON) # multithreading is currently not used; maybe in UPX version 5
set(UPX_CONFIG_DISABLE_BZIP2 ON) # bzip2 is currently not used; we might need it to decompress linux kernels set(UPX_CONFIG_DISABLE_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
@@ -372,10 +447,12 @@ set(t upx_vendor_zlib)
upx_compile_target_debug_with_O2(${t}) upx_compile_target_debug_with_O2(${t})
upx_sanitize_target(${t}) upx_sanitize_target(${t})
target_compile_definitions(${t} PRIVATE HAVE_VSNPRINTF=1) target_compile_definitions(${t} PRIVATE HAVE_VSNPRINTF=1)
if(HAVE_UNISTD_H)
target_compile_definitions(${t} PRIVATE HAVE_UNISTD_H=1)
endif()
if(MSVC_FRONTEND) if(MSVC_FRONTEND)
target_compile_options(${t} PRIVATE -W3 ${warn_WX}) target_compile_options(${t} PRIVATE -W3 ${warn_WX})
else() else()
target_compile_definitions(${t} PRIVATE HAVE_UNISTD_H=1)
target_compile_options(${t} PRIVATE -Wall ${warn_Werror}) 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()
@@ -416,6 +493,15 @@ 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)
endif() endif()
if(HAVE_UTIMENSAT)
target_compile_definitions(${t} PRIVATE USE_UTIMENSAT=1)
if(HAVE_STRUCT_STAT_ST_MTIMESPEC_TV_NSEC)
target_compile_definitions(${t} PRIVATE HAVE_STRUCT_STAT_ST_MTIMESPEC_TV_NSEC=1)
endif()
endif()
# improve speed of the Debug versions
upx_compile_source_debug_with_O2(src/compress/compress_lzma.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)
@@ -425,14 +511,16 @@ else()
endif() endif()
#*********************************************************************** #***********************************************************************
# ctest # test
# make test # ctest
# ninja test # make test
# ninja 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) if(NOT CMAKE_CROSSCOMPILING)
add_test(NAME upx-version COMMAND upx --version) add_test(NAME upx-version COMMAND upx --version)
add_test(NAME upx-help COMMAND upx --help) add_test(NAME upx-help COMMAND upx --help)
@@ -464,9 +552,10 @@ endif()
endif() # UPX_CONFIG_CMAKE_DISABLE_TEST endif() # UPX_CONFIG_CMAKE_DISABLE_TEST
#*********************************************************************** #***********************************************************************
# cmake --install . # install
# make install # cmake --install .
# ninja install # make install
# ninja install
#*********************************************************************** #***********************************************************************
if(NOT UPX_CONFIG_CMAKE_DISABLE_INSTALL) if(NOT UPX_CONFIG_CMAKE_DISABLE_INSTALL)
@@ -491,13 +580,16 @@ endif()
endif() # UPX_CONFIG_CMAKE_DISABLE_INSTALL endif() # UPX_CONFIG_CMAKE_DISABLE_INSTALL
#*********************************************************************** #***********************************************************************
# finally print some info about the build configuration # show summary
# print some info about the build configuration
#*********************************************************************** #***********************************************************************
function(print_var) function(print_var)
foreach(var ${ARGV}) foreach(var ${ARGV})
if(${var}) if(DEFINED ${var} AND NOT ",${${var}}," STREQUAL ",,")
message(STATUS "${var} = ${${var}}") if(${var})
message(STATUS "${var} = ${${var}}")
endif()
endif() endif()
endforeach() endforeach()
endfunction() endfunction()
+19 -181
View File
@@ -8,8 +8,8 @@
# HINT: if you only have an older CMake 3.x then you can invoke cmake manually like this: # HINT: if you only have an older CMake 3.x then you can invoke cmake manually like this:
# mkdir -p build/release # mkdir -p build/release
# cd build/release # cd build/release
# cmake ../.. # cmake ../.. # run config
# make -j (or use "cmake --build . --parallel") # make -j # and run build
CMAKE = cmake CMAKE = cmake
UPX_CMAKE_BUILD_FLAGS += --parallel UPX_CMAKE_BUILD_FLAGS += --parallel
@@ -40,192 +40,30 @@ build/release: PHONY
$(call run_config,$@,Release) $(call run_config,$@,Release)
$(call run_build,$@,Release) $(call run_build,$@,Release)
# shortcuts
all: build/debug build/release
debug: build/debug
release: build/release
.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)
debug: build/debug
release: build/release
all build/all: build/debug build/release
build/%/all: $$(dir $$@)debug $$(dir $$@)release ;
# #
# END of Makefile; extra stuff follows # END of Makefile
# #
#*********************************************************************** # extra pre-defined build configurations and some utility; optional
# extra builds: some pre-defined build configurations ifneq ($(MAKEFILE_LIST),)
#*********************************************************************** include $(dir $(lastword $(MAKEFILE_LIST)))/misc/make/Makefile-extra.mk
else
define run_config_and_build include ./misc/make/Makefile-extra.mk
$(call run_config,$1,$2)
$(call run_build,$1,$2)
endef
# force building with clang/clang++
build/extra/clang/debug: PHONY; $(call run_config_and_build,$@,Debug)
build/extra/clang/release: PHONY; $(call run_config_and_build,$@,Release)
build/extra/clang/%: export CC = clang
build/extra/clang/%: export CXX = clang++
# force building with clang/clang++ -m32
build/extra/clang-m32/debug: PHONY; $(call run_config_and_build,$@,Debug)
build/extra/clang-m32/release: PHONY; $(call run_config_and_build,$@,Release)
build/extra/clang-m32/%: export CC = clang -m32
build/extra/clang-m32/%: export CXX = clang++ -m32
# force building with clang/clang++ -mx32
build/extra/clang-mx32/debug: PHONY; $(call run_config_and_build,$@,Debug)
build/extra/clang-mx32/release: PHONY; $(call run_config_and_build,$@,Release)
build/extra/clang-mx32/%: export CC = clang -mx32
build/extra/clang-mx32/%: export CXX = clang++ -mx32
# force building with clang/clang++ -m64
build/extra/clang-m64/debug: PHONY; $(call run_config_and_build,$@,Debug)
build/extra/clang-m64/release: PHONY; $(call run_config_and_build,$@,Release)
build/extra/clang-m64/%: export CC = clang -m64
build/extra/clang-m64/%: export CXX = clang++ -m64
# force building with clang/clang++ -static
build/extra/clang-static/debug: PHONY; $(call run_config_and_build,$@,Debug)
build/extra/clang-static/release: PHONY; $(call run_config_and_build,$@,Release)
build/extra/clang-static/%: export CC = clang -static
build/extra/clang-static/%: export CXX = clang++ -static
# force building with gcc/g++
build/extra/gcc/debug: PHONY; $(call run_config_and_build,$@,Debug)
build/extra/gcc/release: PHONY; $(call run_config_and_build,$@,Release)
build/extra/gcc/%: export CC = gcc
build/extra/gcc/%: export CXX = g++
# force building with gcc/g++ -m32
build/extra/gcc-m32/debug: PHONY; $(call run_config_and_build,$@,Debug)
build/extra/gcc-m32/release: PHONY; $(call run_config_and_build,$@,Release)
build/extra/gcc-m32/%: export CC = gcc -m32
build/extra/gcc-m32/%: export CXX = g++ -m32
# force building with gcc/g++ -mx32
build/extra/gcc-mx32/debug: PHONY; $(call run_config_and_build,$@,Debug)
build/extra/gcc-mx32/release: PHONY; $(call run_config_and_build,$@,Release)
build/extra/gcc-mx32/%: export CC = gcc -mx32
build/extra/gcc-mx32/%: export CXX = g++ -mx32
# force building with gcc/g++ -m64
build/extra/gcc-m64/debug: PHONY; $(call run_config_and_build,$@,Debug)
build/extra/gcc-m64/release: PHONY; $(call run_config_and_build,$@,Release)
build/extra/gcc-m64/%: export CC = gcc -m64
build/extra/gcc-m64/%: export CXX = g++ -m64
# force building with gcc/g++ -static
build/extra/gcc-static/debug: PHONY; $(call run_config_and_build,$@,Debug)
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 CXX = g++ -static
# cross compiler: Linux glibc aarch64-linux-gnu (arm64)
build/extra/cross-linux-gnu-aarch64/debug: PHONY; $(call run_config_and_build,$@,Debug)
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 CXX = aarch64-linux-gnu-g++
# 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/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 CXX = arm-linux-gnueabihf-g++ -Wno-psabi
# 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/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 CXX = i686-w64-mingw32-g++ -static
# 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/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 CXX = x86_64-w64-mingw32-g++ -static
# cross compiler: macOS arm64 (aarch64)
build/extra/cross-darwin-arm64/debug: PHONY; $(call run_config_and_build,$@,Debug)
build/extra/cross-darwin-arm64/release: PHONY; $(call run_config_and_build,$@,Release)
build/extra/cross-darwin-arm64/%: export CC = clang -target arm64-apple-darwin
build/extra/cross-darwin-arm64/%: export CXX = clang++ -target arm64-apple-darwin
# cross compiler: macOS x86_64 (amd64)
build/extra/cross-darwin-x86_64/debug: PHONY; $(call run_config_and_build,$@,Debug)
build/extra/cross-darwin-x86_64/release: PHONY; $(call run_config_and_build,$@,Release)
build/extra/cross-darwin-x86_64/%: export CC = clang -target x86_64-apple-darwin
build/extra/cross-darwin-x86_64/%: export CXX = clang++ -target x86_64-apple-darwin
#***********************************************************************
# C/C++ static analyzers
#***********************************************************************
# force building with clang Static Analyzer (scan-build)
build/analyze/clang-analyzer/debug: PHONY; $(call run_config_and_build,$@,Debug)
build/analyze/clang-analyzer/release: PHONY; $(call run_config_and_build,$@,Release)
build/analyze/clang-analyzer/%: CMAKE := scan-build $(CMAKE)
build/analyze/clang-analyzer/%: export CCC_CC ?= clang
build/analyze/clang-analyzer/%: export CCC_CXX ?= clang++
# run clang-tidy: uses file compile_commands.json from an existing clang build
# does not create any actual files, so purely PHONY
RUN_CLANG_TIDY = time python3 ./misc/analyze/clang-tidy/run-clang-tidy.py -p $<
RUN_CLANG_TIDY_WERROR = $(RUN_CLANG_TIDY) '-warnings-as-errors=*'
build/analyze/clang-tidy-upx/debug build/analyze/clang-tidy-upx/release: build/extra/clang/$$(notdir $$@) PHONY
$(RUN_CLANG_TIDY_WERROR) -config-file ./.clang-tidy '/src/.*\.cpp'
build/analyze/clang-tidy-bzip2/debug build/analyze/clang-tidy-bzip2/release: build/extra/clang/$$(notdir $$@) PHONY
$(RUN_CLANG_TIDY) -config-file ./misc/analyze/clang-tidy/clang-tidy-bzip2.yml /vendor/bzip2/
build/analyze/clang-tidy-ucl/debug build/analyze/clang-tidy-ucl/release: build/extra/clang/$$(notdir $$@) PHONY
$(RUN_CLANG_TIDY_WERROR) -config-file ./misc/analyze/clang-tidy/clang-tidy-ucl.yml /vendor/ucl/
build/analyze/clang-tidy-zlib/debug build/analyze/clang-tidy-zlib/release: build/extra/clang/$$(notdir $$@) PHONY
$(RUN_CLANG_TIDY_WERROR) -config-file ./misc/analyze/clang-tidy/clang-tidy-zlib.yml /vendor/zlib/
build/analyze/clang-tidy-zstd/debug build/analyze/clang-tidy-zstd/release: build/extra/clang/$$(notdir $$@) PHONY
$(RUN_CLANG_TIDY) -config-file ./misc/analyze/clang-tidy/clang-tidy-zstd.yml /vendor/zstd/
build/analyze/clang-tidy/debug build/analyze/clang-tidy/release: build/analyze/clang-tidy-upx/$$(notdir $$@)
build/analyze/clang-tidy/debug build/analyze/clang-tidy/release: build/analyze/clang-tidy-bzip2/$$(notdir $$@)
build/analyze/clang-tidy/debug build/analyze/clang-tidy/release: build/analyze/clang-tidy-ucl/$$(notdir $$@)
build/analyze/clang-tidy/debug build/analyze/clang-tidy/release: build/analyze/clang-tidy-zlib/$$(notdir $$@)
build/analyze/clang-tidy/debug build/analyze/clang-tidy/release: build/analyze/clang-tidy-zstd/$$(notdir $$@)
# OLD names
build/extra/scan-build/debug: build/analyze/clang-analyzer/debug
build/extra/scan-build/release: build/analyze/clang-analyzer/release
#***********************************************************************
# advanced: generic extra target
#***********************************************************************
# usage:
# make UPX_XTARGET=my-target CC="my-cc -flags" CXX="my-cxx -flags"
# make UPX_XTARGET=my-target CC="my-cc -flags" CXX="my-cxx -flags" xtarget/debug
ifneq ($(UPX_XTARGET),)
ifneq ($(CC),)
ifneq ($(CXX),)
UPX_XTARGET := $(UPX_XTARGET)
build/xtarget/$(UPX_XTARGET)/debug: PHONY; $(call run_config_and_build,$@,Debug)
build/xtarget/$(UPX_XTARGET)/release: PHONY; $(call run_config_and_build,$@,Release)
build/xtarget/$(UPX_XTARGET)/%: export CC
build/xtarget/$(UPX_XTARGET)/%: export CXX
# shortcuts
xtarget/debug: build/xtarget/$(UPX_XTARGET)/debug
xtarget/release: build/xtarget/$(UPX_XTARGET)/release
# set new default
.DEFAULT_GOAL = xtarget/release
endif
endif
endif endif
#*********************************************************************** # developer convenience
# check git submodules ifneq ($(wildcard /usr/bin/env),) # needs bash, perl, xargs, etc.
#*********************************************************************** check-whitespace clang-format run-testsuite run-testsuite-debug run-testsuite-release: PHONY src/Makefile
$(MAKE) -C src $@
SUBMODULES = doctest lzma-sdk ucl valgrind zlib endif
dummy := $(foreach m,$(SUBMODULES),$(if $(wildcard vendor/$m/[CL]*),$m,\
$(error ERROR: missing git submodule '$m'; run 'git submodule update --init')))
+15
View File
@@ -2,6 +2,21 @@
User visible changes for UPX User visible changes for UPX
================================================================== ==================================================================
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):
* 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)
* add support for NO_COLOR env var; see https://no-color.org/
* 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
Changes in 4.1.0 (08 Aug 2023): Changes in 4.1.0 (08 Aug 2023):
* ELF: handle shared libraries with more than 2 PT_LOAD segments * ELF: handle shared libraries with more than 2 PT_LOAD segments
* bug fixes - see https://github.com/upx/upx/milestone/11 * bug fixes - see https://github.com/upx/upx/milestone/11
+1 -1
View File
@@ -35,7 +35,7 @@ and run exactly as before, with no runtime or memory penalty for most
of the supported formats. of the supported formats.
UPX supports a number of different executable formats, including UPX supports a number of different executable formats, including
Windows programs and DLLs, macOS apps and Linux executables. Windows programs and DLLs, and Linux executables.
UPX is free software distributed under the term of the GNU General UPX is free software distributed under the term of the GNU General
Public License. Full source code is available. Public License. Full source code is available.
Generated
+1 -1
View File
@@ -133,7 +133,7 @@
.\" ======================================================================== .\" ========================================================================
.\" .\"
.IX Title "UPX 1" .IX Title "UPX 1"
.TH UPX 1 "2023-08-08" "upx 4.1.0" " " .TH UPX 1 "2023-11-01" "upx 4.2.1" " "
.\" 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
+49 -15
View File
@@ -308,10 +308,21 @@ def main():
if yaml: if yaml:
parser.add_argument( parser.add_argument(
"-export-fixes", "-export-fixes",
metavar="filename", metavar="file_or_directory",
dest="export_fixes", dest="export_fixes",
help="Create a yaml file to store suggested fixes in, " help="A directory or a yaml file to store suggested fixes in, "
"which can be applied with clang-apply-replacements.", "which can be applied with clang-apply-replacements. If the "
"parameter is a directory, the fixes of each compilation unit are "
"stored in individual yaml files in the directory.",
)
else:
parser.add_argument(
"-export-fixes",
metavar="directory",
dest="export_fixes",
help="A directory to store suggested fixes in, which can be applied "
"with clang-apply-replacements. The fixes of each compilation unit are "
"stored in individual yaml files in the directory.",
) )
parser.add_argument( parser.add_argument(
"-j", "-j",
@@ -384,12 +395,35 @@ def main():
clang_tidy_binary = find_binary(args.clang_tidy_binary, "clang-tidy", build_path) clang_tidy_binary = find_binary(args.clang_tidy_binary, "clang-tidy", build_path)
tmpdir = None
if args.fix: if args.fix:
clang_apply_replacements_binary = find_binary( clang_apply_replacements_binary = find_binary(
args.clang_apply_replacements_binary, "clang-apply-replacements", build_path args.clang_apply_replacements_binary, "clang-apply-replacements", build_path
) )
tmpdir = tempfile.mkdtemp()
combine_fixes = False
export_fixes_dir = None
delete_fixes_dir = False
if args.export_fixes is not None:
# if a directory is given, create it if it does not exist
if args.export_fixes.endswith(os.path.sep) and not os.path.isdir(
args.export_fixes
):
os.makedirs(args.export_fixes)
if not os.path.isdir(args.export_fixes):
if not yaml:
raise RuntimeError(
"Cannot combine fixes in one yaml file. Either install PyYAML or specify an output directory."
)
combine_fixes = True
if os.path.isdir(args.export_fixes):
export_fixes_dir = args.export_fixes
if export_fixes_dir is None and (args.fix or combine_fixes):
export_fixes_dir = tempfile.mkdtemp()
delete_fixes_dir = True
# Load the database and extract all files. # Load the database and extract all files.
database = json.load(open(os.path.join(build_path, db_path))) database = json.load(open(os.path.join(build_path, db_path)))
@@ -408,8 +442,8 @@ def main():
matched_files.append(name) matched_files.append(name)
files = sorted(matched_files) files = sorted(matched_files)
if not files: if not files:
if tmpdir: if delete_fixes_dir:
shutil.rmtree(tmpdir) shutil.rmtree(export_fixes_dir)
sys.exit(0) sys.exit(0)
try: try:
@@ -460,7 +494,7 @@ def main():
args=( args=(
args, args,
clang_tidy_binary, clang_tidy_binary,
tmpdir, export_fixes_dir,
build_path, build_path,
task_queue, task_queue,
lock, lock,
@@ -484,14 +518,14 @@ def main():
# This is a sad hack. Unfortunately subprocess goes # This is a sad hack. Unfortunately subprocess goes
# bonkers with ctrl-c and we start forking merrily. # bonkers with ctrl-c and we start forking merrily.
print("\nCtrl-C detected, goodbye.") print("\nCtrl-C detected, goodbye.")
if tmpdir: if delete_fixes_dir:
shutil.rmtree(tmpdir) shutil.rmtree(export_fixes_dir)
os.kill(0, 9) os.kill(0, 9)
if yaml and args.export_fixes: if combine_fixes:
print("Writing fixes to " + args.export_fixes + " ...") print("Writing fixes to " + args.export_fixes + " ...")
try: try:
merge_replacement_files(tmpdir, args.export_fixes) merge_replacement_files(export_fixes_dir, args.export_fixes)
except: except:
print("Error exporting fixes.\n", file=sys.stderr) print("Error exporting fixes.\n", file=sys.stderr)
traceback.print_exc() traceback.print_exc()
@@ -500,14 +534,14 @@ def main():
if args.fix: if args.fix:
print("Applying fixes ...") print("Applying fixes ...")
try: try:
apply_fixes(args, clang_apply_replacements_binary, tmpdir) apply_fixes(args, clang_apply_replacements_binary, export_fixes_dir)
except: except:
print("Error applying fixes.\n", file=sys.stderr) print("Error applying fixes.\n", file=sys.stderr)
traceback.print_exc() traceback.print_exc()
return_code = 1 return_code = 1
if tmpdir: if delete_fixes_dir:
shutil.rmtree(tmpdir) shutil.rmtree(export_fixes_dir)
sys.exit(return_code) sys.exit(return_code)
+256
View File
@@ -0,0 +1,256 @@
#
# UPX top-level Makefile - needs GNU make and CMake >= 3.13
# Copyright (C) Markus Franz Xaver Johannes Oberhumer
#
ifeq ($(UPX_MAKEFILE_EXTRA_MK_INCLUDED),)
UPX_MAKEFILE_EXTRA_MK_INCLUDED := 1
#***********************************************************************
# extra builds: some pre-defined build configurations
#***********************************************************************
define run_config_and_build
$(call run_config,$1,$2)
$(call run_build,$1,$2)
endef
# force building with clang/clang++
build/extra/clang/debug: PHONY; $(call run_config_and_build,$@,Debug)
build/extra/clang/release: PHONY; $(call run_config_and_build,$@,Release)
build/extra/clang/%: export CC = clang
build/extra/clang/%: export CXX = clang++
# force building with clang/clang++ -m32
build/extra/clang-m32/debug: PHONY; $(call run_config_and_build,$@,Debug)
build/extra/clang-m32/release: PHONY; $(call run_config_and_build,$@,Release)
build/extra/clang-m32/%: export CC = clang -m32
build/extra/clang-m32/%: export CXX = clang++ -m32
# force building with clang/clang++ -mx32
build/extra/clang-mx32/debug: PHONY; $(call run_config_and_build,$@,Debug)
build/extra/clang-mx32/release: PHONY; $(call run_config_and_build,$@,Release)
build/extra/clang-mx32/%: export CC = clang -mx32
build/extra/clang-mx32/%: export CXX = clang++ -mx32
# force building with clang/clang++ -m64
build/extra/clang-m64/debug: PHONY; $(call run_config_and_build,$@,Debug)
build/extra/clang-m64/release: PHONY; $(call run_config_and_build,$@,Release)
build/extra/clang-m64/%: export CC = clang -m64
build/extra/clang-m64/%: export CXX = clang++ -m64
# force building with clang/clang++ -static
build/extra/clang-static/debug: PHONY; $(call run_config_and_build,$@,Debug)
build/extra/clang-static/release: PHONY; $(call run_config_and_build,$@,Release)
build/extra/clang-static/%: export CC = clang -static
build/extra/clang-static/%: export CXX = clang++ -static
# force building with clang/clang++ -static -flto
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/%: export CC = clang -static -flto
build/extra/clang-static-lto/%: export CXX = clang++ -static -flto
# force building with clang/clang++ C17/C++20
build/extra/clang-std-cxx20/debug: PHONY; $(call run_config_and_build,$@,Debug)
build/extra/clang-std-cxx20/release: PHONY; $(call run_config_and_build,$@,Release)
build/extra/clang-std-cxx20/%: export CC = clang -std=gnu17
build/extra/clang-std-cxx20/%: export CXX = clang++ -std=gnu++20
build/extra/clang-std-cxx20/%: export UPX_CONFIG_DISABLE_C_STANDARD=ON
build/extra/clang-std-cxx20/%: export UPX_CONFIG_DISABLE_CXX_STANDARD=ON
# force building with clang/clang++ C23/C++23
build/extra/clang-std-cxx23/debug: PHONY; $(call run_config_and_build,$@,Debug)
build/extra/clang-std-cxx23/release: PHONY; $(call run_config_and_build,$@,Release)
build/extra/clang-std-cxx23/%: export CC = clang -std=gnu2x
build/extra/clang-std-cxx23/%: export CXX = clang++ -std=gnu++2b
build/extra/clang-std-cxx23/%: export UPX_CONFIG_DISABLE_C_STANDARD=ON
build/extra/clang-std-cxx23/%: export UPX_CONFIG_DISABLE_CXX_STANDARD=ON
# force building with gcc/g++
build/extra/gcc/debug: PHONY; $(call run_config_and_build,$@,Debug)
build/extra/gcc/release: PHONY; $(call run_config_and_build,$@,Release)
build/extra/gcc/%: export CC = gcc
build/extra/gcc/%: export CXX = g++
# force building with gcc/g++ -m32
build/extra/gcc-m32/debug: PHONY; $(call run_config_and_build,$@,Debug)
build/extra/gcc-m32/release: PHONY; $(call run_config_and_build,$@,Release)
build/extra/gcc-m32/%: export CC = gcc -m32
build/extra/gcc-m32/%: export CXX = g++ -m32
# force building with gcc/g++ -mx32
build/extra/gcc-mx32/debug: PHONY; $(call run_config_and_build,$@,Debug)
build/extra/gcc-mx32/release: PHONY; $(call run_config_and_build,$@,Release)
build/extra/gcc-mx32/%: export CC = gcc -mx32
build/extra/gcc-mx32/%: export CXX = g++ -mx32
# force building with gcc/g++ -m64
build/extra/gcc-m64/debug: PHONY; $(call run_config_and_build,$@,Debug)
build/extra/gcc-m64/release: PHONY; $(call run_config_and_build,$@,Release)
build/extra/gcc-m64/%: export CC = gcc -m64
build/extra/gcc-m64/%: export CXX = g++ -m64
# force building with gcc/g++ -static
build/extra/gcc-static/debug: PHONY; $(call run_config_and_build,$@,Debug)
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 CXX = g++ -static
# 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/release: PHONY; $(call run_config_and_build,$@,Release)
build/extra/gcc-static-lto/%: export CC = gcc -static -flto
build/extra/gcc-static-lto/%: export CXX = g++ -static -flto
# force building with gcc/g++ C17/C++20
build/extra/gcc-std-cxx20/debug: PHONY; $(call run_config_and_build,$@,Debug)
build/extra/gcc-std-cxx20/release: PHONY; $(call run_config_and_build,$@,Release)
build/extra/gcc-std-cxx20/%: export CC = gcc -std=gnu17
build/extra/gcc-std-cxx20/%: export CXX = g++ -std=gnu++20
build/extra/gcc-std-cxx20/%: export UPX_CONFIG_DISABLE_C_STANDARD=ON
build/extra/gcc-std-cxx20/%: export UPX_CONFIG_DISABLE_CXX_STANDARD=ON
# force building with gcc/g++ C23/C++23
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/%: export CC = gcc -std=gnu2x
build/extra/gcc-std-cxx23/%: export CXX = g++ -std=gnu++23
build/extra/gcc-std-cxx23/%: export UPX_CONFIG_DISABLE_C_STANDARD=ON
build/extra/gcc-std-cxx23/%: export UPX_CONFIG_DISABLE_CXX_STANDARD=ON
# cross compiler: Linux glibc aarch64-linux-gnu (arm64)
build/extra/cross-linux-gnu-aarch64/debug: PHONY; $(call run_config_and_build,$@,Debug)
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 CXX = aarch64-linux-gnu-g++
# 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/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 CXX = arm-linux-gnueabihf-g++ -Wno-psabi
# 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/release: PHONY; $(call run_config_and_build,$@,Release)
build/extra/cross-windows-mingw32/%: export CC = i686-w64-mingw32-gcc -static -D_WIN32_WINNT=0x0400
build/extra/cross-windows-mingw32/%: export CXX = i686-w64-mingw32-g++ -static -D_WIN32_WINNT=0x0400
# 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/release: PHONY; $(call run_config_and_build,$@,Release)
build/extra/cross-windows-mingw64/%: export CC = x86_64-w64-mingw32-gcc -static -D_WIN32_WINNT=0x0400
build/extra/cross-windows-mingw64/%: export CXX = x86_64-w64-mingw32-g++ -static -D_WIN32_WINNT=0x0400
# cross compiler: macOS arm64 (aarch64)
build/extra/cross-darwin-arm64/debug: PHONY; $(call run_config_and_build,$@,Debug)
build/extra/cross-darwin-arm64/release: PHONY; $(call run_config_and_build,$@,Release)
build/extra/cross-darwin-arm64/%: export CC = clang -target arm64-apple-darwin
build/extra/cross-darwin-arm64/%: export CXX = clang++ -target arm64-apple-darwin
# cross compiler: macOS x86_64 (amd64)
build/extra/cross-darwin-x86_64/debug: PHONY; $(call run_config_and_build,$@,Debug)
build/extra/cross-darwin-x86_64/release: PHONY; $(call run_config_and_build,$@,Release)
build/extra/cross-darwin-x86_64/%: export CC = clang -target x86_64-apple-darwin
build/extra/cross-darwin-x86_64/%: export CXX = clang++ -target x86_64-apple-darwin
#***********************************************************************
# C/C++ static analyzers
#***********************************************************************
# force building with clang Static Analyzer (scan-build)
SCAN_BUILD = scan-build
build/analyze/clang-analyzer/debug: PHONY; $(call run_config_and_build,$@,Debug)
build/analyze/clang-analyzer/release: PHONY; $(call run_config_and_build,$@,Release)
build/analyze/clang-analyzer/%: override CMAKE := $(SCAN_BUILD) $(CMAKE)
build/analyze/clang-analyzer/%: export CCC_CC ?= clang
build/analyze/clang-analyzer/%: export CCC_CXX ?= clang++
# run clang-tidy: uses file compile_commands.json from an existing clang build
# does not create any actual files, so purely PHONY
RUN_CLANG_TIDY = time python3 ./misc/analyze/clang-tidy/run-clang-tidy.py -p $<
RUN_CLANG_TIDY_WERROR = $(RUN_CLANG_TIDY) '-warnings-as-errors=*'
build/analyze/clang-tidy-upx/debug build/analyze/clang-tidy-upx/release: build/extra/clang/$$(notdir $$@) PHONY
$(RUN_CLANG_TIDY_WERROR) -config-file ./.clang-tidy '/src/.*\.cpp'
build/analyze/clang-tidy-bzip2/debug build/analyze/clang-tidy-bzip2/release: build/extra/clang/$$(notdir $$@) PHONY
$(RUN_CLANG_TIDY) -config-file ./misc/analyze/clang-tidy/clang-tidy-bzip2.yml /vendor/bzip2/
build/analyze/clang-tidy-ucl/debug build/analyze/clang-tidy-ucl/release: build/extra/clang/$$(notdir $$@) PHONY
$(RUN_CLANG_TIDY_WERROR) -config-file ./misc/analyze/clang-tidy/clang-tidy-ucl.yml /vendor/ucl/
build/analyze/clang-tidy-zlib/debug build/analyze/clang-tidy-zlib/release: build/extra/clang/$$(notdir $$@) PHONY
$(RUN_CLANG_TIDY_WERROR) -config-file ./misc/analyze/clang-tidy/clang-tidy-zlib.yml /vendor/zlib/
build/analyze/clang-tidy-zstd/debug build/analyze/clang-tidy-zstd/release: build/extra/clang/$$(notdir $$@) PHONY
$(RUN_CLANG_TIDY) -config-file ./misc/analyze/clang-tidy/clang-tidy-zstd.yml /vendor/zstd/
build/analyze/clang-tidy/debug build/analyze/clang-tidy/release: build/analyze/clang-tidy-upx/$$(notdir $$@)
build/analyze/clang-tidy/debug build/analyze/clang-tidy/release: build/analyze/clang-tidy-bzip2/$$(notdir $$@)
build/analyze/clang-tidy/debug build/analyze/clang-tidy/release: build/analyze/clang-tidy-ucl/$$(notdir $$@)
build/analyze/clang-tidy/debug build/analyze/clang-tidy/release: build/analyze/clang-tidy-zlib/$$(notdir $$@)
build/analyze/clang-tidy/debug build/analyze/clang-tidy/release: build/analyze/clang-tidy-zstd/$$(notdir $$@)
# OLD names [deprecated]
build/extra/scan-build/debug: build/analyze/clang-analyzer/debug
build/extra/scan-build/release: build/analyze/clang-analyzer/release
#***********************************************************************
# advanced: generic extra target
#***********************************************************************
# usage:
# make UPX_XTARGET=my-target CC="my-cc -flags" CXX="my-cxx -flags"
# make UPX_XTARGET=my-target CC="my-cc -flags" CXX="my-cxx -flags" xtarget/debug
ifneq ($(UPX_XTARGET),)
ifneq ($(CC),)
ifneq ($(CXX),)
UPX_XTARGET := $(UPX_XTARGET)
build/xtarget/$(UPX_XTARGET)/debug: PHONY; $(call run_config_and_build,$@,Debug)
build/xtarget/$(UPX_XTARGET)/release: PHONY; $(call run_config_and_build,$@,Release)
build/xtarget/$(UPX_XTARGET)/%: export CC
build/xtarget/$(UPX_XTARGET)/%: export CXX
# shortcuts
xtarget/all: xtarget/debug xtarget/release
xtarget/debug: build/xtarget/$(UPX_XTARGET)/debug
xtarget/release: build/xtarget/$(UPX_XTARGET)/release
# set new default
.DEFAULT_GOAL = xtarget/release
endif
endif
endif
#***********************************************************************
# 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
# 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
#***********************************************************************
# check git submodules
#***********************************************************************
SUBMODULES = doctest lzma-sdk ucl valgrind zlib
dummy := $(foreach m,$(SUBMODULES),$(if $(wildcard vendor/$m/[CL]*),$m,\
$(error ERROR: missing git submodule '$m'; run 'git submodule update --init')))
endif # UPX_MAKEFILE_EXTRA_MK_INCLUDED
@@ -49,7 +49,7 @@ function run_config_and_build {
# run_config # run_config
if [[ ! -f $bdir/CMakeCache.txt ]]; then if [[ ! -f $bdir/CMakeCache.txt ]]; then
export CMAKE_REQUIRED_QUIET=OFF export CMAKE_REQUIRED_QUIET=OFF
cmake -S . -B "$bdir" -DCMAKE_BUILD_TYPE=$build_type -DCMAKE_AR=$AR -DCMAKE_RANLIB=$RANLIB $cmake_config_flags cmake -S . -B "$bdir" -DCMAKE_BUILD_TYPE=$build_type -DCMAKE_AR="$AR" -DCMAKE_RANLIB="$RANLIB" $cmake_config_flags
fi fi
# run_build # run_build
cmake --build "$bdir" --config $build_type --parallel cmake --build "$bdir" --config $build_type --parallel
@@ -93,7 +93,7 @@ do
export CC=/usr/bin/${toolchain}-gcc export CC=/usr/bin/${toolchain}-gcc
export CXX=/usr/bin/${toolchain}-g++ export CXX=/usr/bin/${toolchain}-g++
export RANLIB=/usr/bin/${toolchain}-ranlib export RANLIB=/usr/bin/${toolchain}-ranlib
ls -l $AR $CC $CXX $RANLIB ls -l "$AR" "$CC" "$CXX" "$RANLIB"
run_config_and_build $toolchain run_config_and_build $toolchain
unset AR CC CXX RANLIB unset AR CC CXX RANLIB
done done
File diff suppressed because it is too large Load Diff
+4 -2
View File
@@ -16,6 +16,7 @@ RUN dpkg --add-architecture i386 \
7zip bfs busybox bzip2 cabextract ccache chrpath cmake cpio curl elfutils fd-find file fzf \ 7zip bfs busybox bzip2 cabextract ccache chrpath cmake cpio curl elfutils fd-find file fzf \
g++ gawk gdb gojq ht htop hyperfine jq libzstd-dev lsb-release lz4 lzip lzop \ g++ gawk gdb gojq ht htop hyperfine jq libzstd-dev lsb-release lz4 lzip lzop \
mksh moreutils ninja-build p7zip parallel patch patchelf pax-utils paxctl \ mksh moreutils ninja-build p7zip parallel patch patchelf pax-utils paxctl \
python3 python3-pyasn1 python3-pycryptodome python3-zstd \
re2c ripgrep rsync screen universal-ctags unzip vim yash zip zlib1g-dev zsh zstd \ re2c ripgrep rsync screen universal-ctags unzip vim yash zip zlib1g-dev zsh zstd \
# extra packages for compiling with "gcc -m32" and and "gcc -mx32": # extra packages for compiling with "gcc -m32" and and "gcc -mx32":
g++-multilib gcc-multilib \ g++-multilib gcc-multilib \
@@ -44,9 +45,10 @@ 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; do wget -q https://github.com/upx/upx/releases/download/v${v}/upx-${v}-amd64_linux.tar.xz; done \ && xzlist="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" \
&& for v in $xzlist; 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; do d=upx-${v}-amd64_linux; ./$d/upx -qq -d $d/upx -o /usr/local/bin/upx-${v}; done \ && for v in 3.91 $xzlist; 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
+129 -123
View File
@@ -3,16 +3,16 @@ Packages:
Desired=Unknown/Install/Remove/Purge/Hold Desired=Unknown/Install/Remove/Purge/Hold
ii 7zip 21.07+dfsg-4 amd64 7-Zip file archiver with a high compression ratio ii 7zip 21.07+dfsg-4 amd64 7-Zip file archiver with a high compression ratio
ii adduser 3.118ubuntu5 all add and remove users and groups ii adduser 3.118ubuntu5 all add and remove users and groups
ii apt 2.4.9 amd64 commandline package manager ii apt 2.4.10 amd64 commandline package manager
ii aria2 1.36.0-1 amd64 High speed download utility ii aria2 1.36.0-1 amd64 High speed download utility
ii base-files 12ubuntu4.3 amd64 Debian base system miscellaneous files ii base-files 12ubuntu4.4 amd64 Debian base system miscellaneous files
ii base-passwd 3.5.52build1 amd64 Debian base system master password and group files ii base-passwd 3.5.52build1 amd64 Debian base system master password and group files
ii bash 5.1-6ubuntu1 amd64 GNU Bourne Again SHell ii bash 5.1-6ubuntu1 amd64 GNU Bourne Again SHell
ii bash-completion 1:2.11-5ubuntu1 all programmable completion for the bash shell ii bash-completion 1:2.11-5ubuntu1 all programmable completion for the bash shell
ii bfs 2.3.1-1 amd64 Breadth-first version of find(1) ii bfs 2.3.1-1 amd64 Breadth-first version of find(1)
ii binutils 2.38-4ubuntu2.2 amd64 GNU assembler, linker and binary utilities ii binutils 2.38-4ubuntu2.3 amd64 GNU assembler, linker and binary utilities
ii binutils-common:amd64 2.38-4ubuntu2.2 amd64 Common files for the GNU assembler, linker and binary utilities ii binutils-common:amd64 2.38-4ubuntu2.3 amd64 Common files for the GNU assembler, linker and binary utilities
ii binutils-x86-64-linux-gnu 2.38-4ubuntu2.2 amd64 GNU binary utilities, for x86-64-linux-gnu target ii binutils-x86-64-linux-gnu 2.38-4ubuntu2.3 amd64 GNU binary utilities, for x86-64-linux-gnu target
ii bsdutils 1:2.37.2-4ubuntu3 amd64 basic utilities from 4.4BSD-Lite ii bsdutils 1:2.37.2-4ubuntu3 amd64 basic utilities from 4.4BSD-Lite
ii busybox 1:1.30.1-7ubuntu3 amd64 Tiny utilities for small and embedded systems ii busybox 1:1.30.1-7ubuntu3 amd64 Tiny utilities for small and embedded systems
ii bzip2 1.0.8-5build1 amd64 high-quality block-sorting file compressor - utilities ii bzip2 1.0.8-5build1 amd64 high-quality block-sorting file compressor - utilities
@@ -25,37 +25,37 @@ ii cmake-data 3.22.1-1ubuntu1.22.04.1 all
ii coreutils 8.32-4.1ubuntu1 amd64 GNU core utilities ii coreutils 8.32-4.1ubuntu1 amd64 GNU core utilities
ii cpio 2.13+dfsg-7 amd64 GNU cpio -- a program to manage archives of files ii cpio 2.13+dfsg-7 amd64 GNU cpio -- a program to manage archives of files
ii cpp 4:11.2.0-1ubuntu1 amd64 GNU C preprocessor (cpp) ii cpp 4:11.2.0-1ubuntu1 amd64 GNU C preprocessor (cpp)
ii cpp-11 11.3.0-1ubuntu1~22.04.1 amd64 GNU C preprocessor ii cpp-11 11.4.0-1ubuntu1~22.04 amd64 GNU C preprocessor
ii curl 7.81.0-1ubuntu1.13 amd64 command line tool for transferring data with URL syntax ii curl 7.81.0-1ubuntu1.14 amd64 command line tool for transferring data with URL syntax
ii dash 0.5.11+git20210903+057cd650a4ed-3build1 amd64 POSIX-compliant shell ii dash 0.5.11+git20210903+057cd650a4ed-3build1 amd64 POSIX-compliant shell
ii debconf 1.5.79ubuntu1 all Debian configuration management system ii debconf 1.5.79ubuntu1 all Debian configuration management system
ii debianutils 5.5-1ubuntu2 amd64 Miscellaneous utilities specific to Debian ii debianutils 5.5-1ubuntu2 amd64 Miscellaneous utilities specific to Debian
ii dh-elpa-helper 2.0.9ubuntu1 all helper package for emacs lisp extensions ii dh-elpa-helper 2.0.9ubuntu1 all helper package for emacs lisp extensions
ii diffutils 1:3.8-0ubuntu2 amd64 File comparison utilities ii diffutils 1:3.8-0ubuntu2 amd64 File comparison utilities
ii distro-info-data 0.52ubuntu0.4 all information about the distributions' releases (data files) ii distro-info-data 0.52ubuntu0.5 all information about the distributions' releases (data files)
ii dpkg 1.21.1ubuntu2.2 amd64 Debian package management system ii dpkg 1.21.1ubuntu2.2 amd64 Debian package management system
ii e2fsprogs 1.46.5-2ubuntu1.1 amd64 ext2/ext3/ext4 file system utilities ii e2fsprogs 1.46.5-2ubuntu1.1 amd64 ext2/ext3/ext4 file system utilities
ii elfutils 0.186-1build1 amd64 collection of utilities to handle ELF objects ii elfutils 0.186-1build1 amd64 collection of utilities to handle ELF objects
ii emacsen-common 3.0.4 all Common facilities for all emacsen ii emacsen-common 3.0.4 all Common facilities for all emacsen
ii fd-find 8.3.1-1ubuntu0.1 amd64 Simple, fast and user-friendly alternative to find ii fd-find 8.3.1-1ubuntu0.1 amd64 Simple, fast and user-friendly alternative to find
ii file 1:5.41-3 amd64 Recognize the type of data in a file using "magic" numbers ii file 1:5.41-3ubuntu0.1 amd64 Recognize the type of data in a file using "magic" numbers
ii findutils 4.8.0-1ubuntu3 amd64 utilities for finding files--find, xargs ii findutils 4.8.0-1ubuntu3 amd64 utilities for finding files--find, xargs
ii fzf 0.29.0-1 amd64 general-purpose command-line fuzzy finder ii fzf 0.29.0-1 amd64 general-purpose command-line fuzzy finder
ii g++ 4:11.2.0-1ubuntu1 amd64 GNU C++ compiler ii g++ 4:11.2.0-1ubuntu1 amd64 GNU C++ compiler
ii g++-11 11.3.0-1ubuntu1~22.04.1 amd64 GNU C++ compiler ii g++-11 11.4.0-1ubuntu1~22.04 amd64 GNU C++ compiler
ii g++-11-multilib 11.3.0-1ubuntu1~22.04.1 amd64 GNU C++ compiler (multilib support) ii g++-11-multilib 11.4.0-1ubuntu1~22.04 amd64 GNU C++ compiler (multilib support)
ii g++-multilib 4:11.2.0-1ubuntu1 amd64 GNU C++ compiler (multilib files) ii g++-multilib 4:11.2.0-1ubuntu1 amd64 GNU C++ compiler (multilib files)
ii gawk 1:5.1.0-1build3 amd64 GNU awk, a pattern scanning and processing language ii gawk 1:5.1.0-1ubuntu0.1 amd64 GNU awk, a pattern scanning and processing language
ii gcc 4:11.2.0-1ubuntu1 amd64 GNU C compiler ii gcc 4:11.2.0-1ubuntu1 amd64 GNU C compiler
ii gcc-11 11.3.0-1ubuntu1~22.04.1 amd64 GNU C compiler ii gcc-11 11.4.0-1ubuntu1~22.04 amd64 GNU C compiler
ii gcc-11-base:amd64 11.3.0-1ubuntu1~22.04.1 amd64 GCC, the GNU Compiler Collection (base package) ii gcc-11-base:amd64 11.4.0-1ubuntu1~22.04 amd64 GCC, the GNU Compiler Collection (base package)
ii gcc-11-multilib 11.3.0-1ubuntu1~22.04.1 amd64 GNU C compiler (multilib support) ii gcc-11-multilib 11.4.0-1ubuntu1~22.04 amd64 GNU C compiler (multilib support)
ii gcc-12-base:amd64 12.1.0-2ubuntu1~22.04 amd64 GCC, the GNU Compiler Collection (base package) ii gcc-12-base:amd64 12.3.0-1ubuntu1~22.04 amd64 GCC, the GNU Compiler Collection (base package)
ii gcc-12-base:i386 12.1.0-2ubuntu1~22.04 i386 GCC, the GNU Compiler Collection (base package) ii gcc-12-base:i386 12.3.0-1ubuntu1~22.04 i386 GCC, the GNU Compiler Collection (base package)
ii gcc-multilib 4:11.2.0-1ubuntu1 amd64 GNU C compiler (multilib files) ii gcc-multilib 4:11.2.0-1ubuntu1 amd64 GNU C compiler (multilib files)
ii gdb 12.1-0ubuntu1~22.04 amd64 GNU Debugger ii gdb 12.1-0ubuntu1~22.04 amd64 GNU Debugger
ii git 1:2.34.1-1ubuntu1.9 amd64 fast, scalable, distributed revision control system ii git 1:2.34.1-1ubuntu1.10 amd64 fast, scalable, distributed revision control system
ii git-man 1:2.34.1-1ubuntu1.9 all fast, scalable, distributed revision control system (manual pages) ii git-man 1:2.34.1-1ubuntu1.10 all fast, scalable, distributed revision control system (manual pages)
ii gojq 0.12.6-1 amd64 pure Go implementation of jq (program) ii gojq 0.12.6-1 amd64 pure Go implementation of jq (program)
ii gpgv 2.2.27-3ubuntu2.1 amd64 GNU privacy guard - signature verification tool ii gpgv 2.2.27-3ubuntu2.1 amd64 GNU privacy guard - signature verification tool
ii grep 3.7-1build1 amd64 GNU grep, egrep and fgrep ii grep 3.7-1build1 amd64 GNU grep, egrep and fgrep
@@ -67,54 +67,54 @@ ii hyperfine 1.12.0-3ubuntu0.1 amd64
ii init-system-helpers 1.62 all helper tools for all init systems ii init-system-helpers 1.62 all helper tools for all init systems
ii jq 1.6-2.1ubuntu3 amd64 lightweight and flexible command-line JSON processor ii jq 1.6-2.1ubuntu3 amd64 lightweight and flexible command-line JSON processor
ii less 590-1ubuntu0.22.04.1 amd64 pager program similar to more ii less 590-1ubuntu0.22.04.1 amd64 pager program similar to more
ii lib32asan6 11.3.0-1ubuntu1~22.04.1 amd64 AddressSanitizer -- a fast memory error detector (32bit) ii lib32asan6 11.4.0-1ubuntu1~22.04 amd64 AddressSanitizer -- a fast memory error detector (32bit)
ii lib32atomic1 12.1.0-2ubuntu1~22.04 amd64 support library providing __atomic built-in functions (32bit) ii lib32atomic1 12.3.0-1ubuntu1~22.04 amd64 support library providing __atomic built-in functions (32bit)
ii lib32gcc-11-dev 11.3.0-1ubuntu1~22.04.1 amd64 GCC support library (32 bit development files) ii lib32gcc-11-dev 11.4.0-1ubuntu1~22.04 amd64 GCC support library (32 bit development files)
ii lib32gcc-s1 12.1.0-2ubuntu1~22.04 amd64 GCC support library (32 bit Version) ii lib32gcc-s1 12.3.0-1ubuntu1~22.04 amd64 GCC support library (32 bit Version)
ii lib32gomp1 12.1.0-2ubuntu1~22.04 amd64 GCC OpenMP (GOMP) support library (32bit) ii lib32gomp1 12.3.0-1ubuntu1~22.04 amd64 GCC OpenMP (GOMP) support library (32bit)
ii lib32itm1 12.1.0-2ubuntu1~22.04 amd64 GNU Transactional Memory Library (32bit) ii lib32itm1 12.3.0-1ubuntu1~22.04 amd64 GNU Transactional Memory Library (32bit)
ii lib32quadmath0 12.1.0-2ubuntu1~22.04 amd64 GCC Quad-Precision Math Library (32bit) ii lib32quadmath0 12.3.0-1ubuntu1~22.04 amd64 GCC Quad-Precision Math Library (32bit)
ii lib32stdc++-11-dev 11.3.0-1ubuntu1~22.04.1 amd64 GNU Standard C++ Library v3 (development files) ii lib32stdc++-11-dev 11.4.0-1ubuntu1~22.04 amd64 GNU Standard C++ Library v3 (development files)
ii lib32stdc++6 12.1.0-2ubuntu1~22.04 amd64 GNU Standard C++ Library v3 (32 bit Version) ii lib32stdc++6 12.3.0-1ubuntu1~22.04 amd64 GNU Standard C++ Library v3 (32 bit Version)
ii lib32ubsan1 12.1.0-2ubuntu1~22.04 amd64 UBSan -- undefined behaviour sanitizer (32bit) ii lib32ubsan1 12.3.0-1ubuntu1~22.04 amd64 UBSan -- undefined behaviour sanitizer (32bit)
ii libacl1:amd64 2.3.1-1 amd64 access control list - shared library ii libacl1:amd64 2.3.1-1 amd64 access control list - shared library
ii libapt-pkg6.0:amd64 2.4.9 amd64 package management runtime library ii libapt-pkg6.0:amd64 2.4.10 amd64 package management runtime library
ii libarchive13:amd64 3.6.0-1ubuntu1 amd64 Multi-format archive and compression library (shared library) ii libarchive13:amd64 3.6.0-1ubuntu1 amd64 Multi-format archive and compression library (shared library)
ii libaria2-0:amd64 1.36.0-1 amd64 C++ library interface to aria2 ii libaria2-0:amd64 1.36.0-1 amd64 C++ library interface to aria2
ii libasan6:amd64 11.3.0-1ubuntu1~22.04.1 amd64 AddressSanitizer -- a fast memory error detector ii libasan6:amd64 11.4.0-1ubuntu1~22.04 amd64 AddressSanitizer -- a fast memory error detector
ii libasm1:amd64 0.186-1build1 amd64 library with a programmable assembler interface ii libasm1:amd64 0.186-1build1 amd64 library with a programmable assembler interface
ii libatomic1:amd64 12.1.0-2ubuntu1~22.04 amd64 support library providing __atomic built-in functions ii libatomic1:amd64 12.3.0-1ubuntu1~22.04 amd64 support library providing __atomic built-in functions
ii libattr1:amd64 1:2.5.1-1build1 amd64 extended attribute handling - shared library ii libattr1:amd64 1:2.5.1-1build1 amd64 extended attribute handling - shared library
ii libaudit-common 1:3.0.7-1build1 all Dynamic library for security auditing - common files ii libaudit-common 1:3.0.7-1build1 all Dynamic library for security auditing - common files
ii libaudit1:amd64 1:3.0.7-1build1 amd64 Dynamic library for security auditing ii libaudit1:amd64 1:3.0.7-1build1 amd64 Dynamic library for security auditing
ii libbabeltrace1:amd64 1.5.8-2build1 amd64 Babeltrace conversion libraries ii libbabeltrace1:amd64 1.5.8-2build1 amd64 Babeltrace conversion libraries
ii libbinutils:amd64 2.38-4ubuntu2.2 amd64 GNU binary utilities (private shared library) ii libbinutils:amd64 2.38-4ubuntu2.3 amd64 GNU binary utilities (private shared library)
ii libblkid1:amd64 2.37.2-4ubuntu3 amd64 block device ID library ii libblkid1:amd64 2.37.2-4ubuntu3 amd64 block device ID library
ii libboost-regex1.74.0:amd64 1.74.0-14ubuntu3 amd64 regular expression library for C++ ii libboost-regex1.74.0:amd64 1.74.0-14ubuntu3 amd64 regular expression library for C++
ii libbrotli1:amd64 1.0.9-2build6 amd64 library implementing brotli encoder and decoder (shared libraries) ii libbrotli1:amd64 1.0.9-2build6 amd64 library implementing brotli encoder and decoder (shared libraries)
ii libbsd0:amd64 0.11.5-1 amd64 utility functions from BSD systems - shared library ii libbsd0:amd64 0.11.5-1 amd64 utility functions from BSD systems - shared library
ii libbz2-1.0:amd64 1.0.8-5build1 amd64 high-quality block-sorting file compressor library - runtime ii libbz2-1.0:amd64 1.0.8-5build1 amd64 high-quality block-sorting file compressor library - runtime
ii libc-ares2:amd64 1.18.1-1ubuntu0.22.04.2 amd64 asynchronous name resolver ii libc-ares2:amd64 1.18.1-1ubuntu0.22.04.2 amd64 asynchronous name resolver
ii libc-bin 2.35-0ubuntu3.1 amd64 GNU C Library: Binaries ii libc-bin 2.35-0ubuntu3.4 amd64 GNU C Library: Binaries
ii libc-dev-bin 2.35-0ubuntu3.1 amd64 GNU C Library: Development binaries ii libc-dev-bin 2.35-0ubuntu3.4 amd64 GNU C Library: Development binaries
ii libc6-dev-i386 2.35-0ubuntu3.1 amd64 GNU C Library: 32-bit development libraries for AMD64 ii libc6-dev-i386 2.35-0ubuntu3.4 amd64 GNU C Library: 32-bit development libraries for AMD64
ii libc6-dev-x32 2.35-0ubuntu3.1 amd64 GNU C Library: X32 ABI Development Libraries for AMD64 ii libc6-dev-x32 2.35-0ubuntu3.4 amd64 GNU C Library: X32 ABI Development Libraries for AMD64
ii libc6-dev:amd64 2.35-0ubuntu3.1 amd64 GNU C Library: Development Libraries and Header Files ii libc6-dev:amd64 2.35-0ubuntu3.4 amd64 GNU C Library: Development Libraries and Header Files
ii libc6-i386 2.35-0ubuntu3.1 amd64 GNU C Library: 32-bit shared libraries for AMD64 ii libc6-i386 2.35-0ubuntu3.4 amd64 GNU C Library: 32-bit shared libraries for AMD64
ii libc6-x32 2.35-0ubuntu3.1 amd64 GNU C Library: X32 ABI Shared libraries for AMD64 ii libc6-x32 2.35-0ubuntu3.4 amd64 GNU C Library: X32 ABI Shared libraries for AMD64
ii libc6:amd64 2.35-0ubuntu3.1 amd64 GNU C Library: Shared libraries ii libc6:amd64 2.35-0ubuntu3.4 amd64 GNU C Library: Shared libraries
ii libc6:i386 2.35-0ubuntu3.1 i386 GNU C Library: Shared libraries ii libc6:i386 2.35-0ubuntu3.4 i386 GNU C Library: Shared libraries
ii libcap-ng0:amd64 0.7.9-2.2build3 amd64 An alternate POSIX capabilities library ii libcap-ng0:amd64 0.7.9-2.2build3 amd64 An alternate POSIX capabilities library
ii libcap2:amd64 1:2.44-1ubuntu0.22.04.1 amd64 POSIX 1003.1e capabilities (library) ii libcap2:amd64 1:2.44-1ubuntu0.22.04.1 amd64 POSIX 1003.1e capabilities (library)
ii libcc1-0:amd64 12.1.0-2ubuntu1~22.04 amd64 GCC cc1 plugin for GDB ii libcc1-0:amd64 12.3.0-1ubuntu1~22.04 amd64 GCC cc1 plugin for GDB
ii libcom-err2:amd64 1.46.5-2ubuntu1.1 amd64 common error description library ii libcom-err2:amd64 1.46.5-2ubuntu1.1 amd64 common error description library
ii libcrypt-dev:amd64 1:4.4.27-1 amd64 libcrypt development files ii libcrypt-dev:amd64 1:4.4.27-1 amd64 libcrypt development files
ii libcrypt1:amd64 1:4.4.27-1 amd64 libcrypt shared library ii libcrypt1:amd64 1:4.4.27-1 amd64 libcrypt shared library
ii libcrypt1:i386 1:4.4.27-1 i386 libcrypt shared library ii libcrypt1:i386 1:4.4.27-1 i386 libcrypt shared library
ii libctf-nobfd0:amd64 2.38-4ubuntu2.2 amd64 Compact C Type Format library (runtime, no BFD dependency) ii libctf-nobfd0:amd64 2.38-4ubuntu2.3 amd64 Compact C Type Format library (runtime, no BFD dependency)
ii libctf0:amd64 2.38-4ubuntu2.2 amd64 Compact C Type Format library (runtime, BFD dependency) ii libctf0:amd64 2.38-4ubuntu2.3 amd64 Compact C Type Format library (runtime, BFD dependency)
ii libcurl3-gnutls:amd64 7.81.0-1ubuntu1.13 amd64 easy-to-use client-side URL transfer library (GnuTLS flavour) ii libcurl3-gnutls:amd64 7.81.0-1ubuntu1.14 amd64 easy-to-use client-side URL transfer library (GnuTLS flavour)
ii libcurl4:amd64 7.81.0-1ubuntu1.13 amd64 easy-to-use client-side URL transfer library (OpenSSL flavour) ii libcurl4:amd64 7.81.0-1ubuntu1.14 amd64 easy-to-use client-side URL transfer library (OpenSSL flavour)
ii libdb5.3:amd64 5.3.28+dfsg1-0.8ubuntu3 amd64 Berkeley v5.3 Database Libraries [runtime] ii libdb5.3:amd64 5.3.28+dfsg1-0.8ubuntu3 amd64 Berkeley v5.3 Database Libraries [runtime]
ii libdebconfclient0:amd64 0.261ubuntu1 amd64 Debian Configuration Management System (C-implementation library) ii libdebconfclient0:amd64 0.261ubuntu1 amd64 Debian Configuration Management System (C-implementation library)
ii libdebuginfod-common 0.186-1build1 all configuration to enable the Debian debug info server ii libdebuginfod-common 0.186-1build1 all configuration to enable the Debian debug info server
@@ -125,16 +125,16 @@ ii liberror-perl 0.17029-1 all
ii libexpat1:amd64 2.4.7-1ubuntu0.2 amd64 XML parsing C library - runtime library ii libexpat1:amd64 2.4.7-1ubuntu0.2 amd64 XML parsing C library - runtime library
ii libext2fs2:amd64 1.46.5-2ubuntu1.1 amd64 ext2/ext3/ext4 file system libraries ii libext2fs2:amd64 1.46.5-2ubuntu1.1 amd64 ext2/ext3/ext4 file system libraries
ii libffi8:amd64 3.4.2-4 amd64 Foreign Function Interface library runtime ii libffi8:amd64 3.4.2-4 amd64 Foreign Function Interface library runtime
ii libgcc-11-dev:amd64 11.3.0-1ubuntu1~22.04.1 amd64 GCC support library (development files) ii libgcc-11-dev:amd64 11.4.0-1ubuntu1~22.04 amd64 GCC support library (development files)
ii libgcc-s1:amd64 12.1.0-2ubuntu1~22.04 amd64 GCC support library ii libgcc-s1:amd64 12.3.0-1ubuntu1~22.04 amd64 GCC support library
ii libgcc-s1:i386 12.1.0-2ubuntu1~22.04 i386 GCC support library ii libgcc-s1:i386 12.3.0-1ubuntu1~22.04 i386 GCC support library
ii libgcrypt20:amd64 1.9.4-3ubuntu3 amd64 LGPL Crypto library - runtime library ii libgcrypt20:amd64 1.9.4-3ubuntu3 amd64 LGPL Crypto library - runtime library
ii libgdbm-compat4:amd64 1.23-1 amd64 GNU dbm database routines (legacy support runtime version) ii libgdbm-compat4:amd64 1.23-1 amd64 GNU dbm database routines (legacy support runtime version)
ii libgdbm6:amd64 1.23-1 amd64 GNU dbm database routines (runtime version) ii libgdbm6:amd64 1.23-1 amd64 GNU dbm database routines (runtime version)
ii libglib2.0-0:amd64 2.72.4-0ubuntu2.2 amd64 GLib library of C routines ii libglib2.0-0:amd64 2.72.4-0ubuntu2.2 amd64 GLib library of C routines
ii libgmp10:amd64 2:6.2.1+dfsg-3ubuntu1 amd64 Multiprecision arithmetic library ii libgmp10:amd64 2:6.2.1+dfsg-3ubuntu1 amd64 Multiprecision arithmetic library
ii libgnutls30:amd64 3.7.3-4ubuntu1.2 amd64 GNU TLS library - main runtime library ii libgnutls30:amd64 3.7.3-4ubuntu1.2 amd64 GNU TLS library - main runtime library
ii libgomp1:amd64 12.1.0-2ubuntu1~22.04 amd64 GCC OpenMP (GOMP) support library ii libgomp1:amd64 12.3.0-1ubuntu1~22.04 amd64 GCC OpenMP (GOMP) support library
ii libgpg-error0:amd64 1.43-3 amd64 GnuPG development runtime library ii libgpg-error0:amd64 1.43-3 amd64 GnuPG development runtime library
ii libgpm2:amd64 1.20.7-10build1 amd64 General Purpose Mouse - shared library ii libgpm2:amd64 1.20.7-10build1 amd64 General Purpose Mouse - shared library
ii libgssapi-krb5-2:amd64 1.19.2-2ubuntu0.2 amd64 MIT Kerberos runtime libraries - krb5 GSS-API Mechanism ii libgssapi-krb5-2:amd64 1.19.2-2ubuntu0.2 amd64 MIT Kerberos runtime libraries - krb5 GSS-API Mechanism
@@ -146,7 +146,7 @@ ii libio-pty-perl 1:1.15-2build2 amd64
ii libipc-run-perl 20200505.0-1 all Perl module for running processes ii libipc-run-perl 20200505.0-1 all Perl module for running processes
ii libipt2 2.0.5-1 amd64 Intel Processor Trace Decoder Library ii libipt2 2.0.5-1 amd64 Intel Processor Trace Decoder Library
ii libisl23:amd64 0.24-2build1 amd64 manipulating sets and relations of integer points bounded by linear constraints ii libisl23:amd64 0.24-2build1 amd64 manipulating sets and relations of integer points bounded by linear constraints
ii libitm1:amd64 12.1.0-2ubuntu1~22.04 amd64 GNU Transactional Memory Library ii libitm1:amd64 12.3.0-1ubuntu1~22.04 amd64 GNU Transactional Memory Library
ii libjansson4:amd64 2.13.1-1.1build3 amd64 C library for encoding, decoding and manipulating JSON data ii libjansson4:amd64 2.13.1-1.1build3 amd64 C library for encoding, decoding and manipulating JSON data
ii libjq1:amd64 1.6-2.1ubuntu3 amd64 lightweight and flexible command-line JSON processor - shared library ii libjq1:amd64 1.6-2.1ubuntu3 amd64 lightweight and flexible command-line JSON processor - shared library
ii libjsoncpp25:amd64 1.9.5-3 amd64 library for reading and writing JSON for C++ ii libjsoncpp25:amd64 1.9.5-3 amd64 library for reading and writing JSON for C++
@@ -154,13 +154,13 @@ ii libk5crypto3:amd64 1.19.2-2ubuntu0.2 amd64
ii libkeyutils1:amd64 1.6.1-2ubuntu3 amd64 Linux Key Management Utilities (library) ii libkeyutils1:amd64 1.6.1-2ubuntu3 amd64 Linux Key Management Utilities (library)
ii libkrb5-3:amd64 1.19.2-2ubuntu0.2 amd64 MIT Kerberos runtime libraries ii libkrb5-3:amd64 1.19.2-2ubuntu0.2 amd64 MIT Kerberos runtime libraries
ii libkrb5support0:amd64 1.19.2-2ubuntu0.2 amd64 MIT Kerberos runtime libraries - Support library ii libkrb5support0:amd64 1.19.2-2ubuntu0.2 amd64 MIT Kerberos runtime libraries - Support library
ii libldap-2.5-0:amd64 2.5.14+dfsg-0ubuntu0.22.04.2 amd64 OpenLDAP libraries ii libldap-2.5-0:amd64 2.5.16+dfsg-0ubuntu0.22.04.1 amd64 OpenLDAP libraries
ii liblsan0:amd64 12.1.0-2ubuntu1~22.04 amd64 LeakSanitizer -- a memory leak detector (runtime) ii liblsan0:amd64 12.3.0-1ubuntu1~22.04 amd64 LeakSanitizer -- a memory leak detector (runtime)
ii liblz4-1:amd64 1.9.3-2build2 amd64 Fast LZ compression algorithm library - runtime ii liblz4-1:amd64 1.9.3-2build2 amd64 Fast LZ compression algorithm library - runtime
ii liblzma5:amd64 5.2.5-2ubuntu1 amd64 XZ-format compression library ii liblzma5:amd64 5.2.5-2ubuntu1 amd64 XZ-format compression library
ii liblzo2-2:amd64 2.10-2build3 amd64 data compression library ii liblzo2-2:amd64 2.10-2build3 amd64 data compression library
ii libmagic-mgc 1:5.41-3 amd64 File type determination library using "magic" numbers (compiled magic file) ii libmagic-mgc 1:5.41-3ubuntu0.1 amd64 File type determination library using "magic" numbers (compiled magic file)
ii libmagic1:amd64 1:5.41-3 amd64 Recognize the type of data in a file using "magic" numbers - library ii libmagic1:amd64 1:5.41-3ubuntu0.1 amd64 Recognize the type of data in a file using "magic" numbers - library
ii libmd0:amd64 1.0.4-1build1 amd64 message digest functions from BSD systems - shared library ii libmd0:amd64 1.0.4-1build1 amd64 message digest functions from BSD systems - shared library
ii libmount1:amd64 2.37.2-4ubuntu3 amd64 device mounting library ii libmount1:amd64 2.37.2-4ubuntu3 amd64 device mounting library
ii libmpc3:amd64 1.2.1-2build1 amd64 multiple precision complex floating-point library ii libmpc3:amd64 1.2.1-2build1 amd64 multiple precision complex floating-point library
@@ -190,10 +190,10 @@ ii libprocps8:amd64 2:3.3.17-6ubuntu2 amd64
ii libpsl5:amd64 0.21.0-1.2build2 amd64 Library for Public Suffix List (shared libraries) ii libpsl5:amd64 0.21.0-1.2build2 amd64 Library for Public Suffix List (shared libraries)
ii libpython2.7-minimal:amd64 2.7.18-13ubuntu1.1 amd64 Minimal subset of the Python language (version 2.7) ii libpython2.7-minimal:amd64 2.7.18-13ubuntu1.1 amd64 Minimal subset of the Python language (version 2.7)
ii libpython3-stdlib:amd64 3.10.6-1~22.04 amd64 interactive high-level object-oriented language (default python3 version) ii libpython3-stdlib:amd64 3.10.6-1~22.04 amd64 interactive high-level object-oriented language (default python3 version)
ii libpython3.10-minimal:amd64 3.10.6-1~22.04.2ubuntu1.1 amd64 Minimal subset of the Python language (version 3.10) ii libpython3.10-minimal:amd64 3.10.12-1~22.04.2 amd64 Minimal subset of the Python language (version 3.10)
ii libpython3.10-stdlib:amd64 3.10.6-1~22.04.2ubuntu1.1 amd64 Interactive high-level object-oriented language (standard library, version 3.10) ii libpython3.10-stdlib:amd64 3.10.12-1~22.04.2 amd64 Interactive high-level object-oriented language (standard library, version 3.10)
ii libpython3.10:amd64 3.10.6-1~22.04.2ubuntu1.1 amd64 Shared Python runtime library (version 3.10) ii libpython3.10:amd64 3.10.12-1~22.04.2 amd64 Shared Python runtime library (version 3.10)
ii libquadmath0:amd64 12.1.0-2ubuntu1~22.04 amd64 GCC Quad-Precision Math Library ii libquadmath0:amd64 12.3.0-1ubuntu1~22.04 amd64 GCC Quad-Precision Math Library
ii libreadline8:amd64 8.1.2-1 amd64 GNU readline and history libraries, run-time libraries ii libreadline8:amd64 8.1.2-1 amd64 GNU readline and history libraries, run-time libraries
ii librhash0:amd64 1.4.2-1ubuntu1 amd64 shared library for hash functions computing ii librhash0:amd64 1.4.2-1ubuntu1 amd64 shared library for hash functions computing
ii librtmp1:amd64 2.4+20151223.gitfa8646d.1-2build4 amd64 toolkit for RTMP streams (shared library) ii librtmp1:amd64 2.4+20151223.gitfa8646d.1-2build4 amd64 toolkit for RTMP streams (shared library)
@@ -215,10 +215,10 @@ ii libsqlite3-0:amd64 3.37.2-2ubuntu0.1 amd64
ii libss2:amd64 1.46.5-2ubuntu1.1 amd64 command-line interface parsing library ii libss2:amd64 1.46.5-2ubuntu1.1 amd64 command-line interface parsing library
ii libssh-4:amd64 0.9.6-2ubuntu0.22.04.1 amd64 tiny C SSH library (OpenSSL flavor) ii libssh-4:amd64 0.9.6-2ubuntu0.22.04.1 amd64 tiny C SSH library (OpenSSL flavor)
ii libssh2-1:amd64 1.10.0-3 amd64 SSH2 client-side library ii libssh2-1:amd64 1.10.0-3 amd64 SSH2 client-side library
ii libssl3:amd64 3.0.2-0ubuntu1.10 amd64 Secure Sockets Layer toolkit - shared libraries ii libssl3:amd64 3.0.2-0ubuntu1.12 amd64 Secure Sockets Layer toolkit - shared libraries
ii libstdc++-11-dev:amd64 11.3.0-1ubuntu1~22.04.1 amd64 GNU Standard C++ Library v3 (development files) ii libstdc++-11-dev:amd64 11.4.0-1ubuntu1~22.04 amd64 GNU Standard C++ Library v3 (development files)
ii libstdc++6:amd64 12.1.0-2ubuntu1~22.04 amd64 GNU Standard C++ Library v3 ii libstdc++6:amd64 12.3.0-1ubuntu1~22.04 amd64 GNU Standard C++ Library v3
ii libsystemd0:amd64 249.11-0ubuntu3.9 amd64 systemd utility library ii libsystemd0:amd64 249.11-0ubuntu3.11 amd64 systemd utility library
ii libtasn1-6:amd64 4.18.0-4build1 amd64 Manage ASN.1 structures (runtime) ii libtasn1-6:amd64 4.18.0-4build1 amd64 Manage ASN.1 structures (runtime)
ii libtime-duration-perl 1.21-1 all module for rounded or exact English expression of durations ii libtime-duration-perl 1.21-1 all module for rounded or exact English expression of durations
ii libtimedate-perl 2.3300-2 all collection of modules to manipulate date/time information ii libtimedate-perl 2.3300-2 all collection of modules to manipulate date/time information
@@ -227,25 +227,25 @@ ii libtinfo6:amd64 6.3-2ubuntu0.1 amd64
ii libtirpc-common 1.3.2-2ubuntu0.1 all transport-independent RPC library - common files ii libtirpc-common 1.3.2-2ubuntu0.1 all transport-independent RPC library - common files
ii libtirpc-dev:amd64 1.3.2-2ubuntu0.1 amd64 transport-independent RPC library - development files ii libtirpc-dev:amd64 1.3.2-2ubuntu0.1 amd64 transport-independent RPC library - development files
ii libtirpc3:amd64 1.3.2-2ubuntu0.1 amd64 transport-independent RPC library ii libtirpc3:amd64 1.3.2-2ubuntu0.1 amd64 transport-independent RPC library
ii libtsan0:amd64 11.3.0-1ubuntu1~22.04.1 amd64 ThreadSanitizer -- a Valgrind-based detector of data races (runtime) ii libtsan0:amd64 11.4.0-1ubuntu1~22.04 amd64 ThreadSanitizer -- a Valgrind-based detector of data races (runtime)
ii libubsan1:amd64 12.1.0-2ubuntu1~22.04 amd64 UBSan -- undefined behaviour sanitizer (runtime) ii libubsan1:amd64 12.3.0-1ubuntu1~22.04 amd64 UBSan -- undefined behaviour sanitizer (runtime)
ii libudev1:amd64 249.11-0ubuntu3.9 amd64 libudev shared library ii libudev1:amd64 249.11-0ubuntu3.11 amd64 libudev shared library
ii libunistring2:amd64 1.0-1 amd64 Unicode string library for C ii libunistring2:amd64 1.0-1 amd64 Unicode string library for C
ii libutempter0:amd64 1.2.1-2build2 amd64 privileged helper for utmp/wtmp updates (runtime) ii libutempter0:amd64 1.2.1-2build2 amd64 privileged helper for utmp/wtmp updates (runtime)
ii libuuid1:amd64 2.37.2-4ubuntu3 amd64 Universally Unique ID library ii libuuid1:amd64 2.37.2-4ubuntu3 amd64 Universally Unique ID library
ii libuv1:amd64 1.43.0-1 amd64 asynchronous event notification library - runtime library ii libuv1:amd64 1.43.0-1 amd64 asynchronous event notification library - runtime library
ii libx11-6:amd64 2:1.7.5-1ubuntu0.2 amd64 X11 client-side library ii libx11-6:amd64 2:1.7.5-1ubuntu0.3 amd64 X11 client-side library
ii libx11-data 2:1.7.5-1ubuntu0.2 all X11 client-side library ii libx11-data 2:1.7.5-1ubuntu0.3 all X11 client-side library
ii libx32asan6 11.3.0-1ubuntu1~22.04.1 amd64 AddressSanitizer -- a fast memory error detector (x32) ii libx32asan6 11.4.0-1ubuntu1~22.04 amd64 AddressSanitizer -- a fast memory error detector (x32)
ii libx32atomic1 12.1.0-2ubuntu1~22.04 amd64 support library providing __atomic built-in functions (x32) ii libx32atomic1 12.3.0-1ubuntu1~22.04 amd64 support library providing __atomic built-in functions (x32)
ii libx32gcc-11-dev 11.3.0-1ubuntu1~22.04.1 amd64 GCC support library (x32 development files) ii libx32gcc-11-dev 11.4.0-1ubuntu1~22.04 amd64 GCC support library (x32 development files)
ii libx32gcc-s1 12.1.0-2ubuntu1~22.04 amd64 GCC support library (x32) ii libx32gcc-s1 12.3.0-1ubuntu1~22.04 amd64 GCC support library (x32)
ii libx32gomp1 12.1.0-2ubuntu1~22.04 amd64 GCC OpenMP (GOMP) support library (x32) ii libx32gomp1 12.3.0-1ubuntu1~22.04 amd64 GCC OpenMP (GOMP) support library (x32)
ii libx32itm1 12.1.0-2ubuntu1~22.04 amd64 GNU Transactional Memory Library (x32) ii libx32itm1 12.3.0-1ubuntu1~22.04 amd64 GNU Transactional Memory Library (x32)
ii libx32quadmath0 12.1.0-2ubuntu1~22.04 amd64 GCC Quad-Precision Math Library (x32) ii libx32quadmath0 12.3.0-1ubuntu1~22.04 amd64 GCC Quad-Precision Math Library (x32)
ii libx32stdc++-11-dev 11.3.0-1ubuntu1~22.04.1 amd64 GNU Standard C++ Library v3 (development files) ii libx32stdc++-11-dev 11.4.0-1ubuntu1~22.04 amd64 GNU Standard C++ Library v3 (development files)
ii libx32stdc++6 12.1.0-2ubuntu1~22.04 amd64 GNU Standard C++ Library v3 (x32) ii libx32stdc++6 12.3.0-1ubuntu1~22.04 amd64 GNU Standard C++ Library v3 (x32)
ii libx32ubsan1 12.1.0-2ubuntu1~22.04 amd64 UBSan -- undefined behaviour sanitizer (x32) ii libx32ubsan1 12.3.0-1ubuntu1~22.04 amd64 UBSan -- undefined behaviour sanitizer (x32)
ii libxau6:amd64 1:1.0.9-1build5 amd64 X11 authorisation library ii libxau6:amd64 1:1.0.9-1build5 amd64 X11 authorisation library
ii libxcb1:amd64 1.14-3ubuntu3 amd64 X C Binding ii libxcb1:amd64 1.14-3ubuntu3 amd64 X C Binding
ii libxdmcp6:amd64 1:1.1.3-0ubuntu5 amd64 X11 Display Manager Control Protocol library ii libxdmcp6:amd64 1:1.1.3-0ubuntu5 amd64 X11 Display Manager Control Protocol library
@@ -254,7 +254,7 @@ ii libxxhash0:amd64 0.8.1-1 amd64
ii libyaml-0-2:amd64 0.2.2-1build2 amd64 Fast YAML 1.1 parser and emitter library ii libyaml-0-2:amd64 0.2.2-1build2 amd64 Fast YAML 1.1 parser and emitter library
ii libzstd-dev:amd64 1.4.8+dfsg-3build1 amd64 fast lossless compression algorithm -- development files ii libzstd-dev:amd64 1.4.8+dfsg-3build1 amd64 fast lossless compression algorithm -- development files
ii libzstd1:amd64 1.4.8+dfsg-3build1 amd64 fast lossless compression algorithm ii libzstd1:amd64 1.4.8+dfsg-3build1 amd64 fast lossless compression algorithm
ii linux-libc-dev:amd64 5.15.0-76.83 amd64 Linux Kernel Headers for development ii linux-libc-dev:amd64 5.15.0-88.98 amd64 Linux Kernel Headers for development
ii login 1:4.8.1-2ubuntu2.1 amd64 system login tools ii login 1:4.8.1-2ubuntu2.1 amd64 system login tools
ii logsave 1.46.5-2ubuntu1.1 amd64 save the output of a command in a log file ii logsave 1.46.5-2ubuntu1.1 amd64 save the output of a command in a log file
ii lsb-base 11.1.0ubuntu4 all Linux Standard Base init script functionality ii lsb-base 11.1.0ubuntu4 all Linux Standard Base init script functionality
@@ -272,7 +272,7 @@ ii ncurses-base 6.3-2ubuntu0.1 all
ii ncurses-bin 6.3-2ubuntu0.1 amd64 terminal-related programs and man pages ii ncurses-bin 6.3-2ubuntu0.1 amd64 terminal-related programs and man pages
ii ncurses-term 6.3-2ubuntu0.1 all additional terminal type definitions ii ncurses-term 6.3-2ubuntu0.1 all additional terminal type definitions
ii ninja-build 1.10.1-1 amd64 small build system closest in spirit to Make ii ninja-build 1.10.1-1 amd64 small build system closest in spirit to Make
ii openssl 3.0.2-0ubuntu1.10 amd64 Secure Sockets Layer toolkit - cryptographic utility ii openssl 3.0.2-0ubuntu1.12 amd64 Secure Sockets Layer toolkit - cryptographic utility
ii p7zip 16.02+dfsg-8 amd64 7zr file archiver with high compression ratio ii p7zip 16.02+dfsg-8 amd64 7zr file archiver with high compression ratio
ii parallel 20210822+ds-2 all build and execute command lines from standard input in parallel ii parallel 20210822+ds-2 all build and execute command lines from standard input in parallel
ii passwd 1:4.8.1-2ubuntu2.1 amd64 change and administer password and group data ii passwd 1:4.8.1-2ubuntu2.1 amd64 change and administer password and group data
@@ -288,8 +288,11 @@ ii python2-minimal 2.7.18-3 amd64
ii python2.7-minimal 2.7.18-13ubuntu1.1 amd64 Minimal subset of the Python language (version 2.7) ii python2.7-minimal 2.7.18-13ubuntu1.1 amd64 Minimal subset of the Python language (version 2.7)
ii python3 3.10.6-1~22.04 amd64 interactive high-level object-oriented language (default python3 version) ii python3 3.10.6-1~22.04 amd64 interactive high-level object-oriented language (default python3 version)
ii python3-minimal 3.10.6-1~22.04 amd64 minimal subset of the Python language (default python3 version) ii python3-minimal 3.10.6-1~22.04 amd64 minimal subset of the Python language (default python3 version)
ii python3.10 3.10.6-1~22.04.2ubuntu1.1 amd64 Interactive high-level object-oriented language (version 3.10) ii python3-pyasn1 0.4.8-1 all ASN.1 library for Python (Python 3 module)
ii python3.10-minimal 3.10.6-1~22.04.2ubuntu1.1 amd64 Minimal subset of the Python language (version 3.10) ii python3-pycryptodome 3.11.0+dfsg1-3build1 amd64 cryptographic Python library (Python 3)
ii python3-zstd 1.5.0.2-1build1 amd64 python bindings to Yann Collet ZSTD compression library
ii python3.10 3.10.12-1~22.04.2 amd64 Interactive high-level object-oriented language (version 3.10)
ii python3.10-minimal 3.10.12-1~22.04.2 amd64 Minimal subset of the Python language (version 3.10)
ii re2c 3.0-1 amd64 lexer generator for C, C++, Go and Rust ii re2c 3.0-1 amd64 lexer generator for C, C++, Go and Rust
ii readline-common 8.1.2-1 all GNU readline and history libraries, common files ii readline-common 8.1.2-1 all GNU readline and history libraries, common files
ii ripgrep 13.0.0-2ubuntu0.1 amd64 Recursively searches directories for a regex pattern ii ripgrep 13.0.0-2ubuntu0.1 amd64 Recursively searches directories for a regex pattern
@@ -308,11 +311,11 @@ ii universal-ctags 5.9.20210829.0-1 amd64
ii unzip 6.0-26ubuntu3.1 amd64 De-archiver for .zip files ii unzip 6.0-26ubuntu3.1 amd64 De-archiver for .zip files
ii usrmerge 25ubuntu2 all Convert the system to the merged /usr directories scheme ii usrmerge 25ubuntu2 all Convert the system to the merged /usr directories scheme
ii util-linux 2.37.2-4ubuntu3 amd64 miscellaneous system utilities ii util-linux 2.37.2-4ubuntu3 amd64 miscellaneous system utilities
ii vim 2:8.2.3995-1ubuntu2.9 amd64 Vi IMproved - enhanced vi editor ii vim 2:8.2.3995-1ubuntu2.13 amd64 Vi IMproved - enhanced vi editor
ii vim-common 2:8.2.3995-1ubuntu2.9 all Vi IMproved - Common files ii vim-common 2:8.2.3995-1ubuntu2.13 all Vi IMproved - Common files
ii vim-runtime 2:8.2.3995-1ubuntu2.9 all Vi IMproved - Runtime files ii vim-runtime 2:8.2.3995-1ubuntu2.13 all Vi IMproved - Runtime files
ii wget 1.21.2-2ubuntu1 amd64 retrieves files from the web ii wget 1.21.2-2ubuntu1 amd64 retrieves files from the web
ii xxd 2:8.2.3995-1ubuntu2.9 amd64 tool to make (or reverse) a hex dump ii xxd 2:8.2.3995-1ubuntu2.13 amd64 tool to make (or reverse) a hex dump
ii xz-utils 5.2.5-2ubuntu1 amd64 XZ-format compression utilities ii xz-utils 5.2.5-2ubuntu1 amd64 XZ-format compression utilities
ii yash 2.51-1 amd64 yet another shell ii yash 2.51-1 amd64 yet another shell
ii zip 3.0-12build2 amd64 Archiver for .zip files ii zip 3.0-12build2 amd64 Archiver for .zip files
@@ -327,53 +330,54 @@ ii zstd 1.4.8+dfsg-3build1 amd64
||/ Name Version Architecture Description ||/ Name Version Architecture Description
Packages sorted by Installed-Size: Packages sorted by Installed-Size:
748809 ===== TOTAL (321 packages) 754091 ===== TOTAL (324 packages)
52577 gcc-11 amd64 52747 gcc-11 amd64
34444 libicu70 amd64 34444 libicu70 amd64
32780 vim-runtime all 32782 vim-runtime all
28795 g++-11 amd64 28891 g++-11 amd64
28441 libperl5.34 amd64 28441 libperl5.34 amd64
26212 cpp-11 amd64 26284 cpp-11 amd64
20742 cmake amd64 20742 cmake amd64
18721 libstdc++-11-dev amd64 18759 libstdc++-11-dev amd64
18468 git amd64 18468 git amd64
17671 perl-modules-5.34 all 17671 perl-modules-5.34 all
15293 zsh-common all 15293 zsh-common all
13894 libgcc-11-dev amd64 13895 libgcc-11-dev amd64
13592 libc6 amd64 13592 libc6 amd64
13037 libc6-dev amd64 13037 libc6-dev amd64
12561 libc6-x32 amd64 12561 libc6-x32 amd64
12479 libc6 i386 12479 libc6 i386
12200 libc6-i386 amd64 12200 libc6-i386 amd64
11311 gdb amd64 11311 gdb amd64
10876 lib32stdc++-11-dev amd64 10877 lib32stdc++-11-dev amd64
10439 binutils-x86-64-linux-gnu amd64 10439 binutils-x86-64-linux-gnu amd64
10391 libx32stdc++-11-dev amd64 10390 libx32stdc++-11-dev amd64
9866 cmake-data all 9866 cmake-data all
8248 libc6-dev-x32 amd64 8248 libc6-dev-x32 amd64
8040 libpython3.10-stdlib amd64 8119 libpython3.10-stdlib amd64
7947 lib32gcc-11-dev amd64 7948 lib32gcc-11-dev amd64
7730 perl-base amd64 7730 perl-base amd64
7518 libasan6 amd64 7518 libasan6 amd64
7261 libc6-dev-i386 amd64 7262 libc6-dev-i386 amd64
7255 libtsan0 amd64 7255 libtsan0 amd64
7127 libmagic-mgc amd64 7128 libmagic-mgc amd64
7112 coreutils amd64 7112 coreutils amd64
6988 libx32gcc-11-dev amd64 6988 libx32gcc-11-dev amd64
6734 linux-libc-dev amd64 6802 linux-libc-dev amd64
6733 dpkg amd64 6733 dpkg amd64
6659 lib32asan6 amd64 6667 lib32asan6 amd64
6570 libx32asan6 amd64 6570 libx32asan6 amd64
5902 python3.10-minimal amd64 5905 python3.10-minimal amd64
5824 libssl3 amd64 5828 libssl3 amd64
5780 libpython3.10 amd64 5768 libpython3.10 amd64
5093 libpython3.10-minimal amd64 5103 libpython3.10-minimal amd64
4249 ncurses-term all 4249 ncurses-term all
4156 apt amd64 4156 apt amd64
4147 ripgrep amd64 4147 ripgrep amd64
4082 libglib2.0-0 amd64 4082 libglib2.0-0 amd64
3923 vim amd64 3930 vim amd64
3643 python2.7-minimal amd64 3643 python2.7-minimal amd64
3542 python3-pycryptodome amd64
3506 re2c amd64 3506 re2c amd64
3487 gojq amd64 3487 gojq amd64
3405 libmpfr6 amd64 3405 libmpfr6 amd64
@@ -386,15 +390,15 @@ Packages sorted by Installed-Size:
2801 elfutils amd64 2801 elfutils amd64
2784 libpython2.7-minimal amd64 2784 libpython2.7-minimal amd64
2776 libbinutils amd64 2776 libbinutils amd64
2746 libstdc++6 amd64 2755 libstdc++6 amd64
2675 libubsan1 amd64 2676 libubsan1 amd64
2662 lib32stdc++6 amd64 2662 lib32stdc++6 amd64
2537 libc-bin amd64 2537 libc-bin amd64
2518 libx32ubsan1 amd64 2518 libx32ubsan1 amd64
2510 fd-find amd64 2510 fd-find amd64
2500 lib32ubsan1 amd64 2499 lib32ubsan1 amd64
2468 zsh amd64 2468 zsh amd64
2438 libx32stdc++6 amd64 2450 libx32stdc++6 amd64
2428 fzf amd64 2428 fzf amd64
2396 7zip amd64 2396 7zip amd64
2325 passwd amd64 2325 passwd amd64
@@ -404,7 +408,7 @@ Packages sorted by Installed-Size:
2097 libxml2 amd64 2097 libxml2 amd64
2053 openssl amd64 2053 openssl amd64
2009 universal-ctags amd64 2009 universal-ctags amd64
1959 git-man all 1958 git-man all
1864 bash amd64 1864 bash amd64
1854 aria2 amd64 1854 aria2 amd64
1750 libdb5.3 amd64 1750 libdb5.3 amd64
@@ -417,10 +421,10 @@ Packages sorted by Installed-Size:
1472 sysstat amd64 1472 sysstat amd64
1464 bash-completion all 1464 bash-completion all
1445 hyperfine amd64 1445 hyperfine amd64
1430 libx11-data all
1429 yash amd64 1429 yash amd64
1429 libx11-data all
1388 procps amd64 1388 procps amd64
1386 libx11-6 amd64 1387 libx11-6 amd64
1354 libgcrypt20 amd64 1354 libgcrypt20 amd64
1343 ccache amd64 1343 ccache amd64
1328 libzstd-dev amd64 1328 libzstd-dev amd64
@@ -440,6 +444,7 @@ Packages sorted by Installed-Size:
787 libcurl4 amd64 787 libcurl4 amd64
784 libbrotli1 amd64 784 libbrotli1 amd64
771 libcurl3-gnutls amd64 771 libcurl3-gnutls amd64
743 python3-zstd amd64
735 libsepol2 amd64 735 libsepol2 amd64
729 libdw1 amd64 729 libdw1 amd64
720 libtirpc-dev amd64 720 libtirpc-dev amd64
@@ -447,8 +452,8 @@ Packages sorted by Installed-Size:
686 lib32quadmath0 amd64 686 lib32quadmath0 amd64
683 libpcre3 amd64 683 libpcre3 amd64
646 ncurses-bin amd64 646 ncurses-bin amd64
632 python3.10 amd64
621 libpcre2-8-0 amd64 621 libpcre2-8-0 amd64
620 python3.10 amd64
620 findutils amd64 620 findutils amd64
615 libonig5 amd64 615 libonig5 amd64
610 libsource-highlight4v5 amd64 610 libsource-highlight4v5 amd64
@@ -475,10 +480,11 @@ Packages sorted by Installed-Size:
402 libsodium23 amd64 402 libsodium23 amd64
394 base-files amd64 394 base-files amd64
393 ncurses-base all 393 ncurses-base all
390 python3-pyasn1 all
390 ca-certificates all 390 ca-certificates all
389 mount amd64 389 mount amd64
382 libmount1 amd64 382 libmount1 amd64
379 vim-common all 381 vim-common all
376 unzip amd64 376 unzip amd64
372 xz-utils amd64 372 xz-utils amd64
368 libssh2-1 amd64 368 libssh2-1 amd64
@@ -507,14 +513,14 @@ Packages sorted by Installed-Size:
300 libsemanage2 amd64 300 libsemanage2 amd64
298 libc-dev-bin amd64 298 libc-dev-bin amd64
296 libquadmath0 amd64 296 libquadmath0 amd64
295 libx32quadmath0 amd64
292 libk5crypto3 amd64 292 libk5crypto3 amd64
291 libx32quadmath0 amd64
290 pax-utils amd64 290 pax-utils amd64
290 liblzma5 amd64 290 liblzma5 amd64
277 xxd amd64 279 xxd amd64
271 gcc-11-base amd64 273 gcc-11-base amd64
266 gcc-12-base i386 272 gcc-12-base i386
266 gcc-12-base amd64 272 gcc-12-base amd64
252 libuv1 amd64 252 libuv1 amd64
252 libipc-run-perl all 252 libipc-run-perl all
252 libcrypt1 i386 252 libcrypt1 i386
@@ -532,7 +538,7 @@ Packages sorted by Installed-Size:
230 lz4 amd64 230 lz4 amd64
229 patch amd64 229 patch amd64
229 mawk amd64 229 mawk amd64
228 libmagic1 amd64 229 libmagic1 amd64
225 libcrypt1 amd64 225 libcrypt1 amd64
221 bfs amd64 221 bfs amd64
220 libidn2-0 amd64 220 libidn2-0 amd64
@@ -600,8 +606,8 @@ Packages sorted by Installed-Size:
92 libhiredis0.14 amd64 92 libhiredis0.14 amd64
91 libjansson4 amd64 91 libjansson4 amd64
90 python3 amd64 90 python3 amd64
84 file amd64
83 sysvinit-utils amd64 83 sysvinit-utils amd64
83 file amd64
82 cabextract amd64 82 cabextract amd64
80 readline-common all 80 readline-common all
79 libdebconfclient0 amd64 79 libdebconfclient0 amd64
+9 -2
View File
@@ -8,7 +8,7 @@ set -e
# Copyright (C) Markus Franz Xaver Johannes Oberhumer # Copyright (C) Markus Franz Xaver Johannes Oberhumer
# #
# uses optional environment variables: AR, CC, CXX, OPTIMIZE, top_srcdir # uses optional environment variables: AR, CC, CXX, OPTIMIZE, VERBOSE, top_srcdir
# shell init # shell init
### set -x # enable logging ### set -x # enable logging
@@ -26,6 +26,8 @@ if test "x$AR" = "x0" || test "x$AR" = "xfalse" || test "x$AR" = "x/bin/false";
fi fi
# protect against security threats caused by misguided compiler "optimizations" # protect against security threats caused by misguided compiler "optimizations"
mandatory_flags="-fno-strict-aliasing -fno-strict-overflow -funsigned-char" 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 if test "x$OPTIMIZE" != "x" && test "x$OPTIMIZE" != "x0"; then
# not mandatory and not minimal, but usually a good idea: # not mandatory and not minimal, but usually a good idea:
mandatory_flags="-Wall -O2 $mandatory_flags" mandatory_flags="-Wall -O2 $mandatory_flags"
@@ -62,7 +64,12 @@ run() {
fi fi
# print short info and run command # print short info and run command
test "x$1" != "x" && test "x$1" != "x+" && echo "$1" test "x$1" != "x" && test "x$1" != "x+" && echo "$1"
shift; "$@" shift
if test "x$VERBOSE" != "x" && test "x$VERBOSE" != "x0"; then
# print full command
echo " $@"
fi
"$@"
} }
# helper function # helper function
+5 -4
View File
@@ -31,9 +31,10 @@ LC_ALL=C sort -z | xargs -0r perl -n -e '
} }
} }
if (m,\t,) { if (m,\t,) {
if ($ARGV =~ m,(^|/)(gnu|m)?make(file|vars),i) { } if ($ARGV =~ m,(^|/)(gnu|m)?make(file|vars),i) { }
elsif ($ARGV =~ m,/tmp/.*\.(disasm|dump)$,) { } elsif ($ARGV =~ m,\.mk$,) { }
elsif ($ARGV =~ m,/src/stub/src/arch/.*/lzma\w+\.S$,) { } elsif ($ARGV =~ m,/tmp/.*\.(disasm|dump)$,) { }
else { print "ERROR: hard TAB detected $ARGV: $_"; exit(1); } elsif ($ARGV =~ m,/src/stub/src/arch/.*/lzma\w+\.S$,) { }
else { print "ERROR: hard TAB detected $ARGV: $_"; exit(1); }
} }
' || exit 1 ' || exit 1
+5 -4
View File
@@ -25,9 +25,10 @@ git ls-files --full-name -z | perl -0 -n -e '
} }
} }
if (m,\t,) { if (m,\t,) {
if ($ARGV =~ m,(^|/)(gnu|m)?make(file|vars),i) { } if ($ARGV =~ m,(^|/)(gnu|m)?make(file|vars),i) { }
elsif ($ARGV =~ m,/tmp/.*\.(disasm|dump)$,) { } elsif ($ARGV =~ m,\.mk$,) { }
elsif ($ARGV =~ m,/src/stub/src/arch/.*/lzma\w+\.S$,) { } elsif ($ARGV =~ m,/tmp/.*\.(disasm|dump)$,) { }
else { print "ERROR: hard TAB detected $ARGV: $_"; exit(1); } elsif ($ARGV =~ m,/src/stub/src/arch/.*/lzma\w+\.S$,) { }
else { print "ERROR: hard TAB detected $ARGV: $_"; exit(1); }
} }
' || exit 1 ' || exit 1
+394
View File
@@ -0,0 +1,394 @@
#! /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")
# disable on macOS for now, see https://github.com/upx/upx/issues/612
if [[ "$(uname)" == Darwin ]]; then
echo "$0: SKIPPED"
exit 0
fi
# IMPORTANT NOTE: do NOT run as user root!!
# IMPORTANT NOTE: this script only works on Unix!!
umask 0022
id || true
echo "PWD='$PWD'"
if [[ $UID == 0 || $EUID == 0 ]]; then
echo "ERROR: do not run as root: UID=$UID EUID=$EUID"
exit 91
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
#***********************************************************************
# 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
upx_run=()
if [[ -n $upx_exe_runner ]]; then
# usage examples:
# export upx_exe_runner="qemu-x86_64 -cpu Westmere"
# export upx_exe_runner="valgrind --leak-check=no --error-exitcode=1 --quiet"
# export upx_exe_runner="wine"
IFS=' ' read -r -a upx_run <<< "$upx_exe_runner" # split at spaces into array
fi
upx_run+=( "$upx_exe" )
echo "upx_run='${upx_run[*]}'"
# upx_run check
if ! "${upx_run[@]}" --version-short >/dev/null; then echo "UPX-ERROR: FATAL: upx --version-short FAILED"; exit 1; fi
if ! "${upx_run[@]}" -L >/dev/null 2>&1; then echo "UPX-ERROR: FATAL: upx -L FAILED"; exit 1; fi
if ! "${upx_run[@]}" --help >/dev/null; then echo "UPX-ERROR: FATAL: upx --help FAILED"; exit 1; fi
#***********************************************************************
# util
#***********************************************************************
exit_code=0
num_errors=0
all_errors=
failed() {
####exit $1
# log error and keep going
exit_code=1
local a="$(basename "$(dirname "$PWD")")"
local b="$(basename "$PWD")"
let num_errors+=1 || true
all_errors="${all_errors} $a/$b/$1"
echo " FAILED $b/$1"
}
assert_file() {
local f
for f in "$@"; do
[[ ! -L "$f" && -f "$f" ]] && continue
echo "failed '$f': not a regular file"
failed 21
done
}
assert_symlink_to_file() {
local f
for f in "$@"; do
[[ -L "$f" && -f "$f" ]] && continue
echo "failed '$f': not a symlink to file"
failed 22
done
}
assert_symlink_to_dir() {
local f
for f in "$@"; do
[[ -L "$f" && -d "$f" ]] && continue
echo "failed '$f': not a symlink to dir"
failed 23
done
}
assert_symlink_dangling() {
local f
for f in "$@"; do
[[ -L "$f" && ! -e "$f" ]] && continue
echo "failed '$f': not a dangling symlink"
failed 24
done
}
copy_directory() {
if command -v rsync >/dev/null; then
rsync -aH "$1/" "$2"
else
cp -ai "$1" "$2"
fi
}
create_files() {
# clean
local d
for d in z_dir_1 z_dir_2 z_dir_3 z_dir_4; do
if [[ -d $d ]]; then
chmod -R +rwx "./$d"
rm -rf "./$d"
fi
done
mkdir z_dir_1
cd z_dir_1
: > z_file
ln -s z_file z_symlink_file
: > z_file_link_1
ln z_file_link_1 z_file_link_2
ln -s z_file_link_1 z_symlink_file_link
mkdir z_dir
ln -s z_dir z_symlink_dir
ln -s z_file_missing z_symlink_dangling
assert_file z_file*
assert_symlink_to_file z_symlink_file
assert_symlink_to_dir z_symlink_dir
assert_symlink_dangling z_symlink_dangling
cd ..
# write-protect z_dir_2/z_file*
copy_directory z_dir_1 z_dir_2
chmod a-w z_dir_2/z_file*
# write-protect z_dir_3 itself
copy_directory z_dir_1 z_dir_3
chmod a-w z_dir_3
# write-protect everything in z_dir_4
copy_directory z_dir_1 z_dir_4
chmod -R a-w z_dir_4
}
#***********************************************************************
#
#***********************************************************************
#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"
echo -e "\n${x}\n${1}\n${x}\n"
}
enter_dir() {
cd "$1" || exit 1
echo "===== $(basename "$PWD")"
}
leave_dir() {
echo "===== $(basename "$PWD") files"
ls -lA
cd ..
}
# create a tmpdir in current directory
tmpdir="$(mktemp -d tmp-upx-test-XXXXXX)"
cd "./$tmpdir" || exit 1
if [[ -f /bin/ls ]]; then
test_file="$(readlink -fn /bin/ls)"
else
test_file="$(readlink -fn /usr/bin/env)"
fi
testsuite_header "default"
flags="-qq -1 --no-filter"
mkdir default
cd default
create_files
enter_dir z_dir_1
"${upx_run[@]}" $flags z_symlink_file && failed 10
"${upx_run[@]}" $flags "$test_file" -o z_file_new || failed 11
"${upx_run[@]}" $flags "$test_file" -o z_dir && failed 12
"${upx_run[@]}" $flags "$test_file" -o z_file && failed 13
"${upx_run[@]}" $flags "$test_file" -o z_file_link_1 && failed 14
"${upx_run[@]}" $flags "$test_file" -o z_symlink_file && failed 15
"${upx_run[@]}" $flags "$test_file" -o z_symlink_file_link && failed 16
"${upx_run[@]}" $flags "$test_file" -o z_symlink_dir && failed 17
"${upx_run[@]}" $flags "$test_file" -o z_symlink_dangling && failed 18
assert_symlink_to_file z_symlink_file z_symlink_file_link
assert_symlink_to_dir z_symlink_dir
assert_symlink_dangling z_symlink_dangling
leave_dir
enter_dir z_dir_2
"${upx_run[@]}" $flags z_symlink_file && failed 10
"${upx_run[@]}" $flags "$test_file" -o z_file_new || failed 11
"${upx_run[@]}" $flags "$test_file" -o z_dir && failed 12
"${upx_run[@]}" $flags "$test_file" -o z_file && failed 13
"${upx_run[@]}" $flags "$test_file" -o z_file_link_1 && failed 14
"${upx_run[@]}" $flags "$test_file" -o z_symlink_file && failed 15
"${upx_run[@]}" $flags "$test_file" -o z_symlink_file_link && failed 16
"${upx_run[@]}" $flags "$test_file" -o z_symlink_dir && failed 17
"${upx_run[@]}" $flags "$test_file" -o z_symlink_dangling && failed 18
assert_symlink_to_file z_symlink_file z_symlink_file_link
assert_symlink_to_dir z_symlink_dir
assert_symlink_dangling z_symlink_dangling
leave_dir
enter_dir z_dir_3
"${upx_run[@]}" $flags z_symlink_file && failed 10
"${upx_run[@]}" $flags "$test_file" -o z_file_new && failed 11
"${upx_run[@]}" $flags "$test_file" -o z_dir && failed 12
"${upx_run[@]}" $flags "$test_file" -o z_file && failed 13
"${upx_run[@]}" $flags "$test_file" -o z_file_link_1 && failed 14
"${upx_run[@]}" $flags "$test_file" -o z_symlink_file && failed 15
"${upx_run[@]}" $flags "$test_file" -o z_symlink_file_link && failed 16
"${upx_run[@]}" $flags "$test_file" -o z_symlink_dir && failed 17
"${upx_run[@]}" $flags "$test_file" -o z_symlink_dangling && failed 18
assert_symlink_to_file z_symlink_file z_symlink_file_link
assert_symlink_to_dir z_symlink_dir
assert_symlink_dangling z_symlink_dangling
leave_dir
enter_dir z_dir_4
"${upx_run[@]}" $flags z_symlink_file && failed 10
"${upx_run[@]}" $flags "$test_file" -o z_file_new && failed 11
"${upx_run[@]}" $flags "$test_file" -o z_dir && failed 12
"${upx_run[@]}" $flags "$test_file" -o z_file && failed 13
"${upx_run[@]}" $flags "$test_file" -o z_file_link_1 && failed 14
"${upx_run[@]}" $flags "$test_file" -o z_symlink_file && failed 15
"${upx_run[@]}" $flags "$test_file" -o z_symlink_file_link && failed 16
"${upx_run[@]}" $flags "$test_file" -o z_symlink_dir && failed 17
"${upx_run[@]}" $flags "$test_file" -o z_symlink_dangling && failed 18
assert_symlink_to_file z_symlink_file z_symlink_file_link
assert_symlink_to_dir z_symlink_dir
assert_symlink_dangling z_symlink_dangling
leave_dir
cd ..
testsuite_header "force-overwrite"
flags="-qq -1 --no-filter --force-overwrite"
mkdir force-overwrite
cd force-overwrite
create_files
enter_dir z_dir_1
"${upx_run[@]}" $flags z_symlink_file && failed 10
"${upx_run[@]}" $flags "$test_file" -o z_file_new || failed 11
"${upx_run[@]}" $flags "$test_file" -o z_dir && failed 12
"${upx_run[@]}" $flags "$test_file" -o z_file || failed 13
"${upx_run[@]}" $flags "$test_file" -o z_file_link_1 || failed 14
"${upx_run[@]}" $flags "$test_file" -o z_symlink_file || failed 15
"${upx_run[@]}" $flags "$test_file" -o z_symlink_file_link || failed 16
"${upx_run[@]}" $flags "$test_file" -o z_symlink_dir || failed 17
"${upx_run[@]}" $flags "$test_file" -o z_symlink_dangling || failed 18
assert_file z_symlink_file z_symlink_file_link
assert_file z_symlink_dir
assert_file z_symlink_dangling
leave_dir
enter_dir z_dir_2
"${upx_run[@]}" $flags z_symlink_file && failed 10
"${upx_run[@]}" $flags "$test_file" -o z_file_new || failed 11
"${upx_run[@]}" $flags "$test_file" -o z_dir && failed 12
"${upx_run[@]}" $flags "$test_file" -o z_file || failed 13
"${upx_run[@]}" $flags "$test_file" -o z_file_link_1 || failed 14
"${upx_run[@]}" $flags "$test_file" -o z_symlink_file || failed 15
"${upx_run[@]}" $flags "$test_file" -o z_symlink_file_link || failed 16
"${upx_run[@]}" $flags "$test_file" -o z_symlink_dir || failed 17
"${upx_run[@]}" $flags "$test_file" -o z_symlink_dangling || failed 18
assert_file z_symlink_file z_symlink_file_link
assert_file z_symlink_dir
assert_file z_symlink_dangling
leave_dir
enter_dir z_dir_3
"${upx_run[@]}" $flags z_symlink_file && failed 10
"${upx_run[@]}" $flags "$test_file" -o z_file_new && failed 11
"${upx_run[@]}" $flags "$test_file" -o z_dir && failed 12
"${upx_run[@]}" $flags "$test_file" -o z_file || failed 13
"${upx_run[@]}" $flags "$test_file" -o z_file_link_1 || failed 14
"${upx_run[@]}" $flags "$test_file" -o z_symlink_file || failed 15
"${upx_run[@]}" $flags "$test_file" -o z_symlink_file_link || failed 16
"${upx_run[@]}" $flags "$test_file" -o z_symlink_dir && failed 17
"${upx_run[@]}" $flags "$test_file" -o z_symlink_dangling && failed 18
assert_symlink_to_file z_symlink_file z_symlink_file_link
assert_symlink_to_dir z_symlink_dir
assert_symlink_dangling z_symlink_dangling
leave_dir
enter_dir z_dir_4
"${upx_run[@]}" $flags z_symlink_file && failed 10
"${upx_run[@]}" $flags "$test_file" -o z_file_new && failed 11
"${upx_run[@]}" $flags "$test_file" -o z_dir && failed 12
"${upx_run[@]}" $flags "$test_file" -o z_file || failed 13
"${upx_run[@]}" $flags "$test_file" -o z_file_link_1 || failed 14
"${upx_run[@]}" $flags "$test_file" -o z_symlink_file || failed 15
"${upx_run[@]}" $flags "$test_file" -o z_symlink_file_link || failed 16
"${upx_run[@]}" $flags "$test_file" -o z_symlink_dir && failed 17
"${upx_run[@]}" $flags "$test_file" -o z_symlink_dangling && failed 18
assert_symlink_to_file z_symlink_file z_symlink_file_link
assert_symlink_to_dir z_symlink_dir
assert_symlink_dangling z_symlink_dangling
leave_dir
cd ..
if [[ 1 == 1 ]]; then
testsuite_header "link"
flags="-qq -1 --no-filter --link"
mkdir link
cd link
create_files
enter_dir z_dir_1
"${upx_run[@]}" $flags z_symlink_file && failed 10
"${upx_run[@]}" $flags "$test_file" -o z_file_new || failed 11
"${upx_run[@]}" $flags "$test_file" -o z_dir && failed 12
"${upx_run[@]}" $flags "$test_file" -o z_file || failed 13
"${upx_run[@]}" $flags "$test_file" -o z_file_link_1 || failed 14
"${upx_run[@]}" $flags "$test_file" -o z_symlink_file || failed 15
"${upx_run[@]}" $flags "$test_file" -o z_symlink_file_link || failed 16
"${upx_run[@]}" $flags "$test_file" -o z_symlink_dir || failed 17
"${upx_run[@]}" $flags "$test_file" -o z_symlink_dangling || failed 18
assert_file z_symlink_file z_symlink_file_link
assert_file z_symlink_dir
assert_file z_symlink_dangling
leave_dir
enter_dir z_dir_2
"${upx_run[@]}" $flags z_symlink_file && failed 10
"${upx_run[@]}" $flags "$test_file" -o z_file_new || failed 11
"${upx_run[@]}" $flags "$test_file" -o z_dir && failed 12
"${upx_run[@]}" $flags "$test_file" -o z_file && failed 13
"${upx_run[@]}" $flags "$test_file" -o z_file_link_1 && failed 14
"${upx_run[@]}" $flags "$test_file" -o z_symlink_file || failed 15
"${upx_run[@]}" $flags "$test_file" -o z_symlink_file_link || failed 16
"${upx_run[@]}" $flags "$test_file" -o z_symlink_dir || failed 17
"${upx_run[@]}" $flags "$test_file" -o z_symlink_dangling || failed 18
assert_file z_symlink_file z_symlink_file_link
assert_file z_symlink_dir
assert_file z_symlink_dangling
leave_dir
enter_dir z_dir_3
"${upx_run[@]}" $flags z_symlink_file && failed 10
"${upx_run[@]}" $flags "$test_file" -o z_file_new && failed 11
"${upx_run[@]}" $flags "$test_file" -o z_dir && failed 12
"${upx_run[@]}" $flags "$test_file" -o z_file || failed 13
"${upx_run[@]}" $flags "$test_file" -o z_file_link_1 || failed 14
"${upx_run[@]}" $flags "$test_file" -o z_symlink_file || failed 15
"${upx_run[@]}" $flags "$test_file" -o z_symlink_file_link || failed 16
"${upx_run[@]}" $flags "$test_file" -o z_symlink_dir && failed 17
"${upx_run[@]}" $flags "$test_file" -o z_symlink_dangling && failed 18
assert_symlink_to_file z_symlink_file z_symlink_file_link
assert_symlink_to_dir z_symlink_dir
assert_symlink_dangling z_symlink_dangling
leave_dir
enter_dir z_dir_4
"${upx_run[@]}" $flags z_symlink_file && failed 10
"${upx_run[@]}" $flags "$test_file" -o z_file_new && failed 11
"${upx_run[@]}" $flags "$test_file" -o z_dir && failed 12
"${upx_run[@]}" $flags "$test_file" -o z_file && failed 13
"${upx_run[@]}" $flags "$test_file" -o z_file_link_1 && failed 14
"${upx_run[@]}" $flags "$test_file" -o z_symlink_file || failed 15
"${upx_run[@]}" $flags "$test_file" -o z_symlink_file_link || failed 16
"${upx_run[@]}" $flags "$test_file" -o z_symlink_dir && failed 17
"${upx_run[@]}" $flags "$test_file" -o z_symlink_dangling && failed 18
assert_symlink_to_file z_symlink_file z_symlink_file_link
assert_symlink_to_dir z_symlink_dir
assert_symlink_dangling z_symlink_dangling
leave_dir
cd ..
fi
# clean up
cd ..
chmod -R +rwx "./$tmpdir"
rm -rf "./$tmpdir"
if [[ $exit_code == 0 ]]; then
echo "UPX testsuite passed. All done."
else
echo "UPX-ERROR: UPX testsuite FAILED:${all_errors}"
echo "UPX-ERROR: UPX testsuite FAILED with $num_errors error(s). See log file."
fi
exit $exit_code
@@ -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="\
d0b9b8a5bdbbc2f037e7e7b7a9fd2acd7b434ac03d7c59b4f2779c8621eed95e *amd64-linux.elf/upx-3.91 def838b0032333bf3f525944ccafe362e8921b828936fcd6f3fb397c74432795 *amd64-linux.elf/upx-3.91
d36bff9e6f49c93e4c37ab50e109bd6378128017555f8f819080f02235d48d7e *amd64-linux.elf/upx-3.95 aae4ab6795a826cee7a3f3d56acb613c17c1b1ab8c52e9830848bd8380ca395c *amd64-linux.elf/upx-3.95
9c312f13ddd40a62fed7ee9f6a21fff15cae7517d4ddf55f493101b22d8e43f1 *amd64-win64.pe/upx-3.95.exe 4faf76c6f509b5ced9349065d94da7ef4e2ff7356f050d429ae6ba37a66f7069 *amd64-win64.pe/upx-3.95.exe
b138d38c3955697ee0302332c031c996bacacf5e17eea8fce3282c4ea88f7299 *arm-linux.elf/upx-3.95 29da363abd195475090b86e9be0aff13bab7eded09575dd67bf0fc90013c00e9 *arm-linux.elf/upx-3.95
e0436401972603f7fad6c693e96c89c37370113e75b8bdb4d4ecd14dda4cd8fe *arm-wince.pe/upx-3.91.exe 0049eb0e899fc07f8f4cbe44d57b8e9558a70c34337b9f47e06a7ffdc21ad256 *arm-wince.pe/upx-3.91.exe
22107e27f63c5509f5d1c1312cb8ea1e116811695ee7f4deb765f0aa53b25a51 *arm64-linux.elf/upx-3.95 4cc6c4a1808a9a6502c92510137c28aeceb1dbd4c5a31b44ef781a02a47163d3 *arm64-linux.elf/upx-3.95
beae687a0575a65cec981e7cc63fd562d212d7ed64befe5dde2f0b7f92e4838e *armeb-linux.elf/upx-3.91 a9311d80c688a188f29f98284887fa8dca54a98c6a1693098f0bd23efadb59f4 *armeb-linux.elf/upx-3.91
55391ffd6bccd2be4e423466d327b9f345371f9941dbb30c003e677b984e8a5e *armeb-linux.elf/upx-3.95 638103772ef45ea4ce182f784609b269b8d77974d408a74752d677c0c619ee44 *armeb-linux.elf/upx-3.95
a467edf8758a5b3e219bc193a9d143cb880f7d1a94771367cda7117129b34cfc *i386-dos32.djgpp2.coff/upx-3.91.exe e8256dfde7bb3da63eb62f70bf8cef9abc6fdf9d52fd89963039bbe01e3aa10e *i386-dos32.djgpp2.coff/upx-3.91.exe
934593ba98f2dfff94197885894e7e56ff452da02a234e70734e2445b27ae8aa *i386-dos32.djgpp2.coff/upx-3.95.exe 1acd381ebcb396cd1affd59ad2708a538fda1e49be8992b908680ff3a9de0648 *i386-dos32.djgpp2.coff/upx-3.95.exe
f26697e9a9fceca98b10c1ab6a834fa6b2bd2826a2285deaafe8cd1c754a2f61 *i386-linux.elf/upx-3.91 0f806dae28529256ea89ed5c44b7f8daf8ad0f614a7433dc8b8fc9f99b1dd164 *i386-linux.elf/upx-3.91
f23467fde1af895827e7ad7c46c372802820143620fef2abe657aa8b6e7bdb26 *i386-linux.elf/upx-3.95 2b6b2e106ff23305f0713cab0f8d9509a53e82fb550cdbc8378ff52f4f5df19c *i386-linux.elf/upx-3.95
9dd14ff1328b0d501aca10d36623b2b76c754e9677cc0bdd0c5ded740796cecf *i386-win32.pe/upx-3.91.exe 695d27ebcefe8f4a6fccba050f0f82641e575233a83ea944fd35573c62c58538 *i386-win32.pe/upx-3.91.exe
5320b28b44ae1a50ea435ccabf7fe94c8031be7375c425ed618cb1f9a649442f *i386-win32.pe/upx-3.95.exe 2cff918961f8e7eee395a8d2018cb94f91ecdcac1a01988437087d2c32c78d25 *i386-win32.pe/upx-3.95.exe
d30bf134c5231317ae2182059034842f58d906b9dc49546bbb552f4e0411085f *m68k-atari.tos/upx-3.91.ttp 17a754921048185871bb83c92788e1bec8b6a86b5a8f1b6be5077894759b3edc *m68k-atari.tos/upx-3.91.ttp
9d0fca1d248d11ec8e96801dae3978c959a26e372e05836c15b56cfc0b4aa077 *mips-linux.elf/upx-3.95 f0ff4d442c1ac39411be6c8077be60476281f5a04e2736c9fbad0d950cfebe52 *mips-linux.elf/upx-3.95
d68a073cb1c222515502a3a0e8f91f424cb8cedb0d849d247531c2955fa5399a *mipsel-linux.elf/upx-3.91 3175422f8cccffaa1f7b0cda5a6f273977642652f2f618e7ef554aa74b3deae0 *mipsel-linux.elf/upx-3.91
48919a0e564866d59ae1efae06269cea2cf7ebb5e3fda4a9ce70f9f1092a7e59 *mipsel-linux.elf/upx-3.95 db78052d467edb695d31a7540c2ff07c5d5157171824e55be1c0bf830d755f9e *mipsel-linux.elf/upx-3.95
93f04183b21f077d6423c23efee62f0c920cd63463b0932ac6200e966e423763 *powerpc-linux.elf/upx-3.91 8cfb74cc5a592857167ae511c48f6ca126016b41e459846ac9376eb753e5ed2b *powerpc-linux.elf/upx-3.91
9ef05193c11073f477606ff2c8654f11c370951ff5a7902ba0cab31598751029 *powerpc-linux.elf/upx-3.95 8aaf2b9c4fbd7274f841b183b3bf799d673c77444e62b2d93cf49ecaf4eb82d8 *powerpc-linux.elf/upx-3.95
1c04d45914809449337f22c93bf645703c6c6aa499e789ff9d2dd787be257e96 *powerpc64le-linux.elf/upx-3.95 be81fe407b90afce31898085bc23b5f47b5e899347817ec85a866d10ee8f4ca9 *powerpc64le-linux.elf/upx-3.95
" "
expected_sha256sums__t120_compress_ucl_nrv2d_3_no_filter="\ expected_sha256sums__t120_compress_ucl_nrv2d_3_no_filter="\
89369823c5f2316f00f4a8af2e810a94050e28254669a2a2547a73b166178db2 *amd64-linux.elf/upx-3.91 07828062ffc59e911b115d0f4f576a996bd6c732672646cdcec9cb9f28b1e1fd *amd64-linux.elf/upx-3.91
a267b53b2de081c414ef82351a5e88431cafdd86f8202e48929d637bf6af9192 *amd64-linux.elf/upx-3.95 fa36932d3b862ffa9142025440c02b5d4b604b5bb74a680e24f00c05c415590b *amd64-linux.elf/upx-3.95
1f40d3e26e266b7c305e01a0e480f936746d1c54df32826f5f6f16fbbe58f20b *amd64-win64.pe/upx-3.95.exe 4377c48118aac9eb2d93853e7a8f26d7aeb0b09dd98b76685418424670c18d38 *amd64-win64.pe/upx-3.95.exe
3d1ac6e85dfa79f8aa36d2d73073181c5cf7dd6c3e83da3b9248fa990c535d2a *arm-linux.elf/upx-3.95 2b07d4aacbf14b188d18c814709435ff861cdd9af1cab8579604d6b64d554f18 *arm-linux.elf/upx-3.95
856d307362db229387d3d33ad8478a8cba45c71d67d5bbf2d9794154a755722f *arm-wince.pe/upx-3.91.exe f1abde57de44ea314d8b5a6ae1fbaadc539f004c1eed3153557dff0d36d86e9c *arm-wince.pe/upx-3.91.exe
2fdec54995bf5367991ef64a7582a3a0e3724a71d89e77fdbe8c5bb67071d65e *arm64-linux.elf/upx-3.95 3d71827807812c85271d26ad241b88ede4731e5d23abb49daa3141941911668a *arm64-linux.elf/upx-3.95
ddde64e009beff80e2e185b03dbe1b966ffa4c5db18fcd80c409b52233d4bb81 *armeb-linux.elf/upx-3.91 a6f100ddd3bc9a0b20c2225395aeead23038bcbcd7c2855fa8bf4b0389bded5f *armeb-linux.elf/upx-3.91
08aece1b25973a84bedb155c2976ca08e4ce1334e21659e5583f17a0e9e3bc3c *armeb-linux.elf/upx-3.95 7961d15d103ffabacf74f5be77e584eb2b382807f127ec658b62a79865cd8d7b *armeb-linux.elf/upx-3.95
ee07e1e15ff7a467f9ad262daa12886211f107886cae154795651d3cdba6fba3 *i386-dos32.djgpp2.coff/upx-3.91.exe b6e7e212ec1b839cd0fb5f0ba2676af500f12222f76eeb4961966f3efde82d59 *i386-dos32.djgpp2.coff/upx-3.91.exe
f73ac819d5f7f81b7cf62198381a51273df6a697d5429a144f42fabef0bcc327 *i386-dos32.djgpp2.coff/upx-3.95.exe 63b8c444e413534f9f57b7777635a21ed41eee5441707a61884ed504408fcf10 *i386-dos32.djgpp2.coff/upx-3.95.exe
3b9e78245b5fa3108d2e69c22764e8204d24089f6661790edbdb88a508923191 *i386-linux.elf/upx-3.91 6e5e55eaeae0861e3340d863c7ac272b5e82abf7e74805ab6c2c91406cb6d80e *i386-linux.elf/upx-3.91
6a9aa8025e9389cbbe81a04926d12e120fd57b9909de4ee934e878a04fcf6169 *i386-linux.elf/upx-3.95 3fb3dbc4de5d6a6587f179f121d3bf2b43dd35c87bb02737e08ae19659bd63b0 *i386-linux.elf/upx-3.95
7a667cc2b566ae2f8836cc3c21d55e45bf35d61beca22ec2a806d6bcbfa1f082 *i386-win32.pe/upx-3.91.exe 93dd8e25e4a4f9d73859ef82b565deadf06cf645c017f871803ec9a65e3a1f2e *i386-win32.pe/upx-3.91.exe
cdd58a31c4914bdde47f03d81b988ffc9aa2af482de775c88cae144b4ff04293 *i386-win32.pe/upx-3.95.exe c9fd12f5bd7fd7fd9b224387a19db65132829f057927b523d307986588862778 *i386-win32.pe/upx-3.95.exe
02b969917d52c4bd07e49e4ad589db8a1e4fa27984eac2eede03bc1abf73c376 *m68k-atari.tos/upx-3.91.ttp 72eabcdf8483677d4e6a34fd9292d0acc6afb977b9c11c04cb9d8701ed70a514 *m68k-atari.tos/upx-3.91.ttp
722ac1505bdaed421b6cce390608661be7236d4108429853485b8354b3c59347 *mips-linux.elf/upx-3.95 8405b6f62a9da0fb1ed48e39b835787f44e0007df25fbb5addf62e537bea5b8d *mips-linux.elf/upx-3.95
7309ee902e2c41ae72cc111c185d34e355e3892566e826698780fe69845174ad *mipsel-linux.elf/upx-3.91 e1399cdbd927de11ee2e190870072c20ae4b0457293ed095e216ec07aaef63be *mipsel-linux.elf/upx-3.91
fec12c58da7886a1eaf4702b2b0c710e2b72c4179070b04691b963d1c503c73b *mipsel-linux.elf/upx-3.95 e3ee3305d7eb8a087347563cb918826c0020f9425517dd2379d35b81f7558523 *mipsel-linux.elf/upx-3.95
13ad283bc0e4f37f9f06eddb8c384faa4a2e66e045496aa79dfde0ae59f14a95 *powerpc-linux.elf/upx-3.91 9359c529192c47170f54724d5552a9c7aea525fbe48bcb65cadf649d2a1a61bc *powerpc-linux.elf/upx-3.91
812550c5b65c39e347648e6ab9d51b2466919205a8b0928ef941ab3160151471 *powerpc-linux.elf/upx-3.95 ebfde9974eb2f5f0d84cb1d94b68bb3839f337cc19cd49f7a5bf05f5f06d0104 *powerpc-linux.elf/upx-3.95
0e651fdc257be7b3143ad06559a137be6c87f7b7ec721d1f727dc138465b219d *powerpc64le-linux.elf/upx-3.95 fe0d0e08f3f52a09b3ef266dc8ef20f8ca1b101a84697e1336aa7100be5c20bd *powerpc64le-linux.elf/upx-3.95
" "
expected_sha256sums__t130_compress_ucl_nrv2e_3_no_filter="\ expected_sha256sums__t130_compress_ucl_nrv2e_3_no_filter="\
5ee77141a1fdf1af31f3f9be97e60446873e659e341993a3bbceacb655618aa5 *amd64-linux.elf/upx-3.91 2767214e38bef8040a2ffcc49ed566110d4017c584ef8d70a19150123db70b07 *amd64-linux.elf/upx-3.91
b94c4603c372400a06c2ae7838ed9f41e6e9393d81e091a0ceed39c861e3443f *amd64-linux.elf/upx-3.95 977d6d3ea341af39113df6194981b219b03752e5690371dbe26da2e95cc3cfe0 *amd64-linux.elf/upx-3.95
c9230d017885d7727ca766cb7933d0681a93ef21856c39fbf807899b734172c0 *amd64-win64.pe/upx-3.95.exe 0b69830516796f9018614270e0f07050c09c479495c753fab9c1f0029f3e8f33 *amd64-win64.pe/upx-3.95.exe
6ae717a2a7ebe99f6d1c3af8c83939f5efe2144670806c336640ad88c29a9d90 *arm-linux.elf/upx-3.95 b6c169e5ac4e1d84202d4ca885d66c50d10a8fc0754cd11fd5b10030e02bfebb *arm-linux.elf/upx-3.95
6dbd0442d9e45c82d113463eb592d117c6761fd073e942342516fb0339d935e7 *arm-wince.pe/upx-3.91.exe bea5d7bace3c48d53c3e32c1cd21660ec38f1e5181d032e338ed01df0d2127fc *arm-wince.pe/upx-3.91.exe
6f12e95d71382a7960b9712c75a897974f29561d2a8e774b7e984c9fba380aea *arm64-linux.elf/upx-3.95 61397d56c882183181996024120c1ff6693eaad1d94b25ad589ca3f3f13f20f2 *arm64-linux.elf/upx-3.95
94dbeae5763e5c86d865e9c6e473aafdb200b1ed06bfd5981728e0fa5cc6dcc6 *armeb-linux.elf/upx-3.91 50a9129df007f66036d6c975ec65f01d40d647816495b37de22c68fcfb78029d *armeb-linux.elf/upx-3.91
cab852c4a69042aca4337869edce3af5f5aab8bf562a626ab755da0a5517bd73 *armeb-linux.elf/upx-3.95 2d60dd807a5b6e751a03bc27422e18370f33a84a400fe9764bb457df2cd71462 *armeb-linux.elf/upx-3.95
dc6d412f41101e334f9e09c52e63f513e2b0bd047064283c0f7389276dd6d28b *i386-dos32.djgpp2.coff/upx-3.91.exe 0fc777c5ce9357496422b14f426aadbd0430f862cd7d3c6a441bfab861ff7e22 *i386-dos32.djgpp2.coff/upx-3.91.exe
0ab8e2454b1f5bfed09a8d0c231f4c595c7445b09077387ebb9348292206be59 *i386-dos32.djgpp2.coff/upx-3.95.exe 0152a5c3587016f5eaac20637b6ed05df7a73de2a270a8384d6026c3c4196967 *i386-dos32.djgpp2.coff/upx-3.95.exe
7b6efd3d82b503f4d0ea3a111e80b0a1b785a2766ddea9f4090a7de190f811be *i386-linux.elf/upx-3.91 38a9525611849ea6ef99a4b9203f664c23f3f970d8057d21ebb6679674d4f1db *i386-linux.elf/upx-3.91
c1ede9406344f8b0d5fb08777c31c62016e36f54f3ff69fc03ffbc09d5b40a0e *i386-linux.elf/upx-3.95 c692d7890d9b853303374cadfea9eb53eee603acb7d483c359d40e1500dd1f78 *i386-linux.elf/upx-3.95
728c6dc0c02d9ea3f7a0c86595fd64423f5545651b3a7bbc9e708759d8eec157 *i386-win32.pe/upx-3.91.exe 9dbc382f2c7bdc808183a81fd338b8089596695128edd2def6ce39b7b4328d68 *i386-win32.pe/upx-3.91.exe
8569f6942377259c5a92acfe5bf0b2874f6ef3af40177947a8055e7641a776ef *i386-win32.pe/upx-3.95.exe 98a657dd4b718c973e88003b13ad338d1375dfa3355dc5cfc9bbb661aae158ed *i386-win32.pe/upx-3.95.exe
c4753f47328d70823f85b5d378502556388ee0a9ea6bf100cd6c73651126b3fb *m68k-atari.tos/upx-3.91.ttp 4f69c4101b169a5b77ae387f6e58413a8f0b75edfef418e48a85d4fa208f622c *m68k-atari.tos/upx-3.91.ttp
a918b7825fd5bf50097a62177b4638abee5aeb864e06ce1624042cace8a9a922 *mips-linux.elf/upx-3.95 b5795fce568d81b0d3962f022983f2c9ccc9873ab1c92c8ae2d5c2df08ba05cc *mips-linux.elf/upx-3.95
4b5cddac9a79b5e7aa99b7589d7e862bfbe026da44c2fed2a1f396883b072442 *mipsel-linux.elf/upx-3.91 29ece4f791c731eb3f17ae3ea67cc31477260050591852a12612be2d8b5f1cc2 *mipsel-linux.elf/upx-3.91
cc1be3f4d27d3ab5f6073f38c47ca72f4ba47121b14b7e60a4906a6d04af4e9c *mipsel-linux.elf/upx-3.95 00350a2493106d353c17230902ddfbd375b0b5be92c8746514a32fb5b4f20531 *mipsel-linux.elf/upx-3.95
cedc2def9464f839e9aab153dfe93dda0d37d0da43e8c600ef366f6adf17b64b *powerpc-linux.elf/upx-3.91 7bb5a8d7b9f563557eb3bc970e5a92f0e5583b43151f75ac48e2360cd3d53c87 *powerpc-linux.elf/upx-3.91
748a4a2481b73ff2881b6de39749f1672b8b8d7f1d66a6453374caf6d840777d *powerpc-linux.elf/upx-3.95 ce49efdc960a78078277c3dc746db0d9eb409d45bc6f91863e49a862bc65c966 *powerpc-linux.elf/upx-3.95
f07f45141bf199db4847fd11ff56f496790efc3b7cff248a93c4ca45ca76a71a *powerpc64le-linux.elf/upx-3.95 9a800c16d1d7db5e8c6b8140c9aecc253d65717e1dfba5ac65de7804f487efee *powerpc64le-linux.elf/upx-3.95
" "
expected_sha256sums__t140_compress_lzma_2_no_filter="\ expected_sha256sums__t140_compress_lzma_2_no_filter="\
f553659c34a772cbdaf571d83d9c8173b75f1e2deecf7c590d38e34b46cab43b *amd64-linux.elf/upx-3.91 0069bd038cddcd0b87b2f56471c7fe223eaa1186c29648c5505103e813d841c3 *amd64-linux.elf/upx-3.91
9464896ca0082d41cf7e51159e7cd58a637b0a9d7a9151930e81746f1f43898b *amd64-linux.elf/upx-3.95 82ae15c72fddba6a569c7a3c3c9dbcb9021f5de8dcaf20ef304a6255475dc076 *amd64-linux.elf/upx-3.95
255ef236a7fe03865dd300ce447c57754aef05de537564f38715eef64285c6fa *amd64-win64.pe/upx-3.95.exe 616c7bfe28cbf059d23036fab3931f1a77d8383287102e0f4533ac8bba2ed3f1 *amd64-win64.pe/upx-3.95.exe
88ae278afa54ac766f1940f3607c91d4915cdd492988dafac9be274dbda6fd5b *arm-linux.elf/upx-3.95 24110285d7f44c2caf53f8e8a4cd83e07d7650964d0d0f1adff9411731918bb2 *arm-linux.elf/upx-3.95
14f77ebb33e788aa8f9a9ad608232c3f9047dc6dfd55ceb02244a36cac9aea25 *arm-wince.pe/upx-3.91.exe 4f5a9de1efe24c8ba5acd4b858f38da0f5a05fac2eb6582960d999341c6b5a7b *arm-wince.pe/upx-3.91.exe
a79b9a7fc7e8a5e0b42fdf342fe44aae827e63809b0797d3deefd4b9f184388c *arm64-linux.elf/upx-3.95 6fe5e2a043e84e376a66a22a3cdc0cf30f04ca5fe404129e3d6ff8746a597cfd *arm64-linux.elf/upx-3.95
17603d9f6b48e10b438d65c70e8afbf87a82f84a6ee12e96ac66371663d4f18f *armeb-linux.elf/upx-3.91 fd1d2050a4e414db32375d9400dd583462d21ddc625bf48318525c4cef750194 *armeb-linux.elf/upx-3.91
5162fcc6f1327c76c2221d7a5f9668d05dd828f7a6d4dbbc732005d244947805 *armeb-linux.elf/upx-3.95 db077c6fd75e81e889ae7cfccd7fb2eb604ada3d8f68ddced1c283c8d65ec5c5 *armeb-linux.elf/upx-3.95
3a94cec95fd3eac557bf929b372b20b155e8d331e44e47eb3486b048ebb36c9f *i386-dos32.djgpp2.coff/upx-3.91.exe 68d307bdbb6dbd721cc62ca2029879c7e505e889d322176c894b5451d1975563 *i386-dos32.djgpp2.coff/upx-3.91.exe
632b63bce916203d52d997d191728667d1091694a5cfc1a2ed327b540357e7e9 *i386-dos32.djgpp2.coff/upx-3.95.exe 3a2619475906f20e9aca7eb31167c6ab502de7c496c54167f0589d0c52ab060b *i386-dos32.djgpp2.coff/upx-3.95.exe
04edc6bc3ec1a4217461ee6b81b0ea29fb25a62721c92ea62ab0dfaa147412b1 *i386-linux.elf/upx-3.91 3b64a7279552c9754b9fbe9760ce94df698d5c72e0e722013a4c8992854da97a *i386-linux.elf/upx-3.91
36f47959198dace24777e95c3dcff64940ce514dc62b9cb794e957e969f07bae *i386-linux.elf/upx-3.95 3da0a1c028d6b9a325d7beef6399379fcb2c1f6654b1be8548654c0451ff92cb *i386-linux.elf/upx-3.95
cf3c0f31aca86f30edb45e4bd945997d7acca9c2d54acfc427936fe4ff2ba355 *i386-win32.pe/upx-3.91.exe 366c066909663c9b19f9211a444ae08e228cc78a9f2cc32af6c07a5be02fcb19 *i386-win32.pe/upx-3.91.exe
c774fb5e3dcc0a00fa58ce223c30d7805f2f96606d9dddda30075c6a6c35a639 *i386-win32.pe/upx-3.95.exe 615a77ca6df08458e34c4a67ff657bab9dcc3cebf2da3d675fec623eb7dcd631 *i386-win32.pe/upx-3.95.exe
3be124d31c578530d8aa4da4ad53346a6fd62c8d4f3a9b1d068d5f912d9117ee *m68k-atari.tos/upx-3.91.ttp cd612528df6180c7a72e80dcd779729a082d9b5b5312b930032f1425f0ee6525 *m68k-atari.tos/upx-3.91.ttp
0ed619426db38bdbb783e2f47a1ce36c4b6831e00be8626f560cdf968b61f8a1 *mips-linux.elf/upx-3.95 18371b44212bb75de8ab435ad0302d5a69b9fdeb2d0e3241a860e57c8c7ae684 *mips-linux.elf/upx-3.95
9b83be53c444ad4dda60b8fa3faf9a7ae4ffb1f99027364a2af52e6c12e64462 *mipsel-linux.elf/upx-3.91 ec3b847217121ee5b7de02f1d81c44b149af9676c59d1a20eb71bd00cc200a96 *mipsel-linux.elf/upx-3.91
e405854a04fc1ebf272e57ffc74580e387ce8860ec460d77e660c829d30d9153 *mipsel-linux.elf/upx-3.95 70febd6b0460cf481681d0d2c3062d7dbfe4031a94dc0a60527b8ac236a61464 *mipsel-linux.elf/upx-3.95
f876a78a55939bf5ec990aaa3ece0a8a69d0a70eb7b00422d44ee1f0fa9ec6ea *powerpc-linux.elf/upx-3.91 7901f9f8c87e0e6adc91e4cb1f3013f8e48ac484c7f1ec93712a54bb4054b86a *powerpc-linux.elf/upx-3.91
8e65ca7e13e26b18c5ee93ab2c1a06f244dd7fff72da4523de3225feed9a4002 *powerpc-linux.elf/upx-3.95 3233502fc41d22fb5d6708a4b4a8c8bbb1a469baa818de2313d3eb682e2bcabf *powerpc-linux.elf/upx-3.95
07c6d83eeb6c664674df125fa9711c76140ccec562022f8d1334c761c00e787e *powerpc64le-linux.elf/upx-3.95 240f68868436b71c258b3941d497506ae7aa908c47a6e8d860b315f31747ae8f *powerpc64le-linux.elf/upx-3.95
" "
expected_sha256sums__t150_compress_ucl_2_all_filters="\ expected_sha256sums__t150_compress_ucl_2_all_filters="\
c41d2eb5d32c57b1302ceb17bb18b3cf7f611f8e31478f47e188cc39870b0e8d *amd64-linux.elf/upx-3.91 44782eb9d4612c0da2349a85ff203434be9fec95a7de831d5c9dddf86b4bcca6 *amd64-linux.elf/upx-3.91
0dd8f6812aed9accea975c855dc2b4ae48fa2d03554614484de1d0335364e370 *amd64-linux.elf/upx-3.95 f2a9302c55856518941e15e5e27396b09b0a6436f3fd285a72233e70307cd84f *amd64-linux.elf/upx-3.95
8cf83b49aab1a366318591fe69d87408ec1f7b36c3470a9cee82fd1fc39d7899 *amd64-win64.pe/upx-3.95.exe cea35c25e4417fa815f383195bf2bef77631e5a594943dd830228e7efb2fceaf *amd64-win64.pe/upx-3.95.exe
b4b25da30e8f5da864bd8319d1c9b193eff9cf20f365d768763a2972a02d4c0f *arm-linux.elf/upx-3.95 e3a22eea074646a74221a2f77719711cbd7dd773dc4118d1e20e7f4b4243ab7c *arm-linux.elf/upx-3.95
040117965a54878b7665b7f8155230e0f171a7749c961a1dca26eb76719b3b97 *arm-wince.pe/upx-3.91.exe 44be9300e7a196715ec98757058bd033d54f60d9b472a9bb44574bcf13ad6872 *arm-wince.pe/upx-3.91.exe
2b790cb0fe0b83ade980b1014e4b2f9336557f4f3ae469b94a32757ea88a281c *arm64-linux.elf/upx-3.95 e59d29a593ec04952ebb9d8739104eeb191c84bf179232bfd5f4cf3d93d9c300 *arm64-linux.elf/upx-3.95
aa7ad6e9b537ab8a17d4bee539d220b39ec0fded7e9924178e3be786c6cc6907 *armeb-linux.elf/upx-3.91 af99b4f754a2d69788ecd802c23b2073acb6a2c255205b1f48ee5bf858b4e0ec *armeb-linux.elf/upx-3.91
66b161bdb4f9c94518f04acb385ddcaa180913f62bafc060d9f723f2bde40bdb *armeb-linux.elf/upx-3.95 6222c23490376a8b639c887e4a74329563c887745e23e2805b2747ce4592afea *armeb-linux.elf/upx-3.95
1584cbffe0037e9e3c441aeac8fc2ef226ee78d0430d4298070c7258a5de650e *i386-dos32.djgpp2.coff/upx-3.91.exe 27d0e4525aab2f136cd9711f7f49971eeac3916c1c020b3ae96012d63d259bfa *i386-dos32.djgpp2.coff/upx-3.91.exe
da37d160c4c185dfb7c0754637278a512503ecc396741678adfda38423eaae44 *i386-dos32.djgpp2.coff/upx-3.95.exe 36825cb489b31be59873a2d7b7b70d73f5693384b4d07b43ef824c39781ba2f2 *i386-dos32.djgpp2.coff/upx-3.95.exe
39d8526dfd19d6fa8753731dc4dd362ede4a360f834f41f7d320f3e5ac1aa083 *i386-linux.elf/upx-3.91 b8f50569863c7ddc62678a83e64db1f92d52f208dab82bd0f682f2e94e9893b6 *i386-linux.elf/upx-3.91
3a86c29348f68ec5b99dad6b739a66c36f64bf35adcc7defa950e3140c99e11d *i386-linux.elf/upx-3.95 21b192de6430e534e408dd84438f3df41e0c9e2f4874d404a48fa0f6c8ef420c *i386-linux.elf/upx-3.95
6cc7deccbafc7c5a658a017ca18613b004d3b9b21e2a4e08343f92fbb82587fb *i386-win32.pe/upx-3.91.exe 0f563975edf33eda453a3ff6c29c6d4cb4986b411fd1e08ac3335a7e0efecbf0 *i386-win32.pe/upx-3.91.exe
43c04b1eef6ea89821dc8689f09865008784fcb2152cbc59a3be7c091a56a536 *i386-win32.pe/upx-3.95.exe 01192c4c7ab197ec9f94e1d759bf5375a759d258719999e30b9252598d5ba3fd *i386-win32.pe/upx-3.95.exe
d0ccb6fa3cb2557923c494a5d41615e2ba6687960144a98ae575761d20ff29d6 *m68k-atari.tos/upx-3.91.ttp e9da1f7bbac24026b3d0e102e3428b5408521140a72421be9133b3e4383f7ae8 *m68k-atari.tos/upx-3.91.ttp
9a217e5a233b523a1d031819f8e9acb00d5be03e8e8b718dc18a8819b5b04a3a *mips-linux.elf/upx-3.95 2ca89ba1d0fa58a6741e1f59b313e95501385c003628a6f54f4314a81e3bf003 *mips-linux.elf/upx-3.95
a5e18b41cad43cc4583cbb49248c3608d64df760a8deb302aaed5f96d3f9a46b *mipsel-linux.elf/upx-3.91 987d193c228b498cb0096783e0dad3f3f1a5964f0ecd8d88373be5619bf365e6 *mipsel-linux.elf/upx-3.91
b799dbcfc4fde1cdfa572a0143a4513d83636ea0883eec320761ae57a7c36ccd *mipsel-linux.elf/upx-3.95 b90ac46b8d1ad5e89c3aef00317de48de343a8789d08beba8ce73ea3d3389e0c *mipsel-linux.elf/upx-3.95
ce42a8aad4bbed730e7bcd7970efa170040eef22c9ecad4a993b81d2f6780329 *powerpc-linux.elf/upx-3.91 643e83b549b120d4b95ab9776aceb1bce00b5bcd092f8e797c6de569b7319d60 *powerpc-linux.elf/upx-3.91
6c812174a92107ac598a6b36b2e14cad82109813e14c436a2aa9d517bdea107b *powerpc-linux.elf/upx-3.95 835e1e6100c9538feae120fc49b2d279bbd47bc06d121e068b20120c1d723370 *powerpc-linux.elf/upx-3.95
047a4063962c372bce50aed451404d06e3f00a4f8a535acf0f92895ebc47ba0a *powerpc64le-linux.elf/upx-3.95 adde61c5841ee5774c58828e199410c288b1b820eb1c2a541937208c4571d6e0 *powerpc64le-linux.elf/upx-3.95
" "
expected_sha256sums__t160_compress_all_methods_1_no_filter="\ expected_sha256sums__t160_compress_all_methods_1_no_filter="\
848eff62a732dce17b36fa34277727cdbe68637dd169c0d4fa831a8085369c6c *amd64-linux.elf/upx-3.91 30d2d0daad443d6510ca98211cbb252eb7e34fb8e64dcff9f488b80efe16ae11 *amd64-linux.elf/upx-3.91
9a7a1df07d95f17b64a9c714a444b61baf790a3a3378b53c1f0f7752c5ef7aa3 *amd64-linux.elf/upx-3.95 d0d739ddf40049b1aa47adf4d223b93423b24e4b3d0b90c6784984eaf543a6a0 *amd64-linux.elf/upx-3.95
ff5f4d665a04bfa1bddabf9853686626aea828a8e542006ef7d76d49b549d9d5 *amd64-win64.pe/upx-3.95.exe 83aed8c5af108230c8e1a65978ceb0284f9aba3a2d322751a835fc00b44977e3 *amd64-win64.pe/upx-3.95.exe
a1f0f5df99eeed2009cdf2d253c824335b7010d91458297718bd257a2c2bc464 *arm-linux.elf/upx-3.95 c52fc32e70518dbb4a018bb13cae96189d6829e022a66a290ae22bdc2002ddda *arm-linux.elf/upx-3.95
8b236855f4df2df1072a93d3bd1f7203c3d43801830a38679afc354250c6a7be *arm-wince.pe/upx-3.91.exe 9f3bbd889e8ae5e84c9642b469e7572d33ee907cded259cce0cc06313694da94 *arm-wince.pe/upx-3.91.exe
e0644a18614e3ff48c3a8c306ab0c057a3ef58fab7015e522a6ef7a9aeb28970 *arm64-linux.elf/upx-3.95 4cc27218d283568ea3d291e7e81823582dadf6aad171e5e1a3cf5ed498f7e42d *arm64-linux.elf/upx-3.95
bffe4754c49568fcc9cf67e973ecb9a48e8119bab4b03d9ebae436192fbfe76b *armeb-linux.elf/upx-3.91 22b15aec122fff9af6b165be15202e2b37a9040e29d8134b36a2f1b6089b4d31 *armeb-linux.elf/upx-3.91
e69f6fc17db59b12c6910af45704c33387079492c24b1659038433e4211a8898 *armeb-linux.elf/upx-3.95 aafc89fe42ad632bf97611f0fa883ea2bad3fa8acc8609bf3fafb9e3eb7e836b *armeb-linux.elf/upx-3.95
14133daa854c4355b25e58803ad9b5e4bfb5e665fdbf12489f8b7c29ef6646a3 *i386-dos32.djgpp2.coff/upx-3.91.exe a60b7ac4aa974e777f53010d2e67b9f1797f264303a6520f6a5091c74d3ee2d5 *i386-dos32.djgpp2.coff/upx-3.91.exe
1a903afd11b866820a1814c6ee8a68431727e5c570045169295a425a6198a273 *i386-dos32.djgpp2.coff/upx-3.95.exe 40dd6e828e194af6c7ba556bb0b3f871b4359678aaa8774e4ebd2f3d2f0f8a8b *i386-dos32.djgpp2.coff/upx-3.95.exe
86a466a5d4568b225216cce95738fc63457b065b36590ca4d204108768ca8f78 *i386-linux.elf/upx-3.91 f5060a90ccdeace91e6ad7b76cea9b91782726e1ec87006a479623014c0f9a15 *i386-linux.elf/upx-3.91
79077dc8b999ee25171ee721e8ca56880c6d0b486f88747861ef437370075504 *i386-linux.elf/upx-3.95 313401757dbac85507981b32a0a1b91b8dae69341df8b883a8c9503fdc853a5e *i386-linux.elf/upx-3.95
58b93bd7d162f89c2ea187590c515192649831ab94435b87b27d47a9e74379e4 *i386-win32.pe/upx-3.91.exe b3ca631c6ef394cb1c6128a9fe80ae15046f08d6117f34b3b50f9038d9abd040 *i386-win32.pe/upx-3.91.exe
34c4260a53579a6859668cf3eb6c069cf5db82c00ad605bfdc8b2f1e0450aa16 *i386-win32.pe/upx-3.95.exe 2abd77c25d1b127df71b2ca907b886698fe366325d13fc79d42d3bad9bc80c9a *i386-win32.pe/upx-3.95.exe
8495d281bf4a8f193a204b5a56d49b3c645370049e8e83db4154db3e02d55543 *m68k-atari.tos/upx-3.91.ttp c7cb10370e0b1fc829751e454b8c31db71f374b4242a495193dd1a3095353030 *m68k-atari.tos/upx-3.91.ttp
388b013a17b84b1068502fb01b13a78a17bec5f1bd7953ec127ee3c952a7da1c *mips-linux.elf/upx-3.95 3ad999051b105774b6156216196afceca832e23ed182f23068b3fd72cb405776 *mips-linux.elf/upx-3.95
466da371ef3123d18c61e2a094d7a609e16dd005f0ea8a46d813690405e1d616 *mipsel-linux.elf/upx-3.91 22bd048307eb9c72537558e6f50f971a3d083639849fcbdba7f2ae465985f6be *mipsel-linux.elf/upx-3.91
36bed2f441c3abc918b46cfb80ff1bd31c82b264c3f69dcf0c1c28521fd53128 *mipsel-linux.elf/upx-3.95 7d85fd4fac91e65ec7c480f56dcf66fabe6597123b93e9a5d8ac09739ffb1a0c *mipsel-linux.elf/upx-3.95
0b988e12ea324ce2c6ba9506209bbb80c10bb6a02ff8949887e810f44d710338 *powerpc-linux.elf/upx-3.91 91f2cf4275d14d60ff086b6eb79eaea3b5bac5ea182cb678339a4cf70b4e46a7 *powerpc-linux.elf/upx-3.91
94981cf2f48631c476da88f8e5dcecf3ee68772ce12b189d33aaf871ef7a9536 *powerpc-linux.elf/upx-3.95 51c8366e143061412e9e9e92846ae9d6ed78dc687dd8ac3ee944c6cc55ad2b95 *powerpc-linux.elf/upx-3.95
616a829f2d1324fad2863481a5cba088f2a51c38de866c20fe9d9d7a75df3dfc *powerpc64le-linux.elf/upx-3.95 1d88a2605b6a12966b26b9d0fdd9b3f8b4ac2ebfacb022d539e52fa2ea1be0cf *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="\
55046a0c623116f9d6c78e62d7f3fb781e3aa8d8a03e987f49f0705ee3a7840b *amd64-linux.elf/upx-3.91 687cd0d51188481265c6253757a87a94378b307caa88ca95f159a9cfeb6cfa66 *amd64-linux.elf/upx-3.91
a9ca57293b43b093fb9582a81a2ad2877f7c2546a536541bf3766452a9faa4aa *amd64-linux.elf/upx-3.95 794e33f457d112b0380ccbcbfced16cf2569f15a36a974a4b009fa1ffb2e8949 *amd64-linux.elf/upx-3.95
3247a637f6cc56219bc2d6a3b16237226e1ba97ac1d0fce012657e23bfe256c3 *amd64-win64.pe/upx-3.95.exe 9ae9462455f1f8b5eb3e8950f7626a984597bb025659314acce71534e35cee88 *amd64-win64.pe/upx-3.95.exe
d43683421216236ab6e90f4f7d6ad69f3b1d18e53bc5dd57b5dcea2916fe480f *arm-linux.elf/upx-3.95 e62442fc7c0b9f4a6b54780d0cd279b59cf127b6c5f09b7d641cf07e1fd567c2 *arm-linux.elf/upx-3.95
387787098a33b61637b39d7d015972d18e687771d8596b74286764ac73ee9286 *arm-wince.pe/upx-3.91.exe 19ed6d80777a365175602a24a5207c861f79e356fdacb17623522f8b427d4233 *arm-wince.pe/upx-3.91.exe
e2e476b9ccfd13f14940f28240b8e6f85ce0e21f6cc5b619cc2972b9238b5bd2 *arm64-linux.elf/upx-3.95 66f4e3b6e14d3a38ee603708cf60896e05203fbe22f5212ae388bd807471ceef *arm64-linux.elf/upx-3.95
538eef066d7deb4b6c07de4a50ffaf24a759278beeee9204e4d6c642aa382de3 *armeb-linux.elf/upx-3.91 dc5e78ab3d0b501223e9bc43a941117c2aa5a95ebeb901cef895c40b6a61d589 *armeb-linux.elf/upx-3.91
9349eca3e551ce1d2ab95735b8898efc54439c3d87395f2c0bddbe88fbc35cbc *armeb-linux.elf/upx-3.95 78b345cbd58873a179b300519b2207ed8b419fd8aa594196522dbe53a6ab46e9 *armeb-linux.elf/upx-3.95
ce768b3be6ffeb84d0558a937a9a5778427ce56898a9b3ef9490e7e5ba6ce688 *i386-dos32.djgpp2.coff/upx-3.91.exe 7e74eac05b02b3032ae86946a4cf9e6d3c0c9af65da38bc018fcff6cb028f952 *i386-dos32.djgpp2.coff/upx-3.91.exe
849e285cb39e5609f384559398c47f5e34d2067711c58aacc5ed1c97495b8da0 *i386-dos32.djgpp2.coff/upx-3.95.exe 21136df18a98ffe3cd02cca2b28afe7680af22c36673b074d7428ae7cdb997de *i386-dos32.djgpp2.coff/upx-3.95.exe
6a0b78c2af8d68faac587531b32679a3a264fa86f524cf801db31a41a231becb *i386-linux.elf/upx-3.91 f49473440ae7ab009fabc7ef010d63abbcbffd997a9765eded2d7aee987410a6 *i386-linux.elf/upx-3.91
e524ee0c3058ba4a44073ec29d67982bc39721865b33e6881dffbe2329a79279 *i386-linux.elf/upx-3.95 a900c4100b29ef2cbddaa3fafb8ad0c036a78643c673bc95f752c804132fac82 *i386-linux.elf/upx-3.95
06d281a60d5ed815f74052e3e133915739e58c3a563a2e914186e85114687a12 *i386-win32.pe/upx-3.91.exe f30af1a399ee567e48a6421bde100c185c2adc2c4f511082de3b5269560b27f3 *i386-win32.pe/upx-3.91.exe
a1c3256670c4f55d3aea58063c4689d122c605d079537a27b1952eeab8d5d6ad *i386-win32.pe/upx-3.95.exe 675e2ee5c4bf3cb238df206342a89b66781b2805028d637a175b6f0c9f4f2334 *i386-win32.pe/upx-3.95.exe
b866f184c6fe911b410afa8080acd1c7fddc11131d15bd272eb8adbca20439d2 *m68k-atari.tos/upx-3.91.ttp cbd080edafac3eff5d1d2942a5b1084f088bf681ceaed099b40daec8c67a6a5c *m68k-atari.tos/upx-3.91.ttp
197d7dace27bbeba5627868b7a333b4580673ffe38353f3a11bd2d65b4216470 *mips-linux.elf/upx-3.95 a4dbaf71ead4ca4f4ffaa0061ceb25f531f81532fb37845cffdd2fd9750e9d12 *mips-linux.elf/upx-3.95
9b13d57d59a97313e20a0d3e02641045fddd5eb3bcbbcf7772181d5d87c4b3bf *mipsel-linux.elf/upx-3.91 2894ae7f01ed6bc44d1a1da580ba6b2a9c5a69fc18d8105f1d7afae5ef5e5769 *mipsel-linux.elf/upx-3.91
6f671511e19d9719c0bc7c2344d65cbf13a04da1c9bae9e55d2ca83ba9dede0a *mipsel-linux.elf/upx-3.95 27447c78485ac0421138594bf3b80e7ea0745537437e8915ee665509e89a80fe *mipsel-linux.elf/upx-3.95
4ec415399f04f546d9831758a3cfedb00f20b06cb7e1c2eb38354aff3b6d3004 *powerpc-linux.elf/upx-3.91 9cc94dc937a895d07cbaf50ef116a6b45e6127a10e23bc47e993d838bf1e398a *powerpc-linux.elf/upx-3.91
20e31a1df4eb5f6a930b34707b591265c6b5609ee2b2cdd5f504009284d1afc9 *powerpc-linux.elf/upx-3.95 b2ad0b8dcfb788ba344b3700f31946c9b1d8b9fda6f29665b3c9f71f2dbcdf9b *powerpc-linux.elf/upx-3.95
fe4dd9c59e6ae76ff23d6b4df27ca0df4289f6d13c8e3dc8d82c22982639ddd9 *powerpc64le-linux.elf/upx-3.95 10785a5ef331592f2135964f3e46b29f1591708bf3c09fef079ded145eb9e0e4 *powerpc64le-linux.elf/upx-3.95
" "
########## end .sha256sums.recreate ########## end .sha256sums.recreate
+27 -27
View File
@@ -15,9 +15,9 @@ argv0=$0; argv0abs=$(readlink -fn "$argv0"); argv0dir=$(dirname "$argv0abs")
# #
# see https://github.com/upx/upx-testsuite.git # see https://github.com/upx/upx-testsuite.git
# /*********************************************************************** #***********************************************************************
# // init & checks # init & checks
# ************************************************************************/ #***********************************************************************
# upx_exe # upx_exe
[[ -z $upx_exe && -f ./upx && -x ./upx ]] && upx_exe=./upx # convenience fallback [[ -z $upx_exe && -f ./upx && -x ./upx ]] && upx_exe=./upx # convenience fallback
@@ -91,9 +91,9 @@ if [[ $UPX_TESTSUITE_LEVEL == 0 ]]; then
exit 0 exit 0
fi fi
# /*********************************************************************** #***********************************************************************
# // setup # setup
# ************************************************************************/ #***********************************************************************
#set -x # debug #set -x # debug
exit_code=0 exit_code=0
@@ -108,9 +108,9 @@ rm -rf ./testsuite_1
mkdir testsuite_1 || exit 1 mkdir testsuite_1 || exit 1
cd testsuite_1 || exit 1 cd testsuite_1 || exit 1
# /*********************************************************************** #***********************************************************************
# // support functions # support functions
# ************************************************************************/ #***********************************************************************
run_upx() { run_upx() {
local ec=0 local ec=0
@@ -194,13 +194,13 @@ testsuite_run_compress() {
fi fi
} }
# /*********************************************************************** #***********************************************************************
# // expected checksums # expected checksums
# // #
# // To ease maintenance of this script in case of updates this section # To ease maintenance of this script in case of updates this section
# // can be automatically re-created from the current checksums - # can be automatically re-created from the current checksums -
# // see call of function recreate_expected_sha256sums below. # see call of function recreate_expected_sha256sums below.
# ************************************************************************/ #***********************************************************************
recreate_expected_sha256sums() { recreate_expected_sha256sums() {
local o="$1" local o="$1"
@@ -218,9 +218,9 @@ recreate_expected_sha256sums() {
source "$argv0dir/upx_testsuite_1-expected_sha256sums.sh" || exit 1 source "$argv0dir/upx_testsuite_1-expected_sha256sums.sh" || exit 1
# /*********************************************************************** #***********************************************************************
# // decompression tests # decompression tests
# ************************************************************************/ #***********************************************************************
testdir=t010_decompressed testdir=t010_decompressed
mkdir $testdir; v=expected_sha256sums__$testdir; echo -n "${!v}" >$testdir/.sha256sums.expected mkdir $testdir; v=expected_sha256sums__$testdir; echo -n "${!v}" >$testdir/.sha256sums.expected
@@ -250,11 +250,11 @@ for f in t010_decompressed/*/*; do
done done
testsuite_check_sha $testdir testsuite_check_sha $testdir
# /*********************************************************************** #***********************************************************************
# // compression tests # compression tests
# // info: we use fast compression levels because we want to # info: we use fast compression levels because we want to
# // test UPX and not the compression libraries # test UPX and not the compression libraries
# ************************************************************************/ #***********************************************************************
if [[ $UPX_TESTSUITE_LEVEL -ge 2 ]]; then if [[ $UPX_TESTSUITE_LEVEL -ge 2 ]]; then
testdir=t110_compress_ucl_nrv2b_3_no_filter testdir=t110_compress_ucl_nrv2b_3_no_filter
@@ -298,9 +298,9 @@ mkdir $testdir; v=expected_sha256sums__$testdir; echo -n "${!v}" >$testdir/.sha2
time testsuite_run_compress --all-methods --no-lzma -5 --no-filter time testsuite_run_compress --all-methods --no-lzma -5 --no-filter
fi fi
# /*********************************************************************** #***********************************************************************
# // summary # summary
# ************************************************************************/ #***********************************************************************
# recreate checksums from current version for an easy update in case of changes # recreate checksums from current version for an easy update in case of changes
recreate_expected_sha256sums .sha256sums.recreate recreate_expected_sha256sums .sha256sums.recreate
+29 -33
View File
@@ -7,12 +7,8 @@
# instead. And see the top-level Makefile for some pre-defined CMake # instead. And see the top-level Makefile for some pre-defined CMake
# build configurations. # build configurations.
MAKEFLAGS += -r
export SHELL = /bin/sh
ifndef srcdir ifndef srcdir
srcdir := $(dir $(lastword $(MAKEFILE_LIST))) srcdir := $(patsubst %/,%,$(dir $(lastword $(MAKEFILE_LIST))))
srcdir := $(shell echo '$(srcdir)' | sed 's,/*$$,,' || echo 'ERROR')
endif endif
ifndef top_srcdir ifndef top_srcdir
top_srcdir := $(srcdir)/.. top_srcdir := $(srcdir)/..
@@ -27,21 +23,22 @@ endif
build/debug: $(top_srcdir)/build/debug/upx build/debug: $(top_srcdir)/build/debug/upx
build/release: $(top_srcdir)/build/release/upx build/release: $(top_srcdir)/build/release/upx
# shortcuts
all: build/debug build/release
debug: build/debug
release: build/release
$(top_srcdir)/build/debug/upx: PHONY
$(MAKE) -C $(top_srcdir) build/debug
$(top_srcdir)/build/release/upx: PHONY
$(MAKE) -C $(top_srcdir) build/release
.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)
debug: build/debug
release: build/release
all build/all: build/debug build/release
$(top_srcdir)/build/debug/upx: 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 # see https://github.com/upx/upx-testsuite.git
@@ -77,29 +74,11 @@ run-testsuite-release: PHONY $(top_srcdir)/build/release/upx
endif endif
endif endif
#
# "make clang-format"
#
# automatically format some C++ source code files
ifeq ($(shell uname),Linux)
# Markus loves clang-format, but John hates it; find a compromise
CLANG_FORMAT_EXCLUDE_FILES += conf.h miniacc.h version.h packer_c.cpp
CLANG_FORMAT_EXCLUDE_FILES += p_elf.h p_elf_enum.h p_lx_% p_mach% p_unix% p_vmlin%
CLANG_FORMAT_EXCLUDE_FILES += compress/compress.h filter/filter_impl.cpp
CLANG_FORMAT_FILES := $(sort $(wildcard *.[ch]* ../maint/src/*.[ch]* [cu]*/*.[ch]*))
CLANG_FORMAT_FILES := $(filter-out $(CLANG_FORMAT_EXCLUDE_FILES),$(CLANG_FORMAT_FILES))
clang-format: PHONY $(CLANG_FORMAT_FILES)
@echo "running upx-clang-format"
@$(top_srcdir)/misc/scripts/upx-clang-format.sh -i $(CLANG_FORMAT_FILES)
endif
# #
# "make check-whitespace" # "make check-whitespace"
# #
CHECK_WHITESPACE = ifneq ($(wildcard /usr/bin/env),) # needs bash, perl, xargs, etc.
ifeq ($(shell uname),Linux)
CHECK_WHITESPACE = $(top_srcdir)/misc/scripts/check_whitespace.sh $(top_srcdir) CHECK_WHITESPACE = $(top_srcdir)/misc/scripts/check_whitespace.sh $(top_srcdir)
ifneq ($(wildcard $(top_srcdir)/.git/.),) ifneq ($(wildcard $(top_srcdir)/.git/.),)
CHECK_WHITESPACE = $(top_srcdir)/misc/scripts/check_whitespace_git.sh $(top_srcdir) CHECK_WHITESPACE = $(top_srcdir)/misc/scripts/check_whitespace_git.sh $(top_srcdir)
@@ -107,4 +86,21 @@ endif
check-whitespace: PHONY; $(CHECK_WHITESPACE) check-whitespace: PHONY; $(CHECK_WHITESPACE)
endif endif
#
# "make clang-format"
#
# automatically format some C++ source code files
ifeq ($(shell uname),Linux)
# Markus loves clang-format, but John hates it; find a compromise
CLANG_FORMAT_EXCLUDE_FILES += miniacc.h stub/%.h
CLANG_FORMAT_EXCLUDE_FILES += p_elf.h p_elf_enum.h p_lx_% p_mach% p_unix% p_vmlin%
CLANG_FORMAT_FILES := $(sort $(wildcard *.[ch]* ../maint/src/*.[ch]* */*.[ch]*))
CLANG_FORMAT_FILES += $(sort $(wildcard stub/tools/*/*.[ch]*))
CLANG_FORMAT_FILES := $(filter-out $(CLANG_FORMAT_EXCLUDE_FILES),$(CLANG_FORMAT_FILES))
clang-format: PHONY $(CLANG_FORMAT_FILES)
@echo "running upx-clang-format"
@$(top_srcdir)/misc/scripts/upx-clang-format.sh -i $(CLANG_FORMAT_FILES)
endif
# vim:set ts=8 sw=8 noet: # vim:set ts=8 sw=8 noet:
+136 -40
View File
@@ -42,39 +42,103 @@
#define bswap64 upx_bswap64 #define bswap64 upx_bswap64
#endif #endif
/*************************************************************************
// XE - eXtended Endian compatibility
// try to detect XX16 vs XX32 vs XX64 size mismatches
**************************************************************************/
#if 0 // permissive version using "void *"
#define REQUIRE_XE16 /*empty*/
#define REQUIRE_XE24 /*empty*/
#define REQUIRE_XE32 /*empty*/
#define REQUIRE_XE64 /*empty*/
typedef void XE16;
typedef void XE24;
typedef void XE32;
typedef void XE64;
#else // permissive version
// forward declarations
struct BE16;
struct BE32;
struct BE64;
struct LE16;
struct LE32;
struct LE64;
// Note:
// void is explicitly allowed (but there is no automatic pointer conversion because of template!)
// char is explicitly allowed
// byte is explicitly allowed
template <class T>
static inline constexpr bool is_xe16_type =
upx::is_same_any_v<T, void, char, byte, upx_int16_t, upx_uint16_t, BE16, LE16>;
template <class T>
static inline constexpr bool is_xe24_type = upx::is_same_any_v<T, void, char, byte>;
template <class T>
static inline constexpr bool is_xe32_type =
upx::is_same_any_v<T, void, char, byte, upx_int32_t, upx_uint32_t, BE32, LE32>;
template <class T>
static inline constexpr bool is_xe64_type =
upx::is_same_any_v<T, void, char, byte, upx_int64_t, upx_uint64_t, BE64, LE64>;
template <class T>
using enable_if_xe16 = std::enable_if_t<is_xe16_type<T>, T>;
template <class T>
using enable_if_xe24 = std::enable_if_t<is_xe24_type<T>, T>;
template <class T>
using enable_if_xe32 = std::enable_if_t<is_xe32_type<T>, T>;
template <class 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> >
#define REQUIRE_XE24 template <class XE24, class = enable_if_xe24<XE24> >
#define REQUIRE_XE32 template <class XE32, class = enable_if_xe32<XE32> >
#define REQUIRE_XE64 template <class XE64, class = enable_if_xe64<XE64> >
#endif // permissive version
/************************************************************************* /*************************************************************************
// core - NE // core - NE
**************************************************************************/ **************************************************************************/
static forceinline unsigned get_ne16(const void *p) noexcept { REQUIRE_XE16
static forceinline unsigned get_ne16(const XE16 *p) noexcept {
upx_uint16_t v = 0; upx_uint16_t v = 0;
upx_memcpy_inline(&v, p, sizeof(v)); upx_memcpy_inline(&v, p, sizeof(v));
return v; return v;
} }
static forceinline unsigned get_ne32(const void *p) noexcept { REQUIRE_XE32
static forceinline unsigned get_ne32(const XE32 *p) noexcept {
upx_uint32_t v = 0; upx_uint32_t v = 0;
upx_memcpy_inline(&v, p, sizeof(v)); upx_memcpy_inline(&v, p, sizeof(v));
return v; return v;
} }
static forceinline upx_uint64_t get_ne64(const void *p) noexcept { REQUIRE_XE64
static forceinline upx_uint64_t get_ne64(const XE64 *p) noexcept {
upx_uint64_t v = 0; upx_uint64_t v = 0;
upx_memcpy_inline(&v, p, sizeof(v)); upx_memcpy_inline(&v, p, sizeof(v));
return v; return v;
} }
static forceinline void set_ne16(void *p, unsigned vv) noexcept { REQUIRE_XE16
static forceinline void set_ne16(XE16 *p, unsigned vv) noexcept {
upx_uint16_t v = (upx_uint16_t) (vv & 0xffff); upx_uint16_t v = (upx_uint16_t) (vv & 0xffff);
upx_memcpy_inline(p, &v, sizeof(v)); upx_memcpy_inline(p, &v, sizeof(v));
} }
static forceinline void set_ne32(void *p, unsigned vv) noexcept { REQUIRE_XE32
static forceinline void set_ne32(XE32 *p, unsigned vv) noexcept {
upx_uint32_t v = vv; upx_uint32_t v = vv;
upx_memcpy_inline(p, &v, sizeof(v)); upx_memcpy_inline(p, &v, sizeof(v));
} }
static forceinline void set_ne64(void *p, upx_uint64_t vv) noexcept { REQUIRE_XE64
static forceinline void set_ne64(XE64 *p, upx_uint64_t vv) noexcept {
upx_uint64_t v = vv; upx_uint64_t v = vv;
upx_memcpy_inline(p, &v, sizeof(v)); upx_memcpy_inline(p, &v, sizeof(v));
} }
@@ -97,13 +161,19 @@ static forceinline upx_uint64_t bswap64(upx_uint64_t v) noexcept { return _bytes
#else #else
static forceinline constexpr unsigned bswap16(unsigned v) noexcept { static forceinline constexpr unsigned bswap16(unsigned v) noexcept {
#if defined(__riscv) && __riscv_xlen == 64
return (unsigned) __builtin_bswap64((upx_uint64_t) v << 48);
#else
// return __builtin_bswap16((upx_uint16_t) (v & 0xffff)); // return __builtin_bswap16((upx_uint16_t) (v & 0xffff));
// return (unsigned) __builtin_bswap64((upx_uint64_t) v << 48);
return __builtin_bswap32(v << 16); return __builtin_bswap32(v << 16);
#endif
} }
static forceinline constexpr unsigned bswap32(unsigned v) noexcept { static forceinline constexpr unsigned bswap32(unsigned v) noexcept {
// return (unsigned) __builtin_bswap64((upx_uint64_t) v << 32); #if defined(__riscv) && __riscv_xlen == 64
return (unsigned) __builtin_bswap64((upx_uint64_t) v << 32);
#else
return __builtin_bswap32(v); return __builtin_bswap32(v);
#endif
} }
static forceinline constexpr upx_uint64_t bswap64(upx_uint64_t v) noexcept { static forceinline constexpr upx_uint64_t bswap64(upx_uint64_t v) noexcept {
return __builtin_bswap64(v); return __builtin_bswap64(v);
@@ -138,41 +208,58 @@ static forceinline constexpr upx_uint64_t no_bswap64(upx_uint64_t v) noexcept {
// get/set 16/32/64 // get/set 16/32/64
**************************************************************************/ **************************************************************************/
inline unsigned get_be16(const void *p) noexcept { return ne16_to_be16(get_ne16(p)); } REQUIRE_XE16
inline unsigned get_be32(const void *p) noexcept { return ne32_to_be32(get_ne32(p)); } inline unsigned get_be16(const XE16 *p) noexcept { return ne16_to_be16(get_ne16(p)); }
inline upx_uint64_t get_be64(const void *p) noexcept { return ne64_to_be64(get_ne64(p)); } REQUIRE_XE32
inline unsigned get_le16(const void *p) noexcept { return ne16_to_le16(get_ne16(p)); } inline unsigned get_be32(const XE32 *p) noexcept { return ne32_to_be32(get_ne32(p)); }
inline unsigned get_le32(const void *p) noexcept { return ne32_to_le32(get_ne32(p)); } REQUIRE_XE64
inline upx_uint64_t get_le64(const void *p) noexcept { return ne64_to_le64(get_ne64(p)); } inline upx_uint64_t get_be64(const XE64 *p) noexcept { return ne64_to_be64(get_ne64(p)); }
inline void set_be16(void *p, unsigned v) noexcept { set_ne16(p, ne16_to_be16(v)); } REQUIRE_XE16
inline void set_be32(void *p, unsigned v) noexcept { set_ne32(p, ne32_to_be32(v)); } inline unsigned get_le16(const XE16 *p) noexcept { return ne16_to_le16(get_ne16(p)); }
inline void set_be64(void *p, upx_uint64_t v) noexcept { set_ne64(p, ne64_to_be64(v)); } REQUIRE_XE32
inline void set_le16(void *p, unsigned v) noexcept { set_ne16(p, ne16_to_le16(v)); } inline unsigned get_le32(const XE32 *p) noexcept { return ne32_to_le32(get_ne32(p)); }
inline void set_le32(void *p, unsigned v) noexcept { set_ne32(p, ne32_to_le32(v)); } REQUIRE_XE64
inline void set_le64(void *p, upx_uint64_t v) noexcept { set_ne64(p, ne64_to_le64(v)); } inline upx_uint64_t get_le64(const XE64 *p) noexcept { return ne64_to_le64(get_ne64(p)); }
REQUIRE_XE16
inline void set_be16(XE16 *p, unsigned v) noexcept { set_ne16(p, ne16_to_be16(v)); }
REQUIRE_XE32
inline void set_be32(XE32 *p, unsigned v) noexcept { set_ne32(p, ne32_to_be32(v)); }
REQUIRE_XE64
inline void set_be64(XE64 *p, upx_uint64_t v) noexcept { set_ne64(p, ne64_to_be64(v)); }
REQUIRE_XE16
inline void set_le16(XE16 *p, unsigned v) noexcept { set_ne16(p, ne16_to_le16(v)); }
REQUIRE_XE32
inline void set_le32(XE32 *p, unsigned v) noexcept { set_ne32(p, ne32_to_le32(v)); }
REQUIRE_XE64
inline void set_le64(XE64 *p, upx_uint64_t v) noexcept { set_ne64(p, ne64_to_le64(v)); }
/************************************************************************* /*************************************************************************
// get/set 24/26 // get/set 24/26
**************************************************************************/ **************************************************************************/
inline unsigned get_be24(const void *p) noexcept { REQUIRE_XE24
inline unsigned get_be24(const XE24 *p) noexcept {
const byte *b = ACC_CCAST(const byte *, p); const byte *b = ACC_CCAST(const byte *, p);
return (b[0] << 16) | (b[1] << 8) | (b[2] << 0); return (b[0] << 16) | (b[1] << 8) | (b[2] << 0);
} }
inline unsigned get_le24(const void *p) noexcept { REQUIRE_XE24
inline unsigned get_le24(const XE24 *p) noexcept {
const byte *b = ACC_CCAST(const byte *, p); const byte *b = ACC_CCAST(const byte *, p);
return (b[0] << 0) | (b[1] << 8) | (b[2] << 16); return (b[0] << 0) | (b[1] << 8) | (b[2] << 16);
} }
inline void set_be24(void *p, unsigned v) noexcept { REQUIRE_XE24
inline void set_be24(XE24 *p, unsigned v) noexcept {
byte *b = ACC_PCAST(byte *, p); byte *b = ACC_PCAST(byte *, p);
b[0] = ACC_ICONV(byte, (v >> 16) & 0xff); b[0] = ACC_ICONV(byte, (v >> 16) & 0xff);
b[1] = ACC_ICONV(byte, (v >> 8) & 0xff); b[1] = ACC_ICONV(byte, (v >> 8) & 0xff);
b[2] = ACC_ICONV(byte, (v >> 0) & 0xff); b[2] = ACC_ICONV(byte, (v >> 0) & 0xff);
} }
inline void set_le24(void *p, unsigned v) noexcept { REQUIRE_XE24
inline void set_le24(XE24 *p, unsigned v) noexcept {
byte *b = ACC_PCAST(byte *, p); byte *b = ACC_PCAST(byte *, p);
b[0] = ACC_ICONV(byte, (v >> 0) & 0xff); b[0] = ACC_ICONV(byte, (v >> 0) & 0xff);
b[1] = ACC_ICONV(byte, (v >> 8) & 0xff); b[1] = ACC_ICONV(byte, (v >> 8) & 0xff);
@@ -201,56 +288,64 @@ inline void set_le14_5(void *p, unsigned v) noexcept {
// get signed values // get signed values
**************************************************************************/ **************************************************************************/
static forceinline int sign_extend(unsigned v, unsigned bits) noexcept { static forceinline constexpr int sign_extend(unsigned v, unsigned bits) noexcept {
const unsigned sign_bit = 1u << (bits - 1); const unsigned sign_bit = 1u << (bits - 1);
v &= sign_bit | (sign_bit - 1); v &= sign_bit | (sign_bit - 1);
v |= 0u - (v & sign_bit); v |= 0u - (v & sign_bit);
return ACC_ICAST(int, v); return ACC_ICAST(int, v);
} }
static forceinline upx_int64_t sign_extend(upx_uint64_t v, unsigned bits) noexcept { static forceinline constexpr upx_int64_t sign_extend(upx_uint64_t v, unsigned bits) noexcept {
const upx_uint64_t sign_bit = 1ull << (bits - 1); const upx_uint64_t sign_bit = 1ull << (bits - 1);
v &= sign_bit | (sign_bit - 1); v &= sign_bit | (sign_bit - 1);
v |= 0ull - (v & sign_bit); v |= 0ull - (v & sign_bit);
return ACC_ICAST(upx_int64_t, v); return ACC_ICAST(upx_int64_t, v);
} }
inline int get_be16_signed(const void *p) noexcept { REQUIRE_XE16
inline int get_be16_signed(const XE16 *p) noexcept {
unsigned v = get_be16(p); unsigned v = get_be16(p);
return sign_extend(v, 16); return sign_extend(v, 16);
} }
inline int get_be24_signed(const void *p) noexcept { REQUIRE_XE24
inline int get_be24_signed(const XE24 *p) noexcept {
unsigned v = get_be24(p); unsigned v = get_be24(p);
return sign_extend(v, 24); return sign_extend(v, 24);
} }
inline int get_be32_signed(const void *p) noexcept { REQUIRE_XE32
inline int get_be32_signed(const XE32 *p) noexcept {
unsigned v = get_be32(p); unsigned v = get_be32(p);
return sign_extend(v, 32); return sign_extend(v, 32);
} }
inline upx_int64_t get_be64_signed(const void *p) noexcept { REQUIRE_XE64
inline upx_int64_t get_be64_signed(const XE64 *p) noexcept {
upx_uint64_t v = get_be64(p); upx_uint64_t v = get_be64(p);
return sign_extend(v, 64); return sign_extend(v, 64);
} }
inline int get_le16_signed(const void *p) noexcept { REQUIRE_XE16
inline int get_le16_signed(const XE16 *p) noexcept {
unsigned v = get_le16(p); unsigned v = get_le16(p);
return sign_extend(v, 16); return sign_extend(v, 16);
} }
inline int get_le24_signed(const void *p) noexcept { REQUIRE_XE24
inline int get_le24_signed(const XE24 *p) noexcept {
unsigned v = get_le24(p); unsigned v = get_le24(p);
return sign_extend(v, 24); return sign_extend(v, 24);
} }
inline int get_le32_signed(const void *p) noexcept { REQUIRE_XE32
inline int get_le32_signed(const XE32 *p) noexcept {
unsigned v = get_le32(p); unsigned v = get_le32(p);
return sign_extend(v, 32); return sign_extend(v, 32);
} }
inline upx_int64_t get_le64_signed(const void *p) noexcept { REQUIRE_XE64
inline upx_int64_t get_le64_signed(const XE64 *p) noexcept {
upx_uint64_t v = get_le64(p); upx_uint64_t v = get_le64(p);
return sign_extend(v, 64); return sign_extend(v, 64);
} }
@@ -633,6 +728,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()
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)); }
@@ -662,9 +758,9 @@ inline unsigned UPX_MIN(const LE32 &a, unsigned b) { return UPX_MIN(unsigned(a),
typedef BE16 NE16; typedef BE16 NE16;
typedef BE32 NE32; typedef BE32 NE32;
typedef BE64 NE64; typedef BE64 NE64;
#define ne16_compare be16_compare #define ne16_compare be16_compare
#define ne32_compare be32_compare #define ne32_compare be32_compare
#define ne64_compare be64_compare #define ne64_compare be64_compare
#define ne16_compare_signed be16_compare_signed #define ne16_compare_signed be16_compare_signed
#define ne32_compare_signed be32_compare_signed #define ne32_compare_signed be32_compare_signed
#define ne64_compare_signed be64_compare_signed #define ne64_compare_signed be64_compare_signed
@@ -672,9 +768,9 @@ typedef BE64 NE64;
typedef LE16 NE16; typedef LE16 NE16;
typedef LE32 NE32; typedef LE32 NE32;
typedef LE64 NE64; typedef LE64 NE64;
#define ne16_compare le16_compare #define ne16_compare le16_compare
#define ne32_compare le32_compare #define ne32_compare le32_compare
#define ne64_compare le64_compare #define ne64_compare le64_compare
#define ne16_compare_signed le16_compare_signed #define ne16_compare_signed le16_compare_signed
#define ne32_compare_signed le32_compare_signed #define ne32_compare_signed le32_compare_signed
#define ne64_compare_signed le64_compare_signed #define ne64_compare_signed le64_compare_signed
+64 -68
View File
@@ -43,6 +43,8 @@ int upx_doctest_check(int argc, char **argv) {
return 0; return 0;
#else #else
const char *e = getenv("UPX_DEBUG_DOCTEST_DISABLE"); const char *e = getenv("UPX_DEBUG_DOCTEST_DISABLE");
if (!e)
e = getenv("UPX_DEBUG_DISABLE_DOCTEST"); // allow alternate spelling
if (e && e[0] && strcmp(e, "0") != 0) 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
@@ -100,21 +102,6 @@ ACC_COMPILE_TIME_ASSERT_HEADER((std::is_same<unsigned, upx_uint32_t>::value))
ACC_COMPILE_TIME_ASSERT_HEADER((std::is_same<long long, upx_int64_t>::value)) ACC_COMPILE_TIME_ASSERT_HEADER((std::is_same<long long, upx_int64_t>::value))
ACC_COMPILE_TIME_ASSERT_HEADER((std::is_same<unsigned long long, upx_uint64_t>::value)) ACC_COMPILE_TIME_ASSERT_HEADER((std::is_same<unsigned long long, upx_uint64_t>::value))
ACC_COMPILE_TIME_ASSERT_HEADER((is_same_all_v<int>) )
ACC_COMPILE_TIME_ASSERT_HEADER((is_same_all_v<int, int>) )
ACC_COMPILE_TIME_ASSERT_HEADER((is_same_all_v<int, int, int>) )
ACC_COMPILE_TIME_ASSERT_HEADER((!is_same_all_v<int, char>) )
ACC_COMPILE_TIME_ASSERT_HEADER((!is_same_all_v<int, char, int>) )
ACC_COMPILE_TIME_ASSERT_HEADER((!is_same_all_v<int, int, char>) )
ACC_COMPILE_TIME_ASSERT_HEADER((!is_same_any_v<int>) )
ACC_COMPILE_TIME_ASSERT_HEADER((is_same_any_v<int, int>) )
ACC_COMPILE_TIME_ASSERT_HEADER((is_same_any_v<int, char, int>) )
ACC_COMPILE_TIME_ASSERT_HEADER((is_same_any_v<int, int, char>) )
ACC_COMPILE_TIME_ASSERT_HEADER((!is_same_any_v<int, char>) )
ACC_COMPILE_TIME_ASSERT_HEADER((!is_same_any_v<int, char, char>) )
ACC_COMPILE_TIME_ASSERT_HEADER((!is_same_any_v<int, char, long>) )
ACC_COMPILE_TIME_ASSERT_HEADER(no_bswap16(0x04030201) == 0x0201) ACC_COMPILE_TIME_ASSERT_HEADER(no_bswap16(0x04030201) == 0x0201)
ACC_COMPILE_TIME_ASSERT_HEADER(no_bswap32(0x04030201) == 0x04030201) ACC_COMPILE_TIME_ASSERT_HEADER(no_bswap32(0x04030201) == 0x04030201)
ACC_COMPILE_TIME_ASSERT_HEADER(no_bswap64(0x0807060504030201ull) == 0x0807060504030201ull) ACC_COMPILE_TIME_ASSERT_HEADER(no_bswap64(0x0807060504030201ull) == 0x0807060504030201ull)
@@ -128,42 +115,16 @@ ACC_COMPILE_TIME_ASSERT_HEADER(bswap64(bswap64(0xf8f7f6f5f4f3f2f1ull)) ==
no_bswap64(0xf8f7f6f5f4f3f2f1ull)) no_bswap64(0xf8f7f6f5f4f3f2f1ull))
#endif #endif
ACC_COMPILE_TIME_ASSERT_HEADER(usizeof(int) == sizeof(int)) ACC_COMPILE_TIME_ASSERT_HEADER(sign_extend(0u + 0, 8) == 0)
ACC_COMPILE_TIME_ASSERT_HEADER(usizeof('a') == sizeof(char)) ACC_COMPILE_TIME_ASSERT_HEADER(sign_extend(0u + 1, 8) == 1)
ACC_COMPILE_TIME_ASSERT_HEADER(usizeof("") == 1) ACC_COMPILE_TIME_ASSERT_HEADER(sign_extend(0u + 127, 8) == 127)
ACC_COMPILE_TIME_ASSERT_HEADER(usizeof("a") == 2) ACC_COMPILE_TIME_ASSERT_HEADER(sign_extend(0u + 128, 8) == -128)
ACC_COMPILE_TIME_ASSERT_HEADER(usizeof(0) == sizeof(int)) ACC_COMPILE_TIME_ASSERT_HEADER(sign_extend(0u - 1, 8) == -1)
ACC_COMPILE_TIME_ASSERT_HEADER(usizeof(0L) == sizeof(long)) ACC_COMPILE_TIME_ASSERT_HEADER(sign_extend(0u + 256, 8) == 0)
ACC_COMPILE_TIME_ASSERT_HEADER(usizeof(0LL) == sizeof(long long)) ACC_COMPILE_TIME_ASSERT_HEADER(sign_extend(0u + 257, 8) == 1)
ACC_COMPILE_TIME_ASSERT_HEADER(usizeof(nullptr) == sizeof(void *)) ACC_COMPILE_TIME_ASSERT_HEADER(sign_extend(0u + 383, 8) == 127)
ACC_COMPILE_TIME_ASSERT_HEADER(usizeof(sizeof(0)) == sizeof(size_t)) ACC_COMPILE_TIME_ASSERT_HEADER(sign_extend(0u + 384, 8) == -128)
ACC_COMPILE_TIME_ASSERT_HEADER(usizeof(usizeof(0)) == sizeof(unsigned)) ACC_COMPILE_TIME_ASSERT_HEADER(sign_extend(0u + 511, 8) == -1)
ACC_COMPILE_TIME_ASSERT_HEADER(compile_time::string_len("") == 0)
ACC_COMPILE_TIME_ASSERT_HEADER(compile_time::string_len("a") == 1)
ACC_COMPILE_TIME_ASSERT_HEADER(compile_time::string_len("ab") == 2)
ACC_COMPILE_TIME_ASSERT_HEADER(compile_time::string_len("abc") == 3)
ACC_COMPILE_TIME_ASSERT_HEADER(compile_time::string_eq("", ""))
ACC_COMPILE_TIME_ASSERT_HEADER(!compile_time::string_eq("a", ""))
ACC_COMPILE_TIME_ASSERT_HEADER(!compile_time::string_eq("", "a"))
ACC_COMPILE_TIME_ASSERT_HEADER(compile_time::string_eq("abc", "abc"))
ACC_COMPILE_TIME_ASSERT_HEADER(!compile_time::string_eq("ab", "abc"))
ACC_COMPILE_TIME_ASSERT_HEADER(!compile_time::string_eq("abc", "ab"))
ACC_COMPILE_TIME_ASSERT_HEADER(!compile_time::string_lt("", ""))
ACC_COMPILE_TIME_ASSERT_HEADER(!compile_time::string_lt("a", ""))
ACC_COMPILE_TIME_ASSERT_HEADER(compile_time::string_lt("", "a"))
ACC_COMPILE_TIME_ASSERT_HEADER(!compile_time::string_lt("abc", "abc"))
ACC_COMPILE_TIME_ASSERT_HEADER(compile_time::string_lt("ab", "abc"))
ACC_COMPILE_TIME_ASSERT_HEADER(!compile_time::string_lt("abc", "ab"))
ACC_COMPILE_TIME_ASSERT_HEADER(!compile_time::string_lt("abc", "aba"))
ACC_COMPILE_TIME_ASSERT_HEADER(compile_time::string_lt("abc", "abz"))
ACC_COMPILE_TIME_ASSERT_HEADER(compile_time::string_ne("abc", "abz"))
ACC_COMPILE_TIME_ASSERT_HEADER(!compile_time::string_gt("abc", "abz"))
ACC_COMPILE_TIME_ASSERT_HEADER(!compile_time::string_ge("abc", "abz"))
ACC_COMPILE_TIME_ASSERT_HEADER(compile_time::string_le("abc", "abz"))
ACC_COMPILE_TIME_ASSERT_HEADER(CHAR_BIT == 8) ACC_COMPILE_TIME_ASSERT_HEADER(CHAR_BIT == 8)
#if 0 // does not work with MSVC #if 0 // does not work with MSVC
@@ -227,7 +188,7 @@ struct CheckIntegral {
assert_noexcept(t.y[0] == 0 && t.y[1] == 0); assert_noexcept(t.y[0] == 0 && t.y[1] == 0);
assert_noexcept(t.z[0] == 0 && t.z[1] == 0); assert_noexcept(t.z[0] == 0 && t.z[1] == 0);
} }
#if __cplusplus < 202002L #if __cplusplus <= 201703L
COMPILE_TIME_ASSERT(std::is_pod<U>::value) // std::is_pod is deprecated in C++20 COMPILE_TIME_ASSERT(std::is_pod<U>::value) // std::is_pod is deprecated in C++20
#endif #endif
COMPILE_TIME_ASSERT(std::is_standard_layout<U>::value) COMPILE_TIME_ASSERT(std::is_standard_layout<U>::value)
@@ -360,7 +321,7 @@ 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; }
}; };
static noinline void throwSomeValue(int x) { static noinline void throwSomeValue(int x) may_throw {
if (x < 0) if (x < 0)
throw int(x); throw int(x);
else else
@@ -387,6 +348,8 @@ static noinline void check_basic_cxx_exception_handling(void (*func)(int)) noexc
void upx_compiler_sanity_check(void) noexcept { void upx_compiler_sanity_check(void) noexcept {
const char *e = getenv("UPX_DEBUG_DOCTEST_DISABLE"); const char *e = getenv("UPX_DEBUG_DOCTEST_DISABLE");
if (!e)
e = getenv("UPX_DEBUG_DISABLE_DOCTEST"); // allow alternate spelling
if (e && e[0] && strcmp(e, "0") != 0) { 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.
@@ -577,7 +540,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 don't generate any warnings
byte dummy = 0; byte dummy = 0;
byte *ptr1 = &dummy; byte *ptr1 = &dummy;
const byte *const ptr2 = &dummy; const byte *const ptr2 = &dummy;
@@ -594,20 +557,6 @@ TEST_CASE("assert_noexcept") {
assert_noexcept(!ptr3); assert_noexcept(!ptr3);
} }
TEST_CASE("noncopyable") {
struct Test : private noncopyable {
int v = 1;
};
Test t = {};
CHECK(t.v == 1);
#if (ACC_CC_MSC) // MSVC thinks that Test is not std::is_trivially_copyable; true or compiler bug?
t.v = 0;
#else
mem_clear(&t);
#endif
CHECK(t.v == 0);
}
TEST_CASE("acc_vget") { TEST_CASE("acc_vget") {
CHECK_EQ(acc_vget_int(0, 0), 0); CHECK_EQ(acc_vget_int(0, 0), 0);
CHECK_EQ(acc_vget_long(1, -1), 1); CHECK_EQ(acc_vget_long(1, -1), 1);
@@ -637,6 +586,7 @@ TEST_CASE("working -fno-strict-aliasing") {
*pi = -1; *pi = -1;
ok = *pl != 0; ok = *pl != 0;
CHECK(ok); CHECK(ok);
UNUSED(ok);
} }
TEST_CASE("working -fno-strict-overflow") { TEST_CASE("working -fno-strict-overflow") {
@@ -654,6 +604,7 @@ TEST_CASE("working -fno-strict-overflow") {
i -= 1; i -= 1;
ok = i == INT_MAX; ok = i == INT_MAX;
CHECK(ok); CHECK(ok);
UNUSED(ok);
} }
TEST_CASE("libc snprintf") { TEST_CASE("libc snprintf") {
@@ -675,4 +626,49 @@ TEST_CASE("libc snprintf") {
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);
} }
#if 0
TEST_CASE("libc qsort") {
// runtime check that libc qsort() never compares identical objects
// UPDATE: while only poor implementations of qsort() would actually do
// this, it is probably allowed by the standard; so skip this test case
struct Elem {
upx_uint16_t id;
upx_uint16_t value;
static int __acc_cdecl_qsort compare(const void *aa, const void *bb) noexcept {
const Elem *a = (const Elem *) aa;
const Elem *b = (const Elem *) bb;
assert_noexcept(a->id != b->id); // check not IDENTICAL
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) {
upx_uint32_t x = 5381 + n + ((upx_uintptr_t) e & 0xff);
for (size_t i = 0; i < n; i++) {
e[i].id = (upx_uint16_t) i;
x = x * 33 + 1 + (i & 255);
e[i].value = (upx_uint16_t) x;
}
sort(e, n, sizeof(Elem), Elem::compare);
for (size_t i = 1; i < n; i++)
if very_unlikely (e[i - 1].value > e[i].value)
return false;
return true;
}
};
constexpr size_t N = 4096;
Elem e[N];
for (size_t n = 0; n <= N; n = 2 * n + 1) {
// CHECK(Elem::check_sort(qsort, e, n)); // libc qsort()
CHECK(Elem::check_sort(upx_gnomesort, e, n));
CHECK(Elem::check_sort(upx_shellsort_memswap, e, n));
CHECK(Elem::check_sort(upx_shellsort_memcpy, e, n));
#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_std_stable_sort<sizeof(Elem)>(aa, nn, cc);
};
CHECK(Elem::check_sort(wrap_stable_sort, e, n));
#endif
}
}
#endif
/* vim:set ts=4 sw=4 et: */ /* vim:set ts=4 sw=4 et: */
+283
View File
@@ -0,0 +1,283 @@
/* dt_cxxlib.cpp -- doctest check
This file is part of the UPX executable compressor.
Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer
All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them
and/or modify them under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of
the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; see the file COPYING.
If not, write to the Free Software Foundation, Inc.,
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
Markus F.X.J. Oberhumer
<markus@oberhumer.com>
*/
// lots of tests (and probably quite a number of redundant tests)
// modern compilers will optimize away much of this code
#include "../conf.h"
/*************************************************************************
// compile-time checks
**************************************************************************/
// need extra parenthesis because the C preprocessor does not understand C++ templates
ACC_COMPILE_TIME_ASSERT_HEADER((upx::is_same_all_v<int>) )
ACC_COMPILE_TIME_ASSERT_HEADER((upx::is_same_all_v<int, int>) )
ACC_COMPILE_TIME_ASSERT_HEADER((upx::is_same_all_v<int, int, int>) )
ACC_COMPILE_TIME_ASSERT_HEADER((!upx::is_same_all_v<int, char>) )
ACC_COMPILE_TIME_ASSERT_HEADER((!upx::is_same_all_v<int, char, int>) )
ACC_COMPILE_TIME_ASSERT_HEADER((!upx::is_same_all_v<int, int, char>) )
ACC_COMPILE_TIME_ASSERT_HEADER((!upx::is_same_any_v<int>) )
ACC_COMPILE_TIME_ASSERT_HEADER((upx::is_same_any_v<int, int>) )
ACC_COMPILE_TIME_ASSERT_HEADER((upx::is_same_any_v<int, char, int>) )
ACC_COMPILE_TIME_ASSERT_HEADER((upx::is_same_any_v<int, int, char>) )
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, long>) )
ACC_COMPILE_TIME_ASSERT_HEADER(usizeof(int) == sizeof(int))
ACC_COMPILE_TIME_ASSERT_HEADER(usizeof('a') == sizeof(char))
ACC_COMPILE_TIME_ASSERT_HEADER(usizeof("") == 1)
ACC_COMPILE_TIME_ASSERT_HEADER(usizeof("a") == 2)
ACC_COMPILE_TIME_ASSERT_HEADER(usizeof(0) == sizeof(int))
ACC_COMPILE_TIME_ASSERT_HEADER(usizeof(0L) == sizeof(long))
ACC_COMPILE_TIME_ASSERT_HEADER(usizeof(0LL) == sizeof(long long))
ACC_COMPILE_TIME_ASSERT_HEADER(usizeof(nullptr) == sizeof(void *))
ACC_COMPILE_TIME_ASSERT_HEADER(usizeof(sizeof(0)) == sizeof(size_t))
ACC_COMPILE_TIME_ASSERT_HEADER(usizeof(usizeof(0)) == sizeof(unsigned))
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("a") == 1)
ACC_COMPILE_TIME_ASSERT_HEADER(compile_time::string_len("ab") == 2)
ACC_COMPILE_TIME_ASSERT_HEADER(compile_time::string_len("abc") == 3)
ACC_COMPILE_TIME_ASSERT_HEADER(compile_time::string_eq("", ""))
ACC_COMPILE_TIME_ASSERT_HEADER(!compile_time::string_eq("a", ""))
ACC_COMPILE_TIME_ASSERT_HEADER(!compile_time::string_eq("", "a"))
ACC_COMPILE_TIME_ASSERT_HEADER(compile_time::string_eq("abc", "abc"))
ACC_COMPILE_TIME_ASSERT_HEADER(!compile_time::string_eq("ab", "abc"))
ACC_COMPILE_TIME_ASSERT_HEADER(!compile_time::string_eq("abc", "ab"))
ACC_COMPILE_TIME_ASSERT_HEADER(!compile_time::string_lt("", ""))
ACC_COMPILE_TIME_ASSERT_HEADER(!compile_time::string_lt("a", ""))
ACC_COMPILE_TIME_ASSERT_HEADER(compile_time::string_lt("", "a"))
ACC_COMPILE_TIME_ASSERT_HEADER(!compile_time::string_lt("abc", "abc"))
ACC_COMPILE_TIME_ASSERT_HEADER(compile_time::string_lt("ab", "abc"))
ACC_COMPILE_TIME_ASSERT_HEADER(!compile_time::string_lt("abc", "ab"))
ACC_COMPILE_TIME_ASSERT_HEADER(!compile_time::string_lt("abc", "aba"))
ACC_COMPILE_TIME_ASSERT_HEADER(compile_time::string_lt("abc", "abz"))
ACC_COMPILE_TIME_ASSERT_HEADER(compile_time::string_ne("abc", "abz"))
ACC_COMPILE_TIME_ASSERT_HEADER(!compile_time::string_gt("abc", "abz"))
ACC_COMPILE_TIME_ASSERT_HEADER(!compile_time::string_ge("abc", "abz"))
ACC_COMPILE_TIME_ASSERT_HEADER(compile_time::string_le("abc", "abz"))
/*************************************************************************
// util
**************************************************************************/
TEST_CASE("ptr_reinterpret_cast") {
// check that we don't trigger any -Wcast-align warnings
using upx::ptr_reinterpret_cast;
void *vp = nullptr;
byte *bp = nullptr;
int *ip = nullptr;
double *dp = nullptr;
assert((vp == ptr_reinterpret_cast<void *>(vp)));
assert((vp == ptr_reinterpret_cast<void *>(bp)));
assert((vp == ptr_reinterpret_cast<void *>(ip)));
assert((vp == ptr_reinterpret_cast<void *>(dp)));
assert((bp == ptr_reinterpret_cast<byte *>(vp)));
assert((bp == ptr_reinterpret_cast<byte *>(bp)));
assert((bp == ptr_reinterpret_cast<byte *>(ip)));
assert((bp == ptr_reinterpret_cast<byte *>(dp)));
assert((ip == ptr_reinterpret_cast<int *>(vp)));
assert((ip == ptr_reinterpret_cast<int *>(bp)));
assert((ip == ptr_reinterpret_cast<int *>(ip)));
assert((ip == ptr_reinterpret_cast<int *>(dp)));
assert((dp == ptr_reinterpret_cast<double *>(vp)));
assert((dp == ptr_reinterpret_cast<double *>(bp)));
assert((dp == ptr_reinterpret_cast<double *>(ip)));
assert((dp == ptr_reinterpret_cast<double *>(dp)));
const byte *bc = nullptr;
const int *ic = nullptr;
assert((bc == ptr_reinterpret_cast<byte *>(bp)));
assert((bc == ptr_reinterpret_cast<const byte *>(bc)));
assert((bc == ptr_reinterpret_cast<byte *>(ip)));
assert((bc == ptr_reinterpret_cast<const byte *>(ic)));
assert((ic == ptr_reinterpret_cast<int *>(bp)));
assert((ic == ptr_reinterpret_cast<const int *>(bc)));
assert((ic == ptr_reinterpret_cast<int *>(ip)));
assert((ic == ptr_reinterpret_cast<const int *>(ic)));
}
TEST_CASE("noncopyable") {
struct Test : private upx::noncopyable {
int v = 1;
};
Test t = {};
CHECK(t.v == 1);
#if (ACC_CC_MSC) // MSVC thinks that Test is not std::is_trivially_copyable; true or compiler bug?
// @COMPILER_BUG @MSVC_BUG
t.v = 0;
#else
mem_clear(&t);
#endif
CHECK(t.v == 0);
constexpr Test x = {};
static_assert(x.v == 1);
}
/*************************************************************************
// TriBool checks
**************************************************************************/
namespace {
template <class T>
struct TestTriBool {
static void test(bool expect_true) {
static_assert(std::is_class<T>::value);
static_assert(std::is_nothrow_default_constructible<T>::value);
static_assert(std::is_nothrow_destructible<T>::value);
static_assert(std::is_standard_layout<T>::value);
static_assert(std::is_trivially_copyable<T>::value);
static_assert(sizeof(typename T::value_type) == sizeof(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__)
// broken compiler or broken ABI
#else
static_assert(sizeof(T) == sizeof(typename T::underlying_type));
static_assert(alignof(T) == alignof(typename T::underlying_type));
#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(true) == T::True);
static_assert(T(T::False) == T::False);
static_assert(T(T::True) == T::True);
static_assert(T(T::Third) == T::Third);
static_assert(T(T::Third) == T(9));
static_assert(T(8) == T(9));
static_assert(!(T(0) == T(9)));
static_assert(!(T(1) == T(9)));
static_assert(T(T::Third) == 9);
static_assert(T(8) == 9);
static_assert(!(T(0) == 9));
static_assert(!(T(1) == 9));
constexpr T array[] = {false, true, T::Third};
static_assert(array[0].isStrictFalse());
static_assert(array[1].isStrictTrue());
static_assert(array[2].isThird());
static_assert(sizeof(array) == 3 * sizeof(T));
T a;
assert(a.getValue() == T::False);
assert(!a);
assert(!bool(a));
assert((!a ? true : false));
assert(a.isStrictFalse());
assert(!a.isStrictTrue());
assert(a.isStrictBool());
assert(!a.isThird());
a = false;
assert(a.getValue() == T::False);
assert(!a);
assert(!bool(a));
assert((!a ? true : false));
assert(a.isStrictFalse());
assert(!a.isStrictTrue());
assert(a.isStrictBool());
assert(!a.isThird());
a = true;
assert(a.getValue() == T::True);
assert(a);
assert(bool(a));
assert((a ? true : false));
assert(!a.isStrictFalse());
assert(a.isStrictTrue());
assert(a.isStrictBool());
assert(!a.isThird());
a = T::Third;
assert(a.getValue() == T::Third);
assert(T::is_third_true == expect_true);
if (expect_true) {
assert(a);
assert(bool(a));
assert((a ? true : false));
} else {
assert(!a);
assert(!bool(a));
assert((!a ? true : false));
}
assert(!a.isStrictFalse());
assert(!a.isStrictTrue());
assert(!a.isStrictBool());
assert(a.isThird());
a = 99;
assert(a.getValue() == T::Third);
if (expect_true) {
assert(a);
assert(bool(a));
assert((a ? true : false));
} else {
assert(!a);
assert(!bool(a));
assert((!a ? true : false));
}
assert(!a.isStrictFalse());
assert(!a.isStrictTrue());
assert(!a.isStrictBool());
assert(a.isThird());
mem_clear(&a);
assert(a.isStrictFalse());
}
};
} // namespace
TEST_CASE("TriBool") {
using upx::TriBool, upx::tribool;
static_assert(!tribool(false));
static_assert(tribool(true));
static_assert(!tribool(tribool::Third));
TestTriBool<tribool>::test(false);
#if DEBUG || 1
TestTriBool<TriBool<upx_int8_t> >::test(false);
TestTriBool<TriBool<upx_uint8_t> >::test(false);
TestTriBool<TriBool<upx_int16_t> >::test(false);
TestTriBool<TriBool<upx_uint16_t> >::test(false);
TestTriBool<TriBool<upx_int32_t> >::test(false);
TestTriBool<TriBool<upx_uint32_t> >::test(false);
TestTriBool<TriBool<upx_int64_t> >::test(false);
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: */
+134 -2
View File
@@ -43,6 +43,7 @@ TEST_CASE("raw_bytes ptr") {
ptr = buf; ptr = buf;
CHECK(ptr_udiff_bytes(raw_index_bytes(ptr, 1, 1), ptr) == 2u); CHECK(ptr_udiff_bytes(raw_index_bytes(ptr, 1, 1), ptr) == 2u);
CHECK(ptr_udiff_bytes(raw_index_bytes(ptr, 4, 0), ptr) == 8u); CHECK(ptr_udiff_bytes(raw_index_bytes(ptr, 4, 0), ptr) == 8u);
UNUSED(ptr);
} }
TEST_CASE("raw_bytes bounded array") { TEST_CASE("raw_bytes bounded array") {
@@ -55,6 +56,7 @@ TEST_CASE("raw_bytes bounded array") {
CHECK_THROWS(raw_index_bytes(buf, 3, 3)); CHECK_THROWS(raw_index_bytes(buf, 3, 3));
CHECK(ptr_udiff_bytes(raw_index_bytes(buf, 1, 1), buf) == 2u); CHECK(ptr_udiff_bytes(raw_index_bytes(buf, 1, 1), buf) == 2u);
CHECK(ptr_udiff_bytes(raw_index_bytes(buf, 4, 0), buf) == 8u); CHECK(ptr_udiff_bytes(raw_index_bytes(buf, 4, 0), buf) == 8u);
UNUSED(buf);
} }
/************************************************************************* /*************************************************************************
@@ -62,7 +64,7 @@ TEST_CASE("raw_bytes bounded array") {
**************************************************************************/ **************************************************************************/
TEST_CASE("basic xspan usage") { TEST_CASE("basic xspan usage") {
char buf[4] = {0, 1, 2, 3}; alignas(4) char buf[4] = {0, 1, 2, 3};
SUBCASE("XSPAN_x") { SUBCASE("XSPAN_x") {
XSPAN_0(char) a0 = nullptr; XSPAN_0(char) a0 = nullptr;
@@ -112,6 +114,28 @@ TEST_CASE("basic xspan usage") {
CHECK_THROWS(raw_bytes(cs, 5)); CHECK_THROWS(raw_bytes(cs, 5));
CHECK_THROWS(raw_index_bytes(cs, 1, 4)); CHECK_THROWS(raw_index_bytes(cs, 1, 4));
#endif #endif
XSPAN_0(upx_uint16_t) c0_2 = XSPAN_TYPE_CAST(upx_uint16_t, c0 + 2);
XSPAN_P(upx_uint16_t) cp_2 = XSPAN_TYPE_CAST(upx_uint16_t, cp + 2);
XSPAN_S(upx_uint16_t) cs_2 = XSPAN_TYPE_CAST(upx_uint16_t, cs + 2);
CHECK(ptr_udiff_bytes(c0_2, c0) == 2u);
CHECK(ptr_udiff_bytes(cp_2, c0) == 2u);
CHECK(ptr_udiff_bytes(cs_2, c0) == 2u);
CHECK(ptr_udiff_bytes(c0_2, cp) == 2u);
CHECK(ptr_udiff_bytes(cp_2, cp) == 2u);
CHECK(ptr_udiff_bytes(cs_2, cp) == 2u);
CHECK(ptr_udiff_bytes(c0_2, cs) == 2u);
CHECK(ptr_udiff_bytes(cp_2, cs) == 2u);
CHECK(ptr_udiff_bytes(cs_2, cs) == 2u);
XSPAN_0(upx_uint16_t) c0_2b = XSPAN_TYPE_CAST(upx_uint16_t, c0) + 1;
XSPAN_P(upx_uint16_t) cp_2b = XSPAN_TYPE_CAST(upx_uint16_t, cp) + 1;
XSPAN_S(upx_uint16_t) cs_2b = XSPAN_TYPE_CAST(upx_uint16_t, cs) + 1;
CHECK(c0_2 == c0_2b);
CHECK(cp_2 == cp_2b);
CHECK(cs_2 == cs_2b);
CHECK(sizeof(*c0) == 1u);
CHECK(sizeof(*c0_2) == 2u);
} }
SUBCASE("XSPAN_x_VAR") { SUBCASE("XSPAN_x_VAR") {
@@ -169,6 +193,28 @@ TEST_CASE("basic xspan usage") {
CHECK_THROWS(raw_bytes(cs, 5)); CHECK_THROWS(raw_bytes(cs, 5));
CHECK_THROWS(raw_index_bytes(cs, 1, 4)); CHECK_THROWS(raw_index_bytes(cs, 1, 4));
#endif #endif
XSPAN_0_VAR(upx_uint16_t, c0_2, XSPAN_TYPE_CAST(upx_uint16_t, c0 + 2));
XSPAN_P_VAR(upx_uint16_t, cp_2, XSPAN_TYPE_CAST(upx_uint16_t, cp + 2));
XSPAN_S_VAR(upx_uint16_t, cs_2, XSPAN_TYPE_CAST(upx_uint16_t, cs + 2));
CHECK(ptr_udiff_bytes(c0_2, c0) == 2u);
CHECK(ptr_udiff_bytes(cp_2, c0) == 2u);
CHECK(ptr_udiff_bytes(cs_2, c0) == 2u);
CHECK(ptr_udiff_bytes(c0_2, cp) == 2u);
CHECK(ptr_udiff_bytes(cp_2, cp) == 2u);
CHECK(ptr_udiff_bytes(cs_2, cp) == 2u);
CHECK(ptr_udiff_bytes(c0_2, cs) == 2u);
CHECK(ptr_udiff_bytes(cp_2, cs) == 2u);
CHECK(ptr_udiff_bytes(cs_2, cs) == 2u);
XSPAN_0_VAR(upx_uint16_t, c0_2b, XSPAN_TYPE_CAST(upx_uint16_t, c0) + 1);
XSPAN_P_VAR(upx_uint16_t, cp_2b, XSPAN_TYPE_CAST(upx_uint16_t, cp) + 1);
XSPAN_S_VAR(upx_uint16_t, cs_2b, XSPAN_TYPE_CAST(upx_uint16_t, cs) + 1);
CHECK(c0_2 == c0_2b);
CHECK(cp_2 == cp_2b);
CHECK(cs_2 == cs_2b);
CHECK(sizeof(*c0) == 1u);
CHECK(sizeof(*c0_2) == 2u);
} }
SUBCASE("xspan in class") { SUBCASE("xspan in class") {
@@ -405,6 +451,7 @@ TEST_CASE("PtrOrSpan") {
CHECK_THROWS(sp_with_base = s0_no_base); // nullptr assignment CHECK_THROWS(sp_with_base = s0_no_base); // nullptr assignment
CHECK_THROWS(sp_with_base = s0_with_base); // nullptr assignment CHECK_THROWS(sp_with_base = s0_with_base); // nullptr assignment
#endif #endif
UNUSED(my_null);
} }
/************************************************************************* /*************************************************************************
@@ -556,6 +603,7 @@ TEST_CASE("Span") {
CHECK((XSPAN_S_MAKE(char, b1_b1).raw_base() == base_buf + 1)); CHECK((XSPAN_S_MAKE(char, b1_b1).raw_base() == base_buf + 1));
} }
#endif #endif
UNUSED(my_null);
} }
/************************************************************************* /*************************************************************************
@@ -686,6 +734,7 @@ TEST_CASE("PtrOrSpan") {
CHECK(my_memcmp_v1(buf, nullptr, 4) == -2); CHECK(my_memcmp_v1(buf, nullptr, 4) == -2);
CHECK(my_memcmp_v2(buf + 4, buf + 4, 999) == 0); CHECK(my_memcmp_v2(buf + 4, buf + 4, 999) == 0);
CHECK(my_memcmp_v2(buf, buf + 2, 3) == 0); CHECK(my_memcmp_v2(buf, buf + 2, 3) == 0);
UNUSED(buf);
} }
/************************************************************************* /*************************************************************************
@@ -801,7 +850,7 @@ TEST_CASE("PtrOrSpan int") {
namespace { namespace {
template <class T> template <class T>
__acc_static_noinline int foo(T p) { static noinline int foo(T p) {
unsigned r = 0; unsigned r = 0;
r += *p++; r += *p++;
r += *++p; r += *++p;
@@ -839,8 +888,91 @@ TEST_CASE("Span codegen") {
CHECK(foo(XSPAN_0_MAKE(upx_uint8_t, buf, 8)) == 0 + 2 + 5 + 4 + 4 + 3); CHECK(foo(XSPAN_0_MAKE(upx_uint8_t, buf, 8)) == 0 + 2 + 5 + 4 + 4 + 3);
CHECK(foo(XSPAN_P_MAKE(upx_uint8_t, buf, 8)) == 0 + 2 + 5 + 4 + 4 + 3); CHECK(foo(XSPAN_P_MAKE(upx_uint8_t, buf, 8)) == 0 + 2 + 5 + 4 + 4 + 3);
CHECK(foo(XSPAN_S_MAKE(upx_uint8_t, buf, 8)) == 0 + 2 + 5 + 4 + 4 + 3); CHECK(foo(XSPAN_S_MAKE(upx_uint8_t, buf, 8)) == 0 + 2 + 5 + 4 + 4 + 3);
UNUSED(buf);
} }
#endif // WITH_XSPAN >= 2 #endif // WITH_XSPAN >= 2
/*************************************************************************
// misc
**************************************************************************/
namespace {
template <class T>
struct PointerTraits {
typedef typename std::add_lvalue_reference<T>::type reference;
typedef
typename std::add_lvalue_reference<typename std::add_const<T>::type>::type const_reference;
typedef typename std::add_pointer<T>::type pointer;
typedef typename std::add_pointer<typename std::add_const<T>::type>::type const_pointer;
};
} // namespace
#if __cplusplus >= 201103L
TEST_CASE("decltype integral constants") {
static_assert((std::is_same<decltype(0), int>::value), "");
static_assert((std::is_same<decltype(0u), unsigned>::value), "");
static_assert((std::is_same<decltype(0l), long>::value), "");
static_assert((std::is_same<decltype(0ul), unsigned long>::value), "");
static_assert((std::is_same<decltype(0ll), long long>::value), "");
static_assert((std::is_same<decltype(0ull), unsigned long long>::value), "");
static_assert((std::is_same<decltype((char) 0), char>::value), "");
static_assert((std::is_same<decltype((short) 0), short>::value), "");
static_assert((std::is_same<decltype((long) 0), long>::value), "");
static_assert((std::is_same<decltype((long long) 0), long long>::value), "");
static_assert((std::is_same<decltype(char(0)), char>::value), "");
static_assert((std::is_same<decltype(short(0)), short>::value), "");
static_assert((std::is_same<decltype(long(0)), long>::value), "");
}
TEST_CASE("decltype pointer") {
int dummy = 0;
int *p = &dummy;
const int *c = &dummy;
static_assert((std::is_same<decltype(p - p), std::ptrdiff_t>::value), "");
static_assert((std::is_same<decltype(c - c), std::ptrdiff_t>::value), "");
static_assert((std::is_same<decltype(p - c), std::ptrdiff_t>::value), "");
static_assert((std::is_same<decltype(c - p), std::ptrdiff_t>::value), "");
typedef PointerTraits<int> TInt;
typedef PointerTraits<const int> TConstInt;
static_assert((std::is_same<int *, TInt::pointer>::value), "");
static_assert((std::is_same<const int *, TInt::const_pointer>::value), "");
static_assert((std::is_same<const int *, TConstInt::pointer>::value), "");
static_assert((std::is_same<const int *, TConstInt::const_pointer>::value), "");
//
static_assert((std::is_same<decltype(p), TInt::pointer>::value), "");
static_assert((std::is_same<decltype(c), TInt::const_pointer>::value), "");
static_assert((std::is_same<decltype(c), TConstInt::pointer>::value), "");
static_assert((std::is_same<decltype(p + 1), TInt::pointer>::value), "");
static_assert((std::is_same<decltype(c + 1), TInt::const_pointer>::value), "");
static_assert((std::is_same<decltype(c + 1), TConstInt::pointer>::value), "");
static_assert((std::is_same<decltype(c + 1), TConstInt::const_pointer>::value), "");
static_assert((std::is_same<decltype(c + 1), const int *>::value), "");
// dereference
static_assert((std::is_same<decltype(*p), TInt::reference>::value), "");
static_assert((std::is_same<decltype(*c), TInt::const_reference>::value), "");
#if 0
// this works, but avoid clang warnings:
// "Expression with side effects has no effect in an unevaluated context"
static_assert((std::is_same<decltype(*p++), TInt::reference>::value), "");
static_assert((std::is_same<decltype(*++p), TInt::reference>::value), "");
static_assert((std::is_same<decltype(*c++), TInt::const_reference>::value), "");
static_assert((std::is_same<decltype(*c++), TConstInt::reference>::value), "");
static_assert((std::is_same<decltype(*c++), TConstInt::const_reference>::value), "");
static_assert((std::is_same<decltype(*++c), TInt::const_reference>::value), "");
static_assert((std::is_same<decltype(*++c), TConstInt::reference>::value), "");
static_assert((std::is_same<decltype(*++c), TConstInt::const_reference>::value), "");
#endif
// array access
static_assert((std::is_same<decltype(p[0]), TInt::reference>::value), "");
static_assert((std::is_same<decltype(c[0]), TInt::const_reference>::value), "");
static_assert((std::is_same<decltype(c[0]), TConstInt::reference>::value), "");
static_assert((std::is_same<decltype(c[0]), TConstInt::const_reference>::value), "");
UNUSED(p);
UNUSED(c);
}
#endif // __cplusplus >= 201103L
/* vim:set ts=4 sw=4 et: */ /* vim:set ts=4 sw=4 et: */
+6
View File
@@ -92,6 +92,7 @@ int upx_compress(const upx_bytep src, unsigned src_len, upx_bytep dst, unsigned
cresult->debug.c_len = 0; cresult->debug.c_len = 0;
#endif #endif
const unsigned orig_dst_len = *dst_len;
if (__acc_cte(false)) { if (__acc_cte(false)) {
} }
#if (WITH_LZMA) #if (WITH_LZMA)
@@ -118,6 +119,7 @@ int upx_compress(const upx_bytep src, unsigned src_len, upx_bytep dst, unsigned
// debugging aid // debugging aid
cresult->debug.c_len = *dst_len; cresult->debug.c_len = *dst_len;
#endif #endif
assert_noexcept(*dst_len <= orig_dst_len);
return r; return r;
} }
@@ -135,6 +137,7 @@ int upx_decompress(const upx_bytep src, unsigned src_len, upx_bytep dst, unsigne
if (cresult && cresult->debug.method == 0) if (cresult && cresult->debug.method == 0)
cresult = nullptr; cresult = nullptr;
const unsigned orig_dst_len = *dst_len;
if (__acc_cte(false)) { if (__acc_cte(false)) {
} }
#if (WITH_LZMA) #if (WITH_LZMA)
@@ -161,6 +164,7 @@ int upx_decompress(const upx_bytep src, unsigned src_len, upx_bytep dst, unsigne
throwInternalError("unknown decompression method"); throwInternalError("unknown decompression method");
} }
assert_noexcept(*dst_len <= orig_dst_len);
return r; return r;
} }
@@ -180,6 +184,7 @@ int upx_test_overlap(const upx_bytep buf, const upx_bytep tbuf, unsigned src_off
unsigned overlap_overhead = src_off + src_len - *dst_len; unsigned overlap_overhead = src_off + src_len - *dst_len;
assert((int) overlap_overhead > 0); assert((int) overlap_overhead > 0);
const unsigned orig_dst_len = *dst_len;
if (__acc_cte(false)) { if (__acc_cte(false)) {
} }
#if (WITH_LZMA) #if (WITH_LZMA)
@@ -202,6 +207,7 @@ int upx_test_overlap(const upx_bytep buf, const upx_bytep tbuf, unsigned src_off
throwInternalError("unknown decompression method"); throwInternalError("unknown decompression method");
} }
assert_noexcept(*dst_len <= orig_dst_len);
return r; return r;
} }
+2 -10
View File
@@ -25,8 +25,8 @@
*/ */
#pragma once #pragma once
#ifndef UPX_COMPRESS_H__
#define UPX_COMPRESS_H__ 1 // clang-format off
/************************************************************************* /*************************************************************************
// //
@@ -53,7 +53,6 @@ int upx_bzip2_test_overlap ( const upx_bytep buf,
const upx_compress_result_t *cresult ); const upx_compress_result_t *cresult );
#endif #endif
#if (WITH_LZMA) #if (WITH_LZMA)
int upx_lzma_init(void); int upx_lzma_init(void);
const char *upx_lzma_version_string(void); const char *upx_lzma_version_string(void);
@@ -75,7 +74,6 @@ int upx_lzma_test_overlap ( const upx_bytep buf,
const upx_compress_result_t *cresult ); const upx_compress_result_t *cresult );
#endif #endif
#if (WITH_NRV) #if (WITH_NRV)
int upx_nrv_init(void); int upx_nrv_init(void);
const char *upx_nrv_version_string(void); const char *upx_nrv_version_string(void);
@@ -97,7 +95,6 @@ int upx_nrv_test_overlap ( const upx_bytep buf,
const upx_compress_result_t *cresult ); const upx_compress_result_t *cresult );
#endif #endif
#if (WITH_UCL) #if (WITH_UCL)
int upx_ucl_init(void); int upx_ucl_init(void);
const char *upx_ucl_version_string(void); const char *upx_ucl_version_string(void);
@@ -121,7 +118,6 @@ unsigned upx_ucl_adler32(const void *buf, unsigned len, unsigned adler);
unsigned upx_ucl_crc32 (const void *buf, unsigned len, unsigned crc); unsigned upx_ucl_crc32 (const void *buf, unsigned len, unsigned crc);
#endif #endif
#if (WITH_ZLIB) #if (WITH_ZLIB)
int upx_zlib_init(void); int upx_zlib_init(void);
const char *upx_zlib_version_string(void); const char *upx_zlib_version_string(void);
@@ -145,7 +141,6 @@ unsigned upx_zlib_adler32(const void *buf, unsigned len, unsigned adler);
unsigned upx_zlib_crc32 (const void *buf, unsigned len, unsigned crc); unsigned upx_zlib_crc32 (const void *buf, unsigned len, unsigned crc);
#endif #endif
#if (WITH_ZSTD) #if (WITH_ZSTD)
int upx_zstd_init(void); int upx_zstd_init(void);
const char *upx_zstd_version_string(void); const char *upx_zstd_version_string(void);
@@ -167,7 +162,4 @@ int upx_zstd_test_overlap ( const upx_bytep buf,
const upx_compress_result_t *cresult ); const upx_compress_result_t *cresult );
#endif #endif
#endif /* already included */
/* vim:set ts=4 sw=4 et: */ /* vim:set ts=4 sw=4 et: */
+1
View File
@@ -547,6 +547,7 @@ TEST_CASE("upx_lzma_decompress") {
d_len = 15; d_len = 15;
r = upx_lzma_decompress(c_data, 9, d_buf, &d_len, M_LZMA, nullptr); r = upx_lzma_decompress(c_data, 9, d_buf, &d_len, M_LZMA, nullptr);
CHECK(r == UPX_E_OUTPUT_OVERRUN); CHECK(r == UPX_E_OUTPUT_OVERRUN);
UNUSED(r);
} }
/* vim:set ts=4 sw=4 et: */ /* vim:set ts=4 sw=4 et: */
+1
View File
@@ -363,6 +363,7 @@ TEST_CASE("upx_ucl_decompress") {
d_len = 15; d_len = 15;
r = upx_ucl_decompress(c_data, 9, d_buf, &d_len, M_NRV2E_8, nullptr); r = upx_ucl_decompress(c_data, 9, d_buf, &d_len, M_NRV2E_8, nullptr);
CHECK(r == UPX_E_OUTPUT_OVERRUN); CHECK(r == UPX_E_OUTPUT_OVERRUN);
UNUSED(r);
} }
/* vim:set ts=4 sw=4 et: */ /* vim:set ts=4 sw=4 et: */
+1
View File
@@ -305,6 +305,7 @@ TEST_CASE("upx_zlib_decompress") {
d_len = 15; d_len = 15;
r = upx_zlib_decompress(c_data, 6, d_buf, &d_len, M_DEFLATE, nullptr); r = upx_zlib_decompress(c_data, 6, d_buf, &d_len, M_DEFLATE, nullptr);
CHECK(r == UPX_E_OUTPUT_OVERRUN); CHECK(r == UPX_E_OUTPUT_OVERRUN);
UNUSED(r);
} }
/* vim:set ts=4 sw=4 et: */ /* vim:set ts=4 sw=4 et: */
+355 -399
View File
File diff suppressed because it is too large Load Diff
+25 -25
View File
@@ -44,7 +44,7 @@
#endif #endif
#if 1 && defined(__linux__) #if 1 && defined(__linux__)
#define USE_SCREEN 1 #define USE_SCREEN 1
#define USE_SCREEN_VCSA 1 #define USE_SCREEN_VCSA 1
#if !(HAVE_LINUX_KD_H) #if !(HAVE_LINUX_KD_H)
#undef USE_SCREEN #undef USE_SCREEN
@@ -59,10 +59,10 @@
#if 1 && (ACC_OS_DOS32) && defined(__DJGPP__) #if 1 && (ACC_OS_DOS32) && defined(__DJGPP__)
#define USE_SCREEN 1 #define USE_SCREEN 1
#elif 1 && (ACC_OS_CYGWIN || ACC_OS_WIN32 || ACC_OS_WIN64) #elif 1 && (ACC_OS_CYGWIN || ACC_OS_WIN32 || ACC_OS_WIN64)
#define USE_SCREEN 1 #define USE_SCREEN 1
#define USE_SCREEN_WIN32 1 #define USE_SCREEN_WIN32 1
#elif 1 && (ACC_OS_EMX && defined(__RSXNT__)) #elif 1 && (ACC_OS_EMX && defined(__RSXNT__))
#define USE_SCREEN 1 #define USE_SCREEN 1
#define USE_SCREEN_WIN32 1 #define USE_SCREEN_WIN32 1
#elif 1 && (ACC_ARCH_M68K && ACC_OS_TOS) #elif 1 && (ACC_ARCH_M68K && ACC_OS_TOS)
#define NO_CONSOLE 1 #define NO_CONSOLE 1
@@ -111,31 +111,31 @@ typedef struct {
void con_fprintf(FILE *f, const char *format, ...) attribute_format(2, 3); void con_fprintf(FILE *f, const char *format, ...) attribute_format(2, 3);
#define FG_BLACK 0x00 #define FG_BLACK 0x00
#define FG_BLUE 0x01 #define FG_BLUE 0x01
#define FG_GREEN 0x02 #define FG_GREEN 0x02
#define FG_CYAN 0x03 #define FG_CYAN 0x03
#define FG_RED 0x04 #define FG_RED 0x04
#define FG_VIOLET 0x05 #define FG_VIOLET 0x05
#define FG_ORANGE 0x06 #define FG_ORANGE 0x06
#define FG_LTGRAY 0x07 #define FG_LTGRAY 0x07
#define FG_DKGRAY 0x08 #define FG_DKGRAY 0x08
#define FG_BRTBLUE 0x09 #define FG_BRTBLUE 0x09
#define FG_BRTGREEN 0x0a #define FG_BRTGREEN 0x0a
#define FG_BRTCYAN 0x0b #define FG_BRTCYAN 0x0b
#define FG_BRTRED 0x0c #define FG_BRTRED 0x0c
#define FG_BRTVIOLET 0x0d #define FG_BRTVIOLET 0x0d
#define FG_YELLOW 0x0e #define FG_YELLOW 0x0e
#define FG_WHITE 0x0f #define FG_WHITE 0x0f
#define BG_BLACK 0x00 #define BG_BLACK 0x00
#define BG_BLUE 0x10 #define BG_BLUE 0x10
#define BG_GREEN 0x20 #define BG_GREEN 0x20
#define BG_CYAN 0x30 #define BG_CYAN 0x30
#define BG_RED 0x40 #define BG_RED 0x40
#define BG_VIOLET 0x50 #define BG_VIOLET 0x50
#define BG_ORANGE 0x60 #define BG_ORANGE 0x60
#define BG_WHITE 0x70 #define BG_WHITE 0x70
#endif /* USE_CONSOLE */ #endif /* USE_CONSOLE */
@@ -162,7 +162,7 @@ extern console_t console_screen;
#else #else
#define con_fg(f, x) 0 #define con_fg(f, x) 0
#define con_fprintf fprintf #define con_fprintf fprintf
#endif /* USE_CONSOLE */ #endif /* USE_CONSOLE */
+1 -1
View File
@@ -55,7 +55,7 @@
#include <sys/farptr.h> #include <sys/farptr.h>
#include <sys/movedata.h> #include <sys/movedata.h>
#define dossel _go32_info_block.selector_for_linear_memory #define dossel _go32_info_block.selector_for_linear_memory
#define co80 _go32_info_block.linear_address_of_primary_screen #define co80 _go32_info_block.linear_address_of_primary_screen
#undef kbhit #undef kbhit
#define Cell upx_uint16_t #define Cell upx_uint16_t
+9 -18
View File
@@ -29,6 +29,15 @@
#if (USE_SCREEN_WIN32) #if (USE_SCREEN_WIN32)
/*************************************************************************
// 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
@@ -36,24 +45,6 @@
#define mask_fg 0x0f #define mask_fg 0x0f
#define mask_bg 0xf0 #define mask_bg 0xf0
/*************************************************************************
// direct screen access
**************************************************************************/
#if (ACC_CC_MSC && (_MSC_VER >= 1000 && _MSC_VER < 1200))
/* avoid -W4 warnings in <conio.h> */
#pragma warning(disable : 4032)
/* avoid -W4 warnings in <windows.h> */
#pragma warning(disable : 4201 4214 4514)
#endif
#if defined(__RSXNT__)
#define timeval win32_timeval /* struct timeval already in <sys/time.h> */
#endif
#include <windows.h>
#if (HAVE_CONIO_H)
#include <conio.h>
#endif
struct screen_data_t { struct screen_data_t {
HANDLE hi; HANDLE hi;
HANDLE ho; HANDLE ho;
-4
View File
@@ -26,8 +26,6 @@
*/ */
#pragma once #pragma once
#ifndef UPX_SCREEN_H__
#define UPX_SCREEN_H__ 1
#if (USE_SCREEN) #if (USE_SCREEN)
@@ -100,6 +98,4 @@ void screen_show_frames(screen_t *);
#endif /* USE_SCREEN */ #endif /* USE_SCREEN */
#endif /* already included */
/* vim:set ts=4 sw=4 et: */ /* vim:set ts=4 sw=4 et: */
+3 -3
View File
@@ -142,7 +142,7 @@ void throwEOFException(const char *msg, int e) {
} }
/************************************************************************* /*************************************************************************
// // varargs overloads
**************************************************************************/ **************************************************************************/
template <> template <>
@@ -166,7 +166,7 @@ void throwCantUnpack(const char *format, ...) {
} }
/************************************************************************* /*************************************************************************
// // util
**************************************************************************/ **************************************************************************/
void assertFailed(const char *expr, const char *file, int line, const char *func) noexcept { void assertFailed(const char *expr, const char *file, int line, const char *func) noexcept {
@@ -191,7 +191,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++ else if (strncmp(n, "class ", 6) == 0) // Visual C++ (msvc)
n += 6; n += 6;
else else
break; break;
+18 -18
View File
@@ -186,32 +186,32 @@ public:
#define NORET noinline #define NORET noinline
#endif #endif
NORET void throwCantPack(const char *msg); NORET void throwCantPack(const char *msg) may_throw;
NORET void throwCantPackExact(); NORET void throwCantPackExact() may_throw;
NORET void throwUnknownExecutableFormat(const char *msg = nullptr, bool warn = false); NORET void throwUnknownExecutableFormat(const char *msg = nullptr, bool warn = false) may_throw;
NORET void throwNotCompressible(const char *msg = nullptr); NORET void throwNotCompressible(const char *msg = nullptr) may_throw;
NORET void throwAlreadyPacked(const char *msg = nullptr); NORET void throwAlreadyPacked(const char *msg = nullptr) may_throw;
NORET void throwAlreadyPackedByUPX(const char *msg = nullptr); NORET void throwAlreadyPackedByUPX(const char *msg = nullptr) may_throw;
NORET void throwCantUnpack(const char *msg); NORET void throwCantUnpack(const char *msg) may_throw;
NORET void throwNotPacked(const char *msg = nullptr); NORET void throwNotPacked(const char *msg = nullptr) may_throw;
NORET void throwFilterException(); NORET void throwFilterException() may_throw;
NORET void throwBadLoader(); NORET void throwBadLoader() may_throw;
NORET void throwChecksumError(); NORET void throwChecksumError() may_throw;
NORET void throwCompressedDataViolation(); NORET void throwCompressedDataViolation() may_throw;
NORET void throwInternalError(const char *msg); NORET void throwInternalError(const char *msg) may_throw;
NORET void throwOutOfMemoryException(const char *msg = nullptr); NORET void throwOutOfMemoryException(const char *msg = nullptr) may_throw;
NORET void throwIOException(const char *msg = nullptr, int e = 0); NORET void throwIOException(const char *msg = nullptr, int e = 0) may_throw;
NORET void throwEOFException(const char *msg = nullptr, int e = 0); NORET void throwEOFException(const char *msg = nullptr, int e = 0) may_throw;
// some C++ template wizardry is needed to overload throwCantPack() for varargs // some C++ template wizardry is needed to overload throwCantPack() for varargs
template <class T> template <class T>
void throwCantPack(const T *, ...) DELETED_FUNCTION; void throwCantPack(const T *, ...) DELETED_FUNCTION;
template <> template <>
NORET void throwCantPack(const char *format, ...) attribute_format(1, 2); NORET void throwCantPack(const char *format, ...) may_throw attribute_format(1, 2);
template <class T> template <class T>
void throwCantUnpack(const T *, ...) DELETED_FUNCTION; void throwCantUnpack(const T *, ...) DELETED_FUNCTION;
template <> template <>
NORET void throwCantUnpack(const char *format, ...) attribute_format(1, 2); NORET void throwCantUnpack(const char *format, ...) may_throw attribute_format(1, 2);
#undef NORET #undef NORET
+29 -18
View File
@@ -33,6 +33,7 @@
**************************************************************************/ **************************************************************************/
/*static*/ void FileBase::chmod(const char *name, int mode) { /*static*/ void FileBase::chmod(const char *name, int mode) {
assert(name != nullptr && name[0] != 0);
#if HAVE_CHMOD #if HAVE_CHMOD
if (::chmod(name, mode) != 0) if (::chmod(name, mode) != 0)
throwIOException(name, errno); throwIOException(name, errno);
@@ -51,24 +52,34 @@
throwIOException("rename error", errno); throwIOException("rename error", errno);
} }
/*static*/ bool FileBase::unlink_noexcept(const char *name) noexcept {
assert_noexcept(name != nullptr && name[0] != 0);
bool success = ::unlink(name) == 0;
#if HAVE_CHMOD
if (!success)
success = (::chmod(name, 0666) == 0 && ::unlink(name) == 0);
#endif
return success;
}
/*static*/ void FileBase::unlink(const char *name) { /*static*/ void FileBase::unlink(const char *name) {
if (::unlink(name) != 0) if (!unlink_noexcept(name))
throwIOException(name, errno); throwIOException(name, errno);
} }
/************************************************************************* /*************************************************************************
// // FileBase
**************************************************************************/ **************************************************************************/
FileBase::~FileBase() may_throw { FileBase::~FileBase() may_throw {
#if 0 && defined(__GNUC__) // debug #if 0 && defined(__GNUC__) // debug
if (isOpen()) if (isOpen())
fprintf(stderr,"%s: %s\n", _name, __PRETTY_FUNCTION__); fprintf(stderr, "%s: %s\n", _name, __PRETTY_FUNCTION__);
#endif #endif
if (std::uncaught_exceptions() == 0)
// FIXME: we should use close() during exception unwinding but closex(); // may_throw
// closex() otherwise else
closex(); close_noexcept(); // currently in exception unwinding, use noexcept variant
} }
bool FileBase::do_sopen() { bool FileBase::do_sopen() {
@@ -93,7 +104,7 @@ bool FileBase::do_sopen() {
return true; return true;
} }
bool FileBase::close() noexcept { bool FileBase::close_noexcept() noexcept {
bool ok = true; bool ok = true;
if (isOpen() && _fd != STDIN_FILENO && _fd != STDOUT_FILENO && _fd != STDERR_FILENO) if (isOpen() && _fd != STDIN_FILENO && _fd != STDOUT_FILENO && _fd != STDERR_FILENO)
if (::close(_fd) == -1) if (::close(_fd) == -1)
@@ -108,7 +119,7 @@ bool FileBase::close() noexcept {
} }
void FileBase::closex() may_throw { void FileBase::closex() may_throw {
if (!close()) if (!close_noexcept())
throwIOException("close failed", errno); throwIOException("close failed", errno);
} }
@@ -121,14 +132,14 @@ upx_off_t FileBase::seek(upx_off_t off, int whence) {
if (off < 0) if (off < 0)
throwIOException("bad seek 2"); throwIOException("bad seek 2");
off += _offset; off += _offset;
} } else if (whence == SEEK_END) {
if (whence == SEEK_END) {
if (off > 0) if (off > 0)
throwIOException("bad seek 3"); throwIOException("bad seek 3");
off += _offset + _length; off += _offset + _length;
whence = SEEK_SET; whence = SEEK_SET;
} } else if (whence == SEEK_CUR) {
// SEEK_CUR falls through to here } else
throwInternalError("bad seek: whence");
upx_off_t l = ::lseek(_fd, off, whence); upx_off_t l = ::lseek(_fd, off, whence);
if (l < 0) if (l < 0)
throwIOException("seek error", errno); throwIOException("seek error", errno);
@@ -152,11 +163,11 @@ void FileBase::set_extent(upx_off_t offset, upx_off_t length) {
upx_off_t FileBase::st_size() const { return _length; } upx_off_t FileBase::st_size() const { return _length; }
/************************************************************************* /*************************************************************************
// // InputFile
**************************************************************************/ **************************************************************************/
void InputFile::sopen(const char *name, int flags, int shflags) { void InputFile::sopen(const char *name, int flags, int shflags) {
close(); closex();
_name = name; _name = name;
_flags = flags; _flags = flags;
_shflags = shflags; _shflags = shflags;
@@ -202,11 +213,11 @@ upx_off_t InputFile::seek(upx_off_t off, int whence) {
upx_off_t InputFile::st_size_orig() const { return _length_orig; } upx_off_t InputFile::st_size_orig() const { return _length_orig; }
/************************************************************************* /*************************************************************************
// // OutputFile
**************************************************************************/ **************************************************************************/
void OutputFile::sopen(const char *name, int flags, int shflags, int mode) { void OutputFile::sopen(const char *name, int flags, int shflags, int mode) {
close(); closex();
_name = name; _name = name;
_flags = flags; _flags = flags;
_shflags = shflags; _shflags = shflags;
@@ -228,7 +239,7 @@ void OutputFile::sopen(const char *name, int flags, int shflags, int mode) {
} }
bool OutputFile::openStdout(int flags, bool force) { bool OutputFile::openStdout(int flags, bool force) {
close(); closex();
int fd = STDOUT_FILENO; int fd = STDOUT_FILENO;
if (!force && acc_isatty(fd)) if (!force && acc_isatty(fd))
return false; return false;
+8 -7
View File
@@ -37,11 +37,11 @@ protected:
virtual ~FileBase() may_throw; virtual ~FileBase() may_throw;
public: public:
bool close() noexcept; bool close_noexcept() noexcept;
void closex() may_throw; void closex() may_throw;
bool isOpen() const { return _fd >= 0; } bool isOpen() const noexcept { return _fd >= 0; }
int getFd() const { return _fd; } int getFd() const noexcept { return _fd; }
const char *getName() const { return _name; } const char *getName() const noexcept { return _name; }
virtual upx_off_t seek(upx_off_t off, int whence); virtual upx_off_t seek(upx_off_t off, int whence);
upx_off_t tell() const; upx_off_t tell() const;
@@ -50,9 +50,10 @@ public:
public: public:
// static file-related util functions; will throw on error // static file-related util functions; will throw on error
static void chmod(const char *name, int mode); static void chmod(const char *name, int mode) may_throw;
static void rename(const char *old_, const char *new_); static void rename(const char *old_, const char *new_) may_throw;
static void unlink(const char *name); static void unlink(const char *name) may_throw;
static bool unlink_noexcept(const char *name) noexcept;
protected: protected:
bool do_sopen(); bool do_sopen();
+1 -1
View File
@@ -96,7 +96,7 @@ private:
// This class is private to Filter - don't look. // This class is private to Filter - don't look.
**************************************************************************/ **************************************************************************/
class FilterImpl { class FilterImpl final {
friend class Filter; friend class Filter;
private: private:
+157 -276
View File
@@ -25,434 +25,325 @@
<markus@oberhumer.com> <ezerotven+github@gmail.com> <markus@oberhumer.com> <ezerotven+github@gmail.com>
*/ */
/************************************************************************* /*************************************************************************
// 16-bit calltrick ("naive") // 16-bit calltrick ("naive")
**************************************************************************/ **************************************************************************/
#define CT16(f, cond, addvalue, get, set) \ #define CT16(f, cond, addvalue, get, set) \
byte *b = f->buf; \ byte *b = f->buf; \
byte *b_end = b + f->buf_len - 3; \ byte *b_end = b + f->buf_len - 3; \
do { \ do { \
if (cond) \ if (cond) { \
{ \ b += 1; \
b += 1; \ unsigned a = (unsigned) (b - f->buf); \
unsigned a = (unsigned) (b - f->buf); \ f->lastcall = a; \
f->lastcall = a; \ set(b, get(b) + (addvalue)); \
set(b, get(b) + (addvalue)); \ f->calls++; \
f->calls++; \ b += 2 - 1; \
b += 2 - 1; \ } \
} \ } while (++b < b_end); \
} while (++b < b_end); \ if (f->lastcall) \
if (f->lastcall) f->lastcall += 2; \ f->lastcall += 2; \
return 0; return 0;
// filter: e8, e9, e8e9 // filter: e8, e9, e8e9
static int f_ct16_e8(Filter *f) static int f_ct16_e8(Filter *f) { CT16(f, (*b == 0xe8), a + f->addvalue, get_le16, set_le16) }
{
CT16(f, (*b == 0xe8), a + f->addvalue, get_le16, set_le16)
}
static int f_ct16_e9(Filter *f) static int f_ct16_e9(Filter *f) { CT16(f, (*b == 0xe9), a + f->addvalue, get_le16, set_le16) }
{
CT16(f, (*b == 0xe9), a + f->addvalue, get_le16, set_le16)
}
static int f_ct16_e8e9(Filter *f) static int f_ct16_e8e9(Filter *f) {
{
CT16(f, (*b == 0xe8 || *b == 0xe9), a + f->addvalue, get_le16, set_le16) CT16(f, (*b == 0xe8 || *b == 0xe9), a + f->addvalue, get_le16, set_le16)
} }
// unfilter: e8, e9, e8e9 // unfilter: e8, e9, e8e9
static int u_ct16_e8(Filter *f) static int u_ct16_e8(Filter *f) { CT16(f, (*b == 0xe8), 0 - a - f->addvalue, get_le16, set_le16) }
{
CT16(f, (*b == 0xe8), 0 - a - f->addvalue, get_le16, set_le16)
}
static int u_ct16_e9(Filter *f) static int u_ct16_e9(Filter *f) { CT16(f, (*b == 0xe9), 0 - a - f->addvalue, get_le16, set_le16) }
{
CT16(f, (*b == 0xe9), 0 - a - f->addvalue, get_le16, set_le16)
}
static int u_ct16_e8e9(Filter *f) static int u_ct16_e8e9(Filter *f) {
{
CT16(f, (*b == 0xe8 || *b == 0xe9), 0 - a - f->addvalue, get_le16, set_le16) CT16(f, (*b == 0xe8 || *b == 0xe9), 0 - a - f->addvalue, get_le16, set_le16)
} }
// scan: e8, e9, e8e9 // scan: e8, e9, e8e9
static int s_ct16_e8(Filter *f) static int s_ct16_e8(Filter *f) { CT16(f, (*b == 0xe8), a + f->addvalue, get_le16, set_dummy) }
{
CT16(f, (*b == 0xe8), a + f->addvalue, get_le16, set_dummy)
}
static int s_ct16_e9(Filter *f) static int s_ct16_e9(Filter *f) { CT16(f, (*b == 0xe9), a + f->addvalue, get_le16, set_dummy) }
{
CT16(f, (*b == 0xe9), a + f->addvalue, get_le16, set_dummy)
}
static int s_ct16_e8e9(Filter *f) static int s_ct16_e8e9(Filter *f) {
{
CT16(f, (*b == 0xe8 || *b == 0xe9), a + f->addvalue, get_le16, set_dummy) CT16(f, (*b == 0xe8 || *b == 0xe9), a + f->addvalue, get_le16, set_dummy)
} }
// filter: e8, e9, e8e9 with bswap le->be // filter: e8, e9, e8e9 with bswap le->be
static int f_ct16_e8_bswap_le(Filter *f) static int f_ct16_e8_bswap_le(Filter *f) {
{
CT16(f, (*b == 0xe8), a + f->addvalue, get_le16, set_be16) CT16(f, (*b == 0xe8), a + f->addvalue, get_le16, set_be16)
} }
static int f_ct16_e9_bswap_le(Filter *f) static int f_ct16_e9_bswap_le(Filter *f) {
{
CT16(f, (*b == 0xe9), a + f->addvalue, get_le16, set_be16) CT16(f, (*b == 0xe9), a + f->addvalue, get_le16, set_be16)
} }
static int f_ct16_e8e9_bswap_le(Filter *f) static int f_ct16_e8e9_bswap_le(Filter *f) {
{
CT16(f, (*b == 0xe8 || *b == 0xe9), a + f->addvalue, get_le16, set_be16) CT16(f, (*b == 0xe8 || *b == 0xe9), a + f->addvalue, get_le16, set_be16)
} }
// unfilter: e8, e9, e8e9 with bswap le->be // unfilter: e8, e9, e8e9 with bswap le->be
static int u_ct16_e8_bswap_le(Filter *f) static int u_ct16_e8_bswap_le(Filter *f) {
{
CT16(f, (*b == 0xe8), 0 - a - f->addvalue, get_be16, set_le16) CT16(f, (*b == 0xe8), 0 - a - f->addvalue, get_be16, set_le16)
} }
static int u_ct16_e9_bswap_le(Filter *f) static int u_ct16_e9_bswap_le(Filter *f) {
{
CT16(f, (*b == 0xe9), 0 - a - f->addvalue, get_be16, set_le16) CT16(f, (*b == 0xe9), 0 - a - f->addvalue, get_be16, set_le16)
} }
static int u_ct16_e8e9_bswap_le(Filter *f) static int u_ct16_e8e9_bswap_le(Filter *f) {
{
CT16(f, (*b == 0xe8 || *b == 0xe9), 0 - a - f->addvalue, get_be16, set_le16) CT16(f, (*b == 0xe8 || *b == 0xe9), 0 - a - f->addvalue, get_be16, set_le16)
} }
// scan: e8, e9, e8e9 with bswap le->be // scan: e8, e9, e8e9 with bswap le->be
static int s_ct16_e8_bswap_le(Filter *f) static int s_ct16_e8_bswap_le(Filter *f) {
{
CT16(f, (*b == 0xe8), a + f->addvalue, get_be16, set_dummy) CT16(f, (*b == 0xe8), a + f->addvalue, get_be16, set_dummy)
} }
static int s_ct16_e9_bswap_le(Filter *f) static int s_ct16_e9_bswap_le(Filter *f) {
{
CT16(f, (*b == 0xe9), a + f->addvalue, get_be16, set_dummy) CT16(f, (*b == 0xe9), a + f->addvalue, get_be16, set_dummy)
} }
static int s_ct16_e8e9_bswap_le(Filter *f) static int s_ct16_e8e9_bswap_le(Filter *f) {
{
CT16(f, (*b == 0xe8 || *b == 0xe9), a + f->addvalue, get_be16, set_dummy) CT16(f, (*b == 0xe8 || *b == 0xe9), a + f->addvalue, get_be16, set_dummy)
} }
// filter: e8, e9, e8e9 with bswap be->le // filter: e8, e9, e8e9 with bswap be->le
static int f_ct16_e8_bswap_be(Filter *f) static int f_ct16_e8_bswap_be(Filter *f) {
{
CT16(f, (*b == 0xe8), a + f->addvalue, get_be16, set_le16) CT16(f, (*b == 0xe8), a + f->addvalue, get_be16, set_le16)
} }
static int f_ct16_e9_bswap_be(Filter *f) static int f_ct16_e9_bswap_be(Filter *f) {
{
CT16(f, (*b == 0xe9), a + f->addvalue, get_be16, set_le16) CT16(f, (*b == 0xe9), a + f->addvalue, get_be16, set_le16)
} }
static int f_ct16_e8e9_bswap_be(Filter *f) static int f_ct16_e8e9_bswap_be(Filter *f) {
{
CT16(f, (*b == 0xe8 || *b == 0xe9), a + f->addvalue, get_be16, set_le16) CT16(f, (*b == 0xe8 || *b == 0xe9), a + f->addvalue, get_be16, set_le16)
} }
// unfilter: e8, e9, e8e9 with bswap be->le // unfilter: e8, e9, e8e9 with bswap be->le
static int u_ct16_e8_bswap_be(Filter *f) static int u_ct16_e8_bswap_be(Filter *f) {
{
CT16(f, (*b == 0xe8), 0 - a - f->addvalue, get_le16, set_be16) CT16(f, (*b == 0xe8), 0 - a - f->addvalue, get_le16, set_be16)
} }
static int u_ct16_e9_bswap_be(Filter *f) static int u_ct16_e9_bswap_be(Filter *f) {
{
CT16(f, (*b == 0xe9), 0 - a - f->addvalue, get_le16, set_be16) CT16(f, (*b == 0xe9), 0 - a - f->addvalue, get_le16, set_be16)
} }
static int u_ct16_e8e9_bswap_be(Filter *f) static int u_ct16_e8e9_bswap_be(Filter *f) {
{
CT16(f, (*b == 0xe8 || *b == 0xe9), 0 - a - f->addvalue, get_le16, set_be16) CT16(f, (*b == 0xe8 || *b == 0xe9), 0 - a - f->addvalue, get_le16, set_be16)
} }
// scan: e8, e9, e8e9 with bswap be->le // scan: e8, e9, e8e9 with bswap be->le
static int s_ct16_e8_bswap_be(Filter *f) static int s_ct16_e8_bswap_be(Filter *f) {
{
CT16(f, (*b == 0xe8), a + f->addvalue, get_le16, set_dummy) CT16(f, (*b == 0xe8), a + f->addvalue, get_le16, set_dummy)
} }
static int s_ct16_e9_bswap_be(Filter *f) static int s_ct16_e9_bswap_be(Filter *f) {
{
CT16(f, (*b == 0xe9), a + f->addvalue, get_le16, set_dummy) CT16(f, (*b == 0xe9), a + f->addvalue, get_le16, set_dummy)
} }
static int s_ct16_e8e9_bswap_be(Filter *f) static int s_ct16_e8e9_bswap_be(Filter *f) {
{
CT16(f, (*b == 0xe8 || *b == 0xe9), a + f->addvalue, get_le16, set_dummy) CT16(f, (*b == 0xe8 || *b == 0xe9), a + f->addvalue, get_le16, set_dummy)
} }
#undef CT16 #undef CT16
/************************************************************************* /*************************************************************************
// 32-bit calltrick ("naive") // 32-bit calltrick ("naive")
**************************************************************************/ **************************************************************************/
#define CT32(f, cond, addvalue, get, set) \ #define CT32(f, cond, addvalue, get, set) \
byte *b = f->buf; \ byte *b = f->buf; \
byte *b_end = b + f->buf_len - 5; \ byte *b_end = b + f->buf_len - 5; \
do { \ do { \
if (cond) \ if (cond) { \
{ \ b += 1; \
b += 1; \ unsigned a = (unsigned) (b - f->buf); \
unsigned a = (unsigned) (b - f->buf); \ f->lastcall = a; \
f->lastcall = a; \ set(b, get(b) + (addvalue)); \
set(b, get(b) + (addvalue)); \ f->calls++; \
f->calls++; \ b += 4 - 1; \
b += 4 - 1; \ } \
} \ } while (++b < b_end); \
} while (++b < b_end); \ if (f->lastcall) \
if (f->lastcall) f->lastcall += 4; \ f->lastcall += 4; \
return 0; return 0;
// filter: e8, e9, e8e9 // filter: e8, e9, e8e9
static int f_ct32_e8(Filter *f) static int f_ct32_e8(Filter *f) { CT32(f, (*b == 0xe8), a + f->addvalue, get_le32, set_le32) }
{
CT32(f, (*b == 0xe8), a + f->addvalue, get_le32, set_le32)
}
static int f_ct32_e9(Filter *f) static int f_ct32_e9(Filter *f) { CT32(f, (*b == 0xe9), a + f->addvalue, get_le32, set_le32) }
{
CT32(f, (*b == 0xe9), a + f->addvalue, get_le32, set_le32)
}
static int f_ct32_e8e9(Filter *f) static int f_ct32_e8e9(Filter *f) {
{
CT32(f, (*b == 0xe8 || *b == 0xe9), a + f->addvalue, get_le32, set_le32) CT32(f, (*b == 0xe8 || *b == 0xe9), a + f->addvalue, get_le32, set_le32)
} }
// unfilter: e8, e9, e8e9 // unfilter: e8, e9, e8e9
static int u_ct32_e8(Filter *f) static int u_ct32_e8(Filter *f) { CT32(f, (*b == 0xe8), 0 - a - f->addvalue, get_le32, set_le32) }
{
CT32(f, (*b == 0xe8), 0 - a - f->addvalue, get_le32, set_le32)
}
static int u_ct32_e9(Filter *f) static int u_ct32_e9(Filter *f) { CT32(f, (*b == 0xe9), 0 - a - f->addvalue, get_le32, set_le32) }
{
CT32(f, (*b == 0xe9), 0 - a - f->addvalue, get_le32, set_le32)
}
static int u_ct32_e8e9(Filter *f) static int u_ct32_e8e9(Filter *f) {
{
CT32(f, (*b == 0xe8 || *b == 0xe9), 0 - a - f->addvalue, get_le32, set_le32) CT32(f, (*b == 0xe8 || *b == 0xe9), 0 - a - f->addvalue, get_le32, set_le32)
} }
// scan: e8, e9, e8e9 // scan: e8, e9, e8e9
static int s_ct32_e8(Filter *f) static int s_ct32_e8(Filter *f) { CT32(f, (*b == 0xe8), a + f->addvalue, get_le32, set_dummy) }
{
CT32(f, (*b == 0xe8), a + f->addvalue, get_le32, set_dummy)
}
static int s_ct32_e9(Filter *f) static int s_ct32_e9(Filter *f) { CT32(f, (*b == 0xe9), a + f->addvalue, get_le32, set_dummy) }
{
CT32(f, (*b == 0xe9), a + f->addvalue, get_le32, set_dummy)
}
static int s_ct32_e8e9(Filter *f) static int s_ct32_e8e9(Filter *f) {
{
CT32(f, (*b == 0xe8 || *b == 0xe9), a + f->addvalue, get_le32, set_dummy) CT32(f, (*b == 0xe8 || *b == 0xe9), a + f->addvalue, get_le32, set_dummy)
} }
// filter: e8, e9, e8e9 with bswap le->be // filter: e8, e9, e8e9 with bswap le->be
static int f_ct32_e8_bswap_le(Filter *f) static int f_ct32_e8_bswap_le(Filter *f) {
{
CT32(f, (*b == 0xe8), a + f->addvalue, get_le32, set_be32) CT32(f, (*b == 0xe8), a + f->addvalue, get_le32, set_be32)
} }
static int f_ct32_e9_bswap_le(Filter *f) static int f_ct32_e9_bswap_le(Filter *f) {
{
CT32(f, (*b == 0xe9), a + f->addvalue, get_le32, set_be32) CT32(f, (*b == 0xe9), a + f->addvalue, get_le32, set_be32)
} }
static int f_ct32_e8e9_bswap_le(Filter *f) static int f_ct32_e8e9_bswap_le(Filter *f) {
{
CT32(f, (*b == 0xe8 || *b == 0xe9), a + f->addvalue, get_le32, set_be32) CT32(f, (*b == 0xe8 || *b == 0xe9), a + f->addvalue, get_le32, set_be32)
} }
// unfilter: e8, e9, e8e9 with bswap le->be // unfilter: e8, e9, e8e9 with bswap le->be
static int u_ct32_e8_bswap_le(Filter *f) static int u_ct32_e8_bswap_le(Filter *f) {
{
CT32(f, (*b == 0xe8), 0 - a - f->addvalue, get_be32, set_le32) CT32(f, (*b == 0xe8), 0 - a - f->addvalue, get_be32, set_le32)
} }
static int u_ct32_e9_bswap_le(Filter *f) static int u_ct32_e9_bswap_le(Filter *f) {
{
CT32(f, (*b == 0xe9), 0 - a - f->addvalue, get_be32, set_le32) CT32(f, (*b == 0xe9), 0 - a - f->addvalue, get_be32, set_le32)
} }
static int u_ct32_e8e9_bswap_le(Filter *f) static int u_ct32_e8e9_bswap_le(Filter *f) {
{
CT32(f, (*b == 0xe8 || *b == 0xe9), 0 - a - f->addvalue, get_be32, set_le32) CT32(f, (*b == 0xe8 || *b == 0xe9), 0 - a - f->addvalue, get_be32, set_le32)
} }
// scan: e8, e9, e8e9 with bswap le->be // scan: e8, e9, e8e9 with bswap le->be
static int s_ct32_e8_bswap_le(Filter *f) static int s_ct32_e8_bswap_le(Filter *f) {
{
CT32(f, (*b == 0xe8), a + f->addvalue, get_be32, set_dummy) CT32(f, (*b == 0xe8), a + f->addvalue, get_be32, set_dummy)
} }
static int s_ct32_e9_bswap_le(Filter *f) static int s_ct32_e9_bswap_le(Filter *f) {
{
CT32(f, (*b == 0xe9), a + f->addvalue, get_be32, set_dummy) CT32(f, (*b == 0xe9), a + f->addvalue, get_be32, set_dummy)
} }
static int s_ct32_e8e9_bswap_le(Filter *f) static int s_ct32_e8e9_bswap_le(Filter *f) {
{
CT32(f, (*b == 0xe8 || *b == 0xe9), a + f->addvalue, get_be32, set_dummy) CT32(f, (*b == 0xe8 || *b == 0xe9), a + f->addvalue, get_be32, set_dummy)
} }
// filter: e8, e9, e8e9 with bswap be->le // filter: e8, e9, e8e9 with bswap be->le
static int f_ct32_e8_bswap_be(Filter *f) static int f_ct32_e8_bswap_be(Filter *f) {
{
CT32(f, (*b == 0xe8), a + f->addvalue, get_be32, set_le32) CT32(f, (*b == 0xe8), a + f->addvalue, get_be32, set_le32)
} }
static int f_ct32_e9_bswap_be(Filter *f) static int f_ct32_e9_bswap_be(Filter *f) {
{
CT32(f, (*b == 0xe9), a + f->addvalue, get_be32, set_le32) CT32(f, (*b == 0xe9), a + f->addvalue, get_be32, set_le32)
} }
static int f_ct32_e8e9_bswap_be(Filter *f) static int f_ct32_e8e9_bswap_be(Filter *f) {
{
CT32(f, (*b == 0xe8 || *b == 0xe9), a + f->addvalue, get_be32, set_le32) CT32(f, (*b == 0xe8 || *b == 0xe9), a + f->addvalue, get_be32, set_le32)
} }
// unfilter: e8, e9, e8e9 with bswap be->le // unfilter: e8, e9, e8e9 with bswap be->le
static int u_ct32_e8_bswap_be(Filter *f) static int u_ct32_e8_bswap_be(Filter *f) {
{
CT32(f, (*b == 0xe8), 0 - a - f->addvalue, get_le32, set_be32) CT32(f, (*b == 0xe8), 0 - a - f->addvalue, get_le32, set_be32)
} }
static int u_ct32_e9_bswap_be(Filter *f) static int u_ct32_e9_bswap_be(Filter *f) {
{
CT32(f, (*b == 0xe9), 0 - a - f->addvalue, get_le32, set_be32) CT32(f, (*b == 0xe9), 0 - a - f->addvalue, get_le32, set_be32)
} }
static int u_ct32_e8e9_bswap_be(Filter *f) static int u_ct32_e8e9_bswap_be(Filter *f) {
{
CT32(f, (*b == 0xe8 || *b == 0xe9), 0 - a - f->addvalue, get_le32, set_be32) CT32(f, (*b == 0xe8 || *b == 0xe9), 0 - a - f->addvalue, get_le32, set_be32)
} }
// scan: e8, e9, e8e9 with bswap be->le // scan: e8, e9, e8e9 with bswap be->le
static int s_ct32_e8_bswap_be(Filter *f) static int s_ct32_e8_bswap_be(Filter *f) {
{
CT32(f, (*b == 0xe8), a + f->addvalue, get_le32, set_dummy) CT32(f, (*b == 0xe8), a + f->addvalue, get_le32, set_dummy)
} }
static int s_ct32_e9_bswap_be(Filter *f) static int s_ct32_e9_bswap_be(Filter *f) {
{
CT32(f, (*b == 0xe9), a + f->addvalue, get_le32, set_dummy) CT32(f, (*b == 0xe9), a + f->addvalue, get_le32, set_dummy)
} }
static int s_ct32_e8e9_bswap_be(Filter *f) static int s_ct32_e8e9_bswap_be(Filter *f) {
{
CT32(f, (*b == 0xe8 || *b == 0xe9), a + f->addvalue, get_le32, set_dummy) CT32(f, (*b == 0xe8 || *b == 0xe9), a + f->addvalue, get_le32, set_dummy)
} }
#undef CT32 #undef CT32
/************************************************************************* /*************************************************************************
// 24-bit ARM calltrick ("naive") // 24-bit ARM calltrick ("naive")
**************************************************************************/ **************************************************************************/
#define CT24ARM_LE(f, cond, addvalue, get, set) \ #define CT24ARM_LE(f, cond, addvalue, get, set) \
byte *b = f->buf; \ byte *b = f->buf; \
byte *b_end = b + f->buf_len - 4; \ byte *b_end = b + f->buf_len - 4; \
do { \ do { \
if (cond) \ if (cond) { \
{ \ unsigned a = (unsigned) (b - f->buf); \
unsigned a = (unsigned) (b - f->buf); \ f->lastcall = a; \
f->lastcall = a; \ set(b, get(b) + (addvalue)); \
set(b, get(b) + (addvalue)); \ f->calls++; \
f->calls++; \ } \
} \ b += 4; \
b += 4; \ } while (b < b_end); \
} while (b < b_end); \ if (f->lastcall) \
if (f->lastcall) f->lastcall += 4; \ f->lastcall += 4; \
return 0; return 0;
#define ARMCT_COND_le (((b[3] & 0x0f) == 0x0b)) #define ARMCT_COND_le (((b[3] & 0x0f) == 0x0b))
static int f_ct24arm_le(Filter *f) static int f_ct24arm_le(Filter *f) {
{
CT24ARM_LE(f, ARMCT_COND_le, a / 4 + f->addvalue, get_le24, set_le24) CT24ARM_LE(f, ARMCT_COND_le, a / 4 + f->addvalue, get_le24, set_le24)
} }
static int u_ct24arm_le(Filter *f) static int u_ct24arm_le(Filter *f) {
{
CT24ARM_LE(f, ARMCT_COND_le, 0 - a / 4 - f->addvalue, get_le24, set_le24) CT24ARM_LE(f, ARMCT_COND_le, 0 - a / 4 - f->addvalue, get_le24, set_le24)
} }
static int s_ct24arm_le(Filter *f) static int s_ct24arm_le(Filter *f) {
{
CT24ARM_LE(f, ARMCT_COND_le, a + f->addvalue, get_le24, set_dummy) CT24ARM_LE(f, ARMCT_COND_le, a + f->addvalue, get_le24, set_dummy)
} }
#undef CT24ARM_LE #undef CT24ARM_LE
#define CT24ARM_BE(f, cond, addvalue, get, set) \ #define CT24ARM_BE(f, cond, addvalue, get, set) \
byte *b = f->buf; \ byte *b = f->buf; \
byte *b_end = b + f->buf_len - 4; \ byte *b_end = b + f->buf_len - 4; \
do { \ do { \
if (cond) \ if (cond) { \
{ \ unsigned a = (unsigned) (b - f->buf); \
unsigned a = (unsigned) (b - f->buf); \ f->lastcall = a; \
f->lastcall = a; \ set(1 + b, get(1 + b) + (addvalue)); \
set(1+b, get(1+b) + (addvalue)); \ f->calls++; \
f->calls++; \ } \
} \ b += 4; \
b += 4; \ } while (b < b_end); \
} while (b < b_end); \ if (f->lastcall) \
if (f->lastcall) f->lastcall += 4; \ f->lastcall += 4; \
return 0; return 0;
#define ARMCT_COND_be (((b[0] & 0x0f) == 0x0b)) #define ARMCT_COND_be (((b[0] & 0x0f) == 0x0b))
static int f_ct24arm_be(Filter *f) static int f_ct24arm_be(Filter *f) {
{
CT24ARM_BE(f, ARMCT_COND_be, a / 4 + f->addvalue, get_be24, set_be24) CT24ARM_BE(f, ARMCT_COND_be, a / 4 + f->addvalue, get_be24, set_be24)
} }
static int u_ct24arm_be(Filter *f) static int u_ct24arm_be(Filter *f) {
{
CT24ARM_BE(f, ARMCT_COND_be, 0 - a / 4 - f->addvalue, get_be24, set_be24) CT24ARM_BE(f, ARMCT_COND_be, 0 - a / 4 - f->addvalue, get_be24, set_be24)
} }
static int s_ct24arm_be(Filter *f) static int s_ct24arm_be(Filter *f) {
{
CT24ARM_BE(f, ARMCT_COND_be, a + f->addvalue, get_be24, set_dummy) CT24ARM_BE(f, ARMCT_COND_be, a + f->addvalue, get_be24, set_dummy)
} }
@@ -463,89 +354,79 @@ static int s_ct24arm_be(Filter *f)
// 26-bit ARM calltrick ("naive") // 26-bit ARM calltrick ("naive")
**************************************************************************/ **************************************************************************/
#if 1 //{ old reliable #if 1 //{ old reliable
#define CT26ARM_LE(f, cond, addvalue, get, set) \ #define CT26ARM_LE(f, cond, addvalue, get, set) \
byte *b = f->buf; \ byte *b = f->buf; \
byte *b_end = b + f->buf_len - 4; \ byte *b_end = b + f->buf_len - 4; \
do { \ do { \
if (cond) \ if (cond) { \
{ \ unsigned a = (unsigned) (b - f->buf); \
unsigned a = (unsigned) (b - f->buf); \ f->lastcall = a; \
f->lastcall = a; \ set(b, get(b) + (addvalue)); \
set(b, get(b) + (addvalue)); \ f->calls++; \
f->calls++; \ } \
} \ b += 4; \
b += 4; \ } while (b < b_end); \
} while (b < b_end); \ if (f->lastcall) \
if (f->lastcall) f->lastcall += 4; \ f->lastcall += 4; \
return 0; return 0;
#define ARMCT_COND (((b[3] & 0x7C) == 0x14)) #define ARMCT_COND (((b[3] & 0x7C) == 0x14))
static int f_ct26arm_le(Filter *f) static int f_ct26arm_le(Filter *f) {
{
CT26ARM_LE(f, ARMCT_COND, a / 4 + f->addvalue, get_le26, set_le26) CT26ARM_LE(f, ARMCT_COND, a / 4 + f->addvalue, get_le26, set_le26)
} }
static int u_ct26arm_le(Filter *f) static int u_ct26arm_le(Filter *f) {
{
CT26ARM_LE(f, ARMCT_COND, 0 - a / 4 - f->addvalue, get_le26, set_le26) CT26ARM_LE(f, ARMCT_COND, 0 - a / 4 - f->addvalue, get_le26, set_le26)
} }
static int s_ct26arm_le(Filter *f) static int s_ct26arm_le(Filter *f) {
{
CT26ARM_LE(f, ARMCT_COND, a + f->addvalue, get_le26, set_dummy) CT26ARM_LE(f, ARMCT_COND, a + f->addvalue, get_le26, set_dummy)
} }
#else //}{ new enhanced but DIFFERENT; need new filter type! #else //}{ new enhanced but DIFFERENT; need new filter type!
static int CTarm64(Filter *f, int dir) // dir: 1, 0, -1 static int CTarm64(Filter *f, int dir) // dir: 1, 0, -1
{ {
upx_byte *b = f->buf; // will be incremented upx_byte *b = f->buf; // will be incremented
upx_byte *const b_end = b + f->buf_len - 4; upx_byte *const b_end = b + f->buf_len - 4;
do { do {
unsigned const a = b - f->buf; unsigned const a = b - f->buf;
int const d = dir * (f->addvalue + (a >> 2)); int const d = dir * (f->addvalue + (a >> 2));
unsigned const v = get_le32(f->buf); // the 32-bit instruction unsigned const v = get_le32(f->buf); // the 32-bit instruction
if (0x05 == (0x1f & (v >> 26))) { // b, bl if (0x05 == (0x1f & (v >> 26))) { // b, bl
f->lastcall = a; f->lastcall = a;
if (dir) set_le26(b, v + d); if (dir)
set_le26(b, v + d);
f->calls++; f->calls++;
} } else if ((0x54 == (v >> 24)) // b.cond
else if ( (0x54 == (v >> 24) ) // b.cond || (0x1a == ((v >> 25) & 0x3f)) // cb{z,nz}
|| (0x1a == ((v >> 25) & 0x3f)) // cb{z,nz} ) {
) {
f->lastcall = a; f->lastcall = a;
if (dir) set_le19_5(b, (v >> 5) + d); if (dir)
set_le19_5(b, (v >> 5) + d);
f->calls++; f->calls++;
} } else if (0x1b == ((v >> 25) & 0x3f)) { // tb{z,nz}
else if (0x1b == ((v >> 25) & 0x3f)) { // tb{z,nz}
f->lastcall = a; f->lastcall = a;
if (dir) set_le14_5(b, (v >> 5) + d); if (dir)
set_le14_5(b, (v >> 5) + d);
f->calls++; f->calls++;
} }
b += 4; b += 4;
} while (b < b_end); } while (b < b_end);
if (f->lastcall) f->lastcall += 4; if (f->lastcall)
f->lastcall += 4;
return 0; return 0;
} }
static int f_CTarm64_le(Filter *f) static int f_CTarm64_le(Filter *f) { return CTarm64(f, 1); }
{
return CTarm64(f, 1);
}
static int u_CTarm64_le(Filter *f) static int u_CTarm64_le(Filter *f) { return CTarm64(f, -1); }
{
return CTarm64(f, -1);
}
static int s_CTarm64_le(Filter *f) static int s_CTarm64_le(Filter *f) { return CTarm64(f, 0); }
{
return CTarm64(f, 0);
}
#endif //} #endif //}
#undef CT26ARM_LE #undef CT26ARM_LE
#undef ARMCT_COND #undef ARMCT_COND
+31 -49
View File
@@ -25,14 +25,11 @@
<markus@oberhumer.com> <ezerotven+github@gmail.com> <markus@oberhumer.com> <ezerotven+github@gmail.com>
*/ */
/************************************************************************* /*************************************************************************
// filter / scan // filter / scan
**************************************************************************/ **************************************************************************/
static int F(Filter *f) static int F(Filter *f) {
{
#ifdef U #ifdef U
// filter // filter
byte *b = f->buf; byte *b = f->buf;
@@ -50,25 +47,22 @@ static int F(Filter *f)
// find a 16 MiB large empty address space // find a 16 MiB large empty address space
{ {
unsigned char buf[256]; unsigned char buf[256];
memset(buf,0,256); memset(buf, 0, 256);
// A call to a destination that is inside the buffer // A call to a destination that is inside the buffer
// will be rewritten and marked with cto8 as first byte. // will be rewritten and marked with cto8 as first byte.
// So, a call to a destination that is outside the buffer // So, a call to a destination that is outside the buffer
// must not conflict with the mark. // must not conflict with the mark.
// Note that unsigned comparison checks both edges of buffer. // Note that unsigned comparison checks both edges of buffer.
for (ic = 0; ic < size - 5; ic++) for (ic = 0; ic < size - 5; ic++) {
{ if (!COND(b, ic))
if (!COND(b,ic))
continue; continue;
jc = get_le32(b+ic+1)+ic+1; jc = get_le32(b + ic + 1) + ic + 1;
if (jc < size) if (jc < size) {
{
if (jc + addvalue >= (1u << 24)) // hi 8 bits won't be cto8 if (jc + addvalue >= (1u << 24)) // hi 8 bits won't be cto8
return -1; return -1;
} } else
else buf[b[ic + 1]] |= 1;
buf[b[ic+1]] |= 1;
} }
if (getcto(f, buf) < 0) if (getcto(f, buf) < 0)
@@ -76,35 +70,31 @@ static int F(Filter *f)
} }
const unsigned char cto8 = f->cto; const unsigned char cto8 = f->cto;
#ifdef U #ifdef U
const unsigned cto = (unsigned)f->cto << 24; const unsigned cto = (unsigned) f->cto << 24;
#endif #endif
for (ic = 0; ic < size - 5; ic++) for (ic = 0; ic < size - 5; ic++) {
{ if (!COND(b, ic))
if (!COND(b,ic))
continue; continue;
jc = get_le32(b+ic+1)+ic+1; jc = get_le32(b + ic + 1) + ic + 1;
// try to detect 'real' calls only // try to detect 'real' calls only
if (jc < size) if (jc < size) {
{
assert(jc + addvalue < (1u << 24)); // hi 8 bits won't be cto8 assert(jc + addvalue < (1u << 24)); // hi 8 bits won't be cto8
#ifdef U #ifdef U
set_be32(b+ic+1,jc+addvalue+cto); set_be32(b + ic + 1, jc + addvalue + cto);
#endif #endif
if (ic - lastnoncall < 5) if (ic - lastnoncall < 5) {
{
// check the last 4 bytes before this call // check the last 4 bytes before this call
for (kc = 4; kc; kc--) for (kc = 4; kc; kc--)
if (COND(b,ic-kc) && b[ic-kc+1] == cto8) if (COND(b, ic - kc) && b[ic - kc + 1] == cto8)
break; break;
if (kc) if (kc) {
{
#ifdef U #ifdef U
// restore original // restore original
set_le32(b+ic+1,jc-ic-1); set_le32(b + ic + 1, jc - ic - 1);
#endif #endif
if (b[ic+1] == cto8) if (b[ic + 1] == cto8)
return 1; // fail - buffer not restored return 1; // fail - buffer not restored
lastnoncall = ic; lastnoncall = ic;
noncalls2++; noncalls2++;
continue; continue;
@@ -112,11 +102,9 @@ static int F(Filter *f)
} }
calls++; calls++;
ic += 4; ic += 4;
lastcall = ic+1; lastcall = ic + 1;
} } else {
else assert(b[ic + 1] != cto8); // this should not happen
{
assert(b[ic+1] != cto8); // this should not happen
lastnoncall = ic; lastnoncall = ic;
noncalls++; noncalls++;
} }
@@ -133,40 +121,34 @@ static int F(Filter *f)
return 0; return 0;
} }
/************************************************************************* /*************************************************************************
// unfilter // unfilter
**************************************************************************/ **************************************************************************/
#ifdef U #ifdef U
static int U(Filter *f) static int U(Filter *f) {
{
byte *b = f->buf; byte *b = f->buf;
const unsigned size5 = f->buf_len - 5; const unsigned size5 = f->buf_len - 5;
const unsigned addvalue = f->addvalue; const unsigned addvalue = f->addvalue;
const unsigned cto = (unsigned)f->cto << 24; const unsigned cto = (unsigned) f->cto << 24;
unsigned ic, jc; unsigned ic, jc;
for (ic = 0; ic < size5; ic++) for (ic = 0; ic < size5; ic++)
if (COND(b,ic)) if (COND(b, ic)) {
{ jc = get_be32(b + ic + 1);
jc = get_be32(b+ic+1); if (b[ic + 1] == f->cto) {
if (b[ic+1] == f->cto) set_le32(b + ic + 1, jc - ic - 1 - addvalue - cto);
{
set_le32(b+ic+1,jc-ic-1-addvalue-cto);
f->calls++; f->calls++;
ic += 4; ic += 4;
f->lastcall = ic+1; f->lastcall = ic + 1;
} } else
else
f->noncalls++; f->noncalls++;
} }
return 0; return 0;
} }
#endif #endif
#undef F #undef F
#undef U #undef U
+32 -50
View File
@@ -29,14 +29,11 @@
<jreiser@users.sourceforge.net> <jreiser@users.sourceforge.net>
*/ */
/************************************************************************* /*************************************************************************
// filter / scan // filter / scan
**************************************************************************/ **************************************************************************/
static int F(Filter *f) static int F(Filter *f) {
{
#ifdef U #ifdef U
// filter // filter
byte *b = f->buf; byte *b = f->buf;
@@ -54,20 +51,17 @@ static int F(Filter *f)
// find a 16 MiB large empty address space // find a 16 MiB large empty address space
{ {
unsigned char buf[256]; unsigned char buf[256];
memset(buf,0,256); memset(buf, 0, 256);
for (ic = 0; ic < size - 5; ic++) for (ic = 0; ic < size - 5; ic++) {
{ if (!COND(b, ic, lastcall))
if (!COND(b,ic,lastcall))
continue; continue;
jc = get_le32(b+ic+1)+ic+1; jc = get_le32(b + ic + 1) + ic + 1;
if (jc < size) if (jc < size) {
{
if (jc + addvalue >= (1u << 24)) // hi 8 bits won't be cto8 if (jc + addvalue >= (1u << 24)) // hi 8 bits won't be cto8
return -1; return -1;
} } else
else buf[b[ic + 1]] |= 1;
buf[b[ic+1]] |= 1;
} }
if (getcto(f, buf) < 0) if (getcto(f, buf) < 0)
@@ -75,35 +69,31 @@ static int F(Filter *f)
} }
const unsigned char cto8 = f->cto; const unsigned char cto8 = f->cto;
#ifdef U #ifdef U
const unsigned cto = (unsigned)f->cto << 24; const unsigned cto = (unsigned) f->cto << 24;
#endif #endif
for (ic = 0; ic < size - 5; ic++) for (ic = 0; ic < size - 5; ic++) {
{ if (!COND(b, ic, lastcall))
if (!COND(b,ic,lastcall))
continue; continue;
jc = get_le32(b+ic+1)+ic+1; jc = get_le32(b + ic + 1) + ic + 1;
// try to detect 'real' calls only // try to detect 'real' calls only
if (jc < size) if (jc < size) {
{
assert(jc + addvalue < (1u << 24)); // hi 8 bits won't be cto8 assert(jc + addvalue < (1u << 24)); // hi 8 bits won't be cto8
#ifdef U #ifdef U
set_be32(b+ic+1,jc+addvalue+cto); set_be32(b + ic + 1, jc + addvalue + cto);
#endif #endif
if (ic - lastnoncall < 5) if (ic - lastnoncall < 5) {
{
// check the last 4 bytes before this call // check the last 4 bytes before this call
for (kc = 4; kc; kc--) for (kc = 4; kc; kc--)
if (COND(b,ic-kc,lastcall) && b[ic-kc+1] == cto8) if (COND(b, ic - kc, lastcall) && b[ic - kc + 1] == cto8)
break; break;
if (kc) if (kc) {
{
#ifdef U #ifdef U
// restore original // restore original
set_le32(b+ic+1,jc-ic-1); set_le32(b + ic + 1, jc - ic - 1);
#endif #endif
if (b[ic+1] == cto8) if (b[ic + 1] == cto8)
return 1; // fail - buffer not restored return 1; // fail - buffer not restored
lastnoncall = ic; lastnoncall = ic;
noncalls2++; noncalls2++;
continue; continue;
@@ -111,11 +101,9 @@ static int F(Filter *f)
} }
calls++; calls++;
ic += 4; ic += 4;
lastcall = ic+1; lastcall = ic + 1;
} } else {
else assert(b[ic + 1] != cto8); // this should not happen
{
assert(b[ic+1] != cto8); // this should not happen
lastnoncall = ic; lastnoncall = ic;
noncalls++; noncalls++;
} }
@@ -132,40 +120,34 @@ static int F(Filter *f)
return 0; return 0;
} }
/************************************************************************* /*************************************************************************
// unfilter // unfilter
**************************************************************************/ **************************************************************************/
#ifdef U #ifdef U
static int U(Filter *f) static int U(Filter *f) {
{
byte *b = f->buf; byte *b = f->buf;
const unsigned size5 = f->buf_len - 5; const unsigned size5 = f->buf_len - 5;
const unsigned addvalue = f->addvalue; const unsigned addvalue = f->addvalue;
const unsigned cto = (unsigned)f->cto << 24; const unsigned cto = (unsigned) f->cto << 24;
// unsigned lastcall = 0; // lastcall is not used in COND macro // unsigned lastcall = 0; // lastcall is not used in COND macro
unsigned ic, jc; unsigned ic, jc;
for (ic = 0; ic < size5; ic++) for (ic = 0; ic < size5; ic++)
if (COND(b,ic,lastcall)) if (COND(b, ic, lastcall)) {
{ jc = get_be32(b + ic + 1);
jc = get_be32(b+ic+1); if (b[ic + 1] == f->cto) {
if (b[ic+1] == f->cto) set_le32(b + ic + 1, jc - ic - 1 - addvalue - cto);
{
set_le32(b+ic+1,jc-ic-1-addvalue-cto);
f->calls++; f->calls++;
ic += 4; ic += 4;
f->lastcall = ic+1; f->lastcall = ic + 1;
} } else
else
f->noncalls++; f->noncalls++;
} }
return 0; return 0;
} }
#endif #endif
#undef F #undef F
#undef U #undef U
+109 -151
View File
@@ -29,61 +29,43 @@
<jreiser@users.sourceforge.net> <jreiser@users.sourceforge.net>
*/ */
#if (ACC_CC_MSC && (_MSC_VER >= 1000 && _MSC_VER < 1300)) #if (ACC_CC_MSC && (_MSC_VER >= 1000 && _MSC_VER < 1300))
# pragma warning(disable: 4702) // W4: unreachable code #pragma warning(disable : 4702) // W4: unreachable code
#endif #endif
/************************************************************************* /*************************************************************************
// filter / scan // filter / scan
**************************************************************************/ **************************************************************************/
#ifdef U //{ #ifdef U //{
#define NOFILT 0 // no filter #define NOFILT 0 // no filter
#define FNOMRU 1 // filter, but not using mru #define FNOMRU 1 // filter, but not using mru
#define MRUFLT 2 // mru filter #define MRUFLT 2 // mru filter
static unsigned static unsigned f80_call(Filter const *f) { return (1 + (0x0f & f->id)) % 3; }
f80_call(Filter const *f)
{
return (1+ (0x0f & f->id)) % 3;
}
static unsigned static unsigned f80_jmp1(Filter const *f) { return ((1 + (0x0f & f->id)) / 3) % 3; }
f80_jmp1(Filter const *f)
{
return ((1+ (0x0f & f->id)) / 3) % 3;
}
static unsigned static unsigned f80_jcc2(Filter const *f) { return f80_jmp1(f); }
f80_jcc2(Filter const *f)
{
return f80_jmp1(f);
}
#define N_MRU 32 // does not have to be a power of 2 #define N_MRU 32 // does not have to be a power of 2
// Adaptively remember recent destinations. // Adaptively remember recent destinations.
static void static void update_mru(const unsigned jc, // destination address
update_mru( const int kh, // mru[kh] is slot where found
const unsigned jc, // destination address unsigned mru[N_MRU], // circular buffer of most recent destinations
const int kh, // mru[kh] is slot where found int &hand, // mru[hand] is most recent destination
unsigned mru[N_MRU], // circular buffer of most recent destinations int &tail // mru[tail] is beyond oldest destination ("cold cache" startup)
int &hand, // mru[hand] is most recent destination ) {
int &tail // mru[tail] is beyond oldest destination ("cold cache" startup)
)
{
if (0 > --hand) { if (0 > --hand) {
hand = N_MRU -1; hand = N_MRU - 1;
} }
const unsigned t = mru[hand]; // entry which will be overwritten by jc const unsigned t = mru[hand]; // entry which will be overwritten by jc
if (0!=t) { // have seen at least N_MRU destinations if (0 != t) { // have seen at least N_MRU destinations
mru[kh] = t; mru[kh] = t;
} } else { // "cold cache": keep active region contiguous
else { // "cold cache": keep active region contiguous
if (0 > --tail) { if (0 > --tail) {
tail = N_MRU -1; tail = N_MRU - 1;
} }
const unsigned t2 = mru[tail]; const unsigned t2 = mru[tail];
mru[tail] = 0; mru[tail] = 0;
@@ -91,11 +73,9 @@ update_mru(
} }
mru[hand] = jc; mru[hand] = jc;
} }
#endif //} #endif //}
static int F(Filter *f) {
static int F(Filter *f)
{
#ifdef U #ifdef U
// filter // filter
byte *const b = f->buf; byte *const b = f->buf;
@@ -108,9 +88,10 @@ static int F(Filter *f)
unsigned ic, jc, kc; unsigned ic, jc, kc;
unsigned calls = 0, noncalls = 0, noncalls2 = 0; unsigned calls = 0, noncalls = 0, noncalls2 = 0;
unsigned lastnoncall = size, lastcall = 0; unsigned lastnoncall = size, lastcall = 0;
unsigned wtally[3]; memset(wtally, 0, sizeof(wtally)); unsigned wtally[3];
memset(wtally, 0, sizeof(wtally));
#ifdef U //{ #ifdef U //{
const unsigned f_call = f80_call(f); const unsigned f_call = f80_call(f);
const unsigned f_jmp1 = f80_jmp1(f); const unsigned f_jmp1 = f80_jmp1(f);
const unsigned f_jcc2 = f80_jcc2(f); const unsigned f_jcc2 = f80_jcc2(f);
@@ -118,22 +99,20 @@ static int F(Filter *f)
int hand = 0, tail = 0; int hand = 0, tail = 0;
unsigned mru[N_MRU]; unsigned mru[N_MRU];
memset(&mru[0], 0, sizeof(mru)); memset(&mru[0], 0, sizeof(mru));
assert(N_MRU<=256); assert(N_MRU <= 256);
f->n_mru = (MRUFLT==f_call || MRUFLT==f_jmp1 || MRUFLT==f_jcc2) ? f->n_mru = (MRUFLT == f_call || MRUFLT == f_jmp1 || MRUFLT == f_jcc2) ? N_MRU : 0;
N_MRU : 0; #endif //}
#endif //}
// FIXME: We must fit into 8 MiB because we steal one bit. // FIXME: We must fit into 8 MiB because we steal one bit.
// find a 16 MiB large empty address space // find a 16 MiB large empty address space
{ {
int which; int which;
unsigned char buf[256]; unsigned char buf[256];
memset(buf,0,256); memset(buf, 0, 256);
for (ic = 0; ic < size - 5; ic++) for (ic = 0; ic < size - 5; ic++)
if (CONDF(which,b,ic,lastcall) && get_le32(b+ic+1)+ic+1 >= size) if (CONDF(which, b, ic, lastcall) && get_le32(b + ic + 1) + ic + 1 >= size) {
{ buf[b[ic + 1]] |= 1;
buf[b[ic+1]] |= 1;
} }
UNUSED(which); UNUSED(which);
@@ -142,37 +121,33 @@ static int F(Filter *f)
} }
const unsigned char cto8 = f->cto; const unsigned char cto8 = f->cto;
#ifdef U #ifdef U
const unsigned cto = (unsigned)f->cto << 24; const unsigned cto = (unsigned) f->cto << 24;
#endif #endif
for (ic = 0; ic < size - 5; ic++) for (ic = 0; ic < size - 5; ic++) {
{
int which; int which;
int f_on = 0; int f_on = 0;
if (!CONDF(which,b,ic,lastcall)) if (!CONDF(which, b, ic, lastcall))
continue; continue;
++wtally[which]; ++wtally[which];
jc = get_le32(b+ic+1)+ic+1; jc = get_le32(b + ic + 1) + ic + 1;
// try to detect 'real' calls only // try to detect 'real' calls only
if (jc < size) if (jc < size) {
{
#ifdef U #ifdef U
if (2==which && NOFILT!=f_jcc2) { // 6-byte Jcc <disp32> if (2 == which && NOFILT != f_jcc2) { // 6-byte Jcc <disp32>
// Prefix 0x0f is constant, but opcode condition 0x80..0x8f // Prefix 0x0f is constant, but opcode condition 0x80..0x8f
// varies. Because we store the destination (or its mru index) // varies. Because we store the destination (or its mru index)
// in be32 big endian format, the low-addressed bytes // in be32 big endian format, the low-addressed bytes
// will tend to be constant. Swap prefix and opcode // will tend to be constant. Swap prefix and opcode
// so that constants are together for better compression. // so that constants are together for better compression.
unsigned char const t = unsigned char const t = b[ic - 1];
b[ic-1]; b[ic - 1] = b[ic];
b[ic-1] = b[ic]; b[ic] = t;
b[ic] = t;
} }
// FIXME [?]: Extend to 8 bytes if "ADD ESP, byte 4*n" follows CALL. // FIXME [?]: Extend to 8 bytes if "ADD ESP, byte 4*n" follows CALL.
// This will require two related cto's (consecutive, or otherwise). // This will require two related cto's (consecutive, or otherwise).
if ((0==which && MRUFLT==f_call) if ((0 == which && MRUFLT == f_call) || (1 == which && MRUFLT == f_jmp1) ||
|| (1==which && MRUFLT==f_jmp1) (2 == which && MRUFLT == f_jcc2)) {
|| (2==which && MRUFLT==f_jcc2) ) {
f_on = 1; f_on = 1;
// Recode the destination: narrower mru indices // Recode the destination: narrower mru indices
// should compress better than wider addresses. // should compress better than wider addresses.
@@ -184,62 +159,55 @@ static int F(Filter *f)
kh -= N_MRU; kh -= N_MRU;
} }
if (mru[kh] == jc) { // destination was seen recently if (mru[kh] == jc) { // destination was seen recently
set_be32(b+ic+1,((k<<1)|0)+cto); set_be32(b + ic + 1, ((k << 1) | 0) + cto);
update_mru(jc, kh, mru, hand, tail); update_mru(jc, kh, mru, hand, tail);
break; break;
} }
} }
if (k == N_MRU) { // loop failed; jc is not in mru[] if (k == N_MRU) { // loop failed; jc is not in mru[]
set_be32(b+ic+1,((jc<<1)|1)+cto); set_be32(b + ic + 1, ((jc << 1) | 1) + cto);
// Adaptively remember recent destinations. // Adaptively remember recent destinations.
if (0 > --hand) { if (0 > --hand) {
hand = N_MRU -1; hand = N_MRU - 1;
} }
mru[hand] = jc; mru[hand] = jc;
} }
} else } else if ((0 == which && NOFILT != f_call) || (1 == which && NOFILT != f_jmp1) ||
if ((0==which && NOFILT!=f_call) (2 == which && NOFILT != f_jcc2)) {
|| (1==which && NOFILT!=f_jmp1)
|| (2==which && NOFILT!=f_jcc2) ) {
f_on = 1; f_on = 1;
set_be32(b+ic+1, jc+cto); set_be32(b + ic + 1, jc + cto);
} }
#endif #endif
if (f_on) { if (f_on) {
if (ic - lastnoncall < 5) if (ic - lastnoncall < 5) {
{ // check the last 4 bytes before this call
// check the last 4 bytes before this call for (kc = 4; kc; kc--)
for (kc = 4; kc; kc--) if (CONDF(which, b, ic - kc, lastcall) && b[ic - kc + 1] == cto8)
if (CONDF(which,b,ic-kc,lastcall) && b[ic-kc+1] == cto8) break;
break; if (kc) {
if (kc) #ifdef U
{ // restore original
#ifdef U if (2 == which) {
// restore original // Unswap prefix and opcode for 6-byte Jcc <disp32>
if (2==which) { unsigned char const t = b[ic - 1];
// Unswap prefix and opcode for 6-byte Jcc <disp32> b[ic - 1] = b[ic];
unsigned char const t = b[ic] = t;
b[ic-1];
b[ic-1] = b[ic];
b[ic] = t;
}
set_le32(b+ic+1,jc-ic-1);
#endif
if (b[ic+1] == cto8)
return 1; // fail - buffer not restored
lastnoncall = ic;
noncalls2++;
continue;
} }
set_le32(b + ic + 1, jc - ic - 1);
#endif
if (b[ic + 1] == cto8)
return 1; // fail - buffer not restored
lastnoncall = ic;
noncalls2++;
continue;
} }
calls++; }
ic += 4; calls++;
lastcall = ic+1; ic += 4;
lastcall = ic + 1;
} }
} } else {
else assert(b[ic + 1] != cto8); // this should not happen
{
assert(b[ic+1] != cto8); // this should not happen
lastnoncall = ic; lastnoncall = ic;
noncalls++; noncalls++;
} }
@@ -258,19 +226,17 @@ static int F(Filter *f)
return 0; return 0;
} }
/************************************************************************* /*************************************************************************
// unfilter // unfilter
**************************************************************************/ **************************************************************************/
#ifdef U #ifdef U
static int U(Filter *f) static int U(Filter *f) {
{
unsigned ic, jc; unsigned ic, jc;
byte *const b = f->buf; byte *const b = f->buf;
const unsigned size5 = f->buf_len - 5; const unsigned size5 = f->buf_len - 5;
const unsigned cto = (unsigned)f->cto << 24; const unsigned cto = (unsigned) f->cto << 24;
unsigned lastcall = 0; unsigned lastcall = 0;
int hand = 0, tail = 0; int hand = 0, tail = 0;
const unsigned f_call = f80_call(f); const unsigned f_call = f80_call(f);
@@ -282,58 +248,50 @@ static int U(Filter *f)
for (ic = 0; ic < size5; ic++) { for (ic = 0; ic < size5; ic++) {
int which; int which;
if (CONDU(which,b,ic,lastcall)) if (CONDU(which, b, ic, lastcall)) {
{
unsigned f_on = 0; unsigned f_on = 0;
jc = get_be32(b+ic+1) - cto; jc = get_be32(b + ic + 1) - cto;
if (b[ic+1] == f->cto) if (b[ic + 1] == f->cto) {
{ if ((0 == which && MRUFLT == f_call) || (1 == which && MRUFLT == f_jmp1) ||
if ((0==which && MRUFLT==f_call) (2 == which && MRUFLT == f_jcc2)) {
|| (1==which && MRUFLT==f_jmp1)
|| (2==which && MRUFLT==f_jcc2) ) {
f_on = 1; f_on = 1;
if (1&jc) { // 1st time at this destination if (1 & jc) { // 1st time at this destination
jc >>= 1; jc >>= 1;
if (0 > --hand) { if (0 > --hand) {
hand = N_MRU -1; hand = N_MRU - 1;
}
mru[hand] = jc;
} }
else { // not 1st time at this destination mru[hand] = jc;
jc >>= 1; } else { // not 1st time at this destination
if (N_MRU <= jc) { jc >>= 1;
throwCompressedDataViolation(); if (N_MRU <= jc) {
} throwCompressedDataViolation();
int kh = jc + hand;
if (N_MRU <= kh) {
kh -= N_MRU;
}
jc = mru[kh];
update_mru(jc, kh, mru, hand, tail);
} }
set_le32(b+ic+1,jc-ic-1); int kh = jc + hand;
} else if (N_MRU <= kh) {
if ((0==which && NOFILT!=f_call) kh -= N_MRU;
|| (1==which && NOFILT!=f_jmp1) }
|| (2==which && NOFILT!=f_jcc2) ) { jc = mru[kh];
update_mru(jc, kh, mru, hand, tail);
}
set_le32(b + ic + 1, jc - ic - 1);
} else if ((0 == which && NOFILT != f_call) || (1 == which && NOFILT != f_jmp1) ||
(2 == which && NOFILT != f_jcc2)) {
f_on = 1; f_on = 1;
set_le32(b+ic+1,jc-ic-1); set_le32(b + ic + 1, jc - ic - 1);
} }
if (2==which && NOFILT!=f_jcc2) { if (2 == which && NOFILT != f_jcc2) {
// Unswap prefix and opcode for 6-byte Jcc <disp32> // Unswap prefix and opcode for 6-byte Jcc <disp32>
unsigned char const t = unsigned char const t = b[ic - 1];
b[ic-1]; b[ic - 1] = b[ic];
b[ic-1] = b[ic]; b[ic] = t;
b[ic] = t;
} }
if (f_on) { if (f_on) {
f->calls++; f->calls++;
ic += 4; ic += 4;
f->lastcall = lastcall = ic+1; f->lastcall = lastcall = ic + 1;
} }
} } else
else
f->noncalls++; f->noncalls++;
} }
} }
+31 -49
View File
@@ -29,14 +29,11 @@
<jreiser@users.sourceforge.net> <jreiser@users.sourceforge.net>
*/ */
/************************************************************************* /*************************************************************************
// filter / scan // filter / scan
**************************************************************************/ **************************************************************************/
static int F(Filter *f) static int F(Filter *f) {
{
#ifdef U #ifdef U
// filter // filter
byte *b = f->buf; byte *b = f->buf;
@@ -55,20 +52,17 @@ static int F(Filter *f)
// find a 16 MiB large empty address space // find a 16 MiB large empty address space
{ {
unsigned char buf[256]; unsigned char buf[256];
memset(buf,0,256); memset(buf, 0, 256);
for (ic = 0; ic < size - 5; ic++) for (ic = 0; ic < size - 5; ic++) {
{ if (!COND(b, ic, lastcall, id))
if (!COND(b,ic,lastcall,id))
continue; continue;
jc = get_le32(b+ic+1)+ic+1; jc = get_le32(b + ic + 1) + ic + 1;
if (jc < size) if (jc < size) {
{
if (jc + addvalue >= (1u << 24)) // hi 8 bits won't be cto8 if (jc + addvalue >= (1u << 24)) // hi 8 bits won't be cto8
return -1; return -1;
} } else
else buf[b[ic + 1]] |= 1;
buf[b[ic+1]] |= 1;
} }
if (getcto(f, buf) < 0) if (getcto(f, buf) < 0)
@@ -76,35 +70,31 @@ static int F(Filter *f)
} }
const unsigned char cto8 = f->cto; const unsigned char cto8 = f->cto;
#ifdef U #ifdef U
const unsigned cto = (unsigned)f->cto << 24; const unsigned cto = (unsigned) f->cto << 24;
#endif #endif
for (ic = 0; ic < size - 5; ic++) for (ic = 0; ic < size - 5; ic++) {
{ if (!COND(b, ic, lastcall, id))
if (!COND(b,ic,lastcall,id))
continue; continue;
jc = get_le32(b+ic+1)+ic+1; jc = get_le32(b + ic + 1) + ic + 1;
// try to detect 'real' calls only // try to detect 'real' calls only
if (jc < size) if (jc < size) {
{
assert(jc + addvalue < (1u << 24)); // hi 8 bits won't be cto8 assert(jc + addvalue < (1u << 24)); // hi 8 bits won't be cto8
#ifdef U #ifdef U
set_be32(b+ic+1,jc+addvalue+cto); set_be32(b + ic + 1, jc + addvalue + cto);
#endif #endif
if (ic - lastnoncall < 5) if (ic - lastnoncall < 5) {
{
// check the last 4 bytes before this call // check the last 4 bytes before this call
for (kc = 4; kc; kc--) for (kc = 4; kc; kc--)
if (COND(b,ic-kc,lastcall,id) && b[ic-kc+1] == cto8) if (COND(b, ic - kc, lastcall, id) && b[ic - kc + 1] == cto8)
break; break;
if (kc) if (kc) {
{
#ifdef U #ifdef U
// restore original // restore original
set_le32(b+ic+1,jc-ic-1); set_le32(b + ic + 1, jc - ic - 1);
#endif #endif
if (b[ic+1] == cto8) if (b[ic + 1] == cto8)
return 1; // fail - buffer not restored return 1; // fail - buffer not restored
lastnoncall = ic; lastnoncall = ic;
noncalls2++; noncalls2++;
continue; continue;
@@ -112,11 +102,9 @@ static int F(Filter *f)
} }
calls++; calls++;
ic += 4; ic += 4;
lastcall = ic+1; lastcall = ic + 1;
} } else {
else assert(b[ic + 1] != cto8); // this should not happen
{
assert(b[ic+1] != cto8); // this should not happen
lastnoncall = ic; lastnoncall = ic;
noncalls++; noncalls++;
} }
@@ -133,42 +121,36 @@ static int F(Filter *f)
return 0; return 0;
} }
/************************************************************************* /*************************************************************************
// unfilter // unfilter
**************************************************************************/ **************************************************************************/
#ifdef U #ifdef U
static int U(Filter *f) static int U(Filter *f) {
{
byte *b = f->buf; byte *b = f->buf;
const unsigned size5 = f->buf_len - 5; const unsigned size5 = f->buf_len - 5;
const unsigned addvalue = f->addvalue; const unsigned addvalue = f->addvalue;
const unsigned cto = (unsigned)f->cto << 24; const unsigned cto = (unsigned) f->cto << 24;
const unsigned id = f->id; const unsigned id = f->id;
unsigned lastcall = 0; unsigned lastcall = 0;
unsigned ic, jc; unsigned ic, jc;
for (ic = 0; ic < size5; ic++) for (ic = 0; ic < size5; ic++)
if (COND(b,ic,lastcall,id)) if (COND(b, ic, lastcall, id)) {
{ jc = get_be32(b + ic + 1);
jc = get_be32(b+ic+1); if (b[ic + 1] == f->cto) {
if (b[ic+1] == f->cto) set_le32(b + ic + 1, jc - ic - 1 - addvalue - cto);
{
set_le32(b+ic+1,jc-ic-1-addvalue-cto);
f->calls++; f->calls++;
ic += 4; ic += 4;
f->lastcall = lastcall = ic+1; f->lastcall = lastcall = ic + 1;
} } else
else
f->noncalls++; f->noncalls++;
} }
return 0; return 0;
} }
#endif #endif
#undef F #undef F
#undef U #undef U
+56 -83
View File
@@ -25,145 +25,118 @@
<markus@oberhumer.com> <ezerotven+github@gmail.com> <markus@oberhumer.com> <ezerotven+github@gmail.com>
*/ */
/************************************************************************* /*************************************************************************
// 16-bit call-/swaptrick ("naive") // 16-bit call-/swaptrick ("naive")
**************************************************************************/ **************************************************************************/
#define CTSW16(f, cond1, cond2, addvalue, get, set) \ #define CTSW16(f, cond1, cond2, addvalue, get, set) \
byte *b = f->buf; \ byte *b = f->buf; \
byte *b_end = b + f->buf_len - 3; \ byte *b_end = b + f->buf_len - 3; \
do { \ do { \
if (cond1) \ if (cond1) { \
{ \ b += 1; \
b += 1; \ unsigned a = (unsigned) (b - f->buf); \
unsigned a = (unsigned) (b - f->buf); \ f->lastcall = a; \
f->lastcall = a; \ set(b, get(b) + (addvalue)); \
set(b, get(b) + (addvalue)); \ f->calls++; \
f->calls++; \ b += 2 - 1; \
b += 2 - 1; \ } else if (cond2) { \
} \ b += 1; \
else if (cond2) \ unsigned a = (unsigned) (b - f->buf); \
{ \ f->lastcall = a; \
b += 1; \ set(b, get(b)); \
unsigned a = (unsigned) (b - f->buf); \ f->calls++; \
f->lastcall = a; \ b += 2 - 1; \
set(b, get(b)); \ } \
f->calls++; \ } while (++b < b_end); \
b += 2 - 1; \ if (f->lastcall) \
} \ f->lastcall += 2; \
} while (++b < b_end); \
if (f->lastcall) f->lastcall += 2; \
return 0; return 0;
// filter // filter
static int f_ctsw16_e8_e9(Filter *f) static int f_ctsw16_e8_e9(Filter *f) {
{
CTSW16(f, (*b == 0xe8), (*b == 0xe9), a + f->addvalue, get_le16, set_be16) CTSW16(f, (*b == 0xe8), (*b == 0xe9), a + f->addvalue, get_le16, set_be16)
} }
static int f_ctsw16_e9_e8(Filter *f) static int f_ctsw16_e9_e8(Filter *f) {
{
CTSW16(f, (*b == 0xe9), (*b == 0xe8), a + f->addvalue, get_le16, set_be16) CTSW16(f, (*b == 0xe9), (*b == 0xe8), a + f->addvalue, get_le16, set_be16)
} }
// unfilter // unfilter
static int u_ctsw16_e8_e9(Filter *f) static int u_ctsw16_e8_e9(Filter *f) {
{
CTSW16(f, (*b == 0xe8), (*b == 0xe9), 0 - a - f->addvalue, get_be16, set_le16) CTSW16(f, (*b == 0xe8), (*b == 0xe9), 0 - a - f->addvalue, get_be16, set_le16)
} }
static int u_ctsw16_e9_e8(Filter *f) static int u_ctsw16_e9_e8(Filter *f) {
{
CTSW16(f, (*b == 0xe9), (*b == 0xe8), 0 - a - f->addvalue, get_be16, set_le16) CTSW16(f, (*b == 0xe9), (*b == 0xe8), 0 - a - f->addvalue, get_be16, set_le16)
} }
// scan // scan
static int s_ctsw16_e8_e9(Filter *f) static int s_ctsw16_e8_e9(Filter *f) {
{
CTSW16(f, (*b == 0xe8), (*b == 0xe9), a + f->addvalue, get_le16, set_dummy) CTSW16(f, (*b == 0xe8), (*b == 0xe9), a + f->addvalue, get_le16, set_dummy)
} }
static int s_ctsw16_e9_e8(Filter *f) static int s_ctsw16_e9_e8(Filter *f) {
{
CTSW16(f, (*b == 0xe9), (*b == 0xe8), a + f->addvalue, get_le16, set_dummy) CTSW16(f, (*b == 0xe9), (*b == 0xe8), a + f->addvalue, get_le16, set_dummy)
} }
#undef CTSW16 #undef CTSW16
/************************************************************************* /*************************************************************************
// 32-bit call-/swaptrick ("naive") // 32-bit call-/swaptrick ("naive")
**************************************************************************/ **************************************************************************/
#define CTSW32(f, cond1, cond2, addvalue, get, set) \ #define CTSW32(f, cond1, cond2, addvalue, get, set) \
byte *b = f->buf; \ byte *b = f->buf; \
byte *b_end = b + f->buf_len - 5; \ byte *b_end = b + f->buf_len - 5; \
do { \ do { \
if (cond1) \ if (cond1) { \
{ \ b += 1; \
b += 1; \ unsigned a = (unsigned) (b - f->buf); \
unsigned a = (unsigned) (b - f->buf); \ f->lastcall = a; \
f->lastcall = a; \ set(b, get(b) + (addvalue)); \
set(b, get(b) + (addvalue)); \ f->calls++; \
f->calls++; \ b += 4 - 1; \
b += 4 - 1; \ } else if (cond2) { \
} \ b += 1; \
else if (cond2) \ unsigned a = (unsigned) (b - f->buf); \
{ \ f->lastcall = a; \
b += 1; \ set(b, get(b)); \
unsigned a = (unsigned) (b - f->buf); \ f->calls++; \
f->lastcall = a; \ b += 4 - 1; \
set(b, get(b)); \ } \
f->calls++; \ } while (++b < b_end); \
b += 4 - 1; \ if (f->lastcall) \
} \ f->lastcall += 4; \
} while (++b < b_end); \
if (f->lastcall) f->lastcall += 4; \
return 0; return 0;
// filter // filter
static int f_ctsw32_e8_e9(Filter *f) static int f_ctsw32_e8_e9(Filter *f) {
{
CTSW32(f, (*b == 0xe8), (*b == 0xe9), a + f->addvalue, get_le32, set_be32) CTSW32(f, (*b == 0xe8), (*b == 0xe9), a + f->addvalue, get_le32, set_be32)
} }
static int f_ctsw32_e9_e8(Filter *f) static int f_ctsw32_e9_e8(Filter *f) {
{
CTSW32(f, (*b == 0xe9), (*b == 0xe8), a + f->addvalue, get_le32, set_be32) CTSW32(f, (*b == 0xe9), (*b == 0xe8), a + f->addvalue, get_le32, set_be32)
} }
// unfilter // unfilter
static int u_ctsw32_e8_e9(Filter *f) static int u_ctsw32_e8_e9(Filter *f) {
{
CTSW32(f, (*b == 0xe8), (*b == 0xe9), 0 - a - f->addvalue, get_be32, set_le32) CTSW32(f, (*b == 0xe8), (*b == 0xe9), 0 - a - f->addvalue, get_be32, set_le32)
} }
static int u_ctsw32_e9_e8(Filter *f) static int u_ctsw32_e9_e8(Filter *f) {
{
CTSW32(f, (*b == 0xe9), (*b == 0xe8), 0 - a - f->addvalue, get_be32, set_le32) CTSW32(f, (*b == 0xe9), (*b == 0xe8), 0 - a - f->addvalue, get_be32, set_le32)
} }
// scan // scan
static int s_ctsw32_e8_e9(Filter *f) static int s_ctsw32_e8_e9(Filter *f) {
{
CTSW32(f, (*b == 0xe8), (*b == 0xe9), a + f->addvalue, get_le32, set_dummy) CTSW32(f, (*b == 0xe8), (*b == 0xe9), a + f->addvalue, get_le32, set_dummy)
} }
static int s_ctsw32_e9_e8(Filter *f) static int s_ctsw32_e9_e8(Filter *f) {
{
CTSW32(f, (*b == 0xe9), (*b == 0xe8), a + f->addvalue, get_le32, set_dummy) CTSW32(f, (*b == 0xe9), (*b == 0xe8), a + f->addvalue, get_le32, set_dummy)
} }
#undef CTSW32 #undef CTSW32
/* vim:set ts=4 sw=4 et: */ /* vim:set ts=4 sw=4 et: */
+43 -57
View File
@@ -25,21 +25,14 @@
<markus@oberhumer.com> <ezerotven+github@gmail.com> <markus@oberhumer.com> <ezerotven+github@gmail.com>
*/ */
#include "../conf.h" #include "../conf.h"
#include "../filter.h" #include "../filter.h"
static unsigned static unsigned umin(const unsigned a, const unsigned b) { return (a <= b) ? a : b; }
umin(const unsigned a, const unsigned b)
{
return (a<=b) ? a : b;
}
#define set_dummy(p, v) ((void)0)
#define get_8(p) (*(p))
#define set_8(p, v) (*(p) = (v))
#define set_dummy(p, v) ((void) 0)
#define get_8(p) (*(p))
#define set_8(p, v) (*(p) = (v))
/************************************************************************* /*************************************************************************
// util // util
@@ -47,7 +40,6 @@ umin(const unsigned a, const unsigned b)
#include "getcto.h" #include "getcto.h"
/************************************************************************* /*************************************************************************
// simple filters: calltrick / swaptrick / delta / ... // simple filters: calltrick / swaptrick / delta / ...
**************************************************************************/ **************************************************************************/
@@ -60,86 +52,80 @@ umin(const unsigned a, const unsigned b)
#include "sub16.h" #include "sub16.h"
#include "sub32.h" #include "sub32.h"
/************************************************************************* /*************************************************************************
// cto calltrick // cto calltrick
**************************************************************************/ **************************************************************************/
#define COND(b,x) (b[x] == 0xe8) #define COND(b, x) (b[x] == 0xe8)
#define F f_cto32_e8_bswap_le #define F f_cto32_e8_bswap_le
#define U u_cto32_e8_bswap_le #define U u_cto32_e8_bswap_le
#include "cto.h" #include "cto.h"
#define F s_cto32_e8_bswap_le #define F s_cto32_e8_bswap_le
#include "cto.h" #include "cto.h"
#undef COND #undef COND
#define COND(b,x) (b[x] == 0xe9) #define COND(b, x) (b[x] == 0xe9)
#define F f_cto32_e9_bswap_le #define F f_cto32_e9_bswap_le
#define U u_cto32_e9_bswap_le #define U u_cto32_e9_bswap_le
#include "cto.h" #include "cto.h"
#define F s_cto32_e9_bswap_le #define F s_cto32_e9_bswap_le
#include "cto.h" #include "cto.h"
#undef COND #undef COND
#define COND(b,x) (b[x] == 0xe8 || b[x] == 0xe9) #define COND(b, x) (b[x] == 0xe8 || b[x] == 0xe9)
#define F f_cto32_e8e9_bswap_le #define F f_cto32_e8e9_bswap_le
#define U u_cto32_e8e9_bswap_le #define U u_cto32_e8e9_bswap_le
#include "cto.h" #include "cto.h"
#define F s_cto32_e8e9_bswap_le #define F s_cto32_e8e9_bswap_le
#include "cto.h" #include "cto.h"
#undef COND #undef COND
/************************************************************************* /*************************************************************************
// cto calltrick with jmp // cto calltrick with jmp
**************************************************************************/ **************************************************************************/
#define COND(b,x,lastcall) (b[x] == 0xe8 || b[x] == 0xe9) #define COND(b, x, lastcall) (b[x] == 0xe8 || b[x] == 0xe9)
#define F f_ctoj32_e8e9_bswap_le #define F f_ctoj32_e8e9_bswap_le
#define U u_ctoj32_e8e9_bswap_le #define U u_ctoj32_e8e9_bswap_le
#include "ctoj.h" #include "ctoj.h"
#define F s_ctoj32_e8e9_bswap_le #define F s_ctoj32_e8e9_bswap_le
#include "ctoj.h" #include "ctoj.h"
#undef COND #undef COND
/************************************************************************* /*************************************************************************
// cto calltrick with jmp, optional jcc // cto calltrick with jmp, optional jcc
**************************************************************************/ **************************************************************************/
#define COND1(b,x) (b[x] == 0xe8 || b[x] == 0xe9) #define COND1(b, x) (b[x] == 0xe8 || b[x] == 0xe9)
#define COND2(b,x,lc) (lc!=(x) && 0xf==b[(x)-1] && 0x80<=b[x] && b[x]<=0x8f) #define COND2(b, x, lc) (lc != (x) && 0xf == b[(x) -1] && 0x80 <= b[x] && b[x] <= 0x8f)
#define COND(b,x,lc,id) (COND1(b,x) || ((9<=(0xf&(id))) && COND2(b,x,lc))) #define COND(b, x, lc, id) (COND1(b, x) || ((9 <= (0xf & (id))) && COND2(b, x, lc)))
#define F f_ctok32_e8e9_bswap_le #define F f_ctok32_e8e9_bswap_le
#define U u_ctok32_e8e9_bswap_le #define U u_ctok32_e8e9_bswap_le
#include "ctok.h" #include "ctok.h"
#define F s_ctok32_e8e9_bswap_le #define F s_ctok32_e8e9_bswap_le
#include "ctok.h" #include "ctok.h"
#undef COND #undef COND
#undef COND2 #undef COND2
#undef COND1 #undef COND1
/************************************************************************* /*************************************************************************
// cto calltrick with jmp and jcc and relative renumbering // cto calltrick with jmp and jcc and relative renumbering
**************************************************************************/ **************************************************************************/
#define COND_CALL(which,b,x) ((which = 0), b[x] == 0xe8) #define COND_CALL(which, b, x) ((which = 0), b[x] == 0xe8)
#define COND_JMP( which,b,x) ((which = 1), b[x] == 0xe9) #define COND_JMP(which, b, x) ((which = 1), b[x] == 0xe9)
#define COND_JCC( which,b,lastcall,x,y,z) ((which = 2), \ #define COND_JCC(which, b, lastcall, x, y, z) \
(lastcall!=(x) && 0xf==b[y] && 0x80<=b[z] && b[z]<=0x8f)) ((which = 2), (lastcall != (x) && 0xf == b[y] && 0x80 <= b[z] && b[z] <= 0x8f))
#define COND1(which,b,x) (COND_CALL(which,b,x) || COND_JMP(which,b,x)) #define COND1(which, b, x) (COND_CALL(which, b, x) || COND_JMP(which, b, x))
#define COND2(which,b,lastcall,x,y,z) COND_JCC(which,b,lastcall,x,y,z) #define COND2(which, b, lastcall, x, y, z) COND_JCC(which, b, lastcall, x, y, z)
#define CONDF(which,b,x,lastcall) \ #define CONDF(which, b, x, lastcall) (COND1(which, b, x) || COND2(which, b, lastcall, x, (x) -1, x))
(COND1(which,b,x) || COND2(which,b,lastcall,x,(x)-1, x )) #define CONDU(which, b, x, lastcall) (COND1(which, b, x) || COND2(which, b, lastcall, x, x, (x) -1))
#define CONDU(which,b,x,lastcall) \
(COND1(which,b,x) || COND2(which,b,lastcall,x, x ,(x)-1))
#define F f_ctojr32_e8e9_bswap_le #define F f_ctojr32_e8e9_bswap_le
#define U u_ctojr32_e8e9_bswap_le #define U u_ctojr32_e8e9_bswap_le
#include "ctojr.h" #include "ctojr.h"
#define F s_ctojr32_e8e9_bswap_le #define F s_ctojr32_e8e9_bswap_le
#include "ctojr.h" #include "ctojr.h"
#undef CONDU #undef CONDU
@@ -150,24 +136,23 @@ umin(const unsigned a, const unsigned b)
#undef COND_JMP #undef COND_JMP
#undef COND_CALL #undef COND_CALL
/************************************************************************* /*************************************************************************
// PowerPC branch [incl. call] trick // PowerPC branch [incl. call] trick
**************************************************************************/ **************************************************************************/
#define COND(b,x) (18==(get_be32(b+x)>>26)) #define COND(b, x) (18 == (get_be32(b + x) >> 26))
#define F f_ppcbxx #define F f_ppcbxx
#define U u_ppcbxx #define U u_ppcbxx
#include "ppcbxx.h" #include "ppcbxx.h"
#define F s_ppcbxx #define F s_ppcbxx
#include "ppcbxx.h" #include "ppcbxx.h"
#undef COND #undef COND
/************************************************************************* /*************************************************************************
// database for use in class Filter // database for use in class Filter
**************************************************************************/ **************************************************************************/
// clang-format off
/*static*/ const FilterImpl::FilterEntry FilterImpl::filters[] = { /*static*/ const FilterImpl::FilterEntry FilterImpl::filters[] = {
// no filter // no filter
{ 0x00, 0, 0, nullptr, nullptr, nullptr }, { 0x00, 0, 0, nullptr, nullptr, nullptr },
@@ -265,6 +250,7 @@ umin(const unsigned a, const unsigned b)
// PowerPC branch+call trick // PowerPC branch+call trick
{ 0xd0, 8, 0, f_ppcbxx, u_ppcbxx, s_ppcbxx }, { 0xd0, 8, 0, f_ppcbxx, u_ppcbxx, s_ppcbxx },
}; };
// clang-format on
/*static*/ const int FilterImpl::n_filters = TABLESIZE(filters); /*static*/ const int FilterImpl::n_filters = TABLESIZE(filters);
+5 -11
View File
@@ -25,22 +25,16 @@
<markus@oberhumer.com> <ezerotven+github@gmail.com> <markus@oberhumer.com> <ezerotven+github@gmail.com>
*/ */
/************************************************************************* /*************************************************************************
// //
**************************************************************************/ **************************************************************************/
static int getcto(Filter *f, const byte *buf, const int n=256) static int getcto(Filter *f, const byte *buf, const int n = 256) {
{
int ic = n; int ic = n;
if (f->preferred_ctos) if (f->preferred_ctos) {
{ for (const int *pc = f->preferred_ctos; *pc >= 0; pc++) {
for (const int *pc = f->preferred_ctos; *pc >= 0; pc++) if (*pc < n && buf[*pc] == 0) {
{
if (*pc < n && buf[*pc] == 0)
{
ic = *pc; ic = *pc;
break; break;
} }
@@ -60,7 +54,7 @@ static int getcto(Filter *f, const byte *buf, const int n=256)
break; break;
if (ic >= n) if (ic >= n)
//throwCantPack("call trick problem"); // throwCantPack("call trick problem");
return -1; return -1;
f->cto = (byte) ic; f->cto = (byte) ic;
+43 -47
View File
@@ -29,16 +29,13 @@
<jreiser@users.sourceforge.net> <jreiser@users.sourceforge.net>
*/ */
/************************************************************************* /*************************************************************************
// filter / scan // filter / scan
**************************************************************************/ **************************************************************************/
#define W_CTO 4 /* width of cto; must match stub/ppc_bxx.S */ #define W_CTO 4 /* width of cto; must match stub/ppc_bxx.S */
static int F(Filter *f) static int F(Filter *f) {
{
#ifdef U #ifdef U
// filter // filter
byte *b = f->buf; byte *b = f->buf;
@@ -47,8 +44,8 @@ static int F(Filter *f)
// scan // scan
const byte *b = f->buf; const byte *b = f->buf;
#endif #endif
const unsigned size = umin(f->buf_len, 0u - (~0u<<(32 - (6+ W_CTO)))); const unsigned size = umin(f->buf_len, 0u - (~0u << (32 - (6 + W_CTO))));
const unsigned size4 = size -4; const unsigned size4 = size - 4;
unsigned ic; unsigned ic;
unsigned calls = 0, noncalls = 0; unsigned calls = 0, noncalls = 0;
@@ -58,18 +55,19 @@ static int F(Filter *f)
{ {
unsigned char buf[256]; unsigned char buf[256];
unsigned short wbuf[256]; unsigned short wbuf[256];
const size_t WW = (size_t)0 - ((~(size_t)0) << W_CTO); // ??? const size_t WW = (size_t) 0 - ((~(size_t) 0) << W_CTO); // ???
memset(wbuf, 0, sizeof(wbuf)); memset(wbuf, 0, sizeof(wbuf));
memset(buf , 0, WW); memset(buf, 0, WW);
memset(buf + WW, 1, 256 - WW); memset(buf + WW, 1, 256 - WW);
for (ic = 0; ic<=size4; ic+=4) if (COND(b,ic)) { for (ic = 0; ic <= size4; ic += 4)
unsigned const off = (int)(get_be32(b+ic)<<6) >>6; if (COND(b, ic)) {
if (size <= (off & (~0u<<2))+ic) { unsigned const off = (int) (get_be32(b + ic) << 6) >> 6;
buf[(~(~0u<<W_CTO)) & (off>>(26 - W_CTO))] |= 1; if (size <= (off & (~0u << 2)) + ic) {
++wbuf[0xff&(off>>18)]; buf[(~(~0u << W_CTO)) & (off >> (26 - W_CTO))] |= 1;
++wbuf[0xff & (off >> 18)];
}
} }
}
if (getcto(f, buf) < 0) { if (getcto(f, buf) < 0) {
#if (W_CTO != 0) #if (W_CTO != 0)
@@ -81,29 +79,30 @@ static int F(Filter *f)
} }
const unsigned char cto8 = f->cto; const unsigned char cto8 = f->cto;
#ifdef U #ifdef U
const unsigned cto = (unsigned)f->cto << (24+2 - W_CTO); const unsigned cto = (unsigned) f->cto << (24 + 2 - W_CTO);
#endif #endif
for (ic = 0; ic<=size4; ic+=4) if (COND(b,ic)) { for (ic = 0; ic <= size4; ic += 4)
unsigned const word = get_be32(b+ic); if (COND(b, ic)) {
unsigned const off = (int)(word<<6) >>6; unsigned const word = get_be32(b + ic);
unsigned const jc = (off & (~0u<<2))+ic; unsigned const off = (int) (word << 6) >> 6;
// try to detect 'real' calls only unsigned const jc = (off & (~0u << 2)) + ic;
if (jc < size) { // try to detect 'real' calls only
if (jc < size) {
#ifdef U #ifdef U
set_be32(b+ic,(0xfc000003&word) | (jc+addvalue+cto)); set_be32(b + ic, (0xfc000003 & word) | (jc + addvalue + cto));
#endif #endif
calls++; calls++;
lastcall = ic; lastcall = ic;
} } else {
else {
#if (W_CTO != 0) #if (W_CTO != 0)
assert((~(~0u<<W_CTO) & (word>>(24+2 - W_CTO))) != (unsigned) cto8); // this should not happen assert((~(~0u << W_CTO) & (word >> (24 + 2 - W_CTO))) !=
(unsigned) cto8); // this should not happen
#endif #endif
lastnoncall = ic; lastnoncall = ic;
noncalls++; noncalls++;
}
} }
}
f->calls = calls; f->calls = calls;
f->noncalls = noncalls; f->noncalls = noncalls;
@@ -117,37 +116,34 @@ static int F(Filter *f)
return 0; return 0;
} }
/************************************************************************* /*************************************************************************
// unfilter // unfilter
**************************************************************************/ **************************************************************************/
#ifdef U #ifdef U
static int U(Filter *f) static int U(Filter *f) {
{
byte *b = f->buf; byte *b = f->buf;
const unsigned size4 = umin(f->buf_len - 4, 0u - (~0u<<(32 - (6+ W_CTO)))); const unsigned size4 = umin(f->buf_len - 4, 0u - (~0u << (32 - (6 + W_CTO))));
const unsigned addvalue = f->addvalue; const unsigned addvalue = f->addvalue;
unsigned ic; unsigned ic;
for (ic = 0; ic<=size4; ic+=4) if (COND(b,ic)) { for (ic = 0; ic <= size4; ic += 4)
unsigned const word = get_be32(b+ic); if (COND(b, ic)) {
if ((~(~0u<<W_CTO) & (word>>(24+2 - W_CTO))) == (unsigned) f->cto) { unsigned const word = get_be32(b + ic);
unsigned const jc = word & (~(~0u<<(26 - W_CTO)) & (~0u<<2)); if ((~(~0u << W_CTO) & (word >> (24 + 2 - W_CTO))) == (unsigned) f->cto) {
set_be32(b+ic, (0xfc000003&word)|(0x03fffffc&(jc-ic-addvalue))); unsigned const jc = word & (~(~0u << (26 - W_CTO)) & (~0u << 2));
f->calls++; set_be32(b + ic, (0xfc000003 & word) | (0x03fffffc & (jc - ic - addvalue)));
f->lastcall = ic; f->calls++;
f->lastcall = ic;
} else {
f->noncalls++;
}
} }
else {
f->noncalls++;
}
}
return 0; return 0;
} }
#endif #endif
#undef F #undef F
#undef U #undef U
+46 -44
View File
@@ -25,58 +25,60 @@
<markus@oberhumer.com> <ezerotven+github@gmail.com> <markus@oberhumer.com> <ezerotven+github@gmail.com>
*/ */
/************************************************************************* /*************************************************************************
// //
**************************************************************************/ **************************************************************************/
#define SUB(f, N, T, get, set) \ #define SUB(f, N, T, get, set) \
byte *b = f->buf; \ byte *b = f->buf; \
unsigned l = f->buf_len / sizeof(T); \ unsigned l = f->buf_len / sizeof(T); \
int i; \ int i; \
T d[N]; \ T d[N]; \
\ \
i = N - 1; do d[i] = 0; while (--i >= 0); \ i = N - 1; \
\ do \
i = N - 1; \ d[i] = 0; \
do { \ while (--i >= 0); \
T delta = (T) (get(b) - d[i]); \ \
set(b, delta); \ i = N - 1; \
d[i] = (T) (d[i] + delta); \ do { \
b += sizeof(T); \ T delta = (T) (get(b) - d[i]); \
if (--i < 0) \ set(b, delta); \
i = N - 1; \ d[i] = (T) (d[i] + delta); \
} while (--l > 0); \ b += sizeof(T); \
f->calls = (f->buf_len / sizeof(T)) - N; \ if (--i < 0) \
assert((int)f->calls > 0); \ i = N - 1; \
} while (--l > 0); \
f->calls = (f->buf_len / sizeof(T)) - N; \
assert((int) f->calls > 0); \
return 0; return 0;
#define ADD(f, N, T, get, set) \
#define ADD(f, N, T, get, set) \ byte *b = f->buf; \
byte *b = f->buf; \ unsigned l = f->buf_len / sizeof(T); \
unsigned l = f->buf_len / sizeof(T); \ int i; \
int i; \ T d[N]; \
T d[N]; \ \
\ i = N - 1; \
i = N - 1; do d[i] = 0; while (--i >= 0); \ do \
\ d[i] = 0; \
i = N - 1; \ while (--i >= 0); \
do { \ \
d[i] = (T) (d[i] + get(b)); \ i = N - 1; \
set(b, d[i]); \ do { \
b += sizeof(T); \ d[i] = (T) (d[i] + get(b)); \
if (--i < 0) \ set(b, d[i]); \
i = N - 1; \ b += sizeof(T); \
} while (--l > 0); \ if (--i < 0) \
f->calls = (f->buf_len / sizeof(T)) - N; \ i = N - 1; \
assert((int)f->calls > 0); \ } while (--l > 0); \
f->calls = (f->buf_len / sizeof(T)) - N; \
assert((int) f->calls > 0); \
return 0; return 0;
#define SCAN(f, N, T, get, set) \
#define SCAN(f, N, T, get, set) \ f->calls = (f->buf_len / sizeof(T)) - N; \
f->calls = (f->buf_len / sizeof(T)) - N; \ assert((int) f->calls > 0); \
assert((int)f->calls > 0); \
return 0; return 0;
/* vim:set ts=4 sw=4 et: */ /* vim:set ts=4 sw=4 et: */
+15 -57
View File
@@ -25,88 +25,46 @@
<markus@oberhumer.com> <ezerotven+github@gmail.com> <markus@oberhumer.com> <ezerotven+github@gmail.com>
*/ */
/************************************************************************* /*************************************************************************
// //
**************************************************************************/ **************************************************************************/
#include "sub.hh" #include "sub.hh"
#define SUB16(f, N) SUB(f, N, unsigned short, get_le16, set_le16) #define SUB16(f, N) SUB(f, N, unsigned short, get_le16, set_le16)
#define ADD16(f, N) ADD(f, N, unsigned short, get_le16, set_le16) #define ADD16(f, N) ADD(f, N, unsigned short, get_le16, set_le16)
#define SCAN16(f, N) SCAN(f, N, unsigned short, get_le16, set_le16) #define SCAN16(f, N) SCAN(f, N, unsigned short, get_le16, set_le16)
/************************************************************************* /*************************************************************************
// //
**************************************************************************/ **************************************************************************/
// filter // filter
static int f_sub16_1(Filter *f) static int f_sub16_1(Filter *f) { SUB16(f, 1) }
{
SUB16(f, 1)
}
static int f_sub16_2(Filter *f) static int f_sub16_2(Filter *f) { SUB16(f, 2) }
{
SUB16(f, 2)
}
static int f_sub16_3(Filter *f) static int f_sub16_3(Filter *f) { SUB16(f, 3) }
{
SUB16(f, 3)
}
static int f_sub16_4(Filter *f)
{
SUB16(f, 4)
}
static int f_sub16_4(Filter *f) { SUB16(f, 4) }
// unfilter // unfilter
static int u_sub16_1(Filter *f) static int u_sub16_1(Filter *f) { ADD16(f, 1) }
{
ADD16(f, 1)
}
static int u_sub16_2(Filter *f) static int u_sub16_2(Filter *f) { ADD16(f, 2) }
{
ADD16(f, 2)
}
static int u_sub16_3(Filter *f) static int u_sub16_3(Filter *f) { ADD16(f, 3) }
{
ADD16(f, 3)
}
static int u_sub16_4(Filter *f)
{
ADD16(f, 4)
}
static int u_sub16_4(Filter *f) { ADD16(f, 4) }
// scan // scan
static int s_sub16_1(Filter *f) static int s_sub16_1(Filter *f) { SCAN16(f, 1) }
{
SCAN16(f, 1)
}
static int s_sub16_2(Filter *f) static int s_sub16_2(Filter *f) { SCAN16(f, 2) }
{
SCAN16(f, 2)
}
static int s_sub16_3(Filter *f) static int s_sub16_3(Filter *f) { SCAN16(f, 3) }
{
SCAN16(f, 3)
}
static int s_sub16_4(Filter *f)
{
SCAN16(f, 4)
}
static int s_sub16_4(Filter *f) { SCAN16(f, 4) }
#undef SUB #undef SUB
#undef ADD #undef ADD
+15 -57
View File
@@ -25,88 +25,46 @@
<markus@oberhumer.com> <ezerotven+github@gmail.com> <markus@oberhumer.com> <ezerotven+github@gmail.com>
*/ */
/************************************************************************* /*************************************************************************
// //
**************************************************************************/ **************************************************************************/
#include "sub.hh" #include "sub.hh"
#define SUB32(f, N) SUB(f, N, unsigned int, get_le32, set_le32) #define SUB32(f, N) SUB(f, N, unsigned int, get_le32, set_le32)
#define ADD32(f, N) ADD(f, N, unsigned int, get_le32, set_le32) #define ADD32(f, N) ADD(f, N, unsigned int, get_le32, set_le32)
#define SCAN32(f, N) SCAN(f, N, unsigned int, get_le32, set_le32) #define SCAN32(f, N) SCAN(f, N, unsigned int, get_le32, set_le32)
/************************************************************************* /*************************************************************************
// //
**************************************************************************/ **************************************************************************/
// filter // filter
static int f_sub32_1(Filter *f) static int f_sub32_1(Filter *f) { SUB32(f, 1) }
{
SUB32(f, 1)
}
static int f_sub32_2(Filter *f) static int f_sub32_2(Filter *f) { SUB32(f, 2) }
{
SUB32(f, 2)
}
static int f_sub32_3(Filter *f) static int f_sub32_3(Filter *f) { SUB32(f, 3) }
{
SUB32(f, 3)
}
static int f_sub32_4(Filter *f)
{
SUB32(f, 4)
}
static int f_sub32_4(Filter *f) { SUB32(f, 4) }
// unfilter // unfilter
static int u_sub32_1(Filter *f) static int u_sub32_1(Filter *f) { ADD32(f, 1) }
{
ADD32(f, 1)
}
static int u_sub32_2(Filter *f) static int u_sub32_2(Filter *f) { ADD32(f, 2) }
{
ADD32(f, 2)
}
static int u_sub32_3(Filter *f) static int u_sub32_3(Filter *f) { ADD32(f, 3) }
{
ADD32(f, 3)
}
static int u_sub32_4(Filter *f)
{
ADD32(f, 4)
}
static int u_sub32_4(Filter *f) { ADD32(f, 4) }
// scan // scan
static int s_sub32_1(Filter *f) static int s_sub32_1(Filter *f) { SCAN32(f, 1) }
{
SCAN32(f, 1)
}
static int s_sub32_2(Filter *f) static int s_sub32_2(Filter *f) { SCAN32(f, 2) }
{
SCAN32(f, 2)
}
static int s_sub32_3(Filter *f) static int s_sub32_3(Filter *f) { SCAN32(f, 3) }
{
SCAN32(f, 3)
}
static int s_sub32_4(Filter *f)
{
SCAN32(f, 4)
}
static int s_sub32_4(Filter *f) { SCAN32(f, 4) }
#undef SUB #undef SUB
#undef ADD #undef ADD
+15 -57
View File
@@ -25,88 +25,46 @@
<markus@oberhumer.com> <ezerotven+github@gmail.com> <markus@oberhumer.com> <ezerotven+github@gmail.com>
*/ */
/************************************************************************* /*************************************************************************
// //
**************************************************************************/ **************************************************************************/
#include "sub.hh" #include "sub.hh"
#define SUB8(f, N) SUB(f, N, unsigned char, get_8, set_8) #define SUB8(f, N) SUB(f, N, unsigned char, get_8, set_8)
#define ADD8(f, N) ADD(f, N, unsigned char, get_8, set_8) #define ADD8(f, N) ADD(f, N, unsigned char, get_8, set_8)
#define SCAN8(f, N) SCAN(f, N, unsigned char, get_8, set_8) #define SCAN8(f, N) SCAN(f, N, unsigned char, get_8, set_8)
/************************************************************************* /*************************************************************************
// //
**************************************************************************/ **************************************************************************/
// filter // filter
static int f_sub8_1(Filter *f) static int f_sub8_1(Filter *f) { SUB8(f, 1) }
{
SUB8(f, 1)
}
static int f_sub8_2(Filter *f) static int f_sub8_2(Filter *f) { SUB8(f, 2) }
{
SUB8(f, 2)
}
static int f_sub8_3(Filter *f) static int f_sub8_3(Filter *f) { SUB8(f, 3) }
{
SUB8(f, 3)
}
static int f_sub8_4(Filter *f)
{
SUB8(f, 4)
}
static int f_sub8_4(Filter *f) { SUB8(f, 4) }
// unfilter // unfilter
static int u_sub8_1(Filter *f) static int u_sub8_1(Filter *f) { ADD8(f, 1) }
{
ADD8(f, 1)
}
static int u_sub8_2(Filter *f) static int u_sub8_2(Filter *f) { ADD8(f, 2) }
{
ADD8(f, 2)
}
static int u_sub8_3(Filter *f) static int u_sub8_3(Filter *f) { ADD8(f, 3) }
{
ADD8(f, 3)
}
static int u_sub8_4(Filter *f)
{
ADD8(f, 4)
}
static int u_sub8_4(Filter *f) { ADD8(f, 4) }
// scan // scan
static int s_sub8_1(Filter *f) static int s_sub8_1(Filter *f) { SCAN8(f, 1) }
{
SCAN8(f, 1)
}
static int s_sub8_2(Filter *f) static int s_sub8_2(Filter *f) { SCAN8(f, 2) }
{
SCAN8(f, 2)
}
static int s_sub8_3(Filter *f) static int s_sub8_3(Filter *f) { SCAN8(f, 3) }
{
SCAN8(f, 3)
}
static int s_sub8_4(Filter *f)
{
SCAN8(f, 4)
}
static int s_sub8_4(Filter *f) { SCAN8(f, 4) }
#undef SUB #undef SUB
#undef ADD #undef ADD
+48 -115
View File
@@ -25,158 +25,91 @@
<markus@oberhumer.com> <ezerotven+github@gmail.com> <markus@oberhumer.com> <ezerotven+github@gmail.com>
*/ */
/************************************************************************* /*************************************************************************
// 16-bit swaptrick ("naive") // 16-bit swaptrick ("naive")
**************************************************************************/ **************************************************************************/
#define SW16(f, cond, get, set) \ #define SW16(f, cond, get, set) \
byte *b = f->buf; \ byte *b = f->buf; \
byte *b_end = b + f->buf_len - 3; \ byte *b_end = b + f->buf_len - 3; \
do { \ do { \
if (cond) \ if (cond) { \
{ \ b += 1; \
b += 1; \ unsigned a = (unsigned) (b - f->buf); \
unsigned a = (unsigned) (b - f->buf); \ f->lastcall = a; \
f->lastcall = a; \ set(b, get(b)); \
set(b, get(b)); \ f->calls++; \
f->calls++; \ b += 2 - 1; \
b += 2 - 1; \ } \
} \ } while (++b < b_end); \
} while (++b < b_end); \ if (f->lastcall) \
if (f->lastcall) f->lastcall += 2; \ f->lastcall += 2; \
return 0; return 0;
// filter // filter
static int f_sw16_e8(Filter *f) static int f_sw16_e8(Filter *f) { SW16(f, (*b == 0xe8), get_le16, set_be16) }
{
SW16(f, (*b == 0xe8), get_le16, set_be16)
}
static int f_sw16_e9(Filter *f) static int f_sw16_e9(Filter *f) { SW16(f, (*b == 0xe9), get_le16, set_be16) }
{
SW16(f, (*b == 0xe9), get_le16, set_be16)
}
static int f_sw16_e8e9(Filter *f)
{
SW16(f, (*b == 0xe8 || *b == 0xe9), get_le16, set_be16)
}
static int f_sw16_e8e9(Filter *f) { SW16(f, (*b == 0xe8 || *b == 0xe9), get_le16, set_be16) }
// unfilter // unfilter
static int u_sw16_e8(Filter *f) static int u_sw16_e8(Filter *f) { SW16(f, (*b == 0xe8), get_be16, set_le16) }
{
SW16(f, (*b == 0xe8), get_be16, set_le16)
}
static int u_sw16_e9(Filter *f) static int u_sw16_e9(Filter *f) { SW16(f, (*b == 0xe9), get_be16, set_le16) }
{
SW16(f, (*b == 0xe9), get_be16, set_le16)
}
static int u_sw16_e8e9(Filter *f)
{
SW16(f, (*b == 0xe8 || *b == 0xe9), get_be16, set_le16)
}
static int u_sw16_e8e9(Filter *f) { SW16(f, (*b == 0xe8 || *b == 0xe9), get_be16, set_le16) }
// scan // scan
static int s_sw16_e8(Filter *f) static int s_sw16_e8(Filter *f) { SW16(f, (*b == 0xe8), get_le16, set_dummy) }
{
SW16(f, (*b == 0xe8), get_le16, set_dummy)
}
static int s_sw16_e9(Filter *f) static int s_sw16_e9(Filter *f) { SW16(f, (*b == 0xe9), get_le16, set_dummy) }
{
SW16(f, (*b == 0xe9), get_le16, set_dummy)
}
static int s_sw16_e8e9(Filter *f)
{
SW16(f, (*b == 0xe8 || *b == 0xe9), get_le16, set_dummy)
}
static int s_sw16_e8e9(Filter *f) { SW16(f, (*b == 0xe8 || *b == 0xe9), get_le16, set_dummy) }
#undef SW16 #undef SW16
/************************************************************************* /*************************************************************************
// 32-bit swaptrick ("naive") // 32-bit swaptrick ("naive")
**************************************************************************/ **************************************************************************/
#define SW32(f, cond, get, set) \ #define SW32(f, cond, get, set) \
byte *b = f->buf; \ byte *b = f->buf; \
byte *b_end = b + f->buf_len - 5; \ byte *b_end = b + f->buf_len - 5; \
do { \ do { \
if (cond) \ if (cond) { \
{ \ b += 1; \
b += 1; \ unsigned a = (unsigned) (b - f->buf); \
unsigned a = (unsigned) (b - f->buf); \ f->lastcall = a; \
f->lastcall = a; \ set(b, get(b)); \
set(b, get(b)); \ f->calls++; \
f->calls++; \ b += 4 - 1; \
b += 4 - 1; \ } \
} \ } while (++b < b_end); \
} while (++b < b_end); \ if (f->lastcall) \
if (f->lastcall) f->lastcall += 4; \ f->lastcall += 4; \
return 0; return 0;
// filter // filter
static int f_sw32_e8(Filter *f) static int f_sw32_e8(Filter *f) { SW32(f, (*b == 0xe8), get_le32, set_be32) }
{
SW32(f, (*b == 0xe8), get_le32, set_be32)
}
static int f_sw32_e9(Filter *f) static int f_sw32_e9(Filter *f) { SW32(f, (*b == 0xe9), get_le32, set_be32) }
{
SW32(f, (*b == 0xe9), get_le32, set_be32)
}
static int f_sw32_e8e9(Filter *f)
{
SW32(f, (*b == 0xe8 || *b == 0xe9), get_le32, set_be32)
}
static int f_sw32_e8e9(Filter *f) { SW32(f, (*b == 0xe8 || *b == 0xe9), get_le32, set_be32) }
// unfilter // unfilter
static int u_sw32_e8(Filter *f) static int u_sw32_e8(Filter *f) { SW32(f, (*b == 0xe8), get_be32, set_le32) }
{
SW32(f, (*b == 0xe8), get_be32, set_le32)
}
static int u_sw32_e9(Filter *f) static int u_sw32_e9(Filter *f) { SW32(f, (*b == 0xe9), get_be32, set_le32) }
{
SW32(f, (*b == 0xe9), get_be32, set_le32)
}
static int u_sw32_e8e9(Filter *f)
{
SW32(f, (*b == 0xe8 || *b == 0xe9), get_be32, set_le32)
}
static int u_sw32_e8e9(Filter *f) { SW32(f, (*b == 0xe8 || *b == 0xe9), get_be32, set_le32) }
// scan // scan
static int s_sw32_e8(Filter *f) static int s_sw32_e8(Filter *f) { SW32(f, (*b == 0xe8), get_le32, set_dummy) }
{
SW32(f, (*b == 0xe8), get_le32, set_dummy)
}
static int s_sw32_e9(Filter *f) static int s_sw32_e9(Filter *f) { SW32(f, (*b == 0xe9), get_le32, set_dummy) }
{
SW32(f, (*b == 0xe9), get_le32, set_dummy)
}
static int s_sw32_e8e9(Filter *f)
{
SW32(f, (*b == 0xe8 || *b == 0xe9), get_le32, set_dummy)
}
static int s_sw32_e8e9(Filter *f) { SW32(f, (*b == 0xe8 || *b == 0xe9), get_le32, set_dummy) }
#undef SW32 #undef SW32
+17 -4
View File
@@ -81,11 +81,11 @@ static_assert(sizeof(void *) == 8);
#undef snprintf #undef snprintf
#undef vsnprintf #undef vsnprintf
#define HAVE_STDINT_H 1 #define HAVE_STDINT_H 1
#define ACC_WANT_ACC_INCD_H 1 #define ACC_WANT_ACC_INCD_H 1
#define ACC_WANT_ACC_INCE_H 1 #define ACC_WANT_ACC_INCE_H 1
#define ACC_WANT_ACC_LIB_H 1 #define ACC_WANT_ACC_LIB_H 1
#define ACC_WANT_ACC_CXX_H 1 #define ACC_WANT_ACC_CXX_H 1
#include "miniacc.h" #include "miniacc.h"
#if (ACC_CC_MSC) #if (ACC_CC_MSC)
#include <intrin.h> #include <intrin.h>
@@ -109,6 +109,18 @@ static_assert(sizeof(void *) == 8);
#include <mutex> #include <mutex>
#endif #endif
// sanitizers
#if !defined(__SANITIZE_ADDRESS__) && defined(__has_feature)
#if __has_feature(address_sanitizer)
#define __SANITIZE_ADDRESS__ 1
#endif
#endif
#if !defined(__SANITIZE_MEMORY__) && defined(__has_feature)
#if __has_feature(memory_sanitizer)
#define __SANITIZE_MEMORY__ 1
#endif
#endif
// UPX vendor git submodule headers // UPX vendor git submodule headers
#include <doctest/doctest/parts/doctest_fwd.h> #include <doctest/doctest/parts/doctest_fwd.h>
#if WITH_BOOST_PFR #if WITH_BOOST_PFR
@@ -121,7 +133,8 @@ static_assert(sizeof(void *) == 8);
#ifndef WITH_VALGRIND #ifndef WITH_VALGRIND
#define WITH_VALGRIND 1 #define WITH_VALGRIND 1
#endif #endif
#if defined(__SANITIZE_ADDRESS__) || defined(_WIN32) || !defined(__GNUC__) #if defined(__SANITIZE_ADDRESS__) || defined(__SANITIZE_MEMORY__) || defined(_WIN32) || \
!defined(__GNUC__)
#undef WITH_VALGRIND #undef WITH_VALGRIND
#endif #endif
#if WITH_VALGRIND #if WITH_VALGRIND
+109 -11
View File
@@ -103,17 +103,16 @@ struct PackerNames {
size_t names_count; size_t names_count;
const Options *o; const Options *o;
PackerNames() : names_count(0), o(nullptr) {} PackerNames() : names_count(0), o(nullptr) {}
void add(const Packer *packer) { void add(const PackerBase *pb) {
assert(names_count < 64); assert_noexcept(names_count < 64);
names[names_count].fname = packer->getFullName(o); names[names_count].fname = pb->getFullName(o);
names[names_count].sname = packer->getName(); names[names_count].sname = pb->getName();
names_count++; names_count++;
} }
static Packer *visit(Packer *packer, void *user) { static tribool visit(PackerBase *pb, void *user) {
PackerNames *self = (PackerNames *) user; PackerNames *self = (PackerNames *) user;
self->add(packer); self->add(pb);
delete packer; return false;
return nullptr;
} }
static int __acc_cdecl_qsort cmp_fname(const void *a, const void *b) { static int __acc_cdecl_qsort cmp_fname(const void *a, const void *b) {
return strcmp(((const Entry *) a)->fname, ((const Entry *) b)->fname); return strcmp(((const Entry *) a)->fname, ((const Entry *) b)->fname);
@@ -129,8 +128,8 @@ static void list_all_packers(FILE *f, int verbose) {
o.reset(); o.reset();
PackerNames pn; PackerNames pn;
pn.o = &o; pn.o = &o;
PackMaster::visitAllPackers(PackerNames::visit, nullptr, &o, &pn); (void) PackMaster::visitAllPackers(PackerNames::visit, nullptr, &o, &pn);
qsort(pn.names, pn.names_count, sizeof(PackerNames::Entry), PackerNames::cmp_fname); upx_qsort(pn.names, pn.names_count, sizeof(PackerNames::Entry), PackerNames::cmp_fname);
size_t pos = 0; size_t pos = 0;
for (size_t i = 0; i < pn.names_count; ++i) { for (size_t i = 0; i < pn.names_count; ++i) {
const char *fn = pn.names[i].fname; const char *fn = pn.names[i].fname;
@@ -186,7 +185,6 @@ void show_help(int verbose) {
con_fprintf(f, con_fprintf(f,
" -q be quiet -v be verbose\n" " -q be quiet -v be verbose\n"
" -oFILE write output to 'FILE'\n" " -oFILE write output to 'FILE'\n"
//" -f force overwrite of output files and compression of suspicious files\n"
" -f force compression of suspicious files\n" " -f force compression of suspicious files\n"
"%s%s" "%s%s"
, (verbose == 0) ? " -k keep backup files\n" : "" , (verbose == 0) ? " -k keep backup files\n" : ""
@@ -223,6 +221,19 @@ void show_help(int verbose) {
" --overlay=skip don't compress a file with an overlay\n" " --overlay=skip don't compress a file with an overlay\n"
"\n"); "\n");
fg = con_fg(f, FG_YELLOW); fg = con_fg(f, FG_YELLOW);
con_fprintf(f, "File system options:\n");
fg = con_fg(f, fg);
con_fprintf(f,
" --force-overwrite force overwrite of output files\n"
#if defined(__unix__)
" --link preserve hard links (Unix only) [USE WITH CARE]\n"
" --no-link do not preserve hard links but rename files [default]\n"
#endif
" --no-mode do not preserve file mode (aka permissions)\n"
" --no-owner do not preserve file ownership\n"
" --no-time do not preserve file timestamp\n"
"\n");
fg = con_fg(f, FG_YELLOW);
con_fprintf(f, "Options for djgpp2/coff:\n"); con_fprintf(f, "Options for djgpp2/coff:\n");
fg = con_fg(f, fg); fg = con_fg(f, fg);
con_fprintf(f, con_fprintf(f,
@@ -424,4 +435,91 @@ void show_version(bool one_line) {
// clang-format on // clang-format on
} }
/*************************************************************************
// sysinfo
// undocumented and subject to change
**************************************************************************/
void show_sysinfo(const char *options_var) {
FILE *f = con_term;
show_header();
if (opt->verbose >= 1) {
con_fprintf(f, "UPX version: ");
fflush(f);
show_version(true);
}
fflush(stdout);
// Compilation Flags
if (opt->verbose >= 2) {
size_t cf_count = 0;
auto cf_print = [f, &cf_count](const char *name, const char *fmt, upx_int64_t v) noexcept {
if (cf_count++ == 0)
con_fprintf(f, "\nCompilation flags:\n");
con_fprintf(f, " %s = ", name);
con_fprintf(f, fmt, v);
con_fprintf(f, "\n");
};
// OS and libc
#if defined(WINVER)
cf_print("WINVER", "0x%04llx", WINVER + 0);
#endif
#if defined(_WIN32_WINNT)
cf_print("_WIN32_WINNT", "0x%04llx", _WIN32_WINNT + 0);
#endif
#if defined(__MSVCRT_VERSION__)
cf_print("__MSVCRT_VERSION__", "0x%04llx", __MSVCRT_VERSION__ + 0);
#endif
#if defined(_USE_MINGW_ANSI_STDIO)
cf_print("_USE_MINGW_ANSI_STDIO", "%lld", _USE_MINGW_ANSI_STDIO + 0);
#endif
#if defined(__USE_MINGW_ANSI_STDIO)
cf_print("__USE_MINGW_ANSI_STDIO", "%lld", __USE_MINGW_ANSI_STDIO + 0);
#endif
#if defined(__GLIBC__)
cf_print("__GLIBC__", "%lld", __GLIBC__ + 0);
#endif
#if defined(__GLIBC_MINOR__)
cf_print("__GLIBC_MINOR__", "%lld", __GLIBC_MINOR__ + 0);
#endif
// compiler
#if defined(_MSC_VER) && defined(_MSC_FULL_VER)
cf_print("_MSC_VER", "%lld", _MSC_VER + 0);
cf_print("_MSC_FULL_VER", "%lld", _MSC_FULL_VER + 0);
#endif
UNUSED(cf_count);
UNUSED(cf_print);
}
// run-time
#if defined(HAVE_LOCALTIME) && defined(HAVE_GMTIME)
{
auto tm2str = [](char *s, size_t size, const struct tm *tmp) noexcept {
snprintf(s, size, "%04d-%02d-%02d %02d:%02d:%02d", (int) tmp->tm_year + 1900,
(int) tmp->tm_mon + 1, (int) tmp->tm_mday, (int) tmp->tm_hour,
(int) tmp->tm_min, (int) tmp->tm_sec);
};
char s[40];
const time_t t = time(nullptr);
tm2str(s, sizeof(s), localtime(&t));
con_fprintf(f, "\n");
con_fprintf(f, "Local time is: %s\n", s);
tm2str(s, sizeof(s), gmtime(&t));
con_fprintf(f, "UTC time is: %s\n", s);
}
#endif
if (options_var && options_var[0]) {
const char *e = getenv(options_var);
con_fprintf(f, "\n");
if (e && e[0])
con_fprintf(f, "Contents of environment variable %s: '%s'\n\n", options_var, e);
else
con_fprintf(f, "Environment variable '%s' is not set.\n\n", options_var);
}
}
/* vim:set ts=4 sw=4 et: */ /* vim:set ts=4 sw=4 et: */
+2 -2
View File
@@ -55,8 +55,8 @@ LeFile::~LeFile() noexcept {
} }
#define objects ih.object_table_entries #define objects ih.object_table_entries
#define pages ih.memory_pages #define pages ih.memory_pages
#define mps ih.memory_page_size #define mps ih.memory_page_size
void LeFile::readObjectTable() { void LeFile::readObjectTable() {
soobject_table = objects; soobject_table = objects;
+5 -4
View File
@@ -329,6 +329,7 @@ ElfLinker::Section *ElfLinker::addSection(const char *sname, const void *sdata,
assert(sname[strlen(sname) - 1] != ':'); assert(sname[strlen(sname) - 1] != ':');
assert(findSection(sname, false) == nullptr); assert(findSection(sname, false) == nullptr);
Section *sec = new Section(sname, sdata, slen, p2align); Section *sec = new Section(sname, sdata, slen, p2align);
sec->sort_id = nsections;
sections[nsections++] = sec; sections[nsections++] = sec;
return sec; return sec;
} }
@@ -726,8 +727,8 @@ void ElfLinkerM68k::relocate1(const Relocation *rel, byte *location, upx_uint64_
void ElfLinkerMipsBE::relocate1(const Relocation *rel, byte *location, upx_uint64_t value, void ElfLinkerMipsBE::relocate1(const Relocation *rel, byte *location, upx_uint64_t value,
const char *type) { const char *type) {
#define MIPS_HI(a) (((a) >> 16) + (((a) &0x8000) >> 15)) #define MIPS_HI(a) (((a) >> 16) + (((a) &0x8000) >> 15))
#define MIPS_LO(a) ((a) &0xffff) #define MIPS_LO(a) ((a) &0xffff)
#define MIPS_PC16(a) ((a) >> 2) #define MIPS_PC16(a) ((a) >> 2)
#define MIPS_PC26(a) (((a) &0x0fffffff) >> 2) #define MIPS_PC26(a) (((a) &0x0fffffff) >> 2)
@@ -753,8 +754,8 @@ void ElfLinkerMipsBE::relocate1(const Relocation *rel, byte *location, upx_uint6
void ElfLinkerMipsLE::relocate1(const Relocation *rel, byte *location, upx_uint64_t value, void ElfLinkerMipsLE::relocate1(const Relocation *rel, byte *location, upx_uint64_t value,
const char *type) { const char *type) {
#define MIPS_HI(a) (((a) >> 16) + (((a) &0x8000) >> 15)) #define MIPS_HI(a) (((a) >> 16) + (((a) &0x8000) >> 15))
#define MIPS_LO(a) ((a) &0xffff) #define MIPS_LO(a) ((a) &0xffff)
#define MIPS_PC16(a) ((a) >> 2) #define MIPS_PC16(a) ((a) >> 2)
#define MIPS_PC26(a) (((a) &0x0fffffff) >> 2) #define MIPS_PC26(a) (((a) &0x0fffffff) >> 2)
+1
View File
@@ -119,6 +119,7 @@ struct ElfLinker::Section : private noncopyable {
void *input = nullptr; void *input = nullptr;
byte *output = nullptr; byte *output = nullptr;
unsigned size = 0; unsigned size = 0;
unsigned sort_id = 0; // for qsort()
upx_uint64_t offset = 0; upx_uint64_t offset = 0;
unsigned p2align = 0; // log2 unsigned p2align = 0; // log2
Section *next = nullptr; Section *next = nullptr;
+118 -77
View File
@@ -64,7 +64,7 @@ static void handle_opterr(acc_getopt_p g, const char *f, void *v) {
static int exit_code = EXIT_OK; static int exit_code = EXIT_OK;
#if (WITH_GUI) #if (WITH_GUI)
__acc_static_noinline void do_exit(void) { throw exit_code; } static noinline void do_exit(void) { throw exit_code; }
#else #else
#if defined(__GNUC__) #if defined(__GNUC__)
static void do_exit(void) __attribute__((__noreturn__)); static void do_exit(void) __attribute__((__noreturn__));
@@ -105,14 +105,14 @@ static bool set_eec(int ec, int *eec) {
bool main_set_exit_code(int ec) { return set_eec(ec, &exit_code); } bool main_set_exit_code(int ec) { return set_eec(ec, &exit_code); }
__acc_static_noinline void e_exit(int ec) { static noinline void e_exit(int ec) {
if (opt->debug.getopt_throw_instead_of_exit) if (opt->debug.getopt_throw_instead_of_exit)
throw ec; throw ec;
(void) main_set_exit_code(ec); (void) main_set_exit_code(ec);
do_exit(); do_exit();
} }
__acc_static_noinline void e_usage(void) { static noinline void e_usage(void) {
if (opt->debug.getopt_throw_instead_of_exit) if (opt->debug.getopt_throw_instead_of_exit)
throw EXIT_USAGE; throw EXIT_USAGE;
show_usage(); show_usage();
@@ -160,7 +160,7 @@ static void check_not_both(bool e1, bool e2, const char *c1, const char *c2) {
} }
} }
static void check_options(int i, int argc) { static void check_and_update_options(int i, int argc) {
assert(i <= argc); assert(i <= argc);
if (opt->cmd != CMD_COMPRESS) { if (opt->cmd != CMD_COMPRESS) {
@@ -198,6 +198,16 @@ static void check_options(int i, int argc) {
e_usage(); e_usage();
} }
} }
check_not_both(opt->force_overwrite, opt->preserve_link, "--force-overwrite", "--link");
check_not_both(opt->to_stdout, opt->preserve_link, "--stdout", "--link");
#if defined(__unix__)
static_assert(HAVE_LSTAT);
#else
// preserve_link is currently silently ignored on non-Unix platforms
// (we may revisit this decision later if there is some actual use-case)
opt->preserve_link = false;
#endif
} }
/************************************************************************* /*************************************************************************
@@ -210,7 +220,7 @@ static void e_help(void) {
} }
static void set_term(FILE *f) { static void set_term(FILE *f) {
if (f) if (f != nullptr)
con_term = f; con_term = f;
else else
con_term = acc_isatty(STDIN_FILENO) ? stderr : stdout; con_term = acc_isatty(STDIN_FILENO) ? stderr : stdout;
@@ -364,6 +374,9 @@ static int do_option(int optc, const char *arg) {
case 909: case 909:
set_cmd(CMD_FILEINFO); set_cmd(CMD_FILEINFO);
break; break;
case 910:
set_cmd(CMD_SYSINFO);
break;
case 'h': case 'h':
case 'H': case 'H':
case '?': case '?':
@@ -521,6 +534,14 @@ static int do_option(int optc, const char *arg) {
case 519: case 519:
opt->no_env = true; opt->no_env = true;
break; break;
case 530:
// NOTE: only use "preserve_link" if you really need it, e.g. it can fail
// with ETXTBSY and other unexpected errors; renaming files is much safer
opt->preserve_link = true;
break;
case 531:
opt->preserve_link = false;
break;
case 526: case 526:
opt->preserve_mode = false; opt->preserve_mode = false;
break; break;
@@ -652,54 +673,27 @@ static int do_option(int optc, const char *arg) {
case 564: case 564:
opt->cpu_x86 = opt->CPU_486; opt->cpu_x86 = opt->CPU_486;
break; break;
//
// atari/tos
case 650:
opt->atari_tos.split_segments = true;
break;
// darwin/macho
case 690:
opt->darwin_macho.force_macos = true;
break;
// dos/exe
case 600: case 600:
opt->dos_exe.force_stub = true; opt->dos_exe.force_stub = true;
break; break;
case 601: case 601:
opt->dos_exe.no_reloc = true; opt->dos_exe.no_reloc = true;
break; break;
// djgpp2/coff
case 610: case 610:
opt->djgpp2_coff.coff = true; opt->djgpp2_coff.coff = true;
break; break;
case 620: // o_unix
opt->watcom_le.le = true;
break;
case 630:
opt->win32_pe.compress_exports = 1;
if (mfx_optarg && mfx_optarg[0])
getoptvar(&opt->win32_pe.compress_exports, 0, 1, arg);
// printf("compress_exports: %d\n", opt->win32_pe.compress_exports);
break;
case 631:
opt->win32_pe.compress_icons = 1;
if (mfx_optarg && mfx_optarg[0])
getoptvar(&opt->win32_pe.compress_icons, 0, 3, arg);
// printf("compress_icons: %d\n", opt->win32_pe.compress_icons);
break;
case 632:
opt->win32_pe.compress_resources = 1;
if (mfx_optarg && mfx_optarg[0])
getoptvar(&opt->win32_pe.compress_resources, 0, 1, arg);
// printf("compress_resources: %d\n", opt->win32_pe.compress_resources);
break;
case 633:
// opt->win32_pe.strip_loadconf - OBSOLETE - IGNORED
break;
case 634:
opt->win32_pe.strip_relocs = 1;
if (mfx_optarg && mfx_optarg[0])
getoptvar(&opt->win32_pe.strip_relocs, 0, 1, arg);
// printf("strip_relocs: %d\n", opt->win32_pe.strip_relocs);
break;
case 635:
if (!mfx_optarg || !mfx_optarg[0])
e_optarg(arg);
opt->win32_pe.keep_resource = mfx_optarg;
break;
case 650:
opt->atari_tos.split_segments = true;
break;
case 660: case 660:
getoptvar(&opt->o_unix.blocksize, 8192u, ~0u, arg); getoptvar(&opt->o_unix.blocksize, 8192u, ~0u, arg);
break; break;
@@ -727,6 +721,19 @@ static int do_option(int optc, const char *arg) {
case 669: // OpenBSD case 669: // OpenBSD
opt->o_unix.osabi0 = Elf32_Ehdr::ELFOSABI_OPENBSD; opt->o_unix.osabi0 = Elf32_Ehdr::ELFOSABI_OPENBSD;
break; break;
case 674:
opt->o_unix.unmap_all_pages = true; // val ?
break;
case 675:
opt->o_unix.preserve_build_id = true;
break;
case 676:
opt->o_unix.android_shlib = true;
break;
case 677:
opt->o_unix.force_pie = true;
break;
// ps1/exe
case 670: case 670:
opt->ps1_exe.boot_only = true; opt->ps1_exe.boot_only = true;
break; break;
@@ -740,17 +747,45 @@ static int do_option(int optc, const char *arg) {
case 673: case 673:
opt->ps1_exe.do_8mib = false; opt->ps1_exe.do_8mib = false;
break; break;
case 674: // watcom/le
opt->o_unix.unmap_all_pages = true; // val ? case 620:
opt->watcom_le.le = true;
break; break;
case 675: // win32/pe
opt->o_unix.preserve_build_id = true; case 630:
opt->win32_pe.compress_exports = 1;
if (mfx_optarg && mfx_optarg[0])
getoptvar(&opt->win32_pe.compress_exports, 0, 1, arg);
// printf("compress_exports: %d\n", opt->win32_pe.compress_exports);
break; break;
case 676: case 631:
opt->o_unix.android_shlib = true; opt->win32_pe.compress_icons = 1;
if (mfx_optarg && mfx_optarg[0])
getoptvar(&opt->win32_pe.compress_icons, 0, 3, arg);
// printf("compress_icons: %d\n", opt->win32_pe.compress_icons);
break; break;
case 677: case 632:
opt->o_unix.force_pie = true; opt->win32_pe.compress_resources = 1;
if (mfx_optarg && mfx_optarg[0]) {
int value = 0;
getoptvar(&value, 0, 1, arg);
opt->win32_pe.compress_resources = bool(value);
}
// printf("compress_resources: %d\n", opt->win32_pe.compress_resources);
break;
case 633:
// opt->win32_pe.strip_loadconf - OBSOLETE - IGNORED
break;
case 634:
opt->win32_pe.strip_relocs = 1;
if (mfx_optarg && mfx_optarg[0])
getoptvar(&opt->win32_pe.strip_relocs, 0, 1, arg);
// printf("strip_relocs: %d\n", opt->win32_pe.strip_relocs);
break;
case 635:
if (!mfx_optarg || !mfx_optarg[0])
e_optarg(arg);
opt->win32_pe.keep_resource = mfx_optarg;
break; break;
#if !defined(DOCTEST_CONFIG_DISABLE) #if !defined(DOCTEST_CONFIG_DISABLE)
@@ -786,6 +821,8 @@ int main_get_options(int argc, char **argv) {
{"help", 0, N, 'h' + 256}, // give help {"help", 0, N, 'h' + 256}, // give help
{"license", 0, N, 'L'}, // display software license {"license", 0, N, 'L'}, // display software license
{"list", 0, N, 'l'}, // list compressed exe {"list", 0, N, 'l'}, // list compressed exe
{"sysinfo", 0x90, N, 910}, // display system info // undocumented and subject to change
{"sys-info", 0x90, N, 910}, // display system info // undocumented and subject to change
{"test", 0, N, 't'}, // test compressed file integrity {"test", 0, N, 't'}, // test compressed file integrity
{"uncompress", 0, N, 'd'}, // decompress {"uncompress", 0, N, 'd'}, // decompress
{"version", 0, N, 'V' + 256}, // display version number {"version", 0, N, 'V' + 256}, // display version number
@@ -794,8 +831,10 @@ int main_get_options(int argc, char **argv) {
{"force", 0, N, 'f'}, // force overwrite of output files {"force", 0, N, 'f'}, // force overwrite of output files
{"force-compress", 0, N, 'f'}, // and compression of suspicious files {"force-compress", 0, N, 'f'}, // and compression of suspicious files
{"force-overwrite", 0x90, N, 529}, // force overwrite of output files {"force-overwrite", 0x90, N, 529}, // force overwrite of output files
{"link", 0x90, N, 530}, // preserve hard link
{"info", 0, N, 'i'}, // info mode {"info", 0, N, 'i'}, // info mode
{"no-env", 0x10, N, 519}, // no environment var {"no-env", 0x10, N, 519}, // no environment var
{"no-link", 0x90, N, 531}, // do not preserve hard link [default]
{"no-mode", 0x10, N, 526}, // do not preserve mode (permissions) {"no-mode", 0x10, N, 526}, // do not preserve mode (permissions)
{"no-owner", 0x10, N, 527}, // do not preserve ownership {"no-owner", 0x10, N, 527}, // do not preserve ownership
{"no-progress", 0, N, 516}, // no progress bar {"no-progress", 0, N, 516}, // no progress bar
@@ -816,8 +855,8 @@ int main_get_options(int argc, char **argv) {
{"fake-stub-version", 0x31, N, 542}, // for internal debugging {"fake-stub-version", 0x31, N, 542}, // for internal debugging
{"fake-stub-year", 0x31, N, 543}, // for internal debugging {"fake-stub-year", 0x31, N, 543}, // for internal debugging
{"disable-random-id", 0x90, N, 545}, // for internal debugging {"disable-random-id", 0x90, N, 545}, // for internal debugging
{"debug-use-random-method", 0x90, N, 546}, // for internal debugging {"debug-use-random-method", 0x90, N, 546}, // for internal debugging / fuzz testing
{"debug-use-random-filter", 0x90, N, 547}, // for internal debugging {"debug-use-random-filter", 0x90, N, 547}, // for internal debugging / fuzz testing
// backup options // backup options
{"backup", 0x10, N, 'k'}, {"backup", 0x10, N, 'k'},
@@ -882,15 +921,15 @@ int main_get_options(int argc, char **argv) {
{"crp-zlib-st", 0x31, N, 823}, {"crp-zlib-st", 0x31, N, 823},
// atari/tos // atari/tos
{"split-segments", 0x10, N, 650}, {"split-segments", 0x90, N, 650},
// darwin/macho
{"force-macos", 0x90, N, 690}, // undocumented temporary until we fix macOS 13+
// djgpp2/coff // djgpp2/coff
{"coff", 0x10, N, 610}, // produce COFF output {"coff", 0x90, N, 610}, // produce COFF output
// dos/com // dos/exe
// dos/exe //{"force-stub", 0x10, N, 600},
//{"force-stub", 0x10, 0, 600}, {"no-reloc", 0x10, N, 601}, // no reloc. record into packer dos/exe
{"no-reloc", 0x10, N, 601}, // no reloc. record into packer dos/exe // o_unix
// dos/sys
// unix
{"blocksize", 0x31, N, 660}, // --blocksize= {"blocksize", 0x31, N, 660}, // --blocksize=
{"force-execve", 0x90, N, 661}, // force linux/386 execve format {"force-execve", 0x90, N, 661}, // force linux/386 execve format
{"is_ptinterp", 0x10, N, 663}, // linux/elf386 PT_INTERP program {"is_ptinterp", 0x10, N, 663}, // linux/elf386 PT_INTERP program
@@ -908,21 +947,21 @@ int main_get_options(int argc, char **argv) {
{"preserve-build-id", 0, N, 675}, {"preserve-build-id", 0, N, 675},
{"android-shlib", 0, N, 676}, {"android-shlib", 0, N, 676},
{"force-pie", 0x90, N, 677}, {"force-pie", 0x90, N, 677},
// ps1/exe
{"boot-only", 0x90, N, 670},
{"no-align", 0x90, N, 671},
{"8-bit", 0x90, N, 672},
{"8mib-ram", 0x90, N, 673},
{"8mb-ram", 0x90, N, 673},
// watcom/le // watcom/le
{"le", 0x10, N, 620}, // produce LE output {"le", 0x90, N, 620}, // produce LE output
// win32/pe // win32/pe
{"compress-exports", 2, N, 630}, {"compress-exports", 2, N, 630},
{"compress-icons", 2, N, 631}, {"compress-icons", 2, N, 631},
{"compress-resources", 2, N, 632}, {"compress-resources", 2, N, 632},
{"strip-loadconf", 0x12, N, 633}, // OBSOLETE - IGNORED {"strip-loadconf", 0x12, N, 633}, // OBSOLETE - IGNORED
{"strip-relocs", 0x12, N, 634}, {"strip-relocs", 0x12, N, 634},
{"keep-resource", 0x31, N, 635}, {"keep-resource", 0x31, N, 635},
// ps1/exe
{"boot-only", 0x10, N, 670},
{"no-align", 0x10, N, 671},
{"8-bit", 0x10, N, 672},
{"8mib-ram", 0x10, N, 673},
{"8mb-ram", 0x10, N, 673},
#if !defined(DOCTEST_CONFIG_DISABLE) #if !defined(DOCTEST_CONFIG_DISABLE)
// [doctest] Query flags - the program quits after them. Available: // [doctest] Query flags - the program quits after them. Available:
@@ -1028,8 +1067,6 @@ void main_get_envoptions() {
{"no-lzma", 0x10, N, 722}, // disable all_methods_use_lzma {"no-lzma", 0x10, N, 722}, // disable all_methods_use_lzma
{"prefer-nrv", 0x10, N, 723}, {"prefer-nrv", 0x10, N, 723},
{"prefer-ucl", 0x10, N, 724}, {"prefer-ucl", 0x10, N, 724},
// compression settings
// compression runtime parameters
// win32/pe // win32/pe
{"compress-exports", 2, N, 630}, {"compress-exports", 2, N, 630},
@@ -1144,7 +1181,7 @@ static void first_options(int argc, char **argv) {
// main entry point // main entry point
**************************************************************************/ **************************************************************************/
int upx_main(int argc, char *argv[]) { int upx_main(int argc, char *argv[]) may_throw {
int i; int i;
static char default_argv0[] = "upx"; static char default_argv0[] = "upx";
assert(argc >= 1); // sanity check assert(argc >= 1); // sanity check
@@ -1227,14 +1264,18 @@ int upx_main(int argc, char *argv[]) {
break; break;
case CMD_FILEINFO: case CMD_FILEINFO:
break; break;
case CMD_LICENSE: case CMD_SYSINFO:
show_license(); show_sysinfo(OPTIONS_VAR);
e_exit(EXIT_OK); e_exit(EXIT_OK);
break; break;
case CMD_HELP: case CMD_HELP:
show_help(1); show_help(1);
e_exit(EXIT_OK); e_exit(EXIT_OK);
break; break;
case CMD_LICENSE:
show_license();
e_exit(EXIT_OK);
break;
case CMD_VERSION: case CMD_VERSION:
show_version(); show_version();
e_exit(EXIT_OK); e_exit(EXIT_OK);
@@ -1248,7 +1289,7 @@ int upx_main(int argc, char *argv[]) {
if (argc == 1) if (argc == 1)
e_help(); e_help();
set_term(stderr); set_term(stderr);
check_options(i, argc); check_and_update_options(i, argc);
int num_files = argc - i; int num_files = argc - i;
if (num_files < 1) { if (num_files < 1) {
if (opt->verbose >= 2) if (opt->verbose >= 2)
@@ -1304,7 +1345,7 @@ int _dowildcard = -1;
} }
#endif #endif
int __acc_cdecl_main main(int argc, char *argv[]) { int __acc_cdecl_main main(int argc, char *argv[]) /*noexcept*/ {
#if 0 && (ACC_OS_DOS32) && defined(__DJGPP__) #if 0 && (ACC_OS_DOS32) && defined(__DJGPP__)
// LFN=n may cause problems with 2.03's _rename and mkdir under WinME // LFN=n may cause problems with 2.03's _rename and mkdir under WinME
putenv("LFN=y"); putenv("LFN=y");
+2
View File
@@ -25,6 +25,8 @@
http://www.oberhumer.com/ http://www.oberhumer.com/
*/ */
/* clang-format off */
#ifndef __ACC_H_INCLUDED #ifndef __ACC_H_INCLUDED
#define __ACC_H_INCLUDED 1 #define __ACC_H_INCLUDED 1
#define ACC_VERSION 20230625L #define ACC_VERSION 20230625L
+21 -2
View File
@@ -53,6 +53,7 @@ void Options::reset() noexcept {
o->preserve_mode = true; o->preserve_mode = true;
o->preserve_ownership = true; o->preserve_ownership = true;
o->preserve_timestamp = true; o->preserve_timestamp = true;
o->verbose = 2;
o->console = CON_FILE; o->console = CON_FILE;
#if (ACC_OS_DOS32) && defined(__DJGPP__) #if (ACC_OS_DOS32) && defined(__DJGPP__)
@@ -62,7 +63,13 @@ void Options::reset() noexcept {
#elif 1 && defined(__linux__) #elif 1 && defined(__linux__)
o->console = CON_INIT; o->console = CON_INIT;
#endif #endif
o->verbose = 2; // support NO_COLOR, see https://no-color.org/
// "... when present and not an empty string (regardless of its value)"
const char *e = getenv("NO_COLOR");
if (e && e[0])
o->console = CON_FILE;
// options for various executable formats
o->o_unix.osabi0 = 3; // 3 == ELFOSABI_LINUX o->o_unix.osabi0 = 3; // 3 == ELFOSABI_LINUX
@@ -81,14 +88,26 @@ void Options::reset() noexcept {
**************************************************************************/ **************************************************************************/
TEST_CASE("Options::reset") { TEST_CASE("Options::reset") {
#define opt DO_NOT_USE_opt
COMPILE_TIME_ASSERT(std::is_standard_layout<Options>::value) COMPILE_TIME_ASSERT(std::is_standard_layout<Options>::value)
COMPILE_TIME_ASSERT(std::is_nothrow_default_constructible<Options>::value) COMPILE_TIME_ASSERT(std::is_nothrow_default_constructible<Options>::value)
COMPILE_TIME_ASSERT(std::is_trivially_copyable<Options>::value) COMPILE_TIME_ASSERT(std::is_trivially_copyable<Options>::value)
Options local_options; Options local_options;
Options *o = &local_options; Options *const o = &local_options;
o->reset(); o->reset();
CHECK(o->o_unix.osabi0 == 3); CHECK(o->o_unix.osabi0 == 3);
//
static_assert(TABLESIZE(o->win32_pe.compress_rt) == 25); // 25 == RT_LAST
CHECK(o->win32_pe.compress_exports);
CHECK(o->win32_pe.compress_icons);
CHECK(o->win32_pe.strip_relocs);
// issue 728
CHECK(o->win32_pe.compress_resources);
for (size_t i = 0; i < 24; i++)
CHECK(o->win32_pe.compress_rt[i]);
CHECK(!o->win32_pe.compress_rt[24]); // 24 == RT_MANIFEST
#undef opt
} }
template <size_t N> template <size_t N>
+27 -22
View File
@@ -47,16 +47,19 @@ enum {
CMD_TEST, CMD_TEST,
CMD_LIST, CMD_LIST,
CMD_FILEINFO, CMD_FILEINFO,
CMD_SYSINFO,
CMD_HELP, CMD_HELP,
CMD_LICENSE, CMD_LICENSE,
CMD_VERSION, CMD_VERSION,
}; };
struct Options final { struct Options final {
int cmd; void reset() noexcept;
int cmd; // CMD_xxx
// compression options // compression options
int method; int method; // M_xxx
bool method_lzma_seen; bool method_lzma_seen;
bool method_nrv2b_seen; bool method_nrv2b_seen;
bool method_nrv2d_seen; bool method_nrv2d_seen;
@@ -81,6 +84,7 @@ struct Options final {
bool no_env; bool no_env;
bool no_progress; bool no_progress;
const char *output_name; const char *output_name;
bool preserve_link;
bool preserve_mode; bool preserve_mode;
bool preserve_ownership; bool preserve_ownership;
bool preserve_timestamp; bool preserve_timestamp;
@@ -88,6 +92,20 @@ struct Options final {
int verbose; int verbose;
bool to_stdout; bool to_stdout;
// overlay handling
enum { SKIP_OVERLAY = 0, COPY_OVERLAY = 1, STRIP_OVERLAY = 2 };
int overlay;
// CPU options for i086/i386
enum {
CPU_DEFAULT = 0,
CPU_8086 = 1,
CPU_286 = 2,
CPU_386 = 3,
CPU_486 = 4,
};
int cpu_x86;
// debug options // debug options
struct { struct {
int debug_level; int debug_level;
@@ -96,14 +114,10 @@ struct Options final {
char fake_stub_version[4 + 1]; // for internal debugging char fake_stub_version[4 + 1]; // for internal debugging
char fake_stub_year[4 + 1]; // for internal debugging char fake_stub_year[4 + 1]; // for internal debugging
bool getopt_throw_instead_of_exit; // for internal doctest checks bool getopt_throw_instead_of_exit; // for internal doctest checks
bool use_random_method; // for internal debugging bool use_random_method; // for internal debugging / fuzz testing
bool use_random_filter; // for internal debugging bool use_random_filter; // for internal debugging / fuzz testing
} debug; } debug;
// overlay handling
enum { SKIP_OVERLAY = 0, COPY_OVERLAY = 1, STRIP_OVERLAY = 2 };
int overlay;
// CRP - Compression Runtime Parameters (undocumented and subject to change) // CRP - Compression Runtime Parameters (undocumented and subject to change)
struct { struct {
lzma_compress_config_t crp_lzma; lzma_compress_config_t crp_lzma;
@@ -118,20 +132,13 @@ struct Options final {
} }
} crp; } crp;
// CPU options for i086/i386
enum {
CPU_DEFAULT = 0,
CPU_8086 = 1,
CPU_286 = 2,
CPU_386 = 3,
CPU_486 = 4,
};
int cpu_x86;
// options for various executable formats // options for various executable formats
struct { struct {
bool split_segments; bool split_segments;
} atari_tos; } atari_tos;
struct {
bool force_macos; // undocumented temporary option until we fix macOS 13+ support
} darwin_macho;
struct { struct {
bool coff; bool coff;
} djgpp2_coff; } djgpp2_coff;
@@ -163,13 +170,11 @@ struct Options final {
struct { struct {
int compress_exports; int compress_exports;
int compress_icons; int compress_icons;
int compress_resources; upx::TriBool<upx_int8_t, true> compress_resources;
signed char compress_rt[25]; // 25 == RT_LAST upx::TriBool<upx_int8_t, true> compress_rt[25]; // 25 == RT_LAST
int strip_relocs; int strip_relocs;
const char *keep_resource; const char *keep_resource;
} win32_pe; } win32_pe;
void reset() noexcept;
}; };
/* vim:set ts=4 sw=4 et: */ /* vim:set ts=4 sw=4 et: */
+2 -2
View File
@@ -58,7 +58,7 @@ const int *PackCom::getFilters() const {
// //
**************************************************************************/ **************************************************************************/
bool PackCom::canPack() { tribool PackCom::canPack() {
byte buf[128]; byte buf[128];
fi->readx(buf, sizeof(buf)); fi->readx(buf, sizeof(buf));
@@ -197,7 +197,7 @@ void PackCom::pack(OutputFile *fo) {
// //
**************************************************************************/ **************************************************************************/
int PackCom::canUnpack() { tribool PackCom::canUnpack() {
if (!readPackHeader(128)) // read "ph" if (!readPackHeader(128)) // read "ph"
return false; return false;
if (file_size_u <= ph.c_len) if (file_size_u <= ph.c_len)
+2 -2
View File
@@ -46,8 +46,8 @@ public:
virtual void pack(OutputFile *fo) override; virtual void pack(OutputFile *fo) override;
virtual void unpack(OutputFile *fo) override; virtual void unpack(OutputFile *fo) override;
virtual bool canPack() override; virtual tribool canPack() override;
virtual int canUnpack() override; virtual tribool canUnpack() override;
protected: protected:
virtual Linker *newLinker() const override; virtual Linker *newLinker() const override;
+2 -2
View File
@@ -197,7 +197,7 @@ void PackDjgpp2::stripDebug() {
// //
**************************************************************************/ **************************************************************************/
bool PackDjgpp2::canPack() { tribool PackDjgpp2::canPack() {
if (!readFileHeader()) if (!readFileHeader())
return false; return false;
if (is_dlm(fi, coff_offset)) if (is_dlm(fi, coff_offset))
@@ -346,7 +346,7 @@ void PackDjgpp2::pack(OutputFile *fo) {
// //
**************************************************************************/ **************************************************************************/
int PackDjgpp2::canUnpack() { tribool PackDjgpp2::canUnpack() {
if (!readFileHeader()) if (!readFileHeader())
return false; return false;
if (is_dlm(fi, coff_offset)) if (is_dlm(fi, coff_offset))
+2 -6
View File
@@ -26,8 +26,6 @@
*/ */
#pragma once #pragma once
#ifndef UPX_P_DJGPP2_H__
#define UPX_P_DJGPP2_H__ 1
/************************************************************************* /*************************************************************************
// djgpp2/coff // djgpp2/coff
@@ -50,8 +48,8 @@ public:
virtual void pack(OutputFile *fo) override; virtual void pack(OutputFile *fo) override;
virtual void unpack(OutputFile *fo) override; virtual void unpack(OutputFile *fo) override;
virtual bool canPack() override; virtual tribool canPack() override;
virtual int canUnpack() override; virtual tribool canUnpack() override;
protected: protected:
void handleStub(OutputFile *fo); void handleStub(OutputFile *fo);
@@ -104,6 +102,4 @@ protected:
void stripDebug(); void stripDebug();
}; };
#endif /* already included */
/* vim:set ts=4 sw=4 et: */ /* vim:set ts=4 sw=4 et: */
+22 -22
View File
@@ -49,7 +49,7 @@ struct ElfITypes
// The ELF file header. This appears at the start of every ELF file. // The ELF file header. This appears at the start of every ELF file.
template <class TElfITypes> template <class TElfITypes>
__packed_struct(Ehdr) packed_struct(Ehdr) {
typedef typename TElfITypes::Half Half; typedef typename TElfITypes::Half Half;
typedef typename TElfITypes::Word Word; typedef typename TElfITypes::Word Word;
typedef typename TElfITypes::Addr Addr; typedef typename TElfITypes::Addr Addr;
@@ -72,11 +72,11 @@ __packed_struct(Ehdr)
# define WANT_EHDR_ENUM 1 # define WANT_EHDR_ENUM 1
# include "p_elf_enum.h" # include "p_elf_enum.h"
__packed_struct_end() };
template <class TElfITypes> template <class TElfITypes>
__packed_struct(Dyn) packed_struct(Dyn) {
typedef typename TElfITypes::Xword Xword; typedef typename TElfITypes::Xword Xword;
typedef typename TElfITypes::Addr Addr; typedef typename TElfITypes::Addr Addr;
@@ -85,32 +85,32 @@ __packed_struct(Dyn)
# define WANT_DYN_ENUM 1 # define WANT_DYN_ENUM 1
# include "p_elf_enum.h" # include "p_elf_enum.h"
__packed_struct_end() };
template <class TElfITypes> template <class TElfITypes>
__packed_struct(Rel) packed_struct(Rel) {
typedef typename TElfITypes::Xword Xword; typedef typename TElfITypes::Xword Xword;
typedef typename TElfITypes::Addr Addr; typedef typename TElfITypes::Addr Addr;
Addr r_offset; Addr r_offset;
Xword r_info; Xword r_info;
__packed_struct_end() };
template <class TElfITypes> template <class TElfITypes>
__packed_struct(Rela) packed_struct(Rela) {
typedef typename TElfITypes::Xword Xword; typedef typename TElfITypes::Xword Xword;
typedef typename TElfITypes::Addr Addr; typedef typename TElfITypes::Addr Addr;
Addr r_offset; Addr r_offset;
Xword r_info; Xword r_info;
Xword r_addend; Xword r_addend;
__packed_struct_end() };
template <class TElfITypes> template <class TElfITypes>
__packed_struct(External_Note) packed_struct(External_Note) {
typedef typename TElfITypes::Word Word; typedef typename TElfITypes::Word Word;
Word xn_namesz; // includes terminating '\0' Word xn_namesz; // includes terminating '\0'
@@ -118,7 +118,7 @@ __packed_struct(External_Note)
Word xn_type; Word xn_type;
//char xn_name[N]; // terminate with '\0' //char xn_name[N]; // terminate with '\0'
//char xn_data[M]; // aligned to 0 mod 4 //char xn_data[M]; // aligned to 0 mod 4
__packed_struct_end() };
} // namespace N_Elf } // namespace N_Elf
@@ -131,7 +131,7 @@ __packed_struct_end()
namespace N_Elf32 { namespace N_Elf32 {
template <class TElfITypes> template <class TElfITypes>
__packed_struct(Phdr) packed_struct(Phdr) {
typedef typename TElfITypes::Word Word; typedef typename TElfITypes::Word Word;
typedef typename TElfITypes::Addr Addr; typedef typename TElfITypes::Addr Addr;
typedef typename TElfITypes::Off Off; typedef typename TElfITypes::Off Off;
@@ -147,11 +147,11 @@ __packed_struct(Phdr)
# define WANT_PHDR_ENUM 1 # define WANT_PHDR_ENUM 1
# include "p_elf_enum.h" # include "p_elf_enum.h"
__packed_struct_end() };
template <class TElfITypes> template <class TElfITypes>
__packed_struct(Shdr) packed_struct(Shdr) {
typedef typename TElfITypes::Word Word; typedef typename TElfITypes::Word Word;
typedef typename TElfITypes::Addr Addr; typedef typename TElfITypes::Addr Addr;
typedef typename TElfITypes::Off Off; typedef typename TElfITypes::Off Off;
@@ -169,11 +169,11 @@ __packed_struct(Shdr)
# define WANT_SHDR_ENUM 1 # define WANT_SHDR_ENUM 1
# include "p_elf_enum.h" # include "p_elf_enum.h"
__packed_struct_end() };
template <class TElfITypes> template <class TElfITypes>
__packed_struct(Sym) packed_struct(Sym) {
typedef typename TElfITypes::Word Word; typedef typename TElfITypes::Word Word;
typedef typename TElfITypes::Addr Addr; typedef typename TElfITypes::Addr Addr;
typedef typename TElfITypes::Section Section; typedef typename TElfITypes::Section Section;
@@ -192,7 +192,7 @@ __packed_struct(Sym)
static unsigned int get_st_type(unsigned x) { return 0xf & x ; } static unsigned int get_st_type(unsigned x) { return 0xf & x ; }
static unsigned char make_st_info(unsigned bind, unsigned type) static unsigned char make_st_info(unsigned bind, unsigned type)
{ return (unsigned char) (((bind<<4) + (0xf & type)) & 0xff); } { return (unsigned char) (((bind<<4) + (0xf & type)) & 0xff); }
__packed_struct_end() };
} // namespace N_Elf32 } // namespace N_Elf32
@@ -205,7 +205,7 @@ __packed_struct_end()
namespace N_Elf64 { namespace N_Elf64 {
template <class TElfITypes> template <class TElfITypes>
__packed_struct(Phdr) packed_struct(Phdr) {
typedef typename TElfITypes::Word Word; typedef typename TElfITypes::Word Word;
typedef typename TElfITypes::Xword Xword; typedef typename TElfITypes::Xword Xword;
typedef typename TElfITypes::Addr Addr; typedef typename TElfITypes::Addr Addr;
@@ -222,11 +222,11 @@ __packed_struct(Phdr)
# define WANT_PHDR_ENUM 1 # define WANT_PHDR_ENUM 1
# include "p_elf_enum.h" # include "p_elf_enum.h"
__packed_struct_end() };
template <class TElfITypes> template <class TElfITypes>
__packed_struct(Shdr) packed_struct(Shdr) {
typedef typename TElfITypes::Word Word; typedef typename TElfITypes::Word Word;
typedef typename TElfITypes::Xword Xword; typedef typename TElfITypes::Xword Xword;
typedef typename TElfITypes::Addr Addr; typedef typename TElfITypes::Addr Addr;
@@ -245,11 +245,11 @@ __packed_struct(Shdr)
# define WANT_SHDR_ENUM 1 # define WANT_SHDR_ENUM 1
# include "p_elf_enum.h" # include "p_elf_enum.h"
__packed_struct_end() };
template <class TElfITypes> template <class TElfITypes>
__packed_struct(Sym) packed_struct(Sym) {
typedef typename TElfITypes::Word Word; typedef typename TElfITypes::Word Word;
typedef typename TElfITypes::Xword Xword; typedef typename TElfITypes::Xword Xword;
typedef typename TElfITypes::Addr Addr; typedef typename TElfITypes::Addr Addr;
@@ -269,7 +269,7 @@ __packed_struct(Sym)
static unsigned int get_st_type(unsigned x) { return 0xf & x ; } static unsigned int get_st_type(unsigned x) { return 0xf & x ; }
static unsigned char make_st_info(unsigned bind, unsigned type) static unsigned char make_st_info(unsigned bind, unsigned type)
{ return (unsigned char) (((bind<<4) + (0xf & type)) & 0xff); } { return (unsigned char) (((bind<<4) + (0xf & type)) & 0xff); }
__packed_struct_end() };
} // namespace N_Elf64 } // namespace N_Elf64
+4 -4
View File
@@ -35,7 +35,7 @@
static const CLANG_FORMAT_DUMMY_STATEMENT static const CLANG_FORMAT_DUMMY_STATEMENT
#include "stub/i086-dos16.exe.h" #include "stub/i086-dos16.exe.h"
#define MAXMATCH 0x2000 #define MAXMATCH 0x2000
#define MAXRELOCSIZE (0x8000 - MAXMATCH) #define MAXRELOCSIZE (0x8000 - MAXMATCH)
#define DI_LIMIT 0xff00 // see the assembly why #define DI_LIMIT 0xff00 // see the assembly why
@@ -229,7 +229,7 @@ int PackExe::readFileHeader() {
return UPX_F_DOS_EXE; return UPX_F_DOS_EXE;
} }
bool PackExe::canPack() { tribool PackExe::canPack() {
if (fn_has_ext(fi->getName(), "sys")) // dos/sys if (fn_has_ext(fi->getName(), "sys")) // dos/sys
return false; return false;
if (!readFileHeader()) if (!readFileHeader())
@@ -398,7 +398,7 @@ void PackExe::pack(OutputFile *fo) {
unsigned jc = get_le32(relocs + 4 * ic); unsigned jc = get_le32(relocs + 4 * ic);
set_le32(relocs + 4 * ic, ((jc >> 16) * 16 + (jc & 0xffff)) & 0xfffff); set_le32(relocs + 4 * ic, ((jc >> 16) * 16 + (jc & 0xffff)) & 0xfffff);
} }
qsort(raw_bytes(relocs, 4 * relocnum), relocnum, 4, le32_compare); upx_qsort(raw_bytes(relocs, 4 * relocnum), relocnum, 4, le32_compare);
SPAN_S_VAR(byte, image, ibuf + 0, ih_imagesize); SPAN_S_VAR(byte, image, ibuf + 0, ih_imagesize);
SPAN_S_VAR(byte, crel, ibuf + ih_imagesize, ibuf); SPAN_S_VAR(byte, crel, ibuf + ih_imagesize, ibuf);
@@ -572,7 +572,7 @@ void PackExe::pack(OutputFile *fo) {
// //
**************************************************************************/ **************************************************************************/
int PackExe::canUnpack() { tribool PackExe::canUnpack() {
if (!readFileHeader()) if (!readFileHeader())
return false; return false;
const unsigned off = ih.headsize16 * 16; const unsigned off = ih.headsize16 * 16;
+2 -2
View File
@@ -46,8 +46,8 @@ public:
virtual void pack(OutputFile *fo) override; virtual void pack(OutputFile *fo) override;
virtual void unpack(OutputFile *fo) override; virtual void unpack(OutputFile *fo) override;
virtual bool canPack() override; virtual tribool canPack() override;
virtual int canUnpack() override; virtual tribool canUnpack() override;
// unpacker capabilities // unpacker capabilities
virtual bool canUnpackVersion(int version) const override { virtual bool canUnpackVersion(int version) const override {
+92 -33
View File
@@ -252,7 +252,7 @@ PackLinuxElf::PackLinuxElf(InputFile *f)
: super(f), e_phnum(0), dynstr(nullptr), : super(f), e_phnum(0), dynstr(nullptr),
sz_phdrs(0), sz_elf_hdrs(0), sz_pack2(0), sz_pack2a(0), sz_phdrs(0), sz_elf_hdrs(0), sz_pack2(0), sz_pack2a(0),
lg2_page(12), page_size(1u<<lg2_page), is_pie(0), is_asl(0), lg2_page(12), page_size(1u<<lg2_page), is_pie(0), is_asl(0),
xct_off(0), so_slide(0), xct_va(0), jni_onload_va(0), xct_off(0), o_binfo(0), so_slide(0), xct_va(0), jni_onload_va(0),
user_init_va(0), user_init_off(0), user_init_va(0), user_init_off(0),
e_machine(0), ei_class(0), ei_data(0), ei_osabi(0), osabi_note(nullptr), e_machine(0), ei_class(0), ei_data(0), ei_osabi(0), osabi_note(nullptr),
shstrtab(nullptr), shstrtab(nullptr),
@@ -1046,12 +1046,15 @@ PackLinuxElf64::PackLinuxElf64help1(InputFile *f)
if (!(opt->cmd == CMD_COMPRESS && e_shoff < (upx_uint64_t)file_size && mb_shdr.getSize() == 0)) { if (!(opt->cmd == CMD_COMPRESS && e_shoff < (upx_uint64_t)file_size && mb_shdr.getSize() == 0)) {
shdri = nullptr; shdri = nullptr;
} }
else { else if (e_shnum && e_shoff && ehdri.e_shentsize) {
fi->seek(e_shoff, SEEK_SET); fi->seek(e_shoff, SEEK_SET);
mb_shdr.alloc( sizeof(Elf64_Shdr) * e_shnum); mb_shdr.alloc( sizeof(Elf64_Shdr) * e_shnum);
shdri = (Elf64_Shdr *)mb_shdr.getVoidPtr(); shdri = (Elf64_Shdr *)mb_shdr.getVoidPtr();
fi->readx(shdri, sizeof(Elf64_Shdr) * e_shnum); fi->readx(shdri, sizeof(Elf64_Shdr) * e_shnum);
} }
else {
shdri = nullptr;
}
sec_dynsym = elf_find_section_type(Elf64_Shdr::SHT_DYNSYM); sec_dynsym = elf_find_section_type(Elf64_Shdr::SHT_DYNSYM);
if (sec_dynsym) { if (sec_dynsym) {
unsigned t = get_te32(&sec_dynsym->sh_link); unsigned t = get_te32(&sec_dynsym->sh_link);
@@ -1397,7 +1400,7 @@ void PackLinuxElf32x86::addStubEntrySections(Filter const *ft, unsigned m_decomp
} }
addLoader("IDENTSTR", nullptr); addLoader("IDENTSTR", nullptr);
addLoader("LEXEC020", nullptr); addLoader("+40,LEXEC020", nullptr);
addLoader("FOLDEXEC", nullptr); addLoader("FOLDEXEC", nullptr);
} }
@@ -1445,7 +1448,7 @@ PackLinuxElf32::buildLinuxLoader(
// SO_MAIN C-language supervision based on PT_LOADs // SO_MAIN C-language supervision based on PT_LOADs
char sec[120]; char sec[120];
int len = 0; int len = 0;
unsigned m_decompr = (methods_used ? methods_used : (1u << ph.method)); unsigned m_decompr = (methods_used ? methods_used : (1u << ph_forced_method(ph.method)));
len += snprintf(sec, sizeof(sec), "%s", "SO_HEAD,ptr_NEXT,EXP_HEAD"); len += snprintf(sec, sizeof(sec), "%s", "SO_HEAD,ptr_NEXT,EXP_HEAD");
if (((1u<<M_NRV2B_LE32)|(1u<<M_NRV2B_8)|(1u<<M_NRV2B_LE16)) & m_decompr) { if (((1u<<M_NRV2B_LE32)|(1u<<M_NRV2B_8)|(1u<<M_NRV2B_LE16)) & m_decompr) {
len += snprintf(&sec[len], sizeof(sec) - len, ",%s", "NRV2B"); len += snprintf(&sec[len], sizeof(sec) - len, ",%s", "NRV2B");
@@ -1493,7 +1496,7 @@ PackLinuxElf32::buildLinuxLoader(
h.sz_cpr = mb_cprLoader.getSize(); // max that upx_compress may use h.sz_cpr = mb_cprLoader.getSize(); // max that upx_compress may use
{ {
int r = upx_compress(uncLoader, sz_unc, sizeof(h) + cprLoader, &sz_cpr, int r = upx_compress(uncLoader, sz_unc, sizeof(h) + cprLoader, &sz_cpr,
nullptr, forced_method(method), 10, nullptr, nullptr ); nullptr, ph_forced_method(method), 10, nullptr, nullptr );
h.sz_cpr = sz_cpr; // actual length used h.sz_cpr = sz_cpr; // actual length used
if (r != UPX_E_OK || h.sz_cpr >= h.sz_unc) if (r != UPX_E_OK || h.sz_cpr >= h.sz_unc)
throwInternalError("loader compression failed"); throwInternalError("loader compression failed");
@@ -1514,7 +1517,7 @@ PackLinuxElf32::buildLinuxLoader(
} }
else { else {
addStubEntrySections(ft, (methods_used ? methods_used addStubEntrySections(ft, (methods_used ? methods_used
: (1u << forced_method(ph.method))) ); : (1u << ph_forced_method(ph.method))) );
if (!xct_off) { if (!xct_off) {
defineSymbols(ft); defineSymbols(ft);
} }
@@ -1553,7 +1556,7 @@ PackLinuxElf64::buildLinuxLoader(
// SO_MAIN C-language supervision based on PT_LOADs // SO_MAIN C-language supervision based on PT_LOADs
char sec[120]; char sec[120];
int len = 0; int len = 0;
unsigned m_decompr = (methods_used ? methods_used : (1u << ph.method)); unsigned m_decompr = (methods_used ? methods_used : (1u << ph_forced_method(ph.method)));
len += snprintf(sec, sizeof(sec), "%s", "SO_HEAD,ptr_NEXT,EXP_HEAD"); len += snprintf(sec, sizeof(sec), "%s", "SO_HEAD,ptr_NEXT,EXP_HEAD");
if (((1u<<M_NRV2B_LE32)|(1u<<M_NRV2B_8)|(1u<<M_NRV2B_LE16)) & m_decompr) { if (((1u<<M_NRV2B_LE32)|(1u<<M_NRV2B_8)|(1u<<M_NRV2B_LE16)) & m_decompr) {
len += snprintf(&sec[len], sizeof(sec) - len, ",%s", "NRV2B"); len += snprintf(&sec[len], sizeof(sec) - len, ",%s", "NRV2B");
@@ -1599,7 +1602,7 @@ PackLinuxElf64::buildLinuxLoader(
h.sz_cpr = mb_cprLoader.getSize(); // max that upx_compress may use h.sz_cpr = mb_cprLoader.getSize(); // max that upx_compress may use
{ {
int r = upx_compress(uncLoader, sz_unc, sizeof(h) + cprLoader, &sz_cpr, int r = upx_compress(uncLoader, sz_unc, sizeof(h) + cprLoader, &sz_cpr,
nullptr, forced_method(method), 10, nullptr, nullptr ); nullptr, ph_forced_method(method), 10, nullptr, nullptr );
h.sz_cpr = sz_cpr; // actual length used h.sz_cpr = sz_cpr; // actual length used
if (r != UPX_E_OK || h.sz_cpr >= h.sz_unc) if (r != UPX_E_OK || h.sz_cpr >= h.sz_unc)
throwInternalError("loader compression failed"); throwInternalError("loader compression failed");
@@ -1620,7 +1623,7 @@ PackLinuxElf64::buildLinuxLoader(
} }
else { else {
addStubEntrySections(ft, (methods_used ? methods_used addStubEntrySections(ft, (methods_used ? methods_used
: (1u << forced_method(ph.method))) ); : (1u << ph_forced_method(ph.method))) );
if (!xct_off) { if (!xct_off) {
defineSymbols(ft); defineSymbols(ft);
} }
@@ -2019,7 +2022,7 @@ PackLinuxElf32::sort_DT32_offsets(Elf32_Dyn const *const dynp0)
n_off += !!dt_offsets[n_off]; n_off += !!dt_offsets[n_off];
} }
dt_offsets[n_off++] = file_size; // sentinel dt_offsets[n_off++] = file_size; // sentinel
qsort(dt_offsets, n_off, sizeof(dt_offsets[0]), qcmp_unsigned); upx_qsort(dt_offsets, n_off, sizeof(dt_offsets[0]), qcmp_unsigned);
} }
unsigned PackLinuxElf32::find_dt_ndx(unsigned rva) unsigned PackLinuxElf32::find_dt_ndx(unsigned rva)
@@ -2411,7 +2414,7 @@ bool PackLinuxElf32::calls_crt1(Elf32_Rel const *rel, int sz)
return false; return false;
} }
int PackLinuxElf32::canUnpack() // bool, except -1: format known, but not packed tribool PackLinuxElf32::canUnpack() // bool, except -1: format known, but not packed
{ {
if (checkEhdr(&ehdri)) { if (checkEhdr(&ehdri)) {
return false; return false;
@@ -2506,7 +2509,7 @@ PackLinuxElf32::canPackOSABI(Elf32_Ehdr const *ehdr)
return true; // good so far return true; // good so far
} }
bool PackLinuxElf32::canPack() tribool PackLinuxElf32::canPack()
{ {
union { union {
unsigned char buf[MAX_ELF_HDR_32]; unsigned char buf[MAX_ELF_HDR_32];
@@ -2589,7 +2592,12 @@ bool PackLinuxElf32::canPack()
max_offset = UPX_MAX(max_offset, get_te32(&phdr->p_filesz) + get_te32(&phdr->p_offset)); max_offset = UPX_MAX(max_offset, get_te32(&phdr->p_filesz) + get_te32(&phdr->p_offset));
} }
} }
if (canUnpack() > 0) { if (canUnpack()) {
throwAlreadyPacked();
}
// Heuristic for lopped trailing PackHeader (packed and "hacked"!)
if (3 == e_phnum // not shlib: PT_LOAD.C_BASE, PT_LOAD.C_TEXT, PT_GNU_STACK
&& UPX_MAGIC_LE32 == get_le32(&((l_info *)&phdri[e_phnum])->l_magic)) {
throwAlreadyPacked(); throwAlreadyPacked();
} }
// We want to compress position-independent executable (gcc -pie) // We want to compress position-independent executable (gcc -pie)
@@ -2687,7 +2695,7 @@ bool PackLinuxElf32::canPack()
(int)elf_unsigned_dynamic(Elf32_Dyn::DT_RELSZ)) (int)elf_unsigned_dynamic(Elf32_Dyn::DT_RELSZ))
|| calls_crt1((Elf32_Rel const *)elf_find_dynamic(Elf32_Dyn::DT_JMPREL), || calls_crt1((Elf32_Rel const *)elf_find_dynamic(Elf32_Dyn::DT_JMPREL),
(int)elf_unsigned_dynamic(Elf32_Dyn::DT_PLTRELSZ))) { (int)elf_unsigned_dynamic(Elf32_Dyn::DT_PLTRELSZ))) {
is_pie = true; is_pie = true; // UNUSED except to ignore is_shlib and xct_off
goto proceed; // calls C library init for main program goto proceed; // calls C library init for main program
} }
@@ -2952,7 +2960,7 @@ proceed: ;
return true; return true;
} }
int PackLinuxElf64::canUnpack() // bool, except -1: format known, but not packed tribool PackLinuxElf64::canUnpack() // bool, except -1: format known, but not packed
{ {
if (checkEhdr(&ehdri)) { if (checkEhdr(&ehdri)) {
return false; return false;
@@ -2966,8 +2974,7 @@ int PackLinuxElf64::canUnpack() // bool, except -1: format known, but not packed
return false; return false;
} }
bool tribool PackLinuxElf64::canPack()
PackLinuxElf64::canPack()
{ {
union { union {
unsigned char buf[MAX_ELF_HDR_64]; unsigned char buf[MAX_ELF_HDR_64];
@@ -3024,7 +3031,12 @@ PackLinuxElf64::canPack()
max_offset = UPX_MAX(max_offset, get_te64(&phdr->p_filesz) + get_te64(&phdr->p_offset)); max_offset = UPX_MAX(max_offset, get_te64(&phdr->p_filesz) + get_te64(&phdr->p_offset));
} }
} }
if (canUnpack() > 0) { if (canUnpack()) {
throwAlreadyPacked();
}
// Heuristic for lopped trailing PackHeader (packed and "hacked"!)
if (3 == e_phnum // not shlib: PT_LOAD.C_BASE, PT_LOAD.C_TEXT, PT_GNU_STACK
&& UPX_MAGIC_LE32 == get_le32(&((l_info *)&phdri[e_phnum])->l_magic)) {
throwAlreadyPacked(); throwAlreadyPacked();
} }
// We want to compress position-independent executable (gcc -pie) // We want to compress position-independent executable (gcc -pie)
@@ -3122,7 +3134,7 @@ PackLinuxElf64::canPack()
(int)elf_unsigned_dynamic(Elf64_Dyn::DT_RELASZ)) (int)elf_unsigned_dynamic(Elf64_Dyn::DT_RELASZ))
|| calls_crt1((Elf64_Rela const *)elf_find_dynamic(Elf64_Dyn::DT_JMPREL), || calls_crt1((Elf64_Rela const *)elf_find_dynamic(Elf64_Dyn::DT_JMPREL),
(int)elf_unsigned_dynamic(Elf64_Dyn::DT_PLTRELSZ))) { (int)elf_unsigned_dynamic(Elf64_Dyn::DT_PLTRELSZ))) {
is_pie = true; is_pie = true; // UNUSED except to ignore is_shlib and xct_off
goto proceed; // calls C library init for main program goto proceed; // calls C library init for main program
} }
@@ -3900,7 +3912,7 @@ void PackLinuxElf32::pack1(OutputFile * /*fo*/, Filter &ft)
fi->readx(ibuf, filesz); fi->readx(ibuf, filesz);
ft = orig_ft; ft = orig_ft;
ph = orig_ph; ph = orig_ph;
ph.method = force_method(methods[k]); ph.method = ph_force_method(methods[k]);
ph.u_len = filesz; ph.u_len = filesz;
compressWithFilters(&ft, OVERHEAD, NULL_cconf, 10, true); compressWithFilters(&ft, OVERHEAD, NULL_cconf, 10, true);
sz_this += ph.c_len; sz_this += ph.c_len;
@@ -3913,7 +3925,7 @@ void PackLinuxElf32::pack1(OutputFile * /*fo*/, Filter &ft)
fi->readx(ibuf, sz_tail); fi->readx(ibuf, sz_tail);
ft = orig_ft; ft = orig_ft;
ph = orig_ph; ph = orig_ph;
ph.method = force_method(methods[k]); ph.method = ph_force_method(methods[k]);
ph.u_len = sz_tail; ph.u_len = sz_tail;
compressWithFilters(&ft, OVERHEAD, NULL_cconf, 10, true); compressWithFilters(&ft, OVERHEAD, NULL_cconf, 10, true);
sz_this += ph.c_len; sz_this += ph.c_len;
@@ -3926,7 +3938,7 @@ void PackLinuxElf32::pack1(OutputFile * /*fo*/, Filter &ft)
} }
ft = orig_ft; ft = orig_ft;
ph = orig_ph; ph = orig_ph;
ph.method = force_method(method_best); ph.method = ph_force_method(method_best);
} }
note_size = 0; note_size = 0;
@@ -4782,7 +4794,7 @@ void PackLinuxElf64::pack1(OutputFile * /*fo*/, Filter &ft)
fi->readx(ibuf, filesz); fi->readx(ibuf, filesz);
ft = orig_ft; ft = orig_ft;
ph = orig_ph; ph = orig_ph;
ph.method = force_method(methods[k]); ph.method = ph_force_method(methods[k]);
ph.u_len = filesz; ph.u_len = filesz;
compressWithFilters(&ft, OVERHEAD, NULL_cconf, 10, true); compressWithFilters(&ft, OVERHEAD, NULL_cconf, 10, true);
sz_this += ph.c_len; sz_this += ph.c_len;
@@ -4795,7 +4807,7 @@ void PackLinuxElf64::pack1(OutputFile * /*fo*/, Filter &ft)
fi->readx(ibuf, sz_tail); fi->readx(ibuf, sz_tail);
ft = orig_ft; ft = orig_ft;
ph = orig_ph; ph = orig_ph;
ph.method = force_method(methods[k]); ph.method = ph_force_method(methods[k]);
ph.u_len = sz_tail; ph.u_len = sz_tail;
compressWithFilters(&ft, OVERHEAD, NULL_cconf, 10, true); compressWithFilters(&ft, OVERHEAD, NULL_cconf, 10, true);
sz_this += ph.c_len; sz_this += ph.c_len;
@@ -4808,7 +4820,7 @@ void PackLinuxElf64::pack1(OutputFile * /*fo*/, Filter &ft)
} }
ft = orig_ft; ft = orig_ft;
ph = orig_ph; ph = orig_ph;
ph.method = force_method(method_best); ph.method = ph_force_method(method_best);
} }
note_size = 0; note_size = 0;
@@ -5114,7 +5126,7 @@ int PackLinuxElf32::pack2(OutputFile *fo, Filter &ft)
} }
} }
else { // defnitely compressible unless writeable else { // definitely compressible unless writeable
if (!(Elf32_Phdr::PF_W & get_te32(&phdri[k].p_flags))) { if (!(Elf32_Phdr::PF_W & get_te32(&phdri[k].p_flags))) {
// Read-only PT_LOAD, assume not written by relocations. // Read-only PT_LOAD, assume not written by relocations.
// Also assume not the source for R_*_COPY relocation, // Also assume not the source for R_*_COPY relocation,
@@ -5371,7 +5383,7 @@ int PackLinuxElf64::pack2(OutputFile *fo, Filter &ft)
packExtent(x, &ft, fo, 0, 0, true); packExtent(x, &ft, fo, 0, 0, true);
} }
} }
else { // defnitely compressible unless writeable else { // definitely compressible unless writeable
if (!(Elf64_Phdr::PF_W & get_te32(&phdri[k].p_flags))) { if (!(Elf64_Phdr::PF_W & get_te32(&phdri[k].p_flags))) {
// Read-only PT_LOAD, assume not written by relocations. // Read-only PT_LOAD, assume not written by relocations.
// Also assume not the source for R_*_COPY relocation, // Also assume not the source for R_*_COPY relocation,
@@ -5596,7 +5608,7 @@ unsigned PackLinuxElf32::forward_Shdrs(OutputFile *fo, Elf32_Ehdr *const eho)
| 1u<<SHT_NOTE | 1u<<SHT_NOTE
| 1u<<SHT_REL | 1u<<SHT_REL
| 1u<<SHT_DYNSYM | 1u<<SHT_DYNSYM
//| 1u<<SHT_STRTAB // covered by (j == e_shstrndx) | 1u<<SHT_STRTAB // .shstrtab and .dynstr
| 1u<<SHT_INIT_ARRAY | 1u<<SHT_INIT_ARRAY
| 1u<<SHT_FINI_ARRAY | 1u<<SHT_FINI_ARRAY
| 1u<<SHT_PREINIT_ARRAY | 1u<<SHT_PREINIT_ARRAY
@@ -5769,7 +5781,7 @@ unsigned PackLinuxElf64::forward_Shdrs(OutputFile *fo, Elf64_Ehdr *const eho)
| 1u<<SHT_NOTE | 1u<<SHT_NOTE
| 1u<<SHT_REL | 1u<<SHT_REL
| 1u<<SHT_DYNSYM | 1u<<SHT_DYNSYM
//| 1u<<SHT_STRTAB // covered by (j == e_shstrndx) | 1u<<SHT_STRTAB // .shstrtab and .dynstr
| 1u<<SHT_INIT_ARRAY | 1u<<SHT_INIT_ARRAY
| 1u<<SHT_FINI_ARRAY | 1u<<SHT_FINI_ARRAY
| 1u<<SHT_PREINIT_ARRAY | 1u<<SHT_PREINIT_ARRAY
@@ -5804,6 +5816,8 @@ unsigned PackLinuxElf64::forward_Shdrs(OutputFile *fo, Elf64_Ehdr *const eho)
++sh_in; ++sh_out; unsigned n_sh_out = 1; ++sh_in; ++sh_out; unsigned n_sh_out = 1;
for (unsigned j = 1; j < e_shnum; ++j, ++sh_in) { for (unsigned j = 1; j < e_shnum; ++j, ++sh_in) {
char const *sh_name = &shstrtab[get_te32(&sh_in->sh_name)];
(void)sh_name; // debugging
unsigned sh_type = get_te32(&sh_in->sh_type); unsigned sh_type = get_te32(&sh_in->sh_type);
unsigned sh_info = get_te32(&sh_in->sh_info); unsigned sh_info = get_te32(&sh_in->sh_info);
u64_t sh_flags = get_te64(&sh_in->sh_flags); u64_t sh_flags = get_te64(&sh_in->sh_flags);
@@ -5867,6 +5881,51 @@ unsigned PackLinuxElf64::forward_Shdrs(OutputFile *fo, Elf64_Ehdr *const eho)
set_te64(&sh_out->sh_offset, so_slide + sh_offset); set_te64(&sh_out->sh_offset, so_slide + sh_offset);
} }
} }
// Exploration for updating Shdrs from Dynamic, to pacify Android.
// Motivated by --force-pie with an input shared library;
// see https://github.com/upx/upx/issues/694
// But then realized that the pointed-to regions typically were
// just above Elfhdrs (overlay_offset), so the data would be
// incorrect because occupied by compressed PT_LOADS.
// But don't lose the code, so comment-out via "if (0)".
if (0) switch(sh_type) { // start {Shdr, Dynamic} pairs
case SHT_DYNSYM: {
set_te64(&sh_out->sh_addr, elf_unsigned_dynamic(Elf64_Dyn::DT_SYMTAB));
sh_out->sh_offset = sh_out->sh_addr;
} break;
case SHT_STRTAB: {
if (e_shstrndx != j) {
set_te64(&sh_out->sh_addr, elf_unsigned_dynamic(Elf64_Dyn::DT_STRTAB));
sh_out->sh_offset = sh_out->sh_addr;
}
} break;
case SHT_GNU_versym: {
set_te64(&sh_out->sh_addr, elf_unsigned_dynamic(Elf64_Dyn::DT_VERSYM));
sh_out->sh_offset = sh_out->sh_addr;
} break;
case SHT_GNU_verneed: {
set_te64(&sh_out->sh_addr, elf_unsigned_dynamic(Elf64_Dyn::DT_VERNEED));
sh_out->sh_offset = sh_out->sh_addr;
} break;
case SHT_GNU_HASH: {
set_te64(&sh_out->sh_addr, elf_unsigned_dynamic(Elf64_Dyn::DT_GNU_HASH));
sh_out->sh_offset = sh_out->sh_addr;
} break;
case SHT_HASH: {
set_te64(&sh_out->sh_addr, elf_unsigned_dynamic(Elf64_Dyn::DT_HASH));
sh_out->sh_offset = sh_out->sh_addr;
} break;
case SHT_RELA: {
if (0==strcmp(".rela.dyn", sh_name)) {
set_te64(&sh_out->sh_addr, elf_unsigned_dynamic(Elf64_Dyn::DT_RELA));
sh_out->sh_offset = sh_out->sh_addr;
}
if (0==strcmp(".rela.plt", sh_name)) {
set_te64(&sh_out->sh_addr, elf_unsigned_dynamic(Elf64_Dyn::DT_JMPREL));
sh_out->sh_offset = sh_out->sh_addr;
}
} break;
} // end {Shdr, Dynamic} pairs
++sh_out; ++n_sh_out; ++sh_out; ++n_sh_out;
} }
} }
@@ -7407,7 +7466,7 @@ PackLinuxElf32x86::~PackLinuxElf32x86()
{ {
} }
int PackLinuxElf32x86::canUnpack() // bool, except -1: format known, but not packed tribool PackLinuxElf32x86::canUnpack() // bool, except -1: format known, but not packed
{ {
if (super::canUnpack()) { if (super::canUnpack()) {
return true; return true;
@@ -7590,7 +7649,7 @@ PackLinuxElf32::check_pt_load(Elf32_Phdr const *const phdr)
if ((-1+ align) & (paddr ^ vaddr) if ((-1+ align) & (paddr ^ vaddr)
|| (u32_t)file_size <= (u32_t)offset || (u32_t)file_size <= (u32_t)offset
|| (u32_t)file_size < (u32_t)offend || (u32_t)file_size < (u32_t)offend
|| (u32_t)file_size <= (u32_t)filesz) { || (u32_t)file_size < (u32_t)filesz) {
char msg[50]; snprintf(msg, sizeof(msg), "bad PT_LOAD phdr[%u]", char msg[50]; snprintf(msg, sizeof(msg), "bad PT_LOAD phdr[%u]",
(unsigned)(phdr - phdri)); (unsigned)(phdr - phdri));
throwCantPack(msg); throwCantPack(msg);
@@ -7747,7 +7806,7 @@ PackLinuxElf64::check_pt_load(Elf64_Phdr const *const phdr)
if ((-1+ align) & (paddr ^ vaddr) if ((-1+ align) & (paddr ^ vaddr)
|| (u64_t)file_size <= (u64_t)offset || (u64_t)file_size <= (u64_t)offset
|| (u64_t)file_size < (u64_t)offend || (u64_t)file_size < (u64_t)offend
|| (u64_t)file_size <= (u64_t)filesz) { || (u64_t)file_size < (u64_t)filesz) {
char msg[50]; snprintf(msg, sizeof(msg), "bad PT_LOAD phdr[%u]", char msg[50]; snprintf(msg, sizeof(msg), "bad PT_LOAD phdr[%u]",
(unsigned)(phdr - phdri)); (unsigned)(phdr - phdri));
throwCantPack(msg); throwCantPack(msg);
@@ -7828,7 +7887,7 @@ PackLinuxElf64::sort_DT64_offsets(Elf64_Dyn const *const dynp0)
n_off += !!dt_offsets[n_off]; n_off += !!dt_offsets[n_off];
} }
dt_offsets[n_off++] = file_size; // sentinel dt_offsets[n_off++] = file_size; // sentinel
qsort(dt_offsets, n_off, sizeof(dt_offsets[0]), qcmp_unsigned); upx_qsort(dt_offsets, n_off, sizeof(dt_offsets[0]), qcmp_unsigned);
} }
unsigned PackLinuxElf64::find_dt_ndx(u64_t rva) unsigned PackLinuxElf64::find_dt_ndx(u64_t rva)
+28 -28
View File
@@ -46,7 +46,7 @@ public:
/*virtual void buildLoader(const Filter *);*/ /*virtual void buildLoader(const Filter *);*/
virtual int getVersion() const override { return 14; } // upx-3.96 cannot upack, for instance virtual int getVersion() const override { return 14; } // upx-3.96 cannot upack, for instance
virtual bool canUnpackVersion(int version) const override { return (version >= 11); } virtual bool canUnpackVersion(int version) const override { return (version >= 11); }
virtual int canUnpack() override { return super::canUnpack(); } // bool, except -1: format known, but not packed virtual tribool canUnpack() override { return super::canUnpack(); } // bool, except -1: format known, but not packed
protected: protected:
virtual const int *getCompressionMethods(int method, int level) const override; virtual const int *getCompressionMethods(int method, int level) const override;
@@ -140,8 +140,8 @@ protected:
virtual void PackLinuxElf32help1(InputFile *f); virtual void PackLinuxElf32help1(InputFile *f);
virtual int checkEhdr(Elf32_Ehdr const *ehdr) const; virtual int checkEhdr(Elf32_Ehdr const *ehdr) const;
virtual bool canPackOSABI(Elf32_Ehdr const *); virtual bool canPackOSABI(Elf32_Ehdr const *);
virtual bool canPack() override; virtual tribool canPack() override;
virtual int canUnpack() override; // bool, except -1: format known, but not packed virtual tribool canUnpack() override; // bool, except -1: format known, but not packed
// These ARM routines are essentially common to big/little endian, // These ARM routines are essentially common to big/little endian,
// but the class hierarchy splits after this class. // but the class hierarchy splits after this class.
@@ -242,41 +242,41 @@ protected:
Elf32_Shdr const *sec_dynstr; Elf32_Shdr const *sec_dynstr;
Elf32_Shdr *sec_arm_attr; // SHT_ARM_ATTRIBUTES; Elf32_Shdr *sec_arm_attr; // SHT_ARM_ATTRIBUTES;
__packed_struct(cprElfHdr1) packed_struct(cprElfHdr1) {
Elf32_Ehdr ehdr; Elf32_Ehdr ehdr;
Elf32_Phdr phdr[1]; Elf32_Phdr phdr[1];
l_info linfo; l_info linfo;
__packed_struct_end() };
__packed_struct(cprElfHdr2) packed_struct(cprElfHdr2) {
Elf32_Ehdr ehdr; Elf32_Ehdr ehdr;
Elf32_Phdr phdr[2]; Elf32_Phdr phdr[2];
l_info linfo; l_info linfo;
__packed_struct_end() };
__packed_struct(cprElfHdr3) packed_struct(cprElfHdr3) {
Elf32_Ehdr ehdr; Elf32_Ehdr ehdr;
Elf32_Phdr phdr[3]; Elf32_Phdr phdr[3];
l_info linfo; l_info linfo;
__packed_struct_end() };
__packed_struct(cprElfHdr4) packed_struct(cprElfHdr4) {
Elf32_Ehdr ehdr; Elf32_Ehdr ehdr;
Elf32_Phdr phdr[4]; Elf32_Phdr phdr[4];
l_info linfo; l_info linfo;
__packed_struct_end() };
__packed_struct(cprElfHdrNetBSD) packed_struct(cprElfHdrNetBSD) {
Elf32_Ehdr ehdr; Elf32_Ehdr ehdr;
Elf32_Phdr phdr[4]; Elf32_Phdr phdr[4];
unsigned char notes[512]; unsigned char notes[512];
__packed_struct_end() };
cprElfHdrNetBSD elfout; cprElfHdrNetBSD elfout;
__packed_struct(cprElfShdr3) packed_struct(cprElfShdr3) {
Elf32_Shdr shdr[3]; Elf32_Shdr shdr[3];
__packed_struct_end() };
cprElfShdr3 shdrout; cprElfShdr3 shdrout;
@@ -311,8 +311,8 @@ public:
protected: protected:
virtual void PackLinuxElf64help1(InputFile *f); virtual void PackLinuxElf64help1(InputFile *f);
virtual int checkEhdr(Elf64_Ehdr const *ehdr) const; virtual int checkEhdr(Elf64_Ehdr const *ehdr) const;
virtual bool canPack() override; virtual tribool canPack() override;
virtual int canUnpack() override; // bool, except -1: format known, but not packed virtual tribool canUnpack() override; // bool, except -1: format known, but not packed
virtual void pack1(OutputFile *, Filter &) override; // generate executable header virtual void pack1(OutputFile *, Filter &) override; // generate executable header
virtual void asl_pack2_Shdrs(OutputFile *, unsigned pre_xct_top); // AndroidSharedLibrary processes Shdrs virtual void asl_pack2_Shdrs(OutputFile *, unsigned pre_xct_top); // AndroidSharedLibrary processes Shdrs
@@ -402,35 +402,35 @@ protected:
Elf64_Shdr const *sec_dynstr; Elf64_Shdr const *sec_dynstr;
Elf64_Shdr *sec_arm_attr; // SHT_ARM_ATTRIBUTES; Elf64_Shdr *sec_arm_attr; // SHT_ARM_ATTRIBUTES;
__packed_struct(cprElfHdr1) packed_struct(cprElfHdr1) {
Elf64_Ehdr ehdr; Elf64_Ehdr ehdr;
Elf64_Phdr phdr[1]; Elf64_Phdr phdr[1];
l_info linfo; l_info linfo;
__packed_struct_end() };
__packed_struct(cprElfHdr2) packed_struct(cprElfHdr2) {
Elf64_Ehdr ehdr; Elf64_Ehdr ehdr;
Elf64_Phdr phdr[2]; Elf64_Phdr phdr[2];
l_info linfo; l_info linfo;
__packed_struct_end() };
__packed_struct(cprElfHdr3) packed_struct(cprElfHdr3) {
Elf64_Ehdr ehdr; Elf64_Ehdr ehdr;
Elf64_Phdr phdr[3]; Elf64_Phdr phdr[3];
l_info linfo; l_info linfo;
__packed_struct_end() };
__packed_struct(cprElfHdr4) packed_struct(cprElfHdr4) {
Elf64_Ehdr ehdr; Elf64_Ehdr ehdr;
Elf64_Phdr phdr[4]; Elf64_Phdr phdr[4];
l_info linfo; l_info linfo;
__packed_struct_end() };
cprElfHdr4 elfout; cprElfHdr4 elfout;
__packed_struct(cprElfShdr3) packed_struct(cprElfShdr3) {
Elf64_Shdr shdr[3]; Elf64_Shdr shdr[3];
__packed_struct_end() };
cprElfShdr3 shdrout; cprElfShdr3 shdrout;
@@ -606,7 +606,7 @@ public:
virtual const char *getName() const override { return "linux/i386"; } virtual const char *getName() const override { return "linux/i386"; }
virtual const char *getFullName(const options_t *) const override { return "i386-linux.elf"; } virtual const char *getFullName(const options_t *) const override { return "i386-linux.elf"; }
virtual const int *getFilters() const override; virtual const int *getFilters() const override;
virtual int canUnpack() override; // bool, except -1: format known, but not packed virtual tribool canUnpack() override; // bool, except -1: format known, but not packed
protected: protected:
virtual void pack1(OutputFile *, Filter &) override; // generate executable header virtual void pack1(OutputFile *, Filter &) override; // generate executable header
+1 -1
View File
@@ -495,7 +495,7 @@ int PackLinuxI386::checkEhdr(const Elf_LE32_Ehdr *ehdr) const
// //
**************************************************************************/ **************************************************************************/
bool PackLinuxI386::canPack() tribool PackLinuxI386::canPack()
{ {
if (exetype != 0) if (exetype != 0)
return super::canPack(); return super::canPack();
+8 -7
View File
@@ -29,6 +29,7 @@
*/ */
#pragma once
#ifndef __UPX_P_LX_EXC_H #ifndef __UPX_P_LX_EXC_H
#define __UPX_P_LX_EXC_H 1 #define __UPX_P_LX_EXC_H 1
@@ -54,7 +55,7 @@ public:
virtual const int *getFilters() const override; virtual const int *getFilters() const override;
virtual void buildLoader(const Filter *) override; virtual void buildLoader(const Filter *) override;
virtual bool canPack() override; virtual tribool canPack() override;
protected: protected:
virtual void pack1(OutputFile *, Filter &) override; // generate executable header virtual void pack1(OutputFile *, Filter &) override; // generate executable header
@@ -87,23 +88,23 @@ protected:
unsigned n_mru; unsigned n_mru;
__packed_struct(cprElfHdr1) packed_struct(cprElfHdr1) {
Elf_LE32_Ehdr ehdr; Elf_LE32_Ehdr ehdr;
Elf_LE32_Phdr phdr[1]; Elf_LE32_Phdr phdr[1];
l_info linfo; l_info linfo;
__packed_struct_end() };
__packed_struct(cprElfHdr2) packed_struct(cprElfHdr2) {
Elf_LE32_Ehdr ehdr; Elf_LE32_Ehdr ehdr;
Elf_LE32_Phdr phdr[2]; Elf_LE32_Phdr phdr[2];
l_info linfo; l_info linfo;
__packed_struct_end() };
__packed_struct(cprElfHdr3) packed_struct(cprElfHdr3) {
Elf_LE32_Ehdr ehdr; Elf_LE32_Ehdr ehdr;
Elf_LE32_Phdr phdr[3]; Elf_LE32_Phdr phdr[3];
l_info linfo; l_info linfo;
__packed_struct_end() };
cprElfHdr3 elfout; cprElfHdr3 elfout;
+1 -1
View File
@@ -64,7 +64,7 @@ PackLinuxElf32x86interp::~PackLinuxElf32x86interp()
{ {
} }
bool PackLinuxElf32x86interp::canPack() tribool PackLinuxElf32x86interp::canPack()
{ {
if (opt->o_unix.make_ptinterp) { if (opt->o_unix.make_ptinterp) {
return true; return true;
+2 -1
View File
@@ -30,6 +30,7 @@
*/ */
#pragma once
#ifndef __UPX_P_LX_INTERP_H //{ #ifndef __UPX_P_LX_INTERP_H //{
#define __UPX_P_LX_INTERP_H 1 #define __UPX_P_LX_INTERP_H 1
@@ -49,7 +50,7 @@ public:
virtual const char *getName() const override { return "linux/elfi386"; } virtual const char *getName() const override { return "linux/elfi386"; }
virtual const char *getFullName(const options_t *) const override { return "i386-linux.elf.interp"; } virtual const char *getFullName(const options_t *) const override { return "i386-linux.elf.interp"; }
virtual bool canPack() override; virtual tribool canPack() override;
virtual void unpack(OutputFile *fo) override; virtual void unpack(OutputFile *fo) override;
protected: protected:

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