/* Generate a core file for the inferior process.

   Copyright (C) 2001-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 "defs.h"
#include "elf-bfd.h"
#include "infcall.h"
#include "inferior.h"
#include "gdbcore.h"
#include "objfiles.h"
#include "solib.h"
#include "symfile.h"
#include "arch-utils.h"
#include "completer.h"
#include "gcore.h"
#include "cli/cli-decode.h"
#include <fcntl.h>
#include "regcache.h"
#include "regset.h"
#include "gdb_bfd.h"
#include "readline/tilde.h"
#include <algorithm>
#include "gdbsupport/gdb_unlinker.h"
#include "gdbsupport/byte-vector.h"
#include "gdbsupport/scope-exit.h"

/* To generate sparse cores, we look at the data to write in chunks of
   this size when considering whether to skip the write.  Only if we
   have a full block of this size with all zeros do we skip writing
   it.  A simpler algorithm that would try to skip all zeros would
   result in potentially many more write/lseek syscalls, as normal
   data is typically sprinkled with many small holes of zeros.  Also,
   it's much more efficient to memcmp a block of data against an
   all-zero buffer than to check each and every data byte against zero
   one by one.  */
#define SPARSE_BLOCK_SIZE 0x1000

/* The largest amount of memory to read from the target at once.  We
   must throttle it to limit the amount of memory used by GDB during
   generate-core-file for programs with large resident data.  */
#define MAX_COPY_BYTES (256 * SPARSE_BLOCK_SIZE)

static const char *default_gcore_target (void);
static enum bfd_architecture default_gcore_arch (void);
static int gcore_memory_sections (bfd *);

/* create_gcore_bfd -- helper for gcore_command (exported).
   Open a new bfd core file for output, and return the handle.  */

gdb_bfd_ref_ptr
create_gcore_bfd (const char *filename)
{
  gdb_bfd_ref_ptr obfd (gdb_bfd_openw (filename, default_gcore_target ()));

  if (obfd == NULL)
    error (_("Failed to open '%s' for output."), filename);
  bfd_set_format (obfd.get (), bfd_core);
  bfd_set_arch_mach (obfd.get (), default_gcore_arch (), 0);
  return obfd;
}

/* write_gcore_file_1 -- do the actual work of write_gcore_file.  */

static void
write_gcore_file_1 (bfd *obfd)
{
  gdb::unique_xmalloc_ptr<char> note_data;
  int note_size = 0;
  asection *note_sec = NULL;
  gdbarch *arch = current_inferior ()->arch ();

  /* An external target method must build the notes section.  */
  /* FIXME: uweigand/2011-10-06: All architectures that support core file
     generation should be converted to gdbarch_make_corefile_notes; at that
     point, the target vector method can be removed.  */
  if (!gdbarch_make_corefile_notes_p (arch))
    note_data = target_make_corefile_notes (obfd, &note_size);
  else
    note_data = gdbarch_make_corefile_notes (arch, obfd, &note_size);

  if (note_data == NULL || note_size == 0)
    error (_("Target does not support core file generation."));

  /* Create the note section.  */
  note_sec = bfd_make_section_anyway_with_flags (obfd, "note0",
						 SEC_HAS_CONTENTS
						 | SEC_READONLY
						 | SEC_ALLOC);
  if (note_sec == NULL)
    error (_("Failed to create 'note' section for corefile: %s"),
	   bfd_errmsg (bfd_get_error ()));

  bfd_set_section_vma (note_sec, 0);
  bfd_set_section_alignment (note_sec, 0);
  bfd_set_section_size (note_sec, note_size);

  /* Now create the memory/load sections.  Note
     gcore_memory_sections's sparse logic is assuming that we'll
     always write something afterwards, which we do: just below, we
     write the note section.  So there's no need for an ftruncate-like
     call to grow the file to the right size if the last memory
     sections were zeros and we skipped writing them.  */
  if (gcore_memory_sections (obfd) == 0)
    error (_("gcore: failed to get corefile memory sections from target."));

  /* Write out the contents of the note section.  */
  if (!bfd_set_section_contents (obfd, note_sec, note_data.get (), 0,
				 note_size))
    warning (_("writing note section (%s)"), bfd_errmsg (bfd_get_error ()));
}

