structstd.debug.Dwarf.Die[src]

Fields

tag_id: u64
has_children: bool
attrs: []Attr

Functions

FunctiongetAttrString[src]

pub fn getAttrString( self: *const Die, di: *Dwarf, id: u64, opt_str: ?[]const u8, compile_unit: CompileUnit, ) error{ InvalidDebugInfo, MissingDebugInfo }![]const u8

Parameters

self: *const Die
di: *Dwarf
id: u64
opt_str: ?[]const u8
compile_unit: CompileUnit

Source Code

Source code
pub fn getAttrString(
    self: *const Die,
    di: *Dwarf,
    id: u64,
    opt_str: ?[]const u8,
    compile_unit: CompileUnit,
) error{ InvalidDebugInfo, MissingDebugInfo }![]const u8 {
    const form_value = self.getAttr(id) orelse return error.MissingDebugInfo;
    switch (form_value.*) {
        .string => |value| return value,
        .strp => |offset| return di.getString(offset),
        .strx => |index| {
            const debug_str_offsets = di.section(.debug_str_offsets) orelse return bad();
            if (compile_unit.str_offsets_base == 0) return bad();
            switch (compile_unit.format) {
                .@"32" => {
                    const byte_offset = compile_unit.str_offsets_base + 4 * index;
                    if (byte_offset + 4 > debug_str_offsets.len) return bad();
                    const offset = mem.readInt(u32, debug_str_offsets[byte_offset..][0..4], di.endian);
                    return getStringGeneric(opt_str, offset);
                },
                .@"64" => {
                    const byte_offset = compile_unit.str_offsets_base + 8 * index;
                    if (byte_offset + 8 > debug_str_offsets.len) return bad();
                    const offset = mem.readInt(u64, debug_str_offsets[byte_offset..][0..8], di.endian);
                    return getStringGeneric(opt_str, offset);
                },
            }
        },
        .line_strp => |offset| return di.getLineString(offset),
        else => return bad(),
    }
}

Source Code

Source code
pub const Die = struct {
    tag_id: u64,
    has_children: bool,
    attrs: []Attr,

    const Attr = struct {
        id: u64,
        value: FormValue,
    };

    fn deinit(self: *Die, allocator: Allocator) void {
        allocator.free(self.attrs);
        self.* = undefined;
    }

    fn getAttr(self: *const Die, id: u64) ?*const FormValue {
        for (self.attrs) |*attr| {
            if (attr.id == id) return &attr.value;
        }
        return null;
    }

    fn getAttrAddr(
        self: *const Die,
        di: *const Dwarf,
        id: u64,
        compile_unit: CompileUnit,
    ) error{ InvalidDebugInfo, MissingDebugInfo }!u64 {
        const form_value = self.getAttr(id) orelse return error.MissingDebugInfo;
        return switch (form_value.*) {
            .addr => |value| value,
            .addrx => |index| di.readDebugAddr(compile_unit, index),
            else => bad(),
        };
    }

    fn getAttrSecOffset(self: *const Die, id: u64) !u64 {
        const form_value = self.getAttr(id) orelse return error.MissingDebugInfo;
        return form_value.getUInt(u64);
    }

    fn getAttrUnsignedLe(self: *const Die, id: u64) !u64 {
        const form_value = self.getAttr(id) orelse return error.MissingDebugInfo;
        return switch (form_value.*) {
            .Const => |value| value.asUnsignedLe(),
            else => bad(),
        };
    }

    fn getAttrRef(self: *const Die, id: u64, unit_offset: u64, unit_len: u64) !u64 {
        const form_value = self.getAttr(id) orelse return error.MissingDebugInfo;
        return switch (form_value.*) {
            .ref => |offset| if (offset < unit_len) unit_offset + offset else bad(),
            .ref_addr => |addr| addr,
            else => bad(),
        };
    }

    pub fn getAttrString(
        self: *const Die,
        di: *Dwarf,
        id: u64,
        opt_str: ?[]const u8,
        compile_unit: CompileUnit,
    ) error{ InvalidDebugInfo, MissingDebugInfo }![]const u8 {
        const form_value = self.getAttr(id) orelse return error.MissingDebugInfo;
        switch (form_value.*) {
            .string => |value| return value,
            .strp => |offset| return di.getString(offset),
            .strx => |index| {
                const debug_str_offsets = di.section(.debug_str_offsets) orelse return bad();
                if (compile_unit.str_offsets_base == 0) return bad();
                switch (compile_unit.format) {
                    .@"32" => {
                        const byte_offset = compile_unit.str_offsets_base + 4 * index;
                        if (byte_offset + 4 > debug_str_offsets.len) return bad();
                        const offset = mem.readInt(u32, debug_str_offsets[byte_offset..][0..4], di.endian);
                        return getStringGeneric(opt_str, offset);
                    },
                    .@"64" => {
                        const byte_offset = compile_unit.str_offsets_base + 8 * index;
                        if (byte_offset + 8 > debug_str_offsets.len) return bad();
                        const offset = mem.readInt(u64, debug_str_offsets[byte_offset..][0..8], di.endian);
                        return getStringGeneric(opt_str, offset);
                    },
                }
            },
            .line_strp => |offset| return di.getLineString(offset),
            else => return bad(),
        }
    }
}