From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 23062 invoked by alias); 29 Nov 2006 17:21:06 -0000 Received: (qmail 23052 invoked by uid 22791); 29 Nov 2006 17:21:04 -0000 X-Spam-Check-By: sourceware.org Received: from mail.codesourcery.com (HELO mail.codesourcery.com) (65.74.133.4) by sourceware.org (qpsmtpd/0.31) with ESMTP; Wed, 29 Nov 2006 17:21:00 +0000 Received: (qmail 14038 invoked from network); 29 Nov 2006 17:20:57 -0000 Received: from unknown (HELO ?172.16.64.38?) (vladimir@127.0.0.2) by mail.codesourcery.com with ESMTPA; 29 Nov 2006 17:20:57 -0000 From: Vladimir Prus To: gdb-patches@sources.redhat.com Subject: variable objects and registers Date: Wed, 29 Nov 2006 17:21:00 -0000 User-Agent: KMail/1.9.1 MIME-Version: 1.0 Content-Type: Multipart/Mixed; boundary="Boundary-00=_vFcbFHfvzcl4cSk" Message-Id: <200611292020.47109.vladimir@codesourcery.com> 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: 2006-11/txt/msg00403.txt.bz2 --Boundary-00=_vFcbFHfvzcl4cSk Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Content-Disposition: inline Content-length: 2314 I was working on implementing a new MI command that creates variable objects for registers, and I have something working good enough to discuss. This patch lacks docs, but I wanted to make sure the interface is fine with everybody before documenting it. There are already some commands related to registers, for example, -data-list-register-names. But for registers that are not just integers, one has to use variable objects to property display them. As result, output of -data-list-register-names goes directly to a number of -var-create. It is more reasonable to have a command that immediately produces variable objects. Further, when memory-mapped registers are involved, gdb might want to group them in some hierarchy. Using variable objects is a reasonable way to achieve that. This patch adds new command -var-registers that creates and returns a list of variable objects for all registers gdb knows. The command takes one option -- the frame, which is specified just like for -var-create. While not all registers are saved, and so gdb might not know values of some registers in parent frames, for some registers it's possible, and frontends might want to access those values. Since the command creates several variable objects, it does not accepts a name of varobj. Instead, it automatically generated names much like "var-create -" does. Here's example output: -var-registers * ^done,registers={ {name="var1",exp="$eax",numchild="0",value="16",type="int"}, ............ {name="var10",exp="$eflags",numchild="0",value="[ SF IF ID ]", As soon as we add the code to display memory-mapped registers, there will be a problem that existing frontends might wish to show the memory-mapped registers, but not wish (at the moment) to modify the code for displaying regular registers. I plan to address this by either adding new attribute "register-kind" to the output, that can be either "core" or "memory-mapped", or by adding an option to -var-registers that says what registers to show. But that's for future. Comments? - Volodya * mi/mi-cmds.h (mi_cmd_var_registers): New. * mi/mi-cmds.c: Register "var-registers". * mi/mi-cmd-var.c (create_varobj_in_frame): New function. (mi_cmd_var_create): Use the above. (mi_cmd_var_registers): New. --Boundary-00=_vFcbFHfvzcl4cSk Content-Type: text/x-diff; charset="us-ascii"; name="varobj_for_registers__gdb_mainline.diff" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="varobj_for_registers__gdb_mainline.diff" Content-length: 5091 === gdb/mi/mi-cmds.h ================================================================== --- gdb/mi/mi-cmds.h (/patches/gdb/varobj_printing/gdb_mainline) (revision 2338) +++ gdb/mi/mi-cmds.h (/patches/gdb/varobj_for_registers/gdb_mainline) (revision 2338) @@ -105,6 +105,7 @@ extern mi_cmd_argv_ftype mi_cmd_thread_select; extern mi_cmd_argv_ftype mi_cmd_var_assign; extern mi_cmd_argv_ftype mi_cmd_var_create; +extern mi_cmd_argv_ftype mi_cmd_var_registers; extern mi_cmd_argv_ftype mi_cmd_var_delete; extern mi_cmd_argv_ftype mi_cmd_var_evaluate_expression; extern mi_cmd_argv_ftype mi_cmd_var_info_expression; === gdb/mi/mi-cmds.c ================================================================== --- gdb/mi/mi-cmds.c (/patches/gdb/varobj_printing/gdb_mainline) (revision 2338) +++ gdb/mi/mi-cmds.c (/patches/gdb/varobj_for_registers/gdb_mainline) (revision 2338) @@ -153,6 +153,7 @@ { "trace-stop", { NULL, 0 }, NULL, NULL }, { "var-assign", { NULL, 0 }, 0, mi_cmd_var_assign}, { "var-create", { NULL, 0 }, 0, mi_cmd_var_create}, + { "var-registers", { NULL, 0 }, 0, mi_cmd_var_registers}, { "var-delete", { NULL, 0 }, 0, mi_cmd_var_delete}, { "var-evaluate-expression", { NULL, 0 }, 0, mi_cmd_var_evaluate_expression}, { "var-info-expression", { NULL, 0 }, 0, mi_cmd_var_info_expression}, === gdb/mi/mi-cmd-var.c ================================================================== --- gdb/mi/mi-cmd-var.c (/patches/gdb/varobj_printing/gdb_mainline) (revision 2338) +++ gdb/mi/mi-cmd-var.c (/patches/gdb/varobj_for_registers/gdb_mainline) (revision 2338) @@ -68,16 +68,39 @@ /* VAROBJ operations */ +static struct varobj * +create_varobj_in_frame (char *name, char *expression, char *frame) +{ + CORE_ADDR frameaddr = 0; + struct cleanup *cleanup; + enum varobj_type var_type; + + if (strcmp (frame, "*") == 0) + var_type = USE_CURRENT_FRAME; + else if (strcmp (frame, "@") == 0) + var_type = USE_SELECTED_FRAME; + else + { + var_type = USE_SPECIFIED_FRAME; + frameaddr = string_to_core_addr (frame); + } + + if (varobjdebug) + fprintf_unfiltered (gdb_stdlog, + "Name=\"%s\", Frame=\"%s\" (0x%s), Expression=\"%s\"\n", + name, frame, paddr (frameaddr), expression); + + return varobj_create (name, expression, frameaddr, var_type); +} + enum mi_cmd_result mi_cmd_var_create (char *command, char **argv, int argc) { - CORE_ADDR frameaddr = 0; struct varobj *var; char *name; char *frame; char *expr; struct cleanup *old_cleanups; - enum varobj_type var_type; if (argc != 3) { @@ -104,23 +127,8 @@ else if (!isalpha (*name)) error (_("mi_cmd_var_create: name of object must begin with a letter")); - if (strcmp (frame, "*") == 0) - var_type = USE_CURRENT_FRAME; - else if (strcmp (frame, "@") == 0) - var_type = USE_SELECTED_FRAME; - else - { - var_type = USE_SPECIFIED_FRAME; - frameaddr = string_to_core_addr (frame); - } + var = create_varobj_in_frame (name, expr, frame); - if (varobjdebug) - fprintf_unfiltered (gdb_stdlog, - "Name=\"%s\", Frame=\"%s\" (0x%s), Expression=\"%s\"\n", - name, frame, paddr (frameaddr), expr); - - var = varobj_create (name, expr, frameaddr, var_type); - if (var == NULL) error (_("mi_cmd_var_create: unable to create variable object")); @@ -131,6 +139,58 @@ } enum mi_cmd_result +mi_cmd_var_registers (char *command, char **argv, int argc) +{ + int regnum, numregs; + struct cleanup *cleanup; + char *frame; + + if (argc != 1) + error (_("mi_cmd_var_registers: Usage: FRAME.")); + + frame = xstrdup (argv[0]); + cleanup = make_cleanup (xfree, frame); + + /* Note that the test for a valid register must include checking the + REGISTER_NAME because NUM_REGS may be allocated for the union of + the register sets within a family of related processors. In this + case, some entries of REGISTER_NAME will change depending upon + the particular processor being debugged. */ + + numregs = NUM_REGS + NUM_PSEUDO_REGS; + + make_cleanup_ui_out_tuple_begin_end (uiout, "registers"); + + for (regnum = 0; regnum < numregs; regnum++) + { + if (REGISTER_NAME (regnum) != NULL + && *(REGISTER_NAME (regnum)) != '\0') + { + char *name; + char *expression; + struct varobj *var; + struct cleanup *cleanup_child; + + name = varobj_gen_name (); + make_cleanup (free_current_contents, &name); + + expression = xstrprintf ("$%s", REGISTER_NAME (regnum)); + make_cleanup (xfree, expression); + + var = create_varobj_in_frame (name, expression, frame); + + cleanup_child = make_cleanup_ui_out_tuple_begin_end (uiout, NULL); + print_varobj (var, PRINT_ALL_VALUES, 1 /* print expression */); + do_cleanups (cleanup_child); + } + } + + do_cleanups (cleanup); + return MI_CMD_DONE; +} + + +enum mi_cmd_result mi_cmd_var_delete (char *command, char **argv, int argc) { char *name; Property changes on: ___________________________________________________________________ Name: csl:base +/all/patches/gdb/varobj_printing/gdb_mainline --Boundary-00=_vFcbFHfvzcl4cSk--