Compare commits

..

158 Commits

Author SHA1 Message Date
Markus F.X.J. Oberhumer 099c3d829e all: prepare for release. 2024-01-03 18:43:18 +01:00
Markus F.X.J. Oberhumer a1a6d02b6f all: tired of CI updates 2024-01-03 18:01:56 +01:00
Markus F.X.J. Oberhumer f2ad7fb9c4 testsuite: update checksums caused by version bump 2024-01-03 18:00:07 +01:00
Markus F.X.J. Oberhumer 1bcf709fcf all: bump version date 2024-01-03 17:54:43 +01:00
Markus F.X.J. Oberhumer 47fc230893 all: welcome 2024 2024-01-03 17:47:25 +01:00
Markus F.X.J. Oberhumer be05d85570 submodules: update for new versions 2024-01-03 17:44:57 +01:00
Markus F.X.J. Oberhumer f598fa13a9 clang-format 2024-01-03 17:36:43 +01:00
Markus F.X.J. Oberhumer 568859d16f CI updates 2024-01-03 17:31:16 +01:00
Markus F.X.J. Oberhumer b5ed0a637b CI updates 2023-12-29 10:02:46 +01:00
Markus F.X.J. Oberhumer 17eff0aed4 CI updates 2023-12-29 05:45:00 +01:00
Markus F.X.J. Oberhumer 0a3f048eed CI updates 2023-12-29 05:14:03 +01:00
Markus F.X.J. Oberhumer 3cde897557 Improve testsuite. 2023-12-28 21:44:53 +01:00
Markus F.X.J. Oberhumer 0500e7d016 CI updates; cxxlib.h cleanups 2023-12-28 04:42:41 +01:00
Markus F.X.J. Oberhumer 778663ae69 CI updates 2023-12-21 23:01:52 +01:00
Markus F.X.J. Oberhumer 636cefb9f3 cmake update 2023-12-20 18:49:34 +01:00
Markus F.X.J. Oberhumer 1236776aa2 cmake update 2023-12-20 12:16:25 +01:00
Markus F.X.J. Oberhumer 51a6a5cca5 src: rename ptr_reinterpret_cast to ptr_static_cast; misc cleanups 2023-12-20 11:44:01 +01:00
Markus F.X.J. Oberhumer 3326c86e91 cmake update 2023-12-19 16:11:23 +01:00
Markus F.X.J. Oberhumer b0dbc3fe39 submodules: update for new versions 2023-12-19 16:10:32 +01:00
Markus F.X.J. Oberhumer decc1efb74 CI updates 2023-12-17 07:35:39 +01:00
Markus F.X.J. Oberhumer 2cf1c32d18 CI updates 2023-12-13 18:52:55 +01:00
Markus F.X.J. Oberhumer fc6e3840b7 CI updates 2023-12-09 08:52:25 +01:00
Markus F.X.J. Oberhumer 5e85c1a11b submodules: update for new versions 2023-12-09 08:34:48 +01:00
Markus F.X.J. Oberhumer 468bfce599 submodules: update for new versions 2023-12-02 01:52:32 +01:00
Markus F.X.J. Oberhumer 1e6e4043ed CI updates and minor cleanups. 2023-12-02 01:48:26 +01:00
John Reiser 67564513d2 Update because of age and evolution.
modified:   elf-to-mem.txt
2023-11-30 11:10:24 -08:00
John Reiser ed2633bf95 Honor .p_align <= 64K; else assume 4K is also available
https://github.com/upx/upx/issues/737
	modified:   p_lx_elf.cpp
2023-11-26 11:46:12 -08:00
Markus F.X.J. Oberhumer 3e70021406 all: more minor cleanups 2023-11-26 18:30:47 +01:00
Markus F.X.J. Oberhumer bf8dd31914 all: minor cleanups 2023-11-21 20:29:54 +01:00
John Reiser d4e94f5086 Fix varying page size on arm64
https://github.com/upx/upx/issues/734
	modified:   stub/src/amd64-linux.elf-fold.S
	modified:   stub/src/amd64-linux.elf-main.c
	modified:   stub/src/arm64-linux.elf-entry.S
	modified:   stub/src/arm64-linux.elf-fold.S
	modified:   ../misc/testsuite/upx_testsuite_1-expected_sha256sums.sh
          ... plus associated stub/*.h etc
2023-11-17 15:10:31 -08:00
John Reiser ae77fd60bb initial headway is limited by both file_size and mhcmdi.sizeofcmds
https://github.com/upx/upx/issues/732
	modified:   p_mach.cpp
2023-11-17 07:28:21 -08:00
Markus F.X.J. Oberhumer e79c790264 CI updates 2023-11-17 11:50:52 +01:00
Markus F.X.J. Oberhumer 46029bb8a0 CI updates 2023-11-15 13:06:29 +01:00
Markus F.X.J. Oberhumer f74c225338 CI updates 2023-11-14 19:15:34 +01:00
Markus F.X.J. Oberhumer c479fe32b3 cmake update 2023-11-13 11:29:17 +01:00
Markus F.X.J. Oberhumer dc23ee0ad2 submodules: update for new versions 2023-11-08 11:48:39 +01:00
Markus F.X.J. Oberhumer a5c32db01b CI updates 2023-11-08 11:25:23 +01:00
Markus F.X.J. Oberhumer d7142312c9 CI updates 2023-11-08 10:08:19 +01:00
Markus F.X.J. Oberhumer 283ab0e7ea CI updates and assorted cleanups 2023-11-06 19:29:40 +01:00
Markus F.X.J. Oberhumer b6dd61cea8 CI updates 2023-11-05 09:03:38 +01:00
Markus F.X.J. Oberhumer 11970d276d CI updates 2023-11-04 06:30:07 +01:00
Markus F.X.J. Oberhumer d618716ec1 Minify .clang-format
Remove all settings that currently do not have any effect.
2023-11-03 17:56:12 +01:00
Markus F.X.J. Oberhumer 4f0f977f04 CI updates and cleanups 2023-11-03 17:52:46 +01:00
Markus F.X.J. Oberhumer 2c4b1d8a8c submodules: update for new versions 2023-11-03 16:46:57 +01:00
Markus F.X.J. Oberhumer b2810c6deb testsuite: update checksums caused by version bump 2023-11-01 15:12:39 +01:00
Markus F.X.J. Oberhumer ceb2b56b71 all: post-release version bump 2023-11-01 15:07:18 +01:00
Markus F.X.J. Oberhumer d14fa5f8a4 all: prepare for release 2023-11-01 12:00:03 +01:00
Markus F.X.J. Oberhumer 79263a52ac submodules: update for new versions 2023-11-01 11:40:28 +01:00
Markus F.X.J. Oberhumer ecb3f83e83 CI updates 2023-11-01 11:28:35 +01:00
Markus F.X.J. Oberhumer f6aedb35ce CI updates 2023-11-01 10:06:27 +01:00
Markus F.X.J. Oberhumer 3b7d25ac49 CI updates 2023-11-01 08:48:27 +01:00
Markus F.X.J. Oberhumer e964d4acf3 src/util: change TriBool logic to use a bool template parameter 2023-10-31 12:24:44 +01:00
Markus F.X.J. Oberhumer e306085b81 CI updates 2023-10-31 11:49:18 +01:00
Markus F.X.J. Oberhumer b094ad4f2b CI updates 2023-10-31 10:34:55 +01:00
Markus F.X.J. Oberhumer 19c6b969ab src/options: fix bad TriBool ThirdValue for pefile compress_resources 2023-10-30 21:36:36 +01:00
Markus F.X.J. Oberhumer acfda848cd src/check: add some more tribool checks 2023-10-30 20:29:05 +01:00
John Reiser 52400e2561 /proc/self/exe now is optional
... for the benefit of 'unshare', 'chroot', etc.
If not present, then upx run-time stub unmaps all pages of original main program.
https://github.com/upx/upx/issues/721

	modified:   stub/src/amd64-linux.elf-entry.S
	modified:   stub/src/amd64-linux.elf-fold.S
	modified:   stub/src/arm.v4a-linux.elf-entry.S
	modified:   stub/src/arm.v4a-linux.elf-fold.S
	modified:   stub/src/arm64-linux.elf-entry.S
	modified:   stub/src/arm64-linux.elf-fold.S
	modified:   stub/src/i386-linux.elf-fold.S
	modified:   stub/src/mipsel.r3000-linux.elf-fold.S
	modified:   stub/src/powerpc-linux.elf-fold.S
	modified:   stub/src/powerpc64le-linux.elf-fold.S
	modified:   ../misc/testsuite/upx_testsuite_1-expected_sha256sums.sh

           ... plus all associaed *.h, *.map, *.dump in stub/
2023-10-30 08:23:52 -07:00
Markus F.X.J. Oberhumer f62576a2be CI updates and minor cleanups 2023-10-30 14:15:35 +01:00
Markus F.X.J. Oberhumer 19bf9f59e9 src: clang-format stub/tools/armpe/armpe_tester.c 2023-10-30 13:07:20 +01:00
Markus F.X.J. Oberhumer fadf7cfc7b src: work on packed_struct cleanup 2023-10-30 12:55:07 +01:00
Markus F.X.J. Oberhumer ec0c9399fa src: clang-format conf.h 2023-10-30 12:30:58 +01:00
Markus F.X.J. Oberhumer 37b923245d all: various cleanups 2023-10-30 12:17:51 +01:00
Markus F.X.J. Oberhumer 38a676f6f7 src: introduce upx::ptr_reinterpret_cast 2023-10-29 16:52:24 +01:00
Markus F.X.J. Oberhumer cd1df6f6b1 all: update version 2023-10-29 15:37:13 +01:00
Markus F.X.J. Oberhumer 4a24fe8c53 CI updates and cleanups 2023-10-29 15:12:33 +01:00
Markus F.X.J. Oberhumer 6dac3dd248 CI updates 2023-10-27 09:24:06 +02:00
Markus F.X.J. Oberhumer 37d393cbc8 src: prefer using SetFileTime() on Windows 2023-10-27 06:58:14 +02:00
Markus F.X.J. Oberhumer 27f155374a testsuite: update checksums caused by version bump 2023-10-26 12:28:52 +02:00
Markus F.X.J. Oberhumer 8102137ad7 all: post-release version bump 2023-10-26 12:25:13 +02:00
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
506 changed files with 24457 additions and 22378 deletions
+1 -27
View File
@@ -8,42 +8,16 @@ IndentWidth: 4
--- ---
Language: Cpp Language: Cpp
AccessModifierOffset: -4 AccessModifierOffset: -4
AlignConsecutiveMacros: AcrossComments
AlwaysBreakTemplateDeclarations: true AlwaysBreakTemplateDeclarations: true
AttributeMacros: AttributeMacros:
- __acc_cdecl
- __acc_cdecl_atexit
- __acc_cdecl_qsort
- __acc_cdecl_sighandler
- __acc_forceinline
- __acc_noinline
- __acc_static_forceinline
- __acc_static_noinline
- DELETED_FUNCTION - DELETED_FUNCTION
- XSPAN_DELETED_FUNCTION - XSPAN_DELETED_FUNCTION
- forceinline
- may_throw - may_throw
- noinline
- static_forceinline
- static_noinline
EmptyLineBeforeAccessModifier: Leave EmptyLineBeforeAccessModifier: Leave
SortIncludes: false SortIncludes: false
SpaceAfterCStyleCast: true SpaceAfterCStyleCast: true
Standard: Cpp03 Standard: Cpp03
StatementMacros: StatementMacros:
- ACCCHK_ASSERT
- ACCCHK_ASSERT_IS_SIGNED_T
- ACCCHK_ASSERT_IS_UNSIGNED_T
- ACCCHK_ASSERT_SIGN_T
- ACC_BLOCK_BEGIN
- ACC_COMPILE_TIME_ASSERT
- ACC_COMPILE_TIME_ASSERT_HEADER
- ACC_CXX_DISABLE_NEW_DELETE
- ACC_CXX_TRIGGER_FUNCTION
- ACC_CXX_TRIGGER_FUNCTION_IMPL
- CLANG_FORMAT_DUMMY_STATEMENT - CLANG_FORMAT_DUMMY_STATEMENT
- COMPILE_TIME_ASSERT
- COMPILE_TIME_ASSERT_ALIGNED1
WhitespaceSensitiveMacros:
- ACC_PP_MACRO_EXPAND
- ACC_PP_STRINGIZE
... ...
+3
View File
@@ -14,6 +14,9 @@
/src/stub/src/arch/**/lzma_d_c[fns].S linguist-generated /src/stub/src/arch/**/lzma_d_c[fns].S linguist-generated
/src/stub/tmp/** linguist-generated /src/stub/tmp/** linguist-generated
/misc/podman/*/packages*.txt linguist-generated
/misc/testsuite/*expected_sha256sums* linguist-generated
# #
# make GitHub language detection more accurate # make GitHub language detection more accurate
# #
-1
View File
@@ -1,6 +1,5 @@
* @markus-oberhumer @jreiser * @markus-oberhumer @jreiser
/src/p_elf* @jreiser
/src/p_lx_* @jreiser /src/p_lx_* @jreiser
/src/p_mach* @jreiser /src/p_mach* @jreiser
/src/p_unix* @jreiser /src/p_unix* @jreiser
-9
View File
@@ -1,9 +0,0 @@
version: 2
updates:
- package-ecosystem: 'github-actions'
directory: '/'
schedule:
# Check for updates to GitHub Actions every Wednesday
interval: 'weekly'
day: 'wednesday'
-42
View File
@@ -1,42 +0,0 @@
# see https://github.com/crate-ci/typos
# a generic spell-checker that works on source code is quite
# tricky, so some false positives are fine
[files]
extend-exclude = ["LICENSE", "misc/*/packages.txt", "misc/*/*/packages.txt"]
[default.extend-identifiers]
# misc variable names & symbols
acc_spawnve = "acc_spawnve"
ba = "ba"
fo = "fo"
fof = "fof"
O_WRONLY = "O_WRONLY"
# clang-analyzer-optin.cplusplus
optin = "optin"
sidelen = "sidelen"
tpos = "tpos"
# assembly sources
CArry = "CArry"
hda = "hda"
Larg = "Larg"
pard = "pard"
suble = "suble"
# identifiers are intelligently split into words and then checked again
[default.extend-words]
delt = "delt"
FO = "FO"
fo = "fo"
# parm is used like param
PARM = "PARM"
parm = "parm"
# rela: ELF relocations
RELA = "RELA"
rela = "rela"
# siz is used for size
siz = "siz"
# SEH: Structured Exception Handling
SEH = "SEH"
seh = "seh"
+90 -51
View File
@@ -9,11 +9,14 @@ name: 'CI'
on: [push, workflow_dispatch] on: [push, workflow_dispatch]
env: env:
CMAKE_REQUIRED_QUIET: OFF CMAKE_REQUIRED_QUIET: 'OFF'
CMAKE_VERBOSE_MAKEFILE: 'ON'
CTEST_OUTPUT_ON_FAILURE: 'ON'
DEBIAN_FRONTEND: noninteractive DEBIAN_FRONTEND: noninteractive
UPX_CMAKE_BUILD_FLAGS: --verbose UPX_CMAKE_BUILD_FLAGS: --verbose
# 2023-07-30 UPX_CMAKE_CONFIG_FLAGS: -Wdev --warn-uninitialized
ZIG_DIST_VERSION: 0.11.0-dev.4320+6f0a613b6 # 2023-11-08
ZIG_DIST_VERSION: 0.12.0-dev.1502+b3462b7ce
jobs: jobs:
job-rebuild-and-verify-stubs: job-rebuild-and-verify-stubs:
@@ -27,8 +30,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 +44,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 +60,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 }}
@@ -66,7 +69,9 @@ jobs:
matrix: matrix:
include: include:
- { os: ubuntu-22.04, use_m32: true } - { os: ubuntu-22.04, use_m32: true }
- { os: ubuntu-20.04, use_m32: false } # use_m32 also works here, but save some CI time - { os: ubuntu-20.04, use_m32: true } # use_m32 also works here, but save some CI time
env:
UPX_CONFIG_EXPECT_THREADS: 'ON'
steps: steps:
- name: 'Install extra 32-bit and Windows packages' - name: 'Install extra 32-bit and Windows packages'
if: ${{ matrix.use_m32 }} if: ${{ matrix.use_m32 }}
@@ -74,8 +79,12 @@ jobs:
sudo dpkg --add-architecture i386 sudo dpkg --add-architecture i386
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
# make sure that we use posix-threads (pthread/winpthreads) and NOT win32-threads
for f in i686-w64-mingw32-g++ i686-w64-mingw32-gcc x86_64-w64-mingw32-g++ x86_64-w64-mingw32-gcc; do
if test -f /usr/bin/$f-posix; then sudo update-alternatives --set $f /usr/bin/$f-posix; fi
done
- 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'
@@ -91,13 +100,13 @@ jobs:
if: ${{ matrix.use_m32 }} if: ${{ matrix.use_m32 }}
run: 'make build/extra/gcc-m32/debug' run: 'make build/extra/gcc-m32/debug'
- name: 'Build cmake extra/gcc-m32/release' - name: 'Build cmake extra/gcc-m32/release'
if: ${{ matrix.use_m32 }} if: ${{ matrix.use_m32 && (success() || failure()) }} # run this step even if the previous step failed
run: 'make build/extra/gcc-m32/release' run: 'make build/extra/gcc-m32/release'
- name: 'Build cmake extra/cross-windows-mingw32/release' - name: 'Build cmake extra/cross-windows-mingw32/release'
if: ${{ matrix.use_m32 }} if: ${{ matrix.use_m32 && (success() || failure()) }} # run this step even if the previous step failed
run: 'make build/extra/cross-windows-mingw32/release' run: 'make build/extra/cross-windows-mingw32/release'
- name: 'Build cmake extra/cross-windows-mingw64/release' - name: 'Build cmake extra/cross-windows-mingw64/release'
if: ${{ matrix.use_m32 }} if: ${{ matrix.use_m32 && (success() || failure()) }} # run this step even if the previous step failed
run: 'make build/extra/cross-windows-mingw64/release' run: 'make build/extra/cross-windows-mingw64/release'
- name: 'Make artifact' - name: 'Make artifact'
run: | run: |
@@ -108,7 +117,7 @@ jobs:
# GitHub Actions magic: set "artifact_name" environment value for use in next step # GitHub Actions magic: set "artifact_name" environment value for use in next step
echo "artifact_name=$N" >> $GITHUB_ENV echo "artifact_name=$N" >> $GITHUB_ENV
- name: ${{ format('Upload artifact {0}', env.artifact_name) }} - name: ${{ format('Upload artifact {0}', env.artifact_name) }}
uses: actions/upload-artifact@v3 uses: actions/upload-artifact@v4
with: with:
name: ${{ env.artifact_name }} name: ${{ env.artifact_name }}
path: tmp/artifact path: tmp/artifact
@@ -116,25 +125,38 @@ jobs:
run: | run: |
(cd build/extra/gcc/release && DESTDIR=$PWD/Install-with-cmake cmake --install .) (cd build/extra/gcc/release && DESTDIR=$PWD/Install-with-cmake cmake --install .)
(cd build/extra/gcc/release && DESTDIR=$PWD/Install-with-make make install) (cd build/extra/gcc/release && DESTDIR=$PWD/Install-with-make make install)
- name: 'Run basic tests' - name: 'Run ctest tests'
run: | run: |
make -C build/extra/gcc/debug test make -C build/extra/gcc/debug test
make -C build/extra/gcc/release test make -C build/extra/gcc/release test
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 basic tests 32-bit' - name: 'Run ctest tests 32-bit'
if: ${{ matrix.use_m32 }} if: ${{ matrix.use_m32 }}
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: 'Mimic ctest tests'
run: |
env -C build/extra/gcc/debug bash "$PWD"/misc/testsuite/mimic_ctest.sh
env -C build/extra/gcc/release bash "$PWD"/misc/testsuite/mimic_ctest.sh
env -C build/extra/clang/debug bash "$PWD"/misc/testsuite/mimic_ctest.sh
env -C build/extra/clang/release bash "$PWD"/misc/testsuite/mimic_ctest.sh
- name: 'Mimic ctest tests 32-bit'
if: ${{ matrix.use_m32 }}
run: |
env -C build/extra/gcc-m32/debug bash "$PWD"/misc/testsuite/mimic_ctest.sh
env -C build/extra/gcc-m32/release bash "$PWD"/misc/testsuite/mimic_ctest.sh
- 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)"
testsuite_1="$(readlink -en ./misc/testsuite/upx_testsuite_1.sh)" env -C build/extra/gcc/release bash "$PWD"/misc/testsuite/upx_testsuite_1.sh
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,21 +164,25 @@ jobs:
fail-fast: false fail-fast: false
matrix: matrix:
include: include:
# NOTE: macos does not have "env -C"; only with brew coreutils
# NOTE: macos-11 does not have "readlink -f"; only on macos >= 12 or with brew coreutils
- { os: macos-11, gcc: gcc-10, gxx: 'g++-10', testsuite: true } - { os: macos-11, gcc: gcc-10, gxx: 'g++-10', testsuite: true }
- { os: macos-12, gcc: gcc-11, gxx: 'g++-11', testsuite: true } - { os: macos-12, gcc: gcc-11, gxx: 'g++-11', testsuite: true }
- { os: macos-13, gcc: gcc-12, gxx: 'g++-12', testsuite: true } - { os: macos-13, gcc: gcc-12, gxx: 'g++-12', testsuite: true }
env:
UPX_CONFIG_EXPECT_THREADS: 'ON'
steps: steps:
- name: 'Install brew packages' - name: 'Install brew packages'
if: ${{ matrix.testsuite }} if: ${{ matrix.testsuite }}
run: | run: |
# testsuite needs working "readlink -en" and "sha256sum -b" # testsuite needs working "readlink -en" and "sha256sum -b"
if ! test -e /usr/local/opt/coreutils/libexec/gnubin/readlink; then if ! test -e /usr/local/opt/coreutils/libexec/gnubin/readlink; then
echo "===== brew leaves:"; brew leaves; echo "===== brew list:"; brew list echo "===== brew leaves:"; brew leaves; echo "===== brew list:"; brew list --versions
# only run "brew update" if needed # only run "brew update" if needed
if ! brew install coreutils; then brew update && brew install coreutils; fi if ! brew install 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 }}
@@ -188,7 +214,7 @@ jobs:
# GitHub Actions magic: set "artifact_name" environment value for use in next step # GitHub Actions magic: set "artifact_name" environment value for use in next step
echo "artifact_name=$N" >> $GITHUB_ENV echo "artifact_name=$N" >> $GITHUB_ENV
- name: ${{ format('Upload artifact {0}', env.artifact_name) }} - name: ${{ format('Upload artifact {0}', env.artifact_name) }}
uses: actions/upload-artifact@v3 uses: actions/upload-artifact@v4
with: with:
name: ${{ env.artifact_name }} name: ${{ env.artifact_name }}
path: tmp/artifact path: tmp/artifact
@@ -196,21 +222,32 @@ jobs:
run: | run: |
(cd build/extra/clang/release && DESTDIR=$PWD/Install-with-cmake cmake --install .) (cd build/extra/clang/release && DESTDIR=$PWD/Install-with-cmake cmake --install .)
(cd build/extra/clang/release && DESTDIR=$PWD/Install-with-make make install) (cd build/extra/clang/release && DESTDIR=$PWD/Install-with-make make install)
- name: 'Run basic tests' - name: 'Run ctest tests'
if: ${{ !contains(matrix.os, 'macos-13') }} # FIXME: UPX on macos-13 is broken => disable self-test for now 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
for f in ./build/extra/*/*/upx; do echo "===== $f"; $f --sysinfo -v; done
- name: 'Mimic ctest tests'
if: ${{ !contains(matrix.os, 'macos-13') }} # FIXME: UPX on macos-13 is broken => disable self-test for now
run: |
export PATH="/usr/local/opt/coreutils/libexec/gnubin:$PATH"
env -C build/extra/clang/debug bash "$PWD"/misc/testsuite/mimic_ctest.sh
#env -C build/extra/clang/release bash "$PWD"/misc/testsuite/mimic_ctest.sh
- name: 'Run file system test suite'
if: ${{ matrix.testsuite }} # for coreutils readlink
run: |
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: |
export PATH="/usr/local/opt/coreutils/libexec/gnubin:$PATH" export PATH="/usr/local/opt/coreutils/libexec/gnubin:$PATH"
export upx_testsuite_SRCDIR="$(readlink -en ../deps/upx-testsuite)" export upx_testsuite_SRCDIR="$(readlink -en ../deps/upx-testsuite)"
testsuite_1="$(readlink -en ./misc/testsuite/upx_testsuite_1.sh)" env -C build/extra/clang/release bash "$PWD"/misc/testsuite/upx_testsuite_1.sh
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,14 +255,14 @@ 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 }
env:
UPX_CONFIG_EXPECT_THREADS: 'ON'
steps: steps:
- run: git config --global core.autocrlf false
- 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'
@@ -247,11 +284,11 @@ jobs:
# GitHub Actions magic: set "artifact_name" environment value for use in next step # GitHub Actions magic: set "artifact_name" environment value for use in next step
echo "artifact_name=$N" >> $GITHUB_ENV echo "artifact_name=$N" >> $GITHUB_ENV
- name: ${{ format('Upload artifact {0}', env.artifact_name) }} - name: ${{ format('Upload artifact {0}', env.artifact_name) }}
uses: actions/upload-artifact@v3 uses: actions/upload-artifact@v4
with: with:
name: ${{ env.artifact_name }} name: ${{ env.artifact_name }}
path: tmp/artifact path: tmp/artifact
- name: 'Run basic tests' - name: 'Run ctest tests'
if: ${{ matrix.arch != 'amd64_arm64' }} if: ${{ matrix.arch != 'amd64_arm64' }}
run: | run: |
ctest --test-dir build/debug -C Debug ctest --test-dir build/debug -C Debug
@@ -261,18 +298,16 @@ jobs:
shell: bash shell: bash
run: | run: |
export upx_testsuite_SRCDIR="$(readlink -en ../deps/upx-testsuite)" export upx_testsuite_SRCDIR="$(readlink -en ../deps/upx-testsuite)"
testsuite_1="$(readlink -en ./misc/testsuite/upx_testsuite_1.sh)" env -C build/release/Release bash "$PWD"/misc/testsuite/upx_testsuite_1.sh
env -C build/release/Release upx_exe=./upx bash "$testsuite_1"
job-windows-toolchains: # build "by hand" using cmd.exe job-windows-toolchains: # build "by hand" using cmd.exe
if: ${{ true }} if: github.repository_owner == 'upx'
needs: [ job-rebuild-and-verify-stubs ] needs: [ job-rebuild-and-verify-stubs ]
name: ${{ format('windows {0}', matrix.name) }} name: ${{ format('windows {0}', matrix.name) }}
runs-on: ${{ matrix.os }} runs-on: ${{ matrix.os }}
env: env:
C: ${{ matrix.name }} C: ${{ matrix.name }}
B: release B: release
H: 'd:\a\upx\upx'
strategy: strategy:
fail-fast: false fail-fast: false
matrix: matrix:
@@ -286,14 +321,17 @@ jobs:
- { name: i386-win32-vs2019, os: windows-2019, vsversion: 2019, arch: amd64_x86 } - { name: i386-win32-vs2019, os: windows-2019, vsversion: 2019, arch: amd64_x86 }
- { 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:
- run: git config --global core.autocrlf false
- 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
run: | run: |
git clone --depth=1 https://github.com/upx/upx-testsuite ../deps/upx-testsuite git clone --depth=1 https://github.com/upx/upx-testsuite ../deps/upx-testsuite
mkdir -p -v build/$C/$B/{bzip2,ucl,upx,zlib,zstd} mkdir -p -v build/$C/$B/{bzip2,ucl,upx,zlib,zstd}
repository_name="${GITHUB_REPOSITORY##*/}" # basename
echo "H=d:\\a\\$repository_name\\$repository_name" >> $GITHUB_ENV
- name: 'Set up Developer Command Prompt' - name: 'Set up Developer Command Prompt'
uses: ilammy/msvc-dev-cmd@v1 uses: ilammy/msvc-dev-cmd@v1
with: with:
@@ -306,12 +344,13 @@ 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 =====
cd %BDIR%\bzip2 cd %BDIR%\bzip2
@rem %RUN_CL% -J -O2 -W4 -wd4127 -wd4244 -wd4267 -WX %DEFS% -c %H%\vendor\bzip2\*.c @rem %RUN_CL% -J -O2 -W4 -wd4127 -wd4244 -wd4267 -WX %DEFS% -DBZ_NO_STDIO -c %H%\vendor\bzip2\*.c
@rem %RUN_LIB% -out:bzip2.lib *.obj @rem %RUN_LIB% -out:bzip2.lib *.obj
@REM ===== build UCL ===== @REM ===== build UCL =====
cd %BDIR%\ucl cd %BDIR%\ucl
@@ -332,7 +371,7 @@ jobs:
set s=%H%\src set s=%H%\src
cat .GITREV.txt cat .GITREV.txt
set /p GITREV=<.GITREV.txt set /p GITREV=<.GITREV.txt
set UPX_DEFS=-DUPX_CONFIG_DISABLE_WSTRICT=0 -DUPX_CONFIG_DISABLE_WERROR=0 -DWITH_BZIP2=0 -DWITH_ZSTD=0 set UPX_DEFS=-DUPX_CONFIG_DISABLE_WSTRICT=0 -DUPX_CONFIG_DISABLE_WERROR=0 -DWITH_THREADS=0 -DWITH_BZIP2=0 -DWITH_ZSTD=0
set UPX_LIBS=%BDIR%\ucl\ucl.lib %BDIR%\zlib\zlib.lib set UPX_LIBS=%BDIR%\ucl\ucl.lib %BDIR%\zlib\zlib.lib
@rem set UPX_LIBS=%BDIR%\bzip2\bzip2.lib %BDIR%\ucl\ucl.lib %BDIR%\zlib\zlib.lib %BDIR%\zstd\zstd.lib @rem set UPX_LIBS=%BDIR%\bzip2\bzip2.lib %BDIR%\ucl\ucl.lib %BDIR%\zlib\zlib.lib %BDIR%\zstd\zstd.lib
set sources=%s%\*.cpp %s%\check\*.cpp %s%\compress\*.cpp %s%\console\*.cpp %s%\filter\*.cpp %s%\util\*.cpp set sources=%s%\*.cpp %s%\check\*.cpp %s%\compress\*.cpp %s%\console\*.cpp %s%\filter\*.cpp %s%\util\*.cpp
@@ -346,7 +385,7 @@ jobs:
# GitHub Actions magic: set "artifact_name" environment value for use in next step # GitHub Actions magic: set "artifact_name" environment value for use in next step
echo "artifact_name=$N" >> $GITHUB_ENV echo "artifact_name=$N" >> $GITHUB_ENV
- name: ${{ format('Upload artifact {0}', env.artifact_name) }} - name: ${{ format('Upload artifact {0}', env.artifact_name) }}
uses: actions/upload-artifact@v3 uses: actions/upload-artifact@v4
with: with:
name: ${{ env.artifact_name }} name: ${{ env.artifact_name }}
path: tmp/artifact path: tmp/artifact
@@ -358,6 +397,7 @@ jobs:
cd $Env:H\build\$Env:C\$Env:B\upx cd $Env:H\build\$Env:C\$Env:B\upx
$Env:UPX = "--no-color --no-progress" $Env:UPX = "--no-color --no-progress"
.\upx.exe --version .\upx.exe --version
.\upx.exe --sysinfo -v
.\upx.exe upx.exe -o upx_packed.exe .\upx.exe upx.exe -o upx_packed.exe
dir *.exe dir *.exe
.\upx.exe -l upx_packed.exe .\upx.exe -l upx_packed.exe
@@ -368,15 +408,14 @@ jobs:
shell: bash shell: bash
run: | run: |
export upx_testsuite_SRCDIR="$(readlink -en ../deps/upx-testsuite)" export upx_testsuite_SRCDIR="$(readlink -en ../deps/upx-testsuite)"
testsuite_1="$(readlink -en ./misc/testsuite/upx_testsuite_1.sh)" env -C build/$C/$B/upx upx_exe=./upx.exe bash "$PWD"/misc/testsuite/upx_testsuite_1.sh
env -C build/$C/$B/upx upx_exe=./upx.exe bash "$testsuite_1"
job-linux-zigcc: # uses cmake + make job-linux-zigcc: # uses cmake + make
if: ${{ 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
container: 'alpine:3.18' # older versions such as alpine:3.12 also work; no-container also works container: 'alpine:3.19' # older versions such as alpine:3.12 also work; no-container also works
strategy: strategy:
fail-fast: false fail-fast: false
matrix: matrix:
@@ -391,7 +430,8 @@ jobs:
- { 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 }
@@ -406,6 +446,7 @@ jobs:
# { zig_target: x86_64-macos.13.0-none } # { zig_target: x86_64-macos.13.0-none }
- { zig_target: x86_64-windows-gnu } - { zig_target: x86_64-windows-gnu }
env: env:
UPX_CONFIG_EXPECT_THREADS: 'ON'
# for zig-cc wrapper scripts (see below): # for zig-cc wrapper scripts (see below):
ZIG_CPPFLAGS: -DUPX_DOCTEST_CONFIG_MULTITHREADING ZIG_CPPFLAGS: -DUPX_DOCTEST_CONFIG_MULTITHREADING
ZIG_FLAGS: ${{ matrix.zig_flags }} ZIG_FLAGS: ${{ matrix.zig_flags }}
@@ -422,7 +463,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
@@ -475,7 +516,7 @@ jobs:
# GitHub Actions magic: set "artifact_name" environment value for use in next step # GitHub Actions magic: set "artifact_name" environment value for use in next step
echo "artifact_name=$N" >> $GITHUB_ENV echo "artifact_name=$N" >> $GITHUB_ENV
- name: ${{ format('Upload artifact {0}', env.artifact_name) }} - name: ${{ format('Upload artifact {0}', env.artifact_name) }}
uses: actions/upload-artifact@v3 uses: actions/upload-artifact@v4
with: with:
name: ${{ env.artifact_name }} name: ${{ env.artifact_name }}
path: tmp/artifact path: tmp/artifact
@@ -484,5 +525,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:
@@ -1,38 +0,0 @@
# Copyright (C) Markus Franz Xaver Johannes Oberhumer
# see https://docs.github.com/en/actions/managing-issues-and-pull-requests/closing-inactive-issues
# see https://github.com/actions/stale
# Automatically closing issues is far from perfect, but then we only
# have limited resources and this approach favors issues that people
# actually care about.
#
# also see:
# "Should I Stale or Should I Close? An Analysis of a Bot that Closes
# Abandoned Issues and Pull Request".
# https://igorwiese.com/images/papers/Paper_BotSE_19.pdf
name: 'GitHub - Close inactive issues'
on:
schedule: [cron: '50 3 * * 3'] # run weekly Wednesday 03:50 UTC
workflow_dispatch:
jobs:
close-issues:
name: 'Close inactive issues'
runs-on: ubuntu-latest
permissions:
issues: write
pull-requests: write
steps:
- uses: actions/stale@v8
with:
operations-per-run: 300
exempt-all-milestones: true
exempt-issue-labels: 'blocker,bug,enhancement,help wanted,regression'
days-before-stale: 60
days-before-close: 30
stale-issue-message: 'This issue is stale because it has been open 60 days with no activity. Please remove the stale label or add a comment or this issue will be closed in 30 days.'
stale-pr-message: 'This PR is stale because it has been open 60 days with no activity. Please remove the stale label or add a comment or this PR will be closed in 30 days.'
close-issue-message: 'This issue was closed because it has been stalled for 30 days with no activity. Please feel free to reopen.'
close-pr-message: 'This PR was closed because it has been stalled for 30 days with no activity. Please feel free to reopen.'
repo-token: ${{ secrets.GITHUB_TOKEN }}
@@ -1,17 +0,0 @@
# Copyright (C) Markus Franz Xaver Johannes Oberhumer
name: 'GitHub - Close pull requests'
on:
#pull_request:
workflow_dispatch:
jobs:
close-pull-requests:
name: 'Close pull requests'
runs-on: ubuntu-latest
permissions:
pull-requests: write
steps:
- name: 'Close pull requests'
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
gh pr list --repo='${{ github.repository }}' --state=open --json=number | jq '.[].number' | xargs -r -n1 -- gh pr close --repo='${{ github.repository }}'
-19
View File
@@ -1,19 +0,0 @@
# Copyright (C) Markus Franz Xaver Johannes Oberhumer
# see https://github.com/crate-ci/typos
name: 'Misc - Spell check'
on:
workflow_dispatch:
env:
DEBIAN_FRONTEND: noninteractive
jobs:
job-spell-check:
name: 'Spell check'
runs-on: ubuntu-latest
steps:
- name: 'Check out code'
uses: actions/checkout@v3
with: { submodules: false }
- name: 'Spell check with crate-ci/typos'
uses: crate-ci/typos@master
with: { config: ./.github/typos_config.toml }
@@ -1,30 +0,0 @@
# Copyright (C) Markus Franz Xaver Johannes Oberhumer
name: 'Static Analyzer - clang-analyzer'
on:
schedule: [cron: '10 5 * * 3'] # run weekly Wednesday 05:10 UTC
workflow_dispatch:
env:
CMAKE_REQUIRED_QUIET: OFF
DEBIAN_FRONTEND: noninteractive
jobs:
job-analyze-clang-analyzer: # uses cmake + make
strategy:
fail-fast: false
matrix: {container: ['alpine:3.16','alpine:3.17','alpine:3.18','alpine:edge','i386/alpine:edge']}
name: ${{ format('Analyze {0}', matrix.container) }}
runs-on: ubuntu-latest
container: ${{ matrix.container }}
steps:
- name: ${{ format('Install packages {0}', matrix.container) }}
run: 'apk update && apk upgrade && apk add clang clang-analyzer cmake g++ git make'
- name: ${{ format('Check out UPX {0} source code', github.ref_name) }}
run: |
git clone --branch "$GITHUB_REF_NAME" --depth 1 https://github.com/upx/upx
git -C upx submodule update --init
- name: 'Perform clang-analyzer scan-build Analysis Debug'
run: 'make -C upx build/analyze/clang-analyzer/debug'
- name: 'Perform clang-analyzer scan-build Analysis Release'
if: success() || failure() # run this step even if the previous step failed
run: 'make -C upx build/analyze/clang-analyzer/release'
@@ -1,30 +0,0 @@
# Copyright (C) Markus Franz Xaver Johannes Oberhumer
name: 'Static Analyzer - clang-tidy'
on:
schedule: [cron: '30 5 * * 3'] # run weekly Wednesday 05:30 UTC
workflow_dispatch:
env:
CMAKE_REQUIRED_QUIET: OFF
DEBIAN_FRONTEND: noninteractive
jobs:
job-analyze-clang-tidy: # uses cmake + make
strategy:
fail-fast: false
matrix: {container: ['alpine:edge','i386/alpine:edge']}
name: ${{ format('Analyze clang-tidy {0}', matrix.container) }}
runs-on: ubuntu-latest
container: ${{ matrix.container }}
steps:
- name: ${{ format('Install packages {0}', matrix.container) }}
run: 'apk update && apk upgrade && apk add clang clang-extra-tools cmake g++ git make python3'
- name: ${{ format('Check out UPX {0} source code', github.ref_name) }}
run: |
git clone --branch "$GITHUB_REF_NAME" --depth 1 https://github.com/upx/upx
git -C upx submodule update --init
- name: 'Perform clang-tidy Analysis Debug'
run: 'make -k -C upx build/analyze/clang-tidy/debug'
- name: 'Perform clang-tidy Analysis Release'
if: success() || failure() # run this step even if the previous step failed
run: 'make -k -C upx build/analyze/clang-tidy/release'
@@ -1,34 +0,0 @@
# Copyright (C) Markus Franz Xaver Johannes Oberhumer
name: 'Static Analyzer - CodeQL'
on:
schedule: [cron: '50 5 * * 3'] # run weekly Wednesday 05:50 UTC
workflow_dispatch:
env:
CMAKE_REQUIRED_QUIET: OFF
DEBIAN_FRONTEND: noninteractive
jobs:
job-analyze-codeql:
name: Analyze
runs-on: ubuntu-latest
permissions:
actions: read
contents: read
security-events: write
strategy:
fail-fast: false
matrix:
language: [ 'cpp' ]
steps:
- name: Checkout repository
uses: actions/checkout@v3
with: { submodules: true }
- name: Initialize CodeQL
uses: github/codeql-action/init@v2
with:
languages: ${{ matrix.language }}
- name: Autobuild
uses: github/codeql-action/autobuild@v2
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v2
-135
View File
@@ -1,135 +0,0 @@
# Copyright (C) Markus Franz Xaver Johannes Oberhumer
# test minimal number of packages required for building UPX under Alpine Linux
# clang: apk add clang cmake make
# gcc: apk add cmake g++ make
name: 'Test - Minimal Alpine build'
on: [workflow_dispatch]
env:
CMAKE_REQUIRED_QUIET: OFF
DEBIAN_FRONTEND: noninteractive
jobs:
job-alpine-clang: # uses cmake + make
strategy: { matrix: { container: ['alpine:edge','i386/alpine:edge'] } }
name: ${{ format('clang {0}', matrix.container) }}
runs-on: ubuntu-latest
container: ${{ matrix.container }}
steps:
- name: ${{ format('Build clang {0}', matrix.container) }}
run: |
apk update && apk upgrade && apk add clang cmake make
wget https://github.com/upx/upx/releases/download/v4.0.2/upx-4.0.2-src.tar.xz
tar -xoaf upx-*-src.tar.xz
cd upx-*-src
make build/debug CC="clang -static" CXX="clang++ -static"
make build/release CC="clang -static" CXX="clang++ -static"
make -C build/debug test
make -C build/release test
make -C build/release install DESTDIR="$PWD/Install"
N=$(echo "upx-test-alpine-linux-clang-${{ matrix.container }}" | sed 's/[^0-9a-zA-Z_.-]/-/g')
echo "artifact_name=$N" >> $GITHUB_ENV
- name: ${{ format('Upload artifact {0}', env.artifact_name) }}
if: ${{ !startsWith(matrix.container, 'i386/') }} # i386: missing nodejs on host
uses: actions/upload-artifact@v3
with:
name: ${{ env.artifact_name }}
path: 'upx*/build/*/upx'
job-alpine-gcc: # uses cmake + make
strategy: { matrix: { container: ['alpine:edge','i386/alpine:edge'] } }
name: ${{ format('gcc {0}', matrix.container) }}
runs-on: ubuntu-latest
container: ${{ matrix.container }}
steps:
- name: ${{ format('Build gcc {0}', matrix.container) }}
run: |
apk update && apk upgrade && apk add cmake g++ make
wget https://github.com/upx/upx/releases/download/v4.0.2/upx-4.0.2-src.tar.xz
tar -xoaf upx-*-src.tar.xz
cd upx-*-src
make build/debug CC="gcc -static" CXX="g++ -static"
make build/release CC="gcc -static" CXX="g++ -static"
make -C build/debug test
make -C build/release test
make -C build/release install DESTDIR="$PWD/Install"
N=$(echo "upx-test-alpine-linux-gcc-${{ matrix.container }}" | sed 's/[^0-9a-zA-Z_.-]/-/g')
echo "artifact_name=$N" >> $GITHUB_ENV
- name: ${{ format('Upload artifact {0}', env.artifact_name) }}
if: ${{ !startsWith(matrix.container, 'i386/') }} # i386: missing nodejs on host
uses: actions/upload-artifact@v3
with:
name: ${{ env.artifact_name }}
path: 'upx*/build/*/upx'
job-alpine-by-hand: # uses a POSIX-compliant shell
# ...and also uses a subdirectory "upx with space" in order to detect possible quoting issues
# ...and also uses ccache as we are running the same build-script again and again
if: ${{ true }}
strategy: { matrix: { container: ['alpine:3.9','alpine:edge'] } }
name: ${{ format('gcc by-hand {0}', matrix.container) }}
runs-on: ubuntu-latest
container: ${{ matrix.container }}
steps:
- name: ${{ format('Install packages {0}', matrix.container) }}
run: |
# install ccache, g++, git and various POSIX shells
shells="bash dash loksh mksh zsh"
case ${{ matrix.container }} in
*:edge) shells="$shells oksh yash" ;;
esac
echo "installing shells: $shells"
apk update && apk upgrade && apk add ccache g++ git $shells
# enable ccache
echo -e "CC=ccache gcc\nCXX=ccache g++ -std=gnu++17" >> $GITHUB_ENV
# this seems to be needed when running in a container (beause of UID mismatch??)
git config --global --add safe.directory '*'
- name: 'Check out code'
uses: actions/checkout@v3
with:
submodules: true
path: 'upx with space'
- name: 'Build by-hand with bash'
run: 'bash "./upx with space/misc/scripts/build_upx_by_hand.sh"'
- name: 'Build by-hand with bash --posix'
run: 'bash --posix "./upx with space/misc/scripts/build_upx_by_hand.sh"'
- name: 'Build by-hand with busybox ash'
run: 'busybox ash "./upx with space/misc/scripts/build_upx_by_hand.sh"'
- name: 'Build by-hand with busybox sh'
run: 'busybox sh "./upx with space/misc/scripts/build_upx_by_hand.sh"'
- name: 'Build by-hand with dash'
run: 'dash "./upx with space/misc/scripts/build_upx_by_hand.sh"'
- name: 'Build by-hand with loksh'
run: 'ksh "./upx with space/misc/scripts/build_upx_by_hand.sh"'
- name: 'Build by-hand with loksh -o posix'
run: 'ksh -o posix "./upx with space/misc/scripts/build_upx_by_hand.sh"'
- name: 'Build by-hand with loksh -o sh'
run: 'ksh -o sh "./upx with space/misc/scripts/build_upx_by_hand.sh"'
- name: 'Build by-hand with mksh'
run: 'mksh "./upx with space/misc/scripts/build_upx_by_hand.sh"'
- name: 'Build by-hand with mksh -o posix'
run: 'mksh -o posix "./upx with space/misc/scripts/build_upx_by_hand.sh"'
- name: 'Build by-hand with mksh -o sh'
run: 'mksh -o sh "./upx with space/misc/scripts/build_upx_by_hand.sh"'
- name: 'Build by-hand with oksh'
if: ${{ contains(matrix.container, ':edge') }}
run: 'oksh "./upx with space/misc/scripts/build_upx_by_hand.sh"'
- name: 'Build by-hand with oksh -o posix'
if: ${{ contains(matrix.container, ':edge') }}
run: 'oksh -o posix "./upx with space/misc/scripts/build_upx_by_hand.sh"'
- name: 'Build by-hand with oksh -o sh'
if: ${{ contains(matrix.container, ':edge') }}
run: 'oksh -o sh "./upx with space/misc/scripts/build_upx_by_hand.sh"'
- name: 'Build by-hand with yash'
if: ${{ contains(matrix.container, ':edge') }}
run: 'yash "./upx with space/misc/scripts/build_upx_by_hand.sh"'
- name: 'Build by-hand with zsh'
run: 'zsh "./upx with space/misc/scripts/build_upx_by_hand.sh"'
- name: 'Build by-hand with zsh --emulate ksh'
run: 'zsh --emulate ksh "./upx with space/misc/scripts/build_upx_by_hand.sh"'
- name: 'Build by-hand with zsh --emulate sh'
run: 'zsh --emulate sh "./upx with space/misc/scripts/build_upx_by_hand.sh"'
- name: 'Show ccache stats'
run: |
ccache -s
ccache -p
-132
View File
@@ -1,132 +0,0 @@
# Copyright (C) Markus Franz Xaver Johannes Oberhumer
name: 'Test - CMake default build type'
on: [workflow_dispatch]
env:
CMAKE_REQUIRED_QUIET: OFF
DEBIAN_FRONTEND: noninteractive
jobs:
#
# single-config generators - these use and respect CMAKE_BUILD_TYPE
#
cmake-make:
runs-on: ubuntu-latest
steps:
- name: 'Check out code'
uses: actions/checkout@v3
with: { submodules: true }
- name: 'Config, build, test and install'
run: |
cmake -S . -B build/default -G "Unix Makefiles"
cmake --build build/default --parallel --verbose
ctest --test-dir build/default
(cd build/default && DESTDIR=$PWD/Install-default cmake --install .)
# "make test" also works
env -C build/default make test
# "make install" also works
env -C build/default DESTDIR=./Install-with-make make install
cmake-ninja:
runs-on: ubuntu-latest
steps:
- name: 'Check out code'
uses: actions/checkout@v3
with: { submodules: true }
- name: 'Config, build, test and install'
run: |
test -f /usr/bin/ninja || sudo apt-get install -y ninja-build
cmake -S . -B build/default -G Ninja
cmake --build build/default --parallel --verbose
ctest --test-dir build/default
(cd build/default && DESTDIR=$PWD/Install-default cmake --install .)
# "ninja test" also works
env -C build/default ninja test
# "ninja install" also works
env -C build/default DESTDIR=./Install-with-ninja ninja install
cmake-nmake:
runs-on: windows-2022
steps:
- name: 'Check out code'
uses: actions/checkout@v3
with: { submodules: true }
- name: 'Set up Developer Command Prompt'
uses: ilammy/msvc-dev-cmd@v1
with:
vsversion: 2022
arch: amd64
- name: 'Config, build, test and install'
run: |
cmake -S . -B build/default -G "NMake Makefiles"
cmake --build build/default --parallel --verbose
ctest --test-dir build/default
# "cmake --install" works on Windows as well, nice
env -C build/default DESTDIR=./Install-default cmake --install .
# "nmake test" also works
env -C build/default nmake test
# "nmake install" also works
env -C build/default DESTDIR=./Install-with-nmake nmake install
#
# multi-config generators - these use CMAKE_CONFIGURATION_TYPES, but the defaults seem inconsistent
# => when using multi-config generators always explicitly pass the requested build-config
#
# ninja-multi-config seems to use the *first* element of CMAKE_CONFIGURATION_TYPES; nice
cmake-ninja-multi-config:
runs-on: ubuntu-latest
steps:
- name: 'Check out code'
uses: actions/checkout@v3
with: { submodules: true }
- name: 'Config, build, test and install'
run: |
test -f /usr/bin/ninja || sudo apt-get install -y ninja-build
cmake -S . -B build/default -G "Ninja Multi-Config"
cmake --build build/default --parallel --verbose
# multi-config: ctest NEEDS a config
ctest --test-dir build/default -C Release
(cd build/default && DESTDIR=$PWD/Install-default cmake --install .)
# "ninja test" also works with multi-config
env -C build/default ninja test
# "ninja install" also works with multi-config
env -C build/default DESTDIR=./Install-with-ninja ninja install
# vsstudio-multi-config (msbuild) seems to use "Debug" by default
cmake-vsstudio-multi-config:
runs-on: windows-2022
steps:
- name: 'Check out code'
uses: actions/checkout@v3
with: { submodules: true }
- name: 'Set up Developer Command Prompt'
uses: ilammy/msvc-dev-cmd@v1
with:
vsversion: 2022
arch: amd64
- name: 'Config, build and test'
run: |
cmake -S . -B build/default
cmake --build build/default --parallel --verbose
# multi-config: ctest NEEDS a config
ctest --test-dir build/default -C Debug
# TODO: does cmake --install work?
# xcode-multi-config (xcodebuild) seems to use "Debug" by default, except for "cmake --install" (BUG?)
cmake-xcode-multi-config:
runs-on: macos-12
steps:
- name: 'Check out code'
uses: actions/checkout@v3
with: { submodules: true }
- name: 'Config, build, test and install'
run: |
cmake -S . -B build/default -G Xcode
cmake --build build/default --parallel --verbose
# multi-config: ctest NEEDS a config
ctest --test-dir build/default -C Debug
# BUG(?) multi-config: cmake --install defaults to "Release" !!
(cd build/default && DESTDIR=$PWD/Install-default cmake --install . --config Debug)
@@ -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:
@@ -1,54 +0,0 @@
# Copyright (C) Markus Franz Xaver Johannes Oberhumer
# build with 'cmake -G Xcode'
name: 'Weekly CI - cmake macOS Xcode'
on:
schedule: [cron: '20 4 * * 3'] # run weekly Wednesday 04:20 UTC
workflow_dispatch:
env:
CMAKE_REQUIRED_QUIET: OFF
DEBIAN_FRONTEND: noninteractive
jobs:
job-cmake-macos-xcode: # uses cmake + xcodebuild
name: ${{ format('{0} cmake Xcode', matrix.os) }}
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
include:
- { os: macos-11, run_test: true }
- { os: macos-12, run_test: true }
- { os: macos-13, run_test: false } # TODO: enable once UPX fully works on macos-13
steps:
- name: 'Check out code'
uses: actions/checkout@v3
with: { submodules: true }
- { name: 'Config cmake Xcode', run: 'cmake -S . -B build/xcode -G Xcode' }
- { name: 'Build cmake Xcode default', run: 'cmake --build build/xcode' }
- { name: 'Build cmake Xcode Debug', run: 'cmake --build build/xcode --config Debug' }
- { name: 'Build cmake Xcode Release', run: 'cmake --build build/xcode --config Release' }
- name: 'Make artifact'
run: |
N=$(echo "upx-${GITHUB_REF_NAME}-${GITHUB_SHA:0:7}-weekly-ci-xcode-${{ matrix.os }}" | sed 's/[^0-9a-zA-Z_.-]/-/g')
mkdir -p "tmp/artifact/$N"
(cd build && rsync -R -a */*/upx "../tmp/artifact/$N/")
(cd tmp/artifact && gtar --sort=name -czf "$N.tar.gz" "$N" && rm -rf "./$N")
# GitHub Actions magic: set "artifact_name" environment value for use in next step
echo "artifact_name=$N" >> $GITHUB_ENV
- name: ${{ format('Upload artifact {0}', env.artifact_name) }}
uses: actions/upload-artifact@v3
with:
name: ${{ env.artifact_name }}
path: tmp/artifact
- name: 'Run basic tests'
if: ${{ matrix.run_test }}
run: |
ctest --test-dir build/xcode -C Debug
ctest --test-dir build/xcode -C Release
- name: 'Run install tests'
run: |
(cd build/xcode && DESTDIR=$PWD/Install-default cmake --install .)
(cd build/xcode && DESTDIR=$PWD/Install-debug cmake --install . --config Debug)
(cd build/xcode && DESTDIR=$PWD/Install-release cmake --install . --config Release)
ls -l build/xcode/Install-*/usr/local/bin/upx
@@ -1,76 +0,0 @@
# Copyright (C) Markus Franz Xaver Johannes Oberhumer
# build with 'cmake -G "NMake Makefiles"'
name: 'Weekly CI - cmake Windows NMake'
on:
schedule: [cron: '30 4 * * 3'] # run weekly Wednesday 04:30 UTC
workflow_dispatch:
env:
CMAKE_REQUIRED_QUIET: OFF
DEBIAN_FRONTEND: noninteractive
jobs:
job-cmake-windows-nmake: # uses cmake + nmake
name: ${{ format('vs{0} {1} {2}', matrix.vsversion, matrix.arch, matrix.clang_cl && 'clang-cl' || '') }}
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
include:
# msvc
- { os: windows-2019, vsversion: 2019, arch: amd64 }
- { os: windows-2019, vsversion: 2019, arch: amd64_arm64 }
- { os: windows-2019, vsversion: 2019, arch: amd64_x86 }
- { os: windows-2022, vsversion: 2022, arch: amd64 }
- { os: windows-2022, vsversion: 2022, arch: amd64_arm64 }
- { os: windows-2022, vsversion: 2022, arch: amd64_x86 }
# clang-cl
- { os: windows-2022, vsversion: 2022, arch: amd64, clang_cl: true }
steps:
- name: 'Check out code'
uses: actions/checkout@v3
with: { submodules: true }
- name: 'Set up Developer Command Prompt'
uses: ilammy/msvc-dev-cmd@v1
with:
vsversion: ${{ matrix.vsversion }}
arch: ${{ matrix.arch }}
- name: 'Build cmake NMake Debug'
shell: cmd
run: |
set X=${{ matrix.clang_cl && '-DCMAKE_C_COMPILER=clang-cl -DCMAKE_CXX_COMPILER=clang-cl' || '' }}
cmake -S . -B build/debug -G "NMake Makefiles" -DCMAKE_VERBOSE_MAKEFILE=ON -DCMAKE_BUILD_TYPE=Debug %X%
cd build/debug
nmake
dir *.exe
- name: 'Build cmake NMake Release'
shell: cmd
run: |
set X=${{ matrix.clang_cl && '-DCMAKE_C_COMPILER=clang-cl -DCMAKE_CXX_COMPILER=clang-cl' || '' }}
cmake -S . -B build/release -G "NMake Makefiles" -DCMAKE_VERBOSE_MAKEFILE=ON %X%
cd build/release
nmake
dir *.exe
- name: 'Make artifact'
shell: bash
run: |
X="${{ matrix.clang_cl && '-clang-cl' || '' }}"
N=$(echo "upx-${GITHUB_REF_NAME}-${GITHUB_SHA:0:7}-weekly-ci-nmake-vs${{ matrix.vsversion }}-${{ matrix.arch }}$X" | sed 's/[^0-9a-zA-Z_.-]/-/g')
mkdir -p "tmp/artifact/$N"
(cd build && cp -ai --parents */upx.exe "../tmp/artifact/$N")
# GitHub Actions magic: set "artifact_name" environment value for use in next step
echo "artifact_name=$N" >> $GITHUB_ENV
- name: ${{ format('Upload artifact {0}', env.artifact_name) }}
uses: actions/upload-artifact@v3
with:
name: ${{ env.artifact_name }}
path: tmp/artifact
- name: 'Run basic tests'
if: ${{ matrix.arch != 'amd64_arm64' }}
run: |
ctest --test-dir build/debug
ctest --test-dir build/release
- name: 'Run install tests'
run: |
env DESTDIR=./Install-debug cmake --install build/debug
env DESTDIR=./Install-release cmake --install build/release
-126
View File
@@ -1,126 +0,0 @@
# Copyright (C) Markus Franz Xaver Johannes Oberhumer
# build with "zig cc"; see https://ziglang.org/download/
name: 'Weekly CI - zigcc'
on:
schedule: [cron: '40 4 * * 3'] # run weekly Wednesday 04:40 UTC
workflow_dispatch:
env:
CMAKE_REQUIRED_QUIET: OFF
DEBIAN_FRONTEND: noninteractive
# 2023-07-30
ZIG_DIST_VERSION: 0.11.0-dev.4320+6f0a613b6
jobs:
job-linux-zigcc: # uses cmake + make
name: ${{ format('zigcc {0} {1}', matrix.zig_target, matrix.zig_pic) }}
runs-on: ubuntu-latest
container: 'alpine:3.18' # older versions such as alpine:3.12 also work; no-container also works
strategy:
fail-fast: false
matrix:
include:
- { zig_target: aarch64-linux-musl }
- { zig_target: aarch64-linux-musl, zig_pic: -fPIE }
- { zig_target: aarch64-macos-none }
- { zig_target: aarch64-macos.11.0-none }
- { zig_target: aarch64-macos.12.0-none }
- { zig_target: aarch64-macos.13.0-none }
- { zig_target: aarch64-windows-gnu }
- { zig_target: arm-linux-musleabihf }
- { zig_target: arm-linux-musleabihf, zig_pic: -fPIE }
- { zig_target: i386-linux-musl }
- { zig_target: i386-windows-gnu }
- { zig_target: mips-linux-musl }
- { zig_target: mipsel-linux-musl }
- { zig_target: powerpc-linux-musl }
- { zig_target: powerpc64-linux-musl }
- { zig_target: powerpc64le-linux-musl }
- { zig_target: x86_64-linux-musl }
- { zig_target: x86_64-linux-musl, zig_pic: -fPIE }
- { zig_target: x86_64-macos-none }
- { zig_target: x86_64-macos.11.0-none }
- { zig_target: x86_64-macos.12.0-none }
- { zig_target: x86_64-macos.13.0-none }
- { zig_target: x86_64-windows-gnu }
env:
# for zig-cc wrapper scripts (see below):
ZIG_CPPFLAGS: -DUPX_DOCTEST_CONFIG_MULTITHREADING
ZIG_FLAGS: ${{ matrix.zig_flags }}
ZIG_PIC: ${{ matrix.zig_pic }}
ZIG_TARGET: ${{ matrix.zig_target }}
steps:
- name: 'Install Alpine Linux container packages'
if: ${{ job.container }}
shell: sh
run: |
apk update && apk upgrade && apk add bash cmake file git make tar xz
# set PATH like in Ubuntu
echo "PATH=$HOME/.local/bin:$PATH" >> $GITHUB_ENV
# this seems to be needed when running in a container (beause of UID mismatch??)
git config --global --add safe.directory '*'
- name: 'Check out code'
uses: actions/checkout@v3
with: { submodules: true }
- name: ${{ format('Install Zig {0}', env.ZIG_DIST_VERSION) }}
shell: bash
run: |
# GitHub Actions magic: set "UPX_GITREV_SHORT" environment value for use in steps below
rev=$(git rev-parse --short=7 HEAD)
echo "UPX_GITREV_SHORT=$rev" >> $GITHUB_ENV
# update ZIG_TARGET (i386 => x86)
ZIG_TARGET=${ZIG_TARGET/i386-/x86-}
echo "ZIG_TARGET=$ZIG_TARGET" >> $GITHUB_ENV
# install zig; note that ~/.local/bin is included in the default $PATH on Ubuntu
mkdir -p -v ~/.local/bin
cd ~/.local/bin
ZIG_DIST_NAME=zig-linux-x86_64-${ZIG_DIST_VERSION}
wget -q https://ziglang.org/builds/${ZIG_DIST_NAME}.tar.xz
ls -l ${ZIG_DIST_NAME}.tar.xz
tar -xoJf ${ZIG_DIST_NAME}.tar.xz
rm ${ZIG_DIST_NAME}.tar.xz
ln -s -v ${ZIG_DIST_NAME}/zig zig
#echo "PATH=$PATH" && which zig
echo -n 'zig version: '; zig version
# create wrapper scripts (needed for CMake)
echo -e '#!/bin/sh\nexec zig ar "$@"' > zig-ar
echo -e '#!/bin/sh\nexec zig cc -target $ZIG_TARGET $ZIG_PIC $ZIG_FLAGS $ZIG_CPPFLAGS $ZIG_CFLAGS "$@"' > zig-cc
echo -e '#!/bin/sh\nexec zig c++ -target $ZIG_TARGET $ZIG_PIC $ZIG_FLAGS $ZIG_CPPFLAGS $ZIG_CXXFLAGS "$@"' > zig-cxx
echo -e '#!/bin/sh\nexec zig ranlib "$@"' > zig-ranlib
chmod +x zig-ar zig-cc zig-cxx zig-ranlib
ls -la; head zig-ar zig-cc zig-cxx zig-ranlib
- name: ${{ format('Build Release with zig-cc -target {0} {1}', env.ZIG_TARGET, env.ZIG_PIC) }}
run: |
mkdir -p build/zig/${ZIG_TARGET}${ZIG_PIC}/release
cd build/zig/${ZIG_TARGET}${ZIG_PIC}/release
cmake ../../../.. -DCMAKE_BUILD_TYPE=Release -DCMAKE_AR=$HOME/.local/bin/zig-ar -DCMAKE_C_COMPILER=zig-cc -DCMAKE_CXX_COMPILER=zig-cxx -DCMAKE_RANLIB=$HOME/.local/bin/zig-ranlib $EXTRA_CMAKE_CONFIG_FLAGS_RELEASE
cmake --build . --config Release --parallel --verbose
file ./upx*
- name: ${{ format('Build Debug with zig-cc -target {0} {1}', env.ZIG_TARGET, env.ZIG_PIC) }}
run: |
mkdir -p build/zig/${ZIG_TARGET}${ZIG_PIC}/debug
cd build/zig/${ZIG_TARGET}${ZIG_PIC}/debug
cmake ../../../.. -DCMAKE_BUILD_TYPE=Debug -DCMAKE_AR=$HOME/.local/bin/zig-ar -DCMAKE_C_COMPILER=zig-cc -DCMAKE_CXX_COMPILER=zig-cxx -DCMAKE_RANLIB=$HOME/.local/bin/zig-ranlib $EXTRA_CMAKE_CONFIG_FLAGS_DEBUG
cmake --build . --config Debug --parallel --verbose
file ./upx*
- name: ${{ format('Make artifact from upx-{0}-{1}', github.ref_name, env.UPX_GITREV_SHORT) }}
shell: bash
run: |
N=$(echo "upx-${GITHUB_REF_NAME}-${GITHUB_SHA:0:7}-weekly-ci-zigcc-${{ matrix.zig_target }}${ZIG_PIC}" | sed 's/[^0-9a-zA-Z_.-]/-/g')
mkdir -p "tmp/artifact/$N"
(cd build && shopt -s nullglob && cp -ai --parents */upx{,.exe} */*/*/upx{,.exe} "../tmp/artifact/$N")
(cd tmp/artifact && tar --sort=name -czf "$N.tar.gz" "$N" && rm -rf "./$N")
# GitHub Actions magic: set "artifact_name" environment value for use in next step
echo "artifact_name=$N" >> $GITHUB_ENV
- name: ${{ format('Upload artifact {0}', env.artifact_name) }}
uses: actions/upload-artifact@v3
with:
name: ${{ env.artifact_name }}
path: tmp/artifact
- name: 'Run install tests'
if: ${{ contains(matrix.zig_target, '-linux') }}
run: |
(cd build/zig/${ZIG_TARGET}${ZIG_PIC}/release && DESTDIR=$PWD/Install-with-cmake cmake --install .)
(cd build/zig/${ZIG_TARGET}${ZIG_PIC}/release && DESTDIR=$PWD/Install-with-make make install)
# vim:set ts=2 sw=2 et:
+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*
+165 -177
View File
@@ -7,15 +7,35 @@
# A C++ compiler that fully implements C++17: clang-5, gcc-8 or msvc-2019-16.11 # A C++ compiler that fully implements C++17: clang-5, gcc-8 or msvc-2019-16.11
# (older or other compilers may work but are unsupported, use at your own risk) # (older or other compilers may work but are unsupported, use at your own risk)
# Sections of this CMakeLists.txt:
# - options
# - init
# - common compilation flags
# - targets
# - target compilation flags
# - test
# - install
# - print summary
# CMake version check; using a somewhat current CMake version is highly recommended # CMake version check; using a somewhat current CMake version is highly recommended
file(REMOVE "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/.upx_cmake_config_done.txt")
if(DEFINED UPX_CONFIG_CMAKE_MINIMUM_REQUIRED_VERSION) if(DEFINED UPX_CONFIG_CMAKE_MINIMUM_REQUIRED_VERSION)
cmake_minimum_required(VERSION "${UPX_CONFIG_CMAKE_MINIMUM_REQUIRED_VERSION}" FATAL_ERROR) cmake_minimum_required(VERSION "${UPX_CONFIG_CMAKE_MINIMUM_REQUIRED_VERSION}" FATAL_ERROR)
else() else()
cmake_minimum_required(VERSION 3.8.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()
# support functions
include("${CMAKE_CURRENT_SOURCE_DIR}/misc/cmake/functions.cmake")
#***********************************************************************
# options
#***********************************************************************
upx_cmake_include_hook(1_options)
# compilation config options # compilation config options
if(NOT IS_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/.git") if(NOT IS_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/.git" OR NOT EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/misc/cmake/use_strict_defaults.cmake")
# permissive config defaults when building from source code tarball # permissive config defaults when building from source code tarball
option(UPX_CONFIG_DISABLE_GITREV "Do not compile with default Git version info." ON) option(UPX_CONFIG_DISABLE_GITREV "Do not compile with default Git version info." ON)
option(UPX_CONFIG_DISABLE_SANITIZE "Do not compile with default sanitize options." ON) option(UPX_CONFIG_DISABLE_SANITIZE "Do not compile with default sanitize options." ON)
@@ -38,45 +58,18 @@ option(UPX_CONFIG_DISABLE_SELF_PACK_TEST "Do not test packing UPX with itself" O
# init # init
#*********************************************************************** #***********************************************************************
# Disallow in-source builds. Note that you will still have to manually set(UPX_VERSION_STRING "4.3.0")
upx_cmake_include_hook(2_init)
# Disallow in-source build. Note that you will still have to manually
# clean up a few files if you accidentally try an in-source build. # clean up a few files if you accidentally try an in-source build.
if(IS_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/.git") if(IS_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/.git")
set(CMAKE_DISABLE_IN_SOURCE_BUILD ON) upx_disallow_in_source_build()
set(CMAKE_DISABLE_SOURCE_CHANGES ON)
if(",${CMAKE_CURRENT_SOURCE_DIR}," STREQUAL ",${CMAKE_CURRENT_BINARY_DIR},")
message(FATAL_ERROR "ERROR: In-source builds are not allowed, please use an extra build dir.")
endif() endif()
endif()
# useful for CI jobs: allow settings via environment and cache result
function(upx_cache_bool_vars)
set(default_value "${ARGV0}")
list(REMOVE_AT ARGV 0)
foreach(var ${ARGV})
set(value ${default_value})
if(DEFINED UPX_CACHE_${var})
set(value "${UPX_CACHE_${var}}")
elseif(DEFINED ${var})
set(value "${${var}}")
elseif("$ENV{${var}}" MATCHES "^(0|1|OFF|ON|FALSE|TRUE)$")
set(value "$ENV{${var}}")
set(UPX_CACHE_ORIGIN_FROM_ENV_${var} TRUE CACHE INTERNAL "" FORCE)
endif()
if(value)
set(value ON)
else()
set(value OFF)
endif()
if(UPX_CACHE_ORIGIN_FROM_ENV_${var})
message(STATUS "setting from environment: ${var} = ${value}")
endif()
set(${var} "${value}" PARENT_SCOPE)
set(UPX_CACHE_${var} "${value}" CACHE INTERNAL "" FORCE)
endforeach()
endfunction()
# global settings # global settings
if(${CMAKE_VERSION} VERSION_GREATER "3.14.7" AND NOT DEFINED CMAKE_MSVC_RUNTIME_LIBRARY) if(${CMAKE_VERSION} VERSION_GREATER "3.14.99" AND NOT DEFINED CMAKE_MSVC_RUNTIME_LIBRARY)
set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded") set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded")
cmake_policy(SET CMP0091 NEW) cmake_policy(SET CMP0091 NEW)
endif() endif()
@@ -90,6 +83,7 @@ upx_cache_bool_vars(OFF
UPX_CONFIG_CMAKE_DISABLE_TEST UPX_CONFIG_CMAKE_DISABLE_INSTALL UPX_CONFIG_CMAKE_DISABLE_TEST UPX_CONFIG_CMAKE_DISABLE_INSTALL
UPX_CONFIG_CMAKE_DISABLE_PRINT_INFO UPX_CONFIG_CMAKE_DISABLE_PLATFORM_CHECK UPX_CONFIG_CMAKE_DISABLE_PRINT_INFO UPX_CONFIG_CMAKE_DISABLE_PLATFORM_CHECK
UPX_CONFIG_DISABLE_C_STANDARD UPX_CONFIG_DISABLE_CXX_STANDARD UPX_CONFIG_DISABLE_C_STANDARD UPX_CONFIG_DISABLE_CXX_STANDARD
UPX_CONFIG_EXPECT_THREADS UPX_CONFIG_REQUIRE_THREADS
) )
# determine Git revision # determine Git revision
@@ -134,38 +128,50 @@ else()
message(STATUS "UPX_VERSION_GITREV: not set") message(STATUS "UPX_VERSION_GITREV: not set")
endif() endif()
# set the default build type to "Release"
get_property(is_multi_config GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG)
if(NOT is_multi_config AND NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE "Release" CACHE STRING "Choose the type of build." FORCE)
endif()
# CMake init # CMake init
project(upx VERSION 4.1.0 LANGUAGES C CXX) upx_default_build_type(Release)
project(upx VERSION "${UPX_VERSION_STRING}" LANGUAGES C CXX)
upx_apply_build_type()
# set the default multi-config build type to "Release" # set MSVC_FRONTEND and MINGW
if(is_multi_config) if(NOT DEFINED MSVC_FRONTEND AND (MSVC OR CMAKE_C_COMPILER_FRONTEND_VARIANT MATCHES "^MSVC"))
set(c "${CMAKE_CONFIGURATION_TYPES}")
list(INSERT c 0 "Release")
list(INSERT c 1 "Debug")
if(CMAKE_BUILD_TYPE)
list(INSERT c 0 "${CMAKE_BUILD_TYPE}")
endif()
list(REMOVE_DUPLICATES c)
set(CMAKE_CONFIGURATION_TYPES "${c}" CACHE STRING "List of supported configuration types." FORCE)
endif()
# set MSVC_FRONTEND
set(MSVC_FRONTEND 0)
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)
upx_cmake_include_hook(3_common_compilation_flags)
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,38 +191,10 @@ else()
set(warn_Werror -Werror) set(warn_Werror -Werror)
set(warn_WX -WX) set(warn_WX -WX)
endif() endif()
if(MSVC_FRONTEND)
function(upx_add_definitions_with_prefix) # disable warning C5105 which may get triggered by some older versions of <windows.h>
set(flag_prefix "${ARGV0}") set(warn_WX -wd5105 ${warn_WX})
if(flag_prefix MATCHES "^dummy$") # need dummy to work around bug in old CMake versions
set(flag_prefix "")
endif() endif()
list(REMOVE_AT ARGV 0)
set(failed "")
foreach(f ${ARGV})
set(flag "${flag_prefix}${f}")
string(REGEX REPLACE "[^0-9a-zA-Z_]" "_" cache_var "HAVE_CFLAG_${flag}")
check_c_compiler_flag("${flag}" ${cache_var})
if(${cache_var})
#message(STATUS "add_definitions: ${flag}")
add_definitions("${flag}")
else()
list(APPEND failed "${f}")
endif()
endforeach()
set(failed_flags "${failed}" PARENT_SCOPE) # return value
endfunction()
function(upx_add_definitions)
set(failed_flags "")
if(MSVC_FRONTEND AND CMAKE_C_COMPILER_ID MATCHES "Clang")
# for clang-cl try "-clang:" flag prefix first
upx_add_definitions_with_prefix("-clang:" ${ARGV})
upx_add_definitions_with_prefix("dummy" ${failed_flags})
else()
upx_add_definitions_with_prefix("dummy" ${ARGV})
endif()
endfunction()
if(NOT CMAKE_C_COMPILER_ID MATCHES "^MSVC") if(NOT CMAKE_C_COMPILER_ID MATCHES "^MSVC")
# use -O2 instead of -O3 to reduce code size # use -O2 instead of -O3 to reduce code size
@@ -225,12 +203,16 @@ 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)
add_definitions(-D__USE_MINGW_ANSI_STDIO)
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,85 +231,70 @@ if(NOT CMAKE_C_COMPILER_ID MATCHES "^MSVC")
endif() endif()
endif() endif()
# compile a target with -O2 even in Debug build # examine MinGW/Cygwin compiler configuration
function(upx_compile_target_debug_with_O2) if(IS_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/.git")
foreach(t ${ARGV}) upx_print_mingw_symbols()
if(MSVC_FRONTEND)
# MSVC uses some Debug compilation options like -RTC1 that are incompatible with -O2
else()
target_compile_options(${t} PRIVATE $<$<CONFIG:Debug>:-O2>)
endif() endif()
endforeach()
endfunction()
# sanitize a target
function(upx_sanitize_target)
foreach(t ${ARGV})
if(UPX_CONFIG_DISABLE_SANITIZE)
# no-op
elseif(MSVC_FRONTEND)
# MSVC uses -GS (similar to -fstack-protector) by default
elseif(CMAKE_C_PLATFORM_ID MATCHES "^MinGW" OR MINGW OR CYGWIN)
# avoid link errors with current MinGW-w64 versions
# see https://www.mingw-w64.org/contribute/#sanitizers-asan-tsan-usan
else()
# default sanitizer for Debug builds
target_compile_options(${t} PRIVATE $<$<CONFIG:Debug>:-fsanitize=undefined -fsanitize-undefined-trap-on-error -fstack-protector-all>)
# default sanitizer for Release builds
target_compile_options(${t} PRIVATE $<$<CONFIG:MinSizeRel>:-fstack-protector>)
target_compile_options(${t} PRIVATE $<$<CONFIG:Release>:-fstack-protector>)
target_compile_options(${t} PRIVATE $<$<CONFIG:RelWithDebInfo>:-fstack-protector>)
endif()
endforeach()
endfunction()
#*********************************************************************** #***********************************************************************
# targets # targets
#*********************************************************************** #***********************************************************************
# 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
upx_cmake_include_hook(4_targets)
if(NOT UPX_CONFIG_DISABLE_THREADS) if(NOT UPX_CONFIG_DISABLE_THREADS)
find_package(Threads) find_package(Threads)
endif() endif()
# make sure that threads are indeed fully supported in C++
if(Threads_FOUND)
foreach(f std_lock_guard.cpp)
set(CMAKE_TRY_COMPILE_TARGET_TYPE "EXECUTABLE")
try_compile(result "${CMAKE_CURRENT_BINARY_DIR}"
"${CMAKE_CURRENT_SOURCE_DIR}/misc/cmake/try_compile/${f}"
OUTPUT_VARIABLE output)
if(NOT result)
# failed; under MinGW be sure to use the posix-threads and NOT the win32-threads version
#message(STATUS "Threads FAILED: ${output}") # debug output from try_compile
set(Threads_FOUND OFF)
break()
endif()
endforeach()
endif()
if(NOT UPX_CONFIG_DISABLE_BZIP2) if(NOT UPX_CONFIG_DISABLE_BZIP2)
file(GLOB bzip2_SOURCES "vendor/bzip2/*.c") upx_add_glob_files(bzip2_SOURCES "vendor/bzip2/*.c")
list(SORT bzip2_SOURCES)
add_library(upx_vendor_bzip2 STATIC ${bzip2_SOURCES}) add_library(upx_vendor_bzip2 STATIC ${bzip2_SOURCES})
if(NOT UPX_CONFIG_DISABLE_C_STANDARD) if(NOT UPX_CONFIG_DISABLE_C_STANDARD)
set_property(TARGET upx_vendor_bzip2 PROPERTY C_STANDARD 11) set_property(TARGET upx_vendor_bzip2 PROPERTY C_STANDARD 11)
endif() endif()
endif() # UPX_CONFIG_DISABLE_BZIP2 endif() # UPX_CONFIG_DISABLE_BZIP2
file(GLOB ucl_SOURCES "vendor/ucl/src/*.c") upx_add_glob_files(ucl_SOURCES "vendor/ucl/src/*.c")
list(SORT ucl_SOURCES)
add_library(upx_vendor_ucl STATIC ${ucl_SOURCES}) add_library(upx_vendor_ucl STATIC ${ucl_SOURCES})
if(NOT UPX_CONFIG_DISABLE_C_STANDARD) if(NOT UPX_CONFIG_DISABLE_C_STANDARD)
set_property(TARGET upx_vendor_ucl PROPERTY C_STANDARD 11) set_property(TARGET upx_vendor_ucl PROPERTY C_STANDARD 11)
endif() endif()
file(GLOB zlib_SOURCES "vendor/zlib/*.c") upx_add_glob_files(zlib_SOURCES "vendor/zlib/*.c")
list(SORT zlib_SOURCES)
add_library(upx_vendor_zlib STATIC ${zlib_SOURCES}) add_library(upx_vendor_zlib STATIC ${zlib_SOURCES})
if(NOT UPX_CONFIG_DISABLE_C_STANDARD) if(NOT UPX_CONFIG_DISABLE_C_STANDARD)
set_property(TARGET upx_vendor_zlib PROPERTY C_STANDARD 11) set_property(TARGET upx_vendor_zlib PROPERTY C_STANDARD 11)
endif() endif()
if(NOT UPX_CONFIG_DISABLE_ZSTD) if(NOT UPX_CONFIG_DISABLE_ZSTD)
file(GLOB zstd_SOURCES "vendor/zstd/lib/*/*.c") upx_add_glob_files(zstd_SOURCES "vendor/zstd/lib/*/*.c")
list(SORT zstd_SOURCES)
add_library(upx_vendor_zstd STATIC ${zstd_SOURCES}) add_library(upx_vendor_zstd STATIC ${zstd_SOURCES})
if(NOT UPX_CONFIG_DISABLE_C_STANDARD) if(NOT UPX_CONFIG_DISABLE_C_STANDARD)
set_property(TARGET upx_vendor_zstd PROPERTY C_STANDARD 11) set_property(TARGET upx_vendor_zstd PROPERTY C_STANDARD 11)
endif() endif()
endif() # UPX_CONFIG_DISABLE_ZSTD endif() # UPX_CONFIG_DISABLE_ZSTD
file(GLOB upx_SOURCES "src/*.cpp" "src/[cfu]*/*.cpp") upx_add_glob_files(upx_SOURCES "src/*.cpp" "src/[cfu]*/*.cpp")
list(SORT upx_SOURCES)
add_executable(upx ${upx_SOURCES}) add_executable(upx ${upx_SOURCES})
if(NOT UPX_CONFIG_DISABLE_CXX_STANDARD) if(NOT UPX_CONFIG_DISABLE_CXX_STANDARD)
set_property(TARGET upx PROPERTY CXX_STANDARD 17) set_property(TARGET upx PROPERTY CXX_STANDARD 17)
@@ -347,14 +314,17 @@ endif()
# target compilation flags # target compilation flags
#*********************************************************************** #***********************************************************************
upx_cmake_include_hook(5_target_compilation_flags)
if(NOT UPX_CONFIG_DISABLE_BZIP2) if(NOT UPX_CONFIG_DISABLE_BZIP2)
set(t upx_vendor_bzip2) set(t upx_vendor_bzip2)
upx_compile_target_debug_with_O2(${t}) upx_compile_target_debug_with_O2(${t})
upx_sanitize_target(${t}) upx_sanitize_target(${t})
target_compile_definitions(${t} PRIVATE BZ_NO_STDIO=1)
if(MSVC_FRONTEND) if(MSVC_FRONTEND)
target_compile_options(${t} PRIVATE ${warn_WN} -wd4127 -wd4244 -wd4267 ${warn_WX}) target_compile_options(${t} PRIVATE ${warn_WN} -wd4127 -wd4244 -wd4267 ${warn_WX})
else() else()
target_compile_options(${t} PRIVATE ${warn_Wall} -Wno-implicit-fallthrough ${warn_Werror}) target_compile_options(${t} PRIVATE ${warn_Wall} ${warn_Werror})
endif() endif()
endif() # UPX_CONFIG_DISABLE_BZIP2 endif() # UPX_CONFIG_DISABLE_BZIP2
@@ -372,12 +342,14 @@ 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()
if(NOT UPX_CONFIG_DISABLE_ZSTD) if(NOT UPX_CONFIG_DISABLE_ZSTD)
@@ -411,11 +383,20 @@ if(NOT UPX_CONFIG_DISABLE_WERROR)
target_compile_definitions(${t} PRIVATE UPX_CONFIG_DISABLE_WERROR=0) target_compile_definitions(${t} PRIVATE UPX_CONFIG_DISABLE_WERROR=0)
endif() endif()
if(NOT UPX_CONFIG_DISABLE_BZIP2) if(NOT UPX_CONFIG_DISABLE_BZIP2)
target_compile_definitions(${t} PRIVATE WITH_BZIP2=0) # FIXME TODO target_compile_definitions(${t} PRIVATE WITH_BZIP2=1)
endif() endif()
if(NOT UPX_CONFIG_DISABLE_ZSTD) if(NOT UPX_CONFIG_DISABLE_ZSTD)
target_compile_definitions(${t} PRIVATE WITH_ZSTD=1) target_compile_definitions(${t} PRIVATE WITH_ZSTD=1)
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,50 +406,55 @@ else()
endif() endif()
#*********************************************************************** #***********************************************************************
# test
# ctest # ctest
# make test # make test
# ninja test # ninja test
#*********************************************************************** #***********************************************************************
upx_cmake_include_hook(6_test)
if(NOT UPX_CONFIG_CMAKE_DISABLE_TEST) if(NOT UPX_CONFIG_CMAKE_DISABLE_TEST)
include(CTest) include(CTest)
if(NOT CMAKE_CROSSCOMPILING) if(NOT CMAKE_CROSSCOMPILING OR CMAKE_CROSSCOMPILING_EMULATOR)
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)
endif() add_test(NAME upx-sysinfo COMMAND upx --sysinfo -v)
if(NOT CMAKE_CROSSCOMPILING AND NOT UPX_CONFIG_DISABLE_SELF_PACK_TEST) if(NOT UPX_CONFIG_DISABLE_SELF_PACK_TEST)
# IMPORTANT NOTE: these tests can only work if the host executable format is supported by UPX! # IMPORTANT NOTE: these tests can only work if the host executable format is supported by UPX!
function(upx_add_test) set(emu "")
set(name "${ARGV0}") if(DEFINED CMAKE_CROSSCOMPILING_EMULATOR)
list(REMOVE_AT ARGV 0) set(emu "${CMAKE_CROSSCOMPILING_EMULATOR}")
add_test(NAME "${name}" COMMAND ${ARGV}) endif()
set_tests_properties("${name}" PROPERTIES RUN_SERIAL TRUE) # run these tests sequentially set(exe "${CMAKE_EXECUTABLE_SUFFIX}")
endfunction()
set(exe ${CMAKE_EXECUTABLE_SUFFIX})
set(upx_self_exe "$<TARGET_FILE:upx>") set(upx_self_exe "$<TARGET_FILE:upx>")
set(fo "--force-overwrite") set(fo "--force-overwrite")
upx_add_test(upx-self-pack upx -3 "${upx_self_exe}" ${fo} -o upx-packed${exe}) upx_add_serial_test(upx-self-pack upx -3 "${upx_self_exe}" ${fo} -o upx-packed${exe})
upx_add_test(upx-self-pack-n2b upx -3 --nrv2b "${upx_self_exe}" ${fo} -o upx-packed-n2b${exe}) upx_add_serial_test(upx-self-pack-n2b upx -3 --nrv2b "${upx_self_exe}" ${fo} -o upx-packed-n2b${exe})
upx_add_test(upx-self-pack-n2d upx -3 --nrv2d "${upx_self_exe}" ${fo} -o upx-packed-n2d${exe}) upx_add_serial_test(upx-self-pack-n2d upx -3 --nrv2d "${upx_self_exe}" ${fo} -o upx-packed-n2d${exe})
upx_add_test(upx-self-pack-n2e upx -3 --nrv2e "${upx_self_exe}" ${fo} -o upx-packed-n2e${exe}) upx_add_serial_test(upx-self-pack-n2e upx -3 --nrv2e "${upx_self_exe}" ${fo} -o upx-packed-n2e${exe})
upx_add_test(upx-self-pack-lzma upx -1 --lzma "${upx_self_exe}" ${fo} -o upx-packed-lzma${exe}) upx_add_serial_test(upx-self-pack-lzma upx -1 --lzma "${upx_self_exe}" ${fo} -o upx-packed-lzma${exe})
upx_add_test(upx-list upx -l upx-packed${exe} upx-packed-n2b${exe} upx-packed-n2d${exe} upx-packed-n2e${exe} upx-packed-lzma${exe}) upx_add_serial_test(upx-list upx -l upx-packed${exe} upx-packed-n2b${exe} upx-packed-n2d${exe} upx-packed-n2e${exe} upx-packed-lzma${exe})
upx_add_test(upx-fileinfo upx --fileinfo upx-packed${exe} upx-packed-n2b${exe} upx-packed-n2d${exe} upx-packed-n2e${exe} upx-packed-lzma${exe}) upx_add_serial_test(upx-fileinfo upx --fileinfo upx-packed${exe} upx-packed-n2b${exe} upx-packed-n2d${exe} upx-packed-n2e${exe} upx-packed-lzma${exe})
upx_add_test(upx-test upx -t upx-packed${exe} upx-packed-n2b${exe} upx-packed-n2d${exe} upx-packed-n2e${exe} upx-packed-lzma${exe}) upx_add_serial_test(upx-test upx -t upx-packed${exe} upx-packed-n2b${exe} upx-packed-n2d${exe} upx-packed-n2e${exe} upx-packed-lzma${exe})
upx_add_test(upx-unpack upx -d upx-packed${exe} ${fo} -o upx-unpacked${exe}) upx_add_serial_test(upx-unpack upx -d upx-packed${exe} ${fo} -o upx-unpacked${exe})
upx_add_test(upx-run-unpacked ./upx-unpacked${exe} --version-short) upx_add_serial_test(upx-run-unpacked ${emu} ./upx-unpacked${exe} --version-short)
upx_add_test(upx-run-packed ./upx-packed${exe} --version-short) upx_add_serial_test(upx-run-packed ${emu} ./upx-packed${exe} --version-short)
endif() # UPX_CONFIG_DISABLE_SELF_PACK_TEST
endif() endif()
endif() # UPX_CONFIG_CMAKE_DISABLE_TEST endif() # UPX_CONFIG_CMAKE_DISABLE_TEST
#*********************************************************************** #***********************************************************************
# install
# cmake --install . # cmake --install .
# make install # make install
# ninja install # ninja install
#*********************************************************************** #***********************************************************************
upx_cmake_include_hook(7_install)
if(NOT UPX_CONFIG_CMAKE_DISABLE_INSTALL) if(NOT UPX_CONFIG_CMAKE_DISABLE_INSTALL)
# installation prefix and directories # installation prefix and directories
@@ -479,6 +465,7 @@ endif()
if(CMAKE_INSTALL_PREFIX) if(CMAKE_INSTALL_PREFIX)
include(GNUInstallDirs) include(GNUInstallDirs)
endif() endif()
# install files
if(CMAKE_INSTALL_PREFIX AND DEFINED CMAKE_INSTALL_FULL_BINDIR) if(CMAKE_INSTALL_PREFIX AND DEFINED CMAKE_INSTALL_FULL_BINDIR)
install(TARGETS upx DESTINATION "${CMAKE_INSTALL_FULL_BINDIR}") install(TARGETS upx DESTINATION "${CMAKE_INSTALL_FULL_BINDIR}")
install(FILES install(FILES
@@ -491,31 +478,29 @@ endif()
endif() # UPX_CONFIG_CMAKE_DISABLE_INSTALL endif() # UPX_CONFIG_CMAKE_DISABLE_INSTALL
#*********************************************************************** #***********************************************************************
# finally print some info about the build configuration # summary
# print some info about the build configuration
#*********************************************************************** #***********************************************************************
function(print_var) upx_cmake_include_hook(8_summary)
foreach(var ${ARGV})
if(${var})
message(STATUS "${var} = ${${var}}")
endif()
endforeach()
endfunction()
if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/maint/make/CMakeLists.maint.txt") upx_print_var(CMAKE_VERSION UPX_CONFIG_CMAKE_MINIMUM_REQUIRED_VERSION CMAKE_GENERATOR)
include("${CMAKE_CURRENT_SOURCE_DIR}/maint/make/CMakeLists.maint.txt")
endif()
print_var(CMAKE_VERSION UPX_CONFIG_CMAKE_MINIMUM_REQUIRED_VERSION CMAKE_GENERATOR)
if(NOT UPX_CONFIG_CMAKE_DISABLE_PRINT_INFO) if(NOT UPX_CONFIG_CMAKE_DISABLE_PRINT_INFO)
print_var(CMAKE_HOST_SYSTEM_NAME CMAKE_HOST_SYSTEM_VERSION) upx_print_var(CMAKE_HOST_SYSTEM_NAME CMAKE_HOST_SYSTEM_VERSION)
print_var(CMAKE_SYSTEM_NAME CMAKE_SYSTEM_VERSION CMAKE_CROSSCOMPILING) upx_print_var(CMAKE_SYSTEM_NAME CMAKE_SYSTEM_VERSION CMAKE_CROSSCOMPILING CMAKE_CROSSCOMPILING_EMULATOR)
print_var(CMAKE_C_COMPILER_ID CMAKE_C_COMPILER_VERSION CMAKE_C_COMPILER_FRONTEND_VARIANT CMAKE_C_COMPILER_ARCHITECTURE_ID CMAKE_C_PLATFORM_ID CMAKE_C_COMPILER_ABI) upx_print_var(CMAKE_C_COMPILER_ID CMAKE_C_COMPILER_VERSION CMAKE_C_COMPILER_FRONTEND_VARIANT CMAKE_C_COMPILER_ARCHITECTURE_ID CMAKE_C_PLATFORM_ID CMAKE_C_COMPILER_ABI)
print_var(CMAKE_CXX_COMPILER_ID CMAKE_CXX_COMPILER_VERSION CMAKE_CXX_COMPILER_FRONTEND_VARIANT CMAKE_CXX_COMPILER_ARCHITECTURE_ID CMAKE_CXX_PLATFORM_ID CMAKE_CXX_COMPILER_ABI) upx_print_var(CMAKE_CXX_COMPILER_ID CMAKE_CXX_COMPILER_VERSION CMAKE_CXX_COMPILER_FRONTEND_VARIANT CMAKE_CXX_COMPILER_ARCHITECTURE_ID CMAKE_CXX_PLATFORM_ID CMAKE_CXX_COMPILER_ABI)
print_var(CMAKE_POSITION_INDEPENDENT_CODE) upx_print_var(CMAKE_INTERPROCEDURAL_OPTIMIZATION CMAKE_POSITION_INDEPENDENT_CODE CMAKE_TRY_COMPILE_CONFIGURATION)
print_var(CYGWIN GNUC MINGW MSVC MSVC_FRONTEND MSVC_IDE WIN32 WIN64) upx_print_var(CYGWIN GNUC MINGW MSVC MSVC_FRONTEND MSVC_IDE WIN32 WIN64)
endif() # UPX_CONFIG_CMAKE_DISABLE_PRINT_INFO endif() # UPX_CONFIG_CMAKE_DISABLE_PRINT_INFO
print_var(CMAKE_INSTALL_PREFIX CMAKE_CONFIGURATION_TYPES CMAKE_BUILD_TYPE) upx_print_var(CMAKE_INSTALL_PREFIX CMAKE_CONFIGURATION_TYPES CMAKE_BUILD_TYPE)
if(Threads_FOUND)
message(STATUS "WITH_THREADS = 1")
elseif(UPX_CONFIG_REQUIRE_THREADS)
message(FATAL_ERROR "ERROR: WITH_THREADS required")
elseif(UPX_CONFIG_EXPECT_THREADS AND NOT UPX_CONFIG_DISABLE_THREADS)
message(FATAL_ERROR "ERROR: WITH_THREADS expected")
endif()
if(CMAKE_BUILD_TYPE AND NOT CMAKE_BUILD_TYPE MATCHES "^(Debug|None|Release)$") if(CMAKE_BUILD_TYPE AND NOT CMAKE_BUILD_TYPE MATCHES "^(Debug|None|Release)$")
message(WARNING "WARNING: unsupported CMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}; please use \"Debug\" or \"Release\"") message(WARNING "WARNING: unsupported CMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}; please use \"Debug\" or \"Release\"")
endif() endif()
@@ -533,4 +518,7 @@ if(NOT ",${CMAKE_C_COMPILER_FRONTEND_VARIANT}," STREQUAL ",${CMAKE_CXX_COMPILER_
endif() endif()
endif() # UPX_CONFIG_CMAKE_DISABLE_PLATFORM_CHECK endif() # UPX_CONFIG_CMAKE_DISABLE_PLATFORM_CHECK
upx_cmake_include_hook(9_finish)
file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/.upx_cmake_config_done.txt" "")
# vim:set ft=cmake ts=4 sw=4 tw=0 et: # vim:set ft=cmake ts=4 sw=4 tw=0 et:
+28 -185
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
@@ -24,14 +24,14 @@ endif
# default # default
#*********************************************************************** #***********************************************************************
.DEFAULT_GOAL = build/release
run_cmake_config = $(CMAKE) -S . -B $1 $(UPX_CMAKE_CONFIG_FLAGS) -DCMAKE_BUILD_TYPE=$2 run_cmake_config = $(CMAKE) -S . -B $1 $(UPX_CMAKE_CONFIG_FLAGS) -DCMAKE_BUILD_TYPE=$2
run_cmake_build = $(CMAKE) --build $1 $(UPX_CMAKE_BUILD_FLAGS) --config $2 run_cmake_build = $(CMAKE) --build $1 $(UPX_CMAKE_BUILD_FLAGS) --config $2
# avoid re-running run_cmake_config if CMakeCache.txt already exists # avoid re-running run_cmake_config if .upx_cmake_config_done.txt already exists
run_config = $(if $(wildcard $1/CMakeCache.txt),,$(call run_cmake_config,$1,$2)) run_config = $(if $(wildcard $1/CMakeFiles/.upx_cmake_config_done.txt),,$(call run_cmake_config,$1,$2))
run_build = $(call run_cmake_build,$1,$2) run_build = $(call run_cmake_build,$1,$2)
.DEFAULT_GOAL = build/release
build/debug: PHONY build/debug: PHONY
$(call run_config,$@,Debug) $(call run_config,$@,Debug)
$(call run_build,$@,Debug) $(call run_build,$@,Debug)
@@ -40,192 +40,35 @@ 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 CTEST = ctest
#*********************************************************************** test:: $(.DEFAULT_GOAL) PHONY
cd $(.DEFAULT_GOAL) && $(CTEST)
SUBMODULES = doctest lzma-sdk ucl valgrind zlib ifneq ($(wildcard /usr/bin/env),) # need Unix utils like bash, perl, sed, xargs, etc.
ifneq ($(wildcard ./misc/scripts/.),)
dummy := $(foreach m,$(SUBMODULES),$(if $(wildcard vendor/$m/[CL]*),$m,\ check-whitespace clang-format run-testsuite run-testsuite-debug run-testsuite-release: src/Makefile PHONY
$(error ERROR: missing git submodule '$m'; run 'git submodule update --init'))) $(MAKE) -C src $@
endif
endif
+18
View File
@@ -2,6 +2,24 @@
User visible changes for UPX User visible changes for UPX
================================================================== ==================================================================
Changes in 4.2.2 (03 Jan 2024):
* bug fixes - see https://github.com/upx/upx/milestone/15
Changes in 4.2.1 (01 Nov 2023):
* linux: /proc/self/exe now is optional
* windows: use SetFileTime to preserve sub-second file timestamps
* official Windows builds: revert activeCodePage change introduced in 4.2.0
* bug fixes - see https://github.com/upx/upx/milestone/14
Changes in 4.2.0 (26 Oct 2023):
* 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
+5 -5
View File
@@ -8,7 +8,7 @@
The Ultimate Packer for eXecutables The Ultimate Packer for eXecutables
Copyright (c) 1996-2023 Markus Oberhumer, Laszlo Molnar & John Reiser Copyright (c) 1996-2024 Markus Oberhumer, Laszlo Molnar & John Reiser
https://upx.github.io https://upx.github.io
@@ -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.
@@ -85,9 +85,9 @@ THE FUTURE
COPYRIGHT COPYRIGHT
========= =========
Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer Copyright (C) 1996-2024 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2023 Laszlo Molnar Copyright (C) 1996-2024 Laszlo Molnar
Copyright (C) 2000-2023 John F. Reiser Copyright (C) 2000-2024 John F. Reiser
UPX is distributed with full source code under the terms of the UPX is distributed with full source code under the terms of the
GNU General Public License v2+; either under the pure GPLv2+ (see GNU General Public License v2+; either under the pure GPLv2+ (see
+1 -1
View File
@@ -8,7 +8,7 @@
The Ultimate Packer for eXecutables The Ultimate Packer for eXecutables
Copyright (c) 1996-2023 Markus Oberhumer, Laszlo Molnar & John Reiser Copyright (c) 1996-2024 Markus Oberhumer, Laszlo Molnar & John Reiser
https://upx.github.io https://upx.github.io
+5 -3
View File
@@ -1,5 +1,6 @@
# #
# UPX doc Makefile - needs GNU make, pod2html, pod2man and pod2text # UPX doc Makefile - needs GNU make, sed, pod2html, pod2man and pod2text
# Copyright (C) Markus Franz Xaver Johannes Oberhumer
# #
BUILT_SOURCES = upx.1 upx-doc.html upx-doc.txt BUILT_SOURCES = upx.1 upx-doc.html upx-doc.txt
@@ -24,6 +25,9 @@ DETAB2 := sed -e 's/$(tab)/ /g'
#*********************************************************************** #***********************************************************************
.DEFAULT_GOAL = all .DEFAULT_GOAL = all
.PHONY: PHONY
.SECONDEXPANSION:
.SUFFIXES:
all: $(BUILT_SOURCES) PHONY all: $(BUILT_SOURCES) PHONY
@@ -34,7 +38,6 @@ mostlyclean clean distclean maintainer-clean: PHONY
# rules # rules
#*********************************************************************** #***********************************************************************
.SUFFIXES:
.SUFFIXES: .1 .html .man .pod .ps .tex .txt .SUFFIXES: .1 .html .man .pod .ps .tex .txt
%.1 : %.pod %.1 : %.pod
@@ -68,4 +71,3 @@ mostlyclean clean distclean maintainer-clean: PHONY
$(BUILT_SOURCES): $(top_srcdir)/src/version.h $(MAKEFILE_LIST) $(BUILT_SOURCES): $(top_srcdir)/src/version.h $(MAKEFILE_LIST)
.DELETE_ON_ERROR: $(BUILT_SOURCES) .DELETE_ON_ERROR: $(BUILT_SOURCES)
.PHONY: PHONY
+1 -1
View File
@@ -8,7 +8,7 @@
The Ultimate Packer for eXecutables The Ultimate Packer for eXecutables
Copyright (c) 1996-2023 Markus Oberhumer, Laszlo Molnar & John Reiser Copyright (c) 1996-2024 Markus Oberhumer, Laszlo Molnar & John Reiser
https://upx.github.io https://upx.github.io
+46 -44
View File
@@ -1,5 +1,5 @@
Decompressing ELF Directly to Memory on Linux/x86 Decompressing ELF Directly to Memory on Linux/x86
Copyright (C) 2000-2023 John F. Reiser jreiser@BitWagon.com Copyright (C) 2000-2024 John F. Reiser jreiser@BitWagon.com
References: References:
<elf.h> definitions for the ELF file format <elf.h> definitions for the ELF file format
@@ -15,7 +15,7 @@ the value that is manipulated by system call 45 (__NR_brk in
there will be no execve() except for the execve() of the decompressor there will be no execve() except for the execve() of the decompressor
program itself. So, the decompressor program (which contains the program itself. So, the decompressor program (which contains the
compressed version of the original executable) must have the same compressed version of the original executable) must have the same
brk() as the original executable. So, the second PT_LOAD brk() as the original executable. So, the first PT_LOAD
ELF "segment" of the compressed program is used only to set the brk(0). ELF "segment" of the compressed program is used only to set the brk(0).
See src/p_lx_elf.cpp, function PackLinuxElf32::generateElfHdr. See src/p_lx_elf.cpp, function PackLinuxElf32::generateElfHdr.
All of the decompressor's code, and all of the compressed image All of the decompressor's code, and all of the compressed image
@@ -25,35 +25,27 @@ decompressor program.
The decompressor program stub is just under 2K bytes when linked. The decompressor program stub is just under 2K bytes when linked.
After linking, the decompressor code is converted to an initialized After linking, the decompressor code is converted to an initialized
array, and #included into the compilation of the compressor; array, and #included into the compilation of the compressor;
see src/stub/l_le_n2b.h. To make self-contained compressed see stub/i386-linux.elf-entry.h. To make self-contained compressed
executables even smaller, the compressor also compresses all but the executables even smaller, the compressor also compresses all but the
startup and decompression subroutine of the decompressor itself, startup and decompression subroutine of the decompressor itself,
saving a few hundred bytes. The startup code first decompresses the saving a few hundred bytes. The startup code first decompresses the
rest of the decompressor, then jumps to it. A nonstandard linker rest of the decompressor, then jumps to it. A nonstandard linker
script src/stub/l_lx_elf86.lds places both the .text and .data script src/stub/src/i386-linux.elf-entry.lds arranges the SECTIONS
of the decompressor into the same PT_LOAD at 0x00401000. The so that PackLinuxElf32x86::buildLoader() and buildLinuxLoader()
compressor includes the compressed bytes of the original executable generate the desired stub code, which goes into PT_LOAD[1].
at the end of this first PT_LOAD.
At runtime, the decompressed stub lives at 0x00400000. In order for the At runtime, the decompressed stub lives close beyond the brk().
decompressed stub to work properly at an address that is different In order for the decompressed stub to work properly at an address
from its link-time address, the compiled code must contain no absolute that is different from its link-time address, the compiled code must
addresses. So, the data items in l_lx_elf.c must be only parameters contain no absolute addresses. So, the data items in stub code
and automatic (on-stack) local variables; no global data, no static data, must be only parameters and automatic (on-stack) local variables;
and no string constants. Use "size l_le_n2b.o l_6e_n2b.o" to check no global data, no static data, and no string constants. Also,
that both data and bss have length zero. Also, the '&' operator the '&' operator may not be used to take the address of a function.
may not be used to take the address of a function.
The address 0x00400000 was chosen to be out of the way of the usual
load address 0x08048000, and to minimize fragmentation in kernel
page tables; one page of page tables covers 4 MiB. The address
0x00401000 was chosen as 1 page up from a 64 KiB boundary, to
make the startup code and its constants smaller.
Decompression of the executable begins by decompressing the Elf32_Ehdr Decompression of the executable begins by decompressing the Elf32_Ehdr
and Elf32_Phdr, and then uses the Ehdr and Phdrs to control decompression and Elf32_Phdr, and then uses those Ehdr and Phdrs to control decompression
of the PT_LOAD segments. of the PT_LOAD segments. Subroutine do_xmap() of src/stub/src/
Subroutine do_xmap() of src/stub/l_lx_elf.c performs the i386-linux.elf-main.c performs the
"virtual execve()" using the compressed data as source, and stores "virtual execve()" using the compressed data as source, and stores
the decompressed bytes directly into the appropriate virtual addresses. the decompressed bytes directly into the appropriate virtual addresses.
@@ -74,22 +66,17 @@ expanding $ORIGIN in -rpath, or for application code that relies on
--unmap-all-pages to achieve that effect at run time. Upx-3.04 --unmap-all-pages to achieve that effect at run time. Upx-3.04
and previous versions did this by default with no option. However, and previous versions did this by default with no option. However,
too much other software erroneously assumes that /proc/self/exe too much other software erroneously assumes that /proc/self/exe
always exists. always exists. upx-4.3.0 made /proc/self/exe optional so that
chroot() and related environments can work.
For Elf formats, UPX adds an environment variable named " " [three
spaces] which saves the results of readlink("/proc/self/exe",,)
If /proc/self/exe is ENOENT, then the variable has the same value
as its name "/proc/self/exe".
On arm*-linux-elf there is no good address at which to retain one All of the above documentation refers to ET_EXEC main programs,
page of the compressed executable. Pages below the usual .p_vaddr which always use the same virtual addresses. An ET_DYN executable
0x8000 (32KiB) are rejected by the kernel. Using a page above the (main program or shared library) follows much the same scheme,
original uncompressed brk(0) would require placing the entire initial re-using the address space that the kernel chose originally.
compressed program above uncompressed brk(0), which would significantly
increase the running brk(0); but too many programs break if brk(0)
moves. Thus on arm*-linux-elf the compressed executable begins
with 0x8000==.p_vaddr, all pages mapped by execve() that are also
occupied by decompressed bytes are removed before overwriting, and
/proc/self/exe becomes a "(deleted)" symlink. It might be possible
to preserve /proc/self/exe if the original uncompressed executable
were created with 0x9000==.p_vaddr (one page higher than the usual
0x8000) so that the compressed page mapped at 0x8000 would linger.
[This has not been tested.]
Linux stores the pathname argument that was specified to execve() Linux stores the pathname argument that was specified to execve()
immediately after the '\0' which terminates the character string of the immediately after the '\0' which terminates the character string of the
@@ -99,9 +86,24 @@ records a pointer to that character string in Elf32_auxv[AT_EXECFN].
The pathname is not "bound" to the file as strongly as /proc/self/exe The pathname is not "bound" to the file as strongly as /proc/self/exe
(the file may be changed without affecting the pathname), but the (the file may be changed without affecting the pathname), but the
pathname does provide some information. The pathname may be relative pathname does provide some information. The pathname may be relative
to the working directory, so look before any chdir(). to the working directory, so look before performing any chdir().
The Elf formats for Linux add an environment variable named " " [three On any page, then SELinux in strictest enforcing mode prohibits
spaces] which saves the results of readlink("/proc/self/exe",,) before simultaneous PROT_EXEC and PROT_WRITE, and also prohibits adding
the runtime stub unmaps all its pages. As of 2006-10-03 this works PROT_EXEC if the kernel VMA struct (Virtual Memory Area struct)
for linux/elf386 and linux/ElfAMD. that manages that page ever has had PROT_WRITE. This implies that
the only way to get PROT_EXEC is to map the page directly from a file.
Therefore, in late 2023 the various decompression stubs are being
rewritten to "bounce" the decompressed data through pages in a
memory-resident file created by the memfd_create() system call,
and subsequently mapped PROT_EXEC. Actual copying of the pages
can be avoided by careful sequence mmap() modes, but the overhead
of an additional system call is required.
The not-as-strict "targeted enforcing" mode of
SELinux seems not to demand this extra work, except for executables
that run with elevated privileges, such as various system daemons.
So "ordinary" user-mode apps can run in current "targeted enforcing"
mode. But because the actual runtime mode of SELinux is unknown
at compression time, then the memfd_create method should be used
all the time.
+5 -5
View File
@@ -22,7 +22,7 @@
<h1 id="ABSTRACT">ABSTRACT</h1> <h1 id="ABSTRACT">ABSTRACT</h1>
<pre><code> The Ultimate Packer for eXecutables <pre><code> The Ultimate Packer for eXecutables
Copyright (c) 1996-2023 Markus Oberhumer, Laszlo Molnar &amp; John Reiser Copyright (c) 1996-2024 Markus Oberhumer, Laszlo Molnar &amp; John Reiser
https://upx.github.io</code></pre> https://upx.github.io</code></pre>
<p><b>UPX</b> is a portable, extendable, high-performance executable packer for several different executable formats. It achieves an excellent compression ratio and offers <i>*very*</i> fast decompression. Your executables suffer no memory overhead or other drawbacks for most of the formats supported, because of in-place decompression.</p> <p><b>UPX</b> is a portable, extendable, high-performance executable packer for several different executable formats. It achieves an excellent compression ratio and offers <i>*very*</i> fast decompression. Your executables suffer no memory overhead or other drawbacks for most of the formats supported, because of in-place decompression.</p>
@@ -785,13 +785,13 @@ Jens Medoch &lt;jssg@users.sourceforge.net&gt;</code></pre>
<h1 id="COPYRIGHT">COPYRIGHT</h1> <h1 id="COPYRIGHT">COPYRIGHT</h1>
<p>Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer</p> <p>Copyright (C) 1996-2024 Markus Franz Xaver Johannes Oberhumer</p>
<p>Copyright (C) 1996-2023 Laszlo Molnar</p> <p>Copyright (C) 1996-2024 Laszlo Molnar</p>
<p>Copyright (C) 2000-2023 John F. Reiser</p> <p>Copyright (C) 2000-2024 John F. Reiser</p>
<p>Copyright (C) 2002-2023 Jens Medoch</p> <p>Copyright (C) 2002-2024 Jens Medoch</p>
<p><b>UPX</b> is distributed with full source code under the terms of the GNU General Public License v2+; either under the pure GPLv2+ (see the file COPYING), or (at your option) under the GPLv+2 with special exceptions and restrictions granting the free usage for all binaries including commercial programs (see the file LICENSE).</p> <p><b>UPX</b> is distributed with full source code under the terms of the GNU General Public License v2+; either under the pure GPLv2+ (see the file COPYING), or (at your option) under the GPLv+2 with special exceptions and restrictions granting the free usage for all binaries including commercial programs (see the file LICENSE).</p>
+5 -5
View File
@@ -6,7 +6,7 @@ SYNOPSIS
ABSTRACT ABSTRACT
The Ultimate Packer for eXecutables The Ultimate Packer for eXecutables
Copyright (c) 1996-2023 Markus Oberhumer, Laszlo Molnar & John Reiser Copyright (c) 1996-2024 Markus Oberhumer, Laszlo Molnar & John Reiser
https://upx.github.io https://upx.github.io
UPX is a portable, extendable, high-performance executable packer for UPX is a portable, extendable, high-performance executable packer for
@@ -818,13 +818,13 @@ AUTHORS
Jens Medoch <jssg@users.sourceforge.net> Jens Medoch <jssg@users.sourceforge.net>
COPYRIGHT COPYRIGHT
Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer Copyright (C) 1996-2024 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2023 Laszlo Molnar Copyright (C) 1996-2024 Laszlo Molnar
Copyright (C) 2000-2023 John F. Reiser Copyright (C) 2000-2024 John F. Reiser
Copyright (C) 2002-2023 Jens Medoch Copyright (C) 2002-2024 Jens Medoch
UPX is distributed with full source code under the terms of the GNU UPX is distributed with full source code under the terms of the GNU
General Public License v2+; either under the pure GPLv2+ (see the file General Public License v2+; either under the pure GPLv2+ (see the file
Generated
+6 -6
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 "2024-01-03" "upx 4.2.2" " "
.\" 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
@@ -147,7 +147,7 @@ upx \- compress or expand executable files
.IX Header "ABSTRACT" .IX Header "ABSTRACT"
.Vb 3 .Vb 3
\& The Ultimate Packer for eXecutables \& The Ultimate Packer for eXecutables
\& Copyright (c) 1996\-2023 Markus Oberhumer, Laszlo Molnar & John Reiser \& Copyright (c) 1996\-2024 Markus Oberhumer, Laszlo Molnar & John Reiser
\& https://upx.github.io \& https://upx.github.io
.Ve .Ve
.PP .PP
@@ -1019,13 +1019,13 @@ Please report all bugs immediately to the authors.
.Ve .Ve
.SH "COPYRIGHT" .SH "COPYRIGHT"
.IX Header "COPYRIGHT" .IX Header "COPYRIGHT"
Copyright (C) 1996\-2023 Markus Franz Xaver Johannes Oberhumer Copyright (C) 1996\-2024 Markus Franz Xaver Johannes Oberhumer
.PP .PP
Copyright (C) 1996\-2023 Laszlo Molnar Copyright (C) 1996\-2024 Laszlo Molnar
.PP .PP
Copyright (C) 2000\-2023 John F. Reiser Copyright (C) 2000\-2024 John F. Reiser
.PP .PP
Copyright (C) 2002\-2023 Jens Medoch Copyright (C) 2002\-2024 Jens Medoch
.PP .PP
\&\fB\s-1UPX\s0\fR is distributed with full source code under the terms of the \&\fB\s-1UPX\s0\fR is distributed with full source code under the terms of the
\&\s-1GNU\s0 General Public License v2+; either under the pure GPLv2+ (see \&\s-1GNU\s0 General Public License v2+; either under the pure GPLv2+ (see
+5 -5
View File
@@ -13,7 +13,7 @@ B<upx> S<[ I<command> ]> S<[ I<options> ]> I<filename>...
=head1 ABSTRACT =head1 ABSTRACT
The Ultimate Packer for eXecutables The Ultimate Packer for eXecutables
Copyright (c) 1996-2023 Markus Oberhumer, Laszlo Molnar & John Reiser Copyright (c) 1996-2024 Markus Oberhumer, Laszlo Molnar & John Reiser
https://upx.github.io https://upx.github.io
@@ -932,13 +932,13 @@ Please report all bugs immediately to the authors.
=head1 COPYRIGHT =head1 COPYRIGHT
Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer Copyright (C) 1996-2024 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2023 Laszlo Molnar Copyright (C) 1996-2024 Laszlo Molnar
Copyright (C) 2000-2023 John F. Reiser Copyright (C) 2000-2024 John F. Reiser
Copyright (C) 2002-2023 Jens Medoch Copyright (C) 2002-2024 Jens Medoch
B<UPX> is distributed with full source code under the terms of the B<UPX> is distributed with full source code under the terms of the
GNU General Public License v2+; either under the pure GPLv2+ (see GNU General Public License v2+; either under the pure GPLv2+ (see
+57 -23
View File
@@ -257,7 +257,7 @@ def main():
parser.add_argument( parser.add_argument(
"-allow-enabling-alpha-checkers", "-allow-enabling-alpha-checkers",
action="store_true", action="store_true",
help="allow alpha checkers from " "clang-analyzer.", help="allow alpha checkers from clang-analyzer.",
) )
parser.add_argument( parser.add_argument(
"-clang-tidy-binary", metavar="PATH", help="path to clang-tidy binary" "-clang-tidy-binary", metavar="PATH", help="path to clang-tidy binary"
@@ -270,7 +270,7 @@ def main():
parser.add_argument( parser.add_argument(
"-checks", "-checks",
default=None, default=None,
help="checks filter, when not specified, use clang-tidy " "default", help="checks filter, when not specified, use clang-tidy default",
) )
config_group = parser.add_mutually_exclusive_group() config_group = parser.add_mutually_exclusive_group()
config_group.add_argument( config_group.add_argument(
@@ -303,15 +303,26 @@ def main():
parser.add_argument( parser.add_argument(
"-line-filter", "-line-filter",
default=None, default=None,
help="List of files with line ranges to filter the" "warnings.", help="List of files with line ranges to filter the warnings.",
) )
if yaml: if yaml:
parser.add_argument( parser.add_argument(
"-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",
@@ -324,12 +335,12 @@ def main():
) )
parser.add_argument("-fix", action="store_true", help="apply fix-its") parser.add_argument("-fix", action="store_true", help="apply fix-its")
parser.add_argument( parser.add_argument(
"-format", action="store_true", help="Reformat code " "after applying fixes" "-format", action="store_true", help="Reformat code after applying fixes"
) )
parser.add_argument( parser.add_argument(
"-style", "-style",
default="file", default="file",
help="The style of reformat " "code after applying fixes", help="The style of reformat code after applying fixes",
) )
parser.add_argument( parser.add_argument(
"-use-color", "-use-color",
@@ -348,14 +359,14 @@ def main():
dest="extra_arg", dest="extra_arg",
action="append", action="append",
default=[], default=[],
help="Additional argument to append to the compiler " "command line.", help="Additional argument to append to the compiler command line.",
) )
parser.add_argument( parser.add_argument(
"-extra-arg-before", "-extra-arg-before",
dest="extra_arg_before", dest="extra_arg_before",
action="append", action="append",
default=[], default=[],
help="Additional argument to prepend to the compiler " "command line.", help="Additional argument to prepend to the compiler command line.",
) )
parser.add_argument( parser.add_argument(
"-quiet", action="store_true", help="Run clang-tidy in quiet mode" "-quiet", action="store_true", help="Run clang-tidy in quiet mode"
@@ -370,7 +381,7 @@ def main():
parser.add_argument( parser.add_argument(
"-warnings-as-errors", "-warnings-as-errors",
default=None, default=None,
help="Upgrades warnings to errors. Same format as " "'-checks'", help="Upgrades warnings to errors. Same format as '-checks'",
) )
args = parser.parse_args() args = parser.parse_args()
@@ -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)
+255
View File
@@ -0,0 +1,255 @@
#
# UPX "CMake" build file; see https://cmake.org/
# Copyright (C) Markus Franz Xaver Johannes Oberhumer
#
#***********************************************************************
# macros
#***********************************************************************
# support config hooks; developer convenience
macro(upx_cmake_include_hook section)
include("${CMAKE_CURRENT_SOURCE_DIR}/misc/cmake/hooks/CMakeLists.${section}.txt" OPTIONAL)
include("${CMAKE_CURRENT_SOURCE_DIR}/maint/make/CMakeLists.${section}.txt" OPTIONAL)
endmacro()
# Disallow in-source build. Note that you will still have to manually
# clean up a few files if you accidentally try an in-source build.
macro(upx_disallow_in_source_build)
set(CMAKE_DISABLE_IN_SOURCE_BUILD ON)
set(CMAKE_DISABLE_SOURCE_CHANGES ON)
if(",${CMAKE_CURRENT_SOURCE_DIR}," STREQUAL ",${CMAKE_CURRENT_BINARY_DIR},")
# try to clean up (does not work)
#file(REMOVE "${CMAKE_CURRENT_BINARY_DIR}/CMakeCache.txt")
#file(REMOVE "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/cmake.check_cache")
message(FATAL_ERROR "ERROR: In-source builds are not allowed, please use an extra build dir.")
endif()
endmacro()
# set the default build type; must be called before project() cmake init
macro(upx_default_build_type type)
set(upx_global_default_build_type "${type}")
get_property(upx_global_is_multi_config GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG)
if(NOT upx_global_is_multi_config AND NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE "${upx_global_default_build_type}" CACHE STRING "Choose the type of build." FORCE)
endif()
endmacro()
# set the default multi-config build type; must be called after project() cmake init
macro(upx_apply_build_type)
if(upx_global_is_multi_config)
set(c "${CMAKE_CONFIGURATION_TYPES}")
list(INSERT c 0 "${upx_global_default_build_type}")
if(CMAKE_BUILD_TYPE)
list(INSERT c 0 "${CMAKE_BUILD_TYPE}")
endif()
list(REMOVE_DUPLICATES c)
set(CMAKE_CONFIGURATION_TYPES "${c}" CACHE STRING "List of supported configuration types." FORCE)
endif()
# now also set the build type for use in try_compile()
if(NOT CMAKE_TRY_COMPILE_CONFIGURATION)
if(CMAKE_BUILD_TYPE)
set(CMAKE_TRY_COMPILE_CONFIGURATION "${CMAKE_BUILD_TYPE}")
else()
set(CMAKE_TRY_COMPILE_CONFIGURATION "${upx_global_default_build_type}")
endif()
endif()
endmacro()
#***********************************************************************
# util
#***********************************************************************
function(upx_print_var) # ARGV
foreach(var_name ${ARGV})
if(DEFINED ${var_name})
if(NOT ",${${var_name}}," STREQUAL ",,")
if(${var_name})
message(STATUS "${var_name} = ${${var_name}}")
endif()
endif()
endif()
endforeach()
endfunction()
function(upx_print_have_symbol) # ARGV; needs include(CheckSymbolExists)
foreach(symbol ${ARGV})
set(cache_var_name "HAVE_symbol_${symbol}")
check_symbol_exists(${symbol} "limits.h;stddef.h;stdint.h" ${cache_var_name})
if(${cache_var_name})
message(STATUS "HAVE ${symbol}")
endif()
endforeach()
endfunction()
# examine MinGW/Cygwin compiler configuration
function(upx_print_mingw_symbols)
if(WIN32 OR MINGW OR CYGWIN)
if(CMAKE_C_COMPILER_ID MATCHES "(Clang|GNU)")
# runtime library: msvcrt vs ucrt vs cygwin
upx_print_have_symbol(__CRTDLL__ __CYGWIN__ __CYGWIN32__ __CYGWIN64__ __MINGW32__ __MINGW64__ __MINGW64_VERSION_MAJOR __MSVCRT__ _UCRT _WIN32 _WIN64)
# exception handing: SJLJ (setjmp/longjmp) vs DWARF vs SEH
upx_print_have_symbol(__GCC_HAVE_DWARF2_CFI_ASM __SEH__ __USING_SJLJ_EXCEPTIONS__)
# threads: win32 vs posix/pthread/winpthreads vs mcfgthread
upx_print_have_symbol(_REENTRANT __USING_MCFGTHREAD__)
endif()
endif()
endfunction()
# add wildcard expansions to a variable
function(upx_add_glob_files) # ARGV
set(var_name ${ARGV0})
list(REMOVE_AT ARGV 0)
file(GLOB files ${ARGV})
set(result "")
if(DEFINED ${var_name})
set(result "${${var_name}}")
endif()
list(APPEND result "${files}")
list(SORT result)
list(REMOVE_DUPLICATES result)
##message(STATUS "upx_add_glob_files: ${var_name} = ${result}")
set(${var_name} "${result}" PARENT_SCOPE) # return value
endfunction()
# useful for CI jobs: allow settings via environment and cache result
function(upx_cache_bool_vars) # ARGV
set(default_value "${ARGV0}")
list(REMOVE_AT ARGV 0)
foreach(var_name ${ARGV})
set(value ${default_value})
if(DEFINED UPX_CACHE_VALUE_${var_name}) # check cache
set(value "${UPX_CACHE_VALUE_${var_name}}")
elseif(DEFINED ${var_name}) # defined via "cmake -DXXX=YYY"
set(value "${${var_name}}")
elseif(DEFINED ENV{${var_name}})
if("$ENV{${var_name}}" MATCHES "^(0|1|OFF|ON|FALSE|TRUE)$") # check environment
set(value "$ENV{${var_name}}")
set(UPX_CACHE_ORIGIN_FROM_ENV_${var_name} TRUE CACHE INTERNAL "" FORCE) # for info below
endif()
endif()
# convert to bool
if(value)
set(value ON)
else()
set(value OFF)
endif()
# store result
if(UPX_CACHE_ORIGIN_FROM_ENV_${var_name})
message(STATUS "setting from environment: ${var_name} = ${value}")
endif()
set(${var_name} "${value}" PARENT_SCOPE) # store result
set(UPX_CACHE_VALUE_${var_name} "${value}" CACHE INTERNAL "" FORCE) # and store in cache
endforeach()
endfunction()
#***********************************************************************
# compilation flags
#***********************************************************************
function(upx_internal_add_definitions_with_prefix) # ARGV; needs include(CheckCCompilerFlag)
set(flag_prefix "${ARGV0}")
if(flag_prefix MATCHES "^empty$") # need "empty" to work around bug in old CMake versions
set(flag_prefix "")
endif()
list(REMOVE_AT ARGV 0)
set(failed "")
foreach(f ${ARGV})
set(flag "${flag_prefix}${f}")
string(REGEX REPLACE "[^0-9a-zA-Z_]" "_" cache_var_name "HAVE_CFLAG_${flag}")
check_c_compiler_flag("${flag}" ${cache_var_name})
if(${cache_var_name})
#message(STATUS "add_definitions: ${flag}")
add_definitions("${flag}")
else()
list(APPEND failed "${f}")
endif()
endforeach()
set(failed_flags "${failed}" PARENT_SCOPE) # return value
endfunction()
function(upx_add_definitions) # ARGV; needs include(CheckCCompilerFlag)
set(failed_flags "")
if(MSVC_FRONTEND AND CMAKE_C_COMPILER_ID MATCHES "Clang")
# for clang-cl try "-clang:" flag prefix first
upx_internal_add_definitions_with_prefix("-clang:" ${ARGV})
upx_internal_add_definitions_with_prefix("empty" ${failed_flags})
else()
upx_internal_add_definitions_with_prefix("empty" ${ARGV})
endif()
endfunction()
# compile a target with -O2 optimization even in Debug build
function(upx_compile_target_debug_with_O2) # ARGV
foreach(t ${ARGV})
if(MSVC_FRONTEND)
# MSVC uses some Debug compilation options like -RTC1 that are incompatible with -O2
else()
target_compile_options(${t} PRIVATE $<$<CONFIG:Debug>:-O2>)
endif()
endforeach()
endfunction()
# compile a source file with -O2 optimization even in Debug build; messy because of CMake limitations
function(upx_compile_source_debug_with_O2) # ARGV
set(flags "$<$<CONFIG:Debug>:-O2>")
if(${CMAKE_VERSION} VERSION_LESS "3.8")
# 3.8: The COMPILE_FLAGS source file property learned to support generator expressions
if(upx_global_is_multi_config OR NOT CMAKE_BUILD_TYPE MATCHES "^Debug$")
return()
endif()
set(flags "-O2")
endif()
if(CMAKE_GENERATOR MATCHES "Xcode") # multi-config
# NOTE: Xcode does not support per-config per-source COMPILE_FLAGS (as of CMake 3.27.7)
return()
endif()
foreach(source ${ARGV})
if(MSVC_FRONTEND)
# MSVC uses some Debug compilation options like -RTC1 that are incompatible with -O2
else()
get_source_file_property(prop "${source}" COMPILE_FLAGS)
if(prop MATCHES "^(NOTFOUND)?$")
set_source_files_properties("${source}" PROPERTIES COMPILE_FLAGS "${flags}")
else()
set_source_files_properties("${source}" PROPERTIES COMPILE_FLAGS "${prop} ${flags}")
endif()
endif()
endforeach()
endfunction()
# sanitize a target: this needs proper support from your compiler AND toolchain
function(upx_sanitize_target) # ARGV
foreach(t ${ARGV})
if(UPX_CONFIG_DISABLE_SANITIZE)
# no-op
elseif(MSVC_FRONTEND)
# MSVC uses -GS (similar to -fstack-protector) by default
elseif(MINGW OR CYGWIN)
# avoid link errors with current MinGW-w64 versions
# see https://www.mingw-w64.org/contribute/#sanitizers-asan-tsan-usan
elseif(CMAKE_C_COMPILER_ID MATCHES "^GNU" AND CMAKE_C_COMPILER_VERSION VERSION_LESS "8.0")
# unsupported compiler; unreliable/broken sanitize implementation
else()
# default sanitizer for Debug builds
target_compile_options(${t} PRIVATE $<$<CONFIG:Debug>:-fsanitize=undefined -fsanitize-undefined-trap-on-error -fstack-protector-all>)
# default sanitizer for Release builds
target_compile_options(${t} PRIVATE $<$<CONFIG:MinSizeRel>:-fstack-protector>)
target_compile_options(${t} PRIVATE $<$<CONFIG:Release>:-fstack-protector>)
target_compile_options(${t} PRIVATE $<$<CONFIG:RelWithDebInfo>:-fstack-protector>)
endif()
endforeach()
endfunction()
#***********************************************************************
# test
#***********************************************************************
function(upx_add_serial_test) # ARGV
set(name "${ARGV0}")
list(REMOVE_AT ARGV 0)
add_test(NAME "${name}" COMMAND ${ARGV})
set_tests_properties("${name}" PROPERTIES RUN_SERIAL TRUE) # run these tests sequentially
endfunction()
# vim:set ft=cmake ts=4 sw=4 tw=0 et:
+10
View File
@@ -0,0 +1,10 @@
// Copyright (C) Markus Franz Xaver Johannes Oberhumer
#include <mutex>
static std::mutex lock_mutex;
int main() {
std::lock_guard<std::mutex> lock(lock_mutex);
return 0;
}
+286
View File
@@ -0,0 +1,286 @@
#
# UPX top-level Makefile - needs GNU make and CMake >= 3.13
# Copyright (C) Markus Franz Xaver Johannes Oberhumer
#
ifeq ($(UPX_MAKEFILE_EXTRA_MK_INCLUDED),)
override UPX_MAKEFILE_EXTRA_MK_INCLUDED := 1
override check_defined = $(foreach 1,$1,$(if $(filter undefined,$(origin $1)),$(error ERROR: variable '$1' is not defined),))
override check_undefined = $(foreach 1,$1,$(if $(filter undefined,$(origin $1)),,$(error ERROR: variable '$1' is already defined)))
$(call check_defined,run_config run_build)
$(call check_undefined,run_config_and_build)
#***********************************************************************
# 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++2b
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++
build/extra/cross-linux-gnu-aarch64/%: CMAKE_SYSTEM_NAME ?= Linux
build/extra/cross-linux-gnu-aarch64/%: CMAKE_CROSSCOMPILING_EMULATOR ?= qemu-aarch64
# cross compiler: Linux glibc arm-linux-gnueabihf
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
build/extra/cross-linux-gnu-arm-eabihf/%: CMAKE_SYSTEM_NAME ?= Linux
build/extra/cross-linux-gnu-arm-eabihf/%: CMAKE_CROSSCOMPILING_EMULATOR ?= qemu-arm
# cross compiler: Windows x86 win32 MinGW (i386)
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
build/extra/cross-windows-mingw32/%: CMAKE_SYSTEM_NAME ?= Windows
build/extra/cross-windows-mingw32/%: CMAKE_CROSSCOMPILING_EMULATOR ?= wine
# 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
build/extra/cross-windows-mingw64/%: CMAKE_SYSTEM_NAME ?= Windows
build/extra/cross-windows-mingw64/%: CMAKE_CROSSCOMPILING_EMULATOR ?= wine64
# 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
build/extra/cross-darwin-arm64/%: CMAKE_SYSTEM_NAME ?= 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
build/extra/cross-darwin-x86_64/%: CMAKE_SYSTEM_NAME ?= 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 := $(CC)
build/xtarget/$(UPX_XTARGET)/%: export CXX := $(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 = build/xtarget/$(UPX_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_VERBOSE_MAKEFILE)
# pass common CMake toolchain settings from environment/make to cmake
build/%: UPX_CMAKE_CONFIG_FLAGS += $(call __add_cmake_config,CMAKE_ADDR2LINE)
build/%: UPX_CMAKE_CONFIG_FLAGS += $(call __add_cmake_config,CMAKE_AR)
build/%: UPX_CMAKE_CONFIG_FLAGS += $(call __add_cmake_config,CMAKE_DLLTOOL)
build/%: UPX_CMAKE_CONFIG_FLAGS += $(call __add_cmake_config,CMAKE_LINKER)
build/%: UPX_CMAKE_CONFIG_FLAGS += $(call __add_cmake_config,CMAKE_NM)
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_RANLIB)
build/%: UPX_CMAKE_CONFIG_FLAGS += $(call __add_cmake_config,CMAKE_READELF)
build/%: UPX_CMAKE_CONFIG_FLAGS += $(call __add_cmake_config,CMAKE_STRIP)
build/%: UPX_CMAKE_CONFIG_FLAGS += $(call __add_cmake_config,CMAKE_TAPI)
# pass common CMake LTO toolchain settings from environment/make to cmake (for use with "-flto")
build/%: UPX_CMAKE_CONFIG_FLAGS += $(call __add_cmake_config,CMAKE_C_COMPILER_AR)
build/%: UPX_CMAKE_CONFIG_FLAGS += $(call __add_cmake_config,CMAKE_C_COMPILER_RANLIB)
build/%: UPX_CMAKE_CONFIG_FLAGS += $(call __add_cmake_config,CMAKE_CXX_COMPILER_AR)
build/%: UPX_CMAKE_CONFIG_FLAGS += $(call __add_cmake_config,CMAKE_CXX_COMPILER_RANLIB)
# pass common CMake cross compilation settings from environment/make to cmake
build/%: UPX_CMAKE_CONFIG_FLAGS += $(call __add_cmake_config,CMAKE_SYSTEM_NAME)
build/%: UPX_CMAKE_CONFIG_FLAGS += $(call __add_cmake_config,CMAKE_CROSSCOMPILING_EMULATOR)
# 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
$(foreach 1,$(SUBMODULES),$(if $(wildcard vendor/$1/[CL]*),,\
$(error ERROR: missing git submodule '$1'; run 'git submodule update --init')))
endif # UPX_MAKEFILE_EXTRA_MK_INCLUDED
@@ -6,10 +6,10 @@ argv0=$0; argv0abs="$(readlink -fn "$argv0")"; argv0dir="$(dirname "$argv0abs")"
# create the image from Dockerfile # create the image from Dockerfile
# using a rootless Podman container # using a rootless Podman container
# NOTE: this image is based on rebuild-stubs/upx-stubtools-20221212-v6, # NOTE: this image is based on rebuild-stubs/upx-stubtools-20221212-v7,
# so you have to create that image first # so you have to create that image first
# WARNING: we install many packages, so the resulting image needs A LOT of disk space! # WARNING: we install many packages, so the resulting image needs A LOT of disk space!
image=upx-cross-compile-ubuntu2204-20230721-v1 image=upx-cross-compile-ubuntu2204-20230721-v3
[[ $1 == --print-image ]] && echo "$image" && exit 0 [[ $1 == --print-image ]] && echo "$image" && exit 0
podman build -t "$image" -f "$argv0dir/Dockerfile" "$argv0dir" podman build -t "$image" -f "$argv0dir/Dockerfile" "$argv0dir"
@@ -1,8 +1,8 @@
# NOTE: this image is based on rebuild-stubs/upx-stubtools-20221212-v6, # NOTE: this image is based on rebuild-stubs/upx-stubtools-20221212-v7,
# so you have to create that image first # so you have to create that image first
# WARNING: we install many packages, so the resulting image needs A LOT of disk space! # WARNING: we install many packages, so the resulting image needs A LOT of disk space!
FROM localhost/upx-stubtools-20221212-v6 FROM localhost/upx-stubtools-20221212-v7
ENV UPX_CONTAINER_IMAGE_NAME=upx-cross-compile-ubuntu2204-20230721-v1 ENV UPX_CONTAINER_IMAGE_NAME=upx-cross-compile-ubuntu2204-20230721-v3
ARG DEBIAN_FRONTEND=noninteractive ARG DEBIAN_FRONTEND=noninteractive
USER root USER root
@@ -34,6 +34,8 @@ RUN apt-get update && apt-get upgrade -y \
# Windows cross compilers # Windows cross compilers
g++-mingw-w64-i686 \ g++-mingw-w64-i686 \
g++-mingw-w64-x86-64 \ g++-mingw-w64-x86-64 \
# make sure that we use posix-threads (pthread/winpthreads) and NOT win32-threads
&& for f in i686-w64-mingw32-g++ i686-w64-mingw32-gcc x86_64-w64-mingw32-g++ x86_64-w64-mingw32-gcc; do update-alternatives --set $f /usr/bin/$f-posix; done \
&& true && true
RUN apt-get install -y \ RUN apt-get install -y \
# clang-14 and tools # clang-14 and tools
@@ -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
+1 -1
View File
@@ -6,7 +6,7 @@ argv0=$0; argv0abs="$(readlink -fn "$argv0")"; argv0dir="$(dirname "$argv0abs")"
# create the image from Dockerfile # create the image from Dockerfile
# using a rootless Podman container # using a rootless Podman container
image=upx-stubtools-20221212-v6 image=upx-stubtools-20221212-v7
[[ $1 == --print-image ]] && echo "$image" && exit 0 [[ $1 == --print-image ]] && echo "$image" && exit 0
podman build -t "$image" -f "$argv0dir/Dockerfile" "$argv0dir" podman build -t "$image" -f "$argv0dir/Dockerfile" "$argv0dir"
+5 -3
View File
@@ -15,7 +15,8 @@ RUN dpkg --add-architecture i386 \
# the full UPX binary inside the container via CMake: # the full UPX binary inside the container via CMake:
7zip bfs busybox bzip2 cabextract ccache chrpath cmake cpio curl elfutils fd-find file fzf \ 7zip bfs 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 patchutils 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
+158 -150
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.11 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.4 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.4 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.4 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.15 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.6 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.11 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.4 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.5 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.5 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.5 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.5 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.5 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.5 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.5 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.5 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.5 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.4 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.4 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.15 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.15 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,19 +125,19 @@ 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.3 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.3 amd64 MIT Kerberos runtime libraries - krb5 GSS-API Mechanism
ii libhiredis0.14:amd64 0.14.1-2 amd64 minimalistic C client library for Redis ii libhiredis0.14:amd64 0.14.1-2 amd64 minimalistic C client library for Redis
ii libhogweed6:amd64 3.7.3-1build2 amd64 low level cryptographic library (public-key cryptos) ii libhogweed6:amd64 3.7.3-1build2 amd64 low level cryptographic library (public-key cryptos)
ii libicu70:amd64 70.1-2 amd64 International Components for Unicode ii libicu70:amd64 70.1-2 amd64 International Components for Unicode
@@ -146,21 +146,21 @@ 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++
ii libk5crypto3:amd64 1.19.2-2ubuntu0.2 amd64 MIT Kerberos runtime libraries - Crypto Library ii libk5crypto3:amd64 1.19.2-2ubuntu0.3 amd64 MIT Kerberos runtime libraries - Crypto Library
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.3 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.3 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
@@ -171,7 +171,7 @@ ii libncurses5:amd64 6.3-2ubuntu0.1 amd64
ii libncurses6:amd64 6.3-2ubuntu0.1 amd64 shared libraries for terminal handling ii libncurses6:amd64 6.3-2ubuntu0.1 amd64 shared libraries for terminal handling
ii libncursesw6:amd64 6.3-2ubuntu0.1 amd64 shared libraries for terminal handling (wide character support) ii libncursesw6:amd64 6.3-2ubuntu0.1 amd64 shared libraries for terminal handling (wide character support)
ii libnettle8:amd64 3.7.3-1build2 amd64 low level cryptographic library (symmetric and one-way cryptos) ii libnettle8:amd64 3.7.3-1build2 amd64 low level cryptographic library (symmetric and one-way cryptos)
ii libnghttp2-14:amd64 1.43.0-1build3 amd64 library implementing HTTP/2 protocol (shared library) ii libnghttp2-14:amd64 1.43.0-1ubuntu0.1 amd64 library implementing HTTP/2 protocol (shared library)
ii libnl-3-200:amd64 3.5.0-0.1 amd64 library for dealing with netlink sockets ii libnl-3-200:amd64 3.5.0-0.1 amd64 library for dealing with netlink sockets
ii libnl-genl-3-200:amd64 3.5.0-0.1 amd64 library for dealing with netlink sockets - generic netlink ii libnl-genl-3-200:amd64 3.5.0-0.1 amd64 library for dealing with netlink sockets - generic netlink
ii libnsl-dev:amd64 1.3.0-2build2 amd64 libnsl development files ii libnsl-dev:amd64 1.3.0-2build2 amd64 libnsl development files
@@ -184,16 +184,16 @@ ii libpam-runtime 1.4.0-11ubuntu2.3 all
ii libpam0g:amd64 1.4.0-11ubuntu2.3 amd64 Pluggable Authentication Modules library ii libpam0g:amd64 1.4.0-11ubuntu2.3 amd64 Pluggable Authentication Modules library
ii libpcre2-8-0:amd64 10.39-3ubuntu0.1 amd64 New Perl Compatible Regular Expression Library- 8 bit runtime files ii libpcre2-8-0:amd64 10.39-3ubuntu0.1 amd64 New Perl Compatible Regular Expression Library- 8 bit runtime files
ii libpcre3:amd64 2:8.39-13ubuntu0.22.04.1 amd64 Old Perl 5 Compatible Regular Expression Library - runtime files ii libpcre3:amd64 2:8.39-13ubuntu0.22.04.1 amd64 Old Perl 5 Compatible Regular Expression Library - runtime files
ii libperl5.34:amd64 5.34.0-3ubuntu1.2 amd64 shared Perl library ii libperl5.34:amd64 5.34.0-3ubuntu1.3 amd64 shared Perl library
ii libpopt0:amd64 1.18-3build1 amd64 lib for parsing cmdline parameters ii libpopt0:amd64 1.18-3build1 amd64 lib for parsing cmdline parameters
ii libprocps8:amd64 2:3.3.17-6ubuntu2 amd64 library for accessing process information from /proc ii libprocps8:amd64 2:3.3.17-6ubuntu2.1 amd64 library for accessing process information from /proc
ii libpsl5:amd64 0.21.0-1.2build2 amd64 Library for Public Suffix List (shared libraries) ii 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.3 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.3 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.3 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)
@@ -213,12 +213,12 @@ ii libsource-highlight-common 3.1.9-4.1build2 all
ii libsource-highlight4v5 3.1.9-4.1build2 amd64 source highlighting library ii libsource-highlight4v5 3.1.9-4.1build2 amd64 source highlighting library
ii libsqlite3-0:amd64 3.37.2-2ubuntu0.1 amd64 SQLite 3 shared library ii libsqlite3-0:amd64 3.37.2-2ubuntu0.1 amd64 SQLite 3 shared library
ii libss2:amd64 1.46.5-2ubuntu1.1 amd64 command-line interface parsing library ii 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.2 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-91.101 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,24 +272,28 @@ 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
ii patch 2.7.6-7build2 amd64 Apply a diff file to an original ii patch 2.7.6-7build2 amd64 Apply a diff file to an original
ii patchelf 0.14.3-1 amd64 modify properties of ELF executables ii patchelf 0.14.3-1 amd64 modify properties of ELF executables
ii patchutils 0.4.2-1build2 amd64 Utilities to work with patches
ii pax-utils 1.2.9-1 amd64 Security-focused ELF files checking tool ii pax-utils 1.2.9-1 amd64 Security-focused ELF files checking tool
ii paxctl 0.9-1build1 amd64 new PaX control program for using the PT_PAX_FLAGS marking ii paxctl 0.9-1build1 amd64 new PaX control program for using the PT_PAX_FLAGS marking
ii perl 5.34.0-3ubuntu1.2 amd64 Larry Wall's Practical Extraction and Report Language ii perl 5.34.0-3ubuntu1.3 amd64 Larry Wall's Practical Extraction and Report Language
ii perl-base 5.34.0-3ubuntu1.2 amd64 minimal Perl system ii perl-base 5.34.0-3ubuntu1.3 amd64 minimal Perl system
ii perl-modules-5.34 5.34.0-3ubuntu1.2 all Core Perl modules ii perl-modules-5.34 5.34.0-3ubuntu1.3 all Core Perl modules
ii procps 2:3.3.17-6ubuntu2 amd64 /proc file system utilities ii procps 2:3.3.17-6ubuntu2.1 amd64 /proc file system utilities
ii python2-minimal 2.7.18-3 amd64 minimal subset of the Python2 language ii python2-minimal 2.7.18-3 amd64 minimal subset of the Python2 language
ii python2.7-minimal 2.7.18-13ubuntu1.1 amd64 Minimal subset of the Python language (version 2.7) ii 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.3 amd64 Interactive high-level object-oriented language (version 3.10)
ii python3.10-minimal 3.10.12-1~22.04.3 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
@@ -300,7 +304,7 @@ ii sed 4.8-1ubuntu2 amd64
ii sensible-utils 0.0.17 all Utilities for sensible alternative selection ii sensible-utils 0.0.17 all Utilities for sensible alternative selection
ii sysstat 12.5.2-2ubuntu0.2 amd64 system performance tools for Linux ii sysstat 12.5.2-2ubuntu0.2 amd64 system performance tools for Linux
ii sysvinit-utils 3.01-1ubuntu1 amd64 System-V-like utilities ii sysvinit-utils 3.01-1ubuntu1 amd64 System-V-like utilities
ii tar 1.34+dfsg-1ubuntu0.1.22.04.1 amd64 GNU version of the tar archiving utility ii tar 1.34+dfsg-1ubuntu0.1.22.04.2 amd64 GNU version of the tar archiving utility
ii time 1.9-0.1build2 amd64 GNU time program for measuring CPU resource usage ii time 1.9-0.1build2 amd64 GNU time program for measuring CPU resource usage
ii ubuntu-keyring 2021.03.26 all GnuPG keys of the Ubuntu archive ii ubuntu-keyring 2021.03.26 all GnuPG keys of the Ubuntu archive
ii ucf 3.0043 all Update Configuration File(s): preserve user changes to config files ii ucf 3.0043 all Update Configuration File(s): preserve user changes to config files
@@ -308,11 +312,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.15 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.15 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.15 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.15 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,74 +331,75 @@ 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) 754338 ===== TOTAL (325 packages)
52577 gcc-11 amd64 52747 gcc-11 amd64
34444 libicu70 amd64 34444 libicu70 amd64
32780 vim-runtime all 32783 vim-runtime all
28795 g++-11 amd64 28891 g++-11 amd64
28441 libperl5.34 amd64 28445 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 13593 libc6 amd64
13037 libc6-dev amd64 13037 libc6-dev amd64
12561 libc6-x32 amd64 12562 libc6-x32 amd64
12479 libc6 i386 12480 libc6 i386
12200 libc6-i386 amd64 12201 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 8249 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 7734 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 6810 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 5898 python3.10-minimal amd64
5824 libssl3 amd64 5828 libssl3 amd64
5780 libpython3.10 amd64 5768 libpython3.10 amd64
5093 libpython3.10-minimal amd64 5106 libpython3.10-minimal amd64
4249 ncurses-term all 4249 ncurses-term all
4156 apt amd64
4147 ripgrep amd64 4147 ripgrep amd64
4141 apt amd64
4082 libglib2.0-0 amd64 4082 libglib2.0-0 amd64
3923 vim amd64 3931 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
3399 util-linux amd64 3399 util-linux amd64
3347 libaria2-0 amd64 3347 libaria2-0 amd64
3181 libapt-pkg6.0 amd64 3198 libapt-pkg6.0 amd64
3013 libboost-regex1.74.0 amd64 3013 libboost-regex1.74.0 amd64
2961 liblsan0 amd64 2961 liblsan0 amd64
2943 parallel all 2943 parallel all
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 2538 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 +409,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 +422,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 +445,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 +453,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
633 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 +481,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 vim-common all
382 libmount1 amd64 382 libmount1 amd64
379 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
@@ -500,21 +507,21 @@ Packages sorted by Installed-Size:
320 libgomp1 amd64 320 libgomp1 amd64
320 libcrypt-dev amd64 320 libcrypt-dev amd64
318 libncurses5 amd64 318 libncurses5 amd64
313 libctf-nobfd0 amd64
312 libpam-runtime all 312 libpam-runtime all
312 libctf-nobfd0 amd64
307 libsource-highlight-common all 307 libsource-highlight-common all
306 libx32gomp1 amd64 306 libx32gomp1 amd64
300 libsemanage2 amd64 300 libsemanage2 amd64
298 libc-dev-bin amd64 299 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 280 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,10 +539,11 @@ 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
219 patchutils amd64
219 libtirpc3 amd64 219 libtirpc3 amd64
219 librhash0 amd64 219 librhash0 amd64
214 dash amd64 214 dash amd64
@@ -581,8 +589,8 @@ Packages sorted by Installed-Size:
114 bzip2 amd64 114 bzip2 amd64
113 libss2 amd64 113 libss2 amd64
113 lib32itm1 amd64 113 lib32itm1 amd64
113 binutils amd64
112 libc-ares2 amd64 112 libc-ares2 amd64
112 binutils amd64
110 libio-pty-perl amd64 110 libio-pty-perl amd64
105 python2-minimal amd64 105 python2-minimal amd64
105 libx32itm1 amd64 105 libx32itm1 amd64
@@ -600,8 +608,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
+39 -17
View File
@@ -8,7 +8,8 @@ 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
# and optional settings for top_srcdir, obj_suffix and XXX_extra_flags
# shell init # shell init
### set -x # enable logging ### set -x # enable logging
@@ -24,17 +25,23 @@ CXX="${CXX:-c++ -std=gnu++17}"
if test "x$AR" = "x0" || test "x$AR" = "xfalse" || test "x$AR" = "x/bin/false"; then if test "x$AR" = "x0" || test "x$AR" = "xfalse" || test "x$AR" = "x/bin/false"; then
AR="" # do not use $AR AR="" # do not use $AR
fi fi
if test -z "${mandatory_flags+set}"; then
# 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"
fi
if test -z "${sensible_flags+set}"; then
# not mandatory but good practice when using <windows.h>:
sensible_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" sensible_flags="-Wall -O2 $sensible_flags"
fi fi
CC="$CC $mandatory_flags" fi
CXX="$CXX $mandatory_flags" CC="$CC $sensible_flags $mandatory_flags"
CXX="$CXX $sensible_flags $mandatory_flags"
# go to upx top-level directory # go to upx top-level directory
# HINT: set "top_srcdir" manually if your system does not have "readlink" # HINT: set "top_srcdir" manually if your system does not have "readlink -f"
if test "x$top_srcdir" = "x"; then if test "x$top_srcdir" = "x"; then
my_argv0abs="$(readlink -fn "$my_argv0")" my_argv0abs="$(readlink -fn "$my_argv0")"
test "x$my_argv0abs" = "x" && exit 1 test "x$my_argv0abs" = "x" && exit 1
@@ -62,7 +69,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
@@ -73,7 +85,7 @@ check_submodule() {
# create and enter build directory; updates global $rel_top_srcdir # create and enter build directory; updates global $rel_top_srcdir
run "+" cd "$rel_top_srcdir" || exit 1 run "+" cd "$rel_top_srcdir" || exit 1
rel_top_srcdir=. rel_top_srcdir=.
echo "#==== build $1 =====" echo "#===== build $1 ====="
run "+" mkdir "build/by-hand/$1" run "+" mkdir "build/by-hand/$1"
run "+" cd "build/by-hand/$1" || exit 1 run "+" cd "build/by-hand/$1" || exit 1
rel_top_srcdir=../../.. rel_top_srcdir=../../..
@@ -84,42 +96,52 @@ check_submodule() {
} }
# build # build
upx_submodule_defs=
run "+" mkdir -p "build/by-hand" run "+" mkdir -p "build/by-hand"
if check_submodule bzip2; then if check_submodule bzip2; then
upx_submodule_defs="$upx_submodule_defs -DWITH_BZIP2"
test -z "${bzip2_extra_flags+set}" && bzip2_extra_flags="-DBZ_NO_STDIO"
for f in "$rel_top_srcdir"/vendor/bzip2/*.c; do for f in "$rel_top_srcdir"/vendor/bzip2/*.c; do
run "CC $f" $CC -c "$f" run "CC $f" $CC $bzip2_extra_flags -c "$f"
done done
fi fi
if check_submodule ucl; then if check_submodule ucl; then
#upx_submodule_defs="$upx_submodule_defs -DWITH_UCL"
test -z "${ucl_extra_flags+set}" && ucl_extra_flags=
for f in "$rel_top_srcdir"/vendor/ucl/src/*.c; do for f in "$rel_top_srcdir"/vendor/ucl/src/*.c; do
run "CC $f" $CC -I"$rel_top_srcdir"/vendor/ucl/include -I"$rel_top_srcdir"/vendor/ucl -c "$f" run "CC $f" $CC -I"$rel_top_srcdir"/vendor/ucl/include -I"$rel_top_srcdir"/vendor/ucl $ucl_extra_flags -c "$f"
done done
fi fi
if check_submodule zlib; then if check_submodule zlib; then
#upx_submodule_defs="$upx_submodule_defs -DWITH_ZLIB"
test -z "${zlib_extra_flags+set}" && zlib_extra_flags="-DHAVE_UNISTD_H -DHAVE_VSNPRINTF"
for f in "$rel_top_srcdir"/vendor/zlib/*.c; do for f in "$rel_top_srcdir"/vendor/zlib/*.c; do
run "CC $f" $CC -DHAVE_UNISTD_H -DHAVE_VSNPRINTF -c "$f" run "CC $f" $CC $zlib_extra_flags -c "$f"
done done
fi fi
if check_submodule zstd; then if check_submodule zstd; then
upx_submodule_defs="$upx_submodule_defs -DWITH_ZSTD"
test -z "${zstd_extra_flags+set}" && zstd_extra_flags="-DDYNAMIC_BMI2=0 -DZSTD_DISABLE_ASM"
for f in "$rel_top_srcdir"/vendor/zstd/lib/*/*.c; do for f in "$rel_top_srcdir"/vendor/zstd/lib/*/*.c; do
run "CC $f" $CC -DDYNAMIC_BMI2=0 -DZSTD_DISABLE_ASM -c "$f" run "CC $f" $CC $zstd_extra_flags -c "$f"
done done
fi fi
run "+" cd "$rel_top_srcdir" || exit 1 run "+" cd "$rel_top_srcdir" || exit 1
rel_top_srcdir=. rel_top_srcdir=.
echo "#==== build UPX =====" echo "#===== build UPX ====="
run "+" cd "build/by-hand" || exit 1 run "+" cd "build/by-hand" || exit 1
rel_top_srcdir=../.. rel_top_srcdir=../..
for f in "$rel_top_srcdir"/src/*.cpp "$rel_top_srcdir"/src/*/*.cpp; do for f in "$rel_top_srcdir"/src/*.cpp "$rel_top_srcdir"/src/*/*.cpp; do
run "CXX $f" $CXX -I"$rel_top_srcdir"/vendor -c "$f" run "CXX $f" $CXX -I"$rel_top_srcdir"/vendor $upx_submodule_defs -c "$f"
done done
# echo "#==== link UPX =====" # echo "#===== link UPX ====="
test "x$obj_suffix" = "x" && obj_suffix=.o
if test "x$AR" = "x"; then if test "x$AR" = "x"; then
# link without using $AR # link without using $AR
run "CXX upx" $CXX -o upx *.o */*.o run "CXX upx" $CXX -o upx *${obj_suffix} */*${obj_suffix}
else else
run "AR libupx" $AR rcs libupx_submodules.a */*.o run "AR libupx" $AR rcs ${AR_LIBFILE:-libupx_submodules.a} */*${obj_suffix}
run "CXX upx" $CXX -o upx *.o -L. -lupx_submodules run "CXX upx" $CXX -o upx *${obj_suffix} -L. -lupx_submodules
fi fi
echo "# current directory: '$(pwd)'" echo "# current directory: '$(pwd)'"
ls -l upx* ls -l upx*
+1
View File
@@ -32,6 +32,7 @@ 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,\.mk$,) { }
elsif ($ARGV =~ m,/tmp/.*\.(disasm|dump)$,) { } elsif ($ARGV =~ m,/tmp/.*\.(disasm|dump)$,) { }
elsif ($ARGV =~ m,/src/stub/src/arch/.*/lzma\w+\.S$,) { } elsif ($ARGV =~ m,/src/stub/src/arch/.*/lzma\w+\.S$,) { }
else { print "ERROR: hard TAB detected $ARGV: $_"; exit(1); } else { print "ERROR: hard TAB detected $ARGV: $_"; exit(1); }
+1
View File
@@ -26,6 +26,7 @@ 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,\.mk$,) { }
elsif ($ARGV =~ m,/tmp/.*\.(disasm|dump)$,) { } elsif ($ARGV =~ m,/tmp/.*\.(disasm|dump)$,) { }
elsif ($ARGV =~ m,/src/stub/src/arch/.*/lzma\w+\.S$,) { } elsif ($ARGV =~ m,/src/stub/src/arch/.*/lzma\w+\.S$,) { }
else { print "ERROR: hard TAB detected $ARGV: $_"; exit(1); } else { print "ERROR: hard TAB detected $ARGV: $_"; exit(1); }
+4 -3
View File
@@ -3,11 +3,12 @@
set -e; set -o pipefail set -e; set -o pipefail
# "Gofmt's style is nobody's favourite, but gofmt is everybody's favourite." --Rob Pike # "Gofmt's style is nobody's favourite, but gofmt is everybody's favourite." --Rob Pike
#
# NOTE: we are using clang-format-15.0.6 from upx-stubtools # NOTE: we are using clang-format-15.0.6 from upx-stubtools
# see https://github.com/upx/upx-stubtools/releases # see https://github.com/upx/upx-stubtools/releases
#
# NOTE: we use .clang-format config from upx.git/.clang-format # NOTE: we use .clang-format config from upx.git/.clang-format
# Copyright (C) Markus Franz Xaver Johannes Oberhumer
if [[ ! -f $UPX_CLANG_FORMAT ]]; then if [[ ! -f $UPX_CLANG_FORMAT ]]; then
UPX_CLANG_FORMAT="$HOME/local/bin/bin-upx/clang-format-15.0.6" UPX_CLANG_FORMAT="$HOME/local/bin/bin-upx/clang-format-15.0.6"
@@ -29,4 +30,4 @@ ulimit -v 1048576 || true
#echo $UPX_CLANG_FORMAT #echo $UPX_CLANG_FORMAT
exec "$UPX_CLANG_FORMAT" -style=file "$@" exec "$UPX_CLANG_FORMAT" -style=file "$@"
exit 1 exit 99
+75
View File
@@ -0,0 +1,75 @@
#! /usr/bin/env bash
## vim:set ts=4 sw=4 et:
set -e; set -o pipefail
argv0=$0; argv0abs=$(readlink -fn "$argv0"); argv0dir=$(dirname "$argv0abs")
#
# Copyright (C) Markus Franz Xaver Johannes Oberhumer
#
# mimic running "ctest", i.e. the "test" section of CMakeLists.txt; does not redirect stdout
#
# requires:
# $upx_exe (required, but with convenience fallback "./upx")
# optional settings:
# $upx_exe_runner (e.g. "qemu-x86_64 -cpu Nehalem" or "valgrind")
#
#***********************************************************************
# init & checks
#***********************************************************************
# upx_exe
[[ -z $upx_exe && -f ./upx && -x ./upx ]] && upx_exe=./upx # convenience fallback
if [[ -z $upx_exe ]]; then echo "UPX-ERROR: please set \$upx_exe"; exit 1; fi
if [[ ! -f $upx_exe ]]; then echo "UPX-ERROR: file '$upx_exe' does not exist"; exit 1; fi
upx_exe=$(readlink -fn "$upx_exe") # make absolute
[[ -f $upx_exe ]] || exit 1
upx_run=()
if [[ -n $upx_exe_runner ]]; then
# usage examples:
# export upx_exe_runner="qemu-x86_64 -cpu Nehalem"
# export upx_exe_runner="valgrind --leak-check=no --error-exitcode=1 --quiet"
# export upx_exe_runner="wine"
IFS=' ' read -r -a upx_run <<< "$upx_exe_runner" # split at spaces into array
elif [[ -n $CMAKE_CROSSCOMPILING_EMULATOR ]]; then
IFS=';' read -r -a upx_run <<< "$CMAKE_CROSSCOMPILING_EMULATOR" # split at semicolons into array
fi
upx_runner=( "${upx_run[@]}" )
upx_run+=( "$upx_exe" )
echo "upx_run='${upx_run[*]}'"
# upx_run sanity 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
#***********************************************************************
# see CMakeLists.txt
#***********************************************************************
export UPX="--no-color --no-progress"
"${upx_run[@]}" --version
"${upx_run[@]}" --help
"${upx_run[@]}" --sysinfo -v
exe=".out"
upx_self_exe=$upx_exe
fo="--force-overwrite"
"${upx_run[@]}" -3 "${upx_self_exe}" ${fo} -o upx-packed${exe}
"${upx_run[@]}" -3 --nrv2b "${upx_self_exe}" ${fo} -o upx-packed-n2b${exe}
"${upx_run[@]}" -3 --nrv2d "${upx_self_exe}" ${fo} -o upx-packed-n2d${exe}
"${upx_run[@]}" -3 --nrv2e "${upx_self_exe}" ${fo} -o upx-packed-n2e${exe}
"${upx_run[@]}" -1 --lzma "${upx_self_exe}" ${fo} -o upx-packed-lzma${exe}
"${upx_run[@]}" -l upx-packed${exe} upx-packed-n2b${exe} upx-packed-n2d${exe} upx-packed-n2e${exe} upx-packed-lzma${exe}
"${upx_run[@]}" --fileinfo upx-packed${exe} upx-packed-n2b${exe} upx-packed-n2d${exe} upx-packed-n2e${exe} upx-packed-lzma${exe}
"${upx_run[@]}" -t upx-packed${exe} upx-packed-n2b${exe} upx-packed-n2d${exe} upx-packed-n2e${exe} upx-packed-lzma${exe}
"${upx_run[@]}" -d upx-packed${exe} ${fo} -o upx-unpacked${exe}
set -x
"${upx_runner[@]}" ./upx-unpacked${exe} --version-short
"${upx_runner[@]}" ./upx-packed${exe} --version-short
echo "All done."
+400
View File
@@ -0,0 +1,400 @@
#! /usr/bin/env bash
## vim:set ts=4 sw=4 et:
set -e; set -o pipefail
argv0=$0; argv0abs=$(readlink -fn "$argv0"); argv0dir=$(dirname "$argv0abs")
#
# Copyright (C) Markus Franz Xaver Johannes Oberhumer
#
# test file system behaviour with symlinks; requires:
# $upx_exe (required, but with convenience fallback "./upx")
# optional settings:
# $upx_exe_runner (e.g. "qemu-x86_64 -cpu Nehalem" or "valgrind")
#
# IMPORTANT NOTE: do NOT run as user root!!
# IMPORTANT NOTE: this script only works on Unix!!
umask 0022
# disable on macOS for now, see https://github.com/upx/upx/issues/612
if [[ "$(uname)" == Darwin ]]; then
echo "$0: SKIPPED"
exit 0
fi
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
#***********************************************************************
# 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 Nehalem"
# 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
elif [[ -n $CMAKE_CROSSCOMPILING_EMULATOR ]]; then
IFS=';' read -r -a upx_run <<< "$CMAKE_CROSSCOMPILING_EMULATOR" # split at semicolons into array
fi
upx_run+=( "$upx_exe" )
echo "upx_run='${upx_run[*]}'"
# upx_run sanity 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
+147 -147
View File
@@ -46,164 +46,164 @@ b8c35fa2956da17ca505956e9f5017bb5f3a746322647e24ccb8ff28059cafa4 *powerpc-linux.
a0950546dc17fca9437219431d8ddb0249ce5b08e899e0c799a87ac982adee70 *powerpc64le-linux.elf/upx-3.95 a0950546dc17fca9437219431d8ddb0249ce5b08e899e0c799a87ac982adee70 *powerpc64le-linux.elf/upx-3.95
" "
expected_sha256sums__t110_compress_ucl_nrv2b_3_no_filter="\ expected_sha256sums__t110_compress_ucl_nrv2b_3_no_filter="\
d0b9b8a5bdbbc2f037e7e7b7a9fd2acd7b434ac03d7c59b4f2779c8621eed95e *amd64-linux.elf/upx-3.91 d11ff80ef4e663679699d92bfd5d9ed8421dc2def0a91b104697cdb2ef0a1ffe *amd64-linux.elf/upx-3.91
d36bff9e6f49c93e4c37ab50e109bd6378128017555f8f819080f02235d48d7e *amd64-linux.elf/upx-3.95 14d9ecc398a3b1863b19371387cadc434b8bb9a7da9225c58d3df2ab624cbf9e *amd64-linux.elf/upx-3.95
9c312f13ddd40a62fed7ee9f6a21fff15cae7517d4ddf55f493101b22d8e43f1 *amd64-win64.pe/upx-3.95.exe 3c161ae654b290be806a38be271a4e9498404e038d5ef163543b072077b29859 *amd64-win64.pe/upx-3.95.exe
b138d38c3955697ee0302332c031c996bacacf5e17eea8fce3282c4ea88f7299 *arm-linux.elf/upx-3.95 dc1927ca0317cdefe2c07b0a76f0c2d45cf02079ee163c1ced26688277a22be3 *arm-linux.elf/upx-3.95
e0436401972603f7fad6c693e96c89c37370113e75b8bdb4d4ecd14dda4cd8fe *arm-wince.pe/upx-3.91.exe c5a65ebda6db5f619afad9a0c0e9ece6cb025c5fdfdec57affa26120255b5e73 *arm-wince.pe/upx-3.91.exe
22107e27f63c5509f5d1c1312cb8ea1e116811695ee7f4deb765f0aa53b25a51 *arm64-linux.elf/upx-3.95 4a76cf662f29ef93cb674d9dd8ec144e2388d3b05d33abd89cb0416f760330c5 *arm64-linux.elf/upx-3.95
beae687a0575a65cec981e7cc63fd562d212d7ed64befe5dde2f0b7f92e4838e *armeb-linux.elf/upx-3.91 bfca960388f228846091c7124d49e9bb1504c7696ee0b359278009fa17dfa9a7 *armeb-linux.elf/upx-3.91
55391ffd6bccd2be4e423466d327b9f345371f9941dbb30c003e677b984e8a5e *armeb-linux.elf/upx-3.95 35b09fdbd0f9977172ebaff8231d8e00f68a8475dcba2f75b6d05c36a39f4bb4 *armeb-linux.elf/upx-3.95
a467edf8758a5b3e219bc193a9d143cb880f7d1a94771367cda7117129b34cfc *i386-dos32.djgpp2.coff/upx-3.91.exe 5434fa28036a14abf19e4c24fe1f8bdc4cff132ed9080cb34ef1dd3c596ebce8 *i386-dos32.djgpp2.coff/upx-3.91.exe
934593ba98f2dfff94197885894e7e56ff452da02a234e70734e2445b27ae8aa *i386-dos32.djgpp2.coff/upx-3.95.exe a194bd54d3058fd97871b96a14ede16b337241e912cd51456d2a8e5b3dfa6a39 *i386-dos32.djgpp2.coff/upx-3.95.exe
f26697e9a9fceca98b10c1ab6a834fa6b2bd2826a2285deaafe8cd1c754a2f61 *i386-linux.elf/upx-3.91 a57e4e0d72e8e5ace0e045192150c4b4e9889c0ac7630c885f8cecab8280ecda *i386-linux.elf/upx-3.91
f23467fde1af895827e7ad7c46c372802820143620fef2abe657aa8b6e7bdb26 *i386-linux.elf/upx-3.95 b150460b6061cfca7ec76e868626bb33a92e2558fe1f1fc8baab8c528cd1dde4 *i386-linux.elf/upx-3.95
9dd14ff1328b0d501aca10d36623b2b76c754e9677cc0bdd0c5ded740796cecf *i386-win32.pe/upx-3.91.exe c9a92aa8099262b5174b50f37c4f2995ceff79a8c9ba4c755a4fd1dc98bb0f23 *i386-win32.pe/upx-3.91.exe
5320b28b44ae1a50ea435ccabf7fe94c8031be7375c425ed618cb1f9a649442f *i386-win32.pe/upx-3.95.exe 4f15940af27173ee18aa4fdf96b79ed4c5b563141b7362b398424366e3f51dca *i386-win32.pe/upx-3.95.exe
d30bf134c5231317ae2182059034842f58d906b9dc49546bbb552f4e0411085f *m68k-atari.tos/upx-3.91.ttp 81539760603ca5abbc5f6f0e9f0df922129fad624643d6cfc10d820205519650 *m68k-atari.tos/upx-3.91.ttp
9d0fca1d248d11ec8e96801dae3978c959a26e372e05836c15b56cfc0b4aa077 *mips-linux.elf/upx-3.95 648378e19d72bc85950e6244d837475e21008dbf470a4cb3484fda10677b8afd *mips-linux.elf/upx-3.95
d68a073cb1c222515502a3a0e8f91f424cb8cedb0d849d247531c2955fa5399a *mipsel-linux.elf/upx-3.91 3eb9a06b68617499a0c7994b6b300e4fbe9ca3cf0c3601948ab129d9e181b345 *mipsel-linux.elf/upx-3.91
48919a0e564866d59ae1efae06269cea2cf7ebb5e3fda4a9ce70f9f1092a7e59 *mipsel-linux.elf/upx-3.95 5a188e4aa04e98def8294e21a587a5e958fdd745cafa52fe584976c8b62a96e9 *mipsel-linux.elf/upx-3.95
93f04183b21f077d6423c23efee62f0c920cd63463b0932ac6200e966e423763 *powerpc-linux.elf/upx-3.91 557a255deb0250ea1d0db01b07b40603817b97b9e645328bc01aaf1c51742cae *powerpc-linux.elf/upx-3.91
9ef05193c11073f477606ff2c8654f11c370951ff5a7902ba0cab31598751029 *powerpc-linux.elf/upx-3.95 0751e651da9809deea7926c4125527677d7034fbbbb4d5ae10dd692c37a47074 *powerpc-linux.elf/upx-3.95
1c04d45914809449337f22c93bf645703c6c6aa499e789ff9d2dd787be257e96 *powerpc64le-linux.elf/upx-3.95 08a46dffd447f0b1f723613bfb31d14154c1a31cc3e7982263ec4b242724410c *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 c7b05335f178c5c550e3d1d0d90fb6d921a4c0c66c16e215114483ade78d9b5f *amd64-linux.elf/upx-3.91
a267b53b2de081c414ef82351a5e88431cafdd86f8202e48929d637bf6af9192 *amd64-linux.elf/upx-3.95 9cedd104b3bdd11c6933ecb21e0c47bda7362909905e7e63e950984825650950 *amd64-linux.elf/upx-3.95
1f40d3e26e266b7c305e01a0e480f936746d1c54df32826f5f6f16fbbe58f20b *amd64-win64.pe/upx-3.95.exe d96be2f6f5fb0088736ff7a83a8854844ae41d61aff7862e91f09222755a56b0 *amd64-win64.pe/upx-3.95.exe
3d1ac6e85dfa79f8aa36d2d73073181c5cf7dd6c3e83da3b9248fa990c535d2a *arm-linux.elf/upx-3.95 cf7c02b78bb85e9426b01aaf31a99c65944822d65eaac461de1b3db0c718625d *arm-linux.elf/upx-3.95
856d307362db229387d3d33ad8478a8cba45c71d67d5bbf2d9794154a755722f *arm-wince.pe/upx-3.91.exe c05c9d17f6d74f760d0c9cdbf7c8d0f29b9059ec0048a160579d9d40ee6dde46 *arm-wince.pe/upx-3.91.exe
2fdec54995bf5367991ef64a7582a3a0e3724a71d89e77fdbe8c5bb67071d65e *arm64-linux.elf/upx-3.95 91c4f7d3485e53a5b9cfadc2dda610ad5507c02b2d75f70d9628e336eaf154c8 *arm64-linux.elf/upx-3.95
ddde64e009beff80e2e185b03dbe1b966ffa4c5db18fcd80c409b52233d4bb81 *armeb-linux.elf/upx-3.91 e4b2f54fcacc320e4a7e45b49a499b58ebf8c4ad35232e4982144c817dee19a5 *armeb-linux.elf/upx-3.91
08aece1b25973a84bedb155c2976ca08e4ce1334e21659e5583f17a0e9e3bc3c *armeb-linux.elf/upx-3.95 2a0b9e1cf234ed0746b74f8e63e15bd52f74082705ee74647899da238c7cebb3 *armeb-linux.elf/upx-3.95
ee07e1e15ff7a467f9ad262daa12886211f107886cae154795651d3cdba6fba3 *i386-dos32.djgpp2.coff/upx-3.91.exe 0d16d4489ba249636541134471ac6dca6c78874c9201dc12a7825747cd095767 *i386-dos32.djgpp2.coff/upx-3.91.exe
f73ac819d5f7f81b7cf62198381a51273df6a697d5429a144f42fabef0bcc327 *i386-dos32.djgpp2.coff/upx-3.95.exe 49671cdfa344b6d259ba339e764f0a196b190eb7a3979771b83704d26766ed63 *i386-dos32.djgpp2.coff/upx-3.95.exe
3b9e78245b5fa3108d2e69c22764e8204d24089f6661790edbdb88a508923191 *i386-linux.elf/upx-3.91 f9bde637fa12497a02d38e52fd7acba5b7220eaa3888434fc18dcbf224c14af9 *i386-linux.elf/upx-3.91
6a9aa8025e9389cbbe81a04926d12e120fd57b9909de4ee934e878a04fcf6169 *i386-linux.elf/upx-3.95 11ef9a08ea0aba3ed8d2043be6b2297e0b41f10fc5d73f9b9299fea00eb36426 *i386-linux.elf/upx-3.95
7a667cc2b566ae2f8836cc3c21d55e45bf35d61beca22ec2a806d6bcbfa1f082 *i386-win32.pe/upx-3.91.exe 48984390e36e8b6dd133a372570d215a49e1bf2b5d8304ba060e1088149eb603 *i386-win32.pe/upx-3.91.exe
cdd58a31c4914bdde47f03d81b988ffc9aa2af482de775c88cae144b4ff04293 *i386-win32.pe/upx-3.95.exe 0f9d2325e0d8930b72629c37dbb333a3ac1e3d0be0f00245a376fceb287dfff6 *i386-win32.pe/upx-3.95.exe
02b969917d52c4bd07e49e4ad589db8a1e4fa27984eac2eede03bc1abf73c376 *m68k-atari.tos/upx-3.91.ttp e87f9d09fdd313c3cf552030e9596dea67cdd6178bdf6cefb0b33f1fc893339f *m68k-atari.tos/upx-3.91.ttp
722ac1505bdaed421b6cce390608661be7236d4108429853485b8354b3c59347 *mips-linux.elf/upx-3.95 d31a35f3fae92984df28dd26c90a525038be74a54714948b96914af885902fdb *mips-linux.elf/upx-3.95
7309ee902e2c41ae72cc111c185d34e355e3892566e826698780fe69845174ad *mipsel-linux.elf/upx-3.91 26de609a6eda26fcf93273d6a95abfe211b7080abdbbdc6fd4f793ea59bb8aa6 *mipsel-linux.elf/upx-3.91
fec12c58da7886a1eaf4702b2b0c710e2b72c4179070b04691b963d1c503c73b *mipsel-linux.elf/upx-3.95 0bd931fa89c1cc5b6f0c2425f0d564808caf5223e3214fd718b6a6df2c42ca2b *mipsel-linux.elf/upx-3.95
13ad283bc0e4f37f9f06eddb8c384faa4a2e66e045496aa79dfde0ae59f14a95 *powerpc-linux.elf/upx-3.91 98dc5a8995b36bca8873a41414245db7a608d644b7a75d43bdecf9d6c8660817 *powerpc-linux.elf/upx-3.91
812550c5b65c39e347648e6ab9d51b2466919205a8b0928ef941ab3160151471 *powerpc-linux.elf/upx-3.95 42d0fce35d881b90986b6de32b6dd231c310023c1e3a33f16affe5b36503b663 *powerpc-linux.elf/upx-3.95
0e651fdc257be7b3143ad06559a137be6c87f7b7ec721d1f727dc138465b219d *powerpc64le-linux.elf/upx-3.95 e5db79bd3323df67afc53eed8621cae8de8c57522230cb18463d0a38ef8e0e2b *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 bb7df16340f56a859b10b5c591e69435b72443c4b9387b4c0afc4f3362217c5c *amd64-linux.elf/upx-3.91
b94c4603c372400a06c2ae7838ed9f41e6e9393d81e091a0ceed39c861e3443f *amd64-linux.elf/upx-3.95 bf45e190f7dfce9eec13163ccc7da85c51420736b15ef679290af7f4662e5850 *amd64-linux.elf/upx-3.95
c9230d017885d7727ca766cb7933d0681a93ef21856c39fbf807899b734172c0 *amd64-win64.pe/upx-3.95.exe cedb3c199f6b37c2993c2f6beaff327bebfcef0d1dd904b655f79c7261e374f6 *amd64-win64.pe/upx-3.95.exe
6ae717a2a7ebe99f6d1c3af8c83939f5efe2144670806c336640ad88c29a9d90 *arm-linux.elf/upx-3.95 6887322866a5b77058c1b7ecc229fb43c80ea4d88e965dd34ad8a562604f5f4c *arm-linux.elf/upx-3.95
6dbd0442d9e45c82d113463eb592d117c6761fd073e942342516fb0339d935e7 *arm-wince.pe/upx-3.91.exe 8b12ec425233a4f2e00769f2106a804d64100ac3d32f38db2383a0f51ab0c8fb *arm-wince.pe/upx-3.91.exe
6f12e95d71382a7960b9712c75a897974f29561d2a8e774b7e984c9fba380aea *arm64-linux.elf/upx-3.95 13410a318f80b193f75b26388c45f603e62ab7e30392b248f89409f73f59dcc3 *arm64-linux.elf/upx-3.95
94dbeae5763e5c86d865e9c6e473aafdb200b1ed06bfd5981728e0fa5cc6dcc6 *armeb-linux.elf/upx-3.91 bf60d3e917be3abe66f15d8e61c93e2451f241e5b7e55de8c68d0a5eea4ab474 *armeb-linux.elf/upx-3.91
cab852c4a69042aca4337869edce3af5f5aab8bf562a626ab755da0a5517bd73 *armeb-linux.elf/upx-3.95 8b0ae4260e24398e479a6e220625f50158ab3142c565cc4929350a298437e6a8 *armeb-linux.elf/upx-3.95
dc6d412f41101e334f9e09c52e63f513e2b0bd047064283c0f7389276dd6d28b *i386-dos32.djgpp2.coff/upx-3.91.exe 8b5739273e1565e031c4335ceb76e5efc00830074093f092ab3ac2942b1f756e *i386-dos32.djgpp2.coff/upx-3.91.exe
0ab8e2454b1f5bfed09a8d0c231f4c595c7445b09077387ebb9348292206be59 *i386-dos32.djgpp2.coff/upx-3.95.exe 27875bd06a68b56d4ecf4b1aac7cd088f6fd3c358970b0c0fe881026b83a4603 *i386-dos32.djgpp2.coff/upx-3.95.exe
7b6efd3d82b503f4d0ea3a111e80b0a1b785a2766ddea9f4090a7de190f811be *i386-linux.elf/upx-3.91 018137b520e22511d67d6768ec57a9bc053bc7927a87fd51d60521042d2a26f2 *i386-linux.elf/upx-3.91
c1ede9406344f8b0d5fb08777c31c62016e36f54f3ff69fc03ffbc09d5b40a0e *i386-linux.elf/upx-3.95 b9f6b51798e239c881174a9a93391ea27020fb6632f9cbf6040d2c7c43798f74 *i386-linux.elf/upx-3.95
728c6dc0c02d9ea3f7a0c86595fd64423f5545651b3a7bbc9e708759d8eec157 *i386-win32.pe/upx-3.91.exe 38229e4a2d830568ed2b25f3d23cb20b7b78e912227da45fe1bae57e131470df *i386-win32.pe/upx-3.91.exe
8569f6942377259c5a92acfe5bf0b2874f6ef3af40177947a8055e7641a776ef *i386-win32.pe/upx-3.95.exe f55a0c8f3197977bfe9bca325fb86e1a3f5effe82f4efaa062554b8dc7093e10 *i386-win32.pe/upx-3.95.exe
c4753f47328d70823f85b5d378502556388ee0a9ea6bf100cd6c73651126b3fb *m68k-atari.tos/upx-3.91.ttp e08fb4722915ea11259084c1483e2f40f0a047be600e7a9f2607c44582849ef0 *m68k-atari.tos/upx-3.91.ttp
a918b7825fd5bf50097a62177b4638abee5aeb864e06ce1624042cace8a9a922 *mips-linux.elf/upx-3.95 e452be5c3f9310879626387cbe60a7bd4465f0efc9b31e711733b964ab9286b8 *mips-linux.elf/upx-3.95
4b5cddac9a79b5e7aa99b7589d7e862bfbe026da44c2fed2a1f396883b072442 *mipsel-linux.elf/upx-3.91 bca2e642253157d4e004a53cb393cecf34df82f2072bedf4c46bf32f1302da74 *mipsel-linux.elf/upx-3.91
cc1be3f4d27d3ab5f6073f38c47ca72f4ba47121b14b7e60a4906a6d04af4e9c *mipsel-linux.elf/upx-3.95 849469774baf909c7470f5306f75e91fbed4664475d4f7d60910ce07101a0ce8 *mipsel-linux.elf/upx-3.95
cedc2def9464f839e9aab153dfe93dda0d37d0da43e8c600ef366f6adf17b64b *powerpc-linux.elf/upx-3.91 59a21be192ac75bdf5ed882a53c3e2560380dd46c1af36d256c6329bbed7c2b7 *powerpc-linux.elf/upx-3.91
748a4a2481b73ff2881b6de39749f1672b8b8d7f1d66a6453374caf6d840777d *powerpc-linux.elf/upx-3.95 fa8f8f063ae7eedb936d0774485451b785387b435b9bcbe2fc0c9fbe7ed4eced *powerpc-linux.elf/upx-3.95
f07f45141bf199db4847fd11ff56f496790efc3b7cff248a93c4ca45ca76a71a *powerpc64le-linux.elf/upx-3.95 64ade3a0badb4357bf7714e5192be73ef03678260ac31ac729fc68d639495c56 *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 ba01763526328e15b34441891b4bfbfded4488cfc0221bd923fc33c17cd94f26 *amd64-linux.elf/upx-3.91
9464896ca0082d41cf7e51159e7cd58a637b0a9d7a9151930e81746f1f43898b *amd64-linux.elf/upx-3.95 401dba7e1d660d732006a7b3b39d0b8806ac90530090141c583ad7037482b637 *amd64-linux.elf/upx-3.95
255ef236a7fe03865dd300ce447c57754aef05de537564f38715eef64285c6fa *amd64-win64.pe/upx-3.95.exe 0afff19522cd3480f13170f6f56ad1df918ff6427fdd1f76e0014adbc492112c *amd64-win64.pe/upx-3.95.exe
88ae278afa54ac766f1940f3607c91d4915cdd492988dafac9be274dbda6fd5b *arm-linux.elf/upx-3.95 a7d7457b0dc5105297f070db66bac8e581c3901efa5b4c89c991cc652edd1c58 *arm-linux.elf/upx-3.95
14f77ebb33e788aa8f9a9ad608232c3f9047dc6dfd55ceb02244a36cac9aea25 *arm-wince.pe/upx-3.91.exe a2178a2be4b595adb32e11c0dcdcf6af701a3f1fc41cc4019dee00a96c997860 *arm-wince.pe/upx-3.91.exe
a79b9a7fc7e8a5e0b42fdf342fe44aae827e63809b0797d3deefd4b9f184388c *arm64-linux.elf/upx-3.95 2e45b63d7a9897c8316436cd73ea30c788b9cc873374f572ab4119ccd4585f62 *arm64-linux.elf/upx-3.95
17603d9f6b48e10b438d65c70e8afbf87a82f84a6ee12e96ac66371663d4f18f *armeb-linux.elf/upx-3.91 c77b62df69a4e0e712e7ceab519bb5e8760b6dde3b609be5422258fe8c5464a3 *armeb-linux.elf/upx-3.91
5162fcc6f1327c76c2221d7a5f9668d05dd828f7a6d4dbbc732005d244947805 *armeb-linux.elf/upx-3.95 abe0d09a0e3aa9b483ba652face53718480c3a928d0cb0be183e41eb2c64f1aa *armeb-linux.elf/upx-3.95
3a94cec95fd3eac557bf929b372b20b155e8d331e44e47eb3486b048ebb36c9f *i386-dos32.djgpp2.coff/upx-3.91.exe 46c1aceafa1e3a2fcf224bf6e50d1dfac2dc1519671387cb066e3454b3207635 *i386-dos32.djgpp2.coff/upx-3.91.exe
632b63bce916203d52d997d191728667d1091694a5cfc1a2ed327b540357e7e9 *i386-dos32.djgpp2.coff/upx-3.95.exe 170c70a9fb257ca845bbbef5f8da0062b4197a8b3f5cf9a29f472751ab38879a *i386-dos32.djgpp2.coff/upx-3.95.exe
04edc6bc3ec1a4217461ee6b81b0ea29fb25a62721c92ea62ab0dfaa147412b1 *i386-linux.elf/upx-3.91 3a5d6531b1f1ce021282592dd645fe66affd86b36ccb72c3a4f43976fb150606 *i386-linux.elf/upx-3.91
36f47959198dace24777e95c3dcff64940ce514dc62b9cb794e957e969f07bae *i386-linux.elf/upx-3.95 c073fe95891b83015e7d778a44562d057d5b3bc787e37f794f0e2b9867d83d76 *i386-linux.elf/upx-3.95
cf3c0f31aca86f30edb45e4bd945997d7acca9c2d54acfc427936fe4ff2ba355 *i386-win32.pe/upx-3.91.exe 3e1fcbdb6267e99c50c20c3d0e6ca7795b3c35282bd127e3f09c13ae4a9ef6d0 *i386-win32.pe/upx-3.91.exe
c774fb5e3dcc0a00fa58ce223c30d7805f2f96606d9dddda30075c6a6c35a639 *i386-win32.pe/upx-3.95.exe 7618f249a922b7e504a389eb1c5c640b3bc5678ca1b4575900a778453c2666fc *i386-win32.pe/upx-3.95.exe
3be124d31c578530d8aa4da4ad53346a6fd62c8d4f3a9b1d068d5f912d9117ee *m68k-atari.tos/upx-3.91.ttp b1a481020f6afc2601dac02bba1582f47719c964fbb3e63090cd2ae19caf2c28 *m68k-atari.tos/upx-3.91.ttp
0ed619426db38bdbb783e2f47a1ce36c4b6831e00be8626f560cdf968b61f8a1 *mips-linux.elf/upx-3.95 64574681a2cbef2e5ecd4c290e8c4ed482a1a34438e3b7151eda097c593195df *mips-linux.elf/upx-3.95
9b83be53c444ad4dda60b8fa3faf9a7ae4ffb1f99027364a2af52e6c12e64462 *mipsel-linux.elf/upx-3.91 0a9f789949135858acebd4da834a2d904bbc722adc599d59ae41382475988d6a *mipsel-linux.elf/upx-3.91
e405854a04fc1ebf272e57ffc74580e387ce8860ec460d77e660c829d30d9153 *mipsel-linux.elf/upx-3.95 69faa554496af25239a5fea6f7941c0424d8f40d8078a7e40012ba284bf7b678 *mipsel-linux.elf/upx-3.95
f876a78a55939bf5ec990aaa3ece0a8a69d0a70eb7b00422d44ee1f0fa9ec6ea *powerpc-linux.elf/upx-3.91 224cc6a5336f768457c92a317a4f7e47188779ff459b821f49d2ef2188b5674b *powerpc-linux.elf/upx-3.91
8e65ca7e13e26b18c5ee93ab2c1a06f244dd7fff72da4523de3225feed9a4002 *powerpc-linux.elf/upx-3.95 8da438605f0be0e9a00c4f169d66b4639468f8e3922ed63320f33b91d0a6b099 *powerpc-linux.elf/upx-3.95
07c6d83eeb6c664674df125fa9711c76140ccec562022f8d1334c761c00e787e *powerpc64le-linux.elf/upx-3.95 efa063be5c8a488b16f0d03598b96e144a0c0d317c462a58a3e32585b68403a7 *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 19d81859acc5322e7610e44aee84eed65974650d7a7afb5fb9731d11dad70144 *amd64-linux.elf/upx-3.91
0dd8f6812aed9accea975c855dc2b4ae48fa2d03554614484de1d0335364e370 *amd64-linux.elf/upx-3.95 9663a26ee5367181ad8d8cc0d8df0573d4cfcff0aa5c8f014e56963b80007146 *amd64-linux.elf/upx-3.95
8cf83b49aab1a366318591fe69d87408ec1f7b36c3470a9cee82fd1fc39d7899 *amd64-win64.pe/upx-3.95.exe 1e2dd8689c3e7d4bd484eb53490ab0a9764c1ba4022145e309873537d63765f5 *amd64-win64.pe/upx-3.95.exe
b4b25da30e8f5da864bd8319d1c9b193eff9cf20f365d768763a2972a02d4c0f *arm-linux.elf/upx-3.95 4bf9b45b89d5668e41caf176f34b32336cbd4f858b71ed03385f69b722192796 *arm-linux.elf/upx-3.95
040117965a54878b7665b7f8155230e0f171a7749c961a1dca26eb76719b3b97 *arm-wince.pe/upx-3.91.exe b94e8887f7901239b1fb4aa926c96d4dd5d935a653e619c3ab4c4124dad7380c *arm-wince.pe/upx-3.91.exe
2b790cb0fe0b83ade980b1014e4b2f9336557f4f3ae469b94a32757ea88a281c *arm64-linux.elf/upx-3.95 6138f52201f283e64816f77380da10dc422d1689031fb6c72054647e48f55188 *arm64-linux.elf/upx-3.95
aa7ad6e9b537ab8a17d4bee539d220b39ec0fded7e9924178e3be786c6cc6907 *armeb-linux.elf/upx-3.91 72c31db3472141f44f6034c9eaec3352c4f4391560a3d81fc63cb2fe45778d32 *armeb-linux.elf/upx-3.91
66b161bdb4f9c94518f04acb385ddcaa180913f62bafc060d9f723f2bde40bdb *armeb-linux.elf/upx-3.95 8cfb3a15c6d795e0be95c92791081573d5987633b52c51e044ab3baa7436c8d5 *armeb-linux.elf/upx-3.95
1584cbffe0037e9e3c441aeac8fc2ef226ee78d0430d4298070c7258a5de650e *i386-dos32.djgpp2.coff/upx-3.91.exe ef96852c3865b3e6682e345954568acdf7ef2e3f59f3aaec5477142097b029b7 *i386-dos32.djgpp2.coff/upx-3.91.exe
da37d160c4c185dfb7c0754637278a512503ecc396741678adfda38423eaae44 *i386-dos32.djgpp2.coff/upx-3.95.exe c2c11ca8450b0cf61eb2e4d5ee54692ca0f308be4b61c544e03bfc108a79cb0d *i386-dos32.djgpp2.coff/upx-3.95.exe
39d8526dfd19d6fa8753731dc4dd362ede4a360f834f41f7d320f3e5ac1aa083 *i386-linux.elf/upx-3.91 a595b6d76204351340a2f6eff0cfb7b3f64c40866fc11e6bb7ff9d534f097bee *i386-linux.elf/upx-3.91
3a86c29348f68ec5b99dad6b739a66c36f64bf35adcc7defa950e3140c99e11d *i386-linux.elf/upx-3.95 8b1929b7753b56274c136648359a01a862ae994f291b2f511fdb1d2268bccbbc *i386-linux.elf/upx-3.95
6cc7deccbafc7c5a658a017ca18613b004d3b9b21e2a4e08343f92fbb82587fb *i386-win32.pe/upx-3.91.exe 10f32132ca0a218c069185834ace32447d4cf33c4ab7766141c4c08d967606a1 *i386-win32.pe/upx-3.91.exe
43c04b1eef6ea89821dc8689f09865008784fcb2152cbc59a3be7c091a56a536 *i386-win32.pe/upx-3.95.exe c1146e9c9b1c4e755822fbd5486c53e905b9d16028b97c55d0430bbcec467793 *i386-win32.pe/upx-3.95.exe
d0ccb6fa3cb2557923c494a5d41615e2ba6687960144a98ae575761d20ff29d6 *m68k-atari.tos/upx-3.91.ttp e217c1613fe848e6126f6a05b32aceaeda777e4d4a3755405118e3586b1bd93d *m68k-atari.tos/upx-3.91.ttp
9a217e5a233b523a1d031819f8e9acb00d5be03e8e8b718dc18a8819b5b04a3a *mips-linux.elf/upx-3.95 e2ef44ac8519d9aadf99469c8c387503d8737827f840ef5e5b5695529d4de8f6 *mips-linux.elf/upx-3.95
a5e18b41cad43cc4583cbb49248c3608d64df760a8deb302aaed5f96d3f9a46b *mipsel-linux.elf/upx-3.91 23ebde2dc0d11ab32c056683edca55b8ece7f429cea28520653ed367f16a8b26 *mipsel-linux.elf/upx-3.91
b799dbcfc4fde1cdfa572a0143a4513d83636ea0883eec320761ae57a7c36ccd *mipsel-linux.elf/upx-3.95 354c349f1504b3403ca922fb275f25835a173268a58a2ca5b17b0632220bb6c8 *mipsel-linux.elf/upx-3.95
ce42a8aad4bbed730e7bcd7970efa170040eef22c9ecad4a993b81d2f6780329 *powerpc-linux.elf/upx-3.91 6f3197a3e460b23dde39522a12d734d3dddb1515645931e4fad622d8ffbe37b8 *powerpc-linux.elf/upx-3.91
6c812174a92107ac598a6b36b2e14cad82109813e14c436a2aa9d517bdea107b *powerpc-linux.elf/upx-3.95 66bc0f51d3a2905cdf39d599ec609565fbee3afc962cdb74caa431b71a0f5ee6 *powerpc-linux.elf/upx-3.95
047a4063962c372bce50aed451404d06e3f00a4f8a535acf0f92895ebc47ba0a *powerpc64le-linux.elf/upx-3.95 f47a2f1d67f37af7087c94fc7a3fd3cd81ec3ed8149df79774250a4ace793768 *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 a4e92543a5cf5e692823d0bc2a75a995570358ba899e273d67c1df0709d5f41d *amd64-linux.elf/upx-3.91
9a7a1df07d95f17b64a9c714a444b61baf790a3a3378b53c1f0f7752c5ef7aa3 *amd64-linux.elf/upx-3.95 77e7f8b07304c8acbf55a4755854c51f5d1582558f15ec74585fc471379c81f3 *amd64-linux.elf/upx-3.95
ff5f4d665a04bfa1bddabf9853686626aea828a8e542006ef7d76d49b549d9d5 *amd64-win64.pe/upx-3.95.exe c8c19d2e24cd9c5b416888cff1828ef7a5b09236b0c423adbc3d2215977d4756 *amd64-win64.pe/upx-3.95.exe
a1f0f5df99eeed2009cdf2d253c824335b7010d91458297718bd257a2c2bc464 *arm-linux.elf/upx-3.95 0aa2cd95ed88fd3e220d14e429068269556ad7dc22ef740d07faf5288fc10189 *arm-linux.elf/upx-3.95
8b236855f4df2df1072a93d3bd1f7203c3d43801830a38679afc354250c6a7be *arm-wince.pe/upx-3.91.exe 876f3e8c159f744db0ec8bc9d9afe51be7dac4c18da744c82550d9cc8abfae64 *arm-wince.pe/upx-3.91.exe
e0644a18614e3ff48c3a8c306ab0c057a3ef58fab7015e522a6ef7a9aeb28970 *arm64-linux.elf/upx-3.95 0853acc0af2991a5c87d54215cabc46db588d2626b468559b052418fa90b40f9 *arm64-linux.elf/upx-3.95
bffe4754c49568fcc9cf67e973ecb9a48e8119bab4b03d9ebae436192fbfe76b *armeb-linux.elf/upx-3.91 af0cef4cd954d3eed8218c92434ab351c4d071293223361b12f10381117798c8 *armeb-linux.elf/upx-3.91
e69f6fc17db59b12c6910af45704c33387079492c24b1659038433e4211a8898 *armeb-linux.elf/upx-3.95 6fb686656901a4db12cdf6ffd050be225d74e1123aecea3e45d7604f0eb1104d *armeb-linux.elf/upx-3.95
14133daa854c4355b25e58803ad9b5e4bfb5e665fdbf12489f8b7c29ef6646a3 *i386-dos32.djgpp2.coff/upx-3.91.exe f2e94193758f32cab6b11e7d72d6c35339170e7db7f2fffb828e528a2a8a9611 *i386-dos32.djgpp2.coff/upx-3.91.exe
1a903afd11b866820a1814c6ee8a68431727e5c570045169295a425a6198a273 *i386-dos32.djgpp2.coff/upx-3.95.exe 4ff2bbd08158a94f2d3e7aff2b681b9314704aa9724319c4ea3f2ad554b97edc *i386-dos32.djgpp2.coff/upx-3.95.exe
86a466a5d4568b225216cce95738fc63457b065b36590ca4d204108768ca8f78 *i386-linux.elf/upx-3.91 49e38b822d774cfe637a61a36d18ce0d6b402a80cfbfe2ca16f2d63d0ea05cdf *i386-linux.elf/upx-3.91
79077dc8b999ee25171ee721e8ca56880c6d0b486f88747861ef437370075504 *i386-linux.elf/upx-3.95 2ffc13b1515ad20846cca5b2d1c7d5ae0d2b3410fe14ea97fbeb9da46332b7c9 *i386-linux.elf/upx-3.95
58b93bd7d162f89c2ea187590c515192649831ab94435b87b27d47a9e74379e4 *i386-win32.pe/upx-3.91.exe 76b29c91e9429d4587192584ee8b15a2fc40f00ae6a3c83c220c245a780e31a2 *i386-win32.pe/upx-3.91.exe
34c4260a53579a6859668cf3eb6c069cf5db82c00ad605bfdc8b2f1e0450aa16 *i386-win32.pe/upx-3.95.exe 5c5b5148f679341301776689d41205d746ea96c530721a64edf8c10e8876ae35 *i386-win32.pe/upx-3.95.exe
8495d281bf4a8f193a204b5a56d49b3c645370049e8e83db4154db3e02d55543 *m68k-atari.tos/upx-3.91.ttp cacdad81fb8a39c08f656f07a370c2c21e0c2aa7b3a81bcac22bb114078c478a *m68k-atari.tos/upx-3.91.ttp
388b013a17b84b1068502fb01b13a78a17bec5f1bd7953ec127ee3c952a7da1c *mips-linux.elf/upx-3.95 d9cbddf0e48f870dca28ccb394f2077d49fb7da3c7244a4c132627bc7b2c1a89 *mips-linux.elf/upx-3.95
466da371ef3123d18c61e2a094d7a609e16dd005f0ea8a46d813690405e1d616 *mipsel-linux.elf/upx-3.91 27fad7afdbf8fdce8b9729ed9bac4e2a1fe501ebd9dda00630c7717c504eccbb *mipsel-linux.elf/upx-3.91
36bed2f441c3abc918b46cfb80ff1bd31c82b264c3f69dcf0c1c28521fd53128 *mipsel-linux.elf/upx-3.95 b11fa6e0a609bbf3222f342951cbb77b214602168bd37ddadae23afa479c2ade *mipsel-linux.elf/upx-3.95
0b988e12ea324ce2c6ba9506209bbb80c10bb6a02ff8949887e810f44d710338 *powerpc-linux.elf/upx-3.91 b7e4c9b02c30dc7436ef6cc133342b93c75ba71779b564e21dc2cb88749bc113 *powerpc-linux.elf/upx-3.91
94981cf2f48631c476da88f8e5dcecf3ee68772ce12b189d33aaf871ef7a9536 *powerpc-linux.elf/upx-3.95 920090c1e5147f10e1be0de3ea99a8a3140a6271c260cb90eeff6549e2855828 *powerpc-linux.elf/upx-3.95
616a829f2d1324fad2863481a5cba088f2a51c38de866c20fe9d9d7a75df3dfc *powerpc64le-linux.elf/upx-3.95 29c6854869fd0a4e95cb3d434f8b93e7728c126ce2a8f9d7163506f1271b2af0 *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 f11151a8eea22872544062dcab0190e26d63073c0e0b9e1356f31a336e7a56e4 *amd64-linux.elf/upx-3.91
a9ca57293b43b093fb9582a81a2ad2877f7c2546a536541bf3766452a9faa4aa *amd64-linux.elf/upx-3.95 047ad308483a6f2789de768f8de86a35b9a9c92d9ec4d04efeae55c7ea5c643c *amd64-linux.elf/upx-3.95
3247a637f6cc56219bc2d6a3b16237226e1ba97ac1d0fce012657e23bfe256c3 *amd64-win64.pe/upx-3.95.exe bd559454e3c5ad2e4afd145c2e366aed0e6bb6e8e059e7bd0bc72962cfd1f2ad *amd64-win64.pe/upx-3.95.exe
d43683421216236ab6e90f4f7d6ad69f3b1d18e53bc5dd57b5dcea2916fe480f *arm-linux.elf/upx-3.95 e1966d2e2056dc0af5bd18b880039cca83c70b5c370f3869e013384bdf8c853a *arm-linux.elf/upx-3.95
387787098a33b61637b39d7d015972d18e687771d8596b74286764ac73ee9286 *arm-wince.pe/upx-3.91.exe ef0a4b9341aacd4b9962f9e77c019c5e641616f4f5d713af93263cbf67e32a0f *arm-wince.pe/upx-3.91.exe
e2e476b9ccfd13f14940f28240b8e6f85ce0e21f6cc5b619cc2972b9238b5bd2 *arm64-linux.elf/upx-3.95 45700ca243888ec22cf84018d7b4ec47f2ee6e36edfc4a16056ea81e99eee9d0 *arm64-linux.elf/upx-3.95
538eef066d7deb4b6c07de4a50ffaf24a759278beeee9204e4d6c642aa382de3 *armeb-linux.elf/upx-3.91 fd5697370dca17662f271530af4a164790c63b164cc3160d7d8be317e624af8d *armeb-linux.elf/upx-3.91
9349eca3e551ce1d2ab95735b8898efc54439c3d87395f2c0bddbe88fbc35cbc *armeb-linux.elf/upx-3.95 c09ecb409692d91fc4710896f6fe934066d4bdff778c675c99e27b5c624d1d63 *armeb-linux.elf/upx-3.95
ce768b3be6ffeb84d0558a937a9a5778427ce56898a9b3ef9490e7e5ba6ce688 *i386-dos32.djgpp2.coff/upx-3.91.exe 4766485709641cbbe06b09e64d0c77b66afa45eadf3ee11c0e92e5a0a97e5bc1 *i386-dos32.djgpp2.coff/upx-3.91.exe
849e285cb39e5609f384559398c47f5e34d2067711c58aacc5ed1c97495b8da0 *i386-dos32.djgpp2.coff/upx-3.95.exe f4de30c9fb6b695264db098790d189b01f1df950c75e34f8f445d8fa49b69755 *i386-dos32.djgpp2.coff/upx-3.95.exe
6a0b78c2af8d68faac587531b32679a3a264fa86f524cf801db31a41a231becb *i386-linux.elf/upx-3.91 a25c10adb376e932191aeb2e11d1020e71b56a9c82ea0d7f8af71b4e05cffbf1 *i386-linux.elf/upx-3.91
e524ee0c3058ba4a44073ec29d67982bc39721865b33e6881dffbe2329a79279 *i386-linux.elf/upx-3.95 4dca2d0bdc78d5d8fc582f6638c4595ee45c03ee2523e1da0cd914576ba7a5dd *i386-linux.elf/upx-3.95
06d281a60d5ed815f74052e3e133915739e58c3a563a2e914186e85114687a12 *i386-win32.pe/upx-3.91.exe f4500b64adb382552152c737880a3cd55c172d023437c996ccae5b07414dcb0e *i386-win32.pe/upx-3.91.exe
a1c3256670c4f55d3aea58063c4689d122c605d079537a27b1952eeab8d5d6ad *i386-win32.pe/upx-3.95.exe 8922ab742e9641ca533af2693c85fd5121bbac677b12a2c67a33a49b6e4eb939 *i386-win32.pe/upx-3.95.exe
b866f184c6fe911b410afa8080acd1c7fddc11131d15bd272eb8adbca20439d2 *m68k-atari.tos/upx-3.91.ttp f95d3a1811be7665fc6cb9479eeb4e94b64d4b1f16187b06fa6c9f0c54782564 *m68k-atari.tos/upx-3.91.ttp
197d7dace27bbeba5627868b7a333b4580673ffe38353f3a11bd2d65b4216470 *mips-linux.elf/upx-3.95 e637eb6b7c4c9c06488e79c26f8910cc8c40196a962339c849457e6b6a59b964 *mips-linux.elf/upx-3.95
9b13d57d59a97313e20a0d3e02641045fddd5eb3bcbbcf7772181d5d87c4b3bf *mipsel-linux.elf/upx-3.91 8c1c4fe3430f1524e70c68f2c10ab67f356c94ea79cf7726a24931d29388458c *mipsel-linux.elf/upx-3.91
6f671511e19d9719c0bc7c2344d65cbf13a04da1c9bae9e55d2ca83ba9dede0a *mipsel-linux.elf/upx-3.95 572283b261f90bd2b13f5a65c94f065f7a7e40ed32c2d048f314ec8a9656e365 *mipsel-linux.elf/upx-3.95
4ec415399f04f546d9831758a3cfedb00f20b06cb7e1c2eb38354aff3b6d3004 *powerpc-linux.elf/upx-3.91 0a7c32c5b3cda6e7c90e21227f1b5af14d169d56d074644c431dbf367b308cdb *powerpc-linux.elf/upx-3.91
20e31a1df4eb5f6a930b34707b591265c6b5609ee2b2cdd5f504009284d1afc9 *powerpc-linux.elf/upx-3.95 fe6e2d1c1b8e9119713863997f52735a4814d35c3bfba0a6ef1cd9e218510383 *powerpc-linux.elf/upx-3.95
fe4dd9c59e6ae76ff23d6b4df27ca0df4289f6d13c8e3dc8d82c22982639ddd9 *powerpc64le-linux.elf/upx-3.95 cbeb988b78e3edd3f0d9526998b700c0b1c3c4bb29ef9e2591c4083a40126c50 *powerpc64le-linux.elf/upx-3.95
" "
########## end .sha256sums.recreate ########## end .sha256sums.recreate
+37 -31
View File
@@ -3,21 +3,25 @@
set -e; set -o pipefail set -e; set -o pipefail
argv0=$0; argv0abs=$(readlink -fn "$argv0"); argv0dir=$(dirname "$argv0abs") argv0=$0; argv0abs=$(readlink -fn "$argv0"); argv0dir=$(dirname "$argv0abs")
#
# Copyright (C) Markus Franz Xaver Johannes Oberhumer
#
# very first version of the upx-testsuite; requires: # very first version of the upx-testsuite; requires:
# $upx_exe (required, but with convenience fallback "./upx") # $upx_exe (required, but with convenience fallback "./upx")
# $upx_testsuite_SRCDIR (required, but with convenience fallback) # $upx_testsuite_SRCDIR (required, but with convenience fallback)
# $upx_testsuite_BUILDDIR (optional) # $upx_testsuite_BUILDDIR (optional)
# #
# optional settings: # optional settings:
# $upx_exe_runner (e.g. "qemu-x86_64 -cpu Westmere" or "valgrind") # $upx_exe_runner (e.g. "qemu-x86_64 -cpu Nehalem" or "valgrind")
# $UPX_TESTSUITE_VERBOSE # $UPX_TESTSUITE_VERBOSE
# $UPX_TESTSUITE_LEVEL # $UPX_TESTSUITE_LEVEL
# #
# see https://github.com/upx/upx-testsuite.git # see https://github.com/upx/upx-testsuite.git
#
# /*********************************************************************** #***********************************************************************
# // init & checks # init & checks
# ************************************************************************/ #***********************************************************************
# 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
@@ -28,15 +32,17 @@ upx_exe=$(readlink -fn "$upx_exe") # make absolute
upx_run=() upx_run=()
if [[ -n $upx_exe_runner ]]; then if [[ -n $upx_exe_runner ]]; then
# usage examples: # usage examples:
# export upx_exe_runner="qemu-x86_64 -cpu Westmere" # export upx_exe_runner="qemu-x86_64 -cpu Nehalem"
# export upx_exe_runner="valgrind --leak-check=no --error-exitcode=1 --quiet" # export upx_exe_runner="valgrind --leak-check=no --error-exitcode=1 --quiet"
# export upx_exe_runner="wine" # export upx_exe_runner="wine"
IFS=' ' read -r -a upx_run <<< "$upx_exe_runner" # split at spaces into array IFS=' ' read -r -a upx_run <<< "$upx_exe_runner" # split at spaces into array
elif [[ -n $CMAKE_CROSSCOMPILING_EMULATOR ]]; then
IFS=';' read -r -a upx_run <<< "$CMAKE_CROSSCOMPILING_EMULATOR" # split at semicolons into array
fi fi
upx_run+=( "$upx_exe" ) upx_run+=( "$upx_exe" )
echo "upx_run='${upx_run[*]}'" echo "upx_run='${upx_run[*]}'"
# upx_run check, part1 # upx_run sanity check, part1
if ! "${upx_run[@]}" --version-short >/dev/null; then echo "UPX-ERROR: FATAL: upx --version-short FAILED"; exit 1; fi if ! "${upx_run[@]}" --version-short >/dev/null; then echo "UPX-ERROR: FATAL: upx --version-short FAILED"; exit 1; fi
if ! "${upx_run[@]}" -L >/dev/null 2>&1; then echo "UPX-ERROR: FATAL: upx -L FAILED"; exit 1; fi if ! "${upx_run[@]}" -L >/dev/null 2>&1; then echo "UPX-ERROR: FATAL: upx -L FAILED"; exit 1; fi
if ! "${upx_run[@]}" --help >/dev/null; then echo "UPX-ERROR: FATAL: upx --help FAILED"; exit 1; fi if ! "${upx_run[@]}" --help >/dev/null; then echo "UPX-ERROR: FATAL: upx --help FAILED"; exit 1; fi
@@ -72,7 +78,7 @@ upx_testsuite_BUILDDIR=$(readlink -fn "$upx_testsuite_BUILDDIR") # make absolute
cd / && cd "$upx_testsuite_BUILDDIR" || exit 1 cd / && cd "$upx_testsuite_BUILDDIR" || exit 1
: > ./.mfxnobackup : > ./.mfxnobackup
# upx_run check, part2 # upx_run sanity check, part2
if ! "${upx_run[@]}" --version-short >/dev/null; then if ! "${upx_run[@]}" --version-short >/dev/null; then
echo "UPX-ERROR: FATAL: upx --version-short FAILED" echo "UPX-ERROR: FATAL: upx --version-short FAILED"
echo "please make sure that \$upx_exe contains ABSOLUTE file paths and can be run from any directory" echo "please make sure that \$upx_exe contains ABSOLUTE file paths and can be run from any directory"
@@ -91,9 +97,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 +114,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 +200,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 +224,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 +256,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 +304,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
+45 -44
View File
@@ -3,16 +3,11 @@
# Copyright (C) Markus Franz Xaver Johannes Oberhumer # Copyright (C) Markus Franz Xaver Johannes Oberhumer
# #
# NOTE: this Makefile is deprecated - please directly use the CMake build # NOTE: this Makefile is deprecated - please directly use
# instead. And see the top-level Makefile for some pre-defined CMake # the top-level CMake build instead.
# 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)/..
@@ -23,31 +18,36 @@ endif
# #
# NOTE that top-level Makefile .DEFAULT_GOAL is build/release # NOTE that top-level Makefile .DEFAULT_GOAL is build/release
.DEFAULT_GOAL = build/debug .DEFAULT_GOAL = build/all
build/debug: $(top_srcdir)/build/debug/upx build/debug: $(top_srcdir)/build/debug
build/release: $(top_srcdir)/build/release/upx build/release: $(top_srcdir)/build/release
# 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
# actual rules - redirect to top-level
$(top_srcdir)/build/debug: PHONY; $(MAKE) -C $(top_srcdir) build/debug
$(top_srcdir)/build/release: PHONY; $(MAKE) -C $(top_srcdir) build/release
# convenience
CTEST = ctest
test:: $(top_srcdir)/build/debug PHONY; cd $< && $(CTEST)
test:: $(top_srcdir)/build/release PHONY; cd $< && $(CTEST)
# #
# "make run-testsuite" # "make run-testsuite"
# see https://github.com/upx/upx-testsuite.git # git clone https://github.com/upx/upx-testsuite.git
# #
# search for the UPX testsuite -- git clone https://github.com/upx/upx-testsuite.git # search for the UPX testsuite
# you also can override upx_testsuite_SRCDIR # you also can override upx_testsuite_SRCDIR
ifndef upx_testsuite_SRCDIR ifndef upx_testsuite_SRCDIR
# search standard locations below $(top_srcdir) # search standard locations below $(top_srcdir)
@@ -62,21 +62,34 @@ endif
# run the UPX testsuite # run the UPX testsuite
# The expected (old) checksums are in $(top_srcdir)/misc/testsuite/upx_testsuite_1-expected_sha256sums.sh # The expected (old) checksums are in $(top_srcdir)/misc/testsuite/upx_testsuite_1-expected_sha256sums.sh
# The actual (new) checksums are in ./tmp-upx-testsuite/testsuite_1/.sha256sums.recreate # The actual (new) checksums are in ./tmp-upx-testsuite-*/testsuite_1/.sha256sums.recreate
ifneq ($(wildcard $(upx_testsuite_SRCDIR)/files/packed/.),) ifneq ($(wildcard $(upx_testsuite_SRCDIR)/files/packed/.),)
ifneq ($(wildcard $(top_srcdir)/misc/testsuite/upx_testsuite_1.sh),) ifneq ($(wildcard $(top_srcdir)/misc/testsuite/upx_testsuite_1.sh),)
run-testsuite: run-testsuite-release run-testsuite: run-testsuite-release
run-testsuite-%: export upx_testsuite_SRCDIR := $(upx_testsuite_SRCDIR) run-testsuite-%: export upx_testsuite_SRCDIR := $(upx_testsuite_SRCDIR)
run-testsuite-%: export upx_testsuite_BUILDDIR := ./tmp-upx-testsuite run-testsuite-debug: export upx_testsuite_BUILDDIR := ./tmp-upx-testsuite-debug
run-testsuite-debug: export upx_exe := $(top_srcdir)/build/debug/upx run-testsuite-debug: export upx_exe := $(top_srcdir)/build/debug/upx
run-testsuite-debug: PHONY $(top_srcdir)/build/debug/upx run-testsuite-debug: $(top_srcdir)/build/debug PHONY
time -p bash $(top_srcdir)/misc/testsuite/upx_testsuite_1.sh time -p bash $(top_srcdir)/misc/testsuite/upx_testsuite_1.sh
run-testsuite-release: export upx_testsuite_BUILDDIR := ./tmp-upx-testsuite-release
run-testsuite-release: export upx_exe := $(top_srcdir)/build/release/upx run-testsuite-release: export upx_exe := $(top_srcdir)/build/release/upx
run-testsuite-release: PHONY $(top_srcdir)/build/release/upx run-testsuite-release: $(top_srcdir)/build/release PHONY
time -p bash $(top_srcdir)/misc/testsuite/upx_testsuite_1.sh time -p bash $(top_srcdir)/misc/testsuite/upx_testsuite_1.sh
endif endif
endif endif
#
# "make check-whitespace"
#
ifneq ($(wildcard /usr/bin/env),) # need Unix utils like bash, perl, sed, xargs, etc.
CHECK_WHITESPACE = bash $(top_srcdir)/misc/scripts/check_whitespace.sh $(top_srcdir)
ifneq ($(wildcard $(top_srcdir)/.git/.),)
CHECK_WHITESPACE = bash $(top_srcdir)/misc/scripts/check_whitespace_git.sh $(top_srcdir)
endif
check-whitespace: PHONY; $(CHECK_WHITESPACE)
endif
# #
# "make clang-format" # "make clang-format"
# #
@@ -84,27 +97,15 @@ endif
# automatically format some C++ source code files # automatically format some C++ source code files
ifeq ($(shell uname),Linux) ifeq ($(shell uname),Linux)
# Markus loves clang-format, but John hates it; find a compromise # Markus loves clang-format, but John hates it; find a compromise
CLANG_FORMAT_EXCLUDE_FILES += conf.h miniacc.h version.h packer_c.cpp 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_EXCLUDE_FILES += 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]* */*.[ch]*))
CLANG_FORMAT_FILES := $(sort $(wildcard *.[ch]* ../maint/src/*.[ch]* [cu]*/*.[ch]*)) CLANG_FORMAT_FILES += $(sort $(wildcard stub/tools/*/*.[ch]*))
CLANG_FORMAT_FILES += $(sort $(wildcard ../misc/cmake/try_compile/*.[ch]*))
CLANG_FORMAT_FILES := $(filter-out $(CLANG_FORMAT_EXCLUDE_FILES),$(CLANG_FORMAT_FILES)) CLANG_FORMAT_FILES := $(filter-out $(CLANG_FORMAT_EXCLUDE_FILES),$(CLANG_FORMAT_FILES))
clang-format: PHONY $(CLANG_FORMAT_FILES) clang-format: $(CLANG_FORMAT_FILES) PHONY
@echo "running upx-clang-format" @echo "running upx-clang-format"
@$(top_srcdir)/misc/scripts/upx-clang-format.sh -i $(CLANG_FORMAT_FILES) @$(top_srcdir)/misc/scripts/upx-clang-format.sh -i $(CLANG_FORMAT_FILES)
endif endif
#
# "make check-whitespace"
#
CHECK_WHITESPACE =
ifeq ($(shell uname),Linux)
CHECK_WHITESPACE = $(top_srcdir)/misc/scripts/check_whitespace.sh $(top_srcdir)
ifneq ($(wildcard $(top_srcdir)/.git/.),)
CHECK_WHITESPACE = $(top_srcdir)/misc/scripts/check_whitespace_git.sh $(top_srcdir)
endif
check-whitespace: PHONY; $(CHECK_WHITESPACE)
endif
# vim:set ts=8 sw=8 noet: # vim:set ts=8 sw=8 noet:
+150 -54
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer Copyright (C) 1996-2024 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2023 Laszlo Molnar Copyright (C) 1996-2024 Laszlo Molnar
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
@@ -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)); }
@@ -657,6 +753,24 @@ inline unsigned UPX_MIN(const LE32 &a, unsigned b) { return UPX_MIN(unsigned(a),
// misc support // misc support
**************************************************************************/ **************************************************************************/
// <type_traits> upx_is_integral; see conf.h
#define TT_UPX_IS_INTEGRAL(T) \
template <> \
struct upx_is_integral<T> : public std::true_type {}; \
template <> \
struct upx_is_integral<const T> : public std::true_type {}; \
template <> \
struct upx_is_integral<volatile T> : public std::true_type {}; \
template <> \
struct upx_is_integral<const volatile T> : public std::true_type {}
TT_UPX_IS_INTEGRAL(BE16);
TT_UPX_IS_INTEGRAL(BE32);
TT_UPX_IS_INTEGRAL(BE64);
TT_UPX_IS_INTEGRAL(LE16);
TT_UPX_IS_INTEGRAL(LE32);
TT_UPX_IS_INTEGRAL(LE64);
#undef TT_UPX_IS_INTEGRAL
// native types // native types
#if (ACC_ABI_BIG_ENDIAN) #if (ACC_ABI_BIG_ENDIAN)
typedef BE16 NE16; typedef BE16 NE16;
@@ -680,24 +794,6 @@ typedef LE64 NE64;
#define ne64_compare_signed le64_compare_signed #define ne64_compare_signed le64_compare_signed
#endif #endif
// <type_traits> upx_is_integral
#define TT_IS_INTEGRAL(T) \
template <> \
struct upx_is_integral<T> : public std::true_type {}; \
template <> \
struct upx_is_integral<const T> : public std::true_type {}; \
template <> \
struct upx_is_integral<volatile T> : public std::true_type {}; \
template <> \
struct upx_is_integral<const volatile T> : public std::true_type {}
TT_IS_INTEGRAL(BE16);
TT_IS_INTEGRAL(BE32);
TT_IS_INTEGRAL(BE64);
TT_IS_INTEGRAL(LE16);
TT_IS_INTEGRAL(LE32);
TT_IS_INTEGRAL(LE64);
#undef TT_IS_INTEGRAL
// for use with qsort() // for use with qsort()
extern "C" { extern "C" {
int __acc_cdecl_qsort be16_compare(const void *, const void *); int __acc_cdecl_qsort be16_compare(const void *, const void *);
+8 -17
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer Copyright (C) 1996-2024 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2023 Laszlo Molnar Copyright (C) 1996-2024 Laszlo Molnar
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
@@ -79,12 +79,9 @@ struct AbstractPolicy {
private: private:
// disable copy and move // disable copy and move
AbstractPolicy(const AbstractPolicy &) DELETED_FUNCTION; UPX_CXX_DISABLE_COPY_MOVE(AbstractPolicy)
AbstractPolicy &operator=(const AbstractPolicy &) DELETED_FUNCTION;
AbstractPolicy(AbstractPolicy &&) noexcept DELETED_FUNCTION;
AbstractPolicy &operator=(AbstractPolicy &&) noexcept DELETED_FUNCTION;
// disable dynamic allocation // disable dynamic allocation
ACC_CXX_DISABLE_NEW_DELETE UPX_CXX_DISABLE_NEW_DELETE(AbstractPolicy)
}; };
#endif #endif
@@ -147,12 +144,9 @@ struct BEPolicy
private: private:
// disable copy and move // disable copy and move
BEPolicy(const BEPolicy &) DELETED_FUNCTION; UPX_CXX_DISABLE_COPY_MOVE(BEPolicy)
BEPolicy &operator=(const BEPolicy &) DELETED_FUNCTION;
BEPolicy(BEPolicy &&) noexcept DELETED_FUNCTION;
BEPolicy &operator=(BEPolicy &&) noexcept DELETED_FUNCTION;
// disable dynamic allocation // disable dynamic allocation
ACC_CXX_DISABLE_NEW_DELETE UPX_CXX_DISABLE_NEW_DELETE(BEPolicy)
}; };
struct LEPolicy struct LEPolicy
@@ -209,12 +203,9 @@ struct LEPolicy
private: private:
// disable copy and move // disable copy and move
LEPolicy(const LEPolicy &) DELETED_FUNCTION; UPX_CXX_DISABLE_COPY_MOVE(LEPolicy)
LEPolicy &operator=(const LEPolicy &) DELETED_FUNCTION;
LEPolicy(LEPolicy &&) noexcept DELETED_FUNCTION;
LEPolicy &operator=(LEPolicy &&) noexcept DELETED_FUNCTION;
// disable dynamic allocation // disable dynamic allocation
ACC_CXX_DISABLE_NEW_DELETE UPX_CXX_DISABLE_NEW_DELETE(LEPolicy)
}; };
// Native Endianness policy (aka host policy) // Native Endianness policy (aka host policy)
+76 -69
View File
@@ -2,7 +2,7 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer Copyright (C) 1996-2024 Markus Franz Xaver Johannes Oberhumer
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
@@ -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);
@@ -615,6 +564,17 @@ TEST_CASE("acc_vget") {
CHECK_EQ(acc_vget_acc_hvoid_p(nullptr, 0), nullptr); CHECK_EQ(acc_vget_acc_hvoid_p(nullptr, 0), nullptr);
} }
TEST_CASE("ptr_invalidate_and_poison") {
int *ip = nullptr;
ptr_invalidate_and_poison(ip);
assert(ip != nullptr);
(void) ip;
double *dp;
ptr_invalidate_and_poison(dp);
assert(dp != nullptr);
(void) dp;
}
TEST_CASE("working -fno-strict-aliasing") { TEST_CASE("working -fno-strict-aliasing") {
bool ok; bool ok;
long v = 0; long v = 0;
@@ -637,6 +597,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 +615,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 +637,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: */
+410
View File
@@ -0,0 +1,410 @@
/* dt_cxxlib.cpp -- doctest check
This file is part of the UPX executable compressor.
Copyright (C) 1996-2024 Markus Franz Xaver Johannes Oberhumer
All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them
and/or modify them under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of
the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; see the file COPYING.
If not, write to the Free Software Foundation, Inc.,
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
Markus F.X.J. Oberhumer
<markus@oberhumer.com>
*/
// 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("ab") == 3)
ACC_COMPILE_TIME_ASSERT_HEADER(usizeof(L'a') == sizeof(wchar_t))
ACC_COMPILE_TIME_ASSERT_HEADER(usizeof(L"") == 1 * sizeof(wchar_t))
ACC_COMPILE_TIME_ASSERT_HEADER(usizeof(L"a") == 2 * sizeof(wchar_t))
ACC_COMPILE_TIME_ASSERT_HEADER(usizeof(L"ab") == 3 * sizeof(wchar_t))
ACC_COMPILE_TIME_ASSERT_HEADER(usizeof(0) == sizeof(int))
ACC_COMPILE_TIME_ASSERT_HEADER(usizeof(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))
#if 0
// works, but may trigger clang/gcc warnings "-Wunused-value"
ACC_COMPILE_TIME_ASSERT_HEADER(usizeof((1LL, 1)) == sizeof(int))
ACC_COMPILE_TIME_ASSERT_HEADER(usizeof((1, 1LL)) == sizeof(long long))
#endif
namespace compile_time = upx::compile_time;
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"))
/*************************************************************************
// UPX_CXX_DISABLE_xxx
**************************************************************************/
namespace {
template <class TA, class TB, int TC = 0>
struct MyType1 {
MyType1() noexcept {}
UPX_CXX_DISABLE_ADDRESS(MyType1)
UPX_CXX_DISABLE_COPY_MOVE(MyType1)
UPX_CXX_DISABLE_NEW_DELETE_NO_VIRTUAL(MyType1)
};
template <class TA, class TB, int TC = 0>
struct MyType2 {
MyType2() noexcept {}
UPX_CXX_DISABLE_COPY_MOVE(MyType2)
typedef MyType2<TA, TB, TC> Self;
UPX_CXX_DISABLE_ADDRESS(Self)
UPX_CXX_DISABLE_NEW_DELETE_NO_VIRTUAL(Self)
};
template <class TA, class TB, int TC = 0>
struct MyVType1 {
MyVType1() noexcept {}
virtual ~MyVType1() noexcept {}
UPX_CXX_DISABLE_ADDRESS(MyVType1)
UPX_CXX_DISABLE_COPY_MOVE(MyVType1)
UPX_CXX_DISABLE_NEW_DELETE(MyVType1)
};
template <class TA, class TB, int TC = 0>
struct MyVType2 {
MyVType2() noexcept {}
virtual ~MyVType2() noexcept {}
UPX_CXX_DISABLE_COPY_MOVE(MyVType2)
typedef MyVType2<TA, TB, TC> Self;
UPX_CXX_DISABLE_ADDRESS(Self)
UPX_CXX_DISABLE_NEW_DELETE(Self)
};
TEST_CASE("upx_cxx_disable") {
MyType1<char, int, 1> dummy1;
MyType2<char, int, 2> dummy2;
MyVType1<char, int, 1> vdummy1;
MyVType2<char, int, 2> vdummy2;
(void) dummy1;
(void) dummy2;
(void) vdummy1;
(void) vdummy2;
}
} // namespace
namespace test_disable_new_delete {
struct A1 {
int a;
};
struct A2 {
int a;
UPX_CXX_DISABLE_NEW_DELETE_NO_VIRTUAL(A2)
};
struct B1_A1 : public A1 {
int b;
};
struct B1_A2 : public A2 {
int b;
};
struct B2_A1 : public A1 {
int b;
UPX_CXX_DISABLE_NEW_DELETE_NO_VIRTUAL(B2_A1)
};
struct B2_A2 : public A2 {
int b;
UPX_CXX_DISABLE_NEW_DELETE_NO_VIRTUAL(B2_A2)
};
struct X1 {
virtual ~X1() noexcept {}
int x;
};
struct X2 {
virtual ~X2() noexcept {}
int x;
UPX_CXX_DISABLE_NEW_DELETE(X2)
};
struct Y1_X1 : public X1 {
int y;
};
struct Y1_X2 : public X2 {
int y;
};
struct Y2_X1 : public X1 {
int y;
UPX_CXX_DISABLE_NEW_DELETE(Y2_X1)
};
struct Y2_X2 : public X2 {
int y;
UPX_CXX_DISABLE_NEW_DELETE(Y2_X2)
};
struct Z1_X1 : public X1 {
virtual ~Z1_X1() noexcept {}
int z;
};
struct Z1_X2 : public X2 {
virtual ~Z1_X2() noexcept {}
int z;
};
struct Z2_X1 : public X1 {
virtual ~Z2_X1() noexcept {}
int z;
UPX_CXX_DISABLE_NEW_DELETE(Z2_X1)
};
struct Z2_X2 : public X2 {
virtual ~Z2_X2() noexcept {}
int z;
UPX_CXX_DISABLE_NEW_DELETE(Z2_X2)
};
} // namespace test_disable_new_delete
/*************************************************************************
// util
**************************************************************************/
TEST_CASE("ptr_static_cast") {
// check that we don't trigger any -Wcast-align warnings
using upx::ptr_static_cast;
void *vp = nullptr;
byte *bp = nullptr;
int *ip = nullptr;
double *dp = nullptr;
assert((vp == ptr_static_cast<void *>(vp)));
assert((vp == ptr_static_cast<void *>(bp)));
assert((vp == ptr_static_cast<void *>(ip)));
assert((vp == ptr_static_cast<void *>(dp)));
assert((bp == ptr_static_cast<byte *>(vp)));
assert((bp == ptr_static_cast<byte *>(bp)));
assert((bp == ptr_static_cast<byte *>(ip)));
assert((bp == ptr_static_cast<byte *>(dp)));
assert((ip == ptr_static_cast<int *>(vp)));
assert((ip == ptr_static_cast<int *>(bp)));
assert((ip == ptr_static_cast<int *>(ip)));
assert((ip == ptr_static_cast<int *>(dp)));
assert((dp == ptr_static_cast<double *>(vp)));
assert((dp == ptr_static_cast<double *>(bp)));
assert((dp == ptr_static_cast<double *>(ip)));
assert((dp == ptr_static_cast<double *>(dp)));
const byte *bc = nullptr;
const int *ic = nullptr;
assert((bc == ptr_static_cast<byte *>(bp)));
assert((bc == ptr_static_cast<const byte *>(bc)));
assert((bc == ptr_static_cast<byte *>(ip)));
assert((bc == ptr_static_cast<const byte *>(ic)));
assert((ic == ptr_static_cast<int *>(bp)));
assert((ic == ptr_static_cast<const int *>(bc)));
assert((ic == ptr_static_cast<int *>(ip)));
assert((ic == ptr_static_cast<const int *>(ic)));
}
TEST_CASE("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: */
+4 -2
View File
@@ -2,7 +2,7 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer Copyright (C) 1996-2024 Markus Franz Xaver Johannes Oberhumer
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
@@ -43,9 +43,11 @@
#pragma GCC diagnostic ignored "-Wshadow" #pragma GCC diagnostic ignored "-Wshadow"
#endif #endif
#if !defined(UPX_DOCTEST_CONFIG_MULTITHREADING) #if !defined(UPX_DOCTEST_CONFIG_MULTITHREADING) && !(WITH_THREADS)
#ifndef DOCTEST_CONFIG_NO_MULTITHREADING
#define DOCTEST_CONFIG_NO_MULTITHREADING #define DOCTEST_CONFIG_NO_MULTITHREADING
#endif #endif
#endif
#if defined(__clang__) && defined(__FAST_MATH__) && defined(__INTEL_LLVM_COMPILER) #if defined(__clang__) && defined(__FAST_MATH__) && defined(__INTEL_LLVM_COMPILER)
// warning: comparison with NaN always evaluates to false in fast floating point modes // warning: comparison with NaN always evaluates to false in fast floating point modes
+135 -3
View File
@@ -2,7 +2,7 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer Copyright (C) 1996-2024 Markus Franz Xaver Johannes Oberhumer
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
@@ -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: */
+23 -5
View File
@@ -2,7 +2,7 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer Copyright (C) 1996-2024 Markus Franz Xaver Johannes Oberhumer
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
@@ -62,7 +62,7 @@ unsigned upx_crc32(const void *buf, unsigned len, unsigned crc)
**************************************************************************/ **************************************************************************/
int upx_compress(const upx_bytep src, unsigned src_len, upx_bytep dst, unsigned *dst_len, int upx_compress(const upx_bytep src, unsigned src_len, upx_bytep dst, unsigned *dst_len,
upx_callback_p cb, int method, int level, const upx_compress_config_t *cconf, upx_callback_t *cb, int method, int level, const upx_compress_config_t *cconf,
upx_compress_result_t *cresult) { upx_compress_result_t *cresult) {
int r = UPX_E_ERROR; int r = UPX_E_ERROR;
upx_compress_result_t cresult_buffer; upx_compress_result_t cresult_buffer;
@@ -92,8 +92,13 @@ 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_BZIP2)
else if (M_IS_BZIP2(method))
r = upx_bzip2_compress(src, src_len, dst, dst_len, cb, method, level, cconf, cresult);
#endif
#if (WITH_LZMA) #if (WITH_LZMA)
else if (M_IS_LZMA(method)) else if (M_IS_LZMA(method))
r = upx_lzma_compress(src, src_len, dst, dst_len, cb, method, level, cconf, cresult); r = upx_lzma_compress(src, src_len, dst, dst_len, cb, method, level, cconf, cresult);
@@ -111,13 +116,14 @@ int upx_compress(const upx_bytep src, unsigned src_len, upx_bytep dst, unsigned
r = upx_zstd_compress(src, src_len, dst, dst_len, cb, method, level, cconf, cresult); r = upx_zstd_compress(src, src_len, dst, dst_len, cb, method, level, cconf, cresult);
#endif #endif
else { else {
throwInternalError("unknown compression method"); throwInternalError("unknown compression method %d", method);
} }
#if 1 #if 1
// 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,8 +141,13 @@ 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_BZIP2)
else if (M_IS_BZIP2(method))
r = upx_bzip2_decompress(src, src_len, dst, dst_len, method, cresult);
#endif
#if (WITH_LZMA) #if (WITH_LZMA)
else if (M_IS_LZMA(method)) else if (M_IS_LZMA(method))
r = upx_lzma_decompress(src, src_len, dst, dst_len, method, cresult); r = upx_lzma_decompress(src, src_len, dst, dst_len, method, cresult);
@@ -158,9 +169,10 @@ int upx_decompress(const upx_bytep src, unsigned src_len, upx_bytep dst, unsigne
r = upx_zstd_decompress(src, src_len, dst, dst_len, method, cresult); r = upx_zstd_decompress(src, src_len, dst, dst_len, method, cresult);
#endif #endif
else { else {
throwInternalError("unknown decompression method"); throwInternalError("unknown compression method %d", method);
} }
assert_noexcept(*dst_len <= orig_dst_len);
return r; return r;
} }
@@ -180,8 +192,13 @@ 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_BZIP2)
else if (M_IS_BZIP2(method))
r = upx_bzip2_test_overlap(buf, tbuf, src_off, src_len, dst_len, method, cresult);
#endif
#if (WITH_LZMA) #if (WITH_LZMA)
else if (M_IS_LZMA(method)) else if (M_IS_LZMA(method))
r = upx_lzma_test_overlap(buf, tbuf, src_off, src_len, dst_len, method, cresult); r = upx_lzma_test_overlap(buf, tbuf, src_off, src_len, dst_len, method, cresult);
@@ -199,9 +216,10 @@ int upx_test_overlap(const upx_bytep buf, const upx_bytep tbuf, unsigned src_off
r = upx_zstd_test_overlap(buf, tbuf, src_off, src_len, dst_len, method, cresult); r = upx_zstd_test_overlap(buf, tbuf, src_off, src_len, dst_len, method, cresult);
#endif #endif
else { else {
throwInternalError("unknown decompression method"); throwInternalError("unknown compression method %d", method);
} }
assert_noexcept(*dst_len <= orig_dst_len);
return r; return r;
} }
+9 -17
View File
@@ -2,7 +2,7 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer Copyright (C) 1996-2024 Markus Franz Xaver Johannes Oberhumer
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
@@ -25,8 +25,8 @@
*/ */
#pragma once #pragma once
#ifndef UPX_COMPRESS_H__
#define UPX_COMPRESS_H__ 1 // clang-format off
/************************************************************************* /*************************************************************************
// //
@@ -37,7 +37,7 @@ int upx_bzip2_init(void);
const char *upx_bzip2_version_string(void); const char *upx_bzip2_version_string(void);
int upx_bzip2_compress ( const upx_bytep src, unsigned src_len, int upx_bzip2_compress ( const upx_bytep src, unsigned src_len,
upx_bytep dst, unsigned *dst_len, upx_bytep dst, unsigned *dst_len,
upx_callback_p cb, upx_callback_t *cb,
int method, int level, int method, int level,
const upx_compress_config_t *cconf, const upx_compress_config_t *cconf,
upx_compress_result_t *cresult ); upx_compress_result_t *cresult );
@@ -53,13 +53,12 @@ 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);
int upx_lzma_compress ( const upx_bytep src, unsigned src_len, int upx_lzma_compress ( const upx_bytep src, unsigned src_len,
upx_bytep dst, unsigned *dst_len, upx_bytep dst, unsigned *dst_len,
upx_callback_p cb, upx_callback_t *cb,
int method, int level, int method, int level,
const upx_compress_config_t *cconf, const upx_compress_config_t *cconf,
upx_compress_result_t *cresult ); upx_compress_result_t *cresult );
@@ -75,13 +74,12 @@ 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);
int upx_nrv_compress ( const upx_bytep src, unsigned src_len, int upx_nrv_compress ( const upx_bytep src, unsigned src_len,
upx_bytep dst, unsigned *dst_len, upx_bytep dst, unsigned *dst_len,
upx_callback_p cb, upx_callback_t *cb,
int method, int level, int method, int level,
const upx_compress_config_t *cconf, const upx_compress_config_t *cconf,
upx_compress_result_t *cresult ); upx_compress_result_t *cresult );
@@ -97,13 +95,12 @@ 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);
int upx_ucl_compress ( const upx_bytep src, unsigned src_len, int upx_ucl_compress ( const upx_bytep src, unsigned src_len,
upx_bytep dst, unsigned *dst_len, upx_bytep dst, unsigned *dst_len,
upx_callback_p cb, upx_callback_t *cb,
int method, int level, int method, int level,
const upx_compress_config_t *cconf, const upx_compress_config_t *cconf,
upx_compress_result_t *cresult ); upx_compress_result_t *cresult );
@@ -121,13 +118,12 @@ 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);
int upx_zlib_compress ( const upx_bytep src, unsigned src_len, int upx_zlib_compress ( const upx_bytep src, unsigned src_len,
upx_bytep dst, unsigned *dst_len, upx_bytep dst, unsigned *dst_len,
upx_callback_p cb, upx_callback_t *cb,
int method, int level, int method, int level,
const upx_compress_config_t *cconf, const upx_compress_config_t *cconf,
upx_compress_result_t *cresult ); upx_compress_result_t *cresult );
@@ -145,13 +141,12 @@ 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);
int upx_zstd_compress ( const upx_bytep src, unsigned src_len, int upx_zstd_compress ( const upx_bytep src, unsigned src_len,
upx_bytep dst, unsigned *dst_len, upx_bytep dst, unsigned *dst_len,
upx_callback_p cb, upx_callback_t *cb,
int method, int level, int method, int level,
const upx_compress_config_t *cconf, const upx_compress_config_t *cconf,
upx_compress_result_t *cresult ); upx_compress_result_t *cresult );
@@ -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: */
+208
View File
@@ -0,0 +1,208 @@
/* compress_bzip2.cpp --
This file is part of the UPX executable compressor.
Copyright (C) 1996-2024 Markus Franz Xaver Johannes Oberhumer
All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them
and/or modify them under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of
the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; see the file COPYING.
If not, write to the Free Software Foundation, Inc.,
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
Markus F.X.J. Oberhumer
<markus@oberhumer.com>
*/
#include "../conf.h"
void bzip2_compress_config_t::reset() noexcept { mem_clear(this); }
#if WITH_BZIP2
#include "compress.h"
#include "../util/membuffer.h"
#include <bzip2/bzlib.h>
#if defined(BZ_NO_STDIO) || 1
// we need to supply bz_internal_error() when building with BZ_NO_STDIO
extern "C" {
extern void bz_internal_error(int);
void bz_internal_error(int errcode) { throwInternalError("bz_internal_error %d", errcode); }
}
#endif // BZ_NO_STDIO
static int convert_errno_from_bzip2(int r) {
switch (r) {
case BZ_OK:
return UPX_E_OK;
case BZ_MEM_ERROR:
return UPX_E_OUT_OF_MEMORY;
// TODO later: convert to UPX_E_INPUT_OVERRUN, UPX_E_OUTPUT_OVERRUN
default:
break;
}
return UPX_E_ERROR;
}
/*************************************************************************
//
**************************************************************************/
int upx_bzip2_compress(const upx_bytep src, unsigned src_len, upx_bytep dst, unsigned *dst_len,
upx_callback_t *cb_parm, int method, int level,
const upx_compress_config_t *cconf_parm, upx_compress_result_t *cresult) {
assert(method == M_BZIP2);
assert(level > 0);
assert(cresult != nullptr);
UNUSED(cb_parm);
int r = UPX_E_ERROR;
const bzip2_compress_config_t *const lcconf = cconf_parm ? &cconf_parm->conf_bzip2 : nullptr;
bzip2_compress_result_t *const res = &cresult->result_bzip2;
res->reset();
int blockSize100k = (src_len + 100000 - 1) / 100000;
if (blockSize100k < 1)
blockSize100k = 1;
if (blockSize100k > 9)
blockSize100k = 9;
// idea for later: could enhance lcconf to allow setting blockSize100k
UNUSED(lcconf);
if (level <= 3 && blockSize100k > level)
blockSize100k = level;
char *dest = (char *) dst;
char *source = (char *) const_cast<byte *>(src);
r = BZ2_bzBuffToBuffCompress(dest, dst_len, source, src_len, blockSize100k, 0, 0);
return convert_errno_from_bzip2(r);
}
/*************************************************************************
//
**************************************************************************/
int upx_bzip2_decompress(const upx_bytep src, unsigned src_len, upx_bytep dst, unsigned *dst_len,
int method, const upx_compress_result_t *cresult) {
assert(method == M_BZIP2);
UNUSED(method);
UNUSED(cresult);
char *dest = (char *) dst;
char *source = (char *) const_cast<byte *>(src);
int small = 0;
int r = BZ2_bzBuffToBuffDecompress(dest, dst_len, source, src_len, small, 0);
return convert_errno_from_bzip2(r);
}
/*************************************************************************
// test_overlap - see <ucl/ucl.h> for semantics
**************************************************************************/
int upx_bzip2_test_overlap(const upx_bytep buf, const upx_bytep tbuf, unsigned src_off,
unsigned src_len, unsigned *dst_len, int method,
const upx_compress_result_t *cresult) {
assert(method == M_BZIP2);
MemBuffer b(src_off + src_len);
memcpy(b + src_off, buf + src_off, src_len);
unsigned saved_dst_len = *dst_len;
int r = upx_bzip2_decompress(raw_index_bytes(b, src_off, src_len), src_len,
raw_bytes(b, *dst_len), dst_len, method, cresult);
if (r != UPX_E_OK)
return r;
if (*dst_len != saved_dst_len)
return UPX_E_ERROR;
// NOTE: there is a very tiny possibility that decompression has
// succeeded but the data is not restored correctly because of
// in-place buffer overlapping, so we use an extra memcmp().
if (tbuf != nullptr && memcmp(tbuf, b, *dst_len) != 0)
return UPX_E_ERROR;
return UPX_E_OK;
}
/*************************************************************************
// misc
**************************************************************************/
int upx_bzip2_init(void) { return 0; }
const char *upx_bzip2_version_string(void) { return BZ2_bzlibVersion(); }
/*************************************************************************
// doctest checks
**************************************************************************/
#if DEBUG && !defined(DOCTEST_CONFIG_DISABLE) && 1
static bool check_bzip2(const int method, const int level, const unsigned expected_c_len) {
const unsigned u_len = 16384;
const unsigned c_extra = 4096;
MemBuffer u_buf, c_buf, d_buf;
unsigned c_len, d_len;
upx_compress_result_t cresult;
int r;
u_buf.alloc(u_len);
memset(u_buf, 0, u_len);
c_buf.allocForCompression(u_len, c_extra);
d_buf.allocForDecompression(u_len);
c_len = c_buf.getSize() - c_extra;
r = upx_bzip2_compress(raw_bytes(u_buf, u_len), u_len, raw_index_bytes(c_buf, c_extra, c_len),
&c_len, nullptr, method, level, NULL_cconf, &cresult);
if (r != 0 || c_len != expected_c_len)
return false;
d_len = d_buf.getSize();
r = upx_bzip2_decompress(raw_index_bytes(c_buf, c_extra, c_len), c_len, raw_bytes(d_buf, d_len),
&d_len, method, nullptr);
if (r != 0 || d_len != u_len || memcmp(u_buf, d_buf, u_len) != 0)
return false;
d_len = u_len - 1;
r = upx_bzip2_decompress(raw_index_bytes(c_buf, c_extra, c_len), c_len, raw_bytes(d_buf, d_len),
&d_len, method, nullptr);
if (r == 0)
return false;
// TODO: rewrite Packer::findOverlapOverhead() so that we can test it here
// unsigned x_len = d_len;
// r = upx_bzip2_test_overlap(c_buf, u_buf, c_extra, c_len, &x_len, method, nullptr);
return true;
}
TEST_CASE("compress_bzip2") { CHECK(check_bzip2(M_BZIP2, 9, 46)); }
#endif // DEBUG
TEST_CASE("upx_bzip2_decompress") {
#if 0 // TODO later, see above
const byte *c_data;
byte d_buf[32];
unsigned d_len;
int r;
c_data = (const byte *) "\x28\xb5\x2f\xfd\x20\x20\x3d\x00\x00\x08\xff\x01\x00\x34\x4e\x08";
d_len = 32;
r = upx_bzip2_decompress(c_data, 16, d_buf, &d_len, M_BZIP2, nullptr);
CHECK((r == 0 && d_len == 32));
r = upx_bzip2_decompress(c_data, 15, d_buf, &d_len, M_BZIP2, nullptr);
CHECK(r == UPX_E_INPUT_OVERRUN);
d_len = 31;
r = upx_bzip2_decompress(c_data, 16, d_buf, &d_len, M_BZIP2, nullptr);
CHECK(r == UPX_E_OUTPUT_OVERRUN);
UNUSED(r);
#endif // TODO
}
#endif // WITH_BZIP2
/* vim:set ts=4 sw=4 et: */
+5 -3
View File
@@ -2,7 +2,7 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer Copyright (C) 1996-2024 Markus Franz Xaver Johannes Oberhumer
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
@@ -293,7 +293,7 @@ struct ProgressInfo final : public ICompressProgressInfo, public CMyUnknownImp {
virtual ~ProgressInfo() {} virtual ~ProgressInfo() {}
MY_UNKNOWN_IMP MY_UNKNOWN_IMP
STDMETHOD(SetRatioInfo)(const UInt64 *inSize, const UInt64 *outSize) override; STDMETHOD(SetRatioInfo)(const UInt64 *inSize, const UInt64 *outSize) override;
upx_callback_p cb = nullptr; upx_callback_t *cb = nullptr;
}; };
STDMETHODIMP ProgressInfo::SetRatioInfo(const UInt64 *inSize, const UInt64 *outSize) { STDMETHODIMP ProgressInfo::SetRatioInfo(const UInt64 *inSize, const UInt64 *outSize) {
@@ -317,7 +317,7 @@ STDMETHODIMP ProgressInfo::SetRatioInfo(const UInt64 *inSize, const UInt64 *outS
#undef RC_NORMALIZE #undef RC_NORMALIZE
int upx_lzma_compress(const upx_bytep src, unsigned src_len, upx_bytep dst, unsigned *dst_len, int upx_lzma_compress(const upx_bytep src, unsigned src_len, upx_bytep dst, unsigned *dst_len,
upx_callback_p cb, int method, int level, upx_callback_t *cb, int method, int level,
const upx_compress_config_t *cconf_parm, upx_compress_result_t *cresult) { const upx_compress_config_t *cconf_parm, upx_compress_result_t *cresult) {
assert(M_IS_LZMA(method)); assert(M_IS_LZMA(method));
assert(level > 0); assert(level > 0);
@@ -327,6 +327,7 @@ int upx_lzma_compress(const upx_bytep src, unsigned src_len, upx_bytep dst, unsi
HRESULT rh; HRESULT rh;
const lzma_compress_config_t *const lcconf = cconf_parm ? &cconf_parm->conf_lzma : nullptr; const lzma_compress_config_t *const lcconf = cconf_parm ? &cconf_parm->conf_lzma : nullptr;
lzma_compress_result_t *const res = &cresult->result_lzma; lzma_compress_result_t *const res = &cresult->result_lzma;
res->reset();
MyLzma::InStream is; MyLzma::InStream is;
is.AddRef(); is.AddRef();
@@ -547,6 +548,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: */
+4 -3
View File
@@ -2,7 +2,7 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer Copyright (C) 1996-2024 Markus Franz Xaver Johannes Oberhumer
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
@@ -66,7 +66,7 @@ extern "C" {
static void __UCL_CDECL wrap_nprogress_ucl(ucl_uint a, ucl_uint b, int state, ucl_voidp user) { static void __UCL_CDECL wrap_nprogress_ucl(ucl_uint a, ucl_uint b, int state, ucl_voidp user) {
if (state != -1 && state != 3) if (state != -1 && state != 3)
return; return;
upx_callback_p cb = (upx_callback_p) user; upx_callback_t *cb = (upx_callback_t *) user;
if (cb && cb->nprogress) if (cb && cb->nprogress)
cb->nprogress(cb, a, b); cb->nprogress(cb, a, b);
} }
@@ -77,7 +77,7 @@ static void __UCL_CDECL wrap_nprogress_ucl(ucl_uint a, ucl_uint b, int state, uc
**************************************************************************/ **************************************************************************/
int upx_ucl_compress(const upx_bytep src, unsigned src_len, upx_bytep dst, unsigned *dst_len, int upx_ucl_compress(const upx_bytep src, unsigned src_len, upx_bytep dst, unsigned *dst_len,
upx_callback_p cb_parm, int method, int level, upx_callback_t *cb_parm, int method, int level,
const upx_compress_config_t *cconf_parm, upx_compress_result_t *cresult) { const upx_compress_config_t *cconf_parm, upx_compress_result_t *cresult) {
int r; int r;
assert(level > 0); assert(level > 0);
@@ -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: */
+4 -4
View File
@@ -2,7 +2,7 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer Copyright (C) 1996-2024 Markus Franz Xaver Johannes Oberhumer
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
@@ -75,7 +75,7 @@ static int convert_errno_from_zlib(int zr) {
**************************************************************************/ **************************************************************************/
int upx_zlib_compress(const upx_bytep src, unsigned src_len, upx_bytep dst, unsigned *dst_len, int upx_zlib_compress(const upx_bytep src, unsigned src_len, upx_bytep dst, unsigned *dst_len,
upx_callback_p cb_parm, int method, int level, upx_callback_t *cb_parm, int method, int level,
const upx_compress_config_t *cconf_parm, upx_compress_result_t *cresult) { const upx_compress_config_t *cconf_parm, upx_compress_result_t *cresult) {
assert(method == M_DEFLATE); assert(method == M_DEFLATE);
assert(level > 0); assert(level > 0);
@@ -85,6 +85,7 @@ int upx_zlib_compress(const upx_bytep src, unsigned src_len, upx_bytep dst, unsi
int zr; int zr;
const zlib_compress_config_t *const lcconf = cconf_parm ? &cconf_parm->conf_zlib : nullptr; const zlib_compress_config_t *const lcconf = cconf_parm ? &cconf_parm->conf_zlib : nullptr;
zlib_compress_result_t *const res = &cresult->result_zlib; zlib_compress_result_t *const res = &cresult->result_zlib;
res->reset();
if (level == 10) if (level == 10)
level = 9; level = 9;
@@ -99,8 +100,6 @@ int upx_zlib_compress(const upx_bytep src, unsigned src_len, upx_bytep dst, unsi
oassign(strategy, lcconf->strategy); oassign(strategy, lcconf->strategy);
} }
res->dummy = 0;
z_stream s; z_stream s;
s.zalloc = (alloc_func) nullptr; s.zalloc = (alloc_func) nullptr;
s.zfree = (free_func) nullptr; s.zfree = (free_func) nullptr;
@@ -305,6 +304,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: */
+4 -4
View File
@@ -2,7 +2,7 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer Copyright (C) 1996-2024 Markus Franz Xaver Johannes Oberhumer
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
@@ -55,7 +55,7 @@ static int convert_errno_from_zstd(size_t zr) {
**************************************************************************/ **************************************************************************/
int upx_zstd_compress(const upx_bytep src, unsigned src_len, upx_bytep dst, unsigned *dst_len, int upx_zstd_compress(const upx_bytep src, unsigned src_len, upx_bytep dst, unsigned *dst_len,
upx_callback_p cb_parm, int method, int level, upx_callback_t *cb_parm, int method, int level,
const upx_compress_config_t *cconf_parm, upx_compress_result_t *cresult) { const upx_compress_config_t *cconf_parm, upx_compress_result_t *cresult) {
assert(method == M_ZSTD); assert(method == M_ZSTD);
assert(level > 0); assert(level > 0);
@@ -65,6 +65,7 @@ int upx_zstd_compress(const upx_bytep src, unsigned src_len, upx_bytep dst, unsi
size_t zr; size_t zr;
const zstd_compress_config_t *const lcconf = cconf_parm ? &cconf_parm->conf_zstd : nullptr; const zstd_compress_config_t *const lcconf = cconf_parm ? &cconf_parm->conf_zstd : nullptr;
zstd_compress_result_t *const res = &cresult->result_zstd; zstd_compress_result_t *const res = &cresult->result_zstd;
res->reset();
// TODO later: map level 1..10 to zstd-level 1..22 // TODO later: map level 1..10 to zstd-level 1..22
if (level == 10) if (level == 10)
@@ -75,8 +76,6 @@ int upx_zstd_compress(const upx_bytep src, unsigned src_len, upx_bytep dst, unsi
UNUSED(lcconf); UNUSED(lcconf);
} }
res->dummy = 0;
zr = ZSTD_compress(dst, *dst_len, src, src_len, level); zr = ZSTD_compress(dst, *dst_len, src, src_len, level);
if (ZSTD_isError(zr)) { if (ZSTD_isError(zr)) {
*dst_len = 0; // TODO ??? *dst_len = 0; // TODO ???
@@ -221,6 +220,7 @@ TEST_CASE("upx_zstd_decompress") {
d_len = 31; d_len = 31;
r = upx_zstd_decompress(c_data, 16, d_buf, &d_len, M_ZSTD, nullptr); r = upx_zstd_decompress(c_data, 16, d_buf, &d_len, M_ZSTD, nullptr);
CHECK(r == UPX_E_OUTPUT_OVERRUN); CHECK(r == UPX_E_OUTPUT_OVERRUN);
UNUSED(r);
} }
#endif // WITH_ZSTD #endif // WITH_ZSTD
+145 -171
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer Copyright (C) 1996-2024 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2023 Laszlo Molnar Copyright (C) 1996-2024 Laszlo Molnar
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
@@ -34,6 +34,19 @@
#include "headers.h" #include "headers.h"
#include "version.h" #include "version.h"
#if !defined(__has_attribute)
#define __has_attribute(x) 0
#endif
#if !defined(__has_builtin)
#define __has_builtin(x) 0
#endif
#if !defined(__has_feature)
#define __has_feature(x) 0
#endif
// reserve name "upx" for namespace
namespace upx {}
ACC_COMPILE_TIME_ASSERT_HEADER(CHAR_BIT == 8) ACC_COMPILE_TIME_ASSERT_HEADER(CHAR_BIT == 8)
ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(short) == 2) ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(short) == 2)
ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(int) == 4) ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(int) == 4)
@@ -45,7 +58,7 @@ ACC_COMPILE_TIME_ASSERT_HEADER((1u << 31) << 1 == 0)
ACC_COMPILE_TIME_ASSERT_HEADER(((int) (1u << 31)) >> 31 == -1) // arithmetic right shift ACC_COMPILE_TIME_ASSERT_HEADER(((int) (1u << 31)) >> 31 == -1) // arithmetic right shift
ACC_COMPILE_TIME_ASSERT_HEADER((-1) >> 31 == -1) // arithmetic right shift ACC_COMPILE_TIME_ASSERT_HEADER((-1) >> 31 == -1) // arithmetic right shift
ACC_COMPILE_TIME_ASSERT_HEADER(CHAR_MAX == 255) // -funsigned-char ACC_COMPILE_TIME_ASSERT_HEADER(CHAR_MAX == 255) // -funsigned-char
ACC_COMPILE_TIME_ASSERT_HEADER((char)(-1) == 255) // -funsigned-char ACC_COMPILE_TIME_ASSERT_HEADER((char) (-1) == 255)
// enable some more strict warnings for Git developer builds // enable some more strict warnings for Git developer builds
#if defined(UPX_CONFIG_DISABLE_WSTRICT) && (UPX_CONFIG_DISABLE_WSTRICT + 0 == 0) #if defined(UPX_CONFIG_DISABLE_WSTRICT) && (UPX_CONFIG_DISABLE_WSTRICT + 0 == 0)
@@ -81,40 +94,31 @@ ACC_COMPILE_TIME_ASSERT_HEADER((char)(-1) == 255) // -funsigned-char
#define upx_std_once_flag upx_std_atomic(size_t) #define upx_std_once_flag upx_std_atomic(size_t)
template <class NoexceptCallable> template <class NoexceptCallable>
inline void upx_std_call_once(upx_std_once_flag &flag, NoexceptCallable &&f) { inline void upx_std_call_once(upx_std_once_flag &flag, NoexceptCallable &&f) {
if (__acc_unlikely(!flag)) { flag = 1; f(); } if (__acc_unlikely(!flag)) {
flag = 1;
f();
}
} }
#endif // WITH_THREADS #endif // WITH_THREADS
// <type_traits> upx_std_is_bounded_array: same as C++20 std::is_bounded_array
template <class T>
struct upx_std_is_bounded_array : public std::false_type {};
template <class T, size_t N>
struct upx_std_is_bounded_array<T[N]> : public std::true_type {};
template <class T>
inline constexpr bool upx_std_is_bounded_array_v = upx_std_is_bounded_array<T>::value;
// <type_traits> upx_is_integral is overloaded for BE16 & friends; see bele.h // <type_traits> upx_is_integral is overloaded for BE16 & friends; see bele.h
template <class T> template <class T>
struct upx_is_integral : public std::is_integral<T> {}; struct upx_is_integral : public std::is_integral<T> {};
template <class T> template <class T>
inline constexpr bool upx_is_integral_v = upx_is_integral<T>::value; inline constexpr bool upx_is_integral_v = upx_is_integral<T>::value;
// <type_traits> util: is_same_all and is_same_any means std::is_same for multiple types
template <class T, class... Ts>
struct is_same_all : public std::conjunction<std::is_same<T, Ts>...> {};
template <class T, class... Ts>
inline constexpr bool is_same_all_v = is_same_all<T, Ts...>::value;
template <class T, class... Ts>
struct is_same_any : public std::disjunction<std::is_same<T, Ts>...> {};
template <class T, class... Ts>
inline constexpr bool is_same_any_v = is_same_any<T, Ts...>::value;
#if (ACC_ARCH_M68K && ACC_OS_TOS && ACC_CC_GNUC) && defined(__MINT__) #if (ACC_ARCH_M68K && ACC_OS_TOS && ACC_CC_GNUC) && defined(__MINT__)
// horrible hack for broken compiler // horrible hack for broken compiler / ABI
#define upx_fake_alignas_1 __attribute__((__aligned__(1), __packed__)) #define upx_fake_alignas_1 __attribute__((__aligned__(1), __packed__))
#define upx_fake_alignas_2 __attribute__((__aligned__(2)))
#define upx_fake_alignas_4 __attribute__((__aligned__(2))) // object file maximum 2 ???
#define upx_fake_alignas_16 __attribute__((__aligned__(2))) // object file maximum 2 ??? #define upx_fake_alignas_16 __attribute__((__aligned__(2))) // object file maximum 2 ???
#define upx_fake_alignas__(x) upx_fake_alignas_##x #define upx_fake_alignas__(x) upx_fake_alignas_##x
#define alignas(x) upx_fake_alignas__(x) #define alignas(x) upx_fake_alignas__(x)
#define upx_alignas_max upx_fake_alignas_4
#endif
#ifndef upx_alignas_max
#define upx_alignas_max alignas(std::max_align_t)
#endif #endif
/************************************************************************* /*************************************************************************
@@ -123,6 +127,8 @@ inline constexpr bool is_same_any_v = is_same_any<T, Ts...>::value;
// protect against integer overflows and malicious header fields // protect against integer overflows and malicious header fields
// see C 11 standard, Annex K // see C 11 standard, Annex K
//
// this limits uncompressed_size to about 682 MiB (715_128_832 bytes)
typedef size_t upx_rsize_t; typedef size_t upx_rsize_t;
#define UPX_RSIZE_MAX UPX_RSIZE_MAX_MEM #define UPX_RSIZE_MAX UPX_RSIZE_MAX_MEM
#define UPX_RSIZE_MAX_MEM (768 * 1024 * 1024) // DO NOT CHANGE !!! #define UPX_RSIZE_MAX_MEM (768 * 1024 * 1024) // DO NOT CHANGE !!!
@@ -148,7 +154,7 @@ typedef unsigned char uchar;
// convention: use "charptr" when dealing with abstract pointer arithmetics // convention: use "charptr" when dealing with abstract pointer arithmetics
#define charptr upx_charptr_unit_type * #define charptr upx_charptr_unit_type *
// upx_charptr_unit_type is some opaque type with sizeof(type) == 1 // upx_charptr_unit_type is some opaque type with sizeof(type) == 1
struct alignas(1) upx_charptr_unit_type { char hidden__; }; struct alignas(1) upx_charptr_unit_type final { char hidden__; };
ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(upx_charptr_unit_type) == 1) ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(upx_charptr_unit_type) == 1)
// using the system off_t was a bad idea even back in 199x... // using the system off_t was a bad idea even back in 199x...
@@ -170,6 +176,7 @@ typedef upx_int64_t upx_off_t;
#else #else
#define noinline __acc_noinline #define noinline __acc_noinline
#endif #endif
#define forceinline_constexpr forceinline constexpr
#define likely __acc_likely #define likely __acc_likely
#define unlikely __acc_unlikely #define unlikely __acc_unlikely
#define very_likely __acc_very_likely #define very_likely __acc_very_likely
@@ -180,27 +187,32 @@ typedef upx_int64_t upx_off_t;
#define DELETED_FUNCTION = delete #define DELETED_FUNCTION = delete
#define UNUSED(var) ACC_UNUSED(var) #define UNUSED(var) ACC_UNUSED(var)
/************************************************************************* /*************************************************************************
// portab // portab
**************************************************************************/ **************************************************************************/
// just in case // some platform system headers may pre-define these, so undef to avoid conflicts
#undef _ #undef _
#undef __ #undef __
#undef ___ #undef ___
#undef dos #undef dos
#undef large
#undef linux #undef linux
#undef small #undef small
#undef SP
#undef SS
#undef tos #undef tos
#undef unix #undef unix
#if defined(__linux__) && !defined(__unix__) #if (ACC_OS_POSIX) && !defined(__unix__)
#define __unix__ 1 #define __unix__ 1
#endif #endif
#if (ACC_OS_CYGWIN || ACC_OS_DOS16 || ACC_OS_DOS32 || ACC_OS_EMX || ACC_OS_OS2 || ACC_OS_OS216 || \
ACC_OS_WIN16 || ACC_OS_WIN32 || ACC_OS_WIN64)
#undef __unix
#undef __unix__
#endif
#if (ACC_OS_DOS32) && defined(__DJGPP__) #if (ACC_OS_DOS32) && defined(__DJGPP__)
#undef sopen #undef sopen
# undef __unix
# undef __unix__
#endif #endif
#if defined(HAVE_DUP) && (HAVE_DUP + 0 == 0) #if defined(HAVE_DUP) && (HAVE_DUP + 0 == 0)
@@ -278,7 +290,8 @@ typedef upx_int64_t upx_off_t;
#undef PAGE_SIZE #undef PAGE_SIZE
#if !defined(O_BINARY) || (O_BINARY + 0 == 0) #if !defined(O_BINARY) || (O_BINARY + 0 == 0)
# if (ACC_OS_CYGWIN || ACC_OS_DOS16 || ACC_OS_DOS32 || ACC_OS_EMX || ACC_OS_OS2 || ACC_OS_OS216 || ACC_OS_WIN16 || ACC_OS_WIN32 || ACC_OS_WIN64) #if (ACC_OS_CYGWIN || ACC_OS_DOS16 || ACC_OS_DOS32 || ACC_OS_EMX || ACC_OS_OS2 || ACC_OS_OS216 || \
ACC_OS_WIN16 || ACC_OS_WIN32 || ACC_OS_WIN64)
#error "missing O_BINARY" #error "missing O_BINARY"
#endif #endif
#endif #endif
@@ -286,7 +299,6 @@ typedef upx_int64_t upx_off_t;
#define O_BINARY 0 #define O_BINARY 0
#endif #endif
/************************************************************************* /*************************************************************************
// util // util
**************************************************************************/ **************************************************************************/
@@ -310,6 +322,7 @@ typedef upx_int64_t upx_off_t;
#define VALGRIND_MAKE_MEM_UNDEFINED(addr, len) 0 #define VALGRIND_MAKE_MEM_UNDEFINED(addr, len) 0
#endif #endif
// TODO later: check __MINGW_PRINTF_FORMAT
#if defined(_WIN32) && defined(__MINGW32__) && defined(__GNUC__) && !defined(__clang__) #if defined(_WIN32) && defined(__MINGW32__) && defined(__GNUC__) && !defined(__clang__)
#define attribute_format(a, b) __attribute__((__format__(__gnu_printf__, a, b))) #define attribute_format(a, b) __attribute__((__format__(__gnu_printf__, a, b)))
#elif (ACC_CC_CLANG || ACC_CC_GNUC) #elif (ACC_CC_CLANG || ACC_CC_GNUC)
@@ -324,10 +337,6 @@ inline void NO_fprintf(FILE *, const char *, ...) noexcept attribute_format(2, 3
inline void NO_printf(const char *, ...) noexcept {} inline void NO_printf(const char *, ...) noexcept {}
inline void NO_fprintf(FILE *, const char *, ...) noexcept {} inline void NO_fprintf(FILE *, const char *, ...) noexcept {}
#if !defined(__has_builtin)
# define __has_builtin(x) 0
#endif
#if __has_builtin(__builtin_memcpy_inline) #if __has_builtin(__builtin_memcpy_inline)
#define upx_memcpy_inline __builtin_memcpy_inline #define upx_memcpy_inline __builtin_memcpy_inline
#elif __has_builtin(__builtin_memcpy) #elif __has_builtin(__builtin_memcpy)
@@ -348,15 +357,23 @@ inline void NO_fprintf(FILE *, const char *, ...) noexcept {}
#define upx_return_address() nullptr #define upx_return_address() nullptr
#endif #endif
// TODO cleanup: we now require C++17, so remove all __packed_struct usage // TODO cleanup: we now require C++17, so remove all packed_struct usage
#define __packed_struct(s) struct alignas(1) s { #define packed_struct(s) struct alignas(1) s
#define __packed_struct_end() };
#define COMPILE_TIME_ASSERT_ALIGNOF_USING_SIZEOF__(a,b) { \ #define COMPILE_TIME_ASSERT_ALIGNOF_USING_SIZEOF__(a, b) \
typedef a acc_tmp_a_t; typedef b acc_tmp_b_t; \ { \
struct alignas(1) acc_tmp_t { acc_tmp_b_t x; acc_tmp_a_t y; acc_tmp_b_t z; }; \ typedef a acc_tmp_a_t; \
typedef b acc_tmp_b_t; \
struct alignas(1) acc_tmp_t { \
acc_tmp_b_t x; \
acc_tmp_a_t y; \
acc_tmp_b_t z; \
}; \
COMPILE_TIME_ASSERT(sizeof(struct acc_tmp_t) == 2 * sizeof(b) + sizeof(a)) \ COMPILE_TIME_ASSERT(sizeof(struct acc_tmp_t) == 2 * sizeof(b) + sizeof(a)) \
COMPILE_TIME_ASSERT(sizeof(((acc_tmp_t*)nullptr)->x)+sizeof(((acc_tmp_t*)nullptr)->y)+sizeof(((acc_tmp_t*)nullptr)->z) == 2*sizeof(b)+sizeof(a)) \ COMPILE_TIME_ASSERT(sizeof(((acc_tmp_t *) nullptr)->x) + \
sizeof(((acc_tmp_t *) nullptr)->y) + \
sizeof(((acc_tmp_t *) nullptr)->z) == \
2 * sizeof(b) + sizeof(a)) \
} }
#define COMPILE_TIME_ASSERT_ALIGNOF__(a, b) \ #define COMPILE_TIME_ASSERT_ALIGNOF__(a, b) \
COMPILE_TIME_ASSERT_ALIGNOF_USING_SIZEOF__(a, b) \ COMPILE_TIME_ASSERT_ALIGNOF_USING_SIZEOF__(a, b) \
@@ -366,25 +383,37 @@ inline void NO_fprintf(FILE *, const char *, ...) noexcept {}
#define TABLESIZE(table) ((sizeof(table) / sizeof((table)[0]))) #define TABLESIZE(table) ((sizeof(table) / sizeof((table)[0])))
template <class T>
inline T ALIGN_DOWN(const T &a, const T &b) {
T r;
r = (a / b) * b;
return r;
}
template <class T>
inline T ALIGN_UP(const T &a, const T &b) {
T r;
r = ((a + b - 1) / b) * b;
return r;
}
template <class T>
inline T ALIGN_GAP(const T &a, const T &b) {
T r;
r = ALIGN_UP(a, b) - a;
return r;
}
template <class T> template <class T>
inline T ALIGN_DOWN(const T& a, const T& b) { T r; r = (a / b) * b; return r; } inline const T &UPX_MAX(const T &a, const T &b) {
if (a < b)
return b;
return a;
}
template <class T> template <class T>
inline T ALIGN_UP (const T& a, const T& b) { T r; r = ((a + b - 1) / b) * b; return r; } inline const T &UPX_MIN(const T &a, const T &b) {
template <class T> if (a < b)
inline T ALIGN_GAP (const T& a, const T& b) { T r; r = ALIGN_UP(a, b) - a; return r; } return a;
return b;
template <class T> }
inline const T& UPX_MAX(const T& a, const T& b) { if (a < b) return b; return a; }
template <class T>
inline const T& UPX_MIN(const T& a, const T& b) { if (a < b) return a; return b; }
template <size_t Size>
struct UnsignedSizeOf {
static_assert(Size >= 1 && Size <= UPX_RSIZE_MAX_MEM);
static constexpr unsigned value = unsigned(Size);
};
#define usizeof(expr) (UnsignedSizeOf<sizeof(expr)>::value)
template <class T> template <class T>
inline void mem_clear(T *object) noexcept { inline void mem_clear(T *object) noexcept {
@@ -417,51 +446,25 @@ noinline void throwAssertFailed(const char *expr, const char *file, int line, co
#undef assert #undef assert
#if DEBUG || 0 #if DEBUG || 0
// generate a warning if assert() is used inside a "noexcept" context // generate a warning if assert() is used inside a "noexcept" context
#define assert(e) ((void)(__acc_cte(e) || (assertFailed(#e, __FILE__, __LINE__, __func__), throw 1, 0))) #define assert(e) \
((void) (__acc_cte(e) || (assertFailed(#e, __FILE__, __LINE__, __func__), throw 1, 0)))
#else #else
// turn assertion failures into exceptions // turn assertion failures into exceptions
#define assert(e) ((void)(__acc_cte(e) || (throwAssertFailed(#e, __FILE__, __LINE__, __func__), throw 1, 0))) #define assert(e) \
((void) (__acc_cte(e) || (throwAssertFailed(#e, __FILE__, __LINE__, __func__), throw 1, 0)))
#endif #endif
#define assert_noexcept(e) ((void)(__acc_cte(e) || (assertFailed(#e, __FILE__, __LINE__, __func__), 0))) #define assert_noexcept(e) \
((void) (__acc_cte(e) || (assertFailed(#e, __FILE__, __LINE__, __func__), 0)))
#else #else
#define assert_noexcept assert #define assert_noexcept assert
#endif #endif
class noncopyable { #include "util/cxxlib.h"
protected: using upx::is_same_any_v;
inline noncopyable() noexcept {} using upx::noncopyable;
inline ~noncopyable() noexcept = default; using upx::OptVar;
private: using upx::tribool;
noncopyable(const noncopyable &) noexcept DELETED_FUNCTION; // copy constructor #define usizeof(expr) (upx::UnsignedSizeOf<sizeof(expr)>::value)
noncopyable& operator=(const noncopyable &) noexcept DELETED_FUNCTION; // copy assignment
noncopyable(noncopyable &&) noexcept DELETED_FUNCTION; // move constructor
noncopyable& operator=(noncopyable &&) noexcept DELETED_FUNCTION; // move assignment
};
namespace compile_time {
constexpr size_t string_len(const char *a) {
return *a == '\0' ? 0 : 1 + string_len(a + 1);
}
constexpr bool string_eq(const char *a, const char *b) {
return *a == *b && (*a == '\0' || string_eq(a + 1, b + 1));
}
constexpr bool string_lt(const char *a, const char *b) {
return (uchar)*a < (uchar)*b || (*a != '\0' && *a == *b && string_lt(a + 1, b + 1));
}
constexpr bool string_ne(const char *a, const char *b) {
return !string_eq(a, b);
}
constexpr bool string_gt(const char *a, const char *b) {
return string_lt(b, a);
}
constexpr bool string_le(const char *a, const char *b) {
return !string_lt(b, a);
}
constexpr bool string_ge(const char *a, const char *b) {
return !string_lt(a, b);
}
} // namespace compile_time
/************************************************************************* /*************************************************************************
// constants // constants
@@ -471,7 +474,7 @@ constexpr bool string_ge(const char *a, const char *b) {
#define EXIT_OK 0 #define EXIT_OK 0
#define EXIT_ERROR 1 #define EXIT_ERROR 1
#define EXIT_WARN 2 #define EXIT_WARN 2
//
#define EXIT_USAGE 1 #define EXIT_USAGE 1
#define EXIT_FILE_READ 1 #define EXIT_FILE_READ 1
#define EXIT_FILE_WRITE 1 #define EXIT_FILE_WRITE 1
@@ -480,12 +483,10 @@ constexpr bool string_ge(const char *a, const char *b) {
#define EXIT_INIT 1 #define EXIT_INIT 1
#define EXIT_INTERNAL 1 #define EXIT_INTERNAL 1
// magic constants for patching // magic constants for patching
#define UPX_MAGIC_LE32 0x21585055 /* "UPX!" */ #define UPX_MAGIC_LE32 0x21585055 /* "UPX!" */
#define UPX_MAGIC2_LE32 0xD5D0D8A1 #define UPX_MAGIC2_LE32 0xD5D0D8A1
// upx_compress() error codes // upx_compress() error codes
#define UPX_E_OK (0) #define UPX_E_OK (0)
#define UPX_E_ERROR (-1) #define UPX_E_ERROR (-1)
@@ -499,7 +500,6 @@ constexpr bool string_ge(const char *a, const char *b) {
#define UPX_E_NOT_YET_IMPLEMENTED (-9) #define UPX_E_NOT_YET_IMPLEMENTED (-9)
#define UPX_E_INVALID_ARGUMENT (-10) #define UPX_E_INVALID_ARGUMENT (-10)
// Executable formats (info: big endian types are >= 128); DO NOT CHANGE // Executable formats (info: big endian types are >= 128); DO NOT CHANGE
#define UPX_F_DOS_COM 1 #define UPX_F_DOS_COM 1
#define UPX_F_DOS_SYS 2 #define UPX_F_DOS_SYS 2
@@ -577,6 +577,7 @@ constexpr bool string_ge(const char *a, const char *b) {
#define M_LZMA 14 #define M_LZMA 14
#define M_DEFLATE 15 // zlib #define M_DEFLATE 15 // zlib
#define M_ZSTD 16 #define M_ZSTD 16
#define M_BZIP2 17
// compression methods internal usage // compression methods internal usage
#define M_ALL (-1) #define M_ALL (-1)
#define M_END (-2) #define M_END (-2)
@@ -591,7 +592,7 @@ constexpr bool string_ge(const char *a, const char *b) {
#define M_IS_LZMA(x) (((x) &255) == M_LZMA) #define M_IS_LZMA(x) (((x) &255) == M_LZMA)
#define M_IS_DEFLATE(x) ((x) == M_DEFLATE) #define M_IS_DEFLATE(x) ((x) == M_DEFLATE)
#define M_IS_ZSTD(x) ((x) == M_ZSTD) #define M_IS_ZSTD(x) ((x) == M_ZSTD)
#define M_IS_BZIP2(x) ((x) == M_BZIP2)
// filters internal usage // filters internal usage
#define FT_END (-1) #define FT_END (-1)
@@ -599,7 +600,6 @@ constexpr bool string_ge(const char *a, const char *b) {
#define FT_SKIP (-3) #define FT_SKIP (-3)
#define FT_ULTRA_BRUTE (-4) #define FT_ULTRA_BRUTE (-4)
/************************************************************************* /*************************************************************************
// compression - setup and callback_t // compression - setup and callback_t
**************************************************************************/ **************************************************************************/
@@ -616,69 +616,26 @@ constexpr bool string_ge(const char *a, const char *b) {
#endif #endif
struct upx_callback_t; struct upx_callback_t;
typedef upx_callback_t *upx_callback_p; typedef void(__acc_cdecl *upx_progress_func_t)(upx_callback_t *, unsigned, unsigned);
typedef void (__acc_cdecl *upx_progress_func_t)
(upx_callback_p, unsigned, unsigned);
struct upx_callback_t { struct upx_callback_t final {
upx_progress_func_t nprogress; upx_progress_func_t nprogress;
void *user; void *user;
void reset() noexcept { mem_clear(this); } void reset() noexcept { mem_clear(this); }
}; };
/************************************************************************* /*************************************************************************
// compression - config_t // compression - config_t
**************************************************************************/ **************************************************************************/
template <class T, T default_value_, T min_value_, T max_value_> struct bzip2_compress_config_t final {
struct OptVar final { unsigned dummy;
static_assert(std::is_integral_v<T>);
typedef T value_type;
static constexpr T default_value = default_value_;
static constexpr T min_value = min_value_;
static constexpr T max_value = max_value_;
static_assert(min_value <= default_value && default_value <= max_value);
static void assertValue(const T &v) noexcept { void reset() noexcept;
// info: this generates annoying warnings "unsigned >= 0 is always true"
//assert_noexcept(v >= min_value);
assert_noexcept(v == min_value || v >= min_value + 1);
assert_noexcept(v <= max_value);
}
void assertValue() const noexcept {
assertValue(v);
}
OptVar() noexcept : v(default_value), is_set(false) { }
OptVar& operator= (const T &other) noexcept {
assertValue(other);
v = other;
is_set = true;
return *this;
}
void reset() noexcept { v = default_value; is_set = false; }
operator T () const noexcept { return v; }
T v;
bool is_set;
}; };
struct lzma_compress_config_t final {
// optional assignments
template <class T, T a, T b, T c>
inline void oassign(OptVar<T,a,b,c> &self, const OptVar<T,a,b,c> &other) noexcept {
if (other.is_set) { self.v = other.v; self.is_set = true; }
}
template <class T, T a, T b, T c>
inline void oassign(T &v, const OptVar<T,a,b,c> &other) noexcept {
if (other.is_set) { v = other.v; }
}
struct lzma_compress_config_t {
typedef OptVar<unsigned, 2u, 0u, 4u> pos_bits_t; // pb typedef OptVar<unsigned, 2u, 0u, 4u> pos_bits_t; // pb
typedef OptVar<unsigned, 0u, 0u, 4u> lit_pos_bits_t; // lp typedef OptVar<unsigned, 0u, 0u, 4u> lit_pos_bits_t; // lp
typedef OptVar<unsigned, 3u, 0u, 8u> lit_context_bits_t; // lc typedef OptVar<unsigned, 3u, 0u, 8u> lit_context_bits_t; // lc
@@ -698,11 +655,11 @@ struct lzma_compress_config_t {
void reset() noexcept; void reset() noexcept;
}; };
struct ucl_compress_config_t : public REAL_ucl_compress_config_t { struct ucl_compress_config_t final : public REAL_ucl_compress_config_t {
void reset() noexcept { memset(this, 0xff, sizeof(*this)); } void reset() noexcept { memset(this, 0xff, sizeof(*this)); }
}; };
struct zlib_compress_config_t { struct zlib_compress_config_t final {
typedef OptVar<unsigned, 8u, 1u, 9u> mem_level_t; // ml typedef OptVar<unsigned, 8u, 1u, 9u> mem_level_t; // ml
typedef OptVar<unsigned, 15u, 9u, 15u> window_bits_t; // wb typedef OptVar<unsigned, 15u, 9u, 15u> window_bits_t; // wb
typedef OptVar<unsigned, 0u, 0u, 4u> strategy_t; // st typedef OptVar<unsigned, 0u, 0u, 4u> strategy_t; // st
@@ -714,29 +671,41 @@ struct zlib_compress_config_t {
void reset() noexcept; void reset() noexcept;
}; };
struct zstd_compress_config_t { struct zstd_compress_config_t final {
unsigned dummy; unsigned dummy;
void reset() noexcept; void reset() noexcept;
}; };
struct upx_compress_config_t { struct upx_compress_config_t final {
bzip2_compress_config_t conf_bzip2;
lzma_compress_config_t conf_lzma; lzma_compress_config_t conf_lzma;
ucl_compress_config_t conf_ucl; ucl_compress_config_t conf_ucl;
zlib_compress_config_t conf_zlib; zlib_compress_config_t conf_zlib;
zstd_compress_config_t conf_zstd; zstd_compress_config_t conf_zstd;
void reset() noexcept { conf_lzma.reset(); conf_ucl.reset(); conf_zlib.reset(); conf_zstd.reset(); } void reset() noexcept {
conf_bzip2.reset();
conf_lzma.reset();
conf_ucl.reset();
conf_zlib.reset();
conf_zstd.reset();
}
}; };
#define NULL_cconf ((upx_compress_config_t *) nullptr) #define NULL_cconf ((upx_compress_config_t *) nullptr)
/************************************************************************* /*************************************************************************
// compression - result_t // compression - result_t
**************************************************************************/ **************************************************************************/
struct lzma_compress_result_t { struct bzip2_compress_result_t final {
unsigned dummy;
void reset() noexcept { mem_clear(this); }
};
struct lzma_compress_result_t final {
unsigned pos_bits; // pb unsigned pos_bits; // pb
unsigned lit_pos_bits; // lp unsigned lit_pos_bits; // lp
unsigned lit_context_bits; // lc unsigned lit_context_bits; // lc
@@ -749,25 +718,25 @@ struct lzma_compress_result_t {
void reset() noexcept { mem_clear(this); } void reset() noexcept { mem_clear(this); }
}; };
struct ucl_compress_result_t { struct ucl_compress_result_t final {
ucl_uint result[16]; ucl_uint result[16];
void reset() noexcept { mem_clear(this); } void reset() noexcept { mem_clear(this); }
}; };
struct zlib_compress_result_t { struct zlib_compress_result_t final {
unsigned dummy; unsigned dummy;
void reset() noexcept { mem_clear(this); } void reset() noexcept { mem_clear(this); }
}; };
struct zstd_compress_result_t { struct zstd_compress_result_t final {
unsigned dummy; unsigned dummy;
void reset() noexcept { mem_clear(this); } void reset() noexcept { mem_clear(this); }
}; };
struct upx_compress_result_t { struct upx_compress_result_t final {
// debugging aid // debugging aid
struct Debug { struct Debug {
int method, level; int method, level;
@@ -776,6 +745,7 @@ struct upx_compress_result_t {
}; };
Debug debug; Debug debug;
bzip2_compress_result_t result_bzip2;
lzma_compress_result_t result_lzma; lzma_compress_result_t result_lzma;
ucl_compress_result_t result_ucl; ucl_compress_result_t result_ucl;
zlib_compress_result_t result_zlib; zlib_compress_result_t result_zlib;
@@ -783,11 +753,14 @@ struct upx_compress_result_t {
void reset() noexcept { void reset() noexcept {
debug.reset(); debug.reset();
result_lzma.reset(); result_ucl.reset(); result_zlib.reset(); result_zstd.reset(); result_bzip2.reset();
result_lzma.reset();
result_ucl.reset();
result_zlib.reset();
result_zstd.reset();
} }
}; };
/************************************************************************* /*************************************************************************
// globals // globals
**************************************************************************/ **************************************************************************/
@@ -812,7 +785,7 @@ extern const char *progname;
bool main_set_exit_code(int ec); bool main_set_exit_code(int ec);
int main_get_options(int argc, char **argv); int main_get_options(int argc, char **argv);
void main_get_envoptions(); void main_get_envoptions();
int upx_main(int argc, char *argv[]); int upx_main(int argc, char *argv[]) may_throw;
// msg.cpp // msg.cpp
void printSetNl(int need_nl) noexcept; void printSetNl(int need_nl) noexcept;
@@ -829,24 +802,26 @@ void infoHeader();
void infoWriting(const char *what, upx_int64_t size); void infoWriting(const char *what, upx_int64_t size);
// work.cpp // work.cpp
void do_one_file(const char *iname, char *oname); void do_one_file(const char *iname, char *oname) may_throw;
int do_files(int i, int argc, char *argv[]); int do_files(int i, int argc, char *argv[]) may_throw;
// help.cpp // help.cpp
extern const char gitrev[]; extern const char gitrev[];
void show_header(); void show_header();
void show_help(int verbose = 0); void show_help(int verbose = 0);
void show_license(); void show_license();
void show_sysinfo(const char *options_var);
void show_usage(); void show_usage();
void show_version(bool one_line = false); void show_version(bool one_line = false);
// compress/compress.cpp // compress/compress.cpp
// clang-format off
unsigned upx_adler32(const void *buf, unsigned len, unsigned adler = 1); unsigned upx_adler32(const void *buf, unsigned len, unsigned adler = 1);
unsigned upx_crc32 (const void *buf, unsigned len, unsigned crc = 0); unsigned upx_crc32 (const void *buf, unsigned len, unsigned crc = 0);
int upx_compress ( const upx_bytep src, unsigned src_len, int upx_compress ( const upx_bytep src, unsigned src_len,
upx_bytep dst, unsigned *dst_len, upx_bytep dst, unsigned *dst_len,
upx_callback_p cb, upx_callback_t *cb,
int method, int level, int method, int level,
const upx_compress_config_t *cconf, const upx_compress_config_t *cconf,
upx_compress_result_t *cresult ); upx_compress_result_t *cresult );
@@ -860,17 +835,16 @@ int upx_test_overlap ( const upx_bytep buf,
unsigned *dst_len, unsigned *dst_len,
int method, int method,
const upx_compress_result_t *cresult ); const upx_compress_result_t *cresult );
// clang-format on
#include "util/snprintf.h" // must get included first! #include "util/snprintf.h" // must get included first!
#include "util/util.h"
#include "options.h" #include "options.h"
#include "except.h" #include "except.h"
#include "bele.h" #include "bele.h"
#include "console/console.h" #include "console/console.h"
#include "util/util.h"
// xspan // xspan
#include "util/raw_bytes.h" #include "util/raw_bytes.h"
#include "util/xspan.h" #include "util/xspan.h"
/* vim:set ts=4 sw=4 et: */ /* vim:set ts=4 sw=4 et: */
+2 -2
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer Copyright (C) 1996-2024 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2023 Laszlo Molnar Copyright (C) 1996-2024 Laszlo Molnar
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
+2 -2
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer Copyright (C) 1996-2024 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2023 Laszlo Molnar Copyright (C) 1996-2024 Laszlo Molnar
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
+2 -2
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer Copyright (C) 1996-2024 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2023 Laszlo Molnar Copyright (C) 1996-2024 Laszlo Molnar
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
+2 -2
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer Copyright (C) 1996-2024 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2023 Laszlo Molnar Copyright (C) 1996-2024 Laszlo Molnar
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
+2 -2
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer Copyright (C) 1996-2024 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2023 Laszlo Molnar Copyright (C) 1996-2024 Laszlo Molnar
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
+2 -2
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer Copyright (C) 1996-2024 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2023 Laszlo Molnar Copyright (C) 1996-2024 Laszlo Molnar
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
+2 -2
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer Copyright (C) 1996-2024 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2023 Laszlo Molnar Copyright (C) 1996-2024 Laszlo Molnar
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
+2 -2
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer Copyright (C) 1996-2024 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2023 Laszlo Molnar Copyright (C) 1996-2024 Laszlo Molnar
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
+11 -20
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer Copyright (C) 1996-2024 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2023 Laszlo Molnar Copyright (C) 1996-2024 Laszlo Molnar
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
@@ -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;
+2 -6
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer Copyright (C) 1996-2024 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2023 Laszlo Molnar Copyright (C) 1996-2024 Laszlo Molnar
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
@@ -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: */
+17 -7
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer Copyright (C) 1996-2024 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2023 Laszlo Molnar Copyright (C) 1996-2024 Laszlo Molnar
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
@@ -142,7 +142,7 @@ void throwEOFException(const char *msg, int e) {
} }
/************************************************************************* /*************************************************************************
// // varargs overloads
**************************************************************************/ **************************************************************************/
template <> template <>
@@ -150,7 +150,7 @@ void throwCantPack(const char *format, ...) {
char msg[1024]; char msg[1024];
va_list ap; va_list ap;
va_start(ap, format); va_start(ap, format);
(void) upx_safe_vsnprintf(msg, sizeof(msg), format, ap); (void) upx_safe_vsnprintf_noexcept(msg, sizeof(msg), format, ap);
va_end(ap); va_end(ap);
throwCantPack(msg); throwCantPack(msg);
} }
@@ -160,13 +160,23 @@ void throwCantUnpack(const char *format, ...) {
char msg[1024]; char msg[1024];
va_list ap; va_list ap;
va_start(ap, format); va_start(ap, format);
(void) upx_safe_vsnprintf(msg, sizeof(msg), format, ap); (void) upx_safe_vsnprintf_noexcept(msg, sizeof(msg), format, ap);
va_end(ap);
throwCantUnpack(msg);
}
template <>
void throwInternalError(const char *format, ...) {
char msg[1024];
va_list ap;
va_start(ap, format);
(void) upx_safe_vsnprintf_noexcept(msg, sizeof(msg), format, ap);
va_end(ap); va_end(ap);
throwCantUnpack(msg); throwCantUnpack(msg);
} }
/************************************************************************* /*************************************************************************
// // 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 +201,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;
+29 -26
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer Copyright (C) 1996-2024 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2023 Laszlo Molnar Copyright (C) 1996-2024 Laszlo Molnar
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
@@ -43,7 +43,7 @@ protected:
Throwable(const char *m = nullptr, int e = 0, bool w = false) noexcept; Throwable(const char *m = nullptr, int e = 0, bool w = false) noexcept;
public: public:
Throwable(const Throwable &) noexcept; Throwable(const Throwable &) noexcept; // copy constructor
virtual ~Throwable() noexcept; virtual ~Throwable() noexcept;
const char *getMsg() const noexcept { return msg; } const char *getMsg() const noexcept { return msg; }
int getErrno() const noexcept { return err; } int getErrno() const noexcept { return err; }
@@ -57,14 +57,13 @@ protected:
private: private:
// disable copy assignment and move // disable copy assignment and move
Throwable &operator=(const Throwable &) DELETED_FUNCTION; Throwable &operator=(const Throwable &) noexcept DELETED_FUNCTION; // copy assignment
Throwable(Throwable &&) noexcept DELETED_FUNCTION; UPX_CXX_DISABLE_MOVE(Throwable)
Throwable &operator=(Throwable &&) noexcept DELETED_FUNCTION;
// disable dynamic allocation => force throwing by value // disable dynamic allocation => force throwing by value
ACC_CXX_DISABLE_NEW_DELETE UPX_CXX_DISABLE_NEW_DELETE(Throwable)
// disable taking the address => force passing by reference // disable taking the address => force passing by reference
// [I'm not too sure about this design decision, but we can always allow it if needed] // [I'm not too sure about this design decision, but we can always allow it if needed]
Throwable *operator&() const noexcept DELETED_FUNCTION; UPX_CXX_DISABLE_ADDRESS(Throwable)
private: private:
static upx_std_atomic(size_t) debug_counter; // for debugging static upx_std_atomic(size_t) debug_counter; // for debugging
@@ -186,32 +185,36 @@ 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);
template <class T>
void throwInternalError(const T *, ...) DELETED_FUNCTION;
template <>
NORET void throwInternalError(const char *format, ...) may_throw attribute_format(1, 2);
#undef NORET #undef NORET
+30 -19
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer Copyright (C) 1996-2024 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2023 Laszlo Molnar Copyright (C) 1996-2024 Laszlo Molnar
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
@@ -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,13 +52,23 @@
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 {
@@ -65,10 +76,10 @@ FileBase::~FileBase() may_throw {
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;
+10 -9
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer Copyright (C) 1996-2024 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2023 Laszlo Molnar Copyright (C) 1996-2024 Laszlo Molnar
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
@@ -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();
+2 -2
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer Copyright (C) 1996-2024 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2023 Laszlo Molnar Copyright (C) 1996-2024 Laszlo Molnar
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
+3 -3
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer Copyright (C) 1996-2024 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2023 Laszlo Molnar Copyright (C) 1996-2024 Laszlo Molnar
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
@@ -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:
+93 -212
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer Copyright (C) 1996-2024 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2023 Laszlo Molnar Copyright (C) 1996-2024 Laszlo Molnar
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
@@ -25,8 +25,6 @@
<markus@oberhumer.com> <ezerotven+github@gmail.com> <markus@oberhumer.com> <ezerotven+github@gmail.com>
*/ */
/************************************************************************* /*************************************************************************
// 16-bit calltrick ("naive") // 16-bit calltrick ("naive")
**************************************************************************/ **************************************************************************/
@@ -35,8 +33,7 @@
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; \
@@ -45,167 +42,117 @@
b += 2 - 1; \ b += 2 - 1; \
} \ } \
} while (++b < b_end); \ } while (++b < b_end); \
if (f->lastcall) f->lastcall += 2; \ if (f->lastcall) \
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")
**************************************************************************/ **************************************************************************/
@@ -214,8 +161,7 @@ static int s_ct16_e8e9_bswap_be(Filter *f)
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; \
@@ -224,163 +170,115 @@ static int s_ct16_e8e9_bswap_be(Filter *f)
b += 4 - 1; \ b += 4 - 1; \
} \ } \
} while (++b < b_end); \ } while (++b < b_end); \
if (f->lastcall) f->lastcall += 4; \ if (f->lastcall) \
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
/************************************************************************* /*************************************************************************
@@ -391,8 +289,7 @@ static int s_ct32_e8e9_bswap_be(Filter *f)
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)); \
@@ -400,24 +297,21 @@ static int s_ct32_e8e9_bswap_be(Filter *f)
} \ } \
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;
#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)
} }
@@ -427,8 +321,7 @@ static int s_ct24arm_le(Filter *f)
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)); \
@@ -436,23 +329,21 @@ static int s_ct24arm_le(Filter *f)
} \ } \
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;
#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)
} }
@@ -468,8 +359,7 @@ static int s_ct24arm_be(Filter *f)
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)); \
@@ -477,23 +367,21 @@ static int s_ct24arm_be(Filter *f)
} \ } \
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;
#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)
} }
@@ -509,41 +397,34 @@ static int CTarm64(Filter *f, int dir) // dir: 1, 0, -1
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 //}
+15 -33
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer Copyright (C) 1996-2024 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2023 Laszlo Molnar Copyright (C) 1996-2024 Laszlo Molnar
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
@@ -25,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;
@@ -57,17 +54,14 @@ static int F(Filter *f)
// 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;
} }
@@ -79,26 +73,22 @@ static int F(Filter *f)
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);
@@ -113,9 +103,7 @@ 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,14 +121,12 @@ 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;
@@ -149,24 +135,20 @@ static int U(Filter *f)
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
+16 -34
View File
@@ -2,9 +2,9 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer Copyright (C) 1996-2024 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2023 Laszlo Molnar Copyright (C) 1996-2024 Laszlo Molnar
Copyright (C) 2000-2023 John F. Reiser Copyright (C) 2000-2024 John F. Reiser
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
@@ -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;
@@ -56,17 +53,14 @@ static int F(Filter *f)
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;
} }
@@ -78,26 +72,22 @@ static int F(Filter *f)
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);
@@ -112,9 +102,7 @@ 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,14 +120,12 @@ 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;
@@ -148,24 +134,20 @@ static int U(Filter *f)
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
+35 -77
View File
@@ -2,9 +2,9 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer Copyright (C) 1996-2024 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2023 Laszlo Molnar Copyright (C) 1996-2024 Laszlo Molnar
Copyright (C) 2000-2023 John F. Reiser Copyright (C) 2000-2024 John F. Reiser
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
@@ -29,12 +29,10 @@
<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
**************************************************************************/ **************************************************************************/
@@ -44,44 +42,28 @@
#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 unsigned jc, // destination address
const int kh, // mru[kh] is slot where found const int kh, // mru[kh] is slot where found
unsigned mru[N_MRU], // circular buffer of most recent destinations unsigned mru[N_MRU], // circular buffer of most recent destinations
int &hand, // mru[hand] is most recent destination int &hand, // mru[hand] is most recent destination
int &tail // mru[tail] is beyond oldest destination ("cold cache" startup) int &tail // mru[tail] is beyond oldest destination ("cold cache" startup)
) ) {
{
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;
} }
@@ -93,9 +75,7 @@ update_mru(
} }
#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,7 +88,8 @@ 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);
@@ -119,8 +100,7 @@ static int F(Filter *f)
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.
@@ -131,8 +111,7 @@ static int F(Filter *f)
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);
@@ -145,8 +124,7 @@ static int F(Filter *f)
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))
@@ -154,8 +132,7 @@ static int F(Filter *f)
++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
@@ -163,16 +140,14 @@ static int F(Filter *f)
// 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.
@@ -197,29 +172,24 @@ static int F(Filter *f)
} }
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 #ifdef U
// restore original // restore original
if (2 == which) { if (2 == which) {
// 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;
} }
@@ -236,9 +206,7 @@ static int F(Filter *f)
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++;
@@ -258,14 +226,12 @@ 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;
@@ -282,15 +248,12 @@ 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;
@@ -298,8 +261,7 @@ static int U(Filter *f)
hand = N_MRU - 1; hand = N_MRU - 1;
} }
mru[hand] = jc; mru[hand] = jc;
} } else { // not 1st time at this destination
else { // not 1st time at this destination
jc >>= 1; jc >>= 1;
if (N_MRU <= jc) { if (N_MRU <= jc) {
throwCompressedDataViolation(); throwCompressedDataViolation();
@@ -312,17 +274,14 @@ static int U(Filter *f)
update_mru(jc, kh, mru, hand, tail); update_mru(jc, kh, mru, hand, tail);
} }
set_le32(b + ic + 1, jc - ic - 1); set_le32(b + ic + 1, jc - ic - 1);
} 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_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;
} }
@@ -332,8 +291,7 @@ static int U(Filter *f)
ic += 4; ic += 4;
f->lastcall = lastcall = ic + 1; f->lastcall = lastcall = ic + 1;
} }
} } else
else
f->noncalls++; f->noncalls++;
} }
} }
+16 -34
View File
@@ -2,9 +2,9 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer Copyright (C) 1996-2024 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2023 Laszlo Molnar Copyright (C) 1996-2024 Laszlo Molnar
Copyright (C) 2000-2023 John F. Reiser Copyright (C) 2000-2024 John F. Reiser
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
@@ -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;
@@ -57,17 +54,14 @@ static int F(Filter *f)
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;
} }
@@ -79,26 +73,22 @@ static int F(Filter *f)
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);
@@ -113,9 +103,7 @@ 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,14 +121,12 @@ 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;
@@ -151,24 +137,20 @@ static int U(Filter *f)
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
+22 -49
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer Copyright (C) 1996-2024 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2023 Laszlo Molnar Copyright (C) 1996-2024 Laszlo Molnar
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
@@ -25,8 +25,6 @@
<markus@oberhumer.com> <ezerotven+github@gmail.com> <markus@oberhumer.com> <ezerotven+github@gmail.com>
*/ */
/************************************************************************* /*************************************************************************
// 16-bit call-/swaptrick ("naive") // 16-bit call-/swaptrick ("naive")
**************************************************************************/ **************************************************************************/
@@ -35,17 +33,14 @@
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) { \
else if (cond2) \
{ \
b += 1; \ b += 1; \
unsigned a = (unsigned) (b - f->buf); \ unsigned a = (unsigned) (b - f->buf); \
f->lastcall = a; \ f->lastcall = a; \
@@ -54,49 +49,39 @@
b += 2 - 1; \ b += 2 - 1; \
} \ } \
} while (++b < b_end); \ } while (++b < b_end); \
if (f->lastcall) f->lastcall += 2; \ 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")
**************************************************************************/ **************************************************************************/
@@ -105,17 +90,14 @@ static int s_ctsw16_e9_e8(Filter *f)
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) { \
else if (cond2) \
{ \
b += 1; \ b += 1; \
unsigned a = (unsigned) (b - f->buf); \ unsigned a = (unsigned) (b - f->buf); \
f->lastcall = a; \ f->lastcall = a; \
@@ -124,46 +106,37 @@ static int s_ctsw16_e9_e8(Filter *f)
b += 4 - 1; \ b += 4 - 1; \
} \ } \
} while (++b < b_end); \ } while (++b < b_end); \
if (f->lastcall) f->lastcall += 4; \ 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: */
+9 -23
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer Copyright (C) 1996-2024 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2023 Laszlo Molnar Copyright (C) 1996-2024 Laszlo Molnar
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
@@ -25,29 +25,21 @@
<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 set_dummy(p, v) ((void) 0)
#define get_8(p) (*(p)) #define get_8(p) (*(p))
#define set_8(p, v) (*(p) = (v)) #define set_8(p, v) (*(p) = (v))
/************************************************************************* /*************************************************************************
// util // util
**************************************************************************/ **************************************************************************/
#include "getcto.h" #include "getcto.h"
/************************************************************************* /*************************************************************************
// simple filters: calltrick / swaptrick / delta / ... // simple filters: calltrick / swaptrick / delta / ...
**************************************************************************/ **************************************************************************/
@@ -60,7 +52,6 @@ umin(const unsigned a, const unsigned b)
#include "sub16.h" #include "sub16.h"
#include "sub32.h" #include "sub32.h"
/************************************************************************* /*************************************************************************
// cto calltrick // cto calltrick
**************************************************************************/ **************************************************************************/
@@ -89,7 +80,6 @@ umin(const unsigned a, const unsigned b)
#include "cto.h" #include "cto.h"
#undef COND #undef COND
/************************************************************************* /*************************************************************************
// cto calltrick with jmp // cto calltrick with jmp
**************************************************************************/ **************************************************************************/
@@ -102,7 +92,6 @@ umin(const unsigned a, const unsigned b)
#include "ctoj.h" #include "ctoj.h"
#undef COND #undef COND
/************************************************************************* /*************************************************************************
// cto calltrick with jmp, optional jcc // cto calltrick with jmp, optional jcc
**************************************************************************/ **************************************************************************/
@@ -119,22 +108,19 @@ umin(const unsigned a, const unsigned b)
#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
@@ -150,7 +136,6 @@ 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
**************************************************************************/ **************************************************************************/
@@ -163,11 +148,11 @@ umin(const unsigned a, const unsigned b)
#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);
+6 -12
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer Copyright (C) 1996-2024 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2023 Laszlo Molnar Copyright (C) 1996-2024 Laszlo Molnar
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
@@ -25,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;
} }
+15 -19
View File
@@ -2,9 +2,9 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer Copyright (C) 1996-2024 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2023 Laszlo Molnar Copyright (C) 1996-2024 Laszlo Molnar
Copyright (C) 2004-2023 John F. Reiser Copyright (C) 2004-2024 John F. Reiser
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
@@ -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;
@@ -63,7 +60,8 @@ static int F(Filter *f)
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)
if (COND(b, ic)) {
unsigned const off = (int) (get_be32(b + ic) << 6) >> 6; unsigned const off = (int) (get_be32(b + ic) << 6) >> 6;
if (size <= (off & (~0u << 2)) + ic) { if (size <= (off & (~0u << 2)) + ic) {
buf[(~(~0u << W_CTO)) & (off >> (26 - W_CTO))] |= 1; buf[(~(~0u << W_CTO)) & (off >> (26 - W_CTO))] |= 1;
@@ -84,7 +82,8 @@ static int F(Filter *f)
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)
if (COND(b, ic)) {
unsigned const word = get_be32(b + ic); unsigned const word = get_be32(b + ic);
unsigned const off = (int) (word << 6) >> 6; unsigned const off = (int) (word << 6) >> 6;
unsigned const jc = (off & (~0u << 2)) + ic; unsigned const jc = (off & (~0u << 2)) + ic;
@@ -95,10 +94,10 @@ static int F(Filter *f)
#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++;
@@ -117,29 +116,27 @@ 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)
if (COND(b, ic)) {
unsigned const word = get_be32(b + ic); unsigned const word = get_be32(b + ic);
if ((~(~0u << W_CTO) & (word >> (24 + 2 - W_CTO))) == (unsigned) f->cto) { if ((~(~0u << W_CTO) & (word >> (24 + 2 - W_CTO))) == (unsigned) f->cto) {
unsigned const jc = word & (~(~0u << (26 - W_CTO)) & (~0u << 2)); unsigned const jc = word & (~(~0u << (26 - W_CTO)) & (~0u << 2));
set_be32(b + ic, (0xfc000003 & word) | (0x03fffffc & (jc - ic - addvalue))); set_be32(b + ic, (0xfc000003 & word) | (0x03fffffc & (jc - ic - addvalue)));
f->calls++; f->calls++;
f->lastcall = ic; f->lastcall = ic;
} } else {
else {
f->noncalls++; f->noncalls++;
} }
} }
@@ -147,7 +144,6 @@ static int U(Filter *f)
} }
#endif #endif
#undef F #undef F
#undef U #undef U
+10 -8
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer Copyright (C) 1996-2024 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2023 Laszlo Molnar Copyright (C) 1996-2024 Laszlo Molnar
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
@@ -25,8 +25,6 @@
<markus@oberhumer.com> <ezerotven+github@gmail.com> <markus@oberhumer.com> <ezerotven+github@gmail.com>
*/ */
/************************************************************************* /*************************************************************************
// //
**************************************************************************/ **************************************************************************/
@@ -37,7 +35,10 @@
int i; \ int i; \
T d[N]; \ T d[N]; \
\ \
i = N - 1; do d[i] = 0; while (--i >= 0); \ i = N - 1; \
do \
d[i] = 0; \
while (--i >= 0); \
\ \
i = N - 1; \ i = N - 1; \
do { \ do { \
@@ -52,14 +53,16 @@
assert((int) f->calls > 0); \ 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; do d[i] = 0; while (--i >= 0); \ i = N - 1; \
do \
d[i] = 0; \
while (--i >= 0); \
\ \
i = N - 1; \ i = N - 1; \
do { \ do { \
@@ -73,7 +76,6 @@
assert((int) f->calls > 0); \ 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); \
+14 -56
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer Copyright (C) 1996-2024 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2023 Laszlo Molnar Copyright (C) 1996-2024 Laszlo Molnar
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
@@ -25,8 +25,6 @@
<markus@oberhumer.com> <ezerotven+github@gmail.com> <markus@oberhumer.com> <ezerotven+github@gmail.com>
*/ */
/************************************************************************* /*************************************************************************
// //
**************************************************************************/ **************************************************************************/
@@ -37,76 +35,36 @@
#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
+14 -56
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer Copyright (C) 1996-2024 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2023 Laszlo Molnar Copyright (C) 1996-2024 Laszlo Molnar
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
@@ -25,8 +25,6 @@
<markus@oberhumer.com> <ezerotven+github@gmail.com> <markus@oberhumer.com> <ezerotven+github@gmail.com>
*/ */
/************************************************************************* /*************************************************************************
// //
**************************************************************************/ **************************************************************************/
@@ -37,76 +35,36 @@
#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
+14 -56
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer Copyright (C) 1996-2024 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2023 Laszlo Molnar Copyright (C) 1996-2024 Laszlo Molnar
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
@@ -25,8 +25,6 @@
<markus@oberhumer.com> <ezerotven+github@gmail.com> <markus@oberhumer.com> <ezerotven+github@gmail.com>
*/ */
/************************************************************************* /*************************************************************************
// //
**************************************************************************/ **************************************************************************/
@@ -37,76 +35,36 @@
#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
+26 -93
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer Copyright (C) 1996-2024 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2023 Laszlo Molnar Copyright (C) 1996-2024 Laszlo Molnar
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
@@ -25,8 +25,6 @@
<markus@oberhumer.com> <ezerotven+github@gmail.com> <markus@oberhumer.com> <ezerotven+github@gmail.com>
*/ */
/************************************************************************* /*************************************************************************
// 16-bit swaptrick ("naive") // 16-bit swaptrick ("naive")
**************************************************************************/ **************************************************************************/
@@ -35,8 +33,7 @@
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; \
@@ -45,66 +42,33 @@
b += 2 - 1; \ b += 2 - 1; \
} \ } \
} while (++b < b_end); \ } while (++b < b_end); \
if (f->lastcall) f->lastcall += 2; \ if (f->lastcall) \
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")
**************************************************************************/ **************************************************************************/
@@ -113,8 +77,7 @@ static int s_sw16_e8e9(Filter *f)
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; \
@@ -123,60 +86,30 @@ static int s_sw16_e8e9(Filter *f)
b += 4 - 1; \ b += 4 - 1; \
} \ } \
} while (++b < b_end); \ } while (++b < b_end); \
if (f->lastcall) f->lastcall += 4; \ if (f->lastcall) \
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
+39 -8
View File
@@ -2,7 +2,7 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer Copyright (C) 1996-2024 Markus Franz Xaver Johannes Oberhumer
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
@@ -57,11 +57,26 @@ static_assert(sizeof(void *) == 8);
#if !defined(_FILE_OFFSET_BITS) #if !defined(_FILE_OFFSET_BITS)
#define _FILE_OFFSET_BITS 64 #define _FILE_OFFSET_BITS 64
#endif #endif
#if defined(_WIN32) && defined(__MINGW32__) && defined(__GNUC__) #if defined(_WIN32) && defined(__MINGW32__) && (defined(__clang__) || defined(__GNUC__))
#if !defined(_USE_MINGW_ANSI_STDIO) #if !defined(__USE_MINGW_ANSI_STDIO)
#define _USE_MINGW_ANSI_STDIO 1 #define __USE_MINGW_ANSI_STDIO 1
#endif #endif
#endif #endif
#if defined(_WIN32)
// disable silly warnings about using "deprecated" POSIX functions like fopen()
#if !defined(_CRT_NONSTDC_NO_DEPRECATE)
#define _CRT_NONSTDC_NO_DEPRECATE 1
#endif
#if !defined(_CRT_NONSTDC_NO_WARNINGS)
#define _CRT_NONSTDC_NO_WARNINGS 1
#endif
#if !defined(_CRT_SECURE_NO_DEPRECATE)
#define _CRT_SECURE_NO_DEPRECATE 1
#endif
#if !defined(_CRT_SECURE_NO_WARNINGS)
#define _CRT_SECURE_NO_WARNINGS 1
#endif
#endif // _WIN32
// ACC and C system headers // ACC and C system headers
#ifndef ACC_CFG_USE_NEW_STYLE_CASTS #ifndef ACC_CFG_USE_NEW_STYLE_CASTS
@@ -98,9 +113,6 @@ static_assert(sizeof(void *) == 8);
#include <type_traits> #include <type_traits>
// C++ multithreading (UPX currently does not use multithreading) // C++ multithreading (UPX currently does not use multithreading)
#ifndef WITH_THREADS
#define WITH_THREADS 0
#endif
#if __STDC_NO_ATOMICS__ #if __STDC_NO_ATOMICS__
#undef WITH_THREADS #undef WITH_THREADS
#endif #endif
@@ -109,6 +121,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 +145,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
@@ -139,4 +164,10 @@ static_assert(sizeof(void *) == 8);
#endif #endif
#endif #endif
#ifdef WANT_WINDOWS_LEAN_H
#if defined(_WIN32) || defined(__CYGWIN__)
#include "util/windows_lean.h"
#endif
#endif
/* vim:set ts=4 sw=4 et: */ /* vim:set ts=4 sw=4 et: */
+168 -17
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer Copyright (C) 1996-2024 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2023 Laszlo Molnar Copyright (C) 1996-2024 Laszlo Molnar
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
@@ -25,6 +25,7 @@
<markus@oberhumer.com> <ezerotven+github@gmail.com> <markus@oberhumer.com> <ezerotven+github@gmail.com>
*/ */
#define WANT_WINDOWS_LEAN_H 1 // _WIN32_WINNT
#include "conf.h" #include "conf.h"
#include "compress/compress.h" // upx_ucl_version_string() #include "compress/compress.h" // upx_ucl_version_string()
// for list_all_packers(): // for list_all_packers():
@@ -103,17 +104,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 +129,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 +186,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 +222,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,
@@ -399,14 +411,19 @@ void show_version(bool one_line) {
if (v != nullptr && v[0]) if (v != nullptr && v[0])
fprintf(f, "zstd data compression library %s\n", v); fprintf(f, "zstd data compression library %s\n", v);
#endif #endif
#if (WITH_BZIP2)
v = upx_bzip2_version_string();
if (v != nullptr && v[0])
fprintf(f, "bzip2 data compression library %s\n", v);
#endif
#if !defined(DOCTEST_CONFIG_DISABLE) #if !defined(DOCTEST_CONFIG_DISABLE)
fprintf(f, "doctest C++ testing framework version %s\n", DOCTEST_VERSION_STR); fprintf(f, "doctest C++ testing framework version %s\n", DOCTEST_VERSION_STR);
#endif #endif
// clang-format off // clang-format off
fprintf(f, "Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer\n"); fprintf(f, "Copyright (C) 1996-2024 Markus Franz Xaver Johannes Oberhumer\n");
fprintf(f, "Copyright (C) 1996-2023 Laszlo Molnar\n"); fprintf(f, "Copyright (C) 1996-2024 Laszlo Molnar\n");
fprintf(f, "Copyright (C) 2000-2023 John F. Reiser\n"); fprintf(f, "Copyright (C) 2000-2024 John F. Reiser\n");
fprintf(f, "Copyright (C) 2002-2023 Jens Medoch\n"); fprintf(f, "Copyright (C) 2002-2024 Jens Medoch\n");
#if (WITH_ZLIB) #if (WITH_ZLIB)
fprintf(f, "Copyright (C) 1995" "-2023 Jean-loup Gailly and Mark Adler\n"); fprintf(f, "Copyright (C) 1995" "-2023 Jean-loup Gailly and Mark Adler\n");
#endif #endif
@@ -417,6 +434,9 @@ void show_version(bool one_line) {
// see vendor/zstd/LICENSE; main author is Yann Collet // see vendor/zstd/LICENSE; main author is Yann Collet
fprintf(f, "Copyright (C) 2015" "-2023 Meta Platforms, Inc. and affiliates\n"); fprintf(f, "Copyright (C) 2015" "-2023 Meta Platforms, Inc. and affiliates\n");
#endif #endif
#if (WITH_BZIP2)
fprintf(f, "Copyright (C) 1996" "-2010 Julian Seward\n"); // see <bzlib.h>
#endif
#if !defined(DOCTEST_CONFIG_DISABLE) #if !defined(DOCTEST_CONFIG_DISABLE)
fprintf(f, "Copyright (C) 2016" "-2023 Viktor Kirilov\n"); fprintf(f, "Copyright (C) 2016" "-2023 Viktor Kirilov\n");
#endif #endif
@@ -424,4 +444,135 @@ 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);
con_fprintf(f, "UPX version internal: 0x%06x %s\n", UPX_VERSION_HEX, UPX_VERSION_STRING);
}
fflush(stdout);
// Compilation Flags
{
size_t cf_count = 0;
auto cf_print = [f, &cf_count](const char *name, const char *fmt, upx_int64_t v,
int need_verbose = 2) noexcept {
if (opt->verbose < need_verbose)
return;
if (cf_count++ == 0)
con_fprintf(f, "\nCompilation flags:\n");
con_fprintf(f, " %s = ", name);
con_fprintf(f, fmt, v);
con_fprintf(f, "\n");
};
// language
cf_print("__cplusplus", "%lld", __cplusplus + 0, 3);
#if defined(_MSVC_LANG)
cf_print("_MSVC_LANG", "%lld", _MSVC_LANG + 0, 3);
#endif
// compiler
#if defined(ACC_CC_CLANG)
cf_print("ACC_CC_CLANG", "0x%06llx", ACC_CC_CLANG + 0, 3);
#endif
#if defined(ACC_CC_GNUC)
cf_print("ACC_CC_GNUC", "0x%06llx", ACC_CC_GNUC + 0, 3);
#endif
#if defined(ACC_CC_MSC)
cf_print("ACC_CC_MSC", "%lld", ACC_CC_MSC + 0, 3);
#endif
#if defined(__clang__)
cf_print("__clang__", "%lld", __clang__ + 0);
#endif
#if defined(__clang_major__)
cf_print("__clang_major__", "%lld", __clang_major__ + 0);
#endif
#if defined(__GNUC__)
cf_print("__GNUC__", "%lld", __GNUC__ + 0);
#endif
#if defined(__GNUC_MINOR__)
cf_print("__GNUC_MINOR__", "%lld", __GNUC_MINOR__ + 0);
#endif
#if defined(_MSC_VER)
cf_print("_MSC_VER", "%lld", _MSC_VER + 0);
#endif
#if defined(_MSC_FULL_VER)
cf_print("_MSC_FULL_VER", "%lld", _MSC_FULL_VER + 0);
#endif
// 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(__MINGW64_VERSION_MAJOR)
cf_print("__MINGW64_VERSION_MAJOR", "%lld", __MINGW64_VERSION_MAJOR + 0);
#endif
#if defined(__USE_MINGW_ANSI_STDIO)
cf_print("__USE_MINGW_ANSI_STDIO", "%lld", __USE_MINGW_ANSI_STDIO + 0, 3);
#endif
#if defined(__GLIBC__)
cf_print("__GLIBC__", "%lld", __GLIBC__ + 0);
#endif
#if defined(__GLIBC_MINOR__)
cf_print("__GLIBC_MINOR__", "%lld", __GLIBC_MINOR__ + 0);
#endif
// misc compilation options
#if defined(UPX_CONFIG_DISABLE_WSTRICT)
cf_print("UPX_CONFIG_DISABLE_WSTRICT", "%lld", UPX_CONFIG_DISABLE_WSTRICT + 0, 3);
#endif
#if defined(UPX_CONFIG_DISABLE_WERROR)
cf_print("UPX_CONFIG_DISABLE_WERROR", "%lld", UPX_CONFIG_DISABLE_WERROR + 0, 3);
#endif
#if defined(WITH_THREADS)
cf_print("WITH_THREADS", "%lld", WITH_THREADS + 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 if (e)
con_fprintf(f, "Environment variable '%s' is set but empty.\n\n", options_var);
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
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer Copyright (C) 1996-2024 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2023 Laszlo Molnar Copyright (C) 1996-2024 Laszlo Molnar
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
+2 -2
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer Copyright (C) 1996-2024 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2023 Laszlo Molnar Copyright (C) 1996-2024 Laszlo Molnar
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
+3 -2
View File
@@ -2,8 +2,8 @@
This file is part of the UPX executable compressor. This file is part of the UPX executable compressor.
Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer Copyright (C) 1996-2024 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2023 Laszlo Molnar Copyright (C) 1996-2024 Laszlo Molnar
All Rights Reserved. All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them UPX and the UCL library are free software; you can redistribute them
@@ -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;
} }

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