This is the mail archive of the
gdb-patches@sources.redhat.com
mailing list for the GDB project.
[RFC] Teach dwarf2-frame.c about StackGhost
- From: Mark Kettenis <mark dot kettenis at xs4all dot nl>
- To: gdb-patches at sourceware dot org
- Date: Sun, 3 Apr 2005 00:18:42 +0200 (CEST)
- Subject: [RFC] Teach dwarf2-frame.c about StackGhost
One of the things that still keeps me from enabling the DWARF2
unwinder on SPARC is the fact that it doesn't play nice with
StackGhost. Here is an attempt to make dwarf2-frame.c deal with it by
introducing yet another register rule. People might object since this
is only sort of architecture independent code. However it seems that
this is the cleanest way to solve this.
If there's no opposition, I'll check this in next weekend.
Mark
Index: ChangeLog
from Mark Kettenis <kettenis@gnu.org>
* dwarf2-frame.h (enum dwarf2_frame_reg_rule): Add
DWARF2_FRAME_REG_SAVED_WCOOKIE.
* dwarf2-frame.c: Include "target.h".
(execute_cfa_program): Handle StackGhost.
(dwarf2_frame_prev_register): Likewise.
* Makefile.in (dwarf2-frame.o): Update dependencies.
Index: dwarf2-frame.c
===================================================================
RCS file: /cvs/src/src/gdb/dwarf2-frame.c,v
retrieving revision 1.50
diff -u -p -r1.50 dwarf2-frame.c
--- dwarf2-frame.c 26 Mar 2005 15:20:42 -0000 1.50
+++ dwarf2-frame.c 2 Apr 2005 22:14:29 -0000
@@ -32,6 +32,7 @@
#include "symtab.h"
#include "objfiles.h"
#include "regcache.h"
+#include "target.h"
#include "gdb_assert.h"
#include "gdb_string.h"
@@ -462,11 +463,14 @@ bad CFI data; mismatched DW_CFA_restore_
fs->regs.reg[reg].how = DWARF2_FRAME_REG_SAVED_REG;
fs->regs.reg[reg].loc.reg = reg + 16;
}
- for (reg = 16; reg < 32; reg++)
+ for (reg = 16; reg < 31; reg++)
{
fs->regs.reg[reg].how = DWARF2_FRAME_REG_SAVED_OFFSET;
fs->regs.reg[reg].loc.offset = (reg - 16) * size;
}
+ /* We may have to apply a StackGhost cookie. */
+ fs->regs.reg[31].how = DWARF2_FRAME_REG_SAVED_WCOOKIE;
+ fs->regs.reg[31].loc.offset = 15 * size;
}
break;
@@ -836,6 +840,7 @@ dwarf2_frame_prev_register (struct frame
break;
case DWARF2_FRAME_REG_SAVED_OFFSET:
+ case DWARF2_FRAME_REG_SAVED_WCOOKIE:
*optimizedp = 0;
*lvalp = lval_memory;
*addrp = cache->cfa + cache->reg[regnum].loc.offset;
@@ -915,6 +920,7 @@ dwarf2_frame_prev_register (struct frame
if (valuep)
{
CORE_ADDR pc = cache->reg[regnum].loc.offset;
+ int regnum;
regnum = DWARF2_REG_TO_REGNUM (cache->retaddr_reg.loc.reg);
pc += frame_unwind_register_unsigned (next_frame, regnum);
@@ -925,6 +931,32 @@ dwarf2_frame_prev_register (struct frame
default:
internal_error (__FILE__, __LINE__, _("Unknown register rule."));
}
+
+ /* Handle StackGhost. */
+ if (cache->reg[regnum].how == DWARF2_FRAME_REG_SAVED_WCOOKIE)
+ {
+ int size = register_size (gdbarch, regnum);
+ struct target_ops *ops = ¤t_target;
+ char *buf = alloca (size);
+ int len;
+
+ len = target_read_partial (ops, TARGET_OBJECT_WCOOKIE, NULL,
+ buf, 0, size);
+ if (len != -1)
+ {
+ ULONGEST wcookie = extract_unsigned_integer (buf, len);
+
+ gdb_assert (len == size);
+
+ *lvalp = not_lval;
+ *addrp = 0;
+ if (valuep)
+ {
+ ULONGEST value = extract_unsigned_integer (valuep, size);
+ store_unsigned_integer (valuep, size, value ^ wcookie);
+ }
+ }
+ }
}
static const struct frame_unwind dwarf2_frame_unwind =
Index: dwarf2-frame.h
===================================================================
RCS file: /cvs/src/src/gdb/dwarf2-frame.h,v
retrieving revision 1.8
diff -u -p -r1.8 dwarf2-frame.h
--- dwarf2-frame.h 25 Mar 2005 16:51:40 -0000 1.8
+++ dwarf2-frame.h 2 Apr 2005 22:14:29 -0000
@@ -55,7 +55,9 @@ enum dwarf2_frame_reg_rule
used internally by GDB. */
DWARF2_FRAME_REG_RA, /* Return Address. */
DWARF2_FRAME_REG_RA_OFFSET, /* Return Address with offset. */
- DWARF2_FRAME_REG_CFA /* Call Frame Address. */
+ DWARF2_FRAME_REG_CFA, /* Call Frame Address. */
+ DWARF2_FRAME_REG_SAVED_WCOOKIE/* Like DWARF2_FRAME_SAVED_OFFSET, but
+ apply StackGhost cookie. */
};
/* Register state. */
Index: Makefile.in
===================================================================
RCS file: /cvs/src/src/gdb/Makefile.in,v
retrieving revision 1.710
diff -u -p -r1.710 Makefile.in
--- Makefile.in 31 Mar 2005 19:58:24 -0000 1.710
+++ Makefile.in 2 Apr 2005 22:14:31 -0000
@@ -1887,7 +1887,7 @@ dwarf2expr.o: dwarf2expr.c $(defs_h) $(s
$(gdbcore_h) $(elf_dwarf2_h) $(dwarf2expr_h)
dwarf2-frame.o: dwarf2-frame.c $(defs_h) $(dwarf2expr_h) $(elf_dwarf2_h) \
$(frame_h) $(frame_base_h) $(frame_unwind_h) $(gdbcore_h) \
- $(gdbtypes_h) $(symtab_h) $(objfiles_h) $(regcache_h) \
+ $(gdbtypes_h) $(symtab_h) $(objfiles_h) $(regcache_h) $(target_h) \
$(gdb_assert_h) $(gdb_string_h) $(complaints_h) $(dwarf2_frame_h)
dwarf2loc.o: dwarf2loc.c $(defs_h) $(ui_out_h) $(value_h) $(frame_h) \
$(gdbcore_h) $(target_h) $(inferior_h) $(ax_h) $(ax_gdb_h) \