/* Target-dependent code for Fuchsia, architecture independent.

   Copyright (C) 2009-2016 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/>.  */

/* TODO: This is taken from linux-tdep.c.
   Converting it to fuchsia is a work-in-progress.  */

#include "defs.h"
#include "gdbtypes.h"
#include "fuchsia-tdep.h"
#include "auxv.h"
#include "target.h"
#include "gdbthread.h"
#include "gdbcore.h"
#include "regcache.h"
#include "regset.h"
#include "elf/common.h"
#include "elf-bfd.h"            /* for elfcore_write_* */
#include "inferior.h"
#include "cli/cli-utils.h"
#include "arch-utils.h"
#include "gdb_obstack.h"
#include "observer.h"
#include "objfiles.h"
#include "infcall.h"
#include "gdbcmd.h"
#include "gdb_regex.h"
#include "solib.h"
#include "solib-svr4.h"
#include "solist.h"
#include "common/enum-flags.h"

#include <ctype.h>

static struct target_so_ops fuchsia_so_ops;

/* Signal numbers of the Fuchsia kernel.
   TODO: Work-in-progress.  */

enum
  {
    FUCHSIA_SIGHUP = 1,
    FUCHSIA_SIGINT = 2,
    FUCHSIA_SIGQUIT = 3,
    FUCHSIA_SIGILL = 4,
    FUCHSIA_SIGTRAP = 5,
    FUCHSIA_SIGABRT = 6,
    FUCHSIA_SIGIOT = 6,
    FUCHSIA_SIGBUS = 7,
    FUCHSIA_SIGFPE = 8,
    FUCHSIA_SIGKILL = 9,
    FUCHSIA_SIGUSR1 = 10,
    FUCHSIA_SIGSEGV = 11,
    FUCHSIA_SIGUSR2 = 12,
    FUCHSIA_SIGPIPE = 13,
    FUCHSIA_SIGALRM = 14,
    FUCHSIA_SIGTERM = 15,
    FUCHSIA_SIGSTKFLT = 16,
    FUCHSIA_SIGCHLD = 17,
    FUCHSIA_SIGCONT = 18,
    FUCHSIA_SIGSTOP = 19,
    FUCHSIA_SIGTSTP = 20,
    FUCHSIA_SIGTTIN = 21,
    FUCHSIA_SIGTTOU = 22,
    FUCHSIA_SIGURG = 23,
    FUCHSIA_SIGXCPU = 24,
    FUCHSIA_SIGXFSZ = 25,
    FUCHSIA_SIGVTALRM = 26,
    FUCHSIA_SIGPROF = 27,
    FUCHSIA_SIGWINCH = 28,
    FUCHSIA_SIGIO = 29,
    FUCHSIA_SIGPOLL = FUCHSIA_SIGIO,
    FUCHSIA_SIGPWR = 30,
    FUCHSIA_SIGSYS = 31,
    FUCHSIA_SIGUNUSED = 31,

    FUCHSIA_SIGRTMIN = 32,
    FUCHSIA_SIGRTMAX = 64,
  };

static struct gdbarch_data *fuchsia_gdbarch_data_handle;

struct fuchsia_gdbarch_data
  {
    struct type *siginfo_type;
  };

static void *
init_fuchsia_gdbarch_data (struct gdbarch *gdbarch)
{
  return GDBARCH_OBSTACK_ZALLOC (gdbarch, struct fuchsia_gdbarch_data);
}

static struct fuchsia_gdbarch_data *
get_fuchsia_gdbarch_data (struct gdbarch *gdbarch)
{
  return ((struct fuchsia_gdbarch_data *)
	  gdbarch_data (gdbarch, fuchsia_gdbarch_data_handle));
}

/* Per-inferior data key.  */
static const struct inferior_data *fuchsia_inferior_data;

/* Fuchsia-specific cached data.  This is used by GDB for caching
   purposes for each inferior.  This helps reduce the overhead of
   transfering data from a remote target to the local host.  */
struct fuchsia_info
{
  // True if the exec displacement of this inferior has been calculated.
  bool exec_displacement_known;

  /* Cache of the inferior's vsyscall/vDSO mapping range.  Only valid
     if VSYSCALL_RANGE_P is positive.  This is cached because getting
     at this info requires an auxv lookup (which is itself cached),
     and looking through the inferior's mappings (which change
     throughout execution and therefore cannot be cached).  */
  struct mem_range vsyscall_range;

  /* Zero if we haven't tried looking up the vsyscall's range before
     yet.  Positive if we tried looking it up, and found it.  Negative
     if we tried looking it up but failed.  */
  int vsyscall_range_p;
};

/* Frees whatever allocated space there is to be freed and sets INF's
   fuchsia cache data pointer to NULL.  */

static void
invalidate_fuchsia_cache_inf (struct inferior *inf)
{
  struct fuchsia_info *info;

  info = (struct fuchsia_info *) inferior_data (inf, fuchsia_inferior_data);
  if (info != NULL)
    {
      xfree (info);
      set_inferior_data (inf, fuchsia_inferior_data, NULL);
    }
}

/* Handles the cleanup of the fuchsia cache for inferior INF.  ARG is
   ignored.  Callback for the inferior_appeared and inferior_exit
   events.  */

static void
fuchsia_inferior_data_cleanup (struct inferior *inf, void *arg)
{
  invalidate_fuchsia_cache_inf (inf);
}

/* Fetch the fuchsia cache info for INF.  This function always returns a
   valid INFO pointer.  */

static struct fuchsia_info *
get_fuchsia_inferior_data (void)
{
  struct fuchsia_info *info;
  struct inferior *inf = current_inferior ();

  info = (struct fuchsia_info *) inferior_data (inf, fuchsia_inferior_data);
  if (info == NULL)
    {
      info = XCNEW (struct fuchsia_info);
      set_inferior_data (inf, fuchsia_inferior_data, info);
    }

  return info;
}

/* siginfo is still a work-in-progress for fuchsia.  */

static struct type *
fuchsia_get_siginfo_type (struct gdbarch *gdbarch)
{
  struct fuchsia_gdbarch_data *fuchsia_gdbarch_data;
  struct type *int_type;
  struct type *siginfo_type;

  fuchsia_gdbarch_data = get_fuchsia_gdbarch_data (gdbarch);
  if (fuchsia_gdbarch_data->siginfo_type != NULL)
    return fuchsia_gdbarch_data->siginfo_type;

  int_type = arch_integer_type (gdbarch, gdbarch_int_bit (gdbarch),
			 	0, "int");

  /* struct siginfo */
  siginfo_type = arch_composite_type (gdbarch, NULL, TYPE_CODE_STRUCT);
  TYPE_NAME (siginfo_type) = xstrdup ("siginfo");
  append_composite_type_field (siginfo_type, "si_signo", int_type);
  append_composite_type_field (siginfo_type, "si_errno", int_type);
  append_composite_type_field (siginfo_type, "si_code", int_type);

  fuchsia_gdbarch_data->siginfo_type = siginfo_type;

  return siginfo_type;
}

/* Implementation of `gdbarch_gdb_signal_from_target', as defined in
   gdbarch.h.  This function is not static because it is exported to
   other -tdep files.  */

enum gdb_signal
fuchsia_gdb_signal_from_target (struct gdbarch *gdbarch, int signal)
{
  switch (signal)
    {
    case 0:
      return GDB_SIGNAL_0;

    case FUCHSIA_SIGHUP:
      return GDB_SIGNAL_HUP;

    case FUCHSIA_SIGINT:
      return GDB_SIGNAL_INT;

    case FUCHSIA_SIGQUIT:
      return GDB_SIGNAL_QUIT;

    case FUCHSIA_SIGILL:
      return GDB_SIGNAL_ILL;

    case FUCHSIA_SIGTRAP:
      return GDB_SIGNAL_TRAP;

    case FUCHSIA_SIGABRT:
      return GDB_SIGNAL_ABRT;

    case FUCHSIA_SIGBUS:
      return GDB_SIGNAL_BUS;

    case FUCHSIA_SIGFPE:
      return GDB_SIGNAL_FPE;

    case FUCHSIA_SIGKILL:
      return GDB_SIGNAL_KILL;

    case FUCHSIA_SIGUSR1:
      return GDB_SIGNAL_USR1;

    case FUCHSIA_SIGSEGV:
      return GDB_SIGNAL_SEGV;

    case FUCHSIA_SIGUSR2:
      return GDB_SIGNAL_USR2;

    case FUCHSIA_SIGPIPE:
      return GDB_SIGNAL_PIPE;

    case FUCHSIA_SIGALRM:
      return GDB_SIGNAL_ALRM;

    case FUCHSIA_SIGTERM:
      return GDB_SIGNAL_TERM;

    case FUCHSIA_SIGCHLD:
      return GDB_SIGNAL_CHLD;

    case FUCHSIA_SIGCONT:
      return GDB_SIGNAL_CONT;

    case FUCHSIA_SIGSTOP:
      return GDB_SIGNAL_STOP;

    case FUCHSIA_SIGTSTP:
      return GDB_SIGNAL_TSTP;

    case FUCHSIA_SIGTTIN:
      return GDB_SIGNAL_TTIN;

    case FUCHSIA_SIGTTOU:
      return GDB_SIGNAL_TTOU;

    case FUCHSIA_SIGURG:
      return GDB_SIGNAL_URG;

    case FUCHSIA_SIGXCPU:
      return GDB_SIGNAL_XCPU;

    case FUCHSIA_SIGXFSZ:
      return GDB_SIGNAL_XFSZ;

    case FUCHSIA_SIGVTALRM:
      return GDB_SIGNAL_VTALRM;

    case FUCHSIA_SIGPROF:
      return GDB_SIGNAL_PROF;

    case FUCHSIA_SIGWINCH:
      return GDB_SIGNAL_WINCH;

    /* No way to differentiate between SIGIO and SIGPOLL.
       Therefore, we just handle the first one.  */
    case FUCHSIA_SIGIO:
      return GDB_SIGNAL_IO;

    case FUCHSIA_SIGPWR:
      return GDB_SIGNAL_PWR;

    case FUCHSIA_SIGSYS:
      return GDB_SIGNAL_SYS;

    /* SIGRTMIN and SIGRTMAX are not continuous in <gdb/signals.def>,
       therefore we have to handle them here.  */
    case FUCHSIA_SIGRTMIN:
      return GDB_SIGNAL_REALTIME_32;

    case FUCHSIA_SIGRTMAX:
      return GDB_SIGNAL_REALTIME_64;
    }

  if (signal >= FUCHSIA_SIGRTMIN + 1 && signal <= FUCHSIA_SIGRTMAX - 1)
    {
      int offset = signal - FUCHSIA_SIGRTMIN + 1;

      return (enum gdb_signal) ((int) GDB_SIGNAL_REALTIME_33 + offset);
    }

  return GDB_SIGNAL_UNKNOWN;
}

/* Implementation of `gdbarch_gdb_signal_to_target', as defined in
   gdbarch.h.  This function is not static because it is exported to
   other -tdep files.  */

