Automatic date update in version.in
[platform/upstream/binutils.git] / gdb / solib-som.c
1 /* Handle SOM shared libraries.
2
3    Copyright (C) 2004-2014 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 3 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, see <http://www.gnu.org/licenses/>.  */
19
20 #include "defs.h"
21 #include "symtab.h"
22 #include "bfd.h"
23 #include "symfile.h"
24 #include "objfiles.h"
25 #include "gdbcore.h"
26 #include "target.h"
27 #include "inferior.h"
28
29 #include "hppa-tdep.h"
30 #include "solist.h"
31 #include "solib.h"
32 #include "solib-som.h"
33
34 #undef SOLIB_SOM_DBG 
35
36 /* These ought to be defined in some public interface, but aren't.  They
37    define the meaning of the various bits in the distinguished __dld_flags
38    variable that is declared in every debuggable a.out on HP-UX, and that
39    is shared between the debugger and the dynamic linker.  */
40
41 #define DLD_FLAGS_MAPPRIVATE    0x1
42 #define DLD_FLAGS_HOOKVALID     0x2
43 #define DLD_FLAGS_LISTVALID     0x4
44 #define DLD_FLAGS_BOR_ENABLE    0x8
45
46 struct lm_info
47   {
48     /* Version of this structure (it is expected to change again in
49        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 target_section *sec)
113 {
114   flagword aflag = bfd_get_section_flags(so->abfd, sec->the_bfd_section);
115
116   if (aflag & SEC_CODE)
117     {
118       sec->addr    += so->lm_info->text_addr - so->lm_info->text_link_addr; 
119       sec->endaddr += so->lm_info->text_addr - so->lm_info->text_link_addr;
120     }
121   else if (aflag & SEC_DATA)
122     {
123       sec->addr    += so->lm_info->data_start; 
124       sec->endaddr += so->lm_info->data_start;
125     }
126   else
127     {
128       /* Nothing.  */
129     }
130 }
131
132
133 /* Variable storing HP-UX major release number.
134
135    On non-native system, simply assume that the major release number
136    is 11.  On native systems, hppa-hpux-nat.c initialization code
137    sets this number to the real one on startup.
138    
139    We cannot compute this value here, because we need to make a native
140    call to "uname".  We are are not allowed to do that from here, as
141    this file is used for both native and cross debugging.  */
142
143 #define DEFAULT_HPUX_MAJOR_RELEASE 11
144 int hpux_major_release = DEFAULT_HPUX_MAJOR_RELEASE;
145
146 static int
147 get_hpux_major_release (void)
148 {
149   return hpux_major_release;
150 }
151
152 /* DL header flag defines.  */
153 #define SHLIB_TEXT_PRIVATE_ENABLE 0x4000
154
155 /* The DL header is documented in <shl.h>.  We are only interested
156    in the flags field to determine whether the executable wants shared
157    libraries mapped private.  */
158 struct {
159     short junk[37];
160     short flags;
161 } dl_header;
162
163 /* This hook gets called just before the first instruction in the
164    inferior process is executed.
165
166    This is our opportunity to set magic flags in the inferior so
167    that GDB can be notified when a shared library is mapped in and
168    to tell the dynamic linker that a private copy of the library is
169    needed (so GDB can set breakpoints in the library).
170
171    __dld_flags is the location of the magic flags; as of this implementation
172    there are 3 flags of interest:
173
174    bit 0 when set indicates that private copies of the libraries are needed
175    bit 1 when set indicates that the callback hook routine is valid
176    bit 2 when set indicates that the dynamic linker should maintain the
177    __dld_list structure when loading/unloading libraries.
178
179    Note that shared libraries are not mapped in at this time, so we have
180    run the inferior until the libraries are mapped in.  Typically this
181    means running until the "_start" is called.  */
182
183 static void
184 som_solib_create_inferior_hook (int from_tty)
185 {
186   enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch ());
187   struct bound_minimal_symbol msymbol;
188   unsigned int dld_flags, status, have_endo;
189   asection *shlib_info;
190   gdb_byte buf[4];
191   CORE_ADDR anaddr;
192
193   if (symfile_objfile == NULL)
194     return;
195
196   /* First see if the objfile was dynamically linked.  */
197   shlib_info = bfd_get_section_by_name (symfile_objfile->obfd, "$SHLIB_INFO$");
198   if (!shlib_info)
199     return;
200
201   /* It's got a $SHLIB_INFO$ section, make sure it's not empty.  */
202   if (bfd_section_size (symfile_objfile->obfd, shlib_info) == 0)
203     return;
204
205   /* Read the DL header.  */
206   bfd_get_section_contents (symfile_objfile->obfd, shlib_info,
207                             (char *) &dl_header, 0, sizeof (dl_header));
208
209   have_endo = 0;
210   /* Slam the pid of the process into __d_pid.
211
212      We used to warn when this failed, but that warning is only useful
213      on very old HP systems (hpux9 and older).  The warnings are an
214      annoyance to users of modern systems and foul up the testsuite as
215      well.  As a result, the warnings have been disabled.  */
216   msymbol = lookup_minimal_symbol ("__d_pid", NULL, symfile_objfile);
217   if (msymbol.minsym == NULL)
218     goto keep_going;
219
220   anaddr = BMSYMBOL_VALUE_ADDRESS (msymbol);
221   store_unsigned_integer (buf, 4, byte_order, ptid_get_pid (inferior_ptid));
222   status = target_write_memory (anaddr, buf, 4);
223   if (status != 0)
224     {
225       warning (_("\
226 Unable to write __d_pid.\n\
227 Suggest linking with /opt/langtools/lib/end.o.\n\
228 GDB will be unable to track shl_load/shl_unload calls"));
229       goto keep_going;
230     }
231
232   /* Get the value of _DLD_HOOK (an export stub) and put it in __dld_hook;
233      This will force the dynamic linker to call __d_trap when significant
234      events occur.
235
236      Note that the above is the pre-HP-UX 9.0 behaviour.  At 9.0 and above,
237      the dld provides an export stub named "__d_trap" as well as the
238      function named "__d_trap" itself, but doesn't provide "_DLD_HOOK".
239      We'll look first for the old flavor and then the new.  */
240
241   msymbol = lookup_minimal_symbol ("_DLD_HOOK", NULL, symfile_objfile);
242   if (msymbol.minsym == NULL)
243     msymbol = lookup_minimal_symbol ("__d_trap", NULL, symfile_objfile);
244   if (msymbol.minsym == NULL)
245     {
246       warning (_("\
247 Unable to find _DLD_HOOK symbol in object file.\n\
248 Suggest linking with /opt/langtools/lib/end.o.\n\
249 GDB will be unable to track shl_load/shl_unload calls"));
250       goto keep_going;
251     }
252   anaddr = BMSYMBOL_VALUE_ADDRESS (msymbol);
253   dld_cache.hook.address = anaddr;
254
255   /* Grrr, this might not be an export symbol!  We have to find the
256      export stub.  */
257   msymbol
258     = hppa_lookup_stub_minimal_symbol (MSYMBOL_LINKAGE_NAME (msymbol.minsym),
259                                        EXPORT);
260   if (msymbol.minsym != NULL)
261     {
262       anaddr = MSYMBOL_VALUE (msymbol.minsym);
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.minsym == 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 = BMSYMBOL_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.minsym == 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                                  BMSYMBOL_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.minsym == NULL)
303     {
304       error (_("Unable to find __dld_flags symbol in object file."));
305     }
306
307   anaddr = BMSYMBOL_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.minsym == NULL)
350     error (_("Unable to find _start symbol in object file."));
351
352   anaddr = BMSYMBOL_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 bound_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.minsym != NULL)
385       {
386         dld_cache.load.address = MSYMBOL_VALUE (dld_msymbol.minsym);
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.minsym != NULL)
393       {
394         if (MSYMBOL_TYPE (dld_msymbol.minsym) == mst_solib_trampoline)
395           {
396             u = find_unwind_entry (MSYMBOL_VALUE (dld_msymbol.minsym));
397             if ((u != NULL) && (u->stub_unwind.stub_type == EXPORT))
398               {
399                 dld_cache.load_stub.address
400                   = MSYMBOL_VALUE (dld_msymbol.minsym);
401                 dld_cache.load_stub.unwind = u;
402               }
403           }
404       }
405
406     dld_msymbol = lookup_minimal_symbol ("shl_unload", NULL, objfile);
407     if (dld_msymbol.minsym != NULL)
408       {
409         dld_cache.unload.address = MSYMBOL_VALUE (dld_msymbol.minsym);
410         dld_cache.unload.unwind = find_unwind_entry (dld_cache.unload.address);
411
412         /* ??rehrauer: I'm not sure exactly what this is, but it appears
413            that on some HPUX 10.x versions, there's two unwind regions to
414            cover the body of "shl_unload", the second being 4 bytes past
415            the end of the first.  This is a large hack to handle that
416            case, but since I don't seem to have any legitimate way to
417            look for this thing via the symbol table...  */
418
419         if (dld_cache.unload.unwind != NULL)
420           {
421             u = find_unwind_entry (dld_cache.unload.unwind->region_end + 4);
422             if (u != NULL)
423               {
424                 dld_cache.unload2.address = u->region_start;
425                 dld_cache.unload2.unwind = u;
426               }
427           }
428       }
429
430     dld_msymbol = lookup_minimal_symbol_solib_trampoline ("shl_unload",
431                                                           objfile);
432     if (dld_msymbol.minsym != NULL)
433       {
434         if (MSYMBOL_TYPE (dld_msymbol.minsym) == mst_solib_trampoline)
435           {
436             u = find_unwind_entry (MSYMBOL_VALUE (dld_msymbol.minsym));
437             if ((u != NULL) && (u->stub_unwind.stub_type == EXPORT))
438               {
439                 dld_cache.unload_stub.address
440                   = MSYMBOL_VALUE (dld_msymbol.minsym);
441                 dld_cache.unload_stub.unwind = u;
442               }
443           }
444       }
445
446     /* Did we find everything we were looking for?  If so, stop.  */
447     if ((dld_cache.load.address != 0)
448         && (dld_cache.load_stub.address != 0)
449         && (dld_cache.unload.address != 0)
450         && (dld_cache.unload_stub.address != 0))
451       {
452         dld_cache.is_valid = 1;
453         break;
454       }
455   }
456
457   dld_cache.hook.unwind = find_unwind_entry (dld_cache.hook.address);
458   dld_cache.hook_stub.unwind = find_unwind_entry (dld_cache.hook_stub.address);
459
460   /* We're prepared not to find some of these symbols, which is why
461      this function is a "desire" operation, and not a "require".  */
462 }
463
464 static int
465 som_in_dynsym_resolve_code (CORE_ADDR pc)
466 {
467   struct unwind_table_entry *u_pc;
468
469   /* Are we in the dld itself?
470
471      ??rehrauer: Large hack -- We'll assume that any address in a
472      shared text region is the dld's text.  This would obviously
473      fall down if the user attached to a process, whose shlibs
474      weren't mapped to a (writeable) private region.  However, in
475      that case the debugger probably isn't able to set the fundamental
476      breakpoint in the dld callback anyways, so this hack should be
477      safe.  */
478
479   if ((pc & (CORE_ADDR) 0xc0000000) == (CORE_ADDR) 0xc0000000)
480     return 1;
481
482   /* Cache the address of some symbols that are part of the dynamic
483      linker, if not already known.  */
484
485   som_solib_desire_dynamic_linker_symbols ();
486
487   /* Are we in the dld callback?  Or its export stub?  */
488   u_pc = find_unwind_entry (pc);
489   if (u_pc == NULL)
490     return 0;
491
492   if ((u_pc == dld_cache.hook.unwind) || (u_pc == dld_cache.hook_stub.unwind))
493     return 1;
494
495   /* Or the interface of the dld (i.e., "shl_load" or friends)?  */
496   if ((u_pc == dld_cache.load.unwind)
497       || (u_pc == dld_cache.unload.unwind)
498       || (u_pc == dld_cache.unload2.unwind)
499       || (u_pc == dld_cache.load_stub.unwind)
500       || (u_pc == dld_cache.unload_stub.unwind))
501     return 1;
502
503   /* Apparently this address isn't part of the dld's text.  */
504   return 0;
505 }
506
507 static void
508 som_clear_solib (void)
509 {
510 }
511
512 struct dld_list {
513   char name[4];
514   char info[4];
515   char text_addr[4];
516   char text_link_addr[4];
517   char text_end[4];
518   char data_start[4];
519   char bss_start[4];
520   char data_end[4];
521   char got_value[4];
522   char next[4];
523   char tsd_start_addr_ptr[4];
524 };
525
526 static CORE_ADDR
527 link_map_start (void)
528 {
529   enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch ());
530   struct bound_minimal_symbol sym;
531   CORE_ADDR addr;
532   gdb_byte buf[4];
533   unsigned int dld_flags;
534
535   sym = lookup_minimal_symbol ("__dld_flags", NULL, NULL);
536   if (!sym.minsym)
537     error (_("Unable to find __dld_flags symbol in object file."));
538   addr = BMSYMBOL_VALUE_ADDRESS (sym);
539   read_memory (addr, buf, 4);
540   dld_flags = extract_unsigned_integer (buf, 4, byte_order);
541   if ((dld_flags & DLD_FLAGS_LISTVALID) == 0)
542     error (_("__dld_list is not valid according to __dld_flags."));
543
544   sym = lookup_minimal_symbol ("__dld_list", NULL, NULL);
545   if (!sym.minsym)
546     {
547       /* Older crt0.o files (hpux8) don't have __dld_list as a symbol,
548          but the data is still available if you know where to look.  */
549       sym = lookup_minimal_symbol ("__dld_flags", NULL, NULL);
550       if (!sym.minsym)
551         {
552           error (_("Unable to find dynamic library list."));
553           return 0;
554         }
555       addr = BMSYMBOL_VALUE_ADDRESS (sym) - 8;
556     }
557   else
558     addr = BMSYMBOL_VALUE_ADDRESS (sym);
559
560   read_memory (addr, buf, 4);
561   addr = extract_unsigned_integer (buf, 4, byte_order);
562   if (addr == 0)
563     return 0;
564
565   read_memory (addr, buf, 4);
566   return extract_unsigned_integer (buf, 4, byte_order);
567 }
568
569 /* Does this so's name match the main binary?  */
570 static int
571 match_main (const char *name)
572 {
573   return strcmp (name, objfile_name (symfile_objfile)) == 0;
574 }
575
576 static struct so_list *
577 som_current_sos (void)
578 {
579   enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch ());
580   CORE_ADDR lm;
581   struct so_list *head = 0;
582   struct so_list **link_ptr = &head;
583
584   for (lm = link_map_start (); lm; )
585     {
586       char *namebuf;
587       CORE_ADDR addr;
588       struct so_list *new;
589       struct cleanup *old_chain;
590       int errcode;
591       struct dld_list dbuf;
592       gdb_byte tsdbuf[4];
593
594       new = (struct so_list *) xmalloc (sizeof (struct so_list));
595       old_chain = make_cleanup (xfree, new);
596
597       memset (new, 0, sizeof (*new));
598       new->lm_info = xmalloc (sizeof (struct lm_info));
599       make_cleanup (xfree, new->lm_info);
600
601       read_memory (lm, (gdb_byte *)&dbuf, sizeof (struct dld_list));
602
603       addr = extract_unsigned_integer ((gdb_byte *)&dbuf.name,
604                                        sizeof (dbuf.name), byte_order);
605       target_read_string (addr, &namebuf, SO_NAME_MAX_PATH_SIZE - 1, &errcode);
606       if (errcode != 0)
607         warning (_("Can't read pathname for load map: %s."),
608                  safe_strerror (errcode));
609       else
610         {
611           strncpy (new->so_name, namebuf, SO_NAME_MAX_PATH_SIZE - 1);
612           new->so_name[SO_NAME_MAX_PATH_SIZE - 1] = '\0';
613           xfree (namebuf);
614           strcpy (new->so_original_name, new->so_name);
615         }
616
617         if (new->so_name[0] && !match_main (new->so_name))
618           {
619             struct lm_info *lmi = new->lm_info;
620             unsigned int tmp;
621
622             lmi->lm_addr = lm;
623
624 #define EXTRACT(_fld) \
625   extract_unsigned_integer ((gdb_byte *)&dbuf._fld, \
626                             sizeof (dbuf._fld), byte_order);
627
628             lmi->text_addr = EXTRACT (text_addr);
629             tmp = EXTRACT (info);
630             lmi->library_version = (tmp >> 16) & 0xffff;
631             lmi->bind_mode = (tmp >> 8) & 0xff;
632             lmi->struct_version = tmp & 0xff;
633             lmi->text_link_addr = EXTRACT (text_link_addr);
634             lmi->text_end = EXTRACT (text_end);
635             lmi->data_start = EXTRACT (data_start);
636             lmi->bss_start = EXTRACT (bss_start);
637             lmi->data_end = EXTRACT (data_end);
638             lmi->got_value = EXTRACT (got_value);
639             tmp = EXTRACT (tsd_start_addr_ptr);
640             read_memory (tmp, tsdbuf, 4);
641             lmi->tsd_start_addr
642               = extract_unsigned_integer (tsdbuf, 4, byte_order);
643
644 #ifdef SOLIB_SOM_DBG
645             printf ("\n+ library \"%s\" is described at %s\n", new->so_name,
646                     paddress (target_gdbarch (), 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 %s\n",
652                     paddress (target_gdbarch (), new->lm_info->text_addr));
653             printf ("  'text_link_addr' is %s\n",
654                     paddress (target_gdbarch (), new->lm_info->text_link_addr));
655             printf ("  'text_end' is %s\n",
656                     paddress (target_gdbarch (), new->lm_info->text_end));
657             printf ("  'data_start' is %s\n",
658                     paddress (target_gdbarch (), new->lm_info->data_start));
659             printf ("  'bss_start' is %s\n",
660                     paddress (target_gdbarch (), new->lm_info->bss_start));
661             printf ("  'data_end' is %s\n",
662                     paddress (target_gdbarch (), new->lm_info->data_end));
663             printf ("  'got_value' is %s\n",
664                     paddress (target_gdbarch (), new->lm_info->got_value));
665             printf ("  'tsd_start_addr' is %s\n",
666                     paddress (target_gdbarch (), new->lm_info->tsd_start_addr));
667 #endif
668
669             new->addr_low = lmi->text_addr;
670             new->addr_high = lmi->text_end;
671
672             /* Link the new object onto the list.  */
673             new->next = NULL;
674             *link_ptr = new;
675             link_ptr = &new->next;
676           }
677         else
678           {
679             free_so (new);
680           }
681
682       lm = EXTRACT (next);
683       discard_cleanups (old_chain);
684 #undef EXTRACT
685     }
686
687   /* TODO: The original somsolib code has logic to detect and eliminate 
688      duplicate entries.  Do we need that?  */
689
690   return head;
691 }
692
693 static int
694 som_open_symbol_file_object (void *from_ttyp)
695 {
696   enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch ());
697   CORE_ADDR lm, l_name;
698   char *filename;
699   int errcode;
700   int from_tty = *(int *)from_ttyp;
701   gdb_byte buf[4];
702   struct cleanup *cleanup;
703
704   if (symfile_objfile)
705     if (!query (_("Attempt to reload symbols from process? ")))
706       return 0;
707
708   /* First link map member should be the executable.  */
709   if ((lm = link_map_start ()) == 0)
710     return 0;   /* failed somehow...  */
711
712   /* Read address of name from target memory to GDB.  */
713   read_memory (lm + offsetof (struct dld_list, name), buf, 4);
714
715   /* Convert the address to host format.  Assume that the address is
716      unsigned.  */
717   l_name = extract_unsigned_integer (buf, 4, byte_order);
718
719   if (l_name == 0)
720     return 0;           /* No filename.  */
721
722   /* Now fetch the filename from target memory.  */
723   target_read_string (l_name, &filename, SO_NAME_MAX_PATH_SIZE - 1, &errcode);
724
725   if (errcode)
726     {
727       warning (_("failed to read exec filename from attached file: %s"),
728                safe_strerror (errcode));
729       return 0;
730     }
731
732   cleanup = make_cleanup (xfree, filename);
733   /* Have a pathname: read the symbol file.  */
734   symbol_file_add_main (filename, from_tty);
735
736   do_cleanups (cleanup);
737   return 1;
738 }
739
740 static void
741 som_free_so (struct so_list *so)
742 {
743   xfree (so->lm_info);
744 }
745
746 static CORE_ADDR
747 som_solib_thread_start_addr (struct so_list *so)
748 {
749   return so->lm_info->tsd_start_addr;
750 }
751
752 /* Return the GOT value for the shared library in which ADDR belongs.  If
753    ADDR isn't in any known shared library, return zero.  */
754
755 static CORE_ADDR
756 som_solib_get_got_by_pc (CORE_ADDR addr)
757 {
758   struct so_list *so_list = master_so_list ();
759   CORE_ADDR got_value = 0;
760
761   while (so_list)
762     {
763       if (so_list->lm_info->text_addr <= addr
764           && so_list->lm_info->text_end > addr)
765         {
766           got_value = so_list->lm_info->got_value;
767           break;
768         }
769       so_list = so_list->next;
770     }
771   return got_value;
772 }
773
774 /* Return the address of the handle of the shared library in which
775    ADDR belongs.  If ADDR isn't in any known shared library, return
776    zero.  */
777 /* This function is used in initialize_hp_cxx_exception_support in 
778    hppa-hpux-tdep.c.  */
779
780 static CORE_ADDR
781 som_solib_get_solib_by_pc (CORE_ADDR addr)
782 {
783   struct so_list *so_list = master_so_list ();
784
785   while (so_list)
786     {
787       if (so_list->lm_info->text_addr <= addr
788           && so_list->lm_info->text_end > addr)
789         {
790           break;
791         }
792       so_list = so_list->next;
793     }
794   if (so_list)
795     return so_list->lm_info->lm_addr;
796   else
797     return 0;
798 }
799
800
801 static struct target_so_ops som_so_ops;
802
803 extern initialize_file_ftype _initialize_som_solib; /* -Wmissing-prototypes */
804
805 void
806 _initialize_som_solib (void)
807 {
808   som_so_ops.relocate_section_addresses = som_relocate_section_addresses;
809   som_so_ops.free_so = som_free_so;
810   som_so_ops.clear_solib = som_clear_solib;
811   som_so_ops.solib_create_inferior_hook = som_solib_create_inferior_hook;
812   som_so_ops.special_symbol_handling = som_special_symbol_handling;
813   som_so_ops.current_sos = som_current_sos;
814   som_so_ops.open_symbol_file_object = som_open_symbol_file_object;
815   som_so_ops.in_dynsym_resolve_code = som_in_dynsym_resolve_code;
816   som_so_ops.bfd_open = solib_bfd_open;
817 }
818
819 void
820 som_solib_select (struct gdbarch *gdbarch)
821 {
822   struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
823
824   set_solib_ops (gdbarch, &som_so_ops);
825   tdep->solib_thread_start_addr = som_solib_thread_start_addr;
826   tdep->solib_get_got_by_pc = som_solib_get_got_by_pc;
827   tdep->solib_get_solib_by_pc = som_solib_get_solib_by_pc;
828 }
829
830 /* The rest of these functions are not part of the solib interface; they 
831    are used by somread.c or hppa-hpux-tdep.c.  */
832
833 int
834 som_solib_section_offsets (struct objfile *objfile,
835                            struct section_offsets *offsets)
836 {
837   struct so_list *so_list = master_so_list ();
838
839   while (so_list)
840     {
841       /* Oh what a pain!  We need the offsets before so_list->objfile
842          is valid.  The BFDs will never match.  Make a best guess.  */
843       if (strstr (objfile_name (objfile), so_list->so_name))
844         {
845           asection *private_section;
846           struct obj_section *sect;
847
848           /* The text offset is easy.  */
849           offsets->offsets[SECT_OFF_TEXT (objfile)]
850             = (so_list->lm_info->text_addr
851                - so_list->lm_info->text_link_addr);
852
853           /* We should look at presumed_dp in the SOM header, but
854              that's not easily available.  This should be OK though.  */
855           private_section = bfd_get_section_by_name (objfile->obfd,
856                                                      "$PRIVATE$");
857           if (!private_section)
858             {
859               warning (_("Unable to find $PRIVATE$ in shared library!"));
860               offsets->offsets[SECT_OFF_DATA (objfile)] = 0;
861               offsets->offsets[SECT_OFF_BSS (objfile)] = 0;
862               return 1;
863             }
864           if (objfile->sect_index_data != -1)
865             {
866               offsets->offsets[SECT_OFF_DATA (objfile)]
867                 = (so_list->lm_info->data_start - private_section->vma);
868               if (objfile->sect_index_bss != -1)
869                 offsets->offsets[SECT_OFF_BSS (objfile)]
870                   = ANOFFSET (offsets, SECT_OFF_DATA (objfile));
871             }
872
873           ALL_OBJFILE_OSECTIONS (objfile, sect)
874             {
875               flagword flags = bfd_get_section_flags (objfile->obfd,
876                                                       sect->the_bfd_section);
877
878               if ((flags & SEC_CODE) != 0)
879                 offsets->offsets[sect->the_bfd_section->index]
880                   = offsets->offsets[SECT_OFF_TEXT (objfile)];
881               else
882                 offsets->offsets[sect->the_bfd_section->index]
883                   = offsets->offsets[SECT_OFF_DATA (objfile)];
884             }
885
886           return 1;
887         }
888       so_list = so_list->next;
889     }
890   return 0;
891 }