mirror of
https://github.com/espressif/binutils-gdb.git
synced 2025-06-27 14:39:09 +08:00
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.
This commit is contained in:
@ -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>
|
2015-05-06 Jose E. Marchesi <jose.marchesi@oracle.com>
|
||||||
|
|
||||||
* config/tc-sparc.c: Typo in comment fixed.
|
* config/tc-sparc.c: Typo in comment fixed.
|
||||||
|
@ -8772,6 +8772,25 @@ i386_frag_max_var (fragS *frag)
|
|||||||
return TYPE_FROM_RELAX_STATE (frag->fr_subtype) == UNCOND_JUMP ? 4 : 5;
|
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()
|
/* md_estimate_size_before_relax()
|
||||||
|
|
||||||
Called just before relax() for rs_machine_dependent frags. The x86
|
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 (S_GET_SEGMENT (fragP->fr_symbol) != segment
|
||||||
#if defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF)
|
#if defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF)
|
||||||
|| (IS_ELF
|
|| (IS_ELF
|
||||||
&& (S_IS_EXTERNAL (fragP->fr_symbol)
|
&& !elf_symbol_resolved_in_segment_p (fragP->fr_symbol))
|
||||||
|| S_IS_WEAK (fragP->fr_symbol)
|
|
||||||
|| ((symbol_get_bfdsym (fragP->fr_symbol)->flags
|
|
||||||
& BSF_GNU_INDIRECT_FUNCTION))))
|
|
||||||
#endif
|
#endif
|
||||||
#if defined (OBJ_COFF) && defined (TE_PE)
|
#if defined (OBJ_COFF) && defined (TE_PE)
|
||||||
|| (OUTPUT_FLAVOR == bfd_target_coff_flavour
|
|| (OUTPUT_FLAVOR == bfd_target_coff_flavour
|
||||||
|
@ -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>
|
2015-05-06 Jose E. Marchesi <jose.marchesi@oracle.com>
|
||||||
|
|
||||||
* gas/sparc/natural-32.d: Test ldn, ldna, stn, stna, slln, srln,
|
* gas/sparc/natural-32.d: Test ldn, ldna, stn, stna, slln, srln,
|
||||||
|
@ -394,6 +394,8 @@ if [expr ([istarget "i*86-*-*"] || [istarget "x86_64-*-*"]) && [gas_32_check]]
|
|||||||
run_dump_test "size-4"
|
run_dump_test "size-4"
|
||||||
|
|
||||||
run_dump_test "note"
|
run_dump_test "note"
|
||||||
|
|
||||||
|
run_dump_test "relax-3"
|
||||||
}
|
}
|
||||||
|
|
||||||
# This is a PE specific test.
|
# 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-4"
|
||||||
run_dump_test "x86-64-size-5"
|
run_dump_test "x86-64-size-5"
|
||||||
run_list_test "x86-64-size-inval-1" "-al"
|
run_list_test "x86-64-size-inval-1" "-al"
|
||||||
|
|
||||||
|
run_dump_test "x86-64-relax-2"
|
||||||
}
|
}
|
||||||
|
|
||||||
set ASFLAGS "$old_ASFLAGS"
|
set ASFLAGS "$old_ASFLAGS"
|
||||||
|
30
gas/testsuite/gas/i386/relax-3.d
Normal file
30
gas/testsuite/gas/i386/relax-3.d
Normal file
@ -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
|
39
gas/testsuite/gas/i386/relax-3.s
Normal file
39
gas/testsuite/gas/i386/relax-3.s
Normal file
@ -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
|
32
gas/testsuite/gas/i386/x86-64-relax-2.d
Normal file
32
gas/testsuite/gas/i386/x86-64-relax-2.d
Normal file
@ -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
|
Reference in New Issue
Block a user