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