mirror of
https://github.com/intel/llvm.git
synced 2026-01-29 04:16:38 +08:00
ELF: Report duplicate symbols as many as possible instead of the first one.
http://reviews.llvm.org/D16647 llvm-svn: 259233
This commit is contained in:
@@ -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);
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -7,10 +7,14 @@
|
||||
# RUN: FileCheck -check-prefix=NO_DEMANGLE %s
|
||||
|
||||
# DEMANGLE: duplicate symbol: {{mul\(double, double\)|_Z3muldd}} in
|
||||
# NO_DEMANGLE: duplicate symbol: _Z3muldd in
|
||||
# DEMANGLE: duplicate symbol: foo in
|
||||
|
||||
.globl _Z3muldd
|
||||
# NO_DEMANGLE: duplicate symbol: _Z3muldd in
|
||||
# NO_DEMANGLE: duplicate symbol: foo in
|
||||
|
||||
.globl _Z3muldd, foo
|
||||
_Z3muldd:
|
||||
foo:
|
||||
mov $60, %rax
|
||||
mov $42, %rdi
|
||||
syscall
|
||||
|
||||
Reference in New Issue
Block a user