[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