gdb/
authorJan Kratochvil <jan.kratochvil@redhat.com>
Fri, 14 Oct 2011 07:58:58 +0000 (07:58 +0000)
committerJan Kratochvil <jan.kratochvil@redhat.com>
Fri, 14 Oct 2011 07:58:58 +0000 (07:58 +0000)
Drop lazy lm_info reading.
* solib-svr4.c (struct lm_info): Remove field lm.  New fields l_addr_p,
l_addr_inferior, l_ld, l_next, l_prev and l_name.
(lm_info_read): New function.
(lm_addr_from_link_map, lm_dynamic_from_link_map): Remove.
(lm_addr_check): Use l_addr_p.  No longer use lm_addr_from_link_map and
lm_dynamic_from_link_map.
(lm_next, lm_prev, lm_name): Remove.
(svr4_keep_data_in_core): Use lm_info_read, drop the lm_info entries
initialization incl. read_memory.  No longer use lm_name.
(svr4_free_so): Drop lm_info->lm freeing.
(svr4_default_sos): Initialize lminfo with zeroes.  Use l_addr_p.  Drop
explicit lm_addr and lm initialization.
(svr4_read_so_list): Use lm_info_read, drop the initailization of
fields by hand, incl. read_memory.  No longer use lm_next, lm_prev and
lm_name.

gdb/ChangeLog
gdb/solib-svr4.c

index 417a53c..184b466 100644 (file)
@@ -1,4 +1,23 @@
 2011-10-14  Jan Kratochvil  <jan.kratochvil@redhat.com>
+
+       Drop lazy lm_info reading.
+       * solib-svr4.c (struct lm_info): Remove field lm.  New fields l_addr_p,
+       l_addr_inferior, l_ld, l_next, l_prev and l_name.
+       (lm_info_read): New function.
+       (lm_addr_from_link_map, lm_dynamic_from_link_map): Remove.
+       (lm_addr_check): Use l_addr_p.  No longer use lm_addr_from_link_map and
+       lm_dynamic_from_link_map.
+       (lm_next, lm_prev, lm_name): Remove.
+       (svr4_keep_data_in_core): Use lm_info_read, drop the lm_info entries
+       initialization incl. read_memory.  No longer use lm_name.
+       (svr4_free_so): Drop lm_info->lm freeing.
+       (svr4_default_sos): Initialize lminfo with zeroes.  Use l_addr_p.  Drop
+       explicit lm_addr and lm initialization.
+       (svr4_read_so_list): Use lm_info_read, drop the initailization of
+       fields by hand, incl. read_memory.  No longer use lm_next, lm_prev and
+       lm_name.
+
+2011-10-14  Jan Kratochvil  <jan.kratochvil@redhat.com>
            Paul Pluzhnikov  <ppluzhnikov@google.com>
 
        * defs.h (struct so_list): New forward declaration.
index 554a1e3..2bb31a9 100644 (file)
@@ -56,20 +56,21 @@ static void svr4_relocate_main_executable (void);
 
 struct lm_info
   {
-    /* Pointer to copy of link map from inferior.  The type is char *
-       rather than void *, so that we may use byte offsets to find the
-       various fields without the need for a cast.  */
-    gdb_byte *lm;
-
     /* Amount by which addresses in the binary should be relocated to
-       match the inferior.  This could most often be taken directly
-       from lm, but when prelinking is involved and the prelink base
-       address changes, we may need a different offset, we want to
-       warn about the difference and compute it only once.  */
-    CORE_ADDR l_addr;
+       match the inferior.  The direct inferior value is L_ADDR_INFERIOR.
+       When prelinking is involved and the prelink base address changes,
+       we may need a different offset - the recomputed offset is in L_ADDR.
+       It is commonly the same value.  It is cached as we want to warn about
+       the difference and compute it only once.  L_ADDR is valid
+       iff L_ADDR_P.  */
+    CORE_ADDR l_addr, l_addr_inferior;
+    unsigned int l_addr_p : 1;
 
     /* The target location of lm.  */
     CORE_ADDR lm_addr;
+
+    /* Values read in from inferior's fields of the same name.  */
+    CORE_ADDR l_ld, l_next, l_prev, l_name;
   };
 
 /* On SVR4 systems, a list of symbols in the dynamic linker where
@@ -140,16 +141,44 @@ svr4_same (struct so_list *gdb, struct so_list *inferior)
   return (svr4_same_1 (gdb->so_original_name, inferior->so_original_name));
 }
 
-/* link map access functions.  */
-
-static CORE_ADDR
-lm_addr_from_link_map (struct so_list *so)
+static struct lm_info *
+lm_info_read (CORE_ADDR lm_addr)
 {
   struct link_map_offsets *lmo = svr4_fetch_link_map_offsets ();
-  struct type *ptr_type = builtin_type (target_gdbarch)->builtin_data_ptr;
+  gdb_byte *lm;
+  struct lm_info *lm_info;
+  struct cleanup *back_to;
+
+  lm = xmalloc (lmo->link_map_size);
+  back_to = make_cleanup (xfree, lm);
+
+  if (target_read_memory (lm_addr, lm, lmo->link_map_size) != 0)
+    {
+      warning (_("Error reading shared library list entry at %s"),
+              paddress (target_gdbarch, lm_addr)),
+      lm_info = NULL;
+    }
+  else
+    {
+      struct type *ptr_type = builtin_type (target_gdbarch)->builtin_data_ptr;
 
-  return extract_typed_address (so->lm_info->lm + lmo->l_addr_offset,
-                               ptr_type);
+      lm_info = xzalloc (sizeof (*lm_info));
+      lm_info->lm_addr = lm_addr;
+
+      lm_info->l_addr_inferior = extract_typed_address (&lm[lmo->l_addr_offset],
+                                                       ptr_type);
+      lm_info->l_ld = extract_typed_address (&lm[lmo->l_ld_offset], ptr_type);
+      lm_info->l_next = extract_typed_address (&lm[lmo->l_next_offset],
+                                              ptr_type);
+      lm_info->l_prev = extract_typed_address (&lm[lmo->l_prev_offset],
+                                              ptr_type);
+      lm_info->l_name = extract_typed_address (&lm[lmo->l_name_offset],
+                                              ptr_type);
+    }
+
+  do_cleanups (back_to);
+
+  return lm_info;
 }
 
 static int
@@ -161,29 +190,19 @@ has_lm_dynamic_from_link_map (void)
 }
 
 static CORE_ADDR
-lm_dynamic_from_link_map (struct so_list *so)
-{
-  struct link_map_offsets *lmo = svr4_fetch_link_map_offsets ();
-  struct type *ptr_type = builtin_type (target_gdbarch)->builtin_data_ptr;
-
-  return extract_typed_address (so->lm_info->lm + lmo->l_ld_offset,
-                               ptr_type);
-}
-
-static CORE_ADDR
 lm_addr_check (struct so_list *so, bfd *abfd)
 {
-  if (so->lm_info->l_addr == (CORE_ADDR)-1)
+  if (!so->lm_info->l_addr_p)
     {
       struct bfd_section *dyninfo_sect;
       CORE_ADDR l_addr, l_dynaddr, dynaddr;
 
-      l_addr = lm_addr_from_link_map (so);
+      l_addr = so->lm_info->l_addr_inferior;
 
       if (! abfd || ! has_lm_dynamic_from_link_map ())
        goto set_addr;
 
-      l_dynaddr = lm_dynamic_from_link_map (so);
+      l_dynaddr = so->lm_info->l_ld;
 
       dyninfo_sect = bfd_get_section_by_name (abfd, ".dynamic");
       if (dyninfo_sect == NULL)
@@ -267,41 +286,12 @@ lm_addr_check (struct so_list *so, bfd *abfd)
 
     set_addr:
       so->lm_info->l_addr = l_addr;
+      so->lm_info->l_addr_p = 1;
     }
 
   return so->lm_info->l_addr;
 }
 
-static CORE_ADDR
-lm_next (struct so_list *so)
-{
-  struct link_map_offsets *lmo = svr4_fetch_link_map_offsets ();
-  struct type *ptr_type = builtin_type (target_gdbarch)->builtin_data_ptr;
-
-  return extract_typed_address (so->lm_info->lm + lmo->l_next_offset,
-                               ptr_type);
-}
-
-static CORE_ADDR
-lm_prev (struct so_list *so)
-{
-  struct link_map_offsets *lmo = svr4_fetch_link_map_offsets ();
-  struct type *ptr_type = builtin_type (target_gdbarch)->builtin_data_ptr;
-
-  return extract_typed_address (so->lm_info->lm + lmo->l_prev_offset,
-                               ptr_type);
-}
-
-static CORE_ADDR
-lm_name (struct so_list *so)
-{
-  struct link_map_offsets *lmo = svr4_fetch_link_map_offsets ();
-  struct type *ptr_type = builtin_type (target_gdbarch)->builtin_data_ptr;
-
-  return extract_typed_address (so->lm_info->lm + lmo->l_name_offset,
-                               ptr_type);
-}
-
 /* Per pspace SVR4 specific data.  */
 
 struct svr4_info
