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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-stable/] [gdb-7.2/] [gdb/] [solib-frv.c] - Blame information for rev 853

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

Line No. Rev Author Line
1 330 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_break2_done = 0;
635
 
636
static int
637
enable_break2 (void)
638
{
639
  enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch);
640
  int success = 0;
641
  char **bkpt_namep;
642
  asection *interp_sect;
643
 
644
  if (enable_break2_done)
645
    return 1;
646
 
647
  interp_text_sect_low = interp_text_sect_high = 0;
648
  interp_plt_sect_low = interp_plt_sect_high = 0;
649
 
650
  /* Find the .interp section; if not found, warn the user and drop
651
     into the old breakpoint at symbol code.  */
652
  interp_sect = bfd_get_section_by_name (exec_bfd, ".interp");
653
  if (interp_sect)
654
    {
655
      unsigned int interp_sect_size;
656
      gdb_byte *buf;
657
      bfd *tmp_bfd = NULL;
658
      int status;
659
      CORE_ADDR addr, interp_loadmap_addr;
660
      gdb_byte addr_buf[FRV_PTR_SIZE];
661
      struct int_elf32_fdpic_loadmap *ldm;
662
      volatile struct gdb_exception ex;
663
 
664
      /* Read the contents of the .interp section into a local buffer;
665
         the contents specify the dynamic linker this program uses.  */
666
      interp_sect_size = bfd_section_size (exec_bfd, interp_sect);
667
      buf = alloca (interp_sect_size);
668
      bfd_get_section_contents (exec_bfd, interp_sect,
669
                                buf, 0, interp_sect_size);
670
 
671
      /* Now we need to figure out where the dynamic linker was
672
         loaded so that we can load its symbols and place a breakpoint
673
         in the dynamic linker itself.
674
 
675
         This address is stored on the stack.  However, I've been unable
676
         to find any magic formula to find it for Solaris (appears to
677
         be trivial on GNU/Linux).  Therefore, we have to try an alternate
678
         mechanism to find the dynamic linker's base address.  */
679
 
680
      TRY_CATCH (ex, RETURN_MASK_ALL)
681
        {
682
          tmp_bfd = solib_bfd_open (buf);
683
        }
684
      if (tmp_bfd == NULL)
685
        {
686
          enable_break_failure_warning ();
687
          return 0;
688
        }
689
 
690
      status = frv_fdpic_loadmap_addresses (target_gdbarch,
691
                                            &interp_loadmap_addr, 0);
692
      if (status < 0)
693
        {
694
          warning (_("Unable to determine dynamic linker loadmap address."));
695
          enable_break_failure_warning ();
696
          bfd_close (tmp_bfd);
697
          return 0;
698
        }
699
 
700
      if (solib_frv_debug)
701
        fprintf_unfiltered (gdb_stdlog,
702
                            "enable_break: interp_loadmap_addr = %s\n",
703
                            hex_string_custom (interp_loadmap_addr, 8));
704
 
705
      ldm = fetch_loadmap (interp_loadmap_addr);
706
      if (ldm == NULL)
707
        {
708
          warning (_("Unable to load dynamic linker loadmap at address %s."),
709
                   hex_string_custom (interp_loadmap_addr, 8));
710
          enable_break_failure_warning ();
711
          bfd_close (tmp_bfd);
712
          return 0;
713
        }
714
 
715
      /* Record the relocated start and end address of the dynamic linker
716
         text and plt section for svr4_in_dynsym_resolve_code.  */
717
      interp_sect = bfd_get_section_by_name (tmp_bfd, ".text");
718
      if (interp_sect)
719
        {
720
          interp_text_sect_low
721
            = bfd_section_vma (tmp_bfd, interp_sect);
722
          interp_text_sect_low
723
            += displacement_from_map (ldm, interp_text_sect_low);
724
          interp_text_sect_high
725
            = interp_text_sect_low + bfd_section_size (tmp_bfd, interp_sect);
726
        }
727
      interp_sect = bfd_get_section_by_name (tmp_bfd, ".plt");
728
      if (interp_sect)
729
        {
730
          interp_plt_sect_low =
731
            bfd_section_vma (tmp_bfd, interp_sect);
732
          interp_plt_sect_low
733
            += displacement_from_map (ldm, interp_plt_sect_low);
734
          interp_plt_sect_high =
735
            interp_plt_sect_low + bfd_section_size (tmp_bfd, interp_sect);
736
        }
737
 
738
      addr = bfd_lookup_symbol (tmp_bfd, "_dl_debug_addr");
739
      if (addr == 0)
740
        {
741
          warning (_("Could not find symbol _dl_debug_addr in dynamic linker"));
742
          enable_break_failure_warning ();
743
          bfd_close (tmp_bfd);
744
          return 0;
745
        }
746
 
747
      if (solib_frv_debug)
748
        fprintf_unfiltered (gdb_stdlog,
749
                            "enable_break: _dl_debug_addr (prior to relocation) = %s\n",
750
                            hex_string_custom (addr, 8));
751
 
752
      addr += displacement_from_map (ldm, addr);
753
 
754
      if (solib_frv_debug)
755
        fprintf_unfiltered (gdb_stdlog,
756
                            "enable_break: _dl_debug_addr (after relocation) = %s\n",
757
                            hex_string_custom (addr, 8));
758
 
759
      /* Fetch the address of the r_debug struct.  */
760
      if (target_read_memory (addr, addr_buf, sizeof addr_buf) != 0)
761
        {
762
          warning (_("Unable to fetch contents of _dl_debug_addr (at address %s) from dynamic linker"),
763
                   hex_string_custom (addr, 8));
764
        }
765
      addr = extract_unsigned_integer (addr_buf, sizeof addr_buf, byte_order);
766
 
767
      if (solib_frv_debug)
768
        fprintf_unfiltered (gdb_stdlog,
769
                            "enable_break: _dl_debug_addr[0..3] = %s\n",
770
                            hex_string_custom (addr, 8));
771
 
772
      /* If it's zero, then the ldso hasn't initialized yet, and so
773
         there are no shared libs yet loaded.  */
774
      if (addr == 0)
775
        {
776
          if (solib_frv_debug)
777
            fprintf_unfiltered (gdb_stdlog,
778
                                "enable_break: ldso not yet initialized\n");
779
          /* Do not warn, but mark to run again.  */
780
          return 0;
781
        }
782
 
783
      /* Fetch the r_brk field.  It's 8 bytes from the start of
784
         _dl_debug_addr.  */
785
      if (target_read_memory (addr + 8, addr_buf, sizeof addr_buf) != 0)
786
        {
787
          warning (_("Unable to fetch _dl_debug_addr->r_brk (at address %s) from dynamic linker"),
788
                   hex_string_custom (addr + 8, 8));
789
          enable_break_failure_warning ();
790
          bfd_close (tmp_bfd);
791
          return 0;
792
        }
793
      addr = extract_unsigned_integer (addr_buf, sizeof addr_buf, byte_order);
794
 
795
      /* Now fetch the function entry point.  */
796
      if (target_read_memory (addr, addr_buf, sizeof addr_buf) != 0)
797
        {
798
          warning (_("Unable to fetch _dl_debug_addr->.r_brk entry point (at address %s) from dynamic linker"),
799
                   hex_string_custom (addr, 8));
800
          enable_break_failure_warning ();
801
          bfd_close (tmp_bfd);
802
          return 0;
803
        }
804
      addr = extract_unsigned_integer (addr_buf, sizeof addr_buf, byte_order);
805
 
806
      /* We're done with the temporary bfd.  */
807
      bfd_close (tmp_bfd);
808
 
809
      /* We're also done with the loadmap.  */
810
      xfree (ldm);
811
 
812
      /* Remove all the solib event breakpoints.  Their addresses
813
         may have changed since the last time we ran the program.  */
814
      remove_solib_event_breakpoints ();
815
 
816
      /* Now (finally!) create the solib breakpoint.  */
817
      create_solib_event_breakpoint (target_gdbarch, addr);
818
 
819
      enable_break2_done = 1;
820
 
821
      return 1;
822
    }
