all: assorted cleanups

This commit is contained in:
Markus F.X.J. Oberhumer 2024-01-24 20:53:14 +01:00
parent 65b25adceb
commit 5d649f83ec
27 changed files with 535 additions and 367 deletions

View File

@ -15,6 +15,7 @@ AttributeMacros:
- XSPAN_DELETED_FUNCTION
- may_throw
EmptyLineBeforeAccessModifier: Leave
# IndentPPDirectives: AfterHash # TODO
SortIncludes: false
SpaceAfterCStyleCast: true
Standard: Cpp03

View File

@ -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

View File

@ -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)

View File

@ -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)

View File

@ -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

View File

@ -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 <class T>
T *operator-(T *ptr, const LE64 &v) noexcept DELETED_FUNCTION;
#if !ALLOW_INT_PLUS_MEMBUFFER
template <class T>
T *operator+(const BE16 &v, T *ptr) noexcept DELETED_FUNCTION;
template <class T>
T *operator+(const BE32 &v, T *ptr) noexcept DELETED_FUNCTION;
template <class T>
T *operator+(const LE16 &v, T *ptr) noexcept DELETED_FUNCTION;
template <class T>
T *operator+(const LE32 &v, T *ptr) noexcept DELETED_FUNCTION;
#endif // ALLOW_INT_PLUS_MEMBUFFER
template <class T>
T *operator+(const BE64 &v, T *ptr) noexcept DELETED_FUNCTION;
template <class T>
T *operator+(const LE64 &v, T *ptr) noexcept DELETED_FUNCTION;
/*************************************************************************
// global overloads
**************************************************************************/

View File

@ -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

View File

@ -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 = &dd;

View File

@ -49,6 +49,12 @@ ACC_COMPILE_TIME_ASSERT_HEADER((!upx::is_same_any_v<int, char>) )
ACC_COMPILE_TIME_ASSERT_HEADER((!upx::is_same_any_v<int, char, char>) )
ACC_COMPILE_TIME_ASSERT_HEADER((!upx::is_same_any_v<int, char, long>) )
ACC_COMPILE_TIME_ASSERT_HEADER((upx::is_same_any_v<ptrdiff_t, int, long, long long>) )
ACC_COMPILE_TIME_ASSERT_HEADER(
(upx::is_same_any_v<size_t, unsigned, unsigned long, unsigned long long>) )
ACC_COMPILE_TIME_ASSERT_HEADER(
(upx::is_same_any_v<upx_uintptr_t, unsigned, unsigned long, unsigned long long>) )
ACC_COMPILE_TIME_ASSERT_HEADER(usizeof(int) == sizeof(int))
ACC_COMPILE_TIME_ASSERT_HEADER(usizeof('a') == sizeof(char))
ACC_COMPILE_TIME_ASSERT_HEADER(usizeof("") == 1)

View File

@ -28,12 +28,25 @@
// doctest support code implementation
**************************************************************************/
#if defined(__has_include)
#if __has_include(<features.h>)
#include <features.h> // 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__)

View File

@ -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

View File

@ -25,6 +25,11 @@
<markus@oberhumer.com> <ezerotven+github@gmail.com>
*/
#define WANT_WINDOWS_LEAN_H 1
#include "../headers.h"
#if (HAVE_CONIO_H)
#include <conio.h>
#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 <conio.h>
#endif
#include "screen.h"
#define this self

View File

@ -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);
}
/*************************************************************************

View File

@ -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 <class T>
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 <class T>
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 <class T>
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: */

View File

@ -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 <bzlib.h>
@ -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

View File

@ -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

View File

@ -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: */

View File

@ -24,7 +24,6 @@
<jreiser@users.sourceforge.net>
*/
/*************************************************************************
// 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: */

View File

@ -30,6 +30,7 @@
*/
#define ALLOW_INT_PLUS_MEMBUFFER 1
#include "conf.h"
#include "file.h"

View File

@ -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

View File

@ -345,7 +345,6 @@ using OwningPointer = T *;
// also works: a trivial class with just a number of no-ops
template <class T>
struct OwningPointer final {
static_assert(std::is_class_v<T>); // UPX convention
typedef typename std::add_lvalue_reference<T>::type reference;
typedef typename std::add_lvalue_reference<const T>::type const_reference;
typedef typename std::add_pointer<T>::type pointer;
@ -384,6 +383,17 @@ inline void owner_delete(OwningPointer(T)(&object)) noexcept {
assert_noexcept(object == nullptr);
}
template <class T>
inline void owner_free(OwningPointer(T)(&object)) noexcept {
static_assert(!std::is_class_v<T>); // 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 <class T>

View File

@ -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: */

View File

@ -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 <class T>
T *NewArray(upx_uint64_t n) {
T *NewArray(upx_uint64_t n) may_throw {
COMPILE_TIME_ASSERT(std::is_standard_layout<T>::value)
COMPILE_TIME_ASSERT(std::is_trivially_copyable<T>::value)
COMPILE_TIME_ASSERT(std::is_trivially_default_constructible<T>::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 <class T, class U>
inline typename std::enable_if<sizeof(T) == 1 && sizeof(U) == 1, int>::type ptr_diff(const T *a,
const U *b) {
const U *b)
may_throw {
return ptr_diff_bytes(a, b);
}
template <class T, class U>
inline typename std::enable_if<sizeof(T) == 1 && sizeof(U) == 1, unsigned>::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);

View File

@ -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

View File

@ -280,6 +280,7 @@ public:
return Self(Unchecked, end, (begin - end) * sizeof(T), end);
}
// cast to a different type (creates a new value)
template <class U>
inline CSelf<U> type_cast() const {
typedef CSelf<U> R;

View File

@ -123,6 +123,7 @@ public:
return assign(Self(other));
}
// cast to a different type (creates a new value)
template <class U>
inline CSelf<U> type_cast() const {
typedef CSelf<U> R;

View File

@ -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"