DWARFFormValue.cpp revision 314564
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/Stream.h" 13#include "lldb/Core/dwarf.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 bool verbose = s.GetVerbose(); 410 411 switch (m_form) { 412 case DW_FORM_addr: 413 s.Address(uvalue, sizeof(uint64_t)); 414 break; 415 case DW_FORM_flag: 416 case DW_FORM_data1: 417 s.PutHex8(uvalue); 418 break; 419 case DW_FORM_data2: 420 s.PutHex16(uvalue); 421 break; 422 case DW_FORM_sec_offset: 423 case DW_FORM_data4: 424 s.PutHex32(uvalue); 425 break; 426 case DW_FORM_ref_sig8: 427 case DW_FORM_data8: 428 s.PutHex64(uvalue); 429 break; 430 case DW_FORM_string: 431 s.QuotedCString(AsCString()); 432 break; 433 case DW_FORM_exprloc: 434 case DW_FORM_block: 435 case DW_FORM_block1: 436 case DW_FORM_block2: 437 case DW_FORM_block4: 438 if (uvalue > 0) { 439 switch (m_form) { 440 case DW_FORM_exprloc: 441 case DW_FORM_block: 442 s.Printf("<0x%" PRIx64 "> ", uvalue); 443 break; 444 case DW_FORM_block1: 445 s.Printf("<0x%2.2x> ", (uint8_t)uvalue); 446 break; 447 case DW_FORM_block2: 448 s.Printf("<0x%4.4x> ", (uint16_t)uvalue); 449 break; 450 case DW_FORM_block4: 451 s.Printf("<0x%8.8x> ", (uint32_t)uvalue); 452 break; 453 default: 454 break; 455 } 456 457 const uint8_t *data_ptr = m_value.data; 458 if (data_ptr) { 459 const uint8_t *end_data_ptr = 460 data_ptr + uvalue; // uvalue contains size of block 461 while (data_ptr < end_data_ptr) { 462 s.Printf("%2.2x ", *data_ptr); 463 ++data_ptr; 464 } 465 } else 466 s.PutCString("NULL"); 467 } 468 break; 469 470 case DW_FORM_sdata: 471 s.PutSLEB128(uvalue); 472 break; 473 case DW_FORM_udata: 474 s.PutULEB128(uvalue); 475 break; 476 case DW_FORM_strp: { 477 const char *dbg_str = AsCString(); 478 if (dbg_str) { 479 if (verbose) 480 s.Printf(" .debug_str[0x%8.8x] = ", (uint32_t)uvalue); 481 s.QuotedCString(dbg_str); 482 } else { 483 s.PutHex32(uvalue); 484 } 485 } break; 486 487 case DW_FORM_ref_addr: { 488 assert(m_cu); // CU must be valid for DW_FORM_ref_addr objects or we will 489 // get this wrong 490 if (m_cu->GetVersion() <= 2) 491 s.Address(uvalue, sizeof(uint64_t) * 2); 492 else 493 s.Address(uvalue, 4 * 2); // 4 for DWARF32, 8 for DWARF64, but we don't 494 // support DWARF64 yet 495 break; 496 } 497 case DW_FORM_ref1: 498 cu_relative_offset = true; 499 if (verbose) 500 s.Printf("cu + 0x%2.2x", (uint8_t)uvalue); 501 break; 502 case DW_FORM_ref2: 503 cu_relative_offset = true; 504 if (verbose) 505 s.Printf("cu + 0x%4.4x", (uint16_t)uvalue); 506 break; 507 case DW_FORM_ref4: 508 cu_relative_offset = true; 509 if (verbose) 510 s.Printf("cu + 0x%4.4x", (uint32_t)uvalue); 511 break; 512 case DW_FORM_ref8: 513 cu_relative_offset = true; 514 if (verbose) 515 s.Printf("cu + 0x%8.8" PRIx64, uvalue); 516 break; 517 case DW_FORM_ref_udata: 518 cu_relative_offset = true; 519 if (verbose) 520 s.Printf("cu + 0x%" PRIx64, uvalue); 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 if (verbose) 539 s.PutCString(" => "); 540 541 s.Printf("{0x%8.8" PRIx64 "}", uvalue + m_cu->GetOffset()); 542 } 543} 544 545const char *DWARFFormValue::AsCString() const { 546 SymbolFileDWARF *symbol_file = m_cu->GetSymbolFileDWARF(); 547 548 if (m_form == DW_FORM_string) { 549 return m_value.value.cstr; 550 } else if (m_form == DW_FORM_strp) { 551 if (!symbol_file) 552 return nullptr; 553 554 return symbol_file->get_debug_str_data().PeekCStr(m_value.value.uval); 555 } else if (m_form == DW_FORM_GNU_str_index) { 556 if (!symbol_file) 557 return nullptr; 558 559 uint32_t index_size = m_cu->IsDWARF64() ? 8 : 4; 560 lldb::offset_t offset = m_value.value.uval * index_size; 561 dw_offset_t str_offset = 562 symbol_file->get_debug_str_offsets_data().GetMaxU64(&offset, 563 index_size); 564 return symbol_file->get_debug_str_data().PeekCStr(str_offset); 565 } 566 return nullptr; 567} 568 569dw_addr_t DWARFFormValue::Address() const { 570 SymbolFileDWARF *symbol_file = m_cu->GetSymbolFileDWARF(); 571 572 if (m_form == DW_FORM_addr) 573 return Unsigned(); 574 575 assert(m_cu); 576 assert(m_form == DW_FORM_GNU_addr_index); 577 578 if (!symbol_file) 579 return 0; 580 581 uint32_t index_size = m_cu->GetAddressByteSize(); 582 dw_offset_t addr_base = m_cu->GetAddrBase(); 583 lldb::offset_t offset = addr_base + m_value.value.uval * index_size; 584 return symbol_file->get_debug_addr_data().GetMaxU64(&offset, index_size); 585} 586 587uint64_t DWARFFormValue::Reference() const { 588 uint64_t die_offset = m_value.value.uval; 589 switch (m_form) { 590 case DW_FORM_ref1: 591 case DW_FORM_ref2: 592 case DW_FORM_ref4: 593 case DW_FORM_ref8: 594 case DW_FORM_ref_udata: 595 assert(m_cu); // CU must be valid for DW_FORM_ref forms that are compile 596 // unit relative or we will get this wrong 597 die_offset += m_cu->GetOffset(); 598 break; 599 600 default: 601 break; 602 } 603 604 return die_offset; 605} 606 607uint64_t DWARFFormValue::Reference(dw_offset_t base_offset) const { 608 uint64_t die_offset = m_value.value.uval; 609 switch (m_form) { 610 case DW_FORM_ref1: 611 case DW_FORM_ref2: 612 case DW_FORM_ref4: 613 case DW_FORM_ref8: 614 case DW_FORM_ref_udata: 615 die_offset += base_offset; 616 break; 617 618 default: 619 break; 620 } 621 622 return die_offset; 623} 624 625const uint8_t *DWARFFormValue::BlockData() const { return m_value.data; } 626 627bool DWARFFormValue::IsBlockForm(const dw_form_t form) { 628 switch (form) { 629 case DW_FORM_exprloc: 630 case DW_FORM_block: 631 case DW_FORM_block1: 632 case DW_FORM_block2: 633 case DW_FORM_block4: 634 return true; 635 } 636 return false; 637} 638 639bool DWARFFormValue::IsDataForm(const dw_form_t form) { 640 switch (form) { 641 case DW_FORM_sdata: 642 case DW_FORM_udata: 643 case DW_FORM_data1: 644 case DW_FORM_data2: 645 case DW_FORM_data4: 646 case DW_FORM_data8: 647 return true; 648 } 649 return false; 650} 651 652int DWARFFormValue::Compare(const DWARFFormValue &a_value, 653 const DWARFFormValue &b_value) { 654 dw_form_t a_form = a_value.Form(); 655 dw_form_t b_form = b_value.Form(); 656 if (a_form < b_form) 657 return -1; 658 if (a_form > b_form) 659 return 1; 660 switch (a_form) { 661 case DW_FORM_addr: 662 case DW_FORM_flag: 663 case DW_FORM_data1: 664 case DW_FORM_data2: 665 case DW_FORM_data4: 666 case DW_FORM_data8: 667 case DW_FORM_udata: 668 case DW_FORM_ref_addr: 669 case DW_FORM_sec_offset: 670 case DW_FORM_flag_present: 671 case DW_FORM_ref_sig8: 672 case DW_FORM_GNU_addr_index: { 673 uint64_t a = a_value.Unsigned(); 674 uint64_t b = b_value.Unsigned(); 675 if (a < b) 676 return -1; 677 if (a > b) 678 return 1; 679 return 0; 680 } 681 682 case DW_FORM_sdata: { 683 int64_t a = a_value.Signed(); 684 int64_t b = b_value.Signed(); 685 if (a < b) 686 return -1; 687 if (a > b) 688 return 1; 689 return 0; 690 } 691 692 case DW_FORM_string: 693 case DW_FORM_strp: 694 case DW_FORM_GNU_str_index: { 695 const char *a_string = a_value.AsCString(); 696 const char *b_string = b_value.AsCString(); 697 if (a_string == b_string) 698 return 0; 699 else if (a_string && b_string) 700 return strcmp(a_string, b_string); 701 else if (a_string == NULL) 702 return -1; // A string is NULL, and B is valid 703 else 704 return 1; // A string valid, and B is NULL 705 } 706 707 case DW_FORM_block: 708 case DW_FORM_block1: 709 case DW_FORM_block2: 710 case DW_FORM_block4: 711 case DW_FORM_exprloc: { 712 uint64_t a_len = a_value.Unsigned(); 713 uint64_t b_len = b_value.Unsigned(); 714 if (a_len < b_len) 715 return -1; 716 if (a_len > b_len) 717 return 1; 718 // The block lengths are the same 719 return memcmp(a_value.BlockData(), b_value.BlockData(), a_value.Unsigned()); 720 } break; 721 722 case DW_FORM_ref1: 723 case DW_FORM_ref2: 724 case DW_FORM_ref4: 725 case DW_FORM_ref8: 726 case DW_FORM_ref_udata: { 727 uint64_t a = a_value.Reference(); 728 uint64_t b = b_value.Reference(); 729 if (a < b) 730 return -1; 731 if (a > b) 732 return 1; 733 return 0; 734 } 735 736 case DW_FORM_indirect: 737 llvm_unreachable( 738 "This shouldn't happen after the form has been extracted..."); 739 740 default: 741 llvm_unreachable("Unhandled DW_FORM"); 742 } 743 return -1; 744} 745