OpenCores
URL https://opencores.org/ocsvn/openrisc_2011-10-31/openrisc_2011-10-31/trunk

Subversion Repositories openrisc_2011-10-31

[/] [openrisc/] [trunk/] [gnu-src/] [gdb-7.1/] [gdb/] [solib-frv.c] - Blame information for rev 595

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 227 jeremybenn
/* Handle FR-V (FDPIC) shared libraries for GDB, the GNU Debugger.
2
   Copyright (C) 2004, 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
3
 
4
   This file is part of GDB.
5
 
6
   This program is free software; you can redistribute it and/or modify
7
   it under the terms of the GNU General Public License as published by
8
   the Free Software Foundation; either version 3 of the License, or
9
   (at your option) any later version.
10
 
11
   This program is distributed in the hope that it will be useful,
12
   but WITHOUT ANY WARRANTY; without even the implied warranty of
13
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
   GNU General Public License for more details.
15
 
16
   You should have received a copy of the GNU General Public License
17
   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
18
 
19
 
20
#include "defs.h"
21
#include "gdb_string.h"
22
#include "inferior.h"
23
#include "gdbcore.h"
24
#include "solib.h"
25
#include "solist.h"
26
#include "frv-tdep.h"
27
#include "objfiles.h"
28
#include "symtab.h"
29
#include "language.h"
30
#include "command.h"
31
#include "gdbcmd.h"
32
#include "elf/frv.h"
33
#include "exceptions.h"
34
 
35
/* Flag which indicates whether internal debug messages should be printed.  */
36
static int solib_frv_debug;
37
 
38
/* FR-V pointers are four bytes wide.  */
39
enum { FRV_PTR_SIZE = 4 };
40
 
41
/* Representation of loadmap and related structs for the FR-V FDPIC ABI.  */
42
 
43
/* External versions; the size and alignment of the fields should be
44
   the same as those on the target.  When loaded, the placement of
45
   the bits in each field will be the same as on the target.  */
46
typedef gdb_byte ext_Elf32_Half[2];
47
typedef gdb_byte ext_Elf32_Addr[4];
48
typedef gdb_byte ext_Elf32_Word[4];
49
 
50
struct ext_elf32_fdpic_loadseg
51
{
52
  /* Core address to which the segment is mapped.  */
53
  ext_Elf32_Addr addr;
54
  /* VMA recorded in the program header.  */
55
  ext_Elf32_Addr p_vaddr;
56
  /* Size of this segment in memory.  */
57
  ext_Elf32_Word p_memsz;
58
};
59
 
60
struct ext_elf32_fdpic_loadmap {
61
  /* Protocol version number, must be zero.  */
62
  ext_Elf32_Half version;
63
  /* Number of segments in this map.  */
64
  ext_Elf32_Half nsegs;
65
  /* The actual memory map.  */
66
  struct ext_elf32_fdpic_loadseg segs[1 /* nsegs, actually */];
67
};
68
 
69
/* Internal versions; the types are GDB types and the data in each
70
   of the fields is (or will be) decoded from the external struct
71
   for ease of consumption.  */
72
struct int_elf32_fdpic_loadseg
73
{
74
  /* Core address to which the segment is mapped.  */
75
  CORE_ADDR addr;
76
  /* VMA recorded in the program header.  */
77
  CORE_ADDR p_vaddr;
78
  /* Size of this segment in memory.  */
79
  long p_memsz;
80
};
81
 
82
struct int_elf32_fdpic_loadmap {
83
  /* Protocol version number, must be zero.  */
84
  int version;
85
  /* Number of segments in this map.  */
86
  int nsegs;
87
  /* The actual memory map.  */
88
  struct int_elf32_fdpic_loadseg segs[1 /* nsegs, actually */];
89
};
90
 
91
/* Given address LDMADDR, fetch and decode the loadmap at that address.
92
   Return NULL if there is a problem reading the target memory or if
93
   there doesn't appear to be a loadmap at the given address.  The
94
   allocated space (representing the loadmap) returned by this
95
   function may be freed via a single call to xfree().  */
96
 
97
static struct int_elf32_fdpic_loadmap *
98
fetch_loadmap (CORE_ADDR ldmaddr)
99
{
100
  enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch);
101
  struct ext_elf32_fdpic_loadmap ext_ldmbuf_partial;
102
  struct ext_elf32_fdpic_loadmap *ext_ldmbuf;
103
  struct int_elf32_fdpic_loadmap *int_ldmbuf;
104
  int ext_ldmbuf_size, int_ldmbuf_size;
105
  int version, seg, nsegs;
106
 
107
  /* Fetch initial portion of the loadmap.  */
108
  if (target_read_memory (ldmaddr, (gdb_byte *) &ext_ldmbuf_partial,
109
                          sizeof ext_ldmbuf_partial))
110
    {
111
      /* Problem reading the target's memory.  */
112
      return NULL;
113
    }
114
 
115
  /* Extract the version.  */
116
  version = extract_unsigned_integer (ext_ldmbuf_partial.version,
117
                                      sizeof ext_ldmbuf_partial.version,
118
                                      byte_order);
119
  if (version != 0)
120
    {
121
      /* We only handle version 0.  */
122
      return NULL;
123
    }
124
 
125
  /* Extract the number of segments.  */
126
  nsegs = extract_unsigned_integer (ext_ldmbuf_partial.nsegs,
127
                                    sizeof ext_ldmbuf_partial.nsegs,
128
                                    byte_order);
129
 
130
  if (nsegs <= 0)
131
    return NULL;
132
 
133
  /* Allocate space for the complete (external) loadmap.  */
134
  ext_ldmbuf_size = sizeof (struct ext_elf32_fdpic_loadmap)
135
               + (nsegs - 1) * sizeof (struct ext_elf32_fdpic_loadseg);
136
  ext_ldmbuf = xmalloc (ext_ldmbuf_size);
137
 
138
  /* Copy over the portion of the loadmap that's already been read.  */
139
  memcpy (ext_ldmbuf, &ext_ldmbuf_partial, sizeof ext_ldmbuf_partial);
140
 
141
  /* Read the rest of the loadmap from the target.  */
142
  if (target_read_memory (ldmaddr + sizeof ext_ldmbuf_partial,
143
                          (gdb_byte *) ext_ldmbuf + sizeof ext_ldmbuf_partial,
144
                          ext_ldmbuf_size - sizeof ext_ldmbuf_partial))
145
    {
146
      /* Couldn't read rest of the loadmap.  */
147
      xfree (ext_ldmbuf);
148
      return NULL;
149
    }
