From: Michael Snyder Date: Tue, 10 Jun 2008 18:06:04 +0000 (+0000) Subject: 2007-04-18 Daniel Jacobowitz X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=9ea36100a546a93c1f4f378b66000e46a2038c93;p=thirdparty%2Fbinutils-gdb.git 2007-04-18 Daniel Jacobowitz * arm-tdep.c (arm_scan_epilogue): New. (arm_make_prologue_cache): Use it. (arm_epilogue_unwind_sniffer): New. (arm_gdbarch_init): Register it. --- diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 3deec46401b..8a9b31ae3c4 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -34,6 +34,13 @@ * Makefile.in (reverse.c): New file. * reverse.c: New file. User interface for reverse execution. +2007-04-18 Daniel Jacobowitz + + * arm-tdep.c (arm_scan_epilogue): New. + (arm_make_prologue_cache): Use it. + (arm_epilogue_unwind_sniffer): New. + (arm_gdbarch_init): Register it. + 2008-06-09 Doug Evans * remote.c (remote_wait): Include beginning of malformed packet diff --git a/gdb/arm-tdep.c b/gdb/arm-tdep.c index fd732a87e45..0d4d1fe55b0 100644 --- a/gdb/arm-tdep.c +++ b/gdb/arm-tdep.c @@ -1011,6 +1011,84 @@ arm_scan_prologue (struct frame_info *this_frame, do_cleanups (back_to); } +/* This function tries to guess whether we are in the epilogue of an + ARM function. We need to detect whether the stack frame has + already been destroyed - if it has, then neither the prologue + scanner nor GCC's unwind tables will be valid. This is very hokey + and generally unsafe. */ + +static int +arm_scan_epilogue (struct frame_info *next_frame, + struct arm_prologue_cache *cache) +{ + unsigned int insn; + gdb_byte buf[4]; + CORE_ADDR prev_pc = frame_pc_unwind (next_frame); + + /* Assume there is no frame until proven otherwise. */ + if (cache != NULL) + { + cache->framereg = ARM_SP_REGNUM; + cache->framesize = 0; + cache->frameoffset = 0; + } + + /* Check for Thumb epilogue. */ + if (arm_pc_is_thumb (prev_pc)) + /* Not yet implemented. */ + return 0; + + if (target_read_memory (prev_pc, buf, 4) != 0) + return 0; + insn = extract_unsigned_integer (buf, 4); + + if (insn == 0xe12fff1e) /* bx lr */ + /* If this is a return, we have no frame left and no saved + registers. */ + return 1; + + return 0; +} + +/* This function tries to guess whether we are in the epilogue of an + ARM function. We need to detect whether the stack frame has + already been destroyed - if it has, then neither the prologue + scanner nor GCC's unwind tables will be valid. This is very hokey + and generally unsafe. */ + +static int +arm_scan_epilogue (struct frame_info *next_frame, + struct arm_prologue_cache *cache) +{ + unsigned int insn; + gdb_byte buf[4]; + CORE_ADDR prev_pc = frame_pc_unwind (next_frame); + + /* Assume there is no frame until proven otherwise. */ + if (cache != NULL) + { + cache->framereg = ARM_SP_REGNUM; + cache->framesize = 0; + cache->frameoffset = 0; + } + + /* Check for Thumb epilogue. */ + if (arm_pc_is_thumb (prev_pc)) + /* Not yet implemented. */ + return 0; + + if (target_read_memory (prev_pc, buf, 4) != 0) + return 0; + insn = extract_unsigned_integer (buf, 4); + + if (insn == 0xe12fff1e) /* bx lr */ + /* If this is a return, we have no frame left and no saved + registers. */ + return 1; + + return 0; +} + static struct arm_prologue_cache * arm_make_prologue_cache (struct frame_info *this_frame) { @@ -1132,6 +1210,24 @@ struct frame_unwind arm_prologue_unwind = { default_frame_sniffer }; +static const struct frame_unwind * +arm_epilogue_unwind_sniffer (struct frame_info *next_frame) +{ + if (arm_scan_epilogue (next_frame, NULL)) + return &arm_prologue_unwind; + else + return NULL; +} + +static const struct frame_unwind * +arm_epilogue_unwind_sniffer (struct frame_info *next_frame) +{ + if (arm_scan_epilogue (next_frame, NULL)) + return &arm_prologue_unwind; + else + return NULL; +} + static struct arm_prologue_cache * arm_make_stub_cache (struct frame_info *this_frame) {