9ac429d204903d83a4a539aec3aac52c69b937da
[platform/upstream/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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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 #include "gdb-stabs.h"
37 #include "gdbcmd.h"
38
39 /* TODO:
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 /* If true, then shared library symbols will be added automatically
100    when the inferior is created.  This is almost always what users
101    will want to have happen; but for very large programs, the startup
102    time will be excessive, and so if this is a problem, the user can
103    clear this flag and then add the shared library symbols as needed.
104    Note that there is a potential for confusion, since if the shared
105    library symbols are not loaded, commands like "info fun" will *not*
106    report all the functions that are actually present.  */
107
108 int auto_solib_add_at_startup = 1;
109
110 static struct so_list *so_list_head;
111
112 static void som_sharedlibrary_info_command PARAMS ((char *, int));
113
114 /* Add symbols from shared libraries into the symtab list.  */
115
116 void
117 som_solib_add (arg_string, from_tty, target)
118      char *arg_string;
119      int from_tty;
120      struct target_ops *target;
121 {
122   struct minimal_symbol *msymbol;
123   struct so_list *so_list_tail;
124   CORE_ADDR addr;
125   asection *shlib_info;
126   int status;
127   unsigned int dld_flags;
128   char buf[4], *re_err;
129
130   /* First validate our arguments.  */
131   if ((re_err = re_comp (arg_string ? arg_string : ".")) != NULL)
132     {
133       error ("Invalid regexp: %s", re_err);
134     }
135
136   /* If we're debugging a core file, or have attached to a running
137      process, then som_solib_create_inferior_hook will not have been
138      called.
139
140      We need to first determine if we're dealing with a dynamically
141      linked executable.  If not, then return without an error or warning.
142
143      We also need to examine __dld_flags to determine if the shared library
144      list is valid and to determine if the libraries have been privately
145      mapped.  */
146   if (symfile_objfile == NULL)
147     return;
148
149   /* First see if the objfile was dynamically linked.  */
150   shlib_info = bfd_get_section_by_name (symfile_objfile->obfd, "$SHLIB_INFO$");
151   if (!shlib_info)
152     return;
153
154   /* It's got a $SHLIB_INFO$ section, make sure it's not empty.  */
155   if (bfd_section_size (symfile_objfile->obfd, shlib_info) == 0)
156     return;
157
158   msymbol = lookup_minimal_symbol ("__dld_flags", NULL, NULL);
159   if (msymbol == NULL)
160     {
161       error ("Unable to find __dld_flags symbol in object file.\n");
162       return;
163     }
164
165   addr = SYMBOL_VALUE_ADDRESS (msymbol);
166   /* Read the current contents.  */
167   status = target_read_memory (addr, buf, 4);
168   if (status != 0)
169     {
170       error ("Unable to read __dld_flags\n");
171       return;
172     }
173   dld_flags = extract_unsigned_integer (buf, 4);
174
175   /* __dld_list may not be valid.  If it's not valid tell the user.  */
176   if ((dld_flags & 4) == 0)
177     {
178       error ("__dld_list is not valid according to __dld_flags.\n");
179       return;
180     }
181
182   /* If the libraries were not mapped private, warn the user.  */
183   if ((dld_flags & 1) == 0)
184     warning ("The shared libraries were not privately mapped; setting a\nbreakpoint in a shared library will not work until you rerun the program.\n");
185
186   msymbol = lookup_minimal_symbol ("__dld_list", NULL, NULL);
187   if (!msymbol)
188     {
189       /* Older crt0.o files (hpux8) don't have __dld_list as a symbol,
190          but the data is still available if you know where to look.  */
191       msymbol = lookup_minimal_symbol ("__dld_flags", NULL, NULL);
192       if (!msymbol)
193         {
194           error ("Unable to find dynamic library list.\n");
195           return;
196         }
197       addr = SYMBOL_VALUE_ADDRESS (msymbol) - 8;
198     }
199   else
200     addr = SYMBOL_VALUE_ADDRESS (msymbol);
201
202   status = target_read_memory (addr, buf, 4);
203   if (status != 0)
204     {
205       error ("Unable to find dynamic library list.\n");
206       return;
207     }
208
209   addr = extract_unsigned_integer (buf, 4);
210
211   /* If addr is zero, then we're using an old dynamic loader which
212      doesn't maintain __dld_list.  We'll have to use a completely
213      different approach to get shared library information.  */
214   if (addr == 0)
215     goto old_dld;
216
217   /* Using the information in __dld_list is the preferred method
218      to get at shared library information.  It doesn't depend on
219      any functions in /usr/lib/end.o and has a chance of working
220      with hpux10 when it is released.  */
221   status = target_read_memory (addr, buf, 4);
222   if (status != 0)
223     {
224       error ("Unable to find dynamic library list.\n");
225       return;
226     }
227
228   /* addr now holds the address of the first entry in the dynamic
229      library list.  */
230   addr = extract_unsigned_integer (buf, 4);
231
232   /* Now that we have a pointer to the dynamic library list, walk
233      through it and add the symbols for each library.  */
234
235   so_list_tail = so_list_head;
236   /* Find the end of the list of shared objects.  */
237   while (so_list_tail && so_list_tail->next)
238     so_list_tail = so_list_tail->next;
239
240   while (1)
241     {
242       CORE_ADDR name_addr, text_addr;
243       unsigned int name_len;
244       char *name;
245       struct so_list *new_so;
246       struct so_list *so_list = so_list_head;
247       struct section_table *p;
248
249       if (addr == 0)
250         break;
251
252       /* Get a pointer to the name of this library.  */
253       status = target_read_memory (addr, buf, 4);
254       if (status != 0)
255         goto err;
256
257       name_addr = extract_unsigned_integer (buf, 4);
258       name_len = 0;
259       while (1)
260         {
261           target_read_memory (name_addr + name_len, buf, 1);
262           if (status != 0)
263             goto err;
264
265           name_len++;
266           if (*buf == '\0')
267             break;
268         }
269       name = alloca (name_len);
270       status = target_read_memory (name_addr, name, name_len);
271       if (status != 0)
272         goto err;
273
274       /* See if we've already loaded something with this name.  */
275       while (so_list)
276         {
277           if (!strcmp (so_list->som_solib.name, name))
278             break;
279           so_list = so_list->next;
280         }
281
282       /* We've already loaded this one or it's the main program, skip it.  */
283       if (so_list || !strcmp (name, symfile_objfile->name))
284         {
285           status = target_read_memory (addr + 36, buf, 4);
286           if (status != 0)
287             goto err;
288
289           addr = (CORE_ADDR) extract_unsigned_integer (buf, 4);
290           continue;
291         }
292
293       name = obsavestring (name, name_len - 1,
294                            &symfile_objfile->symbol_obstack);
295
296       status = target_read_memory (addr + 8, buf, 4);
297       if (status != 0)
298         goto err;
299
300       text_addr = extract_unsigned_integer (buf, 4);
301
302
303       new_so = (struct so_list *) malloc (sizeof (struct so_list));
304       memset ((char *)new_so, 0, sizeof (struct so_list));
305       if (so_list_head == NULL)
306         {
307           so_list_head = new_so;
308           so_list_tail = new_so;
309         }
310       else
311         {
312           so_list_tail->next = new_so;
313           so_list_tail = new_so;
314         }
315
316       /* Fill in all the entries in GDB's shared library list.  */
317       new_so->som_solib.name = name;
318       status = target_read_memory (addr + 4, buf, 4);
319       if (status != 0)
320         goto err;
321
322       new_so->som_solib.struct_version = extract_unsigned_integer (buf + 3, 1);
323       new_so->som_solib.bind_mode = extract_unsigned_integer (buf + 2, 1);
324       new_so->som_solib.library_version = extract_unsigned_integer (buf, 2);
325       new_so->som_solib.text_addr = text_addr;
326
327       status = target_read_memory (addr + 12, buf, 4);
328       if (status != 0)
329         goto err;
330
331       new_so->som_solib.text_link_addr = extract_unsigned_integer (buf, 4);
332
333       status = target_read_memory (addr + 16, buf, 4);
334       if (status != 0)
335         goto err;
336
337       new_so->som_solib.text_end = extract_unsigned_integer (buf, 4);
338
339       status = target_read_memory (addr + 20, buf, 4);
340       if (status != 0)
341         goto err;
342
343       new_so->som_solib.data_start = extract_unsigned_integer (buf, 4);
344
345       status = target_read_memory (addr + 24, buf, 4);
346       if (status != 0)
347         goto err;
348
349       new_so->som_solib.bss_start = extract_unsigned_integer (buf, 4);
350
351       status = target_read_memory (addr + 28, buf, 4);
352       if (status != 0)
353         goto err;
354
355       new_so->som_solib.data_end = extract_unsigned_integer (buf, 4);
356
357       status = target_read_memory (addr + 32, buf, 4);
358       if (status != 0)
359         goto err;
360
361       new_so->som_solib.got_value = extract_unsigned_integer (buf, 4);
362
363       status = target_read_memory (addr + 36, buf, 4);
364       if (status != 0)
365         goto err;
366
367       new_so->som_solib.next = (void *)extract_unsigned_integer (buf, 4);
368       addr = (CORE_ADDR)new_so->som_solib.next;
369
370       new_so->objfile = symbol_file_add (name, from_tty, text_addr, 0, 0, 0);
371       new_so->abfd = new_so->objfile->obfd;
372
373       if (!bfd_check_format (new_so->abfd, bfd_object))
374         {
375           error ("\"%s\": not in executable format: %s.",
376                  name, bfd_errmsg (bfd_get_error ()));
377         }
378
379       /* Now we need to build a section table for this library since
380          we might be debugging a core file from a dynamically linked
381          executable in which the libraries were not privately mapped.  */
382       if (build_section_table (new_so->abfd,
383                                &new_so->sections,
384                                &new_so->sections_end))
385         {
386           error ("Unable to build section table for shared library\n.");
387           return;
388         }
389
390       /* Relocate all the sections based on where they got loaded.  */
391       for (p = new_so->sections; p < new_so->sections_end; p++)
392         {
393           if (p->the_bfd_section->flags & SEC_CODE)
394             {
395               p->addr += text_addr - new_so->som_solib.text_link_addr;
396               p->endaddr += text_addr - new_so->som_solib.text_link_addr;
397             }
398           else if (p->the_bfd_section->flags & SEC_DATA)
399             {
400               p->addr += new_so->som_solib.data_start;
401               p->endaddr += new_so->som_solib.data_start;
402             }
403         }
404
405       /* Now see if we need to map in the text and data for this shared
406          library (for example debugging a core file which does not use
407          private shared libraries.). 
408
409          Carefully peek at the first text address in the library.  If the
410          read succeeds, then the libraries were privately mapped and were
411          included in the core dump file.
412
413          If the peek failed, then the libraries were not privately mapped
414          and are not in the core file, we'll have to read them in ourselves.  */
415       status = target_read_memory (text_addr, buf, 4);
416       if (status != 0)
417         {
418           int old, new;
419
420           new = new_so->sections_end - new_so->sections;
421           /* Add sections from the shared library to the core target.  */
422           if (target->to_sections)
423             {
424               old = target->to_sections_end - target->to_sections;
425               target->to_sections = (struct section_table *)
426                 xrealloc ((char *)target->to_sections,
427                           ((sizeof (struct section_table)) * (old + new)));
428             }
429           else
430             {
431               old = 0;
432               target->to_sections = (struct section_table *)
433                 xmalloc ((sizeof (struct section_table)) * new);
434             }
435           target->to_sections_end = (target->to_sections + old + new);
436           memcpy ((char *)(target->to_sections + old),
437                   new_so->sections,
438                   ((sizeof (struct section_table)) * new));
439         }
440     }
441
442   /* Getting new symbols may change our opinion about what is
443      frameless.  */
444   reinit_frame_cache ();
445   return;
446
447 old_dld:
448   error ("Debugging dynamic executables loaded via the hpux8 dld.sl is not supported.\n");
449   return;
450
451 err:
452   error ("Error while reading dynamic library list.\n");
453   return;
454 }
455
456
457 /* This hook gets called just before the first instruction in the
458    inferior process is executed.
459
460    This is our opportunity to set magic flags in the inferior so
461    that GDB can be notified when a shared library is mapped in and
462    to tell the dynamic linker that a private copy of the library is
463    needed (so GDB can set breakpoints in the library).
464
465    __dld_flags is the location of the magic flags; as of this implementation
466    there are 3 flags of interest:
467
468    bit 0 when set indicates that private copies of the libraries are needed
469    bit 1 when set indicates that the callback hook routine is valid
470    bit 2 when set indicates that the dynamic linker should maintain the
471          __dld_list structure when loading/unloading libraries.
472
473    Note that shared libraries are not mapped in at this time, so we have
474    run the inferior until the libraries are mapped in.  Typically this
475    means running until the "_start" is called.  */
476
477 void
478 som_solib_create_inferior_hook()
479 {
480   struct minimal_symbol *msymbol;
481   unsigned int dld_flags, status;
482   asection *shlib_info;
483   char shadow_contents[BREAKPOINT_MAX], buf[4];
484   CORE_ADDR anaddr;
485
486   if (symfile_objfile == NULL)
487     return; 
488
489   /* First see if the objfile was dynamically linked.  */
490   shlib_info = bfd_get_section_by_name (symfile_objfile->obfd, "$SHLIB_INFO$");
491   if (!shlib_info)
492     return;
493
494   /* It's got a $SHLIB_INFO$ section, make sure it's not empty.  */
495   if (bfd_section_size (symfile_objfile->obfd, shlib_info) == 0)
496     return;
497
498   /* Get the address of __dld_flags, if no such symbol exists, then we can
499      not debug the shared code.  */
500   msymbol = lookup_minimal_symbol ("__dld_flags", NULL, NULL);
501   if (msymbol == NULL)
502     {
503       error ("Unable to find __dld_flags symbol in object file.\n");
504       return;
505     }
506
507   anaddr = SYMBOL_VALUE_ADDRESS (msymbol);
508   /* Read the current contents.  */
509   status = target_read_memory (anaddr, buf, 4);
510   if (status != 0)
511     {
512       error ("Unable to read __dld_flags\n");
513       return;
514     }
515   dld_flags = extract_unsigned_integer (buf, 4);
516
517   /* Turn on the flags we care about.  */
518   dld_flags |= 0x5;
519   store_unsigned_integer (buf, 4, dld_flags);
520   status = target_write_memory (anaddr, buf, 4);
521   if (status != 0)
522     {
523       error ("Unable to write __dld_flags\n");
524       return;
525     }
526
527   /* Now find the address of _start and set a breakpoint there.  */
528   msymbol = lookup_minimal_symbol ("_start", NULL, symfile_objfile);
529   if (msymbol == NULL)
530     {
531       error ("Unable to find _start symbol in object file.\n");
532       return;
533     }
534
535   anaddr = SYMBOL_VALUE_ADDRESS (msymbol);
536   if (target_insert_breakpoint (anaddr, shadow_contents))
537     {
538       error ("Unable to set breakpoint at _start.\n");
539       return;
540     }
541
542   /* Wipe out all knowledge of old shared libraries since their
543      mapping can change from one exec to another!  */
544   while (so_list_head)
545     {
546       struct so_list *temp;
547
548       free_objfile (so_list_head->objfile);
549       temp = so_list_head;
550       free (so_list_head);
551       so_list_head = temp->next;
552     }
553
554   /* Start the process again and wait for it to hit our breakpoint.  */
555   clear_proceed_status ();
556   stop_soon_quietly = 1;
557   stop_signal = TARGET_SIGNAL_0;
558   do
559     {
560       target_resume (-1, 0, stop_signal);
561       wait_for_inferior ();
562     }
563   while (stop_signal != TARGET_SIGNAL_TRAP);
564   stop_soon_quietly = 0;
565
566   /* All the libraries should be mapped in now.  Remove our breakpoint and
567      read in the symbol tables from the shared libraries.  */
568   if (target_remove_breakpoint (anaddr, shadow_contents))
569     {
570       error ("Unable to remove breakpoint at _start.\n");
571       return;
572     }
573
574   if (auto_solib_add_at_startup)
575     som_solib_add ((char *) 0, 0, (struct target_ops *) 0);
576 }
577
578 /* Return the GOT value for the shared library in which ADDR belongs.  If
579    ADDR isn't in any known shared library, return zero.  */
580
581 CORE_ADDR
582 som_solib_get_got_by_pc (addr)
583      CORE_ADDR addr;
584 {
585   struct so_list *so_list = so_list_head;
586   CORE_ADDR got_value = 0;
587
588   while (so_list)
589     {
590       if (so_list->som_solib.text_addr <= addr
591           && so_list->som_solib.text_end > addr)
592         {
593           got_value = so_list->som_solib.got_value;
594           break;
595         }
596       so_list = so_list->next;
597     }
598   return got_value;
599 }
600
601 int
602 som_solib_section_offsets (objfile, offsets)
603      struct objfile *objfile;
604      struct section_offsets *offsets;
605 {
606   struct so_list *so_list = so_list_head;
607
608   while (so_list)
609     {
610       /* Oh what a pain!  We need the offsets before so_list->objfile
611          is valid.  The BFDs will never match.  Make a best guess.  */
612       if (strstr (objfile->name, so_list->som_solib.name))
613         {
614           asection *private_section;
615
616           /* The text offset is easy.  */
617           ANOFFSET (offsets, SECT_OFF_TEXT)
618             = (so_list->som_solib.text_addr
619                - so_list->som_solib.text_link_addr);
620           ANOFFSET (offsets, SECT_OFF_RODATA)
621             = ANOFFSET (offsets, SECT_OFF_TEXT);
622
623           /* We should look at presumed_dp in the SOM header, but
624              that's not easily available.  This should be OK though.  */
625           private_section = bfd_get_section_by_name (objfile->obfd,
626                                                      "$PRIVATE$");
627           if (!private_section)
628             {
629               warning ("Unable to find $PRIVATE$ in shared library!");
630               ANOFFSET (offsets, SECT_OFF_DATA) = 0;
631               ANOFFSET (offsets, SECT_OFF_BSS) = 0;
632               return 1;
633             }
634           ANOFFSET (offsets, SECT_OFF_DATA)
635             = (so_list->som_solib.data_start - private_section->vma);
636           ANOFFSET (offsets, SECT_OFF_BSS)
637             = ANOFFSET (offsets, SECT_OFF_DATA);
638           return 1;
639         }
640       so_list = so_list->next;
641     }
642   return 0;
643 }
644
645 /* Dump information about all the currently loaded shared libraries.  */
646
647 static void
648 som_sharedlibrary_info_command (ignore, from_tty)
649      char *ignore;
650      int from_tty;
651 {
652   struct so_list *so_list = so_list_head;
653
654   if (exec_bfd == NULL)
655     {
656       printf_unfiltered ("no exec file.\n");
657       return;
658     }
659
660   if (so_list == NULL)
661     {
662       printf_unfiltered ("No shared libraries loaded at this time.\n");
663       return;
664     }
665
666   printf_unfiltered ("Shared Object Libraries\n");
667   printf_unfiltered ("    %-12s%-12s%-12s%-12s%-12s%-12s\n",
668                      "  flags", "  tstart", "   tend", "  dstart", "   dend", "   dlt");
669   while (so_list)
670     {
671       unsigned int flags;
672
673       flags = so_list->som_solib.struct_version << 24;
674       flags |= so_list->som_solib.bind_mode << 16;
675       flags |= so_list->som_solib.library_version;
676       printf_unfiltered ("%s\n", so_list->som_solib.name);
677       printf_unfiltered ("    %-12s", local_hex_string_custom (flags, "08l"));
678       printf_unfiltered ("%-12s",
679               local_hex_string_custom (so_list->som_solib.text_addr, "08l"));
680       printf_unfiltered ("%-12s",
681               local_hex_string_custom (so_list->som_solib.text_end, "08l"));
682       printf_unfiltered ("%-12s",
683               local_hex_string_custom (so_list->som_solib.data_start, "08l"));
684       printf_unfiltered ("%-12s",
685               local_hex_string_custom (so_list->som_solib.data_end, "08l"));
686       printf_unfiltered ("%-12s\n",
687               local_hex_string_custom (so_list->som_solib.got_value, "08l"));
688       so_list = so_list->next;
689     }
690 }
691
692 static void
693 som_solib_sharedlibrary_command (args, from_tty)
694      char *args;
695      int from_tty;
696 {
697   dont_repeat ();
698   som_solib_add (args, from_tty, (struct target_ops *) 0);
699 }
700
701 void
702 _initialize_som_solib ()
703 {
704   add_com ("sharedlibrary", class_files, som_solib_sharedlibrary_command,
705            "Load shared object library symbols for files matching REGEXP.");
706   add_info ("sharedlibrary", som_sharedlibrary_info_command,
707             "Status of loaded shared object libraries.");
708   add_show_from_set
709     (add_set_cmd ("auto-solib-add", class_support, var_zinteger,
710                   (char *) &auto_solib_add_at_startup,
711                   "Set autoloading of shared library symbols at startup.\n\
712 If nonzero, symbols from all shared object libraries will be loaded\n\
713 automatically when the inferior begins execution.  Otherwise, symbols\n\
714 must be loaded manually, using `sharedlibrary'.",
715                   &setlist),
716      &showlist);
717
718 }