150
 
151
  /* Allocate space into which to put information extract from the
152
     external loadsegs.  I.e, allocate the internal loadsegs.  */
153
  int_ldmbuf_size = sizeof (struct int_elf32_fdpic_loadmap)
154
               + (nsegs - 1) * sizeof (struct int_elf32_fdpic_loadseg);
155
  int_ldmbuf = xmalloc (int_ldmbuf_size);
156
 
157
  /* Place extracted information in internal structs.  */
158
  int_ldmbuf->version = version;
159
  int_ldmbuf->nsegs = nsegs;
160
  for (seg = 0; seg < nsegs; seg++)
161
    {
162
      int_ldmbuf->segs[seg].addr
163
        = extract_unsigned_integer (ext_ldmbuf->segs[seg].addr,
164
                                    sizeof (ext_ldmbuf->segs[seg].addr),
165
                                    byte_order);
166
      int_ldmbuf->segs[seg].p_vaddr
167
        = extract_unsigned_integer (ext_ldmbuf->segs[seg].p_vaddr,
168
                                    sizeof (ext_ldmbuf->segs[seg].p_vaddr),
169
                                    byte_order);
170
      int_ldmbuf->segs[seg].p_memsz
171
        = extract_unsigned_integer (ext_ldmbuf->segs[seg].p_memsz,
172
                                    sizeof (ext_ldmbuf->segs[seg].p_memsz),
173
                                    byte_order);
174
    }
175
 
176
  xfree (ext_ldmbuf);
177
  return int_ldmbuf;
178
}
179
 
180
/* External link_map and elf32_fdpic_loadaddr struct definitions.  */
181
 
182
typedef gdb_byte ext_ptr[4];
183
 
184
struct ext_elf32_fdpic_loadaddr
185
{
186
  ext_ptr map;                  /* struct elf32_fdpic_loadmap *map; */
187
  ext_ptr got_value;            /* void *got_value; */
188
};
189
 
190
struct ext_link_map
191
{
192
  struct ext_elf32_fdpic_loadaddr l_addr;
193
 
194
  /* Absolute file name object was found in.  */
195
  ext_ptr l_name;               /* char *l_name; */
196
 
197
  /* Dynamic section of the shared object.  */
198
  ext_ptr l_ld;                 /* ElfW(Dyn) *l_ld; */
199
 
200
  /* Chain of loaded objects.  */
201
  ext_ptr l_next, l_prev;       /* struct link_map *l_next, *l_prev; */
202
};
203
 
204
/* Link map info to include in an allocated so_list entry */
205
 
206
struct lm_info
207
  {
208
    /* The loadmap, digested into an easier to use form.  */
209
    struct int_elf32_fdpic_loadmap *map;
210
    /* The GOT address for this link map entry.  */
211
    CORE_ADDR got_value;
212
    /* The link map address, needed for frv_fetch_objfile_link_map().  */
213
    CORE_ADDR lm_addr;
214
 
215
    /* Cached dynamic symbol table and dynamic relocs initialized and
216
       used only by find_canonical_descriptor_in_load_object().
217
 
218
       Note: kevinb/2004-02-26: It appears that calls to
219
       bfd_canonicalize_dynamic_reloc() will use the same symbols as
220
       those supplied to the first call to this function.  Therefore,
221
       it's important to NOT free the asymbol ** data structure
222
       supplied to the first call.  Thus the caching of the dynamic
223
       symbols (dyn_syms) is critical for correct operation.  The
224
       caching of the dynamic relocations could be dispensed with.  */
225
    asymbol **dyn_syms;
226
    arelent **dyn_relocs;
227
    int dyn_reloc_count;        /* number of dynamic relocs.  */
228
 
229
  };
230
 
231
/* The load map, got value, etc. are not available from the chain
232
   of loaded shared objects.  ``main_executable_lm_info'' provides
233
   a way to get at this information so that it doesn't need to be
234
   frequently recomputed.  Initialized by frv_relocate_main_executable().  */
235
static struct lm_info *main_executable_lm_info;
236
 
237
static void frv_relocate_main_executable (void);
238
static CORE_ADDR main_got (void);
239
static int enable_break2 (void);
240
 
241
/*
242
 
243
   LOCAL FUNCTION
244
 
245
   bfd_lookup_symbol -- lookup the value for a specific symbol
246
 
247
   SYNOPSIS
248
 
249
   CORE_ADDR bfd_lookup_symbol (bfd *abfd, char *symname)
250
 
251
   DESCRIPTION
252
 
253
   An expensive way to lookup the value of a single symbol for
254
   bfd's that are only temporary anyway.  This is used by the
255
   shared library support to find the address of the debugger
256
   interface structures in the shared library.
257
 
258
   Note that 0 is specifically allowed as an error return (no
259
   such symbol).
260
 */
261
 
262
static CORE_ADDR
263
bfd_lookup_symbol (bfd *abfd, char *symname)
264
{
265
  long storage_needed;
266
  asymbol *sym;
267
  asymbol **symbol_table;
268
  unsigned int number_of_symbols;
269
  unsigned int i;
270
  struct cleanup *back_to;
271
  CORE_ADDR symaddr = 0;
272
 
273
  storage_needed = bfd_get_symtab_upper_bound (abfd);
274
 
275
  if (storage_needed > 0)
276
    {
277
      symbol_table = (asymbol **) xmalloc (storage_needed);
278
      back_to = make_cleanup (xfree, symbol_table);
279
      number_of_symbols = bfd_canonicalize_symtab (abfd, symbol_table);
280
 
281
      for (i = 0; i < number_of_symbols; i++)
282
        {
283
          sym = *symbol_table++;
284
          if (strcmp (sym->name, symname) == 0)
285
            {
286
              /* Bfd symbols are section relative. */
287
              symaddr = sym->value + sym->section->vma;
288
              break;
289
            }
290
        }
291
      do_cleanups (back_to);
292
    }
293
 
294
  if (symaddr)
295
    return symaddr;
296
 
297
  /* Look for the symbol in the dynamic string table too.  */
298
 
299
  storage_needed = bfd_get_dynamic_symtab_upper_bound (abfd);
300
 
301
  if (storage_needed > 0)
302
    {
303
      symbol_table = (asymbol **) xmalloc (storage_needed);
304
      back_to = make_cleanup (xfree, symbol_table);
305
      number_of_symbols = bfd_canonicalize_dynamic_symtab (abfd, symbol_table);
306
 
307
      for (i = 0; i < number_of_symbols; i++)
308
        {
309
          sym = *symbol_table++;
310
          if (strcmp (sym->name, symname) == 0)
311
            {
312
              /* Bfd symbols are section relative. */
313
              symaddr = sym->value + sym->section->vma;
314
              break;
315
            }
316
        }
317
      do_cleanups (back_to);
318
    }
319
 
320
  return symaddr;
321
}
322
 
