diff options
author | Mark Kettenis <kettenis@gnu.org> | 2003-05-30 19:24:30 +0000 |
---|---|---|
committer | Mark Kettenis <kettenis@gnu.org> | 2003-05-30 19:24:30 +0000 |
commit | acd5c79833ffd87197b87fd5afa8c6f4de0bed13 (patch) | |
tree | f37bb66a92d8952b04966cda364480f96d6b5bd4 /gdb/i386-linux-tdep.c | |
parent | c9c27aad5461fcb1189ce1c8d7cf18c29e7346a2 (diff) | |
download | gdb-acd5c79833ffd87197b87fd5afa8c6f4de0bed13.zip gdb-acd5c79833ffd87197b87fd5afa8c6f4de0bed13.tar.gz gdb-acd5c79833ffd87197b87fd5afa8c6f4de0bed13.tar.bz2 |
* i386-tdep.h (i386bsd_sigcontext_addr): Remove prototype.
(I386_SIZEOF_GREGS, I386_SIZEOF_FREGS, I386_SIZEOF_XREGS): Remove
defenitions.
(IS_FP_REGNUM, IS_SSE_REGNUM): Remove definitions.
* i386-tdep.c: Mark functions that are 64-bit safe as such.
(I386_EAX_REGNUM, I386_EDX_REGNUM, I386_ESP_REGNUM,
I386_EBP_REGNUM, I386_EIP_REGNUM, I386_EFLAGS_REGNUM,
I386_ST0_REGNUM): New defines.
(CODESTREAM_BUFSIZ, codestream_tell, codestream_peek,
codestream_get): Remove define.
(codestream_next_addr, condestream_addr, condestream_buf,
codestream_off, codestream_cnt): Remove variables.
(codestream_fill, codestream_seek, codestream_read): Remove
functions.
(i386_follow_jump): Rewrite to avoid usage of removed codestream
functionality.
(i386_get_frame_setup, i386_frameless_signal_p, i386_frame_chain,
i386_sigtramp_saved_pc, i386_sigtramp_saved_sp,
i386_frame_saved_pc, i386_saved_pc_after_call,
i386_frame_num_args, i386_frame_init_saved_regs,
i386_push_return_address, i386_do_pop_frame, i386_pop_frame,
i386_push_arguments): Remove functions.
(i386_skip_prologue): Rewrite to avoid usage of removed codestream
functionality. Use i386_analyze_prologue instead of
i386_get_frame_setup.
(I386_NUM_SAVED_REGS): New define.
(struct i386_frame_cache): New structure.
(i386_alloc_frame_cache, i386_analyze_struct_return,
i386_skip_probe, i386_analyze_frame_setup,
i386_analyze_register_saves, i386_analyze_prologue,
i386_unwind_pc, i386_frame_cache, i386_frame_this_id,
i386_frame_prev_register, i386_sigtramp_frame_cache,
i386_sigtramp_frame_this_id, i386_sigtramp_frame_prev_register,
i386_frame_p, i386_sigtramp_frame_p, i386_frame_base_address,
i386_unwind_dummy_id, i386_save_dummy_tos, i386_push_dummy_call):
New functions.
(i386_frame_unwind, i386_sigtramp_frame_unwind, i386_frame_base):
New variables.
(LOW_RETURN_REGNUM, HIGH_RETURN_REGNUM): Define in terms of
I386_EAX_REGNUM and I386_EDX_REGNUM.
(i386_extract_return_value, i386_store_return_value): Use
I386_ST0_REGNUM where appropriate.
(i386_extract_struct_value_address): Rewrite to use extract_address.
(i386_svr4_pc_in_sigtramp): Add comment.
(i386_svr4_sigcontext_addr): Rewrite.
(i386_svr4_init_abi): Adjust TDEP->sc_pc_offset and
TDEP->sc_sp_offset.
(i386_gdbarch_init): Don't set deprecated_init_frame_pc. Set
sp_regnum, fp_regnum, pc_regnum, ps_regnum and fp0_regnum in terms
of new defines. Set push_dummy_call, don't set
deprecated_push_arguments, deprecated_push_return_address,
deprecated_pop_frame. Don't set parm_boundary. Don't set
deprecated_frame_chain, deprecated_frame_saved_pc,
deprecated_saved_pc_after_call. Set unwind_dummy_id,
save_dummy_frame_tos, unwind_pc. Call
frame_unwind_append_predicate and frame_base_set_default. Don't
set deprecated_dummy_write_pc. Don't set deprecated_fp_regnum.
Don't set frameless_function_invocation. Don't set
deprecated_register_bytes, deprecated_register_size,
deprecated_call_dummy_words and deprecated_sizeof_call_dummy.
* i386-linux-tdep.c: Fix formatting in some comments.
(LINUX_SIGTRAMP_INSN0, LINUX_SIGTRAMP_OFFSET0,
LINUX_SIGTRAMP_INSN1, LINUX_SIGTRAMP_OFFSET1,
LINUX_SIGTRAMP_INSN2, LINUX_SIGTRAMP_OFFSET2,
LINUX_RT_SIGTRAMP_INSN0, LINUX_RT_SIGTRAMP_OFFSET0,
LINUX_RT_SIGTRAMP_INSN1, LINUX_RT_SIGTRAMP_OFFSET1): Drop
redundant parentheses.
(I386_LINUX_UCONTEXT_SIGCONTEXT_OFFSET): New define.
(i386_linux_sigcontext_addr): Use it. Rewrite.
(find_minsym_and_objfile): Change name of second argument.
(skip_gnu_resolver): Renamed from skip_hurd_resolver. All callers
changed. Use frame_pc_unwind instead of
DEPRECATED_SAVED_PC_AFTER_CALL.
(i386_linux_init_abi): Don't set deprecated_register_bytes.
* i386bsd-tdep.c (i386bsd_sigcontext_addr): Rewrite.
* i386-nto-tdep.c (i386nto_sigcontext_addr): Adapt for new frame
unwinder.
* i386-cygwin-tdep.c: Don't include "gdbcore.h", "frame.h" and
"dummy-frame.h".
(i386_cygwin_frame_chain_valid, i386_cygwin_frame_chain): Removed.
(_initialize_i386_cygwin_tdep): New prototype.
(i386_cygwin_init_abi): Don't set deprecated_frame_chain and
deprecated_frame_chain_valid.
* i386-sol2-tdep.c (i386_sol2_init_abi): Don't set
TDEP->sigcontext_addr, TDEP->sc_pc_offset and TDEP->sc_sp_offset.
Rely on the SVR4 defaults.
* config/i386/i386sol2.mt (TDEPFILES): Remove i386bsd-tdep.o.
* Makefile.in (i386-tdep.o, i386-cygwin-tdep.o): Update dependencies.
Diffstat (limited to 'gdb/i386-linux-tdep.c')
-rw-r--r-- | gdb/i386-linux-tdep.c | 100 |
1 files changed, 48 insertions, 52 deletions
diff --git a/gdb/i386-linux-tdep.c b/gdb/i386-linux-tdep.c index afff548..e666610 100644 --- a/gdb/i386-linux-tdep.c +++ b/gdb/i386-linux-tdep.c @@ -81,7 +81,7 @@ i386_linux_register_reggroup_p (struct gdbarch *gdbarch, int regnum, The instruction sequence for normal signals is pop %eax - mov $0x77,%eax + mov $0x77, %eax int $0x80 or 0x58 0xb8 0x77 0x00 0x00 0x00 0xcd 0x80. @@ -103,17 +103,17 @@ i386_linux_register_reggroup_p (struct gdbarch *gdbarch, int regnum, to the ones used by the kernel. Therefore, these trampolines are supported too. */ -#define LINUX_SIGTRAMP_INSN0 (0x58) /* pop %eax */ -#define LINUX_SIGTRAMP_OFFSET0 (0) -#define LINUX_SIGTRAMP_INSN1 (0xb8) /* mov $NNNN,%eax */ -#define LINUX_SIGTRAMP_OFFSET1 (1) -#define LINUX_SIGTRAMP_INSN2 (0xcd) /* int */ -#define LINUX_SIGTRAMP_OFFSET2 (6) +#define LINUX_SIGTRAMP_INSN0 0x58 /* pop %eax */ +#define LINUX_SIGTRAMP_OFFSET0 0 +#define LINUX_SIGTRAMP_INSN1 0xb8 /* mov $NNNN, %eax */ +#define LINUX_SIGTRAMP_OFFSET1 1 +#define LINUX_SIGTRAMP_INSN2 0xcd /* int */ +#define LINUX_SIGTRAMP_OFFSET2 6 static const unsigned char linux_sigtramp_code[] = { LINUX_SIGTRAMP_INSN0, /* pop %eax */ - LINUX_SIGTRAMP_INSN1, 0x77, 0x00, 0x00, 0x00, /* mov $0x77,%eax */ + LINUX_SIGTRAMP_INSN1, 0x77, 0x00, 0x00, 0x00, /* mov $0x77, %eax */ LINUX_SIGTRAMP_INSN2, 0x80 /* int $0x80 */ }; @@ -167,20 +167,20 @@ i386_linux_sigtramp_start (CORE_ADDR pc) /* This function does the same for RT signals. Here the instruction sequence is - mov $0xad,%eax + mov $0xad, %eax int $0x80 or 0xb8 0xad 0x00 0x00 0x00 0xcd 0x80. The effect is to call the system call rt_sigreturn. */ -#define LINUX_RT_SIGTRAMP_INSN0 (0xb8) /* mov $NNNN,%eax */ -#define LINUX_RT_SIGTRAMP_OFFSET0 (0) -#define LINUX_RT_SIGTRAMP_INSN1 (0xcd) /* int */ -#define LINUX_RT_SIGTRAMP_OFFSET1 (5) +#define LINUX_RT_SIGTRAMP_INSN0 0xb8 /* mov $NNNN, %eax */ +#define LINUX_RT_SIGTRAMP_OFFSET0 0 +#define LINUX_RT_SIGTRAMP_INSN1 0xcd /* int */ +#define LINUX_RT_SIGTRAMP_OFFSET1 5 static const unsigned char linux_rt_sigtramp_code[] = { - LINUX_RT_SIGTRAMP_INSN0, 0xad, 0x00, 0x00, 0x00, /* mov $0xad,%eax */ + LINUX_RT_SIGTRAMP_INSN0, 0xad, 0x00, 0x00, 0x00, /* mov $0xad, %eax */ LINUX_RT_SIGTRAMP_INSN1, 0x80 /* int $0x80 */ }; @@ -239,50 +239,47 @@ i386_linux_pc_in_sigtramp (CORE_ADDR pc, char *name) || strcmp ("__restore_rt", name) == 0); } -/* Assuming FRAME is for a GNU/Linux sigtramp routine, return the - address of the associated sigcontext structure. */ +/* Offset to struct sigcontext in ucontext, from <asm/ucontext.h>. */ +#define I386_LINUX_UCONTEXT_SIGCONTEXT_OFFSET 20 + +/* Assuming NEXT_FRAME is a frame following a GNU/Linux sigtramp + routine, return the address of the associated sigcontext structure. */ static CORE_ADDR -i386_linux_sigcontext_addr (struct frame_info *frame) +i386_linux_sigcontext_addr (struct frame_info *next_frame) { CORE_ADDR pc; + CORE_ADDR sp; + char buf[4]; + + frame_unwind_register (next_frame, SP_REGNUM, buf); + sp = extract_unsigned_integer (buf, 4); - pc = i386_linux_sigtramp_start (get_frame_pc (frame)); + pc = i386_linux_sigtramp_start (frame_pc_unwind (next_frame)); if (pc) { - CORE_ADDR sp; - - if (get_next_frame (frame)) - /* If this isn't the top frame, the next frame must be for the - signal handler itself. The sigcontext structure lives on - the stack, right after the signum argument. */ - return get_frame_base (get_next_frame (frame)) + 12; - - /* This is the top frame. We'll have to find the address of the - sigcontext structure by looking at the stack pointer. Keep - in mind that the first instruction of the sigtramp code is - "pop %eax". If the PC is at this instruction, adjust the - returned value accordingly. */ - sp = read_register (SP_REGNUM); - if (pc == get_frame_pc (frame)) + /* The sigcontext structure lives on the stack, right after + the signum argument. We determine the address of the + sigcontext structure by looking at the frame's stack + pointer. Keep in mind that the first instruction of the + sigtramp code is "pop %eax". If the PC is after this + instruction, adjust the returned value accordingly. */ + if (pc == frame_pc_unwind (next_frame)) return sp + 4; return sp; } - pc = i386_linux_rt_sigtramp_start (get_frame_pc (frame)); + pc = i386_linux_rt_sigtramp_start (frame_pc_unwind (next_frame)); if (pc) { - if (get_next_frame (frame)) - /* If this isn't the top frame, the next frame must be for the - signal handler itself. The sigcontext structure is part of - the user context. A pointer to the user context is passed - as the third argument to the signal handler. */ - return read_memory_integer (get_frame_base (get_next_frame (frame)) - + 16, 4) + 20; - - /* This is the top frame. Again, use the stack pointer to find - the address of the sigcontext structure. */ - return read_memory_integer (read_register (SP_REGNUM) + 8, 4) + 20; + CORE_ADDR ucontext_addr; + + /* The sigcontext structure is part of the user context. A + pointer to the user context is passed as the third argument + to the signal handler. */ + read_memory (sp + 8, buf, 4); + ucontext_addr = extract_unsigned_integer (buf, 4) + 20; + return ucontext_addr + I386_LINUX_UCONTEXT_SIGCONTEXT_OFFSET; } error ("Couldn't recognize signal trampoline."); @@ -322,7 +319,7 @@ i386_linux_write_pc (CORE_ADDR pc, ptid_t ptid) be considered too special-purpose for general consumption. */ static struct minimal_symbol * -find_minsym_and_objfile (char *name, struct objfile **objfile_p) +find_minsym_and_objfile (char *name, struct objfile **objfilep) { struct objfile *objfile; @@ -335,7 +332,7 @@ find_minsym_and_objfile (char *name, struct objfile **objfile_p) if (SYMBOL_LINKAGE_NAME (msym) && strcmp (SYMBOL_LINKAGE_NAME (msym), name) == 0) { - *objfile_p = objfile; + *objfilep = objfile; return msym; } } @@ -345,9 +342,9 @@ find_minsym_and_objfile (char *name, struct objfile **objfile_p) } static CORE_ADDR -skip_hurd_resolver (CORE_ADDR pc) +skip_gnu_resolver (CORE_ADDR pc) { - /* The HURD dynamic linker is part of the GNU C library, so many + /* The GNU dynamic linker is part of the GNU C library, so many GNU/Linux distributions use it. (All ELF versions, as far as I know.) An unresolved PLT entry points to "_dl_runtime_resolve", which calls "fixup" to patch the PLT, and then passes control to @@ -374,7 +371,7 @@ skip_hurd_resolver (CORE_ADDR pc) = lookup_minimal_symbol ("fixup", NULL, objfile); if (fixup && SYMBOL_VALUE_ADDRESS (fixup) == pc) - return (DEPRECATED_SAVED_PC_AFTER_CALL (get_current_frame ())); + return frame_pc_unwind (get_current_frame ()); } return 0; @@ -393,7 +390,7 @@ i386_linux_skip_solib_resolver (CORE_ADDR pc) CORE_ADDR result; /* Plug in functions for other kinds of resolvers here. */ - result = skip_hurd_resolver (pc); + result = skip_gnu_resolver (pc); if (result) return result; @@ -461,7 +458,6 @@ i386_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) set_gdbarch_num_regs (gdbarch, I386_SSE_NUM_REGS + 1); set_gdbarch_register_name (gdbarch, i386_linux_register_name); set_gdbarch_register_reggroup_p (gdbarch, i386_linux_register_reggroup_p); - set_gdbarch_deprecated_register_bytes (gdbarch, I386_SSE_SIZEOF_REGS + 4); tdep->jb_pc_offset = 20; /* From <bits/setjmp.h>. */ |