DumpDataExtractor.cpp revision 317027
1317027Sdim//===-- DumpDataExtractor.cpp -----------------------------------*- C++ -*-===// 2317027Sdim// 3317027Sdim// The LLVM Compiler Infrastructure 4317027Sdim// 5317027Sdim// This file is distributed under the University of Illinois Open Source 6317027Sdim// License. See LICENSE.TXT for details. 7317027Sdim// 8317027Sdim//===----------------------------------------------------------------------===// 9317027Sdim 10317027Sdim#include "lldb/Core/DumpDataExtractor.h" 11317027Sdim 12317027Sdim#include "lldb/lldb-defines.h" // for LLDB_INVALID_ADDRESS 13317027Sdim#include "lldb/lldb-forward.h" // for TargetSP, DisassemblerSP 14317027Sdim 15317027Sdim#include "lldb/Core/Address.h" // for Address 16317027Sdim#include "lldb/Core/Disassembler.h" 17317027Sdim#include "lldb/Core/ModuleList.h" // for ModuleList 18317027Sdim#include "lldb/Symbol/ClangASTContext.h" 19317027Sdim#include "lldb/Target/ExecutionContext.h" 20317027Sdim#include "lldb/Target/ExecutionContextScope.h" 21317027Sdim#include "lldb/Target/SectionLoadList.h" 22317027Sdim#include "lldb/Target/Target.h" 23317027Sdim#include "lldb/Utility/DataExtractor.h" 24317027Sdim#include "lldb/Utility/Stream.h" 25317027Sdim 26317027Sdim#include "clang/AST/ASTContext.h" // for ASTContext 27317027Sdim#include "clang/AST/CanonicalType.h" // for CanQualType 28317027Sdim 29317027Sdim#include "llvm/ADT/APFloat.h" // for APFloat, APFloatBase:... 30317027Sdim#include "llvm/ADT/APInt.h" // for APInt 31317027Sdim#include "llvm/ADT/ArrayRef.h" // for ArrayRef 32317027Sdim#include "llvm/ADT/SmallVector.h" // for SmallVector 33317027Sdim 34317027Sdim#include <limits> // for numeric_limits, numer... 35317027Sdim#include <memory> // for shared_ptr 36317027Sdim#include <string> // for string, basic_string 37317027Sdim 38317027Sdim#include <assert.h> // for assert 39317027Sdim#include <ctype.h> // for isprint 40317027Sdim#include <inttypes.h> // for PRIu64, PRIx64, PRIX64 41317027Sdim#include <math.h> // for ldexpf 42317027Sdim 43317027Sdim#include <bitset> 44317027Sdim#include <sstream> 45317027Sdim 46317027Sdimusing namespace lldb_private; 47317027Sdimusing namespace lldb; 48317027Sdim 49317027Sdim#define NON_PRINTABLE_CHAR '.' 50317027Sdim 51317027Sdimstatic float half2float(uint16_t half) { 52317027Sdim union { 53317027Sdim float f; 54317027Sdim uint32_t u; 55317027Sdim } u; 56317027Sdim int32_t v = (int16_t)half; 57317027Sdim 58317027Sdim if (0 == (v & 0x7c00)) { 59317027Sdim u.u = v & 0x80007FFFU; 60317027Sdim return u.f * ldexpf(1, 125); 61317027Sdim } 62317027Sdim 63317027Sdim v <<= 13; 64317027Sdim u.u = v | 0x70000000U; 65317027Sdim return u.f * ldexpf(1, -112); 66317027Sdim} 67317027Sdim 68317027Sdimstatic bool GetAPInt(const DataExtractor &data, lldb::offset_t *offset_ptr, 69317027Sdim lldb::offset_t byte_size, llvm::APInt &result) { 70317027Sdim llvm::SmallVector<uint64_t, 2> uint64_array; 71317027Sdim lldb::offset_t bytes_left = byte_size; 72317027Sdim uint64_t u64; 73317027Sdim const lldb::ByteOrder byte_order = data.GetByteOrder(); 74317027Sdim if (byte_order == lldb::eByteOrderLittle) { 75317027Sdim while (bytes_left > 0) { 76317027Sdim if (bytes_left >= 8) { 77317027Sdim u64 = data.GetU64(offset_ptr); 78317027Sdim bytes_left -= 8; 79317027Sdim } else { 80317027Sdim u64 = data.GetMaxU64(offset_ptr, (uint32_t)bytes_left); 81317027Sdim bytes_left = 0; 82317027Sdim } 83317027Sdim uint64_array.push_back(u64); 84317027Sdim } 85317027Sdim result = llvm::APInt(byte_size * 8, llvm::ArrayRef<uint64_t>(uint64_array)); 86317027Sdim return true; 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; 105317027Sdim result = llvm::APInt(byte_size * 8, llvm::ArrayRef<uint64_t>(uint64_array)); 106317027Sdim return true; 107317027Sdim } 108317027Sdim return false; 109317027Sdim} 110317027Sdim 111317027Sdimstatic lldb::offset_t DumpAPInt(Stream *s, const DataExtractor &data, 112317027Sdim lldb::offset_t offset, lldb::offset_t byte_size, 113317027Sdim bool is_signed, unsigned radix) { 114317027Sdim llvm::APInt apint; 115317027Sdim if (GetAPInt(data, &offset, byte_size, apint)) { 116317027Sdim std::string apint_str(apint.toString(radix, is_signed)); 117317027Sdim switch (radix) { 118317027Sdim case 2: 119317027Sdim s->Write("0b", 2); 120317027Sdim break; 121317027Sdim case 8: 122317027Sdim s->Write("0", 1); 123317027Sdim break; 124317027Sdim case 10: 125317027Sdim break; 126317027Sdim } 127317027Sdim s->Write(apint_str.c_str(), apint_str.size()); 128317027Sdim } 129317027Sdim return offset; 130317027Sdim} 131317027Sdim 132317027Sdimlldb::offset_t lldb_private::DumpDataExtractor( 133317027Sdim const DataExtractor &DE, Stream *s, offset_t start_offset, 134317027Sdim lldb::Format item_format, size_t item_byte_size, size_t item_count, 135317027Sdim size_t num_per_line, uint64_t base_addr, 136317027Sdim uint32_t item_bit_size, // If zero, this is not a bitfield value, if 137317027Sdim // non-zero, the value is a bitfield 138317027Sdim uint32_t item_bit_offset, // If "item_bit_size" is non-zero, this is the 139317027Sdim // shift amount to apply to a bitfield 140317027Sdim ExecutionContextScope *exe_scope) { 141317027Sdim if (s == nullptr) 142317027Sdim return start_offset; 143317027Sdim 144317027Sdim if (item_format == eFormatPointer) { 145317027Sdim if (item_byte_size != 4 && item_byte_size != 8) 146317027Sdim item_byte_size = s->GetAddressByteSize(); 147317027Sdim } 148317027Sdim 149317027Sdim offset_t offset = start_offset; 150317027Sdim 151317027Sdim if (item_format == eFormatInstruction) { 152317027Sdim TargetSP target_sp; 153317027Sdim if (exe_scope) 154317027Sdim target_sp = exe_scope->CalculateTarget(); 155317027Sdim if (target_sp) { 156317027Sdim DisassemblerSP disassembler_sp(Disassembler::FindPlugin( 157317027Sdim target_sp->GetArchitecture(), nullptr, 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); 241317027Sdim // Avoid std::bitset<64>::to_string() since it is missing in 242317027Sdim // earlier 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 265317027Sdim // Put an extra space between the groups of bytes if more than one 266317027Sdim // is 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: { 274317027Sdim // If we are only printing one character surround it with single 275317027Sdim // quotes 276317027Sdim if (item_count == 1 && item_format == eFormatChar) 277317027Sdim s->PutChar('\''); 278317027Sdim 279317027Sdim const uint64_t ch = DE.GetMaxU64Bitfield(&offset, item_byte_size, 280317027Sdim item_bit_size, item_bit_offset); 281317027Sdim if (isprint(ch)) 282317027Sdim s->Printf("%c", (char)ch); 283317027Sdim else if (item_format != eFormatCharPrintable) { 284317027Sdim switch (ch) { 285317027Sdim case '\033': 286317027Sdim s->Printf("\\e"); 287317027Sdim break; 288317027Sdim case '\a': 289317027Sdim s->Printf("\\a"); 290317027Sdim break; 291317027Sdim case '\b': 292317027Sdim s->Printf("\\b"); 293317027Sdim break; 294317027Sdim case '\f': 295317027Sdim s->Printf("\\f"); 296317027Sdim break; 297317027Sdim case '\n': 298317027Sdim s->Printf("\\n"); 299317027Sdim break; 300317027Sdim case '\r': 301317027Sdim s->Printf("\\r"); 302317027Sdim break; 303317027Sdim case '\t': 304317027Sdim s->Printf("\\t"); 305317027Sdim break; 306317027Sdim case '\v': 307317027Sdim s->Printf("\\v"); 308317027Sdim break; 309317027Sdim case '\0': 310317027Sdim s->Printf("\\0"); 311317027Sdim break; 312317027Sdim default: 313317027Sdim if (item_byte_size == 1) 314317027Sdim s->Printf("\\x%2.2x", (uint8_t)ch); 315317027Sdim else 316317027Sdim s->Printf("%" PRIu64, ch); 317317027Sdim break; 318317027Sdim } 319317027Sdim } else { 320317027Sdim s->PutChar(NON_PRINTABLE_CHAR); 321317027Sdim } 322317027Sdim 323317027Sdim // If we are only printing one character surround it with single quotes 324317027Sdim if (item_count == 1 && item_format == eFormatChar) 325317027Sdim s->PutChar('\''); 326317027Sdim } break; 327317027Sdim 328317027Sdim case eFormatEnum: // Print enum value as a signed integer when we don't get 329317027Sdim // the enum type 330317027Sdim case eFormatDecimal: 331317027Sdim if (item_byte_size <= 8) 332317027Sdim s->Printf("%" PRId64, 333317027Sdim DE.GetMaxS64Bitfield(&offset, item_byte_size, item_bit_size, 334317027Sdim item_bit_offset)); 335317027Sdim else { 336317027Sdim const bool is_signed = true; 337317027Sdim const unsigned radix = 10; 338317027Sdim offset = DumpAPInt(s, DE, offset, item_byte_size, is_signed, radix); 339317027Sdim } 340317027Sdim break; 341317027Sdim 342317027Sdim case eFormatUnsigned: 343317027Sdim if (item_byte_size <= 8) 344317027Sdim s->Printf("%" PRIu64, 345317027Sdim DE.GetMaxU64Bitfield(&offset, item_byte_size, item_bit_size, 346317027Sdim item_bit_offset)); 347317027Sdim else { 348317027Sdim const bool is_signed = false; 349317027Sdim const unsigned radix = 10; 350317027Sdim offset = DumpAPInt(s, DE, offset, item_byte_size, is_signed, radix); 351317027Sdim } 352317027Sdim break; 353317027Sdim 354317027Sdim case eFormatOctal: 355317027Sdim if (item_byte_size <= 8) 356317027Sdim s->Printf("0%" PRIo64, 357317027Sdim DE.GetMaxS64Bitfield(&offset, item_byte_size, item_bit_size, 358317027Sdim item_bit_offset)); 359317027Sdim else { 360317027Sdim const bool is_signed = false; 361317027Sdim const unsigned radix = 8; 362317027Sdim offset = DumpAPInt(s, DE, offset, item_byte_size, is_signed, radix); 363317027Sdim } 364317027Sdim break; 365317027Sdim 366317027Sdim case eFormatOSType: { 367317027Sdim uint64_t uval64 = DE.GetMaxU64Bitfield(&offset, item_byte_size, 368317027Sdim item_bit_size, item_bit_offset); 369317027Sdim s->PutChar('\''); 370317027Sdim for (uint32_t i = 0; i < item_byte_size; ++i) { 371317027Sdim uint8_t ch = (uint8_t)(uval64 >> ((item_byte_size - i - 1) * 8)); 372317027Sdim if (isprint(ch)) 373317027Sdim s->Printf("%c", ch); 374317027Sdim else { 375317027Sdim switch (ch) { 376317027Sdim case '\033': 377317027Sdim s->Printf("\\e"); 378317027Sdim break; 379317027Sdim case '\a': 380317027Sdim s->Printf("\\a"); 381317027Sdim break; 382317027Sdim case '\b': 383317027Sdim s->Printf("\\b"); 384317027Sdim break; 385317027Sdim case '\f': 386317027Sdim s->Printf("\\f"); 387317027Sdim break; 388317027Sdim case '\n': 389317027Sdim s->Printf("\\n"); 390317027Sdim break; 391317027Sdim case '\r': 392317027Sdim s->Printf("\\r"); 393317027Sdim break; 394317027Sdim case '\t': 395317027Sdim s->Printf("\\t"); 396317027Sdim break; 397317027Sdim case '\v': 398317027Sdim s->Printf("\\v"); 399317027Sdim break; 400317027Sdim case '\0': 401317027Sdim s->Printf("\\0"); 402317027Sdim break; 403317027Sdim default: 404317027Sdim s->Printf("\\x%2.2x", ch); 405317027Sdim break; 406317027Sdim } 407317027Sdim } 408317027Sdim } 409317027Sdim s->PutChar('\''); 410317027Sdim } break; 411317027Sdim 412317027Sdim case eFormatCString: { 413317027Sdim const char *cstr = DE.GetCStr(&offset); 414317027Sdim 415317027Sdim if (!cstr) { 416317027Sdim s->Printf("NULL"); 417317027Sdim offset = LLDB_INVALID_OFFSET; 418317027Sdim } else { 419317027Sdim s->PutChar('\"'); 420317027Sdim 421317027Sdim while (const char c = *cstr) { 422317027Sdim if (isprint(c)) { 423317027Sdim s->PutChar(c); 424317027Sdim } else { 425317027Sdim switch (c) { 426317027Sdim case '\033': 427317027Sdim s->Printf("\\e"); 428317027Sdim break; 429317027Sdim case '\a': 430317027Sdim s->Printf("\\a"); 431317027Sdim break; 432317027Sdim case '\b': 433317027Sdim s->Printf("\\b"); 434317027Sdim break; 435317027Sdim case '\f': 436317027Sdim s->Printf("\\f"); 437317027Sdim break; 438317027Sdim case '\n': 439317027Sdim s->Printf("\\n"); 440317027Sdim break; 441317027Sdim case '\r': 442317027Sdim s->Printf("\\r"); 443317027Sdim break; 444317027Sdim case '\t': 445317027Sdim s->Printf("\\t"); 446317027Sdim break; 447317027Sdim case '\v': 448317027Sdim s->Printf("\\v"); 449317027Sdim break; 450317027Sdim default: 451317027Sdim s->Printf("\\x%2.2x", c); 452317027Sdim break; 453317027Sdim } 454317027Sdim } 455317027Sdim 456317027Sdim ++cstr; 457317027Sdim } 458317027Sdim 459317027Sdim s->PutChar('\"'); 460317027Sdim } 461317027Sdim } break; 462317027Sdim 463317027Sdim case eFormatPointer: 464317027Sdim s->Address(DE.GetMaxU64Bitfield(&offset, item_byte_size, item_bit_size, 465317027Sdim item_bit_offset), 466317027Sdim sizeof(addr_t)); 467317027Sdim break; 468317027Sdim 469317027Sdim case eFormatComplexInteger: { 470317027Sdim size_t complex_int_byte_size = item_byte_size / 2; 471317027Sdim 472317027Sdim if (complex_int_byte_size > 0 && complex_int_byte_size <= 8) { 473317027Sdim s->Printf("%" PRIu64, 474317027Sdim DE.GetMaxU64Bitfield(&offset, complex_int_byte_size, 0, 0)); 475317027Sdim s->Printf(" + %" PRIu64 "i", 476317027Sdim DE.GetMaxU64Bitfield(&offset, complex_int_byte_size, 0, 0)); 477317027Sdim } else { 478317027Sdim s->Printf("error: unsupported byte size (%" PRIu64 479317027Sdim ") for complex integer format", 480317027Sdim (uint64_t)item_byte_size); 481317027Sdim return offset; 482317027Sdim } 483317027Sdim } break; 484317027Sdim 485317027Sdim case eFormatComplex: 486317027Sdim if (sizeof(float) * 2 == item_byte_size) { 487317027Sdim float f32_1 = DE.GetFloat(&offset); 488317027Sdim float f32_2 = DE.GetFloat(&offset); 489317027Sdim 490317027Sdim s->Printf("%g + %gi", f32_1, f32_2); 491317027Sdim break; 492317027Sdim } else if (sizeof(double) * 2 == item_byte_size) { 493317027Sdim double d64_1 = DE.GetDouble(&offset); 494317027Sdim double d64_2 = DE.GetDouble(&offset); 495317027Sdim 496317027Sdim s->Printf("%lg + %lgi", d64_1, d64_2); 497317027Sdim break; 498317027Sdim } else if (sizeof(long double) * 2 == item_byte_size) { 499317027Sdim long double ld64_1 = DE.GetLongDouble(&offset); 500317027Sdim long double ld64_2 = DE.GetLongDouble(&offset); 501317027Sdim s->Printf("%Lg + %Lgi", ld64_1, ld64_2); 502317027Sdim break; 503317027Sdim } else { 504317027Sdim s->Printf("error: unsupported byte size (%" PRIu64 505317027Sdim ") for complex float format", 506317027Sdim (uint64_t)item_byte_size); 507317027Sdim return offset; 508317027Sdim } 509317027Sdim break; 510317027Sdim 511317027Sdim default: 512317027Sdim case eFormatDefault: 513317027Sdim case eFormatHex: 514317027Sdim case eFormatHexUppercase: { 515317027Sdim bool wantsuppercase = (item_format == eFormatHexUppercase); 516317027Sdim switch (item_byte_size) { 517317027Sdim case 1: 518317027Sdim case 2: 519317027Sdim case 4: 520317027Sdim case 8: 521317027Sdim s->Printf(wantsuppercase ? "0x%*.*" PRIX64 : "0x%*.*" PRIx64, 522317027Sdim (int)(2 * item_byte_size), (int)(2 * item_byte_size), 523317027Sdim DE.GetMaxU64Bitfield(&offset, item_byte_size, item_bit_size, 524317027Sdim item_bit_offset)); 525317027Sdim break; 526317027Sdim default: { 527317027Sdim assert(item_bit_size == 0 && item_bit_offset == 0); 528317027Sdim const uint8_t *bytes = 529317027Sdim (const uint8_t *)DE.GetData(&offset, item_byte_size); 530317027Sdim if (bytes) { 531317027Sdim s->PutCString("0x"); 532317027Sdim uint32_t idx; 533317027Sdim if (DE.GetByteOrder() == eByteOrderBig) { 534317027Sdim for (idx = 0; idx < item_byte_size; ++idx) 535317027Sdim s->Printf(wantsuppercase ? "%2.2X" : "%2.2x", bytes[idx]); 536317027Sdim } else { 537317027Sdim for (idx = 0; idx < item_byte_size; ++idx) 538317027Sdim s->Printf(wantsuppercase ? "%2.2X" : "%2.2x", 539317027Sdim bytes[item_byte_size - 1 - idx]); 540317027Sdim } 541317027Sdim } 542317027Sdim } break; 543317027Sdim } 544317027Sdim } break; 545317027Sdim 546317027Sdim case eFormatFloat: { 547317027Sdim TargetSP target_sp; 548317027Sdim bool used_apfloat = false; 549317027Sdim if (exe_scope) 550317027Sdim target_sp = exe_scope->CalculateTarget(); 551317027Sdim if (target_sp) { 552317027Sdim ClangASTContext *clang_ast = target_sp->GetScratchClangASTContext(); 553317027Sdim if (clang_ast) { 554317027Sdim clang::ASTContext *ast = clang_ast->getASTContext(); 555317027Sdim if (ast) { 556317027Sdim llvm::SmallVector<char, 256> sv; 557317027Sdim // Show full precision when printing float values 558317027Sdim const unsigned format_precision = 0; 559317027Sdim const unsigned format_max_padding = 100; 560317027Sdim size_t item_bit_size = item_byte_size * 8; 561317027Sdim 562317027Sdim if (item_bit_size == ast->getTypeSize(ast->FloatTy)) { 563317027Sdim llvm::APInt apint(item_bit_size, 564317027Sdim DE.GetMaxU64(&offset, item_byte_size)); 565317027Sdim llvm::APFloat apfloat(ast->getFloatTypeSemantics(ast->FloatTy), 566317027Sdim apint); 567317027Sdim apfloat.toString(sv, format_precision, format_max_padding); 568317027Sdim } else if (item_bit_size == ast->getTypeSize(ast->DoubleTy)) { 569317027Sdim llvm::APInt apint; 570317027Sdim if (GetAPInt(DE, &offset, item_byte_size, apint)) { 571317027Sdim llvm::APFloat apfloat(ast->getFloatTypeSemantics(ast->DoubleTy), 572317027Sdim apint); 573317027Sdim apfloat.toString(sv, format_precision, format_max_padding); 574317027Sdim } 575317027Sdim } else if (item_bit_size == ast->getTypeSize(ast->LongDoubleTy)) { 576317027Sdim const auto &semantics = 577317027Sdim ast->getFloatTypeSemantics(ast->LongDoubleTy); 578317027Sdim const auto byte_size = 579317027Sdim (llvm::APFloat::getSizeInBits(semantics) + 7) / 8; 580317027Sdim 581317027Sdim llvm::APInt apint; 582317027Sdim if (GetAPInt(DE, &offset, byte_size, apint)) { 583317027Sdim llvm::APFloat apfloat(semantics, apint); 584317027Sdim apfloat.toString(sv, format_precision, format_max_padding); 585317027Sdim } 586317027Sdim } else if (item_bit_size == ast->getTypeSize(ast->HalfTy)) { 587317027Sdim llvm::APInt apint(item_bit_size, DE.GetU16(&offset)); 588317027Sdim llvm::APFloat apfloat(ast->getFloatTypeSemantics(ast->HalfTy), 589317027Sdim apint); 590317027Sdim apfloat.toString(sv, format_precision, format_max_padding); 591317027Sdim } 592317027Sdim 593317027Sdim if (!sv.empty()) { 594317027Sdim s->Printf("%*.*s", (int)sv.size(), (int)sv.size(), sv.data()); 595317027Sdim used_apfloat = true; 596317027Sdim } 597317027Sdim } 598317027Sdim } 599317027Sdim } 600317027Sdim 601317027Sdim if (!used_apfloat) { 602317027Sdim std::ostringstream ss; 603317027Sdim if (item_byte_size == sizeof(float) || item_byte_size == 2) { 604317027Sdim float f; 605317027Sdim if (item_byte_size == 2) { 606317027Sdim uint16_t half = DE.GetU16(&offset); 607317027Sdim f = half2float(half); 608317027Sdim } else { 609317027Sdim f = DE.GetFloat(&offset); 610317027Sdim } 611317027Sdim ss.precision(std::numeric_limits<float>::digits10); 612317027Sdim ss << f; 613317027Sdim } else if (item_byte_size == sizeof(double)) { 614317027Sdim ss.precision(std::numeric_limits<double>::digits10); 615317027Sdim ss << DE.GetDouble(&offset); 616317027Sdim } else if (item_byte_size == sizeof(long double) || 617317027Sdim item_byte_size == 10) { 618317027Sdim ss.precision(std::numeric_limits<long double>::digits10); 619317027Sdim ss << DE.GetLongDouble(&offset); 620317027Sdim } else { 621317027Sdim s->Printf("error: unsupported byte size (%" PRIu64 622317027Sdim ") for float format", 623317027Sdim (uint64_t)item_byte_size); 624317027Sdim return offset; 625317027Sdim } 626317027Sdim ss.flush(); 627317027Sdim s->Printf("%s", ss.str().c_str()); 628317027Sdim } 629317027Sdim } break; 630317027Sdim 631317027Sdim case eFormatUnicode16: 632317027Sdim s->Printf("U+%4.4x", DE.GetU16(&offset)); 633317027Sdim break; 634317027Sdim 635317027Sdim case eFormatUnicode32: 636317027Sdim s->Printf("U+0x%8.8x", DE.GetU32(&offset)); 637317027Sdim break; 638317027Sdim 639317027Sdim case eFormatAddressInfo: { 640317027Sdim addr_t addr = DE.GetMaxU64Bitfield(&offset, item_byte_size, item_bit_size, 641317027Sdim item_bit_offset); 642317027Sdim s->Printf("0x%*.*" PRIx64, (int)(2 * item_byte_size), 643317027Sdim (int)(2 * item_byte_size), addr); 644317027Sdim if (exe_scope) { 645317027Sdim TargetSP target_sp(exe_scope->CalculateTarget()); 646317027Sdim lldb_private::Address so_addr; 647317027Sdim if (target_sp) { 648317027Sdim if (target_sp->GetSectionLoadList().ResolveLoadAddress(addr, 649317027Sdim so_addr)) { 650317027Sdim s->PutChar(' '); 651317027Sdim so_addr.Dump(s, exe_scope, Address::DumpStyleResolvedDescription, 652317027Sdim Address::DumpStyleModuleWithFileAddress); 653317027Sdim } else { 654317027Sdim so_addr.SetOffset(addr); 655317027Sdim so_addr.Dump(s, exe_scope, 656317027Sdim Address::DumpStyleResolvedPointerDescription); 657317027Sdim } 658317027Sdim } 659317027Sdim } 660317027Sdim } break; 661317027Sdim 662317027Sdim case eFormatHexFloat: 663317027Sdim if (sizeof(float) == item_byte_size) { 664317027Sdim char float_cstr[256]; 665317027Sdim llvm::APFloat ap_float(DE.GetFloat(&offset)); 666317027Sdim ap_float.convertToHexString(float_cstr, 0, false, 667317027Sdim llvm::APFloat::rmNearestTiesToEven); 668317027Sdim s->Printf("%s", float_cstr); 669317027Sdim break; 670317027Sdim } else if (sizeof(double) == item_byte_size) { 671317027Sdim char float_cstr[256]; 672317027Sdim llvm::APFloat ap_float(DE.GetDouble(&offset)); 673317027Sdim ap_float.convertToHexString(float_cstr, 0, false, 674317027Sdim llvm::APFloat::rmNearestTiesToEven); 675317027Sdim s->Printf("%s", float_cstr); 676317027Sdim break; 677317027Sdim } else { 678317027Sdim s->Printf("error: unsupported byte size (%" PRIu64 679317027Sdim ") for hex float format", 680317027Sdim (uint64_t)item_byte_size); 681317027Sdim return offset; 682317027Sdim } 683317027Sdim break; 684317027Sdim 685317027Sdim // please keep the single-item formats below in sync with 686317027Sdim // FormatManager::GetSingleItemFormat 687317027Sdim // if you fail to do so, users will start getting different outputs 688317027Sdim // depending on internal 689317027Sdim // implementation details they should not care about || 690317027Sdim case eFormatVectorOfChar: // || 691317027Sdim s->PutChar('{'); // \/ 692317027Sdim offset = 693317027Sdim DumpDataExtractor(DE, s, offset, eFormatCharArray, 1, item_byte_size, 694317027Sdim item_byte_size, LLDB_INVALID_ADDRESS, 0, 0); 695317027Sdim s->PutChar('}'); 696317027Sdim break; 697317027Sdim 698317027Sdim case eFormatVectorOfSInt8: 699317027Sdim s->PutChar('{'); 700317027Sdim offset = 701317027Sdim DumpDataExtractor(DE, s, offset, eFormatDecimal, 1, item_byte_size, 702317027Sdim item_byte_size, LLDB_INVALID_ADDRESS, 0, 0); 703317027Sdim s->PutChar('}'); 704317027Sdim break; 705317027Sdim 706317027Sdim case eFormatVectorOfUInt8: 707317027Sdim s->PutChar('{'); 708317027Sdim offset = DumpDataExtractor(DE, s, offset, eFormatHex, 1, item_byte_size, 709317027Sdim item_byte_size, LLDB_INVALID_ADDRESS, 0, 0); 710317027Sdim s->PutChar('}'); 711317027Sdim break; 712317027Sdim 713317027Sdim case eFormatVectorOfSInt16: 714317027Sdim s->PutChar('{'); 715317027Sdim offset = DumpDataExtractor( 716317027Sdim DE, s, offset, eFormatDecimal, sizeof(uint16_t), 717317027Sdim item_byte_size / sizeof(uint16_t), item_byte_size / sizeof(uint16_t), 718317027Sdim LLDB_INVALID_ADDRESS, 0, 0); 719317027Sdim s->PutChar('}'); 720317027Sdim break; 721317027Sdim 722317027Sdim case eFormatVectorOfUInt16: 723317027Sdim s->PutChar('{'); 724317027Sdim offset = DumpDataExtractor(DE, s, offset, eFormatHex, sizeof(uint16_t), 725317027Sdim item_byte_size / sizeof(uint16_t), 726317027Sdim item_byte_size / sizeof(uint16_t), 727317027Sdim LLDB_INVALID_ADDRESS, 0, 0); 728317027Sdim s->PutChar('}'); 729317027Sdim break; 730317027Sdim 731317027Sdim case eFormatVectorOfSInt32: 732317027Sdim s->PutChar('{'); 733317027Sdim offset = DumpDataExtractor( 734317027Sdim DE, s, offset, eFormatDecimal, sizeof(uint32_t), 735317027Sdim item_byte_size / sizeof(uint32_t), item_byte_size / sizeof(uint32_t), 736317027Sdim LLDB_INVALID_ADDRESS, 0, 0); 737317027Sdim s->PutChar('}'); 738317027Sdim break; 739317027Sdim 740317027Sdim case eFormatVectorOfUInt32: 741317027Sdim s->PutChar('{'); 742317027Sdim offset = DumpDataExtractor(DE, s, offset, eFormatHex, sizeof(uint32_t), 743317027Sdim item_byte_size / sizeof(uint32_t), 744317027Sdim item_byte_size / sizeof(uint32_t), 745317027Sdim LLDB_INVALID_ADDRESS, 0, 0); 746317027Sdim s->PutChar('}'); 747317027Sdim break; 748317027Sdim 749317027Sdim case eFormatVectorOfSInt64: 750317027Sdim s->PutChar('{'); 751317027Sdim offset = DumpDataExtractor( 752317027Sdim DE, s, offset, eFormatDecimal, sizeof(uint64_t), 753317027Sdim item_byte_size / sizeof(uint64_t), item_byte_size / sizeof(uint64_t), 754317027Sdim LLDB_INVALID_ADDRESS, 0, 0); 755317027Sdim s->PutChar('}'); 756317027Sdim break; 757317027Sdim 758317027Sdim case eFormatVectorOfUInt64: 759317027Sdim s->PutChar('{'); 760317027Sdim offset = DumpDataExtractor(DE, s, offset, eFormatHex, sizeof(uint64_t), 761317027Sdim item_byte_size / sizeof(uint64_t), 762317027Sdim item_byte_size / sizeof(uint64_t), 763317027Sdim LLDB_INVALID_ADDRESS, 0, 0); 764317027Sdim s->PutChar('}'); 765317027Sdim break; 766317027Sdim 767317027Sdim case eFormatVectorOfFloat16: 768317027Sdim s->PutChar('{'); 769317027Sdim offset = 770317027Sdim DumpDataExtractor(DE, s, offset, eFormatFloat, 2, item_byte_size / 2, 771317027Sdim item_byte_size / 2, LLDB_INVALID_ADDRESS, 0, 0); 772317027Sdim s->PutChar('}'); 773317027Sdim break; 774317027Sdim 775317027Sdim case eFormatVectorOfFloat32: 776317027Sdim s->PutChar('{'); 777317027Sdim offset = 778317027Sdim DumpDataExtractor(DE, s, offset, eFormatFloat, 4, item_byte_size / 4, 779317027Sdim item_byte_size / 4, LLDB_INVALID_ADDRESS, 0, 0); 780317027Sdim s->PutChar('}'); 781317027Sdim break; 782317027Sdim 783317027Sdim case eFormatVectorOfFloat64: 784317027Sdim s->PutChar('{'); 785317027Sdim offset = 786317027Sdim DumpDataExtractor(DE, s, offset, eFormatFloat, 8, item_byte_size / 8, 787317027Sdim item_byte_size / 8, LLDB_INVALID_ADDRESS, 0, 0); 788317027Sdim s->PutChar('}'); 789317027Sdim break; 790317027Sdim 791317027Sdim case eFormatVectorOfUInt128: 792317027Sdim s->PutChar('{'); 793317027Sdim offset = 794317027Sdim DumpDataExtractor(DE, s, offset, eFormatHex, 16, item_byte_size / 16, 795317027Sdim item_byte_size / 16, LLDB_INVALID_ADDRESS, 0, 0); 796317027Sdim s->PutChar('}'); 797317027Sdim break; 798317027Sdim } 799317027Sdim } 800317027Sdim 801317027Sdim if (item_format == eFormatBytesWithASCII && offset > line_start_offset) { 802317027Sdim s->Printf("%*s", static_cast<int>( 803317027Sdim (num_per_line - (offset - line_start_offset)) * 3 + 2), 804317027Sdim ""); 805317027Sdim DumpDataExtractor(DE, s, line_start_offset, eFormatCharPrintable, 1, 806317027Sdim offset - line_start_offset, SIZE_MAX, 807317027Sdim LLDB_INVALID_ADDRESS, 0, 0); 808317027Sdim } 809317027Sdim return offset; // Return the offset at which we ended up 810317027Sdim} 811317027Sdim 812317027Sdimvoid lldb_private::DumpHexBytes(Stream *s, const void *src, size_t src_len, 813317027Sdim uint32_t bytes_per_line, 814317027Sdim lldb::addr_t base_addr) { 815317027Sdim DataExtractor data(src, src_len, lldb::eByteOrderLittle, 4); 816317027Sdim DumpDataExtractor(data, s, 817317027Sdim 0, // Offset into "src" 818317027Sdim lldb::eFormatBytes, // Dump as hex bytes 819317027Sdim 1, // Size of each item is 1 for single bytes 820317027Sdim src_len, // Number of bytes 821317027Sdim bytes_per_line, // Num bytes per line 822317027Sdim base_addr, // Base address 823317027Sdim 0, 0); // Bitfield info 824317027Sdim} 825