aboutsummaryrefslogtreecommitdiff
path: root/lld
diff options
context:
space:
mode:
Diffstat (limited to 'lld')
-rw-r--r--lld/MachO/Driver.cpp21
-rw-r--r--lld/MachO/Writer.cpp3
-rw-r--r--lld/test/MachO/load-commands.s51
3 files changed, 63 insertions, 12 deletions
diff --git a/lld/MachO/Driver.cpp b/lld/MachO/Driver.cpp
index 38dc561..4991966 100644
--- a/lld/MachO/Driver.cpp
+++ b/lld/MachO/Driver.cpp
@@ -88,6 +88,24 @@ void MachOOptTable::printHelp(const char *argv0, bool showHidden) const {
lld::outs() << "\n";
}
+HeaderFileType getOutputType(const opt::InputArgList &args) {
+ // TODO: -r, -dylinker, -preload...
+ opt::Arg *outputArg = args.getLastArg(OPT_bundle, OPT_dylib, OPT_execute);
+ if (outputArg == nullptr)
+ return MH_EXECUTE;
+
+ switch (outputArg->getOption().getID()) {
+ case OPT_bundle:
+ return MH_BUNDLE;
+ case OPT_dylib:
+ return MH_DYLIB;
+ case OPT_execute:
+ return MH_EXECUTE;
+ default:
+ llvm_unreachable("internal error");
+ }
+}
+
static Optional<std::string>
findAlongPathsWithExtensions(StringRef name, ArrayRef<StringRef> extensions) {
llvm::SmallString<261> base;
@@ -575,7 +593,7 @@ bool macho::link(llvm::ArrayRef<const char *> argsArr, bool canExitEarly,
config->headerPad = args::getHex(args, OPT_headerpad, /*Default=*/32);
config->headerPadMaxInstallNames =
args.hasArg(OPT_headerpad_max_install_names);
- config->outputType = args.hasArg(OPT_dylib) ? MH_DYLIB : MH_EXECUTE;
+ config->outputType = getOutputType(args);
config->runtimePaths = args::getStrings(args, OPT_rpath);
config->allLoad = args.hasArg(OPT_all_load);
config->forceLoadObjC = args.hasArg(OPT_ObjC);
@@ -661,6 +679,7 @@ bool macho::link(llvm::ArrayRef<const char *> argsArr, bool canExitEarly,
}
config->isPic = config->outputType == MH_DYLIB ||
+ config->outputType == MH_BUNDLE ||
(config->outputType == MH_EXECUTE && args.hasArg(OPT_pie));
// Now that all dylibs have been loaded, search for those that should be
diff --git a/lld/MachO/Writer.cpp b/lld/MachO/Writer.cpp
index 055e2f2..4572c52 100644
--- a/lld/MachO/Writer.cpp
+++ b/lld/MachO/Writer.cpp
@@ -377,6 +377,8 @@ void Writer::createLoadCommands() {
case MH_DYLIB:
in.header->addLoadCommand(make<LCDylib>(LC_ID_DYLIB, config->installName));
break;
+ case MH_BUNDLE:
+ break;
default:
llvm_unreachable("unhandled output file type");
}
@@ -532,6 +534,7 @@ void Writer::createOutputSections() {
make<PageZeroSection>();
break;
case MH_DYLIB:
+ case MH_BUNDLE:
break;
default:
llvm_unreachable("unhandled output file type");
diff --git a/lld/test/MachO/load-commands.s b/lld/test/MachO/load-commands.s
index c9f5d9b..3e9c07c 100644
--- a/lld/test/MachO/load-commands.s
+++ b/lld/test/MachO/load-commands.s
@@ -1,19 +1,48 @@
# REQUIRES: x86
-# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-darwin %s -o %t.o
-# RUN: lld -flavor darwinnew -o %t %t.o
+# RUN: rm -rf %t && mkdir -p %t
+# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-darwin %s -o %t/test.o
+# RUN: lld -flavor darwinnew -o %t/executable %t/test.o
+# RUN: lld -flavor darwinnew -bundle -o %t/bundle %t/test.o
+# RUN: lld -flavor darwinnew -dylib -o %t/dylib %t/test.o
+
+## These load commands should be in every final output binary.
+# COMMON-DAG: cmd LC_DYLD_INFO_ONLY
+# COMMON-DAG: cmd LC_SYMTAB
+# COMMON-DAG: cmd LC_DYSYMTAB
## Check for the presence of load commands that are essential for a working
-## executable.
-# RUN: llvm-objdump --macho --all-headers %t | FileCheck %s
-# CHECK-DAG: cmd LC_DYLD_INFO_ONLY
-# CHECK-DAG: cmd LC_SYMTAB
-# CHECK-DAG: cmd LC_DYSYMTAB
-# CHECK-DAG: cmd LC_MAIN
-# CHECK-DAG: cmd LC_LOAD_DYLINKER
+## executable. Also check that it has the right filetype.
+# RUN: llvm-objdump --macho --all-headers %t/executable | FileCheck %s --check-prefix=COMMON
+# RUN: llvm-objdump --macho --all-headers %t/executable | FileCheck %s --check-prefix=EXEC
+# EXEC: magic cputype cpusubtype caps filetype
+# EXEC-NEXT: MH_MAGIC_64 X86_64 ALL {{.*}} EXECUTE
+# EXEC-DAG: cmd LC_MAIN
+# EXEC-DAG: cmd LC_LOAD_DYLINKER
## Check for the absence of load commands that should not be in an executable.
-# RUN: llvm-objdump --macho --all-headers %t | FileCheck %s --check-prefix=NCHECK
-# NCHECK-NOT: cmd: LC_ID_DYLIB
+# RUN: llvm-objdump --macho --all-headers %t/executable | FileCheck %s --check-prefix=NEXEC
+# NEXEC-NOT: cmd: LC_ID_DYLIB
+
+## Check for the presence / absence of load commands for the dylib.
+# RUN: llvm-objdump --macho --all-headers %t/dylib | FileCheck %s --check-prefix=COMMON
+# RUN: llvm-objdump --macho --all-headers %t/dylib | FileCheck %s --check-prefix=DYLIB
+# DYLIB: magic cputype cpusubtype caps filetype
+# DYLIB-NEXT: MH_MAGIC_64 X86_64 ALL {{.*}} DYLIB
+# DYLIB: cmd LC_ID_DYLIB
+
+# RUN: llvm-objdump --macho --all-headers %t/bundle | FileCheck %s --check-prefix=NDYLIB
+# NDYLIB-NOT: cmd: LC_MAIN
+# NDYLIB-NOT: cmd: LC_LOAD_DYLINKER
+
+## Check for the presence / absence of load commands for the bundle.
+# RUN: llvm-objdump --macho --all-headers %t/bundle | FileCheck %s --check-prefix=COMMON
+# RUN: llvm-objdump --macho --all-headers %t/bundle | FileCheck %s --check-prefix=BUNDLE
+# BUNDLE: magic cputype cpusubtype caps filetype
+# BUNDLE-NEXT: MH_MAGIC_64 X86_64 ALL {{.*}} BUNDLE
+
+# RUN: llvm-objdump --macho --all-headers %t/bundle | FileCheck %s --check-prefix=NBUNDLE
+# NBUNDLE-NOT: cmd: LC_MAIN
+# NBUNDLE-NOT: cmd: LC_LOAD_DYLINKER
.text
.global _main