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.
-   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.
@@ -19,7 +19,7 @@
    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. */
@@ -49,7 +49,7 @@
 #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"
@@ -107,24 +107,33 @@ static char *main_name_list[] =
   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
-   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
 
-#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;
@@ -133,13 +142,11 @@ static CORE_ADDR flag_addr;
 
 #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;
+#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 */
@@ -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 */
+#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
@@ -179,66 +189,155 @@ struct so_list
   };
 
 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 */
 
-extern int
-fdmatch PARAMS ((int, int));   /* In libiberty */
+extern int fdmatch (int, int); /* In libiberty */
 
 /* 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
 
-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);
 
-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
 
-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.  */
@@ -277,8 +376,7 @@ static char *solib_search_path = NULL;
  */
 
 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;
@@ -386,7 +484,7 @@ solib_map_sections (arg)
 /* Allocate the runtime common object file.  */
 
 static void
-allocate_rt_common_objfile ()
+allocate_rt_common_objfile (void)
 {
   struct objfile *objfile;
   struct objfile *last_one;
@@ -425,8 +523,7 @@ allocate_rt_common_objfile ()
    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;
@@ -445,7 +542,7 @@ solib_add_common_symbols (rtc_symp)
     }
 
   init_minimal_symbol_collection ();
-  make_cleanup ((make_cleanup_func) discard_minimal_symbols, 0);
+  make_cleanup_discard_minimal_symbols ();
 
   while (rtc_symp)
     {
@@ -488,8 +585,7 @@ solib_add_common_symbols (rtc_symp)
 
 #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
-bfd_lookup_symbol (abfd, symname)
-     bfd *abfd;
-     char *symname;
+bfd_lookup_symbol (bfd *abfd, char *symname)
 {
   unsigned int storage_needed;
   asymbol *sym;
@@ -545,7 +639,35 @@ bfd_lookup_symbol (abfd, symname)
        }
       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
@@ -574,8 +696,7 @@ static char *debug_base_symbols[] =
   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
-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;
@@ -703,13 +822,14 @@ look_for_base (fd, baseaddr)
  */
 
 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;
+  int arch_size;
 
   /* 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.  */
-#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
-      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
+       }
     }
-#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;
@@ -821,7 +953,7 @@ elf_locate_base ()
  */
 
 static CORE_ADDR
-locate_base ()
+locate_base (void)
 {
 
 #ifndef SVR4_SHARED_LIBS
@@ -887,7 +1019,7 @@ locate_base ()
    does the reading.  */
 
 static CORE_ADDR
-first_link_map_member ()
+first_link_map_member (void)
 {
   CORE_ADDR lm = 0;
 
@@ -904,12 +1036,23 @@ first_link_map_member ()
     }
 
 #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. */
-  lm = SOLIB_EXTRACT_ADDRESS (debug_copy.r_map);
 
 #endif /* !SVR4_SHARED_LIBS */
 
@@ -921,7 +1064,7 @@ first_link_map_member ()
 
   LOCAL FUNCTION
 
-  open_exec_file_object
+  open_symbol_file_object
 
   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;
-  struct link_map lmcopy;
   char *filename;
   int errcode;
 
@@ -957,15 +1098,35 @@ open_symbol_file_object (arg)
   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",
@@ -973,9 +1134,9 @@ open_symbol_file_object (arg)
       return 0;
     }
 
-  make_cleanup ((make_cleanup_func) free, (void *) filename);
+  make_cleanup (free, filename);
   /* Have a pathname: read the symbol file.  */
-  symbol_file_command (filename, from_tty);
+  symbol_file_command (filename, *from_ttyp);
 
   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
-match_main (soname)
-     char *soname;
+match_main (char *soname)
 {
   char **mainp;
 
@@ -1066,7 +1226,7 @@ match_main (soname)
    we provide values for.  */
 
 static struct so_list *
-current_sos ()
+current_sos (void)
 {
   CORE_ADDR lm;
   struct so_list *head = 0;
@@ -1095,7 +1255,13 @@ current_sos ()
       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);
 
@@ -1150,12 +1316,13 @@ current_sos ()
 /* 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 */
-  CORE_ADDR text_addr = 0;
   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)
@@ -1166,25 +1333,33 @@ symbol_add_stub (arg)
 
   /* 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)
     {
-      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)
-       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->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);
@@ -1195,22 +1370,22 @@ symbol_add_stub (arg)
 
 /* 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
 
-   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
-   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.
@@ -1223,7 +1398,7 @@ symbol_add_stub (arg)
    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;
@@ -1234,20 +1409,12 @@ solib_add (char *pattern, int from_tty, struct target_ops *target)
      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
 
-  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.  */
@@ -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
-       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
-       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
-       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
@@ -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.  */
-         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
@@ -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
-     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;
@@ -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;
 
-      /* 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;
@@ -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);
-
-         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
@@ -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
-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;
+  int arch_size;
 
   if (exec_bfd == NULL)
     {
@@ -1441,15 +1657,20 @@ info_sharedlibrary_command (ignore, from_tty)
       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)
     {
@@ -1504,8 +1725,7 @@ info_sharedlibrary_command (ignore, from_tty)
  */
 
 char *
-solib_address (address)
-     CORE_ADDR address;
+solib_address (CORE_ADDR address)
 {
   register struct so_list *so = 0;     /* link map state variable */
 
@@ -1521,7 +1741,7 @@ solib_address (address)
 /* 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
@@ -1558,8 +1778,7 @@ clear_solib ()
 }
 
 static void
-do_clear_solib (dummy)
-     PTR dummy;
+do_clear_solib (PTR dummy)
 {
   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
-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)
@@ -1605,7 +1823,7 @@ in_svr4_dynsym_resolve_code (pc)
 #ifndef SVR4_SHARED_LIBS
 
 static int
-disable_break ()
+disable_break (void)
 {
   int status = 1;
 
@@ -1698,7 +1916,7 @@ disable_break ()
  */
 
 static int
-enable_break ()
+enable_break (void)
 {
   int success = 0;
 
@@ -1911,7 +2129,7 @@ enable_break ()
  */
 
 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
@@ -1999,7 +2217,7 @@ solib_create_inferior_hook ()
  */
 
 static void
-special_symbol_handling ()
+special_symbol_handling (void)
 {
 #ifndef SVR4_SHARED_LIBS
   int j;
@@ -2057,9 +2275,7 @@ special_symbol_handling ()
  */
 
 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);
@@ -2068,7 +2284,7 @@ sharedlibrary_command (args, from_tty)
 #endif /* HAVE_LINK_H */
 
 void
-_initialize_solib ()
+_initialize_solib (void)
 {
 #ifdef HAVE_LINK_H
 
This page took 0.037993 seconds and 4 git commands to generate.