/* Shared library support for IRIX.
   Copyright 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, 2002
   Free Software Foundation, Inc.

   This file was created using portions of irix5-nat.c originally
   contributed to GDB by Ian Lance Taylor.

   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 2 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, write to the Free Software
   Foundation, Inc., 59 Temple Place - Suite 330,
   Boston, MA 02111-1307, USA.  */

#include "defs.h"

#include "symtab.h"
#include "bfd.h"
#include "symfile.h"
#include "objfiles.h"
#include "gdbcore.h"
#include "target.h"
#include "inferior.h"

#include "solist.h"

/* Link map info to include in an allocate so_list entry.  Unlike some
   of the other solib backends, this (Irix) backend chooses to decode
   the link map info obtained from the target and store it as (mostly)
   CORE_ADDRs which need no further decoding.  This is more convenient
   because there are three different link map formats to worry about.
   We use a single routine (fetch_lm_info) to read (and decode) the target
   specific link map data.  */

struct lm_info
{
  CORE_ADDR addr;		/* address of obj_info or obj_list
				   struct on target (from which the
				   following information is obtained).  */
  CORE_ADDR next;		/* address of next item in list.  */
  CORE_ADDR reloc_offset;	/* amount to relocate by  */
  CORE_ADDR pathname_addr;	/* address of pathname  */
  int pathname_len;		/* length of pathname */
};

/* It's not desirable to use the system header files to obtain the
   structure of the obj_list or obj_info structs.  Therefore, we use a
   platform neutral representation which has been derived from the IRIX
   header files.  */

typedef struct
{
  char b[4];
}
gdb_int32_bytes;
typedef struct
{
  char b[8];
}
gdb_int64_bytes;

/* The "old" obj_list struct.  This is used with old (o32) binaries.
   The ``data'' member points at a much larger and more complicated
   struct which we will only refer to by offsets.  See
   fetch_lm_info().  */

struct irix_obj_list
{
  gdb_int32_bytes data;
  gdb_int32_bytes next;
  gdb_int32_bytes prev;
};

/* The ELF32 and ELF64 versions of the above struct.  The oi_magic value
   corresponds to the ``data'' value in the "old" struct.  When this value
   is 0xffffffff, the data will be in one of the following formats.  The
   ``oi_size'' field is used to decide which one we actually have.  */

struct irix_elf32_obj_info
{
  gdb_int32_bytes oi_magic;
  gdb_int32_bytes oi_size;
  gdb_int32_bytes oi_next;
  gdb_int32_bytes oi_prev;
  gdb_int32_bytes oi_ehdr;
  gdb_int32_bytes oi_orig_ehdr;
  gdb_int32_bytes oi_pathname;
  gdb_int32_bytes oi_pathname_len;
};

struct irix_elf64_obj_info
{
  gdb_int32_bytes oi_magic;
  gdb_int32_bytes oi_size;
  gdb_int64_bytes oi_next;
  gdb_int64_bytes oi_prev;
  gdb_int64_bytes oi_ehdr;
  gdb_int64_bytes oi_orig_ehdr;
  gdb_int64_bytes oi_pathname;
  gdb_int32_bytes oi_pathname_len;
  gdb_int32_bytes padding;
};

/* Union of all of the above (plus a split out magic field).  */

union irix_obj_info
{
  gdb_int32_bytes magic;
  struct irix_obj_list ol32;
  struct irix_elf32_obj_info oi32;
  struct irix_elf64_obj_info oi64;
};

/* MIPS sign extends its 32 bit addresses.  We could conceivably use
   extract_typed_address here, but to do so, we'd have to construct an
   appropriate type.  Calling extract_signed_integer or
   extract_address seems simpler.  */

static CORE_ADDR
extract_mips_address (void *addr, int len)
{
  if (len <= 32)
    return extract_signed_integer (addr, len);
  else
    return extract_address (addr, len);
}

/* Fetch and return the link map data associated with ADDR.  Note that
   this routine automatically determines which (of three) link map
   formats is in use by the target.  */

