[lld] c7c9776 - [lld-macho] Allow the entry symbol to be dynamically bound
Jez Ng via llvm-commits
llvm-commits at lists.llvm.org
Fri Sep 25 11:28:52 PDT 2020
Author: Jez Ng
Date: 2020-09-25T11:28:33-07:00
New Revision: c7c9776f77712eb4311708d884c0c70ccaa7125b
URL: https://github.com/llvm/llvm-project/commit/c7c9776f77712eb4311708d884c0c70ccaa7125b
DIFF: https://github.com/llvm/llvm-project/commit/c7c9776f77712eb4311708d884c0c70ccaa7125b.diff
LOG: [lld-macho] Allow the entry symbol to be dynamically bound
Apparently this is used in real programs. I've handled this by reusing
the logic we already have for branch (function call) relocations.
Reviewed By: #lld-macho, smeenai
Differential Revision: https://reviews.llvm.org/D87852
Added:
Modified:
lld/MachO/Arch/X86_64.cpp
lld/MachO/Driver.cpp
lld/MachO/SyntheticSections.cpp
lld/MachO/SyntheticSections.h
lld/MachO/Writer.cpp
lld/test/MachO/entry-symbol.s
Removed:
################################################################################
diff --git a/lld/MachO/Arch/X86_64.cpp b/lld/MachO/Arch/X86_64.cpp
index 8e07ee4ecd62..19e62a919caf 100644
--- a/lld/MachO/Arch/X86_64.cpp
+++ b/lld/MachO/Arch/X86_64.cpp
@@ -238,28 +238,7 @@ void X86_64::prepareSymbolRelocation(lld::macho::Symbol *sym,
break;
}
case X86_64_RELOC_BRANCH: {
- // TODO: factor this logic out so it can be reused for
diff erent
- // architectures
- if (auto *dysym = dyn_cast<DylibSymbol>(sym)) {
- if (in.stubs->addEntry(dysym)) {
- if (sym->isWeakDef()) {
- in.binding->addEntry(dysym, in.lazyPointers,
- sym->stubsIndex * WordSize);
- in.weakBinding->addEntry(sym, in.lazyPointers,
- sym->stubsIndex * WordSize);
- } else {
- in.lazyBinding->addEntry(dysym);
- }
- }
- } else if (auto *defined = dyn_cast<Defined>(sym)) {
- if (defined->isWeakDef() && defined->isExternal()) {
- if (in.stubs->addEntry(sym)) {
- in.rebase->addEntry(in.lazyPointers, sym->stubsIndex * WordSize);
- in.weakBinding->addEntry(sym, in.lazyPointers,
- sym->stubsIndex * WordSize);
- }
- }
- }
+ prepareBranchTarget(sym);
break;
}
case X86_64_RELOC_UNSIGNED: {
diff --git a/lld/MachO/Driver.cpp b/lld/MachO/Driver.cpp
index 49919662fe4c..7a8215bd0398 100644
--- a/lld/MachO/Driver.cpp
+++ b/lld/MachO/Driver.cpp
@@ -697,7 +697,7 @@ bool macho::link(llvm::ArrayRef<const char *> argsArr, bool canExitEarly,
if (!orderFile.empty())
parseOrderFile(orderFile);
- if (config->outputType == MH_EXECUTE && !isa<Defined>(config->entry)) {
+ if (config->outputType == MH_EXECUTE && isa<Undefined>(config->entry)) {
error("undefined symbol: " + config->entry->getName());
return false;
}
diff --git a/lld/MachO/SyntheticSections.cpp b/lld/MachO/SyntheticSections.cpp
index a243a057b3ee..e40b832195b7 100644
--- a/lld/MachO/SyntheticSections.cpp
+++ b/lld/MachO/SyntheticSections.cpp
@@ -529,6 +529,29 @@ uint32_t LazyBindingSection::encode(const DylibSymbol &sym) {
return opstreamOffset;
}
+void macho::prepareBranchTarget(Symbol *sym) {
+ if (auto *dysym = dyn_cast<DylibSymbol>(sym)) {
+ if (in.stubs->addEntry(dysym)) {
+ if (sym->isWeakDef()) {
+ in.binding->addEntry(dysym, in.lazyPointers,
+ sym->stubsIndex * WordSize);
+ in.weakBinding->addEntry(sym, in.lazyPointers,
+ sym->stubsIndex * WordSize);
+ } else {
+ in.lazyBinding->addEntry(dysym);
+ }
+ }
+ } else if (auto *defined = dyn_cast<Defined>(sym)) {
+ if (defined->isWeakDef() && defined->isExternal()) {
+ if (in.stubs->addEntry(sym)) {
+ in.rebase->addEntry(in.lazyPointers, sym->stubsIndex * WordSize);
+ in.weakBinding->addEntry(sym, in.lazyPointers,
+ sym->stubsIndex * WordSize);
+ }
+ }
+ }
+}
+
ExportSection::ExportSection()
: LinkEditSection(segment_names::linkEdit, section_names::export_) {}
diff --git a/lld/MachO/SyntheticSections.h b/lld/MachO/SyntheticSections.h
index 3bd4e118aff8..1736b6a900ca 100644
--- a/lld/MachO/SyntheticSections.h
+++ b/lld/MachO/SyntheticSections.h
@@ -364,6 +364,10 @@ class LazyBindingSection : public LinkEditSection {
llvm::raw_svector_ostream os{contents};
};
+// Adds stubs and bindings where necessary (e.g. if the symbol is a
+// DylibSymbol.)
+void prepareBranchTarget(Symbol *);
+
// Stores a trie that describes the set of exported symbols.
class ExportSection : public LinkEditSection {
public:
diff --git a/lld/MachO/Writer.cpp b/lld/MachO/Writer.cpp
index 4572c521ab29..c47b878b6c59 100644
--- a/lld/MachO/Writer.cpp
+++ b/lld/MachO/Writer.cpp
@@ -194,7 +194,13 @@ class LCMain : public LoadCommand {
auto *c = reinterpret_cast<entry_point_command *>(buf);
c->cmd = LC_MAIN;
c->cmdsize = getSize();
- c->entryoff = config->entry->getFileOffset();
+
+ if (config->entry->isInStubs())
+ c->entryoff =
+ in.stubs->fileOff + config->entry->stubsIndex * target->stubSize;
+ else
+ c->entryoff = config->entry->getFileOffset();
+
c->stacksize = 0;
}
};
@@ -617,6 +623,7 @@ void Writer::run() {
OutputSegment *linkEditSegment =
getOrCreateOutputSegment(segment_names::linkEdit);
+ prepareBranchTarget(config->entry);
scanRelocations();
if (in.stubHelper->isNeeded())
in.stubHelper->setup();
diff --git a/lld/test/MachO/entry-symbol.s b/lld/test/MachO/entry-symbol.s
index 159c7c5af042..d24d4e691c47 100644
--- a/lld/test/MachO/entry-symbol.s
+++ b/lld/test/MachO/entry-symbol.s
@@ -1,7 +1,11 @@
# REQUIRES: x86
-# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-darwin %s -o %t.o
-# RUN: lld -flavor darwinnew -o %t %t.o -e _not_main
-# RUN: llvm-objdump --macho --all-headers --syms %t | FileCheck %s
+# RUN: split-file %s %t
+# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-darwin %t/not-main.s -o %t/not-main.o
+# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-darwin %t/libfoo.s -o %t/libfoo.o
+# RUN: lld -flavor darwinnew -syslibroot %S/Inputs/MacOSX.sdk -lSystem -dylib %t/libfoo.o -o %t/libfoo.dylib
+
+# RUN: lld -flavor darwinnew -o %t/not-main %t/not-main.o -e _not_main
+# RUN: llvm-objdump --macho --all-headers --syms %t/not-main | FileCheck %s
# CHECK-LABEL: SYMBOL TABLE
# CHECK-NEXT: {{0*}}[[#%x, ENTRY_ADDR:]] {{.*}} __TEXT,__text _not_main
# CHECK: cmd LC_MAIN
@@ -15,14 +19,50 @@
# CHECK-NEXT: size
# CHECK-NEXT: offset [[#ENTRYOFF]]
+# RUN: lld -flavor darwinnew -syslibroot %S/Inputs/MacOSX.sdk -lSystem -o %t/dysym-main %t/not-main.o %t/libfoo.dylib -e _dysym_main
+# RUN: llvm-objdump --macho --all-headers --indirect-symbols --lazy-bind %t/dysym-main | FileCheck %s --check-prefix=DYSYM
+# DYSYM-LABEL: Indirect symbols for (__TEXT,__stubs) 1 entries
+# DYSYM-NEXT: address index name
+# DYSYM-NEXT: 0x[[#%x,DYSYM_ENTRY_ADDR:]] [[#]] _dysym_main
+# DYSYM-LABEL: cmd LC_MAIN
+# DYSYM-NEXT: cmdsize 24
+# DYSYM-NEXT: entryoff [[#%u, DYSYM_ENTRY_ADDR - 0x100000000]]
+# DYSYM-LABEL: Lazy bind table:
+# DYSYM-NEXT: segment section address dylib symbol
+# DYSYM-NEXT: __DATA __la_symbol_ptr {{.*}} libfoo _dysym_main
+
+# RUN: lld -flavor darwinnew -syslibroot %S/Inputs/MacOSX.sdk -lSystem -o %t/weak-dysym-main %t/not-main.o %t/libfoo.dylib -e _weak_dysym_main
+# RUN: llvm-objdump --macho --all-headers --indirect-symbols --bind --weak-bind %t/weak-dysym-main | FileCheck %s --check-prefix=WEAK-DYSYM
+# WEAK-DYSYM-LABEL: Indirect symbols for (__TEXT,__stubs) 1 entries
+# WEAK-DYSYM-NEXT: address index name
+# WEAK-DYSYM-NEXT: 0x[[#%x,DYSYM_ENTRY_ADDR:]] [[#]] _weak_dysym_main
+# WEAK-DYSYM: cmd LC_MAIN
+# WEAK-DYSYM-NEXT: cmdsize 24
+# WEAK-DYSYM-NEXT: entryoff [[#%u, DYSYM_ENTRY_ADDR - 0x100000000]]
+# WEAK-DYSYM-LABEL: Bind table:
+# WEAK-DYSYM-NEXT: segment section address type addend dylib symbol
+# WEAK-DYSYM: __DATA __la_symbol_ptr {{.*}} pointer 0 libfoo _weak_dysym_main
+# WEAK-DYSYM-LABEL: Weak bind table:
+# WEAK-DYSYM-NEXT: segment section address type addend symbol
+# WEAK-DYSYM-NEXT: __DATA __la_symbol_ptr {{.*}} pointer 0 _weak_dysym_main
-# RUN: not lld -flavor darwinnew -o /dev/null %t.o -e _missing 2>&1 | FileCheck %s --check-prefix=UNDEFINED
+# RUN: not lld -flavor darwinnew -o /dev/null %t/not-main.o -e _missing 2>&1 | FileCheck %s --check-prefix=UNDEFINED
# UNDEFINED: error: undefined symbol: _missing
-# RUN: not lld -flavor darwinnew -o /dev/null %t.o 2>&1 | FileCheck %s --check-prefix=DEFAULT-ENTRY
+# RUN: not lld -flavor darwinnew -o /dev/null %t/not-main.o 2>&1 | FileCheck %s --check-prefix=DEFAULT-ENTRY
# DEFAULT-ENTRY: error: undefined symbol: _main
+#--- libfoo.s
+.text
+.global _dysym_main, _weak_dysym_main
+.weak_definition _weak_dysym_main
+_dysym_main:
+ ret
+
+_weak_dysym_main:
+ ret
+
+#--- not-main.s
.text
.global _not_main
_not_main:
- movq $0, %rax
- retq
+ ret
More information about the llvm-commits
mailing list