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 16 using namespace lldb_private; 17 18 DWARFAbbreviationDeclaration::DWARFAbbreviationDeclaration() : 19 m_code (InvalidCode), 20 m_tag (0), 21 m_has_children (0), 22 m_attributes() 23 { 24 } 25 26 DWARFAbbreviationDeclaration::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 34 bool 35 DWARFAbbreviationDeclaration::Extract(const DataExtractor& data, lldb::offset_t* offset_ptr) 36 { 37 return Extract(data, offset_ptr, data.GetULEB128(offset_ptr)); 38 } 39 40 bool 41 DWARFAbbreviationDeclaration::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 73 void 74 DWARFAbbreviationDeclaration::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 88 bool 89 DWARFAbbreviationDeclaration::IsValid() 90 { 91 return m_code != 0 && m_tag != 0; 92 } 93 94 95 void 96 DWARFAbbreviationDeclaration::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 139 void 140 DWARFAbbreviationDeclaration::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 174 uint32_t 175 DWARFAbbreviationDeclaration::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 188 bool 189 DWARFAbbreviationDeclaration::operator == (const DWARFAbbreviationDeclaration& rhs) const 190 { 191 return Tag() == rhs.Tag() 192 && HasChildren() == rhs.HasChildren() 193 && Attributes() == rhs.Attributes(); 194 } 195 196 #if 0 197 DWARFAbbreviationDeclaration::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