[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