/* GDB routines for manipulating objfiles.
   Copyright 1992, 1993, 1994, 1995 Free Software Foundation, Inc.
   Contributed by Cygnus Support, using pieces from other GDB modules.

   This file is part of GDB.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   Foundation, Inc., 59 Temple Place - Suite 330,
   Boston, MA 02111-1307, USA.  */

/* This file contains support routines for creating, manipulating, and
   destroying objfile structures. */

#include "defs.h"
#include "bfd.h"		/* Binary File Description */
#include "symtab.h"
#include "symfile.h"
#include "objfiles.h"
#include "gdb-stabs.h"
#include "target.h"

#include <sys/types.h>
#include "gdb_stat.h"
#include <fcntl.h>
#include "obstack.h"
#include "gdb_string.h"

#include "breakpoint.h"

/* Prototypes for local functions */

#if defined(USE_MMALLOC) && defined(HAVE_MMAP)

static int
open_existing_mapped_file PARAMS ((char *, long, int));

static int
open_mapped_file PARAMS ((char *filename, long mtime, int mapped));

static PTR
  map_to_file PARAMS ((int));

#endif /* defined(USE_MMALLOC) && defined(HAVE_MMAP) */

static void
add_to_objfile_sections PARAMS ((bfd *, sec_ptr, PTR));

/* Externally visible variables that are owned by this module.
   See declarations in objfile.h for more info. */

struct objfile *object_files;	/* Linked list of all objfiles */
struct objfile *current_objfile;	/* For symbol file being read in */
struct objfile *symfile_objfile;	/* Main symbol table loaded from */
struct objfile *rt_common_objfile;	/* For runtime common symbols */

int mapped_symbol_files;	/* Try to use mapped symbol files */

/* Locate all mappable sections of a BFD file. 
   objfile_p_char is a char * to get it through
   bfd_map_over_sections; we cast it back to its proper type.  */

#ifndef TARGET_KEEP_SECTION
#define TARGET_KEEP_SECTION(ASECT)	0
#endif

static void
add_to_objfile_sections (abfd, asect, objfile_p_char)
     bfd *abfd;
     sec_ptr asect;
     PTR objfile_p_char;
{
  struct objfile *objfile = (struct objfile *) objfile_p_char;
  struct obj_section section;
  flagword aflag;

  aflag = bfd_get_section_flags (abfd, asect);

  if (!(aflag & SEC_ALLOC) && !(TARGET_KEEP_SECTION (asect)))
    return;

  if (0 == bfd_section_size (abfd, asect))
    return;
  section.offset = 0;
  section.objfile = objfile;
  section.the_bfd_section = asect;
  section.ovly_mapped = 0;
  section.addr = bfd_section_vma (abfd, asect);
  section.endaddr = section.addr + bfd_section_size (abfd, asect);
  obstack_grow (&objfile->psymbol_obstack, (char *) &section, sizeof (section));
  objfile->sections_end = (struct obj_section *) (((unsigned long) objfile->sections_end) + 1);
}

/* Builds a section table for OBJFILE.
   Returns 0 if OK, 1 on error (in which case bfd_error contains the
   error).  */

int
build_objfile_section_table (objfile)
     struct objfile *objfile;
{
  /* objfile->sections can be already set when reading a mapped symbol
     file.  I believe that we do need to rebuild the section table in
     this case (we rebuild other things derived from the bfd), but we
     can't free the old one (it's in the psymbol_obstack).  So we just
     waste some memory.  */

  objfile->sections_end = 0;
  bfd_map_over_sections (objfile->obfd, add_to_objfile_sections, (char *) objfile);
  objfile->sections = (struct obj_section *)
    obstack_finish (&objfile->psymbol_obstack);
  objfile->sections_end = objfile->sections + (unsigned long) objfile->sections_end;
  return (0);
}

