all: minor cleanups

This commit is contained in:
Markus F.X.J. Oberhumer
2024-05-28 10:26:39 +02:00
parent b0ce072370
commit 3495d1affd
17 changed files with 136 additions and 113 deletions
+7
View File
@@ -420,8 +420,12 @@ struct TestBELE {
constexpr T zero = {};
constexpr T zero_copy = T::make(zero);
assert_noexcept(zero_copy == 0);
assert_noexcept(!upx::has_single_bit(zero));
#if defined(upx_is_constant_evaluated)
static_assert(zero_copy == 0);
static_assert(zero_copy == zero);
static_assert(!upx::has_single_bit(zero));
static_assert(!upx::has_single_bit(zero_copy));
#endif
}
#if defined(upx_is_constant_evaluated)
@@ -429,12 +433,15 @@ struct TestBELE {
typedef typename T::integral_conversion_type U;
constexpr T one = T::make(1);
static_assert(one == 1);
static_assert(upx::has_single_bit(one));
constexpr T four = T::make(one + 3);
static_assert(four == 4);
static_assert(upx::has_single_bit(four));
constexpr U all_bits_u = (U) T::make(U(0) - U(1));
constexpr T all_bits = T::make(all_bits_u);
static_assert(all_bits == all_bits_u);
static_assert(all_bits == T::make(one - 2));
static_assert(!upx::has_single_bit(all_bits));
static_assert(one == one);
static_assert(!(one == four));
static_assert(!(one == all_bits));
+55 -32
View File
@@ -50,7 +50,7 @@ TEST_CASE("std::vector") {
}
/*************************************************************************
// core util - UPX_CXX_DISABLE_xxx
// core util: UPX_CXX_DISABLE_xxx, noncopyable
**************************************************************************/
namespace {
@@ -166,6 +166,23 @@ struct Z2_X2 : public X2 {
} // namespace test_disable_new_delete
TEST_CASE("upx::noncopyable") {
struct Test : private upx::noncopyable {
int v = 1;
};
Test t = {};
CHECK(t.v == 1);
#if (ACC_CC_MSC) // MSVC thinks that Test is not std::is_trivially_copyable; true or compiler bug?
// @COMPILER_BUG @MSVC_BUG
t.v = 0;
#else
mem_clear(&t);
#endif
CHECK(t.v == 0);
constexpr Test x = {};
static_assert(x.v == 1);
}
/*************************************************************************
// <type_traits>
**************************************************************************/
@@ -190,6 +207,16 @@ static_assert(upx::is_same_any_v<size_t, unsigned, unsigned long, unsigned long
// TODO later: CHERI
static_assert(upx::is_same_any_v<upx_uintptr_t, unsigned, unsigned long, unsigned long long>);
/*************************************************************************
// <bit>
**************************************************************************/
static_assert(!upx::has_single_bit(0));
static_assert(upx::has_single_bit(1));
static_assert(upx::has_single_bit(2));
static_assert(!upx::has_single_bit(3));
static_assert(upx::has_single_bit(4));
/*************************************************************************
// <algorithm>
**************************************************************************/
@@ -212,25 +239,35 @@ static_assert(upx::align_gap(4, 4) == 0);
static_assert(upx::min<upx_int8_t>(1, 2) == 1);
static_assert(upx::min<upx_int16_t>(1, 2) == 1);
static_assert(upx::min(1, 2) == 1);
static_assert(upx::min(1ll, 2ll) == 1);
static_assert(upx::min<upx_int32_t>(1, 2) == 1);
static_assert(upx::min<upx_int64_t>(1, 2) == 1);
static_assert(upx::max<upx_int8_t>(1, 2) == 2);
static_assert(upx::max<upx_int16_t>(1, 2) == 2);
static_assert(upx::max<upx_int32_t>(1, 2) == 2);
static_assert(upx::max<upx_int64_t>(1, 2) == 2);
static_assert(upx::min(1, 2) == 1);
static_assert(upx::min(1l, 2l) == 1);
static_assert(upx::min(1ll, 2ll) == 1);
static_assert(upx::max(1, 2) == 2);
static_assert(upx::max(1l, 2l) == 2);
static_assert(upx::max(1ll, 2ll) == 2);
static_assert(upx::min(0, 0) == 0);
static_assert(upx::min(0, 1) == 0);
static_assert(upx::min(1, 0) == 0);
static_assert(upx::max(0, 0) == 0);
static_assert(upx::max(0, 1) == 1);
static_assert(upx::max(1, 0) == 1);
static_assert(upx::umin(0u, 0u) == 0u);
static_assert(upx::umin(0u, 1u) == 0u);
static_assert(upx::umin(1u, 0u) == 0u);
static_assert(upx::umax(0u, 0u) == 0u);
static_assert(upx::umax(0u, 1u) == 1u);
static_assert(upx::umax(1u, 0u) == 1u);
static_assert(upx::umin<upx_uint8_t>(1, 2) == 1);
static_assert(upx::umin<upx_uint16_t>(1, 2) == 1);
static_assert(upx::umin<upx_uint32_t>(1, 2) == 1);
static_assert(upx::umin<upx_uint64_t>(1, 2) == 1);
static_assert(upx::umax<upx_uint8_t>(1, 2) == 2);
static_assert(upx::umax<upx_uint16_t>(1, 2) == 2);
static_assert(upx::umax<upx_uint32_t>(1, 2) == 2);
static_assert(upx::umax<upx_uint64_t>(1, 2) == 2);
static_assert(upx::umin(1u, 2u) == 1);
static_assert(upx::umin(1ul, 2ul) == 1);
static_assert(upx::umin(1ull, 2ull) == 1);
static_assert(upx::umax(1u, 2u) == 2);
static_assert(upx::umax(1ul, 2ul) == 2);
static_assert(upx::umax(1ull, 2ull) == 2);
static_assert(upx::wrapping_add<upx_int8_t>(127, 2) == -127);
static_assert(upx::wrapping_add<upx_int16_t>(32767, 2) == -32767);
@@ -241,6 +278,9 @@ static_assert(upx::wrapping_sub<upx_int16_t>(-32767, 2) == 32767);
static_assert(upx::wrapping_sub(-2147483647, 2) == 2147483647);
static_assert(upx::wrapping_sub(-9223372036854775807ll, 2ll) == 9223372036854775807ll);
static_assert(upx::wrapping_add<upx_uint8_t>(255, 2) == 1);
static_assert(upx::wrapping_sub<upx_uint8_t>(1, 2) == 255);
/*************************************************************************
// util
**************************************************************************/
@@ -518,23 +558,6 @@ TEST_CASE("upx::ObjectDeleter 2") {
}
}
TEST_CASE("upx::noncopyable") {
struct Test : private upx::noncopyable {
int v = 1;
};
Test t = {};
CHECK(t.v == 1);
#if (ACC_CC_MSC) // MSVC thinks that Test is not std::is_trivially_copyable; true or compiler bug?
// @COMPILER_BUG @MSVC_BUG
t.v = 0;
#else
mem_clear(&t);
#endif
CHECK(t.v == 0);
constexpr Test x = {};
static_assert(x.v == 1);
}
/*************************************************************************
// namespace upx::compile_time
**************************************************************************/
+5 -5
View File
@@ -127,11 +127,11 @@ static bool prepare_result(lzma_compress_result_t *res, unsigned src_len, int me
// cconf overrides
if (lcconf) {
oassign(res->pos_bits, lcconf->pos_bits);
oassign(res->lit_pos_bits, lcconf->lit_pos_bits);
oassign(res->lit_context_bits, lcconf->lit_context_bits);
oassign(res->dict_size, lcconf->dict_size);
oassign(res->num_fast_bytes, lcconf->num_fast_bytes);
upx::oassign(res->pos_bits, lcconf->pos_bits);
upx::oassign(res->lit_pos_bits, lcconf->lit_pos_bits);
upx::oassign(res->lit_context_bits, lcconf->lit_context_bits);
upx::oassign(res->dict_size, lcconf->dict_size);
upx::oassign(res->num_fast_bytes, lcconf->num_fast_bytes);
}
// limit dictionary size
+3 -3
View File
@@ -97,9 +97,9 @@ int upx_zlib_compress(const upx_bytep src, unsigned src_len, upx_bytep dst, unsi
zlib_compress_config_t::strategy_t strategy;
// cconf overrides
if (lcconf) {
oassign(mem_level, lcconf->mem_level);
oassign(window_bits, lcconf->window_bits);
oassign(strategy, lcconf->strategy);
upx::oassign(mem_level, lcconf->mem_level);
upx::oassign(window_bits, lcconf->window_bits);
upx::oassign(strategy, lcconf->strategy);
}
z_stream s;
+8 -11
View File
@@ -465,9 +465,6 @@ noreturn void throwAssertFailed(const char *expr, const char *file, int line, co
// C++ support library
#include "util/cxxlib.h"
using upx::is_same_any_v;
using upx::noncopyable;
using upx::OptVar;
using upx::tribool;
#define usizeof(expr) (upx::UnsignedSizeOf<sizeof(expr)>::value)
@@ -649,11 +646,11 @@ struct bzip2_compress_config_t final {
};
struct lzma_compress_config_t final {
typedef OptVar<unsigned, 2u, 0u, 4u> pos_bits_t; // pb
typedef OptVar<unsigned, 0u, 0u, 4u> lit_pos_bits_t; // lp
typedef OptVar<unsigned, 3u, 0u, 8u> lit_context_bits_t; // lc
typedef OptVar<unsigned, (1u << 22), 1u, (1u << 30)> dict_size_t;
typedef OptVar<unsigned, 64u, 5u, 273u> num_fast_bytes_t;
typedef upx::OptVar<unsigned, 2u, 0u, 4u> pos_bits_t; // pb
typedef upx::OptVar<unsigned, 0u, 0u, 4u> lit_pos_bits_t; // lp
typedef upx::OptVar<unsigned, 3u, 0u, 8u> lit_context_bits_t; // lc
typedef upx::OptVar<unsigned, (1u << 22), 1u, (1u << 30)> dict_size_t;
typedef upx::OptVar<unsigned, 64u, 5u, 273u> num_fast_bytes_t;
pos_bits_t pos_bits; // pb
lit_pos_bits_t lit_pos_bits; // lp
@@ -673,9 +670,9 @@ struct ucl_compress_config_t final : public REAL_ucl_compress_config_t {
};
struct zlib_compress_config_t final {
typedef OptVar<unsigned, 8u, 1u, 9u> mem_level_t; // ml
typedef OptVar<unsigned, 15u, 9u, 15u> window_bits_t; // wb
typedef OptVar<unsigned, 0u, 0u, 4u> strategy_t; // st
typedef upx::OptVar<unsigned, 8u, 1u, 9u> mem_level_t; // ml
typedef upx::OptVar<unsigned, 15u, 9u, 15u> window_bits_t; // wb
typedef upx::OptVar<unsigned, 0u, 0u, 4u> strategy_t; // st
mem_level_t mem_level; // ml
window_bits_t window_bits; // wb
-2
View File
@@ -28,8 +28,6 @@
#include "../conf.h"
#include "../filter.h"
static unsigned umin(const unsigned a, const unsigned b) { return (a <= b) ? a : b; }
#define set_dummy(p, v) ((void) 0)
#define get_8(p) (*(p))
#define set_8(p, v) (*(p) = (v))
+2 -2
View File
@@ -44,7 +44,7 @@ static int F(Filter *f) {
// scan
const byte *b = f->buf;
#endif
const unsigned size = umin(f->buf_len, 0u - (~0u << (32 - (6 + W_CTO))));
const unsigned size = upx::umin(f->buf_len, 0u - (~0u << (32 - (6 + W_CTO))));
const unsigned size4 = size - 4;
unsigned ic;
@@ -123,7 +123,7 @@ static int F(Filter *f) {
#ifdef U
static int U(Filter *f) {
byte *b = f->buf;
const unsigned size4 = umin(f->buf_len - 4, 0u - (~0u << (32 - (6 + W_CTO))));
const unsigned size4 = upx::umin(f->buf_len - 4, 0u - (~0u << (32 - (6 + W_CTO))));
const unsigned addvalue = f->addvalue;
unsigned ic;
+4 -4
View File
@@ -31,7 +31,7 @@
// ElfLinker
**************************************************************************/
class ElfLinker : private noncopyable {
class ElfLinker : private upx::noncopyable {
friend class Packer;
public:
@@ -114,7 +114,7 @@ protected:
const char *type);
};
struct ElfLinker::Section : private noncopyable {
struct ElfLinker::Section : private upx::noncopyable {
char *name = nullptr;
void *input = nullptr;
byte *output = nullptr;
@@ -128,7 +128,7 @@ struct ElfLinker::Section : private noncopyable {
~Section() noexcept;
};
struct ElfLinker::Symbol : private noncopyable {
struct ElfLinker::Symbol : private upx::noncopyable {
char *name = nullptr;
Section *section = nullptr;
upx_uint64_t offset = 0;
@@ -137,7 +137,7 @@ struct ElfLinker::Symbol : private noncopyable {
~Symbol() noexcept;
};
struct ElfLinker::Relocation : private noncopyable {
struct ElfLinker::Relocation : private upx::noncopyable {
const Section *section = nullptr;
unsigned offset = 0;
const char *type = nullptr;
+2 -1
View File
@@ -343,7 +343,8 @@ done:
}
template <class T, T default_value, T min_value, T max_value>
static int getoptvar(OptVar<T, default_value, min_value, max_value> *var, const char *arg_fatal) {
static int getoptvar(upx::OptVar<T, default_value, min_value, max_value> *var,
const char *arg_fatal) {
T v = default_value;
int r = getoptvar(&v, min_value, max_value, arg_fatal);
if (r == 0)
+5 -14
View File
@@ -43,7 +43,7 @@
#include "p_lx_elf.h"
#include "ui.h"
using upx::umax, upx::umin;
using upx::umin;
#define PT_LOAD32 Elf32_Phdr::PT_LOAD
#define PT_LOAD64 Elf64_Phdr::PT_LOAD
@@ -1304,15 +1304,6 @@ PackLinuxElf64arm::~PackLinuxElf64arm()
{
}
static unsigned
umax(unsigned a, unsigned b)
{
if (a <= b) {
return b;
}
return a;
}
void PackLinuxElf32x86::addStubEntrySections(Filter const *ft, unsigned m_decompr)
{
(void)m_decompr; // FIXME
@@ -1467,9 +1458,9 @@ PackLinuxElf32::buildLinuxLoader(
}
else {
cprElfHdr1 const *const hf = (cprElfHdr1 const *)fold;
unsigned fold_hdrlen = umax(0x80, usizeof(hf->ehdr) +
unsigned fold_hdrlen = upx::umax(0x80u, usizeof(hf->ehdr) +
get_te16(&hf->ehdr.e_phentsize) * get_te16(&hf->ehdr.e_phnum) +
sizeof(l_info) );
usizeof(l_info) );
uncLoader = fold_hdrlen + fold;
sz_unc = ((szfold < fold_hdrlen) ? 0 : (szfold - fold_hdrlen));
method = ph.method;
@@ -1573,9 +1564,9 @@ PackLinuxElf64::buildLinuxLoader(
}
else {
cprElfHdr1 const *const hf = (cprElfHdr1 const *)fold;
unsigned fold_hdrlen = umax(0x80, usizeof(hf->ehdr) +
unsigned fold_hdrlen = upx::umax(0x80u, usizeof(hf->ehdr) +
get_te16(&hf->ehdr.e_phentsize) * get_te16(&hf->ehdr.e_phnum) +
sizeof(l_info) );
usizeof(l_info) );
uncLoader = fold_hdrlen + fold;
sz_unc = ((szfold < fold_hdrlen) ? 0 : (szfold - fold_hdrlen));
method = ph.method;
+8 -8
View File
@@ -193,16 +193,16 @@ bool Packer::compress(SPAN_P(byte) i_ptr, unsigned i_len, SPAN_P(byte) o_ptr,
#endif
}
if (M_IS_LZMA(method)) {
oassign(cconf.conf_lzma.pos_bits, opt->crp.crp_lzma.pos_bits);
oassign(cconf.conf_lzma.lit_pos_bits, opt->crp.crp_lzma.lit_pos_bits);
oassign(cconf.conf_lzma.lit_context_bits, opt->crp.crp_lzma.lit_context_bits);
oassign(cconf.conf_lzma.dict_size, opt->crp.crp_lzma.dict_size);
oassign(cconf.conf_lzma.num_fast_bytes, opt->crp.crp_lzma.num_fast_bytes);
upx::oassign(cconf.conf_lzma.pos_bits, opt->crp.crp_lzma.pos_bits);
upx::oassign(cconf.conf_lzma.lit_pos_bits, opt->crp.crp_lzma.lit_pos_bits);
upx::oassign(cconf.conf_lzma.lit_context_bits, opt->crp.crp_lzma.lit_context_bits);
upx::oassign(cconf.conf_lzma.dict_size, opt->crp.crp_lzma.dict_size);
upx::oassign(cconf.conf_lzma.num_fast_bytes, opt->crp.crp_lzma.num_fast_bytes);
}
if (M_IS_DEFLATE(method)) {
oassign(cconf.conf_zlib.mem_level, opt->crp.crp_zlib.mem_level);
oassign(cconf.conf_zlib.window_bits, opt->crp.crp_zlib.window_bits);
oassign(cconf.conf_zlib.strategy, opt->crp.crp_zlib.strategy);
upx::oassign(cconf.conf_zlib.mem_level, opt->crp.crp_zlib.mem_level);
upx::oassign(cconf.conf_zlib.window_bits, opt->crp.crp_zlib.window_bits);
upx::oassign(cconf.conf_zlib.strategy, opt->crp.crp_zlib.strategy);
}
if (uip->ui_pass >= 0)
uip->ui_pass++;
+6 -3
View File
@@ -267,11 +267,14 @@ protected:
#else
// try to detect TE16 vs TE32 vs TE64 size mismatches; note that byte is explicitly allowed
template <class T>
static inline constexpr bool is_te16_type = is_same_any_v<T, byte, upx_uint16_t, BE16, LE16>;
static inline constexpr bool is_te16_type =
upx::is_same_any_v<T, byte, upx_uint16_t, BE16, LE16>;
template <class T>
static inline constexpr bool is_te32_type = is_same_any_v<T, byte, upx_uint32_t, BE32, LE32>;
static inline constexpr bool is_te32_type =
upx::is_same_any_v<T, byte, upx_uint32_t, BE32, LE32>;
template <class T>
static inline constexpr bool is_te64_type = is_same_any_v<T, byte, upx_uint64_t, BE64, LE64>;
static inline constexpr bool is_te64_type =
upx::is_same_any_v<T, byte, upx_uint64_t, BE64, LE64>;
template <class T>
using enable_if_te16 = std::enable_if_t<is_te16_type<T>, T>;
template <class T>
+4 -4
View File
@@ -371,7 +371,7 @@ protected:
IMAGE_REL_BASED_DIR64 = 10,
};
class Interval final : private noncopyable {
class Interval final : private upx::noncopyable {
SPAN_0(byte) base = nullptr;
unsigned ivcapacity = 0; // for ivarr
public:
@@ -397,7 +397,7 @@ protected:
static int __acc_cdecl_qsort compare(const void *p1, const void *p2);
};
class Reloc final : private noncopyable {
class Reloc final : private upx::noncopyable {
// these are set in the constructor:
byte *start = nullptr;
unsigned start_size_in_bytes = 0;
@@ -433,7 +433,7 @@ protected:
void finish(byte *(&result_ptr), unsigned &result_size); // => transfer ownership
};
class Resource final : private noncopyable {
class Resource final : private upx::noncopyable {
struct res_dir_entry;
struct res_dir;
struct res_data;
@@ -489,7 +489,7 @@ protected:
*/
};
class Export final : private noncopyable {
class Export final : private upx::noncopyable {
struct alignas(1) export_dir_t {
byte _[12]; // flags, timedate, version
LE32 name;
+15 -15
View File
@@ -141,6 +141,17 @@ private:
#define UPX_CXX_DISABLE_NEW_DELETE_NO_VIRTUAL(Klass) private:
#endif
class noncopyable {
protected:
forceinline constexpr noncopyable() noexcept {}
#if __cplusplus >= 202002L
forceinline constexpr ~noncopyable() noexcept = default;
#else
forceinline ~noncopyable() noexcept = default;
#endif
UPX_CXX_DISABLE_COPY_MOVE(noncopyable)
};
/*************************************************************************
// <type_traits>
**************************************************************************/
@@ -178,21 +189,21 @@ forceinline constexpr bool has_single_bit(T x) noexcept {
template <class T>
inline constexpr T align_down(const T &x, const T &alignment) noexcept {
// assert_noexcept(has_single_bit(alignment));
// assert_noexcept(has_single_bit(alignment)); // (not constexpr)
T r = {};
r = (x / alignment) * alignment;
return r;
}
template <class T>
inline constexpr T align_up(const T &x, const T &alignment) noexcept {
// assert_noexcept(has_single_bit(alignment));
// assert_noexcept(has_single_bit(alignment)); // (not constexpr)
T r = {};
r = ((x + (alignment - 1)) / alignment) * alignment;
return r;
}
template <class T>
inline constexpr T align_gap(const T &x, const T &alignment) noexcept {
// assert_noexcept(has_single_bit(alignment));
// assert_noexcept(has_single_bit(alignment)); // (not constexpr)
T r = {};
r = align_up(x, alignment) - x;
return r;
@@ -209,7 +220,7 @@ forceinline constexpr T max(const T &a, const T &b) noexcept {
template <class T>
inline constexpr bool is_uminmax_type =
is_same_any_v<T, upx_uint16_t, upx_uint32_t, upx_uint64_t, unsigned long, size_t>;
is_same_any_v<T, upx_uint8_t, upx_uint16_t, upx_uint32_t, upx_uint64_t, unsigned long, size_t>;
template <class T, class = std::enable_if_t<is_uminmax_type<T>, T> >
forceinline constexpr T umin(const T &a, const T &b) noexcept {
@@ -343,17 +354,6 @@ struct MallocDeleter final {
}
};
class noncopyable {
protected:
forceinline constexpr noncopyable() noexcept {}
#if __cplusplus >= 202002L
forceinline constexpr ~noncopyable() noexcept = default;
#else
forceinline ~noncopyable() noexcept = default;
#endif
UPX_CXX_DISABLE_COPY_MOVE(noncopyable)
};
/*************************************************************************
// compile_time
**************************************************************************/
+4 -3
View File
@@ -93,9 +93,9 @@ T *NewArray(upx_uint64_t n) may_throw {
// ptr util
**************************************************************************/
// also see CHERI cheri_address_get()
forceinline upx_ptraddr_t ptr_get_address(const void *p) { return (upx_uintptr_t) p; }
forceinline upx_ptraddr_t ptr_get_address(upx_uintptr_t p) { return p; }
// TODO later: CHERI; see cheri_address_get()
forceinline upx_ptraddr_t ptr_get_address(const void *p) noexcept { return (upx_uintptr_t) p; }
forceinline upx_ptraddr_t ptr_get_address(upx_uintptr_t p) noexcept { return p; }
// ptrdiff_t with nullptr checks and asserted size; will throw on failure
// NOTE: returns size_in_bytes, not number of elements!
@@ -138,6 +138,7 @@ forceinline void ptr_check_no_overlap(const void *a, size_t a_size, const void *
// - this should play nice with static analyzers like clang-tidy etc.
// NOTE: this is clearly UB (Undefined Behaviour), and stricter compilers or
// architectures may need a more advanced/costly implementation in the future
// TODO later: CHERI
template <class T>
inline void ptr_invalidate_and_poison(T *(&ptr)) noexcept {
ptr = (T *) (void *) 251; // 0x000000fb // NOLINT(performance-no-int-to-ptr)