diff options
Diffstat (limited to 'contrib/llvm-project/lld/MachO/Symbols.cpp')
-rw-r--r-- | contrib/llvm-project/lld/MachO/Symbols.cpp | 68 |
1 files changed, 48 insertions, 20 deletions
diff --git a/contrib/llvm-project/lld/MachO/Symbols.cpp b/contrib/llvm-project/lld/MachO/Symbols.cpp index 47f30d4141fc..bb6d073dcf30 100644 --- a/contrib/llvm-project/lld/MachO/Symbols.cpp +++ b/contrib/llvm-project/lld/MachO/Symbols.cpp @@ -14,6 +14,19 @@ using namespace llvm; using namespace lld; using namespace lld::macho; +static_assert(sizeof(void *) != 8 || sizeof(Symbol) == 48, + "Try to minimize Symbol's size; we create many instances"); + +// The Microsoft ABI doesn't support using parent class tail padding for child +// members, hence the _MSC_VER check. +#if !defined(_MSC_VER) +static_assert(sizeof(void *) != 8 || sizeof(Defined) == 80, + "Try to minimize Defined's size; we create many instances"); +#endif + +static_assert(sizeof(SymbolUnion) == sizeof(Defined), + "Defined should be the largest Symbol kind"); + // Returns a symbol for an error message. static std::string demangle(StringRef symName) { if (config->demangle) @@ -31,26 +44,34 @@ uint64_t Symbol::getStubVA() const { return in.stubs->getVA(stubsIndex); } uint64_t Symbol::getGotVA() const { return in.got->getVA(gotIndex); } uint64_t Symbol::getTlvVA() const { return in.tlvPointers->getVA(gotIndex); } -bool Symbol::isLive() const { - if (isa<DylibSymbol>(this) || isa<Undefined>(this)) - return used; - - if (auto *d = dyn_cast<Defined>(this)) { - // Non-absolute symbols might be alive because their section is - // no_dead_strip or live_support. In that case, the section will know - // that it's live but `used` might be false. Non-absolute symbols always - // have to use the section's `live` bit as source of truth. - if (d->isAbsolute()) - return used; - return d->isec->canonical()->isLive(d->value); +Defined::Defined(StringRefZ name, InputFile *file, InputSection *isec, + uint64_t value, uint64_t size, bool isWeakDef, bool isExternal, + bool isPrivateExtern, bool isThumb, + bool isReferencedDynamically, bool noDeadStrip, + bool canOverrideWeakDef, bool isWeakDefCanBeHidden) + : Symbol(DefinedKind, name, file), overridesWeakDef(canOverrideWeakDef), + privateExtern(isPrivateExtern), includeInSymtab(true), thumb(isThumb), + referencedDynamically(isReferencedDynamically), noDeadStrip(noDeadStrip), + weakDefCanBeHidden(isWeakDefCanBeHidden), weakDef(isWeakDef), + external(isExternal), isec(isec), value(value), size(size) { + if (isec) { + isec->symbols.push_back(this); + // Maintain sorted order. + for (auto it = isec->symbols.rbegin(), rend = isec->symbols.rend(); + it != rend; ++it) { + auto next = std::next(it); + if (next == rend) + break; + if ((*it)->value < (*next)->value) + std::swap(*next, *it); + else + break; + } } +} - assert(!isa<CommonSymbol>(this) && - "replaceCommonSymbols() runs before dead code stripping, and isLive() " - "should only be called after dead code stripping"); - - // Assume any other kind of symbol is live. - return true; +bool Defined::isTlv() const { + return !isAbsolute() && isThreadLocalVariables(isec->getFlags()); } uint64_t Defined::getVA() const { @@ -59,7 +80,7 @@ uint64_t Defined::getVA() const { if (isAbsolute()) return value; - if (!isec->canonical()->isFinal) { + if (!isec->isFinal) { // A target arch that does not use thunks ought never ask for // the address of a function that has not yet been finalized. assert(target->usesThunks()); @@ -70,7 +91,14 @@ uint64_t Defined::getVA() const { // expedient to return a contrived out-of-range address. return TargetInfo::outOfRangeVA; } - return isec->canonical()->getVA(value); + return isec->getVA(value); +} + +void Defined::canonicalize() { + if (unwindEntry) + unwindEntry = unwindEntry->canonical(); + if (isec) + isec = isec->canonical(); } uint64_t DylibSymbol::getVA() const { |