summaryrefslogtreecommitdiffstats
path: root/lldb/source/Core/DataExtractor.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lldb/source/Core/DataExtractor.cpp')
-rw-r--r--lldb/source/Core/DataExtractor.cpp109
1 files changed, 96 insertions, 13 deletions
diff --git a/lldb/source/Core/DataExtractor.cpp b/lldb/source/Core/DataExtractor.cpp
index 6dccc42c990..ff2d293781a 100644
--- a/lldb/source/Core/DataExtractor.cpp
+++ b/lldb/source/Core/DataExtractor.cpp
@@ -13,6 +13,7 @@
#include <bitset>
#include <string>
+#include "llvm/ADT/APFloat.h"
#include "llvm/ADT/APInt.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/Support/MathExtras.h"
@@ -20,12 +21,16 @@
#include "lldb/Core/DataBufferHeap.h"
#include "lldb/Core/DataExtractor.h"
#include "lldb/Core/DataBuffer.h"
+#include "lldb/Core/Disassembler.h"
#include "lldb/Core/Log.h"
#include "lldb/Core/Stream.h"
#include "lldb/Core/StreamString.h"
#include "lldb/Core/UUID.h"
#include "lldb/Core/dwarf.h"
#include "lldb/Host/Endian.h"
+#include "lldb/Target/ExecutionContext.h"
+#include "lldb/Target/ExecutionContextScope.h"
+#include "lldb/Target/Target.h"
using namespace lldb;
using namespace lldb_private;
@@ -1300,18 +1305,16 @@ DumpAPInt (Stream *s, const DataExtractor &data, uint32_t offset, uint32_t byte_
}
uint32_t
-DataExtractor::Dump
-(
- Stream *s,
- uint32_t start_offset,
- lldb::Format item_format,
- uint32_t item_byte_size,
- uint32_t item_count,
- uint32_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
-) const
+DataExtractor::Dump (Stream *s,
+ uint32_t start_offset,
+ lldb::Format item_format,
+ uint32_t item_byte_size,
+ uint32_t item_count,
+ uint32_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 == NULL)
return start_offset;
@@ -1326,9 +1329,44 @@ DataExtractor::Dump
item_byte_size = s->GetAddressByteSize();
}
- if (item_format == eFormatOSType && item_byte_size > 8)
+ if (item_format == eFormatInstruction)
+ {
+ Target *target = NULL;
+ if (exe_scope)
+ target = exe_scope->CalculateTarget();
+ if (target)
+ {
+ DisassemblerSP disassembler_sp (Disassembler::FindPlugin(target->GetArchitecture(), NULL));
+ if (disassembler_sp)
+ {
+ lldb::addr_t addr = base_addr + start_offset;
+ lldb_private::Address so_addr;
+ if (!target->GetSectionLoadList().ResolveLoadAddress(addr, so_addr))
+ {
+ so_addr.SetOffset(addr);
+ so_addr.SetSection(NULL);
+ }
+
+ if (disassembler_sp->DecodeInstructions (so_addr, *this, start_offset, item_count, false))
+ {
+ 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;
+
for (offset = start_offset, line_start_offset = start_offset, count = 0; ValidOffset(offset) && count < item_count; ++count)
{
if ((count % num_per_line) == 0)
@@ -1624,6 +1662,51 @@ DataExtractor::Dump
s->Printf("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%*.*llx", 2 * item_byte_size, 2 * item_byte_size, addr);
+ if (exe_scope)
+ {
+ Target *target = exe_scope->CalculateTarget();
+ lldb_private::Address so_addr;
+ if (target && target->GetSectionLoadList().ResolveLoadAddress(addr, so_addr))
+ {
+ s->PutChar(' ');
+ so_addr.Dump (s,
+ exe_scope,
+ Address::DumpStyleResolvedDescription,
+ Address::DumpStyleModuleWithFileAddress);
+ break;
+ }
+ }
+ }
+ 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 if (sizeof(long double) * 2 == item_byte_size)
+ {
+ s->Printf ("unsupported hex float byte size %u", item_byte_size);
+ return start_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 ||
OpenPOWER on IntegriCloud