Fix ARI violations in c++compile
[deliverable/binutils-gdb.git] / gdb / compile / compile-cplus-symbols.c
CommitLineData
078a0207
KS
1/* Convert symbols from GDB to GCC
2
3 Copyright (C) 2014-2018 Free Software Foundation, Inc.
4
5 This file is part of GDB.
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3 of the License, or
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program. If not, see <http://www.gnu.org/licenses/>. */
19
20
21#include "defs.h"
22#include "compile-internal.h"
23#include "compile-cplus.h"
24#include "gdb_assert.h"
25#include "symtab.h"
26#include "parser-defs.h"
27#include "block.h"
28#include "objfiles.h"
29#include "compile.h"
30#include "value.h"
31#include "exceptions.h"
32#include "gdbtypes.h"
33#include "dwarf2loc.h"
34#include "cp-support.h"
35#include "gdbcmd.h"
36#include "compile-c.h"
37
38/* Convert a given symbol, SYM, to the compiler's representation.
39 INSTANCE is the compiler instance. IS_GLOBAL is true if the
40 symbol came from the global scope. IS_LOCAL is true if the symbol
41 came from a local scope. (Note that the two are not strictly
42 inverses because the symbol might have come from the static
43 scope.) */
44
45static void
46convert_one_symbol (compile_cplus_instance *instance,
47 struct block_symbol sym, bool is_global, bool is_local)
48{
49 /* Squash compiler warning. */
50 gcc_type sym_type = 0;
51 const char *filename = symbol_symtab (sym.symbol)->filename;
52 unsigned short line = SYMBOL_LINE (sym.symbol);
53
54 instance->error_symbol_once (sym.symbol);
55
56 if (SYMBOL_CLASS (sym.symbol) == LOC_LABEL)
57 sym_type = 0;
58 else
59 sym_type = instance->convert_type (SYMBOL_TYPE (sym.symbol));
60
61 if (SYMBOL_DOMAIN (sym.symbol) == STRUCT_DOMAIN)
62 {
63 /* Nothing to do. */
64 }
65 else
66 {
67 /* Squash compiler warning. */
68 gcc_cp_symbol_kind_flags kind = GCC_CP_FLAG_BASE;
69 CORE_ADDR addr = 0;
70 std::string name;
71 gdb::unique_xmalloc_ptr<char> symbol_name;
72
73 switch (SYMBOL_CLASS (sym.symbol))
74 {
75 case LOC_TYPEDEF:
76 if (TYPE_CODE (SYMBOL_TYPE (sym.symbol)) == TYPE_CODE_TYPEDEF)
77 kind = GCC_CP_SYMBOL_TYPEDEF;
78 else if (TYPE_CODE (SYMBOL_TYPE (sym.symbol)) == TYPE_CODE_NAMESPACE)
79 return;
80 break;
81
82 case LOC_LABEL:
83 kind = GCC_CP_SYMBOL_LABEL;
84 addr = SYMBOL_VALUE_ADDRESS (sym.symbol);
85 break;
86
87 case LOC_BLOCK:
88 {
89 kind = GCC_CP_SYMBOL_FUNCTION;
90 addr = BLOCK_START (SYMBOL_BLOCK_VALUE (sym.symbol));
91 if (is_global && TYPE_GNU_IFUNC (SYMBOL_TYPE (sym.symbol)))
92 addr = gnu_ifunc_resolve_addr (target_gdbarch (), addr);
93 }
94 break;
95
96 case LOC_CONST:
97 if (TYPE_CODE (SYMBOL_TYPE (sym.symbol)) == TYPE_CODE_ENUM)
98 {
99 /* Already handled by convert_enum. */
100 return;
101 }
102 instance->plugin ().build_constant
103 (sym_type, SYMBOL_NATURAL_NAME (sym.symbol),
104 SYMBOL_VALUE (sym.symbol), filename, line);
105 return;
106
107 case LOC_CONST_BYTES:
108 error (_("Unsupported LOC_CONST_BYTES for symbol \"%s\"."),
109 SYMBOL_PRINT_NAME (sym.symbol));
110
111 case LOC_UNDEF:
112 internal_error (__FILE__, __LINE__, _("LOC_UNDEF found for \"%s\"."),
113 SYMBOL_PRINT_NAME (sym.symbol));
114
115 case LOC_COMMON_BLOCK:
116 error (_("Fortran common block is unsupported for compilation "
117 "evaluaton of symbol \"%s\"."),
118 SYMBOL_PRINT_NAME (sym.symbol));
119
120 case LOC_OPTIMIZED_OUT:
121 error (_("Symbol \"%s\" cannot be used for compilation evaluation "
122 "as it is optimized out."),
123 SYMBOL_PRINT_NAME (sym.symbol));
124
125 case LOC_COMPUTED:
126 if (is_local)
127 goto substitution;
128 /* Probably TLS here. */
129 warning (_("Symbol \"%s\" is thread-local and currently can only "
130 "be referenced from the current thread in "
131 "compiled code."),
132 SYMBOL_PRINT_NAME (sym.symbol));
133 /* FALLTHROUGH */
134 case LOC_UNRESOLVED:
135 /* 'symbol_name' cannot be used here as that one is used only for
136 local variables from compile_dwarf_expr_to_c.
137 Global variables can be accessed by GCC only by their address, not
138 by their name. */
139 {
140 struct value *val;
141 struct frame_info *frame = nullptr;
142
143 if (symbol_read_needs_frame (sym.symbol))
144 {
145 frame = get_selected_frame (nullptr);
146 if (frame == nullptr)
147 error (_("Symbol \"%s\" cannot be used because "
148 "there is no selected frame"),
149 SYMBOL_PRINT_NAME (sym.symbol));
150 }
151
152 val = read_var_value (sym.symbol, sym.block, frame);
153 if (VALUE_LVAL (val) != lval_memory)
154 error (_("Symbol \"%s\" cannot be used for compilation "
155 "evaluation as its address has not been found."),
156 SYMBOL_PRINT_NAME (sym.symbol));
157
158 kind = GCC_CP_SYMBOL_VARIABLE;
159 addr = value_address (val);
160 }
161 break;
162
163
164 case LOC_REGISTER:
165 case LOC_ARG:
166 case LOC_REF_ARG:
167 case LOC_REGPARM_ADDR:
168 case LOC_LOCAL:
169 substitution:
170 kind = GCC_CP_SYMBOL_VARIABLE;
171 symbol_name = c_symbol_substitution_name (sym.symbol);
172 break;
173
174 case LOC_STATIC:
175 kind = GCC_CP_SYMBOL_VARIABLE;
176 addr = SYMBOL_VALUE_ADDRESS (sym.symbol);
177 break;
178
179 case LOC_FINAL_VALUE:
180 default:
181 gdb_assert_not_reached ("Unreachable case in convert_one_symbol.");
182 }
183
184 /* Don't emit local variable decls for a raw expression. */
185 if (instance->scope () != COMPILE_I_RAW_SCOPE || symbol_name == nullptr)
186 {
187 compile_scope scope;
188
189 /* For non-local symbols, create/push a new scope so that the
190 symbol is properly scoped to the plug-in. */
191 if (!is_local)
192 {
193 scope
194 = instance->new_scope (SYMBOL_NATURAL_NAME (sym.symbol),
195 SYMBOL_TYPE (sym.symbol));
196 if (scope.nested_type () != GCC_TYPE_NONE)
197 {
198 /* We found a symbol for this type that was defined inside
199 some other symbol, e.g., a class tyepdef defined. */
200 return;
201 }
202
203 instance->enter_scope (scope);
204 }
205
206 /* Get the `raw' name of the symbol. */
207 if (name.empty () && SYMBOL_NATURAL_NAME (sym.symbol) != nullptr)
208 name = compile_cplus_instance::decl_name
209 (SYMBOL_NATURAL_NAME (sym.symbol)).get ();
210
211 /* Define the decl. */
212 instance->plugin ().build_decl
213 ("variable", name.c_str (), kind, sym_type,
214 symbol_name.get (), addr, filename, line);
215
216 /* Pop scope for non-local symbols. */
217 if (!is_local)
218 instance->leave_scope ();
219 }
220 }
221}
222
223/* Convert a full symbol to its gcc form. CONTEXT is the compiler to
224 use, IDENTIFIER is the name of the symbol, SYM is the symbol
225 itself, and DOMAIN is the domain which was searched. */
226
227static void
228convert_symbol_sym (compile_cplus_instance *instance,
229 const char *identifier, struct block_symbol sym,
230 domain_enum domain)
231{
232 /* If we found a symbol and it is not in the static or global
233 scope, then we should first convert any static or global scope
234 symbol of the same name. This lets this unusual case work:
235
236 int x; // Global.
237 int func(void)
238 {
239 int x;
240 // At this spot, evaluate "extern int x; x"
241 }
242 */
243
244 const struct block *static_block = block_static_block (sym.block);
245 /* STATIC_BLOCK is NULL if FOUND_BLOCK is the global block. */
246 bool is_local_symbol = (sym.block != static_block && static_block != nullptr);
247 if (is_local_symbol)
248 {
249 struct block_symbol global_sym;
250
251 global_sym = lookup_symbol (identifier, nullptr, domain, nullptr);
252 /* If the outer symbol is in the static block, we ignore it, as
253 it cannot be referenced. */
254 if (global_sym.symbol != nullptr
255 && global_sym.block != block_static_block (global_sym.block))
256 {
257 if (compile_debug)
258 fprintf_unfiltered (gdb_stdlog,
259 "gcc_convert_symbol \"%s\": global symbol\n",
260 identifier);
261 convert_one_symbol (instance, global_sym, true, false);
262 }
263 }
264
265 if (compile_debug)
266 fprintf_unfiltered (gdb_stdlog,
267 "gcc_convert_symbol \"%s\": local symbol\n",
268 identifier);
269 convert_one_symbol (instance, sym, false, is_local_symbol);
270}
271
272/* Convert a minimal symbol to its gcc form. CONTEXT is the compiler
273 to use and BMSYM is the minimal symbol to convert. */
274
275static void
276convert_symbol_bmsym (compile_cplus_instance *instance,
277 struct bound_minimal_symbol bmsym)
278{
279 struct minimal_symbol *msym = bmsym.minsym;
280 struct objfile *objfile = bmsym.objfile;
281 struct type *type;
282 gcc_cp_symbol_kind_flags kind;
283 gcc_type sym_type;
284 CORE_ADDR addr;
285
286 addr = MSYMBOL_VALUE_ADDRESS (objfile, msym);
287
288 /* Conversion copied from write_exp_msymbol. */
289 switch (MSYMBOL_TYPE (msym))
290 {
291 case mst_text:
292 case mst_file_text:
293 case mst_solib_trampoline:
294 type = objfile_type (objfile)->nodebug_text_symbol;
295 kind = GCC_CP_SYMBOL_FUNCTION;
296 break;
297
298 case mst_text_gnu_ifunc:
299 /* nodebug_text_gnu_ifunc_symbol would cause:
300 function return type cannot be function */
301 type = objfile_type (objfile)->nodebug_text_symbol;
302 kind = GCC_CP_SYMBOL_FUNCTION;
303 addr = gnu_ifunc_resolve_addr (target_gdbarch (), addr);
304 break;
305
306 case mst_data:
307 case mst_file_data:
308 case mst_bss:
309 case mst_file_bss:
310 type = objfile_type (objfile)->nodebug_data_symbol;
311 kind = GCC_CP_SYMBOL_VARIABLE;
312 break;
313
314 case mst_slot_got_plt:
315 type = objfile_type (objfile)->nodebug_got_plt_symbol;
316 kind = GCC_CP_SYMBOL_FUNCTION;
317 break;
318
319 default:
320 type = objfile_type (objfile)->nodebug_unknown_symbol;
321 kind = GCC_CP_SYMBOL_VARIABLE;
322 break;
323 }
324
325 sym_type = instance->convert_type (type);
326 instance->plugin ().push_namespace ("");
327 instance->plugin ().build_decl
328 ("minsym", MSYMBOL_NATURAL_NAME (msym), kind, sym_type, nullptr, addr,
329 nullptr, 0);
330 instance->plugin ().pop_binding_level ("");
331}
332
333/* See compile-cplus.h. */
334
335void
336gcc_cplus_convert_symbol (void *datum,
337 struct gcc_cp_context *gcc_context,
5c889512 338 enum gcc_cp_oracle_request request,
078a0207
KS
339 const char *identifier)
340{
341 if (compile_debug)
342 fprintf_unfiltered (gdb_stdlog,
343 "got oracle request for \"%s\"\n", identifier);
344
345 bool found = false;
346 compile_cplus_instance *instance = (compile_cplus_instance *) datum;
347
348 TRY
349 {
350 /* Symbol searching is a three part process unfortunately. */
351
352 /* First do a "standard" lookup, converting any found symbols.
353 This will find variables in the current scope. */
354
355 struct block_symbol sym
356 = lookup_symbol (identifier, instance->block (), VAR_DOMAIN, nullptr);
357
358 if (sym.symbol != nullptr)
359 {
360 found = true;
361 convert_symbol_sym (instance, identifier, sym, VAR_DOMAIN);
362 }
363
364 /* Then use linespec.c's multi-symbol search. This should find
365 all non-variable symbols for which we have debug info. */
366
367 symbol_searcher searcher;
368 searcher.find_all_symbols (identifier, current_language,
369 ALL_DOMAIN, nullptr, nullptr);
370
371 /* Convert any found symbols. */
372 for (const auto &it : searcher.matching_symbols ())
373 {
374 /* Don't convert the symbol found above, if any, twice! */
375 if (it.symbol != sym.symbol)
376 {
377 found = true;
378 convert_symbol_sym (instance, identifier, it,
379 SYMBOL_DOMAIN (it.symbol));
380 }
381 }
382
383 /* Finally, if no symbols have been found, fall back to minsyms. */
384 if (!found)
385 {
386 for (const auto &it : searcher.matching_msymbols ())
387 {
388 found = true;
389 convert_symbol_bmsym (instance, it);
390 }
391 }
392 }
393 CATCH (e, RETURN_MASK_ALL)
394 {
395 /* We can't allow exceptions to escape out of this callback. Safest
396 is to simply emit a gcc error. */
397 instance->plugin ().error (e.message);
398 }
399 END_CATCH
400
401 if (compile_debug && !found)
402 fprintf_unfiltered (gdb_stdlog,
403 "gcc_convert_symbol \"%s\": lookup_symbol failed\n",
404 identifier);
405
406 if (compile_debug)
407 {
408 if (found)
409 fprintf_unfiltered (gdb_stdlog, "found type for %s\n", identifier);
410 else
411 {
412 fprintf_unfiltered (gdb_stdlog, "did not find type for %s\n",
413 identifier);
414 }
415 }
416
417 return;
418}
419
420/* See compile-cplus.h. */
421
422gcc_address
423gcc_cplus_symbol_address (void *datum, struct gcc_cp_context *gcc_context,
424 const char *identifier)
425{
426 compile_cplus_instance *instance = (compile_cplus_instance *) datum;
427 gcc_address result = 0;
428 int found = 0;
429
430 if (compile_debug)
431 fprintf_unfiltered (gdb_stdlog,
432 "got oracle request for address of %s\n", identifier);
433
434 /* We can't allow exceptions to escape out of this callback. Safest
435 is to simply emit a gcc error. */
436 TRY
437 {
438 struct symbol *sym
439 = lookup_symbol (identifier, nullptr, VAR_DOMAIN, nullptr).symbol;
440
441 if (sym != nullptr && SYMBOL_CLASS (sym) == LOC_BLOCK)
442 {
443 if (compile_debug)
444 fprintf_unfiltered (gdb_stdlog,
445 "gcc_symbol_address \"%s\": full symbol\n",
446 identifier);
447 result = BLOCK_START (SYMBOL_BLOCK_VALUE (sym));
448 if (TYPE_GNU_IFUNC (SYMBOL_TYPE (sym)))
449 result = gnu_ifunc_resolve_addr (target_gdbarch (), result);
450 found = 1;
451 }
452 else
453 {
454 struct bound_minimal_symbol msym;
455
456 msym = lookup_bound_minimal_symbol (identifier);
457 if (msym.minsym != nullptr)
458 {
459 if (compile_debug)
460 fprintf_unfiltered (gdb_stdlog,
461 "gcc_symbol_address \"%s\": minimal "
462 "symbol\n",
463 identifier);
464 result = BMSYMBOL_VALUE_ADDRESS (msym);
465 if (MSYMBOL_TYPE (msym.minsym) == mst_text_gnu_ifunc)
466 result = gnu_ifunc_resolve_addr (target_gdbarch (), result);
467 found = 1;
468 }
469 }
470 }
471
472 CATCH (e, RETURN_MASK_ERROR)
473 {
474 instance->plugin ().error (e.message);
475 }
476 END_CATCH
477
478 if (compile_debug && !found)
479 fprintf_unfiltered (gdb_stdlog,
480 "gcc_symbol_address \"%s\": failed\n",
481 identifier);
482
483 if (compile_debug)
484 {
485 if (found)
486 fprintf_unfiltered (gdb_stdlog, "found address for %s!\n", identifier);
487 else
488 fprintf_unfiltered (gdb_stdlog,
489 "did not find address for %s\n", identifier);
490 }
491
492 return result;
493}
This page took 0.046225 seconds and 4 git commands to generate.