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