mirror of
https://github.com/mirror/tinycc.git
synced 2025-01-27 06:10:06 +08:00
lib/bcheck: Prevent libc_malloc/libc_free etc from being miscompiled
On i386 and gcc-4.7 I found that libc_malloc was miscompiled - look: static void *libc_malloc(size_t size) { void *ptr; restore_malloc_hooks(); // __malloc_hook = saved_malloc_hook ptr = malloc(size); install_malloc_hooks(); // saved_malloc_hook = __malloc_hook, __malloc_hook = __bound_malloc return ptr; } .type libc_malloc, @function libc_malloc: .LFB56: .cfi_startproc pushl %edx .cfi_def_cfa_offset 8 movl %eax, (%esp) call malloc movl $__bound_malloc, __malloc_hook movl $__bound_free, __free_hook movl $__bound_realloc, __realloc_hook movl $__bound_memalign, __memalign_hook popl %ecx .cfi_def_cfa_offset 4 ret Here gcc inlined both restore_malloc_hooks() and install_malloc_hooks() and decided that saved_malloc_hook -> __malloc_hook -> saved_malloc_hook stores are not needed and could be ommitted. Only it did not know __molloc_hook affects malloc()... So add compiler barrier to both install and restore hooks functions and be done with it - the code is now ok: diff --git a/bcheck0.s b/bcheck1.s index 5f50293..4c02a5f 100644 --- a/bcheck0.s +++ b/bcheck1.s @@ -42,8 +42,24 @@ libc_malloc: .cfi_startproc pushl %edx .cfi_def_cfa_offset 8 + movl saved_malloc_hook, %edx + movl %edx, __malloc_hook + movl saved_free_hook, %edx + movl %edx, __free_hook + movl saved_realloc_hook, %edx + movl %edx, __realloc_hook + movl saved_memalign_hook, %edx + movl %edx, __memalign_hook movl %eax, (%esp) call malloc + movl __malloc_hook, %edx + movl %edx, saved_malloc_hook + movl __free_hook, %edx + movl %edx, saved_free_hook + movl __realloc_hook, %edx + movl %edx, saved_realloc_hook + movl __memalign_hook, %edx + movl %edx, saved_memalign_hook movl $__bound_malloc, __malloc_hook movl $__bound_free, __free_hook movl $__bound_realloc, __realloc_hook For barrier I use __asm__ __volatile__ ("": : : "memory") which is used as compiler barrier by Linux kernel, and mentioned in gcc docs and in wikipedia [1]. Without this patch any program compiled with tcc -b crashes in startup because of infinite recursion in libc_malloc. [1] http://en.wikipedia.org/wiki/Memory_ordering#Compiler_memory_barrier
This commit is contained in:
parent
14c99236da
commit
646b51833f
@ -638,6 +638,9 @@ static unsigned long get_region_size(void *p)
|
|||||||
|
|
||||||
/* patched memory functions */
|
/* patched memory functions */
|
||||||
|
|
||||||
|
/* force compiler to perform stores coded up to this point */
|
||||||
|
#define barrier() __asm__ __volatile__ ("": : : "memory")
|
||||||
|
|
||||||
static void install_malloc_hooks(void)
|
static void install_malloc_hooks(void)
|
||||||
{
|
{
|
||||||
#ifdef CONFIG_TCC_MALLOC_HOOKS
|
#ifdef CONFIG_TCC_MALLOC_HOOKS
|
||||||
@ -649,6 +652,8 @@ static void install_malloc_hooks(void)
|
|||||||
__free_hook = __bound_free;
|
__free_hook = __bound_free;
|
||||||
__realloc_hook = __bound_realloc;
|
__realloc_hook = __bound_realloc;
|
||||||
__memalign_hook = __bound_memalign;
|
__memalign_hook = __bound_memalign;
|
||||||
|
|
||||||
|
barrier();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -659,6 +664,8 @@ static void restore_malloc_hooks(void)
|
|||||||
__free_hook = saved_free_hook;
|
__free_hook = saved_free_hook;
|
||||||
__realloc_hook = saved_realloc_hook;
|
__realloc_hook = saved_realloc_hook;
|
||||||
__memalign_hook = saved_memalign_hook;
|
__memalign_hook = saved_memalign_hook;
|
||||||
|
|
||||||
|
barrier();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user