aboutsummaryrefslogtreecommitdiff
path: root/gdb/arm-tdep.c
diff options
context:
space:
mode:
authorYao Qi <yao@codesourcery.com>2014-05-30 16:06:32 +0800
committerYao Qi <yao@codesourcery.com>2014-06-24 09:30:29 +0800
commit18d18ac8105647241a4e24a3a4d0196955666e73 (patch)
tree5e8424a3e22e8fad80e4c3caa488cffec8223aa8 /gdb/arm-tdep.c
parent80d8d3908b7ef70c325fcdfb455bf5dbc2c68e16 (diff)
downloadgdb-18d18ac8105647241a4e24a3a4d0196955666e73.zip
gdb-18d18ac8105647241a4e24a3a4d0196955666e73.tar.gz
gdb-18d18ac8105647241a4e24a3a4d0196955666e73.tar.bz2
Apply stub unwinder to 'bx reg' trampoline
In target arm-none-eabi, prologue unwinder is used for trampoline 'bx reg'. However, in target arm-linux, exidx unwinder is selected for trampoline at first, which is not expected. The main function and the trampoline is, 0x00009dfc <main+0>: push {r4, r5, r6, r7, lr} ...... 0x0000ac30 <main+3636>: ldrdeq r3, [r1], -r8 0x0000ac34: bx r2 0x0000ac36: bx r4 and .ARM.exidx is: 0x9dfc <main>: @0xb404 Compact model index: 1 0x97 vsp = r7 0x20 vsp = vsp + 132 0x3f vsp = vsp + 256 0x80 0xf0 pop {r8, r9, r10, r11} 0xab pop {r4, r5, r6, r7, r14} 0xac38 <__aeabi_drsub>: 0x1 [cantunwind] Trampolines 'bx r2' and 'bx r4' doesn't belong to main, but the exidx for main is still selected form them because there is no end address of each exidx entry. Instead of teaching exidx unwinder ignore this trampoline (which looks complicated and error prone), I decide to let stub unwinder to handle trampoline, because stub undwinder is installed before exidx unwinder, and this trampoline can be regarded as a stub too. This patch is to add the code to match 'bx reg' trampoline in the sniffer of stub unwinder. gdb: 2014-06-24 Yao Qi <yao@codesourcery.com> * arm-tdep.c (arm_stub_unwind_sniffer): Return 1 if arm_skip_bx_reg returns non-zero.
Diffstat (limited to 'gdb/arm-tdep.c')
-rw-r--r--gdb/arm-tdep.c9
1 files changed, 8 insertions, 1 deletions
diff --git a/gdb/arm-tdep.c b/gdb/arm-tdep.c
index eabca4c..8cc60a4 100644
--- a/gdb/arm-tdep.c
+++ b/gdb/arm-tdep.c
@@ -2964,12 +2964,19 @@ arm_stub_unwind_sniffer (const struct frame_unwind *self,
{
CORE_ADDR addr_in_block;
gdb_byte dummy[4];
+ CORE_ADDR pc, start_addr;
+ const char *name;
addr_in_block = get_frame_address_in_block (this_frame);
+ pc = get_frame_pc (this_frame);
if (in_plt_section (addr_in_block)
/* We also use the stub winder if the target memory is unreadable
to avoid having the prologue unwinder trying to read it. */
- || target_read_memory (get_frame_pc (this_frame), dummy, 4) != 0)
+ || target_read_memory (pc, dummy, 4) != 0)
+ return 1;
+
+ if (find_pc_partial_function (pc, &name, &start_addr, NULL) == 0
+ && arm_skip_bx_reg (this_frame, pc) != 0)
return 1;
return 0;