LLVM libunwind, repackaged/augmented and renamed by D. McCall - davmac@davmac.org
This is an implementation of the "libunwind" interface, specified via the _Unwind* functions in the Itanium C++ ABI. It provides part of the runtime support necessary for throwing and handling exceptions in C++ code, and is specifically targeted at "bare metal" applications such as operating system kernels and EFI applications.
It is actually a fork of libunwind from LLVM. The LLVM version has some support for building a "bare metal" version, but needs to be be built as part of the LLVM ecosystem, and in any case needed further work before it was properly usable. This fork completes that work, and allows building separately from LLVM. The original CMake build system has been left in place, for now, but should not be used; it has been supplanted by a plain makefile-based build system.
See LICENSE.TXT file for licensing details (this is the original file from LLVM libunwind). Note that the CREDITS.TXT file mentioned within does not exist in the original project. As I understand it, libunwind can be redistributed under a choice of several licenses, including the MIT license.
The original LLVM libunwind seems to have support for numerous unwind information formats and mechanisms: "Dwarf 2 EH" (as used in Linux for at least the x86-64/i386 architecture), "ARM EHABI", "SEH" (Windows structure exception handling), a "compact" unwinding format (used on Mac OS) and a "setjmp-longjmp" based mechanism. The "Dwarf 2" support has been tested; to use it follow the instructions below. Support for other mechanisms has not been removed and may or may not work; you are on your own if you use it (improvements to this documentation are welcome).
Regardless of the mechanism, to use bmunwind, you need to:
- export some symbols which bmunwind will use to location the unwind information (see details for Dwarf 2 EH below)
- build bmunwind and link it (libunwind.a) to your bare-metal application. See the next section.
bmwind (libunwind.a) can be built by running "make" at the top-level of the source tree.
Use make OUTDIR=<some-directory>
to specify the output directory for the library. Read the
Makefile for further details, including how to specify build options.
It is expected that projects using bmunwind will incorporate it into their source tree. Building as a standalone library doesn't make much sense, since the necessary build options will vary between applications.
The .eh_frame
section contains two types of entry, "CIE" (common information entry) and "FDE"
(frame description entry). A CIE may have any number of associated FDEs. These records are
generated by the compiler. When linking the application, all .eh_frame
sections from object
files should be concatenated into a single section. Bmunwind requires that the symbol
__eh_frame_start
point to the beginning of the .eh_frame
section and the __eh_frame_end
symhol point just past the section's end; this can typically be arranged via a linker script
containing something like:
.eh_frame : {
PROVIDE (__eh_frame_start = .);
KEEP(*(.eh_frame .eh_frame.*))
PROVIDE (__eh_frame_end = .);
}
The .eh_frame_hdr
section (if present) contains an index of the FDEs in the .eh_frame
section,
sorted so that it can be searched using a binary search. This improves the performance of
unwinding. The __eh_frame_hdr_start
and __eh_frame_hdr_end
symbols point to the start and end
of the section; if they are equal, the section is assumed not present (bmunwind will still work,
but unwinding may be slower).
The .eh_frame_hdr
section can be generated automatically by GNU ld, via the --eh-frame-hdr
option when producing an executable. The __eh_frame_hdr_start
/_end
symbols should be generated
via the client application's linker script.
Bmunwind can build against a small set of C/C++ headers. The only functions it should typically
require are abort
, memcpy
and memset
.
For C++ exception support, bmunwind must be paired with a C++ ABI runtime support library, such as bmcxxabi (https://github.com/davmac314/bmcxxabi).
For details about the Itanium C++ ABI and the functions provided by BMCXXABI, see:
- https://itanium-cxx-abi.github.io/cxx-abi/abi-eh.html
- https://refspecs.linuxfoundation.org/cxxabi-1.86.html
- https://refspecs.linuxfoundation.org/LSB_3.0.0/LSB-Core-generic/LSB-Core-generic/ehframechpt.html
Note that even in these "official" "specifications", details tend to be sketchy or missing. For more complete and accurate information, check these blog entries from Ian Lance Taylor:
- https://www.airs.com/blog/archives/460 (.eh_frame)
- https://www.airs.com/blog/archives/462 (.eh_frame_hdr)
- https://www.airs.com/blog/archives/464 (.gcc_except)