This is the mail archive of the binutils-cvs@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[binutils-gdb] x86: Cache section contents and relocations


https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=5e5e02aeca4a6edccbf11b5f900d95bba59b9932

commit 5e5e02aeca4a6edccbf11b5f900d95bba59b9932
Author: H.J. Lu <hjl.tools@gmail.com>
Date:   Thu Sep 14 11:41:58 2017 -0700

    x86: Cache section contents and relocations
    
    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.

Diff:
---
 bfd/ChangeLog                     | 10 ++++++++++
 bfd/elf32-i386.c                  | 18 +++++++++++++++---
 bfd/elf64-x86-64.c                | 15 +++++++++++++--
 ld/ChangeLog                      | 10 ++++++++++
 ld/testsuite/ld-i386/i386.exp     |  1 +
 ld/testsuite/ld-i386/pr22135.d    | 12 ++++++++++++
 ld/testsuite/ld-i386/pr22135.s    | 11 +++++++++++
 ld/testsuite/ld-x86-64/pr22135.d  | 12 ++++++++++++
 ld/testsuite/ld-x86-64/pr22135.s  | 11 +++++++++++
 ld/testsuite/ld-x86-64/x86-64.exp |  1 +
 10 files changed, 96 insertions(+), 5 deletions(-)

diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index 3d807b9..e4df74d 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -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
diff --git a/bfd/elf32-i386.c b/bfd/elf32-i386.c
index 4337ab0..d4adaf4 100644
--- a/bfd/elf32-i386.c
+++ b/bfd/elf32-i386.c
@@ -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:
diff --git a/bfd/elf64-x86-64.c b/bfd/elf64-x86-64.c
index 4371a16..84a2603 100644
--- a/bfd/elf64-x86-64.c
+++ b/bfd/elf64-x86-64.c
@@ -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:
diff --git a/ld/ChangeLog b/ld/ChangeLog
index 1d052f7..857f4c9 100644
--- a/ld/ChangeLog
+++ b/ld/ChangeLog
@@ -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.
diff --git a/ld/testsuite/ld-i386/i386.exp b/ld/testsuite/ld-i386/i386.exp
index f691c32..d79c458 100644
--- a/ld/testsuite/ld-i386/i386.exp
+++ b/ld/testsuite/ld-i386/i386.exp
@@ -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
index 0000000..a5796ba
--- /dev/null
+++ b/ld/testsuite/ld-i386/pr22135.d
@@ -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
index 0000000..6afad88
--- /dev/null
+++ b/ld/testsuite/ld-i386/pr22135.s
@@ -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
index 0000000..2cd6861
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/pr22135.d
@@ -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
index 0000000..f4dff5c
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/pr22135.s
@@ -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
diff --git a/ld/testsuite/ld-x86-64/x86-64.exp b/ld/testsuite/ld-x86-64/x86-64.exp
index edf8896..676d44a 100644
--- a/ld/testsuite/ld-x86-64/x86-64.exp
+++ b/ld/testsuite/ld-x86-64/x86-64.exp
@@ -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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]