break;
}
case X86_64_RELOC_BRANCH: {
- // TODO: factor this logic out so it can be reused for different
- // 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: {
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;
}
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_) {}
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:
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;
}
};
OutputSegment *linkEditSegment =
getOrCreateOutputSegment(segment_names::linkEdit);
+ prepareBranchTarget(config->entry);
scanRelocations();
if (in.stubHelper->isNeeded())
in.stubHelper->setup();
# 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
# 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