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