llvm-dwp: Handle GCC's use of multiple debug_types.dwo sections in a single .dwo file

(also includes the .test file missing from my previous commit, r265452)

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@265457 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
David Blaikie 2016-04-05 20:26:50 +00:00
parent 15121b5f36
commit 46c3acf600
2 changed files with 39 additions and 29 deletions

View File

@ -0,0 +1,9 @@
RUN: llvm-dwp %p/../Inputs/gcc_type/a.dwo -o %t
RUN: llvm-dwarfdump %t | FileCheck %s
RUN: not llvm-dwp %p/../Inputs/gcc_type/a.dwo %p/../Inputs/gcc_type/a.dwo -o %t 2>&1 | FileCheck --check-prefix=DUP %s
CHECK: Type Unit
CHECK: Type Unit
// Check that llvm-dwp can parse DW_FORM_string for CU name
DUP: Duplicate DWO ID ({{.*}}) in 'a.cpp' and 'a.cpp'

View File

@ -231,36 +231,36 @@ static void addAllTypesFromDWP(
static void addAllTypes(MCStreamer &Out,
MapVector<uint64_t, UnitIndexEntry> &TypeIndexEntries,
MCSection *OutputTypes, StringRef Types,
MCSection *OutputTypes,
const std::vector<StringRef> &TypesSections,
const UnitIndexEntry &CUEntry, uint32_t &TypesOffset) {
if (Types.empty())
return;
for (StringRef Types : TypesSections) {
Out.SwitchSection(OutputTypes);
uint32_t Offset = 0;
DataExtractor Data(Types, true, 0);
while (Data.isValidOffset(Offset)) {
UnitIndexEntry Entry = CUEntry;
// Zero out the debug_info contribution
Entry.Contributions[0] = {};
auto &C = Entry.Contributions[DW_SECT_TYPES - DW_SECT_INFO];
C.Offset = TypesOffset;
auto PrevOffset = Offset;
// Length of the unit, including the 4 byte length field.
C.Length = Data.getU32(&Offset) + 4;
Out.SwitchSection(OutputTypes);
uint32_t Offset = 0;
DataExtractor Data(Types, true, 0);
while (Data.isValidOffset(Offset)) {
UnitIndexEntry Entry = CUEntry;
// Zero out the debug_info contribution
Entry.Contributions[0] = {};
auto &C = Entry.Contributions[DW_SECT_TYPES - DW_SECT_INFO];
C.Offset = TypesOffset;
auto PrevOffset = Offset;
// Length of the unit, including the 4 byte length field.
C.Length = Data.getU32(&Offset) + 4;
Data.getU16(&Offset); // Version
Data.getU32(&Offset); // Abbrev offset
Data.getU8(&Offset); // Address size
auto Signature = Data.getU64(&Offset);
Offset = PrevOffset + C.Length;
Data.getU16(&Offset); // Version
Data.getU32(&Offset); // Abbrev offset
Data.getU8(&Offset); // Address size
auto Signature = Data.getU64(&Offset);
Offset = PrevOffset + C.Length;
auto P = TypeIndexEntries.insert(std::make_pair(Signature, Entry));
if (!P.second)
continue;
auto P = TypeIndexEntries.insert(std::make_pair(Signature, Entry));
if (!P.second)
continue;
Out.EmitBytes(Types.substr(PrevOffset, C.Length));
TypesOffset += C.Length;
Out.EmitBytes(Types.substr(PrevOffset, C.Length));
TypesOffset += C.Length;
}
}
}
@ -399,7 +399,7 @@ static std::error_code write(MCStreamer &Out, ArrayRef<std::string> Inputs) {
StringRef CurStrSection;
StringRef CurStrOffsetSection;
StringRef CurTypesSection;
std::vector<StringRef> CurTypesSection;
StringRef InfoSection;
StringRef AbbrevSection;
StringRef CurCUIndexSection;
@ -468,7 +468,7 @@ static std::error_code write(MCStreamer &Out, ArrayRef<std::string> Inputs) {
else if (OutSection == StrSection)
CurStrSection = Contents;
else if (OutSection == TypesSection)
CurTypesSection = Contents;
CurTypesSection.push_back(Contents);
else if (OutSection == CUIndexSection)
CurCUIndexSection = Contents;
else if (OutSection == TUIndexSection)
@ -517,6 +517,7 @@ static std::error_code write(MCStreamer &Out, ArrayRef<std::string> Inputs) {
}
if (!CurTypesSection.empty()) {
assert(CurTypesSection.size() == 1);
if (CurTUIndexSection.empty())
return make_error_code(std::errc::invalid_argument);
DWARFUnitIndex TUIndex(DW_SECT_TYPES);
@ -525,7 +526,7 @@ static std::error_code write(MCStreamer &Out, ArrayRef<std::string> Inputs) {
if (!TUIndex.parse(TUIndexData))
return make_error_code(std::errc::invalid_argument);
addAllTypesFromDWP(Out, TypeIndexEntries, TUIndex, TypesSection,
CurTypesSection, CurEntry,
CurTypesSection.front(), CurEntry,
ContributionOffsets[DW_SECT_TYPES - DW_SECT_INFO]);
}
} else {