LLVM API Documentation
00001 //===-- DWARFFormValue.cpp ------------------------------------------------===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 00010 #include "llvm/DebugInfo/DWARFFormValue.h" 00011 #include "DWARFCompileUnit.h" 00012 #include "DWARFContext.h" 00013 #include "llvm/ADT/ArrayRef.h" 00014 #include "llvm/ADT/StringRef.h" 00015 #include "llvm/Support/Debug.h" 00016 #include "llvm/Support/Dwarf.h" 00017 #include "llvm/Support/Format.h" 00018 #include "llvm/Support/raw_ostream.h" 00019 #include <cassert> 00020 using namespace llvm; 00021 using namespace dwarf; 00022 00023 namespace { 00024 uint8_t getRefAddrSize(uint8_t AddrSize, uint16_t Version) { 00025 // FIXME: Support DWARF64. 00026 return (Version == 2) ? AddrSize : 4; 00027 } 00028 00029 template <uint8_t AddrSize, uint8_t RefAddrSize> 00030 ArrayRef<uint8_t> makeFixedFormSizesArrayRef() { 00031 static const uint8_t sizes[] = { 00032 0, // 0x00 unused 00033 AddrSize, // 0x01 DW_FORM_addr 00034 0, // 0x02 unused 00035 0, // 0x03 DW_FORM_block2 00036 0, // 0x04 DW_FORM_block4 00037 2, // 0x05 DW_FORM_data2 00038 4, // 0x06 DW_FORM_data4 00039 8, // 0x07 DW_FORM_data8 00040 0, // 0x08 DW_FORM_string 00041 0, // 0x09 DW_FORM_block 00042 0, // 0x0a DW_FORM_block1 00043 1, // 0x0b DW_FORM_data1 00044 1, // 0x0c DW_FORM_flag 00045 0, // 0x0d DW_FORM_sdata 00046 4, // 0x0e DW_FORM_strp 00047 0, // 0x0f DW_FORM_udata 00048 RefAddrSize, // 0x10 DW_FORM_ref_addr 00049 1, // 0x11 DW_FORM_ref1 00050 2, // 0x12 DW_FORM_ref2 00051 4, // 0x13 DW_FORM_ref4 00052 8, // 0x14 DW_FORM_ref8 00053 0, // 0x15 DW_FORM_ref_udata 00054 0, // 0x16 DW_FORM_indirect 00055 4, // 0x17 DW_FORM_sec_offset 00056 0, // 0x18 DW_FORM_exprloc 00057 0, // 0x19 DW_FORM_flag_present 00058 }; 00059 return makeArrayRef(sizes); 00060 } 00061 } 00062 00063 ArrayRef<uint8_t> DWARFFormValue::getFixedFormSizes(uint8_t AddrSize, 00064 uint16_t Version) { 00065 uint8_t RefAddrSize = getRefAddrSize(AddrSize, Version); 00066 if (AddrSize == 4 && RefAddrSize == 4) 00067 return makeFixedFormSizesArrayRef<4, 4>(); 00068 if (AddrSize == 4 && RefAddrSize == 8) 00069 return makeFixedFormSizesArrayRef<4, 8>(); 00070 if (AddrSize == 8 && RefAddrSize == 4) 00071 return makeFixedFormSizesArrayRef<8, 4>(); 00072 if (AddrSize == 8 && RefAddrSize == 8) 00073 return makeFixedFormSizesArrayRef<8, 8>(); 00074 return None; 00075 } 00076 00077 static const DWARFFormValue::FormClass DWARF4FormClasses[] = { 00078 DWARFFormValue::FC_Unknown, // 0x0 00079 DWARFFormValue::FC_Address, // 0x01 DW_FORM_addr 00080 DWARFFormValue::FC_Unknown, // 0x02 unused 00081 DWARFFormValue::FC_Block, // 0x03 DW_FORM_block2 00082 DWARFFormValue::FC_Block, // 0x04 DW_FORM_block4 00083 DWARFFormValue::FC_Constant, // 0x05 DW_FORM_data2 00084 // --- These can be FC_SectionOffset in DWARF3 and below: 00085 DWARFFormValue::FC_Constant, // 0x06 DW_FORM_data4 00086 DWARFFormValue::FC_Constant, // 0x07 DW_FORM_data8 00087 // --- 00088 DWARFFormValue::FC_String, // 0x08 DW_FORM_string 00089 DWARFFormValue::FC_Block, // 0x09 DW_FORM_block 00090 DWARFFormValue::FC_Block, // 0x0a DW_FORM_block1 00091 DWARFFormValue::FC_Constant, // 0x0b DW_FORM_data1 00092 DWARFFormValue::FC_Flag, // 0x0c DW_FORM_flag 00093 DWARFFormValue::FC_Constant, // 0x0d DW_FORM_sdata 00094 DWARFFormValue::FC_String, // 0x0e DW_FORM_strp 00095 DWARFFormValue::FC_Constant, // 0x0f DW_FORM_udata 00096 DWARFFormValue::FC_Reference, // 0x10 DW_FORM_ref_addr 00097 DWARFFormValue::FC_Reference, // 0x11 DW_FORM_ref1 00098 DWARFFormValue::FC_Reference, // 0x12 DW_FORM_ref2 00099 DWARFFormValue::FC_Reference, // 0x13 DW_FORM_ref4 00100 DWARFFormValue::FC_Reference, // 0x14 DW_FORM_ref8 00101 DWARFFormValue::FC_Reference, // 0x15 DW_FORM_ref_udata 00102 DWARFFormValue::FC_Indirect, // 0x16 DW_FORM_indirect 00103 DWARFFormValue::FC_SectionOffset, // 0x17 DW_FORM_sec_offset 00104 DWARFFormValue::FC_Exprloc, // 0x18 DW_FORM_exprloc 00105 DWARFFormValue::FC_Flag, // 0x19 DW_FORM_flag_present 00106 }; 00107 00108 bool DWARFFormValue::isFormClass(DWARFFormValue::FormClass FC) const { 00109 // First, check DWARF4 form classes. 00110 if (Form < ArrayRef<FormClass>(DWARF4FormClasses).size() && 00111 DWARF4FormClasses[Form] == FC) 00112 return true; 00113 // Check DW_FORM_ref_sig8 from DWARF4. 00114 if (Form == DW_FORM_ref_sig8) 00115 return (FC == FC_Reference); 00116 // Check for some DWARF5 forms. 00117 if (Form == DW_FORM_GNU_addr_index) 00118 return (FC == FC_Address); 00119 if (Form == DW_FORM_GNU_str_index) 00120 return (FC == FC_String); 00121 // In DWARF3 DW_FORM_data4 and DW_FORM_data8 served also as a section offset. 00122 // Don't check for DWARF version here, as some producers may still do this 00123 // by mistake. 00124 if ((Form == DW_FORM_data4 || Form == DW_FORM_data8) && 00125 FC == FC_SectionOffset) 00126 return true; 00127 return false; 00128 } 00129 00130 bool DWARFFormValue::extractValue(DataExtractor data, uint32_t *offset_ptr, 00131 const DWARFUnit *cu) { 00132 bool indirect = false; 00133 bool is_block = false; 00134 Value.data = nullptr; 00135 // Read the value for the form into value and follow and DW_FORM_indirect 00136 // instances we run into 00137 do { 00138 indirect = false; 00139 switch (Form) { 00140 case DW_FORM_addr: 00141 case DW_FORM_ref_addr: { 00142 uint16_t AddrSize = 00143 (Form == DW_FORM_addr) 00144 ? cu->getAddressByteSize() 00145 : getRefAddrSize(cu->getAddressByteSize(), cu->getVersion()); 00146 RelocAddrMap::const_iterator AI = cu->getRelocMap()->find(*offset_ptr); 00147 if (AI != cu->getRelocMap()->end()) { 00148 const std::pair<uint8_t, int64_t> &R = AI->second; 00149 Value.uval = data.getUnsigned(offset_ptr, AddrSize) + R.second; 00150 } else 00151 Value.uval = data.getUnsigned(offset_ptr, AddrSize); 00152 break; 00153 } 00154 case DW_FORM_exprloc: 00155 case DW_FORM_block: 00156 Value.uval = data.getULEB128(offset_ptr); 00157 is_block = true; 00158 break; 00159 case DW_FORM_block1: 00160 Value.uval = data.getU8(offset_ptr); 00161 is_block = true; 00162 break; 00163 case DW_FORM_block2: 00164 Value.uval = data.getU16(offset_ptr); 00165 is_block = true; 00166 break; 00167 case DW_FORM_block4: 00168 Value.uval = data.getU32(offset_ptr); 00169 is_block = true; 00170 break; 00171 case DW_FORM_data1: 00172 case DW_FORM_ref1: 00173 case DW_FORM_flag: 00174 Value.uval = data.getU8(offset_ptr); 00175 break; 00176 case DW_FORM_data2: 00177 case DW_FORM_ref2: 00178 Value.uval = data.getU16(offset_ptr); 00179 break; 00180 case DW_FORM_data4: 00181 case DW_FORM_ref4: { 00182 RelocAddrMap::const_iterator AI = cu->getRelocMap()->find(*offset_ptr); 00183 Value.uval = data.getU32(offset_ptr); 00184 if (AI != cu->getRelocMap()->end()) 00185 Value.uval += AI->second.second; 00186 break; 00187 } 00188 case DW_FORM_data8: 00189 case DW_FORM_ref8: 00190 Value.uval = data.getU64(offset_ptr); 00191 break; 00192 case DW_FORM_sdata: 00193 Value.sval = data.getSLEB128(offset_ptr); 00194 break; 00195 case DW_FORM_strp: { 00196 RelocAddrMap::const_iterator AI 00197 = cu->getRelocMap()->find(*offset_ptr); 00198 if (AI != cu->getRelocMap()->end()) { 00199 const std::pair<uint8_t, int64_t> &R = AI->second; 00200 Value.uval = data.getU32(offset_ptr) + R.second; 00201 } else 00202 Value.uval = data.getU32(offset_ptr); 00203 break; 00204 } 00205 case DW_FORM_udata: 00206 case DW_FORM_ref_udata: 00207 Value.uval = data.getULEB128(offset_ptr); 00208 break; 00209 case DW_FORM_string: 00210 Value.cstr = data.getCStr(offset_ptr); 00211 break; 00212 case DW_FORM_indirect: 00213 Form = data.getULEB128(offset_ptr); 00214 indirect = true; 00215 break; 00216 case DW_FORM_sec_offset: { 00217 // FIXME: This is 64-bit for DWARF64. 00218 RelocAddrMap::const_iterator AI 00219 = cu->getRelocMap()->find(*offset_ptr); 00220 if (AI != cu->getRelocMap()->end()) { 00221 const std::pair<uint8_t, int64_t> &R = AI->second; 00222 Value.uval = data.getU32(offset_ptr) + R.second; 00223 } else 00224 Value.uval = data.getU32(offset_ptr); 00225 break; 00226 } 00227 case DW_FORM_flag_present: 00228 Value.uval = 1; 00229 break; 00230 case DW_FORM_ref_sig8: 00231 Value.uval = data.getU64(offset_ptr); 00232 break; 00233 case DW_FORM_GNU_addr_index: 00234 case DW_FORM_GNU_str_index: 00235 Value.uval = data.getULEB128(offset_ptr); 00236 break; 00237 default: 00238 return false; 00239 } 00240 } while (indirect); 00241 00242 if (is_block) { 00243 StringRef str = data.getData().substr(*offset_ptr, Value.uval); 00244 Value.data = nullptr; 00245 if (!str.empty()) { 00246 Value.data = reinterpret_cast<const uint8_t *>(str.data()); 00247 *offset_ptr += Value.uval; 00248 } 00249 } 00250 00251 return true; 00252 } 00253 00254 bool 00255 DWARFFormValue::skipValue(DataExtractor debug_info_data, uint32_t* offset_ptr, 00256 const DWARFUnit *cu) const { 00257 return DWARFFormValue::skipValue(Form, debug_info_data, offset_ptr, cu); 00258 } 00259 00260 bool 00261 DWARFFormValue::skipValue(uint16_t form, DataExtractor debug_info_data, 00262 uint32_t *offset_ptr, const DWARFUnit *cu) { 00263 bool indirect = false; 00264 do { 00265 switch (form) { 00266 // Blocks if inlined data that have a length field and the data bytes 00267 // inlined in the .debug_info 00268 case DW_FORM_exprloc: 00269 case DW_FORM_block: { 00270 uint64_t size = debug_info_data.getULEB128(offset_ptr); 00271 *offset_ptr += size; 00272 return true; 00273 } 00274 case DW_FORM_block1: { 00275 uint8_t size = debug_info_data.getU8(offset_ptr); 00276 *offset_ptr += size; 00277 return true; 00278 } 00279 case DW_FORM_block2: { 00280 uint16_t size = debug_info_data.getU16(offset_ptr); 00281 *offset_ptr += size; 00282 return true; 00283 } 00284 case DW_FORM_block4: { 00285 uint32_t size = debug_info_data.getU32(offset_ptr); 00286 *offset_ptr += size; 00287 return true; 00288 } 00289 00290 // Inlined NULL terminated C-strings 00291 case DW_FORM_string: 00292 debug_info_data.getCStr(offset_ptr); 00293 return true; 00294 00295 // Compile unit address sized values 00296 case DW_FORM_addr: 00297 *offset_ptr += cu->getAddressByteSize(); 00298 return true; 00299 case DW_FORM_ref_addr: 00300 *offset_ptr += getRefAddrSize(cu->getAddressByteSize(), cu->getVersion()); 00301 return true; 00302 00303 // 0 byte values - implied from the form. 00304 case DW_FORM_flag_present: 00305 return true; 00306 00307 // 1 byte values 00308 case DW_FORM_data1: 00309 case DW_FORM_flag: 00310 case DW_FORM_ref1: 00311 *offset_ptr += 1; 00312 return true; 00313 00314 // 2 byte values 00315 case DW_FORM_data2: 00316 case DW_FORM_ref2: 00317 *offset_ptr += 2; 00318 return true; 00319 00320 // 4 byte values 00321 case DW_FORM_strp: 00322 case DW_FORM_data4: 00323 case DW_FORM_ref4: 00324 *offset_ptr += 4; 00325 return true; 00326 00327 // 8 byte values 00328 case DW_FORM_data8: 00329 case DW_FORM_ref8: 00330 case DW_FORM_ref_sig8: 00331 *offset_ptr += 8; 00332 return true; 00333 00334 // signed or unsigned LEB 128 values 00335 // case DW_FORM_APPLE_db_str: 00336 case DW_FORM_sdata: 00337 case DW_FORM_udata: 00338 case DW_FORM_ref_udata: 00339 case DW_FORM_GNU_str_index: 00340 case DW_FORM_GNU_addr_index: 00341 debug_info_data.getULEB128(offset_ptr); 00342 return true; 00343 00344 case DW_FORM_indirect: 00345 indirect = true; 00346 form = debug_info_data.getULEB128(offset_ptr); 00347 break; 00348 00349 // FIXME: 4 for DWARF32, 8 for DWARF64. 00350 case DW_FORM_sec_offset: 00351 *offset_ptr += 4; 00352 return true; 00353 00354 default: 00355 return false; 00356 } 00357 } while (indirect); 00358 return true; 00359 } 00360 00361 void 00362 DWARFFormValue::dump(raw_ostream &OS, const DWARFUnit *cu) const { 00363 DataExtractor debug_str_data(cu->getStringSection(), true, 0); 00364 DataExtractor debug_str_offset_data(cu->getStringOffsetSection(), true, 0); 00365 uint64_t uvalue = Value.uval; 00366 bool cu_relative_offset = false; 00367 00368 switch (Form) { 00369 case DW_FORM_addr: OS << format("0x%016" PRIx64, uvalue); break; 00370 case DW_FORM_GNU_addr_index: { 00371 OS << format(" indexed (%8.8x) address = ", (uint32_t)uvalue); 00372 uint64_t Address; 00373 if (cu->getAddrOffsetSectionItem(uvalue, Address)) 00374 OS << format("0x%016" PRIx64, Address); 00375 else 00376 OS << "<no .debug_addr section>"; 00377 break; 00378 } 00379 case DW_FORM_flag_present: OS << "true"; break; 00380 case DW_FORM_flag: 00381 case DW_FORM_data1: OS << format("0x%02x", (uint8_t)uvalue); break; 00382 case DW_FORM_data2: OS << format("0x%04x", (uint16_t)uvalue); break; 00383 case DW_FORM_data4: OS << format("0x%08x", (uint32_t)uvalue); break; 00384 case DW_FORM_ref_sig8: 00385 case DW_FORM_data8: OS << format("0x%016" PRIx64, uvalue); break; 00386 case DW_FORM_string: 00387 OS << '"'; 00388 OS.write_escaped(Value.cstr); 00389 OS << '"'; 00390 break; 00391 case DW_FORM_exprloc: 00392 case DW_FORM_block: 00393 case DW_FORM_block1: 00394 case DW_FORM_block2: 00395 case DW_FORM_block4: 00396 if (uvalue > 0) { 00397 switch (Form) { 00398 case DW_FORM_exprloc: 00399 case DW_FORM_block: OS << format("<0x%" PRIx64 "> ", uvalue); break; 00400 case DW_FORM_block1: OS << format("<0x%2.2x> ", (uint8_t)uvalue); break; 00401 case DW_FORM_block2: OS << format("<0x%4.4x> ", (uint16_t)uvalue); break; 00402 case DW_FORM_block4: OS << format("<0x%8.8x> ", (uint32_t)uvalue); break; 00403 default: break; 00404 } 00405 00406 const uint8_t* data_ptr = Value.data; 00407 if (data_ptr) { 00408 // uvalue contains size of block 00409 const uint8_t* end_data_ptr = data_ptr + uvalue; 00410 while (data_ptr < end_data_ptr) { 00411 OS << format("%2.2x ", *data_ptr); 00412 ++data_ptr; 00413 } 00414 } 00415 else 00416 OS << "NULL"; 00417 } 00418 break; 00419 00420 case DW_FORM_sdata: OS << Value.sval; break; 00421 case DW_FORM_udata: OS << Value.uval; break; 00422 case DW_FORM_strp: { 00423 OS << format(" .debug_str[0x%8.8x] = ", (uint32_t)uvalue); 00424 Optional<const char *> DbgStr = getAsCString(cu); 00425 if (DbgStr.hasValue()) { 00426 OS << '"'; 00427 OS.write_escaped(DbgStr.getValue()); 00428 OS << '"'; 00429 } 00430 break; 00431 } 00432 case DW_FORM_GNU_str_index: { 00433 OS << format(" indexed (%8.8x) string = ", (uint32_t)uvalue); 00434 Optional<const char *> DbgStr = getAsCString(cu); 00435 if (DbgStr.hasValue()) { 00436 OS << '"'; 00437 OS.write_escaped(DbgStr.getValue()); 00438 OS << '"'; 00439 } 00440 break; 00441 } 00442 case DW_FORM_ref_addr: 00443 OS << format("0x%016" PRIx64, uvalue); 00444 break; 00445 case DW_FORM_ref1: 00446 cu_relative_offset = true; 00447 OS << format("cu + 0x%2.2x", (uint8_t)uvalue); 00448 break; 00449 case DW_FORM_ref2: 00450 cu_relative_offset = true; 00451 OS << format("cu + 0x%4.4x", (uint16_t)uvalue); 00452 break; 00453 case DW_FORM_ref4: 00454 cu_relative_offset = true; 00455 OS << format("cu + 0x%4.4x", (uint32_t)uvalue); 00456 break; 00457 case DW_FORM_ref8: 00458 cu_relative_offset = true; 00459 OS << format("cu + 0x%8.8" PRIx64, uvalue); 00460 break; 00461 case DW_FORM_ref_udata: 00462 cu_relative_offset = true; 00463 OS << format("cu + 0x%" PRIx64, uvalue); 00464 break; 00465 00466 // All DW_FORM_indirect attributes should be resolved prior to calling 00467 // this function 00468 case DW_FORM_indirect: 00469 OS << "DW_FORM_indirect"; 00470 break; 00471 00472 // Should be formatted to 64-bit for DWARF64. 00473 case DW_FORM_sec_offset: 00474 OS << format("0x%08x", (uint32_t)uvalue); 00475 break; 00476 00477 default: 00478 OS << format("DW_FORM(0x%4.4x)", Form); 00479 break; 00480 } 00481 00482 if (cu_relative_offset) 00483 OS << format(" => {0x%8.8" PRIx64 "}", uvalue + (cu ? cu->getOffset() : 0)); 00484 } 00485 00486 Optional<const char *> DWARFFormValue::getAsCString(const DWARFUnit *U) const { 00487 if (!isFormClass(FC_String)) 00488 return None; 00489 if (Form == DW_FORM_string) 00490 return Value.cstr; 00491 if (!U) 00492 return None; 00493 uint32_t Offset = Value.uval; 00494 if (Form == DW_FORM_GNU_str_index) { 00495 uint32_t StrOffset; 00496 if (!U->getStringOffsetSectionItem(Offset, StrOffset)) 00497 return None; 00498 Offset = StrOffset; 00499 } 00500 if (const char *Str = U->getStringExtractor().getCStr(&Offset)) { 00501 return Str; 00502 } 00503 return None; 00504 } 00505 00506 Optional<uint64_t> DWARFFormValue::getAsAddress(const DWARFUnit *U) const { 00507 if (!isFormClass(FC_Address)) 00508 return None; 00509 if (Form == DW_FORM_GNU_addr_index) { 00510 uint32_t Index = Value.uval; 00511 uint64_t Result; 00512 if (!U || !U->getAddrOffsetSectionItem(Index, Result)) 00513 return None; 00514 return Result; 00515 } 00516 return Value.uval; 00517 } 00518 00519 Optional<uint64_t> DWARFFormValue::getAsReference(const DWARFUnit *U) const { 00520 if (!isFormClass(FC_Reference)) 00521 return None; 00522 switch (Form) { 00523 case DW_FORM_ref1: 00524 case DW_FORM_ref2: 00525 case DW_FORM_ref4: 00526 case DW_FORM_ref8: 00527 case DW_FORM_ref_udata: 00528 if (!U) 00529 return None; 00530 return Value.uval + U->getOffset(); 00531 case DW_FORM_ref_addr: 00532 return Value.uval; 00533 // FIXME: Add proper support for DW_FORM_ref_sig8 00534 default: 00535 return Value.uval; 00536 } 00537 } 00538 00539 Optional<uint64_t> DWARFFormValue::getAsSectionOffset() const { 00540 if (!isFormClass(FC_SectionOffset)) 00541 return None; 00542 return Value.uval; 00543 } 00544 00545 Optional<uint64_t> DWARFFormValue::getAsUnsignedConstant() const { 00546 if ((!isFormClass(FC_Constant) && !isFormClass(FC_Flag)) 00547 || Form == DW_FORM_sdata) 00548 return None; 00549 return Value.uval; 00550 } 00551 00552 Optional<ArrayRef<uint8_t>> DWARFFormValue::getAsBlock() const { 00553 if (!isFormClass(FC_Block) && !isFormClass(FC_Exprloc)) 00554 return None; 00555 return ArrayRef<uint8_t>(Value.data, Value.uval); 00556 } 00557