diff options
author | Jan Kratochvil <jan.kratochvil@redhat.com> | 2012-08-07 13:26:33 +0000 |
---|---|---|
committer | Jan Kratochvil <jan.kratochvil@redhat.com> | 2012-08-07 13:26:33 +0000 |
commit | 4f69f4c267a21e787685116945fb40729a7297a5 (patch) | |
tree | ccffd19fbc910eedac303b46c8c4bad9db964b76 /gdb/linux-tdep.c | |
parent | 82435b3b3da1b288ca2d2596a9de40e6bc734773 (diff) | |
download | gdb-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.c | 42 |
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); |