diff --git a/ld/ChangeLog b/ld/ChangeLog index 3883bcbd4d5..c1c977ac3bb 100644 --- a/ld/ChangeLog +++ b/ld/ChangeLog @@ -1,3 +1,14 @@ +2017-03-09 Andrew Burgess + + * ldlang.c (lang_leave_output_section_statement): Move lma_region + logic to... + (lang_propagate_lma_regions): ...this new function. + (lang_process): Call new function. + * testsuite/ld-elf/orphan-9.d: New file. + * testsuite/ld-elf/orphan-9.ld: New file. + * testsuite/ld-elf/orphan-9.s: New file. + * NEWS: Mention change in behaviour. + 2017-03-07 Alan Modra * ldlang.c (open_input_bfds): Check that lang_assignment_statement diff --git a/ld/NEWS b/ld/NEWS index 23ca25a4f14..86e90736177 100644 --- a/ld/NEWS +++ b/ld/NEWS @@ -5,6 +5,9 @@ * When configuring for arc*-*-linux* targets the default linker emulation will change if --with-cpu=nps400 is used at configure time. +* Improve assignment of LMAs to orphan sections in some edge cases where a + mixture of both AT>LMA_REGION and AT(LMA) are used. + Changes in 2.28: * The EXCLUDE_FILE linker script construct can now be applied outside of the diff --git a/ld/ldlang.c b/ld/ldlang.c index ff6ef395b5d..89b896f51df 100644 --- a/ld/ldlang.c +++ b/ld/ldlang.c @@ -6844,6 +6844,27 @@ lang_check_relocs (void) } } +/* Look through all output sections looking for places where we can + propagate forward the lma region. */ + +static void +lang_propagate_lma_regions (void) +{ + lang_output_section_statement_type *os; + + for (os = &lang_output_section_statement.head->output_section_statement; + os != NULL; + os = os->next) + { + if (os->prev != NULL + && os->lma_region == NULL + && os->load_base == NULL + && os->addr_tree == NULL + && os->region == os->prev->region) + os->lma_region = os->prev->lma_region; + } +} + void lang_process (void) { @@ -7022,6 +7043,9 @@ lang_process (void) } } + /* Copy forward lma regions for output sections in same lma region. */ + lang_propagate_lma_regions (); + /* Do anything special before sizing sections. This is where ELF and other back-ends size dynamic sections. */ ldemul_before_allocation (); @@ -7302,16 +7326,6 @@ lang_leave_output_section_statement (fill_type *fill, const char *memspec, current_section->load_base != NULL, current_section->addr_tree != NULL); - /* If this section has no load region or base, but uses the same - region as the previous section, then propagate the previous - section's load region. */ - - if (current_section->lma_region == NULL - && current_section->load_base == NULL - && current_section->addr_tree == NULL - && current_section->region == current_section->prev->region) - current_section->lma_region = current_section->prev->lma_region; - current_section->fill = fill; current_section->phdrs = phdrs; pop_stat_ptr (); diff --git a/ld/testsuite/ld-elf/orphan-9.d b/ld/testsuite/ld-elf/orphan-9.d new file mode 100644 index 00000000000..637e8c5d374 --- /dev/null +++ b/ld/testsuite/ld-elf/orphan-9.d @@ -0,0 +1,12 @@ +#source: orphan-9.s +#ld: -N -T orphan-9.ld +#objdump: -h +#notarget: d30v-* dlx-* fr30-* frv-* ft32-* iq2000-* mn10200-* moxie-* ms1-* msp430-* mt-* pj-* + +#... + . \.text 0+(08|10) [0-9a-f]+ 0+200 .* +#... + . \.data 0+(08|10) [0-9a-f]+ 0+300 .* +#... + . \.data\.1 0+8 [0-9a-f]+ 0+3(0|1)[0-9a-f] .* +#pass diff --git a/ld/testsuite/ld-elf/orphan-9.ld b/ld/testsuite/ld-elf/orphan-9.ld new file mode 100644 index 00000000000..1a6773de183 --- /dev/null +++ b/ld/testsuite/ld-elf/orphan-9.ld @@ -0,0 +1,28 @@ +/* This linker script is used for orphan-9 test. + + We have a single byte in .data, and an orphan .data.1 + section. We are checking that the .data.1 orphan is assigned an + LMA after .data rather than picking up the lma region of .rodata. */ + +MEMORY +{ + MEM : ORIGIN = 0x1000, LENGTH = 0x100 + TEXT : ORIGIN = 0x200, LENGTH = 0x50 + DATA : ORIGIN = 0x300, LENGTH = 0x50 + RODATA : ORIGIN = 0x400, LENGTH = 0x50 +} + +SECTIONS +{ + .text : { + *(.text) + } >MEM AT>TEXT + + .data : AT(0x300) { + *(.data) + } >MEM + + .rodata : { + *(.rodata) + } >MEM AT>RODATA +} diff --git a/ld/testsuite/ld-elf/orphan-9.s b/ld/testsuite/ld-elf/orphan-9.s new file mode 100644 index 00000000000..27efad8c2df --- /dev/null +++ b/ld/testsuite/ld-elf/orphan-9.s @@ -0,0 +1,11 @@ + .text + .byte 0, 0, 0, 0, 0, 0, 0, 0 + + .data + .byte 0, 0, 0, 0, 0, 0, 0, 0 + + .section ".data.1", "aw" + .byte 0, 0, 0, 0, 0, 0, 0, 0 + + .section ".rodata", "a" + .byte 0, 0, 0, 0, 0, 0, 0, 0