xref: /openbsd-src/gnu/usr.bin/binutils/gdb/somsolib.c (revision 63addd46c1e40ca0f49488ddcdc4ab598023b0c1)
1e93f7393Sniklas /* Handle HP SOM shared libraries for GDB, the GNU Debugger.
2b725ae77Skettenis 
3b725ae77Skettenis    Copyright 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, 2002,
4b725ae77Skettenis    2003, 2004 Free Software Foundation, Inc.
5e93f7393Sniklas 
6e93f7393Sniklas    This file is part of GDB.
7e93f7393Sniklas 
8e93f7393Sniklas    This program is free software; you can redistribute it and/or modify
9e93f7393Sniklas    it under the terms of the GNU General Public License as published by
10e93f7393Sniklas    the Free Software Foundation; either version 2 of the License, or
11e93f7393Sniklas    (at your option) any later version.
12e93f7393Sniklas 
13e93f7393Sniklas    This program is distributed in the hope that it will be useful,
14e93f7393Sniklas    but WITHOUT ANY WARRANTY; without even the implied warranty of
15e93f7393Sniklas    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16e93f7393Sniklas    GNU General Public License for more details.
17e93f7393Sniklas 
18e93f7393Sniklas    You should have received a copy of the GNU General Public License
19e93f7393Sniklas    along with this program; if not, write to the Free Software
20b725ae77Skettenis    Foundation, Inc., 59 Temple Place - Suite 330,
21b725ae77Skettenis    Boston, MA 02111-1307, USA.
22e93f7393Sniklas 
23e93f7393Sniklas    Written by the Center for Software Science at the Univerity of Utah
24e93f7393Sniklas    and by Cygnus Support.  */
25e93f7393Sniklas 
26e93f7393Sniklas 
27e93f7393Sniklas #include "defs.h"
28e93f7393Sniklas 
29e93f7393Sniklas #include "frame.h"
30e93f7393Sniklas #include "bfd.h"
31e93f7393Sniklas #include "som.h"
32e93f7393Sniklas #include "libhppa.h"
33e93f7393Sniklas #include "gdbcore.h"
34e93f7393Sniklas #include "symtab.h"
35e93f7393Sniklas #include "breakpoint.h"
36e93f7393Sniklas #include "symfile.h"
37e93f7393Sniklas #include "objfiles.h"
38e93f7393Sniklas #include "inferior.h"
39e93f7393Sniklas #include "gdb-stabs.h"
40b725ae77Skettenis #include "gdb_stat.h"
41e93f7393Sniklas #include "gdbcmd.h"
42e93f7393Sniklas #include "language.h"
43b725ae77Skettenis #include "regcache.h"
44b725ae77Skettenis #include "gdb_assert.h"
45b725ae77Skettenis #include "exec.h"
46*63addd46Skettenis #include "hppa-tdep.h"
47b725ae77Skettenis 
48b725ae77Skettenis #include <fcntl.h>
49b725ae77Skettenis 
50b725ae77Skettenis #ifndef O_BINARY
51b725ae77Skettenis #define O_BINARY 0
52b725ae77Skettenis #endif
53b725ae77Skettenis 
54b725ae77Skettenis /* Uncomment this to turn on some debugging output.
55b725ae77Skettenis  */
56b725ae77Skettenis 
57b725ae77Skettenis /* #define SOLIB_DEBUG
58b725ae77Skettenis  */
59b725ae77Skettenis 
60b725ae77Skettenis /* This lives in hppa-tdep.c. */
61b725ae77Skettenis extern struct unwind_table_entry *find_unwind_entry (CORE_ADDR pc);
62b725ae77Skettenis 
63b725ae77Skettenis /* These ought to be defined in some public interface, but aren't.  They
64b725ae77Skettenis    define the meaning of the various bits in the distinguished __dld_flags
65b725ae77Skettenis    variable that is declared in every debuggable a.out on HP-UX, and that
66b725ae77Skettenis    is shared between the debugger and the dynamic linker.
67b725ae77Skettenis  */
68b725ae77Skettenis #define DLD_FLAGS_MAPPRIVATE    0x1
69b725ae77Skettenis #define DLD_FLAGS_HOOKVALID     0x2
70b725ae77Skettenis #define DLD_FLAGS_LISTVALID     0x4
71b725ae77Skettenis #define DLD_FLAGS_BOR_ENABLE    0x8
72e93f7393Sniklas 
73e93f7393Sniklas /* TODO:
74e93f7393Sniklas 
75e93f7393Sniklas    * Support for hpux8 dynamic linker.  */
76e93f7393Sniklas 
77e93f7393Sniklas /* The basic structure which describes a dynamically loaded object.  This
78e93f7393Sniklas    data structure is private to the dynamic linker and isn't found in
79e93f7393Sniklas    any HPUX include file.  */
80e93f7393Sniklas 
81e93f7393Sniklas struct som_solib_mapped_entry
82e93f7393Sniklas   {
83e93f7393Sniklas     /* The name of the library.  */
84e93f7393Sniklas     char *name;
85e93f7393Sniklas 
86e93f7393Sniklas     /* Version of this structure (it is expected to change again in hpux10).  */
87e93f7393Sniklas     unsigned char struct_version;
88e93f7393Sniklas 
89e93f7393Sniklas     /* Binding mode for this library.  */
90e93f7393Sniklas     unsigned char bind_mode;
91e93f7393Sniklas 
92e93f7393Sniklas     /* Version of this library.  */
93e93f7393Sniklas     short library_version;
94e93f7393Sniklas 
95b725ae77Skettenis     /* Start of text address,
96b725ae77Skettenis      * link-time text location (length of text area),
97b725ae77Skettenis      * end of text address.  */
98e93f7393Sniklas     CORE_ADDR text_addr;
99e93f7393Sniklas     CORE_ADDR text_link_addr;
100e93f7393Sniklas     CORE_ADDR text_end;
101e93f7393Sniklas 
102e93f7393Sniklas     /* Start of data, start of bss and end of data.  */
103e93f7393Sniklas     CORE_ADDR data_start;
104e93f7393Sniklas     CORE_ADDR bss_start;
105e93f7393Sniklas     CORE_ADDR data_end;
106e93f7393Sniklas 
107e93f7393Sniklas     /* Value of linkage pointer (%r19).  */
108e93f7393Sniklas     CORE_ADDR got_value;
109e93f7393Sniklas 
110e93f7393Sniklas     /* Next entry.  */
111e93f7393Sniklas     struct som_solib_mapped_entry *next;
112e93f7393Sniklas 
113e93f7393Sniklas     /* There are other fields, but I don't have information as to what is
114e93f7393Sniklas        contained in them.  */
115b725ae77Skettenis 
116b725ae77Skettenis     /* For versions from HPUX-10.30 and up */
117b725ae77Skettenis 
118b725ae77Skettenis     /* Address in target of offset from thread-local register of
119b725ae77Skettenis      * start of this thread's data.  I.e., the first thread-local
120b725ae77Skettenis      * variable in this shared library starts at *(tsd_start_addr)
121b725ae77Skettenis      * from that area pointed to by cr27 (mpsfu_hi).
122b725ae77Skettenis      *
123b725ae77Skettenis      * We do the indirection as soon as we read it, so from then
124b725ae77Skettenis      * on it's the offset itself.
125b725ae77Skettenis      */
126b725ae77Skettenis     CORE_ADDR tsd_start_addr;
127b725ae77Skettenis 
128b725ae77Skettenis     /* Following this are longwords holding:
129b725ae77Skettenis 
130b725ae77Skettenis      * ?, ?, ?, ptr to -1, ptr to-1, ptr to lib name (leaf name),
131b725ae77Skettenis      * ptr to __data_start, ptr to __data_end
132b725ae77Skettenis      */
133b725ae77Skettenis 
134b725ae77Skettenis 
135e93f7393Sniklas   };
136e93f7393Sniklas 
137e93f7393Sniklas /* A structure to keep track of all the known shared objects.  */
138e93f7393Sniklas struct so_list
139e93f7393Sniklas   {
140e93f7393Sniklas     struct som_solib_mapped_entry som_solib;
141e93f7393Sniklas     struct objfile *objfile;
142e93f7393Sniklas     bfd *abfd;
143e93f7393Sniklas     struct section_table *sections;
144e93f7393Sniklas     struct section_table *sections_end;
145b725ae77Skettenis /* elz: added this field to store the address in target space (in the
146b725ae77Skettenis    library) of the library descriptor (handle) which we read into
147b725ae77Skettenis    som_solib_mapped_entry structure */
148b725ae77Skettenis     CORE_ADDR solib_addr;
149e93f7393Sniklas     struct so_list *next;
150b725ae77Skettenis 
151e93f7393Sniklas   };
152e93f7393Sniklas 
153e93f7393Sniklas static struct so_list *so_list_head;
154e93f7393Sniklas 
155e93f7393Sniklas 
156b725ae77Skettenis /* This is the cumulative size in bytes of the symbol tables of all
157b725ae77Skettenis    shared objects on the so_list_head list.  (When we say size, here
158b725ae77Skettenis    we mean of the information before it is brought into memory and
159b725ae77Skettenis    potentially expanded by GDB.)  When adding a new shlib, this value
160b725ae77Skettenis    is compared against the threshold size, held by auto_solib_limit
161b725ae77Skettenis    (in megabytes).  If adding symbols for the new shlib would cause
162b725ae77Skettenis    the total size to exceed the threshold, then the new shlib's
163b725ae77Skettenis    symbols are not loaded.  */
164b725ae77Skettenis static LONGEST som_solib_total_st_size;
165e93f7393Sniklas 
166b725ae77Skettenis /* When the threshold is reached for any shlib, we refuse to add
167b725ae77Skettenis    symbols for subsequent shlibs, even if those shlibs' symbols would
168b725ae77Skettenis    be small enough to fit under the threshold.  (Although this may
169b725ae77Skettenis    result in one, early large shlib preventing the loading of later,
170b725ae77Skettenis    smalller shlibs' symbols, it allows us to issue one informational
171b725ae77Skettenis    message.  The alternative, to issue a message for each shlib whose
172b725ae77Skettenis    symbols aren't loaded, could be a big annoyance where the threshold
173b725ae77Skettenis    is exceeded due to a very large number of shlibs.)
174b725ae77Skettenis  */
175b725ae77Skettenis static int som_solib_st_size_threshold_exceeded;
176b725ae77Skettenis 
177b725ae77Skettenis /* These addresses should be filled in by som_solib_create_inferior_hook.
178b725ae77Skettenis    They are also used elsewhere in this module.
179b725ae77Skettenis  */
180b725ae77Skettenis typedef struct
181b725ae77Skettenis   {
182b725ae77Skettenis     CORE_ADDR address;
183b725ae77Skettenis     struct unwind_table_entry *unwind;
184b725ae77Skettenis   }
185b725ae77Skettenis addr_and_unwind_t;
186b725ae77Skettenis 
187b725ae77Skettenis /* When adding fields, be sure to clear them in _initialize_som_solib. */
188b725ae77Skettenis static struct
189b725ae77Skettenis   {
190b725ae77Skettenis     int is_valid;
191b725ae77Skettenis     addr_and_unwind_t hook;
192b725ae77Skettenis     addr_and_unwind_t hook_stub;
193b725ae77Skettenis     addr_and_unwind_t load;
194b725ae77Skettenis     addr_and_unwind_t load_stub;
195b725ae77Skettenis     addr_and_unwind_t unload;
196b725ae77Skettenis     addr_and_unwind_t unload2;
197b725ae77Skettenis     addr_and_unwind_t unload_stub;
198b725ae77Skettenis   }
199b725ae77Skettenis dld_cache;
200b725ae77Skettenis 
201b725ae77Skettenis 
202b725ae77Skettenis 
203b725ae77Skettenis static void som_sharedlibrary_info_command (char *, int);
204b725ae77Skettenis 
205b725ae77Skettenis static void som_solib_sharedlibrary_command (char *, int);
206b725ae77Skettenis 
207b725ae77Skettenis static LONGEST
som_solib_sizeof_symbol_table(char * filename)208b725ae77Skettenis som_solib_sizeof_symbol_table (char *filename)
209b725ae77Skettenis {
210b725ae77Skettenis   bfd *abfd;
211b725ae77Skettenis   int desc;
212b725ae77Skettenis   char *absolute_name;
213b725ae77Skettenis   LONGEST st_size = (LONGEST) 0;
214b725ae77Skettenis   asection *sect;
215b725ae77Skettenis 
216b725ae77Skettenis   /* We believe that filename was handed to us by the dynamic linker, and
217b725ae77Skettenis      is therefore always an absolute path.
218b725ae77Skettenis    */
219*63addd46Skettenis   desc = openp (getenv ("PATH"), OPF_TRY_CWD_FIRST, filename,
220*63addd46Skettenis 		O_RDONLY | O_BINARY, 0, &absolute_name);
221b725ae77Skettenis   if (desc < 0)
222b725ae77Skettenis     {
223b725ae77Skettenis       perror_with_name (filename);
224b725ae77Skettenis     }
225b725ae77Skettenis   filename = absolute_name;
226b725ae77Skettenis 
227b725ae77Skettenis   abfd = bfd_fdopenr (filename, gnutarget, desc);
228b725ae77Skettenis   if (!abfd)
229b725ae77Skettenis     {
230b725ae77Skettenis       close (desc);
231b725ae77Skettenis       make_cleanup (xfree, filename);
232b725ae77Skettenis       error ("\"%s\": can't open to read symbols: %s.", filename,
233b725ae77Skettenis 	     bfd_errmsg (bfd_get_error ()));
234b725ae77Skettenis     }
235b725ae77Skettenis 
236b725ae77Skettenis   if (!bfd_check_format (abfd, bfd_object))	/* Reads in section info */
237b725ae77Skettenis     {
238b725ae77Skettenis       bfd_close (abfd);		/* This also closes desc */
239b725ae77Skettenis       make_cleanup (xfree, filename);
240b725ae77Skettenis       error ("\"%s\": can't read symbols: %s.", filename,
241b725ae77Skettenis 	     bfd_errmsg (bfd_get_error ()));
242b725ae77Skettenis     }
243b725ae77Skettenis 
244b725ae77Skettenis   /* Sum the sizes of the various sections that compose debug info. */
245b725ae77Skettenis 
246b725ae77Skettenis   /* This contains non-DOC information. */
247b725ae77Skettenis   sect = bfd_get_section_by_name (abfd, "$DEBUG$");
248b725ae77Skettenis   if (sect)
249b725ae77Skettenis     st_size += (LONGEST) bfd_section_size (abfd, sect);
250b725ae77Skettenis 
251b725ae77Skettenis   /* This contains DOC information. */
252b725ae77Skettenis   sect = bfd_get_section_by_name (abfd, "$PINFO$");
253b725ae77Skettenis   if (sect)
254b725ae77Skettenis     st_size += (LONGEST) bfd_section_size (abfd, sect);
255b725ae77Skettenis 
256b725ae77Skettenis   bfd_close (abfd);		/* This also closes desc */
257b725ae77Skettenis   xfree (filename);
258b725ae77Skettenis 
259b725ae77Skettenis   /* Unfortunately, just summing the sizes of various debug info
260b725ae77Skettenis      sections isn't a very accurate measurement of how much heap
261b725ae77Skettenis      space the debugger will need to hold them.  It also doesn't
262b725ae77Skettenis      account for space needed by linker (aka "minimal") symbols.
263b725ae77Skettenis 
264b725ae77Skettenis      Anecdotal evidence suggests that just summing the sizes of
265b725ae77Skettenis      debug-info-related sections understates the heap space needed
266b725ae77Skettenis      to represent it internally by about an order of magnitude.
267b725ae77Skettenis 
268b725ae77Skettenis      Since it's not exactly brain surgery we're doing here, rather
269b725ae77Skettenis      than attempt to more accurately measure the size of a shlib's
270b725ae77Skettenis      symbol table in GDB's heap, we'll just apply a 10x fudge-
271b725ae77Skettenis      factor to the debug info sections' size-sum.  No, this doesn't
272b725ae77Skettenis      account for minimal symbols in non-debuggable shlibs.  But it
273b725ae77Skettenis      all roughly washes out in the end.
274b725ae77Skettenis    */
275b725ae77Skettenis   return st_size * (LONGEST) 10;
276b725ae77Skettenis }
277b725ae77Skettenis 
278b725ae77Skettenis 
279b725ae77Skettenis static void
som_solib_add_solib_objfile(struct so_list * so,char * name,int from_tty,CORE_ADDR text_addr)280b725ae77Skettenis som_solib_add_solib_objfile (struct so_list *so, char *name, int from_tty,
281b725ae77Skettenis 			     CORE_ADDR text_addr)
282b725ae77Skettenis {
283*63addd46Skettenis   struct hppa_objfile_private *obj_private;
284b725ae77Skettenis   struct obj_section *s;
285b725ae77Skettenis 
286b725ae77Skettenis   so->objfile = symbol_file_add (name, from_tty, NULL, 0, OBJF_SHARED);
287b725ae77Skettenis   so->abfd = so->objfile->obfd;
288b725ae77Skettenis 
289b725ae77Skettenis   /* syms_from_objfile has bizarre section offset code,
290b725ae77Skettenis      so I do my own right here.  */
291b725ae77Skettenis   for (s = so->objfile->sections; s < so->objfile->sections_end; s++)
292b725ae77Skettenis     {
293b725ae77Skettenis       flagword aflag = bfd_get_section_flags(so->abfd, s->the_bfd_section);
294b725ae77Skettenis       if (aflag & SEC_CODE)
295b725ae77Skettenis 	{
296b725ae77Skettenis 	  s->addr    += so->som_solib.text_addr - so->som_solib.text_link_addr;
297b725ae77Skettenis 	  s->endaddr += so->som_solib.text_addr - so->som_solib.text_link_addr;
298b725ae77Skettenis 	}
299b725ae77Skettenis       else if (aflag & SEC_DATA)
300b725ae77Skettenis 	{
301b725ae77Skettenis 	  s->addr    += so->som_solib.data_start;
302b725ae77Skettenis 	  s->endaddr += so->som_solib.data_start;
303b725ae77Skettenis 	}
304b725ae77Skettenis       else
305b725ae77Skettenis 	;
306b725ae77Skettenis     }
307b725ae77Skettenis 
308b725ae77Skettenis   /* Mark this as a shared library and save private data.
309b725ae77Skettenis    */
310b725ae77Skettenis   so->objfile->flags |= OBJF_SHARED;
311b725ae77Skettenis 
312*63addd46Skettenis   obj_private = (struct hppa_objfile_private *)
313*63addd46Skettenis 	        objfile_data (so->objfile, hppa_objfile_priv_data);
314*63addd46Skettenis   if (obj_private == NULL)
315b725ae77Skettenis     {
316*63addd46Skettenis       obj_private = (struct hppa_objfile_private *)
317b725ae77Skettenis 	obstack_alloc (&so->objfile->objfile_obstack,
318*63addd46Skettenis 		       sizeof (struct hppa_objfile_private));
319*63addd46Skettenis       set_objfile_data (so->objfile, hppa_objfile_priv_data, obj_private);
320b725ae77Skettenis       obj_private->unwind_info = NULL;
321b725ae77Skettenis       obj_private->so_info = NULL;
322b725ae77Skettenis     }
323b725ae77Skettenis 
324b725ae77Skettenis   obj_private->so_info = so;
325b725ae77Skettenis 
326b725ae77Skettenis   if (!bfd_check_format (so->abfd, bfd_object))
327b725ae77Skettenis     {
328b725ae77Skettenis       error ("\"%s\": not in executable format: %s.",
329b725ae77Skettenis 	     name, bfd_errmsg (bfd_get_error ()));
330b725ae77Skettenis     }
331b725ae77Skettenis }
332b725ae77Skettenis 
333b725ae77Skettenis 
334b725ae77Skettenis static void
som_solib_load_symbols(struct so_list * so,char * name,int from_tty,CORE_ADDR text_addr,struct target_ops * target)335b725ae77Skettenis som_solib_load_symbols (struct so_list *so, char *name, int from_tty,
336b725ae77Skettenis 			CORE_ADDR text_addr, struct target_ops *target)
337b725ae77Skettenis {
338b725ae77Skettenis   struct section_table *p;
339b725ae77Skettenis   int status;
340b725ae77Skettenis   char buf[4];
341b725ae77Skettenis   CORE_ADDR presumed_data_start;
342b725ae77Skettenis 
343b725ae77Skettenis #ifdef SOLIB_DEBUG
344b725ae77Skettenis   printf ("--Adding symbols for shared library \"%s\"\n", name);
345b725ae77Skettenis #endif
346b725ae77Skettenis 
347b725ae77Skettenis   som_solib_add_solib_objfile (so, name, from_tty, text_addr);
348b725ae77Skettenis 
349b725ae77Skettenis   /* Now we need to build a section table for this library since
350b725ae77Skettenis      we might be debugging a core file from a dynamically linked
351b725ae77Skettenis      executable in which the libraries were not privately mapped.  */
352b725ae77Skettenis   if (build_section_table (so->abfd,
353b725ae77Skettenis 			   &so->sections,
354b725ae77Skettenis 			   &so->sections_end))
355b725ae77Skettenis     {
356b725ae77Skettenis       error ("Unable to build section table for shared library\n.");
357b725ae77Skettenis       return;
358b725ae77Skettenis     }
359b725ae77Skettenis 
360b725ae77Skettenis   /* Relocate all the sections based on where they got loaded.  */
361b725ae77Skettenis   for (p = so->sections; p < so->sections_end; p++)
362b725ae77Skettenis     {
363b725ae77Skettenis       if (p->the_bfd_section->flags & SEC_CODE)
364b725ae77Skettenis 	{
365b725ae77Skettenis 	  p->addr += ANOFFSET (so->objfile->section_offsets, SECT_OFF_TEXT (so->objfile));
366b725ae77Skettenis 	  p->endaddr += ANOFFSET (so->objfile->section_offsets, SECT_OFF_TEXT (so->objfile));
367b725ae77Skettenis 	}
368b725ae77Skettenis       else if (p->the_bfd_section->flags & SEC_DATA)
369b725ae77Skettenis 	{
370b725ae77Skettenis 	  p->addr += ANOFFSET (so->objfile->section_offsets, SECT_OFF_DATA (so->objfile));
371b725ae77Skettenis 	  p->endaddr += ANOFFSET (so->objfile->section_offsets, SECT_OFF_DATA (so->objfile));
372b725ae77Skettenis 	}
373b725ae77Skettenis     }
374b725ae77Skettenis 
375b725ae77Skettenis   /* Now see if we need to map in the text and data for this shared
376b725ae77Skettenis      library (for example debugging a core file which does not use
377b725ae77Skettenis      private shared libraries.).
378b725ae77Skettenis 
379b725ae77Skettenis      Carefully peek at the first text address in the library.  If the
380b725ae77Skettenis      read succeeds, then the libraries were privately mapped and were
381b725ae77Skettenis      included in the core dump file.
382b725ae77Skettenis 
383b725ae77Skettenis      If the peek failed, then the libraries were not privately mapped
384b725ae77Skettenis      and are not in the core file, we'll have to read them in ourselves.  */
385b725ae77Skettenis   status = target_read_memory (text_addr, buf, 4);
386b725ae77Skettenis   if (status != 0)
387b725ae77Skettenis     {
388b725ae77Skettenis       int old, new;
389b725ae77Skettenis 
390b725ae77Skettenis       new = so->sections_end - so->sections;
391b725ae77Skettenis 
392b725ae77Skettenis       old = target_resize_to_sections (target, new);
393b725ae77Skettenis 
394b725ae77Skettenis       /* Copy over the old data before it gets clobbered.  */
395b725ae77Skettenis       memcpy ((char *) (target->to_sections + old),
396b725ae77Skettenis 	      so->sections,
397b725ae77Skettenis 	      ((sizeof (struct section_table)) * new));
398b725ae77Skettenis     }
399b725ae77Skettenis }
400b725ae77Skettenis 
401b725ae77Skettenis 
402b725ae77Skettenis /* FIXME: cagney/2003-02-01: This just isn't right.  Given an address
403b725ae77Skettenis    within the target's address space, this converts the value into an
404b725ae77Skettenis    address within the host's (i.e., GDB's) address space.  Given that
405b725ae77Skettenis    the host/target address spaces are separate, this can't be right.  */
406b725ae77Skettenis 
407b725ae77Skettenis static void *
hpux_address_to_host_pointer_hack(CORE_ADDR addr)408b725ae77Skettenis hpux_address_to_host_pointer_hack (CORE_ADDR addr)
409b725ae77Skettenis {
410b725ae77Skettenis   void *ptr;
411b725ae77Skettenis 
412b725ae77Skettenis   gdb_assert (sizeof (ptr) == TYPE_LENGTH (builtin_type_void_data_ptr));
413b725ae77Skettenis   ADDRESS_TO_POINTER (builtin_type_void_data_ptr, &ptr, addr);
414b725ae77Skettenis   return ptr;
415b725ae77Skettenis }
416b725ae77Skettenis 
417b725ae77Skettenis /* Add symbols from shared libraries into the symtab list, unless the
418b725ae77Skettenis    size threshold specified by auto_solib_limit (in megabytes) would
419b725ae77Skettenis    be exceeded.  */
420e93f7393Sniklas 
421e93f7393Sniklas void
som_solib_add(char * arg_string,int from_tty,struct target_ops * target,int readsyms)422b725ae77Skettenis som_solib_add (char *arg_string, int from_tty, struct target_ops *target, int readsyms)
423e93f7393Sniklas {
424e93f7393Sniklas   struct minimal_symbol *msymbol;
425e93f7393Sniklas   struct so_list *so_list_tail;
426e93f7393Sniklas   CORE_ADDR addr;
427e93f7393Sniklas   asection *shlib_info;
428e93f7393Sniklas   int status;
429e93f7393Sniklas   unsigned int dld_flags;
430e93f7393Sniklas   char buf[4], *re_err;
431b725ae77Skettenis   int threshold_warning_given = 0;
432e93f7393Sniklas 
433e93f7393Sniklas   /* First validate our arguments.  */
434b725ae77Skettenis   re_err = re_comp (arg_string ? arg_string : ".");
435b725ae77Skettenis   if (re_err != NULL)
436e93f7393Sniklas     {
437e93f7393Sniklas       error ("Invalid regexp: %s", re_err);
438e93f7393Sniklas     }
439e93f7393Sniklas 
440e93f7393Sniklas   /* If we're debugging a core file, or have attached to a running
441e93f7393Sniklas      process, then som_solib_create_inferior_hook will not have been
442e93f7393Sniklas      called.
443e93f7393Sniklas 
444e93f7393Sniklas      We need to first determine if we're dealing with a dynamically
445e93f7393Sniklas      linked executable.  If not, then return without an error or warning.
446e93f7393Sniklas 
447e93f7393Sniklas      We also need to examine __dld_flags to determine if the shared library
448e93f7393Sniklas      list is valid and to determine if the libraries have been privately
449e93f7393Sniklas      mapped.  */
450e93f7393Sniklas   if (symfile_objfile == NULL)
451e93f7393Sniklas     return;
452e93f7393Sniklas 
453e93f7393Sniklas   /* First see if the objfile was dynamically linked.  */
454e93f7393Sniklas   shlib_info = bfd_get_section_by_name (symfile_objfile->obfd, "$SHLIB_INFO$");
455e93f7393Sniklas   if (!shlib_info)
456e93f7393Sniklas     return;
457e93f7393Sniklas 
458e93f7393Sniklas   /* It's got a $SHLIB_INFO$ section, make sure it's not empty.  */
459e93f7393Sniklas   if (bfd_section_size (symfile_objfile->obfd, shlib_info) == 0)
460e93f7393Sniklas     return;
461e93f7393Sniklas 
462e93f7393Sniklas   msymbol = lookup_minimal_symbol ("__dld_flags", NULL, NULL);
463e93f7393Sniklas   if (msymbol == NULL)
464e93f7393Sniklas     {
465e93f7393Sniklas       error ("Unable to find __dld_flags symbol in object file.\n");
466e93f7393Sniklas       return;
467e93f7393Sniklas     }
468e93f7393Sniklas 
469e93f7393Sniklas   addr = SYMBOL_VALUE_ADDRESS (msymbol);
470e93f7393Sniklas   /* Read the current contents.  */
471e93f7393Sniklas   status = target_read_memory (addr, buf, 4);
472e93f7393Sniklas   if (status != 0)
473e93f7393Sniklas     {
474e93f7393Sniklas       error ("Unable to read __dld_flags\n");
475e93f7393Sniklas       return;
476e93f7393Sniklas     }
477e93f7393Sniklas   dld_flags = extract_unsigned_integer (buf, 4);
478e93f7393Sniklas 
479b725ae77Skettenis   /* __dld_list may not be valid.  If not, then we punt, warning the user if
480b725ae77Skettenis      we were called as a result of the add-symfile command.
481b725ae77Skettenis    */
482b725ae77Skettenis   if ((dld_flags & DLD_FLAGS_LISTVALID) == 0)
483e93f7393Sniklas     {
484b725ae77Skettenis       if (from_tty)
485e93f7393Sniklas 	error ("__dld_list is not valid according to __dld_flags.\n");
486e93f7393Sniklas       return;
487e93f7393Sniklas     }
488e93f7393Sniklas 
489e93f7393Sniklas   /* If the libraries were not mapped private, warn the user.  */
490b725ae77Skettenis   if ((dld_flags & DLD_FLAGS_MAPPRIVATE) == 0)
491e93f7393Sniklas     warning ("The shared libraries were not privately mapped; setting a\nbreakpoint in a shared library will not work until you rerun the program.\n");
492e93f7393Sniklas 
493e93f7393Sniklas   msymbol = lookup_minimal_symbol ("__dld_list", NULL, NULL);
494e93f7393Sniklas   if (!msymbol)
495e93f7393Sniklas     {
496e93f7393Sniklas       /* Older crt0.o files (hpux8) don't have __dld_list as a symbol,
497e93f7393Sniklas          but the data is still available if you know where to look.  */
498e93f7393Sniklas       msymbol = lookup_minimal_symbol ("__dld_flags", NULL, NULL);
499e93f7393Sniklas       if (!msymbol)
500e93f7393Sniklas 	{
501e93f7393Sniklas 	  error ("Unable to find dynamic library list.\n");
502e93f7393Sniklas 	  return;
503e93f7393Sniklas 	}
504e93f7393Sniklas       addr = SYMBOL_VALUE_ADDRESS (msymbol) - 8;
505e93f7393Sniklas     }
506e93f7393Sniklas   else
507e93f7393Sniklas     addr = SYMBOL_VALUE_ADDRESS (msymbol);
508e93f7393Sniklas 
509e93f7393Sniklas   status = target_read_memory (addr, buf, 4);
510e93f7393Sniklas   if (status != 0)
511e93f7393Sniklas     {
512e93f7393Sniklas       error ("Unable to find dynamic library list.\n");
513e93f7393Sniklas       return;
514e93f7393Sniklas     }
515e93f7393Sniklas 
516e93f7393Sniklas   addr = extract_unsigned_integer (buf, 4);
517e93f7393Sniklas 
518e93f7393Sniklas   /* If addr is zero, then we're using an old dynamic loader which
519e93f7393Sniklas      doesn't maintain __dld_list.  We'll have to use a completely
520e93f7393Sniklas      different approach to get shared library information.  */
521e93f7393Sniklas   if (addr == 0)
522e93f7393Sniklas     goto old_dld;
523e93f7393Sniklas 
524e93f7393Sniklas   /* Using the information in __dld_list is the preferred method
525e93f7393Sniklas      to get at shared library information.  It doesn't depend on
526b725ae77Skettenis      any functions in /opt/langtools/lib/end.o and has a chance of working
527e93f7393Sniklas      with hpux10 when it is released.  */
528e93f7393Sniklas   status = target_read_memory (addr, buf, 4);
529e93f7393Sniklas   if (status != 0)
530e93f7393Sniklas     {
531e93f7393Sniklas       error ("Unable to find dynamic library list.\n");
532e93f7393Sniklas       return;
533e93f7393Sniklas     }
534e93f7393Sniklas 
535e93f7393Sniklas   /* addr now holds the address of the first entry in the dynamic
536e93f7393Sniklas      library list.  */
537e93f7393Sniklas   addr = extract_unsigned_integer (buf, 4);
538e93f7393Sniklas 
539e93f7393Sniklas   /* Now that we have a pointer to the dynamic library list, walk
540e93f7393Sniklas      through it and add the symbols for each library.  */
541e93f7393Sniklas 
542e93f7393Sniklas   so_list_tail = so_list_head;
543e93f7393Sniklas   /* Find the end of the list of shared objects.  */
544e93f7393Sniklas   while (so_list_tail && so_list_tail->next)
545e93f7393Sniklas     so_list_tail = so_list_tail->next;
546e93f7393Sniklas 
547b725ae77Skettenis #ifdef SOLIB_DEBUG
548b725ae77Skettenis   printf ("--About to read shared library list data\n");
549b725ae77Skettenis #endif
550b725ae77Skettenis 
551b725ae77Skettenis   /* "addr" will always point to the base of the
552b725ae77Skettenis    * current data entry describing the current
553b725ae77Skettenis    * shared library.
554b725ae77Skettenis    */
555e93f7393Sniklas   while (1)
556e93f7393Sniklas     {
557e93f7393Sniklas       CORE_ADDR name_addr, text_addr;
558e93f7393Sniklas       unsigned int name_len;
559e93f7393Sniklas       char *name;
560e93f7393Sniklas       struct so_list *new_so;
561e93f7393Sniklas       struct so_list *so_list = so_list_head;
562e93f7393Sniklas       struct stat statbuf;
563b725ae77Skettenis       LONGEST st_size;
564b725ae77Skettenis       int is_main_program;
565e93f7393Sniklas 
566e93f7393Sniklas       if (addr == 0)
567e93f7393Sniklas 	break;
568e93f7393Sniklas 
569e93f7393Sniklas       /* Get a pointer to the name of this library.  */
570e93f7393Sniklas       status = target_read_memory (addr, buf, 4);
571e93f7393Sniklas       if (status != 0)
572e93f7393Sniklas 	goto err;
573e93f7393Sniklas 
574e93f7393Sniklas       name_addr = extract_unsigned_integer (buf, 4);
575e93f7393Sniklas       name_len = 0;
576e93f7393Sniklas       while (1)
577e93f7393Sniklas 	{
578e93f7393Sniklas 	  target_read_memory (name_addr + name_len, buf, 1);
579e93f7393Sniklas 	  if (status != 0)
580e93f7393Sniklas 	    goto err;
581e93f7393Sniklas 
582e93f7393Sniklas 	  name_len++;
583e93f7393Sniklas 	  if (*buf == '\0')
584e93f7393Sniklas 	    break;
585e93f7393Sniklas 	}
586e93f7393Sniklas       name = alloca (name_len);
587e93f7393Sniklas       status = target_read_memory (name_addr, name, name_len);
588e93f7393Sniklas       if (status != 0)
589e93f7393Sniklas 	goto err;
590e93f7393Sniklas 
591e93f7393Sniklas       /* See if we've already loaded something with this name.  */
592e93f7393Sniklas       while (so_list)
593e93f7393Sniklas 	{
594e93f7393Sniklas 	  if (!strcmp (so_list->som_solib.name, name))
595e93f7393Sniklas 	    break;
596e93f7393Sniklas 	  so_list = so_list->next;
597e93f7393Sniklas 	}
598e93f7393Sniklas 
599e93f7393Sniklas       /* See if the file exists.  If not, give a warning, but don't
600e93f7393Sniklas          die.  */
601e93f7393Sniklas       status = stat (name, &statbuf);
602e93f7393Sniklas       if (status == -1)
603e93f7393Sniklas 	{
604e93f7393Sniklas 	  warning ("Can't find file %s referenced in dld_list.", name);
605e93f7393Sniklas 
606e93f7393Sniklas 	  status = target_read_memory (addr + 36, buf, 4);
607e93f7393Sniklas 	  if (status != 0)
608e93f7393Sniklas 	    goto err;
609e93f7393Sniklas 
610e93f7393Sniklas 	  addr = (CORE_ADDR) extract_unsigned_integer (buf, 4);
611e93f7393Sniklas 	  continue;
612e93f7393Sniklas 	}
613e93f7393Sniklas 
614e93f7393Sniklas       /* If we've already loaded this one or it's the main program, skip it.  */
615b725ae77Skettenis       is_main_program = (strcmp (name, symfile_objfile->name) == 0);
616b725ae77Skettenis       if (so_list || is_main_program)
617e93f7393Sniklas 	{
618b725ae77Skettenis 	  /* This is the "next" pointer in the strcuture.
619b725ae77Skettenis 	   */
620e93f7393Sniklas 	  status = target_read_memory (addr + 36, buf, 4);
621e93f7393Sniklas 	  if (status != 0)
622e93f7393Sniklas 	    goto err;
623e93f7393Sniklas 
624e93f7393Sniklas 	  addr = (CORE_ADDR) extract_unsigned_integer (buf, 4);
625b725ae77Skettenis 
626b725ae77Skettenis 	  /* Record the main program's symbol table size. */
627b725ae77Skettenis 	  if (is_main_program && !so_list)
628b725ae77Skettenis 	    {
629b725ae77Skettenis 	      st_size = som_solib_sizeof_symbol_table (name);
630b725ae77Skettenis 	      som_solib_total_st_size += st_size;
631b725ae77Skettenis 	    }
632b725ae77Skettenis 
633b725ae77Skettenis 	  /* Was this a shlib that we noted but didn't load the symbols for?
634b725ae77Skettenis 	     If so, were we invoked this time from the command-line, via
635b725ae77Skettenis 	     a 'sharedlibrary' or 'add-symbol-file' command?  If yes to
636b725ae77Skettenis 	     both, we'd better load the symbols this time.
637b725ae77Skettenis 	   */
638b725ae77Skettenis 	  if (from_tty && so_list && !is_main_program && (so_list->objfile == NULL))
639b725ae77Skettenis 	    som_solib_load_symbols (so_list,
640b725ae77Skettenis 				    name,
641b725ae77Skettenis 				    from_tty,
642b725ae77Skettenis 				    so_list->som_solib.text_addr,
643b725ae77Skettenis 				    target);
644b725ae77Skettenis 
645e93f7393Sniklas 	  continue;
646e93f7393Sniklas 	}
647e93f7393Sniklas 
648e93f7393Sniklas       name = obsavestring (name, name_len - 1,
649b725ae77Skettenis 			   &symfile_objfile->objfile_obstack);
650e93f7393Sniklas 
651e93f7393Sniklas       status = target_read_memory (addr + 8, buf, 4);
652e93f7393Sniklas       if (status != 0)
653e93f7393Sniklas 	goto err;
654e93f7393Sniklas 
655e93f7393Sniklas       text_addr = extract_unsigned_integer (buf, 4);
656e93f7393Sniklas 
657e93f7393Sniklas       new_so = (struct so_list *) xmalloc (sizeof (struct so_list));
658e93f7393Sniklas       memset ((char *) new_so, 0, sizeof (struct so_list));
659e93f7393Sniklas       if (so_list_head == NULL)
660e93f7393Sniklas 	{
661e93f7393Sniklas 	  so_list_head = new_so;
662e93f7393Sniklas 	  so_list_tail = new_so;
663e93f7393Sniklas 	}
664e93f7393Sniklas       else
665e93f7393Sniklas 	{
666e93f7393Sniklas 	  so_list_tail->next = new_so;
667e93f7393Sniklas 	  so_list_tail = new_so;
668e93f7393Sniklas 	}
669e93f7393Sniklas 
670b725ae77Skettenis       /* Fill in all the entries in GDB's shared library list.
671b725ae77Skettenis        */
672b725ae77Skettenis 
673b725ae77Skettenis       new_so->solib_addr = addr;
674e93f7393Sniklas       new_so->som_solib.name = name;
675e93f7393Sniklas       status = target_read_memory (addr + 4, buf, 4);
676e93f7393Sniklas       if (status != 0)
677e93f7393Sniklas 	goto err;
678e93f7393Sniklas 
679e93f7393Sniklas       new_so->som_solib.struct_version = extract_unsigned_integer (buf + 3, 1);
680e93f7393Sniklas       new_so->som_solib.bind_mode = extract_unsigned_integer (buf + 2, 1);
681b725ae77Skettenis       /* Following is "high water mark", highest version number
682b725ae77Skettenis        * seen, rather than plain version number.
683b725ae77Skettenis        */
684e93f7393Sniklas       new_so->som_solib.library_version = extract_unsigned_integer (buf, 2);
685e93f7393Sniklas       new_so->som_solib.text_addr = text_addr;
686e93f7393Sniklas 
687b725ae77Skettenis       /* Q: What about longword at "addr + 8"?
688b725ae77Skettenis        * A: It's read above, out of order, into "text_addr".
689b725ae77Skettenis        */
690b725ae77Skettenis 
691e93f7393Sniklas       status = target_read_memory (addr + 12, buf, 4);
692e93f7393Sniklas       if (status != 0)
693e93f7393Sniklas 	goto err;
694e93f7393Sniklas 
695e93f7393Sniklas       new_so->som_solib.text_link_addr = extract_unsigned_integer (buf, 4);
696e93f7393Sniklas 
697e93f7393Sniklas       status = target_read_memory (addr + 16, buf, 4);
698e93f7393Sniklas       if (status != 0)
699e93f7393Sniklas 	goto err;
700e93f7393Sniklas 
701e93f7393Sniklas       new_so->som_solib.text_end = extract_unsigned_integer (buf, 4);
702e93f7393Sniklas 
703e93f7393Sniklas       status = target_read_memory (addr + 20, buf, 4);
704e93f7393Sniklas       if (status != 0)
705e93f7393Sniklas 	goto err;
706e93f7393Sniklas 
707e93f7393Sniklas       new_so->som_solib.data_start = extract_unsigned_integer (buf, 4);
708e93f7393Sniklas 
709e93f7393Sniklas       status = target_read_memory (addr + 24, buf, 4);
710e93f7393Sniklas       if (status != 0)
711e93f7393Sniklas 	goto err;
712e93f7393Sniklas 
713e93f7393Sniklas       new_so->som_solib.bss_start = extract_unsigned_integer (buf, 4);
714e93f7393Sniklas 
715e93f7393Sniklas       status = target_read_memory (addr + 28, buf, 4);
716e93f7393Sniklas       if (status != 0)
717e93f7393Sniklas 	goto err;
718e93f7393Sniklas 
719e93f7393Sniklas       new_so->som_solib.data_end = extract_unsigned_integer (buf, 4);
720e93f7393Sniklas 
721e93f7393Sniklas       status = target_read_memory (addr + 32, buf, 4);
722e93f7393Sniklas       if (status != 0)
723e93f7393Sniklas 	goto err;
724e93f7393Sniklas 
725e93f7393Sniklas       new_so->som_solib.got_value = extract_unsigned_integer (buf, 4);
726e93f7393Sniklas 
727e93f7393Sniklas       status = target_read_memory (addr + 36, buf, 4);
728e93f7393Sniklas       if (status != 0)
729e93f7393Sniklas 	goto err;
730e93f7393Sniklas 
731b725ae77Skettenis       /* FIXME: cagney/2003-02-01: I think som_solib.next should be a
732b725ae77Skettenis          CORE_ADDR.  */
733b725ae77Skettenis       new_so->som_solib.next =
734b725ae77Skettenis 	hpux_address_to_host_pointer_hack (extract_unsigned_integer (buf, 4));
735b725ae77Skettenis 
736b725ae77Skettenis       /* Note that we don't re-set "addr" to the next pointer
737b725ae77Skettenis        * until after we've read the trailing data.
738b725ae77Skettenis        */
739b725ae77Skettenis 
740b725ae77Skettenis       status = target_read_memory (addr + 40, buf, 4);
741b725ae77Skettenis       new_so->som_solib.tsd_start_addr = extract_unsigned_integer (buf, 4);
742b725ae77Skettenis       if (status != 0)
743b725ae77Skettenis 	goto err;
744b725ae77Skettenis 
745b725ae77Skettenis       /* Now indirect via that value!
746b725ae77Skettenis        */
747b725ae77Skettenis       status = target_read_memory (new_so->som_solib.tsd_start_addr, buf, 4);
748b725ae77Skettenis       new_so->som_solib.tsd_start_addr = extract_unsigned_integer (buf, 4);
749b725ae77Skettenis       if (status != 0)
750b725ae77Skettenis 	goto err;
751b725ae77Skettenis #ifdef SOLIB_DEBUG
752b725ae77Skettenis       printf ("\n+ library \"%s\" is described at 0x%x\n", name, addr);
753b725ae77Skettenis       printf ("  'version' is %d\n", new_so->som_solib.struct_version);
754b725ae77Skettenis       printf ("  'bind_mode' is %d\n", new_so->som_solib.bind_mode);
755b725ae77Skettenis       printf ("  'library_version' is %d\n", new_so->som_solib.library_version);
756b725ae77Skettenis       printf ("  'text_addr' is 0x%x\n", new_so->som_solib.text_addr);
757b725ae77Skettenis       printf ("  'text_link_addr' is 0x%x\n", new_so->som_solib.text_link_addr);
758b725ae77Skettenis       printf ("  'text_end' is 0x%x\n", new_so->som_solib.text_end);
759b725ae77Skettenis       printf ("  'data_start' is 0x%x\n", new_so->som_solib.data_start);
760b725ae77Skettenis       printf ("  'bss_start' is 0x%x\n", new_so->som_solib.bss_start);
761b725ae77Skettenis       printf ("  'data_end' is 0x%x\n", new_so->som_solib.data_end);
762b725ae77Skettenis       printf ("  'got_value' is %x\n", new_so->som_solib.got_value);
763b725ae77Skettenis       printf ("  'next' is 0x%x\n", new_so->som_solib.next);
764b725ae77Skettenis       printf ("  'tsd_start_addr' is 0x%x\n", new_so->som_solib.tsd_start_addr);
765b725ae77Skettenis #endif
766b725ae77Skettenis 
767b725ae77Skettenis       /* Go on to the next shared library descriptor.
768b725ae77Skettenis        */
769e93f7393Sniklas       addr = (CORE_ADDR) new_so->som_solib.next;
770e93f7393Sniklas 
771e93f7393Sniklas 
772b725ae77Skettenis 
773b725ae77Skettenis       /* At this point, we have essentially hooked the shlib into the
774b725ae77Skettenis          "info share" command.  However, we haven't yet loaded its
775b725ae77Skettenis          symbol table.  We must now decide whether we ought to, i.e.,
776b725ae77Skettenis          whether doing so would exceed the symbol table size threshold.
777b725ae77Skettenis 
778b725ae77Skettenis          If the threshold has just now been exceeded, then we'll issue
779b725ae77Skettenis          a warning message (which explains how to load symbols manually,
780b725ae77Skettenis          if the user so desires).
781b725ae77Skettenis 
782b725ae77Skettenis          If the threshold has just now or previously been exceeded,
783b725ae77Skettenis          we'll just add the shlib to the list of object files, but won't
784b725ae77Skettenis          actually load its symbols.  (This is more useful than it might
785b725ae77Skettenis          sound, for it allows us to e.g., still load and use the shlibs'
786b725ae77Skettenis          unwind information for stack tracebacks.)
787b725ae77Skettenis        */
788b725ae77Skettenis 
789b725ae77Skettenis       /* Note that we DON'T want to preclude the user from using the
790b725ae77Skettenis          add-symbol-file command!  Thus, we only worry about the threshold
791b725ae77Skettenis          when we're invoked for other reasons.
792b725ae77Skettenis        */
793b725ae77Skettenis       st_size = som_solib_sizeof_symbol_table (name);
794b725ae77Skettenis       som_solib_st_size_threshold_exceeded =
795b725ae77Skettenis 	!from_tty &&
796b725ae77Skettenis 	auto_solib_limit > 0 &&
797b725ae77Skettenis 	readsyms &&
798b725ae77Skettenis 	((st_size + som_solib_total_st_size) > (auto_solib_limit * (LONGEST) (1024 * 1024)));
799b725ae77Skettenis 
800b725ae77Skettenis       if (som_solib_st_size_threshold_exceeded)
801e93f7393Sniklas 	{
802b725ae77Skettenis 	  if (!threshold_warning_given)
803b725ae77Skettenis 	    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");
804b725ae77Skettenis 	  threshold_warning_given = 1;
805b725ae77Skettenis 
806b725ae77Skettenis 	  /* We'll still make note of this shlib, even if we don't
807b725ae77Skettenis 	     read its symbols.  This allows us to use its unwind
808b725ae77Skettenis 	     information well enough to know how to e.g., correctly
809b725ae77Skettenis 	     do a traceback from a PC within the shlib, even if we
810b725ae77Skettenis 	     can't symbolize those PCs...
811b725ae77Skettenis 	   */
812b725ae77Skettenis 	  som_solib_add_solib_objfile (new_so, name, from_tty, text_addr);
813b725ae77Skettenis 	  continue;
814e93f7393Sniklas 	}
815e93f7393Sniklas 
816b725ae77Skettenis       som_solib_total_st_size += st_size;
817b725ae77Skettenis 
818b725ae77Skettenis       /* This fills in new_so->objfile, among others. */
819b725ae77Skettenis       som_solib_load_symbols (new_so, name, from_tty, text_addr, target);
820e93f7393Sniklas     }
821e93f7393Sniklas 
822b725ae77Skettenis #ifdef SOLIB_DEBUG
823b725ae77Skettenis   printf ("--Done reading shared library data\n");
824b725ae77Skettenis #endif
825e93f7393Sniklas 
826e93f7393Sniklas   /* Getting new symbols may change our opinion about what is
827e93f7393Sniklas      frameless.  */
828e93f7393Sniklas   reinit_frame_cache ();
829e93f7393Sniklas   return;
830e93f7393Sniklas 
831e93f7393Sniklas old_dld:
832e93f7393Sniklas   error ("Debugging dynamic executables loaded via the hpux8 dld.sl is not supported.\n");
833e93f7393Sniklas   return;
834e93f7393Sniklas 
835e93f7393Sniklas err:
836e93f7393Sniklas   error ("Error while reading dynamic library list.\n");
837e93f7393Sniklas   return;
838e93f7393Sniklas }
839e93f7393Sniklas 
840e93f7393Sniklas 
841e93f7393Sniklas /* This hook gets called just before the first instruction in the
842e93f7393Sniklas    inferior process is executed.
843e93f7393Sniklas 
844e93f7393Sniklas    This is our opportunity to set magic flags in the inferior so
845e93f7393Sniklas    that GDB can be notified when a shared library is mapped in and
846e93f7393Sniklas    to tell the dynamic linker that a private copy of the library is
847e93f7393Sniklas    needed (so GDB can set breakpoints in the library).
848e93f7393Sniklas 
849e93f7393Sniklas    __dld_flags is the location of the magic flags; as of this implementation
850e93f7393Sniklas    there are 3 flags of interest:
851e93f7393Sniklas 
852e93f7393Sniklas    bit 0 when set indicates that private copies of the libraries are needed
853e93f7393Sniklas    bit 1 when set indicates that the callback hook routine is valid
854e93f7393Sniklas    bit 2 when set indicates that the dynamic linker should maintain the
855e93f7393Sniklas    __dld_list structure when loading/unloading libraries.
856e93f7393Sniklas 
857e93f7393Sniklas    Note that shared libraries are not mapped in at this time, so we have
858e93f7393Sniklas    run the inferior until the libraries are mapped in.  Typically this
859e93f7393Sniklas    means running until the "_start" is called.  */
860e93f7393Sniklas 
861e93f7393Sniklas void
som_solib_create_inferior_hook(void)862b725ae77Skettenis som_solib_create_inferior_hook (void)
863e93f7393Sniklas {
864e93f7393Sniklas   struct minimal_symbol *msymbol;
865e93f7393Sniklas   unsigned int dld_flags, status, have_endo;
866e93f7393Sniklas   asection *shlib_info;
867e93f7393Sniklas   char buf[4];
868e93f7393Sniklas   struct objfile *objfile;
869e93f7393Sniklas   CORE_ADDR anaddr;
870e93f7393Sniklas 
871e93f7393Sniklas   /* First, remove all the solib event breakpoints.  Their addresses
872e93f7393Sniklas      may have changed since the last time we ran the program.  */
873e93f7393Sniklas   remove_solib_event_breakpoints ();
874e93f7393Sniklas 
875e93f7393Sniklas   if (symfile_objfile == NULL)
876e93f7393Sniklas     return;
877e93f7393Sniklas 
878e93f7393Sniklas   /* First see if the objfile was dynamically linked.  */
879e93f7393Sniklas   shlib_info = bfd_get_section_by_name (symfile_objfile->obfd, "$SHLIB_INFO$");
880e93f7393Sniklas   if (!shlib_info)
881e93f7393Sniklas     return;
882e93f7393Sniklas 
883e93f7393Sniklas   /* It's got a $SHLIB_INFO$ section, make sure it's not empty.  */
884e93f7393Sniklas   if (bfd_section_size (symfile_objfile->obfd, shlib_info) == 0)
885e93f7393Sniklas     return;
886e93f7393Sniklas 
887e93f7393Sniklas   have_endo = 0;
888b725ae77Skettenis   /* Slam the pid of the process into __d_pid.
889e93f7393Sniklas 
890b725ae77Skettenis      We used to warn when this failed, but that warning is only useful
891b725ae77Skettenis      on very old HP systems (hpux9 and older).  The warnings are an
892b725ae77Skettenis      annoyance to users of modern systems and foul up the testsuite as
893b725ae77Skettenis      well.  As a result, the warnings have been disabled.  */
894e93f7393Sniklas   msymbol = lookup_minimal_symbol ("__d_pid", NULL, symfile_objfile);
895b725ae77Skettenis   if (msymbol == NULL)
896b725ae77Skettenis     goto keep_going;
897b725ae77Skettenis 
898e93f7393Sniklas   anaddr = SYMBOL_VALUE_ADDRESS (msymbol);
899b725ae77Skettenis   store_unsigned_integer (buf, 4, PIDGET (inferior_ptid));
900e93f7393Sniklas   status = target_write_memory (anaddr, buf, 4);
901e93f7393Sniklas   if (status != 0)
902e93f7393Sniklas     {
903e93f7393Sniklas       warning ("Unable to write __d_pid");
904b725ae77Skettenis       warning ("Suggest linking with /opt/langtools/lib/end.o.");
905b725ae77Skettenis       warning ("GDB will be unable to track shl_load/shl_unload calls");
906e93f7393Sniklas       goto keep_going;
907e93f7393Sniklas     }
908e93f7393Sniklas 
909e93f7393Sniklas   /* Get the value of _DLD_HOOK (an export stub) and put it in __dld_hook;
910e93f7393Sniklas      This will force the dynamic linker to call __d_trap when significant
911b725ae77Skettenis      events occur.
912b725ae77Skettenis 
913b725ae77Skettenis      Note that the above is the pre-HP-UX 9.0 behaviour.  At 9.0 and above,
914b725ae77Skettenis      the dld provides an export stub named "__d_trap" as well as the
915b725ae77Skettenis      function named "__d_trap" itself, but doesn't provide "_DLD_HOOK".
916b725ae77Skettenis      We'll look first for the old flavor and then the new.
917b725ae77Skettenis    */
918e93f7393Sniklas   msymbol = lookup_minimal_symbol ("_DLD_HOOK", NULL, symfile_objfile);
919e93f7393Sniklas   if (msymbol == NULL)
920b725ae77Skettenis     msymbol = lookup_minimal_symbol ("__d_trap", NULL, symfile_objfile);
921b725ae77Skettenis   if (msymbol == NULL)
922e93f7393Sniklas     {
923e93f7393Sniklas       warning ("Unable to find _DLD_HOOK symbol in object file.");
924b725ae77Skettenis       warning ("Suggest linking with /opt/langtools/lib/end.o.");
925e93f7393Sniklas       warning ("GDB will be unable to track shl_load/shl_unload calls");
926e93f7393Sniklas       goto keep_going;
927e93f7393Sniklas     }
928e93f7393Sniklas   anaddr = SYMBOL_VALUE_ADDRESS (msymbol);
929b725ae77Skettenis   dld_cache.hook.address = anaddr;
930e93f7393Sniklas 
931e93f7393Sniklas   /* Grrr, this might not be an export symbol!  We have to find the
932e93f7393Sniklas      export stub.  */
933e93f7393Sniklas   ALL_OBJFILES (objfile)
934e93f7393Sniklas   {
935b725ae77Skettenis     struct unwind_table_entry *u;
936b725ae77Skettenis     struct minimal_symbol *msymbol2;
937e93f7393Sniklas 
938e93f7393Sniklas     /* What a crock.  */
939b725ae77Skettenis     msymbol2 = lookup_minimal_symbol_solib_trampoline (DEPRECATED_SYMBOL_NAME (msymbol),
940b725ae77Skettenis 						       objfile);
941e93f7393Sniklas     /* Found a symbol with the right name.  */
942b725ae77Skettenis     if (msymbol2)
943e93f7393Sniklas       {
944e93f7393Sniklas 	struct unwind_table_entry *u;
945e93f7393Sniklas 	/* It must be a shared library trampoline.  */
946b725ae77Skettenis 	if (SYMBOL_TYPE (msymbol2) != mst_solib_trampoline)
947e93f7393Sniklas 	  continue;
948e93f7393Sniklas 
949e93f7393Sniklas 	/* It must also be an export stub.  */
950b725ae77Skettenis 	u = find_unwind_entry (SYMBOL_VALUE (msymbol2));
951b725ae77Skettenis 	if (!u || u->stub_unwind.stub_type != EXPORT)
952e93f7393Sniklas 	  continue;
953e93f7393Sniklas 
954e93f7393Sniklas 	/* OK.  Looks like the correct import stub.  */
955b725ae77Skettenis 	anaddr = SYMBOL_VALUE (msymbol2);
956b725ae77Skettenis 	dld_cache.hook_stub.address = anaddr;
957e93f7393Sniklas       }
958e93f7393Sniklas   }
959e93f7393Sniklas   store_unsigned_integer (buf, 4, anaddr);
960e93f7393Sniklas 
961e93f7393Sniklas   msymbol = lookup_minimal_symbol ("__dld_hook", NULL, symfile_objfile);
962e93f7393Sniklas   if (msymbol == NULL)
963e93f7393Sniklas     {
964e93f7393Sniklas       warning ("Unable to find __dld_hook symbol in object file.");
965b725ae77Skettenis       warning ("Suggest linking with /opt/langtools/lib/end.o.");
966e93f7393Sniklas       warning ("GDB will be unable to track shl_load/shl_unload calls");
967e93f7393Sniklas       goto keep_going;
968e93f7393Sniklas     }
969e93f7393Sniklas   anaddr = SYMBOL_VALUE_ADDRESS (msymbol);
970e93f7393Sniklas   status = target_write_memory (anaddr, buf, 4);
971e93f7393Sniklas 
972e93f7393Sniklas   /* Now set a shlib_event breakpoint at __d_trap so we can track
973e93f7393Sniklas      significant shared library events.  */
974e93f7393Sniklas   msymbol = lookup_minimal_symbol ("__d_trap", NULL, symfile_objfile);
975e93f7393Sniklas   if (msymbol == NULL)
976e93f7393Sniklas     {
977e93f7393Sniklas       warning ("Unable to find __dld_d_trap symbol in object file.");
978b725ae77Skettenis       warning ("Suggest linking with /opt/langtools/lib/end.o.");
979e93f7393Sniklas       warning ("GDB will be unable to track shl_load/shl_unload calls");
980e93f7393Sniklas       goto keep_going;
981e93f7393Sniklas     }
982e93f7393Sniklas   create_solib_event_breakpoint (SYMBOL_VALUE_ADDRESS (msymbol));
983e93f7393Sniklas 
984e93f7393Sniklas   /* We have all the support usually found in end.o, so we can track
985e93f7393Sniklas      shl_load and shl_unload calls.  */
986e93f7393Sniklas   have_endo = 1;
987e93f7393Sniklas 
988e93f7393Sniklas keep_going:
989e93f7393Sniklas 
990e93f7393Sniklas   /* Get the address of __dld_flags, if no such symbol exists, then we can
991e93f7393Sniklas      not debug the shared code.  */
992e93f7393Sniklas   msymbol = lookup_minimal_symbol ("__dld_flags", NULL, NULL);
993e93f7393Sniklas   if (msymbol == NULL)
994e93f7393Sniklas     {
995e93f7393Sniklas       error ("Unable to find __dld_flags symbol in object file.\n");
996e93f7393Sniklas     }
997e93f7393Sniklas 
998e93f7393Sniklas   anaddr = SYMBOL_VALUE_ADDRESS (msymbol);
999b725ae77Skettenis 
1000e93f7393Sniklas   /* Read the current contents.  */
1001e93f7393Sniklas   status = target_read_memory (anaddr, buf, 4);
1002e93f7393Sniklas   if (status != 0)
1003e93f7393Sniklas     {
1004e93f7393Sniklas       error ("Unable to read __dld_flags\n");
1005e93f7393Sniklas     }
1006e93f7393Sniklas   dld_flags = extract_unsigned_integer (buf, 4);
1007e93f7393Sniklas 
1008e93f7393Sniklas   /* Turn on the flags we care about.  */
1009b725ae77Skettenis   dld_flags |= DLD_FLAGS_MAPPRIVATE;
1010b725ae77Skettenis   if (have_endo)
1011b725ae77Skettenis     dld_flags |= DLD_FLAGS_HOOKVALID;
1012e93f7393Sniklas   store_unsigned_integer (buf, 4, dld_flags);
1013e93f7393Sniklas   status = target_write_memory (anaddr, buf, 4);
1014e93f7393Sniklas   if (status != 0)
1015e93f7393Sniklas     {
1016e93f7393Sniklas       error ("Unable to write __dld_flags\n");
1017e93f7393Sniklas     }
1018e93f7393Sniklas 
1019e93f7393Sniklas   /* Now find the address of _start and set a breakpoint there.
1020e93f7393Sniklas      We still need this code for two reasons:
1021e93f7393Sniklas 
1022b725ae77Skettenis      * Not all sites have /opt/langtools/lib/end.o, so it's not always
1023e93f7393Sniklas      possible to track the dynamic linker's events.
1024e93f7393Sniklas 
1025e93f7393Sniklas      * At this time no events are triggered for shared libraries
1026e93f7393Sniklas      loaded at startup time (what a crock).  */
1027e93f7393Sniklas 
1028e93f7393Sniklas   msymbol = lookup_minimal_symbol ("_start", NULL, symfile_objfile);
1029e93f7393Sniklas   if (msymbol == NULL)
1030e93f7393Sniklas     {
1031e93f7393Sniklas       error ("Unable to find _start symbol in object file.\n");
1032e93f7393Sniklas     }
1033e93f7393Sniklas 
1034e93f7393Sniklas   anaddr = SYMBOL_VALUE_ADDRESS (msymbol);
1035e93f7393Sniklas 
1036e93f7393Sniklas   /* Make the breakpoint at "_start" a shared library event breakpoint.  */
1037e93f7393Sniklas   create_solib_event_breakpoint (anaddr);
1038e93f7393Sniklas 
1039e93f7393Sniklas   /* Wipe out all knowledge of old shared libraries since their
1040e93f7393Sniklas      mapping can change from one exec to another!  */
1041e93f7393Sniklas   while (so_list_head)
1042e93f7393Sniklas     {
1043e93f7393Sniklas       struct so_list *temp;
1044e93f7393Sniklas 
1045e93f7393Sniklas       temp = so_list_head;
1046b725ae77Skettenis       xfree (so_list_head);
1047e93f7393Sniklas       so_list_head = temp->next;
1048e93f7393Sniklas     }
1049e93f7393Sniklas   clear_symtab_users ();
1050e93f7393Sniklas }
1051e93f7393Sniklas 
1052b725ae77Skettenis /* This operation removes the "hook" between GDB and the dynamic linker,
1053b725ae77Skettenis    which causes the dld to notify GDB of shared library events.
1054b725ae77Skettenis 
1055b725ae77Skettenis    After this operation completes, the dld will no longer notify GDB of
1056b725ae77Skettenis    shared library events.  To resume notifications, GDB must call
1057b725ae77Skettenis    som_solib_create_inferior_hook.
1058b725ae77Skettenis 
1059b725ae77Skettenis    This operation does not remove any knowledge of shared libraries which
1060b725ae77Skettenis    GDB may already have been notified of.
1061b725ae77Skettenis  */
1062b725ae77Skettenis void
som_solib_remove_inferior_hook(int pid)1063b725ae77Skettenis som_solib_remove_inferior_hook (int pid)
1064b725ae77Skettenis {
1065b725ae77Skettenis   CORE_ADDR addr;
1066b725ae77Skettenis   struct minimal_symbol *msymbol;
1067b725ae77Skettenis   int status;
1068*63addd46Skettenis   char dld_flags_buffer[4];
1069b725ae77Skettenis   unsigned int dld_flags_value;
1070b725ae77Skettenis   struct cleanup *old_cleanups = save_inferior_ptid ();
1071b725ae77Skettenis 
1072b725ae77Skettenis   /* Ensure that we're really operating on the specified process. */
1073b725ae77Skettenis   inferior_ptid = pid_to_ptid (pid);
1074b725ae77Skettenis 
1075b725ae77Skettenis   /* We won't bother to remove the solib breakpoints from this process.
1076b725ae77Skettenis 
1077b725ae77Skettenis      In fact, on PA64 the breakpoint is hard-coded into the dld callback,
1078b725ae77Skettenis      and thus we're not supposed to remove it.
1079b725ae77Skettenis 
1080b725ae77Skettenis      Rather, we'll merely clear the dld_flags bit that enables callbacks.
1081b725ae77Skettenis    */
1082b725ae77Skettenis   msymbol = lookup_minimal_symbol ("__dld_flags", NULL, NULL);
1083b725ae77Skettenis 
1084b725ae77Skettenis   addr = SYMBOL_VALUE_ADDRESS (msymbol);
1085*63addd46Skettenis   status = target_read_memory (addr, dld_flags_buffer, 4);
1086b725ae77Skettenis 
1087*63addd46Skettenis   dld_flags_value = extract_unsigned_integer (dld_flags_buffer, 4);
1088b725ae77Skettenis 
1089b725ae77Skettenis   dld_flags_value &= ~DLD_FLAGS_HOOKVALID;
1090*63addd46Skettenis   store_unsigned_integer (dld_flags_buffer, 4, dld_flags_value);
1091*63addd46Skettenis   status = target_write_memory (addr, dld_flags_buffer, 4);
1092b725ae77Skettenis 
1093b725ae77Skettenis   do_cleanups (old_cleanups);
1094b725ae77Skettenis }
1095b725ae77Skettenis 
1096b725ae77Skettenis 
1097b725ae77Skettenis /* This function creates a breakpoint on the dynamic linker hook, which
1098b725ae77Skettenis    is called when e.g., a shl_load or shl_unload call is made.  This
1099b725ae77Skettenis    breakpoint will only trigger when a shl_load call is made.
1100b725ae77Skettenis 
1101b725ae77Skettenis    If filename is NULL, then loads of any dll will be caught.  Else,
1102b725ae77Skettenis    only loads of the file whose pathname is the string contained by
1103b725ae77Skettenis    filename will be caught.
1104b725ae77Skettenis 
1105b725ae77Skettenis    Undefined behaviour is guaranteed if this function is called before
1106b725ae77Skettenis    som_solib_create_inferior_hook.
1107b725ae77Skettenis  */
1108b725ae77Skettenis void
som_solib_create_catch_load_hook(int pid,int tempflag,char * filename,char * cond_string)1109b725ae77Skettenis som_solib_create_catch_load_hook (int pid, int tempflag, char *filename,
1110b725ae77Skettenis 				  char *cond_string)
1111b725ae77Skettenis {
1112b725ae77Skettenis   create_solib_load_event_breakpoint ("__d_trap", tempflag, filename, cond_string);
1113b725ae77Skettenis }
1114b725ae77Skettenis 
1115b725ae77Skettenis /* This function creates a breakpoint on the dynamic linker hook, which
1116b725ae77Skettenis    is called when e.g., a shl_load or shl_unload call is made.  This
1117b725ae77Skettenis    breakpoint will only trigger when a shl_unload call is made.
1118b725ae77Skettenis 
1119b725ae77Skettenis    If filename is NULL, then unloads of any dll will be caught.  Else,
1120b725ae77Skettenis    only unloads of the file whose pathname is the string contained by
1121b725ae77Skettenis    filename will be caught.
1122b725ae77Skettenis 
1123b725ae77Skettenis    Undefined behaviour is guaranteed if this function is called before
1124b725ae77Skettenis    som_solib_create_inferior_hook.
1125b725ae77Skettenis  */
1126b725ae77Skettenis void
som_solib_create_catch_unload_hook(int pid,int tempflag,char * filename,char * cond_string)1127b725ae77Skettenis som_solib_create_catch_unload_hook (int pid, int tempflag, char *filename,
1128b725ae77Skettenis 				    char *cond_string)
1129b725ae77Skettenis {
1130b725ae77Skettenis   create_solib_unload_event_breakpoint ("__d_trap", tempflag, filename, cond_string);
1131b725ae77Skettenis }
1132b725ae77Skettenis 
1133b725ae77Skettenis int
som_solib_have_load_event(int pid)1134b725ae77Skettenis som_solib_have_load_event (int pid)
1135b725ae77Skettenis {
1136b725ae77Skettenis   CORE_ADDR event_kind;
1137b725ae77Skettenis 
1138*63addd46Skettenis   event_kind = read_register (HPPA_ARG0_REGNUM);
1139b725ae77Skettenis   return (event_kind == SHL_LOAD);
1140b725ae77Skettenis }
1141b725ae77Skettenis 
1142b725ae77Skettenis int
som_solib_have_unload_event(int pid)1143b725ae77Skettenis som_solib_have_unload_event (int pid)
1144b725ae77Skettenis {
1145b725ae77Skettenis   CORE_ADDR event_kind;
1146b725ae77Skettenis 
1147*63addd46Skettenis   event_kind = read_register (HPPA_ARG0_REGNUM);
1148b725ae77Skettenis   return (event_kind == SHL_UNLOAD);
1149b725ae77Skettenis }
1150b725ae77Skettenis 
1151b725ae77Skettenis static char *
som_solib_library_pathname(int pid)1152b725ae77Skettenis som_solib_library_pathname (int pid)
1153b725ae77Skettenis {
1154b725ae77Skettenis   CORE_ADDR dll_handle_address;
1155b725ae77Skettenis   CORE_ADDR dll_pathname_address;
1156b725ae77Skettenis   struct som_solib_mapped_entry dll_descriptor;
1157b725ae77Skettenis   char *p;
1158b725ae77Skettenis   static char dll_pathname[1024];
1159b725ae77Skettenis 
1160b725ae77Skettenis   /* Read the descriptor of this newly-loaded library. */
1161*63addd46Skettenis   dll_handle_address = read_register (HPPA_ARG1_REGNUM);
1162b725ae77Skettenis   read_memory (dll_handle_address, (char *) &dll_descriptor, sizeof (dll_descriptor));
1163b725ae77Skettenis 
1164b725ae77Skettenis   /* We can find a pointer to the dll's pathname within the descriptor. */
1165b725ae77Skettenis   dll_pathname_address = (CORE_ADDR) dll_descriptor.name;
1166b725ae77Skettenis 
1167b725ae77Skettenis   /* Read the pathname, one byte at a time. */
1168b725ae77Skettenis   p = dll_pathname;
1169b725ae77Skettenis   for (;;)
1170b725ae77Skettenis     {
1171b725ae77Skettenis       char b;
1172b725ae77Skettenis       read_memory (dll_pathname_address++, (char *) &b, 1);
1173b725ae77Skettenis       *p++ = b;
1174b725ae77Skettenis       if (b == '\0')
1175b725ae77Skettenis 	break;
1176b725ae77Skettenis     }
1177b725ae77Skettenis 
1178b725ae77Skettenis   return dll_pathname;
1179b725ae77Skettenis }
1180b725ae77Skettenis 
1181b725ae77Skettenis char *
som_solib_loaded_library_pathname(int pid)1182b725ae77Skettenis som_solib_loaded_library_pathname (int pid)
1183b725ae77Skettenis {
1184b725ae77Skettenis   if (!som_solib_have_load_event (pid))
1185b725ae77Skettenis     error ("Must have a load event to use this query");
1186b725ae77Skettenis 
1187b725ae77Skettenis   return som_solib_library_pathname (pid);
1188b725ae77Skettenis }
1189b725ae77Skettenis 
1190b725ae77Skettenis char *
som_solib_unloaded_library_pathname(int pid)1191b725ae77Skettenis som_solib_unloaded_library_pathname (int pid)
1192b725ae77Skettenis {
1193b725ae77Skettenis   if (!som_solib_have_unload_event (pid))
1194b725ae77Skettenis     error ("Must have an unload event to use this query");
1195b725ae77Skettenis 
1196b725ae77Skettenis   return som_solib_library_pathname (pid);
1197b725ae77Skettenis }
1198b725ae77Skettenis 
1199b725ae77Skettenis static void
som_solib_desire_dynamic_linker_symbols(void)1200b725ae77Skettenis som_solib_desire_dynamic_linker_symbols (void)
1201b725ae77Skettenis {
1202b725ae77Skettenis   struct objfile *objfile;
1203b725ae77Skettenis   struct unwind_table_entry *u;
1204b725ae77Skettenis   struct minimal_symbol *dld_msymbol;
1205b725ae77Skettenis 
1206b725ae77Skettenis   /* Do we already know the value of these symbols?  If so, then
1207b725ae77Skettenis      we've no work to do.
1208b725ae77Skettenis 
1209b725ae77Skettenis      (If you add clauses to this test, be sure to likewise update the
1210b725ae77Skettenis      test within the loop.)
1211b725ae77Skettenis    */
1212b725ae77Skettenis   if (dld_cache.is_valid)
1213b725ae77Skettenis     return;
1214b725ae77Skettenis 
1215b725ae77Skettenis   ALL_OBJFILES (objfile)
1216b725ae77Skettenis   {
1217b725ae77Skettenis     dld_msymbol = lookup_minimal_symbol ("shl_load", NULL, objfile);
1218b725ae77Skettenis     if (dld_msymbol != NULL)
1219b725ae77Skettenis       {
1220b725ae77Skettenis 	dld_cache.load.address = SYMBOL_VALUE (dld_msymbol);
1221b725ae77Skettenis 	dld_cache.load.unwind = find_unwind_entry (dld_cache.load.address);
1222b725ae77Skettenis       }
1223b725ae77Skettenis 
1224b725ae77Skettenis     dld_msymbol = lookup_minimal_symbol_solib_trampoline ("shl_load",
1225b725ae77Skettenis 							  objfile);
1226b725ae77Skettenis     if (dld_msymbol != NULL)
1227b725ae77Skettenis       {
1228b725ae77Skettenis 	if (SYMBOL_TYPE (dld_msymbol) == mst_solib_trampoline)
1229b725ae77Skettenis 	  {
1230b725ae77Skettenis 	    u = find_unwind_entry (SYMBOL_VALUE (dld_msymbol));
1231b725ae77Skettenis 	    if ((u != NULL) && (u->stub_unwind.stub_type == EXPORT))
1232b725ae77Skettenis 	      {
1233b725ae77Skettenis 		dld_cache.load_stub.address = SYMBOL_VALUE (dld_msymbol);
1234b725ae77Skettenis 		dld_cache.load_stub.unwind = u;
1235b725ae77Skettenis 	      }
1236b725ae77Skettenis 	  }
1237b725ae77Skettenis       }
1238b725ae77Skettenis 
1239b725ae77Skettenis     dld_msymbol = lookup_minimal_symbol ("shl_unload", NULL, objfile);
1240b725ae77Skettenis     if (dld_msymbol != NULL)
1241b725ae77Skettenis       {
1242b725ae77Skettenis 	dld_cache.unload.address = SYMBOL_VALUE (dld_msymbol);
1243b725ae77Skettenis 	dld_cache.unload.unwind = find_unwind_entry (dld_cache.unload.address);
1244b725ae77Skettenis 
1245b725ae77Skettenis 	/* ??rehrauer: I'm not sure exactly what this is, but it appears
1246b725ae77Skettenis 	   that on some HPUX 10.x versions, there's two unwind regions to
1247b725ae77Skettenis 	   cover the body of "shl_unload", the second being 4 bytes past
1248b725ae77Skettenis 	   the end of the first.  This is a large hack to handle that
1249b725ae77Skettenis 	   case, but since I don't seem to have any legitimate way to
1250b725ae77Skettenis 	   look for this thing via the symbol table...
1251b725ae77Skettenis 	 */
1252b725ae77Skettenis 	if (dld_cache.unload.unwind != NULL)
1253b725ae77Skettenis 	  {
1254b725ae77Skettenis 	    u = find_unwind_entry (dld_cache.unload.unwind->region_end + 4);
1255b725ae77Skettenis 	    if (u != NULL)
1256b725ae77Skettenis 	      {
1257b725ae77Skettenis 		dld_cache.unload2.address = u->region_start;
1258b725ae77Skettenis 		dld_cache.unload2.unwind = u;
1259b725ae77Skettenis 	      }
1260b725ae77Skettenis 	  }
1261b725ae77Skettenis       }
1262b725ae77Skettenis 
1263b725ae77Skettenis     dld_msymbol = lookup_minimal_symbol_solib_trampoline ("shl_unload",
1264b725ae77Skettenis 							  objfile);
1265b725ae77Skettenis     if (dld_msymbol != NULL)
1266b725ae77Skettenis       {
1267b725ae77Skettenis 	if (SYMBOL_TYPE (dld_msymbol) == mst_solib_trampoline)
1268b725ae77Skettenis 	  {
1269b725ae77Skettenis 	    u = find_unwind_entry (SYMBOL_VALUE (dld_msymbol));
1270b725ae77Skettenis 	    if ((u != NULL) && (u->stub_unwind.stub_type == EXPORT))
1271b725ae77Skettenis 	      {
1272b725ae77Skettenis 		dld_cache.unload_stub.address = SYMBOL_VALUE (dld_msymbol);
1273b725ae77Skettenis 		dld_cache.unload_stub.unwind = u;
1274b725ae77Skettenis 	      }
1275b725ae77Skettenis 	  }
1276b725ae77Skettenis       }
1277b725ae77Skettenis 
1278b725ae77Skettenis     /* Did we find everything we were looking for?  If so, stop. */
1279b725ae77Skettenis     if ((dld_cache.load.address != 0)
1280b725ae77Skettenis 	&& (dld_cache.load_stub.address != 0)
1281b725ae77Skettenis 	&& (dld_cache.unload.address != 0)
1282b725ae77Skettenis 	&& (dld_cache.unload_stub.address != 0))
1283b725ae77Skettenis       {
1284b725ae77Skettenis 	dld_cache.is_valid = 1;
1285b725ae77Skettenis 	break;
1286b725ae77Skettenis       }
1287b725ae77Skettenis   }
1288b725ae77Skettenis 
1289b725ae77Skettenis   dld_cache.hook.unwind = find_unwind_entry (dld_cache.hook.address);
1290b725ae77Skettenis   dld_cache.hook_stub.unwind = find_unwind_entry (dld_cache.hook_stub.address);
1291b725ae77Skettenis 
1292b725ae77Skettenis   /* We're prepared not to find some of these symbols, which is why
1293b725ae77Skettenis      this function is a "desire" operation, and not a "require".
1294b725ae77Skettenis    */
1295b725ae77Skettenis }
1296b725ae77Skettenis 
1297b725ae77Skettenis int
som_solib_in_dynamic_linker(int pid,CORE_ADDR pc)1298b725ae77Skettenis som_solib_in_dynamic_linker (int pid, CORE_ADDR pc)
1299b725ae77Skettenis {
1300b725ae77Skettenis   struct unwind_table_entry *u_pc;
1301b725ae77Skettenis 
1302b725ae77Skettenis   /* Are we in the dld itself?
1303b725ae77Skettenis 
1304b725ae77Skettenis      ??rehrauer: Large hack -- We'll assume that any address in a
1305b725ae77Skettenis      shared text region is the dld's text.  This would obviously
1306b725ae77Skettenis      fall down if the user attached to a process, whose shlibs
1307b725ae77Skettenis      weren't mapped to a (writeable) private region.  However, in
1308b725ae77Skettenis      that case the debugger probably isn't able to set the fundamental
1309b725ae77Skettenis      breakpoint in the dld callback anyways, so this hack should be
1310b725ae77Skettenis      safe.
1311b725ae77Skettenis    */
1312b725ae77Skettenis   if ((pc & (CORE_ADDR) 0xc0000000) == (CORE_ADDR) 0xc0000000)
1313b725ae77Skettenis     return 1;
1314b725ae77Skettenis 
1315b725ae77Skettenis   /* Cache the address of some symbols that are part of the dynamic
1316b725ae77Skettenis      linker, if not already known.
1317b725ae77Skettenis    */
1318b725ae77Skettenis   som_solib_desire_dynamic_linker_symbols ();
1319b725ae77Skettenis 
1320b725ae77Skettenis   /* Are we in the dld callback?  Or its export stub? */
1321b725ae77Skettenis   u_pc = find_unwind_entry (pc);
1322b725ae77Skettenis   if (u_pc == NULL)
1323b725ae77Skettenis     return 0;
1324b725ae77Skettenis 
1325b725ae77Skettenis   if ((u_pc == dld_cache.hook.unwind) || (u_pc == dld_cache.hook_stub.unwind))
1326b725ae77Skettenis     return 1;
1327b725ae77Skettenis 
1328b725ae77Skettenis   /* Or the interface of the dld (i.e., "shl_load" or friends)? */
1329b725ae77Skettenis   if ((u_pc == dld_cache.load.unwind)
1330b725ae77Skettenis       || (u_pc == dld_cache.unload.unwind)
1331b725ae77Skettenis       || (u_pc == dld_cache.unload2.unwind)
1332b725ae77Skettenis       || (u_pc == dld_cache.load_stub.unwind)
1333b725ae77Skettenis       || (u_pc == dld_cache.unload_stub.unwind))
1334b725ae77Skettenis     return 1;
1335b725ae77Skettenis 
1336b725ae77Skettenis   /* Apparently this address isn't part of the dld's text. */
1337b725ae77Skettenis   return 0;
1338b725ae77Skettenis }
1339b725ae77Skettenis 
1340b725ae77Skettenis 
1341e93f7393Sniklas /* Return the GOT value for the shared library in which ADDR belongs.  If
1342e93f7393Sniklas    ADDR isn't in any known shared library, return zero.  */
1343e93f7393Sniklas 
1344e93f7393Sniklas CORE_ADDR
som_solib_get_got_by_pc(CORE_ADDR addr)1345b725ae77Skettenis som_solib_get_got_by_pc (CORE_ADDR addr)
1346e93f7393Sniklas {
1347e93f7393Sniklas   struct so_list *so_list = so_list_head;
1348e93f7393Sniklas   CORE_ADDR got_value = 0;
1349e93f7393Sniklas 
1350e93f7393Sniklas   while (so_list)
1351e93f7393Sniklas     {
1352e93f7393Sniklas       if (so_list->som_solib.text_addr <= addr
1353e93f7393Sniklas 	  && so_list->som_solib.text_end > addr)
1354e93f7393Sniklas 	{
1355e93f7393Sniklas 	  got_value = so_list->som_solib.got_value;
1356e93f7393Sniklas 	  break;
1357e93f7393Sniklas 	}
1358e93f7393Sniklas       so_list = so_list->next;
1359e93f7393Sniklas     }
1360e93f7393Sniklas   return got_value;
1361e93f7393Sniklas }
1362e93f7393Sniklas 
1363b725ae77Skettenis /*  elz:
1364b725ae77Skettenis    Return the address of the handle of the shared library
1365b725ae77Skettenis    in which ADDR belongs.  If
1366b725ae77Skettenis    ADDR isn't in any known shared library, return zero.  */
1367b725ae77Skettenis /* this function is used in hppa_fix_call_dummy in hppa-tdep.c */
1368b725ae77Skettenis 
1369b725ae77Skettenis CORE_ADDR
som_solib_get_solib_by_pc(CORE_ADDR addr)1370b725ae77Skettenis som_solib_get_solib_by_pc (CORE_ADDR addr)
1371b725ae77Skettenis {
1372b725ae77Skettenis   struct so_list *so_list = so_list_head;
1373b725ae77Skettenis 
1374b725ae77Skettenis   while (so_list)
1375b725ae77Skettenis     {
1376b725ae77Skettenis       if (so_list->som_solib.text_addr <= addr
1377b725ae77Skettenis 	  && so_list->som_solib.text_end > addr)
1378b725ae77Skettenis 	{
1379b725ae77Skettenis 	  break;
1380b725ae77Skettenis 	}
1381b725ae77Skettenis       so_list = so_list->next;
1382b725ae77Skettenis     }
1383b725ae77Skettenis   if (so_list)
1384b725ae77Skettenis     return so_list->solib_addr;
1385b725ae77Skettenis   else
1386b725ae77Skettenis     return 0;
1387b725ae77Skettenis }
1388b725ae77Skettenis 
1389b725ae77Skettenis 
1390e93f7393Sniklas int
som_solib_section_offsets(struct objfile * objfile,struct section_offsets * offsets)1391b725ae77Skettenis som_solib_section_offsets (struct objfile *objfile,
1392b725ae77Skettenis 			   struct section_offsets *offsets)
1393e93f7393Sniklas {
1394e93f7393Sniklas   struct so_list *so_list = so_list_head;
1395e93f7393Sniklas 
1396e93f7393Sniklas   while (so_list)
1397e93f7393Sniklas     {
1398e93f7393Sniklas       /* Oh what a pain!  We need the offsets before so_list->objfile
1399e93f7393Sniklas          is valid.  The BFDs will never match.  Make a best guess.  */
1400e93f7393Sniklas       if (strstr (objfile->name, so_list->som_solib.name))
1401e93f7393Sniklas 	{
1402e93f7393Sniklas 	  asection *private_section;
1403e93f7393Sniklas 
1404e93f7393Sniklas 	  /* The text offset is easy.  */
1405b725ae77Skettenis 	  offsets->offsets[SECT_OFF_TEXT (objfile)]
1406e93f7393Sniklas 	    = (so_list->som_solib.text_addr
1407e93f7393Sniklas 	       - so_list->som_solib.text_link_addr);
1408b725ae77Skettenis 	  offsets->offsets[SECT_OFF_RODATA (objfile)]
1409b725ae77Skettenis 	    = ANOFFSET (offsets, SECT_OFF_TEXT (objfile));
1410e93f7393Sniklas 
1411e93f7393Sniklas 	  /* We should look at presumed_dp in the SOM header, but
1412e93f7393Sniklas 	     that's not easily available.  This should be OK though.  */
1413e93f7393Sniklas 	  private_section = bfd_get_section_by_name (objfile->obfd,
1414e93f7393Sniklas 						     "$PRIVATE$");
1415e93f7393Sniklas 	  if (!private_section)
1416e93f7393Sniklas 	    {
1417e93f7393Sniklas 	      warning ("Unable to find $PRIVATE$ in shared library!");
1418b725ae77Skettenis 	      offsets->offsets[SECT_OFF_DATA (objfile)] = 0;
1419b725ae77Skettenis 	      offsets->offsets[SECT_OFF_BSS (objfile)] = 0;
1420e93f7393Sniklas 	      return 1;
1421e93f7393Sniklas 	    }
1422b725ae77Skettenis 	  offsets->offsets[SECT_OFF_DATA (objfile)]
1423e93f7393Sniklas 	    = (so_list->som_solib.data_start - private_section->vma);
1424b725ae77Skettenis 	  offsets->offsets[SECT_OFF_BSS (objfile)]
1425b725ae77Skettenis 	    = ANOFFSET (offsets, SECT_OFF_DATA (objfile));
1426e93f7393Sniklas 	  return 1;
1427e93f7393Sniklas 	}
1428e93f7393Sniklas       so_list = so_list->next;
1429e93f7393Sniklas     }
1430e93f7393Sniklas   return 0;
1431e93f7393Sniklas }
1432e93f7393Sniklas 
1433e93f7393Sniklas /* Dump information about all the currently loaded shared libraries.  */
1434e93f7393Sniklas 
1435e93f7393Sniklas static void
som_sharedlibrary_info_command(char * ignore,int from_tty)1436b725ae77Skettenis som_sharedlibrary_info_command (char *ignore, int from_tty)
1437e93f7393Sniklas {
1438e93f7393Sniklas   struct so_list *so_list = so_list_head;
1439e93f7393Sniklas 
1440e93f7393Sniklas   if (exec_bfd == NULL)
1441e93f7393Sniklas     {
1442b725ae77Skettenis       printf_unfiltered ("No executable file.\n");
1443e93f7393Sniklas       return;
1444e93f7393Sniklas     }
1445e93f7393Sniklas 
1446e93f7393Sniklas   if (so_list == NULL)
1447e93f7393Sniklas     {
1448e93f7393Sniklas       printf_unfiltered ("No shared libraries loaded at this time.\n");
1449e93f7393Sniklas       return;
1450e93f7393Sniklas     }
1451e93f7393Sniklas 
1452e93f7393Sniklas   printf_unfiltered ("Shared Object Libraries\n");
1453e93f7393Sniklas   printf_unfiltered ("    %-12s%-12s%-12s%-12s%-12s%-12s\n",
1454e93f7393Sniklas 	 "  flags", "  tstart", "   tend", "  dstart", "   dend", "   dlt");
1455e93f7393Sniklas   while (so_list)
1456e93f7393Sniklas     {
1457e93f7393Sniklas       unsigned int flags;
1458e93f7393Sniklas 
1459e93f7393Sniklas       flags = so_list->som_solib.struct_version << 24;
1460e93f7393Sniklas       flags |= so_list->som_solib.bind_mode << 16;
1461e93f7393Sniklas       flags |= so_list->som_solib.library_version;
1462b725ae77Skettenis       printf_unfiltered ("%s", so_list->som_solib.name);
1463b725ae77Skettenis       if (so_list->objfile == NULL)
1464b725ae77Skettenis 	printf_unfiltered ("  (symbols not loaded)");
1465b725ae77Skettenis       printf_unfiltered ("\n");
1466*63addd46Skettenis       printf_unfiltered ("    %-12s", hex_string_custom (flags, 8));
1467e93f7393Sniklas       printf_unfiltered ("%-12s",
1468*63addd46Skettenis 			 hex_string_custom (so_list->som_solib.text_addr, 8));
1469e93f7393Sniklas       printf_unfiltered ("%-12s",
1470*63addd46Skettenis 			 hex_string_custom (so_list->som_solib.text_end, 8));
1471e93f7393Sniklas       printf_unfiltered ("%-12s",
1472*63addd46Skettenis 			 hex_string_custom (so_list->som_solib.data_start, 8));
1473e93f7393Sniklas       printf_unfiltered ("%-12s",
1474*63addd46Skettenis 			 hex_string_custom (so_list->som_solib.data_end, 8));
1475e93f7393Sniklas       printf_unfiltered ("%-12s\n",
1476*63addd46Skettenis 			 hex_string_custom (so_list->som_solib.got_value, 8));
1477e93f7393Sniklas       so_list = so_list->next;
1478e93f7393Sniklas     }
1479e93f7393Sniklas }
1480e93f7393Sniklas 
1481e93f7393Sniklas static void
som_solib_sharedlibrary_command(char * args,int from_tty)1482b725ae77Skettenis som_solib_sharedlibrary_command (char *args, int from_tty)
1483e93f7393Sniklas {
1484e93f7393Sniklas   dont_repeat ();
1485b725ae77Skettenis   som_solib_add (args, from_tty, (struct target_ops *) 0, 1);
1486e93f7393Sniklas }
1487e93f7393Sniklas 
1488b725ae77Skettenis 
1489b725ae77Skettenis 
1490b725ae77Skettenis char *
som_solib_address(CORE_ADDR addr)1491b725ae77Skettenis som_solib_address (CORE_ADDR addr)
1492b725ae77Skettenis {
1493b725ae77Skettenis   struct so_list *so = so_list_head;
1494b725ae77Skettenis 
1495b725ae77Skettenis   while (so)
1496b725ae77Skettenis     {
1497b725ae77Skettenis       /* Is this address within this shlib's text range?  If so,
1498b725ae77Skettenis          return the shlib's name.
1499b725ae77Skettenis        */
1500b725ae77Skettenis       if ((addr >= so->som_solib.text_addr) && (addr <= so->som_solib.text_end))
1501b725ae77Skettenis 	return so->som_solib.name;
1502b725ae77Skettenis 
1503b725ae77Skettenis       /* Nope, keep looking... */
1504b725ae77Skettenis       so = so->next;
1505b725ae77Skettenis     }
1506b725ae77Skettenis 
1507b725ae77Skettenis   /* No, we couldn't prove that the address is within a shlib. */
1508b725ae77Skettenis   return NULL;
1509b725ae77Skettenis }
1510b725ae77Skettenis 
1511b725ae77Skettenis 
1512e93f7393Sniklas void
som_solib_restart(void)1513b725ae77Skettenis som_solib_restart (void)
1514b725ae77Skettenis {
1515b725ae77Skettenis   struct so_list *sl = so_list_head;
1516b725ae77Skettenis 
1517b725ae77Skettenis   /* Before the shlib info vanishes, use it to disable any breakpoints
1518b725ae77Skettenis      that may still be active in those shlibs.
1519b725ae77Skettenis    */
1520b725ae77Skettenis   disable_breakpoints_in_shlibs (0);
1521b725ae77Skettenis 
1522b725ae77Skettenis   /* Discard all the shlib descriptors.
1523b725ae77Skettenis    */
1524b725ae77Skettenis   while (sl)
1525b725ae77Skettenis     {
1526b725ae77Skettenis       struct so_list *next_sl = sl->next;
1527b725ae77Skettenis       xfree (sl);
1528b725ae77Skettenis       sl = next_sl;
1529b725ae77Skettenis     }
1530b725ae77Skettenis   so_list_head = NULL;
1531b725ae77Skettenis 
1532b725ae77Skettenis   som_solib_total_st_size = (LONGEST) 0;
1533b725ae77Skettenis   som_solib_st_size_threshold_exceeded = 0;
1534b725ae77Skettenis 
1535b725ae77Skettenis   dld_cache.is_valid = 0;
1536b725ae77Skettenis 
1537b725ae77Skettenis   dld_cache.hook.address = 0;
1538b725ae77Skettenis   dld_cache.hook.unwind = NULL;
1539b725ae77Skettenis 
1540b725ae77Skettenis   dld_cache.hook_stub.address = 0;
1541b725ae77Skettenis   dld_cache.hook_stub.unwind = NULL;
1542b725ae77Skettenis 
1543b725ae77Skettenis   dld_cache.load.address = 0;
1544b725ae77Skettenis   dld_cache.load.unwind = NULL;
1545b725ae77Skettenis 
1546b725ae77Skettenis   dld_cache.load_stub.address = 0;
1547b725ae77Skettenis   dld_cache.load_stub.unwind = NULL;
1548b725ae77Skettenis 
1549b725ae77Skettenis   dld_cache.unload.address = 0;
1550b725ae77Skettenis   dld_cache.unload.unwind = NULL;
1551b725ae77Skettenis 
1552b725ae77Skettenis   dld_cache.unload2.address = 0;
1553b725ae77Skettenis   dld_cache.unload2.unwind = NULL;
1554b725ae77Skettenis 
1555b725ae77Skettenis   dld_cache.unload_stub.address = 0;
1556b725ae77Skettenis   dld_cache.unload_stub.unwind = NULL;
1557b725ae77Skettenis }
1558b725ae77Skettenis 
1559b725ae77Skettenis 
1560b725ae77Skettenis /* LOCAL FUNCTION
1561b725ae77Skettenis 
1562b725ae77Skettenis    no_shared_libraries -- handle command to explicitly discard symbols
1563b725ae77Skettenis    from shared libraries.
1564b725ae77Skettenis 
1565b725ae77Skettenis    DESCRIPTION
1566b725ae77Skettenis 
1567b725ae77Skettenis    Implements the command "nosharedlibrary", which discards symbols
1568b725ae77Skettenis    that have been auto-loaded from shared libraries.  Symbols from
1569b725ae77Skettenis    shared libraries that were added by explicit request of the user
1570b725ae77Skettenis    are not discarded.  Also called from remote.c.  */
1571b725ae77Skettenis 
1572b725ae77Skettenis void
no_shared_libraries(char * ignored,int from_tty)1573b725ae77Skettenis no_shared_libraries (char *ignored, int from_tty)
1574b725ae77Skettenis {
1575b725ae77Skettenis   /* FIXME */
1576b725ae77Skettenis }
1577b725ae77Skettenis 
1578b725ae77Skettenis 
1579b725ae77Skettenis void
_initialize_som_solib(void)1580b725ae77Skettenis _initialize_som_solib (void)
1581e93f7393Sniklas {
1582e93f7393Sniklas   add_com ("sharedlibrary", class_files, som_solib_sharedlibrary_command,
1583e93f7393Sniklas 	   "Load shared object library symbols for files matching REGEXP.");
1584e93f7393Sniklas   add_info ("sharedlibrary", som_sharedlibrary_info_command,
1585e93f7393Sniklas 	    "Status of loaded shared object libraries.");
1586b725ae77Skettenis 
1587*63addd46Skettenis   deprecated_add_show_from_set
1588b725ae77Skettenis     (add_set_cmd ("auto-solib-add", class_support, var_boolean,
1589e93f7393Sniklas 		  (char *) &auto_solib_add,
1590b725ae77Skettenis 		  "Set autoloading of shared library symbols.\n\
1591b725ae77Skettenis If \"on\", symbols from all shared object libraries will be loaded\n\
1592b725ae77Skettenis automatically when the inferior begins execution, when the dynamic linker\n\
1593b725ae77Skettenis informs gdb that a new library has been loaded, or when attaching to the\n\
1594b725ae77Skettenis inferior.  Otherwise, symbols must be loaded manually, using `sharedlibrary'.",
1595e93f7393Sniklas 		  &setlist),
1596e93f7393Sniklas      &showlist);
1597e93f7393Sniklas 
1598*63addd46Skettenis   deprecated_add_show_from_set
1599b725ae77Skettenis     (add_set_cmd ("auto-solib-limit", class_support, var_zinteger,
1600b725ae77Skettenis 		  (char *) &auto_solib_limit,
1601b725ae77Skettenis 		  "Set threshold (in Mb) for autoloading shared library symbols.\n\
1602b725ae77Skettenis When shared library autoloading is enabled, new libraries will be loaded\n\
1603b725ae77Skettenis only until the total size of shared library symbols exceeds this\n\
1604b725ae77Skettenis threshold in megabytes.  Is ignored when using `sharedlibrary'.",
1605b725ae77Skettenis 		  &setlist),
1606b725ae77Skettenis      &showlist);
1607b725ae77Skettenis 
1608b725ae77Skettenis   /* ??rehrauer: On HP-UX, the kernel parameter MAXDSIZ limits how
1609b725ae77Skettenis      much data space a process can use.  We ought to be reading
1610b725ae77Skettenis      MAXDSIZ and setting auto_solib_limit to some large fraction of
1611b725ae77Skettenis      that value.  If not that, we maybe ought to be setting it smaller
1612b725ae77Skettenis      than the default for MAXDSIZ (that being 64Mb, I believe).
1613b725ae77Skettenis      However, [1] this threshold is only crudely approximated rather
1614b725ae77Skettenis      than actually measured, and [2] 50 Mbytes is too small for
1615b725ae77Skettenis      debugging gdb itself.  Thus, the arbitrary 100 figure.  */
1616b725ae77Skettenis   auto_solib_limit = 100;	/* Megabytes */
1617b725ae77Skettenis 
1618b725ae77Skettenis   som_solib_restart ();
1619b725ae77Skettenis }
1620b725ae77Skettenis 
1621b725ae77Skettenis /* Get some HPUX-specific data from a shared lib.
1622b725ae77Skettenis  */
1623b725ae77Skettenis CORE_ADDR
so_lib_thread_start_addr(struct so_list * so)1624b725ae77Skettenis so_lib_thread_start_addr (struct so_list *so)
1625b725ae77Skettenis {
1626b725ae77Skettenis   return so->som_solib.tsd_start_addr;
1627e93f7393Sniklas }
1628