1 //===------ dwarf2yaml.cpp - obj2yaml conversion tool -----------*- C++ -*-===//
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 "Error.h"
11 #include "llvm/DebugInfo/DWARF/DWARFContext.h"
12 #include "llvm/DebugInfo/DWARF/DWARFDebugArangeSet.h"
13 #include "llvm/ObjectYAML/DWARFYAML.h"
14 
15 using namespace llvm;
16 
17 void dumpDebugAbbrev(DWARFContextInMemory &DCtx, DWARFYAML::Data &Y) {
18   auto AbbrevSetPtr = DCtx.getDebugAbbrev();
19   if (AbbrevSetPtr) {
20     for (auto AbbrvDeclSet : *AbbrevSetPtr) {
21       for (auto AbbrvDecl : AbbrvDeclSet.second) {
22         DWARFYAML::Abbrev Abbrv;
23         Abbrv.Code = AbbrvDecl.getCode();
24         Abbrv.Tag = AbbrvDecl.getTag();
25         Abbrv.Children = AbbrvDecl.hasChildren() ? dwarf::DW_CHILDREN_yes
26                                                  : dwarf::DW_CHILDREN_no;
27         for (auto Attribute : AbbrvDecl.attributes()) {
28           DWARFYAML::AttributeAbbrev AttAbrv;
29           AttAbrv.Attribute = Attribute.Attr;
30           AttAbrv.Form = Attribute.Form;
31           Abbrv.Attributes.push_back(AttAbrv);
32         }
33         Y.AbbrevDecls.push_back(Abbrv);
34       }
35     }
36   }
37 }
38 
39 void dumpDebugStrings(DWARFContextInMemory &DCtx, DWARFYAML::Data &Y) {
40   StringRef RemainingTable = DCtx.getStringSection();
41   while (RemainingTable.size() > 0) {
42     auto SymbolPair = RemainingTable.split('\0');
43     RemainingTable = SymbolPair.second;
44     Y.DebugStrings.push_back(SymbolPair.first);
45   }
46 }
47 
48 void dumpDebugARanges(DWARFContextInMemory &DCtx, DWARFYAML::Data &Y) {
49   DataExtractor ArangesData(DCtx.getARangeSection(), DCtx.isLittleEndian(), 0);
50   uint32_t Offset = 0;
51   DWARFDebugArangeSet Set;
52 
53   while (Set.extract(ArangesData, &Offset)) {
54     DWARFYAML::ARange Range;
55     Range.Length = Set.getHeader().Length;
56     Range.Version = Set.getHeader().Version;
57     Range.CuOffset = Set.getHeader().CuOffset;
58     Range.AddrSize = Set.getHeader().AddrSize;
59     Range.SegSize = Set.getHeader().SegSize;
60     for (auto Descriptor : Set.descriptors()) {
61       DWARFYAML::ARangeDescriptor Desc;
62       Desc.Address = Descriptor.Address;
63       Desc.Length = Descriptor.Length;
64       Range.Descriptors.push_back(Desc);
65     }
66     Y.ARanges.push_back(Range);
67   }
68 }
69 
70 void dumpPubSection(DWARFContextInMemory &DCtx, DWARFYAML::PubSection &Y,
71                     StringRef Section) {
72   DataExtractor PubSectionData(Section, DCtx.isLittleEndian(), 0);
73   uint32_t Offset = 0;
74   Y.Length = PubSectionData.getU32(&Offset);
75   Y.Version = PubSectionData.getU16(&Offset);
76   Y.UnitOffset = PubSectionData.getU32(&Offset);
77   Y.UnitSize = PubSectionData.getU32(&Offset);
78   while (Offset < Y.Length) {
79     DWARFYAML::PubEntry NewEntry;
80     NewEntry.DieOffset = PubSectionData.getU32(&Offset);
81     if (Y.IsGNUStyle)
82       NewEntry.Descriptor = PubSectionData.getU8(&Offset);
83     NewEntry.Name = PubSectionData.getCStr(&Offset);
84     Y.Entries.push_back(NewEntry);
85   }
86 }
87 
88 void dumpDebugPubSections(DWARFContextInMemory &DCtx, DWARFYAML::Data &Y) {
89   Y.PubNames.IsGNUStyle = false;
90   dumpPubSection(DCtx, Y.PubNames, DCtx.getPubNamesSection());
91 
92   Y.PubTypes.IsGNUStyle = false;
93   dumpPubSection(DCtx, Y.PubTypes, DCtx.getPubTypesSection());
94 
95   Y.GNUPubNames.IsGNUStyle = true;
96   dumpPubSection(DCtx, Y.GNUPubNames, DCtx.getGnuPubNamesSection());
97 
98   Y.GNUPubTypes.IsGNUStyle = true;
99   dumpPubSection(DCtx, Y.GNUPubTypes, DCtx.getGnuPubTypesSection());
100 }
101 
102 std::error_code dwarf2yaml(DWARFContextInMemory &DCtx,
103                            DWARFYAML::Data &Y) {
104   dumpDebugAbbrev(DCtx, Y);
105   dumpDebugStrings(DCtx, Y);
106   dumpDebugARanges(DCtx, Y);
107   dumpDebugPubSections(DCtx, Y);
108 
109   return obj2yaml_error::success;
110 }
111