Function parse [src]
This function expects to read the FDE starting at the PC Begin field.
The returned struct references memory backed by fde_bytes.
pc_rel_offset specifies an offset to be applied to pc_rel_base values
used when decoding pointers. This should be set to zero if fde_bytes is
backed by the memory of a .eh_frame / .debug_frame section in the running executable.
Otherwise, it should be the relative offset to translate addresses from
where the section is currently stored in memory, to where it would be
stored at runtime: section base addr - backing data base ptr.
Similarly, is_runtime specifies this function is being called on a runtime
section, and so indirect pointers can be followed.
Prototype
pub fn parse( fde_bytes: []const u8, pc_rel_offset: i64, is_runtime: bool, cie: CommonInformationEntry, addr_size_bytes: u8, endian: std.builtin.Endian, ) !FrameDescriptionEntry
Parameters
fde_bytes: []const u8
pc_rel_offset: i64
is_runtime: bool
cie: CommonInformationEntry
addr_size_bytes: u8
endian: std.builtin.Endian
Source
pub fn parse(
fde_bytes: []const u8,
pc_rel_offset: i64,
is_runtime: bool,
cie: CommonInformationEntry,
addr_size_bytes: u8,
endian: std.builtin.Endian,
) !FrameDescriptionEntry {
if (addr_size_bytes > 8) return error.InvalidAddrSize;
var fbr: FixedBufferReader = .{ .buf = fde_bytes, .endian = endian };
const pc_begin = try readEhPointer(&fbr, cie.fde_pointer_enc, addr_size_bytes, .{
.pc_rel_base = try pcRelBase(@intFromPtr(&fde_bytes[fbr.pos]), pc_rel_offset),
.follow_indirect = is_runtime,
}) orelse return bad();
const pc_range = try readEhPointer(&fbr, cie.fde_pointer_enc, addr_size_bytes, .{
.pc_rel_base = 0,
.follow_indirect = false,
}) orelse return bad();
var aug_data: []const u8 = &[_]u8{};
const lsda_pointer = if (cie.aug_str.len > 0) blk: {
const aug_data_len = try fbr.readUleb128(usize);
const aug_data_start = fbr.pos;
aug_data = fde_bytes[aug_data_start..][0..aug_data_len];
const lsda_pointer = if (cie.lsda_pointer_enc != EH.PE.omit)
try readEhPointer(&fbr, cie.lsda_pointer_enc, addr_size_bytes, .{
.pc_rel_base = try pcRelBase(@intFromPtr(&fde_bytes[fbr.pos]), pc_rel_offset),
.follow_indirect = is_runtime,
})
else
null;
fbr.pos = aug_data_start + aug_data_len;
break :blk lsda_pointer;
} else null;
const instructions = fde_bytes[fbr.pos..];
return .{
.cie_length_offset = cie.length_offset,
.pc_begin = pc_begin,
.pc_range = pc_range,
.lsda_pointer = lsda_pointer,
.aug_data = aug_data,
.instructions = instructions,
};
}