323
 
324
/*
325
 
326
  LOCAL FUNCTION
327
 
328
  open_symbol_file_object
329
 
330
  SYNOPSIS
331
 
332
  void open_symbol_file_object (void *from_tty)
333
 
334
  DESCRIPTION
335
 
336
  If no open symbol file, attempt to locate and open the main symbol
337
  file.
338
 
339
  If FROM_TTYP dereferences to a non-zero integer, allow messages to
340
  be printed.  This parameter is a pointer rather than an int because
341
  open_symbol_file_object() is called via catch_errors() and
342
  catch_errors() requires a pointer argument. */
343
 
344
static int
345
open_symbol_file_object (void *from_ttyp)
346
{
347
  /* Unimplemented.  */
348
  return 0;
349
}
350
 
351
/* Cached value for lm_base(), below.  */
352
static CORE_ADDR lm_base_cache = 0;
353
 
354
/* Link map address for main module.  */
355
static CORE_ADDR main_lm_addr = 0;
356
 
357
/* Return the address from which the link map chain may be found.  On
358
   the FR-V, this may be found in a number of ways.  Assuming that the
359
   main executable has already been relocated, the easiest way to find
360
   this value is to look up the address of _GLOBAL_OFFSET_TABLE_.  A
361
   pointer to the start of the link map will be located at the word found
362
   at _GLOBAL_OFFSET_TABLE_ + 8.  (This is part of the dynamic linker
363
   reserve area mandated by the ABI.)  */
364
 
365
static CORE_ADDR
366
lm_base (void)
367
{
368
  enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch);
369
  struct minimal_symbol *got_sym;
370
  CORE_ADDR addr;
371
  gdb_byte buf[FRV_PTR_SIZE];
372
 
373
  /* One of our assumptions is that the main executable has been relocated.
374
     Bail out if this has not happened.  (Note that post_create_inferior()
375
     in infcmd.c will call solib_add prior to solib_create_inferior_hook().
376
     If we allow this to happen, lm_base_cache will be initialized with
377
     a bogus value.  */
378
  if (main_executable_lm_info == 0)
379
    return 0;
380
 
381
  /* If we already have a cached value, return it.  */
382
  if (lm_base_cache)
383
    return lm_base_cache;
384
 
385
  got_sym = lookup_minimal_symbol ("_GLOBAL_OFFSET_TABLE_", NULL,
386
                                   symfile_objfile);
387
  if (got_sym == 0)
388
    {
389
      if (solib_frv_debug)
390
        fprintf_unfiltered (gdb_stdlog,
391
                            "lm_base: _GLOBAL_OFFSET_TABLE_ not found.\n");
392
      return 0;
393
    }
394
 
395
  addr = SYMBOL_VALUE_ADDRESS (got_sym) + 8;
396
 
397
  if (solib_frv_debug)
398
    fprintf_unfiltered (gdb_stdlog,
399
                        "lm_base: _GLOBAL_OFFSET_TABLE_ + 8 = %s\n",
400
                        hex_string_custom (addr, 8));
401
 
402
  if (target_read_memory (addr, buf, sizeof buf) != 0)
403
    return 0;
404
  lm_base_cache = extract_unsigned_integer (buf, sizeof buf, byte_order);
405
 
406
  if (solib_frv_debug)
407
    fprintf_unfiltered (gdb_stdlog,
408
                        "lm_base: lm_base_cache = %s\n",
409
                        hex_string_custom (lm_base_cache, 8));
410
 
411
  return lm_base_cache;
412
}
413
 
414
 
415
/* LOCAL FUNCTION
416
 
417
   frv_current_sos -- build a list of currently loaded shared objects
418
 
419
   SYNOPSIS
420
 
421
   struct so_list *frv_current_sos ()
422
 
423
   DESCRIPTION
424
 
425
   Build a list of `struct so_list' objects describing the shared
426
   objects currently loaded in the inferior.  This list does not
427
   include an entry for the main executable file.
428
 
429
   Note that we only gather information directly available from the
430
   inferior --- we don't examine any of the shared library files
431
   themselves.  The declaration of `struct so_list' says which fields
432
   we provide values for.  */
433
 
434
static struct so_list *
435
frv_current_sos (void)
436
{
437
  enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch);
438
  CORE_ADDR lm_addr, mgot;
439
  struct so_list *sos_head = NULL;
440
  struct so_list **sos_next_ptr = &sos_head;
441
 
442
  /* Make sure that the main executable has been relocated.  This is
443
     required in order to find the address of the global offset table,
444
     which in turn is used to find the link map info.  (See lm_base()
445
     for details.)
446
 
447
     Note that the relocation of the main executable is also performed
448
     by SOLIB_CREATE_INFERIOR_HOOK(), however, in the case of core
449
     files, this hook is called too late in order to be of benefit to
450
     SOLIB_ADD.  SOLIB_ADD eventually calls this this function,
451
     frv_current_sos, and also precedes the call to
452
     SOLIB_CREATE_INFERIOR_HOOK().   (See post_create_inferior() in
453
     infcmd.c.)  */
454
  if (main_executable_lm_info == 0 && core_bfd != NULL)
455
    frv_relocate_main_executable ();
456
 
457
  /* Fetch the GOT corresponding to the main executable.  */
458
  mgot = main_got ();
459
 
460
  /* Locate the address of the first link map struct.  */
461
  lm_addr = lm_base ();
462
 
463
  /* We have at least one link map entry.  Fetch the the lot of them,
464
     building the solist chain.  */
465
  while (lm_addr)
