1 //===- DWARFDebugPubTable.cpp ---------------------------------------------===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 
10 #include "llvm/DebugInfo/DWARF/DWARFDebugPubTable.h"
11 #include "llvm/DebugInfo/DWARF/DWARFDataExtractor.h"
12 #include "llvm/ADT/StringRef.h"
13 #include "llvm/BinaryFormat/Dwarf.h"
14 #include "llvm/Support/DataExtractor.h"
15 #include "llvm/Support/Format.h"
16 #include "llvm/Support/raw_ostream.h"
17 #include <cstdint>
18 
19 using namespace llvm;
20 using namespace dwarf;
21 
DWARFDebugPubTable(const DWARFObject & Obj,const DWARFSection & Sec,bool LittleEndian,bool GnuStyle)22 DWARFDebugPubTable::DWARFDebugPubTable(const DWARFObject &Obj,
23                                        const DWARFSection &Sec,
24                                        bool LittleEndian, bool GnuStyle)
25     : GnuStyle(GnuStyle) {
26   DWARFDataExtractor PubNames(Obj, Sec, LittleEndian, 0);
27   uint32_t Offset = 0;
28   while (PubNames.isValidOffset(Offset)) {
29     Sets.push_back({});
30     Set &SetData = Sets.back();
31 
32     SetData.Length = PubNames.getU32(&Offset);
33     SetData.Version = PubNames.getU16(&Offset);
34     SetData.Offset = PubNames.getRelocatedValue(4, &Offset);
35     SetData.Size = PubNames.getU32(&Offset);
36 
37     while (Offset < Sec.Data.size()) {
38       uint32_t DieRef = PubNames.getU32(&Offset);
39       if (DieRef == 0)
40         break;
41       uint8_t IndexEntryValue = GnuStyle ? PubNames.getU8(&Offset) : 0;
42       StringRef Name = PubNames.getCStrRef(&Offset);
43       SetData.Entries.push_back(
44           {DieRef, PubIndexEntryDescriptor(IndexEntryValue), Name});
45     }
46   }
47 }
48 
dump(raw_ostream & OS) const49 void DWARFDebugPubTable::dump(raw_ostream &OS) const {
50   for (const Set &S : Sets) {
51     OS << "length = " << format("0x%08x", S.Length);
52     OS << " version = " << format("0x%04x", S.Version);
53     OS << " unit_offset = " << format("0x%08x", S.Offset);
54     OS << " unit_size = " << format("0x%08x", S.Size) << '\n';
55     OS << (GnuStyle ? "Offset     Linkage  Kind     Name\n"
56                     : "Offset     Name\n");
57 
58     for (const Entry &E : S.Entries) {
59       OS << format("0x%8.8x ", E.SecOffset);
60       if (GnuStyle) {
61         StringRef EntryLinkage =
62             GDBIndexEntryLinkageString(E.Descriptor.Linkage);
63         StringRef EntryKind = dwarf::GDBIndexEntryKindString(E.Descriptor.Kind);
64         OS << format("%-8s", EntryLinkage.data()) << ' '
65            << format("%-8s", EntryKind.data()) << ' ';
66       }
67       OS << '\"' << E.Name << "\"\n";
68     }
69   }
70 }
71