* config/sparc/tm-sun4sol2.h, dbxread.c: Rename
[external/binutils.git] / gdb / somsolib.c
1 /* Handle HP SOM shared libraries for GDB, the GNU Debugger.
2    Copyright 1993 Free Software Foundation, Inc.
3
4 This file is part of GDB.
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19
20 Written by the Center for Software Science at the Univerity of Utah
21 and by Cygnus Support.  */
22
23
24 #include "defs.h"
25
26 #include "frame.h"
27 #include "bfd.h"
28 #include "som.h"
29 #include "libhppa.h"
30 #include "gdbcore.h"
31 #include "symtab.h"
32 #include "breakpoint.h"
33 #include "symfile.h"
34 #include "objfiles.h"
35 #include "inferior.h"
36
37 /* TODO:
38
39    * Relocate data addresses in the shared library.
40
41    * Most of this code should work for hp300 shared libraries.  Does
42    anyone care enough to weed out any SOM-isms.
43
44    * Do we need/want a command to load a shared library?
45
46    * Support for hpux8 dynamic linker.
47
48    * Support for tracking user calls to dld_load, dld_unload.  */
49
50 /* The basic structure which describes a dynamically loaded object.  This
51    data structure is private to the dynamic linker and isn't found in
52    any HPUX include file.  */
53
54 struct som_solib_mapped_entry
55 {
56   /* The name of the library.  */
57   char *name;
58
59   /* Version of this structure (it is expected to change again in hpux10).  */
60   unsigned char struct_version;
61
62   /* Binding mode for this library.  */
63   unsigned char bind_mode;
64
65   /* Version of this library.  */
66   short library_version;
67
68   /* Start of text address, link-time text location, end of text address.  */
69   CORE_ADDR text_addr;
70   CORE_ADDR text_link_addr;
71   CORE_ADDR text_end;
72
73   /* Start of data, start of bss and end of data.  */
74   CORE_ADDR data_start;
75   CORE_ADDR bss_start;
76   CORE_ADDR data_end;
77
78   /* Value of linkage pointer (%r19).  */
79   CORE_ADDR got_value;
80
81   /* Next entry.  */
82   struct som_solib_mapped_entry *next;
83
84   /* There are other fields, but I don't have information as to what is
85      contained in them.  */
86 };
87
88 /* A structure to keep track of all the known shared objects.  */
89 struct so_list
90 {
91   struct som_solib_mapped_entry som_solib;
92   struct objfile *objfile;
93   bfd *abfd;
94   struct section_table *sections;
95   struct section_table *sections_end;
96   struct so_list *next;
97 };
98
99 static struct so_list *so_list_head;
100
101 static void som_sharedlibrary_info_command PARAMS ((char *, int));
102
103 /* Add symbols from shared libraries into the symtab list.  */
104
105 void
106 som_solib_add (arg_string, from_tty, target)
107      char *arg_string;
108      int from_tty;
109      struct target_ops *target;
110 {
111   struct minimal_symbol *msymbol;
112   struct so_list *so_list_tail;
113   CORE_ADDR addr;
114   asection *shlib_info;
115   int status;
116   unsigned int dld_flags;
117   char buf[4];
118
119   /* If we're debugging a core file, or have attached to a running
120      process, then som_solib_create_inferior_hook will not have been
121      called.
122
123      We need to first determine if we're dealing with a dynamically
124      linked executable.  If not, then return without an error or warning.
125
126      We also need to examine __dld_flags to determine if the shared library
127      list is valid and to determine if the libraries have been privately
128      mapped.  */
129   if (symfile_objfile == NULL)
130     return;
131
132   /* First see if the objfile was dynamically linked.  */
133   shlib_info = bfd_get_section_by_name (symfile_objfile->obfd, "$SHLIB_INFO$");
134   if (!shlib_info)
135     return;
136
137   /* It's got a $SHLIB_INFO$ section, make sure it's not empty.  */
138   if (bfd_section_size (symfile_objfile->obfd, shlib_info) == 0)
139     return;
140
141   msymbol = lookup_minimal_symbol ("__dld_flags", NULL, NULL);
142   if (msymbol == NULL)
143     {
144       error ("Unable to find __dld_flags symbol in object file.\n");
145       return;
146     }
147
148   addr = SYMBOL_VALUE_ADDRESS (msymbol);
149   /* Read the current contents.  */
150   status = target_read_memory (addr, buf, 4);
151   if (status != 0)
152     {
153       error ("Unable to read __dld_flags\n");
154       return;
155     }
156   dld_flags = extract_unsigned_integer (buf, 4);
157
158   /* __dld_list may not be valid.  If it's not valid tell the user.  */
159   if ((dld_flags & 4) == 0)
160     {
161       error ("__dld_list is not valid according to __dld_flags.\n");
162       return;
163     }
164
165   /* If the libraries were not mapped private, warn the user.  */
166   if ((dld_flags & 1) == 0)
167     warning ("The shared libraries were not privately mapped; setting a\nbreakpoint in a shared library will not work until you rerun the program.\n");
168
169   msymbol = lookup_minimal_symbol ("__dld_list", NULL, NULL);
170   if (!msymbol)
171     {
172       /* Older crt0.o files (hpux8) don't have __dld_list as a symbol,
173          but the data is still available if you know where to look.  */
174       msymbol = lookup_minimal_symbol ("__dld_flags", NULL, NULL);
175       if (!msymbol)
176         {
177           error ("Unable to find dynamic library list.\n");
178           return;
179         }
180       addr = SYMBOL_VALUE_ADDRESS (msymbol) - 8;
181     }
182   else
183     addr = SYMBOL_VALUE_ADDRESS (msymbol);
184
185   status = target_read_memory (addr, buf, 4);
186   if (status != 0)
187     {
188       error ("Unable to find dynamic library list.\n");
189       return;
190     }
191
192   addr = extract_unsigned_integer (buf, 4);
193
194   /* If addr is zero, then we're using an old dynamic loader which
195      doesn't maintain __dld_list.  We'll have to use a completely
196      different approach to get shared library information.  */
197   if (addr == 0)
198     goto old_dld;
199
200   /* Using the information in __dld_list is the preferred method
201      to get at shared library information.  It doesn't depend on
202      any functions in /usr/lib/end.o and has a chance of working
203      with hpux10 when it is released.  */
204   status = target_read_memory (addr, buf, 4);
205   if (status != 0)
206     {
207       error ("Unable to find dynamic library list.\n");
208       return;
209     }
210
211   /* addr now holds the address of the first entry in the dynamic
212      library list.  */
213   addr = extract_unsigned_integer (buf, 4);
214
215   /* Now that we have a pointer to the dynamic library list, walk
216      through it and add the symbols for each library.
217
218      Skip the first entry since it's our executable.  */
219   status = target_read_memory (addr + 36, buf, 4);
220   if (status != 0)
221     goto err;
222
223   addr = extract_unsigned_integer (buf, 4);
224
225   so_list_tail = so_list_head;
226   /* Find the end of the list of shared objects.  */
227   while (so_list_tail && so_list_tail->next)
228     so_list_tail = so_list_tail->next;
229
230   while (1)
231     {
232       CORE_ADDR name_addr, text_addr;
233       unsigned int name_len;
234       char *name;
235       struct so_list *new_so;
236       struct section_table *p;
237
238       if (addr == 0)
239         break;
240
241       /* Get a pointer to the name of this library.  */
242       status = target_read_memory (addr, buf, 4);
243       if (status != 0)
244         goto err;
245
246       name_addr = extract_unsigned_integer (buf, 4);
247       name_len = 0;
248       while (1)
249         {
250           target_read_memory (name_addr + name_len, buf, 1);
251           if (status != 0)
252             goto err;
253
254           name_len++;
255           if (*buf == '\0')
256             break;
257         }
258       name = alloca (name_len);
259       status = target_read_memory (name_addr, name, name_len);
260       if (status != 0)
261         goto err;
262
263       name = obsavestring (name, name_len - 1,
264                            &symfile_objfile->symbol_obstack);
265
266       status = target_read_memory (addr + 8, buf, 4);
267       if (status != 0)
268         goto err;
269
270       text_addr = extract_unsigned_integer (buf, 4);
271
272
273       new_so = (struct so_list *) malloc (sizeof (struct so_list));
274       memset ((char *)new_so, 0, sizeof (struct so_list));
275       if (so_list_head == NULL)
276         {
277           so_list_head = new_so;
278           so_list_tail = new_so;
279         }
280       else
281         {
282           so_list_tail->next = new_so;
283           so_list_tail = new_so;
284         }
285
286       /* Fill in all the entries in GDB's shared library list.  */
287       new_so->som_solib.name = name;
288       status = target_read_memory (addr + 4, buf, 4);
289       if (status != 0)
290         goto err;
291
292       new_so->som_solib.struct_version = extract_unsigned_integer (buf + 3, 1);
293       new_so->som_solib.bind_mode = extract_unsigned_integer (buf + 2, 1);
294       new_so->som_solib.library_version = extract_unsigned_integer (buf, 2);
295       new_so->som_solib.text_addr = text_addr;
296
297       status = target_read_memory (addr + 12, buf, 4);
298       if (status != 0)
299         goto err;
300
301       new_so->som_solib.text_link_addr = extract_unsigned_integer (buf, 4);
302
303       status = target_read_memory (addr + 16, buf, 4);
304       if (status != 0)
305         goto err;
306
307       new_so->som_solib.text_end = extract_unsigned_integer (buf, 4);
308
309       status = target_read_memory (addr + 20, buf, 4);
310       if (status != 0)
311         goto err;
312
313       new_so->som_solib.data_start = extract_unsigned_integer (buf, 4);
314
315       status = target_read_memory (addr + 24, buf, 4);
316       if (status != 0)
317         goto err;
318
319       new_so->som_solib.bss_start = extract_unsigned_integer (buf, 4);
320
321       status = target_read_memory (addr + 28, buf, 4);
322       if (status != 0)
323         goto err;
324
325       new_so->som_solib.data_end = extract_unsigned_integer (buf, 4);
326
327       status = target_read_memory (addr + 32, buf, 4);
328       if (status != 0)
329         goto err;
330
331       new_so->som_solib.got_value = extract_unsigned_integer (buf, 4);
332
333       status = target_read_memory (addr + 36, buf, 4);
334       if (status != 0)
335         goto err;
336
337       new_so->som_solib.next = (void *)extract_unsigned_integer (buf, 4);
338       addr = (CORE_ADDR)new_so->som_solib.next;
339
340       new_so->objfile = symbol_file_add (name, from_tty, text_addr, 0, 0, 0);
341       new_so->abfd = bfd_openr (name, gnutarget);
342       new_so->abfd->cacheable = true;
343
344       if (!bfd_check_format (new_so->abfd, bfd_object))
345         {
346           error ("\"%s\": not in executable format: %s.",
347                  name, bfd_errmsg (bfd_get_error ()));
348         }
349
350       /* Now we need to build a section table for this library since
351          we might be debugging a core file from a dynamically linked
352          executable in which the libraries were not privately mapped.  */
353       if (build_section_table (new_so->abfd,
354                                &new_so->sections,
355                                &new_so->sections_end))
356         {
357           error ("Unable to build section table for shared library\n.");
358           return;
359         }
360
361       /* Relocate all the sections based on where they got loaded.  */
362       for (p = new_so->sections; p < new_so->sections_end; p++)
363         {
364           if (p->the_bfd_section->flags & SEC_CODE)
365             {
366               p->addr += text_addr - new_so->som_solib.text_link_addr;
367               p->endaddr += text_addr - new_so->som_solib.text_link_addr;
368             }
369           else if (p->the_bfd_section->flags & SEC_DATA)
370             {
371               p->addr += new_so->som_solib.data_start;
372               p->endaddr += new_so->som_solib.data_start;
373             }
374         }
375
376       /* Now see if we need to map in the text and data for this shared
377          library (for example debugging a core file which does not use
378          private shared libraries.). 
379
380          Carefully peek at the first text address in the library.  If the
381          read succeeds, then the libraries were privately mapped and were
382          included in the core dump file.
383
384          If the peek failed, then the libraries were not privately mapped
385          and are not in the core file, we'll have to read them in ourselves.  */
386       status = target_read_memory (text_addr, buf, 4);
387       if (status != 0)
388         {
389           int old;
390
391           /* Add sections from the shared library to the core target.  */
392           if (target->to_sections)
393             {
394               old = target->to_sections_end - target->to_sections;
395               target->to_sections = (struct section_table *)
396                 xrealloc ((char *)target->to_sections,
397                           ((sizeof (struct section_table))
398                             * (old + bfd_count_sections (new_so->abfd))));
399             }
400           else
401             {
402               old = 0;
403               target->to_sections = (struct section_table *)
404                 xmalloc ((sizeof (struct section_table))
405                          * bfd_count_sections (new_so->abfd));
406             }
407           target->to_sections_end = (target->to_sections
408                                 + old + bfd_count_sections (new_so->abfd));
409           memcpy ((char *)(target->to_sections + old),
410                   new_so->sections,
411                   ((sizeof (struct section_table))
412                    * bfd_count_sections (new_so->abfd)));
413         }
414     }
415
416   /* Getting new symbols may change our opinion about what is
417      frameless.  */
418   reinit_frame_cache ();
419   return;
420
421 old_dld:
422   error ("Debugging dynamic executables loaded via the hpux8 dld.sl is not supported.\n");
423   return;
424
425 err:
426   error ("Error while reading dynamic library list.\n");
427   return;
428 }
429
430
431 /* This hook gets called just before the first instruction in the
432    inferior process is executed.
433
434    This is our opportunity to set magic flags in the inferior so
435    that GDB can be notified when a shared library is mapped in and
436    to tell the dynamic linker that a private copy of the library is
437    needed (so GDB can set breakpoints in the library).
438
439    __dld_flags is the location of the magic flags; as of this implementation
440    there are 3 flags of interest:
441
442    bit 0 when set indicates that private copies of the libraries are needed
443    bit 1 when set indicates that the callback hook routine is valid
444    bit 2 when set indicates that the dynamic linker should maintain the
445          __dld_list structure when loading/unloading libraries.
446
447    Note that shared libraries are not mapped in at this time, so we have
448    run the inferior until the libraries are mapped in.  Typically this
449    means running until the "_start" is called.  */
450
451 void
452 som_solib_create_inferior_hook()
453 {
454   struct minimal_symbol *msymbol;
455   unsigned int dld_flags, status;
456   asection *shlib_info;
457   char shadow_contents[BREAKPOINT_MAX], buf[4];
458   CORE_ADDR anaddr;
459
460   if (symfile_objfile == NULL)
461     return; 
462
463   /* First see if the objfile was dynamically linked.  */
464   shlib_info = bfd_get_section_by_name (symfile_objfile->obfd, "$SHLIB_INFO$");
465   if (!shlib_info)
466     return;
467
468   /* It's got a $SHLIB_INFO$ section, make sure it's not empty.  */
469   if (bfd_section_size (symfile_objfile->obfd, shlib_info) == 0)
470     return;
471
472   /* Get the address of __dld_flags, if no such symbol exists, then we can
473      not debug the shared code.  */
474   msymbol = lookup_minimal_symbol ("__dld_flags", NULL, NULL);
475   if (msymbol == NULL)
476     {
477       error ("Unable to find __dld_flags symbol in object file.\n");
478       return;
479     }
480
481   anaddr = SYMBOL_VALUE_ADDRESS (msymbol);
482   /* Read the current contents.  */
483   status = target_read_memory (anaddr, buf, 4);
484   if (status != 0)
485     {
486       error ("Unable to read __dld_flags\n");
487       return;
488     }
489   dld_flags = extract_unsigned_integer (buf, 4);
490
491   /* Turn on the flags we care about.  */
492   dld_flags |= 0x5;
493   store_unsigned_integer (buf, 4, dld_flags);
494   status = target_write_memory (anaddr, buf, 4);
495   if (status != 0)
496     {
497       error ("Unable to write __dld_flags\n");
498       return;
499     }
500
501   /* Now find the address of _start and set a breakpoint there.  */
502   msymbol = lookup_minimal_symbol ("_start", NULL, symfile_objfile);
503   if (msymbol == NULL)
504     {
505       error ("Unable to find _start symbol in object file.\n");
506       return;
507     }
508
509   anaddr = SYMBOL_VALUE_ADDRESS (msymbol);
510   if (target_insert_breakpoint (anaddr, shadow_contents))
511     {
512       error ("Unable to set breakpoint at _start.\n");
513       return;
514     }
515
516   /* Wipe out all knowledge of old shared libraries since their
517      mapping can change from one exec to another!  */
518   while (so_list_head)
519     {
520       struct so_list *temp;
521
522       free_objfile (so_list_head->objfile);
523       temp = so_list_head;
524       free (so_list_head);
525       so_list_head = temp->next;
526     }
527
528   /* Start the process again and wait for it to hit our breakpoint.  */
529   clear_proceed_status ();
530   stop_soon_quietly = 1;
531   stop_signal = TARGET_SIGNAL_0;
532   do
533     {
534       target_resume (-1, 0, stop_signal);
535       wait_for_inferior ();
536     }
537   while (stop_signal != TARGET_SIGNAL_TRAP);
538   stop_soon_quietly = 0;
539
540   /* All the libraries should be mapped in now.  Remove our breakpoint and
541      read in the symbol tables from the shared libraries.  */
542   if (target_remove_breakpoint (anaddr, shadow_contents))
543     {
544       error ("Unable to remove breakpoint at _start.\n");
545       return;
546     }
547
548   som_solib_add ((char *) 0, 0, (struct target_ops *) 0);
549 }
550
551 /* Return the GOT value for the shared library in which ADDR belongs.  If
552    ADDR isn't in any known shared library, return zero.  */
553
554 CORE_ADDR
555 som_solib_get_got_by_pc (addr)
556      CORE_ADDR addr;
557 {
558   struct so_list *so_list = so_list_head;
559   CORE_ADDR got_value = 0;
560
561   while (so_list)
562     {
563       if (so_list->som_solib.text_addr <= addr
564           && so_list->som_solib.text_end > addr)
565         {
566           got_value = so_list->som_solib.got_value;
567           break;
568         }
569       so_list = so_list->next;
570     }
571   return got_value;
572 }
573
574 /* Dump information about all the currently loaded shared libraries.  */
575
576 static void
577 som_sharedlibrary_info_command (ignore, from_tty)
578      char *ignore;
579      int from_tty;
580 {
581   struct so_list *so_list = so_list_head;
582
583   if (exec_bfd == NULL)
584     {
585       printf_unfiltered ("no exec file.\n");
586       return;
587     }
588
589   if (so_list == NULL)
590     {
591       printf_unfiltered ("No shared libraries loaded at this time.\n");
592       return;
593     }
594
595   printf_unfiltered ("Shared Object Libraries\n");
596   printf_unfiltered ("    %-12s%-12s%-12s%-12s%-12s%-12s\n",
597                      "  flags", "  tstart", "   tend", "  dstart", "   dend", "   dlt");
598   while (so_list)
599     {
600       unsigned int flags;
601
602       flags = so_list->som_solib.struct_version << 24;
603       flags |= so_list->som_solib.bind_mode << 16;
604       flags |= so_list->som_solib.library_version;
605       printf_unfiltered ("%s\n", so_list->som_solib.name);
606       printf_unfiltered ("    %-12s", local_hex_string_custom (flags, "08l"));
607       printf_unfiltered ("%-12s",
608               local_hex_string_custom (so_list->som_solib.text_addr, "08l"));
609       printf_unfiltered ("%-12s",
610               local_hex_string_custom (so_list->som_solib.text_end, "08l"));
611       printf_unfiltered ("%-12s",
612               local_hex_string_custom (so_list->som_solib.data_start, "08l"));
613       printf_unfiltered ("%-12s",
614               local_hex_string_custom (so_list->som_solib.data_end, "08l"));
615       printf_unfiltered ("%-12s\n",
616               local_hex_string_custom (so_list->som_solib.got_value, "08l"));
617       so_list = so_list->next;
618     }
619 }
620
621 void
622 _initialize_som_solib ()
623 {
624   add_info ("sharedlibrary", som_sharedlibrary_info_command,
625             "Status of loaded shared object libraries.");
626 }