1317027Sdim//===-- DumpDataExtractor.cpp -----------------------------------*- C++ -*-===// 2317027Sdim// 3353358Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4353358Sdim// See https://llvm.org/LICENSE.txt for license information. 5353358Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6317027Sdim// 7317027Sdim//===----------------------------------------------------------------------===// 8317027Sdim 9317027Sdim#include "lldb/Core/DumpDataExtractor.h" 10317027Sdim 11344779Sdim#include "lldb/lldb-defines.h" 12344779Sdim#include "lldb/lldb-forward.h" 13317027Sdim 14344779Sdim#include "lldb/Core/Address.h" 15317027Sdim#include "lldb/Core/Disassembler.h" 16344779Sdim#include "lldb/Core/ModuleList.h" 17317027Sdim#include "lldb/Target/ExecutionContext.h" 18317027Sdim#include "lldb/Target/ExecutionContextScope.h" 19317027Sdim#include "lldb/Target/SectionLoadList.h" 20317027Sdim#include "lldb/Target/Target.h" 21317027Sdim#include "lldb/Utility/DataExtractor.h" 22360784Sdim#include "lldb/Utility/Log.h" 23317027Sdim#include "lldb/Utility/Stream.h" 24317027Sdim 25344779Sdim#include "llvm/ADT/APFloat.h" 26344779Sdim#include "llvm/ADT/APInt.h" 27344779Sdim#include "llvm/ADT/ArrayRef.h" 28360784Sdim#include "llvm/ADT/Optional.h" 29344779Sdim#include "llvm/ADT/SmallVector.h" 30317027Sdim 31344779Sdim#include <limits> 32344779Sdim#include <memory> 33344779Sdim#include <string> 34317027Sdim 35344779Sdim#include <assert.h> 36344779Sdim#include <ctype.h> 37344779Sdim#include <inttypes.h> 38344779Sdim#include <math.h> 39317027Sdim 40317027Sdim#include <bitset> 41317027Sdim#include <sstream> 42317027Sdim 43317027Sdimusing namespace lldb_private; 44317027Sdimusing namespace lldb; 45317027Sdim 46317027Sdim#define NON_PRINTABLE_CHAR '.' 47317027Sdim 48317027Sdimstatic float half2float(uint16_t half) { 49317027Sdim union { 50317027Sdim float f; 51317027Sdim uint32_t u; 52317027Sdim } u; 53317027Sdim int32_t v = (int16_t)half; 54317027Sdim 55317027Sdim if (0 == (v & 0x7c00)) { 56317027Sdim u.u = v & 0x80007FFFU; 57317027Sdim return u.f * ldexpf(1, 125); 58317027Sdim } 59317027Sdim 60317027Sdim v <<= 13; 61317027Sdim u.u = v | 0x70000000U; 62317027Sdim return u.f * ldexpf(1, -112); 63317027Sdim} 64317027Sdim 65360784Sdimstatic llvm::Optional<llvm::APInt> GetAPInt(const DataExtractor &data, 66360784Sdim lldb::offset_t *offset_ptr, 67360784Sdim lldb::offset_t byte_size) { 68360784Sdim if (byte_size == 0) 69360784Sdim return llvm::None; 70360784Sdim 71317027Sdim llvm::SmallVector<uint64_t, 2> uint64_array; 72317027Sdim lldb::offset_t bytes_left = byte_size; 73317027Sdim uint64_t u64; 74317027Sdim const lldb::ByteOrder byte_order = data.GetByteOrder(); 75317027Sdim if (byte_order == lldb::eByteOrderLittle) { 76317027Sdim while (bytes_left > 0) { 77317027Sdim if (bytes_left >= 8) { 78317027Sdim u64 = data.GetU64(offset_ptr); 79317027Sdim bytes_left -= 8; 80317027Sdim } else { 81317027Sdim u64 = data.GetMaxU64(offset_ptr, (uint32_t)bytes_left); 82317027Sdim bytes_left = 0; 83317027Sdim } 84317027Sdim uint64_array.push_back(u64); 85317027Sdim } 86360784Sdim return llvm::APInt(byte_size * 8, llvm::ArrayRef<uint64_t>(uint64_array)); 87317027Sdim } else if (byte_order == lldb::eByteOrderBig) { 88317027Sdim lldb::offset_t be_offset = *offset_ptr + byte_size; 89317027Sdim lldb::offset_t temp_offset; 90317027Sdim while (bytes_left > 0) { 91317027Sdim if (bytes_left >= 8) { 92317027Sdim be_offset -= 8; 93317027Sdim temp_offset = be_offset; 94317027Sdim u64 = data.GetU64(&temp_offset); 95317027Sdim bytes_left -= 8; 96317027Sdim } else { 97317027Sdim be_offset -= bytes_left; 98317027Sdim temp_offset = be_offset; 99317027Sdim u64 = data.GetMaxU64(&temp_offset, (uint32_t)bytes_left); 100317027Sdim bytes_left = 0; 101317027Sdim } 102317027Sdim uint64_array.push_back(u64); 103317027Sdim } 104317027Sdim *offset_ptr += byte_size; 105360784Sdim return llvm::APInt(byte_size * 8, llvm::ArrayRef<uint64_t>(uint64_array)); 106317027Sdim } 107360784Sdim return llvm::None; 108317027Sdim} 109317027Sdim 110317027Sdimstatic lldb::offset_t DumpAPInt(Stream *s, const DataExtractor &data, 111317027Sdim lldb::offset_t offset, lldb::offset_t byte_size, 112317027Sdim bool is_signed, unsigned radix) { 113360784Sdim llvm::Optional<llvm::APInt> apint = GetAPInt(data, &offset, byte_size); 114360784Sdim if (apint.hasValue()) { 115360784Sdim std::string apint_str(apint.getValue().toString(radix, is_signed)); 116317027Sdim switch (radix) { 117317027Sdim case 2: 118317027Sdim s->Write("0b", 2); 119317027Sdim break; 120317027Sdim case 8: 121317027Sdim s->Write("0", 1); 122317027Sdim break; 123317027Sdim case 10: 124317027Sdim break; 125317027Sdim } 126317027Sdim s->Write(apint_str.c_str(), apint_str.size()); 127317027Sdim } 128317027Sdim return offset; 129317027Sdim} 130317027Sdim 131317027Sdimlldb::offset_t lldb_private::DumpDataExtractor( 132317027Sdim const DataExtractor &DE, Stream *s, offset_t start_offset, 133317027Sdim lldb::Format item_format, size_t item_byte_size, size_t item_count, 134317027Sdim size_t num_per_line, uint64_t base_addr, 135317027Sdim uint32_t item_bit_size, // If zero, this is not a bitfield value, if 136317027Sdim // non-zero, the value is a bitfield 137317027Sdim uint32_t item_bit_offset, // If "item_bit_size" is non-zero, this is the 138317027Sdim // shift amount to apply to a bitfield 139317027Sdim ExecutionContextScope *exe_scope) { 140317027Sdim if (s == nullptr) 141317027Sdim return start_offset; 142317027Sdim 143317027Sdim if (item_format == eFormatPointer) { 144317027Sdim if (item_byte_size != 4 && item_byte_size != 8) 145317027Sdim item_byte_size = s->GetAddressByteSize(); 146317027Sdim } 147317027Sdim 148317027Sdim offset_t offset = start_offset; 149317027Sdim 150317027Sdim if (item_format == eFormatInstruction) { 151317027Sdim TargetSP target_sp; 152317027Sdim if (exe_scope) 153317027Sdim target_sp = exe_scope->CalculateTarget(); 154317027Sdim if (target_sp) { 155317027Sdim DisassemblerSP disassembler_sp(Disassembler::FindPlugin( 156320970Sdim target_sp->GetArchitecture(), 157320970Sdim target_sp->GetDisassemblyFlavor(), nullptr)); 158317027Sdim if (disassembler_sp) { 159317027Sdim lldb::addr_t addr = base_addr + start_offset; 160317027Sdim lldb_private::Address so_addr; 161317027Sdim bool data_from_file = true; 162317027Sdim if (target_sp->GetSectionLoadList().ResolveLoadAddress(addr, so_addr)) { 163317027Sdim data_from_file = false; 164317027Sdim } else { 165317027Sdim if (target_sp->GetSectionLoadList().IsEmpty() || 166317027Sdim !target_sp->GetImages().ResolveFileAddress(addr, so_addr)) 167317027Sdim so_addr.SetRawAddress(addr); 168317027Sdim } 169317027Sdim 170317027Sdim size_t bytes_consumed = disassembler_sp->DecodeInstructions( 171317027Sdim so_addr, DE, start_offset, item_count, false, data_from_file); 172317027Sdim 173317027Sdim if (bytes_consumed) { 174317027Sdim offset += bytes_consumed; 175317027Sdim const bool show_address = base_addr != LLDB_INVALID_ADDRESS; 176317027Sdim const bool show_bytes = true; 177317027Sdim ExecutionContext exe_ctx; 178317027Sdim exe_scope->CalculateExecutionContext(exe_ctx); 179317027Sdim disassembler_sp->GetInstructionList().Dump(s, show_address, 180317027Sdim show_bytes, &exe_ctx); 181317027Sdim } 182317027Sdim } 183317027Sdim } else 184317027Sdim s->Printf("invalid target"); 185317027Sdim 186317027Sdim return offset; 187317027Sdim } 188317027Sdim 189317027Sdim if ((item_format == eFormatOSType || item_format == eFormatAddressInfo) && 190317027Sdim item_byte_size > 8) 191317027Sdim item_format = eFormatHex; 192317027Sdim 193317027Sdim lldb::offset_t line_start_offset = start_offset; 194317027Sdim for (uint32_t count = 0; DE.ValidOffset(offset) && count < item_count; 195317027Sdim ++count) { 196317027Sdim if ((count % num_per_line) == 0) { 197317027Sdim if (count > 0) { 198317027Sdim if (item_format == eFormatBytesWithASCII && 199317027Sdim offset > line_start_offset) { 200317027Sdim s->Printf("%*s", 201317027Sdim static_cast<int>( 202317027Sdim (num_per_line - (offset - line_start_offset)) * 3 + 2), 203317027Sdim ""); 204317027Sdim DumpDataExtractor(DE, s, line_start_offset, eFormatCharPrintable, 1, 205317027Sdim offset - line_start_offset, SIZE_MAX, 206317027Sdim LLDB_INVALID_ADDRESS, 0, 0); 207317027Sdim } 208317027Sdim s->EOL(); 209317027Sdim } 210317027Sdim if (base_addr != LLDB_INVALID_ADDRESS) 211317027Sdim s->Printf("0x%8.8" PRIx64 ": ", 212317027Sdim (uint64_t)(base_addr + 213317027Sdim (offset - start_offset) / DE.getTargetByteSize())); 214317027Sdim 215317027Sdim line_start_offset = offset; 216317027Sdim } else if (item_format != eFormatChar && 217317027Sdim item_format != eFormatCharPrintable && 218317027Sdim item_format != eFormatCharArray && count > 0) { 219317027Sdim s->PutChar(' '); 220317027Sdim } 221317027Sdim 222317027Sdim switch (item_format) { 223317027Sdim case eFormatBoolean: 224317027Sdim if (item_byte_size <= 8) 225317027Sdim s->Printf("%s", DE.GetMaxU64Bitfield(&offset, item_byte_size, 226317027Sdim item_bit_size, item_bit_offset) 227317027Sdim ? "true" 228317027Sdim : "false"); 229317027Sdim else { 230317027Sdim s->Printf("error: unsupported byte size (%" PRIu64 231317027Sdim ") for boolean format", 232317027Sdim (uint64_t)item_byte_size); 233317027Sdim return offset; 234317027Sdim } 235317027Sdim break; 236317027Sdim 237317027Sdim case eFormatBinary: 238317027Sdim if (item_byte_size <= 8) { 239317027Sdim uint64_t uval64 = DE.GetMaxU64Bitfield(&offset, item_byte_size, 240317027Sdim item_bit_size, item_bit_offset); 241341825Sdim // Avoid std::bitset<64>::to_string() since it is missing in earlier 242341825Sdim // C++ libraries 243317027Sdim std::string binary_value(64, '0'); 244317027Sdim std::bitset<64> bits(uval64); 245317027Sdim for (uint32_t i = 0; i < 64; ++i) 246317027Sdim if (bits[i]) 247317027Sdim binary_value[64 - 1 - i] = '1'; 248317027Sdim if (item_bit_size > 0) 249317027Sdim s->Printf("0b%s", binary_value.c_str() + 64 - item_bit_size); 250317027Sdim else if (item_byte_size > 0 && item_byte_size <= 8) 251317027Sdim s->Printf("0b%s", binary_value.c_str() + 64 - item_byte_size * 8); 252317027Sdim } else { 253317027Sdim const bool is_signed = false; 254317027Sdim const unsigned radix = 2; 255317027Sdim offset = DumpAPInt(s, DE, offset, item_byte_size, is_signed, radix); 256317027Sdim } 257317027Sdim break; 258317027Sdim 259317027Sdim case eFormatBytes: 260317027Sdim case eFormatBytesWithASCII: 261317027Sdim for (uint32_t i = 0; i < item_byte_size; ++i) { 262317027Sdim s->Printf("%2.2x", DE.GetU8(&offset)); 263317027Sdim } 264317027Sdim 265341825Sdim // Put an extra space between the groups of bytes if more than one is 266341825Sdim // being dumped in a group (item_byte_size is more than 1). 267317027Sdim if (item_byte_size > 1) 268317027Sdim s->PutChar(' '); 269317027Sdim break; 270317027Sdim 271317027Sdim case eFormatChar: 272317027Sdim case eFormatCharPrintable: 273317027Sdim case eFormatCharArray: { 274327952Sdim // Reject invalid item_byte_size. 275327952Sdim if (item_byte_size > 8) { 276327952Sdim s->Printf("error: unsupported byte size (%" PRIu64 ") for char format", 277327952Sdim (uint64_t)item_byte_size); 278327952Sdim return offset; 279327952Sdim } 280327952Sdim 281341825Sdim // If we are only printing one character surround it with single quotes 282317027Sdim if (item_count == 1 && item_format == eFormatChar) 283317027Sdim s->PutChar('\''); 284317027Sdim 285317027Sdim const uint64_t ch = DE.GetMaxU64Bitfield(&offset, item_byte_size, 286317027Sdim item_bit_size, item_bit_offset); 287317027Sdim if (isprint(ch)) 288317027Sdim s->Printf("%c", (char)ch); 289317027Sdim else if (item_format != eFormatCharPrintable) { 290317027Sdim switch (ch) { 291317027Sdim case '\033': 292317027Sdim s->Printf("\\e"); 293317027Sdim break; 294317027Sdim case '\a': 295317027Sdim s->Printf("\\a"); 296317027Sdim break; 297317027Sdim case '\b': 298317027Sdim s->Printf("\\b"); 299317027Sdim break; 300317027Sdim case '\f': 301317027Sdim s->Printf("\\f"); 302317027Sdim break; 303317027Sdim case '\n': 304317027Sdim s->Printf("\\n"); 305317027Sdim break; 306317027Sdim case '\r': 307317027Sdim s->Printf("\\r"); 308317027Sdim break; 309317027Sdim case '\t': 310317027Sdim s->Printf("\\t"); 311317027Sdim break; 312317027Sdim case '\v': 313317027Sdim s->Printf("\\v"); 314317027Sdim break; 315317027Sdim case '\0': 316317027Sdim s->Printf("\\0"); 317317027Sdim break; 318317027Sdim default: 319317027Sdim if (item_byte_size == 1) 320317027Sdim s->Printf("\\x%2.2x", (uint8_t)ch); 321317027Sdim else 322317027Sdim s->Printf("%" PRIu64, ch); 323317027Sdim break; 324317027Sdim } 325317027Sdim } else { 326317027Sdim s->PutChar(NON_PRINTABLE_CHAR); 327317027Sdim } 328317027Sdim 329317027Sdim // If we are only printing one character surround it with single quotes 330317027Sdim if (item_count == 1 && item_format == eFormatChar) 331317027Sdim s->PutChar('\''); 332317027Sdim } break; 333317027Sdim 334317027Sdim case eFormatEnum: // Print enum value as a signed integer when we don't get 335317027Sdim // the enum type 336317027Sdim case eFormatDecimal: 337317027Sdim if (item_byte_size <= 8) 338317027Sdim s->Printf("%" PRId64, 339317027Sdim DE.GetMaxS64Bitfield(&offset, item_byte_size, item_bit_size, 340317027Sdim item_bit_offset)); 341317027Sdim else { 342317027Sdim const bool is_signed = true; 343317027Sdim const unsigned radix = 10; 344317027Sdim offset = DumpAPInt(s, DE, offset, item_byte_size, is_signed, radix); 345317027Sdim } 346317027Sdim break; 347317027Sdim 348317027Sdim case eFormatUnsigned: 349317027Sdim if (item_byte_size <= 8) 350317027Sdim s->Printf("%" PRIu64, 351317027Sdim DE.GetMaxU64Bitfield(&offset, item_byte_size, item_bit_size, 352317027Sdim item_bit_offset)); 353317027Sdim else { 354317027Sdim const bool is_signed = false; 355317027Sdim const unsigned radix = 10; 356317027Sdim offset = DumpAPInt(s, DE, offset, item_byte_size, is_signed, radix); 357317027Sdim } 358317027Sdim break; 359317027Sdim 360317027Sdim case eFormatOctal: 361317027Sdim if (item_byte_size <= 8) 362317027Sdim s->Printf("0%" PRIo64, 363317027Sdim DE.GetMaxS64Bitfield(&offset, item_byte_size, item_bit_size, 364317027Sdim item_bit_offset)); 365317027Sdim else { 366317027Sdim const bool is_signed = false; 367317027Sdim const unsigned radix = 8; 368317027Sdim offset = DumpAPInt(s, DE, offset, item_byte_size, is_signed, radix); 369317027Sdim } 370317027Sdim break; 371317027Sdim 372317027Sdim case eFormatOSType: { 373317027Sdim uint64_t uval64 = DE.GetMaxU64Bitfield(&offset, item_byte_size, 374317027Sdim item_bit_size, item_bit_offset); 375317027Sdim s->PutChar('\''); 376317027Sdim for (uint32_t i = 0; i < item_byte_size; ++i) { 377317027Sdim uint8_t ch = (uint8_t)(uval64 >> ((item_byte_size - i - 1) * 8)); 378317027Sdim if (isprint(ch)) 379317027Sdim s->Printf("%c", ch); 380317027Sdim else { 381317027Sdim switch (ch) { 382317027Sdim case '\033': 383317027Sdim s->Printf("\\e"); 384317027Sdim break; 385317027Sdim case '\a': 386317027Sdim s->Printf("\\a"); 387317027Sdim break; 388317027Sdim case '\b': 389317027Sdim s->Printf("\\b"); 390317027Sdim break; 391317027Sdim case '\f': 392317027Sdim s->Printf("\\f"); 393317027Sdim break; 394317027Sdim case '\n': 395317027Sdim s->Printf("\\n"); 396317027Sdim break; 397317027Sdim case '\r': 398317027Sdim s->Printf("\\r"); 399317027Sdim break; 400317027Sdim case '\t': 401317027Sdim s->Printf("\\t"); 402317027Sdim break; 403317027Sdim case '\v': 404317027Sdim s->Printf("\\v"); 405317027Sdim break; 406317027Sdim case '\0': 407317027Sdim s->Printf("\\0"); 408317027Sdim break; 409317027Sdim default: 410317027Sdim s->Printf("\\x%2.2x", ch); 411317027Sdim break; 412317027Sdim } 413317027Sdim } 414317027Sdim } 415317027Sdim s->PutChar('\''); 416317027Sdim } break; 417317027Sdim 418317027Sdim case eFormatCString: { 419317027Sdim const char *cstr = DE.GetCStr(&offset); 420317027Sdim 421317027Sdim if (!cstr) { 422317027Sdim s->Printf("NULL"); 423317027Sdim offset = LLDB_INVALID_OFFSET; 424317027Sdim } else { 425317027Sdim s->PutChar('\"'); 426317027Sdim 427317027Sdim while (const char c = *cstr) { 428317027Sdim if (isprint(c)) { 429317027Sdim s->PutChar(c); 430317027Sdim } else { 431317027Sdim switch (c) { 432317027Sdim case '\033': 433317027Sdim s->Printf("\\e"); 434317027Sdim break; 435317027Sdim case '\a': 436317027Sdim s->Printf("\\a"); 437317027Sdim break; 438317027Sdim case '\b': 439317027Sdim s->Printf("\\b"); 440317027Sdim break; 441317027Sdim case '\f': 442317027Sdim s->Printf("\\f"); 443317027Sdim break; 444317027Sdim case '\n': 445317027Sdim s->Printf("\\n"); 446317027Sdim break; 447317027Sdim case '\r': 448317027Sdim s->Printf("\\r"); 449317027Sdim break; 450317027Sdim case '\t': 451317027Sdim s->Printf("\\t"); 452317027Sdim break; 453317027Sdim case '\v': 454317027Sdim s->Printf("\\v"); 455317027Sdim break; 456317027Sdim default: 457317027Sdim s->Printf("\\x%2.2x", c); 458317027Sdim break; 459317027Sdim } 460317027Sdim } 461317027Sdim 462317027Sdim ++cstr; 463317027Sdim } 464317027Sdim 465317027Sdim s->PutChar('\"'); 466317027Sdim } 467317027Sdim } break; 468317027Sdim 469317027Sdim case eFormatPointer: 470360784Sdim DumpAddress(s->AsRawOstream(), 471360784Sdim DE.GetMaxU64Bitfield(&offset, item_byte_size, item_bit_size, 472360784Sdim item_bit_offset), 473360784Sdim sizeof(addr_t)); 474317027Sdim break; 475317027Sdim 476317027Sdim case eFormatComplexInteger: { 477317027Sdim size_t complex_int_byte_size = item_byte_size / 2; 478317027Sdim 479317027Sdim if (complex_int_byte_size > 0 && complex_int_byte_size <= 8) { 480317027Sdim s->Printf("%" PRIu64, 481317027Sdim DE.GetMaxU64Bitfield(&offset, complex_int_byte_size, 0, 0)); 482317027Sdim s->Printf(" + %" PRIu64 "i", 483317027Sdim DE.GetMaxU64Bitfield(&offset, complex_int_byte_size, 0, 0)); 484317027Sdim } else { 485317027Sdim s->Printf("error: unsupported byte size (%" PRIu64 486317027Sdim ") for complex integer format", 487317027Sdim (uint64_t)item_byte_size); 488317027Sdim return offset; 489317027Sdim } 490317027Sdim } break; 491317027Sdim 492317027Sdim case eFormatComplex: 493317027Sdim if (sizeof(float) * 2 == item_byte_size) { 494317027Sdim float f32_1 = DE.GetFloat(&offset); 495317027Sdim float f32_2 = DE.GetFloat(&offset); 496317027Sdim 497317027Sdim s->Printf("%g + %gi", f32_1, f32_2); 498317027Sdim break; 499317027Sdim } else if (sizeof(double) * 2 == item_byte_size) { 500317027Sdim double d64_1 = DE.GetDouble(&offset); 501317027Sdim double d64_2 = DE.GetDouble(&offset); 502317027Sdim 503317027Sdim s->Printf("%lg + %lgi", d64_1, d64_2); 504317027Sdim break; 505317027Sdim } else if (sizeof(long double) * 2 == item_byte_size) { 506317027Sdim long double ld64_1 = DE.GetLongDouble(&offset); 507317027Sdim long double ld64_2 = DE.GetLongDouble(&offset); 508317027Sdim s->Printf("%Lg + %Lgi", ld64_1, ld64_2); 509317027Sdim break; 510317027Sdim } else { 511317027Sdim s->Printf("error: unsupported byte size (%" PRIu64 512317027Sdim ") for complex float format", 513317027Sdim (uint64_t)item_byte_size); 514317027Sdim return offset; 515317027Sdim } 516317027Sdim break; 517317027Sdim 518317027Sdim default: 519317027Sdim case eFormatDefault: 520317027Sdim case eFormatHex: 521317027Sdim case eFormatHexUppercase: { 522317027Sdim bool wantsuppercase = (item_format == eFormatHexUppercase); 523317027Sdim switch (item_byte_size) { 524317027Sdim case 1: 525317027Sdim case 2: 526317027Sdim case 4: 527317027Sdim case 8: 528317027Sdim s->Printf(wantsuppercase ? "0x%*.*" PRIX64 : "0x%*.*" PRIx64, 529317027Sdim (int)(2 * item_byte_size), (int)(2 * item_byte_size), 530317027Sdim DE.GetMaxU64Bitfield(&offset, item_byte_size, item_bit_size, 531317027Sdim item_bit_offset)); 532317027Sdim break; 533317027Sdim default: { 534317027Sdim assert(item_bit_size == 0 && item_bit_offset == 0); 535317027Sdim const uint8_t *bytes = 536317027Sdim (const uint8_t *)DE.GetData(&offset, item_byte_size); 537317027Sdim if (bytes) { 538317027Sdim s->PutCString("0x"); 539317027Sdim uint32_t idx; 540317027Sdim if (DE.GetByteOrder() == eByteOrderBig) { 541317027Sdim for (idx = 0; idx < item_byte_size; ++idx) 542317027Sdim s->Printf(wantsuppercase ? "%2.2X" : "%2.2x", bytes[idx]); 543317027Sdim } else { 544317027Sdim for (idx = 0; idx < item_byte_size; ++idx) 545317027Sdim s->Printf(wantsuppercase ? "%2.2X" : "%2.2x", 546317027Sdim bytes[item_byte_size - 1 - idx]); 547317027Sdim } 548317027Sdim } 549317027Sdim } break; 550317027Sdim } 551317027Sdim } break; 552317027Sdim 553317027Sdim case eFormatFloat: { 554317027Sdim TargetSP target_sp; 555353358Sdim bool used_upfloat = false; 556317027Sdim if (exe_scope) 557317027Sdim target_sp = exe_scope->CalculateTarget(); 558317027Sdim if (target_sp) { 559360784Sdim auto type_system_or_err = 560360784Sdim target_sp->GetScratchTypeSystemForLanguage(eLanguageTypeC); 561360784Sdim if (!type_system_or_err) { 562360784Sdim llvm::consumeError(type_system_or_err.takeError()); 563360784Sdim } else { 564360784Sdim auto &type_system = *type_system_or_err; 565360784Sdim llvm::SmallVector<char, 256> sv; 566360784Sdim // Show full precision when printing float values 567360784Sdim const unsigned format_precision = 0; 568360784Sdim const unsigned format_max_padding = 569360784Sdim target_sp->GetMaxZeroPaddingInFloatFormat(); 570317027Sdim 571360784Sdim const auto &semantics = 572360784Sdim type_system.GetFloatTypeSemantics(item_byte_size); 573317027Sdim 574360784Sdim // Recalculate the byte size in case of a difference. This is possible 575360784Sdim // when item_byte_size is 16 (128-bit), because you could get back the 576360784Sdim // x87DoubleExtended semantics which has a byte size of 10 (80-bit). 577360784Sdim const size_t semantics_byte_size = 578360784Sdim (llvm::APFloat::getSizeInBits(semantics) + 7) / 8; 579360784Sdim llvm::Optional<llvm::APInt> apint = 580360784Sdim GetAPInt(DE, &offset, semantics_byte_size); 581360784Sdim if (apint.hasValue()) { 582360784Sdim llvm::APFloat apfloat(semantics, apint.getValue()); 583360784Sdim apfloat.toString(sv, format_precision, format_max_padding); 584317027Sdim if (!sv.empty()) { 585317027Sdim s->Printf("%*.*s", (int)sv.size(), (int)sv.size(), sv.data()); 586353358Sdim used_upfloat = true; 587317027Sdim } 588317027Sdim } 589317027Sdim } 590317027Sdim } 591317027Sdim 592353358Sdim if (!used_upfloat) { 593317027Sdim std::ostringstream ss; 594317027Sdim if (item_byte_size == sizeof(float) || item_byte_size == 2) { 595317027Sdim float f; 596317027Sdim if (item_byte_size == 2) { 597317027Sdim uint16_t half = DE.GetU16(&offset); 598317027Sdim f = half2float(half); 599317027Sdim } else { 600317027Sdim f = DE.GetFloat(&offset); 601317027Sdim } 602317027Sdim ss.precision(std::numeric_limits<float>::digits10); 603317027Sdim ss << f; 604317027Sdim } else if (item_byte_size == sizeof(double)) { 605317027Sdim ss.precision(std::numeric_limits<double>::digits10); 606317027Sdim ss << DE.GetDouble(&offset); 607317027Sdim } else if (item_byte_size == sizeof(long double) || 608317027Sdim item_byte_size == 10) { 609317027Sdim ss.precision(std::numeric_limits<long double>::digits10); 610317027Sdim ss << DE.GetLongDouble(&offset); 611317027Sdim } else { 612317027Sdim s->Printf("error: unsupported byte size (%" PRIu64 613317027Sdim ") for float format", 614317027Sdim (uint64_t)item_byte_size); 615317027Sdim return offset; 616317027Sdim } 617317027Sdim ss.flush(); 618317027Sdim s->Printf("%s", ss.str().c_str()); 619317027Sdim } 620317027Sdim } break; 621317027Sdim 622317027Sdim case eFormatUnicode16: 623317027Sdim s->Printf("U+%4.4x", DE.GetU16(&offset)); 624317027Sdim break; 625317027Sdim 626317027Sdim case eFormatUnicode32: 627317027Sdim s->Printf("U+0x%8.8x", DE.GetU32(&offset)); 628317027Sdim break; 629317027Sdim 630317027Sdim case eFormatAddressInfo: { 631317027Sdim addr_t addr = DE.GetMaxU64Bitfield(&offset, item_byte_size, item_bit_size, 632317027Sdim item_bit_offset); 633317027Sdim s->Printf("0x%*.*" PRIx64, (int)(2 * item_byte_size), 634317027Sdim (int)(2 * item_byte_size), addr); 635317027Sdim if (exe_scope) { 636317027Sdim TargetSP target_sp(exe_scope->CalculateTarget()); 637317027Sdim lldb_private::Address so_addr; 638317027Sdim if (target_sp) { 639317027Sdim if (target_sp->GetSectionLoadList().ResolveLoadAddress(addr, 640317027Sdim so_addr)) { 641317027Sdim s->PutChar(' '); 642317027Sdim so_addr.Dump(s, exe_scope, Address::DumpStyleResolvedDescription, 643317027Sdim Address::DumpStyleModuleWithFileAddress); 644317027Sdim } else { 645317027Sdim so_addr.SetOffset(addr); 646317027Sdim so_addr.Dump(s, exe_scope, 647317027Sdim Address::DumpStyleResolvedPointerDescription); 648317027Sdim } 649317027Sdim } 650317027Sdim } 651317027Sdim } break; 652317027Sdim 653317027Sdim case eFormatHexFloat: 654317027Sdim if (sizeof(float) == item_byte_size) { 655317027Sdim char float_cstr[256]; 656317027Sdim llvm::APFloat ap_float(DE.GetFloat(&offset)); 657317027Sdim ap_float.convertToHexString(float_cstr, 0, false, 658317027Sdim llvm::APFloat::rmNearestTiesToEven); 659317027Sdim s->Printf("%s", float_cstr); 660317027Sdim break; 661317027Sdim } else if (sizeof(double) == item_byte_size) { 662317027Sdim char float_cstr[256]; 663317027Sdim llvm::APFloat ap_float(DE.GetDouble(&offset)); 664317027Sdim ap_float.convertToHexString(float_cstr, 0, false, 665317027Sdim llvm::APFloat::rmNearestTiesToEven); 666317027Sdim s->Printf("%s", float_cstr); 667317027Sdim break; 668317027Sdim } else { 669317027Sdim s->Printf("error: unsupported byte size (%" PRIu64 670317027Sdim ") for hex float format", 671317027Sdim (uint64_t)item_byte_size); 672317027Sdim return offset; 673317027Sdim } 674317027Sdim break; 675317027Sdim 676317027Sdim // please keep the single-item formats below in sync with 677341825Sdim // FormatManager::GetSingleItemFormat if you fail to do so, users will 678341825Sdim // start getting different outputs depending on internal implementation 679341825Sdim // details they should not care about || 680317027Sdim case eFormatVectorOfChar: // || 681317027Sdim s->PutChar('{'); // \/ 682317027Sdim offset = 683317027Sdim DumpDataExtractor(DE, s, offset, eFormatCharArray, 1, item_byte_size, 684317027Sdim item_byte_size, LLDB_INVALID_ADDRESS, 0, 0); 685317027Sdim s->PutChar('}'); 686317027Sdim break; 687317027Sdim 688317027Sdim case eFormatVectorOfSInt8: 689317027Sdim s->PutChar('{'); 690317027Sdim offset = 691317027Sdim DumpDataExtractor(DE, s, offset, eFormatDecimal, 1, item_byte_size, 692317027Sdim item_byte_size, LLDB_INVALID_ADDRESS, 0, 0); 693317027Sdim s->PutChar('}'); 694317027Sdim break; 695317027Sdim 696317027Sdim case eFormatVectorOfUInt8: 697317027Sdim s->PutChar('{'); 698317027Sdim offset = DumpDataExtractor(DE, s, offset, eFormatHex, 1, item_byte_size, 699317027Sdim item_byte_size, LLDB_INVALID_ADDRESS, 0, 0); 700317027Sdim s->PutChar('}'); 701317027Sdim break; 702317027Sdim 703317027Sdim case eFormatVectorOfSInt16: 704317027Sdim s->PutChar('{'); 705317027Sdim offset = DumpDataExtractor( 706317027Sdim DE, s, offset, eFormatDecimal, sizeof(uint16_t), 707317027Sdim item_byte_size / sizeof(uint16_t), item_byte_size / sizeof(uint16_t), 708317027Sdim LLDB_INVALID_ADDRESS, 0, 0); 709317027Sdim s->PutChar('}'); 710317027Sdim break; 711317027Sdim 712317027Sdim case eFormatVectorOfUInt16: 713317027Sdim s->PutChar('{'); 714317027Sdim offset = DumpDataExtractor(DE, s, offset, eFormatHex, sizeof(uint16_t), 715317027Sdim item_byte_size / sizeof(uint16_t), 716317027Sdim item_byte_size / sizeof(uint16_t), 717317027Sdim LLDB_INVALID_ADDRESS, 0, 0); 718317027Sdim s->PutChar('}'); 719317027Sdim break; 720317027Sdim 721317027Sdim case eFormatVectorOfSInt32: 722317027Sdim s->PutChar('{'); 723317027Sdim offset = DumpDataExtractor( 724317027Sdim DE, s, offset, eFormatDecimal, sizeof(uint32_t), 725317027Sdim item_byte_size / sizeof(uint32_t), item_byte_size / sizeof(uint32_t), 726317027Sdim LLDB_INVALID_ADDRESS, 0, 0); 727317027Sdim s->PutChar('}'); 728317027Sdim break; 729317027Sdim 730317027Sdim case eFormatVectorOfUInt32: 731317027Sdim s->PutChar('{'); 732317027Sdim offset = DumpDataExtractor(DE, s, offset, eFormatHex, sizeof(uint32_t), 733317027Sdim item_byte_size / sizeof(uint32_t), 734317027Sdim item_byte_size / sizeof(uint32_t), 735317027Sdim LLDB_INVALID_ADDRESS, 0, 0); 736317027Sdim s->PutChar('}'); 737317027Sdim break; 738317027Sdim 739317027Sdim case eFormatVectorOfSInt64: 740317027Sdim s->PutChar('{'); 741317027Sdim offset = DumpDataExtractor( 742317027Sdim DE, s, offset, eFormatDecimal, sizeof(uint64_t), 743317027Sdim item_byte_size / sizeof(uint64_t), item_byte_size / sizeof(uint64_t), 744317027Sdim LLDB_INVALID_ADDRESS, 0, 0); 745317027Sdim s->PutChar('}'); 746317027Sdim break; 747317027Sdim 748317027Sdim case eFormatVectorOfUInt64: 749317027Sdim s->PutChar('{'); 750317027Sdim offset = DumpDataExtractor(DE, s, offset, eFormatHex, sizeof(uint64_t), 751317027Sdim item_byte_size / sizeof(uint64_t), 752317027Sdim item_byte_size / sizeof(uint64_t), 753317027Sdim LLDB_INVALID_ADDRESS, 0, 0); 754317027Sdim s->PutChar('}'); 755317027Sdim break; 756317027Sdim 757317027Sdim case eFormatVectorOfFloat16: 758317027Sdim s->PutChar('{'); 759317027Sdim offset = 760317027Sdim DumpDataExtractor(DE, s, offset, eFormatFloat, 2, item_byte_size / 2, 761317027Sdim item_byte_size / 2, LLDB_INVALID_ADDRESS, 0, 0); 762317027Sdim s->PutChar('}'); 763317027Sdim break; 764317027Sdim 765317027Sdim case eFormatVectorOfFloat32: 766317027Sdim s->PutChar('{'); 767317027Sdim offset = 768317027Sdim DumpDataExtractor(DE, s, offset, eFormatFloat, 4, item_byte_size / 4, 769317027Sdim item_byte_size / 4, LLDB_INVALID_ADDRESS, 0, 0); 770317027Sdim s->PutChar('}'); 771317027Sdim break; 772317027Sdim 773317027Sdim case eFormatVectorOfFloat64: 774317027Sdim s->PutChar('{'); 775317027Sdim offset = 776317027Sdim DumpDataExtractor(DE, s, offset, eFormatFloat, 8, item_byte_size / 8, 777317027Sdim item_byte_size / 8, LLDB_INVALID_ADDRESS, 0, 0); 778317027Sdim s->PutChar('}'); 779317027Sdim break; 780317027Sdim 781317027Sdim case eFormatVectorOfUInt128: 782317027Sdim s->PutChar('{'); 783317027Sdim offset = 784317027Sdim DumpDataExtractor(DE, s, offset, eFormatHex, 16, item_byte_size / 16, 785317027Sdim item_byte_size / 16, LLDB_INVALID_ADDRESS, 0, 0); 786317027Sdim s->PutChar('}'); 787317027Sdim break; 788317027Sdim } 789317027Sdim } 790317027Sdim 791317027Sdim if (item_format == eFormatBytesWithASCII && offset > line_start_offset) { 792317027Sdim s->Printf("%*s", static_cast<int>( 793317027Sdim (num_per_line - (offset - line_start_offset)) * 3 + 2), 794317027Sdim ""); 795317027Sdim DumpDataExtractor(DE, s, line_start_offset, eFormatCharPrintable, 1, 796317027Sdim offset - line_start_offset, SIZE_MAX, 797317027Sdim LLDB_INVALID_ADDRESS, 0, 0); 798317027Sdim } 799317027Sdim return offset; // Return the offset at which we ended up 800317027Sdim} 801317027Sdim 802317027Sdimvoid lldb_private::DumpHexBytes(Stream *s, const void *src, size_t src_len, 803317027Sdim uint32_t bytes_per_line, 804317027Sdim lldb::addr_t base_addr) { 805317027Sdim DataExtractor data(src, src_len, lldb::eByteOrderLittle, 4); 806317027Sdim DumpDataExtractor(data, s, 807317027Sdim 0, // Offset into "src" 808317027Sdim lldb::eFormatBytes, // Dump as hex bytes 809317027Sdim 1, // Size of each item is 1 for single bytes 810317027Sdim src_len, // Number of bytes 811317027Sdim bytes_per_line, // Num bytes per line 812317027Sdim base_addr, // Base address 813317027Sdim 0, 0); // Bitfield info 814317027Sdim} 815