aboutsummaryrefslogtreecommitdiff
path: root/gdb/alpha-tdep.c
diff options
context:
space:
mode:
authorJason Thorpe <thorpej@netbsd.org>2002-04-26 01:08:19 +0000
committerJason Thorpe <thorpej@netbsd.org>2002-04-26 01:08:19 +0000
commitaccc6d1ff368635135fb961397da748a4505008c (patch)
tree9e67a682a1462c55bb84208a36c39a7b38d9d03a /gdb/alpha-tdep.c
parentd5ba2a0169386af2ecd2e678876297ee4bee61da (diff)
downloadfsf-binutils-gdb-accc6d1ff368635135fb961397da748a4505008c.zip
fsf-binutils-gdb-accc6d1ff368635135fb961397da748a4505008c.tar.gz
fsf-binutils-gdb-accc6d1ff368635135fb961397da748a4505008c.tar.bz2
* alpha-tdep.h (gdbarch_tdep): Add jb_pc and jb_elt_size members.
* alpha-linux-tdep.c (alpha_linux_init_abi): Initialize tdep->jb_pc and tdep->jb_elt_size. * alpha-osf1-tdep.c (alpha_osf1_init_abi): Likewise. * alphafbsd-tdep.c (alphafbsd_init_abi): Likewise. * alphanbsd-tdep.c (alphanbsd_init_abi): Likewise. * alpha-nat.c (get_longjmp_target): Remove. (JB_ELEMENT_SIZE): Ditto. (JB_PC): Ditto. * alpha-tdep.c (alpha_get_longjmp_target): New function. (alpha_gdbarch_init): Default tdep->jb_pc to -1. If the OS ABI sets jb_pc to a valid value, set gdbarch_get_longjmp_target to alpha_get_longjmp_target. (alpha_dump_tdep): Report tdep->jb_pc and tdep->jb_elt_size. * config/alpha/nm-linux.h (GET_LONGJMP_TARGET): Remove. * config/alpha/nm-osf.h (GET_LONGJMP_TARGET): Remove.
Diffstat (limited to 'gdb/alpha-tdep.c')
-rw-r--r--gdb/alpha-tdep.c39
1 files changed, 39 insertions, 0 deletions
diff --git a/gdb/alpha-tdep.c b/gdb/alpha-tdep.c
index 4bec6bc..81c932c 100644
--- a/gdb/alpha-tdep.c
+++ b/gdb/alpha-tdep.c
@@ -78,6 +78,8 @@ static gdbarch_fix_call_dummy_ftype alpha_fix_call_dummy;
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;
@@ -1617,6 +1619,28 @@ alpha_extract_struct_value_address (char *regbuf)
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
@@ -1975,6 +1999,8 @@ alpha_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
tdep->dynamic_sigtramp_offset = NULL;
tdep->skip_sigtramp_frame = NULL;
+ tdep->jb_pc = -1; /* longjmp support not enabled by default */
+
/* Type sizes */
set_gdbarch_short_bit (gdbarch, 16);
set_gdbarch_int_bit (gdbarch, 32);
@@ -2113,6 +2139,12 @@ alpha_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
}
}
+ /* 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;
}
@@ -2134,6 +2166,13 @@ alpha_dump_tdep (struct gdbarch *current_gdbarch, struct ui_file *file)
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