From 5eb7481d035dc9ad67335d2e36ee2aab1c010025 Mon Sep 17 00:00:00 2001 From: Rafael Espindola Date: Wed, 3 Jun 2015 21:52:06 +0000 Subject: [PATCH] Remember if a weakref of a symbol has been used. This avoids yet another last minute patching of the binding. While at it, also simplify the weakref implementation a bit by not walking past it in the expression evaluation. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@238982 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/MC/MCSymbolELF.h | 7 +++++- lib/MC/ELFObjectWriter.cpp | 40 ++++++++++++----------------------- lib/MC/MCExpr.cpp | 7 ++++++ lib/MC/MCSymbolELF.cpp | 6 ++++++ 4 files changed, 33 insertions(+), 27 deletions(-) diff --git a/include/llvm/MC/MCSymbolELF.h b/include/llvm/MC/MCSymbolELF.h index 63c7a6794bf..374e6b87f71 100644 --- a/include/llvm/MC/MCSymbolELF.h +++ b/include/llvm/MC/MCSymbolELF.h @@ -19,11 +19,13 @@ class MCSymbolELF : public MCSymbol { mutable unsigned BindingSet : 1; mutable unsigned UsedInReloc : 1; + mutable unsigned WeakrefUsedInReloc : 1; mutable unsigned IsSignature : 1; public: MCSymbolELF(const StringMapEntry *Name, bool isTemporary) - : MCSymbol(true, Name, isTemporary), BindingSet(false) {} + : MCSymbol(true, Name, isTemporary), BindingSet(false), + UsedInReloc(false), WeakrefUsedInReloc(false), IsSignature(false) {} void setSize(const MCExpr *SS) { SymbolSize = SS; } const MCExpr *getSize() const { return SymbolSize; } @@ -45,6 +47,9 @@ public: void setUsedInReloc() const; bool isUsedInReloc() const; + void setIsWeakrefUsedInReloc() const; + bool isWeakrefUsedInReloc() const; + void setIsSignature() const; bool isSignature() const; diff --git a/lib/MC/ELFObjectWriter.cpp b/lib/MC/ELFObjectWriter.cpp index bf9a29a41db..6e3f9d189dd 100644 --- a/lib/MC/ELFObjectWriter.cpp +++ b/lib/MC/ELFObjectWriter.cpp @@ -98,7 +98,6 @@ class ELFObjectWriter : public MCObjectWriter { /// The target specific ELF writer instance. std::unique_ptr TargetObjectWriter; - SmallPtrSet WeakrefUsedInReloc; DenseMap Renames; llvm::DenseMap> @@ -141,7 +140,6 @@ class ELFObjectWriter : public MCObjectWriter { : MCObjectWriter(OS, IsLittleEndian), TargetObjectWriter(MOTW) {} void reset() override { - WeakrefUsedInReloc.clear(); Renames.clear(); Relocations.clear(); StrTabBuilder.clear(); @@ -589,25 +587,6 @@ 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(Expr); - if (!Inner) - return nullptr; - - if (Inner->getKind() == MCSymbolRefExpr::VK_WEAKREF) - return &Inner->getSymbol(); - return nullptr; -} - // True if the assembler knows nothing about the final value of the symbol. // This doesn't cover the comdat issues, since in those cases the assembler // can at least know that all symbols in the section will move together. @@ -681,6 +660,17 @@ void ELFObjectWriter::RecordRelocation(MCAssembler &Asm, const MCSymbolRefExpr *RefA = Target.getSymA(); const auto *SymA = RefA ? cast(&RefA->getSymbol()) : nullptr; + bool ViaWeakRef = false; + if (SymA && SymA->isVariable()) { + const MCExpr *Expr = SymA->getVariableValue(); + if (const auto *Inner = dyn_cast(Expr)) { + if (Inner->getKind() == MCSymbolRefExpr::VK_WEAKREF) { + SymA = cast(&Inner->getSymbol()); + ViaWeakRef = true; + } + } + } + unsigned Type = GetRelocType(Target, Fixup, IsPCRel); bool RelocateWithSymbol = shouldRelocateWithSymbol(Asm, RefA, SymA, C, Type); if (!RelocateWithSymbol && SymA && !SymA->isUndefined()) @@ -709,8 +699,8 @@ void ELFObjectWriter::RecordRelocation(MCAssembler &Asm, if (const MCSymbolELF *R = Renames.lookup(SymA)) SymA = R; - if (const MCSymbol *WeakRef = getWeakRef(*RefA)) - WeakrefUsedInReloc.insert(WeakRef); + if (ViaWeakRef) + SymA->setIsWeakrefUsedInReloc(); else SymA->setUsedInReloc(); } @@ -785,7 +775,7 @@ void ELFObjectWriter::computeSymbolTable( for (const MCSymbol &S : Asm.symbols()) { const auto &Symbol = cast(S); bool Used = Symbol.isUsedInReloc(); - bool WeakrefUsed = WeakrefUsedInReloc.count(&Symbol); + bool WeakrefUsed = Symbol.isWeakrefUsedInReloc(); bool isSignature = Symbol.isSignature(); if (!isInSymtab(Layout, Symbol, Used || WeakrefUsed || isSignature, @@ -809,8 +799,6 @@ void ELFObjectWriter::computeSymbolTable( } else { MSD.SectionIndex = ELF::SHN_UNDEF; } - if (!Used && WeakrefUsed) - Symbol.setBinding(ELF::STB_WEAK); } else { const MCSectionELF &Section = static_cast(Symbol.getSection()); diff --git a/lib/MC/MCExpr.cpp b/lib/MC/MCExpr.cpp index 39ea8722547..f5e39e7815d 100644 --- a/lib/MC/MCExpr.cpp +++ b/lib/MC/MCExpr.cpp @@ -601,6 +601,13 @@ bool MCExpr::evaluateAsValue(MCValue &Res, const MCAsmLayout &Layout) const { } static bool canExpand(const MCSymbol &Sym, const MCAssembler *Asm, bool InSet) { + const MCExpr *Expr = Sym.getVariableValue(); + const auto *Inner = dyn_cast(Expr); + if (Inner) { + if (Inner->getKind() == MCSymbolRefExpr::VK_WEAKREF) + return false; + } + if (InSet) return true; if (!Asm) diff --git a/lib/MC/MCSymbolELF.cpp b/lib/MC/MCSymbolELF.cpp index 4e6def0c2e1..458248104e0 100644 --- a/lib/MC/MCSymbolELF.cpp +++ b/lib/MC/MCSymbolELF.cpp @@ -35,6 +35,8 @@ unsigned MCSymbolELF::getBinding() const { return ELF::STB_LOCAL; if (isUsedInReloc()) return ELF::STB_GLOBAL; + if (isWeakrefUsedInReloc()) + return ELF::STB_WEAK; if (isSignature()) return ELF::STB_LOCAL; return ELF::STB_GLOBAL; @@ -96,6 +98,10 @@ bool MCSymbolELF::isUsedInReloc() const { return UsedInReloc; } +void MCSymbolELF::setIsWeakrefUsedInReloc() const { WeakrefUsedInReloc = true; } + +bool MCSymbolELF::isWeakrefUsedInReloc() const { return WeakrefUsedInReloc; } + void MCSymbolELF::setIsSignature() const { IsSignature = true; } bool MCSymbolELF::isSignature() const { return IsSignature; } -- 2.34.1