diff lld/MachO/Symbols.cpp @ 236:c4bab56944e8 llvm-original

LLVM 16
author kono
date Wed, 09 Nov 2022 17:45:10 +0900
parents 5f17cb93ff66
children 1f2b6ac9f198
line wrap: on
line diff
--- a/lld/MachO/Symbols.cpp	Wed Jul 21 10:27:27 2021 +0900
+++ b/lld/MachO/Symbols.cpp	Wed Nov 09 17:45:10 2022 +0900
@@ -9,48 +9,80 @@
 #include "Symbols.h"
 #include "InputFiles.h"
 #include "SyntheticSections.h"
+#include "llvm/Demangle/Demangle.h"
 
 using namespace llvm;
 using namespace lld;
 using namespace lld::macho;
 
-// Returns a symbol for an error message.
-static std::string demangle(StringRef symName) {
-  if (config->demangle)
-    return demangleItanium(symName);
-  return std::string(symName);
+static_assert(sizeof(void *) != 8 || sizeof(Symbol) == 56,
+              "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) == 88,
+              "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 name for an error message.
+static std::string maybeDemangleSymbol(StringRef symName) {
+  if (config->demangle) {
+    symName.consume_front("_");
+    return demangle(symName.str());
+  }
+  return symName.str();
 }
 
-std::string lld::toString(const Symbol &sym) { return demangle(sym.getName()); }
+std::string lld::toString(const Symbol &sym) {
+  return maybeDemangleSymbol(sym.getName());
+}
 
 std::string lld::toMachOString(const object::Archive::Symbol &b) {
-  return demangle(b.getName());
+  return maybeDemangleSymbol(b.getName());
 }
 
 uint64_t Symbol::getStubVA() const { return in.stubs->getVA(stubsIndex); }
+uint64_t Symbol::getLazyPtrVA() const {
+  return in.lazyPointers->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;
+Defined::Defined(StringRefZ name, InputFile *file, InputSection *isec,
+                 uint64_t value, uint64_t size, bool isWeakDef, bool isExternal,
+                 bool isPrivateExtern, bool includeInSymtab, bool isThumb,
+                 bool isReferencedDynamically, bool noDeadStrip,
+                 bool canOverrideWeakDef, bool isWeakDefCanBeHidden,
+                 bool interposable)
+    : Symbol(DefinedKind, name, file), overridesWeakDef(canOverrideWeakDef),
+      privateExtern(isPrivateExtern), includeInSymtab(includeInSymtab),
+      wasIdenticalCodeFolded(false), thumb(isThumb),
+      referencedDynamically(isReferencedDynamically), noDeadStrip(noDeadStrip),
+      interposable(interposable), 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;
+    }
+  }
+}
 
-  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);
-  }
-
-  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 +91,7 @@
   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,11 +102,28 @@
     // expedient to return a contrived out-of-range address.
     return TargetInfo::outOfRangeVA;
   }
-  return isec->canonical()->getVA(value);
+  return isec->getVA(value);
+}
+
+ObjFile *Defined::getObjectFile() const {
+  return isec ? dyn_cast_or_null<ObjFile>(isec->getFile()) : nullptr;
+}
+
+void Defined::canonicalize() {
+  if (unwindEntry)
+    unwindEntry = unwindEntry->canonical();
+  if (isec)
+    isec = isec->canonical();
+}
+
+std::string Defined::getSourceLocation() {
+  if (!isec)
+    return {};
+  return isec->getSourceLocation(value);
 }
 
 uint64_t DylibSymbol::getVA() const {
   return isInStubs() ? getStubVA() : Symbol::getVA();
 }
 
-void LazySymbol::fetchArchiveMember() { getFile()->fetch(sym); }
+void LazyArchive::fetchArchiveMember() { getFile()->fetch(sym); }