# Unwinder Support Per Android Release
This document describes the changes in the way the libunwindstack
unwinder works on different Android versions. It does not describe
every change in the code made between different versions, but is
meant to allow an app developer to know what might be supported
on different versions. It also describes the different way an unwind
will display on different versions of Android.

## Android 9 ("Pie", API level 28)
libunwindstack was first introduced in API level 28.

* Supports up to and including Dwarf 4 unwinding information.
  See http://dwarfstd.org/ for Dwarf standards.
* Supports Arm exidx unwinding.
* Supports the gdb JIT unwinding interface, which is how ART creates unwinding
  information for the JIT'd Java frames.
* Supports special frames added to represent an ART Java interpreter frame.
  ART has marked the dex pc using cfi information that the unwinder
  understands and handles by adding a new frame in the stacktrace.

## Note
By default, lld creates two separate maps of the elf in memory, one read-only
and one read/executable. The libunwindstack on P and the unwinder on older
versions of Android will not unwind properly in this case. For apps that
target API level 28 or older, make sure that `-Wl,--no-rosegment` is
included in linker arguments when using lld.

## Android 10 ("Q", API level 29)
* Fix bug (b/109824792) that handled load bias data incorrectly when
  FDEs use pc relative addressing in the eh\_frame\_hdr.
  Unfortunately, this wasn't fixed correctly in Q since it assumes
  that the bias is coming from the program header for the executable
  load. The real fix was to use the bias from the actual section data and
  is not completely fixed until API level 30. For apps targeting API level 29,
  if it is being compiled with the llvm linker lld, it might be necessary
  to add the linker option `-Wl,-zseparate-code` to avoid creating an elf
  created this way.
* Change the way the exidx section offset is found (b/110704153). Before
  the p\_vaddr value from the program header minus the load bias was used
  to find the start of the exidx data. Changed to use the p\_offset since
  it doesn't require any load bias manipulations.
* Fix bug handling of dwarf sections without any header (b/110235461).
  Previously, the code assumed that FDEs are non-overlapping, and the FDEs
  are always in sorted order from low pc to high pc. Thus the code would
  read the entire set of CIEs/FDEs and then do a binary search to find
  the appropriate FDE for a given pc. Now the code does a sequential read
  and stops when it finds the FDE for a pc. It also understands the
  overlapping FDEs, so find the first FDE that matches a pc. In practice,
  elf files with this format only ever occurs if the file was generated
  without an eh\_frame/eh\_frame\_hdr section and only a debug\_frame. The
  other way this has been observed is when running simpleperf to unwind since
  sometimes there is not enough information in the eh\_frame for all points
  in the executable. On API level 28, this would result in some incorrect
  unwinds coming from simpleperf. Nearly all crashes from API level 28 should
  be correct since the eh\_frame information was enough to do the unwind
  properly.
* Be permissive of badly formed elf files. Previously, any detected error
  would result in unwinds stopping even if there is enough valid information
  to do an unwind.
  * The code now allows program header/section header offsets to point
    to unreadable memory. As long as the code can find the unwind tables,
    that is good enough.
  * The code allows program headers/section headers to be missing.
  * Allow a symbol table section header to point to invalid symbol table
    values.
* Support for the linker read-only segment option (b/109657296).
  This is a feature of lld whereby there are two sections that
  contain elf data. The first is read-only and contains the elf header data,
  and the second is read-execute or execute only that
  contains the executable code from the elf. Before this, the unwinder
  always assumed that there was only a single read-execute section that
  contained the elf header data and the executable code.
* Build ID information for elf objects added. This will display the
  NT\_GNU\_BUILD\_ID note found in elf files. This information can be used
  to identify the exact version of a shared library to help get symbol
  information when looking at a crash.
* Add support for displaying the soname from an apk frame. Previously,
  a frame map name would be only the apk, but now if the shared library
  in the apk has set a soname, the map name will be `app.apk!libexample.so`
  instead of only `app.apk`.
* Minimal support for Dwarf 5. This merely treats a Dwarf 5 version
  elf file as Dwarf 4. It does not support the new dwarf ops in Dwarf 5.
  Since the new ops are not likely to be used very often, this allows
  continuing to unwind even when encountering Dwarf 5 elf files.
* Fix bug in pc handling of signal frames (b/130302288). In the previous
  version, the pc would be wrong in the signal frame. The rest of the
  unwind was correct, only the frame in the signal handler was incorrect
  in API level 28.
* Detect when an elf file is not readable so that a message can be
  displayed indicating that. This can happen when an app puts the shared
  libraries in non-standard locations that are not readable due to
  security restrictions (selinux rules).

## Android 11 ("R", API level 30)
* Display the offsets for Java interpreter frames. If this frame came
  from a non-zero offset map, no offset is printed. Previously, the
  line would look like:

    #17 pc 00500d7a  GoogleCamera.apk (com.google.camera.AndroidPriorityThread.run+10)

  to:

    #17 pc 00500d7a  GoogleCamera.apk (offset 0x11d0000) (com.google.camera.AndroidPriorityThread.run+10)
* Fix bug where the load bias was set from the first PT\_LOAD program
  header that has a zero p\_offset value. Now it is set from the first
  executable PT\_LOAD program header. This has only ever been a problem
  for host executables compiled for the x86\_64 architecture.
* Switched to the libc++ demangler for function names. Previously, the
  demangler used was not complete, so some less common demangled function
  names would not be properly demangled or the function name would not be
  demangled at all.
* Fix bug in load bias handling. If the unwind information in the eh\_frame
  or eh\_frame\_hdr does not have the same bias as the executable section,
  and uses pc relative FDEs, the unwind will be incorrect. This tends
  to truncate unwinds since the unwinder could not find the correct unwind
  information for a given pc.

## Android 12 ("S", API level 31)
* Fix bug where, if a shared library is dlopen'ed from within an apk file,
  is not readable, and the shared library only produces a single read-
  executable map for the elf data and executable data, the offset into the
  apk will not be displayed. Previously the line would look like:

    #01 pc 000000000222675c  GoogleCamera.apk

  to:

    #01 pc 000000000222675c  GoogleCamera.apk (offset 0x269f000)

  If the apk file is readable, or dlopen'ing the shared library creates
  a read-only map of the elf data, and a read-executable map of the
  code, the offset will be displayed properly without this fix.
