/* BSD Kernel Data Access Library (libkvm) interface.

   Copyright (C) 2004-2021 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/>.  */

#define _KMEMUSER
#include "defs.h"
#include "cli/cli-cmds.h"
#include "command.h"
#include "frame.h"
#include "regcache.h"
#include "target.h"
#include "process-stratum-target.h"
#include "value.h"
#include "gdbcore.h"
#include "inferior.h"          /* for get_exec_file */
#include "gdbthread.h"
#include "gdbsupport/pathstuff.h"

#include <fcntl.h>
#include <kvm.h>
#ifdef HAVE_NLIST_H
#include <nlist.h>
#endif
#include <paths.h>
#include "readline/readline.h"
#include <sys/param.h>
#include <sys/proc.h>
#ifdef HAVE_SYS_USER_H
#include <sys/user.h>
#endif

#include "bsd-kvm.h"

/* Kernel memory device file.  */
static const char *bsd_kvm_corefile;

/* Kernel memory interface descriptor.  */
static kvm_t *core_kd;

/* Address of process control block.  */
static struct pcb *bsd_kvm_paddr;

/* Pointer to architecture-specific function that reconstructs the
   register state from PCB and supplies it to REGCACHE.  */
static int (*bsd_kvm_supply_pcb)(struct regcache *regcache, struct pcb *pcb);

/* This is the ptid we use while we're connected to kvm.  The kvm
   target currently doesn't export any view of the running processes,
   so this represents the kernel task.  */
static ptid_t bsd_kvm_ptid;

/* The libkvm target.  */

static const target_info bsd_kvm_target_info = {
  "kvm",
  N_("Kernel memory interface"),
  N_("Use a kernel virtual memory image as a target.\n\
Optionally specify the filename of a core dump.")
};

class bsd_kvm_target final : public process_stratum_target
{
public:
  bsd_kvm_target () = default;

  const target_info &info () const override
  { return bsd_kvm_target_info; }

  void close () override;

  void fetch_registers (struct regcache *, int) override;
  enum target_xfer_status xfer_partial (enum target_object object,
					const char *annex,
					gdb_byte *readbuf,
					const gdb_byte *writebuf,
					ULONGEST offset, ULONGEST len,
					ULONGEST *xfered_len) override;

  void files_info () override;
  bool thread_alive (ptid_t ptid) override;
  std::string pid_to_str (ptid_t) override;

  bool has_memory () override { return true; }
  bool has_stack () override { return true; }
  bool has_registers () override { return true; }
};

/* Target ops for libkvm interface.  */
static bsd_kvm_target bsd_kvm_ops;

static void
bsd_kvm_target_open (const char *arg, int from_tty)
{
  char errbuf[_POSIX2_LINE_MAX];
  const char *execfile = NULL;
  kvm_t *temp_kd;
  char *filename = NULL;

  target_preopen (from_tty);

  if (arg)
    {
      filename = tilde_expand (arg);
      if (filename[0] != '/')
	{
	  gdb::unique_xmalloc_ptr<char> temp (gdb_abspath (filename));

	  xfree (filename);
	  filename = temp.release ();
	}
    }

  execfile = get_exec_file (0);
  temp_kd = kvm_openfiles (execfile, filename, NULL,
			   write_files ? O_RDWR : O_RDONLY, errbuf);
  if (temp_kd == NULL)
    error (("%s"), errbuf);

  bsd_kvm_corefile = filename;
  current_inferior ()->unpush_target (&bsd_kvm_ops);
  core_kd = temp_kd;
  current_inferior ()->push_target (&bsd_kvm_ops);

  thread_info *thr = add_thread_silent (&bsd_kvm_ops, bsd_kvm_ptid);
  switch_to_thread (thr);

  target_fetch_registers (get_current_regcache (), -1);

  reinit_frame_cache ();
  print_stack_frame (get_selected_frame (NULL), 0, SRC_AND_LOC, 1);
}

void
bsd_kvm_target::close ()
{
  if (core_kd)
    {
      if (kvm_close (core_kd) == -1)
	warning (("%s"), kvm_geterr(core_kd));
      core_kd = NULL;
    }

  switch_to_no_thread ();
  exit_inferior_silent (current_inferior ());
}