/* Given a pointer to an initialized bfd (ABFD) and a flag that indicates
   whether or not an objfile is to be mapped (MAPPED), allocate a new objfile
   struct, fill it in as best we can, link it into the list of all known
   objfiles, and return a pointer to the new objfile struct.

   USER_LOADED is simply recorded in the objfile.  This record offers a way for
   run_command to remove old objfile entries which are no longer valid (i.e.,
   are associated with an old inferior), but to preserve ones that the user
   explicitly loaded via the add-symbol-file command.

   IS_SOLIB is also simply recorded in the objfile. */

struct objfile *
allocate_objfile (abfd, mapped, user_loaded, is_solib)
     bfd *abfd;
     int mapped;
     int user_loaded;
     int is_solib;
{
  struct objfile *objfile = NULL;
  struct objfile *last_one = NULL;

  mapped |= mapped_symbol_files;

#if defined(USE_MMALLOC) && defined(HAVE_MMAP)
  if (abfd != NULL)
    {

      /* If we can support mapped symbol files, try to open/reopen the
         mapped file that corresponds to the file from which we wish to
         read symbols.  If the objfile is to be mapped, we must malloc
         the structure itself using the mmap version, and arrange that
         all memory allocation for the objfile uses the mmap routines.
         If we are reusing an existing mapped file, from which we get
         our objfile pointer, we have to make sure that we update the
         pointers to the alloc/free functions in the obstack, in case
         these functions have moved within the current gdb.  */

      int fd;

      fd = open_mapped_file (bfd_get_filename (abfd), bfd_get_mtime (abfd),
			     mapped);
      if (fd >= 0)
	{
	  PTR md;

	  if ((md = map_to_file (fd)) == NULL)
	    {
	      close (fd);
	    }
	  else if ((objfile = (struct objfile *) mmalloc_getkey (md, 0)) != NULL)
	    {
	      /* Update memory corruption handler function addresses. */
	      init_malloc (md);
	      objfile->md = md;
	      objfile->mmfd = fd;
	      /* Update pointers to functions to *our* copies */
	      obstack_chunkfun (&objfile->psymbol_cache.cache, xmmalloc);
	      obstack_freefun (&objfile->psymbol_cache.cache, mfree);
	      obstack_chunkfun (&objfile->psymbol_obstack, xmmalloc);
	      obstack_freefun (&objfile->psymbol_obstack, mfree);
	      obstack_chunkfun (&objfile->symbol_obstack, xmmalloc);
	      obstack_freefun (&objfile->symbol_obstack, mfree);
	      obstack_chunkfun (&objfile->type_obstack, xmmalloc);
	      obstack_freefun (&objfile->type_obstack, mfree);
	      /* If already in objfile list, unlink it. */
	      unlink_objfile (objfile);
	      /* Forget things specific to a particular gdb, may have changed. */
	      objfile->sf = NULL;
	    }
	  else
	    {

	      /* Set up to detect internal memory corruption.  MUST be
	         done before the first malloc.  See comments in
	         init_malloc() and mmcheck().  */

	      init_malloc (md);

	      objfile = (struct objfile *)
		xmmalloc (md, sizeof (struct objfile));
	      memset (objfile, 0, sizeof (struct objfile));
	      objfile->md = md;
	      objfile->mmfd = fd;
	      objfile->flags |= OBJF_MAPPED;
	      mmalloc_setkey (objfile->md, 0, objfile);
	      obstack_specify_allocation_with_arg (&objfile->psymbol_cache.cache,
						   0, 0, xmmalloc, mfree,
						   objfile->md);
	      obstack_specify_allocation_with_arg (&objfile->psymbol_obstack,
						   0, 0, xmmalloc, mfree,
						   objfile->md);
	      obstack_specify_allocation_with_arg (&objfile->symbol_obstack,
						   0, 0, xmmalloc, mfree,
						   objfile->md);
	      obstack_specify_allocation_with_arg (&objfile->type_obstack,
						   0, 0, xmmalloc, mfree,
						   objfile->md);
	    }
	}

      if (mapped && (objfile == NULL))
	{
	  warning ("symbol table for '%s' will not be mapped",
		   bfd_get_filename (abfd));
	}
    }
#else /* !defined(USE_MMALLOC) || !defined(HAVE_MMAP) */

  if (mapped)
    {
      warning ("mapped symbol tables are not supported on this machine; missing or broken mmap().");

      /* Turn off the global flag so we don't try to do mapped symbol tables
         any more, which shuts up gdb unless the user specifically gives the
         "mapped" keyword again. */

      mapped_symbol_files = 0;
    }

#endif /* defined(USE_MMALLOC) && defined(HAVE_MMAP) */

  /* If we don't support mapped symbol files, didn't ask for the file to be
     mapped, or failed to open the mapped file for some reason, then revert
     back to an unmapped objfile. */

  if (objfile == NULL)
    {
      objfile = (struct objfile *) xmalloc (sizeof (struct objfile));
      memset (objfile, 0, sizeof (struct objfile));
      objfile->md = NULL;
      obstack_specify_allocation (&objfile->psymbol_cache.cache, 0, 0,
				  xmalloc, free);
      obstack_specify_allocation (&objfile->psymbol_obstack, 0, 0, xmalloc,
				  free);
      obstack_specify_allocation (&objfile->symbol_obstack, 0, 0, xmalloc,
				  free);
      obstack_specify_allocation (&objfile->type_obstack, 0, 0, xmalloc,
				  free);
    }

  /* Update the per-objfile information that comes from the bfd, ensuring
     that any data that is reference is saved in the per-objfile data
     region. */

  objfile->obfd = abfd;
  if (objfile->name != NULL)
    {
      mfree (objfile->md, objfile->name);
    }
  if (abfd != NULL)
    {
      objfile->name = mstrsave (objfile->md, bfd_get_filename (abfd));
      objfile->mtime = bfd_get_mtime (abfd);

      /* Build section table.  */

      if (build_objfile_section_table (objfile))
	{
	  error ("Can't find the file sections in `%s': %s",
		 objfile->name, bfd_errmsg (bfd_get_error ()));
	}
    }

  /* Add this file onto the tail of the linked list of other such files. */

  objfile->next = NULL;
  if (object_files == NULL)
    object_files = objfile;
  else
    {
      for (last_one = object_files;
	   last_one->next;
	   last_one = last_one->next);
      last_one->next = objfile;
    }

  /* Record whether this objfile was created because the user explicitly
     caused it (e.g., used the add-symbol-file command).
   */
  objfile->user_loaded = user_loaded;

  /* Record whether this objfile definitely represents a solib. */
  objfile->is_solib = is_solib;

  return (objfile);
}

