@ -1614,18 +1614,21 @@ static void handle_query_thread_extra(GArray *params, void *user_ctx)
gdb_put_strbuf ( ) ;
}
static char * extended_qsupported_features ;
void gdb_extend_qsupported_features ( char * qsupported_features )
{
/*
* We don ' t support different sets of CPU gdb features on different CPUs yet
* so assert the feature strings are the same on all CPUs , or is set only
* once ( 1 CPU ) .
*/
g_assert ( extended_qsupported_features = = NULL | |
g_strcmp0 ( extended_qsupported_features , qsupported_features ) = = 0 ) ;
extended_qsupported_features = qsupported_features ;
static char * * extra_query_flags ;
void gdb_extend_qsupported_features ( char * qflags )
{
if ( ! extra_query_flags ) {
extra_query_flags = g_new0 ( char * , 2 ) ;
extra_query_flags [ 0 ] = g_strdup ( qflags ) ;
} else if ( ! g_strv_contains ( ( const gchar * const * ) extra_query_flags ,
qflags ) ) {
int len = g_strv_length ( extra_query_flags ) ;
extra_query_flags = g_realloc_n ( extra_query_flags , len + 2 ,
sizeof ( char * ) ) ;
extra_query_flags [ len ] = g_strdup ( qflags ) ;
}
}
static void handle_query_supported ( GArray * params , void * user_ctx )
@ -1668,8 +1671,11 @@ static void handle_query_supported(GArray *params, void *user_ctx)
g_string_append ( gdbserver_state . str_buf , " ;vContSupported+;multiprocess+ " ) ;
if ( extended_qsupported_features ) {
g_string_append ( gdbserver_state . str_buf , extended_qsupported_features ) ;
if ( extra_query_flags ) {
int extras = g_strv_length ( extra_query_flags ) ;
for ( int i = 0 ; i < extras ; i + + ) {
g_string_append ( gdbserver_state . str_buf , extra_query_flags [ i ] ) ;
}
}
gdb_put_strbuf ( ) ;
@ -1753,39 +1759,58 @@ static const GdbCmdParseEntry gdb_gen_query_set_common_table[] = {
} ,
} ;
/* Compares if a set of command parsers is equal to another set of parsers. */
static bool cmp_cmds ( GdbCmdParseEntry * c , GdbCmdParseEntry * d , int size )
/**
* extend_table ( ) - extend one of the command tables
* @ table : the command table to extend ( or NULL )
* @ extensions : a list of GdbCmdParseEntry pointers
*
* The entries themselves should be pointers to static const
* GdbCmdParseEntry entries . If the entry is already in the table we
* skip adding it again .
*
* Returns ( a potentially freshly allocated ) GPtrArray of GdbCmdParseEntry
*/
static GPtrArray * extend_table ( GPtrArray * table , GPtrArray * extensions )
{
for ( int i = 0 ; i < size ; i + + ) {
if ( ! ( c [ i ] . handler = = d [ i ] . handler & &
g_strcmp0 ( c [ i ] . cmd , d [ i ] . cmd ) = = 0 & &
c [ i ] . cmd_startswith = = d [ i ] . cmd_startswith & &
g_strcmp0 ( c [ i ] . schema , d [ i ] . schema ) = = 0 ) ) {
if ( ! table ) {
table = g_ptr_array_new ( ) ;
}
/* Sets are different. */
return false ;
for ( int i = 0 ; i < extensions - > len ; i + + ) {
gpointer entry = g_ptr_array_index ( extensions , i ) ;
if ( ! g_ptr_array_find ( table , entry , NULL ) ) {
g_ptr_array_add ( table , entry ) ;
}
}
/* Sets are equal, i.e. contain the same command parsers. */
return true ;
return table ;
}
static GdbCmdParseEntry * extended_query_table ;
static int extended_query_table_size ;
void gdb_extend_query_table ( GdbCmdParseEntry * table , int size )
/**
* process_extended_table ( ) - run through an extended command table
* @ table : the command table to check
* @ data : parameters
*
* returns true if the command was found and executed
*/
static bool process_extended_table ( GPtrArray * table , const char * data )
{
/*
* We don ' t support different sets of CPU gdb features on different CPUs yet
* so assert query table is the same on all CPUs , or is set only once
* ( 1 CPU ) .
*/
g_assert ( extended_query_table = = NULL | |
( extended_query_table_size = = size & &
cmp_cmds ( extended_query_table , table , size ) ) ) ;
for ( int i = 0 ; i < table - > len ; i + + ) {
const GdbCmdParseEntry * entry = g_ptr_array_index ( table , i ) ;
if ( process_string_cmd ( data , entry , 1 ) ) {
return true ;
}
}
return false ;
}
extended_query_table = table ;
extended_query_table_size = size ;
/* Ptr to GdbCmdParseEntry */
static GPtrArray * extended_query_table ;
void gdb_extend_query_table ( GPtrArray * new_queries )
{
extended_query_table = extend_table ( extended_query_table , new_queries ) ;
}
static const GdbCmdParseEntry gdb_gen_query_table [ ] = {
@ -1880,20 +1905,12 @@ static const GdbCmdParseEntry gdb_gen_query_table[] = {
# endif
} ;
static GdbCmdParseEntry * extended_set_table ;
static int extended_set_table_size ;
void gdb_extend_set_table ( GdbCmdParseEntry * table , int size )
{
/*
* We don ' t support different sets of CPU gdb features on different CPUs yet
* so assert set table is the same on all CPUs , or is set only once ( 1 CPU ) .
*/
g_assert ( extended_set_table = = NULL | |
( extended_set_table_size = = size & &
cmp_cmds ( extended_set_table , table , size ) ) ) ;
/* Ptr to GdbCmdParseEntry */
static GPtrArray * extended_set_table ;
extended_set_table = table ;
extended_set_table_size = size ;
void gdb_extend_set_table ( GPtrArray * new_set )
{
extended_set_table = extend_table ( extended_set_table , new_set ) ;
}
static const GdbCmdParseEntry gdb_gen_set_table [ ] = {
@ -1924,26 +1941,28 @@ static const GdbCmdParseEntry gdb_gen_set_table[] = {
static void handle_gen_query ( GArray * params , void * user_ctx )
{
const char * data ;
if ( ! params - > len ) {
return ;
}
if ( process_string_cmd ( gdb_get_cmd_param ( params , 0 ) - > data ,
data = gdb_get_cmd_param ( params , 0 ) - > data ;
if ( process_string_cmd ( data ,
gdb_gen_query_set_common_table ,
ARRAY_SIZE ( gdb_gen_query_set_common_table ) ) ) {
return ;
}
if ( process_string_cmd ( gdb_get_cmd_param ( params , 0 ) - > data ,
if ( process_string_cmd ( data ,
gdb_gen_query_table ,
ARRAY_SIZE ( gdb_gen_query_table ) ) ) {
return ;
}
if ( extended_query_table & &
process_string_cmd ( gdb_get_cmd_param ( params , 0 ) - > data ,
extended_query_table ,
extended_query_table_size ) ) {
process_extended_table ( extended_query_table , data ) ) {
return ;
}
@ -1953,26 +1972,28 @@ static void handle_gen_query(GArray *params, void *user_ctx)
static void handle_gen_set ( GArray * params , void * user_ctx )
{
const char * data ;
if ( ! params - > len ) {
return ;
}
if ( process_string_cmd ( gdb_get_cmd_param ( params , 0 ) - > data ,
data = gdb_get_cmd_param ( params , 0 ) - > data ;
if ( process_string_cmd ( data ,
gdb_gen_query_set_common_table ,
ARRAY_SIZE ( gdb_gen_query_set_common_table ) ) ) {
return ;
}
if ( process_string_cmd ( gdb_get_cmd_param ( params , 0 ) - > data ,
if ( process_string_cmd ( data ,
gdb_gen_set_table ,
ARRAY_SIZE ( gdb_gen_set_table ) ) ) {
return ;
}
if ( extended_set_table & &
process_string_cmd ( gdb_get_cmd_param ( params , 0 ) - > data ,
extended_set_table ,
extended_set_table_size ) ) {
process_extended_table ( extended_set_table , data ) ) {
return ;
}