466
    {
467
      struct ext_link_map lm_buf;
468
      CORE_ADDR got_addr;
469
 
470
      if (solib_frv_debug)
471
        fprintf_unfiltered (gdb_stdlog,
472
                            "current_sos: reading link_map entry at %s\n",
473
                            hex_string_custom (lm_addr, 8));
474
 
475
      if (target_read_memory (lm_addr, (gdb_byte *) &lm_buf, sizeof (lm_buf)) != 0)
476
        {
477
          warning (_("frv_current_sos: Unable to read link map entry.  Shared object chain may be incomplete."));
478
          break;
479
        }
480
 
481
      got_addr
482
        = extract_unsigned_integer (lm_buf.l_addr.got_value,
483
                                    sizeof (lm_buf.l_addr.got_value),
484
                                    byte_order);
485
      /* If the got_addr is the same as mgotr, then we're looking at the
486
         entry for the main executable.  By convention, we don't include
487
         this in the list of shared objects.  */
488
      if (got_addr != mgot)
489
        {
490
          int errcode;
491
          char *name_buf;
492
          struct int_elf32_fdpic_loadmap *loadmap;
493
          struct so_list *sop;
494
          CORE_ADDR addr;
495
 
496
          /* Fetch the load map address.  */
497
          addr = extract_unsigned_integer (lm_buf.l_addr.map,
498
                                           sizeof lm_buf.l_addr.map,
499
                                           byte_order);
500
          loadmap = fetch_loadmap (addr);
501
          if (loadmap == NULL)
502
            {
503
              warning (_("frv_current_sos: Unable to fetch load map.  Shared object chain may be incomplete."));
504
              break;
505
            }
506
 
507
          sop = xcalloc (1, sizeof (struct so_list));
508
          sop->lm_info = xcalloc (1, sizeof (struct lm_info));
509
          sop->lm_info->map = loadmap;
510
          sop->lm_info->got_value = got_addr;
511
          sop->lm_info->lm_addr = lm_addr;
512
          /* Fetch the name.  */
513
          addr = extract_unsigned_integer (lm_buf.l_name,
514
                                           sizeof (lm_buf.l_name),
515
                                           byte_order);
516
          target_read_string (addr, &name_buf, SO_NAME_MAX_PATH_SIZE - 1,
517
                              &errcode);
518
 
519
          if (solib_frv_debug)
520
            fprintf_unfiltered (gdb_stdlog, "current_sos: name = %s\n",
521
                                name_buf);
522
 
523
          if (errcode != 0)
524
            warning (_("Can't read pathname for link map entry: %s."),
525
                     safe_strerror (errcode));
526
          else
527
            {
528
              strncpy (sop->so_name, name_buf, SO_NAME_MAX_PATH_SIZE - 1);
529
              sop->so_name[SO_NAME_MAX_PATH_SIZE - 1] = '\0';
530
              xfree (name_buf);
531
              strcpy (sop->so_original_name, sop->so_name);
532
            }
533
 
534
          *sos_next_ptr = sop;
535
          sos_next_ptr = &sop->next;
536
        }
537
      else
538
        {
539
          main_lm_addr = lm_addr;
540
        }
541
 
542
      lm_addr = extract_unsigned_integer (lm_buf.l_next,
543
                                          sizeof (lm_buf.l_next), byte_order);
544
    }
545
 
546
  enable_break2 ();
547
 
548
  return sos_head;
549
}
550
 
551
 
552
/* Return 1 if PC lies in the dynamic symbol resolution code of the
553
   run time loader.  */
554
 
555
static CORE_ADDR interp_text_sect_low;
556
static CORE_ADDR interp_text_sect_high;
557
static CORE_ADDR interp_plt_sect_low;
558
static CORE_ADDR interp_plt_sect_high;
559
 
560
static int
561
frv_in_dynsym_resolve_code (CORE_ADDR pc)
562
{
563
  return ((pc >= interp_text_sect_low && pc < interp_text_sect_high)
564
          || (pc >= interp_plt_sect_low && pc < interp_plt_sect_high)
565
          || in_plt_section (pc, NULL));
566
}
567
 
568
/* Given a loadmap and an address, return the displacement needed
569
   to relocate the address.  */
570
 
571
static CORE_ADDR
572
displacement_from_map (struct int_elf32_fdpic_loadmap *map,
573
                       CORE_ADDR addr)
574
{
575
  int seg;
576
 
577
  for (seg = 0; seg < map->nsegs; seg++)
578
    {
579
      if (map->segs[seg].p_vaddr <= addr
580
          && addr < map->segs[seg].p_vaddr + map->segs[seg].p_memsz)
581
        {
582
          return map->segs[seg].addr - map->segs[seg].p_vaddr;
583
        }
584
    }
585
 
586
  return 0;
587
}
588
 
589
/* Print a warning about being unable to set the dynamic linker
590
   breakpoint.  */
591
 
592
static void
593
enable_break_failure_warning (void)
594
{
595
  warning (_("Unable to find dynamic linker breakpoint function.\n"
596
           "GDB will be unable to debug shared library initializers\n"
597
           "and track explicitly loaded dynamic code."));
598
}
599
 
600
/*
601
 
602
   LOCAL FUNCTION
603
 
604
   enable_break -- arrange for dynamic linker to hit breakpoint
605
 
606
   SYNOPSIS
607
 
608
   int enable_break (void)
609
 
610
   DESCRIPTION
611
 
612
   The dynamic linkers has, as part of its debugger interface, support
613
   for arranging for the inferior to hit a breakpoint after mapping in
614
   the shared libraries.  This function enables that breakpoint.
615
 
616
   On the FR-V, using the shared library (FDPIC) ABI, the symbol
617
   _dl_debug_addr points to the r_debug struct which contains
618
   a field called r_brk.  r_brk is the address of the function
619
   descriptor upon which a breakpoint must be placed.  Being a
620
   function descriptor, we must extract the entry point in order
621
   to set the breakpoint.
622
 
623
   Our strategy will be to get the .interp section from the
624
   executable.  This section will provide us with the name of the
625
   interpreter.  We'll open the interpreter and then look up
626
   the address of _dl_debug_addr.  We then relocate this address
627
   using the interpreter's loadmap.  Once the relocated address
628
   is known, we fetch the value (address) corresponding to r_brk
629
   and then use that value to fetch the entry point of the function
630
   we're interested in.
631
 
632
 */
633
 
634
static int enable_break1_done = 0;
635
static int enable_break2_done = 0;
636
 
637
static int
638
enable_break2 (void)
639
{
640
  enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch);
641
  int success = 0;
642
  char **bkpt_namep;
643
  asection *interp_sect;
644
 
645
  if (!enable_break1_done || enable_break2_done)
646
    return 1;
647
 
648
  enable_break2_done = 1;
649
 
650
  /* First, remove all the solib event breakpoints.  Their addresses
651
     may have changed since the last time we ran the program.  */
652
  remove_solib_event_breakpoints ();
653
 
654
  interp_text_sect_low = interp_text_sect_high = 0;
655
  interp_plt_sect_low = interp_plt_sect_high = 0;
656
 
657
  /* Find the .interp section; if not found, warn the user and drop
658
     into the old breakpoint at symbol code.  */
659
  interp_sect = bfd_get_section_by_name (exec_bfd, ".interp");
660
  if (interp_sect)
661
    {
662
      unsigned int interp_sect_size;
663
      gdb_byte *buf;
664
      bfd *tmp_bfd = NULL;
665
      int status;
666
      CORE_ADDR addr, interp_loadmap_addr;
667
      gdb_byte addr_buf[FRV_PTR_SIZE];
668
      struct int_elf32_fdpic_loadmap *ldm;
669
      volatile struct gdb_exception ex;
670
 
671
      /* Read the contents of the .interp section into a local buffer;
672
         the contents specify the dynamic linker this program uses.  */
673
      interp_sect_size = bfd_section_size (exec_bfd, interp_sect);
674
      buf = alloca (interp_sect_size);
675
      bfd_get_section_contents (exec_bfd, interp_sect,
676
                                buf, 0, interp_sect_size);
677
 
678
      /* Now we need to figure out where the dynamic linker was
679
         loaded so that we can load its symbols and place a breakpoint
680
         in the dynamic linker itself.
681
 
682
         This address is stored on the stack.  However, I've been unable
683
         to find any magic formula to find it for Solaris (appears to
684
         be trivial on GNU/Linux).  Therefore, we have to try an alternate
685
         mechanism to find the dynamic linker's base address.  */
686
 
687
      TRY_CATCH (ex, RETURN_MASK_ALL)
688
        {
689
          tmp_bfd = solib_bfd_open (buf);
690
        }
691
      if (tmp_bfd == NULL)
692
        {
693
          enable_break_failure_warning ();
694
          return 0;
695
        }
696
 
697
      status = frv_fdpic_loadmap_addresses (target_gdbarch,
698
                                            &interp_loadmap_addr, 0);
699
      if (status < 0)
700
        {
701
          warning (_("Unable to determine dynamic linker loadmap address."));
702
          enable_break_failure_warning ();
703
          bfd_close (tmp_bfd);
704
          return 0;
705
        }
706
 
707
      if (solib_frv_debug)
708
        fprintf_unfiltered (gdb_stdlog,
709
                            "enable_break: interp_loadmap_addr = %s\n",
710
                            hex_string_custom (interp_loadmap_addr, 8));
711
 
712
      ldm = fetch_loadmap (interp_loadmap_addr);
713
      if (ldm == NULL)
714
        {
715
          warning (_("Unable to load dynamic linker loadmap at address %s."),
716
                   hex_string_custom (interp_loadmap_addr, 8));
717
          enable_break_failure_warning ();
718
          bfd_close (tmp_bfd);
719
          return 0;
720
        }
721
 
722
      /* Record the relocated start and end address of the dynamic linker
723
         text and plt section for svr4_in_dynsym_resolve_code.  */
724
      interp_sect = bfd_get_section_by_name (tmp_bfd, ".text");
725
      if (interp_sect)
726
        {
727
          interp_text_sect_low
728
            = bfd_section_vma (tmp_bfd, interp_sect);
729
          interp_text_sect_low
730
            += displacement_from_map (ldm, interp_text_sect_low);
731
          interp_text_sect_high
732
            = interp_text_sect_low + bfd_section_size (tmp_bfd, interp_sect);
733
        }
734
      interp_sect = bfd_get_section_by_name (tmp_bfd, ".plt");
735
      if (interp_sect)
736
        {
737
          interp_plt_sect_low =
738
            bfd_section_vma (tmp_bfd, interp_sect);
739
          interp_plt_sect_low
740
            += displacement_from_map (ldm, interp_plt_sect_low);
741
          interp_plt_sect_high =
742
            interp_plt_sect_low + bfd_section_size (tmp_bfd, interp_sect);
743
        }
744
 
745
      addr = bfd_lookup_symbol (tmp_bfd, "_dl_debug_addr");
746
      if (addr == 0)
747
        {
748
          warning (_("Could not find symbol _dl_debug_addr in dynamic linker"));
749
          enable_break_failure_warning ();
750
          bfd_close (tmp_bfd);
751
          return 0;
752
        }
753
 
754
      if (solib_frv_debug)
755
        fprintf_unfiltered (gdb_stdlog,
756
                            "enable_break: _dl_debug_addr (prior to relocation) = %s\n",
757
                            hex_string_custom (addr, 8));
758
 
759
      addr += displacement_from_map (ldm, addr);
760
 
761
      if (solib_frv_debug)
762
        fprintf_unfiltered (gdb_stdlog,
763
                            "enable_break: _dl_debug_addr (after relocation) = %s\n",
764
                            hex_string_custom (addr, 8));
765
 
766
      /* Fetch the address of the r_debug struct.  */
767
      if (target_read_memory (addr, addr_buf, sizeof addr_buf) != 0)
768
        {
769
          warning (_("Unable to fetch contents of _dl_debug_addr (at address %s) from dynamic linker"),
770
                   hex_string_custom (addr, 8));
771
        }
772
      addr = extract_unsigned_integer (addr_buf, sizeof addr_buf, byte_order);
773
 
774
      /* Fetch the r_brk field.  It's 8 bytes from the start of
775
         _dl_debug_addr.  */
776
      if (target_read_memory (addr + 8, addr_buf, sizeof addr_buf) != 0)
777
        {
778
          warning (_("Unable to fetch _dl_debug_addr->r_brk (at address %s) from dynamic linker"),
779
                   hex_string_custom (addr + 8, 8));
780
          enable_break_failure_warning ();
781
          bfd_close (tmp_bfd);
782
          return 0;
783
        }
784
      addr = extract_unsigned_integer (addr_buf, sizeof addr_buf, byte_order);
785
 
786
      /* Now fetch the function entry point.  */
787
      if (target_read_memory (addr, addr_buf, sizeof addr_buf) != 0)
788
        {
789
          warning (_("Unable to fetch _dl_debug_addr->.r_brk entry point (at address %s) from dynamic linker"),
790
                   hex_string_custom (addr, 8));
791
          enable_break_failure_warning ();
792
          bfd_close (tmp_bfd);
793
          return 0;
794
        }
795
      addr = extract_unsigned_integer (addr_buf, sizeof addr_buf, byte_order);
796
 
797
      /* We're done with the temporary bfd.  */
798
      bfd_close (tmp_bfd);
799
 
800
      /* We're also done with the loadmap.  */
801
      xfree (ldm);
802
 
803
      /* Now (finally!) create the solib breakpoint.  */
804
      create_solib_event_breakpoint (target_gdbarch, addr);
805
 
806
      return 1;
807
    }
