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