[reprise] PIC and flat shared library support for m68k
Richard Sandiford
richard at codesourcery.com
Fri Nov 17 07:37:12 UTC 2006
Mike Frysinger <vapier at gentoo.org> writes:
> this change was introduced as a fix on Blackfin ...
Right. AIUI, the Blackfin issue was that heap structures are only
aligned in the same way that HEAP_GRANULARITY_TYPE is aligned, so the
alignment macros should reflect that. Before the patch, the addresses
of heap objects were not always a multiple of either MALLOC_ALIGNMENT or
HEAP_GRANULARITY (the two macros must be the same), which triggers an
error in the debug checker.
I fully agree that __alignof__((double)) is the right value for most
targets, and my patch was supposed to keep that behaviour. I.e. the
patch should be a no-op for targets like Blackfin, but fixes those
weird targets like m68k where __alignof__((double)) < sizeof (size_t).
Richard
> -mike
>
> On Friday 27 October 2006 10:15, Richard Sandiford wrote:
>> However, retesting on m68k showed up a problem that had appeared in
>> uClibc since the last time I tried. Specifically, revision 15785 did:
>>
>> -#define HEAP_GRANULARITY (sizeof (HEAP_GRANULARITY_TYPE))
>> +#define HEAP_GRANULARITY (__alignof__ (HEAP_GRANULARITY_TYPE))
>>
>> -#define MALLOC_ALIGNMENT (sizeof (double))
>> +#define MALLOC_ALIGNMENT (__alignof__ (double))
>>
>> The problem is that
>>
>> (a) MALLOC_HEADER_SIZE == MALLOC_ALIGNMENT
>> (b) the header contains a size value of type size_t
>> (c) sizeof (size_t) is 4 on m68k, but...
>> (d) __alignof__ (double) is only 2 (the largest alignment used on m68k)
>>
>> So we only allocate 2 bytes for the 4-byte header, and the least
>> significant 2 bytes of the size are in the user's area rather than
>> the header. The patch below fixes that problem by redefining
>> MALLOC_HEADER_SIZE to:
>>
>> MAX (MALLOC_ALIGNMENT, sizeof (size_t))
>>
>> (but without the help of the MAX macro ;)). However, we really would
>> like to have word alignment on Coldfire. It makes a big performance
>> difference, and because we have to allocate a 4-byte header anyway,
>> what wastage there is will be confined to the end of the allocated block.
>> Any wastage will also be limited to 2 bytes per allocation compared to
>> the current alignment.
>>
>> I've therefore used the __aligned__ type attribute to create a double
>> type that has at least sizeof (size_t) bytes of alignment. I've
>> introduced a new __attribute_aligned__ macro for this. It might seem
>> silly protecting against old or non-GNU compilers here, but the extra
>> alignment is only an optimisation, and having the macro is more in the
>> spirit of the other attribute code.
>>
>> Tested on m68k. Please install if OK.
>>
>> Richard
>>
>>
>> Index: include/sys/cdefs.h
>> ===================================================================
>> --- include/sys/cdefs.h (revision 16433)
>> +++ include/sys/cdefs.h (working copy)
>> @@ -189,6 +189,14 @@ #define __warndecl(name, msg) extern voi
>> # define __attribute__(xyz) /* Ignore */
>> #endif
>>
>> +/* __attribute_aligned__ is a no-op unless it can be used as both a
>> + variable and a type attribute. gcc 2.8 is known to support both. */
>> +#if __GNUC_PREREQ (2,8)
>> +#define __attribute_aligned__(size) __attribute__ ((__aligned__ (size)))
>> +#else
>> +#define __attribute_aligned__(size) /* Ignore */
>> +#endif
>> +
>> /* At some point during the gcc 2.96 development the `malloc' attribute
>> for functions was introduced. We don't want to use it unconditionally
>> (although this would be possible) since it generates warnings. */
>> Index: libc/stdlib/malloc/heap.h
>> ===================================================================
>> --- libc/stdlib/malloc/heap.h (revision 16433)
>> +++ libc/stdlib/malloc/heap.h (working copy)
>> @@ -24,7 +24,7 @@
>> /* The heap allocates in multiples of, and aligned to, HEAP_GRANULARITY.
>> HEAP_GRANULARITY must be a power of 2. Malloc depends on this being
>> the same as MALLOC_ALIGNMENT. */
>> -#define HEAP_GRANULARITY_TYPE double
>> +#define HEAP_GRANULARITY_TYPE double __attribute_aligned__ (sizeof
>> (size_t)) #define HEAP_GRANULARITY (__alignof__ (HEAP_GRANULARITY_TYPE))
>>
>>
>> Index: libc/stdlib/malloc/malloc.h
>> ===================================================================
>> --- libc/stdlib/malloc/malloc.h (revision 16433)
>> +++ libc/stdlib/malloc/malloc.h (working copy)
>> @@ -11,8 +11,13 @@
>> * Written by Miles Bader <miles at gnu.org>
>> */
>>
>> -/* The alignment we guarantee for malloc return values. */
>> -#define MALLOC_ALIGNMENT (__alignof__ (double))
>> +/* The alignment we guarantee for malloc return values. We prefer this
>> + to be at least sizeof (size_t) bytes because (a) we have to allocate
>> + that many bytes for the header anyway and (b) guaranteeing word
>> + alignment can be a significant win on targets like m68k and Coldfire,
>> + where __alignof__(double) == 2. */
>> +#define MALLOC_ALIGNMENT \
>> + __alignof__ (double __attribute_aligned__ (sizeof (size_t)))
>>
>> /* The system pagesize... */
>> extern size_t __pagesize;
>> @@ -98,17 +103,20 @@ extern int __putc(int c, FILE *stream) a
>>
>>
>> /* The size of a malloc allocation is stored in a size_t word
>> - MALLOC_ALIGNMENT bytes prior to the start address of the allocation:
>> + MALLOC_HEADER_SIZE bytes prior to the start address of the allocation:
>>
>> +--------+---------+-------------------+
>>
>> | SIZE |(unused) | allocation ... |
>>
>> +--------+---------+-------------------+
>> ^ BASE ^ ADDR
>> - ^ ADDR - MALLOC_ALIGN
>> + ^ ADDR - MALLOC_HEADER_SIZE
>> */
>>
>> /* The amount of extra space used by the malloc header. */
>> -#define MALLOC_HEADER_SIZE MALLOC_ALIGNMENT
>> +#define MALLOC_HEADER_SIZE \
>> + (MALLOC_ALIGNMENT < sizeof (size_t) \
>> + ? sizeof (size_t) \
>> + : MALLOC_ALIGNMENT)
>>
>> /* Set up the malloc header, and return the user address of a malloc
>> block. */ #define MALLOC_SETUP(base, size) \
More information about the uClibc
mailing list