diff options
Diffstat (limited to 'lld')
-rw-r--r-- | lld/MachO/Driver.cpp | 21 | ||||
-rw-r--r-- | lld/MachO/Writer.cpp | 3 | ||||
-rw-r--r-- | lld/test/MachO/load-commands.s | 51 |
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 |