all: cleanups
This commit is contained in:
+45
-1
@@ -64,7 +64,7 @@ TEST_CASE("raw_bytes bounded array") {
|
||||
**************************************************************************/
|
||||
|
||||
TEST_CASE("basic xspan usage") {
|
||||
char buf[4] = {0, 1, 2, 3};
|
||||
alignas(4) char buf[4] = {0, 1, 2, 3};
|
||||
|
||||
SUBCASE("XSPAN_x") {
|
||||
XSPAN_0(char) a0 = nullptr;
|
||||
@@ -114,6 +114,28 @@ TEST_CASE("basic xspan usage") {
|
||||
CHECK_THROWS(raw_bytes(cs, 5));
|
||||
CHECK_THROWS(raw_index_bytes(cs, 1, 4));
|
||||
#endif
|
||||
|
||||
XSPAN_0(upx_uint16_t) c0_2 = XSPAN_TYPE_CAST(upx_uint16_t, c0 + 2);
|
||||
XSPAN_P(upx_uint16_t) cp_2 = XSPAN_TYPE_CAST(upx_uint16_t, cp + 2);
|
||||
XSPAN_S(upx_uint16_t) cs_2 = XSPAN_TYPE_CAST(upx_uint16_t, cs + 2);
|
||||
CHECK(ptr_udiff_bytes(c0_2, c0) == 2u);
|
||||
CHECK(ptr_udiff_bytes(cp_2, c0) == 2u);
|
||||
CHECK(ptr_udiff_bytes(cs_2, c0) == 2u);
|
||||
CHECK(ptr_udiff_bytes(c0_2, cp) == 2u);
|
||||
CHECK(ptr_udiff_bytes(cp_2, cp) == 2u);
|
||||
CHECK(ptr_udiff_bytes(cs_2, cp) == 2u);
|
||||
CHECK(ptr_udiff_bytes(c0_2, cs) == 2u);
|
||||
CHECK(ptr_udiff_bytes(cp_2, cs) == 2u);
|
||||
CHECK(ptr_udiff_bytes(cs_2, cs) == 2u);
|
||||
XSPAN_0(upx_uint16_t) c0_2b = XSPAN_TYPE_CAST(upx_uint16_t, c0) + 1;
|
||||
XSPAN_P(upx_uint16_t) cp_2b = XSPAN_TYPE_CAST(upx_uint16_t, cp) + 1;
|
||||
XSPAN_S(upx_uint16_t) cs_2b = XSPAN_TYPE_CAST(upx_uint16_t, cs) + 1;
|
||||
CHECK(c0_2 == c0_2b);
|
||||
CHECK(cp_2 == cp_2b);
|
||||
CHECK(cs_2 == cs_2b);
|
||||
|
||||
CHECK(sizeof(*c0) == 1u);
|
||||
CHECK(sizeof(*c0_2) == 2u);
|
||||
}
|
||||
|
||||
SUBCASE("XSPAN_x_VAR") {
|
||||
@@ -171,6 +193,28 @@ TEST_CASE("basic xspan usage") {
|
||||
CHECK_THROWS(raw_bytes(cs, 5));
|
||||
CHECK_THROWS(raw_index_bytes(cs, 1, 4));
|
||||
#endif
|
||||
|
||||
XSPAN_0_VAR(upx_uint16_t, c0_2, XSPAN_TYPE_CAST(upx_uint16_t, c0 + 2));
|
||||
XSPAN_P_VAR(upx_uint16_t, cp_2, XSPAN_TYPE_CAST(upx_uint16_t, cp + 2));
|
||||
XSPAN_S_VAR(upx_uint16_t, cs_2, XSPAN_TYPE_CAST(upx_uint16_t, cs + 2));
|
||||
CHECK(ptr_udiff_bytes(c0_2, c0) == 2u);
|
||||
CHECK(ptr_udiff_bytes(cp_2, c0) == 2u);
|
||||
CHECK(ptr_udiff_bytes(cs_2, c0) == 2u);
|
||||
CHECK(ptr_udiff_bytes(c0_2, cp) == 2u);
|
||||
CHECK(ptr_udiff_bytes(cp_2, cp) == 2u);
|
||||
CHECK(ptr_udiff_bytes(cs_2, cp) == 2u);
|
||||
CHECK(ptr_udiff_bytes(c0_2, cs) == 2u);
|
||||
CHECK(ptr_udiff_bytes(cp_2, cs) == 2u);
|
||||
CHECK(ptr_udiff_bytes(cs_2, cs) == 2u);
|
||||
XSPAN_0_VAR(upx_uint16_t, c0_2b, XSPAN_TYPE_CAST(upx_uint16_t, c0) + 1);
|
||||
XSPAN_P_VAR(upx_uint16_t, cp_2b, XSPAN_TYPE_CAST(upx_uint16_t, cp) + 1);
|
||||
XSPAN_S_VAR(upx_uint16_t, cs_2b, XSPAN_TYPE_CAST(upx_uint16_t, cs) + 1);
|
||||
CHECK(c0_2 == c0_2b);
|
||||
CHECK(cp_2 == cp_2b);
|
||||
CHECK(cs_2 == cs_2b);
|
||||
|
||||
CHECK(sizeof(*c0) == 1u);
|
||||
CHECK(sizeof(*c0_2) == 2u);
|
||||
}
|
||||
|
||||
SUBCASE("xspan in class") {
|
||||
|
||||
+2
-1
@@ -107,7 +107,8 @@ inline constexpr bool upx_is_integral_v = upx_is_integral<T>::value;
|
||||
#if (ACC_ARCH_M68K && ACC_OS_TOS && ACC_CC_GNUC) && defined(__MINT__)
|
||||
// horrible hack for broken compiler / ABI
|
||||
#define upx_fake_alignas_1 __attribute__((__aligned__(1),__packed__))
|
||||
#define upx_fake_alignas_4 __attribute__((__aligned__(2)))
|
||||
#define upx_fake_alignas_2 __attribute__((__aligned__(2)))
|
||||
#define upx_fake_alignas_4 __attribute__((__aligned__(2))) // object file maximum 2 ???
|
||||
#define upx_fake_alignas_16 __attribute__((__aligned__(2))) // object file maximum 2 ???
|
||||
#define upx_fake_alignas__(x) upx_fake_alignas_ ## x
|
||||
#define alignas(x) upx_fake_alignas__(x)
|
||||
|
||||
+19
-14
@@ -335,8 +335,8 @@ PeFile::Reloc::Reloc(unsigned relocnum) {
|
||||
|
||||
void PeFile::Reloc::initSpans() {
|
||||
start_buf = SPAN_S_MAKE(byte, start, start_size_in_bytes);
|
||||
rel = SPAN_S_CAST(BaseReloc, start_buf);
|
||||
rel1 = SPAN_S_CAST(LE16, start_buf);
|
||||
rel = SPAN_TYPE_CAST(BaseReloc, start_buf);
|
||||
rel1 = SPAN_TYPE_CAST(LE16, start_buf);
|
||||
rel = nullptr;
|
||||
rel1 = nullptr;
|
||||
}
|
||||
@@ -366,7 +366,7 @@ bool PeFile::Reloc::next(unsigned &result_pos, unsigned &result_type) {
|
||||
pos = rel->pagestart + (*rel1 & 0xfff);
|
||||
type = *rel1++ >> 12;
|
||||
NO_printf("%x %d\n", pos, type);
|
||||
if (ptr_udiff_bytes(raw_bytes(rel1, 0), rel) >= rel->size_of_block)
|
||||
if (ptr_udiff_bytes(rel1, rel) >= rel->size_of_block)
|
||||
advanceBaseRelocPos(raw_bytes(rel1, 0));
|
||||
} while (type == 0);
|
||||
result_pos = pos;
|
||||
@@ -380,7 +380,7 @@ void PeFile::Reloc::add(unsigned pos, unsigned type) {
|
||||
counts[0] += 1;
|
||||
}
|
||||
|
||||
void PeFile::Reloc::finish(byte *&result_ptr, unsigned &result_size) {
|
||||
void PeFile::Reloc::finish(byte *(&result_ptr), unsigned &result_size) {
|
||||
assert(start_did_alloc);
|
||||
// sentinel to force final advanceBaseRelocPos()
|
||||
set_le32(start_buf + (RELOC_BUF_OFFSET + 4 * counts[0]), 0xfff00000);
|
||||
@@ -392,32 +392,37 @@ void PeFile::Reloc::finish(byte *&result_ptr, unsigned &result_size) {
|
||||
rel1 = nullptr;
|
||||
unsigned prev = 0xffffffff;
|
||||
for (unsigned ic = 0; ic < counts[0]; ic++) {
|
||||
unsigned pos = get_le32(start_buf + (RELOC_BUF_OFFSET + 4 * ic));
|
||||
const unsigned pos = get_le32(start_buf + (RELOC_BUF_OFFSET + 4 * ic));
|
||||
if (rel == (BaseReloc *) (void *) start)
|
||||
if (ptr_udiff_bytes(rel1, rel) > RELOC_BUF_OFFSET - sizeof(*rel1))
|
||||
throwCantPack("too many relocs");
|
||||
if (ic == 0) {
|
||||
prev = pos;
|
||||
advanceBaseRelocPos(start);
|
||||
rel->pagestart = (pos >> 4) & ~0xfff;
|
||||
rel->size_of_block = 0; // to be filled later
|
||||
rel->size_of_block = unsigned(-1); // to be filled later
|
||||
} else if ((pos ^ prev) >= 0x10000) {
|
||||
prev = pos;
|
||||
*rel1 = 0; // clear align-up memory
|
||||
rel->size_of_block = ALIGN_UP(ptr_udiff_bytes(raw_bytes(rel1, 0), rel), 4u);
|
||||
*rel1 = 0; // clear align-up memory
|
||||
rel->size_of_block = ALIGN_UP(ptr_udiff_bytes(rel1, rel), 4u); // <= FILL
|
||||
advanceBaseRelocPos((char *) raw_bytes(rel, rel->size_of_block) + rel->size_of_block);
|
||||
rel->pagestart = (pos >> 4) & ~0xfff;
|
||||
rel->size_of_block = 0;
|
||||
rel->size_of_block = unsigned(-1); // to be filled later
|
||||
}
|
||||
*rel1++ = (pos << 12) + ((pos >> 4) & 0xfff);
|
||||
}
|
||||
assert(ptr_udiff_bytes(raw_bytes(rel1, 0), rel) == 10); // sentinel
|
||||
assert(ptr_udiff_bytes(rel1, rel) == 10); // sentinel
|
||||
result_size = ptr_udiff_bytes(rel, start);
|
||||
assert((result_size & 3) == 0);
|
||||
// assert(result_size > 0); // result_size can be 0 in 64-bit mode
|
||||
// transfer ownership
|
||||
assert(start_did_alloc);
|
||||
result_ptr = start;
|
||||
start = nullptr; // safety
|
||||
start_buf = nullptr; // safety
|
||||
start = nullptr;
|
||||
start_did_alloc = false;
|
||||
SPAN_INVALIDATE(start_buf); // safety
|
||||
SPAN_INVALIDATE(rel); // safety
|
||||
SPAN_INVALIDATE(rel1); // safety
|
||||
}
|
||||
|
||||
void PeFile::processRelocs(Reloc *rel) // pass2
|
||||
@@ -2673,7 +2678,7 @@ void PeFile::rebuildRelocs(SPAN_S(byte) & extra_info, unsigned bits, unsigned fl
|
||||
unsigned relocnum = unoptimizeReloc(rdata, mb_wrkmem, obuf, orig_crelocs, bits, true);
|
||||
unsigned r16 = 0;
|
||||
if (big & 6) { // count 16 bit relocations
|
||||
SPAN_S_VAR(const LE32, q, SPAN_S_CAST(const LE32, rdata));
|
||||
SPAN_S_VAR(const LE32, q, SPAN_TYPE_CAST(const LE32, rdata));
|
||||
while (*q++)
|
||||
r16++;
|
||||
if ((big & 6) == 6)
|
||||
@@ -2682,7 +2687,7 @@ void PeFile::rebuildRelocs(SPAN_S(byte) & extra_info, unsigned bits, unsigned fl
|
||||
}
|
||||
Reloc rel(relocnum + r16);
|
||||
if (big & 6) { // add 16 bit relocations
|
||||
SPAN_S_VAR(const LE32, q, SPAN_S_CAST(const LE32, rdata));
|
||||
SPAN_S_VAR(const LE32, q, SPAN_TYPE_CAST(const LE32, rdata));
|
||||
while (*q)
|
||||
rel.add(*q++ + rvamin, (big & 4) ? 2 : 1);
|
||||
if ((big & 6) == 6)
|
||||
|
||||
+1
-1
@@ -410,7 +410,7 @@ protected:
|
||||
const unsigned *getcounts() const { return counts; }
|
||||
//
|
||||
void add(unsigned pos, unsigned type);
|
||||
void finish(byte *&result_ptr, unsigned &result_size); // => transfer ownership
|
||||
void finish(byte *(&result_ptr), unsigned &result_size); // => transfer ownership
|
||||
};
|
||||
|
||||
class Resource : private noncopyable {
|
||||
|
||||
@@ -125,6 +125,16 @@ forceinline void ptr_check_no_overlap(const void *a, size_t a_size, const void *
|
||||
(upx_uintptr_t) c, c_size);
|
||||
}
|
||||
|
||||
// invalidate and poison a pointer: point to a non-null invalid address
|
||||
// - resulting pointer should crash on dereference
|
||||
// - this should be efficient, so no mmap() guard page etc.
|
||||
// - this should play nice with runtime checkers like ASAN, MSAN, valgrind, etc.
|
||||
// - this should play nice with static analyzers like clang-tidy etc.
|
||||
template <class T>
|
||||
inline void ptr_invalidate_and_poison(T *(&ptr)) noexcept {
|
||||
ptr = (T *) (void *) 251; // 0x000000fb // NOLINT(performance-no-int-to-ptr)
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
// stdlib
|
||||
**************************************************************************/
|
||||
|
||||
+21
-21
@@ -96,9 +96,9 @@ using XSPAN_NAMESPACE_NAME::raw_index_bytes; // overloaded for all classes
|
||||
#define XSPAN_S_VAR(type, var, first, ...) XSPAN_S(type) var((first), ##__VA_ARGS__)
|
||||
|
||||
// cast to a different type (creates a new value)
|
||||
#define XSPAN_0_CAST(type, var) ((var).type_cast<type>())
|
||||
#define XSPAN_P_CAST(type, var) ((var).type_cast<type>())
|
||||
#define XSPAN_S_CAST(type, var) ((var).type_cast<type>())
|
||||
#define XSPAN_TYPE_CAST(type, x) ((x).type_cast<type>())
|
||||
// poison a pointer: point to a non-null invalid address
|
||||
#define XSPAN_INVALIDATE(x) ((x).invalidate())
|
||||
|
||||
#elif WITH_XSPAN >= 1
|
||||
|
||||
@@ -120,9 +120,9 @@ using XSPAN_NAMESPACE_NAME::raw_index_bytes; // overloaded for all classes
|
||||
#define XSPAN_S_VAR(type, var, first, ...) XSPAN_S(type) var((first))
|
||||
|
||||
// cast to a different type (creates a new value)
|
||||
#define XSPAN_0_CAST(type, var) ((var).type_cast<type>())
|
||||
#define XSPAN_P_CAST(type, var) ((var).type_cast<type>())
|
||||
#define XSPAN_S_CAST(type, var) ((var).type_cast<type>())
|
||||
#define XSPAN_TYPE_CAST(type, x) ((x).type_cast<type>())
|
||||
// poison a pointer: point to a non-null invalid address
|
||||
#define XSPAN_INVALIDATE(x) ((x).invalidate())
|
||||
|
||||
#else // WITH_XSPAN
|
||||
|
||||
@@ -158,9 +158,9 @@ inline R *xspan_make_helper__(R * /*dummy*/, MemBuffer &mb) noexcept {
|
||||
#define XSPAN_S_VAR(type, var, first, ...) type *var = XSPAN_S_MAKE(type, (first))
|
||||
|
||||
// cast to a different type (creates a new value)
|
||||
#define XSPAN_0_CAST(type, var) ((type *) (var))
|
||||
#define XSPAN_P_CAST(type, var) ((type *) (var))
|
||||
#define XSPAN_S_CAST(type, var) ((type *) (var))
|
||||
#define XSPAN_TYPE_CAST(type, x) (reinterpret_cast<type *>(x))
|
||||
// poison a pointer: point to a non-null invalid address
|
||||
#define XSPAN_INVALIDATE(x) ptr_invalidate_and_poison(x)
|
||||
|
||||
#endif // WITH_XSPAN
|
||||
|
||||
@@ -170,21 +170,21 @@ inline R *xspan_make_helper__(R * /*dummy*/, MemBuffer &mb) noexcept {
|
||||
|
||||
#if 1
|
||||
// types
|
||||
#define SPAN_0 XSPAN_0
|
||||
#define SPAN_P XSPAN_P
|
||||
#define SPAN_S XSPAN_S
|
||||
#define SPAN_0 XSPAN_0
|
||||
#define SPAN_P XSPAN_P
|
||||
#define SPAN_S XSPAN_S
|
||||
// create a value
|
||||
#define SPAN_0_MAKE XSPAN_0_MAKE
|
||||
#define SPAN_P_MAKE XSPAN_P_MAKE
|
||||
#define SPAN_S_MAKE XSPAN_S_MAKE
|
||||
#define SPAN_0_MAKE XSPAN_0_MAKE
|
||||
#define SPAN_P_MAKE XSPAN_P_MAKE
|
||||
#define SPAN_S_MAKE XSPAN_S_MAKE
|
||||
// define a variable
|
||||
#define SPAN_0_VAR XSPAN_0_VAR
|
||||
#define SPAN_P_VAR XSPAN_P_VAR
|
||||
#define SPAN_S_VAR XSPAN_S_VAR
|
||||
#define SPAN_0_VAR XSPAN_0_VAR
|
||||
#define SPAN_P_VAR XSPAN_P_VAR
|
||||
#define SPAN_S_VAR XSPAN_S_VAR
|
||||
// cast to a different type (creates a new value)
|
||||
#define SPAN_0_CAST XSPAN_0_CAST
|
||||
#define SPAN_P_CAST XSPAN_P_CAST
|
||||
#define SPAN_S_CAST XSPAN_S_CAST
|
||||
#define SPAN_TYPE_CAST XSPAN_TYPE_CAST
|
||||
// poison a pointer: point to a non-null invalid address
|
||||
#define SPAN_INVALIDATE XSPAN_INVALIDATE
|
||||
#endif
|
||||
|
||||
/* vim:set ts=4 sw=4 et: */
|
||||
|
||||
+66
-18
@@ -34,15 +34,62 @@
|
||||
// #define XSPAN_REQUIRES_CONVERTIBLE_ANY_DIRECTION(A, B, RType)
|
||||
// std::enable_if_t<std::is_convertible_v<A *, B *> || std::is_convertible_v<B *, A *>, RType>
|
||||
|
||||
#define XSPAN_FWD_TU(RType) \
|
||||
// requires convertible T to U, or U to T
|
||||
#define XSPAN_FWD_TU_CONVERTIBLE(RType) \
|
||||
template <class T, class U> \
|
||||
inline XSPAN_REQUIRES_CONVERTIBLE_ANY_DIRECTION(T, U, RType)
|
||||
// any pointer type, matching automatic conversion to "void *"
|
||||
#define XSPAN_FWD_TU_VOIDPTR(RType) \
|
||||
template <class T, class U> \
|
||||
inline RType
|
||||
|
||||
/*************************************************************************
|
||||
// overloads of global operators
|
||||
**************************************************************************/
|
||||
|
||||
#ifndef XSPAN_FWD_C_IS_MEMBUFFER
|
||||
|
||||
// global operator: disallow "n + C" => force using "C + n" (member function) instead
|
||||
template <class T, class U>
|
||||
inline typename std::enable_if<std::is_integral<U>::value, void *>::type operator+(U, const C<T> &)
|
||||
XSPAN_DELETED_FUNCTION;
|
||||
|
||||
#if 0 // handled by member functions
|
||||
XSPAN_FWD_TU_CONVERTIBLE(bool) operator==(const C<T> &a, const U *b) {
|
||||
return a.raw_bytes(0) == b;
|
||||
}
|
||||
XSPAN_FWD_TU_CONVERTIBLE(bool) operator==(const C<T> &a, const C<U> &b) {
|
||||
return a.raw_bytes(0) == b.raw_bytes(0);
|
||||
}
|
||||
#ifdef D
|
||||
XSPAN_FWD_TU_CONVERTIBLE(bool) operator==(const C<T> &a, const D<U> &b) {
|
||||
return a.raw_bytes(0) == b.raw_bytes(0);
|
||||
}
|
||||
#endif
|
||||
#ifdef E
|
||||
XSPAN_FWD_TU_CONVERTIBLE(bool) operator==(const C<T> &a, const E<U> &b) {
|
||||
return a.raw_bytes(0) == b.raw_bytes(0);
|
||||
}
|
||||
#endif
|
||||
|
||||
XSPAN_FWD_TU_CONVERTIBLE(bool) operator!=(const C<T> &a, const U *b) {
|
||||
return a.raw_bytes(0) != b;
|
||||
}
|
||||
XSPAN_FWD_TU_CONVERTIBLE(bool) operator!=(const C<T> &a, const C<U> &b) {
|
||||
return a.raw_bytes(0) != b.raw_bytes(0);
|
||||
}
|
||||
#ifdef D
|
||||
XSPAN_FWD_TU_CONVERTIBLE(bool) operator!=(const C<T> &a, const D<U> &b) {
|
||||
return a.raw_bytes(0) != b.raw_bytes(0);
|
||||
}
|
||||
#endif
|
||||
#ifdef E
|
||||
XSPAN_FWD_TU_CONVERTIBLE(bool) operator!=(const C<T> &a, const E<U> &b) {
|
||||
return a.raw_bytes(0) != b.raw_bytes(0);
|
||||
}
|
||||
#endif
|
||||
#endif // if 0 // handled by member functions
|
||||
|
||||
#endif // XSPAN_FWD_C_IS_MEMBUFFER
|
||||
|
||||
/*************************************************************************
|
||||
@@ -66,16 +113,16 @@ template <class T>
|
||||
inline int memcmp(const void *a, const C<T> &b, size_t n) {
|
||||
return memcmp(a, b.raw_bytes(n), n);
|
||||
}
|
||||
XSPAN_FWD_TU(int) memcmp(const C<T> &a, const C<U> &b, size_t n) {
|
||||
XSPAN_FWD_TU_VOIDPTR(int) memcmp(const C<T> &a, const C<U> &b, size_t n) {
|
||||
return memcmp(a.raw_bytes(n), b.raw_bytes(n), n);
|
||||
}
|
||||
#ifdef D
|
||||
XSPAN_FWD_TU(int) memcmp(const C<T> &a, const D<U> &b, size_t n) {
|
||||
XSPAN_FWD_TU_VOIDPTR(int) memcmp(const C<T> &a, const D<U> &b, size_t n) {
|
||||
return memcmp(a.raw_bytes(n), b.raw_bytes(n), n);
|
||||
}
|
||||
#endif
|
||||
#ifdef E
|
||||
XSPAN_FWD_TU(int) memcmp(const C<T> &a, const E<U> &b, size_t n) {
|
||||
XSPAN_FWD_TU_VOIDPTR(int) memcmp(const C<T> &a, const E<U> &b, size_t n) {
|
||||
return memcmp(a.raw_bytes(n), b.raw_bytes(n), n);
|
||||
}
|
||||
#endif
|
||||
@@ -88,16 +135,16 @@ template <class T>
|
||||
inline void *memcpy(void *a, const C<T> &b, size_t n) {
|
||||
return memcpy(a, b.raw_bytes(n), n);
|
||||
}
|
||||
XSPAN_FWD_TU(void *) memcpy(const C<T> &a, const C<U> &b, size_t n) {
|
||||
XSPAN_FWD_TU_VOIDPTR(void *) memcpy(const C<T> &a, const C<U> &b, size_t n) {
|
||||
return memcpy(a.raw_bytes(n), b.raw_bytes(n), n);
|
||||
}
|
||||
#ifdef D
|
||||
XSPAN_FWD_TU(void *) memcpy(const C<T> &a, const D<U> &b, size_t n) {
|
||||
XSPAN_FWD_TU_VOIDPTR(void *) memcpy(const C<T> &a, const D<U> &b, size_t n) {
|
||||
return memcpy(a.raw_bytes(n), b.raw_bytes(n), n);
|
||||
}
|
||||
#endif
|
||||
#ifdef E
|
||||
XSPAN_FWD_TU(void *) memcpy(const C<T> &a, const E<U> &b, size_t n) {
|
||||
XSPAN_FWD_TU_VOIDPTR(void *) memcpy(const C<T> &a, const E<U> &b, size_t n) {
|
||||
return memcpy(a.raw_bytes(n), b.raw_bytes(n), n);
|
||||
}
|
||||
#endif
|
||||
@@ -110,16 +157,16 @@ template <class T>
|
||||
inline void *memmove(void *a, const C<T> &b, size_t n) {
|
||||
return memmove(a, b.raw_bytes(n), n);
|
||||
}
|
||||
XSPAN_FWD_TU(void *) memmove(const C<T> &a, const C<U> &b, size_t n) {
|
||||
XSPAN_FWD_TU_VOIDPTR(void *) memmove(const C<T> &a, const C<U> &b, size_t n) {
|
||||
return memmove(a.raw_bytes(n), b.raw_bytes(n), n);
|
||||
}
|
||||
#ifdef D
|
||||
XSPAN_FWD_TU(void *) memmove(const C<T> &a, const D<U> &b, size_t n) {
|
||||
XSPAN_FWD_TU_VOIDPTR(void *) memmove(const C<T> &a, const D<U> &b, size_t n) {
|
||||
return memmove(a.raw_bytes(n), b.raw_bytes(n), n);
|
||||
}
|
||||
#endif
|
||||
#ifdef E
|
||||
XSPAN_FWD_TU(void *) memmove(const C<T> &a, const E<U> &b, size_t n) {
|
||||
XSPAN_FWD_TU_VOIDPTR(void *) memmove(const C<T> &a, const E<U> &b, size_t n) {
|
||||
return memmove(a.raw_bytes(n), b.raw_bytes(n), n);
|
||||
}
|
||||
#endif
|
||||
@@ -141,16 +188,16 @@ template <class T>
|
||||
inline int ptr_diff_bytes(const void *a, const C<T> &b) {
|
||||
return ptr_diff_bytes(a, b.raw_bytes(0));
|
||||
}
|
||||
XSPAN_FWD_TU(int) ptr_diff_bytes(const C<T> &a, const C<U> &b) {
|
||||
XSPAN_FWD_TU_VOIDPTR(int) ptr_diff_bytes(const C<T> &a, const C<U> &b) {
|
||||
return ptr_diff_bytes(a.raw_bytes(0), b.raw_bytes(0));
|
||||
}
|
||||
#ifdef D
|
||||
XSPAN_FWD_TU(int) ptr_diff_bytes(const C<T> &a, const D<U> &b) {
|
||||
XSPAN_FWD_TU_VOIDPTR(int) ptr_diff_bytes(const C<T> &a, const D<U> &b) {
|
||||
return ptr_diff_bytes(a.raw_bytes(0), b.raw_bytes(0));
|
||||
}
|
||||
#endif
|
||||
#ifdef E
|
||||
XSPAN_FWD_TU(int) ptr_diff_bytes(const C<T> &a, const E<U> &b) {
|
||||
XSPAN_FWD_TU_VOIDPTR(int) ptr_diff_bytes(const C<T> &a, const E<U> &b) {
|
||||
return ptr_diff_bytes(a.raw_bytes(0), b.raw_bytes(0));
|
||||
}
|
||||
#endif
|
||||
@@ -163,16 +210,16 @@ template <class T>
|
||||
inline unsigned ptr_udiff_bytes(const void *a, const C<T> &b) {
|
||||
return ptr_udiff_bytes(a, b.raw_bytes(0));
|
||||
}
|
||||
XSPAN_FWD_TU(unsigned) ptr_udiff_bytes(const C<T> &a, const C<U> &b) {
|
||||
XSPAN_FWD_TU_VOIDPTR(unsigned) ptr_udiff_bytes(const C<T> &a, const C<U> &b) {
|
||||
return ptr_udiff_bytes(a.raw_bytes(0), b.raw_bytes(0));
|
||||
}
|
||||
#ifdef D
|
||||
XSPAN_FWD_TU(unsigned) ptr_udiff_bytes(const C<T> &a, const D<U> &b) {
|
||||
XSPAN_FWD_TU_VOIDPTR(unsigned) ptr_udiff_bytes(const C<T> &a, const D<U> &b) {
|
||||
return ptr_udiff_bytes(a.raw_bytes(0), b.raw_bytes(0));
|
||||
}
|
||||
#endif
|
||||
#ifdef E
|
||||
XSPAN_FWD_TU(unsigned) ptr_udiff_bytes(const C<T> &a, const E<U> &b) {
|
||||
XSPAN_FWD_TU_VOIDPTR(unsigned) ptr_udiff_bytes(const C<T> &a, const E<U> &b) {
|
||||
return ptr_udiff_bytes(a.raw_bytes(0), b.raw_bytes(0));
|
||||
}
|
||||
#endif
|
||||
@@ -180,7 +227,7 @@ XSPAN_FWD_TU(unsigned) ptr_udiff_bytes(const C<T> &a, const E<U> &b) {
|
||||
#ifdef UPX_VERSION_HEX
|
||||
|
||||
template <class T>
|
||||
inline unsigned upx_adler32(const C<T> &a, unsigned n, unsigned adler = 1) {
|
||||
unsigned upx_adler32(const C<T> &a, unsigned n, unsigned adler = 1) {
|
||||
return upx_adler32(a.raw_bytes(n), n, adler);
|
||||
}
|
||||
|
||||
@@ -316,6 +363,7 @@ typename std::enable_if<sizeof(T) == 1, upx_rsize_t>::type upx_safe_strlen(const
|
||||
|
||||
#endif // UPX_VERSION_HEX
|
||||
|
||||
#undef XSPAN_FWD_TU
|
||||
#undef XSPAN_FWD_TU_CONVERTIBLE
|
||||
#undef XSPAN_FWD_TU_VOIDPTR
|
||||
|
||||
/* vim:set ts=4 sw=4 et: */
|
||||
|
||||
+1
-11
@@ -200,7 +200,7 @@ class XSpanInternalDummyArgFake; // not implemented on purpose
|
||||
typedef XSpanInternalDummyArgFake *XSpanInternalDummyArg;
|
||||
#define XSpanInternalDummyArgInit nullptr
|
||||
#elif __cplusplus >= 201103L && 1
|
||||
// use an enum
|
||||
// use an enum and a move constructor
|
||||
struct XSpanInternalDummyArg final {
|
||||
enum DummyEnum {};
|
||||
explicit forceinline_constexpr XSpanInternalDummyArg(DummyEnum &&) noexcept {}
|
||||
@@ -220,16 +220,6 @@ private:
|
||||
(XSPAN_NS(XSpanInternalDummyArg)(XSPAN_NS(XSpanInternalDummyArg)::make()))
|
||||
#endif
|
||||
|
||||
// poison a pointer: point to a non-null invalid address
|
||||
// - resulting pointer should crash on dereference
|
||||
// - this should be efficient (so no mmap() guard page etc.)
|
||||
// - this should play nice with runtime checkers like ASAN, MSAN, valgrind, etc.
|
||||
// - this should play nice with static analyzers like clang-tidy etc.
|
||||
static forceinline void *XSPAN_GET_POISON_VOID_PTR() noexcept {
|
||||
// return (void *) (upx_uintptr_t) 251; // NOLINT(performance-no-int-to-ptr)
|
||||
return (void *) 251;
|
||||
}
|
||||
|
||||
XSPAN_NAMESPACE_END
|
||||
|
||||
#ifndef XSPAN_DELETED_FUNCTION
|
||||
|
||||
@@ -114,10 +114,8 @@ forceinline ~CSelf() noexcept {}
|
||||
#endif
|
||||
noinline void invalidate() {
|
||||
assertInvariants();
|
||||
// poison the pointer: point to non-null invalid address
|
||||
ptr = (pointer) XSPAN_GET_POISON_VOID_PTR();
|
||||
// ptr = (pointer) (void *) &ptr; // point to self
|
||||
base = ptr;
|
||||
ptr_invalidate_and_poison(ptr); // point to non-null invalid address
|
||||
base = ptr; // point to non-null invalid address
|
||||
size_in_bytes = 0;
|
||||
assertInvariants();
|
||||
}
|
||||
@@ -283,11 +281,11 @@ public:
|
||||
}
|
||||
|
||||
template <class U>
|
||||
CSelf<U> type_cast() const {
|
||||
assertInvariants();
|
||||
inline CSelf<U> type_cast() const {
|
||||
typedef CSelf<U> R;
|
||||
return R(R::Unchecked, reinterpret_cast<typename R::pointer>(ptr), size_in_bytes,
|
||||
reinterpret_cast<typename R::pointer>(base));
|
||||
typedef typename R::pointer rpointer;
|
||||
return R(R::Unchecked, reinterpret_cast<rpointer>(ptr), size_in_bytes,
|
||||
reinterpret_cast<rpointer>(base));
|
||||
}
|
||||
|
||||
bool operator==(pointer other) const { return ptr == other; }
|
||||
|
||||
@@ -77,9 +77,7 @@ public:
|
||||
#endif
|
||||
noinline void invalidate() {
|
||||
assertInvariants();
|
||||
// poison the pointer: point to non-null invalid address
|
||||
ptr = (pointer) XSPAN_GET_POISON_VOID_PTR();
|
||||
// ptr = (pointer) (void *) &ptr; // point to self
|
||||
ptr_invalidate_and_poison(ptr); // point to non-null invalid address
|
||||
assertInvariants();
|
||||
}
|
||||
inline CSelf() { assertInvariants(); }
|
||||
@@ -126,10 +124,10 @@ public:
|
||||
}
|
||||
|
||||
template <class U>
|
||||
CSelf<U> type_cast() const {
|
||||
assertInvariants();
|
||||
inline CSelf<U> type_cast() const {
|
||||
typedef CSelf<U> R;
|
||||
return R(reinterpret_cast<typename R::pointer>(ptr));
|
||||
typedef typename R::pointer rpointer;
|
||||
return R(reinterpret_cast<rpointer>(ptr));
|
||||
}
|
||||
|
||||
// comparison
|
||||
|
||||
Reference in New Issue
Block a user