OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [insight/] [gdb/] [solib-aix5.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 578 markom
/* 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
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 *
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
    xasprintf (&map_pathname, "/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 (sizeof (struct so_list), 1);
266
          make_cleanup (xfree, sop);
267
          sop->lm_info = xcalloc (sizeof (struct lm_info), 1);
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
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 *
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
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
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
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
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
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 (sizeof (struct section_offsets),
718
                         symfile_objfile->num_sections);
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
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
807
aix5_clear_solib (void)
808
{
809
}
810
 
811
static void
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
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
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
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
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
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.