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