.ehframehdr

If you followed my last post, you will see that in order to unwind the stack you have to find the FDE associated with a given program counter value. There are two steps to this problem. The first one is finding the CIEs and FDEs at all. The second one is, given the set of FDEs, finding the one you need.

The old way this worked was that gcc would create a global constructor which called the function __register_frame_info, passing a pointer to the .eh_frame data and a pointer to the object. The latter pointer would indicate the shared library, and was used to deregister the information after a dlclose. When looking for an FDE, the unwinder would walk through the registered frames, and sort them. Then it would use the sorted list to find the desired FDE.

The old way still works, but these days, at least on GNU/Linux, the sorting is done at link time, which is better than doing it at runtime. Both gold and the GNU linker support an option --eh-frame-hdr which tell them to construct a header for all the .ehframe sections. This header is placed in a section named .ehframehdr and also in a PTGNUEHFRAME segment. At runtime the unwinder can find all the PT_GNU_EH_FRAME segments by calling dl_iterate_phdr.

The format of the .eh_frame_hdr section is as follows:

Since FDEs do not overlap, this table is sufficient for the stack unwinder to quickly find the relevant FDE if there is one.