/* Core dump and executable file functions below target vector, for GDB.

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

#include "defs.h"
#include "arch-utils.h"
#include <signal.h>
#include <fcntl.h>
#include "frame.h"		/* required by inferior.h */
#include "inferior.h"
#include "infrun.h"
#include "symtab.h"
#include "command.h"
#include "bfd.h"
#include "target.h"
#include "process-stratum-target.h"
#include "gdbcore.h"
#include "gdbthread.h"
#include "regcache.h"
#include "regset.h"
#include "symfile.h"
#include "exec.h"
#include "readline/tilde.h"
#include "solib.h"
#include "solist.h"
#include "filenames.h"
#include "progspace.h"
#include "objfiles.h"
#include "gdb_bfd.h"
#include "completer.h"
#include "gdbsupport/filestuff.h"
#include "build-id.h"
#include "gdbsupport/pathstuff.h"
#include <unordered_map>
#include <unordered_set>
#include "gdbcmd.h"
#include "xml-tdesc.h"

#ifndef O_LARGEFILE
#define O_LARGEFILE 0
#endif

/* The core file target.  */

static const target_info core_target_info = {
  "core",
  N_("Local core dump file"),
  N_("Use a core file as a target.\n\
Specify the filename of the core file.")
};

class core_target final : public process_stratum_target
{
public:
  core_target ();

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

  void close () override;
  void detach (inferior *, int) 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;
  const struct target_desc *read_description () override;

  std::string pid_to_str (ptid_t) override;

  const char *thread_name (struct thread_info *) override;

  bool has_all_memory () override { return true; }
  bool has_memory () override;
  bool has_stack () override;
  bool has_registers () override;
  bool has_execution (inferior *inf) override { return false; }

  bool info_proc (const char *, enum info_proc_what) override;

  /* A few helpers.  */

  /* Getter, see variable definition.  */
  struct gdbarch *core_gdbarch ()
  {
    return m_core_gdbarch;
  }

  /* See definition.  */
  void get_core_register_section (struct regcache *regcache,
				  const struct regset *regset,
				  const char *name,
				  int section_min_size,
				  const char *human_name,
				  bool required);

  /* See definition.  */
  void info_proc_mappings (struct gdbarch *gdbarch);

private: /* per-core data */

  /* The core's section table.  Note that these target sections are
     *not* mapped in the current address spaces' set of target
     sections --- those should come only from pure executable or
     shared library bfds.  The core bfd sections are an implementation
     detail of the core target, just like ptrace is for unix child
     targets.  */
  target_section_table m_core_section_table;

  /* File-backed address space mappings: some core files include
     information about memory mapped files.  */
  target_section_table m_core_file_mappings;

  /* Unavailable mappings.  These correspond to pathnames which either
     weren't found or could not be opened.  Knowing these addresses can
     still be useful.  */
  std::vector<mem_range> m_core_unavailable_mappings;

  /* Build m_core_file_mappings.  Called from the constructor.  */
  void build_file_mappings ();

  /* Helper method for xfer_partial.  */
  enum target_xfer_status xfer_memory_via_mappings (gdb_byte *readbuf,
						    const gdb_byte *writebuf,
						    ULONGEST offset,
						    ULONGEST len,
						    ULONGEST *xfered_len);

  /* FIXME: kettenis/20031023: Eventually this field should
     disappear.  */
  struct gdbarch *m_core_gdbarch = NULL;
};

core_target::core_target ()
{
  /* Find a first arch based on the BFD.  We need the initial gdbarch so
     we can setup the hooks to find a target description.  */
  m_core_gdbarch = gdbarch_from_bfd (core_bfd);

  /* If the arch is able to read a target description from the core, it
     could yield a more specific gdbarch.  */
  const struct target_desc *tdesc = read_description ();

  if (tdesc != nullptr)
    {
      struct gdbarch_info info;
      info.abfd = core_bfd;
      info.target_desc = tdesc;
      m_core_gdbarch = gdbarch_find_by_info (info);
    }

  if (!m_core_gdbarch
      || !gdbarch_iterate_over_regset_sections_p (m_core_gdbarch))
    error (_("\"%s\": Core file format not supported"),
	   bfd_get_filename (core_bfd));

  /* Find the data section */
  m_core_section_table = build_section_table (core_bfd);

  build_file_mappings ();
}

/* Construct the target_section_table for file-backed mappings if
   they exist.

   For each unique path in the note, we'll open a BFD with a bfd
   target of "binary".  This is an unstructured bfd target upon which
   we'll impose a structure from the mappings in the architecture-specific
   mappings note.  A BFD section is allocated and initialized for each
   file-backed mapping.

   We take care to not share already open bfds with other parts of
   GDB; in particular, we don't want to add new sections to existing
   BFDs.  We do, however, ensure that the BFDs that we allocate here
   will go away (be deallocated) when the core target is detached.  */

void
core_target::build_file_mappings ()
{
  std::unordered_map<std::string, struct bfd *> bfd_map;
  std::unordered_set<std::string> unavailable_paths;

  /* See linux_read_core_file_mappings() in linux-tdep.c for an example
     read_core_file_mappings method.  */
  gdbarch_read_core_file_mappings (m_core_gdbarch, core_bfd,

    /* After determining the number of mappings, read_core_file_mappings
       will invoke this lambda.  */
    [&] (ULONGEST)
      {
      },

    /* read_core_file_mappings will invoke this lambda for each mapping
       that it finds.  */
    [&] (int num, ULONGEST start, ULONGEST end, ULONGEST file_ofs,
	 const char *filename)
      {
	/* Architecture-specific read_core_mapping methods are expected to
	   weed out non-file-backed mappings.  */
	gdb_assert (filename != nullptr);

	struct bfd *bfd = bfd_map[filename];
	if (bfd == nullptr)
	  {
	    /* Use exec_file_find() to do sysroot expansion.  It'll
	       also strip the potential sysroot "target:" prefix.  If
	       there is no sysroot, an equivalent (possibly more
	       canonical) pathname will be provided.  */
	    gdb::unique_xmalloc_ptr<char> expanded_fname
	      = exec_file_find (filename, NULL);
	    if (expanded_fname == nullptr)
	      {
		m_core_unavailable_mappings.emplace_back (start, end - start);
		/* Print just one warning per path.  */
		if (unavailable_paths.insert (filename).second)
		  warning (_("Can't open file %s during file-backed mapping "
			     "note processing"),
			   filename);
		return;
	      }

	    bfd = bfd_map[filename] = bfd_openr (expanded_fname.get (),
						 "binary");

	    if (bfd == nullptr || !bfd_check_format (bfd, bfd_object))
	      {
		m_core_unavailable_mappings.emplace_back (start, end - start);
		/* If we get here, there's a good chance that it's due to
		   an internal error.  We issue a warning instead of an
		   internal error because of the possibility that the
		   file was removed in between checking for its
		   existence during the expansion in exec_file_find()
		   and the calls to bfd_openr() / bfd_check_format(). 
		   Output both the path from the core file note along
		   with its expansion to make debugging this problem
		   easier.  */
		warning (_("Can't open file %s which was expanded to %s "
			   "during file-backed mapping note processing"),
			 filename, expanded_fname.get ());
		if (bfd != nullptr)
		  bfd_close (bfd);
		return;
	      }
	    /* Ensure that the bfd will be closed when core_bfd is closed. 
	       This can be checked before/after a core file detach via
	       "maint info bfds".  */
	    gdb_bfd_record_inclusion (core_bfd, bfd);
	  }

	/* Make new BFD section.  All sections have the same name,
	   which is permitted by bfd_make_section_anyway().  */
	asection *sec = bfd_make_section_anyway (bfd, "load");
	if (sec == nullptr)
	  error (_("Can't make section"));
	sec->filepos = file_ofs;
	bfd_set_section_flags (sec, SEC_READONLY | SEC_HAS_CONTENTS);
	bfd_set_section_size (sec, end - start);
	bfd_set_section_vma (sec, start);
	bfd_set_section_lma (sec, start);
	bfd_set_section_alignment (sec, 2);

	/* Set target_section fields.  */
	m_core_file_mappings.emplace_back (start, end, sec);
      });

  normalize_mem_ranges (&m_core_unavailable_mappings);
}

/* An arbitrary identifier for the core inferior.  */
#define CORELOW_PID 1

/* Close the core target.  */

void
core_target::close ()
{
  if (core_bfd)
    {
      switch_to_no_thread ();    /* Avoid confusion from thread
				    stuff.  */
      exit_inferior_silent (current_inferior ());

      /* Clear out solib state while the bfd is still open.  See
	 comments in clear_solib in solib.c.  */
      clear_solib ();

      current_program_space->cbfd.reset (nullptr);
    }

  /* Core targets are heap-allocated (see core_target_open), so here
     we delete ourselves.  */
  delete this;
}

/* Look for sections whose names start with `.reg/' so that we can
   extract the list of threads in a core file.  */

static void
add_to_thread_list (asection *asect, asection *reg_sect)
{
  int core_tid;
  int pid, lwpid;
  bool fake_pid_p = false;
  struct inferior *inf;

  if (!startswith (bfd_section_name (asect), ".reg/"))
    return;

  core_tid = atoi (bfd_section_name (asect) + 5);

  pid = bfd_core_file_pid (core_bfd);
  if (pid == 0)
    {
      fake_pid_p = true;
      pid = CORELOW_PID;
    }

  lwpid = core_tid;

  inf = current_inferior ();
  if (inf->pid == 0)
    {
      inferior_appeared (inf, pid);
      inf->fake_pid_p = fake_pid_p;
    }

  ptid_t ptid (pid, lwpid);

  thread_info *thr = add_thread (inf->process_target (), ptid);

/* Warning, Will Robinson, looking at BFD private data! */

  if (reg_sect != NULL
      && asect->filepos == reg_sect->filepos)	/* Did we find .reg?  */
    switch_to_thread (thr);			/* Yes, make it current.  */
}

/* Issue a message saying we have no core to debug, if FROM_TTY.  */

static void
maybe_say_no_core_file_now (int from_tty)
{
  if (from_tty)
    printf_filtered (_("No core file now.\n"));
}

/* Backward compatibility with old way of specifying core files.  */

void
core_file_command (const char *filename, int from_tty)
{
  dont_repeat ();		/* Either way, seems bogus.  */

  if (filename == NULL)
    {
      if (core_bfd != NULL)
	{
	  target_detach (current_inferior (), from_tty);
	  gdb_assert (core_bfd == NULL);
	}
      else
	maybe_say_no_core_file_now (from_tty);
    }
  else
    core_target_open (filename, from_tty);
}

/* Locate (and load) an executable file (and symbols) given the core file
   BFD ABFD.  */

static void
locate_exec_from_corefile_build_id (bfd *abfd, int from_tty)
{
  const bfd_build_id *build_id = build_id_bfd_get (abfd);
  if (build_id == nullptr)
    return;

  gdb_bfd_ref_ptr execbfd
    = build_id_to_exec_bfd (build_id->size, build_id->data);

  if (execbfd != nullptr)
    {
      exec_file_attach (bfd_get_filename (execbfd.get ()), from_tty);
      symbol_file_add_main (bfd_get_filename (execbfd.get ()),
			    symfile_add_flag (from_tty ? SYMFILE_VERBOSE : 0));
    }
}

/* See gdbcore.h.  */

void
core_target_open (const char *arg, int from_tty)
{
  const char *p;
  int siggy;
  int scratch_chan;
  int flags;

  target_preopen (from_tty);
  if (!arg)
    {
      if (core_bfd)
	error (_("No core file specified.  (Use `detach' "
		 "to stop debugging a core file.)"));
      else
	error (_("No core file specified."));
    }

  gdb::unique_xmalloc_ptr<char> filename (tilde_expand (arg));
  if (strlen (filename.get ()) != 0
      && !IS_ABSOLUTE_PATH (filename.get ()))
    filename = gdb_abspath (filename.get ());

  flags = O_BINARY | O_LARGEFILE;
  if (write_files)
    flags |= O_RDWR;
  else
    flags |= O_RDONLY;
  scratch_chan = gdb_open_cloexec (filename.get (), flags, 0);
  if (scratch_chan < 0)
    perror_with_name (filename.get ());

  gdb_bfd_ref_ptr temp_bfd (gdb_bfd_fopen (filename.get (), gnutarget,
					   write_files ? FOPEN_RUB : FOPEN_RB,
					   scratch_chan));
  if (temp_bfd == NULL)
    perror_with_name (filename.get ());

  if (!bfd_check_format (temp_bfd.get (), bfd_core))
    {
      /* Do it after the err msg */
      /* FIXME: should be checking for errors from bfd_close (for one
	 thing, on error it does not free all the storage associated
	 with the bfd).  */
      error (_("\"%s\" is not a core dump: %s"),
	     filename.get (), bfd_errmsg (bfd_get_error ()));
    }

  current_program_space->cbfd = std::move (temp_bfd);

  core_target *target = new core_target ();

  /* Own the target until it is successfully pushed.  */
  target_ops_up target_holder (target);

  validate_files ();

  /* If we have no exec file, try to set the architecture from the
     core file.  We don't do this unconditionally since an exec file
     typically contains more information that helps us determine the
     architecture than a core file.  */
  if (!current_program_space->exec_bfd ())
    set_gdbarch_from_file (core_bfd);

  current_inferior ()->push_target (std::move (target_holder));

  switch_to_no_thread ();

  /* Need to flush the register cache (and the frame cache) from a
     previous debug session.  If inferior_ptid ends up the same as the
     last debug session --- e.g., b foo; run; gcore core1; step; gcore
     core2; core core1; core core2 --- then there's potential for
     get_current_regcache to return the cached regcache of the
     previous session, and the frame cache being stale.  */
  registers_changed ();

  /* Build up thread list from BFD sections, and possibly set the
     current thread to the .reg/NN section matching the .reg
     section.  */
  asection *reg_sect = bfd_get_section_by_name (core_bfd, ".reg");
  for (asection *sect : gdb_bfd_sections (core_bfd))
    add_to_thread_list (sect, reg_sect);

  if (inferior_ptid == null_ptid)
    {
      /* Either we found no .reg/NN section, and hence we have a
	 non-threaded core (single-threaded, from gdb's perspective),
	 or for some reason add_to_thread_list couldn't determine
	 which was the "main" thread.  The latter case shouldn't
	 usually happen, but we're dealing with input here, which can
	 always be broken in different ways.  */
      thread_info *thread = first_thread_of_inferior (current_inferior ());

      if (thread == NULL)
	{
	  inferior_appeared (current_inferior (), CORELOW_PID);
	  thread = add_thread_silent (target, ptid_t (CORELOW_PID));
	}

      switch_to_thread (thread);
    }

  if (current_program_space->exec_bfd () == nullptr)
    locate_exec_from_corefile_build_id (core_bfd, from_tty);

  post_create_inferior (from_tty);

  /* Now go through the target stack looking for threads since there
     may be a thread_stratum target loaded on top of target core by
     now.  The layer above should claim threads found in the BFD
     sections.  */
  try
    {
      target_update_thread_list ();
    }

  catch (const gdb_exception_error &except)
    {
      exception_print (gdb_stderr, except);
    }

  p = bfd_core_file_failing_command (core_bfd);
  if (p)
    printf_filtered (_("Core was generated by `%s'.\n"), p);

  /* Clearing any previous state of convenience variables.  */
  clear_exit_convenience_vars ();

  siggy = bfd_core_file_failing_signal (core_bfd);
  if (siggy > 0)
    {
      gdbarch *core_gdbarch = target->core_gdbarch ();

      /* If we don't have a CORE_GDBARCH to work with, assume a native
	 core (map gdb_signal from host signals).  If we do have
	 CORE_GDBARCH to work with, but no gdb_signal_from_target
	 implementation for that gdbarch, as a fallback measure,
	 assume the host signal mapping.  It'll be correct for native
	 cores, but most likely incorrect for cross-cores.  */
      enum gdb_signal sig = (core_gdbarch != NULL
			     && gdbarch_gdb_signal_from_target_p (core_gdbarch)
			     ? gdbarch_gdb_signal_from_target (core_gdbarch,
							       siggy)
			     : gdb_signal_from_host (siggy));

      printf_filtered (_("Program terminated with signal %s, %s"),
		       gdb_signal_to_name (sig), gdb_signal_to_string (sig));
      if (gdbarch_report_signal_info_p (core_gdbarch))
	gdbarch_report_signal_info (core_gdbarch, current_uiout, sig);
      printf_filtered (_(".\n"));

      /* Set the value of the internal variable $_exitsignal,
	 which holds the signal uncaught by the inferior.  */
      set_internalvar_integer (lookup_internalvar ("_exitsignal"),
			       siggy);
    }

  /* Fetch all registers from core file.  */
  target_fetch_registers (get_current_regcache (), -1);

  /* Now, set up the frame cache, and print the top of stack.  */
  reinit_frame_cache ();
  print_stack_frame (get_selected_frame (NULL), 1, SRC_AND_LOC, 1);

  /* Current thread should be NUM 1 but the user does not know that.
     If a program is single threaded gdb in general does not mention
     anything about threads.  That is why the test is >= 2.  */
  if (thread_count (target) >= 2)
    {
      try
	{
	  thread_command (NULL, from_tty);
	}
      catch (const gdb_exception_error &except)
	{
	  exception_print (gdb_stderr, except);
	}
    }
}

void
core_target::detach (inferior *inf, int from_tty)
{
  /* Note that 'this' is dangling after this call.  unpush_target
     closes the target, and our close implementation deletes
     'this'.  */
  inf->unpush_target (this);

  /* Clear the register cache and the frame cache.  */
  registers_changed ();
  reinit_frame_cache ();
  maybe_say_no_core_file_now (from_tty);
}

/* Try to retrieve registers from a section in core_bfd, and supply
   them to REGSET.

   If ptid's lwp member is zero, do the single-threaded
   thing: look for a section named NAME.  If ptid's lwp
   member is non-zero, do the multi-threaded thing: look for a section
   named "NAME/LWP", where LWP is the shortest ASCII decimal
   representation of ptid's lwp member.

   HUMAN_NAME is a human-readable name for the kind of registers the
   NAME section contains, for use in error messages.

   If REQUIRED is true, print an error if the core file doesn't have a
   section by the appropriate name.  Otherwise, just do nothing.  */

void
core_target::get_core_register_section (struct regcache *regcache,
					const struct regset *regset,
					const char *name,
					int section_min_size,
					const char *human_name,
					bool required)
{
  gdb_assert (regset != nullptr);

  struct bfd_section *section;
  bfd_size_type size;
  bool variable_size_section = (regset->flags & REGSET_VARIABLE_SIZE);

  thread_section_name section_name (name, regcache->ptid ());

  section = bfd_get_section_by_name (core_bfd, section_name.c_str ());
  if (! section)
    {
      if (required)
	warning (_("Couldn't find %s registers in core file."),
		 human_name);
      return;
    }

  size = bfd_section_size (section);
  if (size < section_min_size)
    {
      warning (_("Section `%s' in core file too small."),
	       section_name.c_str ());
      return;
    }
  if (size != section_min_size && !variable_size_section)
    {
      warning (_("Unexpected size of section `%s' in core file."),
	       section_name.c_str ());
    }

  gdb::byte_vector contents (size);
  if (!bfd_get_section_contents (core_bfd, section, contents.data (),
				 (file_ptr) 0, size))
    {
      warning (_("Couldn't read %s registers from `%s' section in core file."),
	       human_name, section_name.c_str ());
      return;
    }

  regset->supply_regset (regset, regcache, -1, contents.data (), size);
}

/* Data passed to gdbarch_iterate_over_regset_sections's callback.  */
struct get_core_registers_cb_data
{
  core_target *target;
  struct regcache *regcache;
};

/* Callback for get_core_registers that handles a single core file
   register note section. */

static void
get_core_registers_cb (const char *sect_name, int supply_size, int collect_size,
		       const struct regset *regset,
		       const char *human_name, void *cb_data)
{
  gdb_assert (regset != nullptr);

  auto *data = (get_core_registers_cb_data *) cb_data;
  bool required = false;
  bool variable_size_section = (regset->flags & REGSET_VARIABLE_SIZE);

  if (!variable_size_section)
    gdb_assert (supply_size == collect_size);

  if (strcmp (sect_name, ".reg") == 0)
    {
      required = true;
      if (human_name == NULL)
	human_name = "general-purpose";
    }
  else if (strcmp (sect_name, ".reg2") == 0)
    {
      if (human_name == NULL)
	human_name = "floating-point";
    }

  data->target->get_core_register_section (data->regcache, regset, sect_name,
					   supply_size, human_name, required);
}

/* Get the registers out of a core file.  This is the machine-
   independent part.  Fetch_core_registers is the machine-dependent
   part, typically implemented in the xm-file for each
   architecture.  */

/* We just get all the registers, so we don't use regno.  */

void
core_target::fetch_registers (struct regcache *regcache, int regno)
{
  if (!(m_core_gdbarch != nullptr
	&& gdbarch_iterate_over_regset_sections_p (m_core_gdbarch)))
    {
      fprintf_filtered (gdb_stderr,
		     "Can't fetch registers from this type of core file\n");
      return;
    }

  struct gdbarch *gdbarch = regcache->arch ();
  get_core_registers_cb_data data = { this, regcache };
  gdbarch_iterate_over_regset_sections (gdbarch,
					get_core_registers_cb,
					(void *) &data, NULL);

  /* Mark all registers not found in the core as unavailable.  */
  for (int i = 0; i < gdbarch_num_regs (regcache->arch ()); i++)
    if (regcache->get_register_status (i) == REG_UNKNOWN)
      regcache->raw_supply (i, NULL);
}

void
core_target::files_info ()
{
  print_section_info (&m_core_section_table, core_bfd);
}

/* Helper method for core_target::xfer_partial.  */