/* Put OBJFILE at the front of the list.  */

void
objfile_to_front (objfile)
     struct objfile *objfile;
{
  struct objfile **objp;
  for (objp = &object_files; *objp != NULL; objp = &((*objp)->next))
    {
      if (*objp == objfile)
	{
	  /* Unhook it from where it is.  */
	  *objp = objfile->next;
	  /* Put it in the front.  */
	  objfile->next = object_files;
	  object_files = objfile;
	  break;
	}
    }
}

/* Unlink OBJFILE from the list of known objfiles, if it is found in the
   list.

   It is not a bug, or error, to call this function if OBJFILE is not known
   to be in the current list.  This is done in the case of mapped objfiles,
   for example, just to ensure that the mapped objfile doesn't appear twice
   in the list.  Since the list is threaded, linking in a mapped objfile
   twice would create a circular list.

   If OBJFILE turns out to be in the list, we zap it's NEXT pointer after
   unlinking it, just to ensure that we have completely severed any linkages
   between the OBJFILE and the list. */

void
unlink_objfile (objfile)
     struct objfile *objfile;
{
  struct objfile **objpp;

  for (objpp = &object_files; *objpp != NULL; objpp = &((*objpp)->next))
    {
      if (*objpp == objfile)
	{
	  *objpp = (*objpp)->next;
	  objfile->next = NULL;
	  break;
	}
    }
}


/* Destroy an objfile and all the symtabs and psymtabs under it.  Note
   that as much as possible is allocated on the symbol_obstack and
   psymbol_obstack, so that the memory can be efficiently freed.

   Things which we do NOT free because they are not in malloc'd memory
   or not in memory specific to the objfile include:

   objfile -> sf

   FIXME:  If the objfile is using reusable symbol information (via mmalloc),
   then we need to take into account the fact that more than one process
   may be using the symbol information at the same time (when mmalloc is
   extended to support cooperative locking).  When more than one process
   is using the mapped symbol info, we need to be more careful about when
   we free objects in the reusable area. */

void
free_objfile (objfile)
     struct objfile *objfile;
{
  /* First do any symbol file specific actions required when we are
     finished with a particular symbol file.  Note that if the objfile
     is using reusable symbol information (via mmalloc) then each of
     these routines is responsible for doing the correct thing, either
     freeing things which are valid only during this particular gdb
     execution, or leaving them to be reused during the next one. */

  if (objfile->sf != NULL)
    {
      (*objfile->sf->sym_finish) (objfile);
    }

  /* We always close the bfd. */

  if (objfile->obfd != NULL)
    {
      char *name = bfd_get_filename (objfile->obfd);
      if (!bfd_close (objfile->obfd))
	warning ("cannot close \"%s\": %s",
		 name, bfd_errmsg (bfd_get_error ()));
      free (name);
    }

  /* Remove it from the chain of all objfiles. */

  unlink_objfile (objfile);

  /* If we are going to free the runtime common objfile, mark it
     as unallocated.  */

  if (objfile == rt_common_objfile)
    rt_common_objfile = NULL;

  /* Before the symbol table code was redone to make it easier to
     selectively load and remove information particular to a specific
     linkage unit, gdb used to do these things whenever the monolithic
     symbol table was blown away.  How much still needs to be done
     is unknown, but we play it safe for now and keep each action until
     it is shown to be no longer needed. */

#if defined (CLEAR_SOLIB)
  CLEAR_SOLIB ();
  /* CLEAR_SOLIB closes the bfd's for any shared libraries.  But
     the to_sections for a core file might refer to those bfd's.  So
     detach any core file.  */
  {
    struct target_ops *t = find_core_target ();
    if (t != NULL)
      (t->to_detach) (NULL, 0);
  }
#endif
  /* I *think* all our callers call clear_symtab_users.  If so, no need
     to call this here.  */
  clear_pc_function_cache ();

  /* The last thing we do is free the objfile struct itself for the
     non-reusable case, or detach from the mapped file for the reusable
     case.  Note that the mmalloc_detach or the mfree is the last thing
     we can do with this objfile. */

#if defined(USE_MMALLOC) && defined(HAVE_MMAP)

  if (objfile->flags & OBJF_MAPPED)
    {
      /* Remember the fd so we can close it.  We can't close it before
         doing the detach, and after the detach the objfile is gone. */
      int mmfd;

      mmfd = objfile->mmfd;
      mmalloc_detach (objfile->md);
      objfile = NULL;
      close (mmfd);
    }

#endif /* defined(USE_MMALLOC) && defined(HAVE_MMAP) */

  /* If we still have an objfile, then either we don't support reusable
     objfiles or this one was not reusable.  So free it normally. */

  if (objfile != NULL)
    {
      if (objfile->name != NULL)
	{
	  mfree (objfile->md, objfile->name);
	}
      if (objfile->global_psymbols.list)
	mfree (objfile->md, objfile->global_psymbols.list);
      if (objfile->static_psymbols.list)
	mfree (objfile->md, objfile->static_psymbols.list);
      /* Free the obstacks for non-reusable objfiles */
      obstack_free (&objfile->psymbol_cache.cache, 0);
      obstack_free (&objfile->psymbol_obstack, 0);
      obstack_free (&objfile->symbol_obstack, 0);
      obstack_free (&objfile->type_obstack, 0);
      mfree (objfile->md, objfile);
      objfile = NULL;
    }
}


