1//===-- DWARFDebugInfoEntry.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 "DWARFDebugInfoEntry.h" 11#include "DWARFCompileUnit.h" 12#include "DWARFContext.h" 13#include "DWARFDebugAbbrev.h" 14#include "DWARFFormValue.h" 15#include "llvm/Support/Dwarf.h" 16#include "llvm/Support/Format.h" 17#include "llvm/Support/raw_ostream.h" 18using namespace llvm; 19using namespace dwarf; 20 21void DWARFDebugInfoEntryMinimal::dump(raw_ostream &OS, 22 const DWARFCompileUnit *cu, 23 unsigned recurseDepth, 24 unsigned indent) const { 25 DataExtractor debug_info_data = cu->getDebugInfoExtractor(); 26 uint32_t offset = Offset; 27 28 if (debug_info_data.isValidOffset(offset)) { 29 uint32_t abbrCode = debug_info_data.getULEB128(&offset); 30 31 OS << format("\n0x%8.8x: ", Offset); 32 if (abbrCode) { 33 if (AbbrevDecl) { 34 const char *tagString = TagString(getTag()); 35 if (tagString) 36 OS.indent(indent) << tagString; 37 else 38 OS.indent(indent) << format("DW_TAG_Unknown_%x", getTag()); 39 OS << format(" [%u] %c\n", abbrCode, 40 AbbrevDecl->hasChildren() ? '*' : ' '); 41 42 // Dump all data in the .debug_info for the attributes 43 const uint32_t numAttributes = AbbrevDecl->getNumAttributes(); 44 for (uint32_t i = 0; i != numAttributes; ++i) { 45 uint16_t attr = AbbrevDecl->getAttrByIndex(i); 46 uint16_t form = AbbrevDecl->getFormByIndex(i); 47 dumpAttribute(OS, cu, &offset, attr, form, indent); 48 } 49 50 const DWARFDebugInfoEntryMinimal *child = getFirstChild(); 51 if (recurseDepth > 0 && child) { 52 while (child) { 53 child->dump(OS, cu, recurseDepth-1, indent+2); 54 child = child->getSibling(); 55 } 56 } 57 } else { 58 OS << "Abbreviation code not found in 'debug_abbrev' class for code: " 59 << abbrCode << '\n'; 60 } 61 } else { 62 OS.indent(indent) << "NULL\n"; 63 } 64 } 65} 66 67void DWARFDebugInfoEntryMinimal::dumpAttribute(raw_ostream &OS, 68 const DWARFCompileUnit *cu, 69 uint32_t* offset_ptr, 70 uint16_t attr, 71 uint16_t form, 72 unsigned indent) const { 73 OS << format("0x%8.8x: ", *offset_ptr); 74 OS.indent(indent+2); 75 const char *attrString = AttributeString(attr); 76 if (attrString) 77 OS << attrString; 78 else 79 OS << format("DW_AT_Unknown_%x", attr); 80 const char *formString = FormEncodingString(form); 81 if (formString) 82 OS << " [" << formString << ']'; 83 else 84 OS << format(" [DW_FORM_Unknown_%x]", form); 85 86 DWARFFormValue formValue(form); 87 88 if (!formValue.extractValue(cu->getDebugInfoExtractor(), offset_ptr, cu)) 89 return; 90 91 OS << "\t("; 92 formValue.dump(OS, cu); 93 OS << ")\n"; 94} 95 96bool DWARFDebugInfoEntryMinimal::extractFast(const DWARFCompileUnit *cu, 97 const uint8_t *fixed_form_sizes, 98 uint32_t *offset_ptr) { 99 Offset = *offset_ptr; 100 101 DataExtractor debug_info_data = cu->getDebugInfoExtractor(); 102 uint64_t abbrCode = debug_info_data.getULEB128(offset_ptr); 103 104 assert (fixed_form_sizes); // For best performance this should be specified! 105 106 if (abbrCode) { 107 uint32_t offset = *offset_ptr; 108 109 AbbrevDecl = cu->getAbbreviations()->getAbbreviationDeclaration(abbrCode); 110 111 // Skip all data in the .debug_info for the attributes 112 const uint32_t numAttributes = AbbrevDecl->getNumAttributes(); 113 uint32_t i; 114 uint16_t form; 115 for (i=0; i<numAttributes; ++i) { 116 form = AbbrevDecl->getFormByIndex(i); 117 118 const uint8_t fixed_skip_size = fixed_form_sizes[form]; 119 if (fixed_skip_size) 120 offset += fixed_skip_size; 121 else { 122 bool form_is_indirect = false; 123 do { 124 form_is_indirect = false; 125 uint32_t form_size = 0; 126 switch (form) { 127 // Blocks if inlined data that have a length field and the data bytes 128 // inlined in the .debug_info. 129 case DW_FORM_block: 130 form_size = debug_info_data.getULEB128(&offset); 131 break; 132 case DW_FORM_block1: 133 form_size = debug_info_data.getU8(&offset); 134 break; 135 case DW_FORM_block2: 136 form_size = debug_info_data.getU16(&offset); 137 break; 138 case DW_FORM_block4: 139 form_size = debug_info_data.getU32(&offset); 140 break; 141 142 // Inlined NULL terminated C-strings 143 case DW_FORM_string: 144 debug_info_data.getCStr(&offset); 145 break; 146 147 // Compile unit address sized values 148 case DW_FORM_addr: 149 case DW_FORM_ref_addr: 150 form_size = cu->getAddressByteSize(); 151 break; 152 153 // 1 byte values 154 case DW_FORM_data1: 155 case DW_FORM_flag: 156 case DW_FORM_ref1: 157 form_size = 1; 158 break; 159 160 // 2 byte values 161 case DW_FORM_data2: 162 case DW_FORM_ref2: 163 form_size = 2; 164 break; 165 166 // 4 byte values 167 case DW_FORM_strp: 168 case DW_FORM_data4: 169 case DW_FORM_ref4: 170 form_size = 4; 171 break; 172 173 // 8 byte values 174 case DW_FORM_data8: 175 case DW_FORM_ref8: 176 form_size = 8; 177 break; 178 179 // signed or unsigned LEB 128 values 180 case DW_FORM_sdata: 181 case DW_FORM_udata: 182 case DW_FORM_ref_udata: 183 debug_info_data.getULEB128(&offset); 184 break; 185 186 case DW_FORM_indirect: 187 form_is_indirect = true; 188 form = debug_info_data.getULEB128(&offset); 189 break; 190 191 default: 192 *offset_ptr = Offset; 193 return false; 194 } 195 offset += form_size; 196 197 } while (form_is_indirect); 198 } 199 } 200 *offset_ptr = offset; 201 return true; 202 } else { 203 AbbrevDecl = NULL; 204 return true; // NULL debug tag entry 205 } 206} 207 208bool 209DWARFDebugInfoEntryMinimal::extract(const DWARFCompileUnit *cu, 210 uint32_t *offset_ptr) { 211 DataExtractor debug_info_data = cu->getDebugInfoExtractor(); 212 const uint32_t cu_end_offset = cu->getNextCompileUnitOffset(); 213 const uint8_t cu_addr_size = cu->getAddressByteSize(); 214 uint32_t offset = *offset_ptr; 215 if ((offset < cu_end_offset) && debug_info_data.isValidOffset(offset)) { 216 Offset = offset; 217 218 uint64_t abbrCode = debug_info_data.getULEB128(&offset); 219 220 if (abbrCode) { 221 AbbrevDecl = cu->getAbbreviations()->getAbbreviationDeclaration(abbrCode); 222 223 if (AbbrevDecl) { 224 uint16_t tag = AbbrevDecl->getTag(); 225 226 bool isCompileUnitTag = tag == DW_TAG_compile_unit; 227 if(cu && isCompileUnitTag) 228 const_cast<DWARFCompileUnit*>(cu)->setBaseAddress(0); 229 230 // Skip all data in the .debug_info for the attributes 231 const uint32_t numAttributes = AbbrevDecl->getNumAttributes(); 232 for (uint32_t i = 0; i != numAttributes; ++i) { 233 uint16_t attr = AbbrevDecl->getAttrByIndex(i); 234 uint16_t form = AbbrevDecl->getFormByIndex(i); 235 236 if (isCompileUnitTag && 237 ((attr == DW_AT_entry_pc) || (attr == DW_AT_low_pc))) { 238 DWARFFormValue form_value(form); 239 if (form_value.extractValue(debug_info_data, &offset, cu)) { 240 if (attr == DW_AT_low_pc || attr == DW_AT_entry_pc) 241 const_cast<DWARFCompileUnit*>(cu) 242 ->setBaseAddress(form_value.getUnsigned()); 243 } 244 } else { 245 bool form_is_indirect = false; 246 do { 247 form_is_indirect = false; 248 register uint32_t form_size = 0; 249 switch (form) { 250 // Blocks if inlined data that have a length field and the data 251 // bytes // inlined in the .debug_info 252 case DW_FORM_block: 253 form_size = debug_info_data.getULEB128(&offset); 254 break; 255 case DW_FORM_block1: 256 form_size = debug_info_data.getU8(&offset); 257 break; 258 case DW_FORM_block2: 259 form_size = debug_info_data.getU16(&offset); 260 break; 261 case DW_FORM_block4: 262 form_size = debug_info_data.getU32(&offset); 263 break; 264 265 // Inlined NULL terminated C-strings 266 case DW_FORM_string: 267 debug_info_data.getCStr(&offset); 268 break; 269 270 // Compile unit address sized values 271 case DW_FORM_addr: 272 case DW_FORM_ref_addr: 273 form_size = cu_addr_size; 274 break; 275 276 // 1 byte values 277 case DW_FORM_data1: 278 case DW_FORM_flag: 279 case DW_FORM_ref1: 280 form_size = 1; 281 break; 282 283 // 2 byte values 284 case DW_FORM_data2: 285 case DW_FORM_ref2: 286 form_size = 2; 287 break; 288 289 // 4 byte values 290 case DW_FORM_strp: 291 form_size = 4; 292 break; 293 294 case DW_FORM_data4: 295 case DW_FORM_ref4: 296 form_size = 4; 297 break; 298 299 // 8 byte values 300 case DW_FORM_data8: 301 case DW_FORM_ref8: 302 form_size = 8; 303 break; 304 305 // signed or unsigned LEB 128 values 306 case DW_FORM_sdata: 307 case DW_FORM_udata: 308 case DW_FORM_ref_udata: 309 debug_info_data.getULEB128(&offset); 310 break; 311 312 case DW_FORM_indirect: 313 form = debug_info_data.getULEB128(&offset); 314 form_is_indirect = true; 315 break; 316 317 default: 318 *offset_ptr = offset; 319 return false; 320 } 321 322 offset += form_size; 323 } while (form_is_indirect); 324 } 325 } 326 *offset_ptr = offset; 327 return true; 328 } 329 } else { 330 AbbrevDecl = NULL; 331 *offset_ptr = offset; 332 return true; // NULL debug tag entry 333 } 334 } 335 336 return false; 337} 338 339uint32_t 340DWARFDebugInfoEntryMinimal::getAttributeValue(const DWARFCompileUnit *cu, 341 const uint16_t attr, 342 DWARFFormValue &form_value, 343 uint32_t *end_attr_offset_ptr) 344 const { 345 if (AbbrevDecl) { 346 uint32_t attr_idx = AbbrevDecl->findAttributeIndex(attr); 347 348 if (attr_idx != -1U) { 349 uint32_t offset = getOffset(); 350 351 DataExtractor debug_info_data = cu->getDebugInfoExtractor(); 352 353 // Skip the abbreviation code so we are at the data for the attributes 354 debug_info_data.getULEB128(&offset); 355 356 uint32_t idx = 0; 357 while (idx < attr_idx) 358 DWARFFormValue::skipValue(AbbrevDecl->getFormByIndex(idx++), 359 debug_info_data, &offset, cu); 360 361 const uint32_t attr_offset = offset; 362 form_value = DWARFFormValue(AbbrevDecl->getFormByIndex(idx)); 363 if (form_value.extractValue(debug_info_data, &offset, cu)) { 364 if (end_attr_offset_ptr) 365 *end_attr_offset_ptr = offset; 366 return attr_offset; 367 } 368 } 369 } 370 371 return 0; 372} 373 374const char* 375DWARFDebugInfoEntryMinimal::getAttributeValueAsString( 376 const DWARFCompileUnit* cu, 377 const uint16_t attr, 378 const char* fail_value) const { 379 DWARFFormValue form_value; 380 if (getAttributeValue(cu, attr, form_value)) { 381 DataExtractor stringExtractor(cu->getContext().getStringSection(), 382 false, 0); 383 return form_value.getAsCString(&stringExtractor); 384 } 385 return fail_value; 386} 387 388uint64_t 389DWARFDebugInfoEntryMinimal::getAttributeValueAsUnsigned( 390 const DWARFCompileUnit* cu, 391 const uint16_t attr, 392 uint64_t fail_value) const { 393 DWARFFormValue form_value; 394 if (getAttributeValue(cu, attr, form_value)) 395 return form_value.getUnsigned(); 396 return fail_value; 397} 398 399int64_t 400DWARFDebugInfoEntryMinimal::getAttributeValueAsSigned( 401 const DWARFCompileUnit* cu, 402 const uint16_t attr, 403 int64_t fail_value) const { 404 DWARFFormValue form_value; 405 if (getAttributeValue(cu, attr, form_value)) 406 return form_value.getSigned(); 407 return fail_value; 408} 409 410uint64_t 411DWARFDebugInfoEntryMinimal::getAttributeValueAsReference( 412 const DWARFCompileUnit* cu, 413 const uint16_t attr, 414 uint64_t fail_value) const { 415 DWARFFormValue form_value; 416 if (getAttributeValue(cu, attr, form_value)) 417 return form_value.getReference(cu); 418 return fail_value; 419} 420 421void 422DWARFDebugInfoEntryMinimal::buildAddressRangeTable(const DWARFCompileUnit *cu, 423 DWARFDebugAranges *debug_aranges) 424 const { 425 if (AbbrevDecl) { 426 uint16_t tag = AbbrevDecl->getTag(); 427 if (tag == DW_TAG_subprogram) { 428 uint64_t hi_pc = -1ULL; 429 uint64_t lo_pc = getAttributeValueAsUnsigned(cu, DW_AT_low_pc, -1ULL); 430 if (lo_pc != -1ULL) 431 hi_pc = getAttributeValueAsUnsigned(cu, DW_AT_high_pc, -1ULL); 432 if (hi_pc != -1ULL) 433 debug_aranges->appendRange(cu->getOffset(), lo_pc, hi_pc); 434 } 435 436 const DWARFDebugInfoEntryMinimal *child = getFirstChild(); 437 while (child) { 438 child->buildAddressRangeTable(cu, debug_aranges); 439 child = child->getSibling(); 440 } 441 } 442} 443