Example #1
0
/* Return a 1 if any of the address ranges for block BL begins with START
   and any of the address ranges for BL ends with END; return a 0 otherwise.  */
int
block_starts_and_ends (struct block *bl, CORE_ADDR start, CORE_ADDR end)
{
  int retval;
  int start_found = 0;
  int end_found = 0;

  if (!BLOCK_RANGES (bl))
    retval = BLOCK_START (bl) == start && BLOCK_END (bl) == end;
  else
    {
      int i;
      for (i = 0;
           i < BLOCK_RANGES (bl)->nelts && !start_found && !end_found;
           i++)
	{
	  if (BLOCK_RANGE_START (bl, i) == start)
	    start_found = 1;
	  if (BLOCK_RANGE_END (bl, i) == end)
	    end_found = 1;
	}
      retval = start_found && end_found;
    }

  return retval;
}
Example #2
0
CORE_ADDR
block_highest_pc (const struct block *bl)
{
  int i;
  CORE_ADDR highest = 0;
  if (BLOCK_RANGES (bl) == NULL)
    return BLOCK_END (bl);

  for (i = 0; i < BLOCK_RANGES (bl)->nelts; i++)
    {
      if (highest < BLOCK_RANGE_END (bl, i))
        highest = BLOCK_RANGE_END (bl, i);
    }
  return highest;
}
Example #3
0
int
block_contains_pc (const struct block *bl, CORE_ADDR pc)
{
  int i;
  int contains_pc = 0;

  if (! BLOCK_RANGES (bl))
    /* No range list; just a low & high address  */
    contains_pc = BLOCK_START (bl) <= pc && BLOCK_END (bl) > pc;
  else
    for (i = 0; i < BLOCK_RANGES (bl)->nelts && !contains_pc; i++)
      if (BLOCK_RANGE_START (bl, i) <= pc && BLOCK_RANGE_END (bl, i) > pc)
	contains_pc = 1;

  return contains_pc;
}
Example #4
0
struct block *
allocate_block(struct obstack *obstack)
{
  struct block *bl = (struct block *)obstack_alloc(obstack,
                                                   sizeof(struct block));

  BLOCK_START(bl) = 0;
  BLOCK_END(bl) = 0;
  BLOCK_FUNCTION(bl) = NULL;
  BLOCK_SUPERBLOCK(bl) = NULL;
  BLOCK_DICT(bl) = NULL;
  BLOCK_NAMESPACE(bl) = NULL;
  BLOCK_GCC_COMPILED(bl) = 0;
  /* APPLE LOCAL begin address ranges  */
  BLOCK_RANGES(bl) = NULL;
  /* APPLE LOCAL end address ranges  */

  return bl;
}
Example #5
0
int
addr_inside_main_func (CORE_ADDR pc)
{
  struct minimal_symbol *msymbol;

  if (symfile_objfile == 0)
    return 0;

  /* APPLE LOCAL begin don't recompute start/end of main */
  /* If we've already found the start/end addrs of main, don't
     recompute them.  This will probably be fixed in the FSF sources
     soon too, in which case this change can be dropped.
     jmolenda/2004-04-28 */
  if (symfile_objfile->ei.main_func_lowpc != INVALID_ENTRY_LOWPC
      && symfile_objfile->ei.main_func_highpc != INVALID_ENTRY_LOWPC)
    return (symfile_objfile->ei.main_func_lowpc <= pc
            && symfile_objfile->ei.main_func_highpc > pc);
  /* APPLE LOCAL end don't recompute start/end of main */

  /* APPLE LOCAL begin don't restrict lookup_minimal_symbol's object file */
  /* Don't restrict lookup_minimal_symbol's object file to
     symfile_objfile -- this will fail for ZeroLink apps where
     symfile_objfile is just the ZL launcher stub.  */
  msymbol = lookup_minimal_symbol (main_name (), NULL, NULL);
  /* APPLE LOCAL end don't restrict lookup_minimal_symbol's object file */

  /* If the address range hasn't been set up at symbol reading time,
     set it up now.  */

  if (msymbol != NULL
      && symfile_objfile->ei.main_func_lowpc == INVALID_ENTRY_LOWPC
      && symfile_objfile->ei.main_func_highpc == INVALID_ENTRY_HIGHPC)
    {
      /* brobecker/2003-10-10: We used to rely on lookup_symbol() to
	 search the symbol associated to the "main" function.
	 Unfortunately, lookup_symbol() uses the current-language
	 la_lookup_symbol_nonlocal function to do the global symbol
	 search.  Depending on the language, this can introduce
	 certain side-effects, because certain languages, for instance
	 Ada, may find more than one match.  Therefore we prefer to
	 search the "main" function symbol using its address rather
	 than its name.  */
      struct symbol *mainsym =
	find_pc_function (SYMBOL_VALUE_ADDRESS (msymbol));

      if (mainsym && SYMBOL_CLASS (mainsym) == LOC_BLOCK)
	{
	  /* APPLE LOCAL begin address ranges  */
	  struct block *bl = SYMBOL_BLOCK_VALUE (mainsym);

	  if (BLOCK_RANGES (bl))
	    {
	      symfile_objfile->ei.main_func_lowpc = BLOCK_LOWEST_PC (bl);
	      symfile_objfile->ei.main_func_highpc = BLOCK_HIGHEST_PC (bl);
	    }
	  else
	    {
	      symfile_objfile->ei.main_func_lowpc =
		BLOCK_START (SYMBOL_BLOCK_VALUE (mainsym));
	      symfile_objfile->ei.main_func_highpc =
		BLOCK_END (SYMBOL_BLOCK_VALUE (mainsym));
	    }
	  /* APPLE LOCAL end address ranges  */
	}
    }

  /* Not in the normal symbol tables, see if "main" is in the partial
     symbol table.  If it's not, then give up.  */
  if (msymbol != NULL && MSYMBOL_TYPE (msymbol) == mst_text)
    {
      CORE_ADDR maddr = SYMBOL_VALUE_ADDRESS (msymbol);
      asection *msect = SYMBOL_BFD_SECTION (msymbol);
      struct obj_section *osect = find_pc_sect_section (maddr, msect);

      if (osect != NULL)
	{
	  int i;

	  /* Step over other symbols at this same address, and symbols
	     in other sections, to find the next symbol in this
	     section with a different address.  */
	  for (i = 1; SYMBOL_LINKAGE_NAME (msymbol + i) != NULL; i++)
	    {
	      if (SYMBOL_VALUE_ADDRESS (msymbol + i) != maddr
		  && SYMBOL_BFD_SECTION (msymbol + i) == msect)
		break;
	    }

	  symfile_objfile->ei.main_func_lowpc = maddr;

	  /* Use the lesser of the next minimal symbol in the same
	     section, or the end of the section, as the end of the
	     function.  */
	  if (SYMBOL_LINKAGE_NAME (msymbol + i) != NULL
	      && SYMBOL_VALUE_ADDRESS (msymbol + i) < osect->endaddr)
	    symfile_objfile->ei.main_func_highpc =
	      SYMBOL_VALUE_ADDRESS (msymbol + i);
	  else
	    /* We got the start address from the last msymbol in the
	       objfile.  So the end address is the end of the
	       section.  */
	    symfile_objfile->ei.main_func_highpc = osect->endaddr;
	}
    }

  return (symfile_objfile->ei.main_func_lowpc <= pc
	  && symfile_objfile->ei.main_func_highpc > pc);
}
Example #6
0
static int
find_pc_partial_function_impl (CORE_ADDR pc, char **name, CORE_ADDR *address,
			       CORE_ADDR *endaddr, int inlining_flag)
{
  struct bfd_section *section;
  struct partial_symtab *pst;
  struct symbol *f;
  struct minimal_symbol *msymbol;
  struct partial_symbol *psb;
  struct obj_section *osect;
  int i;
  CORE_ADDR mapped_pc;

  /* To ensure that the symbol returned belongs to the correct setion
     (and that the last [random] symbol from the previous section
     isn't returned) try to find the section containing PC.  First try
     the overlay code (which by default returns NULL); and second try
     the normal section code (which almost always succeeds).  */
  section = find_pc_overlay (pc);
  if (section == NULL)
    {
      struct obj_section *obj_section = find_pc_section (pc);
      if (obj_section == NULL)
	section = NULL;
      else
	section = obj_section->the_bfd_section;
    }

  mapped_pc = overlay_mapped_address (pc, section);

  if (mapped_pc >= cache_pc_function_low
      && mapped_pc < cache_pc_function_high
      && section == cache_pc_function_section
      && inlining_flag == cache_pc_function_inlining)
    goto return_cached_value;

  cache_pc_function_inlining = inlining_flag;

  msymbol = lookup_minimal_symbol_by_pc_section (mapped_pc, section);
  pst = find_pc_sect_psymtab (mapped_pc, section);
  if (pst)
    {
      /* Need to read the symbols to get a good value for the end address.  */
      if (endaddr != NULL && !pst->readin)
	{
	  /* Need to get the terminal in case symbol-reading produces
	     output.  */
	  target_terminal_ours_for_output ();
	  PSYMTAB_TO_SYMTAB (pst);
	}

      if (pst->readin)
	{
	  /* Checking whether the msymbol has a larger value is for the
	     "pathological" case mentioned in print_frame_info.  */

	  if (inlining_flag)
	    f = find_pc_sect_function (mapped_pc, section);
	  else
	    f = find_pc_sect_function_no_inlined (mapped_pc, section);

	  /* APPLE LOCAL begin address ranges  */
	  if (f != NULL
	      && (msymbol == NULL
		  || (BLOCK_LOWEST_PC (SYMBOL_BLOCK_VALUE (f))
		      >= SYMBOL_VALUE_ADDRESS (msymbol))))
	    {
	      cache_pc_function_low = BLOCK_LOWEST_PC (SYMBOL_BLOCK_VALUE (f));
	      if (BLOCK_RANGES (SYMBOL_BLOCK_VALUE (f)))
		cache_pc_function_high =
		  BLOCK_HIGHEST_PC (SYMBOL_BLOCK_VALUE (f));
	      else
		cache_pc_function_high = BLOCK_END (SYMBOL_BLOCK_VALUE (f));
	  /* APPLE LOCAL end address ranges  */
	      cache_pc_function_name = DEPRECATED_SYMBOL_NAME (f);
	      cache_pc_function_section = section;
	      goto return_cached_value;
	    }
	}
      else
	{
	  /* Now that static symbols go in the minimal symbol table, perhaps
	     we could just ignore the partial symbols.  But at least for now
	     we use the partial or minimal symbol, whichever is larger.  */
	  psb = find_pc_sect_psymbol (pst, mapped_pc, section);

	  if (psb
	      && (msymbol == NULL ||
		  (SYMBOL_VALUE_ADDRESS (psb)
		   >= SYMBOL_VALUE_ADDRESS (msymbol))))
	    {
	      /* This case isn't being cached currently. */
	      if (address)
		*address = SYMBOL_VALUE_ADDRESS (psb);
	      if (name)
		*name = DEPRECATED_SYMBOL_NAME (psb);
	      /* endaddr non-NULL can't happen here.  */
	      return 1;
	    }
	}
    }

  /* Not in the normal symbol tables, see if the pc is in a known section.
     If it's not, then give up.  This ensures that anything beyond the end
     of the text seg doesn't appear to be part of the last function in the
     text segment.  */

  osect = find_pc_sect_section (mapped_pc, section);

  if (!osect)
    msymbol = NULL;

  /* Must be in the minimal symbol table.  */
  if (msymbol == NULL)
    {
      /* No available symbol.  */
      if (name != NULL)
	*name = 0;
      if (address != NULL)
	*address = 0;
      if (endaddr != NULL)
	*endaddr = 0;
      return 0;
    }

  cache_pc_function_low = SYMBOL_VALUE_ADDRESS (msymbol);
  cache_pc_function_name = DEPRECATED_SYMBOL_NAME (msymbol);
  cache_pc_function_section = section;

  /* Use the lesser of the next minimal symbol in the same section, or
     the end of the section, as the end of the function.  */

  /* Step over other symbols at this same address, and symbols in
     other sections, to find the next symbol in this section with
     a different address.  */

  for (i = 1; DEPRECATED_SYMBOL_NAME (msymbol + i) != NULL; i++)
    {
      if (SYMBOL_VALUE_ADDRESS (msymbol + i) != SYMBOL_VALUE_ADDRESS (msymbol)
	  && SYMBOL_BFD_SECTION (msymbol + i) == SYMBOL_BFD_SECTION (msymbol))
	break;
    }

  if (DEPRECATED_SYMBOL_NAME (msymbol + i) != NULL
      && SYMBOL_VALUE_ADDRESS (msymbol + i) < osect->endaddr)
    cache_pc_function_high = SYMBOL_VALUE_ADDRESS (msymbol + i);
  else
    /* We got the start address from the last msymbol in the objfile.
       So the end address is the end of the section.  */
    cache_pc_function_high = osect->endaddr;

 return_cached_value:

  if (address)
    {
      if (pc_in_unmapped_range (pc, section))
	*address = overlay_unmapped_address (cache_pc_function_low, section);
      else
	*address = cache_pc_function_low;
    }

  if (name)
    *name = cache_pc_function_name;

  if (endaddr)
    {
      if (pc_in_unmapped_range (pc, section))
	{
	  /* Because the high address is actually beyond the end of
	     the function (and therefore possibly beyond the end of
	     the overlay), we must actually convert (high - 1) and
	     then add one to that. */

	  *endaddr = 1 + overlay_unmapped_address (cache_pc_function_high - 1,
						   section);
	}
      else
	*endaddr = cache_pc_function_high;
    }

  return 1;
}
Example #7
0
int
contained_in (const struct block *a, const struct block *b)
{
  int i, j;
  if (!a || !b)
    return 0;

  /* APPLE LOCAL begin address ranges  */
  if (BLOCK_RANGES (a) == NULL
      && BLOCK_RANGES (b) == NULL)
    {
 /* APPLE LOCAL end address ranges  */

      return BLOCK_START (a) >= BLOCK_START (b)
	&& BLOCK_END (a) <= BLOCK_END (b);

 /* APPLE LOCAL begin address ranges  */
    }
  else if (!BLOCK_RANGES (a))
    {
      /* Block A has a single contiguous address range, but block B
	 has multiple non-contiguous ranges.  A is contained in B
         if A's address range fits within ANY of B's address ranges. */

      for (i = 0; i < BLOCK_RANGES (b)->nelts; i++)
	if (BLOCK_START (a) >= BLOCK_RANGE_START (b, i)
	    && BLOCK_END (a) <= BLOCK_RANGE_END (b, i))
	  {
	    return 1;  /* A's scope fits within one of B's ranges */
	  }
      return 0; /* A's scope did not fit within any of B's ranges */
    }
  else if (!BLOCK_RANGES (b))
    {
      /* Block B has a single contiguous address range, but block A
	 has multiple non-contiguous ranges.  A is contained in B if
         ALL of A's address ranges fit within B's address range.  */

      for (i = 0; i < BLOCK_RANGES (a)->nelts; i++)
	if (BLOCK_RANGE_START (a, i) < BLOCK_START (b)
	    || BLOCK_RANGE_END (a, i) > BLOCK_END (b))
          {
	    return 0;  /* One of A's ranges is outside B's scope */
          }
      return 1; /* All of A's ranges are within B's scope */
    }
  else
    {
      /* Both block A and block B have non-contiguous address ranges.
         A is contained in B if all of A's address ranges fit within at
         least one of B's address ranges.  */

      int fits;
      for (i = 0; i < BLOCK_RANGES (a)->nelts; i++)
	{
	  fits = 0;
	  for (j = 0; j < BLOCK_RANGES (b)->nelts && !fits; j++)
	    if (BLOCK_RANGE_START (a, i) >= BLOCK_RANGE_START (b, j)
		&& BLOCK_RANGE_END (a, i) <= BLOCK_RANGE_END (b, j))
              {
	        fits = 1;
              }
          if (fits == 0)
            {
              /* One of A's ranges is is not contained within any B range */
              return 0;
            }
	}
      return 1;  /* All of A's ranges are contained within B's ranges */
    }
  /* APPLE LOCAL end address ranges  */
  return 0; /* notreached */
}