]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
x86: widen @got{,pcrel} support to PUSH and APX IMUL
authorJan Beulich <jbeulich@suse.com>
Fri, 21 Feb 2025 09:24:50 +0000 (10:24 +0100)
committerJan Beulich <jbeulich@suse.com>
Fri, 21 Feb 2025 09:24:50 +0000 (10:24 +0100)
With us doing the transformation to an immediate operand for MOV and
various ALU insns, there's little reason to then not support the same
conversion for the other two insns which have respective immediate
operand forms. Unfortunately for IMUL (due to the 0F opcode prefix)
there's no suitable relocation, so the pre-APX forms cannot be marked
for relaxation in the assembler.

15 files changed:
bfd/elf32-i386.c
bfd/elf64-x86-64.c
gas/config/tc-i386.c
ld/testsuite/ld-i386/i386.exp
ld/testsuite/ld-i386/load9.s [new file with mode: 0644]
ld/testsuite/ld-i386/load9a.d [new file with mode: 0644]
ld/testsuite/ld-i386/load9b.d [new file with mode: 0644]
ld/testsuite/ld-x86-64/apx-load1.s
ld/testsuite/ld-x86-64/apx-load1a.d
ld/testsuite/ld-x86-64/apx-load1c.d
ld/testsuite/ld-x86-64/apx-load1d.d
ld/testsuite/ld-x86-64/load5.s [new file with mode: 0644]
ld/testsuite/ld-x86-64/load5a.d [new file with mode: 0644]
ld/testsuite/ld-x86-64/load5b.d [new file with mode: 0644]
ld/testsuite/ld-x86-64/x86-64.exp

