src: more upx::max cleanups
This commit is contained in:
parent
57763ca1e2
commit
344246725b
110
src/bele.h
110
src/bele.h
@ -42,6 +42,14 @@
|
||||
#define bswap64 upx_bswap64
|
||||
#endif
|
||||
|
||||
// forward declarations
|
||||
struct BE16;
|
||||
struct BE32;
|
||||
struct BE64;
|
||||
struct LE16;
|
||||
struct LE32;
|
||||
struct LE64;
|
||||
|
||||
/*************************************************************************
|
||||
// XE - eXtended Endian compatibility
|
||||
// try to detect XX16 vs XX32 vs XX64 size mismatches
|
||||
@ -61,14 +69,6 @@ typedef void XE64;
|
||||
|
||||
#else // permissive version
|
||||
|
||||
// forward declarations
|
||||
struct BE16;
|
||||
struct BE32;
|
||||
struct BE64;
|
||||
struct LE16;
|
||||
struct LE32;
|
||||
struct LE64;
|
||||
|
||||
namespace bele_detail {
|
||||
|
||||
// Note:
|
||||
@ -755,35 +755,81 @@ T *operator+(const LE64 &v, T *ptr) noexcept DELETED_FUNCTION;
|
||||
|
||||
namespace upx {
|
||||
|
||||
inline unsigned align_down(unsigned a, const BE32 &b) { return align_down(a, unsigned(b)); }
|
||||
inline unsigned align_down(const BE32 &a, unsigned b) { return align_down(unsigned(a), b); }
|
||||
inline unsigned align_up(unsigned a, const BE32 &b) { return align_up(a, unsigned(b)); }
|
||||
inline unsigned align_up(const BE32 &a, unsigned b) { return align_up(unsigned(a), b); }
|
||||
#define REQUIRE_UINT32 \
|
||||
template <class T, class = std::enable_if_t<std::is_same_v<T, upx_uint32_t>, T> >
|
||||
#define REQUIRE_UINT64 \
|
||||
template <class T, class = std::enable_if_t<std::is_same_v<T, upx_uint64_t>, T> >
|
||||
|
||||
inline unsigned align_down(unsigned a, const LE32 &b) { return align_down(a, unsigned(b)); }
|
||||
inline unsigned align_down(const LE32 &a, unsigned b) { return align_down(unsigned(a), b); }
|
||||
inline unsigned align_up(unsigned a, const LE32 &b) { return align_up(a, unsigned(b)); }
|
||||
inline unsigned align_up(const LE32 &a, unsigned b) { return align_up(unsigned(a), b); }
|
||||
REQUIRE_UINT32
|
||||
inline T align_down(const T &a, const BE32 &b) noexcept { return align_down(a, T(b)); }
|
||||
REQUIRE_UINT32
|
||||
inline T align_down(const BE32 &a, const T &b) noexcept { return align_down(T(a), b); }
|
||||
REQUIRE_UINT32
|
||||
inline T align_down(const T &a, const LE32 &b) noexcept { return align_down(a, T(b)); }
|
||||
REQUIRE_UINT32
|
||||
inline T align_down(const LE32 &a, const T &b) noexcept { return align_down(T(a), b); }
|
||||
|
||||
inline unsigned max(unsigned a, const BE16 &b) { return max(a, unsigned(b)); }
|
||||
inline unsigned max(const BE16 &a, unsigned b) { return max(unsigned(a), b); }
|
||||
inline unsigned min(unsigned a, const BE16 &b) { return min(a, unsigned(b)); }
|
||||
inline unsigned min(const BE16 &a, unsigned b) { return min(unsigned(a), b); }
|
||||
REQUIRE_UINT32
|
||||
inline T align_up(const T &a, const LE32 &b) noexcept { return align_up(a, T(b)); }
|
||||
REQUIRE_UINT32
|
||||
inline T align_up(const LE32 &a, const T &b) noexcept { return align_up(T(a), b); }
|
||||
REQUIRE_UINT32
|
||||
inline T align_up(const T &a, const BE32 &b) noexcept { return align_up(a, T(b)); }
|
||||
REQUIRE_UINT32
|
||||
inline T align_up(const BE32 &a, const T &b) noexcept { return align_up(T(a), b); }
|
||||
|
||||
inline unsigned max(unsigned a, const BE32 &b) { return max(a, unsigned(b)); }
|
||||
inline unsigned max(const BE32 &a, unsigned b) { return max(unsigned(a), b); }
|
||||
inline unsigned min(unsigned a, const BE32 &b) { return min(a, unsigned(b)); }
|
||||
inline unsigned min(const BE32 &a, unsigned b) { return min(unsigned(a), b); }
|
||||
REQUIRE_UINT32
|
||||
inline T min(const T &a, const BE16 &b) noexcept { return min(a, T(b)); }
|
||||
REQUIRE_UINT32
|
||||
inline T min(const BE16 &a, const T &b) noexcept { return min(T(a), b); }
|
||||
REQUIRE_UINT32
|
||||
inline T min(const T &a, const BE32 &b) noexcept { return min(a, T(b)); }
|
||||
REQUIRE_UINT32
|
||||
inline T min(const BE32 &a, const T &b) noexcept { return min(T(a), b); }
|
||||
REQUIRE_UINT64
|
||||
inline T min(const T &a, const BE64 &b) noexcept { return min(a, T(b)); }
|
||||
REQUIRE_UINT64
|
||||
inline T min(const BE64 &a, const T &b) noexcept { return min(T(a), b); }
|
||||
REQUIRE_UINT32
|
||||
inline T min(const T &a, const LE16 &b) noexcept { return min(a, T(b)); }
|
||||
REQUIRE_UINT32
|
||||
inline T min(const LE16 &a, const T &b) noexcept { return min(T(a), b); }
|
||||
REQUIRE_UINT32
|
||||
inline T min(const T &a, const LE32 &b) noexcept { return min(a, T(b)); }
|
||||
REQUIRE_UINT32
|
||||
inline T min(const LE32 &a, const T &b) noexcept { return min(T(a), b); }
|
||||
REQUIRE_UINT64
|
||||
inline T min(const T &a, const LE64 &b) noexcept { return min(a, T(b)); }
|
||||
REQUIRE_UINT64
|
||||
inline T min(const LE64 &a, const T &b) noexcept { return min(T(a), b); }
|
||||
|
||||
inline unsigned max(unsigned a, const LE16 &b) { return max(a, unsigned(b)); }
|
||||
inline unsigned max(const LE16 &a, unsigned b) { return max(unsigned(a), b); }
|
||||
inline unsigned min(unsigned a, const LE16 &b) { return min(a, unsigned(b)); }
|
||||
inline unsigned min(const LE16 &a, unsigned b) { return min(unsigned(a), b); }
|
||||
REQUIRE_UINT32
|
||||
inline T max(const T &a, const BE16 &b) noexcept { return max(a, T(b)); }
|
||||
REQUIRE_UINT32
|
||||
inline T max(const BE16 &a, const T &b) noexcept { return max(T(a), b); }
|
||||
REQUIRE_UINT32
|
||||
inline T max(const T &a, const BE32 &b) noexcept { return max(a, T(b)); }
|
||||
REQUIRE_UINT32
|
||||
inline T max(const BE32 &a, const T &b) noexcept { return max(T(a), b); }
|
||||
REQUIRE_UINT64
|
||||
inline T max(const T &a, const BE64 &b) noexcept { return max(a, T(b)); }
|
||||
REQUIRE_UINT64
|
||||
inline T max(const BE64 &a, const T &b) noexcept { return max(T(a), b); }
|
||||
REQUIRE_UINT32
|
||||
inline T max(const T &a, const LE16 &b) noexcept { return max(a, T(b)); }
|
||||
REQUIRE_UINT32
|
||||
inline T max(const LE16 &a, const T &b) noexcept { return max(T(a), b); }
|
||||
REQUIRE_UINT32
|
||||
inline T max(const T &a, const LE32 &b) noexcept { return max(a, T(b)); }
|
||||
REQUIRE_UINT32
|
||||
inline T max(const LE32 &a, const T &b) noexcept { return max(T(a), b); }
|
||||
REQUIRE_UINT64
|
||||
inline T max(const T &a, const LE64 &b) noexcept { return max(a, T(b)); }
|
||||
REQUIRE_UINT64
|
||||
inline T max(const LE64 &a, const T &b) noexcept { return max(T(a), b); }
|
||||
|
||||
inline unsigned max(unsigned a, const LE32 &b) { return max(a, unsigned(b)); }
|
||||
inline unsigned max(const LE32 &a, unsigned b) { return max(unsigned(a), b); }
|
||||
inline unsigned min(unsigned a, const LE32 &b) { return min(a, unsigned(b)); }
|
||||
inline unsigned min(const LE32 &a, unsigned b) { return min(unsigned(a), b); }
|
||||
#undef REQUIRE_UINT32
|
||||
#undef REQUIRE_UINT64
|
||||
|
||||
} // namespace upx
|
||||
|
||||
|
||||
@ -298,48 +298,119 @@ struct CheckAlignment {
|
||||
template <class T>
|
||||
struct TestBELE {
|
||||
static noinline bool test(void) noexcept {
|
||||
static_assert(upx::is_same_any_v<T, BE16, BE32, BE64, LE16, LE32, LE64>);
|
||||
static_assert(
|
||||
upx::is_same_any_v<typename T::integral_conversion_type, upx_uint32_t, upx_uint64_t>);
|
||||
CheckIntegral<T>::check();
|
||||
CheckAlignment<T>::check();
|
||||
// arithmetic checks
|
||||
T all_bits = {};
|
||||
assert_noexcept(all_bits == 0);
|
||||
all_bits += 1;
|
||||
all_bits -= 2;
|
||||
T v1;
|
||||
v1 = 1;
|
||||
v1 *= 4;
|
||||
v1 /= 2;
|
||||
v1 -= 1;
|
||||
T v2;
|
||||
v2 = 1;
|
||||
assert_noexcept((v1 == v2));
|
||||
assert_noexcept(!(v1 != v2));
|
||||
assert_noexcept((v1 <= v2));
|
||||
assert_noexcept((v1 >= v2));
|
||||
assert_noexcept(!(v1 < v2));
|
||||
assert_noexcept(!(v1 > v2));
|
||||
v2 ^= all_bits;
|
||||
assert_noexcept(!(v1 == v2));
|
||||
assert_noexcept((v1 != v2));
|
||||
assert_noexcept((v1 <= v2));
|
||||
assert_noexcept(!(v1 >= v2));
|
||||
assert_noexcept((v1 < v2));
|
||||
assert_noexcept(!(v1 > v2));
|
||||
v2 += 2;
|
||||
assert_noexcept(v1 == 1);
|
||||
assert_noexcept(v2 == 0);
|
||||
v1 <<= 1;
|
||||
v1 |= v2;
|
||||
v1 >>= 1;
|
||||
v2 &= v1;
|
||||
v2 /= v1;
|
||||
v2 *= v1;
|
||||
v1 += v2;
|
||||
v1 -= v2;
|
||||
assert_noexcept(v1 == 1);
|
||||
assert_noexcept(v2 == 0);
|
||||
if ((v1 ^ v2) != 1)
|
||||
return false;
|
||||
{
|
||||
T all_bits = {}; // == zero
|
||||
assert_noexcept(all_bits == 0);
|
||||
assert_noexcept(!upx::has_single_bit(all_bits));
|
||||
all_bits += 1;
|
||||
assert_noexcept(upx::has_single_bit(all_bits));
|
||||
all_bits -= 2;
|
||||
assert_noexcept(!upx::has_single_bit(all_bits));
|
||||
T v1;
|
||||
v1 = 1;
|
||||
v1 *= 4;
|
||||
v1 /= 2;
|
||||
v1 -= 1;
|
||||
T v2;
|
||||
v2 = 1;
|
||||
assert_noexcept((v1 == v2));
|
||||
assert_noexcept(!(v1 != v2));
|
||||
assert_noexcept((v1 <= v2));
|
||||
assert_noexcept((v1 >= v2));
|
||||
assert_noexcept(!(v1 < v2));
|
||||
assert_noexcept(!(v1 > v2));
|
||||
v2 ^= all_bits;
|
||||
assert_noexcept(!(v1 == v2));
|
||||
assert_noexcept((v1 != v2));
|
||||
assert_noexcept((v1 <= v2));
|
||||
assert_noexcept(!(v1 >= v2));
|
||||
assert_noexcept((v1 < v2));
|
||||
assert_noexcept(!(v1 > v2));
|
||||
v2 += 2;
|
||||
assert_noexcept(v1 == 1);
|
||||
assert_noexcept(v2 == 0);
|
||||
v1 <<= 1;
|
||||
v1 |= v2;
|
||||
v1 >>= 1;
|
||||
v2 &= v1;
|
||||
v2 /= v1;
|
||||
v2 *= v1;
|
||||
v1 += v2;
|
||||
v1 -= v2;
|
||||
assert_noexcept(v1 == 1);
|
||||
assert_noexcept(v2 == 0);
|
||||
if ((v1 ^ v2) != 1)
|
||||
return false;
|
||||
}
|
||||
// min/max
|
||||
{
|
||||
constexpr T a = {}; // == zero
|
||||
typedef typename T::integral_conversion_type U;
|
||||
constexpr U b = 1;
|
||||
assert_noexcept(upx::min(a, a) == 0);
|
||||
assert_noexcept(upx::min(a, a) == a);
|
||||
assert_noexcept(upx::min(a, b) == 0);
|
||||
assert_noexcept(upx::min(a, b) == a);
|
||||
assert_noexcept(upx::min(b, a) == 0);
|
||||
assert_noexcept(upx::min(b, a) == a);
|
||||
assert_noexcept(upx::min(b, b) == 1);
|
||||
assert_noexcept(upx::min(b, b) == b);
|
||||
assert_noexcept(upx::max(a, a) == 0);
|
||||
assert_noexcept(upx::max(a, a) == a);
|
||||
assert_noexcept(upx::max(a, b) == 1);
|
||||
assert_noexcept(upx::max(a, b) == b);
|
||||
assert_noexcept(upx::max(b, a) == 1);
|
||||
assert_noexcept(upx::max(b, a) == b);
|
||||
assert_noexcept(upx::max(b, b) == 1);
|
||||
assert_noexcept(upx::max(b, b) == b);
|
||||
T minus_one_t = {}, minus_two_t = {};
|
||||
minus_one_t -= 1;
|
||||
minus_two_t -= 2;
|
||||
const U minus_one_u = minus_one_t;
|
||||
const U minus_two_u = minus_two_t;
|
||||
assert_noexcept(upx::min(minus_one_t, minus_one_t) == minus_one_t);
|
||||
assert_noexcept(upx::min(minus_one_t, minus_one_t) == minus_one_u);
|
||||
assert_noexcept(upx::min(minus_one_u, minus_one_t) == minus_one_t);
|
||||
assert_noexcept(upx::min(minus_one_u, minus_one_t) == minus_one_u);
|
||||
assert_noexcept(upx::min(minus_one_t, minus_one_u) == minus_one_t);
|
||||
assert_noexcept(upx::min(minus_one_t, minus_one_u) == minus_one_u);
|
||||
assert_noexcept(upx::min(minus_two_t, minus_one_t) == minus_two_t);
|
||||
assert_noexcept(upx::min(minus_two_t, minus_one_t) == minus_two_u);
|
||||
assert_noexcept(upx::min(minus_two_u, minus_one_t) == minus_two_t);
|
||||
assert_noexcept(upx::min(minus_two_u, minus_one_t) == minus_two_u);
|
||||
assert_noexcept(upx::min(minus_two_t, minus_one_u) == minus_two_t);
|
||||
assert_noexcept(upx::min(minus_two_t, minus_one_u) == minus_two_u);
|
||||
assert_noexcept(upx::min(minus_one_t, minus_two_t) == minus_two_t);
|
||||
assert_noexcept(upx::min(minus_one_t, minus_two_t) == minus_two_u);
|
||||
assert_noexcept(upx::min(minus_one_u, minus_two_t) == minus_two_t);
|
||||
assert_noexcept(upx::min(minus_one_u, minus_two_t) == minus_two_u);
|
||||
assert_noexcept(upx::min(minus_one_t, minus_two_u) == minus_two_t);
|
||||
assert_noexcept(upx::min(minus_one_t, minus_two_u) == minus_two_u);
|
||||
assert_noexcept(upx::max(minus_one_t, minus_one_t) == minus_one_t);
|
||||
assert_noexcept(upx::max(minus_one_t, minus_one_t) == minus_one_u);
|
||||
assert_noexcept(upx::max(minus_one_u, minus_one_t) == minus_one_t);
|
||||
assert_noexcept(upx::max(minus_one_u, minus_one_t) == minus_one_u);
|
||||
assert_noexcept(upx::max(minus_one_t, minus_one_u) == minus_one_t);
|
||||
assert_noexcept(upx::max(minus_one_t, minus_one_u) == minus_one_u);
|
||||
assert_noexcept(upx::max(minus_two_t, minus_one_t) == minus_one_t);
|
||||
assert_noexcept(upx::max(minus_two_t, minus_one_t) == minus_one_u);
|
||||
assert_noexcept(upx::max(minus_two_u, minus_one_t) == minus_one_t);
|
||||
assert_noexcept(upx::max(minus_two_u, minus_one_t) == minus_one_u);
|
||||
assert_noexcept(upx::max(minus_two_t, minus_one_u) == minus_one_t);
|
||||
assert_noexcept(upx::max(minus_two_t, minus_one_u) == minus_one_u);
|
||||
assert_noexcept(upx::max(minus_one_t, minus_two_t) == minus_one_t);
|
||||
assert_noexcept(upx::max(minus_one_t, minus_two_t) == minus_one_u);
|
||||
assert_noexcept(upx::max(minus_one_u, minus_two_t) == minus_one_t);
|
||||
assert_noexcept(upx::max(minus_one_u, minus_two_t) == minus_one_u);
|
||||
assert_noexcept(upx::max(minus_one_t, minus_two_u) == minus_one_t);
|
||||
assert_noexcept(upx::max(minus_one_t, minus_two_u) == minus_one_u);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
@ -243,7 +243,8 @@ void PackW32PeI386::setOhDataBase(const pe_section_t *osection) { oh.database =
|
||||
|
||||
void PackW32PeI386::setOhHeaderSize(const pe_section_t *osection) {
|
||||
// SizeOfHeaders
|
||||
oh.headersize = ALIGN_UP(pe_offset + sizeof(oh) + sizeof(*osection) * oh.objects, oh.filealign);
|
||||
oh.headersize =
|
||||
ALIGN_UP(pe_offset + usizeof(oh) + usizeof(*osection) * oh.objects, oh.filealign);
|
||||
}
|
||||
|
||||
void PackW32PeI386::pack(OutputFile *fo) {
|
||||
|
||||
@ -236,7 +236,8 @@ void PackW64PeAmd64::defineSymbols(unsigned ncsection, unsigned upxsection, unsi
|
||||
|
||||
void PackW64PeAmd64::setOhHeaderSize(const pe_section_t *osection) {
|
||||
// SizeOfHeaders
|
||||
oh.headersize = ALIGN_UP(pe_offset + sizeof(oh) + sizeof(*osection) * oh.objects, oh.filealign);
|
||||
oh.headersize =
|
||||
ALIGN_UP(pe_offset + usizeof(oh) + usizeof(*osection) * oh.objects, oh.filealign);
|
||||
}
|
||||
|
||||
void PackW64PeAmd64::pack(OutputFile *fo) {
|
||||
|
||||
@ -1417,7 +1417,7 @@ void PeFile::processTls1(Interval *iv, typename tls_traits<LEXX>::cb_value_t ima
|
||||
// ... and those dwords should be correctly aligned
|
||||
if (use_tls_callbacks)
|
||||
sotls = ALIGN_UP(sotls, cb_size) + 2 * cb_size;
|
||||
const unsigned aligned_sotls = ALIGN_UP(sotls, (unsigned) sizeof(LEXX));
|
||||
const unsigned aligned_sotls = ALIGN_UP(sotls, usizeof(LEXX));
|
||||
|
||||
// the PE loader wants this stuff uncompressed
|
||||
mb_otls.alloc(aligned_sotls);
|
||||
@ -2140,7 +2140,7 @@ void PeFile::checkHeaderValues(unsigned subsystem, unsigned mask, unsigned ih_en
|
||||
throwCantPack("run a virus scanner on this file!");
|
||||
|
||||
const unsigned fam1 = ih_filealign - 1;
|
||||
if (!(1 + fam1) || (1 + fam1) & fam1) { // ih_filealign is not a power of 2
|
||||
if (!upx::has_single_bit(ih_filealign)) { // ih_filealign is not a power of 2
|
||||
char buf[32];
|
||||
snprintf(buf, sizeof(buf), "bad file alignment %#x", 1 + fam1);
|
||||
throwCantPack(buf);
|
||||
@ -2338,7 +2338,7 @@ void PeFile::pack0(OutputFile *fo, ht &ih, ht &oh, unsigned subsystem_mask,
|
||||
allow_filter = false;
|
||||
|
||||
const unsigned oam1 = ih.objectalign - 1;
|
||||
if (!(1 + oam1) || (1 + oam1) & oam1) { // ih.objectalign is not a power of 2
|
||||
if (!upx::has_single_bit(ih.objectalign)) { // ih.objectalign is not a power of 2
|
||||
char buf[32];
|
||||
snprintf(buf, sizeof(buf), "bad object alignment %#x", 1 + oam1);
|
||||
throwCantPack(buf);
|
||||
@ -2414,7 +2414,7 @@ void PeFile::pack0(OutputFile *fo, ht &ih, ht &oh, unsigned subsystem_mask,
|
||||
if (tlsindex && ((newvsize - ph.c_len - 1024 + oam1) & ~oam1) > tlsindex + 4)
|
||||
tlsindex = 0;
|
||||
|
||||
const int oh_filealign = UPX_MIN(ih.filealign, 0x200);
|
||||
const int oh_filealign = UPX_MIN(ih.filealign, 0x200u);
|
||||
const unsigned fam1 = oh_filealign - 1;
|
||||
|
||||
int identsize = 0;
|
||||
@ -2456,9 +2456,9 @@ void PeFile::pack0(OutputFile *fo, ht &ih, ht &oh, unsigned subsystem_mask,
|
||||
((ph.c_len + ic) & 15) == 0 ? ph.c_len : ph.c_len + 16 - ((ph.c_len + ic) & 15);
|
||||
obuf.clear(ph.c_len, c_len - ph.c_len);
|
||||
|
||||
const unsigned aligned_sotls = ALIGN_UP(sotls, (unsigned) sizeof(LEXX));
|
||||
const unsigned aligned_sotls = ALIGN_UP(sotls, usizeof(LEXX));
|
||||
const unsigned s1size =
|
||||
ALIGN_UP(ic + c_len + codesize, (unsigned) sizeof(LEXX)) + aligned_sotls + soloadconf;
|
||||
ALIGN_UP(ic + c_len + codesize, usizeof(LEXX)) + aligned_sotls + soloadconf;
|
||||
const unsigned s1addr = (newvsize - (ic + c_len) + oam1) & ~oam1;
|
||||
|
||||
const unsigned ncsection = (s1addr + s1size + oam1) & ~oam1;
|
||||
|
||||
Loading…
Reference in New Issue
Block a user