diff options
author | H.J. Lu <hjl.tools@gmail.com> | 2015-09-01 05:06:16 -0700 |
---|---|---|
committer | H.J. Lu <hjl.tools@gmail.com> | 2015-09-01 05:06:33 -0700 |
commit | 04ebc307f9601168c165fb63aa39a676e45454b7 (patch) | |
tree | 3db90b1dba71a706df7edb2f28a6e2104587ebdd /ld | |
parent | b07bca4ecd27f9cbaff822e4135abaf0ae6cd0db (diff) | |
download | gdb-04ebc307f9601168c165fb63aa39a676e45454b7.zip gdb-04ebc307f9601168c165fb63aa39a676e45454b7.tar.gz gdb-04ebc307f9601168c165fb63aa39a676e45454b7.tar.bz2 |
Skip PLT for function pointer initialization
We use its PLT entry to initialize function pointer at run-time. If
there is no other usage for the PLT entry, we can generate run-time
function pointer relocations in read-write section, which can be
resolved by dynamic linker, to initialize function pointers. It avoids
the extra indirect branch overhead in PLT.
bfd/
PR ld/18900
* elf32-i386.c (elf_i386_link_hash_entry): Add
func_pointer_refcount.
(elf_i386_link_hash_newfunc): Clear func_pointer_refcount.
(elf_i386_get_local_sym_hash): Likewise.
(elf_i386_copy_indirect_symbol): Also copy
func_pointer_refcount.
(elf_i386_check_relocs): Increment func_pointer_refcount.
(elf_i386_gc_sweep_hook): Decrement func_pointer_refcount.
(elf_i386_allocate_dynrelocs): Don't create the PLT entry if
there are only function pointer relocations which can be
resolved at run-time. Keep dynanamic relocations for run-time
function pointer initialization.
(elf_i386_relocate_section): Copy dynamic function pointer
relocations.
* elf64-x86-64.c (elf_x86_64_link_hash_entry): Add
func_pointer_refcount.
(elf_x86_64_link_hash_newfunc): Clear func_pointer_refcount.
(elf_x86_64_get_local_sym_hash): Likewise.
(elf_x86_64_copy_indirect_symbol): Also copy
func_pointer_refcount.
(elf_x86_64_check_relocs): Increment func_pointer_refcount.
(elf_x86_64_gc_sweep_hook): Decrement func_pointer_refcount.
(elf_x86_64_allocate_dynrelocs): Don't create the PLT entry if
there are only function pointer relocations which can be
resolved at run-time. Keep dynanamic relocations for run-time
function pointer initialization.
(elf_x86_64_relocate_section): Copy dynamic function pointer
relocations.
ld/testsuite/
PR ld/18900
* ld-i386/i386.exp: Run tests for PR ld/18900.
* ld-x86-64/x86-64.exp: Likewise.
* ld-i386/pr18900.out: New file.
* ld-i386/pr18900a.c: Likewise.
* ld-i386/pr18900a.c: Likewise.
* ld-i386/pr18900a.rd: Likewise.
* ld-i386/pr18900b.c: Likewise.
* ld-i386/pr18900b.rd: Likewise.
* ld-i386/pr18900c.c: Likewise.
* ld-x86-64/pr18900.out: Likewise.
* ld-x86-64/pr18900a.c: Likewise.
* ld-x86-64/pr18900a.rd: Likewise.
* ld-x86-64/pr18900b.c: Likewise.
* ld-x86-64/pr18900b.rd: Likewise.
* ld-x86-64/pr18900c.c: Likewise.
* ld-x86-64/mpx3.dd: Updated.
Diffstat (limited to 'ld')
-rw-r--r-- | ld/testsuite/ChangeLog | 20 | ||||
-rw-r--r-- | ld/testsuite/ld-i386/i386.exp | 32 | ||||
-rw-r--r-- | ld/testsuite/ld-i386/pr18900.out | 4 | ||||
-rw-r--r-- | ld/testsuite/ld-i386/pr18900a.c | 14 | ||||
-rw-r--r-- | ld/testsuite/ld-i386/pr18900a.rd | 4 | ||||
-rw-r--r-- | ld/testsuite/ld-i386/pr18900b.c | 22 | ||||
-rw-r--r-- | ld/testsuite/ld-i386/pr18900b.rd | 4 | ||||
-rw-r--r-- | ld/testsuite/ld-i386/pr18900c.c | 5 | ||||
-rw-r--r-- | ld/testsuite/ld-x86-64/mpx3.dd | 25 | ||||
-rw-r--r-- | ld/testsuite/ld-x86-64/pr18900.out | 4 | ||||
-rw-r--r-- | ld/testsuite/ld-x86-64/pr18900a.c | 14 | ||||
-rw-r--r-- | ld/testsuite/ld-x86-64/pr18900a.rd | 4 | ||||
-rw-r--r-- | ld/testsuite/ld-x86-64/pr18900b.c | 22 | ||||
-rw-r--r-- | ld/testsuite/ld-x86-64/pr18900b.rd | 4 | ||||
-rw-r--r-- | ld/testsuite/ld-x86-64/pr18900c.c | 5 | ||||
-rw-r--r-- | ld/testsuite/ld-x86-64/x86-64.exp | 32 |
16 files changed, 199 insertions, 16 deletions
diff --git a/ld/testsuite/ChangeLog b/ld/testsuite/ChangeLog index 7650cda..0241c08 100644 --- a/ld/testsuite/ChangeLog +++ b/ld/testsuite/ChangeLog @@ -1,3 +1,23 @@ +2015-09-01 H.J. Lu <hongjiu.lu@intel.com> + + PR ld/18900 + * ld-i386/i386.exp: Run tests for PR ld/18900. + * ld-x86-64/x86-64.exp: Likewise. + * ld-i386/pr18900.out: New file. + * ld-i386/pr18900a.c: Likewise. + * ld-i386/pr18900a.c: Likewise. + * ld-i386/pr18900a.rd: Likewise. + * ld-i386/pr18900b.c: Likewise. + * ld-i386/pr18900b.rd: Likewise. + * ld-i386/pr18900c.c: Likewise. + * ld-x86-64/pr18900.out: Likewise. + * ld-x86-64/pr18900a.c: Likewise. + * ld-x86-64/pr18900a.rd: Likewise. + * ld-x86-64/pr18900b.c: Likewise. + * ld-x86-64/pr18900b.rd: Likewise. + * ld-x86-64/pr18900c.c: Likewise. + * ld-x86-64/mpx3.dd: Updated. + 2015-08-27 Alan Modra <amodra@gmail.com> * ld-powerpc/relocsort.s, * ld-powerpc/relocsort.d: New test. diff --git a/ld/testsuite/ld-i386/i386.exp b/ld/testsuite/ld-i386/i386.exp index 47911a6..6213dbe 100644 --- a/ld/testsuite/ld-i386/i386.exp +++ b/ld/testsuite/ld-i386/i386.exp @@ -466,6 +466,30 @@ if { [isnative] {{readelf {-Wr} pr17827.rd}} \ "pr17827" \ ] \ + [list \ + "Build pr18900.so" \ + "-shared" \ + "-fPIC" \ + { pr18900a.c } \ + "" \ + "pr18900.so" \ + ] \ + [list \ + "Build pr18900a" \ + "tmpdir/pr18900.so" \ + "" \ + { pr18900b.c pr18900c.c } \ + {{readelf {-Wrd} pr18900a.rd}} \ + "pr18900a" \ + ] \ + [list \ + "Build pr18900b" \ + "tmpdir/pr18900.so" \ + "" \ + { pr18900b.c pr18900c.c } \ + {{readelf {-Wrd} pr18900b.rd}} \ + "pr18900b" \ + ] \ ] run_ld_link_exec_tests [] [list \ @@ -520,6 +544,14 @@ if { [isnative] "pr17689ver" \ "pr17689.out" \ ] \ + [list \ + "Run pr18900" \ + "tmpdir/pr18900.so" \ + "" \ + { pr18900b.c pr18900c.c } \ + "pr18900" \ + "pr18900.out" \ + ] \ ] } diff --git a/ld/testsuite/ld-i386/pr18900.out b/ld/testsuite/ld-i386/pr18900.out new file mode 100644 index 0000000..b462a5a --- /dev/null +++ b/ld/testsuite/ld-i386/pr18900.out @@ -0,0 +1,4 @@ +OK +OK +OK +OK diff --git a/ld/testsuite/ld-i386/pr18900a.c b/ld/testsuite/ld-i386/pr18900a.c new file mode 100644 index 0000000..fa2fc06 --- /dev/null +++ b/ld/testsuite/ld-i386/pr18900a.c @@ -0,0 +1,14 @@ +#include <stdio.h> + +void +foo (void) +{ + printf ("OK\n"); +} + +void * +bar (void) +{ + foo (); + return &foo; +} diff --git a/ld/testsuite/ld-i386/pr18900a.rd b/ld/testsuite/ld-i386/pr18900a.rd new file mode 100644 index 0000000..0731396 --- /dev/null +++ b/ld/testsuite/ld-i386/pr18900a.rd @@ -0,0 +1,4 @@ +#failif +#... +.*\(TEXTREL\).* +#... diff --git a/ld/testsuite/ld-i386/pr18900b.c b/ld/testsuite/ld-i386/pr18900b.c new file mode 100644 index 0000000..e666305 --- /dev/null +++ b/ld/testsuite/ld-i386/pr18900b.c @@ -0,0 +1,22 @@ +extern void abort (void); +extern void foo (void); +extern void *bar (void); + +typedef void (*func_p) (void); + +extern const func_p p1; + +func_p p2 = &foo; +func_p p3 = &foo; + +int +main () +{ + void *p = bar (); + p1 (); + p2 (); + p3 (); + if (p != p1) + abort (); + return 0; +} diff --git a/ld/testsuite/ld-i386/pr18900b.rd b/ld/testsuite/ld-i386/pr18900b.rd new file mode 100644 index 0000000..e256a70 --- /dev/null +++ b/ld/testsuite/ld-i386/pr18900b.rd @@ -0,0 +1,4 @@ +#failif +#... +[0-9a-f ]+R_386_JUMP_SLOT[0-9a-f ]+foo +#... diff --git a/ld/testsuite/ld-i386/pr18900c.c b/ld/testsuite/ld-i386/pr18900c.c new file mode 100644 index 0000000..b37ca16 --- /dev/null +++ b/ld/testsuite/ld-i386/pr18900c.c @@ -0,0 +1,5 @@ +extern void foo (void); + +typedef void (*func_p) (void); + +func_p p1 = &foo; diff --git a/ld/testsuite/ld-x86-64/mpx3.dd b/ld/testsuite/ld-x86-64/mpx3.dd index 2a8356d..eb529f4 100644 --- a/ld/testsuite/ld-x86-64/mpx3.dd +++ b/ld/testsuite/ld-x86-64/mpx3.dd @@ -3,33 +3,26 @@ Disassembly of section .plt: -0+400290 <.plt>: -[ ]*[a-f0-9]+: ff 35 6a 01 20 00 pushq 0x20016a\(%rip\) # 600400 <_GLOBAL_OFFSET_TABLE_\+0x8> -[ ]*[a-f0-9]+: f2 ff 25 6b 01 20 00 bnd jmpq \*0x20016b\(%rip\) # 600408 <_GLOBAL_OFFSET_TABLE_\+0x10> +0+[a-f0-9]+ <.plt>: +[ ]*[a-f0-9]+: ff ([0-9a-f]{2} ){5} pushq 0x[a-f0-9]+\(%rip\) # [a-f0-9]+ <_GLOBAL_OFFSET_TABLE_\+0x8> +[ ]*[a-f0-9]+: f2 ff ([0-9a-f]{2} ){5} bnd jmpq \*0x[a-f0-9]+\(%rip\) # [a-f0-9]+ <_GLOBAL_OFFSET_TABLE_\+0x10> [ ]*[a-f0-9]+: 0f 1f 00 nopl \(%rax\) [ ]*[a-f0-9]+: 68 00 00 00 00 pushq \$0x0 -[ ]*[a-f0-9]+: f2 e9 e5 ff ff ff bnd jmpq 400290 <call1@plt-0x30> -[ ]*[a-f0-9]+: 0f 1f 44 00 00 nopl 0x0\(%rax,%rax,1\) -[ ]*[a-f0-9]+: 68 01 00 00 00 pushq \$0x1 -[ ]*[a-f0-9]+: f2 e9 d5 ff ff ff bnd jmpq 400290 <call1@plt-0x30> +[ ]*[a-f0-9]+: f2 e9 ([0-9a-f]{2} ){4} bnd jmpq [a-f0-9]+ <call1@plt-0x20> [ ]*[a-f0-9]+: 0f 1f 44 00 00 nopl 0x0\(%rax,%rax,1\) Disassembly of section .plt.bnd: -0+4002c0 <call1@plt>: -[ ]*[a-f0-9]+: f2 ff 25 49 01 20 00 bnd jmpq \*0x200149\(%rip\) # 600410 <_GLOBAL_OFFSET_TABLE_\+0x18> -[ ]*[a-f0-9]+: 90 nop - -0+4002c8 <call2@plt>: -[ ]*[a-f0-9]+: f2 ff 25 49 01 20 00 bnd jmpq \*0x200149\(%rip\) # 600418 <_GLOBAL_OFFSET_TABLE_\+0x20> +0+[a-f0-9]+ <call1@plt>: +[ ]*[a-f0-9]+: f2 ff ([0-9a-f]{2} ){5} bnd jmpq \*0x[a-f0-9]+\(%rip\) # [a-f0-9]+ <_GLOBAL_OFFSET_TABLE_\+0x18> [ ]*[a-f0-9]+: 90 nop Disassembly of section .text: -0+4002d0 <_start>: -[ ]*[a-f0-9]+: bf c0 02 40 00 mov \$0x4002c0,%edi +0+[a-f0-9]+ <_start>: +[ ]*[a-f0-9]+: bf ([0-9a-f]{2} ){4} mov \$0x[a-f0-9]+,%edi [ ]*[a-f0-9]+: f2 ff d7 bnd callq \*%rdi -[ ]*[a-f0-9]+: 48 8b 3d 41 01 20 00 mov 0x200141\(%rip\),%rdi # 600420 <func> +[ ]*[a-f0-9]+: 48 8b ([0-9a-f]{2} ){5} mov 0x[a-f0-9]+\(%rip\),%rdi # [a-f0-9]+ <func> [ ]*[a-f0-9]+: f2 ff d7 bnd callq \*%rdi [ ]*[a-f0-9]+: c3 retq #pass diff --git a/ld/testsuite/ld-x86-64/pr18900.out b/ld/testsuite/ld-x86-64/pr18900.out new file mode 100644 index 0000000..b462a5a --- /dev/null +++ b/ld/testsuite/ld-x86-64/pr18900.out @@ -0,0 +1,4 @@ +OK +OK +OK +OK diff --git a/ld/testsuite/ld-x86-64/pr18900a.c b/ld/testsuite/ld-x86-64/pr18900a.c new file mode 100644 index 0000000..fa2fc06 --- /dev/null +++ b/ld/testsuite/ld-x86-64/pr18900a.c @@ -0,0 +1,14 @@ +#include <stdio.h> + +void +foo (void) +{ + printf ("OK\n"); +} + +void * +bar (void) +{ + foo (); + return &foo; +} diff --git a/ld/testsuite/ld-x86-64/pr18900a.rd b/ld/testsuite/ld-x86-64/pr18900a.rd new file mode 100644 index 0000000..0731396 --- /dev/null +++ b/ld/testsuite/ld-x86-64/pr18900a.rd @@ -0,0 +1,4 @@ +#failif +#... +.*\(TEXTREL\).* +#... diff --git a/ld/testsuite/ld-x86-64/pr18900b.c b/ld/testsuite/ld-x86-64/pr18900b.c new file mode 100644 index 0000000..e666305 --- /dev/null +++ b/ld/testsuite/ld-x86-64/pr18900b.c @@ -0,0 +1,22 @@ +extern void abort (void); +extern void foo (void); +extern void *bar (void); + +typedef void (*func_p) (void); + +extern const func_p p1; + +func_p p2 = &foo; +func_p p3 = &foo; + +int +main () +{ + void *p = bar (); + p1 (); + p2 (); + p3 (); + if (p != p1) + abort (); + return 0; +} diff --git a/ld/testsuite/ld-x86-64/pr18900b.rd b/ld/testsuite/ld-x86-64/pr18900b.rd new file mode 100644 index 0000000..7e46c85 --- /dev/null +++ b/ld/testsuite/ld-x86-64/pr18900b.rd @@ -0,0 +1,4 @@ +#failif +#... +[0-9a-f ]+R_X86_64_JUMP_SLOT[0-9a-f ]+foo \+ 0 +#... diff --git a/ld/testsuite/ld-x86-64/pr18900c.c b/ld/testsuite/ld-x86-64/pr18900c.c new file mode 100644 index 0000000..b37ca16 --- /dev/null +++ b/ld/testsuite/ld-x86-64/pr18900c.c @@ -0,0 +1,5 @@ +extern void foo (void); + +typedef void (*func_p) (void); + +func_p p1 = &foo; diff --git a/ld/testsuite/ld-x86-64/x86-64.exp b/ld/testsuite/ld-x86-64/x86-64.exp index 5409dff..6320999 100644 --- a/ld/testsuite/ld-x86-64/x86-64.exp +++ b/ld/testsuite/ld-x86-64/x86-64.exp @@ -476,6 +476,30 @@ if { [isnative] && [which $CC] != 0 } { {{readelf {-Wr} pr17827.rd}} \ "pr17827" \ ] \ + [list \ + "Build pr18900.so" \ + "-shared" \ + "-fPIC" \ + { pr18900a.c } \ + "" \ + "pr18900.so" \ + ] \ + [list \ + "Build pr18900a" \ + "tmpdir/pr18900.so" \ + "" \ + { pr18900b.c pr18900c.c } \ + {{readelf {-Wrd} pr18900a.rd}} \ + "pr18900a" \ + ] \ + [list \ + "Build pr18900b" \ + "tmpdir/pr18900.so" \ + "" \ + { pr18900b.c pr18900c.c } \ + {{readelf {-Wrd} pr18900b.rd}} \ + "pr18900b" \ + ] \ ] run_ld_link_exec_tests [] [list \ @@ -522,6 +546,14 @@ if { [isnative] && [which $CC] != 0 } { "pr17689now" \ "pr17689.out" \ ] \ + [list \ + "Run pr18900" \ + "tmpdir/pr18900.so" \ + "" \ + { pr18900b.c pr18900c.c } \ + "pr18900" \ + "pr18900.out" \ + ] \ ] if { [istarget "x86_64-*-linux*"] \ |