* solib-aix5.c: New file.
[platform/upstream/binutils.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