From patchwork Fri Jan 15 14:33:47 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Florian Weimer X-Patchwork-Id: 10393 Received: (qmail 52162 invoked by alias); 15 Jan 2016 14:33:54 -0000 Mailing-List: contact libc-alpha-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: libc-alpha-owner@sourceware.org Delivered-To: mailing list libc-alpha@sourceware.org Received: (qmail 52148 invoked by uid 89); 15 Jan 2016 14:33:52 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-1.9 required=5.0 tests=BAYES_00, RP_MATCHES_RCVD, SPF_HELO_PASS autolearn=ham version=3.3.2 spammy=1497, 149, 7, expense, decreasing X-HELO: mx1.redhat.com To: GNU C Library From: Florian Weimer Subject: [PATCH] Avoid expected failure of tst-malloc-thread-fail on ppc X-Enigmail-Draft-Status: N1110 Message-ID: <5699034B.5080206@redhat.com> Date: Fri, 15 Jan 2016 15:33:47 +0100 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:38.0) Gecko/20100101 Thunderbird/38.4.0 MIME-Version: 1.0 ppc has a conformance issue where malloc does not return pointers with sufficient alignment (bug 6527). The alignment checks in tst-malloc-thread-fail reveal this. I believe a previous attempt to fix this has been rolled back because it broke undump support in Emacs, so I'm working around this in the test case. Getting MALLOC_ALIGNMENT out of malloc.c is a bit tricky because its definition changes between SHARED and !SHARED, so I created a new internal header and included it from a dedicated file. In the future, I will add additional items to for some whitebox testing. Tested on powerpc-redhat-linux-gnu and x86_64-redhat-linux-gnu. Florian 2016-01-15 Florian Weimer * malloc/malloc-private.h: New file. (INTERNAL_SIZE_T, SIZE_SZ, MALLOC_ALIGNMENT, MALLOC_ALIGN_MASK): Moved ... * malloc/malloc.c (INTERNAL_SIZE_T, SIZE_SZ, MALLOC_ALIGNMENT) (MALLOC_ALIGN_MASK): ... from here. * malloc/tst-malloc-thread-fail.c (allocate_1): Use malloc_alignment. * malloc/test-malloc-alignment.c, malloc/test-malloc-alignment.h: New file. * malloc/Makefile (tst-malloc-thread-fail): Add dependency. diff --git a/malloc/Makefile b/malloc/Makefile index 360288b..cac1b5e 100644 --- a/malloc/Makefile +++ b/malloc/Makefile @@ -167,3 +167,5 @@ $(objpfx)libmemusage.so: $(libdl) # Extra dependencies $(foreach o,$(all-object-suffixes),$(objpfx)malloc$(o)): arena.c hooks.c + +$(objpfx)tst-malloc-thread-fail: $(objpfx)test-malloc-alignment.o diff --git a/malloc/malloc-private.h b/malloc/malloc-private.h new file mode 100644 index 0000000..482a406 --- /dev/null +++ b/malloc/malloc-private.h @@ -0,0 +1,91 @@ +/* Malloc implementation for multiple threads without lock contention. + Copyright (C) 1996-2016 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Wolfram Gloger + and Doug Lea , 2001. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; see the file COPYING.LIB. If + not, see . */ + +#ifndef MALLOC_PRIVATE_H +#define MALLOC_PRIVATE_H + +#include +#include +#include +#include + +/* INTERNAL_SIZE_T is the word-size used for internal bookkeeping of + chunk sizes. + + The default version is the same as size_t. + + While not strictly necessary, it is best to define this as an + unsigned type, even if size_t is a signed type. This may avoid some + artificial size limitations on some systems. + + On a 64-bit machine, you may be able to reduce malloc overhead by + defining INTERNAL_SIZE_T to be a 32 bit `unsigned int' at the + expense of not being able to handle more than 2^32 of malloced + space. If this limitation is acceptable, you are encouraged to set + this unless you are on a platform requiring 16byte alignments. In + this case the alignment requirements turn out to negate any + potential advantages of decreasing size_t word size. + + Implementors: Beware of the possible combinations of: + - INTERNAL_SIZE_T might be signed or unsigned, might be 32 or 64 bits, + and might be the same width as int or as long + - size_t might have different width and signedness as INTERNAL_SIZE_T + - int and long might be 32 or 64 bits, and might be the same width + To deal with this, most comparisons and difference computations + among INTERNAL_SIZE_Ts should cast them to unsigned long, being + aware of the fact that casting an unsigned int to a wider long does + not sign-extend. (This also makes checking for negative numbers + awkward.) Some of these casts result in harmless compiler warnings + on some systems. */ +#ifndef INTERNAL_SIZE_T +#define INTERNAL_SIZE_T size_t +#endif + +/* The corresponding word size. */ +#define SIZE_SZ (sizeof (INTERNAL_SIZE_T)) + + +/* MALLOC_ALIGNMENT is the minimum alignment for malloc'ed chunks. + + It must be a power of two at least 2 * SIZE_SZ, even on machines + for which smaller alignments would suffice. It may be defined as + larger than this though. Note however that code and data structures + are optimized for the case of 8-byte alignment. */ +#ifndef MALLOC_ALIGNMENT +# if !SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_16) +/* This is the correct definition when there is no past ABI to constrain it. + + Among configurations with a past ABI constraint, it differs from + 2*SIZE_SZ only on powerpc32. For the time being, changing this is + causing more compatibility problems due to malloc_get_state and + malloc_set_state than will returning blocks not adequately aligned for + long double objects under -mlong-double-128. */ + +# define MALLOC_ALIGNMENT (2 * SIZE_SZ < __alignof__ (long double) \ + ? __alignof__ (long double) : 2 * SIZE_SZ) +# else +# define MALLOC_ALIGNMENT (2 * SIZE_SZ) +# endif +#endif + +/* The corresponding bit mask value */ +#define MALLOC_ALIGN_MASK (MALLOC_ALIGNMENT - 1) + +#endif /* MALLOC_PRIVATE_H */ diff --git a/malloc/malloc.c b/malloc/malloc.c index d20d595..1572448 100644 --- a/malloc/malloc.c +++ b/malloc/malloc.c @@ -216,8 +216,7 @@ #include /* for getenv(), abort() */ #include /* for __libc_enable_secure */ -#include -#include +#include #include #include <_itoa.h> @@ -303,76 +302,6 @@ __malloc_assert (const char *assertion, const char *file, unsigned int line, /* - INTERNAL_SIZE_T is the word-size used for internal bookkeeping - of chunk sizes. - - The default version is the same as size_t. - - While not strictly necessary, it is best to define this as an - unsigned type, even if size_t is a signed type. This may avoid some - artificial size limitations on some systems. - - On a 64-bit machine, you may be able to reduce malloc overhead by - defining INTERNAL_SIZE_T to be a 32 bit `unsigned int' at the - expense of not being able to handle more than 2^32 of malloced - space. If this limitation is acceptable, you are encouraged to set - this unless you are on a platform requiring 16byte alignments. In - this case the alignment requirements turn out to negate any - potential advantages of decreasing size_t word size. - - Implementors: Beware of the possible combinations of: - - INTERNAL_SIZE_T might be signed or unsigned, might be 32 or 64 bits, - and might be the same width as int or as long - - size_t might have different width and signedness as INTERNAL_SIZE_T - - int and long might be 32 or 64 bits, and might be the same width - To deal with this, most comparisons and difference computations - among INTERNAL_SIZE_Ts should cast them to unsigned long, being - aware of the fact that casting an unsigned int to a wider long does - not sign-extend. (This also makes checking for negative numbers - awkward.) Some of these casts result in harmless compiler warnings - on some systems. -*/ - -#ifndef INTERNAL_SIZE_T -#define INTERNAL_SIZE_T size_t -#endif - -/* The corresponding word size */ -#define SIZE_SZ (sizeof(INTERNAL_SIZE_T)) - - -/* - MALLOC_ALIGNMENT is the minimum alignment for malloc'ed chunks. - It must be a power of two at least 2 * SIZE_SZ, even on machines - for which smaller alignments would suffice. It may be defined as - larger than this though. Note however that code and data structures - are optimized for the case of 8-byte alignment. -*/ - - -#ifndef MALLOC_ALIGNMENT -# if !SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_16) -/* This is the correct definition when there is no past ABI to constrain it. - - Among configurations with a past ABI constraint, it differs from - 2*SIZE_SZ only on powerpc32. For the time being, changing this is - causing more compatibility problems due to malloc_get_state and - malloc_set_state than will returning blocks not adequately aligned for - long double objects under -mlong-double-128. */ - -# define MALLOC_ALIGNMENT (2 *SIZE_SZ < __alignof__ (long double) \ - ? __alignof__ (long double) : 2 *SIZE_SZ) -# else -# define MALLOC_ALIGNMENT (2 *SIZE_SZ) -# endif -#endif - -/* The corresponding bit mask value */ -#define MALLOC_ALIGN_MASK (MALLOC_ALIGNMENT - 1) - - - -/* REALLOC_ZERO_BYTES_FREES should be set if a call to realloc with zero bytes should be the same as a call to free. This is required by the C standard. Otherwise, since this malloc diff --git a/malloc/test-malloc-alignment.c b/malloc/test-malloc-alignment.c new file mode 100644 index 0000000..492d23a --- /dev/null +++ b/malloc/test-malloc-alignment.c @@ -0,0 +1,28 @@ +/* Export malloc alignment for use in test cases. + Copyright (C) 2016 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; see the file COPYING.LIB. If + not, see . */ + +#include + +/* If we do not define SHARED, SHLIB_COMPAT in the definition of + MALLOC_ALIGNMENT will not provide the expected definition. Because + of the need to define SHARED, we put this definition into a + separate file. */ +#define SHARED 1 +#include + +size_t malloc_alignment = MALLOC_ALIGNMENT; diff --git a/malloc/test-malloc-alignment.h b/malloc/test-malloc-alignment.h new file mode 100644 index 0000000..940709d --- /dev/null +++ b/malloc/test-malloc-alignment.h @@ -0,0 +1,26 @@ +/* Export malloc alignment for use in test cases. + Copyright (C) 2016 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; see the file COPYING.LIB. If + not, see . */ + +#ifndef TEST_MALLOC_ALIGNMENT_H +#define TEST_MALLOC_ALIGNMENT_H + +#include + +extern size_t malloc_alignment; + +#endif /* TEST_MALLOC_ALIGNMENT_H */ diff --git a/malloc/tst-malloc-thread-fail.c b/malloc/tst-malloc-thread-fail.c index fc090ef..4968b19 100644 --- a/malloc/tst-malloc-thread-fail.c +++ b/malloc/tst-malloc-thread-fail.c @@ -31,6 +31,8 @@ #include #include +#include + /* Wrapper for calloc with an optimization barrier. */ static void * __attribute__ ((noinline, noclone)) @@ -82,8 +84,10 @@ allocate_1 (void) switch (allocation_function) { case with_malloc: + /* Use malloc_alignment instead of _Alignof (max_align_t) so + that this test does not fail due to bug 6527. */ return (struct allocate_result) - {malloc (allocation_size), _Alignof (max_align_t)}; + {malloc (allocation_size), malloc_alignment}; case with_realloc: { void *p = realloc (NULL, 16); @@ -96,7 +100,7 @@ allocate_1 (void) if (q == NULL) free (p); } - return (struct allocate_result) {q, _Alignof (max_align_t)}; + return (struct allocate_result) {q, malloc_alignment}; } case with_aligned_alloc: { @@ -145,7 +149,7 @@ allocate_1 (void) printf ("error: non-zero byte at offset %zu\n", i); abort (); } - return (struct allocate_result) {p, _Alignof (max_align_t)}; + return (struct allocate_result) {p, malloc_alignment}; } } abort ();