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 const uint8_t * 100 DWARFFormValue::GetFixedFormSizesForAddressSize (uint8_t addr_size) 101 { 102 switch (addr_size) 103 { 104 case 4: return g_form_sizes_addr4; 105 case 8: return g_form_sizes_addr8; 106 } 107 return NULL; 108 } 109 110 DWARFFormValue::DWARFFormValue(dw_form_t form) : 111 m_form(form), 112 m_value() 113 { 114 } 115 116 bool 117 DWARFFormValue::ExtractValue(const DataExtractor& data, lldb::offset_t* offset_ptr, const DWARFCompileUnit* cu) 118 { 119 bool indirect = false; 120 bool is_block = false; 121 m_value.data = NULL; 122 // Read the value for the form into value and follow and DW_FORM_indirect instances we run into 123 do 124 { 125 indirect = false; 126 switch (m_form) 127 { 128 case DW_FORM_addr: m_value.value.uval = data.GetMaxU64(offset_ptr, DWARFCompileUnit::GetAddressByteSize(cu)); break; 129 case DW_FORM_block2: m_value.value.uval = data.GetU16(offset_ptr); is_block = true; break; 130 case DW_FORM_block4: m_value.value.uval = data.GetU32(offset_ptr); is_block = true; break; 131 case DW_FORM_data2: m_value.value.uval = data.GetU16(offset_ptr); break; 132 case DW_FORM_data4: m_value.value.uval = data.GetU32(offset_ptr); break; 133 case DW_FORM_data8: m_value.value.uval = data.GetU64(offset_ptr); break; 134 case DW_FORM_string: m_value.value.cstr = data.GetCStr(offset_ptr); 135 // Set the string value to also be the data for inlined cstr form values only 136 // so we can tell the differnence between DW_FORM_string and DW_FORM_strp form 137 // values; 138 m_value.data = (uint8_t*)m_value.value.cstr; break; 139 case DW_FORM_exprloc: 140 case DW_FORM_block: m_value.value.uval = data.GetULEB128(offset_ptr); is_block = true; break; 141 case DW_FORM_block1: m_value.value.uval = data.GetU8(offset_ptr); is_block = true; break; 142 case DW_FORM_data1: m_value.value.uval = data.GetU8(offset_ptr); break; 143 case DW_FORM_flag: m_value.value.uval = data.GetU8(offset_ptr); break; 144 case DW_FORM_sdata: m_value.value.sval = data.GetSLEB128(offset_ptr); break; 145 case DW_FORM_strp: m_value.value.uval = data.GetU32(offset_ptr); break; 146 // case DW_FORM_APPLE_db_str: 147 case DW_FORM_udata: m_value.value.uval = data.GetULEB128(offset_ptr); break; 148 case DW_FORM_ref_addr: 149 if (cu->GetVersion() <= 2) 150 m_value.value.uval = data.GetMaxU64(offset_ptr, DWARFCompileUnit::GetAddressByteSize(cu)); 151 else 152 m_value.value.uval = data.GetU32(offset_ptr); // 4 for DWARF32, 8 for DWARF64, but we don't support DWARF64 yet 153 break; 154 case DW_FORM_ref1: m_value.value.uval = data.GetU8(offset_ptr); break; 155 case DW_FORM_ref2: m_value.value.uval = data.GetU16(offset_ptr); break; 156 case DW_FORM_ref4: m_value.value.uval = data.GetU32(offset_ptr); break; 157 case DW_FORM_ref8: m_value.value.uval = data.GetU64(offset_ptr); break; 158 case DW_FORM_ref_udata: m_value.value.uval = data.GetULEB128(offset_ptr); break; 159 case DW_FORM_indirect: 160 m_form = data.GetULEB128(offset_ptr); 161 indirect = true; 162 break; 163 164 case DW_FORM_sec_offset: m_value.value.uval = data.GetU32(offset_ptr); break; 165 case DW_FORM_flag_present: m_value.value.uval = 1; break; 166 case DW_FORM_ref_sig8: m_value.value.uval = data.GetU64(offset_ptr); break; 167 default: 168 return false; 169 break; 170 } 171 } while (indirect); 172 173 if (is_block) 174 { 175 m_value.data = data.PeekData(*offset_ptr, m_value.value.uval); 176 if (m_value.data != NULL) 177 { 178 *offset_ptr += m_value.value.uval; 179 } 180 } 181 182 return true; 183 } 184 185 bool 186 DWARFFormValue::SkipValue(const DataExtractor& debug_info_data, lldb::offset_t *offset_ptr, const DWARFCompileUnit* cu) const 187 { 188 return DWARFFormValue::SkipValue(m_form, debug_info_data, offset_ptr, cu); 189 } 190 191 bool 192 DWARFFormValue::SkipValue(dw_form_t form, const DataExtractor& debug_info_data, lldb::offset_t *offset_ptr, const DWARFCompileUnit* cu) 193 { 194 switch (form) 195 { 196 // Blocks if inlined data that have a length field and the data bytes 197 // inlined in the .debug_info 198 case DW_FORM_exprloc: 199 case DW_FORM_block: { dw_uleb128_t size = debug_info_data.GetULEB128(offset_ptr); *offset_ptr += size; } return true; 200 case DW_FORM_block1: { dw_uleb128_t size = debug_info_data.GetU8(offset_ptr); *offset_ptr += size; } return true; 201 case DW_FORM_block2: { dw_uleb128_t size = debug_info_data.GetU16(offset_ptr); *offset_ptr += size; } return true; 202 case DW_FORM_block4: { dw_uleb128_t size = debug_info_data.GetU32(offset_ptr); *offset_ptr += size; } return true; 203 204 // Inlined NULL terminated C-strings 205 case DW_FORM_string: 206 debug_info_data.GetCStr(offset_ptr); 207 return true; 208 209 // Compile unit address sized values 210 case DW_FORM_addr: 211 *offset_ptr += DWARFCompileUnit::GetAddressByteSize(cu); 212 return true; 213 214 case DW_FORM_ref_addr: 215 if (cu->GetVersion() <= 2) 216 *offset_ptr += DWARFCompileUnit::GetAddressByteSize(cu); 217 else 218 *offset_ptr += 4;// 4 for DWARF32, 8 for DWARF64, but we don't support DWARF64 yet 219 return true; 220 221 // 0 bytes values (implied from DW_FORM) 222 case DW_FORM_flag_present: 223 return true; 224 225 // 1 byte values 226 case DW_FORM_data1: 227 case DW_FORM_flag: 228 case DW_FORM_ref1: 229 *offset_ptr += 1; 230 return true; 231 232 // 2 byte values 233 case DW_FORM_data2: 234 case DW_FORM_ref2: 235 *offset_ptr += 2; 236 return true; 237 238 // 32 bit for DWARF 32, 64 for DWARF 64 239 case DW_FORM_sec_offset: 240 *offset_ptr += 4; 241 return true; 242 243 // 4 byte values 244 case DW_FORM_strp: 245 case DW_FORM_data4: 246 case DW_FORM_ref4: 247 *offset_ptr += 4; 248 return true; 249 250 // 8 byte values 251 case DW_FORM_data8: 252 case DW_FORM_ref8: 253 case DW_FORM_ref_sig8: 254 *offset_ptr += 8; 255 return true; 256 257 // signed or unsigned LEB 128 values 258 case DW_FORM_sdata: 259 case DW_FORM_udata: 260 case DW_FORM_ref_udata: 261 debug_info_data.Skip_LEB128(offset_ptr); 262 return true; 263 264 case DW_FORM_indirect: 265 { 266 dw_form_t indirect_form = debug_info_data.GetULEB128(offset_ptr); 267 return DWARFFormValue::SkipValue (indirect_form, 268 debug_info_data, 269 offset_ptr, 270 cu); 271 } 272 273 default: 274 break; 275 } 276 return false; 277 } 278 279 280 void 281 DWARFFormValue::Dump(Stream &s, const DataExtractor* debug_str_data, const DWARFCompileUnit* cu) const 282 { 283 uint64_t uvalue = Unsigned(); 284 bool cu_relative_offset = false; 285 286 bool verbose = s.GetVerbose(); 287 288 switch (m_form) 289 { 290 case DW_FORM_addr: s.Address(uvalue, sizeof (uint64_t)); break; 291 case DW_FORM_flag: 292 case DW_FORM_data1: s.PutHex8(uvalue); break; 293 case DW_FORM_data2: s.PutHex16(uvalue); break; 294 case DW_FORM_sec_offset: 295 case DW_FORM_data4: s.PutHex32(uvalue); break; 296 case DW_FORM_ref_sig8: 297 case DW_FORM_data8: s.PutHex64(uvalue); break; 298 case DW_FORM_string: s.QuotedCString(AsCString(NULL)); break; 299 case DW_FORM_exprloc: 300 case DW_FORM_block: 301 case DW_FORM_block1: 302 case DW_FORM_block2: 303 case DW_FORM_block4: 304 if (uvalue > 0) 305 { 306 switch (m_form) 307 { 308 case DW_FORM_exprloc: 309 case DW_FORM_block: s.Printf("<0x%" PRIx64 "> ", uvalue); break; 310 case DW_FORM_block1: s.Printf("<0x%2.2x> ", (uint8_t)uvalue); break; 311 case DW_FORM_block2: s.Printf("<0x%4.4x> ", (uint16_t)uvalue); break; 312 case DW_FORM_block4: s.Printf("<0x%8.8x> ", (uint32_t)uvalue); break; 313 default: break; 314 } 315 316 const uint8_t* data_ptr = m_value.data; 317 if (data_ptr) 318 { 319 const uint8_t* end_data_ptr = data_ptr + uvalue; // uvalue contains size of block 320 while (data_ptr < end_data_ptr) 321 { 322 s.Printf("%2.2x ", *data_ptr); 323 ++data_ptr; 324 } 325 } 326 else 327 s.PutCString("NULL"); 328 } 329 break; 330 331 case DW_FORM_sdata: s.PutSLEB128(uvalue); break; 332 case DW_FORM_udata: s.PutULEB128(uvalue); break; 333 case DW_FORM_strp: 334 if (debug_str_data) 335 { 336 if (verbose) 337 s.Printf(" .debug_str[0x%8.8x] = ", (uint32_t)uvalue); 338 339 const char* dbg_str = AsCString(debug_str_data); 340 if (dbg_str) 341 s.QuotedCString(dbg_str); 342 } 343 else 344 { 345 s.PutHex32(uvalue); 346 } 347 break; 348 349 case DW_FORM_ref_addr: 350 { 351 if (cu->GetVersion() <= 2) 352 s.Address(uvalue, sizeof (uint64_t) * 2); 353 else 354 s.Address(uvalue, 4 * 2);// 4 for DWARF32, 8 for DWARF64, but we don't support DWARF64 yet 355 break; 356 } 357 case DW_FORM_ref1: cu_relative_offset = true; if (verbose) s.Printf("cu + 0x%2.2x", (uint8_t)uvalue); break; 358 case DW_FORM_ref2: cu_relative_offset = true; if (verbose) s.Printf("cu + 0x%4.4x", (uint16_t)uvalue); break; 359 case DW_FORM_ref4: cu_relative_offset = true; if (verbose) s.Printf("cu + 0x%4.4x", (uint32_t)uvalue); break; 360 case DW_FORM_ref8: cu_relative_offset = true; if (verbose) s.Printf("cu + 0x%8.8" PRIx64, uvalue); break; 361 case DW_FORM_ref_udata: cu_relative_offset = true; if (verbose) s.Printf("cu + 0x%" PRIx64, uvalue); break; 362 363 // All DW_FORM_indirect attributes should be resolved prior to calling this function 364 case DW_FORM_indirect: s.PutCString("DW_FORM_indirect"); break; 365 case DW_FORM_flag_present: break; 366 default: 367 s.Printf("DW_FORM(0x%4.4x)", m_form); 368 break; 369 } 370 371 if (cu_relative_offset) 372 { 373 if (verbose) 374 s.PutCString(" => "); 375 376 s.Printf("{0x%8.8" PRIx64 "}", (uvalue + (cu ? cu->GetOffset() : 0))); 377 } 378 } 379 380 const char* 381 DWARFFormValue::AsCString(const DataExtractor* debug_str_data_ptr) const 382 { 383 if (IsInlinedCStr()) 384 return m_value.value.cstr; 385 else if (debug_str_data_ptr) 386 return debug_str_data_ptr->PeekCStr(m_value.value.uval); 387 return NULL; 388 } 389 390 uint64_t 391 DWARFFormValue::Reference(const DWARFCompileUnit* cu) const 392 { 393 uint64_t die_offset = m_value.value.uval; 394 switch (m_form) 395 { 396 case DW_FORM_ref1: 397 case DW_FORM_ref2: 398 case DW_FORM_ref4: 399 case DW_FORM_ref8: 400 case DW_FORM_ref_udata: 401 die_offset += (cu ? cu->GetOffset() : 0); 402 break; 403 404 default: 405 break; 406 } 407 408 return die_offset; 409 } 410 411 uint64_t 412 DWARFFormValue::Reference (dw_offset_t base_offset) const 413 { 414 uint64_t die_offset = m_value.value.uval; 415 switch (m_form) 416 { 417 case DW_FORM_ref1: 418 case DW_FORM_ref2: 419 case DW_FORM_ref4: 420 case DW_FORM_ref8: 421 case DW_FORM_ref_udata: 422 die_offset += base_offset; 423 break; 424 425 default: 426 break; 427 } 428 429 return die_offset; 430 } 431 432 //---------------------------------------------------------------------- 433 // Resolve any compile unit specific references so that we don't need 434 // the compile unit at a later time in order to work with the form 435 // value. 436 //---------------------------------------------------------------------- 437 bool 438 DWARFFormValue::ResolveCompileUnitReferences(const DWARFCompileUnit* cu) 439 { 440 switch (m_form) 441 { 442 case DW_FORM_ref1: 443 case DW_FORM_ref2: 444 case DW_FORM_ref4: 445 case DW_FORM_ref8: 446 case DW_FORM_ref_udata: 447 m_value.value.uval += cu->GetOffset(); 448 m_form = DW_FORM_ref_addr; 449 return true; 450 break; 451 452 default: 453 break; 454 } 455 456 return false; 457 } 458 459 const uint8_t* 460 DWARFFormValue::BlockData() const 461 { 462 if (!IsInlinedCStr()) 463 return m_value.data; 464 return NULL; 465 } 466 467 468 bool 469 DWARFFormValue::IsBlockForm(const dw_form_t form) 470 { 471 switch (form) 472 { 473 case DW_FORM_block: 474 case DW_FORM_block1: 475 case DW_FORM_block2: 476 case DW_FORM_block4: 477 return true; 478 } 479 return false; 480 } 481 482 bool 483 DWARFFormValue::IsDataForm(const dw_form_t form) 484 { 485 switch (form) 486 { 487 case DW_FORM_sdata: 488 case DW_FORM_udata: 489 case DW_FORM_data1: 490 case DW_FORM_data2: 491 case DW_FORM_data4: 492 case DW_FORM_data8: 493 return true; 494 } 495 return false; 496 } 497 498 int 499 DWARFFormValue::Compare (const DWARFFormValue& a_value, const DWARFFormValue& b_value, const DWARFCompileUnit* a_cu, const DWARFCompileUnit* b_cu, const DataExtractor* debug_str_data_ptr) 500 { 501 dw_form_t a_form = a_value.Form(); 502 dw_form_t b_form = b_value.Form(); 503 if (a_form < b_form) 504 return -1; 505 if (a_form > b_form) 506 return 1; 507 switch (a_form) 508 { 509 case DW_FORM_addr: 510 case DW_FORM_flag: 511 case DW_FORM_data1: 512 case DW_FORM_data2: 513 case DW_FORM_data4: 514 case DW_FORM_data8: 515 case DW_FORM_udata: 516 case DW_FORM_ref_addr: 517 case DW_FORM_sec_offset: 518 case DW_FORM_flag_present: 519 case DW_FORM_ref_sig8: 520 { 521 uint64_t a = a_value.Unsigned(); 522 uint64_t b = b_value.Unsigned(); 523 if (a < b) 524 return -1; 525 if (a > b) 526 return 1; 527 return 0; 528 } 529 530 case DW_FORM_sdata: 531 { 532 int64_t a = a_value.Signed(); 533 int64_t b = b_value.Signed(); 534 if (a < b) 535 return -1; 536 if (a > b) 537 return 1; 538 return 0; 539 } 540 541 case DW_FORM_string: 542 case DW_FORM_strp: 543 { 544 const char *a_string = a_value.AsCString(debug_str_data_ptr); 545 const char *b_string = b_value.AsCString(debug_str_data_ptr); 546 if (a_string == b_string) 547 return 0; 548 else if (a_string && b_string) 549 return strcmp(a_string, b_string); 550 else if (a_string == NULL) 551 return -1; // A string is NULL, and B is valid 552 else 553 return 1; // A string valid, and B is NULL 554 } 555 556 557 case DW_FORM_block: 558 case DW_FORM_block1: 559 case DW_FORM_block2: 560 case DW_FORM_block4: 561 case DW_FORM_exprloc: 562 { 563 uint64_t a_len = a_value.Unsigned(); 564 uint64_t b_len = b_value.Unsigned(); 565 if (a_len < b_len) 566 return -1; 567 if (a_len > b_len) 568 return 1; 569 // The block lengths are the same 570 return memcmp(a_value.BlockData(), b_value.BlockData(), a_value.Unsigned()); 571 } 572 break; 573 574 case DW_FORM_ref1: 575 case DW_FORM_ref2: 576 case DW_FORM_ref4: 577 case DW_FORM_ref8: 578 case DW_FORM_ref_udata: 579 { 580 uint64_t a = a_value.Reference(a_cu); 581 uint64_t b = b_value.Reference(b_cu); 582 if (a < b) 583 return -1; 584 if (a > b) 585 return 1; 586 return 0; 587 } 588 589 case DW_FORM_indirect: 590 assert(!"This shouldn't happen after the form has been extracted..."); 591 break; 592 593 default: 594 assert(!"Unhandled DW_FORM"); 595 break; 596 } 597 return -1; 598 } 599 600