gdb/
[deliverable/binutils-gdb.git] / gdb / solib-svr4.c
index 554a1e31dee8ddd1af7ea877f275df94f38972f5..37cc654dbdd58212f68bf25cc736d60e6ea53b35 100644 (file)
@@ -1,8 +1,7 @@
 /* Handle SVR4 shared libraries for GDB, the GNU Debugger.
 
-   Copyright (C) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000,
-   2001, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011
-   Free Software Foundation, Inc.
+   Copyright (C) 1990-1996, 1998-2001, 2003-2012 Free Software
+   Foundation, Inc.
 
    This file is part of GDB.
 
@@ -47,6 +46,7 @@
 #include "exec.h"
 #include "auxv.h"
 #include "exceptions.h"
+#include "gdb_bfd.h"
 
 static struct link_map_offsets *svr4_fetch_link_map_offsets (void);
 static int svr4_have_link_map_offsets (void);
@@ -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;
+
+      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);
+    }
 
-  return extract_typed_address (so->lm_info->lm + lmo->l_addr_offset,
-                               ptr_type);
+  do_cleanups (back_to);
+
+  return lm_info;
 }
 
 static int
@@ -160,30 +189,20 @@ has_lm_dynamic_from_link_map (void)
   return lmo->l_ld_offset >= 0;
 }
 
-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)
@@ -245,7 +264,7 @@ lm_addr_check (struct so_list *so, bfd *abfd)
              if (info_verbose)
                printf_unfiltered (_("Using PIC (Position Independent Code) "
                                     "prelink displacement %s for \"%s\".\n"),
-                                  paddress (target_gdbarch, l_addr),
+                                  paddress (target_gdbarch (), l_addr),
                                   so->so_name);
            }
          else
@@ -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
@@ -373,11 +363,12 @@ static int match_main (const char *);
 static gdb_byte *
 read_program_header (int type, int *p_sect_size, int *p_arch_size)
 {
-  enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch);
-  CORE_ADDR at_phdr, at_phent, at_phnum;
+  enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch ());
+  CORE_ADDR at_phdr, at_phent, at_phnum, pt_phdr = 0;
   int arch_size, sect_size;
   CORE_ADDR sect_addr;
   gdb_byte *buf;
+  int pt_phdr_p = 0;
 
   /* Get required auxv elements from target.  */
   if (target_auxv_search (&current_target, AT_PHDR, &at_phdr) <= 0)
@@ -411,12 +402,23 @@ read_program_header (int type, int *p_sect_size, int *p_arch_size)
       /* Search for requested PHDR.  */
       for (i = 0; i < at_phnum; i++)
        {
+         int p_type;
+
          if (target_read_memory (at_phdr + i * sizeof (phdr),
                                  (gdb_byte *)&phdr, sizeof (phdr)))
            return 0;
 
-         if (extract_unsigned_integer ((gdb_byte *)phdr.p_type,
-                                       4, byte_order) == type)
+         p_type = extract_unsigned_integer ((gdb_byte *) phdr.p_type,
+                                            4, byte_order);
+
+         if (p_type == PT_PHDR)
+           {
+             pt_phdr_p = 1;
+             pt_phdr = extract_unsigned_integer ((gdb_byte *) phdr.p_vaddr,
+                                                 4, byte_order);
+           }
+
+         if (p_type == type)
            break;
        }
 
@@ -437,12 +439,23 @@ read_program_header (int type, int *p_sect_size, int *p_arch_size)
       /* Search for requested PHDR.  */
       for (i = 0; i < at_phnum; i++)
        {
+         int p_type;
+
          if (target_read_memory (at_phdr + i * sizeof (phdr),
                                  (gdb_byte *)&phdr, sizeof (phdr)))
            return 0;
 
-         if (extract_unsigned_integer ((gdb_byte *)phdr.p_type,
-                                       4, byte_order) == type)
+         p_type = extract_unsigned_integer ((gdb_byte *) phdr.p_type,
+                                            4, byte_order);
+
+         if (p_type == PT_PHDR)
+           {
+             pt_phdr_p = 1;
+             pt_phdr = extract_unsigned_integer ((gdb_byte *) phdr.p_vaddr,
+                                                 8, byte_order);
+           }
+
+         if (p_type == type)
            break;
        }
 
@@ -456,6 +469,16 @@ read_program_header (int type, int *p_sect_size, int *p_arch_size)
                                            8, byte_order);
     }
 
+  /* PT_PHDR is optional, but we really need it
+     for PIE to make this work in general.  */
+
+  if (pt_phdr_p)
+    {
+      /* at_phdr is real address in memory. pt_phdr is what pheader says it is.
+        Relocation offset is the difference between the two. */
+      sect_addr = sect_addr + (at_phdr - pt_phdr);
+    }
+
   /* Read in requested program header.  */
   buf = xmalloc (sect_size);
   if (target_read_memory (sect_addr, buf, sect_size))
@@ -589,7 +612,7 @@ scan_dyntag (int dyntag, bfd *abfd, CORE_ADDR *ptr)
             gdb_byte ptr_buf[8];
             CORE_ADDR ptr_addr;
 
-            ptr_type = builtin_type (target_gdbarch)->builtin_data_ptr;
+            ptr_type = builtin_type (target_gdbarch ())->builtin_data_ptr;
             ptr_addr = dyn_addr + (buf - bufstart) + arch_size / 8;
             if (target_read_memory (ptr_addr, ptr_buf, arch_size / 8) == 0)
               dyn_ptr = extract_typed_address (ptr_buf, ptr_type);
@@ -609,7 +632,7 @@ scan_dyntag (int dyntag, bfd *abfd, CORE_ADDR *ptr)
 static int
 scan_dyntag_auxv (int dyntag, CORE_ADDR *ptr)
 {
-  enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch);
+  enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch ());
   int sect_size, arch_size, step;
   long dyn_tag;
   CORE_ADDR dyn_ptr;
@@ -686,7 +709,7 @@ elf_locate_base (void)
   if (scan_dyntag (DT_MIPS_RLD_MAP, exec_bfd, &dyn_ptr)
       || scan_dyntag_auxv (DT_MIPS_RLD_MAP, &dyn_ptr))
     {
-      struct type *ptr_type = builtin_type (target_gdbarch)->builtin_data_ptr;
+      struct type *ptr_type = builtin_type (target_gdbarch ())->builtin_data_ptr;
       gdb_byte *pbuf;
       int pbuf_size = TYPE_LENGTH (ptr_type);
 
@@ -764,7 +787,7 @@ static CORE_ADDR
 solib_svr4_r_map (struct svr4_info *info)
 {
   struct link_map_offsets *lmo = svr4_fetch_link_map_offsets ();
-  struct type *ptr_type = builtin_type (target_gdbarch)->builtin_data_ptr;
+  struct type *ptr_type = builtin_type (target_gdbarch ())->builtin_data_ptr;
   CORE_ADDR addr = 0;
   volatile struct gdb_exception ex;
 
@@ -783,7 +806,7 @@ static CORE_ADDR
 solib_svr4_r_brk (struct svr4_info *info)
 {
   struct link_map_offsets *lmo = svr4_fetch_link_map_offsets ();
-  struct type *ptr_type = builtin_type (target_gdbarch)->builtin_data_ptr;
+  struct type *ptr_type = builtin_type (target_gdbarch ())->builtin_data_ptr;
 
   return read_memory_typed_address (info->debug_base + lmo->r_brk_offset,
                                    ptr_type);
@@ -796,8 +819,8 @@ static CORE_ADDR
 solib_svr4_r_ldsomap (struct svr4_info *info)
 {
   struct link_map_offsets *lmo = svr4_fetch_link_map_offsets ();
-  struct type *ptr_type = builtin_type (target_gdbarch)->builtin_data_ptr;
-  enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch);
+  struct type *ptr_type = builtin_type (target_gdbarch ())->builtin_data_ptr;
+  enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch ());
   ULONGEST version;
 
   /* Check version, and return zero if `struct r_debug' doesn't have
@@ -843,14 +866,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);
@@ -871,7 +889,7 @@ open_symbol_file_object (void *from_ttyp)
   int errcode;
   int from_tty = *(int *)from_ttyp;
   struct link_map_offsets *lmo = svr4_fetch_link_map_offsets ();
-  struct type *ptr_type = builtin_type (target_gdbarch)->builtin_data_ptr;
+  struct type *ptr_type = builtin_type (target_gdbarch ())->builtin_data_ptr;
   int l_name_size = TYPE_LENGTH (ptr_type);
   gdb_byte *l_name_buf = xmalloc (l_name_size);
   struct cleanup *cleanups = make_cleanup (xfree, l_name_buf);
@@ -931,13 +949,23 @@ open_symbol_file_object (void *from_ttyp)
   return 1;
 }
 
+/* Data exchange structure for the XML parser as returned by
+   svr4_current_sos_via_xfer_libraries.  */
+
+struct svr4_library_list
+{
+  struct so_list *head, **tailp;
+
+  /* Inferior address of struct link_map used for the main executable.  It is
+     NULL if not known.  */
+  CORE_ADDR main_lm;
+};
+
 /* Implementation for target_so_ops.free_so.  */
 
 static void
 svr4_free_so (struct so_list *so)
 {
-  if (so->lm_info)
-    xfree (so->lm_info->lm);
   xfree (so->lm_info);
 }
 
@@ -952,11 +980,163 @@ svr4_free_library_list (void *p_list)
     {
       struct so_list *next = list->next;
 
-      svr4_free_so (list);
+      free_so (list);
       list = next;
     }
 }
 
+#ifdef HAVE_LIBEXPAT
+
+#include "xml-support.h"
+
+/* Handle the start of a <library> element.  Note: new elements are added
+   at the tail of the list, keeping the list in order.  */
+
+static void
+library_list_start_library (struct gdb_xml_parser *parser,
+                           const struct gdb_xml_element *element,
+                           void *user_data, VEC(gdb_xml_value_s) *attributes)
+{
+  struct svr4_library_list *list = user_data;
+  const char *name = xml_find_attribute (attributes, "name")->value;
+  ULONGEST *lmp = xml_find_attribute (attributes, "lm")->value;
+  ULONGEST *l_addrp = xml_find_attribute (attributes, "l_addr")->value;
+  ULONGEST *l_ldp = xml_find_attribute (attributes, "l_ld")->value;
+  struct so_list *new_elem;
+
+  new_elem = XZALLOC (struct so_list);
+  new_elem->lm_info = XZALLOC (struct lm_info);
+  new_elem->lm_info->lm_addr = *lmp;
+  new_elem->lm_info->l_addr_inferior = *l_addrp;
+  new_elem->lm_info->l_ld = *l_ldp;
+
+  strncpy (new_elem->so_name, name, sizeof (new_elem->so_name) - 1);
+  new_elem->so_name[sizeof (new_elem->so_name) - 1] = 0;
+  strcpy (new_elem->so_original_name, new_elem->so_name);
+
+  *list->tailp = new_elem;
+  list->tailp = &new_elem->next;
+}
+
+/* Handle the start of a <library-list-svr4> element.  */
+
+static void
+svr4_library_list_start_list (struct gdb_xml_parser *parser,
+                             const struct gdb_xml_element *element,
+                             void *user_data, VEC(gdb_xml_value_s) *attributes)
+{
+  struct svr4_library_list *list = user_data;
+  const char *version = xml_find_attribute (attributes, "version")->value;
+  struct gdb_xml_value *main_lm = xml_find_attribute (attributes, "main-lm");
+
+  if (strcmp (version, "1.0") != 0)
+    gdb_xml_error (parser,
+                  _("SVR4 Library list has unsupported version \"%s\""),
+                  version);
+
+  if (main_lm)
+    list->main_lm = *(ULONGEST *) main_lm->value;
+}
+
+/* The allowed elements and attributes for an XML library list.
+   The root element is a <library-list>.  */
+
+static const struct gdb_xml_attribute svr4_library_attributes[] =
+{
+  { "name", GDB_XML_AF_NONE, NULL, NULL },
+  { "lm", GDB_XML_AF_NONE, gdb_xml_parse_attr_ulongest, NULL },
+  { "l_addr", GDB_XML_AF_NONE, gdb_xml_parse_attr_ulongest, NULL },
+  { "l_ld", GDB_XML_AF_NONE, gdb_xml_parse_attr_ulongest, NULL },
+  { NULL, GDB_XML_AF_NONE, NULL, NULL }
+};
+
+static const struct gdb_xml_element svr4_library_list_children[] =
+{
+  {
+    "library", svr4_library_attributes, NULL,
+    GDB_XML_EF_REPEATABLE | GDB_XML_EF_OPTIONAL,
+    library_list_start_library, NULL
+  },
+  { NULL, NULL, NULL, GDB_XML_EF_NONE, NULL, NULL }
+};
+
+static const struct gdb_xml_attribute svr4_library_list_attributes[] =
+{
+  { "version", GDB_XML_AF_NONE, NULL, NULL },
+  { "main-lm", GDB_XML_AF_OPTIONAL, gdb_xml_parse_attr_ulongest, NULL },
+  { NULL, GDB_XML_AF_NONE, NULL, NULL }
+};
+
+static const struct gdb_xml_element svr4_library_list_elements[] =
+{
+  { "library-list-svr4", svr4_library_list_attributes, svr4_library_list_children,
+    GDB_XML_EF_NONE, svr4_library_list_start_list, NULL },
+  { NULL, NULL, NULL, GDB_XML_EF_NONE, NULL, NULL }
+};
+
+/* Parse qXfer:libraries:read packet into *SO_LIST_RETURN.  Return 1 if
+
+   Return 0 if packet not supported, *SO_LIST_RETURN is not modified in such
+   case.  Return 1 if *SO_LIST_RETURN contains the library list, it may be
+   empty, caller is responsible for freeing all its entries.  */
+
+static int
+svr4_parse_libraries (const char *document, struct svr4_library_list *list)
+{
+  struct cleanup *back_to = make_cleanup (svr4_free_library_list,
+                                         &list->head);
+
+  memset (list, 0, sizeof (*list));
+  list->tailp = &list->head;
+  if (gdb_xml_parse_quick (_("target library list"), "library-list.dtd",
+                          svr4_library_list_elements, document, list) == 0)
+    {
+      /* Parsed successfully, keep the result.  */
+      discard_cleanups (back_to);
+      return 1;
+    }
+
+  do_cleanups (back_to);
+  return 0;
+}
+
+/* Attempt to get so_list from target via qXfer:libraries:read packet.
+
+   Return 0 if packet not supported, *SO_LIST_RETURN is not modified in such
+   case.  Return 1 if *SO_LIST_RETURN contains the library list, it may be
+   empty, caller is responsible for freeing all its entries.  */
+
+static int
+svr4_current_sos_via_xfer_libraries (struct svr4_library_list *list)
+{
+  char *svr4_library_document;
+  int result;
+  struct cleanup *back_to;
+
+  /* Fetch the list of shared libraries.  */
+  svr4_library_document = target_read_stralloc (&current_target,
+                                               TARGET_OBJECT_LIBRARIES_SVR4,
+                                               NULL);
+  if (svr4_library_document == NULL)
+    return 0;
+
+  back_to = make_cleanup (xfree, svr4_library_document);
+  result = svr4_parse_libraries (svr4_library_document, list);
+  do_cleanups (back_to);
+
+  return result;
+}
+
+#else
+
+static int
+svr4_current_sos_via_xfer_libraries (struct svr4_library_list *list)
+{
+  return 0;
+}
+
+#endif
+
 /* If no shared library information is available from the dynamic
    linker, build a fallback list from other sources.  */
 
@@ -971,13 +1151,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,18 +1185,20 @@ 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"));
+         warning (_("Corrupted shared library list: %s != %s"),
+                  paddress (target_gdbarch (), prev_lm),
+                  paddress (target_gdbarch (), new->lm_info->l_prev));
          do_cleanups (old_chain);
          break;
        }
