/* Common code for targets with the none ABI (bare-metal), but where the
   BFD library is build with ELF support.

   Copyright (C) 2020-2021 Free Software Foundation, Inc.

   This file is part of GDB.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 3 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */

#include "defs.h"
#include "elf-none-tdep.h"
#include "regset.h"
#include "elf-bfd.h"            /* for elfcore_write_* */
#include "inferior.h"
#include "regcache.h"
#include "gdbarch.h"
#include "gcore.h"
#include "gcore-elf.h"

/* Build the note section for a corefile, and return it in a malloc
   buffer.  Currently this just dumps all available registers for each
   thread.  */

static gdb::unique_xmalloc_ptr<char>
elf_none_make_corefile_notes (struct gdbarch *gdbarch, bfd *obfd,
			      int *note_size)
{
  gdb::unique_xmalloc_ptr<char> note_data;

  /* Add note information about the executable and its arguments.  */
  std::string fname;
  std::string psargs;
  static const size_t fname_len = 16;
  static const size_t psargs_len = 80;
  if (get_exec_file (0))
    {
      const char *exe = get_exec_file (0);
      fname = lbasename (exe);
      psargs = std::string (exe);

      const char *infargs = get_inferior_args ();
      if (infargs != nullptr)
	psargs += " " + std::string (infargs);

      /* All existing targets that handle writing out prpsinfo expect the
	 fname and psargs strings to be at least 16 and 80 characters long
	 respectively, including a null terminator at the end.  Resize to
	 the expected length minus one to ensure there is a null within the
	 required length.  */
      fname.resize (fname_len - 1);
      psargs.resize (psargs_len - 1);
    }

  /* Resize the buffers up to their required lengths.  This will fill any
     remaining space with the null character.  */
  fname.resize (fname_len);
  psargs.resize (psargs_len);

  /* Now write out the prpsinfo structure.  */
  note_data.reset (elfcore_write_prpsinfo (obfd, note_data.release (),
					   note_size, fname.c_str (),
					   psargs.c_str ()));
  if (note_data == nullptr)
    return nullptr;

  /* Thread register information.  */
  try
    {
      update_thread_list ();
    }
  catch (const gdb_exception_error &e)
    {
      exception_print (gdb_stderr, e);
    }

  /* Like the Linux kernel, prefer dumping the signalled thread first.
     "First thread" is what tools use to infer the signalled thread.  */
  thread_info *signalled_thr = gcore_find_signalled_thread ();

  /* All threads are reported as having been stopped by the same signal
     that stopped SIGNALLED_THR.  */
  gdb_signal stop_signal;
  if (signalled_thr != nullptr)
    stop_signal = signalled_thr->suspend.stop_signal;
  else
    stop_signal = GDB_SIGNAL_0;

  if (signalled_thr != nullptr)
    gcore_elf_build_thread_register_notes (gdbarch, signalled_thr,
					   stop_signal, obfd, &note_data,
					   note_size);
  for (thread_info *thr : current_inferior ()->non_exited_threads ())
    {
      if (thr == signalled_thr)
	continue;

      gcore_elf_build_thread_register_notes (gdbarch, thr, stop_signal, obfd,
					     &note_data, note_size);
    }


  /* Target description.  */
  gcore_elf_make_tdesc_note (obfd, &note_data, note_size);

  return note_data;
}

/* See none-tdep.h.  */

void
elf_none_init_abi (struct gdbarch *gdbarch)
{
  /* Default core file support.  */
  set_gdbarch_make_corefile_notes (gdbarch, elf_none_make_corefile_notes);
}
