summaryrefslogtreecommitdiff
path: root/tools/llvm-dwp
diff options
context:
space:
mode:
authorDavid Blaikie <dblaikie@gmail.com>2016-02-17 07:00:24 +0000
committerDavid Blaikie <dblaikie@gmail.com>2016-02-17 07:00:24 +0000
commit11dc371299195999d396f43ed1d2b388757a64a1 (patch)
tree27655dbdf27c5b8a86f8404ff604a56ce5cb085f /tools/llvm-dwp
parent2697fc56882e9817b133e25ddcf01e347798bc33 (diff)
llvm-dwp: Support for type units when merging DWPs into larger DWPs
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@261072 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'tools/llvm-dwp')
-rw-r--r--tools/llvm-dwp/llvm-dwp.cpp56
1 files changed, 54 insertions, 2 deletions
diff --git a/tools/llvm-dwp/llvm-dwp.cpp b/tools/llvm-dwp/llvm-dwp.cpp
index 47fbe1c7db4..02fcc151c05 100644
--- a/tools/llvm-dwp/llvm-dwp.cpp
+++ b/tools/llvm-dwp/llvm-dwp.cpp
@@ -139,6 +139,41 @@ struct UnitIndexEntry {
DWARFUnitIndex::Entry::SectionContribution Contributions[8];
};
+static void addAllTypesFromDWP(MCStreamer &Out,
+ std::vector<UnitIndexEntry> &TypeIndexEntries,
+ const DWARFUnitIndex &TUIndex,
+ MCSection *OutputTypes, StringRef Types,
+ const UnitIndexEntry &TUEntry,
+ uint32_t &TypesOffset) {
+ Out.SwitchSection(OutputTypes);
+ for (const DWARFUnitIndex::Entry &E : TUIndex.getRows()) {
+ auto *I = E.getOffsets();
+ if (!I)
+ continue;
+ if (any_of(TypeIndexEntries, [&](const UnitIndexEntry &OldEntry) {
+ return OldEntry.Signature == E.getSignature();
+ }))
+ continue;
+ auto Entry = TUEntry;
+ Entry.Signature = E.getSignature();
+ // Zero out the debug_info contribution
+ Entry.Contributions[0] = {};
+ for (auto Kind : TUIndex.getColumnKinds()) {
+ auto &C = Entry.Contributions[Kind - DW_SECT_INFO];
+ C.Offset += I->Offset;
+ C.Length = I->Length;
+ ++I;
+ }
+ auto &C = Entry.Contributions[DW_SECT_TYPES - DW_SECT_INFO];
+ Out.EmitBytes(Types.substr(
+ C.Offset - TUEntry.Contributions[DW_SECT_TYPES - DW_SECT_INFO].Offset,
+ C.Length));
+ C.Offset = TypesOffset;
+ TypesOffset += C.Length;
+ TypeIndexEntries.push_back(Entry);
+ }
+}
+
static void addAllTypes(MCStreamer &Out,
std::vector<UnitIndexEntry> &TypeIndexEntries,
MCSection *OutputTypes, StringRef Types,
@@ -241,6 +276,7 @@ static std::error_code write(MCStreamer &Out, ArrayRef<std::string> Inputs) {
MCSection *const StrOffsetSection = MCOFI.getDwarfStrOffDWOSection();
MCSection *const TypesSection = MCOFI.getDwarfTypesDWOSection();
MCSection *const CUIndexSection = MCOFI.getDwarfCUIndexSection();
+ MCSection *const TUIndexSection = MCOFI.getDwarfTUIndexSection();
const StringMap<std::pair<MCSection *, DWARFSectionKind>> KnownSections = {
{"debug_info.dwo", {MCOFI.getDwarfInfoDWOSection(), DW_SECT_INFO}},
{"debug_types.dwo", {MCOFI.getDwarfTypesDWOSection(), DW_SECT_TYPES}},
@@ -249,8 +285,8 @@ static std::error_code write(MCStreamer &Out, ArrayRef<std::string> Inputs) {
{"debug_loc.dwo", {MCOFI.getDwarfLocDWOSection(), DW_SECT_LOC}},
{"debug_line.dwo", {MCOFI.getDwarfLineDWOSection(), DW_SECT_LINE}},
{"debug_abbrev.dwo", {MCOFI.getDwarfAbbrevDWOSection(), DW_SECT_ABBREV}},
- {"debug_cu_index",
- {MCOFI.getDwarfCUIndexSection(), static_cast<DWARFSectionKind>(0)}}};
+ {"debug_cu_index", {CUIndexSection, static_cast<DWARFSectionKind>(0)}},
+ {"debug_tu_index", {TUIndexSection, static_cast<DWARFSectionKind>(0)}}};
std::vector<UnitIndexEntry> IndexEntries;
std::vector<UnitIndexEntry> TypeIndexEntries;
@@ -273,6 +309,7 @@ static std::error_code write(MCStreamer &Out, ArrayRef<std::string> Inputs) {
StringRef InfoSection;
StringRef AbbrevSection;
StringRef CurCUIndexSection;
+ StringRef CurTUIndexSection;
for (const auto &Section : ErrOrObj->getBinary()->sections()) {
StringRef Name;
@@ -317,6 +354,8 @@ static std::error_code write(MCStreamer &Out, ArrayRef<std::string> Inputs) {
CurTypesSection = Contents;
else if (OutSection == CUIndexSection)
CurCUIndexSection = Contents;
+ else if (OutSection == TUIndexSection)
+ CurTUIndexSection = Contents;
else {
Out.SwitchSection(OutSection);
Out.EmitBytes(Contents);
@@ -346,6 +385,19 @@ static std::error_code write(MCStreamer &Out, ArrayRef<std::string> Inputs) {
}
IndexEntries.push_back(NewEntry);
}
+
+ if (!CurTypesSection.empty()) {
+ if (CurTUIndexSection.empty())
+ return make_error_code(std::errc::invalid_argument);
+ DWARFUnitIndex TUIndex(DW_SECT_TYPES);
+ DataExtractor TUIndexData(CurTUIndexSection,
+ ErrOrObj->getBinary()->isLittleEndian(), 0);
+ if (!TUIndex.parse(TUIndexData))
+ return make_error_code(std::errc::invalid_argument);
+ addAllTypesFromDWP(Out, TypeIndexEntries, TUIndex, TypesSection,
+ CurTypesSection, CurEntry,
+ ContributionOffsets[DW_SECT_TYPES - DW_SECT_INFO]);
+ }
} else {
CurEntry.Signature = getCUSignature(AbbrevSection, InfoSection);
addAllTypes(Out, TypeIndexEntries, TypesSection, CurTypesSection,