@@ -843,14 +833,9 @@ svr4_keep_data_in_core (CORE_ADDR vaddr, unsigned long size)
   lmo = svr4_fetch_link_map_offsets ();
   new = XZALLOC (struct so_list);
   old_chain = make_cleanup (xfree, new);
-  new->lm_info = xmalloc (sizeof (struct lm_info));
+  new->lm_info = lm_info_read (ldsomap);
   make_cleanup (xfree, new->lm_info);
-  new->lm_info->l_addr = (CORE_ADDR)-1;
-  new->lm_info->lm_addr = ldsomap;
-  new->lm_info->lm = xzalloc (lmo->link_map_size);
-  make_cleanup (xfree, new->lm_info->lm);
-  read_memory (ldsomap, new->lm_info->lm, lmo->link_map_size);
-  name_lm = lm_name (new);
+  name_lm = new->lm_info ? new->lm_info->l_name : 0;
   do_cleanups (old_chain);
 
   return (name_lm >= vaddr && name_lm < vaddr + size);
@@ -936,8 +921,6 @@ open_symbol_file_object (void *from_ttyp)
 static void
 svr4_free_so (struct so_list *so)
 {
-  if (so->lm_info)
-    xfree (so->lm_info->lm);
   xfree (so->lm_info);
 }
 
@@ -971,13 +954,11 @@ svr4_default_sos (void)
 
   new = XZALLOC (struct so_list);
 
-  new->lm_info = xmalloc (sizeof (struct lm_info));
+  new->lm_info = xzalloc (sizeof (struct lm_info));
 
-  /* Nothing will ever check the cached copy of the link
-     map if we set l_addr.  */
+  /* Nothing will ever check the other fields if we set l_addr_p.  */
   new->lm_info->l_addr = info->debug_loader_offset;
-  new->lm_info->lm_addr = 0;
-  new->lm_info->lm = NULL;
+  new->lm_info->l_addr_p = 1;
 
   strncpy (new->so_name, info->debug_loader_name, SO_NAME_MAX_PATH_SIZE - 1);
   new->so_name[SO_NAME_MAX_PATH_SIZE - 1] = '\0';
@@ -1007,16 +988,16 @@ svr4_read_so_list (CORE_ADDR lm, struct so_list ***link_ptr_ptr,
       new = XZALLOC (struct so_list);
       old_chain = make_cleanup_free_so (new);
 
-      new->lm_info = xmalloc (sizeof (struct lm_info));
-      new->lm_info->l_addr = (CORE_ADDR) -1;
-      new->lm_info->lm_addr = lm;
-      new->lm_info->lm = xzalloc (lmo->link_map_size);
-
-      read_memory (lm, new->lm_info->lm, lmo->link_map_size);
+      new->lm_info = lm_info_read (lm);
+      if (new->lm_info == NULL)
+       {
+         do_cleanups (old_chain);
+         break;
+       }
 
-      next_lm = lm_next (new);
+      next_lm = new->lm_info->l_next;
 
-      if (lm_prev (new) != prev_lm)
+      if (new->lm_info->l_prev != prev_lm)
        {
          warning (_("Corrupted shared library list"));
          do_cleanups (old_chain);
@@ -1028,7 +1009,7 @@ svr4_read_so_list (CORE_ADDR lm, struct so_list ***link_ptr_ptr,
          SVR4, it has no name.  For others (Solaris 2.3 for example), it
          does have a name, so we can no longer use a missing name to
          decide when to ignore it.  */
-      if (ignore_first && lm_prev (new) == 0)
+      if (ignore_first && new->lm_info->l_prev == 0)
        {
          struct svr4_info *info = get_svr4_info ();
 
@@ -1038,7 +1019,7 @@ svr4_read_so_list (CORE_ADDR lm, struct so_list ***link_ptr_ptr,
        }
 
       /* Extract this shared object's name.  */
-      target_read_string (lm_name (new), &buffer,
+      target_read_string (new->lm_info->l_name, &buffer,
                          SO_NAME_MAX_PATH_SIZE - 1, &errcode);
       if (errcode != 0)
        {