Skip to content

bare-metal libunwind implementation, for supporting C++ exceptions in EFI apps and OS kernels

License

Notifications You must be signed in to change notification settings

davmac314/bmunwind

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

7 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

bmunwind - bare-metal "libunwind" implementation

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.

Use

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.

Building

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.

Use with Dwarf 2 EH unwinding mechanism

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.

Requirements

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).

Background documentation

For details about the Itanium C++ ABI and the functions provided by BMCXXABI, see:

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:

About

bare-metal libunwind implementation, for supporting C++ exceptions in EFI apps and OS kernels

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published