src: fix m68k-atari build, prepare for std::atomic, port John's MemBuffer debug

This commit is contained in:
Markus F.X.J. Oberhumer
2022-12-22 16:06:25 +01:00
parent 0b47e474a7
commit bb4cbdff44
6 changed files with 88 additions and 15 deletions
+24 -4
View File
@@ -32,6 +32,14 @@
void *membuffer_get_void_ptr(MemBuffer &mb) { return mb.getVoidPtr(); }
unsigned membuffer_get_size(MemBuffer &mb) { return mb.getSize(); }
MemBuffer::Stats MemBuffer::stats;
#if DEBUG
#define debug_set(var, expr) (var) = (expr)
#else
#define debug_set(var, expr) /*empty*/
#endif
/*************************************************************************
// bool use_simple_mcheck()
**************************************************************************/
@@ -60,13 +68,17 @@ __acc_static_forceinline constexpr bool use_simple_mcheck() { return true; }
//
**************************************************************************/
MemBuffer::MemBuffer(upx_uint64_t size_in_bytes) { alloc(size_in_bytes); }
MemBuffer::MemBuffer(upx_uint64_t size_in_bytes) {
alloc(size_in_bytes);
debug_set(debug.last_return_address_alloc, upx_return_address());
}
MemBuffer::~MemBuffer() { this->dealloc(); }
// similar to BoundedPtr, except checks only at creation
// skip == offset, take == size_in_bytes
void *MemBuffer::subref_impl(const char *errfmt, size_t skip, size_t take) {
debug_set(debug.last_return_address_subref, upx_return_address());
// check overrun and wrap-around
if (skip + take > b_size_in_bytes || skip + take < skip) {
char buf[100];
@@ -130,14 +142,17 @@ unsigned MemBuffer::getSizeForDecompression(unsigned uncompressed_size, unsigned
void MemBuffer::allocForCompression(unsigned uncompressed_size, unsigned extra) {
unsigned size = getSizeForCompression(uncompressed_size, extra);
alloc(size);
debug_set(debug.last_return_address_alloc, upx_return_address());
}
void MemBuffer::allocForDecompression(unsigned uncompressed_size, unsigned extra) {
unsigned size = getSizeForDecompression(uncompressed_size, extra);
alloc(size);
debug_set(debug.last_return_address_alloc, upx_return_address());
}
void MemBuffer::fill(unsigned off, unsigned len, int value) {
debug_set(debug.last_return_address_fill, upx_return_address());
checkState();
assert((int) off >= 0);
assert((int) len >= 0);
@@ -156,8 +171,6 @@ void MemBuffer::fill(unsigned off, unsigned len, int value) {
#define MAGIC1(p) ((PTR_BITS(p) ^ 0xfefdbeeb) | 1)
#define MAGIC2(p) ((PTR_BITS(p) ^ 0xfefdbeeb ^ 0x80024011) | 1)
unsigned MemBuffer::global_alloc_counter = 0;
void MemBuffer::checkState() const {
if (!b)
throwInternalError("block not allocated");
@@ -177,8 +190,10 @@ void MemBuffer::alloc(upx_uint64_t size) {
assert(b_size_in_bytes == 0);
//
assert(size > 0);
debug_set(debug.last_return_address_alloc, upx_return_address());
size_t bytes = mem_size(1, size, use_simple_mcheck() ? 32 : 0);
unsigned char *p = (unsigned char *) malloc(bytes);
NO_printf("MemBuffer::alloc %llu: %p\n", size, p);
if (!p)
throwOutOfMemoryException();
b = p;
@@ -189,17 +204,22 @@ void MemBuffer::alloc(upx_uint64_t size) {
set_ne32(b - 8, b_size_in_bytes);
set_ne32(b - 4, MAGIC1(b));
set_ne32(b + b_size_in_bytes, MAGIC2(b));
set_ne32(b + b_size_in_bytes + 4, global_alloc_counter++);
set_ne32(b + b_size_in_bytes + 4, stats.global_alloc_counter);
}
#if !defined(__SANITIZE_ADDRESS__) && 0
fill(0, b_size_in_bytes, (rand() & 0xff) | 1); // debug
(void) VALGRIND_MAKE_MEM_UNDEFINED(b, b_size_in_bytes);
#endif
stats.global_alloc_counter += 1;
stats.global_total_bytes += b_size_in_bytes;
stats.global_total_active_bytes += b_size_in_bytes;
}
void MemBuffer::dealloc() {
if (b != nullptr) {
debug_set(debug.last_return_address_dealloc, upx_return_address());
checkState();
stats.global_total_active_bytes -= b_size_in_bytes;
if (use_simple_mcheck()) {
// clear magic constants
set_ne32(b - 8, 0);