diff options
author | David Blaikie <dblaikie@gmail.com> | 2016-02-26 07:30:15 +0000 |
---|---|---|
committer | David Blaikie <dblaikie@gmail.com> | 2016-02-26 07:30:15 +0000 |
commit | f1958da1c33b5f456ec759eb24c2a807071ebc90 (patch) | |
tree | 317117aa1d20fa52ca361e276e41353e22837034 /llvm/tools/llvm-dwp/llvm-dwp.cpp | |
parent | 5d6d4dc3061777393f4d2b830186a2f716c689a0 (diff) | |
download | bcm5719-llvm-f1958da1c33b5f456ec759eb24c2a807071ebc90.tar.gz bcm5719-llvm-f1958da1c33b5f456ec759eb24c2a807071ebc90.zip |
llvm-dwp: provide diagnostics for duplicate DWO IDs
These diagnostics aren't perfect - in the case of merging several dwos
into dwps and those dwps into more dwps - just getting the message about
the original source file name might not be much help (since it's the
same in both dwos, by definition - but doesn't tell you which chain of
dwps to backtrack)
It might be worth adding the DW_AT_dwo_id to the split debug info to
improve the diagnostic experience - might help track down the duplicates
better.
llvm-svn: 261988
Diffstat (limited to 'llvm/tools/llvm-dwp/llvm-dwp.cpp')
-rw-r--r-- | llvm/tools/llvm-dwp/llvm-dwp.cpp | 78 |
1 files changed, 75 insertions, 3 deletions
diff --git a/llvm/tools/llvm-dwp/llvm-dwp.cpp b/llvm/tools/llvm-dwp/llvm-dwp.cpp index 82b7d12fcb1..ceadfb1b9ee 100644 --- a/llvm/tools/llvm-dwp/llvm-dwp.cpp +++ b/llvm/tools/llvm-dwp/llvm-dwp.cpp @@ -24,6 +24,7 @@ #include "llvm/Support/raw_ostream.h" #include "llvm/Target/TargetMachine.h" #include <list> +#include <iostream> #include <memory> #include <system_error> #include <unordered_set> @@ -106,6 +107,43 @@ static uint32_t getCUAbbrev(StringRef Abbrev, uint64_t AbbrCode) { return Offset; } +static const char *getCUName(StringRef Abbrev, StringRef Info, + StringRef StrOffsets, StringRef Str) { + uint32_t Offset = 0; + DataExtractor InfoData(Info, true, 0); + InfoData.getU32(&Offset); // Length + uint16_t Version = InfoData.getU16(&Offset); + InfoData.getU32(&Offset); // Abbrev offset (should be zero) + uint8_t AddrSize = InfoData.getU8(&Offset); + + uint32_t AbbrCode = InfoData.getULEB128(&Offset); + + DataExtractor AbbrevData(Abbrev, true, 0); + uint32_t AbbrevOffset = getCUAbbrev(Abbrev, AbbrCode); + uint64_t Tag = AbbrevData.getULEB128(&AbbrevOffset); + (void)Tag; + // FIXME: Real error handling + assert(Tag == dwarf::DW_TAG_compile_unit); + // DW_CHILDREN + AbbrevData.getU8(&AbbrevOffset); + uint32_t Name; + uint32_t Form; + while ((Name = AbbrevData.getULEB128(&AbbrevOffset)) | + (Form = AbbrevData.getULEB128(&AbbrevOffset)) && + Name != dwarf::DW_AT_name) { + DWARFFormValue::skipValue(Form, InfoData, &Offset, Version, AddrSize); + } + // FIXME: Real error handling + assert(Name == 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); + return StrData.getCStr(&StrOffset); +} + static uint64_t getCUSignature(StringRef Abbrev, StringRef Info) { uint32_t Offset = 0; DataExtractor InfoData(Info, true, 0); @@ -138,8 +176,17 @@ static uint64_t getCUSignature(StringRef Abbrev, StringRef Info) { struct UnitIndexEntry { DWARFUnitIndex::Entry::SectionContribution Contributions[8]; + std::string Name; + StringRef DWPName; }; +StringRef getSubsection(StringRef Section, const DWARFUnitIndex::Entry &Entry, DWARFSectionKind Kind) { + const auto *Off = Entry.getOffset(Kind); + if (!Off) + return StringRef(); + return Section.substr(Off->Offset, Off->Length); +} + static void addAllTypesFromDWP( MCStreamer &Out, MapVector<uint64_t, UnitIndexEntry> &TypeIndexEntries, const DWARFUnitIndex &TUIndex, MCSection *OutputTypes, StringRef Types, @@ -416,8 +463,22 @@ static std::error_code write(MCStreamer &Out, ArrayRef<std::string> Inputs) { continue; auto P = IndexEntries.insert(std::make_pair(E.getSignature(), CurEntry)); - // FIXME: Check P.second and error for duplicate CU signatures + const char* Name = getCUName( + getSubsection(AbbrevSection, E, DW_SECT_ABBREV), + getSubsection(InfoSection, E, DW_SECT_INFO), + 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 '" << Name << "' (from '" << Input << "')\n"; + return make_error_code(std::errc::invalid_argument); + } auto &NewEntry = P.first->second; + NewEntry.Name = Name; + NewEntry.DWPName = Input; for (auto Kind : CUIndex.getColumnKinds()) { auto &C = NewEntry.Contributions[Kind - DW_SECT_INFO]; C.Offset += I->Offset; @@ -439,9 +500,20 @@ static std::error_code write(MCStreamer &Out, ArrayRef<std::string> Inputs) { ContributionOffsets[DW_SECT_TYPES - DW_SECT_INFO]); } } else { - IndexEntries.insert( + auto P = IndexEntries.insert( std::make_pair(getCUSignature(AbbrevSection, InfoSection), CurEntry)); - // FIXME: Check P.second and error for duplicate CU signatures + const char *Name = getCUName(AbbrevSection, InfoSection, + CurStrOffsetSection, CurStrSection); + if (!P.second) { + auto &E = *P.first; + std::cerr << "Duplicate DWO ID (" << E.first << ") in '" << Name + << "' "; + if (!E.second.DWPName.empty()) + std::cerr << "(from '" << E.second.DWPName.str() << "') "; + std::cerr << "and '" << E.second.Name << "'\n"; + return make_error_code(std::errc::invalid_argument); + } + P.first->second.Name = Name; addAllTypes(Out, TypeIndexEntries, TypesSection, CurTypesSection, CurEntry, ContributionOffsets[DW_SECT_TYPES - DW_SECT_INFO]); } |