823
 
824
  /* Tell the user we couldn't set a dynamic linker breakpoint.  */
825
  enable_break_failure_warning ();
826
 
827
  /* Failure return.  */
828
  return 0;
829
}
830
 
831
static int
832
enable_break (void)
833
{
834
  asection *interp_sect;
835
 
836
  if (symfile_objfile == NULL)
837
    {
838
      if (solib_frv_debug)
839
        fprintf_unfiltered (gdb_stdlog,
840
                            "enable_break: No symbol file found.\n");
841
      return 0;
842
    }
843
 
844
  if (!symfile_objfile->ei.entry_point_p)
845
    {
846
      if (solib_frv_debug)
847
        fprintf_unfiltered (gdb_stdlog,
848
                            "enable_break: Symbol file has no entry point.\n");
849
      return 0;
850
    }
851
 
852
  /* Check for the presence of a .interp section.  If there is no
853
     such section, the executable is statically linked.  */
854
 
855
  interp_sect = bfd_get_section_by_name (exec_bfd, ".interp");
856
 
857
  if (interp_sect == NULL)
858
    {
859
      if (solib_frv_debug)
860
        fprintf_unfiltered (gdb_stdlog,
861
                            "enable_break: No .interp section found.\n");
862
      return 0;
863
    }
864
 
865
  create_solib_event_breakpoint (target_gdbarch,
866
                                 symfile_objfile->ei.entry_point);
867
 
868
  if (solib_frv_debug)
869
    fprintf_unfiltered (gdb_stdlog,
870
                        "enable_break: solib event breakpoint placed at entry point: %s\n",
871
                        hex_string_custom (symfile_objfile->ei.entry_point, 8));
872
  return 1;
873
}
874
 
875
/*
876
 
877
   LOCAL FUNCTION
878
 
879
   special_symbol_handling -- additional shared library symbol handling
880
 
881
   SYNOPSIS
882
 
883
   void special_symbol_handling ()
884
 
885
   DESCRIPTION
886
 
887
   Once the symbols from a shared object have been loaded in the usual
888
   way, we are called to do any system specific symbol handling that
889
   is needed.
890
 
891
 */
892
 
893
static void
894
frv_special_symbol_handling (void)
895
{
896
  /* Nothing needed (yet) for FRV. */
897
}
898
 
899
static void
900
frv_relocate_main_executable (void)
901
{
902
  int status;
903
  CORE_ADDR exec_addr, interp_addr;
904
  struct int_elf32_fdpic_loadmap *ldm;
905
  struct cleanup *old_chain;
906
  struct section_offsets *new_offsets;
907
  int changed;
908
  struct obj_section *osect;
909
 
910
  status = frv_fdpic_loadmap_addresses (target_gdbarch,
911
                                        &interp_addr, &exec_addr);
912
 
913
  if (status < 0 || (exec_addr == 0 && interp_addr == 0))
914
    {
915
      /* Not using FDPIC ABI, so do nothing.  */
916
      return;
917
    }
918
 
919
  /* Fetch the loadmap located at ``exec_addr''.  */
920
  ldm = fetch_loadmap (exec_addr);
921
  if (ldm == NULL)
922
    error (_("Unable to load the executable's loadmap."));
923
 
924
  if (main_executable_lm_info)
925
    xfree (main_executable_lm_info);
926
  main_executable_lm_info = xcalloc (1, sizeof (struct lm_info));
927
  main_executable_lm_info->map = ldm;
928
 
929
  new_offsets = xcalloc (symfile_objfile->num_sections,
930
                         sizeof (struct section_offsets));
931
  old_chain = make_cleanup (xfree, new_offsets);
932
  changed = 0;
933
 
934
  ALL_OBJFILE_OSECTIONS (symfile_objfile, osect)
935
    {
936
      CORE_ADDR orig_addr, addr, offset;
937
      int osect_idx;
938
      int seg;
939
 
940
      osect_idx = osect->the_bfd_section->index;
941
 
942
      /* Current address of section.  */
943
      addr = obj_section_addr (osect);
944
      /* Offset from where this section started.  */
945
      offset = ANOFFSET (symfile_objfile->section_offsets, osect_idx);
946
      /* Original address prior to any past relocations.  */
947
      orig_addr = addr - offset;
948
 
949
      for (seg = 0; seg < ldm->nsegs; seg++)
950
        {
951
          if (ldm->segs[seg].p_vaddr <= orig_addr
952
              && orig_addr < ldm->segs[seg].p_vaddr + ldm->segs[seg].p_memsz)
953
            {
954
              new_offsets->offsets[osect_idx]
955
                = ldm->segs[seg].addr - ldm->segs[seg].p_vaddr;
956
 
957
              if (new_offsets->offsets[osect_idx] != offset)
958
                changed = 1;
959
              break;
960
            }
961
        }
962
    }
963
 
964
  if (changed)
965
    objfile_relocate (symfile_objfile, new_offsets);
966
 
967
  do_cleanups (old_chain);
968
 
969
  /* Now that symfile_objfile has been relocated, we can compute the
970
     GOT value and stash it away.  */
971
  main_executable_lm_info->got_value = main_got ();
972
}
973
 
