x86: Cache section contents and relocations
authorH.J. Lu <hjl.tools@gmail.com>
Thu, 14 Sep 2017 18:41:58 +0000 (11:41 -0700)
committerH.J. Lu <hjl.tools@gmail.com>
Thu, 14 Sep 2017 19:29:29 +0000 (12:29 -0700)
bfd/

PR ld/22135
* elf32-i386.c (elf_i386_convert_load_reloc): Add an argument
to indicate if conversion is performed.
(elf_i386_check_relocs): Cache section contents and relocations
if conversion is performed.
* elf64-x86-64.c (elf_x86_64_check_relocs): Cache section
contents and relocations if conversion is performed.

ld/

PR ld/22135
* testsuite/ld-i386/i386.exp: Run pr22135.
* testsuite/ld-x86-64/x86-64.exp: Likewise.
* testsuite/ld-i386/pr22135.d: New file.
* testsuite/ld-i386/pr22135.s: Likewise.
* testsuite/ld-x86-64/pr22135.d: Likewise.
* testsuite/ld-x86-64/pr22135.s: Likewise.

bfd/ChangeLog
bfd/elf32-i386.c
bfd/elf64-x86-64.c
ld/ChangeLog
ld/testsuite/ld-i386/i386.exp
ld/testsuite/ld-i386/pr22135.d [new file with mode: 0644]
ld/testsuite/ld-i386/pr22135.s [new file with mode: 0644]
ld/testsuite/ld-x86-64/pr22135.d [new file with mode: 0644]
ld/testsuite/ld-x86-64/pr22135.s [new file with mode: 0644]
ld/testsuite/ld-x86-64/x86-64.exp

index 3d807b9f6c3913dcac85aa40915c1e3f82123fef..e4df74d3318b5c188d7add71b67fe69c77ce39cf 100644 (file)
@@ -1,3 +1,13 @@
+2017-09-14  H.J. Lu  <hongjiu.lu@intel.com>
+
+       PR ld/22135
+       * elf32-i386.c (elf_i386_convert_load_reloc): Add an argument
+       to indicate if conversion is performed.
+       (elf_i386_check_relocs): Cache section contents and relocations
+       if conversion is performed.
+       * elf64-x86-64.c (elf_x86_64_check_relocs): Cache section
+       contents and relocations if conversion is performed.
+
 2017-09-14  Nick Clifton  <nickc@redhat.com>
 
        PR binutils/22113
index 4337ab0ea0b68d3e60c227cc225b971181730dff..d4adaf48dee83e4ef56d6e457118b42c3d359da0 100644 (file)
@@ -1214,6 +1214,7 @@ elf_i386_convert_load_reloc (bfd *abfd, Elf_Internal_Shdr *symtab_hdr,
                             unsigned int *r_type_p,
                             Elf_Internal_Rela *irel,
                             struct elf_link_hash_entry *h,
+                            bfd_boolean *converted,
                             struct bfd_link_info *link_info)
 {
   struct elf_x86_link_hash_table *htab;
@@ -1369,6 +1370,7 @@ convert_branch:
          bfd_put_32 (abfd, -4, contents + irel->r_offset);
          irel->r_info = ELF32_R_INFO (r_symndx, R_386_PC32);
          *r_type_p = R_386_PC32;
+         *converted = TRUE;
        }
     }
   else
@@ -1441,6 +1443,7 @@ convert_load:
          bfd_put_8 (abfd, opcode, contents + roff - 2);
          irel->r_info = ELF32_R_INFO (r_symndx, r_type);
          *r_type_p = r_type;
+         *converted = TRUE;
        }
     }
 
