[lld] 3da2130 - [lld-macho] Emit the right header flags for weak bindings/symbols
Jez Ng via llvm-commits
llvm-commits at lists.llvm.org
Thu Aug 27 17:44:41 PDT 2020
Author: Jez Ng
Date: 2020-08-27T17:44:16-07:00
New Revision: 3da2130e45a4bd61df09bcdb15ec07e9fc71747c
URL: https://github.com/llvm/llvm-project/commit/3da2130e45a4bd61df09bcdb15ec07e9fc71747c
DIFF: https://github.com/llvm/llvm-project/commit/3da2130e45a4bd61df09bcdb15ec07e9fc71747c.diff
LOG: [lld-macho] Emit the right header flags for weak bindings/symbols
Reviewed By: #lld-macho, smeenai
Differential Revision: https://reviews.llvm.org/D86574
Added:
lld/test/MachO/weak-header-flags.s
Modified:
lld/MachO/SyntheticSections.cpp
lld/MachO/SyntheticSections.h
lld/MachO/Writer.cpp
Removed:
################################################################################
diff --git a/lld/MachO/SyntheticSections.cpp b/lld/MachO/SyntheticSections.cpp
index 35a76e002dc2..07e8dfcddea8 100644
--- a/lld/MachO/SyntheticSections.cpp
+++ b/lld/MachO/SyntheticSections.cpp
@@ -63,6 +63,14 @@ void MachHeaderSection::writeTo(uint8_t *buf) const {
if (config->outputType == MachO::MH_DYLIB && !config->hasReexports)
hdr->flags |= MachO::MH_NO_REEXPORTED_DYLIBS;
+ // TODO: ld64 also sets this flag if we have defined a non-weak symbol that
+ // overrides a weak symbol from an imported dylib.
+ if (in.exports->hasWeakSymbol)
+ hdr->flags |= MachO::MH_WEAK_DEFINES;
+
+ if (in.exports->hasWeakSymbol || in.weakBinding->isNeeded())
+ hdr->flags |= MachO::MH_BINDS_TO_WEAK;
+
for (OutputSegment *seg : outputSegments) {
for (OutputSection *osec : seg->getSections()) {
if (isThreadLocalVariables(osec->flags)) {
@@ -415,9 +423,12 @@ ExportSection::ExportSection()
void ExportSection::finalizeContents() {
// TODO: We should check symbol visibility.
- for (const Symbol *sym : symtab->getSymbols())
- if (auto *defined = dyn_cast<Defined>(sym))
+ for (const Symbol *sym : symtab->getSymbols()) {
+ if (const auto *defined = dyn_cast<Defined>(sym)) {
trieBuilder.addSymbol(*defined);
+ hasWeakSymbol = hasWeakSymbol || sym->isWeakDef();
+ }
+ }
size = trieBuilder.build();
}
diff --git a/lld/MachO/SyntheticSections.h b/lld/MachO/SyntheticSections.h
index c1e938809c8a..155d39ef9053 100644
--- a/lld/MachO/SyntheticSections.h
+++ b/lld/MachO/SyntheticSections.h
@@ -333,6 +333,8 @@ class ExportSection : public LinkEditSection {
bool isHidden() const override { return true; }
void writeTo(uint8_t *buf) const override;
+ bool hasWeakSymbol = false;
+
private:
TrieBuilder trieBuilder;
size_t size = 0;
@@ -386,6 +388,7 @@ struct InStruct {
BindingSection *binding = nullptr;
WeakBindingSection *weakBinding = nullptr;
LazyBindingSection *lazyBinding = nullptr;
+ ExportSection *exports = nullptr;
GotSection *got = nullptr;
TlvPointerSection *tlvPointers = nullptr;
LazyPointerSection *lazyPointers = nullptr;
diff --git a/lld/MachO/Writer.cpp b/lld/MachO/Writer.cpp
index 437852cf4fbf..6abee4338486 100644
--- a/lld/MachO/Writer.cpp
+++ b/lld/MachO/Writer.cpp
@@ -55,7 +55,6 @@ class Writer {
uint64_t addr = 0;
uint64_t fileOff = 0;
MachHeaderSection *header = nullptr;
- ExportSection *exportSection = nullptr;
StringTableSection *stringTableSection = nullptr;
SymtabSection *symtabSection = nullptr;
};
@@ -326,8 +325,8 @@ void Writer::scanRelocations() {
}
void Writer::createLoadCommands() {
- in.header->addLoadCommand(make<LCDyldInfo>(in.binding, in.weakBinding,
- in.lazyBinding, exportSection));
+ in.header->addLoadCommand(
+ make<LCDyldInfo>(in.binding, in.weakBinding, in.lazyBinding, in.exports));
in.header->addLoadCommand(make<LCSymtab>(symtabSection, stringTableSection));
in.header->addLoadCommand(make<LCDysymtab>());
for (StringRef path : config->runtimePaths)
@@ -474,7 +473,6 @@ void Writer::createOutputSections() {
// First, create hidden sections
stringTableSection = make<StringTableSection>();
symtabSection = make<SymtabSection>(*stringTableSection);
- exportSection = make<ExportSection>();
switch (config->outputType) {
case MH_EXECUTE:
@@ -584,7 +582,7 @@ void Writer::run() {
in.binding->finalizeContents();
in.weakBinding->finalizeContents();
in.lazyBinding->finalizeContents();
- exportSection->finalizeContents();
+ in.exports->finalizeContents();
symtabSection->finalizeContents();
// Now that __LINKEDIT is filled out, do a proper calculation of its
@@ -608,6 +606,7 @@ void macho::createSyntheticSections() {
in.binding = make<BindingSection>();
in.weakBinding = make<WeakBindingSection>();
in.lazyBinding = make<LazyBindingSection>();
+ in.exports = make<ExportSection>();
in.got = make<GotSection>();
in.tlvPointers = make<TlvPointerSection>();
in.lazyPointers = make<LazyPointerSection>();
diff --git a/lld/test/MachO/weak-header-flags.s b/lld/test/MachO/weak-header-flags.s
new file mode 100644
index 000000000000..3d3c5660a65a
--- /dev/null
+++ b/lld/test/MachO/weak-header-flags.s
@@ -0,0 +1,35 @@
+# REQUIRES: x86
+# RUN: split-file %s %t
+
+# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-darwin %t/libweak-defines.s -o %t/libweak-defines.o
+# RUN: lld -flavor darwinnew -syslibroot %S/Inputs/MacOSX.sdk -dylib %t/libweak-defines.o -o %t/libweak-defines.dylib
+# RUN: llvm-readobj --file-headers %t/libweak-defines.dylib | FileCheck %s --check-prefix=WEAK-DEFINES-AND-BINDS
+
+# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-darwin %t/binds-to-weak.s -o %t/binds-to-weak.o
+# RUN: lld -flavor darwinnew -L%S/Inputs/MacOSX.sdk/usr/lib -lSystem -L%t -lweak-defines -o %t/binds-to-weak %t/binds-to-weak.o
+# RUN: llvm-readobj --file-headers %t/binds-to-weak | FileCheck %s --check-prefix=WEAK-BINDS-ONLY
+
+# WEAK-DEFINES-AND-BINDS: MH_BINDS_TO_WEAK
+# WEAK-DEFINES-AND-BINDS: MH_WEAK_DEFINES
+
+# WEAK-BINDS-ONLY-NOT: MH_WEAK_DEFINES
+# WEAK-BINDS-ONLY: MH_BINDS_TO_WEAK
+# WEAK-BINDS-ONLY-NOT: MH_WEAK_DEFINES
+
+#--- libweak-defines.s
+
+.globl _foo
+.weak_definition _foo
+_foo:
+ ret
+
+#--- binds-to-weak.s
+
+.globl _main
+_main:
+ callq _foo
+ ret
+
+## Don't generate MH_WEAK_DEFINES for weak locals
+.weak_definition _weak_local
+_weak_local:
More information about the llvm-commits
mailing list