Fix a segfault caused by under-allocating an array.
[deliverable/binutils-gdb.git] / gdb / solib.c
index 621bd6cc4250ded01c1f939216130d94a1089082..843a73c7b4c6ed36e7b037f8cb1d43913c6a3de5 100644 (file)
@@ -1,5 +1,5 @@
 /* Handle SunOS and SVR4 shared libraries for GDB, the GNU Debugger.
 /* Handle SunOS and SVR4 shared libraries for GDB, the GNU Debugger.
-   Copyright 1990, 91, 92, 93, 94, 95, 96, 98, 1999
+   Copyright 1990, 91, 92, 93, 94, 95, 96, 98, 1999, 2000
    Free Software Foundation, Inc.
 
    This file is part of GDB.
    Free Software Foundation, Inc.
 
    This file is part of GDB.
@@ -19,7 +19,7 @@
    Foundation, Inc., 59 Temple Place - Suite 330,
    Boston, MA 02111-1307, USA.  */
 
    Foundation, Inc., 59 Temple Place - Suite 330,
    Boston, MA 02111-1307, USA.  */
 
-
+#define _SYSCALL32     /* for Sparc64 cross Sparc32 */
 #include "defs.h"
 
 /* This file is only compilable if link.h is available. */
 #include "defs.h"
 
 /* This file is only compilable if link.h is available. */
@@ -49,7 +49,7 @@
 #include "command.h"
 #include "target.h"
 #include "frame.h"
 #include "command.h"
 #include "target.h"
 #include "frame.h"
-#include "gnu-regex.h"
+#include "gdb_regex.h"
 #include "inferior.h"
 #include "environ.h"
 #include "language.h"
 #include "inferior.h"
 #include "environ.h"
 #include "language.h"
@@ -107,24 +107,33 @@ static char *main_name_list[] =
   NULL
 };
 
   NULL
 };
 
-/* local data declarations */
-
-/* Macro to extract an address from a solib structure.
+/* Function to extract an address from a solib structure.
    When GDB is configured for some 32-bit targets (e.g. Solaris 2.7
    sparc), BFD is configured to handle 64-bit targets, so CORE_ADDR is
    64 bits.  We have to extract only the significant bits of addresses
    When GDB is configured for some 32-bit targets (e.g. Solaris 2.7
    sparc), BFD is configured to handle 64-bit targets, so CORE_ADDR is
    64 bits.  We have to extract only the significant bits of addresses
-   to get the right address when accessing the core file BFD.  */
+   to get the right address when accessing the core file BFD.  
+
+   We'll use the BFD itself to determine the number of significant bits.  
+   MVS, June 2000  */
+
+static CORE_ADDR
+solib_extract_address (void *memberp)
+{
+  return extract_address (memberp, 
+                         bfd_get_arch_size (exec_bfd) / 8);
+}
+
+#define SOLIB_EXTRACT_ADDRESS(MEMBER) \
+        solib_extract_address (&MEMBER)
 
 
-#define SOLIB_EXTRACT_ADDRESS(member) \
-  extract_address (&member, sizeof (member))
+/* local data declarations */
 
 #ifndef SVR4_SHARED_LIBS
 
 
 #ifndef SVR4_SHARED_LIBS
 
-#define LM_ADDR(so) (SOLIB_EXTRACT_ADDRESS ((so) -> lm.lm_addr))
-#define LM_NEXT(so) (SOLIB_EXTRACT_ADDRESS ((so) -> lm.lm_next))
-#define LM_NAME(so) (SOLIB_EXTRACT_ADDRESS ((so) -> lm.lm_name))
-/* Test for first link map entry; first entry is a shared library. */
-#define IGNORE_FIRST_LINK_MAP_ENTRY(so) (0)
+/* NOTE: converted the macros LM_ADDR, LM_NEXT, LM_NAME and
+   IGNORE_FIRST_LINK_MAP_ENTRY into functions (see below).
+   MVS, June 2000  */
+
 static struct link_dynamic dynamic_copy;
 static struct link_dynamic_2 ld_2_copy;
 static struct ld_debug debug_copy;
 static struct link_dynamic dynamic_copy;
 static struct link_dynamic_2 ld_2_copy;
 static struct ld_debug debug_copy;
@@ -133,13 +142,11 @@ static CORE_ADDR flag_addr;
 
 #else /* SVR4_SHARED_LIBS */
 
 
 #else /* SVR4_SHARED_LIBS */
 
-#define LM_ADDR(so) (SOLIB_EXTRACT_ADDRESS ((so) -> lm.l_addr))
-#define LM_NEXT(so) (SOLIB_EXTRACT_ADDRESS ((so) -> lm.l_next))
-#define LM_NAME(so) (SOLIB_EXTRACT_ADDRESS ((so) -> lm.l_name))
-/* Test for first link map entry; first entry is the exec-file. */
-#define IGNORE_FIRST_LINK_MAP_ENTRY(so) \
-  (SOLIB_EXTRACT_ADDRESS ((so) -> lm.l_prev) == 0)
 static struct r_debug debug_copy;
 static struct r_debug debug_copy;
+#if defined (HAVE_STRUCT_LINK_MAP32)
+static struct r_debug32 debug32_copy;  /* Sparc64 cross Sparc32 */
+#endif
+
 char shadow_contents[BREAKPOINT_MAX];  /* Stash old bkpt addr contents */
 
 #endif /* !SVR4_SHARED_LIBS */
 char shadow_contents[BREAKPOINT_MAX];  /* Stash old bkpt addr contents */
 
 #endif /* !SVR4_SHARED_LIBS */
@@ -152,6 +159,9 @@ struct so_list
 
     struct so_list *next;      /* next structure in linked list */
     struct link_map lm;                /* copy of link map from inferior */
 
     struct so_list *next;      /* next structure in linked list */
     struct link_map lm;                /* copy of link map from inferior */
+#if defined (HAVE_STRUCT_LINK_MAP32)
+    struct link_map32 lm32;    /* copy of link map from 32-bit inferior */
+#endif
     CORE_ADDR lmaddr;          /* addr in inferior lm was read from */
 
     /* Shared object file name, exactly as it appears in the
     CORE_ADDR lmaddr;          /* addr in inferior lm was read from */
 
     /* Shared object file name, exactly as it appears in the
@@ -179,66 +189,155 @@ struct so_list
   };
 
 static struct so_list *so_list_head;   /* List of known shared objects */
   };
 
 static struct so_list *so_list_head;   /* List of known shared objects */
