From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 15564 invoked by alias); 26 Oct 2011 20:50:19 -0000 Received: (qmail 15549 invoked by uid 22791); 26 Oct 2011 20:50:16 -0000 X-SWARE-Spam-Status: No, hits=-5.4 required=5.0 tests=AWL,BAYES_50,RCVD_IN_DNSWL_HI,RP_MATCHES_RCVD,SPF_HELO_PASS,TW_BJ,TW_RG X-Spam-Check-By: sourceware.org Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Wed, 26 Oct 2011 20:49:58 +0000 Received: from int-mx01.intmail.prod.int.phx2.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id p9QKnvoM031710 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK) for ; Wed, 26 Oct 2011 16:49:58 -0400 Received: from psique (ovpn-112-22.phx2.redhat.com [10.3.112.22]) by int-mx01.intmail.prod.int.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id p9QKnset006663 for ; Wed, 26 Oct 2011 16:49:56 -0400 From: Sergio Durigan Junior To: gdb-patches@sourceware.org Subject: [PATCH] Implement new `info core mappings' command Date: Wed, 26 Oct 2011 21:08:00 -0000 Message-ID: User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/23.2 (gnu/linux) MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii X-IsSubscribed: yes Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org X-SW-Source: 2011-10/txt/msg00707.txt.bz2 Hello there, This patch is the revival of: http://sourceware.org/ml/gdb-patches/2008-12/msg00322.html It's been a while since I wanted to work on this again, and hopefully get it upstream. I re-read the above thread, tried to address all the comments, rewrote some things, wrote testcase & doc & NEWS, and that's it. What this patch does is implement a new `info' command, called `info core', and then implement a sub-command called `info core mappings'. This was heavily based on the existing `info proc mappings'. The code iterates over the corefile's sections and, using some heuristics, match the ones containing useful information for displaying a memory mapping of the process. If the corefile section we're examining is empty, then it tries to search this information at ELF program headers, which is almost always the used solution. One thing I am not sure is where to put the entry for this command on the documentation. I decided to put it below `info proc', but I'd be glad if you could give your opinions. Reviews are welcome, as usual. Thanks! Sergio. 2011-10-26 Sergio Durigan Junior Implement `info core mappings'. * NEWS: Mention new `info core mappings' command. * corefile.c: Include a bunch of header files needed to implement the `info core mappings'. (print_proc_map_iter): New function. (print_core_map): Likewise. (info_core_cmd): Likewise. (_initialize_core): Add new `info core' command. 2011-10-26 Sergio Durigan Junior Implement `info core mappings'. * gdb.texinfo: Add documentation for `info core mappings'. 2011-10-26 Sergio Durigan Junior Implement `info core mappings'. * gdb.base/corefile.exp: Add test for `info core mappings'. diff --git a/gdb/NEWS b/gdb/NEWS index 5cdb63e..6f8feaa 100644 --- a/gdb/NEWS +++ b/gdb/NEWS @@ -3,6 +3,9 @@ *** Changes since GDB 7.3.1 +* GDB has a new `info core mappings' command. It displays the memory + regions in a corefile, similar to `info pro mappings' command. + * GDB has two new commands: "set remote hardware-watchpoint-length-limit" and "show remote hardware-watchpoint-length-limit". These allows to set or show the maximum length limit (in bytes) of a remote diff --git a/gdb/corefile.c b/gdb/corefile.c index ce3b755..af5a065 100644 --- a/gdb/corefile.c +++ b/gdb/corefile.c @@ -24,17 +24,23 @@ #include #include #include +#include #include "inferior.h" #include "symtab.h" +#include "gdbarch.h" +#include "arch-utils.h" #include "command.h" #include "gdbcmd.h" #include "bfd.h" +#include "elf-bfd.h" +#include "elf/internal.h" #include "target.h" #include "gdbcore.h" #include "dis-asm.h" #include "gdb_stat.h" #include "completer.h" #include "exceptions.h" +#include "objfiles.h" /* Local function declarations. */ @@ -83,6 +89,186 @@ core_file_command (char *filename, int from_tty) } +/* Helper function for `print_core_map'. It is used to iterate + over the corefile's sections and print proper information about + memory-mappings. + + BFD is the bfd used to get the sections. + SECT is the current section being "visited". + OBJ is not used. */ + +static void +print_proc_map_iter (bfd *bfd, asection *sect, void *obj) +{ + /* We're interested in matching sections' names beginning with + `load', because they are the sections containing information + about the process' memory regions. */ + static const char *proc_map_match = "load"; + int proc_map_match_size = strlen (proc_map_match); + /* Flag to indicate whether we have found something. */ + int found = 0; + /* The section's size. */ + bfd_size_type secsize; + /* We have to know the bitness of this architecture. */ + int bitness; + /* We'll use these later. They are basically used for iterating + over every objfile in the system so that we can find needed + information about the memory region being examinated. */ + struct obj_section *s = NULL; + struct objfile *objfile = NULL; + /* Fields to be printed for the proc map. */ + unsigned long start = 0, end = 0; + unsigned int size = 0; + char *filename = NULL; + + if (strncmp (proc_map_match, sect->name, proc_map_match_size) != 0) + /* This section is not useful. */ + return; + + bitness = gdbarch_addr_bit (gdbarch_from_bfd (bfd)); + + /* Unfortunately, some sections in the corefile don't have any + content inside. This is bad because we need to print, among + other things, its final address in the memory (which is + impossible to know if we don't have a size). That's why we + first need to check if the section's got anything inside it. */ + secsize = bfd_section_size (bfd, sect); + + if (secsize == 0) + { + /* Ok, the section is empty. In this case, we must look inside + ELF's Program Header, because (at least) there we have + information about the section's size. That's what we're doing + here. */ + Elf_Internal_Phdr *p = elf_tdata (bfd)->phdr; + if (p != NULL) + { + int i; + unsigned int n = elf_elfheader (bfd)->e_phnum; + for (i = 0; i < n; i++, p++) + /* For each entry in the Program Header, we have to + check if the section's initial address is equal to + the entry's virtual address. If it is, then we + have just found the section's entry in the Program + Header, and can use the entry's information to + complete missing data from the section. */ + if (sect->vma == p->p_vaddr) + { + found = 1; + break; + } + if (found) + secsize = p->p_memsz; + } + } + + size = secsize; + start = sect->vma; + end = (unsigned long) (sect->vma + size); + + /* Now begins a new part of the work. We still don't have complete + information about the memory region. For example, we still need + to know the filename which is represented by the region. Such + info can be gathered from the objfile's data structure, and for + that we must iterate over all the objsections and check if the + objsection's initial address is inside the section we have at hand. + If it is, then we can use this specific objsection to obtain the + missing data. */ + found = 0; + ALL_OBJSECTIONS (objfile, s) + if (obj_section_addr (s) >= start + && obj_section_addr (s) <= end) + { + found = 1; + break; + } + + if (found) + filename = s->objfile->name; + + if (bitness == 32) + printf_filtered ("\t%#10lx %#10lx %#10x %7s\n", + start, + end, + (int) size, + filename ? filename : ""); + else + printf_filtered (" %#18lx %#18lx %#10x %7s\n", + start, + end, + (int) size, + filename ? filename : ""); +} + +/* Implements the `info proc map' command when the user has provided + a corefile. */ + +static void +print_core_map (void) +{ + const char *exe; + int bitness; + + gdb_assert (core_bfd != NULL); + + bitness = gdbarch_addr_bit (gdbarch_from_bfd (core_bfd)); + + /* Getting the executable name. */ + exe = bfd_core_file_failing_command (core_bfd); + + printf_filtered (_("exe = '%s'\n"), exe); + printf_filtered (_("Mapped address spaces:\n\n")); + if (bitness == 32) + printf_filtered ("\t%10s %10s %10s %7s\n", + "Start Addr", + " End Addr", + " Size", "objfile"); + else + printf_filtered (" %18s %18s %10s %7s\n", + "Start Addr", + " End Addr", + " Size", "objfile"); + + bfd_map_over_sections (core_bfd, + print_proc_map_iter, + NULL); +} + +/* Implement the `info core' command. */ + +static void +info_core_cmd (char *args, int from_tty) +{ + char **argv = NULL; + int mappings_f = 1; + int all = 0; + + if (!core_bfd) + error (_("You are not using a corefile at the moment.")); + + if (args) + { + /* Break up 'args' into an argv array. */ + argv = gdb_buildargv (args); + make_cleanup_freeargv (argv); + } + while (argv != NULL && *argv != NULL) + { + if (strncmp (argv[0], "mappings", strlen (argv[0])) == 0) + { + mappings_f = 1; + } + else if (strncmp (argv[0], "all", strlen (argv[0])) == 0) + { + all = 1; + } + argv++; + } + + if (mappings_f || all) + print_core_map (); +} + /* If there are two or more functions that wish to hook into exec_file_command, this function will call all of the hook functions. */ @@ -450,6 +636,11 @@ _initialize_core (void) { struct cmd_list_element *c; + add_info ("core", info_core_cmd, _("\ +Show information about a corefile.\n\ +Specify any of the following keywords for detailed info:\n\ + mappings -- list of mapped memory regions.")); + c = add_cmd ("core-file", class_files, core_file_command, _("\ Use FILE as core dump for examining memory and registers.\n\ No arg means have no core file. This command has been superseded by the\n\ diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo index b451a6a..92e06f3 100644 --- a/gdb/doc/gdb.texinfo +++ b/gdb/doc/gdb.texinfo @@ -17655,6 +17655,13 @@ value; etc. For more information, see the @samp{proc} man page Show all the information about the process described under all of the above @code{info proc} subcommands. +@kindex info core +@cindex core dump file +@item info core +@item info core mappings +@cindex memory address space mappings +Report the memory address space ranges accessible in the core file. + @ignore @comment These sub-options of 'info proc' were not included when @comment procfs.c was re-written. Keep their descriptions around diff --git a/gdb/testsuite/gdb.base/corefile.exp b/gdb/testsuite/gdb.base/corefile.exp index 5b0cdf1..190281c 100644 --- a/gdb/testsuite/gdb.base/corefile.exp +++ b/gdb/testsuite/gdb.base/corefile.exp @@ -171,6 +171,13 @@ gdb_test_multiple "x/8bd buf2" "$test" { } } +# Test the `info core mapping' command. +set ws "\[ \t\]+" +set test "test info core mapping" +gdb_test "info core mapping" \ + ".*Mapped address spaces:.*${hex}${ws}${hex}${ws}${hex}.*" \ + $test + # test reinit_frame_cache gdb_load ${binfile}