/* Copyright (C) 2021-2022 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 "gcore-elf.h"
#include "elf-bfd.h"
#include "target.h"
#include "regcache.h"
#include "gdbarch.h"
#include "gdbthread.h"
#include "inferior.h"
#include "regset.h"
#include "gdbsupport/tdesc.h"

/* Structure for passing information from GCORE_COLLECT_THREAD_REGISTERS
   via an iterator to GCORE_COLLECT_REGSET_SECTION_CB. */

struct gcore_elf_collect_regset_section_cb_data
{
  gcore_elf_collect_regset_section_cb_data
	(struct gdbarch *gdbarch, const struct regcache *regcache,
	 bfd *obfd, ptid_t ptid, gdb_signal stop_signal,
	 gdb::unique_xmalloc_ptr<char> *note_data, int *note_size)
    : gdbarch (gdbarch), regcache (regcache), obfd (obfd),
      note_data (note_data), note_size (note_size),
      stop_signal (stop_signal)
  {
    /* The LWP is often not available for bare metal target, in which case
       use the tid instead.  */
    if (ptid.lwp_p ())
      lwp = ptid.lwp ();
    else
      lwp = ptid.tid ();
  }

  struct gdbarch *gdbarch;
  const struct regcache *regcache;
  bfd *obfd;
  gdb::unique_xmalloc_ptr<char> *note_data;
  int *note_size;
  unsigned long lwp;
  enum gdb_signal stop_signal;
  bool abort_iteration = false;
};

/* Callback for ITERATE_OVER_REGSET_SECTIONS that records a single
   regset in the core file note section.  */

static void
gcore_elf_collect_regset_section_cb (const char *sect_name,
				     int supply_size, int collect_size,
				     const struct regset *regset,
				     const char *human_name, void *cb_data)
{
  struct gcore_elf_collect_regset_section_cb_data *data
    = (struct gcore_elf_collect_regset_section_cb_data *) cb_data;
  bool variable_size_section = (regset != nullptr
				&& regset->flags & REGSET_VARIABLE_SIZE);

  gdb_assert (variable_size_section || supply_size == collect_size);

  if (data->abort_iteration)
    return;

  gdb_assert (regset != nullptr && regset->collect_regset != nullptr);

  /* This is intentionally zero-initialized by using std::vector, so
     that any padding bytes in the core file will show as 0.  */
  std::vector<gdb_byte> buf (collect_size);

  regset->collect_regset (regset, data->regcache, -1, buf.data (),
			  collect_size);

  /* PRSTATUS still needs to be treated specially.  */
  if (strcmp (sect_name, ".reg") == 0)
    data->note_data->reset (elfcore_write_prstatus
			    (data->obfd, data->note_data->release (),
			     data->note_size, data->lwp,
			     gdb_signal_to_host (data->stop_signal),
			     buf.data ()));
  else
    data->note_data->reset (elfcore_write_register_note
			    (data->obfd, data->note_data->release (),
			     data->note_size, sect_name, buf.data (),
			     collect_size));

  if (*data->note_data == nullptr)
    data->abort_iteration = true;
}

/* Records the register state of thread PTID out of REGCACHE into the note
   buffer represented by *NOTE_DATA and NOTE_SIZE.  OBFD is the bfd into
   which the core file is being created, and STOP_SIGNAL is the signal that
   cause thread PTID to stop.  */

static void
gcore_elf_collect_thread_registers
	(const struct regcache *regcache, ptid_t ptid, bfd *obfd,
	 gdb::unique_xmalloc_ptr<char> *note_data, int *note_size,
	 enum gdb_signal stop_signal)
{
  struct gdbarch *gdbarch = regcache->arch ();
  gcore_elf_collect_regset_section_cb_data data (gdbarch, regcache, obfd,
						 ptid, stop_signal,
						 note_data, note_size);
  gdbarch_iterate_over_regset_sections
    (gdbarch, gcore_elf_collect_regset_section_cb, &data, regcache);
}

/* See gcore-elf.h.  */

void
gcore_elf_build_thread_register_notes
  (struct gdbarch *gdbarch, struct thread_info *info, gdb_signal stop_signal,
   bfd *obfd, gdb::unique_xmalloc_ptr<char> *note_data, int *note_size)
{
  struct regcache *regcache
    = get_thread_arch_regcache (info->inf->process_target (),
				info->ptid, gdbarch);
  target_fetch_registers (regcache, -1);
  gcore_elf_collect_thread_registers (regcache, info->ptid, obfd,
				      note_data, note_size, stop_signal);
}

/* See gcore-elf.h.  */

void
gcore_elf_make_tdesc_note (bfd *obfd,
			   gdb::unique_xmalloc_ptr<char> *note_data,
			   int *note_size)
{
  /* Append the target description to the core file.  */
  const struct target_desc *tdesc = gdbarch_target_desc (target_gdbarch ());
  const char *tdesc_xml
    = tdesc == nullptr ? nullptr : tdesc_get_features_xml (tdesc);
  if (tdesc_xml != nullptr && *tdesc_xml != '\0')
    {
      /* Skip the leading '@'.  */
      if (*tdesc_xml == '@')
	++tdesc_xml;

      /* Include the null terminator in the length.  */
      size_t tdesc_len = strlen (tdesc_xml) + 1;

      /* Now add the target description into the core file.  */
      note_data->reset (elfcore_write_register_note (obfd,
						     note_data->release (),
						     note_size,
						     ".gdb-tdesc", tdesc_xml,
						     tdesc_len));
    }
}
