This is the mail archive of the
gdb-patches@sourceware.org
mailing list for the GDB project.
[RFC/TileGX 1/2] fix hand-written backtracer bug
- From: Jiong Wang <jiwang at tilera dot com>
- To: <gdb-patches at sourceware dot org>
- Date: Tue, 5 Feb 2013 18:36:40 +0800
- Subject: [RFC/TileGX 1/2] fix hand-written backtracer bug
noramlly, tilegx gcc always generate unwind table, so dwarf unwinder
invoked
instead of hand-written unwinder, thus this bug is not triggered.
but if the the user remove those unwind table from the elf files, for
example,
specify -fno-asynchronous-unwind-tables, then tilegx gdb backtracer can
not work.
the reason is, tilegx hand-written backtracer did not handle the
situation when
"lr", the return address is saved on stack.
gdb/ChangeLog:
* tilegx-tdep.c (tilegx_analyze_prologue): add check for
for return address, "lr" register, saved on stack.
* tilegx-tdep.c (tilegx_frame_cache): update "PC" reg
after we invoke tilegx_analyze_prologue.
please review.
thanks.
--
Regards,
Jiong. Wang
Tilera Corporation.
---
gdb/tilegx-tdep.c | 19 +++++++++++++++++--
1 file changed, 17 insertions(+), 2 deletions(-)
diff --git a/gdb/tilegx-tdep.c b/gdb/tilegx-tdep.c
index 0c560ba..c74f527 100644
--- a/gdb/tilegx-tdep.c
+++ b/gdb/tilegx-tdep.c
@@ -405,7 +405,7 @@ tilegx_analyze_prologue (struct gdbarch* gdbarch,
struct tilegx_reverse_regs
new_reverse_frame[TILEGX_MAX_INSTRUCTIONS_PER_BUNDLE];
int dest_regs[TILEGX_MAX_INSTRUCTIONS_PER_BUNDLE];
- int reverse_frame_valid, prolog_done, branch_seen;
+ int reverse_frame_valid, prolog_done, branch_seen, lr_saved_on_stack_p;
LONGEST prev_sp_value;
int i, j;
@@ -421,6 +421,7 @@ tilegx_analyze_prologue (struct gdbarch* gdbarch,
prolog_done = 0;
branch_seen = 0;
prev_sp_value = 0;
+ lr_saved_on_stack_p = 0;
/* To cut down on round-trip overhead, we fetch multiple bundles
at once. These variables describe the range of memory we have
@@ -484,6 +485,12 @@ tilegx_analyze_prologue (struct gdbarch* gdbarch,
See trad-frame.h. */
cache->saved_regs[saved_register].realreg = saved_register;
cache->saved_regs[saved_register].addr = saved_address;
+ }
+ else if (cache
+ && (operands[0] == TILEGX_SP_REGNUM)
+ && (operands[1] == TILEGX_LR_REGNUM))
+ {
+ lr_saved_on_stack_p = 1;
}
break;
case TILEGX_OPC_ADDI:
@@ -737,6 +744,13 @@ tilegx_analyze_prologue (struct gdbarch* gdbarch,
}
}
+ if (lr_saved_on_stack_p)
+ {
+ cache->saved_regs[TILEGX_LR_REGNUM].realreg = TILEGX_LR_REGNUM;
+ cache->saved_regs[TILEGX_LR_REGNUM].addr =
+ cache->saved_regs[TILEGX_SP_REGNUM].addr;
+ }
+
return prolog_end;
}
@@ -821,11 +835,12 @@ tilegx_frame_cache (struct frame_info *this_frame, void **this_cache)
cache->base = get_frame_register_unsigned (this_frame, TILEGX_SP_REGNUM);
trad_frame_set_value (cache->saved_regs, TILEGX_SP_REGNUM, cache->base);
- cache->saved_regs[TILEGX_PC_REGNUM] = cache->saved_regs[TILEGX_LR_REGNUM];
if (cache->start_pc)
tilegx_analyze_prologue (gdbarch, cache->start_pc, current_pc,
cache, this_frame);
+ cache->saved_regs[TILEGX_PC_REGNUM] = cache->saved_regs[TILEGX_LR_REGNUM];
+
return cache;
}
--
1.7.10.3