aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/MC/MCObjectStreamer.cpp
diff options
context:
space:
mode:
authorFangrui Song <i@maskray.me>2025-04-12 19:02:07 -0700
committerFangrui Song <i@maskray.me>2025-04-12 19:02:07 -0700
commit39662922e15c53f54da93b5a1d029589d49caec9 (patch)
treefb0b4b9eedc7865f505fd05959e9dd386b19e6b6 /llvm/lib/MC/MCObjectStreamer.cpp
parentb0acbbee88f8ae706658f2a7635df4ce39e15e74 (diff)
downloadllvm-39662922e15c53f54da93b5a1d029589d49caec9.zip
llvm-39662922e15c53f54da93b5a1d029589d49caec9.tar.gz
llvm-39662922e15c53f54da93b5a1d029589d49caec9.tar.bz2
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).
Diffstat (limited to 'llvm/lib/MC/MCObjectStreamer.cpp')
-rw-r--r--llvm/lib/MC/MCObjectStreamer.cpp26
1 files changed, 14 insertions, 12 deletions
diff --git a/llvm/lib/MC/MCObjectStreamer.cpp b/llvm/lib/MC/MCObjectStreamer.cpp
index e228418..e9295f0 100644
--- a/llvm/lib/MC/MCObjectStreamer.cpp
+++ b/llvm/lib/MC/MCObjectStreamer.cpp
@@ -94,8 +94,12 @@ void MCObjectStreamer::resolvePendingFixups() {
static std::optional<uint64_t> 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<MCDataFragment>(Lo->getFragment());
+ if (!LoF || Hi->getFragment() != LoF || LoF->isLinkerRelaxable())
return std::nullopt;
return Hi->getOffset() - Lo->getOffset();
@@ -104,20 +108,18 @@ static std::optional<uint64_t> absoluteSymbolDiff(const MCSymbol *Hi,
void MCObjectStreamer::emitAbsoluteSymbolDiff(const MCSymbol *Hi,
const MCSymbol *Lo,
unsigned Size) {
- if (!getAssembler().getContext().getTargetTriple().isRISCV())
- if (std::optional<uint64_t> Diff = absoluteSymbolDiff(Hi, Lo))
- return emitIntValue(*Diff, Size);
- MCStreamer::emitAbsoluteSymbolDiff(Hi, Lo, Size);
+ if (std::optional<uint64_t> 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<uint64_t> Diff = absoluteSymbolDiff(Hi, Lo)) {
- emitULEB128IntValue(*Diff);
- return;
- }
- MCStreamer::emitAbsoluteSymbolDiffAsULEB128(Hi, Lo);
+ if (std::optional<uint64_t> Diff = absoluteSymbolDiff(Hi, Lo))
+ emitULEB128IntValue(*Diff);
+ else
+ MCStreamer::emitAbsoluteSymbolDiffAsULEB128(Hi, Lo);
}
void MCObjectStreamer::reset() {