<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
This commit is contained in:
Greg Clayton
2013-10-15 00:14:28 +00:00
parent 059e05eeef
commit ef8180a3f6
11 changed files with 566 additions and 70 deletions

View File

@@ -62,7 +62,7 @@ static ScriptInterpreter::SWIGPythonScriptKeyword_Process g_swig_run_script_keyw
static ScriptInterpreter::SWIGPythonScriptKeyword_Thread g_swig_run_script_keyword_thread = NULL;
static ScriptInterpreter::SWIGPythonScriptKeyword_Target g_swig_run_script_keyword_target = NULL;
static ScriptInterpreter::SWIGPythonScriptKeyword_Frame g_swig_run_script_keyword_frame = NULL;
static ScriptInterpreter::SWIGPythonGDBPlugin_GetDynamicSetting g_swig_gdbremote_plugin_get = NULL;
static ScriptInterpreter::SWIGPython_GetDynamicSetting g_swig_plugin_get = NULL;
// these are the Pythonic implementations of the required callbacks
// these are scripting-language specific, which is why they belong here
@@ -157,9 +157,9 @@ LLDBSWIGPythonRunScriptKeywordFrame (const char* python_function_name,
std::string& output);
extern "C" void*
LLDBSWIGPython_GDBPluginGetDynamicSetting (void* module,
const char* setting,
const lldb::TargetSP& target_sp);
LLDBSWIGPython_GetDynamicSetting (void* module,
const char* setting,
const lldb::TargetSP& target_sp);
static int
_check_and_flush (FILE *stream)
@@ -2081,8 +2081,8 @@ ScriptInterpreterPython::OSPlugin_CreateThread (lldb::ScriptInterpreterObjectSP
}
lldb::ScriptInterpreterObjectSP
ScriptInterpreterPython::GDBRemotePlugin_LoadPluginModule (const FileSpec& file_spec,
lldb_private::Error& error)
ScriptInterpreterPython::LoadPluginModule (const FileSpec& file_spec,
lldb_private::Error& error)
{
if (!file_spec.Exists())
{
@@ -2099,15 +2099,15 @@ ScriptInterpreterPython::GDBRemotePlugin_LoadPluginModule (const FileSpec& file_
}
lldb::ScriptInterpreterObjectSP
ScriptInterpreterPython::GDBRemotePlugin_GetDynamicSettings (lldb::ScriptInterpreterObjectSP gdbremote_plugin_module_sp,
Target* target,
const char* setting_name,
lldb_private::Error& error)
ScriptInterpreterPython::GetDynamicSettings (lldb::ScriptInterpreterObjectSP plugin_module_sp,
Target* target,
const char* setting_name,
lldb_private::Error& error)
{
if (!gdbremote_plugin_module_sp || !target || !setting_name || !setting_name[0])
if (!plugin_module_sp || !target || !setting_name || !setting_name[0])
return lldb::ScriptInterpreterObjectSP();
if (!g_swig_gdbremote_plugin_get)
if (!g_swig_plugin_get)
return lldb::ScriptInterpreterObjectSP();
PyObject *reply_pyobj = nullptr;
@@ -2115,7 +2115,7 @@ ScriptInterpreterPython::GDBRemotePlugin_GetDynamicSettings (lldb::ScriptInterpr
{
Locker py_lock(this);
TargetSP target_sp(target->shared_from_this());
reply_pyobj = (PyObject*)g_swig_gdbremote_plugin_get(gdbremote_plugin_module_sp->GetObject(),setting_name,target_sp);
reply_pyobj = (PyObject*)g_swig_plugin_get(plugin_module_sp->GetObject(),setting_name,target_sp);
}
return MakeScriptObject(reply_pyobj);
@@ -3136,7 +3136,7 @@ ScriptInterpreterPython::InitializeInterpreter (SWIGInitCallback python_swig_ini
g_swig_run_script_keyword_thread = LLDBSWIGPythonRunScriptKeywordThread;
g_swig_run_script_keyword_target = LLDBSWIGPythonRunScriptKeywordTarget;
g_swig_run_script_keyword_frame = LLDBSWIGPythonRunScriptKeywordFrame;
g_swig_gdbremote_plugin_get = LLDBSWIGPython_GDBPluginGetDynamicSetting;
g_swig_plugin_get = LLDBSWIGPython_GetDynamicSetting;
}
void