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