/* Cell SPU GNU/Linux support -- shared library handling.
   Copyright (C) 2009, 2010 Free Software Foundation, Inc.

   Contributed by Ulrich Weigand <uweigand@de.ibm.com>.

   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 "gdbcore.h"
#include "gdb_string.h"
#include "gdb_assert.h"
#include "gdb_stat.h"
#include "arch-utils.h"
#include "bfd.h"
#include "symtab.h"
#include "solib.h"
#include "solib-svr4.h"
#include "solist.h"
#include "inferior.h"
#include "objfiles.h"
#include "observer.h"
#include "breakpoint.h"
#include "gdbthread.h"

#include "spu-tdep.h"

/* Highest SPE id (file handle) the inferior may have.  */
#define MAX_SPE_FD 1024

/* Stand-alone SPE executable?  */
#define spu_standalone_p() \
  (symfile_objfile && symfile_objfile->obfd \
   && bfd_get_arch (symfile_objfile->obfd) == bfd_arch_spu)


/* Relocate main SPE executable.  */
static void
spu_relocate_main_executable (int spufs_fd)
{
  struct section_offsets *new_offsets;
  int i;

  if (symfile_objfile == NULL)
    return;

  new_offsets = alloca (symfile_objfile->num_sections
			* sizeof (struct section_offsets));

  for (i = 0; i < symfile_objfile->num_sections; i++)
    new_offsets->offsets[i] = SPUADDR (spufs_fd, 0);

  objfile_relocate (symfile_objfile, new_offsets);
}

/* When running a stand-alone SPE executable, we may need to skip one more
   exec event on startup, to get past the binfmt_misc loader.  */
static void
spu_skip_standalone_loader (void)
{
  if (target_has_execution && !current_inferior ()->attach_flag)
    {
      struct target_waitstatus ws;

      /* Only some kernels report an extra SIGTRAP with the binfmt_misc
	 loader; others do not.  In addition, if we have attached to an
	 already running inferior instead of starting a new one, we will
	 not see the extra SIGTRAP -- and we cannot readily distinguish
	 the two cases, in particular with the extended-remote target.

	 Thus we issue a single-step here.  If no extra SIGTRAP was pending,
	 this will step past the first instruction of the stand-alone SPE
	 executable loader, but we don't care about that.  */

      inferior_thread ()->in_infcall = 1;   /* Suppress MI messages.  */

      target_resume (inferior_ptid, 1, TARGET_SIGNAL_0);
      target_wait (minus_one_ptid, &ws, 0);
      set_executing (minus_one_ptid, 0);

      inferior_thread ()->in_infcall = 0;
    }
}

/* Build a list of `struct so_list' objects describing the shared
   objects currently loaded in the inferior.  */
static struct so_list *
spu_current_sos (void)
{
  enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch);
  struct so_list *head;
  struct so_list **link_ptr;

  char buf[MAX_SPE_FD * 4];
  int i, size;

  /* First, retrieve the SVR4 shared library list.  */
  head = svr4_so_ops.current_sos ();

  /* Append our libraries to the end of the list.  */
  for (link_ptr = &head; *link_ptr; link_ptr = &(*link_ptr)->next)
    ;

  /* Determine list of SPU ids.  */
  size = target_read (&current_target, TARGET_OBJECT_SPU, NULL,
		      buf, 0, sizeof buf);

  /* Do not add stand-alone SPE executable context as shared library,
     but relocate main SPE executable objfile.  */
  if (spu_standalone_p ())
    {
      if (size == 4)
	{
	  int fd = extract_unsigned_integer (buf, 4, byte_order);
	  spu_relocate_main_executable (fd);

	  /* Re-enable breakpoints after main SPU context was established;
	     see also comments in spu_solib_create_inferior_hook.  */
	  enable_breakpoints_after_startup ();
	}

      return head;
    }

  /* Create an so_list entry for each SPU id.  */
  for (i = 0; i < size; i += 4)
    {
      int fd = extract_unsigned_integer (buf + i, 4, byte_order);
      struct so_list *new;

      unsigned long long addr;
      char annex[32], id[100];
      int len;

      /* Read object ID.  There's a race window where the inferior may have
	 already created the SPE context, but not installed the object-id
	 yet.  Skip such entries; we'll be back for them later.  */
      xsnprintf (annex, sizeof annex, "%d/object-id", fd);
      len = target_read (&current_target, TARGET_OBJECT_SPU, annex,
			 id, 0, sizeof id);
      if (len <= 0 || len >= sizeof id)
	continue;
      id[len] = 0;
      if (sscanf (id, "0x%llx", &addr) != 1 || !addr)
	continue;

      /* Allocate so_list structure.  */
      new = XZALLOC (struct so_list);

      /* Encode FD and object ID in path name.  Choose the name so as not
	 to conflict with any (normal) SVR4 library path name.  */
      xsnprintf (new->so_name, sizeof new->so_name, "@0x%llx <%d>", addr, fd);
      strcpy (new->so_original_name, new->so_name);

      *link_ptr = new;
      link_ptr = &new->next;
    }

  return head;
}

