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,
};
}