mirror of
https://github.com/microsoft/mimalloc.git
synced 2025-05-06 15:29:31 +03:00
merge from dev
This commit is contained in:
commit
c0e1132674
9 changed files with 54 additions and 18 deletions
|
@ -319,6 +319,17 @@ if(MI_WIN_USE_FLS)
|
||||||
list(APPEND mi_defines MI_WIN_USE_FLS=1)
|
list(APPEND mi_defines MI_WIN_USE_FLS=1)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
|
||||||
|
# Check /proc/cpuinfo for an SV39 MMU and define a constant if one is
|
||||||
|
# found. We will want to skip the aligned hinting in that case. Issue #939, #949
|
||||||
|
if (EXISTS /proc/cpuinfo)
|
||||||
|
file(STRINGS /proc/cpuinfo mi_sv39_mmu REGEX "^mmu[ \t]+:[ \t]+sv39$")
|
||||||
|
if (mi_sv39_mmu)
|
||||||
|
MESSAGE( STATUS "Disable aligned hints (SV39 MMU detected)" )
|
||||||
|
list(APPEND mi_defines MI_NO_ALIGNED_HINT=1)
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
# On Haiku use `-DCMAKE_INSTALL_PREFIX` instead, issue #788
|
# On Haiku use `-DCMAKE_INSTALL_PREFIX` instead, issue #788
|
||||||
# if(CMAKE_SYSTEM_NAME MATCHES "Haiku")
|
# if(CMAKE_SYSTEM_NAME MATCHES "Haiku")
|
||||||
# SET(CMAKE_INSTALL_LIBDIR ~/config/non-packaged/lib)
|
# SET(CMAKE_INSTALL_LIBDIR ~/config/non-packaged/lib)
|
||||||
|
|
|
@ -707,6 +707,16 @@ static inline mi_encoded_t mi_ptr_encode(const void* null, const void* p, const
|
||||||
return mi_rotl(x ^ keys[1], keys[0]) + keys[0];
|
return mi_rotl(x ^ keys[1], keys[0]) + keys[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline uint32_t mi_ptr_encode_canary(const void* null, const void* p, const uintptr_t* keys) {
|
||||||
|
const uint32_t x = (uint32_t)(mi_ptr_encode(null,p,keys));
|
||||||
|
// make the lowest byte 0 to prevent spurious read overflows which could be a security issue (issue #951)
|
||||||
|
#ifdef MI_BIG_ENDIAN
|
||||||
|
return (x & 0x00FFFFFF);
|
||||||
|
#else
|
||||||
|
return (x & 0xFFFFFF00);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
static inline mi_block_t* mi_block_nextx( const void* null, const mi_block_t* block, const uintptr_t* keys ) {
|
static inline mi_block_t* mi_block_nextx( const void* null, const mi_block_t* block, const uintptr_t* keys ) {
|
||||||
mi_track_mem_defined(block,sizeof(mi_block_t));
|
mi_track_mem_defined(block,sizeof(mi_block_t));
|
||||||
mi_block_t* next;
|
mi_block_t* next;
|
||||||
|
|
|
@ -289,8 +289,8 @@ mi_decl_weak int reallocarr(void* p, size_t count, size_t size) { return mi_r
|
||||||
void __libc_free(void* p) MI_FORWARD0(mi_free, p)
|
void __libc_free(void* p) MI_FORWARD0(mi_free, p)
|
||||||
void* __libc_memalign(size_t alignment, size_t size) { return mi_memalign(alignment, size); }
|
void* __libc_memalign(size_t alignment, size_t size) { return mi_memalign(alignment, size); }
|
||||||
|
|
||||||
#elif defined(__GLIBC__) && defined(__linux__)
|
#elif defined(__linux__)
|
||||||
// forward __libc interface (needed for glibc-based Linux distributions)
|
// forward __libc interface (needed for glibc-based and musl-based Linux distributions)
|
||||||
void* __libc_malloc(size_t size) MI_FORWARD1(mi_malloc,size)
|
void* __libc_malloc(size_t size) MI_FORWARD1(mi_malloc,size)
|
||||||
void* __libc_calloc(size_t count, size_t size) MI_FORWARD2(mi_calloc,count,size)
|
void* __libc_calloc(size_t count, size_t size) MI_FORWARD2(mi_calloc,count,size)
|
||||||
void* __libc_realloc(void* p, size_t size) MI_FORWARD2(mi_realloc,p,size)
|
void* __libc_realloc(void* p, size_t size) MI_FORWARD2(mi_realloc,p,size)
|
||||||
|
|
|
@ -99,7 +99,7 @@ extern inline void* _mi_page_malloc_zero(mi_heap_t* heap, mi_page_t* page, size_
|
||||||
mi_assert_internal(delta >= 0 && mi_page_usable_block_size(page) >= (size - MI_PADDING_SIZE + delta));
|
mi_assert_internal(delta >= 0 && mi_page_usable_block_size(page) >= (size - MI_PADDING_SIZE + delta));
|
||||||
#endif
|
#endif
|
||||||
mi_track_mem_defined(padding,sizeof(mi_padding_t)); // note: re-enable since mi_page_usable_block_size may set noaccess
|
mi_track_mem_defined(padding,sizeof(mi_padding_t)); // note: re-enable since mi_page_usable_block_size may set noaccess
|
||||||
padding->canary = (uint32_t)(mi_ptr_encode(page,block,page->keys));
|
padding->canary = mi_ptr_encode_canary(page,block,page->keys);
|
||||||
padding->delta = (uint32_t)(delta);
|
padding->delta = (uint32_t)(delta);
|
||||||
#if MI_PADDING_CHECK
|
#if MI_PADDING_CHECK
|
||||||
if (!mi_page_is_huge(page)) {
|
if (!mi_page_is_huge(page)) {
|
||||||
|
|
|
@ -148,7 +148,7 @@ static void mi_arena_segment_os_mark_abandoned(mi_segment_t* segment) {
|
||||||
void _mi_arena_segment_mark_abandoned(mi_segment_t* segment)
|
void _mi_arena_segment_mark_abandoned(mi_segment_t* segment)
|
||||||
{
|
{
|
||||||
mi_assert_internal(segment->used == segment->abandoned);
|
mi_assert_internal(segment->used == segment->abandoned);
|
||||||
mi_atomic_store_release(&segment->thread_id, 0); // mark as abandoned for multi-thread free's
|
mi_atomic_store_release(&segment->thread_id, (uintptr_t)0); // mark as abandoned for multi-thread free's
|
||||||
if mi_unlikely(segment->memid.memkind != MI_MEM_ARENA) {
|
if mi_unlikely(segment->memid.memkind != MI_MEM_ARENA) {
|
||||||
mi_arena_segment_os_mark_abandoned(segment);
|
mi_arena_segment_os_mark_abandoned(segment);
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -422,7 +422,7 @@ static bool mi_page_decode_padding(const mi_page_t* page, const mi_block_t* bloc
|
||||||
uintptr_t keys[2];
|
uintptr_t keys[2];
|
||||||
keys[0] = page->keys[0];
|
keys[0] = page->keys[0];
|
||||||
keys[1] = page->keys[1];
|
keys[1] = page->keys[1];
|
||||||
bool ok = ((uint32_t)mi_ptr_encode(page,block,keys) == canary && *delta <= *bsize);
|
bool ok = (mi_ptr_encode_canary(page,block,keys) == canary && *delta <= *bsize);
|
||||||
mi_track_mem_noaccess(padding,sizeof(mi_padding_t));
|
mi_track_mem_noaccess(padding,sizeof(mi_padding_t));
|
||||||
return ok;
|
return ok;
|
||||||
}
|
}
|
||||||
|
|
20
src/libc.c
20
src/libc.c
|
@ -130,7 +130,7 @@ static void mi_out_alignright(char fill, char* start, size_t len, size_t extra,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void mi_out_num(uintptr_t x, size_t base, char prefix, char** out, char* end)
|
static void mi_out_num(uintmax_t x, size_t base, char prefix, char** out, char* end)
|
||||||
{
|
{
|
||||||
if (x == 0 || base == 0 || base > 16) {
|
if (x == 0 || base == 0 || base > 16) {
|
||||||
if (prefix != 0) { mi_outc(prefix, out, end); }
|
if (prefix != 0) { mi_outc(prefix, out, end); }
|
||||||
|
@ -206,12 +206,13 @@ void _mi_vsnprintf(char* buf, size_t bufsize, const char* fmt, va_list args) {
|
||||||
}
|
}
|
||||||
else if (c == 'p' || c == 'x' || c == 'u') {
|
else if (c == 'p' || c == 'x' || c == 'u') {
|
||||||
// unsigned
|
// unsigned
|
||||||
uintptr_t x = 0;
|
uintmax_t x = 0;
|
||||||
if (c == 'x' || c == 'u') {
|
if (c == 'x' || c == 'u') {
|
||||||
if (numtype == 'z') x = va_arg(args, size_t);
|
if (numtype == 'z') x = va_arg(args, size_t);
|
||||||
else if (numtype == 't') x = va_arg(args, uintptr_t); // unsigned ptrdiff_t
|
else if (numtype == 't') x = va_arg(args, uintptr_t); // unsigned ptrdiff_t
|
||||||
else if (numtype == 'L') x = (uintptr_t)va_arg(args, unsigned long long);
|
else if (numtype == 'L') x = va_arg(args, unsigned long long);
|
||||||
else x = va_arg(args, unsigned long);
|
else if (numtype == 'l') x = va_arg(args, unsigned long);
|
||||||
|
else x = va_arg(args, unsigned int);
|
||||||
}
|
}
|
||||||
else if (c == 'p') {
|
else if (c == 'p') {
|
||||||
x = va_arg(args, uintptr_t);
|
x = va_arg(args, uintptr_t);
|
||||||
|
@ -228,20 +229,21 @@ void _mi_vsnprintf(char* buf, size_t bufsize, const char* fmt, va_list args) {
|
||||||
}
|
}
|
||||||
else if (c == 'i' || c == 'd') {
|
else if (c == 'i' || c == 'd') {
|
||||||
// signed
|
// signed
|
||||||
intptr_t x = 0;
|
intmax_t x = 0;
|
||||||
if (numtype == 'z') x = va_arg(args, intptr_t );
|
if (numtype == 'z') x = va_arg(args, intptr_t );
|
||||||
else if (numtype == 't') x = va_arg(args, ptrdiff_t);
|
else if (numtype == 't') x = va_arg(args, ptrdiff_t);
|
||||||
else if (numtype == 'L') x = (intptr_t)va_arg(args, long long);
|
else if (numtype == 'L') x = va_arg(args, long long);
|
||||||
else x = va_arg(args, long);
|
else if (numtype == 'l') x = va_arg(args, long);
|
||||||
|
else x = va_arg(args, int);
|
||||||
char pre = 0;
|
char pre = 0;
|
||||||
if (x < 0) {
|
if (x < 0) {
|
||||||
pre = '-';
|
pre = '-';
|
||||||
if (x > INTPTR_MIN) { x = -x; }
|
if (x > INTMAX_MIN) { x = -x; }
|
||||||
}
|
}
|
||||||
else if (numplus != 0) {
|
else if (numplus != 0) {
|
||||||
pre = numplus;
|
pre = numplus;
|
||||||
}
|
}
|
||||||
mi_out_num((uintptr_t)x, 10, pre, &out, end);
|
mi_out_num((uintmax_t)x, 10, pre, &out, end);
|
||||||
}
|
}
|
||||||
else if (c >= ' ' && c <= '~') {
|
else if (c >= ' ' && c <= '~') {
|
||||||
// unknown format
|
// unknown format
|
||||||
|
|
7
src/os.c
7
src/os.c
|
@ -77,8 +77,9 @@ bool _mi_os_commit(void* addr, size_t size, bool* is_zero, mi_stats_t* tld_stats
|
||||||
-------------------------------------------------------------- */
|
-------------------------------------------------------------- */
|
||||||
|
|
||||||
// On 64-bit systems, we can do efficient aligned allocation by using
|
// On 64-bit systems, we can do efficient aligned allocation by using
|
||||||
// the 2TiB to 30TiB area to allocate those.
|
// the 2TiB to 30TiB area to allocate those. We assume we have
|
||||||
#if (MI_INTPTR_SIZE >= 8)
|
// at least 48 bits of virtual address space on 64-bit systems (but see issue #939)
|
||||||
|
#if (MI_INTPTR_SIZE >= 8) && !defined(MI_NO_ALIGNED_HINT)
|
||||||
static mi_decl_cache_align _Atomic(uintptr_t)aligned_base;
|
static mi_decl_cache_align _Atomic(uintptr_t)aligned_base;
|
||||||
|
|
||||||
// Return a MI_SEGMENT_SIZE aligned address that is probably available.
|
// Return a MI_SEGMENT_SIZE aligned address that is probably available.
|
||||||
|
@ -224,7 +225,7 @@ static void* mi_os_prim_alloc_aligned(size_t size, size_t alignment, bool commit
|
||||||
if (!(alignment >= _mi_os_page_size() && ((alignment & (alignment - 1)) == 0))) return NULL;
|
if (!(alignment >= _mi_os_page_size() && ((alignment & (alignment - 1)) == 0))) return NULL;
|
||||||
size = _mi_align_up(size, _mi_os_page_size());
|
size = _mi_align_up(size, _mi_os_page_size());
|
||||||
|
|
||||||
// try first with a hint (this will be aligned directly on Win 10+ or BSD)
|
// try first with a requested alignment hint (this will usually be aligned directly on Win 10+ or BSD)
|
||||||
void* p = mi_os_prim_alloc(size, alignment, commit, allow_large, is_large, is_zero, stats);
|
void* p = mi_os_prim_alloc(size, alignment, commit, allow_large, is_large, is_zero, stats);
|
||||||
if (p == NULL) return NULL;
|
if (p == NULL) return NULL;
|
||||||
|
|
||||||
|
|
|
@ -20,8 +20,12 @@ static void test_reserved(void);
|
||||||
static void negative_stat(void);
|
static void negative_stat(void);
|
||||||
static void alloc_huge(void);
|
static void alloc_huge(void);
|
||||||
static void test_heap_walk(void);
|
static void test_heap_walk(void);
|
||||||
|
<<<<<<< HEAD
|
||||||
static void test_heap_arena(void);
|
static void test_heap_arena(void);
|
||||||
static void test_align(void);
|
static void test_align(void);
|
||||||
|
=======
|
||||||
|
static void test_canary_leak(void);
|
||||||
|
>>>>>>> dev
|
||||||
// static void test_large_pages(void);
|
// static void test_large_pages(void);
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
|
@ -33,7 +37,8 @@ int main() {
|
||||||
// double_free2();
|
// double_free2();
|
||||||
// corrupt_free();
|
// corrupt_free();
|
||||||
// block_overflow1();
|
// block_overflow1();
|
||||||
block_overflow2();
|
// block_overflow2();
|
||||||
|
test_canary_leak();
|
||||||
// test_aslr();
|
// test_aslr();
|
||||||
// invalid_free();
|
// invalid_free();
|
||||||
// test_reserved();
|
// test_reserved();
|
||||||
|
@ -250,6 +255,13 @@ static void test_heap_arena(void) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
static void test_canary_leak(void) {
|
||||||
|
char* p = mi_mallocn_tp(char,23);
|
||||||
|
for(int i = 0; i < 23; i++) {
|
||||||
|
p[i] = '0'+i;
|
||||||
|
}
|
||||||
|
puts(p);
|
||||||
|
free(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Experiment with huge OS pages
|
// Experiment with huge OS pages
|
||||||
|
|
Loading…
Add table
Reference in a new issue