Allow for the possibility that the local labels won't be in the objdump output.
[deliverable/binutils-gdb.git] / gdb / solib-svr4.c
index f7c7a78c66fc7786bf067e004a3977527407739d..79bbcdc55ee553a284bfd7f2af24e91168cc594f 100644 (file)
@@ -1,5 +1,6 @@
 /* Handle SunOS and SVR4 shared libraries for GDB, the GNU Debugger.
-   Copyright 1990, 91, 92, 93, 94, 95, 96, 98, 1999, 2000
+   Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000,
+   2001
    Free Software Foundation, Inc.
 
    This file is part of GDB.
@@ -19,8 +20,8 @@
    Foundation, Inc., 59 Temple Place - Suite 330,
    Boston, MA 02111-1307, USA.  */
 
-#define _SYSCALL32     /* for Sparc64 cross Sparc32 */
 #include "defs.h"
+#include "regcache.h"
 
 
 #include <sys/types.h>
 #ifndef SVR4_SHARED_LIBS
  /* SunOS shared libs need the nlist structure.  */
 #include <a.out.h>
+#include <link.h>
 #else
 #include "elf/external.h"
-#endif
-
-#ifdef HAVE_LINK_H
-#include <link.h>
+#include "elf/common.h"
 #endif
 
 #include "symtab.h"
 #include "solist.h"
 #include "solib-svr4.h"
 
+#ifndef SVR4_FETCH_LINK_MAP_OFFSETS
+#define SVR4_FETCH_LINK_MAP_OFFSETS() fetch_link_map_offsets ()
+#endif
+
+static struct link_map_offsets *default_svr4_fetch_link_map_offsets (void);
+static struct link_map_offsets *(*fetch_link_map_offsets)(void) = 
+  default_svr4_fetch_link_map_offsets;
+
+/* legacy_svr4_fetch_link_map_offsets_hook is a pointer to a function
+   which is used to fetch link map offsets.  It will only be set
+   by solib-legacy.c, if at all. */
+struct link_map_offsets *(*legacy_svr4_fetch_link_map_offsets_hook)(void) = 0;
+
 /* Link map info to include in an allocated so_list entry */
 
 struct lm_info
@@ -82,6 +94,7 @@ static char *solib_break_names[] =
   "_r_debug_state",
   "_dl_debug_state",
   "rtld_db_dlactivity",
+  "_rtld_debug_state",
   NULL
 };
 #endif
@@ -119,100 +132,24 @@ static char *main_name_list[] =
 
 
 /* Fetch (and possibly build) an appropriate link_map_offsets structure
-   for native targets using struct definitions from link.h.  */
+   for native targets using struct definitions from link.h.  
+   
+   Note: For non-native targets (i.e. cross-debugging situations),
+   you need to define a target specific fetch_link_map_offsets()
+   function and call set_solib_svr4_fetch_link_map_offsets () to
+   register this function.  */
 
