/* 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 std::string &infargs = current_inferior ()->args ();
      if (!infargs.empty ())
	psargs += ' ' + 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->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);
}
