This is the mail archive of the gdb-patches@sources.redhat.com mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [RFA] arm_scan_prologue: accept strh and strb as well as str


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
2002-04-25  Michael Snyder  <msnyder@redhat.com>

	* 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, <cnt>, [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, <cnt>, [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)

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]