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