From 43083a502b8d658b8d096111e54afcc73b0215a4 Mon Sep 17 00:00:00 2001 From: Jan Beulich Date: Thu, 23 Nov 2017 11:02:30 +0100 Subject: [PATCH] x86-64: always use unsigned 32-bit reloc for 32-bit addressing w/o base reg 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 | 9 +++++++++ gas/config/tc-i386.c | 4 ++-- gas/testsuite/gas/i386/reloc64.d | 4 ++++ gas/testsuite/gas/i386/reloc64.s | 6 ++++++ ld/ChangeLog | 6 ++++++ ld/testsuite/ld-x86-64/apic.d | 18 ++++++++++++++++++ ld/testsuite/ld-x86-64/apic.s | 13 +++++++++++++ ld/testsuite/ld-x86-64/x86-64.exp | 1 + 8 files changed, 59 insertions(+), 2 deletions(-) create mode 100644 ld/testsuite/ld-x86-64/apic.d create mode 100644 ld/testsuite/ld-x86-64/apic.s diff --git a/gas/ChangeLog b/gas/ChangeLog index d871aa3f9f..fbe7896af3 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,3 +1,12 @@ +2017-11-23 Jan Beulich + + 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 * config/tc-i386.c (build_modrm_byte): Drop VSIB handling from diff --git a/gas/config/tc-i386.c b/gas/config/tc-i386.c index e22e74ce4d..4b602d422d 100644 --- a/gas/config/tc-i386.c +++ b/gas/config/tc-i386.c @@ -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; diff --git a/gas/testsuite/gas/i386/reloc64.d b/gas/testsuite/gas/i386/reloc64.d index ea7f696a6b..a7fd3d6a3d 100644 --- a/gas/testsuite/gas/i386/reloc64.d +++ b/gas/testsuite/gas/i386/reloc64.d @@ -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 diff --git a/gas/testsuite/gas/i386/reloc64.s b/gas/testsuite/gas/i386/reloc64.s index ecaaef5276..0f9c51e4c8 100644 --- a/gas/testsuite/gas/i386/reloc64.s +++ b/gas/testsuite/gas/i386/reloc64.s @@ -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 diff --git a/ld/ChangeLog b/ld/ChangeLog index 4cfcf6d8ba..6ec3260765 100644 --- a/ld/ChangeLog +++ b/ld/ChangeLog @@ -1,3 +1,9 @@ +2017-11-23 Jan Beulich + + 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 PR 22419 diff --git a/ld/testsuite/ld-x86-64/apic.d b/ld/testsuite/ld-x86-64/apic.d new file mode 100644 index 0000000000..782c6fa3a7 --- /dev/null +++ b/ld/testsuite/ld-x86-64/apic.d @@ -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]+[ ]+: +[ ]*[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]+[ ]+: +[ ]*[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 index 0000000000..d500799a73 --- /dev/null +++ b/ld/testsuite/ld-x86-64/apic.s @@ -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 diff --git a/ld/testsuite/ld-x86-64/x86-64.exp b/ld/testsuite/ld-x86-64/x86-64.exp index ef2cb1551c..e58d7c8974 100644 --- a/ld/testsuite/ld-x86-64/x86-64.exp +++ b/ld/testsuite/ld-x86-64/x86-64.exp @@ -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" -- 2.34.1