forked from OSchip/llvm-project
Isolate Target-specific functionality of DataExtractor.
In an effort to move the various DataBuffer / DataExtractor classes from Core -> Utility, we have to separate the low-level functionality from the higher level functionality. Only a few functions required anything other than reading/writing raw bytes, so those functions are separated out into a more appropriate area. Specifically, Dump() and DumpHexBytes() are moved into free functions in Core/DumpDataExtractor.cpp, and GetGNUEHPointer is moved into a static function in the only file that it's referenced from. Differential Revision: https://reviews.llvm.org/D30560 llvm-svn: 296910
This commit is contained in:
parent
6f9e690199
commit
29cb868aa4
|
@ -43,8 +43,6 @@ public:
|
|||
//------------------------------------------------------------------
|
||||
/// @typedef DataExtractor::Type
|
||||
/// @brief Type enumerations used in the dump routines.
|
||||
/// @see DataExtractor::Dump()
|
||||
/// @see DataExtractor::DumpRawHexBytes()
|
||||
//------------------------------------------------------------------
|
||||
typedef enum {
|
||||
TypeUInt8, ///< Format output as unsigned 8 bit integers
|
||||
|
@ -57,12 +55,6 @@ public:
|
|||
TypeSLEB128 ///< Format output as SLEB128 numbers
|
||||
} Type;
|
||||
|
||||
static void DumpHexBytes(Stream *s, const void *src, size_t src_len,
|
||||
uint32_t bytes_per_line,
|
||||
lldb::addr_t base_addr); // Pass LLDB_INVALID_ADDRESS
|
||||
// to not show address at
|
||||
// start of line
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Default constructor.
|
||||
///
|
||||
|
@ -172,7 +164,9 @@ public:
|
|||
/// reference count on the data will be decremented, and if zero,
|
||||
/// the data will be freed.
|
||||
//------------------------------------------------------------------
|
||||
~DataExtractor();
|
||||
virtual ~DataExtractor();
|
||||
|
||||
uint32_t getTargetByteSize() const { return m_target_byte_size; }
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Clears the object state.
|
||||
|
@ -224,73 +218,6 @@ public:
|
|||
uint32_t num_per_line, Type type,
|
||||
const char *type_format = nullptr) const;
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Dumps \a item_count objects into the stream \a s.
|
||||
///
|
||||
/// Dumps \a item_count objects using \a item_format, each of which
|
||||
/// are \a item_byte_size bytes long starting at offset \a offset
|
||||
/// bytes into the contained data, into the stream \a s. \a
|
||||
/// num_per_line objects will be dumped on each line before a new
|
||||
/// line will be output. If \a base_addr is a valid address, then
|
||||
/// each new line of output will be preceded by the address value
|
||||
/// plus appropriate offset, and a colon and space. Bitfield values
|
||||
/// can be dumped by calling this function multiple times with the
|
||||
/// same start offset, format and size, yet differing \a
|
||||
/// item_bit_size and \a item_bit_offset values.
|
||||
///
|
||||
/// @param[in] s
|
||||
/// The stream to dump the output to. This value can not be nullptr.
|
||||
///
|
||||
/// @param[in] offset
|
||||
/// The offset into the data at which to start dumping.
|
||||
///
|
||||
/// @param[in] item_format
|
||||
/// The format to use when dumping each item.
|
||||
///
|
||||
/// @param[in] item_byte_size
|
||||
/// The byte size of each item.
|
||||
///
|
||||
/// @param[in] item_count
|
||||
/// The number of items to dump.
|
||||
///
|
||||
/// @param[in] num_per_line
|
||||
/// The number of items to display on each line.
|
||||
///
|
||||
/// @param[in] base_addr
|
||||
/// The base address that gets added to the offset displayed on
|
||||
/// each line if the value is valid. Is \a base_addr is
|
||||
/// LLDB_INVALID_ADDRESS then no address values will be prepended
|
||||
/// to any lines.
|
||||
///
|
||||
/// @param[in] item_bit_size
|
||||
/// If the value to display is a bitfield, this value should
|
||||
/// be the number of bits that the bitfield item has within the
|
||||
/// item's byte size value. This function will need to be called
|
||||
/// multiple times with identical \a offset and \a item_byte_size
|
||||
/// values in order to display multiple bitfield values that
|
||||
/// exist within the same integer value. If the items being
|
||||
/// displayed are not bitfields, this value should be zero.
|
||||
///
|
||||
/// @param[in] item_bit_offset
|
||||
/// If the value to display is a bitfield, this value should
|
||||
/// be the offset in bits, or shift right amount, that the
|
||||
/// bitfield item occupies within the item's byte size value.
|
||||
/// This function will need to be called multiple times with
|
||||
/// identical \a offset and \a item_byte_size values in order
|
||||
/// to display multiple bitfield values that exist within the
|
||||
/// same integer value. If the items being displayed are not
|
||||
/// bitfields, this value should be zero.
|
||||
///
|
||||
/// @return
|
||||
/// The offset at which dumping ended.
|
||||
//------------------------------------------------------------------
|
||||
lldb::offset_t Dump(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) const;
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Dump a UUID value at \a offset.
|
||||
///
|
||||
|
@ -572,38 +499,6 @@ public:
|
|||
|
||||
long double GetLongDouble(lldb::offset_t *offset_ptr) const;
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Extract a GNU encoded pointer value from \a *offset_ptr.
|
||||
///
|
||||
/// @param[in,out] offset_ptr
|
||||
/// A pointer to an offset within the data that will be advanced
|
||||
/// by the appropriate number of bytes if the value is extracted
|
||||
/// correctly. If the offset is out of bounds or there are not
|
||||
/// enough bytes to extract this value, the offset will be left
|
||||
/// unmodified.
|
||||
///
|
||||
/// @param[in] eh_ptr_enc
|
||||
/// The GNU pointer encoding type.
|
||||
///
|
||||
/// @param[in] pc_rel_addr
|
||||
/// The PC relative address to use when the encoding is
|
||||
/// \c DW_GNU_EH_PE_pcrel.
|
||||
///
|
||||
/// @param[in] text_addr
|
||||
/// The text (code) relative address to use when the encoding is
|
||||
/// \c DW_GNU_EH_PE_textrel.
|
||||
///
|
||||
/// @param[in] data_addr
|
||||
/// The data relative address to use when the encoding is
|
||||
/// \c DW_GNU_EH_PE_datarel.
|
||||
///
|
||||
/// @return
|
||||
/// The extracted GNU encoded pointer value.
|
||||
//------------------------------------------------------------------
|
||||
uint64_t GetGNUEHPointer(lldb::offset_t *offset_ptr, uint32_t eh_ptr_enc,
|
||||
lldb::addr_t pc_rel_addr, lldb::addr_t text_addr,
|
||||
lldb::addr_t data_addr);
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Extract an integer of size \a byte_size from \a *offset_ptr.
|
||||
///
|
||||
|
|
|
@ -0,0 +1,88 @@
|
|||
//===-- DumpDataExtractor.h -------------------------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLDB_CORE_DUMPDATAEXTRACTOR_H
|
||||
#define LLDB_CORE_DUMPDATAEXTRACTOR_H
|
||||
|
||||
#include "lldb/lldb-types.h"
|
||||
|
||||
namespace lldb_private {
|
||||
class DataExtractor;
|
||||
class ExecutionContextScope;
|
||||
class Stream;
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Dumps \a item_count objects into the stream \a s.
|
||||
///
|
||||
/// Dumps \a item_count objects using \a item_format, each of which
|
||||
/// are \a item_byte_size bytes long starting at offset \a offset
|
||||
/// bytes into the contained data, into the stream \a s. \a
|
||||
/// num_per_line objects will be dumped on each line before a new
|
||||
/// line will be output. If \a base_addr is a valid address, then
|
||||
/// each new line of output will be preceded by the address value
|
||||
/// plus appropriate offset, and a colon and space. Bitfield values
|
||||
/// can be dumped by calling this function multiple times with the
|
||||
/// same start offset, format and size, yet differing \a
|
||||
/// item_bit_size and \a item_bit_offset values.
|
||||
///
|
||||
/// @param[in] s
|
||||
/// The stream to dump the output to. This value can not be nullptr.
|
||||
///
|
||||
/// @param[in] offset
|
||||
/// The offset into the data at which to start dumping.
|
||||
///
|
||||
/// @param[in] item_format
|
||||
/// The format to use when dumping each item.
|
||||
///
|
||||
/// @param[in] item_byte_size
|
||||
/// The byte size of each item.
|
||||
///
|
||||
/// @param[in] item_count
|
||||
/// The number of items to dump.
|
||||
///
|
||||
/// @param[in] num_per_line
|
||||
/// The number of items to display on each line.
|
||||
///
|
||||
/// @param[in] base_addr
|
||||
/// The base address that gets added to the offset displayed on
|
||||
/// each line if the value is valid. Is \a base_addr is
|
||||
/// LLDB_INVALID_ADDRESS then no address values will be prepended
|
||||
/// to any lines.
|
||||
///
|
||||
/// @param[in] item_bit_size
|
||||
/// If the value to display is a bitfield, this value should
|
||||
/// be the number of bits that the bitfield item has within the
|
||||
/// item's byte size value. This function will need to be called
|
||||
/// multiple times with identical \a offset and \a item_byte_size
|
||||
/// values in order to display multiple bitfield values that
|
||||
/// exist within the same integer value. If the items being
|
||||
/// displayed are not bitfields, this value should be zero.
|
||||
///
|
||||
/// @param[in] item_bit_offset
|
||||
/// If the value to display is a bitfield, this value should
|
||||
/// be the offset in bits, or shift right amount, that the
|
||||
/// bitfield item occupies within the item's byte size value.
|
||||
/// This function will need to be called multiple times with
|
||||
/// identical \a offset and \a item_byte_size values in order
|
||||
/// to display multiple bitfield values that exist within the
|
||||
/// same integer value. If the items being displayed are not
|
||||
/// bitfields, this value should be zero.
|
||||
///
|
||||
/// @return
|
||||
/// The offset at which dumping ended.
|
||||
//------------------------------------------------------------------
|
||||
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);
|
||||
}
|
||||
|
||||
#endif
|
|
@ -23,6 +23,8 @@
|
|||
|
||||
namespace lldb_private {
|
||||
|
||||
class DataExtractor;
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// A class that can carry around a clang ASTContext and a opaque clang
|
||||
// QualType. A clang::QualType can be easily reconstructed from an
|
||||
|
|
|
@ -14,7 +14,6 @@
|
|||
#include <mutex>
|
||||
|
||||
#include "lldb/Core/AddressRange.h"
|
||||
#include "lldb/Core/DataExtractor.h"
|
||||
#include "lldb/Utility/Flags.h"
|
||||
|
||||
#include "lldb/Core/RangeMap.h"
|
||||
|
|
|
@ -23,7 +23,6 @@
|
|||
#include <set>
|
||||
|
||||
namespace lldb_private {
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// CompilerContext allows an array of these items to be passed to
|
||||
// perform detailed lookups in SymbolVendor and SymbolFile functions.
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
|
||||
#include "lldb/Core/DataBufferHeap.h"
|
||||
#include "lldb/Core/DataExtractor.h"
|
||||
#include "lldb/Core/DumpDataExtractor.h"
|
||||
#include "lldb/Utility/Log.h"
|
||||
#include "lldb/Utility/Stream.h"
|
||||
|
||||
|
@ -347,7 +348,7 @@ bool SBData::GetDescription(lldb::SBStream &description,
|
|||
Stream &strm = description.ref();
|
||||
|
||||
if (m_opaque_sp) {
|
||||
m_opaque_sp->Dump(&strm, 0, lldb::eFormatBytesWithASCII, 1,
|
||||
DumpDataExtractor(*m_opaque_sp, &strm, 0, lldb::eFormatBytesWithASCII, 1,
|
||||
m_opaque_sp->GetByteSize(), 16, base_addr, 0, 0);
|
||||
} else
|
||||
strm.PutCString("No value");
|
||||
|
|
|
@ -18,8 +18,8 @@
|
|||
#include "CommandObjectMemory.h"
|
||||
#include "Plugins/ExpressionParser/Clang/ClangPersistentVariables.h"
|
||||
#include "lldb/Core/DataBufferHeap.h"
|
||||
#include "lldb/Core/DataExtractor.h"
|
||||
#include "lldb/Core/Debugger.h"
|
||||
#include "lldb/Core/DumpDataExtractor.h"
|
||||
#include "lldb/Core/Module.h"
|
||||
#include "lldb/Core/Section.h"
|
||||
#include "lldb/Core/ValueObjectMemory.h"
|
||||
|
@ -861,10 +861,10 @@ protected:
|
|||
}
|
||||
|
||||
assert(output_stream);
|
||||
size_t bytes_dumped =
|
||||
data.Dump(output_stream, 0, format, item_byte_size, item_count,
|
||||
num_per_line / target->GetArchitecture().GetDataByteSize(),
|
||||
addr, 0, 0, exe_scope);
|
||||
size_t bytes_dumped = DumpDataExtractor(
|
||||
data, output_stream, 0, format, item_byte_size, item_count,
|
||||
num_per_line / target->GetArchitecture().GetDataByteSize(), addr, 0, 0,
|
||||
exe_scope);
|
||||
m_next_addr = addr + bytes_dumped;
|
||||
output_stream->EOL();
|
||||
return true;
|
||||
|
@ -1131,10 +1131,10 @@ protected:
|
|||
DataExtractor data(dumpbuffer.GetBytes(), dumpbuffer.GetByteSize(),
|
||||
process->GetByteOrder(),
|
||||
process->GetAddressByteSize());
|
||||
data.Dump(&result.GetOutputStream(), 0, lldb::eFormatBytesWithASCII, 1,
|
||||
dumpbuffer.GetByteSize(), 16,
|
||||
found_location + m_memory_options.m_offset.GetCurrentValue(),
|
||||
0, 0);
|
||||
DumpDataExtractor(
|
||||
data, &result.GetOutputStream(), 0, lldb::eFormatBytesWithASCII, 1,
|
||||
dumpbuffer.GetByteSize(), 16,
|
||||
found_location + m_memory_options.m_offset.GetCurrentValue(), 0, 0);
|
||||
result.GetOutputStream().EOL();
|
||||
}
|
||||
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
|
||||
// Other libraries and framework includes
|
||||
// Project includes
|
||||
#include "lldb/Core/DumpDataExtractor.h"
|
||||
#include "lldb/Core/Module.h"
|
||||
#include "lldb/Core/Section.h"
|
||||
#include "lldb/Symbol/Block.h"
|
||||
|
@ -143,15 +144,15 @@ static bool DumpUInt(ExecutionContextScope *exe_scope, const Address &address,
|
|||
if (GetByteOrderAndAddressSize(exe_scope, address, byte_order, addr_size)) {
|
||||
DataExtractor data(&buf.front(), buf.size(), byte_order, addr_size);
|
||||
|
||||
data.Dump(strm,
|
||||
0, // Start offset in "data"
|
||||
eFormatHex, // Print as characters
|
||||
buf.size(), // Size of item
|
||||
1, // Items count
|
||||
UINT32_MAX, // num per line
|
||||
LLDB_INVALID_ADDRESS, // base address
|
||||
0, // bitfield bit size
|
||||
0); // bitfield bit offset
|
||||
DumpDataExtractor(data, strm,
|
||||
0, // Start offset in "data"
|
||||
eFormatHex, // Print as characters
|
||||
buf.size(), // Size of item
|
||||
1, // Items count
|
||||
UINT32_MAX, // num per line
|
||||
LLDB_INVALID_ADDRESS, // base address
|
||||
0, // bitfield bit size
|
||||
0); // bitfield bit offset
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -181,16 +182,16 @@ static size_t ReadCStringFromMemory(ExecutionContextScope *exe_scope,
|
|||
if (len > bytes_read)
|
||||
len = bytes_read;
|
||||
|
||||
data.Dump(strm,
|
||||
0, // Start offset in "data"
|
||||
eFormatChar, // Print as characters
|
||||
1, // Size of item (1 byte for a char!)
|
||||
len, // How many bytes to print?
|
||||
UINT32_MAX, // num per line
|
||||
LLDB_INVALID_ADDRESS, // base address
|
||||
0, // bitfield bit size
|
||||
DumpDataExtractor(data, strm,
|
||||
0, // Start offset in "data"
|
||||
eFormatChar, // Print as characters
|
||||
1, // Size of item (1 byte for a char!)
|
||||
len, // How many bytes to print?
|
||||
UINT32_MAX, // num per line
|
||||
LLDB_INVALID_ADDRESS, // base address
|
||||
0, // bitfield bit size
|
||||
|
||||
0); // bitfield bit offset
|
||||
0); // bitfield bit offset
|
||||
|
||||
total_len += bytes_read;
|
||||
|
||||
|
|
|
@ -15,6 +15,7 @@ add_lldb_library(lldbCore
|
|||
DataExtractor.cpp
|
||||
Debugger.cpp
|
||||
Disassembler.cpp
|
||||
DumpDataExtractor.cpp
|
||||
DynamicLoader.cpp
|
||||
EmulateInstruction.cpp
|
||||
Event.cpp
|
||||
|
|
|
@ -9,35 +9,22 @@
|
|||
|
||||
// C Includes
|
||||
// C++ Includes
|
||||
#include <bitset>
|
||||
#include <cassert>
|
||||
#include <cmath>
|
||||
#include <cstddef>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
|
||||
// Other libraries and framework includes
|
||||
#include "llvm/ADT/APFloat.h"
|
||||
#include "llvm/ADT/APInt.h"
|
||||
#include "llvm/ADT/ArrayRef.h"
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
#include "llvm/Support/MD5.h"
|
||||
#include "llvm/Support/MathExtras.h"
|
||||
|
||||
#include "clang/AST/ASTContext.h"
|
||||
|
||||
// Project includes
|
||||
#include "lldb/Core/DataBuffer.h"
|
||||
#include "lldb/Core/DataBufferHeap.h"
|
||||
#include "lldb/Core/DataExtractor.h"
|
||||
#include "lldb/Core/Disassembler.h"
|
||||
#include "lldb/Core/UUID.h"
|
||||
#include "lldb/Core/dwarf.h"
|
||||
#include "lldb/Symbol/ClangASTContext.h"
|
||||
#include "lldb/Target/ExecutionContext.h"
|
||||
#include "lldb/Target/ExecutionContextScope.h"
|
||||
#include "lldb/Target/SectionLoadList.h"
|
||||
#include "lldb/Target/Target.h"
|
||||
#include "lldb/Utility/Endian.h"
|
||||
#include "lldb/Utility/Log.h"
|
||||
#include "lldb/Utility/Stream.h"
|
||||
|
@ -111,8 +98,6 @@ static inline uint64_t ReadSwapInt64(const void *ptr) {
|
|||
return llvm::ByteSwap_64(value);
|
||||
}
|
||||
|
||||
#define NON_PRINTABLE_CHAR '.'
|
||||
|
||||
DataExtractor::DataExtractor()
|
||||
: m_start(nullptr), m_end(nullptr),
|
||||
m_byte_order(endian::InlHostByteOrder()), m_addr_size(sizeof(void *)),
|
||||
|
@ -785,129 +770,6 @@ uint64_t DataExtractor::GetPointer(offset_t *offset_ptr) const {
|
|||
return GetMaxU64(offset_ptr, m_addr_size);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// GetDwarfEHPtr
|
||||
//
|
||||
// Used for calls when the value type is specified by a DWARF EH Frame
|
||||
// pointer encoding.
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
uint64_t DataExtractor::GetGNUEHPointer(
|
||||
offset_t *offset_ptr, uint32_t eh_ptr_enc, lldb::addr_t pc_rel_addr,
|
||||
lldb::addr_t text_addr,
|
||||
lldb::addr_t data_addr) //, BSDRelocs *data_relocs) const
|
||||
{
|
||||
if (eh_ptr_enc == DW_EH_PE_omit)
|
||||
return ULLONG_MAX; // Value isn't in the buffer...
|
||||
|
||||
uint64_t baseAddress = 0;
|
||||
uint64_t addressValue = 0;
|
||||
const uint32_t addr_size = GetAddressByteSize();
|
||||
#ifdef LLDB_CONFIGURATION_DEBUG
|
||||
assert(addr_size == 4 || addr_size == 8);
|
||||
#endif
|
||||
|
||||
bool signExtendValue = false;
|
||||
// Decode the base part or adjust our offset
|
||||
switch (eh_ptr_enc & 0x70) {
|
||||
case DW_EH_PE_pcrel:
|
||||
signExtendValue = true;
|
||||
baseAddress = *offset_ptr;
|
||||
if (pc_rel_addr != LLDB_INVALID_ADDRESS)
|
||||
baseAddress += pc_rel_addr;
|
||||
// else
|
||||
// Log::GlobalWarning ("PC relative pointer encoding found with
|
||||
// invalid pc relative address.");
|
||||
break;
|
||||
|
||||
case DW_EH_PE_textrel:
|
||||
signExtendValue = true;
|
||||
if (text_addr != LLDB_INVALID_ADDRESS)
|
||||
baseAddress = text_addr;
|
||||
// else
|
||||
// Log::GlobalWarning ("text relative pointer encoding being
|
||||
// decoded with invalid text section address, setting base address
|
||||
// to zero.");
|
||||
break;
|
||||
|
||||
case DW_EH_PE_datarel:
|
||||
signExtendValue = true;
|
||||
if (data_addr != LLDB_INVALID_ADDRESS)
|
||||
baseAddress = data_addr;
|
||||
// else
|
||||
// Log::GlobalWarning ("data relative pointer encoding being
|
||||
// decoded with invalid data section address, setting base address
|
||||
// to zero.");
|
||||
break;
|
||||
|
||||
case DW_EH_PE_funcrel:
|
||||
signExtendValue = true;
|
||||
break;
|
||||
|
||||
case DW_EH_PE_aligned: {
|
||||
// SetPointerSize should be called prior to extracting these so the
|
||||
// pointer size is cached
|
||||
assert(addr_size != 0);
|
||||
if (addr_size) {
|
||||
// Align to a address size boundary first
|
||||
uint32_t alignOffset = *offset_ptr % addr_size;
|
||||
if (alignOffset)
|
||||
offset_ptr += addr_size - alignOffset;
|
||||
}
|
||||
} break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
// Decode the value part
|
||||
switch (eh_ptr_enc & DW_EH_PE_MASK_ENCODING) {
|
||||
case DW_EH_PE_absptr: {
|
||||
addressValue = GetAddress(offset_ptr);
|
||||
// if (data_relocs)
|
||||
// addressValue = data_relocs->Relocate(*offset_ptr -
|
||||
// addr_size, *this, addressValue);
|
||||
} break;
|
||||
case DW_EH_PE_uleb128:
|
||||
addressValue = GetULEB128(offset_ptr);
|
||||
break;
|
||||
case DW_EH_PE_udata2:
|
||||
addressValue = GetU16(offset_ptr);
|
||||
break;
|
||||
case DW_EH_PE_udata4:
|
||||
addressValue = GetU32(offset_ptr);
|
||||
break;
|
||||
case DW_EH_PE_udata8:
|
||||
addressValue = GetU64(offset_ptr);
|
||||
break;
|
||||
case DW_EH_PE_sleb128:
|
||||
addressValue = GetSLEB128(offset_ptr);
|
||||
break;
|
||||
case DW_EH_PE_sdata2:
|
||||
addressValue = (int16_t)GetU16(offset_ptr);
|
||||
break;
|
||||
case DW_EH_PE_sdata4:
|
||||
addressValue = (int32_t)GetU32(offset_ptr);
|
||||
break;
|
||||
case DW_EH_PE_sdata8:
|
||||
addressValue = (int64_t)GetU64(offset_ptr);
|
||||
break;
|
||||
default:
|
||||
// Unhandled encoding type
|
||||
assert(eh_ptr_enc);
|
||||
break;
|
||||
}
|
||||
|
||||
// Since we promote everything to 64 bit, we may need to sign extend
|
||||
if (signExtendValue && addr_size < sizeof(baseAddress)) {
|
||||
uint64_t sign_bit = 1ull << ((addr_size * 8ull) - 1ull);
|
||||
if (sign_bit & addressValue) {
|
||||
uint64_t mask = ~sign_bit + 1;
|
||||
addressValue |= mask;
|
||||
}
|
||||
}
|
||||
return baseAddress + addressValue;
|
||||
}
|
||||
|
||||
size_t DataExtractor::ExtractBytes(offset_t offset, offset_t length,
|
||||
ByteOrder dst_byte_order, void *dst) const {
|
||||
|
@ -1199,759 +1061,6 @@ uint32_t DataExtractor::Skip_LEB128(offset_t *offset_ptr) const {
|
|||
return bytes_consumed;
|
||||
}
|
||||
|
||||
static bool GetAPInt(const DataExtractor &data, lldb::offset_t *offset_ptr,
|
||||
lldb::offset_t byte_size, llvm::APInt &result) {
|
||||
llvm::SmallVector<uint64_t, 2> uint64_array;
|
||||
lldb::offset_t bytes_left = byte_size;
|
||||
uint64_t u64;
|
||||
const lldb::ByteOrder byte_order = data.GetByteOrder();
|
||||
if (byte_order == lldb::eByteOrderLittle) {
|
||||
while (bytes_left > 0) {
|
||||
if (bytes_left >= 8) {
|
||||
u64 = data.GetU64(offset_ptr);
|
||||
bytes_left -= 8;
|
||||
} else {
|
||||
u64 = data.GetMaxU64(offset_ptr, (uint32_t)bytes_left);
|
||||
bytes_left = 0;
|
||||
}
|
||||
uint64_array.push_back(u64);
|
||||
}
|
||||
result = llvm::APInt(byte_size * 8, llvm::ArrayRef<uint64_t>(uint64_array));
|
||||
return true;
|
||||
} else if (byte_order == lldb::eByteOrderBig) {
|
||||
lldb::offset_t be_offset = *offset_ptr + byte_size;
|
||||
lldb::offset_t temp_offset;
|
||||
while (bytes_left > 0) {
|
||||
if (bytes_left >= 8) {
|
||||
be_offset -= 8;
|
||||
temp_offset = be_offset;
|
||||
u64 = data.GetU64(&temp_offset);
|
||||
bytes_left -= 8;
|
||||
} else {
|
||||
be_offset -= bytes_left;
|
||||
temp_offset = be_offset;
|
||||
u64 = data.GetMaxU64(&temp_offset, (uint32_t)bytes_left);
|
||||
bytes_left = 0;
|
||||
}
|
||||
uint64_array.push_back(u64);
|
||||
}
|
||||
*offset_ptr += byte_size;
|
||||
result = llvm::APInt(byte_size * 8, llvm::ArrayRef<uint64_t>(uint64_array));
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static lldb::offset_t DumpAPInt(Stream *s, const DataExtractor &data,
|
||||
lldb::offset_t offset, lldb::offset_t byte_size,
|
||||
bool is_signed, unsigned radix) {
|
||||
llvm::APInt apint;
|
||||
if (GetAPInt(data, &offset, byte_size, apint)) {
|
||||
std::string apint_str(apint.toString(radix, is_signed));
|
||||
switch (radix) {
|
||||
case 2:
|
||||
s->Write("0b", 2);
|
||||
break;
|
||||
case 8:
|
||||
s->Write("0", 1);
|
||||
break;
|
||||
case 10:
|
||||
break;
|
||||
}
|
||||
s->Write(apint_str.c_str(), apint_str.size());
|
||||
}
|
||||
return offset;
|
||||
}
|
||||
|
||||
static float half2float(uint16_t half) {
|
||||
union {
|
||||
float f;
|
||||
uint32_t u;
|
||||
} u;
|
||||
int32_t v = (int16_t)half;
|
||||
|
||||
if (0 == (v & 0x7c00)) {
|
||||
u.u = v & 0x80007FFFU;
|
||||
return u.f * ldexpf(1, 125);
|
||||
}
|
||||
|
||||
v <<= 13;
|
||||
u.u = v | 0x70000000U;
|
||||
return u.f * ldexpf(1, -112);
|
||||
}
|
||||
|
||||
lldb::offset_t DataExtractor::Dump(
|
||||
Stream *s, offset_t start_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, // If zero, this is not a bitfield value, if
|
||||
// non-zero, the value is a bitfield
|
||||
uint32_t item_bit_offset, // If "item_bit_size" is non-zero, this is the
|
||||
// shift amount to apply to a bitfield
|
||||
ExecutionContextScope *exe_scope) const {
|
||||
if (s == nullptr)
|
||||
return start_offset;
|
||||
|
||||
if (item_format == eFormatPointer) {
|
||||
if (item_byte_size != 4 && item_byte_size != 8)
|
||||
item_byte_size = s->GetAddressByteSize();
|
||||
}
|
||||
|
||||
offset_t offset = start_offset;
|
||||
|
||||
if (item_format == eFormatInstruction) {
|
||||
TargetSP target_sp;
|
||||
if (exe_scope)
|
||||
target_sp = exe_scope->CalculateTarget();
|
||||
if (target_sp) {
|
||||
DisassemblerSP disassembler_sp(Disassembler::FindPlugin(
|
||||
target_sp->GetArchitecture(), nullptr, nullptr));
|
||||
if (disassembler_sp) {
|
||||
lldb::addr_t addr = base_addr + start_offset;
|
||||
lldb_private::Address so_addr;
|
||||
bool data_from_file = true;
|
||||
if (target_sp->GetSectionLoadList().ResolveLoadAddress(addr, so_addr)) {
|
||||
data_from_file = false;
|
||||
} else {
|
||||
if (target_sp->GetSectionLoadList().IsEmpty() ||
|
||||
!target_sp->GetImages().ResolveFileAddress(addr, so_addr))
|
||||
so_addr.SetRawAddress(addr);
|
||||
}
|
||||
|
||||
size_t bytes_consumed = disassembler_sp->DecodeInstructions(
|
||||
so_addr, *this, start_offset, item_count, false, data_from_file);
|
||||
|
||||
if (bytes_consumed) {
|
||||
offset += bytes_consumed;
|
||||
const bool show_address = base_addr != LLDB_INVALID_ADDRESS;
|
||||
const bool show_bytes = true;
|
||||
ExecutionContext exe_ctx;
|
||||
exe_scope->CalculateExecutionContext(exe_ctx);
|
||||
disassembler_sp->GetInstructionList().Dump(s, show_address,
|
||||
show_bytes, &exe_ctx);
|
||||
}
|
||||
}
|
||||
} else
|
||||
s->Printf("invalid target");
|
||||
|
||||
return offset;
|
||||
}
|
||||
|
||||
if ((item_format == eFormatOSType || item_format == eFormatAddressInfo) &&
|
||||
item_byte_size > 8)
|
||||
item_format = eFormatHex;
|
||||
|
||||
lldb::offset_t line_start_offset = start_offset;
|
||||
for (uint32_t count = 0; ValidOffset(offset) && count < item_count; ++count) {
|
||||
if ((count % num_per_line) == 0) {
|
||||
if (count > 0) {
|
||||
if (item_format == eFormatBytesWithASCII &&
|
||||
offset > line_start_offset) {
|
||||
s->Printf("%*s",
|
||||
static_cast<int>(
|
||||
(num_per_line - (offset - line_start_offset)) * 3 + 2),
|
||||
"");
|
||||
Dump(s, line_start_offset, eFormatCharPrintable, 1,
|
||||
offset - line_start_offset, SIZE_MAX, LLDB_INVALID_ADDRESS, 0,
|
||||
0);
|
||||
}
|
||||
s->EOL();
|
||||
}
|
||||
if (base_addr != LLDB_INVALID_ADDRESS)
|
||||
s->Printf("0x%8.8" PRIx64 ": ",
|
||||
(uint64_t)(base_addr +
|
||||
(offset - start_offset) / m_target_byte_size));
|
||||
|
||||
line_start_offset = offset;
|
||||
} else if (item_format != eFormatChar &&
|
||||
item_format != eFormatCharPrintable &&
|
||||
item_format != eFormatCharArray && count > 0) {
|
||||
s->PutChar(' ');
|
||||
}
|
||||
|
||||
switch (item_format) {
|
||||
case eFormatBoolean:
|
||||
if (item_byte_size <= 8)
|
||||
s->Printf("%s", GetMaxU64Bitfield(&offset, item_byte_size,
|
||||
item_bit_size, item_bit_offset)
|
||||
? "true"
|
||||
: "false");
|
||||
else {
|
||||
s->Printf("error: unsupported byte size (%" PRIu64
|
||||
") for boolean format",
|
||||
(uint64_t)item_byte_size);
|
||||
return offset;
|
||||
}
|
||||
break;
|
||||
|
||||
case eFormatBinary:
|
||||
if (item_byte_size <= 8) {
|
||||
uint64_t uval64 = GetMaxU64Bitfield(&offset, item_byte_size,
|
||||
item_bit_size, item_bit_offset);
|
||||
// Avoid std::bitset<64>::to_string() since it is missing in
|
||||
// earlier C++ libraries
|
||||
std::string binary_value(64, '0');
|
||||
std::bitset<64> bits(uval64);
|
||||
for (uint32_t i = 0; i < 64; ++i)
|
||||
if (bits[i])
|
||||
binary_value[64 - 1 - i] = '1';
|
||||
if (item_bit_size > 0)
|
||||
s->Printf("0b%s", binary_value.c_str() + 64 - item_bit_size);
|
||||
else if (item_byte_size > 0 && item_byte_size <= 8)
|
||||
s->Printf("0b%s", binary_value.c_str() + 64 - item_byte_size * 8);
|
||||
} else {
|
||||
const bool is_signed = false;
|
||||
const unsigned radix = 2;
|
||||
offset = DumpAPInt(s, *this, offset, item_byte_size, is_signed, radix);
|
||||
}
|
||||
break;
|
||||
|
||||
case eFormatBytes:
|
||||
case eFormatBytesWithASCII:
|
||||
for (uint32_t i = 0; i < item_byte_size; ++i) {
|
||||
s->Printf("%2.2x", GetU8(&offset));
|
||||
}
|
||||
|
||||
// Put an extra space between the groups of bytes if more than one
|
||||
// is being dumped in a group (item_byte_size is more than 1).
|
||||
if (item_byte_size > 1)
|
||||
s->PutChar(' ');
|
||||
break;
|
||||
|
||||
case eFormatChar:
|
||||
case eFormatCharPrintable:
|
||||
case eFormatCharArray: {
|
||||
// If we are only printing one character surround it with single
|
||||
// quotes
|
||||
if (item_count == 1 && item_format == eFormatChar)
|
||||
s->PutChar('\'');
|
||||
|
||||
const uint64_t ch = GetMaxU64Bitfield(&offset, item_byte_size,
|
||||
item_bit_size, item_bit_offset);
|
||||
if (isprint(ch))
|
||||
s->Printf("%c", (char)ch);
|
||||
else if (item_format != eFormatCharPrintable) {
|
||||
switch (ch) {
|
||||
case '\033':
|
||||
s->Printf("\\e");
|
||||
break;
|
||||
case '\a':
|
||||
s->Printf("\\a");
|
||||
break;
|
||||
case '\b':
|
||||
s->Printf("\\b");
|
||||
break;
|
||||
case '\f':
|
||||
s->Printf("\\f");
|
||||
break;
|
||||
case '\n':
|
||||
s->Printf("\\n");
|
||||
break;
|
||||
case '\r':
|
||||
s->Printf("\\r");
|
||||
break;
|
||||
case '\t':
|
||||
s->Printf("\\t");
|
||||
break;
|
||||
case '\v':
|
||||
s->Printf("\\v");
|
||||
break;
|
||||
case '\0':
|
||||
s->Printf("\\0");
|
||||
break;
|
||||
default:
|
||||
if (item_byte_size == 1)
|
||||
s->Printf("\\x%2.2x", (uint8_t)ch);
|
||||
else
|
||||
s->Printf("%" PRIu64, ch);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
s->PutChar(NON_PRINTABLE_CHAR);
|
||||
}
|
||||
|
||||
// If we are only printing one character surround it with single quotes
|
||||
if (item_count == 1 && item_format == eFormatChar)
|
||||
s->PutChar('\'');
|
||||
} break;
|
||||
|
||||
case eFormatEnum: // Print enum value as a signed integer when we don't get
|
||||
// the enum type
|
||||
case eFormatDecimal:
|
||||
if (item_byte_size <= 8)
|
||||
s->Printf("%" PRId64,
|
||||
GetMaxS64Bitfield(&offset, item_byte_size, item_bit_size,
|
||||
item_bit_offset));
|
||||
else {
|
||||
const bool is_signed = true;
|
||||
const unsigned radix = 10;
|
||||
offset = DumpAPInt(s, *this, offset, item_byte_size, is_signed, radix);
|
||||
}
|
||||
break;
|
||||
|
||||
case eFormatUnsigned:
|
||||
if (item_byte_size <= 8)
|
||||
s->Printf("%" PRIu64,
|
||||
GetMaxU64Bitfield(&offset, item_byte_size, item_bit_size,
|
||||
item_bit_offset));
|
||||
else {
|
||||
const bool is_signed = false;
|
||||
const unsigned radix = 10;
|
||||
offset = DumpAPInt(s, *this, offset, item_byte_size, is_signed, radix);
|
||||
}
|
||||
break;
|
||||
|
||||
case eFormatOctal:
|
||||
if (item_byte_size <= 8)
|
||||
s->Printf("0%" PRIo64,
|
||||
GetMaxS64Bitfield(&offset, item_byte_size, item_bit_size,
|
||||
item_bit_offset));
|
||||
else {
|
||||
const bool is_signed = false;
|
||||
const unsigned radix = 8;
|
||||
offset = DumpAPInt(s, *this, offset, item_byte_size, is_signed, radix);
|
||||
}
|
||||
break;
|
||||
|
||||
case eFormatOSType: {
|
||||
uint64_t uval64 = GetMaxU64Bitfield(&offset, item_byte_size,
|
||||
item_bit_size, item_bit_offset);
|
||||
s->PutChar('\'');
|
||||
for (uint32_t i = 0; i < item_byte_size; ++i) {
|
||||
uint8_t ch = (uint8_t)(uval64 >> ((item_byte_size - i - 1) * 8));
|
||||
if (isprint(ch))
|
||||
s->Printf("%c", ch);
|
||||
else {
|
||||
switch (ch) {
|
||||
case '\033':
|
||||
s->Printf("\\e");
|
||||
break;
|
||||
case '\a':
|
||||
s->Printf("\\a");
|
||||
break;
|
||||
case '\b':
|
||||
s->Printf("\\b");
|
||||
break;
|
||||
case '\f':
|
||||
s->Printf("\\f");
|
||||
break;
|
||||
case '\n':
|
||||
s->Printf("\\n");
|
||||
break;
|
||||
case '\r':
|
||||
s->Printf("\\r");
|
||||
break;
|
||||
case '\t':
|
||||
s->Printf("\\t");
|
||||
break;
|
||||
case '\v':
|
||||
s->Printf("\\v");
|
||||
break;
|
||||
case '\0':
|
||||
s->Printf("\\0");
|
||||
break;
|
||||
default:
|
||||
s->Printf("\\x%2.2x", ch);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
s->PutChar('\'');
|
||||
} break;
|
||||
|
||||
case eFormatCString: {
|
||||
const char *cstr = GetCStr(&offset);
|
||||
|
||||
if (!cstr) {
|
||||
s->Printf("NULL");
|
||||
offset = LLDB_INVALID_OFFSET;
|
||||
} else {
|
||||
s->PutChar('\"');
|
||||
|
||||
while (const char c = *cstr) {
|
||||
if (isprint(c)) {
|
||||
s->PutChar(c);
|
||||
} else {
|
||||
switch (c) {
|
||||
case '\033':
|
||||
s->Printf("\\e");
|
||||
break;
|
||||
case '\a':
|
||||
s->Printf("\\a");
|
||||
break;
|
||||
case '\b':
|
||||
s->Printf("\\b");
|
||||
break;
|
||||
case '\f':
|
||||
s->Printf("\\f");
|
||||
break;
|
||||
case '\n':
|
||||
s->Printf("\\n");
|
||||
break;
|
||||
case '\r':
|
||||
s->Printf("\\r");
|
||||
break;
|
||||
case '\t':
|
||||
s->Printf("\\t");
|
||||
break;
|
||||
case '\v':
|
||||
s->Printf("\\v");
|
||||
break;
|
||||
default:
|
||||
s->Printf("\\x%2.2x", c);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
++cstr;
|
||||
}
|
||||
|
||||
s->PutChar('\"');
|
||||
}
|
||||
} break;
|
||||
|
||||
case eFormatPointer:
|
||||
s->Address(GetMaxU64Bitfield(&offset, item_byte_size, item_bit_size,
|
||||
item_bit_offset),
|
||||
sizeof(addr_t));
|
||||
break;
|
||||
|
||||
case eFormatComplexInteger: {
|
||||
size_t complex_int_byte_size = item_byte_size / 2;
|
||||
|
||||
if (complex_int_byte_size > 0 && complex_int_byte_size <= 8) {
|
||||
s->Printf("%" PRIu64,
|
||||
GetMaxU64Bitfield(&offset, complex_int_byte_size, 0, 0));
|
||||
s->Printf(" + %" PRIu64 "i",
|
||||
GetMaxU64Bitfield(&offset, complex_int_byte_size, 0, 0));
|
||||
} else {
|
||||
s->Printf("error: unsupported byte size (%" PRIu64
|
||||
") for complex integer format",
|
||||
(uint64_t)item_byte_size);
|
||||
return offset;
|
||||
}
|
||||
} break;
|
||||
|
||||
case eFormatComplex:
|
||||
if (sizeof(float) * 2 == item_byte_size) {
|
||||
float f32_1 = GetFloat(&offset);
|
||||
float f32_2 = GetFloat(&offset);
|
||||
|
||||
s->Printf("%g + %gi", f32_1, f32_2);
|
||||
break;
|
||||
} else if (sizeof(double) * 2 == item_byte_size) {
|
||||
double d64_1 = GetDouble(&offset);
|
||||
double d64_2 = GetDouble(&offset);
|
||||
|
||||
s->Printf("%lg + %lgi", d64_1, d64_2);
|
||||
break;
|
||||
} else if (sizeof(long double) * 2 == item_byte_size) {
|
||||
long double ld64_1 = GetLongDouble(&offset);
|
||||
long double ld64_2 = GetLongDouble(&offset);
|
||||
s->Printf("%Lg + %Lgi", ld64_1, ld64_2);
|
||||
break;
|
||||
} else {
|
||||
s->Printf("error: unsupported byte size (%" PRIu64
|
||||
") for complex float format",
|
||||
(uint64_t)item_byte_size);
|
||||
return offset;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
case eFormatDefault:
|
||||
case eFormatHex:
|
||||
case eFormatHexUppercase: {
|
||||
bool wantsuppercase = (item_format == eFormatHexUppercase);
|
||||
switch (item_byte_size) {
|
||||
case 1:
|
||||
case 2:
|
||||
case 4:
|
||||
case 8:
|
||||
s->Printf(wantsuppercase ? "0x%*.*" PRIX64 : "0x%*.*" PRIx64,
|
||||
(int)(2 * item_byte_size), (int)(2 * item_byte_size),
|
||||
GetMaxU64Bitfield(&offset, item_byte_size, item_bit_size,
|
||||
item_bit_offset));
|
||||
break;
|
||||
default: {
|
||||
assert(item_bit_size == 0 && item_bit_offset == 0);
|
||||
const uint8_t *bytes =
|
||||
(const uint8_t *)GetData(&offset, item_byte_size);
|
||||
if (bytes) {
|
||||
s->PutCString("0x");
|
||||
uint32_t idx;
|
||||
if (m_byte_order == eByteOrderBig) {
|
||||
for (idx = 0; idx < item_byte_size; ++idx)
|
||||
s->Printf(wantsuppercase ? "%2.2X" : "%2.2x", bytes[idx]);
|
||||
} else {
|
||||
for (idx = 0; idx < item_byte_size; ++idx)
|
||||
s->Printf(wantsuppercase ? "%2.2X" : "%2.2x",
|
||||
bytes[item_byte_size - 1 - idx]);
|
||||
}
|
||||
}
|
||||
} break;
|
||||
}
|
||||
} break;
|
||||
|
||||
case eFormatFloat: {
|
||||
TargetSP target_sp;
|
||||
bool used_apfloat = false;
|
||||
if (exe_scope)
|
||||
target_sp = exe_scope->CalculateTarget();
|
||||
if (target_sp) {
|
||||
ClangASTContext *clang_ast = target_sp->GetScratchClangASTContext();
|
||||
if (clang_ast) {
|
||||
clang::ASTContext *ast = clang_ast->getASTContext();
|
||||
if (ast) {
|
||||
llvm::SmallVector<char, 256> sv;
|
||||
// Show full precision when printing float values
|
||||
const unsigned format_precision = 0;
|
||||
const unsigned format_max_padding = 100;
|
||||
size_t item_bit_size = item_byte_size * 8;
|
||||
|
||||
if (item_bit_size == ast->getTypeSize(ast->FloatTy)) {
|
||||
llvm::APInt apint(item_bit_size,
|
||||
this->GetMaxU64(&offset, item_byte_size));
|
||||
llvm::APFloat apfloat(ast->getFloatTypeSemantics(ast->FloatTy),
|
||||
apint);
|
||||
apfloat.toString(sv, format_precision, format_max_padding);
|
||||
} else if (item_bit_size == ast->getTypeSize(ast->DoubleTy)) {
|
||||
llvm::APInt apint;
|
||||
if (GetAPInt(*this, &offset, item_byte_size, apint)) {
|
||||
llvm::APFloat apfloat(ast->getFloatTypeSemantics(ast->DoubleTy),
|
||||
apint);
|
||||
apfloat.toString(sv, format_precision, format_max_padding);
|
||||
}
|
||||
} else if (item_bit_size == ast->getTypeSize(ast->LongDoubleTy)) {
|
||||
const auto &semantics =
|
||||
ast->getFloatTypeSemantics(ast->LongDoubleTy);
|
||||
const auto byte_size =
|
||||
(llvm::APFloat::getSizeInBits(semantics) + 7) / 8;
|
||||
|
||||
llvm::APInt apint;
|
||||
if (GetAPInt(*this, &offset, byte_size, apint)) {
|
||||
llvm::APFloat apfloat(semantics, apint);
|
||||
apfloat.toString(sv, format_precision, format_max_padding);
|
||||
}
|
||||
} else if (item_bit_size == ast->getTypeSize(ast->HalfTy)) {
|
||||
llvm::APInt apint(item_bit_size, this->GetU16(&offset));
|
||||
llvm::APFloat apfloat(ast->getFloatTypeSemantics(ast->HalfTy),
|
||||
apint);
|
||||
apfloat.toString(sv, format_precision, format_max_padding);
|
||||
}
|
||||
|
||||
if (!sv.empty()) {
|
||||
s->Printf("%*.*s", (int)sv.size(), (int)sv.size(), sv.data());
|
||||
used_apfloat = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!used_apfloat) {
|
||||
std::ostringstream ss;
|
||||
if (item_byte_size == sizeof(float) || item_byte_size == 2) {
|
||||
float f;
|
||||
if (item_byte_size == 2) {
|
||||
uint16_t half = this->GetU16(&offset);
|
||||
f = half2float(half);
|
||||
} else {
|
||||
f = GetFloat(&offset);
|
||||
}
|
||||
ss.precision(std::numeric_limits<float>::digits10);
|
||||
ss << f;
|
||||
} else if (item_byte_size == sizeof(double)) {
|
||||
ss.precision(std::numeric_limits<double>::digits10);
|
||||
ss << GetDouble(&offset);
|
||||
} else if (item_byte_size == sizeof(long double) ||
|
||||
item_byte_size == 10) {
|
||||
ss.precision(std::numeric_limits<long double>::digits10);
|
||||
ss << GetLongDouble(&offset);
|
||||
} else {
|
||||
s->Printf("error: unsupported byte size (%" PRIu64
|
||||
") for float format",
|
||||
(uint64_t)item_byte_size);
|
||||
return offset;
|
||||
}
|
||||
ss.flush();
|
||||
s->Printf("%s", ss.str().c_str());
|
||||
}
|
||||
} break;
|
||||
|
||||
case eFormatUnicode16:
|
||||
s->Printf("U+%4.4x", GetU16(&offset));
|
||||
break;
|
||||
|
||||
case eFormatUnicode32:
|
||||
s->Printf("U+0x%8.8x", GetU32(&offset));
|
||||
break;
|
||||
|
||||
case eFormatAddressInfo: {
|
||||
addr_t addr = GetMaxU64Bitfield(&offset, item_byte_size, item_bit_size,
|
||||
item_bit_offset);
|
||||
s->Printf("0x%*.*" PRIx64, (int)(2 * item_byte_size),
|
||||
(int)(2 * item_byte_size), addr);
|
||||
if (exe_scope) {
|
||||
TargetSP target_sp(exe_scope->CalculateTarget());
|
||||
lldb_private::Address so_addr;
|
||||
if (target_sp) {
|
||||
if (target_sp->GetSectionLoadList().ResolveLoadAddress(addr,
|
||||
so_addr)) {
|
||||
s->PutChar(' ');
|
||||
so_addr.Dump(s, exe_scope, Address::DumpStyleResolvedDescription,
|
||||
Address::DumpStyleModuleWithFileAddress);
|
||||
} else {
|
||||
so_addr.SetOffset(addr);
|
||||
so_addr.Dump(s, exe_scope,
|
||||
Address::DumpStyleResolvedPointerDescription);
|
||||
}
|
||||
}
|
||||
}
|
||||
} break;
|
||||
|
||||
case eFormatHexFloat:
|
||||
if (sizeof(float) == item_byte_size) {
|
||||
char float_cstr[256];
|
||||
llvm::APFloat ap_float(GetFloat(&offset));
|
||||
ap_float.convertToHexString(float_cstr, 0, false,
|
||||
llvm::APFloat::rmNearestTiesToEven);
|
||||
s->Printf("%s", float_cstr);
|
||||
break;
|
||||
} else if (sizeof(double) == item_byte_size) {
|
||||
char float_cstr[256];
|
||||
llvm::APFloat ap_float(GetDouble(&offset));
|
||||
ap_float.convertToHexString(float_cstr, 0, false,
|
||||
llvm::APFloat::rmNearestTiesToEven);
|
||||
s->Printf("%s", float_cstr);
|
||||
break;
|
||||
} else {
|
||||
s->Printf("error: unsupported byte size (%" PRIu64
|
||||
") for hex float format",
|
||||
(uint64_t)item_byte_size);
|
||||
return offset;
|
||||
}
|
||||
break;
|
||||
|
||||
// please keep the single-item formats below in sync with
|
||||
// FormatManager::GetSingleItemFormat
|
||||
// if you fail to do so, users will start getting different outputs
|
||||
// depending on internal
|
||||
// implementation details they should not care about ||
|
||||
case eFormatVectorOfChar: // ||
|
||||
s->PutChar('{'); // \/
|
||||
offset = Dump(s, offset, eFormatCharArray, 1, item_byte_size,
|
||||
item_byte_size, LLDB_INVALID_ADDRESS, 0, 0);
|
||||
s->PutChar('}');
|
||||
break;
|
||||
|
||||
case eFormatVectorOfSInt8:
|
||||
s->PutChar('{');
|
||||
offset = Dump(s, offset, eFormatDecimal, 1, item_byte_size,
|
||||
item_byte_size, LLDB_INVALID_ADDRESS, 0, 0);
|
||||
s->PutChar('}');
|
||||
break;
|
||||
|
||||
case eFormatVectorOfUInt8:
|
||||
s->PutChar('{');
|
||||
offset = Dump(s, offset, eFormatHex, 1, item_byte_size, item_byte_size,
|
||||
LLDB_INVALID_ADDRESS, 0, 0);
|
||||
s->PutChar('}');
|
||||
break;
|
||||
|
||||
case eFormatVectorOfSInt16:
|
||||
s->PutChar('{');
|
||||
offset =
|
||||
Dump(s, offset, eFormatDecimal, sizeof(uint16_t),
|
||||
item_byte_size / sizeof(uint16_t),
|
||||
item_byte_size / sizeof(uint16_t), LLDB_INVALID_ADDRESS, 0, 0);
|
||||
s->PutChar('}');
|
||||
break;
|
||||
|
||||
case eFormatVectorOfUInt16:
|
||||
s->PutChar('{');
|
||||
offset =
|
||||
Dump(s, offset, eFormatHex, sizeof(uint16_t),
|
||||
item_byte_size / sizeof(uint16_t),
|
||||
item_byte_size / sizeof(uint16_t), LLDB_INVALID_ADDRESS, 0, 0);
|
||||
s->PutChar('}');
|
||||
break;
|
||||
|
||||
case eFormatVectorOfSInt32:
|
||||
s->PutChar('{');
|
||||
offset =
|
||||
Dump(s, offset, eFormatDecimal, sizeof(uint32_t),
|
||||
item_byte_size / sizeof(uint32_t),
|
||||
item_byte_size / sizeof(uint32_t), LLDB_INVALID_ADDRESS, 0, 0);
|
||||
s->PutChar('}');
|
||||
break;
|
||||
|
||||
case eFormatVectorOfUInt32:
|
||||
s->PutChar('{');
|
||||
offset =
|
||||
Dump(s, offset, eFormatHex, sizeof(uint32_t),
|
||||
item_byte_size / sizeof(uint32_t),
|
||||
item_byte_size / sizeof(uint32_t), LLDB_INVALID_ADDRESS, 0, 0);
|
||||
s->PutChar('}');
|
||||
break;
|
||||
|
||||
case eFormatVectorOfSInt64:
|
||||
s->PutChar('{');
|
||||
offset =
|
||||
Dump(s, offset, eFormatDecimal, sizeof(uint64_t),
|
||||
item_byte_size / sizeof(uint64_t),
|
||||
item_byte_size / sizeof(uint64_t), LLDB_INVALID_ADDRESS, 0, 0);
|
||||
s->PutChar('}');
|
||||
break;
|
||||
|
||||
case eFormatVectorOfUInt64:
|
||||
s->PutChar('{');
|
||||
offset =
|
||||
Dump(s, offset, eFormatHex, sizeof(uint64_t),
|
||||
item_byte_size / sizeof(uint64_t),
|
||||
item_byte_size / sizeof(uint64_t), LLDB_INVALID_ADDRESS, 0, 0);
|
||||
s->PutChar('}');
|
||||
break;
|
||||
|
||||
case eFormatVectorOfFloat16:
|
||||
s->PutChar('{');
|
||||
offset = Dump(s, offset, eFormatFloat, 2, item_byte_size / 2,
|
||||
item_byte_size / 2, LLDB_INVALID_ADDRESS, 0, 0);
|
||||
s->PutChar('}');
|
||||
break;
|
||||
|
||||
case eFormatVectorOfFloat32:
|
||||
s->PutChar('{');
|
||||
offset = Dump(s, offset, eFormatFloat, 4, item_byte_size / 4,
|
||||
item_byte_size / 4, LLDB_INVALID_ADDRESS, 0, 0);
|
||||
s->PutChar('}');
|
||||
break;
|
||||
|
||||
case eFormatVectorOfFloat64:
|
||||
s->PutChar('{');
|
||||
offset = Dump(s, offset, eFormatFloat, 8, item_byte_size / 8,
|
||||
item_byte_size / 8, LLDB_INVALID_ADDRESS, 0, 0);
|
||||
s->PutChar('}');
|
||||
break;
|
||||
|
||||
case eFormatVectorOfUInt128:
|
||||
s->PutChar('{');
|
||||
offset = Dump(s, offset, eFormatHex, 16, item_byte_size / 16,
|
||||
item_byte_size / 16, LLDB_INVALID_ADDRESS, 0, 0);
|
||||
s->PutChar('}');
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (item_format == eFormatBytesWithASCII && offset > line_start_offset) {
|
||||
s->Printf("%*s", static_cast<int>(
|
||||
(num_per_line - (offset - line_start_offset)) * 3 + 2),
|
||||
"");
|
||||
Dump(s, line_start_offset, eFormatCharPrintable, 1,
|
||||
offset - line_start_offset, SIZE_MAX, LLDB_INVALID_ADDRESS, 0, 0);
|
||||
}
|
||||
return offset; // Return the offset at which we ended up
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// Dumps bytes from this object's data to the stream "s" starting
|
||||
// "start_offset" bytes into this data, and ending with the byte
|
||||
|
@ -2043,19 +1152,6 @@ void DataExtractor::DumpUUID(Stream *s, offset_t offset) const {
|
|||
}
|
||||
}
|
||||
|
||||
void DataExtractor::DumpHexBytes(Stream *s, const void *src, size_t src_len,
|
||||
uint32_t bytes_per_line, addr_t base_addr) {
|
||||
DataExtractor data(src, src_len, eByteOrderLittle, 4);
|
||||
data.Dump(s,
|
||||
0, // Offset into "src"
|
||||
eFormatBytes, // Dump as hex bytes
|
||||
1, // Size of each item is 1 for single bytes
|
||||
src_len, // Number of bytes
|
||||
bytes_per_line, // Num bytes per line
|
||||
base_addr, // Base address
|
||||
0, 0); // Bitfield info
|
||||
}
|
||||
|
||||
size_t DataExtractor::Copy(DataExtractor &dest_data) const {
|
||||
if (m_data_sp) {
|
||||
// we can pass along the SP to the data
|
||||
|
|
|
@ -0,0 +1,788 @@
|
|||
//===-- DumpDataExtractor.cpp -----------------------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "lldb/Core/DumpDataExtractor.h"
|
||||
|
||||
#include "lldb/Core/DataExtractor.h"
|
||||
#include "lldb/Core/Disassembler.h"
|
||||
#include "lldb/Symbol/ClangASTContext.h"
|
||||
#include "lldb/Target/ExecutionContext.h"
|
||||
#include "lldb/Target/ExecutionContextScope.h"
|
||||
#include "lldb/Target/SectionLoadList.h"
|
||||
#include "lldb/Target/Target.h"
|
||||
#include "lldb/Utility/Stream.h"
|
||||
|
||||
#include <bitset>
|
||||
#include <sstream>
|
||||
|
||||
using namespace lldb_private;
|
||||
using namespace lldb;
|
||||
|
||||
#define NON_PRINTABLE_CHAR '.'
|
||||
|
||||
static float half2float(uint16_t half) {
|
||||
union {
|
||||
float f;
|
||||
uint32_t u;
|
||||
} u;
|
||||
int32_t v = (int16_t)half;
|
||||
|
||||
if (0 == (v & 0x7c00)) {
|
||||
u.u = v & 0x80007FFFU;
|
||||
return u.f * ldexpf(1, 125);
|
||||
}
|
||||
|
||||
v <<= 13;
|
||||
u.u = v | 0x70000000U;
|
||||
return u.f * ldexpf(1, -112);
|
||||
}
|
||||
|
||||
static bool GetAPInt(const DataExtractor &data, lldb::offset_t *offset_ptr,
|
||||
lldb::offset_t byte_size, llvm::APInt &result) {
|
||||
llvm::SmallVector<uint64_t, 2> uint64_array;
|
||||
lldb::offset_t bytes_left = byte_size;
|
||||
uint64_t u64;
|
||||
const lldb::ByteOrder byte_order = data.GetByteOrder();
|
||||
if (byte_order == lldb::eByteOrderLittle) {
|
||||
while (bytes_left > 0) {
|
||||
if (bytes_left >= 8) {
|
||||
u64 = data.GetU64(offset_ptr);
|
||||
bytes_left -= 8;
|
||||
} else {
|
||||
u64 = data.GetMaxU64(offset_ptr, (uint32_t)bytes_left);
|
||||
bytes_left = 0;
|
||||
}
|
||||
uint64_array.push_back(u64);
|
||||
}
|
||||
result = llvm::APInt(byte_size * 8, llvm::ArrayRef<uint64_t>(uint64_array));
|
||||
return true;
|
||||
} else if (byte_order == lldb::eByteOrderBig) {
|
||||
lldb::offset_t be_offset = *offset_ptr + byte_size;
|
||||
lldb::offset_t temp_offset;
|
||||
while (bytes_left > 0) {
|
||||
if (bytes_left >= 8) {
|
||||
be_offset -= 8;
|
||||
temp_offset = be_offset;
|
||||
u64 = data.GetU64(&temp_offset);
|
||||
bytes_left -= 8;
|
||||
} else {
|
||||
be_offset -= bytes_left;
|
||||
temp_offset = be_offset;
|
||||
u64 = data.GetMaxU64(&temp_offset, (uint32_t)bytes_left);
|
||||
bytes_left = 0;
|
||||
}
|
||||
uint64_array.push_back(u64);
|
||||
}
|
||||
*offset_ptr += byte_size;
|
||||
result = llvm::APInt(byte_size * 8, llvm::ArrayRef<uint64_t>(uint64_array));
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static lldb::offset_t DumpAPInt(Stream *s, const DataExtractor &data,
|
||||
lldb::offset_t offset, lldb::offset_t byte_size,
|
||||
bool is_signed, unsigned radix) {
|
||||
llvm::APInt apint;
|
||||
if (GetAPInt(data, &offset, byte_size, apint)) {
|
||||
std::string apint_str(apint.toString(radix, is_signed));
|
||||
switch (radix) {
|
||||
case 2:
|
||||
s->Write("0b", 2);
|
||||
break;
|
||||
case 8:
|
||||
s->Write("0", 1);
|
||||
break;
|
||||
case 10:
|
||||
break;
|
||||
}
|
||||
s->Write(apint_str.c_str(), apint_str.size());
|
||||
}
|
||||
return offset;
|
||||
}
|
||||
|
||||
lldb::offset_t lldb_private::DumpDataExtractor(
|
||||
const DataExtractor &DE, Stream *s, offset_t start_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, // If zero, this is not a bitfield value, if
|
||||
// non-zero, the value is a bitfield
|
||||
uint32_t item_bit_offset, // If "item_bit_size" is non-zero, this is the
|
||||
// shift amount to apply to a bitfield
|
||||
ExecutionContextScope *exe_scope) {
|
||||
if (s == nullptr)
|
||||
return start_offset;
|
||||
|
||||
if (item_format == eFormatPointer) {
|
||||
if (item_byte_size != 4 && item_byte_size != 8)
|
||||
item_byte_size = s->GetAddressByteSize();
|
||||
}
|
||||
|
||||
offset_t offset = start_offset;
|
||||
|
||||
if (item_format == eFormatInstruction) {
|
||||
TargetSP target_sp;
|
||||
if (exe_scope)
|
||||
target_sp = exe_scope->CalculateTarget();
|
||||
if (target_sp) {
|
||||
DisassemblerSP disassembler_sp(Disassembler::FindPlugin(
|
||||
target_sp->GetArchitecture(), nullptr, nullptr));
|
||||
if (disassembler_sp) {
|
||||
lldb::addr_t addr = base_addr + start_offset;
|
||||
lldb_private::Address so_addr;
|
||||
bool data_from_file = true;
|
||||
if (target_sp->GetSectionLoadList().ResolveLoadAddress(addr, so_addr)) {
|
||||
data_from_file = false;
|
||||
} else {
|
||||
if (target_sp->GetSectionLoadList().IsEmpty() ||
|
||||
!target_sp->GetImages().ResolveFileAddress(addr, so_addr))
|
||||
so_addr.SetRawAddress(addr);
|
||||
}
|
||||
|
||||
size_t bytes_consumed = disassembler_sp->DecodeInstructions(
|
||||
so_addr, DE, start_offset, item_count, false, data_from_file);
|
||||
|
||||
if (bytes_consumed) {
|
||||
offset += bytes_consumed;
|
||||
const bool show_address = base_addr != LLDB_INVALID_ADDRESS;
|
||||
const bool show_bytes = true;
|
||||
ExecutionContext exe_ctx;
|
||||
exe_scope->CalculateExecutionContext(exe_ctx);
|
||||
disassembler_sp->GetInstructionList().Dump(s, show_address,
|
||||
show_bytes, &exe_ctx);
|
||||
}
|
||||
}
|
||||
} else
|
||||
s->Printf("invalid target");
|
||||
|
||||
return offset;
|
||||
}
|
||||
|
||||
if ((item_format == eFormatOSType || item_format == eFormatAddressInfo) &&
|
||||
item_byte_size > 8)
|
||||
item_format = eFormatHex;
|
||||
|
||||
lldb::offset_t line_start_offset = start_offset;
|
||||
for (uint32_t count = 0; DE.ValidOffset(offset) && count < item_count;
|
||||
++count) {
|
||||
if ((count % num_per_line) == 0) {
|
||||
if (count > 0) {
|
||||
if (item_format == eFormatBytesWithASCII &&
|
||||
offset > line_start_offset) {
|
||||
s->Printf("%*s",
|
||||
static_cast<int>(
|
||||
(num_per_line - (offset - line_start_offset)) * 3 + 2),
|
||||
"");
|
||||
DumpDataExtractor(DE, s, line_start_offset, eFormatCharPrintable, 1,
|
||||
offset - line_start_offset, SIZE_MAX,
|
||||
LLDB_INVALID_ADDRESS, 0, 0);
|
||||
}
|
||||
s->EOL();
|
||||
}
|
||||
if (base_addr != LLDB_INVALID_ADDRESS)
|
||||
s->Printf("0x%8.8" PRIx64 ": ",
|
||||
(uint64_t)(base_addr +
|
||||
(offset - start_offset) / DE.getTargetByteSize()));
|
||||
|
||||
line_start_offset = offset;
|
||||
} else if (item_format != eFormatChar &&
|
||||
item_format != eFormatCharPrintable &&
|
||||
item_format != eFormatCharArray && count > 0) {
|
||||
s->PutChar(' ');
|
||||
}
|
||||
|
||||
switch (item_format) {
|
||||
case eFormatBoolean:
|
||||
if (item_byte_size <= 8)
|
||||
s->Printf("%s", DE.GetMaxU64Bitfield(&offset, item_byte_size,
|
||||
item_bit_size, item_bit_offset)
|
||||
? "true"
|
||||
: "false");
|
||||
else {
|
||||
s->Printf("error: unsupported byte size (%" PRIu64
|
||||
") for boolean format",
|
||||
(uint64_t)item_byte_size);
|
||||
return offset;
|
||||
}
|
||||
break;
|
||||
|
||||
case eFormatBinary:
|
||||
if (item_byte_size <= 8) {
|
||||
uint64_t uval64 = DE.GetMaxU64Bitfield(&offset, item_byte_size,
|
||||
item_bit_size, item_bit_offset);
|
||||
// Avoid std::bitset<64>::to_string() since it is missing in
|
||||
// earlier C++ libraries
|
||||
std::string binary_value(64, '0');
|
||||
std::bitset<64> bits(uval64);
|
||||
for (uint32_t i = 0; i < 64; ++i)
|
||||
if (bits[i])
|
||||
binary_value[64 - 1 - i] = '1';
|
||||
if (item_bit_size > 0)
|
||||
s->Printf("0b%s", binary_value.c_str() + 64 - item_bit_size);
|
||||
else if (item_byte_size > 0 && item_byte_size <= 8)
|
||||
s->Printf("0b%s", binary_value.c_str() + 64 - item_byte_size * 8);
|
||||
} else {
|
||||
const bool is_signed = false;
|
||||
const unsigned radix = 2;
|
||||
offset = DumpAPInt(s, DE, offset, item_byte_size, is_signed, radix);
|
||||
}
|
||||
break;
|
||||
|
||||
case eFormatBytes:
|
||||
case eFormatBytesWithASCII:
|
||||
for (uint32_t i = 0; i < item_byte_size; ++i) {
|
||||
s->Printf("%2.2x", DE.GetU8(&offset));
|
||||
}
|
||||
|
||||
// Put an extra space between the groups of bytes if more than one
|
||||
// is being dumped in a group (item_byte_size is more than 1).
|
||||
if (item_byte_size > 1)
|
||||
s->PutChar(' ');
|
||||
break;
|
||||
|
||||
case eFormatChar:
|
||||
case eFormatCharPrintable:
|
||||
case eFormatCharArray: {
|
||||
// If we are only printing one character surround it with single
|
||||
// quotes
|
||||
if (item_count == 1 && item_format == eFormatChar)
|
||||
s->PutChar('\'');
|
||||
|
||||
const uint64_t ch = DE.GetMaxU64Bitfield(&offset, item_byte_size,
|
||||
item_bit_size, item_bit_offset);
|
||||
if (isprint(ch))
|
||||
s->Printf("%c", (char)ch);
|
||||
else if (item_format != eFormatCharPrintable) {
|
||||
switch (ch) {
|
||||
case '\033':
|
||||
s->Printf("\\e");
|
||||
break;
|
||||
case '\a':
|
||||
s->Printf("\\a");
|
||||
break;
|
||||
case '\b':
|
||||
s->Printf("\\b");
|
||||
break;
|
||||
case '\f':
|
||||
s->Printf("\\f");
|
||||
break;
|
||||
case '\n':
|
||||
s->Printf("\\n");
|
||||
break;
|
||||
case '\r':
|
||||
s->Printf("\\r");
|
||||
break;
|
||||
case '\t':
|
||||
s->Printf("\\t");
|
||||
break;
|
||||
case '\v':
|
||||
s->Printf("\\v");
|
||||
break;
|
||||
case '\0':
|
||||
s->Printf("\\0");
|
||||
break;
|
||||
default:
|
||||
if (item_byte_size == 1)
|
||||
s->Printf("\\x%2.2x", (uint8_t)ch);
|
||||
else
|
||||
s->Printf("%" PRIu64, ch);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
s->PutChar(NON_PRINTABLE_CHAR);
|
||||
}
|
||||
|
||||
// If we are only printing one character surround it with single quotes
|
||||
if (item_count == 1 && item_format == eFormatChar)
|
||||
s->PutChar('\'');
|
||||
} break;
|
||||
|
||||
case eFormatEnum: // Print enum value as a signed integer when we don't get
|
||||
// the enum type
|
||||
case eFormatDecimal:
|
||||
if (item_byte_size <= 8)
|
||||
s->Printf("%" PRId64,
|
||||
DE.GetMaxS64Bitfield(&offset, item_byte_size, item_bit_size,
|
||||
item_bit_offset));
|
||||
else {
|
||||
const bool is_signed = true;
|
||||
const unsigned radix = 10;
|
||||
offset = DumpAPInt(s, DE, offset, item_byte_size, is_signed, radix);
|
||||
}
|
||||
break;
|
||||
|
||||
case eFormatUnsigned:
|
||||
if (item_byte_size <= 8)
|
||||
s->Printf("%" PRIu64,
|
||||
DE.GetMaxU64Bitfield(&offset, item_byte_size, item_bit_size,
|
||||
item_bit_offset));
|
||||
else {
|
||||
const bool is_signed = false;
|
||||
const unsigned radix = 10;
|
||||
offset = DumpAPInt(s, DE, offset, item_byte_size, is_signed, radix);
|
||||
}
|
||||
break;
|
||||
|
||||
case eFormatOctal:
|
||||
if (item_byte_size <= 8)
|
||||
s->Printf("0%" PRIo64,
|
||||
DE.GetMaxS64Bitfield(&offset, item_byte_size, item_bit_size,
|
||||
item_bit_offset));
|
||||
else {
|
||||
const bool is_signed = false;
|
||||
const unsigned radix = 8;
|
||||
offset = DumpAPInt(s, DE, offset, item_byte_size, is_signed, radix);
|
||||
}
|
||||
break;
|
||||
|
||||
case eFormatOSType: {
|
||||
uint64_t uval64 = DE.GetMaxU64Bitfield(&offset, item_byte_size,
|
||||
item_bit_size, item_bit_offset);
|
||||
s->PutChar('\'');
|
||||
for (uint32_t i = 0; i < item_byte_size; ++i) {
|
||||
uint8_t ch = (uint8_t)(uval64 >> ((item_byte_size - i - 1) * 8));
|
||||
if (isprint(ch))
|
||||
s->Printf("%c", ch);
|
||||
else {
|
||||
switch (ch) {
|
||||
case '\033':
|
||||
s->Printf("\\e");
|
||||
break;
|
||||
case '\a':
|
||||
s->Printf("\\a");
|
||||
break;
|
||||
case '\b':
|
||||
s->Printf("\\b");
|
||||
break;
|
||||
case '\f':
|
||||
s->Printf("\\f");
|
||||
break;
|
||||
case '\n':
|
||||
s->Printf("\\n");
|
||||
break;
|
||||
case '\r':
|
||||
s->Printf("\\r");
|
||||
break;
|
||||
case '\t':
|
||||
s->Printf("\\t");
|
||||
break;
|
||||
case '\v':
|
||||
s->Printf("\\v");
|
||||
break;
|
||||
case '\0':
|
||||
s->Printf("\\0");
|
||||
break;
|
||||
default:
|
||||
s->Printf("\\x%2.2x", ch);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
s->PutChar('\'');
|
||||
} break;
|
||||
|
||||
case eFormatCString: {
|
||||
const char *cstr = DE.GetCStr(&offset);
|
||||
|
||||
if (!cstr) {
|
||||
s->Printf("NULL");
|
||||
offset = LLDB_INVALID_OFFSET;
|
||||
} else {
|
||||
s->PutChar('\"');
|
||||
|
||||
while (const char c = *cstr) {
|
||||
if (isprint(c)) {
|
||||
s->PutChar(c);
|
||||
} else {
|
||||
switch (c) {
|
||||
case '\033':
|
||||
s->Printf("\\e");
|
||||
break;
|
||||
case '\a':
|
||||
s->Printf("\\a");
|
||||
break;
|
||||
case '\b':
|
||||
s->Printf("\\b");
|
||||
break;
|
||||
case '\f':
|
||||
s->Printf("\\f");
|
||||
break;
|
||||
case '\n':
|
||||
s->Printf("\\n");
|
||||
break;
|
||||
case '\r':
|
||||
s->Printf("\\r");
|
||||
break;
|
||||
case '\t':
|
||||
s->Printf("\\t");
|
||||
break;
|
||||
case '\v':
|
||||
s->Printf("\\v");
|
||||
break;
|
||||
default:
|
||||
s->Printf("\\x%2.2x", c);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
++cstr;
|
||||
}
|
||||
|
||||
s->PutChar('\"');
|
||||
}
|
||||
} break;
|
||||
|
||||
case eFormatPointer:
|
||||
s->Address(DE.GetMaxU64Bitfield(&offset, item_byte_size, item_bit_size,
|
||||
item_bit_offset),
|
||||
sizeof(addr_t));
|
||||
break;
|
||||
|
||||
case eFormatComplexInteger: {
|
||||
size_t complex_int_byte_size = item_byte_size / 2;
|
||||
|
||||
if (complex_int_byte_size > 0 && complex_int_byte_size <= 8) {
|
||||
s->Printf("%" PRIu64,
|
||||
DE.GetMaxU64Bitfield(&offset, complex_int_byte_size, 0, 0));
|
||||
s->Printf(" + %" PRIu64 "i",
|
||||
DE.GetMaxU64Bitfield(&offset, complex_int_byte_size, 0, 0));
|
||||
} else {
|
||||
s->Printf("error: unsupported byte size (%" PRIu64
|
||||
") for complex integer format",
|
||||
(uint64_t)item_byte_size);
|
||||
return offset;
|
||||
}
|
||||
} break;
|
||||
|
||||
case eFormatComplex:
|
||||
if (sizeof(float) * 2 == item_byte_size) {
|
||||
float f32_1 = DE.GetFloat(&offset);
|
||||
float f32_2 = DE.GetFloat(&offset);
|
||||
|
||||
s->Printf("%g + %gi", f32_1, f32_2);
|
||||
break;
|
||||
} else if (sizeof(double) * 2 == item_byte_size) {
|
||||
double d64_1 = DE.GetDouble(&offset);
|
||||
double d64_2 = DE.GetDouble(&offset);
|
||||
|
||||
s->Printf("%lg + %lgi", d64_1, d64_2);
|
||||
break;
|
||||
} else if (sizeof(long double) * 2 == item_byte_size) {
|
||||
long double ld64_1 = DE.GetLongDouble(&offset);
|
||||
long double ld64_2 = DE.GetLongDouble(&offset);
|
||||
s->Printf("%Lg + %Lgi", ld64_1, ld64_2);
|
||||
break;
|
||||
} else {
|
||||
s->Printf("error: unsupported byte size (%" PRIu64
|
||||
") for complex float format",
|
||||
(uint64_t)item_byte_size);
|
||||
return offset;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
case eFormatDefault:
|
||||
case eFormatHex:
|
||||
case eFormatHexUppercase: {
|
||||
bool wantsuppercase = (item_format == eFormatHexUppercase);
|
||||
switch (item_byte_size) {
|
||||
case 1:
|
||||
case 2:
|
||||
case 4:
|
||||
case 8:
|
||||
s->Printf(wantsuppercase ? "0x%*.*" PRIX64 : "0x%*.*" PRIx64,
|
||||
(int)(2 * item_byte_size), (int)(2 * item_byte_size),
|
||||
DE.GetMaxU64Bitfield(&offset, item_byte_size, item_bit_size,
|
||||
item_bit_offset));
|
||||
break;
|
||||
default: {
|
||||
assert(item_bit_size == 0 && item_bit_offset == 0);
|
||||
const uint8_t *bytes =
|
||||
(const uint8_t *)DE.GetData(&offset, item_byte_size);
|
||||
if (bytes) {
|
||||
s->PutCString("0x");
|
||||
uint32_t idx;
|
||||
if (DE.GetByteOrder() == eByteOrderBig) {
|
||||
for (idx = 0; idx < item_byte_size; ++idx)
|
||||
s->Printf(wantsuppercase ? "%2.2X" : "%2.2x", bytes[idx]);
|
||||
} else {
|
||||
for (idx = 0; idx < item_byte_size; ++idx)
|
||||
s->Printf(wantsuppercase ? "%2.2X" : "%2.2x",
|
||||
bytes[item_byte_size - 1 - idx]);
|
||||
}
|
||||
}
|
||||
} break;
|
||||
}
|
||||
} break;
|
||||
|
||||
case eFormatFloat: {
|
||||
TargetSP target_sp;
|
||||
bool used_apfloat = false;
|
||||
if (exe_scope)
|
||||
target_sp = exe_scope->CalculateTarget();
|
||||
if (target_sp) {
|
||||
ClangASTContext *clang_ast = target_sp->GetScratchClangASTContext();
|
||||
if (clang_ast) {
|
||||
clang::ASTContext *ast = clang_ast->getASTContext();
|
||||
if (ast) {
|
||||
llvm::SmallVector<char, 256> sv;
|
||||
// Show full precision when printing float values
|
||||
const unsigned format_precision = 0;
|
||||
const unsigned format_max_padding = 100;
|
||||
size_t item_bit_size = item_byte_size * 8;
|
||||
|
||||
if (item_bit_size == ast->getTypeSize(ast->FloatTy)) {
|
||||
llvm::APInt apint(item_bit_size,
|
||||
DE.GetMaxU64(&offset, item_byte_size));
|
||||
llvm::APFloat apfloat(ast->getFloatTypeSemantics(ast->FloatTy),
|
||||
apint);
|
||||
apfloat.toString(sv, format_precision, format_max_padding);
|
||||
} else if (item_bit_size == ast->getTypeSize(ast->DoubleTy)) {
|
||||
llvm::APInt apint;
|
||||
if (GetAPInt(DE, &offset, item_byte_size, apint)) {
|
||||
llvm::APFloat apfloat(ast->getFloatTypeSemantics(ast->DoubleTy),
|
||||
apint);
|
||||
apfloat.toString(sv, format_precision, format_max_padding);
|
||||
}
|
||||
} else if (item_bit_size == ast->getTypeSize(ast->LongDoubleTy)) {
|
||||
const auto &semantics =
|
||||
ast->getFloatTypeSemantics(ast->LongDoubleTy);
|
||||
const auto byte_size =
|
||||
(llvm::APFloat::getSizeInBits(semantics) + 7) / 8;
|
||||
|
||||
llvm::APInt apint;
|
||||
if (GetAPInt(DE, &offset, byte_size, apint)) {
|
||||
llvm::APFloat apfloat(semantics, apint);
|
||||
apfloat.toString(sv, format_precision, format_max_padding);
|
||||
}
|
||||
} else if (item_bit_size == ast->getTypeSize(ast->HalfTy)) {
|
||||
llvm::APInt apint(item_bit_size, DE.GetU16(&offset));
|
||||
llvm::APFloat apfloat(ast->getFloatTypeSemantics(ast->HalfTy),
|
||||
apint);
|
||||
apfloat.toString(sv, format_precision, format_max_padding);
|
||||
}
|
||||
|
||||
if (!sv.empty()) {
|
||||
s->Printf("%*.*s", (int)sv.size(), (int)sv.size(), sv.data());
|
||||
used_apfloat = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!used_apfloat) {
|
||||
std::ostringstream ss;
|
||||
if (item_byte_size == sizeof(float) || item_byte_size == 2) {
|
||||
float f;
|
||||
if (item_byte_size == 2) {
|
||||
uint16_t half = DE.GetU16(&offset);
|
||||
f = half2float(half);
|
||||
} else {
|
||||
f = DE.GetFloat(&offset);
|
||||
}
|
||||
ss.precision(std::numeric_limits<float>::digits10);
|
||||
ss << f;
|
||||
} else if (item_byte_size == sizeof(double)) {
|
||||
ss.precision(std::numeric_limits<double>::digits10);
|
||||
ss << DE.GetDouble(&offset);
|
||||
} else if (item_byte_size == sizeof(long double) ||
|
||||
item_byte_size == 10) {
|
||||
ss.precision(std::numeric_limits<long double>::digits10);
|
||||
ss << DE.GetLongDouble(&offset);
|
||||
} else {
|
||||
s->Printf("error: unsupported byte size (%" PRIu64
|
||||
") for float format",
|
||||
(uint64_t)item_byte_size);
|
||||
return offset;
|
||||
}
|
||||
ss.flush();
|
||||
s->Printf("%s", ss.str().c_str());
|
||||
}
|
||||
} break;
|
||||
|
||||
case eFormatUnicode16:
|
||||
s->Printf("U+%4.4x", DE.GetU16(&offset));
|
||||
break;
|
||||
|
||||
case eFormatUnicode32:
|
||||
s->Printf("U+0x%8.8x", DE.GetU32(&offset));
|
||||
break;
|
||||
|
||||
case eFormatAddressInfo: {
|
||||
addr_t addr = DE.GetMaxU64Bitfield(&offset, item_byte_size, item_bit_size,
|
||||
item_bit_offset);
|
||||
s->Printf("0x%*.*" PRIx64, (int)(2 * item_byte_size),
|
||||
(int)(2 * item_byte_size), addr);
|
||||
if (exe_scope) {
|
||||
TargetSP target_sp(exe_scope->CalculateTarget());
|
||||
lldb_private::Address so_addr;
|
||||
if (target_sp) {
|
||||
if (target_sp->GetSectionLoadList().ResolveLoadAddress(addr,
|
||||
so_addr)) {
|
||||
s->PutChar(' ');
|
||||
so_addr.Dump(s, exe_scope, Address::DumpStyleResolvedDescription,
|
||||
Address::DumpStyleModuleWithFileAddress);
|
||||
} else {
|
||||
so_addr.SetOffset(addr);
|
||||
so_addr.Dump(s, exe_scope,
|
||||
Address::DumpStyleResolvedPointerDescription);
|
||||
}
|
||||
}
|
||||
}
|
||||
} break;
|
||||
|
||||
case eFormatHexFloat:
|
||||
if (sizeof(float) == item_byte_size) {
|
||||
char float_cstr[256];
|
||||
llvm::APFloat ap_float(DE.GetFloat(&offset));
|
||||
ap_float.convertToHexString(float_cstr, 0, false,
|
||||
llvm::APFloat::rmNearestTiesToEven);
|
||||
s->Printf("%s", float_cstr);
|
||||
break;
|
||||
} else if (sizeof(double) == item_byte_size) {
|
||||
char float_cstr[256];
|
||||
llvm::APFloat ap_float(DE.GetDouble(&offset));
|
||||
ap_float.convertToHexString(float_cstr, 0, false,
|
||||
llvm::APFloat::rmNearestTiesToEven);
|
||||
s->Printf("%s", float_cstr);
|
||||
break;
|
||||
} else {
|
||||
s->Printf("error: unsupported byte size (%" PRIu64
|
||||
") for hex float format",
|
||||
(uint64_t)item_byte_size);
|
||||
return offset;
|
||||
}
|
||||
break;
|
||||
|
||||
// please keep the single-item formats below in sync with
|
||||
// FormatManager::GetSingleItemFormat
|
||||
// if you fail to do so, users will start getting different outputs
|
||||
// depending on internal
|
||||
// implementation details they should not care about ||
|
||||
case eFormatVectorOfChar: // ||
|
||||
s->PutChar('{'); // \/
|
||||
offset =
|
||||
DumpDataExtractor(DE, s, offset, eFormatCharArray, 1, item_byte_size,
|
||||
item_byte_size, LLDB_INVALID_ADDRESS, 0, 0);
|
||||
s->PutChar('}');
|
||||
break;
|
||||
|
||||
case eFormatVectorOfSInt8:
|
||||
s->PutChar('{');
|
||||
offset =
|
||||
DumpDataExtractor(DE, s, offset, eFormatDecimal, 1, item_byte_size,
|
||||
item_byte_size, LLDB_INVALID_ADDRESS, 0, 0);
|
||||
s->PutChar('}');
|
||||
break;
|
||||
|
||||
case eFormatVectorOfUInt8:
|
||||
s->PutChar('{');
|
||||
offset = DumpDataExtractor(DE, s, offset, eFormatHex, 1, item_byte_size,
|
||||
item_byte_size, LLDB_INVALID_ADDRESS, 0, 0);
|
||||
s->PutChar('}');
|
||||
break;
|
||||
|
||||
case eFormatVectorOfSInt16:
|
||||
s->PutChar('{');
|
||||
offset = DumpDataExtractor(
|
||||
DE, s, offset, eFormatDecimal, sizeof(uint16_t),
|
||||
item_byte_size / sizeof(uint16_t), item_byte_size / sizeof(uint16_t),
|
||||
LLDB_INVALID_ADDRESS, 0, 0);
|
||||
s->PutChar('}');
|
||||
break;
|
||||
|
||||
case eFormatVectorOfUInt16:
|
||||
s->PutChar('{');
|
||||
offset = DumpDataExtractor(DE, s, offset, eFormatHex, sizeof(uint16_t),
|
||||
item_byte_size / sizeof(uint16_t),
|
||||
item_byte_size / sizeof(uint16_t),
|
||||
LLDB_INVALID_ADDRESS, 0, 0);
|
||||
s->PutChar('}');
|
||||
break;
|
||||
|
||||
case eFormatVectorOfSInt32:
|
||||
s->PutChar('{');
|
||||
offset = DumpDataExtractor(
|
||||
DE, s, offset, eFormatDecimal, sizeof(uint32_t),
|
||||
item_byte_size / sizeof(uint32_t), item_byte_size / sizeof(uint32_t),
|
||||
LLDB_INVALID_ADDRESS, 0, 0);
|
||||
s->PutChar('}');
|
||||
break;
|
||||
|
||||
case eFormatVectorOfUInt32:
|
||||
s->PutChar('{');
|
||||
offset = DumpDataExtractor(DE, s, offset, eFormatHex, sizeof(uint32_t),
|
||||
item_byte_size / sizeof(uint32_t),
|
||||
item_byte_size / sizeof(uint32_t),
|
||||
LLDB_INVALID_ADDRESS, 0, 0);
|
||||
s->PutChar('}');
|
||||
break;
|
||||
|
||||
case eFormatVectorOfSInt64:
|
||||
s->PutChar('{');
|
||||
offset = DumpDataExtractor(
|
||||
DE, s, offset, eFormatDecimal, sizeof(uint64_t),
|
||||
item_byte_size / sizeof(uint64_t), item_byte_size / sizeof(uint64_t),
|
||||
LLDB_INVALID_ADDRESS, 0, 0);
|
||||
s->PutChar('}');
|
||||
break;
|
||||
|
||||
case eFormatVectorOfUInt64:
|
||||
s->PutChar('{');
|
||||
offset = DumpDataExtractor(DE, s, offset, eFormatHex, sizeof(uint64_t),
|
||||
item_byte_size / sizeof(uint64_t),
|
||||
item_byte_size / sizeof(uint64_t),
|
||||
LLDB_INVALID_ADDRESS, 0, 0);
|
||||
s->PutChar('}');
|
||||
break;
|
||||
|
||||
case eFormatVectorOfFloat16:
|
||||
s->PutChar('{');
|
||||
offset =
|
||||
DumpDataExtractor(DE, s, offset, eFormatFloat, 2, item_byte_size / 2,
|
||||
item_byte_size / 2, LLDB_INVALID_ADDRESS, 0, 0);
|
||||
s->PutChar('}');
|
||||
break;
|
||||
|
||||
case eFormatVectorOfFloat32:
|
||||
s->PutChar('{');
|
||||
offset =
|
||||
DumpDataExtractor(DE, s, offset, eFormatFloat, 4, item_byte_size / 4,
|
||||
item_byte_size / 4, LLDB_INVALID_ADDRESS, 0, 0);
|
||||
s->PutChar('}');
|
||||
break;
|
||||
|
||||
case eFormatVectorOfFloat64:
|
||||
s->PutChar('{');
|
||||
offset =
|
||||
DumpDataExtractor(DE, s, offset, eFormatFloat, 8, item_byte_size / 8,
|
||||
item_byte_size / 8, LLDB_INVALID_ADDRESS, 0, 0);
|
||||
s->PutChar('}');
|
||||
break;
|
||||
|
||||
case eFormatVectorOfUInt128:
|
||||
s->PutChar('{');
|
||||
offset =
|
||||
DumpDataExtractor(DE, s, offset, eFormatHex, 16, item_byte_size / 16,
|
||||
item_byte_size / 16, LLDB_INVALID_ADDRESS, 0, 0);
|
||||
s->PutChar('}');
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (item_format == eFormatBytesWithASCII && offset > line_start_offset) {
|
||||
s->Printf("%*s", static_cast<int>(
|
||||
(num_per_line - (offset - line_start_offset)) * 3 + 2),
|
||||
"");
|
||||
DumpDataExtractor(DE, s, line_start_offset, eFormatCharPrintable, 1,
|
||||
offset - line_start_offset, SIZE_MAX,
|
||||
LLDB_INVALID_ADDRESS, 0, 0);
|
||||
}
|
||||
return offset; // Return the offset at which we ended up
|
||||
}
|
|
@ -15,6 +15,7 @@
|
|||
// Project includes
|
||||
#include "lldb/Core/Broadcaster.h"
|
||||
#include "lldb/Core/DataExtractor.h"
|
||||
#include "lldb/Core/DumpDataExtractor.h"
|
||||
#include "lldb/Core/Event.h"
|
||||
#include "lldb/Core/State.h"
|
||||
#include "lldb/Target/Process.h"
|
||||
|
@ -140,8 +141,8 @@ void EventDataBytes::Dump(Stream *s) const {
|
|||
} else if (!m_bytes.empty()) {
|
||||
DataExtractor data;
|
||||
data.SetData(m_bytes.data(), m_bytes.size(), endian::InlHostByteOrder());
|
||||
data.Dump(s, 0, eFormatBytes, 1, m_bytes.size(), 32, LLDB_INVALID_ADDRESS,
|
||||
0, 0);
|
||||
DumpDataExtractor(data, s, 0, eFormatBytes, 1, m_bytes.size(), 32,
|
||||
LLDB_INVALID_ADDRESS, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
|
||||
// Project includes
|
||||
#include "lldb/Core/DataExtractor.h"
|
||||
#include "lldb/Core/DumpDataExtractor.h"
|
||||
#include "lldb/Core/Scalar.h"
|
||||
#include "lldb/Host/StringConvert.h"
|
||||
#include "lldb/Interpreter/Args.h"
|
||||
|
@ -76,15 +77,15 @@ bool RegisterValue::Dump(Stream *s, const RegisterInfo *reg_info,
|
|||
if (format == eFormatDefault)
|
||||
format = reg_info->format;
|
||||
|
||||
data.Dump(s,
|
||||
0, // Offset in "data"
|
||||
format, // Format to use when dumping
|
||||
reg_info->byte_size, // item_byte_size
|
||||
1, // item_count
|
||||
UINT32_MAX, // num_per_line
|
||||
LLDB_INVALID_ADDRESS, // base_addr
|
||||
0, // item_bit_size
|
||||
0); // item_bit_offset
|
||||
DumpDataExtractor(data, s,
|
||||
0, // Offset in "data"
|
||||
format, // Format to use when dumping
|
||||
reg_info->byte_size, // item_byte_size
|
||||
1, // item_count
|
||||
UINT32_MAX, // num_per_line
|
||||
LLDB_INVALID_ADDRESS, // base_addr
|
||||
0, // item_bit_size
|
||||
0); // item_bit_offset
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
|
|
@ -19,6 +19,8 @@
|
|||
#include "lldb/lldb-enumerations.h"
|
||||
#include "lldb/lldb-public.h"
|
||||
|
||||
#include "lldb/Core/DataExtractor.h"
|
||||
#include "lldb/Core/DumpDataExtractor.h"
|
||||
#include "lldb/DataFormatters/FormatManager.h"
|
||||
#include "lldb/Symbol/CompilerType.h"
|
||||
#include "lldb/Symbol/SymbolContext.h"
|
||||
|
@ -60,9 +62,9 @@ bool TypeFormatImpl_Format::FormatObject(ValueObject *valobj,
|
|||
return false;
|
||||
|
||||
StreamString reg_sstr;
|
||||
data.Dump(®_sstr, 0, GetFormat(), reg_info->byte_size, 1, UINT32_MAX,
|
||||
LLDB_INVALID_ADDRESS, 0, 0,
|
||||
exe_ctx.GetBestExecutionContextScope());
|
||||
DumpDataExtractor(data, ®_sstr, 0, GetFormat(), reg_info->byte_size,
|
||||
1, UINT32_MAX, LLDB_INVALID_ADDRESS, 0, 0,
|
||||
exe_ctx.GetBestExecutionContextScope());
|
||||
dest = reg_sstr.GetString();
|
||||
}
|
||||
} else {
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
// Other libraries and framework includes
|
||||
// Project includes
|
||||
#include "lldb/Expression/Materializer.h"
|
||||
#include "lldb/Core/DumpDataExtractor.h"
|
||||
#include "lldb/Core/RegisterValue.h"
|
||||
#include "lldb/Core/ValueObjectConstResult.h"
|
||||
#include "lldb/Core/ValueObjectVariable.h"
|
||||
|
@ -29,6 +30,19 @@
|
|||
|
||||
using namespace lldb_private;
|
||||
|
||||
static void DumpHexBytes(Stream *s, const void *src, size_t src_len,
|
||||
uint32_t bytes_per_line, lldb::addr_t base_addr) {
|
||||
DataExtractor data(src, src_len, lldb::eByteOrderLittle, 4);
|
||||
DumpDataExtractor(data, s,
|
||||
0, // Offset into "src"
|
||||
lldb::eFormatBytes, // Dump as hex bytes
|
||||
1, // Size of each item is 1 for single bytes
|
||||
src_len, // Number of bytes
|
||||
bytes_per_line, // Num bytes per line
|
||||
base_addr, // Base address
|
||||
0, 0); // Bitfield info
|
||||
}
|
||||
|
||||
uint32_t Materializer::AddStructMember(Entity &entity) {
|
||||
uint32_t size = entity.GetSize();
|
||||
uint32_t alignment = entity.GetAlignment();
|
||||
|
@ -370,11 +384,8 @@ public:
|
|||
if (!err.Success()) {
|
||||
dump_stream.Printf(" <could not be read>\n");
|
||||
} else {
|
||||
DataExtractor extractor(data.GetBytes(), data.GetByteSize(),
|
||||
map.GetByteOrder(), map.GetAddressByteSize());
|
||||
|
||||
extractor.DumpHexBytes(&dump_stream, data.GetBytes(),
|
||||
data.GetByteSize(), 16, load_addr);
|
||||
DumpHexBytes(&dump_stream, data.GetBytes(), data.GetByteSize(), 16,
|
||||
load_addr);
|
||||
|
||||
dump_stream.PutChar('\n');
|
||||
}
|
||||
|
@ -398,11 +409,8 @@ public:
|
|||
if (!err.Success()) {
|
||||
dump_stream.Printf(" <could not be read>\n");
|
||||
} else {
|
||||
DataExtractor extractor(data.GetBytes(), data.GetByteSize(),
|
||||
map.GetByteOrder(), map.GetAddressByteSize());
|
||||
|
||||
extractor.DumpHexBytes(&dump_stream, data.GetBytes(),
|
||||
data.GetByteSize(), 16, target_address);
|
||||
DumpHexBytes(&dump_stream, data.GetBytes(), data.GetByteSize(), 16,
|
||||
target_address);
|
||||
|
||||
dump_stream.PutChar('\n');
|
||||
}
|
||||
|
@ -711,8 +719,8 @@ public:
|
|||
DataExtractor extractor(data.GetBytes(), data.GetByteSize(),
|
||||
map.GetByteOrder(), map.GetAddressByteSize());
|
||||
|
||||
extractor.DumpHexBytes(&dump_stream, data.GetBytes(),
|
||||
data.GetByteSize(), 16, load_addr);
|
||||
DumpHexBytes(&dump_stream, data.GetBytes(), data.GetByteSize(), 16,
|
||||
load_addr);
|
||||
|
||||
lldb::offset_t offset;
|
||||
|
||||
|
@ -739,11 +747,8 @@ public:
|
|||
if (!err.Success()) {
|
||||
dump_stream.Printf(" <could not be read>\n");
|
||||
} else {
|
||||
DataExtractor extractor(data.GetBytes(), data.GetByteSize(),
|
||||
map.GetByteOrder(), map.GetAddressByteSize());
|
||||
|
||||
extractor.DumpHexBytes(&dump_stream, data.GetBytes(),
|
||||
data.GetByteSize(), 16, load_addr);
|
||||
DumpHexBytes(&dump_stream, data.GetBytes(), data.GetByteSize(), 16,
|
||||
load_addr);
|
||||
|
||||
dump_stream.PutChar('\n');
|
||||
}
|
||||
|
@ -981,8 +986,8 @@ public:
|
|||
DataExtractor extractor(data.GetBytes(), data.GetByteSize(),
|
||||
map.GetByteOrder(), map.GetAddressByteSize());
|
||||
|
||||
extractor.DumpHexBytes(&dump_stream, data.GetBytes(),
|
||||
data.GetByteSize(), 16, load_addr);
|
||||
DumpHexBytes(&dump_stream, data.GetBytes(), data.GetByteSize(), 16,
|
||||
load_addr);
|
||||
|
||||
lldb::offset_t offset;
|
||||
|
||||
|
@ -1009,11 +1014,8 @@ public:
|
|||
if (!err.Success()) {
|
||||
dump_stream.Printf(" <could not be read>\n");
|
||||
} else {
|
||||
DataExtractor extractor(data.GetBytes(), data.GetByteSize(),
|
||||
map.GetByteOrder(), map.GetAddressByteSize());
|
||||
|
||||
extractor.DumpHexBytes(&dump_stream, data.GetBytes(),
|
||||
data.GetByteSize(), 16, load_addr);
|
||||
DumpHexBytes(&dump_stream, data.GetBytes(), data.GetByteSize(), 16,
|
||||
load_addr);
|
||||
|
||||
dump_stream.PutChar('\n');
|
||||
}
|
||||
|
@ -1146,11 +1148,8 @@ public:
|
|||
if (!err.Success()) {
|
||||
dump_stream.Printf(" <could not be read>\n");
|
||||
} else {
|
||||
DataExtractor extractor(data.GetBytes(), data.GetByteSize(),
|
||||
map.GetByteOrder(), map.GetAddressByteSize());
|
||||
|
||||
extractor.DumpHexBytes(&dump_stream, data.GetBytes(),
|
||||
data.GetByteSize(), 16, load_addr);
|
||||
DumpHexBytes(&dump_stream, data.GetBytes(), data.GetByteSize(), 16,
|
||||
load_addr);
|
||||
|
||||
dump_stream.PutChar('\n');
|
||||
}
|
||||
|
@ -1322,11 +1321,8 @@ public:
|
|||
if (!err.Success()) {
|
||||
dump_stream.Printf(" <could not be read>\n");
|
||||
} else {
|
||||
DataExtractor extractor(data.GetBytes(), data.GetByteSize(),
|
||||
map.GetByteOrder(), map.GetAddressByteSize());
|
||||
|
||||
extractor.DumpHexBytes(&dump_stream, data.GetBytes(),
|
||||
data.GetByteSize(), 16, load_addr);
|
||||
DumpHexBytes(&dump_stream, data.GetBytes(), data.GetByteSize(), 16,
|
||||
load_addr);
|
||||
|
||||
dump_stream.PutChar('\n');
|
||||
}
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
|
||||
#include "lldb/Breakpoint/StoppointCallbackContext.h"
|
||||
#include "lldb/Core/Debugger.h"
|
||||
#include "lldb/Core/DumpDataExtractor.h"
|
||||
#include "lldb/Core/PluginManager.h"
|
||||
#include "lldb/Core/ValueObjectVariable.h"
|
||||
#include "lldb/DataFormatters/DumpValueObjectOptions.h"
|
||||
|
@ -3409,8 +3410,9 @@ bool RenderScriptRuntime::DumpAllocation(Stream &strm, StackFrame *frame_ptr,
|
|||
// Print the results to our stream.
|
||||
expr_result->Dump(strm, expr_options);
|
||||
} else {
|
||||
alloc_data.Dump(&strm, offset, format, data_size - padding, 1, 1,
|
||||
LLDB_INVALID_ADDRESS, 0, 0);
|
||||
DumpDataExtractor(alloc_data, &strm, offset, format,
|
||||
data_size - padding, 1, 1, LLDB_INVALID_ADDRESS, 0,
|
||||
0);
|
||||
}
|
||||
offset += data_size;
|
||||
}
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#include "DWARFCompileUnit.h"
|
||||
|
||||
#include "Plugins/Language/ObjC/ObjCLanguage.h"
|
||||
#include "lldb/Core/DumpDataExtractor.h"
|
||||
#include "lldb/Core/Mangled.h"
|
||||
#include "lldb/Core/Module.h"
|
||||
#include "lldb/Core/Timer.h"
|
||||
|
@ -328,10 +329,9 @@ bool DWARFCompileUnit::Verify(Stream *s) const {
|
|||
return true;
|
||||
} else {
|
||||
s->Printf(" 0x%8.8x: ", m_offset);
|
||||
|
||||
m_dwarf2Data->get_debug_info_data().Dump(s, m_offset, lldb::eFormatHex, 1,
|
||||
Size(), 32, LLDB_INVALID_ADDRESS,
|
||||
0, 0);
|
||||
DumpDataExtractor(m_dwarf2Data->get_debug_info_data(), s, m_offset,
|
||||
lldb::eFormatHex, 1, Size(), 32, LLDB_INVALID_ADDRESS, 0,
|
||||
0);
|
||||
s->EOL();
|
||||
if (valid_offset) {
|
||||
if (!length_OK)
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
|
||||
namespace lldb_private {
|
||||
|
||||
class DWARFDataExtractor : public lldb_private::DataExtractor {
|
||||
class DWARFDataExtractor : public DataExtractor {
|
||||
public:
|
||||
DWARFDataExtractor() : DataExtractor(), m_is_dwarf64(false) {}
|
||||
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
#include "lldb/Core/DataBufferHeap.h"
|
||||
#include "lldb/Core/DataExtractor.h"
|
||||
#include "lldb/Core/Disassembler.h"
|
||||
#include "lldb/Core/DumpDataExtractor.h"
|
||||
#include "lldb/Core/FormatEntity.h"
|
||||
#include "lldb/Core/PluginManager.h"
|
||||
#include "lldb/Target/ExecutionContext.h"
|
||||
|
@ -408,7 +409,8 @@ size_t UnwindAssemblyInstEmulation::WriteMemory(
|
|||
StreamString strm;
|
||||
|
||||
strm.PutCString("UnwindAssemblyInstEmulation::WriteMemory (");
|
||||
data.Dump(&strm, 0, eFormatBytes, 1, dst_len, UINT32_MAX, addr, 0, 0);
|
||||
DumpDataExtractor(data, &strm, 0, eFormatBytes, 1, dst_len, UINT32_MAX,
|
||||
addr, 0, 0);
|
||||
strm.PutCString(", context = ");
|
||||
context.Dump(strm, instruction);
|
||||
log->PutString(strm.GetString());
|
||||
|
|
|
@ -73,6 +73,8 @@
|
|||
#include "lldb/Core/ArchSpec.h"
|
||||
#include "lldb/Utility/Flags.h"
|
||||
|
||||
#include "lldb/Core/DataExtractor.h"
|
||||
#include "lldb/Core/DumpDataExtractor.h"
|
||||
#include "lldb/Core/Module.h"
|
||||
#include "lldb/Core/PluginManager.h"
|
||||
#include "lldb/Core/Scalar.h"
|
||||
|
@ -8826,7 +8828,7 @@ ClangASTContext::ConvertStringToFloatValue(lldb::opaque_compiler_type_t type,
|
|||
|
||||
void ClangASTContext::DumpValue(
|
||||
lldb::opaque_compiler_type_t type, ExecutionContext *exe_ctx, Stream *s,
|
||||
lldb::Format format, const lldb_private::DataExtractor &data,
|
||||
lldb::Format format, const DataExtractor &data,
|
||||
lldb::offset_t data_byte_offset, size_t data_byte_size,
|
||||
uint32_t bitfield_bit_size, uint32_t bitfield_bit_offset, bool show_types,
|
||||
bool show_summary, bool verbose, uint32_t depth) {
|
||||
|
@ -9034,8 +9036,9 @@ void ClangASTContext::DumpValue(
|
|||
|
||||
if (is_array_of_characters) {
|
||||
s->PutChar('"');
|
||||
data.Dump(s, data_byte_offset, lldb::eFormatChar, element_byte_size,
|
||||
element_count, UINT32_MAX, LLDB_INVALID_ADDRESS, 0, 0);
|
||||
DumpDataExtractor(data, s, data_byte_offset, lldb::eFormatChar,
|
||||
element_byte_size, element_count, UINT32_MAX,
|
||||
LLDB_INVALID_ADDRESS, 0, 0);
|
||||
s->PutChar('"');
|
||||
return;
|
||||
} else {
|
||||
|
@ -9191,8 +9194,9 @@ void ClangASTContext::DumpValue(
|
|||
|
||||
default:
|
||||
// We are down to a scalar type that we just need to display.
|
||||
data.Dump(s, data_byte_offset, format, data_byte_size, 1, UINT32_MAX,
|
||||
LLDB_INVALID_ADDRESS, bitfield_bit_size, bitfield_bit_offset);
|
||||
DumpDataExtractor(data, s, data_byte_offset, format, data_byte_size, 1,
|
||||
UINT32_MAX, LLDB_INVALID_ADDRESS, bitfield_bit_size,
|
||||
bitfield_bit_offset);
|
||||
|
||||
if (show_summary)
|
||||
DumpSummary(type, exe_ctx, s, data, data_byte_offset, data_byte_size);
|
||||
|
@ -9202,8 +9206,8 @@ void ClangASTContext::DumpValue(
|
|||
|
||||
bool ClangASTContext::DumpTypeValue(
|
||||
lldb::opaque_compiler_type_t type, Stream *s, lldb::Format format,
|
||||
const lldb_private::DataExtractor &data, lldb::offset_t byte_offset,
|
||||
size_t byte_size, uint32_t bitfield_bit_size, uint32_t bitfield_bit_offset,
|
||||
const DataExtractor &data, lldb::offset_t byte_offset, size_t byte_size,
|
||||
uint32_t bitfield_bit_size, uint32_t bitfield_bit_offset,
|
||||
ExecutionContextScope *exe_scope) {
|
||||
if (!type)
|
||||
return false;
|
||||
|
@ -9341,9 +9345,10 @@ bool ClangASTContext::DumpTypeValue(
|
|||
byte_size = 4;
|
||||
break;
|
||||
}
|
||||
return data.Dump(s, byte_offset, format, byte_size, item_count,
|
||||
UINT32_MAX, LLDB_INVALID_ADDRESS, bitfield_bit_size,
|
||||
bitfield_bit_offset, exe_scope);
|
||||
return DumpDataExtractor(data, s, byte_offset, format, byte_size,
|
||||
item_count, UINT32_MAX, LLDB_INVALID_ADDRESS,
|
||||
bitfield_bit_size, bitfield_bit_offset,
|
||||
exe_scope);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -9369,8 +9374,8 @@ void ClangASTContext::DumpSummary(lldb::opaque_compiler_type_t type,
|
|||
else
|
||||
buf.resize(256);
|
||||
|
||||
lldb_private::DataExtractor cstr_data(&buf.front(), buf.size(),
|
||||
process->GetByteOrder(), 4);
|
||||
DataExtractor cstr_data(&buf.front(), buf.size(),
|
||||
process->GetByteOrder(), 4);
|
||||
buf.back() = '\0';
|
||||
size_t bytes_read;
|
||||
size_t total_cstr_len = 0;
|
||||
|
@ -9382,8 +9387,8 @@ void ClangASTContext::DumpSummary(lldb::opaque_compiler_type_t type,
|
|||
break;
|
||||
if (total_cstr_len == 0)
|
||||
s->PutCString(" \"");
|
||||
cstr_data.Dump(s, 0, lldb::eFormatChar, 1, len, UINT32_MAX,
|
||||
LLDB_INVALID_ADDRESS, 0, 0);
|
||||
DumpDataExtractor(cstr_data, s, 0, lldb::eFormatChar, 1, len,
|
||||
UINT32_MAX, LLDB_INVALID_ADDRESS, 0, 0);
|
||||
total_cstr_len += len;
|
||||
if (len < buf.size())
|
||||
break;
|
||||
|
|
|
@ -744,8 +744,7 @@ size_t CompilerType::ConvertStringToFloatValue(const char *s, uint8_t *dst,
|
|||
#define DEPTH_INCREMENT 2
|
||||
|
||||
void CompilerType::DumpValue(ExecutionContext *exe_ctx, Stream *s,
|
||||
lldb::Format format,
|
||||
const lldb_private::DataExtractor &data,
|
||||
lldb::Format format, const DataExtractor &data,
|
||||
lldb::offset_t data_byte_offset,
|
||||
size_t data_byte_size, uint32_t bitfield_bit_size,
|
||||
uint32_t bitfield_bit_offset, bool show_types,
|
||||
|
@ -759,7 +758,7 @@ void CompilerType::DumpValue(ExecutionContext *exe_ctx, Stream *s,
|
|||
}
|
||||
|
||||
bool CompilerType::DumpTypeValue(Stream *s, lldb::Format format,
|
||||
const lldb_private::DataExtractor &data,
|
||||
const DataExtractor &data,
|
||||
lldb::offset_t byte_offset, size_t byte_size,
|
||||
uint32_t bitfield_bit_size,
|
||||
uint32_t bitfield_bit_offset,
|
||||
|
@ -772,7 +771,7 @@ bool CompilerType::DumpTypeValue(Stream *s, lldb::Format format,
|
|||
}
|
||||
|
||||
void CompilerType::DumpSummary(ExecutionContext *exe_ctx, Stream *s,
|
||||
const lldb_private::DataExtractor &data,
|
||||
const DataExtractor &data,
|
||||
lldb::offset_t data_byte_offset,
|
||||
size_t data_byte_size) {
|
||||
if (IsValid())
|
||||
|
|
|
@ -14,8 +14,8 @@
|
|||
#include "lldb/Core/ArchSpec.h"
|
||||
#include "lldb/Core/Module.h"
|
||||
#include "lldb/Core/Section.h"
|
||||
#include "lldb/Core/Section.h"
|
||||
#include "lldb/Core/Timer.h"
|
||||
#include "lldb/Core/dwarf.h"
|
||||
#include "lldb/Host/Host.h"
|
||||
#include "lldb/Symbol/DWARFCallFrameInfo.h"
|
||||
#include "lldb/Symbol/ObjectFile.h"
|
||||
|
@ -27,6 +27,129 @@
|
|||
using namespace lldb;
|
||||
using namespace lldb_private;
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// GetDwarfEHPtr
|
||||
//
|
||||
// Used for calls when the value type is specified by a DWARF EH Frame
|
||||
// pointer encoding.
|
||||
//----------------------------------------------------------------------
|
||||
static uint64_t
|
||||
GetGNUEHPointer(const DataExtractor &DE, offset_t *offset_ptr,
|
||||
uint32_t eh_ptr_enc, addr_t pc_rel_addr, addr_t text_addr,
|
||||
addr_t data_addr) //, BSDRelocs *data_relocs) const
|
||||
{
|
||||
if (eh_ptr_enc == DW_EH_PE_omit)
|
||||
return ULLONG_MAX; // Value isn't in the buffer...
|
||||
|
||||
uint64_t baseAddress = 0;
|
||||
uint64_t addressValue = 0;
|
||||
const uint32_t addr_size = DE.GetAddressByteSize();
|
||||
#ifdef LLDB_CONFIGURATION_DEBUG
|
||||
assert(addr_size == 4 || addr_size == 8);
|
||||
#endif
|
||||
|
||||
bool signExtendValue = false;
|
||||
// Decode the base part or adjust our offset
|
||||
switch (eh_ptr_enc & 0x70) {
|
||||
case DW_EH_PE_pcrel:
|
||||
signExtendValue = true;
|
||||
baseAddress = *offset_ptr;
|
||||
if (pc_rel_addr != LLDB_INVALID_ADDRESS)
|
||||
baseAddress += pc_rel_addr;
|
||||
// else
|
||||
// Log::GlobalWarning ("PC relative pointer encoding found with
|
||||
// invalid pc relative address.");
|
||||
break;
|
||||
|
||||
case DW_EH_PE_textrel:
|
||||
signExtendValue = true;
|
||||
if (text_addr != LLDB_INVALID_ADDRESS)
|
||||
baseAddress = text_addr;
|
||||
// else
|
||||
// Log::GlobalWarning ("text relative pointer encoding being
|
||||
// decoded with invalid text section address, setting base address
|
||||
// to zero.");
|
||||
break;
|
||||
|
||||
case DW_EH_PE_datarel:
|
||||
signExtendValue = true;
|
||||
if (data_addr != LLDB_INVALID_ADDRESS)
|
||||
baseAddress = data_addr;
|
||||
// else
|
||||
// Log::GlobalWarning ("data relative pointer encoding being
|
||||
// decoded with invalid data section address, setting base address
|
||||
// to zero.");
|
||||
break;
|
||||
|
||||
case DW_EH_PE_funcrel:
|
||||
signExtendValue = true;
|
||||
break;
|
||||
|
||||
case DW_EH_PE_aligned: {
|
||||
// SetPointerSize should be called prior to extracting these so the
|
||||
// pointer size is cached
|
||||
assert(addr_size != 0);
|
||||
if (addr_size) {
|
||||
// Align to a address size boundary first
|
||||
uint32_t alignOffset = *offset_ptr % addr_size;
|
||||
if (alignOffset)
|
||||
offset_ptr += addr_size - alignOffset;
|
||||
}
|
||||
} break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
// Decode the value part
|
||||
switch (eh_ptr_enc & DW_EH_PE_MASK_ENCODING) {
|
||||
case DW_EH_PE_absptr: {
|
||||
addressValue = DE.GetAddress(offset_ptr);
|
||||
// if (data_relocs)
|
||||
// addressValue = data_relocs->Relocate(*offset_ptr -
|
||||
// addr_size, *this, addressValue);
|
||||
} break;
|
||||
case DW_EH_PE_uleb128:
|
||||
addressValue = DE.GetULEB128(offset_ptr);
|
||||
break;
|
||||
case DW_EH_PE_udata2:
|
||||
addressValue = DE.GetU16(offset_ptr);
|
||||
break;
|
||||
case DW_EH_PE_udata4:
|
||||
addressValue = DE.GetU32(offset_ptr);
|
||||
break;
|
||||
case DW_EH_PE_udata8:
|
||||
addressValue = DE.GetU64(offset_ptr);
|
||||
break;
|
||||
case DW_EH_PE_sleb128:
|
||||
addressValue = DE.GetSLEB128(offset_ptr);
|
||||
break;
|
||||
case DW_EH_PE_sdata2:
|
||||
addressValue = (int16_t)DE.GetU16(offset_ptr);
|
||||
break;
|
||||
case DW_EH_PE_sdata4:
|
||||
addressValue = (int32_t)DE.GetU32(offset_ptr);
|
||||
break;
|
||||
case DW_EH_PE_sdata8:
|
||||
addressValue = (int64_t)DE.GetU64(offset_ptr);
|
||||
break;
|
||||
default:
|
||||
// Unhandled encoding type
|
||||
assert(eh_ptr_enc);
|
||||
break;
|
||||
}
|
||||
|
||||
// Since we promote everything to 64 bit, we may need to sign extend
|
||||
if (signExtendValue && addr_size < sizeof(baseAddress)) {
|
||||
uint64_t sign_bit = 1ull << ((addr_size * 8ull) - 1ull);
|
||||
if (sign_bit & addressValue) {
|
||||
uint64_t mask = ~sign_bit + 1;
|
||||
addressValue |= mask;
|
||||
}
|
||||
}
|
||||
return baseAddress + addressValue;
|
||||
}
|
||||
|
||||
DWARFCallFrameInfo::DWARFCallFrameInfo(ObjectFile &objfile,
|
||||
SectionSP §ion_sp,
|
||||
lldb::RegisterKind reg_kind,
|
||||
|
@ -223,9 +346,9 @@ DWARFCallFrameInfo::ParseCIE(const dw_offset_t cie_offset) {
|
|||
{
|
||||
uint8_t arg_ptr_encoding = m_cfi_data.GetU8(&offset);
|
||||
const lldb::addr_t pc_rel_addr = m_section_sp->GetFileAddress();
|
||||
cie_sp->personality_loc = m_cfi_data.GetGNUEHPointer(
|
||||
&offset, arg_ptr_encoding, pc_rel_addr, LLDB_INVALID_ADDRESS,
|
||||
LLDB_INVALID_ADDRESS);
|
||||
cie_sp->personality_loc = GetGNUEHPointer(
|
||||
m_cfi_data, &offset, arg_ptr_encoding, pc_rel_addr,
|
||||
LLDB_INVALID_ADDRESS, LLDB_INVALID_ADDRESS);
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -361,14 +484,15 @@ void DWARFCallFrameInfo::GetFDEIndex() {
|
|||
const lldb::addr_t text_addr = LLDB_INVALID_ADDRESS;
|
||||
const lldb::addr_t data_addr = LLDB_INVALID_ADDRESS;
|
||||
|
||||
lldb::addr_t addr = m_cfi_data.GetGNUEHPointer(
|
||||
&offset, cie->ptr_encoding, pc_rel_addr, text_addr, data_addr);
|
||||
lldb::addr_t addr =
|
||||
GetGNUEHPointer(m_cfi_data, &offset, cie->ptr_encoding, pc_rel_addr,
|
||||
text_addr, data_addr);
|
||||
if (clear_address_zeroth_bit)
|
||||
addr &= ~1ull;
|
||||
|
||||
lldb::addr_t length = m_cfi_data.GetGNUEHPointer(
|
||||
&offset, cie->ptr_encoding & DW_EH_PE_MASK_ENCODING, pc_rel_addr,
|
||||
text_addr, data_addr);
|
||||
lldb::addr_t length = GetGNUEHPointer(
|
||||
m_cfi_data, &offset, cie->ptr_encoding & DW_EH_PE_MASK_ENCODING,
|
||||
pc_rel_addr, text_addr, data_addr);
|
||||
FDEEntryMap::Entry fde(addr, length, current_entry);
|
||||
m_fde_index.Append(fde);
|
||||
} else {
|
||||
|
@ -434,11 +558,12 @@ bool DWARFCallFrameInfo::FDEToUnwindPlan(dw_offset_t dwarf_offset,
|
|||
const lldb::addr_t pc_rel_addr = m_section_sp->GetFileAddress();
|
||||
const lldb::addr_t text_addr = LLDB_INVALID_ADDRESS;
|
||||
const lldb::addr_t data_addr = LLDB_INVALID_ADDRESS;
|
||||
lldb::addr_t range_base = m_cfi_data.GetGNUEHPointer(
|
||||
&offset, cie->ptr_encoding, pc_rel_addr, text_addr, data_addr);
|
||||
lldb::addr_t range_len = m_cfi_data.GetGNUEHPointer(
|
||||
&offset, cie->ptr_encoding & DW_EH_PE_MASK_ENCODING, pc_rel_addr,
|
||||
text_addr, data_addr);
|
||||
lldb::addr_t range_base =
|
||||
GetGNUEHPointer(m_cfi_data, &offset, cie->ptr_encoding, pc_rel_addr,
|
||||
text_addr, data_addr);
|
||||
lldb::addr_t range_len = GetGNUEHPointer(
|
||||
m_cfi_data, &offset, cie->ptr_encoding & DW_EH_PE_MASK_ENCODING,
|
||||
pc_rel_addr, text_addr, data_addr);
|
||||
AddressRange range(range_base, m_objfile.GetAddressByteSize(),
|
||||
m_objfile.GetSectionList());
|
||||
range.SetByteSize(range_len);
|
||||
|
@ -449,8 +574,9 @@ bool DWARFCallFrameInfo::FDEToUnwindPlan(dw_offset_t dwarf_offset,
|
|||
uint32_t aug_data_len = (uint32_t)m_cfi_data.GetULEB128(&offset);
|
||||
if (aug_data_len != 0 && cie->lsda_addr_encoding != DW_EH_PE_omit) {
|
||||
offset_t saved_offset = offset;
|
||||
lsda_data_file_address = m_cfi_data.GetGNUEHPointer(
|
||||
&offset, cie->lsda_addr_encoding, pc_rel_addr, text_addr, data_addr);
|
||||
lsda_data_file_address =
|
||||
GetGNUEHPointer(m_cfi_data, &offset, cie->lsda_addr_encoding,
|
||||
pc_rel_addr, text_addr, data_addr);
|
||||
if (offset - saved_offset != aug_data_len) {
|
||||
// There is more in the augmentation region than we know how to process;
|
||||
// don't read anything.
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "lldb/Core/DumpDataExtractor.h"
|
||||
#include "lldb/Core/Module.h"
|
||||
#include "lldb/Core/PluginManager.h"
|
||||
#include "lldb/Core/StreamFile.h"
|
||||
|
@ -1263,9 +1264,9 @@ bool GoASTContext::DumpTypeValue(lldb::opaque_compiler_type_t type, Stream *s,
|
|||
byte_size = 4;
|
||||
break;
|
||||
}
|
||||
return data.Dump(s, byte_offset, format, byte_size, item_count, UINT32_MAX,
|
||||
LLDB_INVALID_ADDRESS, bitfield_bit_size,
|
||||
bitfield_bit_offset, exe_scope);
|
||||
return DumpDataExtractor(data, s, byte_offset, format, byte_size,
|
||||
item_count, UINT32_MAX, LLDB_INVALID_ADDRESS,
|
||||
bitfield_bit_size, bitfield_bit_offset, exe_scope);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
#include <sstream>
|
||||
|
||||
#include "lldb/Core/ArchSpec.h"
|
||||
#include "lldb/Core/DataExtractor.h"
|
||||
#include "lldb/Core/DumpDataExtractor.h"
|
||||
#include "lldb/Core/Module.h"
|
||||
#include "lldb/Core/PluginManager.h"
|
||||
#include "lldb/Core/StreamFile.h"
|
||||
|
@ -1004,10 +1004,10 @@ bool JavaASTContext::DumpTypeValue(
|
|||
size_t data_byte_size, uint32_t bitfield_bit_size,
|
||||
uint32_t bitfield_bit_offset, ExecutionContextScope *exe_scope) {
|
||||
if (IsScalarType(type)) {
|
||||
return data.Dump(s, data_offset, format, data_byte_size,
|
||||
1, // count
|
||||
UINT32_MAX, LLDB_INVALID_ADDRESS, bitfield_bit_size,
|
||||
bitfield_bit_offset, exe_scope);
|
||||
return DumpDataExtractor(data, s, data_offset, format, data_byte_size,
|
||||
1, // count
|
||||
UINT32_MAX, LLDB_INVALID_ADDRESS,
|
||||
bitfield_bit_size, bitfield_bit_offset, exe_scope);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "lldb/Symbol/OCamlASTContext.h"
|
||||
#include "lldb/Core/DumpDataExtractor.h"
|
||||
#include "lldb/Core/Module.h"
|
||||
#include "lldb/Core/PluginManager.h"
|
||||
#include "lldb/Core/StreamFile.h"
|
||||
|
@ -621,9 +622,9 @@ bool OCamlASTContext::DumpTypeValue(
|
|||
}
|
||||
|
||||
if (IsScalarType(type)) {
|
||||
return data.Dump(s, byte_offset, format, byte_size, 1, SIZE_MAX,
|
||||
LLDB_INVALID_ADDRESS, bitfield_bit_size,
|
||||
bitfield_bit_offset, exe_scope);
|
||||
return DumpDataExtractor(data, s, byte_offset, format, byte_size, 1,
|
||||
SIZE_MAX, LLDB_INVALID_ADDRESS, bitfield_bit_size,
|
||||
bitfield_bit_offset, exe_scope);
|
||||
}
|
||||
|
||||
return false;
|
||||
|
|
Loading…
Reference in New Issue