GDB (API)
|
00001 /* Handle FR-V (FDPIC) shared libraries for GDB, the GNU Debugger. 00002 Copyright (C) 2004-2013 Free Software Foundation, Inc. 00003 00004 This file is part of GDB. 00005 00006 This program is free software; you can redistribute it and/or modify 00007 it under the terms of the GNU General Public License as published by 00008 the Free Software Foundation; either version 3 of the License, or 00009 (at your option) any later version. 00010 00011 This program is distributed in the hope that it will be useful, 00012 but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 GNU General Public License for more details. 00015 00016 You should have received a copy of the GNU General Public License 00017 along with this program. If not, see <http://www.gnu.org/licenses/>. */ 00018 00019 00020 #include "defs.h" 00021 #include "gdb_string.h" 00022 #include "inferior.h" 00023 #include "gdbcore.h" 00024 #include "solib.h" 00025 #include "solist.h" 00026 #include "frv-tdep.h" 00027 #include "objfiles.h" 00028 #include "symtab.h" 00029 #include "language.h" 00030 #include "command.h" 00031 #include "gdbcmd.h" 00032 #include "elf/frv.h" 00033 #include "exceptions.h" 00034 #include "gdb_bfd.h" 00035 00036 /* Flag which indicates whether internal debug messages should be printed. */ 00037 static unsigned int solib_frv_debug; 00038 00039 /* FR-V pointers are four bytes wide. */ 00040 enum { FRV_PTR_SIZE = 4 }; 00041 00042 /* Representation of loadmap and related structs for the FR-V FDPIC ABI. */ 00043 00044 /* External versions; the size and alignment of the fields should be 00045 the same as those on the target. When loaded, the placement of 00046 the bits in each field will be the same as on the target. */ 00047 typedef gdb_byte ext_Elf32_Half[2]; 00048 typedef gdb_byte ext_Elf32_Addr[4]; 00049 typedef gdb_byte ext_Elf32_Word[4]; 00050 00051 struct ext_elf32_fdpic_loadseg 00052 { 00053 /* Core address to which the segment is mapped. */ 00054 ext_Elf32_Addr addr; 00055 /* VMA recorded in the program header. */ 00056 ext_Elf32_Addr p_vaddr; 00057 /* Size of this segment in memory. */ 00058 ext_Elf32_Word p_memsz; 00059 }; 00060 00061 struct ext_elf32_fdpic_loadmap { 00062 /* Protocol version number, must be zero. */ 00063 ext_Elf32_Half version; 00064 /* Number of segments in this map. */ 00065 ext_Elf32_Half nsegs; 00066 /* The actual memory map. */ 00067 struct ext_elf32_fdpic_loadseg segs[1 /* nsegs, actually */]; 00068 }; 00069 00070 /* Internal versions; the types are GDB types and the data in each 00071 of the fields is (or will be) decoded from the external struct 00072 for ease of consumption. */ 00073 struct int_elf32_fdpic_loadseg 00074 { 00075 /* Core address to which the segment is mapped. */ 00076 CORE_ADDR addr; 00077 /* VMA recorded in the program header. */ 00078 CORE_ADDR p_vaddr; 00079 /* Size of this segment in memory. */ 00080 long p_memsz; 00081 }; 00082 00083 struct int_elf32_fdpic_loadmap { 00084 /* Protocol version number, must be zero. */ 00085 int version; 00086 /* Number of segments in this map. */ 00087 int nsegs; 00088 /* The actual memory map. */ 00089 struct int_elf32_fdpic_loadseg segs[1 /* nsegs, actually */]; 00090 }; 00091 00092 /* Given address LDMADDR, fetch and decode the loadmap at that address. 00093 Return NULL if there is a problem reading the target memory or if 00094 there doesn't appear to be a loadmap at the given address. The 00095 allocated space (representing the loadmap) returned by this 00096 function may be freed via a single call to xfree(). */ 00097 00098 static struct int_elf32_fdpic_loadmap * 00099 fetch_loadmap (CORE_ADDR ldmaddr) 00100 { 00101 enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch ()); 00102 struct ext_elf32_fdpic_loadmap ext_ldmbuf_partial; 00103 struct ext_elf32_fdpic_loadmap *ext_ldmbuf; 00104 struct int_elf32_fdpic_loadmap *int_ldmbuf; 00105 int ext_ldmbuf_size, int_ldmbuf_size; 00106 int version, seg, nsegs; 00107 00108 /* Fetch initial portion of the loadmap. */ 00109 if (target_read_memory (ldmaddr, (gdb_byte *) &ext_ldmbuf_partial, 00110 sizeof ext_ldmbuf_partial)) 00111 { 00112 /* Problem reading the target's memory. */ 00113 return NULL; 00114 } 00115 00116 /* Extract the version. */ 00117 version = extract_unsigned_integer (ext_ldmbuf_partial.version, 00118 sizeof ext_ldmbuf_partial.version, 00119 byte_order); 00120 if (version != 0) 00121 { 00122 /* We only handle version 0. */ 00123 return NULL; 00124 } 00125 00126 /* Extract the number of segments. */ 00127 nsegs = extract_unsigned_integer (ext_ldmbuf_partial.nsegs, 00128 sizeof ext_ldmbuf_partial.nsegs, 00129 byte_order); 00130 00131 if (nsegs <= 0) 00132 return NULL; 00133 00134 /* Allocate space for the complete (external) loadmap. */ 00135 ext_ldmbuf_size = sizeof (struct ext_elf32_fdpic_loadmap) 00136 + (nsegs - 1) * sizeof (struct ext_elf32_fdpic_loadseg); 00137 ext_ldmbuf = xmalloc (ext_ldmbuf_size); 00138 00139 /* Copy over the portion of the loadmap that's already been read. */ 00140 memcpy (ext_ldmbuf, &ext_ldmbuf_partial, sizeof ext_ldmbuf_partial); 00141 00142 /* Read the rest of the loadmap from the target. */ 00143 if (target_read_memory (ldmaddr + sizeof ext_ldmbuf_partial, 00144 (gdb_byte *) ext_ldmbuf + sizeof ext_ldmbuf_partial, 00145 ext_ldmbuf_size - sizeof ext_ldmbuf_partial)) 00146 { 00147 /* Couldn't read rest of the loadmap. */ 00148 xfree (ext_ldmbuf); 00149 return NULL; 00150 } 00151 00152 /* Allocate space into which to put information extract from the 00153 external loadsegs. I.e, allocate the internal loadsegs. */ 00154 int_ldmbuf_size = sizeof (struct int_elf32_fdpic_loadmap) 00155 + (nsegs - 1) * sizeof (struct int_elf32_fdpic_loadseg); 00156 int_ldmbuf = xmalloc (int_ldmbuf_size); 00157 00158 /* Place extracted information in internal structs. */ 00159 int_ldmbuf->version = version; 00160 int_ldmbuf->nsegs = nsegs; 00161 for (seg = 0; seg < nsegs; seg++) 00162 { 00163 int_ldmbuf->segs[seg].addr 00164 = extract_unsigned_integer (ext_ldmbuf->segs[seg].addr, 00165 sizeof (ext_ldmbuf->segs[seg].addr), 00166 byte_order); 00167 int_ldmbuf->segs[seg].p_vaddr 00168 = extract_unsigned_integer (ext_ldmbuf->segs[seg].p_vaddr, 00169 sizeof (ext_ldmbuf->segs[seg].p_vaddr), 00170 byte_order); 00171 int_ldmbuf->segs[seg].p_memsz 00172 = extract_unsigned_integer (ext_ldmbuf->segs[seg].p_memsz, 00173 sizeof (ext_ldmbuf->segs[seg].p_memsz), 00174 byte_order); 00175 } 00176 00177 xfree (ext_ldmbuf); 00178 return int_ldmbuf; 00179 } 00180 00181 /* External link_map and elf32_fdpic_loadaddr struct definitions. */ 00182 00183 typedef gdb_byte ext_ptr[4]; 00184 00185 struct ext_elf32_fdpic_loadaddr 00186 { 00187 ext_ptr map; /* struct elf32_fdpic_loadmap *map; */ 00188 ext_ptr got_value; /* void *got_value; */ 00189 }; 00190 00191 struct ext_link_map 00192 { 00193 struct ext_elf32_fdpic_loadaddr l_addr; 00194 00195 /* Absolute file name object was found in. */ 00196 ext_ptr l_name; /* char *l_name; */ 00197 00198 /* Dynamic section of the shared object. */ 00199 ext_ptr l_ld; /* ElfW(Dyn) *l_ld; */ 00200 00201 /* Chain of loaded objects. */ 00202 ext_ptr l_next, l_prev; /* struct link_map *l_next, *l_prev; */ 00203 }; 00204 00205 /* Link map info to include in an allocated so_list entry. */ 00206 00207 struct lm_info 00208 { 00209 /* The loadmap, digested into an easier to use form. */ 00210 struct int_elf32_fdpic_loadmap *map; 00211 /* The GOT address for this link map entry. */ 00212 CORE_ADDR got_value; 00213 /* The link map address, needed for frv_fetch_objfile_link_map(). */ 00214 CORE_ADDR lm_addr; 00215 00216 /* Cached dynamic symbol table and dynamic relocs initialized and 00217 used only by find_canonical_descriptor_in_load_object(). 00218 00219 Note: kevinb/2004-02-26: It appears that calls to 00220 bfd_canonicalize_dynamic_reloc() will use the same symbols as 00221 those supplied to the first call to this function. Therefore, 00222 it's important to NOT free the asymbol ** data structure 00223 supplied to the first call. Thus the caching of the dynamic 00224 symbols (dyn_syms) is critical for correct operation. The 00225 caching of the dynamic relocations could be dispensed with. */ 00226 asymbol **dyn_syms; 00227 arelent **dyn_relocs; 00228 int dyn_reloc_count; /* Number of dynamic relocs. */ 00229 00230 }; 00231 00232 /* The load map, got value, etc. are not available from the chain 00233 of loaded shared objects. ``main_executable_lm_info'' provides 00234 a way to get at this information so that it doesn't need to be 00235 frequently recomputed. Initialized by frv_relocate_main_executable(). */ 00236 static struct lm_info *main_executable_lm_info; 00237 00238 static void frv_relocate_main_executable (void); 00239 static CORE_ADDR main_got (void); 00240 static int enable_break2 (void); 00241 00242 /* Implement the "open_symbol_file_object" target_so_ops method. */ 00243 00244 static int 00245 open_symbol_file_object (void *from_ttyp) 00246 { 00247 /* Unimplemented. */ 00248 return 0; 00249 } 00250 00251 /* Cached value for lm_base(), below. */ 00252 static CORE_ADDR lm_base_cache = 0; 00253 00254 /* Link map address for main module. */ 00255 static CORE_ADDR main_lm_addr = 0; 00256 00257 /* Return the address from which the link map chain may be found. On 00258 the FR-V, this may be found in a number of ways. Assuming that the 00259 main executable has already been relocated, the easiest way to find 00260 this value is to look up the address of _GLOBAL_OFFSET_TABLE_. A 00261 pointer to the start of the link map will be located at the word found 00262 at _GLOBAL_OFFSET_TABLE_ + 8. (This is part of the dynamic linker 00263 reserve area mandated by the ABI.) */ 00264 00265 static CORE_ADDR 00266 lm_base (void) 00267 { 00268 enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch ()); 00269 struct minimal_symbol *got_sym; 00270 CORE_ADDR addr; 00271 gdb_byte buf[FRV_PTR_SIZE]; 00272 00273 /* One of our assumptions is that the main executable has been relocated. 00274 Bail out if this has not happened. (Note that post_create_inferior() 00275 in infcmd.c will call solib_add prior to solib_create_inferior_hook(). 00276 If we allow this to happen, lm_base_cache will be initialized with 00277 a bogus value. */ 00278 if (main_executable_lm_info == 0) 00279 return 0; 00280 00281 /* If we already have a cached value, return it. */ 00282 if (lm_base_cache) 00283 return lm_base_cache; 00284 00285 got_sym = lookup_minimal_symbol ("_GLOBAL_OFFSET_TABLE_", NULL, 00286 symfile_objfile); 00287 if (got_sym == 0) 00288 { 00289 if (solib_frv_debug) 00290 fprintf_unfiltered (gdb_stdlog, 00291 "lm_base: _GLOBAL_OFFSET_TABLE_ not found.\n"); 00292 return 0; 00293 } 00294 00295 addr = SYMBOL_VALUE_ADDRESS (got_sym) + 8; 00296 00297 if (solib_frv_debug) 00298 fprintf_unfiltered (gdb_stdlog, 00299 "lm_base: _GLOBAL_OFFSET_TABLE_ + 8 = %s\n", 00300 hex_string_custom (addr, 8)); 00301 00302 if (target_read_memory (addr, buf, sizeof buf) != 0) 00303 return 0; 00304 lm_base_cache = extract_unsigned_integer (buf, sizeof buf, byte_order); 00305 00306 if (solib_frv_debug) 00307 fprintf_unfiltered (gdb_stdlog, 00308 "lm_base: lm_base_cache = %s\n", 00309 hex_string_custom (lm_base_cache, 8)); 00310 00311 return lm_base_cache; 00312 } 00313 00314 00315 /* Implement the "current_sos" target_so_ops method. */ 00316 00317 static struct so_list * 00318 frv_current_sos (void) 00319 { 00320 enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch ()); 00321 CORE_ADDR lm_addr, mgot; 00322 struct so_list *sos_head = NULL; 00323 struct so_list **sos_next_ptr = &sos_head; 00324 00325 /* Make sure that the main executable has been relocated. This is 00326 required in order to find the address of the global offset table, 00327 which in turn is used to find the link map info. (See lm_base() 00328 for details.) 00329 00330 Note that the relocation of the main executable is also performed 00331 by solib_create_inferior_hook(), however, in the case of core 00332 files, this hook is called too late in order to be of benefit to 00333 solib_add. solib_add eventually calls this this function, 00334 frv_current_sos, and also precedes the call to 00335 solib_create_inferior_hook(). (See post_create_inferior() in 00336 infcmd.c.) */ 00337 if (main_executable_lm_info == 0 && core_bfd != NULL) 00338 frv_relocate_main_executable (); 00339 00340 /* Fetch the GOT corresponding to the main executable. */ 00341 mgot = main_got (); 00342 00343 /* Locate the address of the first link map struct. */ 00344 lm_addr = lm_base (); 00345 00346 /* We have at least one link map entry. Fetch the lot of them, 00347 building the solist chain. */ 00348 while (lm_addr) 00349 { 00350 struct ext_link_map lm_buf; 00351 CORE_ADDR got_addr; 00352 00353 if (solib_frv_debug) 00354 fprintf_unfiltered (gdb_stdlog, 00355 "current_sos: reading link_map entry at %s\n", 00356 hex_string_custom (lm_addr, 8)); 00357 00358 if (target_read_memory (lm_addr, (gdb_byte *) &lm_buf, 00359 sizeof (lm_buf)) != 0) 00360 { 00361 warning (_("frv_current_sos: Unable to read link map entry. " 00362 "Shared object chain may be incomplete.")); 00363 break; 00364 } 00365 00366 got_addr 00367 = extract_unsigned_integer (lm_buf.l_addr.got_value, 00368 sizeof (lm_buf.l_addr.got_value), 00369 byte_order); 00370 /* If the got_addr is the same as mgotr, then we're looking at the 00371 entry for the main executable. By convention, we don't include 00372 this in the list of shared objects. */ 00373 if (got_addr != mgot) 00374 { 00375 int errcode; 00376 char *name_buf; 00377 struct int_elf32_fdpic_loadmap *loadmap; 00378 struct so_list *sop; 00379 CORE_ADDR addr; 00380 00381 /* Fetch the load map address. */ 00382 addr = extract_unsigned_integer (lm_buf.l_addr.map, 00383 sizeof lm_buf.l_addr.map, 00384 byte_order); 00385 loadmap = fetch_loadmap (addr); 00386 if (loadmap == NULL) 00387 { 00388 warning (_("frv_current_sos: Unable to fetch load map. " 00389 "Shared object chain may be incomplete.")); 00390 break; 00391 } 00392 00393 sop = xcalloc (1, sizeof (struct so_list)); 00394 sop->lm_info = xcalloc (1, sizeof (struct lm_info)); 00395 sop->lm_info->map = loadmap; 00396 sop->lm_info->got_value = got_addr; 00397 sop->lm_info->lm_addr = lm_addr; 00398 /* Fetch the name. */ 00399 addr = extract_unsigned_integer (lm_buf.l_name, 00400 sizeof (lm_buf.l_name), 00401 byte_order); 00402 target_read_string (addr, &name_buf, SO_NAME_MAX_PATH_SIZE - 1, 00403 &errcode); 00404 00405 if (solib_frv_debug) 00406 fprintf_unfiltered (gdb_stdlog, "current_sos: name = %s\n", 00407 name_buf); 00408 00409 if (errcode != 0) 00410 warning (_("Can't read pathname for link map entry: %s."), 00411 safe_strerror (errcode)); 00412 else 00413 { 00414 strncpy (sop->so_name, name_buf, SO_NAME_MAX_PATH_SIZE - 1); 00415 sop->so_name[SO_NAME_MAX_PATH_SIZE - 1] = '\0'; 00416 xfree (name_buf); 00417 strcpy (sop->so_original_name, sop->so_name); 00418 } 00419 00420 *sos_next_ptr = sop; 00421 sos_next_ptr = &sop->next; 00422 } 00423 else 00424 { 00425 main_lm_addr = lm_addr; 00426 } 00427 00428 lm_addr = extract_unsigned_integer (lm_buf.l_next, 00429 sizeof (lm_buf.l_next), byte_order); 00430 } 00431 00432 enable_break2 (); 00433 00434 return sos_head; 00435 } 00436 00437 00438 /* Return 1 if PC lies in the dynamic symbol resolution code of the 00439 run time loader. */ 00440 00441 static CORE_ADDR interp_text_sect_low; 00442 static CORE_ADDR interp_text_sect_high; 00443 static CORE_ADDR interp_plt_sect_low; 00444 static CORE_ADDR interp_plt_sect_high; 00445 00446 static int 00447 frv_in_dynsym_resolve_code (CORE_ADDR pc) 00448 { 00449 return ((pc >= interp_text_sect_low && pc < interp_text_sect_high) 00450 || (pc >= interp_plt_sect_low && pc < interp_plt_sect_high) 00451 || in_plt_section (pc)); 00452 } 00453 00454 /* Given a loadmap and an address, return the displacement needed 00455 to relocate the address. */ 00456 00457 static CORE_ADDR 00458 displacement_from_map (struct int_elf32_fdpic_loadmap *map, 00459 CORE_ADDR addr) 00460 { 00461 int seg; 00462 00463 for (seg = 0; seg < map->nsegs; seg++) 00464 { 00465 if (map->segs[seg].p_vaddr <= addr 00466 && addr < map->segs[seg].p_vaddr + map->segs[seg].p_memsz) 00467 { 00468 return map->segs[seg].addr - map->segs[seg].p_vaddr; 00469 } 00470 } 00471 00472 return 0; 00473 } 00474 00475 /* Print a warning about being unable to set the dynamic linker 00476 breakpoint. */ 00477 00478 static void 00479 enable_break_failure_warning (void) 00480 { 00481 warning (_("Unable to find dynamic linker breakpoint function.\n" 00482 "GDB will be unable to debug shared library initializers\n" 00483 "and track explicitly loaded dynamic code.")); 00484 } 00485 00486 /* Helper function for gdb_bfd_lookup_symbol. */ 00487 00488 static int 00489 cmp_name (asymbol *sym, void *data) 00490 { 00491 return (strcmp (sym->name, (const char *) data) == 0); 00492 } 00493 00494 /* Arrange for dynamic linker to hit breakpoint. 00495 00496 The dynamic linkers has, as part of its debugger interface, support 00497 for arranging for the inferior to hit a breakpoint after mapping in 00498 the shared libraries. This function enables that breakpoint. 00499 00500 On the FR-V, using the shared library (FDPIC) ABI, the symbol 00501 _dl_debug_addr points to the r_debug struct which contains 00502 a field called r_brk. r_brk is the address of the function 00503 descriptor upon which a breakpoint must be placed. Being a 00504 function descriptor, we must extract the entry point in order 00505 to set the breakpoint. 00506 00507 Our strategy will be to get the .interp section from the 00508 executable. This section will provide us with the name of the 00509 interpreter. We'll open the interpreter and then look up 00510 the address of _dl_debug_addr. We then relocate this address 00511 using the interpreter's loadmap. Once the relocated address 00512 is known, we fetch the value (address) corresponding to r_brk 00513 and then use that value to fetch the entry point of the function 00514 we're interested in. */ 00515 00516 static int enable_break2_done = 0; 00517 00518 static int 00519 enable_break2 (void) 00520 { 00521 enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch ()); 00522 int success = 0; 00523 char **bkpt_namep; 00524 asection *interp_sect; 00525 00526 if (enable_break2_done) 00527 return 1; 00528 00529 interp_text_sect_low = interp_text_sect_high = 0; 00530 interp_plt_sect_low = interp_plt_sect_high = 0; 00531 00532 /* Find the .interp section; if not found, warn the user and drop 00533 into the old breakpoint at symbol code. */ 00534 interp_sect = bfd_get_section_by_name (exec_bfd, ".interp"); 00535 if (interp_sect) 00536 { 00537 unsigned int interp_sect_size; 00538 char *buf; 00539 bfd *tmp_bfd = NULL; 00540 int status; 00541 CORE_ADDR addr, interp_loadmap_addr; 00542 gdb_byte addr_buf[FRV_PTR_SIZE]; 00543 struct int_elf32_fdpic_loadmap *ldm; 00544 volatile struct gdb_exception ex; 00545 00546 /* Read the contents of the .interp section into a local buffer; 00547 the contents specify the dynamic linker this program uses. */ 00548 interp_sect_size = bfd_section_size (exec_bfd, interp_sect); 00549 buf = alloca (interp_sect_size); 00550 bfd_get_section_contents (exec_bfd, interp_sect, 00551 buf, 0, interp_sect_size); 00552 00553 /* Now we need to figure out where the dynamic linker was 00554 loaded so that we can load its symbols and place a breakpoint 00555 in the dynamic linker itself. 00556 00557 This address is stored on the stack. However, I've been unable 00558 to find any magic formula to find it for Solaris (appears to 00559 be trivial on GNU/Linux). Therefore, we have to try an alternate 00560 mechanism to find the dynamic linker's base address. */ 00561 00562 TRY_CATCH (ex, RETURN_MASK_ALL) 00563 { 00564 tmp_bfd = solib_bfd_open (buf); 00565 } 00566 if (tmp_bfd == NULL) 00567 { 00568 enable_break_failure_warning (); 00569 return 0; 00570 } 00571 00572 status = frv_fdpic_loadmap_addresses (target_gdbarch (), 00573 &interp_loadmap_addr, 0); 00574 if (status < 0) 00575 { 00576 warning (_("Unable to determine dynamic linker loadmap address.")); 00577 enable_break_failure_warning (); 00578 gdb_bfd_unref (tmp_bfd); 00579 return 0; 00580 } 00581 00582 if (solib_frv_debug) 00583 fprintf_unfiltered (gdb_stdlog, 00584 "enable_break: interp_loadmap_addr = %s\n", 00585 hex_string_custom (interp_loadmap_addr, 8)); 00586 00587 ldm = fetch_loadmap (interp_loadmap_addr); 00588 if (ldm == NULL) 00589 { 00590 warning (_("Unable to load dynamic linker loadmap at address %s."), 00591 hex_string_custom (interp_loadmap_addr, 8)); 00592 enable_break_failure_warning (); 00593 gdb_bfd_unref (tmp_bfd); 00594 return 0; 00595 } 00596 00597 /* Record the relocated start and end address of the dynamic linker 00598 text and plt section for svr4_in_dynsym_resolve_code. */ 00599 interp_sect = bfd_get_section_by_name (tmp_bfd, ".text"); 00600 if (interp_sect) 00601 { 00602 interp_text_sect_low 00603 = bfd_section_vma (tmp_bfd, interp_sect); 00604 interp_text_sect_low 00605 += displacement_from_map (ldm, interp_text_sect_low); 00606 interp_text_sect_high 00607 = interp_text_sect_low + bfd_section_size (tmp_bfd, interp_sect); 00608 } 00609 interp_sect = bfd_get_section_by_name (tmp_bfd, ".plt"); 00610 if (interp_sect) 00611 { 00612 interp_plt_sect_low = 00613 bfd_section_vma (tmp_bfd, interp_sect); 00614 interp_plt_sect_low 00615 += displacement_from_map (ldm, interp_plt_sect_low); 00616 interp_plt_sect_high = 00617 interp_plt_sect_low + bfd_section_size (tmp_bfd, interp_sect); 00618 } 00619 00620 addr = gdb_bfd_lookup_symbol (tmp_bfd, cmp_name, "_dl_debug_addr"); 00621 00622 if (addr == 0) 00623 { 00624 warning (_("Could not find symbol _dl_debug_addr " 00625 "in dynamic linker")); 00626 enable_break_failure_warning (); 00627 gdb_bfd_unref (tmp_bfd); 00628 return 0; 00629 } 00630 00631 if (solib_frv_debug) 00632 fprintf_unfiltered (gdb_stdlog, 00633 "enable_break: _dl_debug_addr " 00634 "(prior to relocation) = %s\n", 00635 hex_string_custom (addr, 8)); 00636 00637 addr += displacement_from_map (ldm, addr); 00638 00639 if (solib_frv_debug) 00640 fprintf_unfiltered (gdb_stdlog, 00641 "enable_break: _dl_debug_addr " 00642 "(after relocation) = %s\n", 00643 hex_string_custom (addr, 8)); 00644 00645 /* Fetch the address of the r_debug struct. */ 00646 if (target_read_memory (addr, addr_buf, sizeof addr_buf) != 0) 00647 { 00648 warning (_("Unable to fetch contents of _dl_debug_addr " 00649 "(at address %s) from dynamic linker"), 00650 hex_string_custom (addr, 8)); 00651 } 00652 addr = extract_unsigned_integer (addr_buf, sizeof addr_buf, byte_order); 00653 00654 if (solib_frv_debug) 00655 fprintf_unfiltered (gdb_stdlog, 00656 "enable_break: _dl_debug_addr[0..3] = %s\n", 00657 hex_string_custom (addr, 8)); 00658 00659 /* If it's zero, then the ldso hasn't initialized yet, and so 00660 there are no shared libs yet loaded. */ 00661 if (addr == 0) 00662 { 00663 if (solib_frv_debug) 00664 fprintf_unfiltered (gdb_stdlog, 00665 "enable_break: ldso not yet initialized\n"); 00666 /* Do not warn, but mark to run again. */ 00667 return 0; 00668 } 00669 00670 /* Fetch the r_brk field. It's 8 bytes from the start of 00671 _dl_debug_addr. */ 00672 if (target_read_memory (addr + 8, addr_buf, sizeof addr_buf) != 0) 00673 { 00674 warning (_("Unable to fetch _dl_debug_addr->r_brk " 00675 "(at address %s) from dynamic linker"), 00676 hex_string_custom (addr + 8, 8)); 00677 enable_break_failure_warning (); 00678 gdb_bfd_unref (tmp_bfd); 00679 return 0; 00680 } 00681 addr = extract_unsigned_integer (addr_buf, sizeof addr_buf, byte_order); 00682 00683 /* Now fetch the function entry point. */ 00684 if (target_read_memory (addr, addr_buf, sizeof addr_buf) != 0) 00685 { 00686 warning (_("Unable to fetch _dl_debug_addr->.r_brk entry point " 00687 "(at address %s) from dynamic linker"), 00688 hex_string_custom (addr, 8)); 00689 enable_break_failure_warning (); 00690 gdb_bfd_unref (tmp_bfd); 00691 return 0; 00692 } 00693 addr = extract_unsigned_integer (addr_buf, sizeof addr_buf, byte_order); 00694 00695 /* We're done with the temporary bfd. */ 00696 gdb_bfd_unref (tmp_bfd); 00697 00698 /* We're also done with the loadmap. */ 00699 xfree (ldm); 00700 00701 /* Remove all the solib event breakpoints. Their addresses 00702 may have changed since the last time we ran the program. */ 00703 remove_solib_event_breakpoints (); 00704 00705 /* Now (finally!) create the solib breakpoint. */ 00706 create_solib_event_breakpoint (target_gdbarch (), addr); 00707 00708 enable_break2_done = 1; 00709 00710 return 1; 00711 } 00712 00713 /* Tell the user we couldn't set a dynamic linker breakpoint. */ 00714 enable_break_failure_warning (); 00715 00716 /* Failure return. */ 00717 return 0; 00718 } 00719 00720 static int 00721 enable_break (void) 00722 { 00723 asection *interp_sect; 00724 00725 if (symfile_objfile == NULL) 00726 { 00727 if (solib_frv_debug) 00728 fprintf_unfiltered (gdb_stdlog, 00729 "enable_break: No symbol file found.\n"); 00730 return 0; 00731 } 00732 00733 if (!symfile_objfile->ei.entry_point_p) 00734 { 00735 if (solib_frv_debug) 00736 fprintf_unfiltered (gdb_stdlog, 00737 "enable_break: Symbol file has no entry point.\n"); 00738 return 0; 00739 } 00740 00741 /* Check for the presence of a .interp section. If there is no 00742 such section, the executable is statically linked. */ 00743 00744 interp_sect = bfd_get_section_by_name (exec_bfd, ".interp"); 00745 00746 if (interp_sect == NULL) 00747 { 00748 if (solib_frv_debug) 00749 fprintf_unfiltered (gdb_stdlog, 00750 "enable_break: No .interp section found.\n"); 00751 return 0; 00752 } 00753 00754 create_solib_event_breakpoint (target_gdbarch (), 00755 symfile_objfile->ei.entry_point); 00756 00757 if (solib_frv_debug) 00758 fprintf_unfiltered (gdb_stdlog, 00759 "enable_break: solib event breakpoint " 00760 "placed at entry point: %s\n", 00761 hex_string_custom (symfile_objfile->ei.entry_point, 00762 8)); 00763 return 1; 00764 } 00765 00766 /* Implement the "special_symbol_handling" target_so_ops method. */ 00767 00768 static void 00769 frv_special_symbol_handling (void) 00770 { 00771 /* Nothing needed for FRV. */ 00772 } 00773 00774 static void 00775 frv_relocate_main_executable (void) 00776 { 00777 int status; 00778 CORE_ADDR exec_addr, interp_addr; 00779 struct int_elf32_fdpic_loadmap *ldm; 00780 struct cleanup *old_chain; 00781 struct section_offsets *new_offsets; 00782 int changed; 00783 struct obj_section *osect; 00784 00785 status = frv_fdpic_loadmap_addresses (target_gdbarch (), 00786 &interp_addr, &exec_addr); 00787 00788 if (status < 0 || (exec_addr == 0 && interp_addr == 0)) 00789 { 00790 /* Not using FDPIC ABI, so do nothing. */ 00791 return; 00792 } 00793 00794 /* Fetch the loadmap located at ``exec_addr''. */ 00795 ldm = fetch_loadmap (exec_addr); 00796 if (ldm == NULL) 00797 error (_("Unable to load the executable's loadmap.")); 00798 00799 if (main_executable_lm_info) 00800 xfree (main_executable_lm_info); 00801 main_executable_lm_info = xcalloc (1, sizeof (struct lm_info)); 00802 main_executable_lm_info->map = ldm; 00803 00804 new_offsets = xcalloc (symfile_objfile->num_sections, 00805 sizeof (struct section_offsets)); 00806 old_chain = make_cleanup (xfree, new_offsets); 00807 changed = 0; 00808 00809 ALL_OBJFILE_OSECTIONS (symfile_objfile, osect) 00810 { 00811 CORE_ADDR orig_addr, addr, offset; 00812 int osect_idx; 00813 int seg; 00814 00815 osect_idx = osect - symfile_objfile->sections; 00816 00817 /* Current address of section. */ 00818 addr = obj_section_addr (osect); 00819 /* Offset from where this section started. */ 00820 offset = ANOFFSET (symfile_objfile->section_offsets, osect_idx); 00821 /* Original address prior to any past relocations. */ 00822 orig_addr = addr - offset; 00823 00824 for (seg = 0; seg < ldm->nsegs; seg++) 00825 { 00826 if (ldm->segs[seg].p_vaddr <= orig_addr 00827 && orig_addr < ldm->segs[seg].p_vaddr + ldm->segs[seg].p_memsz) 00828 { 00829 new_offsets->offsets[osect_idx] 00830 = ldm->segs[seg].addr - ldm->segs[seg].p_vaddr; 00831 00832 if (new_offsets->offsets[osect_idx] != offset) 00833 changed = 1; 00834 break; 00835 } 00836 } 00837 } 00838 00839 if (changed) 00840 objfile_relocate (symfile_objfile, new_offsets); 00841 00842 do_cleanups (old_chain); 00843 00844 /* Now that symfile_objfile has been relocated, we can compute the 00845 GOT value and stash it away. */ 00846 main_executable_lm_info->got_value = main_got (); 00847 } 00848 00849 /* Implement the "create_inferior_hook" target_solib_ops method. 00850 00851 For the FR-V shared library ABI (FDPIC), the main executable needs 00852 to be relocated. The shared library breakpoints also need to be 00853 enabled. */ 00854 00855 static void 00856 frv_solib_create_inferior_hook (int from_tty) 00857 { 00858 /* Relocate main executable. */ 00859 frv_relocate_main_executable (); 00860 00861 /* Enable shared library breakpoints. */ 00862 if (!enable_break ()) 00863 { 00864 warning (_("shared library handler failed to enable breakpoint")); 00865 return; 00866 } 00867 } 00868 00869 static void 00870 frv_clear_solib (void) 00871 { 00872 lm_base_cache = 0; 00873 enable_break2_done = 0; 00874 main_lm_addr = 0; 00875 if (main_executable_lm_info != 0) 00876 { 00877 xfree (main_executable_lm_info->map); 00878 xfree (main_executable_lm_info->dyn_syms); 00879 xfree (main_executable_lm_info->dyn_relocs); 00880 xfree (main_executable_lm_info); 00881 main_executable_lm_info = 0; 00882 } 00883 } 00884 00885 static void 00886 frv_free_so (struct so_list *so) 00887 { 00888 xfree (so->lm_info->map); 00889 xfree (so->lm_info->dyn_syms); 00890 xfree (so->lm_info->dyn_relocs); 00891 xfree (so->lm_info); 00892 } 00893 00894 static void 00895 frv_relocate_section_addresses (struct so_list *so, 00896 struct target_section *sec) 00897 { 00898 int seg; 00899 struct int_elf32_fdpic_loadmap *map; 00900 00901 map = so->lm_info->map; 00902 00903 for (seg = 0; seg < map->nsegs; seg++) 00904 { 00905 if (map->segs[seg].p_vaddr <= sec->addr 00906 && sec->addr < map->segs[seg].p_vaddr + map->segs[seg].p_memsz) 00907 { 00908 CORE_ADDR displ = map->segs[seg].addr - map->segs[seg].p_vaddr; 00909 00910 sec->addr += displ; 00911 sec->endaddr += displ; 00912 break; 00913 } 00914 } 00915 } 00916 00917 /* Return the GOT address associated with the main executable. Return 00918 0 if it can't be found. */ 00919 00920 static CORE_ADDR 00921 main_got (void) 00922 { 00923 struct minimal_symbol *got_sym; 00924 00925 got_sym = lookup_minimal_symbol ("_GLOBAL_OFFSET_TABLE_", 00926 NULL, symfile_objfile); 00927 if (got_sym == 0) 00928 return 0; 00929 00930 return SYMBOL_VALUE_ADDRESS (got_sym); 00931 } 00932 00933 /* Find the global pointer for the given function address ADDR. */ 00934 00935 CORE_ADDR 00936 frv_fdpic_find_global_pointer (CORE_ADDR addr) 00937 { 00938 struct so_list *so; 00939 00940 so = master_so_list (); 00941 while (so) 00942 { 00943 int seg; 00944 struct int_elf32_fdpic_loadmap *map; 00945 00946 map = so->lm_info->map; 00947 00948 for (seg = 0; seg < map->nsegs; seg++) 00949 { 00950 if (map->segs[seg].addr <= addr 00951 && addr < map->segs[seg].addr + map->segs[seg].p_memsz) 00952 return so->lm_info->got_value; 00953 } 00954 00955 so = so->next; 00956 } 00957 00958 /* Didn't find it in any of the shared objects. So assume it's in the 00959 main executable. */ 00960 return main_got (); 00961 } 00962 00963 /* Forward declarations for frv_fdpic_find_canonical_descriptor(). */ 00964 static CORE_ADDR find_canonical_descriptor_in_load_object 00965 (CORE_ADDR, CORE_ADDR, const char *, bfd *, struct lm_info *); 00966 00967 /* Given a function entry point, attempt to find the canonical descriptor 00968 associated with that entry point. Return 0 if no canonical descriptor 00969 could be found. */ 00970 00971 CORE_ADDR 00972 frv_fdpic_find_canonical_descriptor (CORE_ADDR entry_point) 00973 { 00974 const char *name; 00975 CORE_ADDR addr; 00976 CORE_ADDR got_value; 00977 struct int_elf32_fdpic_loadmap *ldm = 0; 00978 struct symbol *sym; 00979 00980 /* Fetch the corresponding global pointer for the entry point. */ 00981 got_value = frv_fdpic_find_global_pointer (entry_point); 00982 00983 /* Attempt to find the name of the function. If the name is available, 00984 it'll be used as an aid in finding matching functions in the dynamic 00985 symbol table. */ 00986 sym = find_pc_function (entry_point); 00987 if (sym == 0) 00988 name = 0; 00989 else 00990 name = SYMBOL_LINKAGE_NAME (sym); 00991 00992 /* Check the main executable. */ 00993 addr = find_canonical_descriptor_in_load_object 00994 (entry_point, got_value, name, symfile_objfile->obfd, 00995 main_executable_lm_info); 00996 00997 /* If descriptor not found via main executable, check each load object 00998 in list of shared objects. */ 00999 if (addr == 0) 01000 { 01001 struct so_list *so; 01002 01003 so = master_so_list (); 01004 while (so) 01005 { 01006 addr = find_canonical_descriptor_in_load_object 01007 (entry_point, got_value, name, so->abfd, so->lm_info); 01008 01009 if (addr != 0) 01010 break; 01011 01012 so = so->next; 01013 } 01014 } 01015 01016 return addr; 01017 } 01018 01019 static CORE_ADDR 01020 find_canonical_descriptor_in_load_object 01021 (CORE_ADDR entry_point, CORE_ADDR got_value, const char *name, bfd *abfd, 01022 struct lm_info *lm) 01023 { 01024 enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch ()); 01025 arelent *rel; 01026 unsigned int i; 01027 CORE_ADDR addr = 0; 01028 01029 /* Nothing to do if no bfd. */ 01030 if (abfd == 0) 01031 return 0; 01032 01033 /* Nothing to do if no link map. */ 01034 if (lm == 0) 01035 return 0; 01036 01037 /* We want to scan the dynamic relocs for R_FRV_FUNCDESC relocations. 01038 (More about this later.) But in order to fetch the relocs, we 01039 need to first fetch the dynamic symbols. These symbols need to 01040 be cached due to the way that bfd_canonicalize_dynamic_reloc() 01041 works. (See the comments in the declaration of struct lm_info 01042 for more information.) */ 01043 if (lm->dyn_syms == NULL) 01044 { 01045 long storage_needed; 01046 unsigned int number_of_symbols; 01047 01048 /* Determine amount of space needed to hold the dynamic symbol table. */ 01049 storage_needed = bfd_get_dynamic_symtab_upper_bound (abfd); 01050 01051 /* If there are no dynamic symbols, there's nothing to do. */ 01052 if (storage_needed <= 0) 01053 return 0; 01054 01055 /* Allocate space for the dynamic symbol table. */ 01056 lm->dyn_syms = (asymbol **) xmalloc (storage_needed); 01057 01058 /* Fetch the dynamic symbol table. */ 01059 number_of_symbols = bfd_canonicalize_dynamic_symtab (abfd, lm->dyn_syms); 01060 01061 if (number_of_symbols == 0) 01062 return 0; 01063 } 01064 01065 /* Fetch the dynamic relocations if not already cached. */ 01066 if (lm->dyn_relocs == NULL) 01067 { 01068 long storage_needed; 01069 01070 /* Determine amount of space needed to hold the dynamic relocs. */ 01071 storage_needed = bfd_get_dynamic_reloc_upper_bound (abfd); 01072 01073 /* Bail out if there are no dynamic relocs. */ 01074 if (storage_needed <= 0) 01075 return 0; 01076 01077 /* Allocate space for the relocs. */ 01078 lm->dyn_relocs = (arelent **) xmalloc (storage_needed); 01079 01080 /* Fetch the dynamic relocs. */ 01081 lm->dyn_reloc_count 01082 = bfd_canonicalize_dynamic_reloc (abfd, lm->dyn_relocs, lm->dyn_syms); 01083 } 01084 01085 /* Search the dynamic relocs. */ 01086 for (i = 0; i < lm->dyn_reloc_count; i++) 01087 { 01088 rel = lm->dyn_relocs[i]; 01089 01090 /* Relocs of interest are those which meet the following 01091 criteria: 01092 01093 - the names match (assuming the caller could provide 01094 a name which matches ``entry_point''). 01095 - the relocation type must be R_FRV_FUNCDESC. Relocs 01096 of this type are used (by the dynamic linker) to 01097 look up the address of a canonical descriptor (allocating 01098 it if need be) and initializing the GOT entry referred 01099 to by the offset to the address of the descriptor. 01100 01101 These relocs of interest may be used to obtain a 01102 candidate descriptor by first adjusting the reloc's 01103 address according to the link map and then dereferencing 01104 this address (which is a GOT entry) to obtain a descriptor 01105 address. */ 01106 if ((name == 0 || strcmp (name, (*rel->sym_ptr_ptr)->name) == 0) 01107 && rel->howto->type == R_FRV_FUNCDESC) 01108 { 01109 gdb_byte buf [FRV_PTR_SIZE]; 01110 01111 /* Compute address of address of candidate descriptor. */ 01112 addr = rel->address + displacement_from_map (lm->map, rel->address); 01113 01114 /* Fetch address of candidate descriptor. */ 01115 if (target_read_memory (addr, buf, sizeof buf) != 0) 01116 continue; 01117 addr = extract_unsigned_integer (buf, sizeof buf, byte_order); 01118 01119 /* Check for matching entry point. */ 01120 if (target_read_memory (addr, buf, sizeof buf) != 0) 01121 continue; 01122 if (extract_unsigned_integer (buf, sizeof buf, byte_order) 01123 != entry_point) 01124 continue; 01125 01126 /* Check for matching got value. */ 01127 if (target_read_memory (addr + 4, buf, sizeof buf) != 0) 01128 continue; 01129 if (extract_unsigned_integer (buf, sizeof buf, byte_order) 01130 != got_value) 01131 continue; 01132 01133 /* Match was successful! Exit loop. */ 01134 break; 01135 } 01136 } 01137 01138 return addr; 01139 } 01140 01141 /* Given an objfile, return the address of its link map. This value is 01142 needed for TLS support. */ 01143 CORE_ADDR 01144 frv_fetch_objfile_link_map (struct objfile *objfile) 01145 { 01146 struct so_list *so; 01147 01148 /* Cause frv_current_sos() to be run if it hasn't been already. */ 01149 if (main_lm_addr == 0) 01150 solib_add (0, 0, 0, 1); 01151 01152 /* frv_current_sos() will set main_lm_addr for the main executable. */ 01153 if (objfile == symfile_objfile) 01154 return main_lm_addr; 01155 01156 /* The other link map addresses may be found by examining the list 01157 of shared libraries. */ 01158 for (so = master_so_list (); so; so = so->next) 01159 { 01160 if (so->objfile == objfile) 01161 return so->lm_info->lm_addr; 01162 } 01163 01164 /* Not found! */ 01165 return 0; 01166 } 01167 01168 struct target_so_ops frv_so_ops; 01169 01170 /* Provide a prototype to silence -Wmissing-prototypes. */ 01171 extern initialize_file_ftype _initialize_frv_solib; 01172 01173 void 01174 _initialize_frv_solib (void) 01175 { 01176 frv_so_ops.relocate_section_addresses = frv_relocate_section_addresses; 01177 frv_so_ops.free_so = frv_free_so; 01178 frv_so_ops.clear_solib = frv_clear_solib; 01179 frv_so_ops.solib_create_inferior_hook = frv_solib_create_inferior_hook; 01180 frv_so_ops.special_symbol_handling = frv_special_symbol_handling; 01181 frv_so_ops.current_sos = frv_current_sos; 01182 frv_so_ops.open_symbol_file_object = open_symbol_file_object; 01183 frv_so_ops.in_dynsym_resolve_code = frv_in_dynsym_resolve_code; 01184 frv_so_ops.bfd_open = solib_bfd_open; 01185 01186 /* Debug this file's internals. */ 01187 add_setshow_zuinteger_cmd ("solib-frv", class_maintenance, 01188 &solib_frv_debug, _("\ 01189 Set internal debugging of shared library code for FR-V."), _("\ 01190 Show internal debugging of shared library code for FR-V."), _("\ 01191 When non-zero, FR-V solib specific internal debugging is enabled."), 01192 NULL, 01193 NULL, /* FIXME: i18n: */ 01194 &setdebuglist, &showdebuglist); 01195 }