diff options
author | Alexandre Oliva <aoliva@redhat.com> | 2006-05-28 05:56:50 +0000 |
---|---|---|
committer | Alexandre Oliva <aoliva@redhat.com> | 2006-05-28 05:56:50 +0000 |
commit | 46ea248bcc124c1874e8783c5e4cd90dae6610a2 (patch) | |
tree | 6aa171631bcbe0beb72c7da00ff0d576c6cd8958 /gdb/dwarf2-frame.c | |
parent | 56c987f6063485c5c588dc27dbf1b3ddce3b0200 (diff) | |
download | gdb-46ea248bcc124c1874e8783c5e4cd90dae6610a2.zip gdb-46ea248bcc124c1874e8783c5e4cd90dae6610a2.tar.gz gdb-46ea248bcc124c1874e8783c5e4cd90dae6610a2.tar.bz2 |
* dwarf2-frame.h (enum dwarf2_frame_reg_rule): Add
DWARF2_FRAME_REG_SAVED_VAL_OFFSET and
DWARF2_FRAME_REG_SAVED_VAL_EXP.
* dwarf2-frame.c (execute_cfa_program): Handle val_offset,
val_offset_sf and val_expression.
(dwarf2_frame_prev_register): Handle the new reg rules.
(dwarf2_frame_this_id): Use pc instead of function entry point.
Diffstat (limited to 'gdb/dwarf2-frame.c')
-rw-r--r-- | gdb/dwarf2-frame.c | 50 |
1 files changed, 50 insertions, 0 deletions
diff --git a/gdb/dwarf2-frame.c b/gdb/dwarf2-frame.c index 6b81dff..edd9a75 100644 --- a/gdb/dwarf2-frame.c +++ b/gdb/dwarf2-frame.c @@ -481,6 +481,34 @@ bad CFI data; mismatched DW_CFA_restore_state at 0x%s"), paddr (fs->pc)); fs->regs.reg[reg].loc.offset = offset; break; + case DW_CFA_val_offset: + insn_ptr = read_uleb128 (insn_ptr, insn_end, ®); + dwarf2_frame_state_alloc_regs (&fs->regs, reg + 1); + insn_ptr = read_uleb128 (insn_ptr, insn_end, &utmp); + offset = utmp * fs->data_align; + fs->regs.reg[reg].how = DWARF2_FRAME_REG_SAVED_VAL_OFFSET; + fs->regs.reg[reg].loc.offset = offset; + break; + + case DW_CFA_val_offset_sf: + insn_ptr = read_uleb128 (insn_ptr, insn_end, ®); + dwarf2_frame_state_alloc_regs (&fs->regs, reg + 1); + insn_ptr = read_sleb128 (insn_ptr, insn_end, &offset); + offset *= fs->data_align; + fs->regs.reg[reg].how = DWARF2_FRAME_REG_SAVED_VAL_OFFSET; + fs->regs.reg[reg].loc.offset = offset; + break; + + case DW_CFA_val_expression: + insn_ptr = read_uleb128 (insn_ptr, insn_end, ®); + dwarf2_frame_state_alloc_regs (&fs->regs, reg + 1); + insn_ptr = read_uleb128 (insn_ptr, insn_end, &utmp); + fs->regs.reg[reg].loc.exp = insn_ptr; + fs->regs.reg[reg].exp_len = utmp; + fs->regs.reg[reg].how = DWARF2_FRAME_REG_SAVED_VAL_EXP; + insn_ptr += utmp; + break; + case DW_CFA_def_cfa_sf: insn_ptr = read_uleb128 (insn_ptr, insn_end, &fs->cfa_reg); if (eh_frame_p) @@ -965,6 +993,28 @@ dwarf2_frame_prev_register (struct frame_info *next_frame, void **this_cache, } break; + case DWARF2_FRAME_REG_SAVED_VAL_OFFSET: + *optimizedp = 0; + *lvalp = not_lval; + *addrp = 0; + *realnump = -1; + if (valuep) + store_unsigned_integer (valuep, register_size (gdbarch, regnum), + cache->cfa + cache->reg[regnum].loc.offset); + break; + + case DWARF2_FRAME_REG_SAVED_VAL_EXP: + *optimizedp = 0; + *lvalp = not_lval; + *addrp = 0; + *realnump = -1; + if (valuep) + store_unsigned_integer (valuep, register_size (gdbarch, regnum), + execute_stack_op (cache->reg[regnum].loc.exp, + cache->reg[regnum].exp_len, + next_frame, cache->cfa)); + break; + case DWARF2_FRAME_REG_UNSPECIFIED: /* GCC, in its infinite wisdom decided to not provide unwind information for registers that are "same value". Since |