[PATCH]: Fix stack offset correction for 68hc11

Stephane Carrez Stephane.Carrez@worldnet.fr
Tue Aug 29 12:13:00 GMT 2000


Hi!

For 68hc11, a stack offset correction of +1 must be applied on the stack
register before using it to read/write the memory.  No correction is required
for 68hc12. The stack offset correction was already applied (inlined) at
several places but it was only correct for 68hc11.

I've committed the following patch to fix the problem.

	Stephane

2000-08-29  Stephane Carrez  <Stephane.Carrez@worldnet.fr>

	* m68hc11-tdep.c (stack_correction): New variable for stack offset
	correction (1 for 68hc11, 0 for 68hc12).
	(m68hc11_saved_pc_after_call): Use it.
	(m68hc11_frame_chain): Likewise.
	(m68hc11_frame_init_saved_regs): Likewise.
	(m68hc11_init_extra_frame_info): Likewise.
	(m68hc11_push_return_address): Likewise.
	(m68hc11_push_arguments): Struct address must be corrected by
	applying the stack_correction offset.
	(m68hc11_store_struct_return): Likewise.
Index: m68hc11-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/m68hc11-tdep.c,v
retrieving revision 1.3
diff -p -r1.3 m68hc11-tdep.c
*** m68hc11-tdep.c	2000/08/26 13:36:25	1.3
--- m68hc11-tdep.c	2000/08/29 19:09:47
*************** static int soft_min_addr;
*** 120,125 ****
--- 120,131 ----
  static int soft_max_addr;
  static int soft_reg_initialized = 0;
  
+ /* Stack pointer correction value.  For 68hc11, the stack pointer points
+    to the next push location.  An offset of 1 must be applied to obtain
+    the address where the last value is saved.  For 68hc12, the stack
+    pointer points to the last value pushed.  No offset is necessary.  */
+ static int stack_correction = 1;
+ 
  /* Look in the symbol table for the address of a pseudo register
     in memory.  If we don't find it, pretend the register is not used
     and not available.  */
