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