diff options
-rw-r--r-- | gdb/ChangeLog | 7 | ||||
-rw-r--r-- | gdb/amd64-tdep.c | 32 | ||||
-rw-r--r-- | gdb/i386-tdep.c | 21 |
3 files changed, 47 insertions, 13 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 31a9b70..ce3f532 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,5 +1,12 @@ 2008-04-25 Pedro Alves <pedro@codesourcery.com> + * amd64-tdep.c (amd64_get_longjmp_target): New. + (amd64_init_abi): Register amd64_get_longjmp_target as + gdbarch_get_longjmp_target callback. + * i386-tdep.c (i386_get_longjmp_target): Remove 64-bit handling. + +2008-04-25 Pedro Alves <pedro@codesourcery.com> + * breakpoint.h (enum bpstat_what_main_action): Delete BPSTAT_WHAT_CLEAR_LONGJMP_RESUME_SINGLE. diff --git a/gdb/amd64-tdep.c b/gdb/amd64-tdep.c index a9a29b3..33338b6 100644 --- a/gdb/amd64-tdep.c +++ b/gdb/amd64-tdep.c @@ -1101,6 +1101,36 @@ amd64_regset_from_core_section (struct gdbarch *gdbarch, } +/* Figure out where the longjmp will land. Slurp the jmp_buf out of + %rdi. We expect its value to be a pointer to the jmp_buf structure + from which we extract the address that we will land at. This + address is copied into PC. This routine returns non-zero on + success. */ + +static int +amd64_get_longjmp_target (struct frame_info *frame, CORE_ADDR *pc) +{ + gdb_byte buf[8]; + CORE_ADDR jb_addr; + struct gdbarch *gdbarch = get_frame_arch (frame); + int jb_pc_offset = gdbarch_tdep (gdbarch)->jb_pc_offset; + int len = TYPE_LENGTH (builtin_type_void_func_ptr); + + /* If JB_PC_OFFSET is -1, we have no way to find out where the + longjmp will land. */ + if (jb_pc_offset == -1) + return 0; + + get_frame_register (frame, AMD64_RDI_REGNUM, buf); + jb_addr = extract_typed_address (buf, builtin_type_void_data_ptr); + if (target_read_memory (jb_addr + jb_pc_offset, buf, len)) + return 0; + + *pc = extract_typed_address (buf, builtin_type_void_func_ptr); + + return 1; +} + void amd64_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) { @@ -1174,6 +1204,8 @@ amd64_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) if (tdep->gregset_reg_offset) set_gdbarch_regset_from_core_section (gdbarch, amd64_regset_from_core_section); + + set_gdbarch_get_longjmp_target (gdbarch, amd64_get_longjmp_target); } diff --git a/gdb/i386-tdep.c b/gdb/i386-tdep.c index ee7ed51..765f1ca 100644 --- a/gdb/i386-tdep.c +++ b/gdb/i386-tdep.c @@ -1295,36 +1295,31 @@ i386_unwind_dummy_id (struct gdbarch *gdbarch, struct frame_info *next_frame) stack. We expect the first arg to be a pointer to the jmp_buf structure from which we extract the address that we will land at. This address is copied into PC. This routine returns non-zero on - success. - - This function is 64-bit safe. */ + success. */ static int i386_get_longjmp_target (struct frame_info *frame, CORE_ADDR *pc) { - gdb_byte buf[8]; + gdb_byte buf[4]; CORE_ADDR sp, jb_addr; struct gdbarch *gdbarch = get_frame_arch (frame); int jb_pc_offset = gdbarch_tdep (gdbarch)->jb_pc_offset; - int len = TYPE_LENGTH (builtin_type_void_func_ptr); /* If JB_PC_OFFSET is -1, we have no way to find out where the longjmp will land. */ if (jb_pc_offset == -1) return 0; - /* Don't use I386_ESP_REGNUM here, since this function is also used - for AMD64. */ - get_frame_register (frame, gdbarch_sp_regnum (gdbarch), buf); - sp = extract_typed_address (buf, builtin_type_void_data_ptr); - if (target_read_memory (sp + len, buf, len)) + get_frame_register (frame, I386_ESP_REGNUM, buf); + sp = extract_unsigned_integer (buf, 4); + if (target_read_memory (sp + 4, buf, 4)) return 0; - jb_addr = extract_typed_address (buf, builtin_type_void_data_ptr); - if (target_read_memory (jb_addr + jb_pc_offset, buf, len)) + jb_addr = extract_unsigned_integer (buf, 4); + if (target_read_memory (jb_addr + jb_pc_offset, buf, 4)) return 0; - *pc = extract_typed_address (buf, builtin_type_void_func_ptr); + *pc = extract_unsigned_integer (buf, 4); return 1; } |