Enhance powerpc ld -r --relax
authorAlan Modra <amodra@gmail.com>
Wed, 25 Jul 2018 05:54:55 +0000 (15:24 +0930)
committerAlan Modra <amodra@gmail.com>
Wed, 25 Jul 2018 07:22:58 +0000 (16:52 +0930)
One of the ill effects of ld -r is to mash together sections.  That
can result in reduced icache performance at runtime due to unexpected
movement of code.  Another problem is that sections can become too
large to link on targets that have limited relative addressing.  ld -r
--relax attempts to overcome the large section problem for branches by
inserting trampolines, but the powerpc support added lots of
unnecessary trampolines.  This patch trims them somewhat.

bfd/
* elf32-ppc.c (ppc_elf_relax_section): Ignore common or undef locals.
Avoid trashing toff with added when used as a symbol index.
Ignore R_PPC_PLTREL24 addends in unused example code.  Avoid
creating unnecessary fixups when relocatable.
ld/
* testsuite/ld-powerpc/big.s: New file.
* testsuite/ld-powerpc/relaxrl.d: New test.
* testsuite/ld-powerpc/powerpc.exp: Run new test.
* testsuite/ld-powerpc/relaxr.d: Adjust.

bfd/ChangeLog
bfd/elf32-ppc.c
ld/ChangeLog
ld/testsuite/ld-powerpc/big.s [new file with mode: 0644]
ld/testsuite/ld-powerpc/powerpc.exp
ld/testsuite/ld-powerpc/relaxr.d
ld/testsuite/ld-powerpc/relaxrl.d [new file with mode: 0644]

index 8efa3870933d2a12c8a6601a2149d8efd0f8ba6f..e0e1a46e143597fa4c71af61a55b23b092f59b5f 100644 (file)
@@ -1,3 +1,10 @@
+2018-07-25  Alan Modra  <amodra@gmail.com>
+
+       * elf32-ppc.c (ppc_elf_relax_section): Ignore common or undef locals.
+       Avoid trashing toff with added when used as a symbol index.
+       Ignore R_PPC_PLTREL24 addends in unused example code.  Avoid
+       creating unnecessary fixups when relocatable.
+
 2018-07-25  Alan Modra  <amodra@gmail.com>
 
        * elf32-arm.c (elf32_arm_nabi_write_core_note): Disable
