Changed the emulate instruction function to take emulate options which
are defined as enumerations. Current bits include: eEmulateInstructionOptionAutoAdvancePC eEmulateInstructionOptionIgnoreConditions Modified the EmulateInstruction class to have a few more pure virtuals that can help clients understand how many instructions the emulator can handle: virtual bool SupportsEmulatingIntructionsOfType (InstructionType inst_type) = 0; Where instruction types are defined as: //------------------------------------------------------------------ /// Instruction types //------------------------------------------------------------------ typedef enum InstructionType { eInstructionTypeAny, // Support for any instructions at all (at least one) eInstructionTypePrologueEpilogue, // All prologue and epilogue instructons that push and pop register values and modify sp/fp eInstructionTypePCModifying, // Any instruction that modifies the program counter/instruction pointer eInstructionTypeAll // All instructions of any kind } InstructionType; This allows use to tell what an emulator can do and also allows us to request these abilities when we are finding the plug-in interface. Added the ability for an EmulateInstruction class to get the register names for any registers that are part of the emulation. This helps with being able to dump and log effectively. The UnwindAssembly class now stores the architecture it was created with in case it is needed later in the unwinding process. Added a function that can tell us DWARF register names for ARM that goes along with the source/Utility/ARM_DWARF_Registers.h file: source/Utility/ARM_DWARF_Registers.c Took some of plug-ins out of the lldb_private namespace. llvm-svn: 130189
This commit is contained in:
parent
80cb3cb1d6
commit
2ed751bd47
|
@ -53,7 +53,7 @@ public:
|
||||||
GetDescription (lldb::SBStream &description);
|
GetDescription (lldb::SBStream &description);
|
||||||
|
|
||||||
bool
|
bool
|
||||||
EmulateWithFrame (lldb::SBFrame &frame, bool auto_advance_pc);
|
EmulateWithFrame (lldb::SBFrame &frame, uint32_t evaluate_options);
|
||||||
|
|
||||||
bool
|
bool
|
||||||
DumpEmulation (const char * triple); // triple is to specify the architecture, e.g. 'armv6' or 'arm-apple-darwin'
|
DumpEmulation (const char * triple); // triple is to specify the architecture, e.g. 'armv6' or 'arm-apple-darwin'
|
||||||
|
|
|
@ -86,7 +86,7 @@ public:
|
||||||
|
|
||||||
bool
|
bool
|
||||||
Emulate (const ArchSpec &arch,
|
Emulate (const ArchSpec &arch,
|
||||||
bool auto_advance_pc,
|
uint32_t evaluate_options,
|
||||||
void *baton,
|
void *baton,
|
||||||
EmulateInstruction::ReadMemory read_mem_callback,
|
EmulateInstruction::ReadMemory read_mem_callback,
|
||||||
EmulateInstruction::WriteMemory write_mem_calback,
|
EmulateInstruction::WriteMemory write_mem_calback,
|
||||||
|
|
|
@ -86,7 +86,9 @@ class EmulateInstruction :
|
||||||
public:
|
public:
|
||||||
|
|
||||||
static EmulateInstruction*
|
static EmulateInstruction*
|
||||||
FindPlugin (const ArchSpec &arch, const char *plugin_name);
|
FindPlugin (const ArchSpec &arch,
|
||||||
|
InstructionType supported_inst_type,
|
||||||
|
const char *plugin_name);
|
||||||
|
|
||||||
enum ContextType
|
enum ContextType
|
||||||
{
|
{
|
||||||
|
@ -366,45 +368,43 @@ public:
|
||||||
static void
|
static void
|
||||||
PrintContext (const char *context_type, const Context &context);
|
PrintContext (const char *context_type, const Context &context);
|
||||||
|
|
||||||
typedef size_t (*ReadMemory) (void *baton,
|
typedef size_t (*ReadMemory) (EmulateInstruction *instruction,
|
||||||
|
void *baton,
|
||||||
const Context &context,
|
const Context &context,
|
||||||
lldb::addr_t addr,
|
lldb::addr_t addr,
|
||||||
void *dst,
|
void *dst,
|
||||||
size_t length);
|
size_t length);
|
||||||
|
|
||||||
typedef size_t (*WriteMemory) (void *baton,
|
typedef size_t (*WriteMemory) (EmulateInstruction *instruction,
|
||||||
|
void *baton,
|
||||||
const Context &context,
|
const Context &context,
|
||||||
lldb::addr_t addr,
|
lldb::addr_t addr,
|
||||||
const void *dst,
|
const void *dst,
|
||||||
size_t length);
|
size_t length);
|
||||||
|
|
||||||
typedef bool (*ReadRegister) (void *baton,
|
typedef bool (*ReadRegister) (EmulateInstruction *instruction,
|
||||||
|
void *baton,
|
||||||
uint32_t reg_kind,
|
uint32_t reg_kind,
|
||||||
uint32_t reg_num,
|
uint32_t reg_num,
|
||||||
uint64_t ®_value);
|
uint64_t ®_value);
|
||||||
|
|
||||||
typedef bool (*WriteRegister) (void *baton,
|
typedef bool (*WriteRegister) (EmulateInstruction *instruction,
|
||||||
|
void *baton,
|
||||||
const Context &context,
|
const Context &context,
|
||||||
uint32_t reg_kind,
|
uint32_t reg_kind,
|
||||||
uint32_t reg_num,
|
uint32_t reg_num,
|
||||||
uint64_t reg_value);
|
uint64_t reg_value);
|
||||||
|
|
||||||
EmulateInstruction (lldb::ByteOrder byte_order,
|
EmulateInstruction (const ArchSpec &arch);
|
||||||
uint32_t addr_byte_size,
|
|
||||||
const ArchSpec &arch,
|
|
||||||
void *baton,
|
|
||||||
ReadMemory read_mem_callback,
|
|
||||||
WriteMemory write_mem_callback,
|
|
||||||
ReadRegister read_reg_callback,
|
|
||||||
WriteRegister write_reg_callback);
|
|
||||||
|
|
||||||
EmulateInstruction (lldb::ByteOrder byte_order,
|
|
||||||
uint32_t addr_byte_size,
|
|
||||||
const ArchSpec &arch);
|
|
||||||
|
|
||||||
virtual ~EmulateInstruction()
|
virtual ~EmulateInstruction()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
//----------------------------------------------------------------------
|
||||||
|
// Mandatory overrides
|
||||||
|
//----------------------------------------------------------------------
|
||||||
|
virtual bool
|
||||||
|
SupportsEmulatingIntructionsOfType (InstructionType inst_type) = 0;
|
||||||
|
|
||||||
virtual bool
|
virtual bool
|
||||||
SetTargetTriple (const ArchSpec &arch) = 0;
|
SetTargetTriple (const ArchSpec &arch) = 0;
|
||||||
|
@ -413,21 +413,20 @@ public:
|
||||||
ReadInstruction () = 0;
|
ReadInstruction () = 0;
|
||||||
|
|
||||||
virtual bool
|
virtual bool
|
||||||
SetInstruction (const Opcode &insn_opcode, const Address &inst_addr) = 0;
|
EvaluateInstruction (uint32_t evaluate_options) = 0;
|
||||||
|
|
||||||
virtual bool
|
|
||||||
EvaluateInstruction () = 0;
|
|
||||||
|
|
||||||
virtual bool
|
virtual bool
|
||||||
TestEmulation (Stream *out_stream, ArchSpec &arch, OptionValueDictionary *test_data) = 0;
|
TestEmulation (Stream *out_stream, ArchSpec &arch, OptionValueDictionary *test_data) = 0;
|
||||||
|
|
||||||
|
virtual const char *
|
||||||
|
GetRegisterName (uint32_t reg_kind, uint32_t reg_num) = 0;
|
||||||
|
//----------------------------------------------------------------------
|
||||||
|
// Optional overrides
|
||||||
|
//----------------------------------------------------------------------
|
||||||
|
virtual bool
|
||||||
|
SetInstruction (const Opcode &insn_opcode, const Address &inst_addr, Target *target);
|
||||||
|
|
||||||
bool
|
static const char *
|
||||||
GetAdvancePC () { return m_advance_pc; }
|
|
||||||
|
|
||||||
void
|
|
||||||
SetAdvancePC (bool value) { m_advance_pc = value; }
|
|
||||||
|
|
||||||
static void
|
|
||||||
TranslateRegister (uint32_t reg_kind, uint32_t reg_num, std::string ®_name);
|
TranslateRegister (uint32_t reg_kind, uint32_t reg_num, std::string ®_name);
|
||||||
|
|
||||||
uint64_t
|
uint64_t
|
||||||
|
@ -458,13 +457,13 @@ public:
|
||||||
uint32_t
|
uint32_t
|
||||||
GetAddressByteSize () const
|
GetAddressByteSize () const
|
||||||
{
|
{
|
||||||
return m_addr_byte_size;
|
return m_arch.GetAddressByteSize();
|
||||||
}
|
}
|
||||||
|
|
||||||
lldb::ByteOrder
|
lldb::ByteOrder
|
||||||
GetByteOrder () const
|
GetByteOrder () const
|
||||||
{
|
{
|
||||||
return m_byte_order;
|
return m_arch.GetByteOrder();
|
||||||
}
|
}
|
||||||
|
|
||||||
const Opcode &
|
const Opcode &
|
||||||
|
@ -472,59 +471,73 @@ public:
|
||||||
{
|
{
|
||||||
return m_opcode;
|
return m_opcode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const ArchSpec &
|
||||||
|
GetArchitecture () const
|
||||||
|
{
|
||||||
|
return m_arch;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static size_t
|
static size_t
|
||||||
ReadMemoryFrame (void *baton,
|
ReadMemoryFrame (EmulateInstruction *instruction,
|
||||||
|
void *baton,
|
||||||
const Context &context,
|
const Context &context,
|
||||||
lldb::addr_t addr,
|
lldb::addr_t addr,
|
||||||
void *dst,
|
void *dst,
|
||||||
size_t length);
|
size_t length);
|
||||||
|
|
||||||
static size_t
|
static size_t
|
||||||
WriteMemoryFrame (void *baton,
|
WriteMemoryFrame (EmulateInstruction *instruction,
|
||||||
|
void *baton,
|
||||||
const Context &context,
|
const Context &context,
|
||||||
lldb::addr_t addr,
|
lldb::addr_t addr,
|
||||||
const void *dst,
|
const void *dst,
|
||||||
size_t length);
|
size_t length);
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
ReadRegisterFrame (void *baton,
|
ReadRegisterFrame (EmulateInstruction *instruction,
|
||||||
|
void *baton,
|
||||||
uint32_t reg_kind,
|
uint32_t reg_kind,
|
||||||
uint32_t reg_num,
|
uint32_t reg_num,
|
||||||
uint64_t ®_value);
|
uint64_t ®_value);
|
||||||
|
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
WriteRegisterFrame (void *baton,
|
WriteRegisterFrame (EmulateInstruction *instruction,
|
||||||
|
void *baton,
|
||||||
const Context &context,
|
const Context &context,
|
||||||
uint32_t reg_kind,
|
uint32_t reg_kind,
|
||||||
uint32_t reg_num,
|
uint32_t reg_num,
|
||||||
uint64_t reg_value);
|
uint64_t reg_value);
|
||||||
|
|
||||||
static size_t
|
static size_t
|
||||||
ReadMemoryDefault (void *baton,
|
ReadMemoryDefault (EmulateInstruction *instruction,
|
||||||
|
void *baton,
|
||||||
const Context &context,
|
const Context &context,
|
||||||
lldb::addr_t addr,
|
lldb::addr_t addr,
|
||||||
void *dst,
|
void *dst,
|
||||||
size_t length);
|
size_t length);
|
||||||
|
|
||||||
static size_t
|
static size_t
|
||||||
WriteMemoryDefault (void *baton,
|
WriteMemoryDefault (EmulateInstruction *instruction,
|
||||||
|
void *baton,
|
||||||
const Context &context,
|
const Context &context,
|
||||||
lldb::addr_t addr,
|
lldb::addr_t addr,
|
||||||
const void *dst,
|
const void *dst,
|
||||||
size_t length);
|
size_t length);
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
ReadRegisterDefault (void *baton,
|
ReadRegisterDefault (EmulateInstruction *instruction,
|
||||||
|
void *baton,
|
||||||
uint32_t reg_kind,
|
uint32_t reg_kind,
|
||||||
uint32_t reg_num,
|
uint32_t reg_num,
|
||||||
uint64_t ®_value);
|
uint64_t ®_value);
|
||||||
|
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
WriteRegisterDefault (void *baton,
|
WriteRegisterDefault (EmulateInstruction *instruction,
|
||||||
|
void *baton,
|
||||||
const Context &context,
|
const Context &context,
|
||||||
uint32_t reg_kind,
|
uint32_t reg_kind,
|
||||||
uint32_t reg_num,
|
uint32_t reg_num,
|
||||||
|
@ -553,8 +566,6 @@ public:
|
||||||
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
lldb::ByteOrder m_byte_order;
|
|
||||||
uint32_t m_addr_byte_size;
|
|
||||||
ArchSpec m_arch;
|
ArchSpec m_arch;
|
||||||
void * m_baton;
|
void * m_baton;
|
||||||
ReadMemory m_read_mem_callback;
|
ReadMemory m_read_mem_callback;
|
||||||
|
@ -563,7 +574,6 @@ protected:
|
||||||
WriteRegister m_write_reg_callback;
|
WriteRegister m_write_reg_callback;
|
||||||
lldb::addr_t m_opcode_pc;
|
lldb::addr_t m_opcode_pc;
|
||||||
Opcode m_opcode;
|
Opcode m_opcode;
|
||||||
bool m_advance_pc;
|
|
||||||
//------------------------------------------------------------------
|
//------------------------------------------------------------------
|
||||||
// For EmulateInstruction only
|
// For EmulateInstruction only
|
||||||
//------------------------------------------------------------------
|
//------------------------------------------------------------------
|
||||||
|
|
|
@ -24,7 +24,8 @@ public:
|
||||||
~ArchDefaultUnwindPlan();
|
~ArchDefaultUnwindPlan();
|
||||||
|
|
||||||
virtual lldb::UnwindPlanSP
|
virtual lldb::UnwindPlanSP
|
||||||
GetArchDefaultUnwindPlan (Thread& thread, Address current_pc) = 0;
|
GetArchDefaultUnwindPlan (Thread& thread,
|
||||||
|
const Address ¤t_pc) = 0;
|
||||||
|
|
||||||
static lldb::ArchDefaultUnwindPlanSP
|
static lldb::ArchDefaultUnwindPlanSP
|
||||||
FindPlugin (const ArchSpec &arch);
|
FindPlugin (const ArchSpec &arch);
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
#define utility_UnwindAssembly_h_
|
#define utility_UnwindAssembly_h_
|
||||||
|
|
||||||
#include "lldb/lldb-private.h"
|
#include "lldb/lldb-private.h"
|
||||||
|
#include "lldb/Core/ArchSpec.h"
|
||||||
#include "lldb/Core/PluginInterface.h"
|
#include "lldb/Core/PluginInterface.h"
|
||||||
|
|
||||||
namespace lldb_private {
|
namespace lldb_private {
|
||||||
|
@ -43,8 +44,11 @@ public:
|
||||||
Address& first_non_prologue_insn) = 0;
|
Address& first_non_prologue_insn) = 0;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
UnwindAssembly();
|
UnwindAssembly (const ArchSpec &arch);
|
||||||
|
ArchSpec m_arch;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
UnwindAssembly(); // Outlaw default constructor
|
||||||
DISALLOW_COPY_AND_ASSIGN (UnwindAssembly);
|
DISALLOW_COPY_AND_ASSIGN (UnwindAssembly);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -457,6 +457,13 @@ namespace lldb {
|
||||||
|
|
||||||
} SectionType;
|
} SectionType;
|
||||||
|
|
||||||
|
typedef enum EmulateInstructionOptions
|
||||||
|
{
|
||||||
|
eEmulateInstructionOptionNone = (0u),
|
||||||
|
eEmulateInstructionOptionAutoAdvancePC = (1u << 0),
|
||||||
|
eEmulateInstructionOptionIgnoreConditions = (1u << 1)
|
||||||
|
} EmulateInstructionOptions;
|
||||||
|
|
||||||
} // namespace lldb
|
} // namespace lldb
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -204,6 +204,19 @@ typedef enum NameMatchType
|
||||||
} NameMatchType;
|
} NameMatchType;
|
||||||
|
|
||||||
|
|
||||||
|
//------------------------------------------------------------------
|
||||||
|
/// Instruction types
|
||||||
|
//------------------------------------------------------------------
|
||||||
|
typedef enum InstructionType
|
||||||
|
{
|
||||||
|
eInstructionTypeAny, // Support for any instructions at all (at least one)
|
||||||
|
eInstructionTypePrologueEpilogue, // All prologue and epilogue instructons that push and pop register values and modify sp/fp
|
||||||
|
eInstructionTypePCModifying, // Any instruction that modifies the program counter/instruction pointer
|
||||||
|
eInstructionTypeAll // All instructions of any kind
|
||||||
|
|
||||||
|
} InstructionType;
|
||||||
|
|
||||||
|
|
||||||
} // namespace lldb
|
} // namespace lldb
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -22,7 +22,7 @@ namespace lldb_private
|
||||||
typedef ObjectContainer* (*ObjectContainerCreateInstance) (Module* module, lldb::DataBufferSP& dataSP, const FileSpec *file, lldb::addr_t offset, lldb::addr_t length);
|
typedef ObjectContainer* (*ObjectContainerCreateInstance) (Module* module, lldb::DataBufferSP& dataSP, const FileSpec *file, lldb::addr_t offset, lldb::addr_t length);
|
||||||
typedef ObjectFile* (*ObjectFileCreateInstance) (Module* module, lldb::DataBufferSP& dataSP, const FileSpec* file, lldb::addr_t offset, lldb::addr_t length);
|
typedef ObjectFile* (*ObjectFileCreateInstance) (Module* module, lldb::DataBufferSP& dataSP, const FileSpec* file, lldb::addr_t offset, lldb::addr_t length);
|
||||||
typedef LogChannel* (*LogChannelCreateInstance) ();
|
typedef LogChannel* (*LogChannelCreateInstance) ();
|
||||||
typedef EmulateInstruction * (*EmulateInstructionCreateInstance) (const ArchSpec &arch);
|
typedef EmulateInstruction * (*EmulateInstructionCreateInstance) (const ArchSpec &arch, InstructionType inst_type);
|
||||||
typedef LanguageRuntime *(*LanguageRuntimeCreateInstance) (Process *process, lldb::LanguageType language);
|
typedef LanguageRuntime *(*LanguageRuntimeCreateInstance) (Process *process, lldb::LanguageType language);
|
||||||
typedef Platform* (*PlatformCreateInstance) ();
|
typedef Platform* (*PlatformCreateInstance) ();
|
||||||
typedef Process* (*ProcessCreateInstance) (Target &target, Listener &listener);
|
typedef Process* (*ProcessCreateInstance) (Target &target, Listener &listener);
|
||||||
|
|
|
@ -404,6 +404,7 @@
|
||||||
26DE20611161902700A093E2 /* SBBlock.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26DE20601161902600A093E2 /* SBBlock.cpp */; };
|
26DE20611161902700A093E2 /* SBBlock.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26DE20601161902600A093E2 /* SBBlock.cpp */; };
|
||||||
26DE20631161904200A093E2 /* SBLineEntry.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26DE20621161904200A093E2 /* SBLineEntry.cpp */; };
|
26DE20631161904200A093E2 /* SBLineEntry.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26DE20621161904200A093E2 /* SBLineEntry.cpp */; };
|
||||||
26DE20651161904E00A093E2 /* SBSymbol.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26DE20641161904E00A093E2 /* SBSymbol.cpp */; };
|
26DE20651161904E00A093E2 /* SBSymbol.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26DE20641161904E00A093E2 /* SBSymbol.cpp */; };
|
||||||
|
26ECA04313665FED008D1F18 /* ARM_DWARF_Registers.c in Sources */ = {isa = PBXBuildFile; fileRef = 26ECA04213665FED008D1F18 /* ARM_DWARF_Registers.c */; };
|
||||||
26F5C27710F3D9E4009D5894 /* Driver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26F5C27310F3D9E4009D5894 /* Driver.cpp */; };
|
26F5C27710F3D9E4009D5894 /* Driver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26F5C27310F3D9E4009D5894 /* Driver.cpp */; };
|
||||||
26F5C27810F3D9E4009D5894 /* IOChannel.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26F5C27510F3D9E4009D5894 /* IOChannel.cpp */; };
|
26F5C27810F3D9E4009D5894 /* IOChannel.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26F5C27510F3D9E4009D5894 /* IOChannel.cpp */; };
|
||||||
26F5C32510F3DF23009D5894 /* libpython.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 26F5C32410F3DF23009D5894 /* libpython.dylib */; };
|
26F5C32510F3DF23009D5894 /* libpython.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 26F5C32410F3DF23009D5894 /* libpython.dylib */; };
|
||||||
|
@ -1043,6 +1044,7 @@
|
||||||
26E3EEF811A994E800FBADB6 /* RegisterContextMacOSXFrameBackchain.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RegisterContextMacOSXFrameBackchain.h; path = Utility/RegisterContextMacOSXFrameBackchain.h; sourceTree = "<group>"; };
|
26E3EEF811A994E800FBADB6 /* RegisterContextMacOSXFrameBackchain.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RegisterContextMacOSXFrameBackchain.h; path = Utility/RegisterContextMacOSXFrameBackchain.h; sourceTree = "<group>"; };
|
||||||
26E6902E129C6BD500DDECD9 /* ClangExternalASTSourceCallbacks.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ClangExternalASTSourceCallbacks.h; path = include/lldb/Symbol/ClangExternalASTSourceCallbacks.h; sourceTree = "<group>"; };
|
26E6902E129C6BD500DDECD9 /* ClangExternalASTSourceCallbacks.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ClangExternalASTSourceCallbacks.h; path = include/lldb/Symbol/ClangExternalASTSourceCallbacks.h; sourceTree = "<group>"; };
|
||||||
26E69030129C6BEF00DDECD9 /* ClangExternalASTSourceCallbacks.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ClangExternalASTSourceCallbacks.cpp; path = source/Symbol/ClangExternalASTSourceCallbacks.cpp; sourceTree = "<group>"; };
|
26E69030129C6BEF00DDECD9 /* ClangExternalASTSourceCallbacks.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ClangExternalASTSourceCallbacks.cpp; path = source/Symbol/ClangExternalASTSourceCallbacks.cpp; sourceTree = "<group>"; };
|
||||||
|
26ECA04213665FED008D1F18 /* ARM_DWARF_Registers.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = ARM_DWARF_Registers.c; path = source/Utility/ARM_DWARF_Registers.c; sourceTree = "<group>"; };
|
||||||
26F5C26A10F3D9A4009D5894 /* lldb */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = lldb; sourceTree = BUILT_PRODUCTS_DIR; };
|
26F5C26A10F3D9A4009D5894 /* lldb */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = lldb; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||||
26F5C27210F3D9E4009D5894 /* lldb-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = "lldb-Info.plist"; path = "tools/driver/lldb-Info.plist"; sourceTree = "<group>"; };
|
26F5C27210F3D9E4009D5894 /* lldb-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = "lldb-Info.plist"; path = "tools/driver/lldb-Info.plist"; sourceTree = "<group>"; };
|
||||||
26F5C27310F3D9E4009D5894 /* Driver.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Driver.cpp; path = tools/driver/Driver.cpp; sourceTree = "<group>"; };
|
26F5C27310F3D9E4009D5894 /* Driver.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Driver.cpp; path = tools/driver/Driver.cpp; sourceTree = "<group>"; };
|
||||||
|
@ -1761,6 +1763,7 @@
|
||||||
4C2FAE2E135E3A70001EDE44 /* SharedCluster.h */,
|
4C2FAE2E135E3A70001EDE44 /* SharedCluster.h */,
|
||||||
261B5A5311C3F2AD00AABD0A /* SharingPtr.h */,
|
261B5A5311C3F2AD00AABD0A /* SharingPtr.h */,
|
||||||
26F996A7119B79C300412154 /* ARM_DWARF_Registers.h */,
|
26F996A7119B79C300412154 /* ARM_DWARF_Registers.h */,
|
||||||
|
26ECA04213665FED008D1F18 /* ARM_DWARF_Registers.c */,
|
||||||
26F996A8119B79C300412154 /* ARM_GCC_Registers.h */,
|
26F996A8119B79C300412154 /* ARM_GCC_Registers.h */,
|
||||||
2660D9F611922A1300958FBD /* StringExtractor.cpp */,
|
2660D9F611922A1300958FBD /* StringExtractor.cpp */,
|
||||||
2660D9F711922A1300958FBD /* StringExtractor.h */,
|
2660D9F711922A1300958FBD /* StringExtractor.h */,
|
||||||
|
@ -3231,6 +3234,7 @@
|
||||||
2692BA231366150100F9E14D /* ArchVolatileRegs-x86.cpp in Sources */,
|
2692BA231366150100F9E14D /* ArchVolatileRegs-x86.cpp in Sources */,
|
||||||
263E949F13661AEA00E7D1CE /* UnwindAssembly-x86.cpp in Sources */,
|
263E949F13661AEA00E7D1CE /* UnwindAssembly-x86.cpp in Sources */,
|
||||||
264D8D5013661BD7003A368F /* UnwindAssembly.cpp in Sources */,
|
264D8D5013661BD7003A368F /* UnwindAssembly.cpp in Sources */,
|
||||||
|
26ECA04313665FED008D1F18 /* ARM_DWARF_Registers.c in Sources */,
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
};
|
};
|
||||||
|
|
|
@ -74,8 +74,6 @@
|
||||||
<LaunchAction
|
<LaunchAction
|
||||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||||
displayScaleIsEnabled = "NO"
|
|
||||||
displayScale = "1.00"
|
|
||||||
launchStyle = "0"
|
launchStyle = "0"
|
||||||
useCustomWorkingDirectory = "YES"
|
useCustomWorkingDirectory = "YES"
|
||||||
customWorkingDirectory = "/Volumes/work/gclayton/Documents/src/lldb/build/Debug"
|
customWorkingDirectory = "/Volumes/work/gclayton/Documents/src/lldb/build/Debug"
|
||||||
|
@ -131,8 +129,6 @@
|
||||||
</AdditionalOptions>
|
</AdditionalOptions>
|
||||||
</LaunchAction>
|
</LaunchAction>
|
||||||
<ProfileAction
|
<ProfileAction
|
||||||
displayScaleIsEnabled = "NO"
|
|
||||||
displayScale = "1.00"
|
|
||||||
shouldUseLaunchSchemeArgsEnv = "YES"
|
shouldUseLaunchSchemeArgsEnv = "YES"
|
||||||
savedToolIdentifier = ""
|
savedToolIdentifier = ""
|
||||||
useCustomWorkingDirectory = "NO"
|
useCustomWorkingDirectory = "NO"
|
||||||
|
|
|
@ -116,7 +116,7 @@ SBInstruction::Print (FILE *out)
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
SBInstruction::EmulateWithFrame (lldb::SBFrame &frame, bool auto_advance_pc)
|
SBInstruction::EmulateWithFrame (lldb::SBFrame &frame, uint32_t evaluate_options)
|
||||||
{
|
{
|
||||||
if (m_opaque_sp && frame.get())
|
if (m_opaque_sp && frame.get())
|
||||||
{
|
{
|
||||||
|
@ -126,7 +126,7 @@ SBInstruction::EmulateWithFrame (lldb::SBFrame &frame, bool auto_advance_pc)
|
||||||
lldb_private::ArchSpec arch = target->GetArchitecture();
|
lldb_private::ArchSpec arch = target->GetArchitecture();
|
||||||
|
|
||||||
return m_opaque_sp->Emulate (arch,
|
return m_opaque_sp->Emulate (arch,
|
||||||
auto_advance_pc,
|
evaluate_options,
|
||||||
(void *) frame.get(),
|
(void *) frame.get(),
|
||||||
&lldb_private::EmulateInstruction::ReadMemoryFrame,
|
&lldb_private::EmulateInstruction::ReadMemoryFrame,
|
||||||
&lldb_private::EmulateInstruction::WriteMemoryFrame,
|
&lldb_private::EmulateInstruction::WriteMemoryFrame,
|
||||||
|
|
|
@ -503,11 +503,11 @@ Instruction::GetAddressClass ()
|
||||||
bool
|
bool
|
||||||
Instruction::DumpEmulation (const ArchSpec &arch)
|
Instruction::DumpEmulation (const ArchSpec &arch)
|
||||||
{
|
{
|
||||||
std::auto_ptr<EmulateInstruction> insn_emulator_ap (EmulateInstruction::FindPlugin (arch, NULL));
|
std::auto_ptr<EmulateInstruction> insn_emulator_ap (EmulateInstruction::FindPlugin (arch, eInstructionTypeAny, NULL));
|
||||||
if (insn_emulator_ap.get())
|
if (insn_emulator_ap.get())
|
||||||
{
|
{
|
||||||
insn_emulator_ap->SetInstruction (GetOpcode(), GetAddress());
|
insn_emulator_ap->SetInstruction (GetOpcode(), GetAddress(), NULL);
|
||||||
return insn_emulator_ap->EvaluateInstruction ();
|
return insn_emulator_ap->EvaluateInstruction (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
@ -766,7 +766,7 @@ Instruction::TestEmulation (Stream *out_stream, const char *file_name)
|
||||||
arch.SetTriple (llvm::Triple (value_sp->GetStringValue()));
|
arch.SetTriple (llvm::Triple (value_sp->GetStringValue()));
|
||||||
|
|
||||||
bool success = false;
|
bool success = false;
|
||||||
std::auto_ptr<EmulateInstruction> insn_emulator_ap (EmulateInstruction::FindPlugin (arch, NULL));
|
std::auto_ptr<EmulateInstruction> insn_emulator_ap (EmulateInstruction::FindPlugin (arch, eInstructionTypeAny, NULL));
|
||||||
if (insn_emulator_ap.get())
|
if (insn_emulator_ap.get())
|
||||||
success = insn_emulator_ap->TestEmulation (out_stream, arch, data_dictionary);
|
success = insn_emulator_ap->TestEmulation (out_stream, arch, data_dictionary);
|
||||||
|
|
||||||
|
@ -780,21 +780,20 @@ Instruction::TestEmulation (Stream *out_stream, const char *file_name)
|
||||||
|
|
||||||
bool
|
bool
|
||||||
Instruction::Emulate (const ArchSpec &arch,
|
Instruction::Emulate (const ArchSpec &arch,
|
||||||
bool auto_advance_pc,
|
uint32_t evaluate_options,
|
||||||
void *baton,
|
void *baton,
|
||||||
EmulateInstruction::ReadMemory read_mem_callback,
|
EmulateInstruction::ReadMemory read_mem_callback,
|
||||||
EmulateInstruction::WriteMemory write_mem_callback,
|
EmulateInstruction::WriteMemory write_mem_callback,
|
||||||
EmulateInstruction::ReadRegister read_reg_callback,
|
EmulateInstruction::ReadRegister read_reg_callback,
|
||||||
EmulateInstruction::WriteRegister write_reg_callback)
|
EmulateInstruction::WriteRegister write_reg_callback)
|
||||||
{
|
{
|
||||||
std::auto_ptr<EmulateInstruction> insn_emulator_ap (EmulateInstruction::FindPlugin (arch, NULL));
|
std::auto_ptr<EmulateInstruction> insn_emulator_ap (EmulateInstruction::FindPlugin (arch, eInstructionTypeAny, NULL));
|
||||||
if (insn_emulator_ap.get())
|
if (insn_emulator_ap.get())
|
||||||
{
|
{
|
||||||
insn_emulator_ap->SetBaton (baton);
|
insn_emulator_ap->SetBaton (baton);
|
||||||
insn_emulator_ap->SetCallbacks (read_mem_callback, write_mem_callback, read_reg_callback, write_reg_callback);
|
insn_emulator_ap->SetCallbacks (read_mem_callback, write_mem_callback, read_reg_callback, write_reg_callback);
|
||||||
insn_emulator_ap->SetInstruction (GetOpcode(), GetAddress());
|
insn_emulator_ap->SetInstruction (GetOpcode(), GetAddress(), NULL);
|
||||||
insn_emulator_ap->SetAdvancePC (auto_advance_pc);
|
return insn_emulator_ap->EvaluateInstruction (evaluate_options);
|
||||||
return insn_emulator_ap->EvaluateInstruction ();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
|
|
||||||
#include "lldb/Core/EmulateInstruction.h"
|
#include "lldb/Core/EmulateInstruction.h"
|
||||||
|
|
||||||
|
#include "lldb/Core/Address.h"
|
||||||
#include "lldb/Core/DataBufferHeap.h"
|
#include "lldb/Core/DataBufferHeap.h"
|
||||||
#include "lldb/Core/DataExtractor.h"
|
#include "lldb/Core/DataExtractor.h"
|
||||||
#include "lldb/Core/Error.h"
|
#include "lldb/Core/Error.h"
|
||||||
|
@ -17,6 +18,7 @@
|
||||||
#include "lldb/Host/Endian.h"
|
#include "lldb/Host/Endian.h"
|
||||||
#include "lldb/Target/Process.h"
|
#include "lldb/Target/Process.h"
|
||||||
#include "lldb/Target/RegisterContext.h"
|
#include "lldb/Target/RegisterContext.h"
|
||||||
|
#include "lldb/Target/Target.h"
|
||||||
#include "lldb/Target/Thread.h"
|
#include "lldb/Target/Thread.h"
|
||||||
|
|
||||||
#include "Plugins/Instruction/ARM/EmulateInstructionARM.h"
|
#include "Plugins/Instruction/ARM/EmulateInstructionARM.h"
|
||||||
|
@ -25,7 +27,7 @@ using namespace lldb;
|
||||||
using namespace lldb_private;
|
using namespace lldb_private;
|
||||||
|
|
||||||
EmulateInstruction*
|
EmulateInstruction*
|
||||||
EmulateInstruction::FindPlugin (const ArchSpec &arch, const char *plugin_name)
|
EmulateInstruction::FindPlugin (const ArchSpec &arch, InstructionType supported_inst_type, const char *plugin_name)
|
||||||
{
|
{
|
||||||
EmulateInstructionCreateInstance create_callback = NULL;
|
EmulateInstructionCreateInstance create_callback = NULL;
|
||||||
if (plugin_name)
|
if (plugin_name)
|
||||||
|
@ -33,7 +35,7 @@ EmulateInstruction::FindPlugin (const ArchSpec &arch, const char *plugin_name)
|
||||||
create_callback = PluginManager::GetEmulateInstructionCreateCallbackForPluginName (plugin_name);
|
create_callback = PluginManager::GetEmulateInstructionCreateCallbackForPluginName (plugin_name);
|
||||||
if (create_callback)
|
if (create_callback)
|
||||||
{
|
{
|
||||||
EmulateInstruction *emulate_insn_ptr = create_callback(arch);
|
EmulateInstruction *emulate_insn_ptr = create_callback(arch, supported_inst_type);
|
||||||
if (emulate_insn_ptr)
|
if (emulate_insn_ptr)
|
||||||
return emulate_insn_ptr;
|
return emulate_insn_ptr;
|
||||||
}
|
}
|
||||||
|
@ -42,7 +44,7 @@ EmulateInstruction::FindPlugin (const ArchSpec &arch, const char *plugin_name)
|
||||||
{
|
{
|
||||||
for (uint32_t idx = 0; (create_callback = PluginManager::GetEmulateInstructionCreateCallbackAtIndex(idx)) != NULL; ++idx)
|
for (uint32_t idx = 0; (create_callback = PluginManager::GetEmulateInstructionCreateCallbackAtIndex(idx)) != NULL; ++idx)
|
||||||
{
|
{
|
||||||
EmulateInstruction *emulate_insn_ptr = create_callback(arch);
|
EmulateInstruction *emulate_insn_ptr = create_callback(arch, supported_inst_type);
|
||||||
if (emulate_insn_ptr)
|
if (emulate_insn_ptr)
|
||||||
return emulate_insn_ptr;
|
return emulate_insn_ptr;
|
||||||
}
|
}
|
||||||
|
@ -50,47 +52,14 @@ EmulateInstruction::FindPlugin (const ArchSpec &arch, const char *plugin_name)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
EmulateInstruction::EmulateInstruction
|
EmulateInstruction::EmulateInstruction (const ArchSpec &arch) :
|
||||||
(
|
|
||||||
lldb::ByteOrder byte_order,
|
|
||||||
uint32_t addr_byte_size,
|
|
||||||
const ArchSpec &arch,
|
|
||||||
void *baton,
|
|
||||||
ReadMemory read_mem_callback,
|
|
||||||
WriteMemory write_mem_callback,
|
|
||||||
ReadRegister read_reg_callback,
|
|
||||||
WriteRegister write_reg_callback
|
|
||||||
) :
|
|
||||||
m_byte_order (endian::InlHostByteOrder()),
|
|
||||||
m_addr_byte_size (addr_byte_size),
|
|
||||||
m_arch (arch),
|
|
||||||
m_baton (baton),
|
|
||||||
m_read_mem_callback (read_mem_callback),
|
|
||||||
m_write_mem_callback (write_mem_callback),
|
|
||||||
m_read_reg_callback (read_reg_callback),
|
|
||||||
m_write_reg_callback (write_reg_callback),
|
|
||||||
m_opcode_pc (LLDB_INVALID_ADDRESS),
|
|
||||||
m_opcode (),
|
|
||||||
m_advance_pc (false)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
EmulateInstruction::EmulateInstruction
|
|
||||||
(
|
|
||||||
lldb::ByteOrder byte_order,
|
|
||||||
uint32_t addr_byte_size,
|
|
||||||
const ArchSpec &arch
|
|
||||||
) :
|
|
||||||
m_byte_order (endian::InlHostByteOrder()),
|
|
||||||
m_addr_byte_size (addr_byte_size),
|
|
||||||
m_arch (arch),
|
m_arch (arch),
|
||||||
m_baton (NULL),
|
m_baton (NULL),
|
||||||
m_read_mem_callback (&ReadMemoryDefault),
|
m_read_mem_callback (&ReadMemoryDefault),
|
||||||
m_write_mem_callback (&WriteMemoryDefault),
|
m_write_mem_callback (&WriteMemoryDefault),
|
||||||
m_read_reg_callback (&ReadRegisterDefault),
|
m_read_reg_callback (&ReadRegisterDefault),
|
||||||
m_write_reg_callback (&WriteRegisterDefault),
|
m_write_reg_callback (&WriteRegisterDefault),
|
||||||
m_opcode_pc (LLDB_INVALID_ADDRESS),
|
m_opcode_pc (LLDB_INVALID_ADDRESS)
|
||||||
m_advance_pc (false)
|
|
||||||
{
|
{
|
||||||
::memset (&m_opcode, 0, sizeof (m_opcode));
|
::memset (&m_opcode, 0, sizeof (m_opcode));
|
||||||
}
|
}
|
||||||
|
@ -99,7 +68,7 @@ uint64_t
|
||||||
EmulateInstruction::ReadRegisterUnsigned (uint32_t reg_kind, uint32_t reg_num, uint64_t fail_value, bool *success_ptr)
|
EmulateInstruction::ReadRegisterUnsigned (uint32_t reg_kind, uint32_t reg_num, uint64_t fail_value, bool *success_ptr)
|
||||||
{
|
{
|
||||||
uint64_t uval64 = 0;
|
uint64_t uval64 = 0;
|
||||||
bool success = m_read_reg_callback (m_baton, reg_kind, reg_num, uval64);
|
bool success = m_read_reg_callback (this, m_baton, reg_kind, reg_num, uval64);
|
||||||
if (success_ptr)
|
if (success_ptr)
|
||||||
*success_ptr = success;
|
*success_ptr = success;
|
||||||
if (!success)
|
if (!success)
|
||||||
|
@ -110,7 +79,7 @@ EmulateInstruction::ReadRegisterUnsigned (uint32_t reg_kind, uint32_t reg_num, u
|
||||||
bool
|
bool
|
||||||
EmulateInstruction::WriteRegisterUnsigned (const Context &context, uint32_t reg_kind, uint32_t reg_num, uint64_t reg_value)
|
EmulateInstruction::WriteRegisterUnsigned (const Context &context, uint32_t reg_kind, uint32_t reg_num, uint64_t reg_value)
|
||||||
{
|
{
|
||||||
return m_write_reg_callback (m_baton, context, reg_kind, reg_num, reg_value);
|
return m_write_reg_callback (this, m_baton, context, reg_kind, reg_num, reg_value);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t
|
uint64_t
|
||||||
|
@ -121,11 +90,11 @@ EmulateInstruction::ReadMemoryUnsigned (const Context &context, lldb::addr_t add
|
||||||
if (byte_size <= 8)
|
if (byte_size <= 8)
|
||||||
{
|
{
|
||||||
uint8_t buf[sizeof(uint64_t)];
|
uint8_t buf[sizeof(uint64_t)];
|
||||||
size_t bytes_read = m_read_mem_callback (m_baton, context, addr, buf, byte_size);
|
size_t bytes_read = m_read_mem_callback (this, m_baton, context, addr, buf, byte_size);
|
||||||
if (bytes_read == byte_size)
|
if (bytes_read == byte_size)
|
||||||
{
|
{
|
||||||
uint32_t offset = 0;
|
uint32_t offset = 0;
|
||||||
DataExtractor data (buf, byte_size, m_byte_order, m_addr_byte_size);
|
DataExtractor data (buf, byte_size, GetByteOrder(), GetAddressByteSize());
|
||||||
uval64 = data.GetMaxU64 (&offset, byte_size);
|
uval64 = data.GetMaxU64 (&offset, byte_size);
|
||||||
success = true;
|
success = true;
|
||||||
}
|
}
|
||||||
|
@ -149,7 +118,7 @@ EmulateInstruction::WriteMemoryUnsigned (const Context &context,
|
||||||
StreamString strm(Stream::eBinary, GetAddressByteSize(), GetByteOrder());
|
StreamString strm(Stream::eBinary, GetAddressByteSize(), GetByteOrder());
|
||||||
strm.PutMaxHex64 (uval, uval_byte_size);
|
strm.PutMaxHex64 (uval, uval_byte_size);
|
||||||
|
|
||||||
size_t bytes_written = m_write_mem_callback (m_baton, context, addr, strm.GetData(), uval_byte_size);
|
size_t bytes_written = m_write_mem_callback (this, m_baton, context, addr, strm.GetData(), uval_byte_size);
|
||||||
if (bytes_written == uval_byte_size)
|
if (bytes_written == uval_byte_size)
|
||||||
return true;
|
return true;
|
||||||
return false;
|
return false;
|
||||||
|
@ -208,7 +177,8 @@ EmulateInstruction::SetWriteRegCallback (WriteRegister write_reg_callback)
|
||||||
//
|
//
|
||||||
|
|
||||||
size_t
|
size_t
|
||||||
EmulateInstruction::ReadMemoryFrame (void *baton,
|
EmulateInstruction::ReadMemoryFrame (EmulateInstruction *instruction,
|
||||||
|
void *baton,
|
||||||
const Context &context,
|
const Context &context,
|
||||||
lldb::addr_t addr,
|
lldb::addr_t addr,
|
||||||
void *dst,
|
void *dst,
|
||||||
|
@ -233,7 +203,8 @@ EmulateInstruction::ReadMemoryFrame (void *baton,
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t
|
size_t
|
||||||
EmulateInstruction::WriteMemoryFrame (void *baton,
|
EmulateInstruction::WriteMemoryFrame (EmulateInstruction *instruction,
|
||||||
|
void *baton,
|
||||||
const Context &context,
|
const Context &context,
|
||||||
lldb::addr_t addr,
|
lldb::addr_t addr,
|
||||||
const void *dst,
|
const void *dst,
|
||||||
|
@ -262,7 +233,8 @@ EmulateInstruction::WriteMemoryFrame (void *baton,
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
EmulateInstruction::ReadRegisterFrame (void *baton,
|
EmulateInstruction::ReadRegisterFrame (EmulateInstruction *instruction,
|
||||||
|
void *baton,
|
||||||
uint32_t reg_kind,
|
uint32_t reg_kind,
|
||||||
uint32_t reg_num,
|
uint32_t reg_num,
|
||||||
uint64_t ®_value)
|
uint64_t ®_value)
|
||||||
|
@ -289,7 +261,8 @@ EmulateInstruction::ReadRegisterFrame (void *baton,
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
EmulateInstruction::WriteRegisterFrame (void *baton,
|
EmulateInstruction::WriteRegisterFrame (EmulateInstruction *instruction,
|
||||||
|
void *baton,
|
||||||
const Context &context,
|
const Context &context,
|
||||||
uint32_t reg_kind,
|
uint32_t reg_kind,
|
||||||
uint32_t reg_num,
|
uint32_t reg_num,
|
||||||
|
@ -310,7 +283,8 @@ EmulateInstruction::WriteRegisterFrame (void *baton,
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t
|
size_t
|
||||||
EmulateInstruction::ReadMemoryDefault (void *baton,
|
EmulateInstruction::ReadMemoryDefault (EmulateInstruction *instruction,
|
||||||
|
void *baton,
|
||||||
const Context &context,
|
const Context &context,
|
||||||
lldb::addr_t addr,
|
lldb::addr_t addr,
|
||||||
void *dst,
|
void *dst,
|
||||||
|
@ -324,7 +298,8 @@ EmulateInstruction::ReadMemoryDefault (void *baton,
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t
|
size_t
|
||||||
EmulateInstruction::WriteMemoryDefault (void *baton,
|
EmulateInstruction::WriteMemoryDefault (EmulateInstruction *instruction,
|
||||||
|
void *baton,
|
||||||
const Context &context,
|
const Context &context,
|
||||||
lldb::addr_t addr,
|
lldb::addr_t addr,
|
||||||
const void *dst,
|
const void *dst,
|
||||||
|
@ -336,7 +311,8 @@ EmulateInstruction::WriteMemoryDefault (void *baton,
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
EmulateInstruction::ReadRegisterDefault (void *baton,
|
EmulateInstruction::ReadRegisterDefault (EmulateInstruction *instruction,
|
||||||
|
void *baton,
|
||||||
uint32_t reg_kind,
|
uint32_t reg_kind,
|
||||||
uint32_t reg_num,
|
uint32_t reg_num,
|
||||||
uint64_t ®_value)
|
uint64_t ®_value)
|
||||||
|
@ -350,7 +326,8 @@ EmulateInstruction::ReadRegisterDefault (void *baton,
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
EmulateInstruction::WriteRegisterDefault (void *baton,
|
EmulateInstruction::WriteRegisterDefault (EmulateInstruction *instruction,
|
||||||
|
void *baton,
|
||||||
const Context &context,
|
const Context &context,
|
||||||
uint32_t reg_kind,
|
uint32_t reg_kind,
|
||||||
uint32_t reg_num,
|
uint32_t reg_num,
|
||||||
|
@ -601,54 +578,69 @@ EmulateInstruction::PrintContext (const char *context_type, const Context &conte
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
bool
|
||||||
EmulateInstruction::TranslateRegister (uint32_t kind, uint32_t num, std::string &name)
|
EmulateInstruction::SetInstruction (const Opcode &opcode, const Address &inst_addr, Target *target)
|
||||||
{
|
{
|
||||||
if (kind == eRegisterKindDWARF)
|
m_opcode = opcode;
|
||||||
|
m_opcode_pc = LLDB_INVALID_ADDRESS;
|
||||||
|
if (inst_addr.IsValid())
|
||||||
{
|
{
|
||||||
if (num == 13) //dwarf_sp NOTE: This is ARM-SPECIFIC
|
if (target)
|
||||||
name = "sp";
|
m_opcode_pc = inst_addr.GetLoadAddress (target);
|
||||||
else if (num == 14) //dwarf_lr NOTE: This is ARM-SPECIFIC
|
if (m_opcode_pc == LLDB_INVALID_ADDRESS)
|
||||||
name = "lr";
|
m_opcode_pc = inst_addr.GetFileAddress ();
|
||||||
else if (num == 15) //dwarf_pc NOTE: This is ARM-SPECIFIC
|
|
||||||
name = "pc";
|
|
||||||
else if (num == 16) //dwarf_cpsr NOTE: This is ARM-SPECIFIC
|
|
||||||
name = "cpsr";
|
|
||||||
else
|
|
||||||
{
|
|
||||||
StreamString sstr;
|
|
||||||
|
|
||||||
sstr.Printf ("r%d", num);
|
|
||||||
name = sstr.GetData();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
else if (kind == eRegisterKindGeneric)
|
|
||||||
{
|
|
||||||
if (num == LLDB_REGNUM_GENERIC_SP)
|
|
||||||
name = "sp";
|
|
||||||
else if (num == LLDB_REGNUM_GENERIC_FLAGS)
|
|
||||||
name = "cpsr";
|
|
||||||
else if (num == LLDB_REGNUM_GENERIC_PC)
|
|
||||||
name = "pc";
|
|
||||||
else if (num == LLDB_REGNUM_GENERIC_RA)
|
|
||||||
name = "lr";
|
|
||||||
else
|
|
||||||
{
|
|
||||||
StreamString sstr;
|
|
||||||
|
|
||||||
sstr.Printf ("r%d", num);
|
|
||||||
name = sstr.GetData();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
StreamString sstr;
|
|
||||||
|
|
||||||
sstr.Printf ("r%d", num);
|
|
||||||
name = sstr.GetData();
|
|
||||||
}
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const char *
|
||||||
|
EmulateInstruction::TranslateRegister (uint32_t kind, uint32_t num, std::string &name)
|
||||||
|
{
|
||||||
|
if (kind == eRegisterKindGeneric)
|
||||||
|
{
|
||||||
|
switch (num)
|
||||||
|
{
|
||||||
|
case LLDB_REGNUM_GENERIC_PC: name = "pc"; break;
|
||||||
|
case LLDB_REGNUM_GENERIC_SP: name = "sp"; break;
|
||||||
|
case LLDB_REGNUM_GENERIC_FP: name = "fp"; break;
|
||||||
|
case LLDB_REGNUM_GENERIC_RA: name = "ra"; break;
|
||||||
|
case LLDB_REGNUM_GENERIC_FLAGS: name = "flags"; break;
|
||||||
|
default: name.clear(); break;
|
||||||
|
}
|
||||||
|
if (!name.empty())
|
||||||
|
return name.c_str();
|
||||||
|
}
|
||||||
|
const char *kind_cstr = NULL;
|
||||||
|
|
||||||
|
switch (kind)
|
||||||
|
{
|
||||||
|
case eRegisterKindGCC: // the register numbers seen in eh_frame
|
||||||
|
kind_cstr = "gcc";
|
||||||
|
break;
|
||||||
|
|
||||||
|
case eRegisterKindDWARF: // the register numbers seen DWARF
|
||||||
|
kind_cstr = "dwarf";
|
||||||
|
break;
|
||||||
|
|
||||||
|
case eRegisterKindGeneric: // insn ptr reg, stack ptr reg, etc not specific to any particular target
|
||||||
|
kind_cstr = "generic";
|
||||||
|
break;
|
||||||
|
|
||||||
|
case eRegisterKindGDB: // the register numbers gdb uses (matches stabs numbers?)
|
||||||
|
kind_cstr = "gdb";
|
||||||
|
break;
|
||||||
|
|
||||||
|
case eRegisterKindLLDB: // lldb's internal register numbers
|
||||||
|
kind_cstr = "lldb";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
StreamString sstr;
|
||||||
|
sstr.Printf ("%s(%u)", kind_cstr, num);
|
||||||
|
name.swap (sstr.GetString());
|
||||||
|
return name.c_str();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -15,8 +15,8 @@
|
||||||
using namespace lldb;
|
using namespace lldb;
|
||||||
using namespace lldb_private;
|
using namespace lldb_private;
|
||||||
|
|
||||||
lldb_private::ArchDefaultUnwindPlan *
|
ArchDefaultUnwindPlan *
|
||||||
ArchDefaultUnwindPlan_x86_64::CreateInstance (const lldb_private::ArchSpec &arch)
|
ArchDefaultUnwindPlan_x86_64::CreateInstance (const ArchSpec &arch)
|
||||||
{
|
{
|
||||||
if (arch.GetMachine () == llvm::Triple::x86_64)
|
if (arch.GetMachine () == llvm::Triple::x86_64)
|
||||||
return new ArchDefaultUnwindPlan_x86_64 ();
|
return new ArchDefaultUnwindPlan_x86_64 ();
|
||||||
|
@ -24,7 +24,7 @@ ArchDefaultUnwindPlan_x86_64::CreateInstance (const lldb_private::ArchSpec &arch
|
||||||
}
|
}
|
||||||
|
|
||||||
ArchDefaultUnwindPlan_x86_64::ArchDefaultUnwindPlan_x86_64() :
|
ArchDefaultUnwindPlan_x86_64::ArchDefaultUnwindPlan_x86_64() :
|
||||||
lldb_private::ArchDefaultUnwindPlan(),
|
ArchDefaultUnwindPlan(),
|
||||||
m_unwind_plan_sp (new UnwindPlan)
|
m_unwind_plan_sp (new UnwindPlan)
|
||||||
{
|
{
|
||||||
UnwindPlan::Row row;
|
UnwindPlan::Row row;
|
||||||
|
@ -96,15 +96,16 @@ ArchDefaultUnwindPlan_x86_64::GetPluginDescriptionStatic()
|
||||||
}
|
}
|
||||||
|
|
||||||
UnwindPlanSP
|
UnwindPlanSP
|
||||||
ArchDefaultUnwindPlan_x86_64::GetArchDefaultUnwindPlan (Thread& thread, Address current_pc)
|
ArchDefaultUnwindPlan_x86_64::GetArchDefaultUnwindPlan (Thread& thread,
|
||||||
|
const Address ¤t_pc)
|
||||||
{
|
{
|
||||||
return m_unwind_plan_sp;
|
return m_unwind_plan_sp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
lldb_private::ArchDefaultUnwindPlan *
|
ArchDefaultUnwindPlan *
|
||||||
ArchDefaultUnwindPlan_i386::CreateInstance (const lldb_private::ArchSpec &arch)
|
ArchDefaultUnwindPlan_i386::CreateInstance (const ArchSpec &arch)
|
||||||
{
|
{
|
||||||
if (arch.GetMachine () == llvm::Triple::x86)
|
if (arch.GetMachine () == llvm::Triple::x86)
|
||||||
return new ArchDefaultUnwindPlan_i386 ();
|
return new ArchDefaultUnwindPlan_i386 ();
|
||||||
|
@ -112,7 +113,7 @@ ArchDefaultUnwindPlan_i386::CreateInstance (const lldb_private::ArchSpec &arch)
|
||||||
}
|
}
|
||||||
|
|
||||||
ArchDefaultUnwindPlan_i386::ArchDefaultUnwindPlan_i386() :
|
ArchDefaultUnwindPlan_i386::ArchDefaultUnwindPlan_i386() :
|
||||||
lldb_private::ArchDefaultUnwindPlan(),
|
ArchDefaultUnwindPlan(),
|
||||||
m_unwind_plan_sp (new UnwindPlan)
|
m_unwind_plan_sp (new UnwindPlan)
|
||||||
{
|
{
|
||||||
UnwindPlan::Row row;
|
UnwindPlan::Row row;
|
||||||
|
@ -185,7 +186,7 @@ ArchDefaultUnwindPlan_i386::GetPluginDescriptionStatic()
|
||||||
}
|
}
|
||||||
|
|
||||||
UnwindPlanSP
|
UnwindPlanSP
|
||||||
ArchDefaultUnwindPlan_i386::GetArchDefaultUnwindPlan (Thread& thread, Address current_pc)
|
ArchDefaultUnwindPlan_i386::GetArchDefaultUnwindPlan (Thread& thread, const Address ¤t_pc)
|
||||||
{
|
{
|
||||||
return m_unwind_plan_sp;
|
return m_unwind_plan_sp;
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,8 +15,6 @@
|
||||||
#include "lldb/Target/Thread.h"
|
#include "lldb/Target/Thread.h"
|
||||||
#include "lldb/Symbol/UnwindPlan.h"
|
#include "lldb/Symbol/UnwindPlan.h"
|
||||||
|
|
||||||
namespace lldb_private {
|
|
||||||
|
|
||||||
class ArchDefaultUnwindPlan_x86_64 : public lldb_private::ArchDefaultUnwindPlan
|
class ArchDefaultUnwindPlan_x86_64 : public lldb_private::ArchDefaultUnwindPlan
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -24,7 +22,8 @@ public:
|
||||||
~ArchDefaultUnwindPlan_x86_64 () { }
|
~ArchDefaultUnwindPlan_x86_64 () { }
|
||||||
|
|
||||||
virtual lldb::UnwindPlanSP
|
virtual lldb::UnwindPlanSP
|
||||||
GetArchDefaultUnwindPlan (Thread& thread, Address current_pc);
|
GetArchDefaultUnwindPlan (lldb_private::Thread& thread,
|
||||||
|
const lldb_private::Address ¤t_pc);
|
||||||
|
|
||||||
static lldb_private::ArchDefaultUnwindPlan *
|
static lldb_private::ArchDefaultUnwindPlan *
|
||||||
CreateInstance (const lldb_private::ArchSpec &arch);
|
CreateInstance (const lldb_private::ArchSpec &arch);
|
||||||
|
@ -66,7 +65,8 @@ public:
|
||||||
~ArchDefaultUnwindPlan_i386 () { }
|
~ArchDefaultUnwindPlan_i386 () { }
|
||||||
|
|
||||||
virtual lldb::UnwindPlanSP
|
virtual lldb::UnwindPlanSP
|
||||||
GetArchDefaultUnwindPlan (Thread& thread, Address current_pc);
|
GetArchDefaultUnwindPlan (lldb_private::Thread& thread,
|
||||||
|
const lldb_private::Address& current_pc);
|
||||||
|
|
||||||
static lldb_private::ArchDefaultUnwindPlan *
|
static lldb_private::ArchDefaultUnwindPlan *
|
||||||
CreateInstance (const lldb_private::ArchSpec &arch);
|
CreateInstance (const lldb_private::ArchSpec &arch);
|
||||||
|
@ -101,7 +101,4 @@ private:
|
||||||
lldb::UnwindPlanSP m_unwind_plan_sp;
|
lldb::UnwindPlanSP m_unwind_plan_sp;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
} // namespace lldb_private
|
|
||||||
|
|
||||||
#endif // liblldb_UnwindAssembly_x86_h_
|
#endif // liblldb_UnwindAssembly_x86_h_
|
||||||
|
|
|
@ -15,8 +15,6 @@
|
||||||
#include "lldb/Target/ArchVolatileRegs.h"
|
#include "lldb/Target/ArchVolatileRegs.h"
|
||||||
#include <set>
|
#include <set>
|
||||||
|
|
||||||
namespace lldb_private {
|
|
||||||
|
|
||||||
class ArchVolatileRegs_x86 : public lldb_private::ArchVolatileRegs
|
class ArchVolatileRegs_x86 : public lldb_private::ArchVolatileRegs
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -62,7 +60,4 @@ private:
|
||||||
std::set<int> m_non_volatile_regs;
|
std::set<int> m_non_volatile_regs;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
} // namespace lldb_private
|
|
||||||
|
|
||||||
#endif // liblldb_ArchVolatileRegs_x86_h_
|
#endif // liblldb_ArchVolatileRegs_x86_h_
|
||||||
|
|
|
@ -181,21 +181,24 @@ EmulateInstructionARM::GetPluginDescriptionStatic ()
|
||||||
}
|
}
|
||||||
|
|
||||||
EmulateInstruction *
|
EmulateInstruction *
|
||||||
EmulateInstructionARM::CreateInstance (const ArchSpec &arch)
|
EmulateInstructionARM::CreateInstance (const ArchSpec &arch, InstructionType inst_type)
|
||||||
{
|
{
|
||||||
if (arch.GetTriple().getArch() == llvm::Triple::arm)
|
if (EmulateInstructionARM::SupportsEmulatingIntructionsOfTypeStatic(inst_type))
|
||||||
{
|
{
|
||||||
std::auto_ptr<EmulateInstructionARM> emulate_insn_ap (new EmulateInstructionARM (arch));
|
if (arch.GetTriple().getArch() == llvm::Triple::arm)
|
||||||
|
{
|
||||||
if (emulate_insn_ap.get())
|
std::auto_ptr<EmulateInstructionARM> emulate_insn_ap (new EmulateInstructionARM (arch));
|
||||||
return emulate_insn_ap.release();
|
|
||||||
}
|
if (emulate_insn_ap.get())
|
||||||
else if (arch.GetTriple().getArch() == llvm::Triple::thumb)
|
return emulate_insn_ap.release();
|
||||||
{
|
}
|
||||||
std::auto_ptr<EmulateInstructionARM> emulate_insn_ap (new EmulateInstructionARM (arch));
|
else if (arch.GetTriple().getArch() == llvm::Triple::thumb)
|
||||||
|
{
|
||||||
if (emulate_insn_ap.get())
|
std::auto_ptr<EmulateInstructionARM> emulate_insn_ap (new EmulateInstructionARM (arch));
|
||||||
return emulate_insn_ap.release();
|
|
||||||
|
if (emulate_insn_ap.get())
|
||||||
|
return emulate_insn_ap.release();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -340,7 +343,7 @@ EmulateInstructionARM::EmulatePUSH (const uint32_t opcode, const ARMEncoding enc
|
||||||
Register dwarf_reg;
|
Register dwarf_reg;
|
||||||
dwarf_reg.SetRegister (eRegisterKindDWARF, 0);
|
dwarf_reg.SetRegister (eRegisterKindDWARF, 0);
|
||||||
Register sp_reg;
|
Register sp_reg;
|
||||||
sp_reg.SetRegister (eRegisterKindDWARF, dwarf_sp);
|
sp_reg.SetRegister (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP);
|
||||||
for (i=0; i<15; ++i)
|
for (i=0; i<15; ++i)
|
||||||
{
|
{
|
||||||
if (BitIsSet (registers, i))
|
if (BitIsSet (registers, i))
|
||||||
|
@ -1247,7 +1250,7 @@ EmulateInstructionARM::EmulateADDSPImm (const uint32_t opcode, const ARMEncoding
|
||||||
EmulateInstruction::Context context;
|
EmulateInstruction::Context context;
|
||||||
context.type = EmulateInstruction::eContextAdjustStackPointer;
|
context.type = EmulateInstruction::eContextAdjustStackPointer;
|
||||||
Register sp_reg;
|
Register sp_reg;
|
||||||
sp_reg.SetRegister (eRegisterKindDWARF, dwarf_sp);
|
sp_reg.SetRegister (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP);
|
||||||
context.SetRegisterPlusOffset (sp_reg, sp_offset);
|
context.SetRegisterPlusOffset (sp_reg, sp_offset);
|
||||||
|
|
||||||
if (d == 15)
|
if (d == 15)
|
||||||
|
@ -1312,7 +1315,7 @@ EmulateInstructionARM::EmulateADDSPRm (const uint32_t opcode, const ARMEncoding
|
||||||
EmulateInstruction::Context context;
|
EmulateInstruction::Context context;
|
||||||
context.type = EmulateInstruction::eContextAddition;
|
context.type = EmulateInstruction::eContextAddition;
|
||||||
Register sp_reg;
|
Register sp_reg;
|
||||||
sp_reg.SetRegister (eRegisterKindDWARF, dwarf_sp);
|
sp_reg.SetRegister (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP);
|
||||||
Register other_reg;
|
Register other_reg;
|
||||||
other_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + Rm);
|
other_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + Rm);
|
||||||
context.SetRegisterRegisterOperands (sp_reg, other_reg);
|
context.SetRegisterRegisterOperands (sp_reg, other_reg);
|
||||||
|
@ -1849,7 +1852,7 @@ EmulateInstructionARM::EmulateSTRRtSP (const uint32_t opcode, const ARMEncoding
|
||||||
EmulateInstruction::Context context;
|
EmulateInstruction::Context context;
|
||||||
context.type = EmulateInstruction::eContextPushRegisterOnStack;
|
context.type = EmulateInstruction::eContextPushRegisterOnStack;
|
||||||
Register sp_reg;
|
Register sp_reg;
|
||||||
sp_reg.SetRegister (eRegisterKindDWARF, dwarf_sp);
|
sp_reg.SetRegister (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP);
|
||||||
context.SetRegisterPlusOffset (sp_reg, addr - sp);
|
context.SetRegisterPlusOffset (sp_reg, addr - sp);
|
||||||
if (Rt != 15)
|
if (Rt != 15)
|
||||||
{
|
{
|
||||||
|
@ -1952,7 +1955,7 @@ EmulateInstructionARM::EmulateVPUSH (const uint32_t opcode, const ARMEncoding en
|
||||||
Register dwarf_reg;
|
Register dwarf_reg;
|
||||||
dwarf_reg.SetRegister (eRegisterKindDWARF, 0);
|
dwarf_reg.SetRegister (eRegisterKindDWARF, 0);
|
||||||
Register sp_reg;
|
Register sp_reg;
|
||||||
sp_reg.SetRegister (eRegisterKindDWARF, dwarf_sp);
|
sp_reg.SetRegister (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP);
|
||||||
for (i=0; i<regs; ++i)
|
for (i=0; i<regs; ++i)
|
||||||
{
|
{
|
||||||
dwarf_reg.num = start_reg + d + i;
|
dwarf_reg.num = start_reg + d + i;
|
||||||
|
@ -2047,7 +2050,7 @@ EmulateInstructionARM::EmulateVPOP (const uint32_t opcode, const ARMEncoding enc
|
||||||
Register dwarf_reg;
|
Register dwarf_reg;
|
||||||
dwarf_reg.SetRegister (eRegisterKindDWARF, 0);
|
dwarf_reg.SetRegister (eRegisterKindDWARF, 0);
|
||||||
Register sp_reg;
|
Register sp_reg;
|
||||||
sp_reg.SetRegister (eRegisterKindDWARF, dwarf_sp);
|
sp_reg.SetRegister (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP);
|
||||||
for (i=0; i<regs; ++i)
|
for (i=0; i<regs; ++i)
|
||||||
{
|
{
|
||||||
dwarf_reg.num = start_reg + d + i;
|
dwarf_reg.num = start_reg + d + i;
|
||||||
|
@ -9330,7 +9333,7 @@ EmulateInstructionARM::EmulateSUBSPReg (const uint32_t opcode, const ARMEncoding
|
||||||
EmulateInstruction::Context context;
|
EmulateInstruction::Context context;
|
||||||
context.type = eContextSubtraction;
|
context.type = eContextSubtraction;
|
||||||
Register sp_reg;
|
Register sp_reg;
|
||||||
sp_reg.SetRegister (eRegisterKindDWARF, dwarf_sp);
|
sp_reg.SetRegister (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP);
|
||||||
Register dwarf_reg;
|
Register dwarf_reg;
|
||||||
dwarf_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + m);
|
dwarf_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + m);
|
||||||
context.SetRegisterRegisterOperands (sp_reg, dwarf_reg);
|
context.SetRegisterRegisterOperands (sp_reg, dwarf_reg);
|
||||||
|
@ -10604,7 +10607,7 @@ EmulateInstructionARM::EmulateVLDM (const uint32_t opcode, const ARMEncoding enc
|
||||||
// // Combine the word-aligned words in the correct order for current endianness.
|
// // Combine the word-aligned words in the correct order for current endianness.
|
||||||
// D[d+r] = if BigEndian() then word1:word2 else word2:word1;
|
// D[d+r] = if BigEndian() then word1:word2 else word2:word1;
|
||||||
uint64_t data;
|
uint64_t data;
|
||||||
if (m_byte_order == eByteOrderBig)
|
if (GetByteOrder() == eByteOrderBig)
|
||||||
{
|
{
|
||||||
data = word1;
|
data = word1;
|
||||||
data = (data << 32) | word2;
|
data = (data << 32) | word2;
|
||||||
|
@ -10791,7 +10794,7 @@ EmulateInstructionARM::EmulateVSTM (const uint32_t opcode, const ARMEncoding enc
|
||||||
|
|
||||||
data_reg.num = start_reg + d + r;
|
data_reg.num = start_reg + d + r;
|
||||||
|
|
||||||
if (m_byte_order == eByteOrderBig)
|
if (GetByteOrder() == eByteOrderBig)
|
||||||
{
|
{
|
||||||
context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn);
|
context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn);
|
||||||
if (!MemAWrite (context, address, Bits64 (data, 63, 32), addr_byte_size))
|
if (!MemAWrite (context, address, Bits64 (data, 63, 32), addr_byte_size))
|
||||||
|
@ -10931,7 +10934,7 @@ EmulateInstructionARM::EmulateVLDR (const uint32_t opcode, ARMEncoding encoding)
|
||||||
// // Combine the word-aligned words in the correct order for current endianness.
|
// // Combine the word-aligned words in the correct order for current endianness.
|
||||||
// D[d] = if BigEndian() then word1:word2 else word2:word1;
|
// D[d] = if BigEndian() then word1:word2 else word2:word1;
|
||||||
uint64_t data64;
|
uint64_t data64;
|
||||||
if (m_byte_order == eByteOrderBig)
|
if (GetByteOrder() == eByteOrderBig)
|
||||||
{
|
{
|
||||||
data64 = word1;
|
data64 = word1;
|
||||||
data64 = (data64 << 32) | word2;
|
data64 = (data64 << 32) | word2;
|
||||||
|
@ -11059,7 +11062,7 @@ EmulateInstructionARM::EmulateVSTR (const uint32_t opcode, ARMEncoding encoding)
|
||||||
if (!success)
|
if (!success)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (m_byte_order == eByteOrderBig)
|
if (GetByteOrder() == eByteOrderBig)
|
||||||
{
|
{
|
||||||
if (!MemAWrite (context, address, Bits64 (data, 63, 32), addr_byte_size))
|
if (!MemAWrite (context, address, Bits64 (data, 63, 32), addr_byte_size))
|
||||||
return false;
|
return false;
|
||||||
|
@ -12064,7 +12067,7 @@ EmulateInstructionARM::EmulateSUBSPcLrEtc (const uint32_t opcode, const ARMEncod
|
||||||
}
|
}
|
||||||
|
|
||||||
EmulateInstructionARM::ARMOpcode*
|
EmulateInstructionARM::ARMOpcode*
|
||||||
EmulateInstructionARM::GetARMOpcodeForInstruction (const uint32_t opcode)
|
EmulateInstructionARM::GetARMOpcodeForInstruction (const uint32_t opcode, uint32_t arm_isa)
|
||||||
{
|
{
|
||||||
static ARMOpcode
|
static ARMOpcode
|
||||||
g_arm_opcodes[] =
|
g_arm_opcodes[] =
|
||||||
|
@ -12289,7 +12292,8 @@ EmulateInstructionARM::GetARMOpcodeForInstruction (const uint32_t opcode)
|
||||||
|
|
||||||
for (size_t i=0; i<k_num_arm_opcodes; ++i)
|
for (size_t i=0; i<k_num_arm_opcodes; ++i)
|
||||||
{
|
{
|
||||||
if ((g_arm_opcodes[i].mask & opcode) == g_arm_opcodes[i].value)
|
if ((g_arm_opcodes[i].mask & opcode) == g_arm_opcodes[i].value &&
|
||||||
|
(g_arm_opcodes[i].variants & arm_isa) != 0)
|
||||||
return &g_arm_opcodes[i];
|
return &g_arm_opcodes[i];
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -12297,7 +12301,7 @@ EmulateInstructionARM::GetARMOpcodeForInstruction (const uint32_t opcode)
|
||||||
|
|
||||||
|
|
||||||
EmulateInstructionARM::ARMOpcode*
|
EmulateInstructionARM::ARMOpcode*
|
||||||
EmulateInstructionARM::GetThumbOpcodeForInstruction (const uint32_t opcode)
|
EmulateInstructionARM::GetThumbOpcodeForInstruction (const uint32_t opcode, uint32_t arm_isa)
|
||||||
{
|
{
|
||||||
|
|
||||||
static ARMOpcode
|
static ARMOpcode
|
||||||
|
@ -12607,7 +12611,8 @@ EmulateInstructionARM::GetThumbOpcodeForInstruction (const uint32_t opcode)
|
||||||
const size_t k_num_thumb_opcodes = sizeof(g_thumb_opcodes)/sizeof(ARMOpcode);
|
const size_t k_num_thumb_opcodes = sizeof(g_thumb_opcodes)/sizeof(ARMOpcode);
|
||||||
for (size_t i=0; i<k_num_thumb_opcodes; ++i)
|
for (size_t i=0; i<k_num_thumb_opcodes; ++i)
|
||||||
{
|
{
|
||||||
if ((g_thumb_opcodes[i].mask & opcode) == g_thumb_opcodes[i].value)
|
if ((g_thumb_opcodes[i].mask & opcode) == g_thumb_opcodes[i].value &&
|
||||||
|
(g_thumb_opcodes[i].variants & arm_isa) != 0)
|
||||||
return &g_thumb_opcodes[i];
|
return &g_thumb_opcodes[i];
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -12636,24 +12641,30 @@ EmulateInstructionARM::SetArchitecture (const ArchSpec &arch)
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
EmulateInstructionARM::SetInstruction (const Opcode &insn_opcode, const Address &inst_addr)
|
EmulateInstructionARM::SetInstruction (const Opcode &insn_opcode, const Address &inst_addr, Target *target)
|
||||||
{
|
{
|
||||||
m_opcode = insn_opcode;
|
if (EmulateInstruction::SetInstruction (insn_opcode, inst_addr, target))
|
||||||
|
{
|
||||||
|
if (m_arch.GetTriple().getArch() == llvm::Triple::thumb)
|
||||||
|
m_opcode_mode = eModeThumb;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
AddressClass addr_class = inst_addr.GetAddressClass();
|
||||||
|
|
||||||
if (m_arch.GetTriple().getArch() == llvm::Triple::thumb)
|
if ((addr_class == eAddressClassCode) || (addr_class == eAddressClassUnknown))
|
||||||
m_opcode_mode = eModeThumb;
|
m_opcode_mode = eModeARM;
|
||||||
else
|
else if (addr_class == eAddressClassCodeAlternateISA)
|
||||||
{
|
m_opcode_mode = eModeThumb;
|
||||||
AddressClass addr_class = inst_addr.GetAddressClass();
|
else
|
||||||
|
return false;
|
||||||
if ((addr_class == eAddressClassCode) || (addr_class == eAddressClassUnknown))
|
}
|
||||||
m_opcode_mode = eModeARM;
|
if (m_opcode_mode == eModeThumb)
|
||||||
else if (addr_class == eAddressClassCodeAlternateISA)
|
m_opcode_cpsr = CPSR_MODE_USR | MASK_CPSR_T;
|
||||||
m_opcode_mode = eModeThumb;
|
else
|
||||||
else
|
m_opcode_cpsr = CPSR_MODE_USR;
|
||||||
return false;
|
return true;
|
||||||
}
|
}
|
||||||
return true;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
|
@ -12711,6 +12722,12 @@ EmulateInstructionARM::ArchVersion ()
|
||||||
bool
|
bool
|
||||||
EmulateInstructionARM::ConditionPassed (const uint32_t opcode)
|
EmulateInstructionARM::ConditionPassed (const uint32_t opcode)
|
||||||
{
|
{
|
||||||
|
// If we are ignoring conditions, then always return true.
|
||||||
|
// this allows us to iterate over disassembly code and still
|
||||||
|
// emulate an instruction even if we don't have all the right
|
||||||
|
// bits set in the CPSR register...
|
||||||
|
if (m_ignore_conditions)
|
||||||
|
return true;
|
||||||
|
|
||||||
const uint32_t cond = CurrentCond (opcode);
|
const uint32_t cond = CurrentCond (opcode);
|
||||||
|
|
||||||
|
@ -12855,7 +12872,7 @@ EmulateInstructionARM::CurrentModeIsPrivileged ()
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (mode == 16)
|
if (mode == 16)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -13188,123 +13205,72 @@ EmulateInstructionARM::WriteFlags (Context &context,
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
EmulateInstructionARM::EvaluateInstruction ()
|
EmulateInstructionARM::EvaluateInstruction (uint32_t evaluate_options)
|
||||||
{
|
{
|
||||||
// Advance the ITSTATE bits to their values for the next instruction.
|
// Advance the ITSTATE bits to their values for the next instruction.
|
||||||
if (m_opcode_mode == eModeThumb && m_it_session.InITBlock())
|
if (m_opcode_mode == eModeThumb && m_it_session.InITBlock())
|
||||||
m_it_session.ITAdvance();
|
m_it_session.ITAdvance();
|
||||||
|
|
||||||
|
ARMOpcode *opcode_data = NULL;
|
||||||
ARMOpcode *opcode_data;
|
|
||||||
|
|
||||||
if (m_opcode_mode == eModeThumb)
|
if (m_opcode_mode == eModeThumb)
|
||||||
opcode_data = GetThumbOpcodeForInstruction (m_opcode.GetOpcode32());
|
opcode_data = GetThumbOpcodeForInstruction (m_opcode.GetOpcode32(), m_arm_isa);
|
||||||
else if (m_opcode_mode == eModeARM)
|
else if (m_opcode_mode == eModeARM)
|
||||||
opcode_data = GetARMOpcodeForInstruction (m_opcode.GetOpcode32());
|
opcode_data = GetARMOpcodeForInstruction (m_opcode.GetOpcode32(), m_arm_isa);
|
||||||
else
|
|
||||||
|
if (opcode_data == NULL)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (!opcode_data)
|
|
||||||
return false;
|
|
||||||
// Verify that we're the right arch for this opcode
|
|
||||||
|
|
||||||
switch (m_arm_isa)
|
const bool auto_advance_pc = evaluate_options & eEmulateInstructionOptionAutoAdvancePC;
|
||||||
{
|
m_ignore_conditions = evaluate_options & eEmulateInstructionOptionIgnoreConditions;
|
||||||
case ARMv4:
|
|
||||||
if (opcode_data->variants != ARMvAll)
|
|
||||||
return false;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case ARMv4T:
|
|
||||||
if ((opcode_data->variants!= ARMvAll)
|
|
||||||
&& (opcode_data->variants != ARMV4T_ABOVE))
|
|
||||||
return false;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case ARMv5T:
|
|
||||||
case ARMv5TE:
|
|
||||||
if ((opcode_data->variants != ARMvAll)
|
|
||||||
&& (opcode_data->variants != ARMV4T_ABOVE)
|
|
||||||
&& (opcode_data->variants != ARMV5_ABOVE))
|
|
||||||
return false;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case ARMv5TEJ:
|
|
||||||
if ((opcode_data->variants != ARMvAll)
|
|
||||||
&& (opcode_data->variants != ARMV4T_ABOVE)
|
|
||||||
&& (opcode_data->variants != ARMV5_ABOVE)
|
|
||||||
&& (opcode_data->variants != ARMV5J_ABOVE))
|
|
||||||
return false;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case ARMv6:
|
|
||||||
case ARMv6K:
|
|
||||||
if ((opcode_data->variants != ARMvAll)
|
|
||||||
&& (opcode_data->variants != ARMV4T_ABOVE)
|
|
||||||
&& (opcode_data->variants != ARMV5_ABOVE)
|
|
||||||
&& (opcode_data->variants != ARMV5J_ABOVE)
|
|
||||||
&& (opcode_data->variants != ARMV6_ABOVE))
|
|
||||||
return false;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case ARMv6T2:
|
|
||||||
case ARMv7:
|
|
||||||
case ARMv8:
|
|
||||||
if ((opcode_data->variants != ARMvAll)
|
|
||||||
&& (opcode_data->variants != ARMV4T_ABOVE)
|
|
||||||
&& (opcode_data->variants != ARMV5_ABOVE)
|
|
||||||
&& (opcode_data->variants != ARMV5J_ABOVE)
|
|
||||||
&& (opcode_data->variants != ARMV6_ABOVE)
|
|
||||||
&& (opcode_data->variants != ARMV6T2_ABOVE))
|
|
||||||
return false;
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
// if (opcode_data->variants != ARMvAll)
|
|
||||||
// return false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Just for now, for testing purposes.
|
|
||||||
if (m_baton == NULL)
|
|
||||||
fprintf (stdout, "\nEvaluateInstruction, opcode (0x%x), found = '%s'\n", m_opcode.GetOpcode32(),
|
|
||||||
opcode_data->name);
|
|
||||||
|
|
||||||
bool success;
|
bool success = false;
|
||||||
if (m_baton)
|
if (m_opcode_cpsr == 0 || m_ignore_conditions == false)
|
||||||
{
|
{
|
||||||
uint32_t cpsr_value = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_cpsr, 0, &success);
|
m_opcode_cpsr = ReadRegisterUnsigned (eRegisterKindDWARF,
|
||||||
if (success)
|
dwarf_cpsr,
|
||||||
m_opcode_cpsr = cpsr_value;
|
0,
|
||||||
}
|
&success);
|
||||||
|
|
||||||
uint32_t orig_pc_value = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc, 0, &success);
|
|
||||||
if (!success)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
success = (this->*opcode_data->callback) (m_opcode.GetOpcode32(), opcode_data->encoding); // Call the Emulate... function.
|
|
||||||
if (!success)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
uint32_t after_pc_value = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc, 0, &success);
|
|
||||||
if (!success)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (m_advance_pc && (after_pc_value == orig_pc_value))
|
|
||||||
{
|
|
||||||
if (opcode_data->size == eSize32)
|
|
||||||
after_pc_value += 4;
|
|
||||||
else if (opcode_data->size == eSize16)
|
|
||||||
after_pc_value += 2;
|
|
||||||
|
|
||||||
EmulateInstruction::Context context;
|
|
||||||
context.type = eContextAdvancePC;
|
|
||||||
context.SetNoArgs();
|
|
||||||
if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc, after_pc_value))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Only return false if we are unable to read the CPSR if we care about conditions
|
||||||
|
if (success == false && m_ignore_conditions == false)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
uint32_t orig_pc_value = 0;
|
||||||
|
if (auto_advance_pc)
|
||||||
|
{
|
||||||
|
orig_pc_value = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc, 0, &success);
|
||||||
|
if (!success)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Call the Emulate... function.
|
||||||
|
success = (this->*opcode_data->callback) (m_opcode.GetOpcode32(), opcode_data->encoding);
|
||||||
|
if (!success)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (auto_advance_pc)
|
||||||
|
{
|
||||||
|
uint32_t after_pc_value = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc, 0, &success);
|
||||||
|
if (!success)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (auto_advance_pc && (after_pc_value == orig_pc_value))
|
||||||
|
{
|
||||||
|
if (opcode_data->size == eSize32)
|
||||||
|
after_pc_value += 4;
|
||||||
|
else if (opcode_data->size == eSize16)
|
||||||
|
after_pc_value += 2;
|
||||||
|
|
||||||
|
EmulateInstruction::Context context;
|
||||||
|
context.type = eContextAdvancePC;
|
||||||
|
context.SetNoArgs();
|
||||||
|
if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc, after_pc_value))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -13331,10 +13297,6 @@ EmulateInstructionARM::TestEmulation (Stream *out_stream, ArchSpec &arch, Option
|
||||||
}
|
}
|
||||||
test_opcode = value_sp->GetUInt64Value ();
|
test_opcode = value_sp->GetUInt64Value ();
|
||||||
|
|
||||||
// If the instruction emulation does not directly update the PC, advance the PC to the next instruction after
|
|
||||||
// performing the emulation.
|
|
||||||
SetAdvancePC (true);
|
|
||||||
|
|
||||||
if (arch.GetTriple().getArch() == llvm::Triple::arm)
|
if (arch.GetTriple().getArch() == llvm::Triple::arm)
|
||||||
{
|
{
|
||||||
m_opcode_mode = eModeARM;
|
m_opcode_mode = eModeARM;
|
||||||
|
@ -13392,7 +13354,7 @@ EmulateInstructionARM::TestEmulation (Stream *out_stream, ArchSpec &arch, Option
|
||||||
&EmulationStateARM::ReadPseudoRegister,
|
&EmulationStateARM::ReadPseudoRegister,
|
||||||
&EmulationStateARM::WritePseudoRegister);
|
&EmulationStateARM::WritePseudoRegister);
|
||||||
|
|
||||||
bool success = EvaluateInstruction ();
|
bool success = EvaluateInstruction (eEmulateInstructionOptionAutoAdvancePC);
|
||||||
if (!success)
|
if (!success)
|
||||||
{
|
{
|
||||||
out_stream->Printf ("TestEmulation: EvaluateInstruction() failed.\n");
|
out_stream->Printf ("TestEmulation: EvaluateInstruction() failed.\n");
|
||||||
|
@ -13406,3 +13368,26 @@ EmulateInstructionARM::TestEmulation (Stream *out_stream, ArchSpec &arch, Option
|
||||||
return success;
|
return success;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const char *
|
||||||
|
EmulateInstructionARM::GetRegisterName (uint32_t reg_kind, uint32_t reg_num)
|
||||||
|
{
|
||||||
|
if (reg_kind == eRegisterKindGeneric)
|
||||||
|
{
|
||||||
|
switch (reg_num)
|
||||||
|
{
|
||||||
|
case LLDB_REGNUM_GENERIC_PC: return "pc";
|
||||||
|
case LLDB_REGNUM_GENERIC_SP: return "sp";
|
||||||
|
case LLDB_REGNUM_GENERIC_FP: return "fp";
|
||||||
|
case LLDB_REGNUM_GENERIC_RA: return "lr";
|
||||||
|
case LLDB_REGNUM_GENERIC_FLAGS: return "cpsr";
|
||||||
|
default: return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (reg_kind == eRegisterKindDWARF)
|
||||||
|
{
|
||||||
|
return GetARMDWARFRegisterName (reg_num);
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -75,8 +75,28 @@ public:
|
||||||
GetPluginDescriptionStatic ();
|
GetPluginDescriptionStatic ();
|
||||||
|
|
||||||
static lldb_private::EmulateInstruction *
|
static lldb_private::EmulateInstruction *
|
||||||
CreateInstance (const lldb_private::ArchSpec &arch);
|
CreateInstance (const lldb_private::ArchSpec &arch,
|
||||||
|
InstructionType inst_type);
|
||||||
|
|
||||||
|
static bool
|
||||||
|
SupportsEmulatingIntructionsOfTypeStatic (InstructionType inst_type)
|
||||||
|
{
|
||||||
|
switch (inst_type)
|
||||||
|
{
|
||||||
|
case eInstructionTypeAny:
|
||||||
|
case eInstructionTypePrologueEpilogue:
|
||||||
|
case eInstructionTypePCModifying:
|
||||||
|
return true;
|
||||||
|
|
||||||
|
case eInstructionTypeAll:
|
||||||
|
return false;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
virtual const char *
|
virtual const char *
|
||||||
GetPluginName()
|
GetPluginName()
|
||||||
{
|
{
|
||||||
|
@ -106,38 +126,43 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
EmulateInstructionARM (const ArchSpec &arch) :
|
EmulateInstructionARM (const ArchSpec &arch) :
|
||||||
EmulateInstruction (lldb::eByteOrderLittle,
|
EmulateInstruction (arch),
|
||||||
4,
|
|
||||||
arch),
|
|
||||||
m_arm_isa (0),
|
m_arm_isa (0),
|
||||||
m_opcode_mode (eModeInvalid),
|
m_opcode_mode (eModeInvalid),
|
||||||
m_opcode_cpsr (0),
|
m_opcode_cpsr (0),
|
||||||
m_it_session ()
|
m_it_session (),
|
||||||
|
m_ignore_conditions (false)
|
||||||
{
|
{
|
||||||
|
SetArchitecture (arch);
|
||||||
}
|
}
|
||||||
|
|
||||||
EmulateInstructionARM (const ArchSpec &arch,
|
// EmulateInstructionARM (const ArchSpec &arch,
|
||||||
void *baton,
|
// bool ignore_conditions,
|
||||||
ReadMemory read_mem_callback,
|
// void *baton,
|
||||||
WriteMemory write_mem_callback,
|
// ReadMemory read_mem_callback,
|
||||||
ReadRegister read_reg_callback,
|
// WriteMemory write_mem_callback,
|
||||||
WriteRegister write_reg_callback) :
|
// ReadRegister read_reg_callback,
|
||||||
EmulateInstruction (lldb::eByteOrderLittle, // Byte order for ARM
|
// WriteRegister write_reg_callback) :
|
||||||
4, // Address size in byte
|
// EmulateInstruction (arch,
|
||||||
arch,
|
// ignore_conditions,
|
||||||
baton,
|
// baton,
|
||||||
read_mem_callback,
|
// read_mem_callback,
|
||||||
write_mem_callback,
|
// write_mem_callback,
|
||||||
read_reg_callback,
|
// read_reg_callback,
|
||||||
write_reg_callback),
|
// write_reg_callback),
|
||||||
m_arm_isa (0),
|
// m_arm_isa (0),
|
||||||
m_opcode_mode (eModeInvalid),
|
// m_opcode_mode (eModeInvalid),
|
||||||
m_opcode_cpsr (0),
|
// m_opcode_cpsr (0),
|
||||||
m_it_session ()
|
// m_it_session ()
|
||||||
|
// {
|
||||||
|
// }
|
||||||
|
|
||||||
|
virtual bool
|
||||||
|
SupportsEmulatingIntructionsOfType (InstructionType inst_type)
|
||||||
{
|
{
|
||||||
|
return SupportsEmulatingIntructionsOfTypeStatic (inst_type);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
virtual bool
|
virtual bool
|
||||||
SetArchitecture (const ArchSpec &arch);
|
SetArchitecture (const ArchSpec &arch);
|
||||||
|
|
||||||
|
@ -145,14 +170,17 @@ public:
|
||||||
ReadInstruction ();
|
ReadInstruction ();
|
||||||
|
|
||||||
virtual bool
|
virtual bool
|
||||||
SetInstruction (const Opcode &insn_opcode, const Address &inst_addr);
|
SetInstruction (const Opcode &insn_opcode, const Address &inst_addr, Target *target);
|
||||||
|
|
||||||
virtual bool
|
virtual bool
|
||||||
EvaluateInstruction ();
|
EvaluateInstruction (uint32_t evaluate_options);
|
||||||
|
|
||||||
virtual bool
|
virtual bool
|
||||||
TestEmulation (Stream *out_stream, ArchSpec &arch, OptionValueDictionary *test_data);
|
TestEmulation (Stream *out_stream, ArchSpec &arch, OptionValueDictionary *test_data);
|
||||||
|
|
||||||
|
virtual const char *
|
||||||
|
GetRegisterName (uint32_t reg_kind, uint32_t reg_num);
|
||||||
|
|
||||||
uint32_t
|
uint32_t
|
||||||
ArchVersion();
|
ArchVersion();
|
||||||
|
|
||||||
|
@ -340,10 +368,10 @@ protected:
|
||||||
|
|
||||||
|
|
||||||
static ARMOpcode*
|
static ARMOpcode*
|
||||||
GetARMOpcodeForInstruction (const uint32_t opcode);
|
GetARMOpcodeForInstruction (const uint32_t opcode, uint32_t isa_mask);
|
||||||
|
|
||||||
static ARMOpcode*
|
static ARMOpcode*
|
||||||
GetThumbOpcodeForInstruction (const uint32_t opcode);
|
GetThumbOpcodeForInstruction (const uint32_t opcode, uint32_t isa_mask);
|
||||||
|
|
||||||
// A8.6.123 PUSH
|
// A8.6.123 PUSH
|
||||||
bool
|
bool
|
||||||
|
@ -948,6 +976,7 @@ protected:
|
||||||
uint32_t m_opcode_cpsr;
|
uint32_t m_opcode_cpsr;
|
||||||
uint32_t m_new_inst_cpsr; // This can get updated by the opcode.
|
uint32_t m_new_inst_cpsr; // This can get updated by the opcode.
|
||||||
ITSession m_it_session;
|
ITSession m_it_session;
|
||||||
|
bool m_ignore_conditions;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace lldb_private
|
} // namespace lldb_private
|
||||||
|
|
|
@ -187,11 +187,12 @@ EmulationStateARM::ReadFromPseudoAddress (lldb::addr_t p_address, uint32_t size,
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t
|
size_t
|
||||||
EmulationStateARM::ReadPseudoMemory (void *baton,
|
EmulationStateARM::ReadPseudoMemory (EmulateInstruction *instruction,
|
||||||
const EmulateInstruction::Context &context,
|
void *baton,
|
||||||
lldb::addr_t addr,
|
const EmulateInstruction::Context &context,
|
||||||
void *dst,
|
lldb::addr_t addr,
|
||||||
size_t length)
|
void *dst,
|
||||||
|
size_t length)
|
||||||
{
|
{
|
||||||
if (!baton)
|
if (!baton)
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -230,11 +231,12 @@ EmulationStateARM::ReadPseudoMemory (void *baton,
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t
|
size_t
|
||||||
EmulationStateARM::WritePseudoMemory (void *baton,
|
EmulationStateARM::WritePseudoMemory (EmulateInstruction *instruction,
|
||||||
const EmulateInstruction::Context &context,
|
void *baton,
|
||||||
lldb::addr_t addr,
|
const EmulateInstruction::Context &context,
|
||||||
const void *dst,
|
lldb::addr_t addr,
|
||||||
size_t length)
|
const void *dst,
|
||||||
|
size_t length)
|
||||||
{
|
{
|
||||||
if (!baton)
|
if (!baton)
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -250,10 +252,11 @@ EmulationStateARM::WritePseudoMemory (void *baton,
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
EmulationStateARM::ReadPseudoRegister (void *baton,
|
EmulationStateARM::ReadPseudoRegister (EmulateInstruction *instruction,
|
||||||
uint32_t reg_kind,
|
void *baton,
|
||||||
uint32_t reg_num,
|
uint32_t reg_kind,
|
||||||
uint64_t ®_value)
|
uint32_t reg_num,
|
||||||
|
uint64_t ®_value)
|
||||||
{
|
{
|
||||||
if (!baton)
|
if (!baton)
|
||||||
return false;
|
return false;
|
||||||
|
@ -284,11 +287,12 @@ EmulationStateARM::ReadPseudoRegister (void *baton,
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
EmulationStateARM::WritePseudoRegister (void *baton,
|
EmulationStateARM::WritePseudoRegister (EmulateInstruction *instruction,
|
||||||
const EmulateInstruction::Context &context,
|
void *baton,
|
||||||
uint32_t reg_kind,
|
const EmulateInstruction::Context &context,
|
||||||
uint32_t reg_num,
|
uint32_t reg_kind,
|
||||||
uint64_t reg_value)
|
uint32_t reg_num,
|
||||||
|
uint64_t reg_value)
|
||||||
{
|
{
|
||||||
if (!baton)
|
if (!baton)
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -16,8 +16,6 @@
|
||||||
#include "lldb/Core/Opcode.h"
|
#include "lldb/Core/Opcode.h"
|
||||||
#include "lldb/Interpreter/NamedOptionValue.h"
|
#include "lldb/Interpreter/NamedOptionValue.h"
|
||||||
|
|
||||||
namespace lldb_private {
|
|
||||||
|
|
||||||
class EmulationStateARM {
|
class EmulationStateARM {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
@ -45,37 +43,41 @@ public:
|
||||||
ClearPseudoMemory ();
|
ClearPseudoMemory ();
|
||||||
|
|
||||||
bool
|
bool
|
||||||
LoadPseudoRegistersFromFrame (StackFrame &frame);
|
LoadPseudoRegistersFromFrame (lldb_private::StackFrame &frame);
|
||||||
|
|
||||||
bool
|
bool
|
||||||
LoadStateFromDictionary (OptionValueDictionary *test_data);
|
LoadStateFromDictionary (lldb_private::OptionValueDictionary *test_data);
|
||||||
|
|
||||||
bool
|
bool
|
||||||
CompareState (EmulationStateARM &other_state);
|
CompareState (EmulationStateARM &other_state);
|
||||||
|
|
||||||
static size_t
|
static size_t
|
||||||
ReadPseudoMemory (void *baton,
|
ReadPseudoMemory (lldb_private::EmulateInstruction *instruction,
|
||||||
const EmulateInstruction::Context &context,
|
void *baton,
|
||||||
|
const lldb_private::EmulateInstruction::Context &context,
|
||||||
lldb::addr_t addr,
|
lldb::addr_t addr,
|
||||||
void *dst,
|
void *dst,
|
||||||
size_t length);
|
size_t length);
|
||||||
|
|
||||||
static size_t
|
static size_t
|
||||||
WritePseudoMemory (void *baton,
|
WritePseudoMemory (lldb_private::EmulateInstruction *instruction,
|
||||||
const EmulateInstruction::Context &context,
|
void *baton,
|
||||||
|
const lldb_private::EmulateInstruction::Context &context,
|
||||||
lldb::addr_t addr,
|
lldb::addr_t addr,
|
||||||
const void *dst,
|
const void *dst,
|
||||||
size_t length);
|
size_t length);
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
ReadPseudoRegister (void *baton,
|
ReadPseudoRegister (lldb_private::EmulateInstruction *instruction,
|
||||||
|
void *baton,
|
||||||
uint32_t reg_kind,
|
uint32_t reg_kind,
|
||||||
uint32_t reg_num,
|
uint32_t reg_num,
|
||||||
uint64_t ®_value);
|
uint64_t ®_value);
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
WritePseudoRegister (void *baton,
|
WritePseudoRegister (lldb_private::EmulateInstruction *instruction,
|
||||||
const EmulateInstruction::Context &context,
|
void *baton,
|
||||||
|
const lldb_private::EmulateInstruction::Context &context,
|
||||||
uint32_t reg_kind,
|
uint32_t reg_kind,
|
||||||
uint32_t reg_num,
|
uint32_t reg_num,
|
||||||
uint64_t reg_value);
|
uint64_t reg_value);
|
||||||
|
@ -97,7 +99,5 @@ private:
|
||||||
|
|
||||||
DISALLOW_COPY_AND_ASSIGN (EmulationStateARM);
|
DISALLOW_COPY_AND_ASSIGN (EmulationStateARM);
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace lldb_private
|
|
||||||
|
|
||||||
#endif // lldb_EmulationStateARM_h_
|
#endif // lldb_EmulationStateARM_h_
|
||||||
|
|
|
@ -79,6 +79,15 @@ static inline const char *ARMCondCodeToString(uint32_t CC)
|
||||||
#define CPSR_Z_POS 30
|
#define CPSR_Z_POS 30
|
||||||
#define CPSR_N_POS 31
|
#define CPSR_N_POS 31
|
||||||
|
|
||||||
|
// CPSR mode definitions
|
||||||
|
#define CPSR_MODE_USR 0x10u
|
||||||
|
#define CPSR_MODE_FIQ 0x11u
|
||||||
|
#define CPSR_MODE_IRQ 0x12u
|
||||||
|
#define CPSR_MODE_SVC 0x13u
|
||||||
|
#define CPSR_MODE_ABT 0x17u
|
||||||
|
#define CPSR_MODE_UND 0x1bu
|
||||||
|
#define CPSR_MODE_SYS 0x1fu
|
||||||
|
|
||||||
// Masks for CPSR
|
// Masks for CPSR
|
||||||
#define MASK_CPSR_MODE_MASK (0x0000001fu)
|
#define MASK_CPSR_MODE_MASK (0x0000001fu)
|
||||||
#define MASK_CPSR_T (1u << CPSR_T_POS)
|
#define MASK_CPSR_T (1u << CPSR_T_POS)
|
||||||
|
|
|
@ -143,16 +143,21 @@ ThreadGDBRemote::GetUnwinder ()
|
||||||
{
|
{
|
||||||
const ArchSpec target_arch (GetProcess().GetTarget().GetArchitecture ());
|
const ArchSpec target_arch (GetProcess().GetTarget().GetArchitecture ());
|
||||||
const llvm::Triple::ArchType machine = target_arch.GetMachine();
|
const llvm::Triple::ArchType machine = target_arch.GetMachine();
|
||||||
if (machine == llvm::Triple::x86_64 || machine == llvm::Triple::x86)
|
switch (machine)
|
||||||
{
|
{
|
||||||
m_unwinder_ap.reset (new UnwindLLDB (*this));
|
case llvm::Triple::x86_64:
|
||||||
}
|
case llvm::Triple::x86:
|
||||||
|
case llvm::Triple::arm:
|
||||||
|
case llvm::Triple::thumb:
|
||||||
|
m_unwinder_ap.reset (new UnwindLLDB (*this));
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
#if defined(__APPLE__)
|
#if defined(__APPLE__)
|
||||||
else
|
m_unwinder_ap.reset (new UnwindMacOSXFrameBackchain (*this));
|
||||||
{
|
|
||||||
m_unwinder_ap.reset (new UnwindMacOSXFrameBackchain (*this));
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return m_unwinder_ap.get();
|
return m_unwinder_ap.get();
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,16 +12,16 @@
|
||||||
#include "llvm-c/EnhancedDisassembly.h"
|
#include "llvm-c/EnhancedDisassembly.h"
|
||||||
|
|
||||||
#include "lldb/Core/Address.h"
|
#include "lldb/Core/Address.h"
|
||||||
#include "lldb/Core/Error.h"
|
|
||||||
#include "lldb/Core/ArchSpec.h"
|
#include "lldb/Core/ArchSpec.h"
|
||||||
|
#include "lldb/Core/DataBufferHeap.h"
|
||||||
|
#include "lldb/Core/Disassembler.h"
|
||||||
|
#include "lldb/Core/Error.h"
|
||||||
#include "lldb/Core/PluginManager.h"
|
#include "lldb/Core/PluginManager.h"
|
||||||
#include "lldb/Symbol/UnwindPlan.h"
|
#include "lldb/Core/StreamFile.h"
|
||||||
#include "lldb/Target/ExecutionContext.h"
|
#include "lldb/Target/ExecutionContext.h"
|
||||||
#include "lldb/Target/Process.h"
|
#include "lldb/Target/Process.h"
|
||||||
#include "lldb/Target/RegisterContext.h"
|
|
||||||
#include "lldb/Target/Thread.h"
|
#include "lldb/Target/Thread.h"
|
||||||
#include "lldb/Target/Target.h"
|
#include "lldb/Target/Target.h"
|
||||||
#include "lldb/Target/UnwindAssembly.h"
|
|
||||||
|
|
||||||
using namespace lldb;
|
using namespace lldb;
|
||||||
using namespace lldb_private;
|
using namespace lldb_private;
|
||||||
|
@ -33,19 +33,108 @@ using namespace lldb_private;
|
||||||
//-----------------------------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
bool
|
bool
|
||||||
UnwindAssemblyInstEmulation::GetNonCallSiteUnwindPlanFromAssembly (AddressRange& func, Thread& thread, UnwindPlan& unwind_plan)
|
UnwindAssemblyInstEmulation::GetNonCallSiteUnwindPlanFromAssembly (AddressRange& range,
|
||||||
|
Thread& thread,
|
||||||
|
UnwindPlan& unwind_plan)
|
||||||
|
{
|
||||||
|
#if 0
|
||||||
|
UnwindPlan::Row row;
|
||||||
|
UnwindPlan::Row::RegisterLocation regloc;
|
||||||
|
|
||||||
|
m_unwind_plan_sp->SetRegisterKind (eRegisterKindGeneric);
|
||||||
|
row.SetCFARegister (LLDB_REGNUM_GENERIC_FP);
|
||||||
|
row.SetCFAOffset (2 * 8);
|
||||||
|
row.SetOffset (0);
|
||||||
|
|
||||||
|
regloc.SetAtCFAPlusOffset (2 * -8);
|
||||||
|
row.SetRegisterInfo (LLDB_REGNUM_GENERIC_FP, regloc);
|
||||||
|
regloc.SetAtCFAPlusOffset (1 * -8);
|
||||||
|
row.SetRegisterInfo (LLDB_REGNUM_GENERIC_PC, regloc);
|
||||||
|
regloc.SetIsCFAPlusOffset (0);
|
||||||
|
row.SetRegisterInfo (LLDB_REGNUM_GENERIC_SP, regloc);
|
||||||
|
|
||||||
|
m_unwind_plan_sp->AppendRow (row);
|
||||||
|
m_unwind_plan_sp->SetSourceName ("x86_64 architectural default");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (range.GetByteSize() > 0 &&
|
||||||
|
range.GetBaseAddress().IsValid() &&
|
||||||
|
m_inst_emulator_ap.get())
|
||||||
|
{
|
||||||
|
#if 0
|
||||||
|
Target &target = thread.GetProcess().GetTarget();
|
||||||
|
const ArchSpec &target_arch = target.GetArchitecture();
|
||||||
|
bool prefer_file_cache = true;
|
||||||
|
Error error;
|
||||||
|
DataBufferHeap data_buffer (range.GetByteSize(), 0);
|
||||||
|
if (target.ReadMemory (range.GetBaseAddress(),
|
||||||
|
prefer_file_cache,
|
||||||
|
data_buffer.GetBytes(),
|
||||||
|
data_buffer.GetByteSize(),
|
||||||
|
error) == data_buffer.GetByteSize())
|
||||||
|
{
|
||||||
|
DataExtractor data (data_buffer.GetBytes(),
|
||||||
|
data_buffer.GetByteSize(),
|
||||||
|
target_arch.GetByteOrder(),
|
||||||
|
target_arch.GetAddressByteSize());
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
StreamFile strm (stdout, false);
|
||||||
|
|
||||||
|
ExecutionContext exe_ctx;
|
||||||
|
thread.CalculateExecutionContext(exe_ctx);
|
||||||
|
DisassemblerSP disasm_sp (Disassembler::DisassembleRange (m_arch,
|
||||||
|
NULL,
|
||||||
|
exe_ctx,
|
||||||
|
range));
|
||||||
|
if (disasm_sp)
|
||||||
|
{
|
||||||
|
|
||||||
|
m_range_ptr = ⦥
|
||||||
|
m_thread_ptr = &thread;
|
||||||
|
m_unwind_plan_ptr = &unwind_plan;
|
||||||
|
|
||||||
|
const uint32_t addr_byte_size = m_arch.GetAddressByteSize();
|
||||||
|
const bool show_address = true;
|
||||||
|
const bool show_bytes = true;
|
||||||
|
const bool raw = false;
|
||||||
|
// Initialize the stack pointer with a known value. In the 32 bit case
|
||||||
|
// it will be 0x80000000, and in the 64 bit case 0x8000000000000000.
|
||||||
|
// We use the address byte size to be safe for any future addresss sizes
|
||||||
|
SetRegisterValue (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, (1ull << ((addr_byte_size * 8) - 1)));
|
||||||
|
|
||||||
|
const InstructionList &inst_list = disasm_sp->GetInstructionList ();
|
||||||
|
const size_t num_instructions = inst_list.GetSize();
|
||||||
|
for (size_t idx=0; idx<num_instructions; ++idx)
|
||||||
|
{
|
||||||
|
Instruction *inst = inst_list.GetInstructionAtIndex (idx).get();
|
||||||
|
if (inst)
|
||||||
|
{
|
||||||
|
inst->Dump(&strm, inst_list.GetMaxOpcocdeByteSize (), show_address, show_bytes, &exe_ctx, raw);
|
||||||
|
strm.EOL();
|
||||||
|
|
||||||
|
m_inst_emulator_ap->SetInstruction (inst->GetOpcode(), inst->GetAddress(), exe_ctx.target);
|
||||||
|
m_inst_emulator_ap->EvaluateInstruction (eEmulateInstructionOptionIgnoreConditions);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
UnwindAssemblyInstEmulation::GetFastUnwindPlan (AddressRange& func,
|
||||||
|
Thread& thread,
|
||||||
|
UnwindPlan &unwind_plan)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
UnwindAssemblyInstEmulation::GetFastUnwindPlan (AddressRange& func, Thread& thread, UnwindPlan &unwind_plan)
|
UnwindAssemblyInstEmulation::FirstNonPrologueInsn (AddressRange& func,
|
||||||
{
|
Target& target,
|
||||||
return false;
|
Thread* thread,
|
||||||
}
|
Address& first_non_prologue_insn)
|
||||||
|
|
||||||
bool
|
|
||||||
UnwindAssemblyInstEmulation::FirstNonPrologueInsn (AddressRange& func, Target& target, Thread* thread, Address& first_non_prologue_insn)
|
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -53,6 +142,10 @@ UnwindAssemblyInstEmulation::FirstNonPrologueInsn (AddressRange& func, Target& t
|
||||||
UnwindAssembly *
|
UnwindAssembly *
|
||||||
UnwindAssemblyInstEmulation::CreateInstance (const ArchSpec &arch)
|
UnwindAssemblyInstEmulation::CreateInstance (const ArchSpec &arch)
|
||||||
{
|
{
|
||||||
|
std::auto_ptr<lldb_private::EmulateInstruction> inst_emulator_ap (EmulateInstruction::FindPlugin (arch, eInstructionTypePrologueEpilogue, NULL));
|
||||||
|
// Make sure that all prologue instructions are handled
|
||||||
|
if (inst_emulator_ap.get())
|
||||||
|
return new UnwindAssemblyInstEmulation (arch, inst_emulator_ap.release());
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -106,3 +199,120 @@ UnwindAssemblyInstEmulation::GetPluginDescriptionStatic()
|
||||||
{
|
{
|
||||||
return "Instruction emulation based unwind information.";
|
return "Instruction emulation based unwind information.";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
size_t
|
||||||
|
UnwindAssemblyInstEmulation::ReadMemory (EmulateInstruction *instruction,
|
||||||
|
void *baton,
|
||||||
|
const EmulateInstruction::Context &context,
|
||||||
|
lldb::addr_t addr,
|
||||||
|
void *dst,
|
||||||
|
size_t dst_len)
|
||||||
|
{
|
||||||
|
//UnwindAssemblyInstEmulation *inst_emulator = (UnwindAssemblyInstEmulation *)baton;
|
||||||
|
printf ("UnwindAssemblyInstEmulation::ReadMemory (context.type = %i, context.info_type = %i, addr = 0x%16.16llx, dst = %p, dst_len = %zu)\n",
|
||||||
|
context.type,
|
||||||
|
context.info_type,
|
||||||
|
addr,
|
||||||
|
dst,
|
||||||
|
dst_len);
|
||||||
|
return dst_len;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t
|
||||||
|
UnwindAssemblyInstEmulation::WriteMemory (EmulateInstruction *instruction,
|
||||||
|
void *baton,
|
||||||
|
const EmulateInstruction::Context &context,
|
||||||
|
lldb::addr_t addr,
|
||||||
|
const void *dst,
|
||||||
|
size_t dst_len)
|
||||||
|
{
|
||||||
|
// UnwindAssemblyInstEmulation *inst_emulator = (UnwindAssemblyInstEmulation *)baton;
|
||||||
|
|
||||||
|
DataExtractor data (dst,
|
||||||
|
dst_len,
|
||||||
|
instruction->GetArchitecture ().GetByteOrder(),
|
||||||
|
instruction->GetArchitecture ().GetAddressByteSize());
|
||||||
|
StreamFile strm(stdout, false);
|
||||||
|
|
||||||
|
strm.Printf ("UnwindAssemblyInstEmulation::WriteMemory (context.type = %i, context.info_type = %i, ",
|
||||||
|
context.type,
|
||||||
|
context.info_type);
|
||||||
|
data.Dump(&strm, 0, eFormatBytes, 1, dst_len, UINT32_MAX, addr, 0, 0);
|
||||||
|
strm.EOL();
|
||||||
|
return dst_len;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
UnwindAssemblyInstEmulation::ReadRegister (EmulateInstruction *instruction,
|
||||||
|
void *baton,
|
||||||
|
uint32_t reg_kind,
|
||||||
|
uint32_t reg_num,
|
||||||
|
uint64_t ®_value)
|
||||||
|
{
|
||||||
|
UnwindAssemblyInstEmulation *inst_emulator = (UnwindAssemblyInstEmulation *)baton;
|
||||||
|
const char *reg_name = instruction->GetRegisterName (reg_kind, reg_num);
|
||||||
|
|
||||||
|
reg_value = inst_emulator->GetRegisterValue (reg_kind, reg_num);
|
||||||
|
|
||||||
|
printf ("UnwindAssemblyInstEmulation::ReadRegister (name = \"%s\") => value = 0x%16.16llx\n", reg_name, reg_value);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
UnwindAssemblyInstEmulation::WriteRegister (EmulateInstruction *instruction,
|
||||||
|
void *baton,
|
||||||
|
const EmulateInstruction::Context &context,
|
||||||
|
uint32_t reg_kind,
|
||||||
|
uint32_t reg_num,
|
||||||
|
uint64_t reg_value)
|
||||||
|
{
|
||||||
|
UnwindAssemblyInstEmulation *inst_emulator = (UnwindAssemblyInstEmulation *)baton;
|
||||||
|
const char *reg_name = instruction->GetRegisterName (reg_kind, reg_num);
|
||||||
|
|
||||||
|
printf ("UnwindAssemblyInstEmulation::WriteRegister (name = \"%s\", value = 0x%16.16llx, context.type = %i, context.info_type = %i)\n",
|
||||||
|
reg_name,
|
||||||
|
reg_value,
|
||||||
|
context.type,
|
||||||
|
context.info_type);
|
||||||
|
|
||||||
|
inst_emulator->SetRegisterValue (reg_kind, reg_num, reg_value);
|
||||||
|
|
||||||
|
switch (context.type)
|
||||||
|
{
|
||||||
|
case EmulateInstruction::eContextInvalid:
|
||||||
|
case EmulateInstruction::eContextReadOpcode:
|
||||||
|
case EmulateInstruction::eContextImmediate:
|
||||||
|
case EmulateInstruction::eContextAdjustBaseRegister:
|
||||||
|
case EmulateInstruction::eContextRegisterPlusOffset:
|
||||||
|
case EmulateInstruction::eContextAdjustPC:
|
||||||
|
case EmulateInstruction::eContextRegisterStore:
|
||||||
|
case EmulateInstruction::eContextRegisterLoad:
|
||||||
|
case EmulateInstruction::eContextRelativeBranchImmediate:
|
||||||
|
case EmulateInstruction::eContextAbsoluteBranchRegister:
|
||||||
|
case EmulateInstruction::eContextSupervisorCall:
|
||||||
|
case EmulateInstruction::eContextTableBranchReadMemory:
|
||||||
|
case EmulateInstruction::eContextWriteRegisterRandomBits:
|
||||||
|
case EmulateInstruction::eContextWriteMemoryRandomBits:
|
||||||
|
case EmulateInstruction::eContextMultiplication:
|
||||||
|
case EmulateInstruction::eContextAddition:
|
||||||
|
case EmulateInstruction::eContextSubtraction:
|
||||||
|
case EmulateInstruction::eContextAdvancePC:
|
||||||
|
case EmulateInstruction::eContextReturnFromException:
|
||||||
|
break;
|
||||||
|
|
||||||
|
case EmulateInstruction::eContextPushRegisterOnStack:
|
||||||
|
break;
|
||||||
|
|
||||||
|
case EmulateInstruction::eContextPopRegisterOffStack:
|
||||||
|
break;
|
||||||
|
|
||||||
|
case EmulateInstruction::eContextAdjustStackPointer:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -11,8 +11,8 @@
|
||||||
#define liblldb_UnwindAssemblyInstEmulation_h_
|
#define liblldb_UnwindAssemblyInstEmulation_h_
|
||||||
|
|
||||||
#include "lldb/lldb-private.h"
|
#include "lldb/lldb-private.h"
|
||||||
|
#include "lldb/Core/EmulateInstruction.h"
|
||||||
#include "lldb/Target/UnwindAssembly.h"
|
#include "lldb/Target/UnwindAssembly.h"
|
||||||
#include "lldb/Target/Thread.h"
|
|
||||||
|
|
||||||
class UnwindAssemblyInstEmulation : public lldb_private::UnwindAssembly
|
class UnwindAssemblyInstEmulation : public lldb_private::UnwindAssembly
|
||||||
{
|
{
|
||||||
|
@ -43,7 +43,6 @@ public:
|
||||||
static lldb_private::UnwindAssembly *
|
static lldb_private::UnwindAssembly *
|
||||||
CreateInstance (const lldb_private::ArchSpec &arch);
|
CreateInstance (const lldb_private::ArchSpec &arch);
|
||||||
|
|
||||||
|
|
||||||
//------------------------------------------------------------------
|
//------------------------------------------------------------------
|
||||||
// PluginInterface protocol
|
// PluginInterface protocol
|
||||||
//------------------------------------------------------------------
|
//------------------------------------------------------------------
|
||||||
|
@ -69,14 +68,83 @@ public:
|
||||||
GetPluginVersion();
|
GetPluginVersion();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
static size_t
|
||||||
|
ReadMemory (lldb_private::EmulateInstruction *instruction,
|
||||||
|
void *baton,
|
||||||
|
const lldb_private::EmulateInstruction::Context &context,
|
||||||
|
lldb::addr_t addr,
|
||||||
|
void *dst,
|
||||||
|
size_t length);
|
||||||
|
|
||||||
|
static size_t
|
||||||
|
WriteMemory (lldb_private::EmulateInstruction *instruction,
|
||||||
|
void *baton,
|
||||||
|
const lldb_private::EmulateInstruction::Context &context,
|
||||||
|
lldb::addr_t addr,
|
||||||
|
const void *dst,
|
||||||
|
size_t length);
|
||||||
|
|
||||||
|
static bool
|
||||||
|
ReadRegister (lldb_private::EmulateInstruction *instruction,
|
||||||
|
void *baton,
|
||||||
|
uint32_t reg_kind,
|
||||||
|
uint32_t reg_num,
|
||||||
|
uint64_t ®_value);
|
||||||
|
|
||||||
|
static bool
|
||||||
|
WriteRegister (lldb_private::EmulateInstruction *instruction,
|
||||||
|
void *baton,
|
||||||
|
const lldb_private::EmulateInstruction::Context &context,
|
||||||
|
uint32_t reg_kind,
|
||||||
|
uint32_t reg_num,
|
||||||
|
uint64_t reg_value);
|
||||||
|
|
||||||
|
|
||||||
// Call CreateInstance to get an instance of this class
|
// Call CreateInstance to get an instance of this class
|
||||||
UnwindAssemblyInstEmulation(int cpu) :
|
UnwindAssemblyInstEmulation (const lldb_private::ArchSpec &arch,
|
||||||
lldb_private::UnwindAssembly(), m_cpu(cpu)
|
lldb_private::EmulateInstruction *inst_emulator) :
|
||||||
|
UnwindAssembly (arch),
|
||||||
|
m_inst_emulator_ap (inst_emulator),
|
||||||
|
m_range_ptr (NULL),
|
||||||
|
m_thread_ptr (NULL),
|
||||||
|
m_unwind_plan_ptr (NULL)
|
||||||
{
|
{
|
||||||
|
if (m_inst_emulator_ap.get())
|
||||||
|
{
|
||||||
|
m_inst_emulator_ap->SetBaton (this);
|
||||||
|
m_inst_emulator_ap->SetCallbacks (ReadMemory, WriteMemory, ReadRegister, WriteRegister);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int m_cpu;
|
static uint64_t
|
||||||
|
MakeRegisterKindValuePair (uint32_t reg_kind, uint32_t reg_num)
|
||||||
|
{
|
||||||
|
return (uint64_t)reg_kind << 32 | reg_num;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
SetRegisterValue (uint32_t reg_kind, uint32_t reg_num, uint64_t reg_value)
|
||||||
|
{
|
||||||
|
m_register_values[MakeRegisterKindValuePair (reg_kind, reg_num)] = reg_value;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t
|
||||||
|
GetRegisterValue (uint32_t reg_kind, uint32_t reg_num)
|
||||||
|
{
|
||||||
|
const uint64_t reg_id = MakeRegisterKindValuePair (reg_kind, reg_num);
|
||||||
|
RegisterValueMap::const_iterator pos = m_register_values.find(reg_id);
|
||||||
|
if (pos != m_register_values.end())
|
||||||
|
return pos->second;
|
||||||
|
return (uint64_t)reg_kind << 24 | (uint64_t)reg_num;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::auto_ptr<lldb_private::EmulateInstruction> m_inst_emulator_ap;
|
||||||
|
lldb_private::AddressRange* m_range_ptr;
|
||||||
|
lldb_private::Thread* m_thread_ptr;
|
||||||
|
lldb_private::UnwindPlan* m_unwind_plan_ptr;
|
||||||
|
typedef std::map<uint64_t, uint64_t> RegisterValueMap;
|
||||||
|
RegisterValueMap m_register_values;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // liblldb_UnwindAssemblyInstEmulation_h_
|
#endif // liblldb_UnwindAssemblyInstEmulation_h_
|
||||||
|
|
|
@ -818,6 +818,17 @@ AssemblyParse_x86::find_first_non_prologue_insn (Address &address)
|
||||||
// UnwindAssemblyParser_x86 method definitions
|
// UnwindAssemblyParser_x86 method definitions
|
||||||
//-----------------------------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
UnwindAssembly_x86::UnwindAssembly_x86 (const ArchSpec &arch, int cpu) :
|
||||||
|
lldb_private::UnwindAssembly(arch),
|
||||||
|
m_cpu(cpu)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
UnwindAssembly_x86::~UnwindAssembly_x86 ()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
UnwindAssembly_x86::GetNonCallSiteUnwindPlanFromAssembly (AddressRange& func, Thread& thread, UnwindPlan& unwind_plan)
|
UnwindAssembly_x86::GetNonCallSiteUnwindPlanFromAssembly (AddressRange& func, Thread& thread, UnwindPlan& unwind_plan)
|
||||||
{
|
{
|
||||||
|
@ -844,9 +855,9 @@ UnwindAssembly_x86::CreateInstance (const ArchSpec &arch)
|
||||||
{
|
{
|
||||||
const llvm::Triple::ArchType cpu = arch.GetMachine ();
|
const llvm::Triple::ArchType cpu = arch.GetMachine ();
|
||||||
if (cpu == llvm::Triple::x86)
|
if (cpu == llvm::Triple::x86)
|
||||||
return new UnwindAssembly_x86 (k_i386);
|
return new UnwindAssembly_x86 (arch, k_i386);
|
||||||
else if (cpu == llvm::Triple::x86_64)
|
else if (cpu == llvm::Triple::x86_64)
|
||||||
return new UnwindAssembly_x86 (k_x86_64);
|
return new UnwindAssembly_x86 (arch, k_x86_64);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -12,25 +12,29 @@
|
||||||
|
|
||||||
#include "lldb/lldb-private.h"
|
#include "lldb/lldb-private.h"
|
||||||
#include "lldb/Target/UnwindAssembly.h"
|
#include "lldb/Target/UnwindAssembly.h"
|
||||||
#include "lldb/Target/Thread.h"
|
|
||||||
|
|
||||||
namespace lldb_private {
|
|
||||||
|
|
||||||
class UnwindAssembly_x86 : public lldb_private::UnwindAssembly
|
class UnwindAssembly_x86 : public lldb_private::UnwindAssembly
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
~UnwindAssembly_x86 () { }
|
~UnwindAssembly_x86 ();
|
||||||
|
|
||||||
virtual bool
|
virtual bool
|
||||||
GetNonCallSiteUnwindPlanFromAssembly (AddressRange& func, lldb_private::Thread& thread, UnwindPlan& unwind_plan);
|
GetNonCallSiteUnwindPlanFromAssembly (lldb_private::AddressRange& func,
|
||||||
|
lldb_private::Thread& thread,
|
||||||
|
lldb_private::UnwindPlan& unwind_plan);
|
||||||
|
|
||||||
virtual bool
|
virtual bool
|
||||||
GetFastUnwindPlan (AddressRange& func, lldb_private::Thread& thread, UnwindPlan &unwind_plan);
|
GetFastUnwindPlan (lldb_private::AddressRange& func,
|
||||||
|
lldb_private::Thread& thread,
|
||||||
|
lldb_private::UnwindPlan &unwind_plan);
|
||||||
|
|
||||||
// thread may be NULL in which case we only use the Target (e.g. if this is called pre-process-launch).
|
// thread may be NULL in which case we only use the Target (e.g. if this is called pre-process-launch).
|
||||||
virtual bool
|
virtual bool
|
||||||
FirstNonPrologueInsn (AddressRange& func, lldb_private::Target& target, lldb_private::Thread* thread, Address& first_non_prologue_insn);
|
FirstNonPrologueInsn (lldb_private::AddressRange& func,
|
||||||
|
lldb_private::Target& target,
|
||||||
|
lldb_private::Thread* thread,
|
||||||
|
lldb_private::Address& first_non_prologue_insn);
|
||||||
|
|
||||||
static lldb_private::UnwindAssembly *
|
static lldb_private::UnwindAssembly *
|
||||||
CreateInstance (const lldb_private::ArchSpec &arch);
|
CreateInstance (const lldb_private::ArchSpec &arch);
|
||||||
|
@ -61,13 +65,10 @@ public:
|
||||||
GetPluginVersion();
|
GetPluginVersion();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
UnwindAssembly_x86(int cpu) :
|
UnwindAssembly_x86 (const lldb_private::ArchSpec &arch, int cpu);
|
||||||
lldb_private::UnwindAssembly(), m_cpu(cpu) { } // Call CreateInstance instead.
|
|
||||||
|
|
||||||
int m_cpu;
|
int m_cpu;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
} // namespace lldb_private
|
|
||||||
|
|
||||||
#endif // liblldb_UnwindAssembly_x86_h_
|
#endif // liblldb_UnwindAssembly_x86_h_
|
||||||
|
|
|
@ -6,12 +6,6 @@
|
||||||
// License. See LICENSE.TXT for details.
|
// License. See LICENSE.TXT for details.
|
||||||
//
|
//
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
//
|
|
||||||
//
|
|
||||||
|
|
||||||
//
|
|
||||||
//===----------------------------------------------------------------------===//
|
|
||||||
|
|
||||||
|
|
||||||
#include "lldb/Target/ExecutionContext.h"
|
#include "lldb/Target/ExecutionContext.h"
|
||||||
#include "lldb/Target/ExecutionContextScope.h"
|
#include "lldb/Target/ExecutionContextScope.h"
|
||||||
|
|
|
@ -31,7 +31,8 @@ UnwindAssembly::FindPlugin (const ArchSpec &arch)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
UnwindAssembly::UnwindAssembly ()
|
UnwindAssembly::UnwindAssembly (const ArchSpec &arch) :
|
||||||
|
m_arch (arch)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,183 @@
|
||||||
|
//===-- ARM_DWARF_Registers.c -----------------------------------*- C++ -*-===//
|
||||||
|
//
|
||||||
|
// The LLVM Compiler Infrastructure
|
||||||
|
//
|
||||||
|
// This file is distributed under the University of Illinois Open Source
|
||||||
|
// License. See LICENSE.TXT for details.
|
||||||
|
//
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
#include "ARM_DWARF_Registers.h"
|
||||||
|
|
||||||
|
const char *
|
||||||
|
GetARMDWARFRegisterName (unsigned reg_num)
|
||||||
|
{
|
||||||
|
switch (reg_num)
|
||||||
|
{
|
||||||
|
case dwarf_r0: return "r0";
|
||||||
|
case dwarf_r1: return "r1";
|
||||||
|
case dwarf_r2: return "r2";
|
||||||
|
case dwarf_r3: return "r3";
|
||||||
|
case dwarf_r4: return "r4";
|
||||||
|
case dwarf_r5: return "r5";
|
||||||
|
case dwarf_r6: return "r6";
|
||||||
|
case dwarf_r7: return "r7";
|
||||||
|
case dwarf_r8: return "r8";
|
||||||
|
case dwarf_r9: return "r9";
|
||||||
|
case dwarf_r10: return "r10";
|
||||||
|
case dwarf_r11: return "r11";
|
||||||
|
case dwarf_r12: return "r12";
|
||||||
|
case dwarf_sp: return "sp";
|
||||||
|
case dwarf_lr: return "lr";
|
||||||
|
case dwarf_pc: return "pc";
|
||||||
|
case dwarf_cpsr:return "cpsr";
|
||||||
|
|
||||||
|
case dwarf_s0: return "s0";
|
||||||
|
case dwarf_s1: return "s1";
|
||||||
|
case dwarf_s2: return "s2";
|
||||||
|
case dwarf_s3: return "s3";
|
||||||
|
case dwarf_s4: return "s4";
|
||||||
|
case dwarf_s5: return "s5";
|
||||||
|
case dwarf_s6: return "s6";
|
||||||
|
case dwarf_s7: return "s7";
|
||||||
|
case dwarf_s8: return "s8";
|
||||||
|
case dwarf_s9: return "s9";
|
||||||
|
case dwarf_s10: return "s10";
|
||||||
|
case dwarf_s11: return "s11";
|
||||||
|
case dwarf_s12: return "s12";
|
||||||
|
case dwarf_s13: return "s13";
|
||||||
|
case dwarf_s14: return "s14";
|
||||||
|
case dwarf_s15: return "s15";
|
||||||
|
case dwarf_s16: return "s16";
|
||||||
|
case dwarf_s17: return "s17";
|
||||||
|
case dwarf_s18: return "s18";
|
||||||
|
case dwarf_s19: return "s19";
|
||||||
|
case dwarf_s20: return "s20";
|
||||||
|
case dwarf_s21: return "s21";
|
||||||
|
case dwarf_s22: return "s22";
|
||||||
|
case dwarf_s23: return "s23";
|
||||||
|
case dwarf_s24: return "s24";
|
||||||
|
case dwarf_s25: return "s25";
|
||||||
|
case dwarf_s26: return "s26";
|
||||||
|
case dwarf_s27: return "s27";
|
||||||
|
case dwarf_s28: return "s28";
|
||||||
|
case dwarf_s29: return "s29";
|
||||||
|
case dwarf_s30: return "s30";
|
||||||
|
case dwarf_s31: return "s31";
|
||||||
|
|
||||||
|
// FPA Registers 0-7
|
||||||
|
case dwarf_f0: return "f0";
|
||||||
|
case dwarf_f1: return "f1";
|
||||||
|
case dwarf_f2: return "f2";
|
||||||
|
case dwarf_f3: return "f3";
|
||||||
|
case dwarf_f4: return "f4";
|
||||||
|
case dwarf_f5: return "f5";
|
||||||
|
case dwarf_f6: return "f6";
|
||||||
|
case dwarf_f7: return "f7";
|
||||||
|
|
||||||
|
// Intel wireless MMX general purpose registers 0–7
|
||||||
|
// XScale accumulator register 0–7 (they do overlap with wCGR0 - wCGR7)
|
||||||
|
case dwarf_wCGR0: return "wCGR0/ACC0";
|
||||||
|
case dwarf_wCGR1: return "wCGR1/ACC1";
|
||||||
|
case dwarf_wCGR2: return "wCGR2/ACC2";
|
||||||
|
case dwarf_wCGR3: return "wCGR3/ACC3";
|
||||||
|
case dwarf_wCGR4: return "wCGR4/ACC4";
|
||||||
|
case dwarf_wCGR5: return "wCGR5/ACC5";
|
||||||
|
case dwarf_wCGR6: return "wCGR6/ACC6";
|
||||||
|
case dwarf_wCGR7: return "wCGR7/ACC7";
|
||||||
|
|
||||||
|
// Intel wireless MMX data registers 0–15
|
||||||
|
case dwarf_wR0: return "wR0";
|
||||||
|
case dwarf_wR1: return "wR1";
|
||||||
|
case dwarf_wR2: return "wR2";
|
||||||
|
case dwarf_wR3: return "wR3";
|
||||||
|
case dwarf_wR4: return "wR4";
|
||||||
|
case dwarf_wR5: return "wR5";
|
||||||
|
case dwarf_wR6: return "wR6";
|
||||||
|
case dwarf_wR7: return "wR7";
|
||||||
|
case dwarf_wR8: return "wR8";
|
||||||
|
case dwarf_wR9: return "wR9";
|
||||||
|
case dwarf_wR10: return "wR10";
|
||||||
|
case dwarf_wR11: return "wR11";
|
||||||
|
case dwarf_wR12: return "wR12";
|
||||||
|
case dwarf_wR13: return "wR13";
|
||||||
|
case dwarf_wR14: return "wR14";
|
||||||
|
case dwarf_wR15: return "wR15";
|
||||||
|
|
||||||
|
case dwarf_spsr: return "spsr";
|
||||||
|
case dwarf_spsr_fiq: return "spsr_fiq";
|
||||||
|
case dwarf_spsr_irq: return "spsr_irq";
|
||||||
|
case dwarf_spsr_abt: return "spsr_abt";
|
||||||
|
case dwarf_spsr_und: return "spsr_und";
|
||||||
|
case dwarf_spsr_svc: return "spsr_svc";
|
||||||
|
|
||||||
|
case dwarf_r8_usr: return "r8_usr";
|
||||||
|
case dwarf_r9_usr: return "r9_usr";
|
||||||
|
case dwarf_r10_usr: return "r10_usr";
|
||||||
|
case dwarf_r11_usr: return "r11_usr";
|
||||||
|
case dwarf_r12_usr: return "r12_usr";
|
||||||
|
case dwarf_r13_usr: return "r13_usr";
|
||||||
|
case dwarf_r14_usr: return "r14_usr";
|
||||||
|
case dwarf_r8_fiq: return "r8_fiq";
|
||||||
|
case dwarf_r9_fiq: return "r9_fiq";
|
||||||
|
case dwarf_r10_fiq: return "r10_fiq";
|
||||||
|
case dwarf_r11_fiq: return "r11_fiq";
|
||||||
|
case dwarf_r12_fiq: return "r12_fiq";
|
||||||
|
case dwarf_r13_fiq: return "r13_fiq";
|
||||||
|
case dwarf_r14_fiq: return "r14_fiq";
|
||||||
|
case dwarf_r13_irq: return "r13_irq";
|
||||||
|
case dwarf_r14_irq: return "r14_irq";
|
||||||
|
case dwarf_r13_abt: return "r13_abt";
|
||||||
|
case dwarf_r14_abt: return "r14_abt";
|
||||||
|
case dwarf_r13_und: return "r13_und";
|
||||||
|
case dwarf_r14_und: return "r14_und";
|
||||||
|
case dwarf_r13_svc: return "r13_svc";
|
||||||
|
case dwarf_r14_svc: return "r14_svc";
|
||||||
|
|
||||||
|
// Intel wireless MMX control register in co-processor 0–7
|
||||||
|
case dwarf_wC0: return "wC0";
|
||||||
|
case dwarf_wC1: return "wC1";
|
||||||
|
case dwarf_wC2: return "wC2";
|
||||||
|
case dwarf_wC3: return "wC3";
|
||||||
|
case dwarf_wC4: return "wC4";
|
||||||
|
case dwarf_wC5: return "wC5";
|
||||||
|
case dwarf_wC6: return "wC6";
|
||||||
|
case dwarf_wC7: return "wC7";
|
||||||
|
|
||||||
|
// VFP-v3/Neon
|
||||||
|
case dwarf_d0: return "d0";
|
||||||
|
case dwarf_d1: return "d1";
|
||||||
|
case dwarf_d2: return "d2";
|
||||||
|
case dwarf_d3: return "d3";
|
||||||
|
case dwarf_d4: return "d4";
|
||||||
|
case dwarf_d5: return "d5";
|
||||||
|
case dwarf_d6: return "d6";
|
||||||
|
case dwarf_d7: return "d7";
|
||||||
|
case dwarf_d8: return "d8";
|
||||||
|
case dwarf_d9: return "d9";
|
||||||
|
case dwarf_d10: return "d10";
|
||||||
|
case dwarf_d11: return "d11";
|
||||||
|
case dwarf_d12: return "d12";
|
||||||
|
case dwarf_d13: return "d13";
|
||||||
|
case dwarf_d14: return "d14";
|
||||||
|
case dwarf_d15: return "d15";
|
||||||
|
case dwarf_d16: return "d16";
|
||||||
|
case dwarf_d17: return "d17";
|
||||||
|
case dwarf_d18: return "d18";
|
||||||
|
case dwarf_d19: return "d19";
|
||||||
|
case dwarf_d20: return "d20";
|
||||||
|
case dwarf_d21: return "d21";
|
||||||
|
case dwarf_d22: return "d22";
|
||||||
|
case dwarf_d23: return "d23";
|
||||||
|
case dwarf_d24: return "d24";
|
||||||
|
case dwarf_d25: return "d25";
|
||||||
|
case dwarf_d26: return "d26";
|
||||||
|
case dwarf_d27: return "d27";
|
||||||
|
case dwarf_d28: return "d28";
|
||||||
|
case dwarf_d29: return "d29";
|
||||||
|
case dwarf_d30: return "d30";
|
||||||
|
case dwarf_d31: return "d31";
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
|
@ -186,5 +186,16 @@ enum
|
||||||
dwarf_d31
|
dwarf_d31
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#if defined(__cplusplus)
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
const char *
|
||||||
|
GetARMDWARFRegisterName (unsigned reg_num);
|
||||||
|
|
||||||
|
#if defined(__cplusplus)
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif // utility_ARM_DWARF_Registers_h_
|
#endif // utility_ARM_DWARF_Registers_h_
|
||||||
|
|
||||||
|
|
|
@ -83,8 +83,8 @@ lldb_private::Initialize ()
|
||||||
ObjectFileELF::Initialize();
|
ObjectFileELF::Initialize();
|
||||||
SymbolFileDWARF::Initialize();
|
SymbolFileDWARF::Initialize();
|
||||||
SymbolFileSymtab::Initialize();
|
SymbolFileSymtab::Initialize();
|
||||||
UnwindAssembly_x86::Initialize();
|
|
||||||
UnwindAssemblyInstEmulation::Initialize();
|
UnwindAssemblyInstEmulation::Initialize();
|
||||||
|
UnwindAssembly_x86::Initialize();
|
||||||
ArchDefaultUnwindPlan_x86_64::Initialize();
|
ArchDefaultUnwindPlan_x86_64::Initialize();
|
||||||
ArchDefaultUnwindPlan_i386::Initialize();
|
ArchDefaultUnwindPlan_i386::Initialize();
|
||||||
ArchVolatileRegs_x86::Initialize();
|
ArchVolatileRegs_x86::Initialize();
|
||||||
|
|
Loading…
Reference in New Issue