Commit | Line | Data |
---|---|---|
0d18235f | 1 | /* MI Command Set - symbol commands. |
42a4f53d | 2 | Copyright (C) 2003-2019 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 | 31 | void |
9f33b8b7 | 32 | mi_cmd_symbol_list_lines (const char *command, char **argv, int argc) |
0d18235f | 33 | { |
5af949e3 | 34 | struct gdbarch *gdbarch; |
0d18235f JB |
35 | char *filename; |
36 | struct symtab *s; | |
37 | int i; | |
79a45e25 | 38 | struct ui_out *uiout = current_uiout; |
0d18235f JB |
39 | |
40 | if (argc != 1) | |
1b05df00 | 41 | error (_("-symbol-list-lines: Usage: SOURCE_FILENAME")); |
0d18235f JB |
42 | |
43 | filename = argv[0]; | |
44 | s = lookup_symtab (filename); | |
45 | ||
46 | if (s == NULL) | |
1b05df00 | 47 | error (_("-symbol-list-lines: Unknown source file name.")); |
0d18235f | 48 | |
2b03b41d SS |
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. */ | |
0d18235f | 52 | |
eb822aa6 | 53 | gdbarch = get_objfile_arch (SYMTAB_OBJFILE (s)); |
0d18235f | 54 | |
10f489e5 | 55 | ui_out_emit_list list_emitter (uiout, "lines"); |
8435453b DE |
56 | if (SYMTAB_LINETABLE (s) != NULL && SYMTAB_LINETABLE (s)->nitems > 0) |
57 | for (i = 0; i < SYMTAB_LINETABLE (s)->nitems; i++) | |
0d18235f | 58 | { |
2e783024 | 59 | ui_out_emit_tuple tuple_emitter (uiout, NULL); |
112e8700 | 60 | uiout->field_core_addr ("pc", gdbarch, SYMTAB_LINETABLE (s)->item[i].pc); |
381befee | 61 | uiout->field_signed ("line", SYMTAB_LINETABLE (s)->item[i].line); |
0d18235f | 62 | } |
0d18235f | 63 | } |
7dc42066 AB |
64 | |
65 | /* Used by the -symbol-info-* and -symbol-info-module-* commands to print | |
66 | information about the symbol SYM in a block of index BLOCK (either | |
67 | GLOBAL_BLOCK or STATIC_BLOCK). KIND is the kind of symbol we searched | |
68 | for in order to find SYM, which impact which fields are displayed in the | |
69 | results. */ | |
70 | ||
71 | static void | |
72 | output_debug_symbol (ui_out *uiout, enum search_domain kind, | |
73 | struct symbol *sym, int block) | |
74 | { | |
75 | ui_out_emit_tuple tuple_emitter (uiout, NULL); | |
76 | ||
77 | if (SYMBOL_LINE (sym) != 0) | |
78 | uiout->field_unsigned ("line", SYMBOL_LINE (sym)); | |
79 | uiout->field_string ("name", sym->print_name ()); | |
80 | ||
81 | if (kind == FUNCTIONS_DOMAIN || kind == VARIABLES_DOMAIN) | |
82 | { | |
83 | string_file tmp_stream; | |
84 | type_print (SYMBOL_TYPE (sym), "", &tmp_stream, -1); | |
85 | uiout->field_string ("type", tmp_stream.string ()); | |
86 | ||
87 | std::string str = symbol_to_info_string (sym, block, kind); | |
88 | uiout->field_string ("description", str); | |
89 | } | |
90 | } | |
91 | ||
92 | /* Actually output one nondebug symbol, puts a tuple emitter in place | |
93 | and then outputs the fields for this msymbol. */ | |
94 | ||
95 | static void | |
96 | output_nondebug_symbol (ui_out *uiout, | |
97 | const struct bound_minimal_symbol &msymbol) | |
98 | { | |
99 | struct gdbarch *gdbarch = get_objfile_arch (msymbol.objfile); | |
100 | ui_out_emit_tuple tuple_emitter (uiout, NULL); | |
101 | ||
102 | uiout->field_core_addr ("address", gdbarch, | |
103 | BMSYMBOL_VALUE_ADDRESS (msymbol)); | |
104 | uiout->field_string ("name", msymbol.minsym->print_name ()); | |
105 | } | |
106 | ||
107 | /* This is the guts of the commands '-symbol-info-functions', | |
108 | '-symbol-info-variables', and '-symbol-info-types'. It searches for | |
109 | symbols matching KING, NAME_REGEXP, TYPE_REGEXP, and EXCLUDE_MINSYMS, | |
110 | and then prints the matching [m]symbols in an MI structured format. */ | |
111 | ||
112 | static void | |
113 | mi_symbol_info (enum search_domain kind, const char *name_regexp, | |
114 | const char *type_regexp, bool exclude_minsyms) | |
115 | { | |
116 | global_symbol_searcher sym_search (kind, name_regexp); | |
117 | sym_search.set_symbol_type_regexp (type_regexp); | |
118 | sym_search.set_exclude_minsyms (exclude_minsyms); | |
119 | std::vector<symbol_search> symbols = sym_search.search (); | |
120 | ui_out *uiout = current_uiout; | |
121 | int i = 0; | |
122 | ||
123 | ui_out_emit_tuple outer_symbols_emitter (uiout, "symbols"); | |
124 | ||
125 | /* Debug symbols are placed first. */ | |
126 | if (i < symbols.size () && symbols[i].msymbol.minsym == nullptr) | |
127 | { | |
128 | ui_out_emit_list debug_symbols_list_emitter (uiout, "debug"); | |
129 | ||
130 | /* As long as we have debug symbols... */ | |
131 | while (i < symbols.size () && symbols[i].msymbol.minsym == nullptr) | |
132 | { | |
133 | symtab *symtab = symbol_symtab (symbols[i].symbol); | |
134 | ui_out_emit_tuple symtab_tuple_emitter (uiout, nullptr); | |
135 | ||
136 | uiout->field_string ("filename", | |
137 | symtab_to_filename_for_display (symtab)); | |
138 | uiout->field_string ("fullname", symtab_to_fullname (symtab)); | |
139 | ||
140 | ui_out_emit_list symbols_list_emitter (uiout, "symbols"); | |
141 | ||
142 | /* As long as we have debug symbols from this symtab... */ | |
143 | for (; (i < symbols.size () | |
144 | && symbols[i].msymbol.minsym == nullptr | |
145 | && symbol_symtab (symbols[i].symbol) == symtab); | |
146 | ++i) | |
147 | { | |
148 | symbol_search &s = symbols[i]; | |
149 | ||
150 | output_debug_symbol (uiout, kind, s.symbol, s.block); | |
151 | } | |
152 | } | |
153 | } | |
154 | ||
155 | /* Non-debug symbols are placed after. */ | |
156 | if (i < symbols.size ()) | |
157 | { | |
158 | ui_out_emit_list nondebug_symbols_list_emitter (uiout, "nondebug"); | |
159 | ||
160 | /* As long as we have nondebug symbols... */ | |
161 | for (; i < symbols.size (); i++) | |
162 | { | |
163 | gdb_assert (symbols[i].msymbol.minsym != nullptr); | |
164 | output_nondebug_symbol (uiout, symbols[i].msymbol); | |
165 | } | |
166 | } | |
167 | } | |
168 | ||
169 | /* Helper for mi_cmd_symbol_info_{functions,variables} - depending on KIND. | |
170 | Processes command line options from ARGV and ARGC. */ | |
171 | ||
172 | static void | |
173 | mi_info_functions_or_variables (enum search_domain kind, char **argv, int argc) | |
174 | { | |
175 | const char *regexp = nullptr; | |
176 | const char *t_regexp = nullptr; | |
177 | bool exclude_minsyms = true; | |
178 | ||
179 | enum opt | |
180 | { | |
181 | INCLUDE_NONDEBUG_OPT, TYPE_REGEXP_OPT, NAME_REGEXP_OPT | |
182 | }; | |
183 | static const struct mi_opt opts[] = | |
184 | { | |
185 | {"-include-nondebug" , INCLUDE_NONDEBUG_OPT, 0}, | |
186 | {"-type", TYPE_REGEXP_OPT, 1}, | |
187 | {"-name", NAME_REGEXP_OPT, 1}, | |
188 | { 0, 0, 0 } | |
189 | }; | |
190 | ||
191 | int oind = 0; | |
192 | char *oarg = nullptr; | |
193 | ||
194 | while (1) | |
195 | { | |
196 | const char *cmd_string | |
197 | = ((kind == FUNCTIONS_DOMAIN) | |
198 | ? "-symbol-info-functions" : "-symbol-info-variables"); | |
199 | int opt = mi_getopt (cmd_string, argc, argv, opts, &oind, &oarg); | |
200 | if (opt < 0) | |
201 | break; | |
202 | switch ((enum opt) opt) | |
203 | { | |
204 | case INCLUDE_NONDEBUG_OPT: | |
205 | exclude_minsyms = false; | |
206 | break; | |
207 | case TYPE_REGEXP_OPT: | |
208 | t_regexp = oarg; | |
209 | break; | |
210 | case NAME_REGEXP_OPT: | |
211 | regexp = oarg; | |
212 | break; | |
213 | } | |
214 | } | |
215 | ||
216 | mi_symbol_info (kind, regexp, t_regexp, exclude_minsyms); | |
217 | } | |
218 | ||
219 | /* Implement -symbol-info-functions command. */ | |
220 | ||
221 | void | |
222 | mi_cmd_symbol_info_functions (const char *command, char **argv, int argc) | |
223 | { | |
224 | mi_info_functions_or_variables (FUNCTIONS_DOMAIN, argv, argc); | |
225 | } | |
226 | ||
227 | /* Implement -symbol-info-types command. */ | |
228 | ||
229 | void | |
230 | mi_cmd_symbol_info_types (const char *command, char **argv, int argc) | |
231 | { | |
232 | const char *regexp = nullptr; | |
233 | ||
234 | enum opt | |
235 | { | |
236 | NAME_REGEXP_OPT | |
237 | }; | |
238 | static const struct mi_opt opts[] = | |
239 | { | |
240 | {"-name", NAME_REGEXP_OPT, 1}, | |
241 | { 0, 0, 0 } | |
242 | }; | |
243 | ||
244 | int oind = 0; | |
245 | char *oarg = nullptr; | |
246 | ||
247 | while (true) | |
248 | { | |
249 | int opt = mi_getopt ("-symbol-info-types", argc, argv, opts, | |
250 | &oind, &oarg); | |
251 | if (opt < 0) | |
252 | break; | |
253 | switch ((enum opt) opt) | |
254 | { | |
255 | case NAME_REGEXP_OPT: | |
256 | regexp = oarg; | |
257 | break; | |
258 | } | |
259 | } | |
260 | ||
261 | mi_symbol_info (TYPES_DOMAIN, regexp, nullptr, true); | |
262 | } | |
263 | ||
264 | /* Implement -symbol-info-variables command. */ | |
265 | ||
266 | void | |
267 | mi_cmd_symbol_info_variables (const char *command, char **argv, int argc) | |
268 | { | |
269 | mi_info_functions_or_variables (VARIABLES_DOMAIN, argv, argc); | |
270 | } |