diff options
author | Rafael Espindola <rafael.espindola@gmail.com> | 2014-05-03 19:57:04 +0000 |
---|---|---|
committer | Rafael Espindola <rafael.espindola@gmail.com> | 2014-05-03 19:57:04 +0000 |
commit | 3d082fa50704f55a3c6d25c9d6b25d652e7d84ae (patch) | |
tree | a3aff89a7742699070c17f25e005b1f04fdeb4a7 /llvm/lib/MC/ELFObjectWriter.cpp | |
parent | 834652ade026fa990a110c8bc572f988d94a18a5 (diff) | |
download | bcm5719-llvm-3d082fa50704f55a3c6d25c9d6b25d652e7d84ae.tar.gz bcm5719-llvm-3d082fa50704f55a3c6d25c9d6b25d652e7d84ae.zip |
Fix pr19645.
The fix itself is fairly simple: move getAccessVariant to MCValue so that we
replace the old weak expression evaluation with the far more general
EvaluateAsRelocatable.
This then requires that EvaluateAsRelocatable stop when it finds a non
trivial reference kind. And that in turn requires the ELF writer to look
harder for weak references.
Last but not least, this found a case where we were being bug by bug
compatible with gas and accepting an invalid input. I reported pr19647
to track it.
llvm-svn: 207920
Diffstat (limited to 'llvm/lib/MC/ELFObjectWriter.cpp')
-rw-r--r-- | llvm/lib/MC/ELFObjectWriter.cpp | 23 |
1 files changed, 21 insertions, 2 deletions
diff --git a/llvm/lib/MC/ELFObjectWriter.cpp b/llvm/lib/MC/ELFObjectWriter.cpp index 3bce1211920..0a54627f8cd 100644 --- a/llvm/lib/MC/ELFObjectWriter.cpp +++ b/llvm/lib/MC/ELFObjectWriter.cpp @@ -787,6 +787,25 @@ bool ELFObjectWriter::shouldRelocateWithSymbol(const MCAssembler &Asm, return false; } +static const MCSymbol *getWeakRef(const MCSymbolRefExpr &Ref) { + const MCSymbol &Sym = Ref.getSymbol(); + + if (Ref.getKind() == MCSymbolRefExpr::VK_WEAKREF) + return &Sym; + + if (!Sym.isVariable()) + return nullptr; + + const MCExpr *Expr = Sym.getVariableValue(); + const auto *Inner = dyn_cast<MCSymbolRefExpr>(Expr); + if (!Inner) + return nullptr; + + if (Inner->getKind() == MCSymbolRefExpr::VK_WEAKREF) + return &Inner->getSymbol(); + return nullptr; +} + void ELFObjectWriter::RecordRelocation(const MCAssembler &Asm, const MCAsmLayout &Layout, const MCFragment *Fragment, @@ -872,8 +891,8 @@ void ELFObjectWriter::RecordRelocation(const MCAssembler &Asm, if (const MCSymbol *R = Renames.lookup(SymA)) SymA = R; - if (RefA->getKind() == MCSymbolRefExpr::VK_WEAKREF) - WeakrefUsedInReloc.insert(SymA); + if (const MCSymbol *WeakRef = getWeakRef(*RefA)) + WeakrefUsedInReloc.insert(WeakRef); else UsedInReloc.insert(SymA); } |