808
 
809
  /* Tell the user we couldn't set a dynamic linker breakpoint.  */
810
  enable_break_failure_warning ();
811
 
812
  /* Failure return.  */
813
  return 0;
814
}
815
 
816
static int
817
enable_break (void)
818
{
819
  asection *interp_sect;
820
 
821
  /* Remove all the solib event breakpoints.  Their addresses
822
     may have changed since the last time we ran the program.  */
823
  remove_solib_event_breakpoints ();
824
 
825
  if (symfile_objfile == NULL)
826
    {
827
      if (solib_frv_debug)
828
        fprintf_unfiltered (gdb_stdlog,
829
                            "enable_break: No symbol file found.\n");
830
      return 0;
831
    }
832
 
833
  if (!symfile_objfile->ei.entry_point_p)
834
    {
835
      if (solib_frv_debug)
836
        fprintf_unfiltered (gdb_stdlog,
837
                            "enable_break: Symbol file has no entry point.\n");
838
      return 0;
839
    }
840
 
841
  /* Check for the presence of a .interp section.  If there is no
842
     such section, the executable is statically linked.  */
843
 
844
  interp_sect = bfd_get_section_by_name (exec_bfd, ".interp");
845
 
846
  if (interp_sect == NULL)
847
    {
848
      if (solib_frv_debug)
849
        fprintf_unfiltered (gdb_stdlog,
850
                            "enable_break: No .interp section found.\n");
851
      return 0;
852
    }
853
 
854
  enable_break1_done = 1;
855
  create_solib_event_breakpoint (target_gdbarch,
856
                                 symfile_objfile->ei.entry_point);
857
 
858
  if (solib_frv_debug)
859
    fprintf_unfiltered (gdb_stdlog,
860
                        "enable_break: solib event breakpoint placed at entry point: %s\n",
861
                        hex_string_custom (symfile_objfile->ei.entry_point, 8));
862
  return 1;
863
}
864
 
865
/*
866
 
867
   LOCAL FUNCTION
868
 
869
   special_symbol_handling -- additional shared library symbol handling
870
 
871
   SYNOPSIS
872
 
873
   void special_symbol_handling ()
874
 
875
   DESCRIPTION
876
 
877
   Once the symbols from a shared object have been loaded in the usual
878
   way, we are called to do any system specific symbol handling that
879
   is needed.
880
 
881
 */
882
 
883
static void
884
frv_special_symbol_handling (void)
885
{
886
  /* Nothing needed (yet) for FRV. */
887
}
888
 
889
static void
890
frv_relocate_main_executable (void)
891
{
892
  int status;
893
  CORE_ADDR exec_addr, interp_addr;
894
  struct int_elf32_fdpic_loadmap *ldm;
895
  struct cleanup *old_chain;
896
  struct section_offsets *new_offsets;
897
  int changed;
898
  struct obj_section *osect;
899
 
900
  status = frv_fdpic_loadmap_addresses (target_gdbarch,
901
                                        &interp_addr, &exec_addr);
902
 
903
  if (status < 0 || (exec_addr == 0 && interp_addr == 0))
904
    {
905
      /* Not using FDPIC ABI, so do nothing.  */
906
      return;
907
    }
908
 
909
  /* Fetch the loadmap located at ``exec_addr''.  */
910
  ldm = fetch_loadmap (exec_addr);
911
  if (ldm == NULL)
912
    error (_("Unable to load the executable's loadmap."));
913
 
914
  if (main_executable_lm_info)
915
    xfree (main_executable_lm_info);
916
  main_executable_lm_info = xcalloc (1, sizeof (struct lm_info));
917
  main_executable_lm_info->map = ldm;
918
 
919
  new_offsets = xcalloc (symfile_objfile->num_sections,
920
                         sizeof (struct section_offsets));
921
  old_chain = make_cleanup (xfree, new_offsets);
922
  changed = 0;
923
 
924
  ALL_OBJFILE_OSECTIONS (symfile_objfile, osect)
925
    {
926
      CORE_ADDR orig_addr, addr, offset;
927
      int osect_idx;
928
      int seg;
929
 
930
      osect_idx = osect->the_bfd_section->index;
931
 
932
      /* Current address of section.  */
933
      addr = obj_section_addr (osect);
934
      /* Offset from where this section started.  */
935
      offset = ANOFFSET (symfile_objfile->section_offsets, osect_idx);
936
      /* Original address prior to any past relocations.  */
937
      orig_addr = addr - offset;
938
 
939
      for (seg = 0; seg < ldm->nsegs; seg++)
940
        {
941
          if (ldm->segs[seg].p_vaddr <= orig_addr
942
              && orig_addr < ldm->segs[seg].p_vaddr + ldm->segs[seg].p_memsz)
943
            {
944
              new_offsets->offsets[osect_idx]
945
                = ldm->segs[seg].addr - ldm->segs[seg].p_vaddr;
946
 
947
              if (new_offsets->offsets[osect_idx] != offset)
948
                changed = 1;
949
              break;
950
            }
951
        }
952
    }
953
 
954
  if (changed)
955
    objfile_relocate (symfile_objfile, new_offsets);
956
 
957
  do_cleanups (old_chain);
958
 
959
  /* Now that symfile_objfile has been relocated, we can compute the
960
     GOT value and stash it away.  */
961
  main_executable_lm_info->got_value = main_got ();
962
}
963
 
964
/*
965
 
966
   GLOBAL FUNCTION
967
 
968
   frv_solib_create_inferior_hook -- shared library startup support
969
 
970
   SYNOPSIS
971
 
972
   void frv_solib_create_inferior_hook ()
973
 
974
   DESCRIPTION
975
 
976
   When gdb starts up the inferior, it nurses it along (through the
977
   shell) until it is ready to execute it's first instruction.  At this
978
   point, this function gets called via expansion of the macro
979
   SOLIB_CREATE_INFERIOR_HOOK.
980
 
981
   For the FR-V shared library ABI (FDPIC), the main executable
982
   needs to be relocated.  The shared library breakpoints also need
983
   to be enabled.
984
 */
985
 
986
static void
987
frv_solib_create_inferior_hook (int from_tty)
988
{
989
  /* Relocate main executable.  */
990
  frv_relocate_main_executable ();
991
 
992
  /* Enable shared library breakpoints.  */
993
  if (!enable_break ())
994
    {
995
      warning (_("shared library handler failed to enable breakpoint"));
996
      return;
997
    }
998
}
999
 
