This is the mail archive of the
gdb-patches@sources.redhat.com
mailing list for the GDB project.
[PATCH]: Fix gdb calling a function for 68hc11
- To: gdb-patches at sourceware dot cygnus dot com
- Subject: [PATCH]: Fix gdb calling a function for 68hc11
- From: Stephane Carrez <Stephane dot Carrez at worldnet dot fr>
- Date: Wed, 06 Sep 2000 23:44:09 +0200
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, ®buf[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, ®buf[HARD_D_REGNUM * 2 + 1], len);
+ break;
+
+ case 2:
+ memcpy (valbuf, ®buf[HARD_D_REGNUM * 2], len);
+ break;
+
+ case 3:
+ memcpy (&valbuf[0], ®buf[HARD_X_REGNUM * 2 + 1], 1);
+ memcpy (&valbuf[1], ®buf[HARD_D_REGNUM * 2], 2);
+ break;
+
+ case 4:
+ memcpy (&valbuf[0], ®buf[HARD_X_REGNUM * 2], 2);
+ memcpy (&valbuf[2], ®buf[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);