struct Die [src]
Fields
tag_id: u64
has_children: bool
attrs: []Attr
Members
- getAttrString (Function)
Source
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(),
}
}
}