/* Handle COFF SVR3 shared libraries for GDB, the GNU Debugger.
   Copyright 1993 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 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 "frame.h"
#include "bfd.h"
#include "gdbcore.h"
#include "symtab.h"

/*

   GLOBAL FUNCTION

   coff_solib_add -- add a shared library files to the symtab list.  We
   examine the `.lib' section of the exec file and determine the names of
   the shared libraries.

   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.

   SYNOPSIS

   void coff_solib_add (char *arg_string, int from_tty,
   struct target_ops *target)

   DESCRIPTION

 */

void
coff_solib_add (arg_string, from_tty, target)
     char *arg_string;
     int from_tty;
     struct target_ops *target;
{
  asection *libsect;

  libsect = bfd_get_section_by_name (exec_bfd, ".lib");

  if (libsect)
    {
      int libsize;
      unsigned char *lib;
      struct libent
	{
	  bfd_byte len[4];
	  bfd_byte nameoffset[4];
	};

      libsize = bfd_section_size (exec_bfd, libsect);

      lib = (unsigned char *) alloca (libsize);

      bfd_get_section_contents (exec_bfd, libsect, lib, 0, libsize);

      while (libsize > 0)
	{
	  struct libent *ent;
	  struct objfile *objfile;
	  int len, nameoffset;
	  char *filename;

	  ent = (struct libent *) lib;

	  len = bfd_get_32 (exec_bfd, ent->len);

	  nameoffset = bfd_get_32 (exec_bfd, ent->nameoffset);

	  if (len <= 0)
	    break;

	  filename = (char *) ent + nameoffset * 4;

	  objfile = symbol_file_add (filename, from_tty,
				     0,		/* addr */
				     0,		/* not mainline */
				     0,		/* not mapped */
				     0,		/* Not readnow */
				     0,		/* Not user loaded */
				     1);	/* Is a solib */

	  libsize -= len * 4;
	  lib += len * 4;
	}

      /* Getting new symbols may change our opinion about what is
         frameless.  */
      reinit_frame_cache ();
    }
}

/*

   GLOBAL FUNCTION

   coff_solib_create_inferior_hook -- shared library startup support

   SYNOPSIS

   void coff_solib_create_inferior_hook()

   DESCRIPTION

   When gdb starts up the inferior, the kernel maps in the shared
   libraries.  We get here with the target stopped at it's first
   instruction, and the libraries already mapped.  At this      point, this
   function gets called via expansion of the macro
   SOLIB_CREATE_INFERIOR_HOOK.
 */

void
coff_solib_create_inferior_hook ()
{
  coff_solib_add ((char *) 0, 0, (struct target_ops *) 0);
}
