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