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