From 3e210248bd30a25cad7598cf3acd95a9a6d933be Mon Sep 17 00:00:00 2001 From: Andrew Cagney Date: Fri, 13 Jun 2003 20:37:28 +0000 Subject: [PATCH] 2003-06-13 Andrew Cagney * infcall.c (call_function_by_hand): When UNWIND_DUMMY_ID is available, do not use the FP register, and always save the TOS. * dummy-frame.c (dummy_frame_this_id): Do not assert SAVE_DUMMY_FRAME_TOS. * i386-tdep.c (i386_save_dummy_frame_tos): Delete function. (i386_gdbarch_init): Do not set save_dummy_frame_tos. (i386_push_dummy_call): Add 8 to the returned SP. * frame.c (legacy_frame_p): Do not require SAVE_DUMMY_FRAME_TOS. * d10v-tdep.c (d10v_unwind_dummy_id): Use d10v_unwind_sp. (d10v_gdbarch_init): Do not set save_dummy_frame_tos. * x86-64-tdep.c (x86_64_save_dummy_frame_tos): Delete function. (x86_64_push_dummy_call): Return "sp + 16". (x86_64_init_abi): Do not set save_dummy_frame_tos. * alpha-tdep.c (alpha_gdbarch_init): Do not set save_dummy_frame_tos. --- gdb/ChangeLog | 18 ++++++++++++++++++ gdb/alpha-tdep.c | 1 - gdb/d10v-tdep.c | 10 +++++----- gdb/dummy-frame.c | 4 ---- gdb/frame.c | 3 +-- gdb/i386-tdep.c | 21 +++++++++++++-------- gdb/infcall.c | 42 +++++++++++++++++++++++++++++++----------- gdb/x86-64-tdep.c | 9 +-------- 8 files changed, 69 insertions(+), 39 deletions(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index cff9df4529a..50e7fbbec62 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,21 @@ +2003-06-13 Andrew Cagney + + * infcall.c (call_function_by_hand): When UNWIND_DUMMY_ID is + available, do not use the FP register, and always save the TOS. + * dummy-frame.c (dummy_frame_this_id): Do not assert + SAVE_DUMMY_FRAME_TOS. + * i386-tdep.c (i386_save_dummy_frame_tos): Delete function. + (i386_gdbarch_init): Do not set save_dummy_frame_tos. + (i386_push_dummy_call): Add 8 to the returned SP. + * frame.c (legacy_frame_p): Do not require SAVE_DUMMY_FRAME_TOS. + * d10v-tdep.c (d10v_unwind_dummy_id): Use d10v_unwind_sp. + (d10v_gdbarch_init): Do not set save_dummy_frame_tos. + * x86-64-tdep.c (x86_64_save_dummy_frame_tos): Delete function. + (x86_64_push_dummy_call): Return "sp + 16". + (x86_64_init_abi): Do not set save_dummy_frame_tos. + * alpha-tdep.c (alpha_gdbarch_init): Do not set + save_dummy_frame_tos. + 2003-06-13 Jim Blandy * frv-tdep.c (frv_use_struct_convention): Delete static diff --git a/gdb/alpha-tdep.c b/gdb/alpha-tdep.c index 64d12db65c0..d5235779bd6 100644 --- a/gdb/alpha-tdep.c +++ b/gdb/alpha-tdep.c @@ -1544,7 +1544,6 @@ alpha_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) /* Methods for saving / extracting a dummy frame's ID. */ set_gdbarch_unwind_dummy_id (gdbarch, alpha_unwind_dummy_id); - set_gdbarch_save_dummy_frame_tos (gdbarch, generic_save_dummy_frame_tos); /* Return the unwound PC value. */ set_gdbarch_unwind_pc (gdbarch, alpha_unwind_pc); diff --git a/gdb/d10v-tdep.c b/gdb/d10v-tdep.c index 62a8c30bc21..d522580c76c 100644 --- a/gdb/d10v-tdep.c +++ b/gdb/d10v-tdep.c @@ -1477,9 +1477,8 @@ static const struct frame_base d10v_frame_base = { static struct frame_id d10v_unwind_dummy_id (struct gdbarch *gdbarch, struct frame_info *next_frame) { - ULONGEST base; - frame_unwind_unsigned_register (next_frame, D10V_SP_REGNUM, &base); - return frame_id_build (d10v_make_daddr (base), frame_pc_unwind (next_frame)); + return frame_id_build (d10v_unwind_sp (gdbarch, next_frame), + frame_pc_unwind (next_frame)); } static gdbarch_init_ftype d10v_gdbarch_init; @@ -1593,9 +1592,10 @@ d10v_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) frame_unwind_append_predicate (gdbarch, d10v_frame_p); frame_base_set_default (gdbarch, &d10v_frame_base); - /* Methods for saving / extracting a dummy frame's ID. */ + /* Methods for saving / extracting a dummy frame's ID. The ID's + stack address must match the SP value returned by + PUSH_DUMMY_CALL, and saved by generic_save_dummy_frame_tos. */ set_gdbarch_unwind_dummy_id (gdbarch, d10v_unwind_dummy_id); - set_gdbarch_save_dummy_frame_tos (gdbarch, generic_save_dummy_frame_tos); /* Return the unwound PC value. */ set_gdbarch_unwind_pc (gdbarch, d10v_unwind_pc); diff --git a/gdb/dummy-frame.c b/gdb/dummy-frame.c index 94413f4baef..c395c936e70 100644 --- a/gdb/dummy-frame.c +++ b/gdb/dummy-frame.c @@ -360,10 +360,6 @@ dummy_frame_this_id (struct frame_info *next_frame, just asking for trouble. */ if (gdbarch_unwind_dummy_id_p (current_gdbarch)) { - /* Assume call_function_by_hand(), via SAVE_DUMMY_FRAME_TOS, - previously saved the dummy frame's ID. Things only work if - the two return the same value. */ - gdb_assert (SAVE_DUMMY_FRAME_TOS_P ()); /* Use an architecture specific method to extract the prev's dummy ID from the next frame. Note that this method uses frame_register_unwind to obtain the register values needed to diff --git a/gdb/frame.c b/gdb/frame.c index b1107efa8e5..18f95611b37 100644 --- a/gdb/frame.c +++ b/gdb/frame.c @@ -2288,8 +2288,7 @@ legacy_frame_p (struct gdbarch *current_gdbarch) || DEPRECATED_INIT_FRAME_PC_FIRST_P () || DEPRECATED_INIT_EXTRA_FRAME_INFO_P () || DEPRECATED_FRAME_CHAIN_P () - || !gdbarch_unwind_dummy_id_p (current_gdbarch) - || !SAVE_DUMMY_FRAME_TOS_P ()); + || !gdbarch_unwind_dummy_id_p (current_gdbarch)); } extern initialize_file_ftype _initialize_frame; /* -Wmissing-prototypes */ diff --git a/gdb/i386-tdep.c b/gdb/i386-tdep.c index 80f69e09d79..467f686a123 100644 --- a/gdb/i386-tdep.c +++ b/gdb/i386-tdep.c @@ -751,6 +751,7 @@ i386_frame_this_id (struct frame_info *next_frame, void **this_cache, if (cache->base == 0) return; + /* See the end of i386_push_dummy_call. */ (*this_id) = frame_id_build (cache->base + 8, cache->pc); } @@ -902,6 +903,7 @@ i386_sigtramp_frame_this_id (struct frame_info *next_frame, void **this_cache, struct i386_frame_cache *cache = i386_sigtramp_frame_cache (next_frame, this_cache); + /* See the end of i386_push_dummy_call. */ (*this_id) = frame_id_build (cache->base + 8, frame_pc_unwind (next_frame)); } @@ -960,12 +962,6 @@ static const struct frame_base i386_frame_base = i386_frame_base_address }; -static void -i386_save_dummy_frame_tos (CORE_ADDR sp) -{ - generic_save_dummy_frame_tos (sp + 8); -} - static struct frame_id i386_unwind_dummy_id (struct gdbarch *gdbarch, struct frame_info *next_frame) { @@ -975,6 +971,7 @@ i386_unwind_dummy_id (struct gdbarch *gdbarch, struct frame_info *next_frame) frame_unwind_register (next_frame, I386_EBP_REGNUM, buf); fp = extract_unsigned_integer (buf, 4); + /* See the end of i386_push_dummy_call. */ return frame_id_build (fp + 8, frame_pc_unwind (next_frame)); } @@ -1058,7 +1055,16 @@ i386_push_dummy_call (struct gdbarch *gdbarch, CORE_ADDR func_addr, /* ...and fake a frame pointer. */ regcache_cooked_write (regcache, I386_EBP_REGNUM, buf); - return sp; + /* MarkK wrote: This "+ 8" is all over the place: + (i386_frame_this_id, i386_sigtramp_frame_this_id, + i386_unwind_dummy_id). It's there, since all frame unwinders for + a given target have to agree (within a certain margin) on the + defenition of the stack address of a frame. Otherwise + frame_id_inner() won't work correctly. Since DWARF2/GCC uses the + stack address *before* the function call as a frame's CFA. On + the i386, when %ebp is used as a frame pointer, the offset + between the contents %ebp and the CFA as defined by GCC. */ + return sp + 8; } /* These registers are used for returning integers (and on some @@ -1716,7 +1722,6 @@ i386_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) set_gdbarch_print_insn (gdbarch, i386_print_insn); set_gdbarch_unwind_dummy_id (gdbarch, i386_unwind_dummy_id); - set_gdbarch_save_dummy_frame_tos (gdbarch, i386_save_dummy_frame_tos); set_gdbarch_unwind_pc (gdbarch, i386_unwind_pc); diff --git a/gdb/infcall.c b/gdb/infcall.c index 23a5664aa22..0a10c31b287 100644 --- a/gdb/infcall.c +++ b/gdb/infcall.c @@ -823,7 +823,15 @@ You must use a pointer to function type variable. Command ignored.", arg_name); if (DEPRECATED_DUMMY_WRITE_SP_P ()) DEPRECATED_DUMMY_WRITE_SP (sp); - if (SAVE_DUMMY_FRAME_TOS_P ()) + if (gdbarch_unwind_dummy_id_p (current_gdbarch)) + { + /* Sanity. The exact same SP value is returned by + PUSH_DUMMY_CALL, saved as the dummy-frame TOS, and used by + unwind_dummy_id to form the frame ID's stack address. */ + gdb_assert (DEPRECATED_USE_GENERIC_DUMMY_FRAMES); + generic_save_dummy_frame_tos (sp); + } + else if (SAVE_DUMMY_FRAME_TOS_P ()) SAVE_DUMMY_FRAME_TOS (sp); /* Now proceed, having reached the desired place. */ @@ -843,17 +851,29 @@ You must use a pointer to function type variable. Command ignored.", arg_name); set_momentary_breakpoint. We need to give the breakpoint a frame ID so that the breakpoint code can correctly re-identify the dummy breakpoint. */ - /* The assumption here is that push_dummy_call() returned the - stack part of the frame ID. Unfortunatly, many older - architectures were, via a convoluted mess, relying on the - poorly defined and greatly overloaded DEPRECATED_TARGET_READ_FP - or DEPRECATED_FP_REGNUM to supply the value. */ - if (DEPRECATED_TARGET_READ_FP_P ()) - frame = frame_id_build (DEPRECATED_TARGET_READ_FP (), sal.pc); - else if (DEPRECATED_FP_REGNUM >= 0) - frame = frame_id_build (read_register (DEPRECATED_FP_REGNUM), sal.pc); + if (gdbarch_unwind_dummy_id_p (current_gdbarch)) + { + /* Sanity. The exact same SP value is returned by + PUSH_DUMMY_CALL, saved as the dummy-frame TOS, and used by + unwind_dummy_id to form the frame ID's stack address. */ + gdb_assert (DEPRECATED_USE_GENERIC_DUMMY_FRAMES); + frame = frame_id_build (sp, sal.pc); + } else - frame = frame_id_build (sp, sal.pc); + { + /* The assumption here is that push_dummy_call() returned the + stack part of the frame ID. Unfortunatly, many older + architectures were, via a convoluted mess, relying on the + poorly defined and greatly overloaded + DEPRECATED_TARGET_READ_FP or DEPRECATED_FP_REGNUM to supply + the value. */ + if (DEPRECATED_TARGET_READ_FP_P ()) + frame = frame_id_build (DEPRECATED_TARGET_READ_FP (), sal.pc); + else if (DEPRECATED_FP_REGNUM >= 0) + frame = frame_id_build (read_register (DEPRECATED_FP_REGNUM), sal.pc); + else + frame = frame_id_build (sp, sal.pc); + } bpt = set_momentary_breakpoint (sal, frame, bp_call_dummy); bpt->disposition = disp_del; } diff --git a/gdb/x86-64-tdep.c b/gdb/x86-64-tdep.c index 0b2f6913dd6..6c38f8d3c15 100644 --- a/gdb/x86-64-tdep.c +++ b/gdb/x86-64-tdep.c @@ -783,7 +783,7 @@ x86_64_push_dummy_call (struct gdbarch *gdbarch, CORE_ADDR func_addr, /* ...and fake a frame pointer. */ regcache_cooked_write (regcache, X86_64_RBP_REGNUM, buf); - return sp; + return sp + 16; } @@ -1122,12 +1122,6 @@ static const struct frame_base x86_64_frame_base = x86_64_frame_base_address }; -static void -x86_64_save_dummy_frame_tos (CORE_ADDR sp) -{ - generic_save_dummy_frame_tos (sp + 16); -} - static struct frame_id x86_64_unwind_dummy_id (struct gdbarch *gdbarch, struct frame_info *next_frame) { @@ -1196,7 +1190,6 @@ x86_64_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) set_gdbarch_num_pseudo_regs (gdbarch, 0); set_gdbarch_unwind_dummy_id (gdbarch, x86_64_unwind_dummy_id); - set_gdbarch_save_dummy_frame_tos (gdbarch, x86_64_save_dummy_frame_tos); /* FIXME: kettenis/20021026: This is ELF-specific. Fine for now, since all supported x86-64 targets are ELF, but that might change -- 2.30.2