/* write_gcore_file -- helper for gcore_command (exported).
   Compose and write the corefile data to the core file.  */

void
write_gcore_file (bfd *obfd)
{
  target_prepare_to_generate_core ();
  SCOPE_EXIT { target_done_generating_core (); };
  write_gcore_file_1 (obfd);
}

/* gcore_command -- implements the 'gcore' command.
   Generate a core file from the inferior process.  */

static void
gcore_command (const char *args, int from_tty)
{
  gdb::unique_xmalloc_ptr<char> corefilename;

  /* No use generating a corefile without a target process.  */
  if (!target_has_execution ())
    noprocess ();

  if (args && *args)
    corefilename.reset (tilde_expand (args));
  else
    {
      /* Default corefile name is "core.PID".  */
      corefilename = xstrprintf ("core.%d", inferior_ptid.pid ());
    }

  if (info_verbose)
    gdb_printf ("Opening corefile '%s' for output.\n",
		corefilename.get ());

  if (target_supports_dumpcore ())
    target_dumpcore (corefilename.get ());
  else
    {
      /* Open the output file.  */
      gdb_bfd_ref_ptr obfd (create_gcore_bfd (corefilename.get ()));

      /* Arrange to unlink the file on failure.  */
      gdb::unlinker unlink_file (corefilename.get ());

      /* Call worker function.  */
      write_gcore_file (obfd.get ());

      /* Succeeded.  */
      unlink_file.keep ();
    }

  gdb_printf ("Saved corefile %s\n", corefilename.get ());
}

static enum bfd_architecture
default_gcore_arch (void)
{
  const bfd_arch_info *bfdarch
    = gdbarch_bfd_arch_info (current_inferior ()->arch ());

  if (bfdarch != NULL)
    return bfdarch->arch;
  if (current_program_space->exec_bfd () == NULL)
    error (_("Can't find bfd architecture for corefile (need execfile)."));

  return bfd_get_arch (current_program_space->exec_bfd ());
}

static const char *
default_gcore_target (void)
{
  gdbarch *arch = current_inferior ()->arch ();
  /* The gdbarch may define a target to use for core files.  */
  if (gdbarch_gcore_bfd_target_p (arch))
    return gdbarch_gcore_bfd_target (arch);

  /* Otherwise, try to fall back to the exec target.  This will probably
     not work for non-ELF targets.  */
  if (current_program_space->exec_bfd () == NULL)
    return NULL;
  else
    return bfd_get_target (current_program_space->exec_bfd ());
}

/* Derive a reasonable stack segment by unwinding the target stack,
   and store its limits in *BOTTOM and *TOP.  Return non-zero if
   successful.  */

static int
derive_stack_segment (bfd_vma *bottom, bfd_vma *top)
{
  frame_info_ptr fi, tmp_fi;

  gdb_assert (bottom);
  gdb_assert (top);

  /* Can't succeed without stack and registers.  */
  if (!target_has_stack () || !target_has_registers ())
    return 0;

  /* Can't succeed without current frame.  */
  fi = get_current_frame ();
  if (fi == NULL)
    return 0;

  /* Save frame pointer of TOS frame.  */
  *top = get_frame_base (fi);
  /* If current stack pointer is more "inner", use that instead.  */
  if (gdbarch_inner_than (get_frame_arch (fi), get_frame_sp (fi), *top))
    *top = get_frame_sp (fi);

  /* Find prev-most frame.  */
  while ((tmp_fi = get_prev_frame (fi)) != NULL)
    fi = tmp_fi;

  /* Save frame pointer of prev-most frame.  */
  *bottom = get_frame_base (fi);

  /* Now canonicalize their order, so that BOTTOM is a lower address
     (as opposed to a lower stack frame).  */
  if (*bottom > *top)
    {
      bfd_vma tmp_vma;

      tmp_vma = *top;
      *top = *bottom;
      *bottom = tmp_vma;
    }

  return 1;
}

/* call_target_sbrk --
   helper function for derive_heap_segment.  */

static bfd_vma
call_target_sbrk (int sbrk_arg)
{
  struct objfile *sbrk_objf;
  struct gdbarch *gdbarch;
  bfd_vma top_of_heap;
  struct value *target_sbrk_arg;
  struct value *sbrk_fn, *ret;
  bfd_vma tmp;

  if (lookup_minimal_symbol ("sbrk", NULL, NULL).minsym != NULL)
    {
      sbrk_fn = find_function_in_inferior ("sbrk", &sbrk_objf);
      if (sbrk_fn == NULL)
	return (bfd_vma) 0;
    }
  else if (lookup_minimal_symbol ("_sbrk", NULL, NULL).minsym != NULL)
    {
      sbrk_fn = find_function_in_inferior ("_sbrk", &sbrk_objf);
      if (sbrk_fn == NULL)
	return (bfd_vma) 0;
    }
  else
    return (bfd_vma) 0;

  gdbarch = sbrk_objf->arch ();
  target_sbrk_arg = value_from_longest (builtin_type (gdbarch)->builtin_int, 
					sbrk_arg);
  gdb_assert (target_sbrk_arg);
  ret = call_function_by_hand (sbrk_fn, NULL, target_sbrk_arg);
  if (ret == NULL)
    return (bfd_vma) 0;

  tmp = value_as_long (ret);
  if ((LONGEST) tmp <= 0 || (LONGEST) tmp == 0xffffffff)
    return (bfd_vma) 0;

  top_of_heap = tmp;
  return top_of_heap;
}

/* Derive a reasonable heap segment for ABFD by looking at sbrk and
   the static data sections.  Store its limits in *BOTTOM and *TOP.
   Return non-zero if successful.  */

static int
derive_heap_segment (bfd *abfd, bfd_vma *bottom, bfd_vma *top)
{
  bfd_vma top_of_data_memory = 0;
  bfd_vma top_of_heap = 0;
  bfd_size_type sec_size;
  bfd_vma sec_vaddr;
  asection *sec;

  gdb_assert (bottom);
  gdb_assert (top);

  /* This function depends on being able to call a function in the
     inferior.  */
  if (!target_has_execution ())
    return 0;

  /* The following code assumes that the link map is arranged as
     follows (low to high addresses):

     ---------------------------------
     | text sections                 |
     ---------------------------------
     | data sections (including bss) |
     ---------------------------------
     | heap                          |
     --------------------------------- */

  for (sec = abfd->sections; sec; sec = sec->next)
    {
      if (bfd_section_flags (sec) & SEC_DATA
	  || strcmp (".bss", bfd_section_name (sec)) == 0)
	{
	  sec_vaddr = bfd_section_vma (sec);
	  sec_size = bfd_section_size (sec);
	  if (sec_vaddr + sec_size > top_of_data_memory)
	    top_of_data_memory = sec_vaddr + sec_size;
	}
    }

  top_of_heap = call_target_sbrk (0);
  if (top_of_heap == (bfd_vma) 0)
    return 0;

  /* Return results.  */
  if (top_of_heap > top_of_data_memory)
    {
      *bottom = top_of_data_memory;
      *top = top_of_heap;
      return 1;
    }

  /* No additional heap space needs to be saved.  */
  return 0;
}

static void
make_output_phdrs (bfd *obfd, asection *osec)
{
  int p_flags = 0;
  int p_type = 0;

  /* Memory tag segments have already been handled by the architecture, as
     those contain arch-specific information.  If we have one of those, just
     return.  */
  if (startswith (bfd_section_name (osec), "memtag"))
    return;

  /* FIXME: these constants may only be applicable for ELF.  */
  if (startswith (bfd_section_name (osec), "load"))
    p_type = PT_LOAD;
  else if (startswith (bfd_section_name (osec), "note"))
    p_type = PT_NOTE;
  else
    p_type = PT_NULL;

  p_flags |= PF_R;	/* Segment is readable.  */
  if (!(bfd_section_flags (osec) & SEC_READONLY))
    p_flags |= PF_W;	/* Segment is writable.  */
  if (bfd_section_flags (osec) & SEC_CODE)
    p_flags |= PF_X;	/* Segment is executable.  */

  bfd_record_phdr (obfd, p_type, 1, p_flags, 0, 0, 0, 0, 1, &osec);
}

/* find_memory_region_ftype implementation.

   MEMORY_TAGGED is true if the memory region contains memory tags, false
   otherwise.

   DATA is 'bfd *' for the core file GDB is creating.  */

static int
gcore_create_callback (CORE_ADDR vaddr, unsigned long size, int read,
		       int write, int exec, int modified, bool memory_tagged,
		       void *data)
{
  bfd *obfd = (bfd *) data;
  asection *osec;
  flagword flags = SEC_ALLOC | SEC_HAS_CONTENTS | SEC_LOAD;

  /* If the memory segment has no permissions set, ignore it, otherwise
     when we later try to access it for read/write, we'll get an error
     or jam the kernel.  */
  if (read == 0 && write == 0 && exec == 0 && modified == 0)
    {
      if (info_verbose)
	gdb_printf ("Ignore segment, %s bytes at %s\n",
		    plongest (size), paddress (current_inferior ()->arch (),
		    vaddr));

      return 0;
    }

  if (write == 0 && modified == 0 && !solib_keep_data_in_core (vaddr, size))
    {
      /* See if this region of memory lies inside a known file on disk.
	 If so, we can avoid copying its contents by clearing SEC_LOAD.  */

      for (objfile *objfile : current_program_space->objfiles ())
	for (obj_section *objsec : objfile->sections ())
	  {
	    bfd *abfd = objfile->obfd.get ();
	    asection *asec = objsec->the_bfd_section;
	    bfd_vma align = (bfd_vma) 1 << bfd_section_alignment (asec);
	    bfd_vma start = objsec->addr () & -align;
	    bfd_vma end = (objsec->endaddr () + align - 1) & -align;

	    /* Match if either the entire memory region lies inside the
	       section (i.e. a mapping covering some pages of a large
	       segment) or the entire section lies inside the memory region
	       (i.e. a mapping covering multiple small sections).

	       This BFD was synthesized from reading target memory,
	       we don't want to omit that.  */
	    if (objfile->separate_debug_objfile_backlink == NULL
		&& ((vaddr >= start && vaddr + size <= end)
		    || (start >= vaddr && end <= vaddr + size))
		&& !(bfd_get_file_flags (abfd) & BFD_IN_MEMORY))
	      {
		flags &= ~(SEC_LOAD | SEC_HAS_CONTENTS);
		goto keep;	/* Break out of two nested for loops.  */
	      }
	  }

    keep:;
    }

  if (write == 0)
    flags |= SEC_READONLY;

  if (exec)
    flags |= SEC_CODE;
  else
    flags |= SEC_DATA;

  osec = bfd_make_section_anyway_with_flags (obfd, "load", flags);
  if (osec == NULL)
    {
      warning (_("Couldn't make gcore segment: %s"),
	       bfd_errmsg (bfd_get_error ()));
      return 1;
    }

  if (info_verbose)
    gdb_printf ("Save segment, %s bytes at %s\n",
		plongest (size), paddress (current_inferior ()->arch (),
		vaddr));

  bfd_set_section_size (osec, size);
  bfd_set_section_vma (osec, vaddr);
  bfd_set_section_lma (osec, 0);
  return 0;
}

/* gdbarch_find_memory_region callback for creating a memory tag section.

   MEMORY_TAGGED is true if the memory region contains memory tags, false
   otherwise.

   DATA is 'bfd *' for the core file GDB is creating.  */

