Re: How to generate frame pointers on Cortex-M?

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

 



On Monday, May 20, 2019 11:33:39 PM CEST, Richard Earnshaw (lists) wrote:
On 20/05/2019 18:08, Vicente Bergas wrote:
On Monday, May 20, 2019 6:44:19 PM CEST, Richard Earnshaw (lists) wrote: ...

I'm not sure what you mean by 'reserved'.  The AAPCS does not reserve it.

I was meaning that r11 has an specific name assigned: fp, although it looks
like it is just for historical reasons for what follows.

GCC however, still occasionally needs to use a register for it's own
internal purposes of laying out a stack frame (when the value held in SP
cannot be kept invariant during a function).  In this case it creates
what it terms a frame pointer to point to the current stack frame and
uses that for addressing the local variables that reside on the stack
(normally it can eliminate this use and address such variables directly
via SP).  However, on Arm there's no mandated layout of the call saved
registers relative to where this register points and consequently it's
of no use for a forming a frame chain.

Things are further complicated due to the history of the architecture.
In the early days, when only the Arm (A32) instruction set existed, R11
was initially allocated as a traditional frame pointer and thus known as
FP.  There was a well formulized sequence for creating a stack frame
which included a frame chain.

But then the original thumb instruction set came along, which couldn't
use r11 for addressing memory (as it wasn't in the register subset
r0-r7,sp,pc which had instructions for making such accesses).  At such
point the APCS frame pointer (r11) became deprecated.  Furthermore,
compilers started using r7 for the internal uses of a frame pointer when
SP could not be used in thumb code, but continued to use r11 in Arm
code.  But it's then impossible to create a frame chain as Arm and Thumb
functions can call each other and it is far to expensive for a function
to have to work out which of r7 and r11 is a frame pointer at every call
site.  Frame pointers, however, were fortunately becoming much less
important to debugging by this point as object file formats such as ELF
could support rich debug information formats, such as Dwarf.  So the
decision was taken in the ATPCS to drop the concept of a global frame
pointer entirely, allowing compilers do generate whatever code sequences
provided the best code and to then use Dwarf to describe to debugging
tools how to reconstruct the call hierarchy when necessary.

OK, I see. Thanks for this extensive history review. It is really
appreciated to know why things are the way they are.

However, there are some environments where a very simple stack-based
chain can prove very useful, because it is expensive to have to decode
the dwarf unwind data on the fly (it doesn't usually matter in debuggers
since the target program is normally stopped when unwinding is being
done).  So we are looking at what options are available to us at this
point.  In the mean time your only real option is either something you
construct yourself, or to use the information recorded in either the
dwarf data or the C++ exception unwinding tables (you can ask GCC to
include this even when compiling languages other than C).

R.

I've already solved my issue with an stack on the application. Anyways,
those unwinding tables are interesting. You are talking about using
-funwind-tables with (e.g.) plain C, aren't you?

Regards,
 Vicenç.





[Index of Archives]     [Linux C Programming]     [Linux Kernel]     [eCos]     [Fedora Development]     [Fedora Announce]     [Autoconf]     [The DWARVES Debugging Tools]     [Yosemite Campsites]     [Yosemite News]     [Linux GCC]

  Powered by Linux