1 /* Convert symbols from GDB to GCC
3 Copyright (C) 2014-2023 Free Software Foundation, Inc.
5 This file is part of GDB.
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.
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.
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/>. */
22 #include "compile-internal.h"
23 #include "compile-cplus.h"
24 #include "gdbsupport/gdb_assert.h"
26 #include "parser-defs.h"
31 #include "exceptions.h"
33 #include "dwarf2/loc.h"
34 #include "cp-support.h"
36 #include "compile-c.h"
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
46 convert_one_symbol (compile_cplus_instance
*instance
,
47 struct block_symbol sym
, bool is_global
, bool is_local
)
49 /* Squash compiler warning. */
50 gcc_type sym_type
= 0;
51 const char *filename
= sym
.symbol
->symtab ()->filename
;
52 unsigned short line
= sym
.symbol
->line ();
54 instance
->error_symbol_once (sym
.symbol
);
56 if (sym
.symbol
->aclass () == LOC_LABEL
)
59 sym_type
= instance
->convert_type (sym
.symbol
->type ());
61 if (sym
.symbol
->domain () == STRUCT_DOMAIN
)
67 /* Squash compiler warning. */
68 gcc_cp_symbol_kind_flags kind
= GCC_CP_FLAG_BASE
;
71 gdb::unique_xmalloc_ptr
<char> symbol_name
;
73 switch (sym
.symbol
->aclass ())
76 if (sym
.symbol
->type ()->code () == TYPE_CODE_TYPEDEF
)
77 kind
= GCC_CP_SYMBOL_TYPEDEF
;
78 else if (sym
.symbol
->type ()->code () == TYPE_CODE_NAMESPACE
)
83 kind
= GCC_CP_SYMBOL_LABEL
;
84 addr
= sym
.symbol
->value_address ();
89 kind
= GCC_CP_SYMBOL_FUNCTION
;
90 addr
= sym
.symbol
->value_block()->start ();
91 if (is_global
&& sym
.symbol
->type ()->is_gnu_ifunc ())
92 addr
= gnu_ifunc_resolve_addr (target_gdbarch (), addr
);
97 if (sym
.symbol
->type ()->code () == TYPE_CODE_ENUM
)
99 /* Already handled by convert_enum. */
102 instance
->plugin ().build_constant
103 (sym_type
, sym
.symbol
->natural_name (),
104 sym
.symbol
->value_longest (), filename
, line
);
107 case LOC_CONST_BYTES
:
108 error (_("Unsupported LOC_CONST_BYTES for symbol \"%s\"."),
109 sym
.symbol
->print_name ());
112 internal_error (_("LOC_UNDEF found for \"%s\"."),
113 sym
.symbol
->print_name ());
115 case LOC_COMMON_BLOCK
:
116 error (_("Fortran common block is unsupported for compilation "
117 "evaluaton of symbol \"%s\"."),
118 sym
.symbol
->print_name ());
120 case LOC_OPTIMIZED_OUT
:
121 error (_("Symbol \"%s\" cannot be used for compilation evaluation "
122 "as it is optimized out."),
123 sym
.symbol
->print_name ());
128 /* Probably TLS here. */
129 warning (_("Symbol \"%s\" is thread-local and currently can only "
130 "be referenced from the current thread in "
132 sym
.symbol
->print_name ());
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
141 frame_info_ptr frame
= nullptr;
143 if (symbol_read_needs_frame (sym
.symbol
))
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 sym
.symbol
->print_name ());
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 sym
.symbol
->print_name ());
158 kind
= GCC_CP_SYMBOL_VARIABLE
;
159 addr
= value_address (val
);
167 case LOC_REGPARM_ADDR
:
170 kind
= GCC_CP_SYMBOL_VARIABLE
;
171 symbol_name
= c_symbol_substitution_name (sym
.symbol
);
175 kind
= GCC_CP_SYMBOL_VARIABLE
;
176 addr
= sym
.symbol
->value_address ();
179 case LOC_FINAL_VALUE
:
181 gdb_assert_not_reached ("Unreachable case in convert_one_symbol.");
184 /* Don't emit local variable decls for a raw expression. */
185 if (instance
->scope () != COMPILE_I_RAW_SCOPE
|| symbol_name
== nullptr)
187 /* For non-local symbols, create/push a new scope so that the
188 symbol is properly scoped to the plug-in. */
192 = instance
->new_scope (sym
.symbol
->natural_name (),
193 sym
.symbol
->type ());
194 if (scope
.nested_type () != GCC_TYPE_NONE
)
196 /* We found a symbol for this type that was defined inside
197 some other symbol, e.g., a class typedef defined. */
201 instance
->enter_scope (std::move (scope
));
204 /* Get the `raw' name of the symbol. */
205 if (name
.empty () && sym
.symbol
->natural_name () != nullptr)
206 name
= compile_cplus_instance::decl_name
207 (sym
.symbol
->natural_name ()).get ();
209 /* Define the decl. */
210 instance
->plugin ().build_decl
211 ("variable", name
.c_str (), kind
.raw (), sym_type
,
212 symbol_name
.get (), addr
, filename
, line
);
214 /* Pop scope for non-local symbols. */
216 instance
->leave_scope ();
221 /* Convert a full symbol to its gcc form. CONTEXT is the compiler to
222 use, IDENTIFIER is the name of the symbol, SYM is the symbol
223 itself, and DOMAIN is the domain which was searched. */
226 convert_symbol_sym (compile_cplus_instance
*instance
,
227 const char *identifier
, struct block_symbol sym
,
230 /* If we found a symbol and it is not in the static or global
231 scope, then we should first convert any static or global scope
232 symbol of the same name. This lets this unusual case work:
238 // At this spot, evaluate "extern int x; x"
242 const struct block
*static_block
= block_static_block (sym
.block
);
243 /* STATIC_BLOCK is NULL if FOUND_BLOCK is the global block. */
244 bool is_local_symbol
= (sym
.block
!= static_block
&& static_block
!= nullptr);
247 struct block_symbol global_sym
;
249 global_sym
= lookup_symbol (identifier
, nullptr, domain
, nullptr);
250 /* If the outer symbol is in the static block, we ignore it, as
251 it cannot be referenced. */
252 if (global_sym
.symbol
!= nullptr
253 && global_sym
.block
!= block_static_block (global_sym
.block
))
256 gdb_printf (gdb_stdlog
,
257 "gcc_convert_symbol \"%s\": global symbol\n",
259 convert_one_symbol (instance
, global_sym
, true, false);
264 gdb_printf (gdb_stdlog
,
265 "gcc_convert_symbol \"%s\": local symbol\n",
267 convert_one_symbol (instance
, sym
, false, is_local_symbol
);
270 /* Convert a minimal symbol to its gcc form. CONTEXT is the compiler
271 to use and BMSYM is the minimal symbol to convert. */
274 convert_symbol_bmsym (compile_cplus_instance
*instance
,
275 struct bound_minimal_symbol bmsym
)
277 struct minimal_symbol
*msym
= bmsym
.minsym
;
278 struct objfile
*objfile
= bmsym
.objfile
;
280 gcc_cp_symbol_kind_flags kind
;
284 addr
= msym
->value_address (objfile
);
286 /* Conversion copied from write_exp_msymbol. */
287 switch (msym
->type ())
291 case mst_solib_trampoline
:
292 type
= objfile_type (objfile
)->nodebug_text_symbol
;
293 kind
= GCC_CP_SYMBOL_FUNCTION
;
296 case mst_text_gnu_ifunc
:
297 /* nodebug_text_gnu_ifunc_symbol would cause:
298 function return type cannot be function */
299 type
= objfile_type (objfile
)->nodebug_text_symbol
;
300 kind
= GCC_CP_SYMBOL_FUNCTION
;
301 addr
= gnu_ifunc_resolve_addr (target_gdbarch (), addr
);
308 type
= objfile_type (objfile
)->nodebug_data_symbol
;
309 kind
= GCC_CP_SYMBOL_VARIABLE
;
312 case mst_slot_got_plt
:
313 type
= objfile_type (objfile
)->nodebug_got_plt_symbol
;
314 kind
= GCC_CP_SYMBOL_FUNCTION
;
318 type
= objfile_type (objfile
)->nodebug_unknown_symbol
;
319 kind
= GCC_CP_SYMBOL_VARIABLE
;
323 sym_type
= instance
->convert_type (type
);
324 instance
->plugin ().push_namespace ("");
325 instance
->plugin ().build_decl
326 ("minsym", msym
->natural_name (), kind
.raw (), sym_type
, nullptr, addr
,
328 instance
->plugin ().pop_binding_level ("");
331 /* See compile-cplus.h. */
334 gcc_cplus_convert_symbol (void *datum
,
335 struct gcc_cp_context
*gcc_context
,
336 enum gcc_cp_oracle_request request
,
337 const char *identifier
)
340 gdb_printf (gdb_stdlog
,
341 "got oracle request for \"%s\"\n", identifier
);
344 compile_cplus_instance
*instance
= (compile_cplus_instance
*) datum
;
348 /* Symbol searching is a three part process unfortunately. */
350 /* First do a "standard" lookup, converting any found symbols.
351 This will find variables in the current scope. */
353 struct block_symbol sym
354 = lookup_symbol (identifier
, instance
->block (), VAR_DOMAIN
, nullptr);
356 if (sym
.symbol
!= nullptr)
359 convert_symbol_sym (instance
, identifier
, sym
, VAR_DOMAIN
);
362 /* Then use linespec.c's multi-symbol search. This should find
363 all non-variable symbols for which we have debug info. */
365 symbol_searcher searcher
;
366 searcher
.find_all_symbols (identifier
, current_language
,
367 ALL_DOMAIN
, nullptr, nullptr);
369 /* Convert any found symbols. */
370 for (const auto &it
: searcher
.matching_symbols ())
372 /* Don't convert the symbol found above, if any, twice! */
373 if (it
.symbol
!= sym
.symbol
)
376 convert_symbol_sym (instance
, identifier
, it
,
377 it
.symbol
->domain ());
381 /* Finally, if no symbols have been found, fall back to minsyms. */
384 for (const auto &it
: searcher
.matching_msymbols ())
387 convert_symbol_bmsym (instance
, it
);
391 catch (const gdb_exception
&e
)
393 /* We can't allow exceptions to escape out of this callback. Safest
394 is to simply emit a gcc error. */
395 instance
->plugin ().error (e
.what ());
398 if (compile_debug
&& !found
)
399 gdb_printf (gdb_stdlog
,
400 "gcc_convert_symbol \"%s\": lookup_symbol failed\n",
406 gdb_printf (gdb_stdlog
, "found type for %s\n", identifier
);
409 gdb_printf (gdb_stdlog
, "did not find type for %s\n",
417 /* See compile-cplus.h. */
420 gcc_cplus_symbol_address (void *datum
, struct gcc_cp_context
*gcc_context
,
421 const char *identifier
)
423 compile_cplus_instance
*instance
= (compile_cplus_instance
*) datum
;
424 gcc_address result
= 0;
428 gdb_printf (gdb_stdlog
,
429 "got oracle request for address of %s\n", identifier
);
431 /* We can't allow exceptions to escape out of this callback. Safest
432 is to simply emit a gcc error. */
436 = lookup_symbol (identifier
, nullptr, VAR_DOMAIN
, nullptr).symbol
;
438 if (sym
!= nullptr && sym
->aclass () == LOC_BLOCK
)
441 gdb_printf (gdb_stdlog
,
442 "gcc_symbol_address \"%s\": full symbol\n",
444 result
= sym
->value_block ()->start ();
445 if (sym
->type ()->is_gnu_ifunc ())
446 result
= gnu_ifunc_resolve_addr (target_gdbarch (), result
);
451 struct bound_minimal_symbol msym
;
453 msym
= lookup_bound_minimal_symbol (identifier
);
454 if (msym
.minsym
!= nullptr)
457 gdb_printf (gdb_stdlog
,
458 "gcc_symbol_address \"%s\": minimal "
461 result
= msym
.value_address ();
462 if (msym
.minsym
->type () == mst_text_gnu_ifunc
)
463 result
= gnu_ifunc_resolve_addr (target_gdbarch (), result
);
469 catch (const gdb_exception_error
&e
)
471 instance
->plugin ().error (e
.what ());
474 if (compile_debug
&& !found
)
475 gdb_printf (gdb_stdlog
,
476 "gcc_symbol_address \"%s\": failed\n",
482 gdb_printf (gdb_stdlog
, "found address for %s!\n", identifier
);
484 gdb_printf (gdb_stdlog
,
485 "did not find address for %s\n", identifier
);