This is the mail archive of the
mailing list for the GCC project.
Re: Expansion of __builtin_frame_address
Mark Mitchell <firstname.lastname@example.org> writes:
> Richard Sandiford wrote:
>> Mark Mitchell <email@example.com> writes:
>>> I'd suggest we leave backtrace() aside, and just talk about
>>> __builtin_frame_address(0), which does have well-defined semantics.
>>> _b_f_a(0) is currently broken on ARM, and we all agree we should fix it.
>> I don't want to fan the flames here, but I'm not sure either statement
>> is true. Does __builtin_frame_address(0) really have well-defined
>> semantics on a target for which the ABI does not specify a frame layout?
>> I think that's Richard's point.
> Thanks for explaining; after the latest messages from you and Richard
> E., I understand the ARM doesn't have a standard frame layout. I had
> not realized that before. However, even though there's not an ARM ABI
> layout, if GCC uses a standard layout, then it would make sense for
> _b_f_a(0) to return a pointer to that frame. (_b_f_a(0) is a GCC
> extension, so it can have a GCC-specific definition.)
> If even that condition does not hold, then I agree that _b_f_a(0) should
> just have undefined behavior on ARM. We might even consider making it
> an error to use it. We should document in the manual that you can't use
> _b_f_a(0) on reliably on some architectures.
Sounds like a good idea.
> Richard E. asked what possible uses this function might have.
> Obviously, GLIBC's backtrace() function is one, though I guess that's a
> weak example, in that we all agree one should really be using unwind
> information. (I still think it's somewhat valid, in that there are a
> lot of people building GCC-only applications, and if backtrace() worked
> in that case, it would be better than not working at all.) The other
> examples I can think of are also odd hacks; for example, checking for
> stack overwrites, manually poking ones own return address pointer, or
> manually grabbing saved registers from a caller, or some such.
I think it would be better to add builtin-functions that do the things
we think would be useful, and that we're prepared to keep working in
the forseeable future. Otherwise the knowledge about the exact stack
layout has to be pushed to each user's code, for each architecture that
the user supports.
For example, if all we want in the immediate term is to get a backtrace()
that works on ARM, and we have logic that we think would work, then we
should first make sure that __builtin_return_address(N) implements that
logic for N>0. To avoid quadrictness in backtrace() itself, we could
add new interfaces, such as a version of __builtin_return_address that
provides the return addresses for a range of call depths.
That probably sounds like a lot of work, but I'm not sure it is.
It might be something we could implement using our existing target hooks.
And it's probably less work than documenting what is and isn't guaranteed
about gcc's frame layout -- and its relation to __builtin_frame_address()
-- for each supported architecture.