+
+/* link map access functions */
+
+#ifndef SVR4_SHARED_LIBS
+
+static CORE_ADDR
+LM_ADDR (so)
+     struct so_list *so;
+{
+#if defined (HAVE_STRUCT_LINK_MAP32)
+  if (bfd_get_arch_size (exec_bfd) == 32)
+    return extract_address (&so->lm32.lm_addr, sizeof (so->lm32.lm_addr));
+  else
+#endif
+    return extract_address (&so->lm.lm_addr, sizeof (so->lm.lm_addr));
+}
+
+static CORE_ADDR
+LM_NEXT (so)
+     struct so_list *so;
+{
+#if defined (HAVE_STRUCT_LINK_MAP32)
+  if (bfd_get_arch_size (exec_bfd) == 32)
+    return extract_address (&so->lm32.lm_next, sizeof (so->lm32.lm_next));
+  else
+#endif
+    return extract_address (&so->lm.lm_next, sizeof (so->lm.lm_next));
+}
+
+static CORE_ADDR
+LM_NAME (so)
+     struct so_list *so;
+{
+#if defined (HAVE_STRUCT_LINK_MAP32)
+  if (bfd_get_arch_size (exec_bfd) == 32)
+    return extract_address (&so->lm32.lm_name, sizeof (so->lm32.lm_name));
+  else
+#endif
+    return extract_address (&so->lm.lm_name, sizeof (so->lm.lm_name));
+}
+
+static int 
+IGNORE_FIRST_LINK_MAP_ENTRY (so)
+     struct so_list *so;
+{
+  return 0;
+}
+
+#else /* SVR4_SHARED_LIBS */
+
+static CORE_ADDR
+LM_ADDR (so)
+     struct so_list *so;
+{
+#if defined (HAVE_STRUCT_LINK_MAP32)
+  if (bfd_get_arch_size (exec_bfd) == 32)
+    return extract_address (&so->lm32.l_addr, sizeof (so->lm32.l_addr));
+  else
+#endif
+    return extract_address (&so->lm.l_addr, sizeof (so->lm.l_addr));
+}
+
+static CORE_ADDR
+LM_NEXT (so)
+     struct so_list *so;
+{
+#if defined (HAVE_STRUCT_LINK_MAP32)
+  if (bfd_get_arch_size (exec_bfd) == 32)
+    return extract_address (&so->lm32.l_next, sizeof (so->lm32.l_next));
+  else
+#endif
+    return extract_address (&so->lm.l_next, sizeof (so->lm.l_next));
+}
+
+static CORE_ADDR
+LM_NAME (so)
+     struct so_list *so;
+{
+#if defined (HAVE_STRUCT_LINK_MAP32)
+  if (bfd_get_arch_size (exec_bfd) == 32)
+    return extract_address (&so->lm32.l_name, sizeof (so->lm32.l_name));
+  else
+#endif
+    return extract_address (&so->lm.l_name, sizeof (so->lm.l_name));
+}
+
+static int
+IGNORE_FIRST_LINK_MAP_ENTRY (so)
+     struct so_list *so;
+{
+#if defined (HAVE_STRUCT_LINK_MAP32)
+  if (bfd_get_arch_size (exec_bfd) == 32)
+    return (solib_extract_address (&(so) -> lm32.l_prev) == 0);
+  else
+#endif
+    return (solib_extract_address (&(so) -> lm.l_prev) == 0);
+}
+
+#endif /* !SVR4_SHARED_LIBS */
+
+
 static CORE_ADDR debug_base;   /* Base of dynamic linker structures */
 static CORE_ADDR breakpoint_addr;      /* Address where end bkpt is set */
 
 static int solib_cleanup_queued = 0;   /* make_run_cleanup called */
 
 static CORE_ADDR debug_base;   /* Base of dynamic linker structures */
 static CORE_ADDR breakpoint_addr;      /* Address where end bkpt is set */
 
 static int solib_cleanup_queued = 0;   /* make_run_cleanup called */
 
-extern int
-fdmatch PARAMS ((int, int));   /* In libiberty */
+extern int fdmatch (int, int); /* In libiberty */
 
 /* Local function prototypes */
 
 
 /* Local function prototypes */
 
-static void
-do_clear_solib PARAMS ((PTR));
+static void do_clear_solib (PTR);
 
 
-static int
-match_main PARAMS ((char *));
+static int match_main (char *);
 
 
-static void
-special_symbol_handling PARAMS ((void));
+static void special_symbol_handling (void);
 
 
-static void
-sharedlibrary_command PARAMS ((char *, int));
+static void sharedlibrary_command (char *, int);
 
 
-static int
-enable_break PARAMS ((void));
+static int enable_break (void);
 
 
-static void
-info_sharedlibrary_command PARAMS ((char *, int));
+static void info_sharedlibrary_command (char *, int);
 
 
-static int symbol_add_stub PARAMS ((PTR));
+static int symbol_add_stub (PTR);
 
 
-static CORE_ADDR
-  first_link_map_member PARAMS ((void));
+static CORE_ADDR first_link_map_member (void);
 
 
-static CORE_ADDR
-  locate_base PARAMS ((void));
+static CORE_ADDR locate_base (void);
 
 
-static int solib_map_sections PARAMS ((PTR));
+static int solib_map_sections (PTR);
 
 #ifdef SVR4_SHARED_LIBS
 
 
 #ifdef SVR4_SHARED_LIBS
 
-static CORE_ADDR
-  elf_locate_base PARAMS ((void));
+static CORE_ADDR elf_locate_base (void);
 
 #else
 
 static struct so_list *current_sos (void);
 static void free_so (struct so_list *node);
 
 
 #else
 
 static struct so_list *current_sos (void);
 static void free_so (struct so_list *node);
 
-static int
-disable_break PARAMS ((void));
+static int disable_break (void);
 
 
-static void
-allocate_rt_common_objfile PARAMS ((void));
+static void allocate_rt_common_objfile (void);
 
 static void
 solib_add_common_symbols (CORE_ADDR);
 
 #endif
 
 
 static void
 solib_add_common_symbols (CORE_ADDR);
 
 #endif
 
-void _initialize_solib PARAMS ((void));
+void _initialize_solib (void);
 
 /* If non-zero, this is a prefix that will be added to the front of the name
    shared libraries with an absolute filename for loading.  */
 
 /* If non-zero, this is a prefix that will be added to the front of the name
    shared libraries with an absolute filename for loading.  */
@@ -277,8 +376,7 @@ static char *solib_search_path = NULL;
  */
 
 static int
  */
 
 static int
-solib_map_sections (arg)
-     PTR arg;
+solib_map_sections (PTR arg)
 {
   struct so_list *so = (struct so_list *) arg; /* catch_errors bogon */
   char *filename;
 {
   struct so_list *so = (struct so_list *) arg; /* catch_errors bogon */
   char *filename;
@@ -386,7 +484,7 @@ solib_map_sections (arg)
 /* Allocate the runtime common object file.  */
 
 static void
 /* Allocate the runtime common object file.  */
 
 static void
-allocate_rt_common_objfile ()
+allocate_rt_common_objfile (void)
 {
   struct objfile *objfile;
   struct objfile *last_one;
 {
   struct objfile *objfile;
   struct objfile *last_one;
@@ -425,8 +523,7 @@ allocate_rt_common_objfile ()
    objfile.  */
 
 static void
    objfile.  */
 
 static void
-solib_add_common_symbols (rtc_symp)
-     CORE_ADDR rtc_symp;
+solib_add_common_symbols (CORE_ADDR rtc_symp)
 {
   struct rtc_symb inferior_rtc_symb;
   struct nlist inferior_rtc_nlist;
 {
   struct rtc_symb inferior_rtc_symb;
   struct nlist inferior_rtc_nlist;
@@ -445,7 +542,7 @@ solib_add_common_symbols (rtc_symp)
     }
 
   init_minimal_symbol_collection ();
     }
 
   init_minimal_symbol_collection ();
-  make_cleanup ((make_cleanup_func) discard_minimal_symbols, 0);
+  make_cleanup_discard_minimal_symbols ();
 
   while (rtc_symp)
     {
 
   while (rtc_symp)
     {
@@ -488,8 +585,7 @@ solib_add_common_symbols (rtc_symp)
 
 #ifdef SVR4_SHARED_LIBS
 
 
 #ifdef SVR4_SHARED_LIBS
 
-static CORE_ADDR
-  bfd_lookup_symbol PARAMS ((bfd *, char *));
+static CORE_ADDR bfd_lookup_symbol (bfd *, char *);
 
 /*
 
 
 /*
 
@@ -513,9 +609,7 @@ static CORE_ADDR
  */
 
 static CORE_ADDR
  */
 
 static CORE_ADDR
-bfd_lookup_symbol (abfd, symname)
-     bfd *abfd;
-     char *symname;
+bfd_lookup_symbol (bfd *abfd, char *symname)
 {
   unsigned int storage_needed;
   asymbol *sym;
 {
   unsigned int storage_needed;
   asymbol *sym;
@@ -545,7 +639,35 @@ bfd_lookup_symbol (abfd, symname)
        }
       do_cleanups (back_to);
     }
        }
       do_cleanups (back_to);
     }
-  return (symaddr);
+
+  if (symaddr)
+    return symaddr;
+
+  /* On FreeBSD, the dynamic linker is stripped by default.  So we'll
+     have to check the dynamic string table too.  */
+
+  storage_needed = bfd_get_dynamic_symtab_upper_bound (abfd);
+
+  if (storage_needed > 0)
+    {
+      symbol_table = (asymbol **) xmalloc (storage_needed);
+      back_to = make_cleanup (free, (PTR) symbol_table);
+      number_of_symbols = bfd_canonicalize_dynamic_symtab (abfd, symbol_table);
+
+      for (i = 0; i < number_of_symbols; i++)
+       {
+         sym = *symbol_table++;
+         if (STREQ (sym->name, symname))
+           {
+             /* Bfd symbols are section relative. */
+             symaddr = sym->value + sym->section->vma;
+             break;
+           }
+       }
+      do_cleanups (back_to);
+    }
+
+  return symaddr;
 }
 
 #ifdef HANDLE_SVR4_EXEC_EMULATORS
 }
 
 #ifdef HANDLE_SVR4_EXEC_EMULATORS
@@ -574,8 +696,7 @@ static char *debug_base_symbols[] =
   NULL
 };
 
   NULL
 };
 
-static int
-look_for_base PARAMS ((int, CORE_ADDR));
+static int look_for_base (int, CORE_ADDR);
 
 /*
 
 
 /*
 
@@ -604,9 +725,7 @@ look_for_base PARAMS ((int, CORE_ADDR));
  */
 
 static int
  */
 
 static int
-look_for_base (fd, baseaddr)
-     int fd;
-     CORE_ADDR baseaddr;
+look_for_base (int fd, CORE_ADDR baseaddr)
 {
   bfd *interp_bfd;
   CORE_ADDR address = 0;
 {
   bfd *interp_bfd;
   CORE_ADDR address = 0;
@@ -703,13 +822,14 @@ look_for_base (fd, baseaddr)
  */
 
 static CORE_ADDR
  */
 
 static CORE_ADDR
-elf_locate_base ()
+elf_locate_base (void)
 {
   sec_ptr dyninfo_sect;
   int dyninfo_sect_size;
   CORE_ADDR dyninfo_addr;
   char *buf;
   char *bufend;
 {
   sec_ptr dyninfo_sect;
   int dyninfo_sect_size;
   CORE_ADDR dyninfo_addr;
   char *buf;
   char *bufend;
+  int arch_size;
 
   /* Find the start address of the .dynamic section.  */
   dyninfo_sect = bfd_get_section_by_name (exec_bfd, ".dynamic");
 
   /* Find the start address of the .dynamic section.  */
   dyninfo_sect = bfd_get_section_by_name (exec_bfd, ".dynamic");
@@ -726,56 +846,68 @@ elf_locate_base ()
   /* Find the DT_DEBUG entry in the the .dynamic section.
      For mips elf we look for DT_MIPS_RLD_MAP, mips elf apparently has
      no DT_DEBUG entries.  */
   /* Find the DT_DEBUG entry in the the .dynamic section.
      For mips elf we look for DT_MIPS_RLD_MAP, mips elf apparently has
      no DT_DEBUG entries.  */
-#ifndef TARGET_ELF64
-  for (bufend = buf + dyninfo_sect_size;
-       buf < bufend;
-       buf += sizeof (Elf32_External_Dyn))
-    {
-      Elf32_External_Dyn *x_dynp = (Elf32_External_Dyn *) buf;
-      long dyn_tag;
-      CORE_ADDR dyn_ptr;
-
-      dyn_tag = bfd_h_get_32 (exec_bfd, (bfd_byte *) x_dynp->d_tag);
-      if (dyn_tag == DT_NULL)
-       break;
-      else if (dyn_tag == DT_DEBUG)
+
+  arch_size = bfd_get_arch_size (exec_bfd);
+  if (arch_size == -1) /* failure */
+    return 0;
+
+  if (arch_size == 32)
+    { /* 32-bit elf */
+      for (bufend = buf + dyninfo_sect_size;
+          buf < bufend;
+          buf += sizeof (Elf32_External_Dyn))
        {
        {
-         dyn_ptr = bfd_h_get_32 (exec_bfd, (bfd_byte *) x_dynp->d_un.d_ptr);
-         return dyn_ptr;
-       }
+         Elf32_External_Dyn *x_dynp = (Elf32_External_Dyn *) buf;
+         long dyn_tag;
+         CORE_ADDR dyn_ptr;
+
+         dyn_tag = bfd_h_get_32 (exec_bfd, (bfd_byte *) x_dynp->d_tag);
+         if (dyn_tag == DT_NULL)
+           break;
+         else if (dyn_tag == DT_DEBUG)
+           {
+             dyn_ptr = bfd_h_get_32 (exec_bfd, 
+                                     (bfd_byte *) x_dynp->d_un.d_ptr);
+             return dyn_ptr;
+           }
 #ifdef DT_MIPS_RLD_MAP
 #ifdef DT_MIPS_RLD_MAP
-      else if (dyn_tag == DT_MIPS_RLD_MAP)
-       {
-         char pbuf[TARGET_PTR_BIT / HOST_CHAR_BIT];
-
-         /* DT_MIPS_RLD_MAP contains a pointer to the address
-            of the dynamic link structure.  */
-         dyn_ptr = bfd_h_get_32 (exec_bfd, (bfd_byte *) x_dynp->d_un.d_ptr);
-         if (target_read_memory (dyn_ptr, pbuf, sizeof (pbuf)))
-           return 0;
-         return extract_unsigned_integer (pbuf, sizeof (pbuf));
-       }
+         else if (dyn_tag == DT_MIPS_RLD_MAP)
+           {
+             char *pbuf;
+
+             pbuf = alloca (TARGET_PTR_BIT / HOST_CHAR_BIT);
+             /* DT_MIPS_RLD_MAP contains a pointer to the address
+                of the dynamic link structure.  */
+             dyn_ptr = bfd_h_get_32 (exec_bfd, 
+                                     (bfd_byte *) x_dynp->d_un.d_ptr);
+             if (target_read_memory (dyn_ptr, pbuf, sizeof (pbuf)))
+               return 0;
+             return extract_unsigned_integer (pbuf, sizeof (pbuf));
+           }
 #endif
 #endif
+       }
     }
     }
-#else /* ELF64 */
-  for (bufend = buf + dyninfo_sect_size;
-       buf < bufend;
-       buf += sizeof (Elf64_External_Dyn))
+  else /* 64-bit elf */
     {
     {
-      Elf64_External_Dyn *x_dynp = (Elf64_External_Dyn *) buf;
-      long dyn_tag;
-      CORE_ADDR dyn_ptr;
-
-      dyn_tag = bfd_h_get_64 (exec_bfd, (bfd_byte *) x_dynp->d_tag);
-      if (dyn_tag == DT_NULL)
-       break;
-      else if (dyn_tag == DT_DEBUG)
+      for (bufend = buf + dyninfo_sect_size;
+          buf < bufend;
+          buf += sizeof (Elf64_External_Dyn))
        {
        {
-         dyn_ptr = bfd_h_get_64 (exec_bfd, (bfd_byte *) x_dynp->d_un.d_ptr);
-         return dyn_ptr;
+         Elf64_External_Dyn *x_dynp = (Elf64_External_Dyn *) buf;
+         long dyn_tag;
+         CORE_ADDR dyn_ptr;
+
+         dyn_tag = bfd_h_get_64 (exec_bfd, (bfd_byte *) x_dynp->d_tag);
+         if (dyn_tag == DT_NULL)
+           break;
+         else if (dyn_tag == DT_DEBUG)
+           {
+             dyn_ptr = bfd_h_get_64 (exec_bfd, 
+                                     (bfd_byte *) x_dynp->d_un.d_ptr);
+             return dyn_ptr;
+           }
        }
     }
        }
     }
-#endif
 
   /* DT_DEBUG entry not found.  */
   return 0;
 
   /* DT_DEBUG entry not found.  */
   return 0;
@@ -821,7 +953,7 @@ elf_locate_base ()
  */
 
 static CORE_ADDR
  */
 
 static CORE_ADDR
-locate_base ()
+locate_base (void)
 {
 
 #ifndef SVR4_SHARED_LIBS
 {
 
 #ifndef SVR4_SHARED_LIBS
@@ -887,7 +1019,7 @@ locate_base ()
    does the reading.  */
 
 static CORE_ADDR
    does the reading.  */
 
 static CORE_ADDR
-first_link_map_member ()
+first_link_map_member (void)
 {
   CORE_ADDR lm = 0;
 
 {
   CORE_ADDR lm = 0;
 
@@ -904,12 +1036,23 @@ first_link_map_member ()
     }
 
 #else /* SVR4_SHARED_LIBS */
     }
 
 #else /* SVR4_SHARED_LIBS */
-
-  read_memory (debug_base, (char *) &debug_copy, sizeof (struct r_debug));
+#if defined (HAVE_STRUCT_LINK_MAP32)
+  if (bfd_get_arch_size (exec_bfd) == 32)
+    {
+      read_memory (debug_base, (char *) &debug32_copy, 
+                  sizeof (struct r_debug32));
+      lm = SOLIB_EXTRACT_ADDRESS (debug32_copy.r_map);
+    }
+  else
+#endif
+    {
+      read_memory (debug_base, (char *) &debug_copy, 
+                  sizeof (struct r_debug));
+      lm = SOLIB_EXTRACT_ADDRESS (debug_copy.r_map);
+    }
   /* FIXME:  Perhaps we should validate the info somehow, perhaps by
      checking r_version for a known version number, or r_state for
      RT_CONSISTENT. */
   /* FIXME:  Perhaps we should validate the info somehow, perhaps by
      checking r_version for a known version number, or r_state for
      RT_CONSISTENT. */
-  lm = SOLIB_EXTRACT_ADDRESS (debug_copy.r_map);
 
 #endif /* !SVR4_SHARED_LIBS */
 
 
 #endif /* !SVR4_SHARED_LIBS */
 
@@ -921,7 +1064,7 @@ first_link_map_member ()
 
   LOCAL FUNCTION
 
 
   LOCAL FUNCTION
 
-  open_exec_file_object
+  open_symbol_file_object
 
   SYNOPSIS
 
 
   SYNOPSIS
 
@@ -936,13 +1079,11 @@ first_link_map_member ()
 
  */
 
 
  */
 
-int
-open_symbol_file_object (arg)
-     PTR arg;
+static int
+open_symbol_file_object (from_ttyp)
+     int *from_ttyp;   /* sneak past catch_errors */
 {
 {
-  int from_tty = (int) arg;    /* sneak past catch_errors */
   CORE_ADDR lm;
   CORE_ADDR lm;
-  struct link_map lmcopy;
   char *filename;
   int errcode;
 
   char *filename;
   int errcode;
 
@@ -957,15 +1098,35 @@ open_symbol_file_object (arg)
   if ((lm = first_link_map_member ()) == 0)
     return 0;  /* failed somehow... */
 
   if ((lm = first_link_map_member ()) == 0)
     return 0;  /* failed somehow... */
 
-  /* Read from target memory to GDB.  */
-  read_memory (lm, (void *) &lmcopy, sizeof (lmcopy));
+#if defined (HAVE_STRUCT_LINK_MAP32)
+  if (bfd_get_arch_size (exec_bfd) == 32)
+    {
+      struct link_map32 lmcopy;
+      /* Read from target memory to GDB.  */
+      read_memory (lm, (void *) &lmcopy, sizeof (lmcopy));
+
+      if (lmcopy.l_name == 0)
+       return 0;       /* no filename.  */
+
+      /* Now fetch the filename from target memory.  */
+      target_read_string (SOLIB_EXTRACT_ADDRESS (lmcopy.l_name), 
+                         &filename, MAX_PATH_SIZE - 1, &errcode);
+    }
+  else
+#endif /* HAVE_STRUCT_LINK_MAP32 */
+    {
+      struct link_map lmcopy;
+      /* Read from target memory to GDB.  */
+      read_memory (lm, (void *) &lmcopy, sizeof (lmcopy));
 
 
-  if (lmcopy.l_name == 0)
-    return 0;  /* no filename.  */
+      if (lmcopy.l_name == 0)
+       return 0;       /* no filename.  */
+
+      /* Now fetch the filename from target memory.  */
+      target_read_string (SOLIB_EXTRACT_ADDRESS (lmcopy.l_name), &filename, 
+                         MAX_PATH_SIZE - 1, &errcode);
+    }
 
 
-  /* Now fetch the filename from target memory.  */
-  target_read_string (SOLIB_EXTRACT_ADDRESS (lmcopy.l_name), &filename, 
-                     MAX_PATH_SIZE - 1, &errcode);
   if (errcode)
     {
       warning ("failed to read exec filename from attached file: %s",
   if (errcode)
     {
       warning ("failed to read exec filename from attached file: %s",
@@ -973,9 +1134,9 @@ open_symbol_file_object (arg)
       return 0;
     }
 
       return 0;
     }
 
-  make_cleanup ((make_cleanup_func) free, (void *) filename);
+  make_cleanup (free, filename);
   /* Have a pathname: read the symbol file.  */
   /* Have a pathname: read the symbol file.  */
-  symbol_file_command (filename, from_tty);
+  symbol_file_command (filename, *from_ttyp);
 
   return 1;
 }
 
   return 1;
 }
@@ -1031,8 +1192,7 @@ free_so (struct so_list *so)
    non-zero iff SONAME matches one of the known main executable names.  */
 
 static int
    non-zero iff SONAME matches one of the known main executable names.  */
 
 static int
-match_main (soname)
-     char *soname;
+match_main (char *soname)
 {
   char **mainp;
 
 {
   char **mainp;
 
@@ -1066,7 +1226,7 @@ match_main (soname)
    we provide values for.  */
 
 static struct so_list *
    we provide values for.  */
 
 static struct so_list *
-current_sos ()
+current_sos (void)
 {
   CORE_ADDR lm;
   struct so_list *head = 0;
 {
   CORE_ADDR lm;
   struct so_list *head = 0;
@@ -1095,7 +1255,13 @@ current_sos ()
       memset (new, 0, sizeof (*new));
 
       new->lmaddr = lm;
       memset (new, 0, sizeof (*new));
 
       new->lmaddr = lm;
-      read_memory (lm, (char *) &(new->lm), sizeof (struct link_map));
+
+#if defined (HAVE_STRUCT_LINK_MAP32)
+      if (bfd_get_arch_size (exec_bfd) == 32)
+       read_memory (lm, (char *) &(new->lm32), sizeof (struct link_map32));
+      else
+#endif
+       read_memory (lm, (char *) &(new->lm), sizeof (struct link_map));
 
       lm = LM_NEXT (new);
 
 
       lm = LM_NEXT (new);
 
@@ -1150,12 +1316,13 @@ current_sos ()
 /* A small stub to get us past the arg-passing pinhole of catch_errors.  */
 
 static int
 /* A small stub to get us past the arg-passing pinhole of catch_errors.  */
 
 static int
-symbol_add_stub (arg)
-     PTR arg;
+symbol_add_stub (PTR arg)
 {
   register struct so_list *so = (struct so_list *) arg;  /* catch_errs bogon */
 {
   register struct so_list *so = (struct so_list *) arg;  /* catch_errs bogon */
-  CORE_ADDR text_addr = 0;
   struct section_addr_info *sap;
   struct section_addr_info *sap;
+  CORE_ADDR lowest_addr = 0;
+  int lowest_index;
+  asection *lowest_sect = NULL;
 
   /* Have we already loaded this shared object?  */
   ALL_OBJFILES (so->objfile)
 
   /* Have we already loaded this shared object?  */
   ALL_OBJFILES (so->objfile)
@@ -1166,25 +1333,33 @@ symbol_add_stub (arg)
 
   /* Find the shared object's text segment.  */
   if (so->textsection)
 
   /* Find the shared object's text segment.  */
   if (so->textsection)
-    text_addr = so->textsection->addr;
+    {
+      lowest_addr = so->textsection->addr;
+      lowest_sect = bfd_get_section_by_name (so->abfd, ".text");
+      lowest_index = lowest_sect->index;
+    }
   else if (so->abfd != NULL)
     {
   else if (so->abfd != NULL)
     {
-      asection *lowest_sect;
-
-      /* If we didn't find a mapped non zero sized .text section, set up
-         text_addr so that the relocation in symbol_file_add does no harm.  */
+      /* If we didn't find a mapped non zero sized .text section, set
+         up lowest_addr so that the relocation in symbol_file_add does
+         no harm.  */
       lowest_sect = bfd_get_section_by_name (so->abfd, ".text");
       if (lowest_sect == NULL)
        bfd_map_over_sections (so->abfd, find_lowest_section,
                               (PTR) &lowest_sect);
       if (lowest_sect)
       lowest_sect = bfd_get_section_by_name (so->abfd, ".text");
       if (lowest_sect == NULL)
        bfd_map_over_sections (so->abfd, find_lowest_section,
                               (PTR) &lowest_sect);
       if (lowest_sect)
-       text_addr = bfd_section_vma (so->abfd, lowest_sect)
-         + LM_ADDR (so);
+       {
+         lowest_addr = bfd_section_vma (so->abfd, lowest_sect)
+           + LM_ADDR (so);
+         lowest_index = lowest_sect->index;
+       }
     }
 
   sap = build_section_addr_info_from_section_table (so->sections,
                                                     so->sections_end);
     }
 
   sap = build_section_addr_info_from_section_table (so->sections,
                                                     so->sections_end);
-  sap->text_addr = text_addr;
+
+  sap->other[lowest_index].addr = lowest_addr;
+
   so->objfile = symbol_file_add (so->so_name, so->from_tty,
                                 sap, 0, OBJF_SHARED);
   free_section_addr_info (sap);
   so->objfile = symbol_file_add (so->so_name, so->from_tty,
                                 sap, 0, OBJF_SHARED);
   free_section_addr_info (sap);
@@ -1195,22 +1370,22 @@ symbol_add_stub (arg)
 
 /* LOCAL FUNCTION
 
 
 /* LOCAL FUNCTION
 
-   solib_add -- synchronize GDB's shared object list with the inferior's
+   update_solib_list --- synchronize GDB's shared object list with inferior's
 
    SYNOPSIS
 
 
    SYNOPSIS
 
-   void solib_add (char *pattern, int from_tty, struct target_ops *TARGET)
-
-   DESCRIPTION
+   void update_solib_list (int from_tty, struct target_ops *TARGET)
 
    Extract the list of currently loaded shared objects from the
 
    Extract the list of currently loaded shared objects from the
-   inferior, and compare it with the list of shared objects for which
-   GDB has currently loaded symbolic information.  If new shared
-   objects have been loaded, or old shared objects have disappeared,
-   make the appropriate changes to GDB's tables.
+   inferior, and compare it with the list of shared objects currently
+   in GDB's so_list_head list.  Edit so_list_head to bring it in sync
+   with the inferior's new list.
 
 
-   If PATTERN is non-null, read symbols only for shared objects
-   whose names match PATTERN.
+   If we notice that the inferior has unloaded some shared objects,
+   free any symbolic info GDB had read about those shared objects.
+
+   Don't load symbolic info for any new shared objects; just add them
+   to the list, and leave their symbols_loaded flag clear.
 
    If FROM_TTY is non-null, feel free to print messages about what
    we're doing.
 
    If FROM_TTY is non-null, feel free to print messages about what
    we're doing.
@@ -1223,7 +1398,7 @@ symbol_add_stub (arg)
    processes we've just attached to, so that's okay.  */
 
 void
    processes we've just attached to, so that's okay.  */
 
 void
-solib_add (char *pattern, int from_tty, struct target_ops *target)
+update_solib_list (int from_tty, struct target_ops *target)
 {
   struct so_list *inferior = current_sos ();
   struct so_list *gdb, **gdb_link;
 {
   struct so_list *inferior = current_sos ();
   struct so_list *gdb, **gdb_link;
@@ -1234,20 +1409,12 @@ solib_add (char *pattern, int from_tty, struct target_ops *target)
      symbols now!  */
   if (attach_flag &&
       symfile_objfile == NULL)
      symbols now!  */
   if (attach_flag &&
       symfile_objfile == NULL)
-    catch_errors (open_symbol_file_object, (PTR) from_tty, 
+    catch_errors (open_symbol_file_object, (PTR) &from_tty, 
                  "Error reading attached process's symbol file.\n",
                  RETURN_MASK_ALL);
 
 #endif SVR4_SHARED_LIBS
 
                  "Error reading attached process's symbol file.\n",
                  RETURN_MASK_ALL);
 
 #endif SVR4_SHARED_LIBS
 
-  if (pattern)
-    {
-      char *re_err = re_comp (pattern);
-
-      if (re_err)
-       error ("Invalid regexp: %s", re_err);
-    }
-
   /* Since this function might actually add some elements to the
      so_list_head list, arrange for it to be cleaned up when
      appropriate.  */
   /* Since this function might actually add some elements to the
      so_list_head list, arrange for it to be cleaned up when
      appropriate.  */
@@ -1263,16 +1430,16 @@ solib_add (char *pattern, int from_tty, struct target_ops *target)
      shared objects appear where.  There are three cases:
 
      - A shared object appears on both lists.  This means that GDB
      shared objects appear where.  There are three cases:
 
      - A shared object appears on both lists.  This means that GDB
-       knows about it already, and it's still loaded in the inferior.
-       Nothing needs to happen.
+     knows about it already, and it's still loaded in the inferior.
+     Nothing needs to happen.
 
      - A shared object appears only on GDB's list.  This means that
 
      - A shared object appears only on GDB's list.  This means that
-       the inferior has unloaded it.  We should remove the shared
-       object from GDB's tables.
+     the inferior has unloaded it.  We should remove the shared
+     object from GDB's tables.
 
      - A shared object appears only on the inferior's list.  This
 
      - A shared object appears only on the inferior's list.  This
-       means that it's just been loaded.  We should add it to GDB's
-       tables.
+     means that it's just been loaded.  We should add it to GDB's
+     tables.
 
      So we walk GDB's list, checking each entry to see if it appears
      in the inferior's list too.  If it does, no action is needed, and
 
      So we walk GDB's list, checking each entry to see if it appears
      in the inferior's list too.  If it does, no action is needed, and
@@ -1316,7 +1483,7 @@ solib_add (char *pattern, int from_tty, struct target_ops *target)
          *gdb_link = gdb->next;
 
          /* Unless the user loaded it explicitly, free SO's objfile.  */
          *gdb_link = gdb->next;
 
          /* Unless the user loaded it explicitly, free SO's objfile.  */
-         if (! (gdb->objfile->flags & OBJF_USERLOADED))
+         if (gdb->objfile && ! (gdb->objfile->flags & OBJF_USERLOADED))
            free_objfile (gdb->objfile);
 
          /* Some targets' section tables might be referring to
            free_objfile (gdb->objfile);
 
          /* Some targets' section tables might be referring to
@@ -1330,8 +1497,7 @@ solib_add (char *pattern, int from_tty, struct target_ops *target)
 
   /* Now the inferior's list contains only shared objects that don't
      appear in GDB's list --- those that are newly loaded.  Add them
 
   /* Now the inferior's list contains only shared objects that don't
      appear in GDB's list --- those that are newly loaded.  Add them
-     to GDB's shared object list, and read in their symbols, if
-     appropriate.  */
+     to GDB's shared object list.  */
   if (inferior)
     {
       struct so_list *i;
   if (inferior)
     {
       struct so_list *i;
@@ -1339,8 +1505,7 @@ solib_add (char *pattern, int from_tty, struct target_ops *target)
       /* Add the new shared objects to GDB's list.  */
       *gdb_link = inferior;
 
       /* Add the new shared objects to GDB's list.  */
       *gdb_link = inferior;
 
-      /* Fill in the rest of each of the `struct so_list' nodes, and
-        read symbols for those files whose names match PATTERN.  */
+      /* Fill in the rest of each of the `struct so_list' nodes.  */
       for (i = inferior; i; i = i->next)
        {
          i->from_tty = from_tty;
       for (i = inferior; i; i = i->next)
        {
          i->from_tty = from_tty;
@@ -1349,29 +1514,6 @@ solib_add (char *pattern, int from_tty, struct target_ops *target)
          catch_errors (solib_map_sections, i,
                        "Error while mapping shared library sections:\n",
                        RETURN_MASK_ALL);
          catch_errors (solib_map_sections, i,
                        "Error while mapping shared library sections:\n",
                        RETURN_MASK_ALL);
-
-         if (! pattern || re_exec (i->so_name))
-           {
-             if (i->symbols_loaded)
-               {
-                 if (from_tty)
-                   printf_unfiltered ("Symbols already loaded for %s\n",
-                                      i->so_name);
-               }
-             else
-               {
-                 if (catch_errors
-                     (symbol_add_stub, i,
-                      "Error while reading shared library symbols:\n",
-                      RETURN_MASK_ALL))
-                   {
-                     if (from_tty)
-                       printf_unfiltered ("Loaded symbols for %s\n",
-                                          i->so_name);
-                     i->symbols_loaded = 1;
-                   }
-               }
-           }
        }
 
       /* If requested, add the shared objects' sections to the the
        }
 
       /* If requested, add the shared objects' sections to the the
@@ -1399,13 +1541,88 @@ solib_add (char *pattern, int from_tty, struct target_ops *target)
                }
            }
        }
                }
            }
        }
+    }
+}
+
 
 
-      /* Getting new symbols may change our opinion about what is
-         frameless.  */
-      reinit_frame_cache ();
+/* GLOBAL FUNCTION
+
+   solib_add -- read in symbol info for newly added shared libraries
+
+   SYNOPSIS
+
+   void solib_add (char *pattern, int from_tty, struct target_ops *TARGET)
+
+   DESCRIPTION
+
+   Read in symbolic information for any shared objects whose names
+   match PATTERN.  (If we've already read a shared object's symbol
+   info, leave it alone.)  If PATTERN is zero, read them all.
+
+   FROM_TTY and TARGET are as described for update_solib_list, above.  */
+
+void
+solib_add (char *pattern, int from_tty, struct target_ops *target)
+{
+  struct so_list *gdb;
+
+  if (pattern)
+    {
+      char *re_err = re_comp (pattern);
 
 
-      special_symbol_handling ();
+      if (re_err)
+       error ("Invalid regexp: %s", re_err);
     }
     }
+
+  update_solib_list (from_tty, target);
+
+  /* Walk the list of currently loaded shared libraries, and read
+     symbols for any that match the pattern --- or any whose symbols
+     aren't already loaded, if no pattern was given.  */
+  {
+    int any_matches = 0;
+    int loaded_any_symbols = 0;
+
+    for (gdb = so_list_head; gdb; gdb = gdb->next)
+      if (! pattern || re_exec (gdb->so_name))
+       {
+         any_matches = 1;
+
+         if (gdb->symbols_loaded)
+           {
+             if (from_tty)
+               printf_unfiltered ("Symbols already loaded for %s\n",
+                                  gdb->so_name);
+           }
+         else
+           {
+             if (catch_errors
+                 (symbol_add_stub, gdb,
+                  "Error while reading shared library symbols:\n",
+                  RETURN_MASK_ALL))
+               {
+                 if (from_tty)
+                   printf_unfiltered ("Loaded symbols for %s\n",
+                                      gdb->so_name);
+                 gdb->symbols_loaded = 1;
+                 loaded_any_symbols = 1;
+               }
+           }
+       }
+
+    if (from_tty && pattern && ! any_matches)
+      printf_unfiltered
+       ("No loaded shared libraries match the pattern `%s'.\n", pattern);
+
+    if (loaded_any_symbols)
+      {
+       /* Getting new symbols may change our opinion about what is
+          frameless.  */
+       reinit_frame_cache ();
+
+       special_symbol_handling ();
+      }
+  }
 }
 
 
 }
 
 
@@ -1426,14 +1643,13 @@ solib_add (char *pattern, int from_tty, struct target_ops *target)
  */
 
 static void
  */
 
 static void
-info_sharedlibrary_command (ignore, from_tty)
-     char *ignore;
-     int from_tty;
+info_sharedlibrary_command (char *ignore, int from_tty)
 {
   register struct so_list *so = NULL;  /* link map state variable */
   int header_done = 0;
   int addr_width;
   char *addr_fmt;
 {
   register struct so_list *so = NULL;  /* link map state variable */
   int header_done = 0;
   int addr_width;
   char *addr_fmt;
+  int arch_size;
 
   if (exec_bfd == NULL)
     {
 
   if (exec_bfd == NULL)
     {
@@ -1441,15 +1657,20 @@ info_sharedlibrary_command (ignore, from_tty)
       return;
     }
 
       return;
     }
 
-#ifndef TARGET_ELF64
-  addr_width = 8 + 4;
-  addr_fmt = "08l";
-#else
-  addr_width = 16 + 4;
-  addr_fmt = "016l";
-#endif
+  arch_size = bfd_get_arch_size (exec_bfd);
+  /* Default to 32-bit in case of failure (non-elf). */
+  if (arch_size == 32 || arch_size == -1)
+    {
+      addr_width = 8 + 4;
+      addr_fmt = "08l";
+    }
+  else if (arch_size == 64)
+    {
+      addr_width = 16 + 4;
+      addr_fmt = "016l";
+    }
 
 
-  solib_add (0, 0, 0);
+  update_solib_list (from_tty, 0);
 
   for (so = so_list_head; so; so = so->next)
     {
 
   for (so = so_list_head; so; so = so->next)
     {
@@ -1504,8 +1725,7 @@ info_sharedlibrary_command (ignore, from_tty)
  */
 
 char *
  */
 
 char *
-solib_address (address)
-     CORE_ADDR address;
+solib_address (CORE_ADDR address)
 {
   register struct so_list *so = 0;     /* link map state variable */
 
 {
   register struct so_list *so = 0;     /* link map state variable */
 
@@ -1521,7 +1741,7 @@ solib_address (address)
 /* Called by free_all_symtabs */
 
 void
 /* Called by free_all_symtabs */
 
 void
-clear_solib ()
+clear_solib (void)
 {
   /* This function is expected to handle ELF shared libraries.  It is
      also used on Solaris, which can run either ELF or a.out binaries
 {
   /* This function is expected to handle ELF shared libraries.  It is
      also used on Solaris, which can run either ELF or a.out binaries
@@ -1558,8 +1778,7 @@ clear_solib ()
 }
 
 static void
 }
 
 static void
-do_clear_solib (dummy)
-     PTR dummy;
+do_clear_solib (PTR dummy)
 {
   solib_cleanup_queued = 0;
   clear_solib ();
 {
   solib_cleanup_queued = 0;
   clear_solib ();
@@ -1576,8 +1795,7 @@ static CORE_ADDR interp_plt_sect_low;
 static CORE_ADDR interp_plt_sect_high;
 
 int
 static CORE_ADDR interp_plt_sect_high;
 
 int
-in_svr4_dynsym_resolve_code (pc)
-     CORE_ADDR pc;
+in_svr4_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)
 {
   return ((pc >= interp_text_sect_low && pc < interp_text_sect_high)
          || (pc >= interp_plt_sect_low && pc < interp_plt_sect_high)
@@ -1605,7 +1823,7 @@ in_svr4_dynsym_resolve_code (pc)
 #ifndef SVR4_SHARED_LIBS
 
 static int
 #ifndef SVR4_SHARED_LIBS
 
 static int
-disable_break ()
+disable_break (void)
 {
   int status = 1;
 
 {
   int status = 1;
 
@@ -1698,7 +1916,7 @@ disable_break ()
  */
 
 static int
  */
 
 static int
-enable_break ()
+enable_break (void)
 {
   int success = 0;
 
 {
   int success = 0;
 
@@ -1911,7 +2129,7 @@ enable_break ()
  */
 
 void
  */
 
 void
-solib_create_inferior_hook ()
+solib_create_inferior_hook (void)
 {
   /* If we are using the BKPT_AT_SYMBOL code, then we don't need the base
      yet.  In fact, in the case of a SunOS4 executable being run on
 {
   /* If we are using the BKPT_AT_SYMBOL code, then we don't need the base
      yet.  In fact, in the case of a SunOS4 executable being run on
@@ -1999,7 +2217,7 @@ solib_create_inferior_hook ()
  */
 
 static void
  */
 
 static void
-special_symbol_handling ()
+special_symbol_handling (void)
 {
 #ifndef SVR4_SHARED_LIBS
   int j;
 {
 #ifndef SVR4_SHARED_LIBS
   int j;
@@ -2057,9 +2275,7 @@ special_symbol_handling ()
  */
 
 static void
  */
 
 static void
-sharedlibrary_command (args, from_tty)
-     char *args;
-     int from_tty;
+sharedlibrary_command (char *args, int from_tty)
 {
   dont_repeat ();
   solib_add (args, from_tty, (struct target_ops *) 0);
 {
   dont_repeat ();
   solib_add (args, from_tty, (struct target_ops *) 0);
@@ -2068,7 +2284,7 @@ sharedlibrary_command (args, from_tty)
 #endif /* HAVE_LINK_H */
 
 void
 #endif /* HAVE_LINK_H */
 
 void
-_initialize_solib ()
+_initialize_solib (void)
 {
 #ifdef HAVE_LINK_H
 
 {
 #ifdef HAVE_LINK_H
 
This page took 0.036116 seconds and 4 git commands to generate.