diff options
| -rw-r--r-- | lld/ELF/Driver.cpp | 2 | ||||
| -rw-r--r-- | lld/ELF/SymbolTable.cpp | 26 | ||||
| -rw-r--r-- | lld/test/ELF/conflict.s | 6 |
3 files changed, 22 insertions, 12 deletions
diff --git a/lld/ELF/Driver.cpp b/lld/ELF/Driver.cpp index 2b0789b972f..61727c446f8 100644 --- a/lld/ELF/Driver.cpp +++ b/lld/ELF/Driver.cpp @@ -335,6 +335,8 @@ template <class ELFT> void LinkerDriver::link(opt::InputArgList &Args) { for (std::unique_ptr<InputFile> &F : Files) Symtab.addFile(std::move(F)); + if (HasError) + return; // There were duplicate symbols or incompatible files for (StringRef S : Config->Undefined) Symtab.addUndefinedOpt(S); diff --git a/lld/ELF/SymbolTable.cpp b/lld/ELF/SymbolTable.cpp index 1cb8b5d9a57..1e1c8aad589 100644 --- a/lld/ELF/SymbolTable.cpp +++ b/lld/ELF/SymbolTable.cpp @@ -30,25 +30,26 @@ using namespace lld::elf2; // All input object files must be for the same architecture // (e.g. it does not make sense to link x86 object files with // MIPS object files.) This function checks for that error. -template <class ELFT> -static void checkCompatibility(InputFile *FileP) { +template <class ELFT> static bool isCompatible(InputFile *FileP) { auto *F = dyn_cast<ELFFileBase<ELFT>>(FileP); if (!F) - return; + return true; if (F->getELFKind() == Config->EKind && F->getEMachine() == Config->EMachine) - return; + return true; StringRef A = F->getName(); StringRef B = Config->Emulation; if (B.empty()) B = Config->FirstElf->getName(); - fatal(A + " is incompatible with " + B); + error(A + " is incompatible with " + B); + return false; } // Add symbols in File to the symbol table. template <class ELFT> void SymbolTable<ELFT>::addFile(std::unique_ptr<InputFile> File) { InputFile *FileP = File.get(); - checkCompatibility<ELFT>(FileP); + if (!isCompatible<ELFT>(FileP)) + return; // .a file if (auto *F = dyn_cast<ArchiveFile>(FileP)) { @@ -181,17 +182,20 @@ template <class ELFT> void SymbolTable<ELFT>::resolve(SymbolBody *New) { return; } - if (New->isTls() != Existing->isTls()) - fatal("TLS attribute mismatch for symbol: " + conflictMsg(Existing, New)); + if (New->isTls() != Existing->isTls()) { + error("TLS attribute mismatch for symbol: " + conflictMsg(Existing, New)); + return; + } // compare() returns -1, 0, or 1 if the lhs symbol is less preferable, // equivalent (conflicting), or more preferable, respectively. int Comp = Existing->compare<ELFT>(New); if (Comp == 0) { std::string S = "duplicate symbol: " + conflictMsg(Existing, New); - if (!Config->AllowMultipleDefinition) - fatal(S); - warning(S); + if (Config->AllowMultipleDefinition) + warning(S); + else + error(S); return; } if (Comp < 0) diff --git a/lld/test/ELF/conflict.s b/lld/test/ELF/conflict.s index 73bdc7dacfc..96c1c3915b7 100644 --- a/lld/test/ELF/conflict.s +++ b/lld/test/ELF/conflict.s @@ -7,10 +7,14 @@ # RUN: FileCheck -check-prefix=NO_DEMANGLE %s # DEMANGLE: duplicate symbol: {{mul\(double, double\)|_Z3muldd}} in +# DEMANGLE: duplicate symbol: foo in + # NO_DEMANGLE: duplicate symbol: _Z3muldd in +# NO_DEMANGLE: duplicate symbol: foo in -.globl _Z3muldd +.globl _Z3muldd, foo _Z3muldd: +foo: mov $60, %rax mov $42, %rdi syscall |

