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