static LONGEST
bsd_kvm_xfer_memory (CORE_ADDR addr, ULONGEST len,
		     gdb_byte *readbuf, const gdb_byte *writebuf)
{
  ssize_t nbytes = len;

  if (readbuf)
    nbytes = kvm_read (core_kd, addr, readbuf, nbytes);
  if (writebuf && nbytes > 0)
    nbytes = kvm_write (core_kd, addr, writebuf, nbytes);
  return nbytes;
}

enum target_xfer_status
bsd_kvm_target::xfer_partial (enum target_object object,
			      const char *annex, gdb_byte *readbuf,
			      const gdb_byte *writebuf,
			      ULONGEST offset, ULONGEST len, ULONGEST *xfered_len)
{
  switch (object)
    {
    case TARGET_OBJECT_MEMORY:
      {
	LONGEST ret = bsd_kvm_xfer_memory (offset, len, readbuf, writebuf);

	if (ret < 0)
	  return TARGET_XFER_E_IO;
	else if (ret == 0)
	  return TARGET_XFER_EOF;
	else
	  {
	    *xfered_len = (ULONGEST) ret;
	    return TARGET_XFER_OK;
	  }
      }

    default:
      return TARGET_XFER_E_IO;
    }
}

void
bsd_kvm_target::files_info ()
{
  if (bsd_kvm_corefile && strcmp (bsd_kvm_corefile, _PATH_MEM) != 0)
    printf_filtered (_("\tUsing the kernel crash dump %s.\n"),
		     bsd_kvm_corefile);
  else
    printf_filtered (_("\tUsing the currently running kernel.\n"));
}

/* Fetch process control block at address PADDR.  */

static int
bsd_kvm_fetch_pcb (struct regcache *regcache, struct pcb *paddr)
{
  struct pcb pcb;

  if (kvm_read (core_kd, (unsigned long) paddr, &pcb, sizeof pcb) == -1)
    error (("%s"), kvm_geterr (core_kd));

  gdb_assert (bsd_kvm_supply_pcb);
  return bsd_kvm_supply_pcb (regcache, &pcb);
}

void
bsd_kvm_target::fetch_registers (struct regcache *regcache, int regnum)
{
  struct nlist nl[2];

  if (bsd_kvm_paddr)
    {
      bsd_kvm_fetch_pcb (regcache, bsd_kvm_paddr);
      return;
    }

  /* On dumping core, BSD kernels store the faulting context (PCB)
     in the variable "dumppcb".  */
  memset (nl, 0, sizeof nl);
  nl[0].n_name = (char *) "_dumppcb";

  if (kvm_nlist (core_kd, nl) == -1)
    error (("%s"), kvm_geterr (core_kd));

  if (nl[0].n_value != 0)
    {
      /* Found dumppcb.  If it contains a valid context, return
	 immediately.  */
      if (bsd_kvm_fetch_pcb (regcache, (struct pcb *) nl[0].n_value))
	return;
    }

  /* Traditional BSD kernels have a process proc0 that should always
     be present.  The address of proc0's PCB is stored in the variable
     "proc0paddr".  */

  memset (nl, 0, sizeof nl);
  nl[0].n_name = (char *) "_proc0paddr";

  if (kvm_nlist (core_kd, nl) == -1)
    error (("%s"), kvm_geterr (core_kd));

  if (nl[0].n_value != 0)
    {
      struct pcb *paddr;

      /* Found proc0paddr.  */
      if (kvm_read (core_kd, nl[0].n_value, &paddr, sizeof paddr) == -1)
	error (("%s"), kvm_geterr (core_kd));

      bsd_kvm_fetch_pcb (regcache, paddr);
      return;
    }

#ifdef HAVE_STRUCT_THREAD_TD_PCB
  /* In FreeBSD kernels for 5.0-RELEASE and later, the PCB no longer
     lives in `struct proc' but in `struct thread'.  The `struct
     thread' for the initial thread for proc0 can be found in the
     variable "thread0".  */

  memset (nl, 0, sizeof nl);
  nl[0].n_name = (char *) "_thread0";

  if (kvm_nlist (core_kd, nl) == -1)
    error (("%s"), kvm_geterr (core_kd));

  if (nl[0].n_value != 0)
    {
      struct pcb *paddr;

      /* Found thread0.  */
      nl[0].n_value += offsetof (struct thread, td_pcb);
      if (kvm_read (core_kd, nl[0].n_value, &paddr, sizeof paddr) == -1)
	error (("%s"), kvm_geterr (core_kd));

      bsd_kvm_fetch_pcb (regcache, paddr);
      return;
    }
#endif

  /* i18n: PCB == "Process Control Block".  */
  error (_("Cannot find a valid PCB"));
}


