2011-08-22 02:49:39 +00:00
//===-- DynamicRegisterInfo.cpp ----------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
2012-12-05 00:20:57 +00:00
# include "lldb/lldb-python.h"
2011-08-22 02:49:39 +00:00
# include "DynamicRegisterInfo.h"
// C Includes
// C++ Includes
// Other libraries and framework includes
// Project includes
2012-08-24 01:42:50 +00:00
# include "lldb/Interpreter/Args.h"
<rdar://problem/14972424>
- Made the dynamic register context for the GDB remote plug-in inherit from the generic DynamicRegisterInfo to avoid code duplication
- Finished up the target definition python setting stuff.
- Added a new "slice" key/value pair that can specify that a register is part of another register:
{ 'name':'eax', 'set':0, 'bitsize':32, 'encoding':eEncodingUint, 'format':eFormatHex, 'slice': 'rax[31:0]' },
- Added a new "composite" key/value pair that can specify that a register is made up of two or more registers:
{ 'name':'d0', 'set':0, 'bitsize':64 , 'encoding':eEncodingIEEE754, 'format':eFormatFloat, 'composite': ['s1', 's0'] },
- Added a new "invalidate-regs" key/value pair for when a register is modified, it can invalidate other registers:
{ 'name':'cpsr', 'set':0, 'bitsize':32 , 'encoding':eEncodingUint, 'format':eFormatHex, 'invalidate-regs': ['r8', 'r9', 'r10', 'r11', 'r12', 'r13', 'r14', 'r15']},
This now completes the feature that allows a GDB remote target to completely describe itself.
llvm-svn: 192858
2013-10-17 01:10:23 +00:00
# include "lldb/Core/RegularExpression.h"
# include "lldb/Core/StreamFile.h"
# include "lldb/DataFormatters/FormatManager.h"
2012-09-11 06:35:15 +00:00
# ifndef LLDB_DISABLE_PYTHON
2012-08-24 01:42:50 +00:00
# include "lldb/Interpreter/PythonDataObjects.h"
2012-09-11 06:35:15 +00:00
# endif
2011-08-22 02:49:39 +00:00
using namespace lldb ;
using namespace lldb_private ;
DynamicRegisterInfo : : DynamicRegisterInfo ( ) :
m_regs ( ) ,
m_sets ( ) ,
m_set_reg_nums ( ) ,
m_set_names ( ) ,
<rdar://problem/14972424>
- Made the dynamic register context for the GDB remote plug-in inherit from the generic DynamicRegisterInfo to avoid code duplication
- Finished up the target definition python setting stuff.
- Added a new "slice" key/value pair that can specify that a register is part of another register:
{ 'name':'eax', 'set':0, 'bitsize':32, 'encoding':eEncodingUint, 'format':eFormatHex, 'slice': 'rax[31:0]' },
- Added a new "composite" key/value pair that can specify that a register is made up of two or more registers:
{ 'name':'d0', 'set':0, 'bitsize':64 , 'encoding':eEncodingIEEE754, 'format':eFormatFloat, 'composite': ['s1', 's0'] },
- Added a new "invalidate-regs" key/value pair for when a register is modified, it can invalidate other registers:
{ 'name':'cpsr', 'set':0, 'bitsize':32 , 'encoding':eEncodingUint, 'format':eFormatHex, 'invalidate-regs': ['r8', 'r9', 'r10', 'r11', 'r12', 'r13', 'r14', 'r15']},
This now completes the feature that allows a GDB remote target to completely describe itself.
llvm-svn: 192858
2013-10-17 01:10:23 +00:00
m_value_regs_map ( ) ,
m_invalidate_regs_map ( ) ,
m_reg_data_byte_size ( 0 ) ,
m_finalized ( false )
2011-08-22 02:49:39 +00:00
{
}
<rdar://problem/14972424>
- Made the dynamic register context for the GDB remote plug-in inherit from the generic DynamicRegisterInfo to avoid code duplication
- Finished up the target definition python setting stuff.
- Added a new "slice" key/value pair that can specify that a register is part of another register:
{ 'name':'eax', 'set':0, 'bitsize':32, 'encoding':eEncodingUint, 'format':eFormatHex, 'slice': 'rax[31:0]' },
- Added a new "composite" key/value pair that can specify that a register is made up of two or more registers:
{ 'name':'d0', 'set':0, 'bitsize':64 , 'encoding':eEncodingIEEE754, 'format':eFormatFloat, 'composite': ['s1', 's0'] },
- Added a new "invalidate-regs" key/value pair for when a register is modified, it can invalidate other registers:
{ 'name':'cpsr', 'set':0, 'bitsize':32 , 'encoding':eEncodingUint, 'format':eFormatHex, 'invalidate-regs': ['r8', 'r9', 'r10', 'r11', 'r12', 'r13', 'r14', 'r15']},
This now completes the feature that allows a GDB remote target to completely describe itself.
llvm-svn: 192858
2013-10-17 01:10:23 +00:00
DynamicRegisterInfo : : DynamicRegisterInfo ( const lldb_private : : PythonDictionary & dict , ByteOrder byte_order ) :
2012-08-24 01:42:50 +00:00
m_regs ( ) ,
m_sets ( ) ,
m_set_reg_nums ( ) ,
m_set_names ( ) ,
<rdar://problem/14972424>
- Made the dynamic register context for the GDB remote plug-in inherit from the generic DynamicRegisterInfo to avoid code duplication
- Finished up the target definition python setting stuff.
- Added a new "slice" key/value pair that can specify that a register is part of another register:
{ 'name':'eax', 'set':0, 'bitsize':32, 'encoding':eEncodingUint, 'format':eFormatHex, 'slice': 'rax[31:0]' },
- Added a new "composite" key/value pair that can specify that a register is made up of two or more registers:
{ 'name':'d0', 'set':0, 'bitsize':64 , 'encoding':eEncodingIEEE754, 'format':eFormatFloat, 'composite': ['s1', 's0'] },
- Added a new "invalidate-regs" key/value pair for when a register is modified, it can invalidate other registers:
{ 'name':'cpsr', 'set':0, 'bitsize':32 , 'encoding':eEncodingUint, 'format':eFormatHex, 'invalidate-regs': ['r8', 'r9', 'r10', 'r11', 'r12', 'r13', 'r14', 'r15']},
This now completes the feature that allows a GDB remote target to completely describe itself.
llvm-svn: 192858
2013-10-17 01:10:23 +00:00
m_value_regs_map ( ) ,
m_invalidate_regs_map ( ) ,
m_reg_data_byte_size ( 0 ) ,
m_finalized ( false )
2012-08-24 01:42:50 +00:00
{
<rdar://problem/14972424>
- Made the dynamic register context for the GDB remote plug-in inherit from the generic DynamicRegisterInfo to avoid code duplication
- Finished up the target definition python setting stuff.
- Added a new "slice" key/value pair that can specify that a register is part of another register:
{ 'name':'eax', 'set':0, 'bitsize':32, 'encoding':eEncodingUint, 'format':eFormatHex, 'slice': 'rax[31:0]' },
- Added a new "composite" key/value pair that can specify that a register is made up of two or more registers:
{ 'name':'d0', 'set':0, 'bitsize':64 , 'encoding':eEncodingIEEE754, 'format':eFormatFloat, 'composite': ['s1', 's0'] },
- Added a new "invalidate-regs" key/value pair for when a register is modified, it can invalidate other registers:
{ 'name':'cpsr', 'set':0, 'bitsize':32 , 'encoding':eEncodingUint, 'format':eFormatHex, 'invalidate-regs': ['r8', 'r9', 'r10', 'r11', 'r12', 'r13', 'r14', 'r15']},
This now completes the feature that allows a GDB remote target to completely describe itself.
llvm-svn: 192858
2013-10-17 01:10:23 +00:00
SetRegisterInfo ( dict , byte_order ) ;
2012-08-24 01:42:50 +00:00
}
2011-08-22 02:49:39 +00:00
DynamicRegisterInfo : : ~ DynamicRegisterInfo ( )
{
}
2012-08-24 01:42:50 +00:00
size_t
<rdar://problem/14972424>
- Made the dynamic register context for the GDB remote plug-in inherit from the generic DynamicRegisterInfo to avoid code duplication
- Finished up the target definition python setting stuff.
- Added a new "slice" key/value pair that can specify that a register is part of another register:
{ 'name':'eax', 'set':0, 'bitsize':32, 'encoding':eEncodingUint, 'format':eFormatHex, 'slice': 'rax[31:0]' },
- Added a new "composite" key/value pair that can specify that a register is made up of two or more registers:
{ 'name':'d0', 'set':0, 'bitsize':64 , 'encoding':eEncodingIEEE754, 'format':eFormatFloat, 'composite': ['s1', 's0'] },
- Added a new "invalidate-regs" key/value pair for when a register is modified, it can invalidate other registers:
{ 'name':'cpsr', 'set':0, 'bitsize':32 , 'encoding':eEncodingUint, 'format':eFormatHex, 'invalidate-regs': ['r8', 'r9', 'r10', 'r11', 'r12', 'r13', 'r14', 'r15']},
This now completes the feature that allows a GDB remote target to completely describe itself.
llvm-svn: 192858
2013-10-17 01:10:23 +00:00
DynamicRegisterInfo : : SetRegisterInfo ( const lldb_private : : PythonDictionary & dict ,
ByteOrder byte_order )
2012-08-24 01:42:50 +00:00
{
<rdar://problem/14972424>
- Made the dynamic register context for the GDB remote plug-in inherit from the generic DynamicRegisterInfo to avoid code duplication
- Finished up the target definition python setting stuff.
- Added a new "slice" key/value pair that can specify that a register is part of another register:
{ 'name':'eax', 'set':0, 'bitsize':32, 'encoding':eEncodingUint, 'format':eFormatHex, 'slice': 'rax[31:0]' },
- Added a new "composite" key/value pair that can specify that a register is made up of two or more registers:
{ 'name':'d0', 'set':0, 'bitsize':64 , 'encoding':eEncodingIEEE754, 'format':eFormatFloat, 'composite': ['s1', 's0'] },
- Added a new "invalidate-regs" key/value pair for when a register is modified, it can invalidate other registers:
{ 'name':'cpsr', 'set':0, 'bitsize':32 , 'encoding':eEncodingUint, 'format':eFormatHex, 'invalidate-regs': ['r8', 'r9', 'r10', 'r11', 'r12', 'r13', 'r14', 'r15']},
This now completes the feature that allows a GDB remote target to completely describe itself.
llvm-svn: 192858
2013-10-17 01:10:23 +00:00
assert ( ! m_finalized ) ;
2012-09-11 06:35:15 +00:00
# ifndef LLDB_DISABLE_PYTHON
<rdar://problem/13010007>
Added the ability for OS plug-ins to lazily populate the thread this. The python OS plug-in classes can now implement the following method:
class OperatingSystemPlugin:
def create_thread(self, tid, context):
# Return a dictionary for a new thread to create it on demand
This will add a new thread to the thread list if it doesn't already exist. The example code in lldb/examples/python/operating_system.py has been updated to show how this call us used.
Cleaned up the code in PythonDataObjects.cpp/h:
- renamed all classes that started with PythonData* to be Python*.
- renamed PythonArray to PythonList. Cleaned up the code to use inheritance where
- Centralized the code that does ref counting in the PythonObject class to a single function.
- Made the "bool PythonObject::Reset(PyObject *)" function be virtual so each subclass can correctly check to ensure a PyObject is of the right type before adopting the object.
- Cleaned up all APIs and added new constructors for the Python* classes to they can all construct form:
- PyObject *
- const PythonObject &
- const lldb::ScriptInterpreterObjectSP &
Cleaned up code in ScriptInterpreterPython:
- Made calling python functions safer by templatizing the production of value formats. Python specifies the value formats based on built in C types (long, long long, etc), and code often uses typedefs for uint32_t, uint64_t, etc when passing arguments down to python. We will now always produce correct value formats as the templatized code will "do the right thing" all the time.
- Fixed issues with the ScriptInterpreterPython::Locker where entering the session and leaving the session had a bunch of issues that could cause the "lldb" module globals lldb.debugger, lldb.target, lldb.process, lldb.thread, and lldb.frame to not be initialized.
llvm-svn: 172873
2013-01-18 23:41:08 +00:00
PythonList sets ( dict . GetItemForKey ( " sets " ) ) ;
2012-08-24 01:42:50 +00:00
if ( sets )
{
const uint32_t num_sets = sets . GetSize ( ) ;
for ( uint32_t i = 0 ; i < num_sets ; + + i )
{
<rdar://problem/13010007>
Added the ability for OS plug-ins to lazily populate the thread this. The python OS plug-in classes can now implement the following method:
class OperatingSystemPlugin:
def create_thread(self, tid, context):
# Return a dictionary for a new thread to create it on demand
This will add a new thread to the thread list if it doesn't already exist. The example code in lldb/examples/python/operating_system.py has been updated to show how this call us used.
Cleaned up the code in PythonDataObjects.cpp/h:
- renamed all classes that started with PythonData* to be Python*.
- renamed PythonArray to PythonList. Cleaned up the code to use inheritance where
- Centralized the code that does ref counting in the PythonObject class to a single function.
- Made the "bool PythonObject::Reset(PyObject *)" function be virtual so each subclass can correctly check to ensure a PyObject is of the right type before adopting the object.
- Cleaned up all APIs and added new constructors for the Python* classes to they can all construct form:
- PyObject *
- const PythonObject &
- const lldb::ScriptInterpreterObjectSP &
Cleaned up code in ScriptInterpreterPython:
- Made calling python functions safer by templatizing the production of value formats. Python specifies the value formats based on built in C types (long, long long, etc), and code often uses typedefs for uint32_t, uint64_t, etc when passing arguments down to python. We will now always produce correct value formats as the templatized code will "do the right thing" all the time.
- Fixed issues with the ScriptInterpreterPython::Locker where entering the session and leaving the session had a bunch of issues that could cause the "lldb" module globals lldb.debugger, lldb.target, lldb.process, lldb.thread, and lldb.frame to not be initialized.
llvm-svn: 172873
2013-01-18 23:41:08 +00:00
PythonString py_set_name ( sets . GetItemAtIndex ( i ) ) ;
ConstString set_name ;
if ( py_set_name )
set_name . SetCString ( py_set_name . GetString ( ) ) ;
2012-08-24 01:42:50 +00:00
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 ( ) ) ;
}
<rdar://problem/13010007>
Added the ability for OS plug-ins to lazily populate the thread this. The python OS plug-in classes can now implement the following method:
class OperatingSystemPlugin:
def create_thread(self, tid, context):
# Return a dictionary for a new thread to create it on demand
This will add a new thread to the thread list if it doesn't already exist. The example code in lldb/examples/python/operating_system.py has been updated to show how this call us used.
Cleaned up the code in PythonDataObjects.cpp/h:
- renamed all classes that started with PythonData* to be Python*.
- renamed PythonArray to PythonList. Cleaned up the code to use inheritance where
- Centralized the code that does ref counting in the PythonObject class to a single function.
- Made the "bool PythonObject::Reset(PyObject *)" function be virtual so each subclass can correctly check to ensure a PyObject is of the right type before adopting the object.
- Cleaned up all APIs and added new constructors for the Python* classes to they can all construct form:
- PyObject *
- const PythonObject &
- const lldb::ScriptInterpreterObjectSP &
Cleaned up code in ScriptInterpreterPython:
- Made calling python functions safer by templatizing the production of value formats. Python specifies the value formats based on built in C types (long, long long, etc), and code often uses typedefs for uint32_t, uint64_t, etc when passing arguments down to python. We will now always produce correct value formats as the templatized code will "do the right thing" all the time.
- Fixed issues with the ScriptInterpreterPython::Locker where entering the session and leaving the session had a bunch of issues that could cause the "lldb" module globals lldb.debugger, lldb.target, lldb.process, lldb.thread, and lldb.frame to not be initialized.
llvm-svn: 172873
2013-01-18 23:41:08 +00:00
PythonList regs ( dict . GetItemForKey ( " registers " ) ) ;
2012-08-24 01:42:50 +00:00
if ( regs )
{
const uint32_t num_regs = regs . GetSize ( ) ;
<rdar://problem/13010007>
Added the ability for OS plug-ins to lazily populate the thread this. The python OS plug-in classes can now implement the following method:
class OperatingSystemPlugin:
def create_thread(self, tid, context):
# Return a dictionary for a new thread to create it on demand
This will add a new thread to the thread list if it doesn't already exist. The example code in lldb/examples/python/operating_system.py has been updated to show how this call us used.
Cleaned up the code in PythonDataObjects.cpp/h:
- renamed all classes that started with PythonData* to be Python*.
- renamed PythonArray to PythonList. Cleaned up the code to use inheritance where
- Centralized the code that does ref counting in the PythonObject class to a single function.
- Made the "bool PythonObject::Reset(PyObject *)" function be virtual so each subclass can correctly check to ensure a PyObject is of the right type before adopting the object.
- Cleaned up all APIs and added new constructors for the Python* classes to they can all construct form:
- PyObject *
- const PythonObject &
- const lldb::ScriptInterpreterObjectSP &
Cleaned up code in ScriptInterpreterPython:
- Made calling python functions safer by templatizing the production of value formats. Python specifies the value formats based on built in C types (long, long long, etc), and code often uses typedefs for uint32_t, uint64_t, etc when passing arguments down to python. We will now always produce correct value formats as the templatized code will "do the right thing" all the time.
- Fixed issues with the ScriptInterpreterPython::Locker where entering the session and leaving the session had a bunch of issues that could cause the "lldb" module globals lldb.debugger, lldb.target, lldb.process, lldb.thread, and lldb.frame to not be initialized.
llvm-svn: 172873
2013-01-18 23:41:08 +00:00
PythonString name_pystr ( " name " ) ;
PythonString altname_pystr ( " alt-name " ) ;
PythonString bitsize_pystr ( " bitsize " ) ;
PythonString offset_pystr ( " offset " ) ;
PythonString encoding_pystr ( " encoding " ) ;
PythonString format_pystr ( " format " ) ;
PythonString set_pystr ( " set " ) ;
PythonString gcc_pystr ( " gcc " ) ;
PythonString dwarf_pystr ( " dwarf " ) ;
PythonString generic_pystr ( " generic " ) ;
<rdar://problem/14972424>
- Made the dynamic register context for the GDB remote plug-in inherit from the generic DynamicRegisterInfo to avoid code duplication
- Finished up the target definition python setting stuff.
- Added a new "slice" key/value pair that can specify that a register is part of another register:
{ 'name':'eax', 'set':0, 'bitsize':32, 'encoding':eEncodingUint, 'format':eFormatHex, 'slice': 'rax[31:0]' },
- Added a new "composite" key/value pair that can specify that a register is made up of two or more registers:
{ 'name':'d0', 'set':0, 'bitsize':64 , 'encoding':eEncodingIEEE754, 'format':eFormatFloat, 'composite': ['s1', 's0'] },
- Added a new "invalidate-regs" key/value pair for when a register is modified, it can invalidate other registers:
{ 'name':'cpsr', 'set':0, 'bitsize':32 , 'encoding':eEncodingUint, 'format':eFormatHex, 'invalidate-regs': ['r8', 'r9', 'r10', 'r11', 'r12', 'r13', 'r14', 'r15']},
This now completes the feature that allows a GDB remote target to completely describe itself.
llvm-svn: 192858
2013-10-17 01:10:23 +00:00
PythonString slice_pystr ( " slice " ) ;
PythonString composite_pystr ( " composite " ) ;
PythonString invalidate_regs_pystr ( " invalidate-regs " ) ;
// typedef std::map<std::string, std::vector<std::string> > InvalidateNameMap;
// InvalidateNameMap invalidate_map;
2012-08-24 01:42:50 +00:00
for ( uint32_t i = 0 ; i < num_regs ; + + i )
{
<rdar://problem/13010007>
Added the ability for OS plug-ins to lazily populate the thread this. The python OS plug-in classes can now implement the following method:
class OperatingSystemPlugin:
def create_thread(self, tid, context):
# Return a dictionary for a new thread to create it on demand
This will add a new thread to the thread list if it doesn't already exist. The example code in lldb/examples/python/operating_system.py has been updated to show how this call us used.
Cleaned up the code in PythonDataObjects.cpp/h:
- renamed all classes that started with PythonData* to be Python*.
- renamed PythonArray to PythonList. Cleaned up the code to use inheritance where
- Centralized the code that does ref counting in the PythonObject class to a single function.
- Made the "bool PythonObject::Reset(PyObject *)" function be virtual so each subclass can correctly check to ensure a PyObject is of the right type before adopting the object.
- Cleaned up all APIs and added new constructors for the Python* classes to they can all construct form:
- PyObject *
- const PythonObject &
- const lldb::ScriptInterpreterObjectSP &
Cleaned up code in ScriptInterpreterPython:
- Made calling python functions safer by templatizing the production of value formats. Python specifies the value formats based on built in C types (long, long long, etc), and code often uses typedefs for uint32_t, uint64_t, etc when passing arguments down to python. We will now always produce correct value formats as the templatized code will "do the right thing" all the time.
- Fixed issues with the ScriptInterpreterPython::Locker where entering the session and leaving the session had a bunch of issues that could cause the "lldb" module globals lldb.debugger, lldb.target, lldb.process, lldb.thread, and lldb.frame to not be initialized.
llvm-svn: 172873
2013-01-18 23:41:08 +00:00
PythonDictionary reg_info_dict ( regs . GetItemAtIndex ( i ) ) ;
2012-08-24 01:42:50 +00:00
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 ;
<rdar://problem/14972424>
- Made the dynamic register context for the GDB remote plug-in inherit from the generic DynamicRegisterInfo to avoid code duplication
- Finished up the target definition python setting stuff.
- Added a new "slice" key/value pair that can specify that a register is part of another register:
{ 'name':'eax', 'set':0, 'bitsize':32, 'encoding':eEncodingUint, 'format':eFormatHex, 'slice': 'rax[31:0]' },
- Added a new "composite" key/value pair that can specify that a register is made up of two or more registers:
{ 'name':'d0', 'set':0, 'bitsize':64 , 'encoding':eEncodingIEEE754, 'format':eFormatFloat, 'composite': ['s1', 's0'] },
- Added a new "invalidate-regs" key/value pair for when a register is modified, it can invalidate other registers:
{ 'name':'cpsr', 'set':0, 'bitsize':32 , 'encoding':eEncodingUint, 'format':eFormatHex, 'invalidate-regs': ['r8', 'r9', 'r10', 'r11', 'r12', 'r13', 'r14', 'r15']},
This now completes the feature that allows a GDB remote target to completely describe itself.
llvm-svn: 192858
2013-10-17 01:10:23 +00:00
std : : vector < uint32_t > value_regs ;
std : : vector < uint32_t > invalidate_regs ;
2012-08-24 01:42:50 +00:00
bzero ( & reg_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 )
{
<rdar://problem/14972424>
- Made the dynamic register context for the GDB remote plug-in inherit from the generic DynamicRegisterInfo to avoid code duplication
- Finished up the target definition python setting stuff.
- Added a new "slice" key/value pair that can specify that a register is part of another register:
{ 'name':'eax', 'set':0, 'bitsize':32, 'encoding':eEncodingUint, 'format':eFormatHex, 'slice': 'rax[31:0]' },
- Added a new "composite" key/value pair that can specify that a register is made up of two or more registers:
{ 'name':'d0', 'set':0, 'bitsize':64 , 'encoding':eEncodingIEEE754, 'format':eFormatFloat, 'composite': ['s1', 's0'] },
- Added a new "invalidate-regs" key/value pair for when a register is modified, it can invalidate other registers:
{ 'name':'cpsr', 'set':0, 'bitsize':32 , 'encoding':eEncodingUint, 'format':eFormatHex, 'invalidate-regs': ['r8', 'r9', 'r10', 'r11', 'r12', 'r13', 'r14', 'r15']},
This now completes the feature that allows a GDB remote target to completely describe itself.
llvm-svn: 192858
2013-10-17 01:10:23 +00:00
// No offset for this register, see if the register has a value expression
// which indicates this register is part of another register. Value expressions
// are things like "rax[31:0]" which state that the current register's value
// is in a concrete register "rax" in bits 31:0. If there is a value expression
// we can calculate the offset
bool success = false ;
const char * slice_cstr = reg_info_dict . GetItemForKeyAsString ( slice_pystr ) ;
if ( slice_cstr )
{
// Slices use the following format:
// REGNAME[MSBIT:LSBIT]
// REGNAME - name of the register to grab a slice of
// MSBIT - the most significant bit at which the current register value starts at
// LSBIT - the least significant bit at which the current register value ends at
static RegularExpression g_bitfield_regex ( " ([A-Za-z_][A-Za-z0-9_]*) \ \ [ ( [ 0 - 9 ] + ) : ( [ 0 - 9 ] + ) \ \ ] " ) ;
RegularExpression : : Match regex_match ( 3 ) ;
if ( g_bitfield_regex . Execute ( slice_cstr , & regex_match ) )
{
llvm : : StringRef reg_name_str ;
std : : string msbit_str ;
std : : string lsbit_str ;
if ( regex_match . GetMatchAtIndex ( slice_cstr , 1 , reg_name_str ) & &
regex_match . GetMatchAtIndex ( slice_cstr , 2 , msbit_str ) & &
regex_match . GetMatchAtIndex ( slice_cstr , 3 , lsbit_str ) )
{
const uint32_t msbit = Args : : StringToUInt32 ( msbit_str . c_str ( ) , UINT32_MAX ) ;
const uint32_t lsbit = Args : : StringToUInt32 ( lsbit_str . c_str ( ) , UINT32_MAX ) ;
if ( msbit ! = UINT32_MAX & & lsbit ! = UINT32_MAX )
{
if ( msbit > lsbit )
{
const uint32_t msbyte = msbit / 8 ;
const uint32_t lsbyte = lsbit / 8 ;
ConstString containing_reg_name ( reg_name_str ) ;
RegisterInfo * containing_reg_info = GetRegisterInfo ( containing_reg_name ) ;
if ( containing_reg_info )
{
const uint32_t max_bit = containing_reg_info - > byte_size * 8 ;
if ( msbit < max_bit & & lsbit < max_bit )
{
m_invalidate_regs_map [ containing_reg_info - > kinds [ eRegisterKindLLDB ] ] . push_back ( i ) ;
m_value_regs_map [ i ] . push_back ( containing_reg_info - > kinds [ eRegisterKindLLDB ] ) ;
m_invalidate_regs_map [ i ] . push_back ( containing_reg_info - > kinds [ eRegisterKindLLDB ] ) ;
if ( byte_order = = eByteOrderLittle )
{
success = true ;
reg_info . byte_offset = containing_reg_info - > byte_offset + lsbyte ;
}
else if ( byte_order = = eByteOrderBig )
{
success = true ;
reg_info . byte_offset = containing_reg_info - > byte_offset + msbyte ;
}
else
{
assert ( ! " Invalid byte order " ) ;
}
}
else
{
if ( msbit > max_bit )
printf ( " error: msbit (%u) must be less than the bitsize of the register (%u) \n " , msbit , max_bit ) ;
else
printf ( " error: lsbit (%u) must be less than the bitsize of the register (%u) \n " , lsbit , max_bit ) ;
}
}
else
{
printf ( " error: invalid concrete register \" %s \" \n " , containing_reg_name . GetCString ( ) ) ;
}
}
else
{
printf ( " error: msbit (%u) must be greater than lsbit (%u) \n " , msbit , lsbit ) ;
}
}
else
{
printf ( " error: msbit (%u) and lsbit (%u) must be valid \n " , msbit , lsbit ) ;
}
}
else
{
// TODO: print error invalid slice string that doesn't follow the format
printf ( " error: failed to extract regex matches for parsing the register bitfield regex \n " ) ;
}
}
else
{
// TODO: print error invalid slice string that doesn't follow the format
printf ( " error: failed to match against register bitfield regex \n " ) ;
}
}
else
{
PythonList composite_reg_list ( reg_info_dict . GetItemForKey ( composite_pystr ) ) ;
if ( composite_reg_list )
{
const size_t num_composite_regs = composite_reg_list . GetSize ( ) ;
if ( num_composite_regs > 0 )
{
uint32_t composite_offset = UINT32_MAX ;
for ( uint32_t composite_idx = 0 ; composite_idx < num_composite_regs ; + + composite_idx )
{
PythonString composite_reg_name_pystr ( composite_reg_list . GetItemAtIndex ( composite_idx ) ) ;
if ( composite_reg_name_pystr )
{
ConstString composite_reg_name ( composite_reg_name_pystr . GetString ( ) ) ;
if ( composite_reg_name )
{
RegisterInfo * composite_reg_info = GetRegisterInfo ( composite_reg_name ) ;
if ( composite_reg_info )
{
if ( composite_offset > composite_reg_info - > byte_offset )
composite_offset = composite_reg_info - > byte_offset ;
m_value_regs_map [ i ] . push_back ( composite_reg_info - > kinds [ eRegisterKindLLDB ] ) ;
m_invalidate_regs_map [ composite_reg_info - > kinds [ eRegisterKindLLDB ] ] . push_back ( i ) ;
m_invalidate_regs_map [ i ] . push_back ( composite_reg_info - > kinds [ eRegisterKindLLDB ] ) ;
}
else
{
// TODO: print error invalid slice string that doesn't follow the format
printf ( " error: failed to find composite register by name: \" %s \" \n " , composite_reg_name . GetCString ( ) ) ;
}
}
else
{
printf ( " error: 'composite' key contained an empty string \n " ) ;
}
}
else
{
printf ( " error: 'composite' list value wasn't a python string \n " ) ;
}
}
if ( composite_offset ! = UINT32_MAX )
{
reg_info . byte_offset = composite_offset ;
success = m_value_regs_map . find ( i ) ! = m_value_regs_map . end ( ) ;
}
else
{
printf ( " error: 'composite' registers must specify at least one real register \n " ) ;
}
}
else
{
printf ( " error: 'composite' list was empty \n " ) ;
}
}
}
if ( ! success )
{
Clear ( ) ;
return 0 ;
}
2012-08-24 01:42:50 +00:00
}
<rdar://problem/14972424>
When debugging with the GDB remote in LLDB, LLDB uses special packets to discover the
registers on the remote server. When those packets aren't supported, LLDB doesn't
know what the registers look like. This checkin implements a setting that can be used
to specify a python file that contains the registers definitions. The setting is:
(lldb) settings set plugin.process.gdb-remote.target-definition-file /path/to/module.py
Inside module there should be a function:
def get_dynamic_setting(target, setting_name):
This dynamic setting function is handed the "target" which is a SBTarget, and the
"setting_name", which is the name of the dynamic setting to retrieve. For the GDB
remote target definition the setting name is 'gdb-server-target-definition'. The
return value is a dictionary that follows the same format as the OperatingSystem
plugins follow. I have checked in an example file that implements the x86_64 GDB
register set for people to see:
examples/python/x86_64_target_definition.py
This allows LLDB to debug to any archticture that is support and allows users to
define the registers contexts when the discovery packets (qRegisterInfo, qHostInfo)
are not supported by the remote GDB server.
A few benefits of doing this in Python:
1 - The dynamic register context was already supported in the OperatingSystem plug-in
2 - Register contexts can use all of the LLDB enumerations and definitions for things
like lldb::Format, lldb::Encoding, generic register numbers, invalid registers
numbers, etc.
3 - The code that generates the register context can use the program to calculate the
register context contents (like offsets, register numbers, and more)
4 - True dynamic detection could be used where variables and types could be read from
the target program itself in order to determine which registers are available since
the target is passed into the python function.
This is designed to be used instead of XML since it is more dynamic and code flow and
functions can be used to make the dictionary.
llvm-svn: 192646
2013-10-15 00:14:28 +00:00
const int64_t bitsize = reg_info_dict . GetItemForKeyAsInteger ( bitsize_pystr , 0 ) ;
if ( bitsize = = 0 )
2012-08-24 01:42:50 +00:00
{
Clear ( ) ;
return 0 ;
}
<rdar://problem/14972424>
When debugging with the GDB remote in LLDB, LLDB uses special packets to discover the
registers on the remote server. When those packets aren't supported, LLDB doesn't
know what the registers look like. This checkin implements a setting that can be used
to specify a python file that contains the registers definitions. The setting is:
(lldb) settings set plugin.process.gdb-remote.target-definition-file /path/to/module.py
Inside module there should be a function:
def get_dynamic_setting(target, setting_name):
This dynamic setting function is handed the "target" which is a SBTarget, and the
"setting_name", which is the name of the dynamic setting to retrieve. For the GDB
remote target definition the setting name is 'gdb-server-target-definition'. The
return value is a dictionary that follows the same format as the OperatingSystem
plugins follow. I have checked in an example file that implements the x86_64 GDB
register set for people to see:
examples/python/x86_64_target_definition.py
This allows LLDB to debug to any archticture that is support and allows users to
define the registers contexts when the discovery packets (qRegisterInfo, qHostInfo)
are not supported by the remote GDB server.
A few benefits of doing this in Python:
1 - The dynamic register context was already supported in the OperatingSystem plug-in
2 - Register contexts can use all of the LLDB enumerations and definitions for things
like lldb::Format, lldb::Encoding, generic register numbers, invalid registers
numbers, etc.
3 - The code that generates the register context can use the program to calculate the
register context contents (like offsets, register numbers, and more)
4 - True dynamic detection could be used where variables and types could be read from
the target program itself in order to determine which registers are available since
the target is passed into the python function.
This is designed to be used instead of XML since it is more dynamic and code flow and
functions can be used to make the dictionary.
llvm-svn: 192646
2013-10-15 00:14:28 +00:00
reg_info . byte_size = bitsize / 8 ;
2012-08-24 01:42:50 +00:00
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
<rdar://problem/14972424>
When debugging with the GDB remote in LLDB, LLDB uses special packets to discover the
registers on the remote server. When those packets aren't supported, LLDB doesn't
know what the registers look like. This checkin implements a setting that can be used
to specify a python file that contains the registers definitions. The setting is:
(lldb) settings set plugin.process.gdb-remote.target-definition-file /path/to/module.py
Inside module there should be a function:
def get_dynamic_setting(target, setting_name):
This dynamic setting function is handed the "target" which is a SBTarget, and the
"setting_name", which is the name of the dynamic setting to retrieve. For the GDB
remote target definition the setting name is 'gdb-server-target-definition'. The
return value is a dictionary that follows the same format as the OperatingSystem
plugins follow. I have checked in an example file that implements the x86_64 GDB
register set for people to see:
examples/python/x86_64_target_definition.py
This allows LLDB to debug to any archticture that is support and allows users to
define the registers contexts when the discovery packets (qRegisterInfo, qHostInfo)
are not supported by the remote GDB server.
A few benefits of doing this in Python:
1 - The dynamic register context was already supported in the OperatingSystem plug-in
2 - Register contexts can use all of the LLDB enumerations and definitions for things
like lldb::Format, lldb::Encoding, generic register numbers, invalid registers
numbers, etc.
3 - The code that generates the register context can use the program to calculate the
register context contents (like offsets, register numbers, and more)
4 - True dynamic detection could be used where variables and types could be read from
the target program itself in order to determine which registers are available since
the target is passed into the python function.
This is designed to be used instead of XML since it is more dynamic and code flow and
functions can be used to make the dictionary.
llvm-svn: 192646
2013-10-15 00:14:28 +00:00
{
reg_info . format = ( Format ) reg_info_dict . GetItemForKeyAsInteger ( format_pystr , eFormatHex ) ;
}
2012-08-24 01:42:50 +00:00
const char * encoding_cstr = reg_info_dict . GetItemForKeyAsString ( encoding_pystr ) ;
if ( encoding_cstr )
reg_info . encoding = Args : : StringToEncoding ( encoding_cstr , eEncodingUint ) ;
else
<rdar://problem/14972424>
When debugging with the GDB remote in LLDB, LLDB uses special packets to discover the
registers on the remote server. When those packets aren't supported, LLDB doesn't
know what the registers look like. This checkin implements a setting that can be used
to specify a python file that contains the registers definitions. The setting is:
(lldb) settings set plugin.process.gdb-remote.target-definition-file /path/to/module.py
Inside module there should be a function:
def get_dynamic_setting(target, setting_name):
This dynamic setting function is handed the "target" which is a SBTarget, and the
"setting_name", which is the name of the dynamic setting to retrieve. For the GDB
remote target definition the setting name is 'gdb-server-target-definition'. The
return value is a dictionary that follows the same format as the OperatingSystem
plugins follow. I have checked in an example file that implements the x86_64 GDB
register set for people to see:
examples/python/x86_64_target_definition.py
This allows LLDB to debug to any archticture that is support and allows users to
define the registers contexts when the discovery packets (qRegisterInfo, qHostInfo)
are not supported by the remote GDB server.
A few benefits of doing this in Python:
1 - The dynamic register context was already supported in the OperatingSystem plug-in
2 - Register contexts can use all of the LLDB enumerations and definitions for things
like lldb::Format, lldb::Encoding, generic register numbers, invalid registers
numbers, etc.
3 - The code that generates the register context can use the program to calculate the
register context contents (like offsets, register numbers, and more)
4 - True dynamic detection could be used where variables and types could be read from
the target program itself in order to determine which registers are available since
the target is passed into the python function.
This is designed to be used instead of XML since it is more dynamic and code flow and
functions can be used to make the dictionary.
llvm-svn: 192646
2013-10-15 00:14:28 +00:00
reg_info . encoding = ( Encoding ) reg_info_dict . GetItemForKeyAsInteger ( encoding_pystr , eEncodingUint ) ;
2012-08-24 01:42:50 +00:00
const int64_t set = reg_info_dict . GetItemForKeyAsInteger ( set_pystr , - 1 ) ;
2012-08-24 02:01:39 +00:00
if ( set > = m_sets . size ( ) )
2012-08-24 01:42:50 +00:00
{
Clear ( ) ;
return 0 ;
}
<rdar://problem/14972424>
- Made the dynamic register context for the GDB remote plug-in inherit from the generic DynamicRegisterInfo to avoid code duplication
- Finished up the target definition python setting stuff.
- Added a new "slice" key/value pair that can specify that a register is part of another register:
{ 'name':'eax', 'set':0, 'bitsize':32, 'encoding':eEncodingUint, 'format':eFormatHex, 'slice': 'rax[31:0]' },
- Added a new "composite" key/value pair that can specify that a register is made up of two or more registers:
{ 'name':'d0', 'set':0, 'bitsize':64 , 'encoding':eEncodingIEEE754, 'format':eFormatFloat, 'composite': ['s1', 's0'] },
- Added a new "invalidate-regs" key/value pair for when a register is modified, it can invalidate other registers:
{ 'name':'cpsr', 'set':0, 'bitsize':32 , 'encoding':eEncodingUint, 'format':eFormatHex, 'invalidate-regs': ['r8', 'r9', 'r10', 'r11', 'r12', 'r13', 'r14', 'r15']},
This now completes the feature that allows a GDB remote target to completely describe itself.
llvm-svn: 192858
2013-10-17 01:10:23 +00:00
// Fill in the register numbers
2012-08-24 01:42:50 +00:00
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 ) ;
<rdar://problem/14972424>
When debugging with the GDB remote in LLDB, LLDB uses special packets to discover the
registers on the remote server. When those packets aren't supported, LLDB doesn't
know what the registers look like. This checkin implements a setting that can be used
to specify a python file that contains the registers definitions. The setting is:
(lldb) settings set plugin.process.gdb-remote.target-definition-file /path/to/module.py
Inside module there should be a function:
def get_dynamic_setting(target, setting_name):
This dynamic setting function is handed the "target" which is a SBTarget, and the
"setting_name", which is the name of the dynamic setting to retrieve. For the GDB
remote target definition the setting name is 'gdb-server-target-definition'. The
return value is a dictionary that follows the same format as the OperatingSystem
plugins follow. I have checked in an example file that implements the x86_64 GDB
register set for people to see:
examples/python/x86_64_target_definition.py
This allows LLDB to debug to any archticture that is support and allows users to
define the registers contexts when the discovery packets (qRegisterInfo, qHostInfo)
are not supported by the remote GDB server.
A few benefits of doing this in Python:
1 - The dynamic register context was already supported in the OperatingSystem plug-in
2 - Register contexts can use all of the LLDB enumerations and definitions for things
like lldb::Format, lldb::Encoding, generic register numbers, invalid registers
numbers, etc.
3 - The code that generates the register context can use the program to calculate the
register context contents (like offsets, register numbers, and more)
4 - True dynamic detection could be used where variables and types could be read from
the target program itself in order to determine which registers are available since
the target is passed into the python function.
This is designed to be used instead of XML since it is more dynamic and code flow and
functions can be used to make the dictionary.
llvm-svn: 192646
2013-10-15 00:14:28 +00:00
const char * generic_cstr = reg_info_dict . GetItemForKeyAsString ( generic_pystr ) ;
if ( generic_cstr )
reg_info . kinds [ lldb : : eRegisterKindGeneric ] = Args : : StringToGenericRegister ( generic_cstr ) ;
else
reg_info . kinds [ lldb : : eRegisterKindGeneric ] = reg_info_dict . GetItemForKeyAsInteger ( generic_pystr , LLDB_INVALID_REGNUM ) ;
<rdar://problem/14972424>
- Made the dynamic register context for the GDB remote plug-in inherit from the generic DynamicRegisterInfo to avoid code duplication
- Finished up the target definition python setting stuff.
- Added a new "slice" key/value pair that can specify that a register is part of another register:
{ 'name':'eax', 'set':0, 'bitsize':32, 'encoding':eEncodingUint, 'format':eFormatHex, 'slice': 'rax[31:0]' },
- Added a new "composite" key/value pair that can specify that a register is made up of two or more registers:
{ 'name':'d0', 'set':0, 'bitsize':64 , 'encoding':eEncodingIEEE754, 'format':eFormatFloat, 'composite': ['s1', 's0'] },
- Added a new "invalidate-regs" key/value pair for when a register is modified, it can invalidate other registers:
{ 'name':'cpsr', 'set':0, 'bitsize':32 , 'encoding':eEncodingUint, 'format':eFormatHex, 'invalidate-regs': ['r8', 'r9', 'r10', 'r11', 'r12', 'r13', 'r14', 'r15']},
This now completes the feature that allows a GDB remote target to completely describe itself.
llvm-svn: 192858
2013-10-17 01:10:23 +00:00
// Check if this register invalidates any other register values when it is modified
PythonList invalidate_reg_list ( reg_info_dict . GetItemForKey ( invalidate_regs_pystr ) ) ;
if ( invalidate_reg_list )
{
const size_t num_regs = invalidate_reg_list . GetSize ( ) ;
if ( num_regs > 0 )
{
for ( uint32_t idx = 0 ; idx < num_regs ; + + idx )
{
PythonObject invalidate_reg_object ( invalidate_reg_list . GetItemAtIndex ( idx ) ) ;
PythonString invalidate_reg_name_pystr ( invalidate_reg_object ) ;
if ( invalidate_reg_name_pystr )
{
ConstString invalidate_reg_name ( invalidate_reg_name_pystr . GetString ( ) ) ;
if ( invalidate_reg_name )
{
RegisterInfo * invalidate_reg_info = GetRegisterInfo ( invalidate_reg_name ) ;
if ( invalidate_reg_info )
{
m_invalidate_regs_map [ i ] . push_back ( invalidate_reg_info - > kinds [ eRegisterKindLLDB ] ) ;
}
else
{
// TODO: print error invalid slice string that doesn't follow the format
printf ( " error: failed to find a 'invalidate-regs' register for \" %s \" while parsing register \" %s \" \n " , invalidate_reg_name . GetCString ( ) , reg_info . name ) ;
}
}
else
{
printf ( " error: 'invalidate-regs' list value was an empty string \n " ) ;
}
}
else
{
PythonInteger invalidate_reg_num ( invalidate_reg_object ) ;
if ( invalidate_reg_num )
{
const int64_t r = invalidate_reg_num . GetInteger ( ) ;
if ( r ! = UINT64_MAX )
m_invalidate_regs_map [ i ] . push_back ( r ) ;
else
printf ( " error: 'invalidate-regs' list value wasn't a valid integer \n " ) ;
}
else
{
printf ( " error: 'invalidate-regs' list value wasn't a python string or integer \n " ) ;
}
}
}
}
else
{
printf ( " error: 'invalidate-regs' contained an empty list \n " ) ;
}
}
// Calculate the register offset
2012-08-24 02:01:39 +00:00
const size_t end_reg_offset = reg_info . byte_offset + reg_info . byte_size ;
if ( m_reg_data_byte_size < end_reg_offset )
m_reg_data_byte_size = end_reg_offset ;
m_regs . push_back ( reg_info ) ;
m_set_reg_nums [ set ] . push_back ( i ) ;
2012-08-24 01:42:50 +00:00
}
else
{
Clear ( ) ;
return 0 ;
}
}
Finalize ( ) ;
}
2012-09-11 06:35:15 +00:00
# endif
<rdar://problem/14972424>
- Made the dynamic register context for the GDB remote plug-in inherit from the generic DynamicRegisterInfo to avoid code duplication
- Finished up the target definition python setting stuff.
- Added a new "slice" key/value pair that can specify that a register is part of another register:
{ 'name':'eax', 'set':0, 'bitsize':32, 'encoding':eEncodingUint, 'format':eFormatHex, 'slice': 'rax[31:0]' },
- Added a new "composite" key/value pair that can specify that a register is made up of two or more registers:
{ 'name':'d0', 'set':0, 'bitsize':64 , 'encoding':eEncodingIEEE754, 'format':eFormatFloat, 'composite': ['s1', 's0'] },
- Added a new "invalidate-regs" key/value pair for when a register is modified, it can invalidate other registers:
{ 'name':'cpsr', 'set':0, 'bitsize':32 , 'encoding':eEncodingUint, 'format':eFormatHex, 'invalidate-regs': ['r8', 'r9', 'r10', 'r11', 'r12', 'r13', 'r14', 'r15']},
This now completes the feature that allows a GDB remote target to completely describe itself.
llvm-svn: 192858
2013-10-17 01:10:23 +00:00
return m_regs . size ( ) ;
2012-08-24 01:42:50 +00:00
}
2011-08-22 02:49:39 +00:00
void
2012-08-24 01:42:50 +00:00
DynamicRegisterInfo : : AddRegister ( RegisterInfo & reg_info ,
2011-08-22 02:49:39 +00:00
ConstString & reg_name ,
ConstString & reg_alt_name ,
ConstString & set_name )
{
<rdar://problem/14972424>
- Made the dynamic register context for the GDB remote plug-in inherit from the generic DynamicRegisterInfo to avoid code duplication
- Finished up the target definition python setting stuff.
- Added a new "slice" key/value pair that can specify that a register is part of another register:
{ 'name':'eax', 'set':0, 'bitsize':32, 'encoding':eEncodingUint, 'format':eFormatHex, 'slice': 'rax[31:0]' },
- Added a new "composite" key/value pair that can specify that a register is made up of two or more registers:
{ 'name':'d0', 'set':0, 'bitsize':64 , 'encoding':eEncodingIEEE754, 'format':eFormatFloat, 'composite': ['s1', 's0'] },
- Added a new "invalidate-regs" key/value pair for when a register is modified, it can invalidate other registers:
{ 'name':'cpsr', 'set':0, 'bitsize':32 , 'encoding':eEncodingUint, 'format':eFormatHex, 'invalidate-regs': ['r8', 'r9', 'r10', 'r11', 'r12', 'r13', 'r14', 'r15']},
This now completes the feature that allows a GDB remote target to completely describe itself.
llvm-svn: 192858
2013-10-17 01:10:23 +00:00
assert ( ! m_finalized ) ;
2011-08-22 02:49:39 +00:00
const uint32_t reg_num = m_regs . size ( ) ;
reg_info . name = reg_name . AsCString ( ) ;
assert ( reg_info . name ) ;
reg_info . alt_name = reg_alt_name . AsCString ( NULL ) ;
<rdar://problem/14972424>
- Made the dynamic register context for the GDB remote plug-in inherit from the generic DynamicRegisterInfo to avoid code duplication
- Finished up the target definition python setting stuff.
- Added a new "slice" key/value pair that can specify that a register is part of another register:
{ 'name':'eax', 'set':0, 'bitsize':32, 'encoding':eEncodingUint, 'format':eFormatHex, 'slice': 'rax[31:0]' },
- Added a new "composite" key/value pair that can specify that a register is made up of two or more registers:
{ 'name':'d0', 'set':0, 'bitsize':64 , 'encoding':eEncodingIEEE754, 'format':eFormatFloat, 'composite': ['s1', 's0'] },
- Added a new "invalidate-regs" key/value pair for when a register is modified, it can invalidate other registers:
{ 'name':'cpsr', 'set':0, 'bitsize':32 , 'encoding':eEncodingUint, 'format':eFormatHex, 'invalidate-regs': ['r8', 'r9', 'r10', 'r11', 'r12', 'r13', 'r14', 'r15']},
This now completes the feature that allows a GDB remote target to completely describe itself.
llvm-svn: 192858
2013-10-17 01:10:23 +00:00
uint32_t i ;
if ( reg_info . value_regs )
{
for ( i = 0 ; reg_info . value_regs [ i ] ! = LLDB_INVALID_REGNUM ; + + i )
m_value_regs_map [ reg_num ] . push_back ( reg_info . value_regs [ i ] ) ;
}
if ( reg_info . invalidate_regs )
{
for ( i = 0 ; reg_info . invalidate_regs [ i ] ! = LLDB_INVALID_REGNUM ; + + i )
m_invalidate_regs_map [ reg_num ] . push_back ( reg_info . invalidate_regs [ i ] ) ;
}
2011-08-22 02:49:39 +00:00
m_regs . push_back ( reg_info ) ;
uint32_t set = GetRegisterSetIndexByName ( set_name , true ) ;
assert ( set < m_sets . size ( ) ) ;
assert ( set < m_set_reg_nums . size ( ) ) ;
assert ( set < m_set_names . size ( ) ) ;
m_set_reg_nums [ set ] . push_back ( reg_num ) ;
size_t end_reg_offset = reg_info . byte_offset + reg_info . byte_size ;
if ( m_reg_data_byte_size < end_reg_offset )
m_reg_data_byte_size = end_reg_offset ;
}
void
DynamicRegisterInfo : : Finalize ( )
{
<rdar://problem/14972424>
- Made the dynamic register context for the GDB remote plug-in inherit from the generic DynamicRegisterInfo to avoid code duplication
- Finished up the target definition python setting stuff.
- Added a new "slice" key/value pair that can specify that a register is part of another register:
{ 'name':'eax', 'set':0, 'bitsize':32, 'encoding':eEncodingUint, 'format':eFormatHex, 'slice': 'rax[31:0]' },
- Added a new "composite" key/value pair that can specify that a register is made up of two or more registers:
{ 'name':'d0', 'set':0, 'bitsize':64 , 'encoding':eEncodingIEEE754, 'format':eFormatFloat, 'composite': ['s1', 's0'] },
- Added a new "invalidate-regs" key/value pair for when a register is modified, it can invalidate other registers:
{ 'name':'cpsr', 'set':0, 'bitsize':32 , 'encoding':eEncodingUint, 'format':eFormatHex, 'invalidate-regs': ['r8', 'r9', 'r10', 'r11', 'r12', 'r13', 'r14', 'r15']},
This now completes the feature that allows a GDB remote target to completely describe itself.
llvm-svn: 192858
2013-10-17 01:10:23 +00:00
if ( m_finalized )
return ;
m_finalized = true ;
const size_t num_sets = m_sets . size ( ) ;
for ( size_t set = 0 ; set < num_sets ; + + set )
2011-08-22 02:49:39 +00:00
{
assert ( m_sets . size ( ) = = m_set_reg_nums . size ( ) ) ;
m_sets [ set ] . num_registers = m_set_reg_nums [ set ] . size ( ) ;
m_sets [ set ] . registers = & m_set_reg_nums [ set ] [ 0 ] ;
}
<rdar://problem/14972424>
- Made the dynamic register context for the GDB remote plug-in inherit from the generic DynamicRegisterInfo to avoid code duplication
- Finished up the target definition python setting stuff.
- Added a new "slice" key/value pair that can specify that a register is part of another register:
{ 'name':'eax', 'set':0, 'bitsize':32, 'encoding':eEncodingUint, 'format':eFormatHex, 'slice': 'rax[31:0]' },
- Added a new "composite" key/value pair that can specify that a register is made up of two or more registers:
{ 'name':'d0', 'set':0, 'bitsize':64 , 'encoding':eEncodingIEEE754, 'format':eFormatFloat, 'composite': ['s1', 's0'] },
- Added a new "invalidate-regs" key/value pair for when a register is modified, it can invalidate other registers:
{ 'name':'cpsr', 'set':0, 'bitsize':32 , 'encoding':eEncodingUint, 'format':eFormatHex, 'invalidate-regs': ['r8', 'r9', 'r10', 'r11', 'r12', 'r13', 'r14', 'r15']},
This now completes the feature that allows a GDB remote target to completely describe itself.
llvm-svn: 192858
2013-10-17 01:10:23 +00:00
// sort and unique all value registers and make sure each is terminated with
// LLDB_INVALID_REGNUM
for ( reg_to_regs_map : : iterator pos = m_value_regs_map . begin ( ) , end = m_value_regs_map . end ( ) ;
pos ! = end ;
+ + pos )
{
if ( pos - > second . size ( ) > 1 )
{
std : : sort ( pos - > second . begin ( ) , pos - > second . end ( ) ) ;
reg_num_collection : : iterator unique_end = std : : unique ( pos - > second . begin ( ) , pos - > second . end ( ) ) ;
if ( unique_end ! = pos - > second . end ( ) )
pos - > second . erase ( unique_end , pos - > second . end ( ) ) ;
}
assert ( ! pos - > second . empty ( ) ) ;
if ( pos - > second . back ( ) ! = LLDB_INVALID_REGNUM )
pos - > second . push_back ( LLDB_INVALID_REGNUM ) ;
}
// Now update all value_regs with each register info as needed
const size_t num_regs = m_regs . size ( ) ;
for ( size_t i = 0 ; i < num_regs ; + + i )
{
if ( m_value_regs_map . find ( i ) ! = m_value_regs_map . end ( ) )
m_regs [ i ] . value_regs = m_value_regs_map [ i ] . data ( ) ;
else
m_regs [ i ] . value_regs = NULL ;
}
// Expand all invalidation dependencies
for ( reg_to_regs_map : : iterator pos = m_invalidate_regs_map . begin ( ) , end = m_invalidate_regs_map . end ( ) ;
pos ! = end ;
+ + pos )
{
const uint32_t reg_num = pos - > first ;
if ( m_regs [ reg_num ] . value_regs )
{
reg_num_collection extra_invalid_regs ;
for ( const uint32_t invalidate_reg_num : pos - > second )
{
reg_to_regs_map : : iterator invalidate_pos = m_invalidate_regs_map . find ( invalidate_reg_num ) ;
if ( invalidate_pos ! = m_invalidate_regs_map . end ( ) )
{
for ( const uint32_t concrete_invalidate_reg_num : invalidate_pos - > second )
{
if ( concrete_invalidate_reg_num ! = reg_num )
extra_invalid_regs . push_back ( concrete_invalidate_reg_num ) ;
}
}
}
pos - > second . insert ( pos - > second . end ( ) , extra_invalid_regs . begin ( ) , extra_invalid_regs . end ( ) ) ;
}
}
// sort and unique all invalidate registers and make sure each is terminated with
// LLDB_INVALID_REGNUM
for ( reg_to_regs_map : : iterator pos = m_invalidate_regs_map . begin ( ) , end = m_invalidate_regs_map . end ( ) ;
pos ! = end ;
+ + pos )
{
if ( pos - > second . size ( ) > 1 )
{
std : : sort ( pos - > second . begin ( ) , pos - > second . end ( ) ) ;
reg_num_collection : : iterator unique_end = std : : unique ( pos - > second . begin ( ) , pos - > second . end ( ) ) ;
if ( unique_end ! = pos - > second . end ( ) )
pos - > second . erase ( unique_end , pos - > second . end ( ) ) ;
}
assert ( ! pos - > second . empty ( ) ) ;
if ( pos - > second . back ( ) ! = LLDB_INVALID_REGNUM )
pos - > second . push_back ( LLDB_INVALID_REGNUM ) ;
}
// Now update all invalidate_regs with each register info as needed
for ( size_t i = 0 ; i < num_regs ; + + i )
{
if ( m_invalidate_regs_map . find ( i ) ! = m_invalidate_regs_map . end ( ) )
m_regs [ i ] . invalidate_regs = m_invalidate_regs_map [ i ] . data ( ) ;
else
m_regs [ i ] . invalidate_regs = NULL ;
}
2011-08-22 02:49:39 +00:00
}
size_t
DynamicRegisterInfo : : GetNumRegisters ( ) const
{
return m_regs . size ( ) ;
}
size_t
DynamicRegisterInfo : : GetNumRegisterSets ( ) const
{
return m_sets . size ( ) ;
}
size_t
DynamicRegisterInfo : : GetRegisterDataByteSize ( ) const
{
return m_reg_data_byte_size ;
}
const RegisterInfo *
DynamicRegisterInfo : : GetRegisterInfoAtIndex ( uint32_t i ) const
{
if ( i < m_regs . size ( ) )
return & m_regs [ i ] ;
return NULL ;
}
const RegisterSet *
DynamicRegisterInfo : : GetRegisterSet ( uint32_t i ) const
{
if ( i < m_sets . size ( ) )
return & m_sets [ i ] ;
return NULL ;
}
uint32_t
DynamicRegisterInfo : : GetRegisterSetIndexByName ( ConstString & set_name , bool can_create )
{
name_collection : : iterator pos , end = m_set_names . end ( ) ;
for ( pos = m_set_names . begin ( ) ; pos ! = end ; + + pos )
{
if ( * pos = = set_name )
return std : : distance ( m_set_names . begin ( ) , pos ) ;
}
m_set_names . push_back ( set_name ) ;
m_set_reg_nums . resize ( m_set_reg_nums . size ( ) + 1 ) ;
RegisterSet new_set = { set_name . AsCString ( ) , NULL , 0 , NULL } ;
m_sets . push_back ( new_set ) ;
return m_sets . size ( ) - 1 ;
}
uint32_t
DynamicRegisterInfo : : ConvertRegisterKindToRegisterNumber ( uint32_t kind , uint32_t num ) const
{
reg_collection : : const_iterator pos , end = m_regs . end ( ) ;
for ( pos = m_regs . begin ( ) ; pos ! = end ; + + pos )
{
if ( pos - > kinds [ kind ] = = num )
return std : : distance ( m_regs . begin ( ) , pos ) ;
}
return LLDB_INVALID_REGNUM ;
}
void
DynamicRegisterInfo : : Clear ( )
{
m_regs . clear ( ) ;
m_sets . clear ( ) ;
m_set_reg_nums . clear ( ) ;
m_set_names . clear ( ) ;
<rdar://problem/14972424>
- Made the dynamic register context for the GDB remote plug-in inherit from the generic DynamicRegisterInfo to avoid code duplication
- Finished up the target definition python setting stuff.
- Added a new "slice" key/value pair that can specify that a register is part of another register:
{ 'name':'eax', 'set':0, 'bitsize':32, 'encoding':eEncodingUint, 'format':eFormatHex, 'slice': 'rax[31:0]' },
- Added a new "composite" key/value pair that can specify that a register is made up of two or more registers:
{ 'name':'d0', 'set':0, 'bitsize':64 , 'encoding':eEncodingIEEE754, 'format':eFormatFloat, 'composite': ['s1', 's0'] },
- Added a new "invalidate-regs" key/value pair for when a register is modified, it can invalidate other registers:
{ 'name':'cpsr', 'set':0, 'bitsize':32 , 'encoding':eEncodingUint, 'format':eFormatHex, 'invalidate-regs': ['r8', 'r9', 'r10', 'r11', 'r12', 'r13', 'r14', 'r15']},
This now completes the feature that allows a GDB remote target to completely describe itself.
llvm-svn: 192858
2013-10-17 01:10:23 +00:00
m_value_regs_map . clear ( ) ;
m_invalidate_regs_map . clear ( ) ;
m_reg_data_byte_size = 0 ;
m_finalized = false ;
}
void
DynamicRegisterInfo : : Dump ( ) const
{
StreamFile s ( stdout , false ) ;
const size_t num_regs = m_regs . size ( ) ;
2014-03-03 15:39:47 +00:00
s . Printf ( " %p: DynamicRegisterInfo contains % " PRIu64 " registers: \n " , this , ( uint64_t ) num_regs ) ;
<rdar://problem/14972424>
- Made the dynamic register context for the GDB remote plug-in inherit from the generic DynamicRegisterInfo to avoid code duplication
- Finished up the target definition python setting stuff.
- Added a new "slice" key/value pair that can specify that a register is part of another register:
{ 'name':'eax', 'set':0, 'bitsize':32, 'encoding':eEncodingUint, 'format':eFormatHex, 'slice': 'rax[31:0]' },
- Added a new "composite" key/value pair that can specify that a register is made up of two or more registers:
{ 'name':'d0', 'set':0, 'bitsize':64 , 'encoding':eEncodingIEEE754, 'format':eFormatFloat, 'composite': ['s1', 's0'] },
- Added a new "invalidate-regs" key/value pair for when a register is modified, it can invalidate other registers:
{ 'name':'cpsr', 'set':0, 'bitsize':32 , 'encoding':eEncodingUint, 'format':eFormatHex, 'invalidate-regs': ['r8', 'r9', 'r10', 'r11', 'r12', 'r13', 'r14', 'r15']},
This now completes the feature that allows a GDB remote target to completely describe itself.
llvm-svn: 192858
2013-10-17 01:10:23 +00:00
for ( size_t i = 0 ; i < num_regs ; + + i )
{
2014-03-03 15:39:47 +00:00
s . Printf ( " [%3 " PRId64 " ] name = %-10s " , i , m_regs [ i ] . name ) ;
<rdar://problem/14972424>
- Made the dynamic register context for the GDB remote plug-in inherit from the generic DynamicRegisterInfo to avoid code duplication
- Finished up the target definition python setting stuff.
- Added a new "slice" key/value pair that can specify that a register is part of another register:
{ 'name':'eax', 'set':0, 'bitsize':32, 'encoding':eEncodingUint, 'format':eFormatHex, 'slice': 'rax[31:0]' },
- Added a new "composite" key/value pair that can specify that a register is made up of two or more registers:
{ 'name':'d0', 'set':0, 'bitsize':64 , 'encoding':eEncodingIEEE754, 'format':eFormatFloat, 'composite': ['s1', 's0'] },
- Added a new "invalidate-regs" key/value pair for when a register is modified, it can invalidate other registers:
{ 'name':'cpsr', 'set':0, 'bitsize':32 , 'encoding':eEncodingUint, 'format':eFormatHex, 'invalidate-regs': ['r8', 'r9', 'r10', 'r11', 'r12', 'r13', 'r14', 'r15']},
This now completes the feature that allows a GDB remote target to completely describe itself.
llvm-svn: 192858
2013-10-17 01:10:23 +00:00
s . Printf ( " , size = %2u, offset = %4u, encoding = %u, format = %-10s " ,
m_regs [ i ] . byte_size ,
m_regs [ i ] . byte_offset ,
m_regs [ i ] . encoding ,
FormatManager : : GetFormatAsCString ( m_regs [ i ] . format ) ) ;
if ( m_regs [ i ] . kinds [ eRegisterKindGDB ] ! = LLDB_INVALID_REGNUM )
s . Printf ( " , gdb = %3u " , m_regs [ i ] . kinds [ eRegisterKindGDB ] ) ;
if ( m_regs [ i ] . kinds [ eRegisterKindDWARF ] ! = LLDB_INVALID_REGNUM )
s . Printf ( " , dwarf = %3u " , m_regs [ i ] . kinds [ eRegisterKindDWARF ] ) ;
if ( m_regs [ i ] . kinds [ eRegisterKindGCC ] ! = LLDB_INVALID_REGNUM )
s . Printf ( " , gcc = %3u " , m_regs [ i ] . kinds [ eRegisterKindGCC ] ) ;
if ( m_regs [ i ] . kinds [ eRegisterKindGeneric ] ! = LLDB_INVALID_REGNUM )
s . Printf ( " , generic = %3u " , m_regs [ i ] . kinds [ eRegisterKindGeneric ] ) ;
if ( m_regs [ i ] . alt_name )
s . Printf ( " , alt-name = %s " , m_regs [ i ] . alt_name ) ;
if ( m_regs [ i ] . value_regs )
{
s . Printf ( " , value_regs = [ " ) ;
for ( size_t j = 0 ; m_regs [ i ] . value_regs [ j ] ! = LLDB_INVALID_REGNUM ; + + j )
{
s . Printf ( " %s " , m_regs [ m_regs [ i ] . value_regs [ j ] ] . name ) ;
}
s . Printf ( " ] " ) ;
}
if ( m_regs [ i ] . invalidate_regs )
{
s . Printf ( " , invalidate_regs = [ " ) ;
for ( size_t j = 0 ; m_regs [ i ] . invalidate_regs [ j ] ! = LLDB_INVALID_REGNUM ; + + j )
{
s . Printf ( " %s " , m_regs [ m_regs [ i ] . invalidate_regs [ j ] ] . name ) ;
}
s . Printf ( " ] " ) ;
}
s . EOL ( ) ;
}
const size_t num_sets = m_sets . size ( ) ;
2014-03-03 15:39:47 +00:00
s . Printf ( " %p: DynamicRegisterInfo contains % " PRIu64 " register sets: \n " , this , ( uint64_t ) num_sets ) ;
<rdar://problem/14972424>
- Made the dynamic register context for the GDB remote plug-in inherit from the generic DynamicRegisterInfo to avoid code duplication
- Finished up the target definition python setting stuff.
- Added a new "slice" key/value pair that can specify that a register is part of another register:
{ 'name':'eax', 'set':0, 'bitsize':32, 'encoding':eEncodingUint, 'format':eFormatHex, 'slice': 'rax[31:0]' },
- Added a new "composite" key/value pair that can specify that a register is made up of two or more registers:
{ 'name':'d0', 'set':0, 'bitsize':64 , 'encoding':eEncodingIEEE754, 'format':eFormatFloat, 'composite': ['s1', 's0'] },
- Added a new "invalidate-regs" key/value pair for when a register is modified, it can invalidate other registers:
{ 'name':'cpsr', 'set':0, 'bitsize':32 , 'encoding':eEncodingUint, 'format':eFormatHex, 'invalidate-regs': ['r8', 'r9', 'r10', 'r11', 'r12', 'r13', 'r14', 'r15']},
This now completes the feature that allows a GDB remote target to completely describe itself.
llvm-svn: 192858
2013-10-17 01:10:23 +00:00
for ( size_t i = 0 ; i < num_sets ; + + i )
{
2014-03-03 15:39:47 +00:00
s . Printf ( " set[% " PRIu64 " ] name = %s, regs = [ " , ( uint64_t ) i , m_sets [ i ] . name ) ;
<rdar://problem/14972424>
- Made the dynamic register context for the GDB remote plug-in inherit from the generic DynamicRegisterInfo to avoid code duplication
- Finished up the target definition python setting stuff.
- Added a new "slice" key/value pair that can specify that a register is part of another register:
{ 'name':'eax', 'set':0, 'bitsize':32, 'encoding':eEncodingUint, 'format':eFormatHex, 'slice': 'rax[31:0]' },
- Added a new "composite" key/value pair that can specify that a register is made up of two or more registers:
{ 'name':'d0', 'set':0, 'bitsize':64 , 'encoding':eEncodingIEEE754, 'format':eFormatFloat, 'composite': ['s1', 's0'] },
- Added a new "invalidate-regs" key/value pair for when a register is modified, it can invalidate other registers:
{ 'name':'cpsr', 'set':0, 'bitsize':32 , 'encoding':eEncodingUint, 'format':eFormatHex, 'invalidate-regs': ['r8', 'r9', 'r10', 'r11', 'r12', 'r13', 'r14', 'r15']},
This now completes the feature that allows a GDB remote target to completely describe itself.
llvm-svn: 192858
2013-10-17 01:10:23 +00:00
for ( size_t idx = 0 ; idx < m_sets [ i ] . num_registers ; + + idx )
{
s . Printf ( " %s " , m_regs [ m_sets [ i ] . registers [ idx ] ] . name ) ;
}
s . Printf ( " ] \n " ) ;
}
}
lldb_private : : RegisterInfo *
DynamicRegisterInfo : : GetRegisterInfo ( const lldb_private : : ConstString & reg_name )
{
for ( auto & reg_info : m_regs )
{
// We can use pointer comparison since we used a ConstString to set
// the "name" member in AddRegister()
if ( reg_info . name = = reg_name . GetCString ( ) )
{
return & reg_info ;
}
}
return NULL ;
2011-08-22 02:49:39 +00:00
}