[lld] 2c25f39 - [lld/mac] Implement -final_output

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


Author: Nico Weber
Date: 2021-07-05T20:06:26-04:00
New Revision: 2c25f39fcce4f1789c18f67dbf5f10e9ef8c51e6

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

LOG: [lld/mac] Implement -final_output

This is one of two flags clang passes to the linker when giving calling
clang with multiple -arch flags.

I think it'd make sense to also use finalOutput instead of outputFile
in CodeSignatureSection() and when replacing @executable_path, but
ld64 doesn't do that, so I'll at least put those in separate commits.

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

Added: 
    lld/test/MachO/final-output.s

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

Removed: 
    


################################################################################
diff  --git a/lld/MachO/Config.h b/lld/MachO/Config.h
index e0d4959ca1d6..297d5fa4a381 100644
--- a/lld/MachO/Config.h
+++ b/lld/MachO/Config.h
@@ -121,9 +121,17 @@ struct Configuration {
   uint32_t dylibCurrentVersion = 0;
   uint32_t timeTraceGranularity = 500;
   std::string progName;
+
+  // For `clang -arch arm64 -arch x86_64`, clang will:
+  // 1. invoke the linker twice, to write one temporary output per arch
+  // 2. invoke `lipo` to merge the two outputs into a single file
+  // `outputFile` is the name of the temporary file the linker writes to.
+  // `finalOutput `is the name of the file lipo writes to after the link.
+  llvm::StringRef outputFile;
+  llvm::StringRef finalOutput;
+
   llvm::StringRef installName;
   llvm::StringRef mapFile;
-  llvm::StringRef outputFile;
   llvm::StringRef ltoObjPath;
   llvm::StringRef thinLTOJobs;
   llvm::StringRef umbrella;

diff  --git a/lld/MachO/Driver.cpp b/lld/MachO/Driver.cpp
index 2c90d9098e8e..e03871bcce1f 100644
--- a/lld/MachO/Driver.cpp
+++ b/lld/MachO/Driver.cpp
@@ -1106,6 +1106,10 @@ bool macho::link(ArrayRef<const char *> argsArr, bool canExitEarly,
 
   config->mapFile = args.getLastArgValue(OPT_map);
   config->outputFile = args.getLastArgValue(OPT_o, "a.out");
+  if (const Arg *arg = args.getLastArg(OPT_final_output))
+    config->finalOutput = arg->getValue();
+  else
+    config->finalOutput = config->outputFile;
   config->astPaths = args.getAllArgValues(OPT_add_ast_path);
   config->headerPad = args::getHex(args, OPT_headerpad, /*Default=*/32);
   config->headerPadMaxInstallNames =
@@ -1169,7 +1173,7 @@ bool macho::link(ArrayRef<const char *> argsArr, bool canExitEarly,
     else
       config->installName = arg->getValue();
   } else if (config->outputType == MH_DYLIB) {
-    config->installName = config->outputFile;
+    config->installName = config->finalOutput;
   }
 
   if (args.hasArg(OPT_mark_dead_strippable_dylib)) {

diff  --git a/lld/MachO/InputFiles.cpp b/lld/MachO/InputFiles.cpp
index 703050157328..57773bff7253 100644
--- a/lld/MachO/InputFiles.cpp
+++ b/lld/MachO/InputFiles.cpp
@@ -867,6 +867,7 @@ static DylibFile *findDylib(StringRef path, DylibFile *umbrella,
       path.consume_front("@executable_path/")) {
     // ld64 allows overriding this with the undocumented flag -executable_path.
     // lld doesn't currently implement that flag.
+    // FIXME: Consider using finalOutput instead of outputFile.
     path::append(newPath, path::parent_path(config->outputFile), path);
     path = newPath;
   } else if (path.consume_front("@loader_path/")) {

diff  --git a/lld/MachO/Options.td b/lld/MachO/Options.td
index 91bed1fc17bd..76937b8db95d 100644
--- a/lld/MachO/Options.td
+++ b/lld/MachO/Options.td
@@ -873,8 +873,7 @@ def w : Flag<["-"], "w">,
     Group<grp_rare>;
 def final_output : Separate<["-"], "final_output">,
     MetaVarName<"<name>">,
-    HelpText<"Specify the dylib install name if -install_name is not used--used by compiler driver for multiple -arch arguments">,
-    Flags<[HelpHidden]>,
+    HelpText<"Specify dylib install name if -install_name is not used; used by compiler driver for multiple -arch arguments">,
     Group<grp_rare>;
 def arch_multiple : Flag<["-"], "arch_multiple">,
     HelpText<"Augment error and warning messages with the architecture name">,

diff  --git a/lld/MachO/SyntheticSections.cpp b/lld/MachO/SyntheticSections.cpp
index 0a8153f42246..a95dddff28a3 100644
--- a/lld/MachO/SyntheticSections.cpp
+++ b/lld/MachO/SyntheticSections.cpp
@@ -1044,6 +1044,7 @@ static_assert((CodeSignatureSection::fixedHeadersSize % 8) == 0, "");
 CodeSignatureSection::CodeSignatureSection()
     : LinkEditSection(segment_names::linkEdit, section_names::codeSignature) {
   align = 16; // required by libstuff
+  // FIXME: Consider using finalOutput instead of outputFile.
   fileName = config->outputFile;
   size_t slashIndex = fileName.rfind("/");
   if (slashIndex != std::string::npos)

diff  --git a/lld/test/MachO/final-output.s b/lld/test/MachO/final-output.s
new file mode 100644
index 000000000000..ecaa7181ddea
--- /dev/null
+++ b/lld/test/MachO/final-output.s
@@ -0,0 +1,18 @@
+# REQUIRES: x86
+
+# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-macos -o %t.o %s
+
+## -final_output sets the default for -install_name, but an explicit
+## -install_name wins
+# RUN: %lld -dylib -o %t.dylib -final_output /lib/foo.dylib %t.o
+# RUN: llvm-otool -D %t.dylib | FileCheck -DID=/lib/foo.dylib %s
+
+# RUN: %lld -dylib -o %t.dylib -install_name /foo/bar.dylib \
+# RUN:     -final_output /lib/foo.dylib %t.o
+# RUN: llvm-otool -D %t.dylib | FileCheck -DID=/foo/bar.dylib %s
+
+# CHECK: [[ID]]
+
+.globl __Z3foo
+__Z3foo:
+  ret


        


More information about the llvm-commits mailing list