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
som_relocate_section_addresses(struct so_list * so,struct section_table * sec)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
som_solib_create_inferior_hook(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
som_solib_remove_inferior_hook(int pid)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
som_special_symbol_handling(void)361 som_special_symbol_handling (void)
362 {
363 }
364 
365 static void
som_solib_desire_dynamic_linker_symbols(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
som_in_dynsym_resolve_code(CORE_ADDR pc)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
som_clear_solib(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
link_map_start(void)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
match_main(const char * name)575 match_main (const char *name)
576 {
577   return strcmp (name, symfile_objfile->name) == 0;
578 }
579 
580 static struct so_list *
som_current_sos(void)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
som_open_symbol_file_object(void * from_ttyp)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
som_free_so(struct so_list * so)735 som_free_so (struct so_list *so)
736 {
737   xfree (so->lm_info);
738 }
739 
740 static CORE_ADDR
som_solib_thread_start_addr(struct so_list * so)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
som_solib_get_got_by_pc(CORE_ADDR 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
som_solib_get_solib_by_pc(CORE_ADDR 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
_initialize_som_solib(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 
som_solib_select(struct gdbarch_tdep * tdep)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
som_solib_section_offsets(struct objfile * objfile,struct section_offsets * offsets)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 }
865