arc: Fix ARI warning for printf(%p)
[deliverable/binutils-gdb.git] / gdb / linux-tdep.c
index 555c302bc889d41e153150c88c80fcfd92ade242..718dc1ab6620f5ae5099c12f13de654f10c0d87b 100644 (file)
@@ -1757,7 +1757,6 @@ linux_fill_prpsinfo (struct elf_internal_linux_prpsinfo *p)
   int n_fields = 0;
   /* Cleanups.  */
   struct cleanup *c;
-  int i;
 
   gdb_assert (p != NULL);
 
@@ -1789,7 +1788,7 @@ linux_fill_prpsinfo (struct elf_internal_linux_prpsinfo *p)
 
   psargs = xstrdup (fname);
   if (infargs != NULL)
-    psargs = reconcat (psargs, psargs, " ", infargs, NULL);
+    psargs = reconcat (psargs, psargs, " ", infargs, (char *) NULL);
 
   make_cleanup (xfree, psargs);
 
@@ -2278,39 +2277,95 @@ linux_gdb_signal_to_target (struct gdbarch *gdbarch,
   return -1;
 }
 
-/* Rummage through mappings to find a mapping's size.  */
-
-static int
-find_mapping_size (CORE_ADDR vaddr, unsigned long size,
-                  int read, int write, int exec, int modified,
-                  void *data)
-{
-  struct mem_range *range = (struct mem_range *) data;
-
-  if (vaddr == range->start)
-    {
-      range->length = size;
-      return 1;
-    }
-  return 0;
-}
-
 /* Helper for linux_vsyscall_range that does the real work of finding
    the vsyscall's address range.  */
 
 static int
 linux_vsyscall_range_raw (struct gdbarch *gdbarch, struct mem_range *range)
 {
+  char filename[100];
+  long pid;
+  char *data;
+
   if (target_auxv_search (&current_target, AT_SYSINFO_EHDR, &range->start) <= 0)
     return 0;
 
-  /* This is installed by linux_init_abi below, so should always be
-     available.  */
-  gdb_assert (gdbarch_find_memory_regions_p (target_gdbarch ()));
+  /* It doesn't make sense to access the host's /proc when debugging a
+     core file.  Instead, look for the PT_LOAD segment that matches
+     the vDSO.  */
+  if (!target_has_execution)
+    {
+      Elf_Internal_Phdr *phdrs;
+      long phdrs_size;
+      int num_phdrs, i;
+
+      phdrs_size = bfd_get_elf_phdr_upper_bound (core_bfd);
+      if (phdrs_size == -1)
+       return 0;
 
-  range->length = 0;
-  gdbarch_find_memory_regions (gdbarch, find_mapping_size, range);
-  return 1;
+      phdrs = (Elf_Internal_Phdr *) alloca (phdrs_size);
+      num_phdrs = bfd_get_elf_phdrs (core_bfd, phdrs);
+      if (num_phdrs == -1)
+       return 0;
+
+      for (i = 0; i < num_phdrs; i++)
+       if (phdrs[i].p_type == PT_LOAD
+           && phdrs[i].p_vaddr == range->start)
+         {
+           range->length = phdrs[i].p_memsz;
+           return 1;
+         }
+
+      return 0;
+    }
+
+  /* We need to know the real target PID to access /proc.  */
+  if (current_inferior ()->fake_pid_p)
+    return 0;
+
+  pid = current_inferior ()->pid;
+
+  /* Note that reading /proc/PID/task/PID/maps (1) is much faster than
+     reading /proc/PID/maps (2).  The later identifies thread stacks
+     in the output, which requires scanning every thread in the thread
+     group to check whether a VMA is actually a thread's stack.  With
+     Linux 4.4 on an Intel i7-4810MQ @ 2.80GHz, with an inferior with
+     a few thousand threads, (1) takes a few miliseconds, while (2)
+     takes several seconds.  Also note that "smaps", what we read for
+     determining core dump mappings, is even slower than "maps".  */
+  xsnprintf (filename, sizeof filename, "/proc/%ld/task/%ld/maps", pid, pid);
+  data = target_fileio_read_stralloc (NULL, filename);
+  if (data != NULL)
+    {
+      struct cleanup *cleanup = make_cleanup (xfree, data);
+      char *line;
+      char *saveptr = NULL;
+
+      for (line = strtok_r (data, "\n", &saveptr);
+          line != NULL;
+          line = strtok_r (NULL, "\n", &saveptr))
+       {
+         ULONGEST addr, endaddr;
+         const char *p = line;
+
+         addr = strtoulst (p, &p, 16);
+         if (addr == range->start)
+           {
+             if (*p == '-')
+               p++;
+             endaddr = strtoulst (p, &p, 16);
+             range->length = endaddr - addr;
+             do_cleanups (cleanup);
+             return 1;
+           }
+       }
+
+      do_cleanups (cleanup);
+    }
+  else
+    warning (_("unable to open /proc file '%s'"), filename);
+
+  return 0;
 }
 
 /* Implementation of the "vsyscall_range" gdbarch hook.  Handles
@@ -2426,7 +2481,8 @@ linux_displaced_step_location (struct gdbarch *gdbarch)
      location.  The auxiliary vector gets us the PowerPC-side entry
      point address instead.  */
   if (target_auxv_search (&current_target, AT_ENTRY, &addr) <= 0)
-    error (_("Cannot find AT_ENTRY auxiliary vector entry."));
+    throw_error (NOT_SUPPORTED_ERROR,
+                _("Cannot find AT_ENTRY auxiliary vector entry."));
 
   /* Make certain that the address points at real code, and not a
      function descriptor.  */
This page took 0.026836 seconds and 4 git commands to generate.