<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

@ -0,0 +1,298 @@
#!/usr/bin/python
#===-- x86_64_target_definition.py -----------------------------*- C++ -*-===//
#
# The LLVM Compiler Infrastructure
#
# This file is distributed under the University of Illinois Open Source
# License. See LICENSE.TXT for details.
#
#===----------------------------------------------------------------------===//
#----------------------------------------------------------------------
# DESCRIPTION
#
# This file can be used with the following setting:
# plugin.process.gdb-remote.target-definition-file
# This setting should be used when you are trying to connect to a
# remote GDB server that doesn't support any of the register discovery
# packets that LLDB normally uses.
#
# Why is this necessary? LLDB doesn't require a new build of LLDB that
# targets each new architecture you will debug with. Instead, all
# architectures are supported and LLDB relies on extra GDB server
# packets to discover the target we are connecting to so that is can
# show the right registers for each target. This allows the GDB server
# to change and add new registers without requiring a new LLDB build
# just so we can see new registers.
#
# This file implements the x86_64 registers for the darwin version of
# GDB and allows you to connect to servers that use this register set.
#
# USAGE
#
# (lldb) settings set plugin.process.gdb-remote.target-definition-file /path/to/x86_64_target_definition.py
# (lldb) gdb-remote other.baz.com:1234
#
# The target definition file will get used if and only if the
# qRegisterInfo packets are not supported when connecting to a remote
# GDB server.
#----------------------------------------------------------------------
from lldb import *
# Compiler and DWARF register numbers
name_to_gcc_dwarf_regnum = {
'rax' : 0 ,
'rdx' : 1 ,
'rcx' : 2 ,
'rbx' : 3 ,
'rsi' : 4 ,
'rdi' : 5 ,
'rbp' : 6 ,
'rsp' : 7 ,
'r8' : 8 ,
'r9' : 9 ,
'r10' : 10,
'r11' : 11,
'r12' : 12,
'r13' : 13,
'r14' : 14,
'r15' : 15,
'rip' : 16,
'xmm0' : 17,
'xmm1' : 18,
'xmm2' : 19,
'xmm3' : 20,
'xmm4' : 21,
'xmm5' : 22,
'xmm6' : 23,
'xmm7' : 24,
'xmm8' : 25,
'xmm9' : 26,
'xmm10' : 27,
'xmm11' : 28,
'xmm12' : 29,
'xmm13' : 30,
'xmm14' : 31,
'xmm15' : 32,
'stmm0' : 33,
'stmm1' : 34,
'stmm2' : 35,
'stmm3' : 36,
'stmm4' : 37,
'stmm5' : 38,
'stmm6' : 39,
'stmm7' : 30,
'ymm0' : 41,
'ymm1' : 42,
'ymm2' : 43,
'ymm3' : 44,
'ymm4' : 45,
'ymm5' : 46,
'ymm6' : 47,
'ymm7' : 48,
'ymm8' : 49,
'ymm9' : 40,
'ymm10' : 41,
'ymm11' : 42,
'ymm12' : 43,
'ymm13' : 44,
'ymm14' : 45,
'ymm15' : 46
};
name_to_gdb_regnum = {
'rax' : 0,
'rbx' : 1,
'rcx' : 2,
'rdx' : 3,
'rsi' : 4,
'rdi' : 5,
'rbp' : 6,
'rsp' : 7,
'r8' : 8,
'r9' : 9,
'r10' : 10,
'r11' : 11,
'r12' : 12,
'r13' : 13,
'r14' : 14,
'r15' : 15,
'rip' : 16,
'rflags': 17,
'cs' : 18,
'ss' : 19,
'ds' : 20,
'es' : 21,
'fs' : 22,
'gs' : 23,
'stmm0' : 24,
'stmm1' : 25,
'stmm2' : 26,
'stmm3' : 27,
'stmm4' : 28,
'stmm5' : 29,
'stmm6' : 30,
'stmm7' : 31,
'fctrl' : 32,
'fstat' : 33,
'ftag' : 34,
'fiseg' : 35,
'fioff' : 36,
'foseg' : 37,
'fooff' : 38,
'fop' : 39,
'xmm0' : 40,
'xmm1' : 41,
'xmm2' : 42,
'xmm3' : 43,
'xmm4' : 44,
'xmm5' : 45,
'xmm6' : 46,
'xmm7' : 47,
'xmm8' : 48,
'xmm9' : 49,
'xmm10' : 50,
'xmm11' : 51,
'xmm12' : 52,
'xmm13' : 53,
'xmm14' : 54,
'xmm15' : 55,
'mxcsr' : 56,
'ymm0' : 57,
'ymm1' : 58,
'ymm2' : 59,
'ymm3' : 60,
'ymm4' : 61,
'ymm5' : 62,
'ymm6' : 63,
'ymm7' : 64,
'ymm8' : 65,
'ymm9' : 66,
'ymm10' : 67,
'ymm11' : 68,
'ymm12' : 69,
'ymm13' : 70,
'ymm14' : 71,
'ymm15' : 72
};
name_to_generic_regnum = {
'rip' : LLDB_REGNUM_GENERIC_PC,
'rsp' : LLDB_REGNUM_GENERIC_SP,
'rbp' : LLDB_REGNUM_GENERIC_FP,
'rdi' : LLDB_REGNUM_GENERIC_ARG1,
'rsi' : LLDB_REGNUM_GENERIC_ARG2,
'rdx' : LLDB_REGNUM_GENERIC_ARG3,
'rcx' : LLDB_REGNUM_GENERIC_ARG4,
'r8' : LLDB_REGNUM_GENERIC_ARG5,
'r9' : LLDB_REGNUM_GENERIC_ARG6
};
def get_reg_num (reg_num_dict, reg_name):
if reg_name in reg_num_dict:
return reg_num_dict[reg_name]
return LLDB_INVALID_REGNUM
def get_reg_num (reg_num_dict, reg_name):
if reg_name in reg_num_dict:
return reg_num_dict[reg_name]
return LLDB_INVALID_REGNUM
x86_64_register_infos = [
{ 'name':'rax' , 'set':0, 'bitsize':64 , 'encoding':eEncodingUint , 'format':eFormatAddressInfo },
{ 'name':'rbx' , 'set':0, 'bitsize':64 , 'encoding':eEncodingUint , 'format':eFormatAddressInfo },
{ 'name':'rcx' , 'alt-name':'arg4' , 'set':0, 'bitsize':64 , 'encoding':eEncodingUint , 'format':eFormatAddressInfo },
{ 'name':'rdx' , 'alt-name':'arg3' , 'set':0, 'bitsize':64 , 'encoding':eEncodingUint , 'format':eFormatAddressInfo },
{ 'name':'rsi' , 'alt-name':'arg2' , 'set':0, 'bitsize':64 , 'encoding':eEncodingUint , 'format':eFormatAddressInfo },
{ 'name':'rdi' , 'alt-name':'arg1' , 'set':0, 'bitsize':64 , 'encoding':eEncodingUint , 'format':eFormatAddressInfo },
{ 'name':'rbp' , 'alt-name':'fp' , 'set':0, 'bitsize':64 , 'encoding':eEncodingUint , 'format':eFormatAddressInfo },
{ 'name':'rsp' , 'alt-name':'sp' , 'set':0, 'bitsize':64 , 'encoding':eEncodingUint , 'format':eFormatAddressInfo },
{ 'name':'r8' , 'alt-name':'arg5' , 'set':0, 'bitsize':64 , 'encoding':eEncodingUint , 'format':eFormatAddressInfo },
{ 'name':'r9' , 'alt-name':'arg6' , 'set':0, 'bitsize':64 , 'encoding':eEncodingUint , 'format':eFormatAddressInfo },
{ 'name':'r10' , 'set':0, 'bitsize':64 , 'encoding':eEncodingUint , 'format':eFormatAddressInfo },
{ 'name':'r11' , 'set':0, 'bitsize':64 , 'encoding':eEncodingUint , 'format':eFormatAddressInfo },
{ 'name':'r12' , 'set':0, 'bitsize':64 , 'encoding':eEncodingUint , 'format':eFormatAddressInfo },
{ 'name':'r13' , 'set':0, 'bitsize':64 , 'encoding':eEncodingUint , 'format':eFormatAddressInfo },
{ 'name':'r14' , 'set':0, 'bitsize':64 , 'encoding':eEncodingUint , 'format':eFormatAddressInfo },
{ 'name':'r15' , 'set':0, 'bitsize':64 , 'encoding':eEncodingUint , 'format':eFormatAddressInfo },
{ 'name':'rip' , 'alt-name':'pc' , 'set':0, 'bitsize':64 , 'encoding':eEncodingUint , 'format':eFormatAddressInfo },
{ 'name':'rflags', 'set':0, 'bitsize':32 , 'encoding':eEncodingUint , 'format':eFormatHex },
{ 'name':'cs' , 'set':0, 'bitsize':32 , 'encoding':eEncodingUint , 'format':eFormatHex },
{ 'name':'ss' , 'set':0, 'bitsize':32 , 'encoding':eEncodingUint , 'format':eFormatHex },
{ 'name':'ds' , 'set':0, 'bitsize':32 , 'encoding':eEncodingUint , 'format':eFormatHex },
{ 'name':'es' , 'set':0, 'bitsize':32 , 'encoding':eEncodingUint , 'format':eFormatHex },
{ 'name':'fs' , 'set':0, 'bitsize':32 , 'encoding':eEncodingUint , 'format':eFormatHex },
{ 'name':'gs' , 'set':0, 'bitsize':32 , 'encoding':eEncodingUint , 'format':eFormatHex },
{ 'name':'stmm0' , 'set':1, 'bitsize':80 , 'encoding':eEncodingVector, 'format':eFormatVectorOfUInt8 },
{ 'name':'stmm1' , 'set':1, 'bitsize':80 , 'encoding':eEncodingVector, 'format':eFormatVectorOfUInt8 },
{ 'name':'stmm2' , 'set':1, 'bitsize':80 , 'encoding':eEncodingVector, 'format':eFormatVectorOfUInt8 },
{ 'name':'stmm3' , 'set':1, 'bitsize':80 , 'encoding':eEncodingVector, 'format':eFormatVectorOfUInt8 },
{ 'name':'stmm4' , 'set':1, 'bitsize':80 , 'encoding':eEncodingVector, 'format':eFormatVectorOfUInt8 },
{ 'name':'stmm5' , 'set':1, 'bitsize':80 , 'encoding':eEncodingVector, 'format':eFormatVectorOfUInt8 },
{ 'name':'stmm6' , 'set':1, 'bitsize':80 , 'encoding':eEncodingVector, 'format':eFormatVectorOfUInt8 },
{ 'name':'stmm7' , 'set':1, 'bitsize':80 , 'encoding':eEncodingVector, 'format':eFormatVectorOfUInt8 },
{ 'name':'fctrl' , 'set':1, 'bitsize':32 , 'encoding':eEncodingUint , 'format':eFormatHex },
{ 'name':'fstat' , 'set':1, 'bitsize':32 , 'encoding':eEncodingUint , 'format':eFormatHex },
{ 'name':'ftag' , 'set':1, 'bitsize':32 , 'encoding':eEncodingUint , 'format':eFormatHex },
{ 'name':'fiseg' , 'set':1, 'bitsize':32 , 'encoding':eEncodingUint , 'format':eFormatHex },
{ 'name':'fioff' , 'set':1, 'bitsize':32 , 'encoding':eEncodingUint , 'format':eFormatHex },
{ 'name':'foseg' , 'set':1, 'bitsize':32 , 'encoding':eEncodingUint , 'format':eFormatHex },
{ 'name':'fooff' , 'set':1, 'bitsize':32 , 'encoding':eEncodingUint , 'format':eFormatHex },
{ 'name':'fop' , 'set':1, 'bitsize':32 , 'encoding':eEncodingUint , 'format':eFormatHex },
{ 'name':'xmm0' , 'set':1, 'bitsize':128, 'encoding':eEncodingVector, 'format':eFormatVectorOfUInt8 },
{ 'name':'xmm1' , 'set':1, 'bitsize':128, 'encoding':eEncodingVector, 'format':eFormatVectorOfUInt8 },
{ 'name':'xmm2' , 'set':1, 'bitsize':128, 'encoding':eEncodingVector, 'format':eFormatVectorOfUInt8 },
{ 'name':'xmm3' , 'set':1, 'bitsize':128, 'encoding':eEncodingVector, 'format':eFormatVectorOfUInt8 },
{ 'name':'xmm4' , 'set':1, 'bitsize':128, 'encoding':eEncodingVector, 'format':eFormatVectorOfUInt8 },
{ 'name':'xmm5' , 'set':1, 'bitsize':128, 'encoding':eEncodingVector, 'format':eFormatVectorOfUInt8 },
{ 'name':'xmm6' , 'set':1, 'bitsize':128, 'encoding':eEncodingVector, 'format':eFormatVectorOfUInt8 },
{ 'name':'xmm7' , 'set':1, 'bitsize':128, 'encoding':eEncodingVector, 'format':eFormatVectorOfUInt8 },
{ 'name':'xmm8' , 'set':1, 'bitsize':128, 'encoding':eEncodingVector, 'format':eFormatVectorOfUInt8 },
{ 'name':'xmm9' , 'set':1, 'bitsize':128, 'encoding':eEncodingVector, 'format':eFormatVectorOfUInt8 },
{ 'name':'xmm10' , 'set':1, 'bitsize':128, 'encoding':eEncodingVector, 'format':eFormatVectorOfUInt8 },
{ 'name':'xmm11' , 'set':1, 'bitsize':128, 'encoding':eEncodingVector, 'format':eFormatVectorOfUInt8 },
{ 'name':'xmm12' , 'set':1, 'bitsize':128, 'encoding':eEncodingVector, 'format':eFormatVectorOfUInt8 },
{ 'name':'xmm13' , 'set':1, 'bitsize':128, 'encoding':eEncodingVector, 'format':eFormatVectorOfUInt8 },
{ 'name':'xmm14' , 'set':1, 'bitsize':128, 'encoding':eEncodingVector, 'format':eFormatVectorOfUInt8 },
{ 'name':'xmm15' , 'set':1, 'bitsize':128, 'encoding':eEncodingVector, 'format':eFormatVectorOfUInt8 },
{ 'name':'mxcsr' , 'set':1, 'bitsize':32 , 'encoding':eEncodingUint , 'format':eFormatHex }
];
g_target_definition = None
def get_target_definition ():
global g_target_definition
if g_target_definition == None:
g_target_definition = {}
offset = 0
for reg_info in x86_64_register_infos:
reg_name = reg_info['name']
reg_info['offset'] = offset
# Set the GCC/DWARF register number for this register if it has one
reg_num = get_reg_num(name_to_gcc_dwarf_regnum, reg_name)
if reg_num != LLDB_INVALID_REGNUM:
reg_info['gcc'] = reg_num
reg_info['dwarf'] = reg_num
# Set the generic register number for this register if it has one
reg_num = get_reg_num(name_to_generic_regnum, reg_name)
if reg_num != LLDB_INVALID_REGNUM:
reg_info['generic'] = reg_num
# Set the GDB register number for this register if it has one
reg_num = get_reg_num(name_to_gdb_regnum, reg_name)
if reg_num != LLDB_INVALID_REGNUM:
reg_info['gdb'] = reg_num
offset += reg_info['bitsize']/8
g_target_definition['sets'] = ['General Purpose Registers', 'Floating Point Registers']
g_target_definition['registers'] = x86_64_register_infos
g_target_definition['host-info'] = { 'triple' : 'x86_64-apple-macosx', 'endian': eByteOrderLittle }
g_target_definition['g-packet-size'] = offset
return g_target_definition
def get_dynamic_setting(target, setting_name):
if setting_name == 'gdb-server-target-definition':
return get_target_definition()

