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 = DW_TAG_null;
20   HasChildren = false;
21   AttributeSpecs.clear();
22 }
23 
24 DWARFAbbreviationDeclaration::DWARFAbbreviationDeclaration() {
25   clear();
26 }
27 
28 bool
29 DWARFAbbreviationDeclaration::extract(DataExtractor Data,
30                                       uint32_t* OffsetPtr) {
31   clear();
32   Code = Data.getULEB128(OffsetPtr);
33   if (Code == 0) {
34     return false;
35   }
36   Tag = static_cast<llvm::dwarf::Tag>(Data.getULEB128(OffsetPtr));
37   if (Tag == DW_TAG_null) {
38     clear();
39     return false;
40   }
41   uint8_t ChildrenByte = Data.getU8(OffsetPtr);
42   HasChildren = (ChildrenByte == DW_CHILDREN_yes);
43 
44   while (true) {
45     auto A = static_cast<Attribute>(Data.getULEB128(OffsetPtr));
46     auto F = static_cast<Form>(Data.getULEB128(OffsetPtr));
47     if (A && F) {
48         AttributeSpecs.push_back(AttributeSpec(A, F));
49     } else if (A == 0 && F == 0) {
50       // We successfully reached the end of this abbreviation declaration
51       // since both attribute and form are zero.
52       break;
53     } else {
54       // Attribute and form pairs must either both be non-zero, in which case
55       // they are added to the abbreviation declaration, or both be zero to
56       // terminate the abbrevation declaration. In this case only one was
57       // zero which is an error.
58       clear();
59       return false;
60     }
61   }
62   return true;
63 }
64 
65 void DWARFAbbreviationDeclaration::dump(raw_ostream &OS) const {
66   auto tagString = TagString(getTag());
67   OS << '[' << getCode() << "] ";
68   if (!tagString.empty())
69     OS << tagString;
70   else
71     OS << format("DW_TAG_Unknown_%x", getTag());
72   OS << "\tDW_CHILDREN_" << (hasChildren() ? "yes" : "no") << '\n';
73   for (const AttributeSpec &Spec : AttributeSpecs) {
74     OS << '\t';
75     auto attrString = AttributeString(Spec.Attr);
76     if (!attrString.empty())
77       OS << attrString;
78     else
79       OS << format("DW_AT_Unknown_%x", Spec.Attr);
80     OS << '\t';
81     auto formString = FormEncodingString(Spec.Form);
82     if (!formString.empty())
83       OS << formString;
84     else
85       OS << format("DW_FORM_Unknown_%x", Spec.Form);
86     OS << '\n';
87   }
88   OS << '\n';
89 }
90 
91 uint32_t
92 DWARFAbbreviationDeclaration::findAttributeIndex(dwarf::Attribute attr) const {
93   for (uint32_t i = 0, e = AttributeSpecs.size(); i != e; ++i) {
94     if (AttributeSpecs[i].Attr == attr)
95       return i;
96   }
97   return -1U;
98 }
99