diff --git a/lld/ELF/Config.h b/lld/ELF/Config.h --- a/lld/ELF/Config.h +++ b/lld/ELF/Config.h @@ -90,6 +90,7 @@ uint32_t andFeatures = 0; llvm::CachePruningPolicy thinLTOCachePolicy; llvm::StringMap sectionStartMap; + llvm::StringRef bfdname; llvm::StringRef chroot; llvm::StringRef dynamicLinker; llvm::StringRef dwoDir; diff --git a/lld/ELF/InputFiles.cpp b/lld/ELF/InputFiles.cpp --- a/lld/ELF/InputFiles.cpp +++ b/lld/ELF/InputFiles.cpp @@ -138,8 +138,10 @@ return true; } - if (!config->emulation.empty()) { - error(toString(file) + " is incompatible with " + config->emulation); + StringRef target = + !config->bfdname.empty() ? config->bfdname : config->emulation; + if (!target.empty()) { + error(toString(file) + " is incompatible with " + target); return false; } @@ -148,8 +150,11 @@ existing = objectFiles[0]; else if (!sharedFiles.empty()) existing = sharedFiles[0]; - else + else if (!bitcodeFiles.empty()) existing = bitcodeFiles[0]; + else + llvm_unreachable("Must have -m, OUTPUT_FORMAT or existing input file to " + "determine target emulation"); error(toString(file) + " is incompatible with " + toString(existing)); return false; diff --git a/lld/ELF/ScriptParser.cpp b/lld/ELF/ScriptParser.cpp --- a/lld/ELF/ScriptParser.cpp +++ b/lld/ELF/ScriptParser.cpp @@ -412,14 +412,14 @@ void ScriptParser::readOutputFormat() { expect("("); - StringRef name = unquote(next()); - StringRef s = name; + config->bfdname = unquote(next()); + StringRef s = config->bfdname; if (s.consume_back("-freebsd")) config->osabi = ELFOSABI_FREEBSD; std::tie(config->ekind, config->emachine) = parseBfdName(s); if (config->emachine == EM_NONE) - setError("unknown output format name: " + name); + setError("unknown output format name: " + config->bfdname); if (s == "elf32-ntradlittlemips" || s == "elf32-ntradbigmips") config->mipsN32Abi = true; diff --git a/lld/test/ELF/incompatible.s b/lld/test/ELF/incompatible.s --- a/lld/test/ELF/incompatible.s +++ b/lld/test/ELF/incompatible.s @@ -44,6 +44,14 @@ // RUN: FileCheck --check-prefix=SO-AND-C-I386 %s // SO-AND-C-I386: c.o is incompatible with elf_i386 +// RUN: echo 'OUTPUT_FORMAT(elf32-i386)' > %t.script +// RUN: not ld.lld %t.script %ta.o -o /dev/null 2>&1 | \ +// RUN: FileCheck --check-prefix=A-AND-SCRIPT %s +// RUN: not ld.lld %ta.o %t.script -o /dev/null 2>&1 | \ +// RUN: FileCheck --check-prefix=A-AND-SCRIPT %s +// RUN: not ld.lld -m elf_x86_64 %ta.o %t.script -o /dev/null 2>&1 | \ +// RUN: FileCheck --check-prefix=A-AND-SCRIPT %s +// A-AND-SCRIPT: a.o is incompatible with elf32-i386 // We used to fail to identify this incompatibility and crash trying to // read a 64 bit file as a 32 bit one.