diff options
author | George Rimar <grimar@accesssoftek.com> | 2018-02-20 10:17:57 +0000 |
---|---|---|
committer | George Rimar <grimar@accesssoftek.com> | 2018-02-20 10:17:57 +0000 |
commit | da4f43a4b4987f4b207b3ecee6bf67a9f5761c81 (patch) | |
tree | c11eb14e1b86924d37fc608556d42d8cfc956197 /llvm/lib/Target/X86/MCTargetDesc | |
parent | 65d2d5bad4ee0db2c824ebd7faec75df401c4056 (diff) | |
download | bcm5719-llvm-da4f43a4b4987f4b207b3ecee6bf67a9f5761c81.tar.gz bcm5719-llvm-da4f43a4b4987f4b207b3ecee6bf67a9f5761c81.zip |
[llvm-mc] - Produce R_X86_64_PLT32 for "call/jmp foo".
For instructions like call foo and jmp foo patch changes
relocation produced from R_X86_64_PC32 to R_X86_64_PLT32.
Relocation can be used as a marker for 32-bit PC-relative branches.
Linker will reduce PLT32 relocation to PC32 if function is defined locally.
Differential revision: https://reviews.llvm.org/D43383
llvm-svn: 325569
Diffstat (limited to 'llvm/lib/Target/X86/MCTargetDesc')
6 files changed, 39 insertions, 2 deletions
diff --git a/llvm/lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp b/llvm/lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp index da4ca665d83..eea94b2eb1d 100644 --- a/llvm/lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp +++ b/llvm/lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp @@ -46,6 +46,7 @@ static unsigned getFixupKindLog2Size(unsigned Kind) { case X86::reloc_signed_4byte: case X86::reloc_signed_4byte_relax: case X86::reloc_global_offset_table: + case X86::reloc_branch_4byte_pcrel: case FK_SecRel_4: case FK_Data_4: return 2; @@ -86,6 +87,7 @@ public: {"reloc_signed_4byte_relax", 0, 32, 0}, {"reloc_global_offset_table", 0, 32, 0}, {"reloc_global_offset_table8", 0, 64, 0}, + {"reloc_branch_4byte_pcrel", 0, 32, MCFixupKindInfo::FKF_IsPCRel}, }; if (Kind < FirstTargetFixupKind) @@ -93,6 +95,7 @@ public: assert(unsigned(Kind - FirstTargetFixupKind) < getNumFixupKinds() && "Invalid kind!"); + assert(Infos[Kind - FirstTargetFixupKind].Name && "Empty fixup name!"); return Infos[Kind - FirstTargetFixupKind]; } diff --git a/llvm/lib/Target/X86/MCTargetDesc/X86ELFObjectWriter.cpp b/llvm/lib/Target/X86/MCTargetDesc/X86ELFObjectWriter.cpp index 4cdbae4d0d9..2ecbb80cd06 100644 --- a/llvm/lib/Target/X86/MCTargetDesc/X86ELFObjectWriter.cpp +++ b/llvm/lib/Target/X86/MCTargetDesc/X86ELFObjectWriter.cpp @@ -75,6 +75,9 @@ static X86_64RelType getType64(unsigned Kind, case X86::reloc_riprel_4byte_relax_rex: case X86::reloc_riprel_4byte_movq_load: return RT64_32; + case X86::reloc_branch_4byte_pcrel: + Modifier = MCSymbolRefExpr::VK_PLT; + return RT64_32; case FK_PCRel_2: case FK_Data_2: return RT64_16; diff --git a/llvm/lib/Target/X86/MCTargetDesc/X86FixupKinds.h b/llvm/lib/Target/X86/MCTargetDesc/X86FixupKinds.h index dfdc9ec29ae..3c04b13e002 100644 --- a/llvm/lib/Target/X86/MCTargetDesc/X86FixupKinds.h +++ b/llvm/lib/Target/X86/MCTargetDesc/X86FixupKinds.h @@ -30,6 +30,7 @@ enum Fixups { // of the instruction. Used only // for _GLOBAL_OFFSET_TABLE_. reloc_global_offset_table8, // 64-bit variant. + reloc_branch_4byte_pcrel, // 32-bit PC relative branch. // Marker LastTargetFixupKind, NumTargetFixupKinds = LastTargetFixupKind - FirstTargetFixupKind diff --git a/llvm/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp b/llvm/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp index 4ddc1f0ba42..608dc4acb04 100644 --- a/llvm/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp +++ b/llvm/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp @@ -152,6 +152,8 @@ public: uint8_t DetermineREXPrefix(const MCInst &MI, uint64_t TSFlags, int MemOperand, const MCInstrDesc &Desc) const; + + bool isPCRel32Branch(const MCInst &MI) const; }; } // end anonymous namespace @@ -276,6 +278,22 @@ static bool HasSecRelSymbolRef(const MCExpr *Expr) { return false; } +bool X86MCCodeEmitter::isPCRel32Branch(const MCInst &MI) const { + unsigned Opcode = MI.getOpcode(); + const MCInstrDesc &Desc = MCII.get(Opcode); + if ((Opcode != X86::CALL64pcrel32 && Opcode != X86::JMP_4) || + getImmFixupKind(Desc.TSFlags) != FK_PCRel_4) + return false; + + unsigned CurOp = X86II::getOperandBias(Desc); + const MCOperand &Op = MI.getOperand(CurOp); + if (!Op.isExpr()) + return false; + + const MCSymbolRefExpr *Ref = dyn_cast<MCSymbolRefExpr>(Op.getExpr()); + return Ref && Ref->getKind() == MCSymbolRefExpr::VK_None; +} + void X86MCCodeEmitter:: EmitImmediate(const MCOperand &DispOp, SMLoc Loc, unsigned Size, MCFixupKind FixupKind, unsigned &CurByte, raw_ostream &OS, @@ -331,7 +349,8 @@ EmitImmediate(const MCOperand &DispOp, SMLoc Loc, unsigned Size, FixupKind == MCFixupKind(X86::reloc_riprel_4byte) || FixupKind == MCFixupKind(X86::reloc_riprel_4byte_movq_load) || FixupKind == MCFixupKind(X86::reloc_riprel_4byte_relax) || - FixupKind == MCFixupKind(X86::reloc_riprel_4byte_relax_rex)) + FixupKind == MCFixupKind(X86::reloc_riprel_4byte_relax_rex) || + FixupKind == MCFixupKind(X86::reloc_branch_4byte_pcrel)) ImmOffset -= 4; if (FixupKind == FK_PCRel_2) ImmOffset -= 2; @@ -1287,9 +1306,18 @@ encodeInstruction(const MCInst &MI, raw_ostream &OS, EmitByte(BaseOpcode, CurByte, OS); break; } - case X86II::RawFrm: + case X86II::RawFrm: { EmitByte(BaseOpcode, CurByte, OS); + + if (!is64BitMode(STI) || !isPCRel32Branch(MI)) + break; + + const MCOperand &Op = MI.getOperand(CurOp++); + EmitImmediate(Op, MI.getLoc(), X86II::getSizeOfImm(TSFlags), + MCFixupKind(X86::reloc_branch_4byte_pcrel), CurByte, OS, + Fixups); break; + } case X86II::RawFrmMemOffs: // Emit segment override opcode prefix as needed. EmitSegmentOverridePrefix(CurByte, 1, MI, OS); diff --git a/llvm/lib/Target/X86/MCTargetDesc/X86MachObjectWriter.cpp b/llvm/lib/Target/X86/MCTargetDesc/X86MachObjectWriter.cpp index 965f7de809b..22773e64409 100644 --- a/llvm/lib/Target/X86/MCTargetDesc/X86MachObjectWriter.cpp +++ b/llvm/lib/Target/X86/MCTargetDesc/X86MachObjectWriter.cpp @@ -94,6 +94,7 @@ static unsigned getFixupKindLog2Size(unsigned Kind) { case X86::reloc_riprel_4byte_movq_load: case X86::reloc_signed_4byte: case X86::reloc_signed_4byte_relax: + case X86::reloc_branch_4byte_pcrel: case FK_Data_4: return 2; case FK_Data_8: return 3; } diff --git a/llvm/lib/Target/X86/MCTargetDesc/X86WinCOFFObjectWriter.cpp b/llvm/lib/Target/X86/MCTargetDesc/X86WinCOFFObjectWriter.cpp index 5139bb46b56..291056e3526 100644 --- a/llvm/lib/Target/X86/MCTargetDesc/X86WinCOFFObjectWriter.cpp +++ b/llvm/lib/Target/X86/MCTargetDesc/X86WinCOFFObjectWriter.cpp @@ -62,6 +62,7 @@ unsigned X86WinCOFFObjectWriter::getRelocType(MCContext &Ctx, case X86::reloc_riprel_4byte_movq_load: case X86::reloc_riprel_4byte_relax: case X86::reloc_riprel_4byte_relax_rex: + case X86::reloc_branch_4byte_pcrel: return COFF::IMAGE_REL_AMD64_REL32; case FK_Data_4: case X86::reloc_signed_4byte: |