1 //===-- DWARFFormValue.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 <assert.h> 11 12 #include "lldb/Core/dwarf.h" 13 #include "lldb/Core/Stream.h" 14 15 #include "DWARFFormValue.h" 16 #include "DWARFCompileUnit.h" 17 18 class DWARFCompileUnit; 19 20 using namespace lldb_private; 21 22 23 static uint8_t g_form_sizes_addr4[] = 24 { 25 0, // 0x00 unused 26 4, // 0x01 DW_FORM_addr 27 0, // 0x02 unused 28 0, // 0x03 DW_FORM_block2 29 0, // 0x04 DW_FORM_block4 30 2, // 0x05 DW_FORM_data2 31 4, // 0x06 DW_FORM_data4 32 8, // 0x07 DW_FORM_data8 33 0, // 0x08 DW_FORM_string 34 0, // 0x09 DW_FORM_block 35 0, // 0x0a DW_FORM_block1 36 1, // 0x0b DW_FORM_data1 37 1, // 0x0c DW_FORM_flag 38 0, // 0x0d DW_FORM_sdata 39 4, // 0x0e DW_FORM_strp 40 0, // 0x0f DW_FORM_udata 41 0, // 0x10 DW_FORM_ref_addr (addr size for DWARF2 and earlier, 4 bytes for DWARF32, 8 bytes for DWARF32 in DWARF 3 and later 42 1, // 0x11 DW_FORM_ref1 43 2, // 0x12 DW_FORM_ref2 44 4, // 0x13 DW_FORM_ref4 45 8, // 0x14 DW_FORM_ref8 46 0, // 0x15 DW_FORM_ref_udata 47 0, // 0x16 DW_FORM_indirect 48 4, // 0x17 DW_FORM_sec_offset 49 0, // 0x18 DW_FORM_exprloc 50 0, // 0x19 DW_FORM_flag_present 51 0, // 0x1a 52 0, // 0x1b 53 0, // 0x1c 54 0, // 0x1d 55 0, // 0x1e 56 0, // 0x1f 57 8, // 0x20 DW_FORM_ref_sig8 58 59 }; 60 61 static uint8_t 62 g_form_sizes_addr8[] = 63 { 64 0, // 0x00 unused 65 8, // 0x01 DW_FORM_addr 66 0, // 0x02 unused 67 0, // 0x03 DW_FORM_block2 68 0, // 0x04 DW_FORM_block4 69 2, // 0x05 DW_FORM_data2 70 4, // 0x06 DW_FORM_data4 71 8, // 0x07 DW_FORM_data8 72 0, // 0x08 DW_FORM_string 73 0, // 0x09 DW_FORM_block 74 0, // 0x0a DW_FORM_block1 75 1, // 0x0b DW_FORM_data1 76 1, // 0x0c DW_FORM_flag 77 0, // 0x0d DW_FORM_sdata 78 4, // 0x0e DW_FORM_strp 79 0, // 0x0f DW_FORM_udata 80 0, // 0x10 DW_FORM_ref_addr (addr size for DWARF2 and earlier, 4 bytes for DWARF32, 8 bytes for DWARF32 in DWARF 3 and later 81 1, // 0x11 DW_FORM_ref1 82 2, // 0x12 DW_FORM_ref2 83 4, // 0x13 DW_FORM_ref4 84 8, // 0x14 DW_FORM_ref8 85 0, // 0x15 DW_FORM_ref_udata 86 0, // 0x16 DW_FORM_indirect 87 4, // 0x17 DW_FORM_sec_offset 88 0, // 0x18 DW_FORM_exprloc 89 0, // 0x19 DW_FORM_flag_present 90 0, // 0x1a 91 0, // 0x1b 92 0, // 0x1c 93 0, // 0x1d 94 0, // 0x1e 95 0, // 0x1f 96 8, // 0x20 DW_FORM_ref_sig8 97 }; 98 99 // Difference with g_form_sizes_addr8: 100 // DW_FORM_strp and DW_FORM_sec_offset are 8 instead of 4 101 static uint8_t 102 g_form_sizes_addr8_dwarf64[] = 103 { 104 0, // 0x00 unused 105 8, // 0x01 DW_FORM_addr 106 0, // 0x02 unused 107 0, // 0x03 DW_FORM_block2 108 0, // 0x04 DW_FORM_block4 109 2, // 0x05 DW_FORM_data2 110 4, // 0x06 DW_FORM_data4 111 8, // 0x07 DW_FORM_data8 112 0, // 0x08 DW_FORM_string 113 0, // 0x09 DW_FORM_block 114 0, // 0x0a DW_FORM_block1 115 1, // 0x0b DW_FORM_data1 116 1, // 0x0c DW_FORM_flag 117 0, // 0x0d DW_FORM_sdata 118 8, // 0x0e DW_FORM_strp 119 0, // 0x0f DW_FORM_udata 120 0, // 0x10 DW_FORM_ref_addr (addr size for DWARF2 and earlier, 4 bytes for DWARF32, 8 bytes for DWARF32 in DWARF 3 and later 121 1, // 0x11 DW_FORM_ref1 122 2, // 0x12 DW_FORM_ref2 123 4, // 0x13 DW_FORM_ref4 124 8, // 0x14 DW_FORM_ref8 125 0, // 0x15 DW_FORM_ref_udata 126 0, // 0x16 DW_FORM_indirect 127 8, // 0x17 DW_FORM_sec_offset 128 0, // 0x18 DW_FORM_exprloc 129 0, // 0x19 DW_FORM_flag_present 130 0, // 0x1a 131 0, // 0x1b 132 0, // 0x1c 133 0, // 0x1d 134 0, // 0x1e 135 0, // 0x1f 136 8, // 0x20 DW_FORM_ref_sig8 137 }; 138 139 const uint8_t * 140 DWARFFormValue::GetFixedFormSizesForAddressSize (uint8_t addr_size, bool is_dwarf64) 141 { 142 if (!is_dwarf64) { 143 switch (addr_size) 144 { 145 case 4: return g_form_sizes_addr4; 146 case 8: return g_form_sizes_addr8; 147 } 148 } else { 149 if (addr_size == 8) 150 return g_form_sizes_addr8_dwarf64; 151 // is_dwarf64 && addr_size == 4 : no provider does this. 152 } 153 return NULL; 154 } 155 156 DWARFFormValue::DWARFFormValue(dw_form_t form) : 157 m_form(form), 158 m_value() 159 { 160 } 161 162 bool 163 DWARFFormValue::ExtractValue(const DWARFDataExtractor& data, lldb::offset_t* offset_ptr, const DWARFCompileUnit* cu) 164 { 165 bool indirect = false; 166 bool is_block = false; 167 m_value.data = NULL; 168 uint8_t ref_addr_size; 169 // Read the value for the form into value and follow and DW_FORM_indirect instances we run into 170 do 171 { 172 indirect = false; 173 switch (m_form) 174 { 175 case DW_FORM_addr: m_value.value.uval = data.GetMaxU64(offset_ptr, DWARFCompileUnit::GetAddressByteSize(cu)); break; 176 case DW_FORM_block2: m_value.value.uval = data.GetU16(offset_ptr); is_block = true; break; 177 case DW_FORM_block4: m_value.value.uval = data.GetU32(offset_ptr); is_block = true; break; 178 case DW_FORM_data2: m_value.value.uval = data.GetU16(offset_ptr); break; 179 case DW_FORM_data4: m_value.value.uval = data.GetU32(offset_ptr); break; 180 case DW_FORM_data8: m_value.value.uval = data.GetU64(offset_ptr); break; 181 case DW_FORM_string: m_value.value.cstr = data.GetCStr(offset_ptr); 182 // Set the string value to also be the data for inlined cstr form values only 183 // so we can tell the difference between DW_FORM_string and DW_FORM_strp form 184 // values; 185 m_value.data = (uint8_t*)m_value.value.cstr; break; 186 case DW_FORM_exprloc: 187 case DW_FORM_block: m_value.value.uval = data.GetULEB128(offset_ptr); is_block = true; break; 188 case DW_FORM_block1: m_value.value.uval = data.GetU8(offset_ptr); is_block = true; break; 189 case DW_FORM_data1: m_value.value.uval = data.GetU8(offset_ptr); break; 190 case DW_FORM_flag: m_value.value.uval = data.GetU8(offset_ptr); break; 191 case DW_FORM_sdata: m_value.value.sval = data.GetSLEB128(offset_ptr); break; 192 case DW_FORM_strp: m_value.value.uval = data.GetMaxU64(offset_ptr, DWARFCompileUnit::IsDWARF64(cu) ? 8 : 4); break; 193 // case DW_FORM_APPLE_db_str: 194 case DW_FORM_udata: m_value.value.uval = data.GetULEB128(offset_ptr); break; 195 case DW_FORM_ref_addr: ref_addr_size = 4; 196 if (cu) { 197 if (cu->GetVersion() <= 2) 198 ref_addr_size = cu->GetAddressByteSize(); 199 else 200 ref_addr_size = cu->IsDWARF64() ? 8 : 4; 201 } 202 m_value.value.uval = data.GetMaxU64(offset_ptr, ref_addr_size); break; 203 case DW_FORM_ref1: m_value.value.uval = data.GetU8(offset_ptr); break; 204 case DW_FORM_ref2: m_value.value.uval = data.GetU16(offset_ptr); break; 205 case DW_FORM_ref4: m_value.value.uval = data.GetU32(offset_ptr); break; 206 case DW_FORM_ref8: m_value.value.uval = data.GetU64(offset_ptr); break; 207 case DW_FORM_ref_udata: m_value.value.uval = data.GetULEB128(offset_ptr); break; 208 case DW_FORM_indirect: 209 m_form = data.GetULEB128(offset_ptr); 210 indirect = true; 211 break; 212 213 case DW_FORM_sec_offset: m_value.value.uval = data.GetMaxU64(offset_ptr, DWARFCompileUnit::IsDWARF64(cu) ? 8 : 4); break; 214 case DW_FORM_flag_present: m_value.value.uval = 1; break; 215 case DW_FORM_ref_sig8: m_value.value.uval = data.GetU64(offset_ptr); break; 216 default: 217 return false; 218 break; 219 } 220 } while (indirect); 221 222 if (is_block) 223 { 224 m_value.data = data.PeekData(*offset_ptr, m_value.value.uval); 225 if (m_value.data != NULL) 226 { 227 *offset_ptr += m_value.value.uval; 228 } 229 } 230 231 return true; 232 } 233 234 bool 235 DWARFFormValue::SkipValue(const DWARFDataExtractor& debug_info_data, lldb::offset_t *offset_ptr, const DWARFCompileUnit* cu) const 236 { 237 return DWARFFormValue::SkipValue(m_form, debug_info_data, offset_ptr, cu); 238 } 239 240 bool 241 DWARFFormValue::SkipValue(dw_form_t form, const DWARFDataExtractor& debug_info_data, lldb::offset_t *offset_ptr, const DWARFCompileUnit* cu) 242 { 243 uint8_t ref_addr_size; 244 switch (form) 245 { 246 // Blocks if inlined data that have a length field and the data bytes 247 // inlined in the .debug_info 248 case DW_FORM_exprloc: 249 case DW_FORM_block: { dw_uleb128_t size = debug_info_data.GetULEB128(offset_ptr); *offset_ptr += size; } return true; 250 case DW_FORM_block1: { dw_uleb128_t size = debug_info_data.GetU8(offset_ptr); *offset_ptr += size; } return true; 251 case DW_FORM_block2: { dw_uleb128_t size = debug_info_data.GetU16(offset_ptr); *offset_ptr += size; } return true; 252 case DW_FORM_block4: { dw_uleb128_t size = debug_info_data.GetU32(offset_ptr); *offset_ptr += size; } return true; 253 254 // Inlined NULL terminated C-strings 255 case DW_FORM_string: 256 debug_info_data.GetCStr(offset_ptr); 257 return true; 258 259 // Compile unit address sized values 260 case DW_FORM_addr: 261 *offset_ptr += DWARFCompileUnit::GetAddressByteSize(cu); 262 return true; 263 264 case DW_FORM_ref_addr: 265 ref_addr_size = 4; 266 if (cu) { 267 if (cu->GetVersion() <= 2) 268 ref_addr_size = cu->GetAddressByteSize(); 269 else 270 ref_addr_size = cu->IsDWARF64() ? 8 : 4; 271 } 272 *offset_ptr += ref_addr_size; 273 return true; 274 275 // 0 bytes values (implied from DW_FORM) 276 case DW_FORM_flag_present: 277 return true; 278 279 // 1 byte values 280 case DW_FORM_data1: 281 case DW_FORM_flag: 282 case DW_FORM_ref1: 283 *offset_ptr += 1; 284 return true; 285 286 // 2 byte values 287 case DW_FORM_data2: 288 case DW_FORM_ref2: 289 *offset_ptr += 2; 290 return true; 291 292 // 32 bit for DWARF 32, 64 for DWARF 64 293 case DW_FORM_sec_offset: 294 case DW_FORM_strp: 295 *offset_ptr += (cu->IsDWARF64() ? 8 : 4); 296 return true; 297 298 // 4 byte values 299 case DW_FORM_data4: 300 case DW_FORM_ref4: 301 *offset_ptr += 4; 302 return true; 303 304 // 8 byte values 305 case DW_FORM_data8: 306 case DW_FORM_ref8: 307 case DW_FORM_ref_sig8: 308 *offset_ptr += 8; 309 return true; 310 311 // signed or unsigned LEB 128 values 312 case DW_FORM_sdata: 313 case DW_FORM_udata: 314 case DW_FORM_ref_udata: 315 debug_info_data.Skip_LEB128(offset_ptr); 316 return true; 317 318 case DW_FORM_indirect: 319 { 320 dw_form_t indirect_form = debug_info_data.GetULEB128(offset_ptr); 321 return DWARFFormValue::SkipValue (indirect_form, 322 debug_info_data, 323 offset_ptr, 324 cu); 325 } 326 327 default: 328 break; 329 } 330 return false; 331 } 332 333 334 void 335 DWARFFormValue::Dump(Stream &s, const DWARFDataExtractor* debug_str_data, const DWARFCompileUnit* cu) const 336 { 337 uint64_t uvalue = Unsigned(); 338 bool cu_relative_offset = false; 339 340 bool verbose = s.GetVerbose(); 341 342 switch (m_form) 343 { 344 case DW_FORM_addr: s.Address(uvalue, sizeof (uint64_t)); break; 345 case DW_FORM_flag: 346 case DW_FORM_data1: s.PutHex8(uvalue); break; 347 case DW_FORM_data2: s.PutHex16(uvalue); break; 348 case DW_FORM_sec_offset: 349 case DW_FORM_data4: s.PutHex32(uvalue); break; 350 case DW_FORM_ref_sig8: 351 case DW_FORM_data8: s.PutHex64(uvalue); break; 352 case DW_FORM_string: s.QuotedCString(AsCString(NULL)); break; 353 case DW_FORM_exprloc: 354 case DW_FORM_block: 355 case DW_FORM_block1: 356 case DW_FORM_block2: 357 case DW_FORM_block4: 358 if (uvalue > 0) 359 { 360 switch (m_form) 361 { 362 case DW_FORM_exprloc: 363 case DW_FORM_block: s.Printf("<0x%" PRIx64 "> ", uvalue); break; 364 case DW_FORM_block1: s.Printf("<0x%2.2x> ", (uint8_t)uvalue); break; 365 case DW_FORM_block2: s.Printf("<0x%4.4x> ", (uint16_t)uvalue); break; 366 case DW_FORM_block4: s.Printf("<0x%8.8x> ", (uint32_t)uvalue); break; 367 default: break; 368 } 369 370 const uint8_t* data_ptr = m_value.data; 371 if (data_ptr) 372 { 373 const uint8_t* end_data_ptr = data_ptr + uvalue; // uvalue contains size of block 374 while (data_ptr < end_data_ptr) 375 { 376 s.Printf("%2.2x ", *data_ptr); 377 ++data_ptr; 378 } 379 } 380 else 381 s.PutCString("NULL"); 382 } 383 break; 384 385 case DW_FORM_sdata: s.PutSLEB128(uvalue); break; 386 case DW_FORM_udata: s.PutULEB128(uvalue); break; 387 case DW_FORM_strp: 388 if (debug_str_data) 389 { 390 if (verbose) 391 s.Printf(" .debug_str[0x%8.8x] = ", (uint32_t)uvalue); 392 393 const char* dbg_str = AsCString(debug_str_data); 394 if (dbg_str) 395 s.QuotedCString(dbg_str); 396 } 397 else 398 { 399 s.PutHex32(uvalue); 400 } 401 break; 402 403 case DW_FORM_ref_addr: 404 { 405 if (cu->GetVersion() <= 2) 406 s.Address(uvalue, sizeof (uint64_t) * 2); 407 else 408 s.Address(uvalue, 4 * 2);// 4 for DWARF32, 8 for DWARF64, but we don't support DWARF64 yet 409 break; 410 } 411 case DW_FORM_ref1: cu_relative_offset = true; if (verbose) s.Printf("cu + 0x%2.2x", (uint8_t)uvalue); break; 412 case DW_FORM_ref2: cu_relative_offset = true; if (verbose) s.Printf("cu + 0x%4.4x", (uint16_t)uvalue); break; 413 case DW_FORM_ref4: cu_relative_offset = true; if (verbose) s.Printf("cu + 0x%4.4x", (uint32_t)uvalue); break; 414 case DW_FORM_ref8: cu_relative_offset = true; if (verbose) s.Printf("cu + 0x%8.8" PRIx64, uvalue); break; 415 case DW_FORM_ref_udata: cu_relative_offset = true; if (verbose) s.Printf("cu + 0x%" PRIx64, uvalue); break; 416 417 // All DW_FORM_indirect attributes should be resolved prior to calling this function 418 case DW_FORM_indirect: s.PutCString("DW_FORM_indirect"); break; 419 case DW_FORM_flag_present: break; 420 default: 421 s.Printf("DW_FORM(0x%4.4x)", m_form); 422 break; 423 } 424 425 if (cu_relative_offset) 426 { 427 if (verbose) 428 s.PutCString(" => "); 429 430 s.Printf("{0x%8.8" PRIx64 "}", (uvalue + (cu ? cu->GetOffset() : 0))); 431 } 432 } 433 434 const char* 435 DWARFFormValue::AsCString(const DWARFDataExtractor* debug_str_data_ptr) const 436 { 437 if (IsInlinedCStr()) 438 return m_value.value.cstr; 439 else if (debug_str_data_ptr) 440 return debug_str_data_ptr->PeekCStr(m_value.value.uval); 441 return NULL; 442 } 443 444 uint64_t 445 DWARFFormValue::Reference(const DWARFCompileUnit* cu) const 446 { 447 uint64_t die_offset = m_value.value.uval; 448 switch (m_form) 449 { 450 case DW_FORM_ref1: 451 case DW_FORM_ref2: 452 case DW_FORM_ref4: 453 case DW_FORM_ref8: 454 case DW_FORM_ref_udata: 455 die_offset += (cu ? cu->GetOffset() : 0); 456 break; 457 458 default: 459 break; 460 } 461 462 return die_offset; 463 } 464 465 uint64_t 466 DWARFFormValue::Reference (dw_offset_t base_offset) const 467 { 468 uint64_t die_offset = m_value.value.uval; 469 switch (m_form) 470 { 471 case DW_FORM_ref1: 472 case DW_FORM_ref2: 473 case DW_FORM_ref4: 474 case DW_FORM_ref8: 475 case DW_FORM_ref_udata: 476 die_offset += base_offset; 477 break; 478 479 default: 480 break; 481 } 482 483 return die_offset; 484 } 485 486 //---------------------------------------------------------------------- 487 // Resolve any compile unit specific references so that we don't need 488 // the compile unit at a later time in order to work with the form 489 // value. 490 //---------------------------------------------------------------------- 491 bool 492 DWARFFormValue::ResolveCompileUnitReferences(const DWARFCompileUnit* cu) 493 { 494 switch (m_form) 495 { 496 case DW_FORM_ref1: 497 case DW_FORM_ref2: 498 case DW_FORM_ref4: 499 case DW_FORM_ref8: 500 case DW_FORM_ref_udata: 501 m_value.value.uval += cu->GetOffset(); 502 m_form = DW_FORM_ref_addr; 503 return true; 504 break; 505 506 default: 507 break; 508 } 509 510 return false; 511 } 512 513 const uint8_t* 514 DWARFFormValue::BlockData() const 515 { 516 if (!IsInlinedCStr()) 517 return m_value.data; 518 return NULL; 519 } 520 521 522 bool 523 DWARFFormValue::IsBlockForm(const dw_form_t form) 524 { 525 switch (form) 526 { 527 case DW_FORM_block: 528 case DW_FORM_block1: 529 case DW_FORM_block2: 530 case DW_FORM_block4: 531 return true; 532 } 533 return false; 534 } 535 536 bool 537 DWARFFormValue::IsDataForm(const dw_form_t form) 538 { 539 switch (form) 540 { 541 case DW_FORM_sdata: 542 case DW_FORM_udata: 543 case DW_FORM_data1: 544 case DW_FORM_data2: 545 case DW_FORM_data4: 546 case DW_FORM_data8: 547 return true; 548 } 549 return false; 550 } 551 552 int 553 DWARFFormValue::Compare (const DWARFFormValue& a_value, const DWARFFormValue& b_value, const DWARFCompileUnit* a_cu, const DWARFCompileUnit* b_cu, const DWARFDataExtractor* debug_str_data_ptr) 554 { 555 dw_form_t a_form = a_value.Form(); 556 dw_form_t b_form = b_value.Form(); 557 if (a_form < b_form) 558 return -1; 559 if (a_form > b_form) 560 return 1; 561 switch (a_form) 562 { 563 case DW_FORM_addr: 564 case DW_FORM_flag: 565 case DW_FORM_data1: 566 case DW_FORM_data2: 567 case DW_FORM_data4: 568 case DW_FORM_data8: 569 case DW_FORM_udata: 570 case DW_FORM_ref_addr: 571 case DW_FORM_sec_offset: 572 case DW_FORM_flag_present: 573 case DW_FORM_ref_sig8: 574 { 575 uint64_t a = a_value.Unsigned(); 576 uint64_t b = b_value.Unsigned(); 577 if (a < b) 578 return -1; 579 if (a > b) 580 return 1; 581 return 0; 582 } 583 584 case DW_FORM_sdata: 585 { 586 int64_t a = a_value.Signed(); 587 int64_t b = b_value.Signed(); 588 if (a < b) 589 return -1; 590 if (a > b) 591 return 1; 592 return 0; 593 } 594 595 case DW_FORM_string: 596 case DW_FORM_strp: 597 { 598 const char *a_string = a_value.AsCString(debug_str_data_ptr); 599 const char *b_string = b_value.AsCString(debug_str_data_ptr); 600 if (a_string == b_string) 601 return 0; 602 else if (a_string && b_string) 603 return strcmp(a_string, b_string); 604 else if (a_string == NULL) 605 return -1; // A string is NULL, and B is valid 606 else 607 return 1; // A string valid, and B is NULL 608 } 609 610 611 case DW_FORM_block: 612 case DW_FORM_block1: 613 case DW_FORM_block2: 614 case DW_FORM_block4: 615 case DW_FORM_exprloc: 616 { 617 uint64_t a_len = a_value.Unsigned(); 618 uint64_t b_len = b_value.Unsigned(); 619 if (a_len < b_len) 620 return -1; 621 if (a_len > b_len) 622 return 1; 623 // The block lengths are the same 624 return memcmp(a_value.BlockData(), b_value.BlockData(), a_value.Unsigned()); 625 } 626 break; 627 628 case DW_FORM_ref1: 629 case DW_FORM_ref2: 630 case DW_FORM_ref4: 631 case DW_FORM_ref8: 632 case DW_FORM_ref_udata: 633 { 634 uint64_t a = a_value.Reference(a_cu); 635 uint64_t b = b_value.Reference(b_cu); 636 if (a < b) 637 return -1; 638 if (a > b) 639 return 1; 640 return 0; 641 } 642 643 case DW_FORM_indirect: 644 assert(!"This shouldn't happen after the form has been extracted..."); 645 break; 646 647 default: 648 assert(!"Unhandled DW_FORM"); 649 break; 650 } 651 return -1; 652 } 653 654