forked from OSchip/llvm-project
[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
This commit is contained in:
parent
65d2d5bad4
commit
da4f43a4b4
|
@ -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];
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -240,7 +240,7 @@ define i32 @test12() ssp uwtable {
|
|||
; CHECK-NEXT: pushq %rax # encoding: [0x50]
|
||||
; CHECK-NEXT: .cfi_def_cfa_offset 16
|
||||
; CHECK-NEXT: callq test12b # encoding: [0xe8,A,A,A,A]
|
||||
; CHECK-NEXT: # fixup A - offset: 1, value: test12b-4, kind: FK_PCRel_4
|
||||
; CHECK-NEXT: # fixup A - offset: 1, value: test12b-4, kind: reloc_branch_4byte_pcrel
|
||||
; CHECK-NEXT: testb %al, %al # encoding: [0x84,0xc0]
|
||||
; CHECK-NEXT: je .LBB12_2 # encoding: [0x74,A]
|
||||
; CHECK-NEXT: # fixup A - offset: 1, value: .LBB12_2-1, kind: FK_PCRel_1
|
||||
|
|
|
@ -137,7 +137,7 @@ define x86_fp80 @test_f80(x86_fp80 %a, x86_fp80 %b, x86_fp80 %c) #0 {
|
|||
; FMA64-NEXT: fstpt {{[0-9]+}}(%rsp) ## encoding: [0xdb,0x7c,0x24,0x10]
|
||||
; FMA64-NEXT: fstpt (%rsp) ## encoding: [0xdb,0x3c,0x24]
|
||||
; FMA64-NEXT: callq _fmal ## encoding: [0xe8,A,A,A,A]
|
||||
; FMA64-NEXT: ## fixup A - offset: 1, value: _fmal-4, kind: FK_PCRel_4
|
||||
; FMA64-NEXT: ## fixup A - offset: 1, value: _fmal-4, kind: reloc_branch_4byte_pcrel
|
||||
; FMA64-NEXT: addq $56, %rsp ## encoding: [0x48,0x83,0xc4,0x38]
|
||||
; FMA64-NEXT: retq ## encoding: [0xc3]
|
||||
;
|
||||
|
@ -151,7 +151,7 @@ define x86_fp80 @test_f80(x86_fp80 %a, x86_fp80 %b, x86_fp80 %c) #0 {
|
|||
; FMACALL64-NEXT: fstpt {{[0-9]+}}(%rsp) ## encoding: [0xdb,0x7c,0x24,0x10]
|
||||
; FMACALL64-NEXT: fstpt (%rsp) ## encoding: [0xdb,0x3c,0x24]
|
||||
; FMACALL64-NEXT: callq _fmal ## encoding: [0xe8,A,A,A,A]
|
||||
; FMACALL64-NEXT: ## fixup A - offset: 1, value: _fmal-4, kind: FK_PCRel_4
|
||||
; FMACALL64-NEXT: ## fixup A - offset: 1, value: _fmal-4, kind: reloc_branch_4byte_pcrel
|
||||
; FMACALL64-NEXT: addq $56, %rsp ## encoding: [0x48,0x83,0xc4,0x38]
|
||||
; FMACALL64-NEXT: retq ## encoding: [0xc3]
|
||||
;
|
||||
|
@ -165,7 +165,7 @@ define x86_fp80 @test_f80(x86_fp80 %a, x86_fp80 %b, x86_fp80 %c) #0 {
|
|||
; AVX512-NEXT: fstpt {{[0-9]+}}(%rsp) ## encoding: [0xdb,0x7c,0x24,0x10]
|
||||
; AVX512-NEXT: fstpt (%rsp) ## encoding: [0xdb,0x3c,0x24]
|
||||
; AVX512-NEXT: callq _fmal ## encoding: [0xe8,A,A,A,A]
|
||||
; AVX512-NEXT: ## fixup A - offset: 1, value: _fmal-4, kind: FK_PCRel_4
|
||||
; AVX512-NEXT: ## fixup A - offset: 1, value: _fmal-4, kind: reloc_branch_4byte_pcrel
|
||||
; AVX512-NEXT: addq $56, %rsp ## encoding: [0x48,0x83,0xc4,0x38]
|
||||
; AVX512-NEXT: retq ## encoding: [0xc3]
|
||||
;
|
||||
|
@ -179,7 +179,7 @@ define x86_fp80 @test_f80(x86_fp80 %a, x86_fp80 %b, x86_fp80 %c) #0 {
|
|||
; AVX512VL-NEXT: fstpt {{[0-9]+}}(%rsp) ## encoding: [0xdb,0x7c,0x24,0x10]
|
||||
; AVX512VL-NEXT: fstpt (%rsp) ## encoding: [0xdb,0x3c,0x24]
|
||||
; AVX512VL-NEXT: callq _fmal ## encoding: [0xe8,A,A,A,A]
|
||||
; AVX512VL-NEXT: ## fixup A - offset: 1, value: _fmal-4, kind: FK_PCRel_4
|
||||
; AVX512VL-NEXT: ## fixup A - offset: 1, value: _fmal-4, kind: reloc_branch_4byte_pcrel
|
||||
; AVX512VL-NEXT: addq $56, %rsp ## encoding: [0x48,0x83,0xc4,0x38]
|
||||
; AVX512VL-NEXT: retq ## encoding: [0xc3]
|
||||
entry:
|
||||
|
|
|
@ -161,7 +161,7 @@ define x86_intrcc void @foo(i8* %frame) {
|
|||
; CHECK64-KNL-NEXT: .cfi_offset %k7, -82
|
||||
; CHECK64-KNL-NEXT: cld ## encoding: [0xfc]
|
||||
; CHECK64-KNL-NEXT: callq _bar ## encoding: [0xe8,A,A,A,A]
|
||||
; CHECK64-KNL-NEXT: ## fixup A - offset: 1, value: _bar-4, kind: FK_PCRel_4
|
||||
; CHECK64-KNL-NEXT: ## fixup A - offset: 1, value: _bar-4, kind: reloc_branch_4byte_pcrel
|
||||
; CHECK64-KNL-NEXT: vmovups (%rsp), %zmm0 ## 64-byte Reload
|
||||
; CHECK64-KNL-NEXT: ## encoding: [0x62,0xf1,0x7c,0x48,0x10,0x04,0x24]
|
||||
; CHECK64-KNL-NEXT: vmovups {{[0-9]+}}(%rsp), %zmm1 ## 64-byte Reload
|
||||
|
@ -410,7 +410,7 @@ define x86_intrcc void @foo(i8* %frame) {
|
|||
; CHECK64-SKX-NEXT: cld ## encoding: [0xfc]
|
||||
; CHECK64-SKX-NEXT: vzeroupper ## encoding: [0xc5,0xf8,0x77]
|
||||
; CHECK64-SKX-NEXT: callq _bar ## encoding: [0xe8,A,A,A,A]
|
||||
; CHECK64-SKX-NEXT: ## fixup A - offset: 1, value: _bar-4, kind: FK_PCRel_4
|
||||
; CHECK64-SKX-NEXT: ## fixup A - offset: 1, value: _bar-4, kind: reloc_branch_4byte_pcrel
|
||||
; CHECK64-SKX-NEXT: vmovups (%rsp), %zmm0 ## 64-byte Reload
|
||||
; CHECK64-SKX-NEXT: ## encoding: [0x62,0xf1,0x7c,0x48,0x10,0x04,0x24]
|
||||
; CHECK64-SKX-NEXT: vmovups {{[0-9]+}}(%rsp), %zmm1 ## 64-byte Reload
|
||||
|
|
|
@ -13,6 +13,7 @@ main: # @main
|
|||
callq puts
|
||||
xorl %eax, %eax
|
||||
addq $8, %rsp
|
||||
call foo@GOTPCREL
|
||||
ret
|
||||
.Ltmp0:
|
||||
.size main, .Ltmp0-main
|
||||
|
@ -44,14 +45,15 @@ main: # @main
|
|||
|
||||
// CHECK: Name: .rela.text
|
||||
|
||||
// CHECK: Relocations [
|
||||
// CHECK: Section {{.*}} .rela.text {
|
||||
// CHECK: 0x5 R_X86_64_32 .rodata.str1.1 0x0
|
||||
// CHECK: 0xA R_X86_64_PC32 puts 0xFFFFFFFFFFFFFFFC
|
||||
// CHECK: 0xF R_X86_64_32 .rodata.str1.1 0x6
|
||||
// CHECK: 0x14 R_X86_64_PC32 puts 0xFFFFFFFFFFFFFFFC
|
||||
// CHECK: }
|
||||
// CHECK: ]
|
||||
// CHECK: Relocations [
|
||||
// CHECK: Section {{.*}} .rela.text {
|
||||
// CHECK-NEXT: 0x5 R_X86_64_32 .rodata.str1.1 0x0
|
||||
// CHECK-NEXT: 0xA R_X86_64_PLT32 puts 0xFFFFFFFFFFFFFFFC
|
||||
// CHECK-NEXT: 0xF R_X86_64_32 .rodata.str1.1 0x6
|
||||
// CHECK-NEXT: 0x14 R_X86_64_PLT32 puts 0xFFFFFFFFFFFFFFFC
|
||||
// CHECK-NEXT: 0x1F R_X86_64_GOTPCREL foo 0xFFFFFFFFFFFFFFFC
|
||||
// CHECK-NEXT: }
|
||||
// CHECK-NEXT: ]
|
||||
|
||||
// CHECK: Symbol {
|
||||
// CHECK: Binding: Local
|
||||
|
|
|
@ -11,6 +11,6 @@ alias:
|
|||
|
||||
// CHECK: Relocations [
|
||||
// CHECK-NEXT: Section {{.*}} .rela.text {
|
||||
// CHECK-NEXT: 0x1 R_X86_64_PC32 sym 0xFFFFFFFFFFFFFFFC
|
||||
// CHECK-NEXT: 0x1 R_X86_64_PLT32 sym 0xFFFFFFFFFFFFFFFC
|
||||
// CHECK-NEXT: }
|
||||
// CHECK-NEXT: ]
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
// CHECK: Relocations [
|
||||
// CHECK-NEXT: Section ({{.*}}) .rela.text {
|
||||
// CHECK-NEXT: 0x1D R_X86_64_PC32 f2 0xFFFFFFFFFFFFFFFC
|
||||
// CHECK-NEXT: 0x1D R_X86_64_PLT32 f2 0xFFFFFFFFFFFFFFFC
|
||||
// CHECK-NEXT: }
|
||||
// CHECK-NEXT: ]
|
||||
|
||||
|
|
|
@ -9,6 +9,6 @@ bar:
|
|||
|
||||
// CHECK: Relocations [
|
||||
// CHECK-NEXT: Section ({{[0-9]+}}) .rela.text {
|
||||
// CHECK-NEXT: 0x1 R_X86_64_PC32 foo 0xFFFFFFFFFFFFFFFC
|
||||
// CHECK-NEXT: 0x1 R_X86_64_PLT32 foo 0xFFFFFFFFFFFFFFFC
|
||||
// CHECK-NEXT: }
|
||||
// CHECK-NEXT: ]
|
||||
|
|
|
@ -9,6 +9,6 @@
|
|||
// CHECK: Relocations [
|
||||
// CHECK-NEXT: Section ({{[0-9]+}}) {{[^ ]+}} {
|
||||
// CHECK-NEXT: 0x1 R_X86_64_PLT32 zed 0xFFFFFFFFFFFFFFFC
|
||||
// CHECK-NEXT: 0x6 R_X86_64_PC32 foo 0xFFFFFFFFFFFFFFFC
|
||||
// CHECK-NEXT: 0x6 R_X86_64_PLT32 foo 0xFFFFFFFFFFFFFFFC
|
||||
// CHECK-NEXT: }
|
||||
// CHECK-NEXT: ]
|
||||
|
|
Loading…
Reference in New Issue