View File

@ -108,45 +108,47 @@ public:
const char *session_dictionary_name,
const lldb::ProcessSP& process_sp);
typedef uint32_t (*SWIGPythonCalculateNumChildren) (void *implementor);
typedef void* (*SWIGPythonGetChildAtIndex) (void *implementor, uint32_t idx);
typedef int (*SWIGPythonGetIndexOfChildWithName) (void *implementor, const char* child_name);
typedef void* (*SWIGPythonCastPyObjectToSBValue) (void* data);
typedef lldb::ValueObjectSP (*SWIGPythonGetValueObjectSPFromSBValue) (void* data);
typedef bool (*SWIGPythonUpdateSynthProviderInstance) (void* data);
typedef bool (*SWIGPythonMightHaveChildrenSynthProviderInstance) (void* data);
typedef uint32_t (*SWIGPythonCalculateNumChildren) (void *implementor);
typedef void* (*SWIGPythonGetChildAtIndex) (void *implementor, uint32_t idx);
typedef int (*SWIGPythonGetIndexOfChildWithName) (void *implementor, const char* child_name);
typedef void* (*SWIGPythonCastPyObjectToSBValue) (void* data);
typedef lldb::ValueObjectSP (*SWIGPythonGetValueObjectSPFromSBValue) (void* data);
typedef bool (*SWIGPythonUpdateSynthProviderInstance) (void* data);
typedef bool (*SWIGPythonMightHaveChildrenSynthProviderInstance) (void* data);
typedef bool (*SWIGPythonCallCommand) (const char *python_function_name,
const char *session_dictionary_name,
lldb::DebuggerSP& debugger,
const char* args,
lldb_private::CommandReturnObject& cmd_retobj);
typedef bool (*SWIGPythonCallCommand) (const char *python_function_name,
const char *session_dictionary_name,
lldb::DebuggerSP& debugger,
const char* args,
lldb_private::CommandReturnObject& cmd_retobj);
typedef bool (*SWIGPythonCallModuleInit) (const char *python_module_name,
const char *session_dictionary_name,
lldb::DebuggerSP& debugger);
typedef bool (*SWIGPythonCallModuleInit) (const char *python_module_name,
const char *session_dictionary_name,
lldb::DebuggerSP& debugger);
typedef bool (*SWIGPythonScriptKeyword_Process) (const char* python_function_name,
const char* session_dictionary_name,
lldb::ProcessSP& process,
std::string& output);
typedef bool (*SWIGPythonScriptKeyword_Thread) (const char* python_function_name,
const char* session_dictionary_name,
lldb::ThreadSP& thread,
std::string& output);
typedef bool (*SWIGPythonScriptKeyword_Process) (const char* python_function_name,
const char* session_dictionary_name,
lldb::ProcessSP& process,
std::string& output);
typedef bool (*SWIGPythonScriptKeyword_Thread) (const char* python_function_name,
const char* session_dictionary_name,
lldb::ThreadSP& thread,
std::string& output);
typedef bool (*SWIGPythonScriptKeyword_Target) (const char* python_function_name,
const char* session_dictionary_name,
lldb::TargetSP& target,
std::string& output);
typedef bool (*SWIGPythonScriptKeyword_Target) (const char* python_function_name,
const char* session_dictionary_name,
lldb::TargetSP& target,
std::string& output);
typedef bool (*SWIGPythonScriptKeyword_Frame) (const char* python_function_name,
const char* session_dictionary_name,
lldb::StackFrameSP& frame,
std::string& output);
typedef bool (*SWIGPythonScriptKeyword_Frame) (const char* python_function_name,
const char* session_dictionary_name,
lldb::StackFrameSP& frame,
std::string& output);
typedef void* (*SWIGPythonGDBPlugin_GetDynamicSetting) (void* module, const char* setting, const lldb::TargetSP& target_sp);
typedef void* (*SWIGPython_GetDynamicSetting) (void* module,
const char* setting,
const lldb::TargetSP& target_sp);
typedef enum
{
@ -340,17 +342,17 @@ public:
}
virtual lldb::ScriptInterpreterObjectSP
GDBRemotePlugin_LoadPluginModule (const FileSpec& file_spec,
lldb_private::Error& error)
LoadPluginModule (const FileSpec& file_spec,
lldb_private::Error& error)
{
return lldb::ScriptInterpreterObjectSP();
}
virtual lldb::ScriptInterpreterObjectSP
GDBRemotePlugin_GetDynamicSettings (lldb::ScriptInterpreterObjectSP gdbremote_plugin_module_sp,
Target* target,
const char* setting_name,
lldb_private::Error& error)
GetDynamicSettings (lldb::ScriptInterpreterObjectSP plugin_module_sp,
Target* target,
const char* setting_name,
lldb_private::Error& error)
{
return lldb::ScriptInterpreterObjectSP();
}

