diff options
Diffstat (limited to 'gdb/mi')
-rw-r--r-- | gdb/mi/mi-cmds.c | 4 | ||||
-rw-r--r-- | gdb/mi/mi-cmds.h | 2 | ||||
-rw-r--r-- | gdb/mi/mi-symbol-cmds.c | 155 |
3 files changed, 161 insertions, 0 deletions
diff --git a/gdb/mi/mi-cmds.c b/gdb/mi/mi-cmds.c index 85c15ec..991fb4b 100644 --- a/gdb/mi/mi-cmds.c +++ b/gdb/mi/mi-cmds.c @@ -155,6 +155,10 @@ static struct mi_cmd mi_cmds[] = DEF_MI_CMD_MI ("symbol-info-variables", mi_cmd_symbol_info_variables), DEF_MI_CMD_MI ("symbol-info-types", mi_cmd_symbol_info_types), DEF_MI_CMD_MI ("symbol-info-modules", mi_cmd_symbol_info_modules), + DEF_MI_CMD_MI ("symbol-info-module-functions", + mi_cmd_symbol_info_module_functions), + DEF_MI_CMD_MI ("symbol-info-module-variables", + mi_cmd_symbol_info_module_variables), DEF_MI_CMD_CLI ("target-attach", "attach", 1), DEF_MI_CMD_MI ("target-detach", mi_cmd_target_detach), DEF_MI_CMD_CLI ("target-disconnect", "disconnect", 0), diff --git a/gdb/mi/mi-cmds.h b/gdb/mi/mi-cmds.h index 30de780..faeb36b 100644 --- a/gdb/mi/mi-cmds.h +++ b/gdb/mi/mi-cmds.h @@ -95,6 +95,8 @@ extern mi_cmd_argv_ftype mi_cmd_stack_list_variables; extern mi_cmd_argv_ftype mi_cmd_stack_select_frame; extern mi_cmd_argv_ftype mi_cmd_symbol_list_lines; extern mi_cmd_argv_ftype mi_cmd_symbol_info_functions; +extern mi_cmd_argv_ftype mi_cmd_symbol_info_module_functions; +extern mi_cmd_argv_ftype mi_cmd_symbol_info_module_variables; extern mi_cmd_argv_ftype mi_cmd_symbol_info_modules; extern mi_cmd_argv_ftype mi_cmd_symbol_info_types; extern mi_cmd_argv_ftype mi_cmd_symbol_info_variables; diff --git a/gdb/mi/mi-symbol-cmds.c b/gdb/mi/mi-symbol-cmds.c index 10dd273..2bebd11 100644 --- a/gdb/mi/mi-symbol-cmds.c +++ b/gdb/mi/mi-symbol-cmds.c @@ -216,6 +216,143 @@ mi_info_functions_or_variables (enum search_domain kind, char **argv, int argc) mi_symbol_info (kind, regexp, t_regexp, exclude_minsyms); } +/* Type for an iterator over a vector of module_symbol_search results. */ +typedef std::vector<module_symbol_search>::const_iterator + module_symbol_search_iterator; + +/* Helper for mi_info_module_functions_or_variables. Display the results + from ITER up to END or until we find a symbol that is in a different + module, or in a different symtab than the first symbol we print. Update + and return the new value for ITER. */ +static module_symbol_search_iterator +output_module_symbols_in_single_module_and_file + (struct ui_out *uiout, module_symbol_search_iterator iter, + const module_symbol_search_iterator end, enum search_domain kind) +{ + /* The symbol for the module in which the first result resides. */ + const symbol *first_module_symbol = iter->first.symbol; + + /* The symbol for the first result, and the symtab in which it resides. */ + const symbol *first_result_symbol = iter->second.symbol; + symtab *first_symbtab = symbol_symtab (first_result_symbol); + + /* Formatted output. */ + ui_out_emit_tuple current_file (uiout, nullptr); + uiout->field_string ("filename", + symtab_to_filename_for_display (first_symbtab)); + uiout->field_string ("fullname", symtab_to_fullname (first_symbtab)); + ui_out_emit_list item_list (uiout, "symbols"); + + /* Repeatedly output result symbols until either we run out of symbols, + we change module, or we change symtab. */ + for (; (iter != end + && first_module_symbol == iter->first.symbol + && first_symbtab == symbol_symtab (iter->second.symbol)); + ++iter) + output_debug_symbol (uiout, kind, iter->second.symbol, + iter->second.block); + + return iter; +} + +/* Helper for mi_info_module_functions_or_variables. Display the results + from ITER up to END or until we find a symbol that is in a different + module than the first symbol we print. Update and return the new value + for ITER. */ +static module_symbol_search_iterator +output_module_symbols_in_single_module + (struct ui_out *uiout, module_symbol_search_iterator iter, + const module_symbol_search_iterator end, enum search_domain kind) +{ + gdb_assert (iter->first.symbol != nullptr); + gdb_assert (iter->second.symbol != nullptr); + + /* The symbol for the module in which the first result resides. */ + const symbol *first_module_symbol = iter->first.symbol; + + /* Create output formatting. */ + ui_out_emit_tuple module_tuple (uiout, nullptr); + uiout->field_string ("module", first_module_symbol->print_name ()); + ui_out_emit_list files_list (uiout, "files"); + + /* The results are sorted so that symbols within the same file are next + to each other in the list. Calling the output function once will + print all results within a single file. We keep calling the output + function until we change module. */ + while (iter != end && first_module_symbol == iter->first.symbol) + iter = output_module_symbols_in_single_module_and_file (uiout, iter, + end, kind); + return iter; +} + +/* Core of -symbol-info-module-functions and -symbol-info-module-variables. + KIND indicates what we are searching for, and ARGV and ARGC are the + command line options passed to the MI command. */ + +static void +mi_info_module_functions_or_variables (enum search_domain kind, + char **argv, int argc) +{ + const char *module_regexp = nullptr; + const char *regexp = nullptr; + const char *type_regexp = nullptr; + + /* Process the command line options. */ + + enum opt + { + MODULE_REGEXP_OPT, TYPE_REGEXP_OPT, NAME_REGEXP_OPT + }; + static const struct mi_opt opts[] = + { + {"-module", MODULE_REGEXP_OPT, 1}, + {"-type", TYPE_REGEXP_OPT, 1}, + {"-name", NAME_REGEXP_OPT, 1}, + { 0, 0, 0 } + }; + + int oind = 0; + char *oarg = nullptr; + + while (1) + { + const char *cmd_string + = ((kind == FUNCTIONS_DOMAIN) + ? "-symbol-info-module-functions" + : "-symbol-info-module-variables"); + int opt = mi_getopt (cmd_string, argc, argv, opts, &oind, &oarg); + if (opt < 0) + break; + switch ((enum opt) opt) + { + case MODULE_REGEXP_OPT: + module_regexp = oarg; + break; + case TYPE_REGEXP_OPT: + type_regexp = oarg; + break; + case NAME_REGEXP_OPT: + regexp = oarg; + break; + } + } + + std::vector<module_symbol_search> module_symbols + = search_module_symbols (module_regexp, regexp, type_regexp, kind); + + struct ui_out *uiout = current_uiout; + ui_out_emit_list all_matching_symbols (uiout, "symbols"); + + /* The results in the module_symbols list are ordered so symbols in the + same module are next to each other. Repeatedly call the output + function to print sequences of symbols that are in the same module + until we have no symbols left to print. */ + module_symbol_search_iterator iter = module_symbols.begin (); + const module_symbol_search_iterator end = module_symbols.end (); + while (iter != end) + iter = output_module_symbols_in_single_module (uiout, iter, end, kind); +} + /* Implement -symbol-info-functions command. */ void @@ -224,6 +361,24 @@ mi_cmd_symbol_info_functions (const char *command, char **argv, int argc) mi_info_functions_or_variables (FUNCTIONS_DOMAIN, argv, argc); } +/* Implement -symbol-info-module-functions command. */ + +void +mi_cmd_symbol_info_module_functions (const char *command, char **argv, + int argc) +{ + mi_info_module_functions_or_variables (FUNCTIONS_DOMAIN, argv, argc); +} + +/* Implement -symbol-info-module-variables command. */ + +void +mi_cmd_symbol_info_module_variables (const char *command, char **argv, + int argc) +{ + mi_info_module_functions_or_variables (VARIABLES_DOMAIN, argv, argc); +} + /* Implement -symbol-inf-modules command. */ void |