]> Git Repo - binutils.git/blob - gdb/solib-som.c
2005-04-10 H.J. Lu <[email protected]>
[binutils.git] / gdb / solib-som.c
1 /* Handle SOM shared libraries for GDB, the GNU Debugger.
2
3    Copyright 2004 Free Software Foundation, Inc.
4
5    This file is part of GDB.
6
7    This program is free software; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 2 of the License, or
10    (at your option) any later version.
11
12    This program is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16
17    You should have received a copy of the GNU General Public License
18    along with this program; if not, write to the Free Software
19    Foundation, Inc., 59 Temple Place - Suite 330,
20    Boston, MA 02111-1307, USA.  */
21
22 #include "defs.h"
23 #include "som.h"
24 #include "symtab.h"
25 #include "bfd.h"
26 #include "symfile.h"
27 #include "objfiles.h"
28 #include "gdbcore.h"
29 #include "target.h"
30 #include "inferior.h"
31
32 #include "hppa-tdep.h"
33 #include "solist.h"
34
35 #undef SOLIB_SOM_DBG 
36
37 /* These ought to be defined in some public interface, but aren't.  They
38    define the meaning of the various bits in the distinguished __dld_flags
39    variable that is declared in every debuggable a.out on HP-UX, and that
40    is shared between the debugger and the dynamic linker.
41  */
42 #define DLD_FLAGS_MAPPRIVATE    0x1
43 #define DLD_FLAGS_HOOKVALID     0x2
44 #define DLD_FLAGS_LISTVALID     0x4
45 #define DLD_FLAGS_BOR_ENABLE    0x8
46
47 struct lm_info
48   {
49     /* Version of this structure (it is expected to change again in hpux10).  */
50     unsigned char struct_version;
51
52     /* Binding mode for this library.  */
53     unsigned char bind_mode;
54
55     /* Version of this library.  */
56     short library_version;
57
58     /* Start of text address,
59        link-time text location (length of text area),
60        end of text address.  */
61     CORE_ADDR text_addr;
62     CORE_ADDR text_link_addr;
63     CORE_ADDR text_end;
64
65     /* Start of data, start of bss and end of data.  */
66     CORE_ADDR data_start;
67     CORE_ADDR bss_start;
68     CORE_ADDR data_end;
69
70     /* Value of linkage pointer (%r19).  */
71     CORE_ADDR got_value;
72
73     /* Address in target of offset from thread-local register of
74        start of this thread's data.  I.e., the first thread-local
75        variable in this shared library starts at *(tsd_start_addr)
76        from that area pointed to by cr27 (mpsfu_hi).
77       
78        We do the indirection as soon as we read it, so from then
79        on it's the offset itself.  */
80     CORE_ADDR tsd_start_addr;
81
82     /* Address of the link map entry in the loader.  */
83     CORE_ADDR lm_addr;
84   };
85
86 /* These addresses should be filled in by som_solib_create_inferior_hook.
87    They are also used elsewhere in this module.
88  */
89 typedef struct
90   {
91     CORE_ADDR address;
92     struct unwind_table_entry *unwind;
93   }
94 addr_and_unwind_t;
95
96 /* When adding fields, be sure to clear them in _initialize_som_solib. */
97 static struct
98   {
99     int is_valid;
100     addr_and_unwind_t hook;
101     addr_and_unwind_t hook_stub;
102     addr_and_unwind_t load;
103     addr_and_unwind_t load_stub;
104     addr_and_unwind_t unload;
105     addr_and_unwind_t unload2;
106     addr_and_unwind_t unload_stub;
107   }
108 dld_cache;
109
110 static void
111 som_relocate_section_addresses (struct so_list *so,
112                                 struct section_table *sec)
113 {
114   flagword aflag = bfd_get_section_flags(so->abfd, sec->the_bfd_section);
115
116   /* solib.c does something similar, but it only recognizes ".text", SOM calls
117      the text section "$CODE$".  */
118   if (strcmp (sec->the_bfd_section->name, "$CODE$") == 0)
119     {
120       so->textsection = sec;
121     }
122
123   if (aflag & SEC_CODE)
124     {
125       sec->addr    += so->lm_info->text_addr - so->lm_info->text_link_addr; 
126       sec->endaddr += so->lm_info->text_addr - so->lm_info->text_link_addr;
127     }
128   else if (aflag & SEC_DATA)
129     {
130       sec->addr    += so->lm_info->data_start; 
131       sec->endaddr += so->lm_info->data_start;
132     }
133   else
134     ;
135 }
136
137 /* This hook gets called just before the first instruction in the
138    inferior process is executed.
139
140    This is our opportunity to set magic flags in the inferior so
141    that GDB can be notified when a shared library is mapped in and
142    to tell the dynamic linker that a private copy of the library is
143    needed (so GDB can set breakpoints in the library).
144
145    __dld_flags is the location of the magic flags; as of this implementation
146    there are 3 flags of interest:
147
148    bit 0 when set indicates that private copies of the libraries are needed
149    bit 1 when set indicates that the callback hook routine is valid
150    bit 2 when set indicates that the dynamic linker should maintain the
151    __dld_list structure when loading/unloading libraries.
152
153    Note that shared libraries are not mapped in at this time, so we have
154    run the inferior until the libraries are mapped in.  Typically this
155    means running until the "_start" is called.  */
156
157 static void
158 som_solib_create_inferior_hook (void)
159 {
160   struct minimal_symbol *msymbol;
161   unsigned int dld_flags, status, have_endo;
162   asection *shlib_info;
163   char buf[4];
164   CORE_ADDR anaddr;
165
166   /* First, remove all the solib event breakpoints.  Their addresses
167      may have changed since the last time we ran the program.  */
168   remove_solib_event_breakpoints ();
169
170   if (symfile_objfile == NULL)
171     return;
172
173   /* First see if the objfile was dynamically linked.  */
174   shlib_info = bfd_get_section_by_name (symfile_objfile->obfd, "$SHLIB_INFO$");
175   if (!shlib_info)
176     return;
177
178   /* It's got a $SHLIB_INFO$ section, make sure it's not empty.  */
179   if (bfd_section_size (symfile_objfile->obfd, shlib_info) == 0)
180     return;
181
182   have_endo = 0;
183   /* Slam the pid of the process into __d_pid.
184
185      We used to warn when this failed, but that warning is only useful
186      on very old HP systems (hpux9 and older).  The warnings are an
187      annoyance to users of modern systems and foul up the testsuite as
188      well.  As a result, the warnings have been disabled.  */
189   msymbol = lookup_minimal_symbol ("__d_pid", NULL, symfile_objfile);
190   if (msymbol == NULL)
191     goto keep_going;
192
193   anaddr = SYMBOL_VALUE_ADDRESS (msymbol);
194   store_unsigned_integer (buf, 4, PIDGET (inferior_ptid));
195   status = target_write_memory (anaddr, buf, 4);
196   if (status != 0)
197     {
198       warning (_("\
199 Unable to write __d_pid.\n\
200 Suggest linking with /opt/langtools/lib/end.o.\n\
201 GDB will be unable to track shl_load/shl_unload calls"));
202       goto keep_going;
203     }
204
205   /* Get the value of _DLD_HOOK (an export stub) and put it in __dld_hook;
206      This will force the dynamic linker to call __d_trap when significant
207      events occur.
208
209      Note that the above is the pre-HP-UX 9.0 behaviour.  At 9.0 and above,
210      the dld provides an export stub named "__d_trap" as well as the
211      function named "__d_trap" itself, but doesn't provide "_DLD_HOOK".
212      We'll look first for the old flavor and then the new.
213    */
214   msymbol = lookup_minimal_symbol ("_DLD_HOOK", NULL, symfile_objfile);
215   if (msymbol == NULL)
216     msymbol = lookup_minimal_symbol ("__d_trap", NULL, symfile_objfile);
217   if (msymbol == NULL)
218     {
219       warning (_("\
220 Unable to find _DLD_HOOK symbol in object file.\n\
221 Suggest linking with /opt/langtools/lib/end.o.\n\
222 GDB will be unable to track shl_load/shl_unload calls"));
223       goto keep_going;
224     }
225   anaddr = SYMBOL_VALUE_ADDRESS (msymbol);
226   dld_cache.hook.address = anaddr;
227
228   /* Grrr, this might not be an export symbol!  We have to find the
229      export stub.  */
230   msymbol = hppa_lookup_stub_minimal_symbol (SYMBOL_LINKAGE_NAME (msymbol),
231                                              EXPORT);
232   if (msymbol != NULL)
233     {
234       anaddr = SYMBOL_VALUE (msymbol);
235       dld_cache.hook_stub.address = anaddr;
236     }
237   store_unsigned_integer (buf, 4, anaddr);
238
239   msymbol = lookup_minimal_symbol ("__dld_hook", NULL, symfile_objfile);
240   if (msymbol == NULL)
241     {
242       warning (_("\
243 Unable to find __dld_hook symbol in object file.\n\
244 Suggest linking with /opt/langtools/lib/end.o.\n\
245 GDB will be unable to track shl_load/shl_unload calls"));
246       goto keep_going;
247     }
248   anaddr = SYMBOL_VALUE_ADDRESS (msymbol);
249   status = target_write_memory (anaddr, buf, 4);
250
251   /* Now set a shlib_event breakpoint at __d_trap so we can track
252      significant shared library events.  */
253   msymbol = lookup_minimal_symbol ("__d_trap", NULL, symfile_objfile);
254   if (msymbol == NULL)
255     {
256       warning (_("\
257 Unable to find __dld_d_trap symbol in object file.\n\
258 Suggest linking with /opt/langtools/lib/end.o.\n\
259 GDB will be unable to track shl_load/shl_unload calls"));
260       goto keep_going;
261     }
262   create_solib_event_breakpoint (SYMBOL_VALUE_ADDRESS (msymbol));
263
264   /* We have all the support usually found in end.o, so we can track
265      shl_load and shl_unload calls.  */
266   have_endo = 1;
267
268 keep_going:
269
270   /* Get the address of __dld_flags, if no such symbol exists, then we can
271      not debug the shared code.  */
272   msymbol = lookup_minimal_symbol ("__dld_flags", NULL, NULL);
273   if (msymbol == NULL)
274     {
275       error (_("Unable to find __dld_flags symbol in object file."));
276     }
277
278   anaddr = SYMBOL_VALUE_ADDRESS (msymbol);
279
280   /* Read the current contents.  */
281   status = target_read_memory (anaddr, buf, 4);
282   if (status != 0)
283     error (_("Unable to read __dld_flags."));
284   dld_flags = extract_unsigned_integer (buf, 4);
285
286   /* Turn on the flags we care about.  */
287   dld_flags |= DLD_FLAGS_MAPPRIVATE;
288   if (have_endo)
289     dld_flags |= DLD_FLAGS_HOOKVALID;
290   store_unsigned_integer (buf, 4, dld_flags);
291   status = target_write_memory (anaddr, buf, 4);
292   if (status != 0)
293     error (_("Unable to write __dld_flags."));
294
295   /* Now find the address of _start and set a breakpoint there. 
296      We still need this code for two reasons:
297
298      * Not all sites have /opt/langtools/lib/end.o, so it's not always
299      possible to track the dynamic linker's events.
300
301      * At this time no events are triggered for shared libraries
302      loaded at startup time (what a crock).  */
303
304   msymbol = lookup_minimal_symbol ("_start", NULL, symfile_objfile);
305   if (msymbol == NULL)
306     error (_("Unable to find _start symbol in object file."));
307
308   anaddr = SYMBOL_VALUE_ADDRESS (msymbol);
309
310   /* Make the breakpoint at "_start" a shared library event breakpoint.  */
311   create_solib_event_breakpoint (anaddr);
312
313   clear_symtab_users ();
314 }
315
316 /* This operation removes the "hook" between GDB and the dynamic linker,
317    which causes the dld to notify GDB of shared library events.
318
319    After this operation completes, the dld will no longer notify GDB of
320    shared library events.  To resume notifications, GDB must call
321    som_solib_create_inferior_hook.
322
323    This operation does not remove any knowledge of shared libraries
324    of which GDB may already have been notified.
325  */
326 static void
327 som_solib_remove_inferior_hook (int pid)
328 {
329   CORE_ADDR addr;
330   struct minimal_symbol *msymbol;
331   int status;
332   char dld_flags_buffer[4];
333   unsigned int dld_flags_value;
334   struct cleanup *old_cleanups = save_inferior_ptid ();
335
336   /* Ensure that we're really operating on the specified process. */
337   inferior_ptid = pid_to_ptid (pid);
338
339   /* We won't bother to remove the solib breakpoints from this process.
340
341      In fact, on PA64 the breakpoint is hard-coded into the dld callback,
342      and thus we're not supposed to remove it.
343
344      Rather, we'll merely clear the dld_flags bit that enables callbacks.
345    */
346   msymbol = lookup_minimal_symbol ("__dld_flags", NULL, NULL);
347
348   addr = SYMBOL_VALUE_ADDRESS (msymbol);
349   status = target_read_memory (addr, dld_flags_buffer, 4);
350
351   dld_flags_value = extract_unsigned_integer (dld_flags_buffer, 4);
352
353   dld_flags_value &= ~DLD_FLAGS_HOOKVALID;
354   store_unsigned_integer (dld_flags_buffer, 4, dld_flags_value);
355   status = target_write_memory (addr, dld_flags_buffer, 4);
356
357   do_cleanups (old_cleanups);
358 }
359
360 static void
361 som_special_symbol_handling (void)
362 {
363 }
364
365 static void
366 som_solib_desire_dynamic_linker_symbols (void)
367 {
368   struct objfile *objfile;
369   struct unwind_table_entry *u;
370   struct minimal_symbol *dld_msymbol;
371
372   /* Do we already know the value of these symbols?  If so, then
373      we've no work to do.
374
375      (If you add clauses to this test, be sure to likewise update the
376      test within the loop.)
377    */
378   if (dld_cache.is_valid)
379     return;
380
381   ALL_OBJFILES (objfile)
382   {
383     dld_msymbol = lookup_minimal_symbol ("shl_load", NULL, objfile);
384     if (dld_msymbol != NULL)
385       {
386         dld_cache.load.address = SYMBOL_VALUE (dld_msymbol);
387         dld_cache.load.unwind = find_unwind_entry (dld_cache.load.address);
388       }
389
390     dld_msymbol = lookup_minimal_symbol_solib_trampoline ("shl_load",
391                                                           objfile);
392     if (dld_msymbol != NULL)
393       {
394         if (SYMBOL_TYPE (dld_msymbol) == mst_solib_trampoline)
395           {
396             u = find_unwind_entry (SYMBOL_VALUE (dld_msymbol));
397             if ((u != NULL) && (u->stub_unwind.stub_type == EXPORT))
398               {
399                 dld_cache.load_stub.address = SYMBOL_VALUE (dld_msymbol);
400                 dld_cache.load_stub.unwind = u;
401               }
402           }
403       }
404
405     dld_msymbol = lookup_minimal_symbol ("shl_unload", NULL, objfile);
406     if (dld_msymbol != NULL)
407       {
408         dld_cache.unload.address = SYMBOL_VALUE (dld_msymbol);
409         dld_cache.unload.unwind = find_unwind_entry (dld_cache.unload.address);
410
411         /* ??rehrauer: I'm not sure exactly what this is, but it appears
412            that on some HPUX 10.x versions, there's two unwind regions to
413            cover the body of "shl_unload", the second being 4 bytes past
414            the end of the first.  This is a large hack to handle that
415            case, but since I don't seem to have any legitimate way to
416            look for this thing via the symbol table...
417          */
418         if (dld_cache.unload.unwind != NULL)
419           {
420             u = find_unwind_entry (dld_cache.unload.unwind->region_end + 4);
421             if (u != NULL)
422               {
423                 dld_cache.unload2.address = u->region_start;
424                 dld_cache.unload2.unwind = u;
425               }
426           }
427       }
428
429     dld_msymbol = lookup_minimal_symbol_solib_trampoline ("shl_unload",
430                                                           objfile);
431     if (dld_msymbol != NULL)
432       {
433         if (SYMBOL_TYPE (dld_msymbol) == mst_solib_trampoline)
434           {
435             u = find_unwind_entry (SYMBOL_VALUE (dld_msymbol));
436             if ((u != NULL) && (u->stub_unwind.stub_type == EXPORT))
437               {
438                 dld_cache.unload_stub.address = SYMBOL_VALUE (dld_msymbol);
439                 dld_cache.unload_stub.unwind = u;
440               }
441           }
442       }
443
444     /* Did we find everything we were looking for?  If so, stop. */
445     if ((dld_cache.load.address != 0)
446         && (dld_cache.load_stub.address != 0)
447         && (dld_cache.unload.address != 0)
448         && (dld_cache.unload_stub.address != 0))
449       {
450         dld_cache.is_valid = 1;
451         break;
452       }
453   }
454
455   dld_cache.hook.unwind = find_unwind_entry (dld_cache.hook.address);
456   dld_cache.hook_stub.unwind = find_unwind_entry (dld_cache.hook_stub.address);
457
458   /* We're prepared not to find some of these symbols, which is why
459      this function is a "desire" operation, and not a "require".
460    */
461 }
462
463 static int
464 som_in_dynsym_resolve_code (CORE_ADDR pc)
465 {
466   struct unwind_table_entry *u_pc;
467
468   /* Are we in the dld itself?
469
470      ??rehrauer: Large hack -- We'll assume that any address in a
471      shared text region is the dld's text.  This would obviously
472      fall down if the user attached to a process, whose shlibs
473      weren't mapped to a (writeable) private region.  However, in
474      that case the debugger probably isn't able to set the fundamental
475      breakpoint in the dld callback anyways, so this hack should be
476      safe.
477    */
478   if ((pc & (CORE_ADDR) 0xc0000000) == (CORE_ADDR) 0xc0000000)
479     return 1;
480
481   /* Cache the address of some symbols that are part of the dynamic
482      linker, if not already known.
483    */
484   som_solib_desire_dynamic_linker_symbols ();
485
486   /* Are we in the dld callback?  Or its export stub? */
487   u_pc = find_unwind_entry (pc);
488   if (u_pc == NULL)
489     return 0;
490
491   if ((u_pc == dld_cache.hook.unwind) || (u_pc == dld_cache.hook_stub.unwind))
492     return 1;
493
494   /* Or the interface of the dld (i.e., "shl_load" or friends)? */
495   if ((u_pc == dld_cache.load.unwind)
496       || (u_pc == dld_cache.unload.unwind)
497       || (u_pc == dld_cache.unload2.unwind)
498       || (u_pc == dld_cache.load_stub.unwind)
499       || (u_pc == dld_cache.unload_stub.unwind))
500     return 1;
501
502   /* Apparently this address isn't part of the dld's text. */
503   return 0;
504 }
505
506 static void
507 som_clear_solib (void)
508 {
509 }
510
511 struct dld_list {
512   char name[4];
513   char info[4];
514   char text_addr[4];
515   char text_link_addr[4];
516   char text_end[4];
517   char data_start[4];
518   char bss_start[4];
519   char data_end[4];
520   char got_value[4];
521   char next[4];
522   char tsd_start_addr_ptr[4];
523 };
524
525 static CORE_ADDR
526 link_map_start (void)
527 {
528   struct minimal_symbol *sym;
529   CORE_ADDR addr;
530   char buf[4];
531   unsigned int dld_flags;
532
533   sym = lookup_minimal_symbol ("__dld_flags", NULL, NULL);
534   if (!sym)
535     error (_("Unable to find __dld_flags symbol in object file."));
536   addr = SYMBOL_VALUE_ADDRESS (sym);
537   read_memory (addr, buf, 4);
538   dld_flags = extract_unsigned_integer (buf, 4);
539   if ((dld_flags & DLD_FLAGS_LISTVALID) == 0)
540     error (_("__dld_list is not valid according to __dld_flags."));
541
542   /* If the libraries were not mapped private, warn the user.  */
543   if ((dld_flags & DLD_FLAGS_MAPPRIVATE) == 0)
544     warning (_("The shared libraries were not privately mapped; setting a\n"
545              "breakpoint in a shared library will not work until you rerun the "
546              "program.\n"));
547
548   sym = lookup_minimal_symbol ("__dld_list", NULL, NULL);
549   if (!sym)
550     {
551       /* Older crt0.o files (hpux8) don't have __dld_list as a symbol,
552          but the data is still available if you know where to look.  */
553       sym = lookup_minimal_symbol ("__dld_flags", NULL, NULL);
554       if (!sym)
555         {
556           error (_("Unable to find dynamic library list."));
557           return 0;
558         }
559       addr = SYMBOL_VALUE_ADDRESS (sym) - 8;
560     }
561   else
562     addr = SYMBOL_VALUE_ADDRESS (sym);
563
564   read_memory (addr, buf, 4);
565   addr = extract_unsigned_integer (buf, 4);
566   if (addr == 0)
567     error (_("Debugging dynamic executables loaded via the hpux8 dld.sl is not supported."));
568
569   read_memory (addr, buf, 4);
570   return extract_unsigned_integer (buf, 4);
571 }
572
573 /* Does this so's name match the main binary? */
574 static int
575 match_main (const char *name)
576 {
577   return strcmp (name, symfile_objfile->name) == 0;
578 }
579
580 static struct so_list *
581 som_current_sos (void)
582 {
583   CORE_ADDR lm;
584   struct so_list *head = 0;
585   struct so_list **link_ptr = &head;
586
587   for (lm = link_map_start (); lm; )
588     {
589       char *namebuf;
590       CORE_ADDR addr;
591       struct so_list *new;
592       struct cleanup *old_chain;
593       int errcode;
594       struct dld_list dbuf;
595       char tsdbuf[4];
596
597       new = (struct so_list *) xmalloc (sizeof (struct so_list));
598       old_chain = make_cleanup (xfree, new);
599
600       memset (new, 0, sizeof (*new));
601       new->lm_info = xmalloc (sizeof (struct lm_info));
602       make_cleanup (xfree, new->lm_info);
603
604       read_memory (lm, (char *)&dbuf, sizeof (struct dld_list));
605
606       addr = extract_unsigned_integer (&dbuf.name, sizeof (dbuf.name));
607       target_read_string (addr, &namebuf, SO_NAME_MAX_PATH_SIZE - 1, &errcode);
608       if (errcode != 0)
609         warning (_("Can't read pathname for load map: %s."),
610                  safe_strerror (errcode));
611       else
612         {
613           strncpy (new->so_name, namebuf, SO_NAME_MAX_PATH_SIZE - 1);
614           new->so_name[SO_NAME_MAX_PATH_SIZE - 1] = '\0';
615           xfree (namebuf);
616           strcpy (new->so_original_name, new->so_name);
617         }
618
619         if (new->so_name[0] && !match_main (new->so_name))
620           {
621             struct lm_info *lmi = new->lm_info;
622             unsigned int tmp;
623
624             lmi->lm_addr = lm;
625
626 #define EXTRACT(_fld) \
627   extract_unsigned_integer (&dbuf._fld, sizeof (dbuf._fld));
628
629             lmi->text_addr = EXTRACT (text_addr);
630             tmp = EXTRACT (info);
631             lmi->library_version = (tmp >> 16) & 0xffff;
632             lmi->bind_mode = (tmp >> 8) & 0xff;
633             lmi->struct_version = tmp & 0xff;
634             lmi->text_link_addr = EXTRACT (text_link_addr);
635             lmi->text_end = EXTRACT (text_end);
636             lmi->data_start = EXTRACT (data_start);
637             lmi->bss_start = EXTRACT (bss_start);
638             lmi->data_end = EXTRACT (data_end);
639             lmi->got_value = EXTRACT (got_value);
640             tmp = EXTRACT (tsd_start_addr_ptr);
641             read_memory (tmp, tsdbuf, 4);
642             lmi->tsd_start_addr = extract_unsigned_integer (tsdbuf, 4);
643
644 #ifdef SOLIB_SOM_DBG
645             printf ("\n+ library \"%s\" is described at 0x%s\n", new->so_name, 
646                     paddr_nz (lm));
647             printf ("  'version' is %d\n", new->lm_info->struct_version);
648             printf ("  'bind_mode' is %d\n", new->lm_info->bind_mode);
649             printf ("  'library_version' is %d\n", 
650                     new->lm_info->library_version);
651             printf ("  'text_addr' is 0x%s\n", 
652                     paddr_nz (new->lm_info->text_addr));
653             printf ("  'text_link_addr' is 0x%s\n", 
654                     paddr_nz (new->lm_info->text_link_addr));
655             printf ("  'text_end' is 0x%s\n", 
656                     paddr_nz (new->lm_info->text_end));
657             printf ("  'data_start' is 0x%s\n", 
658                     paddr_nz (new->lm_info->data_start));
659             printf ("  'bss_start' is 0x%s\n", 
660                     paddr_nz (new->lm_info->bss_start));
661             printf ("  'data_end' is 0x%s\n", 
662                     paddr_nz (new->lm_info->data_end));
663             printf ("  'got_value' is %s\n", 
664                     paddr_nz (new->lm_info->got_value));
665             printf ("  'tsd_start_addr' is 0x%s\n", 
666                     paddr_nz (new->lm_info->tsd_start_addr));
667 #endif
668
669             /* Link the new object onto the list.  */
670             new->next = NULL;
671             *link_ptr = new;
672             link_ptr = &new->next;
673           }
674         else
675           {
676             free_so (new);
677           }
678
679       lm = EXTRACT (next);
680       discard_cleanups (old_chain);
681 #undef EXTRACT
682     }
683
684   /* TODO: The original somsolib code has logic to detect and eliminate 
685      duplicate entries.  Do we need that?  */
686
687   return head;
688 }
689
690 static int
691 som_open_symbol_file_object (void *from_ttyp)
692 {
693   CORE_ADDR lm, l_name;
694   char *filename;
695   int errcode;
696   int from_tty = *(int *)from_ttyp;
697   char buf[4];
698
699   if (symfile_objfile)
700     if (!query ("Attempt to reload symbols from process? "))
701       return 0;
702
703   /* First link map member should be the executable.  */
704   if ((lm = link_map_start ()) == 0)
705     return 0;   /* failed somehow... */
706
707   /* Read address of name from target memory to GDB.  */
708   read_memory (lm + offsetof (struct dld_list, name), buf, 4);
709
710   /* Convert the address to host format.  Assume that the address is
711      unsigned.  */
712   l_name = extract_unsigned_integer (buf, 4);
713
714   if (l_name == 0)
715     return 0;           /* No filename.  */
716
717   /* Now fetch the filename from target memory.  */
718   target_read_string (l_name, &filename, SO_NAME_MAX_PATH_SIZE - 1, &errcode);
719
720   if (errcode)
721     {
722       warning (_("failed to read exec filename from attached file: %s"),
723                safe_strerror (errcode));
724       return 0;
725     }
726
727   make_cleanup (xfree, filename);
728   /* Have a pathname: read the symbol file.  */
729   symbol_file_add_main (filename, from_tty);
730
731   return 1;
732 }
733
734 static void
735 som_free_so (struct so_list *so)
736 {
737   xfree (so->lm_info);
738 }
739
740 static CORE_ADDR
741 som_solib_thread_start_addr (struct so_list *so)
742 {
743   return so->lm_info->tsd_start_addr;
744 }
745
746 /* Return the GOT value for the shared library in which ADDR belongs.  If
747    ADDR isn't in any known shared library, return zero.  */
748
749 static CORE_ADDR
750 som_solib_get_got_by_pc (CORE_ADDR addr)
751 {
752   struct so_list *so_list = master_so_list ();
753   CORE_ADDR got_value = 0;
754
755   while (so_list)
756     {
757       if (so_list->lm_info->text_addr <= addr
758           && so_list->lm_info->text_end > addr)
759         {
760           got_value = so_list->lm_info->got_value;
761           break;
762         }
763       so_list = so_list->next;
764     }
765   return got_value;
766 }
767
768 /* Return the address of the handle of the shared library in which ADDR belongs.
769    If ADDR isn't in any known shared library, return zero.  */
770 /* this function is used in initialize_hp_cxx_exception_support in 
771    hppa-hpux-tdep.c  */
772
773 static CORE_ADDR
774 som_solib_get_solib_by_pc (CORE_ADDR addr)
775 {
776   struct so_list *so_list = master_so_list ();
777
778   while (so_list)
779     {
780       if (so_list->lm_info->text_addr <= addr
781           && so_list->lm_info->text_end > addr)
782         {
783           break;
784         }
785       so_list = so_list->next;
786     }
787   if (so_list)
788     return so_list->lm_info->lm_addr;
789   else
790     return 0;
791 }
792
793
794 static struct target_so_ops som_so_ops;
795
796 extern initialize_file_ftype _initialize_som_solib; /* -Wmissing-prototypes */
797
798 void
799 _initialize_som_solib (void)
800 {
801   som_so_ops.relocate_section_addresses = som_relocate_section_addresses;
802   som_so_ops.free_so = som_free_so;
803   som_so_ops.clear_solib = som_clear_solib;
804   som_so_ops.solib_create_inferior_hook = som_solib_create_inferior_hook;
805   som_so_ops.special_symbol_handling = som_special_symbol_handling;
806   som_so_ops.current_sos = som_current_sos;
807   som_so_ops.open_symbol_file_object = som_open_symbol_file_object;
808   som_so_ops.in_dynsym_resolve_code = som_in_dynsym_resolve_code;
809 }
810
811 void som_solib_select (struct gdbarch_tdep *tdep)
812 {
813   current_target_so_ops = &som_so_ops;
814
815   tdep->solib_thread_start_addr = som_solib_thread_start_addr;
816   tdep->solib_get_got_by_pc = som_solib_get_got_by_pc;
817   tdep->solib_get_solib_by_pc = som_solib_get_solib_by_pc;
818 }
819
820 /* The rest of these functions are not part of the solib interface; they 
821    are used by somread.c or hppa-hpux-tdep.c */
822
823 int
824 som_solib_section_offsets (struct objfile *objfile,
825                            struct section_offsets *offsets)
826 {
827   struct so_list *so_list = master_so_list ();
828
829   while (so_list)
830     {
831       /* Oh what a pain!  We need the offsets before so_list->objfile
832          is valid.  The BFDs will never match.  Make a best guess.  */
833       if (strstr (objfile->name, so_list->so_name))
834         {
835           asection *private_section;
836
837           /* The text offset is easy.  */
838           offsets->offsets[SECT_OFF_TEXT (objfile)]
839             = (so_list->lm_info->text_addr
840                - so_list->lm_info->text_link_addr);
841           offsets->offsets[SECT_OFF_RODATA (objfile)]
842             = ANOFFSET (offsets, SECT_OFF_TEXT (objfile));
843
844           /* We should look at presumed_dp in the SOM header, but
845              that's not easily available.  This should be OK though.  */
846           private_section = bfd_get_section_by_name (objfile->obfd,
847                                                      "$PRIVATE$");
848           if (!private_section)
849             {
850               warning (_("Unable to find $PRIVATE$ in shared library!"));
851               offsets->offsets[SECT_OFF_DATA (objfile)] = 0;
852               offsets->offsets[SECT_OFF_BSS (objfile)] = 0;
853               return 1;
854             }
855           offsets->offsets[SECT_OFF_DATA (objfile)]
856             = (so_list->lm_info->data_start - private_section->vma);
857           offsets->offsets[SECT_OFF_BSS (objfile)]
858             = ANOFFSET (offsets, SECT_OFF_DATA (objfile));
859           return 1;
860         }
861       so_list = so_list->next;
862     }
863   return 0;
864 }
This page took 0.074621 seconds and 4 git commands to generate.