DoxigAlpha

read

Reads a header for either an FDE or a CIE, then advances the fbr to the position after the trailing structure. fbr must be a FixedBufferReader backed by either the .eh_frame or .debug_frame sections.

Function parameters

Parameters

#
fbr:*FixedBufferReader
opt_ma:?*MemoryAccessor
dwarf_section:Section.Id

Type definitions in this namespace

Types

#
ExceptionFrameHeader
This represents the decoded .eh_frame_hdr header

Initialize DWARF info.

Functions

#
open
Initialize DWARF info.
findCompileUnit
TODO: change this to binary searching the sorted compile unit list
scanAllUnwindInfo
If `.eh_frame_hdr` is present, then only the header needs to be parsed.
scanCieFdeInfo
Scan `.eh_frame` and `.debug_frame` and build a sorted list of FDEs for binary searching during
compactUnwindToDwarfRegNumber
Returns the DWARF register number for an x86_64 register number found in compact unwind info
bad
This function is to make it handy to comment out the return and make it

Error sets in this namespace

Error Sets

#

= [_]?Section{null} ** num_sections

Values

#
null_section_array
= [_]?Section{null} ** num_sections

Source

Implementation

#
pub fn read(
    fbr: *FixedBufferReader,
    opt_ma: ?*MemoryAccessor,
    dwarf_section: Section.Id,
) !EntryHeader {
    assert(dwarf_section == .eh_frame or dwarf_section == .debug_frame);

    const length_offset = fbr.pos;
    const unit_header = try readUnitHeader(fbr, opt_ma);
    const unit_length = cast(usize, unit_header.unit_length) orelse return bad();
    if (unit_length == 0) return .{
        .length_offset = length_offset,
        .format = unit_header.format,
        .type = .terminator,
        .entry_bytes = &.{},
    };
    const start_offset = fbr.pos;
    const end_offset = start_offset + unit_length;
    defer fbr.pos = end_offset;

    const id = try if (opt_ma) |ma|
        fbr.readAddressChecked(unit_header.format, ma)
    else
        fbr.readAddress(unit_header.format);
    const entry_bytes = fbr.buf[fbr.pos..end_offset];
    const cie_id: u64 = switch (dwarf_section) {
        .eh_frame => CommonInformationEntry.eh_id,
        .debug_frame => switch (unit_header.format) {
            .@"32" => CommonInformationEntry.dwarf32_id,
            .@"64" => CommonInformationEntry.dwarf64_id,
        },
        else => unreachable,
    };

    return .{
        .length_offset = length_offset,
        .format = unit_header.format,
        .type = if (id == cie_id) .cie else .{ .fde = switch (dwarf_section) {
            .eh_frame => try std.math.sub(u64, start_offset, id),
            .debug_frame => id,
            else => unreachable,
        } },
        .entry_bytes = entry_bytes,
    };
}