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) {
132 target_sp->GetArchitecture(), target_sp->GetDisassemblyFlavor(),
133 target_sp->GetDisassemblyCPU(), target_sp->GetDisassemblyFeatures(),
135 if (disassembler_sp) {
138 bool data_from_file =
true;
139 if (target_sp->GetSectionLoadList().ResolveLoadAddress(addr, so_addr)) {
140 data_from_file =
false;
142 if (target_sp->GetSectionLoadList().IsEmpty() ||
143 !target_sp->GetImages().ResolveFileAddress(addr, so_addr))
147 size_t bytes_consumed = disassembler_sp->DecodeInstructions(
148 so_addr, DE, start_offset, number_of_instructions,
false,
151 if (bytes_consumed) {
152 offset += bytes_consumed;
154 const bool show_bytes =
false;
155 const bool show_control_flow_kind =
false;
158 disassembler_sp->GetInstructionList().Dump(
159 s, show_address, show_bytes, show_control_flow_kind, &exe_ctx);
163 s->
Printf(
"invalid target");
212 if (llvm::isPrint(c)) {
216 s.
Printf(
"\\x%2.2hhx", c);
220template <
typename FloatT>
222 static_assert(std::is_floating_point<FloatT>::value,
223 "Only floating point types can be dumped.");
242static std::optional<MemoryTagMap>
254 ProcessSP process_sp = target_sp->CalculateProcess();
258 llvm::Expected<const MemoryTagManager *> tag_manager_or_err =
259 process_sp->GetMemoryTagManager();
260 if (!tag_manager_or_err) {
261 llvm::consumeError(tag_manager_or_err.takeError());
267 process_sp->GetMemoryRegions(memory_regions);
269 llvm::Expected<std::vector<MemoryTagManager::TagRange>> tagged_ranges_or_err =
270 (*tag_manager_or_err)
271 ->MakeTaggedRanges(addr, addr + length, memory_regions);
274 if (!tagged_ranges_or_err) {
275 llvm::consumeError(tagged_ranges_or_err.takeError());
278 if (tagged_ranges_or_err->empty())
283 llvm::Expected<std::vector<lldb::addr_t>> tags_or_err =
284 process_sp->ReadMemoryTags(range.GetRangeBase(), range.GetByteSize());
287 memory_tag_map.
InsertTags(range.GetRangeBase(), *tags_or_err);
289 llvm::consumeError(tags_or_err.takeError());
292 if (memory_tag_map.
Empty())
295 return memory_tag_map;
300 const std::optional<MemoryTagMap> &memory_tag_map) {
301 std::vector<std::optional<lldb::addr_t>> tags =
302 memory_tag_map->GetTags(addr, len);
308 s->
Printf(
" (tag%s:", tags.size() > 1 ?
"s" :
"");
311 for (
auto tag : tags) {
313 s->
Printf(
" 0x%" PRIx64, *tag);
323 auto type_system_or_err =
325 if (!type_system_or_err)
326 llvm::consumeError(type_system_or_err.takeError());
327 else if (
auto ts = *type_system_or_err)
328 return ts->GetFloatTypeSemantics(byte_size);
333 return llvm::APFloat::IEEEhalf();
335 return llvm::APFloat::IEEEsingle();
337 return llvm::APFloat::IEEEdouble();
339 return llvm::APFloat::Bogus();
344 lldb::Format item_format,
size_t item_byte_size,
size_t item_count,
345 size_t num_per_line, uint64_t base_addr,
346 uint32_t item_bit_size,
348 uint32_t item_bit_offset,
355 if (item_byte_size != 4 && item_byte_size != 8)
361 std::optional<MemoryTagMap> memory_tag_map;
375 for (uint32_t count = 0; DE.
ValidOffset(offset) && count < item_count;
379 if ((count % num_per_line) == 0) {
383 offset > line_start_offset) {
386 (num_per_line - (offset - line_start_offset)) * 3 + 2),
389 offset - line_start_offset, SIZE_MAX,
394 size_t line_len = offset - line_start_offset;
404 s->
Printf(
"0x%8.8" PRIx64
": ",
405 (uint64_t)(base_addr +
408 line_start_offset = offset;
415 switch (item_format) {
417 if (item_byte_size <= 8)
419 item_bit_size, item_bit_offset)
423 s->
Printf(
"error: unsupported byte size (%" PRIu64
424 ") for boolean format",
425 (uint64_t)item_byte_size);
431 if (item_byte_size <= 8) {
433 item_bit_size, item_bit_offset);
436 std::string binary_value(64,
'0');
437 std::bitset<64>
bits(uval64);
438 for (uint32_t i = 0; i < 64; ++i)
440 binary_value[64 - 1 - i] =
'1';
441 if (item_bit_size > 0)
442 s->
Printf(
"0b%s", binary_value.c_str() + 64 - item_bit_size);
443 else if (item_byte_size > 0 && item_byte_size <= 8)
444 s->
Printf(
"0b%s", binary_value.c_str() + 64 - item_byte_size * 8);
446 const bool is_signed =
false;
447 const unsigned radix = 2;
448 offset =
DumpAPInt(s, DE, offset, item_byte_size, is_signed, radix);
454 for (uint32_t i = 0; i < item_byte_size; ++i) {
460 if (item_byte_size > 1)
468 if (item_byte_size > 8) {
469 s->
Printf(
"error: unsupported byte size (%" PRIu64
") for char format",
470 (uint64_t)item_byte_size);
479 item_bit_size, item_bit_offset);
480 if (llvm::isPrint(ch))
481 s->
Printf(
"%c", (
char)ch);
484 if (item_byte_size == 1)
485 s->
Printf(
"\\x%2.2x", (uint8_t)ch);
487 s->
Printf(
"%" PRIu64, ch);
501 if (item_byte_size <= 8)
506 const bool is_signed =
true;
507 const unsigned radix = 10;
508 offset =
DumpAPInt(s, DE, offset, item_byte_size, is_signed, radix);
513 if (item_byte_size <= 8)
518 const bool is_signed =
false;
519 const unsigned radix = 10;
520 offset =
DumpAPInt(s, DE, offset, item_byte_size, is_signed, radix);
525 if (item_byte_size <= 8)
530 const bool is_signed =
false;
531 const unsigned radix = 8;
532 offset =
DumpAPInt(s, DE, offset, item_byte_size, is_signed, radix);
538 item_bit_size, item_bit_offset);
540 for (uint32_t i = 0; i < item_byte_size; ++i) {
541 uint8_t ch = (uint8_t)(uval64 >> ((item_byte_size - i - 1) * 8));
548 const char *cstr = DE.
GetCStr(&offset);
556 while (
const char c = *cstr) {
573 size_t complex_int_byte_size = item_byte_size / 2;
575 if (complex_int_byte_size > 0 && complex_int_byte_size <= 8) {
578 s->
Printf(
" + %" PRIu64
"i",
581 s->
Printf(
"error: unsupported byte size (%" PRIu64
582 ") for complex integer format",
583 (uint64_t)item_byte_size);
589 if (
sizeof(
float) * 2 == item_byte_size) {
593 s->
Printf(
"%g + %gi", f32_1, f32_2);
595 }
else if (
sizeof(
double) * 2 == item_byte_size) {
599 s->
Printf(
"%lg + %lgi", d64_1, d64_2);
601 }
else if (
sizeof(
long double) * 2 == item_byte_size) {
604 s->
Printf(
"%Lg + %Lgi", ld64_1, ld64_2);
607 s->
Printf(
"error: unsupported byte size (%" PRIu64
608 ") for complex float format",
609 (uint64_t)item_byte_size);
619 switch (item_byte_size) {
626 s->
Printf(wantsuppercase ?
"0x%*.*" PRIX64 :
"0x%*.*" PRIx64,
627 (
int)(2 * item_byte_size), (
int)(2 * item_byte_size),
631 s->
Printf(wantsuppercase ?
"0x%" PRIX64 :
"0x%" PRIx64,
637 assert(item_bit_size == 0 && item_bit_offset == 0);
638 const uint8_t *bytes =
639 (
const uint8_t *)DE.
GetData(&offset, item_byte_size);
644 for (idx = 0; idx < item_byte_size; ++idx)
645 s->
Printf(wantsuppercase ?
"%2.2X" :
"%2.2x", bytes[idx]);
647 for (idx = 0; idx < item_byte_size; ++idx)
648 s->
Printf(wantsuppercase ?
"%2.2X" :
"%2.2x",
649 bytes[item_byte_size - 1 - idx]);
661 std::optional<unsigned> format_max_padding;
663 format_max_padding = target_sp->GetMaxZeroPaddingInFloatFormat();
666 const unsigned format_precision = 0;
668 const llvm::fltSemantics &semantics =
674 const size_t semantics_byte_size =
675 (llvm::APFloat::getSizeInBits(semantics) + 7) / 8;
676 std::optional<llvm::APInt> apint =
677 GetAPInt(DE, &offset, semantics_byte_size);
679 llvm::APFloat apfloat(semantics, *apint);
680 llvm::SmallVector<char, 256> sv;
681 if (format_max_padding)
682 apfloat.toString(sv, format_precision, *format_max_padding);
684 apfloat.toString(sv, format_precision);
687 s->
Format(
"error: unsupported byte size ({0}) for float format",
704 s->
Printf(
"0x%*.*" PRIx64, (
int)(2 * item_byte_size),
705 (
int)(2 * item_byte_size), addr);
710 if (target_sp->GetSectionLoadList().ResolveLoadAddress(addr,
717 so_addr.
Dump(s, exe_scope,
720 if (
ABISP abi_sp = process_sp->GetABI()) {
721 addr_t addr_fixed = abi_sp->FixCodeAddress(addr);
722 if (target_sp->GetSectionLoadList().ResolveLoadAddress(
723 addr_fixed, so_addr)) {
725 s->
Printf(
"(0x%*.*" PRIx64
")", (
int)(2 * item_byte_size),
726 (
int)(2 * item_byte_size), addr_fixed);
728 so_addr.
Dump(s, exe_scope,
740 if (
sizeof(
float) == item_byte_size) {
741 char float_cstr[256];
742 llvm::APFloat ap_float(DE.
GetFloat(&offset));
743 ap_float.convertToHexString(float_cstr, 0,
false,
744 llvm::APFloat::rmNearestTiesToEven);
745 s->
Printf(
"%s", float_cstr);
747 }
else if (
sizeof(
double) == item_byte_size) {
748 char float_cstr[256];
749 llvm::APFloat ap_float(DE.
GetDouble(&offset));
750 ap_float.convertToHexString(float_cstr, 0,
false,
751 llvm::APFloat::rmNearestTiesToEven);
752 s->
Printf(
"%s", float_cstr);
755 s->
Printf(
"error: unsupported byte size (%" PRIu64
756 ") for hex float format",
757 (uint64_t)item_byte_size);
793 item_byte_size /
sizeof(uint16_t), item_byte_size /
sizeof(uint16_t),
801 item_byte_size /
sizeof(uint16_t),
802 item_byte_size /
sizeof(uint16_t),
811 item_byte_size /
sizeof(uint32_t), item_byte_size /
sizeof(uint32_t),
819 item_byte_size /
sizeof(uint32_t),
820 item_byte_size /
sizeof(uint32_t),
829 item_byte_size /
sizeof(uint64_t), item_byte_size /
sizeof(uint64_t),
837 item_byte_size /
sizeof(uint64_t),
838 item_byte_size /
sizeof(uint64_t),
880 if (offset > line_start_offset) {
884 (num_per_line - (offset - line_start_offset)) * 3 + 2),
887 offset - line_start_offset, SIZE_MAX,
892 size_t line_len = offset - line_start_offset;
893 lldb::addr_t line_base = base_addr + (offset - start_offset - line_len) /
903 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 *cpu, const char *features, 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