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/Utility/Stream.h" 14 15 #include "DWARFUnit.h" 16 #include "DWARFFormValue.h" 17 18 class DWARFUnit; 19 20 using namespace lldb_private; 21 22 static uint8_t g_form_sizes_addr4[] = { 23 0, // 0x00 unused 24 4, // 0x01 DW_FORM_addr 25 0, // 0x02 unused 26 0, // 0x03 DW_FORM_block2 27 0, // 0x04 DW_FORM_block4 28 2, // 0x05 DW_FORM_data2 29 4, // 0x06 DW_FORM_data4 30 8, // 0x07 DW_FORM_data8 31 0, // 0x08 DW_FORM_string 32 0, // 0x09 DW_FORM_block 33 0, // 0x0a DW_FORM_block1 34 1, // 0x0b DW_FORM_data1 35 1, // 0x0c DW_FORM_flag 36 0, // 0x0d DW_FORM_sdata 37 4, // 0x0e DW_FORM_strp 38 0, // 0x0f DW_FORM_udata 39 0, // 0x10 DW_FORM_ref_addr (addr size for DWARF2 and earlier, 4 bytes for 40 // DWARF32, 8 bytes for DWARF32 in DWARF 3 and later 41 1, // 0x11 DW_FORM_ref1 42 2, // 0x12 DW_FORM_ref2 43 4, // 0x13 DW_FORM_ref4 44 8, // 0x14 DW_FORM_ref8 45 0, // 0x15 DW_FORM_ref_udata 46 0, // 0x16 DW_FORM_indirect 47 4, // 0x17 DW_FORM_sec_offset 48 0, // 0x18 DW_FORM_exprloc 49 0, // 0x19 DW_FORM_flag_present 50 0, // 0x1a 51 0, // 0x1b 52 0, // 0x1c 53 0, // 0x1d 54 0, // 0x1e 55 0, // 0x1f 56 8, // 0x20 DW_FORM_ref_sig8 57 58 }; 59 60 static uint8_t g_form_sizes_addr8[] = { 61 0, // 0x00 unused 62 8, // 0x01 DW_FORM_addr 63 0, // 0x02 unused 64 0, // 0x03 DW_FORM_block2 65 0, // 0x04 DW_FORM_block4 66 2, // 0x05 DW_FORM_data2 67 4, // 0x06 DW_FORM_data4 68 8, // 0x07 DW_FORM_data8 69 0, // 0x08 DW_FORM_string 70 0, // 0x09 DW_FORM_block 71 0, // 0x0a DW_FORM_block1 72 1, // 0x0b DW_FORM_data1 73 1, // 0x0c DW_FORM_flag 74 0, // 0x0d DW_FORM_sdata 75 4, // 0x0e DW_FORM_strp 76 0, // 0x0f DW_FORM_udata 77 0, // 0x10 DW_FORM_ref_addr (addr size for DWARF2 and earlier, 4 bytes for 78 // DWARF32, 8 bytes for DWARF32 in DWARF 3 and later 79 1, // 0x11 DW_FORM_ref1 80 2, // 0x12 DW_FORM_ref2 81 4, // 0x13 DW_FORM_ref4 82 8, // 0x14 DW_FORM_ref8 83 0, // 0x15 DW_FORM_ref_udata 84 0, // 0x16 DW_FORM_indirect 85 4, // 0x17 DW_FORM_sec_offset 86 0, // 0x18 DW_FORM_exprloc 87 0, // 0x19 DW_FORM_flag_present 88 0, // 0x1a 89 0, // 0x1b 90 0, // 0x1c 91 0, // 0x1d 92 0, // 0x1e 93 0, // 0x1f 94 8, // 0x20 DW_FORM_ref_sig8 95 }; 96 97 // Difference with g_form_sizes_addr8: 98 // DW_FORM_strp and DW_FORM_sec_offset are 8 instead of 4 99 static uint8_t g_form_sizes_addr8_dwarf64[] = { 100 0, // 0x00 unused 101 8, // 0x01 DW_FORM_addr 102 0, // 0x02 unused 103 0, // 0x03 DW_FORM_block2 104 0, // 0x04 DW_FORM_block4 105 2, // 0x05 DW_FORM_data2 106 4, // 0x06 DW_FORM_data4 107 8, // 0x07 DW_FORM_data8 108 0, // 0x08 DW_FORM_string 109 0, // 0x09 DW_FORM_block 110 0, // 0x0a DW_FORM_block1 111 1, // 0x0b DW_FORM_data1 112 1, // 0x0c DW_FORM_flag 113 0, // 0x0d DW_FORM_sdata 114 8, // 0x0e DW_FORM_strp 115 0, // 0x0f DW_FORM_udata 116 0, // 0x10 DW_FORM_ref_addr (addr size for DWARF2 and earlier, 4 bytes for 117 // DWARF32, 8 bytes for DWARF32 in DWARF 3 and later 118 1, // 0x11 DW_FORM_ref1 119 2, // 0x12 DW_FORM_ref2 120 4, // 0x13 DW_FORM_ref4 121 8, // 0x14 DW_FORM_ref8 122 0, // 0x15 DW_FORM_ref_udata 123 0, // 0x16 DW_FORM_indirect 124 8, // 0x17 DW_FORM_sec_offset 125 0, // 0x18 DW_FORM_exprloc 126 0, // 0x19 DW_FORM_flag_present 127 0, // 0x1a 128 0, // 0x1b 129 0, // 0x1c 130 0, // 0x1d 131 0, // 0x1e 132 0, // 0x1f 133 8, // 0x20 DW_FORM_ref_sig8 134 }; 135 136 DWARFFormValue::FixedFormSizes 137 DWARFFormValue::GetFixedFormSizesForAddressSize(uint8_t addr_size, 138 bool is_dwarf64) { 139 if (!is_dwarf64) { 140 switch (addr_size) { 141 case 4: 142 return FixedFormSizes(g_form_sizes_addr4, sizeof(g_form_sizes_addr4)); 143 case 8: 144 return FixedFormSizes(g_form_sizes_addr8, sizeof(g_form_sizes_addr8)); 145 } 146 } else { 147 if (addr_size == 8) 148 return FixedFormSizes(g_form_sizes_addr8_dwarf64, 149 sizeof(g_form_sizes_addr8_dwarf64)); 150 // is_dwarf64 && addr_size == 4 : no provider does this. 151 } 152 return FixedFormSizes(); 153 } 154 155 DWARFFormValue::DWARFFormValue() : m_cu(NULL), m_form(0), m_value() {} 156 157 DWARFFormValue::DWARFFormValue(const DWARFUnit *cu) 158 : m_cu(cu), m_form(0), m_value() {} 159 160 DWARFFormValue::DWARFFormValue(const DWARFUnit *cu, dw_form_t form) 161 : m_cu(cu), m_form(form), m_value() {} 162 163 void DWARFFormValue::Clear() { 164 m_cu = nullptr; 165 m_form = 0; 166 memset(&m_value, 0, sizeof(m_value)); 167 } 168 169 bool DWARFFormValue::ExtractValue(const DWARFDataExtractor &data, 170 lldb::offset_t *offset_ptr) { 171 if (m_form == DW_FORM_implicit_const) 172 return true; 173 174 bool indirect = false; 175 bool is_block = false; 176 m_value.data = NULL; 177 uint8_t ref_addr_size; 178 // Read the value for the form into value and follow and DW_FORM_indirect 179 // instances we run into 180 do { 181 indirect = false; 182 switch (m_form) { 183 case DW_FORM_addr: 184 assert(m_cu); 185 m_value.value.uval = data.GetMaxU64( 186 offset_ptr, DWARFUnit::GetAddressByteSize(m_cu)); 187 break; 188 case DW_FORM_block2: 189 m_value.value.uval = data.GetU16(offset_ptr); 190 is_block = true; 191 break; 192 case DW_FORM_block4: 193 m_value.value.uval = data.GetU32(offset_ptr); 194 is_block = true; 195 break; 196 case DW_FORM_data2: 197 m_value.value.uval = data.GetU16(offset_ptr); 198 break; 199 case DW_FORM_data4: 200 m_value.value.uval = data.GetU32(offset_ptr); 201 break; 202 case DW_FORM_data8: 203 m_value.value.uval = data.GetU64(offset_ptr); 204 break; 205 case DW_FORM_data16: 206 m_value.value.uval = 16; 207 is_block = true; 208 break; 209 case DW_FORM_string: 210 m_value.value.cstr = data.GetCStr(offset_ptr); 211 break; 212 case DW_FORM_exprloc: 213 case DW_FORM_block: 214 m_value.value.uval = data.GetULEB128(offset_ptr); 215 is_block = true; 216 break; 217 case DW_FORM_block1: 218 m_value.value.uval = data.GetU8(offset_ptr); 219 is_block = true; 220 break; 221 case DW_FORM_data1: 222 m_value.value.uval = data.GetU8(offset_ptr); 223 break; 224 case DW_FORM_flag: 225 m_value.value.uval = data.GetU8(offset_ptr); 226 break; 227 case DW_FORM_sdata: 228 m_value.value.sval = data.GetSLEB128(offset_ptr); 229 break; 230 case DW_FORM_strp: 231 case DW_FORM_line_strp: 232 assert(m_cu); 233 m_value.value.uval = 234 data.GetMaxU64(offset_ptr, DWARFUnit::IsDWARF64(m_cu) ? 8 : 4); 235 break; 236 case DW_FORM_strx: 237 m_value.value.uval = data.GetULEB128(offset_ptr); 238 break; 239 case DW_FORM_strx1: 240 m_value.value.uval = data.GetU8(offset_ptr); 241 break; 242 case DW_FORM_strx2: 243 m_value.value.uval = data.GetU16(offset_ptr); 244 break; 245 case DW_FORM_strx3: 246 m_value.value.uval = data.GetMaxU64(offset_ptr, 3); 247 break; 248 case DW_FORM_strx4: 249 m_value.value.uval = data.GetU32(offset_ptr); 250 break; 251 // case DW_FORM_APPLE_db_str: 252 case DW_FORM_udata: 253 m_value.value.uval = data.GetULEB128(offset_ptr); 254 break; 255 case DW_FORM_ref_addr: 256 assert(m_cu); 257 ref_addr_size = 4; 258 if (m_cu->GetVersion() <= 2) 259 ref_addr_size = m_cu->GetAddressByteSize(); 260 else 261 ref_addr_size = m_cu->IsDWARF64() ? 8 : 4; 262 m_value.value.uval = data.GetMaxU64(offset_ptr, ref_addr_size); 263 break; 264 case DW_FORM_ref1: 265 m_value.value.uval = data.GetU8(offset_ptr); 266 break; 267 case DW_FORM_ref2: 268 m_value.value.uval = data.GetU16(offset_ptr); 269 break; 270 case DW_FORM_ref4: 271 m_value.value.uval = data.GetU32(offset_ptr); 272 break; 273 case DW_FORM_ref8: 274 m_value.value.uval = data.GetU64(offset_ptr); 275 break; 276 case DW_FORM_ref_udata: 277 m_value.value.uval = data.GetULEB128(offset_ptr); 278 break; 279 case DW_FORM_indirect: 280 m_form = data.GetULEB128(offset_ptr); 281 indirect = true; 282 break; 283 284 case DW_FORM_sec_offset: 285 assert(m_cu); 286 m_value.value.uval = 287 data.GetMaxU64(offset_ptr, DWARFUnit::IsDWARF64(m_cu) ? 8 : 4); 288 break; 289 case DW_FORM_flag_present: 290 m_value.value.uval = 1; 291 break; 292 case DW_FORM_ref_sig8: 293 m_value.value.uval = data.GetU64(offset_ptr); 294 break; 295 case DW_FORM_GNU_str_index: 296 m_value.value.uval = data.GetULEB128(offset_ptr); 297 break; 298 case DW_FORM_GNU_addr_index: 299 m_value.value.uval = data.GetULEB128(offset_ptr); 300 break; 301 default: 302 return false; 303 break; 304 } 305 } while (indirect); 306 307 if (is_block) { 308 m_value.data = data.PeekData(*offset_ptr, m_value.value.uval); 309 if (m_value.data != NULL) { 310 *offset_ptr += m_value.value.uval; 311 } 312 } 313 314 return true; 315 } 316 317 bool DWARFFormValue::SkipValue(const DWARFDataExtractor &debug_info_data, 318 lldb::offset_t *offset_ptr) const { 319 return DWARFFormValue::SkipValue(m_form, debug_info_data, offset_ptr, m_cu); 320 } 321 322 bool DWARFFormValue::SkipValue(dw_form_t form, 323 const DWARFDataExtractor &debug_info_data, 324 lldb::offset_t *offset_ptr, 325 const DWARFUnit *cu) { 326 uint8_t ref_addr_size; 327 switch (form) { 328 // Blocks if inlined data that have a length field and the data bytes inlined 329 // in the .debug_info 330 case DW_FORM_exprloc: 331 case DW_FORM_block: { 332 dw_uleb128_t size = debug_info_data.GetULEB128(offset_ptr); 333 *offset_ptr += size; 334 } 335 return true; 336 case DW_FORM_block1: { 337 dw_uleb128_t size = debug_info_data.GetU8(offset_ptr); 338 *offset_ptr += size; 339 } 340 return true; 341 case DW_FORM_block2: { 342 dw_uleb128_t size = debug_info_data.GetU16(offset_ptr); 343 *offset_ptr += size; 344 } 345 return true; 346 case DW_FORM_block4: { 347 dw_uleb128_t size = debug_info_data.GetU32(offset_ptr); 348 *offset_ptr += size; 349 } 350 return true; 351 352 // Inlined NULL terminated C-strings 353 case DW_FORM_string: 354 debug_info_data.GetCStr(offset_ptr); 355 return true; 356 357 // Compile unit address sized values 358 case DW_FORM_addr: 359 *offset_ptr += DWARFUnit::GetAddressByteSize(cu); 360 return true; 361 362 case DW_FORM_ref_addr: 363 ref_addr_size = 4; 364 assert(cu); // CU must be valid for DW_FORM_ref_addr objects or we will get 365 // this wrong 366 if (cu->GetVersion() <= 2) 367 ref_addr_size = cu->GetAddressByteSize(); 368 else 369 ref_addr_size = cu->IsDWARF64() ? 8 : 4; 370 *offset_ptr += ref_addr_size; 371 return true; 372 373 // 0 bytes values (implied from DW_FORM) 374 case DW_FORM_flag_present: 375 case DW_FORM_implicit_const: 376 return true; 377 378 // 1 byte values 379 case DW_FORM_data1: 380 case DW_FORM_flag: 381 case DW_FORM_ref1: 382 case DW_FORM_strx1: 383 *offset_ptr += 1; 384 return true; 385 386 // 2 byte values 387 case DW_FORM_data2: 388 case DW_FORM_ref2: 389 case DW_FORM_strx2: 390 *offset_ptr += 2; 391 return true; 392 393 // 3 byte values 394 case DW_FORM_strx3: 395 *offset_ptr += 3; 396 return true; 397 398 // 32 bit for DWARF 32, 64 for DWARF 64 399 case DW_FORM_sec_offset: 400 case DW_FORM_strp: 401 assert(cu); 402 *offset_ptr += (cu->IsDWARF64() ? 8 : 4); 403 return true; 404 405 // 4 byte values 406 case DW_FORM_data4: 407 case DW_FORM_ref4: 408 case DW_FORM_strx4: 409 *offset_ptr += 4; 410 return true; 411 412 // 8 byte values 413 case DW_FORM_data8: 414 case DW_FORM_ref8: 415 case DW_FORM_ref_sig8: 416 *offset_ptr += 8; 417 return true; 418 419 // signed or unsigned LEB 128 values 420 case DW_FORM_sdata: 421 case DW_FORM_udata: 422 case DW_FORM_ref_udata: 423 case DW_FORM_GNU_addr_index: 424 case DW_FORM_GNU_str_index: 425 case DW_FORM_strx: 426 debug_info_data.Skip_LEB128(offset_ptr); 427 return true; 428 429 case DW_FORM_indirect: { 430 dw_form_t indirect_form = debug_info_data.GetULEB128(offset_ptr); 431 return DWARFFormValue::SkipValue(indirect_form, debug_info_data, offset_ptr, 432 cu); 433 } 434 435 default: 436 break; 437 } 438 return false; 439 } 440 441 void DWARFFormValue::Dump(Stream &s) const { 442 uint64_t uvalue = Unsigned(); 443 bool cu_relative_offset = false; 444 445 switch (m_form) { 446 case DW_FORM_addr: 447 s.Address(uvalue, sizeof(uint64_t)); 448 break; 449 case DW_FORM_flag: 450 case DW_FORM_data1: 451 s.PutHex8(uvalue); 452 break; 453 case DW_FORM_data2: 454 s.PutHex16(uvalue); 455 break; 456 case DW_FORM_sec_offset: 457 case DW_FORM_data4: 458 s.PutHex32(uvalue); 459 break; 460 case DW_FORM_ref_sig8: 461 case DW_FORM_data8: 462 s.PutHex64(uvalue); 463 break; 464 case DW_FORM_string: 465 s.QuotedCString(AsCString()); 466 break; 467 case DW_FORM_exprloc: 468 case DW_FORM_block: 469 case DW_FORM_block1: 470 case DW_FORM_block2: 471 case DW_FORM_block4: 472 if (uvalue > 0) { 473 switch (m_form) { 474 case DW_FORM_exprloc: 475 case DW_FORM_block: 476 s.Printf("<0x%" PRIx64 "> ", uvalue); 477 break; 478 case DW_FORM_block1: 479 s.Printf("<0x%2.2x> ", (uint8_t)uvalue); 480 break; 481 case DW_FORM_block2: 482 s.Printf("<0x%4.4x> ", (uint16_t)uvalue); 483 break; 484 case DW_FORM_block4: 485 s.Printf("<0x%8.8x> ", (uint32_t)uvalue); 486 break; 487 default: 488 break; 489 } 490 491 const uint8_t *data_ptr = m_value.data; 492 if (data_ptr) { 493 const uint8_t *end_data_ptr = 494 data_ptr + uvalue; // uvalue contains size of block 495 while (data_ptr < end_data_ptr) { 496 s.Printf("%2.2x ", *data_ptr); 497 ++data_ptr; 498 } 499 } else 500 s.PutCString("NULL"); 501 } 502 break; 503 504 case DW_FORM_sdata: 505 s.PutSLEB128(uvalue); 506 break; 507 case DW_FORM_udata: 508 s.PutULEB128(uvalue); 509 break; 510 case DW_FORM_strp: { 511 const char *dbg_str = AsCString(); 512 if (dbg_str) { 513 s.QuotedCString(dbg_str); 514 } else { 515 s.PutHex32(uvalue); 516 } 517 } break; 518 519 case DW_FORM_ref_addr: { 520 assert(m_cu); // CU must be valid for DW_FORM_ref_addr objects or we will 521 // get this wrong 522 if (m_cu->GetVersion() <= 2) 523 s.Address(uvalue, sizeof(uint64_t) * 2); 524 else 525 s.Address(uvalue, 4 * 2); // 4 for DWARF32, 8 for DWARF64, but we don't 526 // support DWARF64 yet 527 break; 528 } 529 case DW_FORM_ref1: 530 cu_relative_offset = true; 531 break; 532 case DW_FORM_ref2: 533 cu_relative_offset = true; 534 break; 535 case DW_FORM_ref4: 536 cu_relative_offset = true; 537 break; 538 case DW_FORM_ref8: 539 cu_relative_offset = true; 540 break; 541 case DW_FORM_ref_udata: 542 cu_relative_offset = true; 543 break; 544 545 // All DW_FORM_indirect attributes should be resolved prior to calling this 546 // function 547 case DW_FORM_indirect: 548 s.PutCString("DW_FORM_indirect"); 549 break; 550 case DW_FORM_flag_present: 551 break; 552 default: 553 s.Printf("DW_FORM(0x%4.4x)", m_form); 554 break; 555 } 556 557 if (cu_relative_offset) { 558 assert(m_cu); // CU must be valid for DW_FORM_ref forms that are compile 559 // unit relative or we will get this wrong 560 s.Printf("{0x%8.8" PRIx64 "}", uvalue + m_cu->GetOffset()); 561 } 562 } 563 564 const char *DWARFFormValue::AsCString() const { 565 SymbolFileDWARF *symbol_file = m_cu->GetSymbolFileDWARF(); 566 567 if (m_form == DW_FORM_string) { 568 return m_value.value.cstr; 569 } else if (m_form == DW_FORM_strp) { 570 if (!symbol_file) 571 return nullptr; 572 573 return symbol_file->get_debug_str_data().PeekCStr(m_value.value.uval); 574 } else if (m_form == DW_FORM_GNU_str_index) { 575 if (!symbol_file) 576 return nullptr; 577 578 uint32_t index_size = m_cu->IsDWARF64() ? 8 : 4; 579 lldb::offset_t offset = m_value.value.uval * index_size; 580 dw_offset_t str_offset = 581 symbol_file->get_debug_str_offsets_data().GetMaxU64(&offset, 582 index_size); 583 return symbol_file->get_debug_str_data().PeekCStr(str_offset); 584 } 585 586 if (m_form == DW_FORM_strx || m_form == DW_FORM_strx1 || 587 m_form == DW_FORM_strx2 || m_form == DW_FORM_strx3 || 588 m_form == DW_FORM_strx4) { 589 590 // The same code as above. 591 if (!symbol_file) 592 return nullptr; 593 594 lldb::offset_t baseOffset = 0; 595 const DWARFDataExtractor &strOffsets = 596 symbol_file->get_debug_str_offsets_data(); 597 uint64_t length = strOffsets.GetU32(&baseOffset); 598 if (length == 0xffffffff) 599 length = strOffsets.GetU64(&baseOffset); 600 601 // Check version. 602 if (strOffsets.GetU16(&baseOffset) < 5) 603 return nullptr; 604 605 // Skip padding. 606 baseOffset += 2; 607 608 uint32_t indexSize = m_cu->IsDWARF64() ? 8 : 4; 609 lldb::offset_t offset = baseOffset + m_value.value.uval * indexSize; 610 dw_offset_t strOffset = 611 symbol_file->get_debug_str_offsets_data().GetMaxU64(&offset, indexSize); 612 return symbol_file->get_debug_str_data().PeekCStr(strOffset); 613 } 614 615 if (m_form == DW_FORM_line_strp) 616 return symbol_file->get_debug_line_str_data().PeekCStr(m_value.value.uval); 617 618 return nullptr; 619 } 620 621 dw_addr_t DWARFFormValue::Address() const { 622 SymbolFileDWARF *symbol_file = m_cu->GetSymbolFileDWARF(); 623 624 if (m_form == DW_FORM_addr) 625 return Unsigned(); 626 627 assert(m_cu); 628 assert(m_form == DW_FORM_GNU_addr_index); 629 630 if (!symbol_file) 631 return 0; 632 633 uint32_t index_size = m_cu->GetAddressByteSize(); 634 dw_offset_t addr_base = m_cu->GetAddrBase(); 635 lldb::offset_t offset = addr_base + m_value.value.uval * index_size; 636 return symbol_file->get_debug_addr_data().GetMaxU64(&offset, index_size); 637 } 638 639 uint64_t DWARFFormValue::Reference() const { 640 uint64_t die_offset = m_value.value.uval; 641 switch (m_form) { 642 case DW_FORM_ref1: 643 case DW_FORM_ref2: 644 case DW_FORM_ref4: 645 case DW_FORM_ref8: 646 case DW_FORM_ref_udata: 647 assert(m_cu); // CU must be valid for DW_FORM_ref forms that are compile 648 // unit relative or we will get this wrong 649 die_offset += m_cu->GetOffset(); 650 break; 651 652 default: 653 break; 654 } 655 656 return die_offset; 657 } 658 659 uint64_t DWARFFormValue::Reference(dw_offset_t base_offset) const { 660 uint64_t die_offset = m_value.value.uval; 661 switch (m_form) { 662 case DW_FORM_ref1: 663 case DW_FORM_ref2: 664 case DW_FORM_ref4: 665 case DW_FORM_ref8: 666 case DW_FORM_ref_udata: 667 die_offset += base_offset; 668 break; 669 670 default: 671 break; 672 } 673 674 return die_offset; 675 } 676 677 const uint8_t *DWARFFormValue::BlockData() const { return m_value.data; } 678 679 bool DWARFFormValue::IsBlockForm(const dw_form_t form) { 680 switch (form) { 681 case DW_FORM_exprloc: 682 case DW_FORM_block: 683 case DW_FORM_block1: 684 case DW_FORM_block2: 685 case DW_FORM_block4: 686 return true; 687 } 688 return false; 689 } 690 691 bool DWARFFormValue::IsDataForm(const dw_form_t form) { 692 switch (form) { 693 case DW_FORM_sdata: 694 case DW_FORM_udata: 695 case DW_FORM_data1: 696 case DW_FORM_data2: 697 case DW_FORM_data4: 698 case DW_FORM_data8: 699 return true; 700 } 701 return false; 702 } 703 704 int DWARFFormValue::Compare(const DWARFFormValue &a_value, 705 const DWARFFormValue &b_value) { 706 dw_form_t a_form = a_value.Form(); 707 dw_form_t b_form = b_value.Form(); 708 if (a_form < b_form) 709 return -1; 710 if (a_form > b_form) 711 return 1; 712 switch (a_form) { 713 case DW_FORM_addr: 714 case DW_FORM_flag: 715 case DW_FORM_data1: 716 case DW_FORM_data2: 717 case DW_FORM_data4: 718 case DW_FORM_data8: 719 case DW_FORM_udata: 720 case DW_FORM_ref_addr: 721 case DW_FORM_sec_offset: 722 case DW_FORM_flag_present: 723 case DW_FORM_ref_sig8: 724 case DW_FORM_GNU_addr_index: { 725 uint64_t a = a_value.Unsigned(); 726 uint64_t b = b_value.Unsigned(); 727 if (a < b) 728 return -1; 729 if (a > b) 730 return 1; 731 return 0; 732 } 733 734 case DW_FORM_sdata: { 735 int64_t a = a_value.Signed(); 736 int64_t b = b_value.Signed(); 737 if (a < b) 738 return -1; 739 if (a > b) 740 return 1; 741 return 0; 742 } 743 744 case DW_FORM_string: 745 case DW_FORM_strp: 746 case DW_FORM_GNU_str_index: { 747 const char *a_string = a_value.AsCString(); 748 const char *b_string = b_value.AsCString(); 749 if (a_string == b_string) 750 return 0; 751 else if (a_string && b_string) 752 return strcmp(a_string, b_string); 753 else if (a_string == NULL) 754 return -1; // A string is NULL, and B is valid 755 else 756 return 1; // A string valid, and B is NULL 757 } 758 759 case DW_FORM_block: 760 case DW_FORM_block1: 761 case DW_FORM_block2: 762 case DW_FORM_block4: 763 case DW_FORM_exprloc: { 764 uint64_t a_len = a_value.Unsigned(); 765 uint64_t b_len = b_value.Unsigned(); 766 if (a_len < b_len) 767 return -1; 768 if (a_len > b_len) 769 return 1; 770 // The block lengths are the same 771 return memcmp(a_value.BlockData(), b_value.BlockData(), a_value.Unsigned()); 772 } break; 773 774 case DW_FORM_ref1: 775 case DW_FORM_ref2: 776 case DW_FORM_ref4: 777 case DW_FORM_ref8: 778 case DW_FORM_ref_udata: { 779 uint64_t a = a_value.Reference(); 780 uint64_t b = b_value.Reference(); 781 if (a < b) 782 return -1; 783 if (a > b) 784 return 1; 785 return 0; 786 } 787 788 case DW_FORM_indirect: 789 llvm_unreachable( 790 "This shouldn't happen after the form has been extracted..."); 791 792 default: 793 llvm_unreachable("Unhandled DW_FORM"); 794 } 795 return -1; 796 } 797 798 bool DWARFFormValue::FormIsSupported(dw_form_t form) { 799 switch (form) { 800 case DW_FORM_addr: 801 case DW_FORM_block2: 802 case DW_FORM_block4: 803 case DW_FORM_data2: 804 case DW_FORM_data4: 805 case DW_FORM_data8: 806 case DW_FORM_string: 807 case DW_FORM_block: 808 case DW_FORM_block1: 809 case DW_FORM_data1: 810 case DW_FORM_flag: 811 case DW_FORM_sdata: 812 case DW_FORM_strp: 813 case DW_FORM_strx: 814 case DW_FORM_strx1: 815 case DW_FORM_strx2: 816 case DW_FORM_strx3: 817 case DW_FORM_strx4: 818 case DW_FORM_udata: 819 case DW_FORM_ref_addr: 820 case DW_FORM_ref1: 821 case DW_FORM_ref2: 822 case DW_FORM_ref4: 823 case DW_FORM_ref8: 824 case DW_FORM_ref_udata: 825 case DW_FORM_indirect: 826 case DW_FORM_sec_offset: 827 case DW_FORM_exprloc: 828 case DW_FORM_flag_present: 829 case DW_FORM_ref_sig8: 830 case DW_FORM_GNU_str_index: 831 case DW_FORM_GNU_addr_index: 832 case DW_FORM_implicit_const: 833 return true; 834 default: 835 break; 836 } 837 return false; 838 } 839