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