974
/*
975
 
976
   GLOBAL FUNCTION
977
 
978
   frv_solib_create_inferior_hook -- shared library startup support
979
 
980
   SYNOPSIS
981
 
982
   void frv_solib_create_inferior_hook ()
983
 
984
   DESCRIPTION
985
 
986
   When gdb starts up the inferior, it nurses it along (through the
987
   shell) until it is ready to execute it's first instruction.  At this
988
   point, this function gets called via expansion of the macro
989
   SOLIB_CREATE_INFERIOR_HOOK.
990
 
991
   For the FR-V shared library ABI (FDPIC), the main executable
992
   needs to be relocated.  The shared library breakpoints also need
993
   to be enabled.
994
 */
995
 
996
static void
997
frv_solib_create_inferior_hook (int from_tty)
998
{
999
  /* Relocate main executable.  */
1000
  frv_relocate_main_executable ();
1001
 
1002
  /* Enable shared library breakpoints.  */
1003
  if (!enable_break ())
1004
    {
1005
      warning (_("shared library handler failed to enable breakpoint"));
1006
      return;
1007
    }
1008
}
1009
 
1010
static void
1011
frv_clear_solib (void)
1012
{
1013
  lm_base_cache = 0;
1014
  enable_break2_done = 0;
1015
  main_lm_addr = 0;
1016
  if (main_executable_lm_info != 0)
1017
    {
1018
      xfree (main_executable_lm_info->map);
1019
      xfree (main_executable_lm_info->dyn_syms);
1020
      xfree (main_executable_lm_info->dyn_relocs);
1021
      xfree (main_executable_lm_info);
1022
      main_executable_lm_info = 0;
1023
    }
1024
}
1025
 
1026
static void
1027
frv_free_so (struct so_list *so)
1028
{
1029
  xfree (so->lm_info->map);
1030
  xfree (so->lm_info->dyn_syms);
1031
  xfree (so->lm_info->dyn_relocs);
1032
  xfree (so->lm_info);
1033
}
1034
 
1035
static void
1036
frv_relocate_section_addresses (struct so_list *so,
1037
                                 struct target_section *sec)
1038
{
1039
  int seg;
1040
  struct int_elf32_fdpic_loadmap *map;
1041
 
1042
  map = so->lm_info->map;
1043
 
1044
  for (seg = 0; seg < map->nsegs; seg++)
1045
    {
1046
      if (map->segs[seg].p_vaddr <= sec->addr
1047
          && sec->addr < map->segs[seg].p_vaddr + map->segs[seg].p_memsz)
1048
        {
1049
          CORE_ADDR displ = map->segs[seg].addr - map->segs[seg].p_vaddr;
1050
 
1051
          sec->addr += displ;
1052
          sec->endaddr += displ;
1053
          break;
1054
        }
1055
    }
1056
}
1057
 
1058
/* Return the GOT address associated with the main executable.  Return
1059
 
1060
 
1061
static CORE_ADDR
1062
main_got (void)
1063
{
1064
  struct minimal_symbol *got_sym;
1065
 
1066
  got_sym = lookup_minimal_symbol ("_GLOBAL_OFFSET_TABLE_", NULL, symfile_objfile);
1067
  if (got_sym == 0)
1068
    return 0;
1069
 
1070
  return SYMBOL_VALUE_ADDRESS (got_sym);
1071
}
1072
 
1073
/* Find the global pointer for the given function address ADDR.  */
1074
 
1075
CORE_ADDR
1076
frv_fdpic_find_global_pointer (CORE_ADDR addr)
1077
{
1078
  struct so_list *so;
1079
 
1080
  so = master_so_list ();
1081
  while (so)
1082
    {
1083
      int seg;
1084
      struct int_elf32_fdpic_loadmap *map;
1085
 
1086
      map = so->lm_info->map;
1087
 
1088
      for (seg = 0; seg < map->nsegs; seg++)
1089
        {
1090
          if (map->segs[seg].addr <= addr
1091
              && addr < map->segs[seg].addr + map->segs[seg].p_memsz)
1092
            return so->lm_info->got_value;
1093
        }
1094
 
1095
      so = so->next;
1096
    }
1097
 
1098
  /* Didn't find it it any of the shared objects.  So assume it's in the
1099
     main executable.  */
1100
  return main_got ();
1101
}
1102
 
1103
/* Forward declarations for frv_fdpic_find_canonical_descriptor().  */
1104
static CORE_ADDR find_canonical_descriptor_in_load_object
1105
  (CORE_ADDR, CORE_ADDR, char *, bfd *, struct lm_info *);
1106
 
1107
/* Given a function entry point, attempt to find the canonical descriptor
1108
   associated with that entry point.  Return 0 if no canonical descriptor
1109
   could be found.  */
1110
 
1111
CORE_ADDR
1112
frv_fdpic_find_canonical_descriptor (CORE_ADDR entry_point)
1113
{
1114
  char *name;
1115
  CORE_ADDR addr;
1116
  CORE_ADDR got_value;
1117
  struct int_elf32_fdpic_loadmap *ldm = 0;
1118
  struct symbol *sym;
1119
  int status;
1120
  CORE_ADDR exec_loadmap_addr;
1121
 
1122
  /* Fetch the corresponding global pointer for the entry point.  */
1123
  got_value = frv_fdpic_find_global_pointer (entry_point);
1124
 
1125
  /* Attempt to find the name of the function.  If the name is available,
1126
     it'll be used as an aid in finding matching functions in the dynamic
1127
     symbol table.  */
1128
  sym = find_pc_function (entry_point);
1129
  if (sym == 0)
1130
    name = 0;
1131
  else
1132
    name = SYMBOL_LINKAGE_NAME (sym);
1133
 
1134
  /* Check the main executable.  */
1135
  addr = find_canonical_descriptor_in_load_object
1136
           (entry_point, got_value, name, symfile_objfile->obfd,
1137
            main_executable_lm_info);
1138
 
1139
  /* If descriptor not found via main executable, check each load object
1140
     in list of shared objects.  */
1141
  if (addr == 0)
1142
    {
1143
      struct so_list *so;
1144
 
1145
      so = master_so_list ();
1146
      while (so)
1147
        {
1148
          addr = find_canonical_descriptor_in_load_object
1149
                   (entry_point, got_value, name, so->abfd, so->lm_info);
1150
 
1151
          if (addr != 0)
1152
            break;
1153
 
1154
          so = so->next;
1155
        }
1156
    }
1157
 
1158
  return addr;
1159
}
1160
 
1161
static CORE_ADDR
1162
find_canonical_descriptor_in_load_object
1163
  (CORE_ADDR entry_point, CORE_ADDR got_value, char *name, bfd *abfd,
1164
   struct lm_info *lm)
1165
{
1166
  enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch);
1167
  arelent *rel;
1168
  unsigned int i;
1169
  CORE_ADDR addr = 0;
1170
 
1171
  /* Nothing to do if no bfd.  */
1172
  if (abfd == 0)
1173
    return 0;
1174
 
1175
  /* Nothing to do if no link map.  */
1176
  if (lm == 0)
1177
    return 0;
1178
 
1179
  /* We want to scan the dynamic relocs for R_FRV_FUNCDESC relocations.
1180
     (More about this later.)  But in order to fetch the relocs, we
1181
     need to first fetch the dynamic symbols.  These symbols need to
1182
     be cached due to the way that bfd_canonicalize_dynamic_reloc()
1183
     works.  (See the comments in the declaration of struct lm_info
1184
     for more information.)  */
1185
  if (lm->dyn_syms == NULL)
1186
    {
1187
      long storage_needed;
1188
      unsigned int number_of_symbols;
1189
 
1190
      /* Determine amount of space needed to hold the dynamic symbol table.  */
1191
      storage_needed = bfd_get_dynamic_symtab_upper_bound (abfd);
1192
 
1193
      /* If there are no dynamic symbols, there's nothing to do.  */
1194
      if (storage_needed <= 0)
1195
        return 0;
1196
 
1197
      /* Allocate space for the dynamic symbol table.  */
1198
      lm->dyn_syms = (asymbol **) xmalloc (storage_needed);
1199
 
1200
      /* Fetch the dynamic symbol table.  */
1201
      number_of_symbols = bfd_canonicalize_dynamic_symtab (abfd, lm->dyn_syms);
1202
 
1203
      if (number_of_symbols == 0)
1204
        return 0;
1205
    }
1206
 
1207
  /* Fetch the dynamic relocations if not already cached.  */
1208
  if (lm->dyn_relocs == NULL)
1209
    {
1210
      long storage_needed;
1211
 
1212
      /* Determine amount of space needed to hold the dynamic relocs.  */
1213
      storage_needed = bfd_get_dynamic_reloc_upper_bound (abfd);
1214
 
1215
      /* Bail out if there are no dynamic relocs.  */
1216
      if (storage_needed <= 0)
1217
        return 0;
1218
 
1219
      /* Allocate space for the relocs.  */
1220
      lm->dyn_relocs = (arelent **) xmalloc (storage_needed);
1221
 
1222
      /* Fetch the dynamic relocs.  */
1223
      lm->dyn_reloc_count
1224
        = bfd_canonicalize_dynamic_reloc (abfd, lm->dyn_relocs, lm->dyn_syms);
1225
    }
1226
 
1227
  /* Search the dynamic relocs.  */
1228
  for (i = 0; i < lm->dyn_reloc_count; i++)
