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