GDB (API)
|
00001 /* Handle PA64 shared libraries for GDB, the GNU Debugger. 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 /* HP in their infinite stupidity choose not to use standard ELF dynamic 00021 linker interfaces. They also choose not to make their ELF dymamic 00022 linker interfaces compatible with the SOM dynamic linker. The 00023 net result is we can not use either of the existing somsolib.c or 00024 solib.c. What a crock. 00025 00026 Even more disgusting. This file depends on functions provided only 00027 in certain PA64 libraries. Thus this file is supposed to only be 00028 used native. When will HP ever learn that they need to provide the 00029 same functionality in all their libraries! */ 00030 00031 #include "defs.h" 00032 #include "symtab.h" 00033 #include "bfd.h" 00034 #include "symfile.h" 00035 #include "objfiles.h" 00036 #include "gdbcore.h" 00037 #include "target.h" 00038 #include "inferior.h" 00039 #include "regcache.h" 00040 #include "gdb_bfd.h" 00041 00042 #include "hppa-tdep.h" 00043 #include "solist.h" 00044 #include "solib.h" 00045 #include "solib-pa64.h" 00046 00047 #undef SOLIB_PA64_DBG 00048 00049 /* We can build this file only when running natively on 64-bit HP/UX. 00050 We check for that by checking for the elf_hp.h header file. */ 00051 #if defined(HAVE_ELF_HP_H) && defined(__LP64__) 00052 00053 /* FIXME: kettenis/20041213: These includes should be eliminated. */ 00054 #include <dlfcn.h> 00055 #include <elf.h> 00056 #include <elf_hp.h> 00057 00058 struct lm_info { 00059 struct load_module_desc desc; 00060 CORE_ADDR desc_addr; 00061 }; 00062 00063 /* When adding fields, be sure to clear them in _initialize_pa64_solib. */ 00064 typedef struct 00065 { 00066 CORE_ADDR dld_flags_addr; 00067 LONGEST dld_flags; 00068 struct bfd_section *dyninfo_sect; 00069 int have_read_dld_descriptor; 00070 int is_valid; 00071 CORE_ADDR load_map; 00072 CORE_ADDR load_map_addr; 00073 struct load_module_desc dld_desc; 00074 } 00075 dld_cache_t; 00076 00077 static dld_cache_t dld_cache; 00078 00079 static int read_dynamic_info (asection *dyninfo_sect, 00080 dld_cache_t *dld_cache_p); 00081 00082 static void 00083 pa64_relocate_section_addresses (struct so_list *so, 00084 struct target_section *sec) 00085 { 00086 asection *asec = sec->the_bfd_section; 00087 CORE_ADDR load_offset; 00088 00089 /* Relocate all the sections based on where they got loaded. */ 00090 00091 load_offset = bfd_section_vma (so->abfd, asec) - asec->filepos; 00092 00093 if (asec->flags & SEC_CODE) 00094 { 00095 sec->addr += so->lm_info->desc.text_base - load_offset; 00096 sec->endaddr += so->lm_info->desc.text_base - load_offset; 00097 } 00098 else if (asec->flags & SEC_DATA) 00099 { 00100 sec->addr += so->lm_info->desc.data_base - load_offset; 00101 sec->endaddr += so->lm_info->desc.data_base - load_offset; 00102 } 00103 } 00104 00105 static void 00106 pa64_free_so (struct so_list *so) 00107 { 00108 xfree (so->lm_info); 00109 } 00110 00111 static void 00112 pa64_clear_solib (void) 00113 { 00114 } 00115 00116 /* Wrapper for target_read_memory for dlgetmodinfo. */ 00117 00118 static void * 00119 pa64_target_read_memory (void *buffer, CORE_ADDR ptr, size_t bufsiz, int ident) 00120 { 00121 if (target_read_memory (ptr, buffer, bufsiz) != 0) 00122 return 0; 00123 return buffer; 00124 } 00125 00126 /* Read the dynamic linker's internal shared library descriptor. 00127 00128 This must happen after dld starts running, so we can't do it in 00129 read_dynamic_info. Record the fact that we have loaded the 00130 descriptor. If the library is archive bound or the load map 00131 hasn't been setup, then return zero; else return nonzero. */ 00132 00133 static int 00134 read_dld_descriptor (void) 00135 { 00136 char *dll_path; 00137 asection *dyninfo_sect; 00138 00139 /* If necessary call read_dynamic_info to extract the contents of the 00140 .dynamic section from the shared library. */ 00141 if (!dld_cache.is_valid) 00142 { 00143 if (symfile_objfile == NULL) 00144 error (_("No object file symbols.")); 00145 00146 dyninfo_sect = bfd_get_section_by_name (symfile_objfile->obfd, 00147 ".dynamic"); 00148 if (!dyninfo_sect) 00149 { 00150 return 0; 00151 } 00152 00153 if (!read_dynamic_info (dyninfo_sect, &dld_cache)) 00154 error (_("Unable to read in .dynamic section information.")); 00155 } 00156 00157 /* Read the load map pointer. */ 00158 if (target_read_memory (dld_cache.load_map_addr, 00159 (char *) &dld_cache.load_map, 00160 sizeof (dld_cache.load_map)) 00161 != 0) 00162 { 00163 error (_("Error while reading in load map pointer.")); 00164 } 00165 00166 if (!dld_cache.load_map) 00167 return 0; 00168 00169 /* Read in the dld load module descriptor. */ 00170 if (dlgetmodinfo (-1, 00171 &dld_cache.dld_desc, 00172 sizeof (dld_cache.dld_desc), 00173 pa64_target_read_memory, 00174 0, 00175 dld_cache.load_map) 00176 == 0) 00177 { 00178 error (_("Error trying to get information about dynamic linker.")); 00179 } 00180 00181 /* Indicate that we have loaded the dld descriptor. */ 00182 dld_cache.have_read_dld_descriptor = 1; 00183 00184 return 1; 00185 } 00186 00187 00188 /* Read the .dynamic section and extract the information of interest, 00189 which is stored in dld_cache. The routine elf_locate_base in solib.c 00190 was used as a model for this. */ 00191 00192 static int 00193 read_dynamic_info (asection *dyninfo_sect, dld_cache_t *dld_cache_p) 00194 { 00195 char *buf; 00196 char *bufend; 00197 CORE_ADDR dyninfo_addr; 00198 int dyninfo_sect_size; 00199 CORE_ADDR entry_addr; 00200 00201 /* Read in .dynamic section, silently ignore errors. */ 00202 dyninfo_addr = bfd_section_vma (symfile_objfile->obfd, dyninfo_sect); 00203 dyninfo_sect_size = bfd_section_size (exec_bfd, dyninfo_sect); 00204 buf = alloca (dyninfo_sect_size); 00205 if (target_read_memory (dyninfo_addr, buf, dyninfo_sect_size)) 00206 return 0; 00207 00208 /* Scan the .dynamic section and record the items of interest. 00209 In particular, DT_HP_DLD_FLAGS. */ 00210 for (bufend = buf + dyninfo_sect_size, entry_addr = dyninfo_addr; 00211 buf < bufend; 00212 buf += sizeof (Elf64_Dyn), entry_addr += sizeof (Elf64_Dyn)) 00213 { 00214 Elf64_Dyn *x_dynp = (Elf64_Dyn*)buf; 00215 Elf64_Sxword dyn_tag; 00216 CORE_ADDR dyn_ptr; 00217 00218 dyn_tag = bfd_h_get_64 (symfile_objfile->obfd, 00219 (bfd_byte*) &x_dynp->d_tag); 00220 00221 /* We can't use a switch here because dyn_tag is 64 bits and HP's 00222 lame comiler does not handle 64bit items in switch statements. */ 00223 if (dyn_tag == DT_NULL) 00224 break; 00225 else if (dyn_tag == DT_HP_DLD_FLAGS) 00226 { 00227 /* Set dld_flags_addr and dld_flags in *dld_cache_p. */ 00228 dld_cache_p->dld_flags_addr = entry_addr + offsetof(Elf64_Dyn, d_un); 00229 if (target_read_memory (dld_cache_p->dld_flags_addr, 00230 (char*) &dld_cache_p->dld_flags, 00231 sizeof (dld_cache_p->dld_flags)) 00232 != 0) 00233 { 00234 error (_("Error while reading in " 00235 ".dynamic section of the program.")); 00236 } 00237 } 00238 else if (dyn_tag == DT_HP_LOAD_MAP) 00239 { 00240 /* Dld will place the address of the load map at load_map_addr 00241 after it starts running. */ 00242 if (target_read_memory (entry_addr + offsetof(Elf64_Dyn, 00243 d_un.d_ptr), 00244 (char*) &dld_cache_p->load_map_addr, 00245 sizeof (dld_cache_p->load_map_addr)) 00246 != 0) 00247 { 00248 error (_("Error while reading in " 00249 ".dynamic section of the program.")); 00250 } 00251 } 00252 else 00253 { 00254 /* Tag is not of interest. */ 00255 } 00256 } 00257 00258 /* Record other information and set is_valid to 1. */ 00259 dld_cache_p->dyninfo_sect = dyninfo_sect; 00260 00261 /* Verify that we read in required info. These fields are re-set to zero 00262 in pa64_solib_restart. */ 00263 00264 if (dld_cache_p->dld_flags_addr != 0 && dld_cache_p->load_map_addr != 0) 00265 dld_cache_p->is_valid = 1; 00266 else 00267 return 0; 00268 00269 return 1; 00270 } 00271 00272 /* Helper function for gdb_bfd_lookup_symbol_from_symtab. */ 00273 00274 static int 00275 cmp_name (asymbol *sym, void *data) 00276 { 00277 return (strcmp (sym->name, (const char *) data) == 0); 00278 } 00279 00280 /* This hook gets called just before the first instruction in the 00281 inferior process is executed. 00282 00283 This is our opportunity to set magic flags in the inferior so 00284 that GDB can be notified when a shared library is mapped in and 00285 to tell the dynamic linker that a private copy of the library is 00286 needed (so GDB can set breakpoints in the library). 00287 00288 We need to set DT_HP_DEBUG_CALLBACK to indicate that we want the 00289 dynamic linker to call the breakpoint routine for significant events. 00290 We used to set DT_HP_DEBUG_PRIVATE to indicate that shared libraries 00291 should be mapped private. However, this flag can be set using 00292 "chatr +dbg enable". Not setting DT_HP_DEBUG_PRIVATE allows debugging 00293 with shared libraries mapped shareable. */ 00294 00295 static void 00296 pa64_solib_create_inferior_hook (int from_tty) 00297 { 00298 struct minimal_symbol *msymbol; 00299 unsigned int dld_flags, status; 00300 asection *shlib_info, *interp_sect; 00301 struct objfile *objfile; 00302 CORE_ADDR anaddr; 00303 00304 if (symfile_objfile == NULL) 00305 return; 00306 00307 /* First see if the objfile was dynamically linked. */ 00308 shlib_info = bfd_get_section_by_name (symfile_objfile->obfd, ".dynamic"); 00309 if (!shlib_info) 00310 return; 00311 00312 /* It's got a .dynamic section, make sure it's not empty. */ 00313 if (bfd_section_size (symfile_objfile->obfd, shlib_info) == 0) 00314 return; 00315 00316 /* Read in the .dynamic section. */ 00317 if (! read_dynamic_info (shlib_info, &dld_cache)) 00318 error (_("Unable to read the .dynamic section.")); 00319 00320 /* If the libraries were not mapped private, warn the user. */ 00321 if ((dld_cache.dld_flags & DT_HP_DEBUG_PRIVATE) == 0) 00322 warning 00323 (_("\ 00324 Private mapping of shared library text was not specified\n\ 00325 by the executable; setting a breakpoint in a shared library which\n\ 00326 is not privately mapped will not work. See the HP-UX 11i v3 chatr\n\ 00327 manpage for methods to privately map shared library text.")); 00328 00329 /* Turn on the flags we care about. */ 00330 dld_cache.dld_flags |= DT_HP_DEBUG_CALLBACK; 00331 status = target_write_memory (dld_cache.dld_flags_addr, 00332 (char *) &dld_cache.dld_flags, 00333 sizeof (dld_cache.dld_flags)); 00334 if (status != 0) 00335 error (_("Unable to modify dynamic linker flags.")); 00336 00337 /* Now we have to create a shared library breakpoint in the dynamic 00338 linker. This can be somewhat tricky since the symbol is inside 00339 the dynamic linker (for which we do not have symbols or a base 00340 load address! Luckily I wrote this code for solib.c years ago. */ 00341 interp_sect = bfd_get_section_by_name (exec_bfd, ".interp"); 00342 if (interp_sect) 00343 { 00344 unsigned int interp_sect_size; 00345 char *buf; 00346 CORE_ADDR load_addr; 00347 bfd *tmp_bfd; 00348 CORE_ADDR sym_addr = 0; 00349 00350 /* Read the contents of the .interp section into a local buffer; 00351 the contents specify the dynamic linker this program uses. */ 00352 interp_sect_size = bfd_section_size (exec_bfd, interp_sect); 00353 buf = alloca (interp_sect_size); 00354 bfd_get_section_contents (exec_bfd, interp_sect, 00355 buf, 0, interp_sect_size); 00356 00357 /* Now we need to figure out where the dynamic linker was 00358 loaded so that we can load its symbols and place a breakpoint 00359 in the dynamic linker itself. 00360 00361 This address is stored on the stack. However, I've been unable 00362 to find any magic formula to find it for Solaris (appears to 00363 be trivial on GNU/Linux). Therefore, we have to try an alternate 00364 mechanism to find the dynamic linker's base address. */ 00365 tmp_bfd = gdb_bfd_open (buf, gnutarget, -1); 00366 if (tmp_bfd == NULL) 00367 return; 00368 00369 /* Make sure the dynamic linker's really a useful object. */ 00370 if (!bfd_check_format (tmp_bfd, bfd_object)) 00371 { 00372 warning (_("Unable to grok dynamic linker %s as an object file"), 00373 buf); 00374 gdb_bfd_unref (tmp_bfd); 00375 return; 00376 } 00377 00378 /* We find the dynamic linker's base address by examining the 00379 current pc (which point at the entry point for the dynamic 00380 linker) and subtracting the offset of the entry point. 00381 00382 Also note the breakpoint is the second instruction in the 00383 routine. */ 00384 load_addr = regcache_read_pc (get_current_regcache ()) 00385 - tmp_bfd->start_address; 00386 sym_addr = gdb_bfd_lookup_symbol_from_symtab (tmp_bfd, cmp_name, 00387 "__dld_break"); 00388 sym_addr = load_addr + sym_addr + 4; 00389 00390 /* Create the shared library breakpoint. */ 00391 { 00392 struct breakpoint *b 00393 = create_solib_event_breakpoint (target_gdbarch (), sym_addr); 00394 00395 /* The breakpoint is actually hard-coded into the dynamic linker, 00396 so we don't need to actually insert a breakpoint instruction 00397 there. In fact, the dynamic linker's code is immutable, even to 00398 ttrace, so we shouldn't even try to do that. For cases like 00399 this, we have "permanent" breakpoints. */ 00400 make_breakpoint_permanent (b); 00401 } 00402 00403 /* We're done with the temporary bfd. */ 00404 gdb_bfd_unref (tmp_bfd); 00405 } 00406 } 00407 00408 static void 00409 pa64_special_symbol_handling (void) 00410 { 00411 } 00412 00413 static struct so_list * 00414 pa64_current_sos (void) 00415 { 00416 struct so_list *head = 0; 00417 struct so_list **link_ptr = &head; 00418 int dll_index; 00419 00420 /* Read in the load map pointer if we have not done so already. */ 00421 if (! dld_cache.have_read_dld_descriptor) 00422 if (! read_dld_descriptor ()) 00423 return NULL; 00424 00425 for (dll_index = -1; ; dll_index++) 00426 { 00427 struct load_module_desc dll_desc; 00428 char *dll_path; 00429 struct so_list *new; 00430 struct cleanup *old_chain; 00431 00432 if (dll_index == 0) 00433 continue; 00434 00435 /* Read in the load module descriptor. */ 00436 if (dlgetmodinfo (dll_index, &dll_desc, sizeof (dll_desc), 00437 pa64_target_read_memory, 0, dld_cache.load_map) 00438 == 0) 00439 break; 00440 00441 /* Get the name of the shared library. */ 00442 dll_path = (char *)dlgetname (&dll_desc, sizeof (dll_desc), 00443 pa64_target_read_memory, 00444 0, dld_cache.load_map); 00445 00446 new = (struct so_list *) xmalloc (sizeof (struct so_list)); 00447 memset (new, 0, sizeof (struct so_list)); 00448 new->lm_info = (struct lm_info *) xmalloc (sizeof (struct lm_info)); 00449 memset (new->lm_info, 0, sizeof (struct lm_info)); 00450 00451 strncpy (new->so_name, dll_path, SO_NAME_MAX_PATH_SIZE - 1); 00452 new->so_name[SO_NAME_MAX_PATH_SIZE - 1] = '\0'; 00453 strcpy (new->so_original_name, new->so_name); 00454 00455 memcpy (&new->lm_info->desc, &dll_desc, sizeof (dll_desc)); 00456 00457 #ifdef SOLIB_PA64_DBG 00458 { 00459 struct load_module_desc *d = &new->lm_info->desc; 00460 00461 printf ("\n+ library \"%s\" is described at index %d\n", new->so_name, 00462 dll_index); 00463 printf (" text_base = %s\n", hex_string (d->text_base)); 00464 printf (" text_size = %s\n", hex_string (d->text_size)); 00465 printf (" data_base = %s\n", hex_string (d->data_base)); 00466 printf (" data_size = %s\n", hex_string (d->data_size)); 00467 printf (" unwind_base = %s\n", hex_string (d->unwind_base)); 00468 printf (" linkage_ptr = %s\n", hex_string (d->linkage_ptr)); 00469 printf (" phdr_base = %s\n", hex_string (d->phdr_base)); 00470 printf (" tls_size = %s\n", hex_string (d->tls_size)); 00471 printf (" tls_start_addr = %s\n", hex_string (d->tls_start_addr)); 00472 printf (" unwind_size = %s\n", hex_string (d->unwind_size)); 00473 printf (" tls_index = %s\n", hex_string (d->tls_index)); 00474 } 00475 #endif 00476 00477 /* Link the new object onto the list. */ 00478 new->next = NULL; 00479 *link_ptr = new; 00480 link_ptr = &new->next; 00481 } 00482 00483 return head; 00484 } 00485 00486 static int 00487 pa64_open_symbol_file_object (void *from_ttyp) 00488 { 00489 int from_tty = *(int *)from_ttyp; 00490 struct load_module_desc dll_desc; 00491 char *dll_path; 00492 00493 if (symfile_objfile) 00494 if (!query (_("Attempt to reload symbols from process? "))) 00495 return 0; 00496 00497 /* Read in the load map pointer if we have not done so already. */ 00498 if (! dld_cache.have_read_dld_descriptor) 00499 if (! read_dld_descriptor ()) 00500 return 0; 00501 00502 /* Read in the load module descriptor. */ 00503 if (dlgetmodinfo (0, &dll_desc, sizeof (dll_desc), 00504 pa64_target_read_memory, 0, dld_cache.load_map) == 0) 00505 return 0; 00506 00507 /* Get the name of the shared library. */ 00508 dll_path = (char *)dlgetname (&dll_desc, sizeof (dll_desc), 00509 pa64_target_read_memory, 00510 0, dld_cache.load_map); 00511 00512 /* Have a pathname: read the symbol file. */ 00513 symbol_file_add_main (dll_path, from_tty); 00514 00515 return 1; 00516 } 00517 00518 /* Return nonzero if PC is an address inside the dynamic linker. */ 00519 static int 00520 pa64_in_dynsym_resolve_code (CORE_ADDR pc) 00521 { 00522 asection *shlib_info; 00523 00524 if (symfile_objfile == NULL) 00525 return 0; 00526 00527 if (!dld_cache.have_read_dld_descriptor) 00528 if (!read_dld_descriptor ()) 00529 return 0; 00530 00531 return (pc >= dld_cache.dld_desc.text_base 00532 && pc < dld_cache.dld_desc.text_base + dld_cache.dld_desc.text_size); 00533 } 00534 00535 00536 /* Return the GOT value for the shared library in which ADDR belongs. If 00537 ADDR isn't in any known shared library, return zero. */ 00538 00539 static CORE_ADDR 00540 pa64_solib_get_got_by_pc (CORE_ADDR addr) 00541 { 00542 struct so_list *so_list = master_so_list (); 00543 CORE_ADDR got_value = 0; 00544 00545 while (so_list) 00546 { 00547 if (so_list->lm_info->desc.text_base <= addr 00548 && ((so_list->lm_info->desc.text_base 00549 + so_list->lm_info->desc.text_size) 00550 > addr)) 00551 { 00552 got_value = so_list->lm_info->desc.linkage_ptr; 00553 break; 00554 } 00555 so_list = so_list->next; 00556 } 00557 return got_value; 00558 } 00559 00560 /* Get some HPUX-specific data from a shared lib. */ 00561 static CORE_ADDR 00562 pa64_solib_thread_start_addr (struct so_list *so) 00563 { 00564 return so->lm_info->desc.tls_start_addr; 00565 } 00566 00567 00568 /* Return the address of the handle of the shared library in which ADDR 00569 belongs. If ADDR isn't in any known shared library, return zero. */ 00570 00571 static CORE_ADDR 00572 pa64_solib_get_solib_by_pc (CORE_ADDR addr) 00573 { 00574 struct so_list *so_list = master_so_list (); 00575 CORE_ADDR retval = 0; 00576 00577 while (so_list) 00578 { 00579 if (so_list->lm_info->desc.text_base <= addr 00580 && ((so_list->lm_info->desc.text_base 00581 + so_list->lm_info->desc.text_size) 00582 > addr)) 00583 { 00584 retval = so_list->lm_info->desc_addr; 00585 break; 00586 } 00587 so_list = so_list->next; 00588 } 00589 return retval; 00590 } 00591 00592 /* pa64 libraries do not seem to set the section offsets in a standard (i.e. 00593 SVr4) way; the text section offset stored in the file doesn't correspond 00594 to the place where the library is actually loaded into memory. Instead, 00595 we rely on the dll descriptor to tell us where things were loaded. */ 00596 static CORE_ADDR 00597 pa64_solib_get_text_base (struct objfile *objfile) 00598 { 00599 struct so_list *so; 00600 00601 for (so = master_so_list (); so; so = so->next) 00602 if (so->objfile == objfile) 00603 return so->lm_info->desc.text_base; 00604 00605 return 0; 00606 } 00607 00608 static struct target_so_ops pa64_so_ops; 00609 00610 extern initialize_file_ftype _initialize_pa64_solib; /* -Wmissing-prototypes */ 00611 00612 void 00613 _initialize_pa64_solib (void) 00614 { 00615 pa64_so_ops.relocate_section_addresses = pa64_relocate_section_addresses; 00616 pa64_so_ops.free_so = pa64_free_so; 00617 pa64_so_ops.clear_solib = pa64_clear_solib; 00618 pa64_so_ops.solib_create_inferior_hook = pa64_solib_create_inferior_hook; 00619 pa64_so_ops.special_symbol_handling = pa64_special_symbol_handling; 00620 pa64_so_ops.current_sos = pa64_current_sos; 00621 pa64_so_ops.open_symbol_file_object = pa64_open_symbol_file_object; 00622 pa64_so_ops.in_dynsym_resolve_code = pa64_in_dynsym_resolve_code; 00623 pa64_so_ops.bfd_open = solib_bfd_open; 00624 00625 memset (&dld_cache, 0, sizeof (dld_cache)); 00626 } 00627 00628 void pa64_solib_select (struct gdbarch *gdbarch) 00629 { 00630 struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); 00631 00632 set_solib_ops (gdbarch, &pa64_so_ops); 00633 tdep->solib_thread_start_addr = pa64_solib_thread_start_addr; 00634 tdep->solib_get_got_by_pc = pa64_solib_get_got_by_pc; 00635 tdep->solib_get_solib_by_pc = pa64_solib_get_solib_by_pc; 00636 tdep->solib_get_text_base = pa64_solib_get_text_base; 00637 } 00638 00639 #else /* HAVE_ELF_HP_H */ 00640 00641 extern initialize_file_ftype _initialize_pa64_solib; /* -Wmissing-prototypes */ 00642 00643 void 00644 _initialize_pa64_solib (void) 00645 { 00646 } 00647 00648 void pa64_solib_select (struct gdbarch *gdbarch) 00649 { 00650 /* For a SOM-only target, there is no pa64 solib support. This is needed 00651 for hppa-hpux-tdep.c to build. */ 00652 error (_("Cannot select pa64 solib support for this configuration.")); 00653 } 00654 #endif