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