/* Free all the object files at once and clean up their users.  */

void
free_all_objfiles ()
{
  struct objfile *objfile, *temp;

  ALL_OBJFILES_SAFE (objfile, temp)
  {
    free_objfile (objfile);
  }
  clear_symtab_users ();
}

/* Relocate OBJFILE to NEW_OFFSETS.  There should be OBJFILE->NUM_SECTIONS
   entries in new_offsets.  */
void
objfile_relocate (objfile, new_offsets)
     struct objfile *objfile;
     struct section_offsets *new_offsets;
{
  struct section_offsets *delta = (struct section_offsets *)
  alloca (sizeof (struct section_offsets)
	  + objfile->num_sections * sizeof (delta->offsets));

  {
    int i;
    int something_changed = 0;
    for (i = 0; i < objfile->num_sections; ++i)
      {
	ANOFFSET (delta, i) =
	  ANOFFSET (new_offsets, i) - ANOFFSET (objfile->section_offsets, i);
	if (ANOFFSET (delta, i) != 0)
	  something_changed = 1;
      }
    if (!something_changed)
      return;
  }

  /* OK, get all the symtabs.  */
  {
    struct symtab *s;

    ALL_OBJFILE_SYMTABS (objfile, s)
    {
      struct linetable *l;
      struct blockvector *bv;
      int i;

      /* First the line table.  */
      l = LINETABLE (s);
      if (l)
	{
	  for (i = 0; i < l->nitems; ++i)
	    l->item[i].pc += ANOFFSET (delta, s->block_line_section);
	}

      /* Don't relocate a shared blockvector more than once.  */
      if (!s->primary)
	continue;

      bv = BLOCKVECTOR (s);
      for (i = 0; i < BLOCKVECTOR_NBLOCKS (bv); ++i)
	{
	  struct block *b;
	  int j;

	  b = BLOCKVECTOR_BLOCK (bv, i);
	  BLOCK_START (b) += ANOFFSET (delta, s->block_line_section);
	  BLOCK_END (b) += ANOFFSET (delta, s->block_line_section);

	  for (j = 0; j < BLOCK_NSYMS (b); ++j)
	    {
	      struct symbol *sym = BLOCK_SYM (b, j);
	      /* The RS6000 code from which this was taken skipped
	         any symbols in STRUCT_NAMESPACE or UNDEF_NAMESPACE.
	         But I'm leaving out that test, on the theory that
	         they can't possibly pass the tests below.  */
	      if ((SYMBOL_CLASS (sym) == LOC_LABEL
		   || SYMBOL_CLASS (sym) == LOC_STATIC
		   || SYMBOL_CLASS (sym) == LOC_INDIRECT)
		  && SYMBOL_SECTION (sym) >= 0)
		{
		  SYMBOL_VALUE_ADDRESS (sym) +=
		    ANOFFSET (delta, SYMBOL_SECTION (sym));
		}
#ifdef MIPS_EFI_SYMBOL_NAME
	      /* Relocate Extra Function Info for ecoff.  */

	      else if (SYMBOL_CLASS (sym) == LOC_CONST
		       && SYMBOL_NAMESPACE (sym) == LABEL_NAMESPACE
		   && STRCMP (SYMBOL_NAME (sym), MIPS_EFI_SYMBOL_NAME) == 0)
		ecoff_relocate_efi (sym, ANOFFSET (delta,
						   s->block_line_section));
#endif
	    }
	}
    }
  }

  {
    struct partial_symtab *p;

    ALL_OBJFILE_PSYMTABS (objfile, p)
    {
      p->textlow += ANOFFSET (delta, SECT_OFF_TEXT);
      p->texthigh += ANOFFSET (delta, SECT_OFF_TEXT);
    }
  }

