* somsolib.c (som_solib_get_got_by_pc): New function.
[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   /* First see if the objfile was dynamically linked.  */
130   shlib_info = bfd_get_section_by_name (symfile_objfile->obfd, "$SHLIB_INFO$");
131   if (!shlib_info)
132     return;
133
134   /* It's got a $SHLIB_INFO$ section, make sure it's not empty.  */
135   if (bfd_section_size (symfile_objfile->obfd, shlib_info) == 0)
136     return;
137
138   msymbol = lookup_minimal_symbol ("__dld_flags", (struct objfile *) NULL);
139   if (msymbol == NULL)
140     {
141       error ("Unable to find __dld_flags symbol in object file.\n");
142       return;
143     }
144
145   addr = SYMBOL_VALUE_ADDRESS (msymbol);
146   /* Read the current contents.  */
147   status = target_read_memory (addr, buf, 4);
148   if (status != 0)
149     {
150       error ("Unable to read __dld_flags\n");
151       return;
152     }
153   dld_flags = extract_unsigned_integer (buf, 4);
154
155   /* __dld_list may not be valid.  If it's not valid tell the user.  */
156   if ((dld_flags & 4) == 0)
157     {
158       error ("__dld_list is not valid according to __dld_flags.\n");
159       return;
160     }
161
162   /* If the libraries were not mapped private, warn the user.  */
163   if ((dld_flags & 1) == 0)
164     warning ("The shared libraries were not privately mapped; setting a\nbreakpoint in a shared library will not work until you rerun the program.\n");
165
166   msymbol = lookup_minimal_symbol ("__dld_list", (struct objfile *) NULL);
167   if (!msymbol)
168     {
169       /* Older crt0.o files (hpux8) don't have __dld_list as a symbol,
170          but the data is still available if you know where to look.  */
171       msymbol = lookup_minimal_symbol ("__dld_flags", (struct objfile *)NULL);
172       if (!msymbol)
173         {
174           error ("Unable to find dynamic library list.\n");
175           return;
176         }
177       addr = SYMBOL_VALUE_ADDRESS (msymbol) - 8;
178     }
179   else
180     addr = SYMBOL_VALUE_ADDRESS (msymbol);
181
182   status = target_read_memory (addr, buf, 4);
183   if (status != 0)
184     {
185       error ("Unable to find dynamic library list.\n");
186       return;
187     }
188
189   addr = extract_unsigned_integer (buf, 4);
190
191   /* If addr is zero, then we're using an old dynamic loader which
192      doesn't maintain __dld_list.  We'll have to use a completely
193      different approach to get shared library information.  */
194   if (addr == 0)
195     goto old_dld;
196
197   /* Using the information in __dld_list is the preferred method
198      to get at shared library information.  It doesn't depend on
199      any functions in /usr/lib/end.o and has a chance of working
200      with hpux10 when it is released.  */
201   status = target_read_memory (addr, buf, 4);
202   if (status != 0)
203     {
204       error ("Unable to find dynamic library list.\n");
205       return;
206     }
207
208   /* addr now holds the address of the first entry in the dynamic
209      library list.  */
210   addr = extract_unsigned_integer (buf, 4);
211
212   /* Now that we have a pointer to the dynamic library list, walk
213      through it and add the symbols for each library.
214
215      Skip the first entry since it's our executable.  */
216   status = target_read_memory (addr + 36, buf, 4);
217   if (status != 0)
218     goto err;
219
220   addr = extract_unsigned_integer (buf, 4);
221
222   so_list_tail = so_list_head;
223   /* Find the end of the list of shared objects.  */
224   while (so_list_tail && so_list_tail->next)
225     so_list_tail = so_list_tail->next;
226
227   while (1)
228     {
229       CORE_ADDR name_addr, text_addr;
230       unsigned int name_len;
231       char *name;
232       struct so_list *new_so;
233       struct section_table *p;
234
235       if (addr == 0)
236         break;
237
238       /* Get a pointer to the name of this library.  */
239       status = target_read_memory (addr, buf, 4);
240       if (status != 0)
241         goto err;
242
243       name_addr = extract_unsigned_integer (buf, 4);
244       name_len = 0;
245       while (1)
246         {
247           target_read_memory (name_addr + name_len, buf, 1);
248           if (status != 0)
249             goto err;
250
251           name_len++;
252           if (*buf == '\0')
253             break;
254         }
255       name = alloca (name_len);
256       status = target_read_memory (name_addr, name, name_len);
257       if (status != 0)
258         goto err;
259
260       name = obsavestring (name, name_len - 1,
261                            &symfile_objfile->symbol_obstack);
262
263       status = target_read_memory (addr + 8, buf, 4);
264       if (status != 0)
265         goto err;
266
267       text_addr = extract_unsigned_integer (buf, 4);
268
269
270       new_so = (struct so_list *) malloc (sizeof (struct so_list));
271       memset ((char *)new_so, 0, sizeof (struct so_list));
272       if (so_list_head == NULL)
273         {
274           so_list_head = new_so;
275           so_list_tail = new_so;
276         }
277       else
278         {
279           so_list_tail->next = new_so;
280           so_list_tail = new_so;
281         }
282
283       /* Fill in all the entries in GDB's shared library list.  */
284       new_so->som_solib.name = name;
285       status = target_read_memory (addr + 4, buf, 4);
286       if (status != 0)
287         goto err;
288
289       new_so->som_solib.struct_version = extract_unsigned_integer (buf + 3, 1);
290       new_so->som_solib.bind_mode = extract_unsigned_integer (buf + 2, 1);
291       new_so->som_solib.library_version = extract_unsigned_integer (buf, 2);
292       new_so->som_solib.text_addr = text_addr;
293
294       status = target_read_memory (addr + 12, buf, 4);
295       if (status != 0)
296         goto err;
297
298       new_so->som_solib.text_link_addr = extract_unsigned_integer (buf, 4);
299
300       status = target_read_memory (addr + 16, buf, 4);
301       if (status != 0)
302         goto err;
303
304       new_so->som_solib.text_end = extract_unsigned_integer (buf, 4);
305
306       status = target_read_memory (addr + 20, buf, 4);
307       if (status != 0)
308         goto err;
309
310       new_so->som_solib.data_start = extract_unsigned_integer (buf, 4);
311
312       status = target_read_memory (addr + 24, buf, 4);
313       if (status != 0)
314         goto err;
315
316       new_so->som_solib.bss_start = extract_unsigned_integer (buf, 4);
317
318       status = target_read_memory (addr + 28, buf, 4);
319       if (status != 0)
320         goto err;
321
322       new_so->som_solib.data_end = extract_unsigned_integer (buf, 4);
323
324       status = target_read_memory (addr + 32, buf, 4);
325       if (status != 0)
326         goto err;
327
328       new_so->som_solib.got_value = extract_unsigned_integer (buf, 4);
329
330       status = target_read_memory (addr + 36, buf, 4);
331       if (status != 0)
332         goto err;
333
334       new_so->som_solib.next = (void *)extract_unsigned_integer (buf, 4);
335       addr = (CORE_ADDR)new_so->som_solib.next;
336
337       new_so->objfile = symbol_file_add (name, from_tty, text_addr, 0, 0, 0);
338       new_so->abfd = bfd_openr (name, gnutarget);
339       new_so->abfd->cacheable = true;
340
341       if (!bfd_check_format (new_so->abfd, bfd_object))
342         {
343           error ("\"%s\": not in executable format: %s.",
344                  name, bfd_errmsg (bfd_get_error ()));
345         }
346
347       /* Now we need to build a section table for this library since
348          we might be debugging a core file from a dynamically linked
349          executable in which the libraries were not privately mapped.  */
350       if (build_section_table (new_so->abfd,
351                                &new_so->sections,
352                                &new_so->sections_end))
353         {
354           error ("Unable to build section table for shared library\n.");
355           return;
356         }
357
358       /* Relocate all the sections based on where they got loaded.  */
359       for (p = new_so->sections; p < new_so->sections_end; p++)
360         {
361           if (p->the_bfd_section->flags & SEC_CODE)
362             {
363               p->addr += text_addr - new_so->som_solib.text_link_addr;
364               p->endaddr += text_addr - new_so->som_solib.text_link_addr;
365             }
366           else if (p->the_bfd_section->flags & SEC_DATA)
367             {
368               p->addr += new_so->som_solib.data_start;
369               p->endaddr += new_so->som_solib.data_start;
370             }
371         }
372
373       /* Now see if we need to map in the text and data for this shared
374          library (for example debugging a core file which does not use
375          private shared libraries.). 
376
377          Carefully peek at the first text address in the library.  If the
378          read succeeds, then the libraries were privately mapped and were
379          included in the core dump file.
380
381          If the peek failed, then the libraries were not privately mapped
382          and are not in the core file, we'll have to read them in ourselves.  */
383       status = target_read_memory (text_addr, buf, 4);
384       if (status != 0)
385         {
386           int old;
387
388           /* Add sections from the shared library to the core target.  */
389           if (target->to_sections)
390             {
391               old = target->to_sections_end - target->to_sections;
392               target->to_sections = (struct section_table *)
393                 xrealloc ((char *)target->to_sections,
394                           ((sizeof (struct section_table))
395                             * (old + bfd_count_sections (new_so->abfd))));
396             }
397           else
398             {
399               old = 0;
400               target->to_sections = (struct section_table *)
401                 xmalloc ((sizeof (struct section_table))
402                          * bfd_count_sections (new_so->abfd));
403             }
404           target->to_sections_end = (target->to_sections
405                                 + old + bfd_count_sections (new_so->abfd));
406           memcpy ((char *)(target->to_sections + old),
407                   new_so->sections,
408                   ((sizeof (struct section_table))
409                    * bfd_count_sections (new_so->abfd)));
410         }
411     }
412
413   /* Getting new symbols may change our opinion about what is
414      frameless.  */
415   reinit_frame_cache ();
416   return;
417
418 old_dld:
419   error ("Debugging dynamic executables loaded via the hpux8 dld.sl is not supported.\n");
420   return;
421
422 err:
423   error ("Error while reading dynamic library list.\n");
424   return;
425 }
426
427
428 /* This hook gets called just before the first instruction in the
429    inferior process is executed.
430
431    This is our opportunity to set magic flags in the inferior so
432    that GDB can be notified when a shared library is mapped in and
433    to tell the dynamic linker that a private copy of the library is
434    needed (so GDB can set breakpoints in the library).
435
436    __dld_flags is the location of the magic flags; as of this implementation
437    there are 3 flags of interest:
438
439    bit 0 when set indicates that private copies of the libraries are needed
440    bit 1 when set indicates that the callback hook routine is valid
441    bit 2 when set indicates that the dynamic linker should maintain the
442          __dld_list structure when loading/unloading libraries.
443
444    Note that shared libraries are not mapped in at this time, so we have
445    run the inferior until the libraries are mapped in.  Typically this
446    means running until the "_start" is called.  */
447
448 void
449 som_solib_create_inferior_hook()
450 {
451   struct minimal_symbol *msymbol;
452   unsigned int dld_flags, status;
453   asection *shlib_info;
454   char shadow_contents[BREAKPOINT_MAX], buf[4];
455   CORE_ADDR anaddr;
456
457   /* First see if the objfile was dynamically linked.  */
458   shlib_info = bfd_get_section_by_name (symfile_objfile->obfd, "$SHLIB_INFO$");
459   if (!shlib_info)
460     return;
461
462   /* It's got a $SHLIB_INFO$ section, make sure it's not empty.  */
463   if (bfd_section_size (symfile_objfile->obfd, shlib_info) == 0)
464     return;
465
466   /* Get the address of __dld_flags, if no such symbol exists, then we can
467      not debug the shared code.  */
468   msymbol = lookup_minimal_symbol ("__dld_flags", (struct objfile *) NULL);
469   if (msymbol == NULL)
470     {
471       error ("Unable to find __dld_flags symbol in object file.\n");
472       return;
473     }
474
475   anaddr = SYMBOL_VALUE_ADDRESS (msymbol);
476   /* Read the current contents.  */
477   status = target_read_memory (anaddr, buf, 4);
478   if (status != 0)
479     {
480       error ("Unable to read __dld_flags\n");
481       return;
482     }
483   dld_flags = extract_unsigned_integer (buf, 4);
484
485   /* Turn on the flags we care about.  */
486   dld_flags |= 0x5;
487   store_unsigned_integer (buf, 4, dld_flags);
488   status = target_write_memory (anaddr, buf, 4);
489   if (status != 0)
490     {
491       error ("Unable to write __dld_flags\n");
492       return;
493     }
494
495   /* Now find the address of _start and set a breakpoint there.  */
496   msymbol = lookup_minimal_symbol ("_start", symfile_objfile);
497   if (msymbol == NULL)
498     {
499       error ("Unable to find _start symbol in object file.\n");
500       return;
501     }
502
503   anaddr = SYMBOL_VALUE_ADDRESS (msymbol);
504   if (target_insert_breakpoint (anaddr, shadow_contents))
505     {
506       error ("Unable to set breakpoint at _start.\n");
507       return;
508     }
509
510   /* Wipe out all knowledge of old shared libraries since their
511      mapping can change from one exec to another!  */
512   while (so_list_head)
513     {
514       struct so_list *temp;
515
516       free_objfile (so_list_head->objfile);
517       temp = so_list_head;
518       free (so_list_head);
519       so_list_head = temp->next;
520     }
521
522   /* Start the process again and wait for it to hit our breakpoint.  */
523   clear_proceed_status ();
524   stop_soon_quietly = 1;
525   stop_signal = TARGET_SIGNAL_0;
526   do
527     {
528       target_resume (-1, 0, stop_signal);
529       wait_for_inferior ();
530     }
531   while (stop_signal != TARGET_SIGNAL_TRAP);
532   stop_soon_quietly = 0;
533
534   /* All the libraries should be mapped in now.  Remove our breakpoint and
535      read in the symbol tables from the shared libraries.  */
536   if (target_remove_breakpoint (anaddr, shadow_contents))
537     {
538       error ("Unable to remove breakpoint at _start.\n");
539       return;
540     }
541
542   som_solib_add ((char *) 0, 0, (struct target_ops *) 0);
543 }
544
545 /* Return the GOT value for the shared library in which ADDR belongs.  If
546    ADDR isn't in any known shared library, return zero.  */
547
548 CORE_ADDR
549 som_solib_get_got_by_pc (addr)
550      CORE_ADDR addr;
551 {
552   struct so_list *so_list = so_list_head;
553   CORE_ADDR got_value = 0;
554
555   while (so_list)
556     {
557       if (so_list->som_solib.text_addr <= addr
558           && so_list->som_solib.text_end > addr)
559         {
560           got_value = so_list->som_solib.got_value;
561           break;
562         }
563       so_list = so_list->next;
564     }
565   return got_value;
566 }
567
568 /* Dump information about all the currently loaded shared libraries.  */
569
570 static void
571 som_sharedlibrary_info_command (ignore, from_tty)
572      char *ignore;
573      int from_tty;
574 {
575   struct so_list *so_list = so_list_head;
576
577   if (exec_bfd == NULL)
578     {
579       printf_unfiltered ("no exec file.\n");
580       return;
581     }
582
583   if (so_list == NULL)
584     {
585       printf_unfiltered ("No shared libraries loaded at this time.\n");
586       return;
587     }
588
589   printf_unfiltered ("Shared Object Libraries\n");
590   printf_unfiltered ("    %-12s%-12s%-12s%-12s%-12s%-12s\n",
591                      "  flags", "  tstart", "   tend", "  dstart", "   dend", "   dlt");
592   while (so_list)
593     {
594       unsigned int flags;
595
596       flags = so_list->som_solib.struct_version << 24;
597       flags |= so_list->som_solib.bind_mode << 16;
598       flags |= so_list->som_solib.library_version;
599       printf_unfiltered ("%s\n", so_list->som_solib.name);
600       printf_unfiltered ("    %-12s", local_hex_string_custom (flags, "08l"));
601       printf_unfiltered ("%-12s",
602               local_hex_string_custom (so_list->som_solib.text_addr, "08l"));
603       printf_unfiltered ("%-12s",
604               local_hex_string_custom (so_list->som_solib.text_end, "08l"));
605       printf_unfiltered ("%-12s",
606               local_hex_string_custom (so_list->som_solib.data_start, "08l"));
607       printf_unfiltered ("%-12s",
608               local_hex_string_custom (so_list->som_solib.data_end, "08l"));
609       printf_unfiltered ("%-12s\n",
610               local_hex_string_custom (so_list->som_solib.got_value, "08l"));
611       so_list = so_list->next;
612     }
613 }
614
615 void
616 _initialize_som_solib ()
617 {
618   add_info ("sharedlibrary", som_sharedlibrary_info_command,
619             "Status of loaded shared object libraries.");
620 }