xref: /openbsd-src/gnu/usr.bin/binutils/gdb/pa64solib.c (revision 11efff7f3ac2b3cfeff0c0cddc14294d9b3aca4f)
1b725ae77Skettenis /* Handle HP ELF shared libraries for GDB, the GNU Debugger.
2b725ae77Skettenis 
3b725ae77Skettenis    Copyright 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation,
4b725ae77Skettenis    Inc.
5b725ae77Skettenis 
6b725ae77Skettenis    This file is part of GDB.
7b725ae77Skettenis 
8b725ae77Skettenis    This program is free software; you can redistribute it and/or modify
9b725ae77Skettenis    it under the terms of the GNU General Public License as published by
10b725ae77Skettenis    the Free Software Foundation; either version 2 of the License, or
11b725ae77Skettenis    (at your option) any later version.
12b725ae77Skettenis 
13b725ae77Skettenis    This program is distributed in the hope that it will be useful,
14b725ae77Skettenis    but WITHOUT ANY WARRANTY; without even the implied warranty of
15b725ae77Skettenis    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16b725ae77Skettenis    GNU General Public License for more details.
17b725ae77Skettenis 
18b725ae77Skettenis    You should have received a copy of the GNU General Public License
19b725ae77Skettenis    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.
22b725ae77Skettenis 
23b725ae77Skettenis    HP in their infinite stupidity choose not to use standard ELF dynamic
24b725ae77Skettenis    linker interfaces.  They also choose not to make their ELF dymamic
25b725ae77Skettenis    linker interfaces compatible with the SOM dynamic linker.  The
26b725ae77Skettenis    net result is we can not use either of the existing somsolib.c or
27b725ae77Skettenis    solib.c.  What a crock.
28b725ae77Skettenis 
29b725ae77Skettenis    Even more disgusting.  This file depends on functions provided only
30b725ae77Skettenis    in certain PA64 libraries.  Thus this file is supposed to only be
31b725ae77Skettenis    used native.  When will HP ever learn that they need to provide the
32b725ae77Skettenis    same functionality in all their libraries!  */
33b725ae77Skettenis 
34b725ae77Skettenis #include <dlfcn.h>
35b725ae77Skettenis #include <elf.h>
36b725ae77Skettenis #include <elf_hp.h>
37b725ae77Skettenis 
38b725ae77Skettenis #include "defs.h"
39b725ae77Skettenis 
40b725ae77Skettenis #include "frame.h"
41b725ae77Skettenis #include "bfd.h"
42b725ae77Skettenis #include "libhppa.h"
43b725ae77Skettenis #include "gdbcore.h"
44b725ae77Skettenis #include "symtab.h"
45b725ae77Skettenis #include "breakpoint.h"
46b725ae77Skettenis #include "symfile.h"
47b725ae77Skettenis #include "objfiles.h"
48b725ae77Skettenis #include "inferior.h"
49b725ae77Skettenis #include "gdb-stabs.h"
50b725ae77Skettenis #include "gdb_stat.h"
51b725ae77Skettenis #include "gdbcmd.h"
52b725ae77Skettenis #include "language.h"
53b725ae77Skettenis #include "regcache.h"
54b725ae77Skettenis #include "exec.h"
55*11efff7fSkettenis #include "hppa-tdep.h"
56b725ae77Skettenis 
57b725ae77Skettenis #include <fcntl.h>
58b725ae77Skettenis 
59b725ae77Skettenis #ifndef O_BINARY
60b725ae77Skettenis #define O_BINARY 0
61b725ae77Skettenis #endif
62b725ae77Skettenis 
63b725ae77Skettenis static CORE_ADDR bfd_lookup_symbol (bfd *, char *);
64b725ae77Skettenis /* This lives in hppa-tdep.c. */
65b725ae77Skettenis extern struct unwind_table_entry *find_unwind_entry (CORE_ADDR pc);
66b725ae77Skettenis 
67b725ae77Skettenis /* These ought to be defined in some public interface, but aren't.  They
68b725ae77Skettenis    identify dynamic linker events.  */
69b725ae77Skettenis #define DLD_CB_LOAD     1
70b725ae77Skettenis #define DLD_CB_UNLOAD   0
71b725ae77Skettenis 
72b725ae77Skettenis /* A structure to keep track of all the known shared objects.  */
73b725ae77Skettenis struct so_list
74b725ae77Skettenis   {
75b725ae77Skettenis     bfd *abfd;
76b725ae77Skettenis     char *name;
77b725ae77Skettenis     struct so_list *next;
78b725ae77Skettenis     struct objfile *objfile;
79b725ae77Skettenis     CORE_ADDR pa64_solib_desc_addr;
80b725ae77Skettenis     struct load_module_desc pa64_solib_desc;
81b725ae77Skettenis     struct section_table *sections;
82b725ae77Skettenis     struct section_table *sections_end;
83b725ae77Skettenis     int loaded;
84b725ae77Skettenis   };
85b725ae77Skettenis 
86b725ae77Skettenis static struct so_list *so_list_head;
87b725ae77Skettenis 
88b725ae77Skettenis /* This is the cumulative size in bytes of the symbol tables of all
89b725ae77Skettenis    shared objects on the so_list_head list.  (When we say size, here
90b725ae77Skettenis    we mean of the information before it is brought into memory and
91b725ae77Skettenis    potentially expanded by GDB.)  When adding a new shlib, this value
92b725ae77Skettenis    is compared against a threshold size, held by auto_solib_limit (in
93b725ae77Skettenis    megabytes).  If adding symbols for the new shlib would cause the
94b725ae77Skettenis    total size to exceed the threshold, then the new shlib's symbols
95b725ae77Skettenis    are not loaded. */
96b725ae77Skettenis static LONGEST pa64_solib_total_st_size;
97b725ae77Skettenis 
98b725ae77Skettenis /* When the threshold is reached for any shlib, we refuse to add
99b725ae77Skettenis    symbols for subsequent shlibs, even if those shlibs' symbols would
100b725ae77Skettenis    be small enough to fit under the threshold.  Although this may
101b725ae77Skettenis    result in one, early large shlib preventing the loading of later,
102b725ae77Skettenis    smaller shlibs' symbols, it allows us to issue one informational
103b725ae77Skettenis    message.  The alternative, to issue a message for each shlib whose
104b725ae77Skettenis    symbols aren't loaded, could be a big annoyance where the threshold
105b725ae77Skettenis    is exceeded due to a very large number of shlibs. */
106b725ae77Skettenis static int pa64_solib_st_size_threshold_exceeded;
107b725ae77Skettenis 
108b725ae77Skettenis /* When adding fields, be sure to clear them in _initialize_pa64_solib. */
109b725ae77Skettenis typedef struct
110b725ae77Skettenis   {
111b725ae77Skettenis     CORE_ADDR dld_flags_addr;
112b725ae77Skettenis     LONGEST dld_flags;
113b725ae77Skettenis     struct bfd_section *dyninfo_sect;
114b725ae77Skettenis     int have_read_dld_descriptor;
115b725ae77Skettenis     int is_valid;
116b725ae77Skettenis     CORE_ADDR load_map;
117b725ae77Skettenis     CORE_ADDR load_map_addr;
118b725ae77Skettenis     struct load_module_desc dld_desc;
119b725ae77Skettenis   }
120b725ae77Skettenis dld_cache_t;
121b725ae77Skettenis 
122b725ae77Skettenis static dld_cache_t dld_cache;
123b725ae77Skettenis 
124b725ae77Skettenis static void pa64_sharedlibrary_info_command (char *, int);
125b725ae77Skettenis 
126b725ae77Skettenis static void pa64_solib_sharedlibrary_command (char *, int);
127b725ae77Skettenis 
128b725ae77Skettenis static void *pa64_target_read_memory (void *, CORE_ADDR, size_t, int);
129b725ae77Skettenis 
130b725ae77Skettenis static int read_dld_descriptor (struct target_ops *, int readsyms);
131b725ae77Skettenis 
132b725ae77Skettenis static int read_dynamic_info (asection *, dld_cache_t *);
133b725ae77Skettenis 
134b725ae77Skettenis static void add_to_solist (int, char *, int, struct load_module_desc *,
135b725ae77Skettenis 			   CORE_ADDR, struct target_ops *);
136b725ae77Skettenis 
137b725ae77Skettenis /* When examining the shared library for debugging information we have to
138b725ae77Skettenis    look for HP debug symbols, stabs and dwarf2 debug symbols.  */
139b725ae77Skettenis static char *pa64_debug_section_names[] = {
140b725ae77Skettenis   ".debug_header", ".debug_gntt", ".debug_lntt", ".debug_slt", ".debug_vt",
141b725ae77Skettenis   ".stabs", ".stabstr", ".debug_info", ".debug_abbrev", ".debug_aranges",
142b725ae77Skettenis   ".debug_macinfo", ".debug_line", ".debug_loc", ".debug_pubnames",
143b725ae77Skettenis   ".debug_str", NULL
144b725ae77Skettenis };
145b725ae77Skettenis 
146b725ae77Skettenis /* Return a ballbark figure for the amount of memory GDB will need to
147b725ae77Skettenis    allocate to read in the debug symbols from FILENAME.  */
148b725ae77Skettenis static LONGEST
pa64_solib_sizeof_symbol_table(char * filename)149b725ae77Skettenis pa64_solib_sizeof_symbol_table (char *filename)
150b725ae77Skettenis {
151b725ae77Skettenis   bfd *abfd;
152b725ae77Skettenis   int i;
153b725ae77Skettenis   int desc;
154b725ae77Skettenis   char *absolute_name;
155b725ae77Skettenis   LONGEST st_size = (LONGEST) 0;
156b725ae77Skettenis   asection *sect;
157b725ae77Skettenis 
158b725ae77Skettenis   /* We believe that filename was handed to us by the dynamic linker, and
159b725ae77Skettenis      is therefore always an absolute path.  */
160*11efff7fSkettenis   desc = openp (getenv ("PATH"), OPF_TRY_CWD_FIRST, filename,
161*11efff7fSkettenis 		O_RDONLY | O_BINARY, 0, &absolute_name);
162b725ae77Skettenis   if (desc < 0)
163b725ae77Skettenis     {
164b725ae77Skettenis       perror_with_name (filename);
165b725ae77Skettenis     }
166b725ae77Skettenis   filename = absolute_name;
167b725ae77Skettenis 
168b725ae77Skettenis   abfd = bfd_fdopenr (filename, gnutarget, desc);
169b725ae77Skettenis   if (!abfd)
170b725ae77Skettenis     {
171b725ae77Skettenis       close (desc);
172b725ae77Skettenis       make_cleanup (xfree, filename);
173b725ae77Skettenis       error ("\"%s\": can't open to read symbols: %s.", filename,
174b725ae77Skettenis 	     bfd_errmsg (bfd_get_error ()));
175b725ae77Skettenis     }
176b725ae77Skettenis 
177b725ae77Skettenis   if (!bfd_check_format (abfd, bfd_object))
178b725ae77Skettenis     {
179b725ae77Skettenis       bfd_close (abfd);
180b725ae77Skettenis       make_cleanup (xfree, filename);
181b725ae77Skettenis       error ("\"%s\": can't read symbols: %s.", filename,
182b725ae77Skettenis 	     bfd_errmsg (bfd_get_error ()));
183b725ae77Skettenis     }
184b725ae77Skettenis 
185b725ae77Skettenis   /* Sum the sizes of the various sections that compose debug info. */
186b725ae77Skettenis   for (i = 0; pa64_debug_section_names[i] != NULL; i++)
187b725ae77Skettenis     {
188b725ae77Skettenis       asection *sect;
189b725ae77Skettenis 
190b725ae77Skettenis       sect = bfd_get_section_by_name (abfd, pa64_debug_section_names[i]);
191b725ae77Skettenis       if (sect)
192b725ae77Skettenis 	st_size += (LONGEST)bfd_section_size (abfd, sect);
193b725ae77Skettenis     }
194b725ae77Skettenis 
195b725ae77Skettenis   bfd_close (abfd);
196b725ae77Skettenis   xfree (filename);
197b725ae77Skettenis 
198b725ae77Skettenis   /* Unfortunately, just summing the sizes of various debug info
199b725ae77Skettenis      sections isn't a very accurate measurement of how much heap
200b725ae77Skettenis      space the debugger will need to hold them.  It also doesn't
201b725ae77Skettenis      account for space needed by linker (aka "minimal") symbols.
202b725ae77Skettenis 
203b725ae77Skettenis      Anecdotal evidence suggests that just summing the sizes of
204b725ae77Skettenis      debug-info-related sections understates the heap space needed
205b725ae77Skettenis      to represent it internally by about an order of magnitude.
206b725ae77Skettenis 
207b725ae77Skettenis      Since it's not exactly brain surgery we're doing here, rather
208b725ae77Skettenis      than attempt to more accurately measure the size of a shlib's
209b725ae77Skettenis      symbol table in GDB's heap, we'll just apply a 10x fudge-
210b725ae77Skettenis      factor to the debug info sections' size-sum.  No, this doesn't
211b725ae77Skettenis      account for minimal symbols in non-debuggable shlibs.  But it
212b725ae77Skettenis      all roughly washes out in the end.  */
213b725ae77Skettenis   return st_size * (LONGEST) 10;
214b725ae77Skettenis }
215b725ae77Skettenis 
216b725ae77Skettenis /* Add a shared library to the objfile list and load its symbols into
217b725ae77Skettenis    GDB's symbol table.  */
218b725ae77Skettenis static void
pa64_solib_add_solib_objfile(struct so_list * so,char * name,int from_tty,CORE_ADDR text_addr)219b725ae77Skettenis pa64_solib_add_solib_objfile (struct so_list *so, char *name, int from_tty,
220b725ae77Skettenis 			      CORE_ADDR text_addr)
221b725ae77Skettenis {
222b725ae77Skettenis   bfd *tmp_bfd;
223b725ae77Skettenis   asection *sec;
224*11efff7fSkettenis   struct hppa_objfile_private *obj_private;
225b725ae77Skettenis   struct section_addr_info *section_addrs;
226b725ae77Skettenis   struct cleanup *my_cleanups;
227b725ae77Skettenis 
228b725ae77Skettenis   /* We need the BFD so that we can look at its sections.  We open up the
229b725ae77Skettenis      file temporarily, then close it when we are done.  */
230b725ae77Skettenis   tmp_bfd = bfd_openr (name, gnutarget);
231b725ae77Skettenis   if (tmp_bfd == NULL)
232b725ae77Skettenis     {
233b725ae77Skettenis       perror_with_name (name);
234b725ae77Skettenis       return;
235b725ae77Skettenis     }
236b725ae77Skettenis 
237b725ae77Skettenis   if (!bfd_check_format (tmp_bfd, bfd_object))
238b725ae77Skettenis     {
239b725ae77Skettenis       bfd_close (tmp_bfd);
240b725ae77Skettenis       error ("\"%s\" is not an object file: %s", name,
241b725ae77Skettenis 	     bfd_errmsg (bfd_get_error ()));
242b725ae77Skettenis     }
243b725ae77Skettenis 
244b725ae77Skettenis 
245b725ae77Skettenis   /* Undo some braindamage from symfile.c.
246b725ae77Skettenis 
247b725ae77Skettenis      First, symfile.c will subtract the VMA of the first .text section
248b725ae77Skettenis      in the shared library that it finds.  Undo that.  */
249b725ae77Skettenis   sec = bfd_get_section_by_name (tmp_bfd, ".text");
250b725ae77Skettenis   text_addr += bfd_section_vma (tmp_bfd, sec);
251b725ae77Skettenis 
252b725ae77Skettenis   /* Now find the true lowest section in the shared library.  */
253b725ae77Skettenis   sec = NULL;
254b725ae77Skettenis   bfd_map_over_sections (tmp_bfd, find_lowest_section, &sec);
255b725ae77Skettenis 
256b725ae77Skettenis   if (sec)
257b725ae77Skettenis     {
258b725ae77Skettenis       /* Subtract out the VMA of the lowest section.  */
259b725ae77Skettenis       text_addr -= bfd_section_vma (tmp_bfd, sec);
260b725ae77Skettenis 
261b725ae77Skettenis       /* ??? Add back in the filepos of that lowest section. */
262b725ae77Skettenis       text_addr += sec->filepos;
263b725ae77Skettenis     }
264b725ae77Skettenis 
265b725ae77Skettenis   section_addrs = alloc_section_addr_info (bfd_count_sections (tmp_bfd));
266b725ae77Skettenis   my_cleanups = make_cleanup (xfree, section_addrs);
267b725ae77Skettenis 
268b725ae77Skettenis   /* We are done with the temporary bfd.  Get rid of it and make sure
269b725ae77Skettenis      nobody else can us it.  */
270b725ae77Skettenis   bfd_close (tmp_bfd);
271b725ae77Skettenis   tmp_bfd = NULL;
272b725ae77Skettenis 
273b725ae77Skettenis   /* Now let the generic code load up symbols for this library.  */
274b725ae77Skettenis   section_addrs->other[0].addr = text_addr;
275b725ae77Skettenis   section_addrs->other[0].name = ".text";
276b725ae77Skettenis   so->objfile = symbol_file_add (name, from_tty, section_addrs, 0, OBJF_SHARED);
277b725ae77Skettenis   so->abfd = so->objfile->obfd;
278b725ae77Skettenis 
279b725ae77Skettenis   /* Mark this as a shared library and save private data.  */
280b725ae77Skettenis   so->objfile->flags |= OBJF_SHARED;
281b725ae77Skettenis 
282*11efff7fSkettenis   obj_private = (struct hppa_objfile_private *)
283*11efff7fSkettenis 	        objfile_data (so->objfile, hppa_objfile_priv_data);
284*11efff7fSkettenis   if (obj_private == NULL)
285b725ae77Skettenis     {
286*11efff7fSkettenis       obj_private = (struct hppa_objfile_private *)
287b725ae77Skettenis 	obstack_alloc (&so->objfile->objfile_obstack,
288*11efff7fSkettenis 		       sizeof (struct hppa_objfile_private));
289*11efff7fSkettenis       set_objfile_data (so->objfile, hppa_objfile_priv_data, obj_private);
290b725ae77Skettenis       obj_private->unwind_info = NULL;
291b725ae77Skettenis       obj_private->so_info = NULL;
292b725ae77Skettenis     }
293b725ae77Skettenis 
294b725ae77Skettenis   obj_private->so_info = so;
295b725ae77Skettenis   obj_private->dp = so->pa64_solib_desc.linkage_ptr;
296b725ae77Skettenis   do_cleanups (my_cleanups);
297b725ae77Skettenis }
298b725ae77Skettenis 
299b725ae77Skettenis /* Load debugging information for a shared library.  TARGET may be
300b725ae77Skettenis    NULL if we are not attaching to a process or reading a core file.  */
301b725ae77Skettenis 
302b725ae77Skettenis static void
pa64_solib_load_symbols(struct so_list * so,char * name,int from_tty,CORE_ADDR text_addr,struct target_ops * target)303b725ae77Skettenis pa64_solib_load_symbols (struct so_list *so, char *name, int from_tty,
304b725ae77Skettenis 			 CORE_ADDR text_addr, struct target_ops *target)
305b725ae77Skettenis {
306b725ae77Skettenis   struct section_table *p;
307b725ae77Skettenis   asection *sec;
308b725ae77Skettenis   int status;
309b725ae77Skettenis   char buf[4];
310b725ae77Skettenis   CORE_ADDR presumed_data_start;
311b725ae77Skettenis 
312b725ae77Skettenis   if (text_addr == 0)
313b725ae77Skettenis     text_addr = so->pa64_solib_desc.text_base;
314b725ae77Skettenis 
315b725ae77Skettenis   pa64_solib_add_solib_objfile (so, name, from_tty, text_addr);
316b725ae77Skettenis 
317b725ae77Skettenis   /* Now we need to build a section table for this library since
318b725ae77Skettenis      we might be debugging a core file from a dynamically linked
319b725ae77Skettenis      executable in which the libraries were not privately mapped.  */
320b725ae77Skettenis   if (build_section_table (so->abfd,
321b725ae77Skettenis 			   &so->sections,
322b725ae77Skettenis 			   &so->sections_end))
323b725ae77Skettenis     {
324b725ae77Skettenis       error ("Unable to build section table for shared library\n.");
325b725ae77Skettenis       return;
326b725ae77Skettenis     }
327b725ae77Skettenis 
328b725ae77Skettenis   (so->objfile->section_offsets)->offsets[SECT_OFF_TEXT (so->objfile)]
329b725ae77Skettenis     = so->pa64_solib_desc.text_base;
330b725ae77Skettenis   (so->objfile->section_offsets)->offsets[SECT_OFF_DATA (so->objfile)]
331b725ae77Skettenis     = so->pa64_solib_desc.data_base;
332b725ae77Skettenis 
333b725ae77Skettenis   /* Relocate all the sections based on where they got loaded.  */
334b725ae77Skettenis   for (p = so->sections; p < so->sections_end; p++)
335b725ae77Skettenis     {
336b725ae77Skettenis       if (p->the_bfd_section->flags & SEC_CODE)
337b725ae77Skettenis 	{
338b725ae77Skettenis 	  p->addr += ANOFFSET (so->objfile->section_offsets, SECT_OFF_TEXT (so->objfile));
339b725ae77Skettenis 	  p->endaddr += ANOFFSET (so->objfile->section_offsets, SECT_OFF_TEXT (so->objfile));
340b725ae77Skettenis 	}
341b725ae77Skettenis       else if (p->the_bfd_section->flags & SEC_DATA)
342b725ae77Skettenis 	{
343b725ae77Skettenis 	  p->addr += ANOFFSET (so->objfile->section_offsets, SECT_OFF_DATA (so->objfile));
344b725ae77Skettenis 	  p->endaddr += ANOFFSET (so->objfile->section_offsets, SECT_OFF_DATA (so->objfile));
345b725ae77Skettenis 	}
346b725ae77Skettenis     }
347b725ae77Skettenis 
348b725ae77Skettenis   /* Now see if we need to map in the text and data for this shared
349b725ae77Skettenis      library (for example debugging a core file which does not use
350b725ae77Skettenis      private shared libraries.).
351b725ae77Skettenis 
352b725ae77Skettenis      Carefully peek at the first text address in the library.  If the
353b725ae77Skettenis      read succeeds, then the libraries were privately mapped and were
354b725ae77Skettenis      included in the core dump file.
355b725ae77Skettenis 
356b725ae77Skettenis      If the peek failed, then the libraries were not privately mapped
357b725ae77Skettenis      and are not in the core file, we'll have to read them in ourselves.  */
358b725ae77Skettenis   status = target_read_memory (text_addr, buf, 4);
359b725ae77Skettenis   if (status != 0)
360b725ae77Skettenis     {
361b725ae77Skettenis       int new, old;
362b725ae77Skettenis 
363b725ae77Skettenis       new = so->sections_end - so->sections;
364b725ae77Skettenis 
365b725ae77Skettenis       old = target_resize_to_sections (target, new);
366b725ae77Skettenis 
367b725ae77Skettenis       /* Copy over the old data before it gets clobbered.  */
368b725ae77Skettenis       memcpy ((char *) (target->to_sections + old),
369b725ae77Skettenis 	      so->sections,
370b725ae77Skettenis 	      ((sizeof (struct section_table)) * new));
371b725ae77Skettenis     }
372b725ae77Skettenis }
373b725ae77Skettenis 
374b725ae77Skettenis 
375b725ae77Skettenis /* Add symbols from shared libraries into the symtab list, unless the
376b725ae77Skettenis    size threshold specified by auto_solib_limit (in megabytes) would
377b725ae77Skettenis    be exceeded.  */
378b725ae77Skettenis 
379b725ae77Skettenis void
pa64_solib_add(char * arg_string,int from_tty,struct target_ops * target,int readsyms)380b725ae77Skettenis pa64_solib_add (char *arg_string, int from_tty, struct target_ops *target, int readsyms)
381b725ae77Skettenis {
382b725ae77Skettenis   struct minimal_symbol *msymbol;
383b725ae77Skettenis   CORE_ADDR addr;
384b725ae77Skettenis   asection *shlib_info;
385b725ae77Skettenis   int status;
386b725ae77Skettenis   unsigned int dld_flags;
387b725ae77Skettenis   char buf[4], *re_err;
388b725ae77Skettenis   int threshold_warning_given = 0;
389b725ae77Skettenis   int dll_index;
390b725ae77Skettenis   struct load_module_desc dll_desc;
391b725ae77Skettenis   char *dll_path;
392b725ae77Skettenis 
393b725ae77Skettenis   /* First validate our arguments.  */
394b725ae77Skettenis   if ((re_err = re_comp (arg_string ? arg_string : ".")) != NULL)
395b725ae77Skettenis     {
396b725ae77Skettenis       error ("Invalid regexp: %s", re_err);
397b725ae77Skettenis     }
398b725ae77Skettenis 
399b725ae77Skettenis   /* If we're debugging a core file, or have attached to a running
400b725ae77Skettenis      process, then pa64_solib_create_inferior_hook will not have been
401b725ae77Skettenis      called.
402b725ae77Skettenis 
403b725ae77Skettenis      We need to first determine if we're dealing with a dynamically
404b725ae77Skettenis      linked executable.  If not, then return without an error or warning.
405b725ae77Skettenis 
406b725ae77Skettenis      We also need to examine __dld_flags to determine if the shared library
407b725ae77Skettenis      list is valid and to determine if the libraries have been privately
408b725ae77Skettenis      mapped.  */
409b725ae77Skettenis   if (symfile_objfile == NULL)
410b725ae77Skettenis     return;
411b725ae77Skettenis 
412b725ae77Skettenis   /* First see if the objfile was dynamically linked.  */
413b725ae77Skettenis   shlib_info = bfd_get_section_by_name (symfile_objfile->obfd, ".dynamic");
414b725ae77Skettenis   if (!shlib_info)
415b725ae77Skettenis     return;
416b725ae77Skettenis 
417b725ae77Skettenis   /* It's got a .dynamic section, make sure it's not empty.  */
418b725ae77Skettenis   if (bfd_section_size (symfile_objfile->obfd, shlib_info) == 0)
419b725ae77Skettenis     return;
420b725ae77Skettenis 
421b725ae77Skettenis   /* Read in the load map pointer if we have not done so already.  */
422b725ae77Skettenis   if (! dld_cache.have_read_dld_descriptor)
423b725ae77Skettenis     if (! read_dld_descriptor (target, readsyms))
424b725ae77Skettenis       return;
425b725ae77Skettenis 
426b725ae77Skettenis   /* If the libraries were not mapped private, warn the user.  */
427b725ae77Skettenis   if ((dld_cache.dld_flags & DT_HP_DEBUG_PRIVATE) == 0)
428b725ae77Skettenis     warning ("The shared libraries were not privately mapped; setting a\nbreakpoint in a shared library will not work until you rerun the program.\n");
429b725ae77Skettenis 
430b725ae77Skettenis   /* For each shaerd library, add it to the shared library list.  */
431b725ae77Skettenis   for (dll_index = 1; ; dll_index++)
432b725ae77Skettenis     {
433b725ae77Skettenis       /* Read in the load module descriptor.  */
434b725ae77Skettenis       if (dlgetmodinfo (dll_index, &dll_desc, sizeof (dll_desc),
435b725ae77Skettenis 			pa64_target_read_memory, 0, dld_cache.load_map)
436b725ae77Skettenis 	  == 0)
437b725ae77Skettenis 	return;
438b725ae77Skettenis 
439b725ae77Skettenis       /* Get the name of the shared library.  */
440b725ae77Skettenis       dll_path = (char *)dlgetname (&dll_desc, sizeof (dll_desc),
441b725ae77Skettenis 			    pa64_target_read_memory,
442b725ae77Skettenis 			    0, dld_cache.load_map);
443b725ae77Skettenis 
444b725ae77Skettenis       if (!dll_path)
445b725ae77Skettenis 	error ("pa64_solib_add, unable to read shared library path.");
446b725ae77Skettenis 
447b725ae77Skettenis       add_to_solist (from_tty, dll_path, readsyms, &dll_desc, 0, target);
448b725ae77Skettenis     }
449b725ae77Skettenis }
450b725ae77Skettenis 
451b725ae77Skettenis 
452b725ae77Skettenis /* This hook gets called just before the first instruction in the
453b725ae77Skettenis    inferior process is executed.
454b725ae77Skettenis 
455b725ae77Skettenis    This is our opportunity to set magic flags in the inferior so
456b725ae77Skettenis    that GDB can be notified when a shared library is mapped in and
457b725ae77Skettenis    to tell the dynamic linker that a private copy of the library is
458b725ae77Skettenis    needed (so GDB can set breakpoints in the library).
459b725ae77Skettenis 
460b725ae77Skettenis    We need to set two flag bits in this routine.
461b725ae77Skettenis 
462b725ae77Skettenis      DT_HP_DEBUG_PRIVATE to indicate that shared libraries should be
463b725ae77Skettenis      mapped private.
464b725ae77Skettenis 
465b725ae77Skettenis      DT_HP_DEBUG_CALLBACK to indicate that we want the dynamic linker to
466b725ae77Skettenis      call the breakpoint routine for significant events.  */
467b725ae77Skettenis 
468b725ae77Skettenis void
pa64_solib_create_inferior_hook(void)469b725ae77Skettenis pa64_solib_create_inferior_hook (void)
470b725ae77Skettenis {
471b725ae77Skettenis   struct minimal_symbol *msymbol;
472b725ae77Skettenis   unsigned int dld_flags, status;
473b725ae77Skettenis   asection *shlib_info, *interp_sect;
474b725ae77Skettenis   char buf[4];
475b725ae77Skettenis   struct objfile *objfile;
476b725ae77Skettenis   CORE_ADDR anaddr;
477b725ae77Skettenis 
478b725ae77Skettenis   /* First, remove all the solib event breakpoints.  Their addresses
479b725ae77Skettenis      may have changed since the last time we ran the program.  */
480b725ae77Skettenis   remove_solib_event_breakpoints ();
481b725ae77Skettenis 
482b725ae77Skettenis   if (symfile_objfile == NULL)
483b725ae77Skettenis     return;
484b725ae77Skettenis 
485b725ae77Skettenis   /* First see if the objfile was dynamically linked.  */
486b725ae77Skettenis   shlib_info = bfd_get_section_by_name (symfile_objfile->obfd, ".dynamic");
487b725ae77Skettenis   if (!shlib_info)
488b725ae77Skettenis     return;
489b725ae77Skettenis 
490b725ae77Skettenis   /* It's got a .dynamic section, make sure it's not empty.  */
491b725ae77Skettenis   if (bfd_section_size (symfile_objfile->obfd, shlib_info) == 0)
492b725ae77Skettenis     return;
493b725ae77Skettenis 
494b725ae77Skettenis   /* Read in the .dynamic section.  */
495b725ae77Skettenis   if (! read_dynamic_info (shlib_info, &dld_cache))
496b725ae77Skettenis     error ("Unable to read the .dynamic section.");
497b725ae77Skettenis 
498b725ae77Skettenis   /* Turn on the flags we care about.  */
499b725ae77Skettenis   dld_cache.dld_flags |= DT_HP_DEBUG_PRIVATE;
500b725ae77Skettenis   dld_cache.dld_flags |= DT_HP_DEBUG_CALLBACK;
501b725ae77Skettenis   status = target_write_memory (dld_cache.dld_flags_addr,
502b725ae77Skettenis 				(char *) &dld_cache.dld_flags,
503b725ae77Skettenis 				sizeof (dld_cache.dld_flags));
504b725ae77Skettenis   if (status != 0)
505b725ae77Skettenis     error ("Unable to modify dynamic linker flags.");
506b725ae77Skettenis 
507b725ae77Skettenis   /* Now we have to create a shared library breakpoint in the dynamic
508b725ae77Skettenis      linker.  This can be somewhat tricky since the symbol is inside
509b725ae77Skettenis      the dynamic linker (for which we do not have symbols or a base
510b725ae77Skettenis      load address!   Luckily I wrote this code for solib.c years ago.  */
511b725ae77Skettenis   interp_sect = bfd_get_section_by_name (exec_bfd, ".interp");
512b725ae77Skettenis   if (interp_sect)
513b725ae77Skettenis     {
514b725ae77Skettenis       unsigned int interp_sect_size;
515b725ae77Skettenis       char *buf;
516b725ae77Skettenis       CORE_ADDR load_addr;
517b725ae77Skettenis       bfd *tmp_bfd;
518b725ae77Skettenis       CORE_ADDR sym_addr = 0;
519b725ae77Skettenis 
520b725ae77Skettenis       /* Read the contents of the .interp section into a local buffer;
521b725ae77Skettenis 	 the contents specify the dynamic linker this program uses.  */
522b725ae77Skettenis       interp_sect_size = bfd_section_size (exec_bfd, interp_sect);
523b725ae77Skettenis       buf = alloca (interp_sect_size);
524b725ae77Skettenis       bfd_get_section_contents (exec_bfd, interp_sect,
525b725ae77Skettenis 				buf, 0, interp_sect_size);
526b725ae77Skettenis 
527b725ae77Skettenis       /* Now we need to figure out where the dynamic linker was
528b725ae77Skettenis 	 loaded so that we can load its symbols and place a breakpoint
529b725ae77Skettenis 	 in the dynamic linker itself.
530b725ae77Skettenis 
531b725ae77Skettenis 	 This address is stored on the stack.  However, I've been unable
532b725ae77Skettenis 	 to find any magic formula to find it for Solaris (appears to
533b725ae77Skettenis 	 be trivial on GNU/Linux).  Therefore, we have to try an alternate
534b725ae77Skettenis 	 mechanism to find the dynamic linker's base address.  */
535b725ae77Skettenis       tmp_bfd = bfd_openr (buf, gnutarget);
536b725ae77Skettenis       if (tmp_bfd == NULL)
537b725ae77Skettenis 	goto get_out;
538b725ae77Skettenis 
539b725ae77Skettenis       /* Make sure the dynamic linker's really a useful object.  */
540b725ae77Skettenis       if (!bfd_check_format (tmp_bfd, bfd_object))
541b725ae77Skettenis 	{
542b725ae77Skettenis 	  warning ("Unable to grok dynamic linker %s as an object file", buf);
543b725ae77Skettenis 	  bfd_close (tmp_bfd);
544b725ae77Skettenis 	  goto get_out;
545b725ae77Skettenis 	}
546b725ae77Skettenis 
547b725ae77Skettenis       /* We find the dynamic linker's base address by examining the
548b725ae77Skettenis 	 current pc (which point at the entry point for the dynamic
549b725ae77Skettenis 	 linker) and subtracting the offset of the entry point.
550b725ae77Skettenis 
551b725ae77Skettenis 	 Also note the breakpoint is the second instruction in the
552b725ae77Skettenis 	 routine.  */
553b725ae77Skettenis       load_addr = read_pc () - tmp_bfd->start_address;
554b725ae77Skettenis       sym_addr = bfd_lookup_symbol (tmp_bfd, "__dld_break");
555b725ae77Skettenis       sym_addr = load_addr + sym_addr + 4;
556b725ae77Skettenis 
557b725ae77Skettenis       /* Create the shared library breakpoint.  */
558b725ae77Skettenis       {
559b725ae77Skettenis 	struct breakpoint *b
560b725ae77Skettenis 	  = create_solib_event_breakpoint (sym_addr);
561b725ae77Skettenis 
562b725ae77Skettenis 	/* The breakpoint is actually hard-coded into the dynamic linker,
563b725ae77Skettenis 	   so we don't need to actually insert a breakpoint instruction
564b725ae77Skettenis 	   there.  In fact, the dynamic linker's code is immutable, even to
565b725ae77Skettenis 	   ttrace, so we shouldn't even try to do that.  For cases like
566b725ae77Skettenis 	   this, we have "permanent" breakpoints.  */
567b725ae77Skettenis 	make_breakpoint_permanent (b);
568b725ae77Skettenis       }
569b725ae77Skettenis 
570b725ae77Skettenis       /* We're done with the temporary bfd.  */
571b725ae77Skettenis       bfd_close (tmp_bfd);
572b725ae77Skettenis     }
573b725ae77Skettenis 
574b725ae77Skettenis get_out:
575b725ae77Skettenis   /* Wipe out all knowledge of old shared libraries since their
576b725ae77Skettenis      mapping can change from one exec to another!  */
577b725ae77Skettenis   while (so_list_head)
578b725ae77Skettenis     {
579b725ae77Skettenis       struct so_list *temp;
580b725ae77Skettenis 
581b725ae77Skettenis       temp = so_list_head;
582b725ae77Skettenis       xfree (so_list_head);
583b725ae77Skettenis       so_list_head = temp->next;
584b725ae77Skettenis     }
585b725ae77Skettenis   clear_symtab_users ();
586b725ae77Skettenis }
587b725ae77Skettenis 
588b725ae77Skettenis /* This operation removes the "hook" between GDB and the dynamic linker,
589b725ae77Skettenis    which causes the dld to notify GDB of shared library events.
590b725ae77Skettenis 
591b725ae77Skettenis    After this operation completes, the dld will no longer notify GDB of
592b725ae77Skettenis    shared library events.  To resume notifications, GDB must call
593b725ae77Skettenis    pa64_solib_create_inferior_hook.
594b725ae77Skettenis 
595b725ae77Skettenis    This operation does not remove any knowledge of shared libraries which
596b725ae77Skettenis    GDB may already have been notified of.  */
597b725ae77Skettenis 
598b725ae77Skettenis void
pa64_solib_remove_inferior_hook(int pid)599b725ae77Skettenis pa64_solib_remove_inferior_hook (int pid)
600b725ae77Skettenis {
601b725ae77Skettenis   /* Turn off the DT_HP_DEBUG_CALLBACK bit in the dynamic linker flags.  */
602b725ae77Skettenis   dld_cache.dld_flags &= ~DT_HP_DEBUG_CALLBACK;
603b725ae77Skettenis   target_write_memory (dld_cache.dld_flags_addr,
604b725ae77Skettenis 		       (char *)&dld_cache.dld_flags,
605b725ae77Skettenis 		       sizeof (dld_cache.dld_flags));
606b725ae77Skettenis }
607b725ae77Skettenis 
608b725ae77Skettenis /* This function creates a breakpoint on the dynamic linker hook, which
609b725ae77Skettenis    is called when e.g., a shl_load or shl_unload call is made.  This
610b725ae77Skettenis    breakpoint will only trigger when a shl_load call is made.
611b725ae77Skettenis 
612b725ae77Skettenis    If filename is NULL, then loads of any dll will be caught.  Else,
613b725ae77Skettenis    only loads of the file whose pathname is the string contained by
614b725ae77Skettenis    filename will be caught.
615b725ae77Skettenis 
616b725ae77Skettenis    Undefined behaviour is guaranteed if this function is called before
617b725ae77Skettenis    pa64_solib_create_inferior_hook.  */
618b725ae77Skettenis 
619b725ae77Skettenis void
pa64_solib_create_catch_load_hook(int pid,int tempflag,char * filename,char * cond_string)620b725ae77Skettenis pa64_solib_create_catch_load_hook (int pid, int tempflag, char *filename,
621b725ae77Skettenis 				   char *cond_string)
622b725ae77Skettenis {
623b725ae77Skettenis   create_solib_load_event_breakpoint ("", tempflag, filename, cond_string);
624b725ae77Skettenis }
625b725ae77Skettenis 
626b725ae77Skettenis /* This function creates a breakpoint on the dynamic linker hook, which
627b725ae77Skettenis    is called when e.g., a shl_load or shl_unload call is made.  This
628b725ae77Skettenis    breakpoint will only trigger when a shl_unload call is made.
629b725ae77Skettenis 
630b725ae77Skettenis    If filename is NULL, then unloads of any dll will be caught.  Else,
631b725ae77Skettenis    only unloads of the file whose pathname is the string contained by
632b725ae77Skettenis    filename will be caught.
633b725ae77Skettenis 
634b725ae77Skettenis    Undefined behaviour is guaranteed if this function is called before
635b725ae77Skettenis    pa64_solib_create_inferior_hook.  */
636b725ae77Skettenis 
637b725ae77Skettenis void
pa64_solib_create_catch_unload_hook(int pid,int tempflag,char * filename,char * cond_string)638b725ae77Skettenis pa64_solib_create_catch_unload_hook (int pid, int tempflag, char *filename,
639b725ae77Skettenis 				     char *cond_string)
640b725ae77Skettenis {
641b725ae77Skettenis   create_solib_unload_event_breakpoint ("", tempflag, filename, cond_string);
642b725ae77Skettenis }
643b725ae77Skettenis 
644b725ae77Skettenis /* Return nonzero if the dynamic linker has reproted that a library
645b725ae77Skettenis    has been loaded.  */
646b725ae77Skettenis 
647b725ae77Skettenis int
pa64_solib_have_load_event(int pid)648b725ae77Skettenis pa64_solib_have_load_event (int pid)
649b725ae77Skettenis {
650b725ae77Skettenis   CORE_ADDR event_kind;
651b725ae77Skettenis 
652*11efff7fSkettenis   event_kind = read_register (HPPA_ARG0_REGNUM);
653b725ae77Skettenis   return (event_kind == DLD_CB_LOAD);
654b725ae77Skettenis }
655b725ae77Skettenis 
656b725ae77Skettenis /* Return nonzero if the dynamic linker has reproted that a library
657b725ae77Skettenis    has been unloaded.  */
658b725ae77Skettenis int
pa64_solib_have_unload_event(int pid)659b725ae77Skettenis pa64_solib_have_unload_event (int pid)
660b725ae77Skettenis {
661b725ae77Skettenis   CORE_ADDR event_kind;
662b725ae77Skettenis 
663*11efff7fSkettenis   event_kind = read_register (HPPA_ARG0_REGNUM);
664b725ae77Skettenis   return (event_kind == DLD_CB_UNLOAD);
665b725ae77Skettenis }
666b725ae77Skettenis 
667b725ae77Skettenis /* Return a pointer to a string indicating the pathname of the most
668b725ae77Skettenis    recently loaded library.
669b725ae77Skettenis 
670b725ae77Skettenis    The caller is reposible for copying the string before the inferior is
671b725ae77Skettenis    restarted.  */
672b725ae77Skettenis 
673b725ae77Skettenis char *
pa64_solib_loaded_library_pathname(int pid)674b725ae77Skettenis pa64_solib_loaded_library_pathname (int pid)
675b725ae77Skettenis {
676b725ae77Skettenis   static char dll_path[MAXPATHLEN];
677*11efff7fSkettenis   CORE_ADDR  dll_path_addr = read_register (HPPA_ARG3_REGNUM);
678b725ae77Skettenis   read_memory_string (dll_path_addr, dll_path, MAXPATHLEN);
679b725ae77Skettenis   return dll_path;
680b725ae77Skettenis }
681b725ae77Skettenis 
682b725ae77Skettenis /* Return a pointer to a string indicating the pathname of the most
683b725ae77Skettenis    recently unloaded library.
684b725ae77Skettenis 
685b725ae77Skettenis    The caller is reposible for copying the string before the inferior is
686b725ae77Skettenis    restarted.  */
687b725ae77Skettenis 
688b725ae77Skettenis char *
pa64_solib_unloaded_library_pathname(int pid)689b725ae77Skettenis pa64_solib_unloaded_library_pathname (int pid)
690b725ae77Skettenis {
691b725ae77Skettenis   static char dll_path[MAXPATHLEN];
692*11efff7fSkettenis   CORE_ADDR dll_path_addr = read_register (HPPA_ARG3_REGNUM);
693b725ae77Skettenis   read_memory_string (dll_path_addr, dll_path, MAXPATHLEN);
694b725ae77Skettenis   return dll_path;
695b725ae77Skettenis }
696b725ae77Skettenis 
697b725ae77Skettenis /* Return nonzero if PC is an address inside the dynamic linker.  */
698b725ae77Skettenis 
699b725ae77Skettenis int
pa64_solib_in_dynamic_linker(int pid,CORE_ADDR pc)700b725ae77Skettenis pa64_solib_in_dynamic_linker (int pid, CORE_ADDR pc)
701b725ae77Skettenis {
702b725ae77Skettenis   asection *shlib_info;
703b725ae77Skettenis 
704b725ae77Skettenis   if (symfile_objfile == NULL)
705b725ae77Skettenis     return 0;
706b725ae77Skettenis 
707b725ae77Skettenis   if (!dld_cache.have_read_dld_descriptor)
708b725ae77Skettenis     if (!read_dld_descriptor (&current_target, auto_solib_add))
709b725ae77Skettenis       return 0;
710b725ae77Skettenis 
711b725ae77Skettenis   return (pc >= dld_cache.dld_desc.text_base
712b725ae77Skettenis 	  && pc < dld_cache.dld_desc.text_base + dld_cache.dld_desc.text_size);
713b725ae77Skettenis }
714b725ae77Skettenis 
715b725ae77Skettenis 
716b725ae77Skettenis /* Return the GOT value for the shared library in which ADDR belongs.  If
717b725ae77Skettenis    ADDR isn't in any known shared library, return zero.  */
718b725ae77Skettenis 
719b725ae77Skettenis CORE_ADDR
pa64_solib_get_got_by_pc(CORE_ADDR addr)720b725ae77Skettenis pa64_solib_get_got_by_pc (CORE_ADDR addr)
721b725ae77Skettenis {
722b725ae77Skettenis   struct so_list *so_list = so_list_head;
723b725ae77Skettenis   CORE_ADDR got_value = 0;
724b725ae77Skettenis 
725b725ae77Skettenis   while (so_list)
726b725ae77Skettenis     {
727b725ae77Skettenis       if (so_list->pa64_solib_desc.text_base <= addr
728b725ae77Skettenis 	  && ((so_list->pa64_solib_desc.text_base
729b725ae77Skettenis 	       + so_list->pa64_solib_desc.text_size)
730b725ae77Skettenis 	      > addr))
731b725ae77Skettenis 	{
732b725ae77Skettenis 	  got_value = so_list->pa64_solib_desc.linkage_ptr;
733b725ae77Skettenis 	  break;
734b725ae77Skettenis 	}
735b725ae77Skettenis       so_list = so_list->next;
736b725ae77Skettenis     }
737b725ae77Skettenis   return got_value;
738b725ae77Skettenis }
739b725ae77Skettenis 
740b725ae77Skettenis /* Return the address of the handle of the shared library in which ADDR
741b725ae77Skettenis    belongs.  If ADDR isn't in any known shared library, return zero.
742b725ae77Skettenis 
743b725ae77Skettenis    This function is used in hppa_fix_call_dummy in hppa-tdep.c.  */
744b725ae77Skettenis 
745b725ae77Skettenis CORE_ADDR
pa64_solib_get_solib_by_pc(CORE_ADDR addr)746b725ae77Skettenis pa64_solib_get_solib_by_pc (CORE_ADDR addr)
747b725ae77Skettenis {
748b725ae77Skettenis   struct so_list *so_list = so_list_head;
749b725ae77Skettenis   CORE_ADDR retval = 0;
750b725ae77Skettenis 
751b725ae77Skettenis   while (so_list)
752b725ae77Skettenis     {
753b725ae77Skettenis       if (so_list->pa64_solib_desc.text_base <= addr
754b725ae77Skettenis 	  && ((so_list->pa64_solib_desc.text_base
755b725ae77Skettenis 	       + so_list->pa64_solib_desc.text_size)
756b725ae77Skettenis 	      > addr))
757b725ae77Skettenis 	{
758b725ae77Skettenis 	  retval = so_list->pa64_solib_desc_addr;
759b725ae77Skettenis 	  break;
760b725ae77Skettenis 	}
761b725ae77Skettenis       so_list = so_list->next;
762b725ae77Skettenis     }
763b725ae77Skettenis   return retval;
764b725ae77Skettenis }
765b725ae77Skettenis 
766b725ae77Skettenis /* Dump information about all the currently loaded shared libraries.  */
767b725ae77Skettenis 
768b725ae77Skettenis static void
pa64_sharedlibrary_info_command(char * ignore,int from_tty)769b725ae77Skettenis pa64_sharedlibrary_info_command (char *ignore, int from_tty)
770b725ae77Skettenis {
771b725ae77Skettenis   struct so_list *so_list = so_list_head;
772b725ae77Skettenis 
773b725ae77Skettenis   if (exec_bfd == NULL)
774b725ae77Skettenis     {
775b725ae77Skettenis       printf_unfiltered ("No executable file.\n");
776b725ae77Skettenis       return;
777b725ae77Skettenis     }
778b725ae77Skettenis 
779b725ae77Skettenis   if (so_list == NULL)
780b725ae77Skettenis     {
781b725ae77Skettenis       printf_unfiltered ("No shared libraries loaded at this time.\n");
782b725ae77Skettenis       return;
783b725ae77Skettenis     }
784b725ae77Skettenis 
785b725ae77Skettenis   printf_unfiltered ("Shared Object Libraries\n");
786b725ae77Skettenis   printf_unfiltered ("   %-19s%-19s%-19s%-19s\n",
787b725ae77Skettenis 		     "  text start", "   text end",
788b725ae77Skettenis 		     "  data start", "   data end");
789b725ae77Skettenis   while (so_list)
790b725ae77Skettenis     {
791b725ae77Skettenis       unsigned int flags;
792b725ae77Skettenis 
793b725ae77Skettenis       printf_unfiltered ("%s", so_list->name);
794b725ae77Skettenis       if (so_list->objfile == NULL)
795b725ae77Skettenis 	printf_unfiltered ("  (symbols not loaded)");
796b725ae77Skettenis       if (so_list->loaded == 0)
797b725ae77Skettenis 	printf_unfiltered ("  (shared library unloaded)");
798b725ae77Skettenis       printf_unfiltered ("  %-18s",
799*11efff7fSkettenis 	hex_string_custom (so_list->pa64_solib_desc.linkage_ptr, 16));
800b725ae77Skettenis       printf_unfiltered ("\n");
801b725ae77Skettenis       printf_unfiltered ("%-18s",
802*11efff7fSkettenis 	hex_string_custom (so_list->pa64_solib_desc.text_base, 16));
803b725ae77Skettenis       printf_unfiltered (" %-18s",
804*11efff7fSkettenis 	hex_string_custom ((so_list->pa64_solib_desc.text_base
805*11efff7fSkettenis 			    + so_list->pa64_solib_desc.text_size), 16));
806b725ae77Skettenis       printf_unfiltered (" %-18s",
807*11efff7fSkettenis 	hex_string_custom (so_list->pa64_solib_desc.data_base, 16));
808b725ae77Skettenis       printf_unfiltered (" %-18s\n",
809*11efff7fSkettenis 	hex_string_custom ((so_list->pa64_solib_desc.data_base
810*11efff7fSkettenis 			    + so_list->pa64_solib_desc.data_size), 16));
811b725ae77Skettenis       so_list = so_list->next;
812b725ae77Skettenis     }
813b725ae77Skettenis }
814b725ae77Skettenis 
815b725ae77Skettenis /* Load up one or more shared libraries as directed by the user.  */
816b725ae77Skettenis 
817b725ae77Skettenis static void
pa64_solib_sharedlibrary_command(char * args,int from_tty)818b725ae77Skettenis pa64_solib_sharedlibrary_command (char *args, int from_tty)
819b725ae77Skettenis {
820b725ae77Skettenis   dont_repeat ();
821b725ae77Skettenis   pa64_solib_add (args, from_tty, (struct target_ops *) 0, 1);
822b725ae77Skettenis }
823b725ae77Skettenis 
824b725ae77Skettenis /* Return the name of the shared library containing ADDR or NULL if ADDR
825b725ae77Skettenis    is not contained in any known shared library.  */
826b725ae77Skettenis 
827b725ae77Skettenis char *
pa64_solib_address(CORE_ADDR addr)828b725ae77Skettenis pa64_solib_address (CORE_ADDR addr)
829b725ae77Skettenis {
830b725ae77Skettenis   struct so_list *so = so_list_head;
831b725ae77Skettenis 
832b725ae77Skettenis   while (so)
833b725ae77Skettenis     {
834b725ae77Skettenis       /* Is this address within this shlib's text range?  If so,
835b725ae77Skettenis 	 return the shlib's name.  */
836b725ae77Skettenis       if (addr >= so->pa64_solib_desc.text_base
837b725ae77Skettenis 	  && addr < (so->pa64_solib_desc.text_base
838b725ae77Skettenis 		     | so->pa64_solib_desc.text_size))
839b725ae77Skettenis 	return so->name;
840b725ae77Skettenis 
841b725ae77Skettenis       /* Nope, keep looking... */
842b725ae77Skettenis       so = so->next;
843b725ae77Skettenis     }
844b725ae77Skettenis 
845b725ae77Skettenis   /* No, we couldn't prove that the address is within a shlib. */
846b725ae77Skettenis   return NULL;
847b725ae77Skettenis }
848b725ae77Skettenis 
849b725ae77Skettenis /* We are killing the inferior and restarting the program.  */
850b725ae77Skettenis 
851b725ae77Skettenis void
pa64_solib_restart(void)852b725ae77Skettenis pa64_solib_restart (void)
853b725ae77Skettenis {
854b725ae77Skettenis   struct so_list *sl = so_list_head;
855b725ae77Skettenis 
856b725ae77Skettenis   /* Before the shlib info vanishes, use it to disable any breakpoints
857b725ae77Skettenis      that may still be active in those shlibs.  */
858b725ae77Skettenis   disable_breakpoints_in_shlibs (0);
859b725ae77Skettenis 
860b725ae77Skettenis   /* Discard all the shlib descriptors.  */
861b725ae77Skettenis   while (sl)
862b725ae77Skettenis     {
863b725ae77Skettenis       struct so_list *next_sl = sl->next;
864b725ae77Skettenis       xfree (sl);
865b725ae77Skettenis       sl = next_sl;
866b725ae77Skettenis     }
867b725ae77Skettenis   so_list_head = NULL;
868b725ae77Skettenis 
869b725ae77Skettenis   pa64_solib_total_st_size = (LONGEST) 0;
870b725ae77Skettenis   pa64_solib_st_size_threshold_exceeded = 0;
871b725ae77Skettenis 
872b725ae77Skettenis   dld_cache.is_valid = 0;
873b725ae77Skettenis   dld_cache.have_read_dld_descriptor = 0;
874b725ae77Skettenis   dld_cache.dld_flags_addr = 0;
875b725ae77Skettenis   dld_cache.load_map = 0;
876b725ae77Skettenis   dld_cache.load_map_addr = 0;
877b725ae77Skettenis   dld_cache.dld_desc.data_base = 0;
878b725ae77Skettenis   dld_cache.dld_flags = 0;
879b725ae77Skettenis   dld_cache.dyninfo_sect = 0;
880b725ae77Skettenis }
881b725ae77Skettenis 
882b725ae77Skettenis void
_initialize_pa64_solib(void)883b725ae77Skettenis _initialize_pa64_solib (void)
884b725ae77Skettenis {
885b725ae77Skettenis   add_com ("sharedlibrary", class_files, pa64_solib_sharedlibrary_command,
886b725ae77Skettenis 	   "Load shared object library symbols for files matching REGEXP.");
887b725ae77Skettenis   add_info ("sharedlibrary", pa64_sharedlibrary_info_command,
888b725ae77Skettenis 	    "Status of loaded shared object libraries.");
889b725ae77Skettenis 
890*11efff7fSkettenis   deprecated_add_show_from_set
891b725ae77Skettenis     (add_set_cmd ("auto-solib-add", class_support, var_boolean,
892b725ae77Skettenis 		  (char *) &auto_solib_add,
893b725ae77Skettenis 		  "Set autoloading of shared library symbols.\n\
894b725ae77Skettenis If \"on\", symbols from all shared object libraries will be loaded\n\
895b725ae77Skettenis automatically when the inferior begins execution, when the dynamic linker\n\
896b725ae77Skettenis informs gdb that a new library has been loaded, or when attaching to the\n\
897b725ae77Skettenis inferior.  Otherwise, symbols must be loaded manually, using `sharedlibrary'.",
898b725ae77Skettenis 		  &setlist),
899b725ae77Skettenis      &showlist);
900b725ae77Skettenis 
901*11efff7fSkettenis   deprecated_add_show_from_set
902b725ae77Skettenis     (add_set_cmd ("auto-solib-limit", class_support, var_zinteger,
903b725ae77Skettenis 		  (char *) &auto_solib_limit,
904b725ae77Skettenis 		  "Set threshold (in Mb) for autoloading shared library symbols.\n\
905b725ae77Skettenis When shared library autoloading is enabled, new libraries will be loaded\n\
906b725ae77Skettenis only until the total size of shared library symbols exceeds this\n\
907b725ae77Skettenis threshold in megabytes.  Is ignored when using `sharedlibrary'.",
908b725ae77Skettenis 		  &setlist),
909b725ae77Skettenis      &showlist);
910b725ae77Skettenis 
911b725ae77Skettenis   /* ??rehrauer: On HP-UX, the kernel parameter MAXDSIZ limits how
912b725ae77Skettenis      much data space a process can use.  We ought to be reading
913b725ae77Skettenis      MAXDSIZ and setting auto_solib_limit to some large fraction of
914b725ae77Skettenis      that value.  If not that, we maybe ought to be setting it smaller
915b725ae77Skettenis      than the default for MAXDSIZ (that being 64Mb, I believe).
916b725ae77Skettenis      However, [1] this threshold is only crudely approximated rather
917b725ae77Skettenis      than actually measured, and [2] 50 Mbytes is too small for
918b725ae77Skettenis      debugging gdb itself.  Thus, the arbitrary 100 figure.  */
919b725ae77Skettenis   auto_solib_limit = 100;	/* Megabytes */
920b725ae77Skettenis 
921b725ae77Skettenis   pa64_solib_restart ();
922b725ae77Skettenis }
923b725ae77Skettenis 
924b725ae77Skettenis /* Get some HPUX-specific data from a shared lib.  */
925b725ae77Skettenis CORE_ADDR
so_lib_thread_start_addr(struct so_list * so)926b725ae77Skettenis so_lib_thread_start_addr (struct so_list *so)
927b725ae77Skettenis {
928b725ae77Skettenis   return so->pa64_solib_desc.tls_start_addr;
929b725ae77Skettenis }
930b725ae77Skettenis 
931b725ae77Skettenis /* Read the dynamic linker's internal shared library descriptor.
932b725ae77Skettenis 
933b725ae77Skettenis    This must happen after dld starts running, so we can't do it in
934b725ae77Skettenis    read_dynamic_info.  Record the fact that we have loaded the
935b725ae77Skettenis    descriptor.  If the library is archive bound, then return zero, else
936b725ae77Skettenis    return nonzero.  */
937b725ae77Skettenis 
938b725ae77Skettenis static int
read_dld_descriptor(struct target_ops * target,int readsyms)939b725ae77Skettenis read_dld_descriptor (struct target_ops *target, int readsyms)
940b725ae77Skettenis {
941b725ae77Skettenis   char *dll_path;
942b725ae77Skettenis   asection *dyninfo_sect;
943b725ae77Skettenis 
944b725ae77Skettenis   /* If necessary call read_dynamic_info to extract the contents of the
945b725ae77Skettenis      .dynamic section from the shared library.  */
946b725ae77Skettenis   if (!dld_cache.is_valid)
947b725ae77Skettenis     {
948b725ae77Skettenis       if (symfile_objfile == NULL)
949b725ae77Skettenis 	error ("No object file symbols.");
950b725ae77Skettenis 
951b725ae77Skettenis       dyninfo_sect = bfd_get_section_by_name (symfile_objfile->obfd,
952b725ae77Skettenis 					      ".dynamic");
953b725ae77Skettenis       if (!dyninfo_sect)
954b725ae77Skettenis 	{
955b725ae77Skettenis 	  return 0;
956b725ae77Skettenis 	}
957b725ae77Skettenis 
958b725ae77Skettenis       if (!read_dynamic_info (dyninfo_sect, &dld_cache))
959b725ae77Skettenis 	error ("Unable to read in .dynamic section information.");
960b725ae77Skettenis     }
961b725ae77Skettenis 
962b725ae77Skettenis   /* Read the load map pointer.  */
963b725ae77Skettenis   if (target_read_memory (dld_cache.load_map_addr,
964b725ae77Skettenis 			  (char*) &dld_cache.load_map,
965b725ae77Skettenis 			  sizeof(dld_cache.load_map))
966b725ae77Skettenis       != 0)
967b725ae77Skettenis     {
968b725ae77Skettenis       error ("Error while reading in load map pointer.");
969b725ae77Skettenis     }
970b725ae77Skettenis 
971b725ae77Skettenis   /* Read in the dld load module descriptor */
972b725ae77Skettenis   if (dlgetmodinfo (-1,
973b725ae77Skettenis 		    &dld_cache.dld_desc,
974b725ae77Skettenis 		    sizeof(dld_cache.dld_desc),
975b725ae77Skettenis 		    pa64_target_read_memory,
976b725ae77Skettenis 		    0,
977b725ae77Skettenis 		    dld_cache.load_map)
978b725ae77Skettenis       == 0)
979b725ae77Skettenis     {
980b725ae77Skettenis       error ("Error trying to get information about dynamic linker.");
981b725ae77Skettenis     }
982b725ae77Skettenis 
983b725ae77Skettenis   /* Indicate that we have loaded the dld descriptor.  */
984b725ae77Skettenis   dld_cache.have_read_dld_descriptor = 1;
985b725ae77Skettenis 
986b725ae77Skettenis   /* Add dld.sl to the list of known shared libraries so that we can
987b725ae77Skettenis      do unwind, etc.
988b725ae77Skettenis 
989b725ae77Skettenis      ?!? This may not be correct.  Consider of dld.sl contains symbols
990b725ae77Skettenis      which are also referenced/defined by the user program or some user
991b725ae77Skettenis      shared library.  We need to make absolutely sure that we do not
992b725ae77Skettenis      pollute the namespace from GDB's point of view.  */
993b725ae77Skettenis   dll_path = dlgetname (&dld_cache.dld_desc,
994b725ae77Skettenis 			sizeof(dld_cache.dld_desc),
995b725ae77Skettenis 			pa64_target_read_memory,
996b725ae77Skettenis 			0,
997b725ae77Skettenis 			dld_cache.load_map);
998b725ae77Skettenis   add_to_solist(0, dll_path, readsyms, &dld_cache.dld_desc, 0, target);
999b725ae77Skettenis 
1000b725ae77Skettenis   return 1;
1001b725ae77Skettenis }
1002b725ae77Skettenis 
1003b725ae77Skettenis /* Read the .dynamic section and extract the information of interest,
1004b725ae77Skettenis    which is stored in dld_cache.  The routine elf_locate_base in solib.c
1005b725ae77Skettenis    was used as a model for this.  */
1006b725ae77Skettenis 
1007b725ae77Skettenis static int
read_dynamic_info(asection * dyninfo_sect,dld_cache_t * dld_cache_p)1008b725ae77Skettenis read_dynamic_info (asection *dyninfo_sect, dld_cache_t *dld_cache_p)
1009b725ae77Skettenis {
1010b725ae77Skettenis   char *buf;
1011b725ae77Skettenis   char *bufend;
1012b725ae77Skettenis   CORE_ADDR dyninfo_addr;
1013b725ae77Skettenis   int dyninfo_sect_size;
1014b725ae77Skettenis   CORE_ADDR entry_addr;
1015b725ae77Skettenis 
1016b725ae77Skettenis   /* Read in .dynamic section, silently ignore errors.  */
1017b725ae77Skettenis   dyninfo_addr = bfd_section_vma (symfile_objfile->obfd, dyninfo_sect);
1018b725ae77Skettenis   dyninfo_sect_size = bfd_section_size (exec_bfd, dyninfo_sect);
1019b725ae77Skettenis   buf = alloca (dyninfo_sect_size);
1020b725ae77Skettenis   if (target_read_memory (dyninfo_addr, buf, dyninfo_sect_size))
1021b725ae77Skettenis     return 0;
1022b725ae77Skettenis 
1023b725ae77Skettenis   /* Scan the .dynamic section and record the items of interest.
1024b725ae77Skettenis      In particular, DT_HP_DLD_FLAGS */
1025b725ae77Skettenis   for (bufend = buf + dyninfo_sect_size, entry_addr = dyninfo_addr;
1026b725ae77Skettenis        buf < bufend;
1027b725ae77Skettenis        buf += sizeof (Elf64_Dyn), entry_addr += sizeof (Elf64_Dyn))
1028b725ae77Skettenis     {
1029b725ae77Skettenis       Elf64_Dyn *x_dynp = (Elf64_Dyn*)buf;
1030b725ae77Skettenis       Elf64_Sxword dyn_tag;
1031b725ae77Skettenis       CORE_ADDR	dyn_ptr;
1032b725ae77Skettenis       char *pbuf;
1033b725ae77Skettenis 
1034b725ae77Skettenis       pbuf = alloca (TARGET_PTR_BIT / HOST_CHAR_BIT);
1035b725ae77Skettenis       dyn_tag = bfd_h_get_64 (symfile_objfile->obfd,
1036b725ae77Skettenis 			      (bfd_byte*) &x_dynp->d_tag);
1037b725ae77Skettenis 
1038b725ae77Skettenis       /* We can't use a switch here because dyn_tag is 64 bits and HP's
1039b725ae77Skettenis 	 lame comiler does not handle 64bit items in switch statements.  */
1040b725ae77Skettenis       if (dyn_tag == DT_NULL)
1041b725ae77Skettenis 	break;
1042b725ae77Skettenis       else if (dyn_tag == DT_HP_DLD_FLAGS)
1043b725ae77Skettenis 	{
1044b725ae77Skettenis 	  /* Set dld_flags_addr and dld_flags in *dld_cache_p */
1045b725ae77Skettenis 	  dld_cache_p->dld_flags_addr = entry_addr + offsetof(Elf64_Dyn, d_un);
1046b725ae77Skettenis 	  if (target_read_memory (dld_cache_p->dld_flags_addr,
1047b725ae77Skettenis 	  			  (char*) &dld_cache_p->dld_flags,
1048b725ae77Skettenis 				  sizeof(dld_cache_p->dld_flags))
1049b725ae77Skettenis 	      != 0)
1050b725ae77Skettenis 	    {
1051b725ae77Skettenis 	      error ("Error while reading in .dynamic section of the program.");
1052b725ae77Skettenis 	    }
1053b725ae77Skettenis 	}
1054b725ae77Skettenis       else if (dyn_tag == DT_HP_LOAD_MAP)
1055b725ae77Skettenis 	{
1056b725ae77Skettenis 	  /* Dld will place the address of the load map at load_map_addr
1057b725ae77Skettenis 	     after it starts running.  */
1058b725ae77Skettenis 	  if (target_read_memory (entry_addr + offsetof(Elf64_Dyn,
1059b725ae77Skettenis 							d_un.d_ptr),
1060b725ae77Skettenis 				  (char*) &dld_cache_p->load_map_addr,
1061b725ae77Skettenis 				  sizeof(dld_cache_p->load_map_addr))
1062b725ae77Skettenis 	      != 0)
1063b725ae77Skettenis 	    {
1064b725ae77Skettenis 	      error ("Error while reading in .dynamic section of the program.");
1065b725ae77Skettenis 	    }
1066b725ae77Skettenis 	}
1067b725ae77Skettenis       else
1068b725ae77Skettenis 	{
1069b725ae77Skettenis 	  /* tag is not of interest */
1070b725ae77Skettenis 	}
1071b725ae77Skettenis     }
1072b725ae77Skettenis 
1073b725ae77Skettenis   /* Record other information and set is_valid to 1. */
1074b725ae77Skettenis   dld_cache_p->dyninfo_sect = dyninfo_sect;
1075b725ae77Skettenis 
1076b725ae77Skettenis   /* Verify that we read in required info.  These fields are re-set to zero
1077b725ae77Skettenis      in pa64_solib_restart.  */
1078b725ae77Skettenis 
1079b725ae77Skettenis   if (dld_cache_p->dld_flags_addr != 0 && dld_cache_p->load_map_addr != 0)
1080b725ae77Skettenis     dld_cache_p->is_valid = 1;
1081b725ae77Skettenis   else
1082b725ae77Skettenis     return 0;
1083b725ae77Skettenis 
1084b725ae77Skettenis   return 1;
1085b725ae77Skettenis }
1086b725ae77Skettenis 
1087b725ae77Skettenis /* Wrapper for target_read_memory to make dlgetmodinfo happy.  */
1088b725ae77Skettenis 
1089b725ae77Skettenis static void *
pa64_target_read_memory(void * buffer,CORE_ADDR ptr,size_t bufsiz,int ident)1090b725ae77Skettenis pa64_target_read_memory (void *buffer, CORE_ADDR ptr, size_t bufsiz, int ident)
1091b725ae77Skettenis {
1092b725ae77Skettenis   if (target_read_memory (ptr, buffer, bufsiz) != 0)
1093b725ae77Skettenis     return 0;
1094b725ae77Skettenis   return buffer;
1095b725ae77Skettenis }
1096b725ae77Skettenis 
1097b725ae77Skettenis /* Called from handle_dynlink_load_event and pa64_solib_add to add
1098b725ae77Skettenis    a shared library to so_list_head list and possibly to read in the
1099b725ae77Skettenis    debug information for the library.
1100b725ae77Skettenis 
1101b725ae77Skettenis    If load_module_desc_p is NULL, then the load module descriptor must
1102b725ae77Skettenis    be read from the inferior process at the address load_module_desc_addr.  */
1103b725ae77Skettenis 
1104b725ae77Skettenis static void
add_to_solist(int from_tty,char * dll_path,int readsyms,struct load_module_desc * load_module_desc_p,CORE_ADDR load_module_desc_addr,struct target_ops * target)1105b725ae77Skettenis add_to_solist (int from_tty, char *dll_path, int readsyms,
1106b725ae77Skettenis 	       struct load_module_desc *load_module_desc_p,
1107b725ae77Skettenis 	       CORE_ADDR load_module_desc_addr, struct target_ops *target)
1108b725ae77Skettenis {
1109b725ae77Skettenis   struct so_list *new_so, *so_list_tail;
1110b725ae77Skettenis   int pa64_solib_st_size_threshhold_exceeded;
1111b725ae77Skettenis   LONGEST st_size;
1112b725ae77Skettenis 
1113b725ae77Skettenis   if (symfile_objfile == NULL)
1114b725ae77Skettenis     return;
1115b725ae77Skettenis 
1116b725ae77Skettenis   so_list_tail = so_list_head;
1117b725ae77Skettenis   /* Find the end of the list of shared objects.  */
1118b725ae77Skettenis   while (so_list_tail && so_list_tail->next)
1119b725ae77Skettenis     {
1120b725ae77Skettenis       if (strcmp (so_list_tail->name, dll_path) == 0)
1121b725ae77Skettenis 	return;
1122b725ae77Skettenis       so_list_tail = so_list_tail->next;
1123b725ae77Skettenis     }
1124b725ae77Skettenis 
1125b725ae77Skettenis   if (so_list_tail && strcmp (so_list_tail->name, dll_path) == 0)
1126b725ae77Skettenis     return;
1127b725ae77Skettenis 
1128b725ae77Skettenis   /* Add the shared library to the so_list_head list */
1129b725ae77Skettenis   new_so = (struct so_list *) xmalloc (sizeof (struct so_list));
1130b725ae77Skettenis   memset ((char *)new_so, 0, sizeof (struct so_list));
1131b725ae77Skettenis   if (so_list_head == NULL)
1132b725ae77Skettenis     {
1133b725ae77Skettenis       so_list_head = new_so;
1134b725ae77Skettenis       so_list_tail = new_so;
1135b725ae77Skettenis     }
1136b725ae77Skettenis   else
1137b725ae77Skettenis     {
1138b725ae77Skettenis       so_list_tail->next = new_so;
1139b725ae77Skettenis       so_list_tail = new_so;
1140b725ae77Skettenis     }
1141b725ae77Skettenis 
1142b725ae77Skettenis   /* Initialize the new_so */
1143b725ae77Skettenis   if (load_module_desc_p)
1144b725ae77Skettenis     {
1145b725ae77Skettenis       new_so->pa64_solib_desc = *load_module_desc_p;
1146b725ae77Skettenis     }
1147b725ae77Skettenis   else
1148b725ae77Skettenis     {
1149b725ae77Skettenis       if (target_read_memory (load_module_desc_addr,
1150b725ae77Skettenis 			      (char*) &new_so->pa64_solib_desc,
1151b725ae77Skettenis 			      sizeof(struct load_module_desc))
1152b725ae77Skettenis 	  != 0)
1153b725ae77Skettenis       {
1154b725ae77Skettenis 	error ("Error while reading in dynamic library %s", dll_path);
1155b725ae77Skettenis       }
1156b725ae77Skettenis     }
1157b725ae77Skettenis 
1158b725ae77Skettenis   new_so->pa64_solib_desc_addr = load_module_desc_addr;
1159b725ae77Skettenis   new_so->loaded = 1;
1160b725ae77Skettenis   new_so->name = obsavestring (dll_path, strlen(dll_path),
1161b725ae77Skettenis 			       &symfile_objfile->objfile_obstack);
1162b725ae77Skettenis 
1163b725ae77Skettenis   /* If we are not going to load the library, tell the user if we
1164b725ae77Skettenis      haven't already and return.  */
1165b725ae77Skettenis 
1166b725ae77Skettenis   st_size = pa64_solib_sizeof_symbol_table (dll_path);
1167b725ae77Skettenis   pa64_solib_st_size_threshhold_exceeded =
1168b725ae77Skettenis        !from_tty
1169b725ae77Skettenis     && readsyms
1170b725ae77Skettenis     && (  (st_size + pa64_solib_total_st_size)
1171b725ae77Skettenis 	> (auto_solib_limit * (LONGEST) (1024 * 1024)));
1172b725ae77Skettenis   if (pa64_solib_st_size_threshhold_exceeded)
1173b725ae77Skettenis     {
1174b725ae77Skettenis       pa64_solib_add_solib_objfile (new_so, dll_path, from_tty, 1);
1175b725ae77Skettenis       return;
1176b725ae77Skettenis     }
1177b725ae77Skettenis 
1178b725ae77Skettenis   /* Now read in debug info. */
1179b725ae77Skettenis   pa64_solib_total_st_size += st_size;
1180b725ae77Skettenis 
1181b725ae77Skettenis   /* This fills in new_so->objfile, among others. */
1182b725ae77Skettenis   pa64_solib_load_symbols (new_so,
1183b725ae77Skettenis 			   dll_path,
1184b725ae77Skettenis 			   from_tty,
1185b725ae77Skettenis 			   0,
1186b725ae77Skettenis 			   target);
1187b725ae77Skettenis   return;
1188b725ae77Skettenis }
1189b725ae77Skettenis 
1190b725ae77Skettenis 
1191b725ae77Skettenis /*
1192b725ae77Skettenis    LOCAL FUNCTION
1193b725ae77Skettenis 
1194b725ae77Skettenis    bfd_lookup_symbol -- lookup the value for a specific symbol
1195b725ae77Skettenis 
1196b725ae77Skettenis    SYNOPSIS
1197b725ae77Skettenis 
1198b725ae77Skettenis    CORE_ADDR bfd_lookup_symbol (bfd *abfd, char *symname)
1199b725ae77Skettenis 
1200b725ae77Skettenis    DESCRIPTION
1201b725ae77Skettenis 
1202b725ae77Skettenis    An expensive way to lookup the value of a single symbol for
1203b725ae77Skettenis    bfd's that are only temporary anyway.  This is used by the
1204b725ae77Skettenis    shared library support to find the address of the debugger
1205b725ae77Skettenis    interface structures in the shared library.
1206b725ae77Skettenis 
1207b725ae77Skettenis    Note that 0 is specifically allowed as an error return (no
1208b725ae77Skettenis    such symbol).
1209b725ae77Skettenis  */
1210b725ae77Skettenis 
1211b725ae77Skettenis static CORE_ADDR
bfd_lookup_symbol(bfd * abfd,char * symname)1212b725ae77Skettenis bfd_lookup_symbol (bfd *abfd, char *symname)
1213b725ae77Skettenis {
1214b725ae77Skettenis   unsigned int storage_needed;
1215b725ae77Skettenis   asymbol *sym;
1216b725ae77Skettenis   asymbol **symbol_table;
1217b725ae77Skettenis   unsigned int number_of_symbols;
1218b725ae77Skettenis   unsigned int i;
1219b725ae77Skettenis   struct cleanup *back_to;
1220b725ae77Skettenis   CORE_ADDR symaddr = 0;
1221b725ae77Skettenis 
1222b725ae77Skettenis   storage_needed = bfd_get_symtab_upper_bound (abfd);
1223b725ae77Skettenis 
1224b725ae77Skettenis   if (storage_needed > 0)
1225b725ae77Skettenis     {
1226b725ae77Skettenis       symbol_table = (asymbol **) xmalloc (storage_needed);
1227b725ae77Skettenis       back_to = make_cleanup (xfree, symbol_table);
1228b725ae77Skettenis       number_of_symbols = bfd_canonicalize_symtab (abfd, symbol_table);
1229b725ae77Skettenis 
1230b725ae77Skettenis       for (i = 0; i < number_of_symbols; i++)
1231b725ae77Skettenis 	{
1232b725ae77Skettenis 	  sym = *symbol_table++;
1233b725ae77Skettenis 	  if (strcmp (sym->name, symname) == 0)
1234b725ae77Skettenis 	    {
1235b725ae77Skettenis 	      /* Bfd symbols are section relative. */
1236b725ae77Skettenis 	      symaddr = sym->value + sym->section->vma;
1237b725ae77Skettenis 	      break;
1238b725ae77Skettenis 	    }
1239b725ae77Skettenis 	}
1240b725ae77Skettenis       do_cleanups (back_to);
1241b725ae77Skettenis     }
1242b725ae77Skettenis   return (symaddr);
1243b725ae77Skettenis }
1244b725ae77Skettenis 
1245