diff options
author | Matt Fleming <matt@console-pimps.org> | 2009-08-15 20:44:33 -0400 |
---|---|---|
committer | Matt Fleming <matt@console-pimps.org> | 2009-08-16 07:48:53 -0400 |
commit | cd7246f0e2747bd2b43d25d0f63f05db182a62c0 (patch) | |
tree | 729c855c6e17a35b8467161baeeb6431765cf372 /arch/sh/kernel/dwarf.c | |
parent | b955873bf530ee4b80e6c8b734521ad07cbaed7e (diff) |
sh: Add support for DWARF GNU extensions
Also, remove the "fix" to DW_CFA_def_cfa_register where we reset the
frame's cfa_offset to 0. This action is incorrect when handling
DW_CFA_def_cfa_register as the DWARF spec specifically states that the
previous contents of cfa_offset should be used with the new
register. The reason that I thought cfa_offset should be reset to 0 was
because it was being assigned a bogus value prior to executing the
DW_CFA_def_cfa_register op. It turns out that the bogus cfa_offset value
came from interpreting .cfi_escape pseudo-ops (those used by the GNU
extensions) as CFA_DW_def_cfa ops.
Signed-off-by: Matt Fleming <matt@console-pimps.org>
Diffstat (limited to 'arch/sh/kernel/dwarf.c')
-rw-r--r-- | arch/sh/kernel/dwarf.c | 14 |
1 files changed, 13 insertions, 1 deletions
diff --git a/arch/sh/kernel/dwarf.c b/arch/sh/kernel/dwarf.c index 44e674ed2871..5fd6e604816d 100644 --- a/arch/sh/kernel/dwarf.c +++ b/arch/sh/kernel/dwarf.c | |||
@@ -429,7 +429,6 @@ static int dwarf_cfa_execute_insns(unsigned char *insn_start, | |||
429 | count = dwarf_read_uleb128(current_insn, | 429 | count = dwarf_read_uleb128(current_insn, |
430 | &frame->cfa_register); | 430 | &frame->cfa_register); |
431 | current_insn += count; | 431 | current_insn += count; |
432 | frame->cfa_offset = 0; | ||
433 | frame->flags |= DWARF_FRAME_CFA_REG_OFFSET; | 432 | frame->flags |= DWARF_FRAME_CFA_REG_OFFSET; |
434 | break; | 433 | break; |
435 | case DW_CFA_def_cfa_offset: | 434 | case DW_CFA_def_cfa_offset: |
@@ -465,6 +464,19 @@ static int dwarf_cfa_execute_insns(unsigned char *insn_start, | |||
465 | frame->regs[reg].flags |= DWARF_REG_OFFSET; | 464 | frame->regs[reg].flags |= DWARF_REG_OFFSET; |
466 | frame->regs[reg].addr = offset; | 465 | frame->regs[reg].addr = offset; |
467 | break; | 466 | break; |
467 | case DW_CFA_GNU_args_size: | ||
468 | count = dwarf_read_uleb128(current_insn, &offset); | ||
469 | current_insn += count; | ||
470 | break; | ||
471 | case DW_CFA_GNU_negative_offset_extended: | ||
472 | count = dwarf_read_uleb128(current_insn, ®); | ||
473 | current_insn += count; | ||
474 | count = dwarf_read_uleb128(current_insn, &offset); | ||
475 | offset *= cie->data_alignment_factor; | ||
476 | dwarf_frame_alloc_regs(frame, reg); | ||
477 | frame->regs[reg].flags |= DWARF_REG_OFFSET; | ||
478 | frame->regs[reg].addr = -offset; | ||
479 | break; | ||
468 | default: | 480 | default: |
469 | pr_debug("unhandled DWARF instruction 0x%x\n", insn); | 481 | pr_debug("unhandled DWARF instruction 0x%x\n", insn); |
470 | break; | 482 | break; |