From 5d649f83ecae9afa68f77d344aec5575b5eac948 Mon Sep 17 00:00:00 2001 From: "Markus F.X.J. Oberhumer" Date: Wed, 24 Jan 2024 20:53:14 +0100 Subject: [PATCH] all: assorted cleanups --- .clang-format | 1 + .github/workflows/ci.yml | 12 +- CMakeLists.txt | 10 +- misc/cmake/functions.cmake | 34 ++- misc/make/Makefile-extra.mk | 3 +- src/bele.h | 60 +++-- src/bele_policy.h | 23 +- src/check/dt_check.cpp | 34 +++ src/check/dt_cxxlib.cpp | 6 + src/check/dt_impl.cpp | 15 +- src/conf.h | 27 +- src/console/s_win32.cpp | 10 +- src/except.cpp | 11 +- src/except.h | 56 ++-- src/help.cpp | 18 +- src/main.cpp | 5 +- src/p_elf_enum.h | 492 ++++++++++++++++++----------------- src/p_mach_enum.h | 9 +- src/p_vmlinx.cpp | 1 + src/packer.cpp | 2 +- src/util/cxxlib.h | 12 +- src/util/util.cpp | 13 +- src/util/util.h | 30 ++- src/util/xspan_impl.h | 12 +- src/util/xspan_impl_common.h | 1 + src/util/xspan_impl_ptr.h | 1 + src/version.h | 4 +- 27 files changed, 535 insertions(+), 367 deletions(-) diff --git a/.clang-format b/.clang-format index f6eb2334..7cdeb70f 100644 --- a/.clang-format +++ b/.clang-format @@ -15,6 +15,7 @@ AttributeMacros: - XSPAN_DELETED_FUNCTION - may_throw EmptyLineBeforeAccessModifier: Leave +# IndentPPDirectives: AfterHash # TODO SortIncludes: false SpaceAfterCStyleCast: true Standard: Cpp03 diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index d5ebf7f8..18fdd018 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -15,8 +15,8 @@ env: DEBIAN_FRONTEND: noninteractive UPX_CMAKE_BUILD_FLAGS: --verbose UPX_CMAKE_CONFIG_FLAGS: -Wdev --warn-uninitialized - # 2023-11-08 - ZIG_DIST_VERSION: 0.12.0-dev.1502+b3462b7ce + # 2024-01-24 + ZIG_DIST_VERSION: 0.12.0-dev.2334+aef1da163 jobs: job-rebuild-and-verify-stubs: @@ -53,16 +53,16 @@ jobs: git status || true make -C src/stub extra-all all if ! git diff --quiet; then git diff; exit 1; fi + - run: bash ./misc/scripts/check_whitespace_git.sh - name: 'Check source code formatting' run: | - bash ./misc/scripts/check_whitespace_git.sh UPX_CLANG_FORMAT="$PWD/../deps/bin-upx-20221212/clang-format-15.0.6" make -C src clang-format if ! git diff --quiet; then git diff; exit 1; fi job-linux-cmake: # uses cmake + make if: true needs: [ job-rebuild-and-verify-stubs ] - name: ${{ format('{0} cmake', matrix.os) }} + name: ${{ format('{0}', matrix.os) }} runs-on: ${{ matrix.os }} strategy: fail-fast: false @@ -158,7 +158,7 @@ jobs: job-macos-cmake: # uses cmake + make if: true needs: [ job-rebuild-and-verify-stubs ] - name: ${{ format('{0} cmake', matrix.os) }} + name: ${{ format('{0}', matrix.os) }} runs-on: ${{ matrix.os }} strategy: fail-fast: false @@ -249,7 +249,7 @@ jobs: job-windows-cmake: # uses cmake + msbuild if: true needs: [ job-rebuild-and-verify-stubs ] - name: ${{ format('{0} cmake', matrix.name) }} + name: ${{ format('{0}', matrix.name) }} runs-on: ${{ matrix.os }} strategy: fail-fast: false diff --git a/CMakeLists.txt b/CMakeLists.txt index 8404e266..e7367a8a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -129,7 +129,7 @@ else() endif() # CMake init -upx_default_build_type(Release) +upx_set_default_build_type(Release) project(upx VERSION "${UPX_VERSION_STRING}" LANGUAGES C CXX) upx_apply_build_type() @@ -348,7 +348,6 @@ endif() if(MSVC_FRONTEND) target_compile_options(${t} PRIVATE -W3 ${warn_WX}) else() - ##target_compile_options(${t} PRIVATE -Wall ${warn_Werror}) target_compile_options(${t} PRIVATE ${warn_Wall} -Wno-cast-align -Wno-cast-qual ${warn_Werror}) endif() @@ -486,12 +485,13 @@ upx_cmake_include_hook(8_summary) upx_print_var(CMAKE_VERSION UPX_CONFIG_CMAKE_MINIMUM_REQUIRED_VERSION CMAKE_GENERATOR) if(NOT UPX_CONFIG_CMAKE_DISABLE_PRINT_INFO) -upx_print_var(CMAKE_HOST_SYSTEM_NAME CMAKE_HOST_SYSTEM_VERSION) -upx_print_var(CMAKE_SYSTEM_NAME CMAKE_SYSTEM_VERSION CMAKE_CROSSCOMPILING CMAKE_CROSSCOMPILING_EMULATOR) +upx_print_var(CMAKE_BINARY_DIR CMAKE_SOURCE_DIR CMAKE_CURRENT_BINARY_DIR CMAKE_CURRENT_SOURCE_DIR) +upx_print_var(CMAKE_HOST_SYSTEM_NAME CMAKE_HOST_SYSTEM_VERSION CMAKE_HOST_SYSTEM_PROCESSOR CMAKE_APPLE_SILICON_PROCESSOR) +upx_print_var(CMAKE_SYSTEM_NAME CMAKE_SYSTEM_VERSION CMAKE_SYSTEM_PROCESSOR CMAKE_CROSSCOMPILING CMAKE_CROSSCOMPILING_EMULATOR) 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) 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) upx_print_var(CMAKE_INTERPROCEDURAL_OPTIMIZATION CMAKE_POSITION_INDEPENDENT_CODE CMAKE_TRY_COMPILE_CONFIGURATION) -upx_print_var(CYGWIN GNUC MINGW MSVC MSVC_FRONTEND MSVC_IDE WIN32 WIN64) +upx_print_var(APPLE CYGWIN GNUC MINGW MSVC MSVC_FRONTEND MSVC_IDE UNIX WIN32 WIN64) endif() # UPX_CONFIG_CMAKE_DISABLE_PRINT_INFO upx_print_var(CMAKE_INSTALL_PREFIX CMAKE_CONFIGURATION_TYPES CMAKE_BUILD_TYPE) if(Threads_FOUND) diff --git a/misc/cmake/functions.cmake b/misc/cmake/functions.cmake index c218faa5..4cc6d3fb 100644 --- a/misc/cmake/functions.cmake +++ b/misc/cmake/functions.cmake @@ -27,7 +27,7 @@ macro(upx_disallow_in_source_build) endmacro() # set the default build type; must be called before project() cmake init -macro(upx_default_build_type type) +macro(upx_set_default_build_type type) set(upx_global_default_build_type "${type}") get_property(upx_global_is_multi_config GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG) if(NOT upx_global_is_multi_config AND NOT CMAKE_BUILD_TYPE) @@ -77,7 +77,7 @@ function(upx_print_have_symbol) # ARGV; needs include(CheckSymbolExists) 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}") + message(STATUS "HAVE ${symbol}") endif() endforeach() endfunction() @@ -87,7 +87,7 @@ 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) + upx_print_have_symbol(__CRTDLL__ __CYGWIN__ __CYGWIN32__ __CYGWIN64__ __MINGW32__ __MINGW64__ __MINGW64_VERSION_MAJOR __MSVCRT__ __MSVCRT_VERSION__ _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 @@ -108,7 +108,25 @@ function(upx_add_glob_files) # ARGV list(APPEND result "${files}") list(SORT result) list(REMOVE_DUPLICATES result) - ##message(STATUS "upx_add_glob_files: ${var_name} = ${result}") + #message(STATUS "upx_add_glob_files: ${var_name} = ${result}") + set(${var_name} "${result}" PARENT_SCOPE) # return value +endfunction() + +# remove wildcard expansions from a variable +function(upx_remove_glob_files) # ARGV + set(var_name ${ARGV0}) + list(REMOVE_AT ARGV 0) + file(GLOB files ${ARGV}) + set(result "") + if(DEFINED ${var_name}) + set(result "${${var_name}}") + foreach(file ${files}) + list(REMOVE_ITEM result "${file}") + endforeach() + list(SORT result) + list(REMOVE_DUPLICATES result) + endif() + #message(STATUS "upx_remove_glob_files: ${var_name} = ${result}") set(${var_name} "${result}" PARENT_SCOPE) # return value endfunction() @@ -122,10 +140,10 @@ function(upx_cache_bool_vars) # ARGV 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 + elseif(DEFINED ENV{${var_name}}) # check environment + if("$ENV{${var_name}}" MATCHES "^(0|1|OFF|ON|FALSE|TRUE)$") set(value "$ENV{${var_name}}") - set(UPX_CACHE_ORIGIN_FROM_ENV_${var_name} TRUE CACHE INTERNAL "" FORCE) # for info below + set(UPX_CACHE_ORIGIN_FROM_ENV_${var_name} TRUE CACHE INTERNAL "" FORCE) # for status message below endif() endif() # convert to bool @@ -218,7 +236,7 @@ function(upx_compile_source_debug_with_O2) # ARGV endforeach() endfunction() -# sanitize a target: this needs proper support from your compiler AND toolchain +# sanitize a target; note that this may require special run-time support libs from your toolchain function(upx_sanitize_target) # ARGV foreach(t ${ARGV}) if(UPX_CONFIG_DISABLE_SANITIZE) diff --git a/misc/make/Makefile-extra.mk b/misc/make/Makefile-extra.mk index a7f0b6d2..0da4126a 100644 --- a/misc/make/Makefile-extra.mk +++ b/misc/make/Makefile-extra.mk @@ -264,6 +264,7 @@ build/%: UPX_CMAKE_CONFIG_FLAGS += $(call __add_cmake_config,CMAKE_CXX_COMPILER_ 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_SYSTEM_PROCESSOR) 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) @@ -272,7 +273,7 @@ build/%: UPX_CMAKE_CONFIG_FLAGS += $(call __add_cmake_config,UPX_CONFIG_DISABLE_ 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 +endif # GNU make bug work-around #*********************************************************************** # check git submodules diff --git a/src/bele.h b/src/bele.h index d89f7a17..680d5d2a 100644 --- a/src/bele.h +++ b/src/bele.h @@ -152,11 +152,15 @@ static forceinline void set_ne64(XE64 *p, upx_uint64_t vv) noexcept { ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(long) == 4) // unfortunately *not* constexpr with current MSVC -static forceinline unsigned bswap16(unsigned v) noexcept { +static forceinline /*constexpr*/ unsigned bswap16(unsigned v) noexcept { return (unsigned) _byteswap_ulong(v << 16); } -static forceinline unsigned bswap32(unsigned v) noexcept { return (unsigned) _byteswap_ulong(v); } -static forceinline upx_uint64_t bswap64(upx_uint64_t v) noexcept { return _byteswap_uint64(v); } +static forceinline /*constexpr*/ unsigned bswap32(unsigned v) noexcept { + return (unsigned) _byteswap_ulong(v); +} +static forceinline /*constexpr*/ upx_uint64_t bswap64(upx_uint64_t v) noexcept { + return _byteswap_uint64(v); +} #else @@ -266,21 +270,27 @@ inline void set_le24(XE24 *p, unsigned v) noexcept { b[2] = ACC_ICONV(byte, (v >> 16) & 0xff); } -inline unsigned get_le26(const void *p) noexcept { return get_le32(p) & 0x03ffffff; } -inline unsigned get_le19_5(const void *p) noexcept { return (get_le32(p) >> 5) & 0x0007ffff; } -inline unsigned get_le14_5(const void *p) noexcept { return (get_le32(p) >> 5) & 0x00003fff; } +REQUIRE_XE32 +inline unsigned get_le26(const XE32 *p) noexcept { return get_le32(p) & 0x03ffffff; } +REQUIRE_XE32 +inline unsigned get_le19_5(const XE32 *p) noexcept { return (get_le32(p) >> 5) & 0x0007ffff; } +REQUIRE_XE32 +inline unsigned get_le14_5(const XE32 *p) noexcept { return (get_le32(p) >> 5) & 0x00003fff; } -inline void set_le26(void *p, unsigned v) noexcept { +REQUIRE_XE32 +inline void set_le26(XE32 *p, unsigned v) noexcept { // preserve the top 6 bits // set_le32(p, (get_le32(p) & 0xfc000000) | (v & 0x03ffffff)); // optimized version, saving a runtime bswap32 set_ne32(p, (get_ne32(p) & ne32_to_le32(0xfc000000)) | (ne32_to_le32(v) & ne32_to_le32(0x03ffffff))); } -inline void set_le19_5(void *p, unsigned v) noexcept { +REQUIRE_XE32 +inline void set_le19_5(XE32 *p, unsigned v) noexcept { set_le32(p, (get_le32(p) & 0xff00001f) | ((v & 0x0007ffff) << 5)); } -inline void set_le14_5(void *p, unsigned v) noexcept { +REQUIRE_XE32 +inline void set_le14_5(XE32 *p, unsigned v) noexcept { set_le32(p, (get_le32(p) & 0xfff8001f) | ((v & 0x00003fff) << 5)); } @@ -289,17 +299,21 @@ inline void set_le14_5(void *p, unsigned v) noexcept { **************************************************************************/ static forceinline constexpr int sign_extend(unsigned v, unsigned bits) noexcept { +#if (ACC_ARCH_M68K) // no barrel shifter const unsigned sign_bit = 1u << (bits - 1); - v &= sign_bit | (sign_bit - 1); - v |= 0u - (v & sign_bit); - return ACC_ICAST(int, v); + return ACC_ICAST(int, (v & (sign_bit - 1)) - (v & sign_bit)); +#else + return ACC_ICAST(int, v << (32 - bits)) >> (32 - bits); +#endif } static forceinline constexpr upx_int64_t sign_extend(upx_uint64_t v, unsigned bits) noexcept { +#if (ACC_ARCH_M68K) // no barrel shifter const upx_uint64_t sign_bit = 1ull << (bits - 1); - v &= sign_bit | (sign_bit - 1); - v |= 0ull - (v & sign_bit); - return ACC_ICAST(upx_int64_t, v); + return ACC_ICAST(upx_int64_t, (v & (sign_bit - 1)) - (v & sign_bit)); +#else + return ACC_ICAST(upx_int64_t, v << (64 - bits)) >> (64 - bits); +#endif } REQUIRE_XE16 @@ -714,6 +728,22 @@ T *operator+(T *ptr, const LE64 &v) noexcept DELETED_FUNCTION; template T *operator-(T *ptr, const LE64 &v) noexcept DELETED_FUNCTION; +#if !ALLOW_INT_PLUS_MEMBUFFER +template +T *operator+(const BE16 &v, T *ptr) noexcept DELETED_FUNCTION; +template +T *operator+(const BE32 &v, T *ptr) noexcept DELETED_FUNCTION; +template +T *operator+(const LE16 &v, T *ptr) noexcept DELETED_FUNCTION; +template +T *operator+(const LE32 &v, T *ptr) noexcept DELETED_FUNCTION; +#endif // ALLOW_INT_PLUS_MEMBUFFER + +template +T *operator+(const BE64 &v, T *ptr) noexcept DELETED_FUNCTION; +template +T *operator+(const LE64 &v, T *ptr) noexcept DELETED_FUNCTION; + /************************************************************************* // global overloads **************************************************************************/ diff --git a/src/bele_policy.h b/src/bele_policy.h index 920178a4..b3b36e19 100644 --- a/src/bele_policy.h +++ b/src/bele_policy.h @@ -33,14 +33,16 @@ #if defined(BELE_CTP) // CTP - Compile-Time Polymorphism (templates) -#define V static inline -#define S static int __acc_cdecl_qsort -#define C noexcept +#define V static inline +#define VV static forceinline_constexpr +#define S static int __acc_cdecl_qsort +#define C noexcept #elif defined(BELE_RTP) // RTP - Run-Time Polymorphism (virtual functions) -#define V virtual -#define S virtual int -#define C const noexcept +#define V virtual +#define VV virtual +#define S virtual int +#define C const noexcept #else #error #endif @@ -101,8 +103,8 @@ struct BEPolicy #elif defined(BELE_RTP) typedef N_BELE_CTP::BEPolicy CTP_Policy; #endif - V bool isBE() C { return true; } - V bool isLE() C { return false; } + VV bool isBE() C { return true; } + VV bool isLE() C { return false; } typedef BE16 U16; typedef BE32 U32; @@ -160,8 +162,8 @@ struct LEPolicy #elif defined(BELE_RTP) typedef N_BELE_CTP::LEPolicy CTP_Policy; #endif - V bool isBE() C { return false; } - V bool isLE() C { return true; } + VV bool isBE() C { return false; } + VV bool isLE() C { return true; } typedef LE16 U16; typedef LE32 U32; @@ -220,6 +222,7 @@ typedef LEPolicy HostPolicy; #endif #undef V +#undef VV #undef S #undef C diff --git a/src/check/dt_check.cpp b/src/check/dt_check.cpp index 9a24a626..174b042b 100644 --- a/src/check/dt_check.cpp +++ b/src/check/dt_check.cpp @@ -125,6 +125,8 @@ ACC_COMPILE_TIME_ASSERT_HEADER(sign_extend(0u + 257, 8) == 1) ACC_COMPILE_TIME_ASSERT_HEADER(sign_extend(0u + 383, 8) == 127) ACC_COMPILE_TIME_ASSERT_HEADER(sign_extend(0u + 384, 8) == -128) ACC_COMPILE_TIME_ASSERT_HEADER(sign_extend(0u + 511, 8) == -1) +ACC_COMPILE_TIME_ASSERT_HEADER(sign_extend(0ull + 0, 1) == 0) +ACC_COMPILE_TIME_ASSERT_HEADER(sign_extend(0ull + 1, 1) == -1) ACC_COMPILE_TIME_ASSERT_HEADER(CHAR_BIT == 8) #if 0 // does not work with MSVC @@ -468,6 +470,38 @@ void upx_compiler_sanity_check(void) noexcept { assert_noexcept(get_be32_signed(d) == 2138996092); assert_noexcept(get_be64_signed(d) == 9186918263483431288LL); } +#if DEBUG >= 1 + { + for (int i = 0; i < 256; i++) { + { + const unsigned u = i; + assert_noexcept(sign_extend(u, 1) == ((i & 1) ? -1 : 0)); + assert_noexcept(sign_extend(u, 2) == ((i & 2) ? -2 + (i & 1) : (i & 1))); + assert_noexcept(sign_extend(u, 3) == ((i & 4) ? -4 + (i & 3) : (i & 3))); + assert_noexcept(sign_extend(u, 4) == ((i & 8) ? -8 + (i & 7) : (i & 7))); + assert_noexcept(sign_extend(u, 5) == ((i & 16) ? -16 + (i & 15) : (i & 15))); + assert_noexcept(sign_extend(u, 6) == ((i & 32) ? -32 + (i & 31) : (i & 31))); + assert_noexcept(sign_extend(u, 7) == ((i & 64) ? -64 + (i & 63) : (i & 63))); + assert_noexcept(sign_extend(u, 8) == ((i & 128) ? -128 + (i & 127) : (i & 127))); + assert_noexcept(sign_extend(u, 32) == i); + assert_noexcept(sign_extend(0u - u, 32) == -i); + } + { + const upx_uint64_t u = i; + assert_noexcept(sign_extend(u, 1) == ((i & 1) ? -1 : 0)); + assert_noexcept(sign_extend(u, 2) == ((i & 2) ? -2 + (i & 1) : (i & 1))); + assert_noexcept(sign_extend(u, 3) == ((i & 4) ? -4 + (i & 3) : (i & 3))); + assert_noexcept(sign_extend(u, 4) == ((i & 8) ? -8 + (i & 7) : (i & 7))); + assert_noexcept(sign_extend(u, 5) == ((i & 16) ? -16 + (i & 15) : (i & 15))); + assert_noexcept(sign_extend(u, 6) == ((i & 32) ? -32 + (i & 31) : (i & 31))); + assert_noexcept(sign_extend(u, 7) == ((i & 64) ? -64 + (i & 63) : (i & 63))); + assert_noexcept(sign_extend(u, 8) == ((i & 128) ? -128 + (i & 127) : (i & 127))); + assert_noexcept(sign_extend(u, 64) == i); + assert_noexcept(sign_extend(0ull - u, 64) == -i); + } + } + } +#endif { unsigned dd; void *const d = ⅆ diff --git a/src/check/dt_cxxlib.cpp b/src/check/dt_cxxlib.cpp index a1ff6dc5..775ebc6d 100644 --- a/src/check/dt_cxxlib.cpp +++ b/src/check/dt_cxxlib.cpp @@ -49,6 +49,12 @@ ACC_COMPILE_TIME_ASSERT_HEADER((!upx::is_same_any_v) ) ACC_COMPILE_TIME_ASSERT_HEADER((!upx::is_same_any_v) ) ACC_COMPILE_TIME_ASSERT_HEADER((!upx::is_same_any_v) ) +ACC_COMPILE_TIME_ASSERT_HEADER((upx::is_same_any_v) ) +ACC_COMPILE_TIME_ASSERT_HEADER( + (upx::is_same_any_v) ) +ACC_COMPILE_TIME_ASSERT_HEADER( + (upx::is_same_any_v) ) + 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) diff --git a/src/check/dt_impl.cpp b/src/check/dt_impl.cpp index e147b02e..b2e127dd 100644 --- a/src/check/dt_impl.cpp +++ b/src/check/dt_impl.cpp @@ -28,12 +28,25 @@ // doctest support code implementation **************************************************************************/ +#if defined(__has_include) +#if __has_include() +#include // for __GLIBC__ +#endif +#endif +// aligned_alloc() was added in glibc-2.16 +#if defined(__ELF__) && (__GLIBC__ + 0 == 2) && (__GLIBC_MINOR__ + 0 < 16) +#define _LIBCPP_HAS_NO_LIBRARY_ALIGNED_ALLOCATION +#endif + #define DOCTEST_CONFIG_IMPLEMENT #define DOCTEST_CONFIG_NO_UNPREFIXED_OPTIONS #if !defined(DOCTEST_CONFIG_DISABLE) -#if defined(__i386__) && defined(__MSDOS__) && defined(__DJGPP__) && defined(__GNUC__) +#if defined(__wasi__) +#define DOCTEST_CONFIG_NO_MULTITHREADING +#define DOCTEST_CONFIG_NO_POSIX_SIGNALS +#elif defined(__i386__) && defined(__MSDOS__) && defined(__DJGPP__) && defined(__GNUC__) #define DOCTEST_CONFIG_NO_MULTITHREADING #define DOCTEST_CONFIG_NO_POSIX_SIGNALS #elif defined(__m68k__) && defined(__atarist__) && defined(__GNUC__) diff --git a/src/conf.h b/src/conf.h index 773080db..415c412d 100644 --- a/src/conf.h +++ b/src/conf.h @@ -169,18 +169,29 @@ typedef upx_int64_t upx_off_t; // shortcuts #define forceinline __acc_forceinline -#if _MSC_VER +#if (ACC_CC_MSC) #define noinline __declspec(noinline) #undef __acc_noinline #define __acc_noinline noinline #else #define noinline __acc_noinline #endif +#if defined(__clang__) || defined(__GNUC__) +#define noreturn noinline __attribute__((__noreturn__)) +#elif (ACC_CC_MSC) +// do not use, generates annoying "warning C4702: unreachable code" +////#define noreturn noinline __declspec(noreturn) +#define noreturn noinline +#else +#define noreturn noinline +#endif #define forceinline_constexpr forceinline constexpr #define likely __acc_likely #define unlikely __acc_unlikely #define very_likely __acc_very_likely #define very_unlikely __acc_very_unlikely +// cosmetic: explictly annotate some functions which may throw exceptions +// note: noexcept(false) is the default for all C++ functions anyway #define may_throw noexcept(false) #define COMPILE_TIME_ASSERT(e) ACC_COMPILE_TIME_ASSERT(e) @@ -341,15 +352,17 @@ inline void NO_fprintf(FILE *, const char *, ...) noexcept {} #define upx_memcpy_inline __builtin_memcpy_inline #elif __has_builtin(__builtin_memcpy) #define upx_memcpy_inline __builtin_memcpy -#elif defined(__GNUC__) +#elif defined(__clang__) || defined(__GNUC__) #define upx_memcpy_inline __builtin_memcpy #else #define upx_memcpy_inline memcpy #endif -#if __has_builtin(__builtin_return_address) +#if defined(__wasi__) +#define upx_return_address() nullptr +#elif __has_builtin(__builtin_return_address) #define upx_return_address() __builtin_return_address(0) -#elif defined(__GNUC__) +#elif defined(__clang__) || defined(__GNUC__) #define upx_return_address() __builtin_return_address(0) #elif (ACC_CC_MSC) #define upx_return_address() _ReturnAddress() @@ -440,9 +453,9 @@ inline void mem_clear(T (&array)[N]) noexcept DELETED_FUNCTION; #define ByteArray(var, n) Array(byte, var, (n)) // assert_noexcept() -noinline void assertFailed(const char *expr, const char *file, int line, const char *func) noexcept; -noinline void throwAssertFailed(const char *expr, const char *file, int line, const char *func); -#if defined(__GNUC__) +noreturn void assertFailed(const char *expr, const char *file, int line, const char *func) noexcept; +noreturn void throwAssertFailed(const char *expr, const char *file, int line, const char *func); +#if defined(__clang__) || defined(__GNUC__) #undef assert #if DEBUG || 0 // generate a warning if assert() is used inside a "noexcept" context diff --git a/src/console/s_win32.cpp b/src/console/s_win32.cpp index 7227eea2..cb1fae19 100644 --- a/src/console/s_win32.cpp +++ b/src/console/s_win32.cpp @@ -25,6 +25,11 @@ */ +#define WANT_WINDOWS_LEAN_H 1 +#include "../headers.h" +#if (HAVE_CONIO_H) +#include +#endif #include "../conf.h" #if (USE_SCREEN_WIN32) @@ -33,11 +38,6 @@ // direct screen access **************************************************************************/ -#include "../util/windows_lean.h" -#if (HAVE_CONIO_H) -#include -#endif - #include "screen.h" #define this self diff --git a/src/except.cpp b/src/except.cpp index ce01689b..f24ade25 100644 --- a/src/except.cpp +++ b/src/except.cpp @@ -37,8 +37,10 @@ Throwable::Throwable(const char *m, int e, bool w) noexcept : super(), msg(nullptr), err(e), is_warning(w) { - if (m) + if (m != nullptr) { msg = strdup(m); + assert_noexcept(msg != nullptr); + } #if 0 fprintf(stderr, "construct exception: %s %zu\n", msg, debug_counter); debug_counter += 1; @@ -49,8 +51,10 @@ Throwable::Throwable(const Throwable &other) noexcept : super(other), msg(nullptr), err(other.err), is_warning(other.is_warning) { - if (other.msg) + if (other.msg != nullptr) { msg = strdup(other.msg); + assert_noexcept(msg != nullptr); + } #if 0 fprintf(stderr, "copy exception: %s %zu\n", msg, debug_counter); debug_counter += 1; @@ -62,8 +66,7 @@ Throwable::~Throwable() noexcept { debug_counter -= 1; fprintf(stderr, "destruct exception: %s %zu\n", msg, debug_counter); #endif - if (msg) - free(msg); + upx::owner_free(msg); } /************************************************************************* diff --git a/src/except.h b/src/except.h index b4f4a493..a2716169 100644 --- a/src/except.h +++ b/src/except.h @@ -27,11 +27,6 @@ #pragma once -const char *prettyName(const char *n) noexcept; - -noinline void assertFailed(const char *expr, const char *file, int line, const char *func) noexcept; -noinline void throwAssertFailed(const char *expr, const char *file, int line, const char *func); - /************************************************************************* // exceptions **************************************************************************/ @@ -50,7 +45,7 @@ public: bool isWarning() const noexcept { return is_warning; } private: - char *msg = nullptr; + OwningPointer(char) msg = nullptr; int err = 0; protected: bool is_warning = false; // can be set by subclasses @@ -84,7 +79,7 @@ public: }; /************************************************************************* -// system exception +// system exceptions **************************************************************************/ class OutOfMemoryException final : public Exception { @@ -178,44 +173,37 @@ public: // util **************************************************************************/ -#undef NORET -#if 1 && defined(__GNUC__) -#define NORET noinline __attribute__((__noreturn__)) -#else -#define NORET noinline -#endif +const char *prettyName(const char *n) noexcept; -NORET void throwCantPack(const char *msg) may_throw; -NORET void throwCantPackExact() may_throw; -NORET void throwUnknownExecutableFormat(const char *msg = nullptr, bool warn = false) may_throw; -NORET void throwNotCompressible(const char *msg = nullptr) may_throw; -NORET void throwAlreadyPacked(const char *msg = nullptr) may_throw; -NORET void throwAlreadyPackedByUPX(const char *msg = nullptr) may_throw; -NORET void throwCantUnpack(const char *msg) may_throw; -NORET void throwNotPacked(const char *msg = nullptr) may_throw; -NORET void throwFilterException() may_throw; -NORET void throwBadLoader() may_throw; -NORET void throwChecksumError() may_throw; -NORET void throwCompressedDataViolation() may_throw; -NORET void throwInternalError(const char *msg) may_throw; -NORET void throwOutOfMemoryException(const char *msg = nullptr) may_throw; -NORET void throwIOException(const char *msg = nullptr, int e = 0) may_throw; -NORET void throwEOFException(const char *msg = nullptr, int e = 0) may_throw; +noreturn void throwCantPack(const char *msg) may_throw; +noreturn void throwCantPackExact() may_throw; +noreturn void throwUnknownExecutableFormat(const char *msg = nullptr, bool warn = false) may_throw; +noreturn void throwNotCompressible(const char *msg = nullptr) may_throw; +noreturn void throwAlreadyPacked(const char *msg = nullptr) may_throw; +noreturn void throwAlreadyPackedByUPX(const char *msg = nullptr) may_throw; +noreturn void throwCantUnpack(const char *msg) may_throw; +noreturn void throwNotPacked(const char *msg = nullptr) may_throw; +noreturn void throwFilterException() may_throw; +noreturn void throwBadLoader() may_throw; +noreturn void throwChecksumError() may_throw; +noreturn void throwCompressedDataViolation() may_throw; +noreturn void throwInternalError(const char *msg) may_throw; +noreturn void throwOutOfMemoryException(const char *msg = nullptr) may_throw; +noreturn void throwIOException(const char *msg = nullptr, int e = 0) may_throw; +noreturn void throwEOFException(const char *msg = nullptr, int e = 0) may_throw; // some C++ template wizardry is needed to overload throwCantPack() for varargs template void throwCantPack(const T *, ...) DELETED_FUNCTION; template <> -NORET void throwCantPack(const char *format, ...) may_throw attribute_format(1, 2); +noreturn void throwCantPack(const char *format, ...) may_throw attribute_format(1, 2); template void throwCantUnpack(const T *, ...) DELETED_FUNCTION; template <> -NORET void throwCantUnpack(const char *format, ...) may_throw attribute_format(1, 2); +noreturn void throwCantUnpack(const char *format, ...) may_throw attribute_format(1, 2); template void throwInternalError(const T *, ...) DELETED_FUNCTION; template <> -NORET void throwInternalError(const char *format, ...) may_throw attribute_format(1, 2); - -#undef NORET +noreturn void throwInternalError(const char *format, ...) may_throw attribute_format(1, 2); /* vim:set ts=4 sw=4 et: */ diff --git a/src/help.cpp b/src/help.cpp index 7cdbf792..274543a5 100644 --- a/src/help.cpp +++ b/src/help.cpp @@ -425,14 +425,14 @@ void show_version(bool one_line) { fprintf(f, "Copyright (C) 2000-2024 John F. Reiser\n"); fprintf(f, "Copyright (C) 2002-2024 Jens Medoch\n"); #if (WITH_ZLIB) - fprintf(f, "Copyright (C) 1995" "-2023 Jean-loup Gailly and Mark Adler\n"); + fprintf(f, "Copyright (C) 1995" "-2024 Jean-loup Gailly and Mark Adler\n"); #endif #if (WITH_LZMA) fprintf(f, "Copyright (C) 1999" "-2006 Igor Pavlov\n"); #endif #if (WITH_ZSTD) // 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" "-2024 Meta Platforms, Inc. and affiliates\n"); #endif #if (WITH_BZIP2) fprintf(f, "Copyright (C) 1996" "-2010 Julian Seward\n"); // see @@ -496,11 +496,20 @@ void show_sysinfo(const char *options_var) { #if defined(__clang_major__) cf_print("__clang_major__", "%lld", __clang_major__ + 0); #endif +#if defined(__clang_minor__) + cf_print("__clang_minor__", "%lld", __clang_minor__ + 0, 3); +#endif +#if defined(__clang_patchlevel__) + cf_print("__clang_patchlevel__", "%lld", __clang_patchlevel__ + 0, 3); +#endif #if defined(__GNUC__) cf_print("__GNUC__", "%lld", __GNUC__ + 0); #endif #if defined(__GNUC_MINOR__) - cf_print("__GNUC_MINOR__", "%lld", __GNUC_MINOR__ + 0); + cf_print("__GNUC_MINOR__", "%lld", __GNUC_MINOR__ + 0, 3); +#endif +#if defined(__GNUC_PATCHLEVEL__) + cf_print("__GNUC_PATCHLEVEL__", "%lld", __GNUC_PATCHLEVEL__ + 0, 3); #endif #if defined(_MSC_VER) cf_print("_MSC_VER", "%lld", _MSC_VER + 0); @@ -524,6 +533,9 @@ void show_sysinfo(const char *options_var) { #if defined(__USE_MINGW_ANSI_STDIO) cf_print("__USE_MINGW_ANSI_STDIO", "%lld", __USE_MINGW_ANSI_STDIO + 0, 3); #endif +#if defined(__ELF__) + cf_print("__ELF__", "%lld", __ELF__ + 0, 3); +#endif #if defined(__GLIBC__) cf_print("__GLIBC__", "%lld", __GLIBC__ + 0); #endif diff --git a/src/main.cpp b/src/main.cpp index 4d38b3d7..b64a1e8d 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1355,8 +1355,11 @@ int __acc_cdecl_main main(int argc, char *argv[]) /*noexcept*/ { _set_abort_behavior(_WRITE_ABORT_MSG, _WRITE_ABORT_MSG | _CALL_REPORTFAULT); #endif acc_wildargv(&argc, &argv); - // srand((int) time(nullptr)); +#if defined(__wasi__) + srand((int) time(nullptr)); +#else srand((int) clock()); +#endif // info: main() is implicitly "noexcept", so we need a try block #if 0 diff --git a/src/p_elf_enum.h b/src/p_elf_enum.h index 34e1507a..375a43e8 100644 --- a/src/p_elf_enum.h +++ b/src/p_elf_enum.h @@ -33,293 +33,303 @@ // - that older compilers do not correctly perform EBCO **************************************************************************/ +#if CLANG_FORMAT_DUMMY_CLASS +class Dummy { +#endif + #ifdef WANT_EHDR_ENUM #undef WANT_EHDR_ENUM -enum { // indices for e_ident[16] - EI_CLASS = 4, - EI_DATA = 5, /* Data encoding */ - EI_VERSION = 6, - EI_OSABI = 7, - EI_ABIVERSION = 8, -}; -enum { // e_ident[EI_CLASS] - ELFCLASS32 = 1, /* 32-bit objects */ - ELFCLASS64 = 2, /* 64-bit objects */ -}; -enum { // e_ident[EI_DATA] - ELFDATA2LSB = 1, /* 2's complement, little endian */ - ELFDATA2MSB = 2, /* 2's complement, big endian */ -}; -enum { // e_ident[EI_OSABI] - ELFOSABI_NONE = 0, // == ELFOSABI_SYSV - ELFOSABI_NETBSD = 2, - ELFOSABI_LINUX = 3, - ELFOSABI_SOLARIS = 6, - ELFOSABI_AIX = 7, - ELFOSABI_FREEBSD = 9, - ELFOSABI_OPENBSD = 12, - ELFOSABI_ARM = 97, - ELFOSABI_STANDALONE = 255 // Standalone (embedded) application -}; -enum { // e_type - ET_NONE = 0, /* No file type */ - ET_REL = 1, /* Relocatable file */ - ET_EXEC = 2, /* Executable file */ - ET_DYN = 3, /* Shared object file */ - ET_CORE = 4, /* Core file */ -}; -enum { // e_machine - EM_386 = 3, // i386 - EM_MIPS = 8, - EM_MIPS_RS3_LE = 10, // MIPS R3000 little-endian - EM_PPC = 20, - EM_PPC64 = 21, - EM_ARM = 40, - EM_X86_64 = 62, // amd64 - EM_AMD64 = EM_X86_64, - EM_AARCH64 = 183, // arm64 - EM_ARM64 = EM_AARCH64, - EM_RISCV = 243, // risc-v - EM_LOONGARCH = 258, -}; -enum { // e_version - EV_CURRENT = 1, -}; -#endif + enum { // indices for e_ident[16] + EI_CLASS = 4, + EI_DATA = 5, // Data encoding + EI_VERSION = 6, + EI_OSABI = 7, + EI_ABIVERSION = 8, + }; + enum { // e_ident[EI_CLASS] + ELFCLASS32 = 1, // 32-bit objects + ELFCLASS64 = 2, // 64-bit objects + }; + enum { // e_ident[EI_DATA] + ELFDATA2LSB = 1, // 2's complement, little endian + ELFDATA2MSB = 2, // 2's complement, big endian + }; + enum { // e_ident[EI_OSABI] + ELFOSABI_NONE = 0, // == ELFOSABI_SYSV + ELFOSABI_NETBSD = 2, + ELFOSABI_LINUX = 3, + ELFOSABI_SOLARIS = 6, + ELFOSABI_AIX = 7, + ELFOSABI_FREEBSD = 9, + ELFOSABI_OPENBSD = 12, + ELFOSABI_ARM = 97, + ELFOSABI_STANDALONE = 255 // Standalone (embedded) application + }; + enum { // e_type + ET_NONE = 0, /* No file type */ + ET_REL = 1, /* Relocatable file */ + ET_EXEC = 2, /* Executable file */ + ET_DYN = 3, /* Shared object file */ + ET_CORE = 4, /* Core file */ + }; + enum { // e_machine + EM_386 = 3, // i386 + EM_MIPS = 8, + EM_MIPS_RS3_LE = 10, // MIPS R3000 little-endian + EM_PPC = 20, + EM_PPC64 = 21, + EM_ARM = 40, + EM_X86_64 = 62, // amd64 + EM_AMD64 = EM_X86_64, + EM_AARCH64 = 183, // arm64 + EM_ARM64 = EM_AARCH64, + EM_RISCV = 243, // risc-v + EM_LOONGARCH = 258, + }; + enum { // e_version + EV_CURRENT = 1, + }; +#endif // WANT_EHDR_ENUM #ifdef WANT_PHDR_ENUM #undef WANT_PHDR_ENUM -enum { // p_type - PT_NULL = 0, /* Ignore: a "comment" */ - PT_LOAD = 1, /* Loadable program segment */ - PT_DYNAMIC = 2, /* Dynamic linking information */ - PT_INTERP = 3, /* Name of program interpreter */ - PT_NOTE = 4, /* Auxiliary information (esp. OpenBSD) */ - PT_PHDR = 6, /* Entry for header table itself */ - PT_NUM = 8, /* Number of defined types in low range */ - PT_GNU_STACK = 0x6474e551, /* Indicates stack executability */ - PT_GNU_RELRO = 0x6474e552, /* Read-only after relocation */ -}; + enum { // p_type + PT_NULL = 0, /* Ignore: a "comment" */ + PT_LOAD = 1, /* Loadable program segment */ + PT_DYNAMIC = 2, /* Dynamic linking information */ + PT_INTERP = 3, /* Name of program interpreter */ + PT_NOTE = 4, /* Auxiliary information (esp. OpenBSD) */ + PT_PHDR = 6, /* Entry for header table itself */ + PT_NUM = 8, /* Number of defined types in low range */ + PT_GNU_STACK = 0x6474e551, /* Indicates stack executability */ + PT_GNU_RELRO = 0x6474e552, /* Read-only after relocation */ + }; -enum { // p_flags - PF_X = 1, /* Segment is executable */ - PF_W = 2, /* Segment is writable */ - PF_R = 4, /* Segment is readable */ -}; -#endif + enum { // p_flags + PF_X = 1, /* Segment is executable */ + PF_W = 2, /* Segment is writable */ + PF_R = 4, /* Segment is readable */ + }; +#endif // WANT_PHDR_ENUM #ifdef WANT_SHDR_ENUM #undef WANT_SHDR_ENUM -enum { // sh_type - SHT_NULL = 0, /* Section header table entry unused */ - SHT_PROGBITS = 1, /* Program data */ - SHT_SYMTAB = 2, /* Symbol table */ - SHT_STRTAB = 3, /* String table */ - SHT_RELA = 4, /* Relocation entries with addends */ - SHT_HASH = 5, /* Symbol hash table */ - SHT_DYNAMIC = 6, /* Dynamic linking information */ - SHT_NOTE = 7, /* Notes */ - SHT_NOBITS = 8, /* Program space with no data (bss) */ - SHT_REL = 9, /* Relocation entries, no addends */ - SHT_SHLIB = 10, /* Reserved */ - SHT_DYNSYM = 11, /* Dynamic linker symbol table */ - /* 12, 13 hole */ - SHT_INIT_ARRAY = 14, /* Array of constructors */ - SHT_FINI_ARRAY = 15, /* Array of destructors */ - SHT_PREINIT_ARRAY = 16, /* Array of pre-constructors */ - SHT_GROUP = 17, /* Section group */ - SHT_SYMTAB_SHNDX = 18, /* Extended section indices */ - SHT_GNU_HASH = 0x6ffffff6, /* GNU-style hash table. */ - SHT_GNU_LIBLIST = 0x6ffffff7, /* Prelink library list */ - SHT_GNU_verdef = 0x6ffffffd, /* Version definition section. */ - SHT_GNU_verneed = 0x6ffffffe, /* Version needs section. */ - SHT_GNU_versym = 0x6fffffff, /* Version symbol table. */ + enum { // sh_type + SHT_NULL = 0, /* Section header table entry unused */ + SHT_PROGBITS = 1, /* Program data */ + SHT_SYMTAB = 2, /* Symbol table */ + SHT_STRTAB = 3, /* String table */ + SHT_RELA = 4, /* Relocation entries with addends */ + SHT_HASH = 5, /* Symbol hash table */ + SHT_DYNAMIC = 6, /* Dynamic linking information */ + SHT_NOTE = 7, /* Notes */ + SHT_NOBITS = 8, /* Program space with no data (bss) */ + SHT_REL = 9, /* Relocation entries, no addends */ + SHT_SHLIB = 10, /* Reserved */ + SHT_DYNSYM = 11, /* Dynamic linker symbol table */ + /* 12, 13 hole */ + SHT_INIT_ARRAY = 14, /* Array of constructors */ + SHT_FINI_ARRAY = 15, /* Array of destructors */ + SHT_PREINIT_ARRAY = 16, /* Array of pre-constructors */ + SHT_GROUP = 17, /* Section group */ + SHT_SYMTAB_SHNDX = 18, /* Extended section indices */ + SHT_GNU_HASH = 0x6ffffff6, /* GNU-style hash table. */ + SHT_GNU_LIBLIST = 0x6ffffff7, /* Prelink library list */ + SHT_GNU_verdef = 0x6ffffffd, /* Version definition section. */ + SHT_GNU_verneed = 0x6ffffffe, /* Version needs section. */ + SHT_GNU_versym = 0x6fffffff, /* Version symbol table. */ - SHT_LOOS = 0x60000000, /* LOcal OS; SHT_ANDROID_REL{,A} is +1, +2 */ - SHT_LOPROC = 0x70000000, /* Start of processor-specific */ - SHT_ARM_ATTRIBUTES = (SHT_LOPROC + 3), /* ARM attributes section. */ -}; + SHT_LOOS = 0x60000000, /* LOcal OS; SHT_ANDROID_REL{,A} is +1, +2 */ + SHT_LOPROC = 0x70000000, /* Start of processor-specific */ + SHT_ARM_ATTRIBUTES = (SHT_LOPROC + 3), /* ARM attributes section. */ + }; -enum { // sh_flags - SHF_WRITE = (1 << 0), /* Writable */ - SHF_ALLOC = (1 << 1), /* Occupies memory during execution */ - SHF_EXECINSTR = (1 << 2), /* Executable */ - SHF_MERGE = (1 << 4), /* Might be merged */ - SHF_STRINGS = (1 << 5), /* Contains nul-terminated strings */ - SHF_INFO_LINK = (1 << 6), /* 'sh_info' contains SHT index */ - SHF_LINK_ORDER = (1 << 7), /* Preserve order after combining */ -}; -#endif + enum { // sh_flags + SHF_WRITE = (1 << 0), /* Writable */ + SHF_ALLOC = (1 << 1), /* Occupies memory during execution */ + SHF_EXECINSTR = (1 << 2), /* Executable */ + SHF_MERGE = (1 << 4), /* Might be merged */ + SHF_STRINGS = (1 << 5), /* Contains nul-terminated strings */ + SHF_INFO_LINK = (1 << 6), /* 'sh_info' contains SHT index */ + SHF_LINK_ORDER = (1 << 7), /* Preserve order after combining */ + }; +#endif // WANT_SHDR_ENUM #ifdef WANT_DYN_ENUM #undef WANT_DYN_ENUM -enum { // d_tag - DT_NULL = 0, /* End flag */ - DT_NEEDED = 1, /* Name of needed library */ - DT_PLTRELSZ = 2, /* Size in bytes of PLT relocs */ - DT_PLTGOT = 3, /* Processor defined value */ - DT_HASH = 4, /* Hash table of symbol names */ - DT_STRTAB = 5, /* String table */ - DT_SYMTAB = 6, /* Symbol table */ - DT_RELA = 7, /* Relocations which do contain an addend */ - DT_RELASZ = 8, /* Total size of Rela relocs */ - DT_RELAENT = 9, /* Size of one RELA relocation */ - DT_STRSZ = 10, /* Size of string table */ - DT_SYMENT = 11, /* Size of one symbol table entry */ - DT_INIT = 12, /* Address of init function */ - DT_FINI = 13, /* Address of termination function */ + enum { // d_tag + DT_NULL = 0, /* End flag */ + DT_NEEDED = 1, /* Name of needed library */ + DT_PLTRELSZ = 2, /* Size in bytes of PLT relocs */ + DT_PLTGOT = 3, /* Processor defined value */ + DT_HASH = 4, /* Hash table of symbol names */ + DT_STRTAB = 5, /* String table */ + DT_SYMTAB = 6, /* Symbol table */ + DT_RELA = 7, /* Relocations which do contain an addend */ + DT_RELASZ = 8, /* Total size of Rela relocs */ + DT_RELAENT = 9, /* Size of one RELA relocation */ + DT_STRSZ = 10, /* Size of string table */ + DT_SYMENT = 11, /* Size of one symbol table entry */ + DT_INIT = 12, /* Address of init function */ + DT_FINI = 13, /* Address of termination function */ - DT_REL = 17, /* Relocations which contain no addend */ - DT_RELSZ = 18, /* Total size of Rel relocs */ - DT_RELENT = 19, /* Size of one Rel relocation */ - DT_PLTREL = 20, /* Type of reloc in PLT */ - DT_TEXTREL = 22, /* Reloc might modify .text */ - DT_JMPREL = 23, /* Address of PLT relocs */ - DT_INIT_ARRAY = 25, /* Array with addresses of init fct */ - DT_FINI_ARRAY = 26, /* Array with addresses of fini fct */ - DT_INIT_ARRAYSZ = 27, /* size in bytes */ - DT_FINI_ARRAYSZ = 28, /* size in bytes */ - DT_PREINIT_ARRAY = 32, /* Array with addresses of preinit fct*/ - DT_PREINIT_ARRAYSZ = 33, /* size in bytes */ - DT_NUM = 35, /* end of easy range */ + DT_REL = 17, /* Relocations which contain no addend */ + DT_RELSZ = 18, /* Total size of Rel relocs */ + DT_RELENT = 19, /* Size of one Rel relocation */ + DT_PLTREL = 20, /* Type of reloc in PLT */ + DT_TEXTREL = 22, /* Reloc might modify .text */ + DT_JMPREL = 23, /* Address of PLT relocs */ + DT_INIT_ARRAY = 25, /* Array with addresses of init fct */ + DT_FINI_ARRAY = 26, /* Array with addresses of fini fct */ + DT_INIT_ARRAYSZ = 27, /* size in bytes */ + DT_FINI_ARRAYSZ = 28, /* size in bytes */ + DT_PREINIT_ARRAY = 32, /* Array with addresses of preinit fct*/ + DT_PREINIT_ARRAYSZ = 33, /* size in bytes */ + DT_NUM = 35, /* end of easy range */ - DT_CHECKSUM = 0x6ffffdf8, /* Only for prelink? */ - DT_GNU_HASH = 0x6ffffef5, /* GNU-style hash table */ - DT_VERSYM = 0x6ffffff0, /* version[] for each symbol */ - DT_FLAGS_1 = 0x6ffffffb, /* DF_1_* */ - DT_VERDEF = 0x6ffffffc, /* version definitions[] */ - DT_VERNEED = 0x6ffffffe, /* version[] needed */ -}; -enum { // DT_FLAGS_1 - DF_1_NOW = 0x00000001, /* Set RTLD_NOW for this object. */ - DF_1_PIE = 0x08000000, // Position-Independent Executable (main program) -}; -#endif + DT_CHECKSUM = 0x6ffffdf8, /* Only for prelink? */ + DT_GNU_HASH = 0x6ffffef5, /* GNU-style hash table */ + DT_VERSYM = 0x6ffffff0, /* version[] for each symbol */ + DT_FLAGS_1 = 0x6ffffffb, /* DF_1_* */ + DT_VERDEF = 0x6ffffffc, /* version definitions[] */ + DT_VERNEED = 0x6ffffffe, /* version[] needed */ + }; + enum { // DT_FLAGS_1 + DF_1_NOW = 0x00000001, /* Set RTLD_NOW for this object. */ + DF_1_PIE = 0x08000000, // Position-Independent Executable (main program) + }; +#endif // WANT_DYN_ENUM #ifdef WANT_SYM_ENUM #undef WANT_SYM_ENUM -enum { // st_bind (high 4 bits of st_info) - STB_LOCAL = 0, /* Local symbol */ - STB_GLOBAL = 1, /* Global symbol */ - STB_WEAK = 2, /* Weak symbol */ -}; + enum { // st_bind (high 4 bits of st_info) + STB_LOCAL = 0, /* Local symbol */ + STB_GLOBAL = 1, /* Global symbol */ + STB_WEAK = 2, /* Weak symbol */ + }; -enum { // st_type (low 4 bits of st_info) - STT_NOTYPE = 0, /* Symbol type is unspecified */ - STT_OBJECT = 1, /* Symbol is a data object */ - STT_FUNC = 2, /* Symbol is a code object */ - STT_SECTION = 3, /* Symbol associated with a section */ - STT_FILE = 4, /* Symbol's name is file name */ - STT_COMMON = 5, /* Symbol is a common data object */ - STT_TLS = 6, /* Symbol is thread-local data object*/ -}; + enum { // st_type (low 4 bits of st_info) + STT_NOTYPE = 0, /* Symbol type is unspecified */ + STT_OBJECT = 1, /* Symbol is a data object */ + STT_FUNC = 2, /* Symbol is a code object */ + STT_SECTION = 3, /* Symbol associated with a section */ + STT_FILE = 4, /* Symbol's name is file name */ + STT_COMMON = 5, /* Symbol is a common data object */ + STT_TLS = 6, /* Symbol is thread-local data object*/ + }; -enum { // st_other (visibility) - STV_DEFAULT = 0, /* Default symbol visibility rules */ - STV_INTERNAL = 1, /* Processor specific hidden class */ - STV_HIDDEN = 2, /* Sym unavailable in other modules */ - STV_PROTECTED = 3, /* Not preemptible, not exported */ -}; + enum { // st_other (visibility) + STV_DEFAULT = 0, /* Default symbol visibility rules */ + STV_INTERNAL = 1, /* Processor specific hidden class */ + STV_HIDDEN = 2, /* Sym unavailable in other modules */ + STV_PROTECTED = 3, /* Not preemptible, not exported */ + }; -enum { // st_shndx - SHN_UNDEF = 0, /* Undefined section */ - SHN_ABS = 0xfff1, /* Associated symbol is absolute */ - SHN_COMMON = 0xfff2, /* Associated symbol is common */ -}; -#endif + enum { // st_shndx + SHN_UNDEF = 0, /* Undefined section */ + SHN_ABS = 0xfff1, /* Associated symbol is absolute */ + SHN_COMMON = 0xfff2, /* Associated symbol is common */ + }; +#endif // WANT_SYM_ENUM -#ifdef WANT_REL_ENUM //{ +#ifdef WANT_REL_ENUM #undef WANT_REL_ENUM -static inline unsigned ELF32_R_TYPE(unsigned x) { return 0xff & x; } -static inline unsigned ELF64_R_TYPE(upx_uint64_t x) { return 0xffffffff & (unsigned) x; } -static inline unsigned ELF32_R_SYM(unsigned x) { return x >> 8; } -static inline unsigned ELF64_R_SYM(upx_uint64_t x) { return x >> 32; } -static inline unsigned ELF32_R_INFO(unsigned sym, unsigned type) { - return (sym << 8) + (type & 0xff); -} -static inline upx_int64_t ELF64_R_INFO(unsigned sym, unsigned type) { - return ((upx_uint64_t) sym << 32) + type; -} + static constexpr inline unsigned ELF32_R_TYPE(unsigned x) noexcept { return 0xff & x; } + static constexpr inline unsigned ELF64_R_TYPE(upx_uint64_t x) noexcept { + return 0xffffffff & (unsigned) x; + } + static constexpr inline unsigned ELF32_R_SYM(unsigned x) noexcept { return x >> 8; } + static constexpr inline unsigned ELF64_R_SYM(upx_uint64_t x) noexcept { return x >> 32; } + static constexpr inline unsigned ELF32_R_INFO(unsigned sym, unsigned type) noexcept { + return (sym << 8) + (type & 0xff); + } + static constexpr inline upx_int64_t ELF64_R_INFO(unsigned sym, unsigned type) { + return ((upx_uint64_t) sym << 32) + type; + } #undef R_PPC_RELATIVE #undef R_PPC64_RELATIVE #undef R_PPC_JMP_SLOT #undef R_PPC64_JMP_SLOT -enum { // relocation types - R_386_RELATIVE = 8, - R_AARCH64_RELATIVE = 1027, - R_ARM_RELATIVE = 23, - R_PPC_RELATIVE = 22, - R_PPC64_RELATIVE = R_PPC_RELATIVE, - R_X86_64_RELATIVE = 8, + enum { // relocation types + R_386_RELATIVE = 8, + R_AARCH64_RELATIVE = 1027, + R_ARM_RELATIVE = 23, + R_PPC_RELATIVE = 22, + R_PPC64_RELATIVE = R_PPC_RELATIVE, + R_X86_64_RELATIVE = 8, - R_386_JMP_SLOT = 7, - R_AARCH64_JUMP_SLOT = 1026, - R_ARM_JUMP_SLOT = 22, - R_PPC_JMP_SLOT = 21, - R_PPC64_JMP_SLOT = R_PPC_JMP_SLOT, - R_X86_64_JUMP_SLOT = 7, + R_386_JMP_SLOT = 7, + R_AARCH64_JUMP_SLOT = 1026, + R_ARM_JUMP_SLOT = 22, + R_PPC_JMP_SLOT = 21, + R_PPC64_JMP_SLOT = R_PPC_JMP_SLOT, + R_X86_64_JUMP_SLOT = 7, - R_386_32 = 1, - R_ARM_ABS32 = 2, - R_ARM_GLOB_DAT = 21, - R_MIPS_32 = 2, + R_386_32 = 1, + R_ARM_ABS32 = 2, + R_ARM_GLOB_DAT = 21, + R_MIPS_32 = 2, - R_386_GLOB_DAT = 6, - R_X86_64_64 = 1, - R_AARCH64_ABS64 = 257, - R_AARCH64_GLOB_DAT = 1025, + R_386_GLOB_DAT = 6, + R_X86_64_64 = 1, + R_AARCH64_ABS64 = 257, + R_AARCH64_GLOB_DAT = 1025, -}; -#endif //} + }; +#endif // WANT_REL_ENUM #ifdef WANT_NHDR_ENUM #undef WANT_NHDR_ENUM -enum { // ELF PT_NOTE types + enum { // ELF PT_NOTE types #define ELF_NOTE_GNU_NAME "GNU\0" - NT_GNU_ABI_TAG = 1, - NT_GNU_HWCAP = 2, - NT_GNU_BUILD_ID = 3, + NT_GNU_ABI_TAG = 1, + NT_GNU_HWCAP = 2, + NT_GNU_BUILD_ID = 3, #define ELF_NOTE_OPENBSD_NAME "OpenBSD\0" - NHDR_OPENBSD_TAG = 1, + NHDR_OPENBSD_TAG = 1, #define ELF_NOTE_NETBSD_NAME "NetBSD\0" - NHDR_NETBSD_TAG = 1, - NHDR_CHECKSUM_TAG = 2, - NHDR_PAX_TAG = 3, -}; + NHDR_NETBSD_TAG = 1, + NHDR_CHECKSUM_TAG = 2, + NHDR_PAX_TAG = 3, + }; -enum { // descsz descriptor sizes - GNU_ABI_DESCSZ = 16, // int GNU_OS, major, minor, subminor; - NETBSD_DESCSZ = 4, // major_ver * (10**8) + minor - OPENBSD_DESCSZ = 4, // 32-bit zero - // CHECKSUM_DESCSZ is 2*sizeof(short) + sizeof(checksum) - PAX_DESCSZ = 4, // 32-bit mask -}; + enum { // descsz descriptor sizes + GNU_ABI_DESCSZ = 16, // int GNU_OS, major, minor, subminor; + NETBSD_DESCSZ = 4, // major_ver * (10**8) + minor + OPENBSD_DESCSZ = 4, // 32-bit zero + // CHECKSUM_DESCSZ is 2*sizeof(short) + sizeof(checksum) + PAX_DESCSZ = 4, // 32-bit mask + }; -enum { // GNU OS/version - GNU_OS_LINUX = 0, - GNU_OS_HURD = 1, - GNU_OS_SOLARIS = 2, -}; + enum { // GNU OS/version + GNU_OS_LINUX = 0, + GNU_OS_HURD = 1, + GNU_OS_SOLARIS = 2, + }; -enum { // NetBSD checksum methods - CHECKSUM_CRC32 = 1, - CHECKSUM_MD5 = 2, - CHECKSUM_SHA1 = 3, - CHECKSUM_SHA256 = 4, -}; + enum { // NetBSD checksum methods + CHECKSUM_CRC32 = 1, + CHECKSUM_MD5 = 2, + CHECKSUM_SHA1 = 3, + CHECKSUM_SHA256 = 4, + }; #define ELF_NOTE_PAX_NAME "PaX\0" -enum { // NetBSD PaX bit values - PAX_MPROTECT = (1 << 0), /* force enable Mprotect */ - PAX_NOMPROTECT = (1 << 1), /* force disable Mprotect */ - PAX_GUARD = (1 << 2), /* force enable SEGVguard */ - PAX_NOGUARD = (1 << 3), /* force disable SEGVguard */ - PAX_ASLR = (1 << 4), /* force enable ASLR */ - PAX_NOASLR = (1 << 5), /* force disable ASLR */ -}; + enum { // NetBSD PaX bit values + PAX_MPROTECT = (1 << 0), /* force enable Mprotect */ + PAX_NOMPROTECT = (1 << 1), /* force disable Mprotect */ + PAX_GUARD = (1 << 2), /* force enable SEGVguard */ + PAX_NOGUARD = (1 << 3), /* force disable SEGVguard */ + PAX_ASLR = (1 << 4), /* force enable ASLR */ + PAX_NOASLR = (1 << 5), /* force disable ASLR */ + }; +#endif // WANT_NHDR_ENUM + +#if CLANG_FORMAT_DUMMY_CLASS +}; // class #endif /* vim:set ts=4 sw=4 et: */ diff --git a/src/p_mach_enum.h b/src/p_mach_enum.h index 1e24bd51..3b794b29 100644 --- a/src/p_mach_enum.h +++ b/src/p_mach_enum.h @@ -24,7 +24,6 @@ */ - /************************************************************************* // Use the preprocessor to work around // - that the types embedding these enums have to be PODs, and @@ -33,6 +32,10 @@ // - that older compilers do not correctly perform EBCO **************************************************************************/ +#if CLANG_FORMAT_DUMMY_CLASS +class Dummy { +#endif + #ifdef WANT_MACH_HEADER_ENUM /*{*/ #undef WANT_MACH_HEADER_ENUM enum : unsigned { // magic @@ -168,4 +171,8 @@ }; #endif /*}*/ +#if CLANG_FORMAT_DUMMY_CLASS +}; // class +#endif + /* vim:set ts=4 sw=4 et: */ diff --git a/src/p_vmlinx.cpp b/src/p_vmlinx.cpp index 160eada6..40a7cb5d 100644 --- a/src/p_vmlinx.cpp +++ b/src/p_vmlinx.cpp @@ -30,6 +30,7 @@ */ +#define ALLOW_INT_PLUS_MEMBUFFER 1 #include "conf.h" #include "file.h" diff --git a/src/packer.cpp b/src/packer.cpp index 1ee00258..30f729e7 100644 --- a/src/packer.cpp +++ b/src/packer.cpp @@ -481,7 +481,7 @@ unsigned Packer::getRandomId() const { } #endif while (id == 0) { -#if !(HAVE_GETTIMEOFDAY) || ((ACC_OS_DOS32) && defined(__DJGPP__)) +#if (!(HAVE_GETTIMEOFDAY) || ((ACC_OS_DOS32) && defined(__DJGPP__))) && !defined(__wasi__) id ^= (unsigned) time(nullptr); id ^= ((unsigned) clock()) << 12; #else diff --git a/src/util/cxxlib.h b/src/util/cxxlib.h index bfcca572..de5c6afe 100644 --- a/src/util/cxxlib.h +++ b/src/util/cxxlib.h @@ -345,7 +345,6 @@ using OwningPointer = T *; // also works: a trivial class with just a number of no-ops template struct OwningPointer final { - static_assert(std::is_class_v); // UPX convention typedef typename std::add_lvalue_reference::type reference; typedef typename std::add_lvalue_reference::type const_reference; typedef typename std::add_pointer::type pointer; @@ -384,6 +383,17 @@ inline void owner_delete(OwningPointer(T)(&object)) noexcept { assert_noexcept(object == nullptr); } +template +inline void owner_free(OwningPointer(T)(&object)) noexcept { + static_assert(!std::is_class_v); // UPX convention + if (object != nullptr) { + free((T *) object); + object = nullptr; + } + assert_noexcept((T *) object == nullptr); + assert_noexcept(object == nullptr); +} + // disable some overloads #if defined(__clang__) || __GNUC__ != 7 template diff --git a/src/util/util.cpp b/src/util/util.cpp index d6208c80..507195ac 100644 --- a/src/util/util.cpp +++ b/src/util/util.cpp @@ -176,7 +176,7 @@ void uintptr_check_no_overlap(upx_uintptr_t a, size_t a_size, upx_uintptr_t b, s throwCantPack("ptr_check_no_overlap-bc"); } -#if !defined(DOCTEST_CONFIG_DISABLE) && DEBUG +#if !defined(DOCTEST_CONFIG_DISABLE) && !defined(__wasi__) && DEBUG TEST_CASE("ptr_check_no_overlap 2") { byte p[4] = {}; @@ -922,4 +922,15 @@ TEST_CASE("get_ratio") { CHECK(get_ratio(2 * UPX_RSIZE_MAX, 1024ull * UPX_RSIZE_MAX) == 9999999); } +/************************************************************************* +// compat +**************************************************************************/ + +#if defined(__wasi__) // TODO later - wait for wasm/wasi exception handling proposal +extern "C" { +void __cxa_allocate_exception() { std::terminate(); } +void __cxa_throw() { std::terminate(); } +} // extern "C" +#endif + /* vim:set ts=4 sw=4 et: */ diff --git a/src/util/util.h b/src/util/util.h index 159c2d00..7b944a7a 100644 --- a/src/util/util.h +++ b/src/util/util.h @@ -40,14 +40,14 @@ bool mem_size_valid(upx_uint64_t element_size, upx_uint64_t n, upx_uint64_t extr // will throw on invalid size upx_rsize_t mem_size(upx_uint64_t element_size, upx_uint64_t n, upx_uint64_t extra1, - upx_uint64_t extra2 = 0); + upx_uint64_t extra2 = 0) may_throw; // // inline fast paths: // // will throw on invalid size -inline upx_rsize_t mem_size(upx_uint64_t element_size, upx_uint64_t n) { +inline upx_rsize_t mem_size(upx_uint64_t element_size, upx_uint64_t n) may_throw { upx_uint64_t bytes = element_size * n; if very_unlikely (element_size == 0 || element_size > UPX_RSIZE_MAX || n > UPX_RSIZE_MAX || bytes > UPX_RSIZE_MAX) @@ -56,20 +56,20 @@ inline upx_rsize_t mem_size(upx_uint64_t element_size, upx_uint64_t n) { } // will throw on invalid size -inline upx_rsize_t mem_size_get_n(upx_uint64_t element_size, upx_uint64_t n) { +inline upx_rsize_t mem_size_get_n(upx_uint64_t element_size, upx_uint64_t n) may_throw { (void) mem_size(element_size, n); // assert size return ACC_ICONV(upx_rsize_t, n); // and return n } // will throw on invalid size -inline void mem_size_assert(upx_uint64_t element_size, upx_uint64_t n) { +inline void mem_size_assert(upx_uint64_t element_size, upx_uint64_t n) may_throw { (void) mem_size(element_size, n); // assert size } // "new" with asserted size; will throw on invalid size #if DEBUG template -T *NewArray(upx_uint64_t n) { +T *NewArray(upx_uint64_t n) may_throw { COMPILE_TIME_ASSERT(std::is_standard_layout::value) COMPILE_TIME_ASSERT(std::is_trivially_copyable::value) COMPILE_TIME_ASSERT(std::is_trivially_default_constructible::value) @@ -95,32 +95,34 @@ T *NewArray(upx_uint64_t n) { // ptrdiff_t with nullptr checks and asserted size; will throw on failure // NOTE: returns size_in_bytes, not number of elements! -int ptr_diff_bytes(const void *a, const void *b); -unsigned ptr_udiff_bytes(const void *a, const void *b); // asserts a >= b +int ptr_diff_bytes(const void *a, const void *b) may_throw; +unsigned ptr_udiff_bytes(const void *a, const void *b) may_throw; // asserts a >= b // short names "ptr_diff" and "ptr_udiff" for types with sizeof(X) == 1 template inline typename std::enable_if::type ptr_diff(const T *a, - const U *b) { + const U *b) + may_throw { return ptr_diff_bytes(a, b); } template inline typename std::enable_if::type -ptr_udiff(const T *a, const U *b) { +ptr_udiff(const T *a, const U *b) may_throw { return ptr_udiff_bytes(a, b); } // check that buffers do not overlap; will throw on error noinline void uintptr_check_no_overlap(upx_uintptr_t a, size_t a_size, upx_uintptr_t b, - size_t b_size); + size_t b_size) may_throw; noinline void uintptr_check_no_overlap(upx_uintptr_t a, size_t a_size, upx_uintptr_t b, - size_t b_size, upx_uintptr_t c, size_t c_size); + size_t b_size, upx_uintptr_t c, size_t c_size) may_throw; -forceinline void ptr_check_no_overlap(const void *a, size_t a_size, const void *b, size_t b_size) { +forceinline void ptr_check_no_overlap(const void *a, size_t a_size, const void *b, size_t b_size) + may_throw { uintptr_check_no_overlap((upx_uintptr_t) a, a_size, (upx_uintptr_t) b, b_size); } forceinline void ptr_check_no_overlap(const void *a, size_t a_size, const void *b, size_t b_size, - const void *c, size_t c_size) { + const void *c, size_t c_size) may_throw { uintptr_check_no_overlap((upx_uintptr_t) a, a_size, (upx_uintptr_t) b, b_size, (upx_uintptr_t) c, c_size); } @@ -141,7 +143,7 @@ inline void ptr_invalidate_and_poison(T *(&ptr)) noexcept { // stdlib **************************************************************************/ -void *upx_calloc(size_t n, size_t element_size); +void *upx_calloc(size_t n, size_t element_size) may_throw; void upx_memswap(void *a, void *b, size_t n); diff --git a/src/util/xspan_impl.h b/src/util/xspan_impl.h index db1f382a..be02051e 100644 --- a/src/util/xspan_impl.h +++ b/src/util/xspan_impl.h @@ -43,12 +43,12 @@ XSPAN_NAMESPACE_BEGIN // HINT: set env-var "UPX_DEBUG_DOCTEST_DISABLE=1" for improved debugging experience -noinline void xspan_fail_nullptr(void) may_throw; -noinline void xspan_fail_nullbase(void) may_throw; -noinline void xspan_fail_not_same_base(void) may_throw; -noinline void xspan_fail_range_nullptr(void) may_throw; -noinline void xspan_fail_range_nullbase(void) may_throw; -noinline void xspan_fail_range_range(void) may_throw; +noreturn void xspan_fail_nullptr(void) may_throw; +noreturn void xspan_fail_nullbase(void) may_throw; +noreturn void xspan_fail_not_same_base(void) may_throw; +noreturn void xspan_fail_range_nullptr(void) may_throw; +noreturn void xspan_fail_range_nullbase(void) may_throw; +noreturn void xspan_fail_range_range(void) may_throw; void xspan_check_range(const void *ptr, const void *base, ptrdiff_t size_in_bytes) may_throw; // help constructor to distinguish between number of elements and bytes diff --git a/src/util/xspan_impl_common.h b/src/util/xspan_impl_common.h index 3d5d95ce..66d6063a 100644 --- a/src/util/xspan_impl_common.h +++ b/src/util/xspan_impl_common.h @@ -280,6 +280,7 @@ public: return Self(Unchecked, end, (begin - end) * sizeof(T), end); } + // cast to a different type (creates a new value) template inline CSelf type_cast() const { typedef CSelf R; diff --git a/src/util/xspan_impl_ptr.h b/src/util/xspan_impl_ptr.h index 0d659010..4dfa2df8 100644 --- a/src/util/xspan_impl_ptr.h +++ b/src/util/xspan_impl_ptr.h @@ -123,6 +123,7 @@ public: return assign(Self(other)); } + // cast to a different type (creates a new value) template inline CSelf type_cast() const { typedef CSelf R; diff --git a/src/version.h b/src/version.h index ce8f50fb..93961b11 100644 --- a/src/version.h +++ b/src/version.h @@ -2,6 +2,6 @@ #define UPX_VERSION_HEX 0x040300 /* 04.03.00 */ #define UPX_VERSION_STRING "4.3.0" #define UPX_VERSION_STRING4 "4.30" -#define UPX_VERSION_DATE "Jan 4th 2024" -#define UPX_VERSION_DATE_ISO "2024-01-04" +#define UPX_VERSION_DATE "Jan 24th 2024" +#define UPX_VERSION_DATE_ISO "2024-01-24" #define UPX_VERSION_YEAR "2024"