diff --git a/lld/MachO/Arch/PlaceHolderTarget.cpp b/lld/MachO/Arch/PlaceHolderTarget.cpp new file mode 100644 --- /dev/null +++ b/lld/MachO/Arch/PlaceHolderTarget.cpp @@ -0,0 +1,64 @@ +#include "InputFiles.h" +#include "Symbols.h" +#include "SyntheticSections.h" +#include "Target.h" + +#include "lld/Common/ErrorHandler.h" +#include "llvm/BinaryFormat/MachO.h" + +using namespace llvm; +using namespace llvm::MachO; +using namespace llvm::support::endian; +using namespace lld; +using namespace lld::macho; + +namespace { +struct PlaceHolderTarget : TargetInfo { + PlaceHolderTarget() : TargetInfo(LP64()) {} + + int64_t getEmbeddedAddend(MemoryBufferRef, uint64_t offset, + const relocation_info) const override { + llvm_unreachable("not implemented"); + } + void relocateOne(uint8_t *loc, const Reloc &, uint64_t va, + uint64_t relocVA) const override { + llvm_unreachable("not implemented"); + } + + void writeStub(uint8_t *buf, const Symbol &) const override { + llvm_unreachable("not implemented"); + } + + void writeStubHelperHeader(uint8_t *buf) const override { + llvm_unreachable("not implemented"); + } + + void writeStubHelperEntry(uint8_t *buf, const DylibSymbol &, + uint64_t entryAddr) const override { + llvm_unreachable("not implemented"); + } + + void relaxGotLoad(uint8_t *loc, uint8_t type) const override { + llvm_unreachable("not implemented"); + } + + const RelocAttrs &getRelocAttrs(uint8_t type) const override { + llvm_unreachable("not implemented"); + } + + uint64_t getPageSize() const override { llvm_unreachable("not implemented"); } + + bool isPlaceHolder() const override { return true; } +}; + +} // namespace +namespace lld { +namespace macho { + +TargetInfo *createPlaceHolderTargetInfo() { + static PlaceHolderTarget t; + return &t; +} + +} // namespace macho +} // namespace lld diff --git a/lld/MachO/CMakeLists.txt b/lld/MachO/CMakeLists.txt --- a/lld/MachO/CMakeLists.txt +++ b/lld/MachO/CMakeLists.txt @@ -10,6 +10,7 @@ Arch/ARM64Common.cpp Arch/ARM64_32.cpp Arch/X86_64.cpp + Arch/PlaceHolderTarget.cpp ConcatOutputSection.cpp Driver.cpp DriverUtils.cpp diff --git a/lld/MachO/Driver.cpp b/lld/MachO/Driver.cpp --- a/lld/MachO/Driver.cpp +++ b/lld/MachO/Driver.cpp @@ -206,7 +206,9 @@ args.filtered(OPT_thinlto_cache_policy, OPT_prune_interval_lto, OPT_prune_after_lto, OPT_max_relative_cache_size_lto)) { switch (arg->getOption().getID()) { - case OPT_thinlto_cache_policy: add(arg->getValue()); break; + case OPT_thinlto_cache_policy: + add(arg->getValue()); + break; case OPT_prune_interval_lto: if (!strcmp("-1", arg->getValue())) add("prune_interval=87600h"); // 10 years @@ -653,8 +655,9 @@ // Has the side-effect of setting Config::target. static TargetInfo *createTargetInfo(InputArgList &args) { StringRef archName = args.getLastArgValue(OPT_arch); - if (archName.empty()) - fatal("must specify -arch"); + if (archName.empty()) { + error("must specify -arch"); + } PlatformKind platform = parsePlatformVersion(args); config->platformInfo.target = @@ -674,7 +677,10 @@ case CPU_TYPE_ARM: return createARMTargetInfo(cpuSubtype); default: - fatal("missing or unsupported -arch " + archName); + // Empty arch would have been reported already. + if (!archName.empty()) + error("unsupported -arch " + archName); + return createPlaceHolderTargetInfo(); } } @@ -1336,6 +1342,10 @@ initLLVM(); // must be run before any call to addFile() createFiles(args); + // Now that files have been parsed, check again to make sure the target is + // good. + if (target->isPlaceHolder()) + fatal("unknown target platform - giving up"); config->isPic = config->outputType == MH_DYLIB || config->outputType == MH_BUNDLE || diff --git a/lld/MachO/Target.h b/lld/MachO/Target.h --- a/lld/MachO/Target.h +++ b/lld/MachO/Target.h @@ -76,6 +76,8 @@ bool usesThunks() const { return thunkSize > 0; } + virtual bool isPlaceHolder() const { return false; } + uint32_t magic; llvm::MachO::CPUType cpuType; uint32_t cpuSubtype; @@ -102,6 +104,7 @@ TargetInfo *createARM64TargetInfo(); TargetInfo *createARM64_32TargetInfo(); TargetInfo *createARMTargetInfo(uint32_t cpuSubtype); +TargetInfo *createPlaceHolderTargetInfo(); struct LP64 { using mach_header = llvm::MachO::mach_header_64; diff --git a/lld/test/MachO/reproduce.s b/lld/test/MachO/reproduce.s --- a/lld/test/MachO/reproduce.s +++ b/lld/test/MachO/reproduce.s @@ -53,6 +53,11 @@ # RUN: cd repro2; ld64.lld @response.txt +## Error case +# RUN: rm -rf @no_such_file.txt +# RUN: not %lld @no_such_file.txt 2>&1 | FileCheck %s --check-prefix=NOFILE +# NOFILE: error: cannot open @no_such_file.txt: No such file or directory + .globl _main _main: ret