1130812Smarcel/* Handle HP SOM shared libraries for GDB, the GNU Debugger.
2130812Smarcel
3130812Smarcel   Copyright 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, 2002,
4130812Smarcel   2003, 2004 Free Software Foundation, Inc.
5130812Smarcel
6130812Smarcel   This file is part of GDB.
7130812Smarcel
8130812Smarcel   This program is free software; you can redistribute it and/or modify
9130812Smarcel   it under the terms of the GNU General Public License as published by
10130812Smarcel   the Free Software Foundation; either version 2 of the License, or
11130812Smarcel   (at your option) any later version.
12130812Smarcel
13130812Smarcel   This program is distributed in the hope that it will be useful,
14130812Smarcel   but WITHOUT ANY WARRANTY; without even the implied warranty of
15130812Smarcel   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16130812Smarcel   GNU General Public License for more details.
17130812Smarcel
18130812Smarcel   You should have received a copy of the GNU General Public License
19130812Smarcel   along with this program; if not, write to the Free Software
20130812Smarcel   Foundation, Inc., 59 Temple Place - Suite 330,
21130812Smarcel   Boston, MA 02111-1307, USA.
22130812Smarcel
23130812Smarcel   Written by the Center for Software Science at the Univerity of Utah
24130812Smarcel   and by Cygnus Support.  */
25130812Smarcel
26130812Smarcel
27130812Smarcel#include "defs.h"
28130812Smarcel
29130812Smarcel#include "frame.h"
30130812Smarcel#include "bfd.h"
31130812Smarcel#include "som.h"
32130812Smarcel#include "libhppa.h"
33130812Smarcel#include "gdbcore.h"
34130812Smarcel#include "symtab.h"
35130812Smarcel#include "breakpoint.h"
36130812Smarcel#include "symfile.h"
37130812Smarcel#include "objfiles.h"
38130812Smarcel#include "inferior.h"
39130812Smarcel#include "gdb-stabs.h"
40130812Smarcel#include "gdb_stat.h"
41130812Smarcel#include "gdbcmd.h"
42130812Smarcel#include "language.h"
43130812Smarcel#include "regcache.h"
44130812Smarcel#include "gdb_assert.h"
45130812Smarcel#include "exec.h"
46130812Smarcel
47130812Smarcel#include <fcntl.h>
48130812Smarcel
49130812Smarcel#ifndef O_BINARY
50130812Smarcel#define O_BINARY 0
51130812Smarcel#endif
52130812Smarcel
53130812Smarcel/* Uncomment this to turn on some debugging output.
54130812Smarcel */
55130812Smarcel
56130812Smarcel/* #define SOLIB_DEBUG
57130812Smarcel */
58130812Smarcel
59130812Smarcel/* This lives in hppa-tdep.c. */
60130812Smarcelextern struct unwind_table_entry *find_unwind_entry (CORE_ADDR pc);
61130812Smarcel
62130812Smarcel/* These ought to be defined in some public interface, but aren't.  They
63130812Smarcel   define the meaning of the various bits in the distinguished __dld_flags
64130812Smarcel   variable that is declared in every debuggable a.out on HP-UX, and that
65130812Smarcel   is shared between the debugger and the dynamic linker.
66130812Smarcel */
67130812Smarcel#define DLD_FLAGS_MAPPRIVATE    0x1
68130812Smarcel#define DLD_FLAGS_HOOKVALID     0x2
69130812Smarcel#define DLD_FLAGS_LISTVALID     0x4
70130812Smarcel#define DLD_FLAGS_BOR_ENABLE    0x8
71130812Smarcel
72130812Smarcel/* TODO:
73130812Smarcel
74130812Smarcel   * Support for hpux8 dynamic linker.  */
75130812Smarcel
76130812Smarcel/* The basic structure which describes a dynamically loaded object.  This
77130812Smarcel   data structure is private to the dynamic linker and isn't found in
78130812Smarcel   any HPUX include file.  */
79130812Smarcel
80130812Smarcelstruct som_solib_mapped_entry
81130812Smarcel  {
82130812Smarcel    /* The name of the library.  */
83130812Smarcel    char *name;
84130812Smarcel
85130812Smarcel    /* Version of this structure (it is expected to change again in hpux10).  */
86130812Smarcel    unsigned char struct_version;
87130812Smarcel
88130812Smarcel    /* Binding mode for this library.  */
89130812Smarcel    unsigned char bind_mode;
90130812Smarcel
91130812Smarcel    /* Version of this library.  */
92130812Smarcel    short library_version;
93130812Smarcel
94130812Smarcel    /* Start of text address,
95130812Smarcel     * link-time text location (length of text area),
96130812Smarcel     * end of text address.  */
97130812Smarcel    CORE_ADDR text_addr;
98130812Smarcel    CORE_ADDR text_link_addr;
99130812Smarcel    CORE_ADDR text_end;
100130812Smarcel
101130812Smarcel    /* Start of data, start of bss and end of data.  */
102130812Smarcel    CORE_ADDR data_start;
103130812Smarcel    CORE_ADDR bss_start;
104130812Smarcel    CORE_ADDR data_end;
105130812Smarcel
106130812Smarcel    /* Value of linkage pointer (%r19).  */
107130812Smarcel    CORE_ADDR got_value;
108130812Smarcel
109130812Smarcel    /* Next entry.  */
110130812Smarcel    struct som_solib_mapped_entry *next;
111130812Smarcel
112130812Smarcel    /* There are other fields, but I don't have information as to what is
113130812Smarcel       contained in them.  */
114130812Smarcel
115130812Smarcel    /* For versions from HPUX-10.30 and up */
116130812Smarcel
117130812Smarcel    /* Address in target of offset from thread-local register of
118130812Smarcel     * start of this thread's data.  I.e., the first thread-local
119130812Smarcel     * variable in this shared library starts at *(tsd_start_addr)
120130812Smarcel     * from that area pointed to by cr27 (mpsfu_hi).
121130812Smarcel     *
122130812Smarcel     * We do the indirection as soon as we read it, so from then
123130812Smarcel     * on it's the offset itself.
124130812Smarcel     */
125130812Smarcel    CORE_ADDR tsd_start_addr;
126130812Smarcel
127130812Smarcel    /* Following this are longwords holding:
128130812Smarcel
129130812Smarcel     * ?, ?, ?, ptr to -1, ptr to-1, ptr to lib name (leaf name),
130130812Smarcel     * ptr to __data_start, ptr to __data_end
131130812Smarcel     */
132130812Smarcel
133130812Smarcel
134130812Smarcel  };
135130812Smarcel
136130812Smarcel/* A structure to keep track of all the known shared objects.  */
137130812Smarcelstruct so_list
138130812Smarcel  {
139130812Smarcel    struct som_solib_mapped_entry som_solib;
140130812Smarcel    struct objfile *objfile;
141130812Smarcel    bfd *abfd;
142130812Smarcel    struct section_table *sections;
143130812Smarcel    struct section_table *sections_end;
144130812Smarcel/* elz: added this field to store the address in target space (in the
145130812Smarcel   library) of the library descriptor (handle) which we read into
146130812Smarcel   som_solib_mapped_entry structure */
147130812Smarcel    CORE_ADDR solib_addr;
148130812Smarcel    struct so_list *next;
149130812Smarcel
150130812Smarcel  };
151130812Smarcel
152130812Smarcelstatic struct so_list *so_list_head;
153130812Smarcel
154130812Smarcel
155130812Smarcel/* This is the cumulative size in bytes of the symbol tables of all
156130812Smarcel   shared objects on the so_list_head list.  (When we say size, here
157130812Smarcel   we mean of the information before it is brought into memory and
158130812Smarcel   potentially expanded by GDB.)  When adding a new shlib, this value
159130812Smarcel   is compared against the threshold size, held by auto_solib_limit
160130812Smarcel   (in megabytes).  If adding symbols for the new shlib would cause
161130812Smarcel   the total size to exceed the threshold, then the new shlib's
162130812Smarcel   symbols are not loaded.  */
163130812Smarcelstatic LONGEST som_solib_total_st_size;
164130812Smarcel
165130812Smarcel/* When the threshold is reached for any shlib, we refuse to add
166130812Smarcel   symbols for subsequent shlibs, even if those shlibs' symbols would
167130812Smarcel   be small enough to fit under the threshold.  (Although this may
168130812Smarcel   result in one, early large shlib preventing the loading of later,
169130812Smarcel   smalller shlibs' symbols, it allows us to issue one informational
170130812Smarcel   message.  The alternative, to issue a message for each shlib whose
171130812Smarcel   symbols aren't loaded, could be a big annoyance where the threshold
172130812Smarcel   is exceeded due to a very large number of shlibs.)
173130812Smarcel */
174130812Smarcelstatic int som_solib_st_size_threshold_exceeded;
175130812Smarcel
176130812Smarcel/* These addresses should be filled in by som_solib_create_inferior_hook.
177130812Smarcel   They are also used elsewhere in this module.
178130812Smarcel */
179130812Smarceltypedef struct
180130812Smarcel  {
181130812Smarcel    CORE_ADDR address;
182130812Smarcel    struct unwind_table_entry *unwind;
183130812Smarcel  }
184130812Smarceladdr_and_unwind_t;
185130812Smarcel
186130812Smarcel/* When adding fields, be sure to clear them in _initialize_som_solib. */
187130812Smarcelstatic struct
188130812Smarcel  {
189130812Smarcel    int is_valid;
190130812Smarcel    addr_and_unwind_t hook;
191130812Smarcel    addr_and_unwind_t hook_stub;
192130812Smarcel    addr_and_unwind_t load;
193130812Smarcel    addr_and_unwind_t load_stub;
194130812Smarcel    addr_and_unwind_t unload;
195130812Smarcel    addr_and_unwind_t unload2;
196130812Smarcel    addr_and_unwind_t unload_stub;
197130812Smarcel  }
198130812Smarceldld_cache;
199130812Smarcel
200130812Smarcel
201130812Smarcel
202130812Smarcelstatic void som_sharedlibrary_info_command (char *, int);
203130812Smarcel
204130812Smarcelstatic void som_solib_sharedlibrary_command (char *, int);
205130812Smarcel
206130812Smarcelstatic LONGEST
207130812Smarcelsom_solib_sizeof_symbol_table (char *filename)
208130812Smarcel{
209130812Smarcel  bfd *abfd;
210130812Smarcel  int desc;
211130812Smarcel  char *absolute_name;
212130812Smarcel  LONGEST st_size = (LONGEST) 0;
213130812Smarcel  asection *sect;
214130812Smarcel
215130812Smarcel  /* We believe that filename was handed to us by the dynamic linker, and
216130812Smarcel     is therefore always an absolute path.
217130812Smarcel   */
218130812Smarcel  desc = openp (getenv ("PATH"), 1, filename, O_RDONLY | O_BINARY, 0, &absolute_name);
219130812Smarcel  if (desc < 0)
220130812Smarcel    {
221130812Smarcel      perror_with_name (filename);
222130812Smarcel    }
223130812Smarcel  filename = absolute_name;
224130812Smarcel
225130812Smarcel  abfd = bfd_fdopenr (filename, gnutarget, desc);
226130812Smarcel  if (!abfd)
227130812Smarcel    {
228130812Smarcel      close (desc);
229130812Smarcel      make_cleanup (xfree, filename);
230130812Smarcel      error ("\"%s\": can't open to read symbols: %s.", filename,
231130812Smarcel	     bfd_errmsg (bfd_get_error ()));
232130812Smarcel    }
233130812Smarcel
234130812Smarcel  if (!bfd_check_format (abfd, bfd_object))	/* Reads in section info */
235130812Smarcel    {
236130812Smarcel      bfd_close (abfd);		/* This also closes desc */
237130812Smarcel      make_cleanup (xfree, filename);
238130812Smarcel      error ("\"%s\": can't read symbols: %s.", filename,
239130812Smarcel	     bfd_errmsg (bfd_get_error ()));
240130812Smarcel    }
241130812Smarcel
242130812Smarcel  /* Sum the sizes of the various sections that compose debug info. */
243130812Smarcel
244130812Smarcel  /* This contains non-DOC information. */
245130812Smarcel  sect = bfd_get_section_by_name (abfd, "$DEBUG$");
246130812Smarcel  if (sect)
247130812Smarcel    st_size += (LONGEST) bfd_section_size (abfd, sect);
248130812Smarcel
249130812Smarcel  /* This contains DOC information. */
250130812Smarcel  sect = bfd_get_section_by_name (abfd, "$PINFO$");
251130812Smarcel  if (sect)
252130812Smarcel    st_size += (LONGEST) bfd_section_size (abfd, sect);
253130812Smarcel
254130812Smarcel  bfd_close (abfd);		/* This also closes desc */
255130812Smarcel  xfree (filename);
256130812Smarcel
257130812Smarcel  /* Unfortunately, just summing the sizes of various debug info
258130812Smarcel     sections isn't a very accurate measurement of how much heap
259130812Smarcel     space the debugger will need to hold them.  It also doesn't
260130812Smarcel     account for space needed by linker (aka "minimal") symbols.
261130812Smarcel
262130812Smarcel     Anecdotal evidence suggests that just summing the sizes of
263130812Smarcel     debug-info-related sections understates the heap space needed
264130812Smarcel     to represent it internally by about an order of magnitude.
265130812Smarcel
266130812Smarcel     Since it's not exactly brain surgery we're doing here, rather
267130812Smarcel     than attempt to more accurately measure the size of a shlib's
268130812Smarcel     symbol table in GDB's heap, we'll just apply a 10x fudge-
269130812Smarcel     factor to the debug info sections' size-sum.  No, this doesn't
270130812Smarcel     account for minimal symbols in non-debuggable shlibs.  But it
271130812Smarcel     all roughly washes out in the end.
272130812Smarcel   */
273130812Smarcel  return st_size * (LONGEST) 10;
274130812Smarcel}
275130812Smarcel
276130812Smarcel
277130812Smarcelstatic void
278130812Smarcelsom_solib_add_solib_objfile (struct so_list *so, char *name, int from_tty,
279130812Smarcel			     CORE_ADDR text_addr)
280130812Smarcel{
281130812Smarcel  obj_private_data_t *obj_private;
282130812Smarcel  struct obj_section *s;
283130812Smarcel
284130812Smarcel  so->objfile = symbol_file_add (name, from_tty, NULL, 0, OBJF_SHARED);
285130812Smarcel  so->abfd = so->objfile->obfd;
286130812Smarcel
287130812Smarcel  /* syms_from_objfile has bizarre section offset code,
288130812Smarcel     so I do my own right here.  */
289130812Smarcel  for (s = so->objfile->sections; s < so->objfile->sections_end; s++)
290130812Smarcel    {
291130812Smarcel      flagword aflag = bfd_get_section_flags(so->abfd, s->the_bfd_section);
292130812Smarcel      if (aflag & SEC_CODE)
293130812Smarcel	{
294130812Smarcel	  s->addr    += so->som_solib.text_addr - so->som_solib.text_link_addr;
295130812Smarcel	  s->endaddr += so->som_solib.text_addr - so->som_solib.text_link_addr;
296130812Smarcel	}
297130812Smarcel      else if (aflag & SEC_DATA)
298130812Smarcel	{
299130812Smarcel	  s->addr    += so->som_solib.data_start;
300130812Smarcel	  s->endaddr += so->som_solib.data_start;
301130812Smarcel	}
302130812Smarcel      else
303130812Smarcel	;
304130812Smarcel    }
305130812Smarcel
306130812Smarcel  /* Mark this as a shared library and save private data.
307130812Smarcel   */
308130812Smarcel  so->objfile->flags |= OBJF_SHARED;
309130812Smarcel
310130812Smarcel  if (so->objfile->obj_private == NULL)
311130812Smarcel    {
312130812Smarcel      obj_private = (obj_private_data_t *)
313130812Smarcel	obstack_alloc (&so->objfile->objfile_obstack,
314130812Smarcel		       sizeof (obj_private_data_t));
315130812Smarcel      obj_private->unwind_info = NULL;
316130812Smarcel      obj_private->so_info = NULL;
317130812Smarcel      so->objfile->obj_private = obj_private;
318130812Smarcel    }
319130812Smarcel
320130812Smarcel  obj_private = (obj_private_data_t *) so->objfile->obj_private;
321130812Smarcel  obj_private->so_info = so;
322130812Smarcel
323130812Smarcel  if (!bfd_check_format (so->abfd, bfd_object))
324130812Smarcel    {
325130812Smarcel      error ("\"%s\": not in executable format: %s.",
326130812Smarcel	     name, bfd_errmsg (bfd_get_error ()));
327130812Smarcel    }
328130812Smarcel}
329130812Smarcel
330130812Smarcel
331130812Smarcelstatic void
332130812Smarcelsom_solib_load_symbols (struct so_list *so, char *name, int from_tty,
333130812Smarcel			CORE_ADDR text_addr, struct target_ops *target)
334130812Smarcel{
335130812Smarcel  struct section_table *p;
336130812Smarcel  int status;
337130812Smarcel  char buf[4];
338130812Smarcel  CORE_ADDR presumed_data_start;
339130812Smarcel
340130812Smarcel#ifdef SOLIB_DEBUG
341130812Smarcel  printf ("--Adding symbols for shared library \"%s\"\n", name);
342130812Smarcel#endif
343130812Smarcel
344130812Smarcel  som_solib_add_solib_objfile (so, name, from_tty, text_addr);
345130812Smarcel
346130812Smarcel  /* Now we need to build a section table for this library since
347130812Smarcel     we might be debugging a core file from a dynamically linked
348130812Smarcel     executable in which the libraries were not privately mapped.  */
349130812Smarcel  if (build_section_table (so->abfd,
350130812Smarcel			   &so->sections,
351130812Smarcel			   &so->sections_end))
352130812Smarcel    {
353130812Smarcel      error ("Unable to build section table for shared library\n.");
354130812Smarcel      return;
355130812Smarcel    }
356130812Smarcel
357130812Smarcel  /* Relocate all the sections based on where they got loaded.  */
358130812Smarcel  for (p = so->sections; p < so->sections_end; p++)
359130812Smarcel    {
360130812Smarcel      if (p->the_bfd_section->flags & SEC_CODE)
361130812Smarcel	{
362130812Smarcel	  p->addr += ANOFFSET (so->objfile->section_offsets, SECT_OFF_TEXT (so->objfile));
363130812Smarcel	  p->endaddr += ANOFFSET (so->objfile->section_offsets, SECT_OFF_TEXT (so->objfile));
364130812Smarcel	}
365130812Smarcel      else if (p->the_bfd_section->flags & SEC_DATA)
366130812Smarcel	{
367130812Smarcel	  p->addr += ANOFFSET (so->objfile->section_offsets, SECT_OFF_DATA (so->objfile));
368130812Smarcel	  p->endaddr += ANOFFSET (so->objfile->section_offsets, SECT_OFF_DATA (so->objfile));
369130812Smarcel	}
370130812Smarcel    }
371130812Smarcel
372130812Smarcel  /* Now see if we need to map in the text and data for this shared
373130812Smarcel     library (for example debugging a core file which does not use
374130812Smarcel     private shared libraries.).
375130812Smarcel
376130812Smarcel     Carefully peek at the first text address in the library.  If the
377130812Smarcel     read succeeds, then the libraries were privately mapped and were
378130812Smarcel     included in the core dump file.
379130812Smarcel
380130812Smarcel     If the peek failed, then the libraries were not privately mapped
381130812Smarcel     and are not in the core file, we'll have to read them in ourselves.  */
382130812Smarcel  status = target_read_memory (text_addr, buf, 4);
383130812Smarcel  if (status != 0)
384130812Smarcel    {
385130812Smarcel      int old, new;
386130812Smarcel
387130812Smarcel      new = so->sections_end - so->sections;
388130812Smarcel
389130812Smarcel      old = target_resize_to_sections (target, new);
390130812Smarcel
391130812Smarcel      /* Copy over the old data before it gets clobbered.  */
392130812Smarcel      memcpy ((char *) (target->to_sections + old),
393130812Smarcel	      so->sections,
394130812Smarcel	      ((sizeof (struct section_table)) * new));
395130812Smarcel    }
396130812Smarcel}
397130812Smarcel
398130812Smarcel
399130812Smarcel/* FIXME: cagney/2003-02-01: This just isn't right.  Given an address
400130812Smarcel   within the target's address space, this converts the value into an
401130812Smarcel   address within the host's (i.e., GDB's) address space.  Given that
402130812Smarcel   the host/target address spaces are separate, this can't be right.  */
403130812Smarcel
404130812Smarcelstatic void *
405130812Smarcelhpux_address_to_host_pointer_hack (CORE_ADDR addr)
406130812Smarcel{
407130812Smarcel  void *ptr;
408130812Smarcel
409130812Smarcel  gdb_assert (sizeof (ptr) == TYPE_LENGTH (builtin_type_void_data_ptr));
410130812Smarcel  ADDRESS_TO_POINTER (builtin_type_void_data_ptr, &ptr, addr);
411130812Smarcel  return ptr;
412130812Smarcel}
413130812Smarcel
414130812Smarcel/* Add symbols from shared libraries into the symtab list, unless the
415130812Smarcel   size threshold specified by auto_solib_limit (in megabytes) would
416130812Smarcel   be exceeded.  */
417130812Smarcel
418130812Smarcelvoid
419130812Smarcelsom_solib_add (char *arg_string, int from_tty, struct target_ops *target, int readsyms)
420130812Smarcel{
421130812Smarcel  struct minimal_symbol *msymbol;
422130812Smarcel  struct so_list *so_list_tail;
423130812Smarcel  CORE_ADDR addr;
424130812Smarcel  asection *shlib_info;
425130812Smarcel  int status;
426130812Smarcel  unsigned int dld_flags;
427130812Smarcel  char buf[4], *re_err;
428130812Smarcel  int threshold_warning_given = 0;
429130812Smarcel
430130812Smarcel  /* First validate our arguments.  */
431130812Smarcel  re_err = re_comp (arg_string ? arg_string : ".");
432130812Smarcel  if (re_err != NULL)
433130812Smarcel    {
434130812Smarcel      error ("Invalid regexp: %s", re_err);
435130812Smarcel    }
436130812Smarcel
437130812Smarcel  /* If we're debugging a core file, or have attached to a running
438130812Smarcel     process, then som_solib_create_inferior_hook will not have been
439130812Smarcel     called.
440130812Smarcel
441130812Smarcel     We need to first determine if we're dealing with a dynamically
442130812Smarcel     linked executable.  If not, then return without an error or warning.
443130812Smarcel
444130812Smarcel     We also need to examine __dld_flags to determine if the shared library
445130812Smarcel     list is valid and to determine if the libraries have been privately
446130812Smarcel     mapped.  */
447130812Smarcel  if (symfile_objfile == NULL)
448130812Smarcel    return;
449130812Smarcel
450130812Smarcel  /* First see if the objfile was dynamically linked.  */
451130812Smarcel  shlib_info = bfd_get_section_by_name (symfile_objfile->obfd, "$SHLIB_INFO$");
452130812Smarcel  if (!shlib_info)
453130812Smarcel    return;
454130812Smarcel
455130812Smarcel  /* It's got a $SHLIB_INFO$ section, make sure it's not empty.  */
456130812Smarcel  if (bfd_section_size (symfile_objfile->obfd, shlib_info) == 0)
457130812Smarcel    return;
458130812Smarcel
459130812Smarcel  msymbol = lookup_minimal_symbol ("__dld_flags", NULL, NULL);
460130812Smarcel  if (msymbol == NULL)
461130812Smarcel    {
462130812Smarcel      error ("Unable to find __dld_flags symbol in object file.\n");
463130812Smarcel      return;
464130812Smarcel    }
465130812Smarcel
466130812Smarcel  addr = SYMBOL_VALUE_ADDRESS (msymbol);
467130812Smarcel  /* Read the current contents.  */
468130812Smarcel  status = target_read_memory (addr, buf, 4);
469130812Smarcel  if (status != 0)
470130812Smarcel    {
471130812Smarcel      error ("Unable to read __dld_flags\n");
472130812Smarcel      return;
473130812Smarcel    }
474130812Smarcel  dld_flags = extract_unsigned_integer (buf, 4);
475130812Smarcel
476130812Smarcel  /* __dld_list may not be valid.  If not, then we punt, warning the user if
477130812Smarcel     we were called as a result of the add-symfile command.
478130812Smarcel   */
479130812Smarcel  if ((dld_flags & DLD_FLAGS_LISTVALID) == 0)
480130812Smarcel    {
481130812Smarcel      if (from_tty)
482130812Smarcel	error ("__dld_list is not valid according to __dld_flags.\n");
483130812Smarcel      return;
484130812Smarcel    }
485130812Smarcel
486130812Smarcel  /* If the libraries were not mapped private, warn the user.  */
487130812Smarcel  if ((dld_flags & DLD_FLAGS_MAPPRIVATE) == 0)
488130812Smarcel    warning ("The shared libraries were not privately mapped; setting a\nbreakpoint in a shared library will not work until you rerun the program.\n");
489130812Smarcel
490130812Smarcel  msymbol = lookup_minimal_symbol ("__dld_list", NULL, NULL);
491130812Smarcel  if (!msymbol)
492130812Smarcel    {
493130812Smarcel      /* Older crt0.o files (hpux8) don't have __dld_list as a symbol,
494130812Smarcel         but the data is still available if you know where to look.  */
495130812Smarcel      msymbol = lookup_minimal_symbol ("__dld_flags", NULL, NULL);
496130812Smarcel      if (!msymbol)
497130812Smarcel	{
498130812Smarcel	  error ("Unable to find dynamic library list.\n");
499130812Smarcel	  return;
500130812Smarcel	}
501130812Smarcel      addr = SYMBOL_VALUE_ADDRESS (msymbol) - 8;
502130812Smarcel    }
503130812Smarcel  else
504130812Smarcel    addr = SYMBOL_VALUE_ADDRESS (msymbol);
505130812Smarcel
506130812Smarcel  status = target_read_memory (addr, buf, 4);
507130812Smarcel  if (status != 0)
508130812Smarcel    {
509130812Smarcel      error ("Unable to find dynamic library list.\n");
510130812Smarcel      return;
511130812Smarcel    }
512130812Smarcel
513130812Smarcel  addr = extract_unsigned_integer (buf, 4);
514130812Smarcel
515130812Smarcel  /* If addr is zero, then we're using an old dynamic loader which
516130812Smarcel     doesn't maintain __dld_list.  We'll have to use a completely
517130812Smarcel     different approach to get shared library information.  */
518130812Smarcel  if (addr == 0)
519130812Smarcel    goto old_dld;
520130812Smarcel
521130812Smarcel  /* Using the information in __dld_list is the preferred method
522130812Smarcel     to get at shared library information.  It doesn't depend on
523130812Smarcel     any functions in /opt/langtools/lib/end.o and has a chance of working
524130812Smarcel     with hpux10 when it is released.  */
525130812Smarcel  status = target_read_memory (addr, buf, 4);
526130812Smarcel  if (status != 0)
527130812Smarcel    {
528130812Smarcel      error ("Unable to find dynamic library list.\n");
529130812Smarcel      return;
530130812Smarcel    }
531130812Smarcel
532130812Smarcel  /* addr now holds the address of the first entry in the dynamic
533130812Smarcel     library list.  */
534130812Smarcel  addr = extract_unsigned_integer (buf, 4);
535130812Smarcel
536130812Smarcel  /* Now that we have a pointer to the dynamic library list, walk
537130812Smarcel     through it and add the symbols for each library.  */
538130812Smarcel
539130812Smarcel  so_list_tail = so_list_head;
540130812Smarcel  /* Find the end of the list of shared objects.  */
541130812Smarcel  while (so_list_tail && so_list_tail->next)
542130812Smarcel    so_list_tail = so_list_tail->next;
543130812Smarcel
544130812Smarcel#ifdef SOLIB_DEBUG
545130812Smarcel  printf ("--About to read shared library list data\n");
546130812Smarcel#endif
547130812Smarcel
548130812Smarcel  /* "addr" will always point to the base of the
549130812Smarcel   * current data entry describing the current
550130812Smarcel   * shared library.
551130812Smarcel   */
552130812Smarcel  while (1)
553130812Smarcel    {
554130812Smarcel      CORE_ADDR name_addr, text_addr;
555130812Smarcel      unsigned int name_len;
556130812Smarcel      char *name;
557130812Smarcel      struct so_list *new_so;
558130812Smarcel      struct so_list *so_list = so_list_head;
559130812Smarcel      struct stat statbuf;
560130812Smarcel      LONGEST st_size;
561130812Smarcel      int is_main_program;
562130812Smarcel
563130812Smarcel      if (addr == 0)
564130812Smarcel	break;
565130812Smarcel
566130812Smarcel      /* Get a pointer to the name of this library.  */
567130812Smarcel      status = target_read_memory (addr, buf, 4);
568130812Smarcel      if (status != 0)
569130812Smarcel	goto err;
570130812Smarcel
571130812Smarcel      name_addr = extract_unsigned_integer (buf, 4);
572130812Smarcel      name_len = 0;
573130812Smarcel      while (1)
574130812Smarcel	{
575130812Smarcel	  target_read_memory (name_addr + name_len, buf, 1);
576130812Smarcel	  if (status != 0)
577130812Smarcel	    goto err;
578130812Smarcel
579130812Smarcel	  name_len++;
580130812Smarcel	  if (*buf == '\0')
581130812Smarcel	    break;
582130812Smarcel	}
583130812Smarcel      name = alloca (name_len);
584130812Smarcel      status = target_read_memory (name_addr, name, name_len);
585130812Smarcel      if (status != 0)
586130812Smarcel	goto err;
587130812Smarcel
588130812Smarcel      /* See if we've already loaded something with this name.  */
589130812Smarcel      while (so_list)
590130812Smarcel	{
591130812Smarcel	  if (!strcmp (so_list->som_solib.name, name))
592130812Smarcel	    break;
593130812Smarcel	  so_list = so_list->next;
594130812Smarcel	}
595130812Smarcel
596130812Smarcel      /* See if the file exists.  If not, give a warning, but don't
597130812Smarcel         die.  */
598130812Smarcel      status = stat (name, &statbuf);
599130812Smarcel      if (status == -1)
600130812Smarcel	{
601130812Smarcel	  warning ("Can't find file %s referenced in dld_list.", name);
602130812Smarcel
603130812Smarcel	  status = target_read_memory (addr + 36, buf, 4);
604130812Smarcel	  if (status != 0)
605130812Smarcel	    goto err;
606130812Smarcel
607130812Smarcel	  addr = (CORE_ADDR) extract_unsigned_integer (buf, 4);
608130812Smarcel	  continue;
609130812Smarcel	}
610130812Smarcel
611130812Smarcel      /* If we've already loaded this one or it's the main program, skip it.  */
612130812Smarcel      is_main_program = (strcmp (name, symfile_objfile->name) == 0);
613130812Smarcel      if (so_list || is_main_program)
614130812Smarcel	{
615130812Smarcel	  /* This is the "next" pointer in the strcuture.
616130812Smarcel	   */
617130812Smarcel	  status = target_read_memory (addr + 36, buf, 4);
618130812Smarcel	  if (status != 0)
619130812Smarcel	    goto err;
620130812Smarcel
621130812Smarcel	  addr = (CORE_ADDR) extract_unsigned_integer (buf, 4);
622130812Smarcel
623130812Smarcel	  /* Record the main program's symbol table size. */
624130812Smarcel	  if (is_main_program && !so_list)
625130812Smarcel	    {
626130812Smarcel	      st_size = som_solib_sizeof_symbol_table (name);
627130812Smarcel	      som_solib_total_st_size += st_size;
628130812Smarcel	    }
629130812Smarcel
630130812Smarcel	  /* Was this a shlib that we noted but didn't load the symbols for?
631130812Smarcel	     If so, were we invoked this time from the command-line, via
632130812Smarcel	     a 'sharedlibrary' or 'add-symbol-file' command?  If yes to
633130812Smarcel	     both, we'd better load the symbols this time.
634130812Smarcel	   */
635130812Smarcel	  if (from_tty && so_list && !is_main_program && (so_list->objfile == NULL))
636130812Smarcel	    som_solib_load_symbols (so_list,
637130812Smarcel				    name,
638130812Smarcel				    from_tty,
639130812Smarcel				    so_list->som_solib.text_addr,
640130812Smarcel				    target);
641130812Smarcel
642130812Smarcel	  continue;
643130812Smarcel	}
644130812Smarcel
645130812Smarcel      name = obsavestring (name, name_len - 1,
646130812Smarcel			   &symfile_objfile->objfile_obstack);
647130812Smarcel
648130812Smarcel      status = target_read_memory (addr + 8, buf, 4);
649130812Smarcel      if (status != 0)
650130812Smarcel	goto err;
651130812Smarcel
652130812Smarcel      text_addr = extract_unsigned_integer (buf, 4);
653130812Smarcel
654130812Smarcel      new_so = (struct so_list *) xmalloc (sizeof (struct so_list));
655130812Smarcel      memset ((char *) new_so, 0, sizeof (struct so_list));
656130812Smarcel      if (so_list_head == NULL)
657130812Smarcel	{
658130812Smarcel	  so_list_head = new_so;
659130812Smarcel	  so_list_tail = new_so;
660130812Smarcel	}
661130812Smarcel      else
662130812Smarcel	{
663130812Smarcel	  so_list_tail->next = new_so;
664130812Smarcel	  so_list_tail = new_so;
665130812Smarcel	}
666130812Smarcel
667130812Smarcel      /* Fill in all the entries in GDB's shared library list.
668130812Smarcel       */
669130812Smarcel
670130812Smarcel      new_so->solib_addr = addr;
671130812Smarcel      new_so->som_solib.name = name;
672130812Smarcel      status = target_read_memory (addr + 4, buf, 4);
673130812Smarcel      if (status != 0)
674130812Smarcel	goto err;
675130812Smarcel
676130812Smarcel      new_so->som_solib.struct_version = extract_unsigned_integer (buf + 3, 1);
677130812Smarcel      new_so->som_solib.bind_mode = extract_unsigned_integer (buf + 2, 1);
678130812Smarcel      /* Following is "high water mark", highest version number
679130812Smarcel       * seen, rather than plain version number.
680130812Smarcel       */
681130812Smarcel      new_so->som_solib.library_version = extract_unsigned_integer (buf, 2);
682130812Smarcel      new_so->som_solib.text_addr = text_addr;
683130812Smarcel
684130812Smarcel      /* Q: What about longword at "addr + 8"?
685130812Smarcel       * A: It's read above, out of order, into "text_addr".
686130812Smarcel       */
687130812Smarcel
688130812Smarcel      status = target_read_memory (addr + 12, buf, 4);
689130812Smarcel      if (status != 0)
690130812Smarcel	goto err;
691130812Smarcel
692130812Smarcel      new_so->som_solib.text_link_addr = extract_unsigned_integer (buf, 4);
693130812Smarcel
694130812Smarcel      status = target_read_memory (addr + 16, buf, 4);
695130812Smarcel      if (status != 0)
696130812Smarcel	goto err;
697130812Smarcel
698130812Smarcel      new_so->som_solib.text_end = extract_unsigned_integer (buf, 4);
699130812Smarcel
700130812Smarcel      status = target_read_memory (addr + 20, buf, 4);
701130812Smarcel      if (status != 0)
702130812Smarcel	goto err;
703130812Smarcel
704130812Smarcel      new_so->som_solib.data_start = extract_unsigned_integer (buf, 4);
705130812Smarcel
706130812Smarcel      status = target_read_memory (addr + 24, buf, 4);
707130812Smarcel      if (status != 0)
708130812Smarcel	goto err;
709130812Smarcel
710130812Smarcel      new_so->som_solib.bss_start = extract_unsigned_integer (buf, 4);
711130812Smarcel
712130812Smarcel      status = target_read_memory (addr + 28, buf, 4);
713130812Smarcel      if (status != 0)
714130812Smarcel	goto err;
715130812Smarcel
716130812Smarcel      new_so->som_solib.data_end = extract_unsigned_integer (buf, 4);
717130812Smarcel
718130812Smarcel      status = target_read_memory (addr + 32, buf, 4);
719130812Smarcel      if (status != 0)
720130812Smarcel	goto err;
721130812Smarcel
722130812Smarcel      new_so->som_solib.got_value = extract_unsigned_integer (buf, 4);
723130812Smarcel
724130812Smarcel      status = target_read_memory (addr + 36, buf, 4);
725130812Smarcel      if (status != 0)
726130812Smarcel	goto err;
727130812Smarcel
728130812Smarcel      /* FIXME: cagney/2003-02-01: I think som_solib.next should be a
729130812Smarcel         CORE_ADDR.  */
730130812Smarcel      new_so->som_solib.next =
731130812Smarcel	hpux_address_to_host_pointer_hack (extract_unsigned_integer (buf, 4));
732130812Smarcel
733130812Smarcel      /* Note that we don't re-set "addr" to the next pointer
734130812Smarcel       * until after we've read the trailing data.
735130812Smarcel       */
736130812Smarcel
737130812Smarcel      status = target_read_memory (addr + 40, buf, 4);
738130812Smarcel      new_so->som_solib.tsd_start_addr = extract_unsigned_integer (buf, 4);
739130812Smarcel      if (status != 0)
740130812Smarcel	goto err;
741130812Smarcel
742130812Smarcel      /* Now indirect via that value!
743130812Smarcel       */
744130812Smarcel      status = target_read_memory (new_so->som_solib.tsd_start_addr, buf, 4);
745130812Smarcel      new_so->som_solib.tsd_start_addr = extract_unsigned_integer (buf, 4);
746130812Smarcel      if (status != 0)
747130812Smarcel	goto err;
748130812Smarcel#ifdef SOLIB_DEBUG
749130812Smarcel      printf ("\n+ library \"%s\" is described at 0x%x\n", name, addr);
750130812Smarcel      printf ("  'version' is %d\n", new_so->som_solib.struct_version);
751130812Smarcel      printf ("  'bind_mode' is %d\n", new_so->som_solib.bind_mode);
752130812Smarcel      printf ("  'library_version' is %d\n", new_so->som_solib.library_version);
753130812Smarcel      printf ("  'text_addr' is 0x%x\n", new_so->som_solib.text_addr);
754130812Smarcel      printf ("  'text_link_addr' is 0x%x\n", new_so->som_solib.text_link_addr);
755130812Smarcel      printf ("  'text_end' is 0x%x\n", new_so->som_solib.text_end);
756130812Smarcel      printf ("  'data_start' is 0x%x\n", new_so->som_solib.data_start);
757130812Smarcel      printf ("  'bss_start' is 0x%x\n", new_so->som_solib.bss_start);
758130812Smarcel      printf ("  'data_end' is 0x%x\n", new_so->som_solib.data_end);
759130812Smarcel      printf ("  'got_value' is %x\n", new_so->som_solib.got_value);
760130812Smarcel      printf ("  'next' is 0x%x\n", new_so->som_solib.next);
761130812Smarcel      printf ("  'tsd_start_addr' is 0x%x\n", new_so->som_solib.tsd_start_addr);
762130812Smarcel#endif
763130812Smarcel
764130812Smarcel      /* Go on to the next shared library descriptor.
765130812Smarcel       */
766130812Smarcel      addr = (CORE_ADDR) new_so->som_solib.next;
767130812Smarcel
768130812Smarcel
769130812Smarcel
770130812Smarcel      /* At this point, we have essentially hooked the shlib into the
771130812Smarcel         "info share" command.  However, we haven't yet loaded its
772130812Smarcel         symbol table.  We must now decide whether we ought to, i.e.,
773130812Smarcel         whether doing so would exceed the symbol table size threshold.
774130812Smarcel
775130812Smarcel         If the threshold has just now been exceeded, then we'll issue
776130812Smarcel         a warning message (which explains how to load symbols manually,
777130812Smarcel         if the user so desires).
778130812Smarcel
779130812Smarcel         If the threshold has just now or previously been exceeded,
780130812Smarcel         we'll just add the shlib to the list of object files, but won't
781130812Smarcel         actually load its symbols.  (This is more useful than it might
782130812Smarcel         sound, for it allows us to e.g., still load and use the shlibs'
783130812Smarcel         unwind information for stack tracebacks.)
784130812Smarcel       */
785130812Smarcel
786130812Smarcel      /* Note that we DON'T want to preclude the user from using the
787130812Smarcel         add-symbol-file command!  Thus, we only worry about the threshold
788130812Smarcel         when we're invoked for other reasons.
789130812Smarcel       */
790130812Smarcel      st_size = som_solib_sizeof_symbol_table (name);
791130812Smarcel      som_solib_st_size_threshold_exceeded =
792130812Smarcel	!from_tty &&
793130812Smarcel	auto_solib_limit > 0 &&
794130812Smarcel	readsyms &&
795130812Smarcel	((st_size + som_solib_total_st_size) > (auto_solib_limit * (LONGEST) (1024 * 1024)));
796130812Smarcel
797130812Smarcel      if (som_solib_st_size_threshold_exceeded)
798130812Smarcel	{
799130812Smarcel	  if (!threshold_warning_given)
800130812Smarcel	    warning ("Symbols for some libraries have not been loaded, because\ndoing so would exceed the size threshold specified by auto-solib-limit.\nTo manually load symbols, use the 'sharedlibrary' command.\nTo raise the threshold, set auto-solib-limit to a larger value and rerun\nthe program.\n");
801130812Smarcel	  threshold_warning_given = 1;
802130812Smarcel
803130812Smarcel	  /* We'll still make note of this shlib, even if we don't
804130812Smarcel	     read its symbols.  This allows us to use its unwind
805130812Smarcel	     information well enough to know how to e.g., correctly
806130812Smarcel	     do a traceback from a PC within the shlib, even if we
807130812Smarcel	     can't symbolize those PCs...
808130812Smarcel	   */
809130812Smarcel	  som_solib_add_solib_objfile (new_so, name, from_tty, text_addr);
810130812Smarcel	  continue;
811130812Smarcel	}
812130812Smarcel
813130812Smarcel      som_solib_total_st_size += st_size;
814130812Smarcel
815130812Smarcel      /* This fills in new_so->objfile, among others. */
816130812Smarcel      som_solib_load_symbols (new_so, name, from_tty, text_addr, target);
817130812Smarcel    }
818130812Smarcel
819130812Smarcel#ifdef SOLIB_DEBUG
820130812Smarcel  printf ("--Done reading shared library data\n");
821130812Smarcel#endif
822130812Smarcel
823130812Smarcel  /* Getting new symbols may change our opinion about what is
824130812Smarcel     frameless.  */
825130812Smarcel  reinit_frame_cache ();
826130812Smarcel  return;
827130812Smarcel
828130812Smarcelold_dld:
829130812Smarcel  error ("Debugging dynamic executables loaded via the hpux8 dld.sl is not supported.\n");
830130812Smarcel  return;
831130812Smarcel
832130812Smarcelerr:
833130812Smarcel  error ("Error while reading dynamic library list.\n");
834130812Smarcel  return;
835130812Smarcel}
836130812Smarcel
837130812Smarcel
838130812Smarcel/* This hook gets called just before the first instruction in the
839130812Smarcel   inferior process is executed.
840130812Smarcel
841130812Smarcel   This is our opportunity to set magic flags in the inferior so
842130812Smarcel   that GDB can be notified when a shared library is mapped in and
843130812Smarcel   to tell the dynamic linker that a private copy of the library is
844130812Smarcel   needed (so GDB can set breakpoints in the library).
845130812Smarcel
846130812Smarcel   __dld_flags is the location of the magic flags; as of this implementation
847130812Smarcel   there are 3 flags of interest:
848130812Smarcel
849130812Smarcel   bit 0 when set indicates that private copies of the libraries are needed
850130812Smarcel   bit 1 when set indicates that the callback hook routine is valid
851130812Smarcel   bit 2 when set indicates that the dynamic linker should maintain the
852130812Smarcel   __dld_list structure when loading/unloading libraries.
853130812Smarcel
854130812Smarcel   Note that shared libraries are not mapped in at this time, so we have
855130812Smarcel   run the inferior until the libraries are mapped in.  Typically this
856130812Smarcel   means running until the "_start" is called.  */
857130812Smarcel
858130812Smarcelvoid
859130812Smarcelsom_solib_create_inferior_hook (void)
860130812Smarcel{
861130812Smarcel  struct minimal_symbol *msymbol;
862130812Smarcel  unsigned int dld_flags, status, have_endo;
863130812Smarcel  asection *shlib_info;
864130812Smarcel  char buf[4];
865130812Smarcel  struct objfile *objfile;
866130812Smarcel  CORE_ADDR anaddr;
867130812Smarcel
868130812Smarcel  /* First, remove all the solib event breakpoints.  Their addresses
869130812Smarcel     may have changed since the last time we ran the program.  */
870130812Smarcel  remove_solib_event_breakpoints ();
871130812Smarcel
872130812Smarcel  if (symfile_objfile == NULL)
873130812Smarcel    return;
874130812Smarcel
875130812Smarcel  /* First see if the objfile was dynamically linked.  */
876130812Smarcel  shlib_info = bfd_get_section_by_name (symfile_objfile->obfd, "$SHLIB_INFO$");
877130812Smarcel  if (!shlib_info)
878130812Smarcel    return;
879130812Smarcel
880130812Smarcel  /* It's got a $SHLIB_INFO$ section, make sure it's not empty.  */
881130812Smarcel  if (bfd_section_size (symfile_objfile->obfd, shlib_info) == 0)
882130812Smarcel    return;
883130812Smarcel
884130812Smarcel  have_endo = 0;
885130812Smarcel  /* Slam the pid of the process into __d_pid.
886130812Smarcel
887130812Smarcel     We used to warn when this failed, but that warning is only useful
888130812Smarcel     on very old HP systems (hpux9 and older).  The warnings are an
889130812Smarcel     annoyance to users of modern systems and foul up the testsuite as
890130812Smarcel     well.  As a result, the warnings have been disabled.  */
891130812Smarcel  msymbol = lookup_minimal_symbol ("__d_pid", NULL, symfile_objfile);
892130812Smarcel  if (msymbol == NULL)
893130812Smarcel    goto keep_going;
894130812Smarcel
895130812Smarcel  anaddr = SYMBOL_VALUE_ADDRESS (msymbol);
896130812Smarcel  store_unsigned_integer (buf, 4, PIDGET (inferior_ptid));
897130812Smarcel  status = target_write_memory (anaddr, buf, 4);
898130812Smarcel  if (status != 0)
899130812Smarcel    {
900130812Smarcel      warning ("Unable to write __d_pid");
901130812Smarcel      warning ("Suggest linking with /opt/langtools/lib/end.o.");
902130812Smarcel      warning ("GDB will be unable to track shl_load/shl_unload calls");
903130812Smarcel      goto keep_going;
904130812Smarcel    }
905130812Smarcel
906130812Smarcel  /* Get the value of _DLD_HOOK (an export stub) and put it in __dld_hook;
907130812Smarcel     This will force the dynamic linker to call __d_trap when significant
908130812Smarcel     events occur.
909130812Smarcel
910130812Smarcel     Note that the above is the pre-HP-UX 9.0 behaviour.  At 9.0 and above,
911130812Smarcel     the dld provides an export stub named "__d_trap" as well as the
912130812Smarcel     function named "__d_trap" itself, but doesn't provide "_DLD_HOOK".
913130812Smarcel     We'll look first for the old flavor and then the new.
914130812Smarcel   */
915130812Smarcel  msymbol = lookup_minimal_symbol ("_DLD_HOOK", NULL, symfile_objfile);
916130812Smarcel  if (msymbol == NULL)
917130812Smarcel    msymbol = lookup_minimal_symbol ("__d_trap", NULL, symfile_objfile);
918130812Smarcel  if (msymbol == NULL)
919130812Smarcel    {
920130812Smarcel      warning ("Unable to find _DLD_HOOK symbol in object file.");
921130812Smarcel      warning ("Suggest linking with /opt/langtools/lib/end.o.");
922130812Smarcel      warning ("GDB will be unable to track shl_load/shl_unload calls");
923130812Smarcel      goto keep_going;
924130812Smarcel    }
925130812Smarcel  anaddr = SYMBOL_VALUE_ADDRESS (msymbol);
926130812Smarcel  dld_cache.hook.address = anaddr;
927130812Smarcel
928130812Smarcel  /* Grrr, this might not be an export symbol!  We have to find the
929130812Smarcel     export stub.  */
930130812Smarcel  ALL_OBJFILES (objfile)
931130812Smarcel  {
932130812Smarcel    struct unwind_table_entry *u;
933130812Smarcel    struct minimal_symbol *msymbol2;
934130812Smarcel
935130812Smarcel    /* What a crock.  */
936130812Smarcel    msymbol2 = lookup_minimal_symbol_solib_trampoline (DEPRECATED_SYMBOL_NAME (msymbol),
937130812Smarcel						       objfile);
938130812Smarcel    /* Found a symbol with the right name.  */
939130812Smarcel    if (msymbol2)
940130812Smarcel      {
941130812Smarcel	struct unwind_table_entry *u;
942130812Smarcel	/* It must be a shared library trampoline.  */
943130812Smarcel	if (SYMBOL_TYPE (msymbol2) != mst_solib_trampoline)
944130812Smarcel	  continue;
945130812Smarcel
946130812Smarcel	/* It must also be an export stub.  */
947130812Smarcel	u = find_unwind_entry (SYMBOL_VALUE (msymbol2));
948130812Smarcel	if (!u || u->stub_unwind.stub_type != EXPORT)
949130812Smarcel	  continue;
950130812Smarcel
951130812Smarcel	/* OK.  Looks like the correct import stub.  */
952130812Smarcel	anaddr = SYMBOL_VALUE (msymbol2);
953130812Smarcel	dld_cache.hook_stub.address = anaddr;
954130812Smarcel      }
955130812Smarcel  }
956130812Smarcel  store_unsigned_integer (buf, 4, anaddr);
957130812Smarcel
958130812Smarcel  msymbol = lookup_minimal_symbol ("__dld_hook", NULL, symfile_objfile);
959130812Smarcel  if (msymbol == NULL)
960130812Smarcel    {
961130812Smarcel      warning ("Unable to find __dld_hook symbol in object file.");
962130812Smarcel      warning ("Suggest linking with /opt/langtools/lib/end.o.");
963130812Smarcel      warning ("GDB will be unable to track shl_load/shl_unload calls");
964130812Smarcel      goto keep_going;
965130812Smarcel    }
966130812Smarcel  anaddr = SYMBOL_VALUE_ADDRESS (msymbol);
967130812Smarcel  status = target_write_memory (anaddr, buf, 4);
968130812Smarcel
969130812Smarcel  /* Now set a shlib_event breakpoint at __d_trap so we can track
970130812Smarcel     significant shared library events.  */
971130812Smarcel  msymbol = lookup_minimal_symbol ("__d_trap", NULL, symfile_objfile);
972130812Smarcel  if (msymbol == NULL)
973130812Smarcel    {
974130812Smarcel      warning ("Unable to find __dld_d_trap symbol in object file.");
975130812Smarcel      warning ("Suggest linking with /opt/langtools/lib/end.o.");
976130812Smarcel      warning ("GDB will be unable to track shl_load/shl_unload calls");
977130812Smarcel      goto keep_going;
978130812Smarcel    }
979130812Smarcel  create_solib_event_breakpoint (SYMBOL_VALUE_ADDRESS (msymbol));
980130812Smarcel
981130812Smarcel  /* We have all the support usually found in end.o, so we can track
982130812Smarcel     shl_load and shl_unload calls.  */
983130812Smarcel  have_endo = 1;
984130812Smarcel
985130812Smarcelkeep_going:
986130812Smarcel
987130812Smarcel  /* Get the address of __dld_flags, if no such symbol exists, then we can
988130812Smarcel     not debug the shared code.  */
989130812Smarcel  msymbol = lookup_minimal_symbol ("__dld_flags", NULL, NULL);
990130812Smarcel  if (msymbol == NULL)
991130812Smarcel    {
992130812Smarcel      error ("Unable to find __dld_flags symbol in object file.\n");
993130812Smarcel    }
994130812Smarcel
995130812Smarcel  anaddr = SYMBOL_VALUE_ADDRESS (msymbol);
996130812Smarcel
997130812Smarcel  /* Read the current contents.  */
998130812Smarcel  status = target_read_memory (anaddr, buf, 4);
999130812Smarcel  if (status != 0)
1000130812Smarcel    {
1001130812Smarcel      error ("Unable to read __dld_flags\n");
1002130812Smarcel    }
1003130812Smarcel  dld_flags = extract_unsigned_integer (buf, 4);
1004130812Smarcel
1005130812Smarcel  /* Turn on the flags we care about.  */
1006130812Smarcel  dld_flags |= DLD_FLAGS_MAPPRIVATE;
1007130812Smarcel  if (have_endo)
1008130812Smarcel    dld_flags |= DLD_FLAGS_HOOKVALID;
1009130812Smarcel  store_unsigned_integer (buf, 4, dld_flags);
1010130812Smarcel  status = target_write_memory (anaddr, buf, 4);
1011130812Smarcel  if (status != 0)
1012130812Smarcel    {
1013130812Smarcel      error ("Unable to write __dld_flags\n");
1014130812Smarcel    }
1015130812Smarcel
1016130812Smarcel  /* Now find the address of _start and set a breakpoint there.
1017130812Smarcel     We still need this code for two reasons:
1018130812Smarcel
1019130812Smarcel     * Not all sites have /opt/langtools/lib/end.o, so it's not always
1020130812Smarcel     possible to track the dynamic linker's events.
1021130812Smarcel
1022130812Smarcel     * At this time no events are triggered for shared libraries
1023130812Smarcel     loaded at startup time (what a crock).  */
1024130812Smarcel
1025130812Smarcel  msymbol = lookup_minimal_symbol ("_start", NULL, symfile_objfile);
1026130812Smarcel  if (msymbol == NULL)
1027130812Smarcel    {
1028130812Smarcel      error ("Unable to find _start symbol in object file.\n");
1029130812Smarcel    }
1030130812Smarcel
1031130812Smarcel  anaddr = SYMBOL_VALUE_ADDRESS (msymbol);
1032130812Smarcel
1033130812Smarcel  /* Make the breakpoint at "_start" a shared library event breakpoint.  */
1034130812Smarcel  create_solib_event_breakpoint (anaddr);
1035130812Smarcel
1036130812Smarcel  /* Wipe out all knowledge of old shared libraries since their
1037130812Smarcel     mapping can change from one exec to another!  */
1038130812Smarcel  while (so_list_head)
1039130812Smarcel    {
1040130812Smarcel      struct so_list *temp;
1041130812Smarcel
1042130812Smarcel      temp = so_list_head;
1043130812Smarcel      xfree (so_list_head);
1044130812Smarcel      so_list_head = temp->next;
1045130812Smarcel    }
1046130812Smarcel  clear_symtab_users ();
1047130812Smarcel}
1048130812Smarcel
1049130812Smarcel/* This operation removes the "hook" between GDB and the dynamic linker,
1050130812Smarcel   which causes the dld to notify GDB of shared library events.
1051130812Smarcel
1052130812Smarcel   After this operation completes, the dld will no longer notify GDB of
1053130812Smarcel   shared library events.  To resume notifications, GDB must call
1054130812Smarcel   som_solib_create_inferior_hook.
1055130812Smarcel
1056130812Smarcel   This operation does not remove any knowledge of shared libraries which
1057130812Smarcel   GDB may already have been notified of.
1058130812Smarcel */
1059130812Smarcelvoid
1060130812Smarcelsom_solib_remove_inferior_hook (int pid)
1061130812Smarcel{
1062130812Smarcel  CORE_ADDR addr;
1063130812Smarcel  struct minimal_symbol *msymbol;
1064130812Smarcel  int status;
1065130812Smarcel  char dld_flags_buffer[4];
1066130812Smarcel  unsigned int dld_flags_value;
1067130812Smarcel  struct cleanup *old_cleanups = save_inferior_ptid ();
1068130812Smarcel
1069130812Smarcel  /* Ensure that we're really operating on the specified process. */
1070130812Smarcel  inferior_ptid = pid_to_ptid (pid);
1071130812Smarcel
1072130812Smarcel  /* We won't bother to remove the solib breakpoints from this process.
1073130812Smarcel
1074130812Smarcel     In fact, on PA64 the breakpoint is hard-coded into the dld callback,
1075130812Smarcel     and thus we're not supposed to remove it.
1076130812Smarcel
1077130812Smarcel     Rather, we'll merely clear the dld_flags bit that enables callbacks.
1078130812Smarcel   */
1079130812Smarcel  msymbol = lookup_minimal_symbol ("__dld_flags", NULL, NULL);
1080130812Smarcel
1081130812Smarcel  addr = SYMBOL_VALUE_ADDRESS (msymbol);
1082130812Smarcel  status = target_read_memory (addr, dld_flags_buffer, 4);
1083130812Smarcel
1084130812Smarcel  dld_flags_value = extract_unsigned_integer (dld_flags_buffer, 4);
1085130812Smarcel
1086130812Smarcel  dld_flags_value &= ~DLD_FLAGS_HOOKVALID;
1087130812Smarcel  store_unsigned_integer (dld_flags_buffer, 4, dld_flags_value);
1088130812Smarcel  status = target_write_memory (addr, dld_flags_buffer, 4);
1089130812Smarcel
1090130812Smarcel  do_cleanups (old_cleanups);
1091130812Smarcel}
1092130812Smarcel
1093130812Smarcel
1094130812Smarcel/* This function creates a breakpoint on the dynamic linker hook, which
1095130812Smarcel   is called when e.g., a shl_load or shl_unload call is made.  This
1096130812Smarcel   breakpoint will only trigger when a shl_load call is made.
1097130812Smarcel
1098130812Smarcel   If filename is NULL, then loads of any dll will be caught.  Else,
1099130812Smarcel   only loads of the file whose pathname is the string contained by
1100130812Smarcel   filename will be caught.
1101130812Smarcel
1102130812Smarcel   Undefined behaviour is guaranteed if this function is called before
1103130812Smarcel   som_solib_create_inferior_hook.
1104130812Smarcel */
1105130812Smarcelvoid
1106130812Smarcelsom_solib_create_catch_load_hook (int pid, int tempflag, char *filename,
1107130812Smarcel				  char *cond_string)
1108130812Smarcel{
1109130812Smarcel  create_solib_load_event_breakpoint ("__d_trap", tempflag, filename, cond_string);
1110130812Smarcel}
1111130812Smarcel
1112130812Smarcel/* This function creates a breakpoint on the dynamic linker hook, which
1113130812Smarcel   is called when e.g., a shl_load or shl_unload call is made.  This
1114130812Smarcel   breakpoint will only trigger when a shl_unload call is made.
1115130812Smarcel
1116130812Smarcel   If filename is NULL, then unloads of any dll will be caught.  Else,
1117130812Smarcel   only unloads of the file whose pathname is the string contained by
1118130812Smarcel   filename will be caught.
1119130812Smarcel
1120130812Smarcel   Undefined behaviour is guaranteed if this function is called before
1121130812Smarcel   som_solib_create_inferior_hook.
1122130812Smarcel */
1123130812Smarcelvoid
1124130812Smarcelsom_solib_create_catch_unload_hook (int pid, int tempflag, char *filename,
1125130812Smarcel				    char *cond_string)
1126130812Smarcel{
1127130812Smarcel  create_solib_unload_event_breakpoint ("__d_trap", tempflag, filename, cond_string);
1128130812Smarcel}
1129130812Smarcel
1130130812Smarcelint
1131130812Smarcelsom_solib_have_load_event (int pid)
1132130812Smarcel{
1133130812Smarcel  CORE_ADDR event_kind;
1134130812Smarcel
1135130812Smarcel  event_kind = read_register (ARG0_REGNUM);
1136130812Smarcel  return (event_kind == SHL_LOAD);
1137130812Smarcel}
1138130812Smarcel
1139130812Smarcelint
1140130812Smarcelsom_solib_have_unload_event (int pid)
1141130812Smarcel{
1142130812Smarcel  CORE_ADDR event_kind;
1143130812Smarcel
1144130812Smarcel  event_kind = read_register (ARG0_REGNUM);
1145130812Smarcel  return (event_kind == SHL_UNLOAD);
1146130812Smarcel}
1147130812Smarcel
1148130812Smarcelstatic char *
1149130812Smarcelsom_solib_library_pathname (int pid)
1150130812Smarcel{
1151130812Smarcel  CORE_ADDR dll_handle_address;
1152130812Smarcel  CORE_ADDR dll_pathname_address;
1153130812Smarcel  struct som_solib_mapped_entry dll_descriptor;
1154130812Smarcel  char *p;
1155130812Smarcel  static char dll_pathname[1024];
1156130812Smarcel
1157130812Smarcel  /* Read the descriptor of this newly-loaded library. */
1158130812Smarcel  dll_handle_address = read_register (ARG1_REGNUM);
1159130812Smarcel  read_memory (dll_handle_address, (char *) &dll_descriptor, sizeof (dll_descriptor));
1160130812Smarcel
1161130812Smarcel  /* We can find a pointer to the dll's pathname within the descriptor. */
1162130812Smarcel  dll_pathname_address = (CORE_ADDR) dll_descriptor.name;
1163130812Smarcel
1164130812Smarcel  /* Read the pathname, one byte at a time. */
1165130812Smarcel  p = dll_pathname;
1166130812Smarcel  for (;;)
1167130812Smarcel    {
1168130812Smarcel      char b;
1169130812Smarcel      read_memory (dll_pathname_address++, (char *) &b, 1);
1170130812Smarcel      *p++ = b;
1171130812Smarcel      if (b == '\0')
1172130812Smarcel	break;
1173130812Smarcel    }
1174130812Smarcel
1175130812Smarcel  return dll_pathname;
1176130812Smarcel}
1177130812Smarcel
1178130812Smarcelchar *
1179130812Smarcelsom_solib_loaded_library_pathname (int pid)
1180130812Smarcel{
1181130812Smarcel  if (!som_solib_have_load_event (pid))
1182130812Smarcel    error ("Must have a load event to use this query");
1183130812Smarcel
1184130812Smarcel  return som_solib_library_pathname (pid);
1185130812Smarcel}
1186130812Smarcel
1187130812Smarcelchar *
1188130812Smarcelsom_solib_unloaded_library_pathname (int pid)
1189130812Smarcel{
1190130812Smarcel  if (!som_solib_have_unload_event (pid))
1191130812Smarcel    error ("Must have an unload event to use this query");
1192130812Smarcel
1193130812Smarcel  return som_solib_library_pathname (pid);
1194130812Smarcel}
1195130812Smarcel
1196130812Smarcelstatic void
1197130812Smarcelsom_solib_desire_dynamic_linker_symbols (void)
1198130812Smarcel{
1199130812Smarcel  struct objfile *objfile;
1200130812Smarcel  struct unwind_table_entry *u;
1201130812Smarcel  struct minimal_symbol *dld_msymbol;
1202130812Smarcel
1203130812Smarcel  /* Do we already know the value of these symbols?  If so, then
1204130812Smarcel     we've no work to do.
1205130812Smarcel
1206130812Smarcel     (If you add clauses to this test, be sure to likewise update the
1207130812Smarcel     test within the loop.)
1208130812Smarcel   */
1209130812Smarcel  if (dld_cache.is_valid)
1210130812Smarcel    return;
1211130812Smarcel
1212130812Smarcel  ALL_OBJFILES (objfile)
1213130812Smarcel  {
1214130812Smarcel    dld_msymbol = lookup_minimal_symbol ("shl_load", NULL, objfile);
1215130812Smarcel    if (dld_msymbol != NULL)
1216130812Smarcel      {
1217130812Smarcel	dld_cache.load.address = SYMBOL_VALUE (dld_msymbol);
1218130812Smarcel	dld_cache.load.unwind = find_unwind_entry (dld_cache.load.address);
1219130812Smarcel      }
1220130812Smarcel
1221130812Smarcel    dld_msymbol = lookup_minimal_symbol_solib_trampoline ("shl_load",
1222130812Smarcel							  objfile);
1223130812Smarcel    if (dld_msymbol != NULL)
1224130812Smarcel      {
1225130812Smarcel	if (SYMBOL_TYPE (dld_msymbol) == mst_solib_trampoline)
1226130812Smarcel	  {
1227130812Smarcel	    u = find_unwind_entry (SYMBOL_VALUE (dld_msymbol));
1228130812Smarcel	    if ((u != NULL) && (u->stub_unwind.stub_type == EXPORT))
1229130812Smarcel	      {
1230130812Smarcel		dld_cache.load_stub.address = SYMBOL_VALUE (dld_msymbol);
1231130812Smarcel		dld_cache.load_stub.unwind = u;
1232130812Smarcel	      }
1233130812Smarcel	  }
1234130812Smarcel      }
1235130812Smarcel
1236130812Smarcel    dld_msymbol = lookup_minimal_symbol ("shl_unload", NULL, objfile);
1237130812Smarcel    if (dld_msymbol != NULL)
1238130812Smarcel      {
1239130812Smarcel	dld_cache.unload.address = SYMBOL_VALUE (dld_msymbol);
1240130812Smarcel	dld_cache.unload.unwind = find_unwind_entry (dld_cache.unload.address);
1241130812Smarcel
1242130812Smarcel	/* ??rehrauer: I'm not sure exactly what this is, but it appears
1243130812Smarcel	   that on some HPUX 10.x versions, there's two unwind regions to
1244130812Smarcel	   cover the body of "shl_unload", the second being 4 bytes past
1245130812Smarcel	   the end of the first.  This is a large hack to handle that
1246130812Smarcel	   case, but since I don't seem to have any legitimate way to
1247130812Smarcel	   look for this thing via the symbol table...
1248130812Smarcel	 */
1249130812Smarcel	if (dld_cache.unload.unwind != NULL)
1250130812Smarcel	  {
1251130812Smarcel	    u = find_unwind_entry (dld_cache.unload.unwind->region_end + 4);
1252130812Smarcel	    if (u != NULL)
1253130812Smarcel	      {
1254130812Smarcel		dld_cache.unload2.address = u->region_start;
1255130812Smarcel		dld_cache.unload2.unwind = u;
1256130812Smarcel	      }
1257130812Smarcel	  }
1258130812Smarcel      }
1259130812Smarcel
1260130812Smarcel    dld_msymbol = lookup_minimal_symbol_solib_trampoline ("shl_unload",
1261130812Smarcel							  objfile);
1262130812Smarcel    if (dld_msymbol != NULL)
1263130812Smarcel      {
1264130812Smarcel	if (SYMBOL_TYPE (dld_msymbol) == mst_solib_trampoline)
1265130812Smarcel	  {
1266130812Smarcel	    u = find_unwind_entry (SYMBOL_VALUE (dld_msymbol));
1267130812Smarcel	    if ((u != NULL) && (u->stub_unwind.stub_type == EXPORT))
1268130812Smarcel	      {
1269130812Smarcel		dld_cache.unload_stub.address = SYMBOL_VALUE (dld_msymbol);
1270130812Smarcel		dld_cache.unload_stub.unwind = u;
1271130812Smarcel	      }
1272130812Smarcel	  }
1273130812Smarcel      }
1274130812Smarcel
1275130812Smarcel    /* Did we find everything we were looking for?  If so, stop. */
1276130812Smarcel    if ((dld_cache.load.address != 0)
1277130812Smarcel	&& (dld_cache.load_stub.address != 0)
1278130812Smarcel	&& (dld_cache.unload.address != 0)
1279130812Smarcel	&& (dld_cache.unload_stub.address != 0))
1280130812Smarcel      {
1281130812Smarcel	dld_cache.is_valid = 1;
1282130812Smarcel	break;
1283130812Smarcel      }
1284130812Smarcel  }
1285130812Smarcel
1286130812Smarcel  dld_cache.hook.unwind = find_unwind_entry (dld_cache.hook.address);
1287130812Smarcel  dld_cache.hook_stub.unwind = find_unwind_entry (dld_cache.hook_stub.address);
1288130812Smarcel
1289130812Smarcel  /* We're prepared not to find some of these symbols, which is why
1290130812Smarcel     this function is a "desire" operation, and not a "require".
1291130812Smarcel   */
1292130812Smarcel}
1293130812Smarcel
1294130812Smarcelint
1295130812Smarcelsom_solib_in_dynamic_linker (int pid, CORE_ADDR pc)
1296130812Smarcel{
1297130812Smarcel  struct unwind_table_entry *u_pc;
1298130812Smarcel
1299130812Smarcel  /* Are we in the dld itself?
1300130812Smarcel
1301130812Smarcel     ??rehrauer: Large hack -- We'll assume that any address in a
1302130812Smarcel     shared text region is the dld's text.  This would obviously
1303130812Smarcel     fall down if the user attached to a process, whose shlibs
1304130812Smarcel     weren't mapped to a (writeable) private region.  However, in
1305130812Smarcel     that case the debugger probably isn't able to set the fundamental
1306130812Smarcel     breakpoint in the dld callback anyways, so this hack should be
1307130812Smarcel     safe.
1308130812Smarcel   */
1309130812Smarcel  if ((pc & (CORE_ADDR) 0xc0000000) == (CORE_ADDR) 0xc0000000)
1310130812Smarcel    return 1;
1311130812Smarcel
1312130812Smarcel  /* Cache the address of some symbols that are part of the dynamic
1313130812Smarcel     linker, if not already known.
1314130812Smarcel   */
1315130812Smarcel  som_solib_desire_dynamic_linker_symbols ();
1316130812Smarcel
1317130812Smarcel  /* Are we in the dld callback?  Or its export stub? */
1318130812Smarcel  u_pc = find_unwind_entry (pc);
1319130812Smarcel  if (u_pc == NULL)
1320130812Smarcel    return 0;
1321130812Smarcel
1322130812Smarcel  if ((u_pc == dld_cache.hook.unwind) || (u_pc == dld_cache.hook_stub.unwind))
1323130812Smarcel    return 1;
1324130812Smarcel
1325130812Smarcel  /* Or the interface of the dld (i.e., "shl_load" or friends)? */
1326130812Smarcel  if ((u_pc == dld_cache.load.unwind)
1327130812Smarcel      || (u_pc == dld_cache.unload.unwind)
1328130812Smarcel      || (u_pc == dld_cache.unload2.unwind)
1329130812Smarcel      || (u_pc == dld_cache.load_stub.unwind)
1330130812Smarcel      || (u_pc == dld_cache.unload_stub.unwind))
1331130812Smarcel    return 1;
1332130812Smarcel
1333130812Smarcel  /* Apparently this address isn't part of the dld's text. */
1334130812Smarcel  return 0;
1335130812Smarcel}
1336130812Smarcel
1337130812Smarcel
1338130812Smarcel/* Return the GOT value for the shared library in which ADDR belongs.  If
1339130812Smarcel   ADDR isn't in any known shared library, return zero.  */
1340130812Smarcel
1341130812SmarcelCORE_ADDR
1342130812Smarcelsom_solib_get_got_by_pc (CORE_ADDR addr)
1343130812Smarcel{
1344130812Smarcel  struct so_list *so_list = so_list_head;
1345130812Smarcel  CORE_ADDR got_value = 0;
1346130812Smarcel
1347130812Smarcel  while (so_list)
1348130812Smarcel    {
1349130812Smarcel      if (so_list->som_solib.text_addr <= addr
1350130812Smarcel	  && so_list->som_solib.text_end > addr)
1351130812Smarcel	{
1352130812Smarcel	  got_value = so_list->som_solib.got_value;
1353130812Smarcel	  break;
1354130812Smarcel	}
1355130812Smarcel      so_list = so_list->next;
1356130812Smarcel    }
1357130812Smarcel  return got_value;
1358130812Smarcel}
1359130812Smarcel
1360130812Smarcel/*  elz:
1361130812Smarcel   Return the address of the handle of the shared library
1362130812Smarcel   in which ADDR belongs.  If
1363130812Smarcel   ADDR isn't in any known shared library, return zero.  */
1364130812Smarcel/* this function is used in hppa_fix_call_dummy in hppa-tdep.c */
1365130812Smarcel
1366130812SmarcelCORE_ADDR
1367130812Smarcelsom_solib_get_solib_by_pc (CORE_ADDR addr)
1368130812Smarcel{
1369130812Smarcel  struct so_list *so_list = so_list_head;
1370130812Smarcel
1371130812Smarcel  while (so_list)
1372130812Smarcel    {
1373130812Smarcel      if (so_list->som_solib.text_addr <= addr
1374130812Smarcel	  && so_list->som_solib.text_end > addr)
1375130812Smarcel	{
1376130812Smarcel	  break;
1377130812Smarcel	}
1378130812Smarcel      so_list = so_list->next;
1379130812Smarcel    }
1380130812Smarcel  if (so_list)
1381130812Smarcel    return so_list->solib_addr;
1382130812Smarcel  else
1383130812Smarcel    return 0;
1384130812Smarcel}
1385130812Smarcel
1386130812Smarcel
1387130812Smarcelint
1388130812Smarcelsom_solib_section_offsets (struct objfile *objfile,
1389130812Smarcel			   struct section_offsets *offsets)
1390130812Smarcel{
1391130812Smarcel  struct so_list *so_list = so_list_head;
1392130812Smarcel
1393130812Smarcel  while (so_list)
1394130812Smarcel    {
1395130812Smarcel      /* Oh what a pain!  We need the offsets before so_list->objfile
1396130812Smarcel         is valid.  The BFDs will never match.  Make a best guess.  */
1397130812Smarcel      if (strstr (objfile->name, so_list->som_solib.name))
1398130812Smarcel	{
1399130812Smarcel	  asection *private_section;
1400130812Smarcel
1401130812Smarcel	  /* The text offset is easy.  */
1402130812Smarcel	  offsets->offsets[SECT_OFF_TEXT (objfile)]
1403130812Smarcel	    = (so_list->som_solib.text_addr
1404130812Smarcel	       - so_list->som_solib.text_link_addr);
1405130812Smarcel	  offsets->offsets[SECT_OFF_RODATA (objfile)]
1406130812Smarcel	    = ANOFFSET (offsets, SECT_OFF_TEXT (objfile));
1407130812Smarcel
1408130812Smarcel	  /* We should look at presumed_dp in the SOM header, but
1409130812Smarcel	     that's not easily available.  This should be OK though.  */
1410130812Smarcel	  private_section = bfd_get_section_by_name (objfile->obfd,
1411130812Smarcel						     "$PRIVATE$");
1412130812Smarcel	  if (!private_section)
1413130812Smarcel	    {
1414130812Smarcel	      warning ("Unable to find $PRIVATE$ in shared library!");
1415130812Smarcel	      offsets->offsets[SECT_OFF_DATA (objfile)] = 0;
1416130812Smarcel	      offsets->offsets[SECT_OFF_BSS (objfile)] = 0;
1417130812Smarcel	      return 1;
1418130812Smarcel	    }
1419130812Smarcel	  offsets->offsets[SECT_OFF_DATA (objfile)]
1420130812Smarcel	    = (so_list->som_solib.data_start - private_section->vma);
1421130812Smarcel	  offsets->offsets[SECT_OFF_BSS (objfile)]
1422130812Smarcel	    = ANOFFSET (offsets, SECT_OFF_DATA (objfile));
1423130812Smarcel	  return 1;
1424130812Smarcel	}
1425130812Smarcel      so_list = so_list->next;
1426130812Smarcel    }
1427130812Smarcel  return 0;
1428130812Smarcel}
1429130812Smarcel
1430130812Smarcel/* Dump information about all the currently loaded shared libraries.  */
1431130812Smarcel
1432130812Smarcelstatic void
1433130812Smarcelsom_sharedlibrary_info_command (char *ignore, int from_tty)
1434130812Smarcel{
1435130812Smarcel  struct so_list *so_list = so_list_head;
1436130812Smarcel
1437130812Smarcel  if (exec_bfd == NULL)
1438130812Smarcel    {
1439130812Smarcel      printf_unfiltered ("No executable file.\n");
1440130812Smarcel      return;
1441130812Smarcel    }
1442130812Smarcel
1443130812Smarcel  if (so_list == NULL)
1444130812Smarcel    {
1445130812Smarcel      printf_unfiltered ("No shared libraries loaded at this time.\n");
1446130812Smarcel      return;
1447130812Smarcel    }
1448130812Smarcel
1449130812Smarcel  printf_unfiltered ("Shared Object Libraries\n");
1450130812Smarcel  printf_unfiltered ("    %-12s%-12s%-12s%-12s%-12s%-12s\n",
1451130812Smarcel	 "  flags", "  tstart", "   tend", "  dstart", "   dend", "   dlt");
1452130812Smarcel  while (so_list)
1453130812Smarcel    {
1454130812Smarcel      unsigned int flags;
1455130812Smarcel
1456130812Smarcel      flags = so_list->som_solib.struct_version << 24;
1457130812Smarcel      flags |= so_list->som_solib.bind_mode << 16;
1458130812Smarcel      flags |= so_list->som_solib.library_version;
1459130812Smarcel      printf_unfiltered ("%s", so_list->som_solib.name);
1460130812Smarcel      if (so_list->objfile == NULL)
1461130812Smarcel	printf_unfiltered ("  (symbols not loaded)");
1462130812Smarcel      printf_unfiltered ("\n");
1463130812Smarcel      printf_unfiltered ("    %-12s", local_hex_string_custom (flags, "08l"));
1464130812Smarcel      printf_unfiltered ("%-12s",
1465130812Smarcel	     local_hex_string_custom (so_list->som_solib.text_addr, "08l"));
1466130812Smarcel      printf_unfiltered ("%-12s",
1467130812Smarcel	      local_hex_string_custom (so_list->som_solib.text_end, "08l"));
1468130812Smarcel      printf_unfiltered ("%-12s",
1469130812Smarcel	    local_hex_string_custom (so_list->som_solib.data_start, "08l"));
1470130812Smarcel      printf_unfiltered ("%-12s",
1471130812Smarcel	      local_hex_string_custom (so_list->som_solib.data_end, "08l"));
1472130812Smarcel      printf_unfiltered ("%-12s\n",
1473130812Smarcel	     local_hex_string_custom (so_list->som_solib.got_value, "08l"));
1474130812Smarcel      so_list = so_list->next;
1475130812Smarcel    }
1476130812Smarcel}
1477130812Smarcel
1478130812Smarcelstatic void
1479130812Smarcelsom_solib_sharedlibrary_command (char *args, int from_tty)
1480130812Smarcel{
1481130812Smarcel  dont_repeat ();
1482130812Smarcel  som_solib_add (args, from_tty, (struct target_ops *) 0, 1);
1483130812Smarcel}
1484130812Smarcel
1485130812Smarcel
1486130812Smarcel
1487130812Smarcelchar *
1488130812Smarcelsom_solib_address (CORE_ADDR addr)
1489130812Smarcel{
1490130812Smarcel  struct so_list *so = so_list_head;
1491130812Smarcel
1492130812Smarcel  while (so)
1493130812Smarcel    {
1494130812Smarcel      /* Is this address within this shlib's text range?  If so,
1495130812Smarcel         return the shlib's name.
1496130812Smarcel       */
1497130812Smarcel      if ((addr >= so->som_solib.text_addr) && (addr <= so->som_solib.text_end))
1498130812Smarcel	return so->som_solib.name;
1499130812Smarcel
1500130812Smarcel      /* Nope, keep looking... */
1501130812Smarcel      so = so->next;
1502130812Smarcel    }
1503130812Smarcel
1504130812Smarcel  /* No, we couldn't prove that the address is within a shlib. */
1505130812Smarcel  return NULL;
1506130812Smarcel}
1507130812Smarcel
1508130812Smarcel
1509130812Smarcelvoid
1510130812Smarcelsom_solib_restart (void)
1511130812Smarcel{
1512130812Smarcel  struct so_list *sl = so_list_head;
1513130812Smarcel
1514130812Smarcel  /* Before the shlib info vanishes, use it to disable any breakpoints
1515130812Smarcel     that may still be active in those shlibs.
1516130812Smarcel   */
1517130812Smarcel  disable_breakpoints_in_shlibs (0);
1518130812Smarcel
1519130812Smarcel  /* Discard all the shlib descriptors.
1520130812Smarcel   */
1521130812Smarcel  while (sl)
1522130812Smarcel    {
1523130812Smarcel      struct so_list *next_sl = sl->next;
1524130812Smarcel      xfree (sl);
1525130812Smarcel      sl = next_sl;
1526130812Smarcel    }
1527130812Smarcel  so_list_head = NULL;
1528130812Smarcel
1529130812Smarcel  som_solib_total_st_size = (LONGEST) 0;
1530130812Smarcel  som_solib_st_size_threshold_exceeded = 0;
1531130812Smarcel
1532130812Smarcel  dld_cache.is_valid = 0;
1533130812Smarcel
1534130812Smarcel  dld_cache.hook.address = 0;
1535130812Smarcel  dld_cache.hook.unwind = NULL;
1536130812Smarcel
1537130812Smarcel  dld_cache.hook_stub.address = 0;
1538130812Smarcel  dld_cache.hook_stub.unwind = NULL;
1539130812Smarcel
1540130812Smarcel  dld_cache.load.address = 0;
1541130812Smarcel  dld_cache.load.unwind = NULL;
1542130812Smarcel
1543130812Smarcel  dld_cache.load_stub.address = 0;
1544130812Smarcel  dld_cache.load_stub.unwind = NULL;
1545130812Smarcel
1546130812Smarcel  dld_cache.unload.address = 0;
1547130812Smarcel  dld_cache.unload.unwind = NULL;
1548130812Smarcel
1549130812Smarcel  dld_cache.unload2.address = 0;
1550130812Smarcel  dld_cache.unload2.unwind = NULL;
1551130812Smarcel
1552130812Smarcel  dld_cache.unload_stub.address = 0;
1553130812Smarcel  dld_cache.unload_stub.unwind = NULL;
1554130812Smarcel}
1555130812Smarcel
1556130812Smarcel
1557130812Smarcel/* LOCAL FUNCTION
1558130812Smarcel
1559130812Smarcel   no_shared_libraries -- handle command to explicitly discard symbols
1560130812Smarcel   from shared libraries.
1561130812Smarcel
1562130812Smarcel   DESCRIPTION
1563130812Smarcel
1564130812Smarcel   Implements the command "nosharedlibrary", which discards symbols
1565130812Smarcel   that have been auto-loaded from shared libraries.  Symbols from
1566130812Smarcel   shared libraries that were added by explicit request of the user
1567130812Smarcel   are not discarded.  Also called from remote.c.  */
1568130812Smarcel
1569130812Smarcelvoid
1570130812Smarcelno_shared_libraries (char *ignored, int from_tty)
1571130812Smarcel{
1572130812Smarcel  /* FIXME */
1573130812Smarcel}
1574130812Smarcel
1575130812Smarcel
1576130812Smarcelvoid
1577130812Smarcel_initialize_som_solib (void)
1578130812Smarcel{
1579130812Smarcel  add_com ("sharedlibrary", class_files, som_solib_sharedlibrary_command,
1580130812Smarcel	   "Load shared object library symbols for files matching REGEXP.");
1581130812Smarcel  add_info ("sharedlibrary", som_sharedlibrary_info_command,
1582130812Smarcel	    "Status of loaded shared object libraries.");
1583130812Smarcel
1584130812Smarcel  add_show_from_set
1585130812Smarcel    (add_set_cmd ("auto-solib-add", class_support, var_boolean,
1586130812Smarcel		  (char *) &auto_solib_add,
1587130812Smarcel		  "Set autoloading of shared library symbols.\n\
1588130812SmarcelIf \"on\", symbols from all shared object libraries will be loaded\n\
1589130812Smarcelautomatically when the inferior begins execution, when the dynamic linker\n\
1590130812Smarcelinforms gdb that a new library has been loaded, or when attaching to the\n\
1591130812Smarcelinferior.  Otherwise, symbols must be loaded manually, using `sharedlibrary'.",
1592130812Smarcel		  &setlist),
1593130812Smarcel     &showlist);
1594130812Smarcel
1595130812Smarcel  add_show_from_set
1596130812Smarcel    (add_set_cmd ("auto-solib-limit", class_support, var_zinteger,
1597130812Smarcel		  (char *) &auto_solib_limit,
1598130812Smarcel		  "Set threshold (in Mb) for autoloading shared library symbols.\n\
1599130812SmarcelWhen shared library autoloading is enabled, new libraries will be loaded\n\
1600130812Smarcelonly until the total size of shared library symbols exceeds this\n\
1601130812Smarcelthreshold in megabytes.  Is ignored when using `sharedlibrary'.",
1602130812Smarcel		  &setlist),
1603130812Smarcel     &showlist);
1604130812Smarcel
1605130812Smarcel  /* ??rehrauer: On HP-UX, the kernel parameter MAXDSIZ limits how
1606130812Smarcel     much data space a process can use.  We ought to be reading
1607130812Smarcel     MAXDSIZ and setting auto_solib_limit to some large fraction of
1608130812Smarcel     that value.  If not that, we maybe ought to be setting it smaller
1609130812Smarcel     than the default for MAXDSIZ (that being 64Mb, I believe).
1610130812Smarcel     However, [1] this threshold is only crudely approximated rather
1611130812Smarcel     than actually measured, and [2] 50 Mbytes is too small for
1612130812Smarcel     debugging gdb itself.  Thus, the arbitrary 100 figure.  */
1613130812Smarcel  auto_solib_limit = 100;	/* Megabytes */
1614130812Smarcel
1615130812Smarcel  som_solib_restart ();
1616130812Smarcel}
1617130812Smarcel
1618130812Smarcel/* Get some HPUX-specific data from a shared lib.
1619130812Smarcel */
1620130812SmarcelCORE_ADDR
1621130812Smarcelso_lib_thread_start_addr (struct so_list *so)
1622130812Smarcel{
1623130812Smarcel  return so->som_solib.tsd_start_addr;
1624130812Smarcel}
1625