enum target_xfer_status
core_target::xfer_memory_via_mappings (gdb_byte *readbuf,
				       const gdb_byte *writebuf,
				       ULONGEST offset, ULONGEST len,
				       ULONGEST *xfered_len)
{
  enum target_xfer_status xfer_status;

  xfer_status = (section_table_xfer_memory_partial
		   (readbuf, writebuf,
		    offset, len, xfered_len,
		    m_core_file_mappings));

  if (xfer_status == TARGET_XFER_OK || m_core_unavailable_mappings.empty ())
    return xfer_status;

  /* There are instances - e.g. when debugging within a docker
     container using the AUFS storage driver - where the pathnames
     obtained from the note section are incorrect.  Despite the path
     being wrong, just knowing the start and end addresses of the
     mappings is still useful; we can attempt an access of the file
     stratum constrained to the address ranges corresponding to the
     unavailable mappings.  */

  ULONGEST memaddr = offset;
  ULONGEST memend = offset + len;

  for (const auto &mr : m_core_unavailable_mappings)
    {
      if (address_in_mem_range (memaddr, &mr))
	{
	  if (!address_in_mem_range (memend, &mr))
	    len = mr.start + mr.length - memaddr;

	  xfer_status = this->beneath ()->xfer_partial (TARGET_OBJECT_MEMORY,
							NULL,
							readbuf,
							writebuf,
							offset,
							len,
							xfered_len);
	  break;
	}
    }

  return xfer_status;
}

enum target_xfer_status
core_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:
      {
	enum target_xfer_status xfer_status;

	/* Try accessing memory contents from core file data,
	   restricting consideration to those sections for which
	   the BFD section flag SEC_HAS_CONTENTS is set.  */
	auto has_contents_cb = [] (const struct target_section *s)
	  {
	    return ((s->the_bfd_section->flags & SEC_HAS_CONTENTS) != 0);
	  };
	xfer_status = section_table_xfer_memory_partial
			(readbuf, writebuf,
			 offset, len, xfered_len,
			 m_core_section_table,
			 has_contents_cb);
	if (xfer_status == TARGET_XFER_OK)
	  return TARGET_XFER_OK;

	/* Check file backed mappings.  If they're available, use
	   core file provided mappings (e.g. from .note.linuxcore.file
	   or the like) as this should provide a more accurate
	   result.  If not, check the stratum beneath us, which should
	   be the file stratum.

	   We also check unavailable mappings due to Docker/AUFS driver
	   issues.  */
	if (!m_core_file_mappings.empty ()
	    || !m_core_unavailable_mappings.empty ())
	  {
	    xfer_status = xfer_memory_via_mappings (readbuf, writebuf, offset,
						    len, xfered_len);
	  }
	else
	  xfer_status = this->beneath ()->xfer_partial (object, annex, readbuf,
							writebuf, offset, len,
							xfered_len);
	if (xfer_status == TARGET_XFER_OK)
	  return TARGET_XFER_OK;

	/* Finally, attempt to access data in core file sections with
	   no contents.  These will typically read as all zero.  */
	auto no_contents_cb = [&] (const struct target_section *s)
	  {
	    return !has_contents_cb (s);
	  };
	xfer_status = section_table_xfer_memory_partial
			(readbuf, writebuf,
			 offset, len, xfered_len,
			 m_core_section_table,
			 no_contents_cb);

	return xfer_status;
      }
    case TARGET_OBJECT_AUXV:
      if (readbuf)
	{
	  /* When the aux vector is stored in core file, BFD
	     represents this with a fake section called ".auxv".  */

	  struct bfd_section *section;
	  bfd_size_type size;

	  section = bfd_get_section_by_name (core_bfd, ".auxv");
	  if (section == NULL)
	    return TARGET_XFER_E_IO;

	  size = bfd_section_size (section);
	  if (offset >= size)
	    return TARGET_XFER_EOF;
	  size -= offset;
	  if (size > len)
	    size = len;

	  if (size == 0)
	    return TARGET_XFER_EOF;
	  if (!bfd_get_section_contents (core_bfd, section, readbuf,
					 (file_ptr) offset, size))
	    {
	      warning (_("Couldn't read NT_AUXV note in core file."));
	      return TARGET_XFER_E_IO;
	    }

	  *xfered_len = (ULONGEST) size;
	  return TARGET_XFER_OK;
	}
      return TARGET_XFER_E_IO;

    case TARGET_OBJECT_WCOOKIE:
      if (readbuf)
	{
	  /* When the StackGhost cookie is stored in core file, BFD
	     represents this with a fake section called
	     ".wcookie".  */

	  struct bfd_section *section;
	  bfd_size_type size;

	  section = bfd_get_section_by_name (core_bfd, ".wcookie");
	  if (section == NULL)
	    return TARGET_XFER_E_IO;

	  size = bfd_section_size (section);
	  if (offset >= size)
	    return TARGET_XFER_EOF;
	  size -= offset;
	  if (size > len)
	    size = len;

	  if (size == 0)
	    return TARGET_XFER_EOF;
	  if (!bfd_get_section_contents (core_bfd, section, readbuf,
					 (file_ptr) offset, size))
	    {
	      warning (_("Couldn't read StackGhost cookie in core file."));
	      return TARGET_XFER_E_IO;
	    }

	  *xfered_len = (ULONGEST) size;
	  return TARGET_XFER_OK;

	}
      return TARGET_XFER_E_IO;

    case TARGET_OBJECT_LIBRARIES:
      if (m_core_gdbarch != nullptr
	  && gdbarch_core_xfer_shared_libraries_p (m_core_gdbarch))
	{
	  if (writebuf)
	    return TARGET_XFER_E_IO;
	  else
	    {
	      *xfered_len = gdbarch_core_xfer_shared_libraries (m_core_gdbarch,
								readbuf,
								offset, len);

	      if (*xfered_len == 0)
		return TARGET_XFER_EOF;
	      else
		return TARGET_XFER_OK;
	    }
	}
      /* FALL THROUGH */

    case TARGET_OBJECT_LIBRARIES_AIX:
      if (m_core_gdbarch != nullptr
	  && gdbarch_core_xfer_shared_libraries_aix_p (m_core_gdbarch))
	{
	  if (writebuf)
	    return TARGET_XFER_E_IO;
	  else
	    {
	      *xfered_len
		= gdbarch_core_xfer_shared_libraries_aix (m_core_gdbarch,
							  readbuf, offset,
							  len);

	      if (*xfered_len == 0)
		return TARGET_XFER_EOF;
	      else
		return TARGET_XFER_OK;
	    }
	}
      /* FALL THROUGH */

    case TARGET_OBJECT_SIGNAL_INFO:
      if (readbuf)
	{
	  if (m_core_gdbarch != nullptr
	      && gdbarch_core_xfer_siginfo_p (m_core_gdbarch))
	    {
	      LONGEST l = gdbarch_core_xfer_siginfo  (m_core_gdbarch, readbuf,
						      offset, len);

	      if (l >= 0)
		{
		  *xfered_len = l;
		  if (l == 0)
		    return TARGET_XFER_EOF;
		  else
		    return TARGET_XFER_OK;
		}
	    }
	}
      return TARGET_XFER_E_IO;

    default:
      return this->beneath ()->xfer_partial (object, annex, readbuf,
					     writebuf, offset, len,
					     xfered_len);
    }
}



/* Okay, let's be honest: threads gleaned from a core file aren't
   exactly lively, are they?  On the other hand, if we don't claim
   that each & every one is alive, then we don't get any of them
   to appear in an "info thread" command, which is quite a useful
   behaviour.
 */
bool
core_target::thread_alive (ptid_t ptid)
{
  return true;
}

/* Ask the current architecture what it knows about this core file.
   That will be used, in turn, to pick a better architecture.  This
   wrapper could be avoided if targets got a chance to specialize
   core_target.  */

const struct target_desc *
core_target::read_description ()
{
  /* If the core file contains a target description note then we will use
     that in preference to anything else.  */
  bfd_size_type tdesc_note_size = 0;
  struct bfd_section *tdesc_note_section
    = bfd_get_section_by_name (core_bfd, ".gdb-tdesc");
  if (tdesc_note_section != nullptr)
    tdesc_note_size = bfd_section_size (tdesc_note_section);
  if (tdesc_note_size > 0)
    {
      gdb::char_vector contents (tdesc_note_size + 1);
      if (bfd_get_section_contents (core_bfd, tdesc_note_section,
				    contents.data (), (file_ptr) 0,
				    tdesc_note_size))
	{
	  /* Ensure we have a null terminator.  */
	  contents[tdesc_note_size] = '\0';
	  const struct target_desc *result
	    = string_read_description_xml (contents.data ());
	  if (result != nullptr)
	    return result;
	}
    }

  if (m_core_gdbarch && gdbarch_core_read_description_p (m_core_gdbarch))
    {
      const struct target_desc *result;

      result = gdbarch_core_read_description (m_core_gdbarch, this, core_bfd);
      if (result != NULL)
	return result;
    }

  return this->beneath ()->read_description ();
}

