1 //===-- DumpDataExtractor.cpp ---------------------------------------------===// 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 "lldb/Core/DumpDataExtractor.h" 10 11 #include "lldb/lldb-defines.h" 12 #include "lldb/lldb-forward.h" 13 14 #include "lldb/Core/Address.h" 15 #include "lldb/Core/Disassembler.h" 16 #include "lldb/Core/ModuleList.h" 17 #include "lldb/Target/ABI.h" 18 #include "lldb/Target/ExecutionContext.h" 19 #include "lldb/Target/ExecutionContextScope.h" 20 #include "lldb/Target/MemoryRegionInfo.h" 21 #include "lldb/Target/MemoryTagManager.h" 22 #include "lldb/Target/MemoryTagMap.h" 23 #include "lldb/Target/Process.h" 24 #include "lldb/Target/SectionLoadList.h" 25 #include "lldb/Target/Target.h" 26 #include "lldb/Utility/DataExtractor.h" 27 #include "lldb/Utility/Log.h" 28 #include "lldb/Utility/Stream.h" 29 30 #include "llvm/ADT/APFloat.h" 31 #include "llvm/ADT/APInt.h" 32 #include "llvm/ADT/ArrayRef.h" 33 #include "llvm/ADT/SmallVector.h" 34 35 #include <limits> 36 #include <memory> 37 #include <string> 38 39 #include <cassert> 40 #include <cctype> 41 #include <cinttypes> 42 #include <cmath> 43 44 #include <bitset> 45 #include <optional> 46 #include <sstream> 47 48 using namespace lldb_private; 49 using namespace lldb; 50 51 #define NON_PRINTABLE_CHAR '.' 52 53 static std::optional<llvm::APInt> GetAPInt(const DataExtractor &data, 54 lldb::offset_t *offset_ptr, 55 lldb::offset_t byte_size) { 56 if (byte_size == 0) 57 return std::nullopt; 58 59 llvm::SmallVector<uint64_t, 2> uint64_array; 60 lldb::offset_t bytes_left = byte_size; 61 uint64_t u64; 62 const lldb::ByteOrder byte_order = data.GetByteOrder(); 63 if (byte_order == lldb::eByteOrderLittle) { 64 while (bytes_left > 0) { 65 if (bytes_left >= 8) { 66 u64 = data.GetU64(offset_ptr); 67 bytes_left -= 8; 68 } else { 69 u64 = data.GetMaxU64(offset_ptr, (uint32_t)bytes_left); 70 bytes_left = 0; 71 } 72 uint64_array.push_back(u64); 73 } 74 return llvm::APInt(byte_size * 8, llvm::ArrayRef<uint64_t>(uint64_array)); 75 } else if (byte_order == lldb::eByteOrderBig) { 76 lldb::offset_t be_offset = *offset_ptr + byte_size; 77 lldb::offset_t temp_offset; 78 while (bytes_left > 0) { 79 if (bytes_left >= 8) { 80 be_offset -= 8; 81 temp_offset = be_offset; 82 u64 = data.GetU64(&temp_offset); 83 bytes_left -= 8; 84 } else { 85 be_offset -= bytes_left; 86 temp_offset = be_offset; 87 u64 = data.GetMaxU64(&temp_offset, (uint32_t)bytes_left); 88 bytes_left = 0; 89 } 90 uint64_array.push_back(u64); 91 } 92 *offset_ptr += byte_size; 93 return llvm::APInt(byte_size * 8, llvm::ArrayRef<uint64_t>(uint64_array)); 94 } 95 return std::nullopt; 96 } 97 98 static lldb::offset_t DumpAPInt(Stream *s, const DataExtractor &data, 99 lldb::offset_t offset, lldb::offset_t byte_size, 100 bool is_signed, unsigned radix) { 101 std::optional<llvm::APInt> apint = GetAPInt(data, &offset, byte_size); 102 if (apint) { 103 std::string apint_str = toString(*apint, radix, is_signed); 104 switch (radix) { 105 case 2: 106 s->Write("0b", 2); 107 break; 108 case 8: 109 s->Write("0", 1); 110 break; 111 case 10: 112 break; 113 } 114 s->Write(apint_str.c_str(), apint_str.size()); 115 } 116 return offset; 117 } 118 119 /// Dumps decoded instructions to a stream. 120 static lldb::offset_t DumpInstructions(const DataExtractor &DE, Stream *s, 121 ExecutionContextScope *exe_scope, 122 offset_t start_offset, 123 uint64_t base_addr, 124 size_t number_of_instructions) { 125 offset_t offset = start_offset; 126 127 TargetSP target_sp; 128 if (exe_scope) 129 target_sp = exe_scope->CalculateTarget(); 130 if (target_sp) { 131 DisassemblerSP disassembler_sp(Disassembler::FindPlugin( 132 target_sp->GetArchitecture(), target_sp->GetDisassemblyFlavor(), 133 target_sp->GetDisassemblyCPU(), target_sp->GetDisassemblyFeatures(), 134 nullptr)); 135 if (disassembler_sp) { 136 lldb::addr_t addr = base_addr + start_offset; 137 lldb_private::Address so_addr; 138 bool data_from_file = true; 139 if (target_sp->ResolveLoadAddress(addr, so_addr)) { 140 data_from_file = false; 141 } else { 142 if (!target_sp->HasLoadedSections() || 143 !target_sp->GetImages().ResolveFileAddress(addr, so_addr)) 144 so_addr.SetRawAddress(addr); 145 } 146 147 size_t bytes_consumed = disassembler_sp->DecodeInstructions( 148 so_addr, DE, start_offset, number_of_instructions, false, 149 data_from_file); 150 151 if (bytes_consumed) { 152 offset += bytes_consumed; 153 const bool show_address = base_addr != LLDB_INVALID_ADDRESS; 154 const bool show_bytes = false; 155 const bool show_control_flow_kind = false; 156 ExecutionContext exe_ctx; 157 exe_scope->CalculateExecutionContext(exe_ctx); 158 disassembler_sp->GetInstructionList().Dump( 159 s, show_address, show_bytes, show_control_flow_kind, &exe_ctx); 160 } 161 } 162 } else 163 s->Printf("invalid target"); 164 165 return offset; 166 } 167 168 /// Prints the specific escape sequence of the given character to the stream. 169 /// If the character doesn't have a known specific escape sequence (e.g., '\a', 170 /// '\n' but not generic escape sequences such as'\x12'), this function will 171 /// not modify the stream and return false. 172 static bool TryDumpSpecialEscapedChar(Stream &s, const char c) { 173 switch (c) { 174 case '\033': 175 // Common non-standard escape code for 'escape'. 176 s.Printf("\\e"); 177 return true; 178 case '\a': 179 s.Printf("\\a"); 180 return true; 181 case '\b': 182 s.Printf("\\b"); 183 return true; 184 case '\f': 185 s.Printf("\\f"); 186 return true; 187 case '\n': 188 s.Printf("\\n"); 189 return true; 190 case '\r': 191 s.Printf("\\r"); 192 return true; 193 case '\t': 194 s.Printf("\\t"); 195 return true; 196 case '\v': 197 s.Printf("\\v"); 198 return true; 199 case '\0': 200 s.Printf("\\0"); 201 return true; 202 default: 203 return false; 204 } 205 } 206 207 /// Dump the character to a stream. A character that is not printable will be 208 /// represented by its escape sequence. 209 static void DumpCharacter(Stream &s, const char c) { 210 if (TryDumpSpecialEscapedChar(s, c)) 211 return; 212 if (llvm::isPrint(c)) { 213 s.PutChar(c); 214 return; 215 } 216 s.Printf("\\x%2.2hhx", c); 217 } 218 219 /// Dump a floating point type. 220 template <typename FloatT> 221 void DumpFloatingPoint(std::ostringstream &ss, FloatT f) { 222 static_assert(std::is_floating_point<FloatT>::value, 223 "Only floating point types can be dumped."); 224 // NaN and Inf are potentially implementation defined and on Darwin it 225 // seems NaNs are printed without their sign. Manually implement dumping them 226 // here to avoid having to deal with platform differences. 227 if (std::isnan(f)) { 228 if (std::signbit(f)) 229 ss << '-'; 230 ss << "nan"; 231 return; 232 } 233 if (std::isinf(f)) { 234 if (std::signbit(f)) 235 ss << '-'; 236 ss << "inf"; 237 return; 238 } 239 ss << f; 240 } 241 242 static std::optional<MemoryTagMap> 243 GetMemoryTags(lldb::addr_t addr, size_t length, 244 ExecutionContextScope *exe_scope) { 245 assert(addr != LLDB_INVALID_ADDRESS); 246 247 if (!exe_scope) 248 return std::nullopt; 249 250 TargetSP target_sp = exe_scope->CalculateTarget(); 251 if (!target_sp) 252 return std::nullopt; 253 254 ProcessSP process_sp = target_sp->CalculateProcess(); 255 if (!process_sp) 256 return std::nullopt; 257 258 llvm::Expected<const MemoryTagManager *> tag_manager_or_err = 259 process_sp->GetMemoryTagManager(); 260 if (!tag_manager_or_err) { 261 llvm::consumeError(tag_manager_or_err.takeError()); 262 return std::nullopt; 263 } 264 265 MemoryRegionInfos memory_regions; 266 // Don't check return status, list will be just empty if an error happened. 267 process_sp->GetMemoryRegions(memory_regions); 268 269 llvm::Expected<std::vector<MemoryTagManager::TagRange>> tagged_ranges_or_err = 270 (*tag_manager_or_err) 271 ->MakeTaggedRanges(addr, addr + length, memory_regions); 272 // Here we know that our range will not be inverted but we must still check 273 // for an error. 274 if (!tagged_ranges_or_err) { 275 llvm::consumeError(tagged_ranges_or_err.takeError()); 276 return std::nullopt; 277 } 278 if (tagged_ranges_or_err->empty()) 279 return std::nullopt; 280 281 MemoryTagMap memory_tag_map(*tag_manager_or_err); 282 for (const MemoryTagManager::TagRange &range : *tagged_ranges_or_err) { 283 llvm::Expected<std::vector<lldb::addr_t>> tags_or_err = 284 process_sp->ReadMemoryTags(range.GetRangeBase(), range.GetByteSize()); 285 286 if (tags_or_err) 287 memory_tag_map.InsertTags(range.GetRangeBase(), *tags_or_err); 288 else 289 llvm::consumeError(tags_or_err.takeError()); 290 } 291 292 if (memory_tag_map.Empty()) 293 return std::nullopt; 294 295 return memory_tag_map; 296 } 297 298 static void printMemoryTags(const DataExtractor &DE, Stream *s, 299 lldb::addr_t addr, size_t len, 300 const std::optional<MemoryTagMap> &memory_tag_map) { 301 std::vector<std::optional<lldb::addr_t>> tags = 302 memory_tag_map->GetTags(addr, len); 303 304 // Only print if there is at least one tag for this line 305 if (tags.empty()) 306 return; 307 308 s->Printf(" (tag%s:", tags.size() > 1 ? "s" : ""); 309 // Some granules may not be tagged but print something for them 310 // so that the ordering remains intact. 311 for (auto tag : tags) { 312 if (tag) 313 s->Printf(" 0x%" PRIx64, *tag); 314 else 315 s->PutCString(" <no tag>"); 316 } 317 s->PutCString(")"); 318 } 319 320 static const llvm::fltSemantics &GetFloatSemantics(const TargetSP &target_sp, 321 size_t byte_size) { 322 if (target_sp) { 323 auto type_system_or_err = 324 target_sp->GetScratchTypeSystemForLanguage(eLanguageTypeC); 325 if (!type_system_or_err) 326 llvm::consumeError(type_system_or_err.takeError()); 327 else if (auto ts = *type_system_or_err) 328 return ts->GetFloatTypeSemantics(byte_size); 329 } 330 // No target, just make a reasonable guess 331 switch(byte_size) { 332 case 2: 333 return llvm::APFloat::IEEEhalf(); 334 case 4: 335 return llvm::APFloat::IEEEsingle(); 336 case 8: 337 return llvm::APFloat::IEEEdouble(); 338 } 339 return llvm::APFloat::Bogus(); 340 } 341 342 lldb::offset_t lldb_private::DumpDataExtractor( 343 const DataExtractor &DE, Stream *s, offset_t start_offset, 344 lldb::Format item_format, size_t item_byte_size, size_t item_count, 345 size_t num_per_line, uint64_t base_addr, 346 uint32_t item_bit_size, // If zero, this is not a bitfield value, if 347 // non-zero, the value is a bitfield 348 uint32_t item_bit_offset, // If "item_bit_size" is non-zero, this is the 349 // shift amount to apply to a bitfield 350 ExecutionContextScope *exe_scope, bool show_memory_tags) { 351 if (s == nullptr) 352 return start_offset; 353 354 if (item_format == eFormatPointer) { 355 if (item_byte_size != 4 && item_byte_size != 8) 356 item_byte_size = s->GetAddressByteSize(); 357 } 358 359 offset_t offset = start_offset; 360 361 std::optional<MemoryTagMap> memory_tag_map; 362 if (show_memory_tags && base_addr != LLDB_INVALID_ADDRESS) 363 memory_tag_map = 364 GetMemoryTags(base_addr, DE.GetByteSize() - offset, exe_scope); 365 366 if (item_format == eFormatInstruction) 367 return DumpInstructions(DE, s, exe_scope, start_offset, base_addr, 368 item_count); 369 370 if ((item_format == eFormatOSType || item_format == eFormatAddressInfo) && 371 item_byte_size > 8) 372 item_format = eFormatHex; 373 374 lldb::offset_t line_start_offset = start_offset; 375 for (uint32_t count = 0; DE.ValidOffset(offset) && count < item_count; 376 ++count) { 377 // If we are at the beginning or end of a line 378 // Note that the last line is handled outside this for loop. 379 if ((count % num_per_line) == 0) { 380 // If we are at the end of a line 381 if (count > 0) { 382 if (item_format == eFormatBytesWithASCII && 383 offset > line_start_offset) { 384 s->Printf("%*s", 385 static_cast<int>( 386 (num_per_line - (offset - line_start_offset)) * 3 + 2), 387 ""); 388 DumpDataExtractor(DE, s, line_start_offset, eFormatCharPrintable, 1, 389 offset - line_start_offset, SIZE_MAX, 390 LLDB_INVALID_ADDRESS, 0, 0); 391 } 392 393 if (base_addr != LLDB_INVALID_ADDRESS && memory_tag_map) { 394 size_t line_len = offset - line_start_offset; 395 lldb::addr_t line_base = 396 base_addr + 397 (offset - start_offset - line_len) / DE.getTargetByteSize(); 398 printMemoryTags(DE, s, line_base, line_len, memory_tag_map); 399 } 400 401 s->EOL(); 402 } 403 if (base_addr != LLDB_INVALID_ADDRESS) 404 s->Printf("0x%8.8" PRIx64 ": ", 405 (uint64_t)(base_addr + 406 (offset - start_offset) / DE.getTargetByteSize())); 407 408 line_start_offset = offset; 409 } else if (item_format != eFormatChar && 410 item_format != eFormatCharPrintable && 411 item_format != eFormatCharArray && count > 0) { 412 s->PutChar(' '); 413 } 414 415 switch (item_format) { 416 case eFormatBoolean: 417 if (item_byte_size <= 8) 418 s->Printf("%s", DE.GetMaxU64Bitfield(&offset, item_byte_size, 419 item_bit_size, item_bit_offset) 420 ? "true" 421 : "false"); 422 else { 423 s->Printf("error: unsupported byte size (%" PRIu64 424 ") for boolean format", 425 (uint64_t)item_byte_size); 426 return offset; 427 } 428 break; 429 430 case eFormatBinary: 431 if (item_byte_size <= 8) { 432 uint64_t uval64 = DE.GetMaxU64Bitfield(&offset, item_byte_size, 433 item_bit_size, item_bit_offset); 434 // Avoid std::bitset<64>::to_string() since it is missing in earlier 435 // C++ libraries 436 std::string binary_value(64, '0'); 437 std::bitset<64> bits(uval64); 438 for (uint32_t i = 0; i < 64; ++i) 439 if (bits[i]) 440 binary_value[64 - 1 - i] = '1'; 441 if (item_bit_size > 0) 442 s->Printf("0b%s", binary_value.c_str() + 64 - item_bit_size); 443 else if (item_byte_size > 0 && item_byte_size <= 8) 444 s->Printf("0b%s", binary_value.c_str() + 64 - item_byte_size * 8); 445 } else { 446 const bool is_signed = false; 447 const unsigned radix = 2; 448 offset = DumpAPInt(s, DE, offset, item_byte_size, is_signed, radix); 449 } 450 break; 451 452 case eFormatBytes: 453 case eFormatBytesWithASCII: 454 for (uint32_t i = 0; i < item_byte_size; ++i) { 455 s->Printf("%2.2x", DE.GetU8(&offset)); 456 } 457 458 // Put an extra space between the groups of bytes if more than one is 459 // being dumped in a group (item_byte_size is more than 1). 460 if (item_byte_size > 1) 461 s->PutChar(' '); 462 break; 463 464 case eFormatChar: 465 case eFormatCharPrintable: 466 case eFormatCharArray: { 467 // Reject invalid item_byte_size. 468 if (item_byte_size > 8) { 469 s->Printf("error: unsupported byte size (%" PRIu64 ") for char format", 470 (uint64_t)item_byte_size); 471 return offset; 472 } 473 474 // If we are only printing one character surround it with single quotes 475 if (item_count == 1 && item_format == eFormatChar) 476 s->PutChar('\''); 477 478 const uint64_t ch = DE.GetMaxU64Bitfield(&offset, item_byte_size, 479 item_bit_size, item_bit_offset); 480 if (llvm::isPrint(ch)) 481 s->Printf("%c", (char)ch); 482 else if (item_format != eFormatCharPrintable) { 483 if (!TryDumpSpecialEscapedChar(*s, ch)) { 484 if (item_byte_size == 1) 485 s->Printf("\\x%2.2x", (uint8_t)ch); 486 else 487 s->Printf("%" PRIu64, ch); 488 } 489 } else { 490 s->PutChar(NON_PRINTABLE_CHAR); 491 } 492 493 // If we are only printing one character surround it with single quotes 494 if (item_count == 1 && item_format == eFormatChar) 495 s->PutChar('\''); 496 } break; 497 498 case eFormatEnum: // Print enum value as a signed integer when we don't get 499 // the enum type 500 case eFormatDecimal: 501 if (item_byte_size <= 8) 502 s->Printf("%" PRId64, 503 DE.GetMaxS64Bitfield(&offset, item_byte_size, item_bit_size, 504 item_bit_offset)); 505 else { 506 const bool is_signed = true; 507 const unsigned radix = 10; 508 offset = DumpAPInt(s, DE, offset, item_byte_size, is_signed, radix); 509 } 510 break; 511 512 case eFormatUnsigned: 513 if (item_byte_size <= 8) 514 s->Printf("%" PRIu64, 515 DE.GetMaxU64Bitfield(&offset, item_byte_size, item_bit_size, 516 item_bit_offset)); 517 else { 518 const bool is_signed = false; 519 const unsigned radix = 10; 520 offset = DumpAPInt(s, DE, offset, item_byte_size, is_signed, radix); 521 } 522 break; 523 524 case eFormatOctal: 525 if (item_byte_size <= 8) 526 s->Printf("0%" PRIo64, 527 DE.GetMaxS64Bitfield(&offset, item_byte_size, item_bit_size, 528 item_bit_offset)); 529 else { 530 const bool is_signed = false; 531 const unsigned radix = 8; 532 offset = DumpAPInt(s, DE, offset, item_byte_size, is_signed, radix); 533 } 534 break; 535 536 case eFormatOSType: { 537 uint64_t uval64 = DE.GetMaxU64Bitfield(&offset, item_byte_size, 538 item_bit_size, item_bit_offset); 539 s->PutChar('\''); 540 for (uint32_t i = 0; i < item_byte_size; ++i) { 541 uint8_t ch = (uint8_t)(uval64 >> ((item_byte_size - i - 1) * 8)); 542 DumpCharacter(*s, ch); 543 } 544 s->PutChar('\''); 545 } break; 546 547 case eFormatCString: { 548 const char *cstr = DE.GetCStr(&offset); 549 550 if (!cstr) { 551 s->Printf("NULL"); 552 offset = LLDB_INVALID_OFFSET; 553 } else { 554 s->PutChar('\"'); 555 556 while (const char c = *cstr) { 557 DumpCharacter(*s, c); 558 ++cstr; 559 } 560 561 s->PutChar('\"'); 562 } 563 } break; 564 565 case eFormatPointer: 566 DumpAddress(s->AsRawOstream(), 567 DE.GetMaxU64Bitfield(&offset, item_byte_size, item_bit_size, 568 item_bit_offset), 569 sizeof(addr_t)); 570 break; 571 572 case eFormatComplexInteger: { 573 size_t complex_int_byte_size = item_byte_size / 2; 574 575 if (complex_int_byte_size > 0 && complex_int_byte_size <= 8) { 576 s->Printf("%" PRIu64, 577 DE.GetMaxU64Bitfield(&offset, complex_int_byte_size, 0, 0)); 578 s->Printf(" + %" PRIu64 "i", 579 DE.GetMaxU64Bitfield(&offset, complex_int_byte_size, 0, 0)); 580 } else { 581 s->Printf("error: unsupported byte size (%" PRIu64 582 ") for complex integer format", 583 (uint64_t)item_byte_size); 584 return offset; 585 } 586 } break; 587 588 case eFormatComplex: 589 if (sizeof(float) * 2 == item_byte_size) { 590 float f32_1 = DE.GetFloat(&offset); 591 float f32_2 = DE.GetFloat(&offset); 592 593 s->Printf("%g + %gi", f32_1, f32_2); 594 break; 595 } else if (sizeof(double) * 2 == item_byte_size) { 596 double d64_1 = DE.GetDouble(&offset); 597 double d64_2 = DE.GetDouble(&offset); 598 599 s->Printf("%lg + %lgi", d64_1, d64_2); 600 break; 601 } else if (sizeof(long double) * 2 == item_byte_size) { 602 long double ld64_1 = DE.GetLongDouble(&offset); 603 long double ld64_2 = DE.GetLongDouble(&offset); 604 s->Printf("%Lg + %Lgi", ld64_1, ld64_2); 605 break; 606 } else { 607 s->Printf("error: unsupported byte size (%" PRIu64 608 ") for complex float format", 609 (uint64_t)item_byte_size); 610 return offset; 611 } 612 break; 613 614 default: 615 case eFormatDefault: 616 case eFormatHex: 617 case eFormatHexUppercase: { 618 bool wantsuppercase = (item_format == eFormatHexUppercase); 619 switch (item_byte_size) { 620 case 1: 621 case 2: 622 case 4: 623 case 8: 624 if (Target::GetGlobalProperties() 625 .ShowHexVariableValuesWithLeadingZeroes()) { 626 s->Printf(wantsuppercase ? "0x%*.*" PRIX64 : "0x%*.*" PRIx64, 627 (int)(2 * item_byte_size), (int)(2 * item_byte_size), 628 DE.GetMaxU64Bitfield(&offset, item_byte_size, item_bit_size, 629 item_bit_offset)); 630 } else { 631 s->Printf(wantsuppercase ? "0x%" PRIX64 : "0x%" PRIx64, 632 DE.GetMaxU64Bitfield(&offset, item_byte_size, item_bit_size, 633 item_bit_offset)); 634 } 635 break; 636 default: { 637 assert(item_bit_size == 0 && item_bit_offset == 0); 638 const uint8_t *bytes = 639 (const uint8_t *)DE.GetData(&offset, item_byte_size); 640 if (bytes) { 641 s->PutCString("0x"); 642 uint32_t idx; 643 if (DE.GetByteOrder() == eByteOrderBig) { 644 for (idx = 0; idx < item_byte_size; ++idx) 645 s->Printf(wantsuppercase ? "%2.2X" : "%2.2x", bytes[idx]); 646 } else { 647 for (idx = 0; idx < item_byte_size; ++idx) 648 s->Printf(wantsuppercase ? "%2.2X" : "%2.2x", 649 bytes[item_byte_size - 1 - idx]); 650 } 651 } 652 } break; 653 } 654 } break; 655 656 case eFormatFloat: { 657 TargetSP target_sp; 658 if (exe_scope) 659 target_sp = exe_scope->CalculateTarget(); 660 661 std::optional<unsigned> format_max_padding; 662 if (target_sp) 663 format_max_padding = target_sp->GetMaxZeroPaddingInFloatFormat(); 664 665 // Show full precision when printing float values 666 const unsigned format_precision = 0; 667 668 const llvm::fltSemantics &semantics = 669 GetFloatSemantics(target_sp, item_byte_size); 670 671 // Recalculate the byte size in case of a difference. This is possible 672 // when item_byte_size is 16 (128-bit), because you could get back the 673 // x87DoubleExtended semantics which has a byte size of 10 (80-bit). 674 const size_t semantics_byte_size = 675 (llvm::APFloat::getSizeInBits(semantics) + 7) / 8; 676 std::optional<llvm::APInt> apint = 677 GetAPInt(DE, &offset, semantics_byte_size); 678 if (apint) { 679 llvm::APFloat apfloat(semantics, *apint); 680 llvm::SmallVector<char, 256> sv; 681 if (format_max_padding) 682 apfloat.toString(sv, format_precision, *format_max_padding); 683 else 684 apfloat.toString(sv, format_precision); 685 s->AsRawOstream() << sv; 686 } else { 687 s->Format("error: unsupported byte size ({0}) for float format", 688 item_byte_size); 689 return offset; 690 } 691 } break; 692 693 case eFormatUnicode16: 694 s->Printf("U+%4.4x", DE.GetU16(&offset)); 695 break; 696 697 case eFormatUnicode32: 698 s->Printf("U+0x%8.8x", DE.GetU32(&offset)); 699 break; 700 701 case eFormatAddressInfo: { 702 addr_t addr = DE.GetMaxU64Bitfield(&offset, item_byte_size, item_bit_size, 703 item_bit_offset); 704 s->Printf("0x%*.*" PRIx64, (int)(2 * item_byte_size), 705 (int)(2 * item_byte_size), addr); 706 if (exe_scope) { 707 TargetSP target_sp(exe_scope->CalculateTarget()); 708 lldb_private::Address so_addr; 709 if (target_sp) { 710 if (target_sp->ResolveLoadAddress(addr, so_addr)) { 711 s->PutChar(' '); 712 so_addr.Dump(s, exe_scope, Address::DumpStyleResolvedDescription, 713 Address::DumpStyleModuleWithFileAddress); 714 } else { 715 so_addr.SetOffset(addr); 716 so_addr.Dump(s, exe_scope, 717 Address::DumpStyleResolvedPointerDescription); 718 if (ProcessSP process_sp = exe_scope->CalculateProcess()) { 719 if (ABISP abi_sp = process_sp->GetABI()) { 720 addr_t addr_fixed = abi_sp->FixCodeAddress(addr); 721 if (target_sp->ResolveLoadAddress(addr_fixed, so_addr)) { 722 s->PutChar(' '); 723 s->Printf("(0x%*.*" PRIx64 ")", (int)(2 * item_byte_size), 724 (int)(2 * item_byte_size), addr_fixed); 725 s->PutChar(' '); 726 so_addr.Dump(s, exe_scope, 727 Address::DumpStyleResolvedDescription, 728 Address::DumpStyleModuleWithFileAddress); 729 } 730 } 731 } 732 } 733 } 734 } 735 } break; 736 737 case eFormatHexFloat: 738 if (sizeof(float) == item_byte_size) { 739 char float_cstr[256]; 740 llvm::APFloat ap_float(DE.GetFloat(&offset)); 741 ap_float.convertToHexString(float_cstr, 0, false, 742 llvm::APFloat::rmNearestTiesToEven); 743 s->Printf("%s", float_cstr); 744 break; 745 } else if (sizeof(double) == item_byte_size) { 746 char float_cstr[256]; 747 llvm::APFloat ap_float(DE.GetDouble(&offset)); 748 ap_float.convertToHexString(float_cstr, 0, false, 749 llvm::APFloat::rmNearestTiesToEven); 750 s->Printf("%s", float_cstr); 751 break; 752 } else { 753 s->Printf("error: unsupported byte size (%" PRIu64 754 ") for hex float format", 755 (uint64_t)item_byte_size); 756 return offset; 757 } 758 break; 759 760 // please keep the single-item formats below in sync with 761 // FormatManager::GetSingleItemFormat if you fail to do so, users will 762 // start getting different outputs depending on internal implementation 763 // details they should not care about || 764 case eFormatVectorOfChar: // || 765 s->PutChar('{'); // \/ 766 offset = 767 DumpDataExtractor(DE, s, offset, eFormatCharArray, 1, item_byte_size, 768 item_byte_size, LLDB_INVALID_ADDRESS, 0, 0); 769 s->PutChar('}'); 770 break; 771 772 case eFormatVectorOfSInt8: 773 s->PutChar('{'); 774 offset = 775 DumpDataExtractor(DE, s, offset, eFormatDecimal, 1, item_byte_size, 776 item_byte_size, LLDB_INVALID_ADDRESS, 0, 0); 777 s->PutChar('}'); 778 break; 779 780 case eFormatVectorOfUInt8: 781 s->PutChar('{'); 782 offset = DumpDataExtractor(DE, s, offset, eFormatHex, 1, item_byte_size, 783 item_byte_size, LLDB_INVALID_ADDRESS, 0, 0); 784 s->PutChar('}'); 785 break; 786 787 case eFormatVectorOfSInt16: 788 s->PutChar('{'); 789 offset = DumpDataExtractor( 790 DE, s, offset, eFormatDecimal, sizeof(uint16_t), 791 item_byte_size / sizeof(uint16_t), item_byte_size / sizeof(uint16_t), 792 LLDB_INVALID_ADDRESS, 0, 0); 793 s->PutChar('}'); 794 break; 795 796 case eFormatVectorOfUInt16: 797 s->PutChar('{'); 798 offset = DumpDataExtractor(DE, s, offset, eFormatHex, sizeof(uint16_t), 799 item_byte_size / sizeof(uint16_t), 800 item_byte_size / sizeof(uint16_t), 801 LLDB_INVALID_ADDRESS, 0, 0); 802 s->PutChar('}'); 803 break; 804 805 case eFormatVectorOfSInt32: 806 s->PutChar('{'); 807 offset = DumpDataExtractor( 808 DE, s, offset, eFormatDecimal, sizeof(uint32_t), 809 item_byte_size / sizeof(uint32_t), item_byte_size / sizeof(uint32_t), 810 LLDB_INVALID_ADDRESS, 0, 0); 811 s->PutChar('}'); 812 break; 813 814 case eFormatVectorOfUInt32: 815 s->PutChar('{'); 816 offset = DumpDataExtractor(DE, s, offset, eFormatHex, sizeof(uint32_t), 817 item_byte_size / sizeof(uint32_t), 818 item_byte_size / sizeof(uint32_t), 819 LLDB_INVALID_ADDRESS, 0, 0); 820 s->PutChar('}'); 821 break; 822 823 case eFormatVectorOfSInt64: 824 s->PutChar('{'); 825 offset = DumpDataExtractor( 826 DE, s, offset, eFormatDecimal, sizeof(uint64_t), 827 item_byte_size / sizeof(uint64_t), item_byte_size / sizeof(uint64_t), 828 LLDB_INVALID_ADDRESS, 0, 0); 829 s->PutChar('}'); 830 break; 831 832 case eFormatVectorOfUInt64: 833 s->PutChar('{'); 834 offset = DumpDataExtractor(DE, s, offset, eFormatHex, sizeof(uint64_t), 835 item_byte_size / sizeof(uint64_t), 836 item_byte_size / sizeof(uint64_t), 837 LLDB_INVALID_ADDRESS, 0, 0); 838 s->PutChar('}'); 839 break; 840 841 case eFormatVectorOfFloat16: 842 s->PutChar('{'); 843 offset = 844 DumpDataExtractor(DE, s, offset, eFormatFloat, 2, item_byte_size / 2, 845 item_byte_size / 2, LLDB_INVALID_ADDRESS, 0, 0); 846 s->PutChar('}'); 847 break; 848 849 case eFormatVectorOfFloat32: 850 s->PutChar('{'); 851 offset = 852 DumpDataExtractor(DE, s, offset, eFormatFloat, 4, item_byte_size / 4, 853 item_byte_size / 4, LLDB_INVALID_ADDRESS, 0, 0); 854 s->PutChar('}'); 855 break; 856 857 case eFormatVectorOfFloat64: 858 s->PutChar('{'); 859 offset = 860 DumpDataExtractor(DE, s, offset, eFormatFloat, 8, item_byte_size / 8, 861 item_byte_size / 8, LLDB_INVALID_ADDRESS, 0, 0); 862 s->PutChar('}'); 863 break; 864 865 case eFormatVectorOfUInt128: 866 s->PutChar('{'); 867 offset = 868 DumpDataExtractor(DE, s, offset, eFormatHex, 16, item_byte_size / 16, 869 item_byte_size / 16, LLDB_INVALID_ADDRESS, 0, 0); 870 s->PutChar('}'); 871 break; 872 } 873 } 874 875 // If anything was printed we want to catch the end of the last line. 876 // Since we will exit the for loop above before we get a chance to append to 877 // it normally. 878 if (offset > line_start_offset) { 879 if (item_format == eFormatBytesWithASCII) { 880 s->Printf("%*s", 881 static_cast<int>( 882 (num_per_line - (offset - line_start_offset)) * 3 + 2), 883 ""); 884 DumpDataExtractor(DE, s, line_start_offset, eFormatCharPrintable, 1, 885 offset - line_start_offset, SIZE_MAX, 886 LLDB_INVALID_ADDRESS, 0, 0); 887 } 888 889 if (base_addr != LLDB_INVALID_ADDRESS && memory_tag_map) { 890 size_t line_len = offset - line_start_offset; 891 lldb::addr_t line_base = base_addr + (offset - start_offset - line_len) / 892 DE.getTargetByteSize(); 893 printMemoryTags(DE, s, line_base, line_len, memory_tag_map); 894 } 895 } 896 897 return offset; // Return the offset at which we ended up 898 } 899 900 void lldb_private::DumpHexBytes(Stream *s, const void *src, size_t src_len, 901 uint32_t bytes_per_line, 902 lldb::addr_t base_addr) { 903 DataExtractor data(src, src_len, lldb::eByteOrderLittle, 4); 904 DumpDataExtractor(data, s, 905 0, // Offset into "src" 906 lldb::eFormatBytes, // Dump as hex bytes 907 1, // Size of each item is 1 for single bytes 908 src_len, // Number of bytes 909 bytes_per_line, // Num bytes per line 910 base_addr, // Base address 911 0, 0); // Bitfield info 912 } 913