1 //===-- DumpDataExtractor.cpp -----------------------------------*- C++ -*-===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 #include "lldb/Core/DumpDataExtractor.h"
11 #include "lldb/lldb-defines.h"
12 #include "lldb/lldb-forward.h"
14 #include "lldb/Core/Address.h"
15 #include "lldb/Core/Disassembler.h"
16 #include "lldb/Core/ModuleList.h"
17 #include "lldb/Target/ExecutionContext.h"
18 #include "lldb/Target/ExecutionContextScope.h"
19 #include "lldb/Target/SectionLoadList.h"
20 #include "lldb/Target/Target.h"
21 #include "lldb/Utility/DataExtractor.h"
22 #include "lldb/Utility/Log.h"
23 #include "lldb/Utility/Stream.h"
25 #include "llvm/ADT/APFloat.h"
26 #include "llvm/ADT/APInt.h"
27 #include "llvm/ADT/ArrayRef.h"
28 #include "llvm/ADT/Optional.h"
29 #include "llvm/ADT/SmallVector.h"
43 using namespace lldb_private;
46 #define NON_PRINTABLE_CHAR '.'
48 static float half2float(uint16_t half) {
53 int32_t v = (int16_t)half;
55 if (0 == (v & 0x7c00)) {
56 u.u = v & 0x80007FFFU;
57 return u.f * ldexpf(1, 125);
61 u.u = v | 0x70000000U;
62 return u.f * ldexpf(1, -112);
65 static llvm::Optional<llvm::APInt> GetAPInt(const DataExtractor &data,
66 lldb::offset_t *offset_ptr,
67 lldb::offset_t byte_size) {
71 llvm::SmallVector<uint64_t, 2> uint64_array;
72 lldb::offset_t bytes_left = byte_size;
74 const lldb::ByteOrder byte_order = data.GetByteOrder();
75 if (byte_order == lldb::eByteOrderLittle) {
76 while (bytes_left > 0) {
77 if (bytes_left >= 8) {
78 u64 = data.GetU64(offset_ptr);
81 u64 = data.GetMaxU64(offset_ptr, (uint32_t)bytes_left);
84 uint64_array.push_back(u64);
86 return llvm::APInt(byte_size * 8, llvm::ArrayRef<uint64_t>(uint64_array));
87 } else if (byte_order == lldb::eByteOrderBig) {
88 lldb::offset_t be_offset = *offset_ptr + byte_size;
89 lldb::offset_t temp_offset;
90 while (bytes_left > 0) {
91 if (bytes_left >= 8) {
93 temp_offset = be_offset;
94 u64 = data.GetU64(&temp_offset);
97 be_offset -= bytes_left;
98 temp_offset = be_offset;
99 u64 = data.GetMaxU64(&temp_offset, (uint32_t)bytes_left);
102 uint64_array.push_back(u64);
104 *offset_ptr += byte_size;
105 return llvm::APInt(byte_size * 8, llvm::ArrayRef<uint64_t>(uint64_array));
110 static lldb::offset_t DumpAPInt(Stream *s, const DataExtractor &data,
111 lldb::offset_t offset, lldb::offset_t byte_size,
112 bool is_signed, unsigned radix) {
113 llvm::Optional<llvm::APInt> apint = GetAPInt(data, &offset, byte_size);
114 if (apint.hasValue()) {
115 std::string apint_str(apint.getValue().toString(radix, is_signed));
126 s->Write(apint_str.c_str(), apint_str.size());
131 lldb::offset_t lldb_private::DumpDataExtractor(
132 const DataExtractor &DE, Stream *s, offset_t start_offset,
133 lldb::Format item_format, size_t item_byte_size, size_t item_count,
134 size_t num_per_line, uint64_t base_addr,
135 uint32_t item_bit_size, // If zero, this is not a bitfield value, if
136 // non-zero, the value is a bitfield
137 uint32_t item_bit_offset, // If "item_bit_size" is non-zero, this is the
138 // shift amount to apply to a bitfield
139 ExecutionContextScope *exe_scope) {
143 if (item_format == eFormatPointer) {
144 if (item_byte_size != 4 && item_byte_size != 8)
145 item_byte_size = s->GetAddressByteSize();
148 offset_t offset = start_offset;
150 if (item_format == eFormatInstruction) {
153 target_sp = exe_scope->CalculateTarget();
155 DisassemblerSP disassembler_sp(Disassembler::FindPlugin(
156 target_sp->GetArchitecture(),
157 target_sp->GetDisassemblyFlavor(), nullptr));
158 if (disassembler_sp) {
159 lldb::addr_t addr = base_addr + start_offset;
160 lldb_private::Address so_addr;
161 bool data_from_file = true;
162 if (target_sp->GetSectionLoadList().ResolveLoadAddress(addr, so_addr)) {
163 data_from_file = false;
165 if (target_sp->GetSectionLoadList().IsEmpty() ||
166 !target_sp->GetImages().ResolveFileAddress(addr, so_addr))
167 so_addr.SetRawAddress(addr);
170 size_t bytes_consumed = disassembler_sp->DecodeInstructions(
171 so_addr, DE, start_offset, item_count, false, data_from_file);
173 if (bytes_consumed) {
174 offset += bytes_consumed;
175 const bool show_address = base_addr != LLDB_INVALID_ADDRESS;
176 const bool show_bytes = true;
177 ExecutionContext exe_ctx;
178 exe_scope->CalculateExecutionContext(exe_ctx);
179 disassembler_sp->GetInstructionList().Dump(s, show_address,
180 show_bytes, &exe_ctx);
184 s->Printf("invalid target");
189 if ((item_format == eFormatOSType || item_format == eFormatAddressInfo) &&
191 item_format = eFormatHex;
193 lldb::offset_t line_start_offset = start_offset;
194 for (uint32_t count = 0; DE.ValidOffset(offset) && count < item_count;
196 if ((count % num_per_line) == 0) {
198 if (item_format == eFormatBytesWithASCII &&
199 offset > line_start_offset) {
202 (num_per_line - (offset - line_start_offset)) * 3 + 2),
204 DumpDataExtractor(DE, s, line_start_offset, eFormatCharPrintable, 1,
205 offset - line_start_offset, SIZE_MAX,
206 LLDB_INVALID_ADDRESS, 0, 0);
210 if (base_addr != LLDB_INVALID_ADDRESS)
211 s->Printf("0x%8.8" PRIx64 ": ",
212 (uint64_t)(base_addr +
213 (offset - start_offset) / DE.getTargetByteSize()));
215 line_start_offset = offset;
216 } else if (item_format != eFormatChar &&
217 item_format != eFormatCharPrintable &&
218 item_format != eFormatCharArray && count > 0) {
222 switch (item_format) {
224 if (item_byte_size <= 8)
225 s->Printf("%s", DE.GetMaxU64Bitfield(&offset, item_byte_size,
226 item_bit_size, item_bit_offset)
230 s->Printf("error: unsupported byte size (%" PRIu64
231 ") for boolean format",
232 (uint64_t)item_byte_size);
238 if (item_byte_size <= 8) {
239 uint64_t uval64 = DE.GetMaxU64Bitfield(&offset, item_byte_size,
240 item_bit_size, item_bit_offset);
241 // Avoid std::bitset<64>::to_string() since it is missing in earlier
243 std::string binary_value(64, '0');
244 std::bitset<64> bits(uval64);
245 for (uint32_t i = 0; i < 64; ++i)
247 binary_value[64 - 1 - i] = '1';
248 if (item_bit_size > 0)
249 s->Printf("0b%s", binary_value.c_str() + 64 - item_bit_size);
250 else if (item_byte_size > 0 && item_byte_size <= 8)
251 s->Printf("0b%s", binary_value.c_str() + 64 - item_byte_size * 8);
253 const bool is_signed = false;
254 const unsigned radix = 2;
255 offset = DumpAPInt(s, DE, offset, item_byte_size, is_signed, radix);
260 case eFormatBytesWithASCII:
261 for (uint32_t i = 0; i < item_byte_size; ++i) {
262 s->Printf("%2.2x", DE.GetU8(&offset));
265 // Put an extra space between the groups of bytes if more than one is
266 // being dumped in a group (item_byte_size is more than 1).
267 if (item_byte_size > 1)
272 case eFormatCharPrintable:
273 case eFormatCharArray: {
274 // Reject invalid item_byte_size.
275 if (item_byte_size > 8) {
276 s->Printf("error: unsupported byte size (%" PRIu64 ") for char format",
277 (uint64_t)item_byte_size);
281 // If we are only printing one character surround it with single quotes
282 if (item_count == 1 && item_format == eFormatChar)
285 const uint64_t ch = DE.GetMaxU64Bitfield(&offset, item_byte_size,
286 item_bit_size, item_bit_offset);
288 s->Printf("%c", (char)ch);
289 else if (item_format != eFormatCharPrintable) {
319 if (item_byte_size == 1)
320 s->Printf("\\x%2.2x", (uint8_t)ch);
322 s->Printf("%" PRIu64, ch);
326 s->PutChar(NON_PRINTABLE_CHAR);
329 // If we are only printing one character surround it with single quotes
330 if (item_count == 1 && item_format == eFormatChar)
334 case eFormatEnum: // Print enum value as a signed integer when we don't get
337 if (item_byte_size <= 8)
338 s->Printf("%" PRId64,
339 DE.GetMaxS64Bitfield(&offset, item_byte_size, item_bit_size,
342 const bool is_signed = true;
343 const unsigned radix = 10;
344 offset = DumpAPInt(s, DE, offset, item_byte_size, is_signed, radix);
348 case eFormatUnsigned:
349 if (item_byte_size <= 8)
350 s->Printf("%" PRIu64,
351 DE.GetMaxU64Bitfield(&offset, item_byte_size, item_bit_size,
354 const bool is_signed = false;
355 const unsigned radix = 10;
356 offset = DumpAPInt(s, DE, offset, item_byte_size, is_signed, radix);
361 if (item_byte_size <= 8)
362 s->Printf("0%" PRIo64,
363 DE.GetMaxS64Bitfield(&offset, item_byte_size, item_bit_size,
366 const bool is_signed = false;
367 const unsigned radix = 8;
368 offset = DumpAPInt(s, DE, offset, item_byte_size, is_signed, radix);
372 case eFormatOSType: {
373 uint64_t uval64 = DE.GetMaxU64Bitfield(&offset, item_byte_size,
374 item_bit_size, item_bit_offset);
376 for (uint32_t i = 0; i < item_byte_size; ++i) {
377 uint8_t ch = (uint8_t)(uval64 >> ((item_byte_size - i - 1) * 8));
410 s->Printf("\\x%2.2x", ch);
418 case eFormatCString: {
419 const char *cstr = DE.GetCStr(&offset);
423 offset = LLDB_INVALID_OFFSET;
427 while (const char c = *cstr) {
457 s->Printf("\\x%2.2x", c);
470 DumpAddress(s->AsRawOstream(),
471 DE.GetMaxU64Bitfield(&offset, item_byte_size, item_bit_size,
476 case eFormatComplexInteger: {
477 size_t complex_int_byte_size = item_byte_size / 2;
479 if (complex_int_byte_size > 0 && complex_int_byte_size <= 8) {
480 s->Printf("%" PRIu64,
481 DE.GetMaxU64Bitfield(&offset, complex_int_byte_size, 0, 0));
482 s->Printf(" + %" PRIu64 "i",
483 DE.GetMaxU64Bitfield(&offset, complex_int_byte_size, 0, 0));
485 s->Printf("error: unsupported byte size (%" PRIu64
486 ") for complex integer format",
487 (uint64_t)item_byte_size);
493 if (sizeof(float) * 2 == item_byte_size) {
494 float f32_1 = DE.GetFloat(&offset);
495 float f32_2 = DE.GetFloat(&offset);
497 s->Printf("%g + %gi", f32_1, f32_2);
499 } else if (sizeof(double) * 2 == item_byte_size) {
500 double d64_1 = DE.GetDouble(&offset);
501 double d64_2 = DE.GetDouble(&offset);
503 s->Printf("%lg + %lgi", d64_1, d64_2);
505 } else if (sizeof(long double) * 2 == item_byte_size) {
506 long double ld64_1 = DE.GetLongDouble(&offset);
507 long double ld64_2 = DE.GetLongDouble(&offset);
508 s->Printf("%Lg + %Lgi", ld64_1, ld64_2);
511 s->Printf("error: unsupported byte size (%" PRIu64
512 ") for complex float format",
513 (uint64_t)item_byte_size);
521 case eFormatHexUppercase: {
522 bool wantsuppercase = (item_format == eFormatHexUppercase);
523 switch (item_byte_size) {
528 s->Printf(wantsuppercase ? "0x%*.*" PRIX64 : "0x%*.*" PRIx64,
529 (int)(2 * item_byte_size), (int)(2 * item_byte_size),
530 DE.GetMaxU64Bitfield(&offset, item_byte_size, item_bit_size,
534 assert(item_bit_size == 0 && item_bit_offset == 0);
535 const uint8_t *bytes =
536 (const uint8_t *)DE.GetData(&offset, item_byte_size);
540 if (DE.GetByteOrder() == eByteOrderBig) {
541 for (idx = 0; idx < item_byte_size; ++idx)
542 s->Printf(wantsuppercase ? "%2.2X" : "%2.2x", bytes[idx]);
544 for (idx = 0; idx < item_byte_size; ++idx)
545 s->Printf(wantsuppercase ? "%2.2X" : "%2.2x",
546 bytes[item_byte_size - 1 - idx]);
555 bool used_upfloat = false;
557 target_sp = exe_scope->CalculateTarget();
559 auto type_system_or_err =
560 target_sp->GetScratchTypeSystemForLanguage(eLanguageTypeC);
561 if (!type_system_or_err) {
562 llvm::consumeError(type_system_or_err.takeError());
564 auto &type_system = *type_system_or_err;
565 llvm::SmallVector<char, 256> sv;
566 // Show full precision when printing float values
567 const unsigned format_precision = 0;
568 const unsigned format_max_padding =
569 target_sp->GetMaxZeroPaddingInFloatFormat();
571 const auto &semantics =
572 type_system.GetFloatTypeSemantics(item_byte_size);
574 // Recalculate the byte size in case of a difference. This is possible
575 // when item_byte_size is 16 (128-bit), because you could get back the
576 // x87DoubleExtended semantics which has a byte size of 10 (80-bit).
577 const size_t semantics_byte_size =
578 (llvm::APFloat::getSizeInBits(semantics) + 7) / 8;
579 llvm::Optional<llvm::APInt> apint =
580 GetAPInt(DE, &offset, semantics_byte_size);
581 if (apint.hasValue()) {
582 llvm::APFloat apfloat(semantics, apint.getValue());
583 apfloat.toString(sv, format_precision, format_max_padding);
585 s->Printf("%*.*s", (int)sv.size(), (int)sv.size(), sv.data());
593 std::ostringstream ss;
594 if (item_byte_size == sizeof(float) || item_byte_size == 2) {
596 if (item_byte_size == 2) {
597 uint16_t half = DE.GetU16(&offset);
598 f = half2float(half);
600 f = DE.GetFloat(&offset);
602 ss.precision(std::numeric_limits<float>::digits10);
604 } else if (item_byte_size == sizeof(double)) {
605 ss.precision(std::numeric_limits<double>::digits10);
606 ss << DE.GetDouble(&offset);
607 } else if (item_byte_size == sizeof(long double) ||
608 item_byte_size == 10) {
609 ss.precision(std::numeric_limits<long double>::digits10);
610 ss << DE.GetLongDouble(&offset);
612 s->Printf("error: unsupported byte size (%" PRIu64
613 ") for float format",
614 (uint64_t)item_byte_size);
618 s->Printf("%s", ss.str().c_str());
622 case eFormatUnicode16:
623 s->Printf("U+%4.4x", DE.GetU16(&offset));
626 case eFormatUnicode32:
627 s->Printf("U+0x%8.8x", DE.GetU32(&offset));
630 case eFormatAddressInfo: {
631 addr_t addr = DE.GetMaxU64Bitfield(&offset, item_byte_size, item_bit_size,
633 s->Printf("0x%*.*" PRIx64, (int)(2 * item_byte_size),
634 (int)(2 * item_byte_size), addr);
636 TargetSP target_sp(exe_scope->CalculateTarget());
637 lldb_private::Address so_addr;
639 if (target_sp->GetSectionLoadList().ResolveLoadAddress(addr,
642 so_addr.Dump(s, exe_scope, Address::DumpStyleResolvedDescription,
643 Address::DumpStyleModuleWithFileAddress);
645 so_addr.SetOffset(addr);
646 so_addr.Dump(s, exe_scope,
647 Address::DumpStyleResolvedPointerDescription);
653 case eFormatHexFloat:
654 if (sizeof(float) == item_byte_size) {
655 char float_cstr[256];
656 llvm::APFloat ap_float(DE.GetFloat(&offset));
657 ap_float.convertToHexString(float_cstr, 0, false,
658 llvm::APFloat::rmNearestTiesToEven);
659 s->Printf("%s", float_cstr);
661 } else if (sizeof(double) == item_byte_size) {
662 char float_cstr[256];
663 llvm::APFloat ap_float(DE.GetDouble(&offset));
664 ap_float.convertToHexString(float_cstr, 0, false,
665 llvm::APFloat::rmNearestTiesToEven);
666 s->Printf("%s", float_cstr);
669 s->Printf("error: unsupported byte size (%" PRIu64
670 ") for hex float format",
671 (uint64_t)item_byte_size);
676 // please keep the single-item formats below in sync with
677 // FormatManager::GetSingleItemFormat if you fail to do so, users will
678 // start getting different outputs depending on internal implementation
679 // details they should not care about ||
680 case eFormatVectorOfChar: // ||
681 s->PutChar('{'); // \/
683 DumpDataExtractor(DE, s, offset, eFormatCharArray, 1, item_byte_size,
684 item_byte_size, LLDB_INVALID_ADDRESS, 0, 0);
688 case eFormatVectorOfSInt8:
691 DumpDataExtractor(DE, s, offset, eFormatDecimal, 1, item_byte_size,
692 item_byte_size, LLDB_INVALID_ADDRESS, 0, 0);
696 case eFormatVectorOfUInt8:
698 offset = DumpDataExtractor(DE, s, offset, eFormatHex, 1, item_byte_size,
699 item_byte_size, LLDB_INVALID_ADDRESS, 0, 0);
703 case eFormatVectorOfSInt16:
705 offset = DumpDataExtractor(
706 DE, s, offset, eFormatDecimal, sizeof(uint16_t),
707 item_byte_size / sizeof(uint16_t), item_byte_size / sizeof(uint16_t),
708 LLDB_INVALID_ADDRESS, 0, 0);
712 case eFormatVectorOfUInt16:
714 offset = DumpDataExtractor(DE, s, offset, eFormatHex, sizeof(uint16_t),
715 item_byte_size / sizeof(uint16_t),
716 item_byte_size / sizeof(uint16_t),
717 LLDB_INVALID_ADDRESS, 0, 0);
721 case eFormatVectorOfSInt32:
723 offset = DumpDataExtractor(
724 DE, s, offset, eFormatDecimal, sizeof(uint32_t),
725 item_byte_size / sizeof(uint32_t), item_byte_size / sizeof(uint32_t),
726 LLDB_INVALID_ADDRESS, 0, 0);
730 case eFormatVectorOfUInt32:
732 offset = DumpDataExtractor(DE, s, offset, eFormatHex, sizeof(uint32_t),
733 item_byte_size / sizeof(uint32_t),
734 item_byte_size / sizeof(uint32_t),
735 LLDB_INVALID_ADDRESS, 0, 0);
739 case eFormatVectorOfSInt64:
741 offset = DumpDataExtractor(
742 DE, s, offset, eFormatDecimal, sizeof(uint64_t),
743 item_byte_size / sizeof(uint64_t), item_byte_size / sizeof(uint64_t),
744 LLDB_INVALID_ADDRESS, 0, 0);
748 case eFormatVectorOfUInt64:
750 offset = DumpDataExtractor(DE, s, offset, eFormatHex, sizeof(uint64_t),
751 item_byte_size / sizeof(uint64_t),
752 item_byte_size / sizeof(uint64_t),
753 LLDB_INVALID_ADDRESS, 0, 0);
757 case eFormatVectorOfFloat16:
760 DumpDataExtractor(DE, s, offset, eFormatFloat, 2, item_byte_size / 2,
761 item_byte_size / 2, LLDB_INVALID_ADDRESS, 0, 0);
765 case eFormatVectorOfFloat32:
768 DumpDataExtractor(DE, s, offset, eFormatFloat, 4, item_byte_size / 4,
769 item_byte_size / 4, LLDB_INVALID_ADDRESS, 0, 0);
773 case eFormatVectorOfFloat64:
776 DumpDataExtractor(DE, s, offset, eFormatFloat, 8, item_byte_size / 8,
777 item_byte_size / 8, LLDB_INVALID_ADDRESS, 0, 0);
781 case eFormatVectorOfUInt128:
784 DumpDataExtractor(DE, s, offset, eFormatHex, 16, item_byte_size / 16,
785 item_byte_size / 16, LLDB_INVALID_ADDRESS, 0, 0);
791 if (item_format == eFormatBytesWithASCII && offset > line_start_offset) {
792 s->Printf("%*s", static_cast<int>(
793 (num_per_line - (offset - line_start_offset)) * 3 + 2),
795 DumpDataExtractor(DE, s, line_start_offset, eFormatCharPrintable, 1,
796 offset - line_start_offset, SIZE_MAX,
797 LLDB_INVALID_ADDRESS, 0, 0);
799 return offset; // Return the offset at which we ended up
802 void lldb_private::DumpHexBytes(Stream *s, const void *src, size_t src_len,
803 uint32_t bytes_per_line,
804 lldb::addr_t base_addr) {
805 DataExtractor data(src, src_len, lldb::eByteOrderLittle, 4);
806 DumpDataExtractor(data, s,
807 0, // Offset into "src"
808 lldb::eFormatBytes, // Dump as hex bytes
809 1, // Size of each item is 1 for single bytes
810 src_len, // Number of bytes
811 bytes_per_line, // Num bytes per line
812 base_addr, // Base address
813 0, 0); // Bitfield info