/* Kernel memory interface commands.  */
struct cmd_list_element *bsd_kvm_cmdlist;

static void
bsd_kvm_cmd (const char *arg, int fromtty)
{
  /* ??? Should this become an alias for "target kvm"?  */
}

#ifndef HAVE_STRUCT_THREAD_TD_PCB

static void
bsd_kvm_proc_cmd (const char *arg, int fromtty)
{
  CORE_ADDR addr;

  if (arg == NULL)
    error_no_arg (_("proc address"));

  if (core_kd == NULL)
    error (_("No kernel memory image."));

  addr = parse_and_eval_address (arg);
#ifdef HAVE_STRUCT_LWP
  addr += offsetof (struct lwp, l_addr);
#else
  addr += offsetof (struct proc, p_addr);
#endif

  if (kvm_read (core_kd, addr, &bsd_kvm_paddr, sizeof bsd_kvm_paddr) == -1)
    error (("%s"), kvm_geterr (core_kd));

  target_fetch_registers (get_current_regcache (), -1);

  reinit_frame_cache ();
  print_stack_frame (get_selected_frame (NULL), 0, SRC_AND_LOC, 1);
}

#endif

static void
bsd_kvm_pcb_cmd (const char *arg, int fromtty)
{
  if (arg == NULL)
    /* i18n: PCB == "Process Control Block".  */
    error_no_arg (_("pcb address"));

  if (core_kd == NULL)
    error (_("No kernel memory image."));

  bsd_kvm_paddr = (struct pcb *)(u_long) parse_and_eval_address (arg);

  target_fetch_registers (get_current_regcache (), -1);

  reinit_frame_cache ();
  print_stack_frame (get_selected_frame (NULL), 0, SRC_AND_LOC, 1);
}

bool
bsd_kvm_target::thread_alive (ptid_t ptid)
{
  return true;
}

std::string
bsd_kvm_target::pid_to_str (ptid_t ptid)
{
  return "<kvm>";
}

/* Add the libkvm interface to the list of all possible targets and
   register CUPPLY_PCB as the architecture-specific process control
   block interpreter.  */

void
bsd_kvm_add_target (int (*supply_pcb)(struct regcache *, struct pcb *))
{
  gdb_assert (bsd_kvm_supply_pcb == NULL);
  bsd_kvm_supply_pcb = supply_pcb;

  add_target (bsd_kvm_target_info, bsd_kvm_target_open);
  
  add_prefix_cmd ("kvm", class_obscure, bsd_kvm_cmd, _("\
Generic command for manipulating the kernel memory interface."),
		  &bsd_kvm_cmdlist, 0, &cmdlist);

#ifndef HAVE_STRUCT_THREAD_TD_PCB
  add_cmd ("proc", class_obscure, bsd_kvm_proc_cmd,
	   _("Set current context from proc address"), &bsd_kvm_cmdlist);
#endif
  add_cmd ("pcb", class_obscure, bsd_kvm_pcb_cmd,
	   /* i18n: PCB == "Process Control Block".  */
	   _("Set current context from pcb address"), &bsd_kvm_cmdlist);

  /* Some notes on the ptid usage on this target.

     The pid field represents the kvm inferior instance.  Currently,
     we don't support multiple kvm inferiors, but we start at 1
     anyway.  The lwp field is set to != 0, in case the core wants to
     refer to the whole kvm inferior with ptid(1,0,0).

     If kvm is made to export running processes as gdb threads,
     the following form can be used:
     ptid (1, 1, 0) -> kvm inferior 1, in kernel
     ptid (1, 1, 1) -> kvm inferior 1, process 1
     ptid (1, 1, 2) -> kvm inferior 1, process 2
     ptid (1, 1, n) -> kvm inferior 1, process n  */

  bsd_kvm_ptid = ptid_t (1, 1, 0);
}
