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