1000
static void
1001
frv_clear_solib (void)
1002
{
1003
  lm_base_cache = 0;
1004
  enable_break1_done = 0;
1005
  enable_break2_done = 0;
1006
  main_lm_addr = 0;
1007
  if (main_executable_lm_info != 0)
1008
    {
1009
      xfree (main_executable_lm_info->map);
1010
      xfree (main_executable_lm_info->dyn_syms);
1011
      xfree (main_executable_lm_info->dyn_relocs);
1012
      xfree (main_executable_lm_info);
1013
      main_executable_lm_info = 0;
1014
    }
1015
}
1016
 
1017
static void
1018
frv_free_so (struct so_list *so)
1019
{
1020
  xfree (so->lm_info->map);
1021
  xfree (so->lm_info->dyn_syms);
1022
  xfree (so->lm_info->dyn_relocs);
1023
  xfree (so->lm_info);
1024
}
1025
 
1026
static void
1027
frv_relocate_section_addresses (struct so_list *so,
1028
                                 struct target_section *sec)
1029
{
1030
  int seg;
1031
  struct int_elf32_fdpic_loadmap *map;
1032
 
1033
  map = so->lm_info->map;
1034
 
1035
  for (seg = 0; seg < map->nsegs; seg++)
1036
    {
1037
      if (map->segs[seg].p_vaddr <= sec->addr
1038
          && sec->addr < map->segs[seg].p_vaddr + map->segs[seg].p_memsz)
1039
        {
1040
          CORE_ADDR displ = map->segs[seg].addr - map->segs[seg].p_vaddr;
1041
          sec->addr += displ;
1042
          sec->endaddr += displ;
1043
          break;
1044
        }
1045
    }
1046
}
1047
 
1048
/* Return the GOT address associated with the main executable.  Return
1049
 
1050
 
1051
static CORE_ADDR
1052
main_got (void)
1053
{
1054
  struct minimal_symbol *got_sym;
1055
 
1056
  got_sym = lookup_minimal_symbol ("_GLOBAL_OFFSET_TABLE_", NULL, symfile_objfile);
1057
  if (got_sym == 0)
1058
    return 0;
1059
 
1060
  return SYMBOL_VALUE_ADDRESS (got_sym);
1061
}
1062
 
1063
/* Find the global pointer for the given function address ADDR.  */
1064
 
1065
CORE_ADDR
1066
frv_fdpic_find_global_pointer (CORE_ADDR addr)
1067
{
1068
  struct so_list *so;
1069
 
1070
  so = master_so_list ();
1071
  while (so)
1072
    {
1073
      int seg;
1074
      struct int_elf32_fdpic_loadmap *map;
1075
 
1076
      map = so->lm_info->map;
1077
 
1078
      for (seg = 0; seg < map->nsegs; seg++)
1079
        {
1080
          if (map->segs[seg].addr <= addr
1081
              && addr < map->segs[seg].addr + map->segs[seg].p_memsz)
1082
            return so->lm_info->got_value;
1083
        }
1084
 
1085
      so = so->next;
1086
    }
1087
 
1088
  /* Didn't find it it any of the shared objects.  So assume it's in the
1089
     main executable.  */
1090
  return main_got ();
1091
}
1092
 
1093
/* Forward declarations for frv_fdpic_find_canonical_descriptor().  */
1094
static CORE_ADDR find_canonical_descriptor_in_load_object
1095
  (CORE_ADDR, CORE_ADDR, char *, bfd *, struct lm_info *);
1096
 
1097
/* Given a function entry point, attempt to find the canonical descriptor
1098
   associated with that entry point.  Return 0 if no canonical descriptor
1099
   could be found.  */
1100
 
1101
CORE_ADDR
1102
frv_fdpic_find_canonical_descriptor (CORE_ADDR entry_point)
1103
{
1104
  char *name;
1105
  CORE_ADDR addr;
1106
  CORE_ADDR got_value;
1107
  struct int_elf32_fdpic_loadmap *ldm = 0;
1108
  struct symbol *sym;
1109
  int status;
1110
  CORE_ADDR exec_loadmap_addr;
1111
 
1112
  /* Fetch the corresponding global pointer for the entry point.  */
1113
  got_value = frv_fdpic_find_global_pointer (entry_point);
1114
 
1115
  /* Attempt to find the name of the function.  If the name is available,
1116
     it'll be used as an aid in finding matching functions in the dynamic
1117
     symbol table.  */
1118
  sym = find_pc_function (entry_point);
1119
  if (sym == 0)
1120
    name = 0;
1121
  else
1122
    name = SYMBOL_LINKAGE_NAME (sym);
1123
 
1124
  /* Check the main executable.  */
1125
  addr = find_canonical_descriptor_in_load_object
1126
           (entry_point, got_value, name, symfile_objfile->obfd,
1127
            main_executable_lm_info);
1128
 
1129
  /* If descriptor not found via main executable, check each load object
1130
     in list of shared objects.  */
1131
  if (addr == 0)
1132
    {
1133
      struct so_list *so;
1134
 
1135
      so = master_so_list ();
1136
      while (so)
1137
        {
1138
          addr = find_canonical_descriptor_in_load_object
1139
                   (entry_point, got_value, name, so->abfd, so->lm_info);
1140
 
1141
          if (addr != 0)
1142
            break;
1143
 
1144
          so = so->next;
1145
        }
1146
    }
1147
 
1148
  return addr;
1149
}
1150
 
1151
static CORE_ADDR
1152
find_canonical_descriptor_in_load_object
1153
  (CORE_ADDR entry_point, CORE_ADDR got_value, char *name, bfd *abfd,
1154
   struct lm_info *lm)
1155
{
1156
  enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch);
1157
  arelent *rel;
1158
  unsigned int i;
1159
  CORE_ADDR addr = 0;
1160
 
1161
  /* Nothing to do if no bfd.  */
1162
  if (abfd == 0)
1163
    return 0;
1164
 
1165
  /* Nothing to do if no link map.  */
1166
  if (lm == 0)
1167
    return 0;
1168
 
1169
  /* We want to scan the dynamic relocs for R_FRV_FUNCDESC relocations.
1170
     (More about this later.)  But in order to fetch the relocs, we
1171
     need to first fetch the dynamic symbols.  These symbols need to
1172
     be cached due to the way that bfd_canonicalize_dynamic_reloc()
1173
     works.  (See the comments in the declaration of struct lm_info
1174
     for more information.)  */
1175
  if (lm->dyn_syms == NULL)
