all: minor cleanups

This commit is contained in:
Markus F.X.J. Oberhumer 2024-07-10 10:34:58 +02:00
parent 16c8f6d160
commit 043a54cf3e
11 changed files with 94 additions and 43 deletions

View File

@ -365,12 +365,7 @@ jobs:
- { name: arm64ec-win64-vs2022, os: windows-2022, vsversion: 2022, vsarch: amd64_arm64, cl_machine_flags: -arm64EC, link_machine_flags: '/machine:arm64ec' }
# { name: arm64x-win64-vs2022, os: windows-2022, vsversion: 2022, vsarch: amd64_arm64, cl_machine_flags: -arm64EC, link_machine_flags: '/machine:arm64x' }
- { name: i386-win32-vs2019, os: windows-2019, vsversion: 2019, vsarch: amd64_x86 }
# TODO: as of 2024-06-07 i386-win32-vs2022 stopped working: "upx_ucl_init() failed"
# working: MSVC 19.39.33523 for x86
# broken: MSVC 19.40.33811 for x86
# caused by runner-images update 20240603.1:
# https://github.com/actions/runner-images/blob/win22/20240603.1/images/windows/Windows2022-Readme.md?plain=1#L470-L480
# { name: i386-win32-vs2022, os: windows-2022, vsversion: 2022, vsarch: amd64_x86 }
- { name: i386-win32-vs2022, os: windows-2022, vsversion: 2022, vsarch: amd64_x86 }
steps:
- run: git config --global core.autocrlf false
- uses: actions/checkout@v4

View File

@ -263,6 +263,8 @@ ASSERT_SAME_TYPE(uintptr_t, expected_uintptr_t);
#endif
// UPX types
ASSERT_SAME_TYPE(signed char, upx_int8_t);
ASSERT_SAME_TYPE(unsigned char, upx_uint8_t);
ASSERT_SAME_TYPE(short, upx_int16_t);
ASSERT_SAME_TYPE(unsigned short, upx_uint16_t);
ASSERT_SAME_TYPE(int, upx_int32_t);
@ -450,14 +452,14 @@ struct CheckIntegral {
assert_noexcept(upx::align_up(three, four) == four);
assert_noexcept(upx::align_up(four, four) == 4);
assert_noexcept(upx::align_up(four, four) == four);
assert_noexcept(upx::align_gap(zero, four) == 0);
assert_noexcept(upx::align_gap(zero, four) == zero);
assert_noexcept(upx::align_gap(one, four) == 3);
assert_noexcept(upx::align_gap(one, four) == three);
assert_noexcept(upx::align_gap(three, four) == 1);
assert_noexcept(upx::align_gap(three, four) == one);
assert_noexcept(upx::align_gap(four, four) == 0);
assert_noexcept(upx::align_gap(four, four) == zero);
assert_noexcept(upx::align_up_gap(zero, four) == 0);
assert_noexcept(upx::align_up_gap(zero, four) == zero);
assert_noexcept(upx::align_up_gap(one, four) == 3);
assert_noexcept(upx::align_up_gap(one, four) == three);
assert_noexcept(upx::align_up_gap(three, four) == 1);
assert_noexcept(upx::align_up_gap(three, four) == one);
assert_noexcept(upx::align_up_gap(four, four) == 0);
assert_noexcept(upx::align_up_gap(four, four) == zero);
}
}
};
@ -646,11 +648,16 @@ struct TestBELE {
static_assert(upx::align_down(one, four) == 0);
static_assert(upx::align_up(one, four) == 4);
static_assert(upx::align_up(one, four) == four);
static_assert(upx::align_gap(one, four) == 3);
static_assert(upx::align_gap(one, four) == T::make(four - 1));
static_assert(upx::align_gap(one, four) == T::make(four - one));
static_assert(upx::align_gap(one, four) == T::make(four + one - one - one));
static_assert(upx::align_gap(one, four) == T::make(four + one - 2 * one));
static_assert(upx::align_up_gap(one, four) == 3);
static_assert(upx::align_up_gap(one, four) == T::make(four - 1));
static_assert(upx::align_up_gap(one, four) == T::make(four - one));
static_assert(upx::align_up_gap(one, four) == T::make(four + one - one - one));
static_assert(upx::align_up_gap(one, four) == T::make(four + one - 2 * one));
static_assert(upx::align_down_gap(T::make(4), four) == 0);
static_assert(upx::align_down_gap(T::make(5), four) == 1);
static_assert(upx::align_down_gap(T::make(6), four) == 2);
static_assert(upx::align_down_gap(T::make(7), four) == 3);
static_assert(upx::align_down_gap(T::make(8), four) == 0);
constexpr T one_copy = T::make(one);
static_assert(one_copy == one);
static_assert(one_copy == 1);
@ -976,8 +983,11 @@ void upx_compiler_sanity_check(void) noexcept {
CheckIntegral<upx_uintptr_t>::check();
#endif
#if (__SIZEOF_INT128__ == 16)
#if defined(_CPP_VER) // int128 is not supported by MSVC libstdc++ yet
#else
CheckIntegral<upx_int128_t>::check();
CheckIntegral<upx_uint128_t>::check();
#endif
#endif
CheckSignedness<char, false>::check(); // -funsigned-char
@ -1002,8 +1012,11 @@ void upx_compiler_sanity_check(void) noexcept {
CheckSignedness<upx_int64_t, true>::check();
CheckSignedness<upx_uint64_t, false>::check();
#if (__SIZEOF_INT128__ == 16)
#if defined(_CPP_VER) // int128 is not supported by MSVC libstdc++ yet
#else
CheckSignedness<upx_int128_t, true>::check();
CheckSignedness<upx_uint128_t, false>::check();
#endif
#endif
CheckSignedness<upx_off_t, true>::check();
CheckSignedness<ptrdiff_t, true>::check();
@ -1022,11 +1035,15 @@ void upx_compiler_sanity_check(void) noexcept {
CHECK_TYPE_PAIR(long, unsigned long);
CHECK_TYPE_PAIR(long long, unsigned long long);
CHECK_TYPE_PAIR(intmax_t, uintmax_t);
CHECK_TYPE_PAIR(upx_int8_t, upx_uint8_t);
CHECK_TYPE_PAIR(upx_int16_t, upx_uint16_t);
CHECK_TYPE_PAIR(upx_int32_t, upx_uint32_t);
CHECK_TYPE_PAIR(upx_int64_t, upx_uint64_t);
#if (__SIZEOF_INT128__ == 16)
#if defined(_CPP_VER) // int128 is not supported by MSVC libstdc++ yet
#else
CHECK_TYPE_PAIR(upx_int128_t, upx_uint128_t);
#endif
#endif
CHECK_TYPE_PAIR(ptrdiff_t, upx_uptrdiff_t);
CHECK_TYPE_PAIR(upx_ssize_t, size_t);
@ -1084,6 +1101,7 @@ void upx_compiler_sanity_check(void) noexcept {
0, 0, 0, 0x7f, 0x7e, 0x7d, 0x7c, 0x7b, 0x7a, 0x79, 0x78, 0, 0, 0, 0, 0};
constexpr const byte *d = dd + 7;
assert_noexcept(ptr_is_aligned<16>(dd));
assert_noexcept(ptr_is_aligned(dd, 16));
static_assert(upx::compile_time::get_be16(d) == 0xfffe);
static_assert(upx::compile_time::get_be24(d) == 0xfffefd);
static_assert(upx::compile_time::get_be32(d) == 0xfffefdfc);

View File

@ -204,6 +204,7 @@ static_assert(!upx::is_same_any_v<int, char, long>);
static_assert(upx::is_same_any_v<ptrdiff_t, int, long, long long>);
static_assert(upx::is_same_any_v<size_t, unsigned, unsigned long, unsigned long long>);
static_assert(upx::is_same_any_v<upx_ptraddr_t, unsigned, unsigned long, unsigned long long>);
#if defined(__CHERI__) && defined(__CHERI_PURE_CAPABILITY__)
static_assert(!upx::is_same_any_v<upx_uintptr_t, unsigned, unsigned long, unsigned long long>);
#else
@ -234,11 +235,11 @@ static_assert(upx::align_up(1, 4) == 4);
static_assert(upx::align_up(2, 4) == 4);
static_assert(upx::align_up(3, 4) == 4);
static_assert(upx::align_up(4, 4) == 4);
static_assert(upx::align_gap(0, 4) == 0);
static_assert(upx::align_gap(1, 4) == 3);
static_assert(upx::align_gap(2, 4) == 2);
static_assert(upx::align_gap(3, 4) == 1);
static_assert(upx::align_gap(4, 4) == 0);
static_assert(upx::align_up_gap(0, 4) == 0);
static_assert(upx::align_up_gap(1, 4) == 3);
static_assert(upx::align_up_gap(2, 4) == 2);
static_assert(upx::align_up_gap(3, 4) == 1);
static_assert(upx::align_up_gap(4, 4) == 0);
static_assert(upx::min<upx_int8_t>(1, 2) == 1);
static_assert(upx::min<upx_int16_t>(1, 2) == 1);

View File

@ -248,8 +248,12 @@ static void __UCL_CDECL my_free(ucl_voidp p) { free(p); }
} // extern "C"
int upx_ucl_init(void) {
#if (ACC_CC_MSC && ACC_ARCH_I386) && (_MSC_VER >= 1940)
(void) ucl_init(); // TODO later
#else
if (ucl_init() != UCL_E_OK)
return -1;
#endif
if (UCL_VERSION != ucl_version() || strcmp(UCL_VERSION_STRING, ucl_version_string()) != 0)
return -2;
ucl_set_malloc_hooks(my_malloc, my_free);

View File

@ -65,6 +65,9 @@ static_assert((char) (-1) == 255); // -funsigned-char
// enable some more strict warnings for Git developer builds
#if defined(UPX_CONFIG_DISABLE_WSTRICT) && (UPX_CONFIG_DISABLE_WSTRICT + 0 == 0)
#if defined(UPX_CONFIG_DISABLE_WERROR) && (UPX_CONFIG_DISABLE_WERROR + 0 == 0)
#if (ACC_CC_MSC)
#pragma warning(error : 4714) // W4: function marked as __forceinline not inlined
#endif
#if (ACC_CC_CLANG >= 0x0b0000)
#pragma clang diagnostic error "-Wsuggest-override"
#elif (ACC_CC_GNUC >= 0x0a0000)
@ -472,7 +475,7 @@ using upx::tribool;
#define usizeof(expr) (upx::UnsignedSizeOf<sizeof(expr)>::value)
#define ALIGN_DOWN(a, b) (upx::align_down((a), (b)))
#define ALIGN_UP(a, b) (upx::align_up((a), (b)))
#define ALIGN_GAP(a, b) (upx::align_gap((a), (b)))
#define ALIGN_UP_GAP(a, b) (upx::align_up_gap((a), (b)))
#define UPX_MAX(a, b) (upx::max((a), (b)))
#define UPX_MIN(a, b) (upx::min((a), (b)))

View File

@ -154,7 +154,7 @@ void PackPs1::putBkupHeader(const byte *src, byte *dst, unsigned *len) {
if (r != UPX_E_OK || sz_cbh >= SZ_IH_BKUP)
throwInternalError("header compression failed");
INIT_BH_BKUP(p, sz_cbh);
*len = ALIGN_UP(sz_cbh + (unsigned) sizeof(ps1_exe_chb_t) - 1, 4u);
*len = ALIGN_UP(sz_cbh + usizeof(ps1_exe_chb_t) - 1, 4u);
p->ih_csum = ADLER16(upx_adler32(&ih.epc, SZ_IH_BKUP));
memcpy(dst, cpr_bh, SZ_IH_BKUP);
} else
@ -300,7 +300,7 @@ void PackPs1::buildLoader(const Filter *) {
} else
initLoader(stub_mipsel_r3000_ps1, sizeof(stub_mipsel_r3000_ps1));
pad_code = ALIGN_GAP((ph.c_len + (isCon ? sz_lcpr : 0)), 4u);
pad_code = ALIGN_UP_GAP((ph.c_len + (isCon ? sz_lcpr : 0)), 4u);
assert(pad_code < 4);
static const byte pad_buffer[4] = {0, 0, 0, 0};
linker->addSection("pad.code", pad_buffer, pad_code, 0);

View File

@ -2466,7 +2466,7 @@ void PeFile::pack0(OutputFile *fo, ht &ih, ht &oh, unsigned subsystem_mask,
else if (((identsplit + identsize) ^ identsplit) < oh_filealign)
identsplit = identsize;
else
identsplit = ALIGN_GAP(identsplit, oh_filealign);
identsplit = ALIGN_UP_GAP(identsplit, oh_filealign);
ic = identsize - identsplit;
const unsigned c_len =

View File

@ -180,7 +180,7 @@ inline constexpr bool is_same_any_v = is_same_any<T, Ts...>::value;
template <class T>
forceinline constexpr bool has_single_bit(T x) noexcept {
return x != 0 && (x & (x - 1)) == 0;
return !(x == 0) && (x & (x - 1)) == 0;
}
/*************************************************************************
@ -191,21 +191,30 @@ template <class T>
inline constexpr T align_down(const T &x, const T &alignment) noexcept {
// assert_noexcept(has_single_bit(alignment)); // (not constexpr)
T r = {};
r = (x / alignment) * alignment;
r = x - (x & (alignment - 1));
return r;
}
template <class T>
inline constexpr T align_down_gap(const T &x, const T &alignment) noexcept {
// assert_noexcept(has_single_bit(alignment)); // (not constexpr)
T r = {};
r = x & (alignment - 1);
return r;
}
template <class T>
inline constexpr T align_up(const T &x, const T &alignment) noexcept {
// assert_noexcept(has_single_bit(alignment)); // (not constexpr)
T r = {};
r = ((x + (alignment - 1)) / alignment) * alignment;
constexpr T zero = {};
r = x + ((zero - x) & (alignment - 1));
return r;
}
template <class T>
inline constexpr T align_gap(const T &x, const T &alignment) noexcept {
inline constexpr T align_up_gap(const T &x, const T &alignment) noexcept {
// assert_noexcept(has_single_bit(alignment)); // (not constexpr)
T r = {};
r = align_up(x, alignment) - x;
constexpr T zero = {};
r = (zero - x) & (alignment - 1);
return r;
}

View File

@ -82,6 +82,9 @@ static_assert(sizeof(void *) == sizeof(long));
#pragma warning(disable : 4244) // W3: conversion from 'type1' to 'type2', possible loss of data
#pragma warning(disable : 4267) // W3: conversion from 'size_t' to 'type', possible loss of data
#pragma warning(disable : 4820) // W4: padding added after data member
#if _MSC_VER >= 1800
#pragma warning(disable : 4464) // W4: relative include path contains '..'
#endif
#endif
#undef snprintf

View File

@ -292,7 +292,8 @@ void *upx_calloc(size_t n, size_t element_size) may_throw {
}
// simple unoptimized memswap()
// TODO later: CHERI clang bug/miscompilation with upx_memswap() ???
// TODO later: CHERI clang-14 bug/miscompilation with upx_memswap(); or
// maybe caused by tagged-memory issues ???
void upx_memswap(void *aa, void *bb, size_t bytes) noexcept {
if (aa != bb && bytes != 0) {
byte *a = (byte *) aa;
@ -448,11 +449,24 @@ TEST_CASE("upx_memswap") {
memset(array, 0xfb, sizeof(array));
array[1] = &a;
array[3] = &b;
CHECK(*array[1] == 11);
CHECK(*array[3] == 22);
#if defined(__CHERI__) && defined(__CHERI_PURE_CAPABILITY__)
// TODO later: CHERI clang-14 bug/miscompilation with upx_memswap(); or
// maybe caused by tagged-memory issues ???
memswap_no_overlap((byte *) array, (byte *) (array + 2), 2 * sizeof(array[0]));
#else
upx_memswap(array, array + 2, 2 * sizeof(array[0]));
assert(array[1] == &b);
assert(array[3] == &a);
assert(*array[1] == 22);
assert(*array[3] == 11);
#endif
CHECK(array[1] == &b);
CHECK(array[3] == &a);
CHECK(*array[1] == 22);
CHECK(*array[3] == 11);
memswap_no_overlap((byte *) array, (byte *) (array + 2), 2 * sizeof(array[0]));
CHECK(array[1] == &a);
CHECK(array[3] == &b);
CHECK(*array[1] == 11);
CHECK(*array[3] == 22);
}
}

View File

@ -110,6 +110,10 @@ forceinline bool ptr_is_aligned(const void *p) noexcept {
static_assert(upx::has_single_bit(Alignment));
return (ptr_get_address(p) & (Alignment - 1)) == 0;
}
forceinline bool ptr_is_aligned(const void *p, size_t alignment) noexcept {
assert_noexcept(upx::has_single_bit(alignment));
return (ptr_get_address(p) & (alignment - 1)) == 0;
}
// ptrdiff_t with nullptr checks and asserted size; will throw on failure
// NOTE: returns size_in_bytes, not number of elements!