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