diff options
Diffstat (limited to 'libtest')
| -rw-r--r-- | libtest/common.h | 2 | ||||
| -rw-r--r-- | libtest/globals.c | 4 | ||||
| -rw-r--r-- | libtest/libtest.h | 2 | ||||
| -rw-r--r-- | libtest/libtest_alloc.c | 58 | ||||
| -rw-r--r-- | libtest/libtest_free.c | 10 | ||||
| -rw-r--r-- | libtest/mmap.c | 2 |
6 files changed, 73 insertions, 5 deletions
diff --git a/libtest/common.h b/libtest/common.h index ab59bab..d6557b1 100644 --- a/libtest/common.h +++ b/libtest/common.h @@ -160,6 +160,8 @@ extern struct meminfo libtest_allocs_head; extern struct meminfo libtest_allocs_tail; extern int libtest_allocs_list_inited; extern atomic_flag libtest_allocs_list_spinlock; +extern void *libtest_pretend_list[128]; +extern size_t libtest_npretends; extern _Thread_local int libtest_zero_on_alloc; extern _Thread_local int libtest_expect_zeroed; diff --git a/libtest/globals.c b/libtest/globals.c index e5229a1..6e79402 100644 --- a/libtest/globals.c +++ b/libtest/globals.c @@ -25,10 +25,14 @@ volatile int libtest_mmap_is_custom = -1; volatile int libtest_munmap_is_custom = -1; volatile int libtest_mremap_is_custom = -1; +volatile int libtest_pretend_allocation_successful = 0; + struct meminfo libtest_allocs_head; struct meminfo libtest_allocs_tail; int libtest_allocs_list_inited = 0; atomic_flag libtest_allocs_list_spinlock = ATOMIC_FLAG_INIT; +void *libtest_pretend_list[128]; +size_t libtest_npretends = 0u; _Thread_local int libtest_zero_on_alloc = 0; _Thread_local int libtest_expect_zeroed = 0; diff --git a/libtest/libtest.h b/libtest/libtest.h index e4b4098..6eadd6f 100644 --- a/libtest/libtest.h +++ b/libtest/libtest.h @@ -437,6 +437,8 @@ size_t libtest_get_alloc_failure_in(void); void libtest_set_alloc_failure_in(size_t n); +extern volatile int libtest_pretend_allocation_successful; + extern const unsigned char *volatile libtest_random_pattern; extern volatile size_t libtest_random_pattern_length; extern volatile size_t libtest_random_pattern_offset; diff --git a/libtest/libtest_alloc.c b/libtest/libtest_alloc.c index 96aa132..022881a 100644 --- a/libtest/libtest_alloc.c +++ b/libtest/libtest_alloc.c @@ -53,8 +53,8 @@ mmap_anon(size_t size) } -void * -libtest_alloc(struct meminfo *meminfo) +static void * +try_alloc(struct meminfo *meminfo) { static _Thread_local int recursion_guard = 0; void *base_ptr, *ret_ptr; @@ -206,6 +206,60 @@ libtest_alloc(struct meminfo *meminfo) } +void * +libtest_alloc(struct meminfo *meminfo) +{ + void *ptr; + size_t reqsize; + ptr = try_alloc(meminfo); + if (!ptr && libtest_pretend_allocation_successful) { + reqsize = meminfo->requested_alloc_size; + meminfo->requested_alloc_size = 0u; + ptr = try_alloc(meminfo); + assert(ptr != NULL); + meminfo->requested_alloc_size = reqsize; + GET_MEMINFO(ptr)->requested_alloc_size = reqsize; + SPINLOCK(libtest_allocs_list_spinlock); + if (libtest_npretends >= ELEMSOF(libtest_pretend_list)) + SPINUNLOCK(libtest_allocs_list_spinlock); + assert(libtest_npretends < ELEMSOF(libtest_pretend_list)); + libtest_pretend_list[libtest_npretends++] = ptr; + SPINUNLOCK(libtest_allocs_list_spinlock); + } + return ptr; +} + + +void * +(memset)(void *s, int c, size_t n) +{ + unsigned char *us = s, uc = (unsigned char)c; + size_t i; + + SPINLOCK(libtest_allocs_list_spinlock); + for (i = 0u; i < libtest_npretends; i++) { + if (libtest_pretend_list[i] == s) { + /* We only do this for pointers in the pretend list + * because we must know that it is actually a + * pointer created with libtest_alloc, and not + * mmap(2) or stack-allocated or statically + * allocated buffer; and that's why libtest_pretend_list + * exist instead of being inferred or a flag. */ + if (n > GET_MEMINFO(s)->usable_alloc_size) + n = GET_MEMINFO(s)->usable_alloc_size; + break; + } + } + SPINUNLOCK(libtest_allocs_list_spinlock); + + for (i = 0u; i < n; i++) + us[i] = uc; + + return us; +} + + + #else diff --git a/libtest/libtest_free.c b/libtest/libtest_free.c index 5592e0a..d46218e 100644 --- a/libtest/libtest_free.c +++ b/libtest/libtest_free.c @@ -39,12 +39,18 @@ libtest_free(void *ptr, enum libtest_zero_check zero_checking) assert(mem->origin != FROM_MMAP_ANON); /* Delist allocation */ + SPINLOCK(libtest_allocs_list_spinlock); if (!libtest_kill_malloc_tracking) { - SPINLOCK(libtest_allocs_list_spinlock); mem->prev->next = mem->next; mem->next->prev = mem->prev; - SPINUNLOCK(libtest_allocs_list_spinlock); } + for (i = 0u; i < libtest_npretends; i++) { + if (libtest_pretend_list[i] == ptr) { + libtest_pretend_list[i] = libtest_pretend_list[--libtest_npretends]; + break; + } + } + SPINUNLOCK(libtest_allocs_list_spinlock); /* Check memory is zeroed */ if (zero_checking && libtest_expect_zeroed && !mem->accept_leakage) { diff --git a/libtest/mmap.c b/libtest/mmap.c index c3b3067..3bd3cb3 100644 --- a/libtest/mmap.c +++ b/libtest/mmap.c @@ -8,7 +8,7 @@ #ifdef SYS_mmap2 -# define IF_MMAP2(A) (A) +# define IF_MMAP2(A) do { A; } while (0) #else # define IF_MMAP2(A) ((void)0) #endif |