View File

@ -99,14 +99,14 @@ public:
lldb::addr_t context);
virtual lldb::ScriptInterpreterObjectSP
GDBRemotePlugin_LoadPluginModule (const FileSpec& file_spec,
lldb_private::Error& error);
LoadPluginModule (const FileSpec& file_spec,
lldb_private::Error& error);
virtual lldb::ScriptInterpreterObjectSP
GDBRemotePlugin_GetDynamicSettings (lldb::ScriptInterpreterObjectSP gdbremote_plugin_module_sp,
Target* target,
const char* setting_name,
lldb_private::Error& error);
GetDynamicSettings (lldb::ScriptInterpreterObjectSP plugin_module_sp,
Target* target,
const char* setting_name,
lldb_private::Error& error);
virtual size_t
CalculateNumChildren (const lldb::ScriptInterpreterObjectSP& implementor);

View File

@ -714,7 +714,7 @@ LLDBSWIGPythonCreateOSPlugin
}
SWIGEXPORT 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)
{
if (!module || !setting)

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

View File

@ -114,13 +114,14 @@ DynamicRegisterInfo::SetRegisterInfo (const lldb_private::PythonDictionary &dict
Clear();
return 0;
}
reg_info.byte_size = reg_info_dict.GetItemForKeyAsInteger(bitsize_pystr, 0) / 8;
if (reg_info.byte_size == 0)
const int64_t bitsize = reg_info_dict.GetItemForKeyAsInteger(bitsize_pystr, 0);
if (bitsize == 0)
{
Clear();
return 0;
}
reg_info.byte_size = bitsize / 8;
const char *format_cstr = reg_info_dict.GetItemForKeyAsString(format_pystr);
if (format_cstr)
@ -132,13 +133,15 @@ DynamicRegisterInfo::SetRegisterInfo (const lldb_private::PythonDictionary &dict
}
}
else
reg_info.format = eFormatHex;
{
reg_info.format = (Format)reg_info_dict.GetItemForKeyAsInteger (format_pystr, 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;
reg_info.encoding = (Encoding)reg_info_dict.GetItemForKeyAsInteger (encoding_pystr, eEncodingUint);
const int64_t set = reg_info_dict.GetItemForKeyAsInteger(set_pystr, -1);
if (set >= m_sets.size())
@ -151,7 +154,11 @@ DynamicRegisterInfo::SetRegisterInfo (const lldb_private::PythonDictionary &dict
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));
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);
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;

