aboutsummaryrefslogtreecommitdiff
path: root/ld
diff options
context:
space:
mode:
authorH.J. Lu <hjl.tools@gmail.com>2009-06-01 13:11:52 +0000
committerH.J. Lu <hjl.tools@gmail.com>2009-06-01 13:11:52 +0000
commitcbe950e9fe8a56f788bcf985cc51733f18abb45b (patch)
treede47fda9cf9ccd6a3aed05d68e65ca79fd754505 /ld
parent3aa14d16c669ca75f9fa4e995a2e2d13069dff3f (diff)
downloadgdb-cbe950e9fe8a56f788bcf985cc51733f18abb45b.zip
gdb-cbe950e9fe8a56f788bcf985cc51733f18abb45b.tar.gz
gdb-cbe950e9fe8a56f788bcf985cc51733f18abb45b.tar.bz2
bfd/
2009-06-01 H.J. Lu <hongjiu.lu@intel.com> PR ld/10205 * elf32-i386.c (elf_howto_table): Add R_386_IRELATIVE. (elf_i386_reloc_type_lookup): Likewise. (R_386_tls): Removed. (R_386_irelative): New. (R_386_vt_offset): Updated. (elf_i386_rtype_to_howto): Likewise. (elf_i386_link_hash_table): Add igotplt, iplt and irelplt. (elf_i386_link_hash_table_create): Initialize igotplt, iplt and irelplt. (elf_i386_check_relocs): Handle STT_GNU_IFUNC symbol first. (elf_i386_adjust_dynamic_symbol): Likewise. (elf_i386_allocate_dynrelocs): Likewise. (elf_i386_relocate_section): Likewise. (elf_i386_size_dynamic_sections): Set up .iplt and .igot.plt sections. (elf_i386_finish_dynamic_symbol): When building a static executable, use .iplt, .igot.plt and .rel.iplt sections for STT_GNU_IFUNC symbols. Generate R_386_IRELATIVE relocation for locally defined STT_GNU_IFUNC symbol. * elf64-x86-64.c (x86_64_elf_howto): Add R_X86_64_IRELATIVE. (x86_64_reloc_map): Likewise. (R_X86_64_standard): Updated. (elf64_x86_64_link_hash_table): Add igotplt, iplt and irelplt. (elf64_x86_64_link_hash_table_create): Initialize igotplt, iplt and irelplt. (elf64_x86_64_check_relocs): Handle STT_GNU_IFUNC symbol first. (elf64_x86_64_adjust_dynamic_symbol): Likewise. (elf64_x86_64_allocate_dynrelocs): Likewise. (elf64_x86_64_relocate_section): Likewise. (elf64_x86_64_size_dynamic_sections): Set up .iplt and .igot.plt sections. (elf64_x86_64_finish_dynamic_symbol): When building a static executable, use .iplt, .igot.plt and .rela.iplt sections for STT_GNU_IFUNC symbols. Generate R_X86_64_IRELATIVE relocation for locally defined STT_GNU_IFUNC symbol. * reloc.c (BFD_RELOC_386_IRELATIVE): New. (BFD_RELOC_X86_64_IRELATIVE): Likewise. * bfd-in2.h: Regenerated. * libbfd.h: Likewise. include/elf/ 2009-06-01 H.J. Lu <hongjiu.lu@intel.com> PR ld/10205 * i386.h (R_386_IRELATIVE): New. * x86-64.h (R_X86_64_IRELATIVE): Likewise. ld/testsuite/ 2009-06-01 H.J. Lu <hongjiu.lu@intel.com> PR ld/10205 * ld-ifunc/ifunc.exp (contains_irelative_reloc): New. Use it on executable and shared library. Run *.d. * ld-ifunc/lib.c: Add a hidden alias, __GI_library_func2, for library_func2. (library_func): New. * ld-ifunc/ifunc-1-x86.d: New. * ld-ifunc/ifunc-1-x86.s: Likewise. * ld-ifunc/ifunc-2-i386.d: Likewise. * ld-ifunc/ifunc-2-i386.s: Likewise. * ld-ifunc/ifunc-2-x86-64.d: Likewise. * ld-ifunc/ifunc-2-x86-64.s: Likewise. * ld-ifunc/ifunc-3a-x86.d: Likewise. * ld-ifunc/ifunc-3b-x86.d: Likewise. * ld-ifunc/ifunc-3-x86.s: Likewise. * ld-ifunc/ifunc-4-x86.d: Likewise. * ld-ifunc/ifunc-4-x86.s: Likewise. * ld-ifunc/ifunc-5-i386.d: Likewise. * ld-ifunc/ifunc-5-i386.s: Likewise. * ld-ifunc/ifunc-5-x86-64.d: Likewise. * ld-ifunc/ifunc-5-x86-64.s: Likewise.
Diffstat (limited to 'ld')
-rw-r--r--ld/testsuite/ChangeLog27
-rw-r--r--ld/testsuite/ld-ifunc/ifunc-1-x86.d7
-rw-r--r--ld/testsuite/ld-ifunc/ifunc-1-x86.s16
-rw-r--r--ld/testsuite/ld-ifunc/ifunc-2-i386.d8
-rw-r--r--ld/testsuite/ld-ifunc/ifunc-2-i386.s21
-rw-r--r--ld/testsuite/ld-ifunc/ifunc-2-x86-64.d8
-rw-r--r--ld/testsuite/ld-ifunc/ifunc-2-x86-64.s17
-rw-r--r--ld/testsuite/ld-ifunc/ifunc-3-x86.s16
-rw-r--r--ld/testsuite/ld-ifunc/ifunc-3a-x86.d8
-rw-r--r--ld/testsuite/ld-ifunc/ifunc-3b-x86.d8
-rw-r--r--ld/testsuite/ld-ifunc/ifunc-4-x86.d7
-rw-r--r--ld/testsuite/ld-ifunc/ifunc-4-x86.s19
-rw-r--r--ld/testsuite/ld-ifunc/ifunc-5-i386.d8
-rw-r--r--ld/testsuite/ld-ifunc/ifunc-5-i386.s23
-rw-r--r--ld/testsuite/ld-ifunc/ifunc-5-x86-64.d7
-rw-r--r--ld/testsuite/ld-ifunc/ifunc-5-x86-64.s19
-rw-r--r--ld/testsuite/ld-ifunc/ifunc.exp69
-rw-r--r--ld/testsuite/ld-ifunc/lib.c13
18 files changed, 291 insertions, 10 deletions
diff --git a/ld/testsuite/ChangeLog b/ld/testsuite/ChangeLog
index e6a02b0..03fb645 100644
--- a/ld/testsuite/ChangeLog
+++ b/ld/testsuite/ChangeLog
@@ -1,3 +1,30 @@
+2009-06-01 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR ld/10205
+ * ld-ifunc/ifunc.exp (contains_irelative_reloc): New.
+ Use it on executable and shared library.
+ Run *.d.
+
+ * ld-ifunc/lib.c: Add a hidden alias, __GI_library_func2, for
+ library_func2.
+ (library_func): New.
+
+ * ld-ifunc/ifunc-1-x86.d: New.
+ * ld-ifunc/ifunc-1-x86.s: Likewise.
+ * ld-ifunc/ifunc-2-i386.d: Likewise.
+ * ld-ifunc/ifunc-2-i386.s: Likewise.
+ * ld-ifunc/ifunc-2-x86-64.d: Likewise.
+ * ld-ifunc/ifunc-2-x86-64.s: Likewise.
+ * ld-ifunc/ifunc-3a-x86.d: Likewise.
+ * ld-ifunc/ifunc-3b-x86.d: Likewise.
+ * ld-ifunc/ifunc-3-x86.s: Likewise.
+ * ld-ifunc/ifunc-4-x86.d: Likewise.
+ * ld-ifunc/ifunc-4-x86.s: Likewise.
+ * ld-ifunc/ifunc-5-i386.d: Likewise.
+ * ld-ifunc/ifunc-5-i386.s: Likewise.
+ * ld-ifunc/ifunc-5-x86-64.d: Likewise.
+ * ld-ifunc/ifunc-5-x86-64.s: Likewise.
+
2009-05-27 Dave Korn <dave.korn.cygwin@gmail.com>
* ld-pe/non-c-lang-syms.c: New dump test source file.
diff --git a/ld/testsuite/ld-ifunc/ifunc-1-x86.d b/ld/testsuite/ld-ifunc/ifunc-1-x86.d
new file mode 100644
index 0000000..ee043b1207
--- /dev/null
+++ b/ld/testsuite/ld-ifunc/ifunc-1-x86.d
@@ -0,0 +1,7 @@
+#ld: -shared
+#objdump: -dw
+#target: x86_64-*-* i?86-*-*
+
+#...
+[ \t0-9a-f]+:[ \t0-9a-f]+call[ \t0-9a-fq]+<\*ABS\*@plt>
+#pass
diff --git a/ld/testsuite/ld-ifunc/ifunc-1-x86.s b/ld/testsuite/ld-ifunc/ifunc-1-x86.s
new file mode 100644
index 0000000..82b64f0
--- /dev/null
+++ b/ld/testsuite/ld-ifunc/ifunc-1-x86.s
@@ -0,0 +1,16 @@
+ .type foo, %gnu_indirect_function
+ .global __GI_foo
+ .hidden __GI_foo
+ .set __GI_foo, foo
+ .text
+.globl foo
+ .type foo, @function
+foo:
+ ret
+ .size foo, .-foo
+.globl bar
+ .type bar, @function
+bar:
+ call __GI_foo@PLT
+ ret
+ .size bar, .-bar
diff --git a/ld/testsuite/ld-ifunc/ifunc-2-i386.d b/ld/testsuite/ld-ifunc/ifunc-2-i386.d
new file mode 100644
index 0000000..7dfc1fe
--- /dev/null
+++ b/ld/testsuite/ld-ifunc/ifunc-2-i386.d
@@ -0,0 +1,8 @@
+#ld: -m elf_i386 -shared
+#as: --32
+#objdump: -dw
+#target: x86_64-*-* i?86-*-*
+
+#...
+[ \t0-9a-f]+:[ \t0-9a-f]+call[ \t0-9a-f]+<\*ABS\*@plt>
+#pass
diff --git a/ld/testsuite/ld-ifunc/ifunc-2-i386.s b/ld/testsuite/ld-ifunc/ifunc-2-i386.s
new file mode 100644
index 0000000..32d8812
--- /dev/null
+++ b/ld/testsuite/ld-ifunc/ifunc-2-i386.s
@@ -0,0 +1,21 @@
+ .type foo, %gnu_indirect_function
+ .global __GI_foo
+ .hidden __GI_foo
+ .set __GI_foo, foo
+ .text
+.globl foo
+ .type foo, @function
+foo:
+ ret
+ .size foo, .-foo
+.globl bar
+ .type bar, @function
+bar:
+ call .L6
+.L6:
+ popl %ebx
+ addl $_GLOBAL_OFFSET_TABLE_+[.-.L6], %ebx
+ call __GI_foo
+ leal __GI_foo@GOTOFF(%ebx), %eax
+ ret
+ .size bar, .-bar
diff --git a/ld/testsuite/ld-ifunc/ifunc-2-x86-64.d b/ld/testsuite/ld-ifunc/ifunc-2-x86-64.d
new file mode 100644
index 0000000..103db78
--- /dev/null
+++ b/ld/testsuite/ld-ifunc/ifunc-2-x86-64.d
@@ -0,0 +1,8 @@
+#ld: -shared
+#objdump: -dw
+#target: x86_64-*-*
+
+#...
+[ \t0-9a-f]+:[ \t0-9a-f]+call[ \t0-9a-fq]+<\*ABS\*@plt>
+[ \t0-9a-f]+:[ \t0-9a-f]+lea[ \t]+.*\(%rip\),%rax.*[ \t0-9a-fq]+<\*ABS\*@plt>
+#pass
diff --git a/ld/testsuite/ld-ifunc/ifunc-2-x86-64.s b/ld/testsuite/ld-ifunc/ifunc-2-x86-64.s
new file mode 100644
index 0000000..4137ff1
--- /dev/null
+++ b/ld/testsuite/ld-ifunc/ifunc-2-x86-64.s
@@ -0,0 +1,17 @@
+ .type foo, %gnu_indirect_function
+ .global __GI_foo
+ .hidden __GI_foo
+ .set __GI_foo, foo
+ .text
+.globl foo
+ .type foo, @function
+foo:
+ ret
+ .size foo, .-foo
+.globl bar
+ .type bar, @function
+bar:
+ call __GI_foo
+ leaq __GI_foo(%rip), %rax
+ ret
+ .size bar, .-bar
diff --git a/ld/testsuite/ld-ifunc/ifunc-3-x86.s b/ld/testsuite/ld-ifunc/ifunc-3-x86.s
new file mode 100644
index 0000000..24af7eb
--- /dev/null
+++ b/ld/testsuite/ld-ifunc/ifunc-3-x86.s
@@ -0,0 +1,16 @@
+ .type foo, %gnu_indirect_function
+ .global __GI_foo
+ .protected __GI_foo
+ .set __GI_foo, foo
+ .text
+.globl foo
+ .type foo, @function
+foo:
+ ret
+ .size foo, .-foo
+.globl bar
+ .type bar, @function
+bar:
+ call __GI_foo@PLT
+ ret
+ .size bar, .-bar
diff --git a/ld/testsuite/ld-ifunc/ifunc-3a-x86.d b/ld/testsuite/ld-ifunc/ifunc-3a-x86.d
new file mode 100644
index 0000000..97225ba
--- /dev/null
+++ b/ld/testsuite/ld-ifunc/ifunc-3a-x86.d
@@ -0,0 +1,8 @@
+#source: ifunc-3-x86.s
+#ld: -shared
+#objdump: -dw
+#target: x86_64-*-* i?86-*-*
+
+#...
+[ \t0-9a-f]+:[ \t0-9a-f]+call[ \t0-9a-fq]+<\*ABS\*@plt>
+#pass
diff --git a/ld/testsuite/ld-ifunc/ifunc-3b-x86.d b/ld/testsuite/ld-ifunc/ifunc-3b-x86.d
new file mode 100644
index 0000000..a543825
--- /dev/null
+++ b/ld/testsuite/ld-ifunc/ifunc-3b-x86.d
@@ -0,0 +1,8 @@
+#source: ifunc-3-x86.s
+#ld: -shared
+#readelf: -r --wide
+#target: x86_64-*-* i?86-*-*
+
+#...
+[0-9a-f]+[ ]+[0-9a-f]+[ ]+R_[_0-9A-Z]+_IRELATIVE[ ]*[0-9a-f]*
+#pass
diff --git a/ld/testsuite/ld-ifunc/ifunc-4-x86.d b/ld/testsuite/ld-ifunc/ifunc-4-x86.d
new file mode 100644
index 0000000..5fe66e0
--- /dev/null
+++ b/ld/testsuite/ld-ifunc/ifunc-4-x86.d
@@ -0,0 +1,7 @@
+#ld:
+#readelf: -r --wide
+#target: x86_64-*-* i?86-*-*
+
+#...
+[0-9a-f]+[ ]+[0-9a-f]+[ ]+R_[_0-9A-Z]+_IRELATIVE[ ]*[0-9a-f]*
+#pass
diff --git a/ld/testsuite/ld-ifunc/ifunc-4-x86.s b/ld/testsuite/ld-ifunc/ifunc-4-x86.s
new file mode 100644
index 0000000..1c7e07e
--- /dev/null
+++ b/ld/testsuite/ld-ifunc/ifunc-4-x86.s
@@ -0,0 +1,19 @@
+ .text
+ .type foo, %gnu_indirect_function
+.globl foo
+ .type foo, @function
+foo:
+ ret
+ .size foo, .-foo
+ .type start,"function"
+ .global start
+start:
+ .type _start,"function"
+ .global _start
+_start:
+ .type __start,"function"
+ .global __start
+__start:
+ .type __start,"function"
+ call foo
+ movl $foo,%eax
diff --git a/ld/testsuite/ld-ifunc/ifunc-5-i386.d b/ld/testsuite/ld-ifunc/ifunc-5-i386.d
new file mode 100644
index 0000000..eb3fc01
--- /dev/null
+++ b/ld/testsuite/ld-ifunc/ifunc-5-i386.d
@@ -0,0 +1,8 @@
+#ld: -m elf_i386
+#as: --32
+#readelf: -r --wide
+#target: x86_64-*-* i?86-*-*
+
+#...
+[0-9a-f]+[ ]+[0-9a-f]+[ ]+R_386_IRELATIVE[ ]*
+#pass
diff --git a/ld/testsuite/ld-ifunc/ifunc-5-i386.s b/ld/testsuite/ld-ifunc/ifunc-5-i386.s
new file mode 100644
index 0000000..8e351ff
--- /dev/null
+++ b/ld/testsuite/ld-ifunc/ifunc-5-i386.s
@@ -0,0 +1,23 @@
+ .text
+ .type foo, %gnu_indirect_function
+.globl foo
+ .type foo, @function
+foo:
+ ret
+ .size foo, .-foo
+ .type start,"function"
+ .global start
+start:
+ .type _start,"function"
+ .global _start
+_start:
+ .type __start,"function"
+ .global __start
+__start:
+ .type __start,"function"
+ call .L6
+.L6:
+ popl %ebx
+ addl $_GLOBAL_OFFSET_TABLE_+[.-.L6], %ebx
+ call foo@PLT
+ leal foo@GOT(%ebx), %eax
diff --git a/ld/testsuite/ld-ifunc/ifunc-5-x86-64.d b/ld/testsuite/ld-ifunc/ifunc-5-x86-64.d
new file mode 100644
index 0000000..84347cc
--- /dev/null
+++ b/ld/testsuite/ld-ifunc/ifunc-5-x86-64.d
@@ -0,0 +1,7 @@
+#ld:
+#readelf: -r --wide
+#target: x86_64-*-*
+
+#...
+[0-9a-f]+[ ]+[0-9a-f]+[ ]+R_X86_64_IRELATIVE[ ]+[0-9a-f]*
+#pass
diff --git a/ld/testsuite/ld-ifunc/ifunc-5-x86-64.s b/ld/testsuite/ld-ifunc/ifunc-5-x86-64.s
new file mode 100644
index 0000000..054ce97
--- /dev/null
+++ b/ld/testsuite/ld-ifunc/ifunc-5-x86-64.s
@@ -0,0 +1,19 @@
+ .text
+ .type foo, %gnu_indirect_function
+.globl foo
+ .type foo, @function
+foo:
+ ret
+ .size foo, .-foo
+ .type start,"function"
+ .global start
+start:
+ .type _start,"function"
+ .global _start
+_start:
+ .type __start,"function"
+ .global __start
+__start:
+ .type __start,"function"
+ call foo@PLT
+ movq foo@GOTPCREL(%rip), %rax
diff --git a/ld/testsuite/ld-ifunc/ifunc.exp b/ld/testsuite/ld-ifunc/ifunc.exp
index 2ba5da1..6840e4e 100644
--- a/ld/testsuite/ld-ifunc/ifunc.exp
+++ b/ld/testsuite/ld-ifunc/ifunc.exp
@@ -98,6 +98,33 @@ proc contains_ifunc_symbol { binary_file } {
return 1
}
+# A procedure to confirm that a file contains the R_*_IRELATIVE
+# relocation.
+# Returns -1 upon error, 0 if the relocation was not found and 1 if
+# it was found.
+proc contains_irelative_reloc { binary_file } {
+ global READELF
+ global READELFFLAGS
+
+ catch "exec $READELF $READELFFLAGS --relocs --wide $binary_file > readelf.out" got
+
+ if ![string match "" $got] then {
+ verbose "proc contains_irelative_reloc: Readelf produced unexpected out processing $binary_file: $got"
+ return -1
+ }
+
+ # Look for a line like this:
+ # 0000000000600ab0 0000000000000025 R_X86_64_IRELATIVE 000000000040061c
+ # 080496f4 0000002a R_386_IRELATIVE
+
+
+ if { ![regexp "\[0-9a-f\]+\[ \]+\[0-9a-f\]+\[ \]+R_\[_0-9A-Z\]+_IRELATIVE\[ \]*\[0-9a-f\]*\n" [file_contents readelf.out]] } {
+ return 0
+ }
+
+ return 1
+}
+
# A procedure to confirm that a file contains a relocation that references an IFUNC symbol.
# Returns -1 upon error, 0 if the reloc was not found and 1 if it was found.
proc contains_ifunc_reloc { binary_file } {
@@ -184,11 +211,16 @@ if { $fails == 0 } {
return
}
-# Check the executables.
+# Check the executables and shared libraries
#
-# The linked ifunc using executables should have an OSABI field of LINUX
-# The linked non-ifunc using executable should have an OSABI field of NONE (aka System V).
+# The linked ifunc using executables and the shared library containing
+# ifunc should have an OSABI field of LINUX. The linked non-ifunc using
+# executable should have an OSABI field of NONE (aka System V).
+if {! [check_osabi tmpdir/libshared_ifunc.so {UNIX - Linux}]} {
+ fail "Shared libraries containing ifunc does not have an OS/ABI field of LINUX"
+ set fails [expr $fails + 1]
+}
if {! [check_osabi tmpdir/static_prog {UNIX - Linux}]} {
fail "Static ifunc-using executable does not have an OS/ABI field of LINUX"
set fails [expr $fails + 1]
@@ -202,9 +234,14 @@ if {! [check_osabi tmpdir/static_nonifunc_prog {UNIX - System V}]} {
set fails [expr $fails + 1]
}
-# The linked ifunc using executables should contain an IFUNC symbol,
-# The non-ifunc using executable should not.
+# The linked ifunc using executables and the shared library containing
+# ifunc should contain an IFUNC symbol. The non-ifunc using executable
+# should not.
+if {[contains_ifunc_symbol tmpdir/libshared_ifunc.so] != 1} {
+ fail "Shared libraries containing ifunc does not contain an IFUNC symbol"
+ set fails [expr $fails + 1]
+}
if {[contains_ifunc_symbol tmpdir/static_prog] != 1} {
fail "Static ifunc-using executable does not contain an IFUNC symbol"
set fails [expr $fails + 1]
@@ -218,12 +255,17 @@ if {[contains_ifunc_symbol tmpdir/static_nonifunc_prog] != 0} {
set fails [expr $fails + 1]
}
-# The linked ifunc using executablea should contain a dynamic reloc referencing the IFUNC symbol.
-# (Even the static executable which should have a dynamic section created for it).
-# The non-ifunc using executable should not.
+# The linked ifunc using executables and shared libraries should contain
+# a dynamic reloc referencing the IFUNC symbol. (Even the static
+# executable which should have a dynamic section created for it). The
+# non-ifunc using executable should not.
-if {[contains_ifunc_reloc tmpdir/static_prog] != 1} {
- fail "Static ifunc-using executable does not contain a reloc against an IFUNC symbol"
+if {[contains_irelative_reloc tmpdir/libshared_ifunc.so] != 1} {
+ fail "ifunc-using shared library does not contain R_*_IRELATIVE relocation"
+ set fails [expr $fails + 1]
+}
+if {[contains_irelative_reloc tmpdir/static_prog] != 1} {
+ fail "Static ifunc-using executable does not contain R_*_IRELATIVE relocation"
set fails [expr $fails + 1]
}
if {[contains_ifunc_reloc tmpdir/dynamic_prog] != 1} {
@@ -252,3 +294,10 @@ if { $verbose < 1 } {
remote_file host delete "tmpdir/static_prog"
remote_file host delete "tmpdir/static_nonifunc_prog"
}
+
+set test_list [lsort [glob -nocomplain $srcdir/$subdir/*.d]]
+foreach t $test_list {
+ # We need to strip the ".d", but can leave the dirname.
+ verbose [file rootname $t]
+ run_dump_test [file rootname $t]
+}
diff --git a/ld/testsuite/ld-ifunc/lib.c b/ld/testsuite/ld-ifunc/lib.c
index 5bfd2cd..393dabf 100644
--- a/ld/testsuite/ld-ifunc/lib.c
+++ b/ld/testsuite/ld-ifunc/lib.c
@@ -15,6 +15,19 @@ void * library_func2_ifunc (void) __asm__ ("library_func2");
void * library_func2_ifunc (void) { return global ? minus_one : zero ; }
__asm__(".type library_func2, %gnu_indirect_function");
+extern int library_func2 (int);
+extern __typeof (library_func2) library_func2 __asm__ ("__GI_library_func2");
+
+__asm__(".global __GI_library_func2");
+__asm__(".hidden __GI_library_func2");
+__asm__(".set __GI_library_func2, library_func2");
+
+int
+library_func (int x)
+{
+ return library_func2 (x);
+}
+
#else /* WITHOUT_IFUNC */
int