@@ -1028,7 +1208,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 +1218,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)
        {
@@ -1079,6 +1259,26 @@ svr4_current_sos (void)
   struct svr4_info *info;
   struct cleanup *back_to;
   int ignore_first;
+  struct svr4_library_list library_list;
+
+  /* Fall back to manual examination of the target if the packet is not
+     supported or gdbserver failed to find DT_DEBUG.  gdb.server/solib-list.exp
+     tests a case where gdbserver cannot find the shared libraries list while
+     GDB itself is able to find it via SYMFILE_OBJFILE.
+
+     Unfortunately statically linked inferiors will also fall back through this
+     suboptimal code path.  */
+
+  if (svr4_current_sos_via_xfer_libraries (&library_list))
+    {
+      if (library_list.main_lm)
+       {
+         info = get_svr4_info ();
+         info->main_lm_addr = library_list.main_lm;
+       }
+
+      return library_list.head ? library_list.head : svr4_default_sos ();
+    }
 
   info = get_svr4_info ();
 
@@ -1196,7 +1396,7 @@ exec_entry_point (struct bfd *abfd, struct target_ops *targ)
      gdbarch_convert_from_func_ptr_addr().  The method
      gdbarch_convert_from_func_ptr_addr() is the merely the identify
      function for targets which don't use function descriptors.  */
-  return gdbarch_convert_from_func_ptr_addr (target_gdbarch,
+  return gdbarch_convert_from_func_ptr_addr (target_gdbarch (),
                                             bfd_get_start_address (abfd),
                                             targ);
 }
@@ -1268,7 +1468,7 @@ enable_break (struct svr4_info *info, int from_tty)
       struct obj_section *os;
 
       sym_addr = gdbarch_addr_bits_remove
-       (target_gdbarch, gdbarch_convert_from_func_ptr_addr (target_gdbarch,
+       (target_gdbarch (), gdbarch_convert_from_func_ptr_addr (target_gdbarch (),
                                                             sym_addr,
                                                             &current_target));
 
@@ -1322,7 +1522,7 @@ enable_break (struct svr4_info *info, int from_tty)
                + bfd_section_size (tmp_bfd, interp_sect);
            }
 
-         create_solib_event_breakpoint (target_gdbarch, sym_addr);
+         create_solib_event_breakpoint (target_gdbarch (), sym_addr);
          return 1;
        }
     }
@@ -1359,9 +1559,11 @@ enable_break (struct svr4_info *info, int from_tty)
        goto bkpt_at_symbol;
 
       /* Now convert the TMP_BFD into a target.  That way target, as
-         well as BFD operations can be used.  Note that closing the
-         target will also close the underlying bfd.  */
+         well as BFD operations can be used.  */
       tmp_bfd_target = target_bfd_reopen (tmp_bfd);
+      /* target_bfd_reopen acquired its own reference, so we can
+         release ours now.  */
+      gdb_bfd_unref (tmp_bfd);
 
       /* On a running target, we can get the dynamic linker's base
          address from the shared library table.  */
@@ -1383,7 +1585,7 @@ enable_break (struct svr4_info *info, int from_tty)
       if (!load_addr_found)
         if (target_auxv_search (&current_target, AT_BASE, &load_addr) > 0)
          {
-           int addr_bit = gdbarch_addr_bit (target_gdbarch);
+           int addr_bit = gdbarch_addr_bit (target_gdbarch ());
 
            /* Ensure LOAD_ADDR has proper sign in its possible upper bits so
               that `+ load_addr' will overflow CORE_ADDR width not creating
@@ -1419,7 +1621,7 @@ enable_break (struct svr4_info *info, int from_tty)
       if (!load_addr_found)
        {
          struct regcache *regcache
-           = get_thread_arch_regcache (inferior_ptid, target_gdbarch);
+           = get_thread_arch_regcache (inferior_ptid, target_gdbarch ());
 
          load_addr = (regcache_read_pc (regcache)
                       - exec_entry_point (tmp_bfd, tmp_bfd_target));
@@ -1467,17 +1669,18 @@ enable_break (struct svr4_info *info, int from_tty)
        /* Convert 'sym_addr' from a function pointer to an address.
           Because we pass tmp_bfd_target instead of the current
           target, this will always produce an unrelocated value.  */
-       sym_addr = gdbarch_convert_from_func_ptr_addr (target_gdbarch,
+       sym_addr = gdbarch_convert_from_func_ptr_addr (target_gdbarch (),
                                                       sym_addr,
                                                       tmp_bfd_target);
 
-      /* We're done with both the temporary bfd and target.  Remember,
-         closing the target closes the underlying bfd.  */
+      /* We're done with both the temporary bfd and target.  Closing
+         the target closes the underlying bfd, because it holds the
+         only remaining reference.  */
       target_close (tmp_bfd_target, 0);
 
       if (sym_addr != 0)
        {
-         create_solib_event_breakpoint (target_gdbarch, load_addr + sym_addr);
+         create_solib_event_breakpoint (target_gdbarch (), load_addr + sym_addr);
          xfree (interp_name);
          return 1;
        }
@@ -1500,15 +1703,15 @@ enable_break (struct svr4_info *info, int from_tty)
       if ((msymbol != NULL) && (SYMBOL_VALUE_ADDRESS (msymbol) != 0))
        {
          sym_addr = SYMBOL_VALUE_ADDRESS (msymbol);
-         sym_addr = gdbarch_convert_from_func_ptr_addr (target_gdbarch,
+         sym_addr = gdbarch_convert_from_func_ptr_addr (target_gdbarch (),
                                                         sym_addr,
                                                         &current_target);
-         create_solib_event_breakpoint (target_gdbarch, sym_addr);
+         create_solib_event_breakpoint (target_gdbarch (), sym_addr);
          return 1;
        }
     }
 
-  if (!current_inferior ()->attach_flag)
+  if (interp_name != NULL && !current_inferior ()->attach_flag)
     {
       for (bkpt_namep = bkpt_names; *bkpt_namep != NULL; bkpt_namep++)
        {
@@ -1516,10 +1719,10 @@ enable_break (struct svr4_info *info, int from_tty)
          if ((msymbol != NULL) && (SYMBOL_VALUE_ADDRESS (msymbol) != 0))
            {
              sym_addr = SYMBOL_VALUE_ADDRESS (msymbol);
-             sym_addr = gdbarch_convert_from_func_ptr_addr (target_gdbarch,
+             sym_addr = gdbarch_convert_from_func_ptr_addr (target_gdbarch (),
                                                             sym_addr,
                                                             &current_target);
-             create_solib_event_breakpoint (target_gdbarch, sym_addr);
+             create_solib_event_breakpoint (target_gdbarch (), sym_addr);
              return 1;
            }
        }
@@ -1660,7 +1863,7 @@ svr4_exec_displacement (CORE_ADDR *displacementp)
       buf2 = read_program_headers_from_bfd (exec_bfd, &phdrs2_size);
       if (buf != NULL && buf2 != NULL)
        {
-         enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch);
+         enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch ());
 
          /* We are dealing with three different addresses.  EXEC_BFD
             represents current address in on-disk file.  target memory content
@@ -1915,7 +2118,7 @@ svr4_exec_displacement (CORE_ADDR *displacementp)
 
       printf_unfiltered (_("Using PIE (Position Independent Executable) "
                           "displacement %s for \"%s\".\n"),
-                        paddress (target_gdbarch, displacement),
+                        paddress (target_gdbarch (), displacement),
                         bfd_get_filename (exec_bfd));
     }
 
@@ -2058,13 +2261,13 @@ svr4_solib_create_inferior_hook (int from_tty)
 
   clear_proceed_status ();
   inf->control.stop_soon = STOP_QUIETLY;
-  tp->suspend.stop_signal = TARGET_SIGNAL_0;
+  tp->suspend.stop_signal = GDB_SIGNAL_0;
   do
     {
       target_resume (pid_to_ptid (-1), 0, tp->suspend.stop_signal);
       wait_for_inferior ();
     }
-  while (tp->suspend.stop_signal != TARGET_SIGNAL_TRAP);
+  while (tp->suspend.stop_signal != GDB_SIGNAL_TRAP);
   inf->control.stop_soon = NO_STOP_QUIETLY;
 #endif /* defined(_SCO_DS) */
 }
@@ -2098,12 +2301,12 @@ svr4_clear_solib (void)
 static CORE_ADDR
 svr4_truncate_ptr (CORE_ADDR addr)
 {
-  if (gdbarch_ptr_bit (target_gdbarch) == sizeof (CORE_ADDR) * 8)
+  if (gdbarch_ptr_bit (target_gdbarch ()) == sizeof (CORE_ADDR) * 8)
     /* We don't need to truncate anything, and the bit twiddling below
        will fail due to overflow problems.  */
     return addr;
   else
-    return addr & (((CORE_ADDR) 1 << gdbarch_ptr_bit (target_gdbarch)) - 1);
+    return addr & (((CORE_ADDR) 1 << gdbarch_ptr_bit (target_gdbarch ())) - 1);
 }
 
 
@@ -2161,7 +2364,7 @@ set_solib_svr4_fetch_link_map_offsets (struct gdbarch *gdbarch,
 static struct link_map_offsets *
 svr4_fetch_link_map_offsets (void)
 {
-  struct solib_svr4_ops *ops = gdbarch_data (target_gdbarch, solib_svr4_data);
+  struct solib_svr4_ops *ops = gdbarch_data (target_gdbarch (), solib_svr4_data);
 
   gdb_assert (ops->fetch_link_map_offsets);
   return ops->fetch_link_map_offsets ();
@@ -2172,7 +2375,7 @@ svr4_fetch_link_map_offsets (void)
 static int
 svr4_have_link_map_offsets (void)
 {
-  struct solib_svr4_ops *ops = gdbarch_data (target_gdbarch, solib_svr4_data);
+  struct solib_svr4_ops *ops = gdbarch_data (target_gdbarch (), solib_svr4_data);
 
   return (ops->fetch_link_map_offsets != NULL);
 }
@@ -2281,7 +2484,7 @@ _initialize_svr4_solib (void)
 {
   solib_svr4_data = gdbarch_data_register_pre_init (solib_svr4_init);
   solib_svr4_pspace_data
-    = register_program_space_data_with_cleanup (svr4_pspace_data_cleanup);
+    = register_program_space_data_with_cleanup (NULL, svr4_pspace_data_cleanup);
 
   svr4_so_ops.relocate_section_addresses = svr4_relocate_section_addresses;
   svr4_so_ops.free_so = svr4_free_so;
This page took 0.033765 seconds and 4 git commands to generate.