/* BFD back-end for HP/UX core files.
   Copyright 1993, 1994, 1996, 1998, 1999, 2001, 2002, 2003, 2004, 2005, 2006,
   2007, 2008, 2010, 2011, 2012  Free Software Foundation, Inc.
   Written by Stu Grossman, Cygnus Support.
   Converted to back-end form by Ian Lance Taylor, Cygnus SUpport

   This file is part of BFD, the Binary File Descriptor library.

   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, write to the Free Software
   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
   MA 02110-1301, USA.  */


/* This file can only be compiled on systems which use HP/UX style
   core files.  */

#include "sysdep.h"
#include "bfd.h"
#include "libbfd.h"

#if defined (HOST_HPPAHPUX) || defined (HOST_HP300HPUX) || defined (HOST_HPPAMPEIX)

/* FIXME: sys/core.h doesn't exist for HPUX version 7.  HPUX version
   5, 6, and 7 core files seem to be standard trad-core.c type core
   files; can we just use trad-core.c in addition to this file?  */

#include <sys/core.h>
#include <sys/utsname.h>

#endif /* HOST_HPPAHPUX */

#ifdef HOST_HPPABSD

/* Not a very swift place to put it, but that's where the BSD port
   puts them.  */
#include "/hpux/usr/include/sys/core.h"

#endif /* HOST_HPPABSD */

#include <sys/param.h>
#ifdef HAVE_DIRENT_H
# include <dirent.h>
#else
# ifdef HAVE_SYS_NDIR_H
#  include <sys/ndir.h>
# endif
# ifdef HAVE_SYS_DIR_H
#  include <sys/dir.h>
# endif
# ifdef HAVE_NDIR_H
#  include <ndir.h>
# endif
#endif
#include <signal.h>
#ifdef HPUX_CORE
#include <machine/reg.h>
#endif
#include <sys/file.h>

/* Kludge: There's no explicit mechanism provided by sys/core.h to
   conditionally know whether a proc_info has thread id fields.
   However, CORE_ANON_SHMEM shows up first at 10.30, which is
   happily also when meaningful thread id's show up in proc_info. */
#if defined(CORE_ANON_SHMEM)
#define PROC_INFO_HAS_THREAD_ID (1)
#endif

/* This type appears at HP-UX 10.30.  Defining it if not defined
   by sys/core.h allows us to build for older HP-UX's, and (since
   it won't be encountered in core-dumps from older HP-UX's) is
   harmless. */
#if !defined(CORE_ANON_SHMEM)
#define CORE_ANON_SHMEM 0x00000200         /* anonymous shared memory */
#endif

/* These are stored in the bfd's tdata */

/* .lwpid and .user_tid are only valid if PROC_INFO_HAS_THREAD_ID, else they
   are set to 0.  Also, until HP-UX implements MxN threads, .user_tid and
   .lwpid are synonymous. */
struct hpux_core_struct
{
  int sig;
  int lwpid;               /* Kernel thread ID. */
  unsigned long user_tid;  /* User thread ID. */
  char cmd[MAXCOMLEN + 1];
};

#define core_hdr(bfd) ((bfd)->tdata.hpux_core_data)
#define core_signal(bfd) (core_hdr(bfd)->sig)
#define core_command(bfd) (core_hdr(bfd)->cmd)
#define core_kernel_thread_id(bfd) (core_hdr(bfd)->lwpid)
#define core_user_thread_id(bfd) (core_hdr(bfd)->user_tid)
#define hpux_core_core_file_matches_executable_p generic_core_file_matches_executable_p
#define hpux_core_core_file_pid _bfd_nocore_core_file_pid

static asection *make_bfd_asection (bfd *, const char *, flagword,
                                    bfd_size_type, bfd_vma, unsigned int);
static const bfd_target *hpux_core_core_file_p (bfd *);
static char *hpux_core_core_file_failing_command (bfd *);
static int hpux_core_core_file_failing_signal (bfd *);
static void swap_abort (void);

static asection *
make_bfd_asection (bfd *abfd, const char *name, flagword flags,
                   bfd_size_type size, bfd_vma vma,
                   unsigned int alignment_power)
{
  asection *asect;
  char *newname;

  newname = bfd_alloc (abfd, (bfd_size_type) strlen (name) + 1);
  if (!newname)
    return NULL;

  strcpy (newname, name);

  asect = bfd_make_section_anyway_with_flags (abfd, newname, flags);
  if (!asect)
    return NULL;

  asect->size = size;
  asect->vma = vma;
  asect->filepos = bfd_tell (abfd);
  asect->alignment_power = alignment_power;

  return asect;
}

/* Return true if the given core file section corresponds to a thread,
   based on its name.  */

static int
thread_section_p (bfd *abfd ATTRIBUTE_UNUSED,
                  asection *sect,
                  void *obj ATTRIBUTE_UNUSED)
{
  return CONST_STRNEQ (sect->name, ".reg/");
}