index 1ddfc6c1f400b9bff6e07e16b96f7736b3d20598..c289eebe316509d6fbfa9b1ac3e12b78829b0ea8 100644 (file)
@@ -7386,12 +7386,10 @@ ppc_elf_relax_section (bfd *abfd,
            {
              if (tsec != NULL)
                ;
-             else if (isym->st_shndx == SHN_UNDEF)
-               tsec = bfd_und_section_ptr;
              else if (isym->st_shndx == SHN_ABS)
                tsec = bfd_abs_section_ptr;
-             else if (isym->st_shndx == SHN_COMMON)
-               tsec = bfd_com_section_ptr;
+             else
+               continue;
 
              toff = isym->st_value;
              sym_type = ELF_ST_TYPE (isym->st_info);
@@ -7533,6 +7531,17 @@ ppc_elf_relax_section (bfd *abfd,
          if (tsec == isec)
            continue;
 
+         /* toff is used for the symbol index when the symbol is
+            undefined and we're doing a relocatable link, so we can't
+            support addends.  It would be possible to do so by
+            putting the addend in one_branch_fixup but addends on
+            branches are rare so it hardly seems worth supporting.  */
+         if (bfd_link_relocatable (link_info)
+             && tsec == bfd_und_section_ptr
+             && r_type != R_PPC_PLTREL24
+             && irel->r_addend != 0)
+           continue;
+
          /* There probably isn't any reason to handle symbols in
             SEC_MERGE sections;  SEC_MERGE doesn't seem a likely
             attribute for a code section, and we are only looking at
@@ -7556,7 +7565,8 @@ ppc_elf_relax_section (bfd *abfd,
                 a section symbol should not include the addend;  Such an
                 access is presumed to be an offset from "sym";  The
                 location of interest is just "sym".  */
-             if (sym_type == STT_SECTION)
+             if (sym_type == STT_SECTION
+                 && r_type != R_PPC_PLTREL24)
                toff += irel->r_addend;
 
              toff
@@ -7564,7 +7574,8 @@ ppc_elf_relax_section (bfd *abfd,
                                              elf_section_data (tsec)->sec_info,
                                              toff);
 
-             if (sym_type != STT_SECTION)
+             if (sym_type != STT_SECTION
+                 && r_type != R_PPC_PLTREL24)
                toff += irel->r_addend;
            }
          /* PLTREL24 addends are special.  */
@@ -7581,6 +7592,16 @@ ppc_elf_relax_section (bfd *abfd,
 
          roff = irel->r_offset;
 
+         /* Avoid creating a lot of unnecessary fixups when
+            relocatable if the output section size is such that a
+            fixup can be created at final link.
+            The max_branch_offset adjustment allows for some number
+            of other fixups being needed at final link.  */
+         if (bfd_link_relocatable (link_info)
+             && (isec->output_section->rawsize - (isec->output_offset + roff)
+                 < max_branch_offset - (max_branch_offset >> 4)))
+           continue;
+
          /* If the branch is in range, no need to do anything.  */
          if (tsec != bfd_und_section_ptr
              && (!bfd_link_relocatable (link_info)
index ecbbf485c9098a21baa362023fb36d4d0f5e8381..0b3058b20e56f17556773cf7bcce9b1beea23ec4 100644 (file)
@@ -1,3 +1,10 @@
+2018-07-25  Alan Modra  <amodra@gmail.com>
+
+       * testsuite/ld-powerpc/big.s: New file.
+       * testsuite/ld-powerpc/relaxrl.d: New test.
+       * testsuite/ld-powerpc/powerpc.exp: Run new test.
+       * testsuite/ld-powerpc/relaxr.d: Adjust.
+
 2018-07-24  Nick Clifton  <nickc@redhat.com>
 
        * po/fr.po: Updated French translation.
diff --git a/ld/testsuite/ld-powerpc/big.s b/ld/testsuite/ld-powerpc/big.s
new file mode 100644 (file)
index 0000000..e372c97
--- /dev/null
@@ -0,0 +1,2 @@
+ .text
+ .space 32*1024*1024
index 0359ba28cb2ac1f0f33a4a1bc29c6ce11e82926a..cfeb277f043d225b56c183af8ff7c78f28327c40 100644 (file)
@@ -160,6 +160,9 @@ set ppcelftests {
     {"relocatable relaxing" "-melf32ppc -r --relax" "" "-a32" "relax.s"
      {{objdump -dr relaxr.d}}
      "rrelax"}
+    {"relocatable relaxing large" "-melf32ppc -r --relax" "" "-a32" "relax.s big.s"
+     {{objdump -dr relaxrl.d}}
+     "rrelax"}
 }
 
 set ppc64elftests {
index 3ce2751c158c254e5b894257327926078bc262eb..1b3a3c147d0213d8656e208f29e4ee4ae0a37c95 100644 (file)
@@ -4,23 +4,13 @@
 Disassembly of section .text:
 
 00000000 <_start>:
-   0:  (48 00 00 15|15 00 00 48)       bl      14 <_start\+0x14>
-   4:  (48 00 00 21|21 00 00 48)       bl      24 <_start\+0x24>
-   8:  (48 00 00 0d|0d 00 00 48)       bl      14 <_start\+0x14>
-                       8: R_PPC_NONE   \*ABS\*
-   c:  (48 00 00 19|19 00 00 48)       bl      24 <_start\+0x24>
-                       c: R_PPC_NONE   \*ABS\*
+   0:  (48 00 00 01|01 00 00 48)       bl      0 <_start>
+                       0: R_PPC_REL24  near
+   4:  (48 00 00 01|01 00 00 48)       bl      4 <_start\+0x4>
+                       4: R_PPC_REL24  far
+   8:  (48 00 00 01|01 00 00 48)       bl      8 <_start\+0x8>
+                       8: R_PPC_REL24  near
+   c:  (48 00 00 01|01 00 00 48)       bl      c <_start\+0xc>
+                       c: R_PPC_REL24  far
   10:  (48 00 00 00|00 00 00 48)       b       10 <_start\+0x10>
                        10: R_PPC_REL24 _start
-  14:  (3d 80 00 00|00 00 80 3d)       lis     r12,0
-                       1(6|4): R_PPC_ADDR16_HA near
-  18:  (39 8c 00 00|00 00 8c 39)       addi    r12,r12,0
-                       1(a|8): R_PPC_ADDR16_LO near
-  1c:  (7d 89 03 a6|a6 03 89 7d)       mtctr   r12
-  20:  (4e 80 04 20|20 04 80 4e)       bctr
-  24:  (3d 80 00 00|00 00 80 3d)       lis     r12,0
-                       2(6|4): R_PPC_ADDR16_HA far
-  28:  (39 8c 00 00|00 00 8c 39)       addi    r12,r12,0
-                       2(a|8): R_PPC_ADDR16_LO far
-  2c:  (7d 89 03 a6|a6 03 89 7d)       mtctr   r12
-  30:  (4e 80 04 20|20 04 80 4e)       bctr
diff --git a/ld/testsuite/ld-powerpc/relaxrl.d b/ld/testsuite/ld-powerpc/relaxrl.d
new file mode 100644 (file)
index 0000000..8557e3f
--- /dev/null
@@ -0,0 +1,27 @@
+
+.*:     file format .*
+
+Disassembly of section .text:
+
+0+ <_start>:
+ +0:   (48 00 00 15|15 00 00 48)       bl      14 <_start\+0x14>
+ +4:   (48 00 00 21|21 00 00 48)       bl      24 <_start\+0x24>
+ +8:   (48 00 00 0d|0d 00 00 48)       bl      14 <_start\+0x14>
+                       8: R_PPC_NONE   \*ABS\*
+ +c:   (48 00 00 19|19 00 00 48)       bl      24 <_start\+0x24>
+                       c: R_PPC_NONE   \*ABS\*
+ +10:  (48 00 00 00|00 00 00 48)       b       10 <_start\+0x10>
+                       10: R_PPC_REL24 _start
+ +14:  (3d 80 00 00|00 00 80 3d)       lis     r12,0
+                       1(6|4): R_PPC_ADDR16_HA near
+ +18:  (39 8c 00 00|00 00 8c 39)       addi    r12,r12,0
+                       1(a|8): R_PPC_ADDR16_LO near
+ +1c:  (7d 89 03 a6|a6 03 89 7d)       mtctr   r12
+ +20:  (4e 80 04 20|20 04 80 4e)       bctr
+ +24:  (3d 80 00 00|00 00 80 3d)       lis     r12,0
+                       2(6|4): R_PPC_ADDR16_HA far
+ +28:  (39 8c 00 00|00 00 8c 39)       addi    r12,r12,0
+                       2(a|8): R_PPC_ADDR16_LO far
+ +2c:  (7d 89 03 a6|a6 03 89 7d)       mtctr   r12
+ +30:  (4e 80 04 20|20 04 80 4e)       bctr
+       \.\.\.