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]

[PATCH]: Fix gdb calling a function for 68hc11



Hi!

I've committed the following patch to solve problems related to gdb calling
a function on 68hc11 target (detected using the gdb testsuite):

 - Return values were not correct for some types ( > 2 bytes or union/struct)
 - Alignment and padding of arguments and struct return on the stack was not
   correct if sizeof(type) was not a multiple of 2.
 - We must use the entry point address for a correct management of the frame
   (poping a frame fails otherwise).

	Stephane

2000-09-06  Stephane Carrez  <Stephane.Carrez@worldnet.fr>

	* m68hc11-tdep.c (m68hc11_store_return_value): Store the value
	in D and X if it's larger than 16-bits.
	(m68hc11_extract_return_value): Fix extractions for 1 and 3 bytes
	return.
	(m68hc11_push_return_address): Use CALL_DUMMY_ADDRESS for the
	return address.
	(m68hc11_use_struct_convention): Check for struct and union.
	(m68hc11_return_value_on_stack): Use the struct convention.
	(m68hc11_call_dummy_address): Use the entry point address.
	(m68hc11_push_arguments): Fix alignment and padding.
	(m68hc11_stack_align): New function.
	(m68hc11_gdbarch_init): Register it.
Index: m68hc11-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/m68hc11-tdep.c,v
retrieving revision 1.5
diff -p -r1.5 m68hc11-tdep.c
*** m68hc11-tdep.c	2000/09/05 20:57:25	1.5
--- m68hc11-tdep.c	2000/09/06 19:36:20
*************** show_regs (char *args, int from_tty)
*** 750,755 ****
--- 750,761 ----
  }
  
  static CORE_ADDR
