This is the mail archive of the libc-hacker@sourceware.org mailing list for the glibc project.
Note that libc-hacker is a closed list. You may look at the archives of this list, but subscription and posting are not open.
Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
---|---|---|
Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |
Other format: | [Raw text] |
Hi! The recent switch to 128-bit long double on ppc32 broke malloc, as on this 32-bit arch long double is 16 byte aligned, but malloc was only guaranteeing 8 byte aligment so far. On sparc32 and s390 this is not a problem, since __alignof__ (long double) is 8. But, apparently some of the quick checks for invalid pointers don't work when MALLOC_ALIGNMENT is bigger than 2 * SIZE_SZ, in that case the pointer returned to the user must be MALLOC_ALIGNMENT aligned, not the chunk pointer (which is always user pointer - 2 * SIZE_SZ). With this, ppc32 glibc passes make check. I haven't checked though if this pessimizes code on i?86/x86_64 or other important arches, will do soon. If it does, then we might consider doing: #define check_align_OK(chunkptr, userptr) \ (MALLOC_ALIGNMENT > 2 * SIZE_SZ \ ? __builtin_expect ((uintptr_t) userptr & MALLOC_ALIGN_MASK, 0) \ : __builtin_expect ((uintptr_t) chunkptr & MALLOC_ALIGN_MASK, 0)) and using check_align_OK (oldp, oldmem) etc. 2006-02-28 Jakub Jelinek <jakub@redhat.com> * malloc/malloc.c (MALLOC_ALIGNMENT): Set to __alignof__ (long double) if long double is more aligned than 2 * SIZE_SZ. (public_rEALLOc, _int_free, _int_realloc): Check that *mem is aligned, rather than corresponding mem2chunk pointer. --- libc/malloc/malloc.c 2005-12-30 09:04:02.000000000 +0100 +++ libc/malloc/malloc.c 2006-02-28 15:30:20.000000000 +0100 @@ -188,7 +188,8 @@ Changing default word sizes: INTERNAL_SIZE_T size_t - MALLOC_ALIGNMENT 2 * sizeof(INTERNAL_SIZE_T) + MALLOC_ALIGNMENT MAX (2 * sizeof(INTERNAL_SIZE_T), + __alignof__ (long double)) Configuration and functionality options: @@ -380,7 +381,8 @@ extern "C" { #ifndef MALLOC_ALIGNMENT -#define MALLOC_ALIGNMENT (2 * SIZE_SZ) +#define MALLOC_ALIGNMENT (2 * SIZE_SZ < __alignof__ (long double) \ + ? __alignof__ (long double) : 2 * SIZE_SZ) #endif /* The corresponding bit mask value */ @@ -3468,7 +3470,7 @@ public_rEALLOc(Void_t* oldmem, size_t by Therefore we can exclude some size values which might appear here by accident or by "design" from some intruder. */ if (__builtin_expect ((uintptr_t) oldp > (uintptr_t) -oldsize, 0) - || __builtin_expect ((uintptr_t) oldp & MALLOC_ALIGN_MASK, 0)) + || __builtin_expect ((uintptr_t) oldmem & MALLOC_ALIGN_MASK, 0)) { malloc_printerr (check_action, "realloc(): invalid pointer", oldmem); return NULL; @@ -4282,7 +4284,7 @@ _int_free(mstate av, Void_t* mem) Therefore we can exclude some size values which might appear here by accident or by "design" from some intruder. */ if (__builtin_expect ((uintptr_t) p > (uintptr_t) -size, 0) - || __builtin_expect ((uintptr_t) p & MALLOC_ALIGN_MASK, 0)) + || __builtin_expect ((uintptr_t) mem & MALLOC_ALIGN_MASK, 0)) { errstr = "free(): invalid pointer"; errout: @@ -4628,7 +4630,7 @@ _int_realloc(mstate av, Void_t* oldmem, oldsize = chunksize(oldp); /* Simple tests for old block integrity. */ - if (__builtin_expect ((uintptr_t) oldp & MALLOC_ALIGN_MASK, 0)) + if (__builtin_expect ((uintptr_t) oldmem & MALLOC_ALIGN_MASK, 0)) { errstr = "realloc(): invalid pointer"; errout: Jakub
Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
---|---|---|
Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |