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