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