crash printing non-local variable from nested subprogram
[deliverable/binutils-gdb.git] / gdb / solib-svr4.c
index 71522c6122d4f0962a2d0094ef61ece162f3da39..5d3d41e006b80a8808909ce30561d9569319ddb6 100644 (file)
@@ -45,9 +45,6 @@
 #include "auxv.h"
 #include "gdb_bfd.h"
 #include "probe.h"
-#include "rsp-low.h"
-
-#define NOTE_GNU_BUILD_ID_NAME  ".note.gnu.build-id"
 
 static struct link_map_offsets *svr4_fetch_link_map_offsets (void);
 static int svr4_have_link_map_offsets (void);
@@ -213,7 +210,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 = XCNEW (struct lm_info);
       lm_info->lm_addr = lm_addr;
 
       lm_info->l_addr_inferior = extract_typed_address (&lm[lmo->l_addr_offset],
@@ -446,10 +443,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;
@@ -579,6 +578,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;
 }
@@ -608,7 +609,7 @@ find_program_interpreter (void)
 
   /* 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;
 }
@@ -618,7 +619,8 @@ find_program_interpreter (void)
    found, 1 is returned and the corresponding PTR is set.  */
 
 static int
-scan_dyntag (const int desired_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 current_dyntag;
@@ -698,13 +700,15 @@ scan_dyntag (const int desired_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;
        }
@@ -718,16 +722,19 @@ scan_dyntag (const int desired_dyntag, bfd *abfd, CORE_ADDR *ptr)
    is returned and the corresponding PTR is set.  */
 
 static int
-scan_dyntag_auxv (const int desired_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 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;
 
@@ -764,6 +771,9 @@ scan_dyntag_auxv (const int desired_dyntag, CORE_ADDR *ptr)
        if (ptr)
          *ptr = dyn_ptr;
 
+       if (ptr_addr)
+         *ptr_addr = base_addr + buf - bufstart;
+
        xfree (bufstart);
        return 1;
       }
@@ -789,13 +799,13 @@ static CORE_ADDR
 elf_locate_base (void)
 {
   struct bound_minimal_symbol msymbol;
-  CORE_ADDR dyn_ptr;
+  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;
@@ -809,9 +819,27 @@ 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 = 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
@@ -973,64 +1001,6 @@ svr4_keep_data_in_core (CORE_ADDR vaddr, unsigned long size)
   return (name_lm >= vaddr && name_lm < vaddr + size);
 }
 
-/* Validate SO by comparing build-id from the associated bfd and
-   corresponding build-id from target memory.  Return NULL for success
-   or a string for error.  Caller must call xfree for the error string.  */
-
-static char *
-svr4_validate (const struct so_list *const so)
-{
-  const bfd_byte *local_id;
-  size_t local_idsz;
-
-  gdb_assert (so != NULL);
-
-  /* Target doesn't support reporting the build ID or the remote shared library
-     does not have build ID.  */
-  if (so->build_id == NULL)
-    return NULL;
-
-  /* Build ID may be present in the local file, just GDB is unable to retrieve
-     it.  As it has been reported by gdbserver it is not FSF gdbserver.  */
-  if (so->abfd == NULL
-      || !bfd_check_format (so->abfd, bfd_object))
-    return NULL;
-
-  /* GDB has verified the local file really does not contain the build ID.  */
-  if (so->abfd->build_id == NULL)
-    {
-      char *remote_hex;
-
-      remote_hex = alloca (so->build_idsz * 2 + 1);
-      bin2hex (so->build_id, remote_hex, so->build_idsz);
-
-      return xstrprintf (_("remote build ID is %s "
-                          "but local file does not have build ID"),
-                        remote_hex);
-    }
-
-  local_id = so->abfd->build_id->data;
-  local_idsz = so->abfd->build_id->size;
-
-  if (so->build_idsz != local_idsz
-      || memcmp (so->build_id, local_id, so->build_idsz) != 0)
-    {
-      char *remote_hex, *local_hex;
-
-      remote_hex = alloca (so->build_idsz * 2 + 1);
-      bin2hex (so->build_id, remote_hex, so->build_idsz);
-      local_hex = alloca (local_idsz * 2 + 1);
-      bin2hex (local_id, local_hex, local_idsz);
-
-      return xstrprintf (_("remote build ID %s "
-                          "does not match local build ID %s"),
-                        remote_hex, local_hex);
-    }
-
-  /* Both build IDs are present and they match.  */
-  return NULL;
-}
-
 /* Implement the "open_symbol_file_object" target_so_ops method.
 
    If no open symbol file, attempt to locate and open the main symbol
@@ -1163,18 +1133,12 @@ svr4_copy_library_list (struct so_list *src)
     {
       struct so_list *newobj;
 
-      newobj = xmalloc (sizeof (struct so_list));
+      newobj = XNEW (struct so_list);
       memcpy (newobj, src, sizeof (struct so_list));
 
-      newobj->lm_info = xmalloc (sizeof (struct lm_info));
+      newobj->lm_info = XNEW (struct lm_info);
       memcpy (newobj->lm_info, src->lm_info, sizeof (struct lm_info));
 
-      if (newobj->build_id != NULL)
-       {
-         newobj->build_id = xmalloc (src->build_idsz);
-         memcpy (newobj->build_id, src->build_id, src->build_idsz);
-       }
-
       newobj->next = NULL;
       *link = newobj;
       link = &newobj->next;
@@ -1202,9 +1166,6 @@ library_list_start_library (struct gdb_xml_parser *parser,
   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;
-  const struct gdb_xml_value *const att_build_id
-    = xml_find_attribute (attributes, "build-id");
-  const char *const hex_build_id = att_build_id ? att_build_id->value : NULL;
   struct so_list *new_elem;
 
   new_elem = XCNEW (struct so_list);
@@ -1216,37 +1177,6 @@ library_list_start_library (struct gdb_xml_parser *parser,
   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);
-  if (hex_build_id != NULL)
-    {
-      const size_t hex_build_id_len = strlen (hex_build_id);
-
-      if (hex_build_id_len == 0)
-       warning (_("Shared library \"%s\" received empty build-id "
-                  "from gdbserver"), new_elem->so_original_name);
-      else if ((hex_build_id_len & 1U) != 0)
-       warning (_("Shared library \"%s\" received odd number "
-                  "of build-id \"%s\" hex characters from gdbserver"),
-                new_elem->so_original_name, hex_build_id);
-      else
-       {
-         const size_t build_idsz = hex_build_id_len / 2;
-
-         new_elem->build_id = xmalloc (build_idsz);
-         new_elem->build_idsz = hex2bin (hex_build_id, new_elem->build_id,
-                                         build_idsz);
-         if (new_elem->build_idsz != build_idsz)
-           {
-             warning (_("Shared library \"%s\" received invalid "
-                        "build-id \"%s\" hex character at encoded byte "
-                        "position %s (first as 0) from gdbserver"),
-                      new_elem->so_original_name, hex_build_id,
-                      pulongest (new_elem->build_idsz));
-             xfree (new_elem->build_id);
-             new_elem->build_id = NULL;
-             new_elem->build_idsz = 0;
-           }
-       }
-    }
 
   *list->tailp = new_elem;
   list->tailp = &new_elem->next;
@@ -1281,7 +1211,6 @@ static const struct gdb_xml_attribute svr4_library_attributes[] =
   { "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 },
-  { "build-id", GDB_XML_AF_OPTIONAL, NULL, NULL },
   { NULL, GDB_XML_AF_NONE, NULL, NULL }
 };
 
@@ -1394,7 +1323,7 @@ svr4_default_sos (void)
 
   newobj = XCNEW (struct so_list);
 
-  newobj->lm_info = xzalloc (sizeof (struct lm_info));
+  newobj->lm_info = XCNEW (struct lm_info);
 
   /* Nothing will ever check the other fields if we set l_addr_p.  */
   newobj->lm_info->l_addr = info->debug_loader_offset;
@@ -1843,7 +1772,7 @@ 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;
@@ -1857,7 +1786,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, frame);
+  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)
@@ -1963,7 +1908,7 @@ 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 ();
@@ -2011,7 +1956,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, frame);
+  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);
@@ -2042,7 +1997,18 @@ svr4_handle_solib_event (void)
 
   if (action == UPDATE_OR_RELOAD)
     {
-      val = evaluate_probe_argument (pa->probe, 2, frame);
+      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);
 
@@ -2709,7 +2675,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)
        {
@@ -3313,7 +3279,7 @@ 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 *
+static struct block_symbol
 elf_lookup_lib_symbol (struct objfile *objfile,
                       const char *name,
                       const domain_enum domain)
@@ -3330,8 +3296,8 @@ elf_lookup_lib_symbol (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);
 }
@@ -3360,5 +3326,4 @@ _initialize_svr4_solib (void)
   svr4_so_ops.keep_data_in_core = svr4_keep_data_in_core;
   svr4_so_ops.update_breakpoints = svr4_update_solib_event_breakpoints;
   svr4_so_ops.handle_event = svr4_handle_solib_event;
-  svr4_so_ops.validate = svr4_validate;
 }
This page took 0.028351 seconds and 4 git commands to generate.