DWARFFormValue.cpp revision 344779
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 18class DWARFUnit; 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 DWARFUnit *cu) 158 : m_cu(cu), m_form(0), m_value() {} 159 160DWARFFormValue::DWARFFormValue(const DWARFUnit *cu, dw_form_t form) 161 : m_cu(cu), m_form(form), m_value() {} 162 163void DWARFFormValue::Clear() { 164 m_cu = nullptr; 165 m_form = 0; 166 memset(&m_value, 0, sizeof(m_value)); 167} 168 169bool 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 289bool 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 294bool 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 419void 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 542const 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 uint32_t indexSize = m_cu->IsDWARF64() ? 8 : 4; 573 lldb::offset_t offset = 574 m_cu->GetStrOffsetsBase() + m_value.value.uval * indexSize; 575 dw_offset_t strOffset = 576 symbol_file->get_debug_str_offsets_data().GetMaxU64(&offset, indexSize); 577 return symbol_file->get_debug_str_data().PeekCStr(strOffset); 578 } 579 580 if (m_form == DW_FORM_line_strp) 581 return symbol_file->get_debug_line_str_data().PeekCStr(m_value.value.uval); 582 583 return nullptr; 584} 585 586dw_addr_t DWARFFormValue::Address() const { 587 SymbolFileDWARF *symbol_file = m_cu->GetSymbolFileDWARF(); 588 589 if (m_form == DW_FORM_addr) 590 return Unsigned(); 591 592 assert(m_cu); 593 assert(m_form == DW_FORM_GNU_addr_index || m_form == DW_FORM_addrx || 594 m_form == DW_FORM_addrx1 || m_form == DW_FORM_addrx2 || 595 m_form == DW_FORM_addrx3 || m_form == DW_FORM_addrx4); 596 597 if (!symbol_file) 598 return 0; 599 600 uint32_t index_size = m_cu->GetAddressByteSize(); 601 dw_offset_t addr_base = m_cu->GetAddrBase(); 602 lldb::offset_t offset = addr_base + m_value.value.uval * index_size; 603 return symbol_file->get_debug_addr_data().GetMaxU64(&offset, index_size); 604} 605 606uint64_t DWARFFormValue::Reference() const { 607 uint64_t value = m_value.value.uval; 608 switch (m_form) { 609 case DW_FORM_ref1: 610 case DW_FORM_ref2: 611 case DW_FORM_ref4: 612 case DW_FORM_ref8: 613 case DW_FORM_ref_udata: 614 assert(m_cu); // CU must be valid for DW_FORM_ref forms that are compile 615 // unit relative or we will get this wrong 616 return value + m_cu->GetOffset(); 617 618 case DW_FORM_ref_addr: 619 case DW_FORM_ref_sig8: 620 case DW_FORM_GNU_ref_alt: 621 return value; 622 623 default: 624 return DW_INVALID_OFFSET; 625 } 626} 627 628uint64_t DWARFFormValue::Reference(dw_offset_t base_offset) const { 629 uint64_t value = m_value.value.uval; 630 switch (m_form) { 631 case DW_FORM_ref1: 632 case DW_FORM_ref2: 633 case DW_FORM_ref4: 634 case DW_FORM_ref8: 635 case DW_FORM_ref_udata: 636 return value + base_offset; 637 638 case DW_FORM_ref_addr: 639 case DW_FORM_ref_sig8: 640 case DW_FORM_GNU_ref_alt: 641 return value; 642 643 default: 644 return DW_INVALID_OFFSET; 645 } 646} 647 648const uint8_t *DWARFFormValue::BlockData() const { return m_value.data; } 649 650bool DWARFFormValue::IsBlockForm(const dw_form_t form) { 651 switch (form) { 652 case DW_FORM_exprloc: 653 case DW_FORM_block: 654 case DW_FORM_block1: 655 case DW_FORM_block2: 656 case DW_FORM_block4: 657 return true; 658 } 659 return false; 660} 661 662bool DWARFFormValue::IsDataForm(const dw_form_t form) { 663 switch (form) { 664 case DW_FORM_sdata: 665 case DW_FORM_udata: 666 case DW_FORM_data1: 667 case DW_FORM_data2: 668 case DW_FORM_data4: 669 case DW_FORM_data8: 670 return true; 671 } 672 return false; 673} 674 675int DWARFFormValue::Compare(const DWARFFormValue &a_value, 676 const DWARFFormValue &b_value) { 677 dw_form_t a_form = a_value.Form(); 678 dw_form_t b_form = b_value.Form(); 679 if (a_form < b_form) 680 return -1; 681 if (a_form > b_form) 682 return 1; 683 switch (a_form) { 684 case DW_FORM_addr: 685 case DW_FORM_flag: 686 case DW_FORM_data1: 687 case DW_FORM_data2: 688 case DW_FORM_data4: 689 case DW_FORM_data8: 690 case DW_FORM_udata: 691 case DW_FORM_ref_addr: 692 case DW_FORM_sec_offset: 693 case DW_FORM_flag_present: 694 case DW_FORM_ref_sig8: 695 case DW_FORM_GNU_addr_index: { 696 uint64_t a = a_value.Unsigned(); 697 uint64_t b = b_value.Unsigned(); 698 if (a < b) 699 return -1; 700 if (a > b) 701 return 1; 702 return 0; 703 } 704 705 case DW_FORM_sdata: { 706 int64_t a = a_value.Signed(); 707 int64_t b = b_value.Signed(); 708 if (a < b) 709 return -1; 710 if (a > b) 711 return 1; 712 return 0; 713 } 714 715 case DW_FORM_string: 716 case DW_FORM_strp: 717 case DW_FORM_GNU_str_index: { 718 const char *a_string = a_value.AsCString(); 719 const char *b_string = b_value.AsCString(); 720 if (a_string == b_string) 721 return 0; 722 else if (a_string && b_string) 723 return strcmp(a_string, b_string); 724 else if (a_string == NULL) 725 return -1; // A string is NULL, and B is valid 726 else 727 return 1; // A string valid, and B is NULL 728 } 729 730 case DW_FORM_block: 731 case DW_FORM_block1: 732 case DW_FORM_block2: 733 case DW_FORM_block4: 734 case DW_FORM_exprloc: { 735 uint64_t a_len = a_value.Unsigned(); 736 uint64_t b_len = b_value.Unsigned(); 737 if (a_len < b_len) 738 return -1; 739 if (a_len > b_len) 740 return 1; 741 // The block lengths are the same 742 return memcmp(a_value.BlockData(), b_value.BlockData(), a_value.Unsigned()); 743 } break; 744 745 case DW_FORM_ref1: 746 case DW_FORM_ref2: 747 case DW_FORM_ref4: 748 case DW_FORM_ref8: 749 case DW_FORM_ref_udata: { 750 uint64_t a = a_value.Reference(); 751 uint64_t b = b_value.Reference(); 752 if (a < b) 753 return -1; 754 if (a > b) 755 return 1; 756 return 0; 757 } 758 759 case DW_FORM_indirect: 760 llvm_unreachable( 761 "This shouldn't happen after the form has been extracted..."); 762 763 default: 764 llvm_unreachable("Unhandled DW_FORM"); 765 } 766 return -1; 767} 768 769bool DWARFFormValue::FormIsSupported(dw_form_t form) { 770 switch (form) { 771 case DW_FORM_addr: 772 case DW_FORM_addrx: 773 case DW_FORM_rnglistx: 774 case DW_FORM_block2: 775 case DW_FORM_block4: 776 case DW_FORM_data2: 777 case DW_FORM_data4: 778 case DW_FORM_data8: 779 case DW_FORM_string: 780 case DW_FORM_block: 781 case DW_FORM_block1: 782 case DW_FORM_data1: 783 case DW_FORM_flag: 784 case DW_FORM_sdata: 785 case DW_FORM_strp: 786 case DW_FORM_strx: 787 case DW_FORM_strx1: 788 case DW_FORM_strx2: 789 case DW_FORM_strx3: 790 case DW_FORM_strx4: 791 case DW_FORM_udata: 792 case DW_FORM_ref_addr: 793 case DW_FORM_ref1: 794 case DW_FORM_ref2: 795 case DW_FORM_ref4: 796 case DW_FORM_ref8: 797 case DW_FORM_ref_udata: 798 case DW_FORM_indirect: 799 case DW_FORM_sec_offset: 800 case DW_FORM_exprloc: 801 case DW_FORM_flag_present: 802 case DW_FORM_ref_sig8: 803 case DW_FORM_GNU_str_index: 804 case DW_FORM_GNU_addr_index: 805 case DW_FORM_implicit_const: 806 return true; 807 default: 808 break; 809 } 810 return false; 811} 812