From 9fbe95ad487274783e04a3126d0ca051e7f528c5 Mon Sep 17 00:00:00 2001 From: "Markus F.X.J. Oberhumer" Date: Sat, 21 Oct 2023 11:22:18 +0200 Subject: [PATCH] all: cleanups --- .github/workflows/ci.yml | 4 +- .github/workflows/weekly-ci-cc-llvm-mingw.yml | 12 +-- .github/workflows/weekly-ci-cc-zigcc.yml | 4 +- CMakeLists.txt | 8 +- misc/podman/rebuild-stubs/Dockerfile | 1 + misc/podman/rebuild-stubs/packages.txt | 54 ++++++------ src/check/dt_xspan.cpp | 46 +++++++++- src/conf.h | 3 +- src/pefile.cpp | 33 ++++---- src/pefile.h | 2 +- src/util/util.h | 10 +++ src/util/xspan.h | 42 +++++----- src/util/xspan_fwd.h | 84 +++++++++++++++---- src/util/xspan_impl.h | 12 +-- src/util/xspan_impl_common.h | 14 ++-- src/util/xspan_impl_ptr.h | 10 +-- 16 files changed, 220 insertions(+), 119 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a8ac960c..2796075d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -12,8 +12,8 @@ env: CMAKE_REQUIRED_QUIET: OFF DEBIAN_FRONTEND: noninteractive UPX_CMAKE_BUILD_FLAGS: --verbose - # 2023-10-12 - ZIG_DIST_VERSION: 0.12.0-dev.890+8c6b0271c + # 2023-10-21 + ZIG_DIST_VERSION: 0.12.0-dev.1137+fbbccc9d5 jobs: job-rebuild-and-verify-stubs: diff --git a/.github/workflows/weekly-ci-cc-llvm-mingw.yml b/.github/workflows/weekly-ci-cc-llvm-mingw.yml index eae1c1f4..352f0c8f 100644 --- a/.github/workflows/weekly-ci-cc-llvm-mingw.yml +++ b/.github/workflows/weekly-ci-cc-llvm-mingw.yml @@ -24,12 +24,12 @@ jobs: - name: llvm-mingw-20230614-ucrt llvm_version: 16.0.6 url: 'https://github.com/mstorsjo/llvm-mingw/releases/download/20230614/llvm-mingw-20230614-ucrt-ubuntu-20.04-x86_64.tar.xz' - - name: llvm-mingw-20231003-msvcrt - llvm_version: 17.0.2 - url: 'https://github.com/mstorsjo/llvm-mingw/releases/download/20231003/llvm-mingw-20231003-msvcrt-ubuntu-20.04-x86_64.tar.xz' - - name: llvm-mingw-20231003-ucrt - llvm_version: 17.0.2 - url: 'https://github.com/mstorsjo/llvm-mingw/releases/download/20231003/llvm-mingw-20231003-ucrt-ubuntu-20.04-x86_64.tar.xz' + - name: llvm-mingw-20231017-msvcrt + llvm_version: 17.0.3 + url: 'https://github.com/mstorsjo/llvm-mingw/releases/download/20231017/llvm-mingw-20231017-msvcrt-ubuntu-20.04-x86_64.tar.xz' + - name: llvm-mingw-20231017-ucrt + llvm_version: 17.0.3 + url: 'https://github.com/mstorsjo/llvm-mingw/releases/download/20231017/llvm-mingw-20231017-ucrt-ubuntu-20.04-x86_64.tar.xz' name: ${{ format('{0} {1}', matrix.name, matrix.llvm_version) }} runs-on: ubuntu-latest steps: diff --git a/.github/workflows/weekly-ci-cc-zigcc.yml b/.github/workflows/weekly-ci-cc-zigcc.yml index b6d23d97..53192236 100644 --- a/.github/workflows/weekly-ci-cc-zigcc.yml +++ b/.github/workflows/weekly-ci-cc-zigcc.yml @@ -10,8 +10,8 @@ on: env: CMAKE_REQUIRED_QUIET: OFF DEBIAN_FRONTEND: noninteractive - # 2023-10-12 - ZIG_DIST_VERSION: 0.12.0-dev.890+8c6b0271c + # 2023-10-21 + ZIG_DIST_VERSION: 0.12.0-dev.1137+fbbccc9d5 jobs: job-linux-zigcc: # uses cmake + make diff --git a/CMakeLists.txt b/CMakeLists.txt index d8a52c74..abaa2610 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -189,13 +189,13 @@ else() set(warn_WX -WX) endif() if(MSVC_FRONTEND) - # disable warning C5105 which may get triggered by some versions of + # disable warning C5105 which may get triggered by some older versions of set(warn_WX -wd5105 ${warn_WX}) endif() function(upx_add_definitions_with_prefix) set(flag_prefix "${ARGV0}") - if(flag_prefix MATCHES "^dummy$") # need dummy to work around bug in old CMake versions + if(flag_prefix MATCHES "^empty$") # need "empty" to work around bug in old CMake versions set(flag_prefix "") endif() list(REMOVE_AT ARGV 0) @@ -219,9 +219,9 @@ function(upx_add_definitions) 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}) + upx_add_definitions_with_prefix("empty" ${failed_flags}) else() - upx_add_definitions_with_prefix("dummy" ${ARGV}) + upx_add_definitions_with_prefix("empty" ${ARGV}) endif() endfunction() diff --git a/misc/podman/rebuild-stubs/Dockerfile b/misc/podman/rebuild-stubs/Dockerfile index b0e1f33f..b40e3dc7 100644 --- a/misc/podman/rebuild-stubs/Dockerfile +++ b/misc/podman/rebuild-stubs/Dockerfile @@ -16,6 +16,7 @@ RUN dpkg --add-architecture i386 \ 7zip bfs busybox bzip2 cabextract ccache chrpath cmake cpio curl elfutils fd-find file fzf \ g++ gawk gdb gojq ht htop hyperfine jq libzstd-dev lsb-release lz4 lzip lzop \ mksh moreutils ninja-build p7zip parallel patch patchelf pax-utils paxctl \ + python3 python3-pyasn1 python3-pycryptodome python3-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": g++-multilib gcc-multilib \ diff --git a/misc/podman/rebuild-stubs/packages.txt b/misc/podman/rebuild-stubs/packages.txt index 63dd6f33..88774852 100644 --- a/misc/podman/rebuild-stubs/packages.txt +++ b/misc/podman/rebuild-stubs/packages.txt @@ -26,7 +26,7 @@ ii coreutils 8.32-4.1ubuntu1 amd64 ii cpio 2.13+dfsg-7 amd64 GNU cpio -- a program to manage archives of files ii cpp 4:11.2.0-1ubuntu1 amd64 GNU C preprocessor (cpp) ii cpp-11 11.4.0-1ubuntu1~22.04 amd64 GNU C preprocessor -ii curl 7.81.0-1ubuntu1.13 amd64 command line tool for transferring data with URL syntax +ii curl 7.81.0-1ubuntu1.14 amd64 command line tool for transferring data with URL syntax ii dash 0.5.11+git20210903+057cd650a4ed-3build1 amd64 POSIX-compliant shell ii debconf 1.5.79ubuntu1 all Debian configuration management system ii debianutils 5.5-1ubuntu2 amd64 Miscellaneous utilities specific to Debian @@ -95,15 +95,15 @@ ii libbrotli1:amd64 1.0.9-2build6 amd64 ii libbsd0:amd64 0.11.5-1 amd64 utility functions from BSD systems - shared library ii libbz2-1.0:amd64 1.0.8-5build1 amd64 high-quality block-sorting file compressor library - runtime ii libc-ares2:amd64 1.18.1-1ubuntu0.22.04.2 amd64 asynchronous name resolver -ii libc-bin 2.35-0ubuntu3.3 amd64 GNU C Library: Binaries -ii libc-dev-bin 2.35-0ubuntu3.3 amd64 GNU C Library: Development binaries -ii libc6-dev-i386 2.35-0ubuntu3.3 amd64 GNU C Library: 32-bit development libraries for AMD64 -ii libc6-dev-x32 2.35-0ubuntu3.3 amd64 GNU C Library: X32 ABI Development Libraries for AMD64 -ii libc6-dev:amd64 2.35-0ubuntu3.3 amd64 GNU C Library: Development Libraries and Header Files -ii libc6-i386 2.35-0ubuntu3.3 amd64 GNU C Library: 32-bit shared libraries for AMD64 -ii libc6-x32 2.35-0ubuntu3.3 amd64 GNU C Library: X32 ABI Shared libraries for AMD64 -ii libc6:amd64 2.35-0ubuntu3.3 amd64 GNU C Library: Shared libraries -ii libc6:i386 2.35-0ubuntu3.3 i386 GNU C Library: Shared libraries +ii libc-bin 2.35-0ubuntu3.4 amd64 GNU C Library: Binaries +ii libc-dev-bin 2.35-0ubuntu3.4 amd64 GNU C Library: Development binaries +ii libc6-dev-i386 2.35-0ubuntu3.4 amd64 GNU C Library: 32-bit development libraries for AMD64 +ii libc6-dev-x32 2.35-0ubuntu3.4 amd64 GNU C Library: X32 ABI Development Libraries for AMD64 +ii libc6-dev:amd64 2.35-0ubuntu3.4 amd64 GNU C Library: Development Libraries and Header Files +ii libc6-i386 2.35-0ubuntu3.4 amd64 GNU C Library: 32-bit shared libraries for AMD64 +ii libc6-x32 2.35-0ubuntu3.4 amd64 GNU C Library: X32 ABI Shared libraries for AMD64 +ii libc6:amd64 2.35-0ubuntu3.4 amd64 GNU C Library: Shared libraries +ii libc6:i386 2.35-0ubuntu3.4 i386 GNU C Library: Shared libraries ii libcap-ng0:amd64 0.7.9-2.2build3 amd64 An alternate POSIX capabilities library ii libcap2:amd64 1:2.44-1ubuntu0.22.04.1 amd64 POSIX 1003.1e capabilities (library) ii libcc1-0:amd64 12.3.0-1ubuntu1~22.04 amd64 GCC cc1 plugin for GDB @@ -113,8 +113,8 @@ ii libcrypt1:amd64 1:4.4.27-1 amd64 ii libcrypt1:i386 1:4.4.27-1 i386 libcrypt shared library ii libctf-nobfd0:amd64 2.38-4ubuntu2.3 amd64 Compact C Type Format library (runtime, no BFD dependency) ii libctf0:amd64 2.38-4ubuntu2.3 amd64 Compact C Type Format library (runtime, BFD dependency) -ii libcurl3-gnutls:amd64 7.81.0-1ubuntu1.13 amd64 easy-to-use client-side URL transfer library (GnuTLS flavour) -ii libcurl4:amd64 7.81.0-1ubuntu1.13 amd64 easy-to-use client-side URL transfer library (OpenSSL flavour) +ii libcurl3-gnutls:amd64 7.81.0-1ubuntu1.14 amd64 easy-to-use client-side URL transfer library (GnuTLS flavour) +ii libcurl4:amd64 7.81.0-1ubuntu1.14 amd64 easy-to-use client-side URL transfer library (OpenSSL flavour) ii libdb5.3:amd64 5.3.28+dfsg1-0.8ubuntu3 amd64 Berkeley v5.3 Database Libraries [runtime] ii 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 @@ -234,8 +234,8 @@ ii libunistring2:amd64 1.0-1 amd64 ii libutempter0:amd64 1.2.1-2build2 amd64 privileged helper for utmp/wtmp updates (runtime) ii libuuid1:amd64 2.37.2-4ubuntu3 amd64 Universally Unique ID library ii libuv1:amd64 1.43.0-1 amd64 asynchronous event notification library - runtime library -ii libx11-6:amd64 2:1.7.5-1ubuntu0.2 amd64 X11 client-side library -ii libx11-data 2:1.7.5-1ubuntu0.2 all X11 client-side library +ii libx11-6:amd64 2:1.7.5-1ubuntu0.3 amd64 X11 client-side library +ii libx11-data 2:1.7.5-1ubuntu0.3 all X11 client-side library ii libx32asan6 11.4.0-1ubuntu1~22.04 amd64 AddressSanitizer -- a fast memory error detector (x32) ii libx32atomic1 12.3.0-1ubuntu1~22.04 amd64 support library providing __atomic built-in functions (x32) ii libx32gcc-11-dev 11.4.0-1ubuntu1~22.04 amd64 GCC support library (x32 development files) @@ -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 libzstd-dev:amd64 1.4.8+dfsg-3build1 amd64 fast lossless compression algorithm -- development files ii libzstd1:amd64 1.4.8+dfsg-3build1 amd64 fast lossless compression algorithm -ii linux-libc-dev:amd64 5.15.0-84.93 amd64 Linux Kernel Headers for development +ii linux-libc-dev:amd64 5.15.0-87.97 amd64 Linux Kernel Headers for development ii login 1:4.8.1-2ubuntu2.1 amd64 system login tools ii logsave 1.46.5-2ubuntu1.1 amd64 save the output of a command in a log file ii lsb-base 11.1.0ubuntu4 all Linux Standard Base init script functionality @@ -288,6 +288,9 @@ ii python2-minimal 2.7.18-3 amd64 ii python2.7-minimal 2.7.18-13ubuntu1.1 amd64 Minimal subset of the Python language (version 2.7) ii 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-pyasn1 0.4.8-1 all ASN.1 library for Python (Python 3 module) +ii python3-pycryptodome 3.11.0+dfsg1-3build1 amd64 cryptographic Python library (Python 3) +ii python3-zstd 1.5.0.2-1build1 amd64 python bindings to Yann Collet ZSTD compression library ii python3.10 3.10.12-1~22.04.2 amd64 Interactive high-level object-oriented language (version 3.10) ii python3.10-minimal 3.10.12-1~22.04.2 amd64 Minimal subset of the Python language (version 3.10) ii re2c 3.0-1 amd64 lexer generator for C, C++, Go and Rust @@ -308,11 +311,11 @@ ii universal-ctags 5.9.20210829.0-1 amd64 ii unzip 6.0-26ubuntu3.1 amd64 De-archiver for .zip files ii usrmerge 25ubuntu2 all Convert the system to the merged /usr directories scheme ii util-linux 2.37.2-4ubuntu3 amd64 miscellaneous system utilities -ii vim 2:8.2.3995-1ubuntu2.11 amd64 Vi IMproved - enhanced vi editor -ii vim-common 2:8.2.3995-1ubuntu2.11 all Vi IMproved - Common files -ii vim-runtime 2:8.2.3995-1ubuntu2.11 all Vi IMproved - Runtime files +ii vim 2:8.2.3995-1ubuntu2.12 amd64 Vi IMproved - enhanced vi editor +ii vim-common 2:8.2.3995-1ubuntu2.12 all Vi IMproved - Common files +ii vim-runtime 2:8.2.3995-1ubuntu2.12 all Vi IMproved - Runtime files ii wget 1.21.2-2ubuntu1 amd64 retrieves files from the web -ii xxd 2:8.2.3995-1ubuntu2.11 amd64 tool to make (or reverse) a hex dump +ii xxd 2:8.2.3995-1ubuntu2.12 amd64 tool to make (or reverse) a hex dump ii xz-utils 5.2.5-2ubuntu1 amd64 XZ-format compression utilities ii yash 2.51-1 amd64 yet another shell ii zip 3.0-12build2 amd64 Archiver for .zip files @@ -327,7 +330,7 @@ ii zstd 1.4.8+dfsg-3build1 amd64 ||/ Name Version Architecture Description Packages sorted by Installed-Size: - 749380 ===== TOTAL (321 packages) + 754072 ===== TOTAL (324 packages) 52747 gcc-11 amd64 34444 libicu70 amd64 32781 vim-runtime all @@ -355,12 +358,12 @@ Packages sorted by Installed-Size: 7948 lib32gcc-11-dev amd64 7730 perl-base amd64 7518 libasan6 amd64 - 7261 libc6-dev-i386 amd64 + 7262 libc6-dev-i386 amd64 7255 libtsan0 amd64 7128 libmagic-mgc amd64 7112 coreutils amd64 6988 libx32gcc-11-dev amd64 - 6781 linux-libc-dev amd64 + 6795 linux-libc-dev amd64 6733 dpkg amd64 6667 lib32asan6 amd64 6570 libx32asan6 amd64 @@ -374,6 +377,7 @@ Packages sorted by Installed-Size: 4082 libglib2.0-0 amd64 3925 vim amd64 3643 python2.7-minimal amd64 + 3542 python3-pycryptodome amd64 3506 re2c amd64 3487 gojq amd64 3405 libmpfr6 amd64 @@ -417,10 +421,10 @@ Packages sorted by Installed-Size: 1472 sysstat amd64 1464 bash-completion all 1445 hyperfine amd64 + 1430 libx11-data all 1429 yash amd64 - 1429 libx11-data all 1388 procps amd64 - 1386 libx11-6 amd64 + 1387 libx11-6 amd64 1354 libgcrypt20 amd64 1343 ccache amd64 1328 libzstd-dev amd64 @@ -440,6 +444,7 @@ Packages sorted by Installed-Size: 787 libcurl4 amd64 784 libbrotli1 amd64 771 libcurl3-gnutls amd64 + 743 python3-zstd amd64 735 libsepol2 amd64 729 libdw1 amd64 720 libtirpc-dev amd64 @@ -475,6 +480,7 @@ Packages sorted by Installed-Size: 402 libsodium23 amd64 394 base-files amd64 393 ncurses-base all + 390 python3-pyasn1 all 390 ca-certificates all 389 mount amd64 382 libmount1 amd64 diff --git a/src/check/dt_xspan.cpp b/src/check/dt_xspan.cpp index e706ae5c..78b6ea31 100644 --- a/src/check/dt_xspan.cpp +++ b/src/check/dt_xspan.cpp @@ -64,7 +64,7 @@ TEST_CASE("raw_bytes bounded array") { **************************************************************************/ TEST_CASE("basic xspan usage") { - char buf[4] = {0, 1, 2, 3}; + alignas(4) char buf[4] = {0, 1, 2, 3}; SUBCASE("XSPAN_x") { XSPAN_0(char) a0 = nullptr; @@ -114,6 +114,28 @@ TEST_CASE("basic xspan usage") { CHECK_THROWS(raw_bytes(cs, 5)); CHECK_THROWS(raw_index_bytes(cs, 1, 4)); #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") { @@ -171,6 +193,28 @@ TEST_CASE("basic xspan usage") { CHECK_THROWS(raw_bytes(cs, 5)); CHECK_THROWS(raw_index_bytes(cs, 1, 4)); #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") { diff --git a/src/conf.h b/src/conf.h index 3bf9883f..a946292b 100644 --- a/src/conf.h +++ b/src/conf.h @@ -107,7 +107,8 @@ inline constexpr bool upx_is_integral_v = upx_is_integral::value; #if (ACC_ARCH_M68K && ACC_OS_TOS && ACC_CC_GNUC) && defined(__MINT__) // horrible hack for broken compiler / ABI #define upx_fake_alignas_1 __attribute__((__aligned__(1),__packed__)) -#define upx_fake_alignas_4 __attribute__((__aligned__(2))) +#define upx_fake_alignas_2 __attribute__((__aligned__(2))) +#define upx_fake_alignas_4 __attribute__((__aligned__(2))) // object file maximum 2 ??? #define upx_fake_alignas_16 __attribute__((__aligned__(2))) // object file maximum 2 ??? #define upx_fake_alignas__(x) upx_fake_alignas_ ## x #define alignas(x) upx_fake_alignas__(x) diff --git a/src/pefile.cpp b/src/pefile.cpp index fa2850ec..cba67de1 100644 --- a/src/pefile.cpp +++ b/src/pefile.cpp @@ -335,8 +335,8 @@ PeFile::Reloc::Reloc(unsigned relocnum) { void PeFile::Reloc::initSpans() { start_buf = SPAN_S_MAKE(byte, start, start_size_in_bytes); - rel = SPAN_S_CAST(BaseReloc, start_buf); - rel1 = SPAN_S_CAST(LE16, start_buf); + rel = SPAN_TYPE_CAST(BaseReloc, start_buf); + rel1 = SPAN_TYPE_CAST(LE16, start_buf); rel = nullptr; rel1 = nullptr; } @@ -366,7 +366,7 @@ bool PeFile::Reloc::next(unsigned &result_pos, unsigned &result_type) { pos = rel->pagestart + (*rel1 & 0xfff); type = *rel1++ >> 12; NO_printf("%x %d\n", pos, type); - if (ptr_udiff_bytes(raw_bytes(rel1, 0), rel) >= rel->size_of_block) + if (ptr_udiff_bytes(rel1, rel) >= rel->size_of_block) advanceBaseRelocPos(raw_bytes(rel1, 0)); } while (type == 0); result_pos = pos; @@ -380,7 +380,7 @@ void PeFile::Reloc::add(unsigned pos, unsigned type) { counts[0] += 1; } -void PeFile::Reloc::finish(byte *&result_ptr, unsigned &result_size) { +void PeFile::Reloc::finish(byte *(&result_ptr), unsigned &result_size) { assert(start_did_alloc); // sentinel to force final advanceBaseRelocPos() set_le32(start_buf + (RELOC_BUF_OFFSET + 4 * counts[0]), 0xfff00000); @@ -392,32 +392,37 @@ void PeFile::Reloc::finish(byte *&result_ptr, unsigned &result_size) { rel1 = nullptr; unsigned prev = 0xffffffff; for (unsigned ic = 0; ic < counts[0]; ic++) { - unsigned pos = get_le32(start_buf + (RELOC_BUF_OFFSET + 4 * ic)); + const unsigned pos = get_le32(start_buf + (RELOC_BUF_OFFSET + 4 * ic)); + if (rel == (BaseReloc *) (void *) start) + if (ptr_udiff_bytes(rel1, rel) > RELOC_BUF_OFFSET - sizeof(*rel1)) + throwCantPack("too many relocs"); if (ic == 0) { prev = pos; advanceBaseRelocPos(start); rel->pagestart = (pos >> 4) & ~0xfff; - rel->size_of_block = 0; // to be filled later + rel->size_of_block = unsigned(-1); // to be filled later } else if ((pos ^ prev) >= 0x10000) { prev = pos; - *rel1 = 0; // clear align-up memory - rel->size_of_block = ALIGN_UP(ptr_udiff_bytes(raw_bytes(rel1, 0), rel), 4u); + *rel1 = 0; // clear align-up memory + rel->size_of_block = ALIGN_UP(ptr_udiff_bytes(rel1, rel), 4u); // <= FILL advanceBaseRelocPos((char *) raw_bytes(rel, rel->size_of_block) + rel->size_of_block); rel->pagestart = (pos >> 4) & ~0xfff; - rel->size_of_block = 0; + rel->size_of_block = unsigned(-1); // to be filled later } *rel1++ = (pos << 12) + ((pos >> 4) & 0xfff); } - assert(ptr_udiff_bytes(raw_bytes(rel1, 0), rel) == 10); // sentinel + assert(ptr_udiff_bytes(rel1, rel) == 10); // sentinel result_size = ptr_udiff_bytes(rel, start); assert((result_size & 3) == 0); // assert(result_size > 0); // result_size can be 0 in 64-bit mode // transfer ownership assert(start_did_alloc); result_ptr = start; - start = nullptr; // safety - start_buf = nullptr; // safety + start = nullptr; start_did_alloc = false; + SPAN_INVALIDATE(start_buf); // safety + SPAN_INVALIDATE(rel); // safety + SPAN_INVALIDATE(rel1); // safety } void PeFile::processRelocs(Reloc *rel) // pass2 @@ -2673,7 +2678,7 @@ void PeFile::rebuildRelocs(SPAN_S(byte) & extra_info, unsigned bits, unsigned fl unsigned relocnum = unoptimizeReloc(rdata, mb_wrkmem, obuf, orig_crelocs, bits, true); unsigned r16 = 0; if (big & 6) { // count 16 bit relocations - SPAN_S_VAR(const LE32, q, SPAN_S_CAST(const LE32, rdata)); + SPAN_S_VAR(const LE32, q, SPAN_TYPE_CAST(const LE32, rdata)); while (*q++) r16++; if ((big & 6) == 6) @@ -2682,7 +2687,7 @@ void PeFile::rebuildRelocs(SPAN_S(byte) & extra_info, unsigned bits, unsigned fl } Reloc rel(relocnum + r16); if (big & 6) { // add 16 bit relocations - SPAN_S_VAR(const LE32, q, SPAN_S_CAST(const LE32, rdata)); + SPAN_S_VAR(const LE32, q, SPAN_TYPE_CAST(const LE32, rdata)); while (*q) rel.add(*q++ + rvamin, (big & 4) ? 2 : 1); if ((big & 6) == 6) diff --git a/src/pefile.h b/src/pefile.h index 9314e381..6d625c66 100644 --- a/src/pefile.h +++ b/src/pefile.h @@ -410,7 +410,7 @@ protected: const unsigned *getcounts() const { return counts; } // void add(unsigned pos, unsigned type); - void finish(byte *&result_ptr, unsigned &result_size); // => transfer ownership + void finish(byte *(&result_ptr), unsigned &result_size); // => transfer ownership }; class Resource : private noncopyable { diff --git a/src/util/util.h b/src/util/util.h index bfc7331b..6a6259ba 100644 --- a/src/util/util.h +++ b/src/util/util.h @@ -125,6 +125,16 @@ forceinline void ptr_check_no_overlap(const void *a, size_t a_size, const void * (upx_uintptr_t) c, c_size); } +// invalidate and poison a pointer: point to a non-null invalid address +// - resulting pointer should crash on dereference +// - this should be efficient, so no mmap() guard page etc. +// - this should play nice with runtime checkers like ASAN, MSAN, valgrind, etc. +// - this should play nice with static analyzers like clang-tidy etc. +template +inline void ptr_invalidate_and_poison(T *(&ptr)) noexcept { + ptr = (T *) (void *) 251; // 0x000000fb // NOLINT(performance-no-int-to-ptr) +} + /************************************************************************* // stdlib **************************************************************************/ diff --git a/src/util/xspan.h b/src/util/xspan.h index 21c257c1..0b51ac6f 100644 --- a/src/util/xspan.h +++ b/src/util/xspan.h @@ -96,9 +96,9 @@ using XSPAN_NAMESPACE_NAME::raw_index_bytes; // overloaded for all classes #define XSPAN_S_VAR(type, var, first, ...) XSPAN_S(type) var((first), ##__VA_ARGS__) // cast to a different type (creates a new value) -#define XSPAN_0_CAST(type, var) ((var).type_cast()) -#define XSPAN_P_CAST(type, var) ((var).type_cast()) -#define XSPAN_S_CAST(type, var) ((var).type_cast()) +#define XSPAN_TYPE_CAST(type, x) ((x).type_cast()) +// poison a pointer: point to a non-null invalid address +#define XSPAN_INVALIDATE(x) ((x).invalidate()) #elif WITH_XSPAN >= 1 @@ -120,9 +120,9 @@ using XSPAN_NAMESPACE_NAME::raw_index_bytes; // overloaded for all classes #define XSPAN_S_VAR(type, var, first, ...) XSPAN_S(type) var((first)) // cast to a different type (creates a new value) -#define XSPAN_0_CAST(type, var) ((var).type_cast()) -#define XSPAN_P_CAST(type, var) ((var).type_cast()) -#define XSPAN_S_CAST(type, var) ((var).type_cast()) +#define XSPAN_TYPE_CAST(type, x) ((x).type_cast()) +// poison a pointer: point to a non-null invalid address +#define XSPAN_INVALIDATE(x) ((x).invalidate()) #else // WITH_XSPAN @@ -158,9 +158,9 @@ inline R *xspan_make_helper__(R * /*dummy*/, MemBuffer &mb) noexcept { #define XSPAN_S_VAR(type, var, first, ...) type *var = XSPAN_S_MAKE(type, (first)) // cast to a different type (creates a new value) -#define XSPAN_0_CAST(type, var) ((type *) (var)) -#define XSPAN_P_CAST(type, var) ((type *) (var)) -#define XSPAN_S_CAST(type, var) ((type *) (var)) +#define XSPAN_TYPE_CAST(type, x) (reinterpret_cast(x)) +// poison a pointer: point to a non-null invalid address +#define XSPAN_INVALIDATE(x) ptr_invalidate_and_poison(x) #endif // WITH_XSPAN @@ -170,21 +170,21 @@ inline R *xspan_make_helper__(R * /*dummy*/, MemBuffer &mb) noexcept { #if 1 // types -#define SPAN_0 XSPAN_0 -#define SPAN_P XSPAN_P -#define SPAN_S XSPAN_S +#define SPAN_0 XSPAN_0 +#define SPAN_P XSPAN_P +#define SPAN_S XSPAN_S // create a value -#define SPAN_0_MAKE XSPAN_0_MAKE -#define SPAN_P_MAKE XSPAN_P_MAKE -#define SPAN_S_MAKE XSPAN_S_MAKE +#define SPAN_0_MAKE XSPAN_0_MAKE +#define SPAN_P_MAKE XSPAN_P_MAKE +#define SPAN_S_MAKE XSPAN_S_MAKE // define a variable -#define SPAN_0_VAR XSPAN_0_VAR -#define SPAN_P_VAR XSPAN_P_VAR -#define SPAN_S_VAR XSPAN_S_VAR +#define SPAN_0_VAR XSPAN_0_VAR +#define SPAN_P_VAR XSPAN_P_VAR +#define SPAN_S_VAR XSPAN_S_VAR // cast to a different type (creates a new value) -#define SPAN_0_CAST XSPAN_0_CAST -#define SPAN_P_CAST XSPAN_P_CAST -#define SPAN_S_CAST XSPAN_S_CAST +#define SPAN_TYPE_CAST XSPAN_TYPE_CAST +// poison a pointer: point to a non-null invalid address +#define SPAN_INVALIDATE XSPAN_INVALIDATE #endif /* vim:set ts=4 sw=4 et: */ diff --git a/src/util/xspan_fwd.h b/src/util/xspan_fwd.h index 752787d3..87d7081c 100644 --- a/src/util/xspan_fwd.h +++ b/src/util/xspan_fwd.h @@ -34,15 +34,62 @@ // #define XSPAN_REQUIRES_CONVERTIBLE_ANY_DIRECTION(A, B, RType) // std::enable_if_t || std::is_convertible_v, RType> -#define XSPAN_FWD_TU(RType) \ +// requires convertible T to U, or U to T +#define XSPAN_FWD_TU_CONVERTIBLE(RType) \ template \ inline XSPAN_REQUIRES_CONVERTIBLE_ANY_DIRECTION(T, U, RType) +// any pointer type, matching automatic conversion to "void *" +#define XSPAN_FWD_TU_VOIDPTR(RType) \ + template \ + inline RType + +/************************************************************************* +// overloads of global operators +**************************************************************************/ #ifndef XSPAN_FWD_C_IS_MEMBUFFER + // global operator: disallow "n + C" => force using "C + n" (member function) instead template inline typename std::enable_if::value, void *>::type operator+(U, const C &) XSPAN_DELETED_FUNCTION; + +#if 0 // handled by member functions +XSPAN_FWD_TU_CONVERTIBLE(bool) operator==(const C &a, const U *b) { + return a.raw_bytes(0) == b; +} +XSPAN_FWD_TU_CONVERTIBLE(bool) operator==(const C &a, const C &b) { + return a.raw_bytes(0) == b.raw_bytes(0); +} +#ifdef D +XSPAN_FWD_TU_CONVERTIBLE(bool) operator==(const C &a, const D &b) { + return a.raw_bytes(0) == b.raw_bytes(0); +} +#endif +#ifdef E +XSPAN_FWD_TU_CONVERTIBLE(bool) operator==(const C &a, const E &b) { + return a.raw_bytes(0) == b.raw_bytes(0); +} +#endif + +XSPAN_FWD_TU_CONVERTIBLE(bool) operator!=(const C &a, const U *b) { + return a.raw_bytes(0) != b; +} +XSPAN_FWD_TU_CONVERTIBLE(bool) operator!=(const C &a, const C &b) { + return a.raw_bytes(0) != b.raw_bytes(0); +} +#ifdef D +XSPAN_FWD_TU_CONVERTIBLE(bool) operator!=(const C &a, const D &b) { + return a.raw_bytes(0) != b.raw_bytes(0); +} +#endif +#ifdef E +XSPAN_FWD_TU_CONVERTIBLE(bool) operator!=(const C &a, const E &b) { + return a.raw_bytes(0) != b.raw_bytes(0); +} +#endif +#endif // if 0 // handled by member functions + #endif // XSPAN_FWD_C_IS_MEMBUFFER /************************************************************************* @@ -66,16 +113,16 @@ template inline int memcmp(const void *a, const C &b, size_t n) { return memcmp(a, b.raw_bytes(n), n); } -XSPAN_FWD_TU(int) memcmp(const C &a, const C &b, size_t n) { +XSPAN_FWD_TU_VOIDPTR(int) memcmp(const C &a, const C &b, size_t n) { return memcmp(a.raw_bytes(n), b.raw_bytes(n), n); } #ifdef D -XSPAN_FWD_TU(int) memcmp(const C &a, const D &b, size_t n) { +XSPAN_FWD_TU_VOIDPTR(int) memcmp(const C &a, const D &b, size_t n) { return memcmp(a.raw_bytes(n), b.raw_bytes(n), n); } #endif #ifdef E -XSPAN_FWD_TU(int) memcmp(const C &a, const E &b, size_t n) { +XSPAN_FWD_TU_VOIDPTR(int) memcmp(const C &a, const E &b, size_t n) { return memcmp(a.raw_bytes(n), b.raw_bytes(n), n); } #endif @@ -88,16 +135,16 @@ template inline void *memcpy(void *a, const C &b, size_t n) { return memcpy(a, b.raw_bytes(n), n); } -XSPAN_FWD_TU(void *) memcpy(const C &a, const C &b, size_t n) { +XSPAN_FWD_TU_VOIDPTR(void *) memcpy(const C &a, const C &b, size_t n) { return memcpy(a.raw_bytes(n), b.raw_bytes(n), n); } #ifdef D -XSPAN_FWD_TU(void *) memcpy(const C &a, const D &b, size_t n) { +XSPAN_FWD_TU_VOIDPTR(void *) memcpy(const C &a, const D &b, size_t n) { return memcpy(a.raw_bytes(n), b.raw_bytes(n), n); } #endif #ifdef E -XSPAN_FWD_TU(void *) memcpy(const C &a, const E &b, size_t n) { +XSPAN_FWD_TU_VOIDPTR(void *) memcpy(const C &a, const E &b, size_t n) { return memcpy(a.raw_bytes(n), b.raw_bytes(n), n); } #endif @@ -110,16 +157,16 @@ template inline void *memmove(void *a, const C &b, size_t n) { return memmove(a, b.raw_bytes(n), n); } -XSPAN_FWD_TU(void *) memmove(const C &a, const C &b, size_t n) { +XSPAN_FWD_TU_VOIDPTR(void *) memmove(const C &a, const C &b, size_t n) { return memmove(a.raw_bytes(n), b.raw_bytes(n), n); } #ifdef D -XSPAN_FWD_TU(void *) memmove(const C &a, const D &b, size_t n) { +XSPAN_FWD_TU_VOIDPTR(void *) memmove(const C &a, const D &b, size_t n) { return memmove(a.raw_bytes(n), b.raw_bytes(n), n); } #endif #ifdef E -XSPAN_FWD_TU(void *) memmove(const C &a, const E &b, size_t n) { +XSPAN_FWD_TU_VOIDPTR(void *) memmove(const C &a, const E &b, size_t n) { return memmove(a.raw_bytes(n), b.raw_bytes(n), n); } #endif @@ -141,16 +188,16 @@ template inline int ptr_diff_bytes(const void *a, const C &b) { return ptr_diff_bytes(a, b.raw_bytes(0)); } -XSPAN_FWD_TU(int) ptr_diff_bytes(const C &a, const C &b) { +XSPAN_FWD_TU_VOIDPTR(int) ptr_diff_bytes(const C &a, const C &b) { return ptr_diff_bytes(a.raw_bytes(0), b.raw_bytes(0)); } #ifdef D -XSPAN_FWD_TU(int) ptr_diff_bytes(const C &a, const D &b) { +XSPAN_FWD_TU_VOIDPTR(int) ptr_diff_bytes(const C &a, const D &b) { return ptr_diff_bytes(a.raw_bytes(0), b.raw_bytes(0)); } #endif #ifdef E -XSPAN_FWD_TU(int) ptr_diff_bytes(const C &a, const E &b) { +XSPAN_FWD_TU_VOIDPTR(int) ptr_diff_bytes(const C &a, const E &b) { return ptr_diff_bytes(a.raw_bytes(0), b.raw_bytes(0)); } #endif @@ -163,16 +210,16 @@ template inline unsigned ptr_udiff_bytes(const void *a, const C &b) { return ptr_udiff_bytes(a, b.raw_bytes(0)); } -XSPAN_FWD_TU(unsigned) ptr_udiff_bytes(const C &a, const C &b) { +XSPAN_FWD_TU_VOIDPTR(unsigned) ptr_udiff_bytes(const C &a, const C &b) { return ptr_udiff_bytes(a.raw_bytes(0), b.raw_bytes(0)); } #ifdef D -XSPAN_FWD_TU(unsigned) ptr_udiff_bytes(const C &a, const D &b) { +XSPAN_FWD_TU_VOIDPTR(unsigned) ptr_udiff_bytes(const C &a, const D &b) { return ptr_udiff_bytes(a.raw_bytes(0), b.raw_bytes(0)); } #endif #ifdef E -XSPAN_FWD_TU(unsigned) ptr_udiff_bytes(const C &a, const E &b) { +XSPAN_FWD_TU_VOIDPTR(unsigned) ptr_udiff_bytes(const C &a, const E &b) { return ptr_udiff_bytes(a.raw_bytes(0), b.raw_bytes(0)); } #endif @@ -180,7 +227,7 @@ XSPAN_FWD_TU(unsigned) ptr_udiff_bytes(const C &a, const E &b) { #ifdef UPX_VERSION_HEX template -inline unsigned upx_adler32(const C &a, unsigned n, unsigned adler = 1) { +unsigned upx_adler32(const C &a, unsigned n, unsigned adler = 1) { return upx_adler32(a.raw_bytes(n), n, adler); } @@ -316,6 +363,7 @@ typename std::enable_if::type upx_safe_strlen(const #endif // UPX_VERSION_HEX -#undef XSPAN_FWD_TU +#undef XSPAN_FWD_TU_CONVERTIBLE +#undef XSPAN_FWD_TU_VOIDPTR /* vim:set ts=4 sw=4 et: */ diff --git a/src/util/xspan_impl.h b/src/util/xspan_impl.h index c3cba4c8..80fff7fb 100644 --- a/src/util/xspan_impl.h +++ b/src/util/xspan_impl.h @@ -200,7 +200,7 @@ class XSpanInternalDummyArgFake; // not implemented on purpose typedef XSpanInternalDummyArgFake *XSpanInternalDummyArg; #define XSpanInternalDummyArgInit nullptr #elif __cplusplus >= 201103L && 1 -// use an enum +// use an enum and a move constructor struct XSpanInternalDummyArg final { enum DummyEnum {}; explicit forceinline_constexpr XSpanInternalDummyArg(DummyEnum &&) noexcept {} @@ -220,16 +220,6 @@ private: (XSPAN_NS(XSpanInternalDummyArg)(XSPAN_NS(XSpanInternalDummyArg)::make())) #endif -// poison a pointer: point to a non-null invalid address -// - resulting pointer should crash on dereference -// - this should be efficient (so no mmap() guard page etc.) -// - this should play nice with runtime checkers like ASAN, MSAN, valgrind, etc. -// - this should play nice with static analyzers like clang-tidy etc. -static forceinline void *XSPAN_GET_POISON_VOID_PTR() noexcept { - // return (void *) (upx_uintptr_t) 251; // NOLINT(performance-no-int-to-ptr) - return (void *) 251; -} - XSPAN_NAMESPACE_END #ifndef XSPAN_DELETED_FUNCTION diff --git a/src/util/xspan_impl_common.h b/src/util/xspan_impl_common.h index 1fb0120c..aff1f194 100644 --- a/src/util/xspan_impl_common.h +++ b/src/util/xspan_impl_common.h @@ -114,10 +114,8 @@ forceinline ~CSelf() noexcept {} #endif noinline void invalidate() { assertInvariants(); - // poison the pointer: point to non-null invalid address - ptr = (pointer) XSPAN_GET_POISON_VOID_PTR(); - // ptr = (pointer) (void *) &ptr; // point to self - base = ptr; + ptr_invalidate_and_poison(ptr); // point to non-null invalid address + base = ptr; // point to non-null invalid address size_in_bytes = 0; assertInvariants(); } @@ -283,11 +281,11 @@ public: } template - CSelf type_cast() const { - assertInvariants(); + inline CSelf type_cast() const { typedef CSelf R; - return R(R::Unchecked, reinterpret_cast(ptr), size_in_bytes, - reinterpret_cast(base)); + typedef typename R::pointer rpointer; + return R(R::Unchecked, reinterpret_cast(ptr), size_in_bytes, + reinterpret_cast(base)); } bool operator==(pointer other) const { return ptr == other; } diff --git a/src/util/xspan_impl_ptr.h b/src/util/xspan_impl_ptr.h index 0450c83b..b3ce3ada 100644 --- a/src/util/xspan_impl_ptr.h +++ b/src/util/xspan_impl_ptr.h @@ -77,9 +77,7 @@ public: #endif noinline void invalidate() { assertInvariants(); - // poison the pointer: point to non-null invalid address - ptr = (pointer) XSPAN_GET_POISON_VOID_PTR(); - // ptr = (pointer) (void *) &ptr; // point to self + ptr_invalidate_and_poison(ptr); // point to non-null invalid address assertInvariants(); } inline CSelf() { assertInvariants(); } @@ -126,10 +124,10 @@ public: } template - CSelf type_cast() const { - assertInvariants(); + inline CSelf type_cast() const { typedef CSelf R; - return R(reinterpret_cast(ptr)); + typedef typename R::pointer rpointer; + return R(reinterpret_cast(ptr)); } // comparison