129cb868aSZachary Turner //===-- DumpDataExtractor.cpp -----------------------------------*- C++ -*-===// 229cb868aSZachary Turner // 32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information. 52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 629cb868aSZachary Turner // 729cb868aSZachary Turner //===----------------------------------------------------------------------===// 829cb868aSZachary Turner 929cb868aSZachary Turner #include "lldb/Core/DumpDataExtractor.h" 1029cb868aSZachary Turner 11672d2c12SJonas Devlieghere #include "lldb/lldb-defines.h" 12672d2c12SJonas Devlieghere #include "lldb/lldb-forward.h" 132f3df613SZachary Turner 14672d2c12SJonas Devlieghere #include "lldb/Core/Address.h" 1529cb868aSZachary Turner #include "lldb/Core/Disassembler.h" 16672d2c12SJonas Devlieghere #include "lldb/Core/ModuleList.h" 1729cb868aSZachary Turner #include "lldb/Target/ExecutionContext.h" 1829cb868aSZachary Turner #include "lldb/Target/ExecutionContextScope.h" 1929cb868aSZachary Turner #include "lldb/Target/SectionLoadList.h" 2029cb868aSZachary Turner #include "lldb/Target/Target.h" 21666cc0b2SZachary Turner #include "lldb/Utility/DataExtractor.h" 225e777e1eSAlex Langford #include "lldb/Utility/Log.h" 2329cb868aSZachary Turner #include "lldb/Utility/Stream.h" 2429cb868aSZachary Turner 25672d2c12SJonas Devlieghere #include "clang/AST/ASTContext.h" 26672d2c12SJonas Devlieghere #include "clang/AST/CanonicalType.h" 272f3df613SZachary Turner 28672d2c12SJonas Devlieghere #include "llvm/ADT/APFloat.h" 29672d2c12SJonas Devlieghere #include "llvm/ADT/APInt.h" 30672d2c12SJonas Devlieghere #include "llvm/ADT/ArrayRef.h" 315e777e1eSAlex Langford #include "llvm/ADT/Optional.h" 32672d2c12SJonas Devlieghere #include "llvm/ADT/SmallVector.h" 332f3df613SZachary Turner 34672d2c12SJonas Devlieghere #include <limits> 35672d2c12SJonas Devlieghere #include <memory> 36672d2c12SJonas Devlieghere #include <string> 372f3df613SZachary Turner 38672d2c12SJonas Devlieghere #include <assert.h> 39672d2c12SJonas Devlieghere #include <ctype.h> 40672d2c12SJonas Devlieghere #include <inttypes.h> 41672d2c12SJonas Devlieghere #include <math.h> 422f3df613SZachary Turner 4329cb868aSZachary Turner #include <bitset> 4429cb868aSZachary Turner #include <sstream> 4529cb868aSZachary Turner 4629cb868aSZachary Turner using namespace lldb_private; 4729cb868aSZachary Turner using namespace lldb; 4829cb868aSZachary Turner 4929cb868aSZachary Turner #define NON_PRINTABLE_CHAR '.' 5029cb868aSZachary Turner 5129cb868aSZachary Turner static float half2float(uint16_t half) { 5229cb868aSZachary Turner union { 5329cb868aSZachary Turner float f; 5429cb868aSZachary Turner uint32_t u; 5529cb868aSZachary Turner } u; 5629cb868aSZachary Turner int32_t v = (int16_t)half; 5729cb868aSZachary Turner 5829cb868aSZachary Turner if (0 == (v & 0x7c00)) { 5929cb868aSZachary Turner u.u = v & 0x80007FFFU; 6029cb868aSZachary Turner return u.f * ldexpf(1, 125); 6129cb868aSZachary Turner } 6229cb868aSZachary Turner 6329cb868aSZachary Turner v <<= 13; 6429cb868aSZachary Turner u.u = v | 0x70000000U; 6529cb868aSZachary Turner return u.f * ldexpf(1, -112); 6629cb868aSZachary Turner } 6729cb868aSZachary Turner 685e777e1eSAlex Langford static llvm::Optional<llvm::APInt> GetAPInt(const DataExtractor &data, 695e777e1eSAlex Langford lldb::offset_t *offset_ptr, 705e777e1eSAlex Langford lldb::offset_t byte_size) { 71*b482db6dSAlex Langford if (byte_size == 0) 72*b482db6dSAlex Langford return llvm::None; 73*b482db6dSAlex Langford 7429cb868aSZachary Turner llvm::SmallVector<uint64_t, 2> uint64_array; 7529cb868aSZachary Turner lldb::offset_t bytes_left = byte_size; 7629cb868aSZachary Turner uint64_t u64; 7729cb868aSZachary Turner const lldb::ByteOrder byte_order = data.GetByteOrder(); 7829cb868aSZachary Turner if (byte_order == lldb::eByteOrderLittle) { 7929cb868aSZachary Turner while (bytes_left > 0) { 8029cb868aSZachary Turner if (bytes_left >= 8) { 8129cb868aSZachary Turner u64 = data.GetU64(offset_ptr); 8229cb868aSZachary Turner bytes_left -= 8; 8329cb868aSZachary Turner } else { 8429cb868aSZachary Turner u64 = data.GetMaxU64(offset_ptr, (uint32_t)bytes_left); 8529cb868aSZachary Turner bytes_left = 0; 8629cb868aSZachary Turner } 8729cb868aSZachary Turner uint64_array.push_back(u64); 8829cb868aSZachary Turner } 895e777e1eSAlex Langford return llvm::APInt(byte_size * 8, llvm::ArrayRef<uint64_t>(uint64_array)); 9029cb868aSZachary Turner } else if (byte_order == lldb::eByteOrderBig) { 9129cb868aSZachary Turner lldb::offset_t be_offset = *offset_ptr + byte_size; 9229cb868aSZachary Turner lldb::offset_t temp_offset; 9329cb868aSZachary Turner while (bytes_left > 0) { 9429cb868aSZachary Turner if (bytes_left >= 8) { 9529cb868aSZachary Turner be_offset -= 8; 9629cb868aSZachary Turner temp_offset = be_offset; 9729cb868aSZachary Turner u64 = data.GetU64(&temp_offset); 9829cb868aSZachary Turner bytes_left -= 8; 9929cb868aSZachary Turner } else { 10029cb868aSZachary Turner be_offset -= bytes_left; 10129cb868aSZachary Turner temp_offset = be_offset; 10229cb868aSZachary Turner u64 = data.GetMaxU64(&temp_offset, (uint32_t)bytes_left); 10329cb868aSZachary Turner bytes_left = 0; 10429cb868aSZachary Turner } 10529cb868aSZachary Turner uint64_array.push_back(u64); 10629cb868aSZachary Turner } 10729cb868aSZachary Turner *offset_ptr += byte_size; 1085e777e1eSAlex Langford return llvm::APInt(byte_size * 8, llvm::ArrayRef<uint64_t>(uint64_array)); 10929cb868aSZachary Turner } 1105e777e1eSAlex Langford return llvm::None; 11129cb868aSZachary Turner } 11229cb868aSZachary Turner 11329cb868aSZachary Turner static lldb::offset_t DumpAPInt(Stream *s, const DataExtractor &data, 11429cb868aSZachary Turner lldb::offset_t offset, lldb::offset_t byte_size, 11529cb868aSZachary Turner bool is_signed, unsigned radix) { 1165e777e1eSAlex Langford llvm::Optional<llvm::APInt> apint = GetAPInt(data, &offset, byte_size); 1175e777e1eSAlex Langford if (apint.hasValue()) { 1185e777e1eSAlex Langford std::string apint_str(apint.getValue().toString(radix, is_signed)); 11929cb868aSZachary Turner switch (radix) { 12029cb868aSZachary Turner case 2: 12129cb868aSZachary Turner s->Write("0b", 2); 12229cb868aSZachary Turner break; 12329cb868aSZachary Turner case 8: 12429cb868aSZachary Turner s->Write("0", 1); 12529cb868aSZachary Turner break; 12629cb868aSZachary Turner case 10: 12729cb868aSZachary Turner break; 12829cb868aSZachary Turner } 12929cb868aSZachary Turner s->Write(apint_str.c_str(), apint_str.size()); 13029cb868aSZachary Turner } 13129cb868aSZachary Turner return offset; 13229cb868aSZachary Turner } 13329cb868aSZachary Turner 13429cb868aSZachary Turner lldb::offset_t lldb_private::DumpDataExtractor( 13529cb868aSZachary Turner const DataExtractor &DE, Stream *s, offset_t start_offset, 13629cb868aSZachary Turner lldb::Format item_format, size_t item_byte_size, size_t item_count, 13729cb868aSZachary Turner size_t num_per_line, uint64_t base_addr, 13829cb868aSZachary Turner uint32_t item_bit_size, // If zero, this is not a bitfield value, if 13929cb868aSZachary Turner // non-zero, the value is a bitfield 14029cb868aSZachary Turner uint32_t item_bit_offset, // If "item_bit_size" is non-zero, this is the 14129cb868aSZachary Turner // shift amount to apply to a bitfield 14229cb868aSZachary Turner ExecutionContextScope *exe_scope) { 14329cb868aSZachary Turner if (s == nullptr) 14429cb868aSZachary Turner return start_offset; 14529cb868aSZachary Turner 14629cb868aSZachary Turner if (item_format == eFormatPointer) { 14729cb868aSZachary Turner if (item_byte_size != 4 && item_byte_size != 8) 14829cb868aSZachary Turner item_byte_size = s->GetAddressByteSize(); 14929cb868aSZachary Turner } 15029cb868aSZachary Turner 15129cb868aSZachary Turner offset_t offset = start_offset; 15229cb868aSZachary Turner 15329cb868aSZachary Turner if (item_format == eFormatInstruction) { 15429cb868aSZachary Turner TargetSP target_sp; 15529cb868aSZachary Turner if (exe_scope) 15629cb868aSZachary Turner target_sp = exe_scope->CalculateTarget(); 15729cb868aSZachary Turner if (target_sp) { 15829cb868aSZachary Turner DisassemblerSP disassembler_sp(Disassembler::FindPlugin( 159529d235cSJason Molenda target_sp->GetArchitecture(), 160529d235cSJason Molenda target_sp->GetDisassemblyFlavor(), nullptr)); 16129cb868aSZachary Turner if (disassembler_sp) { 16229cb868aSZachary Turner lldb::addr_t addr = base_addr + start_offset; 16329cb868aSZachary Turner lldb_private::Address so_addr; 16429cb868aSZachary Turner bool data_from_file = true; 16529cb868aSZachary Turner if (target_sp->GetSectionLoadList().ResolveLoadAddress(addr, so_addr)) { 16629cb868aSZachary Turner data_from_file = false; 16729cb868aSZachary Turner } else { 16829cb868aSZachary Turner if (target_sp->GetSectionLoadList().IsEmpty() || 16929cb868aSZachary Turner !target_sp->GetImages().ResolveFileAddress(addr, so_addr)) 17029cb868aSZachary Turner so_addr.SetRawAddress(addr); 17129cb868aSZachary Turner } 17229cb868aSZachary Turner 17329cb868aSZachary Turner size_t bytes_consumed = disassembler_sp->DecodeInstructions( 17429cb868aSZachary Turner so_addr, DE, start_offset, item_count, false, data_from_file); 17529cb868aSZachary Turner 17629cb868aSZachary Turner if (bytes_consumed) { 17729cb868aSZachary Turner offset += bytes_consumed; 17829cb868aSZachary Turner const bool show_address = base_addr != LLDB_INVALID_ADDRESS; 17929cb868aSZachary Turner const bool show_bytes = true; 18029cb868aSZachary Turner ExecutionContext exe_ctx; 18129cb868aSZachary Turner exe_scope->CalculateExecutionContext(exe_ctx); 18229cb868aSZachary Turner disassembler_sp->GetInstructionList().Dump(s, show_address, 18329cb868aSZachary Turner show_bytes, &exe_ctx); 18429cb868aSZachary Turner } 18529cb868aSZachary Turner } 18629cb868aSZachary Turner } else 18729cb868aSZachary Turner s->Printf("invalid target"); 18829cb868aSZachary Turner 18929cb868aSZachary Turner return offset; 19029cb868aSZachary Turner } 19129cb868aSZachary Turner 19229cb868aSZachary Turner if ((item_format == eFormatOSType || item_format == eFormatAddressInfo) && 19329cb868aSZachary Turner item_byte_size > 8) 19429cb868aSZachary Turner item_format = eFormatHex; 19529cb868aSZachary Turner 19629cb868aSZachary Turner lldb::offset_t line_start_offset = start_offset; 19729cb868aSZachary Turner for (uint32_t count = 0; DE.ValidOffset(offset) && count < item_count; 19829cb868aSZachary Turner ++count) { 19929cb868aSZachary Turner if ((count % num_per_line) == 0) { 20029cb868aSZachary Turner if (count > 0) { 20129cb868aSZachary Turner if (item_format == eFormatBytesWithASCII && 20229cb868aSZachary Turner offset > line_start_offset) { 20329cb868aSZachary Turner s->Printf("%*s", 20429cb868aSZachary Turner static_cast<int>( 20529cb868aSZachary Turner (num_per_line - (offset - line_start_offset)) * 3 + 2), 20629cb868aSZachary Turner ""); 20729cb868aSZachary Turner DumpDataExtractor(DE, s, line_start_offset, eFormatCharPrintable, 1, 20829cb868aSZachary Turner offset - line_start_offset, SIZE_MAX, 20929cb868aSZachary Turner LLDB_INVALID_ADDRESS, 0, 0); 21029cb868aSZachary Turner } 21129cb868aSZachary Turner s->EOL(); 21229cb868aSZachary Turner } 21329cb868aSZachary Turner if (base_addr != LLDB_INVALID_ADDRESS) 21429cb868aSZachary Turner s->Printf("0x%8.8" PRIx64 ": ", 21529cb868aSZachary Turner (uint64_t)(base_addr + 21629cb868aSZachary Turner (offset - start_offset) / DE.getTargetByteSize())); 21729cb868aSZachary Turner 21829cb868aSZachary Turner line_start_offset = offset; 21929cb868aSZachary Turner } else if (item_format != eFormatChar && 22029cb868aSZachary Turner item_format != eFormatCharPrintable && 22129cb868aSZachary Turner item_format != eFormatCharArray && count > 0) { 22229cb868aSZachary Turner s->PutChar(' '); 22329cb868aSZachary Turner } 22429cb868aSZachary Turner 22529cb868aSZachary Turner switch (item_format) { 22629cb868aSZachary Turner case eFormatBoolean: 22729cb868aSZachary Turner if (item_byte_size <= 8) 22829cb868aSZachary Turner s->Printf("%s", DE.GetMaxU64Bitfield(&offset, item_byte_size, 22929cb868aSZachary Turner item_bit_size, item_bit_offset) 23029cb868aSZachary Turner ? "true" 23129cb868aSZachary Turner : "false"); 23229cb868aSZachary Turner else { 23329cb868aSZachary Turner s->Printf("error: unsupported byte size (%" PRIu64 23429cb868aSZachary Turner ") for boolean format", 23529cb868aSZachary Turner (uint64_t)item_byte_size); 23629cb868aSZachary Turner return offset; 23729cb868aSZachary Turner } 23829cb868aSZachary Turner break; 23929cb868aSZachary Turner 24029cb868aSZachary Turner case eFormatBinary: 24129cb868aSZachary Turner if (item_byte_size <= 8) { 24229cb868aSZachary Turner uint64_t uval64 = DE.GetMaxU64Bitfield(&offset, item_byte_size, 24329cb868aSZachary Turner item_bit_size, item_bit_offset); 24405097246SAdrian Prantl // Avoid std::bitset<64>::to_string() since it is missing in earlier 24505097246SAdrian Prantl // C++ libraries 24629cb868aSZachary Turner std::string binary_value(64, '0'); 24729cb868aSZachary Turner std::bitset<64> bits(uval64); 24829cb868aSZachary Turner for (uint32_t i = 0; i < 64; ++i) 24929cb868aSZachary Turner if (bits[i]) 25029cb868aSZachary Turner binary_value[64 - 1 - i] = '1'; 25129cb868aSZachary Turner if (item_bit_size > 0) 25229cb868aSZachary Turner s->Printf("0b%s", binary_value.c_str() + 64 - item_bit_size); 25329cb868aSZachary Turner else if (item_byte_size > 0 && item_byte_size <= 8) 25429cb868aSZachary Turner s->Printf("0b%s", binary_value.c_str() + 64 - item_byte_size * 8); 25529cb868aSZachary Turner } else { 25629cb868aSZachary Turner const bool is_signed = false; 25729cb868aSZachary Turner const unsigned radix = 2; 25829cb868aSZachary Turner offset = DumpAPInt(s, DE, offset, item_byte_size, is_signed, radix); 25929cb868aSZachary Turner } 26029cb868aSZachary Turner break; 26129cb868aSZachary Turner 26229cb868aSZachary Turner case eFormatBytes: 26329cb868aSZachary Turner case eFormatBytesWithASCII: 26429cb868aSZachary Turner for (uint32_t i = 0; i < item_byte_size; ++i) { 26529cb868aSZachary Turner s->Printf("%2.2x", DE.GetU8(&offset)); 26629cb868aSZachary Turner } 26729cb868aSZachary Turner 26805097246SAdrian Prantl // Put an extra space between the groups of bytes if more than one is 26905097246SAdrian Prantl // being dumped in a group (item_byte_size is more than 1). 27029cb868aSZachary Turner if (item_byte_size > 1) 27129cb868aSZachary Turner s->PutChar(' '); 27229cb868aSZachary Turner break; 27329cb868aSZachary Turner 27429cb868aSZachary Turner case eFormatChar: 27529cb868aSZachary Turner case eFormatCharPrintable: 27629cb868aSZachary Turner case eFormatCharArray: { 277dbd7c338SPetr Pavlu // Reject invalid item_byte_size. 278dbd7c338SPetr Pavlu if (item_byte_size > 8) { 279dbd7c338SPetr Pavlu s->Printf("error: unsupported byte size (%" PRIu64 ") for char format", 280dbd7c338SPetr Pavlu (uint64_t)item_byte_size); 281dbd7c338SPetr Pavlu return offset; 282dbd7c338SPetr Pavlu } 283dbd7c338SPetr Pavlu 28405097246SAdrian Prantl // If we are only printing one character surround it with single quotes 28529cb868aSZachary Turner if (item_count == 1 && item_format == eFormatChar) 28629cb868aSZachary Turner s->PutChar('\''); 28729cb868aSZachary Turner 28829cb868aSZachary Turner const uint64_t ch = DE.GetMaxU64Bitfield(&offset, item_byte_size, 28929cb868aSZachary Turner item_bit_size, item_bit_offset); 29029cb868aSZachary Turner if (isprint(ch)) 29129cb868aSZachary Turner s->Printf("%c", (char)ch); 29229cb868aSZachary Turner else if (item_format != eFormatCharPrintable) { 29329cb868aSZachary Turner switch (ch) { 29429cb868aSZachary Turner case '\033': 29529cb868aSZachary Turner s->Printf("\\e"); 29629cb868aSZachary Turner break; 29729cb868aSZachary Turner case '\a': 29829cb868aSZachary Turner s->Printf("\\a"); 29929cb868aSZachary Turner break; 30029cb868aSZachary Turner case '\b': 30129cb868aSZachary Turner s->Printf("\\b"); 30229cb868aSZachary Turner break; 30329cb868aSZachary Turner case '\f': 30429cb868aSZachary Turner s->Printf("\\f"); 30529cb868aSZachary Turner break; 30629cb868aSZachary Turner case '\n': 30729cb868aSZachary Turner s->Printf("\\n"); 30829cb868aSZachary Turner break; 30929cb868aSZachary Turner case '\r': 31029cb868aSZachary Turner s->Printf("\\r"); 31129cb868aSZachary Turner break; 31229cb868aSZachary Turner case '\t': 31329cb868aSZachary Turner s->Printf("\\t"); 31429cb868aSZachary Turner break; 31529cb868aSZachary Turner case '\v': 31629cb868aSZachary Turner s->Printf("\\v"); 31729cb868aSZachary Turner break; 31829cb868aSZachary Turner case '\0': 31929cb868aSZachary Turner s->Printf("\\0"); 32029cb868aSZachary Turner break; 32129cb868aSZachary Turner default: 32229cb868aSZachary Turner if (item_byte_size == 1) 32329cb868aSZachary Turner s->Printf("\\x%2.2x", (uint8_t)ch); 32429cb868aSZachary Turner else 32529cb868aSZachary Turner s->Printf("%" PRIu64, ch); 32629cb868aSZachary Turner break; 32729cb868aSZachary Turner } 32829cb868aSZachary Turner } else { 32929cb868aSZachary Turner s->PutChar(NON_PRINTABLE_CHAR); 33029cb868aSZachary Turner } 33129cb868aSZachary Turner 33229cb868aSZachary Turner // If we are only printing one character surround it with single quotes 33329cb868aSZachary Turner if (item_count == 1 && item_format == eFormatChar) 33429cb868aSZachary Turner s->PutChar('\''); 33529cb868aSZachary Turner } break; 33629cb868aSZachary Turner 33729cb868aSZachary Turner case eFormatEnum: // Print enum value as a signed integer when we don't get 33829cb868aSZachary Turner // the enum type 33929cb868aSZachary Turner case eFormatDecimal: 34029cb868aSZachary Turner if (item_byte_size <= 8) 34129cb868aSZachary Turner s->Printf("%" PRId64, 34229cb868aSZachary Turner DE.GetMaxS64Bitfield(&offset, item_byte_size, item_bit_size, 34329cb868aSZachary Turner item_bit_offset)); 34429cb868aSZachary Turner else { 34529cb868aSZachary Turner const bool is_signed = true; 34629cb868aSZachary Turner const unsigned radix = 10; 34729cb868aSZachary Turner offset = DumpAPInt(s, DE, offset, item_byte_size, is_signed, radix); 34829cb868aSZachary Turner } 34929cb868aSZachary Turner break; 35029cb868aSZachary Turner 35129cb868aSZachary Turner case eFormatUnsigned: 35229cb868aSZachary Turner if (item_byte_size <= 8) 35329cb868aSZachary Turner s->Printf("%" PRIu64, 35429cb868aSZachary Turner DE.GetMaxU64Bitfield(&offset, item_byte_size, item_bit_size, 35529cb868aSZachary Turner item_bit_offset)); 35629cb868aSZachary Turner else { 35729cb868aSZachary Turner const bool is_signed = false; 35829cb868aSZachary Turner const unsigned radix = 10; 35929cb868aSZachary Turner offset = DumpAPInt(s, DE, offset, item_byte_size, is_signed, radix); 36029cb868aSZachary Turner } 36129cb868aSZachary Turner break; 36229cb868aSZachary Turner 36329cb868aSZachary Turner case eFormatOctal: 36429cb868aSZachary Turner if (item_byte_size <= 8) 36529cb868aSZachary Turner s->Printf("0%" PRIo64, 36629cb868aSZachary Turner DE.GetMaxS64Bitfield(&offset, item_byte_size, item_bit_size, 36729cb868aSZachary Turner item_bit_offset)); 36829cb868aSZachary Turner else { 36929cb868aSZachary Turner const bool is_signed = false; 37029cb868aSZachary Turner const unsigned radix = 8; 37129cb868aSZachary Turner offset = DumpAPInt(s, DE, offset, item_byte_size, is_signed, radix); 37229cb868aSZachary Turner } 37329cb868aSZachary Turner break; 37429cb868aSZachary Turner 37529cb868aSZachary Turner case eFormatOSType: { 37629cb868aSZachary Turner uint64_t uval64 = DE.GetMaxU64Bitfield(&offset, item_byte_size, 37729cb868aSZachary Turner item_bit_size, item_bit_offset); 37829cb868aSZachary Turner s->PutChar('\''); 37929cb868aSZachary Turner for (uint32_t i = 0; i < item_byte_size; ++i) { 38029cb868aSZachary Turner uint8_t ch = (uint8_t)(uval64 >> ((item_byte_size - i - 1) * 8)); 38129cb868aSZachary Turner if (isprint(ch)) 38229cb868aSZachary Turner s->Printf("%c", ch); 38329cb868aSZachary Turner else { 38429cb868aSZachary Turner switch (ch) { 38529cb868aSZachary Turner case '\033': 38629cb868aSZachary Turner s->Printf("\\e"); 38729cb868aSZachary Turner break; 38829cb868aSZachary Turner case '\a': 38929cb868aSZachary Turner s->Printf("\\a"); 39029cb868aSZachary Turner break; 39129cb868aSZachary Turner case '\b': 39229cb868aSZachary Turner s->Printf("\\b"); 39329cb868aSZachary Turner break; 39429cb868aSZachary Turner case '\f': 39529cb868aSZachary Turner s->Printf("\\f"); 39629cb868aSZachary Turner break; 39729cb868aSZachary Turner case '\n': 39829cb868aSZachary Turner s->Printf("\\n"); 39929cb868aSZachary Turner break; 40029cb868aSZachary Turner case '\r': 40129cb868aSZachary Turner s->Printf("\\r"); 40229cb868aSZachary Turner break; 40329cb868aSZachary Turner case '\t': 40429cb868aSZachary Turner s->Printf("\\t"); 40529cb868aSZachary Turner break; 40629cb868aSZachary Turner case '\v': 40729cb868aSZachary Turner s->Printf("\\v"); 40829cb868aSZachary Turner break; 40929cb868aSZachary Turner case '\0': 41029cb868aSZachary Turner s->Printf("\\0"); 41129cb868aSZachary Turner break; 41229cb868aSZachary Turner default: 41329cb868aSZachary Turner s->Printf("\\x%2.2x", ch); 41429cb868aSZachary Turner break; 41529cb868aSZachary Turner } 41629cb868aSZachary Turner } 41729cb868aSZachary Turner } 41829cb868aSZachary Turner s->PutChar('\''); 41929cb868aSZachary Turner } break; 42029cb868aSZachary Turner 42129cb868aSZachary Turner case eFormatCString: { 42229cb868aSZachary Turner const char *cstr = DE.GetCStr(&offset); 42329cb868aSZachary Turner 42429cb868aSZachary Turner if (!cstr) { 42529cb868aSZachary Turner s->Printf("NULL"); 42629cb868aSZachary Turner offset = LLDB_INVALID_OFFSET; 42729cb868aSZachary Turner } else { 42829cb868aSZachary Turner s->PutChar('\"'); 42929cb868aSZachary Turner 43029cb868aSZachary Turner while (const char c = *cstr) { 43129cb868aSZachary Turner if (isprint(c)) { 43229cb868aSZachary Turner s->PutChar(c); 43329cb868aSZachary Turner } else { 43429cb868aSZachary Turner switch (c) { 43529cb868aSZachary Turner case '\033': 43629cb868aSZachary Turner s->Printf("\\e"); 43729cb868aSZachary Turner break; 43829cb868aSZachary Turner case '\a': 43929cb868aSZachary Turner s->Printf("\\a"); 44029cb868aSZachary Turner break; 44129cb868aSZachary Turner case '\b': 44229cb868aSZachary Turner s->Printf("\\b"); 44329cb868aSZachary Turner break; 44429cb868aSZachary Turner case '\f': 44529cb868aSZachary Turner s->Printf("\\f"); 44629cb868aSZachary Turner break; 44729cb868aSZachary Turner case '\n': 44829cb868aSZachary Turner s->Printf("\\n"); 44929cb868aSZachary Turner break; 45029cb868aSZachary Turner case '\r': 45129cb868aSZachary Turner s->Printf("\\r"); 45229cb868aSZachary Turner break; 45329cb868aSZachary Turner case '\t': 45429cb868aSZachary Turner s->Printf("\\t"); 45529cb868aSZachary Turner break; 45629cb868aSZachary Turner case '\v': 45729cb868aSZachary Turner s->Printf("\\v"); 45829cb868aSZachary Turner break; 45929cb868aSZachary Turner default: 46029cb868aSZachary Turner s->Printf("\\x%2.2x", c); 46129cb868aSZachary Turner break; 46229cb868aSZachary Turner } 46329cb868aSZachary Turner } 46429cb868aSZachary Turner 46529cb868aSZachary Turner ++cstr; 46629cb868aSZachary Turner } 46729cb868aSZachary Turner 46829cb868aSZachary Turner s->PutChar('\"'); 46929cb868aSZachary Turner } 47029cb868aSZachary Turner } break; 47129cb868aSZachary Turner 47229cb868aSZachary Turner case eFormatPointer: 47329cb868aSZachary Turner s->Address(DE.GetMaxU64Bitfield(&offset, item_byte_size, item_bit_size, 47429cb868aSZachary Turner item_bit_offset), 47529cb868aSZachary Turner sizeof(addr_t)); 47629cb868aSZachary Turner break; 47729cb868aSZachary Turner 47829cb868aSZachary Turner case eFormatComplexInteger: { 47929cb868aSZachary Turner size_t complex_int_byte_size = item_byte_size / 2; 48029cb868aSZachary Turner 48129cb868aSZachary Turner if (complex_int_byte_size > 0 && complex_int_byte_size <= 8) { 48229cb868aSZachary Turner s->Printf("%" PRIu64, 48329cb868aSZachary Turner DE.GetMaxU64Bitfield(&offset, complex_int_byte_size, 0, 0)); 48429cb868aSZachary Turner s->Printf(" + %" PRIu64 "i", 48529cb868aSZachary Turner DE.GetMaxU64Bitfield(&offset, complex_int_byte_size, 0, 0)); 48629cb868aSZachary Turner } else { 48729cb868aSZachary Turner s->Printf("error: unsupported byte size (%" PRIu64 48829cb868aSZachary Turner ") for complex integer format", 48929cb868aSZachary Turner (uint64_t)item_byte_size); 49029cb868aSZachary Turner return offset; 49129cb868aSZachary Turner } 49229cb868aSZachary Turner } break; 49329cb868aSZachary Turner 49429cb868aSZachary Turner case eFormatComplex: 49529cb868aSZachary Turner if (sizeof(float) * 2 == item_byte_size) { 49629cb868aSZachary Turner float f32_1 = DE.GetFloat(&offset); 49729cb868aSZachary Turner float f32_2 = DE.GetFloat(&offset); 49829cb868aSZachary Turner 49929cb868aSZachary Turner s->Printf("%g + %gi", f32_1, f32_2); 50029cb868aSZachary Turner break; 50129cb868aSZachary Turner } else if (sizeof(double) * 2 == item_byte_size) { 50229cb868aSZachary Turner double d64_1 = DE.GetDouble(&offset); 50329cb868aSZachary Turner double d64_2 = DE.GetDouble(&offset); 50429cb868aSZachary Turner 50529cb868aSZachary Turner s->Printf("%lg + %lgi", d64_1, d64_2); 50629cb868aSZachary Turner break; 50729cb868aSZachary Turner } else if (sizeof(long double) * 2 == item_byte_size) { 50829cb868aSZachary Turner long double ld64_1 = DE.GetLongDouble(&offset); 50929cb868aSZachary Turner long double ld64_2 = DE.GetLongDouble(&offset); 51029cb868aSZachary Turner s->Printf("%Lg + %Lgi", ld64_1, ld64_2); 51129cb868aSZachary Turner break; 51229cb868aSZachary Turner } else { 51329cb868aSZachary Turner s->Printf("error: unsupported byte size (%" PRIu64 51429cb868aSZachary Turner ") for complex float format", 51529cb868aSZachary Turner (uint64_t)item_byte_size); 51629cb868aSZachary Turner return offset; 51729cb868aSZachary Turner } 51829cb868aSZachary Turner break; 51929cb868aSZachary Turner 52029cb868aSZachary Turner default: 52129cb868aSZachary Turner case eFormatDefault: 52229cb868aSZachary Turner case eFormatHex: 52329cb868aSZachary Turner case eFormatHexUppercase: { 52429cb868aSZachary Turner bool wantsuppercase = (item_format == eFormatHexUppercase); 52529cb868aSZachary Turner switch (item_byte_size) { 52629cb868aSZachary Turner case 1: 52729cb868aSZachary Turner case 2: 52829cb868aSZachary Turner case 4: 52929cb868aSZachary Turner case 8: 53029cb868aSZachary Turner s->Printf(wantsuppercase ? "0x%*.*" PRIX64 : "0x%*.*" PRIx64, 53129cb868aSZachary Turner (int)(2 * item_byte_size), (int)(2 * item_byte_size), 53229cb868aSZachary Turner DE.GetMaxU64Bitfield(&offset, item_byte_size, item_bit_size, 53329cb868aSZachary Turner item_bit_offset)); 53429cb868aSZachary Turner break; 53529cb868aSZachary Turner default: { 53629cb868aSZachary Turner assert(item_bit_size == 0 && item_bit_offset == 0); 53729cb868aSZachary Turner const uint8_t *bytes = 53829cb868aSZachary Turner (const uint8_t *)DE.GetData(&offset, item_byte_size); 53929cb868aSZachary Turner if (bytes) { 54029cb868aSZachary Turner s->PutCString("0x"); 54129cb868aSZachary Turner uint32_t idx; 54229cb868aSZachary Turner if (DE.GetByteOrder() == eByteOrderBig) { 54329cb868aSZachary Turner for (idx = 0; idx < item_byte_size; ++idx) 54429cb868aSZachary Turner s->Printf(wantsuppercase ? "%2.2X" : "%2.2x", bytes[idx]); 54529cb868aSZachary Turner } else { 54629cb868aSZachary Turner for (idx = 0; idx < item_byte_size; ++idx) 54729cb868aSZachary Turner s->Printf(wantsuppercase ? "%2.2X" : "%2.2x", 54829cb868aSZachary Turner bytes[item_byte_size - 1 - idx]); 54929cb868aSZachary Turner } 55029cb868aSZachary Turner } 55129cb868aSZachary Turner } break; 55229cb868aSZachary Turner } 55329cb868aSZachary Turner } break; 55429cb868aSZachary Turner 55529cb868aSZachary Turner case eFormatFloat: { 55629cb868aSZachary Turner TargetSP target_sp; 557d5b44036SJonas Devlieghere bool used_upfloat = false; 55829cb868aSZachary Turner if (exe_scope) 55929cb868aSZachary Turner target_sp = exe_scope->CalculateTarget(); 56029cb868aSZachary Turner if (target_sp) { 561*b482db6dSAlex Langford auto type_system_or_err = 562*b482db6dSAlex Langford target_sp->GetScratchTypeSystemForLanguage(eLanguageTypeC); 563*b482db6dSAlex Langford if (!type_system_or_err) { 564*b482db6dSAlex Langford llvm::consumeError(type_system_or_err.takeError()); 565*b482db6dSAlex Langford } else { 566*b482db6dSAlex Langford auto &type_system = *type_system_or_err; 56729cb868aSZachary Turner llvm::SmallVector<char, 256> sv; 56829cb868aSZachary Turner // Show full precision when printing float values 56929cb868aSZachary Turner const unsigned format_precision = 0; 570e5814d78SRaphael Isemann const unsigned format_max_padding = 571e5814d78SRaphael Isemann target_sp->GetMaxZeroPaddingInFloatFormat(); 57229cb868aSZachary Turner 57329cb868aSZachary Turner const auto &semantics = 574*b482db6dSAlex Langford type_system.GetFloatTypeSemantics(item_byte_size); 575555130c3SPavel Labath 576*b482db6dSAlex Langford // Recalculate the byte size in case of a difference. This is possible 577*b482db6dSAlex Langford // when item_byte_size is 16 (128-bit), because you could get back the 578*b482db6dSAlex Langford // x87DoubleExtended semantics which has a byte size of 10 (80-bit). 579*b482db6dSAlex Langford const size_t semantics_byte_size = 580*b482db6dSAlex Langford (llvm::APFloat::getSizeInBits(semantics) + 7) / 8; 5815e777e1eSAlex Langford llvm::Optional<llvm::APInt> apint = 582*b482db6dSAlex Langford GetAPInt(DE, &offset, semantics_byte_size); 5835e777e1eSAlex Langford if (apint.hasValue()) { 5845e777e1eSAlex Langford llvm::APFloat apfloat(semantics, apint.getValue()); 58529cb868aSZachary Turner apfloat.toString(sv, format_precision, format_max_padding); 58629cb868aSZachary Turner if (!sv.empty()) { 58729cb868aSZachary Turner s->Printf("%*.*s", (int)sv.size(), (int)sv.size(), sv.data()); 588d5b44036SJonas Devlieghere used_upfloat = true; 58929cb868aSZachary Turner } 59029cb868aSZachary Turner } 59129cb868aSZachary Turner } 59229cb868aSZachary Turner } 59329cb868aSZachary Turner 594d5b44036SJonas Devlieghere if (!used_upfloat) { 59529cb868aSZachary Turner std::ostringstream ss; 59629cb868aSZachary Turner if (item_byte_size == sizeof(float) || item_byte_size == 2) { 59729cb868aSZachary Turner float f; 59829cb868aSZachary Turner if (item_byte_size == 2) { 59929cb868aSZachary Turner uint16_t half = DE.GetU16(&offset); 60029cb868aSZachary Turner f = half2float(half); 60129cb868aSZachary Turner } else { 60229cb868aSZachary Turner f = DE.GetFloat(&offset); 60329cb868aSZachary Turner } 60429cb868aSZachary Turner ss.precision(std::numeric_limits<float>::digits10); 60529cb868aSZachary Turner ss << f; 60629cb868aSZachary Turner } else if (item_byte_size == sizeof(double)) { 60729cb868aSZachary Turner ss.precision(std::numeric_limits<double>::digits10); 60829cb868aSZachary Turner ss << DE.GetDouble(&offset); 60929cb868aSZachary Turner } else if (item_byte_size == sizeof(long double) || 61029cb868aSZachary Turner item_byte_size == 10) { 61129cb868aSZachary Turner ss.precision(std::numeric_limits<long double>::digits10); 61229cb868aSZachary Turner ss << DE.GetLongDouble(&offset); 61329cb868aSZachary Turner } else { 61429cb868aSZachary Turner s->Printf("error: unsupported byte size (%" PRIu64 61529cb868aSZachary Turner ") for float format", 61629cb868aSZachary Turner (uint64_t)item_byte_size); 61729cb868aSZachary Turner return offset; 61829cb868aSZachary Turner } 61929cb868aSZachary Turner ss.flush(); 62029cb868aSZachary Turner s->Printf("%s", ss.str().c_str()); 62129cb868aSZachary Turner } 62229cb868aSZachary Turner } break; 62329cb868aSZachary Turner 62429cb868aSZachary Turner case eFormatUnicode16: 62529cb868aSZachary Turner s->Printf("U+%4.4x", DE.GetU16(&offset)); 62629cb868aSZachary Turner break; 62729cb868aSZachary Turner 62829cb868aSZachary Turner case eFormatUnicode32: 62929cb868aSZachary Turner s->Printf("U+0x%8.8x", DE.GetU32(&offset)); 63029cb868aSZachary Turner break; 63129cb868aSZachary Turner 63229cb868aSZachary Turner case eFormatAddressInfo: { 63329cb868aSZachary Turner addr_t addr = DE.GetMaxU64Bitfield(&offset, item_byte_size, item_bit_size, 63429cb868aSZachary Turner item_bit_offset); 63529cb868aSZachary Turner s->Printf("0x%*.*" PRIx64, (int)(2 * item_byte_size), 63629cb868aSZachary Turner (int)(2 * item_byte_size), addr); 63729cb868aSZachary Turner if (exe_scope) { 63829cb868aSZachary Turner TargetSP target_sp(exe_scope->CalculateTarget()); 63929cb868aSZachary Turner lldb_private::Address so_addr; 64029cb868aSZachary Turner if (target_sp) { 64129cb868aSZachary Turner if (target_sp->GetSectionLoadList().ResolveLoadAddress(addr, 64229cb868aSZachary Turner so_addr)) { 64329cb868aSZachary Turner s->PutChar(' '); 64429cb868aSZachary Turner so_addr.Dump(s, exe_scope, Address::DumpStyleResolvedDescription, 64529cb868aSZachary Turner Address::DumpStyleModuleWithFileAddress); 64629cb868aSZachary Turner } else { 64729cb868aSZachary Turner so_addr.SetOffset(addr); 64829cb868aSZachary Turner so_addr.Dump(s, exe_scope, 64929cb868aSZachary Turner Address::DumpStyleResolvedPointerDescription); 65029cb868aSZachary Turner } 65129cb868aSZachary Turner } 65229cb868aSZachary Turner } 65329cb868aSZachary Turner } break; 65429cb868aSZachary Turner 65529cb868aSZachary Turner case eFormatHexFloat: 65629cb868aSZachary Turner if (sizeof(float) == item_byte_size) { 65729cb868aSZachary Turner char float_cstr[256]; 65829cb868aSZachary Turner llvm::APFloat ap_float(DE.GetFloat(&offset)); 65929cb868aSZachary Turner ap_float.convertToHexString(float_cstr, 0, false, 66029cb868aSZachary Turner llvm::APFloat::rmNearestTiesToEven); 66129cb868aSZachary Turner s->Printf("%s", float_cstr); 66229cb868aSZachary Turner break; 66329cb868aSZachary Turner } else if (sizeof(double) == item_byte_size) { 66429cb868aSZachary Turner char float_cstr[256]; 66529cb868aSZachary Turner llvm::APFloat ap_float(DE.GetDouble(&offset)); 66629cb868aSZachary Turner ap_float.convertToHexString(float_cstr, 0, false, 66729cb868aSZachary Turner llvm::APFloat::rmNearestTiesToEven); 66829cb868aSZachary Turner s->Printf("%s", float_cstr); 66929cb868aSZachary Turner break; 67029cb868aSZachary Turner } else { 67129cb868aSZachary Turner s->Printf("error: unsupported byte size (%" PRIu64 67229cb868aSZachary Turner ") for hex float format", 67329cb868aSZachary Turner (uint64_t)item_byte_size); 67429cb868aSZachary Turner return offset; 67529cb868aSZachary Turner } 67629cb868aSZachary Turner break; 67729cb868aSZachary Turner 67829cb868aSZachary Turner // please keep the single-item formats below in sync with 67905097246SAdrian Prantl // FormatManager::GetSingleItemFormat if you fail to do so, users will 68005097246SAdrian Prantl // start getting different outputs depending on internal implementation 68105097246SAdrian Prantl // details they should not care about || 68229cb868aSZachary Turner case eFormatVectorOfChar: // || 68329cb868aSZachary Turner s->PutChar('{'); // \/ 68429cb868aSZachary Turner offset = 68529cb868aSZachary Turner DumpDataExtractor(DE, s, offset, eFormatCharArray, 1, item_byte_size, 68629cb868aSZachary Turner item_byte_size, LLDB_INVALID_ADDRESS, 0, 0); 68729cb868aSZachary Turner s->PutChar('}'); 68829cb868aSZachary Turner break; 68929cb868aSZachary Turner 69029cb868aSZachary Turner case eFormatVectorOfSInt8: 69129cb868aSZachary Turner s->PutChar('{'); 69229cb868aSZachary Turner offset = 69329cb868aSZachary Turner DumpDataExtractor(DE, s, offset, eFormatDecimal, 1, item_byte_size, 69429cb868aSZachary Turner item_byte_size, LLDB_INVALID_ADDRESS, 0, 0); 69529cb868aSZachary Turner s->PutChar('}'); 69629cb868aSZachary Turner break; 69729cb868aSZachary Turner 69829cb868aSZachary Turner case eFormatVectorOfUInt8: 69929cb868aSZachary Turner s->PutChar('{'); 70029cb868aSZachary Turner offset = DumpDataExtractor(DE, s, offset, eFormatHex, 1, item_byte_size, 70129cb868aSZachary Turner item_byte_size, LLDB_INVALID_ADDRESS, 0, 0); 70229cb868aSZachary Turner s->PutChar('}'); 70329cb868aSZachary Turner break; 70429cb868aSZachary Turner 70529cb868aSZachary Turner case eFormatVectorOfSInt16: 70629cb868aSZachary Turner s->PutChar('{'); 70729cb868aSZachary Turner offset = DumpDataExtractor( 70829cb868aSZachary Turner DE, s, offset, eFormatDecimal, sizeof(uint16_t), 70929cb868aSZachary Turner item_byte_size / sizeof(uint16_t), item_byte_size / sizeof(uint16_t), 71029cb868aSZachary Turner LLDB_INVALID_ADDRESS, 0, 0); 71129cb868aSZachary Turner s->PutChar('}'); 71229cb868aSZachary Turner break; 71329cb868aSZachary Turner 71429cb868aSZachary Turner case eFormatVectorOfUInt16: 71529cb868aSZachary Turner s->PutChar('{'); 71629cb868aSZachary Turner offset = DumpDataExtractor(DE, s, offset, eFormatHex, sizeof(uint16_t), 71729cb868aSZachary Turner item_byte_size / sizeof(uint16_t), 71829cb868aSZachary Turner item_byte_size / sizeof(uint16_t), 71929cb868aSZachary Turner LLDB_INVALID_ADDRESS, 0, 0); 72029cb868aSZachary Turner s->PutChar('}'); 72129cb868aSZachary Turner break; 72229cb868aSZachary Turner 72329cb868aSZachary Turner case eFormatVectorOfSInt32: 72429cb868aSZachary Turner s->PutChar('{'); 72529cb868aSZachary Turner offset = DumpDataExtractor( 72629cb868aSZachary Turner DE, s, offset, eFormatDecimal, sizeof(uint32_t), 72729cb868aSZachary Turner item_byte_size / sizeof(uint32_t), item_byte_size / sizeof(uint32_t), 72829cb868aSZachary Turner LLDB_INVALID_ADDRESS, 0, 0); 72929cb868aSZachary Turner s->PutChar('}'); 73029cb868aSZachary Turner break; 73129cb868aSZachary Turner 73229cb868aSZachary Turner case eFormatVectorOfUInt32: 73329cb868aSZachary Turner s->PutChar('{'); 73429cb868aSZachary Turner offset = DumpDataExtractor(DE, s, offset, eFormatHex, sizeof(uint32_t), 73529cb868aSZachary Turner item_byte_size / sizeof(uint32_t), 73629cb868aSZachary Turner item_byte_size / sizeof(uint32_t), 73729cb868aSZachary Turner LLDB_INVALID_ADDRESS, 0, 0); 73829cb868aSZachary Turner s->PutChar('}'); 73929cb868aSZachary Turner break; 74029cb868aSZachary Turner 74129cb868aSZachary Turner case eFormatVectorOfSInt64: 74229cb868aSZachary Turner s->PutChar('{'); 74329cb868aSZachary Turner offset = DumpDataExtractor( 74429cb868aSZachary Turner DE, s, offset, eFormatDecimal, sizeof(uint64_t), 74529cb868aSZachary Turner item_byte_size / sizeof(uint64_t), item_byte_size / sizeof(uint64_t), 74629cb868aSZachary Turner LLDB_INVALID_ADDRESS, 0, 0); 74729cb868aSZachary Turner s->PutChar('}'); 74829cb868aSZachary Turner break; 74929cb868aSZachary Turner 75029cb868aSZachary Turner case eFormatVectorOfUInt64: 75129cb868aSZachary Turner s->PutChar('{'); 75229cb868aSZachary Turner offset = DumpDataExtractor(DE, s, offset, eFormatHex, sizeof(uint64_t), 75329cb868aSZachary Turner item_byte_size / sizeof(uint64_t), 75429cb868aSZachary Turner item_byte_size / sizeof(uint64_t), 75529cb868aSZachary Turner LLDB_INVALID_ADDRESS, 0, 0); 75629cb868aSZachary Turner s->PutChar('}'); 75729cb868aSZachary Turner break; 75829cb868aSZachary Turner 75929cb868aSZachary Turner case eFormatVectorOfFloat16: 76029cb868aSZachary Turner s->PutChar('{'); 76129cb868aSZachary Turner offset = 76229cb868aSZachary Turner DumpDataExtractor(DE, s, offset, eFormatFloat, 2, item_byte_size / 2, 76329cb868aSZachary Turner item_byte_size / 2, LLDB_INVALID_ADDRESS, 0, 0); 76429cb868aSZachary Turner s->PutChar('}'); 76529cb868aSZachary Turner break; 76629cb868aSZachary Turner 76729cb868aSZachary Turner case eFormatVectorOfFloat32: 76829cb868aSZachary Turner s->PutChar('{'); 76929cb868aSZachary Turner offset = 77029cb868aSZachary Turner DumpDataExtractor(DE, s, offset, eFormatFloat, 4, item_byte_size / 4, 77129cb868aSZachary Turner item_byte_size / 4, LLDB_INVALID_ADDRESS, 0, 0); 77229cb868aSZachary Turner s->PutChar('}'); 77329cb868aSZachary Turner break; 77429cb868aSZachary Turner 77529cb868aSZachary Turner case eFormatVectorOfFloat64: 77629cb868aSZachary Turner s->PutChar('{'); 77729cb868aSZachary Turner offset = 77829cb868aSZachary Turner DumpDataExtractor(DE, s, offset, eFormatFloat, 8, item_byte_size / 8, 77929cb868aSZachary Turner item_byte_size / 8, LLDB_INVALID_ADDRESS, 0, 0); 78029cb868aSZachary Turner s->PutChar('}'); 78129cb868aSZachary Turner break; 78229cb868aSZachary Turner 78329cb868aSZachary Turner case eFormatVectorOfUInt128: 78429cb868aSZachary Turner s->PutChar('{'); 78529cb868aSZachary Turner offset = 78629cb868aSZachary Turner DumpDataExtractor(DE, s, offset, eFormatHex, 16, item_byte_size / 16, 78729cb868aSZachary Turner item_byte_size / 16, LLDB_INVALID_ADDRESS, 0, 0); 78829cb868aSZachary Turner s->PutChar('}'); 78929cb868aSZachary Turner break; 79029cb868aSZachary Turner } 79129cb868aSZachary Turner } 79229cb868aSZachary Turner 79329cb868aSZachary Turner if (item_format == eFormatBytesWithASCII && offset > line_start_offset) { 79429cb868aSZachary Turner s->Printf("%*s", static_cast<int>( 79529cb868aSZachary Turner (num_per_line - (offset - line_start_offset)) * 3 + 2), 79629cb868aSZachary Turner ""); 79729cb868aSZachary Turner DumpDataExtractor(DE, s, line_start_offset, eFormatCharPrintable, 1, 79829cb868aSZachary Turner offset - line_start_offset, SIZE_MAX, 79929cb868aSZachary Turner LLDB_INVALID_ADDRESS, 0, 0); 80029cb868aSZachary Turner } 80129cb868aSZachary Turner return offset; // Return the offset at which we ended up 80229cb868aSZachary Turner } 8039739a552SZachary Turner 8049739a552SZachary Turner void lldb_private::DumpHexBytes(Stream *s, const void *src, size_t src_len, 8059739a552SZachary Turner uint32_t bytes_per_line, 8069739a552SZachary Turner lldb::addr_t base_addr) { 8079739a552SZachary Turner DataExtractor data(src, src_len, lldb::eByteOrderLittle, 4); 8089739a552SZachary Turner DumpDataExtractor(data, s, 8099739a552SZachary Turner 0, // Offset into "src" 8109739a552SZachary Turner lldb::eFormatBytes, // Dump as hex bytes 8119739a552SZachary Turner 1, // Size of each item is 1 for single bytes 8129739a552SZachary Turner src_len, // Number of bytes 8139739a552SZachary Turner bytes_per_line, // Num bytes per line 8149739a552SZachary Turner base_addr, // Base address 8159739a552SZachary Turner 0, 0); // Bitfield info 8169739a552SZachary Turner } 817