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;
{"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)
assert(unsigned(Kind - FirstTargetFixupKind) < getNumFixupKinds() &&
"Invalid kind!");
+ assert(Infos[Kind - FirstTargetFixupKind].Name && "Empty fixup name!");
return Infos[Kind - FirstTargetFixupKind];
}
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;
// 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
uint8_t DetermineREXPrefix(const MCInst &MI, uint64_t TSFlags,
int MemOperand, const MCInstrDesc &Desc) const;
+
+ bool isPCRel32Branch(const MCInst &MI) const;
};
} // end anonymous namespace
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,
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;
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);
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;
}
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:
; 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
; 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]
;
; 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]
;
; 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]
;
; 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:
; 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
; 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
callq puts
xorl %eax, %eax
addq $8, %rsp
+ call foo@GOTPCREL
ret
.Ltmp0:
.size main, .Ltmp0-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
// 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: ]
// 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: ]
// 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: ]
// 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: ]