std::string
core_target::pid_to_str (ptid_t ptid)
{
  struct inferior *inf;
  int pid;

  /* The preferred way is to have a gdbarch/OS specific
     implementation.  */
  if (m_core_gdbarch != nullptr
      && gdbarch_core_pid_to_str_p (m_core_gdbarch))
    return gdbarch_core_pid_to_str (m_core_gdbarch, ptid);

  /* Otherwise, if we don't have one, we'll just fallback to
     "process", with normal_pid_to_str.  */

  /* Try the LWPID field first.  */
  pid = ptid.lwp ();
  if (pid != 0)
    return normal_pid_to_str (ptid_t (pid));

  /* Otherwise, this isn't a "threaded" core -- use the PID field, but
     only if it isn't a fake PID.  */
  inf = find_inferior_ptid (this, ptid);
  if (inf != NULL && !inf->fake_pid_p)
    return normal_pid_to_str (ptid);

  /* No luck.  We simply don't have a valid PID to print.  */
  return "<main task>";
}

const char *
core_target::thread_name (struct thread_info *thr)
{
  if (m_core_gdbarch != nullptr
      && gdbarch_core_thread_name_p (m_core_gdbarch))
    return gdbarch_core_thread_name (m_core_gdbarch, thr);
  return NULL;
}

bool
core_target::has_memory ()
{
  return (core_bfd != NULL);
}

bool
core_target::has_stack ()
{
  return (core_bfd != NULL);
}

bool
core_target::has_registers ()
{
  return (core_bfd != NULL);
}

/* Implement the to_info_proc method.  */

bool
core_target::info_proc (const char *args, enum info_proc_what request)
{
  struct gdbarch *gdbarch = get_current_arch ();

  /* Since this is the core file target, call the 'core_info_proc'
     method on gdbarch, not 'info_proc'.  */
  if (gdbarch_core_info_proc_p (gdbarch))
    gdbarch_core_info_proc (gdbarch, args, request);

  return true;
}

/* Get a pointer to the current core target.  If not connected to a
   core target, return NULL.  */

static core_target *
get_current_core_target ()
{
  target_ops *proc_target = current_inferior ()->process_target ();
  return dynamic_cast<core_target *> (proc_target);
}

/* Display file backed mappings from core file.  */

void
core_target::info_proc_mappings (struct gdbarch *gdbarch)
{
  if (!m_core_file_mappings.empty ())
    {
      printf_filtered (_("Mapped address spaces:\n\n"));
      if (gdbarch_addr_bit (gdbarch) == 32)
	{
	  printf_filtered ("\t%10s %10s %10s %10s %s\n",
			   "Start Addr",
			   "  End Addr",
			   "      Size", "    Offset", "objfile");
	}
      else
	{
	  printf_filtered ("  %18s %18s %10s %10s %s\n",
			   "Start Addr",
			   "  End Addr",
			   "      Size", "    Offset", "objfile");
	}
    }

  for (const target_section &tsp : m_core_file_mappings)
    {
      ULONGEST start = tsp.addr;
      ULONGEST end = tsp.endaddr;
      ULONGEST file_ofs = tsp.the_bfd_section->filepos;
      const char *filename = bfd_get_filename (tsp.the_bfd_section->owner);

      if (gdbarch_addr_bit (gdbarch) == 32)
	printf_filtered ("\t%10s %10s %10s %10s %s\n",
			 paddress (gdbarch, start),
			 paddress (gdbarch, end),
			 hex_string (end - start),
			 hex_string (file_ofs),
			 filename);
      else
	printf_filtered ("  %18s %18s %10s %10s %s\n",
			 paddress (gdbarch, start),
			 paddress (gdbarch, end),
			 hex_string (end - start),
			 hex_string (file_ofs),
			 filename);
    }
}

/* Implement "maintenance print core-file-backed-mappings" command.  

   If mappings are loaded, the results should be similar to the
   mappings shown by "info proc mappings".  This command is mainly a
   debugging tool for GDB developers to make sure that the expected
   mappings are present after loading a core file.  For Linux, the
   output provided by this command will be very similar (if not
   identical) to that provided by "info proc mappings".  This is not
   necessarily the case for other OSes which might provide
   more/different information in the "info proc mappings" output.  */

static void
maintenance_print_core_file_backed_mappings (const char *args, int from_tty)
{
  core_target *targ = get_current_core_target ();
  if (targ != nullptr)
    targ->info_proc_mappings (targ->core_gdbarch ());
}

void _initialize_corelow ();
void
_initialize_corelow ()
{
  add_target (core_target_info, core_target_open, filename_completer);
  add_cmd ("core-file-backed-mappings", class_maintenance,
	   maintenance_print_core_file_backed_mappings,
	   _("Print core file's file-backed mappings."),
	   &maintenanceprintlist);
}
