]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - gdb/mi/mi-symbol-cmds.c
Update copyright year range in header of all files managed by GDB
[thirdparty/binutils-gdb.git] / gdb / mi / mi-symbol-cmds.c
CommitLineData
0d18235f 1/* MI Command Set - symbol commands.
1d506c26 2 Copyright (C) 2003-2024 Free Software Foundation, Inc.
0d18235f
JB
3
4 This file is part of GDB.
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
a9762ec7 8 the Free Software Foundation; either version 3 of the License, or
0d18235f
JB
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
a9762ec7 17 along with this program. If not, see <http://www.gnu.org/licenses/>. */
0d18235f
JB
18
19#include "defs.h"
20#include "mi-cmds.h"
21#include "symtab.h"
5af949e3 22#include "objfiles.h"
0d18235f 23#include "ui-out.h"
7dc42066
AB
24#include "source.h"
25#include "mi-getopt.h"
0d18235f 26
2b03b41d
SS
27/* Print the list of all pc addresses and lines of code for the
28 provided (full or base) source file name. The entries are sorted
29 in ascending PC order. */
0d18235f 30
ce8f13f8 31void
9158e49a
TT
32mi_cmd_symbol_list_lines (const char *command, const char *const *argv,
33 int argc)
0d18235f 34{
5af949e3 35 struct gdbarch *gdbarch;
9158e49a 36 const char *filename;
0d18235f
JB
37 struct symtab *s;
38 int i;
79a45e25 39 struct ui_out *uiout = current_uiout;
0d18235f
JB
40
41 if (argc != 1)
1b05df00 42 error (_("-symbol-list-lines: Usage: SOURCE_FILENAME"));
0d18235f
JB
43
44 filename = argv[0];
45 s = lookup_symtab (filename);
46
47 if (s == NULL)
1b05df00 48 error (_("-symbol-list-lines: Unknown source file name."));
0d18235f 49
2b03b41d
SS
50 /* Now, dump the associated line table. The pc addresses are
51 already sorted by increasing values in the symbol table, so no
52 need to perform any other sorting. */
0d18235f 53
1acc9dca
TT
54 struct objfile *objfile = s->compunit ()->objfile ();
55 gdbarch = objfile->arch ();
0d18235f 56
10f489e5 57 ui_out_emit_list list_emitter (uiout, "lines");
5b607461
SM
58 if (s->linetable () != NULL && s->linetable ()->nitems > 0)
59 for (i = 0; i < s->linetable ()->nitems; i++)
01add95b
SM
60 {
61 ui_out_emit_tuple tuple_emitter (uiout, NULL);
1acc9dca
TT
62 uiout->field_core_addr ("pc", gdbarch,
63 s->linetable ()->item[i].pc (objfile));
5b607461 64 uiout->field_signed ("line", s->linetable ()->item[i].line);
01add95b 65 }
0d18235f 66}
7dc42066
AB
67
68/* Used by the -symbol-info-* and -symbol-info-module-* commands to print
69 information about the symbol SYM in a block of index BLOCK (either
70 GLOBAL_BLOCK or STATIC_BLOCK). KIND is the kind of symbol we searched
71 for in order to find SYM, which impact which fields are displayed in the
72 results. */
73
74static void
75output_debug_symbol (ui_out *uiout, enum search_domain kind,
76 struct symbol *sym, int block)
77{
78 ui_out_emit_tuple tuple_emitter (uiout, NULL);
79
5d0027b9
SM
80 if (sym->line () != 0)
81 uiout->field_unsigned ("line", sym->line ());
7dc42066
AB
82 uiout->field_string ("name", sym->print_name ());
83
84 if (kind == FUNCTIONS_DOMAIN || kind == VARIABLES_DOMAIN)
85 {
86 string_file tmp_stream;
5f9c5a63 87 type_print (sym->type (), "", &tmp_stream, -1);
7dc42066
AB
88 uiout->field_string ("type", tmp_stream.string ());
89
90 std::string str = symbol_to_info_string (sym, block, kind);
91 uiout->field_string ("description", str);
92 }
93}
94
95/* Actually output one nondebug symbol, puts a tuple emitter in place
96 and then outputs the fields for this msymbol. */
97
98static void
99output_nondebug_symbol (ui_out *uiout,
100 const struct bound_minimal_symbol &msymbol)
101{
08feed99 102 struct gdbarch *gdbarch = msymbol.objfile->arch ();
7dc42066
AB
103 ui_out_emit_tuple tuple_emitter (uiout, NULL);
104
105 uiout->field_core_addr ("address", gdbarch,
4aeddc50 106 msymbol.value_address ());
7dc42066
AB
107 uiout->field_string ("name", msymbol.minsym->print_name ());
108}
109
110/* This is the guts of the commands '-symbol-info-functions',
111 '-symbol-info-variables', and '-symbol-info-types'. It searches for
112 symbols matching KING, NAME_REGEXP, TYPE_REGEXP, and EXCLUDE_MINSYMS,
113 and then prints the matching [m]symbols in an MI structured format. */
114
115static void
116mi_symbol_info (enum search_domain kind, const char *name_regexp,
c2512106
AB
117 const char *type_regexp, bool exclude_minsyms,
118 size_t max_results)
7dc42066
AB
119{
120 global_symbol_searcher sym_search (kind, name_regexp);
121 sym_search.set_symbol_type_regexp (type_regexp);
122 sym_search.set_exclude_minsyms (exclude_minsyms);
c2512106 123 sym_search.set_max_search_results (max_results);
7dc42066
AB
124 std::vector<symbol_search> symbols = sym_search.search ();
125 ui_out *uiout = current_uiout;
126 int i = 0;
127
128 ui_out_emit_tuple outer_symbols_emitter (uiout, "symbols");
129
130 /* Debug symbols are placed first. */
131 if (i < symbols.size () && symbols[i].msymbol.minsym == nullptr)
132 {
133 ui_out_emit_list debug_symbols_list_emitter (uiout, "debug");
134
135 /* As long as we have debug symbols... */
136 while (i < symbols.size () && symbols[i].msymbol.minsym == nullptr)
137 {
4206d69e 138 symtab *symtab = symbols[i].symbol->symtab ();
7dc42066
AB
139 ui_out_emit_tuple symtab_tuple_emitter (uiout, nullptr);
140
141 uiout->field_string ("filename",
142 symtab_to_filename_for_display (symtab));
143 uiout->field_string ("fullname", symtab_to_fullname (symtab));
144
145 ui_out_emit_list symbols_list_emitter (uiout, "symbols");
146
147 /* As long as we have debug symbols from this symtab... */
148 for (; (i < symbols.size ()
149 && symbols[i].msymbol.minsym == nullptr
4206d69e 150 && symbols[i].symbol->symtab () == symtab);
7dc42066
AB
151 ++i)
152 {
153 symbol_search &s = symbols[i];
154
155 output_debug_symbol (uiout, kind, s.symbol, s.block);
156 }
157 }
158 }
159
160 /* Non-debug symbols are placed after. */
161 if (i < symbols.size ())
162 {
163 ui_out_emit_list nondebug_symbols_list_emitter (uiout, "nondebug");
164
165 /* As long as we have nondebug symbols... */
166 for (; i < symbols.size (); i++)
167 {
168 gdb_assert (symbols[i].msymbol.minsym != nullptr);
169 output_nondebug_symbol (uiout, symbols[i].msymbol);
170 }
171 }
172}
173
c2512106
AB
174/* Helper to parse the option text from an -max-results argument and return
175 the parsed value. If the text can't be parsed then an error is thrown. */
176
177static size_t
9158e49a 178parse_max_results_option (const char *arg)
c2512106 179{
9158e49a 180 char *ptr;
c2512106
AB
181 long long val = strtoll (arg, &ptr, 10);
182 if (arg == ptr || *ptr != '\0' || val > SIZE_MAX || val < 0)
183 error (_("invalid value for --max-results argument"));
184 size_t max_results = (size_t) val;
185
186 return max_results;
187}
188
7dc42066
AB
189/* Helper for mi_cmd_symbol_info_{functions,variables} - depending on KIND.
190 Processes command line options from ARGV and ARGC. */
191
192static void
9158e49a
TT
193mi_info_functions_or_variables (enum search_domain kind,
194 const char *const *argv, int argc)
7dc42066 195{
c2512106 196 size_t max_results = SIZE_MAX;
7dc42066
AB
197 const char *regexp = nullptr;
198 const char *t_regexp = nullptr;
199 bool exclude_minsyms = true;
200
201 enum opt
202 {
c2512106 203 INCLUDE_NONDEBUG_OPT, TYPE_REGEXP_OPT, NAME_REGEXP_OPT, MAX_RESULTS_OPT
7dc42066
AB
204 };
205 static const struct mi_opt opts[] =
206 {
207 {"-include-nondebug" , INCLUDE_NONDEBUG_OPT, 0},
208 {"-type", TYPE_REGEXP_OPT, 1},
209 {"-name", NAME_REGEXP_OPT, 1},
c2512106 210 {"-max-results", MAX_RESULTS_OPT, 1},
7dc42066
AB
211 { 0, 0, 0 }
212 };
213
214 int oind = 0;
9158e49a 215 const char *oarg = nullptr;
7dc42066
AB
216
217 while (1)
218 {
219 const char *cmd_string
220 = ((kind == FUNCTIONS_DOMAIN)
221 ? "-symbol-info-functions" : "-symbol-info-variables");
222 int opt = mi_getopt (cmd_string, argc, argv, opts, &oind, &oarg);
223 if (opt < 0)
224 break;
225 switch ((enum opt) opt)
226 {
227 case INCLUDE_NONDEBUG_OPT:
228 exclude_minsyms = false;
229 break;
230 case TYPE_REGEXP_OPT:
231 t_regexp = oarg;
232 break;
233 case NAME_REGEXP_OPT:
234 regexp = oarg;
235 break;
c2512106
AB
236 case MAX_RESULTS_OPT:
237 max_results = parse_max_results_option (oarg);
238 break;
7dc42066
AB
239 }
240 }
241
c2512106 242 mi_symbol_info (kind, regexp, t_regexp, exclude_minsyms, max_results);
7dc42066
AB
243}
244
293b38d6
AB
245/* Type for an iterator over a vector of module_symbol_search results. */
246typedef std::vector<module_symbol_search>::const_iterator
247 module_symbol_search_iterator;
248
249/* Helper for mi_info_module_functions_or_variables. Display the results
250 from ITER up to END or until we find a symbol that is in a different
251 module, or in a different symtab than the first symbol we print. Update
252 and return the new value for ITER. */
253static module_symbol_search_iterator
254output_module_symbols_in_single_module_and_file
255 (struct ui_out *uiout, module_symbol_search_iterator iter,
256 const module_symbol_search_iterator end, enum search_domain kind)
257{
258 /* The symbol for the module in which the first result resides. */
259 const symbol *first_module_symbol = iter->first.symbol;
260
261 /* The symbol for the first result, and the symtab in which it resides. */
262 const symbol *first_result_symbol = iter->second.symbol;
4206d69e 263 symtab *first_symbtab = first_result_symbol->symtab ();
293b38d6
AB
264
265 /* Formatted output. */
266 ui_out_emit_tuple current_file (uiout, nullptr);
267 uiout->field_string ("filename",
268 symtab_to_filename_for_display (first_symbtab));
269 uiout->field_string ("fullname", symtab_to_fullname (first_symbtab));
270 ui_out_emit_list item_list (uiout, "symbols");
271
272 /* Repeatedly output result symbols until either we run out of symbols,
273 we change module, or we change symtab. */
274 for (; (iter != end
275 && first_module_symbol == iter->first.symbol
4206d69e 276 && first_symbtab == iter->second.symbol->symtab ());
293b38d6
AB
277 ++iter)
278 output_debug_symbol (uiout, kind, iter->second.symbol,
279 iter->second.block);
280
281 return iter;
282}
283
284/* Helper for mi_info_module_functions_or_variables. Display the results
285 from ITER up to END or until we find a symbol that is in a different
286 module than the first symbol we print. Update and return the new value
287 for ITER. */
288static module_symbol_search_iterator
289output_module_symbols_in_single_module
290 (struct ui_out *uiout, module_symbol_search_iterator iter,
291 const module_symbol_search_iterator end, enum search_domain kind)
292{
293 gdb_assert (iter->first.symbol != nullptr);
294 gdb_assert (iter->second.symbol != nullptr);
295
296 /* The symbol for the module in which the first result resides. */
297 const symbol *first_module_symbol = iter->first.symbol;
298
299 /* Create output formatting. */
300 ui_out_emit_tuple module_tuple (uiout, nullptr);
301 uiout->field_string ("module", first_module_symbol->print_name ());
302 ui_out_emit_list files_list (uiout, "files");
303
304 /* The results are sorted so that symbols within the same file are next
305 to each other in the list. Calling the output function once will
306 print all results within a single file. We keep calling the output
307 function until we change module. */
308 while (iter != end && first_module_symbol == iter->first.symbol)
309 iter = output_module_symbols_in_single_module_and_file (uiout, iter,
310 end, kind);
311 return iter;
312}
313
314/* Core of -symbol-info-module-functions and -symbol-info-module-variables.
315 KIND indicates what we are searching for, and ARGV and ARGC are the
316 command line options passed to the MI command. */
317
318static void
319mi_info_module_functions_or_variables (enum search_domain kind,
9158e49a 320 const char *const *argv, int argc)
293b38d6
AB
321{
322 const char *module_regexp = nullptr;
323 const char *regexp = nullptr;
324 const char *type_regexp = nullptr;
325
326 /* Process the command line options. */
327
328 enum opt
329 {
330 MODULE_REGEXP_OPT, TYPE_REGEXP_OPT, NAME_REGEXP_OPT
331 };
332 static const struct mi_opt opts[] =
333 {
334 {"-module", MODULE_REGEXP_OPT, 1},
335 {"-type", TYPE_REGEXP_OPT, 1},
336 {"-name", NAME_REGEXP_OPT, 1},
337 { 0, 0, 0 }
338 };
339
340 int oind = 0;
9158e49a 341 const char *oarg = nullptr;
293b38d6
AB
342
343 while (1)
344 {
345 const char *cmd_string
346 = ((kind == FUNCTIONS_DOMAIN)
347 ? "-symbol-info-module-functions"
348 : "-symbol-info-module-variables");
349 int opt = mi_getopt (cmd_string, argc, argv, opts, &oind, &oarg);
350 if (opt < 0)
351 break;
352 switch ((enum opt) opt)
353 {
354 case MODULE_REGEXP_OPT:
355 module_regexp = oarg;
356 break;
357 case TYPE_REGEXP_OPT:
358 type_regexp = oarg;
359 break;
360 case NAME_REGEXP_OPT:
361 regexp = oarg;
362 break;
363 }
364 }
365
366 std::vector<module_symbol_search> module_symbols
367 = search_module_symbols (module_regexp, regexp, type_regexp, kind);
368
369 struct ui_out *uiout = current_uiout;
370 ui_out_emit_list all_matching_symbols (uiout, "symbols");
371
372 /* The results in the module_symbols list are ordered so symbols in the
373 same module are next to each other. Repeatedly call the output
374 function to print sequences of symbols that are in the same module
375 until we have no symbols left to print. */
376 module_symbol_search_iterator iter = module_symbols.begin ();
377 const module_symbol_search_iterator end = module_symbols.end ();
378 while (iter != end)
379 iter = output_module_symbols_in_single_module (uiout, iter, end, kind);
380}
381
7dc42066
AB
382/* Implement -symbol-info-functions command. */
383
384void
9158e49a
TT
385mi_cmd_symbol_info_functions (const char *command, const char *const *argv,
386 int argc)
7dc42066
AB
387{
388 mi_info_functions_or_variables (FUNCTIONS_DOMAIN, argv, argc);
389}
390
293b38d6
AB
391/* Implement -symbol-info-module-functions command. */
392
393void
9158e49a
TT
394mi_cmd_symbol_info_module_functions (const char *command,
395 const char *const *argv, int argc)
293b38d6
AB
396{
397 mi_info_module_functions_or_variables (FUNCTIONS_DOMAIN, argv, argc);
398}
399
400/* Implement -symbol-info-module-variables command. */
401
402void
9158e49a
TT
403mi_cmd_symbol_info_module_variables (const char *command,
404 const char *const *argv, int argc)
293b38d6
AB
405{
406 mi_info_module_functions_or_variables (VARIABLES_DOMAIN, argv, argc);
407}
408
db5960b4
AB
409/* Implement -symbol-inf-modules command. */
410
411void
9158e49a
TT
412mi_cmd_symbol_info_modules (const char *command, const char *const *argv,
413 int argc)
db5960b4 414{
c2512106 415 size_t max_results = SIZE_MAX;
db5960b4
AB
416 const char *regexp = nullptr;
417
418 enum opt
419 {
c2512106 420 NAME_REGEXP_OPT, MAX_RESULTS_OPT
db5960b4
AB
421 };
422 static const struct mi_opt opts[] =
423 {
424 {"-name", NAME_REGEXP_OPT, 1},
c2512106 425 {"-max-results", MAX_RESULTS_OPT, 1},
db5960b4
AB
426 { 0, 0, 0 }
427 };
428
429 int oind = 0;
9158e49a 430 const char *oarg = nullptr;
db5960b4
AB
431
432 while (1)
433 {
434 int opt = mi_getopt ("-symbol-info-modules", argc, argv, opts,
435 &oind, &oarg);
436 if (opt < 0)
437 break;
438 switch ((enum opt) opt)
439 {
440 case NAME_REGEXP_OPT:
441 regexp = oarg;
442 break;
c2512106
AB
443 case MAX_RESULTS_OPT:
444 max_results = parse_max_results_option (oarg);
445 break;
db5960b4
AB
446 }
447 }
448
c2512106 449 mi_symbol_info (MODULES_DOMAIN, regexp, nullptr, true, max_results);
db5960b4
AB
450}
451
7dc42066
AB
452/* Implement -symbol-info-types command. */
453
454void
9158e49a
TT
455mi_cmd_symbol_info_types (const char *command, const char *const *argv,
456 int argc)
7dc42066 457{
c2512106 458 size_t max_results = SIZE_MAX;
7dc42066
AB
459 const char *regexp = nullptr;
460
461 enum opt
462 {
c2512106 463 NAME_REGEXP_OPT, MAX_RESULTS_OPT
7dc42066
AB
464 };
465 static const struct mi_opt opts[] =
466 {
467 {"-name", NAME_REGEXP_OPT, 1},
c2512106 468 {"-max-results", MAX_RESULTS_OPT, 1},
7dc42066
AB
469 { 0, 0, 0 }
470 };
471
472 int oind = 0;
9158e49a 473 const char *oarg = nullptr;
7dc42066
AB
474
475 while (true)
476 {
477 int opt = mi_getopt ("-symbol-info-types", argc, argv, opts,
478 &oind, &oarg);
479 if (opt < 0)
480 break;
481 switch ((enum opt) opt)
482 {
483 case NAME_REGEXP_OPT:
484 regexp = oarg;
485 break;
c2512106
AB
486 case MAX_RESULTS_OPT:
487 max_results = parse_max_results_option (oarg);
488 break;
7dc42066
AB
489 }
490 }
491
c2512106 492 mi_symbol_info (TYPES_DOMAIN, regexp, nullptr, true, max_results);
7dc42066
AB
493}
494
495/* Implement -symbol-info-variables command. */
496
497void
9158e49a
TT
498mi_cmd_symbol_info_variables (const char *command, const char *const *argv,
499 int argc)
7dc42066
AB
500{
501 mi_info_functions_or_variables (VARIABLES_DOMAIN, argv, argc);
502}