mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-02-21 21:29:41 +00:00
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
This commit is contained in:
parent
f3857c334f
commit
5eb7481d03
@ -19,11 +19,13 @@ class MCSymbolELF : public MCSymbol {
|
|||||||
|
|
||||||
mutable unsigned BindingSet : 1;
|
mutable unsigned BindingSet : 1;
|
||||||
mutable unsigned UsedInReloc : 1;
|
mutable unsigned UsedInReloc : 1;
|
||||||
|
mutable unsigned WeakrefUsedInReloc : 1;
|
||||||
mutable unsigned IsSignature : 1;
|
mutable unsigned IsSignature : 1;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
MCSymbolELF(const StringMapEntry<bool> *Name, bool isTemporary)
|
MCSymbolELF(const StringMapEntry<bool> *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; }
|
void setSize(const MCExpr *SS) { SymbolSize = SS; }
|
||||||
|
|
||||||
const MCExpr *getSize() const { return SymbolSize; }
|
const MCExpr *getSize() const { return SymbolSize; }
|
||||||
@ -45,6 +47,9 @@ public:
|
|||||||
void setUsedInReloc() const;
|
void setUsedInReloc() const;
|
||||||
bool isUsedInReloc() const;
|
bool isUsedInReloc() const;
|
||||||
|
|
||||||
|
void setIsWeakrefUsedInReloc() const;
|
||||||
|
bool isWeakrefUsedInReloc() const;
|
||||||
|
|
||||||
void setIsSignature() const;
|
void setIsSignature() const;
|
||||||
bool isSignature() const;
|
bool isSignature() const;
|
||||||
|
|
||||||
|
@ -98,7 +98,6 @@ class ELFObjectWriter : public MCObjectWriter {
|
|||||||
/// The target specific ELF writer instance.
|
/// The target specific ELF writer instance.
|
||||||
std::unique_ptr<MCELFObjectTargetWriter> TargetObjectWriter;
|
std::unique_ptr<MCELFObjectTargetWriter> TargetObjectWriter;
|
||||||
|
|
||||||
SmallPtrSet<const MCSymbol *, 16> WeakrefUsedInReloc;
|
|
||||||
DenseMap<const MCSymbolELF *, const MCSymbolELF *> Renames;
|
DenseMap<const MCSymbolELF *, const MCSymbolELF *> Renames;
|
||||||
|
|
||||||
llvm::DenseMap<const MCSectionELF *, std::vector<ELFRelocationEntry>>
|
llvm::DenseMap<const MCSectionELF *, std::vector<ELFRelocationEntry>>
|
||||||
@ -141,7 +140,6 @@ class ELFObjectWriter : public MCObjectWriter {
|
|||||||
: MCObjectWriter(OS, IsLittleEndian), TargetObjectWriter(MOTW) {}
|
: MCObjectWriter(OS, IsLittleEndian), TargetObjectWriter(MOTW) {}
|
||||||
|
|
||||||
void reset() override {
|
void reset() override {
|
||||||
WeakrefUsedInReloc.clear();
|
|
||||||
Renames.clear();
|
Renames.clear();
|
||||||
Relocations.clear();
|
Relocations.clear();
|
||||||
StrTabBuilder.clear();
|
StrTabBuilder.clear();
|
||||||
@ -589,25 +587,6 @@ bool ELFObjectWriter::shouldRelocateWithSymbol(const MCAssembler &Asm,
|
|||||||
return false;
|
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
// True if the assembler knows nothing about the final value of the symbol.
|
// 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
|
// 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.
|
// 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 MCSymbolRefExpr *RefA = Target.getSymA();
|
||||||
const auto *SymA = RefA ? cast<MCSymbolELF>(&RefA->getSymbol()) : nullptr;
|
const auto *SymA = RefA ? cast<MCSymbolELF>(&RefA->getSymbol()) : nullptr;
|
||||||
|
|
||||||
|
bool ViaWeakRef = false;
|
||||||
|
if (SymA && SymA->isVariable()) {
|
||||||
|
const MCExpr *Expr = SymA->getVariableValue();
|
||||||
|
if (const auto *Inner = dyn_cast<MCSymbolRefExpr>(Expr)) {
|
||||||
|
if (Inner->getKind() == MCSymbolRefExpr::VK_WEAKREF) {
|
||||||
|
SymA = cast<MCSymbolELF>(&Inner->getSymbol());
|
||||||
|
ViaWeakRef = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
unsigned Type = GetRelocType(Target, Fixup, IsPCRel);
|
unsigned Type = GetRelocType(Target, Fixup, IsPCRel);
|
||||||
bool RelocateWithSymbol = shouldRelocateWithSymbol(Asm, RefA, SymA, C, Type);
|
bool RelocateWithSymbol = shouldRelocateWithSymbol(Asm, RefA, SymA, C, Type);
|
||||||
if (!RelocateWithSymbol && SymA && !SymA->isUndefined())
|
if (!RelocateWithSymbol && SymA && !SymA->isUndefined())
|
||||||
@ -709,8 +699,8 @@ void ELFObjectWriter::RecordRelocation(MCAssembler &Asm,
|
|||||||
if (const MCSymbolELF *R = Renames.lookup(SymA))
|
if (const MCSymbolELF *R = Renames.lookup(SymA))
|
||||||
SymA = R;
|
SymA = R;
|
||||||
|
|
||||||
if (const MCSymbol *WeakRef = getWeakRef(*RefA))
|
if (ViaWeakRef)
|
||||||
WeakrefUsedInReloc.insert(WeakRef);
|
SymA->setIsWeakrefUsedInReloc();
|
||||||
else
|
else
|
||||||
SymA->setUsedInReloc();
|
SymA->setUsedInReloc();
|
||||||
}
|
}
|
||||||
@ -785,7 +775,7 @@ void ELFObjectWriter::computeSymbolTable(
|
|||||||
for (const MCSymbol &S : Asm.symbols()) {
|
for (const MCSymbol &S : Asm.symbols()) {
|
||||||
const auto &Symbol = cast<MCSymbolELF>(S);
|
const auto &Symbol = cast<MCSymbolELF>(S);
|
||||||
bool Used = Symbol.isUsedInReloc();
|
bool Used = Symbol.isUsedInReloc();
|
||||||
bool WeakrefUsed = WeakrefUsedInReloc.count(&Symbol);
|
bool WeakrefUsed = Symbol.isWeakrefUsedInReloc();
|
||||||
bool isSignature = Symbol.isSignature();
|
bool isSignature = Symbol.isSignature();
|
||||||
|
|
||||||
if (!isInSymtab(Layout, Symbol, Used || WeakrefUsed || isSignature,
|
if (!isInSymtab(Layout, Symbol, Used || WeakrefUsed || isSignature,
|
||||||
@ -809,8 +799,6 @@ void ELFObjectWriter::computeSymbolTable(
|
|||||||
} else {
|
} else {
|
||||||
MSD.SectionIndex = ELF::SHN_UNDEF;
|
MSD.SectionIndex = ELF::SHN_UNDEF;
|
||||||
}
|
}
|
||||||
if (!Used && WeakrefUsed)
|
|
||||||
Symbol.setBinding(ELF::STB_WEAK);
|
|
||||||
} else {
|
} else {
|
||||||
const MCSectionELF &Section =
|
const MCSectionELF &Section =
|
||||||
static_cast<const MCSectionELF &>(Symbol.getSection());
|
static_cast<const MCSectionELF &>(Symbol.getSection());
|
||||||
|
@ -601,6 +601,13 @@ bool MCExpr::evaluateAsValue(MCValue &Res, const MCAsmLayout &Layout) const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static bool canExpand(const MCSymbol &Sym, const MCAssembler *Asm, bool InSet) {
|
static bool canExpand(const MCSymbol &Sym, const MCAssembler *Asm, bool InSet) {
|
||||||
|
const MCExpr *Expr = Sym.getVariableValue();
|
||||||
|
const auto *Inner = dyn_cast<MCSymbolRefExpr>(Expr);
|
||||||
|
if (Inner) {
|
||||||
|
if (Inner->getKind() == MCSymbolRefExpr::VK_WEAKREF)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if (InSet)
|
if (InSet)
|
||||||
return true;
|
return true;
|
||||||
if (!Asm)
|
if (!Asm)
|
||||||
|
@ -35,6 +35,8 @@ unsigned MCSymbolELF::getBinding() const {
|
|||||||
return ELF::STB_LOCAL;
|
return ELF::STB_LOCAL;
|
||||||
if (isUsedInReloc())
|
if (isUsedInReloc())
|
||||||
return ELF::STB_GLOBAL;
|
return ELF::STB_GLOBAL;
|
||||||
|
if (isWeakrefUsedInReloc())
|
||||||
|
return ELF::STB_WEAK;
|
||||||
if (isSignature())
|
if (isSignature())
|
||||||
return ELF::STB_LOCAL;
|
return ELF::STB_LOCAL;
|
||||||
return ELF::STB_GLOBAL;
|
return ELF::STB_GLOBAL;
|
||||||
@ -96,6 +98,10 @@ bool MCSymbolELF::isUsedInReloc() const {
|
|||||||
return UsedInReloc;
|
return UsedInReloc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MCSymbolELF::setIsWeakrefUsedInReloc() const { WeakrefUsedInReloc = true; }
|
||||||
|
|
||||||
|
bool MCSymbolELF::isWeakrefUsedInReloc() const { return WeakrefUsedInReloc; }
|
||||||
|
|
||||||
void MCSymbolELF::setIsSignature() const { IsSignature = true; }
|
void MCSymbolELF::setIsSignature() const { IsSignature = true; }
|
||||||
|
|
||||||
bool MCSymbolELF::isSignature() const { return IsSignature; }
|
bool MCSymbolELF::isSignature() const { return IsSignature; }
|
||||||
|
Loading…
x
Reference in New Issue
Block a user