[llvm] r271118 - Fix production of R_X86_64_GOTPCRELX/R_X86_64_REX_GOTPCRELX.
Rafael Espindola via llvm-commits
llvm-commits at lists.llvm.org
Sat May 28 08:51:40 PDT 2016
Author: rafael
Date: Sat May 28 10:51:38 2016
New Revision: 271118
URL: http://llvm.org/viewvc/llvm-project?rev=271118&view=rev
Log:
Fix production of R_X86_64_GOTPCRELX/R_X86_64_REX_GOTPCRELX.
We were producing R_X86_64_GOTPCRELX for invalid instructions and
sometimes producing R_X86_64_GOTPCRELX instead of
R_X86_64_REX_GOTPCRELX.
Added:
llvm/trunk/test/MC/ELF/got-relaxed-no-relax.s
llvm/trunk/test/MC/ELF/got-relaxed-rex.s
Modified:
llvm/trunk/lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp
llvm/trunk/lib/Target/X86/MCTargetDesc/X86ELFObjectWriter.cpp
llvm/trunk/lib/Target/X86/MCTargetDesc/X86FixupKinds.h
llvm/trunk/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp
llvm/trunk/lib/Target/X86/MCTargetDesc/X86MachObjectWriter.cpp
llvm/trunk/test/MC/ELF/got-relaxed.s
Modified: llvm/trunk/lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp?rev=271118&r1=271117&r2=271118&view=diff
==============================================================================
--- llvm/trunk/lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp (original)
+++ llvm/trunk/lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp Sat May 28 10:51:38 2016
@@ -42,6 +42,8 @@ static unsigned getFixupKindLog2Size(uns
return 1;
case FK_PCRel_4:
case X86::reloc_riprel_4byte:
+ case X86::reloc_riprel_4byte_relax:
+ case X86::reloc_riprel_4byte_relax_rex:
case X86::reloc_riprel_4byte_movq_load:
case X86::reloc_signed_4byte:
case X86::reloc_global_offset_table:
@@ -88,6 +90,8 @@ public:
const static MCFixupKindInfo Infos[X86::NumTargetFixupKinds] = {
{"reloc_riprel_4byte", 0, 32, MCFixupKindInfo::FKF_IsPCRel},
{"reloc_riprel_4byte_movq_load", 0, 32, MCFixupKindInfo::FKF_IsPCRel},
+ {"reloc_riprel_4byte_relax", 0, 32, MCFixupKindInfo::FKF_IsPCRel},
+ {"reloc_riprel_4byte_relax_rex", 0, 32, MCFixupKindInfo::FKF_IsPCRel},
{"reloc_signed_4byte", 0, 32, 0},
{"reloc_global_offset_table", 0, 32, 0},
{"reloc_global_offset_table8", 0, 64, 0},
Modified: llvm/trunk/lib/Target/X86/MCTargetDesc/X86ELFObjectWriter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/MCTargetDesc/X86ELFObjectWriter.cpp?rev=271118&r1=271117&r2=271118&view=diff
==============================================================================
--- llvm/trunk/lib/Target/X86/MCTargetDesc/X86ELFObjectWriter.cpp (original)
+++ llvm/trunk/lib/Target/X86/MCTargetDesc/X86ELFObjectWriter.cpp Sat May 28 10:51:38 2016
@@ -68,6 +68,8 @@ static X86_64RelType getType64(unsigned
case FK_Data_4:
case FK_PCRel_4:
case X86::reloc_riprel_4byte:
+ case X86::reloc_riprel_4byte_relax:
+ case X86::reloc_riprel_4byte_relax_rex:
case X86::reloc_riprel_4byte_movq_load:
return RT64_32;
case FK_PCRel_2:
@@ -182,8 +184,9 @@ static unsigned getRelocType64(MCContext
switch (Kind) {
default:
return ELF::R_X86_64_GOTPCREL;
- case X86::reloc_riprel_4byte:
+ case X86::reloc_riprel_4byte_relax:
return ELF::R_X86_64_GOTPCRELX;
+ case X86::reloc_riprel_4byte_relax_rex:
case X86::reloc_riprel_4byte_movq_load:
return ELF::R_X86_64_REX_GOTPCRELX;
}
Modified: llvm/trunk/lib/Target/X86/MCTargetDesc/X86FixupKinds.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/MCTargetDesc/X86FixupKinds.h?rev=271118&r1=271117&r2=271118&view=diff
==============================================================================
--- llvm/trunk/lib/Target/X86/MCTargetDesc/X86FixupKinds.h (original)
+++ llvm/trunk/lib/Target/X86/MCTargetDesc/X86FixupKinds.h Sat May 28 10:51:38 2016
@@ -17,6 +17,10 @@ namespace X86 {
enum Fixups {
reloc_riprel_4byte = FirstTargetFixupKind, // 32-bit rip-relative
reloc_riprel_4byte_movq_load, // 32-bit rip-relative in movq
+ reloc_riprel_4byte_relax, // 32-bit rip-relative in relaxable
+ // instruction
+ reloc_riprel_4byte_relax_rex, // 32-bit rip-relative in relaxable
+ // instruction with rex prefix
reloc_signed_4byte, // 32-bit signed. Unlike FK_Data_4
// this will be sign extended at
// runtime.
Modified: llvm/trunk/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp?rev=271118&r1=271117&r2=271118&view=diff
==============================================================================
--- llvm/trunk/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp (original)
+++ llvm/trunk/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp Sat May 28 10:51:38 2016
@@ -122,11 +122,9 @@ public:
EmitByte(ModRMByte(SS, Index, Base), CurByte, OS);
}
-
- void EmitMemModRMByte(const MCInst &MI, unsigned Op,
- unsigned RegOpcodeField,
- uint64_t TSFlags, unsigned &CurByte, raw_ostream &OS,
- SmallVectorImpl<MCFixup> &Fixups,
+ void emitMemModRMByte(const MCInst &MI, unsigned Op, unsigned RegOpcodeField,
+ uint64_t TSFlags, bool Rex, unsigned &CurByte,
+ raw_ostream &OS, SmallVectorImpl<MCFixup> &Fixups,
const MCSubtargetInfo &STI) const;
void encodeInstruction(const MCInst &MI, raw_ostream &OS,
@@ -140,10 +138,9 @@ public:
void EmitSegmentOverridePrefix(unsigned &CurByte, unsigned SegOperand,
const MCInst &MI, raw_ostream &OS) const;
- void EmitOpcodePrefix(uint64_t TSFlags, unsigned &CurByte, int MemOperand,
+ bool emitOpcodePrefix(uint64_t TSFlags, unsigned &CurByte, int MemOperand,
const MCInst &MI, const MCInstrDesc &Desc,
- const MCSubtargetInfo &STI,
- raw_ostream &OS) const;
+ const MCSubtargetInfo &STI, raw_ostream &OS) const;
uint8_t DetermineREXPrefix(const MCInst &MI, uint64_t TSFlags,
int MemOperand, const MCInstrDesc &Desc) const;
@@ -330,7 +327,9 @@ EmitImmediate(const MCOperand &DispOp, S
// the start of the field, not the end of the field.
if (FixupKind == FK_PCRel_4 ||
FixupKind == MCFixupKind(X86::reloc_riprel_4byte) ||
- FixupKind == MCFixupKind(X86::reloc_riprel_4byte_movq_load))
+ FixupKind == MCFixupKind(X86::reloc_riprel_4byte_movq_load) ||
+ FixupKind == MCFixupKind(X86::reloc_riprel_4byte_relax) ||
+ FixupKind == MCFixupKind(X86::reloc_riprel_4byte_relax_rex))
ImmOffset -= 4;
if (FixupKind == FK_PCRel_2)
ImmOffset -= 2;
@@ -346,12 +345,12 @@ EmitImmediate(const MCOperand &DispOp, S
EmitConstant(0, Size, CurByte, OS);
}
-void X86MCCodeEmitter::EmitMemModRMByte(const MCInst &MI, unsigned Op,
+void X86MCCodeEmitter::emitMemModRMByte(const MCInst &MI, unsigned Op,
unsigned RegOpcodeField,
- uint64_t TSFlags, unsigned &CurByte,
- raw_ostream &OS,
+ uint64_t TSFlags, bool Rex,
+ unsigned &CurByte, raw_ostream &OS,
SmallVectorImpl<MCFixup> &Fixups,
- const MCSubtargetInfo &STI) const{
+ const MCSubtargetInfo &STI) const {
const MCOperand &Disp = MI.getOperand(Op+X86::AddrDisp);
const MCOperand &Base = MI.getOperand(Op+X86::AddrBaseReg);
const MCOperand &Scale = MI.getOperand(Op+X86::AddrScaleAmt);
@@ -366,13 +365,32 @@ void X86MCCodeEmitter::EmitMemModRMByte(
assert(IndexReg.getReg() == 0 && "Invalid rip-relative address");
EmitByte(ModRMByte(0, RegOpcodeField, 5), CurByte, OS);
- unsigned FixupKind = X86::reloc_riprel_4byte;
-
+ unsigned Opcode = MI.getOpcode();
// movq loads are handled with a special relocation form which allows the
// linker to eliminate some loads for GOT references which end up in the
// same linkage unit.
- if (MI.getOpcode() == X86::MOV64rm)
- FixupKind = X86::reloc_riprel_4byte_movq_load;
+ unsigned FixupKind = [=]() {
+ switch (Opcode) {
+ default:
+ return X86::reloc_riprel_4byte;
+ case X86::MOV64rm:
+ assert(Rex);
+ return X86::reloc_riprel_4byte_movq_load;
+ case X86::CALL64m:
+ case X86::JMP64m:
+ case X86::TEST64rm:
+ case X86::ADC64rm:
+ case X86::ADD64rm:
+ case X86::AND64rm:
+ case X86::CMP64rm:
+ case X86::OR64rm:
+ case X86::SBB64rm:
+ case X86::SUB64rm:
+ case X86::XOR64rm:
+ return Rex ? X86::reloc_riprel_4byte_relax_rex
+ : X86::reloc_riprel_4byte_relax;
+ }
+ }();
// rip-relative addressing is actually relative to the *next* instruction.
// Since an immediate can follow the mod/rm byte for an instruction, this
@@ -1027,16 +1045,18 @@ void X86MCCodeEmitter::EmitSegmentOverri
}
}
-/// EmitOpcodePrefix - Emit all instruction prefixes prior to the opcode.
+/// Emit all instruction prefixes prior to the opcode.
///
/// MemOperand is the operand # of the start of a memory operand if present. If
/// Not present, it is -1.
-void X86MCCodeEmitter::EmitOpcodePrefix(uint64_t TSFlags, unsigned &CurByte,
+///
+/// Returns true if a REX prefix was used.
+bool X86MCCodeEmitter::emitOpcodePrefix(uint64_t TSFlags, unsigned &CurByte,
int MemOperand, const MCInst &MI,
const MCInstrDesc &Desc,
const MCSubtargetInfo &STI,
raw_ostream &OS) const {
-
+ bool Ret = false;
// Emit the operand size opcode prefix as needed.
if ((TSFlags & X86II::OpSizeMask) == (is16BitMode(STI) ? X86II::OpSize32
: X86II::OpSize16))
@@ -1061,8 +1081,10 @@ void X86MCCodeEmitter::EmitOpcodePrefix(
// Handle REX prefix.
// FIXME: Can this come before F2 etc to simplify emission?
if (is64BitMode(STI)) {
- if (uint8_t REX = DetermineREXPrefix(MI, TSFlags, MemOperand, Desc))
+ if (uint8_t REX = DetermineREXPrefix(MI, TSFlags, MemOperand, Desc)) {
EmitByte(0x40 | REX, CurByte, OS);
+ Ret = true;
+ }
}
// 0x0F escape code must be emitted just before the opcode.
@@ -1082,6 +1104,7 @@ void X86MCCodeEmitter::EmitOpcodePrefix(
EmitByte(0x3A, CurByte, OS);
break;
}
+ return Ret;
}
void X86MCCodeEmitter::
@@ -1156,8 +1179,9 @@ encodeInstruction(const MCInst &MI, raw_
if (need_address_override)
EmitByte(0x67, CurByte, OS);
+ bool Rex = false;
if (Encoding == 0)
- EmitOpcodePrefix(TSFlags, CurByte, MemoryOperand, MI, Desc, STI, OS);
+ Rex = emitOpcodePrefix(TSFlags, CurByte, MemoryOperand, MI, Desc, STI, OS);
else
EmitVEXOpcodePrefix(TSFlags, CurByte, MemoryOperand, MI, Desc, OS);
@@ -1270,9 +1294,8 @@ encodeInstruction(const MCInst &MI, raw_
if (HasVEX_4V) // Skip 1st src (which is encoded in VEX_VVVV)
++SrcRegNum;
- EmitMemModRMByte(MI, CurOp,
- GetX86RegNum(MI.getOperand(SrcRegNum)),
- TSFlags, CurByte, OS, Fixups, STI);
+ emitMemModRMByte(MI, CurOp, GetX86RegNum(MI.getOperand(SrcRegNum)), TSFlags,
+ Rex, CurByte, OS, Fixups, STI);
CurOp = SrcRegNum + 1;
break;
}
@@ -1315,8 +1338,8 @@ encodeInstruction(const MCInst &MI, raw_
EmitByte(BaseOpcode, CurByte, OS);
- EmitMemModRMByte(MI, FirstMemOp, GetX86RegNum(MI.getOperand(CurOp)),
- TSFlags, CurByte, OS, Fixups, STI);
+ emitMemModRMByte(MI, FirstMemOp, GetX86RegNum(MI.getOperand(CurOp)),
+ TSFlags, Rex, CurByte, OS, Fixups, STI);
CurOp = FirstMemOp + X86::AddrNumOperands;
if (HasVEX_4VOp3)
++CurOp;
@@ -1351,8 +1374,9 @@ encodeInstruction(const MCInst &MI, raw_
if (HasEVEX_K) // Skip writemask
++CurOp;
EmitByte(BaseOpcode, CurByte, OS);
- EmitMemModRMByte(MI, CurOp, (Form == X86II::MRMXm) ? 0 : Form-X86II::MRM0m,
- TSFlags, CurByte, OS, Fixups, STI);
+ emitMemModRMByte(MI, CurOp,
+ (Form == X86II::MRMXm) ? 0 : Form - X86II::MRM0m, TSFlags,
+ Rex, CurByte, OS, Fixups, STI);
CurOp += X86::AddrNumOperands;
break;
}
Modified: llvm/trunk/lib/Target/X86/MCTargetDesc/X86MachObjectWriter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/MCTargetDesc/X86MachObjectWriter.cpp?rev=271118&r1=271117&r2=271118&view=diff
==============================================================================
--- llvm/trunk/lib/Target/X86/MCTargetDesc/X86MachObjectWriter.cpp (original)
+++ llvm/trunk/lib/Target/X86/MCTargetDesc/X86MachObjectWriter.cpp Sat May 28 10:51:38 2016
@@ -73,7 +73,9 @@ public:
static bool isFixupKindRIPRel(unsigned Kind) {
return Kind == X86::reloc_riprel_4byte ||
- Kind == X86::reloc_riprel_4byte_movq_load;
+ Kind == X86::reloc_riprel_4byte_movq_load ||
+ Kind == X86::reloc_riprel_4byte_relax ||
+ Kind == X86::reloc_riprel_4byte_relax_rex;
}
static unsigned getFixupKindLog2Size(unsigned Kind) {
@@ -87,6 +89,8 @@ static unsigned getFixupKindLog2Size(uns
case FK_PCRel_4:
// FIXME: Remove these!!!
case X86::reloc_riprel_4byte:
+ case X86::reloc_riprel_4byte_relax:
+ case X86::reloc_riprel_4byte_relax_rex:
case X86::reloc_riprel_4byte_movq_load:
case X86::reloc_signed_4byte:
case FK_Data_4: return 2;
Added: llvm/trunk/test/MC/ELF/got-relaxed-no-relax.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/ELF/got-relaxed-no-relax.s?rev=271118&view=auto
==============================================================================
--- llvm/trunk/test/MC/ELF/got-relaxed-no-relax.s (added)
+++ llvm/trunk/test/MC/ELF/got-relaxed-no-relax.s Sat May 28 10:51:38 2016
@@ -0,0 +1,15 @@
+// RUN: llvm-mc -filetype=obj -relax-relocations -triple x86_64-pc-linux %s -o - | llvm-readobj -r | FileCheck %s
+
+// these should not produce relaxable relocations
+
+ movq foo at GOT, %rax
+ mulq foo at GOTPCREL(%rip)
+ .long foo at GOTPCREL
+
+// CHECK: Relocations [
+// CHECK: Section ({{.*}}) .rela.text {
+// CHECK-NEXT: R_X86_64_GOT32 foo
+// CHECK-NEXT: R_X86_64_GOTPCREL foo
+// CHECK-NEXT: R_X86_64_GOTPCREL foo
+// CHECK-NEXT: }
+// CHECK-NEXT: ]
Added: llvm/trunk/test/MC/ELF/got-relaxed-rex.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/ELF/got-relaxed-rex.s?rev=271118&view=auto
==============================================================================
--- llvm/trunk/test/MC/ELF/got-relaxed-rex.s (added)
+++ llvm/trunk/test/MC/ELF/got-relaxed-rex.s Sat May 28 10:51:38 2016
@@ -0,0 +1,29 @@
+// RUN: llvm-mc -filetype=obj -relax-relocations -triple x86_64-pc-linux %s -o - | llvm-readobj -r | FileCheck %s
+
+// these should produce R_X86_64_REX_GOTPCRELX
+
+ movq mov at GOTPCREL(%rip), %rax
+ test %rax, test at GOTPCREL(%rip)
+ adc adc at GOTPCREL(%rip), %rax
+ add add at GOTPCREL(%rip), %rax
+ and and at GOTPCREL(%rip), %rax
+ cmp cmp at GOTPCREL(%rip), %rax
+ or or at GOTPCREL(%rip), %rax
+ sbb sbb at GOTPCREL(%rip), %rax
+ sub sub at GOTPCREL(%rip), %rax
+ xor xor at GOTPCREL(%rip), %rax
+
+// CHECK: Relocations [
+// CHECK-NEXT: Section ({{.*}}) .rela.text {
+// CHECK-NEXT: R_X86_64_REX_GOTPCRELX mov
+// CHECK-NEXT: R_X86_64_REX_GOTPCRELX test
+// CHECK-NEXT: R_X86_64_REX_GOTPCRELX adc
+// CHECK-NEXT: R_X86_64_REX_GOTPCRELX add
+// CHECK-NEXT: R_X86_64_REX_GOTPCRELX and
+// CHECK-NEXT: R_X86_64_REX_GOTPCRELX cmp
+// CHECK-NEXT: R_X86_64_REX_GOTPCRELX or
+// CHECK-NEXT: R_X86_64_REX_GOTPCRELX sbb
+// CHECK-NEXT: R_X86_64_REX_GOTPCRELX sub
+// CHECK-NEXT: R_X86_64_REX_GOTPCRELX xor
+// CHECK-NEXT: }
+// CHECK-NEXT: ]
Modified: llvm/trunk/test/MC/ELF/got-relaxed.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/ELF/got-relaxed.s?rev=271118&r1=271117&r2=271118&view=diff
==============================================================================
--- llvm/trunk/test/MC/ELF/got-relaxed.s (original)
+++ llvm/trunk/test/MC/ELF/got-relaxed.s Sat May 28 10:51:38 2016
@@ -1,20 +1,13 @@
-// RUN: llvm-mc -filetype=obj -relax-relocations -triple x86_64-pc-linux-gnu %s -o - | llvm-readobj -r -t | FileCheck %s
+// RUN: llvm-mc -filetype=obj -relax-relocations -triple x86_64-pc-linux %s -o - | llvm-readobj -r | FileCheck %s
-// Test that this produces the correct relaxed relocations.
+// these should produce R_X86_64_GOTPCRELX
- movl foo at GOT, %eax
- movl foo at GOTPCREL(%rip), %eax
- movq foo at GOTPCREL(%rip), %rax
- .long zed at GOTPCREL
+ call *call at GOTPCREL(%rip)
+ jmp *jmp at GOTPCREL(%rip)
// CHECK: Relocations [
-// CHECK: Section ({{[^ ]+}}) .rela.text {
-// CHECK-NEXT: 0x{{[^ ]+}} R_X86_64_GOT32 foo 0x{{[^ ]+}}
-// CHECK-NEXT: 0x{{[^ ]+}} R_X86_64_GOTPCRELX foo 0x{{[^ ]+}}
-// CHECK-NEXT: 0x{{[^ ]+}} R_X86_64_REX_GOTPCRELX foo 0x{{[^ ]+}}
-// CHECK-NEXT: 0x{{[^ ]+}} R_X86_64_GOTPCREL zed 0x{{[^ ]+}}
+// CHECK-NEXT: Section ({{.*}}) .rela.text {
+// CHECK-NEXT: R_X86_64_GOTPCRELX call
+// CHECK-NEXT: R_X86_64_GOTPCRELX jmp
// CHECK-NEXT: }
// CHECK-NEXT: ]
-
-// CHECK: Symbols [
-// CHECK-NOT: _GLOBAL_OFFSET_TABLE_
More information about the llvm-commits
mailing list