/* this function builds a bfd target if the file is a corefile.
   It returns null or 0 if it finds out thaat it is not a core file.
   The way it checks this is by looking for allowed 'type' field values.
   These are declared in sys/core.h
   There are some values which are 'reserved for future use'. In particular
   CORE_NONE is actually defined as 0. This may be a catch-all for cases
   in which the core file is generated by some non-hpux application.
   (I am just guessing here!)
*/
static const bfd_target *
hpux_core_core_file_p (bfd *abfd)
{
  int  good_sections = 0;
  int  unknown_sections = 0;

  core_hdr (abfd) = (struct hpux_core_struct *)
    bfd_zalloc (abfd, (bfd_size_type) sizeof (struct hpux_core_struct));
  if (!core_hdr (abfd))
    return NULL;

  while (1)
    {
      int val;
      struct corehead core_header;

      val = bfd_bread ((void *) &core_header,
		      (bfd_size_type) sizeof core_header, abfd);
      if (val <= 0)
	break;
      switch (core_header.type)
	{
	case CORE_KERNEL:
	case CORE_FORMAT:
	  /* Just skip this.  */
	  bfd_seek (abfd, (file_ptr) core_header.len, SEEK_CUR);
          good_sections++;
	  break;
	case CORE_EXEC:
	  {
	    struct proc_exec proc_exec;
	    if (bfd_bread ((void *) &proc_exec, (bfd_size_type) core_header.len,
			  abfd) != core_header.len)
	      break;
	    strncpy (core_command (abfd), proc_exec.cmd, MAXCOMLEN + 1);
            good_sections++;
	  }
	  break;
	case CORE_PROC:
	  {
	    struct proc_info proc_info;
	    char  secname[100];  /* Of arbitrary size, but plenty large. */

            /* We need to read this section, 'cause we need to determine
               whether the core-dumped app was threaded before we create
               any .reg sections. */
	    if (bfd_bread (&proc_info, (bfd_size_type) core_header.len, abfd)
		!= core_header.len)
	      break;

              /* However, we also want to create those sections with the
                 file positioned at the start of the record, it seems. */
            if (bfd_seek (abfd, -((file_ptr) core_header.len), SEEK_CUR) != 0)
              break;

#if defined(PROC_INFO_HAS_THREAD_ID)
            core_kernel_thread_id (abfd) = proc_info.lwpid;
            core_user_thread_id (abfd) = proc_info.user_tid;
#else
            core_kernel_thread_id (abfd) = 0;
            core_user_thread_id (abfd) = 0;
#endif
            /* If the program was unthreaded, then we'll just create a
               .reg section.

               If the program was threaded, then we'll create .reg/XXXXX
               section for each thread, where XXXXX is a printable
               representation of the kernel thread id.  We'll also
               create a .reg section for the thread that was running
               and signalled at the time of the core-dump (i.e., this
               is effectively an alias, needed to keep GDB happy.)

               Note that we use `.reg/XXXXX' as opposed to '.regXXXXX'
               because GDB expects that .reg2 will be the floating-
               point registers. */
            if (core_kernel_thread_id (abfd) == 0)
              {
                if (!make_bfd_asection (abfd, ".reg",
					SEC_HAS_CONTENTS,
					core_header.len,
					(bfd_vma) offsetof (struct proc_info,
							    hw_regs),
					2))
		  goto fail;
              }
            else
              {
                /* There are threads.  Is this the one that caused the
                   core-dump?  We'll claim it was the running thread. */
                if (proc_info.sig != -1)
                  {
		    if (!make_bfd_asection (abfd, ".reg",
					    SEC_HAS_CONTENTS,
					    core_header.len,
					    (bfd_vma)offsetof (struct proc_info,
							       hw_regs),
					    2))
		      goto fail;
                  }
                /* We always make one of these sections, for every thread. */
                sprintf (secname, ".reg/%d", core_kernel_thread_id (abfd));
                if (!make_bfd_asection (abfd, secname,
					SEC_HAS_CONTENTS,
					core_header.len,
					(bfd_vma) offsetof (struct proc_info,
							    hw_regs),
					2))
		  goto fail;
              }
	    core_signal (abfd) = proc_info.sig;
            if (bfd_seek (abfd, (file_ptr) core_header.len, SEEK_CUR) != 0)
              break;
            good_sections++;
	  }
	  break;

	case CORE_DATA:
	case CORE_STACK:
	case CORE_TEXT:
	case CORE_MMF:
	case CORE_SHM:
	case CORE_ANON_SHMEM:
	  if (!make_bfd_asection (abfd, ".data",
				  SEC_ALLOC + SEC_LOAD + SEC_HAS_CONTENTS,
				  core_header.len,
				  (bfd_vma) core_header.addr, 2))
	    goto fail;

	  bfd_seek (abfd, (file_ptr) core_header.len, SEEK_CUR);
          good_sections++;
	  break;

	case CORE_NONE:
          /* Let's not punt if we encounter a section of unknown
             type.  Rather, let's make a note of it.  If we later
             see that there were also "good" sections, then we'll
             declare that this a core file, but we'll also warn that
             it may be incompatible with this gdb.
             */
	  unknown_sections++;
          break;

         default:
	   goto fail; /*unrecognized core file type */
	}
    }

  /* OK, we believe you.  You're a core file (sure, sure).  */

  /* On HP/UX, we sometimes encounter core files where none of the threads
     was found to be the running thread (ie the signal was set to -1 for
     all threads).  This happens when the program was aborted externally
     via a TT_CORE ttrace system call.  In that case, we just pick one
     thread at random to be the active thread.  */
  if (core_kernel_thread_id (abfd) != 0
      && bfd_get_section_by_name (abfd, ".reg") == NULL)
    {
      asection *asect = bfd_sections_find_if (abfd, thread_section_p, NULL);
      asection *reg_sect;

      if (asect != NULL)
        {
          reg_sect = make_bfd_asection (abfd, ".reg", asect->flags,
                                        asect->size, asect->vma,
                                        asect->alignment_power);
          if (reg_sect == NULL)
            goto fail;

          reg_sect->filepos = asect->filepos;
        }
    }

  /* Were there sections of unknown type?  If so, yet there were
     at least some complete sections of known type, then, issue
     a warning.  Possibly the core file was generated on a version
     of HP-UX that is incompatible with that for which this gdb was
     built.
     */
  if ((unknown_sections > 0) && (good_sections > 0))
    (*_bfd_error_handler)
      ("%s appears to be a core file,\nbut contains unknown sections.  It may have been created on an incompatible\nversion of HP-UX.  As a result, some information may be unavailable.\n",
       abfd->filename);

  return abfd->xvec;

 fail:
  bfd_release (abfd, core_hdr (abfd));
  core_hdr (abfd) = NULL;
  bfd_section_list_clear (abfd);
  return NULL;
}

