/* Reading symbol files from memory.

   Copyright (C) 1986, 1987, 1989, 1991, 1994, 1995, 1996, 1998, 2000, 2001,
   2002, 2003, 2004, 2005, 2007, 2008, 2009 Free Software Foundation, Inc.

   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 3 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, see <http://www.gnu.org/licenses/>.  */

/* This file defines functions (and commands to exercise those
   functions) for reading debugging information from object files
   whose images are mapped directly into the inferior's memory.  For
   example, the Linux kernel maps a "syscall DSO" into each process's
   address space; this DSO provides kernel-specific code for some
   system calls.

   At the moment, BFD only has functions for parsing object files from
   memory for the ELF format, even though the general idea isn't
   ELF-specific.  This means that BFD only provides the functions GDB
   needs when configured for ELF-based targets.  So these functions
   may only be compiled on ELF-based targets.

   GDB has no idea whether it has been configured for an ELF-based
   target or not: it just tries to handle whatever files it is given.
   But this means there are no preprocessor symbols on which we could
   make these functions' compilation conditional.

   So, for the time being, we put these functions alone in this file,
   and have .mt files reference them as appropriate.  In the future, I
   hope BFD will provide a format-independent bfd_from_remote_memory
   entry point.  */


#include "defs.h"
#include "symtab.h"
#include "gdbcore.h"
#include "objfiles.h"
#include "exceptions.h"
#include "gdbcmd.h"
#include "target.h"
#include "value.h"
#include "symfile.h"
#include "observer.h"
#include "auxv.h"
#include "elf/common.h"


/* Read inferior memory at ADDR to find the header of a loaded object file
   and read its in-core symbols out of inferior memory.  TEMPL is a bfd
   representing the target's format.  NAME is the name to use for this
   symbol file in messages; it can be NULL or a malloc-allocated string
   which will be attached to the BFD.  */
static struct objfile *
symbol_file_add_from_memory (struct bfd *templ, CORE_ADDR addr, char *name,
			     int from_tty)
{
  struct objfile *objf;
  struct bfd *nbfd;
  struct bfd_section *sec;
  bfd_vma loadbase;
  struct section_addr_info *sai;
  unsigned int i;

  if (bfd_get_flavour (templ) != bfd_target_elf_flavour)
    error (_("add-symbol-file-from-memory not supported for this target"));

  nbfd = bfd_elf_bfd_from_remote_memory (templ, addr, &loadbase,
					 target_read_memory);
  if (nbfd == NULL)
    error (_("Failed to read a valid object file image from memory."));

  if (name == NULL)
    nbfd->filename = xstrdup ("shared object read from target memory");
  else
    nbfd->filename = name;

  if (!bfd_check_format (nbfd, 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 (nbfd);
      error (_("Got object file from memory but can't read symbols: %s."),
	     bfd_errmsg (bfd_get_error ()));
    }

  sai = alloc_section_addr_info (bfd_count_sections (nbfd));
  make_cleanup (xfree, sai);
  i = 0;
  for (sec = nbfd->sections; sec != NULL; sec = sec->next)
    if ((bfd_get_section_flags (nbfd, sec) & (SEC_ALLOC|SEC_LOAD)) != 0)
      {
	sai->other[i].addr = bfd_get_section_vma (nbfd, sec) + loadbase;
	sai->other[i].name = (char *) bfd_get_section_name (nbfd, sec);
	sai->other[i].sectindex = sec->index;
	++i;
      }

  objf = symbol_file_add_from_bfd (nbfd, from_tty ? SYMFILE_VERBOSE : 0,
                                   sai, OBJF_SHARED);

  /* This might change our ideas about frames already looked at.  */
  reinit_frame_cache ();

  return objf;
}


static void
add_symbol_file_from_memory_command (char *args, int from_tty)
{
  CORE_ADDR addr;
  struct bfd *templ;

  if (args == NULL)
    error (_("add-symbol-file-from-memory requires an expression argument"));

  addr = parse_and_eval_address (args);

  /* We need some representative bfd to know the target we are looking at.  */
  if (symfile_objfile != NULL)
    templ = symfile_objfile->obfd;
  else
    templ = exec_bfd;
  if (templ == NULL)
    error (_("\
Must use symbol-file or exec-file before add-symbol-file-from-memory."));

  symbol_file_add_from_memory (templ, addr, NULL, from_tty);
}

/* Arguments for symbol_file_add_from_memory_wrapper.  */

struct symbol_file_add_from_memory_args
{
  struct bfd *bfd;
  CORE_ADDR sysinfo_ehdr;
  char *name;
  int from_tty;
};

/* Wrapper function for symbol_file_add_from_memory, for
   catch_exceptions.  */

static int
symbol_file_add_from_memory_wrapper (struct ui_out *uiout, void *data)
{
  struct symbol_file_add_from_memory_args *args = data;

  symbol_file_add_from_memory (args->bfd, args->sysinfo_ehdr, args->name,
			       args->from_tty);
  return 0;
}

/* Try to add the symbols for the vsyscall page, if there is one.  This function
   is called via the inferior_created observer.  */

static void
add_vsyscall_page (struct target_ops *target, int from_tty)
{
  CORE_ADDR sysinfo_ehdr;

  if (target_auxv_search (target, AT_SYSINFO_EHDR, &sysinfo_ehdr) > 0
      && sysinfo_ehdr != (CORE_ADDR) 0)
    {
      struct bfd *bfd;
      struct symbol_file_add_from_memory_args args;

      if (core_bfd != NULL)
	bfd = core_bfd;
      else if (exec_bfd != NULL)
	bfd = exec_bfd;
      else
       /* FIXME: cagney/2004-05-06: Should not require an existing
	  BFD when trying to create a run-time BFD of the VSYSCALL
	  page in the inferior.  Unfortunately that's the current
	  interface so for the moment bail.  Introducing a
	  ``bfd_runtime'' (a BFD created using the loaded image) file
	  format should fix this.  */
	{
	  warning (_("\
Could not load vsyscall page because no executable was specified\n\
try using the \"file\" command first."));
	  return;
	}
      args.bfd = bfd;
      args.sysinfo_ehdr = sysinfo_ehdr;
      args.name = xstrprintf ("system-supplied DSO at %s",
			      paddress (target_gdbarch, sysinfo_ehdr));
      /* Pass zero for FROM_TTY, because the action of loading the
	 vsyscall DSO was not triggered by the user, even if the user
	 typed "run" at the TTY.  */
      args.from_tty = 0;
      catch_exceptions (uiout, symbol_file_add_from_memory_wrapper,
			&args, RETURN_MASK_ALL);
    }
}



/* Provide a prototype to silence -Wmissing-prototypes.  */
extern initialize_file_ftype _initialize_symfile_mem;

void
_initialize_symfile_mem (void)
{
  add_cmd ("add-symbol-file-from-memory", class_files,
           add_symbol_file_from_memory_command, _("\
Load the symbols out of memory from a dynamically loaded object file.\n\
Give an expression for the address of the file's shared object file header."),
           &cmdlist);

  /* Want to know of each new inferior so that its vsyscall info can
     be extracted.  */
  observer_attach_inferior_created (add_vsyscall_page);
}
