summaryrefslogtreecommitdiffstats
path: root/llvm/tools/llvm-dwp/llvm-dwp.cpp
diff options
context:
space:
mode:
authorDavid Blaikie <dblaikie@gmail.com>2015-12-02 06:21:34 +0000
committerDavid Blaikie <dblaikie@gmail.com>2015-12-02 06:21:34 +0000
commitb073cb9be2bbd9458035f6ce28b8df78a5399b8a (patch)
tree4d99d4ef04bd63995861e9e14f1026e28504bc97 /llvm/tools/llvm-dwp/llvm-dwp.cpp
parent12e7b99ed052e5e2104d36c83f343a0dd7864d1d (diff)
downloadbcm5719-llvm-b073cb9be2bbd9458035f6ce28b8df78a5399b8a.tar.gz
bcm5719-llvm-b073cb9be2bbd9458035f6ce28b8df78a5399b8a.zip
[llvm-dwp] Emit a rather fictional debug_cu_index
This is very rudimentary support for debug_cu_index, but it is enough to allow llvm-dwarfdump to find the offsets for contributions and correctly dump debug_info. It will need to actually find the real signature of the unit and build the real hash table with the right number of buckets, as per the DWP specification. It will also need to be expanded to cover the tu_index as well. llvm-svn: 254489
Diffstat (limited to 'llvm/tools/llvm-dwp/llvm-dwp.cpp')
-rw-r--r--llvm/tools/llvm-dwp/llvm-dwp.cpp103
1 files changed, 81 insertions, 22 deletions
diff --git a/llvm/tools/llvm-dwp/llvm-dwp.cpp b/llvm/tools/llvm-dwp/llvm-dwp.cpp
index 9ce37ec2cee..6617b0b23ae 100644
--- a/llvm/tools/llvm-dwp/llvm-dwp.cpp
+++ b/llvm/tools/llvm-dwp/llvm-dwp.cpp
@@ -17,6 +17,7 @@
#include "llvm/Support/raw_ostream.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Support/TargetSelect.h"
+#include "llvm/DebugInfo/DWARF/DWARFUnitIndex.h"
#include <memory>
#include <list>
#include <unordered_set>
@@ -85,48 +86,106 @@ static std::error_code write(MCStreamer &Out, ArrayRef<std::string> Inputs) {
const auto &MCOFI = *Out.getContext().getObjectFileInfo();
MCSection *const StrSection = MCOFI.getDwarfStrDWOSection();
MCSection *const StrOffsetSection = MCOFI.getDwarfStrOffDWOSection();
- const StringMap<MCSection *> KnownSections = {
- {"debug_info.dwo", MCOFI.getDwarfInfoDWOSection()},
- {"debug_types.dwo", MCOFI.getDwarfTypesDWOSection()},
- {"debug_str_offsets.dwo", StrOffsetSection},
- {"debug_str.dwo", StrSection},
- {"debug_loc.dwo", MCOFI.getDwarfLocDWOSection()},
- {"debug_abbrev.dwo", MCOFI.getDwarfAbbrevDWOSection()}};
+ const StringMap<std::pair<MCSection *, DWARFSectionKind>> KnownSections = {
+ {"debug_info.dwo", {MCOFI.getDwarfInfoDWOSection(), DW_SECT_INFO}},
+ {"debug_types.dwo", {MCOFI.getDwarfTypesDWOSection(), DW_SECT_TYPES}},
+ {"debug_str_offsets.dwo", {StrOffsetSection, DW_SECT_STR_OFFSETS}},
+ {"debug_str.dwo", {StrSection, static_cast<DWARFSectionKind>(0)}},
+ {"debug_loc.dwo", {MCOFI.getDwarfLocDWOSection(), DW_SECT_LOC}},
+ {"debug_abbrev.dwo", {MCOFI.getDwarfAbbrevDWOSection(), DW_SECT_ABBREV}}};
+
+ struct UnitIndexEntry {
+ uint64_t Signature;
+ DWARFUnitIndex::Entry::SectionContribution Contributions[8];
+ };
+
+ std::vector<UnitIndexEntry> IndexEntries;
StringMap<uint32_t> Strings;
uint32_t StringOffset = 0;
+ uint64_t UnitIndex = 0;
+ uint32_t ContributionOffsets[8] = {};
+
for (const auto &Input : Inputs) {
auto ErrOrObj = object::ObjectFile::createObjectFile(Input);
if (!ErrOrObj)
return ErrOrObj.getError();
- const auto *Obj = ErrOrObj->getBinary();
+
+ IndexEntries.emplace_back();
+ UnitIndexEntry &CurEntry = IndexEntries.back();
+ CurEntry.Signature = UnitIndex++;
+
StringRef CurStrSection;
StringRef CurStrOffsetSection;
- for (const auto &Section : Obj->sections()) {
+
+ for (const auto &Section : ErrOrObj->getBinary()->sections()) {
StringRef Name;
if (std::error_code Err = Section.getName(Name))
return Err;
- if (MCSection *OutSection =
- KnownSections.lookup(Name.substr(Name.find_first_not_of("._")))) {
- StringRef Contents;
- if (auto Err = Section.getContents(Contents))
- return Err;
- if (OutSection == StrOffsetSection)
- CurStrOffsetSection = Contents;
- else if (OutSection == StrSection)
- CurStrSection = Contents;
- else {
- Out.SwitchSection(OutSection);
- Out.EmitBytes(Contents);
- }
+
+ auto SectionPair =
+ KnownSections.find(Name.substr(Name.find_first_not_of("._")));
+ if (SectionPair == KnownSections.end())
+ continue;
+
+ StringRef Contents;
+ if (auto Err = Section.getContents(Contents))
+ return Err;
+
+ if (DWARFSectionKind Kind = SectionPair->second.second) {
+ auto Index = Kind - DW_SECT_INFO;
+ CurEntry.Contributions[Index].Offset = ContributionOffsets[Index];
+ ContributionOffsets[Index] +=
+ (CurEntry.Contributions[Index].Length = Contents.size());
+ }
+
+ MCSection *OutSection = SectionPair->second.first;
+ if (OutSection == StrOffsetSection)
+ CurStrOffsetSection = Contents;
+ else if (OutSection == StrSection)
+ CurStrSection = Contents;
+ else {
+ Out.SwitchSection(OutSection);
+ Out.EmitBytes(Contents);
}
}
+
if (auto Err = writeStringsAndOffsets(Out, Strings, StringOffset,
StrSection, StrOffsetSection,
CurStrSection, CurStrOffsetSection))
return Err;
}
+
+ Out.SwitchSection(MCOFI.getDwarfCUIndexSection());
+ Out.EmitIntValue(2, 4); // Version
+ Out.EmitIntValue(8, 4); // Columns
+ Out.EmitIntValue(IndexEntries.size(), 4); // Num Units
+ // FIXME: This is not the right number of buckets for a real hash.
+ Out.EmitIntValue(IndexEntries.size(), 4); // Num Buckets
+
+ // Write the signatures.
+ for (const auto &E : IndexEntries)
+ Out.EmitIntValue(E.Signature, 8);
+
+ // Write the indexes.
+ for (size_t i = 0; i != IndexEntries.size(); ++i)
+ Out.EmitIntValue(i + 1, 4);
+
+ // Write the column headers (which sections will appear in the table)
+ for (size_t i = 1; i != 9; ++i)
+ Out.EmitIntValue(i, 4);
+
+ // Write the offsets.
+ for (const auto &E : IndexEntries)
+ for (const auto &C : E.Contributions)
+ Out.EmitIntValue(C.Offset, 4);
+
+ // Write the lengths.
+ for (const auto &E : IndexEntries)
+ for (const auto &C : E.Contributions)
+ Out.EmitIntValue(C.Length, 4);
+
return std::error_code();
}
OpenPOWER on IntegriCloud