static char *
hpux_core_core_file_failing_command (bfd *abfd)
{
  return core_command (abfd);
}

static int
hpux_core_core_file_failing_signal (bfd *abfd)
{
  return core_signal (abfd);
}


/* If somebody calls any byte-swapping routines, shoot them.  */
static void
swap_abort (void)
{
  abort(); /* This way doesn't require any declaration for ANSI to fuck up */
}

#define	NO_GET ((bfd_vma (*) (const void *)) swap_abort)
#define	NO_PUT ((void (*) (bfd_vma, void *)) swap_abort)
#define	NO_GETS ((bfd_signed_vma (*) (const void *)) swap_abort)
#define	NO_GET64 ((bfd_uint64_t (*) (const void *)) swap_abort)
#define	NO_PUT64 ((void (*) (bfd_uint64_t, void *)) swap_abort)
#define	NO_GETS64 ((bfd_int64_t (*) (const void *)) swap_abort)

const bfd_target hpux_core_vec =
  {
    "hpux-core",
    bfd_target_unknown_flavour,
    BFD_ENDIAN_BIG,		/* target byte order */
    BFD_ENDIAN_BIG,		/* target headers byte order */
    (HAS_RELOC | EXEC_P |	/* object flags */
     HAS_LINENO | HAS_DEBUG |
     HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED),
    (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
    0,				/* symbol prefix */
    ' ',			/* ar_pad_char */
    16,				/* ar_max_namelen */
    0,				/* match priority.  */
    NO_GET64, NO_GETS64, NO_PUT64,	/* 64 bit data */
    NO_GET, NO_GETS, NO_PUT,		/* 32 bit data */
    NO_GET, NO_GETS, NO_PUT,		/* 16 bit data */
    NO_GET64, NO_GETS64, NO_PUT64,	/* 64 bit hdrs */
    NO_GET, NO_GETS, NO_PUT,		/* 32 bit hdrs */
    NO_GET, NO_GETS, NO_PUT,		/* 16 bit hdrs */

    {				/* bfd_check_format */
      _bfd_dummy_target,		/* unknown format */
      _bfd_dummy_target,		/* object file */
      _bfd_dummy_target,		/* archive */
      hpux_core_core_file_p		/* a core file */
    },
    {				/* bfd_set_format */
      bfd_false, bfd_false,
      bfd_false, bfd_false
    },
    {				/* bfd_write_contents */
      bfd_false, bfd_false,
      bfd_false, bfd_false
    },

    BFD_JUMP_TABLE_GENERIC (_bfd_generic),
    BFD_JUMP_TABLE_COPY (_bfd_generic),
    BFD_JUMP_TABLE_CORE (hpux_core),
    BFD_JUMP_TABLE_ARCHIVE (_bfd_noarchive),
    BFD_JUMP_TABLE_SYMBOLS (_bfd_nosymbols),
    BFD_JUMP_TABLE_RELOCS (_bfd_norelocs),
    BFD_JUMP_TABLE_WRITE (_bfd_generic),
    BFD_JUMP_TABLE_LINK (_bfd_nolink),
    BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),

    NULL,

    NULL			/* backend_data */
  };
