[roll] Roll fuchsia [arm64][exceptions] Include ELR in EL1 backtraces

When we take a synchronous exception from EL1 -> EL1, synthesize a
fake frame from the current frame pointer (at the time the exception
was taken) and the current ELR.  This way, if the exception is fatal,
we will automatically include the ELR in the backtrace generated and
sent to the serial port and crashlog.  This can then be automatically
symbolized, and help to save a bit of time for folks attempting to
triage kernel crashes.

This is accomplished by doing two things.

First, we modify the layout of our iframe structure.  This is the
structure that we store our registers in when we take an exception.
The layout is arbitrary, and we are free to change it as we see fit.
Prior to this, the  layout looked something like this:

```
[x0 - x29]
x30/LR
USP
ELR
SPSR
```

This CL swaps the position of the LR/USP and ELR/SPSR pairs, giving
us:

```
[x0 - x29]
ELR
SPSR
x30/LR
USP
```

So, we have re-arranged the structure so that where we used to have
`x29/x30` next to each other, we now have `x29/ELR`.  We've also done
it in such a way that we have kept all of the pairs of registers in
the structure together.

When registers are saved and restored during exceptions, they are
stored and loaded using the ARM load/store-pair instructions.  By
keeping pairs together and only changing their offsets in the
structure, we don't have to change _any_ of the existing structure of
the code which does the saving and loading.

And, now that we have `x29` next to `ELR` in the iframe layout, we can
pull one more trick.

When we fault, `x29` holds the value of the frame pointer at the time
of the exception, while ELR holds the address of where the synchronous
exception happened.  This is basically identical to the definition of
a frame according to the ARM ABI.  Now, just before jumping into the
C/C++ level of exception handing, if we load `x29` with a value
pointing to `x29` in our iframe, we have make it look like there is a
new "exception handler frame" on the stack.  After this, when we
render a backtrace (to dump to the serial port, or to stuff into a
crashlog) it will automatically include the instruction where the
fault actually happened as a level of the stack, allowing it to be
automatically symbolized by `ffx debug symbolize`.

While the change in structure layout affects all EL1 exception
handlers, the loading of `x29` happens only in synchronous EL1 to EL1
exceptions, which really should only happen when attempting to access
user-memory and hitting a serviceable page fault, or when taking a
fatal exception.

Please note that most of this information (esp the value of the ELR)
is already in these crash-dumps.  Unfortunately, the tools which
symbolise the backtraces don't know that they need to look for the
ELR, nor do they have unambiguous knowledge of where the ELR belongs
in the backtrace, although adding a bit more information is probably
all it would take to nail it down precisely.  Reworking the code which
produces the backtraces as well as the code which interprets them can
achieve similar results, however it is significantly more work than
this small tweak.

So, add this tweak for now.  Someday in the future when we have
consolidated our backtrace handling, we can come back here and remove
this approach and save an instruction in the process.

Original-Reviewed-on: https://fuchsia-review.googlesource.com/c/fuchsia/+/1441275
Original-Revision: bed3d091d1bea9658a5ef38b85e275107e063db9
GitOrigin-RevId: 6be84bd3f0a30fc2530eb58c58a646ff52f0a3f9
Change-Id: I02c84fe48a57b25db0a1315f91f9f73d85972cbd
1 file changed
tree: 4a1db74518068afc9720782629bc6fe47413c7e8
  1. ctf/
  2. git-hooks/
  3. infra/
  4. third_party/
  5. flower
  6. jiri.lock
  7. MILESTONE
  8. minimal
  9. prebuilts
  10. README.md
  11. stem
  12. test_durations
README.md

Integration

This repository contains Fuchsia's Global Integration manifest files.

Making changes

All changes should be made to the internal version of this repository. Our infrastructure automatically updates this version when the internal one changes.

Currently all changes must be made by a Google employee. Non-Google employees wishing to make a change can ask for assistance in one of the communication channels documented at get involved.

Obtaining the source

First install Jiri.

Next run:

$ jiri init
$ jiri import minimal https://fuchsia.googlesource.com/integration
$ jiri update

Third party

Third party projects should have their own subdirectory in ./third_party.