Section sizing + orphan placement bugs

Khem Raj kraj@mvista.com
Thu Nov 24 18:12:00 GMT 2005


Daniel Jacobowitz wrote:
> The patch at the end of this message is fairly obvious, but the testcase
> deserves some explanation.  It shows at least one other serious bug that
> this patch does not fix.
>
> Here's a testcase that works on x86_64.  Should work just about anywhere
> with a standard page size of 4K.  Assemble and then link with -shared.
>
> 	.section .note.foo, "a", %note
> 	.space 16
>
> 	.section .data, "aw"
> 	.space 3800
>
> 	.section .rodata, "a"
> 	.space 4
>   
probably test case should also be added to regression testsuites.
> ./x86/ld/ld-new: section .note.foo [00000000001011a0 -> 00000000001011af] overlaps section .data [00000000001010c8 -> 0000000000101f9f]
> ./x86/ld/ld-new: note: section .note.foo lma 0x1011a0 overlaps previous sections
>
> The -shared option is necessary to trigger the bug because it will cause
> there to be no .interp section in the output.  We try to place notes with
> .interp first.  Without that they get stuck into the orphan list for either
> the next best flags match (usually .rodata), or *ABS*.
>
> The .rodata section is necessary to trigger the bug because otherwise there
> will be no output section for .rodata, so lang_output_section_find_by_flags
> will place the orphaned .note.foo section there.  If there is one, we'll see
> that it has SHT_PROGBITS instead of SHT_NOTE, and refuse to use .rodata.  We
> fall back to *ABS*, which places them at the front of the file.
>
> I suspect we should try to place them with something else for shared
> libraries; .rodata isn't a great choice.  But *ABS* works out OK most of the
> time (if there aren't too many orphans, the note will end up in the first
> page with the phdrs, anyway).
>
> The .data section is necessary to trigger the bug because it causes the
> DATA_SECTION_ALIGN mechanism to size sections a second time.  -z relro would
> probably have a similar effect.
>
> Now we've placed this output section at the very front of the list of
> linker statements.  It ends up before the assignment to
> . = . + SIZEOF_HEADERS, which is the other serious bug I mentioned up top.
> We need to place orphans after an initial assignment to dot; otherwise, the
> program headers will end up outside of the load segment!
>
> Anyway, as a consequence of not having yet assigned to dot, the second call
> to one_lang_size_sections_pass gets a stale value of os->region->current,
> and places the section in an arbitrary location; then it resets dot
> downwards and places everything else, and we end up overlapping .data.
> The unreduced testcase somehow put it in the middle of .hash.
>
> I think the attached fix is right for that part of the bug but I'm open to
> suggestions on how to handle SIZEOF_HEADERS.
>
>   



More information about the Binutils mailing list