static int
gcore_create_memtag_section_callback (CORE_ADDR vaddr, unsigned long size,
				      int read, int write, int exec,
				      int modified, bool memory_tagged,
				      void *data)
{
  /* Are there memory tags in this particular memory map entry?  */
  if (!memory_tagged)
    return 0;

  bfd *obfd = (bfd *) data;

  /* Ask the architecture to create a memory tag section for this particular
     memory map entry.  It will be populated with contents later, as we can't
     start writing the contents before we have all the sections sorted out.  */
  gdbarch *arch = current_inferior ()->arch ();
  asection *memtag_section
    = gdbarch_create_memtag_section (arch, obfd, vaddr, size);

  if (memtag_section == nullptr)
    {
      warning (_("Couldn't make gcore memory tag segment: %s"),
	       bfd_errmsg (bfd_get_error ()));
      return 1;
    }

  if (info_verbose)
    {
      gdb_printf (gdb_stdout, "Saved memory tag segment, %s bytes "
			      "at %s\n",
		  plongest (bfd_section_size (memtag_section)),
		  paddress (arch, vaddr));
    }

  return 0;
}

int
objfile_find_memory_regions (struct target_ops *self,
			     find_memory_region_ftype func, void *obfd)
{
  /* Use objfile data to create memory sections.  */
  bfd_vma temp_bottom, temp_top;

  /* Call callback function for each objfile section.  */
  for (objfile *objfile : current_program_space->objfiles ())
    for (obj_section *objsec : objfile->sections ())
      {
	asection *isec = objsec->the_bfd_section;
	flagword flags = bfd_section_flags (isec);

	/* Separate debug info files are irrelevant for gcore.  */
	if (objfile->separate_debug_objfile_backlink != NULL)
	  continue;

	if ((flags & SEC_ALLOC) || (flags & SEC_LOAD))
	  {
	    int size = bfd_section_size (isec);
	    int ret;

	    ret = (*func) (objsec->addr (), size,
			   1, /* All sections will be readable.  */
			   (flags & SEC_READONLY) == 0, /* Writable.  */
			   (flags & SEC_CODE) != 0, /* Executable.  */
			   1, /* MODIFIED is unknown, pass it as true.  */
			   false, /* No memory tags in the object file.  */
			   obfd);
	    if (ret != 0)
	      return ret;
	  }
      }

  /* Make a stack segment.  */
  if (derive_stack_segment (&temp_bottom, &temp_top))
    (*func) (temp_bottom, temp_top - temp_bottom,
	     1, /* Stack section will be readable.  */
	     1, /* Stack section will be writable.  */
	     0, /* Stack section will not be executable.  */
	     1, /* Stack section will be modified.  */
	     false, /* No memory tags in the object file.  */
	     obfd);

  /* Make a heap segment.  */
  if (derive_heap_segment (current_program_space->exec_bfd (), &temp_bottom,
			   &temp_top))
    (*func) (temp_bottom, temp_top - temp_bottom,
	     1, /* Heap section will be readable.  */
	     1, /* Heap section will be writable.  */
	     0, /* Heap section will not be executable.  */
	     1, /* Heap section will be modified.  */
	     false, /* No memory tags in the object file.  */
	     obfd);

  return 0;
}

/* Check if we have a block full of zeros at DATA within the [DATA,
   DATA+SIZE) buffer.  Returns the size of the all-zero block found.
   Returns at most the minimum between SIZE and SPARSE_BLOCK_SIZE.  */

static size_t
get_all_zero_block_size (const gdb_byte *data, size_t size)
{
  size = std::min (size, (size_t) SPARSE_BLOCK_SIZE);

  /* A memcmp of a whole block is much faster than a simple for loop.
     This makes a big difference, as with a for loop, this code would
     dominate the performance and result in doubling the time to
     generate a core, at the time of writing.  With an optimized
     memcmp, this doesn't even show up in the perf trace.  */
  static const gdb_byte all_zero_block[SPARSE_BLOCK_SIZE] = {};
  if (memcmp (data, all_zero_block, size) == 0)
    return size;
  return 0;
}

/* Basically a named-elements pair, used as return type of
   find_next_all_zero_block.  */

struct offset_and_size
{
  size_t offset;
  size_t size;
};

/* Find the next all-zero block at DATA+OFFSET within the [DATA,
   DATA+SIZE) buffer.  Returns the offset and the size of the all-zero
   block if found, or zero if not found.  */

