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

   Copyright (C) 1986-2024 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 "arch-utils.h"
#include <signal.h>
#include <fcntl.h>
#include "exceptions.h"
#include "frame.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 "gdbsupport/scoped_fd.h"
#include "gdbsupport/x86-xstate.h"
#include <unordered_map>
#include <unordered_set>
#include "cli/cli-cmds.h"
#include "xml-tdesc.h"
#include "memtag.h"
#include "cli/cli-style.h"

#ifndef O_LARGEFILE
#define O_LARGEFILE 0
#endif

/* A mem_range and the build-id associated with the file mapped into the
   given range.  */

struct mem_range_and_build_id
{
  mem_range_and_build_id (mem_range &&r, const bfd_build_id *id)
    : range (r),
      build_id (id)
  { /* Nothing.  */ }

  /* A range of memory addresses.  */
  mem_range range;

  /* The build-id of the file mapped into RANGE.  */
  const bfd_build_id *build_id;
};

/* An instance of this class is created within the core_target and is used
   to hold all the information that relating to mapped files, their address
   ranges, and their corresponding build-ids.  */

struct mapped_file_info
{
  /* See comment on function definition.  */

  void add (const char *soname, const char *expected_filename,
	    const char *actual_filename, std::vector<mem_range> &&ranges,
	    const bfd_build_id *build_id);

  /* See comment on function definition.  */

  std::optional <core_target_mapped_file_info>
  lookup (const char *filename, const std::optional<CORE_ADDR> &addr);

private:

  /* Helper for ::lookup.  BUILD_ID is a build-id that was found in
     one of the data structures within this class.  Lookup the
     corresponding filename in m_build_id_to_filename_map and return a pair
     containing the build-id and filename.

     If no corresponding filename is found in m_build_id_to_filename_map
     then the returned pair contains BUILD_ID and an empty string.

     If BUILD_ID is nullptr then the returned pair contains nullptr and an
     empty string.  */

  struct core_target_mapped_file_info
  make_result (const bfd_build_id *build_id)
  {
    if (build_id != nullptr)
      {
      auto it = m_build_id_to_filename_map.find (build_id);
      if (it != m_build_id_to_filename_map.end ())
	return { build_id, it->second };
    }

    return { build_id, {} };
  }

  /* A type that maps a string to a build-id.  */
  using string_to_build_id_map
    = std::unordered_map<std::string, const bfd_build_id *>;

  /* A type that maps a build-id to a string.  */
  using build_id_to_string_map
    = std::unordered_map<const bfd_build_id *, std::string>;

  /* When loading a core file, the build-ids are extracted based on the
     file backed mappings.  This map associates the name of a file that was
     mapped into the core file with the corresponding build-id.  The
     build-id pointers in this map will never be nullptr as we only record
     files if they have a build-id.  */

  string_to_build_id_map m_filename_to_build_id_map;

  /* Map a build-id pointer back to the name of the file that was mapped
     into the inferior's address space.  If we lookup a matching build-id
     using either a soname or an address then this map allows us to also
     provide a full path to a file with a matching build-id.  */

  build_id_to_string_map m_build_id_to_filename_map;

  /* If the file that was mapped into the core file was a shared library
     then it might have a DT_SONAME tag in its .dynamic section, this tag
     contains the name of a shared object.  When opening a shared library,
     if it's basename appears in this map then we can use the corresponding
     build-id.

     In the rare case that two different files have the same DT_SONAME
     value then the build-id pointer in this map will be nullptr, this
     indicates that it's not possible to find a build-id based on the given
     DT_SONAME value.  */

  string_to_build_id_map m_soname_to_build_id_map;

  /* This vector maps memory ranges onto an associated build-id.  The
     ranges are those of the files mapped into the core file.

     Entries in this vector must not overlap, and are sorted be increasing
     memory address.  Within each entry the build-id pointer will not be
     nullptr.

     While building this vector the entries are not sorted, they are
     sorted once after the table has finished being built.  */

  std::vector<mem_range_and_build_id> m_address_to_build_id_list;

  /* False if address_to_build_id_list is unsorted, otherwise true.  */

  bool m_address_to_build_id_list_sorted = false;
};

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

  bool supports_memory_tagging () override;

  /* Core file implementation of fetch_memtags.  Fetch the memory tags from
     core file notes.  */
  bool fetch_memtags (CORE_ADDR address, size_t len,
		      gdb::byte_vector &tags, int type) override;

  /* If the architecture supports it, check if ADDRESS is within a memory range
     mapped with tags.  For example,  MTE tags for AArch64.  */
  bool is_address_tagged (gdbarch *gdbarch, CORE_ADDR address) override;

  x86_xsave_layout fetch_x86_xsave_layout () 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);

  std::optional <core_target_mapped_file_info>
  lookup_mapped_file_info (const char *filename,
			   const std::optional<CORE_ADDR> &addr)
  {
    return m_mapped_file_info.lookup (filename, addr);
  }

private: /* per-core data */

  /* Get rid of the core inferior.  */
  void clear_core ();

  /* 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.  */
  std::vector<target_section> m_core_section_table;

  /* File-backed address space mappings: some core files include
     information about memory mapped files.  */
  std::vector<target_section> 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;

  /* Data structure that holds information mapping filenames and address
     ranges to the corresponding build-ids as well as the reverse build-id
     to filename mapping.  */
  mapped_file_info m_mapped_file_info;

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

  /* 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 (current_program_space->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 = current_program_space->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 (current_program_space->core_bfd ()));

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

  build_file_mappings ();
}

/* Construct the 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 ()
{
  /* Type holding information about a single file mapped into the inferior
     at the point when the core file was created.  Associates a build-id
     with the list of regions the file is mapped into.  */
  struct mapped_file
  {
    /* Type for a region of a file that was mapped into the inferior when
       the core file was generated.  */
    struct region
    {
      /* Constructor.   See member variables for argument descriptions.  */
      region (CORE_ADDR start_, CORE_ADDR end_, CORE_ADDR file_ofs_)
	: start (start_),
	  end (end_),
	  file_ofs (file_ofs_)
      { /* Nothing.  */ }

      /* The inferior address for the start of the mapped region.  */
      CORE_ADDR start;

      /* The inferior address immediately after the mapped region.  */
      CORE_ADDR end;

      /* The offset within the mapped file for this content.  */
      CORE_ADDR file_ofs;
    };

    /* If not nullptr, then this is the build-id associated with this
       file.  */
    const bfd_build_id *build_id = nullptr;

    /* If true then we have seen multiple different build-ids associated
       with the same filename.  The build_id field will have been set back
       to nullptr, and we should not set build_id in future.  */
    bool ignore_build_id_p = false;

    /* All the mapped regions of this file.  */
    std::vector<region> regions;
  };

  std::unordered_map<std::string, struct bfd *> bfd_map;
  std::unordered_set<std::string> unavailable_paths;

  /* All files mapped into the core file.  The key is the filename.  */
  std::unordered_map<std::string, mapped_file> mapped_files;

  /* 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,
				   current_program_space->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, const bfd_build_id *build_id)
      {
	/* Architecture-specific read_core_mapping methods are expected to
	   weed out non-file-backed mappings.  */
	gdb_assert (filename != nullptr);

	/* Add this mapped region to the data for FILENAME.  */
	mapped_file &file_data = mapped_files[filename];
	file_data.regions.emplace_back (start, end, file_ofs);
	if (build_id != nullptr && !file_data.ignore_build_id_p)
	  {
	    if (file_data.build_id == nullptr)
	      file_data.build_id = build_id;
	    else if (!build_id_equal (build_id, file_data.build_id))
	      {
		warning (_("Multiple build-ids found for %ps"),
			 styled_string (file_name_style.style (), filename));
		file_data.build_id = nullptr;
		file_data.ignore_build_id_p = true;
	      }
	  }
      });

  for (const auto &iter : mapped_files)
    {
      const std::string &filename = iter.first;
      const mapped_file &file_data = iter.second;

      /* 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.c_str (), nullptr);

      bool build_id_mismatch = false;
      if (expanded_fname != nullptr && file_data.build_id != nullptr)
	{
	  /* We temporarily open the bfd as a structured target, this
	     allows us to read the build-id from the bfd if there is one.
	     For this task it's OK if we reuse an already open bfd object,
	     so we make this call through GDB's bfd cache.  Once we've
	     checked the build-id (if there is one) we'll drop this
	     reference and re-open the bfd using the "binary" target.  */
	  gdb_bfd_ref_ptr tmp_bfd
	    = gdb_bfd_open (expanded_fname.get (), gnutarget);

	  if (tmp_bfd != nullptr
	      && bfd_check_format (tmp_bfd.get (), bfd_object)
	      && build_id_bfd_get (tmp_bfd.get ()) != nullptr)
	    {
	      /* The newly opened TMP_BFD has a build-id, and this mapped
		 file has a build-id extracted from the core-file.  Check
		 the build-id's match, and if not, reject TMP_BFD.  */
	      const struct bfd_build_id *found
		= build_id_bfd_get (tmp_bfd.get ());
	      if (!build_id_equal (found, file_data.build_id))
		build_id_mismatch = true;
	    }
	}

      gdb_bfd_ref_ptr abfd;
      if (expanded_fname != nullptr && !build_id_mismatch)
	{
	  struct bfd *b = bfd_openr (expanded_fname.get (), "binary");
	  abfd = gdb_bfd_ref_ptr::new_reference (b);
	}

      if ((expanded_fname == nullptr
	   || abfd == nullptr
	   || !bfd_check_format (abfd.get (), bfd_object))
	  && file_data.build_id != nullptr)
	{
	  abfd = find_objfile_by_build_id (file_data.build_id,
					   filename.c_str ());

	  if (abfd != nullptr)
	    {
	      /* The find_objfile_by_build_id will have opened ABFD using
		 the GNUTARGET global bfd type, however, we need the bfd
		 opened as the binary type (see the function's header
		 comment), so now we reopen ABFD with the desired binary
		 type.  */
	      expanded_fname
		= make_unique_xstrdup (bfd_get_filename (abfd.get ()));
	      struct bfd *b = bfd_openr (expanded_fname.get (), "binary");
	      gdb_assert (b != nullptr);
	      abfd = gdb_bfd_ref_ptr::new_reference (b);
	    }
	}

      std::vector<mem_range> ranges;
      for (const mapped_file::region &region : file_data.regions)
	ranges.emplace_back (region.start, region.end - region.start);

      if (expanded_fname == nullptr
	  || abfd == nullptr
	  || !bfd_check_format (abfd.get (), bfd_object))
	{
	  /* If ABFD was opened, but the wrong format, close it now.  */
	  abfd = nullptr;

	  /* Record all regions for this file as unavailable.  */
	  for (const mapped_file::region &region : file_data.regions)
	    m_core_unavailable_mappings.emplace_back (region.start,
						      region.end
						      - region.start);

	  /* And give the user an appropriate warning.  */
	  if (build_id_mismatch)
	    {
	      if (expanded_fname == nullptr
		  || filename == expanded_fname.get ())
		warning (_("File %ps doesn't match build-id from core-file "
			   "during file-backed mapping processing"),
			 styled_string (file_name_style.style (),
					filename.c_str ()));
	      else
		warning (_("File %ps which was expanded to %ps, doesn't match "
			   "build-id from core-file during file-backed "
			   "mapping processing"),
			 styled_string (file_name_style.style (),
					filename.c_str ()),
			 styled_string (file_name_style.style (),
					expanded_fname.get ()));
	    }
	  else
	    {
	      if (expanded_fname == nullptr
		  || filename == expanded_fname.get ())
		warning (_("Can't open file %ps during file-backed mapping "
			   "note processing"),
			 styled_string (file_name_style.style (),
					filename.c_str ()));
	      else
		warning (_("Can't open file %ps which was expanded to %ps "
			   "during file-backed mapping note processing"),
			 styled_string (file_name_style.style (),
					filename.c_str ()),
			 styled_string (file_name_style.style (),
					expanded_fname.get ()));
	    }
	}
      else
	{
	  /* 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 (current_program_space->core_bfd (),
				    abfd.get ());

	  /* Create sections for each mapped region.  */
	  for (const mapped_file::region &region : file_data.regions)
	    {
	      /* Make new BFD section.  All sections have the same name,
		 which is permitted by bfd_make_section_anyway().  */
	      asection *sec = bfd_make_section_anyway (abfd.get (), "load");
	      if (sec == nullptr)
		error (_("Can't make section"));
	      sec->filepos = region.file_ofs;
	      bfd_set_section_flags (sec, SEC_READONLY | SEC_HAS_CONTENTS);
	      bfd_set_section_size (sec, region.end - region.start);
	      bfd_set_section_vma (sec, region.start);
	      bfd_set_section_lma (sec, region.start);
	      bfd_set_section_alignment (sec, 2);

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

      /* If this is a bfd with a build-id then record the filename,
	 optional soname (DT_SONAME .dynamic attribute), and the range of
	 addresses at which this bfd is mapped.  This information can be
	 used to perform build-id checking when loading the shared
	 libraries.  */
      if (file_data.build_id != nullptr)
	{
	  normalize_mem_ranges (&ranges);

	  const char *actual_filename = nullptr;
	  gdb::unique_xmalloc_ptr<char> soname;
	  if (abfd != nullptr)
	    {
	      actual_filename = bfd_get_filename (abfd.get ());
	      soname = gdb_bfd_read_elf_soname (actual_filename);
	    }

	  m_mapped_file_info.add (soname.get (), filename.c_str (),
				  actual_filename, std::move (ranges),
				  file_data.build_id);
	}
    }

  normalize_mem_ranges (&m_core_unavailable_mappings);
}

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

