x86-64: always use unsigned 32-bit reloc for 32-bit addressing w/o base reg
authorJan Beulich <jbeulich@novell.com>
Thu, 23 Nov 2017 10:02:30 +0000 (11:02 +0100)
committerJan Beulich <jbeulich@suse.com>
Thu, 23 Nov 2017 10:02:30 +0000 (11:02 +0100)
Except for %eip-relative addressing, where we don't have a suitable
relocation type silently wrapping at the 4G boundary, consistently
force use of R_X86_64_32 (in ELF terms) instead of its sign-extending
counterpart. This wasn't right in case there was no base register in
the addressing expression.

gas/ChangeLog
gas/config/tc-i386.c
gas/testsuite/gas/i386/reloc64.d
gas/testsuite/gas/i386/reloc64.s
ld/ChangeLog
ld/testsuite/ld-x86-64/apic.d [new file with mode: 0644]
ld/testsuite/ld-x86-64/apic.s [new file with mode: 0644]
ld/testsuite/ld-x86-64/x86-64.exp

index d871aa3f9fa605400d4222b4c7b10ef19c73a3f4..fbe7896af3ab0c4e2e55d5f9c47cf3c10b98a953 100644 (file)
@@ -1,3 +1,12 @@
+2017-11-23  Jan Beulich  <jbeulich@suse.com>
+
+       PR gas/22441
+       * config/tc-i386.c (build_modrm_byte): Add address override
+       prefix checks alongside 64-bit mode ones.
+       * testsuite/gas/i386/reloc64.s: Add 32-bit signed/unsigned
+       relocation cases.
+       * testsuite/gas/i386/reloc64.d: Adjust expectations.
+
 2017-11-23  Jan Beulich  <jbeulich@suse.com>
 
        * config/tc-i386.c (build_modrm_byte): Drop VSIB handling from
index e22e74ce4db18560314f79e522a4785215f27e98..4b602d422dc7bf21f3065f24792059322177280a 100644 (file)
@@ -6566,7 +6566,7 @@ build_modrm_byte (void)
                  i.types[op].bitfield.disp8 = 0;
                  i.types[op].bitfield.disp16 = 0;
                  i.types[op].bitfield.disp64 = 0;
-                 if (flag_code != CODE_64BIT)
+                 if (flag_code != CODE_64BIT || i.prefix[ADDR_PREFIX])
                    {
                      /* Must be 32 bit */
                      i.types[op].bitfield.disp32 = 1;
@@ -6636,7 +6636,7 @@ build_modrm_byte (void)
                  i.types[op].bitfield.disp8 = 0;
                  i.types[op].bitfield.disp16 = 0;
                  i.types[op].bitfield.disp64 = 0;
-                 if (flag_code != CODE_64BIT)
+                 if (flag_code != CODE_64BIT || i.prefix[ADDR_PREFIX])
                    {
                      /* Must be 32 bit */
                      i.types[op].bitfield.disp32 = 1;
index ea7f696a6b1b6c9864ac98ed407464192d55ccda..a7fd3d6a3df516e08baa2d056b8d5369dafec698 100644 (file)
@@ -51,6 +51,10 @@ Disassembly of section \.text:
 .*[    ]+R_X86_64_TPOFF32[     ]+xtrn
 .*[    ]+R_X86_64_TPOFF32[     ]+xtrn
 .*[    ]+R_X86_64_GOTPLT64[    ]+xtrn
+.*[    ]+R_X86_64_32S[         ]+xtrn
+.*[    ]+R_X86_64_32[  ]+xtrn
+.*[    ]+R_X86_64_32S[         ]+xtrn
+.*[    ]+R_X86_64_32[  ]+xtrn
 Disassembly of section \.data:
 #...
 .*[    ]+R_X86_64_64[  ]+xtrn
index ecaaef527644049baf0e2fcaa2278a28345f9dc8..0f9c51e4c8d9f4633f45c130688f8fdc61b60504 100644 (file)
@@ -218,3 +218,9 @@ bad call    xtrn@gotplt
 bad    .long   xtrn@gotplt
 bad    .word   xtrn@gotplt
 bad    .byte   xtrn@gotplt
+
+       .text
+       mov     xtrn(,%rbx), %eax
+       mov     xtrn(,%ebx), %eax
+       vgatherdps %xmm2, xtrn(,%xmm1), %xmm0
+       addr32 vgatherdps %xmm2, xtrn(,%xmm1), %xmm0
index 4cfcf6d8ba384b4ddd70b91df54d249b41a37ce3..6ec3260765a7685a25d6256837e3c99e710849da 100644 (file)
@@ -1,3 +1,9 @@
+2017-11-23  Jan Beulich  <jbeulich@suse.com>
+
+       PR gas/22441
+       * testsuite/ld-x86-64/apic.{s,d}: New.
+       * testsuite/ld-x86-64/x86-64.exp: Run new test.
+
 2017-11-21  Nick Clifton  <nickc@redhat.com>
 
        PR 22419
diff --git a/ld/testsuite/ld-x86-64/apic.d b/ld/testsuite/ld-x86-64/apic.d
new file mode 100644 (file)
index 0000000..782c6fa
--- /dev/null
@@ -0,0 +1,18 @@
+#name: 32-bit relocs w/ index but no base
+#ld: --defsym APIC_BASE=0xfee00000
+#objdump: -dw
+
+.*: +file format .*
+
+
+Disassembly of section \.text:
+
+#...
+[0-9a-f]+[     ]+<apic_read>:
+[      ]*[0-9a-f]+:[   ]+67 8b 04 bd 00 00 e0 fe[      ]+mov[  ]+(0xfee|-0x12)00000\(,%edi,4\),%eax
+[      ]*[0-9a-f]+:[   ]+c3[   ]+retq?[        ]*
+#...
+[0-9a-f]+[     ]+<apic_write>:
+[      ]*[0-9a-f]+:[   ]+67 89 34 bd 00 00 e0 fe[      ]+mov[  ]+%esi,(0xfee|-0x12)00000\(,%edi,4\)
+[      ]*[0-9a-f]+:[   ]+c3[   ]+retq?[        ]*
+#pass
diff --git a/ld/testsuite/ld-x86-64/apic.s b/ld/testsuite/ld-x86-64/apic.s
new file mode 100644 (file)
index 0000000..d500799
--- /dev/null
@@ -0,0 +1,13 @@
+       .text
+       .intel_syntax noprefix
+       .global _start
+_start:
+       ret
+
+apic_read:
+       mov     eax, [edi*4+APIC_BASE]
+       ret
+
+apic_write:
+       mov     [edi*4+APIC_BASE], esi
+       ret
index ef2cb1551cfa747b6c69db30667dbf4b16bf95c6..e58d7c89749fa64700ccc80eaf23fc278e72c621 100644 (file)
@@ -267,6 +267,7 @@ if { ![ld_link $ld tmpdir/$test "-m$emul tmpdir/${test}a.o tmpdir/${test}b.o"] }
 
 run_dump_test "abs"
 run_dump_test "abs-l1om"
+run_dump_test "apic"
 run_dump_test "pcrel8"
 run_dump_test "pcrel16"
 run_dump_test "tlsgd2"