30#include "llvm/ADT/APFloat.h"
31#include "llvm/ADT/APInt.h"
32#include "llvm/ADT/ArrayRef.h"
33#include "llvm/ADT/SmallVector.h"
51#define NON_PRINTABLE_CHAR '.'
59 llvm::SmallVector<uint64_t, 2> uint64_array;
64 while (bytes_left > 0) {
65 if (bytes_left >= 8) {
66 u64 = data.
GetU64(offset_ptr);
69 u64 = data.
GetMaxU64(offset_ptr, (uint32_t)bytes_left);
72 uint64_array.push_back(u64);
74 return llvm::APInt(byte_size * 8, llvm::ArrayRef<uint64_t>(uint64_array));
78 while (bytes_left > 0) {
79 if (bytes_left >= 8) {
81 temp_offset = be_offset;
82 u64 = data.
GetU64(&temp_offset);
85 be_offset -= bytes_left;
86 temp_offset = be_offset;
87 u64 = data.
GetMaxU64(&temp_offset, (uint32_t)bytes_left);
90 uint64_array.push_back(u64);
92 *offset_ptr += byte_size;
93 return llvm::APInt(byte_size * 8, llvm::ArrayRef<uint64_t>(uint64_array));
100 bool is_signed,
unsigned radix) {
101 std::optional<llvm::APInt> apint =
GetAPInt(data, &offset, byte_size);
103 std::string apint_str =
toString(*apint, radix, is_signed);
114 s->
Write(apint_str.c_str(), apint_str.size());
124 size_t number_of_instructions) {
133 target_sp->GetDisassemblyFlavor(),
nullptr));
134 if (disassembler_sp) {
137 bool data_from_file =
true;
138 if (target_sp->GetSectionLoadList().ResolveLoadAddress(addr, so_addr)) {
139 data_from_file =
false;
141 if (target_sp->GetSectionLoadList().IsEmpty() ||
142 !target_sp->GetImages().ResolveFileAddress(addr, so_addr))
146 size_t bytes_consumed = disassembler_sp->DecodeInstructions(
147 so_addr, DE, start_offset, number_of_instructions,
false,
150 if (bytes_consumed) {
151 offset += bytes_consumed;
153 const bool show_bytes =
false;
154 const bool show_control_flow_kind =
false;
157 disassembler_sp->GetInstructionList().Dump(
158 s, show_address, show_bytes, show_control_flow_kind, &exe_ctx);
162 s->
Printf(
"invalid target");
211 if (llvm::isPrint(c)) {
215 s.
Printf(
"\\x%2.2hhx", c);
219template <
typename FloatT>
221 static_assert(std::is_floating_point<FloatT>::value,
222 "Only floating point types can be dumped.");
241static std::optional<MemoryTagMap>
253 ProcessSP process_sp = target_sp->CalculateProcess();
257 llvm::Expected<const MemoryTagManager *> tag_manager_or_err =
258 process_sp->GetMemoryTagManager();
259 if (!tag_manager_or_err) {
260 llvm::consumeError(tag_manager_or_err.takeError());
266 process_sp->GetMemoryRegions(memory_regions);
268 llvm::Expected<std::vector<MemoryTagManager::TagRange>> tagged_ranges_or_err =
269 (*tag_manager_or_err)
270 ->MakeTaggedRanges(addr, addr + length, memory_regions);
273 if (!tagged_ranges_or_err) {
274 llvm::consumeError(tagged_ranges_or_err.takeError());
277 if (tagged_ranges_or_err->empty())
282 llvm::Expected<std::vector<lldb::addr_t>> tags_or_err =
283 process_sp->ReadMemoryTags(range.GetRangeBase(), range.GetByteSize());
286 memory_tag_map.
InsertTags(range.GetRangeBase(), *tags_or_err);
288 llvm::consumeError(tags_or_err.takeError());
291 if (memory_tag_map.
Empty())
294 return memory_tag_map;
299 const std::optional<MemoryTagMap> &memory_tag_map) {
300 std::vector<std::optional<lldb::addr_t>> tags =
301 memory_tag_map->GetTags(addr, len);
307 s->
Printf(
" (tag%s:", tags.size() > 1 ?
"s" :
"");
310 for (
auto tag : tags) {
312 s->
Printf(
" 0x%" PRIx64, *tag);
322 auto type_system_or_err =
324 if (!type_system_or_err)
325 llvm::consumeError(type_system_or_err.takeError());
326 else if (
auto ts = *type_system_or_err)
327 return ts->GetFloatTypeSemantics(byte_size);
332 return llvm::APFloat::IEEEhalf();
334 return llvm::APFloat::IEEEsingle();
336 return llvm::APFloat::IEEEdouble();
338 return llvm::APFloat::Bogus();
343 lldb::Format item_format,
size_t item_byte_size,
size_t item_count,
344 size_t num_per_line, uint64_t base_addr,
345 uint32_t item_bit_size,
347 uint32_t item_bit_offset,
354 if (item_byte_size != 4 && item_byte_size != 8)
360 std::optional<MemoryTagMap> memory_tag_map;
374 for (uint32_t count = 0; DE.
ValidOffset(offset) && count < item_count;
378 if ((count % num_per_line) == 0) {
382 offset > line_start_offset) {
385 (num_per_line - (offset - line_start_offset)) * 3 + 2),
388 offset - line_start_offset, SIZE_MAX,
393 size_t line_len = offset - line_start_offset;
403 s->
Printf(
"0x%8.8" PRIx64
": ",
404 (uint64_t)(base_addr +
407 line_start_offset = offset;
414 switch (item_format) {
416 if (item_byte_size <= 8)
418 item_bit_size, item_bit_offset)
422 s->
Printf(
"error: unsupported byte size (%" PRIu64
423 ") for boolean format",
424 (uint64_t)item_byte_size);
430 if (item_byte_size <= 8) {
432 item_bit_size, item_bit_offset);
435 std::string binary_value(64,
'0');
436 std::bitset<64>
bits(uval64);
437 for (uint32_t i = 0; i < 64; ++i)
439 binary_value[64 - 1 - i] =
'1';
440 if (item_bit_size > 0)
441 s->
Printf(
"0b%s", binary_value.c_str() + 64 - item_bit_size);
442 else if (item_byte_size > 0 && item_byte_size <= 8)
443 s->
Printf(
"0b%s", binary_value.c_str() + 64 - item_byte_size * 8);
445 const bool is_signed =
false;
446 const unsigned radix = 2;
447 offset =
DumpAPInt(s, DE, offset, item_byte_size, is_signed, radix);
453 for (uint32_t i = 0; i < item_byte_size; ++i) {
459 if (item_byte_size > 1)
467 if (item_byte_size > 8) {
468 s->
Printf(
"error: unsupported byte size (%" PRIu64
") for char format",
469 (uint64_t)item_byte_size);
478 item_bit_size, item_bit_offset);
479 if (llvm::isPrint(ch))
480 s->
Printf(
"%c", (
char)ch);
483 if (item_byte_size == 1)
484 s->
Printf(
"\\x%2.2x", (uint8_t)ch);
486 s->
Printf(
"%" PRIu64, ch);
500 if (item_byte_size <= 8)
505 const bool is_signed =
true;
506 const unsigned radix = 10;
507 offset =
DumpAPInt(s, DE, offset, item_byte_size, is_signed, radix);
512 if (item_byte_size <= 8)
517 const bool is_signed =
false;
518 const unsigned radix = 10;
519 offset =
DumpAPInt(s, DE, offset, item_byte_size, is_signed, radix);
524 if (item_byte_size <= 8)
529 const bool is_signed =
false;
530 const unsigned radix = 8;
531 offset =
DumpAPInt(s, DE, offset, item_byte_size, is_signed, radix);
537 item_bit_size, item_bit_offset);
539 for (uint32_t i = 0; i < item_byte_size; ++i) {
540 uint8_t ch = (uint8_t)(uval64 >> ((item_byte_size - i - 1) * 8));
547 const char *cstr = DE.
GetCStr(&offset);
555 while (
const char c = *cstr) {
572 size_t complex_int_byte_size = item_byte_size / 2;
574 if (complex_int_byte_size > 0 && complex_int_byte_size <= 8) {
577 s->
Printf(
" + %" PRIu64
"i",
580 s->
Printf(
"error: unsupported byte size (%" PRIu64
581 ") for complex integer format",
582 (uint64_t)item_byte_size);
588 if (
sizeof(
float) * 2 == item_byte_size) {
592 s->
Printf(
"%g + %gi", f32_1, f32_2);
594 }
else if (
sizeof(
double) * 2 == item_byte_size) {
598 s->
Printf(
"%lg + %lgi", d64_1, d64_2);
600 }
else if (
sizeof(
long double) * 2 == item_byte_size) {
603 s->
Printf(
"%Lg + %Lgi", ld64_1, ld64_2);
606 s->
Printf(
"error: unsupported byte size (%" PRIu64
607 ") for complex float format",
608 (uint64_t)item_byte_size);
618 switch (item_byte_size) {
625 s->
Printf(wantsuppercase ?
"0x%*.*" PRIX64 :
"0x%*.*" PRIx64,
626 (
int)(2 * item_byte_size), (
int)(2 * item_byte_size),
630 s->
Printf(wantsuppercase ?
"0x%" PRIX64 :
"0x%" PRIx64,
636 assert(item_bit_size == 0 && item_bit_offset == 0);
637 const uint8_t *bytes =
638 (
const uint8_t *)DE.
GetData(&offset, item_byte_size);
643 for (idx = 0; idx < item_byte_size; ++idx)
644 s->
Printf(wantsuppercase ?
"%2.2X" :
"%2.2x", bytes[idx]);
646 for (idx = 0; idx < item_byte_size; ++idx)
647 s->
Printf(wantsuppercase ?
"%2.2X" :
"%2.2x",
648 bytes[item_byte_size - 1 - idx]);
660 std::optional<unsigned> format_max_padding;
662 format_max_padding = target_sp->GetMaxZeroPaddingInFloatFormat();
665 const unsigned format_precision = 0;
667 const llvm::fltSemantics &semantics =
673 const size_t semantics_byte_size =
674 (llvm::APFloat::getSizeInBits(semantics) + 7) / 8;
675 std::optional<llvm::APInt> apint =
676 GetAPInt(DE, &offset, semantics_byte_size);
678 llvm::APFloat apfloat(semantics, *apint);
679 llvm::SmallVector<char, 256> sv;
680 if (format_max_padding)
681 apfloat.toString(sv, format_precision, *format_max_padding);
683 apfloat.toString(sv, format_precision);
686 s->
Format(
"error: unsupported byte size ({0}) for float format",
703 s->
Printf(
"0x%*.*" PRIx64, (
int)(2 * item_byte_size),
704 (
int)(2 * item_byte_size), addr);
709 if (target_sp->GetSectionLoadList().ResolveLoadAddress(addr,
716 so_addr.
Dump(s, exe_scope,
719 if (
ABISP abi_sp = process_sp->GetABI()) {
720 addr_t addr_fixed = abi_sp->FixCodeAddress(addr);
721 if (target_sp->GetSectionLoadList().ResolveLoadAddress(
722 addr_fixed, so_addr)) {
724 s->
Printf(
"(0x%*.*" PRIx64
")", (
int)(2 * item_byte_size),
725 (
int)(2 * item_byte_size), addr_fixed);
727 so_addr.
Dump(s, exe_scope,
739 if (
sizeof(
float) == item_byte_size) {
740 char float_cstr[256];
741 llvm::APFloat ap_float(DE.
GetFloat(&offset));
742 ap_float.convertToHexString(float_cstr, 0,
false,
743 llvm::APFloat::rmNearestTiesToEven);
744 s->
Printf(
"%s", float_cstr);
746 }
else if (
sizeof(
double) == item_byte_size) {
747 char float_cstr[256];
748 llvm::APFloat ap_float(DE.
GetDouble(&offset));
749 ap_float.convertToHexString(float_cstr, 0,
false,
750 llvm::APFloat::rmNearestTiesToEven);
751 s->
Printf(
"%s", float_cstr);
754 s->
Printf(
"error: unsupported byte size (%" PRIu64
755 ") for hex float format",
756 (uint64_t)item_byte_size);
792 item_byte_size /
sizeof(uint16_t), item_byte_size /
sizeof(uint16_t),
800 item_byte_size /
sizeof(uint16_t),
801 item_byte_size /
sizeof(uint16_t),
810 item_byte_size /
sizeof(uint32_t), item_byte_size /
sizeof(uint32_t),
818 item_byte_size /
sizeof(uint32_t),
819 item_byte_size /
sizeof(uint32_t),
828 item_byte_size /
sizeof(uint64_t), item_byte_size /
sizeof(uint64_t),
836 item_byte_size /
sizeof(uint64_t),
837 item_byte_size /
sizeof(uint64_t),
879 if (offset > line_start_offset) {
883 (num_per_line - (offset - line_start_offset)) * 3 + 2),
886 offset - line_start_offset, SIZE_MAX,
891 size_t line_len = offset - line_start_offset;
892 lldb::addr_t line_base = base_addr + (offset - start_offset - line_len) /
902 uint32_t bytes_per_line,
A section + offset based address class.
void SetRawAddress(lldb::addr_t addr)
@ DumpStyleModuleWithFileAddress
Display as the file address with the module name prepended (if any).
@ DumpStyleResolvedDescription
Display the details about what an address resolves to.
@ DumpStyleResolvedPointerDescription
Dereference a pointer at the current address and then lookup the dereferenced address using DumpStyle...
bool Dump(Stream *s, ExecutionContextScope *exe_scope, DumpStyle style, DumpStyle fallback_style=DumpStyleInvalid, uint32_t addr_byte_size=UINT32_MAX, bool all_ranges=false, std::optional< Stream::HighlightSettings > settings=std::nullopt) const
Dump a description of this object to a Stream.
bool SetOffset(lldb::addr_t offset)
Set accessor for the offset.
static lldb::DisassemblerSP FindPlugin(const ArchSpec &arch, const char *flavor, const char *plugin_name)
"lldb/Target/ExecutionContextScope.h" Inherit from this if your object can reconstruct its execution ...
virtual void CalculateExecutionContext(ExecutionContext &exe_ctx)=0
Reconstruct the object's execution context into sc.
virtual lldb::ProcessSP CalculateProcess()=0
virtual lldb::TargetSP CalculateTarget()=0
"lldb/Target/ExecutionContext.h" A class that contains an execution context.
MemoryTagMap provides a way to give a sparse read result when reading memory tags for a range.
void InsertTags(lldb::addr_t addr, const std::vector< lldb::addr_t > tags)
Insert tags into the map starting from addr.
A stream class that can stream formatted output to a file.
void Format(const char *format, Args &&... args)
uint32_t GetAddressByteSize() const
Get the address size in bytes.
size_t Write(const void *src, size_t src_len)
Output character bytes to the stream.
llvm::raw_ostream & AsRawOstream()
Returns a raw_ostream that forwards the data to this Stream object.
size_t Printf(const char *format,...) __attribute__((format(printf
Output printf formatted output to the stream.
size_t PutCString(llvm::StringRef cstr)
Output a C string to the stream.
size_t EOL()
Output and End of Line character to the stream.
bool ShowHexVariableValuesWithLeadingZeroes() const
static TargetProperties & GetGlobalProperties()
#define LLDB_INVALID_ADDRESS
#define LLDB_INVALID_OFFSET
A class that represents a running process on the host machine.
void DumpHexBytes(Stream *s, const void *src, size_t src_len, uint32_t bytes_per_line, lldb::addr_t base_addr)
void DumpAddress(llvm::raw_ostream &s, uint64_t addr, uint32_t addr_size, const char *prefix=nullptr, const char *suffix=nullptr)
Output an address value to this stream.
lldb::offset_t DumpDataExtractor(const DataExtractor &DE, Stream *s, lldb::offset_t offset, lldb::Format item_format, size_t item_byte_size, size_t item_count, size_t num_per_line, uint64_t base_addr, uint32_t item_bit_size, uint32_t item_bit_offset, ExecutionContextScope *exe_scope=nullptr, bool show_memory_tags=false)
Dumps item_count objects into the stream s.
const char * toString(AppleArm64ExceptionClass EC)
static uint32_t bits(const uint32_t val, const uint32_t msbit, const uint32_t lsbit)
std::shared_ptr< lldb_private::ABI > ABISP
Format
Display format definitions.
@ eFormatCString
NULL terminated C strings.
@ eFormatCharArray
Print characters with no single quotes, used for character arrays that can contain non printable char...
@ eFormatInstruction
Disassemble an opcode.
@ eFormatComplex
Floating point complex type.
@ eFormatHexFloat
ISO C99 hex float string.
@ eFormatOSType
OS character codes encoded into an integer 'PICT' 'text' etc...
@ eFormatAddressInfo
Describe what an address points to (func + offset.
@ eFormatCharPrintable
Only printable characters, '.' if not printable.
@ eFormatComplexInteger
Integer complex type.
@ eLanguageTypeC
Non-standardized C, such as K&R.
std::shared_ptr< lldb_private::Process > ProcessSP
std::shared_ptr< lldb_private::Disassembler > DisassemblerSP
ByteOrder
Byte ordering definitions.
std::shared_ptr< lldb_private::Target > TargetSP