Index: include/llvm/DebugInfo/DWARF/DWARFDebugPubTable.h =================================================================== --- include/llvm/DebugInfo/DWARF/DWARFDebugPubTable.h +++ include/llvm/DebugInfo/DWARF/DWARFDebugPubTable.h @@ -0,0 +1,79 @@ +//===-- DWARFDebugPubTable.h ------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIB_DEBUGINFO_DWARFDEBUGPUBTABLE_H +#define LLVM_LIB_DEBUGINFO_DWARFDEBUGPUBTABLE_H + +#include "llvm/ADT/iterator_range.h" +#include "llvm/Support/DataExtractor.h" +#include "llvm/Support/Dwarf.h" +#include + +namespace llvm { + +class raw_ostream; + +// Represents structure for holding and parsing .debug_pub* tables. +class DWARFDebugPubTable { +public: + struct Entry { + // Section offset from the beginning of the compilation unit. + uint32_t SecOffset; + + // An entry of the various gnu_pub* debug sections. + llvm::dwarf::PubIndexEntryDescriptor Descriptor; + + // The name of the object as given by the DW_AT_name attribute of the + // referenced DIE. + const char *Name; + }; + + // Each table consists of sets of variable length entries. Each set describes + // the names of global objects and functions, or global types, respectively, + // whose definitions are represented by debugging information entries owned by + // a single compilation unit. + struct Set { + // The total length of the entries for that set, not including the length + // field itself. + uint32_t Length; + + // This number is specific to the name lookup table and is independent of + // the DWARF version number. + uint16_t Version; + + // The offset from the beginning of the .debug_info section of the + // compilation unit header referenced by the set. + uint32_t Offset; + + // The size in bytes of the contents of the .debug_info section generated to + // represent that compilation unit. + uint32_t Size; + + std::vector Entires; + }; + +private: + typedef std::vector SetColl; + typedef iterator_range entry_iterator_range; + + SetColl Sets; + + bool GnuStyle; + +public: + DWARFDebugPubTable(StringRef Data, bool LittleEndian, bool GnuStyle); + void dump(StringRef Name, raw_ostream &OS) const; + + entry_iterator_range entries() const { + return entry_iterator_range(Sets.begin(), Sets.end()); + } +}; +} + +#endif Index: lib/DebugInfo/DWARF/CMakeLists.txt =================================================================== --- lib/DebugInfo/DWARF/CMakeLists.txt +++ lib/DebugInfo/DWARF/CMakeLists.txt @@ -11,6 +11,7 @@ DWARFDebugLine.cpp DWARFDebugLoc.cpp DWARFDebugMacro.cpp + DWARFDebugPubTable.cpp DWARFDebugRangeList.cpp DWARFDie.cpp DWARFFormValue.cpp Index: lib/DebugInfo/DWARF/DWARFContext.cpp =================================================================== --- lib/DebugInfo/DWARF/DWARFContext.cpp +++ lib/DebugInfo/DWARF/DWARFContext.cpp @@ -12,6 +12,7 @@ #include "llvm/ADT/StringSwitch.h" #include "llvm/DebugInfo/DWARF/DWARFAcceleratorTable.h" #include "llvm/DebugInfo/DWARF/DWARFDebugArangeSet.h" +#include "llvm/DebugInfo/DWARF/DWARFDebugPubTable.h" #include "llvm/DebugInfo/DWARF/DWARFUnitIndex.h" #include "llvm/Object/MachO.h" #include "llvm/Object/RelocVisitor.h" @@ -32,39 +33,6 @@ typedef DILineInfoSpecifier::FileLineInfoKind FileLineInfoKind; typedef DILineInfoSpecifier::FunctionNameKind FunctionNameKind; -static void dumpPubSection(raw_ostream &OS, StringRef Name, StringRef Data, - bool LittleEndian, bool GnuStyle) { - OS << "\n." << Name << " contents:\n"; - DataExtractor pubNames(Data, LittleEndian, 0); - uint32_t offset = 0; - while (pubNames.isValidOffset(offset)) { - OS << "length = " << format("0x%08x", pubNames.getU32(&offset)); - OS << " version = " << format("0x%04x", pubNames.getU16(&offset)); - OS << " unit_offset = " << format("0x%08x", pubNames.getU32(&offset)); - OS << " unit_size = " << format("0x%08x", pubNames.getU32(&offset)) << '\n'; - if (GnuStyle) - OS << "Offset Linkage Kind Name\n"; - else - OS << "Offset Name\n"; - - while (offset < Data.size()) { - uint32_t dieRef = pubNames.getU32(&offset); - if (dieRef == 0) - break; - OS << format("0x%8.8x ", dieRef); - if (GnuStyle) { - PubIndexEntryDescriptor desc(pubNames.getU8(&offset)); - OS << format("%-8s", - dwarf::GDBIndexEntryLinkageString(desc.Linkage).data()) - << ' ' - << format("%-8s", dwarf::GDBIndexEntryKindString(desc.Kind).data()) - << ' '; - } - OS << '\"' << pubNames.getCStr(&offset) << "\"\n"; - } - } -} - static void dumpAccelSection(raw_ostream &OS, StringRef Name, const DWARFSection& Section, StringRef StringSection, bool LittleEndian) { @@ -231,20 +199,22 @@ } if (DumpType == DIDT_All || DumpType == DIDT_Pubnames) - dumpPubSection(OS, "debug_pubnames", getPubNamesSection(), - isLittleEndian(), false); + DWARFDebugPubTable(getPubNamesSection(), isLittleEndian(), false) + .dump("debug_pubnames", OS); if (DumpType == DIDT_All || DumpType == DIDT_Pubtypes) - dumpPubSection(OS, "debug_pubtypes", getPubTypesSection(), - isLittleEndian(), false); + DWARFDebugPubTable(getPubTypesSection(), isLittleEndian(), false) + .dump("debug_pubtypes", OS); if (DumpType == DIDT_All || DumpType == DIDT_GnuPubnames) - dumpPubSection(OS, "debug_gnu_pubnames", getGnuPubNamesSection(), - isLittleEndian(), true /* GnuStyle */); + DWARFDebugPubTable(getGnuPubNamesSection(), isLittleEndian(), + true /* GnuStyle */) + .dump("debug_gnu_pubnames", OS); if (DumpType == DIDT_All || DumpType == DIDT_GnuPubtypes) - dumpPubSection(OS, "debug_gnu_pubtypes", getGnuPubTypesSection(), - isLittleEndian(), true /* GnuStyle */); + DWARFDebugPubTable(getGnuPubTypesSection(), isLittleEndian(), + true /* GnuStyle */) + .dump("debug_gnu_pubtypes", OS); if ((DumpType == DIDT_All || DumpType == DIDT_StrOffsetsDwo) && !getStringOffsetDWOSection().empty()) { Index: lib/DebugInfo/DWARF/DWARFDebugPubTable.cpp =================================================================== --- lib/DebugInfo/DWARF/DWARFDebugPubTable.cpp +++ lib/DebugInfo/DWARF/DWARFDebugPubTable.cpp @@ -0,0 +1,70 @@ +//===-- DWARFDebugPubTable.cpp ---------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "llvm/DebugInfo/DWARF/DWARFDebugPubTable.h" +#include "llvm/Support/Format.h" +#include "llvm/Support/raw_ostream.h" + +using namespace llvm; +using namespace llvm::dwarf; + +DWARFDebugPubTable::DWARFDebugPubTable(StringRef Data, bool LittleEndian, + bool GnuStyle) + : GnuStyle(GnuStyle) { + DataExtractor PubNames(Data, LittleEndian, 0); + uint32_t Offset = 0; + while (PubNames.isValidOffset(Offset)) { + Sets.push_back({}); + Set &SetData = Sets.back(); + + SetData.Length = PubNames.getU32(&Offset); + SetData.Version = PubNames.getU16(&Offset); + SetData.Offset = PubNames.getU32(&Offset); + SetData.Size = PubNames.getU32(&Offset); + + while (Offset < Data.size()) { + uint32_t DieRef = PubNames.getU32(&Offset); + if (DieRef == 0) + break; + uint8_t IndexEntryValue = 0; + if (GnuStyle) + IndexEntryValue = PubNames.getU8(&Offset); + const char *Name = PubNames.getCStr(&Offset); + SetData.Entires.push_back( + {DieRef, PubIndexEntryDescriptor(IndexEntryValue), Name}); + } + } +} + +void DWARFDebugPubTable::dump(StringRef Name, raw_ostream &OS) const { + OS << "\n." << Name << " contents: a\n"; + for (const Set &S : Sets) { + OS << "length = " << format("0x%08x", S.Length); + OS << " version = " << format("0x%04x", S.Version); + OS << " unit_offset = " << format("0x%08x", S.Offset); + OS << " unit_size = " << format("0x%08x", S.Size) << '\n'; + if (GnuStyle) + OS << "Offset Linkage Kind Name\n"; + else + OS << "Offset Name\n"; + + for (const Entry &E : S.Entires) { + OS << format("0x%8.8x ", E.SecOffset); + if (GnuStyle) + OS << format("%-8s", + dwarf::GDBIndexEntryLinkageString(E.Descriptor.Linkage) + .data()) + << ' ' + << format("%-8s", + dwarf::GDBIndexEntryKindString(E.Descriptor.Kind).data()) + << ' '; + OS << '\"' << E.Name << "\"\n"; + } + } +}