xref: /netbsd-src/external/gpl3/gdb.old/dist/gdb/compile/compile-c-symbols.c (revision 8b657b0747480f8989760d71343d6dd33f8d4cf9)
1 /* Convert symbols from GDB to GCC
2 
3    Copyright (C) 2014-2023 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-c.h"
24 #include "symtab.h"
25 #include "parser-defs.h"
26 #include "block.h"
27 #include "objfiles.h"
28 #include "compile.h"
29 #include "value.h"
30 #include "exceptions.h"
31 #include "gdbtypes.h"
32 #include "dwarf2/loc.h"
33 
34 
35 
36 /* Compute the name of the pointer representing a local symbol's
37    address.  */
38 
39 gdb::unique_xmalloc_ptr<char>
40 c_symbol_substitution_name (struct symbol *sym)
41 {
42   return gdb::unique_xmalloc_ptr<char>
43     (concat ("__", sym->natural_name (), "_ptr", (char *) NULL));
44 }
45 
46 /* Convert a given symbol, SYM, to the compiler's representation.
47    CONTEXT is the compiler instance.  IS_GLOBAL is true if the
48    symbol came from the global scope.  IS_LOCAL is true if the symbol
49    came from a local scope.  (Note that the two are not strictly
50    inverses because the symbol might have come from the static
51    scope.)  */
52 
53 static void
54 convert_one_symbol (compile_c_instance *context,
55 		    struct block_symbol sym,
56 		    int is_global,
57 		    int is_local)
58 {
59   gcc_type sym_type;
60   const char *filename = sym.symbol->symtab ()->filename;
61   unsigned short line = sym.symbol->line ();
62 
63   context->error_symbol_once (sym.symbol);
64 
65   if (sym.symbol->aclass () == LOC_LABEL)
66     sym_type = 0;
67   else
68     sym_type = context->convert_type (sym.symbol->type ());
69 
70   if (sym.symbol->domain () == STRUCT_DOMAIN)
71     {
72       /* Binding a tag, so we don't need to build a decl.  */
73       context->plugin ().tagbind (sym.symbol->natural_name (),
74 				  sym_type, filename, line);
75     }
76   else
77     {
78       gcc_decl decl;
79       enum gcc_c_symbol_kind kind;
80       CORE_ADDR addr = 0;
81       gdb::unique_xmalloc_ptr<char> symbol_name;
82 
83       switch (sym.symbol->aclass ())
84 	{
85 	case LOC_TYPEDEF:
86 	  kind = GCC_C_SYMBOL_TYPEDEF;
87 	  break;
88 
89 	case LOC_LABEL:
90 	  kind = GCC_C_SYMBOL_LABEL;
91 	  addr = sym.symbol->value_address ();
92 	  break;
93 
94 	case LOC_BLOCK:
95 	  kind = GCC_C_SYMBOL_FUNCTION;
96 	  addr = sym.symbol->value_block ()->entry_pc ();
97 	  if (is_global && sym.symbol->type ()->is_gnu_ifunc ())
98 	    addr = gnu_ifunc_resolve_addr (target_gdbarch (), addr);
99 	  break;
100 
101 	case LOC_CONST:
102 	  if (sym.symbol->type ()->code () == TYPE_CODE_ENUM)
103 	    {
104 	      /* Already handled by convert_enum.  */
105 	      return;
106 	    }
107 	  context->plugin ().build_constant
108 	    (sym_type, sym.symbol->natural_name (),
109 	     sym.symbol->value_longest (),
110 	     filename, line);
111 	  return;
112 
113 	case LOC_CONST_BYTES:
114 	  error (_("Unsupported LOC_CONST_BYTES for symbol \"%s\"."),
115 		 sym.symbol->print_name ());
116 
117 	case LOC_UNDEF:
118 	  internal_error (_("LOC_UNDEF found for \"%s\"."),
119 			  sym.symbol->print_name ());
120 
121 	case LOC_COMMON_BLOCK:
122 	  error (_("Fortran common block is unsupported for compilation "
123 		   "evaluaton of symbol \"%s\"."),
124 		 sym.symbol->print_name ());
125 
126 	case LOC_OPTIMIZED_OUT:
127 	  error (_("Symbol \"%s\" cannot be used for compilation evaluation "
128 		   "as it is optimized out."),
129 		 sym.symbol->print_name ());
130 
131 	case LOC_COMPUTED:
132 	  if (is_local)
133 	    goto substitution;
134 	  /* Probably TLS here.  */
135 	  warning (_("Symbol \"%s\" is thread-local and currently can only "
136 		     "be referenced from the current thread in "
137 		     "compiled code."),
138 		   sym.symbol->print_name ());
139 	  /* FALLTHROUGH */
140 	case LOC_UNRESOLVED:
141 	  /* 'symbol_name' cannot be used here as that one is used only for
142 	     local variables from compile_dwarf_expr_to_c.
143 	     Global variables can be accessed by GCC only by their address, not
144 	     by their name.  */
145 	  {
146 	    struct value *val;
147 	    frame_info_ptr frame = NULL;
148 
149 	    if (symbol_read_needs_frame (sym.symbol))
150 	      {
151 		frame = get_selected_frame (NULL);
152 		if (frame == NULL)
153 		  error (_("Symbol \"%s\" cannot be used because "
154 			   "there is no selected frame"),
155 			 sym.symbol->print_name ());
156 	      }
157 
158 	    val = read_var_value (sym.symbol, sym.block, frame);
159 	    if (VALUE_LVAL (val) != lval_memory)
160 	      error (_("Symbol \"%s\" cannot be used for compilation "
161 		       "evaluation as its address has not been found."),
162 		     sym.symbol->print_name ());
163 
164 	    kind = GCC_C_SYMBOL_VARIABLE;
165 	    addr = value_address (val);
166 	  }
167 	  break;
168 
169 
170 	case LOC_REGISTER:
171 	case LOC_ARG:
172 	case LOC_REF_ARG:
173 	case LOC_REGPARM_ADDR:
174 	case LOC_LOCAL:
175 	substitution:
176 	  kind = GCC_C_SYMBOL_VARIABLE;
177 	  symbol_name = c_symbol_substitution_name (sym.symbol);
178 	  break;
179 
180 	case LOC_STATIC:
181 	  kind = GCC_C_SYMBOL_VARIABLE;
182 	  addr = sym.symbol->value_address ();
183 	  break;
184 
185 	case LOC_FINAL_VALUE:
186 	default:
187 	  gdb_assert_not_reached ("Unreachable case in convert_one_symbol.");
188 
189 	}
190 
191       /* Don't emit local variable decls for a raw expression.  */
192       if (context->scope () != COMPILE_I_RAW_SCOPE
193 	  || symbol_name == NULL)
194 	{
195 	  decl = context->plugin ().build_decl
196 	    (sym.symbol->natural_name (),
197 	     kind,
198 	     sym_type,
199 	     symbol_name.get (), addr,
200 	     filename, line);
201 
202 	  context->plugin ().bind (decl, is_global);
203 	}
204     }
205 }
206 
207 /* Convert a full symbol to its gcc form.  CONTEXT is the compiler to
208    use, IDENTIFIER is the name of the symbol, SYM is the symbol
209    itself, and DOMAIN is the domain which was searched.  */
210 
211 static void
212 convert_symbol_sym (compile_c_instance *context, const char *identifier,
213 		    struct block_symbol sym, domain_enum domain)
214 {
215   const struct block *static_block;
216   int is_local_symbol;
217 
218   /* If we found a symbol and it is not in the  static or global
219      scope, then we should first convert any static or global scope
220      symbol of the same name.  This lets this unusual case work:
221 
222      int x; // Global.
223      int func(void)
224      {
225      int x;
226      // At this spot, evaluate "extern int x; x"
227      }
228   */
229 
230   static_block = block_static_block (sym.block);
231   /* STATIC_BLOCK is NULL if FOUND_BLOCK is the global block.  */
232   is_local_symbol = (sym.block != static_block && static_block != NULL);
233   if (is_local_symbol)
234     {
235       struct block_symbol global_sym;
236 
237       global_sym = lookup_symbol (identifier, NULL, domain, NULL);
238       /* If the outer symbol is in the static block, we ignore it, as
239 	 it cannot be referenced.  */
240       if (global_sym.symbol != NULL
241 	  && global_sym.block != block_static_block (global_sym.block))
242 	{
243 	  if (compile_debug)
244 	    gdb_printf (gdb_stdlog,
245 			"gcc_convert_symbol \"%s\": global symbol\n",
246 			identifier);
247 	  convert_one_symbol (context, global_sym, 1, 0);
248 	}
249     }
250 
251   if (compile_debug)
252     gdb_printf (gdb_stdlog,
253 		"gcc_convert_symbol \"%s\": local symbol\n",
254 		identifier);
255   convert_one_symbol (context, sym, 0, is_local_symbol);
256 }
257 
258 /* Convert a minimal symbol to its gcc form.  CONTEXT is the compiler
259    to use and BMSYM is the minimal symbol to convert.  */
260 
261 static void
262 convert_symbol_bmsym (compile_c_instance *context,
263 		      struct bound_minimal_symbol bmsym)
264 {
265   struct minimal_symbol *msym = bmsym.minsym;
266   struct objfile *objfile = bmsym.objfile;
267   struct type *type;
268   enum gcc_c_symbol_kind kind;
269   gcc_type sym_type;
270   gcc_decl decl;
271   CORE_ADDR addr;
272 
273   addr = msym->value_address (objfile);
274 
275   /* Conversion copied from write_exp_msymbol.  */
276   switch (msym->type ())
277     {
278     case mst_text:
279     case mst_file_text:
280     case mst_solib_trampoline:
281       type = objfile_type (objfile)->nodebug_text_symbol;
282       kind = GCC_C_SYMBOL_FUNCTION;
283       break;
284 
285     case mst_text_gnu_ifunc:
286       type = objfile_type (objfile)->nodebug_text_gnu_ifunc_symbol;
287       kind = GCC_C_SYMBOL_FUNCTION;
288       addr = gnu_ifunc_resolve_addr (target_gdbarch (), addr);
289       break;
290 
291     case mst_data:
292     case mst_file_data:
293     case mst_bss:
294     case mst_file_bss:
295       type = objfile_type (objfile)->nodebug_data_symbol;
296       kind = GCC_C_SYMBOL_VARIABLE;
297       break;
298 
299     case mst_slot_got_plt:
300       type = objfile_type (objfile)->nodebug_got_plt_symbol;
301       kind = GCC_C_SYMBOL_FUNCTION;
302       break;
303 
304     default:
305       type = objfile_type (objfile)->nodebug_unknown_symbol;
306       kind = GCC_C_SYMBOL_VARIABLE;
307       break;
308     }
309 
310   sym_type = context->convert_type (type);
311   decl = context->plugin ().build_decl (msym->natural_name (),
312 					kind, sym_type, NULL, addr,
313 					NULL, 0);
314   context->plugin ().bind (decl, 1 /* is_global */);
315 }
316 
317 /* See compile-internal.h.  */
318 
319 void
320 gcc_convert_symbol (void *datum,
321 		    struct gcc_c_context *gcc_context,
322 		    enum gcc_c_oracle_request request,
323 		    const char *identifier)
324 {
325   compile_c_instance *context
326     = static_cast<compile_c_instance *> (datum);
327   domain_enum domain;
328   int found = 0;
329 
330   switch (request)
331     {
332     case GCC_C_ORACLE_SYMBOL:
333       domain = VAR_DOMAIN;
334       break;
335     case GCC_C_ORACLE_TAG:
336       domain = STRUCT_DOMAIN;
337       break;
338     case GCC_C_ORACLE_LABEL:
339       domain = LABEL_DOMAIN;
340       break;
341     default:
342       gdb_assert_not_reached ("Unrecognized oracle request.");
343     }
344 
345   /* We can't allow exceptions to escape out of this callback.  Safest
346      is to simply emit a gcc error.  */
347   try
348     {
349       struct block_symbol sym;
350 
351       sym = lookup_symbol (identifier, context->block (), domain, NULL);
352       if (sym.symbol != NULL)
353 	{
354 	  convert_symbol_sym (context, identifier, sym, domain);
355 	  found = 1;
356 	}
357       else if (domain == VAR_DOMAIN)
358 	{
359 	  struct bound_minimal_symbol bmsym;
360 
361 	  bmsym = lookup_minimal_symbol (identifier, NULL, NULL);
362 	  if (bmsym.minsym != NULL)
363 	    {
364 	      convert_symbol_bmsym (context, bmsym);
365 	      found = 1;
366 	    }
367 	}
368     }
369 
370   catch (const gdb_exception &e)
371     {
372       context->plugin ().error (e.what ());
373     }
374 
375   if (compile_debug && !found)
376     gdb_printf (gdb_stdlog,
377 		"gcc_convert_symbol \"%s\": lookup_symbol failed\n",
378 		identifier);
379   return;
380 }
381 
382 /* See compile-internal.h.  */
383 
384 gcc_address
385 gcc_symbol_address (void *datum, struct gcc_c_context *gcc_context,
386 		    const char *identifier)
387 {
388   compile_c_instance *context
389     = static_cast<compile_c_instance *> (datum);
390   gcc_address result = 0;
391   int found = 0;
392 
393   /* We can't allow exceptions to escape out of this callback.  Safest
394      is to simply emit a gcc error.  */
395   try
396     {
397       struct symbol *sym;
398 
399       /* We only need global functions here.  */
400       sym = lookup_symbol (identifier, NULL, VAR_DOMAIN, NULL).symbol;
401       if (sym != NULL && sym->aclass () == LOC_BLOCK)
402 	{
403 	  if (compile_debug)
404 	    gdb_printf (gdb_stdlog,
405 			"gcc_symbol_address \"%s\": full symbol\n",
406 			identifier);
407 	  result = sym->value_block ()->entry_pc ();
408 	  if (sym->type ()->is_gnu_ifunc ())
409 	    result = gnu_ifunc_resolve_addr (target_gdbarch (), result);
410 	  found = 1;
411 	}
412       else
413 	{
414 	  struct bound_minimal_symbol msym;
415 
416 	  msym = lookup_bound_minimal_symbol (identifier);
417 	  if (msym.minsym != NULL)
418 	    {
419 	      if (compile_debug)
420 		gdb_printf (gdb_stdlog,
421 			    "gcc_symbol_address \"%s\": minimal "
422 			    "symbol\n",
423 			    identifier);
424 	      result = msym.value_address ();
425 	      if (msym.minsym->type () == mst_text_gnu_ifunc)
426 		result = gnu_ifunc_resolve_addr (target_gdbarch (), result);
427 	      found = 1;
428 	    }
429 	}
430     }
431 
432   catch (const gdb_exception_error &e)
433     {
434       context->plugin ().error (e.what ());
435     }
436 
437   if (compile_debug && !found)
438     gdb_printf (gdb_stdlog,
439 		"gcc_symbol_address \"%s\": failed\n",
440 		identifier);
441   return result;
442 }
443 
444 
445 
446 /* A hash function for symbol names.  */
447 
448 static hashval_t
449 hash_symname (const void *a)
450 {
451   const struct symbol *sym = (const struct symbol *) a;
452 
453   return htab_hash_string (sym->natural_name ());
454 }
455 
456 /* A comparison function for hash tables that just looks at symbol
457    names.  */
458 
459 static int
460 eq_symname (const void *a, const void *b)
461 {
462   const struct symbol *syma = (const struct symbol *) a;
463   const struct symbol *symb = (const struct symbol *) b;
464 
465   return strcmp (syma->natural_name (), symb->natural_name ()) == 0;
466 }
467 
468 /* If a symbol with the same name as SYM is already in HASHTAB, return
469    1.  Otherwise, add SYM to HASHTAB and return 0.  */
470 
471 static int
472 symbol_seen (htab_t hashtab, struct symbol *sym)
473 {
474   void **slot;
475 
476   slot = htab_find_slot (hashtab, sym, INSERT);
477   if (*slot != NULL)
478     return 1;
479 
480   *slot = sym;
481   return 0;
482 }
483 
484 /* Generate C code to compute the length of a VLA.  */
485 
486 static void
487 generate_vla_size (compile_instance *compiler,
488 		   string_file *stream,
489 		   struct gdbarch *gdbarch,
490 		   std::vector<bool> &registers_used,
491 		   CORE_ADDR pc,
492 		   struct type *type,
493 		   struct symbol *sym)
494 {
495   type = check_typedef (type);
496 
497   if (TYPE_IS_REFERENCE (type))
498     type = check_typedef (type->target_type ());
499 
500   switch (type->code ())
501     {
502     case TYPE_CODE_RANGE:
503       {
504 	if (type->bounds ()->high.kind () == PROP_LOCEXPR
505 	    || type->bounds ()->high.kind () == PROP_LOCLIST)
506 	  {
507 	    const struct dynamic_prop *prop = &type->bounds ()->high;
508 	    std::string name = c_get_range_decl_name (prop);
509 
510 	    dwarf2_compile_property_to_c (stream, name.c_str (),
511 					  gdbarch, registers_used,
512 					  prop, pc, sym);
513 	  }
514       }
515       break;
516 
517     case TYPE_CODE_ARRAY:
518       generate_vla_size (compiler, stream, gdbarch, registers_used, pc,
519 			 type->index_type (), sym);
520       generate_vla_size (compiler, stream, gdbarch, registers_used, pc,
521 			 type->target_type (), sym);
522       break;
523 
524     case TYPE_CODE_UNION:
525     case TYPE_CODE_STRUCT:
526       {
527 	int i;
528 
529 	for (i = 0; i < type->num_fields (); ++i)
530 	  if (!field_is_static (&type->field (i)))
531 	    generate_vla_size (compiler, stream, gdbarch, registers_used, pc,
532 			       type->field (i).type (), sym);
533       }
534       break;
535     }
536 }
537 
538 /* Generate C code to compute the address of SYM.  */
539 
540 static void
541 generate_c_for_for_one_variable (compile_instance *compiler,
542 				 string_file *stream,
543 				 struct gdbarch *gdbarch,
544 				 std::vector<bool> &registers_used,
545 				 CORE_ADDR pc,
546 				 struct symbol *sym)
547 {
548 
549   try
550     {
551       if (is_dynamic_type (sym->type ()))
552 	{
553 	  /* We need to emit to a temporary buffer in case an error
554 	     occurs in the middle.  */
555 	  string_file local_file;
556 
557 	  generate_vla_size (compiler, &local_file, gdbarch, registers_used, pc,
558 			     sym->type (), sym);
559 
560 	  stream->write (local_file.c_str (), local_file.size ());
561 	}
562 
563       if (SYMBOL_COMPUTED_OPS (sym) != NULL)
564 	{
565 	  gdb::unique_xmalloc_ptr<char> generated_name
566 	    = c_symbol_substitution_name (sym);
567 	  /* We need to emit to a temporary buffer in case an error
568 	     occurs in the middle.  */
569 	  string_file local_file;
570 
571 	  SYMBOL_COMPUTED_OPS (sym)->generate_c_location (sym, &local_file,
572 							  gdbarch,
573 							  registers_used,
574 							  pc,
575 							  generated_name.get ());
576 	  stream->write (local_file.c_str (), local_file.size ());
577 	}
578       else
579 	{
580 	  switch (sym->aclass ())
581 	    {
582 	    case LOC_REGISTER:
583 	    case LOC_ARG:
584 	    case LOC_REF_ARG:
585 	    case LOC_REGPARM_ADDR:
586 	    case LOC_LOCAL:
587 	      error (_("Local symbol unhandled when generating C code."));
588 
589 	    case LOC_COMPUTED:
590 	      gdb_assert_not_reached ("LOC_COMPUTED variable "
591 				      "missing a method.");
592 
593 	    default:
594 	      /* Nothing to do for all other cases, as they don't represent
595 		 local variables.  */
596 	      break;
597 	    }
598 	}
599     }
600 
601   catch (const gdb_exception_error &e)
602     {
603       compiler->insert_symbol_error (sym, e.what ());
604     }
605 }
606 
607 /* See compile-c.h.  */
608 
609 std::vector<bool>
610 generate_c_for_variable_locations (compile_instance *compiler,
611 				   string_file *stream,
612 				   struct gdbarch *gdbarch,
613 				   const struct block *block,
614 				   CORE_ADDR pc)
615 {
616   const struct block *static_block = block_static_block (block);
617 
618   /* If we're already in the static or global block, there is nothing
619      to write.  */
620   if (static_block == NULL || block == static_block)
621     return {};
622 
623   std::vector<bool> registers_used (gdbarch_num_regs (gdbarch));
624 
625   /* Ensure that a given name is only entered once.  This reflects the
626      reality of shadowing.  */
627   htab_up symhash (htab_create_alloc (1, hash_symname, eq_symname, NULL,
628 				      xcalloc, xfree));
629 
630   while (1)
631     {
632       struct symbol *sym;
633       struct block_iterator iter;
634 
635       /* Iterate over symbols in this block, generating code to
636 	 compute the location of each local variable.  */
637       for (sym = block_iterator_first (block, &iter);
638 	   sym != NULL;
639 	   sym = block_iterator_next (&iter))
640 	{
641 	  if (!symbol_seen (symhash.get (), sym))
642 	    generate_c_for_for_one_variable (compiler, stream, gdbarch,
643 					     registers_used, pc, sym);
644 	}
645 
646       /* If we just finished the outermost block of a function, we're
647 	 done.  */
648       if (block->function () != NULL)
649 	break;
650       block = block->superblock ();
651     }
652 
653   return registers_used;
654 }
655