-struct link_map_offsets *
+static struct link_map_offsets *
 default_svr4_fetch_link_map_offsets (void)
 {
-#ifdef HAVE_LINK_H
-  static struct link_map_offsets lmo;
-  static struct link_map_offsets *lmp = 0;
-#if defined (HAVE_STRUCT_LINK_MAP32)
-  static struct link_map_offsets lmo32;
-  static struct link_map_offsets *lmp32 = 0;
-#endif
-
-#ifndef offsetof
-#define offsetof(TYPE, MEMBER) ((unsigned long) &((TYPE *)0)->MEMBER)
-#endif
-#define fieldsize(TYPE, MEMBER) (sizeof (((TYPE *)0)->MEMBER))
-
-  if (lmp == 0)
-    {
-      lmp = &lmo;
-
-#ifdef SVR4_SHARED_LIBS
-      lmo.r_debug_size = sizeof (struct r_debug);
-
-      lmo.r_map_offset = offsetof (struct r_debug, r_map);
-      lmo.r_map_size = fieldsize (struct r_debug, r_map);
-
-      lmo.link_map_size = sizeof (struct link_map);
-
-      lmo.l_addr_offset = offsetof (struct link_map, l_addr);
-      lmo.l_addr_size = fieldsize (struct link_map, l_addr);
-
-      lmo.l_next_offset = offsetof (struct link_map, l_next);
-      lmo.l_next_size = fieldsize (struct link_map, l_next);
-
-      lmo.l_prev_offset = offsetof (struct link_map, l_prev);
-      lmo.l_prev_size = fieldsize (struct link_map, l_prev);
-
-      lmo.l_name_offset = offsetof (struct link_map, l_name);
-      lmo.l_name_size = fieldsize (struct link_map, l_name);
-#else /* !SVR4_SHARED_LIBS */
-      lmo.link_map_size = sizeof (struct link_map);
-
-      lmo.l_addr_offset = offsetof (struct link_map, lm_addr);
-      lmo.l_addr_size = fieldsize (struct link_map, lm_addr);
-
-      lmo.l_next_offset = offsetof (struct link_map, lm_next);
-      lmo.l_next_size = fieldsize (struct link_map, lm_next);
-
-      lmo.l_name_offset = offsetof (struct link_map, lm_name);
-      lmo.l_name_size = fieldsize (struct link_map, lm_name);
-#endif /* SVR4_SHARED_LIBS */
-    }
-
-#if defined (HAVE_STRUCT_LINK_MAP32)
-  if (lmp32 == 0)
+  if (legacy_svr4_fetch_link_map_offsets_hook)
+    return legacy_svr4_fetch_link_map_offsets_hook ();
+  else
     {
-      lmp32 = &lmo32;
-
-      lmo32.r_debug_size = sizeof (struct r_debug32);
-
-      lmo32.r_map_offset = offsetof (struct r_debug32, r_map);
-      lmo32.r_map_size = fieldsize (struct r_debug32, r_map);
-
-      lmo32.link_map_size = sizeof (struct link_map32);
-
-      lmo32.l_addr_offset = offsetof (struct link_map32, l_addr);
-      lmo32.l_addr_size = fieldsize (struct link_map32, l_addr);
-
-      lmo32.l_next_offset = offsetof (struct link_map32, l_next);
-      lmo32.l_next_size = fieldsize (struct link_map32, l_next);
-
-      lmo32.l_prev_offset = offsetof (struct link_map32, l_prev);
-      lmo32.l_prev_size = fieldsize (struct link_map32, l_prev);
-
-      lmo32.l_name_offset = offsetof (struct link_map32, l_name);
-      lmo32.l_name_size = fieldsize (struct link_map32, l_name);
+      internal_error (__FILE__, __LINE__,
+"default_svr4_fetch_link_map_offsets called without legacy link_map support enabled.");
+      return 0;
     }
-#endif /* defined (HAVE_STRUCT_LINK_MAP32) */
-
-#if defined (HAVE_STRUCT_LINK_MAP32)
-  if (bfd_get_arch_size (exec_bfd) == 32)
-    return lmp32;
-  else
-#endif
-    return lmp;
-
-#else
-
-  internal_error ("default_svr4_fetch_link_map_offsets called without HAVE_LINK_H defined.");
-  return 0;
-
-#endif /* HAVE_LINK_H */
 }
 
 /* Macro to extract an address from a solib structure.
@@ -247,7 +184,8 @@ LM_ADDR (struct so_list *so)
 {
   struct link_map_offsets *lmo = SVR4_FETCH_LINK_MAP_OFFSETS ();
 
-  return extract_address (so->lm_info->lm + lmo->l_addr_offset, lmo->l_addr_size);
+  return (CORE_ADDR) extract_signed_integer (so->lm_info->lm + lmo->l_addr_offset, 
+                                            lmo->l_addr_size);
 }
 
 static CORE_ADDR
@@ -308,13 +246,13 @@ allocate_rt_common_objfile (void)
   memset (objfile, 0, sizeof (struct objfile));
   objfile->md = NULL;
   obstack_specify_allocation (&objfile->psymbol_cache.cache, 0, 0,
-                             xmalloc, free);
+                             xmalloc, xfree);
   obstack_specify_allocation (&objfile->psymbol_obstack, 0, 0, xmalloc,
-                             free);
+                             xfree);
   obstack_specify_allocation (&objfile->symbol_obstack, 0, 0, xmalloc,
-                             free);
+                             xfree);
   obstack_specify_allocation (&objfile->type_obstack, 0, 0, xmalloc,
-                             free);
+                             xfree);
   objfile->name = mstrsave (objfile->md, "rt_common");
 
   /* Add this file onto the tail of the linked list of other such files. */
@@ -351,7 +289,7 @@ solib_add_common_symbols (CORE_ADDR rtc_symp)
     {
       obstack_free (&rt_common_objfile->symbol_obstack, 0);
       obstack_specify_allocation (&rt_common_objfile->symbol_obstack, 0, 0,
-                                 xmalloc, free);
+                                 xmalloc, xfree);
       rt_common_objfile->minimal_symbol_count = 0;
       rt_common_objfile->msymbols = NULL;
     }
@@ -384,7 +322,7 @@ solib_add_common_symbols (CORE_ADDR rtc_symp)
 
          prim_record_minimal_symbol (name, inferior_rtc_nlist.n_value,
                                      mst_bss, rt_common_objfile);
-         free (name);
+         xfree (name);
        }
       rtc_symp = SOLIB_EXTRACT_ADDRESS (inferior_rtc_symb.rtc_next);
     }
@@ -426,7 +364,7 @@ static CORE_ADDR bfd_lookup_symbol (bfd *, char *);
 static CORE_ADDR
 bfd_lookup_symbol (bfd *abfd, char *symname)
 {
-  unsigned int storage_needed;
+  long storage_needed;
   asymbol *sym;
   asymbol **symbol_table;
   unsigned int number_of_symbols;
@@ -439,7 +377,7 @@ bfd_lookup_symbol (bfd *abfd, char *symname)
   if (storage_needed > 0)
     {
       symbol_table = (asymbol **) xmalloc (storage_needed);
-      back_to = make_cleanup (free, (PTR) symbol_table);
+      back_to = make_cleanup (xfree, (PTR) symbol_table);
       number_of_symbols = bfd_canonicalize_symtab (abfd, symbol_table);
 
       for (i = 0; i < number_of_symbols; i++)
@@ -466,7 +404,7 @@ bfd_lookup_symbol (bfd *abfd, char *symname)
   if (storage_needed > 0)
     {
       symbol_table = (asymbol **) xmalloc (storage_needed);
-      back_to = make_cleanup (free, (PTR) symbol_table);
+      back_to = make_cleanup (xfree, (PTR) symbol_table);
       number_of_symbols = bfd_canonicalize_dynamic_symtab (abfd, symbol_table);
 
       for (i = 0; i < number_of_symbols; i++)
@@ -853,7 +791,7 @@ first_link_map_member (void)
 #else /* SVR4_SHARED_LIBS */
   struct link_map_offsets *lmo = SVR4_FETCH_LINK_MAP_OFFSETS ();
   char *r_map_buf = xmalloc (lmo->r_map_size);
-  struct cleanup *cleanups = make_cleanup (free, r_map_buf);
+  struct cleanup *cleanups = make_cleanup (xfree, r_map_buf);
 
   read_memory (debug_base + lmo->r_map_offset, r_map_buf, lmo->r_map_size);
 
@@ -902,7 +840,7 @@ open_symbol_file_object (void *from_ttyp)
   int from_tty = *(int *)from_ttyp;
   struct link_map_offsets *lmo = SVR4_FETCH_LINK_MAP_OFFSETS ();
   char *l_name_buf = xmalloc (lmo->l_name_size);
-  struct cleanup *cleanups = make_cleanup (free, l_name_buf);
+  struct cleanup *cleanups = make_cleanup (xfree, l_name_buf);
 
   if (symfile_objfile)
     if (!query ("Attempt to reload symbols from process? "))
@@ -937,16 +875,16 @@ open_symbol_file_object (void *from_ttyp)
       return 0;
     }
 
-  make_cleanup (free, filename);
+  make_cleanup (xfree, filename);
   /* Have a pathname: read the symbol file.  */
-  symbol_file_command (filename, from_tty);
+  symbol_file_add_main (filename, from_tty);
 
   return 1;
 }
 #else
 
 static int
-open_symbol_file_object (int *from_ttyp)
+open_symbol_file_object (void *from_ttyp)
 {
   return 1;
 }
@@ -1000,15 +938,15 @@ svr4_current_sos (void)
       struct link_map_offsets *lmo = SVR4_FETCH_LINK_MAP_OFFSETS ();
       struct so_list *new
        = (struct so_list *) xmalloc (sizeof (struct so_list));
-      struct cleanup *old_chain = make_cleanup (free, new);
+      struct cleanup *old_chain = make_cleanup (xfree, new);
 
       memset (new, 0, sizeof (*new));
 
       new->lm_info = xmalloc (sizeof (struct lm_info));
-      make_cleanup (free, new->lm_info);
+      make_cleanup (xfree, new->lm_info);
 
       new->lm_info->lm = xmalloc (lmo->link_map_size);
-      make_cleanup (free, new->lm_info->lm);
+      make_cleanup (xfree, new->lm_info->lm);
       memset (new->lm_info->lm, 0, lmo->link_map_size);
 
       read_memory (lm, new->lm_info->lm, lmo->link_map_size);
@@ -1039,7 +977,7 @@ svr4_current_sos (void)
            {
              strncpy (new->so_name, buffer, SO_NAME_MAX_PATH_SIZE - 1);
              new->so_name[SO_NAME_MAX_PATH_SIZE - 1] = '\0';
-             free (buffer);
+             xfree (buffer);
              strcpy (new->so_original_name, new->so_name);
            }
 
@@ -1082,24 +1020,28 @@ match_main (char *soname)
 }
 
 