int
fuchsia_gdb_signal_to_target (struct gdbarch *gdbarch,
			    enum gdb_signal signal)
{
  switch (signal)
    {
    case GDB_SIGNAL_0:
      return 0;

    case GDB_SIGNAL_HUP:
      return FUCHSIA_SIGHUP;

    case GDB_SIGNAL_INT:
      return FUCHSIA_SIGINT;

    case GDB_SIGNAL_QUIT:
      return FUCHSIA_SIGQUIT;

    case GDB_SIGNAL_ILL:
      return FUCHSIA_SIGILL;

    case GDB_SIGNAL_TRAP:
      return FUCHSIA_SIGTRAP;

    case GDB_SIGNAL_ABRT:
      return FUCHSIA_SIGABRT;

    case GDB_SIGNAL_FPE:
      return FUCHSIA_SIGFPE;

    case GDB_SIGNAL_KILL:
      return FUCHSIA_SIGKILL;

    case GDB_SIGNAL_BUS:
      return FUCHSIA_SIGBUS;

    case GDB_SIGNAL_SEGV:
      return FUCHSIA_SIGSEGV;

    case GDB_SIGNAL_SYS:
      return FUCHSIA_SIGSYS;

    case GDB_SIGNAL_PIPE:
      return FUCHSIA_SIGPIPE;

    case GDB_SIGNAL_ALRM:
      return FUCHSIA_SIGALRM;

    case GDB_SIGNAL_TERM:
      return FUCHSIA_SIGTERM;

    case GDB_SIGNAL_URG:
      return FUCHSIA_SIGURG;

    case GDB_SIGNAL_STOP:
      return FUCHSIA_SIGSTOP;

    case GDB_SIGNAL_TSTP:
      return FUCHSIA_SIGTSTP;

    case GDB_SIGNAL_CONT:
      return FUCHSIA_SIGCONT;

    case GDB_SIGNAL_CHLD:
      return FUCHSIA_SIGCHLD;

    case GDB_SIGNAL_TTIN:
      return FUCHSIA_SIGTTIN;

    case GDB_SIGNAL_TTOU:
      return FUCHSIA_SIGTTOU;

    case GDB_SIGNAL_IO:
      return FUCHSIA_SIGIO;

    case GDB_SIGNAL_XCPU:
      return FUCHSIA_SIGXCPU;

    case GDB_SIGNAL_XFSZ:
      return FUCHSIA_SIGXFSZ;

    case GDB_SIGNAL_VTALRM:
      return FUCHSIA_SIGVTALRM;

    case GDB_SIGNAL_PROF:
      return FUCHSIA_SIGPROF;

    case GDB_SIGNAL_WINCH:
      return FUCHSIA_SIGWINCH;

    case GDB_SIGNAL_USR1:
      return FUCHSIA_SIGUSR1;

    case GDB_SIGNAL_USR2:
      return FUCHSIA_SIGUSR2;

    case GDB_SIGNAL_PWR:
      return FUCHSIA_SIGPWR;

    case GDB_SIGNAL_POLL:
      return FUCHSIA_SIGPOLL;

    /* GDB_SIGNAL_REALTIME_32 is not continuous in <gdb/signals.def>,
       therefore we have to handle it here.  */
    case GDB_SIGNAL_REALTIME_32:
      return FUCHSIA_SIGRTMIN;

    /* Same comment applies to _64.  */
    case GDB_SIGNAL_REALTIME_64:
      return FUCHSIA_SIGRTMAX;
    }

  /* GDB_SIGNAL_REALTIME_33 to _64 are continuous.  */
  if (signal >= GDB_SIGNAL_REALTIME_33
      && signal <= GDB_SIGNAL_REALTIME_63)
    {
      int offset = signal - GDB_SIGNAL_REALTIME_33;

      return FUCHSIA_SIGRTMIN + 1 + offset;
    }

  return -1;
}

/* Helper for fuchsia_vsyscall_range that does the real work of finding
   the vsyscall's address range.  */

static int
fuchsia_vsyscall_range_raw (struct gdbarch *gdbarch, struct mem_range *range)
{
  return 0; // TODO
}

/* Implementation of the "vsyscall_range" gdbarch hook.  Handles
   caching, and defers the real work to fuchsia_vsyscall_range_raw.  */

static int
fuchsia_vsyscall_range (struct gdbarch *gdbarch, struct mem_range *range)
{
  struct fuchsia_info *info = get_fuchsia_inferior_data ();

  if (info->vsyscall_range_p == 0)
    {
      if (fuchsia_vsyscall_range_raw (gdbarch, &info->vsyscall_range))
	info->vsyscall_range_p = 1;
      else
	info->vsyscall_range_p = -1;
    }

  if (info->vsyscall_range_p < 0)
    return 0;

  *range = info->vsyscall_range;
  return 1;
}

/* Symbols for fuchsia_infcall_mmap's ARG_FLAGS; their Fuchsia MAP_* system
   definitions would be dependent on compilation host.  */
#define GDB_MMAP_MAP_PRIVATE   0x02 /* Changes are private.  */
#define GDB_MMAP_MAP_ANONYMOUS 0x20 /* Don't use a file.  */

/* See gdbarch.sh 'infcall_mmap'.  */

static CORE_ADDR
fuchsia_infcall_mmap (CORE_ADDR size, unsigned prot)
{
  struct objfile *objf;
  /* Do there still exist any Fuchsia systems without "mmap64"?
     "mmap" uses 64-bit off_t on x86_64 and 32-bit off_t on i386 and x32.  */
  struct value *mmap_val = find_function_in_inferior ("mmap64", &objf);
  struct value *addr_val;
  struct gdbarch *gdbarch = get_objfile_arch (objf);
  CORE_ADDR retval;
  enum
    {
      ARG_ADDR, ARG_LENGTH, ARG_PROT, ARG_FLAGS, ARG_FD, ARG_OFFSET, ARG_LAST
    };
  struct value *arg[ARG_LAST];

  arg[ARG_ADDR] = value_from_pointer (builtin_type (gdbarch)->builtin_data_ptr,
				      0);
  /* Assuming sizeof (unsigned long) == sizeof (size_t).  */
  arg[ARG_LENGTH] = value_from_ulongest
		    (builtin_type (gdbarch)->builtin_unsigned_long, size);
  gdb_assert ((prot & ~(GDB_MMAP_PROT_READ | GDB_MMAP_PROT_WRITE
			| GDB_MMAP_PROT_EXEC))
	      == 0);
  arg[ARG_PROT] = value_from_longest (builtin_type (gdbarch)->builtin_int, prot);
  arg[ARG_FLAGS] = value_from_longest (builtin_type (gdbarch)->builtin_int,
				       GDB_MMAP_MAP_PRIVATE
				       | GDB_MMAP_MAP_ANONYMOUS);
  arg[ARG_FD] = value_from_longest (builtin_type (gdbarch)->builtin_int, -1);
  arg[ARG_OFFSET] = value_from_longest (builtin_type (gdbarch)->builtin_int64,
					0);
  addr_val = call_function_by_hand (mmap_val, ARG_LAST, arg);
  retval = value_as_address (addr_val);
  if (retval == (CORE_ADDR) -1)
    error (_("Failed inferior mmap call for %s bytes, errno is changed."),
	   pulongest (size));
  return retval;
}

/* See gdbarch.sh 'infcall_munmap'.  */

static void
fuchsia_infcall_munmap (CORE_ADDR addr, CORE_ADDR size)
{
  struct objfile *objf;
  struct value *munmap_val = find_function_in_inferior ("munmap", &objf);
  struct value *retval_val;
  struct gdbarch *gdbarch = get_objfile_arch (objf);
  LONGEST retval;
  enum
    {
      ARG_ADDR, ARG_LENGTH, ARG_LAST
    };
  struct value *arg[ARG_LAST];

  arg[ARG_ADDR] = value_from_pointer (builtin_type (gdbarch)->builtin_data_ptr,
				      addr);
  /* Assuming sizeof (unsigned long) == sizeof (size_t).  */
  arg[ARG_LENGTH] = value_from_ulongest
		    (builtin_type (gdbarch)->builtin_unsigned_long, size);
  retval_val = call_function_by_hand (munmap_val, ARG_LAST, arg);
  retval = value_as_long (retval_val);
  if (retval != 0)
    warning (_("Failed inferior munmap call at %s for %s bytes, "
	       "errno is changed."),
	     hex_string (addr), pulongest (size));
}

/* See fuchsia-tdep.h.  */

CORE_ADDR
fuchsia_displaced_step_location (struct gdbarch *gdbarch)
{
  CORE_ADDR addr;
  int bp_len;

  // TODO: We're assuming this is called after the first
  // dynamic linker breakpoint has been hit (where we know the
  // executable has been loaded). Could try to use the interpreter's
  // entry point here.
  /* Determine entry point from target auxiliary vector.  This avoids
     the need for symbols.  */
  if (target_auxv_search (&current_target, AT_ENTRY, &addr) <= 0)
    throw_error (NOT_SUPPORTED_ERROR,
		 _("Cannot find AT_ENTRY auxiliary vector entry."));

  /* Make certain that the address points at real code, and not a
     function descriptor.  */
  addr = gdbarch_convert_from_func_ptr_addr (gdbarch, addr,
					     &current_target);

  /* Inferior calls also use the entry point as a breakpoint location.
     We don't want displaced stepping to interfere with those
     breakpoints, so leave space.  */
  gdbarch_breakpoint_from_pc (gdbarch, &addr, &bp_len);
  addr += bp_len * 2;

  return addr;
}

// Create inferior hook.

static void
fuchsia_solib_create_inferior_hook (int from_tty)
{
  /* For Fuchsia we need to reset the PIE exec displacement before we do
     anything else.  In between the time the inferior starts and when the main
     executable is loaded the old displacements are wrong and things like
     re-setting breakpoints can get into worse trouble than normal (typically
     the PIE addresses are low enough that memory reads/writes fail, but with
     the previous run's displacement they might errantly work).  A better fix
     would of course be to not even try to access memory until it exists but
     that's a wee bit of work.  */
  svr4_apply_exec_displacement (0);

  /* If the user established breakpoints before starting the inferior, GDB
     would attempt to insert those now.  This will fail because the executable
     hasn't been loaded yet: In Fuchsia the executable is loaded by ld.so.
     To prevent such failures, we disable all user-created breakpoints now;
     they will be re-enabled in fuchsia_handle_solib_event once the main
     executable has been loaded.  */
  disable_breakpoints_before_startup ();

  svr4_solib_create_inferior_hook (from_tty);
}

/* For Fuchsia we can't relocate the main executable until after we get
   to the shlib event breakpoint: The main executable is not loaded until
   the dynamic linker loads it.  */

static void
fuchsia_handle_solib_event (void)
{
  struct fuchsia_info *info = get_fuchsia_inferior_data ();

  if (!info->exec_displacement_known)
    {
      // Presumably this is the first time we've hit the dynamic linker bkpt.
      // It is now that the main executable has been loaded.  To fetch the
      // necessary info (e.g., AT_ENTRY) we need to flush the auxv cache so
      // gdb will refetch it.
      invalidate_auxv_cache_inf (current_inferior ());
      svr4_relocate_main_executable ();
      info->exec_displacement_known = true;

      // Now that the main executable is loaded breakpoints in it can be
      // enabled (e.g., prologue parsing will now work as memory addresses
      // have been relocated and are readable).
      enable_breakpoints_after_startup ();
    }

  /* If fuchsia starts using probes, call svr4_handle_solib_event here.  */
}

/* To be called from the various GDB_OSABI_FUCHSIA handlers for the
   various Fuchsia architectures and machine types.  */

void
fuchsia_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
{
  set_gdbarch_gdb_signal_from_target (gdbarch,
				      fuchsia_gdb_signal_from_target);
  set_gdbarch_gdb_signal_to_target (gdbarch,
				    fuchsia_gdb_signal_to_target);
  set_gdbarch_vsyscall_range (gdbarch, fuchsia_vsyscall_range);
  set_gdbarch_infcall_mmap (gdbarch, fuchsia_infcall_mmap);
  set_gdbarch_infcall_munmap (gdbarch, fuchsia_infcall_munmap);
  set_gdbarch_get_siginfo_type (gdbarch, fuchsia_get_siginfo_type);

  /* Enable TLS support.  */
  set_gdbarch_fetch_tls_load_module_address (gdbarch,
					     svr4_fetch_objfile_link_map);

  /* Fuchsia uses SVR4-style shared libraries.  */
  set_gdbarch_skip_trampoline_code (gdbarch, find_solib_trampoline_target);

  /* Fuchsia uses its own dynamic linker.  */
  set_gdbarch_skip_solib_resolver (gdbarch, fuchsia_skip_solib_resolver);

  /* Fuchsia uses SVR4-style shared libraries.
     Note: This also calls set_solib_ops.  */
  set_solib_svr4_fetch_link_map_offsets
    (gdbarch, svr4_lp64_fetch_link_map_offsets);

  /* We need to use our own so_ops vtable to handle exec displacement
     computation. We also need to reset the exec displacement on each run.
     Initialize this lazily, to avoid an initialization order
     dependency on solib-svr4.c's _initialize routine.  */
  if (fuchsia_so_ops.handle_event == NULL)
    {
      fuchsia_so_ops = svr4_so_ops;
      fuchsia_so_ops.solib_create_inferior_hook
	= fuchsia_solib_create_inferior_hook;
      fuchsia_so_ops.handle_event = fuchsia_handle_solib_event;
    }
  set_solib_ops (gdbarch, &fuchsia_so_ops);
}