  {
    struct partial_symbol **psym;

    for (psym = objfile->global_psymbols.list;
	 psym < objfile->global_psymbols.next;
	 psym++)
      if (SYMBOL_SECTION (*psym) >= 0)
	SYMBOL_VALUE_ADDRESS (*psym) += ANOFFSET (delta,
						  SYMBOL_SECTION (*psym));
    for (psym = objfile->static_psymbols.list;
	 psym < objfile->static_psymbols.next;
	 psym++)
      if (SYMBOL_SECTION (*psym) >= 0)
	SYMBOL_VALUE_ADDRESS (*psym) += ANOFFSET (delta,
						  SYMBOL_SECTION (*psym));
  }

  {
    struct minimal_symbol *msym;
    ALL_OBJFILE_MSYMBOLS (objfile, msym)
      if (SYMBOL_SECTION (msym) >= 0)
      SYMBOL_VALUE_ADDRESS (msym) += ANOFFSET (delta, SYMBOL_SECTION (msym));
  }
  /* Relocating different sections by different amounts may cause the symbols
     to be out of order.  */
  msymbols_sort (objfile);

  {
    int i;
    for (i = 0; i < objfile->num_sections; ++i)
      ANOFFSET (objfile->section_offsets, i) = ANOFFSET (new_offsets, i);
  }

  {
    struct obj_section *s;
    bfd *abfd;

    abfd = objfile->obfd;

    for (s = objfile->sections;
	 s < objfile->sections_end; ++s)
      {
	flagword flags;

	flags = bfd_get_section_flags (abfd, s->the_bfd_section);

	if (flags & SEC_CODE)
	  {
	    s->addr += ANOFFSET (delta, SECT_OFF_TEXT);
	    s->endaddr += ANOFFSET (delta, SECT_OFF_TEXT);
	  }
	else if (flags & (SEC_DATA | SEC_LOAD))
	  {
	    s->addr += ANOFFSET (delta, SECT_OFF_DATA);
	    s->endaddr += ANOFFSET (delta, SECT_OFF_DATA);
	  }
	else if (flags & SEC_ALLOC)
	  {
	    s->addr += ANOFFSET (delta, SECT_OFF_BSS);
	    s->endaddr += ANOFFSET (delta, SECT_OFF_BSS);
	  }
      }
  }

  if (objfile->ei.entry_point != ~(CORE_ADDR) 0)
    objfile->ei.entry_point += ANOFFSET (delta, SECT_OFF_TEXT);

  if (objfile->ei.entry_func_lowpc != INVALID_ENTRY_LOWPC)
    {
      objfile->ei.entry_func_lowpc += ANOFFSET (delta, SECT_OFF_TEXT);
      objfile->ei.entry_func_highpc += ANOFFSET (delta, SECT_OFF_TEXT);
    }

  if (objfile->ei.entry_file_lowpc != INVALID_ENTRY_LOWPC)
    {
      objfile->ei.entry_file_lowpc += ANOFFSET (delta, SECT_OFF_TEXT);
      objfile->ei.entry_file_highpc += ANOFFSET (delta, SECT_OFF_TEXT);
    }

  if (objfile->ei.main_func_lowpc != INVALID_ENTRY_LOWPC)
    {
      objfile->ei.main_func_lowpc += ANOFFSET (delta, SECT_OFF_TEXT);
      objfile->ei.main_func_highpc += ANOFFSET (delta, SECT_OFF_TEXT);
    }

  /* Relocate breakpoints as necessary, after things are relocated. */
  breakpoint_re_set ();
}

/* Many places in gdb want to test just to see if we have any partial
   symbols available.  This function returns zero if none are currently
   available, nonzero otherwise. */

int
have_partial_symbols ()
{
  struct objfile *ofp;

  ALL_OBJFILES (ofp)
  {
    if (ofp->psymtabs != NULL)
      {
	return 1;
      }
  }
  return 0;
}

/* Many places in gdb want to test just to see if we have any full
   symbols available.  This function returns zero if none are currently
   available, nonzero otherwise. */

int
have_full_symbols ()
{
  struct objfile *ofp;

  ALL_OBJFILES (ofp)
  {
    if (ofp->symtabs != NULL)
      {
	return 1;
      }
  }
  return 0;
}


