From 39662922e15c53f54da93b5a1d029589d49caec9 Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Sat, 12 Apr 2025 19:02:07 -0700 Subject: [PATCH] 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). --- llvm/lib/MC/MCObjectStreamer.cpp | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/llvm/lib/MC/MCObjectStreamer.cpp b/llvm/lib/MC/MCObjectStreamer.cpp index e228418fea98..e9295f0e21dd 100644 --- a/llvm/lib/MC/MCObjectStreamer.cpp +++ b/llvm/lib/MC/MCObjectStreamer.cpp @@ -94,8 +94,12 @@ void MCObjectStreamer::resolvePendingFixups() { static std::optional absoluteSymbolDiff(const MCSymbol *Hi, const MCSymbol *Lo) { assert(Hi && Lo); - if (!Hi->getFragment() || Hi->getFragment() != Lo->getFragment() || - Hi->isVariable() || Lo->isVariable()) + if (Lo == Hi) + return 0; + if (Hi->isVariable() || Lo->isVariable()) + return std::nullopt; + auto *LoF = dyn_cast_or_null(Lo->getFragment()); + if (!LoF || Hi->getFragment() != LoF || LoF->isLinkerRelaxable()) return std::nullopt; return Hi->getOffset() - Lo->getOffset(); @@ -104,20 +108,18 @@ static std::optional absoluteSymbolDiff(const MCSymbol *Hi, void MCObjectStreamer::emitAbsoluteSymbolDiff(const MCSymbol *Hi, const MCSymbol *Lo, unsigned Size) { - if (!getAssembler().getContext().getTargetTriple().isRISCV()) - if (std::optional Diff = absoluteSymbolDiff(Hi, Lo)) - return emitIntValue(*Diff, Size); - MCStreamer::emitAbsoluteSymbolDiff(Hi, Lo, Size); + if (std::optional Diff = absoluteSymbolDiff(Hi, Lo)) + emitIntValue(*Diff, Size); + else + MCStreamer::emitAbsoluteSymbolDiff(Hi, Lo, Size); } void MCObjectStreamer::emitAbsoluteSymbolDiffAsULEB128(const MCSymbol *Hi, const MCSymbol *Lo) { - if (!getAssembler().getContext().getTargetTriple().isRISCV()) - if (std::optional Diff = absoluteSymbolDiff(Hi, Lo)) { - emitULEB128IntValue(*Diff); - return; - } - MCStreamer::emitAbsoluteSymbolDiffAsULEB128(Hi, Lo); + if (std::optional Diff = absoluteSymbolDiff(Hi, Lo)) + emitULEB128IntValue(*Diff); + else + MCStreamer::emitAbsoluteSymbolDiffAsULEB128(Hi, Lo); } void MCObjectStreamer::reset() {