/* Calling functions in shared libraries.
   See the comments for SKIP_SOLIB_RESOLVER at the top of infrun.c.
   This function:
   1) decides whether a PLT has sent us into the linker to resolve
      a function reference, and
   2) if so, tells us where to set a temporary breakpoint that will
      trigger when the dynamic linker is done.  */

CORE_ADDR
fuchsia_skip_solib_resolver (struct gdbarch *gdbarch, CORE_ADDR pc)
{
  // TODO: Update for fuchsia/musl.
  /* The GNU dynamic linker is part of the GNU C library, and is used
     by all GNU systems (GNU/Hurd, GNU/Linux).  An unresolved PLT
     entry points to "_dl_runtime_resolve", which calls "fixup" to
     patch the PLT, and then passes control to the function.

     We look for the symbol `_dl_runtime_resolve', and find `fixup' in
     the same objfile.  If we are at the entry point of `fixup', then
     we set a breakpoint at the return address (at the top of the
     stack), and continue.

     It's kind of gross to do all these checks every time we're
     called, since they don't change once the executable has gotten
     started.  But this is only a temporary hack --- upcoming versions
     of GNU/Linux will provide a portable, efficient interface for
     debugging programs that use shared libraries.  */

  struct bound_minimal_symbol resolver
    = lookup_minimal_symbol_and_objfile ("_dl_runtime_resolve");

  if (resolver.minsym)
    {
      /* The dynamic linker began using this name in early 2005.  */
      struct bound_minimal_symbol fixup
	= lookup_minimal_symbol ("_dl_fixup", NULL, resolver.objfile);

      /* This is the name used in older versions.  */
      if (! fixup.minsym)
        fixup = lookup_minimal_symbol ("fixup", NULL, resolver.objfile);

      if (fixup.minsym && BMSYMBOL_VALUE_ADDRESS (fixup) == pc)
	return frame_unwind_caller_pc (get_current_frame ());
    }

  return 0;
}

/* Recognize Fuchsia object files.  */

enum gdb_osabi
fuchsia_osabi_sniffer (bfd *abfd)
{
  /* TODO: Until we have something like a fuchsia .note.ABI-tag, assume the
     absence of .note.ABI-tag means fuchsia.  */
  if (bfd_get_section_by_name (abfd, ".note.ABI-tag") == NULL)
    return GDB_OSABI_FUCHSIA;
  return GDB_OSABI_UNKNOWN;
}

/* Provide a prototype to silence -Wmissing-prototypes.  */
extern initialize_file_ftype _initialize_fuchsia_tdep;

void
_initialize_fuchsia_tdep (void)
{
  fuchsia_gdbarch_data_handle =
    gdbarch_data_register_post_init (init_fuchsia_gdbarch_data);

  /* Set a cache per-inferior.  */
  fuchsia_inferior_data
    = register_inferior_data_with_cleanup (NULL, fuchsia_inferior_data_cleanup);
  /* Observers used to invalidate the cache when needed.  */
  observer_attach_inferior_exit (invalidate_fuchsia_cache_inf);
  observer_attach_inferior_appeared (invalidate_fuchsia_cache_inf);
}
