diff options
author | H.J. Lu <hjl.tools@gmail.com> | 2015-05-07 09:13:39 -0700 |
---|---|---|
committer | H.J. Lu <hjl.tools@gmail.com> | 2015-05-07 09:19:16 -0700 |
commit | b084df0b8d1262fb1e969c74bcc5c61e262a6199 (patch) | |
tree | dce3ec5097f44350ac9f84259ce24aa0ef454330 /gas | |
parent | 1c56a84d9bac1f6a451a89d2c6af3d7078c4290e (diff) | |
download | gdb-b084df0b8d1262fb1e969c74bcc5c61e262a6199.zip gdb-b084df0b8d1262fb1e969c74bcc5c61e262a6199.tar.gz gdb-b084df0b8d1262fb1e969c74bcc5c61e262a6199.tar.bz2 |
Optimize branches to non-weak symbols with visibility
Branches to global non-weak symbols defined in the same segment with
non-default visibility can be optimized the same way as branches to
local symbols.
gas/
* config/tc-i386.c (elf_symbol_resolved_in_segment_p): New.
(md_estimate_size_before_relax): Use it.
gas/testsuite/
* gas/i386/i386.exp: Run relax-3 and x86-64-relax-2.
* gas/i386/relax-3.d: New file.
* gas/i386/relax-3.s: Likewise.
* gas/i386/x86-64-relax-2.d: Likewise.
Diffstat (limited to 'gas')
-rw-r--r-- | gas/ChangeLog | 5 | ||||
-rw-r--r-- | gas/config/tc-i386.c | 24 | ||||
-rw-r--r-- | gas/testsuite/ChangeLog | 7 | ||||
-rw-r--r-- | gas/testsuite/gas/i386/i386.exp | 4 | ||||
-rw-r--r-- | gas/testsuite/gas/i386/relax-3.d | 30 | ||||
-rw-r--r-- | gas/testsuite/gas/i386/relax-3.s | 39 | ||||
-rw-r--r-- | gas/testsuite/gas/i386/x86-64-relax-2.d | 32 |
7 files changed, 137 insertions, 4 deletions
diff --git a/gas/ChangeLog b/gas/ChangeLog index 7f42a64..9758e72 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,3 +1,8 @@ +2015-05-07 H.J. Lu <hongjiu.lu@intel.com> + + * config/tc-i386.c (elf_symbol_resolved_in_segment_p): New. + (md_estimate_size_before_relax): Use it. + 2015-05-06 Jose E. Marchesi <jose.marchesi@oracle.com> * config/tc-sparc.c: Typo in comment fixed. diff --git a/gas/config/tc-i386.c b/gas/config/tc-i386.c index 50f9cb4..c4ba13d 100644 --- a/gas/config/tc-i386.c +++ b/gas/config/tc-i386.c @@ -8772,6 +8772,25 @@ i386_frag_max_var (fragS *frag) return TYPE_FROM_RELAX_STATE (frag->fr_subtype) == UNCOND_JUMP ? 4 : 5; } +#if defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF) +static int +elf_symbol_resolved_in_segment_p (symbolS *fr_symbol) +{ + /* STT_GNU_IFUNC symbol must go through PLT. */ + if ((symbol_get_bfdsym (fr_symbol)->flags + & BSF_GNU_INDIRECT_FUNCTION) != 0) + return 0; + + if (!S_IS_EXTERNAL (fr_symbol)) + /* Symbol may be weak or local. */ + return !S_IS_WEAK (fr_symbol); + + /* Global symbols with default visibility in a shared library may be + preempted by another definition. */ + return ELF_ST_VISIBILITY (S_GET_OTHER (fr_symbol)) != STV_DEFAULT; +} +#endif + /* md_estimate_size_before_relax() Called just before relax() for rs_machine_dependent frags. The x86 @@ -8795,10 +8814,7 @@ md_estimate_size_before_relax (fragS *fragP, segT segment) if (S_GET_SEGMENT (fragP->fr_symbol) != segment #if defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF) || (IS_ELF - && (S_IS_EXTERNAL (fragP->fr_symbol) - || S_IS_WEAK (fragP->fr_symbol) - || ((symbol_get_bfdsym (fragP->fr_symbol)->flags - & BSF_GNU_INDIRECT_FUNCTION)))) + && !elf_symbol_resolved_in_segment_p (fragP->fr_symbol)) #endif #if defined (OBJ_COFF) && defined (TE_PE) || (OUTPUT_FLAVOR == bfd_target_coff_flavour diff --git a/gas/testsuite/ChangeLog b/gas/testsuite/ChangeLog index 6339bff..1cfa577 100644 --- a/gas/testsuite/ChangeLog +++ b/gas/testsuite/ChangeLog @@ -1,3 +1,10 @@ +2015-05-07 H.J. Lu <hongjiu.lu@intel.com> + + * gas/i386/i386.exp: Run relax-3 and x86-64-relax-2. + * gas/i386/relax-3.d: New file. + * gas/i386/relax-3.s: Likewise. + * gas/i386/x86-64-relax-2.d: Likewise. + 2015-05-06 Jose E. Marchesi <jose.marchesi@oracle.com> * gas/sparc/natural-32.d: Test ldn, ldna, stn, stna, slln, srln, diff --git a/gas/testsuite/gas/i386/i386.exp b/gas/testsuite/gas/i386/i386.exp index e1fdd18..af56c26 100644 --- a/gas/testsuite/gas/i386/i386.exp +++ b/gas/testsuite/gas/i386/i386.exp @@ -394,6 +394,8 @@ if [expr ([istarget "i*86-*-*"] || [istarget "x86_64-*-*"]) && [gas_32_check]] run_dump_test "size-4" run_dump_test "note" + + run_dump_test "relax-3" } # This is a PE specific test. @@ -748,6 +750,8 @@ if [expr ([istarget "i*86-*-*"] || [istarget "x86_64-*-*"]) && [gas_64_check]] t run_dump_test "x86-64-size-4" run_dump_test "x86-64-size-5" run_list_test "x86-64-size-inval-1" "-al" + + run_dump_test "x86-64-relax-2" } set ASFLAGS "$old_ASFLAGS" diff --git a/gas/testsuite/gas/i386/relax-3.d b/gas/testsuite/gas/i386/relax-3.d new file mode 100644 index 0000000..8aa94e9 --- /dev/null +++ b/gas/testsuite/gas/i386/relax-3.d @@ -0,0 +1,30 @@ +#objdump: -dwr + +.*: +file format .* + +Disassembly of section .text: + +0+ <foo>: +[ ]*[a-f0-9]+: eb 1f jmp 21 <local> +[ ]*[a-f0-9]+: eb 19 jmp 1d <hidden_def> +[ ]*[a-f0-9]+: e9 fc ff ff ff jmp 5 <foo\+0x5> 5: (R_386_PC)?(DISP)?32 global_def +[ ]*[a-f0-9]+: e9 fc ff ff ff jmp a <foo\+0xa> a: (R_386_PC)?(DISP)?32 weak_def +[ ]*[a-f0-9]+: e9 fc ff ff ff jmp f <foo\+0xf> f: (R_386_PC)?(DISP)?32 weak_hidden_undef +[ ]*[a-f0-9]+: e9 fc ff ff ff jmp 14 <foo\+0x14> 14: (R_386_PC)?(DISP)?32 weak_hidden_def +[ ]*[a-f0-9]+: e9 fc ff ff ff jmp 19 <foo\+0x19> 19: (R_386_PC)?(DISP)?32 hidden_undef + +0+1d <hidden_def>: +[ ]*[a-f0-9]+: c3 ret + +0+1e <weak_hidden_def>: +[ ]*[a-f0-9]+: c3 ret + +0+1f <global_def>: +[ ]*[a-f0-9]+: c3 ret + +0+20 <weak_def>: +[ ]*[a-f0-9]+: c3 ret + +0+21 <local>: +[ ]*[a-f0-9]+: c3 ret +#pass diff --git a/gas/testsuite/gas/i386/relax-3.s b/gas/testsuite/gas/i386/relax-3.s new file mode 100644 index 0000000..ab52185 --- /dev/null +++ b/gas/testsuite/gas/i386/relax-3.s @@ -0,0 +1,39 @@ + .text + .global foo +foo: + jmp local + jmp hidden_def + jmp global_def + jmp weak_def + jmp weak_hidden_undef + jmp weak_hidden_def + jmp hidden_undef + + .hidden hidden_undef + + .global hidden_def + .hidden hidden_def +hidden_def: + ret + + .global weak_hidden_def + .hidden weak_hidden_def + .weak weak_hidden_def +weak_hidden_def: + ret + + .global global_def +global_def: + ret + + .global weak_def + .weak weak_def +weak_def: + ret + +local: + ret + + .global weak_hidden_undef + .weak weak_hidden_undef + .hidden weak_hidden_undef diff --git a/gas/testsuite/gas/i386/x86-64-relax-2.d b/gas/testsuite/gas/i386/x86-64-relax-2.d new file mode 100644 index 0000000..7b0bd56 --- /dev/null +++ b/gas/testsuite/gas/i386/x86-64-relax-2.d @@ -0,0 +1,32 @@ +#source: relax-3.s +#objdump: -dwr + +.*: +file format .* + + +Disassembly of section .text: + +0+ <foo>: +[ ]*[a-f0-9]+: eb 1f jmp 21 <local> +[ ]*[a-f0-9]+: eb 19 jmp 1d <hidden_def> +[ ]*[a-f0-9]+: e9 00 00 00 00 jmpq 9 <foo\+0x9> 5: R_X86_64_PC32 global_def-0x4 +[ ]*[a-f0-9]+: e9 00 00 00 00 jmpq e <foo\+0xe> a: R_X86_64_PC32 weak_def-0x4 +[ ]*[a-f0-9]+: e9 00 00 00 00 jmpq 13 <foo\+0x13> f: R_X86_64_PC32 weak_hidden_undef-0x4 +[ ]*[a-f0-9]+: e9 00 00 00 00 jmpq 18 <foo\+0x18> 14: R_X86_64_PC32 weak_hidden_def-0x4 +[ ]*[a-f0-9]+: e9 00 00 00 00 jmpq 1d <hidden_def> 19: R_X86_64_PC32 hidden_undef-0x4 + +0+1d <hidden_def>: +[ ]*[a-f0-9]+: c3 retq + +0+1e <weak_hidden_def>: +[ ]*[a-f0-9]+: c3 retq + +0+1f <global_def>: +[ ]*[a-f0-9]+: c3 retq + +0+20 <weak_def>: +[ ]*[a-f0-9]+: c3 retq + +0+21 <local>: +[ ]*[a-f0-9]+: c3 retq +#pass |