struct lm_info
fetch_lm_info (CORE_ADDR addr)
{
  struct lm_info li;
  union irix_obj_info buf;

  li.addr = addr;

  /* The smallest region that we'll need is for buf.ol32.  We'll read
     that first.  We'll read more of the buffer later if we have to deal
     with one of the other cases.  (We don't want to incur a memory error
     if we were to read a larger region that generates an error due to
     being at the end of a page or the like.)  */
  read_memory (addr, (char *) &buf, sizeof (buf.ol32));

  if (extract_unsigned_integer (&buf.magic, sizeof (buf.magic)) != 0xffffffff)
    {
      /* Use buf.ol32... */
      char obj_buf[432];
      CORE_ADDR obj_addr = extract_mips_address (&buf.ol32.data,
						 sizeof (buf.ol32.data));
      li.next = extract_mips_address (&buf.ol32.next, sizeof (buf.ol32.next));

      read_memory (obj_addr, obj_buf, sizeof (obj_buf));

      li.pathname_addr = extract_mips_address (&obj_buf[236], 4);
      li.pathname_len = 0;	/* unknown */
      li.reloc_offset = extract_mips_address (&obj_buf[196], 4)
	- extract_mips_address (&obj_buf[248], 4);

    }
  else if (extract_unsigned_integer (&buf.oi32.oi_size,
				     sizeof (buf.oi32.oi_size))
	   == sizeof (buf.oi32))
    {
      /* Use buf.oi32...  */

      /* Read rest of buffer.  */
      read_memory (addr + sizeof (buf.ol32),
		   ((char *) &buf) + sizeof (buf.ol32),
		   sizeof (buf.oi32) - sizeof (buf.ol32));

      /* Fill in fields using buffer contents.  */
      li.next = extract_mips_address (&buf.oi32.oi_next,
				      sizeof (buf.oi32.oi_next));
      li.reloc_offset = extract_mips_address (&buf.oi32.oi_ehdr,
					      sizeof (buf.oi32.oi_ehdr))
	- extract_mips_address (&buf.oi32.oi_orig_ehdr,
				sizeof (buf.oi32.oi_orig_ehdr));
      li.pathname_addr = extract_mips_address (&buf.oi32.oi_pathname,
					       sizeof (buf.oi32.oi_pathname));
      li.pathname_len = extract_unsigned_integer (&buf.oi32.oi_pathname_len,
						  sizeof (buf.oi32.
							  oi_pathname_len));
    }
  else if (extract_unsigned_integer (&buf.oi64.oi_size,
				     sizeof (buf.oi64.oi_size))
	   == sizeof (buf.oi64))
    {
      /* Use buf.oi64...  */

      /* Read rest of buffer.  */
      read_memory (addr + sizeof (buf.ol32),
		   ((char *) &buf) + sizeof (buf.ol32),
		   sizeof (buf.oi64) - sizeof (buf.ol32));

      /* Fill in fields using buffer contents.  */
      li.next = extract_mips_address (&buf.oi64.oi_next,
				      sizeof (buf.oi64.oi_next));
      li.reloc_offset = extract_mips_address (&buf.oi64.oi_ehdr,
					      sizeof (buf.oi64.oi_ehdr))
	- extract_mips_address (&buf.oi64.oi_orig_ehdr,
				sizeof (buf.oi64.oi_orig_ehdr));
      li.pathname_addr = extract_mips_address (&buf.oi64.oi_pathname,
					       sizeof (buf.oi64.oi_pathname));
      li.pathname_len = extract_unsigned_integer (&buf.oi64.oi_pathname_len,
						  sizeof (buf.oi64.
							  oi_pathname_len));
    }
  else
    {
      error ("Unable to fetch shared library obj_info or obj_list info.");
    }

  return li;
}

/* The symbol which starts off the list of shared libraries.  */
#define DEBUG_BASE "__rld_obj_head"

char shadow_contents[BREAKPOINT_MAX];	/* Stash old bkpt addr contents */

static CORE_ADDR debug_base;	/* Base of dynamic linker structures */
static CORE_ADDR breakpoint_addr;	/* Address where end bkpt is set */

/*

   LOCAL FUNCTION

   locate_base -- locate the base address of dynamic linker structs

   SYNOPSIS

   CORE_ADDR locate_base (void)

   DESCRIPTION

   For both the SunOS and SVR4 shared library implementations, if the
   inferior executable has been linked dynamically, there is a single
   address somewhere in the inferior's data space which is the key to
   locating all of the dynamic linker's runtime structures.  This
   address is the value of the symbol defined by the macro DEBUG_BASE.
   The job of this function is to find and return that address, or to
   return 0 if there is no such address (the executable is statically
   linked for example).

   For SunOS, the job is almost trivial, since the dynamic linker and
   all of it's structures are statically linked to the executable at
   link time.  Thus the symbol for the address we are looking for has
   already been added to the minimal symbol table for the executable's
   objfile at the time the symbol file's symbols were read, and all we
   have to do is look it up there.  Note that we explicitly do NOT want
   to find the copies in the shared library.

   The SVR4 version is much more complicated because the dynamic linker
   and it's structures are located in the shared C library, which gets
   run as the executable's "interpreter" by the kernel.  We have to go
   to a lot more work to discover the address of DEBUG_BASE.  Because
   of this complexity, we cache the value we find and return that value
   on subsequent invocations.  Note there is no copy in the executable
   symbol tables.

   Irix 5 is basically like SunOS.

   Note that we can assume nothing about the process state at the time
   we need to find this address.  We may be stopped on the first instruc-
   tion of the interpreter (C shared library), the first instruction of
   the executable itself, or somewhere else entirely (if we attached
   to the process for example).

 */

static CORE_ADDR
locate_base (void)
{
  struct minimal_symbol *msymbol;
  CORE_ADDR address = 0;

  msymbol = lookup_minimal_symbol (DEBUG_BASE, NULL, symfile_objfile);
  if ((msymbol != NULL) && (SYMBOL_VALUE_ADDRESS (msymbol) != 0))
    {
      address = SYMBOL_VALUE_ADDRESS (msymbol);
    }
  return (address);
}

/*

   LOCAL FUNCTION

   disable_break -- remove the "mapping changed" breakpoint

   SYNOPSIS

   static int disable_break ()

   DESCRIPTION

   Removes the breakpoint that gets hit when the dynamic linker
   completes a mapping change.

 */

static int
disable_break (void)
{
  int status = 1;


  /* Note that breakpoint address and original contents are in our address
     space, so we just need to write the original contents back. */

  if (memory_remove_breakpoint (breakpoint_addr, shadow_contents) != 0)
    {
      status = 0;
    }

  /* For the SVR4 version, we always know the breakpoint address.  For the
     SunOS version we don't know it until the above code is executed.
     Grumble if we are stopped anywhere besides the breakpoint address. */

  if (stop_pc != breakpoint_addr)
    {
      warning
	("stopped at unknown breakpoint while handling shared libraries");
    }

  return (status);
}

/*

   LOCAL FUNCTION

   enable_break -- arrange for dynamic linker to hit breakpoint

   SYNOPSIS

   int enable_break (void)

   DESCRIPTION

   This functions inserts a breakpoint at the entry point of the
   main executable, where all shared libraries are mapped in.
 */

static int
enable_break (void)
{
  if (symfile_objfile != NULL
      && target_insert_breakpoint (symfile_objfile->ei.entry_point,
				   shadow_contents) == 0)
    {
      breakpoint_addr = symfile_objfile->ei.entry_point;
      return 1;
    }

  return 0;
}

/*

   LOCAL FUNCTION

   irix_solib_create_inferior_hook -- shared library startup support

   SYNOPSIS

   void solib_create_inferior_hook()

   DESCRIPTION

   When gdb starts up the inferior, it nurses it along (through the
   shell) until it is ready to execute it's first instruction.  At this
   point, this function gets called via expansion of the macro
   SOLIB_CREATE_INFERIOR_HOOK.

   For SunOS executables, this first instruction is typically the
   one at "_start", or a similar text label, regardless of whether
   the executable is statically or dynamically linked.  The runtime
   startup code takes care of dynamically linking in any shared
   libraries, once gdb allows the inferior to continue.

   For SVR4 executables, this first instruction is either the first
   instruction in the dynamic linker (for dynamically linked
   executables) or the instruction at "start" for statically linked
   executables.  For dynamically linked executables, the system
   first exec's /lib/libc.so.N, which contains the dynamic linker,
   and starts it running.  The dynamic linker maps in any needed
   shared libraries, maps in the actual user executable, and then
   jumps to "start" in the user executable.

   For both SunOS shared libraries, and SVR4 shared libraries, we
   can arrange to cooperate with the dynamic linker to discover the
   names of shared libraries that are dynamically linked, and the
   base addresses to which they are linked.

   This function is responsible for discovering those names and
   addresses, and saving sufficient information about them to allow
   their symbols to be read at a later time.

   FIXME

   Between enable_break() and disable_break(), this code does not
   properly handle hitting breakpoints which the user might have
   set in the startup code or in the dynamic linker itself.  Proper
   handling will probably have to wait until the implementation is
   changed to use the "breakpoint handler function" method.

   Also, what if child has exit()ed?  Must exit loop somehow.
 */

static void
irix_solib_create_inferior_hook (void)
{
  if (!enable_break ())
    {
      warning ("shared library handler failed to enable breakpoint");
      return;
    }

  /* Now run the target.  It will eventually hit the breakpoint, at
     which point all of the libraries will have been mapped in and we
     can go groveling around in the dynamic linker structures to find
     out what we need to know about them. */

  clear_proceed_status ();
  stop_soon_quietly = 1;
  stop_signal = TARGET_SIGNAL_0;
  do
    {
      target_resume (pid_to_ptid (-1), 0, stop_signal);
      wait_for_inferior ();
    }
  while (stop_signal != TARGET_SIGNAL_TRAP);

  /* We are now either at the "mapping complete" breakpoint (or somewhere
     else, a condition we aren't prepared to deal with anyway), so adjust
     the PC as necessary after a breakpoint, disable the breakpoint, and
     add any shared libraries that were mapped in. */

  if (!disable_break ())
    {
      warning ("shared library handler failed to disable breakpoint");
    }

  /* solib_add will call reinit_frame_cache.
     But we are stopped in the startup code and we might not have symbols
     for the startup code, so heuristic_proc_start could be called
     and will put out an annoying warning.
     Delaying the resetting of stop_soon_quietly until after symbol loading
     suppresses the warning.  */
  solib_add ((char *) 0, 0, (struct target_ops *) 0, auto_solib_add);
  stop_soon_quietly = 0;
  re_enable_breakpoints_in_shlibs ();
}

/* LOCAL FUNCTION

   current_sos -- build a list of currently loaded shared objects

   SYNOPSIS

   struct so_list *current_sos ()

   DESCRIPTION

   Build a list of `struct so_list' objects describing the shared
   objects currently loaded in the inferior.  This list does not
   include an entry for the main executable file.

   Note that we only gather information directly available from the
   inferior --- we don't examine any of the shared library files
   themselves.  The declaration of `struct so_list' says which fields
   we provide values for.  */

static struct so_list *
irix_current_sos (void)
{
  CORE_ADDR lma;
  char addr_buf[8];
  struct so_list *head = 0;
  struct so_list **link_ptr = &head;
  int is_first = 1;
  struct lm_info lm;

  /* Make sure we've looked up the inferior's dynamic linker's base
     structure.  */
  if (!debug_base)
    {
      debug_base = locate_base ();

      /* If we can't find the dynamic linker's base structure, this
         must not be a dynamically linked executable.  Hmm.  */
      if (!debug_base)
	return 0;
    }

  read_memory (debug_base, addr_buf, TARGET_ADDR_BIT / TARGET_CHAR_BIT);
  lma = extract_mips_address (addr_buf, TARGET_ADDR_BIT / TARGET_CHAR_BIT);

  while (lma)
    {
      lm = fetch_lm_info (lma);
      if (!is_first)
	{
	  int errcode;
	  char *name_buf;
	  int name_size;
	  struct so_list *new
	    = (struct so_list *) xmalloc (sizeof (struct so_list));
	  struct cleanup *old_chain = make_cleanup (xfree, new);

	  memset (new, 0, sizeof (*new));

	  new->lm_info = xmalloc (sizeof (struct lm_info));
	  make_cleanup (xfree, new->lm_info);

	  *new->lm_info = lm;

	  /* Extract this shared object's name.  */
	  name_size = lm.pathname_len;
	  if (name_size == 0)
	    name_size = SO_NAME_MAX_PATH_SIZE - 1;

	  if (name_size >= SO_NAME_MAX_PATH_SIZE)
	    {
	      name_size = SO_NAME_MAX_PATH_SIZE - 1;
	      warning
		("current_sos: truncating name of %d characters to only %d characters",
		 lm.pathname_len, name_size);
	    }

	  target_read_string (lm.pathname_addr, &name_buf,
			      name_size, &errcode);
	  if (errcode != 0)
	    {
	      warning ("current_sos: Can't read pathname for load map: %s\n",
		       safe_strerror (errcode));
	    }
	  else
	    {
	      strncpy (new->so_name, name_buf, name_size);
	      new->so_name[name_size] = '\0';
	      xfree (name_buf);
	      strcpy (new->so_original_name, new->so_name);
	    }

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

	  discard_cleanups (old_chain);
	}
      is_first = 0;
      lma = lm.next;
    }

  return head;
}