@@ -1468,6 +1471,7 @@ elf_i386_check_relocs (bfd *abfd,
   const Elf_Internal_Rela *rel_end;
   asection *sreloc;
   bfd_byte *contents;
+  bfd_boolean converted;
 
   if (bfd_link_relocatable (info))
     return TRUE;
@@ -1502,6 +1506,8 @@ elf_i386_check_relocs (bfd *abfd,
   symtab_hdr = &elf_symtab_hdr (abfd);
   sym_hashes = elf_sym_hashes (abfd);
 
+  converted = FALSE;
+
   sreloc = NULL;
 
   rel_end = relocs + sec->reloc_count;
@@ -1582,7 +1588,8 @@ elf_i386_check_relocs (bfd *abfd,
        {
          Elf_Internal_Rela *irel = (Elf_Internal_Rela *) rel;
          if (!elf_i386_convert_load_reloc (abfd, symtab_hdr, contents,
-                                           &r_type, irel, h, info))
+                                           &r_type, irel, h,
+                                           &converted, info))
            goto error_return;
        }
 
@@ -1937,15 +1944,20 @@ do_size:
 
   if (elf_section_data (sec)->this_hdr.contents != contents)
     {
-      if (!info->keep_memory)
+      if (!converted && !info->keep_memory)
        free (contents);
       else
        {
-         /* Cache the section contents for elf_link_input_bfd.  */
+         /* Cache the section contents for elf_link_input_bfd if any
+            load is converted or --no-keep-memory isn't used.  */
          elf_section_data (sec)->this_hdr.contents = contents;
        }
     }
 
+  /* Cache relocations if any load is converted.  */
+  if (elf_section_data (sec)->relocs != relocs && converted)
+    elf_section_data (sec)->relocs = (Elf_Internal_Rela *) relocs;
+
   return TRUE;
 
 error_return:
index 4371a1625c1fdad7391be931c0504f240dc655bd..84a26033245d096be366d68e959dbe37f4e7b181 100644 (file)
@@ -1780,6 +1780,7 @@ elf_x86_64_check_relocs (bfd *abfd, struct bfd_link_info *info,
   const Elf_Internal_Rela *rel_end;
   asection *sreloc;
   bfd_byte *contents;
+  bfd_boolean converted;
 
   if (bfd_link_relocatable (info))
     return TRUE;
@@ -1814,6 +1815,8 @@ elf_x86_64_check_relocs (bfd *abfd, struct bfd_link_info *info,
   symtab_hdr = &elf_symtab_hdr (abfd);
   sym_hashes = elf_sym_hashes (abfd);
 
+  converted = FALSE;
+
   sreloc = NULL;
 
   rel_end = relocs + sec->reloc_count;
@@ -1931,6 +1934,9 @@ elf_x86_64_check_relocs (bfd *abfd, struct bfd_link_info *info,
                                              irel, h, &converted_reloc,
                                              info))
            goto error_return;
+
+         if (converted_reloc)
+           converted = TRUE;
        }
 
       if (! elf_x86_64_tls_transition (info, abfd, sec, contents,
@@ -2306,15 +2312,20 @@ do_size:
 
   if (elf_section_data (sec)->this_hdr.contents != contents)
     {
-      if (!info->keep_memory)
+      if (!converted && !info->keep_memory)
        free (contents);
       else
        {
-         /* Cache the section contents for elf_link_input_bfd.  */
+         /* Cache the section contents for elf_link_input_bfd if any
+            load is converted or --no-keep-memory isn't used.  */
          elf_section_data (sec)->this_hdr.contents = contents;
        }
     }
 
+  /* Cache relocations if any load is converted.  */
+  if (elf_section_data (sec)->relocs != relocs && converted)
+    elf_section_data (sec)->relocs = (Elf_Internal_Rela *) relocs;
+
   return TRUE;
 
 error_return:
index 1d052f79eeb33ea44078b2a13e7aceca92a9ed8d..857f4c9856e06973dd3bc0add8a0e8249855ea70 100644 (file)
@@ -1,3 +1,13 @@
+2017-09-14  H.J. Lu  <hongjiu.lu@intel.com>
+
+       PR ld/22135
+       * testsuite/ld-i386/i386.exp: Run pr22135.
+       * testsuite/ld-x86-64/x86-64.exp: Likewise.
+       * testsuite/ld-i386/pr22135.d: New file.
+       * testsuite/ld-i386/pr22135.s: Likewise.
+       * testsuite/ld-x86-64/pr22135.d: Likewise.
+       * testsuite/ld-x86-64/pr22135.s: Likewise.
+
 2017-09-09  Alan Modra  <amodra@gmail.com>
 
        * ld.texinfo (--plt-align): Describe new behaviour of option.
index f691c32e8d267ea9978eca21375f1b14e9d85f54..d79c4583e6cdca6c30d41396f024c88a3d308ada 100644 (file)
@@ -444,6 +444,7 @@ run_dump_test "pr22115-1a"
 run_dump_test "pr22115-1b"
 run_dump_test "pr22115-1c"
 run_dump_test "pr22115-1d"
+run_dump_test "pr22135"
 
 if { !([istarget "i?86-*-linux*"]
        || [istarget "i?86-*-gnu*"]
diff --git a/ld/testsuite/ld-i386/pr22135.d b/ld/testsuite/ld-i386/pr22135.d
new file mode 100644 (file)
index 0000000..a5796ba
--- /dev/null
@@ -0,0 +1,12 @@
+#as: --32 -mrelax-relocations=yes
+#ld: -pie -melf_i386 --no-keep-memory
+#objdump: -dw
+
+.*: +file format .*
+
+
+Disassembly of section .text:
+
+#...
+[      ]*[a-f0-9]+:    8d 81 ([0-9a-f]{2} ){4} *       lea    -0x[a-f0-9]+\(%ecx\),%eax
+#pass
diff --git a/ld/testsuite/ld-i386/pr22135.s b/ld/testsuite/ld-i386/pr22135.s
new file mode 100644 (file)
index 0000000..6afad88
--- /dev/null
@@ -0,0 +1,11 @@
+       .text
+       .globl  foo
+       .type   foo, @function
+foo:
+       ret
+       .size   foo, .-foo
+       .globl  _start
+       .type   _start, @function
+_start:
+       movl    foo@GOT(%ecx), %eax
+       .size   _start, .-_start
diff --git a/ld/testsuite/ld-x86-64/pr22135.d b/ld/testsuite/ld-x86-64/pr22135.d
new file mode 100644 (file)
index 0000000..2cd6861
--- /dev/null
@@ -0,0 +1,12 @@
+#as: --64
+#ld: -pie -melf_x86_64 --no-keep-memory
+#objdump: -dw
+
+.*: +file format .*
+
+
+Disassembly of section .text:
+
+#...
+[      ]*[a-f0-9]+:    8d 05 ([0-9a-f]{2} ){4} *       lea    -0x[a-f0-9]+\(%rip\),%eax        # [a-f0-9]+ <foo>
+#pass
diff --git a/ld/testsuite/ld-x86-64/pr22135.s b/ld/testsuite/ld-x86-64/pr22135.s
new file mode 100644 (file)
index 0000000..f4dff5c
--- /dev/null
@@ -0,0 +1,11 @@
+       .text
+       .globl  foo
+       .type   foo, @function
+foo:
+       ret
+       .size   foo, .-foo
+       .globl  _start
+       .type   _start, @function
+_start:
+       movl    foo@GOTPCREL(%rip), %eax
+       .size   _start, .-_start
index edf88969f1b8058472f2724557a86a3c39476e8a..676d44a3d0f6c7cc764079549e3b63005c606d8a 100644 (file)
@@ -377,6 +377,7 @@ run_dump_test "pr22115-1c"
 run_dump_test "pr22115-1c-x32"
 run_dump_test "pr22115-1d"
 run_dump_test "pr22115-1d-x32"
+run_dump_test "pr22135"
 
 if { ![istarget "x86_64-*-linux*"] && ![istarget "x86_64-*-nacl*"]} {
     return