From 13075d049d492477dfbf795c305adbab5abb6d81 Mon Sep 17 00:00:00 2001 From: Sebastian Huber Date: Sun, 2 Feb 2014 06:39:39 -0800 Subject: [PATCH] Fix ALIGN_WITH_INPUT ld/ 2014-02-02 Sebastian Huber * ld/ld.texinfo: Change ALIGN_WITH_INPUT documentation. * ld/ldlang.c (lang_size_sections_1): Add dotdelta variable which reflects the VMA change due to alignment requirements. Use dotdelta do change the LMA if ALIGN_WITH_INPUT is requested. ld/testsuite/ChangeLog 2014-02-02 Sebastian Huber * ld-scripts/rgn-at9.d: New file. * ld-scripts/rgn-at9.t: Likewise. * ld-scripts/rgn-at10.d: Likewise. * ld-scripts/rgn-at10.s: Likewise. * ld-scripts/rgn-at10.t: Likewise. * ld-scripts/rgn-at11.d: Likewise. * ld-scripts/rgn-at11.t: Likewise. --- ld/ChangeLog | 8 ++++++ ld/ld.texinfo | 6 ++--- ld/ldlang.c | 42 ++++++++++++++++++------------ ld/testsuite/ChangeLog | 10 +++++++ ld/testsuite/ld-scripts/rgn-at10.d | 12 +++++++++ ld/testsuite/ld-scripts/rgn-at10.s | 10 +++++++ ld/testsuite/ld-scripts/rgn-at10.t | 13 +++++++++ ld/testsuite/ld-scripts/rgn-at11.d | 11 ++++++++ ld/testsuite/ld-scripts/rgn-at11.t | 13 +++++++++ ld/testsuite/ld-scripts/rgn-at9.d | 10 +++++++ ld/testsuite/ld-scripts/rgn-at9.t | 12 +++++++++ 11 files changed, 127 insertions(+), 20 deletions(-) create mode 100644 ld/testsuite/ld-scripts/rgn-at10.d create mode 100644 ld/testsuite/ld-scripts/rgn-at10.s create mode 100644 ld/testsuite/ld-scripts/rgn-at10.t create mode 100644 ld/testsuite/ld-scripts/rgn-at11.d create mode 100644 ld/testsuite/ld-scripts/rgn-at11.t create mode 100644 ld/testsuite/ld-scripts/rgn-at9.d create mode 100644 ld/testsuite/ld-scripts/rgn-at9.t diff --git a/ld/ChangeLog b/ld/ChangeLog index 1c95e252b7a..df4453935a0 100644 --- a/ld/ChangeLog +++ b/ld/ChangeLog @@ -1,3 +1,11 @@ +2014-02-02 Sebastian Huber + + * ld/ld.texinfo: Change ALIGN_WITH_INPUT documentation. + * ld/ldlang.c (lang_size_sections_1): Add dotdelta + variable which reflects the VMA change due to alignment + requirements. Use dotdelta do change the LMA if + ALIGN_WITH_INPUT is requested. + 2014-02-01 Hans-Peter Nilsson * emultempl/mmix-elfnmmo.em (mmix_after_allocation): Fix typo in diff --git a/ld/ld.texinfo b/ld/ld.texinfo index 1287a6cc180..bfc264378db 100644 --- a/ld/ld.texinfo +++ b/ld/ld.texinfo @@ -4609,10 +4609,8 @@ for (dst = &_bstart; dst< &_bend; dst++) @cindex forcing output section alignment @cindex output section alignment You can increase an output section's alignment by using ALIGN. As an -alternative you can force the output section alignment to the maximum alignment -of all its input sections with ALIGN_WITH_INPUT. The alignment forced by -ALIGN_WITH_INPUT is used even in case the load and virtual memory regions are -different. +alternative you can enforce that the difference between the VMA and LMA remains +intact throughout this output section with the ALIGN_WITH_INPUT attribute. @node Forced Input Alignment @subsubsection Forced Input Alignment diff --git a/ld/ldlang.c b/ld/ldlang.c index 9903f7003cf..4768af7e0d5 100644 --- a/ld/ldlang.c +++ b/ld/ldlang.c @@ -4808,7 +4808,7 @@ lang_size_sections_1 { case lang_output_section_statement_enum: { - bfd_vma newdot, after; + bfd_vma newdot, after, dotdelta; lang_output_section_statement_type *os; lang_memory_region_type *r; int section_alignment = 0; @@ -4874,6 +4874,7 @@ lang_size_sections_1 } newdot = dot; + dotdelta = 0; if (bfd_is_abs_section (os->bfd_section)) { /* No matter what happens, an abs section starts at zero. */ @@ -4942,13 +4943,14 @@ lang_size_sections_1 bfd_vma savedot = newdot; newdot = align_power (newdot, section_alignment); - if (newdot != savedot + dotdelta = newdot - savedot; + if (dotdelta != 0 && (config.warn_section_align || os->addr_tree != NULL) && expld.phase != lang_mark_phase_enum) einfo (_("%P: warning: changing start of section" " %s by %lu bytes\n"), - os->name, (unsigned long) (newdot - savedot)); + os->name, (unsigned long) dotdelta); } bfd_set_section_vma (0, os->bfd_section, newdot); @@ -4996,15 +4998,20 @@ lang_size_sections_1 { bfd_vma lma = os->lma_region->current; - /* When LMA_REGION is the same as REGION, align the LMA - as we did for the VMA, possibly including alignment - from the bfd section. If a different region, then - only align according to the value in the output - statement unless specified otherwise. */ - if (os->lma_region != os->region && !os->align_lma_with_input) - section_alignment = os->section_alignment; - if (section_alignment > 0) - lma = align_power (lma, section_alignment); + if (os->align_lma_with_input) + lma += dotdelta; + else + { + /* When LMA_REGION is the same as REGION, align the LMA + as we did for the VMA, possibly including alignment + from the bfd section. If a different region, then + only align according to the value in the output + statement. */ + if (os->lma_region != os->region) + section_alignment = os->section_alignment; + if (section_alignment > 0) + lma = align_power (lma, section_alignment); + } os->bfd_section->lma = lma; } else if (r->last_os != NULL @@ -5080,7 +5087,10 @@ lang_size_sections_1 if ((os->bfd_section->flags & SEC_HAS_CONTENTS) != 0 || (os->bfd_section->flags & SEC_THREAD_LOCAL) == 0 || link_info.relocatable) - dot += TO_ADDR (os->bfd_section->size); + dotdelta = TO_ADDR (os->bfd_section->size); + else + dotdelta = 0; + dot += dotdelta; if (os->update_dot_tree != 0) exp_fold_tree (os->update_dot_tree, bfd_abs_section_ptr, &dot); @@ -5100,10 +5110,10 @@ lang_size_sections_1 os->bfd_section->vma); if (os->lma_region != NULL && os->lma_region != os->region - && (os->bfd_section->flags & SEC_LOAD)) + && ((os->bfd_section->flags & SEC_LOAD) + || os->align_lma_with_input)) { - os->lma_region->current - = os->bfd_section->lma + TO_ADDR (os->bfd_section->size); + os->lma_region->current = os->bfd_section->lma + dotdelta; if (check_regions) os_region_check (os, os->lma_region, NULL, diff --git a/ld/testsuite/ChangeLog b/ld/testsuite/ChangeLog index a46d25caa29..e9eb2aadfcd 100644 --- a/ld/testsuite/ChangeLog +++ b/ld/testsuite/ChangeLog @@ -1,3 +1,13 @@ +2014-02-02 Sebastian Huber + + * ld-scripts/rgn-at9.d: New file. + * ld-scripts/rgn-at9.t: Likewise. + * ld-scripts/rgn-at10.d: Likewise. + * ld-scripts/rgn-at10.s: Likewise. + * ld-scripts/rgn-at10.t: Likewise. + * ld-scripts/rgn-at11.d: Likewise. + * ld-scripts/rgn-at11.t: Likewise. + 2014-01-30 Sandra Loosemore * ld-nios2/relax_call26.s: New. diff --git a/ld/testsuite/ld-scripts/rgn-at10.d b/ld/testsuite/ld-scripts/rgn-at10.d new file mode 100644 index 00000000000..73ebfccf6b7 --- /dev/null +++ b/ld/testsuite/ld-scripts/rgn-at10.d @@ -0,0 +1,12 @@ +#source: rgn-at10.s +#ld: -T rgn-at10.t +#objdump: -h --wide +#xfail: rx-*-* +# Test that lma is adjusted in case the section start vma is aligned and +# lma_region != region if requested by script. Make sure this works with +# non-load sections. + +#... +.* 0+10000 +0+20000 .* +.* 0+10100 +0+20100 .* +.* 0+10100 +0+20100 .* diff --git a/ld/testsuite/ld-scripts/rgn-at10.s b/ld/testsuite/ld-scripts/rgn-at10.s new file mode 100644 index 00000000000..b53820586e3 --- /dev/null +++ b/ld/testsuite/ld-scripts/rgn-at10.s @@ -0,0 +1,10 @@ + .text + .long 0 + + .section .tbss,"awT",%nobits + .p2align 8 + .zero 4 + + .data + .p2align 4 + .long 0 diff --git a/ld/testsuite/ld-scripts/rgn-at10.t b/ld/testsuite/ld-scripts/rgn-at10.t new file mode 100644 index 00000000000..0aa0b27e0d1 --- /dev/null +++ b/ld/testsuite/ld-scripts/rgn-at10.t @@ -0,0 +1,13 @@ +MEMORY +{ + ram : ORIGIN = 0x10000, LENGTH = 0x10000 + rom : ORIGIN = 0x20000, LENGTH = 0x10000 +} + +SECTIONS +{ + .text : ALIGN_WITH_INPUT {*(.text)} > ram AT> rom + .tbss : ALIGN_WITH_INPUT {*(.tbss)} > ram AT> rom + .data : ALIGN_WITH_INPUT {*(.data)} > ram AT> rom + /DISCARD/ : {*(*)} +} diff --git a/ld/testsuite/ld-scripts/rgn-at11.d b/ld/testsuite/ld-scripts/rgn-at11.d new file mode 100644 index 00000000000..9ebbd28494a --- /dev/null +++ b/ld/testsuite/ld-scripts/rgn-at11.d @@ -0,0 +1,11 @@ +#source: rgn-at10.s +#ld: -T rgn-at11.t +#objdump: -h --wide +#xfail: rx-*-* +# Test that lma is not adjusted in case the section start vma is aligned and +# lma_region != region if not requested by script. + +#... +.* 0+10000 +0+20000 .* +.* 0+10100 +0+20004 .* +.* 0+10100 +0+20004 .* diff --git a/ld/testsuite/ld-scripts/rgn-at11.t b/ld/testsuite/ld-scripts/rgn-at11.t new file mode 100644 index 00000000000..4f07c9db7f3 --- /dev/null +++ b/ld/testsuite/ld-scripts/rgn-at11.t @@ -0,0 +1,13 @@ +MEMORY +{ + ram : ORIGIN = 0x10000, LENGTH = 0x10000 + rom : ORIGIN = 0x20000, LENGTH = 0x10000 +} + +SECTIONS +{ + .text : ALIGN_WITH_INPUT {*(.text)} > ram AT> rom + .tbss : {*(.tbss)} > ram AT> rom + .data : ALIGN_WITH_INPUT {*(.data)} > ram AT> rom + /DISCARD/ : {*(*)} +} diff --git a/ld/testsuite/ld-scripts/rgn-at9.d b/ld/testsuite/ld-scripts/rgn-at9.d new file mode 100644 index 00000000000..e6384b451f3 --- /dev/null +++ b/ld/testsuite/ld-scripts/rgn-at9.d @@ -0,0 +1,10 @@ +#source: rgn-at6.s +#ld: -T rgn-at9.t +#objdump: -h --wide +#xfail: rx-*-* +# Test that lma is adjusted in case the section start vma is aligned and +# lma_region != region if requested by script. + +#... +.* 0+10000 +0+20080 .* +.* 0+10100 +0+20180 .* diff --git a/ld/testsuite/ld-scripts/rgn-at9.t b/ld/testsuite/ld-scripts/rgn-at9.t new file mode 100644 index 00000000000..7342e6449e6 --- /dev/null +++ b/ld/testsuite/ld-scripts/rgn-at9.t @@ -0,0 +1,12 @@ +MEMORY +{ + ram : ORIGIN = 0x10000, LENGTH = 0x10000 + rom : ORIGIN = 0x20080, LENGTH = 0x10000 +} + +SECTIONS +{ + .text : ALIGN_WITH_INPUT {*(.text)} > ram AT> rom + .data : ALIGN_WITH_INPUT {*(.data)} > ram AT> rom + /DISCARD/ : {*(*)} +} -- 2.30.2