1229
    {
1230
      rel = lm->dyn_relocs[i];
1231
 
1232
      /* Relocs of interest are those which meet the following
1233
         criteria:
1234
 
1235
           - the names match (assuming the caller could provide
1236
             a name which matches ``entry_point'').
1237
           - the relocation type must be R_FRV_FUNCDESC.  Relocs
1238
             of this type are used (by the dynamic linker) to
1239
             look up the address of a canonical descriptor (allocating
1240
             it if need be) and initializing the GOT entry referred
1241
             to by the offset to the address of the descriptor.
1242
 
1243
         These relocs of interest may be used to obtain a
1244
         candidate descriptor by first adjusting the reloc's
1245
         address according to the link map and then dereferencing
1246
         this address (which is a GOT entry) to obtain a descriptor
1247
         address.  */
1248
      if ((name == 0 || strcmp (name, (*rel->sym_ptr_ptr)->name) == 0)
1249
          && rel->howto->type == R_FRV_FUNCDESC)
1250
        {
1251
          gdb_byte buf [FRV_PTR_SIZE];
1252
 
1253
          /* Compute address of address of candidate descriptor.  */
1254
          addr = rel->address + displacement_from_map (lm->map, rel->address);
1255
 
1256
          /* Fetch address of candidate descriptor.  */
1257
          if (target_read_memory (addr, buf, sizeof buf) != 0)
1258
            continue;
1259
          addr = extract_unsigned_integer (buf, sizeof buf, byte_order);
1260
 
1261
          /* Check for matching entry point.  */
1262
          if (target_read_memory (addr, buf, sizeof buf) != 0)
1263
            continue;
1264
          if (extract_unsigned_integer (buf, sizeof buf, byte_order)
1265
              != entry_point)
1266
            continue;
1267
 
1268
          /* Check for matching got value.  */
1269
          if (target_read_memory (addr + 4, buf, sizeof buf) != 0)
1270
            continue;
1271
          if (extract_unsigned_integer (buf, sizeof buf, byte_order)
1272
              != got_value)
1273
            continue;
1274
 
1275
          /* Match was successful!  Exit loop.  */
1276
          break;
1277
        }
1278
    }
1279
 
1280
  return addr;
1281
}
1282
 
1283
/* Given an objfile, return the address of its link map.  This value is
1284
   needed for TLS support.  */
1285
CORE_ADDR
1286
frv_fetch_objfile_link_map (struct objfile *objfile)
1287
{
1288
  struct so_list *so;
1289
 
1290
  /* Cause frv_current_sos() to be run if it hasn't been already.  */
1291
  if (main_lm_addr == 0)
1292
    solib_add (0, 0, 0, 1);
1293
 
1294
  /* frv_current_sos() will set main_lm_addr for the main executable.  */
1295
  if (objfile == symfile_objfile)
1296
    return main_lm_addr;
1297
 
1298
  /* The other link map addresses may be found by examining the list
1299
     of shared libraries.  */
1300
  for (so = master_so_list (); so; so = so->next)
1301
    {
1302
      if (so->objfile == objfile)
1303
        return so->lm_info->lm_addr;
1304
    }
1305
 
1306
  /* Not found!  */
1307
  return 0;
1308
}
1309
 
1310
struct target_so_ops frv_so_ops;
1311
 
1312
/* Provide a prototype to silence -Wmissing-prototypes.  */
1313
extern initialize_file_ftype _initialize_frv_solib;
1314
 
1315
void
1316
_initialize_frv_solib (void)
1317
{
1318
  frv_so_ops.relocate_section_addresses = frv_relocate_section_addresses;
1319
  frv_so_ops.free_so = frv_free_so;
1320
  frv_so_ops.clear_solib = frv_clear_solib;
1321
  frv_so_ops.solib_create_inferior_hook = frv_solib_create_inferior_hook;
1322
  frv_so_ops.special_symbol_handling = frv_special_symbol_handling;
1323
  frv_so_ops.current_sos = frv_current_sos;
1324
  frv_so_ops.open_symbol_file_object = open_symbol_file_object;
1325
  frv_so_ops.in_dynsym_resolve_code = frv_in_dynsym_resolve_code;
1326
  frv_so_ops.bfd_open = solib_bfd_open;
1327
 
1328
  /* Debug this file's internals.  */
1329
  add_setshow_zinteger_cmd ("solib-frv", class_maintenance,
1330
                            &solib_frv_debug, _("\
1331
Set internal debugging of shared library code for FR-V."), _("\
1332
Show internal debugging of shared library code for FR-V."), _("\
1333
When non-zero, FR-V solib specific internal debugging is enabled."),
1334
                            NULL,
1335
                            NULL, /* FIXME: i18n: */
1336
                            &setdebuglist, &showdebuglist);
1337
}

powered by: WebSVN 2.1.0

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