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