GDB (API)
/home/stan/gdb/src/gdb/solib-irix.c
Go to the documentation of this file.
00001 /* Shared library support for IRIX.
00002    Copyright (C) 1993-2013 Free Software Foundation, Inc.
00003 
00004    This file was created using portions of irix5-nat.c originally
00005    contributed to GDB by Ian Lance Taylor.
00006 
00007    This file is part of GDB.
00008 
00009    This program is free software; you can redistribute it and/or modify
00010    it under the terms of the GNU General Public License as published by
00011    the Free Software Foundation; either version 3 of the License, or
00012    (at your option) any later version.
00013 
00014    This program is distributed in the hope that it will be useful,
00015    but WITHOUT ANY WARRANTY; without even the implied warranty of
00016    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00017    GNU General Public License for more details.
00018 
00019    You should have received a copy of the GNU General Public License
00020    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
00021 
00022 #include "defs.h"
00023 
00024 #include "symtab.h"
00025 #include "bfd.h"
00026 /* FIXME: ezannoni/2004-02-13 Verify that the include below is
00027    really needed.  */
00028 #include "symfile.h"
00029 #include "objfiles.h"
00030 #include "gdbcore.h"
00031 #include "target.h"
00032 #include "inferior.h"
00033 #include "gdbthread.h"
00034 
00035 #include "solist.h"
00036 #include "solib.h"
00037 #include "solib-irix.h"
00038 
00039 
00040 /* Link map info to include in an allocate so_list entry.  Unlike some
00041    of the other solib backends, this (Irix) backend chooses to decode
00042    the link map info obtained from the target and store it as (mostly)
00043    CORE_ADDRs which need no further decoding.  This is more convenient
00044    because there are three different link map formats to worry about.
00045    We use a single routine (fetch_lm_info) to read (and decode) the target
00046    specific link map data.  */
00047 
00048 struct lm_info
00049 {
00050   CORE_ADDR addr;               /* address of obj_info or obj_list
00051                                    struct on target (from which the
00052                                    following information is obtained).  */
00053   CORE_ADDR next;               /* address of next item in list.  */
00054   CORE_ADDR reloc_offset;       /* amount to relocate by  */
00055   CORE_ADDR pathname_addr;      /* address of pathname  */
00056   int pathname_len;             /* length of pathname */
00057 };
00058 
00059 /* It's not desirable to use the system header files to obtain the
00060    structure of the obj_list or obj_info structs.  Therefore, we use a
00061    platform neutral representation which has been derived from the IRIX
00062    header files.  */
00063 
00064 typedef struct
00065 {
00066   gdb_byte b[4];
00067 }
00068 gdb_int32_bytes;
00069 typedef struct
00070 {
00071   gdb_byte b[8];
00072 }
00073 gdb_int64_bytes;
00074 
00075 /* The "old" obj_list struct.  This is used with old (o32) binaries.
00076    The ``data'' member points at a much larger and more complicated
00077    struct which we will only refer to by offsets.  See
00078    fetch_lm_info().  */
00079 
00080 struct irix_obj_list
00081 {
00082   gdb_int32_bytes data;
00083   gdb_int32_bytes next;
00084   gdb_int32_bytes prev;
00085 };
00086 
00087 /* The ELF32 and ELF64 versions of the above struct.  The oi_magic value
00088    corresponds to the ``data'' value in the "old" struct.  When this value
00089    is 0xffffffff, the data will be in one of the following formats.  The
00090    ``oi_size'' field is used to decide which one we actually have.  */
00091 
00092 struct irix_elf32_obj_info
00093 {
00094   gdb_int32_bytes oi_magic;
00095   gdb_int32_bytes oi_size;
00096   gdb_int32_bytes oi_next;
00097   gdb_int32_bytes oi_prev;
00098   gdb_int32_bytes oi_ehdr;
00099   gdb_int32_bytes oi_orig_ehdr;
00100   gdb_int32_bytes oi_pathname;
00101   gdb_int32_bytes oi_pathname_len;
00102 };
00103 
00104 struct irix_elf64_obj_info
00105 {
00106   gdb_int32_bytes oi_magic;
00107   gdb_int32_bytes oi_size;
00108   gdb_int64_bytes oi_next;
00109   gdb_int64_bytes oi_prev;
00110   gdb_int64_bytes oi_ehdr;
00111   gdb_int64_bytes oi_orig_ehdr;
00112   gdb_int64_bytes oi_pathname;
00113   gdb_int32_bytes oi_pathname_len;
00114   gdb_int32_bytes padding;
00115 };
00116 
00117 /* Union of all of the above (plus a split out magic field).  */
00118 
00119 union irix_obj_info
00120 {
00121   gdb_int32_bytes magic;
00122   struct irix_obj_list ol32;
00123   struct irix_elf32_obj_info oi32;
00124   struct irix_elf64_obj_info oi64;
00125 };
00126 
00127 /* MIPS sign extends its 32 bit addresses.  We could conceivably use
00128    extract_typed_address here, but to do so, we'd have to construct an
00129    appropriate type.  Calling extract_signed_integer seems simpler.  */
00130 
00131 static CORE_ADDR
00132 extract_mips_address (void *addr, int len, enum bfd_endian byte_order)
00133 {
00134   return extract_signed_integer (addr, len, byte_order);
00135 }
00136 
00137 /* Fetch and return the link map data associated with ADDR.  Note that
00138    this routine automatically determines which (of three) link map
00139    formats is in use by the target.  */
00140 
00141 static struct lm_info
00142 fetch_lm_info (CORE_ADDR addr)
00143 {
00144   enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch ());
00145   struct lm_info li;
00146   union irix_obj_info buf;
00147 
00148   li.addr = addr;
00149 
00150   /* The smallest region that we'll need is for buf.ol32.  We'll read
00151      that first.  We'll read more of the buffer later if we have to deal
00152      with one of the other cases.  (We don't want to incur a memory error
00153      if we were to read a larger region that generates an error due to
00154      being at the end of a page or the like.)  */
00155   read_memory (addr, (gdb_byte *) &buf, sizeof (buf.ol32));
00156 
00157   if (extract_unsigned_integer (buf.magic.b, sizeof (buf.magic), byte_order)
00158       != 0xffffffff)
00159     {
00160       /* Use buf.ol32...  */
00161       gdb_byte obj_buf[432];
00162       CORE_ADDR obj_addr = extract_mips_address (&buf.ol32.data,
00163                                                  sizeof (buf.ol32.data),
00164                                                  byte_order);
00165 
00166       li.next = extract_mips_address (&buf.ol32.next,
00167                                       sizeof (buf.ol32.next), byte_order);
00168 
00169       read_memory (obj_addr, obj_buf, sizeof (obj_buf));
00170 
00171       li.pathname_addr = extract_mips_address (&obj_buf[236], 4, byte_order);
00172       li.pathname_len = 0;      /* unknown */
00173       li.reloc_offset = extract_mips_address (&obj_buf[196], 4, byte_order)
00174         - extract_mips_address (&obj_buf[248], 4, byte_order);
00175 
00176     }
00177   else if (extract_unsigned_integer (buf.oi32.oi_size.b,
00178                                      sizeof (buf.oi32.oi_size), byte_order)
00179            == sizeof (buf.oi32))
00180     {
00181       /* Use buf.oi32...  */
00182 
00183       /* Read rest of buffer.  */
00184       read_memory (addr + sizeof (buf.ol32),
00185                    ((gdb_byte *) &buf) + sizeof (buf.ol32),
00186                    sizeof (buf.oi32) - sizeof (buf.ol32));
00187 
00188       /* Fill in fields using buffer contents.  */
00189       li.next = extract_mips_address (&buf.oi32.oi_next,
00190                                       sizeof (buf.oi32.oi_next), byte_order);
00191       li.reloc_offset = extract_mips_address (&buf.oi32.oi_ehdr,
00192                                               sizeof (buf.oi32.oi_ehdr),
00193                                               byte_order)
00194         - extract_mips_address (&buf.oi32.oi_orig_ehdr,
00195                                 sizeof (buf.oi32.oi_orig_ehdr), byte_order);
00196       li.pathname_addr = extract_mips_address (&buf.oi32.oi_pathname,
00197                                                sizeof (buf.oi32.oi_pathname),
00198                                                byte_order);
00199       li.pathname_len = extract_unsigned_integer (buf.oi32.oi_pathname_len.b,
00200                                                   sizeof (buf.oi32.
00201                                                           oi_pathname_len),
00202                                                   byte_order);
00203     }
00204   else if (extract_unsigned_integer (buf.oi64.oi_size.b,
00205                                      sizeof (buf.oi64.oi_size), byte_order)
00206            == sizeof (buf.oi64))
00207     {
00208       /* Use buf.oi64...  */
00209 
00210       /* Read rest of buffer.  */
00211       read_memory (addr + sizeof (buf.ol32),
00212                    ((gdb_byte *) &buf) + sizeof (buf.ol32),
00213                    sizeof (buf.oi64) - sizeof (buf.ol32));
00214 
00215       /* Fill in fields using buffer contents.  */
00216       li.next = extract_mips_address (&buf.oi64.oi_next,
00217                                       sizeof (buf.oi64.oi_next), byte_order);
00218       li.reloc_offset = extract_mips_address (&buf.oi64.oi_ehdr,
00219                                               sizeof (buf.oi64.oi_ehdr),
00220                                               byte_order)
00221         - extract_mips_address (&buf.oi64.oi_orig_ehdr,
00222                                 sizeof (buf.oi64.oi_orig_ehdr), byte_order);
00223       li.pathname_addr = extract_mips_address (&buf.oi64.oi_pathname,
00224                                                sizeof (buf.oi64.oi_pathname),
00225                                                byte_order);
00226       li.pathname_len = extract_unsigned_integer (buf.oi64.oi_pathname_len.b,
00227                                                   sizeof (buf.oi64.
00228                                                           oi_pathname_len),
00229                                                   byte_order);
00230     }
00231   else
00232     {
00233       error (_("Unable to fetch shared library obj_info or obj_list info."));
00234     }
00235 
00236   return li;
00237 }
00238 
00239 /* The symbol which starts off the list of shared libraries.  */
00240 #define DEBUG_BASE "__rld_obj_head"
00241 
00242 static void *base_breakpoint;
00243 
00244 static CORE_ADDR debug_base;    /* Base of dynamic linker structures.  */
00245 
00246 /* Locate the base address of dynamic linker structs.
00247 
00248    For both the SunOS and SVR4 shared library implementations, if the
00249    inferior executable has been linked dynamically, there is a single
00250    address somewhere in the inferior's data space which is the key to
00251    locating all of the dynamic linker's runtime structures.  This
00252    address is the value of the symbol defined by the macro DEBUG_BASE.
00253    The job of this function is to find and return that address, or to
00254    return 0 if there is no such address (the executable is statically
00255    linked for example).
00256 
00257    For SunOS, the job is almost trivial, since the dynamic linker and
00258    all of it's structures are statically linked to the executable at
00259    link time.  Thus the symbol for the address we are looking for has
00260    already been added to the minimal symbol table for the executable's
00261    objfile at the time the symbol file's symbols were read, and all we
00262    have to do is look it up there.  Note that we explicitly do NOT want
00263    to find the copies in the shared library.
00264 
00265    The SVR4 version is much more complicated because the dynamic linker
00266    and it's structures are located in the shared C library, which gets
00267    run as the executable's "interpreter" by the kernel.  We have to go
00268    to a lot more work to discover the address of DEBUG_BASE.  Because
00269    of this complexity, we cache the value we find and return that value
00270    on subsequent invocations.  Note there is no copy in the executable
00271    symbol tables.
00272 
00273    Irix 5 is basically like SunOS.
00274 
00275    Note that we can assume nothing about the process state at the time
00276    we need to find this address.  We may be stopped on the first instruc-
00277    tion of the interpreter (C shared library), the first instruction of
00278    the executable itself, or somewhere else entirely (if we attached
00279    to the process for example).  */
00280 
00281 static CORE_ADDR
00282 locate_base (void)
00283 {
00284   struct minimal_symbol *msymbol;
00285   CORE_ADDR address = 0;
00286 
00287   msymbol = lookup_minimal_symbol (DEBUG_BASE, NULL, symfile_objfile);
00288   if ((msymbol != NULL) && (SYMBOL_VALUE_ADDRESS (msymbol) != 0))
00289     {
00290       address = SYMBOL_VALUE_ADDRESS (msymbol);
00291     }
00292   return (address);
00293 }
00294 
00295 /* Remove the "mapping changed" breakpoint.
00296 
00297    Removes the breakpoint that gets hit when the dynamic linker
00298    completes a mapping change.  */
00299 
00300 static int
00301 disable_break (void)
00302 {
00303   int status = 1;
00304 
00305   /* Note that breakpoint address and original contents are in our address
00306      space, so we just need to write the original contents back.  */
00307 
00308   if (deprecated_remove_raw_breakpoint (target_gdbarch (), base_breakpoint) != 0)
00309     {
00310       status = 0;
00311     }
00312 
00313   base_breakpoint = NULL;
00314 
00315   /* Note that it is possible that we have stopped at a location that
00316      is different from the location where we inserted our breakpoint.
00317      On mips-irix, we can actually land in __dbx_init(), so we should
00318      not check the PC against our breakpoint address here.  See procfs.c
00319      for more details.  */
00320 
00321   return (status);
00322 }
00323 
00324 /* Arrange for dynamic linker to hit breakpoint.
00325 
00326    This functions inserts a breakpoint at the entry point of the
00327    main executable, where all shared libraries are mapped in.  */
00328 
00329 static int
00330 enable_break (void)
00331 {
00332   if (symfile_objfile != NULL && has_stack_frames ())
00333     {
00334       struct frame_info *frame = get_current_frame ();
00335       struct address_space *aspace = get_frame_address_space (frame);
00336       CORE_ADDR entry_point;
00337 
00338       if (!entry_point_address_query (&entry_point))
00339         return 0;
00340 
00341       base_breakpoint = deprecated_insert_raw_breakpoint (target_gdbarch (),
00342                                                           aspace, entry_point);
00343 
00344       if (base_breakpoint != NULL)
00345         return 1;
00346     }
00347 
00348   return 0;
00349 }
00350 
00351 /* Implement the "create_inferior_hook" target_solib_ops method.
00352 
00353    For SunOS executables, this first instruction is typically the
00354    one at "_start", or a similar text label, regardless of whether
00355    the executable is statically or dynamically linked.  The runtime
00356    startup code takes care of dynamically linking in any shared
00357    libraries, once gdb allows the inferior to continue.
00358 
00359    For SVR4 executables, this first instruction is either the first
00360    instruction in the dynamic linker (for dynamically linked
00361    executables) or the instruction at "start" for statically linked
00362    executables.  For dynamically linked executables, the system
00363    first exec's /lib/libc.so.N, which contains the dynamic linker,
00364    and starts it running.  The dynamic linker maps in any needed
00365    shared libraries, maps in the actual user executable, and then
00366    jumps to "start" in the user executable.
00367 
00368    For both SunOS shared libraries, and SVR4 shared libraries, we
00369    can arrange to cooperate with the dynamic linker to discover the
00370    names of shared libraries that are dynamically linked, and the
00371    base addresses to which they are linked.
00372 
00373    This function is responsible for discovering those names and
00374    addresses, and saving sufficient information about them to allow
00375    their symbols to be read at a later time.
00376 
00377    FIXME
00378 
00379    Between enable_break() and disable_break(), this code does not
00380    properly handle hitting breakpoints which the user might have
00381    set in the startup code or in the dynamic linker itself.  Proper
00382    handling will probably have to wait until the implementation is
00383    changed to use the "breakpoint handler function" method.
00384 
00385    Also, what if child has exit()ed?  Must exit loop somehow.  */
00386 
00387 static void
00388 irix_solib_create_inferior_hook (int from_tty)
00389 {
00390   struct inferior *inf;
00391   struct thread_info *tp;
00392 
00393   inf = current_inferior ();
00394 
00395   /* If we are attaching to the inferior, the shared libraries
00396      have already been mapped, so nothing more to do.  */
00397   if (inf->attach_flag)
00398     return;
00399 
00400   /* Likewise when debugging from a core file, the shared libraries
00401      have already been mapped, so nothing more to do.  */
00402   if (!target_can_run (&current_target))
00403     return;
00404 
00405   if (!enable_break ())
00406     {
00407       warning (_("shared library handler failed to enable breakpoint"));
00408       return;
00409     }
00410 
00411   /* Now run the target.  It will eventually hit the breakpoint, at
00412      which point all of the libraries will have been mapped in and we
00413      can go groveling around in the dynamic linker structures to find
00414      out what we need to know about them.  */
00415 
00416   tp = inferior_thread ();
00417 
00418   clear_proceed_status ();
00419 
00420   inf->control.stop_soon = STOP_QUIETLY;
00421   tp->suspend.stop_signal = GDB_SIGNAL_0;
00422 
00423   do
00424     {
00425       target_resume (pid_to_ptid (-1), 0, tp->suspend.stop_signal);
00426       wait_for_inferior ();
00427     }
00428   while (tp->suspend.stop_signal != GDB_SIGNAL_TRAP);
00429 
00430   /* We are now either at the "mapping complete" breakpoint (or somewhere
00431      else, a condition we aren't prepared to deal with anyway), so adjust
00432      the PC as necessary after a breakpoint, disable the breakpoint, and
00433      add any shared libraries that were mapped in.  */
00434 
00435   if (!disable_break ())
00436     {
00437       warning (_("shared library handler failed to disable breakpoint"));
00438     }
00439 
00440   /* solib_add will call reinit_frame_cache.
00441      But we are stopped in the startup code and we might not have symbols
00442      for the startup code, so heuristic_proc_start could be called
00443      and will put out an annoying warning.
00444      Delaying the resetting of stop_soon until after symbol loading
00445      suppresses the warning.  */
00446   solib_add ((char *) 0, 0, (struct target_ops *) 0, auto_solib_add);
00447   inf->control.stop_soon = NO_STOP_QUIETLY;
00448 }
00449 
00450 /* Implement the "current_sos" target_so_ops method.  */
00451 
00452 static struct so_list *
00453 irix_current_sos (void)
00454 {
00455   enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch ());
00456   int addr_size = gdbarch_addr_bit (target_gdbarch ()) / TARGET_CHAR_BIT;
00457   CORE_ADDR lma;
00458   gdb_byte addr_buf[8];
00459   struct so_list *head = 0;
00460   struct so_list **link_ptr = &head;
00461   int is_first = 1;
00462   struct lm_info lm;
00463 
00464   /* Make sure we've looked up the inferior's dynamic linker's base
00465      structure.  */
00466   if (!debug_base)
00467     {
00468       debug_base = locate_base ();
00469 
00470       /* If we can't find the dynamic linker's base structure, this
00471          must not be a dynamically linked executable.  Hmm.  */
00472       if (!debug_base)
00473         return 0;
00474     }
00475 
00476   read_memory (debug_base, addr_buf, addr_size);
00477   lma = extract_mips_address (addr_buf, addr_size, byte_order);
00478 
00479   while (lma)
00480     {
00481       lm = fetch_lm_info (lma);
00482       if (!is_first)
00483         {
00484           int errcode;
00485           char *name_buf;
00486           int name_size;
00487           struct so_list *new
00488             = (struct so_list *) xmalloc (sizeof (struct so_list));
00489           struct cleanup *old_chain = make_cleanup (xfree, new);
00490 
00491           memset (new, 0, sizeof (*new));
00492 
00493           new->lm_info = xmalloc (sizeof (struct lm_info));
00494           make_cleanup (xfree, new->lm_info);
00495 
00496           *new->lm_info = lm;
00497 
00498           /* Extract this shared object's name.  */
00499           name_size = lm.pathname_len;
00500           if (name_size == 0)
00501             name_size = SO_NAME_MAX_PATH_SIZE - 1;
00502 
00503           if (name_size >= SO_NAME_MAX_PATH_SIZE)
00504             {
00505               name_size = SO_NAME_MAX_PATH_SIZE - 1;
00506               warning (_("current_sos: truncating name of "
00507                          "%d characters to only %d characters"),
00508                        lm.pathname_len, name_size);
00509             }
00510 
00511           target_read_string (lm.pathname_addr, &name_buf,
00512                               name_size, &errcode);
00513           if (errcode != 0)
00514             warning (_("Can't read pathname for load map: %s."),
00515                        safe_strerror (errcode));
00516           else
00517             {
00518               strncpy (new->so_name, name_buf, name_size);
00519               new->so_name[name_size] = '\0';
00520               xfree (name_buf);
00521               strcpy (new->so_original_name, new->so_name);
00522             }
00523 
00524           new->next = 0;
00525           *link_ptr = new;
00526           link_ptr = &new->next;
00527 
00528           discard_cleanups (old_chain);
00529         }
00530       is_first = 0;
00531       lma = lm.next;
00532     }
00533 
00534   return head;
00535 }
00536 
00537 /* Implement the "open_symbol_file_object" target_so_ops method.
00538 
00539    If no open symbol file, attempt to locate and open the main symbol
00540    file.  On IRIX, this is the first link map entry.  If its name is
00541    here, we can open it.  Useful when attaching to a process without
00542    first loading its symbol file.  */
00543 
00544 static int
00545 irix_open_symbol_file_object (void *from_ttyp)
00546 {
00547   enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch ());
00548   int addr_size = gdbarch_addr_bit (target_gdbarch ()) / TARGET_CHAR_BIT;
00549   CORE_ADDR lma;
00550   gdb_byte addr_buf[8];
00551   struct lm_info lm;
00552   struct cleanup *cleanups;
00553   int errcode;
00554   int from_tty = *(int *) from_ttyp;
00555   char *filename;
00556 
00557   if (symfile_objfile)
00558     if (!query (_("Attempt to reload symbols from process? ")))
00559       return 0;
00560 
00561   if ((debug_base = locate_base ()) == 0)
00562     return 0;                   /* failed somehow...  */
00563 
00564   /* First link map member should be the executable.  */
00565   read_memory (debug_base, addr_buf, addr_size);
00566   lma = extract_mips_address (addr_buf, addr_size, byte_order);
00567   if (lma == 0)
00568     return 0;                   /* failed somehow...  */
00569 
00570   lm = fetch_lm_info (lma);
00571 
00572   if (lm.pathname_addr == 0)
00573     return 0;                   /* No filename.  */
00574 
00575   /* Now fetch the filename from target memory.  */
00576   target_read_string (lm.pathname_addr, &filename, SO_NAME_MAX_PATH_SIZE - 1,
00577                       &errcode);
00578 
00579   if (errcode)
00580     {
00581       warning (_("failed to read exec filename from attached file: %s"),
00582                safe_strerror (errcode));
00583       return 0;
00584     }
00585 
00586   cleanups = make_cleanup (xfree, filename);
00587   /* Have a pathname: read the symbol file.  */
00588   symbol_file_add_main (filename, from_tty);
00589 
00590   do_cleanups (cleanups);
00591 
00592   return 1;
00593 }
00594 
00595 /* Implement the "special_symbol_handling" target_so_ops method.
00596 
00597    For IRIX, there's nothing to do.  */
00598 
00599 static void
00600 irix_special_symbol_handling (void)
00601 {
00602 }
00603 
00604 /* Using the solist entry SO, relocate the addresses in SEC.  */
00605 
00606 static void
00607 irix_relocate_section_addresses (struct so_list *so,
00608                                  struct target_section *sec)
00609 {
00610   sec->addr += so->lm_info->reloc_offset;
00611   sec->endaddr += so->lm_info->reloc_offset;
00612 }
00613 
00614 /* Free the lm_info struct.  */
00615 
00616 static void
00617 irix_free_so (struct so_list *so)
00618 {
00619   xfree (so->lm_info);
00620 }
00621 
00622 /* Clear backend specific state.  */
00623 
00624 static void
00625 irix_clear_solib (void)
00626 {
00627   debug_base = 0;
00628 }
00629 
00630 /* Return 1 if PC lies in the dynamic symbol resolution code of the
00631    run time loader.  */
00632 static int
00633 irix_in_dynsym_resolve_code (CORE_ADDR pc)
00634 {
00635   return 0;
00636 }
00637 
00638 struct target_so_ops irix_so_ops;
00639 
00640 /* Provide a prototype to silence -Wmissing-prototypes.  */
00641 extern initialize_file_ftype _initialize_irix_solib;
00642 
00643 void
00644 _initialize_irix_solib (void)
00645 {
00646   irix_so_ops.relocate_section_addresses = irix_relocate_section_addresses;
00647   irix_so_ops.free_so = irix_free_so;
00648   irix_so_ops.clear_solib = irix_clear_solib;
00649   irix_so_ops.solib_create_inferior_hook = irix_solib_create_inferior_hook;
00650   irix_so_ops.special_symbol_handling = irix_special_symbol_handling;
00651   irix_so_ops.current_sos = irix_current_sos;
00652   irix_so_ops.open_symbol_file_object = irix_open_symbol_file_object;
00653   irix_so_ops.in_dynsym_resolve_code = irix_in_dynsym_resolve_code;
00654   irix_so_ops.bfd_open = solib_bfd_open;
00655 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines