summaryrefslogtreecommitdiffstats
path: root/lldb/source/Core/DataExtractor.cpp
diff options
context:
space:
mode:
authorGreg Clayton <gclayton@apple.com>2011-10-27 17:55:14 +0000
committerGreg Clayton <gclayton@apple.com>2011-10-27 17:55:14 +0000
commit5009f9d5010a7e34ae15f962dac8505ea11a8716 (patch)
tree0d5999c4d55eb310cef003cd9bb0ae05b6a60c80 /lldb/source/Core/DataExtractor.cpp
parent305bbb7d55437d8adb0bb01142c2e0177834eb63 (diff)
downloadbcm5719-llvm-5009f9d5010a7e34ae15f962dac8505ea11a8716.tar.gz
bcm5719-llvm-5009f9d5010a7e34ae15f962dac8505ea11a8716.zip
Added support for the new ".apple_objc" accelerator tables. These tables are
in the same hashed format as the ".apple_names", but they map objective C class names to all of the methods and class functions. We need to do this because in the DWARF the methods for Objective C are never contained in the class definition, they are scattered about at the translation unit level and they don't even have attributes that say the are contained within the class itself. Added 3 new formats which can be used to display data: eFormatAddressInfo eFormatHexFloat eFormatInstruction eFormatAddressInfo describes an address such as function+offset and file+line, or symbol + offset, or constant data (c string, 2, 4, 8, or 16 byte constants). The format character for this is "A", the long format is "address". eFormatHexFloat will print out the hex float format that compilers tend to use. The format character for this is "X", the long format is "hex float". eFormatInstruction will print out disassembly with bytes and it will use the current target's architecture. The format character for this is "i" (which used to be being used for the integer format, but the integer format also has "d", so we gave the "i" format to disassembly), the long format is "instruction". Mate the lldb::FormatterChoiceCriterion enumeration private as it should have been from the start. It is very specialized and doesn't belong in the public API. llvm-svn: 143114
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