+2015-05-15 H.J. Lu <hongjiu.lu@intel.com>
+
+ * config/tc-i386.c (shared): New.
+ (OPTION_MSHARED): Likewise.
+ (elf_symbol_resolved_in_segment_p): Add relocation argument.
+ Check PLT relocations and shared.
+ (md_estimate_size_before_relax): Pass fragP->fr_var to
+ elf_symbol_resolved_in_segment_p.
+ (md_longopts): Add -mshared.
+ (md_show_usage): Likewise.
+ (md_parse_option): Handle OPTION_MSHARED.
+ * doc/c-i386.texi: Document -mshared.
+
2015-05-14 H.J. Lu <hongjiu.lu@intel.com>
* write.c (compress_debug): Don't write the zlib header, which
static int use_big_obj = 0;
#endif
+#if defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF)
+/* 1 if generating code for a shared library. */
+static int shared = 0;
+#endif
+
/* 1 for intel syntax,
0 if att syntax. */
static int intel_syntax = 0;
#if defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF)
static int
-elf_symbol_resolved_in_segment_p (symbolS *fr_symbol)
+elf_symbol_resolved_in_segment_p (symbolS *fr_symbol, offsetT fr_var)
{
/* STT_GNU_IFUNC symbol must go through PLT. */
if ((symbol_get_bfdsym (fr_symbol)->flags
/* Symbol may be weak or local. */
return !S_IS_WEAK (fr_symbol);
+ /* Global symbols with non-default visibility can't be preempted. */
+ if (ELF_ST_VISIBILITY (S_GET_OTHER (fr_symbol)) != STV_DEFAULT)
+ return 1;
+
+ if (fr_var != NO_RELOC)
+ switch ((enum bfd_reloc_code_real) fr_var)
+ {
+ case BFD_RELOC_386_PLT32:
+ case BFD_RELOC_X86_64_PLT32:
+ /* Symbol with PLT relocatin may be preempted. */
+ return 0;
+ default:
+ abort ();
+ }
+
/* 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;
+ return !shared;
}
#endif
if (S_GET_SEGMENT (fragP->fr_symbol) != segment
#if defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF)
|| (IS_ELF
- && !elf_symbol_resolved_in_segment_p (fragP->fr_symbol))
+ && !elf_symbol_resolved_in_segment_p (fragP->fr_symbol,
+ fragP->fr_var))
#endif
#if defined (OBJ_COFF) && defined (TE_PE)
|| (OUTPUT_FLAVOR == bfd_target_coff_flavour
#define OPTION_MBIG_OBJ (OPTION_MD_BASE + 18)
#define OPTION_OMIT_LOCK_PREFIX (OPTION_MD_BASE + 19)
#define OPTION_MEVEXRCIG (OPTION_MD_BASE + 20)
+#define OPTION_MSHARED (OPTION_MD_BASE + 21)
struct option md_longopts[] =
{
#endif
#if defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF)
{"x32", no_argument, NULL, OPTION_X32},
+ {"mshared", no_argument, NULL, OPTION_MSHARED},
#endif
{"divide", no_argument, NULL, OPTION_DIVIDE},
{"march", required_argument, NULL, OPTION_MARCH},
/* -s: On i386 Solaris, this tells the native assembler to use
.stab instead of .stab.excl. We always use .stab anyhow. */
break;
+
+ case OPTION_MSHARED:
+ shared = 1;
+ break;
#endif
#if (defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF) \
|| defined (TE_PE) || defined (TE_PEP) || defined (OBJ_MACH_O))
-mold-gcc support old (<= 2.8.1) versions of gcc\n"));
fprintf (stream, _("\
-madd-bnd-prefix add BND prefix for all valid branches\n"));
+ fprintf (stream, _("\
+ -mshared disable branch optimization for shared code\n"));
# if defined (TE_PE) || defined (TE_PEP)
fprintf (stream, _("\
-mbig-obj generate big object files\n"));
This option forces the assembler to add BND prefix to all branches, even
if such prefix was not explicitly specified in the source code.
+@cindex @samp{-mshared} option, i386
+@cindex @samp{-mshared} option, x86-64
+@item -mno-shared
+On ELF target, the assembler normally optimizes out non-PLT relocations
+against defined non-weak global branch targets with default visibility.
+The @samp{-mshared} option tells the assembler to generate code which
+may go into a shared library where all non-weak global branch targets
+with default visibility can be preempted. The resulting code is
+slightly bigger. This option only affects the handling of branch
+instructions.
+
@cindex @samp{-mbig-obj} option, x86-64
@item -mbig-obj
On x86-64 PE/COFF target this option forces the use of big object file
+2015-05-15 H.J. Lu <hongjiu.lu@intel.com>
+
+ * gas/i386/i386.exp: Don't run pcrel for ELF targets. Run
+ pcrel-elf, relax-4 and x86-64-relax-3 for ELF targets.
+ * gas/i386/pcrel-elf.d: New file.
+ * gas/i386/relax-4.d: Likewise.
+ * gas/i386/x86-64-relax-3.d: Likewise.
+ * gas/i386/relax-3.d: Pass -mshared to assembler. Updated.
+ * gas/i386/x86-64-relax-2.d: Likewise.
+ * gas/i386/relax-3.s: Add test for PLT relocation.
+
2015-05-14 Peter Bergner <bergner@vnet.ibm.com>
* gas/ppc/power4.d: Add a slbia test.
# but the relocs we currently produce are slightly different
# from those produced for ELF/COFF based toolchains.
# So for now we ignore PE targets.
- run_dump_test "pcrel"
run_dump_test "absrel"
+ if {[istarget "*-*-coff*"]} then {
+ run_dump_test "pcrel"
+ }
}
# ELF specific tests
# PIC is only supported on ELF targets.
run_dump_test "intelpic"
+ run_dump_test "pcrel-elf"
run_dump_test "relax"
run_dump_test "gotpc"
run_dump_test "tlsd"
run_dump_test "note"
run_dump_test "relax-3"
+ run_dump_test "relax-4"
if {![istarget "*-*-nacl*"]} then {
run_dump_test "iamcu-1"
run_list_test "x86-64-size-inval-1" "-al"
run_dump_test "x86-64-relax-2"
+ run_dump_test "x86-64-relax-3"
run_dump_test "x86-64-jump"
}
--- /dev/null
+#source: pcrel.s
+#as: -mshared
+#objdump: -drw
+#name: i386 pcrel ELF reloc
+
+.*: +file format .*i386.*
+
+Disassembly of section \.text:
+
+0+ <loc>:
+[ ]*[a-f0-9]+: e9 30 12 00 00 jmp 1235 <abs\+0x1> 1: R_386_PC32 \*ABS\*
+
+0+5 <glob>:
+[ ]*[a-f0-9]+: e9 fc ff ff ff jmp 6 <glob\+0x1> 6: R_386_PC32 ext
+[ ]*[a-f0-9]+: e9 fc ff ff ff jmp b <glob\+0x6> b: R_386_PC32 weak
+[ ]*[a-f0-9]+: e9 fc ff ff ff jmp 10 <glob\+0xb> 10: R_386_PC32 comm
+[ ]*[a-f0-9]+: eb ea jmp 0 <loc>
+[ ]*[a-f0-9]+: e9 fc ff ff ff jmp 17 <glob\+0x12> 17: R_386_PC32 glob
+[ ]*[a-f0-9]+: e9 72 98 00 00 jmp 9892 <abs2\+0x1c> 1c: R_386_PC32 \*ABS\*
+[ ]*[a-f0-9]+: e9 db 00 00 00 jmp 100 <loc2>
+[ ]*[a-f0-9]+: e9 fc ff ff ff jmp 26 <glob\+0x21> 26: R_386_PC32 glob2
+[ ]*[a-f0-9]+: e9 fc ff ff ff jmp 2b <glob\+0x26> 2b: R_386_PC32 .data
+[ ]*[a-f0-9]+: e9 00 00 00 00 jmp 34 <glob\+0x2f> 30: R_386_PC32 .data
+[ ]*[a-f0-9]+: e9 fc ff ff ff jmp 35 <glob\+0x30> 35: R_386_PC32 \*ABS\*
+[ ]*[a-f0-9]+: e9 c8 ed ff ff jmp ffffee06 <abs2\+0xffff5590> 3a: R_386_PC32 ext
+[ ]*[a-f0-9]+: e9 c8 ed ff ff jmp ffffee0b <abs2\+0xffff5595> 3f: R_386_PC32 weak
+[ ]*[a-f0-9]+: e9 c8 ed ff ff jmp ffffee10 <abs2\+0xffff559a> 44: R_386_PC32 comm
+[ ]*[a-f0-9]+: e9 7f ed ff ff jmp ffffedcc <abs2\+0xffff5556>
+[ ]*[a-f0-9]+: e9 c8 ed ff ff jmp ffffee1a <abs2\+0xffff55a4> 4e: R_386_PC32 glob
+[ ]*[a-f0-9]+: e9 3e 86 00 00 jmp 8695 <abs\+0x7461> 53: R_386_PC32 \*ABS\*
+[ ]*[a-f0-9]+: e9 70 ee ff ff jmp ffffeecc <abs2\+0xffff5656>
+[ ]*[a-f0-9]+: e9 c8 ed ff ff jmp ffffee29 <abs2\+0xffff55b3> 5d: R_386_PC32 glob2
+[ ]*[a-f0-9]+: e9 c8 ed ff ff jmp ffffee2e <abs2\+0xffff55b8> 62: R_386_PC32 .data
+[ ]*[a-f0-9]+: e9 cc ed ff ff jmp ffffee37 <abs2\+0xffff55c1> 67: R_386_PC32 .data
+[ ]*[a-f0-9]+: e9 ba 79 ff ff jmp ffff7a2a <abs2\+0xfffee1b4> 6c: R_386_PC32 \*ABS\*
+[ ]*[a-f0-9]+: e9 86 67 ff ff jmp ffff67fb <abs2\+0xfffecf85> 71: R_386_PC32 ext
+[ ]*[a-f0-9]+: e9 86 67 ff ff jmp ffff6800 <abs2\+0xfffecf8a> 76: R_386_PC32 weak
+[ ]*[a-f0-9]+: e9 86 67 ff ff jmp ffff6805 <abs2\+0xfffecf8f> 7b: R_386_PC32 comm
+[ ]*[a-f0-9]+: e9 06 67 ff ff jmp ffff678a <abs2\+0xfffecf14>
+[ ]*[a-f0-9]+: e9 06 67 ff ff jmp ffff678f <abs2\+0xfffecf19>
+[ ]*[a-f0-9]+: e9 fc ff ff ff jmp 8a <glob\+0x85> 8a: R_386_PC32 \*ABS\*
+[ ]*[a-f0-9]+: e9 f7 67 ff ff jmp ffff688a <abs2\+0xfffed014>
+[ ]*[a-f0-9]+: e9 f7 67 ff ff jmp ffff688f <abs2\+0xfffed019>
+[ ]*[a-f0-9]+: e9 86 67 ff ff jmp ffff6823 <abs2\+0xfffecfad> 99: R_386_PC32 .data
+[ ]*[a-f0-9]+: e9 8a 67 ff ff jmp ffff682c <abs2\+0xfffecfb6> 9e: R_386_PC32 .data
+[ ]*[a-f0-9]+: e9 fc 00 00 00 jmp 1a3 <glob2\+0x9e> a3: R_386_PC32 \*ABS\*
+[ ]*[a-f0-9]+: e9 01 00 00 00 jmp ad <glob\+0xa8> a8: R_386_PC32 \*ABS\*
+[ ]*[a-f0-9]+: e9 01 ff ff ff jmp ffffffb2 <abs2\+0xffff673c> ad: R_386_PC32 \*ABS\*
+[ ]*[a-f0-9]+: e9 01 01 00 00 jmp 1b7 <glob2\+0xb2> b2: R_386_PC32 \*ABS\*
+[ ]*[a-f0-9]+: e9 01 00 00 00 jmp bc <glob\+0xb7> b7: R_386_PC32 \*ABS\*
+ ...
+#pass
+#as: -mshared
#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]+: eb 24 jmp 26 <local>
+[ ]*[a-f0-9]+: eb 1e jmp 22 <hidden_def>
+[ ]*[a-f0-9]+: e9 fc ff ff ff jmp 5 <foo\+0x5> 5: R_386_PC32 global_def
+[ ]*[a-f0-9]+: e9 fc ff ff ff jmp a <foo\+0xa> a: R_386_PLT32 global_def
+[ ]*[a-f0-9]+: e9 fc ff ff ff jmp f <foo\+0xf> f: R_386_PC32 weak_def
+[ ]*[a-f0-9]+: e9 fc ff ff ff jmp 14 <foo\+0x14> 14: R_386_PC32 weak_hidden_undef
+[ ]*[a-f0-9]+: e9 fc ff ff ff jmp 19 <foo\+0x19> 19: R_386_PC32 weak_hidden_def
+[ ]*[a-f0-9]+: e9 fc ff ff ff jmp 1e <foo\+0x1e> 1e: R_386_PC32 hidden_undef
+
+0+22 <hidden_def>:
[ ]*[a-f0-9]+: c3 ret
-0+1e <weak_hidden_def>:
+0+23 <weak_hidden_def>:
[ ]*[a-f0-9]+: c3 ret
-0+1f <global_def>:
+0+24 <global_def>:
[ ]*[a-f0-9]+: c3 ret
-0+20 <weak_def>:
+0+25 <weak_def>:
[ ]*[a-f0-9]+: c3 ret
-0+21 <local>:
+0+26 <local>:
[ ]*[a-f0-9]+: c3 ret
#pass
jmp local
jmp hidden_def
jmp global_def
+ jmp global_def@PLT
jmp weak_def
jmp weak_hidden_undef
jmp weak_hidden_def
--- /dev/null
+#source: relax-3.s
+#objdump: -dwr
+
+.*: +file format .*
+
+Disassembly of section .text:
+
+0+ <foo>:
+[ ]*[a-f0-9]+: eb 21 jmp 23 <local>
+[ ]*[a-f0-9]+: eb 1b jmp 1f <hidden_def>
+[ ]*[a-f0-9]+: eb 1b jmp 21 <global_def>
+[ ]*[a-f0-9]+: e9 fc ff ff ff jmp 7 <foo\+0x7> 7: R_386_PLT32 global_def
+[ ]*[a-f0-9]+: e9 fc ff ff ff jmp c <foo\+0xc> c: R_386_PC32 weak_def
+[ ]*[a-f0-9]+: e9 fc ff ff ff jmp 11 <foo\+0x11> 11: R_386_PC32 weak_hidden_undef
+[ ]*[a-f0-9]+: e9 fc ff ff ff jmp 16 <foo\+0x16> 16: R_386_PC32 weak_hidden_def
+[ ]*[a-f0-9]+: e9 fc ff ff ff jmp 1b <foo\+0x1b> 1b: R_386_PC32 hidden_undef
+
+0+1f <hidden_def>:
+[ ]*[a-f0-9]+: c3 ret
+
+0+20 <weak_hidden_def>:
+[ ]*[a-f0-9]+: c3 ret
+
+0+21 <global_def>:
+[ ]*[a-f0-9]+: c3 ret
+
+0+22 <weak_def>:
+[ ]*[a-f0-9]+: c3 ret
+
+0+23 <local>:
+[ ]*[a-f0-9]+: c3 ret
+#pass
#source: relax-3.s
+#as: -mshared
#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]+: eb 24 jmp 26 <local>
+[ ]*[a-f0-9]+: eb 1e jmp 22 <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
+[ ]*[a-f0-9]+: e9 00 00 00 00 jmpq e <foo\+0xe> a: R_X86_64_PLT32 global_def-0x4
+[ ]*[a-f0-9]+: e9 00 00 00 00 jmpq 13 <foo\+0x13> f: R_X86_64_PC32 weak_def-0x4
+[ ]*[a-f0-9]+: e9 00 00 00 00 jmpq 18 <foo\+0x18> 14: R_X86_64_PC32 weak_hidden_undef-0x4
+[ ]*[a-f0-9]+: e9 00 00 00 00 jmpq 1d <foo\+0x1d> 19: R_X86_64_PC32 weak_hidden_def-0x4
+[ ]*[a-f0-9]+: e9 00 00 00 00 jmpq 22 <hidden_def> 1e: R_X86_64_PC32 hidden_undef-0x4
-0+1d <hidden_def>:
+0+22 <hidden_def>:
[ ]*[a-f0-9]+: c3 retq
-0+1e <weak_hidden_def>:
+0+23 <weak_hidden_def>:
[ ]*[a-f0-9]+: c3 retq
-0+1f <global_def>:
+0+24 <global_def>:
[ ]*[a-f0-9]+: c3 retq
-0+20 <weak_def>:
+0+25 <weak_def>:
[ ]*[a-f0-9]+: c3 retq
-0+21 <local>:
+0+26 <local>:
[ ]*[a-f0-9]+: c3 retq
#pass
--- /dev/null
+#source: relax-3.s
+#objdump: -dwr
+
+.*: +file format .*
+
+
+Disassembly of section .text:
+
+0+ <foo>:
+[ ]*[a-f0-9]+: eb 21 jmp 23 <local>
+[ ]*[a-f0-9]+: eb 1b jmp 1f <hidden_def>
+[ ]*[a-f0-9]+: eb 1b jmp 21 <global_def>
+[ ]*[a-f0-9]+: e9 00 00 00 00 jmpq b <foo\+0xb> 7: R_X86_64_PLT32 global_def-0x4
+[ ]*[a-f0-9]+: e9 00 00 00 00 jmpq 10 <foo\+0x10> c: R_X86_64_PC32 weak_def-0x4
+[ ]*[a-f0-9]+: e9 00 00 00 00 jmpq 15 <foo\+0x15> 11: R_X86_64_PC32 weak_hidden_undef-0x4
+[ ]*[a-f0-9]+: e9 00 00 00 00 jmpq 1a <foo\+0x1a> 16: R_X86_64_PC32 weak_hidden_def-0x4
+[ ]*[a-f0-9]+: e9 00 00 00 00 jmpq 1f <hidden_def> 1b: R_X86_64_PC32 hidden_undef-0x4
+
+0+1f <hidden_def>:
+[ ]*[a-f0-9]+: c3 retq
+
+0+20 <weak_hidden_def>:
+[ ]*[a-f0-9]+: c3 retq
+
+0+21 <global_def>:
+[ ]*[a-f0-9]+: c3 retq
+
+0+22 <weak_def>:
+[ ]*[a-f0-9]+: c3 retq
+
+0+23 <local>:
+[ ]*[a-f0-9]+: c3 retq
+#pass