X-Git-Url: https://git.saurik.com/apple/dyld.git/blobdiff_plain/19894a1236eae932b4028640f24ab843f691d4e4..refs/heads/master:/src/dyldNew.cpp diff --git a/src/dyldNew.cpp b/src/dyldNew.cpp index d68fc4e..2bdafba 100644 --- a/src/dyldNew.cpp +++ b/src/dyldNew.cpp @@ -31,7 +31,7 @@ extern "C" void* __dso_handle; -#include "dyld.h" +#include "dyld2.h" #include "dyldLibSystemInterface.h" // @@ -51,7 +51,10 @@ struct dyld_static_pool { dyld_static_pool* previousPool; uint8_t* current; uint8_t* end; - uint8_t pool[1]; + + // libunwind, and probably others, need the pool to be 16-byte aligned as malloc guarantees that + __attribute__((__aligned__(16))) + uint8_t pool[1]; }; // allocate initial pool independently of pool header to take less space on disk @@ -62,12 +65,19 @@ static dyld_static_pool* currentPool = &initialPool; void* malloc(size_t size) { - if ( dyld::gLibSystemHelpers != NULL) { + if ( (dyld::gLibSystemHelpers != NULL) && dyld::gProcessInfo->libSystemInitialized ) { void* p = dyld::gLibSystemHelpers->malloc(size); //dyld::log("malloc(%lu) => %p from libSystem\n", size, p); return p; } else { + // keep allocations 16-byte aligned + size = ((size + 15) & -16); + + if ( size > DYLD_POOL_CHUNK_SIZE ) { + dyld::log("dyld malloc overflow: size=%lu\n", size); + dyld::halt("dyld malloc overflow\n"); + } size = (size+sizeof(void*)-1) & (-sizeof(void*)); // pointer align uint8_t* result = currentPool->current; currentPool->current += size; @@ -75,8 +85,7 @@ void* malloc(size_t size) vm_address_t addr = 0; kern_return_t r = vm_allocate(mach_task_self(), &addr, DYLD_POOL_CHUNK_SIZE, VM_FLAGS_ANYWHERE); if ( r != KERN_SUCCESS ) { - dyld::log("out of address space for dyld memory pool\n"); - exit(1); + dyld::halt("out of address space for dyld memory pool\n"); } dyld_static_pool* newPool = (dyld_static_pool*)addr; newPool->previousPool = NULL; @@ -86,7 +95,7 @@ void* malloc(size_t size) currentPool = newPool; if ( (currentPool->current + size) > currentPool->end ) { dyld::log("dyld memory pool exhausted: size=%lu\n", size); - exit(1); + dyld::halt("dyld memory pool exhausted\n"); } result = currentPool->current; currentPool->current += size; @@ -122,13 +131,21 @@ void free(void* ptr) void* calloc(size_t count, size_t size) { + // Check for overflow of integer multiplication + size_t total = count * size; + if ( total/count != size ) { + dyld::log("dyld calloc overflow: count=%zu, size=%zu\n", count, size); + dyld::halt("dyld calloc overflow"); + } if ( dyld::gLibSystemHelpers != NULL ) { - void* result = dyld::gLibSystemHelpers->malloc(size*count); - bzero(result, size*count); + void* result = dyld::gLibSystemHelpers->malloc(total); + if ( result != NULL ) + bzero(result, total); return result; } else { - return malloc(count*size); + // this allocates out of static buffer which is already zero filled + return malloc(total); } }