1//===-- DWARFAbbreviationDeclaration.cpp ------------------------*- 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 "DWARFAbbreviationDeclaration.h" 11 12#include "lldb/Core/dwarf.h" 13 14#include "DWARFFormValue.h" 15 16using namespace lldb_private; 17 18DWARFAbbreviationDeclaration::DWARFAbbreviationDeclaration() : 19 m_code (InvalidCode), 20 m_tag (0), 21 m_has_children (0), 22 m_attributes() 23{ 24} 25 26DWARFAbbreviationDeclaration::DWARFAbbreviationDeclaration(dw_tag_t tag, uint8_t has_children) : 27 m_code (InvalidCode), 28 m_tag (tag), 29 m_has_children (has_children), 30 m_attributes() 31{ 32} 33 34bool 35DWARFAbbreviationDeclaration::Extract(const DataExtractor& data, lldb::offset_t* offset_ptr) 36{ 37 return Extract(data, offset_ptr, data.GetULEB128(offset_ptr)); 38} 39 40bool 41DWARFAbbreviationDeclaration::Extract(const DataExtractor& data, lldb::offset_t *offset_ptr, dw_uleb128_t code) 42{ 43 m_code = code; 44 m_attributes.clear(); 45 if (m_code) 46 { 47 m_tag = data.GetULEB128(offset_ptr); 48 m_has_children = data.GetU8(offset_ptr); 49 50 while (data.ValidOffset(*offset_ptr)) 51 { 52 dw_attr_t attr = data.GetULEB128(offset_ptr); 53 dw_form_t form = data.GetULEB128(offset_ptr); 54 55 if (attr && form) 56 m_attributes.push_back(DWARFAttribute(attr, form)); 57 else 58 break; 59 } 60 61 return m_tag != 0; 62 } 63 else 64 { 65 m_tag = 0; 66 m_has_children = 0; 67 } 68 69 return false; 70} 71 72 73void 74DWARFAbbreviationDeclaration::Dump(Stream *s) const 75{ 76// *ostrm_ptr << std::setfill(' ') << std::dec << '[' << std::setw(3) << std::right << m_code << ']' << ' ' << std::setw(30) << std::left << DW_TAG_value_to_name(m_tag) << DW_CHILDREN_value_to_name(m_has_children) << std::endl; 77// 78// DWARFAttribute::const_iterator pos; 79// 80// for (pos = m_attributes.begin(); pos != m_attributes.end(); ++pos) 81// *ostrm_ptr << " " << std::setw(29) << std::left << DW_AT_value_to_name(pos->attr()) << ' ' << DW_FORM_value_to_name(pos->form()) << std::endl; 82// 83// *ostrm_ptr << std::endl; 84} 85 86 87 88bool 89DWARFAbbreviationDeclaration::IsValid() 90{ 91 return m_code != 0 && m_tag != 0; 92} 93 94 95void 96DWARFAbbreviationDeclaration::CopyExcludingAddressAttributes(const DWARFAbbreviationDeclaration& abbr_decl, const uint32_t idx) 97{ 98 m_code = abbr_decl.Code(); // Invalidate the code since that can't be copied safely. 99 m_tag = abbr_decl.Tag(); 100 m_has_children = abbr_decl.HasChildren(); 101 102 const DWARFAttribute::collection& attributes = abbr_decl.Attributes(); 103 const uint32_t num_abbr_decl_attributes = attributes.size(); 104 105 dw_attr_t attr; 106 dw_form_t form; 107 uint32_t i; 108 109 for (i = 0; i < num_abbr_decl_attributes; ++i) 110 { 111 attributes[i].get(attr, form); 112 switch (attr) 113 { 114 case DW_AT_location: 115 case DW_AT_frame_base: 116 // Only add these if they are location expressions (have a single 117 // value) and not location lists (have a lists of location 118 // expressions which are only valid over specific address ranges) 119 if (DWARFFormValue::IsBlockForm(form)) 120 m_attributes.push_back(DWARFAttribute(attr, form)); 121 break; 122 123 case DW_AT_low_pc: 124 case DW_AT_high_pc: 125 case DW_AT_ranges: 126 case DW_AT_entry_pc: 127 // Don't add these attributes 128 if (i >= idx) 129 break; 130 // Fall through and add attribute 131 default: 132 // Add anything that isn't address related 133 m_attributes.push_back(DWARFAttribute(attr, form)); 134 break; 135 } 136 } 137} 138 139void 140DWARFAbbreviationDeclaration::CopyChangingStringToStrp( 141 const DWARFAbbreviationDeclaration& abbr_decl, 142 const DataExtractor& debug_info_data, 143 dw_offset_t debug_info_offset, 144 const DWARFCompileUnit* cu, 145 const uint32_t strp_min_len 146) 147{ 148 m_code = InvalidCode; 149 m_tag = abbr_decl.Tag(); 150 m_has_children = abbr_decl.HasChildren(); 151 152 const DWARFAttribute::collection& attributes = abbr_decl.Attributes(); 153 const uint32_t num_abbr_decl_attributes = attributes.size(); 154 155 dw_attr_t attr; 156 dw_form_t form; 157 uint32_t i; 158 lldb::offset_t offset = debug_info_offset; 159 160 for (i = 0; i < num_abbr_decl_attributes; ++i) 161 { 162 attributes[i].get(attr, form); 163 dw_offset_t attr_offset = offset; 164 DWARFFormValue::SkipValue(form, debug_info_data, &offset, cu); 165 166 if (form == DW_FORM_string && ((offset - attr_offset) >= strp_min_len)) 167 m_attributes.push_back(DWARFAttribute(attr, DW_FORM_strp)); 168 else 169 m_attributes.push_back(DWARFAttribute(attr, form)); 170 } 171} 172 173 174uint32_t 175DWARFAbbreviationDeclaration::FindAttributeIndex(dw_attr_t attr) const 176{ 177 uint32_t i; 178 const uint32_t kNumAttributes = m_attributes.size(); 179 for (i = 0; i < kNumAttributes; ++i) 180 { 181 if (m_attributes[i].get_attr() == attr) 182 return i; 183 } 184 return DW_INVALID_INDEX; 185} 186 187 188bool 189DWARFAbbreviationDeclaration::operator == (const DWARFAbbreviationDeclaration& rhs) const 190{ 191 return Tag() == rhs.Tag() 192 && HasChildren() == rhs.HasChildren() 193 && Attributes() == rhs.Attributes(); 194} 195 196#if 0 197DWARFAbbreviationDeclaration::Append(BinaryStreamBuf& out_buff) const 198{ 199 out_buff.Append32_as_ULEB128(Code()); 200 out_buff.Append32_as_ULEB128(Tag()); 201 out_buff.Append8(HasChildren()); 202 const uint32_t kNumAttributes = m_attributes.size(); 203 for (uint32_t i = 0; i < kNumAttributes; ++i) 204 { 205 out_buff.Append32_as_ULEB128(m_attributes[i].attr()); 206 out_buff.Append32_as_ULEB128(m_attributes[i].form()); 207 } 208 out_buff.Append8(0); // Output a zero for attr (faster than using Append32_as_ULEB128) 209 out_buff.Append8(0); // Output a zero for attr (faster than using Append32_as_ULEB128) 210} 211#endif // 0 212