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