index ca82016fafc6ef9f872516c8b1c3b1cc8fc55a76..77ae13527a880fbea65f7e2f95f1b950226451be 100644 (file)
@@ -1209,6 +1209,10 @@ elf_i386_tls_transition (struct bfd_link_info *info, bfd *abfd,
    to
    test $foo, %reg1
    and convert
+   push foo@GOT[(%reg)]
+   to
+   push $foo
+   and convert
    binop foo@GOT[(%reg1)], %reg2
    to
    binop $foo, %reg2
@@ -1233,7 +1237,7 @@ elf_i386_convert_load_reloc (bfd *abfd, Elf_Internal_Shdr *symtab_hdr,
   unsigned int addend;
   unsigned int nop;
   bfd_vma nop_offset;
-  bool is_pic;
+  bool is_pic, is_branch = false;
   bool to_reloc_32;
   bool abs_symbol;
   unsigned int r_type;
@@ -1301,6 +1305,23 @@ elf_i386_convert_load_reloc (bfd *abfd, Elf_Internal_Shdr *symtab_hdr,
 
   opcode = bfd_get_8 (abfd, contents + roff - 2);
 
+  if (opcode == 0xff)
+    {
+      switch (modrm & 0x38)
+       {
+       case 0x10: /* CALL */
+       case 0x20: /* JMP */
+         is_branch = true;
+         break;
+
+       case 0x30: /* PUSH */
+         break;
+
+       default:
+         return true;
+       }
+    }
+
   /* Convert to R_386_32 if PIC is false or there is no base
      register.  */
   to_reloc_32 = !is_pic || baseless;
@@ -1311,7 +1332,7 @@ elf_i386_convert_load_reloc (bfd *abfd, Elf_Internal_Shdr *symtab_hdr,
      reloc.  */
   if (h == NULL)
     {
-      if (opcode == 0x0ff)
+      if (is_branch)
        /* Convert "call/jmp *foo@GOT[(%reg)]".  */
        goto convert_branch;
       else
@@ -1327,7 +1348,7 @@ elf_i386_convert_load_reloc (bfd *abfd, Elf_Internal_Shdr *symtab_hdr,
       && !eh->linker_def
       && local_ref)
     {
-      if (opcode == 0xff)
+      if (is_branch)
        {
          /* No direct branch to 0 for PIC.  */
          if (is_pic)
@@ -1343,7 +1364,7 @@ elf_i386_convert_load_reloc (bfd *abfd, Elf_Internal_Shdr *symtab_hdr,
        }
     }
 
-  if (opcode == 0xff)
+  if (is_branch)
     {
       /* We have "call/jmp *foo@GOT[(%reg)]".  */
       if ((h->root.type == bfd_link_hash_defined
@@ -1399,7 +1420,8 @@ elf_i386_convert_load_reloc (bfd *abfd, Elf_Internal_Shdr *symtab_hdr,
   else
     {
       /* We have "mov foo@GOT[(%re1g)], %reg2",
-        "test %reg1, foo@GOT(%reg2)" and
+        "test %reg1, foo@GOT(%reg2)",
+        "push foo@GOT[(%reg)]", or
         "binop foo@GOT[(%reg1)], %reg2".
 
         Avoid optimizing _DYNAMIC since ld.so may use its
@@ -1460,6 +1482,13 @@ elf_i386_convert_load_reloc (bfd *abfd, Elf_Internal_Shdr *symtab_hdr,
                  modrm = 0xc0 | ((modrm & 0x38) >> 3) | (opcode & 0x38);
                  opcode = 0x81;
                }
+             else if (opcode == 0xff)
+               {
+                 /* Convert "push foo@GOT(%reg)" to
+                    "push $foo".  */
+                 modrm = 0x68; /* Really the opcode.  */
+                 opcode = 0x2e; /* Really a meaningless %cs: prefix.  */
+               }
              else
                return true;
 
index 5accb752a43fd7ac0bf1a938944b8aa1203c542a..3d68f97ad790e8496f0aba0952e0e676a0d6b3c4 100644 (file)
@@ -1739,13 +1739,16 @@ elf_x86_64_need_pic (struct bfd_link_info *info,
 }
 
 /* Move the R bits to the B bits in EVEX payload byte 1.  */
-static unsigned int evex_move_r_to_b (unsigned int byte1)
+static unsigned int evex_move_r_to_b (unsigned int byte1, bool copy)
 {
   byte1 = (byte1 & ~(1 << 5)) | ((byte1 & (1 << 7)) >> 2); /* R3 -> B3 */
   byte1 = (byte1 & ~(1 << 3)) | ((~byte1 & (1 << 4)) >> 1); /* R4 -> B4 */
 
   /* Set both R bits, as they're inverted.  */
-  return byte1 | (1 << 4) | (1 << 7);
+  if (!copy)
+    byte1 |= (1 << 4) | (1 << 7);
+
+  return byte1;
 }
 
 /* With the local symbol, foo, we convert
@@ -1762,10 +1765,14 @@ static unsigned int evex_move_r_to_b (unsigned int byte1)
    to
    test $foo, %reg
    and convert
+   push foo@GOTPCREL(%rip)
+   to
+   push $foo
+   and convert
    binop foo@GOTPCREL(%rip), %reg
    to
    binop $foo, %reg
-   where binop is one of adc, add, and, cmp, or, sbb, sub, xor
+   where binop is one of adc, add, and, cmp, imul, or, sbb, sub, xor
    instructions.  */
 
 static bool
@@ -1782,6 +1789,7 @@ elf_x86_64_convert_load_reloc (bfd *abfd,
   bool is_pic;
   bool no_overflow;
   bool relocx;
+  bool is_branch = false;
   bool to_reloc_pc32;
   bool abs_symbol;
   bool local_ref;
@@ -1878,6 +1886,23 @@ elf_x86_64_convert_load_reloc (bfd *abfd,
   r_symndx = htab->r_sym (irel->r_info);
 
   opcode = bfd_get_8 (abfd, contents + roff - 2);
+  modrm = bfd_get_8 (abfd, contents + roff - 1);
+  if (opcode == 0xff)
+    {
+      switch (modrm & 0x38)
+       {
+       case 0x10: /* CALL */
+       case 0x20: /* JMP */
+         is_branch = true;
+         break;
+
+       case 0x30: /* PUSH */
+         break;
+
+       default:
+         return true;
+       }
+    }
 
   /* Convert mov to lea since it has been done for a while.  */
   if (opcode != 0x8b)
@@ -1895,7 +1920,7 @@ elf_x86_64_convert_load_reloc (bfd *abfd,
      3. no_overflow is true.
      4. PIC.
      */
-  to_reloc_pc32 = (opcode == 0xff
+  to_reloc_pc32 = (is_branch
                   || !relocx
                   || no_overflow
                   || is_pic);
@@ -1950,7 +1975,7 @@ elf_x86_64_convert_load_reloc (bfd *abfd,
              && !eh->linker_def
              && local_ref))
        {
-         if (opcode == 0xff)
+         if (is_branch)
            {
              /* Skip for branch instructions since R_X86_64_PC32
                 may overflow.  */
@@ -2055,7 +2080,7 @@ elf_x86_64_convert_load_reloc (bfd *abfd,
   else
     relocation = 0;
 
-  if (opcode == 0xff)
+  if (is_branch)
     {
       /* We have "call/jmp *foo@GOTPCREL(%rip)".  */
       unsigned int nop;
@@ -2074,7 +2099,6 @@ elf_x86_64_convert_load_reloc (bfd *abfd,
 
       /* Convert R_X86_64_GOTPCRELX and R_X86_64_REX_GOTPCRELX to
         R_X86_64_PC32.  */
-      modrm = bfd_get_8 (abfd, contents + roff - 1);
       if (modrm == 0x25)
        {
          /* Convert to "jmp foo nop".  */
@@ -2119,11 +2143,12 @@ elf_x86_64_convert_load_reloc (bfd *abfd,
     }
   else if (r_type == R_X86_64_CODE_6_GOTPCRELX && opcode != 0x8b)
     {
+      bool move_v_r = false;
+
       /* R_X86_64_PC32 isn't supported.  */
       if (to_reloc_pc32)
        return true;
 
-      modrm = bfd_get_8 (abfd, contents + roff - 1);
       if (opcode == 0x85)
        {
          /* Convert "ctest<cc> %reg, foo@GOTPCREL(%rip)" to
@@ -2149,6 +2174,23 @@ elf_x86_64_convert_load_reloc (bfd *abfd,
          modrm = 0xc0 | ((modrm & 0x38) >> 3) | (opcode & 0x38);
          opcode = 0x81;
        }
+      else if (opcode == 0xaf)
+       {
+         if (!(evex[2] & 0x10))
+           {
+             /* Convert "imul foo@GOTPCREL(%rip), %reg" to
+                "imul $foo, %reg, %reg".  */
+             modrm = 0xc0 | ((modrm & 0x38) >> 3) | (modrm & 0x38);
+           }
+         else
+           {
+             /* Convert "imul foo@GOTPCREL(%rip), %reg1, %reg2" to
+                "imul $foo, %reg1, %reg2".  */
+             modrm = 0xc0 | ((modrm & 0x38) >> 3) | (~evex[1] & 0x38);
+             move_v_r = true;
+           }
+         opcode = 0x69;
+       }
       else
        return true;
 
@@ -2182,7 +2224,23 @@ elf_x86_64_convert_load_reloc (bfd *abfd,
       bfd_put_8 (abfd, opcode, contents + roff - 2);
       bfd_put_8 (abfd, modrm, contents + roff - 1);
 
-      evex[0] = evex_move_r_to_b (evex[0]);
+      evex[0] = evex_move_r_to_b (evex[0], opcode == 0x69 && !move_v_r);
+      if (move_v_r)
+       {
+         /* Move the top two V bits to the R bits in EVEX payload byte 1.
+            Note that evex_move_r_to_b() set both R bits.  */
+         if (!(evex[1] & (1 << 6)))
+           evex[0] &= ~(1 << 7); /* V3 -> R3 */
+         if (!(evex[2] & (1 << 3)))
+           evex[0] &= ~(1 << 4); /* V4 -> R4 */
+         /* Set all V bits, as they're inverted.  */
+         evex[1] |= 0xf << 3;
+         evex[2] |= 1 << 3;
+         /* Clear the ND (ZU) bit (it ought to be ignored anyway).  */
+         evex[2] &= ~(1 << 4);
+         bfd_put_8 (abfd, evex[2], contents + roff - 3);
+         bfd_put_8 (abfd, evex[1], contents + roff - 4);
+       }
       bfd_put_8 (abfd, evex[0], contents + roff - 5);
 
       /* No addend for R_X86_64_32/R_X86_64_32S relocations.  */
@@ -2225,7 +2283,10 @@ elf_x86_64_convert_load_reloc (bfd *abfd,
        {
          if (bfd_get_8 (abfd, contents + roff - 4) == 0xd5)
            {
-             rex2 = bfd_get_8 (abfd, contents + roff - 3);
+             /* Make sure even an all-zero payload leaves a non-zero value
+                in the variable.  */
+             rex2 = bfd_get_8 (abfd, contents + roff - 3) | 0x100;
+             rex2_mask |= 0x100;
              rex_w = (rex2 & REX_W) != 0;
            }
          else if (bfd_get_8 (abfd, contents + roff - 4) == 0x0f)
@@ -2267,7 +2328,6 @@ elf_x86_64_convert_load_reloc (bfd *abfd,
              /* Convert "mov foo@GOTPCREL(%rip), %reg" to
                 "mov $foo, %reg".  */
              opcode = 0xc7;
-             modrm = bfd_get_8 (abfd, contents + roff - 1);
              modrm = 0xc0 | (modrm & 0x38) >> 3;
              if (rex_w && ABI_64_P (link_info->output_bfd))
                {
@@ -2294,7 +2354,6 @@ elf_x86_64_convert_load_reloc (bfd *abfd,
          if (to_reloc_pc32)
            return true;
 
-         modrm = bfd_get_8 (abfd, contents + roff - 1);
          if (opcode == 0x85)
            {
              /* Convert "test %reg, foo@GOTPCREL(%rip)" to
@@ -2309,6 +2368,39 @@ elf_x86_64_convert_load_reloc (bfd *abfd,
              modrm = 0xc0 | ((modrm & 0x38) >> 3) | (opcode & 0x38);
              opcode = 0x81;
            }
+         else if (opcode == 0xaf && (rex2 & (REX2_M << 4)))
+           {
+             /* Convert "imul foo@GOTPCREL(%rip), %reg" to
+                "imul $foo, %reg, %reg".  */
+             modrm = 0xc0 | ((modrm & 0x38) >> 3) | (modrm & 0x38);
+             rex_mask = 0;
+             rex2_mask = REX2_M << 4;
+             opcode = 0x69;
+           }
+         else if (opcode == 0xff && !(rex2 & (REX2_M << 4)))
+           {
+             /* Convert "push foo@GOTPCREL(%rip)" to
+                "push $foo".  */
+             bfd_put_8 (abfd, 0x68, contents + roff - 1);
+             if (rex)
+               {
+                 bfd_put_8 (abfd, 0x2e, contents + roff - 3);
+                 bfd_put_8 (abfd, rex, contents + roff - 2);
+               }
+             else if (rex2)
+               {
+                 bfd_put_8 (abfd, 0x2e, contents + roff - 4);
+                 bfd_put_8 (abfd, 0xd5, contents + roff - 3);
+                 bfd_put_8 (abfd, rex2, contents + roff - 2);
+               }
+             else
+               bfd_put_8 (abfd, 0x2e, contents + roff - 2);
+
+             r_type = R_X86_64_32S;
+             /* No addend for R_X86_64_32S relocations.  */
+             irel->r_addend = 0;
+             goto finish;
+           }
          else
            return true;
 
@@ -2377,6 +2469,7 @@ elf_x86_64_convert_load_reloc (bfd *abfd,
        }
     }
 
+ finish:
   *r_type_p = r_type;
   irel->r_info = htab->r_info (r_symndx,
                               r_type | R_X86_64_converted_reloc_bit);
@@ -4467,7 +4560,7 @@ elf_x86_64_relocate_section (bfd *output_bfd,
                      continue;
                    }
 
-                 byte1 = evex_move_r_to_b (byte1);
+                 byte1 = evex_move_r_to_b (byte1, false);
                  bfd_put_8 (output_bfd, byte1, contents + roff - 5);
                  bfd_put_8 (output_bfd, 0x81, contents + roff - 2);
                  bfd_put_8 (output_bfd, 0xc0 | reg, contents + roff - 1);
index 53743fb4d7fbd37a90c4fae84cb58e06f5f3cbde..d44efe8050974c0382a127d8db9778ffdff74b3d 100644 (file)
@@ -12932,9 +12932,9 @@ output_disp (fragS *insn_start_frag, offsetT insn_start_off)
              else if (object_64bit)
                continue;
 
-             /* Check for "call/jmp *mem", "mov mem, %reg", "movrs mem, %reg",
-                "test %reg, mem" and "binop mem, %reg" where binop
-                is one of adc, add, and, cmp, or, sbb, sub, xor
+             /* Check for "call/jmp *mem", "push mem", "mov mem, %reg",
+                "movrs mem, %reg", "test %reg, mem" and "binop mem, %reg" where
+                binop is one of adc, add, and, cmp, or, sbb, sub, xor, or imul
                 instructions without data prefix.  Always generate
                 R_386_GOT32X for "sym*GOT" operand in 32-bit mode.  */
              unsigned int space = dot_insn () ? i.insn_opcode_space
@@ -12944,7 +12944,7 @@ output_disp (fragS *insn_start_frag, offsetT insn_start_off)
                      || (i.rm.mode == 0 && i.rm.regmem == 5))
                  && ((space == SPACE_BASE
                       && i.tm.base_opcode == 0xff
-                      && (i.rm.reg == 2 || i.rm.reg == 4))
+                      && (i.rm.reg == 2 || i.rm.reg == 4 || i.rm.reg == 6))
                      || ((space == SPACE_BASE
                           || space == SPACE_0F38
                           || space == SPACE_MAP4)
@@ -12953,7 +12953,13 @@ output_disp (fragS *insn_start_frag, offsetT insn_start_off)
                           || space == SPACE_MAP4)
                          && (i.tm.base_opcode == 0x85
                              || (i.tm.base_opcode
-                                 | (i.operands > 2 ? 0x3a : 0x38)) == 0x3b))))
+                                 | (i.operands > 2 ? 0x3a : 0x38)) == 0x3b))
+                     || (((space == SPACE_0F
+                           /* Because of the 0F prefix, no suitable relocation
+                              exists for this unless it's REX2-encoded.  */
+                           && is_apx_rex2_encoding ())
+                          || space == SPACE_MAP4)
+                         && i.tm.base_opcode == 0xaf)))
                {
                  if (object_64bit)
                    {
index f84b4d4fe59a93b86601e1033c805393964cdc34..dc91f6b2aed0c4e973251c48a43c77dcefe7ad66 100644 (file)
@@ -374,6 +374,8 @@ run_dump_test "load5b"
 run_dump_test "load6"
 run_dump_test "load7"
 run_dump_test "load8"
+run_dump_test "load9a"
+run_dump_test "load9b"
 run_dump_test "pr19175"
 run_dump_test "pr19615"
 run_dump_test "pr19636-1a"
diff --git a/ld/testsuite/ld-i386/load9.s b/ld/testsuite/ld-i386/load9.s
new file mode 100644 (file)
index 0000000..0f42268
--- /dev/null
@@ -0,0 +1,20 @@
+       .data
+       .type   bar, @object
+bar:
+       .byte   1
+       .size   bar, .-bar
+       .globl  foo
+       .type   foo, @object
+foo:
+       .byte   1
+       .size   foo, .-foo
+       .text
+       .globl  _start
+       .type   _start, @function
+_start:
+       push    bar@GOT(%ecx)
+       push    foo@GOT(%edx)
+       .ifndef PIC
+       push    foo@GOT
+       .endif
+       .size   _start, .-_start
diff --git a/ld/testsuite/ld-i386/load9a.d b/ld/testsuite/ld-i386/load9a.d
new file mode 100644 (file)
index 0000000..77a27b4
--- /dev/null
@@ -0,0 +1,14 @@
+#source: load9.s
+#as: --32 -mrelax-relocations=yes
+#ld: -melf_i386 -z noseparate-code
+#objdump: -dw
+
+.*: +file format .*
+
+Disassembly of section .text:
+
+0+8048074 <_start>:
+[      ]*[a-f0-9]+:    2e 68 86 90 04 08       cs push \$0x8049086
+[      ]*[a-f0-9]+:    2e 68 87 90 04 08       cs push \$0x8049087
+[      ]*[a-f0-9]+:    2e 68 87 90 04 08       cs push \$0x8049087
+#pass
diff --git a/ld/testsuite/ld-i386/load9b.d b/ld/testsuite/ld-i386/load9b.d
new file mode 100644 (file)
index 0000000..f3b1c71
--- /dev/null
@@ -0,0 +1,13 @@
+#source: load9.s
+#as: --32 -mshared -mrelax-relocations=yes --defsym PIC=1
+#ld: -melf_i386 -shared -z noseparate-code
+#objdump: -dw
+
+.*: +file format .*
+
+Disassembly of section .text:
+
+0+[0-9a-f]+ <_start>:
+[      ]*[0-9a-f]+:    ff b1 f8 ff ff ff       push   -0x8\(%ecx\)
+[      ]*[0-9a-f]+:    ff b2 fc ff ff ff       push   -0x4\(%edx\)
+#pass
index 7cd39f6af3eeb2b9362d1d63e4c3411b669b5427..58777020d53340b7870e075056d3f786488396b0 100644 (file)
@@ -118,5 +118,11 @@ _start:
        sub     %rbp, bar@GOTPCREL(%rip), %r21
        xor     %rsi, bar@GOTPCREL(%rip), %r22
 
+       imul    bar@GOTPCREL(%rip), %r17
+       {nf} imul bar@GOTPCREL(%rip), %r17
+       imul    bar@GOTPCREL(%rip), %r17, %rdx
+       imul    bar@GOTPCREL(%rip), %rcx, %r18
+       {rex2} pushq bar@GOTPCREL(%rip)
+
        .size   _start, .-_start
        .p2align 12, 0x90
index 83d4cd218bb30cdb2d6d18a9b3575ddae77f0545..87ec931274a7544a57ecd9610ec7db8403a7b057 100644 (file)
@@ -115,4 +115,9 @@ Disassembly of section .text:
  +[a-f0-9]+:   62 f4 dc 10 19 25 74 0c 20 00   sbb    %rsp,0x200c74\(%rip\),%r20        # 602000 <.*>
  +[a-f0-9]+:   62 f4 d4 10 29 2d 6a 0c 20 00   sub    %rbp,0x200c6a\(%rip\),%r21        # 602000 <.*>
  +[a-f0-9]+:   62 f4 cc 10 81 f6 20 20 60 00   xor    \$0x602020,%rsi,%r22
+ +[a-f0-9]+:   d5 58 69 c9 20 20 60 00         imul   \$0x602020,%r17,%r17
+ +[a-f0-9]+:   62 ec fc 0c 69 c9 20 20 60 00   \{nf\} imul \$0x602020,%r17,%r17
+ +[a-f0-9]+:   62 fc fc 08 69 d1 20 20 60 00   imul   \$0x602020,%r17,%rdx
+ +[a-f0-9]+:   62 e4 fc 08 69 d1 20 20 60 00   imul   \$0x602020,%rcx,%r18
+ +[a-f0-9]+:   2e d5 00 68 20 20 60 00         cs \{rex2 0x0\} push \$0x602020
 #pass
index 2f80337c5d1af6adc4e9366317a934d06f84df0f..68cda54b4991670d0bcf4fb239e24fc03c29c9fb 100644 (file)
@@ -108,4 +108,9 @@ Disassembly of section .text:
  +[a-f0-9]+:   62 f4 dc 10 19 25 54 0d 20 00   sbb    %rsp,0x200d54\(%rip\),%r20        # 2020e0 <.*>
  +[a-f0-9]+:   62 f4 d4 10 29 2d 4a 0d 20 00   sub    %rbp,0x200d4a\(%rip\),%r21        # 2020e0 <.*>
  +[a-f0-9]+:   62 f4 cc 10 31 35 40 0d 20 00   xor    %rsi,0x200d40\(%rip\),%r22        # 2020e0 <.*>
+ +[a-f0-9]+:   d5 c8 af 0d 38 0d 20 00         imul   0x200d38\(%rip\),%r17        # 2020e0 <.*>
+ +[a-f0-9]+:   62 e4 fc 0c af 0d 2e 0d 20 00   \{nf\} imul 0x200d2e\(%rip\),%r17        # 2020e0 <.*>
+ +[a-f0-9]+:   62 e4 ec 18 af 0d 24 0d 20 00   imul   0x200d24\(%rip\),%r17,%rdx        # 2020e0 <.*>
+ +[a-f0-9]+:   62 f4 ec 10 af 0d 1a 0d 20 00   imul   0x200d1a\(%rip\),%rcx,%r18        # 2020e0 <.*>
+ +[a-f0-9]+:   d5 00 ff 35 12 0d 20 00         \{rex2 0x0\} push 0x200d12\(%rip\)        # 2020e0 <.*>
 #pass
index 648368fb7e1377617ab13130676c8741332f1897..cc0cf92da476a81243447100c403a7e14f79ddec 100644 (file)
@@ -108,4 +108,9 @@ Disassembly of section .text:
  +[a-f0-9]+:   62 f4 dc 10 19 25 e4 0c 20 00   sbb    %rsp,0x200ce4\(%rip\),%r20        # 202070 <.*>
  +[a-f0-9]+:   62 f4 d4 10 29 2d da 0c 20 00   sub    %rbp,0x200cda\(%rip\),%r21        # 202070 <.*>
  +[a-f0-9]+:   62 f4 cc 10 31 35 d0 0c 20 00   xor    %rsi,0x200cd0\(%rip\),%r22        # 202070 <.*>
+ +[a-f0-9]+:   d5 c8 af 0d c8 0c 20 00         imul   0x200cc8\(%rip\),%r17        # 202070 <.*>
+ +[a-f0-9]+:   62 e4 fc 0c af 0d be 0c 20 00   \{nf\} imul 0x200cbe\(%rip\),%r17        # 202070 <.*>
+ +[a-f0-9]+:   62 e4 ec 18 af 0d b4 0c 20 00   imul   0x200cb4\(%rip\),%r17,%rdx        # 202070 <.*>
+ +[a-f0-9]+:   62 f4 ec 10 af 0d aa 0c 20 00   imul   0x200caa\(%rip\),%rcx,%r18        # 202070 <.*>
+ +[a-f0-9]+:   d5 00 ff 35 a2 0c 20 00         \{rex2 0x0\} push 0x200ca2\(%rip\)        # 202070 <.*>
 #pass
diff --git a/ld/testsuite/ld-x86-64/load5.s b/ld/testsuite/ld-x86-64/load5.s
new file mode 100644 (file)
index 0000000..61f06e9
--- /dev/null
@@ -0,0 +1,17 @@
+       .data
+       .type   bar, @object
+bar:
+       .byte   1
+       .size   bar, .-bar
+       .globl  foo
+       .type   foo, @object
+foo:
+       .byte   1
+       .size   foo, .-foo
+       .text
+       .globl  _start
+       .type   _start, @function
+_start:
+             pushq     bar@GOTPCREL(%rip)
+       {rex} pushq     foo@GOTPCREL(%rip)
+       .size   _start, .-_start
diff --git a/ld/testsuite/ld-x86-64/load5a.d b/ld/testsuite/ld-x86-64/load5a.d
new file mode 100644 (file)
index 0000000..ae58af7
--- /dev/null
@@ -0,0 +1,15 @@
+#source: load5.s
+#as: --64 -mrelax-relocations=yes
+#ld: -melf_x86_64
+#objdump: -dw
+
+.*: +file format .*
+
+
+Disassembly of section .text:
+
+#...
+[a-f0-9]+ <_start>:
+[      ]*[a-f0-9]+:    2e 68 ([0-9a-f]{2} ){4} *       cs push \$0x[a-f0-9]+
+[      ]*[a-f0-9]+:    2e 40 68 ([0-9a-f]{2} ){4} *    cs rex push \$0x[a-f0-9]+
+#pass
diff --git a/ld/testsuite/ld-x86-64/load5b.d b/ld/testsuite/ld-x86-64/load5b.d
new file mode 100644 (file)
index 0000000..3dd2d75
--- /dev/null
@@ -0,0 +1,15 @@
+#source: load5.s
+#as: --64 -mrelax-relocations=yes
+#ld: -shared -melf_x86_64
+#objdump: -dw
+
+.*: +file format .*
+
+
+Disassembly of section .text:
+
+#...
+[a-f0-9]+ <_start>:
+[      ]*[a-f0-9]+:    ff 35 ([0-9a-f]{2} ){4} *       push +0x[a-f0-9]+\(%rip\)        # [a-f0-9]+ <.*>
+[      ]*[a-f0-9]+:    40 ff 35 ([0-9a-f]{2} ){4} *    rex push 0x[a-f0-9]+\(%rip\)        # [a-f0-9]+ <.*>
+#pass
index e4b9ebb033c483e1b31a6fbcb86beae2be5e4c20..01d6459b5d79c03de4587e009284cb1433361fad 100644 (file)
@@ -673,6 +673,8 @@ run_dump_test "load2"
 run_dump_test "load3a"
 run_dump_test "load3b"
 run_dump_test "load4"
+run_dump_test "load5a"
+run_dump_test "load5b"
 run_dump_test "call1a"
 run_dump_test "call1b"
 run_dump_test "call1c"