[lld] r375218 - [LLD] [COFF] Try to report source locations for duplicate symbols
Martin Storsjo via llvm-commits
llvm-commits at lists.llvm.org
Fri Oct 18 03:43:15 PDT 2019
Author: mstorsjo
Date: Fri Oct 18 03:43:15 2019
New Revision: 375218
URL: http://llvm.org/viewvc/llvm-project?rev=375218&view=rev
Log:
[LLD] [COFF] Try to report source locations for duplicate symbols
This fixes the second part of PR42407.
For files with dwarf debug info, it manually loads and iterates
.debug_info to find the declared location of variables, to allow
reporting them. (This matches the corresponding code in the ELF
linker.)
For functions, it uses the existing getFileLineDwarf which uses
LLVMSymbolizer for translating addresses to file lines.
In object files with codeview debug info, only the source location
of duplicate functions is printed. (And even there, only for the
first input file. The getFileLineCodeView function requires the
object file to be fully loaded and initialized to properly resolve
source locations, but duplicate symbols are reported at a stage when
the second object file isn't fully loaded yet.)
Differential Revision: https://reviews.llvm.org/D68975
Added:
lld/trunk/test/COFF/duplicate-cv.s
lld/trunk/test/COFF/duplicate-dwarf.s
Modified:
lld/trunk/COFF/InputFiles.cpp
lld/trunk/COFF/InputFiles.h
lld/trunk/COFF/SymbolTable.cpp
lld/trunk/COFF/SymbolTable.h
lld/trunk/test/COFF/conflict-mangled.test
lld/trunk/test/COFF/conflict.test
lld/trunk/test/COFF/duplicate.test
Modified: lld/trunk/COFF/InputFiles.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/InputFiles.cpp?rev=375218&r1=375217&r2=375218&view=diff
==============================================================================
--- lld/trunk/COFF/InputFiles.cpp (original)
+++ lld/trunk/COFF/InputFiles.cpp Fri Oct 18 03:43:15 2019
@@ -382,7 +382,8 @@ Symbol *ObjFile::createRegular(COFFSymbo
StringRef name;
coffObj->getSymbolName(sym, name);
if (sc)
- return symtab->addRegular(this, name, sym.getGeneric(), sc);
+ return symtab->addRegular(this, name, sym.getGeneric(), sc,
+ sym.getValue());
// For MinGW symbols named .weak.* that point to a discarded section,
// don't create an Undefined symbol. If nothing ever refers to the symbol,
// everything should be fine. If something actually refers to the symbol
@@ -536,7 +537,7 @@ void ObjFile::handleComdatSelection(COFF
// if the two comdat sections have e.g. different alignment.
// Match that.
if (leaderChunk->getContents() != newChunk.getContents())
- symtab->reportDuplicate(leader, this);
+ symtab->reportDuplicate(leader, this, &newChunk, sym.getValue());
break;
}
@@ -788,6 +789,89 @@ void ObjFile::initializeDependencies() {
debugTypesObj = makeTpiSource(this);
}
+// Used only for DWARF debug info, which is not common (except in MinGW
+// environments). This returns an optional pair of file name and line
+// number for where the variable was defined.
+Optional<std::pair<StringRef, uint32_t>>
+ObjFile::getVariableLocation(StringRef var) {
+ if (!dwarf) {
+ dwarf = DWARFContext::create(*getCOFFObj());
+ if (!dwarf)
+ return None;
+ initializeDwarf();
+ }
+ if (config->machine == I386)
+ var.consume_front("_");
+ auto it = variableLoc.find(var);
+ if (it == variableLoc.end())
+ return None;
+
+ // Take file name string from line table.
+ std::string fileName;
+ if (!it->second.lt->getFileNameByIndex(
+ it->second.file, {},
+ DILineInfoSpecifier::FileLineInfoKind::AbsoluteFilePath, fileName))
+ return None;
+
+ return std::make_pair(saver.save(fileName), it->second.line);
+}
+
+// Used only for DWARF debug info, which is not common (except in MinGW
+// environments). This initializes the dwarf, lineTables and variableLoc
+// members.
+void ObjFile::initializeDwarf() {
+ for (std::unique_ptr<DWARFUnit> &cu : dwarf->compile_units()) {
+ auto report = [](Error err) {
+ handleAllErrors(std::move(err),
+ [](ErrorInfoBase &info) { warn(info.message()); });
+ };
+ Expected<const DWARFDebugLine::LineTable *> expectedLT =
+ dwarf->getLineTableForUnit(cu.get(), report);
+ const DWARFDebugLine::LineTable *lt = nullptr;
+ if (expectedLT)
+ lt = *expectedLT;
+ else
+ report(expectedLT.takeError());
+ if (!lt)
+ continue;
+ lineTables.push_back(lt);
+
+ // Loop over variable records and insert them to variableLoc.
+ for (const auto &entry : cu->dies()) {
+ DWARFDie die(cu.get(), &entry);
+ // Skip all tags that are not variables.
+ if (die.getTag() != dwarf::DW_TAG_variable)
+ continue;
+
+ // Skip if a local variable because we don't need them for generating
+ // error messages. In general, only non-local symbols can fail to be
+ // linked.
+ if (!dwarf::toUnsigned(die.find(dwarf::DW_AT_external), 0))
+ continue;
+
+ // Get the source filename index for the variable.
+ unsigned file = dwarf::toUnsigned(die.find(dwarf::DW_AT_decl_file), 0);
+ if (!lt->hasFileAtIndex(file))
+ continue;
+
+ // Get the line number on which the variable is declared.
+ unsigned line = dwarf::toUnsigned(die.find(dwarf::DW_AT_decl_line), 0);
+
+ // Here we want to take the variable name to add it into variableLoc.
+ // Variable can have regular and linkage name associated. At first, we try
+ // to get linkage name as it can be different, for example when we have
+ // two variables in different namespaces of the same object. Use common
+ // name otherwise, but handle the case when it also absent in case if the
+ // input object file lacks some debug info.
+ StringRef name =
+ dwarf::toString(die.find(dwarf::DW_AT_linkage_name),
+ dwarf::toString(die.find(dwarf::DW_AT_name), ""));
+ if (!name.empty())
+ variableLoc.insert({name, {lt, file, line}});
+ }
+ }
+}
+
StringRef ltrim1(StringRef s, const char *chars) {
if (!s.empty() && strchr(chars, s[0]))
return s.substr(1);
Modified: lld/trunk/COFF/InputFiles.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/InputFiles.h?rev=375218&r1=375217&r2=375218&view=diff
==============================================================================
--- lld/trunk/COFF/InputFiles.h (original)
+++ lld/trunk/COFF/InputFiles.h Fri Oct 18 03:43:15 2019
@@ -16,6 +16,7 @@
#include "llvm/ADT/DenseSet.h"
#include "llvm/BinaryFormat/Magic.h"
#include "llvm/DebugInfo/CodeView/TypeRecord.h"
+#include "llvm/DebugInfo/DWARF/DWARFContext.h"
#include "llvm/LTO/LTO.h"
#include "llvm/Object/Archive.h"
#include "llvm/Object/COFF.h"
@@ -202,6 +203,9 @@ public:
// The .debug$T stream if there's one.
llvm::Optional<llvm::codeview::CVTypeArray> debugTypes;
+ llvm::Optional<std::pair<StringRef, uint32_t>>
+ getVariableLocation(StringRef var);
+
private:
const coff_section* getSection(uint32_t i);
const coff_section *getSection(COFFSymbolRef sym) {
@@ -212,6 +216,7 @@ private:
void initializeSymbols();
void initializeFlags();
void initializeDependencies();
+ void initializeDwarf();
SectionChunk *
readSection(uint32_t sectionNumber,
@@ -285,6 +290,15 @@ private:
// index. Nonexistent indices (which are occupied by auxiliary
// symbols in the real symbol table) are filled with null pointers.
std::vector<Symbol *> symbols;
+
+ std::unique_ptr<llvm::DWARFContext> dwarf;
+ std::vector<const llvm::DWARFDebugLine::LineTable *> lineTables;
+ struct VarLoc {
+ const llvm::DWARFDebugLine::LineTable *lt;
+ unsigned file;
+ unsigned line;
+ };
+ llvm::DenseMap<StringRef, VarLoc> variableLoc;
};
// This type represents import library members that contain DLL names
Modified: lld/trunk/COFF/SymbolTable.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/SymbolTable.cpp?rev=375218&r1=375217&r2=375218&view=diff
==============================================================================
--- lld/trunk/COFF/SymbolTable.cpp (original)
+++ lld/trunk/COFF/SymbolTable.cpp Fri Oct 18 03:43:15 2019
@@ -520,15 +520,69 @@ void SymbolTable::addLazyObject(LazyObjF
f->fetch();
}
-void SymbolTable::reportDuplicate(Symbol *existing, InputFile *newFile) {
- std::string msg = "duplicate symbol: " + toString(*existing) + " in " +
- toString(existing->getFile()) + " and in " +
- toString(newFile);
+static std::string getSourceLocationBitcode(BitcodeFile *file) {
+ std::string res("\n>>> defined at ");
+ StringRef source = file->obj->getSourceFileName();
+ if (!source.empty())
+ res += source.str() + "\n>>> ";
+ res += toString(file);
+ return res;
+}
+
+static std::string getSourceLocationObj(ObjFile *file, SectionChunk *sc,
+ uint32_t offset, StringRef name) {
+ Optional<std::pair<StringRef, uint32_t>> fileLine;
+ if (sc)
+ fileLine = getFileLine(sc, offset);
+ if (!fileLine)
+ fileLine = file->getVariableLocation(name);
+
+ std::string res;
+ llvm::raw_string_ostream os(res);
+ os << "\n>>> defined at ";
+ if (fileLine)
+ os << fileLine->first << ":" << fileLine->second << "\n>>> ";
+ os << toString(file);
+ return os.str();
+}
+
+static std::string getSourceLocation(InputFile *file, SectionChunk *sc,
+ uint32_t offset, StringRef name) {
+ if (auto *o = dyn_cast<ObjFile>(file))
+ return getSourceLocationObj(o, sc, offset, name);
+ if (auto *b = dyn_cast<BitcodeFile>(file))
+ return getSourceLocationBitcode(b);
+ return "\n>>> defined at " + toString(file);
+}
+
+// Construct and print an error message in the form of:
+//
+// lld-link: error: duplicate symbol: foo
+// >>> defined at bar.c:30
+// >>> bar.o
+// >>> defined at baz.c:563
+// >>> baz.o
+void SymbolTable::reportDuplicate(Symbol *existing, InputFile *newFile,
+ SectionChunk *newSc,
+ uint32_t newSectionOffset) {
+ std::string msg;
+ llvm::raw_string_ostream os(msg);
+ os << "duplicate symbol: " << toString(*existing);
+
+ DefinedRegular *d = cast<DefinedRegular>(existing);
+ if (d && isa<ObjFile>(d->getFile())) {
+ os << getSourceLocation(d->getFile(), d->getChunk(), d->getValue(),
+ existing->getName());
+ } else {
+ os << getSourceLocation(existing->getFile(), nullptr, 0, "");
+ }
+ os << getSourceLocation(newFile, newSc, newSectionOffset,
+ existing->getName());
if (config->forceMultiple)
- warn(msg);
+ warn(os.str());
else
- error(msg);
+ error(os.str());
}
Symbol *SymbolTable::addAbsolute(StringRef n, COFFSymbolRef sym) {
@@ -568,8 +622,8 @@ Symbol *SymbolTable::addSynthetic(String
}
Symbol *SymbolTable::addRegular(InputFile *f, StringRef n,
- const coff_symbol_generic *sym,
- SectionChunk *c) {
+ const coff_symbol_generic *sym, SectionChunk *c,
+ uint32_t sectionOffset) {
Symbol *s;
bool wasInserted;
std::tie(s, wasInserted) = insert(n, f);
@@ -577,7 +631,7 @@ Symbol *SymbolTable::addRegular(InputFil
replaceSymbol<DefinedRegular>(s, f, n, /*IsCOMDAT*/ false,
/*IsExternal*/ true, sym, c);
else
- reportDuplicate(s, f);
+ reportDuplicate(s, f, c, sectionOffset);
return s;
}
Modified: lld/trunk/COFF/SymbolTable.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/SymbolTable.h?rev=375218&r1=375217&r2=375218&view=diff
==============================================================================
--- lld/trunk/COFF/SymbolTable.h (original)
+++ lld/trunk/COFF/SymbolTable.h Fri Oct 18 03:43:15 2019
@@ -91,7 +91,7 @@ public:
Symbol *addAbsolute(StringRef n, COFFSymbolRef s);
Symbol *addRegular(InputFile *f, StringRef n,
const llvm::object::coff_symbol_generic *s = nullptr,
- SectionChunk *c = nullptr);
+ SectionChunk *c = nullptr, uint32_t sectionOffset = 0);
std::pair<DefinedRegular *, bool>
addComdat(InputFile *f, StringRef n,
const llvm::object::coff_symbol_generic *s = nullptr);
@@ -103,7 +103,9 @@ public:
uint16_t machine);
void addLibcall(StringRef name);
- void reportDuplicate(Symbol *existing, InputFile *newFile);
+ void reportDuplicate(Symbol *existing, InputFile *newFile,
+ SectionChunk *newSc = nullptr,
+ uint32_t newSectionOffset = 0);
// A list of chunks which to be added to .rdata.
std::vector<Chunk *> localImportChunks;
Modified: lld/trunk/test/COFF/conflict-mangled.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/COFF/conflict-mangled.test?rev=375218&r1=375217&r2=375218&view=diff
==============================================================================
--- lld/trunk/test/COFF/conflict-mangled.test (original)
+++ lld/trunk/test/COFF/conflict-mangled.test Fri Oct 18 03:43:15 2019
@@ -5,9 +5,13 @@
# RUN: not lld-link /out:%t.exe /demangle %t1.obj %t2.obj 2>&1 | FileCheck %s
# RUN: not lld-link /out:%t.exe /demangle:no %t1.obj %t2.obj 2>&1 | FileCheck --check-prefix=NODEMANGLE %s
-# NODEMANGLE: duplicate symbol: ?mangled@@YAHXZ in {{.+}}1.obj and in {{.+}}2.obj
+# NODEMANGLE: duplicate symbol: ?mangled@@YAHXZ
+# NODEMANGLE: defined at {{.+}}1.obj
+# NODEMANGLE: defined at {{.+}}2.obj
-# CHECK: duplicate symbol: int __cdecl mangled(void) in {{.+}}1.obj and in {{.+}}2.obj
+# CHECK: duplicate symbol: int __cdecl mangled(void)
+# CHECK: defined at {{.+}}1.obj
+# CHECK: defined at {{.+}}2.obj
--- !COFF
header:
Modified: lld/trunk/test/COFF/conflict.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/COFF/conflict.test?rev=375218&r1=375217&r2=375218&view=diff
==============================================================================
--- lld/trunk/test/COFF/conflict.test (original)
+++ lld/trunk/test/COFF/conflict.test Fri Oct 18 03:43:15 2019
@@ -1,15 +1,21 @@
# REQUIRES: x86
# RUN: yaml2obj < %s > %t1.obj
# RUN: yaml2obj < %s > %t2.obj
-# RUN: not lld-link /out:%t.exe %t1.obj %t2.obj >& %t.log
-# RUN: FileCheck %s < %t.log
+# RUN: not lld-link /out:%t.exe %t1.obj %t2.obj 2>&1 | FileCheck --check-prefix=OBJ %s
# RUN: llvm-as -o %t.lto1.obj %S/Inputs/conflict.ll
# RUN: llvm-as -o %t.lto2.obj %S/Inputs/conflict.ll
-# RUN: not lld-link /out:%t.exe %t.lto1.obj %t.lto2.obj >& %t.log
-# RUN: FileCheck %s < %t.log
+# RUN: not lld-link /out:%t.exe %t.lto1.obj %t.lto2.obj 2>&1 | FileCheck --check-prefix=BC %s
-# CHECK: duplicate symbol: foo in {{.+}}1.obj and in {{.+}}2.obj
+# OBJ: duplicate symbol: foo
+# OBJ: defined at {{.+}}1.obj
+# OBJ: defined at {{.+}}2.obj
+
+# BC: duplicate symbol: foo
+# BC: defined at {{.+}}conflict.ll
+# BC: {{.+}}1.obj
+# BC: defined at {{.+}}conflict.ll
+# BC: {{.+}}2.obj
--- !COFF
header:
Added: lld/trunk/test/COFF/duplicate-cv.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/COFF/duplicate-cv.s?rev=375218&view=auto
==============================================================================
--- lld/trunk/test/COFF/duplicate-cv.s (added)
+++ lld/trunk/test/COFF/duplicate-cv.s Fri Oct 18 03:43:15 2019
@@ -0,0 +1,30 @@
+# REQUIRES: x86
+# RUN: llvm-mc -triple=x86_64-windows-msvc -filetype=obj -o %t.obj %s
+# RUN: cp %t.obj %t.dupl.obj
+# RUN: not lld-link /out:%t.exe %t.obj %t.dupl.obj 2>&1 | FileCheck %s
+
+# CHECK: error: duplicate symbol: main
+# CHECK-NEXT: >>> defined at file1.cpp:2
+# CHECK-NEXT: >>> {{.*}}.obj
+# CHECK-NEXT: >>> defined at {{.*}}.obj
+
+ .cv_file 1 "file1.cpp" "EDA15C78BB573E49E685D8549286F33C" 1
+ .cv_file 2 "file2.cpp" "EDA15C78BB573E49E685D8549286F33D" 1
+
+ .section .text,"xr",one_only,main
+.globl main
+main:
+ .cv_func_id 0
+ .cv_loc 0 1 1 0 is_stmt 0
+ .cv_loc 0 1 2 0
+ retq
+.Lfunc_end0:
+
+ .section .debug$S,"dr",associative,main
+ .long 4
+ .cv_linetable 0, main, .Lfunc_end0
+
+ .section .debug$S,"dr"
+ .long 4
+ .cv_filechecksums
+ .cv_stringtable
Added: lld/trunk/test/COFF/duplicate-dwarf.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/COFF/duplicate-dwarf.s?rev=375218&view=auto
==============================================================================
--- lld/trunk/test/COFF/duplicate-dwarf.s (added)
+++ lld/trunk/test/COFF/duplicate-dwarf.s Fri Oct 18 03:43:15 2019
@@ -0,0 +1,213 @@
+# REQUIRES: x86
+# RUN: llvm-mc -triple=i686-windows-gnu -filetype=obj -o %t.o %s
+# RUN: cp %t.o %t.dupl.o
+# RUN: not lld-link -lldmingw -out:%t.exe %t.o %t.dupl.o -entry:_Z4funcv 2>&1 | FileCheck %s
+
+# CHECK: error: duplicate symbol: func()
+# CHECK-NEXT: >>> defined at /path/to/src{{[/\\]}}dupl.cpp:6
+# CHECK-NEXT: >>> {{.*}}.o
+# CHECK-NEXT: >>> defined at /path/to/src{{[/\\]}}dupl.cpp:6
+# CHECK-NEXT: >>> {{.*}}.o
+# CHECK-EMPTY:
+# CHECK-NEXT: error: duplicate symbol: _var
+# CHECK-NEXT: >>> defined at /path/to/src{{[/\\]}}dupl.cpp:1
+# CHECK-NEXT: >>> {{.*}}.o
+# CHECK-NEXT: >>> defined at /path/to/src{{[/\\]}}dupl.cpp:1
+# CHECK-NEXT: >>> {{.*}}.o
+# CHECK-EMPTY:
+# CHECK-NEXT: error: duplicate symbol: A::namespaceVar
+# CHECK-NEXT: >>> defined at /path/to/src{{[/\\]}}dupl.cpp:3
+# CHECK-NEXT: >>> {{.*}}.o
+# CHECK-NEXT: >>> defined at /path/to/src{{[/\\]}}dupl.cpp:3
+# CHECK-NEXT: >>> {{.*}}.o
+
+ .text
+ .file "dupl.cpp"
+ .file 1 "/path/to/src" "dupl.cpp"
+ .def __Z4funcv;
+ .globl __Z4funcv # -- Begin function _Z4funcv
+__Z4funcv: # @_Z4funcv
+Lfunc_begin0:
+ .loc 1 5 0 # dupl.cpp:5:0
+# %bb.0: # %entry
+ .loc 1 6 1 prologue_end # dupl.cpp:6:1
+ retl
+Lfunc_end0:
+ # -- End function
+ .bss
+ .globl _var # @var
+_var:
+ .long 0 # 0x0
+
+ .globl __ZN1A12namespaceVarE # @_ZN1A12namespaceVarE
+__ZN1A12namespaceVarE:
+ .long 0 # 0x0
+
+ .section .debug_str,"dr"
+Linfo_string:
+Linfo_string0:
+ .asciz "var"
+Linfo_string1:
+ .asciz "int"
+Linfo_string2:
+ .asciz "A"
+Linfo_string3:
+ .asciz "namespaceVar"
+Linfo_string4:
+ .asciz "_ZN1A12namespaceVarE"
+Linfo_string5:
+ .asciz "_Z4funcv"
+Linfo_string6:
+ .asciz "func"
+ .section .debug_abbrev,"dr"
+Lsection_abbrev:
+ .byte 1 # Abbreviation Code
+ .byte 17 # DW_TAG_compile_unit
+ .byte 1 # DW_CHILDREN_yes
+ .byte 37 # DW_AT_producer
+ .byte 37 # DW_FORM_strx1
+ .byte 19 # DW_AT_language
+ .byte 5 # DW_FORM_data2
+ .byte 3 # DW_AT_name
+ .byte 37 # DW_FORM_strx1
+ .byte 16 # DW_AT_stmt_list
+ .byte 23 # DW_FORM_sec_offset
+ .byte 17 # DW_AT_low_pc
+ .byte 1 # DW_FORM_addr
+ .byte 18 # DW_AT_high_pc
+ .byte 6 # DW_FORM_data4
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 2 # Abbreviation Code
+ .byte 52 # DW_TAG_variable
+ .byte 0 # DW_CHILDREN_no
+ .byte 3 # DW_AT_name
+ .byte 14 # DW_FORM_strp
+ .byte 73 # DW_AT_type
+ .byte 19 # DW_FORM_ref4
+ .byte 63 # DW_AT_external
+ .byte 25 # DW_FORM_flag_present
+ .byte 58 # DW_AT_decl_file
+ .byte 11 # DW_FORM_data1
+ .byte 59 # DW_AT_decl_line
+ .byte 11 # DW_FORM_data1
+ .byte 2 # DW_AT_location
+ .byte 24 # DW_FORM_exprloc
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 3 # Abbreviation Code
+ .byte 36 # DW_TAG_base_type
+ .byte 0 # DW_CHILDREN_no
+ .byte 3 # DW_AT_name
+ .byte 14 # DW_FORM_strp
+ .byte 62 # DW_AT_encoding
+ .byte 11 # DW_FORM_data1
+ .byte 11 # DW_AT_byte_size
+ .byte 11 # DW_FORM_data1
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 4 # Abbreviation Code
+ .byte 57 # DW_TAG_namespace
+ .byte 1 # DW_CHILDREN_yes
+ .byte 3 # DW_AT_name
+ .byte 14 # DW_FORM_strp
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 5 # Abbreviation Code
+ .byte 52 # DW_TAG_variable
+ .byte 0 # DW_CHILDREN_no
+ .byte 3 # DW_AT_name
+ .byte 14 # DW_FORM_strp
+ .byte 73 # DW_AT_type
+ .byte 19 # DW_FORM_ref4
+ .byte 63 # DW_AT_external
+ .byte 25 # DW_FORM_flag_present
+ .byte 58 # DW_AT_decl_file
+ .byte 11 # DW_FORM_data1
+ .byte 59 # DW_AT_decl_line
+ .byte 11 # DW_FORM_data1
+ .byte 2 # DW_AT_location
+ .byte 24 # DW_FORM_exprloc
+ .byte 110 # DW_AT_linkage_name
+ .byte 14 # DW_FORM_strp
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 6 # Abbreviation Code
+ .byte 46 # DW_TAG_subprogram
+ .byte 0 # DW_CHILDREN_no
+ .byte 17 # DW_AT_low_pc
+ .byte 1 # DW_FORM_addr
+ .byte 18 # DW_AT_high_pc
+ .byte 6 # DW_FORM_data4
+ .byte 64 # DW_AT_frame_base
+ .byte 24 # DW_FORM_exprloc
+ .byte 110 # DW_AT_linkage_name
+ .byte 14 # DW_FORM_strp
+ .byte 3 # DW_AT_name
+ .byte 14 # DW_FORM_strp
+ .byte 58 # DW_AT_decl_file
+ .byte 11 # DW_FORM_data1
+ .byte 59 # DW_AT_decl_line
+ .byte 11 # DW_FORM_data1
+ .byte 63 # DW_AT_external
+ .byte 25 # DW_FORM_flag_present
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 0 # EOM(3)
+ .section .debug_info,"dr"
+Lsection_info:
+Lcu_begin0:
+ .long Ldebug_info_end0-Ldebug_info_start0 # Length of Unit
+Ldebug_info_start0:
+ .short 4 # DWARF version number
+ .secrel32 Lsection_abbrev # Offset Into Abbrev. Section
+ .byte 4 # Address Size (in bytes)
+ .byte 1 # Abbrev [1] 0xb:0x64 DW_TAG_compile_unit
+ .byte 0 # DW_AT_producer
+ .short 33 # DW_AT_language
+ .byte 0 # DW_AT_name
+ .secrel32 Lline_table_start0 # DW_AT_stmt_list
+ .long Lfunc_begin0 # DW_AT_low_pc
+ .long Lfunc_end0-Lfunc_begin0 # DW_AT_high_pc
+ .byte 2 # Abbrev [2] 0x26:0x11 DW_TAG_variable
+ .secrel32 Linfo_string0 # DW_AT_name
+ .secrel32 Linfo_type_int # DW_AT_type
+ # DW_AT_external
+ .byte 1 # DW_AT_decl_file
+ .byte 1 # DW_AT_decl_line
+ .byte 5 # DW_AT_location
+ .byte 3
+ .long _var
+Linfo_type_int:
+ .byte 3 # Abbrev [3] 0x37:0x7 DW_TAG_base_type
+ .secrel32 Linfo_string1 # DW_AT_name
+ .byte 5 # DW_AT_encoding
+ .byte 4 # DW_AT_byte_size
+ .byte 4 # Abbrev [4] 0x3e:0x1b DW_TAG_namespace
+ .secrel32 Linfo_string2 # DW_AT_name
+ .byte 5 # Abbrev [5] 0x43:0x15 DW_TAG_variable
+ .secrel32 Linfo_string3 # DW_AT_name
+ .secrel32 Linfo_type_int # DW_AT_type
+ # DW_AT_external
+ .byte 1 # DW_AT_decl_file
+ .byte 3 # DW_AT_decl_line
+ .byte 5 # DW_AT_location
+ .byte 3
+ .long __ZN1A12namespaceVarE
+ .secrel32 Linfo_string4 # DW_AT_linkage_name
+ .byte 0 # End Of Children Mark
+ .byte 6 # Abbrev [6] 0x59:0x15 DW_TAG_subprogram
+ .long Lfunc_begin0 # DW_AT_low_pc
+ .long Lfunc_end0-Lfunc_begin0 # DW_AT_high_pc
+ .byte 1 # DW_AT_frame_base
+ .byte 84
+ .secrel32 Linfo_string5 # DW_AT_linkage_name
+ .secrel32 Linfo_string6 # DW_AT_name
+ .byte 1 # DW_AT_decl_file
+ .byte 5 # DW_AT_decl_line
+ # DW_AT_external
+ .byte 0 # End Of Children Mark
+Ldebug_info_end0:
+
+ .section .debug_line,"dr"
+Lline_table_start0:
Modified: lld/trunk/test/COFF/duplicate.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/COFF/duplicate.test?rev=375218&r1=375217&r2=375218&view=diff
==============================================================================
--- lld/trunk/test/COFF/duplicate.test (original)
+++ lld/trunk/test/COFF/duplicate.test Fri Oct 18 03:43:15 2019
@@ -4,10 +4,14 @@ RUN: llc -mtriple x86_64-windows-msvc -f
RUN: lld-link /out:alpha.dll /dll alpha.obj /implib:alpha.lib
RUN: not lld-link /out:beta.dll /dll alpha.obj beta.obj alpha.lib 2>&1 | FileCheck %s -check-prefix CHECK-ALPHA
-CHECK-ALPHA: error: duplicate symbol: f in {{.*}}alpha.obj and in alpha.dll
+CHECK-ALPHA: error: duplicate symbol: f
+CHECK-ALPHA: defined at {{.*}}alpha.obj
+CHECK-APLHA: defined at alpha.dll
RUN: llc -mtriple x86_64-windows-msvc -filetype obj -o gamma.obj %S/Inputs/gamma.ll
RUN: not lld-link /out:gamma.exe /subsystem:console /entry:mainCRTStartup gamma.obj alpha.lib 2>&1 | FileCheck %s -check-prefix CHECK-GAMMA
-CHECK-GAMMA: error: duplicate symbol: __declspec(dllimport) f in {{.*}}gamma.obj and in alpha.dll
+CHECK-GAMMA: error: duplicate symbol: __declspec(dllimport) f
+CHECK-GAMMA: defined at {{.*}}gamma.obj
+CHECK-GAMMA: defined at alpha.dll
More information about the llvm-commits
mailing list