[lld] db64306 - [lld/mac] Implement -umbrella

Nico Weber via llvm-commits llvm-commits at lists.llvm.org
Mon Jul 5 17:06:41 PDT 2021


Author: Nico Weber
Date: 2021-07-05T20:06:25-04:00
New Revision: db64306d99138a3700a2ab9c7d3b47f302781cc3

URL: https://github.com/llvm/llvm-project/commit/db64306d99138a3700a2ab9c7d3b47f302781cc3
DIFF: https://github.com/llvm/llvm-project/commit/db64306d99138a3700a2ab9c7d3b47f302781cc3.diff

LOG: [lld/mac] Implement -umbrella

I think this is an old way for doing what is done with
-reexport_library these days, but it's e.g. still used in libunwind's
build (the opensource.apple.com one, not the llvm one).

Differential Revision: https://reviews.llvm.org/D105448

Added: 
    lld/test/MachO/umbrella.s

Modified: 
    lld/MachO/Config.h
    lld/MachO/Driver.cpp
    lld/MachO/Options.td
    lld/MachO/Writer.cpp

Removed: 
    


################################################################################
diff  --git a/lld/MachO/Config.h b/lld/MachO/Config.h
index ee4d49bd135a..e0d4959ca1d6 100644
--- a/lld/MachO/Config.h
+++ b/lld/MachO/Config.h
@@ -126,6 +126,7 @@ struct Configuration {
   llvm::StringRef outputFile;
   llvm::StringRef ltoObjPath;
   llvm::StringRef thinLTOJobs;
+  llvm::StringRef umbrella;
   uint32_t ltoo = 2;
   bool deadStripDylibs = false;
   bool demangle = false;

diff  --git a/lld/MachO/Driver.cpp b/lld/MachO/Driver.cpp
index 5a17941e5dff..2c90d9098e8e 100644
--- a/lld/MachO/Driver.cpp
+++ b/lld/MachO/Driver.cpp
@@ -1121,6 +1121,11 @@ bool macho::link(ArrayRef<const char *> argsArr, bool canExitEarly,
     addFile(arg->getValue(), /*forceLoadArchive=*/false, /*isExplicit=*/false,
             /*isBundleLoader=*/true);
   }
+  if (const Arg *arg = args.getLastArg(OPT_umbrella)) {
+    if (config->outputType != MH_DYLIB)
+      warn("-umbrella used, but not creating dylib");
+    config->umbrella = arg->getValue();
+  }
   config->ltoObjPath = args.getLastArgValue(OPT_object_path_lto);
   config->ltoNewPassManager =
       args.hasFlag(OPT_no_lto_legacy_pass_manager, OPT_lto_legacy_pass_manager,

diff  --git a/lld/MachO/Options.td b/lld/MachO/Options.td
index 515053a64cf1..91bed1fc17bd 100644
--- a/lld/MachO/Options.td
+++ b/lld/MachO/Options.td
@@ -780,9 +780,8 @@ def client_name : Separate<["-"], "client_name">,
     Flags<[HelpHidden]>,
     Group<grp_rare>;
 def umbrella : Separate<["-"], "umbrella">,
-    MetaVarName<"<<name>>">,
-    HelpText<"Re-export this dylib through the umbrella framework <name>a">,
-    Flags<[HelpHidden]>,
+    MetaVarName<"<name>">,
+    HelpText<"Re-export this dylib through the umbrella framework <name>">,
     Group<grp_rare>;
 def headerpad : Separate<["-"], "headerpad">,
     MetaVarName<"<size>">,

diff  --git a/lld/MachO/Writer.cpp b/lld/MachO/Writer.cpp
index 874708e376a7..3bd0daf7902f 100644
--- a/lld/MachO/Writer.cpp
+++ b/lld/MachO/Writer.cpp
@@ -128,6 +128,31 @@ class LCDyldInfo final : public LoadCommand {
   ExportSection *exportSection;
 };
 
+class LCSubFramework final : public LoadCommand {
+public:
+  LCSubFramework(StringRef umbrella) : umbrella(umbrella) {}
+
+  uint32_t getSize() const override {
+    return alignTo(sizeof(sub_framework_command) + umbrella.size() + 1,
+                   target->wordSize);
+  }
+
+  void writeTo(uint8_t *buf) const override {
+    auto *c = reinterpret_cast<sub_framework_command *>(buf);
+    buf += sizeof(sub_framework_command);
+
+    c->cmd = LC_SUB_FRAMEWORK;
+    c->cmdsize = getSize();
+    c->umbrella = sizeof(sub_framework_command);
+
+    memcpy(buf, umbrella.data(), umbrella.size());
+    buf[umbrella.size()] = '\0';
+  }
+
+private:
+  const StringRef umbrella;
+};
+
 class LCFunctionStarts final : public LoadCommand {
 public:
   explicit LCFunctionStarts(FunctionStartsSection *functionStartsSection)
@@ -665,6 +690,8 @@ template <class LP> void Writer::createLoadCommands() {
   in.header->addLoadCommand(make<LCSymtab>(symtabSection, stringTableSection));
   in.header->addLoadCommand(
       make<LCDysymtab>(symtabSection, indirectSymtabSection));
+  if (!config->umbrella.empty())
+    in.header->addLoadCommand(make<LCSubFramework>(config->umbrella));
   if (functionStartsSection)
     in.header->addLoadCommand(make<LCFunctionStarts>(functionStartsSection));
   if (dataInCodeSection)

diff  --git a/lld/test/MachO/umbrella.s b/lld/test/MachO/umbrella.s
new file mode 100644
index 000000000000..e2f49140a058
--- /dev/null
+++ b/lld/test/MachO/umbrella.s
@@ -0,0 +1,18 @@
+# REQUIRES: x86
+
+# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-macos -o %t.o %s
+# RUN: %lld -dylib -o %t.dylib -umbrella umbrella.dylib %t.o
+# RUN: llvm-otool -lv %t.dylib | FileCheck %s
+
+# RUN: %no_fatal_warnings_lld -bundle -o %t.so -umbrella umbrella.dylib %t.o \
+# RUN:   2>&1 | FileCheck --check-prefix=WARN %s
+# WARN: warning: -umbrella used, but not creating dylib
+# RUN: llvm-otool -lv %t.so | FileCheck %s
+
+# CHECK:           cmd LC_SUB_FRAMEWORK
+# CHECK-NEXT:  cmdsize 32
+# CHECK-NEXT: umbrella umbrella.dylib (offset 12)
+
+.globl __Z3foo
+__Z3foo:
+  ret


        


More information about the llvm-commits mailing list