/* Generate a core file for the inferior process.

   Copyright 2001, 2002, 2003 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 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.  */

#include "defs.h"
#include "cli/cli-decode.h"
#include "inferior.h"
#include "gdbcore.h"
#include "elf-bfd.h"
#include "symfile.h"
#include "objfiles.h"

static char                  *default_gcore_target (void);
static enum bfd_architecture  default_gcore_arch (void);
static unsigned long          default_gcore_mach (void);
static int                    gcore_memory_sections (bfd *);

/* Function: gcore_command
   Generate a core file from the inferior process.  */

static void
gcore_command (char *args, int from_tty)
{
  struct cleanup *old_chain;
  char *corefilename, corefilename_buffer[40];
  asection *note_sec = NULL;
  bfd *obfd;
  void *note_data = NULL;
  int note_size = 0;

  /* No use generating a corefile without a target process.  */
  if (!(target_has_execution))
    noprocess ();

  if (args && *args)
    corefilename = args;
  else
    {
      /* Default corefile name is "core.PID".  */
      sprintf (corefilename_buffer, "core.%d", PIDGET (inferior_ptid));
      corefilename = corefilename_buffer;
    }

  if (info_verbose)
    fprintf_filtered (gdb_stdout, 
		      "Opening corefile '%s' for output.\n", corefilename);

  /* Open the output file. */
  if (!(obfd = bfd_openw (corefilename, default_gcore_target ())))
    {
      error ("Failed to open '%s' for output.", corefilename);
    }

  /* Need a cleanup that will close the file (FIXME: delete it?). */
  old_chain = make_cleanup_bfd_close (obfd);

  bfd_set_format (obfd, bfd_core);
  bfd_set_arch_mach (obfd, default_gcore_arch (), default_gcore_mach ());

  /* An external target method must build the notes section. */
  note_data = (char *) target_make_corefile_notes (obfd, &note_size);

  /* Create the note section. */
  if (note_data != NULL && note_size != 0)
    {
      if ((note_sec = bfd_make_section_anyway (obfd, "note0")) == NULL)
	error ("Failed to create 'note' section for corefile: %s", 
	       bfd_errmsg (bfd_get_error ()));

      bfd_set_section_vma (obfd, note_sec, 0);
      bfd_set_section_flags (obfd, note_sec, 
			     SEC_HAS_CONTENTS | SEC_READONLY | SEC_ALLOC);
      bfd_set_section_alignment (obfd, note_sec, 0);
      bfd_set_section_size (obfd, note_sec, note_size);
    }

  /* Now create the memory/load sections. */
  if (gcore_memory_sections (obfd) == 0)
    error ("gcore: failed to get corefile memory sections from target.");

  /* Write out the contents of the note section. */
  if (note_data != NULL && note_size != 0)
    {
      if (!bfd_set_section_contents (obfd, note_sec, note_data, 0, note_size))
	{
	  warning ("writing note section (%s)", 
		   bfd_errmsg (bfd_get_error ()));
	}
    }

  /* Succeeded. */
  fprintf_filtered (gdb_stdout, 
		    "Saved corefile %s\n", corefilename);

  /* Clean-ups will close the output file and free malloc memory. */
  do_cleanups (old_chain);
  return;
}

static unsigned long
default_gcore_mach (void)
{
#if 1	/* See if this even matters... */
  return 0;
#else
#ifdef TARGET_ARCHITECTURE
  const struct bfd_arch_info * bfdarch = TARGET_ARCHITECTURE;

  if (bfdarch != NULL)
    return bfdarch->mach;
#endif /* TARGET_ARCHITECTURE */
  if (exec_bfd == NULL)
    error ("Can't find default bfd machine type (need execfile).");

  return bfd_get_mach (exec_bfd);
#endif /* 1 */
}

static enum bfd_architecture
default_gcore_arch (void)
{
#ifdef TARGET_ARCHITECTURE
  const struct bfd_arch_info * bfdarch = TARGET_ARCHITECTURE;

  if (bfdarch != NULL)
    return bfdarch->arch;
#endif
  if (exec_bfd == NULL)
    error ("Can't find bfd architecture for corefile (need execfile).");

  return bfd_get_arch (exec_bfd);
}

static char *
default_gcore_target (void)
{
  /* FIXME -- this may only work for ELF targets.  */
  if (exec_bfd == NULL)
    return NULL;
  else
    return bfd_get_target (exec_bfd);
}

/* Function: derive_stack_segment

   Derive a reasonable stack segment by unwinding the target stack. 
   
   Returns 0 for failure, 1 for success.  */

static int 
derive_stack_segment (bfd_vma *bottom, bfd_vma *top)
{
  bfd_vma tmp_vma;
  struct frame_info *fi, *tmp_fi;

  if (bottom == NULL || top == NULL)
    return 0;	/* Paranoia. */

  if (!target_has_stack || !target_has_registers)
    return 0;	/* Can't succeed without stack and registers. */

  if ((fi = get_current_frame ()) == NULL)
    return 0;	/* Can't succeed without current frame. */

  /* Save frame pointer of TOS frame. */
  *top = get_frame_base (fi);
  /* If current stack pointer is more "inner", use that instead. */
  if (INNER_THAN (read_sp (), *top))
    *top = read_sp ();

  /* Find prev-most frame. */
  while ((tmp_fi = get_prev_frame (fi)) != NULL)
    fi = tmp_fi;

  /* Save frame pointer of prev-most frame. */
  *bottom = get_frame_base (fi);

  /* Now canonicalize their order, so that 'bottom' is a lower address
   (as opposed to a lower stack frame). */
  if (*bottom > *top)
    {
      tmp_vma = *top;
      *top = *bottom;
      *bottom = tmp_vma;
    }

  return 1;	/* success */
}

/* Function: derive_heap_segment

   Derive a reasonable heap segment by looking at sbrk and
   the static data sections.
   
   Returns 0 for failure, 1 for success.  */

static int 
derive_heap_segment (bfd *abfd, bfd_vma *bottom, bfd_vma *top)
{
  bfd_vma top_of_data_memory = 0;
  bfd_vma top_of_heap = 0;
  bfd_size_type sec_size;
  struct value *zero, *sbrk;
  bfd_vma sec_vaddr;
  asection *sec;

  if (bottom == NULL || top == NULL)
    return 0;		/* Paranoia. */

  if (!target_has_execution)
    return 0;		/* This function depends on being able
			   to call a function in the inferior.  */

  /* Assumption: link map is arranged as follows (low to high addresses):
     text sections
     data sections (including bss)
     heap
  */

  for (sec = abfd->sections; sec; sec = sec->next)
    {
      if (bfd_get_section_flags (abfd, sec) & SEC_DATA ||
	  strcmp (".bss", bfd_section_name (abfd, sec)) == 0)
	{
	  sec_vaddr = bfd_get_section_vma (abfd, sec);
	  sec_size = bfd_get_section_size_before_reloc (sec);
	  if (sec_vaddr + sec_size > top_of_data_memory)
	    top_of_data_memory = sec_vaddr + sec_size;
	}
    }
  /* Now get the top-of-heap by calling sbrk in the inferior.  */
  if (lookup_minimal_symbol ("sbrk", NULL, NULL) != NULL)
    {
      if ((sbrk = find_function_in_inferior ("sbrk")) == NULL)
	return 0;
    }
  else if (lookup_minimal_symbol ("_sbrk", NULL, NULL) != NULL)
    {
      if ((sbrk = find_function_in_inferior ("_sbrk")) == NULL)
	return 0;
    }
  else
    return 0;

  if ((zero = value_from_longest (builtin_type_int, (LONGEST) 0)) == NULL)
    return 0;
  if ((sbrk = call_function_by_hand (sbrk, 1, &zero)) == NULL)
    return 0;
  top_of_heap = value_as_long (sbrk);

  /* Return results. */
  if (top_of_heap > top_of_data_memory)
    {
      *bottom = top_of_data_memory;
      *top = top_of_heap;
      return 1;	/* success */
    }
  else
    return 0;	/* No additional heap space needs to be saved. */
}

/* ARGSUSED */
static void
make_output_phdrs (bfd *obfd, asection *osec, void *ignored)
{
  int p_flags = 0;
  int p_type;

  /* FIXME: these constants may only be applicable for ELF.  */
  if (strncmp (bfd_section_name (obfd, osec), "load", 4) == 0)
    p_type = PT_LOAD;
  else
    p_type = PT_NOTE;

  p_flags |= PF_R;	/* Segment is readable.  */
  if (!(bfd_get_section_flags (obfd, osec) & SEC_READONLY))
    p_flags |= PF_W;	/* Segment is writable.  */
  if (bfd_get_section_flags (obfd, osec) & SEC_CODE)
    p_flags |= PF_X;	/* Segment is executable.  */

  bfd_record_phdr (obfd, p_type, 1, p_flags, 0, 0, 
		   0, 0, 1, &osec);
}

static asection *
make_mem_sec (bfd *obfd, 
	      bfd_vma addr, 
	      bfd_size_type size, 
	      unsigned int flags, 
	      unsigned int alignment)
{
  asection *osec;

  if ((osec = bfd_make_section_anyway (obfd, "load")) == NULL)
    {
      warning ("Couldn't make gcore segment: %s",
	       bfd_errmsg (bfd_get_error ()));
      return NULL;
    }

  if (info_verbose)
    {
      fprintf_filtered (gdb_stdout, 
			"Save segment, %lld bytes at 0x%s\n",
			(long long) size, paddr_nz (addr));
    }

  bfd_set_section_size (obfd, osec, size);
  bfd_set_section_vma (obfd, osec, addr);
  osec->lma = 0;	/* FIXME: there should be a macro for this! */
  bfd_set_section_alignment (obfd, osec, alignment);
  bfd_set_section_flags (obfd, osec, 
			 flags | SEC_LOAD | SEC_ALLOC | SEC_HAS_CONTENTS);
  return osec;
}

static int
gcore_create_callback (CORE_ADDR vaddr, 
		       unsigned long size,
		       int read, int write, int exec, 
		       void *data)
{
  flagword flags = 0;

  if (write == 0)
    {
      flags |= SEC_READONLY;
      /* Set size == zero for readonly sections. */
      size = 0;
    }
  if (exec)
    {
      flags |= SEC_CODE;
    }
  else
    {
      flags |= SEC_DATA;
    }

  return ((make_mem_sec ((bfd *) data, vaddr, size, flags, 0)) == NULL);
}

static int
objfile_find_memory_regions (int (*func) (CORE_ADDR, 
					  unsigned long,
					  int, int, int,
					   void *), 
			     void *obfd)
{
  /* Use objfile data to create memory sections. */
  struct objfile *objfile;
  struct obj_section *objsec;
  bfd_vma temp_bottom, temp_top;

  /* Call callback function for each objfile section. */
  ALL_OBJSECTIONS (objfile, objsec)
    {
      bfd *ibfd = objfile->obfd;
      asection *isec = objsec->the_bfd_section;
      flagword flags = bfd_get_section_flags (ibfd, isec);
      int ret;

      if ((flags & SEC_ALLOC) || (flags & SEC_LOAD))
	{
	  int size = bfd_section_size (ibfd, isec);
	  int ret;

	  if ((ret = (*func) (objsec->addr, 
			      bfd_section_size (ibfd, isec), 
			      1, /* All sections will be readable.  */
			      (flags & SEC_READONLY) == 0, /* writable */
			      (flags & SEC_CODE) != 0, /* executable */
			      obfd)) != 0)
	    return ret;
	}
    }

  /* Make a stack segment. */
  if (derive_stack_segment (&temp_bottom, &temp_top))
    (*func) (temp_bottom, 
	     temp_top - temp_bottom, 
	     1, /* Stack section will be readable */
	     1, /* Stack section will be writable */
	     0, /* Stack section will not be executable */
	     obfd);

  /* Make a heap segment. */
  if (derive_heap_segment (exec_bfd, &temp_bottom, &temp_top))
    (*func) (temp_bottom, 
	     temp_top - temp_bottom, 
	     1, /* Heap section will be readable */
	     1, /* Heap section will be writable */
	     0, /* Heap section will not be executable */
	     obfd);
  return 0;
}

static void
gcore_copy_callback (bfd *obfd, asection *osec, void *ignored)
{
  bfd_size_type size = bfd_section_size (obfd, osec);
  struct cleanup *old_chain = NULL;
  void *memhunk;

  if (size == 0)
    return;	/* Read-only sections are marked as zero-size.
		   We don't have to copy their contents. */
  if (strncmp ("load", bfd_section_name (obfd, osec), 4) != 0)
    return;	/* Only interested in "load" sections. */

  if ((memhunk = xmalloc (size)) == NULL)
    error ("Not enough memory to create corefile.");
  old_chain = make_cleanup (xfree, memhunk);

  if (target_read_memory (bfd_section_vma (obfd, osec), 
			  memhunk, size) != 0)
    warning ("Memory read failed for corefile section, %ld bytes at 0x%s\n",
	     (long) size, paddr (bfd_section_vma (obfd, osec)));
  if (!bfd_set_section_contents (obfd, osec, memhunk, 0, size))
    warning ("Failed to write corefile contents (%s).", 
	     bfd_errmsg (bfd_get_error ()));

  do_cleanups (old_chain);	/* frees the xmalloc buffer */
}

static int
gcore_memory_sections (bfd *obfd)
{
  if (target_find_memory_regions (gcore_create_callback, obfd) != 0)
    return 0;	/* FIXME error return/msg? */

  /* Record phdrs for section-to-segment mapping. */
  bfd_map_over_sections (obfd, make_output_phdrs, NULL);

  /* Copy memory region contents. */
  bfd_map_over_sections (obfd, gcore_copy_callback, NULL);

  return 1;	/* success */
}

void
_initialize_gcore (void)
{
  add_com ("generate-core-file", class_files, gcore_command,
	   "Save a core file with the current state of the debugged process.\n\
Argument is optional filename.  Default filename is 'core.<process_id>'.");

  add_com_alias ("gcore", "generate-core-file", class_files, 1);
  exec_set_find_memory_regions (objfile_find_memory_regions);
}
