Add -mshared option to x86 ELF assembler
authorH.J. Lu <hjl.tools@gmail.com>
Fri, 15 May 2015 10:17:31 +0000 (03:17 -0700)
committerH.J. Lu <hjl.tools@gmail.com>
Fri, 15 May 2015 10:30:53 +0000 (03:30 -0700)
This patch adds -mshared option to x86 ELF assembler.  By default,
assembler will optimize out non-PLT relocations against defined non-weak
global branch targets with default visibility.  The -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.

This Linux kernel patch is needed to create a working x86 Linux kernel if
it hasn't been applied:

diff --git a/arch/x86/kernel/head_64.S b/arch/x86/kernel/head_64.S
index ae6588b..b91a00c 100644
--- a/arch/x86/kernel/head_64.S
+++ b/arch/x86/kernel/head_64.S
@@ -339,8 +339,8 @@ early_idt_handlers:
  i = i + 1
  .endr

-/* This is global to keep gas from relaxing the jumps */
-ENTRY(early_idt_handler)
+/* This is weak to keep gas from relaxing the jumps */
+WEAK(early_idt_handler)
  cld

  cmpl $2,(%rsp) # X86_TRAP_NMI
--

gas/

* 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.

gas/testsuite/

* 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.

gas/ChangeLog
gas/config/tc-i386.c
gas/doc/c-i386.texi
gas/testsuite/ChangeLog
gas/testsuite/gas/i386/i386.exp
gas/testsuite/gas/i386/pcrel-elf.d [new file with mode: 0644]
gas/testsuite/gas/i386/relax-3.d
gas/testsuite/gas/i386/relax-3.s
gas/testsuite/gas/i386/relax-4.d [new file with mode: 0644]
gas/testsuite/gas/i386/x86-64-relax-2.d
gas/testsuite/gas/i386/x86-64-relax-3.d [new file with mode: 0644]

index 2b1d99c94d1febaec2c8650a33842c4bf1d97fe2..9bc4a157b0a4066136094219e2c948b7752e7638 100644 (file)
@@ -1,3 +1,16 @@
+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
index 75f268f92f0ae2caef33318b51c13a811194d965..254548f21014ba27e22f9f78495cd6eb2dabecf3 100644 (file)
@@ -524,6 +524,11 @@ static enum x86_elf_abi x86_elf_abi = I386_ABI;
 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;
@@ -8818,7 +8823,7 @@ i386_frag_max_var (fragS *frag)
 
 #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
@@ -8829,9 +8834,24 @@ elf_symbol_resolved_in_segment_p (symbolS *fr_symbol)
     /* 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
 
@@ -8858,7 +8878,8 @@ 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
-         && !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
@@ -9528,6 +9549,7 @@ const char *md_shortopts = "qn";
 #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[] =
 {
@@ -9538,6 +9560,7 @@ 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},
@@ -9598,6 +9621,10 @@ md_parse_option (int c, char *arg)
       /* -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))
@@ -10027,6 +10054,8 @@ md_show_usage (FILE *stream)
   -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"));
index 1645c8cba368d55aea672c45a89e8c029bb1a569..ea08c632fe84a77b4052313b9095481e548675bd 100644 (file)
@@ -298,6 +298,17 @@ The @code{.att_syntax} and @code{.intel_syntax} directives will take precedent.
 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
index dab5fcf50a32fb63b115ba64a296fc5ccdf97943..95b7583726689cec9092367dbc4004204a7274b9 100644 (file)
@@ -1,3 +1,14 @@
+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.
index b6f28107460fb10106c09d77c2c89bcac5ef96fb..ff648b04cf421328859b8acec36226f531f1dc9d 100644 (file)
@@ -352,8 +352,10 @@ if [expr ([istarget "i*86-*-*"] ||  [istarget "x86_64-*-*"]) && [gas_32_check]]
        # 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
@@ -361,6 +363,7 @@ if [expr ([istarget "i*86-*-*"] ||  [istarget "x86_64-*-*"]) && [gas_32_check]]
        # 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"
@@ -396,6 +399,7 @@ if [expr ([istarget "i*86-*-*"] ||  [istarget "x86_64-*-*"]) && [gas_32_check]]
        run_dump_test "note"
 
        run_dump_test "relax-3"
+       run_dump_test "relax-4"
 
        if {![istarget "*-*-nacl*"]} then {
            run_dump_test "iamcu-1"
@@ -763,6 +767,7 @@ if [expr ([istarget "i*86-*-*"] || [istarget "x86_64-*-*"]) && [gas_64_check]] t
        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"
     }
diff --git a/gas/testsuite/gas/i386/pcrel-elf.d b/gas/testsuite/gas/i386/pcrel-elf.d
new file mode 100644 (file)
index 0000000..e4d45c8
--- /dev/null
@@ -0,0 +1,52 @@
+#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
index 8aa94e97fecae2ba17b99c7bfbca6cca6496cd7d..4610553e51addb40ef991f38a0566669425fa60f 100644 (file)
@@ -1,3 +1,4 @@
+#as: -mshared
 #objdump: -dwr
 
 .*: +file format .*
@@ -5,26 +6,27 @@
 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
index ab521854f0b17d866ed879d5d14e8a1615a4969c..48ea917df5f45ddc3c31f2b2a4dddd9930e7da4c 100644 (file)
@@ -4,6 +4,7 @@ foo:
        jmp local
        jmp hidden_def
        jmp global_def
+       jmp global_def@PLT
        jmp weak_def
        jmp weak_hidden_undef
        jmp weak_hidden_def
diff --git a/gas/testsuite/gas/i386/relax-4.d b/gas/testsuite/gas/i386/relax-4.d
new file mode 100644 (file)
index 0000000..2039251
--- /dev/null
@@ -0,0 +1,32 @@
+#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
index 7b0bd567b6a0e043700f11840e199be003c68c21..c124102982daf1bbc1a7ad94a35fbec3ad6bedea 100644 (file)
@@ -1,4 +1,5 @@
 #source: relax-3.s
+#as: -mshared
 #objdump: -dwr
 
 .*: +file format .*
@@ -7,26 +8,27 @@
 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
diff --git a/gas/testsuite/gas/i386/x86-64-relax-3.d b/gas/testsuite/gas/i386/x86-64-relax-3.d
new file mode 100644 (file)
index 0000000..98fd28d
--- /dev/null
@@ -0,0 +1,33 @@
+#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