This is the mail archive of the binutils@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]

PATCH: PR ld/14956: Unnecessary R_X86_64_NONE


Hi,

I checked in this patch to check local IFUNC calls so that we can
avoid unnecessary R_*_NONE relocations.


H.J.
----
diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index 5c4ace1..1ff8574 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,3 +1,10 @@
+2012-12-13  H.J. Lu  <hongjiu.lu@intel.com>
+
+	PR ld/14956
+	* elf32-i386.c (elf_i386_adjust_dynamic_symbol): Check local
+	IFUNC calls.
+	* elf64-x86-64.c (elf_x86_64_adjust_dynamic_symbol): Likewise.
+
 2012-12-10  Edgar E. Iglesias <edgar.iglesias@gmail.com>
 
 	* reloc.c (MICROBLAZE): Document new relocations
diff --git a/bfd/elf32-i386.c b/bfd/elf32-i386.c
index 1b04a6e..bb41302 100644
--- a/bfd/elf32-i386.c
+++ b/bfd/elf32-i386.c
@@ -2066,10 +2066,39 @@ elf_i386_adjust_dynamic_symbol (struct bfd_link_info *info,
 {
   struct elf_i386_link_hash_table *htab;
   asection *s;
+  struct elf_i386_link_hash_entry *eh;
+  struct elf_dyn_relocs *p;
 
   /* STT_GNU_IFUNC symbol must go through PLT. */
   if (h->type == STT_GNU_IFUNC)
     {
+      /* Check local STT_GNU_IFUNC calls.  */
+      if (h->ref_regular
+	  && SYMBOL_CALLS_LOCAL (info, h))
+	{
+	  bfd_size_type pc_count = 0;
+	  struct elf_dyn_relocs **pp;
+
+	  eh = (struct elf_i386_link_hash_entry *) h;
+	  for (pp = &eh->dyn_relocs; (p = *pp) != NULL; )
+	    {
+	      pc_count += p->pc_count;
+	      p->count -= p->pc_count;
+	      p->pc_count = 0;
+	      if (p->count == 0)
+		*pp = p->next;
+	      else
+		pp = &p->next;
+	    }
+
+	  if (pc_count)
+	    {
+	      h->needs_plt = 1;
+	      h->plt.refcount += 1;
+	      h->non_got_ref = 1;
+	    }
+	}
+
       if (h->plt.refcount <= 0)
 	{
 	  h->plt.offset = (bfd_vma) -1;
@@ -2155,9 +2184,6 @@ elf_i386_adjust_dynamic_symbol (struct bfd_link_info *info,
   if (ELIMINATE_COPY_RELOCS
       && !get_elf_i386_backend_data (info->output_bfd)->is_vxworks)
     {
-      struct elf_i386_link_hash_entry * eh;
-      struct elf_dyn_relocs *p;
-
       eh = (struct elf_i386_link_hash_entry *) h;
       for (p = eh->dyn_relocs; p != NULL; p = p->next)
 	{
diff --git a/bfd/elf64-x86-64.c b/bfd/elf64-x86-64.c
index d58384f..ec38ddc 100644
--- a/bfd/elf64-x86-64.c
+++ b/bfd/elf64-x86-64.c
@@ -2134,10 +2134,39 @@ elf_x86_64_adjust_dynamic_symbol (struct bfd_link_info *info,
 {
   struct elf_x86_64_link_hash_table *htab;
   asection *s;
+  struct elf_x86_64_link_hash_entry *eh;
+  struct elf_dyn_relocs *p;
 
   /* STT_GNU_IFUNC symbol must go through PLT. */
   if (h->type == STT_GNU_IFUNC)
     {
+      /* Check local STT_GNU_IFUNC calls.  */
+      if (h->ref_regular
+	  && SYMBOL_CALLS_LOCAL (info, h))
+	{
+	  bfd_size_type pc_count = 0;
+	  struct elf_dyn_relocs **pp;
+
+	  eh = (struct elf_x86_64_link_hash_entry *) h;
+	  for (pp = &eh->dyn_relocs; (p = *pp) != NULL; )
+	    {
+	      pc_count += p->pc_count;
+	      p->count -= p->pc_count;
+	      p->pc_count = 0;
+	      if (p->count == 0)
+		*pp = p->next;
+	      else
+		pp = &p->next;
+	    }
+
+	  if (pc_count)
+	    {
+	      h->needs_plt = 1;
+	      h->plt.refcount += 1;
+	      h->non_got_ref = 1;
+	    }
+	}
+
       if (h->plt.refcount <= 0)
 	{
 	  h->plt.offset = (bfd_vma) -1;
@@ -2214,9 +2243,6 @@ elf_x86_64_adjust_dynamic_symbol (struct bfd_link_info *info,
 
   if (ELIMINATE_COPY_RELOCS)
     {
-      struct elf_x86_64_link_hash_entry * eh;
-      struct elf_dyn_relocs *p;
-
       eh = (struct elf_x86_64_link_hash_entry *) h;
       for (p = eh->dyn_relocs; p != NULL; p = p->next)
 	{
diff --git a/ld/testsuite/ChangeLog b/ld/testsuite/ChangeLog
index b534021..994ee04 100644
--- a/ld/testsuite/ChangeLog
+++ b/ld/testsuite/ChangeLog
@@ -1,3 +1,19 @@
+2012-12-13  H.J. Lu  <hongjiu.lu@intel.com>
+
+	PR ld/14956
+	* ld-ifunc/ifunc-14-i386.d: Renamed to ...
+	* ld-ifunc/ifunc-14a-i386.d: This.
+
+	* ld-ifunc/ifunc-14-x86-64.d: Renamed to ...
+	* ld-ifunc/ifunc-14a-x86-64.d: This.
+
+	* ld-ifunc/ifunc-14b-i386.d: New file.
+	* ld-ifunc/ifunc-14b-x86-64.d: Likewise.
+	* ld-ifunc/ifunc-14c-i386.d: Likewise.
+	* ld-ifunc/ifunc-14c-x86-64.d: Likewise.
+	* ld-ifunc/ifunc-14d-i386.d: Likewise.
+	* ld-ifunc/ifunc-14d-x86-64.d: Likewise.
+
 2012-12-07  H.J. Lu  <hongjiu.lu@intel.com>
 
 	* ld-elf/pr14926.d: Use "readelf -S --wide".
diff --git a/ld/testsuite/ld-ifunc/ifunc-14-i386.d b/ld/testsuite/ld-ifunc/ifunc-14-i386.d
deleted file mode 100644
index 0edc9fb..0000000
--- a/ld/testsuite/ld-ifunc/ifunc-14-i386.d
+++ /dev/null
@@ -1,11 +0,0 @@
-#source: ifunc-14a.s
-#source: ifunc-14b.s
-#ld: -shared -m elf_i386 -z nocombreloc
-#as: --32
-#readelf: -d --wide
-#target: x86_64-*-* i?86-*-*
-
-#failif
-#...
-.*\(TEXTREL\).*
-#...
diff --git a/ld/testsuite/ld-ifunc/ifunc-14-x86-64.d b/ld/testsuite/ld-ifunc/ifunc-14-x86-64.d
deleted file mode 100644
index 2c4ebbb..0000000
--- a/ld/testsuite/ld-ifunc/ifunc-14-x86-64.d
+++ /dev/null
@@ -1,11 +0,0 @@
-#source: ifunc-14a.s
-#source: ifunc-14b.s
-#ld: -shared -m elf_x86_64 -z nocombreloc
-#as: --64
-#readelf: -d
-#target: x86_64-*-*
-
-#failif
-#...
-.*\(TEXTREL\).*
-#...
diff --git a/ld/testsuite/ld-ifunc/ifunc-14a-i386.d b/ld/testsuite/ld-ifunc/ifunc-14a-i386.d
new file mode 100644
index 0000000..0edc9fb
--- /dev/null
+++ b/ld/testsuite/ld-ifunc/ifunc-14a-i386.d
@@ -0,0 +1,11 @@
+#source: ifunc-14a.s
+#source: ifunc-14b.s
+#ld: -shared -m elf_i386 -z nocombreloc
+#as: --32
+#readelf: -d --wide
+#target: x86_64-*-* i?86-*-*
+
+#failif
+#...
+.*\(TEXTREL\).*
+#...
diff --git a/ld/testsuite/ld-ifunc/ifunc-14a-x86-64.d b/ld/testsuite/ld-ifunc/ifunc-14a-x86-64.d
new file mode 100644
index 0000000..2c4ebbb
--- /dev/null
+++ b/ld/testsuite/ld-ifunc/ifunc-14a-x86-64.d
@@ -0,0 +1,11 @@
+#source: ifunc-14a.s
+#source: ifunc-14b.s
+#ld: -shared -m elf_x86_64 -z nocombreloc
+#as: --64
+#readelf: -d
+#target: x86_64-*-*
+
+#failif
+#...
+.*\(TEXTREL\).*
+#...
diff --git a/ld/testsuite/ld-ifunc/ifunc-14b-i386.d b/ld/testsuite/ld-ifunc/ifunc-14b-i386.d
new file mode 100644
index 0000000..948237d
--- /dev/null
+++ b/ld/testsuite/ld-ifunc/ifunc-14b-i386.d
@@ -0,0 +1,11 @@
+#source: ifunc-14b.s
+#source: ifunc-14a.s
+#ld: -shared -m elf_i386 -z nocombreloc
+#as: --32
+#readelf: -d --wide
+#target: x86_64-*-* i?86-*-*
+
+#failif
+#...
+.*\(TEXTREL\).*
+#...
diff --git a/ld/testsuite/ld-ifunc/ifunc-14b-x86-64.d b/ld/testsuite/ld-ifunc/ifunc-14b-x86-64.d
new file mode 100644
index 0000000..cc1f5ae
--- /dev/null
+++ b/ld/testsuite/ld-ifunc/ifunc-14b-x86-64.d
@@ -0,0 +1,11 @@
+#source: ifunc-14b.s
+#source: ifunc-14a.s
+#ld: -shared -m elf_x86_64 -z nocombreloc
+#as: --64
+#readelf: -d
+#target: x86_64-*-*
+
+#failif
+#...
+.*\(TEXTREL\).*
+#...
diff --git a/ld/testsuite/ld-ifunc/ifunc-14c-i386.d b/ld/testsuite/ld-ifunc/ifunc-14c-i386.d
new file mode 100644
index 0000000..ca360a3
--- /dev/null
+++ b/ld/testsuite/ld-ifunc/ifunc-14c-i386.d
@@ -0,0 +1,11 @@
+#source: ifunc-14a.s
+#source: ifunc-14b.s
+#ld: -shared -m elf_i386 -z nocombreloc
+#as: --32
+#readelf: -r --wide
+#target: x86_64-*-* i?86-*-*
+
+#failif
+#...
+.* +R_386_NONE +.*
+#...
diff --git a/ld/testsuite/ld-ifunc/ifunc-14c-x86-64.d b/ld/testsuite/ld-ifunc/ifunc-14c-x86-64.d
new file mode 100644
index 0000000..76bfa84
--- /dev/null
+++ b/ld/testsuite/ld-ifunc/ifunc-14c-x86-64.d
@@ -0,0 +1,11 @@
+#source: ifunc-14a.s
+#source: ifunc-14b.s
+#ld: -shared -m elf_x86_64 -z nocombreloc
+#as: --64
+#readelf: -r --wide
+#target: x86_64-*-*
+
+#failif
+#...
+.* +R_X86_64_NONE +.*
+#...
diff --git a/ld/testsuite/ld-ifunc/ifunc-14d-i386.d b/ld/testsuite/ld-ifunc/ifunc-14d-i386.d
new file mode 100644
index 0000000..2327278
--- /dev/null
+++ b/ld/testsuite/ld-ifunc/ifunc-14d-i386.d
@@ -0,0 +1,11 @@
+#source: ifunc-14b.s
+#source: ifunc-14a.s
+#ld: -shared -m elf_i386 -z nocombreloc
+#as: --32
+#readelf: -r --wide
+#target: x86_64-*-* i?86-*-*
+
+#failif
+#...
+.* +R_386_NONE +.*
+#...
diff --git a/ld/testsuite/ld-ifunc/ifunc-14d-x86-64.d b/ld/testsuite/ld-ifunc/ifunc-14d-x86-64.d
new file mode 100644
index 0000000..789584b
--- /dev/null
+++ b/ld/testsuite/ld-ifunc/ifunc-14d-x86-64.d
@@ -0,0 +1,11 @@
+#source: ifunc-14b.s
+#source: ifunc-14a.s
+#ld: -shared -m elf_x86_64 -z nocombreloc
+#as: --64
+#readelf: -r --wide
+#target: x86_64-*-*
+
+#failif
+#...
+.* +R_X86_64_NONE +.*
+#...


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