View File

@ -2341,7 +2341,9 @@ GDBRemoteCommunicationClient::GetThreadStopInfo (lldb::tid_t tid, StringExtracto
assert (packet_len < (int)sizeof(packet));
if (SendPacketAndWaitForResponse(packet, packet_len, response, false))
{
if (response.IsNormalResponse())
if (response.IsUnsupportedResponse())
m_supports_qThreadStopInfo = false;
else if (response.IsNormalResponse())
return true;
else
return false;
@ -2351,8 +2353,6 @@ GDBRemoteCommunicationClient::GetThreadStopInfo (lldb::tid_t tid, StringExtracto
m_supports_qThreadStopInfo = false;
}
}
// if (SetCurrentThread (tid))
// return GetStopReply (response);
return false;
}

View File

@ -17,6 +17,7 @@
#include "lldb/Core/RegisterValue.h"
#include "lldb/Core/Scalar.h"
#include "lldb/Core/StreamString.h"
#include "lldb/Interpreter/PythonDataObjects.h"
#include "lldb/Target/ExecutionContext.h"
#include "lldb/Utility/Utils.h"
// Project includes
@ -696,6 +697,137 @@ GDBRemoteRegisterContext::ConvertRegisterKindToRegisterNumber (uint32_t kind, ui
return m_reg_info.ConvertRegisterKindToRegisterNumber (kind, num);
}
size_t
GDBRemoteDynamicRegisterInfo::SetRegisterInfo (const lldb_private::PythonDictionary &dict)
{
#ifndef LLDB_DISABLE_PYTHON
PythonList sets (dict.GetItemForKey("sets"));
if (sets)
{
const uint32_t num_sets = sets.GetSize();
for (uint32_t i=0; i<num_sets; ++i)
{
PythonString py_set_name(sets.GetItemAtIndex(i));
ConstString set_name;
if (py_set_name)
set_name.SetCString(py_set_name.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());
}
PythonList regs (dict.GetItemForKey("registers"));
if (regs)
{
const uint32_t num_regs = regs.GetSize();
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 gdb_pystr("gdb");
PythonString dwarf_pystr("dwarf");
PythonString generic_pystr("generic");
for (uint32_t i=0; i<num_regs; ++i)
{
PythonDictionary reg_info_dict(regs.GetItemAtIndex(i));
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 (&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)
{
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 = (Format)reg_info_dict.GetItemForKeyAsInteger (format_pystr, 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 = (Encoding)reg_info_dict.GetItemForKeyAsInteger (encoding_pystr, eEncodingUint);
const int64_t set = reg_info_dict.GetItemForKeyAsInteger(set_pystr, -1);
if (set >= m_sets.size())
{
Clear();
return 0;
}
reg_info.kinds[lldb::eRegisterKindLLDB] = i;
reg_info.kinds[lldb::eRegisterKindGDB] = reg_info_dict.GetItemForKeyAsInteger(gdb_pystr , LLDB_INVALID_REGNUM);
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);
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);
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);
}
else
{
Clear();
return 0;
}
}
Finalize ();
}
#endif
return 0;
}
void
GDBRemoteDynamicRegisterInfo::HardcodeARMRegisters(bool from_scratch)
{

View File

@ -171,6 +171,9 @@ public:
void
HardcodeARMRegisters(bool from_scratch);
size_t
SetRegisterInfo (const lldb_private::PythonDictionary &dict);
protected:
//------------------------------------------------------------------
// Classes that inherit from GDBRemoteRegisterContext can see and modify these

View File

@ -49,6 +49,7 @@
#include "lldb/Interpreter/CommandObject.h"
#include "lldb/Interpreter/CommandObjectMultiword.h"
#include "lldb/Interpreter/CommandReturnObject.h"
#include "lldb/Interpreter/PythonDataObjects.h"
#include "lldb/Symbol/ObjectFile.h"
#include "lldb/Target/DynamicLoader.h"
#include "lldb/Target/Target.h"
@ -97,12 +98,14 @@ namespace {
g_properties[] =
{
{ "packet-timeout" , OptionValue::eTypeUInt64 , true , 1, NULL, NULL, "Specify the default packet timeout in seconds." },
{ "target-definition-file" , OptionValue::eTypeFileSpec , true, 0 , NULL, NULL, "The file that provides the description for remote target registers." },
{ NULL , OptionValue::eTypeInvalid, false, 0, NULL, NULL, NULL }
};
enum
{
ePropertyPacketTimeout
ePropertyPacketTimeout,
ePropertyTargetDefinitionFile
};
class PluginProperties : public Properties
@ -133,6 +136,12 @@ namespace {
const uint32_t idx = ePropertyPacketTimeout;
return m_collection_sp->GetPropertyAtIndexAsUInt64(NULL, idx, g_properties[idx].default_uint_value);
}
FileSpec
GetTargetDefinitionFile () const
{
const uint32_t idx = ePropertyTargetDefinitionFile;
return m_collection_sp->GetPropertyAtIndexAsFileSpec (NULL, idx);
}
};
typedef std::shared_ptr<PluginProperties> ProcessKDPPropertiesSP;
@ -308,6 +317,33 @@ ProcessGDBRemote::GetPluginVersion()
return 1;
}
bool
ProcessGDBRemote::ParsePythonTargetDefinition(const FileSpec &target_definition_fspec)
{
ScriptInterpreter *interpreter = GetTarget().GetDebugger().GetCommandInterpreter().GetScriptInterpreter();
Error error;
lldb::ScriptInterpreterObjectSP module_object_sp (interpreter->LoadPluginModule(target_definition_fspec, error));
if (module_object_sp)
{
lldb::ScriptInterpreterObjectSP target_definition_sp (interpreter->GetDynamicSettings(module_object_sp,
&GetTarget(),
"gdb-server-target-definition",
error));
PythonDictionary target_dict(target_definition_sp);
if (target_dict)
{
if (m_register_info.SetRegisterInfo (target_dict) > 0)
{
return true;
}
}
}
return false;
}
void
ProcessGDBRemote::BuildDynamicRegisterInfo (bool force)
{
@ -483,6 +519,18 @@ ProcessGDBRemote::BuildDynamicRegisterInfo (bool force)
}
}
if (reg_num == 0)
{
FileSpec target_definition_fspec = GetGlobalPluginProperties()->GetTargetDefinitionFile ();
// See if we can get register definitions from a python file
if (ParsePythonTargetDefinition (target_definition_fspec))
{
m_register_info.Finalize ();
return;
}
}
// We didn't get anything if the accumulated reg_num is zero. See if we are
// debugging ARM and fill with a hard coded register set until we can get an
// updated debugserver down on the devices.

View File

@ -291,6 +291,12 @@ protected:
void
SetLastStopPacket (const StringExtractorGDBRemote &response);
bool
ParsePythonTargetDefinition(const lldb_private::FileSpec &target_definition_fspec);
bool
ParseRegisters(lldb_private::ScriptInterpreterObject *registers_array);
//------------------------------------------------------------------
/// Broadcaster event bits definitions.
//------------------------------------------------------------------