diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 1542d3df..73937e4d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -378,8 +378,8 @@ jobs: - { zig_target: x86_64-macos.13-none } - { zig_target: x86_64-windows-gnu } env: - # 2023-05-02 - ZIG_DIST_VERSION: 0.11.0-dev.2939+289234744 + # 2023-05-06 + ZIG_DIST_VERSION: 0.11.0-dev.2991+9f3f9fb40 # for zig-cc wrapper scripts (see below): ZIG_CPPFLAGS: -DUPX_DOCTEST_CONFIG_MULTITHREADING ZIG_FLAGS: ${{ matrix.zig_flags }} diff --git a/CMakeLists.txt b/CMakeLists.txt index 724de2ce..5511318a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -232,9 +232,8 @@ if(MSVC_FRONTEND) target_compile_options(${t} PRIVATE -W3 ${warn_WX}) else() target_compile_definitions(${t} PRIVATE HAVE_UNISTD_H=1) - # clang-15: -Wno-strict-prototypes is needed to silence the new -Wdeprecated-non-prototype warning - target_compile_options(${t} PRIVATE -Wall -Wno-strict-prototypes ${warn_Werror}) - ##target_compile_options(${t} PRIVATE ${warn_Wall} -Wno-cast-align -Wno-cast-qual -Wno-strict-prototypes ${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}) endif() if(NOT UPX_CONFIG_DISABLE_ZSTD) diff --git a/src/bele.h b/src/bele.h index 4c7f7aaf..0daf72b5 100644 --- a/src/bele.h +++ b/src/bele.h @@ -26,8 +26,6 @@ */ #pragma once -#ifndef UPX_BELE_H__ -#define UPX_BELE_H__ 1 // BE - Big Endian // LE - Little Endian @@ -753,6 +751,4 @@ inline const N_BELE_RTP::AbstractPolicy *getRTP(const LEPolicy * /*dummy*/) { } } // namespace N_BELE_CTP -#endif /* already included */ - /* vim:set ts=4 sw=4 et: */ diff --git a/src/bele_policy.h b/src/bele_policy.h index f1e8cf26..cfc11598 100644 --- a/src/bele_policy.h +++ b/src/bele_policy.h @@ -25,9 +25,7 @@ */ -#ifndef UPX_BELE_H__ -#error "this is an internal include file" -#endif +// this is an internal include file private to bele.h /************************************************************************* // diff --git a/src/conf.h b/src/conf.h index 711a3659..bdeb82f5 100644 --- a/src/conf.h +++ b/src/conf.h @@ -144,10 +144,10 @@ typedef unsigned char byte; #define upx_byte byte #define upx_bytep byte * typedef unsigned char uchar; -// use "charptr" when dealing with pointer arithmetics +// convention: use "charptr" when dealing with abstract pointer arithmetics #define charptr upx_charptr_unit_type * // upx_charptr_unit_type is some opaque type with sizeof(type) == 1 -struct alignas(1) upx_charptr_unit_type { char dummy; }; +struct alignas(1) upx_charptr_unit_type { char hidden__; }; ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(upx_charptr_unit_type) == 1) // using the system off_t was a bad idea even back in 199x... diff --git a/src/file.h b/src/file.h index ecf8627f..19203001 100644 --- a/src/file.h +++ b/src/file.h @@ -26,8 +26,6 @@ */ #pragma once -#ifndef UPX_FILE_H__ -#define UPX_FILE_H__ 1 /************************************************************************* // @@ -129,6 +127,4 @@ protected: upx_off_t bytes_written = 0; }; -#endif - /* vim:set ts=4 sw=4 et: */ diff --git a/src/main.cpp b/src/main.cpp index 0a749df1..dcc18563 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -87,8 +87,9 @@ static void do_exit(void) { static bool set_eec(int ec, int *eec) { if (ec == EXIT_FATAL) { *eec = EXIT_ERROR; - return 1; - } else if (ec < 0 || ec == EXIT_ERROR) { + return true; + } + if (ec < 0 || ec == EXIT_ERROR) { *eec = EXIT_ERROR; } else if (ec == EXIT_WARN) { if (!opt->ignorewarn) @@ -99,7 +100,7 @@ static bool set_eec(int ec, int *eec) { } else { assert(0); } - return 0; + return false; } bool main_set_exit_code(int ec) { return set_eec(ec, &exit_code); } @@ -632,22 +633,22 @@ static int do_option(int optc, const char *arg) { // CPU case 560: if (mfx_optarg && strcmp(mfx_optarg, "8086") == 0) - opt->cpu = opt->CPU_8086; + opt->cpu_x86 = opt->CPU_8086; else if (mfx_optarg && strcmp(mfx_optarg, "386") == 0) - opt->cpu = opt->CPU_386; + opt->cpu_x86 = opt->CPU_386; else if (mfx_optarg && strcmp(mfx_optarg, "486") == 0) - opt->cpu = opt->CPU_486; + opt->cpu_x86 = opt->CPU_486; else e_optarg(arg); break; case 561: - opt->cpu = opt->CPU_8086; + opt->cpu_x86 = opt->CPU_8086; break; case 563: - opt->cpu = opt->CPU_386; + opt->cpu_x86 = opt->CPU_386; break; case 564: - opt->cpu = opt->CPU_486; + opt->cpu_x86 = opt->CPU_486; break; // case 600: diff --git a/src/options.h b/src/options.h index aae90bea..1db78476 100644 --- a/src/options.h +++ b/src/options.h @@ -26,11 +26,9 @@ */ #pragma once -#ifndef UPX_OPTIONS_H__ -#define UPX_OPTIONS_H__ 1 struct Options; -extern Options *opt; +extern Options *opt; // global options, see class PackMaster for per-file local options #define options_t Options // old name #if WITH_THREADS @@ -38,10 +36,10 @@ extern std::mutex opt_lock_mutex; #endif /************************************************************************* -// globals +// command line options **************************************************************************/ -// options - command +// main command enum { CMD_NONE, CMD_COMPRESS, @@ -105,20 +103,20 @@ struct Options final { int overlay; // CRP - Compression Runtime Parameters (undocumented and subject to change) - // see struct XXX_compress_config_t - struct crp_t { + struct { lzma_compress_config_t crp_lzma; ucl_compress_config_t crp_ucl; zlib_compress_config_t crp_zlib; + zstd_compress_config_t crp_zstd; void reset() { crp_lzma.reset(); crp_ucl.reset(); crp_zlib.reset(); + crp_zstd.reset(); } - }; - crp_t crp; + } crp; - // CPU + // CPU options for i086/i386 enum { CPU_DEFAULT = 0, CPU_8086 = 1, @@ -126,7 +124,7 @@ struct Options final { CPU_386 = 3, CPU_486 = 4, }; - int cpu; + int cpu_x86; // options for various executable formats struct { @@ -172,6 +170,4 @@ struct Options final { void reset(); }; -#endif /* already included */ - /* vim:set ts=4 sw=4 et: */ diff --git a/src/p_com.cpp b/src/p_com.cpp index 232d0f7e..fbb558d5 100644 --- a/src/p_com.cpp +++ b/src/p_com.cpp @@ -88,7 +88,7 @@ void PackCom::addFilter16(int filter_id) { // clang-format off addLoader("CALLTR16", filter_id < 4 ? "CT16SUB0" : "", - filter_id < 4 ? "" : (opt->cpu == opt->CPU_8086 ? "CT16I086" : "CT16I286,CT16SUB0"), + filter_id < 4 ? "" : (opt->cpu_x86 == opt->CPU_8086 ? "CT16I086" : "CT16I286,CT16SUB0"), "CALLTRI2", getFormat() == UPX_F_DOS_COM ? "CORETURN" : ""); // clang-format on @@ -98,7 +98,7 @@ void PackCom::addFilter16(int filter_id) { "CALLTRI5", getFormat() == UPX_F_DOS_COM ? "CT16JEND" : "CT16JUL2", filter_id < 4 ? "CT16SUB1" : "", - filter_id < 4 ? "" : (opt->cpu == opt->CPU_8086 ? "CT16I087" : "CT16I287,CT16SUB1"), + filter_id < 4 ? "" : (opt->cpu_x86 == opt->CPU_8086 ? "CT16I087" : "CT16I287,CT16SUB1"), "CALLTRI6"); // clang-format on } diff --git a/src/p_exe.cpp b/src/p_exe.cpp index bf15a16e..5b58f7b0 100644 --- a/src/p_exe.cpp +++ b/src/p_exe.cpp @@ -186,18 +186,18 @@ void PackExe::buildLoader(const Filter *) { if (ph.method == M_NRV2B_8) addLoader("NRV2B16S", // decompressor ph.u_len > DI_LIMIT ? "N2B64K01" : "", "NRV2BEX1", - opt->cpu == opt->CPU_8086 ? "N2BX8601" : "N2B28601", "NRV2BEX2", - opt->cpu == opt->CPU_8086 ? "N2BX8602" : "N2B28602", "NRV2BEX3", + opt->cpu_x86 == opt->CPU_8086 ? "N2BX8601" : "N2B28601", "NRV2BEX2", + opt->cpu_x86 == opt->CPU_8086 ? "N2BX8602" : "N2B28602", "NRV2BEX3", ph.c_len > 0xffff ? "N2B64K02" : "", "NRV2BEX9"); else if (ph.method == M_NRV2D_8) addLoader("NRV2D16S", ph.u_len > DI_LIMIT ? "N2D64K01" : "", "NRV2DEX1", - opt->cpu == opt->CPU_8086 ? "N2DX8601" : "N2D28601", "NRV2DEX2", - opt->cpu == opt->CPU_8086 ? "N2DX8602" : "N2D28602", "NRV2DEX3", + opt->cpu_x86 == opt->CPU_8086 ? "N2DX8601" : "N2D28601", "NRV2DEX2", + opt->cpu_x86 == opt->CPU_8086 ? "N2DX8602" : "N2D28602", "NRV2DEX3", ph.c_len > 0xffff ? "N2D64K02" : "", "NRV2DEX9"); else if (ph.method == M_NRV2E_8) addLoader("NRV2E16S", ph.u_len > DI_LIMIT ? "N2E64K01" : "", "NRV2EEX1", - opt->cpu == opt->CPU_8086 ? "N2EX8601" : "N2E28601", "NRV2EEX2", - opt->cpu == opt->CPU_8086 ? "N2EX8602" : "N2E28602", "NRV2EEX3", + opt->cpu_x86 == opt->CPU_8086 ? "N2EX8601" : "N2E28601", "NRV2EEX2", + opt->cpu_x86 == opt->CPU_8086 ? "N2EX8602" : "N2E28602", "NRV2EEX3", ph.c_len > 0xffff ? "N2E64K02" : "", "NRV2EEX9"); else if M_IS_LZMA (ph.method) return; diff --git a/src/p_sys.cpp b/src/p_sys.cpp index 2ff40c68..46246cb7 100644 --- a/src/p_sys.cpp +++ b/src/p_sys.cpp @@ -64,7 +64,7 @@ void PackSys::buildLoader(const Filter *ft) { initLoader(stub_i086_dos16_sys, sizeof(stub_i086_dos16_sys)); // clang-format off addLoader("SYSMAIN1", - opt->cpu == opt->CPU_8086 ? "SYSI0861" : "SYSI2861", + opt->cpu_x86 == opt->CPU_8086 ? "SYSI0861" : "SYSI2861", "SYSMAIN2", ph.first_offset_found == 1 ? "SYSSBBBP" : "", ft->id ? "SYSCALLT" : "", @@ -78,7 +78,7 @@ void PackSys::buildLoader(const Filter *ft) { } // clang-format off addLoader("SYSMAIN5", - opt->cpu == opt->CPU_8086 ? "SYSI0862" : "SYSI2862", + opt->cpu_x86 == opt->CPU_8086 ? "SYSI0862" : "SYSI2862", "SYSJUMP1"); // clang-format on } diff --git a/src/p_wince_arm.cpp b/src/p_wince_arm.cpp index 4626a739..fb7f7a7b 100644 --- a/src/p_wince_arm.cpp +++ b/src/p_wince_arm.cpp @@ -118,7 +118,8 @@ bool PackWinCeArm::canPack() { if (ih.cpu != IMAGE_FILE_MACHINE_ARM && ih.cpu != IMAGE_FILE_MACHINE_THUMB) return false; use_thumb_stub |= ih.cpu == IMAGE_FILE_MACHINE_THUMB || (ih.entry & 1) == 1; - use_thumb_stub |= (opt->cpu == opt->CPU_8086); // FIXME + // FIXME later: don't misuse opt->cpu_x86, need an extra option for thumb + use_thumb_stub |= (opt->cpu_x86 == opt->CPU_8086); return true; } diff --git a/src/packer_f.cpp b/src/packer_f.cpp index f2b20d00..607834e6 100644 --- a/src/packer_f.cpp +++ b/src/packer_f.cpp @@ -90,7 +90,7 @@ void Packer::addFilter32(int filter_id) { "CALLTR13"); } if (0x80 == (filter_id & 0xF0)) { - bool const x386 = (opt->cpu <= opt->CPU_386); + bool const x386 = (opt->cpu_x86 <= opt->CPU_386); const unsigned n_mru = ph.n_mru ? 1 + ph.n_mru : 0; bool const mrupwr2 = (0 != n_mru) && 0 == ((n_mru - 1) & n_mru); const unsigned f_call = f80_call(filter_id); diff --git a/src/pefile.h b/src/pefile.h index 5a7e81fc..e932363c 100644 --- a/src/pefile.h +++ b/src/pefile.h @@ -334,7 +334,7 @@ protected: IMAGE_SUBSYSTEM_WINDOWS_BOOT_APPLICATION = 16, }; - // predefined resource types + // predefined Resource Types enum { RT_CURSOR = 1, RT_BITMAP, diff --git a/src/util/membuffer.cpp b/src/util/membuffer.cpp index 1da7ca5e..6da2a9dd 100644 --- a/src/util/membuffer.cpp +++ b/src/util/membuffer.cpp @@ -287,6 +287,37 @@ TEST_CASE("MemBuffer") { } } +TEST_CASE("MemBuffer global overloads") { + MemBuffer mb(1); + MemBuffer mb4(4); + mb.clear(); + mb4.clear(); + CHECK(memcmp(mb, "\x00", 1) == 0); + CHECK_THROWS(memcmp(mb, "\x00\x00", 2)); + CHECK_THROWS(memcmp("\x00\x00", mb, 2)); + CHECK_THROWS(memcmp(mb, mb4, 2)); + CHECK_THROWS(memcmp(mb4, mb, 2)); + CHECK_NOTHROW(memset(mb, 255, 1)); + CHECK_THROWS(memset(mb, 254, 2)); + CHECK(mb[0] == 255); + CHECK_THROWS(get_be16(mb)); + CHECK_THROWS(get_be32(mb)); + CHECK_THROWS(get_be64(mb)); + CHECK_THROWS(get_le16(mb)); + CHECK_THROWS(get_le32(mb)); + CHECK_THROWS(get_le64(mb)); + CHECK_NOTHROW(get_be16(mb4)); + CHECK_NOTHROW(get_be32(mb4)); + CHECK_THROWS(get_be64(mb4)); + CHECK_NOTHROW(get_le16(mb4)); + CHECK_NOTHROW(get_le32(mb4)); + CHECK_THROWS(get_le64(mb4)); + CHECK_NOTHROW(set_be32(mb4, 0)); + CHECK_THROWS(set_be64(mb4, 0)); + CHECK_NOTHROW(set_le32(mb4, 0)); + CHECK_THROWS(set_le64(mb4, 0)); +} + TEST_CASE("MemBuffer unused") { MemBuffer mb; CHECK(mb.raw_ptr() == nullptr); diff --git a/src/util/membuffer.h b/src/util/membuffer.h index 895b9bba..d7411adf 100644 --- a/src/util/membuffer.h +++ b/src/util/membuffer.h @@ -27,19 +27,20 @@ #pragma once -/************************************************************************* // A MemBuffer allocates memory on the heap, and automatically // gets destructed when leaving scope or on exceptions. + +/************************************************************************* +// provides some base functionality for treating a MemBuffer as a pointer **************************************************************************/ -// provides some base functionality for treating a MemBuffer as a pointer template class MemBufferBase { public: typedef T element_type; typedef typename std::add_lvalue_reference::type reference; typedef typename std::add_pointer::type pointer; - typedef unsigned size_type; + typedef unsigned size_type; // limited by UPX_RSIZE_MAX protected: pointer ptr; @@ -79,8 +80,61 @@ public: // raw access } return ptr; } + +private: + // 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] + MemBufferBase *operator&() const DELETED_FUNCTION; }; +/************************************************************************* +// MemBufferBase global overloads +**************************************************************************/ + +// global operators +#if ALLOW_INT_PLUS_MEMBUFFER +// rewrite "n + membuffer" to "membuffer + n" so that this will get checked above +template +inline typename std::enable_if::value, typename MemBufferBase::pointer>::type +operator+(U n, const MemBufferBase &mbb) { + return mbb + n; +} +#else +// not allowed +template +inline typename std::enable_if::value, typename MemBufferBase::pointer>::type +operator+(U n, const MemBufferBase &mbb) DELETED_FUNCTION; +#endif + +// raw_bytes overload +template +inline typename MemBufferBase::pointer raw_bytes(const MemBufferBase &mbb, + size_t size_in_bytes) { + return mbb.raw_bytes(size_in_bytes); +} +template +inline typename MemBufferBase::pointer raw_index_bytes(const MemBufferBase &mbb, size_t index, + size_t size_in_bytes) { + typedef typename MemBufferBase::element_type element_type; + return mbb.raw_bytes(mem_size(sizeof(element_type), index, size_in_bytes)) + index; +} + +#if 1 +// some more global overloads using a checked raw_bytes() call +#define XSPAN_REQUIRES_CONVERTIBLE_ANY_DIRECTION(A, B, RType) \ + typename std::enable_if::value, RType>::type +#define XSPAN_FWD_C_IS_MEMBUFFER 1 +#define C MemBufferBase +#include "xspan_fwd.h" +#undef C +#undef XSPAN_FWD_C_IS_MEMBUFFER +#undef XSPAN_REQUIRES_CONVERTIBLE_ANY_DIRECTION +#endif + +/************************************************************************* +// +**************************************************************************/ + class MemBuffer final : public MemBufferBase { public: inline MemBuffer() noexcept : MemBufferBase() {} @@ -147,37 +201,6 @@ private: #endif // disable dynamic allocation ACC_CXX_DISABLE_NEW_DELETE - - // disable taking the address => force passing by reference - // [I'm not too sure about this design decision, but we can always allow it if needed] - MemBuffer *operator&() const DELETED_FUNCTION; }; -// raw_bytes overload -template -inline typename MemBufferBase::pointer raw_bytes(const MemBufferBase &mbb, - size_t size_in_bytes) { - return mbb.raw_bytes(size_in_bytes); -} -template -inline typename MemBufferBase::pointer raw_index_bytes(const MemBufferBase &mbb, size_t index, - size_t size_in_bytes) { - typedef typename MemBufferBase::element_type element_type; - return mbb.raw_bytes(mem_size(sizeof(element_type), index, size_in_bytes)) + index; -} - -// global operators -#if ALLOW_INT_PLUS_MEMBUFFER -// rewrite "n + membuffer" to "membuffer + n" so that this will get checked above -template -inline typename std::enable_if::value, typename MemBufferBase::pointer>::type -operator+(U n, const MemBufferBase &mbb) { - return mbb + n; -} -#else -template -inline typename std::enable_if::value, typename MemBufferBase::pointer>::type -operator+(U n, const MemBufferBase &mbb) DELETED_FUNCTION; -#endif - /* vim:set ts=4 sw=4 et: */ diff --git a/src/util/xspan_fwd.h b/src/util/xspan_fwd.h index b28f4d06..564907b0 100644 --- a/src/util/xspan_fwd.h +++ b/src/util/xspan_fwd.h @@ -31,21 +31,23 @@ template \ inline XSPAN_REQUIRES_CONVERTIBLE_ANY_DIRECTION(T, U, RType) +#ifndef XSPAN_FWD_C_IS_MEMBUFFER template inline typename std::enable_if::value, void *>::type operator+(U, const C &) DELETED_FUNCTION; +#endif // XSPAN_FWD_C_IS_MEMBUFFER /************************************************************************* // overloads for standard functions **************************************************************************/ template -inline void *memchr(const C &a, int c, size_t n) { - return memchr(a.raw_bytes(n), c, n); +inline void *memchr(const C &a, int v, size_t n) { + return memchr(a.raw_bytes(n), v, n); } template -inline const void *memchr(const C &a, int c, size_t n) { - return memchr(a.raw_bytes(n), c, n); +inline const void *memchr(const C &a, int v, size_t n) { + return memchr(a.raw_bytes(n), v, n); } template @@ -115,8 +117,8 @@ XSPAN_FWD_TU(void *) memmove(const C &a, const E &b, size_t n) { #endif template -inline void *memset(const C &a, int c, size_t n) { - return memset(a.raw_bytes(n), c, n); +inline void *memset(const C &a, int v, size_t n) { + return memset(a.raw_bytes(n), v, n); } /************************************************************************* @@ -255,6 +257,7 @@ void set_le64(const C &a, upx_uint64_t v) { return set_le64(a.raw_bytes(8), v); } +#ifndef XSPAN_FWD_C_IS_MEMBUFFER template inline C operator+(const C &a, const BE16 &v) { return a + unsigned(v); @@ -288,6 +291,7 @@ template inline C operator-(const C &a, const LE32 &v) { return a - unsigned(v); } +#endif // XSPAN_FWD_C_IS_MEMBUFFER template typename std::enable_if::type upx_safe_strlen(const C &a) {