Skip to content

Commit ea60057

Browse files
committed
MCFixup: Add PCRel to ctor parameter and set it in X86MCCodeEmitter
1 parent fa9adbf commit ea60057

File tree

2 files changed

+37
-25
lines changed

2 files changed

+37
-25
lines changed

llvm/include/llvm/MC/MCFixup.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,10 @@ class MCFixup {
7373
/// determine how the operand value should be encoded into the instruction.
7474
uint16_t Kind = FK_NONE;
7575

76+
/// True if this is a PC-relative fixup. The relocatable expression is
77+
/// typically resolved When SymB is nullptr and SymA is a local symbol defined
78+
/// within the current section. While MCAssembler currently sets this based on
79+
/// FKF_IsPCRel, targets should ideally set it at creation.
7680
bool PCRel = false;
7781

7882
/// Used by RISC-V style linker relaxation. Whether the fixup is
@@ -82,11 +86,13 @@ class MCFixup {
8286
/// Consider bit fields if we need more flags.
8387

8488
public:
85-
static MCFixup create(uint32_t Offset, const MCExpr *Value, uint16_t Kind) {
89+
static MCFixup create(uint32_t Offset, const MCExpr *Value, uint16_t Kind,
90+
bool PCRel = false) {
8691
MCFixup FI;
8792
FI.Value = Value;
8893
FI.Offset = Offset;
8994
FI.Kind = Kind;
95+
FI.PCRel = PCRel;
9096
return FI;
9197
}
9298
static MCFixup create(uint32_t Offset, const MCExpr *Value,

llvm/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp

Lines changed: 30 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -359,7 +359,7 @@ class X86MCCodeEmitter : public MCCodeEmitter {
359359
unsigned getX86RegEncoding(const MCInst &MI, unsigned OpNum) const;
360360

361361
void emitImmediate(const MCOperand &Disp, SMLoc Loc, unsigned ImmSize,
362-
MCFixupKind FixupKind, uint64_t StartByte,
362+
unsigned FixupKind, uint64_t StartByte,
363363
SmallVectorImpl<char> &CB,
364364
SmallVectorImpl<MCFixup> &Fixups, int ImmOffset = 0) const;
365365

@@ -528,7 +528,7 @@ unsigned X86MCCodeEmitter::getX86RegEncoding(const MCInst &MI,
528528
}
529529

530530
void X86MCCodeEmitter::emitImmediate(const MCOperand &DispOp, SMLoc Loc,
531-
unsigned Size, MCFixupKind FixupKind,
531+
unsigned Size, unsigned FixupKind,
532532
uint64_t StartByte,
533533
SmallVectorImpl<char> &CB,
534534
SmallVectorImpl<MCFixup> &Fixups,
@@ -549,65 +549,71 @@ void X86MCCodeEmitter::emitImmediate(const MCOperand &DispOp, SMLoc Loc,
549549

550550
// If we have an immoffset, add it to the expression.
551551
if ((FixupKind == FK_Data_4 || FixupKind == FK_Data_8 ||
552-
FixupKind == MCFixupKind(X86::reloc_signed_4byte))) {
552+
FixupKind == X86::reloc_signed_4byte)) {
553553
GlobalOffsetTableExprKind Kind = startsWithGlobalOffsetTable(Expr);
554554
if (Kind != GOT_None) {
555555
assert(ImmOffset == 0);
556556

557557
if (Size == 8) {
558-
FixupKind =
559-
MCFixupKind(FirstLiteralRelocationKind + ELF::R_X86_64_GOTPC64);
558+
FixupKind = FirstLiteralRelocationKind + ELF::R_X86_64_GOTPC64;
560559
} else {
561560
assert(Size == 4);
562-
FixupKind = MCFixupKind(X86::reloc_global_offset_table);
561+
FixupKind = X86::reloc_global_offset_table;
563562
}
564563

565564
if (Kind == GOT_Normal)
566565
ImmOffset = static_cast<int>(CB.size() - StartByte);
567566
} else if (Expr->getKind() == MCExpr::SymbolRef) {
568567
if (hasSecRelSymbolRef(Expr)) {
569-
FixupKind = MCFixupKind(FK_SecRel_4);
568+
FixupKind = FK_SecRel_4;
570569
}
571570
} else if (Expr->getKind() == MCExpr::Binary) {
572571
const MCBinaryExpr *Bin = static_cast<const MCBinaryExpr *>(Expr);
573572
if (hasSecRelSymbolRef(Bin->getLHS()) ||
574573
hasSecRelSymbolRef(Bin->getRHS())) {
575-
FixupKind = MCFixupKind(FK_SecRel_4);
574+
FixupKind = FK_SecRel_4;
576575
}
577576
}
578577
}
579578

580579
// If the fixup is pc-relative, we need to bias the value to be relative to
581580
// the start of the field, not the end of the field.
582-
if (FixupKind == FK_PCRel_4 ||
583-
FixupKind == MCFixupKind(X86::reloc_riprel_4byte) ||
584-
FixupKind == MCFixupKind(X86::reloc_riprel_4byte_movq_load) ||
585-
FixupKind == MCFixupKind(X86::reloc_riprel_4byte_movq_load_rex2) ||
586-
FixupKind == MCFixupKind(X86::reloc_riprel_4byte_relax) ||
587-
FixupKind == MCFixupKind(X86::reloc_riprel_4byte_relax_rex) ||
588-
FixupKind == MCFixupKind(X86::reloc_riprel_4byte_relax_rex2) ||
589-
FixupKind == MCFixupKind(X86::reloc_branch_4byte_pcrel) ||
590-
FixupKind == MCFixupKind(X86::reloc_riprel_4byte_relax_evex)) {
581+
bool PCRel = false;
582+
switch (FixupKind) {
583+
case FK_PCRel_1:
584+
PCRel = true;
585+
ImmOffset -= 1;
586+
break;
587+
case FK_PCRel_2:
588+
PCRel = true;
589+
ImmOffset -= 2;
590+
break;
591+
case FK_PCRel_4:
592+
case X86::reloc_riprel_4byte:
593+
case X86::reloc_riprel_4byte_movq_load:
594+
case X86::reloc_riprel_4byte_movq_load_rex2:
595+
case X86::reloc_riprel_4byte_relax:
596+
case X86::reloc_riprel_4byte_relax_rex:
597+
case X86::reloc_riprel_4byte_relax_rex2:
598+
case X86::reloc_branch_4byte_pcrel:
599+
case X86::reloc_riprel_4byte_relax_evex:
600+
PCRel = true;
591601
ImmOffset -= 4;
592602
// If this is a pc-relative load off _GLOBAL_OFFSET_TABLE_:
593603
// leaq _GLOBAL_OFFSET_TABLE_(%rip), %r15
594604
// this needs to be a GOTPC32 relocation.
595605
if (startsWithGlobalOffsetTable(Expr) != GOT_None)
596-
FixupKind = MCFixupKind(X86::reloc_global_offset_table);
606+
FixupKind = X86::reloc_global_offset_table;
607+
break;
597608
}
598609

599-
if (FixupKind == FK_PCRel_2)
600-
ImmOffset -= 2;
601-
if (FixupKind == FK_PCRel_1)
602-
ImmOffset -= 1;
603-
604610
if (ImmOffset)
605611
Expr = MCBinaryExpr::createAdd(Expr, MCConstantExpr::create(ImmOffset, Ctx),
606612
Ctx, Expr->getLoc());
607613

608614
// Emit a symbolic constant as a fixup and 4 zeros.
609615
Fixups.push_back(MCFixup::create(static_cast<uint32_t>(CB.size() - StartByte),
610-
Expr, FixupKind));
616+
Expr, FixupKind, PCRel));
611617
emitConstant(0, Size, CB);
612618
}
613619

0 commit comments

Comments
 (0)