summaryrefslogtreecommitdiff
path: root/gdb/dwarf2-frame.c
diff options
context:
space:
mode:
authorAlexandre Oliva <aoliva@redhat.com>2006-05-28 05:56:50 +0000
committerAlexandre Oliva <aoliva@redhat.com>2006-05-28 05:56:50 +0000
commitd0bd90ab577a6dac3362860860988d49790a7fb3 (patch)
treefc49b07df7d7aba458268330df9dbe5b0acd9c0f /gdb/dwarf2-frame.c
parentd82c8f1adcb63d492a2cc6603c820a6e1c66128b (diff)
downloadgdb-d0bd90ab577a6dac3362860860988d49790a7fb3.tar.gz
* 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.c50
1 files changed, 50 insertions, 0 deletions
diff --git a/gdb/dwarf2-frame.c b/gdb/dwarf2-frame.c
index 6b81dff7999..edd9a7536ae 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, &reg);
+ 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, &reg);
+ 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, &reg);
+ 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