all: cleanups

This commit is contained in:
Markus F.X.J. Oberhumer
2023-10-21 11:22:18 +02:00
parent 91c15b2475
commit 9fbe95ad48
16 changed files with 220 additions and 119 deletions
+10
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
+6 -8
View File
@@ -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; }
+4 -6
View File
@@ -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