RUN: not llvm-dwp %p/../Inputs/duplicate/c.dwo %p/../Inputs/duplicate/c.dwo -o %t 2>&1 \
-RUN: | FileCheck --check-prefix=CHECK %s
+RUN: | FileCheck --check-prefix=DWOS %s
RUN: not llvm-dwp %p/../Inputs/duplicate/c.dwo %p/../Inputs/duplicate/bc.dwp -o %t 2>&1 \
-RUN: | FileCheck --check-prefix=CHECK --check-prefix=DWP2 %s
+RUN: | FileCheck --check-prefix=2DWP %s
RUN: not llvm-dwp %p/../Inputs/duplicate/ac.dwp %p/../Inputs/duplicate/c.dwo -o %t 2>&1 \
-RUN: | FileCheck --check-prefix=CHECK --check-prefix=DWP1 %s
+RUN: | FileCheck --check-prefix=1DWP %s
-RUN: not llvm-dwp %p/../Inputs/duplicate/ac.dwp %p/../Inputs/duplicate/bc.dwp -o %t 2>&1 \
-RUN: | FileCheck --check-prefix=CHECK --check-prefix=DWP1 --check-prefix=DWP2 %s
+RUN: not llvm-dwp %p/../Inputs/duplicate_dwo_name/c.dwo %p/../Inputs/duplicate_dwo_name/c.dwo -o %t 2>&1 \
+RUN: | FileCheck --check-prefix=DWODWOS %s
+
+RUN: not llvm-dwp %p/../Inputs/duplicate_dwo_name/c.dwo %p/../Inputs/duplicate_dwo_name/bc.dwp -o %t 2>&1 \
+RUN: | FileCheck --check-prefix=DWO2DWP %s
+
+RUN: not llvm-dwp %p/../Inputs/duplicate_dwo_name/ac.dwp %p/../Inputs/duplicate_dwo_name/c.dwo -o %t 2>&1 \
+RUN: | FileCheck --check-prefix=DWO1DWP %s
Build from a, b, and c.c all containing a single void() func by the name of the file.
-CHECK: Duplicate DWO ID ({{.*}}) in 'c.c'
-DWP1-SAME: (from '{{.*}}ac.dwp')
-CHECK-SAME: and 'c.c'
-DWP2-SAME: (from '{{.*}}bc.dwp')
+DWOS: Duplicate DWO ID ({{.*}}) in 'c.c' and 'c.c'{{$}}
+1DWP: Duplicate DWO ID ({{.*}}) in 'c.c' (from '{{.*}}ac.dwp') and 'c.c'{{$}}
+2DWP: Duplicate DWO ID ({{.*}}) in 'c.c' and 'c.c' (from '{{.*}}bc.dwp'){{$}}
+
+DWODWOS: Duplicate DWO ID ({{.*}}) in 'c.c' and 'c.c'{{$}}
+DWO1DWP: Duplicate DWO ID ({{.*}}) in 'c.c' (from 'c.dwo' in '{{.*}}ac.dwp') and 'c.c'{{$}}
+DWO2DWP: Duplicate DWO ID ({{.*}}) in 'c.c' and 'c.c' (from 'c.dwo' in '{{.*}}bc.dwp'){{$}}
struct CompileUnitIdentifiers {
uint64_t Signature = 0;
- const char *Name = nullptr;
- const char *DWOName = nullptr;
+ const char *Name = "";
+ const char *DWOName = "";
};
+static const char *getIndexedString(uint32_t StrIndex, StringRef StrOffsets,
+ StringRef Str) {
+ DataExtractor StrOffsetsData(StrOffsets, true, 0);
+ uint32_t StrOffsetsOffset = 4 * StrIndex;
+ uint32_t StrOffset = StrOffsetsData.getU32(&StrOffsetsOffset);
+ DataExtractor StrData(Str, true, 0);
+ return StrData.getCStr(&StrOffset);
+}
+
static CompileUnitIdentifiers getCUIdentifiers(StringRef Abbrev, StringRef Info,
StringRef StrOffsets,
StringRef Str) {
(Name != 0 || Form != 0)) {
switch (Name) {
case dwarf::DW_AT_name: {
- auto StrIndex = InfoData.getULEB128(&Offset);
-
- DataExtractor StrOffsetsData(StrOffsets, true, 0);
- uint32_t StrOffsetsOffset = 4 * StrIndex;
- uint32_t StrOffset = StrOffsetsData.getU32(&StrOffsetsOffset);
- DataExtractor StrData(Str, true, 0);
- ID.Name = StrData.getCStr(&StrOffset);
+ ID.Name = getIndexedString(InfoData.getULEB128(&Offset), StrOffsets, Str);
+ break;
+ }
+ case dwarf::DW_AT_GNU_dwo_name: {
+ ID.DWOName =
+ getIndexedString(InfoData.getULEB128(&Offset), StrOffsets, Str);
break;
}
case dwarf::DW_AT_GNU_dwo_id:
struct UnitIndexEntry {
DWARFUnitIndex::Entry::SectionContribution Contributions[8];
std::string Name;
+ std::string DWOName;
StringRef DWPName;
};
return true;
}
+void printDuplicateError(const std::pair<uint64_t, UnitIndexEntry> &PrevE,
+ const CompileUnitIdentifiers &ID, StringRef DWPName) {
+ errs() << "Duplicate DWO ID (" << PrevE.first << ") in '" << PrevE.second.Name
+ << '\'';
+ if (!PrevE.second.DWPName.empty()) {
+ errs() << " (from ";
+ if (!PrevE.second.DWOName.empty())
+ errs() << '\'' << PrevE.second.DWOName << "' in ";
+ errs() << "'" << PrevE.second.DWPName.str() << "')";
+ }
+ errs() << " and '" << ID.Name << '\'';
+ if (!DWPName.empty()) {
+ errs() << " (from ";
+ if (*ID.DWOName)
+ errs() << '\'' << ID.DWOName << "\' in ";
+ errs() << '\'' << DWPName << "')";
+ }
+ errs() << '\n';
+}
static std::error_code write(MCStreamer &Out, ArrayRef<std::string> Inputs) {
const auto &MCOFI = *Out.getContext().getObjectFileInfo();
MCSection *const StrSection = MCOFI.getDwarfStrDWOSection();
getSubsection(CurStrOffsetSection, E, DW_SECT_STR_OFFSETS),
CurStrSection);
if (!P.second) {
- auto &PrevE = *P.first;
- std::cerr << "Duplicate DWO ID (" << PrevE.first << ") in '" << PrevE.second.Name << "' ";
- if (!PrevE.second.DWPName.empty())
- std::cerr << "(from '" << PrevE.second.DWPName.str() << "') ";
- std::cerr << "and '" << ID.Name << "' (from '" << Input << "')\n";
+ printDuplicateError(*P.first, ID, Input);
return make_error_code(std::errc::invalid_argument);
}
auto &NewEntry = P.first->second;
NewEntry.Name = ID.Name;
+ NewEntry.DWOName = ID.DWOName;
NewEntry.DWPName = Input;
for (auto Kind : CUIndex.getColumnKinds()) {
auto &C = NewEntry.Contributions[Kind - DW_SECT_INFO];
AbbrevSection, InfoSection, CurStrOffsetSection, CurStrSection);
auto P = IndexEntries.insert(std::make_pair(ID.Signature, CurEntry));
if (!P.second) {
- auto &E = *P.first;
- std::cerr << "Duplicate DWO ID (" << E.first << ") in '" << ID.Name
- << "' ";
- if (!E.second.DWPName.empty())
- std::cerr << "(from '" << E.second.DWPName.str() << "') ";
- std::cerr << "and '" << E.second.Name << "'\n";
+ printDuplicateError(*P.first, ID, "");
return make_error_code(std::errc::invalid_argument);
}
P.first->second.Name = ID.Name;
+ P.first->second.DWOName = ID.DWOName;
addAllTypes(Out, TypeIndexEntries, TypesSection, CurTypesSection,
CurEntry, ContributionOffsets[DW_SECT_TYPES - DW_SECT_INFO]);
}