[lld] f21801d - [lld/mac] Implement -application_extension

Nico Weber via llvm-commits llvm-commits at lists.llvm.org
Mon Jul 12 10:44:28 PDT 2021


Author: Nico Weber
Date: 2021-07-12T13:42:16-04:00
New Revision: f21801dab249df506af4c62c70af34a11fa3d3e1

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

LOG: [lld/mac] Implement -application_extension

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

Added: 
    lld/test/MachO/application-extension.s

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

Removed: 
    


################################################################################
diff  --git a/lld/MachO/Config.h b/lld/MachO/Config.h
index 654fd794b27a..51ead8bfb6cd 100644
--- a/lld/MachO/Config.h
+++ b/lld/MachO/Config.h
@@ -95,6 +95,7 @@ struct Configuration {
   Symbol *entry = nullptr;
   bool hasReexports = false;
   bool allLoad = false;
+  bool applicationExtension = false;
   bool archMultiple = false;
   bool exportDynamic = false;
   bool forceLoadObjC = false;

diff  --git a/lld/MachO/Driver.cpp b/lld/MachO/Driver.cpp
index 98340088a120..e146991e5a01 100644
--- a/lld/MachO/Driver.cpp
+++ b/lld/MachO/Driver.cpp
@@ -1176,6 +1176,8 @@ bool macho::link(ArrayRef<const char *> argsArr, bool canExitEarly,
   config->runtimePaths = args::getStrings(args, OPT_rpath);
   config->allLoad = args.hasArg(OPT_all_load);
   config->archMultiple = args.hasArg(OPT_arch_multiple);
+  config->applicationExtension = args.hasFlag(
+      OPT_application_extension, OPT_no_application_extension, false);
   config->exportDynamic = args.hasArg(OPT_export_dynamic);
   config->forceLoadObjC = args.hasArg(OPT_ObjC);
   config->forceLoadSwift = args.hasArg(OPT_force_load_swift_libs);

diff  --git a/lld/MachO/InputFiles.cpp b/lld/MachO/InputFiles.cpp
index 89f768a61e66..8f5df2529002 100644
--- a/lld/MachO/InputFiles.cpp
+++ b/lld/MachO/InputFiles.cpp
@@ -954,6 +954,8 @@ DylibFile::DylibFile(MemoryBufferRef mb, DylibFile *umbrella,
   if (!checkCompatibility(this))
     return;
 
+  checkAppExtensionSafety(hdr->flags & MH_APP_EXTENSION_SAFE);
+
   for (auto *cmd : findCommands<rpath_command>(hdr, LC_RPATH)) {
     StringRef rpath{reinterpret_cast<const char *>(cmd) + cmd->path};
     rpaths.push_back(rpath);
@@ -1043,6 +1045,8 @@ DylibFile::DylibFile(const InterfaceFile &interface, DylibFile *umbrella,
     return;
   }
 
+  checkAppExtensionSafety(interface.isApplicationExtensionSafe());
+
   exportingFile = isImplicitlyLinked(installName) ? this : umbrella;
   auto addSymbol = [&](const Twine &name) -> void {
     symbols.push_back(symtab->addDylib(saver.save(name), exportingFile,
@@ -1171,6 +1175,11 @@ void DylibFile::handleLDInstallNameSymbol(StringRef name,
     this->installName = saver.save(installName);
 }
 
+void DylibFile::checkAppExtensionSafety(bool dylibIsAppExtensionSafe) const {
+  if (config->applicationExtension && !dylibIsAppExtensionSafe)
+    warn("using '-application_extension' with unsafe dylib: " + toString(this));
+}
+
 ArchiveFile::ArchiveFile(std::unique_ptr<object::Archive> &&f)
     : InputFile(ArchiveKind, f->getMemoryBufferRef()), file(std::move(f)) {
   for (const object::Archive::Symbol &sym : file->symbols())

diff  --git a/lld/MachO/InputFiles.h b/lld/MachO/InputFiles.h
index df8e006a5ccd..3bf9e77cf95a 100644
--- a/lld/MachO/InputFiles.h
+++ b/lld/MachO/InputFiles.h
@@ -177,6 +177,7 @@ class DylibFile final : public InputFile {
   bool handleLDSymbol(StringRef originalName);
   void handleLDPreviousSymbol(StringRef name, StringRef originalName);
   void handleLDInstallNameSymbol(StringRef name, StringRef originalName);
+  void checkAppExtensionSafety(bool dylibIsAppExtensionSafe) const;
 };
 
 // .a file

diff  --git a/lld/MachO/Options.td b/lld/MachO/Options.td
index b351645cedd6..9b233f4b101f 100644
--- a/lld/MachO/Options.td
+++ b/lld/MachO/Options.td
@@ -689,12 +689,10 @@ def allow_heap_execute : Flag<["-"], "allow_heap_execute">,
     Flags<[HelpHidden]>,
     Group<grp_rare>;
 def application_extension : Flag<["-"], "application_extension">,
-    HelpText<"Designate the linker output as safe for use in an application extension">,
-    Flags<[HelpHidden]>,
+    HelpText<"Mark output as safe for use in an application extension, and validate that linked dylibs are safe">,
     Group<grp_rare>;
 def no_application_extension : Flag<["-"], "no_application_extension">,
-    HelpText<"Designate the linker output as unsafe for use in an application extension">,
-    Flags<[HelpHidden]>,
+    HelpText<"Disable application extension functionality (default)">,
     Group<grp_rare>;
 def fatal_warnings : Flag<["-"], "fatal_warnings">,
     HelpText<"Treat warnings as errors">,

diff  --git a/lld/MachO/SyntheticSections.cpp b/lld/MachO/SyntheticSections.cpp
index 12c62554c243..403da5608210 100644
--- a/lld/MachO/SyntheticSections.cpp
+++ b/lld/MachO/SyntheticSections.cpp
@@ -113,6 +113,9 @@ void MachHeaderSection::writeTo(uint8_t *buf) const {
   if (config->outputType == MH_EXECUTE && config->isPic)
     hdr->flags |= MH_PIE;
 
+  if (config->outputType == MH_DYLIB && config->applicationExtension)
+    hdr->flags |= MH_APP_EXTENSION_SAFE;
+
   if (in.exports->hasWeakSymbol || in.weakBinding->hasNonWeakDefinition())
     hdr->flags |= MH_WEAK_DEFINES;
 

diff  --git a/lld/test/MachO/application-extension.s b/lld/test/MachO/application-extension.s
new file mode 100644
index 000000000000..eb4c61965e98
--- /dev/null
+++ b/lld/test/MachO/application-extension.s
@@ -0,0 +1,115 @@
+# REQUIRES: aarch64
+
+## --no-leading-lines is needed for .tbd files.
+# RUN: rm -rf %t; split-file --no-leading-lines %s %t
+
+# RUN: llvm-mc -filetype=obj -triple=arm64-apple-macos -o %t/foo.o %t/foo.s
+# RUN: llvm-mc -filetype=obj -triple=arm64-apple-macos -o %t/bar.o %t/bar.s
+
+## MH_APP_EXTENSION_SAFE is only set on dylibs, and only if requested.
+# RUN: %lld -arch arm64 -dylib -o %t/foo.dylib %t/foo.o
+# RUN: llvm-otool -hv %t/foo.dylib | FileCheck --check-prefix=NOAPPEXT %s
+# RUN: %lld -arch arm64 -dylib -o %t/foo-appext.dylib %t/foo.o \
+# RUN:     -application_extension
+# RUN: llvm-otool -hv %t/foo-appext.dylib | FileCheck --check-prefix=APPEXT %s
+# RUN: %lld -arch arm64 -dylib -o %t/foo-noappext.dylib %t/foo.o \
+# RUN:     -application_extension -no_application_extension
+# RUN: llvm-otool -hv %t/foo-noappext.dylib \
+# RUN:     | FileCheck --check-prefix=NOAPPEXT %s
+# RUN: %lld -arch arm64 -bundle -o %t/foo.so %t/foo.o \
+# RUN:     -application_extension
+# RUN: llvm-otool -hv %t/foo.so | FileCheck --check-prefix=NOAPPEXT %s
+
+# APPEXT: APP_EXTENSION_SAFE
+# NOAPPEXT-NOT: APP_EXTENSION_SAFE
+
+## The warning is emitted for all target types.
+# RUN: %lld -arch arm64 -dylib -o %t/bar.dylib %t/bar.o \
+# RUN:     -application_extension %t/foo-appext.dylib
+# RUN: %lld -arch arm64 -dylib -o %t/bar.dylib %t/bar.o \
+# RUN:     -application_extension -L %t -ltbd-appext
+# RUN: not %lld -arch arm64 -dylib -o %t/bar.dylib %t/bar.o \
+# RUN:     -application_extension %t/foo-noappext.dylib \
+# RUN:     2>&1 | FileCheck --check-prefix=WARN %s
+# RUN: not %lld -arch arm64 -dylib -o %t/bar.dylib %t/bar.o \
+# RUN:     -application_extension -L %t -ltbd-noappext \
+# RUN:     2>&1 | FileCheck --check-prefix=WARN %s
+# RUN: not %lld -arch arm64 -bundle -o %t/bar.so %t/bar.o \
+# RUN:     -application_extension %t/foo-noappext.dylib \
+# RUN:     2>&1 | FileCheck --check-prefix=WARN %s
+# RUN: not %lld -arch arm64 -bundle -o %t/bar.so %t/bar.o \
+# RUN:     -application_extension -L %t -ltbd-noappext \
+# RUN:     2>&1 | FileCheck --check-prefix=WARN %s
+
+# WARN: using '-application_extension' with unsafe dylib:
+
+## Test we warn on dylibs loaded indirectly via reexports.
+# RUN: not %lld -arch arm64 -dylib -o %t/bar.dylib %t/bar.o \
+# RUN:     -application_extension -L %t -lbaz-noappext-reexport \
+# RUN:     -u _baz 2>&1 | FileCheck --check-prefix=WARN %s
+
+#--- foo.s
+.globl _foo
+.p2align 2
+_foo:
+  ret
+
+#--- libtbd-appext.tbd
+--- !tapi-tbd
+tbd-version: 4
+targets: [ arm64-macos ]
+uuids:
+  - target: arm64-macos
+    value:  2E994C7F-3F03-3A07-879C-55690D22BEDA
+install-name:     '/usr/lib/libtbd-appext.dylib'
+exports:
+  - targets:      [ arm64-macos ]
+    symbols:      [ _foo ]
+...
+
+#--- libtbd-noappext.tbd
+--- !tapi-tbd
+tbd-version: 4
+targets: [ arm64-macos ]
+flags: [ not_app_extension_safe ]
+uuids:
+  - target: arm64-macos
+    value:  2E994C7F-3F03-3A07-879C-55690D22BEDA
+install-name:     '/usr/lib/libtbd-noappext.dylib'
+exports:
+  - targets:      [ arm64-macos ]
+    symbols:      [ _foo ]
+...
+
+#--- bar.s
+.globl _bar
+.p2align 2
+_bar:
+  ret
+
+#--- libbaz-noappext-reexport.tbd
+--- !tapi-tbd
+tbd-version:      4
+targets:          [ arm64-macos ]
+uuids:
+  - target:       arm64-macos
+    value:        00000000-0000-0000-0000-000000000001
+install-name:     '/usr/lib/libbaz.dylib'
+reexported-libraries:
+  - targets:      [ arm64-macos ]
+    libraries:    [ '/usr/lib/libbaz-noappext-reexport.dylib']
+--- !tapi-tbd
+tbd-version:      4
+targets:          [ arm64-macos ]
+flags: [ not_app_extension_safe ]
+uuids:
+  - target:       arm64-macos
+    value:        00000000-0000-0000-0000-000000000003
+install-name:     '/usr/lib/libbaz-noappext-reexport.dylib'
+parent-umbrella:
+  - targets:      [ arm64-macos ]
+    umbrella:     baz
+exports:
+  - targets:      [ arm64-macos ]
+    symbols:      [ _baz ]
+...


        


More information about the llvm-commits mailing list