diff options
author | Greg Clayton <gclayton@apple.com> | 2011-10-27 17:55:14 +0000 |
---|---|---|
committer | Greg Clayton <gclayton@apple.com> | 2011-10-27 17:55:14 +0000 |
commit | 5009f9d5010a7e34ae15f962dac8505ea11a8716 (patch) | |
tree | 0d5999c4d55eb310cef003cd9bb0ae05b6a60c80 /lldb/source/Core/DataExtractor.cpp | |
parent | 305bbb7d55437d8adb0bb01142c2e0177834eb63 (diff) | |
download | bcm5719-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.cpp | 109 |
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 || |