/* Generate a core file for the inferior process.
   Copyright 2001, 2002 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 = fi->frame;
  /* 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 = fi->frame;

  /* 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);
}
