From patchwork Tue Nov 26 23:25:46 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Simon Marchi (Code Review)" X-Patchwork-Id: 36284 Received: (qmail 23188 invoked by alias); 26 Nov 2019 23:26:08 -0000 Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org Delivered-To: mailing list gdb-patches@sourceware.org Received: (qmail 23096 invoked by uid 89); 26 Nov 2019 23:26:08 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-20.8 required=5.0 tests=AWL, BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, KAM_SHORT, KAM_STOCKGEN autolearn=ham version=3.3.1 spammy=20name X-HELO: mx1.osci.io Received: from polly.osci.io (HELO mx1.osci.io) (8.43.85.229) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Tue, 26 Nov 2019 23:26:01 +0000 Received: by mx1.osci.io (Postfix, from userid 994) id 1C6D1201F1; Tue, 26 Nov 2019 18:25:57 -0500 (EST) Received: from gnutoolchain-gerrit.osci.io (gnutoolchain-gerrit.osci.io [8.43.85.239]) by mx1.osci.io (Postfix) with ESMTP id 1AA20202DF; Tue, 26 Nov 2019 18:25:49 -0500 (EST) Received: from localhost (localhost [127.0.0.1]) by gnutoolchain-gerrit.osci.io (Postfix) with ESMTP id EA83828173; Tue, 26 Nov 2019 18:25:48 -0500 (EST) X-Gerrit-PatchSet: 6 Date: Tue, 26 Nov 2019 18:25:46 -0500 From: "Andrew Burgess (Code Review)" To: Tom Tromey , gdb-patches@sourceware.org Cc: Joel Brobecker , Simon Marchi Auto-Submitted: auto-generated X-Gerrit-MessageType: newpatchset Subject: [review v6] gdb/mi: Add new commands -symbol-info-{functions, variables, types} X-Gerrit-Change-Id: Ic2fc6a6750bbce91cdde2344791014e5ef45642d X-Gerrit-Change-Number: 266 X-Gerrit-ChangeURL: X-Gerrit-Commit: fd6dd1c212e04e6342aa9df593dc072ad62082e2 In-Reply-To: References: Reply-To: andrew.burgess@embecosm.com, simon.marchi@polymtl.ca, tromey@sourceware.org, brobecker@adacore.com, gdb-patches@sourceware.org MIME-Version: 1.0 Content-Disposition: inline User-Agent: Gerrit/3.0.3-79-g83ff7f88f1 Message-Id: <20191126232548.EA83828173@gnutoolchain-gerrit.osci.io> Change URL: https://gnutoolchain-gerrit.osci.io/r/c/binutils-gdb/+/266 ...................................................................... gdb/mi: Add new commands -symbol-info-{functions,variables,types} Add new MI commands -symbol-info-functions, -symbol-info-variables, and -symbol-info-types which correspond to the CLI commands 'info functions', 'info variables', and 'info types' respectively. gdb/ChangeLog: * mi/mi-cmds.c (mi_cmds): Add '-symbol-info-functions', '-symbol-info-types', and '-symbol-info-variables'. * mi/mi-cmds.h (mi_cmd_symbol_info_functions): Declare. (mi_cmd_symbol_info_types): Declare. (mi_cmd_symbol_info_variables): Declare. * mi/mi-symbol-cmds.c: Add 'source.h' and 'mi-getopt.h' includes. (output_debug_symbol): New function. (output_nondebug_symbol): New function. (mi_symbol_info): New function. (mi_info_functions_or_variables): New function. (mi_cmd_symbol_info_functions): New function. (mi_cmd_symbol_info_types): New function. (mi_cmd_symbol_info_variables): New function. * NEWS: Mention new commands. gdb/testsuite/ChangeLog: * gdb.mi/mi-sym-info-1.c: New file. * gdb.mi/mi-sym-info-2.c: New file. * gdb.mi/mi-sym-info.exp: New file. gdb/doc/ChangeLog: * doc/gdb.texinfo (GDB/MI Symbol Query): Document new MI command -symbol-info-functions, -symbol-info-types, and -symbol-info-variables. Change-Id: Ic2fc6a6750bbce91cdde2344791014e5ef45642d --- M gdb/ChangeLog M gdb/NEWS M gdb/doc/ChangeLog M gdb/doc/gdb.texinfo M gdb/mi/mi-cmds.c M gdb/mi/mi-cmds.h M gdb/mi/mi-symbol-cmds.c M gdb/testsuite/ChangeLog A gdb/testsuite/gdb.mi/mi-sym-info-1.c A gdb/testsuite/gdb.mi/mi-sym-info-2.c A gdb/testsuite/gdb.mi/mi-sym-info.exp 11 files changed, 731 insertions(+), 7 deletions(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 49c95ad..76db458 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,5 +1,22 @@ 2019-11-26 Andrew Burgess + * mi/mi-cmds.c (mi_cmds): Add '-symbol-info-functions', + '-symbol-info-types', and '-symbol-info-variables'. + * mi/mi-cmds.h (mi_cmd_symbol_info_functions): Declare. + (mi_cmd_symbol_info_types): Declare. + (mi_cmd_symbol_info_variables): Declare. + * mi/mi-symbol-cmds.c: Add 'source.h' and 'mi-getopt.h' includes. + (output_debug_symbol): New function. + (output_nondebug_symbol): New function. + (mi_symbol_info): New function. + (mi_info_functions_or_variables): New function. + (mi_cmd_symbol_info_functions): New function. + (mi_cmd_symbol_info_types): New function. + (mi_cmd_symbol_info_variables): New function. + * NEWS: Mention new commands. + +2019-11-26 Andrew Burgess + * symtab.c (symbol_to_info_string): New function, most content moved from print_symbol_info, but updated to return a std::string. (print_symbol_info): Update to use symbol_to_info_string and print diff --git a/gdb/NEWS b/gdb/NEWS index 01b38cf..7ae9a4e 100644 --- a/gdb/NEWS +++ b/gdb/NEWS @@ -359,6 +359,10 @@ These can be used to catch C++ exceptions in a similar fashion to the CLI commands 'catch throw', 'catch rethrow', and 'catch catch'. +-symbol-info-functions, -symbol-info-types, and -symbol-info-variables + These commands are the MI equivalent of the CLI commands 'info + functions', 'info types', and 'info variables' respectively. + * Other MI changes ** The default version of the MI interpreter is now 3 (-i=mi3). diff --git a/gdb/doc/ChangeLog b/gdb/doc/ChangeLog index c6fa5f5..886ffd0 100644 --- a/gdb/doc/ChangeLog +++ b/gdb/doc/ChangeLog @@ -1,3 +1,9 @@ +2019-11-26 Andrew Burgess + + * doc/gdb.texinfo (GDB/MI Symbol Query): Document new MI command + -symbol-info-functions, -symbol-info-types, and + -symbol-info-variables. + 2019-11-25 Luis Machado * gdb.texinfo (Debugging Output): Document set debug diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo index 18bb18b..2eefe41 100644 --- a/gdb/doc/gdb.texinfo +++ b/gdb/doc/gdb.texinfo @@ -33887,27 +33887,283 @@ @subsubheading Example N.A. +@end ignore - -@subheading The @code{-symbol-info-function} Command -@findex -symbol-info-function +@subheading The @code{-symbol-info-functions} Command +@findex -symbol-info-functions +@anchor{-symbol-info-functions} @subsubheading Synopsis @smallexample - -symbol-info-function + -symbol-info-functions [--include-nondebug] + [--type @var{type_regexp}] + [--name @var{name_regexp}] @end smallexample -Show which function the symbol lives in. +@noindent +Return a list containing the names and types for all global functions +taken from the debug information. The functions are grouped by source +file, and shown with the line number on which each function is +defined. + +The @code{--include-nondebug} option causes the output to include +code symbols from the symbol table. + +The options @code{--type} and @code{--name} allow the symbols returned +to be filtered based on either the name of the function, or the type +signature of the function. @subsubheading @value{GDBN} Command -@samp{gdb_get_function} in @code{gdbtk}. +The corresponding @value{GDBN} command is @samp{info functions}. @subsubheading Example -N.A. +@smallexample +@group +(gdb) +-symbol-info-functions +^done,symbols= + @{debug= + [@{filename="/project/gdb/testsuite/gdb.mi/mi-sym-info-1.c", + fullname="/project/gdb/testsuite/gdb.mi/mi-sym-info-1.c", + symbols=[@{line="36", name="f4", type="void (int *)", + description="void f4(int *);"@}, + @{line="42", name="main", type="int ()", + description="int main();"@}, + @{line="30", name="f1", type="my_int_t (int, int)", + description="static my_int_t f1(int, int);"@}]@}, + @{filename="/project/gdb/testsuite/gdb.mi/mi-sym-info-2.c", + fullname="/project/gdb/testsuite/gdb.mi/mi-sym-info-2.c", + symbols=[@{line="33", name="f2", type="float (another_float_t)", + description="float f2(another_float_t);"@}, + @{line="39", name="f3", type="int (another_int_t)", + description="int f3(another_int_t);"@}, + @{line="27", name="f1", type="another_float_t (int)", + description="static another_float_t f1(int);"@}]@}]@} +@end group +@group +(gdb) +-symbol-info-functions --name f1 +^done,symbols= + @{debug= + [@{filename="/project/gdb/testsuite/gdb.mi/mi-sym-info-1.c", + fullname="/project/gdb/testsuite/gdb.mi/mi-sym-info-1.c", + symbols=[@{line="30", name="f1", type="my_int_t (int, int)", + description="static my_int_t f1(int, int);"@}]@}, + @{filename="/project/gdb/testsuite/gdb.mi/mi-sym-info-2.c", + fullname="/project/gdb/testsuite/gdb.mi/mi-sym-info-2.c", + symbols=[@{line="27", name="f1", type="another_float_t (int)", + description="static another_float_t f1(int);"@}]@}]@} +@end group +@group +(gdb) +-symbol-info-functions --type void +^done,symbols= + @{debug= + [@{filename="/project/gdb/testsuite/gdb.mi/mi-sym-info-1.c", + fullname="/project/gdb/testsuite/gdb.mi/mi-sym-info-1.c", + symbols=[@{line="36", name="f4", type="void (int *)", + description="void f4(int *);"@}]@}]@} +@end group +@group +(gdb) +-symbol-info-functions --include-nondebug +^done,symbols= + @{debug= + [@{filename="/project/gdb/testsuite/gdb.mi/mi-sym-info-1.c", + fullname="/project/gdb/testsuite/gdb.mi/mi-sym-info-1.c", + symbols=[@{line="36", name="f4", type="void (int *)", + description="void f4(int *);"@}, + @{line="42", name="main", type="int ()", + description="int main();"@}, + @{line="30", name="f1", type="my_int_t (int, int)", + description="static my_int_t f1(int, int);"@}]@}, + @{filename="/project/gdb/testsuite/gdb.mi/mi-sym-info-2.c", + fullname="/project/gdb/testsuite/gdb.mi/mi-sym-info-2.c", + symbols=[@{line="33", name="f2", type="float (another_float_t)", + description="float f2(another_float_t);"@}, + @{line="39", name="f3", type="int (another_int_t)", + description="int f3(another_int_t);"@}, + @{line="27", name="f1", type="another_float_t (int)", + description="static another_float_t f1(int);"@}]@}], + nondebug= + [@{address="0x0000000000400398",name="_init"@}, + @{address="0x00000000004003b0",name="_start"@}, + ... + ]@} +@end group +@end smallexample +@subheading The @code{-symbol-info-types} Command +@findex -symbol-info-types +@anchor{-symbol-info-types} +@subsubheading Synopsis + +@smallexample + -symbol-info-types [--name @var{name_regexp}] +@end smallexample + +@noindent +Return a list of all defined types. The types are grouped by source +file, and shown with the line number on which each user defined type +is defined. Some base types are not defined in the source code but +are added to the debug information by the compiler, for example +@code{int}, @code{float}, etc.; these types do not have an associated +line number. + +The option @code{--name} allows the list of types returned to be +filtered by name. + +@subsubheading @value{GDBN} Command + +The corresponding @value{GDBN} command is @samp{info types}. + +@subsubheading Example +@smallexample +@group +(gdb) +-symbol-info-types +^done,symbols= + @{debug= + [@{filename="gdb.mi/mi-sym-info-1.c", + fullname="/project/gdb/testsuite/gdb.mi/mi-sym-info-1.c", + symbols=[@{name="float"@}, + @{name="int"@}, + @{line="27",name="typedef int my_int_t;"@}]@}, + @{filename="gdb.mi/mi-sym-info-2.c", + fullname="/project/gdb.mi/mi-sym-info-2.c", + symbols=[@{line="24",name="typedef float another_float_t;"@}, + @{line="23",name="typedef int another_int_t;"@}, + @{name="float"@}, + @{name="int"@}]@}]@} +@end group +@group +(gdb) +-symbol-info-types --name _int_ +^done,symbols= + @{debug= + [@{filename="gdb.mi/mi-sym-info-1.c", + fullname="/project/gdb/testsuite/gdb.mi/mi-sym-info-1.c", + symbols=[@{line="27",name="typedef int my_int_t;"@}]@}, + @{filename="gdb.mi/mi-sym-info-2.c", + fullname="/project/gdb.mi/mi-sym-info-2.c", + symbols=[@{line="23",name="typedef int another_int_t;"@}]@}]@} +@end group +@end smallexample + +@subheading The @code{-symbol-info-variables} Command +@findex -symbol-info-variables +@anchor{-symbol-info-variables} + +@subsubheading Synopsis + +@smallexample + -symbol-info-variables [--include-nondebug] + [--type @var{type_regexp}] + [--name @var{name_regexp}] +@end smallexample + +@noindent +Return a list containing the names and types for all global variables +taken from the debug information. The variables are grouped by source +file, and shown with the line number on which each variable is +defined. + +The @code{--include-nondebug} option causes the output to include +data symbols from the symbol table. + +The options @code{--type} and @code{--name} allow the symbols returned +to be filtered based on either the name of the variable, or the type +of the variable. + +@subsubheading @value{GDBN} Command + +The corresponding @value{GDBN} command is @samp{info variables}. + +@subsubheading Example +@smallexample +@group +(gdb) +-symbol-info-variables +^done,symbols= + @{debug= + [@{filename="/project/gdb/testsuite/gdb.mi/mi-sym-info-1.c", + fullname="/project/gdb/testsuite/gdb.mi/mi-sym-info-1.c", + symbols=[@{line="25",name="global_f1",type="float", + description="static float global_f1;"@}, + @{line="24",name="global_i1",type="int", + description="static int global_i1;"@}]@}, + @{filename="/project/gdb/testsuite/gdb.mi/mi-sym-info-2.c", + fullname="/project/gdb/testsuite/gdb.mi/mi-sym-info-2.c", + symbols=[@{line="21",name="global_f2",type="int", + description="int global_f2;"@}, + @{line="20",name="global_i2",type="int", + description="int global_i2;"@}, + @{line="19",name="global_f1",type="float", + description="static float global_f1;"@}, + @{line="18",name="global_i1",type="int", + description="static int global_i1;"@}]@}]@} +@end group +@group +(gdb) +-symbol-info-variables --name f1 +^done,symbols= + @{debug= + [@{filename="/project/gdb/testsuite/gdb.mi/mi-sym-info-1.c", + fullname="/project/gdb/testsuite/gdb.mi/mi-sym-info-1.c", + symbols=[@{line="25",name="global_f1",type="float", + description="static float global_f1;"@}]@}, + @{filename="/project/gdb/testsuite/gdb.mi/mi-sym-info-2.c", + fullname="/project/gdb/testsuite/gdb.mi/mi-sym-info-2.c", + symbols=[@{line="19",name="global_f1",type="float", + description="static float global_f1;"@}]@}]@} +@end group +@group +(gdb) +-symbol-info-variables --type float +^done,symbols= + @{debug= + [@{filename="/project/gdb/testsuite/gdb.mi/mi-sym-info-1.c", + fullname="/project/gdb/testsuite/gdb.mi/mi-sym-info-1.c", + symbols=[@{line="25",name="global_f1",type="float", + description="static float global_f1;"@}]@}, + @{filename="/project/gdb/testsuite/gdb.mi/mi-sym-info-2.c", + fullname="/project/gdb/testsuite/gdb.mi/mi-sym-info-2.c", + symbols=[@{line="19",name="global_f1",type="float", + description="static float global_f1;"@}]@}]@} +@end group +@group +(gdb) +-symbol-info-variables --include-nondebug +^done,symbols= + @{debug= + [@{filename="/project/gdb/testsuite/gdb.mi/mi-sym-info-1.c", + fullname="/project/gdb/testsuite/gdb.mi/mi-sym-info-1.c", + symbols=[@{line="25",name="global_f1",type="float", + description="static float global_f1;"@}, + @{line="24",name="global_i1",type="int", + description="static int global_i1;"@}]@}, + @{filename="/project/gdb/testsuite/gdb.mi/mi-sym-info-2.c", + fullname="/project/gdb/testsuite/gdb.mi/mi-sym-info-2.c", + symbols=[@{line="21",name="global_f2",type="int", + description="int global_f2;"@}, + @{line="20",name="global_i2",type="int", + description="int global_i2;"@}, + @{line="19",name="global_f1",type="float", + description="static float global_f1;"@}, + @{line="18",name="global_i1",type="int", + description="static int global_i1;"@}]@}], + nondebug= + [@{address="0x00000000004005d0",name="_IO_stdin_used"@}, + @{address="0x00000000004005d8",name="__dso_handle"@} + ... + ]@} +@end group +@end smallexample + +@ignore @subheading The @code{-symbol-info-line} Command @findex -symbol-info-line diff --git a/gdb/mi/mi-cmds.c b/gdb/mi/mi-cmds.c index 37eab01..df9f25f 100644 --- a/gdb/mi/mi-cmds.c +++ b/gdb/mi/mi-cmds.c @@ -151,6 +151,9 @@ DEF_MI_CMD_MI_1 ("stack-select-frame", mi_cmd_stack_select_frame, &mi_suppress_notification.user_selected_context), DEF_MI_CMD_MI ("symbol-list-lines", mi_cmd_symbol_list_lines), + DEF_MI_CMD_MI ("symbol-info-functions", mi_cmd_symbol_info_functions), + 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_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 91ce4cd..c2fd7d3 100644 --- a/gdb/mi/mi-cmds.h +++ b/gdb/mi/mi-cmds.h @@ -94,6 +94,9 @@ 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_types; +extern mi_cmd_argv_ftype mi_cmd_symbol_info_variables; extern mi_cmd_argv_ftype mi_cmd_target_detach; extern mi_cmd_argv_ftype mi_cmd_target_file_get; extern mi_cmd_argv_ftype mi_cmd_target_file_put; diff --git a/gdb/mi/mi-symbol-cmds.c b/gdb/mi/mi-symbol-cmds.c index 63142e8..52d4c64 100644 --- a/gdb/mi/mi-symbol-cmds.c +++ b/gdb/mi/mi-symbol-cmds.c @@ -21,6 +21,8 @@ #include "symtab.h" #include "objfiles.h" #include "ui-out.h" +#include "source.h" +#include "mi-getopt.h" /* Print the list of all pc addresses and lines of code for the provided (full or base) source file name. The entries are sorted @@ -59,3 +61,210 @@ uiout->field_signed ("line", SYMTAB_LINETABLE (s)->item[i].line); } } + +/* Used by the -symbol-info-* and -symbol-info-module-* commands to print + information about the symbol SYM in a block of index BLOCK (either + GLOBAL_BLOCK or STATIC_BLOCK). KIND is the kind of symbol we searched + for in order to find SYM, which impact which fields are displayed in the + results. */ + +static void +output_debug_symbol (ui_out *uiout, enum search_domain kind, + struct symbol *sym, int block) +{ + ui_out_emit_tuple tuple_emitter (uiout, NULL); + + if (SYMBOL_LINE (sym) != 0) + uiout->field_unsigned ("line", SYMBOL_LINE (sym)); + uiout->field_string ("name", sym->print_name ()); + + if (kind == FUNCTIONS_DOMAIN || kind == VARIABLES_DOMAIN) + { + string_file tmp_stream; + type_print (SYMBOL_TYPE (sym), "", &tmp_stream, -1); + uiout->field_string ("type", tmp_stream.string ()); + + std::string str = symbol_to_info_string (sym, block, kind); + uiout->field_string ("description", str.c_str ()); + } +} + +/* Actually output one nondebug symbol, puts a tuple emitter in place + and then outputs the fields for this msymbol. */ + +static void +output_nondebug_symbol (ui_out *uiout, + const struct bound_minimal_symbol &msymbol) +{ + struct gdbarch *gdbarch = get_objfile_arch (msymbol.objfile); + ui_out_emit_tuple tuple_emitter (uiout, NULL); + + uiout->field_core_addr ("address", gdbarch, + BMSYMBOL_VALUE_ADDRESS (msymbol)); + uiout->field_string ("name", msymbol.minsym->print_name ()); +} + +/* This is the guts of the commands '-symbol-info-functions', + '-symbol-info-variables', and '-symbol-info-types'. It searches for + symbols matching KING, REGEXP, T_REGEXP, and EXCLUDE_MINSYMS, and then + prints the matching [m]symbols in an MI structured format. */ + +static void +mi_symbol_info (enum search_domain kind, const char *regexp, + const char *t_regexp, bool exclude_minsyms) +{ + global_symbol_searcher sym_search (kind, regexp); + sym_search.set_symbol_type_regexp (t_regexp); + sym_search.set_exclude_minsyms (exclude_minsyms); + std::vector symbols = sym_search.search (); + ui_out *uiout = current_uiout; + int i = 0; + + ui_out_emit_tuple outer_symbols_emitter (uiout, "symbols"); + + /* Debug symbols are placed first. */ + if (i < symbols.size () && symbols[i].msymbol.minsym == nullptr) + { + ui_out_emit_list debug_symbols_list_emitter (uiout, "debug"); + + /* As long as we have debug symbols... */ + while (i < symbols.size () && symbols[i].msymbol.minsym == nullptr) + { + symtab *symtab = symbol_symtab (symbols[i].symbol); + ui_out_emit_tuple symtab_tuple_emitter (uiout, nullptr); + + uiout->field_string ("filename", + symtab_to_filename_for_display (symtab)); + uiout->field_string ("fullname", symtab_to_fullname (symtab)); + + ui_out_emit_list symbols_list_emitter (uiout, "symbols"); + + /* As long as we have debug symbols from this symtab... */ + for (; (i < symbols.size () + && symbols[i].msymbol.minsym == nullptr + && symbol_symtab (symbols[i].symbol) == symtab); + ++i) + { + symbol_search &s = symbols[i]; + + output_debug_symbol(uiout, kind, s.symbol, s.block); + } + } + } + + /* Non-debug symbols are placed after. */ + if (i < symbols.size ()) + { + ui_out_emit_list nondebug_symbols_list_emitter (uiout, "nondebug"); + + /* As long as we have nondebug symbols... */ + for (; i < symbols.size (); i++) + { + gdb_assert (symbols[i].msymbol.minsym != nullptr); + output_nondebug_symbol(uiout, symbols[i].msymbol); + } + } +} + +/* Helper for mi_cmd_symbol_info_{functions,variables} - depending on KIND. + Processes command line options from ARGV and ARGC. */ + +static void +mi_info_functions_or_variables (enum search_domain kind, char **argv, int argc) +{ + const char *regexp = nullptr; + const char *t_regexp = nullptr; + bool exclude_minsyms = true; + + enum opt + { + INCLUDE_NONDEBUG_OPT, TYPE_REGEXP_OPT, NAME_REGEXP_OPT + }; + static const struct mi_opt opts[] = + { + {"-include-nondebug" , INCLUDE_NONDEBUG_OPT, 0}, + {"-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-functions" : "-symbol-info-variables"); + int opt = mi_getopt (cmd_string, argc, argv, opts, &oind, &oarg); + if (opt < 0) + break; + switch ((enum opt) opt) + { + case INCLUDE_NONDEBUG_OPT: + exclude_minsyms = false; + break; + case TYPE_REGEXP_OPT: + t_regexp = oarg; + break; + case NAME_REGEXP_OPT: + regexp = oarg; + break; + } + } + + mi_symbol_info (kind, regexp, t_regexp, exclude_minsyms); +} + +/* Implement -symbol-info-functions command. */ + +void +mi_cmd_symbol_info_functions (const char *command, char **argv, int argc) +{ + mi_info_functions_or_variables (FUNCTIONS_DOMAIN, argv, argc); +} + +/* Implement -symbol-info-types command. */ + +void +mi_cmd_symbol_info_types (const char *command, char **argv, int argc) +{ + const char *regexp = nullptr; + + enum opt + { + NAME_REGEXP_OPT + }; + static const struct mi_opt opts[] = + { + {"-name", NAME_REGEXP_OPT, 1}, + { 0, 0, 0 } + }; + + int oind = 0; + char *oarg = nullptr; + + while (true) + { + int opt = mi_getopt ("-symbol-info-types", argc, argv, opts, + &oind, &oarg); + if (opt < 0) + break; + switch ((enum opt) opt) + { + case NAME_REGEXP_OPT: + regexp = oarg; + break; + } + } + + mi_symbol_info (TYPES_DOMAIN, regexp, nullptr, true); +} + +/* Implement -symbol-info-variables command. */ + +void +mi_cmd_symbol_info_variables (const char *command, char **argv, int argc) +{ + mi_info_functions_or_variables (VARIABLES_DOMAIN, argv, argc); +} diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog index d4c42bd..0855b2c 100644 --- a/gdb/testsuite/ChangeLog +++ b/gdb/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2019-11-26 Andrew Burgess + + * gdb.mi/mi-sym-info-1.c: New file. + * gdb.mi/mi-sym-info-2.c: New file. + * gdb.mi/mi-sym-info.exp: New file. + 2019-11-21 Peeter Joot * gdb.base/endianity.c: New test. diff --git a/gdb/testsuite/gdb.mi/mi-sym-info-1.c b/gdb/testsuite/gdb.mi/mi-sym-info-1.c new file mode 100644 index 0000000..9b6dc73 --- /dev/null +++ b/gdb/testsuite/gdb.mi/mi-sym-info-1.c @@ -0,0 +1,48 @@ +/* Copyright 2019 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +/* Function and variables declared in mi-sym-info-2.c. */ +extern float f2 (float arg); +extern int f3 (int arg); +extern int global_i2; +extern float global_f2; + +static int global_i1; +static float global_f1; + +typedef int my_int_t; + +static my_int_t +f1 (int arg1, int arg2) +{ + return arg1 + arg2; +} + +void +f4 (int *arg) +{ + (*arg)++; +} + +int +main () +{ + int v = f3 (4); + f4 (&v); + float tmp = f2 (1.0); + return f1 (3, v) + ((int) tmp); +} diff --git a/gdb/testsuite/gdb.mi/mi-sym-info-2.c b/gdb/testsuite/gdb.mi/mi-sym-info-2.c new file mode 100644 index 0000000..c80877d --- /dev/null +++ b/gdb/testsuite/gdb.mi/mi-sym-info-2.c @@ -0,0 +1,43 @@ +/* Copyright 2019 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +static int global_i1; +static float global_f1; +int global_i2; +int global_f2; + +typedef int another_int_t; +typedef float another_float_t; + +static another_float_t +f1 (int arg) +{ + return (float) arg; +} + +float +f2 (another_float_t arg) +{ + return arg + f1 (1); +} + +int +f3 (another_int_t arg) +{ + return arg + 2; +} + diff --git a/gdb/testsuite/gdb.mi/mi-sym-info.exp b/gdb/testsuite/gdb.mi/mi-sym-info.exp new file mode 100644 index 0000000..33fe865 --- /dev/null +++ b/gdb/testsuite/gdb.mi/mi-sym-info.exp @@ -0,0 +1,129 @@ +# Copyright 2019 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +# Test -symbol-info-functions, -symbol-info-variables, and +# -symbol-info-types. + +load_lib mi-support.exp +set MIFLAGS "-i=mi" + +standard_testfile mi-sym-info-1.c mi-sym-info-2.c + +if {[prepare_for_testing "failed to prepare" ${testfile} \ + [list $srcfile $srcfile2] {debug}]} { + return -1 +} + +gdb_exit +if {[mi_gdb_start]} { + continue +} + +mi_run_to_main + +set qstr "\"\[^\"\]+\"" +set fun_re "\{line=\"$decimal\",name=${qstr},type=${qstr},description=${qstr}\}" +set type_re "\{(?:line=\"$decimal\",)*name=${qstr}\}" +set sym_list "\\\[${fun_re}(?:,$fun_re)*\\\]" +set type_sym_list "\\\[${type_re}(?:,$type_re)*\\\]" +set symtab_re \ + "\{filename=${qstr},fullname=${qstr},symbols=${sym_list}\}" +set symtab_type_re \ + "\{filename=${qstr},fullname=${qstr},symbols=${type_sym_list}\}" +set debug_only_syms \ + "symbols=\{debug=\\\[${symtab_re}(?:,${symtab_re})*\\\]\}" +set all_syms \ + "symbols=\{debug=\\\[${symtab_re}(?:,${symtab_re})*\\\],nondebug=\\\[.*\\\]\}" +set type_syms \ + "symbols=\{debug=\\\[${symtab_type_re}(?:,${symtab_type_re})*\\\]\}" + +# Fetch all functions, variables and types without any non-debug +# symbols. +mi_gdb_test "111-symbol-info-functions" \ + "111\\^done,${debug_only_syms}" \ + "List all functions from debug information only" + +mi_gdb_test "112-symbol-info-variables" \ + "112\\^done,${debug_only_syms}" \ + "List all variables from debug information only" + +mi_gdb_test "113-symbol-info-types" \ + "113\\^done,${type_syms}" \ + "List all types" + +# Fetch functions and variables but also grab the non-debug symbols +# (from the symbol table). There's often so much output output from +# this command that we overflow expect's buffers, avoid this by +# fetching the output piece by piece. +set testname "List all functions" +gdb_test_multiple "114-symbol-info-functions --include-nondebug" ${testname} { + -re "114\\^done,symbols=\{debug=\\\[${symtab_re}(?:,${symtab_re})*\\\],nondebug=\\\[" { + exp_continue + } + + -re "\{address=${qstr},name=${qstr}\}," { + exp_continue + } + + -re "\{address=${qstr},name=${qstr}\}\\\]\}\r\n${mi_gdb_prompt}$" { + pass ${testname} + } +} + +set testname "List all variables" +gdb_test_multiple "115-symbol-info-variables --include-nondebug" ${testname} { + -re "115\\^done,symbols=\{debug=\\\[${symtab_re}(?:,${symtab_re})*\\\],nondebug=\\\[" { + verbose -log "Got the first part of the input" + exp_continue + } + + -re "\{address=${qstr},name=${qstr}\}," { + exp_continue + } + + -re "\{address=${qstr},name=${qstr}\}\\\]\}\r\n${mi_gdb_prompt}$" { + pass ${testname} + } +} + +# Filter functions by name and type. +set lineno [gdb_get_line_number "f3 (another_int_t arg)" ${srcfile2}] +mi_gdb_test "116-symbol-info-functions --name f3" \ + "116\\^done,symbols=\{debug=\\\[\{filename=\"\[^\"\]+$srcfile2\",fullname=\"\[^\"\]+$srcfile2\",symbols=\\\[\{line=\"39\",name=\"f3\",type=\"int \\(another_int_t\\)\",description=\"int f3\\(another_int_t\\);\"\}\\\]\}\\\]\}" \ + "List all functions matching pattern f3" + +set lineno [gdb_get_line_number "f4 (int *arg)" ${srcfile}] +mi_gdb_test "117-symbol-info-functions --type void" \ + "117\\^done,symbols=\{debug=\\\[\{filename=\"\[^\"\]+$srcfile\",fullname=\"\[^\"\]+$srcfile\",symbols=\\\[\{line=\"36\",name=\"f4\",type=\"void \\(int \\*\\)\",description=\"void f4\\(int \\*\\);\"\}\\\]\}\\\]\}" \ + "List all functions matching type void" + +# Filter variables by name and type. +set lineno [gdb_get_line_number "int global_f2;" ${srcfile2}] +mi_gdb_test "118-symbol-info-variables --name global_f2" \ + "118\\^done,symbols=\{debug=\\\[\{filename=\"\[^\"\]+$srcfile2\",fullname=\"\[^\"\]+$srcfile2\",symbols=\\\[\{line=\"21\",name=\"global_f2\",type=\"int\",description=\"int global_f2;\"\}\\\]\}\\\]\}" \ + "List all variables matching pattern global_f2" + +set lineno1 [gdb_get_line_number "static float global_f1;" ${srcfile}] +set lineno2 [gdb_get_line_number "static float global_f1;" ${srcfile2}] +mi_gdb_test "119-symbol-info-variables --type float" \ + "119\\^done,symbols=\{debug=\\\[\{filename=\"\[^\"\]+$srcfile\",fullname=\"\[^\"\]+$srcfile\",symbols=\\\[\{line=\"25\",name=\"global_f1\",type=\"float\",description=\"static float global_f1;\"\}\\\]\},\{filename=\"\[^\"\]+$srcfile2\",fullname=\"\[^\"\]+$srcfile2\",symbols=\\\[\{line=\"19\",name=\"global_f1\",type=\"float\",description=\"static float global_f1;\"\}\\\]\}\\\]\}" \ + "List all variables matching type float" + +# Fetch types, filtering by name. +set lineno1 [gdb_get_line_number "typedef int my_int_t;" ${srcfile}] +set lineno2 [gdb_get_line_number "typedef int another_int_t;" ${srcfile2}] +mi_gdb_test "120-symbol-info-types --name _int_" \ + "120\\^done,symbols=\{debug=\\\[\{filename=\"\[^\"\]+$srcfile\",fullname=\"\[^\"\]+$srcfile\",symbols=\\\[\{line=\"27\",name=\"my_int_t\"\}\\\]\},\{filename=\"\[^\"\]+$srcfile2\",fullname=\"\[^\"\]+$srcfile2\",symbols=\\\[\{line=\"23\",name=\"another_int_t\"\}\\\]\}\\\]\}" \ + "List all types matching _int_"