[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