/* Free so_list information.  */
static void
spu_free_so (struct so_list *so)
{
  if (so->so_original_name[0] != '@')
    svr4_so_ops.free_so (so);
}

/* Relocate section addresses.  */
static void
spu_relocate_section_addresses (struct so_list *so,
				struct target_section *sec)
{
  if (so->so_original_name[0] != '@')
    svr4_so_ops.relocate_section_addresses (so, sec);
  else
    {
      unsigned long long addr;
      int fd;

      /* Set addr_low/high to just LS offset for display.  */
      if (so->addr_low == 0 && so->addr_high == 0
          && strcmp (sec->the_bfd_section->name, ".text") == 0)
        {
          so->addr_low = sec->addr;
          so->addr_high = sec->endaddr;
        }

      /* Decode object ID.  */
      if (sscanf (so->so_original_name, "@0x%llx <%d>", &addr, &fd) != 2)
	internal_error (__FILE__, __LINE__, "bad object ID");

      sec->addr = SPUADDR (fd, sec->addr);
      sec->endaddr = SPUADDR (fd, sec->endaddr);
    }
}


/* Inferior memory should contain an SPE executable image at location ADDR.
   Allocate a BFD representing that executable.  Return NULL on error.  */

static void *
spu_bfd_iovec_open (bfd *nbfd, void *open_closure)
{
  return open_closure;
}

static int
spu_bfd_iovec_close (bfd *nbfd, void *stream)
{
  xfree (stream);
  return 1;
}

static file_ptr
spu_bfd_iovec_pread (bfd *abfd, void *stream, void *buf,
                     file_ptr nbytes, file_ptr offset)
{
  CORE_ADDR addr = *(CORE_ADDR *)stream;
  int ret;

  ret = target_read_memory (addr + offset, buf, nbytes);
  if (ret != 0)
    {
      bfd_set_error (bfd_error_invalid_operation);
      return -1;
    }

  return nbytes;
}

static int
spu_bfd_iovec_stat (bfd *abfd, void *stream, struct stat *sb)
{
  /* We don't have an easy way of finding the size of embedded spu
     images.  We could parse the in-memory ELF header and section
     table to find the extent of the last section but that seems
     pointless when the size is needed only for checks of other
     parsed values in dbxread.c.  */
  sb->st_size = INT_MAX;
  return 0;
}

static bfd *
spu_bfd_fopen (char *name, CORE_ADDR addr)
{
  bfd *nbfd;

  CORE_ADDR *open_closure = xmalloc (sizeof (CORE_ADDR));
  *open_closure = addr;

  nbfd = bfd_openr_iovec (xstrdup (name), "elf32-spu",
                          spu_bfd_iovec_open, open_closure,
                          spu_bfd_iovec_pread, spu_bfd_iovec_close,
			  spu_bfd_iovec_stat);
  if (!nbfd)
    return NULL;

  if (!bfd_check_format (nbfd, bfd_object))
    {
      bfd_close (nbfd);
      return NULL;
    }

  return nbfd;
}

/* Open shared library BFD.  */
static bfd *
spu_bfd_open (char *pathname)
{
  char *original_name = strrchr (pathname, '@');
  bfd *abfd;
  asection *spu_name;
  unsigned long long addr;
  int fd;

  /* Handle regular SVR4 libraries.  */
  if (!original_name)
    return svr4_so_ops.bfd_open (pathname);

  /* Decode object ID.  */
  if (sscanf (original_name, "@0x%llx <%d>", &addr, &fd) != 2)
    internal_error (__FILE__, __LINE__, "bad object ID");

  /* Open BFD representing SPE executable.  */
  abfd = spu_bfd_fopen (original_name, (CORE_ADDR) addr);
  if (!abfd)
    error (_("Cannot read SPE executable at %s"), original_name);

  /* Retrieve SPU name note.  */
  spu_name = bfd_get_section_by_name (abfd, ".note.spu_name");
  if (spu_name)
    {
      int sect_size = bfd_section_size (abfd, spu_name);
      if (sect_size > 20)
	{
	  char *buf = alloca (sect_size - 20 + strlen (original_name) + 1);
	  bfd_get_section_contents (abfd, spu_name, buf, 20, sect_size - 20);
	  buf[sect_size - 20] = '\0';

	  strcat (buf, original_name);

	  xfree ((char *)abfd->filename);
	  abfd->filename = xstrdup (buf);
	}
    }

  return abfd;
}

/* Lookup global symbol in a SPE executable.  */
static struct symbol *
spu_lookup_lib_symbol (const struct objfile *objfile,
		       const char *name,
		       const char *linkage_name,
		       const domain_enum domain)
{
  if (bfd_get_arch (objfile->obfd) == bfd_arch_spu)
    return lookup_global_symbol_from_objfile (objfile, name, linkage_name,
					      domain);

  if (svr4_so_ops.lookup_lib_global_symbol != NULL)
    return svr4_so_ops.lookup_lib_global_symbol (objfile, name, linkage_name,
						 domain);
  return NULL;
}

/* Enable shared library breakpoint.  */
static int
spu_enable_break (struct objfile *objfile)
{
  struct minimal_symbol *spe_event_sym = NULL;

  /* The libspe library will call __spe_context_update_event whenever any
     SPE context is allocated or destroyed.  */
  spe_event_sym = lookup_minimal_symbol ("__spe_context_update_event",
					 NULL, objfile);

  /* Place a solib_event breakpoint on the symbol.  */
  if (spe_event_sym)
    {
      CORE_ADDR addr = SYMBOL_VALUE_ADDRESS (spe_event_sym);
      addr = gdbarch_convert_from_func_ptr_addr (target_gdbarch, addr,
                                                 &current_target);
      create_solib_event_breakpoint (target_gdbarch, addr);
      return 1;
    }

  return 0;
}

/* Create inferior hook.  */
static void
spu_solib_create_inferior_hook (int from_tty)
{
  /* Remove all previously installed solib breakpoints.  Both the SVR4
     code and us will re-install all required breakpoints.  */
  remove_solib_event_breakpoints ();

  /* Handle SPE stand-alone executables.  */
  if (spu_standalone_p ())
    {
      /* After an SPE stand-alone executable was loaded, we'll receive
	 an additional trap due to the binfmt_misc handler.  Make sure
	 to skip that trap.  */
      spu_skip_standalone_loader ();

      /* If the user established breakpoints before starting the inferior, GDB
	 would attempt to insert those now.  This would fail because the SPU
	 context has not yet been created and the SPU executable has not yet
	 been loaded.  To prevent such failures, we disable all user-created
	 breakpoints now; they will be re-enabled in spu_current_sos once the
	 main SPU context has been detected.  */
      disable_breakpoints_before_startup ();

      /* A special case arises when re-starting an executable, because at
	 this point it still resides at the relocated address range that was
	 determined during its last execution.  We need to undo the relocation
	 so that that multi-architecture target recognizes the stand-alone
	 initialization special case.  */
      spu_relocate_main_executable (-1);
    }

  /* Call SVR4 hook -- this will re-insert the SVR4 solib breakpoints.  */
  svr4_so_ops.solib_create_inferior_hook (from_tty);

  /* If the inferior is statically linked against libspe, we need to install
     our own solib breakpoint right now.  Otherwise, it will be installed by
     the solib_loaded observer below as soon as libspe is loaded.  */
  spu_enable_break (NULL);
}

/* Install SPE "shared library" handling.  This is called by -tdep code
   that wants to support SPU as a secondary architecture.  */
void
set_spu_solib_ops (struct gdbarch *gdbarch)
{
  static struct target_so_ops spu_so_ops;

  /* Initialize this lazily, to avoid an initialization order
     dependency on solib-svr4.c's _initialize routine.  */
  if (spu_so_ops.current_sos == NULL)
    {
      spu_so_ops = svr4_so_ops;
      spu_so_ops.solib_create_inferior_hook = spu_solib_create_inferior_hook;
      spu_so_ops.relocate_section_addresses = spu_relocate_section_addresses;
      spu_so_ops.free_so = spu_free_so;
      spu_so_ops.current_sos = spu_current_sos;
      spu_so_ops.bfd_open = spu_bfd_open;
      spu_so_ops.lookup_lib_global_symbol = spu_lookup_lib_symbol;
    }

  set_solib_ops (gdbarch, &spu_so_ops);
}

/* Observer for the solib_loaded event.  Used to install our breakpoint
   if libspe is a shared library.  */
static void
spu_solib_loaded (struct so_list *so)
{
  if (strstr (so->so_original_name, "/libspe") != NULL)
    {
      solib_read_symbols (so, so->from_tty ? SYMFILE_VERBOSE : 0);
      spu_enable_break (so->objfile);
    }
}

void
_initialize_spu_solib (void)
{
  observer_attach_solib_loaded (spu_solib_loaded);
}

