Zig 0.17.0-dev (Split by item)

This is an example of documentation generated by ZigDoc, an alternative to Zig's built-in Auto Doc feature. See also examples in other modes/formats. The project being documented here (as the example) is the Zig library itself.

scanAllCompileUnits

Dwarf.scanAllCompileUnits
fn scanAllCompileUnits(di: *Dwarf, gpa: Allocator, endian: Endian) ScanError!void

File

lib/std/debug/Dwarf.zig:570

Code

fn scanAllCompileUnits(di: *Dwarf, gpa: Allocator, endian: Endian) ScanError!void {
    var fr: Reader = .fixed(di.section(.debug_info).?);
    var this_unit_offset: u64 = 0;

    var attrs_buf = std.array_list.Managed(Die.Attr).init(gpa);
    defer attrs_buf.deinit();

    while (this_unit_offset < fr.buffer.len) {
        fr.seek = @intCast(this_unit_offset);

        const unit_header = try readUnitHeader(&fr, endian);
        if (unit_header.unit_length == 0) return;
        const next_offset = unit_header.header_length + unit_header.unit_length;

        const version = try fr.takeInt(u16, endian);
        if (version < 2 or version > 5) return bad();

        var address_size: u8 = undefined;
        var debug_abbrev_offset: u64 = undefined;
        if (version >= 5) {
            const unit_type = try fr.takeByte();
            if (unit_type != UT.compile) return bad();
            address_size = try fr.takeByte();
            debug_abbrev_offset = try readFormatSizedInt(&fr, unit_header.format, endian);
        } else {
            debug_abbrev_offset = try readFormatSizedInt(&fr, unit_header.format, endian);
            address_size = try fr.takeByte();
        }

        const abbrev_table = try di.getAbbrevTable(gpa, debug_abbrev_offset);

        var max_attrs: usize = 0;
        for (abbrev_table.abbrevs) |abbrev| {
            max_attrs = @max(max_attrs, abbrev.attrs.len);
        }
        try attrs_buf.resize(max_attrs);

        var compile_unit_die = (try parseDie(
            &fr,
            attrs_buf.items,
            abbrev_table,
            unit_header.format,
            endian,
            address_size,
        )) orelse return bad();

        if (compile_unit_die.tag_id != DW.TAG.compile_unit) return bad();

        compile_unit_die.attrs = try gpa.dupe(Die.Attr, compile_unit_die.attrs);

        var compile_unit: CompileUnit = .{
            .version = version,
            .format = unit_header.format,
            .addr_size_bytes = address_size,
            .pc_range = null,
            .die = compile_unit_die,
            .str_offsets_base = if (compile_unit_die.getAttr(AT.str_offsets_base)) |fv| try fv.getUInt(usize) else 0,
            .addr_base = if (compile_unit_die.getAttr(AT.addr_base)) |fv| try fv.getUInt(usize) else 0,
            .rnglists_base = if (compile_unit_die.getAttr(AT.rnglists_base)) |fv| try fv.getUInt(usize) else 0,
            .loclists_base = if (compile_unit_die.getAttr(AT.loclists_base)) |fv| try fv.getUInt(usize) else 0,
            .frame_base = compile_unit_die.getAttr(AT.frame_base),
            .src_loc_cache = null,
        };

        compile_unit.pc_range = x: {
            if (compile_unit_die.getAttrAddr(di, endian, AT.low_pc, &compile_unit)) |low_pc| {
                if (compile_unit_die.getAttr(AT.high_pc)) |high_pc_value| {
                    const pc_end = switch (high_pc_value.*) {
                        .addr => |value| value,
                        .udata => |offset| low_pc + offset,
                        else => return bad(),
                    };
                    break :x PcRange{
                        .start = low_pc,
                        .end = pc_end,
                    };
                } else {
                    break :x null;
                }
            } else |err| {
                if (err != error.MissingDebugInfo) return err;
                break :x null;
            }
        };

        try di.compile_unit_list.append(gpa, compile_unit);

        this_unit_offset += next_offset;
    }
}