GDB (API)
|
00001 /* Handle SOM shared libraries. 00002 00003 Copyright (C) 2004-2013 Free Software Foundation, Inc. 00004 00005 This file is part of GDB. 00006 00007 This program is free software; you can redistribute it and/or modify 00008 it under the terms of the GNU General Public License as published by 00009 the Free Software Foundation; either version 3 of the License, or 00010 (at your option) any later version. 00011 00012 This program is distributed in the hope that it will be useful, 00013 but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00015 GNU General Public License for more details. 00016 00017 You should have received a copy of the GNU General Public License 00018 along with this program. If not, see <http://www.gnu.org/licenses/>. */ 00019 00020 #include "defs.h" 00021 #include "symtab.h" 00022 #include "bfd.h" 00023 #include "symfile.h" 00024 #include "objfiles.h" 00025 #include "gdbcore.h" 00026 #include "target.h" 00027 #include "inferior.h" 00028 00029 #include "hppa-tdep.h" 00030 #include "solist.h" 00031 #include "solib.h" 00032 #include "solib-som.h" 00033 00034 #include <string.h> 00035 00036 #undef SOLIB_SOM_DBG 00037 00038 /* These ought to be defined in some public interface, but aren't. They 00039 define the meaning of the various bits in the distinguished __dld_flags 00040 variable that is declared in every debuggable a.out on HP-UX, and that 00041 is shared between the debugger and the dynamic linker. */ 00042 00043 #define DLD_FLAGS_MAPPRIVATE 0x1 00044 #define DLD_FLAGS_HOOKVALID 0x2 00045 #define DLD_FLAGS_LISTVALID 0x4 00046 #define DLD_FLAGS_BOR_ENABLE 0x8 00047 00048 struct lm_info 00049 { 00050 /* Version of this structure (it is expected to change again in 00051 hpux10). */ 00052 unsigned char struct_version; 00053 00054 /* Binding mode for this library. */ 00055 unsigned char bind_mode; 00056 00057 /* Version of this library. */ 00058 short library_version; 00059 00060 /* Start of text address, 00061 link-time text location (length of text area), 00062 end of text address. */ 00063 CORE_ADDR text_addr; 00064 CORE_ADDR text_link_addr; 00065 CORE_ADDR text_end; 00066 00067 /* Start of data, start of bss and end of data. */ 00068 CORE_ADDR data_start; 00069 CORE_ADDR bss_start; 00070 CORE_ADDR data_end; 00071 00072 /* Value of linkage pointer (%r19). */ 00073 CORE_ADDR got_value; 00074 00075 /* Address in target of offset from thread-local register of 00076 start of this thread's data. I.e., the first thread-local 00077 variable in this shared library starts at *(tsd_start_addr) 00078 from that area pointed to by cr27 (mpsfu_hi). 00079 00080 We do the indirection as soon as we read it, so from then 00081 on it's the offset itself. */ 00082 CORE_ADDR tsd_start_addr; 00083 00084 /* Address of the link map entry in the loader. */ 00085 CORE_ADDR lm_addr; 00086 }; 00087 00088 /* These addresses should be filled in by som_solib_create_inferior_hook. 00089 They are also used elsewhere in this module. */ 00090 00091 typedef struct 00092 { 00093 CORE_ADDR address; 00094 struct unwind_table_entry *unwind; 00095 } 00096 addr_and_unwind_t; 00097 00098 /* When adding fields, be sure to clear them in _initialize_som_solib. */ 00099 static struct 00100 { 00101 int is_valid; 00102 addr_and_unwind_t hook; 00103 addr_and_unwind_t hook_stub; 00104 addr_and_unwind_t load; 00105 addr_and_unwind_t load_stub; 00106 addr_and_unwind_t unload; 00107 addr_and_unwind_t unload2; 00108 addr_and_unwind_t unload_stub; 00109 } 00110 dld_cache; 00111 00112 static void 00113 som_relocate_section_addresses (struct so_list *so, 00114 struct target_section *sec) 00115 { 00116 flagword aflag = bfd_get_section_flags(so->abfd, sec->the_bfd_section); 00117 00118 if (aflag & SEC_CODE) 00119 { 00120 sec->addr += so->lm_info->text_addr - so->lm_info->text_link_addr; 00121 sec->endaddr += so->lm_info->text_addr - so->lm_info->text_link_addr; 00122 } 00123 else if (aflag & SEC_DATA) 00124 { 00125 sec->addr += so->lm_info->data_start; 00126 sec->endaddr += so->lm_info->data_start; 00127 } 00128 else 00129 { 00130 /* Nothing. */ 00131 } 00132 } 00133 00134 00135 /* Variable storing HP-UX major release number. 00136 00137 On non-native system, simply assume that the major release number 00138 is 11. On native systems, hppa-hpux-nat.c initialization code 00139 sets this number to the real one on startup. 00140 00141 We cannot compute this value here, because we need to make a native 00142 call to "uname". We are are not allowed to do that from here, as 00143 this file is used for both native and cross debugging. */ 00144 00145 #define DEFAULT_HPUX_MAJOR_RELEASE 11 00146 int hpux_major_release = DEFAULT_HPUX_MAJOR_RELEASE; 00147 00148 static int 00149 get_hpux_major_release (void) 00150 { 00151 return hpux_major_release; 00152 } 00153 00154 /* DL header flag defines. */ 00155 #define SHLIB_TEXT_PRIVATE_ENABLE 0x4000 00156 00157 /* The DL header is documented in <shl.h>. We are only interested 00158 in the flags field to determine whether the executable wants shared 00159 libraries mapped private. */ 00160 struct { 00161 short junk[37]; 00162 short flags; 00163 } dl_header; 00164 00165 /* This hook gets called just before the first instruction in the 00166 inferior process is executed. 00167 00168 This is our opportunity to set magic flags in the inferior so 00169 that GDB can be notified when a shared library is mapped in and 00170 to tell the dynamic linker that a private copy of the library is 00171 needed (so GDB can set breakpoints in the library). 00172 00173 __dld_flags is the location of the magic flags; as of this implementation 00174 there are 3 flags of interest: 00175 00176 bit 0 when set indicates that private copies of the libraries are needed 00177 bit 1 when set indicates that the callback hook routine is valid 00178 bit 2 when set indicates that the dynamic linker should maintain the 00179 __dld_list structure when loading/unloading libraries. 00180 00181 Note that shared libraries are not mapped in at this time, so we have 00182 run the inferior until the libraries are mapped in. Typically this 00183 means running until the "_start" is called. */ 00184 00185 static void 00186 som_solib_create_inferior_hook (int from_tty) 00187 { 00188 enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch ()); 00189 struct minimal_symbol *msymbol; 00190 unsigned int dld_flags, status, have_endo; 00191 asection *shlib_info; 00192 gdb_byte buf[4]; 00193 CORE_ADDR anaddr; 00194 00195 if (symfile_objfile == NULL) 00196 return; 00197 00198 /* First see if the objfile was dynamically linked. */ 00199 shlib_info = bfd_get_section_by_name (symfile_objfile->obfd, "$SHLIB_INFO$"); 00200 if (!shlib_info) 00201 return; 00202 00203 /* It's got a $SHLIB_INFO$ section, make sure it's not empty. */ 00204 if (bfd_section_size (symfile_objfile->obfd, shlib_info) == 0) 00205 return; 00206 00207 /* Read the DL header. */ 00208 bfd_get_section_contents (symfile_objfile->obfd, shlib_info, 00209 (char *) &dl_header, 0, sizeof (dl_header)); 00210 00211 have_endo = 0; 00212 /* Slam the pid of the process into __d_pid. 00213 00214 We used to warn when this failed, but that warning is only useful 00215 on very old HP systems (hpux9 and older). The warnings are an 00216 annoyance to users of modern systems and foul up the testsuite as 00217 well. As a result, the warnings have been disabled. */ 00218 msymbol = lookup_minimal_symbol ("__d_pid", NULL, symfile_objfile); 00219 if (msymbol == NULL) 00220 goto keep_going; 00221 00222 anaddr = SYMBOL_VALUE_ADDRESS (msymbol); 00223 store_unsigned_integer (buf, 4, byte_order, ptid_get_pid (inferior_ptid)); 00224 status = target_write_memory (anaddr, buf, 4); 00225 if (status != 0) 00226 { 00227 warning (_("\ 00228 Unable to write __d_pid.\n\ 00229 Suggest linking with /opt/langtools/lib/end.o.\n\ 00230 GDB will be unable to track shl_load/shl_unload calls")); 00231 goto keep_going; 00232 } 00233 00234 /* Get the value of _DLD_HOOK (an export stub) and put it in __dld_hook; 00235 This will force the dynamic linker to call __d_trap when significant 00236 events occur. 00237 00238 Note that the above is the pre-HP-UX 9.0 behaviour. At 9.0 and above, 00239 the dld provides an export stub named "__d_trap" as well as the 00240 function named "__d_trap" itself, but doesn't provide "_DLD_HOOK". 00241 We'll look first for the old flavor and then the new. */ 00242 00243 msymbol = lookup_minimal_symbol ("_DLD_HOOK", NULL, symfile_objfile); 00244 if (msymbol == NULL) 00245 msymbol = lookup_minimal_symbol ("__d_trap", NULL, symfile_objfile); 00246 if (msymbol == NULL) 00247 { 00248 warning (_("\ 00249 Unable to find _DLD_HOOK symbol in object file.\n\ 00250 Suggest linking with /opt/langtools/lib/end.o.\n\ 00251 GDB will be unable to track shl_load/shl_unload calls")); 00252 goto keep_going; 00253 } 00254 anaddr = SYMBOL_VALUE_ADDRESS (msymbol); 00255 dld_cache.hook.address = anaddr; 00256 00257 /* Grrr, this might not be an export symbol! We have to find the 00258 export stub. */ 00259 msymbol = hppa_lookup_stub_minimal_symbol (SYMBOL_LINKAGE_NAME (msymbol), 00260 EXPORT); 00261 if (msymbol != NULL) 00262 { 00263 anaddr = SYMBOL_VALUE (msymbol); 00264 dld_cache.hook_stub.address = anaddr; 00265 } 00266 store_unsigned_integer (buf, 4, byte_order, anaddr); 00267 00268 msymbol = lookup_minimal_symbol ("__dld_hook", NULL, symfile_objfile); 00269 if (msymbol == NULL) 00270 { 00271 warning (_("\ 00272 Unable to find __dld_hook symbol in object file.\n\ 00273 Suggest linking with /opt/langtools/lib/end.o.\n\ 00274 GDB will be unable to track shl_load/shl_unload calls")); 00275 goto keep_going; 00276 } 00277 anaddr = SYMBOL_VALUE_ADDRESS (msymbol); 00278 status = target_write_memory (anaddr, buf, 4); 00279 00280 /* Now set a shlib_event breakpoint at __d_trap so we can track 00281 significant shared library events. */ 00282 msymbol = lookup_minimal_symbol ("__d_trap", NULL, symfile_objfile); 00283 if (msymbol == NULL) 00284 { 00285 warning (_("\ 00286 Unable to find __dld_d_trap symbol in object file.\n\ 00287 Suggest linking with /opt/langtools/lib/end.o.\n\ 00288 GDB will be unable to track shl_load/shl_unload calls")); 00289 goto keep_going; 00290 } 00291 create_solib_event_breakpoint (target_gdbarch (), 00292 SYMBOL_VALUE_ADDRESS (msymbol)); 00293 00294 /* We have all the support usually found in end.o, so we can track 00295 shl_load and shl_unload calls. */ 00296 have_endo = 1; 00297 00298 keep_going: 00299 00300 /* Get the address of __dld_flags, if no such symbol exists, then we can 00301 not debug the shared code. */ 00302 msymbol = lookup_minimal_symbol ("__dld_flags", NULL, NULL); 00303 if (msymbol == NULL) 00304 { 00305 error (_("Unable to find __dld_flags symbol in object file.")); 00306 } 00307 00308 anaddr = SYMBOL_VALUE_ADDRESS (msymbol); 00309 00310 /* Read the current contents. */ 00311 status = target_read_memory (anaddr, buf, 4); 00312 if (status != 0) 00313 error (_("Unable to read __dld_flags.")); 00314 dld_flags = extract_unsigned_integer (buf, 4, byte_order); 00315 00316 /* If the libraries were not mapped private on HP-UX 11 and later, warn 00317 the user. On HP-UX 10 and earlier, there is no easy way to specify 00318 that shared libraries should be privately mapped. So, we just force 00319 private mapping. */ 00320 if (get_hpux_major_release () >= 11 00321 && (dl_header.flags & SHLIB_TEXT_PRIVATE_ENABLE) == 0 00322 && (dld_flags & DLD_FLAGS_MAPPRIVATE) == 0) 00323 warning 00324 (_("\ 00325 Private mapping of shared library text was not specified\n\ 00326 by the executable; setting a breakpoint in a shared library which\n\ 00327 is not privately mapped will not work. See the HP-UX 11i v3 chatr\n\ 00328 manpage for methods to privately map shared library text.")); 00329 00330 /* Turn on the flags we care about. */ 00331 if (get_hpux_major_release () < 11) 00332 dld_flags |= DLD_FLAGS_MAPPRIVATE; 00333 if (have_endo) 00334 dld_flags |= DLD_FLAGS_HOOKVALID; 00335 store_unsigned_integer (buf, 4, byte_order, dld_flags); 00336 status = target_write_memory (anaddr, buf, 4); 00337 if (status != 0) 00338 error (_("Unable to write __dld_flags.")); 00339 00340 /* Now find the address of _start and set a breakpoint there. 00341 We still need this code for two reasons: 00342 00343 * Not all sites have /opt/langtools/lib/end.o, so it's not always 00344 possible to track the dynamic linker's events. 00345 00346 * At this time no events are triggered for shared libraries 00347 loaded at startup time (what a crock). */ 00348 00349 msymbol = lookup_minimal_symbol ("_start", NULL, symfile_objfile); 00350 if (msymbol == NULL) 00351 error (_("Unable to find _start symbol in object file.")); 00352 00353 anaddr = SYMBOL_VALUE_ADDRESS (msymbol); 00354 00355 /* Make the breakpoint at "_start" a shared library event breakpoint. */ 00356 create_solib_event_breakpoint (target_gdbarch (), anaddr); 00357 00358 clear_symtab_users (0); 00359 } 00360 00361 static void 00362 som_special_symbol_handling (void) 00363 { 00364 } 00365 00366 static void 00367 som_solib_desire_dynamic_linker_symbols (void) 00368 { 00369 struct objfile *objfile; 00370 struct unwind_table_entry *u; 00371 struct minimal_symbol *dld_msymbol; 00372 00373 /* Do we already know the value of these symbols? If so, then 00374 we've no work to do. 00375 00376 (If you add clauses to this test, be sure to likewise update the 00377 test within the loop.) */ 00378 00379 if (dld_cache.is_valid) 00380 return; 00381 00382 ALL_OBJFILES (objfile) 00383 { 00384 dld_msymbol = lookup_minimal_symbol ("shl_load", NULL, objfile); 00385 if (dld_msymbol != NULL) 00386 { 00387 dld_cache.load.address = SYMBOL_VALUE (dld_msymbol); 00388 dld_cache.load.unwind = find_unwind_entry (dld_cache.load.address); 00389 } 00390 00391 dld_msymbol = lookup_minimal_symbol_solib_trampoline ("shl_load", 00392 objfile); 00393 if (dld_msymbol != NULL) 00394 { 00395 if (MSYMBOL_TYPE (dld_msymbol) == mst_solib_trampoline) 00396 { 00397 u = find_unwind_entry (SYMBOL_VALUE (dld_msymbol)); 00398 if ((u != NULL) && (u->stub_unwind.stub_type == EXPORT)) 00399 { 00400 dld_cache.load_stub.address = SYMBOL_VALUE (dld_msymbol); 00401 dld_cache.load_stub.unwind = u; 00402 } 00403 } 00404 } 00405 00406 dld_msymbol = lookup_minimal_symbol ("shl_unload", NULL, objfile); 00407 if (dld_msymbol != NULL) 00408 { 00409 dld_cache.unload.address = SYMBOL_VALUE (dld_msymbol); 00410 dld_cache.unload.unwind = find_unwind_entry (dld_cache.unload.address); 00411 00412 /* ??rehrauer: I'm not sure exactly what this is, but it appears 00413 that on some HPUX 10.x versions, there's two unwind regions to 00414 cover the body of "shl_unload", the second being 4 bytes past 00415 the end of the first. This is a large hack to handle that 00416 case, but since I don't seem to have any legitimate way to 00417 look for this thing via the symbol table... */ 00418 00419 if (dld_cache.unload.unwind != NULL) 00420 { 00421 u = find_unwind_entry (dld_cache.unload.unwind->region_end + 4); 00422 if (u != NULL) 00423 { 00424 dld_cache.unload2.address = u->region_start; 00425 dld_cache.unload2.unwind = u; 00426 } 00427 } 00428 } 00429 00430 dld_msymbol = lookup_minimal_symbol_solib_trampoline ("shl_unload", 00431 objfile); 00432 if (dld_msymbol != NULL) 00433 { 00434 if (MSYMBOL_TYPE (dld_msymbol) == mst_solib_trampoline) 00435 { 00436 u = find_unwind_entry (SYMBOL_VALUE (dld_msymbol)); 00437 if ((u != NULL) && (u->stub_unwind.stub_type == EXPORT)) 00438 { 00439 dld_cache.unload_stub.address = SYMBOL_VALUE (dld_msymbol); 00440 dld_cache.unload_stub.unwind = u; 00441 } 00442 } 00443 } 00444 00445 /* Did we find everything we were looking for? If so, stop. */ 00446 if ((dld_cache.load.address != 0) 00447 && (dld_cache.load_stub.address != 0) 00448 && (dld_cache.unload.address != 0) 00449 && (dld_cache.unload_stub.address != 0)) 00450 { 00451 dld_cache.is_valid = 1; 00452 break; 00453 } 00454 } 00455 00456 dld_cache.hook.unwind = find_unwind_entry (dld_cache.hook.address); 00457 dld_cache.hook_stub.unwind = find_unwind_entry (dld_cache.hook_stub.address); 00458 00459 /* We're prepared not to find some of these symbols, which is why 00460 this function is a "desire" operation, and not a "require". */ 00461 } 00462 00463 static int 00464 som_in_dynsym_resolve_code (CORE_ADDR pc) 00465 { 00466 struct unwind_table_entry *u_pc; 00467 00468 /* Are we in the dld itself? 00469 00470 ??rehrauer: Large hack -- We'll assume that any address in a 00471 shared text region is the dld's text. This would obviously 00472 fall down if the user attached to a process, whose shlibs 00473 weren't mapped to a (writeable) private region. However, in 00474 that case the debugger probably isn't able to set the fundamental 00475 breakpoint in the dld callback anyways, so this hack should be 00476 safe. */ 00477 00478 if ((pc & (CORE_ADDR) 0xc0000000) == (CORE_ADDR) 0xc0000000) 00479 return 1; 00480 00481 /* Cache the address of some symbols that are part of the dynamic 00482 linker, if not already known. */ 00483 00484 som_solib_desire_dynamic_linker_symbols (); 00485 00486 /* Are we in the dld callback? Or its export stub? */ 00487 u_pc = find_unwind_entry (pc); 00488 if (u_pc == NULL) 00489 return 0; 00490 00491 if ((u_pc == dld_cache.hook.unwind) || (u_pc == dld_cache.hook_stub.unwind)) 00492 return 1; 00493 00494 /* Or the interface of the dld (i.e., "shl_load" or friends)? */ 00495 if ((u_pc == dld_cache.load.unwind) 00496 || (u_pc == dld_cache.unload.unwind) 00497 || (u_pc == dld_cache.unload2.unwind) 00498 || (u_pc == dld_cache.load_stub.unwind) 00499 || (u_pc == dld_cache.unload_stub.unwind)) 00500 return 1; 00501 00502 /* Apparently this address isn't part of the dld's text. */ 00503 return 0; 00504 } 00505 00506 static void 00507 som_clear_solib (void) 00508 { 00509 } 00510 00511 struct dld_list { 00512 char name[4]; 00513 char info[4]; 00514 char text_addr[4]; 00515 char text_link_addr[4]; 00516 char text_end[4]; 00517 char data_start[4]; 00518 char bss_start[4]; 00519 char data_end[4]; 00520 char got_value[4]; 00521 char next[4]; 00522 char tsd_start_addr_ptr[4]; 00523 }; 00524 00525 static CORE_ADDR 00526 link_map_start (void) 00527 { 00528 enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch ()); 00529 struct minimal_symbol *sym; 00530 CORE_ADDR addr; 00531 gdb_byte buf[4]; 00532 unsigned int dld_flags; 00533 00534 sym = lookup_minimal_symbol ("__dld_flags", NULL, NULL); 00535 if (!sym) 00536 error (_("Unable to find __dld_flags symbol in object file.")); 00537 addr = SYMBOL_VALUE_ADDRESS (sym); 00538 read_memory (addr, buf, 4); 00539 dld_flags = extract_unsigned_integer (buf, 4, byte_order); 00540 if ((dld_flags & DLD_FLAGS_LISTVALID) == 0) 00541 error (_("__dld_list is not valid according to __dld_flags.")); 00542 00543 sym = lookup_minimal_symbol ("__dld_list", NULL, NULL); 00544 if (!sym) 00545 { 00546 /* Older crt0.o files (hpux8) don't have __dld_list as a symbol, 00547 but the data is still available if you know where to look. */ 00548 sym = lookup_minimal_symbol ("__dld_flags", NULL, NULL); 00549 if (!sym) 00550 { 00551 error (_("Unable to find dynamic library list.")); 00552 return 0; 00553 } 00554 addr = SYMBOL_VALUE_ADDRESS (sym) - 8; 00555 } 00556 else 00557 addr = SYMBOL_VALUE_ADDRESS (sym); 00558 00559 read_memory (addr, buf, 4); 00560 addr = extract_unsigned_integer (buf, 4, byte_order); 00561 if (addr == 0) 00562 return 0; 00563 00564 read_memory (addr, buf, 4); 00565 return extract_unsigned_integer (buf, 4, byte_order); 00566 } 00567 00568 /* Does this so's name match the main binary? */ 00569 static int 00570 match_main (const char *name) 00571 { 00572 return strcmp (name, objfile_name (symfile_objfile)) == 0; 00573 } 00574 00575 static struct so_list * 00576 som_current_sos (void) 00577 { 00578 enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch ()); 00579 CORE_ADDR lm; 00580 struct so_list *head = 0; 00581 struct so_list **link_ptr = &head; 00582 00583 for (lm = link_map_start (); lm; ) 00584 { 00585 char *namebuf; 00586 CORE_ADDR addr; 00587 struct so_list *new; 00588 struct cleanup *old_chain; 00589 int errcode; 00590 struct dld_list dbuf; 00591 gdb_byte tsdbuf[4]; 00592 00593 new = (struct so_list *) xmalloc (sizeof (struct so_list)); 00594 old_chain = make_cleanup (xfree, new); 00595 00596 memset (new, 0, sizeof (*new)); 00597 new->lm_info = xmalloc (sizeof (struct lm_info)); 00598 make_cleanup (xfree, new->lm_info); 00599 00600 read_memory (lm, (gdb_byte *)&dbuf, sizeof (struct dld_list)); 00601 00602 addr = extract_unsigned_integer ((gdb_byte *)&dbuf.name, 00603 sizeof (dbuf.name), byte_order); 00604 target_read_string (addr, &namebuf, SO_NAME_MAX_PATH_SIZE - 1, &errcode); 00605 if (errcode != 0) 00606 warning (_("Can't read pathname for load map: %s."), 00607 safe_strerror (errcode)); 00608 else 00609 { 00610 strncpy (new->so_name, namebuf, SO_NAME_MAX_PATH_SIZE - 1); 00611 new->so_name[SO_NAME_MAX_PATH_SIZE - 1] = '\0'; 00612 xfree (namebuf); 00613 strcpy (new->so_original_name, new->so_name); 00614 } 00615 00616 if (new->so_name[0] && !match_main (new->so_name)) 00617 { 00618 struct lm_info *lmi = new->lm_info; 00619 unsigned int tmp; 00620 00621 lmi->lm_addr = lm; 00622 00623 #define EXTRACT(_fld) \ 00624 extract_unsigned_integer ((gdb_byte *)&dbuf._fld, \ 00625 sizeof (dbuf._fld), byte_order); 00626 00627 lmi->text_addr = EXTRACT (text_addr); 00628 tmp = EXTRACT (info); 00629 lmi->library_version = (tmp >> 16) & 0xffff; 00630 lmi->bind_mode = (tmp >> 8) & 0xff; 00631 lmi->struct_version = tmp & 0xff; 00632 lmi->text_link_addr = EXTRACT (text_link_addr); 00633 lmi->text_end = EXTRACT (text_end); 00634 lmi->data_start = EXTRACT (data_start); 00635 lmi->bss_start = EXTRACT (bss_start); 00636 lmi->data_end = EXTRACT (data_end); 00637 lmi->got_value = EXTRACT (got_value); 00638 tmp = EXTRACT (tsd_start_addr_ptr); 00639 read_memory (tmp, tsdbuf, 4); 00640 lmi->tsd_start_addr 00641 = extract_unsigned_integer (tsdbuf, 4, byte_order); 00642 00643 #ifdef SOLIB_SOM_DBG 00644 printf ("\n+ library \"%s\" is described at %s\n", new->so_name, 00645 paddress (target_gdbarch (), lm)); 00646 printf (" 'version' is %d\n", new->lm_info->struct_version); 00647 printf (" 'bind_mode' is %d\n", new->lm_info->bind_mode); 00648 printf (" 'library_version' is %d\n", 00649 new->lm_info->library_version); 00650 printf (" 'text_addr' is %s\n", 00651 paddress (target_gdbarch (), new->lm_info->text_addr)); 00652 printf (" 'text_link_addr' is %s\n", 00653 paddress (target_gdbarch (), new->lm_info->text_link_addr)); 00654 printf (" 'text_end' is %s\n", 00655 paddress (target_gdbarch (), new->lm_info->text_end)); 00656 printf (" 'data_start' is %s\n", 00657 paddress (target_gdbarch (), new->lm_info->data_start)); 00658 printf (" 'bss_start' is %s\n", 00659 paddress (target_gdbarch (), new->lm_info->bss_start)); 00660 printf (" 'data_end' is %s\n", 00661 paddress (target_gdbarch (), new->lm_info->data_end)); 00662 printf (" 'got_value' is %s\n", 00663 paddress (target_gdbarch (), new->lm_info->got_value)); 00664 printf (" 'tsd_start_addr' is %s\n", 00665 paddress (target_gdbarch (), new->lm_info->tsd_start_addr)); 00666 #endif 00667 00668 new->addr_low = lmi->text_addr; 00669 new->addr_high = lmi->text_end; 00670 00671 /* Link the new object onto the list. */ 00672 new->next = NULL; 00673 *link_ptr = new; 00674 link_ptr = &new->next; 00675 } 00676 else 00677 { 00678 free_so (new); 00679 } 00680 00681 lm = EXTRACT (next); 00682 discard_cleanups (old_chain); 00683 #undef EXTRACT 00684 } 00685 00686 /* TODO: The original somsolib code has logic to detect and eliminate 00687 duplicate entries. Do we need that? */ 00688 00689 return head; 00690 } 00691 00692 static int 00693 som_open_symbol_file_object (void *from_ttyp) 00694 { 00695 enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch ()); 00696 CORE_ADDR lm, l_name; 00697 char *filename; 00698 int errcode; 00699 int from_tty = *(int *)from_ttyp; 00700 gdb_byte buf[4]; 00701 struct cleanup *cleanup; 00702 00703 if (symfile_objfile) 00704 if (!query (_("Attempt to reload symbols from process? "))) 00705 return 0; 00706 00707 /* First link map member should be the executable. */ 00708 if ((lm = link_map_start ()) == 0) 00709 return 0; /* failed somehow... */ 00710 00711 /* Read address of name from target memory to GDB. */ 00712 read_memory (lm + offsetof (struct dld_list, name), buf, 4); 00713 00714 /* Convert the address to host format. Assume that the address is 00715 unsigned. */ 00716 l_name = extract_unsigned_integer (buf, 4, byte_order); 00717 00718 if (l_name == 0) 00719 return 0; /* No filename. */ 00720 00721 /* Now fetch the filename from target memory. */ 00722 target_read_string (l_name, &filename, SO_NAME_MAX_PATH_SIZE - 1, &errcode); 00723 00724 if (errcode) 00725 { 00726 warning (_("failed to read exec filename from attached file: %s"), 00727 safe_strerror (errcode)); 00728 return 0; 00729 } 00730 00731 cleanup = make_cleanup (xfree, filename); 00732 /* Have a pathname: read the symbol file. */ 00733 symbol_file_add_main (filename, from_tty); 00734 00735 do_cleanups (cleanup); 00736 return 1; 00737 } 00738 00739 static void 00740 som_free_so (struct so_list *so) 00741 { 00742 xfree (so->lm_info); 00743 } 00744 00745 static CORE_ADDR 00746 som_solib_thread_start_addr (struct so_list *so) 00747 { 00748 return so->lm_info->tsd_start_addr; 00749 } 00750 00751 /* Return the GOT value for the shared library in which ADDR belongs. If 00752 ADDR isn't in any known shared library, return zero. */ 00753 00754 static CORE_ADDR 00755 som_solib_get_got_by_pc (CORE_ADDR addr) 00756 { 00757 struct so_list *so_list = master_so_list (); 00758 CORE_ADDR got_value = 0; 00759 00760 while (so_list) 00761 { 00762 if (so_list->lm_info->text_addr <= addr 00763 && so_list->lm_info->text_end > addr) 00764 { 00765 got_value = so_list->lm_info->got_value; 00766 break; 00767 } 00768 so_list = so_list->next; 00769 } 00770 return got_value; 00771 } 00772 00773 /* Return the address of the handle of the shared library in which 00774 ADDR belongs. If ADDR isn't in any known shared library, return 00775 zero. */ 00776 /* This function is used in initialize_hp_cxx_exception_support in 00777 hppa-hpux-tdep.c. */ 00778 00779 static CORE_ADDR 00780 som_solib_get_solib_by_pc (CORE_ADDR addr) 00781 { 00782 struct so_list *so_list = master_so_list (); 00783 00784 while (so_list) 00785 { 00786 if (so_list->lm_info->text_addr <= addr 00787 && so_list->lm_info->text_end > addr) 00788 { 00789 break; 00790 } 00791 so_list = so_list->next; 00792 } 00793 if (so_list) 00794 return so_list->lm_info->lm_addr; 00795 else 00796 return 0; 00797 } 00798 00799 00800 static struct target_so_ops som_so_ops; 00801 00802 extern initialize_file_ftype _initialize_som_solib; /* -Wmissing-prototypes */ 00803 00804 void 00805 _initialize_som_solib (void) 00806 { 00807 som_so_ops.relocate_section_addresses = som_relocate_section_addresses; 00808 som_so_ops.free_so = som_free_so; 00809 som_so_ops.clear_solib = som_clear_solib; 00810 som_so_ops.solib_create_inferior_hook = som_solib_create_inferior_hook; 00811 som_so_ops.special_symbol_handling = som_special_symbol_handling; 00812 som_so_ops.current_sos = som_current_sos; 00813 som_so_ops.open_symbol_file_object = som_open_symbol_file_object; 00814 som_so_ops.in_dynsym_resolve_code = som_in_dynsym_resolve_code; 00815 som_so_ops.bfd_open = solib_bfd_open; 00816 } 00817 00818 void 00819 som_solib_select (struct gdbarch *gdbarch) 00820 { 00821 struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); 00822 00823 set_solib_ops (gdbarch, &som_so_ops); 00824 tdep->solib_thread_start_addr = som_solib_thread_start_addr; 00825 tdep->solib_get_got_by_pc = som_solib_get_got_by_pc; 00826 tdep->solib_get_solib_by_pc = som_solib_get_solib_by_pc; 00827 } 00828 00829 /* The rest of these functions are not part of the solib interface; they 00830 are used by somread.c or hppa-hpux-tdep.c. */ 00831 00832 int 00833 som_solib_section_offsets (struct objfile *objfile, 00834 struct section_offsets *offsets) 00835 { 00836 struct so_list *so_list = master_so_list (); 00837 00838 while (so_list) 00839 { 00840 /* Oh what a pain! We need the offsets before so_list->objfile 00841 is valid. The BFDs will never match. Make a best guess. */ 00842 if (strstr (objfile_name (objfile), so_list->so_name)) 00843 { 00844 asection *private_section; 00845 struct obj_section *sect; 00846 00847 /* The text offset is easy. */ 00848 offsets->offsets[SECT_OFF_TEXT (objfile)] 00849 = (so_list->lm_info->text_addr 00850 - so_list->lm_info->text_link_addr); 00851 00852 /* We should look at presumed_dp in the SOM header, but 00853 that's not easily available. This should be OK though. */ 00854 private_section = bfd_get_section_by_name (objfile->obfd, 00855 "$PRIVATE$"); 00856 if (!private_section) 00857 { 00858 warning (_("Unable to find $PRIVATE$ in shared library!")); 00859 offsets->offsets[SECT_OFF_DATA (objfile)] = 0; 00860 offsets->offsets[SECT_OFF_BSS (objfile)] = 0; 00861 return 1; 00862 } 00863 if (objfile->sect_index_data != -1) 00864 { 00865 offsets->offsets[SECT_OFF_DATA (objfile)] 00866 = (so_list->lm_info->data_start - private_section->vma); 00867 if (objfile->sect_index_bss != -1) 00868 offsets->offsets[SECT_OFF_BSS (objfile)] 00869 = ANOFFSET (offsets, SECT_OFF_DATA (objfile)); 00870 } 00871 00872 ALL_OBJFILE_OSECTIONS (objfile, sect) 00873 { 00874 flagword flags = bfd_get_section_flags (objfile->obfd, 00875 sect->the_bfd_section); 00876 00877 if ((flags & SEC_CODE) != 0) 00878 offsets->offsets[sect->the_bfd_section->index] 00879 = offsets->offsets[SECT_OFF_TEXT (objfile)]; 00880 else 00881 offsets->offsets[sect->the_bfd_section->index] 00882 = offsets->offsets[SECT_OFF_DATA (objfile)]; 00883 } 00884 00885 return 1; 00886 } 00887 so_list = so_list->next; 00888 } 00889 return 0; 00890 }