/* 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;
}

/* 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.  */

static void
fuchsia_solib_create_inferior_hook (int from_tty)
{
  svr4_apply_exec_displacement (0);
  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;
    }

  /* 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);
}
