make_cleanup (free, name);
make_cleanup (xfree, name);
static bfd *symfile_bfd_open PARAMS ((char *));static void find_sym_fns PARAMS ((struct objfile *));static void decrement_reading_symtab PARAMS ((void *));/* List of all available sym_fns.  On gdb startup, each object file reader   calls add_symtab_fns() to register information on each format it is   prepared to read. */static struct sym_fns *symtab_fns = NULL;/* Flag for whether user will be reloading symbols multiple times.   Defaults to ON for VxWorks, otherwise OFF.  */#ifdef SYMBOL_RELOADING_DEFAULTint symbol_reloading = SYMBOL_RELOADING_DEFAULT;#elseint symbol_reloading = 0;#endif/* If true, then shared library symbols will be added automatically   when the inferior is created, new libraries are loaded, or when   attaching to the inferior.  This is almost always what users   will want to have happen; but for very large programs, the startup   time will be excessive, and so if this is a problem, the user can   clear this flag and then add the shared library symbols as needed.   Note that there is a potential for confusion, since if the shared   library symbols are not loaded, commands like "info fun" will *not*   report all the functions that are actually present.  */int auto_solib_add = 1;/* Since this function is called from within qsort, in an ANSI environment   it must conform to the prototype for qsort, which specifies that the   comparison function takes two "void *" pointers. */static intcompare_symbols (s1p, s2p)     const PTR s1p;     const PTR s2p;{  register struct symbol **s1, **s2;  s1 = (struct symbol **) s1p;  s2 = (struct symbol **) s2p;  return (STRCMP (SYMBOL_NAME (*s1), SYMBOL_NAME (*s2)));}/*LOCAL FUNCTION	compare_psymbols -- compare two partial symbols by nameDESCRIPTION	Given pointers to pointers to two partial symbol table entries,	compare them by name and return -N, 0, or +N (ala strcmp).	Typically used by sorting routines like qsort().NOTES	Does direct compare of first two characters before punting	and passing to strcmp for longer compares.  Note that the	original version had a bug whereby two null strings or two	identically named one character strings would return the	comparison of memory following the null byte. */static intcompare_psymbols (s1p, s2p)     const PTR s1p;     const PTR s2p;{  register char *st1 = SYMBOL_NAME (*(struct partial_symbol **) s1p);  register char *st2 = SYMBOL_NAME (*(struct partial_symbol **) s2p);  if ((st1[0] - st2[0]) || !st1[0])    {      return (st1[0] - st2[0]);    }  else if ((st1[1] - st2[1]) || !st1[1])    {      return (st1[1] - st2[1]);    }  else    {      return (STRCMP (st1 + 2, st2 + 2));    }}voidsort_pst_symbols (pst)     struct partial_symtab *pst;{  /* Sort the global list; don't sort the static list */  qsort (pst -> objfile -> global_psymbols.list + pst -> globals_offset,	 pst -> n_global_syms, sizeof (struct partial_symbol *),	 compare_psymbols);}/* Call sort_block_syms to sort alphabetically the symbols of one block.  */voidsort_block_syms (b)     register struct block *b;{  qsort (&BLOCK_SYM (b, 0), BLOCK_NSYMS (b),	 sizeof (struct symbol *), compare_symbols);}/* Call sort_symtab_syms to sort alphabetically   the symbols of each block of one symtab.  */voidsort_symtab_syms (s)     register struct symtab *s;{  register struct blockvector *bv;  int nbl;  int i;  register struct block *b;  if (s == 0)    return;  bv = BLOCKVECTOR (s);  nbl = BLOCKVECTOR_NBLOCKS (bv);  for (i = 0; i < nbl; i++)    {      b = BLOCKVECTOR_BLOCK (bv, i);      if (BLOCK_SHOULD_SORT (b))	sort_block_syms (b);    }}/* Make a null terminated copy of the string at PTR with SIZE characters in   the obstack pointed to by OBSTACKP .  Returns the address of the copy.   Note that the string at PTR does not have to be null terminated, I.E. it   may be part of a larger string and we are only saving a substring. */char *obsavestring (ptr, size, obstackp)     char *ptr;     int size;     struct obstack *obstackp;{  register char *p = (char *) obstack_alloc (obstackp, size + 1);  /* Open-coded memcpy--saves function call time.  These strings are usually     short.  FIXME: Is this really still true with a compiler that can     inline memcpy? */  {    register char *p1 = ptr;    register char *p2 = p;    char *end = ptr + size;    while (p1 != end)      *p2++ = *p1++;  }  p[size] = 0;  return p;}/* Concatenate strings S1, S2 and S3; return the new string.  Space is found   in the obstack pointed to by OBSTACKP.  */char *obconcat (obstackp, s1, s2, s3)     struct obstack *obstackp;     const char *s1, *s2, *s3;{  register int len = strlen (s1) + strlen (s2) + strlen (s3) + 1;  register char *val = (char *) obstack_alloc (obstackp, len);  strcpy (val, s1);  strcat (val, s2);  strcat (val, s3);  return val;}/* True if we are nested inside psymtab_to_symtab. */int currently_reading_symtab = 0;static voiddecrement_reading_symtab (dummy)     void *dummy;{  currently_reading_symtab--;}/* Get the symbol table that corresponds to a partial_symtab.   This is fast after the first time you do it.  In fact, there   is an even faster macro PSYMTAB_TO_SYMTAB that does the fast   case inline.  */struct symtab *psymtab_to_symtab (pst)     register struct partial_symtab *pst;{  /* If it's been looked up before, return it. */  if (pst->symtab)    return pst->symtab;  /* If it has not yet been read in, read it.  */  if (!pst->readin)    {       struct cleanup *back_to = make_cleanup (decrement_reading_symtab, NULL);      currently_reading_symtab++;      (*pst->read_symtab) (pst);      do_cleanups (back_to);    }  return pst->symtab;}/* Initialize entry point information for this objfile. */voidinit_entry_point_info (objfile)     struct objfile *objfile;{  /* Save startup file's range of PC addresses to help blockframe.c     decide where the bottom of the stack is.  */  if (bfd_get_file_flags (objfile -> obfd) & EXEC_P)    {      /* Executable file -- record its entry point so we'll recognize	 the startup file because it contains the entry point.  */      objfile -> ei.entry_point = bfd_get_start_address (objfile -> obfd);    }  else    {      /* Examination of non-executable.o files.  Short-circuit this stuff.  */      objfile -> ei.entry_point = INVALID_ENTRY_POINT;    }  objfile -> ei.entry_file_lowpc = INVALID_ENTRY_LOWPC;  objfile -> ei.entry_file_highpc = INVALID_ENTRY_HIGHPC;  objfile -> ei.entry_func_lowpc = INVALID_ENTRY_LOWPC;  objfile -> ei.entry_func_highpc = INVALID_ENTRY_HIGHPC;  objfile -> ei.main_func_lowpc = INVALID_ENTRY_LOWPC;  objfile -> ei.main_func_highpc = INVALID_ENTRY_HIGHPC;}/* Get current entry point address.  */CORE_ADDRentry_point_address(){  return symfile_objfile ? symfile_objfile->ei.entry_point : 0;}/* Remember the lowest-addressed loadable section we've seen.     This function is called via bfd_map_over_sections.    In case of equal vmas, the section with the largest size becomes the   lowest-addressed loadable section.   If the vmas and sizes are equal, the last section is considered the   lowest-addressed loadable section.  */voidfind_lowest_section (abfd, sect, obj)     bfd *abfd;     asection *sect;     PTR obj;{  asection **lowest = (asection **)obj;  if (0 == (bfd_get_section_flags (abfd, sect) & SEC_LOAD))    return;  if (!*lowest)    *lowest = sect;		/* First loadable section */  else if (bfd_section_vma (abfd, *lowest) > bfd_section_vma (abfd, sect))    *lowest = sect;		/* A lower loadable section */  else if (bfd_section_vma (abfd, *lowest) == bfd_section_vma (abfd, sect)	   && (bfd_section_size (abfd, (*lowest))	       <= bfd_section_size (abfd, sect)))    *lowest = sect;}/* Parse the user's idea of an offset for dynamic linking, into our idea   of how to represent it for fast symbol reading.  This is the default    version of the sym_fns.sym_offsets function for symbol readers that   don't need to do anything special.  It allocates a section_offsets table   for the objectfile OBJFILE and stuffs ADDR into all of the offsets.  */struct section_offsets *default_symfile_offsets (objfile, addr)     struct objfile *objfile;     CORE_ADDR addr;{  struct section_offsets *section_offsets;  int i;  objfile->num_sections = SECT_OFF_MAX;  section_offsets = (struct section_offsets *)    obstack_alloc (&objfile -> psymbol_obstack, SIZEOF_SECTION_OFFSETS);  for (i = 0; i < SECT_OFF_MAX; i++)    ANOFFSET (section_offsets, i) = addr;    return section_offsets;}/* Process a symbol file, as either the main file or as a dynamically   loaded file.   NAME is the file name (which will be tilde-expanded and made   absolute herein) (but we don't free or modify NAME itself).   FROM_TTY says how verbose to be.  MAINLINE specifies whether this   is the main symbol file, or whether it's an extra symbol file such   as dynamically loaded code.  If !mainline, ADDR is the address   where the text segment was loaded.  If VERBO, the caller has printed   a verbose message about the symbol reading (and complaints can be   more terse about it).  */voidsyms_from_objfile (objfile, addr, mainline, verbo)     struct objfile *objfile;     CORE_ADDR addr;     int mainline;     int verbo;{  struct section_offsets *section_offsets;  asection *lowest_sect;  struct cleanup *old_chain;  init_entry_point_info (objfile);  find_sym_fns (objfile);  /* Make sure that partially constructed symbol tables will be cleaned up     if an error occurs during symbol reading.  */  old_chain = make_cleanup (free_objfile, objfile);  if (mainline)     {      /* We will modify the main symbol table, make sure that all its users	 will be cleaned up if an error occurs during symbol reading.  */      make_cleanup (clear_symtab_users, 0);      /* Since no error yet, throw away the old symbol table.  */      if (symfile_objfile != NULL)	{	  free_objfile (symfile_objfile);	  symfile_objfile = NULL;	}      /* Currently we keep symbols from the add-symbol-file command.	 If the user wants to get rid of them, they should do "symbol-file"	 without arguments first.  Not sure this is the best behavior	 (PR 2207).  */      (*objfile -> sf -> sym_new_init) (objfile);    }  /* Convert addr into an offset rather than an absolute address.     We find the lowest address of a loaded segment in the objfile,     and assume that <addr> is where that got loaded.  Due to historical     precedent, we warn if that doesn't happen to be a text segment.  */  if (mainline)    {      addr = 0;		/* No offset from objfile addresses.  */    }  else    {      lowest_sect = bfd_get_section_by_name (objfile->obfd, ".text");      if (lowest_sect == NULL)	bfd_map_over_sections (objfile->obfd, find_lowest_section,			       (PTR) &lowest_sect);      if (lowest_sect == NULL)	warning ("no loadable sections found in added symbol-file %s",		 objfile->name);      else if ((bfd_get_section_flags (objfile->obfd, lowest_sect) & SEC_CODE)	       == 0)	/* FIXME-32x64--assumes bfd_vma fits in long.  */	warning ("Lowest section in %s is %s at 0x%lx",		 objfile->name,		 bfd_section_name (objfile->obfd, lowest_sect),		 (unsigned long) bfd_section_vma (objfile->obfd, lowest_sect));      if (lowest_sect)	addr -= bfd_section_vma (objfile->obfd, lowest_sect);    }  /* Initialize symbol reading routines for this objfile, allow complaints to     appear for this new file, and record how verbose to be, then do the     initial symbol reading for this file. */  (*objfile -> sf -> sym_init) (objfile);  clear_complaints (1, verbo);  section_offsets = (*objfile -> sf -> sym_offsets) (objfile, addr);  objfile->section_offsets = section_offsets;#ifndef IBM6000_TARGET  /* This is a SVR4/SunOS specific hack, I think.  In any event, it     screws RS/6000.  sym_offsets should be doing this sort of thing,     because it knows the mapping between bfd sections and     section_offsets.  */  /* This is a hack.  As far as I can tell, section offsets are not     target dependent.  They are all set to addr with a couple of     exceptions.  The exceptions are sysvr4 shared libraries, whose     offsets are kept in solib structures anyway and rs6000 xcoff     which handles shared libraries in a completely unique way.     Section offsets are built similarly, except that they are built     by adding addr in all cases because there is no clear mapping     from section_offsets into actual sections.  Note that solib.c     has a different algorythm for finding section offsets.     These should probably all be collapsed into some target     independent form of shared library support.  FIXME.  */  if (addr)    {      struct obj_section *s;      for (s = objfile->sections; s < objfile->sections_end; ++s)	{	  s->addr -= s->offset;	  s->addr += addr;	  s->endaddr -= s->offset;	  s->endaddr += addr;	  s->offset += addr;	}    }#endif /* not IBM6000_TARGET */  (*objfile -> sf -> sym_read) (objfile, section_offsets, mainline);  if (!have_partial_symbols () && !have_full_symbols ())    {      wrap_here ("");      printf_filtered ("(no debugging symbols found)...");      wrap_here ("");    }  /* Don't allow char * to have a typename (else would get caddr_t).     Ditto void *.  FIXME: Check whether this is now done by all the     symbol readers themselves (many of them now do), and if so remove     it from here.  */  TYPE_NAME (lookup_pointer_type (builtin_type_char)) = 0;  TYPE_NAME (lookup_pointer_type (builtin_type_void)) = 0;  /* Mark the objfile has having had initial symbol read attempted.  Note     that this does not mean we found any symbols... */  objfile -> flags |= OBJF_SYMS;  /* Discard cleanups as symbol reading was successful.  */  discard_cleanups (old_chain);/* Call this after reading in a new symbol table to give target dependant code   a crack at the new symbols.  For instance, this could be used to update the   values of target-specific symbols GDB needs to keep track of (such as   _sigtramp, or whatever).  */  TARGET_SYMFILE_POSTREAD (objfile);}/* Perform required actions after either reading in the initial   symbols for a new objfile, or mapping in the symbols from a reusable   objfile. */   voidnew_symfile_objfile (objfile, mainline, verbo)     struct objfile *objfile;     int mainline;     int verbo;{  /* If this is the main symbol file we have to clean up all users of the     old main symbol file. Otherwise it is sufficient to fixup all the     breakpoints that may have been redefined by this symbol file.  */  if (mainline)    {      /* OK, make it the "real" symbol file.  */      symfile_objfile = objfile;      clear_symtab_users ();    }  else    {      breakpoint_re_set ();    }  /* We're done reading the symbol file; finish off complaints.  */  clear_complaints (0, verbo);}/* Process a symbol file, as either the main file or as a dynamically   loaded file.   NAME is the file name (which will be tilde-expanded and made   absolute herein) (but we don't free or modify NAME itself).   FROM_TTY says how verbose to be.  MAINLINE specifies whether this   is the main symbol file, or whether it's an extra symbol file such   as dynamically loaded code.  If !mainline, ADDR is the address   where the text segment was loaded.   Upon success, returns a pointer to the objfile that was added.   Upon failure, jumps back to command level (never returns). */struct objfile *symbol_file_add (name, from_tty, addr, mainline, mapped, readnow)     char *name;     int from_tty;     CORE_ADDR addr;     int mainline;     int mapped;     int readnow;{  struct objfile *objfile;  struct partial_symtab *psymtab;  bfd *abfd;  /* Open a bfd for the file, and give user a chance to burp if we'd be     interactively wiping out any existing symbols.  */  abfd = symfile_bfd_open (name);  if ((have_full_symbols () || have_partial_symbols ())      && mainline      && from_tty      && !query ("Load new symbol table from \"%s\"? ", name))      error ("Not confirmed.");  objfile = allocate_objfile (abfd, mapped);  /* If the objfile uses a mapped symbol file, and we have a psymtab for     it, then skip reading any symbols at this time. */  if ((objfile -> flags & OBJF_MAPPED) && (objfile -> flags & OBJF_SYMS))    {      /* We mapped in an existing symbol table file that already has had	 initial symbol reading performed, so we can skip that part.  Notify	 the user that instead of reading the symbols, they have been mapped.	 */      if (from_tty || info_verbose)	{	  printf_filtered ("Mapped symbols for %s...", name);	  wrap_here ("");	  gdb_flush (gdb_stdout);	}      init_entry_point_info (objfile);      find_sym_fns (objfile);    }  else    {      /* We either created a new mapped symbol table, mapped an existing	 symbol table file which has not had initial symbol reading	 performed, or need to read an unmapped symbol table. */      if (from_tty || info_verbose)	{	  printf_filtered ("Reading symbols from %s...", name);	  wrap_here ("");	  gdb_flush (gdb_stdout);	}      syms_from_objfile (objfile, addr, mainline, from_tty);    }        /* We now have at least a partial symbol table.  Check to see if the     user requested that all symbols be read on initial access via either     the gdb startup command line or on a per symbol file basis.  Expand     all partial symbol tables for this objfile if so. */  if (readnow || readnow_symbol_files)    {      if (from_tty || info_verbose)	{	  printf_filtered ("expanding to full symbols...");	  wrap_here ("");	  gdb_flush (gdb_stdout);	}      for (psymtab = objfile -> psymtabs;	   psymtab != NULL;	   psymtab = psymtab -> next)	{	  psymtab_to_symtab (psymtab);	}    }  if (from_tty || info_verbose)    {      printf_filtered ("done.\n");      gdb_flush (gdb_stdout);    }  new_symfile_objfile (objfile, mainline, from_tty);  target_new_objfile (objfile);  return (objfile);}/* This is the symbol-file command.  Read the file, analyze its   symbols, and add a struct symtab to a symtab list.  The syntax of   the command is rather bizarre--(1) buildargv implements various   quoting conventions which are undocumented and have little or   nothing in common with the way things are quoted (or not quoted)   elsewhere in GDB, (2) options are used, which are not generally   used in GDB (perhaps "set mapped on", "set readnow on" would be   better), (3) the order of options matters, which is contrary to GNU   conventions (because it is confusing and inconvenient).  */voidsymbol_file_command (args, from_tty)     char *args;     int from_tty;{  char **argv;  char *name = NULL;  CORE_ADDR text_relocation = 0;		/* text_relocation */  struct cleanup *cleanups;  int mapped = 0;  int readnow = 0;  dont_repeat ();  if (args == NULL)    {      if ((have_full_symbols () || have_partial_symbols ())	  && from_tty	  && !query ("Discard symbol table from `%s'? ",		     symfile_objfile -> name))	error ("Not confirmed.");      free_all_objfiles ();      symfile_objfile = NULL;      if (from_tty)	{	  printf_unfiltered ("No symbol file now.\n");	}    }  else    {      if ((argv = buildargv (args)) == NULL)	{	  nomem (0);	}      cleanups = make_cleanup (freeargv, (char *) argv);      while (*argv != NULL)	{	  if (STREQ (*argv, "-mapped"))	    {	      mapped = 1;	    }	  else if (STREQ (*argv, "-readnow"))	    {	      readnow = 1;	    }	  else if (**argv == '-')	    {	      error ("unknown option `%s'", *argv);	    }	  else	    {            char *p;              name = *argv;              /* this is for rombug remote only, to get the text relocation by              using link command */              p = strrchr(name, '/');              if (p != NULL) p++;              else p = name;              target_link(p, &text_relocation);              if (text_relocation == (CORE_ADDR)0)                return;              else if (text_relocation == (CORE_ADDR)-1)                symbol_file_add (name, from_tty, (CORE_ADDR)0, 1, mapped,				 readnow);              else                symbol_file_add (name, from_tty, (CORE_ADDR)text_relocation,				 0, mapped, readnow);	      /* Getting new symbols may change our opinion about what is		 frameless.  */	      reinit_frame_cache ();              set_initial_language ();	    }	  argv++;	}      if (name == NULL)	{	  error ("no symbol file name was specified");	}      do_cleanups (cleanups);    }}/* Set the initial language.   A better solution would be to record the language in the psymtab when reading   partial symbols, and then use it (if known) to set the language.  This would   be a win for formats that encode the language in an easily discoverable place,   such as DWARF.  For stabs, we can jump through hoops looking for specially   named symbols or try to intuit the language from the specific type of stabs   we find, but we can't do that until later when we read in full symbols.   FIXME.  */static voidset_initial_language (){  struct partial_symtab *pst;  enum language lang = language_unknown;  	  pst = find_main_psymtab ();  if (pst != NULL)    {      if (pst -> filename != NULL)	{	  lang = deduce_language_from_filename (pst -> filename);        }      if (lang == language_unknown)	{	    /* Make C the default language */	    lang = language_c;	}      set_language (lang);      expected_language = current_language;	/* Don't warn the user */    }}/* Open file specified by NAME and hand it off to BFD for preliminary   analysis.  Result is a newly initialized bfd *, which includes a newly   malloc'd` copy of NAME (tilde-expanded and made absolute).   In case of trouble, error() is called.  */static bfd *symfile_bfd_open (name)     char *name;{  bfd *sym_bfd;  int desc;  char *absolute_name;  name = tilde_expand (name);	/* Returns 1st new malloc'd copy */  /* Look down path for it, allocate 2nd new malloc'd copy.  */  desc = openp (getenv ("PATH"), 1, name, O_RDONLY | O_BINARY, 0, &absolute_name);#if defined(__GO32__) || defined(_WIN32)  if (desc < 0)    {      char *exename = alloca (strlen (name) + 5);      strcat (strcpy (exename, name), ".exe");      desc = openp (getenv ("PATH"), 1, exename, O_RDONLY | O_BINARY,                    0, &absolute_name);    }#endif  if (desc < 0)    {      make_cleanup (free, name);      perror_with_name (name);    }  free (name);			/* Free 1st new malloc'd copy */  name = absolute_name;		/* Keep 2nd malloc'd copy in bfd */				/* It'll be freed in free_objfile(). */  sym_bfd = bfd_fdopenr (name, gnutarget, desc);  if (!sym_bfd)    {      close (desc);      make_cleanup (free, name);      error ("\"%s\": can't open to read symbols: %s.", name,	     bfd_errmsg (bfd_get_error ()));    }  sym_bfd->cacheable = TRUE;  if (!bfd_check_format (sym_bfd, bfd_object))    {      /* FIXME: should be checking for errors from bfd_close (for one thing,	 on error it does not free all the storage associated with the	 bfd).  */      bfd_close (sym_bfd);	/* This also closes desc */      make_cleanup (free, name);      error ("\"%s\": can't read symbols: %s.", name,	     bfd_errmsg (bfd_get_error ()));    }  return (sym_bfd);}