/* BFD backend for core files which use the ptrace_user structure
   Copyright (C) 1993-2021 Free Software Foundation, Inc.
   The structure of this file is based on trad-core.c written by John Gilmore
   of Cygnus Support.
   Modified to work with the ptrace_user structure by Kevin A. Buettner.
   (Longterm it may be better to merge this file with trad-core.c)

   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.  */

#ifdef PTRACE_CORE

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

#include <sys/param.h>
#include <sys/dir.h>
#include <signal.h>
#include <sys/ptrace.h>

struct trad_core_struct
{
  asection *data_section;
  asection *stack_section;
  asection *reg_section;
  struct ptrace_user u;
};

#define core_upage(bfd)  (&((bfd)->tdata.trad_core_data->u))
#define core_datasec(bfd)  ((bfd)->tdata.trad_core_data->data_section)
#define core_stacksec(bfd) ((bfd)->tdata.trad_core_data->stack_section)
#define core_regsec(bfd)   ((bfd)->tdata.trad_core_data->reg_section)

/* forward declarations */

const bfd_target *ptrace_unix_core_file_p (bfd *abfd);
char * ptrace_unix_core_file_failing_command (bfd *abfd);
int ptrace_unix_core_file_failing_signal (bfd *abfd);
#define ptrace_unix_core_file_matches_executable_p generic_core_file_matches_executable_p
#define ptrace_unix_core_file_pid _bfd_nocore_core_file_pid
static void swap_abort (void);

bfd_cleanup
ptrace_unix_core_file_p (bfd *abfd)
{
  int val;
  struct ptrace_user u;
  struct trad_core_struct *rawptr;
  size_t amt;
  flagword flags;

  val = bfd_bread ((void *)&u, (bfd_size_type) sizeof u, abfd);
  if (val != sizeof u || u.pt_magic != _BCS_PTRACE_MAGIC
      || u.pt_rev != _BCS_PTRACE_REV)
    {
      /* Too small to be a core file */
      bfd_set_error (bfd_error_wrong_format);
      return 0;
    }

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

  /* Allocate both the upage and the struct core_data at once, so
     a single free() will free them both.  */
  amt = sizeof (struct trad_core_struct);
  rawptr = (struct trad_core_struct *) bfd_zalloc (abfd, amt);

  if (rawptr == NULL)
    return 0;

  abfd->tdata.trad_core_data = rawptr;

  rawptr->u = u; /*Copy the uarea into the tdata part of the bfd */

  /* Create the sections.  */

  flags = SEC_ALLOC + SEC_LOAD + SEC_HAS_CONTENTS;
  core_stacksec (abfd) = bfd_make_section_anyway_with_flags (abfd, ".stack",
							     flags);
  if (core_stacksec (abfd) == NULL)
    goto fail;
  core_datasec (abfd) = bfd_make_section_anyway_with_flags (abfd, ".data",
							    flags);
  if (core_datasec (abfd) == NULL)
    goto fail;
  core_regsec (abfd) = bfd_make_section_anyway_with_flags (abfd, ".reg",
							   SEC_HAS_CONTENTS);
  if (core_regsec (abfd) == NULL)
    goto fail;

  /* FIXME:  Need to worry about shared memory, library data, and library
     text.  I don't think that any of these things are supported on the
     system on which I am developing this for though.  */

  core_datasec (abfd)->size =  u.pt_dsize;
  core_stacksec (abfd)->size = u.pt_ssize;
  core_regsec (abfd)->size = sizeof (u);

  core_datasec (abfd)->vma = u.pt_o_data_start;
  core_stacksec (abfd)->vma = USRSTACK - u.pt_ssize;
  core_regsec (abfd)->vma = 0 - sizeof (u);	/* see trad-core.c */

  core_datasec (abfd)->filepos = (int) u.pt_dataptr;
  core_stacksec (abfd)->filepos = (int) (u.pt_dataptr + u.pt_dsize);
  core_regsec (abfd)->filepos = 0; /* Register segment is ptrace_user */

  /* Align to word at least */
  core_stacksec (abfd)->alignment_power = 2;
  core_datasec (abfd)->alignment_power = 2;
  core_regsec (abfd)->alignment_power = 2;

  return _bfd_no_cleanup;

 fail:
  bfd_release (abfd, abfd->tdata.any);
  abfd->tdata.any = NULL;
  bfd_section_list_clear (abfd);
  return NULL;
}

char *
ptrace_unix_core_file_failing_command (bfd *abfd)
{
  char *com = abfd->tdata.trad_core_data->u.pt_comm;

  if (*com)
    return com;
  else
    return 0;
}

int
ptrace_unix_core_file_failing_signal (bfd *abfd)
{
  return abfd->tdata.trad_core_data->u.pt_sigframe.sig_num;
}

/* 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 core_ptrace_vec =
  {
    "trad-core",
    bfd_target_unknown_flavour,
    BFD_ENDIAN_UNKNOWN,		/* target byte order */
    BFD_ENDIAN_UNKNOWN,		/* 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 */
    TARGET_KEEP_UNUSED_SECTION_SYMBOLS, /* keep unused section symbols.  */
    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 */
      ptrace_unix_core_file_p		/* a core file */
    },
    {				/* bfd_set_format */
      _bfd_bool_bfd_false_error, bfd_false,
      _bfd_bool_bfd_false_error, bfd_false
    },
    {				/* bfd_write_contents */
      _bfd_bool_bfd_false_error, bfd_false,
      _bfd_bool_bfd_false_error, bfd_false
    },

    BFD_JUMP_TABLE_GENERIC (_bfd_generic),
    BFD_JUMP_TABLE_COPY (_bfd_generic),
    BFD_JUMP_TABLE_CORE (ptrace_unix),
    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 */
  };

#endif /* PTRACE_CORE */
