diff options
| -rw-r--r-- | lld/ELF/SymbolTable.cpp | 27 | ||||
| -rw-r--r-- | lld/ELF/SymbolTable.h | 2 | ||||
| -rw-r--r-- | lld/test/elf2/basic.s | 2 |
3 files changed, 28 insertions, 3 deletions
diff --git a/lld/ELF/SymbolTable.cpp b/lld/ELF/SymbolTable.cpp index b9640fecb0f..b3b1ce8ca83 100644 --- a/lld/ELF/SymbolTable.cpp +++ b/lld/ELF/SymbolTable.cpp @@ -101,6 +101,29 @@ void SymbolTable::addELFFile(ELFFileBase *File) { } } +template <class ELFT> +void SymbolTable::dupErorr(const SymbolBody &Old, const SymbolBody &New) { + typedef typename ELFFile<ELFT>::Elf_Sym Elf_Sym; + typedef typename ELFFile<ELFT>::Elf_Sym_Range Elf_Sym_Range; + + const Elf_Sym &OldE = cast<ELFSymbolBody<ELFT>>(Old).Sym; + const Elf_Sym &NewE = cast<ELFSymbolBody<ELFT>>(New).Sym; + ELFFileBase *OldFile = nullptr; + ELFFileBase *NewFile = nullptr; + + for (const std::unique_ptr<ObjectFileBase> &F : ObjectFiles) { + const auto &File = cast<ObjectFile<ELFT>>(*F); + Elf_Sym_Range Syms = File.getObj()->symbols(File.getSymbolTable()); + if (&OldE > Syms.begin() && &OldE < Syms.end()) + OldFile = F.get(); + if (&NewE > Syms.begin() && &NewE < Syms.end()) + NewFile = F.get(); + } + + error(Twine("duplicate symbol: ") + Old.getName() + " in " + + OldFile->getName() + " and " + NewFile->getName()); +} + // This function resolves conflicts if there's an existing symbol with // the same name. Decisions are made based on symbol type. template <class ELFT> void SymbolTable::resolve(SymbolBody *New) { @@ -127,8 +150,8 @@ template <class ELFT> void SymbolTable::resolve(SymbolBody *New) { int comp = Existing->compare<ELFT>(New); if (comp < 0) Sym->Body = New; - if (comp == 0) - error(Twine("duplicate symbol: ") + Sym->Body->getName()); + else if (comp == 0) + dupErorr<ELFT>(*Existing, *New); } Symbol *SymbolTable::insert(SymbolBody *New) { diff --git a/lld/ELF/SymbolTable.h b/lld/ELF/SymbolTable.h index bd69290fc98..5f539b372d9 100644 --- a/lld/ELF/SymbolTable.h +++ b/lld/ELF/SymbolTable.h @@ -70,6 +70,8 @@ private: template <class ELFT> void init(uint16_t EMachine); template <class ELFT> void resolve(SymbolBody *Body); + template <class ELFT> + void dupErorr(const SymbolBody &Old, const SymbolBody &New); std::vector<std::unique_ptr<ArchiveFile>> ArchiveFiles; diff --git a/lld/test/elf2/basic.s b/lld/test/elf2/basic.s index ee1cd5f5e11..4c7f4e29aa3 100644 --- a/lld/test/elf2/basic.s +++ b/lld/test/elf2/basic.s @@ -199,4 +199,4 @@ _start: # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t # RUN: not lld -flavor gnu2 %t %t -o %t2 2>&1 | FileCheck --check-prefix=DUP %s -# DUP: duplicate symbol: _start +# DUP: duplicate symbol: _start in {{.*}} and {{.*}} |

