[lld] 0658fc6 - [lld/mac] Implement the missing bits of -undefined

Nico Weber via llvm-commits llvm-commits at lists.llvm.org
Mon Mar 1 12:31:06 PST 2021


Author: Nico Weber
Date: 2021-03-01T15:30:53-05:00
New Revision: 0658fc654c758d0bfab7d119ecf94caf5e5276d5

URL: https://github.com/llvm/llvm-project/commit/0658fc654c758d0bfab7d119ecf94caf5e5276d5
DIFF: https://github.com/llvm/llvm-project/commit/0658fc654c758d0bfab7d119ecf94caf5e5276d5.diff

LOG: [lld/mac] Implement the missing bits of -undefined

This adds support for `-undefined dynamic_lookup`, and for
`-undefined warning` and `-undefined suppress` with `-flat_namespace`.

We just replace undefined symbols with a DynamicLookup when we hit them.

With this, `check-llvm` passes when using ld64.lld.darwinnew as host linker.

Differential Revision: https://reviews.llvm.org/D97642

Added: 
    

Modified: 
    lld/MachO/SymbolTable.cpp
    lld/MachO/UnwindInfoSection.cpp
    lld/MachO/Writer.cpp
    lld/test/MachO/treat-undef-sym.s

Removed: 
    


################################################################################
diff  --git a/lld/MachO/SymbolTable.cpp b/lld/MachO/SymbolTable.cpp
index 1d1e7a02bb5c..2bfc5c37d20e 100644
--- a/lld/MachO/SymbolTable.cpp
+++ b/lld/MachO/SymbolTable.cpp
@@ -174,24 +174,23 @@ Symbol *SymbolTable::addDSOHandle(const MachHeaderSection *header) {
 }
 
 void lld::macho::treatUndefinedSymbol(const Undefined &sym) {
-  std::string message = "undefined symbol: " + toString(sym);
-  std::string fileName = toString(sym.getFile());
-
-  if (!fileName.empty())
-    message += "\n>>> referenced by " + fileName;
+  auto message = [](const Undefined &sym) {
+    std::string message = "undefined symbol: " + toString(sym);
+    std::string fileName = toString(sym.getFile());
+    if (!fileName.empty())
+      message += "\n>>> referenced by " + fileName;
+    return message;
+  };
   switch (config->undefinedSymbolTreatment) {
-  case UndefinedSymbolTreatment::suppress:
-    error("-undefined suppress unimplemented");
-    break;
   case UndefinedSymbolTreatment::error:
-    error(message);
+    error(message(sym));
     break;
   case UndefinedSymbolTreatment::warning:
-    warn(message);
-    error("-undefined warning unimplemented");
-    break;
+    warn(message(sym));
+    LLVM_FALLTHROUGH;
   case UndefinedSymbolTreatment::dynamic_lookup:
-    error("dynamic_lookup unimplemented for " + message);
+  case UndefinedSymbolTreatment::suppress:
+    symtab->addDynamicLookup(sym.getName());
     break;
   case UndefinedSymbolTreatment::unknown:
     llvm_unreachable("unknown -undefined TREATMENT");

diff  --git a/lld/MachO/UnwindInfoSection.cpp b/lld/MachO/UnwindInfoSection.cpp
index 10304327ed2f..ec2c12ed5c9d 100644
--- a/lld/MachO/UnwindInfoSection.cpp
+++ b/lld/MachO/UnwindInfoSection.cpp
@@ -121,7 +121,9 @@ void macho::prepareCompactUnwind(InputSection *isec) {
     if (auto *s = r.referent.dyn_cast<lld::macho::Symbol *>()) {
       if (auto *undefined = dyn_cast<Undefined>(s)) {
         treatUndefinedSymbol(*undefined);
-        continue;
+        // treatUndefinedSymbol() can replace s with a DylibSymbol; re-check.
+        if (isa<Undefined>(s))
+          continue;
       }
       if (auto *defined = dyn_cast<Defined>(s)) {
         // Check if we have created a synthetic symbol at the same address.

diff  --git a/lld/MachO/Writer.cpp b/lld/MachO/Writer.cpp
index 932bfebe0677..0a570a31758a 100644
--- a/lld/MachO/Writer.cpp
+++ b/lld/MachO/Writer.cpp
@@ -462,7 +462,9 @@ void Writer::scanRelocations() {
       if (auto *sym = r.referent.dyn_cast<lld::macho::Symbol *>()) {
         if (auto *undefined = dyn_cast<Undefined>(sym))
           treatUndefinedSymbol(*undefined);
-        else if (target->validateSymbolRelocation(sym, isec, r))
+        // treatUndefinedSymbol() can replace sym with a DylibSymbol; re-check.
+        if (!isa<Undefined>(sym) &&
+            target->validateSymbolRelocation(sym, isec, r))
           prepareSymbolRelocation(sym, isec, r);
       } else {
         assert(r.referent.is<InputSection *>());

diff  --git a/lld/test/MachO/treat-undef-sym.s b/lld/test/MachO/treat-undef-sym.s
index 854f477e5105..23fe47ac4214 100644
--- a/lld/test/MachO/treat-undef-sym.s
+++ b/lld/test/MachO/treat-undef-sym.s
@@ -10,13 +10,24 @@
 # RUN:     FileCheck %s -check-prefix=INVAL-WARNING
 # RUN: not %lld -undefined suppress -o /dev/null %t.o 2>&1 | \
 # RUN:     FileCheck %s -check-prefix=INVAL-SUPPRESS
-
-# FIXME: Enable these -undefined checks once -flat_namespace is implemented.
-# RN: %no_fatal_warnings_lld -flat_namespace -undefined warning \
-# RN:     -o /dev/null %t.o 2>&1 | \
-# RN:     FileCheck %s -check-prefix=WARNING
-# RN: %lld -flat_namespace -undefined suppress -o /dev/null %t.o 2>&1 | \
-# RN:     FileCheck %s -check-prefix=SUPPRESS --allow-empty
+# RUN: %lld -undefined dynamic_lookup -lSystem -o %t.out %t.o 2>&1 | \
+# RUN:     FileCheck %s -check-prefix=SUPPRESS --allow-empty
+# RUN: llvm-objdump --macho --lazy-bind %t.out \
+# RUN:     | FileCheck --check-prefix=BIND %s
+
+# RUN: %no_fatal_warnings_lld -lSystem -flat_namespace -undefined warning \
+# RUN:     -o %t.out %t.o 2>&1 | \
+# RUN:     FileCheck %s -check-prefix=WARNING
+# RUN: llvm-objdump --macho --lazy-bind %t.out \
+# RUN:     | FileCheck --check-prefix=BIND %s
+# RUN: %lld -flat_namespace -lSystem -undefined suppress -o %t.out %t.o 2>&1 | \
+# RUN:     FileCheck %s -check-prefix=SUPPRESS --allow-empty
+# RUN: llvm-objdump --macho --lazy-bind %t.out \
+# RUN:     | FileCheck --check-prefix=BIND %s
+# RUN: %lld -flat_namespace -lSystem -undefined dynamic_lookup -o %t.out %t.o 2>&1 | \
+# RUN:     FileCheck %s -check-prefix=SUPPRESS --allow-empty
+# RUN: llvm-objdump --macho --lazy-bind %t.out \
+# RUN:     | FileCheck --check-prefix=BIND %s
 
 # ERROR: error: undefined symbol: _bar
 # ERROR-NEXT: >>> referenced by
@@ -27,7 +38,6 @@
 # INVAL-SUPPRESS: error: '-undefined suppress' only valid with '-flat_namespace'
 # INVAL-SUPPRESS-NEXT: error: undefined symbol: _bar
 
-
 # WARNING: warning: undefined symbol: _bar
 # WARNING-NEXT: >>> referenced by
 
@@ -37,6 +47,9 @@
 # UNKNOWN-NEXT: error: undefined symbol: _bar
 # UNKNOWN-NEXT: >>> referenced by
 
+# BIND: Lazy bind table:
+# BIND: __DATA   __la_symbol_ptr    0x{{[0-9a-f]*}} flat-namespace   _bar
+
 .globl _main
 _main:
   callq _bar


        


More information about the llvm-commits mailing list