Fix ALIGN_WITH_INPUT
authorSebastian Huber <sebastian.huber@embedded-brains.de>
Sun, 2 Feb 2014 14:39:39 +0000 (06:39 -0800)
committerH.J. Lu <hjl.tools@gmail.com>
Sun, 2 Feb 2014 14:39:39 +0000 (06:39 -0800)
ld/

2014-02-02  Sebastian Huber  <sebastian.huber@embedded-brains.de>

* 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  <sebastian.huber@embedded-brains.de>

* 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
ld/ld.texinfo
ld/ldlang.c
ld/testsuite/ChangeLog
ld/testsuite/ld-scripts/rgn-at10.d [new file with mode: 0644]
ld/testsuite/ld-scripts/rgn-at10.s [new file with mode: 0644]
ld/testsuite/ld-scripts/rgn-at10.t [new file with mode: 0644]
ld/testsuite/ld-scripts/rgn-at11.d [new file with mode: 0644]
ld/testsuite/ld-scripts/rgn-at11.t [new file with mode: 0644]
ld/testsuite/ld-scripts/rgn-at9.d [new file with mode: 0644]
ld/testsuite/ld-scripts/rgn-at9.t [new file with mode: 0644]

index 1c95e25..df44539 100644 (file)
@@ -1,3 +1,11 @@
+2014-02-02  Sebastian Huber  <sebastian.huber@embedded-brains.de>
+
+       * 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  <hp@bitrange.com>
 
        * emultempl/mmix-elfnmmo.em (mmix_after_allocation): Fix typo in
index 1287a6c..bfc2643 100644 (file)
@@ -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
index 9903f70..4768af7 100644 (file)
@@ -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,
index a46d25c..e9eb2aa 100644 (file)
@@ -1,3 +1,13 @@
+2014-02-02  Sebastian Huber  <sebastian.huber@embedded-brains.de>
+
+       * 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  <sandra@codesourcery.com>
 
        * 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 (file)
index 0000000..73ebfcc
--- /dev/null
@@ -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 (file)
index 0000000..b538205
--- /dev/null
@@ -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 (file)
index 0000000..0aa0b27
--- /dev/null
@@ -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 (file)
index 0000000..9ebbd28
--- /dev/null
@@ -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 (file)
index 0000000..4f07c9d
--- /dev/null
@@ -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 (file)
index 0000000..e6384b4
--- /dev/null
@@ -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 (file)
index 0000000..7342e64
--- /dev/null
@@ -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/ : {*(*)}
+}