aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorH.J. Lu <hjl.tools@gmail.com>2015-05-15 03:17:31 -0700
committerH.J. Lu <hjl.tools@gmail.com>2015-05-15 03:30:53 -0700
commit8dcea93252a9ea7dff57e85220a719e2a5e8ab41 (patch)
treec2e6a597a60a10a48c58f9a6e95cb117f65f8fe4
parentd1c4b12b9d48d9266b78e2c22d70aa25830b9f8f (diff)
downloadgdb-8dcea93252a9ea7dff57e85220a719e2a5e8ab41.zip
gdb-8dcea93252a9ea7dff57e85220a719e2a5e8ab41.tar.gz
gdb-8dcea93252a9ea7dff57e85220a719e2a5e8ab41.tar.bz2
Add -mshared option to x86 ELF assembler
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.
-rw-r--r--gas/ChangeLog13
-rw-r--r--gas/config/tc-i386.c35
-rw-r--r--gas/doc/c-i386.texi11
-rw-r--r--gas/testsuite/ChangeLog11
-rw-r--r--gas/testsuite/gas/i386/i386.exp7
-rw-r--r--gas/testsuite/gas/i386/pcrel-elf.d52
-rw-r--r--gas/testsuite/gas/i386/relax-3.d28
-rw-r--r--gas/testsuite/gas/i386/relax-3.s1
-rw-r--r--gas/testsuite/gas/i386/relax-4.d32
-rw-r--r--gas/testsuite/gas/i386/x86-64-relax-2.d24
-rw-r--r--gas/testsuite/gas/i386/x86-64-relax-3.d33
11 files changed, 219 insertions, 28 deletions
diff --git a/gas/ChangeLog b/gas/ChangeLog
index 2b1d99c..9bc4a15 100644
--- a/gas/ChangeLog
+++ b/gas/ChangeLog
@@ -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
diff --git a/gas/config/tc-i386.c b/gas/config/tc-i386.c
index 75f268f..254548f 100644
--- a/gas/config/tc-i386.c
+++ b/gas/config/tc-i386.c
@@ -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"));
diff --git a/gas/doc/c-i386.texi b/gas/doc/c-i386.texi
index 1645c8c..ea08c63 100644
--- a/gas/doc/c-i386.texi
+++ b/gas/doc/c-i386.texi
@@ -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
diff --git a/gas/testsuite/ChangeLog b/gas/testsuite/ChangeLog
index dab5fcf..95b7583 100644
--- a/gas/testsuite/ChangeLog
+++ b/gas/testsuite/ChangeLog
@@ -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.
diff --git a/gas/testsuite/gas/i386/i386.exp b/gas/testsuite/gas/i386/i386.exp
index b6f2810..ff648b0 100644
--- a/gas/testsuite/gas/i386/i386.exp
+++ b/gas/testsuite/gas/i386/i386.exp
@@ -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
index 0000000..e4d45c8
--- /dev/null
+++ b/gas/testsuite/gas/i386/pcrel-elf.d
@@ -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
diff --git a/gas/testsuite/gas/i386/relax-3.d b/gas/testsuite/gas/i386/relax-3.d
index 8aa94e9..4610553 100644
--- a/gas/testsuite/gas/i386/relax-3.d
+++ b/gas/testsuite/gas/i386/relax-3.d
@@ -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
diff --git a/gas/testsuite/gas/i386/relax-3.s b/gas/testsuite/gas/i386/relax-3.s
index ab52185..48ea917 100644
--- a/gas/testsuite/gas/i386/relax-3.s
+++ b/gas/testsuite/gas/i386/relax-3.s
@@ -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
index 0000000..2039251
--- /dev/null
+++ b/gas/testsuite/gas/i386/relax-4.d
@@ -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
diff --git a/gas/testsuite/gas/i386/x86-64-relax-2.d b/gas/testsuite/gas/i386/x86-64-relax-2.d
index 7b0bd56..c124102 100644
--- a/gas/testsuite/gas/i386/x86-64-relax-2.d
+++ b/gas/testsuite/gas/i386/x86-64-relax-2.d
@@ -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
index 0000000..98fd28d
--- /dev/null
+++ b/gas/testsuite/gas/i386/x86-64-relax-3.d
@@ -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