[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [libunwind] problems parsing dwarf frame info on amd64 optimized cod

From: David Mosberger
Subject: Re: [libunwind] problems parsing dwarf frame info on amd64 optimized code
Date: Fri, 12 Mar 2004 17:09:37 -0800

>>>>> On Fri, 12 Mar 2004 11:20:56 -0800, Max Asbock <address@hidden> said:

  Max> Then how about: if (rs->reg[DWARF_CFA_REG_COLUMN].where ==
  Max> DWARF_WHERE_REG) { if ((rs->reg[DWARF_CFA_REG_COLUMN].val ==
  Max> <REGNUM_SP>) && (rs->reg[<REGNUM_SP>].where ==
  Max> DWARF_WHERE_SAME)) cfa = c->cfa; else read the value for the
  Max> cfa from the register }

  Max> This works as well.

Hmmh, it's pretty tricky stuff.


        CFA_def_cfa r7+0x8           (rsp)

says CFA is at rsp+8, so apply_reg_state() will update cfa to this
value (contents of rsp + 8).  Now, in the next frame:

        CFA_def_cfa_offset <offset>

which implicitly says that the CFA is still in rsp, except that the
offset is now <offset>.  But what it really means is that the CFA is
at the _restored_ value of rsp plus <offset>.  Unfortunately, DWARF
code you showed doesn't explicitly say that rsp was restored from rsp
to rsp + 8, so the info is ostensibly wrong (incomplete).  However, I
don't think you can even _express_ the rsp update in DWARF!

I looked at the thread on the GCC mailing-list and that clears it up.
To quote Richard Henderson from this mail:

  ...[T]here's an implicit assumption that the CFA corresponds to the
  stack pointer at the point of the call instruction.  This can be
  overridden by the actual CFI data if the target wants to describe
  the old stack pointer value saved in some register or in memory.

  The normal case, the old stack pointer not saved anywhere directly
  only as a known offset from a register, is not representable in
  dwarf2/3.  There has been talk about adding something for this case
  but nothing has materialized yet.

In other words: ugly... ;-(

OK, I think you can fix that by doing something similar to what is
done on ia64:

 - add an "sp" member to "struct dwarf_cursor"
 - in *access_reg(), treat the stack-pointer as a read-only register
   and when reading it, return the value from c->dwarf.sp
 - when initializing a cursor, initialize c->dwarf.sp appropriately
 - in apply_reg_state(), evaluate the CFA as is done now; if the
   stack-pointer isn't saved, then update c->sp with the new CFA value

That should do it.

BTW: Can you make patches available so others can follow your work?
I'm sure there would be interest.


reply via email to

[Prev in Thread] Current Thread [Next in Thread]