src: introduce ptr_get_address()
This commit is contained in:
@@ -498,8 +498,16 @@ void upx_compiler_sanity_check(void) noexcept {
|
|||||||
CheckIntegral<ptrdiff_t>::check();
|
CheckIntegral<ptrdiff_t>::check();
|
||||||
CheckIntegral<size_t>::check();
|
CheckIntegral<size_t>::check();
|
||||||
CheckIntegral<upx_off_t>::check();
|
CheckIntegral<upx_off_t>::check();
|
||||||
|
CheckIntegral<upx_ptraddr_t>::check();
|
||||||
CheckIntegral<upx_uintptr_t>::check();
|
CheckIntegral<upx_uintptr_t>::check();
|
||||||
|
|
||||||
|
COMPILE_TIME_ASSERT(ptrdiff_t(0) - 1 < 0);
|
||||||
|
COMPILE_TIME_ASSERT(intptr_t(0) - 1 < 0);
|
||||||
|
COMPILE_TIME_ASSERT(size_t(0) - 1 > 0);
|
||||||
|
COMPILE_TIME_ASSERT(uintptr_t(0) - 1 > 0);
|
||||||
|
COMPILE_TIME_ASSERT(upx_ptraddr_t(0) - 1 > 0);
|
||||||
|
COMPILE_TIME_ASSERT(upx_uintptr_t(0) - 1 > 0);
|
||||||
|
|
||||||
COMPILE_TIME_ASSERT(sizeof(upx_charptr_unit_type) == 1)
|
COMPILE_TIME_ASSERT(sizeof(upx_charptr_unit_type) == 1)
|
||||||
COMPILE_TIME_ASSERT_ALIGNED1(upx_charptr_unit_type)
|
COMPILE_TIME_ASSERT_ALIGNED1(upx_charptr_unit_type)
|
||||||
COMPILE_TIME_ASSERT(sizeof(*((charptr) nullptr)) == 1)
|
COMPILE_TIME_ASSERT(sizeof(*((charptr) nullptr)) == 1)
|
||||||
|
|||||||
@@ -54,6 +54,7 @@ ACC_COMPILE_TIME_ASSERT_HEADER((!upx::is_same_any_v<int, char, long>) )
|
|||||||
ACC_COMPILE_TIME_ASSERT_HEADER((upx::is_same_any_v<ptrdiff_t, int, long, long long>) )
|
ACC_COMPILE_TIME_ASSERT_HEADER((upx::is_same_any_v<ptrdiff_t, int, long, long long>) )
|
||||||
ACC_COMPILE_TIME_ASSERT_HEADER(
|
ACC_COMPILE_TIME_ASSERT_HEADER(
|
||||||
(upx::is_same_any_v<size_t, unsigned, unsigned long, unsigned long long>) )
|
(upx::is_same_any_v<size_t, unsigned, unsigned long, unsigned long long>) )
|
||||||
|
// TODO later: CHERI
|
||||||
ACC_COMPILE_TIME_ASSERT_HEADER(
|
ACC_COMPILE_TIME_ASSERT_HEADER(
|
||||||
(upx::is_same_any_v<upx_uintptr_t, unsigned, unsigned long, unsigned long long>) )
|
(upx::is_same_any_v<upx_uintptr_t, unsigned, unsigned long, unsigned long long>) )
|
||||||
|
|
||||||
|
|||||||
@@ -30,11 +30,9 @@
|
|||||||
|
|
||||||
#if (ACC_CC_CLANG)
|
#if (ACC_CC_CLANG)
|
||||||
#pragma clang diagnostic ignored "-Wshadow"
|
#pragma clang diagnostic ignored "-Wshadow"
|
||||||
#endif
|
#elif (ACC_CC_GNUC >= 0x040200)
|
||||||
#if (ACC_CC_GNUC >= 0x040200)
|
|
||||||
#pragma GCC diagnostic ignored "-Wshadow"
|
#pragma GCC diagnostic ignored "-Wshadow"
|
||||||
#endif
|
#elif (ACC_CC_MSC)
|
||||||
#if (ACC_CC_MSC)
|
|
||||||
#pragma warning(disable : 4456) // -Wno-shadow
|
#pragma warning(disable : 4456) // -Wno-shadow
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
@@ -144,6 +144,8 @@ typedef acc_uint32_t upx_uint32_t;
|
|||||||
typedef acc_int64_t upx_int64_t;
|
typedef acc_int64_t upx_int64_t;
|
||||||
typedef acc_uint64_t upx_uint64_t;
|
typedef acc_uint64_t upx_uint64_t;
|
||||||
typedef acc_uintptr_t upx_uintptr_t;
|
typedef acc_uintptr_t upx_uintptr_t;
|
||||||
|
// see CHERI ptraddr_t / vaddr_t
|
||||||
|
typedef upx_uintptr_t upx_ptraddr_t;
|
||||||
|
|
||||||
// UPX convention: use "byte" when dealing with data; use "char/uchar" when dealing
|
// UPX convention: use "byte" when dealing with data; use "char/uchar" when dealing
|
||||||
// with strings; use "upx_uint8_t" when dealing with small integers
|
// with strings; use "upx_uint8_t" when dealing with small integers
|
||||||
|
|||||||
@@ -73,7 +73,7 @@ static forceinline constexpr bool use_simple_mcheck() noexcept { return true; }
|
|||||||
//
|
//
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
MemBuffer::MemBuffer(upx_uint64_t bytes) : MemBufferBase<byte>() {
|
MemBuffer::MemBuffer(upx_uint64_t bytes) may_throw : MemBufferBase<byte>() {
|
||||||
static_assert(element_size == 1);
|
static_assert(element_size == 1);
|
||||||
alloc(bytes);
|
alloc(bytes);
|
||||||
debug_set(debug.last_return_address_alloc, upx_return_address());
|
debug_set(debug.last_return_address_alloc, upx_return_address());
|
||||||
@@ -148,11 +148,11 @@ void MemBuffer::fill(unsigned off, unsigned len, int value) {
|
|||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
// for use_simple_mcheck()
|
// for use_simple_mcheck()
|
||||||
#define PTR_BITS32(p) ((unsigned) ((upx_uintptr_t) (p) &0xffffffff))
|
#define PTR_BITS32(p) ((unsigned) (ptr_get_address(p) & 0xffffffff))
|
||||||
#define MAGIC1(p) ((PTR_BITS32(p) ^ 0xfefdbeeb) | 1)
|
#define MAGIC1(p) ((PTR_BITS32(p) ^ 0xfefdbeeb) | 1)
|
||||||
#define MAGIC2(p) ((PTR_BITS32(p) ^ 0xfefdbeeb ^ 0x88224411) | 1)
|
#define MAGIC2(p) ((PTR_BITS32(p) ^ 0xfefdbeeb ^ 0x88224411) | 1)
|
||||||
|
|
||||||
void MemBuffer::checkState() const {
|
void MemBuffer::checkState() const may_throw {
|
||||||
if (!ptr)
|
if (!ptr)
|
||||||
throwInternalError("block not allocated");
|
throwInternalError("block not allocated");
|
||||||
assert(size_in_bytes > 0);
|
assert(size_in_bytes > 0);
|
||||||
@@ -167,7 +167,7 @@ void MemBuffer::checkState() const {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MemBuffer::alloc(upx_uint64_t bytes) {
|
void MemBuffer::alloc(upx_uint64_t bytes) may_throw {
|
||||||
// INFO: we don't automatically free a used buffer
|
// INFO: we don't automatically free a used buffer
|
||||||
assert(ptr == nullptr);
|
assert(ptr == nullptr);
|
||||||
assert(size_in_bytes == 0);
|
assert(size_in_bytes == 0);
|
||||||
|
|||||||
+8
-8
@@ -144,11 +144,11 @@ TEST_CASE("ptr_diff") {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// check that 2 buffers do not overlap; will throw on error
|
// check that 2 buffers do not overlap; will throw on error
|
||||||
void uintptr_check_no_overlap(upx_uintptr_t a, size_t a_size, upx_uintptr_t b, size_t b_size) {
|
void ptraddr_check_no_overlap(upx_ptraddr_t a, size_t a_size, upx_ptraddr_t b, size_t b_size) {
|
||||||
if very_unlikely (a == 0 || b == 0)
|
if very_unlikely (a == 0 || b == 0)
|
||||||
throwCantPack("ptr_check_no_overlap-nullptr");
|
throwCantPack("ptr_check_no_overlap-nullptr");
|
||||||
upx_uintptr_t a_end = a + mem_size(1, a_size);
|
upx_ptraddr_t a_end = a + mem_size(1, a_size);
|
||||||
upx_uintptr_t b_end = b + mem_size(1, b_size);
|
upx_ptraddr_t b_end = b + mem_size(1, b_size);
|
||||||
if very_unlikely (a_end < a || b_end < b) // wrap-around
|
if very_unlikely (a_end < a || b_end < b) // wrap-around
|
||||||
throwCantPack("ptr_check_no_overlap-overflow");
|
throwCantPack("ptr_check_no_overlap-overflow");
|
||||||
// simple, but a little bit mind bending:
|
// simple, but a little bit mind bending:
|
||||||
@@ -159,13 +159,13 @@ void uintptr_check_no_overlap(upx_uintptr_t a, size_t a_size, upx_uintptr_t b, s
|
|||||||
}
|
}
|
||||||
|
|
||||||
// check that 3 buffers do not overlap; will throw on error
|
// check that 3 buffers do not overlap; will throw on error
|
||||||
void uintptr_check_no_overlap(upx_uintptr_t a, size_t a_size, upx_uintptr_t b, size_t b_size,
|
void ptraddr_check_no_overlap(upx_ptraddr_t a, size_t a_size, upx_ptraddr_t b, size_t b_size,
|
||||||
upx_uintptr_t c, size_t c_size) {
|
upx_ptraddr_t c, size_t c_size) {
|
||||||
if very_unlikely (a == 0 || b == 0 || c == 0)
|
if very_unlikely (a == 0 || b == 0 || c == 0)
|
||||||
throwCantPack("ptr_check_no_overlap-nullptr");
|
throwCantPack("ptr_check_no_overlap-nullptr");
|
||||||
upx_uintptr_t a_end = a + mem_size(1, a_size);
|
upx_ptraddr_t a_end = a + mem_size(1, a_size);
|
||||||
upx_uintptr_t b_end = b + mem_size(1, b_size);
|
upx_ptraddr_t b_end = b + mem_size(1, b_size);
|
||||||
upx_uintptr_t c_end = c + mem_size(1, c_size);
|
upx_ptraddr_t c_end = c + mem_size(1, c_size);
|
||||||
if very_unlikely (a_end < a || b_end < b || c_end < c) // wrap-around
|
if very_unlikely (a_end < a || b_end < b || c_end < c) // wrap-around
|
||||||
throwCantPack("ptr_check_no_overlap-overflow");
|
throwCantPack("ptr_check_no_overlap-overflow");
|
||||||
if very_unlikely (a < b_end && b < a_end)
|
if very_unlikely (a < b_end && b < a_end)
|
||||||
|
|||||||
+10
-6
@@ -93,6 +93,10 @@ T *NewArray(upx_uint64_t n) may_throw {
|
|||||||
// ptr util
|
// 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; }
|
||||||
|
|
||||||
// ptrdiff_t with nullptr checks and asserted size; will throw on failure
|
// ptrdiff_t with nullptr checks and asserted size; will throw on failure
|
||||||
// NOTE: returns size_in_bytes, not number of elements!
|
// NOTE: returns size_in_bytes, not number of elements!
|
||||||
int ptr_diff_bytes(const void *a, const void *b) may_throw;
|
int ptr_diff_bytes(const void *a, const void *b) may_throw;
|
||||||
@@ -112,19 +116,19 @@ ptr_udiff(const T *a, const U *b) may_throw {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// check that buffers do not overlap; will throw on error
|
// check that buffers do not overlap; will throw on error
|
||||||
noinline void uintptr_check_no_overlap(upx_uintptr_t a, size_t a_size, upx_uintptr_t b,
|
noinline void ptraddr_check_no_overlap(upx_ptraddr_t a, size_t a_size, upx_ptraddr_t b,
|
||||||
size_t b_size) may_throw;
|
size_t b_size) may_throw;
|
||||||
noinline void uintptr_check_no_overlap(upx_uintptr_t a, size_t a_size, upx_uintptr_t b,
|
noinline void ptraddr_check_no_overlap(upx_ptraddr_t a, size_t a_size, upx_ptraddr_t b,
|
||||||
size_t b_size, upx_uintptr_t c, size_t c_size) may_throw;
|
size_t b_size, upx_ptraddr_t c, size_t c_size) may_throw;
|
||||||
|
|
||||||
forceinline void ptr_check_no_overlap(const void *a, size_t a_size, const void *b, size_t b_size)
|
forceinline void ptr_check_no_overlap(const void *a, size_t a_size, const void *b, size_t b_size)
|
||||||
may_throw {
|
may_throw {
|
||||||
uintptr_check_no_overlap((upx_uintptr_t) a, a_size, (upx_uintptr_t) b, b_size);
|
ptraddr_check_no_overlap(ptr_get_address(a), a_size, ptr_get_address(b), b_size);
|
||||||
}
|
}
|
||||||
forceinline void ptr_check_no_overlap(const void *a, size_t a_size, const void *b, size_t b_size,
|
forceinline void ptr_check_no_overlap(const void *a, size_t a_size, const void *b, size_t b_size,
|
||||||
const void *c, size_t c_size) may_throw {
|
const void *c, size_t c_size) may_throw {
|
||||||
uintptr_check_no_overlap((upx_uintptr_t) a, a_size, (upx_uintptr_t) b, b_size,
|
ptraddr_check_no_overlap(ptr_get_address(a), a_size, ptr_get_address(b), b_size,
|
||||||
(upx_uintptr_t) c, c_size);
|
ptr_get_address(c), c_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
// invalidate and poison a pointer: point to a non-null invalid address
|
// invalidate and poison a pointer: point to a non-null invalid address
|
||||||
|
|||||||
+3
-2
@@ -76,9 +76,10 @@ void xspan_check_range(const void *ptr, const void *base, ptrdiff_t size_in_byte
|
|||||||
xspan_fail_range_nullptr();
|
xspan_fail_range_nullptr();
|
||||||
if very_unlikely (base == nullptr)
|
if very_unlikely (base == nullptr)
|
||||||
xspan_fail_range_nullbase();
|
xspan_fail_range_nullbase();
|
||||||
#if defined(__SANITIZE_ADDRESS__)
|
#if defined(__SANITIZE_ADDRESS__) || 1
|
||||||
// info: pointers are out of range deliberately during internal doctest checks; see dt_xspan.cpp
|
// info: pointers are out of range deliberately during internal doctest checks; see dt_xspan.cpp
|
||||||
const acc_intptr_t off = (acc_uintptr_t) ptr - (acc_uintptr_t) base;
|
ACC_COMPILE_TIME_ASSERT(sizeof(intptr_t) == sizeof(upx_ptraddr_t))
|
||||||
|
const intptr_t off = ptr_get_address(ptr) - ptr_get_address(base);
|
||||||
#else
|
#else
|
||||||
const ptrdiff_t off = (const charptr) ptr - (const charptr) base;
|
const ptrdiff_t off = (const charptr) ptr - (const charptr) base;
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
Reference in New Issue
Block a user