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