* dwarf2-frame.c (dwarf2_reg_rule): Add REG_RA and REG_CFA.

(dwarf2_frame_cache): Initialize PC_REGNUM with REG_RA and
SP_REGNUM with REG_CFA.  Don't overwrite the initialized register
rule for registers left unspecified by the CFI.  Remove the
special handling of PC_REGNUM.  Add code to eleminate any REG_RA
rules.
(dwarf2_frame_prev_register): Remove the special handling of
SP_REGNUM.  Add support for the REG_CFA rule.
This commit is contained in:
Mark Kettenis 2003-12-27 23:15:00 +00:00
parent 678f5623fd
commit 3588991722
2 changed files with 90 additions and 108 deletions

View file

@ -1,3 +1,14 @@
2003-12-27 Mark Kettenis <kettenis@gnu.org>
* dwarf2-frame.c (dwarf2_reg_rule): Add REG_RA and REG_CFA.
(dwarf2_frame_cache): Initialize PC_REGNUM with REG_RA and
SP_REGNUM with REG_CFA. Don't overwrite the initialized register
rule for registers left unspecified by the CFI. Remove the
special handling of PC_REGNUM. Add code to eleminate any REG_RA
rules.
(dwarf2_frame_prev_register): Remove the special handling of
SP_REGNUM. Add support for the REG_CFA rule.
2003-12-26 Mark Kettenis <kettenis@gnu.org>
* i386obsd-tdep.c: Include "regset.h", "gdb_assert.h" and

View file