*************** m68hc11_saved_pc_after_call (struct fram
*** 275,281 ****
  {
    CORE_ADDR addr;
    
!   addr = read_register (HARD_SP_REGNUM) + 1;
    addr &= 0x0ffff;
    return read_memory_integer (addr, 2) & 0x0FFFF;
  }
--- 281,287 ----
  {
    CORE_ADDR addr;
    
!   addr = read_register (HARD_SP_REGNUM) + stack_correction;
    addr &= 0x0ffff;
    return read_memory_integer (addr, 2) & 0x0FFFF;
  }
*************** m68hc11_frame_chain (struct frame_info *
*** 618,624 ****
        return (CORE_ADDR) 0;
      }
  
!   addr = frame->frame + frame->extra_info->size + 1 - 2;
    addr = read_memory_unsigned_integer (addr, 2) & 0x0FFFF;
    if (addr == 0)
      {
--- 624,630 ----
        return (CORE_ADDR) 0;
      }
  
!   addr = frame->frame + frame->extra_info->size + stack_correction - 2;
    addr = read_memory_unsigned_integer (addr, 2) & 0x0FFFF;
    if (addr == 0)
      {
*************** static void
*** 637,643 ****
  m68hc11_frame_init_saved_regs (struct frame_info *fi)
  {
    CORE_ADDR pc;
! 
    if (fi->saved_regs == NULL)
      frame_saved_regs_zalloc (fi);
    else
--- 643,650 ----
  m68hc11_frame_init_saved_regs (struct frame_info *fi)
  {
    CORE_ADDR pc;
!   CORE_ADDR addr;
!   
    if (fi->saved_regs == NULL)
      frame_saved_regs_zalloc (fi);
    else
*************** m68hc11_frame_init_saved_regs (struct fr
*** 647,654 ****
    m68hc11_guess_from_prologue (pc, fi->frame, &pc, &fi->extra_info->size,
                                 fi->saved_regs);
  
!   fi->saved_regs[SOFT_FP_REGNUM] = fi->frame + fi->extra_info->size + 1 - 2;
!   fi->saved_regs[HARD_SP_REGNUM] = fi->frame + fi->extra_info->size + 1;
    fi->saved_regs[HARD_PC_REGNUM] = fi->saved_regs[HARD_SP_REGNUM];
  }
  
--- 654,662 ----
    m68hc11_guess_from_prologue (pc, fi->frame, &pc, &fi->extra_info->size,
                                 fi->saved_regs);
  
!   addr = fi->frame + fi->extra_info->size + stack_correction;
!   fi->saved_regs[SOFT_FP_REGNUM] = addr - 2;
!   fi->saved_regs[HARD_SP_REGNUM] = addr;
    fi->saved_regs[HARD_PC_REGNUM] = fi->saved_regs[HARD_SP_REGNUM];
  }
  
*************** m68hc11_init_extra_frame_info (int froml
*** 671,677 ****
      }
    else
      {
!       addr = fi->frame + fi->extra_info->size + 1;
        addr = read_memory_unsigned_integer (addr, 2) & 0x0ffff;
        fi->extra_info->return_pc = addr;
  #if 0
--- 679,685 ----
      }
    else
      {
!       addr = fi->frame + fi->extra_info->size + stack_correction;
        addr = read_memory_unsigned_integer (addr, 2) & 0x0ffff;
        fi->extra_info->return_pc = addr;
  #if 0
*************** m68hc11_push_arguments (int nargs,
*** 750,756 ****
    first_stack_argnum = 0;
    if (struct_return)
      {
!       write_register (HARD_D_REGNUM, struct_addr);
      }
    else if (nargs > 0)
      {
--- 758,767 ----
    first_stack_argnum = 0;
    if (struct_return)
      {
!       /* The struct is allocated on the stack and gdb used the stack
!          pointer for the address of that struct.  We must apply the
!          stack offset on the address.  */
!       write_register (HARD_D_REGNUM, struct_addr + stack_correction);
      }
    else if (nargs > 0)
      {
*************** m68hc11_push_arguments (int nargs,
*** 777,783 ****
      }
    sp -= stack_alloc;
  
!   stack_offset = 1;
    for (argnum = first_stack_argnum; argnum < nargs; argnum++)
      {
        type = VALUE_TYPE (args[argnum]);
--- 788,794 ----
      }
    sp -= stack_alloc;
  
!   stack_offset = stack_correction;
    for (argnum = first_stack_argnum; argnum < nargs; argnum++)
      {
        type = VALUE_TYPE (args[argnum]);
*************** m68hc11_register_virtual_type (int reg_n
*** 808,814 ****
  static void
  m68hc11_store_struct_return (CORE_ADDR addr, CORE_ADDR sp)
  {
!   write_register (HARD_D_REGNUM, addr);
  }
  
  static void
--- 819,828 ----
  static void
  m68hc11_store_struct_return (CORE_ADDR addr, CORE_ADDR sp)
  {
!   /* The struct address computed by gdb is on the stack.
!      It uses the stack pointer so we must apply the stack
!      correction offset.  */
!   write_register (HARD_D_REGNUM, addr + stack_correction);
  }
  
  static void
*************** m68hc11_push_return_address (CORE_ADDR p
*** 878,887 ****
    pc = read_register (HARD_PC_REGNUM);
    sp -= 2;
    store_unsigned_integer (valbuf, 2, pc);
!   write_memory (sp + 1, valbuf, 2);
! #if 0
!   write_register (HARD_PC_REGNUM, CALL_DUMMY_ADDRESS ());
! #endif
    return sp;
  }
  
--- 892,898 ----
    pc = read_register (HARD_PC_REGNUM);
    sp -= 2;
    store_unsigned_integer (valbuf, 2, pc);
!   write_memory (sp + stack_correction, valbuf, 2);
    return sp;
  }
  


More information about the Gdb-patches mailing list