From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 14685 invoked by alias); 8 May 2002 22:41:58 -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 14637 invoked from network); 8 May 2002 22:41:51 -0000 Received: from unknown (HELO cygnus.com) (205.180.83.203) by sources.redhat.com with SMTP; 8 May 2002 22:41:51 -0000 Received: from redhat.com (reddwarf.sfbay.redhat.com [172.16.24.50]) by runyon.cygnus.com (8.8.7-cygnus/8.8.7) with ESMTP id PAA03670; Wed, 8 May 2002 15:41:44 -0700 (PDT) Message-ID: <3CD9A696.CF676DB@redhat.com> Date: Wed, 08 May 2002 15:41:00 -0000 From: Michael Snyder Organization: Red Hat, Inc. X-Accept-Language: en MIME-Version: 1.0 To: Richard.Earnshaw@arm.com, Michael Snyder , gdb-patches@sources.redhat.com, rearnsha@arm.com Subject: Re: [RFA] arm_scan_prologue: accept strh and strb as well as str References: <200205081910.UAA08344@cam-mail2.cambridge.arm.com> <3CD9A561.D79A683D@redhat.com> Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit X-SW-Source: 2002-05/txt/msg00237.txt.bz2 Michael Snyder wrote: > > Richard Earnshaw wrote: > > > > > [sorry for the empty reply] > > > OK -- I'd be glad to do that. Could you possibly > > > provide me an example to work from? > > > > Below. > > > > > > > > arm_scan_prologue is easy, since it accepts prologue instructions > > > in any order, but arm_skip_prologue imposes an ordering on them. > > > I would REALLY like to merge these two functions. In fact I started > > > to, but then got busy with other things. > > > > Go for it... > > OK, how do you like the attached? > > Also, Andrew and I have been discussing whether the saved arg regs > should actually be added to the frame-saved-regs. If we decide that > they should, may I have your pre-approval to make that change? > > Thanks, > Michael Err, sorry, I should have mentioned that there are a few more trivial white-space changes in here too. Sloppy of me. Forgot they were there. > ------------------------------------------------------------------------ > 2002-04-25 Michael Snyder > > * arm-tdep.c (arm_scan_prologue): Accept strb r(0123),[r11,#-nn], > strh r(0123),[r11,#-nn], str r(0123),[r11,#-nn], as well as > strb r(0123),[sp,#nn], strh r(0123),[sp,#nn] and > str r(0123),[sp,#nn]. > (arm_skip_prologue): Ditto. Also make disassembly > order-independent by placing it in a loop. > > Index: arm-tdep.c > =================================================================== > RCS file: /cvs/src/src/gdb/arm-tdep.c,v > retrieving revision 1.57 > diff -p -r1.57 arm-tdep.c > *** arm-tdep.c 1 May 2002 00:57:51 -0000 1.57 > --- arm-tdep.c 8 May 2002 22:31:53 -0000 > *************** arm_skip_prologue (CORE_ADDR pc) > *** 417,423 **** > { > unsigned long inst; > CORE_ADDR skip_pc; > ! CORE_ADDR func_addr, func_end; > char *func_name; > struct symtab_and_line sal; > > --- 417,423 ---- > { > unsigned long inst; > CORE_ADDR skip_pc; > ! CORE_ADDR func_addr, func_end = 0; > char *func_name; > struct symtab_and_line sal; > > *************** arm_skip_prologue (CORE_ADDR pc) > *** 444,517 **** > > /* Can't find the prologue end in the symbol table, try it the hard way > by disassembling the instructions. */ > - skip_pc = pc; > - inst = read_memory_integer (skip_pc, 4); > - /* "mov ip, sp" is no longer a required part of the prologue. */ > - if (inst == 0xe1a0c00d) /* mov ip, sp */ > - { > - skip_pc += 4; > - inst = read_memory_integer (skip_pc, 4); > - } > > ! /* Some prologues begin with "str lr, [sp, #-4]!". */ > ! if (inst == 0xe52de004) /* str lr, [sp, #-4]! */ > ! { > ! skip_pc += 4; > ! inst = read_memory_integer (skip_pc, 4); > ! } > > ! if ((inst & 0xfffffff0) == 0xe92d0000) /* stmfd sp!,{a1,a2,a3,a4} */ > { > - skip_pc += 4; > inst = read_memory_integer (skip_pc, 4); > - } > > ! if ((inst & 0xfffff800) == 0xe92dd800) /* stmfd sp!,{fp,ip,lr,pc} */ > ! { > ! skip_pc += 4; > ! inst = read_memory_integer (skip_pc, 4); > ! } > > ! /* Any insns after this point may float into the code, if it makes > ! for better instruction scheduling, so we skip them only if we > ! find them, but still consider the function to be frame-ful. */ > ! > ! /* We may have either one sfmfd instruction here, or several stfe > ! insns, depending on the version of floating point code we > ! support. */ > ! if ((inst & 0xffbf0fff) == 0xec2d0200) /* sfmfd fn, , [sp]! */ > ! { > ! skip_pc += 4; > ! inst = read_memory_integer (skip_pc, 4); > ! } > ! else > ! { > ! while ((inst & 0xffff8fff) == 0xed6d0103) /* stfe fn, [sp, #-12]! */ > ! { > ! skip_pc += 4; > ! inst = read_memory_integer (skip_pc, 4); > ! } > ! } > > ! if ((inst & 0xfffff000) == 0xe24cb000) /* sub fp, ip, #nn */ > ! { > ! skip_pc += 4; > ! inst = read_memory_integer (skip_pc, 4); > ! } > > ! if ((inst & 0xfffff000) == 0xe24dd000) /* sub sp, sp, #nn */ > ! { > ! skip_pc += 4; > ! inst = read_memory_integer (skip_pc, 4); > ! } > > ! while ((inst & 0xffffcfc0) == 0xe50b0000) /* str r(0123), [r11, #-nn] */ > ! { > ! skip_pc += 4; > ! inst = read_memory_integer (skip_pc, 4); > } > > ! return skip_pc; > } > > /* *INDENT-OFF* */ > --- 444,506 ---- > > /* Can't find the prologue end in the symbol table, try it the hard way > by disassembling the instructions. */ > > ! /* Like arm_scan_prologue, stop no later than pc + 64. */ > ! if (func_end == 0 || func_end > pc + 64) > ! func_end = pc + 64; > > ! for (skip_pc = pc; skip_pc < func_end; skip_pc += 4) > { > inst = read_memory_integer (skip_pc, 4); > > ! /* "mov ip, sp" is no longer a required part of the prologue. */ > ! if (inst == 0xe1a0c00d) /* mov ip, sp */ > ! continue; > > ! /* Some prologues begin with "str lr, [sp, #-4]!". */ > ! if (inst == 0xe52de004) /* str lr, [sp, #-4]! */ > ! continue; > > ! if ((inst & 0xfffffff0) == 0xe92d0000) /* stmfd sp!,{a1,a2,a3,a4} */ > ! continue; > > ! if ((inst & 0xfffff800) == 0xe92dd800) /* stmfd sp!,{fp,ip,lr,pc} */ > ! continue; > > ! /* Any insns after this point may float into the code, if it makes > ! for better instruction scheduling, so we skip them only if we > ! find them, but still consider the function to be frame-ful. */ > ! > ! /* We may have either one sfmfd instruction here, or several stfe > ! insns, depending on the version of floating point code we > ! support. */ > ! if ((inst & 0xffbf0fff) == 0xec2d0200) /* sfmfd fn, , [sp]! */ > ! continue; > ! > ! if ((inst & 0xffff8fff) == 0xed6d0103) /* stfe fn, [sp, #-12]! */ > ! continue; > ! > ! if ((inst & 0xfffff000) == 0xe24cb000) /* sub fp, ip, #nn */ > ! continue; > ! > ! if ((inst & 0xfffff000) == 0xe24dd000) /* sub sp, sp, #nn */ > ! continue; > ! > ! if ((inst & 0xffffc000) == 0xe54b0000 || /* strb r(0123),[r11,#-nn] */ > ! (inst & 0xffffc0f0) == 0xe14b00b0 || /* strh r(0123),[r11,#-nn] */ > ! (inst & 0xffffc000) == 0xe50b0000) /* str r(0123),[r11,#-nn] */ > ! continue; > ! > ! if ((inst & 0xffffc000) == 0xe5cd0000 || /* strb r(0123),[sp,#nn] */ > ! (inst & 0xffffc0f0) == 0xe1cd00b0 || /* strh r(0123),[sp,#nn] */ > ! (inst & 0xffffc000) == 0xe58d0000) /* str r(0123),[sp,#nn] */ > ! continue; > ! > ! /* Un-recognized instruction; stop scanning. */ > ! break; > } > > ! return skip_pc; /* End of prologue */ > } > > /* *INDENT-OFF* */ > *************** thumb_scan_prologue (struct frame_info * > *** 597,603 **** > whether to save LR (R14). */ > mask = (insn & 0xff) | ((insn & 0x100) << 6); > > ! /* Calculate offsets of saved R0-R7 and LR. */ > for (regno = ARM_LR_REGNUM; regno >= 0; regno--) > if (mask & (1 << regno)) > { > --- 586,592 ---- > whether to save LR (R14). */ > mask = (insn & 0xff) | ((insn & 0x100) << 6); > > ! /* Calculate offsets of saved R0-R7 and LR. */ > for (regno = ARM_LR_REGNUM; regno >= 0; regno--) > if (mask & (1 << regno)) > { > *************** thumb_scan_prologue (struct frame_info * > *** 611,617 **** > else if ((insn & 0xff00) == 0xb000) /* add sp, #simm OR > sub sp, #simm */ > { > ! if ((findmask & 1) == 0) /* before push? */ > continue; > else > findmask |= 4; /* add/sub sp found */ > --- 600,606 ---- > else if ((insn & 0xff00) == 0xb000) /* add sp, #simm OR > sub sp, #simm */ > { > ! if ((findmask & 1) == 0) /* before push? */ > continue; > else > findmask |= 4; /* add/sub sp found */ > *************** arm_scan_prologue (struct frame_info *fi > *** 857,863 **** > Be careful, however, and if it doesn't look like a prologue, > don't try to scan it. If, for instance, a frameless function > begins with stmfd sp!, then we will tell ourselves there is > ! a frame, which will confuse stack traceback, as well ad"finish" > and other operations that rely on a knowledge of the stack > traceback. > > --- 846,852 ---- > Be careful, however, and if it doesn't look like a prologue, > don't try to scan it. If, for instance, a frameless function > begins with stmfd sp!, then we will tell ourselves there is > ! a frame, which will confuse stack traceback, as well as "finish" > and other operations that rely on a knowledge of the stack > traceback. > > *************** arm_scan_prologue (struct frame_info *fi > *** 870,876 **** > [Note further: The "mov ip,sp" only seems to be missing in > frameless functions at optimization level "-O2" or above, > in which case it is often (but not always) replaced by > ! "str lr, [sp, #-4]!". - Michael Snyder, 2002-04-23] */ > > sp_offset = fp_offset = 0; > > --- 859,865 ---- > [Note further: The "mov ip,sp" only seems to be missing in > frameless functions at optimization level "-O2" or above, > in which case it is often (but not always) replaced by > ! "str lr, [sp, #-4]!". - Michael Snyder, 2002-04-23] */ > > sp_offset = fp_offset = 0; > > *************** arm_scan_prologue (struct frame_info *fi > *** 904,910 **** > fi->saved_regs[regno] = sp_offset; > } > } > ! else if ((insn & 0xffffcfc0) == 0xe50b0000) /* str rx, [r11, -n] */ > { > /* No need to add this to saved_regs -- it's just an arg reg. */ > continue; > --- 893,908 ---- > fi->saved_regs[regno] = sp_offset; > } > } > ! else if ((insn & 0xffffc000) == 0xe54b0000 || /* strb rx,[r11,#-n] */ > ! (insn & 0xffffc0f0) == 0xe14b00b0 || /* strh rx,[r11,#-n] */ > ! (insn & 0xffffc000) == 0xe50b0000) /* str rx,[r11,#-n] */ > ! { > ! /* No need to add this to saved_regs -- it's just an arg reg. */ > ! continue; > ! } > ! else if ((insn & 0xffffc000) == 0xe5cd0000 || /* strb rx,[sp,#n] */ > ! (insn & 0xffffc0f0) == 0xe1cd00b0 || /* strh rx,[sp,#n] */ > ! (insn & 0xffffc000) == 0xe58d0000) /* str rx,[sp,#n] */ > { > /* No need to add this to saved_regs -- it's just an arg reg. */ > continue; > *************** arm_scan_prologue (struct frame_info *fi > *** 960,966 **** > } > else if ((insn & 0xf0000000) != 0xe0000000) > break; /* Condition not true, exit early */ > ! else if ((insn & 0xfe200000) == 0xe8200000) /* ldm? */ > break; /* Don't scan past a block load */ > else > /* The optimizer might shove anything into the prologue, > --- 958,964 ---- > } > else if ((insn & 0xf0000000) != 0xe0000000) > break; /* Condition not true, exit early */ > ! else if ((insn & 0xfe200000) == 0xe8200000) /* ldm? */ > break; /* Don't scan past a block load */ > else > /* The optimizer might shove anything into the prologue, > *************** arm_get_next_pc (CORE_ADDR pc) > *** 2050,2056 **** > static void > arm_software_single_step (enum target_signal sig, int insert_bpt) > { > ! static int next_pc; /* State between setting and unsetting. */ > static char break_mem[BREAKPOINT_MAX]; /* Temporary storage for mem@bpt */ > > if (insert_bpt) > --- 2048,2054 ---- > static void > arm_software_single_step (enum target_signal sig, int insert_bpt) > { > ! static int next_pc; /* State between setting and unsetting. */ > static char break_mem[BREAKPOINT_MAX]; /* Temporary storage for mem@bpt */ > > if (insert_bpt)