/*

  LOCAL FUNCTION

  irix_open_symbol_file_object

  SYNOPSIS

  void irix_open_symbol_file_object (void *from_tty)

  DESCRIPTION

  If no open symbol file, attempt to locate and open the main symbol
  file.  On IRIX, this is the first link map entry.  If its name is
  here, we can open it.  Useful when attaching to a process without
  first loading its symbol file.

  If FROM_TTYP dereferences to a non-zero integer, allow messages to
  be printed.  This parameter is a pointer rather than an int because
  open_symbol_file_object() is called via catch_errors() and
  catch_errors() requires a pointer argument. */

static int
irix_open_symbol_file_object (void *from_ttyp)
{
  CORE_ADDR lma;
  char addr_buf[8];
  struct lm_info lm;
  struct cleanup *cleanups;
  int errcode;
  int from_tty = *(int *) from_ttyp;
  char *filename;

  if (symfile_objfile)
    if (!query ("Attempt to reload symbols from process? "))
      return 0;

  if ((debug_base = locate_base ()) == 0)
    return 0;			/* failed somehow...  */

  /* First link map member should be the executable.  */
  read_memory (debug_base, addr_buf, TARGET_ADDR_BIT / TARGET_CHAR_BIT);
  lma = extract_mips_address (addr_buf, TARGET_ADDR_BIT / TARGET_CHAR_BIT);
  if (lma == 0)
    return 0;			/* failed somehow...  */

  lm = fetch_lm_info (lma);

  if (lm.pathname_addr == 0)
    return 0;			/* No filename.  */

  /* Now fetch the filename from target memory.  */
  target_read_string (lm.pathname_addr, &filename, SO_NAME_MAX_PATH_SIZE - 1,
		      &errcode);

  if (errcode)
    {
      warning ("failed to read exec filename from attached file: %s",
	       safe_strerror (errcode));
      return 0;
    }

  cleanups = make_cleanup (xfree, filename);
  /* Have a pathname: read the symbol file.  */
  symbol_file_add_main (filename, from_tty);

  do_cleanups (cleanups);

  return 1;
}


/*

   LOCAL FUNCTION

   irix_special_symbol_handling -- additional shared library symbol handling

   SYNOPSIS

   void irix_special_symbol_handling ()

   DESCRIPTION

   Once the symbols from a shared object have been loaded in the usual
   way, we are called to do any system specific symbol handling that 
   is needed.

   For SunOS4, this consisted of grunging around in the dynamic
   linkers structures to find symbol definitions for "common" symbols
   and adding them to the minimal symbol table for the runtime common
   objfile.

   However, for IRIX, there's nothing to do.

 */

static void
irix_special_symbol_handling (void)
{
}

/* Using the solist entry SO, relocate the addresses in SEC.  */

static void
irix_relocate_section_addresses (struct so_list *so,
				 struct section_table *sec)
{
  sec->addr += so->lm_info->reloc_offset;
  sec->endaddr += so->lm_info->reloc_offset;
}

/* Free the lm_info struct.  */

static void
irix_free_so (struct so_list *so)
{
  xfree (so->lm_info);
}

/* Clear backend specific state.  */

static void
irix_clear_solib (void)
{
  debug_base = 0;
}

/* Return 1 if PC lies in the dynamic symbol resolution code of the
   run time loader.  */
static int
irix_in_dynsym_resolve_code (CORE_ADDR pc)
{
  return 0;
}

static struct target_so_ops irix_so_ops;

void
_initialize_irix_solib (void)
{
  irix_so_ops.relocate_section_addresses = irix_relocate_section_addresses;
  irix_so_ops.free_so = irix_free_so;
  irix_so_ops.clear_solib = irix_clear_solib;
  irix_so_ops.solib_create_inferior_hook = irix_solib_create_inferior_hook;
  irix_so_ops.special_symbol_handling = irix_special_symbol_handling;
  irix_so_ops.current_sos = irix_current_sos;
  irix_so_ops.open_symbol_file_object = irix_open_symbol_file_object;
  irix_so_ops.in_dynsym_resolve_code = irix_in_dynsym_resolve_code;

  /* FIXME: Don't do this here.  *_gdbarch_init() should set so_ops. */
  current_target_so_ops = &irix_so_ops;
}
