]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - gdb/solib-aix5.c
Copyright updates for 2007.
[thirdparty/binutils-gdb.git] / gdb / solib-aix5.c
CommitLineData
60cf7a85 1/* Handle AIX5 shared libraries for GDB, the GNU Debugger.
197e01b6 2 Copyright (C) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000,
6aba47ca 3 2001, 2007 Free Software Foundation, Inc.
60cf7a85
KB
4
5 This file is part of GDB.
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
197e01b6
EZ
19 Foundation, Inc., 51 Franklin Street, Fifth Floor,
20 Boston, MA 02110-1301, USA. */
60cf7a85
KB
21
22#include "defs.h"
23
24#include <sys/types.h>
25#include <signal.h>
26#include "gdb_string.h"
27#include <sys/param.h>
28#include <fcntl.h>
29#include <sys/procfs.h>
30
31#include "elf/external.h"
32
33#include "symtab.h"
34#include "bfd.h"
35#include "symfile.h"
36#include "objfiles.h"
37#include "gdbcore.h"
38#include "command.h"
39#include "target.h"
40#include "frame.h"
41#include "gdb_regex.h"
42#include "inferior.h"
43#include "environ.h"
44#include "language.h"
45#include "gdbcmd.h"
46
47#include "solist.h"
60cf7a85
KB
48
49/* Link map info to include in an allocated so_list entry */
50
60cf7a85
KB
51struct lm_info
52 {
6c98e688
KB
53 int nmappings; /* number of mappings */
54 struct lm_mapping
60cf7a85
KB
55 {
56 CORE_ADDR addr; /* base address */
57 CORE_ADDR size; /* size of mapped object */
58 CORE_ADDR offset; /* offset into mapped object */
59 long flags; /* MA_ protection and attribute flags */
60 CORE_ADDR gp; /* global pointer value */
6c98e688 61 } *mapping;
60cf7a85
KB
62 char *mapname; /* name in /proc/pid/object */
63 char *pathname; /* full pathname to object */
64 char *membername; /* member name in archive file */
65 };
66
0579d647
KB
67/* List of symbols in the dynamic linker where GDB can try to place
68 a breakpoint to monitor shared library events. */
60cf7a85
KB
69
70static char *solib_break_names[] =
71{
60cf7a85 72 "_r_debug_state",
60cf7a85
KB
73 NULL
74};
75
76static void aix5_relocate_main_executable (void);
77
78/*
79
80 LOCAL FUNCTION
81
82 bfd_lookup_symbol -- lookup the value for a specific symbol
83
84 SYNOPSIS
85
86 CORE_ADDR bfd_lookup_symbol (bfd *abfd, char *symname)
87
88 DESCRIPTION
89
90 An expensive way to lookup the value of a single symbol for
91 bfd's that are only temporary anyway. This is used by the
92 shared library support to find the address of the debugger
93 interface structures in the shared library.
94
95 Note that 0 is specifically allowed as an error return (no
96 such symbol).
97 */
98
99static CORE_ADDR
100bfd_lookup_symbol (bfd *abfd, char *symname)
101{
435b259c 102 long storage_needed;
60cf7a85
KB
103 asymbol *sym;
104 asymbol **symbol_table;
105 unsigned int number_of_symbols;
106 unsigned int i;
107 struct cleanup *back_to;
108 CORE_ADDR symaddr = 0;
109
110 storage_needed = bfd_get_symtab_upper_bound (abfd);
111
112 if (storage_needed > 0)
113 {
114 symbol_table = (asymbol **) xmalloc (storage_needed);
80117be2 115 back_to = make_cleanup (xfree, symbol_table);
60cf7a85
KB
116 number_of_symbols = bfd_canonicalize_symtab (abfd, symbol_table);
117
118 for (i = 0; i < number_of_symbols; i++)
119 {
120 sym = *symbol_table++;
0579d647 121 if (strcmp (sym->name, symname) == 0)
60cf7a85
KB
122 {
123 /* Bfd symbols are section relative. */
124 symaddr = sym->value + sym->section->vma;
125 break;
126 }
127 }
128 do_cleanups (back_to);
129 }
130
131 if (symaddr)
132 return symaddr;
133
0579d647 134 /* Look for the symbol in the dynamic string table too. */
60cf7a85
KB
135
136 storage_needed = bfd_get_dynamic_symtab_upper_bound (abfd);
60cf7a85
KB
137
138 if (storage_needed > 0)
139 {
140 symbol_table = (asymbol **) xmalloc (storage_needed);
80117be2 141 back_to = make_cleanup (xfree, symbol_table);
60cf7a85
KB
142 number_of_symbols = bfd_canonicalize_dynamic_symtab (abfd, symbol_table);
143
144 for (i = 0; i < number_of_symbols; i++)
145 {
146 sym = *symbol_table++;
0579d647 147 if (strcmp (sym->name, symname) == 0)
60cf7a85
KB
148 {
149 /* Bfd symbols are section relative. */
150 symaddr = sym->value + sym->section->vma;
151 break;
152 }
153 }
154 do_cleanups (back_to);
155 }
156
157 return symaddr;
158}
159
160
161/* Read /proc/PID/map and build a list of shared objects such that
162 the pr_mflags value AND'd with MATCH_MASK is equal to MATCH_VAL.
163 This gives us a convenient way to find all of the mappings that
164 don't belong to the main executable or vice versa. Here are
165 some of the possibilities:
166
167 - Fetch all mappings:
168 MATCH_MASK: 0
169 MATCH_VAL: 0
170 - Fetch all mappings except for main executable:
171 MATCH_MASK: MA_MAINEXEC
172 MATCH_VAL: 0
173 - Fetch only main executable:
174 MATCH_MASK: MA_MAINEXEC
175 MATCH_VAL: MA_MAINEXEC
176
177 A cleanup chain for the list allocations done by this function should
178 be established prior to calling build_so_list_from_mapfile(). */
179
180static struct so_list *
181build_so_list_from_mapfile (int pid, long match_mask, long match_val)
182{
183 char *mapbuf = NULL;
184 struct prmap *prmap;
185 int mapbuf_size;
186 struct so_list *sos = NULL;
187
188 {
189 int mapbuf_allocation_size = 8192;
224d8953 190 char *map_pathname;
60cf7a85
KB
191 int map_fd;
192
193 /* Open the map file */
194
b435e160 195 map_pathname = xstrprintf ("/proc/%d/map", pid);
60cf7a85 196 map_fd = open (map_pathname, O_RDONLY);
ed817e68 197 xfree (map_pathname);
60cf7a85
KB
198 if (map_fd < 0)
199 return 0;
200
201 /* Read the entire map file in */
202 do
203 {
204 if (mapbuf)
205 {
80117be2 206 xfree (mapbuf);
60cf7a85
KB
207 mapbuf_allocation_size *= 2;
208 lseek (map_fd, 0, SEEK_SET);
209 }
210 mapbuf = xmalloc (mapbuf_allocation_size);
211 mapbuf_size = read (map_fd, mapbuf, mapbuf_allocation_size);
212 if (mapbuf_size < 0)
213 {
80117be2 214 xfree (mapbuf);
60cf7a85
KB
215 /* FIXME: This warrants an error or a warning of some sort */
216 return 0;
217 }
218 } while (mapbuf_size == mapbuf_allocation_size);
219
220 close (map_fd);
221 }
222
223 for (prmap = (struct prmap *) mapbuf;
224 (char *) prmap < mapbuf + mapbuf_size;
225 prmap++)
226 {
227 char *mapname, *pathname, *membername;
228 struct so_list *sop;
6c98e688 229 int mapidx;
60cf7a85
KB
230
231 if (prmap->pr_size == 0)
232 break;
233
234 /* Skip to the next entry if there's no path associated with the
235 map, unless we're looking for the kernel text region, in which
236 case it's okay if there's no path. */
237 if ((prmap->pr_pathoff == 0 || prmap->pr_pathoff >= mapbuf_size)
238 && ((match_mask & MA_KERNTEXT) == 0))
239 continue;
240
241 /* Skip to the next entry if our match conditions don't hold. */
242 if ((prmap->pr_mflags & match_mask) != match_val)
243 continue;
244
245 mapname = prmap->pr_mapname;
246 if (prmap->pr_pathoff == 0)
247 {
248 pathname = "";
249 membername = "";
250 }
251 else
252 {
253 pathname = mapbuf + prmap->pr_pathoff;
254 membername = pathname + strlen (pathname) + 1;
255 }
256
257 for (sop = sos; sop != NULL; sop = sop->next)
258 if (strcmp (pathname, sop->lm_info->pathname) == 0
259 && strcmp (membername, sop->lm_info->membername) == 0)
260 break;
261
262 if (sop == NULL)
263 {
13fc0c2f 264 sop = xcalloc (1, sizeof (struct so_list));
80117be2 265 make_cleanup (xfree, sop);
13fc0c2f 266 sop->lm_info = xcalloc (1, sizeof (struct lm_info));
80117be2 267 make_cleanup (xfree, sop->lm_info);
60cf7a85 268 sop->lm_info->mapname = xstrdup (mapname);
80117be2 269 make_cleanup (xfree, sop->lm_info->mapname);
60cf7a85
KB
270 /* FIXME: Eliminate the pathname field once length restriction
271 is lifted on so_name and so_original_name. */
272 sop->lm_info->pathname = xstrdup (pathname);
80117be2 273 make_cleanup (xfree, sop->lm_info->pathname);
60cf7a85 274 sop->lm_info->membername = xstrdup (membername);
80117be2 275 make_cleanup (xfree, sop->lm_info->membername);
60cf7a85
KB
276
277 strncpy (sop->so_name, pathname, SO_NAME_MAX_PATH_SIZE - 1);
278 sop->so_name[SO_NAME_MAX_PATH_SIZE - 1] = '\0';
279 strcpy (sop->so_original_name, sop->so_name);
280
281 sop->next = sos;
282 sos = sop;
283 }
284
6c98e688
KB
285 mapidx = sop->lm_info->nmappings;
286 sop->lm_info->nmappings += 1;
287 sop->lm_info->mapping
288 = xrealloc (sop->lm_info->mapping,
289 sop->lm_info->nmappings * sizeof (struct lm_mapping));
290 sop->lm_info->mapping[mapidx].addr = (CORE_ADDR) prmap->pr_vaddr;
291 sop->lm_info->mapping[mapidx].size = prmap->pr_size;
292 sop->lm_info->mapping[mapidx].offset = prmap->pr_off;
293 sop->lm_info->mapping[mapidx].flags = prmap->pr_mflags;
294 sop->lm_info->mapping[mapidx].gp = (CORE_ADDR) prmap->pr_gp;
60cf7a85
KB
295 }
296
80117be2 297 xfree (mapbuf);
60cf7a85
KB
298 return sos;
299}
300
301/*
302
303 LOCAL FUNCTION
304
305 open_symbol_file_object
306
307 SYNOPSIS
308
309 void open_symbol_file_object (void *from_tty)
310
311 DESCRIPTION
312
313 If no open symbol file, attempt to locate and open the main symbol
314 file.
315
316 If FROM_TTYP dereferences to a non-zero integer, allow messages to
317 be printed. This parameter is a pointer rather than an int because
318 open_symbol_file_object() is called via catch_errors() and
319 catch_errors() requires a pointer argument. */
320
321static int
322open_symbol_file_object (void *from_ttyp)
323{
324 CORE_ADDR lm, l_name;
325 char *filename;
326 int errcode;
327 int from_tty = *(int *)from_ttyp;
328 struct cleanup *old_chain = make_cleanup (null_cleanup, 0);
329 struct so_list *sos;
330
39f77062 331 sos = build_so_list_from_mapfile (PIDGET (inferior_ptid),
60cf7a85
KB
332 MA_MAINEXEC, MA_MAINEXEC);
333
334
335 if (sos == NULL)
336 {
8a3fe4f8 337 warning (_("Could not find name of main executable in map file"));
60cf7a85
KB
338 return 0;
339 }
340
341 symbol_file_command (sos->lm_info->pathname, from_tty);
342
343 do_cleanups (old_chain);
344
345 aix5_relocate_main_executable ();
346
347 return 1;
348}
349
350/* LOCAL FUNCTION
351
352 aix5_current_sos -- build a list of currently loaded shared objects
353
354 SYNOPSIS
355
356 struct so_list *aix5_current_sos ()
357
358 DESCRIPTION
359
360 Build a list of `struct so_list' objects describing the shared
361 objects currently loaded in the inferior. This list does not
362 include an entry for the main executable file.
363
364 Note that we only gather information directly available from the
365 inferior --- we don't examine any of the shared library files
366 themselves. The declaration of `struct so_list' says which fields
367 we provide values for. */
368
369static struct so_list *
370aix5_current_sos (void)
371{
372 struct cleanup *old_chain = make_cleanup (null_cleanup, 0);
373 struct so_list *sos;
374
375 /* Fetch the list of mappings, excluding the main executable. */
39f77062 376 sos = build_so_list_from_mapfile (PIDGET (inferior_ptid), MA_MAINEXEC, 0);
60cf7a85
KB
377
378 /* Reverse the list; it looks nicer when we print it if the mappings
379 are in the same order as in the map file. */
380 if (sos)
381 {
382 struct so_list *next = sos->next;
383
384 sos->next = 0;
385 while (next)
386 {
387 struct so_list *prev = sos;
388
389 sos = next;
390 next = next->next;
391 sos->next = prev;
392 }
393 }
394 discard_cleanups (old_chain);
395 return sos;
396}
397
398
399/* Return 1 if PC lies in the dynamic symbol resolution code of the
0579d647 400 run time loader. */
60cf7a85
KB
401
402static CORE_ADDR interp_text_sect_low;
403static CORE_ADDR interp_text_sect_high;
404static CORE_ADDR interp_plt_sect_low;
405static CORE_ADDR interp_plt_sect_high;
406
d7fa2ae2
KB
407static int
408aix5_in_dynsym_resolve_code (CORE_ADDR pc)
60cf7a85
KB
409{
410 return ((pc >= interp_text_sect_low && pc < interp_text_sect_high)
411 || (pc >= interp_plt_sect_low && pc < interp_plt_sect_high)
412 || in_plt_section (pc, NULL));
413}
414
415/*
416
417 LOCAL FUNCTION
418
419 enable_break -- arrange for dynamic linker to hit breakpoint
420
421 SYNOPSIS
422
423 int enable_break (void)
424
425 DESCRIPTION
426
0579d647
KB
427 The dynamic linkers has, as part of its debugger interface, support
428 for arranging for the inferior to hit a breakpoint after mapping in
429 the shared libraries. This function enables that breakpoint.
430
60cf7a85
KB
431 */
432
433static int
434enable_break (void)
435{
436 int success = 0;
437
438 struct minimal_symbol *msymbol;
439 char **bkpt_namep;
440 asection *interp_sect;
441
442 /* First, remove all the solib event breakpoints. Their addresses
443 may have changed since the last time we ran the program. */
444 remove_solib_event_breakpoints ();
445
446 interp_text_sect_low = interp_text_sect_high = 0;
447 interp_plt_sect_low = interp_plt_sect_high = 0;
448
449 /* Find the .interp section; if not found, warn the user and drop
450 into the old breakpoint at symbol code. */
451 interp_sect = bfd_get_section_by_name (exec_bfd, ".interp");
452 if (interp_sect)
453 {
454 unsigned int interp_sect_size;
455 char *buf;
456 CORE_ADDR load_addr;
457 bfd *tmp_bfd;
458 CORE_ADDR sym_addr = 0;
459
460 /* Read the contents of the .interp section into a local buffer;
461 the contents specify the dynamic linker this program uses. */
462 interp_sect_size = bfd_section_size (exec_bfd, interp_sect);
463 buf = alloca (interp_sect_size);
464 bfd_get_section_contents (exec_bfd, interp_sect,
465 buf, 0, interp_sect_size);
466
467 /* Now we need to figure out where the dynamic linker was
468 loaded so that we can load its symbols and place a breakpoint
469 in the dynamic linker itself.
470
471 This address is stored on the stack. However, I've been unable
472 to find any magic formula to find it for Solaris (appears to
473 be trivial on GNU/Linux). Therefore, we have to try an alternate
474 mechanism to find the dynamic linker's base address. */
475 tmp_bfd = bfd_openr (buf, gnutarget);
476 if (tmp_bfd == NULL)
477 goto bkpt_at_symbol;
478
479 /* Make sure the dynamic linker's really a useful object. */
480 if (!bfd_check_format (tmp_bfd, bfd_object))
481 {
8a3fe4f8 482 warning (_("Unable to grok dynamic linker %s as an object file"), buf);
60cf7a85
KB
483 bfd_close (tmp_bfd);
484 goto bkpt_at_symbol;
485 }
486
487 /* We find the dynamic linker's base address by examining the
488 current pc (which point at the entry point for the dynamic
489 linker) and subtracting the offset of the entry point. */
490 load_addr = read_pc () - tmp_bfd->start_address;
491
492 /* Record the relocated start and end address of the dynamic linker
d7fa2ae2 493 text and plt section for aix5_in_dynsym_resolve_code. */
60cf7a85
KB
494 interp_sect = bfd_get_section_by_name (tmp_bfd, ".text");
495 if (interp_sect)
496 {
497 interp_text_sect_low =
498 bfd_section_vma (tmp_bfd, interp_sect) + load_addr;
499 interp_text_sect_high =
500 interp_text_sect_low + bfd_section_size (tmp_bfd, interp_sect);
501 }
502 interp_sect = bfd_get_section_by_name (tmp_bfd, ".plt");
503 if (interp_sect)
504 {
505 interp_plt_sect_low =
506 bfd_section_vma (tmp_bfd, interp_sect) + load_addr;
507 interp_plt_sect_high =
508 interp_plt_sect_low + bfd_section_size (tmp_bfd, interp_sect);
509 }
510
511 /* Now try to set a breakpoint in the dynamic linker. */
512 for (bkpt_namep = solib_break_names; *bkpt_namep != NULL; bkpt_namep++)
513 {
514 sym_addr = bfd_lookup_symbol (tmp_bfd, *bkpt_namep);
515 if (sym_addr != 0)
516 break;
517 }
518
519 /* We're done with the temporary bfd. */
520 bfd_close (tmp_bfd);
521
522 if (sym_addr != 0)
523 {
524 create_solib_event_breakpoint (load_addr + sym_addr);
525 return 1;
526 }
527
528 /* For whatever reason we couldn't set a breakpoint in the dynamic
529 linker. Warn and drop into the old code. */
530 bkpt_at_symbol:
8a3fe4f8 531 warning (_("Unable to find dynamic linker breakpoint function.\nGDB will be unable to debug shared library initializers\nand track explicitly loaded dynamic code."));
60cf7a85
KB
532 }
533
60cf7a85
KB
534 /* Nothing good happened. */
535 success = 0;
536
537 return (success);
538}
539
540/*
541
542 LOCAL FUNCTION
543
544 special_symbol_handling -- additional shared library symbol handling
545
546 SYNOPSIS
547
548 void special_symbol_handling ()
549
550 DESCRIPTION
551
552 Once the symbols from a shared object have been loaded in the usual
553 way, we are called to do any system specific symbol handling that
554 is needed.
555
556 */
557
558static void
559aix5_special_symbol_handling (void)
560{
561 /* Nothing needed (yet) for AIX5. */
562}
563
00c7912d
KB
564/* On AIX5, the /proc/PID/map information is used to determine
565 the relocation offsets needed for relocating the main executable.
566 There is no problem determining which map entries correspond
567 to the main executable, because these will have the MA_MAINEXEC
568 flag set. The tricky part is determining which sections correspond
569 to which map entries. To date, the following approaches have
570 been tried:
571
572 - Use the MA_WRITE attribute of pr_mflags to distinguish the read-only
573 mapping from the read/write mapping. (This assumes that there are
574 only two mappings for the main executable.) All writable sections
575 are associated with the read/write mapping and all non-writable
576 sections are associated with the read-only mapping.
577
578 This approach worked quite well until we came across executables
579 which didn't have a read-only mapping. Both mappings had the
580 same attributes represented in pr_mflags and it was impossible
581 to tell them apart.
582
583 - Use the pr_off field (which represents the offset into the
584 executable) to determine the section-to-mapping relationship.
585 Unfortunately, this approach doesn't work either, because the
586 offset value contained in the mapping is rounded down by some
587 moderately large power-of-2 value (4096 is a typical value).
588 A small (e.g. "Hello World") program will appear to have all
589 of its sections belonging to both mappings.
590
591 Also, the following approach has been considered, but dismissed:
592
593 - The section vma values typically look (something) like
594 0x00000001xxxxxxxx or 0x00000002xxxxxxxx. Furthermore, the
595 0x00000001xxxxxxxx values always belong to one mapping and
596 the 0x00000002xxxxxxxx values always belong to the other.
597 Thus it seems conceivable that GDB could use the bit patterns
598 in the upper portion (for some definition of "upper") in a
599 section's vma to help determine the section-to-mapping
600 relationship.
601
602 This approach was dismissed because there is nothing to prevent
603 the linker from lumping the section vmas together in one large
604 contiguous space and still expecting the dynamic linker to
605 separate them and relocate them independently. Also, different
606 linkers have been observed to use different patterns for the
607 upper portions of the vma addresses and it isn't clear what the
608 mask ought to be for distinguishing these patterns.
609
610 The current (admittedly inelegant) approach uses a lookup
611 table which associates section names with the map index that
612 they're permitted to be in. This is inelegant because we are
613 making the following assumptions:
614
615 1) There will only be two mappings.
616 2) The relevant (i.e. main executable) mappings will always appear
617 in the same order in the map file.
618 3) The sections named in the table will always belong to the
619 indicated mapping.
620 4) The table completely enumerates all possible section names.
621
622 IMO, any of these deficiencies alone will normally be sufficient
623 to disqualify this approach, but I haven't been able to think of
624 a better way to do it.
625
626 map_index_vs_section_name_okay() is a predicate which returns
627 true iff the section name NAME is associated with the map index
628 IDX in its builtin table. Of course, there's no guarantee that
629 this association is actually valid... */
630
631static int
632map_index_vs_section_name_okay (int idx, const char *name)
633{
634 static struct
635 {
636 char *name;
637 int idx;
638 } okay[] =
639 {
640 { ".interp", 0 },
641 { ".hash", 0 },
642 { ".dynsym", 0 },
643 { ".dynstr", 0 },
644 { ".rela.text", 0 },
645 { ".rela.rodata", 0 },
646 { ".rela.data", 0 },
647 { ".rela.ctors", 0 },
648 { ".rela.dtors", 0 },
649 { ".rela.got", 0 },
650 { ".rela.sdata", 0 },
651 { ".rela.IA_64.pltoff", 0 },
652 { ".rel.data", 0 },
653 { ".rel.sdata", 0 },
654 { ".rel.got", 0 },
655 { ".rel.AIX.pfdesc", 0 },
656 { ".rel.IA_64.pltoff", 0 },
657 { ".dynamic", 0 },
658 { ".init", 0 },
659 { ".plt", 0 },
660 { ".text", 0 },
661 { ".fini", 0 },
662 { ".rodata", 0 },
663 { ".IA_64.unwind_info", 0 },
664 { ".IA_64.unwind", 0 },
665 { ".AIX.mustrel", 0 },
666
667 { ".data", 1 },
668 { ".ctors", 1 },
669 { ".dtors", 1 },
670 { ".got", 1 },
671 { ".dynamic", 1},
672 { ".sdata", 1 },
673 { ".IA_64.pltoff", 1 },
674 { ".sbss", 1 },
675 { ".bss", 1 },
676 { ".AIX.pfdesc", 1 }
677 };
678 int i;
679
680 for (i = 0; i < sizeof (okay) / sizeof (okay[0]); i++)
681 {
682 if (strcmp (name, okay[i].name) == 0)
683 return idx == okay[i].idx;
684 }
685
8a3fe4f8 686 warning (_("Ignoring section %s when relocating the executable."),
00c7912d
KB
687 name);
688 return 0;
689}
690
60cf7a85
KB
691#define SECTMAPMASK (~ (CORE_ADDR) 0x03ffffff)
692
693static void
694aix5_relocate_main_executable (void)
695{
696 struct so_list *so;
697 struct section_offsets *new_offsets;
698 int i;
699 int changed = 0;
700 struct cleanup *old_chain = make_cleanup (null_cleanup, 0);
701
702 /* Fetch the mappings for the main executable from the map file. */
39f77062 703 so = build_so_list_from_mapfile (PIDGET (inferior_ptid),
60cf7a85
KB
704 MA_MAINEXEC, MA_MAINEXEC);
705
706 /* Make sure we actually have some mappings to work with. */
707 if (so == NULL)
708 {
8a3fe4f8 709 warning (_("Could not find main executable in map file"));
60cf7a85
KB
710 do_cleanups (old_chain);
711 return;
712 }
713
714 /* Allocate the data structure which'll contain the new offsets to
715 relocate by. Initialize it so it contains the current offsets. */
13fc0c2f
KB
716 new_offsets = xcalloc (symfile_objfile->num_sections,
717 sizeof (struct section_offsets));
80117be2 718 make_cleanup (xfree, new_offsets);
60cf7a85 719 for (i = 0; i < symfile_objfile->num_sections; i++)
d112a051 720 new_offsets->offsets[i] = ANOFFSET (symfile_objfile->section_offsets, i);
60cf7a85
KB
721
722 /* Iterate over the mappings in the main executable and compute
723 the new offset value as appropriate. */
6c98e688 724 for (i = 0; i < so->lm_info->nmappings; i++)
60cf7a85
KB
725 {
726 CORE_ADDR increment = 0;
727 struct obj_section *sect;
728 bfd *obfd = symfile_objfile->obfd;
6c98e688 729 struct lm_mapping *mapping = &so->lm_info->mapping[i];
60cf7a85
KB
730
731 ALL_OBJFILE_OSECTIONS (symfile_objfile, sect)
732 {
733 int flags = bfd_get_section_flags (obfd, sect->the_bfd_section);
734 if (flags & SEC_ALLOC)
735 {
6c98e688 736 file_ptr filepos = sect->the_bfd_section->filepos;
00c7912d
KB
737 if (map_index_vs_section_name_okay (i,
738 bfd_get_section_name (obfd, sect->the_bfd_section)))
60cf7a85
KB
739 {
740 int idx = sect->the_bfd_section->index;
741
742 if (increment == 0)
6c98e688 743 increment = mapping->addr
60cf7a85
KB
744 - (bfd_section_vma (obfd, sect->the_bfd_section)
745 & SECTMAPMASK);
746
747 if (increment != ANOFFSET (new_offsets, idx))
748 {
d112a051 749 new_offsets->offsets[idx] = increment;
60cf7a85
KB
750 changed = 1;
751 }
752 }
753 }
754 }
755 }
756
757 /* If any of the offsets have changed, then relocate the objfile. */
758 if (changed)
759 objfile_relocate (symfile_objfile, new_offsets);
760
761 /* Free up all the space we've allocated. */
762 do_cleanups (old_chain);
763}
764
765/*
766
767 GLOBAL FUNCTION
768
769 aix5_solib_create_inferior_hook -- shared library startup support
770
771 SYNOPSIS
772
7095b863 773 void aix5_solib_create_inferior_hook ()
60cf7a85
KB
774
775 DESCRIPTION
776
777 When gdb starts up the inferior, it nurses it along (through the
778 shell) until it is ready to execute it's first instruction. At this
779 point, this function gets called via expansion of the macro
780 SOLIB_CREATE_INFERIOR_HOOK.
781
0579d647 782 For AIX5 executables, this first instruction is the first
60cf7a85
KB
783 instruction in the dynamic linker (for dynamically linked
784 executables) or the instruction at "start" for statically linked
785 executables. For dynamically linked executables, the system
0579d647 786 first exec's libc.so.N, which contains the dynamic linker,
60cf7a85
KB
787 and starts it running. The dynamic linker maps in any needed
788 shared libraries, maps in the actual user executable, and then
789 jumps to "start" in the user executable.
790
791 */
792
793static void
794aix5_solib_create_inferior_hook (void)
795{
796 aix5_relocate_main_executable ();
797
798 if (!enable_break ())
799 {
8a3fe4f8 800 warning (_("shared library handler failed to enable breakpoint"));
60cf7a85
KB
801 return;
802 }
803}
804
805static void
806aix5_clear_solib (void)
807{
808}
809
810static void
811aix5_free_so (struct so_list *so)
812{
80117be2
KB
813 xfree (so->lm_info->mapname);
814 xfree (so->lm_info->pathname);
815 xfree (so->lm_info->membername);
816 xfree (so->lm_info);
60cf7a85
KB
817}
818
819static void
820aix5_relocate_section_addresses (struct so_list *so,
821 struct section_table *sec)
822{
823 int flags = bfd_get_section_flags (sec->bfd, sec->the_bfd_section);
6c98e688 824 file_ptr filepos = sec->the_bfd_section->filepos;
60cf7a85
KB
825
826 if (flags & SEC_ALLOC)
827 {
6c98e688
KB
828 int idx;
829 CORE_ADDR addr;
830
831 for (idx = 0; idx < so->lm_info->nmappings; idx++)
832 {
833 struct lm_mapping *mapping = &so->lm_info->mapping[idx];
834 if (mapping->offset <= filepos
835 && filepos <= mapping->offset + mapping->size)
836 break;
837 }
838
839 if (idx >= so->lm_info->nmappings)
840 internal_error (__FILE__, __LINE__,
e2e0b3e5 841 _("aix_relocate_section_addresses: Can't find mapping for section %s"),
6c98e688
KB
842 bfd_get_section_name (sec->bfd, sec->the_bfd_section));
843
844 addr = so->lm_info->mapping[idx].addr;
60cf7a85
KB
845
846 sec->addr += addr;
847 sec->endaddr += addr;
848 }
849}
850
851/* Find the global pointer for the given function address ADDR. */
852
853static CORE_ADDR
854aix5_find_global_pointer (CORE_ADDR addr)
855{
856 struct so_list *sos, *so;
857 CORE_ADDR global_pointer = 0;
858 struct cleanup *old_chain = make_cleanup (null_cleanup, 0);
859
39f77062 860 sos = build_so_list_from_mapfile (PIDGET (inferior_ptid), 0, 0);
60cf7a85
KB
861
862 for (so = sos; so != NULL; so = so->next)
863 {
6c98e688
KB
864 int idx;
865 for (idx = 0; idx < so->lm_info->nmappings; idx++)
866 if (so->lm_info->mapping[idx].addr <= addr
867 && addr <= so->lm_info->mapping[idx].addr
868 + so->lm_info->mapping[idx].size)
869 {
870 break;
871 }
872
873 if (idx < so->lm_info->nmappings)
60cf7a85 874 {
6c98e688
KB
875 /* Look for a non-zero global pointer in the current set of
876 mappings. */
877 for (idx = 0; idx < so->lm_info->nmappings; idx++)
878 if (so->lm_info->mapping[idx].gp != 0)
879 {
880 global_pointer = so->lm_info->mapping[idx].gp;
881 break;
882 }
883 /* Get out regardless of whether we found one or not. Mappings
884 don't overlap, so it would be pointless to continue. */
60cf7a85
KB
885 break;
886 }
887 }
888
889 do_cleanups (old_chain);
890
891 return global_pointer;
892}
893
894/* Find the execute-only kernel region known as the gate page. This
895 page is where the signal trampoline lives. It may be found by
896 querying the map file and looking for the MA_KERNTEXT flag. */
897static void
898aix5_find_gate_addresses (CORE_ADDR *start, CORE_ADDR *end)
899{
900 struct so_list *so;
901 struct cleanup *old_chain = make_cleanup (null_cleanup, 0);
902
903 /* Fetch the mappings for the main executable from the map file. */
39f77062 904 so = build_so_list_from_mapfile (PIDGET (inferior_ptid),
60cf7a85
KB
905 MA_KERNTEXT, MA_KERNTEXT);
906
907 /* Make sure we actually have some mappings to work with. */
908 if (so == NULL)
909 {
8a3fe4f8 910 warning (_("Could not find gate page in map file"));
60cf7a85
KB
911 *start = 0;
912 *end = 0;
913 do_cleanups (old_chain);
914 return;
915 }
916
917 /* There should only be on kernel mapping for the gate page and
918 it'll be in the read-only (even though it's execute-only)
919 mapping in the lm_info struct. */
920
6c98e688
KB
921 *start = so->lm_info->mapping[0].addr;
922 *end = *start + so->lm_info->mapping[0].size;
60cf7a85
KB
923
924 /* Free up all the space we've allocated. */
925 do_cleanups (old_chain);
926}
927
928/* From ia64-tdep.c. FIXME: If we end up using this for rs6000 too,
929 we'll need to make the names match. */
930extern CORE_ADDR (*native_find_global_pointer) (CORE_ADDR);
931
932/* From ia64-aix-tdep.c. Hook for finding the starting and
933 ending gate page addresses. The only reason that this hook
934 is in this file is because this is where the map file reading
935 code is located. */
936extern void (*aix5_find_gate_addresses_hook) (CORE_ADDR *, CORE_ADDR *);
937
938static struct target_so_ops aix5_so_ops;
939
940void
941_initialize_aix5_solib (void)
942{
943 aix5_so_ops.relocate_section_addresses = aix5_relocate_section_addresses;
944 aix5_so_ops.free_so = aix5_free_so;
945 aix5_so_ops.clear_solib = aix5_clear_solib;
946 aix5_so_ops.solib_create_inferior_hook = aix5_solib_create_inferior_hook;
947 aix5_so_ops.special_symbol_handling = aix5_special_symbol_handling;
948 aix5_so_ops.current_sos = aix5_current_sos;
949 aix5_so_ops.open_symbol_file_object = open_symbol_file_object;
d7fa2ae2 950 aix5_so_ops.in_dynsym_resolve_code = aix5_in_dynsym_resolve_code;
60cf7a85
KB
951
952 native_find_global_pointer = aix5_find_global_pointer;
953 aix5_find_gate_addresses_hook = aix5_find_gate_addresses;
954
955 /* FIXME: Don't do this here. *_gdbarch_init() should set so_ops. */
956 current_target_so_ops = &aix5_so_ops;
957}