Index: llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFDebugPubTable.h =================================================================== --- llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFDebugPubTable.h +++ llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFDebugPubTable.h @@ -0,0 +1,77 @@ +//===-- 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/ADT/ArrayRef.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 Entries; + }; + +private: + std::vector Sets; + + /// gnu styled tables contains additional information. + /// This flag determines whether or not section we parse is debug_gnu* table. + bool GnuStyle; + +public: + DWARFDebugPubTable(StringRef Data, bool LittleEndian, bool GnuStyle); + void dump(StringRef Name, raw_ostream &OS) const; + + ArrayRef getData() { return Sets; } +}; +} + +#endif Index: llvm/trunk/lib/DebugInfo/DWARF/CMakeLists.txt =================================================================== --- llvm/trunk/lib/DebugInfo/DWARF/CMakeLists.txt +++ llvm/trunk/lib/DebugInfo/DWARF/CMakeLists.txt @@ -11,6 +11,7 @@ DWARFDebugLine.cpp DWARFDebugLoc.cpp DWARFDebugMacro.cpp + DWARFDebugPubTable.cpp DWARFDebugRangeList.cpp DWARFDie.cpp DWARFFormValue.cpp Index: llvm/trunk/lib/DebugInfo/DWARF/DWARFContext.cpp =================================================================== --- llvm/trunk/lib/DebugInfo/DWARF/DWARFContext.cpp +++ llvm/trunk/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: llvm/trunk/lib/DebugInfo/DWARF/DWARFDebugPubTable.cpp =================================================================== --- llvm/trunk/lib/DebugInfo/DWARF/DWARFDebugPubTable.cpp +++ llvm/trunk/lib/DebugInfo/DWARF/DWARFDebugPubTable.cpp @@ -0,0 +1,65 @@ +//===-- 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 = GnuStyle ? PubNames.getU8(&Offset) : 0; + const char *Name = PubNames.getCStr(&Offset); + SetData.Entries.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'; + OS << (GnuStyle ? "Offset Linkage Kind Name\n" + : "Offset Name\n"); + + for (const Entry &E : S.Entries) { + OS << format("0x%8.8x ", E.SecOffset); + if (GnuStyle) { + StringRef EntryLinkage = + dwarf::GDBIndexEntryLinkageString(E.Descriptor.Linkage); + StringRef EntryKind = dwarf::GDBIndexEntryKindString(E.Descriptor.Kind); + OS << format("%-8s", EntryLinkage.data()) << ' ' + << format("%-8s", EntryKind.data()) << ' '; + } + OS << '\"' << E.Name << "\"\n"; + } + } +}