From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 27394 invoked by alias); 2 May 2002 02:57:16 -0000 Mailing-List: contact gdb-help@sources.redhat.com; run by ezmlm Precedence: bulk List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-owner@sources.redhat.com Received: (qmail 27387 invoked from network); 2 May 2002 02:57:15 -0000 Received: from unknown (HELO SUGAH2.triscend.com) (63.87.30.34) by sources.redhat.com with SMTP; 2 May 2002 02:57:15 -0000 Received: by SUGAH2.triscend.com with Internet Mail Service (5.5.2653.19) id <27AV60H1>; Wed, 1 May 2002 19:57:05 -0700 Message-ID: <2407239113CD914CBA855A47698F01B06222F8@SUGAH2.triscend.com> From: Craig Hackney To: "'gdb@sources.redhat.com'" Subject: Displaying more than 16 registers with GDB for ARM targets Date: Wed, 01 May 2002 19:57:00 -0000 MIME-Version: 1.0 Content-Type: text/plain; charset="iso-8859-1" X-SW-Source: 2002-05/txt/msg00006.txt.bz2 Hi, I'm working with a remote ARM target that is capable of sending CPU registers for all CPU modes (FIQ, IRQ, etc...) 37 registers in total. However GDB only displays a max of 16 registers, R0-R15 plus a few floating point ones. I have been looking at a way to allow GDB to display my extra registers without having to change the ARM architecture of GDB for my specific target. And I'd like to share my findings to see if this is the best way of doing it. There are two main problems which I have outlined below. PROBLEM 1: GDB uses a #define called NUM_REGS to determine how many registers a target has, this #define uses gdbarch_num_regs() to return the number of registers for a specific target. For ARM targets, the number of registers is set by calling set_gdbarch_num_regs() in arm-tdep.c the value passed is NUM_GREGS + NUM_FREGS + NUM_SREGS which totals about 26. NUM_REGS is used to allocate memory for the register_valid, and registers variables in regcache.c. Since my target returns 37 registers, there is not enough space to store them all using supply_register(). SOLUTION: Add a #define to arm-tdep.h called MAX_ARM_REGS, this #define is the max number of registers for all ARM targets, currently I'm using a value of 48, which is is enough for the currently supported ARM registers, plus the extra ones I need. This #define is then used in arm-tdep.c to set the number of registers for the ARM target with the call to set_gdbarch_num_regs(). Now when space is allocated for the register_valid and registers variables, there is enough space for my extra registers so I can call supply_register() with out a core dump. PROBLEM 2: There is no way to dynamically change the register names based on a target selection. For example, lets say I create a remote target interface based on remote.c, when I read the target registers by issuing the remote 'g' command I get all 37 registers back from the target and inform GDB by calling supply_register(). Since GDB only displays registers that it has names for, and my extra registers have no names, they are not displayed by GDB. SOLUTION: I have expanded on GDBs 'set disassembly-flavor' command which allows the selection of different names for the standard ARM registers R0-R15. I updated the regnames structure in arm-dis.c so that it can hold upto 48 (the same as MAX_ARM_REGS) register names instead of 16. This allows me to add my extra register names. I also added an entry to the arm_regname structure that contains the number of registers for each flavor. The get_arm_regnames() function in arm-dis.c now returns the number of registers from the new entry in the arm_regname structure instead of a hard coded 16. I updated the set_disassembly_flavor() function in arm-tdep.c so that it uses the value returned from the get_arm_regnames() function to set the correct number of register names. Since the register names are copied to the arm_register_name_strings variable in arm-tdep.c I also increased the array size of this variable to MAX_ARM_REGS again to prevent a core dump. With all of these changes I am able to execute the 'set disassembly-flavor' command and have GDB display all of my registers. Last but not least, I wanted to be able to change the register names (disassembly-flavor) from within my own version of remote.c. So I added a function called set_register_name() to arm-tdep.c, now I can call this function to setup the register names that I want to use from within my remote target back end, since I do this when the target is 'opened', the register names only change when my target is used.