+ m68hc11_stack_align (CORE_ADDR addr)
+ {
+   return ((addr + 1) & -2);
+ }
+ 
+ static CORE_ADDR
  m68hc11_push_arguments (int nargs,
                          value_ptr *args,
                          CORE_ADDR sp,
*************** m68hc11_push_arguments (int nargs,
*** 794,800 ****
    for (argnum = first_stack_argnum; argnum < nargs; argnum++)
      {
        type = VALUE_TYPE (args[argnum]);
!       stack_alloc += (TYPE_LENGTH (type) + 1) & ~2;
      }
    sp -= stack_alloc;
  
--- 800,806 ----
    for (argnum = first_stack_argnum; argnum < nargs; argnum++)
      {
        type = VALUE_TYPE (args[argnum]);
!       stack_alloc += (TYPE_LENGTH (type) + 1) & -2;
      }
    sp -= stack_alloc;
  
*************** m68hc11_push_arguments (int nargs,
*** 807,812 ****
--- 813,825 ----
        val = (char*) VALUE_CONTENTS (args[argnum]);
        write_memory (sp + stack_offset, val, len);
        stack_offset += len;
+       if (len & 1)
+         {
+           static char zero = 0;
+ 
+           write_memory (sp + stack_offset, &zero, 1);
+           stack_offset++;
+         }
      }
    return sp;
  }
*************** m68hc11_push_arguments (int nargs,
*** 817,823 ****
  CORE_ADDR
  m68hc11_call_dummy_address (void)
  {
!   return (CORE_ADDR) read_register (HARD_PC_REGNUM);
  }
  
  static struct type *
--- 830,836 ----
  CORE_ADDR
  m68hc11_call_dummy_address (void)
  {
!   return entry_point_address ();
  }
  
  static struct type *
*************** m68hc11_store_struct_return (CORE_ADDR a
*** 838,845 ****
  static void
  m68hc11_store_return_value (struct type *type, char *valbuf)
  {
!   write_register_bytes (REGISTER_BYTE (HARD_D_REGNUM),
!                         valbuf, TYPE_LENGTH (type));
  }
  
  
--- 851,874 ----
  static void
  m68hc11_store_return_value (struct type *type, char *valbuf)
  {
!   int len;
! 
!   len = TYPE_LENGTH (type);
! 
!   /* First argument is passed in D and X registers.  */
!   if (len <= 4)
!     {
!       LONGEST v = extract_unsigned_integer (valbuf, len);
! 
!       write_register (HARD_D_REGNUM, v);
!       if (len > 2)
!         {
!           v >>= 16;
!           write_register (HARD_X_REGNUM, v);
!         }
!     }
!   else
!     error ("return of value > 4 is not supported.");
  }
  
  
*************** m68hc11_extract_return_value (struct typ
*** 853,868 ****
  {
    int len = TYPE_LENGTH (type);
    
!   if (len <= 2)
!     {
!       memcpy (valbuf, &regbuf[2], len);
!     }
!   else if (len <= 4)
!     {
!       memcpy (valbuf, regbuf, len);
!     }
!   else
      {
        error ("bad size for return value");
      }
  }
--- 882,908 ----
  {
    int len = TYPE_LENGTH (type);
    
!   switch (len)
      {
+     case 1:
+       memcpy (valbuf, &regbuf[HARD_D_REGNUM * 2 + 1], len);
+       break;
+   
+     case 2:
+       memcpy (valbuf, &regbuf[HARD_D_REGNUM * 2], len);
+       break;
+       
+     case 3:
+       memcpy (&valbuf[0], &regbuf[HARD_X_REGNUM * 2 + 1], 1);
+       memcpy (&valbuf[1], &regbuf[HARD_D_REGNUM * 2], 2);
+       break;
+       
+     case 4:
+       memcpy (&valbuf[0], &regbuf[HARD_X_REGNUM * 2], 2);
+       memcpy (&valbuf[2], &regbuf[HARD_D_REGNUM * 2], 2);
+       break;
+ 
+     default:
        error ("bad size for return value");
      }
  }
*************** m68hc11_extract_return_value (struct typ
*** 871,883 ****
  static int
  m68hc11_use_struct_convention (int gcc_p, struct type *type)
  {
!   return (TYPE_LENGTH (type) > 4);
  }
  
  static int
  m68hc11_return_value_on_stack (struct type *type)
  {
!   return m68hc11_use_struct_convention (1, type);
  }
  
  /* Extract from an array REGBUF containing the (raw) register state
--- 911,925 ----
  static int
  m68hc11_use_struct_convention (int gcc_p, struct type *type)
  {
!   return (TYPE_CODE (type) == TYPE_CODE_STRUCT
!           || TYPE_CODE (type) == TYPE_CODE_UNION
!           || TYPE_LENGTH (type) > 4);
  }
  
  static int
  m68hc11_return_value_on_stack (struct type *type)
  {
!   return TYPE_LENGTH (type) > 4;
  }
  
  /* Extract from an array REGBUF containing the (raw) register state
*************** m68hc11_push_return_address (CORE_ADDR p
*** 899,905 ****
  {
    char valbuf[2];
    
!   pc = read_register (HARD_PC_REGNUM);
    sp -= 2;
    store_unsigned_integer (valbuf, 2, pc);
    write_memory (sp + stack_correction, valbuf, 2);
--- 941,947 ----
  {
    char valbuf[2];
    
!   pc = CALL_DUMMY_ADDRESS ();
    sp -= 2;
    store_unsigned_integer (valbuf, 2, pc);
    write_memory (sp + stack_correction, valbuf, 2);
*************** m68hc11_gdbarch_init (struct gdbarch_inf
*** 1042,1047 ****
--- 1084,1090 ----
    set_gdbarch_decr_pc_after_break (gdbarch, 0);
    set_gdbarch_function_start_offset (gdbarch, 0);
    set_gdbarch_breakpoint_from_pc (gdbarch, m68hc11_breakpoint_from_pc);
+   set_gdbarch_stack_align (gdbarch, m68hc11_stack_align);
  
    set_gdbarch_believe_pcc_promotion (gdbarch, 1);
    set_gdbarch_ieee_float (gdbarch, 1);

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