Skip to content

Commit c5eb84e

Browse files
committed
[𝘀𝗽𝗿] initial version
Created using spr 1.3.5-bogner
1 parent ea60057 commit c5eb84e

File tree

15 files changed

+100
-74
lines changed

15 files changed

+100
-74
lines changed

bolt/lib/Target/X86/X86MCPlusBuilder.cpp

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2442,9 +2442,10 @@ class X86MCPlusBuilder : public MCPlusBuilder {
24422442

24432443
assert(FKI.TargetOffset == 0 && "0-bit relocation offset expected");
24442444
const uint64_t RelOffset = Fixup.getOffset();
2445+
auto [RelSymbol, RelAddend] = extractFixupExpr(Fixup);
24452446

24462447
uint32_t RelType;
2447-
if (FKI.Flags & MCFixupKindInfo::FKF_IsPCRel) {
2448+
if (Fixup.isPCRel()) {
24482449
switch (FKI.TargetSize) {
24492450
default:
24502451
return std::nullopt;
@@ -2453,6 +2454,9 @@ class X86MCPlusBuilder : public MCPlusBuilder {
24532454
case 32: RelType = ELF::R_X86_64_PC32; break;
24542455
case 64: RelType = ELF::R_X86_64_PC64; break;
24552456
}
2457+
// Adjust PC-relative fixup offsets, which are calculated from the start
2458+
// of the next instruction.
2459+
RelAddend -= FKI.TargetSize / 8;
24562460
} else {
24572461
switch (FKI.TargetSize) {
24582462
default:
@@ -2464,8 +2468,6 @@ class X86MCPlusBuilder : public MCPlusBuilder {
24642468
}
24652469
}
24662470

2467-
auto [RelSymbol, RelAddend] = extractFixupExpr(Fixup);
2468-
24692471
return Relocation({RelOffset, RelSymbol, RelType, RelAddend, 0});
24702472
}
24712473

llvm/include/llvm/MC/MCAsmBackend.h

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -106,9 +106,12 @@ class LLVM_ABI MCAsmBackend {
106106
return false;
107107
}
108108

109-
virtual bool evaluateTargetFixup(const MCFixup &Fixup, const MCValue &Target,
110-
uint64_t &Value) {
111-
llvm_unreachable("Need to implement hook if target has custom fixups");
109+
// Evaluate a fixup, returning std::nullopt to use default handling for
110+
// `Value` and `IsResolved`. Otherwise, returns `IsResolved` with the
111+
// expectation that the hook updates `Value`.
112+
virtual std::optional<bool> evaluateFixup(MCFixup &Fixup, MCValue &Target,
113+
uint64_t &Value) {
114+
return {};
112115
}
113116

114117
void maybeAddReloc(const MCFragment &, const MCFixup &, const MCValue &,

llvm/include/llvm/MC/MCValue.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ class MCValue {
4242
friend class MCExpr;
4343
MCValue() = default;
4444
int64_t getConstant() const { return Cst; }
45+
void setConstant(int64_t C) { Cst = C; }
4546
uint32_t getSpecifier() const { return Specifier; }
4647
void setSpecifier(uint32_t S) { Specifier = S; }
4748

llvm/lib/MC/MCAssembler.cpp

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -161,11 +161,13 @@ bool MCAssembler::evaluateFixup(const MCFragment &F, MCFixup &Fixup,
161161
return true;
162162
}
163163

164-
bool IsResolved = false;
164+
// TODO: Require targets to set PCRel at fixup creation time.
165165
unsigned FixupFlags = getBackend().getFixupKindInfo(Fixup.getKind()).Flags;
166-
bool IsPCRel = FixupFlags & MCFixupKindInfo::FKF_IsPCRel;
167-
if (FixupFlags & MCFixupKindInfo::FKF_IsTarget) {
168-
IsResolved = getBackend().evaluateTargetFixup(Fixup, Target, Value);
166+
if (FixupFlags & MCFixupKindInfo::FKF_IsPCRel)
167+
Fixup.setPCRel();
168+
bool IsResolved = false;
169+
if (auto State = getBackend().evaluateFixup(Fixup, Target, Value)) {
170+
IsResolved = *State;
169171
} else {
170172
const MCSymbol *Add = Target.getAddSym();
171173
const MCSymbol *Sub = Target.getSubSym();
@@ -177,7 +179,7 @@ bool MCAssembler::evaluateFixup(const MCFragment &F, MCFixup &Fixup,
177179

178180
bool ShouldAlignPC =
179181
FixupFlags & MCFixupKindInfo::FKF_IsAlignedDownTo32Bits;
180-
if (IsPCRel) {
182+
if (Fixup.isPCRel()) {
181183
uint64_t Offset = getFragmentOffset(F) + Fixup.getOffset();
182184

183185
// A number of ARM fixups in Thumb mode require that the effective PC
@@ -202,8 +204,6 @@ bool MCAssembler::evaluateFixup(const MCFragment &F, MCFixup &Fixup,
202204

203205
if (IsResolved && mc::isRelocRelocation(Fixup.getKind()))
204206
IsResolved = false;
205-
if (IsPCRel)
206-
Fixup.setPCRel();
207207
getBackend().applyFixup(F, Fixup, Target, Contents, Value, IsResolved);
208208
return true;
209209
}

llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -70,10 +70,8 @@ MCFixupKindInfo RISCVAsmBackend::getFixupKindInfo(MCFixupKind Kind) const {
7070
{"fixup_riscv_12_i", 20, 12, 0},
7171
{"fixup_riscv_lo12_s", 0, 32, 0},
7272
{"fixup_riscv_pcrel_hi20", 12, 20, MCFixupKindInfo::FKF_IsPCRel},
73-
{"fixup_riscv_pcrel_lo12_i", 20, 12,
74-
MCFixupKindInfo::FKF_IsPCRel | MCFixupKindInfo::FKF_IsTarget},
75-
{"fixup_riscv_pcrel_lo12_s", 0, 32,
76-
MCFixupKindInfo::FKF_IsPCRel | MCFixupKindInfo::FKF_IsTarget},
73+
{"fixup_riscv_pcrel_lo12_i", 20, 12, MCFixupKindInfo::FKF_IsPCRel},
74+
{"fixup_riscv_pcrel_lo12_s", 0, 32, MCFixupKindInfo::FKF_IsPCRel},
7775
{"fixup_riscv_jal", 12, 20, MCFixupKindInfo::FKF_IsPCRel},
7876
{"fixup_riscv_branch", 0, 32, MCFixupKindInfo::FKF_IsPCRel},
7977
{"fixup_riscv_rvc_jump", 2, 11, MCFixupKindInfo::FKF_IsPCRel},
@@ -657,15 +655,16 @@ static const MCFixup *getPCRelHiFixup(const MCSpecifierExpr &Expr,
657655
return nullptr;
658656
}
659657

660-
bool RISCVAsmBackend::evaluateTargetFixup(const MCFixup &Fixup,
661-
const MCValue &Target,
662-
uint64_t &Value) {
658+
std::optional<bool> RISCVAsmBackend::evaluateFixup(MCFixup &Fixup,
659+
MCValue &Target,
660+
uint64_t &Value) {
663661
const MCFixup *AUIPCFixup;
664662
const MCFragment *AUIPCDF;
665663
MCValue AUIPCTarget;
666664
switch (Fixup.getTargetKind()) {
667665
default:
668-
llvm_unreachable("Unexpected fixup kind!");
666+
// Use default handling for `Value` and `IsResolved`.
667+
return {};
669668
case RISCV::fixup_riscv_pcrel_lo12_i:
670669
case RISCV::fixup_riscv_pcrel_lo12_s: {
671670
AUIPCFixup =

llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,8 +47,8 @@ class RISCVAsmBackend : public MCAsmBackend {
4747
bool shouldInsertFixupForCodeAlign(MCAssembler &Asm,
4848
MCAlignFragment &AF) override;
4949

50-
bool evaluateTargetFixup(const MCFixup &Fixup, const MCValue &Target,
51-
uint64_t &Value) override;
50+
std::optional<bool> evaluateFixup(MCFixup &Fixup, MCValue &Target,
51+
uint64_t &Value) override;
5252

5353
bool addReloc(const MCFragment &, const MCFixup &, const MCValue &,
5454
uint64_t &FixedValue, bool IsResolved);

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

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -169,7 +169,8 @@ class X86AsmBackend : public MCAsmBackend {
169169

170170
MCFixupKindInfo getFixupKindInfo(MCFixupKind Kind) const override;
171171

172-
bool shouldForceRelocation(const MCFixup &, const MCValue &);
172+
std::optional<bool> evaluateFixup(MCFixup &Fixup, MCValue &Target,
173+
uint64_t &Value) override;
173174

174175
void applyFixup(const MCFragment &, const MCFixup &, const MCValue &Target,
175176
MutableArrayRef<char> Data, uint64_t Value,
@@ -687,6 +688,40 @@ static unsigned getFixupKindSize(unsigned Kind) {
687688
}
688689
}
689690

691+
// Adjust PC-relative fixup offsets, which are calculated from the start of the
692+
// next instruction.
693+
std::optional<bool>
694+
X86AsmBackend::evaluateFixup(MCFixup &Fixup, MCValue &Target, uint64_t &Value) {
695+
switch (Fixup.getTargetKind()) {
696+
case FK_PCRel_1:
697+
Target.setConstant(Target.getConstant() - 1);
698+
break;
699+
case FK_PCRel_2:
700+
Target.setConstant(Target.getConstant() - 2);
701+
break;
702+
case FK_PCRel_4:
703+
case X86::reloc_riprel_4byte:
704+
case X86::reloc_riprel_4byte_movq_load:
705+
case X86::reloc_riprel_4byte_movq_load_rex2:
706+
case X86::reloc_riprel_4byte_relax:
707+
case X86::reloc_riprel_4byte_relax_rex:
708+
case X86::reloc_riprel_4byte_relax_rex2:
709+
case X86::reloc_branch_4byte_pcrel:
710+
case X86::reloc_riprel_4byte_relax_evex: {
711+
Target.setConstant(Target.getConstant() - 4);
712+
auto *Add = Target.getAddSym();
713+
// If this is a pc-relative load off _GLOBAL_OFFSET_TABLE_:
714+
// leaq _GLOBAL_OFFSET_TABLE_(%rip), %r15
715+
// this needs to be a GOTPC32 relocation.
716+
if (Add && Add->getName() == "_GLOBAL_OFFSET_TABLE_")
717+
Fixup = MCFixup::create(Fixup.getOffset(), Fixup.getValue(),
718+
X86::reloc_global_offset_table);
719+
} break;
720+
}
721+
// Use default handling for `Value` and `IsResolved`.
722+
return {};
723+
}
724+
690725
void X86AsmBackend::applyFixup(const MCFragment &F, const MCFixup &Fixup,
691726
const MCValue &Target,
692727
MutableArrayRef<char> Data, uint64_t Value,

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

Lines changed: 1 addition & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -576,18 +576,10 @@ void X86MCCodeEmitter::emitImmediate(const MCOperand &DispOp, SMLoc Loc,
576576
}
577577
}
578578

579-
// If the fixup is pc-relative, we need to bias the value to be relative to
580-
// the start of the field, not the end of the field.
581579
bool PCRel = false;
582580
switch (FixupKind) {
583581
case FK_PCRel_1:
584-
PCRel = true;
585-
ImmOffset -= 1;
586-
break;
587582
case FK_PCRel_2:
588-
PCRel = true;
589-
ImmOffset -= 2;
590-
break;
591583
case FK_PCRel_4:
592584
case X86::reloc_riprel_4byte:
593585
case X86::reloc_riprel_4byte_movq_load:
@@ -598,20 +590,14 @@ void X86MCCodeEmitter::emitImmediate(const MCOperand &DispOp, SMLoc Loc,
598590
case X86::reloc_branch_4byte_pcrel:
599591
case X86::reloc_riprel_4byte_relax_evex:
600592
PCRel = true;
601-
ImmOffset -= 4;
602-
// If this is a pc-relative load off _GLOBAL_OFFSET_TABLE_:
603-
// leaq _GLOBAL_OFFSET_TABLE_(%rip), %r15
604-
// this needs to be a GOTPC32 relocation.
605-
if (startsWithGlobalOffsetTable(Expr) != GOT_None)
606-
FixupKind = X86::reloc_global_offset_table;
607593
break;
608594
}
609595

610596
if (ImmOffset)
611597
Expr = MCBinaryExpr::createAdd(Expr, MCConstantExpr::create(ImmOffset, Ctx),
612598
Ctx, Expr->getLoc());
613599

614-
// Emit a symbolic constant as a fixup and 4 zeros.
600+
// Emit a symbolic constant as a fixup and a few zero bytes.
615601
Fixups.push_back(MCFixup::create(static_cast<uint32_t>(CB.size() - StartByte),
616602
Expr, FixupKind, PCRel));
617603
emitConstant(0, Size, CB);

llvm/test/MC/ELF/mc-dump.s

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
# CHECK-NEXT: Symbol @0 _start
1414
# CHECK-NEXT:0 Org Offset:3 Value:0
1515
# CHECK-NEXT:3 Relaxable Size:2 <MCInst #1996 <MCOperand Expr:.Ltmp0>>
16-
# CHECK-NEXT: Fixup @1 Value:.Ltmp0-1 Kind:4006
16+
# CHECK-NEXT: Fixup @1 Value:.Ltmp0 Kind:4006
1717
# CHECK-NEXT:5 Data Size:16 [48,8b,04,25,00,00,00,00,48,8b,04,25,00,00,00,00]
1818
# CHECK-NEXT: Fixup @4 Value:f0@<variant 11> Kind:4021
1919
# CHECK-NEXT: Fixup @12 Value:_start@<variant 11> Kind:4021

llvm/test/MC/X86/avx-64-att.s

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4125,7 +4125,7 @@ _foo:
41254125

41264126
// CHECK: vblendvps %ymm1, _foo2(%rip), %ymm0, %ymm0
41274127
// CHECK: encoding: [0xc4,0xe3,0x7d,0x4a,0x05,A,A,A,A,0x10]
4128-
// CHECK: fixup A - offset: 5, value: _foo2-5
4128+
// CHECK: fixup A - offset: 5, value: _foo2-1
41294129
_foo2:
41304130
nop
41314131
vblendvps %ymm1, _foo2(%rip), %ymm0, %ymm0

0 commit comments

Comments
 (0)