This is the mail archive of the newlib@sourceware.org mailing list for the newlib project.
| Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
|---|---|---|
| Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |
| Other format: | [Raw text] | |
Joey? Bin?
Any input?
Thanks,
Corinna
On Jan 3 14:56, Joe Seymour wrote:
> While working on another issue, I noticed something in nano-mallocr.c
> that doesn't look right to me:
>
> As described in nano-mallocr.c, chunks of heap are represented in memory
> as follows: [ size ] [ optional padding ] [ data area ]
>
> Note that "optional padding" refers to padding added explicitly by code,
> not to any padding that the compiler could theoretically introduce into
> the layout of the struct.
>
> Annotating the code around line 310 of nano-mallocr.c (nano_malloc) with
> some comments:
>
> /* r is either a chunk address retrieved from the free list, or a
> new address retrieved from sbrk_aligned. */
>
> /* ptr points to the data area ASSUMING that no optional padding is
> being used. */
> ptr = (char *)r + CHUNK_OFFSET;
>
> /* align_ptr points to the data area, taking any padding into
> account. */
> align_ptr = (char *)ALIGN_TO((unsigned long)ptr, MALLOC_ALIGN);
>
> /* offset is the size of the optional padding. */
> offset = align_ptr - ptr;
>
> This means that r < ptr <= align_ptr
>
> The layout can then be summarised as follows:
> (r) [ size ] [ compiler padding ]
> (ptr) [ explicit optional padding ]
> (align_ptr) [ data area ]
>
> nano_malloc then needs to initialize any optional padding with a
> negative offset to size:
>
> if (offset)
> {
> *(long *)((char *)r + offset) = -offset;
> }
>
> The above code calculates the address of the optional padding as
> (r + offset). This looks incorrect to me, as offset is the size of the
> padding, not the size of [ size ] + [ compiler padding ].
>
> Similarly, it then populates the padding with -offset, when the padding
> should be populated with a negative offset to [ size ].
>
> I don't have a motivating test case for this, it is based purely on
> reading of the code. I suspect that in most (all?) real cases the value
> of offset is coincidentally equal to the required value.
>
> The following patch addresses these concerns.
>
> I've built and tested as follows:
> Configured (gcc+newlib) with: --target=msp430-elf --enable-languages=c
> gcc testsuite variations:
> msp430-sim/-mcpu=msp430
> msp430-sim/-mcpu=msp430x
> msp430-sim/-mcpu=msp430x/-mlarge/-mdata-region=either/-mcode-region=either
> msp430-sim/-mhwmult=none
> msp430-sim/-mhwmult=f5series
> My testing has shown no regressions, however I don't know if the gcc
> testsuite provides sufficient coverage for this patch?
>
> In an ideal world I would propose a patch that eliminates the use of
> code-managed padding in nano_malloc, unfortunately I don't have the time
> to consider whether such a patch is viable.
>
> I don't have write access, so if this patch is deemed correct and
> acceptable, I would appreciate if someone would commit it on my behalf.
>
> Thanks,
>
> 2017-01-XX Joe Seymour <joe.s@somniumtech.com>
>
> newlib/
> * libc/stdlib/nano-mallocr.c (nano_malloc): Fix initialization
> of padding. Add comments.
> (nano_memalign): Fix initialization of padding.
> ---
> newlib/libc/stdlib/nano-mallocr.c | 9 +++++++--
> 1 files changed, 7 insertions(+), 2 deletions(-)
>
> diff --git a/newlib/libc/stdlib/nano-mallocr.c b/newlib/libc/stdlib/nano-mallocr.c
> index 457eb88..61e6591 100644
> --- a/newlib/libc/stdlib/nano-mallocr.c
> +++ b/newlib/libc/stdlib/nano-mallocr.c
> @@ -307,14 +307,19 @@ void * nano_malloc(RARG malloc_size_t s)
> }
> MALLOC_UNLOCK;
>
> + /* ptr points to malloc_chunk.next, ASSUMING that no alignment padding is
> + being used. */
> ptr = (char *)r + CHUNK_OFFSET;
>
> + /* align_ptr points to malloc_chunk.next, taking alignment padding into
> + account. */
> align_ptr = (char *)ALIGN_TO((unsigned long)ptr, MALLOC_ALIGN);
> offset = align_ptr - ptr;
>
> if (offset)
> {
> - *(long *)((char *)r + offset) = -offset;
> + /* Write the negative offset to size into alignment padding. */
> + *(long *)(ptr) = -(CHUNK_OFFSET);
> }
>
> assert(align_ptr + size <= (char *)r + alloc_size);
> @@ -587,7 +592,7 @@ void * nano_memalign(RARG size_t align, size_t s)
> /* Padding is used. Need to set a jump offset for aligned pointer
> * to get back to chunk head */
> assert(offset >= sizeof(int));
> - *(long *)((char *)chunk_p + offset) = -offset;
> + *(long *)((char *)chunk_p + CHUNK_OFFSET) = -(CHUNK_OFFSET);
> }
> }
>
> --
> 1.7.1
--
Corinna Vinschen
Cygwin Maintainer
Red Hat
Attachment:
signature.asc
Description: PGP signature
| Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
|---|---|---|
| Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |