* somread.c (som_symtab_read): Handle dynamic relocation for both
[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 = new_so->objfile->obfd;
342
343       if (!bfd_check_format (new_so->abfd, bfd_object))
344         {
345           error ("\"%s\": not in executable format: %s.",
346                  name, bfd_errmsg (bfd_get_error ()));
347         }
348
349       /* Now we need to build a section table for this library since
350          we might be debugging a core file from a dynamically linked
351          executable in which the libraries were not privately mapped.  */
352       if (build_section_table (new_so->abfd,
353                                &new_so->sections,
354                                &new_so->sections_end))
355         {
356           error ("Unable to build section table for shared library\n.");
357           return;
358         }
359
360       /* Relocate all the sections based on where they got loaded.  */
361       for (p = new_so->sections; p < new_so->sections_end; p++)
362         {
363           if (p->the_bfd_section->flags & SEC_CODE)
364             {
365               p->addr += text_addr - new_so->som_solib.text_link_addr;
366               p->endaddr += text_addr - new_so->som_solib.text_link_addr;
367             }
368           else if (p->the_bfd_section->flags & SEC_DATA)
369             {
370               p->addr += new_so->som_solib.data_start;
371               p->endaddr += new_so->som_solib.data_start;
372             }
373         }
374
375       /* Now see if we need to map in the text and data for this shared
376          library (for example debugging a core file which does not use
377          private shared libraries.). 
378
379          Carefully peek at the first text address in the library.  If the
380          read succeeds, then the libraries were privately mapped and were
381          included in the core dump file.
382
383          If the peek failed, then the libraries were not privately mapped
384          and are not in the core file, we'll have to read them in ourselves.  */
385       status = target_read_memory (text_addr, buf, 4);
386       if (status != 0)
387         {
388           int old;
389
390           /* Add sections from the shared library to the core target.  */
391           if (target->to_sections)
392             {
393               old = target->to_sections_end - target->to_sections;
394               target->to_sections = (struct section_table *)
395                 xrealloc ((char *)target->to_sections,
396                           ((sizeof (struct section_table))
397                             * (old + bfd_count_sections (new_so->abfd))));
398             }
399           else
400             {
401               old = 0;
402               target->to_sections = (struct section_table *)
403                 xmalloc ((sizeof (struct section_table))
404                          * bfd_count_sections (new_so->abfd));
405             }
406           target->to_sections_end = (target->to_sections
407                                 + old + bfd_count_sections (new_so->abfd));
408           memcpy ((char *)(target->to_sections + old),
409                   new_so->sections,
410                   ((sizeof (struct section_table))
411                    * bfd_count_sections (new_so->abfd)));
412         }
413     }
414
415   /* Getting new symbols may change our opinion about what is
416      frameless.  */
417   reinit_frame_cache ();
418   return;
419
420 old_dld:
421   error ("Debugging dynamic executables loaded via the hpux8 dld.sl is not supported.\n");
422   return;
423
424 err:
425   error ("Error while reading dynamic library list.\n");
426   return;
427 }
428
429
430 /* This hook gets called just before the first instruction in the
431    inferior process is executed.
432
433    This is our opportunity to set magic flags in the inferior so
434    that GDB can be notified when a shared library is mapped in and
435    to tell the dynamic linker that a private copy of the library is
436    needed (so GDB can set breakpoints in the library).
437
438    __dld_flags is the location of the magic flags; as of this implementation
439    there are 3 flags of interest:
440
441    bit 0 when set indicates that private copies of the libraries are needed
442    bit 1 when set indicates that the callback hook routine is valid
443    bit 2 when set indicates that the dynamic linker should maintain the
444          __dld_list structure when loading/unloading libraries.
445
446    Note that shared libraries are not mapped in at this time, so we have
447    run the inferior until the libraries are mapped in.  Typically this
448    means running until the "_start" is called.  */
449
450 void
451 som_solib_create_inferior_hook()
452 {
453   struct minimal_symbol *msymbol;
454   unsigned int dld_flags, status;
455   asection *shlib_info;
456   char shadow_contents[BREAKPOINT_MAX], buf[4];
457   CORE_ADDR anaddr;
458
459   if (symfile_objfile == NULL)
460     return; 
461
462   /* First see if the objfile was dynamically linked.  */
463   shlib_info = bfd_get_section_by_name (symfile_objfile->obfd, "$SHLIB_INFO$");
464   if (!shlib_info)
465     return;
466
467   /* It's got a $SHLIB_INFO$ section, make sure it's not empty.  */
468   if (bfd_section_size (symfile_objfile->obfd, shlib_info) == 0)
469     return;
470
471   /* Get the address of __dld_flags, if no such symbol exists, then we can
472      not debug the shared code.  */
473   msymbol = lookup_minimal_symbol ("__dld_flags", NULL, NULL);
474   if (msymbol == NULL)
475     {
476       error ("Unable to find __dld_flags symbol in object file.\n");
477       return;
478     }
479
480   anaddr = SYMBOL_VALUE_ADDRESS (msymbol);
481   /* Read the current contents.  */
482   status = target_read_memory (anaddr, buf, 4);
483   if (status != 0)
484     {
485       error ("Unable to read __dld_flags\n");
486       return;
487     }
488   dld_flags = extract_unsigned_integer (buf, 4);
489
490   /* Turn on the flags we care about.  */
491   dld_flags |= 0x5;
492   store_unsigned_integer (buf, 4, dld_flags);
493   status = target_write_memory (anaddr, buf, 4);
494   if (status != 0)
495     {
496       error ("Unable to write __dld_flags\n");
497       return;
498     }
499
500   /* Now find the address of _start and set a breakpoint there.  */
501   msymbol = lookup_minimal_symbol ("_start", NULL, symfile_objfile);
502   if (msymbol == NULL)
503     {
504       error ("Unable to find _start symbol in object file.\n");
505       return;
506     }
507
508   anaddr = SYMBOL_VALUE_ADDRESS (msymbol);
509   if (target_insert_breakpoint (anaddr, shadow_contents))
510     {
511       error ("Unable to set breakpoint at _start.\n");
512       return;
513     }
514
515   /* Wipe out all knowledge of old shared libraries since their
516      mapping can change from one exec to another!  */
517   while (so_list_head)
518     {
519       struct so_list *temp;
520
521       free_objfile (so_list_head->objfile);
522       temp = so_list_head;
523       free (so_list_head);
524       so_list_head = temp->next;
525     }
526
527   /* Start the process again and wait for it to hit our breakpoint.  */
528   clear_proceed_status ();
529   stop_soon_quietly = 1;
530   stop_signal = TARGET_SIGNAL_0;
531   do
532     {
533       target_resume (-1, 0, stop_signal);
534       wait_for_inferior ();
535     }
536   while (stop_signal != TARGET_SIGNAL_TRAP);
537   stop_soon_quietly = 0;
538
539   /* All the libraries should be mapped in now.  Remove our breakpoint and
540      read in the symbol tables from the shared libraries.  */
541   if (target_remove_breakpoint (anaddr, shadow_contents))
542     {
543       error ("Unable to remove breakpoint at _start.\n");
544       return;
545     }
546
547   som_solib_add ((char *) 0, 0, (struct target_ops *) 0);
548 }
549
550 /* Return the GOT value for the shared library in which ADDR belongs.  If
551    ADDR isn't in any known shared library, return zero.  */
552
553 CORE_ADDR
554 som_solib_get_got_by_pc (addr)
555      CORE_ADDR addr;
556 {
557   struct so_list *so_list = so_list_head;
558   CORE_ADDR got_value = 0;
559
560   while (so_list)
561     {
562       if (so_list->som_solib.text_addr <= addr
563           && so_list->som_solib.text_end > addr)
564         {
565           got_value = so_list->som_solib.got_value;
566           break;
567         }
568       so_list = so_list->next;
569     }
570   return got_value;
571 }
572
573 int
574 som_solib_section_offsets (objfile, offsets)
575      struct objfile *objfile;
576      struct section_offsets *offsets;
577 {
578   struct so_list *so_list = so_list_head;
579
580   while (so_list)
581     {
582       /* Oh what a pain!  We need the offsets before so_list->objfile
583          is valid.  The BFDs will never match.  Make a best guess.  */
584       if (!strcmp (so_list->som_solib.name, objfile->name))
585         {
586           asection *private_section;
587
588           /* The text offset is easy.  */
589           ANOFFSET (offsets, 0) = so_list->som_solib.text_addr;
590
591           /* We should look at presumed_dp in the SOM header, but
592              that's not easily available.  This should be OK though.  */
593           private_section = bfd_get_section_by_name (objfile->obfd,
594                                                      "$PRIVATE$");
595           if (!private_section)
596             {
597               warning ("Unable to find $PRIVATE$ in shared library!");
598               ANOFFSET (offsets, 1) = 0;
599               return 1;
600             }
601           ANOFFSET (offsets, 1) = (so_list->som_solib.data_start
602                                    - private_section->vma);
603           return 1;
604         }
605       so_list = so_list->next;
606     }
607   return 0;
608 }
609
610 /* Dump information about all the currently loaded shared libraries.  */
611
612 static void
613 som_sharedlibrary_info_command (ignore, from_tty)
614      char *ignore;
615      int from_tty;
616 {
617   struct so_list *so_list = so_list_head;
618
619   if (exec_bfd == NULL)
620     {
621       printf_unfiltered ("no exec file.\n");
622       return;
623     }
624
625   if (so_list == NULL)
626     {
627       printf_unfiltered ("No shared libraries loaded at this time.\n");
628       return;
629     }
630
631   printf_unfiltered ("Shared Object Libraries\n");
632   printf_unfiltered ("    %-12s%-12s%-12s%-12s%-12s%-12s\n",
633                      "  flags", "  tstart", "   tend", "  dstart", "   dend", "   dlt");
634   while (so_list)
635     {
636       unsigned int flags;
637
638       flags = so_list->som_solib.struct_version << 24;
639       flags |= so_list->som_solib.bind_mode << 16;
640       flags |= so_list->som_solib.library_version;
641       printf_unfiltered ("%s\n", so_list->som_solib.name);
642       printf_unfiltered ("    %-12s", local_hex_string_custom (flags, "08l"));
643       printf_unfiltered ("%-12s",
644               local_hex_string_custom (so_list->som_solib.text_addr, "08l"));
645       printf_unfiltered ("%-12s",
646               local_hex_string_custom (so_list->som_solib.text_end, "08l"));
647       printf_unfiltered ("%-12s",
648               local_hex_string_custom (so_list->som_solib.data_start, "08l"));
649       printf_unfiltered ("%-12s",
650               local_hex_string_custom (so_list->som_solib.data_end, "08l"));
651       printf_unfiltered ("%-12s\n",
652               local_hex_string_custom (so_list->som_solib.got_value, "08l"));
653       so_list = so_list->next;
654     }
655 }
656
657 void
658 _initialize_som_solib ()
659 {
660   add_info ("sharedlibrary", som_sharedlibrary_info_command,
661             "Status of loaded shared object libraries.");
662 }