alpha_extract_struct_value_address;
static gdbarch_use_struct_convention_ftype alpha_use_struct_convention;
+static gdbarch_breakpoint_from_pc_ftype alpha_breakpoint_from_pc;
+
static gdbarch_frame_args_address_ftype alpha_frame_args_address;
static gdbarch_frame_locals_address_ftype alpha_frame_locals_address;
static gdbarch_init_frame_pc_first_ftype alpha_init_frame_pc_first;
static gdbarch_init_extra_frame_info_ftype alpha_init_extra_frame_info;
+static gdbarch_get_longjmp_target_ftype alpha_get_longjmp_target;
+
struct frame_extra_info
{
alpha_extra_func_info_t proc_desc;
}
*linked_proc_desc_table = NULL;
\f
-int
-alpha_osf_in_sigtramp (CORE_ADDR pc, char *func_name)
-{
- return (func_name != NULL && STREQ ("__sigtramp", func_name));
-}
-
static CORE_ADDR
alpha_frame_past_sigtramp_frame (struct frame_info *frame, CORE_ADDR pc)
{
}
\f
+static CORE_ADDR
+alpha_sigcontext_addr (struct frame_info *fi)
+{
+ struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
+
+ if (tdep->sigcontext_addr)
+ return (tdep->sigcontext_addr (fi));
+
+ return (0);
+}
+
/* Guaranteed to set frame->saved_regs to some values (it never leaves it
NULL). */
{
CORE_ADDR sigcontext_addr;
- sigcontext_addr = SIGCONTEXT_ADDR (frame);
+ sigcontext_addr = alpha_sigcontext_addr (frame);
+ if (sigcontext_addr == 0)
+ {
+ /* Don't know where the sigcontext is; just bail. */
+ return;
+ }
for (ireg = 0; ireg < 32; ireg++)
{
reg_position = sigcontext_addr + SIGFRAME_REGSAVE_OFF + ireg * 8;
CORE_ADDR post_prologue_pc;
char buf[4];
-#ifdef GDB_TARGET_HAS_SHARED_LIBS
/* Silently return the unaltered pc upon memory errors.
This could happen on OSF/1 if decode_line_1 tries to skip the
prologue for quickstarted shared library functions when the
shared library is not yet mapped in.
Reading target memory is slow over serial lines, so we perform
- this check only if the target has shared libraries. */
+ this check only if the target has shared libraries (which all
+ Alpha targets do). */
if (target_read_memory (pc, buf, 4))
return pc;
-#endif
/* See if we can determine the end of the prologue via the symbol table.
If so, then return either PC, or the PC after the prologue, whichever
error ("Cannot store value in floating point register");
}
+static const unsigned char *
+alpha_breakpoint_from_pc (CORE_ADDR *pcptr, int *lenptr)
+{
+ static const unsigned char alpha_breakpoint[] =
+ { 0x80, 0, 0, 0 }; /* call_pal bpt */
+
+ *lenptr = sizeof(alpha_breakpoint);
+ return (alpha_breakpoint);
+}
+
/* Given a return value in `regbuf' with a type `valtype',
extract and copy its value into `valbuf'. */
REGISTER_RAW_SIZE (ALPHA_V0_REGNUM)));
}
+/* Figure out where the longjmp will land.
+ We expect the first arg to be a pointer to the jmp_buf structure from
+ which we extract the PC (JB_PC) that we will land at. The PC is copied
+ into the "pc". This routine returns true on success. */
+
+static int
+alpha_get_longjmp_target (CORE_ADDR *pc)
+{
+ struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
+ CORE_ADDR jb_addr;
+ char raw_buffer[ALPHA_MAX_REGISTER_RAW_SIZE];
+
+ jb_addr = read_register (ALPHA_A0_REGNUM);
+
+ if (target_read_memory (jb_addr + (tdep->jb_pc * tdep->jb_elt_size),
+ raw_buffer, tdep->jb_elt_size))
+ return 0;
+
+ *pc = extract_address (raw_buffer, tdep->jb_elt_size);
+ return 1;
+}
+
/* alpha_software_single_step() is called just before we want to resume
the inferior, if we want to single-step it but there is no hardware
or kernel single-step support (NetBSD on Alpha, for example). We find
tdep->dynamic_sigtramp_offset = NULL;
tdep->skip_sigtramp_frame = NULL;
+ tdep->sigcontext_addr = NULL;
+
+ tdep->jb_pc = -1; /* longjmp support not enabled by default */
/* Type sizes */
set_gdbarch_short_bit (gdbarch, 16);
set_gdbarch_coerce_float_to_double (gdbarch,
standard_coerce_float_to_double);
+ set_gdbarch_breakpoint_from_pc (gdbarch, alpha_breakpoint_from_pc);
set_gdbarch_decr_pc_after_break (gdbarch, 4);
+
+ set_gdbarch_function_start_offset (gdbarch, 0);
set_gdbarch_frame_args_skip (gdbarch, 0);
/* Hook in ABI-specific overrides, if they have been registered. */
}
}
+ /* Now that we have tuned the configuration, set a few final things
+ based on what the OS ABI has told us. */
+
+ if (tdep->jb_pc >= 0)
+ set_gdbarch_get_longjmp_target (gdbarch, alpha_get_longjmp_target);
+
return gdbarch;
}
fprintf_unfiltered (file,
"alpha_dump_tdep: vm_min_address = 0x%lx\n",
(long) tdep->vm_min_address);
+
+ fprintf_unfiltered (file,
+ "alpha_dump_tdep: jb_pc = %d\n",
+ tdep->jb_pc);
+ fprintf_unfiltered (file,
+ "alpha_dump_tdep: jb_elt_size = %ld\n",
+ (long) tdep->jb_elt_size);
}
void