Use XCNEW gdbarch_tdep
[deliverable/binutils-gdb.git] / gdb / solib-svr4.c
index 2c8d893dc493d2d014bfb3e8f66bc5b3a94124ae..080fd795ed48e70e86c6a7f1676e720e10d1d623 100644 (file)
@@ -1,6 +1,6 @@
 /* Handle SVR4 shared libraries for GDB, the GNU Debugger.
 
-   Copyright (C) 1990-2013 Free Software Foundation, Inc.
+   Copyright (C) 1990-2017 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
 #include "gdbcore.h"
 #include "target.h"
 #include "inferior.h"
+#include "infrun.h"
 #include "regcache.h"
 #include "gdbthread.h"
 #include "observer.h"
 
-#include "gdb_assert.h"
-
 #include "solist.h"
 #include "solib.h"
 #include "solib-svr4.h"
@@ -44,7 +43,6 @@
 #include "elf-bfd.h"
 #include "exec.h"
 #include "auxv.h"
-#include "exceptions.h"
 #include "gdb_bfd.h"
 #include "probe.h"
 
@@ -53,27 +51,6 @@ static int svr4_have_link_map_offsets (void);
 static void svr4_relocate_main_executable (void);
 static void svr4_free_library_list (void *p_list);
 
-/* Link map info to include in an allocated so_list entry.  */
-
-struct lm_info
-  {
-    /* Amount by which addresses in the binary should be relocated to
-       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
    GDB can try to place a breakpoint to monitor shared library
    events.
@@ -191,15 +168,15 @@ svr4_same (struct so_list *gdb, struct so_list *inferior)
   return (svr4_same_1 (gdb->so_original_name, inferior->so_original_name));
 }
 
-static struct lm_info *
+static lm_info_svr4 *
 lm_info_read (CORE_ADDR lm_addr)
 {
   struct link_map_offsets *lmo = svr4_fetch_link_map_offsets ();
   gdb_byte *lm;
-  struct lm_info *lm_info;
+  lm_info_svr4 *lm_info;
   struct cleanup *back_to;
 
-  lm = xmalloc (lmo->link_map_size);
+  lm = (gdb_byte *) xmalloc (lmo->link_map_size);
   back_to = make_cleanup (xfree, lm);
 
   if (target_read_memory (lm_addr, lm, lmo->link_map_size) != 0)
@@ -212,7 +189,7 @@ lm_info_read (CORE_ADDR lm_addr)
     {
       struct type *ptr_type = builtin_type (target_gdbarch ())->builtin_data_ptr;
 
-      lm_info = xzalloc (sizeof (*lm_info));
+      lm_info = new lm_info_svr4;
       lm_info->lm_addr = lm_addr;
 
       lm_info->l_addr_inferior = extract_typed_address (&lm[lmo->l_addr_offset],
@@ -242,17 +219,19 @@ has_lm_dynamic_from_link_map (void)
 static CORE_ADDR
 lm_addr_check (const struct so_list *so, bfd *abfd)
 {
-  if (!so->lm_info->l_addr_p)
+  lm_info_svr4 *li = (lm_info_svr4 *) so->lm_info;
+
+  if (!li->l_addr_p)
     {
       struct bfd_section *dyninfo_sect;
       CORE_ADDR l_addr, l_dynaddr, dynaddr;
 
-      l_addr = so->lm_info->l_addr_inferior;
+      l_addr = li->l_addr_inferior;
 
       if (! abfd || ! has_lm_dynamic_from_link_map ())
        goto set_addr;
 
-      l_dynaddr = so->lm_info->l_ld;
+      l_dynaddr = li->l_ld;
 
       dyninfo_sect = bfd_get_section_by_name (abfd, ".dynamic");
       if (dyninfo_sect == NULL)
@@ -335,11 +314,11 @@ lm_addr_check (const struct so_list *so, bfd *abfd)
        }
 
     set_addr:
-      so->lm_info->l_addr = l_addr;
-      so->lm_info->l_addr_p = 1;
+      li->l_addr = l_addr;
+      li->l_addr_p = 1;
     }
 
-  return so->lm_info->l_addr;
+  return li->l_addr;
 }
 
 /* Per pspace SVR4 specific data.  */
@@ -407,11 +386,7 @@ free_solib_list (struct svr4_info *info)
 static void
 svr4_pspace_data_cleanup (struct program_space *pspace, void *arg)
 {
-  struct svr4_info *info;
-
-  info = program_space_data (pspace, solib_svr4_pspace_data);
-  if (info == NULL)
-    return;
+  struct svr4_info *info = (struct svr4_info *) arg;
 
   free_probes_table (info);
   free_solib_list (info);
@@ -427,11 +402,12 @@ get_svr4_info (void)
 {
   struct svr4_info *info;
 
-  info = program_space_data (current_program_space, solib_svr4_pspace_data);
+  info = (struct svr4_info *) program_space_data (current_program_space,
+                                                 solib_svr4_pspace_data);
   if (info != NULL)
     return info;
 
-  info = XZALLOC (struct svr4_info);
+  info = XCNEW (struct svr4_info);
   set_program_space_data (current_program_space, solib_svr4_pspace_data, info);
   return info;
 }
@@ -449,10 +425,12 @@ static int match_main (const char *);
    Return a pointer to allocated memory holding the program header contents,
    or NULL on failure.  If sucessful, and unless P_SECT_SIZE is NULL, the
    size of those contents is returned to P_SECT_SIZE.  Likewise, the target
-   architecture size (32-bit or 64-bit) is returned to P_ARCH_SIZE.  */
+   architecture size (32-bit or 64-bit) is returned to P_ARCH_SIZE and
+   the base address of the section is returned in BASE_ADDR.  */
 
 static gdb_byte *
-read_program_header (int type, int *p_sect_size, int *p_arch_size)
+read_program_header (int type, int *p_sect_size, int *p_arch_size,
+                    CORE_ADDR *base_addr)
 {
   enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch ());
   CORE_ADDR at_phdr, at_phent, at_phnum, pt_phdr = 0;
@@ -571,7 +549,7 @@ read_program_header (int type, int *p_sect_size, int *p_arch_size)
     }
 
   /* Read in requested program header.  */
-  buf = xmalloc (sect_size);
+  buf = (gdb_byte *) xmalloc (sect_size);
   if (target_read_memory (sect_addr, buf, sect_size))
     {
       xfree (buf);
@@ -582,6 +560,8 @@ read_program_header (int type, int *p_sect_size, int *p_arch_size)
     *p_arch_size = arch_size;
   if (p_sect_size)
     *p_sect_size = sect_size;
+  if (base_addr)
+    *base_addr = sect_addr;
 
   return buf;
 }
@@ -604,27 +584,28 @@ find_program_interpreter (void)
       {
        int sect_size = bfd_section_size (exec_bfd, interp_sect);
 
-       buf = xmalloc (sect_size);
+       buf = (gdb_byte *) xmalloc (sect_size);
        bfd_get_section_contents (exec_bfd, interp_sect, buf, 0, sect_size);
       }
    }
 
   /* If we didn't find it, use the target auxillary vector.  */
   if (!buf)
-    buf = read_program_header (PT_INTERP, NULL, NULL);
+    buf = read_program_header (PT_INTERP, NULL, NULL, NULL);
 
   return (char *) buf;
 }
 
 
-/* Scan for DYNTAG in .dynamic section of ABFD.  If DYNTAG is found 1 is
-   returned and the corresponding PTR is set.  */
+/* Scan for DESIRED_DYNTAG in .dynamic section of ABFD.  If DESIRED_DYNTAG is
+   found, 1 is returned and the corresponding PTR is set.  */
 
 static int
-scan_dyntag (int dyntag, bfd *abfd, CORE_ADDR *ptr)
+scan_dyntag (const int desired_dyntag, bfd *abfd, CORE_ADDR *ptr,
+            CORE_ADDR *ptr_addr)
 {
   int arch_size, step, sect_size;
-  long dyn_tag;
+  long current_dyntag;
   CORE_ADDR dyn_ptr, dyn_addr;
   gdb_byte *bufend, *bufstart, *buf;
   Elf32_External_Dyn *x_dynp_32;
@@ -667,7 +648,7 @@ scan_dyntag (int dyntag, bfd *abfd, CORE_ADDR *ptr)
   /* Read in .dynamic from the BFD.  We will get the actual value
      from memory later.  */
   sect_size = bfd_section_size (abfd, sect);
-  buf = bufstart = alloca (sect_size);
+  buf = bufstart = (gdb_byte *) alloca (sect_size);
   if (!bfd_get_section_contents (abfd, sect,
                                 buf, 0, sect_size))
     return 0;
@@ -682,18 +663,18 @@ scan_dyntag (int dyntag, bfd *abfd, CORE_ADDR *ptr)
     if (arch_size == 32)
       {
        x_dynp_32 = (Elf32_External_Dyn *) buf;
-       dyn_tag = bfd_h_get_32 (abfd, (bfd_byte *) x_dynp_32->d_tag);
+       current_dyntag = bfd_h_get_32 (abfd, (bfd_byte *) x_dynp_32->d_tag);
        dyn_ptr = bfd_h_get_32 (abfd, (bfd_byte *) x_dynp_32->d_un.d_ptr);
       }
     else
       {
        x_dynp_64 = (Elf64_External_Dyn *) buf;
-       dyn_tag = bfd_h_get_64 (abfd, (bfd_byte *) x_dynp_64->d_tag);
+       current_dyntag = bfd_h_get_64 (abfd, (bfd_byte *) x_dynp_64->d_tag);
        dyn_ptr = bfd_h_get_64 (abfd, (bfd_byte *) x_dynp_64->d_un.d_ptr);
       }
-     if (dyn_tag == DT_NULL)
+     if (current_dyntag == DT_NULL)
        return 0;
-     if (dyn_tag == dyntag)
+     if (current_dyntag == desired_dyntag)
        {
         /* If requested, try to read the runtime value of this .dynamic
            entry.  */
@@ -701,13 +682,15 @@ scan_dyntag (int dyntag, bfd *abfd, CORE_ADDR *ptr)
           {
             struct type *ptr_type;
             gdb_byte ptr_buf[8];
-            CORE_ADDR ptr_addr;
+            CORE_ADDR ptr_addr_1;
 
             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)
+            ptr_addr_1 = dyn_addr + (buf - bufstart) + arch_size / 8;
+            if (target_read_memory (ptr_addr_1, ptr_buf, arch_size / 8) == 0)
               dyn_ptr = extract_typed_address (ptr_buf, ptr_type);
             *ptr = dyn_ptr;
+            if (ptr_addr)
+              *ptr_addr = dyn_addr + (buf - bufstart);
           }
         return 1;
        }
@@ -716,21 +699,24 @@ scan_dyntag (int dyntag, bfd *abfd, CORE_ADDR *ptr)
   return 0;
 }
 
-/* Scan for DYNTAG in .dynamic section of the target's main executable,
-   found by consulting the OS auxillary vector.  If DYNTAG is found 1 is
-   returned and the corresponding PTR is set.  */
+/* Scan for DESIRED_DYNTAG in .dynamic section of the target's main executable,
+   found by consulting the OS auxillary vector.  If DESIRED_DYNTAG is found, 1
+   is returned and the corresponding PTR is set.  */
 
 static int
-scan_dyntag_auxv (int dyntag, CORE_ADDR *ptr)
+scan_dyntag_auxv (const int desired_dyntag, CORE_ADDR *ptr,
+                 CORE_ADDR *ptr_addr)
 {
   enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch ());
   int sect_size, arch_size, step;
-  long dyn_tag;
+  long current_dyntag;
   CORE_ADDR dyn_ptr;
+  CORE_ADDR base_addr;
   gdb_byte *bufend, *bufstart, *buf;
 
   /* Read in .dynamic section.  */
-  buf = bufstart = read_program_header (PT_DYNAMIC, &sect_size, &arch_size);
+  buf = bufstart = read_program_header (PT_DYNAMIC, &sect_size, &arch_size,
+                                       &base_addr);
   if (!buf)
     return 0;
 
@@ -745,7 +731,7 @@ scan_dyntag_auxv (int dyntag, CORE_ADDR *ptr)
       {
        Elf32_External_Dyn *dynp = (Elf32_External_Dyn *) buf;
 
-       dyn_tag = extract_unsigned_integer ((gdb_byte *) dynp->d_tag,
+       current_dyntag = extract_unsigned_integer ((gdb_byte *) dynp->d_tag,
                                            4, byte_order);
        dyn_ptr = extract_unsigned_integer ((gdb_byte *) dynp->d_un.d_ptr,
                                            4, byte_order);
@@ -754,19 +740,22 @@ scan_dyntag_auxv (int dyntag, CORE_ADDR *ptr)
       {
        Elf64_External_Dyn *dynp = (Elf64_External_Dyn *) buf;
 
-       dyn_tag = extract_unsigned_integer ((gdb_byte *) dynp->d_tag,
+       current_dyntag = extract_unsigned_integer ((gdb_byte *) dynp->d_tag,
                                            8, byte_order);
        dyn_ptr = extract_unsigned_integer ((gdb_byte *) dynp->d_un.d_ptr,
                                            8, byte_order);
       }
-    if (dyn_tag == DT_NULL)
+    if (current_dyntag == DT_NULL)
       break;
 
-    if (dyn_tag == dyntag)
+    if (current_dyntag == desired_dyntag)
       {
        if (ptr)
          *ptr = dyn_ptr;
 
+       if (ptr_addr)
+         *ptr_addr = base_addr + buf - bufstart;
+
        xfree (bufstart);
        return 1;
       }
@@ -791,20 +780,20 @@ scan_dyntag_auxv (int dyntag, CORE_ADDR *ptr)
 static CORE_ADDR
 elf_locate_base (void)
 {
-  struct minimal_symbol *msymbol;
-  CORE_ADDR dyn_ptr;
+  struct bound_minimal_symbol msymbol;
+  CORE_ADDR dyn_ptr, dyn_ptr_addr;
 
   /* Look for DT_MIPS_RLD_MAP first.  MIPS executables use this
      instead of DT_DEBUG, although they sometimes contain an unused
      DT_DEBUG.  */
-  if (scan_dyntag (DT_MIPS_RLD_MAP, exec_bfd, &dyn_ptr)
-      || scan_dyntag_auxv (DT_MIPS_RLD_MAP, &dyn_ptr))
+  if (scan_dyntag (DT_MIPS_RLD_MAP, exec_bfd, &dyn_ptr, NULL)
+      || scan_dyntag_auxv (DT_MIPS_RLD_MAP, &dyn_ptr, NULL))
     {
       struct type *ptr_type = builtin_type (target_gdbarch ())->builtin_data_ptr;
       gdb_byte *pbuf;
       int pbuf_size = TYPE_LENGTH (ptr_type);
 
-      pbuf = alloca (pbuf_size);
+      pbuf = (gdb_byte *) alloca (pbuf_size);
       /* DT_MIPS_RLD_MAP contains a pointer to the address
         of the dynamic link structure.  */
       if (target_read_memory (dyn_ptr, pbuf, pbuf_size))
@@ -812,16 +801,34 @@ elf_locate_base (void)
       return extract_typed_address (pbuf, ptr_type);
     }
 
+  /* Then check DT_MIPS_RLD_MAP_REL.  MIPS executables now use this form
+     because of needing to support PIE.  DT_MIPS_RLD_MAP will also exist
+     in non-PIE.  */
+  if (scan_dyntag (DT_MIPS_RLD_MAP_REL, exec_bfd, &dyn_ptr, &dyn_ptr_addr)
+      || scan_dyntag_auxv (DT_MIPS_RLD_MAP_REL, &dyn_ptr, &dyn_ptr_addr))
+    {
+      struct type *ptr_type = builtin_type (target_gdbarch ())->builtin_data_ptr;
+      gdb_byte *pbuf;
+      int pbuf_size = TYPE_LENGTH (ptr_type);
+
+      pbuf = (gdb_byte *) alloca (pbuf_size);
+      /* DT_MIPS_RLD_MAP_REL contains an offset from the address of the
+        DT slot to the address of the dynamic link structure.  */
+      if (target_read_memory (dyn_ptr + dyn_ptr_addr, pbuf, pbuf_size))
+       return 0;
+      return extract_typed_address (pbuf, ptr_type);
+    }
+
   /* Find DT_DEBUG.  */
-  if (scan_dyntag (DT_DEBUG, exec_bfd, &dyn_ptr)
-      || scan_dyntag_auxv (DT_DEBUG, &dyn_ptr))
+  if (scan_dyntag (DT_DEBUG, exec_bfd, &dyn_ptr, NULL)
+      || scan_dyntag_auxv (DT_DEBUG, &dyn_ptr, NULL))
     return dyn_ptr;
 
   /* This may be a static executable.  Look for the symbol
      conventionally named _r_debug, as a last resort.  */
   msymbol = lookup_minimal_symbol ("_r_debug", NULL, symfile_objfile);
-  if (msymbol != NULL)
-    return SYMBOL_VALUE_ADDRESS (msymbol);
+  if (msymbol.minsym != NULL)
+    return BMSYMBOL_VALUE_ADDRESS (msymbol);
 
   /* DT_DEBUG entry not found.  */
   return 0;
@@ -880,14 +887,18 @@ 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;
   CORE_ADDR addr = 0;
-  volatile struct gdb_exception ex;
 
-  TRY_CATCH (ex, RETURN_MASK_ERROR)
+  TRY
     {
       addr = read_memory_typed_address (info->debug_base + lmo->r_map_offset,
                                         ptr_type);
     }
-  exception_print (gdb_stderr, ex);
+  CATCH (ex, RETURN_MASK_ERROR)
+    {
+      exception_print (gdb_stderr, ex);
+    }
+  END_CATCH
+
   return addr;
 }
 
@@ -912,13 +923,22 @@ 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 ());
-  ULONGEST version;
+  ULONGEST version = 0;
+
+  TRY
+    {
+      /* Check version, and return zero if `struct r_debug' doesn't have
+        the r_ldsomap member.  */
+      version
+       = read_memory_unsigned_integer (info->debug_base + lmo->r_version_offset,
+                                       lmo->r_version_size, byte_order);
+    }
+  CATCH (ex, RETURN_MASK_ERROR)
+    {
+      exception_print (gdb_stderr, ex);
+    }
+  END_CATCH
 
-  /* Check version, and return zero if `struct r_debug' doesn't have
-     the r_ldsomap member.  */
-  version
-    = read_memory_unsigned_integer (info->debug_base + lmo->r_version_offset,
-                                   lmo->r_version_size, byte_order);
   if (version < 2 || lmo->r_ldsomap_offset == -1)
     return 0;
 
@@ -938,7 +958,7 @@ svr4_keep_data_in_core (CORE_ADDR vaddr, unsigned long size)
 {
   struct svr4_info *info;
   CORE_ADDR ldsomap;
-  struct so_list *new;
+  struct so_list *newobj;
   struct cleanup *old_chain;
   CORE_ADDR name_lm;
 
@@ -953,11 +973,12 @@ svr4_keep_data_in_core (CORE_ADDR vaddr, unsigned long size)
   if (!ldsomap)
     return 0;
 
-  new = XZALLOC (struct so_list);
-  old_chain = make_cleanup (xfree, new);
-  new->lm_info = lm_info_read (ldsomap);
-  make_cleanup (xfree, new->lm_info);
-  name_lm = new->lm_info ? new->lm_info->l_name : 0;
+  newobj = XCNEW (struct so_list);
+  old_chain = make_cleanup (xfree, newobj);
+  lm_info_svr4 *li = lm_info_read (ldsomap);
+  newobj->lm_info = li;
+  make_cleanup (xfree, newobj->lm_info);
+  name_lm = li != NULL ? li->l_name : 0;
   do_cleanups (old_chain);
 
   return (name_lm >= vaddr && name_lm < vaddr + size);
@@ -980,9 +1001,13 @@ open_symbol_file_object (void *from_ttyp)
   struct link_map_offsets *lmo = svr4_fetch_link_map_offsets ();
   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);
+  gdb_byte *l_name_buf = (gdb_byte *) xmalloc (l_name_size);
   struct cleanup *cleanups = make_cleanup (xfree, l_name_buf);
   struct svr4_info *info = get_svr4_info ();
+  symfile_add_flags add_flags = 0;
+
+  if (from_tty)
+    add_flags |= SYMFILE_VERBOSE;
 
   if (symfile_objfile)
     if (!query (_("Attempt to reload symbols from process? ")))
@@ -1032,7 +1057,7 @@ open_symbol_file_object (void *from_ttyp)
     }
 
   /* Have a pathname: read the symbol file.  */
-  symbol_file_add_main (filename, from_tty);
+  symbol_file_add_main (filename, add_flags);
 
   do_cleanups (cleanups);
   return 1;
@@ -1055,7 +1080,9 @@ struct svr4_library_list
 static void
 svr4_free_so (struct so_list *so)
 {
-  xfree (so->lm_info);
+  lm_info_svr4 *li = (lm_info_svr4 *) so->lm_info;
+
+  delete li;
 }
 
 /* Implement target_so_ops.clear_so.  */
@@ -1063,8 +1090,10 @@ svr4_free_so (struct so_list *so)
 static void
 svr4_clear_so (struct so_list *so)
 {
-  if (so->lm_info != NULL)
-    so->lm_info->l_addr_p = 0;
+  lm_info_svr4 *li = (lm_info_svr4 *) so->lm_info;
+
+  if (li != NULL)
+    li->l_addr_p = 0;
 }
 
 /* Free so_list built so far (called via cleanup).  */
@@ -1093,17 +1122,17 @@ svr4_copy_library_list (struct so_list *src)
 
   while (src != NULL)
     {
-      struct so_list *new;
+      struct so_list *newobj;
 
-      new = xmalloc (sizeof (struct so_list));
-      memcpy (new, src, sizeof (struct so_list));
+      newobj = XNEW (struct so_list);
+      memcpy (newobj, src, sizeof (struct so_list));
 
-      new->lm_info = xmalloc (sizeof (struct lm_info));
-      memcpy (new->lm_info, src->lm_info, sizeof (struct lm_info));
+      lm_info_svr4 *src_li = (lm_info_svr4 *) src->lm_info;
+      newobj->lm_info = new lm_info_svr4 (*src_li);
 
-      new->next = NULL;
-      *link = new;
-      link = &new->next;
+      newobj->next = NULL;
+      *link = newobj;
+      link = &newobj->next;
 
       src = src->next;
     }
@@ -1123,18 +1152,23 @@ 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 svr4_library_list *list = (struct svr4_library_list *) user_data;
+  const char *name
+    = (const char *) xml_find_attribute (attributes, "name")->value;
+  ULONGEST *lmp
+    = (ULONGEST *) xml_find_attribute (attributes, "lm")->value;
+  ULONGEST *l_addrp
+    = (ULONGEST *) xml_find_attribute (attributes, "l_addr")->value;
+  ULONGEST *l_ldp
+    = (ULONGEST *) 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;
+  new_elem = XCNEW (struct so_list);
+  lm_info_svr4 *li = new lm_info_svr4;
+  new_elem->lm_info = li;
+  li->lm_addr = *lmp;
+  li->l_addr_inferior = *l_addrp;
+  li->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;
@@ -1151,8 +1185,9 @@ 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 svr4_library_list *list = (struct svr4_library_list *) user_data;
+  const char *version
+    = (const char *) xml_find_attribute (attributes, "version")->value;
   struct gdb_xml_value *main_lm = xml_find_attribute (attributes, "main-lm");
 
   if (strcmp (version, "1.0") != 0)
@@ -1214,7 +1249,7 @@ svr4_parse_libraries (const char *document, struct svr4_library_list *list)
 
   memset (list, 0, sizeof (*list));
   list->tailp = &list->head;
-  if (gdb_xml_parse_quick (_("target library list"), "library-list.dtd",
+  if (gdb_xml_parse_quick (_("target library list"), "library-list-svr4.dtd",
                           svr4_library_list_elements, document, list) == 0)
     {
       /* Parsed successfully, keep the result.  */
@@ -1278,24 +1313,24 @@ static struct so_list *
 svr4_default_sos (void)
 {
   struct svr4_info *info = get_svr4_info ();
-  struct so_list *new;
+  struct so_list *newobj;
 
   if (!info->debug_loader_offset_p)
     return NULL;
 
-  new = XZALLOC (struct so_list);
-
-  new->lm_info = xzalloc (sizeof (struct lm_info));
+  newobj = XCNEW (struct so_list);
+  lm_info_svr4 *li = new lm_info_svr4;
+  newobj->lm_info = li;
 
   /* 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->l_addr_p = 1;
+  li->l_addr = info->debug_loader_offset;
+  li->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';
-  strcpy (new->so_original_name, new->so_name);
+  strncpy (newobj->so_name, info->debug_loader_name, SO_NAME_MAX_PATH_SIZE - 1);
+  newobj->so_name[SO_NAME_MAX_PATH_SIZE - 1] = '\0';
+  strcpy (newobj->so_original_name, newobj->so_name);
 
-  return new;
+  return newobj;
 }
 
 /* Read the whole inferior libraries chain starting at address LM.
@@ -1310,32 +1345,34 @@ static int
 svr4_read_so_list (CORE_ADDR lm, CORE_ADDR prev_lm,
                   struct so_list ***link_ptr_ptr, int ignore_first)
 {
+  CORE_ADDR first_l_name = 0;
   CORE_ADDR next_lm;
 
   for (; lm != 0; prev_lm = lm, lm = next_lm)
     {
-      struct so_list *new;
+      struct so_list *newobj;
       struct cleanup *old_chain;
       int errcode;
       char *buffer;
 
-      new = XZALLOC (struct so_list);
-      old_chain = make_cleanup_free_so (new);
+      newobj = XCNEW (struct so_list);
+      old_chain = make_cleanup_free_so (newobj);
 
-      new->lm_info = lm_info_read (lm);
-      if (new->lm_info == NULL)
+      lm_info_svr4 *li = lm_info_read (lm);
+      newobj->lm_info = li;
+      if (li == NULL)
        {
          do_cleanups (old_chain);
          return 0;
        }
 
-      next_lm = new->lm_info->l_next;
+      next_lm = li->l_next;
 
-      if (new->lm_info->l_prev != prev_lm)
+      if (li->l_prev != prev_lm)
        {
          warning (_("Corrupted shared library list: %s != %s"),
                   paddress (target_gdbarch (), prev_lm),
-                  paddress (target_gdbarch (), new->lm_info->l_prev));
+                  paddress (target_gdbarch (), li->l_prev));
          do_cleanups (old_chain);
          return 0;
        }
@@ -1345,43 +1382,49 @@ svr4_read_so_list (CORE_ADDR lm, CORE_ADDR prev_lm,
          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 && new->lm_info->l_prev == 0)
+      if (ignore_first && li->l_prev == 0)
        {
          struct svr4_info *info = get_svr4_info ();
 
-         info->main_lm_addr = new->lm_info->lm_addr;
+         first_l_name = li->l_name;
+         info->main_lm_addr = li->lm_addr;
          do_cleanups (old_chain);
          continue;
        }
 
       /* Extract this shared object's name.  */
-      target_read_string (new->lm_info->l_name, &buffer,
-                         SO_NAME_MAX_PATH_SIZE - 1, &errcode);
+      target_read_string (li->l_name, &buffer, SO_NAME_MAX_PATH_SIZE - 1,
+                         &errcode);
       if (errcode != 0)
        {
-         warning (_("Can't read pathname for load map: %s."),
-                  safe_strerror (errcode));
+         /* If this entry's l_name address matches that of the
+            inferior executable, then this is not a normal shared
+            object, but (most likely) a vDSO.  In this case, silently
+            skip it; otherwise emit a warning. */
+         if (first_l_name == 0 || li->l_name != first_l_name)
+           warning (_("Can't read pathname for load map: %s."),
+                    safe_strerror (errcode));
          do_cleanups (old_chain);
          continue;
        }
 
-      strncpy (new->so_name, buffer, SO_NAME_MAX_PATH_SIZE - 1);
-      new->so_name[SO_NAME_MAX_PATH_SIZE - 1] = '\0';
-      strcpy (new->so_original_name, new->so_name);
+      strncpy (newobj->so_name, buffer, SO_NAME_MAX_PATH_SIZE - 1);
+      newobj->so_name[SO_NAME_MAX_PATH_SIZE - 1] = '\0';
+      strcpy (newobj->so_original_name, newobj->so_name);
       xfree (buffer);
 
       /* If this entry has no name, or its name matches the name
         for the main executable, don't include it in the list.  */
-      if (! new->so_name[0] || match_main (new->so_name))
+      if (! newobj->so_name[0] || match_main (newobj->so_name))
        {
          do_cleanups (old_chain);
          continue;
        }
 
       discard_cleanups (old_chain);
-      new->next = 0;
-      **link_ptr_ptr = new;
-      *link_ptr_ptr = &new->next;
+      newobj->next = 0;
+      **link_ptr_ptr = newobj;
+      *link_ptr_ptr = &newobj->next;
     }
 
   return 1;
@@ -1460,10 +1503,11 @@ svr4_current_sos_direct (struct svr4_info *info)
   return head;
 }
 
-/* Implement the "current_sos" target_so_ops method.  */
+/* Implement the main part of the "current_sos" target_so_ops
+   method.  */
 
 static struct so_list *
-svr4_current_sos (void)
+svr4_current_sos_1 (void)
 {
   struct svr4_info *info = get_svr4_info ();
 
@@ -1476,6 +1520,85 @@ svr4_current_sos (void)
   return svr4_current_sos_direct (info);
 }
 
+/* Implement the "current_sos" target_so_ops method.  */
+
+static struct so_list *
+svr4_current_sos (void)
+{
+  struct so_list *so_head = svr4_current_sos_1 ();
+  struct mem_range vsyscall_range;
+
+  /* Filter out the vDSO module, if present.  Its symbol file would
+     not be found on disk.  The vDSO/vsyscall's OBJFILE is instead
+     managed by symfile-mem.c:add_vsyscall_page.  */
+  if (gdbarch_vsyscall_range (target_gdbarch (), &vsyscall_range)
+      && vsyscall_range.length != 0)
+    {
+      struct so_list **sop;
+
+      sop = &so_head;
+      while (*sop != NULL)
+       {
+         struct so_list *so = *sop;
+
+         /* We can't simply match the vDSO by starting address alone,
+            because lm_info->l_addr_inferior (and also l_addr) do not
+            necessarily represent the real starting address of the
+            ELF if the vDSO's ELF itself is "prelinked".  The l_ld
+            field (the ".dynamic" section of the shared object)
+            always points at the absolute/resolved address though.
+            So check whether that address is inside the vDSO's
+            mapping instead.
+
+            E.g., on Linux 3.16 (x86_64) the vDSO is a regular
+            0-based ELF, and we see:
+
+             (gdb) info auxv
+             33  AT_SYSINFO_EHDR  System-supplied DSO's ELF header 0x7ffff7ffb000
+             (gdb)  p/x *_r_debug.r_map.l_next
+             $1 = {l_addr = 0x7ffff7ffb000, ..., l_ld = 0x7ffff7ffb318, ...}
+
+            And on Linux 2.6.32 (x86_64) we see:
+
+             (gdb) info auxv
+             33  AT_SYSINFO_EHDR  System-supplied DSO's ELF header 0x7ffff7ffe000
+             (gdb) p/x *_r_debug.r_map.l_next
+             $5 = {l_addr = 0x7ffff88fe000, ..., l_ld = 0x7ffff7ffe580, ... }
+
+            Dumping that vDSO shows:
+
+             (gdb) info proc mappings
+             0x7ffff7ffe000  0x7ffff7fff000  0x1000  0  [vdso]
+             (gdb) dump memory vdso.bin 0x7ffff7ffe000 0x7ffff7fff000
+             # readelf -Wa vdso.bin
+             [...]
+               Entry point address: 0xffffffffff700700
+             [...]
+             Section Headers:
+               [Nr] Name     Type    Address          Off    Size
+               [ 0]          NULL    0000000000000000 000000 000000
+               [ 1] .hash    HASH    ffffffffff700120 000120 000038
+               [ 2] .dynsym  DYNSYM  ffffffffff700158 000158 0000d8
+             [...]
+               [ 9] .dynamic DYNAMIC ffffffffff700580 000580 0000f0
+         */
+
+         lm_info_svr4 *li = (lm_info_svr4 *) so->lm_info;
+
+         if (address_in_mem_range (li->l_ld, &vsyscall_range))
+           {
+             *sop = so->next;
+             free_so (so);
+             break;
+           }
+
+         sop = &so->next;
+       }
+    }
+
+  return so_head;
+}
+
 /* Get the address of the link_map for a given OBJFILE.  */
 
 CORE_ADDR
@@ -1486,7 +1609,7 @@ svr4_fetch_objfile_link_map (struct objfile *objfile)
 
   /* Cause svr4_current_sos() to be run if it hasn't been already.  */
   if (info->main_lm_addr == 0)
-    solib_add (NULL, 0, &current_target, auto_solib_add);
+    solib_add (NULL, 0, auto_solib_add);
 
   /* svr4_current_sos() will set main_lm_addr for the main executable.  */
   if (objfile == symfile_objfile)
@@ -1496,7 +1619,11 @@ svr4_fetch_objfile_link_map (struct objfile *objfile)
      of shared libraries.  */
   for (so = master_so_list (); so; so = so->next)
     if (so->objfile == objfile)
-      return so->lm_info->lm_addr;
+      {
+       lm_info_svr4 *li = (lm_info_svr4 *) so->lm_info;
+
+       return li->lm_addr;
+      }
 
   /* Not found!  */
   return 0;
@@ -1532,7 +1659,7 @@ svr4_in_dynsym_resolve_code (CORE_ADDR pc)
           && pc < info->interp_text_sect_high)
          || (pc >= info->interp_plt_sect_low
              && pc < info->interp_plt_sect_high)
-         || in_plt_section (pc, NULL)
+         || in_plt_section (pc)
          || in_gnu_ifunc_stub (pc));
 }
 
@@ -1565,6 +1692,9 @@ struct probe_and_action
   /* The probe.  */
   struct probe *probe;
 
+  /* The relocated address of the probe.  */
+  CORE_ADDR address;
+
   /* The action.  */
   enum probe_action action;
 };
@@ -1574,9 +1704,9 @@ struct probe_and_action
 static hashval_t
 hash_probe_and_action (const void *p)
 {
-  const struct probe_and_action *pa = p;
+  const struct probe_and_action *pa = (const struct probe_and_action *) p;
 
-  return (hashval_t) pa->probe->address;
+  return (hashval_t) pa->address;
 }
 
 /* Returns non-zero if the probe_and_actions referenced by p1 and p2
@@ -1585,17 +1715,18 @@ hash_probe_and_action (const void *p)
 static int
 equal_probe_and_action (const void *p1, const void *p2)
 {
-  const struct probe_and_action *pa1 = p1;
-  const struct probe_and_action *pa2 = p2;
+  const struct probe_and_action *pa1 = (const struct probe_and_action *) p1;
+  const struct probe_and_action *pa2 = (const struct probe_and_action *) p2;
 
-  return pa1->probe->address == pa2->probe->address;
+  return pa1->address == pa2->address;
 }
 
 /* Register a solib event probe and its associated action in the
    probes table.  */
 
 static void
-register_solib_event_probe (struct probe *probe, enum probe_action action)
+register_solib_event_probe (struct probe *probe, CORE_ADDR address,
+                           enum probe_action action)
 {
   struct svr4_info *info = get_svr4_info ();
   struct probe_and_action lookup, *pa;
@@ -1608,11 +1739,13 @@ register_solib_event_probe (struct probe *probe, enum probe_action action)
                                            xfree, xcalloc, xfree);
 
   lookup.probe = probe;
+  lookup.address = address;
   slot = htab_find_slot (info->probes_table, &lookup, INSERT);
   gdb_assert (*slot == HTAB_EMPTY_ENTRY);
 
   pa = XCNEW (struct probe_and_action);
   pa->probe = probe;
+  pa->address = address;
   pa->action = action;
 
   *slot = pa;
@@ -1625,12 +1758,10 @@ register_solib_event_probe (struct probe *probe, enum probe_action action)
 static struct probe_and_action *
 solib_event_probe_at (struct svr4_info *info, CORE_ADDR address)
 {
-  struct probe lookup_probe;
   struct probe_and_action lookup;
   void **slot;
 
-  lookup_probe.address = address;
-  lookup.probe = &lookup_probe;
+  lookup.address = address;
   slot = htab_find_slot (info->probes_table, &lookup, NO_INSERT);
 
   if (slot == NULL)
@@ -1646,7 +1777,8 @@ static enum probe_action
 solib_event_probe_action (struct probe_and_action *pa)
 {
   enum probe_action action;
-  unsigned probe_argc;
+  unsigned probe_argc = 0;
+  struct frame_info *frame = get_current_frame ();
 
   action = pa->action;
   if (action == DO_NOTHING || action == PROBES_INTERFACE_FAILED)
@@ -1659,7 +1791,23 @@ solib_event_probe_action (struct probe_and_action *pa)
        arg0: Lmid_t lmid (mandatory)
        arg1: struct r_debug *debug_base (mandatory)
        arg2: struct link_map *new (optional, for incremental updates)  */
-  probe_argc = get_probe_argument_count (pa->probe);
+  TRY
+    {
+      probe_argc = get_probe_argument_count (pa->probe, frame);
+    }
+  CATCH (ex, RETURN_MASK_ERROR)
+    {
+      exception_print (gdb_stderr, ex);
+      probe_argc = 0;
+    }
+  END_CATCH
+
+  /* If get_probe_argument_count throws an exception, probe_argc will
+     be set to zero.  However, if pa->probe does not have arguments,
+     then get_probe_argument_count will succeed but probe_argc will
+     also be zero.  Both cases happen because of different things, but
+     they are treated equally here: action will be set to
+     PROBES_INTERFACE_FAILED.  */
   if (probe_argc == 2)
     action = FULL_RELOAD;
   else if (probe_argc < 2)
@@ -1707,7 +1855,9 @@ solist_update_incremental (struct svr4_info *info, CORE_ADDR lm)
   /* Walk to the end of the list.  */
   for (tail = info->solib_list; tail->next != NULL; tail = tail->next)
     /* Nothing.  */;
-  prev_lm = tail->lm_info->lm_addr;
+
+  lm_info_svr4 *li = (lm_info_svr4 *) tail->lm_info;
+  prev_lm = li->lm_addr;
 
   /* Read the new objects.  */
   if (info->using_xfer)
@@ -1765,9 +1915,9 @@ svr4_handle_solib_event (void)
   struct probe_and_action *pa;
   enum probe_action action;
   struct cleanup *old_chain, *usm_chain;
-  struct value *val;
+  struct value *val = NULL;
   CORE_ADDR pc, debug_base, lm = 0;
-  int is_initial_ns;
+  struct frame_info *frame = get_current_frame ();
 
   /* Do nothing if not using the probes interface.  */
   if (info->probes_table == NULL)
@@ -1812,7 +1962,17 @@ svr4_handle_solib_event (void)
   usm_chain = make_cleanup (resume_section_map_updates_cleanup,
                            current_program_space);
 
-  val = evaluate_probe_argument (pa->probe, 1);
+  TRY
+    {
+      val = evaluate_probe_argument (pa->probe, 1, frame);
+    }
+  CATCH (ex, RETURN_MASK_ERROR)
+    {
+      exception_print (gdb_stderr, ex);
+      val = NULL;
+    }
+  END_CATCH
+
   if (val == NULL)
     {
       do_cleanups (old_chain);
@@ -1843,7 +2003,18 @@ svr4_handle_solib_event (void)
 
   if (action == UPDATE_OR_RELOAD)
     {
-      val = evaluate_probe_argument (pa->probe, 2);
+      TRY
+       {
+         val = evaluate_probe_argument (pa->probe, 2, frame);
+       }
+      CATCH (ex, RETURN_MASK_ERROR)
+       {
+         exception_print (gdb_stderr, ex);
+         do_cleanups (old_chain);
+         return;
+       }
+      END_CATCH
+
       if (val != NULL)
        lm = value_as_address (val);
 
@@ -1890,7 +2061,8 @@ svr4_update_solib_event_breakpoint (struct breakpoint *b, void *arg)
       struct svr4_info *info;
       struct probe_and_action *pa;
 
-      info = program_space_data (loc->pspace, solib_svr4_pspace_data);
+      info = ((struct svr4_info *)
+             program_space_data (loc->pspace, solib_svr4_pspace_data));
       if (info == NULL || info->probes_table == NULL)
        continue;
 
@@ -1929,7 +2101,8 @@ svr4_update_solib_event_breakpoints (void)
 
 static void
 svr4_create_probe_breakpoints (struct gdbarch *gdbarch,
-                              VEC (probe_p) **probes)
+                              VEC (probe_p) **probes,
+                              struct objfile *objfile)
 {
   int i;
 
@@ -1943,8 +2116,10 @@ svr4_create_probe_breakpoints (struct gdbarch *gdbarch,
           VEC_iterate (probe_p, probes[i], ix, probe);
           ++ix)
        {
-         create_solib_event_breakpoint (gdbarch, probe->address);
-         register_solib_event_probe (probe, action);
+         CORE_ADDR address = get_probe_address (probe, objfile);
+
+         create_solib_event_breakpoint (gdbarch, address);
+         register_solib_event_probe (probe, address, action);
        }
     }
 
@@ -1978,12 +2153,14 @@ svr4_create_solib_event_breakpoints (struct gdbarch *gdbarch,
        {
          VEC (probe_p) *probes[NUM_PROBES];
          int all_probes_found = 1;
+         int checked_can_use_probe_arguments = 0;
          int i;
 
          memset (probes, 0, sizeof (probes));
          for (i = 0; i < NUM_PROBES; i++)
            {
              const char *name = probe_info[i].name;
+             struct probe *p;
              char buf[32];
 
              /* Fedora 17 and Red Hat Enterprise Linux 6.2-6.4
@@ -2012,10 +2189,22 @@ svr4_create_solib_event_breakpoints (struct gdbarch *gdbarch,
                  all_probes_found = 0;
                  break;
                }
+
+             /* Ensure probe arguments can be evaluated.  */
+             if (!checked_can_use_probe_arguments)
+               {
+                 p = VEC_index (probe_p, probes[i], 0);
+                 if (!can_evaluate_probe_arguments (p))
+                   {
+                     all_probes_found = 0;
+                     break;
+                   }
+                 checked_can_use_probe_arguments = 1;
+               }
            }
 
          if (all_probes_found)
-           svr4_create_probe_breakpoints (gdbarch, probes);
+           svr4_create_probe_breakpoints (gdbarch, probes, os->objfile);
 
          for (i = 0; i < NUM_PROBES; i++)
            VEC_free (probe_p, probes[i]);
@@ -2031,7 +2220,7 @@ svr4_create_solib_event_breakpoints (struct gdbarch *gdbarch,
 /* Helper function for gdb_bfd_lookup_symbol.  */
 
 static int
-cmp_name_and_sec_flags (asymbol *sym, void *data)
+cmp_name_and_sec_flags (const asymbol *sym, const void *data)
 {
   return (strcmp (sym->name, (const char *) data) == 0
          && (sym->section->flags & (SEC_CODE | SEC_DATA)) != 0);
@@ -2071,7 +2260,7 @@ cmp_name_and_sec_flags (asymbol *sym, void *data)
 static int
 enable_break (struct svr4_info *info, int from_tty)
 {
-  struct minimal_symbol *msymbol;
+  struct bound_minimal_symbol msymbol;
   const char * const *bkpt_namep;
   asection *interp_sect;
   char *interp_name;
@@ -2085,7 +2274,7 @@ enable_break (struct svr4_info *info, int from_tty)
      mean r_brk has already been relocated.  Assume the dynamic linker
      is the object containing r_brk.  */
 
-  solib_add (NULL, from_tty, &current_target, auto_solib_add);
+  solib_add (NULL, from_tty, auto_solib_add);
   sym_addr = 0;
   if (info->debug_base && solib_svr4_r_map (info) != 0)
     sym_addr = solib_svr4_r_brk (info);
@@ -2163,9 +2352,7 @@ enable_break (struct svr4_info *info, int from_tty)
       int load_addr_found = 0;
       int loader_found_in_list = 0;
       struct so_list *so;
-      bfd *tmp_bfd = NULL;
       struct target_ops *tmp_bfd_target;
-      volatile struct gdb_exception ex;
 
       sym_addr = 0;
 
@@ -2178,19 +2365,23 @@ enable_break (struct svr4_info *info, int from_tty)
          be trivial on GNU/Linux).  Therefore, we have to try an alternate
          mechanism to find the dynamic linker's base address.  */
 
-      TRY_CATCH (ex, RETURN_MASK_ALL)
+      gdb_bfd_ref_ptr tmp_bfd;
+      TRY
         {
          tmp_bfd = solib_bfd_open (interp_name);
        }
+      CATCH (ex, RETURN_MASK_ALL)
+       {
+       }
+      END_CATCH
+
       if (tmp_bfd == NULL)
        goto bkpt_at_symbol;
 
       /* Now convert the TMP_BFD into a target.  That way target, as
-         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);
+         well as BFD operations can be used.  target_bfd_reopen
+         acquires its own reference.  */
+      tmp_bfd_target = target_bfd_reopen (tmp_bfd.get ());
 
       /* On a running target, we can get the dynamic linker's base
          address from the shared library table.  */
@@ -2201,7 +2392,7 @@ enable_break (struct svr4_info *info, int from_tty)
            {
              load_addr_found = 1;
              loader_found_in_list = 1;
-             load_addr = lm_addr_check (so, tmp_bfd);
+             load_addr = lm_addr_check (so, tmp_bfd.get ());
              break;
            }
          so = so->next;
@@ -2222,7 +2413,7 @@ enable_break (struct svr4_info *info, int from_tty)
            if (addr_bit < (sizeof (CORE_ADDR) * HOST_CHAR_BIT))
              {
                CORE_ADDR space_size = (CORE_ADDR) 1 << addr_bit;
-               CORE_ADDR tmp_entry_point = exec_entry_point (tmp_bfd,
+               CORE_ADDR tmp_entry_point = exec_entry_point (tmp_bfd.get (),
                                                              tmp_bfd_target);
 
                gdb_assert (load_addr < space_size);
@@ -2251,7 +2442,7 @@ enable_break (struct svr4_info *info, int from_tty)
            = get_thread_arch_regcache (inferior_ptid, target_gdbarch ());
 
          load_addr = (regcache_read_pc (regcache)
-                      - exec_entry_point (tmp_bfd, tmp_bfd_target));
+                      - exec_entry_point (tmp_bfd.get (), tmp_bfd_target));
        }
 
       if (!loader_found_in_list)
@@ -2259,35 +2450,36 @@ enable_break (struct svr4_info *info, int from_tty)
          info->debug_loader_name = xstrdup (interp_name);
          info->debug_loader_offset_p = 1;
          info->debug_loader_offset = load_addr;
-         solib_add (NULL, from_tty, &current_target, auto_solib_add);
+         solib_add (NULL, from_tty, auto_solib_add);
        }
 
       /* Record the relocated start and end address of the dynamic linker
          text and plt section for svr4_in_dynsym_resolve_code.  */
-      interp_sect = bfd_get_section_by_name (tmp_bfd, ".text");
+      interp_sect = bfd_get_section_by_name (tmp_bfd.get (), ".text");
       if (interp_sect)
        {
          info->interp_text_sect_low =
-           bfd_section_vma (tmp_bfd, interp_sect) + load_addr;
+           bfd_section_vma (tmp_bfd.get (), interp_sect) + load_addr;
          info->interp_text_sect_high =
            info->interp_text_sect_low
-           + bfd_section_size (tmp_bfd, interp_sect);
+           + bfd_section_size (tmp_bfd.get (), interp_sect);
        }
-      interp_sect = bfd_get_section_by_name (tmp_bfd, ".plt");
+      interp_sect = bfd_get_section_by_name (tmp_bfd.get (), ".plt");
       if (interp_sect)
        {
          info->interp_plt_sect_low =
-           bfd_section_vma (tmp_bfd, interp_sect) + load_addr;
+           bfd_section_vma (tmp_bfd.get (), interp_sect) + load_addr;
          info->interp_plt_sect_high =
            info->interp_plt_sect_low
-           + bfd_section_size (tmp_bfd, interp_sect);
+           + bfd_section_size (tmp_bfd.get (), interp_sect);
        }
 
       /* Now try to set a breakpoint in the dynamic linker.  */
       for (bkpt_namep = solib_break_names; *bkpt_namep != NULL; bkpt_namep++)
        {
-         sym_addr = gdb_bfd_lookup_symbol (tmp_bfd, cmp_name_and_sec_flags,
-                                           (void *) *bkpt_namep);
+         sym_addr = gdb_bfd_lookup_symbol (tmp_bfd.get (),
+                                           cmp_name_and_sec_flags,
+                                           *bkpt_namep);
          if (sym_addr != 0)
            break;
        }
@@ -2328,9 +2520,10 @@ enable_break (struct svr4_info *info, int from_tty)
   for (bkpt_namep = solib_break_names; *bkpt_namep != NULL; bkpt_namep++)
     {
       msymbol = lookup_minimal_symbol (*bkpt_namep, NULL, symfile_objfile);
-      if ((msymbol != NULL) && (SYMBOL_VALUE_ADDRESS (msymbol) != 0))
+      if ((msymbol.minsym != NULL)
+         && (BMSYMBOL_VALUE_ADDRESS (msymbol) != 0))
        {
-         sym_addr = SYMBOL_VALUE_ADDRESS (msymbol);
+         sym_addr = BMSYMBOL_VALUE_ADDRESS (msymbol);
          sym_addr = gdbarch_convert_from_func_ptr_addr (target_gdbarch (),
                                                         sym_addr,
                                                         &current_target);
@@ -2344,9 +2537,10 @@ enable_break (struct svr4_info *info, int from_tty)
       for (bkpt_namep = bkpt_names; *bkpt_namep != NULL; bkpt_namep++)
        {
          msymbol = lookup_minimal_symbol (*bkpt_namep, NULL, symfile_objfile);
-         if ((msymbol != NULL) && (SYMBOL_VALUE_ADDRESS (msymbol) != 0))
+         if ((msymbol.minsym != NULL)
+             && (BMSYMBOL_VALUE_ADDRESS (msymbol) != 0))
            {
-             sym_addr = SYMBOL_VALUE_ADDRESS (msymbol);
+             sym_addr = BMSYMBOL_VALUE_ADDRESS (msymbol);
              sym_addr = gdbarch_convert_from_func_ptr_addr (target_gdbarch (),
                                                             sym_addr,
                                                             &current_target);
@@ -2358,14 +2552,6 @@ enable_break (struct svr4_info *info, int from_tty)
   return 0;
 }
 
-/* Implement the "special_symbol_handling" target_so_ops method.  */
-
-static void
-svr4_special_symbol_handling (void)
-{
-  /* Nothing to do.  */
-}
-
 /* Read the ELF program headers from ABFD.  Return the contents and
    set *PHDRS_SIZE to the size of the program headers.  */
 
@@ -2381,7 +2567,7 @@ read_program_headers_from_bfd (bfd *abfd, int *phdrs_size)
   if (*phdrs_size == 0)
     return NULL;
 
-  buf = xmalloc (*phdrs_size);
+  buf = (gdb_byte *) xmalloc (*phdrs_size);
   if (bfd_seek (abfd, ehdr->e_phoff, SEEK_SET) != 0
       || bfd_bread (buf, *phdrs_size, abfd) != *phdrs_size)
     {
@@ -2440,7 +2626,7 @@ svr4_exec_displacement (CORE_ADDR *displacementp)
 {
   /* ENTRY_POINT is a possible function descriptor - before
      a call to gdbarch_convert_from_func_ptr_addr.  */
-  CORE_ADDR entry_point, displacement;
+  CORE_ADDR entry_point, exec_displacement;
 
   if (exec_bfd == NULL)
     return 0;
@@ -2455,9 +2641,9 @@ svr4_exec_displacement (CORE_ADDR *displacementp)
   if (target_auxv_search (&current_target, AT_ENTRY, &entry_point) <= 0)
     return 0;
 
-  displacement = entry_point - bfd_get_start_address (exec_bfd);
+  exec_displacement = entry_point - bfd_get_start_address (exec_bfd);
 
-  /* Verify the DISPLACEMENT candidate complies with the required page
+  /* Verify the EXEC_DISPLACEMENT candidate complies with the required page
      alignment.  It is cheaper than the program headers comparison below.  */
 
   if (bfd_get_flavour (exec_bfd) == bfd_target_elf_flavour)
@@ -2469,7 +2655,7 @@ svr4_exec_displacement (CORE_ADDR *displacementp)
           p_offset % p_align == p_vaddr % p_align
         Kernel is free to load the executable with lower alignment.  */
 
-      if ((displacement & (elf->minpagesize - 1)) != 0)
+      if ((exec_displacement & (elf->minpagesize - 1)) != 0)
        return 0;
     }
 
@@ -2487,7 +2673,7 @@ svr4_exec_displacement (CORE_ADDR *displacementp)
       gdb_byte *buf, *buf2;
       int arch_size;
 
-      buf = read_program_header (-1, &phdrs_size, &arch_size);
+      buf = read_program_header (-1, &phdrs_size, &arch_size, NULL);
       buf2 = read_program_headers_from_bfd (exec_bfd, &phdrs2_size);
       if (buf != NULL && buf2 != NULL)
        {
@@ -2586,6 +2772,28 @@ svr4_exec_displacement (CORE_ADDR *displacementp)
                  if (memcmp (phdrp, phdr2p, sizeof (*phdrp)) == 0)
                    continue;
 
+                 /* Strip modifies the flags and alignment of PT_GNU_RELRO.
+                    CentOS-5 has problems with filesz, memsz as well.
+                    See PR 11786.  */
+                 if (phdr2[i].p_type == PT_GNU_RELRO)
+                   {
+                     Elf32_External_Phdr tmp_phdr = *phdrp;
+                     Elf32_External_Phdr tmp_phdr2 = *phdr2p;
+
+                     memset (tmp_phdr.p_filesz, 0, 4);
+                     memset (tmp_phdr.p_memsz, 0, 4);
+                     memset (tmp_phdr.p_flags, 0, 4);
+                     memset (tmp_phdr.p_align, 0, 4);
+                     memset (tmp_phdr2.p_filesz, 0, 4);
+                     memset (tmp_phdr2.p_memsz, 0, 4);
+                     memset (tmp_phdr2.p_flags, 0, 4);
+                     memset (tmp_phdr2.p_align, 0, 4);
+
+                     if (memcmp (&tmp_phdr, &tmp_phdr2, sizeof (tmp_phdr))
+                         == 0)
+                       continue;
+                   }
+
                  /* prelink can convert .plt SHT_NOBITS to SHT_PROGBITS.  */
                  plt2_asect = bfd_get_section_by_name (exec_bfd, ".plt");
                  if (plt2_asect)
@@ -2695,6 +2903,28 @@ svr4_exec_displacement (CORE_ADDR *displacementp)
                  if (memcmp (phdrp, phdr2p, sizeof (*phdrp)) == 0)
                    continue;
 
+                 /* Strip modifies the flags and alignment of PT_GNU_RELRO.
+                    CentOS-5 has problems with filesz, memsz as well.
+                    See PR 11786.  */
+                 if (phdr2[i].p_type == PT_GNU_RELRO)
+                   {
+                     Elf64_External_Phdr tmp_phdr = *phdrp;
+                     Elf64_External_Phdr tmp_phdr2 = *phdr2p;
+
+                     memset (tmp_phdr.p_filesz, 0, 8);
+                     memset (tmp_phdr.p_memsz, 0, 8);
+                     memset (tmp_phdr.p_flags, 0, 4);
+                     memset (tmp_phdr.p_align, 0, 8);
+                     memset (tmp_phdr2.p_filesz, 0, 8);
+                     memset (tmp_phdr2.p_memsz, 0, 8);
+                     memset (tmp_phdr2.p_flags, 0, 4);
+                     memset (tmp_phdr2.p_align, 0, 8);
+
+                     if (memcmp (&tmp_phdr, &tmp_phdr2, sizeof (tmp_phdr))
+                         == 0)
+                       continue;
+                   }
+
                  /* prelink can convert .plt SHT_NOBITS to SHT_PROGBITS.  */
                  plt2_asect = bfd_get_section_by_name (exec_bfd, ".plt");
                  if (plt2_asect)
@@ -2746,11 +2976,11 @@ 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 (), exec_displacement),
                         bfd_get_filename (exec_bfd));
     }
 
-  *displacementp = displacement;
+  *displacementp = exec_displacement;
   return 1;
 }
 
@@ -2801,8 +3031,8 @@ svr4_relocate_main_executable (void)
       struct section_offsets *new_offsets;
       int i;
 
-      new_offsets = alloca (symfile_objfile->num_sections
-                           * sizeof (*new_offsets));
+      new_offsets = XALLOCAVEC (struct section_offsets,
+                               symfile_objfile->num_sections);
 
       for (i = 0; i < symfile_objfile->num_sections; i++)
        new_offsets->offsets[i] = displacement;
@@ -2907,10 +3137,10 @@ static void
 svr4_relocate_section_addresses (struct so_list *so,
                                  struct target_section *sec)
 {
-  sec->addr    = svr4_truncate_ptr (sec->addr    + lm_addr_check (so,
-                                                                 sec->bfd));
-  sec->endaddr = svr4_truncate_ptr (sec->endaddr + lm_addr_check (so,
-                                                                 sec->bfd));
+  bfd *abfd = sec->the_bfd_section->owner;
+
+  sec->addr = svr4_truncate_ptr (sec->addr + lm_addr_check (so, abfd));
+  sec->endaddr = svr4_truncate_ptr (sec->endaddr + lm_addr_check (so, abfd));
 }
 \f
 
@@ -2944,7 +3174,8 @@ void
 set_solib_svr4_fetch_link_map_offsets (struct gdbarch *gdbarch,
                                        struct link_map_offsets *(*flmo) (void))
 {
-  struct solib_svr4_ops *ops = gdbarch_data (gdbarch, solib_svr4_data);
+  struct solib_svr4_ops *ops
+    = (struct solib_svr4_ops *) gdbarch_data (gdbarch, solib_svr4_data);
 
   ops->fetch_link_map_offsets = flmo;
 
@@ -2957,7 +3188,9 @@ 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
+    = (struct solib_svr4_ops *) gdbarch_data (target_gdbarch (),
+                                             solib_svr4_data);
 
   gdb_assert (ops->fetch_link_map_offsets);
   return ops->fetch_link_map_offsets ();
@@ -2968,7 +3201,9 @@ 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
+    = (struct solib_svr4_ops *) gdbarch_data (target_gdbarch (),
+                                             solib_svr4_data);
 
   return (ops->fetch_link_map_offsets != NULL);
 }
@@ -3047,8 +3282,8 @@ struct target_so_ops svr4_so_ops;
    different rule for symbol lookup.  The lookup begins here in the DSO, not in
    the main executable.  */
 
-static struct symbol *
-elf_lookup_lib_symbol (const struct objfile *objfile,
+static struct block_symbol
+elf_lookup_lib_symbol (struct objfile *objfile,
                       const char *name,
                       const domain_enum domain)
 {
@@ -3064,8 +3299,8 @@ elf_lookup_lib_symbol (const struct objfile *objfile,
       abfd = objfile->obfd;
     }
 
-  if (abfd == NULL || scan_dyntag (DT_SYMBOLIC, abfd, NULL) != 1)
-    return NULL;
+  if (abfd == NULL || scan_dyntag (DT_SYMBOLIC, abfd, NULL, NULL) != 1)
+    return (struct block_symbol) {NULL, NULL};
 
   return lookup_global_symbol_from_objfile (objfile, name, domain);
 }
@@ -3084,7 +3319,6 @@ _initialize_svr4_solib (void)
   svr4_so_ops.clear_so = svr4_clear_so;
   svr4_so_ops.clear_solib = svr4_clear_solib;
   svr4_so_ops.solib_create_inferior_hook = svr4_solib_create_inferior_hook;
-  svr4_so_ops.special_symbol_handling = svr4_special_symbol_handling;
   svr4_so_ops.current_sos = svr4_current_sos;
   svr4_so_ops.open_symbol_file_object = open_symbol_file_object;
   svr4_so_ops.in_dynsym_resolve_code = svr4_in_dynsym_resolve_code;
This page took 0.045623 seconds and 4 git commands to generate.