xref: /openbsd/gnu/usr.bin/binutils/gdb/solib-frv.c (revision 11efff7f)
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 *
fetch_loadmap(CORE_ADDR ldmaddr)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
bfd_lookup_symbol(bfd * abfd,char * symname)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
open_symbol_file_object(void * from_ttyp)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
lm_base(void)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 *
frv_current_sos(void)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 	    {
482 	      warning ("frv_current_sos: Can't read pathname for link map entry: %s\n",
483 		       safe_strerror (errcode));
484 	    }
485 	  else
486 	    {
487 	      strncpy (sop->so_name, name_buf, SO_NAME_MAX_PATH_SIZE - 1);
488 	      sop->so_name[SO_NAME_MAX_PATH_SIZE - 1] = '\0';
489 	      xfree (name_buf);
490 	      strcpy (sop->so_original_name, sop->so_name);
491 	    }
492 
493 	  *sos_next_ptr = sop;
494 	  sos_next_ptr = &sop->next;
495 	}
496 
497       lm_addr = extract_unsigned_integer (&lm_buf.l_next, sizeof (lm_buf.l_next));
498     }
499 
500   enable_break2 ();
501 
502   return sos_head;
503 }
504 
505 
506 /* Return 1 if PC lies in the dynamic symbol resolution code of the
507    run time loader.  */
508 
509 static CORE_ADDR interp_text_sect_low;
510 static CORE_ADDR interp_text_sect_high;
511 static CORE_ADDR interp_plt_sect_low;
512 static CORE_ADDR interp_plt_sect_high;
513 
514 static int
frv_in_dynsym_resolve_code(CORE_ADDR pc)515 frv_in_dynsym_resolve_code (CORE_ADDR pc)
516 {
517   return ((pc >= interp_text_sect_low && pc < interp_text_sect_high)
518 	  || (pc >= interp_plt_sect_low && pc < interp_plt_sect_high)
519 	  || in_plt_section (pc, NULL));
520 }
521 
522 /* Given a loadmap and an address, return the displacement needed
523    to relocate the address.  */
524 
525 CORE_ADDR
displacement_from_map(struct int_elf32_fdpic_loadmap * map,CORE_ADDR addr)526 displacement_from_map (struct int_elf32_fdpic_loadmap *map,
527                        CORE_ADDR addr)
528 {
529   int seg;
530 
531   for (seg = 0; seg < map->nsegs; seg++)
532     {
533       if (map->segs[seg].p_vaddr <= addr
534           && addr < map->segs[seg].p_vaddr + map->segs[seg].p_memsz)
535 	{
536 	  return map->segs[seg].addr - map->segs[seg].p_vaddr;
537 	}
538     }
539 
540   return 0;
541 }
542 
543 /* Print a warning about being unable to set the dynamic linker
544    breakpoint.  */
545 
546 static void
enable_break_failure_warning(void)547 enable_break_failure_warning (void)
548 {
549   warning ("Unable to find dynamic linker breakpoint function.\n"
550            "GDB will be unable to debug shared library initializers\n"
551 	   "and track explicitly loaded dynamic code.");
552 }
553 
554 /*
555 
556    LOCAL FUNCTION
557 
558    enable_break -- arrange for dynamic linker to hit breakpoint
559 
560    SYNOPSIS
561 
562    int enable_break (void)
563 
564    DESCRIPTION
565 
566    The dynamic linkers has, as part of its debugger interface, support
567    for arranging for the inferior to hit a breakpoint after mapping in
568    the shared libraries.  This function enables that breakpoint.
569 
570    On the FR-V, using the shared library (FDPIC) ABI, the symbol
571    _dl_debug_addr points to the r_debug struct which contains
572    a field called r_brk.  r_brk is the address of the function
573    descriptor upon which a breakpoint must be placed.  Being a
574    function descriptor, we must extract the entry point in order
575    to set the breakpoint.
576 
577    Our strategy will be to get the .interp section from the
578    executable.  This section will provide us with the name of the
579    interpreter.  We'll open the interpreter and then look up
580    the address of _dl_debug_addr.  We then relocate this address
581    using the interpreter's loadmap.  Once the relocated address
582    is known, we fetch the value (address) corresponding to r_brk
583    and then use that value to fetch the entry point of the function
584    we're interested in.
585 
586  */
587 
588 static int enable_break1_done = 0;
589 static int enable_break2_done = 0;
590 
591 static int
enable_break2(void)592 enable_break2 (void)
593 {
594   int success = 0;
595   char **bkpt_namep;
596   asection *interp_sect;
597 
598   if (!enable_break1_done || enable_break2_done)
599     return 1;
600 
601   enable_break2_done = 1;
602 
603   /* First, remove all the solib event breakpoints.  Their addresses
604      may have changed since the last time we ran the program.  */
605   remove_solib_event_breakpoints ();
606 
607   interp_text_sect_low = interp_text_sect_high = 0;
608   interp_plt_sect_low = interp_plt_sect_high = 0;
609 
610   /* Find the .interp section; if not found, warn the user and drop
611      into the old breakpoint at symbol code.  */
612   interp_sect = bfd_get_section_by_name (exec_bfd, ".interp");
613   if (interp_sect)
614     {
615       unsigned int interp_sect_size;
616       char *buf;
617       bfd *tmp_bfd = NULL;
618       int tmp_fd = -1;
619       char *tmp_pathname = NULL;
620       int status;
621       CORE_ADDR addr, interp_loadmap_addr;
622       char addr_buf[FRV_PTR_SIZE];
623       struct int_elf32_fdpic_loadmap *ldm;
624 
625       /* Read the contents of the .interp section into a local buffer;
626          the contents specify the dynamic linker this program uses.  */
627       interp_sect_size = bfd_section_size (exec_bfd, interp_sect);
628       buf = alloca (interp_sect_size);
629       bfd_get_section_contents (exec_bfd, interp_sect,
630 				buf, 0, interp_sect_size);
631 
632       /* Now we need to figure out where the dynamic linker was
633          loaded so that we can load its symbols and place a breakpoint
634          in the dynamic linker itself.
635 
636          This address is stored on the stack.  However, I've been unable
637          to find any magic formula to find it for Solaris (appears to
638          be trivial on GNU/Linux).  Therefore, we have to try an alternate
639          mechanism to find the dynamic linker's base address.  */
640 
641       tmp_fd  = solib_open (buf, &tmp_pathname);
642       if (tmp_fd >= 0)
643 	tmp_bfd = bfd_fdopenr (tmp_pathname, gnutarget, tmp_fd);
644 
645       if (tmp_bfd == NULL)
646 	{
647 	  enable_break_failure_warning ();
648 	  return 0;
649 	}
650 
651       /* Make sure the dynamic linker is really a useful object.  */
652       if (!bfd_check_format (tmp_bfd, bfd_object))
653 	{
654 	  warning ("Unable to grok dynamic linker %s as an object file", buf);
655 	  enable_break_failure_warning ();
656 	  bfd_close (tmp_bfd);
657 	  return 0;
658 	}
659 
660       status = frv_fdpic_loadmap_addresses (current_gdbarch,
661                                             &interp_loadmap_addr, 0);
662       if (status < 0)
663 	{
664 	  warning ("Unable to determine dynamic linker loadmap address\n");
665 	  enable_break_failure_warning ();
666 	  bfd_close (tmp_bfd);
667 	  return 0;
668 	}
669 
670       if (solib_frv_debug)
671 	fprintf_unfiltered (gdb_stdlog,
672 	                    "enable_break: interp_loadmap_addr = %s\n",
673 			    hex_string_custom (interp_loadmap_addr, 8));
674 
675       ldm = fetch_loadmap (interp_loadmap_addr);
676       if (ldm == NULL)
677 	{
678 	  warning ("Unable to load dynamic linker loadmap at address %s\n",
679 	           hex_string_custom (interp_loadmap_addr, 8));
680 	  enable_break_failure_warning ();
681 	  bfd_close (tmp_bfd);
682 	  return 0;
683 	}
684 
685       /* Record the relocated start and end address of the dynamic linker
686          text and plt section for svr4_in_dynsym_resolve_code.  */
687       interp_sect = bfd_get_section_by_name (tmp_bfd, ".text");
688       if (interp_sect)
689 	{
690 	  interp_text_sect_low
691 	    = bfd_section_vma (tmp_bfd, interp_sect);
692 	  interp_text_sect_low
693 	    += displacement_from_map (ldm, interp_text_sect_low);
694 	  interp_text_sect_high
695 	    = interp_text_sect_low + bfd_section_size (tmp_bfd, interp_sect);
696 	}
697       interp_sect = bfd_get_section_by_name (tmp_bfd, ".plt");
698       if (interp_sect)
699 	{
700 	  interp_plt_sect_low =
701 	    bfd_section_vma (tmp_bfd, interp_sect);
702 	  interp_plt_sect_low
703 	    += displacement_from_map (ldm, interp_plt_sect_low);
704 	  interp_plt_sect_high =
705 	    interp_plt_sect_low + bfd_section_size (tmp_bfd, interp_sect);
706 	}
707 
708       addr = bfd_lookup_symbol (tmp_bfd, "_dl_debug_addr");
709       if (addr == 0)
710 	{
711 	  warning ("Could not find symbol _dl_debug_addr in dynamic linker");
712 	  enable_break_failure_warning ();
713 	  bfd_close (tmp_bfd);
714 	  return 0;
715 	}
716 
717       if (solib_frv_debug)
718 	fprintf_unfiltered (gdb_stdlog,
719 	                    "enable_break: _dl_debug_addr (prior to relocation) = %s\n",
720 			    hex_string_custom (addr, 8));
721 
722       addr += displacement_from_map (ldm, addr);
723 
724       if (solib_frv_debug)
725 	fprintf_unfiltered (gdb_stdlog,
726 	                    "enable_break: _dl_debug_addr (after relocation) = %s\n",
727 			    hex_string_custom (addr, 8));
728 
729       /* Fetch the address of the r_debug struct.  */
730       if (target_read_memory (addr, addr_buf, sizeof addr_buf) != 0)
731 	{
732 	  warning ("Unable to fetch contents of _dl_debug_addr (at address %s) from dynamic linker",
733 	           hex_string_custom (addr, 8));
734 	}
735       addr = extract_unsigned_integer (addr_buf, sizeof addr_buf);
736 
737       /* Fetch the r_brk field.  It's 8 bytes from the start of
738          _dl_debug_addr.  */
739       if (target_read_memory (addr + 8, addr_buf, sizeof addr_buf) != 0)
740 	{
741 	  warning ("Unable to fetch _dl_debug_addr->r_brk (at address %s) from dynamic linker",
742 	           hex_string_custom (addr + 8, 8));
743 	  enable_break_failure_warning ();
744 	  bfd_close (tmp_bfd);
745 	  return 0;
746 	}
747       addr = extract_unsigned_integer (addr_buf, sizeof addr_buf);
748 
749       /* Now fetch the function entry point.  */
750       if (target_read_memory (addr, addr_buf, sizeof addr_buf) != 0)
751 	{
752 	  warning ("Unable to fetch _dl_debug_addr->.r_brk entry point (at address %s) from dynamic linker",
753 	           hex_string_custom (addr, 8));
754 	  enable_break_failure_warning ();
755 	  bfd_close (tmp_bfd);
756 	  return 0;
757 	}
758       addr = extract_unsigned_integer (addr_buf, sizeof addr_buf);
759 
760       /* We're done with the temporary bfd.  */
761       bfd_close (tmp_bfd);
762 
763       /* We're also done with the loadmap.  */
764       xfree (ldm);
765 
766       /* Now (finally!) create the solib breakpoint.  */
767       create_solib_event_breakpoint (addr);
768 
769       return 1;
770     }
771 
772   /* Tell the user we couldn't set a dynamic linker breakpoint.  */
773   enable_break_failure_warning ();
774 
775   /* Failure return.  */
776   return 0;
777 }
778 
779 static int
enable_break(void)780 enable_break (void)
781 {
782   asection *interp_sect;
783 
784   /* Remove all the solib event breakpoints.  Their addresses
785      may have changed since the last time we ran the program.  */
786   remove_solib_event_breakpoints ();
787 
788   /* Check for the presence of a .interp section.  If there is no
789      such section, the executable is statically linked.  */
790 
791   interp_sect = bfd_get_section_by_name (exec_bfd, ".interp");
792 
793   if (interp_sect)
794     {
795       enable_break1_done = 1;
796       create_solib_event_breakpoint (symfile_objfile->ei.entry_point);
797 
798       if (solib_frv_debug)
799 	fprintf_unfiltered (gdb_stdlog,
800 			    "enable_break: solib event breakpoint placed at entry point: %s\n",
801 			    hex_string_custom
802 			      (symfile_objfile->ei.entry_point, 8));
803     }
804   else
805     {
806       if (solib_frv_debug)
807 	fprintf_unfiltered (gdb_stdlog,
808 	                    "enable_break: No .interp section found.\n");
809     }
810 
811   return 1;
812 }
813 
814 /*
815 
816    LOCAL FUNCTION
817 
818    special_symbol_handling -- additional shared library symbol handling
819 
820    SYNOPSIS
821 
822    void special_symbol_handling ()
823 
824    DESCRIPTION
825 
826    Once the symbols from a shared object have been loaded in the usual
827    way, we are called to do any system specific symbol handling that
828    is needed.
829 
830  */
831 
832 static void
frv_special_symbol_handling(void)833 frv_special_symbol_handling (void)
834 {
835   /* Nothing needed (yet) for FRV. */
836 }
837 
838 static void
frv_relocate_main_executable(void)839 frv_relocate_main_executable (void)
840 {
841   int status;
842   CORE_ADDR exec_addr;
843   struct int_elf32_fdpic_loadmap *ldm;
844   struct cleanup *old_chain;
845   struct section_offsets *new_offsets;
846   int changed;
847   struct obj_section *osect;
848 
849   status = frv_fdpic_loadmap_addresses (current_gdbarch, 0, &exec_addr);
850 
851   if (status < 0)
852     {
853       /* Not using FDPIC ABI, so do nothing.  */
854       return;
855     }
856 
857   /* Fetch the loadmap located at ``exec_addr''.  */
858   ldm = fetch_loadmap (exec_addr);
859   if (ldm == NULL)
860     error ("Unable to load the executable's loadmap.");
861 
862   if (main_executable_lm_info)
863     xfree (main_executable_lm_info);
864   main_executable_lm_info = xcalloc (1, sizeof (struct lm_info));
865   main_executable_lm_info->map = ldm;
866 
867   new_offsets = xcalloc (symfile_objfile->num_sections,
868 			 sizeof (struct section_offsets));
869   old_chain = make_cleanup (xfree, new_offsets);
870   changed = 0;
871 
872   ALL_OBJFILE_OSECTIONS (symfile_objfile, osect)
873     {
874       CORE_ADDR orig_addr, addr, offset;
875       int osect_idx;
876       int seg;
877 
878       osect_idx = osect->the_bfd_section->index;
879 
880       /* Current address of section.  */
881       addr = osect->addr;
882       /* Offset from where this section started.  */
883       offset = ANOFFSET (symfile_objfile->section_offsets, osect_idx);
884       /* Original address prior to any past relocations.  */
885       orig_addr = addr - offset;
886 
887       for (seg = 0; seg < ldm->nsegs; seg++)
888 	{
889 	  if (ldm->segs[seg].p_vaddr <= orig_addr
890 	      && orig_addr < ldm->segs[seg].p_vaddr + ldm->segs[seg].p_memsz)
891 	    {
892 	      new_offsets->offsets[osect_idx]
893 		= ldm->segs[seg].addr - ldm->segs[seg].p_vaddr;
894 
895 	      if (new_offsets->offsets[osect_idx] != offset)
896 		changed = 1;
897 	      break;
898 	    }
899 	}
900     }
901 
902   if (changed)
903     objfile_relocate (symfile_objfile, new_offsets);
904 
905   do_cleanups (old_chain);
906 
907   /* Now that symfile_objfile has been relocated, we can compute the
908      GOT value and stash it away.  */
909   main_executable_lm_info->got_value = main_got ();
910 }
911 
912 /*
913 
914    GLOBAL FUNCTION
915 
916    frv_solib_create_inferior_hook -- shared library startup support
917 
918    SYNOPSIS
919 
920    void frv_solib_create_inferior_hook()
921 
922    DESCRIPTION
923 
924    When gdb starts up the inferior, it nurses it along (through the
925    shell) until it is ready to execute it's first instruction.  At this
926    point, this function gets called via expansion of the macro
927    SOLIB_CREATE_INFERIOR_HOOK.
928 
929    For the FR-V shared library ABI (FDPIC), the main executable
930    needs to be relocated.  The shared library breakpoints also need
931    to be enabled.
932  */
933 
934 static void
frv_solib_create_inferior_hook(void)935 frv_solib_create_inferior_hook (void)
936 {
937   /* Relocate main executable.  */
938   frv_relocate_main_executable ();
939 
940   /* Enable shared library breakpoints.  */
941   if (!enable_break ())
942     {
943       warning ("shared library handler failed to enable breakpoint");
944       return;
945     }
946 }
947 
948 static void
frv_clear_solib(void)949 frv_clear_solib (void)
950 {
951   lm_base_cache = 0;
952   enable_break1_done = 0;
953   enable_break2_done = 0;
954 }
955 
956 static void
frv_free_so(struct so_list * so)957 frv_free_so (struct so_list *so)
958 {
959   xfree (so->lm_info->map);
960   xfree (so->lm_info->dyn_syms);
961   xfree (so->lm_info->dyn_relocs);
962   xfree (so->lm_info);
963 }
964 
965 static void
frv_relocate_section_addresses(struct so_list * so,struct section_table * sec)966 frv_relocate_section_addresses (struct so_list *so,
967                                  struct section_table *sec)
968 {
969   int seg;
970   struct int_elf32_fdpic_loadmap *map;
971 
972   map = so->lm_info->map;
973 
974   for (seg = 0; seg < map->nsegs; seg++)
975     {
976       if (map->segs[seg].p_vaddr <= sec->addr
977           && sec->addr < map->segs[seg].p_vaddr + map->segs[seg].p_memsz)
978 	{
979 	  CORE_ADDR displ = map->segs[seg].addr - map->segs[seg].p_vaddr;
980 	  sec->addr += displ;
981 	  sec->endaddr += displ;
982 	  break;
983 	}
984     }
985 }
986 
987 /* Return the GOT address associated with the main executable.  Return
988    0 if it can't be found.  */
989 
990 static CORE_ADDR
main_got(void)991 main_got (void)
992 {
993   struct minimal_symbol *got_sym;
994 
995   got_sym = lookup_minimal_symbol ("_GLOBAL_OFFSET_TABLE_", NULL, symfile_objfile);
996   if (got_sym == 0)
997     return 0;
998 
999   return SYMBOL_VALUE_ADDRESS (got_sym);
1000 }
1001 
1002 /* Find the global pointer for the given function address ADDR.  */
1003 
1004 CORE_ADDR
frv_fdpic_find_global_pointer(CORE_ADDR addr)1005 frv_fdpic_find_global_pointer (CORE_ADDR addr)
1006 {
1007   struct so_list *so;
1008 
1009   so = master_so_list ();
1010   while (so)
1011     {
1012       int seg;
1013       struct int_elf32_fdpic_loadmap *map;
1014 
1015       map = so->lm_info->map;
1016 
1017       for (seg = 0; seg < map->nsegs; seg++)
1018 	{
1019 	  if (map->segs[seg].addr <= addr
1020 	      && addr < map->segs[seg].addr + map->segs[seg].p_memsz)
1021 	    return so->lm_info->got_value;
1022 	}
1023 
1024       so = so->next;
1025     }
1026 
1027   /* Didn't find it it any of the shared objects.  So assume it's in the
1028      main executable.  */
1029   return main_got ();
1030 }
1031 
1032 /* Forward declarations for frv_fdpic_find_canonical_descriptor().  */
1033 static CORE_ADDR find_canonical_descriptor_in_load_object
1034   (CORE_ADDR, CORE_ADDR, char *, bfd *, struct lm_info *);
1035 
1036 /* Given a function entry point, attempt to find the canonical descriptor
1037    associated with that entry point.  Return 0 if no canonical descriptor
1038    could be found.  */
1039 
1040 CORE_ADDR
frv_fdpic_find_canonical_descriptor(CORE_ADDR entry_point)1041 frv_fdpic_find_canonical_descriptor (CORE_ADDR entry_point)
1042 {
1043   char *name;
1044   CORE_ADDR addr;
1045   CORE_ADDR got_value;
1046   struct int_elf32_fdpic_loadmap *ldm = 0;
1047   struct symbol *sym;
1048   int status;
1049   CORE_ADDR exec_loadmap_addr;
1050 
1051   /* Fetch the corresponding global pointer for the entry point.  */
1052   got_value = frv_fdpic_find_global_pointer (entry_point);
1053 
1054   /* Attempt to find the name of the function.  If the name is available,
1055      it'll be used as an aid in finding matching functions in the dynamic
1056      symbol table.  */
1057   sym = find_pc_function (entry_point);
1058   if (sym == 0)
1059     name = 0;
1060   else
1061     name = SYMBOL_LINKAGE_NAME (sym);
1062 
1063   /* Check the main executable.  */
1064   addr = find_canonical_descriptor_in_load_object
1065            (entry_point, got_value, name, symfile_objfile->obfd,
1066 	    main_executable_lm_info);
1067 
1068   /* If descriptor not found via main executable, check each load object
1069      in list of shared objects.  */
1070   if (addr == 0)
1071     {
1072       struct so_list *so;
1073 
1074       so = master_so_list ();
1075       while (so)
1076 	{
1077 	  addr = find_canonical_descriptor_in_load_object
1078 		   (entry_point, got_value, name, so->abfd, so->lm_info);
1079 
1080 	  if (addr != 0)
1081 	    break;
1082 
1083 	  so = so->next;
1084 	}
1085     }
1086 
1087   return addr;
1088 }
1089 
1090 static CORE_ADDR
find_canonical_descriptor_in_load_object(CORE_ADDR entry_point,CORE_ADDR got_value,char * name,bfd * abfd,struct lm_info * lm)1091 find_canonical_descriptor_in_load_object
1092   (CORE_ADDR entry_point, CORE_ADDR got_value, char *name, bfd *abfd,
1093    struct lm_info *lm)
1094 {
1095   arelent *rel;
1096   unsigned int i;
1097   CORE_ADDR addr = 0;
1098 
1099   /* Nothing to do if no bfd.  */
1100   if (abfd == 0)
1101     return 0;
1102 
1103   /* We want to scan the dynamic relocs for R_FRV_FUNCDESC relocations.
1104      (More about this later.)  But in order to fetch the relocs, we
1105      need to first fetch the dynamic symbols.  These symbols need to
1106      be cached due to the way that bfd_canonicalize_dynamic_reloc()
1107      works.  (See the comments in the declaration of struct lm_info
1108      for more information.)  */
1109   if (lm->dyn_syms == NULL)
1110     {
1111       long storage_needed;
1112       unsigned int number_of_symbols;
1113 
1114       /* Determine amount of space needed to hold the dynamic symbol table.  */
1115       storage_needed = bfd_get_dynamic_symtab_upper_bound (abfd);
1116 
1117       /* If there are no dynamic symbols, there's nothing to do.  */
1118       if (storage_needed <= 0)
1119 	return 0;
1120 
1121       /* Allocate space for the dynamic symbol table.  */
1122       lm->dyn_syms = (asymbol **) xmalloc (storage_needed);
1123 
1124       /* Fetch the dynamic symbol table.  */
1125       number_of_symbols = bfd_canonicalize_dynamic_symtab (abfd, lm->dyn_syms);
1126 
1127       if (number_of_symbols == 0)
1128 	return 0;
1129     }
1130 
1131   /* Fetch the dynamic relocations if not already cached.  */
1132   if (lm->dyn_relocs == NULL)
1133     {
1134       long storage_needed;
1135 
1136       /* Determine amount of space needed to hold the dynamic relocs.  */
1137       storage_needed = bfd_get_dynamic_reloc_upper_bound (abfd);
1138 
1139       /* Bail out if there are no dynamic relocs.  */
1140       if (storage_needed <= 0)
1141 	return 0;
1142 
1143       /* Allocate space for the relocs.  */
1144       lm->dyn_relocs = (arelent **) xmalloc (storage_needed);
1145 
1146       /* Fetch the dynamic relocs.  */
1147       lm->dyn_reloc_count
1148 	= bfd_canonicalize_dynamic_reloc (abfd, lm->dyn_relocs, lm->dyn_syms);
1149     }
1150 
1151   /* Search the dynamic relocs.  */
1152   for (i = 0; i < lm->dyn_reloc_count; i++)
1153     {
1154       rel = lm->dyn_relocs[i];
1155 
1156       /* Relocs of interest are those which meet the following
1157          criteria:
1158 
1159 	   - the names match (assuming the caller could provide
1160 	     a name which matches ``entry_point'').
1161 	   - the relocation type must be R_FRV_FUNCDESC.  Relocs
1162 	     of this type are used (by the dynamic linker) to
1163 	     look up the address of a canonical descriptor (allocating
1164 	     it if need be) and initializing the GOT entry referred
1165 	     to by the offset to the address of the descriptor.
1166 
1167 	 These relocs of interest may be used to obtain a
1168 	 candidate descriptor by first adjusting the reloc's
1169 	 address according to the link map and then dereferencing
1170 	 this address (which is a GOT entry) to obtain a descriptor
1171 	 address.  */
1172       if ((name == 0 || strcmp (name, (*rel->sym_ptr_ptr)->name) == 0)
1173           && rel->howto->type == R_FRV_FUNCDESC)
1174 	{
1175 	  char buf[FRV_PTR_SIZE];
1176 
1177 	  /* Compute address of address of candidate descriptor.  */
1178 	  addr = rel->address + displacement_from_map (lm->map, rel->address);
1179 
1180 	  /* Fetch address of candidate descriptor.  */
1181 	  if (target_read_memory (addr, buf, sizeof buf) != 0)
1182 	    continue;
1183 	  addr = extract_unsigned_integer (buf, sizeof buf);
1184 
1185 	  /* Check for matching entry point.  */
1186 	  if (target_read_memory (addr, buf, sizeof buf) != 0)
1187 	    continue;
1188 	  if (extract_unsigned_integer (buf, sizeof buf) != entry_point)
1189 	    continue;
1190 
1191 	  /* Check for matching got value.  */
1192 	  if (target_read_memory (addr + 4, buf, sizeof buf) != 0)
1193 	    continue;
1194 	  if (extract_unsigned_integer (buf, sizeof buf) != got_value)
1195 	    continue;
1196 
1197 	  /* Match was successful!  Exit loop.  */
1198 	  break;
1199 	}
1200     }
1201 
1202   return addr;
1203 }
1204 
1205 static struct target_so_ops frv_so_ops;
1206 
1207 void
_initialize_frv_solib(void)1208 _initialize_frv_solib (void)
1209 {
1210   frv_so_ops.relocate_section_addresses = frv_relocate_section_addresses;
1211   frv_so_ops.free_so = frv_free_so;
1212   frv_so_ops.clear_solib = frv_clear_solib;
1213   frv_so_ops.solib_create_inferior_hook = frv_solib_create_inferior_hook;
1214   frv_so_ops.special_symbol_handling = frv_special_symbol_handling;
1215   frv_so_ops.current_sos = frv_current_sos;
1216   frv_so_ops.open_symbol_file_object = open_symbol_file_object;
1217   frv_so_ops.in_dynsym_resolve_code = frv_in_dynsym_resolve_code;
1218 
1219   /* FIXME: Don't do this here.  *_gdbarch_init() should set so_ops. */
1220   current_target_so_ops = &frv_so_ops;
1221 
1222   /* Debug this file's internals.  */
1223   deprecated_add_show_from_set
1224     (add_set_cmd ("solib-frv", class_maintenance, var_zinteger,
1225 		  &solib_frv_debug,
1226 "Set internal debugging of shared library code for FR-V.\n"
1227 "When non-zero, FR-V solib specific internal debugging is enabled.",
1228 		  &setdebuglist),
1229      &showdebuglist);
1230 }
1231