-#ifdef SVR4_SHARED_LIBS
-
 /* Return 1 if PC lies in the dynamic symbol resolution code of the
    SVR4 run time loader.  */
-
+#ifdef SVR4_SHARED_LIBS
 static CORE_ADDR interp_text_sect_low;
 static CORE_ADDR interp_text_sect_high;
 static CORE_ADDR interp_plt_sect_low;
 static CORE_ADDR interp_plt_sect_high;
 
-int
-in_svr4_dynsym_resolve_code (CORE_ADDR pc)
+static int
+svr4_in_dynsym_resolve_code (CORE_ADDR pc)
 {
   return ((pc >= interp_text_sect_low && pc < interp_text_sect_high)
          || (pc >= interp_plt_sect_low && pc < interp_plt_sect_high)
          || in_plt_section (pc, NULL));
 }
-#endif
+#else /* !SVR4_SHARED_LIBS */
+static int
+svr4_in_dynsym_resolve_code (CORE_ADDR pc)
+{
+  return 0;
+}
+#endif /* SVR4_SHARED_LIBS */
 
 /*
 
@@ -1300,7 +1242,7 @@ enable_break (void)
       load_addr = read_pc () - tmp_bfd->start_address;
 
       /* Record the relocated start and end address of the dynamic linker
-         text and plt section for in_svr4_dynsym_resolve_code.  */
+         text and plt section for svr4_in_dynsym_resolve_code.  */
       interp_sect = bfd_get_section_by_name (tmp_bfd, ".text");
       if (interp_sect)
        {
@@ -1522,7 +1464,7 @@ svr4_relocate_main_executable (void)
 
       new_offsets = xcalloc (sizeof (struct section_offsets),
                             symfile_objfile->num_sections);
-      old_chain = make_cleanup (free, new_offsets);
+      old_chain = make_cleanup (xfree, new_offsets);
 
       for (i = 0; i < symfile_objfile->num_sections; i++)
        {
@@ -1667,8 +1609,8 @@ svr4_clear_solib (void)
 static void
 svr4_free_so (struct so_list *so)
 {
-  free (so->lm_info->lm);
-  free (so->lm_info);
+  xfree (so->lm_info->lm);
+  xfree (so->lm_info);
 }
 
 static void
@@ -1679,11 +1621,27 @@ svr4_relocate_section_addresses (struct so_list *so,
   sec->endaddr += LM_ADDR (so);
 }
 
+void
+set_solib_svr4_fetch_link_map_offsets (struct link_map_offsets *(*flmo) (void))
+{
+  fetch_link_map_offsets = flmo;
+}
+
+static void
+init_fetch_link_map_offsets (void)
+{
+  set_solib_svr4_fetch_link_map_offsets (default_svr4_fetch_link_map_offsets);
+}
+
 static struct target_so_ops svr4_so_ops;
 
 void
 _initialize_svr4_solib (void)
 {
+  register_gdbarch_swap (&fetch_link_map_offsets,
+                         sizeof (fetch_link_map_offsets),
+                        init_fetch_link_map_offsets);
+
   svr4_so_ops.relocate_section_addresses = svr4_relocate_section_addresses;
   svr4_so_ops.free_so = svr4_free_so;
   svr4_so_ops.clear_solib = svr4_clear_solib;
@@ -1691,6 +1649,7 @@ _initialize_svr4_solib (void)
   svr4_so_ops.special_symbol_handling = svr4_special_symbol_handling;
   svr4_so_ops.current_sos = svr4_current_sos;
   svr4_so_ops.open_symbol_file_object = open_symbol_file_object;
+  svr4_so_ops.in_dynsym_resolve_code = svr4_in_dynsym_resolve_code;
 
   /* FIXME: Don't do this here.  *_gdbarch_init() should set so_ops. */
   current_target_so_ops = &svr4_so_ops;
This page took 0.02835 seconds and 4 git commands to generate.