static offset_and_size
find_next_all_zero_block (const gdb_byte *data, size_t offset, size_t size)
{
  for (; offset < size; offset += SPARSE_BLOCK_SIZE)
    {
      size_t zero_block_size
	= get_all_zero_block_size (data + offset, size - offset);
      if (zero_block_size != 0)
	return {offset, zero_block_size};
    }
  return {0, 0};
}

/* Wrapper around bfd_set_section_contents that avoids writing
   all-zero blocks to disk, so we create a sparse core file.
   SKIP_ALIGN is a recursion helper -- if true, we'll skip aligning
   the file position to SPARSE_BLOCK_SIZE.  */

static bool
sparse_bfd_set_section_contents (bfd *obfd, asection *osec,
				 const gdb_byte *data,
				 size_t sec_offset,
				 size_t size,
				 bool skip_align = false)
{
  /* Note, we don't have to have special handling for the case of the
     last memory region ending with zeros, because our caller always
     writes out the note section after the memory/load sections.  If
     it didn't, we'd have to seek+write the last byte to make the file
     size correct.  (Or add an ftruncate abstraction to bfd and call
     that.)  */

  if (size == 0)
    return true;

  size_t data_offset = 0;

  if (!skip_align)
    {
      /* Align the all-zero block search with SPARSE_BLOCK_SIZE, to
	 better align with filesystem blocks.  If we find we're
	 misaligned, then write/skip the bytes needed to make us
	 aligned.  We do that with (one level) recursion.  */

      /* We need to know the section's file offset on disk.  We can
	 only look at it after the bfd's 'output_has_begun' flag has
	 been set, as bfd hasn't computed the file offsets
	 otherwise.  */
      if (!obfd->output_has_begun)
	{
	  gdb_byte dummy = 0;

	  /* A write forces BFD to compute the bfd's section file
	     positions.  Zero size works for that too.  */
	  if (!bfd_set_section_contents (obfd, osec, &dummy, 0, 0))
	    return false;

	  gdb_assert (obfd->output_has_begun);
	}

      /* How much after the last aligned offset are we writing at.  */
      size_t aligned_offset_remainder
	= (osec->filepos + sec_offset) % SPARSE_BLOCK_SIZE;

      /* Do we need to align?  */
      if (aligned_offset_remainder != 0)
	{
	  /* How much we need to advance in order to find the next
	     SPARSE_BLOCK_SIZE filepos-aligned block.  */
	  size_t distance_to_next_aligned
	    = SPARSE_BLOCK_SIZE - aligned_offset_remainder;

	  /* How much we'll actually write in the recursion call.  The
	     caller may want us to write fewer bytes than
	     DISTANCE_TO_NEXT_ALIGNED.  */
	  size_t align_write_size = std::min (size, distance_to_next_aligned);

	  /* Recurse, skipping the alignment code.  */
	  if (!sparse_bfd_set_section_contents (obfd, osec, data,
						sec_offset,
						align_write_size, true))
	    return false;

	  /* Skip over what we've written, and proceed with
	     assumes-aligned logic.  */
	  data_offset += align_write_size;
	}
    }

  while (data_offset < size)
    {
      size_t all_zero_block_size
	= get_all_zero_block_size (data + data_offset, size - data_offset);
      if (all_zero_block_size != 0)
	{
	  /* Skip writing all-zero blocks.  */
	  data_offset += all_zero_block_size;
	  continue;
	}

      /* We have some non-zero data to write to file.  Find the next
	 all-zero block within the data, and only write up to it.  */

      offset_and_size next_all_zero_block
	= find_next_all_zero_block (data,
				    data_offset + SPARSE_BLOCK_SIZE,
				    size);
      size_t next_data_offset = (next_all_zero_block.offset == 0
				 ? size
				 : next_all_zero_block.offset);

      if (!bfd_set_section_contents (obfd, osec, data + data_offset,
				     sec_offset + data_offset,
				     next_data_offset - data_offset))
	return false;

      data_offset = next_data_offset;

      /* If we already know we have an all-zero block at the next
	 offset, we can skip calling get_all_zero_block_size for
	 it again.  */
      if (next_all_zero_block.offset != 0)
	data_offset += next_all_zero_block.size;
    }

  return true;
}

