From: Mark Kettenis <kettenis@gnu.org>
To: gdb-patches@sources.redhat.com
Subject: [RFC] DWARF2 unwinder on SPARC
Date: Mon, 07 Mar 2005 21:03:00 -0000 [thread overview]
Message-ID: <200503072103.j27L3i4x004351@elgar.sibelius.xs4all.nl> (raw)
I'm working on enabling the DWARF2 unwinder on 32-bit and 64-bit
SPARC. It's basically working for me on FreeBSD/sparc64, but there
are two issues that I'd like some opinions about.
1. I'll need to handle DW_CFA_GNU_window_save. I suppose its
interpretation will be really machine specific, but it really only
makes sense for register window architectures. And I can only
think of a single example of such an architecture that's still
around. Now the problem I'm facing is the choice between two
evils:
a. Contaminate dwarf2-frame.c with a bit of target-specific code.
b. Contaminate dwarf2-frame.c with another architecture-specific
operation that will only be used for SPARC.
Can someone make a choice for me ;-)
2. We need a mechanism for return addresses that are not quite the
contents of a register or memory slot. On SPARC, the address of
the call instruction is stored in a register instead of the address
where we should return to. So the proper way to unwind the pc is
to take this register and add 8 to it. There's also npc, which
should be calculated in a similar way by adding 12. We'll need
something similar for PA-RISC and m88k will need it too if it ever
gains a dwarf2 unwinder. There might be more architectures out
there that need this.
My proposal is to change the definition of DWARF2_FRAME_REG_RA such
that the offset member of `struct dwarf2_frame_state_reg' can be
used to specify the amount to add to the value yielded by the
return address column. This is compatible with the existing use
since currently that offset member is initialized to zero. As an
alternative, we can add a new constant DWARF2_FRAME_REG_RA_OFFSET
for this usage.
Attached is my preliminary patch that implements this stuff.
Mark
Index: dwarf2-frame.c
===================================================================
RCS file: /cvs/src/src/gdb/dwarf2-frame.c,v
retrieving revision 1.48
diff -u -p -r1.48 dwarf2-frame.c
--- dwarf2-frame.c 11 Feb 2005 18:13:49 -0000 1.48
+++ dwarf2-frame.c 7 Mar 2005 21:03:14 -0000
@@ -445,6 +445,20 @@ bad CFI data; mismatched DW_CFA_restore_
/* cfa_how deliberately not set. */
break;
+ case DW_CFA_GNU_window_save:
+ dwarf2_frame_state_alloc_regs (&fs->regs, 32);
+ for (reg = 8; reg < 16; reg++)
+ {
+ fs->regs.reg[reg].how = DWARF2_FRAME_REG_SAVED_REG;
+ fs->regs.reg[reg].loc.reg = reg + 16;
+ }
+ for (reg = 16; reg < 32; reg++)
+ {
+ fs->regs.reg[reg].how = DWARF2_FRAME_REG_SAVED_OFFSET;
+ fs->regs.reg[reg].loc.offset = (reg - 16) * 8;
+ }
+ break;
+
case DW_CFA_GNU_args_size:
/* Ignored. */
insn_ptr = read_uleb128 (insn_ptr, insn_end, &utmp);
@@ -588,6 +602,9 @@ struct dwarf2_frame_cache
/* Saved registers, indexed by GDB register number, not by DWARF
register number. */
struct dwarf2_frame_state_reg *reg;
+
+ /* Return address register. */
+ struct dwarf2_frame_state_reg retaddr_reg;
};
static struct dwarf2_frame_cache *
@@ -733,16 +750,29 @@ incomplete CFI data; unspecified registe
what GCC does on some targets. It turns out that GCC
assumes that the return address can be found in the
register corresponding to the return address column.
- Incidentally, that's how should treat a return address
- column specifying "same value" too. */
+ Incidentally, that's how we should treat a return
+ address column specifying "same value" too. */
if (fs->retaddr_column < fs->regs.num_regs
&& retaddr_reg->how != DWARF2_FRAME_REG_UNSPECIFIED
&& retaddr_reg->how != DWARF2_FRAME_REG_SAME_VALUE)
- cache->reg[regnum] = *retaddr_reg;
+ {
+ if (cache->reg[regnum].loc.offset == 0)
+ cache->reg[regnum] = *retaddr_reg;
+ else
+ cache->retaddr_reg = *retaddr_reg;
+ }
else
{
- cache->reg[regnum].loc.reg = fs->retaddr_column;
- cache->reg[regnum].how = DWARF2_FRAME_REG_SAVED_REG;
+ if (cache->reg[regnum].loc.offset == 0)
+ {
+ cache->reg[regnum].loc.reg = fs->retaddr_column;
+ cache->reg[regnum].how = DWARF2_FRAME_REG_SAVED_REG;
+ }
+ else
+ {
+ cache->retaddr_reg.loc.reg = fs->retaddr_column;
+ cache->retaddr_reg.how = DWARF2_FRAME_REG_SAVED_REG;
+ }
}
}
}
@@ -864,6 +894,21 @@ dwarf2_frame_prev_register (struct frame
}
break;
+ case DWARF2_FRAME_REG_RA:
+ *optimizedp = 0;
+ *lvalp = not_lval;
+ *addrp = 0;
+ *realnump = -1;
+ if (valuep)
+ {
+ CORE_ADDR pc = cache->reg[regnum].loc.offset;
+
+ regnum = DWARF2_REG_TO_REGNUM (cache->retaddr_reg.loc.reg);
+ pc += frame_unwind_register_unsigned (next_frame, regnum);
+ store_typed_address (valuep, builtin_type_void_func_ptr, pc);
+ }
+ break;
+
default:
internal_error (__FILE__, __LINE__, _("Unknown register rule."));
}
next reply other threads:[~2005-03-07 21:03 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
2005-03-07 21:03 Mark Kettenis [this message]
2005-03-07 21:09 ` Daniel Jacobowitz
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=200503072103.j27L3i4x004351@elgar.sibelius.xs4all.nl \
--to=kettenis@gnu.org \
--cc=gdb-patches@sources.redhat.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox