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