forked from OSchip/llvm-project
Added Args::StringForEncoding(), Args::StringToGenericRegister() and centralized the parsing of the string to encoding and string to generic register.
Added code the initialize the register context in the OperatingSystemPython plug-in with the new PythonData classes, and added a test OperatingSystemPython module in lldb/examples/python/operating_system.py that we can use for testing. llvm-svn: 162530
This commit is contained in:
parent
6fb4b055fb
commit
2443cbd7f5
|
@ -0,0 +1,63 @@
|
||||||
|
#!/usr/bin/python
|
||||||
|
|
||||||
|
import lldb
|
||||||
|
|
||||||
|
class PlugIn(object):
|
||||||
|
"""Class that provides data for an instance of a LLDB 'OperatingSystemPython' plug-in class"""
|
||||||
|
|
||||||
|
def __init__(self, process):
|
||||||
|
'''Initialization needs a valid.SBProcess object'''
|
||||||
|
if type(process) is lldb.SBProcess and process.IsValid():
|
||||||
|
self.process = process
|
||||||
|
self.registers = None # Will be an dictionary containing info for each register
|
||||||
|
|
||||||
|
def get_thread_info(self):
|
||||||
|
if not self.threads:
|
||||||
|
self.threads = [
|
||||||
|
{ 'tid' : 0x111111111, 'name' : 'one' , 'queue' : 'queue1', 'state' : 'stopped', 'stop_reason' : 'breakpoint'},
|
||||||
|
{ 'tid' : 0x222222222, 'name' : 'two' , 'queue' : 'queue2', 'state' : 'stopped', 'stop_reason' : 'none' },
|
||||||
|
{ 'tid' : 0x333333333, 'name' : 'three', 'queue' : 'queue3', 'state' : 'stopped', 'stop_reason' : 'trace' }
|
||||||
|
]
|
||||||
|
return self.threads
|
||||||
|
|
||||||
|
def get_register_info(self):
|
||||||
|
if self.register_info == None:
|
||||||
|
self.register_info = dict()
|
||||||
|
triple = self.process.target.triple
|
||||||
|
if triple:
|
||||||
|
arch = triple.split('-')[0]
|
||||||
|
if arch == 'x86_64':
|
||||||
|
self.register_info['sets'] = ['GPR', 'FPU', 'EXC']
|
||||||
|
self.register_info['registers'] = [
|
||||||
|
{ 'name':'rax' , 'bitsize' : 64, 'offset' : 0, 'encoding':'uint' , 'format':'hex' , 'set': 0, 'gcc' : 0, 'dwarf' : 0},
|
||||||
|
{ 'name':'rbx' , 'bitsize' : 64, 'offset' : 8, 'encoding':'uint' , 'format':'hex' , 'set': 0, 'gcc' : 3, 'dwarf' : 3},
|
||||||
|
{ 'name':'rcx' , 'bitsize' : 64, 'offset' : 16, 'encoding':'uint' , 'format':'hex' , 'set': 0, 'gcc' : 2, 'dwarf' : 2, 'generic':'arg4', 'alt-name':'arg4', },
|
||||||
|
{ 'name':'rdx' , 'bitsize' : 64, 'offset' : 24, 'encoding':'uint' , 'format':'hex' , 'set': 0, 'gcc' : 1, 'dwarf' : 1, 'generic':'arg3', 'alt-name':'arg3', },
|
||||||
|
{ 'name':'rdi' , 'bitsize' : 64, 'offset' : 32, 'encoding':'uint' , 'format':'hex' , 'set': 0, 'gcc' : 5, 'dwarf' : 5, 'generic':'arg1', 'alt-name':'arg1', },
|
||||||
|
{ 'name':'rsi' , 'bitsize' : 64, 'offset' : 40, 'encoding':'uint' , 'format':'hex' , 'set': 0, 'gcc' : 4, 'dwarf' : 4, 'generic':'arg2', 'alt-name':'arg2', },
|
||||||
|
{ 'name':'rbp' , 'bitsize' : 64, 'offset' : 48, 'encoding':'uint' , 'format':'hex' , 'set': 0, 'gcc' : 6, 'dwarf' : 6, 'generic':'fp' , 'alt-name':'fp', },
|
||||||
|
{ 'name':'rsp' , 'bitsize' : 64, 'offset' : 56, 'encoding':'uint' , 'format':'hex' , 'set': 0, 'gcc' : 7, 'dwarf' : 7, 'generic':'sp' , 'alt-name':'sp', },
|
||||||
|
{ 'name':'r8' , 'bitsize' : 64, 'offset' : 64, 'encoding':'uint' , 'format':'hex' , 'set': 0, 'gcc' : 8, 'dwarf' : 8, 'generic':'arg5', 'alt-name':'arg5', },
|
||||||
|
{ 'name':'r9' , 'bitsize' : 64, 'offset' : 72, 'encoding':'uint' , 'format':'hex' , 'set': 0, 'gcc' : 9, 'dwarf' : 9, 'generic':'arg6', 'alt-name':'arg6', },
|
||||||
|
{ 'name':'r10' , 'bitsize' : 64, 'offset' : 80, 'encoding':'uint' , 'format':'hex' , 'set': 0, 'gcc' : 10, 'dwarf' : 10},
|
||||||
|
{ 'name':'r11' , 'bitsize' : 64, 'offset' : 88, 'encoding':'uint' , 'format':'hex' , 'set': 0, 'gcc' : 11, 'dwarf' : 11},
|
||||||
|
{ 'name':'r12' , 'bitsize' : 64, 'offset' : 96, 'encoding':'uint' , 'format':'hex' , 'set': 0, 'gcc' : 12, 'dwarf' : 12},
|
||||||
|
{ 'name':'r13' , 'bitsize' : 64, 'offset' : 104, 'encoding':'uint' , 'format':'hex' , 'set': 0, 'gcc' : 13, 'dwarf' : 13},
|
||||||
|
{ 'name':'r14' , 'bitsize' : 64, 'offset' : 112, 'encoding':'uint' , 'format':'hex' , 'set': 0, 'gcc' : 14, 'dwarf' : 14},
|
||||||
|
{ 'name':'r15' , 'bitsize' : 64, 'offset' : 120, 'encoding':'uint' , 'format':'hex' , 'set': 0, 'gcc' : 15, 'dwarf' : 15},
|
||||||
|
{ 'name':'rip' , 'bitsize' : 64, 'offset' : 128, 'encoding':'uint' , 'format':'hex' , 'set': 0, 'gcc' : 16, 'dwarf' : 16, 'generic':'pc', 'alt-name':'pc' },
|
||||||
|
{ 'name':'rflags' , 'bitsize' : 64, 'offset' : 136, 'encoding':'uint' , 'format':'hex' , 'set': 0, 'generic':'flags', 'alt-name':'flags' },
|
||||||
|
{ 'name':'cs' , 'bitsize' : 64, 'offset' : 144, 'encoding':'uint' , 'format':'hex' , 'set': 0 },
|
||||||
|
{ 'name':'fs' , 'bitsize' : 64, 'offset' : 152, 'encoding':'uint' , 'format':'hex' , 'set': 0 },
|
||||||
|
{ 'name':'gs' , 'bitsize' : 64, 'offset' : 160, 'encoding':'uint' , 'format':'hex' , 'set': 0 },
|
||||||
|
]
|
||||||
|
return self.register_info
|
||||||
|
|
||||||
|
def get_register_data(self, tid):
|
||||||
|
if tid == 0x111111111:
|
||||||
|
return pack('Q',1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21);
|
||||||
|
elif tid == 0x222222222:
|
||||||
|
return pack('Q',11,12,13,14,15,16,17,18,19,110,111,112,113,114,115,116,117,118,119,120,121);
|
||||||
|
elif tid == 0x333333333:
|
||||||
|
return pack('Q',21,22,23,24,25,26,27,28,29,210,211,212,213,214,215,216,217,218,219,220,221);
|
||||||
|
|
|
@ -398,6 +398,13 @@ public:
|
||||||
lldb::Format &format,
|
lldb::Format &format,
|
||||||
uint32_t *byte_size_ptr); // If non-NULL, then a byte size can precede the format character
|
uint32_t *byte_size_ptr); // If non-NULL, then a byte size can precede the format character
|
||||||
|
|
||||||
|
static lldb::Encoding
|
||||||
|
StringToEncoding (const char *s,
|
||||||
|
lldb::Encoding fail_value = lldb::eEncodingInvalid);
|
||||||
|
|
||||||
|
static uint32_t
|
||||||
|
StringToGenericRegister (const char *s);
|
||||||
|
|
||||||
static const char *
|
static const char *
|
||||||
StringToVersion (const char *s, uint32_t &major, uint32_t &minor, uint32_t &update);
|
StringToVersion (const char *s, uint32_t &major, uint32_t &minor, uint32_t &update);
|
||||||
|
|
||||||
|
|
|
@ -184,21 +184,27 @@ namespace lldb_private {
|
||||||
uint32_t GetSize();
|
uint32_t GetSize();
|
||||||
|
|
||||||
PythonDataObject
|
PythonDataObject
|
||||||
GetItemForKey (const PythonDataString &key);
|
GetItemForKey (const PythonDataString &key) const;
|
||||||
|
|
||||||
|
const char *
|
||||||
|
GetItemForKeyAsString (const PythonDataString &key, const char *fail_value = NULL) const;
|
||||||
|
|
||||||
|
int64_t
|
||||||
|
GetItemForKeyAsInteger (const PythonDataString &key, int64_t fail_value = 0) const;
|
||||||
|
|
||||||
PythonDataObject
|
PythonDataObject
|
||||||
GetItemForKey (const char *key);
|
GetItemForKey (const char *key) const;
|
||||||
|
|
||||||
typedef bool (*DictionaryIteratorCallback)(PythonDataString* key, PythonDataDictionary* dict);
|
typedef bool (*DictionaryIteratorCallback)(PythonDataString* key, PythonDataDictionary* dict);
|
||||||
|
|
||||||
PythonDataArray
|
PythonDataArray
|
||||||
GetKeys ();
|
GetKeys () const;
|
||||||
|
|
||||||
PythonDataString
|
PythonDataString
|
||||||
GetKeyAtPosition (uint32_t pos);
|
GetKeyAtPosition (uint32_t pos) const;
|
||||||
|
|
||||||
PythonDataObject
|
PythonDataObject
|
||||||
GetValueAtPosition (uint32_t pos);
|
GetValueAtPosition (uint32_t pos) const;
|
||||||
|
|
||||||
void
|
void
|
||||||
SetItemForKey (const PythonDataString &key, const PythonDataObject& value);
|
SetItemForKey (const PythonDataString &key, const PythonDataObject& value);
|
||||||
|
|
|
@ -1007,6 +1007,60 @@ Args::StringToFormat
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
lldb::Encoding
|
||||||
|
Args::StringToEncoding (const char *s, lldb::Encoding fail_value)
|
||||||
|
{
|
||||||
|
if (s && s[0])
|
||||||
|
{
|
||||||
|
if (strcmp(s, "uint") == 0)
|
||||||
|
return eEncodingUint;
|
||||||
|
else if (strcmp(s, "sint") == 0)
|
||||||
|
return eEncodingSint;
|
||||||
|
else if (strcmp(s, "ieee754") == 0)
|
||||||
|
return eEncodingIEEE754;
|
||||||
|
else if (strcmp(s, "vector") == 0)
|
||||||
|
return eEncodingVector;
|
||||||
|
}
|
||||||
|
return fail_value;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t
|
||||||
|
Args::StringToGenericRegister (const char *s)
|
||||||
|
{
|
||||||
|
if (s && s[0])
|
||||||
|
{
|
||||||
|
if (strcmp(s, "pc") == 0)
|
||||||
|
return LLDB_REGNUM_GENERIC_PC;
|
||||||
|
else if (strcmp(s, "sp") == 0)
|
||||||
|
return LLDB_REGNUM_GENERIC_SP;
|
||||||
|
else if (strcmp(s, "fp") == 0)
|
||||||
|
return LLDB_REGNUM_GENERIC_FP;
|
||||||
|
else if (strcmp(s, "ra") == 0)
|
||||||
|
return LLDB_REGNUM_GENERIC_RA;
|
||||||
|
else if (strcmp(s, "flags") == 0)
|
||||||
|
return LLDB_REGNUM_GENERIC_FLAGS;
|
||||||
|
else if (strncmp(s, "arg", 3) == 0)
|
||||||
|
{
|
||||||
|
if (s[3] && s[4] == '\0')
|
||||||
|
{
|
||||||
|
switch (s[3])
|
||||||
|
{
|
||||||
|
case '1': return LLDB_REGNUM_GENERIC_ARG1;
|
||||||
|
case '2': return LLDB_REGNUM_GENERIC_ARG2;
|
||||||
|
case '3': return LLDB_REGNUM_GENERIC_ARG3;
|
||||||
|
case '4': return LLDB_REGNUM_GENERIC_ARG4;
|
||||||
|
case '5': return LLDB_REGNUM_GENERIC_ARG5;
|
||||||
|
case '6': return LLDB_REGNUM_GENERIC_ARG6;
|
||||||
|
case '7': return LLDB_REGNUM_GENERIC_ARG7;
|
||||||
|
case '8': return LLDB_REGNUM_GENERIC_ARG8;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return LLDB_INVALID_REGNUM;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
Args::LongestCommonPrefix (std::string &common_prefix)
|
Args::LongestCommonPrefix (std::string &common_prefix)
|
||||||
{
|
{
|
||||||
|
|
|
@ -212,7 +212,7 @@ PythonDataDictionary::GetSize()
|
||||||
}
|
}
|
||||||
|
|
||||||
PythonDataObject
|
PythonDataObject
|
||||||
PythonDataDictionary::GetItemForKey (const char *key)
|
PythonDataDictionary::GetItemForKey (const char *key) const
|
||||||
{
|
{
|
||||||
if (key && key[0])
|
if (key && key[0])
|
||||||
{
|
{
|
||||||
|
@ -224,15 +224,40 @@ PythonDataDictionary::GetItemForKey (const char *key)
|
||||||
|
|
||||||
|
|
||||||
PythonDataObject
|
PythonDataObject
|
||||||
PythonDataDictionary::GetItemForKey (const PythonDataString &key)
|
PythonDataDictionary::GetItemForKey (const PythonDataString &key) const
|
||||||
{
|
{
|
||||||
if (m_object && key)
|
if (m_object && key)
|
||||||
return PythonDataObject(PyDict_GetItem(GetPythonObject(), key.GetPythonObject()));
|
return PythonDataObject(PyDict_GetItem(GetPythonObject(), key.GetPythonObject()));
|
||||||
return PythonDataObject();
|
return PythonDataObject();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const char *
|
||||||
|
PythonDataDictionary::GetItemForKeyAsString (const PythonDataString &key, const char *fail_value) const
|
||||||
|
{
|
||||||
|
if (m_object && key)
|
||||||
|
{
|
||||||
|
PyObject *object = PyDict_GetItem(GetPythonObject(), key.GetPythonObject());
|
||||||
|
if (object && PyString_Check(object))
|
||||||
|
return PyString_AsString(object);
|
||||||
|
}
|
||||||
|
return fail_value;
|
||||||
|
}
|
||||||
|
|
||||||
|
int64_t
|
||||||
|
PythonDataDictionary::GetItemForKeyAsInteger (const PythonDataString &key, int64_t fail_value) const
|
||||||
|
{
|
||||||
|
if (m_object && key)
|
||||||
|
{
|
||||||
|
PyObject *object = PyDict_GetItem(GetPythonObject(), key.GetPythonObject());
|
||||||
|
if (object && PyInt_Check(object))
|
||||||
|
return PyInt_AsLong(object);
|
||||||
|
}
|
||||||
|
return fail_value;
|
||||||
|
}
|
||||||
|
|
||||||
PythonDataArray
|
PythonDataArray
|
||||||
PythonDataDictionary::GetKeys ()
|
PythonDataDictionary::GetKeys () const
|
||||||
{
|
{
|
||||||
if (m_object)
|
if (m_object)
|
||||||
return PythonDataArray(PyDict_Keys(GetPythonObject()));
|
return PythonDataArray(PyDict_Keys(GetPythonObject()));
|
||||||
|
@ -240,7 +265,7 @@ PythonDataDictionary::GetKeys ()
|
||||||
}
|
}
|
||||||
|
|
||||||
PythonDataString
|
PythonDataString
|
||||||
PythonDataDictionary::GetKeyAtPosition (uint32_t pos)
|
PythonDataDictionary::GetKeyAtPosition (uint32_t pos) const
|
||||||
{
|
{
|
||||||
PyObject *key, *value;
|
PyObject *key, *value;
|
||||||
Py_ssize_t pos_iter = 0;
|
Py_ssize_t pos_iter = 0;
|
||||||
|
@ -257,7 +282,7 @@ PythonDataDictionary::GetKeyAtPosition (uint32_t pos)
|
||||||
}
|
}
|
||||||
|
|
||||||
PythonDataObject
|
PythonDataObject
|
||||||
PythonDataDictionary::GetValueAtPosition (uint32_t pos)
|
PythonDataDictionary::GetValueAtPosition (uint32_t pos) const
|
||||||
{
|
{
|
||||||
PyObject *key, *value;
|
PyObject *key, *value;
|
||||||
Py_ssize_t pos_iter = 0;
|
Py_ssize_t pos_iter = 0;
|
||||||
|
|
|
@ -12,13 +12,12 @@
|
||||||
// C Includes
|
// C Includes
|
||||||
// C++ Includes
|
// C++ Includes
|
||||||
// Other libraries and framework includes
|
// Other libraries and framework includes
|
||||||
#include "llvm/ADT/Triple.h"
|
|
||||||
|
|
||||||
#include "lldb/Core/ArchSpec.h"
|
#include "lldb/Core/ArchSpec.h"
|
||||||
#include "lldb/Core/DataBufferHeap.h"
|
#include "lldb/Core/DataBufferHeap.h"
|
||||||
#include "lldb/Core/Debugger.h"
|
#include "lldb/Core/Debugger.h"
|
||||||
#include "lldb/Core/Module.h"
|
#include "lldb/Core/Module.h"
|
||||||
#include "lldb/Core/PluginManager.h"
|
#include "lldb/Core/PluginManager.h"
|
||||||
|
#include "lldb/Interpreter/PythonDataObjects.h"
|
||||||
#include "lldb/Core/RegisterValue.h"
|
#include "lldb/Core/RegisterValue.h"
|
||||||
#include "lldb/Core/ValueObjectVariable.h"
|
#include "lldb/Core/ValueObjectVariable.h"
|
||||||
#include "lldb/Interpreter/CommandInterpreter.h"
|
#include "lldb/Interpreter/CommandInterpreter.h"
|
||||||
|
@ -56,7 +55,7 @@ OperatingSystem *
|
||||||
OperatingSystemPython::CreateInstance (Process *process, bool force)
|
OperatingSystemPython::CreateInstance (Process *process, bool force)
|
||||||
{
|
{
|
||||||
// Python OperatingSystem plug-ins must be requested by name, so force must be true
|
// Python OperatingSystem plug-ins must be requested by name, so force must be true
|
||||||
//if (force)
|
if (force)
|
||||||
return new OperatingSystemPython (process);
|
return new OperatingSystemPython (process);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -93,7 +92,11 @@ OperatingSystemPython::OperatingSystemPython (lldb_private::Process *process) :
|
||||||
// TODO: hardcoded is not good
|
// TODO: hardcoded is not good
|
||||||
auto object_sp = m_interpreter->CreateOSPlugin("operating_system.PlugIn",process->CalculateProcess());
|
auto object_sp = m_interpreter->CreateOSPlugin("operating_system.PlugIn",process->CalculateProcess());
|
||||||
if (object_sp)
|
if (object_sp)
|
||||||
|
{
|
||||||
m_python_object = object_sp->GetObject();
|
m_python_object = object_sp->GetObject();
|
||||||
|
|
||||||
|
// GetDynamicRegisterInfo (); // Only for testing should this be done here
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -104,74 +107,22 @@ OperatingSystemPython::~OperatingSystemPython ()
|
||||||
DynamicRegisterInfo *
|
DynamicRegisterInfo *
|
||||||
OperatingSystemPython::GetDynamicRegisterInfo ()
|
OperatingSystemPython::GetDynamicRegisterInfo ()
|
||||||
{
|
{
|
||||||
if (!m_interpreter || !m_python_object)
|
if (m_register_info_ap.get() == NULL)
|
||||||
return NULL;
|
|
||||||
auto object_sp = m_interpreter->OSPlugin_QueryForRegisterInfo(m_interpreter->MakeScriptObject(m_python_object));
|
|
||||||
if (!object_sp)
|
|
||||||
return NULL;
|
|
||||||
PythonDataObject dictionary_data_obj((PyObject*)object_sp->GetObject());
|
|
||||||
PythonDataDictionary dictionary = dictionary_data_obj.GetDictionaryObject();
|
|
||||||
if(!dictionary)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
// TODO: iterate over the dictionary
|
|
||||||
if (m_register_info_ap.get() == NULL && m_thread_list_valobj_sp)
|
|
||||||
{
|
{
|
||||||
// static ConstString g_gpr_member_name("gpr");
|
if (!m_interpreter || !m_python_object)
|
||||||
// m_register_info_ap.reset (new DynamicRegisterInfo());
|
return NULL;
|
||||||
// ConstString empty_name;
|
auto object_sp = m_interpreter->OSPlugin_QueryForRegisterInfo(m_interpreter->MakeScriptObject(m_python_object));
|
||||||
// const bool can_create = true;
|
if (!object_sp)
|
||||||
// AddressType addr_type;
|
return NULL;
|
||||||
// addr_t base_addr = LLDB_INVALID_ADDRESS;
|
PythonDataObject dictionary_data_obj((PyObject*)object_sp->GetObject());
|
||||||
// ValueObjectSP gpr_valobj_sp (m_thread_list_valobj_sp->GetChildMemberWithName(GetThreadGPRMemberName (), can_create));
|
PythonDataDictionary dictionary = dictionary_data_obj.GetDictionaryObject();
|
||||||
//
|
if (!dictionary)
|
||||||
// if (gpr_valobj_sp->IsPointerType ())
|
return NULL;
|
||||||
// base_addr = gpr_valobj_sp->GetPointerValue (&addr_type);
|
|
||||||
// else
|
m_register_info_ap.reset (new DynamicRegisterInfo (dictionary));
|
||||||
// base_addr = gpr_valobj_sp->GetAddressOf (true, &addr_type);
|
assert (m_register_info_ap->GetNumRegisters() > 0);
|
||||||
//
|
assert (m_register_info_ap->GetNumRegisterSets() > 0);
|
||||||
// ValueObjectSP child_valobj_sp;
|
|
||||||
// if (gpr_valobj_sp)
|
|
||||||
// {
|
|
||||||
// ABI *abi = m_process->GetABI().get();
|
|
||||||
// assert (abi);
|
|
||||||
// uint32_t num_children = gpr_valobj_sp->GetNumChildren();
|
|
||||||
//
|
|
||||||
// ConstString gpr_name (gpr_valobj_sp->GetName());
|
|
||||||
// uint32_t reg_num = 0;
|
|
||||||
// for (uint32_t i=0; i<num_children; ++i)
|
|
||||||
// {
|
|
||||||
// child_valobj_sp = gpr_valobj_sp->GetChildAtIndex(i, can_create);
|
|
||||||
//
|
|
||||||
// ConstString reg_name(child_valobj_sp->GetName());
|
|
||||||
// if (reg_name)
|
|
||||||
// {
|
|
||||||
// const char *reg_name_cstr = reg_name.GetCString();
|
|
||||||
// while (reg_name_cstr[0] == '_')
|
|
||||||
// ++reg_name_cstr;
|
|
||||||
// if (reg_name_cstr != reg_name.GetCString())
|
|
||||||
// reg_name.SetCString (reg_name_cstr);
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// RegisterInfo reg_info;
|
|
||||||
// if (abi->GetRegisterInfoByName(reg_name, reg_info))
|
|
||||||
// {
|
|
||||||
// // Adjust the byte size and the offset to match the layout of registers in our struct
|
|
||||||
// reg_info.byte_size = child_valobj_sp->GetByteSize();
|
|
||||||
// reg_info.byte_offset = child_valobj_sp->GetAddressOf(true, &addr_type) - base_addr;
|
|
||||||
// reg_info.kinds[eRegisterKindLLDB] = reg_num++;
|
|
||||||
// m_register_info_ap->AddRegister (reg_info, reg_name, empty_name, gpr_name);
|
|
||||||
// }
|
|
||||||
// else
|
|
||||||
// {
|
|
||||||
// printf ("not able to find register info for %s\n", reg_name.GetCString()); // REMOVE THIS printf before checkin!!!
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// m_register_info_ap->Finalize();
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
assert (m_register_info_ap.get());
|
|
||||||
return m_register_info_ap.get();
|
return m_register_info_ap.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -13,6 +13,8 @@
|
||||||
// C++ Includes
|
// C++ Includes
|
||||||
// Other libraries and framework includes
|
// Other libraries and framework includes
|
||||||
// Project includes
|
// Project includes
|
||||||
|
#include "lldb/Interpreter/Args.h"
|
||||||
|
#include "lldb/Interpreter/PythonDataObjects.h"
|
||||||
|
|
||||||
using namespace lldb;
|
using namespace lldb;
|
||||||
using namespace lldb_private;
|
using namespace lldb_private;
|
||||||
|
@ -21,26 +23,147 @@ DynamicRegisterInfo::DynamicRegisterInfo () :
|
||||||
m_regs (),
|
m_regs (),
|
||||||
m_sets (),
|
m_sets (),
|
||||||
m_set_reg_nums (),
|
m_set_reg_nums (),
|
||||||
m_reg_names (),
|
|
||||||
m_reg_alt_names (),
|
|
||||||
m_set_names (),
|
m_set_names (),
|
||||||
m_reg_data_byte_size (0)
|
m_reg_data_byte_size (0)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DynamicRegisterInfo::DynamicRegisterInfo (const lldb_private::PythonDataDictionary &dict) :
|
||||||
|
m_regs (),
|
||||||
|
m_sets (),
|
||||||
|
m_set_reg_nums (),
|
||||||
|
m_set_names (),
|
||||||
|
m_reg_data_byte_size (0)
|
||||||
|
{
|
||||||
|
SetRegisterInfo (dict);
|
||||||
|
}
|
||||||
|
|
||||||
DynamicRegisterInfo::~DynamicRegisterInfo ()
|
DynamicRegisterInfo::~DynamicRegisterInfo ()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
size_t
|
||||||
|
DynamicRegisterInfo::SetRegisterInfo (const lldb_private::PythonDataDictionary &dict)
|
||||||
|
{
|
||||||
|
PythonDataArray sets (dict.GetItemForKey("sets").GetArrayObject());
|
||||||
|
if (sets)
|
||||||
|
{
|
||||||
|
const uint32_t num_sets = sets.GetSize();
|
||||||
|
for (uint32_t i=0; i<num_sets; ++i)
|
||||||
|
{
|
||||||
|
ConstString set_name (sets.GetItemAtIndex(i).GetStringObject().GetString());
|
||||||
|
if (set_name)
|
||||||
|
{
|
||||||
|
RegisterSet new_set = { set_name.AsCString(), NULL, 0, NULL };
|
||||||
|
m_sets.push_back (new_set);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Clear();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
m_set_reg_nums.resize(m_sets.size());
|
||||||
|
}
|
||||||
|
PythonDataArray regs (dict.GetItemForKey("registers").GetArrayObject());
|
||||||
|
if (regs)
|
||||||
|
{
|
||||||
|
const uint32_t num_regs = regs.GetSize();
|
||||||
|
PythonDataString name_pystr("name");
|
||||||
|
PythonDataString altname_pystr("alt-name");
|
||||||
|
PythonDataString bitsize_pystr("bitsize");
|
||||||
|
PythonDataString offset_pystr("offset");
|
||||||
|
PythonDataString encoding_pystr("encoding");
|
||||||
|
PythonDataString format_pystr("format");
|
||||||
|
PythonDataString set_pystr("set");
|
||||||
|
PythonDataString gcc_pystr("gcc");
|
||||||
|
PythonDataString dwarf_pystr("dwarf");
|
||||||
|
PythonDataString generic_pystr("generic");
|
||||||
|
for (uint32_t i=0; i<num_regs; ++i)
|
||||||
|
{
|
||||||
|
PythonDataDictionary reg_info_dict(regs.GetItemAtIndex(i).GetDictionaryObject());
|
||||||
|
if (reg_info_dict)
|
||||||
|
{
|
||||||
|
// { 'name':'rcx' , 'bitsize' : 64, 'offset' : 16, 'encoding':'uint' , 'format':'hex' , 'set': 0, 'gcc' : 2, 'dwarf' : 2, 'generic':'arg4', 'alt-name':'arg4', },
|
||||||
|
RegisterInfo reg_info;
|
||||||
|
bzero (®_info, sizeof(reg_info));
|
||||||
|
|
||||||
|
reg_info.name = ConstString (reg_info_dict.GetItemForKeyAsString(name_pystr)).GetCString();
|
||||||
|
if (reg_info.name == NULL)
|
||||||
|
{
|
||||||
|
Clear();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
reg_info.alt_name = ConstString (reg_info_dict.GetItemForKeyAsString(altname_pystr)).GetCString();
|
||||||
|
|
||||||
|
reg_info.byte_offset = reg_info_dict.GetItemForKeyAsInteger(offset_pystr, UINT32_MAX);
|
||||||
|
|
||||||
|
if (reg_info.byte_offset == UINT32_MAX)
|
||||||
|
{
|
||||||
|
Clear();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
reg_info.byte_size = reg_info_dict.GetItemForKeyAsInteger(bitsize_pystr, 0) / 8;
|
||||||
|
|
||||||
|
if (reg_info.byte_size == 0)
|
||||||
|
{
|
||||||
|
Clear();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *format_cstr = reg_info_dict.GetItemForKeyAsString(format_pystr);
|
||||||
|
if (format_cstr)
|
||||||
|
{
|
||||||
|
if (Args::StringToFormat(format_cstr, reg_info.format, NULL).Fail())
|
||||||
|
{
|
||||||
|
Clear();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
reg_info.format = eFormatHex;
|
||||||
|
|
||||||
|
const char *encoding_cstr = reg_info_dict.GetItemForKeyAsString(encoding_pystr);
|
||||||
|
if (encoding_cstr)
|
||||||
|
reg_info.encoding = Args::StringToEncoding (encoding_cstr, eEncodingUint);
|
||||||
|
else
|
||||||
|
reg_info.encoding = eEncodingUint;
|
||||||
|
|
||||||
|
const int64_t set = reg_info_dict.GetItemForKeyAsInteger(set_pystr, -1);
|
||||||
|
if (set == -1)
|
||||||
|
{
|
||||||
|
Clear();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_set_reg_nums[set].push_back(i);
|
||||||
|
reg_info.kinds[lldb::eRegisterKindLLDB] = i;
|
||||||
|
reg_info.kinds[lldb::eRegisterKindGDB] = i;
|
||||||
|
reg_info.kinds[lldb::eRegisterKindGCC] = reg_info_dict.GetItemForKeyAsInteger(gcc_pystr, LLDB_INVALID_REGNUM);
|
||||||
|
reg_info.kinds[lldb::eRegisterKindDWARF] = reg_info_dict.GetItemForKeyAsInteger(dwarf_pystr, LLDB_INVALID_REGNUM);
|
||||||
|
reg_info.kinds[lldb::eRegisterKindGeneric] = Args::StringToGenericRegister (reg_info_dict.GetItemForKeyAsString(generic_pystr));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Clear();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Finalize ();
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
DynamicRegisterInfo::AddRegister (RegisterInfo ®_info,
|
DynamicRegisterInfo::AddRegister (RegisterInfo ®_info,
|
||||||
ConstString ®_name,
|
ConstString ®_name,
|
||||||
ConstString ®_alt_name,
|
ConstString ®_alt_name,
|
||||||
ConstString &set_name)
|
ConstString &set_name)
|
||||||
{
|
{
|
||||||
const uint32_t reg_num = m_regs.size();
|
const uint32_t reg_num = m_regs.size();
|
||||||
m_reg_names.push_back (reg_name);
|
|
||||||
m_reg_alt_names.push_back (reg_alt_name);
|
|
||||||
reg_info.name = reg_name.AsCString();
|
reg_info.name = reg_name.AsCString();
|
||||||
assert (reg_info.name);
|
assert (reg_info.name);
|
||||||
reg_info.alt_name = reg_alt_name.AsCString(NULL);
|
reg_info.alt_name = reg_alt_name.AsCString(NULL);
|
||||||
|
@ -136,7 +259,5 @@ DynamicRegisterInfo::Clear()
|
||||||
m_regs.clear();
|
m_regs.clear();
|
||||||
m_sets.clear();
|
m_sets.clear();
|
||||||
m_set_reg_nums.clear();
|
m_set_reg_nums.clear();
|
||||||
m_reg_names.clear();
|
|
||||||
m_reg_alt_names.clear();
|
|
||||||
m_set_names.clear();
|
m_set_names.clear();
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,9 +24,14 @@ class DynamicRegisterInfo
|
||||||
public:
|
public:
|
||||||
DynamicRegisterInfo ();
|
DynamicRegisterInfo ();
|
||||||
|
|
||||||
|
DynamicRegisterInfo (const lldb_private::PythonDataDictionary &dict);
|
||||||
|
|
||||||
virtual
|
virtual
|
||||||
~DynamicRegisterInfo ();
|
~DynamicRegisterInfo ();
|
||||||
|
|
||||||
|
size_t
|
||||||
|
SetRegisterInfo (const lldb_private::PythonDataDictionary &dict);
|
||||||
|
|
||||||
void
|
void
|
||||||
AddRegister (lldb_private::RegisterInfo ®_info,
|
AddRegister (lldb_private::RegisterInfo ®_info,
|
||||||
lldb_private::ConstString ®_name,
|
lldb_private::ConstString ®_name,
|
||||||
|
@ -73,8 +78,6 @@ protected:
|
||||||
reg_collection m_regs;
|
reg_collection m_regs;
|
||||||
set_collection m_sets;
|
set_collection m_sets;
|
||||||
set_reg_num_collection m_set_reg_nums;
|
set_reg_num_collection m_set_reg_nums;
|
||||||
name_collection m_reg_names;
|
|
||||||
name_collection m_reg_alt_names;
|
|
||||||
name_collection m_set_names;
|
name_collection m_set_names;
|
||||||
size_t m_reg_data_byte_size; // The number of bytes required to store all registers
|
size_t m_reg_data_byte_size; // The number of bytes required to store all registers
|
||||||
};
|
};
|
||||||
|
|
|
@ -300,18 +300,16 @@ ProcessGDBRemote::BuildDynamicRegisterInfo (bool force)
|
||||||
}
|
}
|
||||||
else if (name.compare("encoding") == 0)
|
else if (name.compare("encoding") == 0)
|
||||||
{
|
{
|
||||||
if (value.compare("uint") == 0)
|
const Encoding encoding = Args::StringToEncoding (value.c_str());
|
||||||
reg_info.encoding = eEncodingUint;
|
if (encoding != eEncodingInvalid)
|
||||||
else if (value.compare("sint") == 0)
|
reg_info.encoding = encoding;
|
||||||
reg_info.encoding = eEncodingSint;
|
|
||||||
else if (value.compare("ieee754") == 0)
|
|
||||||
reg_info.encoding = eEncodingIEEE754;
|
|
||||||
else if (value.compare("vector") == 0)
|
|
||||||
reg_info.encoding = eEncodingVector;
|
|
||||||
}
|
}
|
||||||
else if (name.compare("format") == 0)
|
else if (name.compare("format") == 0)
|
||||||
{
|
{
|
||||||
if (value.compare("binary") == 0)
|
Format format = eFormatInvalid;
|
||||||
|
if (Args::StringToFormat (value.c_str(), format, NULL).Success())
|
||||||
|
reg_info.format = format;
|
||||||
|
else if (value.compare("binary") == 0)
|
||||||
reg_info.format = eFormatBinary;
|
reg_info.format = eFormatBinary;
|
||||||
else if (value.compare("decimal") == 0)
|
else if (value.compare("decimal") == 0)
|
||||||
reg_info.format = eFormatDecimal;
|
reg_info.format = eFormatDecimal;
|
||||||
|
@ -350,33 +348,7 @@ ProcessGDBRemote::BuildDynamicRegisterInfo (bool force)
|
||||||
}
|
}
|
||||||
else if (name.compare("generic") == 0)
|
else if (name.compare("generic") == 0)
|
||||||
{
|
{
|
||||||
if (value.compare("pc") == 0)
|
reg_info.kinds[eRegisterKindGeneric] = Args::StringToGenericRegister (value.c_str());
|
||||||
reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_PC;
|
|
||||||
else if (value.compare("sp") == 0)
|
|
||||||
reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_SP;
|
|
||||||
else if (value.compare("fp") == 0)
|
|
||||||
reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_FP;
|
|
||||||
else if (value.compare("ra") == 0)
|
|
||||||
reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_RA;
|
|
||||||
else if (value.compare("flags") == 0)
|
|
||||||
reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_FLAGS;
|
|
||||||
else if (value.find("arg") == 0)
|
|
||||||
{
|
|
||||||
if (value.size() == 4)
|
|
||||||
{
|
|
||||||
switch (value[3])
|
|
||||||
{
|
|
||||||
case '1': reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_ARG1; break;
|
|
||||||
case '2': reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_ARG2; break;
|
|
||||||
case '3': reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_ARG3; break;
|
|
||||||
case '4': reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_ARG4; break;
|
|
||||||
case '5': reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_ARG5; break;
|
|
||||||
case '6': reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_ARG6; break;
|
|
||||||
case '7': reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_ARG7; break;
|
|
||||||
case '8': reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_ARG8; break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue