From patchwork Wed Mar 18 19:38:40 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sergio Durigan Junior X-Patchwork-Id: 5684 Received: (qmail 101852 invoked by alias); 18 Mar 2015 19:39:24 -0000 Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org Delivered-To: mailing list gdb-patches@sourceware.org Received: (qmail 101780 invoked by uid 89); 18 Mar 2015 19:39:24 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-1.8 required=5.0 tests=AWL, BAYES_00, SPF_HELO_PASS, SPF_PASS, T_RP_MATCHES_RCVD autolearn=ham version=3.3.2 X-HELO: mx1.redhat.com Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES256-GCM-SHA384 encrypted) ESMTPS; Wed, 18 Mar 2015 19:39:22 +0000 Received: from int-mx09.intmail.prod.int.phx2.redhat.com (int-mx09.intmail.prod.int.phx2.redhat.com [10.5.11.22]) by mx1.redhat.com (Postfix) with ESMTPS id 94113C6A1F for ; Wed, 18 Mar 2015 19:39:21 +0000 (UTC) Received: from psique.redhat.com (ovpn-113-183.phx2.redhat.com [10.3.113.183]) by int-mx09.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t2IJdJ9M007817; Wed, 18 Mar 2015 15:39:20 -0400 From: Sergio Durigan Junior To: GDB Patches Cc: Pedro Alves , Sergio Durigan Junior Subject: [PATCH 1/4] Improve identification of memory mappings Date: Wed, 18 Mar 2015 15:38:40 -0400 Message-Id: <1426707523-6499-2-git-send-email-sergiodj@redhat.com> In-Reply-To: <1426707523-6499-1-git-send-email-sergiodj@redhat.com> References: <1426707523-6499-1-git-send-email-sergiodj@redhat.com> X-IsSubscribed: yes This commit implements the new 'enum memory_mapping_state', which can be used to represent the different states of each memory mapping from the inferior. These states are: - MODIFIED, which means that the mapping should be dumped in corefiles - UNMODIFIED, which means that the mapping should not be dumped in corefiles (e.g., mappings that have been marked as VM_DONTDUMP), and - UNKNOWN, which means that we don't know whether the mapping should or should not be dumped. The last state is not used in this patch, but will be used in the following patches of this series. It is also worth mentioning that I do not intend to commit this patch independently. IOW, I will merge everything before pushing one single commit. Changes from v2: - Moved declaration of 'enum memory_mapping_state' from gdb/common/common-defs.h to gdb/defs.h. - Renamed variable to 'modified_state' (instead of 'state'). gdb/ChangeLog: 2015-03-18 Sergio Durigan Junior Jan Kratochvil Oleg Nesterov PR corefiles/16092 * defs.h (enum memory_mapping_state): New enum. (find_memory_region_ftype): Remove 'int modified' parameter, replacing by 'enum memory_mapping_state modified_state'. * gcore.c (gcore_create_callback): Likewise. (objfile_find_memory_regions): Passing 'MEMORY_MAPPING_UNKNOWN_STATE' or 'MEMORY_MAPPING_MODIFIED' when needed to 'func' callback, instead of saying the memory mapping was modified even without knowing it. * gnu-nat.c (gnu_find_memory_regions): Likewise. * linux-tdep.c (linux_find_memory_region_ftype): Remove 'int modified' parameter, replacing by 'enum memory_mapping_state modified_state'. (linux_find_memory_regions_thunk): Likewise. (linux_make_mappings_callback): Likewise. (find_mapping_size): Likewise. * procfs.c (find_memory_regions_callback): Likewise. --- gdb/defs.h | 13 ++++++++++++- gdb/gcore.c | 16 ++++++++++------ gdb/gnu-nat.c | 4 ++-- gdb/linux-tdep.c | 25 ++++++++++++++++--------- gdb/procfs.c | 2 +- 5 files changed, 41 insertions(+), 19 deletions(-) diff --git a/gdb/defs.h b/gdb/defs.h index 72512f6..37b1430 100644 --- a/gdb/defs.h +++ b/gdb/defs.h @@ -330,6 +330,16 @@ extern void init_source_path (void); /* From exec.c */ +/* Enum used to inform the state of a memory mapping. This is used in + functions implementing find_memory_region_ftype. */ + +enum memory_mapping_state + { + MEMORY_MAPPING_MODIFIED, + MEMORY_MAPPING_UNMODIFIED, + MEMORY_MAPPING_UNKNOWN_STATE, + }; + /* * Process memory area starting at ADDR with length SIZE. Area is readable iff READ is non-zero, writable if WRITE is non-zero, executable if EXEC is non-zero. Area is possibly changed against @@ -338,7 +348,8 @@ extern void init_source_path (void); typedef int (*find_memory_region_ftype) (CORE_ADDR addr, unsigned long size, int read, int write, int exec, - int modified, void *data); + enum memory_mapping_state state, + void *data); /* * Possible lvalue types. Like enum language, this should be in value.h, but needs to be here for the same reason. */ diff --git a/gdb/gcore.c b/gdb/gcore.c index 44b9d0c..751ddac 100644 --- a/gdb/gcore.c +++ b/gdb/gcore.c @@ -415,7 +415,8 @@ make_output_phdrs (bfd *obfd, asection *osec, void *ignored) static int gcore_create_callback (CORE_ADDR vaddr, unsigned long size, int read, - int write, int exec, int modified, void *data) + int write, int exec, + enum memory_mapping_state modified_state, void *data) { bfd *obfd = data; asection *osec; @@ -424,7 +425,8 @@ gcore_create_callback (CORE_ADDR vaddr, unsigned long size, int read, /* If the memory segment has no permissions set, ignore it, otherwise when we later try to access it for read/write, we'll get an error or jam the kernel. */ - if (read == 0 && write == 0 && exec == 0 && modified == 0) + if (read == 0 && write == 0 && exec == 0 + && modified_state == MEMORY_MAPPING_UNMODIFIED) { if (info_verbose) { @@ -435,7 +437,8 @@ gcore_create_callback (CORE_ADDR vaddr, unsigned long size, int read, return 0; } - if (write == 0 && modified == 0 && !solib_keep_data_in_core (vaddr, size)) + if (write == 0 && modified_state == MEMORY_MAPPING_UNMODIFIED + && !solib_keep_data_in_core (vaddr, size)) { /* See if this region of memory lies inside a known file on disk. If so, we can avoid copying its contents by clearing SEC_LOAD. */ @@ -528,7 +531,8 @@ objfile_find_memory_regions (struct target_ops *self, 1, /* All sections will be readable. */ (flags & SEC_READONLY) == 0, /* Writable. */ (flags & SEC_CODE) != 0, /* Executable. */ - 1, /* MODIFIED is unknown, pass it as true. */ + MEMORY_MAPPING_UNKNOWN_STATE, /* MODIFIED is + unknown. */ obfd); if (ret != 0) return ret; @@ -541,7 +545,7 @@ objfile_find_memory_regions (struct target_ops *self, 1, /* Stack section will be readable. */ 1, /* Stack section will be writable. */ 0, /* Stack section will not be executable. */ - 1, /* Stack section will be modified. */ + MEMORY_MAPPING_MODIFIED, /* Stack section will be modified. */ obfd); /* Make a heap segment. */ @@ -550,7 +554,7 @@ objfile_find_memory_regions (struct target_ops *self, 1, /* Heap section will be readable. */ 1, /* Heap section will be writable. */ 0, /* Heap section will not be executable. */ - 1, /* Heap section will be modified. */ + MEMORY_MAPPING_MODIFIED, /* Heap section will be modified. */ obfd); return 0; diff --git a/gdb/gnu-nat.c b/gdb/gnu-nat.c index d830773..60612a7 100644 --- a/gdb/gnu-nat.c +++ b/gdb/gnu-nat.c @@ -2611,7 +2611,7 @@ gnu_find_memory_regions (struct target_ops *self, last_protection & VM_PROT_READ, last_protection & VM_PROT_WRITE, last_protection & VM_PROT_EXECUTE, - 1, /* MODIFIED is unknown, pass it as true. */ + MEMORY_MAPPING_UNKNOWN_STATE, /* MODIFIED is unknown. */ data); last_region_address = region_address; last_region_end = region_address += region_length; @@ -2625,7 +2625,7 @@ gnu_find_memory_regions (struct target_ops *self, last_protection & VM_PROT_READ, last_protection & VM_PROT_WRITE, last_protection & VM_PROT_EXECUTE, - 1, /* MODIFIED is unknown, pass it as true. */ + MEMORY_MAPPING_UNKNOWN_STATE, /* MODIFIED is unknown. */ data); return 0; diff --git a/gdb/linux-tdep.c b/gdb/linux-tdep.c index ea0d4cd..15725c7 100644 --- a/gdb/linux-tdep.c +++ b/gdb/linux-tdep.c @@ -807,7 +807,9 @@ linux_core_info_proc (struct gdbarch *gdbarch, const char *args, typedef int linux_find_memory_region_ftype (ULONGEST vaddr, ULONGEST size, ULONGEST offset, ULONGEST inode, int read, int write, - int exec, int modified, + int exec, + enum memory_mapping_state + modified_state, const char *filename, void *data); @@ -847,7 +849,8 @@ linux_find_memory_regions_full (struct gdbarch *gdbarch, const char *permissions, *device, *filename; size_t permissions_len, device_len; int read, write, exec; - int modified = 0, has_anonymous = 0; + enum memory_mapping_state modified_state = MEMORY_MAPPING_UNMODIFIED; + int has_anonymous = 0; read_mapping (line, &addr, &endaddr, &permissions, &permissions_len, &offset, &device, &device_len, &inode, &filename); @@ -885,18 +888,18 @@ linux_find_memory_regions_full (struct gdbarch *gdbarch, break; } if (number != 0) - modified = 1; + modified_state = MEMORY_MAPPING_MODIFIED; } } /* 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; + modified_state = MEMORY_MAPPING_MODIFIED; /* Invoke the callback function to create the corefile segment. */ func (addr, endaddr - addr, offset, inode, - read, write, exec, modified, filename, obfd); + read, write, exec, modified_state, filename, obfd); } do_cleanups (cleanup); @@ -926,12 +929,14 @@ struct linux_find_memory_regions_data static int linux_find_memory_regions_thunk (ULONGEST vaddr, ULONGEST size, ULONGEST offset, ULONGEST inode, - int read, int write, int exec, int modified, + int read, int write, int exec, + enum memory_mapping_state modified_state, const char *filename, void *arg) { struct linux_find_memory_regions_data *data = arg; - return data->func (vaddr, size, read, write, exec, modified, data->obfd); + return data->func (vaddr, size, read, write, exec, modified_state, + data->obfd); } /* A variant of linux_find_memory_regions_full that is suitable as the @@ -1074,7 +1079,8 @@ static linux_find_memory_region_ftype linux_make_mappings_callback; static int linux_make_mappings_callback (ULONGEST vaddr, ULONGEST size, ULONGEST offset, ULONGEST inode, - int read, int write, int exec, int modified, + int read, int write, int exec, + enum memory_mapping_state modified_state, const char *filename, void *data) { struct linux_make_mappings_data *map_data = data; @@ -1872,7 +1878,8 @@ linux_gdb_signal_to_target (struct gdbarch *gdbarch, static int find_mapping_size (CORE_ADDR vaddr, unsigned long size, - int read, int write, int exec, int modified, + int read, int write, int exec, + enum memory_mapping_state modified_state, void *data) { struct mem_range *range = data; diff --git a/gdb/procfs.c b/gdb/procfs.c index b62539f..d074dd3 100644 --- a/gdb/procfs.c +++ b/gdb/procfs.c @@ -4967,7 +4967,7 @@ find_memory_regions_callback (struct prmap *map, (map->pr_mflags & MA_READ) != 0, (map->pr_mflags & MA_WRITE) != 0, (map->pr_mflags & MA_EXEC) != 0, - 1, /* MODIFIED is unknown, pass it as true. */ + MEMORY_MAPPING_UNKNOWN_STATE, /* MODIFIED is unknown. */ data); }