static void
gcore_copy_callback (bfd *obfd, asection *osec)
{
  bfd_size_type size, total_size = bfd_section_size (osec);
  file_ptr offset = 0;

  /* Read-only sections are marked; we don't have to copy their contents.  */
  if ((bfd_section_flags (osec) & SEC_LOAD) == 0)
    return;

  /* Only interested in "load" sections.  */
  if (!startswith (bfd_section_name (osec), "load"))
    return;

  size = std::min (total_size, (bfd_size_type) MAX_COPY_BYTES);
  gdb::byte_vector memhunk (size);

  while (total_size > 0)
    {
      if (size > total_size)
	size = total_size;

      if (target_read_memory (bfd_section_vma (osec) + offset,
			      memhunk.data (), size) != 0)
	{
	  warning (_("Memory read failed for corefile "
		     "section, %s bytes at %s."),
		   plongest (size),
		   paddress (current_inferior ()->arch (),
			     bfd_section_vma (osec)));
	  break;
	}

      if (!sparse_bfd_set_section_contents (obfd, osec, memhunk.data (),
					    offset, size))
	{
	  warning (_("Failed to write corefile contents (%s)."),
		   bfd_errmsg (bfd_get_error ()));
	  break;
	}

      total_size -= size;
      offset += size;
    }
}

/* Callback to copy contents to a particular memory tag section.  */

static void
gcore_copy_memtag_section_callback (bfd *obfd, asection *osec)
{
  /* We are only interested in "memtag" sections.  */
  if (!startswith (bfd_section_name (osec), "memtag"))
    return;

  /* Fill the section with memory tag contents.  */
  if (!gdbarch_fill_memtag_section (current_inferior ()->arch (), osec))
    error (_("Failed to fill memory tag section for core file."));
}

static int
gcore_memory_sections (bfd *obfd)
{
  /* Try gdbarch method first, then fall back to target method.  */
  gdbarch *arch = current_inferior ()->arch ();
  if (!gdbarch_find_memory_regions_p (arch)
      || gdbarch_find_memory_regions (arch, gcore_create_callback, obfd) != 0)
    {
      if (target_find_memory_regions (gcore_create_callback, obfd) != 0)
	return 0;			/* FIXME: error return/msg?  */
    }

  /* Take care of dumping memory tags, if there are any.  */
  if (!gdbarch_find_memory_regions_p (arch)
      || gdbarch_find_memory_regions (arch, gcore_create_memtag_section_callback,
				      obfd) != 0)
    {
      if (target_find_memory_regions (gcore_create_memtag_section_callback,
				      obfd) != 0)
	return 0;
    }

  /* Record phdrs for section-to-segment mapping.  */
  for (asection *sect : gdb_bfd_sections (obfd))
    make_output_phdrs (obfd, sect);

  /* Copy memory region and memory tag contents.  */
  for (asection *sect : gdb_bfd_sections (obfd))
    {
      gcore_copy_callback (obfd, sect);
      gcore_copy_memtag_section_callback (obfd, sect);
    }

  return 1;
}

/* See gcore.h.  */

thread_info *
gcore_find_signalled_thread ()
{
  thread_info *curr_thr = inferior_thread ();
  if (curr_thr->state != THREAD_EXITED
      && curr_thr->stop_signal () != GDB_SIGNAL_0)
    return curr_thr;

  for (thread_info *thr : current_inferior ()->non_exited_threads ())
    if (thr->stop_signal () != GDB_SIGNAL_0)
      return thr;

  /* Default to the current thread, unless it has exited.  */
  if (curr_thr->state != THREAD_EXITED)
    return curr_thr;

  return nullptr;
}

void _initialize_gcore ();
void
_initialize_gcore ()
{
  cmd_list_element *generate_core_file_cmd
    = add_com ("generate-core-file", class_files, gcore_command, _("\
Save a core file with the current state of the debugged process.\n\
Usage: generate-core-file [FILENAME]\n\
Argument is optional filename.  Default filename is 'core.PROCESS_ID'."));

  add_com_alias ("gcore", generate_core_file_cmd, class_files, 1);
}
