Skip to content

Commit c512d95

Browse files
committed
MC: Generalize RISCV/LoongArch handleAddSubRelocations and AVR shouldForceRelocation
Introduce MCAsmBackend::addReloc to manage relocation appending. The default implementation uses shouldForceRelocation to check unresolved fixups and calls recordRelocation to append a relocation when needed. RISCV and LoongArch override addReloc to handle ADD/SUB relocations, with potential support for RELAX relocations in the future. AVR overrides addReloc to customize shouldForceRelocation behavior (#121498). applyFixup is moved into evaluateFixup.
1 parent 0487884 commit c512d95

File tree

11 files changed

+83
-60
lines changed

11 files changed

+83
-60
lines changed

llvm/include/llvm/MC/MCAsmBackend.h

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -116,13 +116,10 @@ class MCAsmBackend {
116116
llvm_unreachable("Need to implement hook if target has custom fixups");
117117
}
118118

119-
virtual bool handleAddSubRelocations(const MCAssembler &Asm,
120-
const MCFragment &F,
121-
const MCFixup &Fixup,
122-
const MCValue &Target,
123-
uint64_t &FixedValue) const {
124-
return false;
125-
}
119+
virtual bool addReloc(MCAssembler &Asm, const MCFragment &F,
120+
const MCFixup &Fixup, const MCValue &Target,
121+
uint64_t &FixedValue, bool IsResolved,
122+
const MCSubtargetInfo *);
126123

127124
/// Apply the \p Value for given \p Fixup into the provided data fragment, at
128125
/// the offset specified by the fixup and following the fixup kind as

llvm/include/llvm/MC/MCAssembler.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,8 @@ class MCAssembler {
9999
/// relocation.
100100
bool evaluateFixup(const MCFixup &Fixup, const MCFragment *DF,
101101
MCValue &Target, const MCSubtargetInfo *STI,
102-
uint64_t &Value, bool RecordReloc) const;
102+
uint64_t &Value, bool RecordReloc,
103+
MutableArrayRef<char> Contents) const;
103104

104105
/// Check whether a fixup can be satisfied, or whether it needs to be relaxed
105106
/// (increased in size, in order to hold its value correctly).

llvm/lib/MC/ELFObjectWriter.cpp

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1350,13 +1350,9 @@ void ELFObjectWriter::recordRelocation(MCAssembler &Asm,
13501350
MCFixupKindInfo::FKF_IsPCRel;
13511351
uint64_t FixupOffset = Asm.getFragmentOffset(*Fragment) + Fixup.getOffset();
13521352
uint64_t Addend = Target.getConstant();
1353-
if (auto *RefB = Target.getSubSym()) {
1354-
// When there is no relocation specifier, a linker relaxation target may
1355-
// emit ADD/SUB relocations for A-B+C.
1356-
if (SymA && Backend.handleAddSubRelocations(Asm, *Fragment, Fixup, Target,
1357-
FixedValue))
1358-
return;
1353+
// Handle special fixups like ADD/SUB relocation pairs.
13591354

1355+
if (auto *RefB = Target.getSubSym()) {
13601356
const auto &SymB = cast<MCSymbolELF>(*RefB);
13611357
if (SymB.isUndefined()) {
13621358
Ctx.reportError(Fixup.getLoc(),

llvm/lib/MC/MCAsmBackend.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,17 @@ bool MCAsmBackend::fixupNeedsRelaxationAdvanced(const MCAssembler &,
124124
return fixupNeedsRelaxation(Fixup, Value);
125125
}
126126

127+
bool MCAsmBackend::addReloc(MCAssembler &Asm, const MCFragment &F,
128+
const MCFixup &Fixup, const MCValue &Target,
129+
uint64_t &FixedValue, bool IsResolved,
130+
const MCSubtargetInfo *STI) {
131+
if (IsResolved && shouldForceRelocation(Asm, Fixup, Target, STI))
132+
IsResolved = false;
133+
if (!IsResolved)
134+
Asm.getWriter().recordRelocation(Asm, &F, Fixup, Target, FixedValue);
135+
return IsResolved;
136+
}
137+
127138
bool MCAsmBackend::isDarwinCanonicalPersonality(const MCSymbol *Sym) const {
128139
// Consider a NULL personality (ie., no personality encoding) to be canonical
129140
// because it's always at 0.

llvm/lib/MC/MCAssembler.cpp

Lines changed: 15 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,8 @@ bool MCAssembler::isThumbFunc(const MCSymbol *Symbol) const {
138138

139139
bool MCAssembler::evaluateFixup(const MCFixup &Fixup, const MCFragment *DF,
140140
MCValue &Target, const MCSubtargetInfo *STI,
141-
uint64_t &Value, bool RecordReloc) const {
141+
uint64_t &Value, bool RecordReloc,
142+
MutableArrayRef<char> Contents) const {
142143
++stats::evaluateFixup;
143144

144145
// FIXME: This code has some duplication with recordRelocation. We should
@@ -196,21 +197,13 @@ bool MCAssembler::evaluateFixup(const MCFixup &Fixup, const MCFragment *DF,
196197
if (!RecordReloc)
197198
return IsResolved;
198199

199-
// .reloc directive and the backend might force the relocation.
200-
// Backends that customize shouldForceRelocation generally just need the fixup
201-
// kind. AVR needs the fixup value to bypass the assembly time overflow with a
202-
// relocation.
203-
if (IsResolved) {
204-
auto TargetVal = Target;
205-
TargetVal.Cst = Value;
206-
if (mc::isRelocRelocation(Fixup.getKind()) ||
207-
getBackend().shouldForceRelocation(*this, Fixup, TargetVal, STI))
208-
IsResolved = false;
209-
}
210-
if (!IsResolved)
211-
getWriter().recordRelocation(const_cast<MCAssembler &>(*this), DF, Fixup,
212-
Target, Value);
213-
return IsResolved;
200+
if (IsResolved && mc::isRelocRelocation(Fixup.getKind()))
201+
IsResolved = false;
202+
IsResolved = getBackend().addReloc(const_cast<MCAssembler &>(*this), *DF,
203+
Fixup, Target, Value, IsResolved, STI);
204+
getBackend().applyFixup(*this, Fixup, Target, Contents, Value, IsResolved,
205+
STI);
206+
return true;
214207
}
215208

216209
uint64_t MCAssembler::computeFragmentSize(const MCFragment &F) const {
@@ -908,7 +901,7 @@ void MCAssembler::layout() {
908901
// Evaluate and apply the fixups, generating relocation entries as necessary.
909902
for (MCSection &Sec : *this) {
910903
for (MCFragment &Frag : Sec) {
911-
ArrayRef<MCFixup> Fixups;
904+
MutableArrayRef<MCFixup> Fixups;
912905
MutableArrayRef<char> Contents;
913906
const MCSubtargetInfo *STI = nullptr;
914907

@@ -974,10 +967,8 @@ void MCAssembler::layout() {
974967
for (const MCFixup &Fixup : Fixups) {
975968
uint64_t FixedValue;
976969
MCValue Target;
977-
bool IsResolved = evaluateFixup(Fixup, &Frag, Target, STI, FixedValue,
978-
/*RecordReloc=*/true);
979-
getBackend().applyFixup(*this, Fixup, Target, Contents, FixedValue,
980-
IsResolved, STI);
970+
evaluateFixup(Fixup, &Frag, Target, STI, FixedValue,
971+
/*RecordReloc=*/true, Contents);
981972
}
982973
}
983974
}
@@ -997,8 +988,9 @@ bool MCAssembler::fixupNeedsRelaxation(const MCFixup &Fixup,
997988
assert(getBackendPtr() && "Expected assembler backend");
998989
MCValue Target;
999990
uint64_t Value;
1000-
bool Resolved = evaluateFixup(Fixup, DF, Target, DF->getSubtargetInfo(),
1001-
Value, /*RecordReloc=*/false);
991+
bool Resolved =
992+
evaluateFixup(const_cast<MCFixup &>(Fixup), DF, Target,
993+
DF->getSubtargetInfo(), Value, /*RecordReloc=*/false, {});
1002994
return getBackend().fixupNeedsRelaxationAdvanced(*this, Fixup, Target, Value,
1003995
Resolved);
1004996
}

llvm/lib/Target/AVR/MCTargetDesc/AVRAsmBackend.cpp

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -368,6 +368,23 @@ AVRAsmBackend::createObjectTargetWriter() const {
368368
return createAVRELFObjectWriter(MCELFObjectTargetWriter::getOSABI(OSType));
369369
}
370370

371+
bool AVRAsmBackend::addReloc(MCAssembler &Asm, const MCFragment &F,
372+
const MCFixup &Fixup, const MCValue &Target,
373+
uint64_t &FixedValue, bool IsResolved,
374+
const MCSubtargetInfo *STI) {
375+
// AVR sets the fixup value to bypass the assembly time overflow with a
376+
// relocation.
377+
if (IsResolved) {
378+
auto TargetVal = MCValue::get(Target.getAddSym(), Target.getSubSym(),
379+
FixedValue, Target.getSpecifier());
380+
if (shouldForceRelocation(Asm, Fixup, TargetVal, STI))
381+
IsResolved = false;
382+
}
383+
if (!IsResolved)
384+
Asm.getWriter().recordRelocation(Asm, &F, Fixup, Target, FixedValue);
385+
return IsResolved;
386+
}
387+
371388
void AVRAsmBackend::applyFixup(const MCAssembler &Asm, const MCFixup &Fixup,
372389
const MCValue &Target,
373390
MutableArrayRef<char> Data, uint64_t Value,

llvm/lib/Target/AVR/MCTargetDesc/AVRAsmBackend.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,10 @@ class AVRAsmBackend : public MCAsmBackend {
3737
std::unique_ptr<MCObjectTargetWriter>
3838
createObjectTargetWriter() const override;
3939

40+
bool addReloc(MCAssembler &Asm, const MCFragment &F, const MCFixup &Fixup,
41+
const MCValue &Target, uint64_t &FixedValue, bool IsResolved,
42+
const MCSubtargetInfo *) override;
43+
4044
void applyFixup(const MCAssembler &Asm, const MCFixup &Fixup,
4145
const MCValue &Target, MutableArrayRef<char> Data,
4246
uint64_t Value, bool IsResolved,

llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchAsmBackend.cpp

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -436,11 +436,16 @@ bool LoongArchAsmBackend::writeNopData(raw_ostream &OS, uint64_t Count,
436436
return true;
437437
}
438438

439-
bool LoongArchAsmBackend::handleAddSubRelocations(const MCAssembler &Asm,
440-
const MCFragment &F,
441-
const MCFixup &Fixup,
442-
const MCValue &Target,
443-
uint64_t &FixedValue) const {
439+
bool LoongArchAsmBackend::addReloc(MCAssembler &Asm, const MCFragment &F,
440+
const MCFixup &Fixup, const MCValue &Target,
441+
uint64_t &FixedValue, bool IsResolved,
442+
const MCSubtargetInfo *CurSTI) {
443+
auto Fallback = [&]() {
444+
return MCAsmBackend::addReloc(Asm, F, Fixup, Target, FixedValue, IsResolved,
445+
CurSTI);
446+
};
447+
if (!Target.getSubSym())
448+
return Fallback();
444449
assert(Target.getSpecifier() == 0 &&
445450
"relocatable SymA-SymB cannot have relocation specifier");
446451
std::pair<MCFixupKind, MCFixupKind> FK;
@@ -458,7 +463,7 @@ bool LoongArchAsmBackend::handleAddSubRelocations(const MCAssembler &Asm,
458463
// is not same as the section of Fixup, it will report error. Just return
459464
// false and then this work can be finished by handleFixup.
460465
if (&SecA != &SecB)
461-
return false;
466+
return Fallback();
462467

463468
// In SecA == SecB case. If the linker relaxation is enabled, we need record
464469
// the ADD, SUB relocations. Otherwise the FixedValue has already been calc-
@@ -490,9 +495,8 @@ bool LoongArchAsmBackend::handleAddSubRelocations(const MCAssembler &Asm,
490495
MCValue B = MCValue::get(Target.getSubSym());
491496
auto FA = MCFixup::create(Fixup.getOffset(), nullptr, std::get<0>(FK));
492497
auto FB = MCFixup::create(Fixup.getOffset(), nullptr, std::get<1>(FK));
493-
auto &Assembler = const_cast<MCAssembler &>(Asm);
494-
Asm.getWriter().recordRelocation(Assembler, &F, FA, A, FixedValueA);
495-
Asm.getWriter().recordRelocation(Assembler, &F, FB, B, FixedValueB);
498+
Asm.getWriter().recordRelocation(Asm, &F, FA, A, FixedValueA);
499+
Asm.getWriter().recordRelocation(Asm, &F, FB, B, FixedValueB);
496500
FixedValue = FixedValueA - FixedValueB;
497501
return true;
498502
}

llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchAsmBackend.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,9 +35,9 @@ class LoongArchAsmBackend : public MCAsmBackend {
3535
LoongArchAsmBackend(const MCSubtargetInfo &STI, uint8_t OSABI, bool Is64Bit,
3636
const MCTargetOptions &Options);
3737

38-
bool handleAddSubRelocations(const MCAssembler &Asm, const MCFragment &F,
39-
const MCFixup &Fixup, const MCValue &Target,
40-
uint64_t &FixedValue) const override;
38+
bool addReloc(MCAssembler &Asm, const MCFragment &F, const MCFixup &Fixup,
39+
const MCValue &Target, uint64_t &FixedValue, bool IsResolved,
40+
const MCSubtargetInfo *) override;
4141

4242
void applyFixup(const MCAssembler &Asm, const MCFixup &Fixup,
4343
const MCValue &Target, MutableArrayRef<char> Data,

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

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -616,11 +616,13 @@ bool RISCVAsmBackend::evaluateTargetFixup(
616616
return AUIPCFixup->getTargetKind() == RISCV::fixup_riscv_pcrel_hi20;
617617
}
618618

619-
bool RISCVAsmBackend::handleAddSubRelocations(const MCAssembler &Asm,
620-
const MCFragment &F,
621-
const MCFixup &Fixup,
622-
const MCValue &Target,
623-
uint64_t &FixedValue) const {
619+
bool RISCVAsmBackend::addReloc(MCAssembler &Asm, const MCFragment &F,
620+
const MCFixup &Fixup, const MCValue &Target,
621+
uint64_t &FixedValue, bool IsResolved,
622+
const MCSubtargetInfo *STI) {
623+
if (!Target.getSubSym())
624+
return MCAsmBackend::addReloc(Asm, F, Fixup, Target, FixedValue, IsResolved,
625+
STI);
624626
assert(Target.getSpecifier() == 0 &&
625627
"relocatable SymA-SymB cannot have relocation specifier");
626628
uint64_t FixedValueA, FixedValueB;
@@ -653,9 +655,8 @@ bool RISCVAsmBackend::handleAddSubRelocations(const MCAssembler &Asm,
653655
MCValue B = MCValue::get(Target.getSubSym());
654656
auto FA = MCFixup::create(Fixup.getOffset(), nullptr, TA);
655657
auto FB = MCFixup::create(Fixup.getOffset(), nullptr, TB);
656-
auto &Assembler = const_cast<MCAssembler &>(Asm);
657-
Asm.getWriter().recordRelocation(Assembler, &F, FA, A, FixedValueA);
658-
Asm.getWriter().recordRelocation(Assembler, &F, FB, B, FixedValueB);
658+
Asm.getWriter().recordRelocation(Asm, &F, FA, A, FixedValueA);
659+
Asm.getWriter().recordRelocation(Asm, &F, FB, B, FixedValueB);
659660
FixedValue = FixedValueA - FixedValueB;
660661
return true;
661662
}

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -48,9 +48,9 @@ class RISCVAsmBackend : public MCAsmBackend {
4848
const MCSubtargetInfo *STI,
4949
uint64_t &Value) override;
5050

51-
bool handleAddSubRelocations(const MCAssembler &Asm, const MCFragment &F,
52-
const MCFixup &Fixup, const MCValue &Target,
53-
uint64_t &FixedValue) const override;
51+
bool addReloc(MCAssembler &Asm, const MCFragment &F, const MCFixup &Fixup,
52+
const MCValue &Target, uint64_t &FixedValue, bool IsResolved,
53+
const MCSubtargetInfo *) override;
5454

5555
void applyFixup(const MCAssembler &Asm, const MCFixup &Fixup,
5656
const MCValue &Target, MutableArrayRef<char> Data,

0 commit comments

Comments
 (0)