* gdb.threads/linux-dp.exp: Recognize an additional message
[deliverable/binutils-gdb.git] / gdb / solib-aix5.c
CommitLineData
60cf7a85 1/* Handle AIX5 shared libraries for GDB, the GNU Debugger.
b6ba6518
KB
2 Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000,
3 2001
60cf7a85
KB
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 2 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, write to the Free Software
20 Foundation, Inc., 59 Temple Place - Suite 330,
21 Boston, MA 02111-1307, USA. */
22
23#include "defs.h"
24
25#include <sys/types.h>
26#include <signal.h>
27#include "gdb_string.h"
28#include <sys/param.h>
29#include <fcntl.h>
30#include <sys/procfs.h>
31
32#include "elf/external.h"
33
34#include "symtab.h"
35#include "bfd.h"
36#include "symfile.h"
37#include "objfiles.h"
38#include "gdbcore.h"
39#include "command.h"
40#include "target.h"
41#include "frame.h"
42#include "gdb_regex.h"
43#include "inferior.h"
44#include "environ.h"
45#include "language.h"
46#include "gdbcmd.h"
47
48#include "solist.h"
60cf7a85
KB
49
50/* Link map info to include in an allocated so_list entry */
51
52enum maptype {
53 MT_READONLY = 0,
54 MT_READWRITE = 1,
55 MT_LAST = 2
56};
57
58struct lm_info
59 {
60 struct
61 {
62 CORE_ADDR addr; /* base address */
63 CORE_ADDR size; /* size of mapped object */
64 CORE_ADDR offset; /* offset into mapped object */
65 long flags; /* MA_ protection and attribute flags */
66 CORE_ADDR gp; /* global pointer value */
67 } mapping[MT_LAST];
68 char *mapname; /* name in /proc/pid/object */
69 char *pathname; /* full pathname to object */
70 char *membername; /* member name in archive file */
71 };
72
0579d647
KB
73/* List of symbols in the dynamic linker where GDB can try to place
74 a breakpoint to monitor shared library events. */
60cf7a85
KB
75
76static char *solib_break_names[] =
77{
60cf7a85 78 "_r_debug_state",
60cf7a85
KB
79 NULL
80};
81
82static void aix5_relocate_main_executable (void);
83
84/*
85
86 LOCAL FUNCTION
87
88 bfd_lookup_symbol -- lookup the value for a specific symbol
89
90 SYNOPSIS
91
92 CORE_ADDR bfd_lookup_symbol (bfd *abfd, char *symname)
93
94 DESCRIPTION
95
96 An expensive way to lookup the value of a single symbol for
97 bfd's that are only temporary anyway. This is used by the
98 shared library support to find the address of the debugger
99 interface structures in the shared library.
100
101 Note that 0 is specifically allowed as an error return (no
102 such symbol).
103 */
104
105static CORE_ADDR
106bfd_lookup_symbol (bfd *abfd, char *symname)
107{
435b259c 108 long storage_needed;
60cf7a85
KB
109 asymbol *sym;
110 asymbol **symbol_table;
111 unsigned int number_of_symbols;
112 unsigned int i;
113 struct cleanup *back_to;
114 CORE_ADDR symaddr = 0;
115
116 storage_needed = bfd_get_symtab_upper_bound (abfd);
117
118 if (storage_needed > 0)
119 {
120 symbol_table = (asymbol **) xmalloc (storage_needed);
80117be2 121 back_to = make_cleanup (xfree, symbol_table);
60cf7a85
KB
122 number_of_symbols = bfd_canonicalize_symtab (abfd, symbol_table);
123
124 for (i = 0; i < number_of_symbols; i++)
125 {
126 sym = *symbol_table++;
0579d647 127 if (strcmp (sym->name, symname) == 0)
60cf7a85
KB
128 {
129 /* Bfd symbols are section relative. */
130 symaddr = sym->value + sym->section->vma;
131 break;
132 }
133 }
134 do_cleanups (back_to);
135 }
136
137 if (symaddr)
138 return symaddr;
139
0579d647 140 /* Look for the symbol in the dynamic string table too. */
60cf7a85
KB
141
142 storage_needed = bfd_get_dynamic_symtab_upper_bound (abfd);
60cf7a85
KB
143
144 if (storage_needed > 0)
145 {
146 symbol_table = (asymbol **) xmalloc (storage_needed);
80117be2 147 back_to = make_cleanup (xfree, symbol_table);
60cf7a85
KB
148 number_of_symbols = bfd_canonicalize_dynamic_symtab (abfd, symbol_table);
149
150 for (i = 0; i < number_of_symbols; i++)
151 {
152 sym = *symbol_table++;
0579d647 153 if (strcmp (sym->name, symname) == 0)
60cf7a85
KB
154 {
155 /* Bfd symbols are section relative. */
156 symaddr = sym->value + sym->section->vma;
157 break;
158 }
159 }
160 do_cleanups (back_to);
161 }
162
163 return symaddr;
164}
165
166
167/* Read /proc/PID/map and build a list of shared objects such that
168 the pr_mflags value AND'd with MATCH_MASK is equal to MATCH_VAL.
169 This gives us a convenient way to find all of the mappings that
170 don't belong to the main executable or vice versa. Here are
171 some of the possibilities:
172
173 - Fetch all mappings:
174 MATCH_MASK: 0
175 MATCH_VAL: 0
176 - Fetch all mappings except for main executable:
177 MATCH_MASK: MA_MAINEXEC
178 MATCH_VAL: 0
179 - Fetch only main executable:
180 MATCH_MASK: MA_MAINEXEC
181 MATCH_VAL: MA_MAINEXEC
182
183 A cleanup chain for the list allocations done by this function should
184 be established prior to calling build_so_list_from_mapfile(). */
185
186static struct so_list *
187build_so_list_from_mapfile (int pid, long match_mask, long match_val)
188{
189 char *mapbuf = NULL;
190 struct prmap *prmap;
191 int mapbuf_size;
192 struct so_list *sos = NULL;
193
194 {
195 int mapbuf_allocation_size = 8192;
196 char map_pathname[64];
197 int map_fd;
198
199 /* Open the map file */
200
80117be2 201 xasprintf (map_pathname, "/proc/%d/map", pid);
60cf7a85
KB
202 map_fd = open (map_pathname, O_RDONLY);
203 if (map_fd < 0)
204 return 0;
205
206 /* Read the entire map file in */
207 do
208 {
209 if (mapbuf)
210 {
80117be2 211 xfree (mapbuf);
60cf7a85
KB
212 mapbuf_allocation_size *= 2;
213 lseek (map_fd, 0, SEEK_SET);
214 }
215 mapbuf = xmalloc (mapbuf_allocation_size);
216 mapbuf_size = read (map_fd, mapbuf, mapbuf_allocation_size);
217 if (mapbuf_size < 0)
218 {
80117be2 219 xfree (mapbuf);
60cf7a85
KB
220 /* FIXME: This warrants an error or a warning of some sort */
221 return 0;
222 }
223 } while (mapbuf_size == mapbuf_allocation_size);
224
225 close (map_fd);
226 }
227
228 for (prmap = (struct prmap *) mapbuf;
229 (char *) prmap < mapbuf + mapbuf_size;
230 prmap++)
231 {
232 char *mapname, *pathname, *membername;
233 struct so_list *sop;
234 enum maptype maptype;
235
236 if (prmap->pr_size == 0)
237 break;
238
239 /* Skip to the next entry if there's no path associated with the
240 map, unless we're looking for the kernel text region, in which
241 case it's okay if there's no path. */
242 if ((prmap->pr_pathoff == 0 || prmap->pr_pathoff >= mapbuf_size)
243 && ((match_mask & MA_KERNTEXT) == 0))
244 continue;
245
246 /* Skip to the next entry if our match conditions don't hold. */
247 if ((prmap->pr_mflags & match_mask) != match_val)
248 continue;
249
250 mapname = prmap->pr_mapname;
251 if (prmap->pr_pathoff == 0)
252 {
253 pathname = "";
254 membername = "";
255 }
256 else
257 {
258 pathname = mapbuf + prmap->pr_pathoff;
259 membername = pathname + strlen (pathname) + 1;
260 }
261
262 for (sop = sos; sop != NULL; sop = sop->next)
263 if (strcmp (pathname, sop->lm_info->pathname) == 0
264 && strcmp (membername, sop->lm_info->membername) == 0)
265 break;
266
267 if (sop == NULL)
268 {
269 sop = xcalloc (sizeof (struct so_list), 1);
80117be2 270 make_cleanup (xfree, sop);
60cf7a85 271 sop->lm_info = xcalloc (sizeof (struct lm_info), 1);
80117be2 272 make_cleanup (xfree, sop->lm_info);
60cf7a85 273 sop->lm_info->mapname = xstrdup (mapname);
80117be2 274 make_cleanup (xfree, sop->lm_info->mapname);
60cf7a85
KB
275 /* FIXME: Eliminate the pathname field once length restriction
276 is lifted on so_name and so_original_name. */
277 sop->lm_info->pathname = xstrdup (pathname);
80117be2 278 make_cleanup (xfree, sop->lm_info->pathname);
60cf7a85 279 sop->lm_info->membername = xstrdup (membername);
80117be2 280 make_cleanup (xfree, sop->lm_info->membername);
60cf7a85
KB
281
282 strncpy (sop->so_name, pathname, SO_NAME_MAX_PATH_SIZE - 1);
283 sop->so_name[SO_NAME_MAX_PATH_SIZE - 1] = '\0';
284 strcpy (sop->so_original_name, sop->so_name);
285
286 sop->next = sos;
287 sos = sop;
288 }
289
290 maptype = (prmap->pr_mflags & MA_WRITE) ? MT_READWRITE : MT_READONLY;
291 sop->lm_info->mapping[maptype].addr = (CORE_ADDR) prmap->pr_vaddr;
292 sop->lm_info->mapping[maptype].size = prmap->pr_size;
293 sop->lm_info->mapping[maptype].offset = prmap->pr_off;
294 sop->lm_info->mapping[maptype].flags = prmap->pr_mflags;
295 sop->lm_info->mapping[maptype].gp = (CORE_ADDR) prmap->pr_gp;
296 }
297
80117be2 298 xfree (mapbuf);
60cf7a85
KB
299 return sos;
300}
301
302/*
303
304 LOCAL FUNCTION
305
306 open_symbol_file_object
307
308 SYNOPSIS
309
310 void open_symbol_file_object (void *from_tty)
311
312 DESCRIPTION
313
314 If no open symbol file, attempt to locate and open the main symbol
315 file.
316
317 If FROM_TTYP dereferences to a non-zero integer, allow messages to
318 be printed. This parameter is a pointer rather than an int because
319 open_symbol_file_object() is called via catch_errors() and
320 catch_errors() requires a pointer argument. */
321
322static int
323open_symbol_file_object (void *from_ttyp)
324{
325 CORE_ADDR lm, l_name;
326 char *filename;
327 int errcode;
328 int from_tty = *(int *)from_ttyp;
329 struct cleanup *old_chain = make_cleanup (null_cleanup, 0);
330 struct so_list *sos;
331
332 sos = build_so_list_from_mapfile (PIDGET (inferior_pid),
333 MA_MAINEXEC, MA_MAINEXEC);
334
335
336 if (sos == NULL)
337 {
338 warning ("Could not find name of main executable in map file");
339 return 0;
340 }
341
342 symbol_file_command (sos->lm_info->pathname, from_tty);
343
344 do_cleanups (old_chain);
345
346 aix5_relocate_main_executable ();
347
348 return 1;
349}
350
351/* LOCAL FUNCTION
352
353 aix5_current_sos -- build a list of currently loaded shared objects
354
355 SYNOPSIS
356
357 struct so_list *aix5_current_sos ()
358
359 DESCRIPTION
360
361 Build a list of `struct so_list' objects describing the shared
362 objects currently loaded in the inferior. This list does not
363 include an entry for the main executable file.
364
365 Note that we only gather information directly available from the
366 inferior --- we don't examine any of the shared library files
367 themselves. The declaration of `struct so_list' says which fields
368 we provide values for. */
369
370static struct so_list *
371aix5_current_sos (void)
372{
373 struct cleanup *old_chain = make_cleanup (null_cleanup, 0);
374 struct so_list *sos;
375
376 /* Fetch the list of mappings, excluding the main executable. */
377 sos = build_so_list_from_mapfile (PIDGET (inferior_pid), MA_MAINEXEC, 0);
378
379 /* Reverse the list; it looks nicer when we print it if the mappings
380 are in the same order as in the map file. */
381 if (sos)
382 {
383 struct so_list *next = sos->next;
384
385 sos->next = 0;
386 while (next)
387 {
388 struct so_list *prev = sos;
389
390 sos = next;
391 next = next->next;
392 sos->next = prev;
393 }
394 }
395 discard_cleanups (old_chain);
396 return sos;
397}
398
399
400/* Return 1 if PC lies in the dynamic symbol resolution code of the
0579d647 401 run time loader. */
60cf7a85
KB
402
403static CORE_ADDR interp_text_sect_low;
404static CORE_ADDR interp_text_sect_high;
405static CORE_ADDR interp_plt_sect_low;
406static CORE_ADDR interp_plt_sect_high;
407
d7fa2ae2
KB
408static int
409aix5_in_dynsym_resolve_code (CORE_ADDR pc)
60cf7a85
KB
410{
411 return ((pc >= interp_text_sect_low && pc < interp_text_sect_high)
412 || (pc >= interp_plt_sect_low && pc < interp_plt_sect_high)
413 || in_plt_section (pc, NULL));
414}
415
416/*
417
418 LOCAL FUNCTION
419
420 enable_break -- arrange for dynamic linker to hit breakpoint
421
422 SYNOPSIS
423
424 int enable_break (void)
425
426 DESCRIPTION
427
0579d647
KB
428 The dynamic linkers has, as part of its debugger interface, support
429 for arranging for the inferior to hit a breakpoint after mapping in
430 the shared libraries. This function enables that breakpoint.
431
60cf7a85
KB
432 */
433
434static int
435enable_break (void)
436{
437 int success = 0;
438
439 struct minimal_symbol *msymbol;
440 char **bkpt_namep;
441 asection *interp_sect;
442
443 /* First, remove all the solib event breakpoints. Their addresses
444 may have changed since the last time we ran the program. */
445 remove_solib_event_breakpoints ();
446
447 interp_text_sect_low = interp_text_sect_high = 0;
448 interp_plt_sect_low = interp_plt_sect_high = 0;
449
450 /* Find the .interp section; if not found, warn the user and drop
451 into the old breakpoint at symbol code. */
452 interp_sect = bfd_get_section_by_name (exec_bfd, ".interp");
453 if (interp_sect)
454 {
455 unsigned int interp_sect_size;
456 char *buf;
457 CORE_ADDR load_addr;
458 bfd *tmp_bfd;
459 CORE_ADDR sym_addr = 0;
460
461 /* Read the contents of the .interp section into a local buffer;
462 the contents specify the dynamic linker this program uses. */
463 interp_sect_size = bfd_section_size (exec_bfd, interp_sect);
464 buf = alloca (interp_sect_size);
465 bfd_get_section_contents (exec_bfd, interp_sect,
466 buf, 0, interp_sect_size);
467
468 /* Now we need to figure out where the dynamic linker was
469 loaded so that we can load its symbols and place a breakpoint
470 in the dynamic linker itself.
471
472 This address is stored on the stack. However, I've been unable
473 to find any magic formula to find it for Solaris (appears to
474 be trivial on GNU/Linux). Therefore, we have to try an alternate
475 mechanism to find the dynamic linker's base address. */
476 tmp_bfd = bfd_openr (buf, gnutarget);
477 if (tmp_bfd == NULL)
478 goto bkpt_at_symbol;
479
480 /* Make sure the dynamic linker's really a useful object. */
481 if (!bfd_check_format (tmp_bfd, bfd_object))
482 {
483 warning ("Unable to grok dynamic linker %s as an object file", buf);
484 bfd_close (tmp_bfd);
485 goto bkpt_at_symbol;
486 }
487
488 /* We find the dynamic linker's base address by examining the
489 current pc (which point at the entry point for the dynamic
490 linker) and subtracting the offset of the entry point. */
491 load_addr = read_pc () - tmp_bfd->start_address;
492
493 /* Record the relocated start and end address of the dynamic linker
d7fa2ae2 494 text and plt section for aix5_in_dynsym_resolve_code. */
60cf7a85
KB
495 interp_sect = bfd_get_section_by_name (tmp_bfd, ".text");
496 if (interp_sect)
497 {
498 interp_text_sect_low =
499 bfd_section_vma (tmp_bfd, interp_sect) + load_addr;
500 interp_text_sect_high =
501 interp_text_sect_low + bfd_section_size (tmp_bfd, interp_sect);
502 }
503 interp_sect = bfd_get_section_by_name (tmp_bfd, ".plt");
504 if (interp_sect)
505 {
506 interp_plt_sect_low =
507 bfd_section_vma (tmp_bfd, interp_sect) + load_addr;
508 interp_plt_sect_high =
509 interp_plt_sect_low + bfd_section_size (tmp_bfd, interp_sect);
510 }
511
512 /* Now try to set a breakpoint in the dynamic linker. */
513 for (bkpt_namep = solib_break_names; *bkpt_namep != NULL; bkpt_namep++)
514 {
515 sym_addr = bfd_lookup_symbol (tmp_bfd, *bkpt_namep);
516 if (sym_addr != 0)
517 break;
518 }
519
520 /* We're done with the temporary bfd. */
521 bfd_close (tmp_bfd);
522
523 if (sym_addr != 0)
524 {
525 create_solib_event_breakpoint (load_addr + sym_addr);
526 return 1;
527 }
528
529 /* For whatever reason we couldn't set a breakpoint in the dynamic
530 linker. Warn and drop into the old code. */
531 bkpt_at_symbol:
532 warning ("Unable to find dynamic linker breakpoint function.\nGDB will be unable to debug shared library initializers\nand track explicitly loaded dynamic code.");
533 }
534
60cf7a85
KB
535 /* Nothing good happened. */
536 success = 0;
537
538 return (success);
539}
540
541/*
542
543 LOCAL FUNCTION
544
545 special_symbol_handling -- additional shared library symbol handling
546
547 SYNOPSIS
548
549 void special_symbol_handling ()
550
551 DESCRIPTION
552
553 Once the symbols from a shared object have been loaded in the usual
554 way, we are called to do any system specific symbol handling that
555 is needed.
556
557 */
558
559static void
560aix5_special_symbol_handling (void)
561{
562 /* Nothing needed (yet) for AIX5. */
563}
564
565#define SECTMAPMASK (~ (CORE_ADDR) 0x03ffffff)
566
567static void
568aix5_relocate_main_executable (void)
569{
570 struct so_list *so;
571 struct section_offsets *new_offsets;
572 int i;
573 int changed = 0;
574 struct cleanup *old_chain = make_cleanup (null_cleanup, 0);
575
576 /* Fetch the mappings for the main executable from the map file. */
577 so = build_so_list_from_mapfile (PIDGET (inferior_pid),
578 MA_MAINEXEC, MA_MAINEXEC);
579
580 /* Make sure we actually have some mappings to work with. */
581 if (so == NULL)
582 {
583 warning ("Could not find main executable in map file");
584 do_cleanups (old_chain);
585 return;
586 }
587
588 /* Allocate the data structure which'll contain the new offsets to
589 relocate by. Initialize it so it contains the current offsets. */
590 new_offsets = xcalloc (sizeof (struct section_offsets),
591 symfile_objfile->num_sections);
80117be2 592 make_cleanup (xfree, new_offsets);
60cf7a85 593 for (i = 0; i < symfile_objfile->num_sections; i++)
d112a051 594 new_offsets->offsets[i] = ANOFFSET (symfile_objfile->section_offsets, i);
60cf7a85
KB
595
596 /* Iterate over the mappings in the main executable and compute
597 the new offset value as appropriate. */
598 for (i = 0; i < MT_LAST; i++)
599 {
600 CORE_ADDR increment = 0;
601 struct obj_section *sect;
602 bfd *obfd = symfile_objfile->obfd;
603
604 ALL_OBJFILE_OSECTIONS (symfile_objfile, sect)
605 {
606 int flags = bfd_get_section_flags (obfd, sect->the_bfd_section);
607 if (flags & SEC_ALLOC)
608 {
609 if (((so->lm_info->mapping[i].flags & MA_WRITE) == 0)
610 == ((flags & SEC_READONLY) != 0))
611 {
612 int idx = sect->the_bfd_section->index;
613
614 if (increment == 0)
615 increment = so->lm_info->mapping[i].addr
616 - (bfd_section_vma (obfd, sect->the_bfd_section)
617 & SECTMAPMASK);
618
619 if (increment != ANOFFSET (new_offsets, idx))
620 {
d112a051 621 new_offsets->offsets[idx] = increment;
60cf7a85
KB
622 changed = 1;
623 }
624 }
625 }
626 }
627 }
628
629 /* If any of the offsets have changed, then relocate the objfile. */
630 if (changed)
631 objfile_relocate (symfile_objfile, new_offsets);
632
633 /* Free up all the space we've allocated. */
634 do_cleanups (old_chain);
635}
636
637/*
638
639 GLOBAL FUNCTION
640
641 aix5_solib_create_inferior_hook -- shared library startup support
642
643 SYNOPSIS
644
645 void aix5_solib_create_inferior_hook()
646
647 DESCRIPTION
648
649 When gdb starts up the inferior, it nurses it along (through the
650 shell) until it is ready to execute it's first instruction. At this
651 point, this function gets called via expansion of the macro
652 SOLIB_CREATE_INFERIOR_HOOK.
653
0579d647 654 For AIX5 executables, this first instruction is the first
60cf7a85
KB
655 instruction in the dynamic linker (for dynamically linked
656 executables) or the instruction at "start" for statically linked
657 executables. For dynamically linked executables, the system
0579d647 658 first exec's libc.so.N, which contains the dynamic linker,
60cf7a85
KB
659 and starts it running. The dynamic linker maps in any needed
660 shared libraries, maps in the actual user executable, and then
661 jumps to "start" in the user executable.
662
663 */
664
665static void
666aix5_solib_create_inferior_hook (void)
667{
668 aix5_relocate_main_executable ();
669
670 if (!enable_break ())
671 {
672 warning ("shared library handler failed to enable breakpoint");
673 return;
674 }
675}
676
677static void
678aix5_clear_solib (void)
679{
680}
681
682static void
683aix5_free_so (struct so_list *so)
684{
80117be2
KB
685 xfree (so->lm_info->mapname);
686 xfree (so->lm_info->pathname);
687 xfree (so->lm_info->membername);
688 xfree (so->lm_info);
60cf7a85
KB
689}
690
691static void
692aix5_relocate_section_addresses (struct so_list *so,
693 struct section_table *sec)
694{
695 int flags = bfd_get_section_flags (sec->bfd, sec->the_bfd_section);
696
697 if (flags & SEC_ALLOC)
698 {
699 int idx = (flags & SEC_READONLY) ? MT_READONLY : MT_READWRITE;
700 CORE_ADDR addr = so->lm_info->mapping[idx].addr;
701
702 sec->addr += addr;
703 sec->endaddr += addr;
704 }
705}
706
707/* Find the global pointer for the given function address ADDR. */
708
709static CORE_ADDR
710aix5_find_global_pointer (CORE_ADDR addr)
711{
712 struct so_list *sos, *so;
713 CORE_ADDR global_pointer = 0;
714 struct cleanup *old_chain = make_cleanup (null_cleanup, 0);
715
716 sos = build_so_list_from_mapfile (PIDGET (inferior_pid), 0, 0);
717
718 for (so = sos; so != NULL; so = so->next)
719 {
720 if (so->lm_info->mapping[MT_READONLY].addr <= addr
721 && addr <= so->lm_info->mapping[MT_READONLY].addr
722 + so->lm_info->mapping[MT_READONLY].size)
723 {
724 global_pointer = so->lm_info->mapping[MT_READWRITE].gp;
725 break;
726 }
727 }
728
729 do_cleanups (old_chain);
730
731 return global_pointer;
732}
733
734/* Find the execute-only kernel region known as the gate page. This
735 page is where the signal trampoline lives. It may be found by
736 querying the map file and looking for the MA_KERNTEXT flag. */
737static void
738aix5_find_gate_addresses (CORE_ADDR *start, CORE_ADDR *end)
739{
740 struct so_list *so;
741 struct cleanup *old_chain = make_cleanup (null_cleanup, 0);
742
743 /* Fetch the mappings for the main executable from the map file. */
744 so = build_so_list_from_mapfile (PIDGET (inferior_pid),
745 MA_KERNTEXT, MA_KERNTEXT);
746
747 /* Make sure we actually have some mappings to work with. */
748 if (so == NULL)
749 {
750 warning ("Could not find gate page in map file");
751 *start = 0;
752 *end = 0;
753 do_cleanups (old_chain);
754 return;
755 }
756
757 /* There should only be on kernel mapping for the gate page and
758 it'll be in the read-only (even though it's execute-only)
759 mapping in the lm_info struct. */
760
761 *start = so->lm_info->mapping[MT_READONLY].addr;
762 *end = *start + so->lm_info->mapping[MT_READONLY].size;
763
764 /* Free up all the space we've allocated. */
765 do_cleanups (old_chain);
766}
767
768/* From ia64-tdep.c. FIXME: If we end up using this for rs6000 too,
769 we'll need to make the names match. */
770extern CORE_ADDR (*native_find_global_pointer) (CORE_ADDR);
771
772/* From ia64-aix-tdep.c. Hook for finding the starting and
773 ending gate page addresses. The only reason that this hook
774 is in this file is because this is where the map file reading
775 code is located. */
776extern void (*aix5_find_gate_addresses_hook) (CORE_ADDR *, CORE_ADDR *);
777
778static struct target_so_ops aix5_so_ops;
779
780void
781_initialize_aix5_solib (void)
782{
783 aix5_so_ops.relocate_section_addresses = aix5_relocate_section_addresses;
784 aix5_so_ops.free_so = aix5_free_so;
785 aix5_so_ops.clear_solib = aix5_clear_solib;
786 aix5_so_ops.solib_create_inferior_hook = aix5_solib_create_inferior_hook;
787 aix5_so_ops.special_symbol_handling = aix5_special_symbol_handling;
788 aix5_so_ops.current_sos = aix5_current_sos;
789 aix5_so_ops.open_symbol_file_object = open_symbol_file_object;
d7fa2ae2 790 aix5_so_ops.in_dynsym_resolve_code = aix5_in_dynsym_resolve_code;
60cf7a85
KB
791
792 native_find_global_pointer = aix5_find_global_pointer;
793 aix5_find_gate_addresses_hook = aix5_find_gate_addresses;
794
795 /* FIXME: Don't do this here. *_gdbarch_init() should set so_ops. */
796 current_target_so_ops = &aix5_so_ops;
797}
This page took 0.056452 seconds and 4 git commands to generate.