xref: /netbsd-src/external/gpl3/gdb.old/dist/gdb/compile/compile-cplus-symbols.c (revision 867d70fc718005c0918b8b8b2f9d7f2d52d0a0db)
1 /* Convert symbols from GDB to GCC
2 
3    Copyright (C) 2014-2019 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 "common/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 
45 static void
46 convert_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 	  /* For non-local symbols, create/push a new scope so that the
188 	     symbol is properly scoped to the plug-in.  */
189 	  if (!is_local)
190 	    {
191 	      compile_scope scope
192 		= instance->new_scope (SYMBOL_NATURAL_NAME (sym.symbol),
193 				       SYMBOL_TYPE (sym.symbol));
194 	      if (scope.nested_type () != GCC_TYPE_NONE)
195 		{
196 		  /* We found a symbol for this type that was defined inside
197 		     some other symbol, e.g., a class tyepdef defined.  */
198 		  return;
199 		}
200 
201 	      instance->enter_scope (std::move (scope));
202 	    }
203 
204 	  /* Get the `raw' name of the symbol.  */
205 	  if (name.empty () && SYMBOL_NATURAL_NAME (sym.symbol) != nullptr)
206 	    name = compile_cplus_instance::decl_name
207 	      (SYMBOL_NATURAL_NAME (sym.symbol)).get ();
208 
209 	  /* Define the decl.  */
210 	  instance->plugin ().build_decl
211 	    ("variable", name.c_str (), kind, sym_type,
212 	     symbol_name.get (), addr, filename, line);
213 
214 	  /* Pop scope for non-local symbols.  */
215 	  if (!is_local)
216 	    instance->leave_scope ();
217 	}
218     }
219 }
220 
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.  */
224 
225 static void
226 convert_symbol_sym (compile_cplus_instance *instance,
227 		    const char *identifier, struct block_symbol sym,
228 		    domain_enum domain)
229 {
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:
233 
234      int x; // Global.
235      int func(void)
236      {
237      int x;
238      // At this spot, evaluate "extern int x; x"
239      }
240   */
241 
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);
245   if (is_local_symbol)
246     {
247       struct block_symbol global_sym;
248 
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))
254 	{
255 	  if (compile_debug)
256 	    fprintf_unfiltered (gdb_stdlog,
257 				"gcc_convert_symbol \"%s\": global symbol\n",
258 				identifier);
259 	  convert_one_symbol (instance, global_sym, true, false);
260 	}
261     }
262 
263   if (compile_debug)
264     fprintf_unfiltered (gdb_stdlog,
265 			"gcc_convert_symbol \"%s\": local symbol\n",
266 			identifier);
267   convert_one_symbol (instance, sym, false, is_local_symbol);
268 }
269 
270 /* Convert a minimal symbol to its gcc form.  CONTEXT is the compiler
271    to use and BMSYM is the minimal symbol to convert.  */
272 
273 static void
274 convert_symbol_bmsym (compile_cplus_instance *instance,
275 		      struct bound_minimal_symbol bmsym)
276 {
277   struct minimal_symbol *msym = bmsym.minsym;
278   struct objfile *objfile = bmsym.objfile;
279   struct type *type;
280   gcc_cp_symbol_kind_flags kind;
281   gcc_type sym_type;
282   CORE_ADDR addr;
283 
284   addr = MSYMBOL_VALUE_ADDRESS (objfile, msym);
285 
286   /* Conversion copied from write_exp_msymbol.  */
287   switch (MSYMBOL_TYPE (msym))
288     {
289     case mst_text:
290     case mst_file_text:
291     case mst_solib_trampoline:
292       type = objfile_type (objfile)->nodebug_text_symbol;
293       kind = GCC_CP_SYMBOL_FUNCTION;
294       break;
295 
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);
302       break;
303 
304     case mst_data:
305     case mst_file_data:
306     case mst_bss:
307     case mst_file_bss:
308       type = objfile_type (objfile)->nodebug_data_symbol;
309       kind = GCC_CP_SYMBOL_VARIABLE;
310       break;
311 
312     case mst_slot_got_plt:
313       type = objfile_type (objfile)->nodebug_got_plt_symbol;
314       kind = GCC_CP_SYMBOL_FUNCTION;
315       break;
316 
317     default:
318       type = objfile_type (objfile)->nodebug_unknown_symbol;
319       kind = GCC_CP_SYMBOL_VARIABLE;
320       break;
321     }
322 
323   sym_type = instance->convert_type (type);
324   instance->plugin ().push_namespace ("");
325   instance->plugin ().build_decl
326     ("minsym", MSYMBOL_NATURAL_NAME (msym), kind, sym_type, nullptr, addr,
327      nullptr, 0);
328   instance->plugin ().pop_binding_level ("");
329 }
330 
331 /* See compile-cplus.h.  */
332 
333 void
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)
338 {
339   if (compile_debug)
340     fprintf_unfiltered (gdb_stdlog,
341 			"got oracle request for \"%s\"\n", identifier);
342 
343   bool found = false;
344   compile_cplus_instance *instance = (compile_cplus_instance *) datum;
345 
346   TRY
347     {
348       /* Symbol searching is a three part process unfortunately.  */
349 
350       /* First do a "standard" lookup, converting any found symbols.
351 	 This will find variables in the current scope.  */
352 
353       struct block_symbol sym
354 	= lookup_symbol (identifier, instance->block (), VAR_DOMAIN, nullptr);
355 
356       if (sym.symbol != nullptr)
357 	{
358 	  found = true;
359 	  convert_symbol_sym (instance, identifier, sym, VAR_DOMAIN);
360 	}
361 
362       /* Then use linespec.c's multi-symbol search.  This should find
363 	 all non-variable symbols for which we have debug info.  */
364 
365       symbol_searcher searcher;
366       searcher.find_all_symbols (identifier, current_language,
367 				 ALL_DOMAIN, nullptr, nullptr);
368 
369       /* Convert any found symbols.  */
370       for (const auto &it : searcher.matching_symbols ())
371 	{
372 	  /* Don't convert the symbol found above, if any, twice!  */
373 	  if (it.symbol != sym.symbol)
374 	    {
375 	      found = true;
376 	      convert_symbol_sym (instance, identifier, it,
377 				  SYMBOL_DOMAIN (it.symbol));
378 	    }
379 	}
380 
381       /* Finally, if no symbols have been found, fall back to minsyms.  */
382       if (!found)
383 	{
384 	  for (const auto &it : searcher.matching_msymbols ())
385 	    {
386 	      found = true;
387 	      convert_symbol_bmsym (instance, it);
388 	    }
389 	}
390     }
391   CATCH (e, RETURN_MASK_ALL)
392     {
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.message);
396     }
397   END_CATCH
398 
399   if (compile_debug && !found)
400     fprintf_unfiltered (gdb_stdlog,
401 			"gcc_convert_symbol \"%s\": lookup_symbol failed\n",
402 			identifier);
403 
404   if (compile_debug)
405     {
406       if (found)
407 	fprintf_unfiltered (gdb_stdlog, "found type for %s\n", identifier);
408       else
409 	{
410 	  fprintf_unfiltered (gdb_stdlog, "did not find type for %s\n",
411 			      identifier);
412 	}
413     }
414 
415   return;
416 }
417 
418 /* See compile-cplus.h.  */
419 
420 gcc_address
421 gcc_cplus_symbol_address (void *datum, struct gcc_cp_context *gcc_context,
422 			  const char *identifier)
423 {
424   compile_cplus_instance *instance = (compile_cplus_instance *) datum;
425   gcc_address result = 0;
426   int found = 0;
427 
428   if (compile_debug)
429     fprintf_unfiltered (gdb_stdlog,
430 			"got oracle request for address of %s\n", identifier);
431 
432   /* We can't allow exceptions to escape out of this callback.  Safest
433      is to simply emit a gcc error.  */
434   TRY
435     {
436       struct symbol *sym
437 	= lookup_symbol (identifier, nullptr, VAR_DOMAIN, nullptr).symbol;
438 
439       if (sym != nullptr && SYMBOL_CLASS (sym) == LOC_BLOCK)
440 	{
441 	  if (compile_debug)
442 	    fprintf_unfiltered (gdb_stdlog,
443 				"gcc_symbol_address \"%s\": full symbol\n",
444 				identifier);
445 	  result = BLOCK_START (SYMBOL_BLOCK_VALUE (sym));
446 	  if (TYPE_GNU_IFUNC (SYMBOL_TYPE (sym)))
447 	    result = gnu_ifunc_resolve_addr (target_gdbarch (), result);
448 	  found = 1;
449 	}
450       else
451 	{
452 	  struct bound_minimal_symbol msym;
453 
454 	  msym = lookup_bound_minimal_symbol (identifier);
455 	  if (msym.minsym != nullptr)
456 	    {
457 	      if (compile_debug)
458 		fprintf_unfiltered (gdb_stdlog,
459 				    "gcc_symbol_address \"%s\": minimal "
460 				    "symbol\n",
461 				    identifier);
462 	      result = BMSYMBOL_VALUE_ADDRESS (msym);
463 	      if (MSYMBOL_TYPE (msym.minsym) == mst_text_gnu_ifunc)
464 		result = gnu_ifunc_resolve_addr (target_gdbarch (), result);
465 	      found = 1;
466 	    }
467 	}
468     }
469 
470   CATCH (e, RETURN_MASK_ERROR)
471     {
472       instance->plugin ().error (e.message);
473     }
474   END_CATCH
475 
476   if (compile_debug && !found)
477     fprintf_unfiltered (gdb_stdlog,
478 			"gcc_symbol_address \"%s\": failed\n",
479 			identifier);
480 
481   if (compile_debug)
482     {
483       if (found)
484 	fprintf_unfiltered (gdb_stdlog, "found address for %s!\n", identifier);
485       else
486 	fprintf_unfiltered (gdb_stdlog,
487 			    "did not find address for %s\n", identifier);
488     }
489 
490   return result;
491 }
492