minsyms.c revision 130804
118334Speter/* GDB routines for manipulating the minimal symbol tables.
290075Sobrien   Copyright 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
3132718Skan   2002, 2003, 2004
418334Speter   Free Software Foundation, Inc.
590075Sobrien   Contributed by Cygnus Support, using pieces from other GDB modules.
618334Speter
790075Sobrien   This file is part of GDB.
890075Sobrien
990075Sobrien   This program is free software; you can redistribute it and/or modify
1090075Sobrien   it under the terms of the GNU General Public License as published by
1118334Speter   the Free Software Foundation; either version 2 of the License, or
1290075Sobrien   (at your option) any later version.
1390075Sobrien
1490075Sobrien   This program is distributed in the hope that it will be useful,
1590075Sobrien   but WITHOUT ANY WARRANTY; without even the implied warranty of
1618334Speter   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1718334Speter   GNU General Public License for more details.
1890075Sobrien
1990075Sobrien   You should have received a copy of the GNU General Public License
2090075Sobrien   along with this program; if not, write to the Free Software
2118334Speter   Foundation, Inc., 59 Temple Place - Suite 330,
2218334Speter   Boston, MA 02111-1307, USA.  */
2318334Speter
2450397Sobrien
25132718Skan/* This file contains support routines for creating, manipulating, and
26132718Skan   destroying minimal symbol tables.
2790075Sobrien
2818334Speter   Minimal symbol tables are used to hold some very basic information about
2990075Sobrien   all defined global symbols (text, data, bss, abs, etc).  The only two
30117395Skan   required pieces of information are the symbol's name and the address
31117395Skan   associated with that symbol.
3290075Sobrien
33117395Skan   In many cases, even if a file was compiled with no special options for
34117395Skan   debugging at all, as long as was not stripped it will contain sufficient
35117395Skan   information to build useful minimal symbol tables using this structure.
3618334Speter
3750397Sobrien   Even when a file contains enough debugging information to build a full
38132718Skan   symbol table, these minimal symbols are still useful for quickly mapping
39132718Skan   between names and addresses, and vice versa.  They are also sometimes used
40132718Skan   to figure out what full symbol table entries need to be read in. */
41132718Skan
42132718Skan
43132718Skan#include "defs.h"
44132718Skan#include <ctype.h>
45132718Skan#include "gdb_string.h"
4650397Sobrien#include "symtab.h"
4718334Speter#include "bfd.h"
4818334Speter#include "symfile.h"
4918334Speter#include "objfiles.h"
5018334Speter#include "demangle.h"
5118334Speter#include "value.h"
5218334Speter#include "cp-abi.h"
5318334Speter
5418334Speter/* Accumulate the minimal symbols for each objfile in bunches of BUNCH_SIZE.
5518334Speter   At the end, copy them all into one newly allocated location on an objfile's
5618334Speter   symbol obstack.  */
5718334Speter
5818334Speter#define BUNCH_SIZE 127
59132718Skan
6018334Speterstruct msym_bunch
6190075Sobrien  {
6290075Sobrien    struct msym_bunch *next;
6390075Sobrien    struct minimal_symbol contents[BUNCH_SIZE];
6418334Speter  };
6590075Sobrien
6690075Sobrien/* Bunch currently being filled up.
6790075Sobrien   The next field points to chain of filled bunches.  */
6890075Sobrien
6918334Speterstatic struct msym_bunch *msym_bunch;
7090075Sobrien
7190075Sobrien/* Number of slots filled in current bunch.  */
7218334Speter
7390075Sobrienstatic int msym_bunch_index;
7490075Sobrien
7590075Sobrien/* Total number of minimal symbols recorded so far for the objfile.  */
7690075Sobrien
7796263Sobrienstatic int msym_count;
7890075Sobrien
7990075Sobrien/* Compute a hash code based using the same criteria as `strcmp_iw'.  */
8090075Sobrien
8118334Speterunsigned int
8290075Sobrienmsymbol_hash_iw (const char *string)
8390075Sobrien{
8490075Sobrien  unsigned int hash = 0;
8590075Sobrien  while (*string && *string != '(')
8690075Sobrien    {
8790075Sobrien      while (isspace (*string))
8890075Sobrien	++string;
8990075Sobrien      if (*string && *string != '(')
9090075Sobrien	{
9190075Sobrien	  hash = hash * 67 + *string - 113;
9290075Sobrien	  ++string;
9390075Sobrien	}
9490075Sobrien    }
9590075Sobrien  return hash;
9690075Sobrien}
9718334Speter
9890075Sobrien/* Compute a hash code for a string.  */
9990075Sobrien
10090075Sobrienunsigned int
10190075Sobrienmsymbol_hash (const char *string)
102132718Skan{
10390075Sobrien  unsigned int hash = 0;
10490075Sobrien  for (; *string; ++string)
10590075Sobrien    hash = hash * 67 + *string - 113;
10690075Sobrien  return hash;
10790075Sobrien}
10818334Speter
10918334Speter/* Add the minimal symbol SYM to an objfile's minsym hash table, TABLE.  */
11018334Spetervoid
11190075Sobrienadd_minsym_to_hash_table (struct minimal_symbol *sym,
11290075Sobrien			  struct minimal_symbol **table)
11390075Sobrien{
11490075Sobrien  if (sym->hash_next == NULL)
11590075Sobrien    {
11690075Sobrien      unsigned int hash
11790075Sobrien	= msymbol_hash (SYMBOL_LINKAGE_NAME (sym)) % MINIMAL_SYMBOL_HASH_SIZE;
11890075Sobrien      sym->hash_next = table[hash];
11990075Sobrien      table[hash] = sym;
12090075Sobrien    }
12190075Sobrien}
12290075Sobrien
12318334Speter/* Add the minimal symbol SYM to an objfile's minsym demangled hash table,
12418334Speter   TABLE.  */
12518334Speterstatic void
12618334Speteradd_minsym_to_demangled_hash_table (struct minimal_symbol *sym,
12718334Speter                                  struct minimal_symbol **table)
12818334Speter{
12990075Sobrien  if (sym->demangled_hash_next == NULL)
13090075Sobrien    {
13118334Speter      unsigned int hash = msymbol_hash_iw (SYMBOL_DEMANGLED_NAME (sym)) % MINIMAL_SYMBOL_HASH_SIZE;
13218334Speter      sym->demangled_hash_next = table[hash];
13318334Speter      table[hash] = sym;
134132718Skan    }
13518334Speter}
136132718Skan
13790075Sobrien
13890075Sobrien/* Look through all the current minimal symbol tables and find the
13918334Speter   first minimal symbol that matches NAME.  If OBJF is non-NULL, limit
140132718Skan   the search to that objfile.  If SFILE is non-NULL, the only file-scope
141132718Skan   symbols considered will be from that source file (global symbols are
142132718Skan   still preferred).  Returns a pointer to the minimal symbol that
143132718Skan   matches, or NULL if no match is found.
14418334Speter
14518334Speter   Note:  One instance where there may be duplicate minimal symbols with
14618334Speter   the same name is when the symbol tables for a shared library and the
14790075Sobrien   symbol tables for an executable contain global symbols with the same
14890075Sobrien   names (the dynamic linker deals with the duplication).  */
14918334Speter
15018334Speterstruct minimal_symbol *
15118334Speterlookup_minimal_symbol (const char *name, const char *sfile,
15218334Speter		       struct objfile *objf)
15318334Speter{
15418334Speter  struct objfile *objfile;
15596263Sobrien  struct minimal_symbol *msymbol;
15618334Speter  struct minimal_symbol *found_symbol = NULL;
15718334Speter  struct minimal_symbol *found_file_symbol = NULL;
15818334Speter  struct minimal_symbol *trampoline_symbol = NULL;
15918334Speter
160132718Skan  unsigned int hash = msymbol_hash (name) % MINIMAL_SYMBOL_HASH_SIZE;
161132718Skan  unsigned int dem_hash = msymbol_hash_iw (name) % MINIMAL_SYMBOL_HASH_SIZE;
162132718Skan
163132718Skan#ifdef SOFUN_ADDRESS_MAYBE_MISSING
16418334Speter  if (sfile != NULL)
16518334Speter    {
16618334Speter      char *p = strrchr (sfile, '/');
16718334Speter      if (p != NULL)
16818334Speter	sfile = p + 1;
16990075Sobrien    }
17090075Sobrien#endif
17190075Sobrien
17290075Sobrien  for (objfile = object_files;
17390075Sobrien       objfile != NULL && found_symbol == NULL;
17490075Sobrien       objfile = objfile->next)
17590075Sobrien    {
17690075Sobrien      if (objf == NULL || objf == objfile)
17790075Sobrien	{
17890075Sobrien	  /* Do two passes: the first over the ordinary hash table,
17990075Sobrien	     and the second over the demangled hash table.  */
18090075Sobrien        int pass;
18190075Sobrien
18290075Sobrien        for (pass = 1; pass <= 2 && found_symbol == NULL; pass++)
18390075Sobrien	    {
18418334Speter            /* Select hash list according to pass.  */
18518334Speter            if (pass == 1)
18618334Speter              msymbol = objfile->msymbol_hash[hash];
18790075Sobrien            else
18890075Sobrien              msymbol = objfile->msymbol_demangled_hash[dem_hash];
18990075Sobrien
19090075Sobrien            while (msymbol != NULL && found_symbol == NULL)
191117395Skan		{
19290075Sobrien		  /* FIXME: carlton/2003-02-27: This is an unholy
19390075Sobrien		     mixture of linkage names and natural names.  If
19490075Sobrien		     you want to test the linkage names with strcmp,
19590075Sobrien		     do that.  If you want to test the natural names
196132718Skan		     with strcmp_iw, use SYMBOL_MATCHES_NATURAL_NAME.  */
19790075Sobrien		  if (strcmp (DEPRECATED_SYMBOL_NAME (msymbol), (name)) == 0
19850397Sobrien		      || (SYMBOL_DEMANGLED_NAME (msymbol) != NULL
19950397Sobrien			  && strcmp_iw (SYMBOL_DEMANGLED_NAME (msymbol),
20018334Speter					(name)) == 0))
20118334Speter		    {
20218334Speter                    switch (MSYMBOL_TYPE (msymbol))
20318334Speter                      {
20418334Speter                      case mst_file_text:
20590075Sobrien                      case mst_file_data:
20690075Sobrien                      case mst_file_bss:
20790075Sobrien#ifdef SOFUN_ADDRESS_MAYBE_MISSING
20890075Sobrien                        if (sfile == NULL
20990075Sobrien			    || strcmp (msymbol->filename, sfile) == 0)
21090075Sobrien                          found_file_symbol = msymbol;
21190075Sobrien#else
21290075Sobrien                        /* We have neither the ability nor the need to
21390075Sobrien                           deal with the SFILE parameter.  If we find
21490075Sobrien                           more than one symbol, just return the latest
21590075Sobrien                           one (the user can't expect useful behavior in
21690075Sobrien                           that case).  */
21718334Speter                        found_file_symbol = msymbol;
21818334Speter#endif
21918334Speter                        break;
22018334Speter
22118334Speter                      case mst_solib_trampoline:
22290075Sobrien
223132718Skan                        /* If a trampoline symbol is found, we prefer to
22418334Speter                           keep looking for the *real* symbol. If the
22590075Sobrien                           actual symbol is not found, then we'll use the
22618334Speter                           trampoline entry. */
22718334Speter                        if (trampoline_symbol == NULL)
22818334Speter                          trampoline_symbol = msymbol;
22918334Speter                        break;
23090075Sobrien
23190075Sobrien                      case mst_unknown:
23218334Speter                      default:
23318334Speter                        found_symbol = msymbol;
23418334Speter                        break;
235132718Skan                      }
236132718Skan		    }
237132718Skan
238132718Skan                /* Find the next symbol on the hash chain.  */
23918334Speter                if (pass == 1)
24018334Speter                  msymbol = msymbol->hash_next;
24190075Sobrien                else
24290075Sobrien                  msymbol = msymbol->demangled_hash_next;
24390075Sobrien		}
24490075Sobrien	    }
24590075Sobrien	}
24690075Sobrien    }
24790075Sobrien  /* External symbols are best.  */
24890075Sobrien  if (found_symbol)
24990075Sobrien    return found_symbol;
25090075Sobrien
25118334Speter  /* File-local symbols are next best.  */
25218334Speter  if (found_file_symbol)
25318334Speter    return found_file_symbol;
25418334Speter
25518334Speter  /* Symbols for shared library trampolines are next best.  */
25618334Speter  if (trampoline_symbol)
25790075Sobrien    return trampoline_symbol;
25890075Sobrien
25990075Sobrien  return NULL;
26090075Sobrien}
26190075Sobrien
26290075Sobrien/* Look through all the current minimal symbol tables and find the
26318334Speter   first minimal symbol that matches NAME and has text type.  If OBJF
26418334Speter   is non-NULL, limit the search to that objfile.  Returns a pointer
26590075Sobrien   to the minimal symbol that matches, or NULL if no match is found.
26618334Speter
26790075Sobrien   This function only searches the mangled (linkage) names.  */
26890075Sobrien
26990075Sobrienstruct minimal_symbol *
27090075Sobrienlookup_minimal_symbol_text (const char *name, struct objfile *objf)
27190075Sobrien{
27290075Sobrien  struct objfile *objfile;
27390075Sobrien  struct minimal_symbol *msymbol;
27490075Sobrien  struct minimal_symbol *found_symbol = NULL;
27550397Sobrien  struct minimal_symbol *found_file_symbol = NULL;
27650397Sobrien
27718334Speter  unsigned int hash = msymbol_hash (name) % MINIMAL_SYMBOL_HASH_SIZE;
27818334Speter
27918334Speter  for (objfile = object_files;
28018334Speter       objfile != NULL && found_symbol == NULL;
28118334Speter       objfile = objfile->next)
28218334Speter    {
283132718Skan      if (objf == NULL || objf == objfile)
284132718Skan	{
285132718Skan	  for (msymbol = objfile->msymbol_hash[hash];
286132718Skan	       msymbol != NULL && found_symbol == NULL;
287132718Skan	       msymbol = msymbol->hash_next)
288132718Skan	    {
289132718Skan	      if (strcmp (SYMBOL_LINKAGE_NAME (msymbol), name) == 0 &&
290132718Skan		  (MSYMBOL_TYPE (msymbol) == mst_text ||
291132718Skan		   MSYMBOL_TYPE (msymbol) == mst_file_text))
292132718Skan		{
293132718Skan		  switch (MSYMBOL_TYPE (msymbol))
294132718Skan		    {
295132718Skan		    case mst_file_text:
296132718Skan		      found_file_symbol = msymbol;
297132718Skan		      break;
298132718Skan		    default:
299132718Skan		      found_symbol = msymbol;
300132718Skan		      break;
301132718Skan		    }
302132718Skan		}
303132718Skan	    }
304132718Skan	}
305132718Skan    }
306132718Skan  /* External symbols are best.  */
307132718Skan  if (found_symbol)
308132718Skan    return found_symbol;
309132718Skan
310132718Skan  /* File-local symbols are next best.  */
311132718Skan  if (found_file_symbol)
312132718Skan    return found_file_symbol;
313132718Skan
314132718Skan  return NULL;
315132718Skan}
316132718Skan
317132718Skan/* Look through all the current minimal symbol tables and find the
318132718Skan   first minimal symbol that matches NAME and is a solib trampoline.
319132718Skan   If OBJF is non-NULL, limit the search to that objfile.  Returns a
320132718Skan   pointer to the minimal symbol that matches, or NULL if no match is
321132718Skan   found.
322132718Skan
323132718Skan   This function only searches the mangled (linkage) names.  */
324132718Skan
325132718Skanstruct minimal_symbol *
326132718Skanlookup_minimal_symbol_solib_trampoline (const char *name,
327132718Skan					struct objfile *objf)
328132718Skan{
329132718Skan  struct objfile *objfile;
330132718Skan  struct minimal_symbol *msymbol;
331132718Skan  struct minimal_symbol *found_symbol = NULL;
332132718Skan
333132718Skan  unsigned int hash = msymbol_hash (name) % MINIMAL_SYMBOL_HASH_SIZE;
334132718Skan
335132718Skan  for (objfile = object_files;
336132718Skan       objfile != NULL && found_symbol == NULL;
337132718Skan       objfile = objfile->next)
338132718Skan    {
339132718Skan      if (objf == NULL || objf == objfile)
340132718Skan	{
341132718Skan	  for (msymbol = objfile->msymbol_hash[hash];
342132718Skan	       msymbol != NULL && found_symbol == NULL;
343132718Skan	       msymbol = msymbol->hash_next)
344132718Skan	    {
345132718Skan	      if (strcmp (SYMBOL_LINKAGE_NAME (msymbol), name) == 0 &&
346132718Skan		  MSYMBOL_TYPE (msymbol) == mst_solib_trampoline)
347132718Skan		return msymbol;
348132718Skan	    }
349132718Skan	}
350132718Skan    }
351132718Skan
352132718Skan  return NULL;
353132718Skan}
354132718Skan
355132718Skan
356132718Skan/* Search through the minimal symbol table for each objfile and find
357132718Skan   the symbol whose address is the largest address that is still less
358132718Skan   than or equal to PC, and matches SECTION (if non-NULL).  Returns a
359132718Skan   pointer to the minimal symbol if such a symbol is found, or NULL if
360132718Skan   PC is not in a suitable range.  Note that we need to look through
361132718Skan   ALL the minimal symbol tables before deciding on the symbol that
362132718Skan   comes closest to the specified PC.  This is because objfiles can
363132718Skan   overlap, for example objfile A has .text at 0x100 and .data at
364132718Skan   0x40000 and objfile B has .text at 0x234 and .data at 0x40048.  */
365132718Skan
366117395Skanstruct minimal_symbol *
36718334Speterlookup_minimal_symbol_by_pc_section (CORE_ADDR pc, asection *section)
368117395Skan{
36990075Sobrien  int lo;
37090075Sobrien  int hi;
37118334Speter  int new;
37218334Speter  struct objfile *objfile;
373132718Skan  struct minimal_symbol *msymbol;
37418334Speter  struct minimal_symbol *best_symbol = NULL;
37590075Sobrien  struct obj_section *pc_section;
37690075Sobrien
37790075Sobrien  /* PC has to be in a known section.  This ensures that anything
37818334Speter     beyond the end of the last segment doesn't appear to be part of
37918334Speter     the last function in the last segment.  */
38018334Speter  pc_section = find_pc_section (pc);
38118334Speter  if (pc_section == NULL)
38218334Speter    return NULL;
38318334Speter
38490075Sobrien  /* NOTE: cagney/2004-01-27: Removed code (added 2003-07-19) that was
38518334Speter     trying to force the PC into a valid section as returned by
38618334Speter     find_pc_section.  It broke IRIX 6.5 mdebug which relies on this
38718334Speter     code returning an absolute symbol - the problem was that
38818334Speter     find_pc_section wasn't returning an absolute section and hence
38950397Sobrien     the code below would skip over absolute symbols.  Since the
39090075Sobrien     original problem was with finding a frame's function, and that
39150397Sobrien     uses [indirectly] lookup_minimal_symbol_by_pc, the original
39250397Sobrien     problem has been fixed by having that function use
39350397Sobrien     find_pc_section.  */
39450397Sobrien
39550397Sobrien  for (objfile = object_files;
39650397Sobrien       objfile != NULL;
39790075Sobrien       objfile = objfile->next)
39850397Sobrien    {
39950397Sobrien      /* If this objfile has a minimal symbol table, go search it using
40018334Speter         a binary search.  Note that a minimal symbol table always consists
40118334Speter         of at least two symbols, a "real" symbol and the terminating
40218334Speter         "null symbol".  If there are no real symbols, then there is no
40318334Speter         minimal symbol table at all. */
40418334Speter
40518334Speter      if (objfile->minimal_symbol_count > 0)
40690075Sobrien	{
40718334Speter          msymbol = objfile->msymbols;
40818334Speter	  lo = 0;
409132718Skan	  hi = objfile->minimal_symbol_count - 1;
41018334Speter
41118334Speter	  /* This code assumes that the minimal symbols are sorted by
41218334Speter	     ascending address values.  If the pc value is greater than or
41318334Speter	     equal to the first symbol's address, then some symbol in this
41418334Speter	     minimal symbol table is a suitable candidate for being the
41518334Speter	     "best" symbol.  This includes the last real symbol, for cases
41618334Speter	     where the pc value is larger than any address in this vector.
41718334Speter
41818334Speter	     By iterating until the address associated with the current
41918334Speter	     hi index (the endpoint of the test interval) is less than
42018334Speter	     or equal to the desired pc value, we accomplish two things:
42118334Speter	     (1) the case where the pc value is larger than any minimal
42218334Speter	     symbol address is trivially solved, (2) the address associated
42318334Speter	     with the hi index is always the one we want when the interation
42418334Speter	     terminates.  In essence, we are iterating the test interval
42518334Speter	     down until the pc value is pushed out of it from the high end.
42618334Speter
42718334Speter	     Warning: this code is trickier than it would appear at first. */
428132718Skan
42918334Speter	  /* Should also require that pc is <= end of objfile.  FIXME! */
43018334Speter	  if (pc >= SYMBOL_VALUE_ADDRESS (&msymbol[lo]))
43118334Speter	    {
43218334Speter	      while (SYMBOL_VALUE_ADDRESS (&msymbol[hi]) > pc)
43318334Speter		{
43418334Speter		  /* pc is still strictly less than highest address */
43518334Speter		  /* Note "new" will always be >= lo */
43618334Speter		  new = (lo + hi) / 2;
43718334Speter		  if ((SYMBOL_VALUE_ADDRESS (&msymbol[new]) >= pc) ||
43818334Speter		      (lo == new))
43918334Speter		    {
44018334Speter		      hi = new;
44118334Speter		    }
44290075Sobrien		  else
44390075Sobrien		    {
44490075Sobrien		      lo = new;
44590075Sobrien		    }
446117395Skan		}
44790075Sobrien
44890075Sobrien	      /* If we have multiple symbols at the same address, we want
44990075Sobrien	         hi to point to the last one.  That way we can find the
450132718Skan	         right symbol if it has an index greater than hi.  */
45190075Sobrien	      while (hi < objfile->minimal_symbol_count - 1
45290075Sobrien		     && (SYMBOL_VALUE_ADDRESS (&msymbol[hi])
45390075Sobrien			 == SYMBOL_VALUE_ADDRESS (&msymbol[hi + 1])))
45490075Sobrien		hi++;
45590075Sobrien
45690075Sobrien	      /* The minimal symbol indexed by hi now is the best one in this
45790075Sobrien	         objfile's minimal symbol table.  See if it is the best one
45890075Sobrien	         overall. */
45990075Sobrien
46090075Sobrien	      /* Skip any absolute symbols.  This is apparently what adb
46190075Sobrien	         and dbx do, and is needed for the CM-5.  There are two
462132718Skan	         known possible problems: (1) on ELF, apparently end, edata,
46390075Sobrien	         etc. are absolute.  Not sure ignoring them here is a big
46490075Sobrien	         deal, but if we want to use them, the fix would go in
46590075Sobrien	         elfread.c.  (2) I think shared library entry points on the
46690075Sobrien	         NeXT are absolute.  If we want special handling for this
46790075Sobrien	         it probably should be triggered by a special
46890075Sobrien	         mst_abs_or_lib or some such.  */
46990075Sobrien	      while (hi >= 0
47090075Sobrien		     && msymbol[hi].type == mst_abs)
47190075Sobrien		--hi;
47290075Sobrien
47390075Sobrien	      /* If "section" specified, skip any symbol from wrong section */
47490075Sobrien	      /* This is the new code that distinguishes it from the old function */
47590075Sobrien	      if (section)
47690075Sobrien		while (hi >= 0
47790075Sobrien		       /* Some types of debug info, such as COFF,
47890075Sobrien			  don't fill the bfd_section member, so don't
47990075Sobrien			  throw away symbols on those platforms.  */
48090075Sobrien		       && SYMBOL_BFD_SECTION (&msymbol[hi]) != NULL
48190075Sobrien		       && SYMBOL_BFD_SECTION (&msymbol[hi]) != section)
48290075Sobrien		  --hi;
48390075Sobrien
48490075Sobrien	      if (hi >= 0
48590075Sobrien		  && ((best_symbol == NULL) ||
48690075Sobrien		      (SYMBOL_VALUE_ADDRESS (best_symbol) <
48790075Sobrien		       SYMBOL_VALUE_ADDRESS (&msymbol[hi]))))
48890075Sobrien		{
48990075Sobrien		  best_symbol = &msymbol[hi];
49090075Sobrien		}
49190075Sobrien	    }
49290075Sobrien	}
49390075Sobrien    }
49490075Sobrien  return (best_symbol);
49590075Sobrien}
49690075Sobrien
49790075Sobrien/* Backward compatibility: search through the minimal symbol table
49890075Sobrien   for a matching PC (no section given) */
49990075Sobrien
50090075Sobrienstruct minimal_symbol *
50190075Sobrienlookup_minimal_symbol_by_pc (CORE_ADDR pc)
50290075Sobrien{
50390075Sobrien  /* NOTE: cagney/2004-01-27: This was using find_pc_mapped_section to
50490075Sobrien     force the section but that (well unless you're doing overlay
50590075Sobrien     debugging) always returns NULL making the call somewhat useless.  */
50690075Sobrien  struct obj_section *section = find_pc_section (pc);
50790075Sobrien  if (section == NULL)
50890075Sobrien    return NULL;
50990075Sobrien  return lookup_minimal_symbol_by_pc_section (pc, section->the_bfd_section);
51090075Sobrien}
51190075Sobrien
51290075Sobrien
51390075Sobrien/* Return leading symbol character for a BFD. If BFD is NULL,
51490075Sobrien   return the leading symbol character from the main objfile.  */
51590075Sobrien
51690075Sobrienstatic int get_symbol_leading_char (bfd *);
51790075Sobrien
51890075Sobrienstatic int
51990075Sobrienget_symbol_leading_char (bfd *abfd)
52090075Sobrien{
52190075Sobrien  if (abfd != NULL)
52290075Sobrien    return bfd_get_symbol_leading_char (abfd);
52390075Sobrien  if (symfile_objfile != NULL && symfile_objfile->obfd != NULL)
52490075Sobrien    return bfd_get_symbol_leading_char (symfile_objfile->obfd);
52590075Sobrien  return 0;
52690075Sobrien}
52790075Sobrien
52890075Sobrien/* Prepare to start collecting minimal symbols.  Note that presetting
52990075Sobrien   msym_bunch_index to BUNCH_SIZE causes the first call to save a minimal
53090075Sobrien   symbol to allocate the memory for the first bunch. */
53190075Sobrien
53290075Sobrienvoid
53390075Sobrieninit_minimal_symbol_collection (void)
53490075Sobrien{
53590075Sobrien  msym_count = 0;
53690075Sobrien  msym_bunch = NULL;
53790075Sobrien  msym_bunch_index = BUNCH_SIZE;
53890075Sobrien}
53990075Sobrien
54090075Sobrienvoid
54190075Sobrienprim_record_minimal_symbol (const char *name, CORE_ADDR address,
54290075Sobrien			    enum minimal_symbol_type ms_type,
54390075Sobrien			    struct objfile *objfile)
54490075Sobrien{
54590075Sobrien  int section;
54690075Sobrien
54790075Sobrien  switch (ms_type)
54890075Sobrien    {
54990075Sobrien    case mst_text:
55090075Sobrien    case mst_file_text:
55190075Sobrien    case mst_solib_trampoline:
55290075Sobrien      section = SECT_OFF_TEXT (objfile);
55390075Sobrien      break;
55490075Sobrien    case mst_data:
55590075Sobrien    case mst_file_data:
55690075Sobrien      section = SECT_OFF_DATA (objfile);
55790075Sobrien      break;
55890075Sobrien    case mst_bss:
55990075Sobrien    case mst_file_bss:
56090075Sobrien      section = SECT_OFF_BSS (objfile);
56190075Sobrien      break;
56290075Sobrien    default:
56390075Sobrien      section = -1;
56490075Sobrien    }
56590075Sobrien
56690075Sobrien  prim_record_minimal_symbol_and_info (name, address, ms_type,
56790075Sobrien				       NULL, section, NULL, objfile);
56890075Sobrien}
56990075Sobrien
57090075Sobrien/* Record a minimal symbol in the msym bunches.  Returns the symbol
57190075Sobrien   newly created.  */
57290075Sobrien
57390075Sobrienstruct minimal_symbol *
574117395Skanprim_record_minimal_symbol_and_info (const char *name, CORE_ADDR address,
575117395Skan				     enum minimal_symbol_type ms_type,
576117395Skan				     char *info, int section,
577117395Skan				     asection *bfd_section,
578132718Skan				     struct objfile *objfile)
579117395Skan{
580117395Skan  struct msym_bunch *new;
581117395Skan  struct minimal_symbol *msymbol;
582117395Skan
583117395Skan  if (ms_type == mst_file_text)
584117395Skan    {
585117395Skan      /* Don't put gcc_compiled, __gnu_compiled_cplus, and friends into
586117395Skan         the minimal symbols, because if there is also another symbol
587117395Skan         at the same address (e.g. the first function of the file),
588117395Skan         lookup_minimal_symbol_by_pc would have no way of getting the
589117395Skan         right one.  */
590117395Skan      if (name[0] == 'g'
591117395Skan	  && (strcmp (name, GCC_COMPILED_FLAG_SYMBOL) == 0
592117395Skan	      || strcmp (name, GCC2_COMPILED_FLAG_SYMBOL) == 0))
593117395Skan	return (NULL);
594117395Skan
595117395Skan      {
596117395Skan	const char *tempstring = name;
597117395Skan	if (tempstring[0] == get_symbol_leading_char (objfile->obfd))
598117395Skan	  ++tempstring;
599117395Skan	if (strncmp (tempstring, "__gnu_compiled", 14) == 0)
600117395Skan	  return (NULL);
601117395Skan      }
602117395Skan    }
603117395Skan
604117395Skan  if (msym_bunch_index == BUNCH_SIZE)
605117395Skan    {
606117395Skan      new = (struct msym_bunch *) xmalloc (sizeof (struct msym_bunch));
607117395Skan      msym_bunch_index = 0;
608117395Skan      new->next = msym_bunch;
609117395Skan      msym_bunch = new;
610117395Skan    }
611117395Skan  msymbol = &msym_bunch->contents[msym_bunch_index];
612117395Skan  SYMBOL_INIT_LANGUAGE_SPECIFIC (msymbol, language_unknown);
613117395Skan  SYMBOL_LANGUAGE (msymbol) = language_auto;
614117395Skan  SYMBOL_SET_NAMES (msymbol, (char *)name, strlen (name), objfile);
615117395Skan
616117395Skan  SYMBOL_VALUE_ADDRESS (msymbol) = address;
617117395Skan  SYMBOL_SECTION (msymbol) = section;
618117395Skan  SYMBOL_BFD_SECTION (msymbol) = bfd_section;
619117395Skan
620117395Skan  MSYMBOL_TYPE (msymbol) = ms_type;
621117395Skan  /* FIXME:  This info, if it remains, needs its own field.  */
622117395Skan  MSYMBOL_INFO (msymbol) = info;	/* FIXME! */
623117395Skan  MSYMBOL_SIZE (msymbol) = 0;
624117395Skan
625117395Skan  /* The hash pointers must be cleared! If they're not,
626117395Skan     add_minsym_to_hash_table will NOT add this msymbol to the hash table. */
627132718Skan  msymbol->hash_next = NULL;
628117395Skan  msymbol->demangled_hash_next = NULL;
629117395Skan
630117395Skan  msym_bunch_index++;
631117395Skan  msym_count++;
632117395Skan  OBJSTAT (objfile, n_minsyms++);
633117395Skan  return msymbol;
634117395Skan}
635117395Skan
636117395Skan/* Compare two minimal symbols by address and return a signed result based
637117395Skan   on unsigned comparisons, so that we sort into unsigned numeric order.
638117395Skan   Within groups with the same address, sort by name.  */
639117395Skan
640117395Skanstatic int
641117395Skancompare_minimal_symbols (const void *fn1p, const void *fn2p)
642117395Skan{
643117395Skan  const struct minimal_symbol *fn1;
644117395Skan  const struct minimal_symbol *fn2;
645117395Skan
64690075Sobrien  fn1 = (const struct minimal_symbol *) fn1p;
64790075Sobrien  fn2 = (const struct minimal_symbol *) fn2p;
64890075Sobrien
64990075Sobrien  if (SYMBOL_VALUE_ADDRESS (fn1) < SYMBOL_VALUE_ADDRESS (fn2))
650132718Skan    {
65190075Sobrien      return (-1);		/* addr 1 is less than addr 2 */
65290075Sobrien    }
65390075Sobrien  else if (SYMBOL_VALUE_ADDRESS (fn1) > SYMBOL_VALUE_ADDRESS (fn2))
65490075Sobrien    {
65590075Sobrien      return (1);		/* addr 1 is greater than addr 2 */
65690075Sobrien    }
65790075Sobrien  else
65890075Sobrien    /* addrs are equal: sort by name */
65990075Sobrien    {
66090075Sobrien      char *name1 = SYMBOL_LINKAGE_NAME (fn1);
66190075Sobrien      char *name2 = SYMBOL_LINKAGE_NAME (fn2);
66290075Sobrien
66390075Sobrien      if (name1 && name2)	/* both have names */
66490075Sobrien	return strcmp (name1, name2);
66590075Sobrien      else if (name2)
66690075Sobrien	return 1;		/* fn1 has no name, so it is "less" */
66796263Sobrien      else if (name1)		/* fn2 has no name, so it is "less" */
66890075Sobrien	return -1;
66990075Sobrien      else
67090075Sobrien	return (0);		/* neither has a name, so they're equal. */
67190075Sobrien    }
67290075Sobrien}
67390075Sobrien
67490075Sobrien/* Discard the currently collected minimal symbols, if any.  If we wish
67590075Sobrien   to save them for later use, we must have already copied them somewhere
67690075Sobrien   else before calling this function.
67790075Sobrien
67890075Sobrien   FIXME:  We could allocate the minimal symbol bunches on their own
67990075Sobrien   obstack and then simply blow the obstack away when we are done with
68090075Sobrien   it.  Is it worth the extra trouble though? */
68190075Sobrien
68290075Sobrienstatic void
68390075Sobriendo_discard_minimal_symbols_cleanup (void *arg)
68490075Sobrien{
68590075Sobrien  struct msym_bunch *next;
68690075Sobrien
68790075Sobrien  while (msym_bunch != NULL)
68890075Sobrien    {
68990075Sobrien      next = msym_bunch->next;
69090075Sobrien      xfree (msym_bunch);
69190075Sobrien      msym_bunch = next;
69290075Sobrien    }
69390075Sobrien}
69490075Sobrien
69590075Sobrienstruct cleanup *
69690075Sobrienmake_cleanup_discard_minimal_symbols (void)
69790075Sobrien{
69890075Sobrien  return make_cleanup (do_discard_minimal_symbols_cleanup, 0);
69990075Sobrien}
70090075Sobrien
70190075Sobrien
70290075Sobrien
70390075Sobrien/* Compact duplicate entries out of a minimal symbol table by walking
70490075Sobrien   through the table and compacting out entries with duplicate addresses
70590075Sobrien   and matching names.  Return the number of entries remaining.
70690075Sobrien
70790075Sobrien   On entry, the table resides between msymbol[0] and msymbol[mcount].
70818334Speter   On exit, it resides between msymbol[0] and msymbol[result_count].
70918334Speter
71018334Speter   When files contain multiple sources of symbol information, it is
71118334Speter   possible for the minimal symbol table to contain many duplicate entries.
71218334Speter   As an example, SVR4 systems use ELF formatted object files, which
713132718Skan   usually contain at least two different types of symbol tables (a
71418334Speter   standard ELF one and a smaller dynamic linking table), as well as
71590075Sobrien   DWARF debugging information for files compiled with -g.
71690075Sobrien
71790075Sobrien   Without compacting, the minimal symbol table for gdb itself contains
71818334Speter   over a 1000 duplicates, about a third of the total table size.  Aside
71918334Speter   from the potential trap of not noticing that two successive entries
72018334Speter   identify the same location, this duplication impacts the time required
72118334Speter   to linearly scan the table, which is done in a number of places.  So we
72218334Speter   just do one linear scan here and toss out the duplicates.
72318334Speter
72418334Speter   Note that we are not concerned here about recovering the space that
72518334Speter   is potentially freed up, because the strings themselves are allocated
72618334Speter   on the objfile_obstack, and will get automatically freed when the symbol
72718334Speter   table is freed.  The caller can free up the unused minimal symbols at
72818334Speter   the end of the compacted region if their allocation strategy allows it.
72918334Speter
73018334Speter   Also note we only go up to the next to last entry within the loop
73118334Speter   and then copy the last entry explicitly after the loop terminates.
73218334Speter
73318334Speter   Since the different sources of information for each symbol may
73418334Speter   have different levels of "completeness", we may have duplicates
73518334Speter   that have one entry with type "mst_unknown" and the other with a
73618334Speter   known type.  So if the one we are leaving alone has type mst_unknown,
73718334Speter   overwrite its type with the type from the one we are compacting out.  */
73818334Speter
73918334Speterstatic int
74018334Spetercompact_minimal_symbols (struct minimal_symbol *msymbol, int mcount,
74118334Speter			 struct objfile *objfile)
74218334Speter{
74318334Speter  struct minimal_symbol *copyfrom;
74496263Sobrien  struct minimal_symbol *copyto;
74518334Speter
74618334Speter  if (mcount > 0)
74718334Speter    {
748117395Skan      copyfrom = copyto = msymbol;
74950397Sobrien      while (copyfrom < msymbol + mcount - 1)
75050397Sobrien	{
75118334Speter	  if (SYMBOL_VALUE_ADDRESS (copyfrom)
75218334Speter	      == SYMBOL_VALUE_ADDRESS ((copyfrom + 1))
75318334Speter	      && strcmp (SYMBOL_LINKAGE_NAME (copyfrom),
75418334Speter			 SYMBOL_LINKAGE_NAME ((copyfrom + 1))) == 0)
75518334Speter	    {
75618334Speter	      if (MSYMBOL_TYPE ((copyfrom + 1)) == mst_unknown)
75718334Speter		{
75818334Speter		  MSYMBOL_TYPE ((copyfrom + 1)) = MSYMBOL_TYPE (copyfrom);
75918334Speter		}
76018334Speter	      copyfrom++;
76118334Speter	    }
76290075Sobrien	  else
76318334Speter	    *copyto++ = *copyfrom++;
76418334Speter	}
76518334Speter      *copyto++ = *copyfrom++;
76618334Speter      mcount = copyto - msymbol;
76718334Speter    }
76818334Speter  return (mcount);
76918334Speter}
77018334Speter
77118334Speter/* Build (or rebuild) the minimal symbol hash tables.  This is necessary
77218334Speter   after compacting or sorting the table since the entries move around
77318334Speter   thus causing the internal minimal_symbol pointers to become jumbled. */
77418334Speter
77518334Speterstatic void
77618334Speterbuild_minimal_symbol_hash_tables (struct objfile *objfile)
77718334Speter{
778132718Skan  int i;
77918334Speter  struct minimal_symbol *msym;
78090075Sobrien
78190075Sobrien  /* Clear the hash tables. */
78290075Sobrien  for (i = 0; i < MINIMAL_SYMBOL_HASH_SIZE; i++)
78318334Speter    {
78418334Speter      objfile->msymbol_hash[i] = 0;
78518334Speter      objfile->msymbol_demangled_hash[i] = 0;
78618334Speter    }
78718334Speter
78818334Speter  /* Now, (re)insert the actual entries. */
78952284Sobrien  for (i = objfile->minimal_symbol_count, msym = objfile->msymbols;
79052284Sobrien       i > 0;
79152284Sobrien       i--, msym++)
79252284Sobrien    {
793132718Skan      msym->hash_next = 0;
79452284Sobrien      add_minsym_to_hash_table (msym, objfile->msymbol_hash);
79590075Sobrien
79652284Sobrien      msym->demangled_hash_next = 0;
79752284Sobrien      if (SYMBOL_DEMANGLED_NAME (msym) != NULL)
79852284Sobrien	add_minsym_to_demangled_hash_table (msym,
79952284Sobrien                                            objfile->msymbol_demangled_hash);
80052284Sobrien    }
80152284Sobrien}
80218334Speter
80318334Speter/* Add the minimal symbols in the existing bunches to the objfile's official
80418334Speter   minimal symbol table.  In most cases there is no minimal symbol table yet
80518334Speter   for this objfile, and the existing bunches are used to create one.  Once
806132718Skan   in a while (for shared libraries for example), we add symbols (e.g. common
80718334Speter   symbols) to an existing objfile.
80890075Sobrien
80918334Speter   Because of the way minimal symbols are collected, we generally have no way
81018334Speter   of knowing what source language applies to any particular minimal symbol.
81118334Speter   Specifically, we have no way of knowing if the minimal symbol comes from a
81218334Speter   C++ compilation unit or not.  So for the sake of supporting cached
81318334Speter   demangled C++ names, we have no choice but to try and demangle each new one
81490075Sobrien   that comes in.  If the demangling succeeds, then we assume it is a C++
81518334Speter   symbol and set the symbol's language and demangled name fields
81618334Speter   appropriately.  Note that in order to avoid unnecessary demanglings, and
81718334Speter   allocating obstack space that subsequently can't be freed for the demangled
81818334Speter   names, we mark all newly added symbols with language_auto.  After
81918334Speter   compaction of the minimal symbols, we go back and scan the entire minimal
82018334Speter   symbol table looking for these new symbols.  For each new symbol we attempt
82118334Speter   to demangle it, and if successful, record it as a language_cplus symbol
82218334Speter   and cache the demangled form on the symbol obstack.  Symbols which don't
82318334Speter   demangle are marked as language_unknown symbols, which inhibits future
82418334Speter   attempts to demangle them if we later add more minimal symbols. */
82518334Speter
82618334Spetervoid
82718334Speterinstall_minimal_symbols (struct objfile *objfile)
828132718Skan{
82918334Speter  int bindex;
83018334Speter  int mcount;
83118334Speter  struct msym_bunch *bunch;
83218334Speter  struct minimal_symbol *msymbols;
83318334Speter  int alloc_count;
83418334Speter  char leading_char;
83518334Speter
83618334Speter  if (msym_count > 0)
83718334Speter    {
83818334Speter      /* Allocate enough space in the obstack, into which we will gather the
83918334Speter         bunches of new and existing minimal symbols, sort them, and then
84018334Speter         compact out the duplicate entries.  Once we have a final table,
84118334Speter         we will give back the excess space.  */
84218334Speter
84318334Speter      alloc_count = msym_count + objfile->minimal_symbol_count + 1;
84418334Speter      obstack_blank (&objfile->objfile_obstack,
84518334Speter		     alloc_count * sizeof (struct minimal_symbol));
84618334Speter      msymbols = (struct minimal_symbol *)
84718334Speter	obstack_base (&objfile->objfile_obstack);
84818334Speter
84918334Speter      /* Copy in the existing minimal symbols, if there are any.  */
85018334Speter
85118334Speter      if (objfile->minimal_symbol_count)
85250397Sobrien	memcpy ((char *) msymbols, (char *) objfile->msymbols,
85318334Speter	    objfile->minimal_symbol_count * sizeof (struct minimal_symbol));
85418334Speter
85518334Speter      /* Walk through the list of minimal symbol bunches, adding each symbol
85618334Speter         to the new contiguous array of symbols.  Note that we start with the
85718334Speter         current, possibly partially filled bunch (thus we use the current
85850397Sobrien         msym_bunch_index for the first bunch we copy over), and thereafter
85918334Speter         each bunch is full. */
86018334Speter
86118334Speter      mcount = objfile->minimal_symbol_count;
86290075Sobrien      leading_char = get_symbol_leading_char (objfile->obfd);
86318334Speter
86418334Speter      for (bunch = msym_bunch; bunch != NULL; bunch = bunch->next)
86518334Speter	{
86618334Speter	  for (bindex = 0; bindex < msym_bunch_index; bindex++, mcount++)
86718334Speter	    {
86890075Sobrien	      msymbols[mcount] = bunch->contents[bindex];
86990075Sobrien	      if (SYMBOL_LINKAGE_NAME (&msymbols[mcount])[0] == leading_char)
87090075Sobrien		{
87118334Speter		  SYMBOL_LINKAGE_NAME (&msymbols[mcount])++;
87218334Speter		}
87390075Sobrien	    }
87490075Sobrien	  msym_bunch_index = BUNCH_SIZE;
87590075Sobrien	}
87690075Sobrien
87790075Sobrien      /* Sort the minimal symbols by address.  */
87818334Speter
87918334Speter      qsort (msymbols, mcount, sizeof (struct minimal_symbol),
88018334Speter	     compare_minimal_symbols);
88118334Speter
88250397Sobrien      /* Compact out any duplicates, and free up whatever space we are
883117395Skan         no longer using.  */
88490075Sobrien
88590075Sobrien      mcount = compact_minimal_symbols (msymbols, mcount, objfile);
88690075Sobrien
88790075Sobrien      obstack_blank (&objfile->objfile_obstack,
88890075Sobrien	       (mcount + 1 - alloc_count) * sizeof (struct minimal_symbol));
88990075Sobrien      msymbols = (struct minimal_symbol *)
89090075Sobrien	obstack_finish (&objfile->objfile_obstack);
89190075Sobrien
89290075Sobrien      /* We also terminate the minimal symbol table with a "null symbol",
89390075Sobrien         which is *not* included in the size of the table.  This makes it
89490075Sobrien         easier to find the end of the table when we are handed a pointer
89550397Sobrien         to some symbol in the middle of it.  Zero out the fields in the
89650397Sobrien         "null symbol" allocated at the end of the array.  Note that the
89718334Speter         symbol count does *not* include this null symbol, which is why it
89818334Speter         is indexed by mcount and not mcount-1. */
89918334Speter
90018334Speter      SYMBOL_LINKAGE_NAME (&msymbols[mcount]) = NULL;
90118334Speter      SYMBOL_VALUE_ADDRESS (&msymbols[mcount]) = 0;
90250397Sobrien      MSYMBOL_INFO (&msymbols[mcount]) = NULL;
90318334Speter      MSYMBOL_SIZE (&msymbols[mcount]) = 0;
90418334Speter      MSYMBOL_TYPE (&msymbols[mcount]) = mst_unknown;
905132718Skan      SYMBOL_INIT_LANGUAGE_SPECIFIC (&msymbols[mcount], language_unknown);
90618334Speter
90790075Sobrien      /* Attach the minimal symbol table to the specified objfile.
90818334Speter         The strings themselves are also located in the objfile_obstack
90918334Speter         of this objfile.  */
91018334Speter
91118334Speter      objfile->minimal_symbol_count = mcount;
91218334Speter      objfile->msymbols = msymbols;
91390075Sobrien
91418334Speter      /* Try to guess the appropriate C++ ABI by looking at the names
91518334Speter	 of the minimal symbols in the table.  */
91618334Speter      {
91718334Speter	int i;
91818334Speter
91918334Speter	for (i = 0; i < mcount; i++)
92018334Speter	  {
92118334Speter	    /* If a symbol's name starts with _Z and was successfully
92218334Speter	       demangled, then we can assume we've found a GNU v3 symbol.
92318334Speter	       For now we set the C++ ABI globally; if the user is
92418334Speter	       mixing ABIs then the user will need to "set cp-abi"
925132718Skan	       manually.  */
92618334Speter	    const char *name = SYMBOL_LINKAGE_NAME (&objfile->msymbols[i]);
92790075Sobrien	    if (name[0] == '_' && name[1] == 'Z'
92818334Speter		&& SYMBOL_DEMANGLED_NAME (&objfile->msymbols[i]) != NULL)
92918334Speter	      {
93018334Speter		set_cp_abi_as_auto_default ("gnu-v3");
93118334Speter		break;
93218334Speter	      }
93390075Sobrien	  }
93418334Speter      }
93518334Speter
93618334Speter      /* Now build the hash tables; we can't do this incrementally
93718334Speter         at an earlier point since we weren't finished with the obstack
93818334Speter	 yet.  (And if the msymbol obstack gets moved, all the internal
93918334Speter	 pointers to other msymbols need to be adjusted.) */
940132718Skan      build_minimal_symbol_hash_tables (objfile);
94118334Speter    }
94218334Speter}
94318334Speter
944132718Skan/* Sort all the minimal symbols in OBJFILE.  */
945132718Skan
94618334Spetervoid
94718334Spetermsymbols_sort (struct objfile *objfile)
94818334Speter{
94918334Speter  qsort (objfile->msymbols, objfile->minimal_symbol_count,
95018334Speter	 sizeof (struct minimal_symbol), compare_minimal_symbols);
95118334Speter  build_minimal_symbol_hash_tables (objfile);
95218334Speter}
95318334Speter
95418334Speter/* Check if PC is in a shared library trampoline code stub.
95518334Speter   Return minimal symbol for the trampoline entry or NULL if PC is not
956132718Skan   in a trampoline code stub.  */
957132718Skan
95818334Speterstruct minimal_symbol *
95990075Sobrienlookup_solib_trampoline_symbol_by_pc (CORE_ADDR pc)
96018334Speter{
96118334Speter  struct minimal_symbol *msymbol = lookup_minimal_symbol_by_pc (pc);
96218334Speter
96352284Sobrien  if (msymbol != NULL && MSYMBOL_TYPE (msymbol) == mst_solib_trampoline)
96452284Sobrien    return msymbol;
96552284Sobrien  return NULL;
96652284Sobrien}
967132718Skan
96852284Sobrien/* If PC is in a shared library trampoline code stub, return the
96952284Sobrien   address of the `real' function belonging to the stub.
97090075Sobrien   Return 0 if PC is not in a trampoline code stub or if the real
97152284Sobrien   function is not found in the minimal symbol table.
97252284Sobrien
97352284Sobrien   We may fail to find the right function if a function with the
97452284Sobrien   same name is defined in more than one shared library, but this
97552284Sobrien   is considered bad programming style. We could return 0 if we find
97652284Sobrien   a duplicate function in case this matters someday.  */
97796263Sobrien
97852284SobrienCORE_ADDR
97952284Sobrienfind_solib_trampoline_target (CORE_ADDR pc)
98052284Sobrien{
98152284Sobrien  struct objfile *objfile;
98252284Sobrien  struct minimal_symbol *msymbol;
98352284Sobrien  struct minimal_symbol *tsymbol = lookup_solib_trampoline_symbol_by_pc (pc);
98452284Sobrien
98552284Sobrien  if (tsymbol != NULL)
98652284Sobrien    {
987117395Skan      ALL_MSYMBOLS (objfile, msymbol)
98852284Sobrien      {
98952284Sobrien	if (MSYMBOL_TYPE (msymbol) == mst_text
99052284Sobrien	    && strcmp (SYMBOL_LINKAGE_NAME (msymbol),
99152284Sobrien		       SYMBOL_LINKAGE_NAME (tsymbol)) == 0)
99252284Sobrien	  return SYMBOL_VALUE_ADDRESS (msymbol);
99352284Sobrien      }
99452284Sobrien    }
99552284Sobrien  return 0;
99652284Sobrien}
99752284Sobrien