aboutsummaryrefslogtreecommitdiff
path: root/contrib/llvm-project/lld/MachO/Symbols.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm-project/lld/MachO/Symbols.cpp')
-rw-r--r--contrib/llvm-project/lld/MachO/Symbols.cpp68
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 {