|
|
|
@ -66,70 +66,104 @@ vax_register_type (struct gdbarch *gdbarch, int regnum) |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
static void |
|
|
|
vax_push_dummy_frame (void) |
|
|
|
static CORE_ADDR |
|
|
|
vax_store_arguments (struct regcache *regcache, int nargs, |
|
|
|
struct value **args, CORE_ADDR sp, |
|
|
|
int struct_return, CORE_ADDR struct_addr) |
|
|
|
{ |
|
|
|
CORE_ADDR sp = read_register (SP_REGNUM); |
|
|
|
int regnum; |
|
|
|
char buf[4]; |
|
|
|
int count = 0; |
|
|
|
int i; |
|
|
|
|
|
|
|
sp = push_word (sp, 0); /* arglist */ |
|
|
|
for (regnum = 11; regnum >= 0; regnum--) |
|
|
|
sp = push_word (sp, read_register (regnum)); |
|
|
|
sp = push_word (sp, read_register (PC_REGNUM)); |
|
|
|
sp = push_word (sp, read_register (VAX_FP_REGNUM)); |
|
|
|
sp = push_word (sp, read_register (VAX_AP_REGNUM)); |
|
|
|
sp = push_word (sp, (read_register (PS_REGNUM) & 0xffef) + 0x2fff0000); |
|
|
|
sp = push_word (sp, 0); |
|
|
|
write_register (SP_REGNUM, sp); |
|
|
|
write_register (VAX_FP_REGNUM, sp); |
|
|
|
write_register (VAX_AP_REGNUM, sp + (17 * 4)); |
|
|
|
} |
|
|
|
/* We create an argument list on the stack, and make the argument
|
|
|
|
pointer to it. */ |
|
|
|
|
|
|
|
static void |
|
|
|
vax_pop_frame (void) |
|
|
|
{ |
|
|
|
CORE_ADDR fp = read_register (VAX_FP_REGNUM); |
|
|
|
int regnum; |
|
|
|
int regmask = read_memory_integer (fp + 4, 4); |
|
|
|
|
|
|
|
write_register (PS_REGNUM, |
|
|
|
(regmask & 0xffff) |
|
|
|
| (read_register (PS_REGNUM) & 0xffff0000)); |
|
|
|
write_register (PC_REGNUM, read_memory_integer (fp + 16, 4)); |
|
|
|
write_register (VAX_FP_REGNUM, read_memory_integer (fp + 12, 4)); |
|
|
|
write_register (VAX_AP_REGNUM, read_memory_integer (fp + 8, 4)); |
|
|
|
fp += 16; |
|
|
|
for (regnum = 0; regnum < 12; regnum++) |
|
|
|
if (regmask & (0x10000 << regnum)) |
|
|
|
write_register (regnum, read_memory_integer (fp += 4, 4)); |
|
|
|
fp = fp + 4 + ((regmask >> 30) & 3); |
|
|
|
if (regmask & 0x20000000) |
|
|
|
/* Push arguments in reverse order. */ |
|
|
|
for (i = nargs - 1; i >= 0; i--) |
|
|
|
{ |
|
|
|
regnum = read_memory_integer (fp, 4); |
|
|
|
fp += (regnum + 1) * 4; |
|
|
|
int len = TYPE_LENGTH (VALUE_ENCLOSING_TYPE (args[i])); |
|
|
|
|
|
|
|
sp -= (len + 3) & ~3; |
|
|
|
count += (len + 3) / 4; |
|
|
|
write_memory (sp, VALUE_CONTENTS_ALL (args[i]), len); |
|
|
|
} |
|
|
|
write_register (SP_REGNUM, fp); |
|
|
|
flush_cached_frames (); |
|
|
|
} |
|
|
|
|
|
|
|
/* The VAX call dummy sequence:
|
|
|
|
/* Push value address. */ |
|
|
|
if (struct_return) |
|
|
|
{ |
|
|
|
sp -= 4; |
|
|
|
count++; |
|
|
|
store_unsigned_integer (buf, 4, struct_addr); |
|
|
|
write_memory (sp, buf, 4); |
|
|
|
} |
|
|
|
|
|
|
|
calls #69, @#32323232 |
|
|
|
bpt |
|
|
|
/* Push argument count. */ |
|
|
|
sp -= 4; |
|
|
|
store_unsigned_integer (buf, 4, count); |
|
|
|
write_memory (sp, buf, 4); |
|
|
|
|
|
|
|
It is 8 bytes long. The address and argc are patched by |
|
|
|
vax_fix_call_dummy(). */ |
|
|
|
static LONGEST vax_call_dummy_words[] = { 0x329f69fb, 0x03323232 }; |
|
|
|
static int sizeof_vax_call_dummy_words = sizeof(vax_call_dummy_words); |
|
|
|
/* Update the argument pointer. */ |
|
|
|
store_unsigned_integer (buf, 4, sp); |
|
|
|
regcache_cooked_write (regcache, VAX_AP_REGNUM, buf); |
|
|
|
|
|
|
|
static void |
|
|
|
vax_fix_call_dummy (char *dummy, CORE_ADDR pc, CORE_ADDR fun, int nargs, |
|
|
|
struct value **args, struct type *type, int gcc_p) |
|
|
|
return sp; |
|
|
|
} |
|
|
|
|
|
|
|
static CORE_ADDR |
|
|
|
vax_push_dummy_call (struct gdbarch *gdbarch, CORE_ADDR func_addr, |
|
|
|
struct regcache *regcache, CORE_ADDR bp_addr, int nargs, |
|
|
|
struct value **args, CORE_ADDR sp, int struct_return, |
|
|
|
CORE_ADDR struct_addr) |
|
|
|
{ |
|
|
|
CORE_ADDR fp = sp; |
|
|
|
char buf[4]; |
|
|
|
|
|
|
|
/* Set up the function arguments. */ |
|
|
|
sp = vax_store_arguments (regcache, nargs, args, sp, |
|
|
|
struct_return, struct_addr); |
|
|
|
|
|
|
|
/* Store return address in the PC slot. */ |
|
|
|
sp -= 4; |
|
|
|
store_unsigned_integer (buf, 4, bp_addr); |
|
|
|
write_memory (sp, buf, 4); |
|
|
|
|
|
|
|
/* Store the (fake) frame pointer in the FP slot. */ |
|
|
|
sp -= 4; |
|
|
|
store_unsigned_integer (buf, 4, fp); |
|
|
|
write_memory (sp, buf, 4); |
|
|
|
|
|
|
|
/* Skip the AP slot. */ |
|
|
|
sp -= 4; |
|
|
|
|
|
|
|
/* Store register save mask and control bits. */ |
|
|
|
sp -= 4; |
|
|
|
store_unsigned_integer (buf, 4, 0); |
|
|
|
write_memory (sp, buf, 4); |
|
|
|
|
|
|
|
/* Store condition handler. */ |
|
|
|
sp -= 4; |
|
|
|
store_unsigned_integer (buf, 4, 0); |
|
|
|
write_memory (sp, buf, 4); |
|
|
|
|
|
|
|
/* Update the stack pointer and frame pointer. */ |
|
|
|
store_unsigned_integer (buf, 4, sp); |
|
|
|
regcache_cooked_write (regcache, VAX_SP_REGNUM, buf); |
|
|
|
regcache_cooked_write (regcache, VAX_FP_REGNUM, buf); |
|
|
|
|
|
|
|
/* Return the saved (fake) frame pointer. */ |
|
|
|
return fp; |
|
|
|
} |
|
|
|
|
|
|
|
static struct frame_id |
|
|
|
vax_unwind_dummy_id (struct gdbarch *gdbarch, struct frame_info *next_frame) |
|
|
|
{ |
|
|
|
dummy[1] = nargs; |
|
|
|
store_unsigned_integer (dummy + 3, 4, fun); |
|
|
|
CORE_ADDR fp; |
|
|
|
|
|
|
|
fp = frame_unwind_register_unsigned (next_frame, VAX_FP_REGNUM); |
|
|
|
return frame_id_build (fp, frame_pc_unwind (next_frame)); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
static void |
|
|
|
vax_store_struct_return (CORE_ADDR addr, CORE_ADDR sp) |
|
|
|
{ |
|
|
|
@ -396,16 +430,9 @@ vax_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) |
|
|
|
set_gdbarch_deprecated_extract_return_value (gdbarch, vax_extract_return_value); |
|
|
|
set_gdbarch_deprecated_store_return_value (gdbarch, vax_store_return_value); |
|
|
|
|
|
|
|
/* Call dummy info */ |
|
|
|
set_gdbarch_deprecated_push_dummy_frame (gdbarch, vax_push_dummy_frame); |
|
|
|
set_gdbarch_deprecated_pop_frame (gdbarch, vax_pop_frame); |
|
|
|
set_gdbarch_call_dummy_location (gdbarch, ON_STACK); |
|
|
|
set_gdbarch_deprecated_call_dummy_words (gdbarch, vax_call_dummy_words); |
|
|
|
set_gdbarch_deprecated_sizeof_call_dummy_words (gdbarch, sizeof_vax_call_dummy_words); |
|
|
|
set_gdbarch_deprecated_fix_call_dummy (gdbarch, vax_fix_call_dummy); |
|
|
|
set_gdbarch_deprecated_call_dummy_breakpoint_offset (gdbarch, 7); |
|
|
|
set_gdbarch_deprecated_use_generic_dummy_frames (gdbarch, 0); |
|
|
|
set_gdbarch_deprecated_pc_in_call_dummy (gdbarch, deprecated_pc_in_call_dummy_on_stack); |
|
|
|
/* Call dummy code. */ |
|
|
|
set_gdbarch_push_dummy_call (gdbarch, vax_push_dummy_call); |
|
|
|
set_gdbarch_unwind_dummy_id (gdbarch, vax_unwind_dummy_id); |
|
|
|
|
|
|
|
/* Breakpoint info */ |
|
|
|
set_gdbarch_breakpoint_from_pc (gdbarch, vax_breakpoint_from_pc); |
|
|
|
@ -414,9 +441,6 @@ vax_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) |
|
|
|
set_gdbarch_function_start_offset (gdbarch, 2); |
|
|
|
set_gdbarch_believe_pcc_promotion (gdbarch, 1); |
|
|
|
|
|
|
|
/* Should be using push_dummy_call. */ |
|
|
|
set_gdbarch_deprecated_dummy_write_sp (gdbarch, deprecated_write_sp); |
|
|
|
|
|
|
|
set_gdbarch_unwind_pc (gdbarch, vax_unwind_pc); |
|
|
|
|
|
|
|
frame_base_set_default (gdbarch, &vax_frame_base); |
|
|
|
|