GDB (API)
/home/stan/gdb/src/gdb/solib-pa64.c
Go to the documentation of this file.
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
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines