This is the mail archive of the mailing list for the GCC project.

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [PATCH] Force DW_CFA_def_cfa after DW_CFA_def_cfa_expression if no longer indirect

> So, all DW_CFA_def_cfa_expression expressions GCC ATM generates
> should look like:
> DW_OP_bregREG <base_offset> DW_OP_deref
> DW_OP_bregx <reg> <base_offset> DW_OP_deref
> DW_OP_bregREG <base_offset> DW_OP_deref DW_OP_plus_uconst <offset>
> DW_OP_bregx <reg> <base_offset> DW_OP_deref DW_OP_plus_uconst <offset>

Yes, I followed that much in the code.

> If GCC generated DW_CFA_def_cfa_expression is followed by GCC generated
> DW_CFA_def_cfa_offset{,_sf}, then the assumed register that is
> meant to be current is the REG/<reg> from those expressions.
> If DW_CFA_def_cfa_register follows that DW_CFA_def_cfa_expression,
> then offset is assumed to be 0 for the first two expressions and
> <offset> for the last two.

I'm afraid I am still not entirely clear from this explanation, sorry.

For the former (offset*), it's only right if REG from above is the same
regno last used in a non-indirect case--I get that.  In actual fact is
it always, usually, or never the case that the regno is the same?  I
would guess that in cfa_expr cases REG is always the FP regno, and that
in cfa_offset cases it's either the FP or the SP.  If that's right, then
the question is whether cfa_offset ever wants to refer to the SP rather
than the FP, in a function that might also use cfa_expr.  If forced to
guess, I'd guess that it might not--when you have the indirect case, you
have an FP for that frame and so always use that.  But I don't want to
guess at all, I want to be told!  I'm not even sure that the former case
might ever really arise--I haven't seen it in a test case.

For the latter (register), first variants (no plus_uconst) it's only
right if the prevous cfa_offset case used 0.  That happens to be the
situation in the one test case I've seen.  In actual fact is it always,
usually, or only sometimes the case that the offset last used was 0 in a
case where cfa_expr is used later?  For the variants using plus_uconst,
it's only right if the previous cfa_offset case used the matching
nonzero offset.  In actual fact is it always, usually, or never the case
that this offset is the same?

> This is just in case you'd want to hardcode the wrong GCC behavior
> into your consumer.  Of course GCC's own unwinder doesn't handle that case
> this way and other unwinders don't either...

AFAICT the GDB code does in fact handle it this way.  It even does so
for DW_CFA_remember_state/DW_CFA_restore_state cases, because the
"stale" regno/offset fields that are ignored when DW_CFA_def_cfa_expression
is in force are pushed/popped along with the rest of the state.

> > Everyone agrees that is valid and well-specified DWARF.  The current
> > behavior at least one person on the DWARF committee asserts is invalid
> > DWARF.
> I completely agree that the current behavior is invalid DWARF too.

Understood.  I'm just trying to define the boundaries of what is best to
do with any possible such situations emitted by extant GCC versions.

If what GDB does now can in actual practice deliver wrong results for
these cases, then we should probably change GDB to diagnose the CFI as
invalid rather than silently doing what it has always done.  Conversely,
if it yields the correct answer, perhaps even only in 90% of cases (and
almost certainly if 99.44%)--even if that's only by happenstance and
neither intent nor theoretical guarantee--then probably the "right"
thing for my other unwinder to do is match GDB's behavior.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]