dwarfdump: Use the index to find the right abbrev offset in DWP files
[oota-llvm.git] / lib / DebugInfo / DWARF / DWARFAbbreviationDeclaration.cpp
1 //===-- DWARFAbbreviationDeclaration.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/DWARFAbbreviationDeclaration.h"
11 #include "llvm/Support/Dwarf.h"
12 #include "llvm/Support/Format.h"
13 #include "llvm/Support/raw_ostream.h"
14 using namespace llvm;
15 using namespace dwarf;
16
17 void DWARFAbbreviationDeclaration::clear() {
18   Code = 0;
19   Tag = 0;
20   HasChildren = false;
21   AttributeSpecs.clear();
22 }
23
24 DWARFAbbreviationDeclaration::DWARFAbbreviationDeclaration() {
25   clear();
26 }
27
28 bool
29 DWARFAbbreviationDeclaration::extract(DataExtractor Data, uint32_t* OffsetPtr) {
30   clear();
31   Code = Data.getULEB128(OffsetPtr);
32   if (Code == 0) {
33     return false;
34   }
35   Tag = Data.getULEB128(OffsetPtr);
36   uint8_t ChildrenByte = Data.getU8(OffsetPtr);
37   HasChildren = (ChildrenByte == DW_CHILDREN_yes);
38
39   while (true) {
40     uint32_t CurOffset = *OffsetPtr;
41     uint16_t Attr = Data.getULEB128(OffsetPtr);
42     if (CurOffset == *OffsetPtr) {
43       clear();
44       return false;
45     }
46     CurOffset = *OffsetPtr;
47     uint16_t Form = Data.getULEB128(OffsetPtr);
48     if (CurOffset == *OffsetPtr) {
49       clear();
50       return false;
51     }
52     if (Attr == 0 && Form == 0)
53       break;
54     AttributeSpecs.push_back(AttributeSpec(Attr, Form));
55   }
56
57   if (Tag == 0) {
58     clear();
59     return false;
60   }
61   return true;
62 }
63
64 void DWARFAbbreviationDeclaration::dump(raw_ostream &OS) const {
65   const char *tagString = TagString(getTag());
66   OS << '[' << getCode() << "] ";
67   if (tagString)
68     OS << tagString;
69   else
70     OS << format("DW_TAG_Unknown_%x", getTag());
71   OS << "\tDW_CHILDREN_" << (hasChildren() ? "yes" : "no") << '\n';
72   for (const AttributeSpec &Spec : AttributeSpecs) {
73     OS << '\t';
74     const char *attrString = AttributeString(Spec.Attr);
75     if (attrString)
76       OS << attrString;
77     else
78       OS << format("DW_AT_Unknown_%x", Spec.Attr);
79     OS << '\t';
80     const char *formString = FormEncodingString(Spec.Form);
81     if (formString)
82       OS << formString;
83     else
84       OS << format("DW_FORM_Unknown_%x", Spec.Form);
85     OS << '\n';
86   }
87   OS << '\n';
88 }
89
90 uint32_t
91 DWARFAbbreviationDeclaration::findAttributeIndex(uint16_t attr) const {
92   for (uint32_t i = 0, e = AttributeSpecs.size(); i != e; ++i) {
93     if (AttributeSpecs[i].Attr == attr)
94       return i;
95   }
96   return -1U;
97 }