From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 10247 invoked by alias); 25 Sep 2003 20:45:20 -0000 Mailing-List: contact gdb-patches-help@sources.redhat.com; run by ezmlm Precedence: bulk List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sources.redhat.com Received: (qmail 10239 invoked from network); 25 Sep 2003 20:45:19 -0000 Received: from unknown (HELO dublin.act-europe.fr) (212.157.227.154) by sources.redhat.com with SMTP; 25 Sep 2003 20:45:19 -0000 Received: from localhost (localhost [127.0.0.1]) by amavis.act-europe.fr (Postfix) with ESMTP id 63C2822A007 for ; Thu, 25 Sep 2003 22:45:18 +0200 (MET DST) Received: from dublin.act-europe.fr ([127.0.0.1]) by localhost (dublin.act-europe.fr [127.0.0.1:10024]) (amavisd-new) with ESMTP id 23796-01 for ; Thu, 25 Sep 2003 22:45:07 +0200 (MET DST) Received: from berne.int.act-europe.fr (berne.act-europe.fr [10.10.0.165]) by dublin.act-europe.fr (Postfix) with ESMTP id 8C0C122A00C for ; Thu, 25 Sep 2003 22:44:53 +0200 (MET DST) Received: by berne.int.act-europe.fr (Postfix, from userid 560) id 786D9592B; Thu, 25 Sep 2003 16:44:52 -0400 (EDT) Date: Thu, 25 Sep 2003 20:45:00 -0000 From: Jerome Guitton To: gdb-patches@sources.redhat.com Subject: [RFA/RFC] ARM : one-line prologue analysis Message-ID: <20030925204452.GA15754@act-europe.fr> Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="x+6KMIRAuhnl3hBn" Content-Disposition: inline User-Agent: Mutt/1.4i X-Virus-Scanned: by amavisd-new X-SW-Source: 2003-09/txt/msg00576.txt.bz2 --x+6KMIRAuhnl3hBn Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Content-length: 2315 The support for unwinding through functions which do not build a frame pointer seems broken for arm-elf. Consider the attached example. It is basically main -> c -> b -> a (X '->' Y meaning "X calls Y"). the calls to printf are here only to avoid sibcall optimization. With gcc 3.2, we will get a one-line prologue for a, b, c and main : a: str lr, [sp, #-4]! [...] Alas, getting a backtrace from 'a' will not work properly: (gdb) file d Reading symbols from d...done. (gdb) target sim Connected to the simulator. (gdb) load d [...] (gdb) b a Breakpoint 1 at 0x8228: file a.c, line 5. (gdb) r Starting program: /cardiff.a/guitton/fsf/gdb-head-merge/tmp/test/d Breakpoint 1, a () at a.c:5 5 printf ("HERE I AM J.H."); (gdb) bt #0 a () at a.c:5 #1 0x00824000 in ?? () There is a 'address minus one' thing going on. Indeed, 0x00824000 is not a valid address, it should be 0x00008240: (gdb) x/i 0x00008240 0x8240 : ldr r0, [pc, #8] ; 0x8250 This problem is in arm_make_prologue_cache. Indeed, for testing if a register has been saved on the stack, arm_make_prologue_cache should compare the field addr of the saved reg table to -1, according to trad-frame.h. It compare it to 0! That's where the 'address minus -1' thing comes from. The first patch is a fix for this bug (obv.dif). It seems straight forward to me. I run the gdb testsuite on a arm-elf simulator, it fixes 150 failures. No regression. Still, there is another bug: (gdb) bt #0 a () at a.c:5 #1 0x00008240 in b () at b.c:4 #2 0x00008240 in b () at b.c:4 For some reason that I don't understand completely (and that's the [RFC] part of this email), in arm_scan_prologue the choice has been made not to get lr from the stack if the prologue is "str lr, [sp, #4]!". I just want to point out that getting it from the stack (my second patch, lr.dif) fixes the problem: (gdb) bt #0 a () at a.c:5 #1 0x00008240 in b () at b.c:4 #2 0x0000825c in c () at c.c:4 #3 0x00008278 in main () at d.c:2 I don't thing that's a good idea to consider that these one-line-prologue functions are frameless, even if they don't build a frame pointer. Opinions/ideas? Tested against the testsuite on the arm simulator, I get no regression and no fix. (the baseline debugger includes my first patch) -- Jerome --x+6KMIRAuhnl3hBn Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename="obv.dif" Content-length: 924 2003-09-25 Jerome Guitton * arm-tdep.c (arm_make_prologue_cache): Compare the field addr of the saved regs record with -1 to test if the register has been saved on the stack. *** arm-tdep.c.1 Tue Sep 23 20:58:12 2003 --- arm-tdep.c Tue Sep 23 20:58:45 2003 *************** arm_make_prologue_cache (struct frame_in *** 967,973 **** /* Calculate actual addresses of saved registers using offsets determined by arm_scan_prologue. */ for (reg = 0; reg < NUM_REGS; reg++) ! if (cache->saved_regs[reg].addr != 0) cache->saved_regs[reg].addr += cache->prev_sp; return cache; --- 967,973 ---- /* Calculate actual addresses of saved registers using offsets determined by arm_scan_prologue. */ for (reg = 0; reg < NUM_REGS; reg++) ! if (cache->saved_regs[reg].addr != -1) cache->saved_regs[reg].addr += cache->prev_sp; return cache; --x+6KMIRAuhnl3hBn Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename="lr.dif" Content-length: 788 2003-09-25 Jerome Guitton * arm-tdep.c (arm_scan_prologue_cache): When analysing the instruction "str lr, [sp, #-4]", save the address where lr has been stored. *** arm-tdep.c.2 Tue Sep 23 20:59:52 2003 --- arm-tdep.c Tue Sep 23 21:06:07 2003 *************** arm_scan_prologue (struct frame_info *ne *** 845,851 **** } else if (insn == 0xe52de004) /* str lr, [sp, #-4]! */ { ! /* Function is frameless: extra_info defaults OK? */ continue; } else if ((insn & 0xffff0000) == 0xe92d0000) --- 845,852 ---- } else if (insn == 0xe52de004) /* str lr, [sp, #-4]! */ { ! sp_offset -= 4; ! cache->saved_regs[ARM_LR_REGNUM].addr = sp_offset; continue; } else if ((insn & 0xffff0000) == 0xe92d0000) --x+6KMIRAuhnl3hBn Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename="example.txt" Content-length: 498 /* a.c */ extern void abort (); void a () { printf ("HERE I AM J.H."); } /* b.c */ void b () { int i = 2; a (); printf ("END B %d \n", i); } /* c.c */ void c () { int i = 3; b (); printf ("END C %d \n", i); } /* d.c */ int main () { c (); printf ("END D\n"); } #Makefile CFLAGS=-O2 -save-temps -g ARMCFLAGS=-mno-apcs-frame .SUFFIXES: .c .c.o: arm-elf-gcc -c $(CFLAGS) $(ARMCFLAGS) $< d: a.o b.o c.o d.o arm-elf-gcc a.o b.o c.o d.o -o d all: d clean: -rm *.o --x+6KMIRAuhnl3hBn--