1176
    {
1177
      long storage_needed;
1178
      unsigned int number_of_symbols;
1179
 
1180
      /* Determine amount of space needed to hold the dynamic symbol table.  */
1181
      storage_needed = bfd_get_dynamic_symtab_upper_bound (abfd);
1182
 
1183
      /* If there are no dynamic symbols, there's nothing to do.  */
1184
      if (storage_needed <= 0)
1185
        return 0;
1186
 
1187
      /* Allocate space for the dynamic symbol table.  */
1188
      lm->dyn_syms = (asymbol **) xmalloc (storage_needed);
1189
 
1190
      /* Fetch the dynamic symbol table.  */
1191
      number_of_symbols = bfd_canonicalize_dynamic_symtab (abfd, lm->dyn_syms);
1192
 
1193
      if (number_of_symbols == 0)
1194
        return 0;
1195
    }
1196
 
1197
  /* Fetch the dynamic relocations if not already cached.  */
1198
  if (lm->dyn_relocs == NULL)
1199
    {
1200
      long storage_needed;
1201
 
1202
      /* Determine amount of space needed to hold the dynamic relocs.  */
1203
      storage_needed = bfd_get_dynamic_reloc_upper_bound (abfd);
1204
 
1205
      /* Bail out if there are no dynamic relocs.  */
1206
      if (storage_needed <= 0)
1207
        return 0;
1208
 
1209
      /* Allocate space for the relocs.  */
1210
      lm->dyn_relocs = (arelent **) xmalloc (storage_needed);
1211
 
1212
      /* Fetch the dynamic relocs.  */
1213
      lm->dyn_reloc_count
1214
        = bfd_canonicalize_dynamic_reloc (abfd, lm->dyn_relocs, lm->dyn_syms);
1215
    }
1216
 
1217
  /* Search the dynamic relocs.  */
1218
  for (i = 0; i < lm->dyn_reloc_count; i++)
1219
    {
1220
      rel = lm->dyn_relocs[i];
1221
 
1222
      /* Relocs of interest are those which meet the following
1223
         criteria:
1224
 
1225
           - the names match (assuming the caller could provide
1226
             a name which matches ``entry_point'').
1227
           - the relocation type must be R_FRV_FUNCDESC.  Relocs
1228
             of this type are used (by the dynamic linker) to
1229
             look up the address of a canonical descriptor (allocating
1230
             it if need be) and initializing the GOT entry referred
1231
             to by the offset to the address of the descriptor.
1232
 
1233
         These relocs of interest may be used to obtain a
1234
         candidate descriptor by first adjusting the reloc's
1235
         address according to the link map and then dereferencing
1236
         this address (which is a GOT entry) to obtain a descriptor
1237
         address.  */
1238
      if ((name == 0 || strcmp (name, (*rel->sym_ptr_ptr)->name) == 0)
1239
          && rel->howto->type == R_FRV_FUNCDESC)
1240
        {
1241
          gdb_byte buf [FRV_PTR_SIZE];
1242
 
1243
          /* Compute address of address of candidate descriptor.  */
1244
          addr = rel->address + displacement_from_map (lm->map, rel->address);
1245
 
1246
          /* Fetch address of candidate descriptor.  */
1247
          if (target_read_memory (addr, buf, sizeof buf) != 0)
1248
            continue;
1249
          addr = extract_unsigned_integer (buf, sizeof buf, byte_order);
1250
 
1251
          /* Check for matching entry point.  */
1252
          if (target_read_memory (addr, buf, sizeof buf) != 0)
1253
            continue;
1254
          if (extract_unsigned_integer (buf, sizeof buf, byte_order)
1255
              != entry_point)
1256
            continue;
1257
 
1258
          /* Check for matching got value.  */
1259
          if (target_read_memory (addr + 4, buf, sizeof buf) != 0)
1260
            continue;
1261
          if (extract_unsigned_integer (buf, sizeof buf, byte_order)
1262
              != got_value)
1263
            continue;
1264
 
1265
          /* Match was successful!  Exit loop.  */
1266
          break;
1267
        }
1268
    }
1269
 
1270
  return addr;
1271
}
1272
 
1273
/* Given an objfile, return the address of its link map.  This value is
1274
   needed for TLS support.  */
1275
CORE_ADDR
1276
frv_fetch_objfile_link_map (struct objfile *objfile)
1277
{
1278
  struct so_list *so;
1279
 
1280
  /* Cause frv_current_sos() to be run if it hasn't been already.  */
1281
  if (main_lm_addr == 0)
1282
    solib_add (0, 0, 0, 1);
1283
 
1284
  /* frv_current_sos() will set main_lm_addr for the main executable.  */
1285
  if (objfile == symfile_objfile)
1286
    return main_lm_addr;
1287
 
1288
  /* The other link map addresses may be found by examining the list
1289
     of shared libraries.  */
1290
  for (so = master_so_list (); so; so = so->next)
1291
    {
1292
      if (so->objfile == objfile)
1293
        return so->lm_info->lm_addr;
1294
    }
1295
 
1296
  /* Not found!  */
1297
  return 0;
1298
}
1299
 
1300
struct target_so_ops frv_so_ops;
1301
 
1302
/* Provide a prototype to silence -Wmissing-prototypes.  */
1303
extern initialize_file_ftype _initialize_frv_solib;
1304
 
1305
void
1306
_initialize_frv_solib (void)
1307
{
1308
  frv_so_ops.relocate_section_addresses = frv_relocate_section_addresses;
1309
  frv_so_ops.free_so = frv_free_so;
1310
  frv_so_ops.clear_solib = frv_clear_solib;
1311
  frv_so_ops.solib_create_inferior_hook = frv_solib_create_inferior_hook;
1312
  frv_so_ops.special_symbol_handling = frv_special_symbol_handling;
1313
  frv_so_ops.current_sos = frv_current_sos;
1314
  frv_so_ops.open_symbol_file_object = open_symbol_file_object;
1315
  frv_so_ops.in_dynsym_resolve_code = frv_in_dynsym_resolve_code;
1316
  frv_so_ops.bfd_open = solib_bfd_open;
1317
 
1318
  /* Debug this file's internals.  */
1319
  add_setshow_zinteger_cmd ("solib-frv", class_maintenance,
1320
                            &solib_frv_debug, _("\
1321
Set internal debugging of shared library code for FR-V."), _("\
1322
Show internal debugging of shared library code for FR-V."), _("\
1323
When non-zero, FR-V solib specific internal debugging is enabled."),
1324
                            NULL,
1325
                            NULL, /* FIXME: i18n: */
1326
                            &setdebuglist, &showdebuglist);
1327
}

powered by: WebSVN 2.1.0

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