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