Skip to content

Commit 3966292

Browse files
committed
MCObjectStreamer: Refine absoluteSymbolDiff condition
The function is called to test the fast path - when Lo/Hi are within the same fragment. This is unsafe - Lo/Hi at the begin and end of a relaxable fragment should not evaluate to a constant. However, we don't have tests that exercise the code path. Nevertheless, make the check safer and remove the now unnecessary isRISCV check (from https://reviews.llvm.org/D103539).
1 parent b0acbbe commit 3966292

File tree

1 file changed

+14
-12
lines changed

1 file changed

+14
-12
lines changed

llvm/lib/MC/MCObjectStreamer.cpp

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -94,8 +94,12 @@ void MCObjectStreamer::resolvePendingFixups() {
9494
static std::optional<uint64_t> absoluteSymbolDiff(const MCSymbol *Hi,
9595
const MCSymbol *Lo) {
9696
assert(Hi && Lo);
97-
if (!Hi->getFragment() || Hi->getFragment() != Lo->getFragment() ||
98-
Hi->isVariable() || Lo->isVariable())
97+
if (Lo == Hi)
98+
return 0;
99+
if (Hi->isVariable() || Lo->isVariable())
100+
return std::nullopt;
101+
auto *LoF = dyn_cast_or_null<MCDataFragment>(Lo->getFragment());
102+
if (!LoF || Hi->getFragment() != LoF || LoF->isLinkerRelaxable())
99103
return std::nullopt;
100104

101105
return Hi->getOffset() - Lo->getOffset();
@@ -104,20 +108,18 @@ static std::optional<uint64_t> absoluteSymbolDiff(const MCSymbol *Hi,
104108
void MCObjectStreamer::emitAbsoluteSymbolDiff(const MCSymbol *Hi,
105109
const MCSymbol *Lo,
106110
unsigned Size) {
107-
if (!getAssembler().getContext().getTargetTriple().isRISCV())
108-
if (std::optional<uint64_t> Diff = absoluteSymbolDiff(Hi, Lo))
109-
return emitIntValue(*Diff, Size);
110-
MCStreamer::emitAbsoluteSymbolDiff(Hi, Lo, Size);
111+
if (std::optional<uint64_t> Diff = absoluteSymbolDiff(Hi, Lo))
112+
emitIntValue(*Diff, Size);
113+
else
114+
MCStreamer::emitAbsoluteSymbolDiff(Hi, Lo, Size);
111115
}
112116

113117
void MCObjectStreamer::emitAbsoluteSymbolDiffAsULEB128(const MCSymbol *Hi,
114118
const MCSymbol *Lo) {
115-
if (!getAssembler().getContext().getTargetTriple().isRISCV())
116-
if (std::optional<uint64_t> Diff = absoluteSymbolDiff(Hi, Lo)) {
117-
emitULEB128IntValue(*Diff);
118-
return;
119-
}
120-
MCStreamer::emitAbsoluteSymbolDiffAsULEB128(Hi, Lo);
119+
if (std::optional<uint64_t> Diff = absoluteSymbolDiff(Hi, Lo))
120+
emitULEB128IntValue(*Diff);
121+
else
122+
MCStreamer::emitAbsoluteSymbolDiffAsULEB128(Hi, Lo);
121123
}
122124

123125
void MCObjectStreamer::reset() {

0 commit comments

Comments
 (0)