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