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