aboutsummaryrefslogtreecommitdiff
path: root/gdb/linux-tdep.c
diff options
context:
space:
mode:
authorJan Kratochvil <jan.kratochvil@redhat.com>2012-08-07 13:26:33 +0000
committerJan Kratochvil <jan.kratochvil@redhat.com>2012-08-07 13:26:33 +0000
commit4f69f4c267a21e787685116945fb40729a7297a5 (patch)
treeccffd19fbc910eedac303b46c8c4bad9db964b76 /gdb/linux-tdep.c
parent82435b3b3da1b288ca2d2596a9de40e6bc734773 (diff)
downloadgdb-4f69f4c267a21e787685116945fb40729a7297a5.zip
gdb-4f69f4c267a21e787685116945fb40729a7297a5.tar.gz
gdb-4f69f4c267a21e787685116945fb40729a7297a5.tar.bz2
gdb/
PR 11804 * defs.h (find_memory_region_ftype): New comment. New arg modified. * fbsd-nat.c (fbsd_find_memory_regions): Add the passed modified value. * gcore.c (gcore_create_callback): New function comment. Add modified parameter. Only write modified regions. Set SEC_READONLY exactly according to MODIFIED. (objfile_find_memory_regions): Ignore separate debug info files. Ass the passed modified value to FUNC. * gnu-nat.c (gnu_find_memory_regions): Add the passed modified value. * linux-tdep.c (linux_find_memory_regions): Try to reads smaps file first. New variables modified and has_anonymous. Parse the lines of smaps file. Add the passed MODIFIED value to FUNC. * procfs.c (find_memory_regions_callback): Add the passed modified value. gdb/testsuite/ PR 11804 * gdb.base/gcore-relro.exp: New file. * gdb.base/gcore-relro-main.c: New file. * gdb.base/gcore-relro-lib.c: New file.
Diffstat (limited to 'gdb/linux-tdep.c')
-rw-r--r--gdb/linux-tdep.c42
1 files changed, 39 insertions, 3 deletions
diff --git a/gdb/linux-tdep.c b/gdb/linux-tdep.c
index b6f2efb..65f5f97 100644
--- a/gdb/linux-tdep.c
+++ b/gdb/linux-tdep.c
@@ -547,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);
@@ -569,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);