Function scanAllUnwindInfo [src]

If .eh_frame_hdr is present, then only the header needs to be parsed. Otherwise, .eh_frame and .debug_frame are scanned and a sorted list of FDEs is built for binary searching during unwinding. Even if .eh_frame_hdr is used, we may find during unwinding that it's incomplete, in which case we build the sorted list of FDEs at that point. See also scanCieFdeInfo.

Prototype

pub fn scanAllUnwindInfo(di: *Dwarf, allocator: Allocator, base_address: usize) !void

Parameters

di: *Dwarfallocator: Allocatorbase_address: usize

Source

pub fn scanAllUnwindInfo(di: *Dwarf, allocator: Allocator, base_address: usize) !void { if (di.section(.eh_frame_hdr)) |eh_frame_hdr| blk: { var fbr: FixedBufferReader = .{ .buf = eh_frame_hdr, .endian = native_endian }; const version = try fbr.readByte(); if (version != 1) break :blk; const eh_frame_ptr_enc = try fbr.readByte(); if (eh_frame_ptr_enc == EH.PE.omit) break :blk; const fde_count_enc = try fbr.readByte(); if (fde_count_enc == EH.PE.omit) break :blk; const table_enc = try fbr.readByte(); if (table_enc == EH.PE.omit) break :blk; const eh_frame_ptr = cast(usize, try readEhPointer(&fbr, eh_frame_ptr_enc, @sizeOf(usize), .{ .pc_rel_base = @intFromPtr(&eh_frame_hdr[fbr.pos]), .follow_indirect = true, }) orelse return bad()) orelse return bad(); const fde_count = cast(usize, try readEhPointer(&fbr, fde_count_enc, @sizeOf(usize), .{ .pc_rel_base = @intFromPtr(&eh_frame_hdr[fbr.pos]), .follow_indirect = true, }) orelse return bad()) orelse return bad(); const entry_size = try ExceptionFrameHeader.entrySize(table_enc); const entries_len = fde_count * entry_size; if (entries_len > eh_frame_hdr.len - fbr.pos) return bad(); di.eh_frame_hdr = .{ .eh_frame_ptr = eh_frame_ptr, .table_enc = table_enc, .fde_count = fde_count, .entries = eh_frame_hdr[fbr.pos..][0..entries_len], }; // No need to scan .eh_frame, we have a binary search table already return; } try di.scanCieFdeInfo(allocator, base_address); }