When would you need a register expression followed by
DW_OP_stack_value?
That can't actually come up in CFI, I don't think. I was just citing the
definition of "simple location description", really.
There is no DW_CFA_val_register (DW_CFA_register will translate to
DW_OP_regx alone, i.e. "a register location description").
DW_CFA_val_expression takes a DWARF expression, which DW_OP_reg* is not.
However, you could have a DW_CFA_val_expression using DW_OP_bregx.
That would translate to {DW_OP_bregx(regno), DW_OP_stack_value}.
That means, "caller's register X value is visible in my register Y, but I
will not be reloading the caller's X directly from register Y if you were
thinking of changing register Y right now."
I'm pretty sure the compiler won't generate that. But it could. (It's
your fault for asking for an example. I'm always just talking about the
general case. ;-)
I must admit to not really see when you need the information "it
got
changed, but I put it back as is" versus "unchanged and in same place".
Well, I think of "same_value" as meaning "that's not my register".
I
always imagined that a GUI display of all register values in a frame would
show all the values, but use a different grey for "same_value" than for
"undefined". For "same_value", I'd actually want the GUI to look
back at
the outer frames' CFI for that register until it found what frame the
visible value belongs to, so it was indicated visually somehow or you went
to that frame by clicking on that register, or whatever.
I'm not sure what "caller's register X located in my register X" (as
distinct from the DW_OP_stack_value case above) would mean different,
either. It's hard to see it ever being emitted. But I just don't like
the idea of our API hiding any distinctions that do exist in the CFI.
I couldn't find a definition for DW_OP_GNU_uninit. What does it
express?
Yeah, good question. It's no my list to take it up on archer and/or gcc
lists to get a good specification for it. It seems to be a not-really-used
feature that perhaps was never thought out or discussed very thoroughly.
AFAICT the concept is a magic suffix op on a location meaning "it's located
there, but by the way it's not initialized yet". Presumably it's in a
location list where the PC ranges after initialization use a location
description that's the same expression but without DW_OP_GNU_uninit tacked
on. I guess if you had a debugger that wanted to say "should I try to
print this yet, or hide the garbage?" it would help. OTOH, perhaps the
compiler would just omit the PC ranges where it's uninitialized from the
location list (equivalent to giving an empty location description for those
ranges), meaning "in scope, but unavailable here". The only use for the
location-with-uninit I can really see is so the debugger can install a
watchpoint that the initializer is expected to hit. But I haven't heard
anybody actually justify the feature with any particular use case like that.
I admit to liking the return value 0 with *NOPS zero means CFI says
the
caller's REGNO is same_value" here of the original better than using
DW_CFA_same_value as special marker.
Do you like DW_CFA_nop any better? ;-)
The main thing I want to do is use DW_OP_stack_value instead of something
else out-of-band for the DW_CFA_val_* cases. That's because it consolidates
more completely with location description handling so register-in-frame
locations feed naturally into generalized location-fiddling things in future.
The two special cases are undefined and same_value, and "length 0" can only
be one of them, so one of the two has to be something more awkward.
I'm open to suggestions.
Thanks,
Roland