void
core_target::clear_core ()
{
  if (current_program_space->core_bfd () != nullptr)
    {
      switch_to_no_thread ();    /* Avoid confusion from thread
				    stuff.  */
      exit_inferior (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);

      current_program_space->cbfd.reset (nullptr);
    }
}

/* Close the core target.  */

void
core_target::close ()
{
  clear_core ();

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

/* If ASECT is a section whose name begins with '.reg/' then extract the
   lwpid after the '/' and create a new thread in INF.

   If REG_SECT is not nullptr, and the both ASECT and REG_SECT point at the
   same position in the parent bfd object then switch to the newly created
   thread, otherwise, the selected thread is left unchanged.  */

static void
add_to_thread_list (asection *asect, asection *reg_sect, inferior *inf)
{
  if (!startswith (bfd_section_name (asect), ".reg/"))
    return;

  int lwpid = atoi (bfd_section_name (asect) + 5);
  ptid_t ptid (inf->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)
    gdb_printf (_("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 (current_program_space->core_bfd () != nullptr)
	{
	  target_detach (current_inferior (), from_tty);
	  gdb_assert (current_program_space->core_bfd () == nullptr);
	}
      else
	maybe_say_no_core_file_now (from_tty);
    }
  else
    core_target_open (filename, from_tty);
}

/* A vmcore file is a core file created by the Linux kernel at the point of
   a crash.  Each thread in the core file represents a real CPU core, and
   the lwpid for each thread is the pid of the process that was running on
   that core at the moment of the crash.

   However, not every CPU core will have been running a process, some cores
   will be idle.  For these idle cores the CPU writes an lwpid of 0.  And
   of course, multiple cores might be idle, so there could be multiple
   threads with an lwpid of 0.

   The problem is GDB doesn't really like threads with an lwpid of 0; GDB
   presents such a thread as a process rather than a thread.  And GDB
   certainly doesn't like multiple threads having the same lwpid, each time
   a new thread is seen with the same lwpid the earlier thread (with the
   same lwpid) will be deleted.

   This function addresses both of these problems by assigning a fake lwpid
   to any thread with an lwpid of 0.

   GDB finds the lwpid information by looking at the bfd section names
   which include the lwpid, e.g. .reg/NN where NN is the lwpid.  This
   function looks though all the section names looking for sections named
   .reg/NN.  If any sections are found where NN == 0, then we assign a new
   unique value of NN.  Then, in a second pass, any sections ending /0 are
   assigned their new number.

   Remember, a core file may contain multiple register sections for
   different register sets, but the sets are always grouped by thread, so
   we can figure out which registers should be assigned the same new
   lwpid.  For example, consider a core file containing:

     .reg/0, .reg2/0, .reg/0, .reg2/0

   This represents two threads, each thread contains a .reg and .reg2
   register set.  The .reg represents the start of each thread.  After
   renaming the sections will now look like this:

     .reg/1, .reg2/1, .reg/2, .reg2/2

   After calling this function the rest of the core file handling code can
   treat this core file just like any other core file.  */

static void
rename_vmcore_idle_reg_sections (bfd *abfd, inferior *inf)
{
  /* Map from the bfd section to its lwpid (the /NN number).  */
  std::vector<std::pair<asection *, int>> sections_and_lwpids;

  /* The set of all /NN numbers found.  Needed so we can easily find unused
     numbers in the case that we need to rename some sections.  */
  std::unordered_set<int> all_lwpids;

  /* A count of how many sections called .reg/0 we have found.  */
  unsigned zero_lwpid_count = 0;

  /* Look for all the .reg sections.  Record the section object and the
     lwpid which is extracted from the section name.  Spot if any have an
     lwpid of zero.  */
  for (asection *sect : gdb_bfd_sections (current_program_space->core_bfd ()))
    {
      if (startswith (bfd_section_name (sect), ".reg/"))
	{
	  int lwpid = atoi (bfd_section_name (sect) + 5);
	  sections_and_lwpids.emplace_back (sect, lwpid);
	  all_lwpids.insert (lwpid);
	  if (lwpid == 0)
	    zero_lwpid_count++;
	}
    }

  /* If every ".reg/NN" section has a non-zero lwpid then we don't need to
     do any renaming.  */
  if (zero_lwpid_count == 0)
    return;

  /* Assign a new number to any .reg sections with an lwpid of 0.  */
  int new_lwpid = 1;
  for (auto &sect_and_lwpid : sections_and_lwpids)
    if (sect_and_lwpid.second == 0)
      {
	while (all_lwpids.find (new_lwpid) != all_lwpids.end ())
	  new_lwpid++;
	sect_and_lwpid.second = new_lwpid;
	new_lwpid++;
      }

  /* Now update the names of any sections with an lwpid of 0.  This is
     more than just the .reg sections we originally found.  */
  std::string replacement_lwpid_str;
  auto iter = sections_and_lwpids.begin ();
  int replacement_lwpid = 0;
  for (asection *sect : gdb_bfd_sections (current_program_space->core_bfd ()))
    {
      if (iter != sections_and_lwpids.end () && sect == iter->first)
	{
	  gdb_assert (startswith (bfd_section_name (sect), ".reg/"));

	  int lwpid = atoi (bfd_section_name (sect) + 5);
	  if (lwpid == iter->second)
	    {
	      /* This section was not given a new number.  */
	      gdb_assert (lwpid != 0);
	      replacement_lwpid = 0;
	    }
	  else
	    {
	      replacement_lwpid = iter->second;
	      ptid_t ptid (inf->pid, replacement_lwpid);
	      if (!replacement_lwpid_str.empty ())
		replacement_lwpid_str += ", ";
	      replacement_lwpid_str += target_pid_to_str (ptid);
	    }

	  iter++;
	}

      if (replacement_lwpid != 0)
	{
	  const char *name = bfd_section_name (sect);
	  size_t len = strlen (name);

	  if (strncmp (name + len - 2, "/0", 2) == 0)
	    {
	      /* This section needs a new name.  */
	      std::string name_str
		= string_printf ("%.*s/%d",
				 static_cast<int> (len - 2),
				 name, replacement_lwpid);
	      char *name_buf
		= static_cast<char *> (bfd_alloc (abfd, name_str.size () + 1));
	      if (name_buf == nullptr)
		error (_("failed to allocate space for section name '%s'"),
		       name_str.c_str ());
	      memcpy (name_buf, name_str.c_str(), name_str.size () + 1);
	      bfd_rename_section (sect, name_buf);
	    }
	}
    }

  if (zero_lwpid_count == 1)
    warning (_("found thread with pid 0, assigned replacement Target Id: %s"),
	     replacement_lwpid_str.c_str ());
  else
    warning (_("found threads with pid 0, assigned replacement Target Ids: %s"),
	     replacement_lwpid_str.c_str ());
}

/* 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
    = find_objfile_by_build_id (build_id, abfd->filename);

  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);

  std::string filename = extract_single_filename_arg (arg);

  if (filename.empty ())
    {
      if (current_program_space->core_bfd ())
	error (_("No core file specified.  (Use `detach' "
		 "to stop debugging a core file.)"));
      else
	error (_("No core file specified."));
    }

  if (!IS_ABSOLUTE_PATH (filename.c_str ()))
    filename = gdb_abspath (filename);

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

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

  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.c_str (), 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 (current_program_space->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 ();

  /* Find (or fake) the pid for the process in this core file, and
     initialise the current inferior with that pid.  */
  bool fake_pid_p = false;
  int pid = bfd_core_file_pid (current_program_space->core_bfd ());
  if (pid == 0)
    {
      fake_pid_p = true;
      pid = CORELOW_PID;
    }

  inferior *inf = current_inferior ();
  gdb_assert (inf->pid == 0);
  inferior_appeared (inf, pid);
  inf->fake_pid_p = fake_pid_p;

  /* Rename any .reg/0 sections, giving them each a fake lwpid.  */
  rename_vmcore_idle_reg_sections (current_program_space->core_bfd (), inf);

  /* 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 (current_program_space->core_bfd (), ".reg");
  for (asection *sect : gdb_bfd_sections (current_program_space->core_bfd ()))
    add_to_thread_list (sect, reg_sect, inf);

  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 (inf);

      if (thread == NULL)
	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 (current_program_space->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 (current_program_space->core_bfd ());
  if (p)
    gdb_printf (_("Core was generated by `%s'.\n"), p);

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

  siggy = bfd_core_file_failing_signal (current_program_space->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));

      gdb_printf (_("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);
      gdb_printf (_(".\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_thread_regcache (inferior_thread ()), -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)
{
  /* Get rid of the core.  Don't rely on core_target::close doing it,
     because target_detach may be called with core_target's refcount > 1,
     meaning core_target::close may not be called yet by the
     unpush_target call below.  */
  clear_core ();

  /* Note that 'this' may be dangling after this call.  unpush_target
     closes the target if the refcount reaches 0, 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 (current_program_space->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 (current_program_space->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)))
    {
      gdb_printf (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, current_program_space->core_bfd ());
}


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 (!m_core_file_mappings.empty ())
	  {
	    xfer_status = section_table_xfer_memory_partial
			    (readbuf, writebuf, offset, len, xfered_len,
			     m_core_file_mappings);
	    if (xfer_status == TARGET_XFER_OK)
	      return xfer_status;
	  }

	/* If the access is within an unavailable file mapping then we try
	   to check in the stratum below (the executable stratum).  The
	   thinking here is that if the mapping was read/write then the
	   contents would have been written into the core file and the
	   access would have been satisfied by m_core_section_table.

	   But if the access has not yet been resolved then we can assume
	   the access is read-only.  If the executable was not found
	   during the mapped file check then we'll have an unavailable
	   mapping entry, however, if the user has provided the executable
	   (maybe in a different location) then we might be able to
	   resolve the access from there.

	   If that fails, but the access is within an unavailable region,
	   then the access itself should fail.  */
	for (const auto &mr : m_core_unavailable_mappings)
	  {
	    if (mr.contains (offset))
	      {
		if (!mr.contains (offset + len))
		  len = mr.start + mr.length - offset;

		xfer_status
		  = this->beneath ()->xfer_partial (TARGET_OBJECT_MEMORY,
						    nullptr, readbuf,
						    writebuf, offset,
						    len, xfered_len);
		if (xfer_status == TARGET_XFER_OK)
		  return TARGET_XFER_OK;

		return TARGET_XFER_E_IO;
	      }
	  }

	/* The following is acting as a fallback in case we encounter a
	   situation where the core file is lacking and mapped file
	   information.  Here we query the exec file stratum to see if it
	   can resolve the access.  Doing this when we are missing mapped
	   file information might be the best we can do, but there are
	   certainly cases this will get wrong, e.g. if an inferior created
	   a zero initialised mapping over the top of some data that exists
	   within the executable then this will return the executable data
	   rather than the zero data.  Maybe we should just drop this
	   block?  */
	if (m_core_file_mappings.empty ()
	    && m_core_unavailable_mappings.empty ())
	  {
	    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 (current_program_space->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 (current_program_space->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 (current_program_space->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 (current_program_space->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;
	    }
	}
      return TARGET_XFER_E_IO;

    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;
	    }
	}
      return TARGET_XFER_E_IO;

    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 ()
{
  /* First check whether the target wants us to use the corefile target
     description notes.  */
  if (gdbarch_use_target_description_from_corefile_notes
	(m_core_gdbarch, current_program_space->core_bfd ()))
    {
      /* If the core file contains a target description note then go ahead and
	 use that.  */
      bfd_size_type tdesc_note_size = 0;
      struct bfd_section *tdesc_note_section
	= bfd_get_section_by_name (current_program_space->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 (current_program_space->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 the architecture provides a corefile target description hook, use
     it now.  Even if the core file contains a target description in a note
     section, it is not useful for targets that can potentially have distinct
     descriptions for each thread.  One example is AArch64's SVE/SME
     extensions that allow per-thread vector length changes, resulting in
     registers with different sizes.  */
  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, current_program_space->core_bfd ());
      if (result != nullptr)
	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 current_program_space->core_bfd () != nullptr;
}

bool
core_target::has_stack ()
{
  return current_program_space->core_bfd () != nullptr;
}

bool
core_target::has_registers ()
{
  return current_program_space->core_bfd () != nullptr;
}

/* 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;
}

/* Implementation of the "supports_memory_tagging" target_ops method.  */

bool
core_target::supports_memory_tagging ()
{
  /* Look for memory tag sections.  If they exist, that means this core file
     supports memory tagging.  */

  return (bfd_get_section_by_name (current_program_space->core_bfd (), "memtag")
	  != nullptr);
}

/* Implementation of the "fetch_memtags" target_ops method.  */

bool
core_target::fetch_memtags (CORE_ADDR address, size_t len,
			    gdb::byte_vector &tags, int type)
{
  gdbarch *gdbarch = current_inferior ()->arch ();

  /* Make sure we have a way to decode the memory tag notes.  */
  if (!gdbarch_decode_memtag_section_p (gdbarch))
    error (_("gdbarch_decode_memtag_section not implemented for this "
	     "architecture."));

  memtag_section_info info;
  info.memtag_section = nullptr;

  while (get_next_core_memtag_section (current_program_space->core_bfd (),
				       info.memtag_section, address, info))
  {
    size_t adjusted_length
      = (address + len < info.end_address) ? len : (info.end_address - address);

    /* Decode the memory tag note and return the tags.  */
    gdb::byte_vector tags_read
      = gdbarch_decode_memtag_section (gdbarch, info.memtag_section, type,
				       address, adjusted_length);

    /* Transfer over the tags that have been read.  */
    tags.insert (tags.end (), tags_read.begin (), tags_read.end ());

    /* ADDRESS + LEN may cross the boundaries of a particular memory tag
       segment.  Check if we need to fetch tags from a different section.  */
    if (!tags_read.empty () && (address + len) < info.end_address)
      return true;

    /* There are more tags to fetch.  Update ADDRESS and LEN.  */
    len -= (info.end_address - address);
    address = info.end_address;
  }

  return false;
}

bool
core_target::is_address_tagged (gdbarch *gdbarch, CORE_ADDR address)
{
  return gdbarch_tagged_address_p (gdbarch, address);
}

/* Implementation of the "fetch_x86_xsave_layout" target_ops method.  */

x86_xsave_layout
core_target::fetch_x86_xsave_layout ()
{
  if (m_core_gdbarch != nullptr &&
      gdbarch_core_read_x86_xsave_layout_p (m_core_gdbarch))
    {
      x86_xsave_layout layout;
      if (!gdbarch_core_read_x86_xsave_layout (m_core_gdbarch, layout))
	return {};

      return layout;
    }

  return {};
}

/* 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 ())
    return;

  gdb_printf (_("Mapped address spaces:\n\n"));
  ui_out_emit_table emitter (current_uiout, 5, -1, "ProcMappings");

  int width = gdbarch_addr_bit (gdbarch) == 32 ? 10 : 18;
  current_uiout->table_header (width, ui_left, "start", "Start Addr");
  current_uiout->table_header (width, ui_left, "end", "End Addr");
  current_uiout->table_header (width, ui_left, "size", "Size");
  current_uiout->table_header (width, ui_left, "offset", "Offset");
  current_uiout->table_header (0, ui_left, "objfile", "File");
  current_uiout->table_body ();

  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);

      ui_out_emit_tuple tuple_emitter (current_uiout, nullptr);
      current_uiout->field_core_addr ("start", gdbarch, start);
      current_uiout->field_core_addr ("end", gdbarch, end);
      /* These next two aren't really addresses and so shouldn't be
	 styled as such.  */
      current_uiout->field_string ("size", paddress (gdbarch, end - start));
      current_uiout->field_string ("offset", paddress (gdbarch, file_ofs));
      current_uiout->field_string ("objfile", filename,
				   file_name_style.style ());
      current_uiout->text ("\n");
    }
}

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

/* Add more details discovered while processing the core-file's mapped file
   information, we're building maps between filenames and the corresponding
   build-ids, between address ranges and the corresponding build-ids, and
   also a reverse map between build-id and the corresponding filename.

   SONAME is the DT_SONAME attribute extracted from the .dynamic section of
   a shared library that was mapped into the core file.  This can be
   nullptr if the mapped files was not a shared library, or didn't have a
   DT_SONAME attribute.

   EXPECTED_FILENAME is the name of the file that was mapped into the
   inferior as extracted from the core file, this should never be nullptr.

   ACTUAL_FILENAME is the name of the actual file GDB found to provide the
   mapped file information, this can be nullptr if GDB failed to find a
   suitable file.  This might be different to EXPECTED_FILENAME, e.g. GDB
   might have downloaded the file from debuginfod and so ACTUAL_FILENAME
   will be a file in the debuginfod client cache.

   RANGES is the list of memory ranges at which this file was mapped into
   the inferior.

   BUILD_ID is the build-id for this mapped file, this will never be
   nullptr.  Not every mapped file will have a build-id, but there's no
   point calling this function if we failed to find a build-id; this
   structure only exists so we can lookup files based on their build-id.  */

void
mapped_file_info::add (const char *soname,
		       const char *expected_filename,
		       const char *actual_filename,
		       std::vector<mem_range> &&ranges,
		       const bfd_build_id *build_id)
{
  gdb_assert (build_id != nullptr);
  gdb_assert (expected_filename != nullptr);

  if (soname != nullptr)
    {
      /* If we already have an entry with this SONAME then this indicates
	 that the inferior has two files mapped into memory with different
	 file names (and most likely different build-ids), but with the
	 same DT_SONAME attribute.  In this case we can't use the
	 DT_SONAME to figure out the expected build-id of a shared
	 library, so poison the entry for this SONAME by setting the entry
	 to nullptr.  */
      auto it = m_soname_to_build_id_map.find (soname);
      if (it != m_soname_to_build_id_map.end ()
	  && it->second != nullptr
	  && !build_id_equal (it->second, build_id))
	m_soname_to_build_id_map[soname] = nullptr;
      else
	m_soname_to_build_id_map[soname] = build_id;
    }

  /* When the core file is initially opened and the mapped files are
     parsed, we group the build-id information based on the file name.  As
     a consequence, we should see each EXPECTED_FILENAME value exactly
     once.  This means that each insertion should always succeed.  */
  const auto inserted
    = m_filename_to_build_id_map.emplace (expected_filename, build_id).second;
  gdb_assert (inserted);

  /* Setup the reverse build-id to file name map.  */
  if (actual_filename != nullptr)
    m_build_id_to_filename_map.emplace (build_id, actual_filename);

  /* Setup the list of memory range to build-id objects.  */
  for (mem_range &r : ranges)
    m_address_to_build_id_list.emplace_back (std::move (r), build_id);

  /* At this point the m_address_to_build_id_list is unsorted (we just
     added some entries to the end of the list).  All entries should be
     added before any look-ups are performed, and the list is only sorted
     when the first look-up is performed.  */
  gdb_assert (!m_address_to_build_id_list_sorted);
}

/* FILENAME is the name of a file GDB is trying to load, and ADDR is
   (optionally) an address within the file in the inferior's address space.

   Search through the information gathered from the core-file's mapped file
   information looking for a file named FILENAME, or for a file that covers
   ADDR.  If a match is found then return the build-id for the file along
   with the location where GDB found the mapped file.

   The location of the mapped file might be the empty string if GDB was
   unable to find the mapped file.

   If no build-id can be found for FILENAME then GDB will return a pair
   containing nullptr (for the build-id) and an empty string for the file
   name.  */

std::optional <core_target_mapped_file_info>
mapped_file_info::lookup (const char *filename,
			  const std::optional<CORE_ADDR> &addr)
{
  if (filename != nullptr)
    {
      /* If there's a matching entry in m_filename_to_build_id_map then the
	 associated build-id will not be nullptr, and can be used to
	 validate that FILENAME is correct.  */
      auto it = m_filename_to_build_id_map.find (filename);
      if (it != m_filename_to_build_id_map.end ())
	return make_result (it->second);
    }

  if (addr.has_value ())
    {
      /* On the first lookup, sort the address_to_build_id_list.  */
      if (!m_address_to_build_id_list_sorted)
	{
	  std::sort (m_address_to_build_id_list.begin (),
		     m_address_to_build_id_list.end (),
		     [] (const mem_range_and_build_id &a,
			 const mem_range_and_build_id &b) {
		       return a.range < b.range;
		     });
	  m_address_to_build_id_list_sorted = true;
	}

      /* Look for the first entry whose range's start address is not less
	 than, or equal too, the address ADDR.  If we find such an entry,
	 then the previous entry's range might contain ADDR.  If it does
	 then that previous entry's build-id can be used.  */
      auto it = std::lower_bound
	(m_address_to_build_id_list.begin (),
	 m_address_to_build_id_list.end (),
	 *addr,
	 [] (const mem_range_and_build_id &a,
	     const CORE_ADDR &b) {
	  return a.range.start <= b;
	});

      if (it != m_address_to_build_id_list.begin ())
	{
	  --it;

	  if (it->range.contains (*addr))
	    return make_result (it->build_id);
	}
    }

  if (filename != nullptr)
    {
      /* If the basename of FILENAME appears in m_soname_to_build_id_map
	 then when the mapped files were processed, we saw a file with a
	 DT_SONAME attribute corresponding to FILENAME, use that build-id
	 to validate FILENAME.

	 However, the build-id in this map might be nullptr if we saw
	 multiple mapped files with the same DT_SONAME attribute (though
	 this should be pretty rare).  */
      auto it
	= m_soname_to_build_id_map.find (lbasename (filename));
      if (it != m_soname_to_build_id_map.end ()
	  && it->second != nullptr)
	return make_result (it->second);
    }

  return {};
}

/* See gdbcore.h.  */

std::optional <core_target_mapped_file_info>
core_target_find_mapped_file (const char *filename,
			      std::optional<CORE_ADDR> addr)
{
  core_target *targ = get_current_core_target ();
  if (targ == nullptr || current_program_space->cbfd.get () == nullptr)
    return {};

  return targ->lookup_mapped_file_info (filename, addr);
}

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