summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
authorRafael Espindola <rafael.espindola@gmail.com>2016-05-28 15:51:38 +0000
committerRafael Espindola <rafael.espindola@gmail.com>2016-05-28 15:51:38 +0000
commit52bd330500339e9c176d1fec7c2733f34ac0aa85 (patch)
treed2eb804be1fbd94f88c9d8ce14cffdac1beec55d /llvm/lib
parentf49c7b157001dfd83f02e596c57577cfc0c08d17 (diff)
downloadbcm5719-llvm-52bd330500339e9c176d1fec7c2733f34ac0aa85.tar.gz
bcm5719-llvm-52bd330500339e9c176d1fec7c2733f34ac0aa85.zip
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. llvm-svn: 271118
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp4
-rw-r--r--llvm/lib/Target/X86/MCTargetDesc/X86ELFObjectWriter.cpp5
-rw-r--r--llvm/lib/Target/X86/MCTargetDesc/X86FixupKinds.h4
-rw-r--r--llvm/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp82
-rw-r--r--llvm/lib/Target/X86/MCTargetDesc/X86MachObjectWriter.cpp6
5 files changed, 70 insertions, 31 deletions
diff --git a/llvm/lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp b/llvm/lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp
index baa6f0c432e..34fe3cdc5ba 100644
--- a/llvm/lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp
+++ b/llvm/lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp
@@ -42,6 +42,8 @@ static unsigned getFixupKindLog2Size(unsigned Kind) {
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},
diff --git a/llvm/lib/Target/X86/MCTargetDesc/X86ELFObjectWriter.cpp b/llvm/lib/Target/X86/MCTargetDesc/X86ELFObjectWriter.cpp
index 6fa479e4d7e..e5084f90f98 100644
--- a/llvm/lib/Target/X86/MCTargetDesc/X86ELFObjectWriter.cpp
+++ b/llvm/lib/Target/X86/MCTargetDesc/X86ELFObjectWriter.cpp
@@ -68,6 +68,8 @@ static X86_64RelType getType64(unsigned Kind,
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 &Ctx, SMLoc Loc,
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;
}
diff --git a/llvm/lib/Target/X86/MCTargetDesc/X86FixupKinds.h b/llvm/lib/Target/X86/MCTargetDesc/X86FixupKinds.h
index 4899900dcef..417e04a5d94 100644
--- a/llvm/lib/Target/X86/MCTargetDesc/X86FixupKinds.h
+++ b/llvm/lib/Target/X86/MCTargetDesc/X86FixupKinds.h
@@ -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.
diff --git a/llvm/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp b/llvm/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp
index d06d1a6caf8..682213908bc 100644
--- a/llvm/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp
+++ b/llvm/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp
@@ -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, SMLoc Loc, unsigned Size,
// 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, SMLoc Loc, unsigned Size,
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(const MCInst &MI, unsigned Op,
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::EmitSegmentOverridePrefix(unsigned &CurByte,
}
}
-/// 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(uint64_t TSFlags, unsigned &CurByte,
// 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(uint64_t TSFlags, unsigned &CurByte,
EmitByte(0x3A, CurByte, OS);
break;
}
+ return Ret;
}
void X86MCCodeEmitter::
@@ -1156,8 +1179,9 @@ encodeInstruction(const MCInst &MI, raw_ostream &OS,
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_ostream &OS,
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_ostream &OS,
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_ostream &OS,
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;
}
diff --git a/llvm/lib/Target/X86/MCTargetDesc/X86MachObjectWriter.cpp b/llvm/lib/Target/X86/MCTargetDesc/X86MachObjectWriter.cpp
index 191ebeac726..c098edec589 100644
--- a/llvm/lib/Target/X86/MCTargetDesc/X86MachObjectWriter.cpp
+++ b/llvm/lib/Target/X86/MCTargetDesc/X86MachObjectWriter.cpp
@@ -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(unsigned Kind) {
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;
OpenPOWER on IntegriCloud