* powerpc.cc (Target_powerpc::iplt_): New output section.
[deliverable/binutils-gdb.git] / gdb / linux-tdep.c
index d94cf6e4c3b2db8427f95e8cc5958900daa1b7e9..65f5f97c3f855a52b56f151896b399588133d399 100644 (file)
@@ -402,7 +402,6 @@ linux_info_proc (struct gdbarch *gdbarch, char *args,
        {
          struct cleanup *cleanup = make_cleanup (xfree, data);
          const char *p = data;
-         ULONGEST val;
 
          printf_filtered (_("Process: %s\n"),
                           pulongest (strtoulst (p, &p, 10)));
@@ -548,19 +547,28 @@ linux_find_memory_regions (struct gdbarch *gdbarch,
     return 1;
 
   xsnprintf (filename, sizeof filename,
-            "/proc/%d/maps", current_inferior ()->pid);
+            "/proc/%d/smaps", current_inferior ()->pid);
   data = target_fileio_read_stralloc (filename);
+  if (data == NULL)
+    {
+      /* Older Linux kernels did not support /proc/PID/smaps.  */
+      xsnprintf (filename, sizeof filename,
+                "/proc/%d/maps", current_inferior ()->pid);
+      data = target_fileio_read_stralloc (filename);
+    }
   if (data)
     {
       struct cleanup *cleanup = make_cleanup (xfree, data);
       char *line;
 
-      for (line = strtok (data, "\n"); line; line = strtok (NULL, "\n"))
+      line = strtok (data, "\n");
+      while (line)
        {
          ULONGEST addr, endaddr, offset, inode;
          const char *permissions, *device, *filename;
          size_t permissions_len, device_len;
          int read, write, exec;
+         int modified = 0, has_anonymous = 0;
 
          read_mapping (line, &addr, &endaddr, &permissions, &permissions_len,
                        &offset, &device, &device_len, &inode, &filename);
@@ -570,8 +578,35 @@ linux_find_memory_regions (struct gdbarch *gdbarch,
          write = (memchr (permissions, 'w', permissions_len) != 0);
          exec = (memchr (permissions, 'x', permissions_len) != 0);
 
+         /* Try to detect if region was modified by parsing smaps counters.  */
+         for (line = strtok (NULL, "\n");
+              line && line[0] >= 'A' && line[0] <= 'Z';
+              line = strtok (NULL, "\n"))
+           {
+             char keyword[64 + 1];
+             unsigned long number;
+
+             if (sscanf (line, "%64s%lu kB\n", keyword, &number) != 2)
+               {
+                 warning (_("Error parsing {s,}maps file '%s'"), filename);
+                 break;
+               }
+             if (strcmp (keyword, "Anonymous:") == 0)
+               has_anonymous = 1;
+             if (number != 0 && (strcmp (keyword, "Shared_Dirty:") == 0
+                                 || strcmp (keyword, "Private_Dirty:") == 0
+                                 || strcmp (keyword, "Swap:") == 0
+                                 || strcmp (keyword, "Anonymous:") == 0))
+               modified = 1;
+           }
+
+         /* Older Linux kernels did not support the "Anonymous:" counter.
+            If it is missing, we can't be sure - dump all the pages.  */
+         if (!has_anonymous)
+           modified = 1;
+
          /* Invoke the callback function to create the corefile segment.  */
-         func (addr, endaddr - addr, read, write, exec, obfd);
+         func (addr, endaddr - addr, read, write, exec, modified, obfd);
        }
 
       do_cleanups (cleanup);
@@ -586,14 +621,14 @@ linux_find_memory_regions (struct gdbarch *gdbarch,
 static int
 find_signalled_thread (struct thread_info *info, void *data)
 {
-  if (info->suspend.stop_signal != TARGET_SIGNAL_0
+  if (info->suspend.stop_signal != GDB_SIGNAL_0
       && ptid_get_pid (info->ptid) == ptid_get_pid (inferior_ptid))
     return 1;
 
   return 0;
 }
 
-static enum target_signal
+static enum gdb_signal
 find_stop_signal (void)
 {
   struct thread_info *info =
@@ -602,7 +637,7 @@ find_stop_signal (void)
   if (info)
     return info->suspend.stop_signal;
   else
-    return TARGET_SIGNAL_0;
+    return GDB_SIGNAL_0;
 }
 
 /* Generate corefile notes for SPU contexts.  */
@@ -684,7 +719,7 @@ static char *
 linux_collect_thread_registers (const struct regcache *regcache,
                                ptid_t ptid, bfd *obfd,
                                char *note_data, int *note_size,
-                               enum target_signal stop_signal)
+                               enum gdb_signal stop_signal)
 {
   struct gdbarch *gdbarch = get_regcache_arch (regcache);
   struct core_regset_section *sect_list;
@@ -715,7 +750,7 @@ linux_collect_thread_registers (const struct regcache *regcache,
       if (strcmp (sect_list->sect_name, ".reg") == 0)
        note_data = (char *) elfcore_write_prstatus
                               (obfd, note_data, note_size, lwp,
-                               target_signal_to_host (stop_signal), buf);
+                               gdb_signal_to_host (stop_signal), buf);
       else
        note_data = (char *) elfcore_write_register_note
                               (obfd, note_data, note_size,
@@ -738,7 +773,7 @@ struct linux_corefile_thread_data
   char *note_data;
   int *note_size;
   int num_notes;
-  enum target_signal stop_signal;
+  enum gdb_signal stop_signal;
   linux_collect_thread_registers_ftype collect;
 };
 
This page took 0.025881 seconds and 4 git commands to generate.