Ejemplo n.º 1
0
void
cp_set_block_scope (const struct symbol *symbol,
		    struct block *block,
		    struct obstack *obstack)
{
  /* Make sure that the name was originally mangled: if not, there
     certainly isn't any namespace information to worry about!  */

  if (SYMBOL_CPLUS_DEMANGLED_NAME (symbol) != NULL)
    {
      if (processing_has_namespace_info)
	{
	  block_set_scope
	    (block, obsavestring (processing_current_prefix,
				  strlen (processing_current_prefix),
				  obstack),
	     obstack);
	}
      else
	{
	  /* Try to figure out the appropriate namespace from the
	     demangled name.  */

	  /* FIXME: carlton/2003-04-15: If the function in question is
	     a method of a class, the name will actually include the
	     name of the class as well.  This should be harmless, but
	     is a little unfortunate.  */

	  const char *name = SYMBOL_CPLUS_DEMANGLED_NAME (symbol);
	  unsigned int prefix_len = cp_entire_prefix_len (name);

	  block_set_scope (block,
			   obsavestring (name, prefix_len, obstack),
			   obstack);
	}
    }
}
Ejemplo n.º 2
0
static void
elf_symtab_read (struct objfile *objfile, int dynamic)
{
  long storage_needed;
  asymbol *sym;
  asymbol **symbol_table;
  long number_of_symbols;
  long i;
  int index;
  struct cleanup *back_to;
  CORE_ADDR symaddr;
  CORE_ADDR offset;
  enum minimal_symbol_type ms_type;
  /* If sectinfo is nonNULL, it contains section info that should end up
     filed in the objfile.  */
  struct stab_section_info *sectinfo = NULL;
  /* If filesym is nonzero, it points to a file symbol, but we haven't
     seen any section info for it yet.  */
  asymbol *filesym = 0;
#ifdef SOFUN_ADDRESS_MAYBE_MISSING
  /* Name of filesym, as saved on the symbol_obstack.  */
  char *filesymname = obsavestring ("", 0, &objfile->symbol_obstack);
#endif
  struct dbx_symfile_info *dbx = objfile->sym_stab_info;
  unsigned long size;
  int stripped = (bfd_get_symcount (objfile->obfd) == 0);

  if (dynamic)
    {
      storage_needed = bfd_get_dynamic_symtab_upper_bound (objfile->obfd);

      /* Nothing to be done if there is no dynamic symtab.  */
      if (storage_needed < 0)
	return;
    }
  else
    {
      storage_needed = bfd_get_symtab_upper_bound (objfile->obfd);
      if (storage_needed < 0)
	error ("Can't read symbols from %s: %s", bfd_get_filename (objfile->obfd),
	       bfd_errmsg (bfd_get_error ()));
    }
  if (storage_needed > 0)
    {
      symbol_table = (asymbol **) xmalloc (storage_needed);
      back_to = make_cleanup (xfree, symbol_table);
      if (dynamic)
	number_of_symbols = bfd_canonicalize_dynamic_symtab (objfile->obfd,
							     symbol_table);
      else
	number_of_symbols = bfd_canonicalize_symtab (objfile->obfd, symbol_table);
      if (number_of_symbols < 0)
	error ("Can't read symbols from %s: %s", bfd_get_filename (objfile->obfd),
	       bfd_errmsg (bfd_get_error ()));

      for (i = 0; i < number_of_symbols; i++)
	{
	  sym = symbol_table[i];
	  if (sym->name == NULL || *sym->name == '\0')
	    {
	      /* Skip names that don't exist (shouldn't happen), or names
	         that are null strings (may happen). */
	      continue;
	    }

          offset = ANOFFSET (objfile->section_offsets, sym->section->index);
	  if (dynamic
	      && sym->section == &bfd_und_section
	      && (sym->flags & BSF_FUNCTION))
	    {
	      struct minimal_symbol *msym;

	      /* Symbol is a reference to a function defined in
	         a shared library.
	         If its value is non zero then it is usually the address
	         of the corresponding entry in the procedure linkage table,
	         plus the desired section offset.
	         If its value is zero then the dynamic linker has to resolve
	         the symbol. We are unable to find any meaningful address
	         for this symbol in the executable file, so we skip it.  */
	      symaddr = sym->value;
	      if (symaddr == 0)
		continue;
	      symaddr += offset;
	      msym = record_minimal_symbol_and_info
		((char *) sym->name, symaddr,
		 mst_solib_trampoline, NULL, sym->section, objfile);
#ifdef SOFUN_ADDRESS_MAYBE_MISSING
	      if (msym != NULL)
		msym->filename = filesymname;
#endif
	      continue;
	    }

	  /* If it is a nonstripped executable, do not enter dynamic
	     symbols, as the dynamic symbol table is usually a subset
	     of the main symbol table.  */
	  if (dynamic && !stripped)
	    continue;
	  if (sym->flags & BSF_FILE)
	    {
	      /* STT_FILE debugging symbol that helps stabs-in-elf debugging.
	         Chain any old one onto the objfile; remember new sym.  */
	      if (sectinfo != NULL)
		{
		  sectinfo->next = dbx->stab_section_info;
		  dbx->stab_section_info = sectinfo;
		  sectinfo = NULL;
		}
	      filesym = sym;
#ifdef SOFUN_ADDRESS_MAYBE_MISSING
	      filesymname =
		obsavestring ((char *) filesym->name, strlen (filesym->name),
			      &objfile->symbol_obstack);
#endif
	    }
	  else if (sym->flags & (BSF_GLOBAL | BSF_LOCAL | BSF_WEAK))
	    {
	      struct minimal_symbol *msym;

	      /* Select global/local/weak symbols.  Note that bfd puts abs
	         symbols in their own section, so all symbols we are
	         interested in will have a section. */
	      /* Bfd symbols are section relative. */
	      symaddr = sym->value + sym->section->vma;
	      /* Relocate all non-absolute symbols by the section offset.  */
	      if (sym->section != &bfd_abs_section)
		{
		  symaddr += offset;
		}
	      /* For non-absolute symbols, use the type of the section
	         they are relative to, to intuit text/data.  Bfd provides
	         no way of figuring this out for absolute symbols. */
	      if (sym->section == &bfd_abs_section)
		{
		  /* This is a hack to get the minimal symbol type
		     right for Irix 5, which has absolute addresses
		     with special section indices for dynamic symbols. */
		  unsigned short shndx =
		  ((elf_symbol_type *) sym)->internal_elf_sym.st_shndx;

		  switch (shndx)
		    {
		    case SHN_MIPS_TEXT:
		      ms_type = mst_text;
		      break;
		    case SHN_MIPS_DATA:
		      ms_type = mst_data;
		      break;
		    case SHN_MIPS_ACOMMON:
		      ms_type = mst_bss;
		      break;
		    default:
		      ms_type = mst_abs;
		    }

		  /* If it is an Irix dynamic symbol, skip section name
		     symbols, relocate all others by section offset. */
		  if (ms_type != mst_abs)
		    {
		      if (sym->name[0] == '.')
			continue;
		      symaddr += offset;
		    }
		}
	      else if (sym->section->flags & SEC_CODE)
		{
		  if (sym->flags & BSF_GLOBAL)
		    {
		      ms_type = mst_text;
		    }
		  else if ((sym->name[0] == '.' && sym->name[1] == 'L')
			   || ((sym->flags & BSF_LOCAL)
			       && sym->name[0] == '$'
			       && sym->name[1] == 'L'))
		    /* Looks like a compiler-generated label.  Skip
		       it.  The assembler should be skipping these (to
		       keep executables small), but apparently with
		       gcc on the (OBSOLETE) delta m88k SVR4, it
		       loses.  So to have us check too should be
		       harmless (but I encourage people to fix this in
		       the assembler instead of adding checks here).  */
		    continue;
		  else
		    {
		      ms_type = mst_file_text;
		    }
		}
	      else if (sym->section->flags & SEC_ALLOC)
		{
		  if (sym->flags & (BSF_GLOBAL | BSF_WEAK))
		    {
		      if (sym->section->flags & SEC_LOAD)
			{
			  ms_type = mst_data;
			}
		      else
			{
			  ms_type = mst_bss;
			}
		    }
		  else if (sym->flags & BSF_LOCAL)
		    {
		      /* Named Local variable in a Data section.  Check its
		         name for stabs-in-elf.  The STREQ macro checks the
		         first character inline, so we only actually do a
		         strcmp function call on names that start with 'B'
		         or 'D' */
		      index = SECT_OFF_MAX;
		      if (STREQ ("Bbss.bss", sym->name))
			{
			  index = SECT_OFF_BSS (objfile);
			}
		      else if (STREQ ("Ddata.data", sym->name))
			{
			  index = SECT_OFF_DATA (objfile);
			}
		      else if (STREQ ("Drodata.rodata", sym->name))
			{
			  index = SECT_OFF_RODATA (objfile);
			}
		      if (index != SECT_OFF_MAX)
			{
			  /* Found a special local symbol.  Allocate a
			     sectinfo, if needed, and fill it in.  */
			  if (sectinfo == NULL)
			    {
			      sectinfo = (struct stab_section_info *)
				xmmalloc (objfile->md, sizeof (*sectinfo));
			      memset (sectinfo, 0,
				      sizeof (*sectinfo));
			      if (filesym == NULL)
				{
				  complain (&section_info_complaint,
					    sym->name);
				}
			      else
				{
				  sectinfo->filename =
				    (char *) filesym->name;
				}
			    }
			  if (index != -1)
			    { 
			      if (sectinfo->sections[index] != 0)
				{
				  complain (&section_info_dup_complaint,
					    sectinfo->filename);
				}
			    }
			  else
			    internal_error (__FILE__, __LINE__,
					    "Section index uninitialized.");
			  /* Bfd symbols are section relative. */
			  symaddr = sym->value + sym->section->vma;
			  /* Relocate non-absolute symbols by the section offset. */
			  if (sym->section != &bfd_abs_section)
			    {
			      symaddr += offset;
			    }
			  if (index != -1)
			    sectinfo->sections[index] = symaddr;
			  else
			    internal_error (__FILE__, __LINE__,
					    "Section index uninitialized.");
			  /* The special local symbols don't go in the
			     minimal symbol table, so ignore this one. */
			  continue;
			}
		      /* Not a special stabs-in-elf symbol, do regular
		         symbol processing. */
		      if (sym->section->flags & SEC_LOAD)
			{
			  ms_type = mst_file_data;
			}
		      else
			{
			  ms_type = mst_file_bss;
			}
		    }
		  else
		    {
		      ms_type = mst_unknown;
		    }
		}
	      else
		{
		  /* FIXME:  Solaris2 shared libraries include lots of
		     odd "absolute" and "undefined" symbols, that play 
		     hob with actions like finding what function the PC
		     is in.  Ignore them if they aren't text, data, or bss.  */
		  /* ms_type = mst_unknown; */
		  continue;	/* Skip this symbol. */
		}
	      /* Pass symbol size field in via BFD.  FIXME!!!  */
	      size = ((elf_symbol_type *) sym)->internal_elf_sym.st_size;
	      msym = record_minimal_symbol_and_info
		((char *) sym->name, symaddr,
		 ms_type, (void *) size, sym->section, objfile);
#ifdef SOFUN_ADDRESS_MAYBE_MISSING
	      if (msym != NULL)
		msym->filename = filesymname;
#endif
	      ELF_MAKE_MSYMBOL_SPECIAL (sym, msym);
	    }
	}
      do_cleanups (back_to);
    }
}