@ -105,6 +105,7 @@ enum dwarf2_reg_rule
about a register, leaving how to obtain its value totally
unspecified. */
REG_UNSPECIFIED = 0,
/* The term "undefined" comes from the DWARF2 CFI spec which this
code is moddeling; it indicates that the register's value is
"undefined". GCC uses the less formal term "unsaved". Its
@ -115,7 +116,12 @@ enum dwarf2_reg_rule
REG_SAVED_OFFSET,
REG_SAVED_REG,
REG_SAVED_EXP,
REG_SAME_VALUE
REG_SAME_VALUE,
/* These aren't defined by the DWARF2 CFI specification, but are
used internally by GDB. */
REG_RA, /* Return Address. */
REG_CFA /* Call Frame Address. */
};
struct dwarf2_frame_state
@ -547,13 +553,43 @@ dwarf2_frame_cache (struct frame_info *next_frame, void **this_cache)
internal_error (__FILE__, __LINE__, "Unknown CFA rule.");
}
/* Initialize things so that all registers are marked as
unspecified. */
/* Initialize the register rules. If we have a register that acts
as a program counter, mark it as a destination for the return
address. If we have a register that serves as the stack pointer,
arrange for it to be filled with the call frame address (CFA).
The other registers are marked as unspecified.
We copy the return address to the program counter, since many
parts in GDB assume that it is possible to get the return address
by unwind the program counter register. However, on ISA's with a
dedicated return address register, the CFI usually only contains
information to unwind that return address register.
The reason we're treating the stack pointer special here is
because in many cases GCC doesn't emit CFI for the stack pointer
and implicitly assumes that it is equal to the CFA. This makes
some sense since the DWARF specification (version 3, draft 8,
p. 102) says that:
"Typically, the CFA is defined to be the value of the stack
pointer at the call site in the previous frame (which may be
different from its value on entry to the current frame)."
However, this isn't true for all platforms supported by GCC
(e.g. IBM S/390 and zSeries). For those targets we should
override the defaults given here. */
{
int regnum;
for (regnum = 0; regnum < num_regs; regnum++)
cache->reg[regnum].how = REG_UNSPECIFIED;
{
if (regnum == PC_REGNUM)
cache->reg[regnum].how = REG_RA;
else if (regnum == SP_REGNUM)
cache->reg[regnum].how = REG_CFA;
else
cache->reg[regnum].how = REG_UNSPECIFIED;
}
}
/* Go through the DWARF2 CFI generated table and save its register
@ -590,35 +626,33 @@ dwarf2_frame_cache (struct frame_info *next_frame, void **this_cache)
complaint (&symfile_complaints,
"Incomplete CFI data; unspecified registers at 0x%s",
paddr (fs->pc));
cache->reg[regnum] = fs->regs.reg[column];
else
cache->reg[regnum] = fs->regs.reg[column];
}
}
/* Store the location of the return addess. If the return address
column (adjusted) is not the same as GDB's PC_REGNUM, then this
implies a copy from the return address column register. */
if (fs->retaddr_column < fs->regs.num_regs
&& fs->regs.reg[fs->retaddr_column].how != REG_UNDEFINED)
{
/* See comment above about a possibly negative PC_REGNUM. If
this assertion fails, it's a problem with this code and not
the architecture. */
gdb_assert (PC_REGNUM >= 0);
cache->reg[PC_REGNUM] = fs->regs.reg[fs->retaddr_column];
}
else
{
if (DWARF2_REG_TO_REGNUM (fs->retaddr_column) != PC_REGNUM)
{
/* See comment above about PC_REGNUM being negative. If
this assertion fails, it's a problem with this code and
not the architecture. */
gdb_assert (PC_REGNUM >= 0);
cache->reg[PC_REGNUM].loc.reg = fs->retaddr_column;
cache->reg[PC_REGNUM].how = REG_SAVED_REG;
}
}
/* Eliminate any REG_RA rules. */
{
int regnum;
for (regnum = 0; regnum < num_regs; regnum++)
{
if (cache->reg[regnum].how == REG_RA)
{
if (fs->retaddr_column < fs->regs.num_regs)
cache->reg[regnum] = fs->regs.reg[fs->retaddr_column];
else
{
/* It turns out that GCC assumes that if the return
address column is "empty" the return address can be
found in the register corresponding to the return
address column. */
cache->reg[regnum].loc.reg = fs->retaddr_column;
cache->reg[regnum].how = REG_SAVED_REG;
}
}
}
}
do_cleanups (old_chain);
@ -654,42 +688,7 @@ dwarf2_frame_prev_register (struct frame_info *next_frame, void **this_cache,
*lvalp = not_lval;
*addrp = 0;
*realnump = -1;
if (regnum == SP_REGNUM)
{
/* GCC defines the CFA as the value of the stack pointer
just before the call instruction is executed. Do other
compilers use the same definition? */
/* DWARF V3 Draft 7 p102: Typically, the CFA is defined to
be the value of the stack pointer at the call site in the
previous frame (which may be different from its value on
entry to the current frame). */
/* DWARF V3 Draft 7 p103: The first column of the rules
defines the rule which computes the CFA value; it may be
either a register and a signed offset that are added
together or a DWARF expression that is evaluated. */
/* FIXME: cagney/2003-07-07: I don't understand this. The
CFI info should have provided unwind information for the
SP register and then pointed ->cfa_reg at it, not the
reverse. Assuming that SP_REGNUM isn't negative, there
is a very real posibility that CFA is an offset from some
other register, having nothing to do with the unwound SP
value. */
/* FIXME: cagney/2003-09-05: I think I understand. GDB was
lumping the two states "unspecified" and "undefined"
together. Here SP_REGNUM was "unspecified", GCC assuming
that in such a case CFA would be used. This branch of
the if statement should be deleted - the problem of
SP_REGNUM is now handed by the case REG_UNSPECIFIED
below. */
*optimizedp = 0;
if (valuep)
{
/* Store the value. */
store_typed_address (valuep, builtin_type_void_data_ptr,
cache->cfa);
}
}
else if (valuep)
if (valuep)
{
/* In some cases, for example %eflags on the i386, we have
to provide a sane value, even though this register wasn't
@ -740,48 +739,8 @@ dwarf2_frame_prev_register (struct frame_info *next_frame, void **this_cache,
"undefined"). Code above issues a complaint about this.
Here just fudge the books, assume GCC, and that the value is
more inner on the stack. */
if (SP_REGNUM >= 0 && regnum == SP_REGNUM)
{
/* Can things get worse? Yep! One of the registers GCC
forgot to provide unwind information for was the stack
pointer. Outch! GCC appears to assumes that the CFA
address can be used - after all it points to the inner
most address of the previous frame before the function
call and that's always the same as the stack pointer on
return, right? Wrong. See GCC's i386 STDCALL option for
an ABI that has a different entry and return stack
pointer. */
/* DWARF V3 Draft 7 p102: Typically, the CFA is defined to
be the value of the stack pointer at the call site in the
previous frame (which may be different from its value on
entry to the current frame). */
/* DWARF V3 Draft 7 p103: The first column of the rules
defines the rule which computes the CFA value; it may be
either a register and a signed offset that are added
together or a DWARF expression that is evaluated. */
/* NOTE: cagney/2003-09-05: Should issue a complaint.
Unfortunately it turns out that DWARF2 CFI has a problem.
Since CFI specifies the location at which a register was
saved (not its value) it isn't possible to specify
something like "unwound(REG) == REG + constant" using CFI
as will almost always occure with the stack pointer. I
guess CFI should be point SP at CFA. Ref: danielj,
"Describing unsaved stack pointers", posted to dwarf2
list 2003-08-15. */
*optimizedp = 0;
*lvalp = not_lval;
*addrp = 0;
*realnump = -1;
if (valuep)
/* Store the value. */
store_typed_address (valuep, builtin_type_void_data_ptr,
cache->cfa);
}
else
/* Assume that the register can be found in the next inner
most frame. */
frame_register_unwind (next_frame, regnum,
optimizedp, lvalp, addrp, realnump, valuep);
frame_register_unwind (next_frame, regnum,
optimizedp, lvalp, addrp, realnump, valuep);
break;
case REG_SAME_VALUE:
@ -789,6 +748,18 @@ dwarf2_frame_prev_register (struct frame_info *next_frame, void **this_cache,
optimizedp, lvalp, addrp, realnump, valuep);
break;
case REG_CFA:
*optimizedp = 0;
*lvalp = not_lval;
*addrp = 0;
*realnump = -1;
if (valuep)
{
/* Store the value. */
store_typed_address (valuep, builtin_type_void_data_ptr, cache->cfa);
}
break;
default:
internal_error (__FILE__, __LINE__, "Unknown register rule.");
}