/* This operations deletes all objfile entries that represent solibs that
   weren't explicitly loaded by the user, via e.g., the add-symbol-file
   command.
 */
void
objfile_purge_solibs ()
{
  struct objfile *objf;
  struct objfile *temp;

  ALL_OBJFILES_SAFE (objf, temp)
  {
    /* We assume that the solib package has been purged already, or will
       be soon.
     */
    if (!objf->user_loaded && objf->is_solib)
      free_objfile (objf);
  }
}


/* Many places in gdb want to test just to see if we have any minimal
   symbols available.  This function returns zero if none are currently
   available, nonzero otherwise. */

int
have_minimal_symbols ()
{
  struct objfile *ofp;

  ALL_OBJFILES (ofp)
  {
    if (ofp->msymbols != NULL)
      {
	return 1;
      }
  }
  return 0;
}

#if defined(USE_MMALLOC) && defined(HAVE_MMAP)

/* Given the name of a mapped symbol file in SYMSFILENAME, and the timestamp
   of the corresponding symbol file in MTIME, try to open an existing file
   with the name SYMSFILENAME and verify it is more recent than the base
   file by checking it's timestamp against MTIME.

   If SYMSFILENAME does not exist (or can't be stat'd), simply returns -1.

   If SYMSFILENAME does exist, but is out of date, we check to see if the
   user has specified creation of a mapped file.  If so, we don't issue
   any warning message because we will be creating a new mapped file anyway,
   overwriting the old one.  If not, then we issue a warning message so that
   the user will know why we aren't using this existing mapped symbol file.
   In either case, we return -1.

   If SYMSFILENAME does exist and is not out of date, but can't be opened for
   some reason, then prints an appropriate system error message and returns -1.

   Otherwise, returns the open file descriptor.  */

static int
open_existing_mapped_file (symsfilename, mtime, mapped)
     char *symsfilename;
     long mtime;
     int mapped;
{
  int fd = -1;
  struct stat sbuf;

  if (stat (symsfilename, &sbuf) == 0)
    {
      if (sbuf.st_mtime < mtime)
	{
	  if (!mapped)
	    {
	      warning ("mapped symbol file `%s' is out of date, ignored it",
		       symsfilename);
	    }
	}
      else if ((fd = open (symsfilename, O_RDWR)) < 0)
	{
	  if (error_pre_print)
	    {
	      printf_unfiltered (error_pre_print);
	    }
	  print_sys_errmsg (symsfilename, errno);
	}
    }
  return (fd);
}

/* Look for a mapped symbol file that corresponds to FILENAME and is more
   recent than MTIME.  If MAPPED is nonzero, the user has asked that gdb
   use a mapped symbol file for this file, so create a new one if one does
   not currently exist.

   If found, then return an open file descriptor for the file, otherwise
   return -1.

   This routine is responsible for implementing the policy that generates
   the name of the mapped symbol file from the name of a file containing
   symbols that gdb would like to read.  Currently this policy is to append
   ".syms" to the name of the file.

   This routine is also responsible for implementing the policy that
   determines where the mapped symbol file is found (the search path).
   This policy is that when reading an existing mapped file, a file of
   the correct name in the current directory takes precedence over a
   file of the correct name in the same directory as the symbol file.
   When creating a new mapped file, it is always created in the current
   directory.  This helps to minimize the chances of a user unknowingly
   creating big mapped files in places like /bin and /usr/local/bin, and
   allows a local copy to override a manually installed global copy (in
   /bin for example).  */

static int
open_mapped_file (filename, mtime, mapped)
     char *filename;
     long mtime;
     int mapped;
{
  int fd;
  char *symsfilename;

  /* First try to open an existing file in the current directory, and
     then try the directory where the symbol file is located. */

  symsfilename = concat ("./", basename (filename), ".syms", (char *) NULL);
  if ((fd = open_existing_mapped_file (symsfilename, mtime, mapped)) < 0)
    {
      free (symsfilename);
      symsfilename = concat (filename, ".syms", (char *) NULL);
      fd = open_existing_mapped_file (symsfilename, mtime, mapped);
    }

  /* If we don't have an open file by now, then either the file does not
     already exist, or the base file has changed since it was created.  In
     either case, if the user has specified use of a mapped file, then
     create a new mapped file, truncating any existing one.  If we can't
     create one, print a system error message saying why we can't.

     By default the file is rw for everyone, with the user's umask taking
     care of turning off the permissions the user wants off. */

  if ((fd < 0) && mapped)
    {
      free (symsfilename);
      symsfilename = concat ("./", basename (filename), ".syms",
			     (char *) NULL);
      if ((fd = open (symsfilename, O_RDWR | O_CREAT | O_TRUNC, 0666)) < 0)
	{
	  if (error_pre_print)
	    {
	      printf_unfiltered (error_pre_print);
	    }
	  print_sys_errmsg (symsfilename, errno);
	}
    }

  free (symsfilename);
  return (fd);
}

static PTR
map_to_file (fd)
     int fd;
{
  PTR md;
  CORE_ADDR mapto;

  md = mmalloc_attach (fd, (PTR) 0);
  if (md != NULL)
    {
      mapto = (CORE_ADDR) mmalloc_getkey (md, 1);
      md = mmalloc_detach (md);
      if (md != NULL)
	{
	  /* FIXME: should figure out why detach failed */
	  md = NULL;
	}
      else if (mapto != (CORE_ADDR) NULL)
	{
	  /* This mapping file needs to be remapped at "mapto" */
	  md = mmalloc_attach (fd, (PTR) mapto);
	}
      else
	{
	  /* This is a freshly created mapping file. */
	  mapto = (CORE_ADDR) mmalloc_findbase (20 * 1024 * 1024);
	  if (mapto != 0)
	    {
	      /* To avoid reusing the freshly created mapping file, at the 
	         address selected by mmap, we must truncate it before trying
	         to do an attach at the address we want. */
	      ftruncate (fd, 0);
	      md = mmalloc_attach (fd, (PTR) mapto);
	      if (md != NULL)
		{
		  mmalloc_setkey (md, 1, (PTR) mapto);
		}
	    }
	}
    }
  return (md);
}

#endif /* defined(USE_MMALLOC) && defined(HAVE_MMAP) */

/* Returns a section whose range includes PC and SECTION, 
   or NULL if none found.  Note the distinction between the return type, 
   struct obj_section (which is defined in gdb), and the input type
   struct sec (which is a bfd-defined data type).  The obj_section
   contains a pointer to the bfd struct sec section.  */

struct obj_section *
find_pc_sect_section (pc, section)
     CORE_ADDR pc;
     struct sec *section;
{
  struct obj_section *s;
  struct objfile *objfile;

  ALL_OBJFILES (objfile)
    for (s = objfile->sections; s < objfile->sections_end; ++s)
#if defined(HPUXHPPA)
    if ((section == 0 || section == s->the_bfd_section) &&
	s->addr <= pc && pc <= s->endaddr)
#else
    if ((section == 0 || section == s->the_bfd_section) &&
	s->addr <= pc && pc < s->endaddr)
#endif
      return (s);

  return (NULL);
}

/* Returns a section whose range includes PC or NULL if none found. 
   Backward compatibility, no section.  */

struct obj_section *
find_pc_section (pc)
     CORE_ADDR pc;
{
  return find_pc_sect_section (pc, find_pc_mapped_section (pc));
}


/* In SVR4, we recognize a trampoline by it's section name. 
   That is, if the pc is in a section named ".plt" then we are in
   a trampoline.  */

int
in_plt_section (pc, name)
     CORE_ADDR pc;
     char *name;
{
  struct obj_section *s;
  int retval = 0;

  s = find_pc_section (pc);

  retval = (s != NULL
	    && s->the_bfd_section->name != NULL
	    && STREQ (s->the_bfd_section->name, ".plt"));
  return (retval);
}
