binutils-gdb/ld/testsuite/ld-ifunc
H.J. Lu 1622ff3b43 Check regular reference without non-GOT reference
non_got_ref may not be set when building shared library. We need to set
non_got_ref if there are any non-PIC relocations.  But we only did this
when there were no PLT/GOT relocations.  It failed when there is a PLT
relocation.  This checkin moves the non_got_ref check out.

bfd/

2013-04-15  H.J. Lu  <hongjiu.lu@intel.com>

	PR ld/15371
	* elf-ifunc.c (_bfd_elf_allocate_ifunc_dyn_relocs): Check
	regular reference without non-GOT reference when building
	shared library.

ld/testsuite/

2013-04-15  H.J. Lu  <hongjiu.lu@intel.com>

	PR ld/15371
	* ld-ifunc/ifunc-20-i386.d: New file.
	* ld-ifunc/ifunc-20-x86-64.d: Likewise.
	* ld-ifunc/ifunc-20.s: Likewise.
diff --git a/bfd/elf-ifunc.c b/bfd/elf-ifunc.c
index e56427d..7e7ec36 100644
--- a/bfd/elf-ifunc.c
+++ b/bfd/elf-ifunc.c
@@ -187,23 +187,20 @@ _bfd_elf_allocate_ifunc_dyn_relocs (struct bfd_link_info *info,

   htab = elf_hash_table (info);

+  /* When building shared library, we need to handle the case where it is
+     marked with regular reference, but not non-GOT reference since the
+     non-GOT reference bit may not be set here.  */
+  if (info->shared && !h->non_got_ref && h->ref_regular)
+    for (p = *head; p != NULL; p = p->next)
+      if (p->count)
+	{
+	  h->non_got_ref = 1;
+	  goto keep;
+	}
+
   /* Support garbage collection against STT_GNU_IFUNC symbols.  */
   if (h->plt.refcount <= 0 && h->got.refcount <= 0)
     {
-      /* When building shared library, we need to handle the case
-         where it is marked with regular reference, but not non-GOT
-	 reference.  It may happen if we didn't see STT_GNU_IFUNC
-	 symbol at the time when checking relocations.  */
-      if (info->shared
-	  && !h->non_got_ref
-	  && h->ref_regular)
-	for (p = *head; p != NULL; p = p->next)
-	  if (p->count)
-	    {
-	      h->non_got_ref = 1;
-	      goto keep;
-	    }
-
       h->got = htab->init_got_offset;
       h->plt = htab->init_plt_offset;
       *head = NULL;
diff --git a/ld/testsuite/ld-ifunc/ifunc-20-i386.d b/ld/testsuite/ld-ifunc/ifunc-20-i386.d
new file mode 100644
index 0000000..9373fcf
--- /dev/null
+++ b/ld/testsuite/ld-ifunc/ifunc-20-i386.d
@@ -0,0 +1,13 @@
+#source: ifunc-20.s
+#ld: -shared -m elf_i386 -z nocombreloc
+#as: --32
+#readelf: -r --wide
+#target: x86_64-*-* i?86-*-*
+
+Relocation section '.rel.ifunc' at offset 0x[0-9a-f]+ contains 1 entries:
+[ ]+Offset[ ]+Info[ ]+Type[ ]+.*
+[0-9a-f]+[ ]+[0-9a-f]+[ ]+R_386_32[ ]+ifunc\(\)[ ]+ifunc
+
+Relocation section '.rel.plt' at offset 0x[0-9a-f]+ contains 1 entries:
+[ ]+Offset[ ]+Info[ ]+Type[ ]+.*
+[0-9a-f]+[ ]+[0-9a-f]+[ ]+R_386_JUMP_SLOT[ ]+ifunc\(\)[ ]+ifunc
diff --git a/ld/testsuite/ld-ifunc/ifunc-20-x86-64.d b/ld/testsuite/ld-ifunc/ifunc-20-x86-64.d
new file mode 100644
index 0000000..39492d4
--- /dev/null
+++ b/ld/testsuite/ld-ifunc/ifunc-20-x86-64.d
@@ -0,0 +1,13 @@
+#source: ifunc-20.s
+#ld: -shared -m elf_x86_64 -z nocombreloc
+#as: --64
+#readelf: -r --wide
+#target: x86_64-*-*
+
+Relocation section '.rela.ifunc' at offset 0x[0-9a-f]+ contains 1 entries:
+[ ]+Offset[ ]+Info[ ]+Type[ ]+.*
+[0-9a-f]+[ ]+[0-9a-f]+[ ]+R_X86_64_64[ ]+ifunc\(\)[ ]+ifunc \+ 0
+
+Relocation section '.rela.plt' at offset 0x[0-9a-f]+ contains 1 entries:
+[ ]+Offset[ ]+Info[ ]+Type[ ]+.*
+[0-9a-f]+[ ]+[0-9a-f]+[ ]+R_X86_64_JUMP_SLOT[ ]+ifunc\(\)[ ]+ifunc \+ 0
diff --git a/ld/testsuite/ld-ifunc/ifunc-20.s b/ld/testsuite/ld-ifunc/ifunc-20.s
new file mode 100644
index 0000000..9d45455
--- /dev/null
+++ b/ld/testsuite/ld-ifunc/ifunc-20.s
@@ -0,0 +1,16 @@
+	.section .data.rel,"aw",@progbits
+	.globl ifunc_ptrt
+	.type	ifunc_ptr, @object
+ifunc_ptr:
+	.dc.a ifunc
+	.text
+	.type ifunc, @gnu_indirect_function
+	.globl ifunc
+ifunc:
+	ret
+	.size	ifunc, .-ifunc
+	.type bar, @function
+	.globl bar
+bar:
+	call	ifunc@PLT
+	.size	bar, .-bar
2013-04-15 21:16:18 +00:00
..
binutils.exp bfd/ 2012-04-03 16:01:38 +00:00
ifunc-1-local-x86.d Adjust x86 IFUNC PLT. 2011-06-20 17:12:49 +00:00
ifunc-1-local-x86.s
ifunc-1-x86.d Adjust x86 IFUNC PLT. 2011-06-20 17:12:49 +00:00
ifunc-1-x86.s
ifunc-2-i386.d
ifunc-2-i386.s
ifunc-2-local-i386.d
ifunc-2-local-i386.s
ifunc-2-local-x86-64.d
ifunc-2-local-x86-64.s
ifunc-2-x86-64.d
ifunc-2-x86-64.s
ifunc-3-x86.s
ifunc-3a-x86.d Support x86_64-*-linux-gnux32 2012-05-04 20:01:03 +00:00
ifunc-3b-x86.d
ifunc-4-local-x86.d
ifunc-4-local-x86.s
ifunc-4-x86.d
ifunc-4-x86.s
ifunc-4a-x86.d
ifunc-5-i386.s
ifunc-5-local-i386.s
ifunc-5-local-x86-64.s
ifunc-5-x86-64.s
ifunc-5a-i386.d
ifunc-5a-local-i386.d
ifunc-5a-local-x86-64.d
ifunc-5a-x86-64.d
ifunc-5b-i386.d
ifunc-5b-local-i386.d
ifunc-5b-local-x86-64.d
ifunc-5b-x86-64.d
ifunc-5r-local-i386.d
ifunc-5r-local-x86-64.d
ifunc-6-i386.s
ifunc-6-x86-64.s
ifunc-6a-i386.d
ifunc-6a-x86-64.d
ifunc-6b-i386.d
ifunc-6b-x86-64.d
ifunc-7-i386.s
ifunc-7-x86-64.s
ifunc-7a-i386.d
ifunc-7a-x86-64.d
ifunc-7b-i386.d
ifunc-7b-x86-64.d
ifunc-8-i386.d
ifunc-8-x86-64.d
ifunc-8a-i386.s
ifunc-8a-x86-64.s
ifunc-8b-i386.s
ifunc-8b-x86-64.s
ifunc-9-x86.d
ifunc-9-x86.s
ifunc-10-i386.d
ifunc-10-i386.s
ifunc-10-x86-64.d
ifunc-10-x86-64.s
ifunc-11-i386.d
ifunc-11-i386.s
ifunc-11-x86-64.d
ifunc-11-x86-64.s
ifunc-12-i386.d
ifunc-12-i386.s
ifunc-12-x86-64.d
ifunc-12-x86-64.s
ifunc-13-i386.d Convert mov to lea in size_dynamic_sections 2012-08-31 20:41:41 +00:00
ifunc-13-x86-64.d Use .got.plt for IFUNC symbols if there are no GOT relocations. 2011-09-12 18:17:36 +00:00
ifunc-13a-i386.s * read.c (read_symbol_name): New function. Reads a symbol names. 2012-05-28 14:20:19 +00:00
ifunc-13a-x86-64.s Add missing "foo" after ".global" 2012-05-31 17:16:54 +00:00
ifunc-13b-i386.s
ifunc-13b-x86-64.s
ifunc-14a-i386.d Check local IFUNC calls 2012-12-13 21:07:16 +00:00
ifunc-14a-x86-64.d Check local IFUNC calls 2012-12-13 21:07:16 +00:00
ifunc-14a.s
ifunc-14b-i386.d Check local IFUNC calls 2012-12-13 21:07:16 +00:00
ifunc-14b-x86-64.d Check local IFUNC calls 2012-12-13 21:07:16 +00:00
ifunc-14b.s
ifunc-14c-i386.d Check local IFUNC calls 2012-12-13 21:07:16 +00:00
ifunc-14c-x86-64.d Check local IFUNC calls 2012-12-13 21:07:16 +00:00
ifunc-14c.s Properly adjust h->plt.refcount 2012-12-21 18:15:22 +00:00
ifunc-14d-i386.d Check local IFUNC calls 2012-12-13 21:07:16 +00:00
ifunc-14d-x86-64.d Check local IFUNC calls 2012-12-13 21:07:16 +00:00
ifunc-14e-i386.d Properly adjust h->plt.refcount 2012-12-21 18:15:22 +00:00
ifunc-14e-x86-64.d Properly adjust h->plt.refcount 2012-12-21 18:15:22 +00:00
ifunc-14f-i386.d Properly adjust h->plt.refcount 2012-12-21 18:15:22 +00:00
ifunc-14f-x86-64.d Properly adjust h->plt.refcount 2012-12-21 18:15:22 +00:00
ifunc-15-i386.d Use .got.plt for IFUNC symbols if there are no GOT relocations. 2011-09-12 18:17:36 +00:00
ifunc-15-i386.s * read.c (read_symbol_name): New function. Reads a symbol names. 2012-05-28 14:20:19 +00:00
ifunc-15-x86-64.d Use .got.plt for IFUNC symbols if there are no GOT relocations. 2011-09-12 18:17:36 +00:00
ifunc-15-x86-64.s Add missing "foo" after ".global" 2012-05-31 17:16:54 +00:00
ifunc-16-i386.d Put IRELATIVE relocations after JUMP_SLOT. 2011-10-21 15:13:37 +00:00
ifunc-16-x86-64.d Put IRELATIVE relocations after JUMP_SLOT. 2011-10-21 15:13:37 +00:00
ifunc-16-x86.s Put IRELATIVE relocations after JUMP_SLOT. 2011-10-21 15:13:37 +00:00
ifunc-17a-i386.d Properly handle common symbol and weak function 2012-09-19 00:53:30 +00:00
ifunc-17a-x86-64.d Properly handle common symbol and weak function 2012-09-19 00:53:30 +00:00
ifunc-17a.s Properly handle common symbol and weak function 2012-09-19 00:53:30 +00:00
ifunc-17b-i386.d Properly handle common symbol and weak function 2012-09-19 00:53:30 +00:00
ifunc-17b-x86-64.d Properly handle common symbol and weak function 2012-09-19 00:53:30 +00:00
ifunc-17b.s Properly handle common symbol and weak function 2012-09-19 00:53:30 +00:00
ifunc-18a-i386.d Also check local IFUNC references 2012-12-16 20:31:08 +00:00
ifunc-18a-x86-64.d Also check local IFUNC references 2012-12-16 20:31:08 +00:00
ifunc-18a.s Also check local IFUNC references 2012-12-16 20:31:08 +00:00
ifunc-18b-i386.d Also check local IFUNC references 2012-12-16 20:31:08 +00:00
ifunc-18b-x86-64.d Also check local IFUNC references 2012-12-16 20:31:08 +00:00
ifunc-18b.s Also check local IFUNC references 2012-12-16 20:31:08 +00:00
ifunc-19a-i386.d Also check local IFUNC references 2012-12-16 20:31:08 +00:00
ifunc-19a-x86-64.d Also check local IFUNC references 2012-12-16 20:31:08 +00:00
ifunc-19a.s Also check local IFUNC references 2012-12-16 20:31:08 +00:00
ifunc-19b-i386.d Also check local IFUNC references 2012-12-16 20:31:08 +00:00
ifunc-19b-x86-64.d Also check local IFUNC references 2012-12-16 20:31:08 +00:00
ifunc-19b.s Also check local IFUNC references 2012-12-16 20:31:08 +00:00
ifunc-20-i386.d Check regular reference without non-GOT reference 2013-04-15 21:16:18 +00:00
ifunc-20-x86-64.d Check regular reference without non-GOT reference 2013-04-15 21:16:18 +00:00
ifunc-20.s Check regular reference without non-GOT reference 2013-04-15 21:16:18 +00:00
ifunc-common-1.out Properly handle common symbol and weak function 2012-09-19 00:53:30 +00:00
ifunc-common-1a.c Properly handle common symbol and weak function 2012-09-19 00:53:30 +00:00
ifunc-common-1b.c Properly handle common symbol and weak function 2012-09-19 00:53:30 +00:00
ifunc.exp Properly handle common symbol and weak function 2012-09-19 00:53:30 +00:00
lib.c bfd/ 2009-06-01 13:11:52 +00:00
prog.c
test-1.c
test-2.c