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