D-12 Unwind table location
Christophe de Dinechin
ddd at cup.hp.com
Wed Feb 16 19:44:11 UTC 2000
Jim,
Jim Dehnert wrote:
> I'm afraid I still haven't made my position clear. So I'll try once
> more, briefly. I want to have a definition that will _allow_ an
> implementation to put the various unwind tables in arbitrary segments,
> without changing their format (and therefore without modifying anything
> in the compiler except the segment choice).
I did understand what you want. What I did not understand is why. This has a
non-zero cost (see below), and I don't see anything you can do with that that
you can't do with the current scheme.
>
> > Correct. As I said, this makes this representation efficient both from a
> > run-time and load-time point of view. Since I don't see any use of splitting
> > .unwind from .text, I am not willing to pay an extra penalty
> > accessing/relocating LPStart for no purpose.
>
> This is the key. Where is the cost? Suppose that the unwind table has
> associated with it two segment pointers, for the unwind info table and
> the text segment. Then the unwind info pointers in the unwind table
> can be relative to the first (not so important since that's under the
> covers), and the LPStart pointers can be relative to the second). If
> the unwind library puts them in the exception object each time it
> locates a new frame, then we have a small number of cache hits per
> frame, all happening in parallel with other memory references that
> often won't be hits. I think that cost is somewhere between zero and
> negligible.
>
The key problem I see is the following: to get the unwind address from the
function address, all you need today is a mechanism that, from the IP, gets the
text segment, which is fairly trivial. Then everything is relative to the text
segment.
However, two identical IP addresses may _not_ correspond to the same GP under
the current ABI (consider two instances of a same shared lib). In other words,
if you want to recover a GP from the IP, you need some magic. The magic we do
currently is that you go to the unwind info block, which contains unwind records
indicating where the GP was saved, and you recover it. That's the value that we
ultimately get from Unwind_GetGR(GP). The process that led to GP did not require
any dld support beyond the IP->text segment translation. Everything after that
is made of self-relative or text-relative offsets.
If the unwind info block is to be placed in a different segment, then you need a
_writable_ pointer to point to that segment (since the segment address is
allocated by the dynamic loader, whether text or data). So the unwind table (or
part of it) has to go to writable data, and become GP-relative. Then, some
really black magic has to occur to make sure that we can recover the initial GP
we need for unwinding. This black magic also needs to have debugger support,
etc, etc.
Also, this whole process becomes also a lot more fragile, since it starts at a
writable pointer, so a corruption of this pointer prevents any unwinding from
happening.
Last, but not least, I can't imagine going to our dld, linker, debugger, backend
and ABI folks and tell them: you need to change the location of the unwind info
block (or unwind table) without a very good reason. Remember that the location
of the unwind tables and unwind info block, and their format, are part of what
we call the C ABI, not the C++ ABI.
Regards
Christophe
More information about the cxx-abi-dev
mailing list