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 = 186 data.GetMaxU64(offset_ptr, DWARFUnit::GetAddressByteSize(m_cu)); 187 break; 188 case DW_FORM_block1: 189 m_value.value.uval = data.GetU8(offset_ptr); 190 is_block = true; 191 break; 192 case DW_FORM_block2: 193 m_value.value.uval = data.GetU16(offset_ptr); 194 is_block = true; 195 break; 196 case DW_FORM_block4: 197 m_value.value.uval = data.GetU32(offset_ptr); 198 is_block = true; 199 break; 200 case DW_FORM_data16: 201 m_value.value.uval = 16; 202 is_block = true; 203 break; 204 case DW_FORM_exprloc: 205 case DW_FORM_block: 206 m_value.value.uval = data.GetULEB128(offset_ptr); 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_sdata: 213 m_value.value.sval = data.GetSLEB128(offset_ptr); 214 break; 215 case DW_FORM_strp: 216 case DW_FORM_line_strp: 217 case DW_FORM_sec_offset: 218 assert(m_cu); 219 m_value.value.uval = 220 data.GetMaxU64(offset_ptr, DWARFUnit::IsDWARF64(m_cu) ? 8 : 4); 221 break; 222 case DW_FORM_addrx1: 223 case DW_FORM_strx1: 224 case DW_FORM_ref1: 225 case DW_FORM_data1: 226 case DW_FORM_flag: 227 m_value.value.uval = data.GetU8(offset_ptr); 228 break; 229 case DW_FORM_addrx2: 230 case DW_FORM_strx2: 231 case DW_FORM_ref2: 232 case DW_FORM_data2: 233 m_value.value.uval = data.GetU16(offset_ptr); 234 break; 235 case DW_FORM_addrx3: 236 case DW_FORM_strx3: 237 m_value.value.uval = data.GetMaxU64(offset_ptr, 3); 238 break; 239 case DW_FORM_addrx4: 240 case DW_FORM_strx4: 241 case DW_FORM_ref4: 242 case DW_FORM_data4: 243 m_value.value.uval = data.GetU32(offset_ptr); 244 break; 245 case DW_FORM_data8: 246 case DW_FORM_ref8: 247 case DW_FORM_ref_sig8: 248 m_value.value.uval = data.GetU64(offset_ptr); 249 break; 250 case DW_FORM_addrx: 251 case DW_FORM_rnglistx: 252 case DW_FORM_strx: 253 case DW_FORM_udata: 254 case DW_FORM_ref_udata: 255 case DW_FORM_GNU_str_index: 256 case DW_FORM_GNU_addr_index: 257 m_value.value.uval = data.GetULEB128(offset_ptr); 258 break; 259 case DW_FORM_ref_addr: 260 assert(m_cu); 261 if (m_cu->GetVersion() <= 2) 262 ref_addr_size = m_cu->GetAddressByteSize(); 263 else 264 ref_addr_size = m_cu->IsDWARF64() ? 8 : 4; 265 m_value.value.uval = data.GetMaxU64(offset_ptr, ref_addr_size); 266 break; 267 case DW_FORM_indirect: 268 m_form = data.GetULEB128(offset_ptr); 269 indirect = true; 270 break; 271 case DW_FORM_flag_present: 272 m_value.value.uval = 1; 273 break; 274 default: 275 return false; 276 } 277 } while (indirect); 278 279 if (is_block) { 280 m_value.data = data.PeekData(*offset_ptr, m_value.value.uval); 281 if (m_value.data != NULL) { 282 *offset_ptr += m_value.value.uval; 283 } 284 } 285 286 return true; 287 } 288 289 bool DWARFFormValue::SkipValue(const DWARFDataExtractor &debug_info_data, 290 lldb::offset_t *offset_ptr) const { 291 return DWARFFormValue::SkipValue(m_form, debug_info_data, offset_ptr, m_cu); 292 } 293 294 bool DWARFFormValue::SkipValue(dw_form_t form, 295 const DWARFDataExtractor &debug_info_data, 296 lldb::offset_t *offset_ptr, 297 const DWARFUnit *cu) { 298 uint8_t ref_addr_size; 299 switch (form) { 300 // Blocks if inlined data that have a length field and the data bytes inlined 301 // in the .debug_info 302 case DW_FORM_exprloc: 303 case DW_FORM_block: { 304 dw_uleb128_t size = debug_info_data.GetULEB128(offset_ptr); 305 *offset_ptr += size; 306 } 307 return true; 308 case DW_FORM_block1: { 309 dw_uleb128_t size = debug_info_data.GetU8(offset_ptr); 310 *offset_ptr += size; 311 } 312 return true; 313 case DW_FORM_block2: { 314 dw_uleb128_t size = debug_info_data.GetU16(offset_ptr); 315 *offset_ptr += size; 316 } 317 return true; 318 case DW_FORM_block4: { 319 dw_uleb128_t size = debug_info_data.GetU32(offset_ptr); 320 *offset_ptr += size; 321 } 322 return true; 323 324 // Inlined NULL terminated C-strings 325 case DW_FORM_string: 326 debug_info_data.GetCStr(offset_ptr); 327 return true; 328 329 // Compile unit address sized values 330 case DW_FORM_addr: 331 *offset_ptr += DWARFUnit::GetAddressByteSize(cu); 332 return true; 333 334 case DW_FORM_ref_addr: 335 ref_addr_size = 4; 336 assert(cu); // CU must be valid for DW_FORM_ref_addr objects or we will get 337 // this wrong 338 if (cu->GetVersion() <= 2) 339 ref_addr_size = cu->GetAddressByteSize(); 340 else 341 ref_addr_size = cu->IsDWARF64() ? 8 : 4; 342 *offset_ptr += ref_addr_size; 343 return true; 344 345 // 0 bytes values (implied from DW_FORM) 346 case DW_FORM_flag_present: 347 case DW_FORM_implicit_const: 348 return true; 349 350 // 1 byte values 351 case DW_FORM_addrx1: 352 case DW_FORM_data1: 353 case DW_FORM_flag: 354 case DW_FORM_ref1: 355 case DW_FORM_strx1: 356 *offset_ptr += 1; 357 return true; 358 359 // 2 byte values 360 case DW_FORM_addrx2: 361 case DW_FORM_data2: 362 case DW_FORM_ref2: 363 case DW_FORM_strx2: 364 *offset_ptr += 2; 365 return true; 366 367 // 3 byte values 368 case DW_FORM_addrx3: 369 case DW_FORM_strx3: 370 *offset_ptr += 3; 371 return true; 372 373 // 32 bit for DWARF 32, 64 for DWARF 64 374 case DW_FORM_sec_offset: 375 case DW_FORM_strp: 376 assert(cu); 377 *offset_ptr += (cu->IsDWARF64() ? 8 : 4); 378 return true; 379 380 // 4 byte values 381 case DW_FORM_addrx4: 382 case DW_FORM_data4: 383 case DW_FORM_ref4: 384 case DW_FORM_strx4: 385 *offset_ptr += 4; 386 return true; 387 388 // 8 byte values 389 case DW_FORM_data8: 390 case DW_FORM_ref8: 391 case DW_FORM_ref_sig8: 392 *offset_ptr += 8; 393 return true; 394 395 // signed or unsigned LEB 128 values 396 case DW_FORM_addrx: 397 case DW_FORM_rnglistx: 398 case DW_FORM_sdata: 399 case DW_FORM_udata: 400 case DW_FORM_ref_udata: 401 case DW_FORM_GNU_addr_index: 402 case DW_FORM_GNU_str_index: 403 case DW_FORM_strx: 404 debug_info_data.Skip_LEB128(offset_ptr); 405 return true; 406 407 case DW_FORM_indirect: { 408 dw_form_t indirect_form = debug_info_data.GetULEB128(offset_ptr); 409 return DWARFFormValue::SkipValue(indirect_form, debug_info_data, offset_ptr, 410 cu); 411 } 412 413 default: 414 break; 415 } 416 return false; 417 } 418 419 void DWARFFormValue::Dump(Stream &s) const { 420 uint64_t uvalue = Unsigned(); 421 bool cu_relative_offset = false; 422 423 switch (m_form) { 424 case DW_FORM_addr: 425 s.Address(uvalue, sizeof(uint64_t)); 426 break; 427 case DW_FORM_flag: 428 case DW_FORM_data1: 429 s.PutHex8(uvalue); 430 break; 431 case DW_FORM_data2: 432 s.PutHex16(uvalue); 433 break; 434 case DW_FORM_sec_offset: 435 case DW_FORM_data4: 436 s.PutHex32(uvalue); 437 break; 438 case DW_FORM_ref_sig8: 439 case DW_FORM_data8: 440 s.PutHex64(uvalue); 441 break; 442 case DW_FORM_string: 443 s.QuotedCString(AsCString()); 444 break; 445 case DW_FORM_exprloc: 446 case DW_FORM_block: 447 case DW_FORM_block1: 448 case DW_FORM_block2: 449 case DW_FORM_block4: 450 if (uvalue > 0) { 451 switch (m_form) { 452 case DW_FORM_exprloc: 453 case DW_FORM_block: 454 s.Printf("<0x%" PRIx64 "> ", uvalue); 455 break; 456 case DW_FORM_block1: 457 s.Printf("<0x%2.2x> ", (uint8_t)uvalue); 458 break; 459 case DW_FORM_block2: 460 s.Printf("<0x%4.4x> ", (uint16_t)uvalue); 461 break; 462 case DW_FORM_block4: 463 s.Printf("<0x%8.8x> ", (uint32_t)uvalue); 464 break; 465 default: 466 break; 467 } 468 469 const uint8_t *data_ptr = m_value.data; 470 if (data_ptr) { 471 const uint8_t *end_data_ptr = 472 data_ptr + uvalue; // uvalue contains size of block 473 while (data_ptr < end_data_ptr) { 474 s.Printf("%2.2x ", *data_ptr); 475 ++data_ptr; 476 } 477 } else 478 s.PutCString("NULL"); 479 } 480 break; 481 482 case DW_FORM_sdata: 483 s.PutSLEB128(uvalue); 484 break; 485 case DW_FORM_udata: 486 s.PutULEB128(uvalue); 487 break; 488 case DW_FORM_strp: { 489 const char *dbg_str = AsCString(); 490 if (dbg_str) { 491 s.QuotedCString(dbg_str); 492 } else { 493 s.PutHex32(uvalue); 494 } 495 } break; 496 497 case DW_FORM_ref_addr: { 498 assert(m_cu); // CU must be valid for DW_FORM_ref_addr objects or we will 499 // get this wrong 500 if (m_cu->GetVersion() <= 2) 501 s.Address(uvalue, sizeof(uint64_t) * 2); 502 else 503 s.Address(uvalue, 4 * 2); // 4 for DWARF32, 8 for DWARF64, but we don't 504 // support DWARF64 yet 505 break; 506 } 507 case DW_FORM_ref1: 508 cu_relative_offset = true; 509 break; 510 case DW_FORM_ref2: 511 cu_relative_offset = true; 512 break; 513 case DW_FORM_ref4: 514 cu_relative_offset = true; 515 break; 516 case DW_FORM_ref8: 517 cu_relative_offset = true; 518 break; 519 case DW_FORM_ref_udata: 520 cu_relative_offset = true; 521 break; 522 523 // All DW_FORM_indirect attributes should be resolved prior to calling this 524 // function 525 case DW_FORM_indirect: 526 s.PutCString("DW_FORM_indirect"); 527 break; 528 case DW_FORM_flag_present: 529 break; 530 default: 531 s.Printf("DW_FORM(0x%4.4x)", m_form); 532 break; 533 } 534 535 if (cu_relative_offset) { 536 assert(m_cu); // CU must be valid for DW_FORM_ref forms that are compile 537 // unit relative or we will get this wrong 538 s.Printf("{0x%8.8" PRIx64 "}", uvalue + m_cu->GetOffset()); 539 } 540 } 541 542 const char *DWARFFormValue::AsCString() const { 543 SymbolFileDWARF *symbol_file = m_cu->GetSymbolFileDWARF(); 544 545 if (m_form == DW_FORM_string) { 546 return m_value.value.cstr; 547 } else if (m_form == DW_FORM_strp) { 548 if (!symbol_file) 549 return nullptr; 550 551 return symbol_file->get_debug_str_data().PeekCStr(m_value.value.uval); 552 } else if (m_form == DW_FORM_GNU_str_index) { 553 if (!symbol_file) 554 return nullptr; 555 556 uint32_t index_size = m_cu->IsDWARF64() ? 8 : 4; 557 lldb::offset_t offset = m_value.value.uval * index_size; 558 dw_offset_t str_offset = 559 symbol_file->get_debug_str_offsets_data().GetMaxU64(&offset, 560 index_size); 561 return symbol_file->get_debug_str_data().PeekCStr(str_offset); 562 } 563 564 if (m_form == DW_FORM_strx || m_form == DW_FORM_strx1 || 565 m_form == DW_FORM_strx2 || m_form == DW_FORM_strx3 || 566 m_form == DW_FORM_strx4) { 567 568 // The same code as above. 569 if (!symbol_file) 570 return nullptr; 571 572 lldb::offset_t baseOffset = 0; 573 const DWARFDataExtractor &strOffsets = 574 symbol_file->get_debug_str_offsets_data(); 575 uint64_t length = strOffsets.GetU32(&baseOffset); 576 if (length == 0xffffffff) 577 length = strOffsets.GetU64(&baseOffset); 578 579 // Check version. 580 if (strOffsets.GetU16(&baseOffset) < 5) 581 return nullptr; 582 583 // Skip padding. 584 baseOffset += 2; 585 586 uint32_t indexSize = m_cu->IsDWARF64() ? 8 : 4; 587 lldb::offset_t offset = baseOffset + m_value.value.uval * indexSize; 588 dw_offset_t strOffset = 589 symbol_file->get_debug_str_offsets_data().GetMaxU64(&offset, indexSize); 590 return symbol_file->get_debug_str_data().PeekCStr(strOffset); 591 } 592 593 if (m_form == DW_FORM_line_strp) 594 return symbol_file->get_debug_line_str_data().PeekCStr(m_value.value.uval); 595 596 return nullptr; 597 } 598 599 dw_addr_t DWARFFormValue::Address() const { 600 SymbolFileDWARF *symbol_file = m_cu->GetSymbolFileDWARF(); 601 602 if (m_form == DW_FORM_addr) 603 return Unsigned(); 604 605 assert(m_cu); 606 assert(m_form == DW_FORM_GNU_addr_index || m_form == DW_FORM_addrx || 607 m_form == DW_FORM_addrx1 || m_form == DW_FORM_addrx2 || 608 m_form == DW_FORM_addrx3 || m_form == DW_FORM_addrx4); 609 610 if (!symbol_file) 611 return 0; 612 613 uint32_t index_size = m_cu->GetAddressByteSize(); 614 dw_offset_t addr_base = m_cu->GetAddrBase(); 615 lldb::offset_t offset = addr_base + m_value.value.uval * index_size; 616 return symbol_file->get_debug_addr_data().GetMaxU64(&offset, index_size); 617 } 618 619 uint64_t DWARFFormValue::Reference() const { 620 uint64_t die_offset = m_value.value.uval; 621 switch (m_form) { 622 case DW_FORM_ref1: 623 case DW_FORM_ref2: 624 case DW_FORM_ref4: 625 case DW_FORM_ref8: 626 case DW_FORM_ref_udata: 627 assert(m_cu); // CU must be valid for DW_FORM_ref forms that are compile 628 // unit relative or we will get this wrong 629 die_offset += m_cu->GetOffset(); 630 break; 631 632 default: 633 break; 634 } 635 636 return die_offset; 637 } 638 639 uint64_t DWARFFormValue::Reference(dw_offset_t base_offset) 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 die_offset += base_offset; 648 break; 649 650 default: 651 break; 652 } 653 654 return die_offset; 655 } 656 657 const uint8_t *DWARFFormValue::BlockData() const { return m_value.data; } 658 659 bool DWARFFormValue::IsBlockForm(const dw_form_t form) { 660 switch (form) { 661 case DW_FORM_exprloc: 662 case DW_FORM_block: 663 case DW_FORM_block1: 664 case DW_FORM_block2: 665 case DW_FORM_block4: 666 return true; 667 } 668 return false; 669 } 670 671 bool DWARFFormValue::IsDataForm(const dw_form_t form) { 672 switch (form) { 673 case DW_FORM_sdata: 674 case DW_FORM_udata: 675 case DW_FORM_data1: 676 case DW_FORM_data2: 677 case DW_FORM_data4: 678 case DW_FORM_data8: 679 return true; 680 } 681 return false; 682 } 683 684 int DWARFFormValue::Compare(const DWARFFormValue &a_value, 685 const DWARFFormValue &b_value) { 686 dw_form_t a_form = a_value.Form(); 687 dw_form_t b_form = b_value.Form(); 688 if (a_form < b_form) 689 return -1; 690 if (a_form > b_form) 691 return 1; 692 switch (a_form) { 693 case DW_FORM_addr: 694 case DW_FORM_flag: 695 case DW_FORM_data1: 696 case DW_FORM_data2: 697 case DW_FORM_data4: 698 case DW_FORM_data8: 699 case DW_FORM_udata: 700 case DW_FORM_ref_addr: 701 case DW_FORM_sec_offset: 702 case DW_FORM_flag_present: 703 case DW_FORM_ref_sig8: 704 case DW_FORM_GNU_addr_index: { 705 uint64_t a = a_value.Unsigned(); 706 uint64_t b = b_value.Unsigned(); 707 if (a < b) 708 return -1; 709 if (a > b) 710 return 1; 711 return 0; 712 } 713 714 case DW_FORM_sdata: { 715 int64_t a = a_value.Signed(); 716 int64_t b = b_value.Signed(); 717 if (a < b) 718 return -1; 719 if (a > b) 720 return 1; 721 return 0; 722 } 723 724 case DW_FORM_string: 725 case DW_FORM_strp: 726 case DW_FORM_GNU_str_index: { 727 const char *a_string = a_value.AsCString(); 728 const char *b_string = b_value.AsCString(); 729 if (a_string == b_string) 730 return 0; 731 else if (a_string && b_string) 732 return strcmp(a_string, b_string); 733 else if (a_string == NULL) 734 return -1; // A string is NULL, and B is valid 735 else 736 return 1; // A string valid, and B is NULL 737 } 738 739 case DW_FORM_block: 740 case DW_FORM_block1: 741 case DW_FORM_block2: 742 case DW_FORM_block4: 743 case DW_FORM_exprloc: { 744 uint64_t a_len = a_value.Unsigned(); 745 uint64_t b_len = b_value.Unsigned(); 746 if (a_len < b_len) 747 return -1; 748 if (a_len > b_len) 749 return 1; 750 // The block lengths are the same 751 return memcmp(a_value.BlockData(), b_value.BlockData(), a_value.Unsigned()); 752 } break; 753 754 case DW_FORM_ref1: 755 case DW_FORM_ref2: 756 case DW_FORM_ref4: 757 case DW_FORM_ref8: 758 case DW_FORM_ref_udata: { 759 uint64_t a = a_value.Reference(); 760 uint64_t b = b_value.Reference(); 761 if (a < b) 762 return -1; 763 if (a > b) 764 return 1; 765 return 0; 766 } 767 768 case DW_FORM_indirect: 769 llvm_unreachable( 770 "This shouldn't happen after the form has been extracted..."); 771 772 default: 773 llvm_unreachable("Unhandled DW_FORM"); 774 } 775 return -1; 776 } 777 778 bool DWARFFormValue::FormIsSupported(dw_form_t form) { 779 switch (form) { 780 case DW_FORM_addr: 781 case DW_FORM_addrx: 782 case DW_FORM_rnglistx: 783 case DW_FORM_block2: 784 case DW_FORM_block4: 785 case DW_FORM_data2: 786 case DW_FORM_data4: 787 case DW_FORM_data8: 788 case DW_FORM_string: 789 case DW_FORM_block: 790 case DW_FORM_block1: 791 case DW_FORM_data1: 792 case DW_FORM_flag: 793 case DW_FORM_sdata: 794 case DW_FORM_strp: 795 case DW_FORM_strx: 796 case DW_FORM_strx1: 797 case DW_FORM_strx2: 798 case DW_FORM_strx3: 799 case DW_FORM_strx4: 800 case DW_FORM_udata: 801 case DW_FORM_ref_addr: 802 case DW_FORM_ref1: 803 case DW_FORM_ref2: 804 case DW_FORM_ref4: 805 case DW_FORM_ref8: 806 case DW_FORM_ref_udata: 807 case DW_FORM_indirect: 808 case DW_FORM_sec_offset: 809 case DW_FORM_exprloc: 810 case DW_FORM_flag_present: 811 case DW_FORM_ref_sig8: 812 case DW_FORM_GNU_str_index: 813 case DW_FORM_GNU_addr_index: 814 case DW_FORM_implicit_const: 815 return true; 816 default: 817 break; 818 } 819 return false; 820 } 821