xref: /dflybsd-src/contrib/gdb-7/gdb/blockframe.c (revision de8e141f24382815c10a4012d209bbbf7abf1112)
15796c8dcSSimon Schubert /* Get info from stack frames; convert between frames, blocks,
25796c8dcSSimon Schubert    functions and pc values.
35796c8dcSSimon Schubert 
4*ef5ccd6cSJohn Marino    Copyright (C) 1986-2013 Free Software Foundation, Inc.
55796c8dcSSimon Schubert 
65796c8dcSSimon Schubert    This file is part of GDB.
75796c8dcSSimon Schubert 
85796c8dcSSimon Schubert    This program is free software; you can redistribute it and/or modify
95796c8dcSSimon Schubert    it under the terms of the GNU General Public License as published by
105796c8dcSSimon Schubert    the Free Software Foundation; either version 3 of the License, or
115796c8dcSSimon Schubert    (at your option) any later version.
125796c8dcSSimon Schubert 
135796c8dcSSimon Schubert    This program is distributed in the hope that it will be useful,
145796c8dcSSimon Schubert    but WITHOUT ANY WARRANTY; without even the implied warranty of
155796c8dcSSimon Schubert    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
165796c8dcSSimon Schubert    GNU General Public License for more details.
175796c8dcSSimon Schubert 
185796c8dcSSimon Schubert    You should have received a copy of the GNU General Public License
195796c8dcSSimon Schubert    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
205796c8dcSSimon Schubert 
215796c8dcSSimon Schubert #include "defs.h"
225796c8dcSSimon Schubert #include "symtab.h"
235796c8dcSSimon Schubert #include "bfd.h"
245796c8dcSSimon Schubert #include "objfiles.h"
255796c8dcSSimon Schubert #include "frame.h"
265796c8dcSSimon Schubert #include "gdbcore.h"
275796c8dcSSimon Schubert #include "value.h"
285796c8dcSSimon Schubert #include "target.h"
295796c8dcSSimon Schubert #include "inferior.h"
305796c8dcSSimon Schubert #include "annotate.h"
315796c8dcSSimon Schubert #include "regcache.h"
325796c8dcSSimon Schubert #include "gdb_assert.h"
335796c8dcSSimon Schubert #include "dummy-frame.h"
345796c8dcSSimon Schubert #include "command.h"
355796c8dcSSimon Schubert #include "gdbcmd.h"
365796c8dcSSimon Schubert #include "block.h"
375796c8dcSSimon Schubert #include "inline-frame.h"
38cf7f2e2dSJohn Marino #include "psymtab.h"
395796c8dcSSimon Schubert 
40c50c785cSJohn Marino /* Return the innermost lexical block in execution in a specified
41c50c785cSJohn Marino    stack frame.  The frame address is assumed valid.
425796c8dcSSimon Schubert 
435796c8dcSSimon Schubert    If ADDR_IN_BLOCK is non-zero, set *ADDR_IN_BLOCK to the exact code
445796c8dcSSimon Schubert    address we used to choose the block.  We use this to find a source
455796c8dcSSimon Schubert    line, to decide which macro definitions are in scope.
465796c8dcSSimon Schubert 
475796c8dcSSimon Schubert    The value returned in *ADDR_IN_BLOCK isn't necessarily the frame's
485796c8dcSSimon Schubert    PC, and may not really be a valid PC at all.  For example, in the
495796c8dcSSimon Schubert    caller of a function declared to never return, the code at the
505796c8dcSSimon Schubert    return address will never be reached, so the call instruction may
515796c8dcSSimon Schubert    be the very last instruction in the block.  So the address we use
525796c8dcSSimon Schubert    to choose the block is actually one byte before the return address
535796c8dcSSimon Schubert    --- hopefully pointing us at the call instruction, or its delay
545796c8dcSSimon Schubert    slot instruction.  */
555796c8dcSSimon Schubert 
565796c8dcSSimon Schubert struct block *
get_frame_block(struct frame_info * frame,CORE_ADDR * addr_in_block)575796c8dcSSimon Schubert get_frame_block (struct frame_info *frame, CORE_ADDR *addr_in_block)
585796c8dcSSimon Schubert {
59c50c785cSJohn Marino   CORE_ADDR pc;
605796c8dcSSimon Schubert   struct block *bl;
615796c8dcSSimon Schubert   int inline_count;
625796c8dcSSimon Schubert 
63c50c785cSJohn Marino   if (!get_frame_address_in_block_if_available (frame, &pc))
64c50c785cSJohn Marino     return NULL;
65c50c785cSJohn Marino 
665796c8dcSSimon Schubert   if (addr_in_block)
675796c8dcSSimon Schubert     *addr_in_block = pc;
685796c8dcSSimon Schubert 
695796c8dcSSimon Schubert   bl = block_for_pc (pc);
705796c8dcSSimon Schubert   if (bl == NULL)
715796c8dcSSimon Schubert     return NULL;
725796c8dcSSimon Schubert 
735796c8dcSSimon Schubert   inline_count = frame_inlined_callees (frame);
745796c8dcSSimon Schubert 
755796c8dcSSimon Schubert   while (inline_count > 0)
765796c8dcSSimon Schubert     {
775796c8dcSSimon Schubert       if (block_inlined_p (bl))
785796c8dcSSimon Schubert 	inline_count--;
795796c8dcSSimon Schubert 
805796c8dcSSimon Schubert       bl = BLOCK_SUPERBLOCK (bl);
815796c8dcSSimon Schubert       gdb_assert (bl != NULL);
825796c8dcSSimon Schubert     }
835796c8dcSSimon Schubert 
845796c8dcSSimon Schubert   return bl;
855796c8dcSSimon Schubert }
865796c8dcSSimon Schubert 
875796c8dcSSimon Schubert CORE_ADDR
get_pc_function_start(CORE_ADDR pc)885796c8dcSSimon Schubert get_pc_function_start (CORE_ADDR pc)
895796c8dcSSimon Schubert {
905796c8dcSSimon Schubert   struct block *bl;
915796c8dcSSimon Schubert   struct minimal_symbol *msymbol;
925796c8dcSSimon Schubert 
935796c8dcSSimon Schubert   bl = block_for_pc (pc);
945796c8dcSSimon Schubert   if (bl)
955796c8dcSSimon Schubert     {
965796c8dcSSimon Schubert       struct symbol *symbol = block_linkage_function (bl);
975796c8dcSSimon Schubert 
985796c8dcSSimon Schubert       if (symbol)
995796c8dcSSimon Schubert 	{
1005796c8dcSSimon Schubert 	  bl = SYMBOL_BLOCK_VALUE (symbol);
1015796c8dcSSimon Schubert 	  return BLOCK_START (bl);
1025796c8dcSSimon Schubert 	}
1035796c8dcSSimon Schubert     }
1045796c8dcSSimon Schubert 
1055796c8dcSSimon Schubert   msymbol = lookup_minimal_symbol_by_pc (pc);
1065796c8dcSSimon Schubert   if (msymbol)
1075796c8dcSSimon Schubert     {
1085796c8dcSSimon Schubert       CORE_ADDR fstart = SYMBOL_VALUE_ADDRESS (msymbol);
1095796c8dcSSimon Schubert 
1105796c8dcSSimon Schubert       if (find_pc_section (fstart))
1115796c8dcSSimon Schubert 	return fstart;
1125796c8dcSSimon Schubert     }
1135796c8dcSSimon Schubert 
1145796c8dcSSimon Schubert   return 0;
1155796c8dcSSimon Schubert }
1165796c8dcSSimon Schubert 
1175796c8dcSSimon Schubert /* Return the symbol for the function executing in frame FRAME.  */
1185796c8dcSSimon Schubert 
1195796c8dcSSimon Schubert struct symbol *
get_frame_function(struct frame_info * frame)1205796c8dcSSimon Schubert get_frame_function (struct frame_info *frame)
1215796c8dcSSimon Schubert {
1225796c8dcSSimon Schubert   struct block *bl = get_frame_block (frame, 0);
1235796c8dcSSimon Schubert 
1245796c8dcSSimon Schubert   if (bl == NULL)
1255796c8dcSSimon Schubert     return NULL;
1265796c8dcSSimon Schubert 
1275796c8dcSSimon Schubert   while (BLOCK_FUNCTION (bl) == NULL && BLOCK_SUPERBLOCK (bl) != NULL)
1285796c8dcSSimon Schubert     bl = BLOCK_SUPERBLOCK (bl);
1295796c8dcSSimon Schubert 
1305796c8dcSSimon Schubert   return BLOCK_FUNCTION (bl);
1315796c8dcSSimon Schubert }
1325796c8dcSSimon Schubert 
1335796c8dcSSimon Schubert 
1345796c8dcSSimon Schubert /* Return the function containing pc value PC in section SECTION.
1355796c8dcSSimon Schubert    Returns 0 if function is not known.  */
1365796c8dcSSimon Schubert 
1375796c8dcSSimon Schubert struct symbol *
find_pc_sect_function(CORE_ADDR pc,struct obj_section * section)1385796c8dcSSimon Schubert find_pc_sect_function (CORE_ADDR pc, struct obj_section *section)
1395796c8dcSSimon Schubert {
1405796c8dcSSimon Schubert   struct block *b = block_for_pc_sect (pc, section);
141cf7f2e2dSJohn Marino 
1425796c8dcSSimon Schubert   if (b == 0)
1435796c8dcSSimon Schubert     return 0;
1445796c8dcSSimon Schubert   return block_linkage_function (b);
1455796c8dcSSimon Schubert }
1465796c8dcSSimon Schubert 
1475796c8dcSSimon Schubert /* Return the function containing pc value PC.
148c50c785cSJohn Marino    Returns 0 if function is not known.
149c50c785cSJohn Marino    Backward compatibility, no section */
1505796c8dcSSimon Schubert 
1515796c8dcSSimon Schubert struct symbol *
find_pc_function(CORE_ADDR pc)1525796c8dcSSimon Schubert find_pc_function (CORE_ADDR pc)
1535796c8dcSSimon Schubert {
1545796c8dcSSimon Schubert   return find_pc_sect_function (pc, find_pc_mapped_section (pc));
1555796c8dcSSimon Schubert }
1565796c8dcSSimon Schubert 
1575796c8dcSSimon Schubert /* These variables are used to cache the most recent result
158c50c785cSJohn Marino    of find_pc_partial_function.  */
1595796c8dcSSimon Schubert 
1605796c8dcSSimon Schubert static CORE_ADDR cache_pc_function_low = 0;
1615796c8dcSSimon Schubert static CORE_ADDR cache_pc_function_high = 0;
162*ef5ccd6cSJohn Marino static const char *cache_pc_function_name = 0;
1635796c8dcSSimon Schubert static struct obj_section *cache_pc_function_section = NULL;
164c50c785cSJohn Marino static int cache_pc_function_is_gnu_ifunc = 0;
1655796c8dcSSimon Schubert 
1665796c8dcSSimon Schubert /* Clear cache, e.g. when symbol table is discarded.  */
1675796c8dcSSimon Schubert 
1685796c8dcSSimon Schubert void
clear_pc_function_cache(void)1695796c8dcSSimon Schubert clear_pc_function_cache (void)
1705796c8dcSSimon Schubert {
1715796c8dcSSimon Schubert   cache_pc_function_low = 0;
1725796c8dcSSimon Schubert   cache_pc_function_high = 0;
1735796c8dcSSimon Schubert   cache_pc_function_name = (char *) 0;
1745796c8dcSSimon Schubert   cache_pc_function_section = NULL;
175c50c785cSJohn Marino   cache_pc_function_is_gnu_ifunc = 0;
1765796c8dcSSimon Schubert }
1775796c8dcSSimon Schubert 
1785796c8dcSSimon Schubert /* Finds the "function" (text symbol) that is smaller than PC but
1795796c8dcSSimon Schubert    greatest of all of the potential text symbols in SECTION.  Sets
1805796c8dcSSimon Schubert    *NAME and/or *ADDRESS conditionally if that pointer is non-null.
1815796c8dcSSimon Schubert    If ENDADDR is non-null, then set *ENDADDR to be the end of the
1825796c8dcSSimon Schubert    function (exclusive), but passing ENDADDR as non-null means that
183c50c785cSJohn Marino    the function might cause symbols to be read.  If IS_GNU_IFUNC_P is provided
184c50c785cSJohn Marino    *IS_GNU_IFUNC_P is set to 1 on return if the function is STT_GNU_IFUNC.
185c50c785cSJohn Marino    This function either succeeds or fails (not halfway succeeds).  If it
186c50c785cSJohn Marino    succeeds, it sets *NAME, *ADDRESS, and *ENDADDR to real information and
187c50c785cSJohn Marino    returns 1.  If it fails, it sets *NAME, *ADDRESS, *ENDADDR and
188c50c785cSJohn Marino    *IS_GNU_IFUNC_P to zero and returns 0.  */
1895796c8dcSSimon Schubert 
1905796c8dcSSimon Schubert /* Backward compatibility, no section argument.  */
1915796c8dcSSimon Schubert 
1925796c8dcSSimon Schubert int
find_pc_partial_function_gnu_ifunc(CORE_ADDR pc,const char ** name,CORE_ADDR * address,CORE_ADDR * endaddr,int * is_gnu_ifunc_p)193*ef5ccd6cSJohn Marino find_pc_partial_function_gnu_ifunc (CORE_ADDR pc, const char **name,
194c50c785cSJohn Marino 				    CORE_ADDR *address, CORE_ADDR *endaddr,
195c50c785cSJohn Marino 				    int *is_gnu_ifunc_p)
1965796c8dcSSimon Schubert {
1975796c8dcSSimon Schubert   struct obj_section *section;
1985796c8dcSSimon Schubert   struct symbol *f;
1995796c8dcSSimon Schubert   struct minimal_symbol *msymbol;
200cf7f2e2dSJohn Marino   struct symtab *symtab = NULL;
201cf7f2e2dSJohn Marino   struct objfile *objfile;
2025796c8dcSSimon Schubert   int i;
2035796c8dcSSimon Schubert   CORE_ADDR mapped_pc;
2045796c8dcSSimon Schubert 
2055796c8dcSSimon Schubert   /* To ensure that the symbol returned belongs to the correct setion
2065796c8dcSSimon Schubert      (and that the last [random] symbol from the previous section
2075796c8dcSSimon Schubert      isn't returned) try to find the section containing PC.  First try
2085796c8dcSSimon Schubert      the overlay code (which by default returns NULL); and second try
2095796c8dcSSimon Schubert      the normal section code (which almost always succeeds).  */
2105796c8dcSSimon Schubert   section = find_pc_overlay (pc);
2115796c8dcSSimon Schubert   if (section == NULL)
2125796c8dcSSimon Schubert     section = find_pc_section (pc);
2135796c8dcSSimon Schubert 
2145796c8dcSSimon Schubert   mapped_pc = overlay_mapped_address (pc, section);
2155796c8dcSSimon Schubert 
2165796c8dcSSimon Schubert   if (mapped_pc >= cache_pc_function_low
2175796c8dcSSimon Schubert       && mapped_pc < cache_pc_function_high
2185796c8dcSSimon Schubert       && section == cache_pc_function_section)
2195796c8dcSSimon Schubert     goto return_cached_value;
2205796c8dcSSimon Schubert 
2215796c8dcSSimon Schubert   msymbol = lookup_minimal_symbol_by_pc_section (mapped_pc, section);
222cf7f2e2dSJohn Marino   ALL_OBJFILES (objfile)
2235796c8dcSSimon Schubert   {
224cf7f2e2dSJohn Marino     if (objfile->sf)
225cf7f2e2dSJohn Marino       symtab = objfile->sf->qf->find_pc_sect_symtab (objfile, msymbol,
226cf7f2e2dSJohn Marino 						     mapped_pc, section, 0);
227cf7f2e2dSJohn Marino     if (symtab)
228cf7f2e2dSJohn Marino       break;
2295796c8dcSSimon Schubert   }
2305796c8dcSSimon Schubert 
231cf7f2e2dSJohn Marino   if (symtab)
2325796c8dcSSimon Schubert     {
2335796c8dcSSimon Schubert       /* Checking whether the msymbol has a larger value is for the
2345796c8dcSSimon Schubert 	 "pathological" case mentioned in print_frame_info.  */
2355796c8dcSSimon Schubert       f = find_pc_sect_function (mapped_pc, section);
2365796c8dcSSimon Schubert       if (f != NULL
2375796c8dcSSimon Schubert 	  && (msymbol == NULL
2385796c8dcSSimon Schubert 	      || (BLOCK_START (SYMBOL_BLOCK_VALUE (f))
2395796c8dcSSimon Schubert 		  >= SYMBOL_VALUE_ADDRESS (msymbol))))
2405796c8dcSSimon Schubert 	{
2415796c8dcSSimon Schubert 	  cache_pc_function_low = BLOCK_START (SYMBOL_BLOCK_VALUE (f));
2425796c8dcSSimon Schubert 	  cache_pc_function_high = BLOCK_END (SYMBOL_BLOCK_VALUE (f));
2435796c8dcSSimon Schubert 	  cache_pc_function_name = SYMBOL_LINKAGE_NAME (f);
2445796c8dcSSimon Schubert 	  cache_pc_function_section = section;
245c50c785cSJohn Marino 	  cache_pc_function_is_gnu_ifunc = TYPE_GNU_IFUNC (SYMBOL_TYPE (f));
2465796c8dcSSimon Schubert 	  goto return_cached_value;
2475796c8dcSSimon Schubert 	}
2485796c8dcSSimon Schubert     }
2495796c8dcSSimon Schubert 
250c50c785cSJohn Marino   /* Not in the normal symbol tables, see if the pc is in a known
251c50c785cSJohn Marino      section.  If it's not, then give up.  This ensures that anything
252c50c785cSJohn Marino      beyond the end of the text seg doesn't appear to be part of the
253c50c785cSJohn Marino      last function in the text segment.  */
2545796c8dcSSimon Schubert 
2555796c8dcSSimon Schubert   if (!section)
2565796c8dcSSimon Schubert     msymbol = NULL;
2575796c8dcSSimon Schubert 
2585796c8dcSSimon Schubert   /* Must be in the minimal symbol table.  */
2595796c8dcSSimon Schubert   if (msymbol == NULL)
2605796c8dcSSimon Schubert     {
2615796c8dcSSimon Schubert       /* No available symbol.  */
2625796c8dcSSimon Schubert       if (name != NULL)
2635796c8dcSSimon Schubert 	*name = 0;
2645796c8dcSSimon Schubert       if (address != NULL)
2655796c8dcSSimon Schubert 	*address = 0;
2665796c8dcSSimon Schubert       if (endaddr != NULL)
2675796c8dcSSimon Schubert 	*endaddr = 0;
268c50c785cSJohn Marino       if (is_gnu_ifunc_p != NULL)
269c50c785cSJohn Marino 	*is_gnu_ifunc_p = 0;
2705796c8dcSSimon Schubert       return 0;
2715796c8dcSSimon Schubert     }
2725796c8dcSSimon Schubert 
2735796c8dcSSimon Schubert   cache_pc_function_low = SYMBOL_VALUE_ADDRESS (msymbol);
2745796c8dcSSimon Schubert   cache_pc_function_name = SYMBOL_LINKAGE_NAME (msymbol);
2755796c8dcSSimon Schubert   cache_pc_function_section = section;
276c50c785cSJohn Marino   cache_pc_function_is_gnu_ifunc = MSYMBOL_TYPE (msymbol) == mst_text_gnu_ifunc;
2775796c8dcSSimon Schubert 
2785796c8dcSSimon Schubert   /* If the minimal symbol has a size, use it for the cache.
2795796c8dcSSimon Schubert      Otherwise use the lesser of the next minimal symbol in the same
2805796c8dcSSimon Schubert      section, or the end of the section, as the end of the
2815796c8dcSSimon Schubert      function.  */
2825796c8dcSSimon Schubert 
2835796c8dcSSimon Schubert   if (MSYMBOL_SIZE (msymbol) != 0)
2845796c8dcSSimon Schubert     cache_pc_function_high = cache_pc_function_low + MSYMBOL_SIZE (msymbol);
2855796c8dcSSimon Schubert   else
2865796c8dcSSimon Schubert     {
2875796c8dcSSimon Schubert       /* Step over other symbols at this same address, and symbols in
2885796c8dcSSimon Schubert 	 other sections, to find the next symbol in this section with
2895796c8dcSSimon Schubert 	 a different address.  */
2905796c8dcSSimon Schubert 
2915796c8dcSSimon Schubert       for (i = 1; SYMBOL_LINKAGE_NAME (msymbol + i) != NULL; i++)
2925796c8dcSSimon Schubert 	{
293c50c785cSJohn Marino 	  if (SYMBOL_VALUE_ADDRESS (msymbol + i)
294c50c785cSJohn Marino 	      != SYMBOL_VALUE_ADDRESS (msymbol)
295c50c785cSJohn Marino 	      && SYMBOL_OBJ_SECTION (msymbol + i)
296c50c785cSJohn Marino 	      == SYMBOL_OBJ_SECTION (msymbol))
2975796c8dcSSimon Schubert 	    break;
2985796c8dcSSimon Schubert 	}
2995796c8dcSSimon Schubert 
3005796c8dcSSimon Schubert       if (SYMBOL_LINKAGE_NAME (msymbol + i) != NULL
301c50c785cSJohn Marino 	  && SYMBOL_VALUE_ADDRESS (msymbol + i)
302c50c785cSJohn Marino 	  < obj_section_endaddr (section))
3035796c8dcSSimon Schubert 	cache_pc_function_high = SYMBOL_VALUE_ADDRESS (msymbol + i);
3045796c8dcSSimon Schubert       else
3055796c8dcSSimon Schubert 	/* We got the start address from the last msymbol in the objfile.
3065796c8dcSSimon Schubert 	   So the end address is the end of the section.  */
3075796c8dcSSimon Schubert 	cache_pc_function_high = obj_section_endaddr (section);
3085796c8dcSSimon Schubert     }
3095796c8dcSSimon Schubert 
3105796c8dcSSimon Schubert  return_cached_value:
3115796c8dcSSimon Schubert 
3125796c8dcSSimon Schubert   if (address)
3135796c8dcSSimon Schubert     {
3145796c8dcSSimon Schubert       if (pc_in_unmapped_range (pc, section))
3155796c8dcSSimon Schubert 	*address = overlay_unmapped_address (cache_pc_function_low, section);
3165796c8dcSSimon Schubert       else
3175796c8dcSSimon Schubert 	*address = cache_pc_function_low;
3185796c8dcSSimon Schubert     }
3195796c8dcSSimon Schubert 
3205796c8dcSSimon Schubert   if (name)
3215796c8dcSSimon Schubert     *name = cache_pc_function_name;
3225796c8dcSSimon Schubert 
3235796c8dcSSimon Schubert   if (endaddr)
3245796c8dcSSimon Schubert     {
3255796c8dcSSimon Schubert       if (pc_in_unmapped_range (pc, section))
3265796c8dcSSimon Schubert 	{
3275796c8dcSSimon Schubert 	  /* Because the high address is actually beyond the end of
3285796c8dcSSimon Schubert 	     the function (and therefore possibly beyond the end of
3295796c8dcSSimon Schubert 	     the overlay), we must actually convert (high - 1) and
3305796c8dcSSimon Schubert 	     then add one to that.  */
3315796c8dcSSimon Schubert 
3325796c8dcSSimon Schubert 	  *endaddr = 1 + overlay_unmapped_address (cache_pc_function_high - 1,
3335796c8dcSSimon Schubert 						   section);
3345796c8dcSSimon Schubert 	}
3355796c8dcSSimon Schubert       else
3365796c8dcSSimon Schubert 	*endaddr = cache_pc_function_high;
3375796c8dcSSimon Schubert     }
3385796c8dcSSimon Schubert 
339c50c785cSJohn Marino   if (is_gnu_ifunc_p)
340c50c785cSJohn Marino     *is_gnu_ifunc_p = cache_pc_function_is_gnu_ifunc;
341c50c785cSJohn Marino 
3425796c8dcSSimon Schubert   return 1;
3435796c8dcSSimon Schubert }
3445796c8dcSSimon Schubert 
345c50c785cSJohn Marino /* See find_pc_partial_function_gnu_ifunc, only the IS_GNU_IFUNC_P parameter
346c50c785cSJohn Marino    is omitted here for backward API compatibility.  */
347c50c785cSJohn Marino 
348c50c785cSJohn Marino int
find_pc_partial_function(CORE_ADDR pc,const char ** name,CORE_ADDR * address,CORE_ADDR * endaddr)349*ef5ccd6cSJohn Marino find_pc_partial_function (CORE_ADDR pc, const char **name, CORE_ADDR *address,
350c50c785cSJohn Marino 			  CORE_ADDR *endaddr)
351c50c785cSJohn Marino {
352c50c785cSJohn Marino   return find_pc_partial_function_gnu_ifunc (pc, name, address, endaddr, NULL);
353c50c785cSJohn Marino }
354c50c785cSJohn Marino 
355*ef5ccd6cSJohn Marino /* Return the innermost stack frame that is executing inside of BLOCK and is
356*ef5ccd6cSJohn Marino    at least as old as the selected frame. Return NULL if there is no
357*ef5ccd6cSJohn Marino    such frame.  If BLOCK is NULL, just return NULL.  */
3585796c8dcSSimon Schubert 
3595796c8dcSSimon Schubert struct frame_info *
block_innermost_frame(const struct block * block)360a45ae5f8SJohn Marino block_innermost_frame (const struct block *block)
3615796c8dcSSimon Schubert {
3625796c8dcSSimon Schubert   struct frame_info *frame;
3635796c8dcSSimon Schubert 
3645796c8dcSSimon Schubert   if (block == NULL)
3655796c8dcSSimon Schubert     return NULL;
3665796c8dcSSimon Schubert 
367*ef5ccd6cSJohn Marino   frame = get_selected_frame_if_set ();
368*ef5ccd6cSJohn Marino   if (frame == NULL)
3695796c8dcSSimon Schubert     frame = get_current_frame ();
3705796c8dcSSimon Schubert   while (frame != NULL)
3715796c8dcSSimon Schubert     {
3725796c8dcSSimon Schubert       struct block *frame_block = get_frame_block (frame, NULL);
3735796c8dcSSimon Schubert       if (frame_block != NULL && contained_in (frame_block, block))
3745796c8dcSSimon Schubert 	return frame;
3755796c8dcSSimon Schubert 
3765796c8dcSSimon Schubert       frame = get_prev_frame (frame);
3775796c8dcSSimon Schubert     }
3785796c8dcSSimon Schubert 
3795796c8dcSSimon Schubert   return NULL;
3805796c8dcSSimon Schubert }
381