Function resolveValue [src]

Resolves the register rule and places the result into out (see regBytes)

Prototype

pub fn resolveValue( self: Column, context: *SelfInfo.UnwindContext, expression_context: std.debug.Dwarf.expression.Context, ma: *std.debug.MemoryAccessor, out: []u8, ) !void

Parameters

self: Columncontext: *SelfInfo.UnwindContextexpression_context: std.debug.Dwarf.expression.Contextma: *std.debug.MemoryAccessorout: []u8

Source

pub fn resolveValue( self: Column, context: *SelfInfo.UnwindContext, expression_context: std.debug.Dwarf.expression.Context, ma: *std.debug.MemoryAccessor, out: []u8, ) !void { switch (self.rule) { .default => { const register = self.register orelse return error.InvalidRegister; try getRegDefaultValue(register, context, out); }, .undefined => { @memset(out, undefined); }, .same_value => { // TODO: This copy could be eliminated if callers always copy the state then call this function to update it const register = self.register orelse return error.InvalidRegister; const src = try regBytes(context.thread_context, register, context.reg_context); if (src.len != out.len) return error.RegisterSizeMismatch; @memcpy(out, src); }, .offset => |offset| { if (context.cfa) |cfa| { const addr = try applyOffset(cfa, offset); if (ma.load(usize, addr) == null) return error.InvalidAddress; const ptr: *const usize = @ptrFromInt(addr); mem.writeInt(usize, out[0..@sizeOf(usize)], ptr.*, native_endian); } else return error.InvalidCFA; }, .val_offset => |offset| { if (context.cfa) |cfa| { mem.writeInt(usize, out[0..@sizeOf(usize)], try applyOffset(cfa, offset), native_endian); } else return error.InvalidCFA; }, .register => |register| { const src = try regBytes(context.thread_context, register, context.reg_context); if (src.len != out.len) return error.RegisterSizeMismatch; @memcpy(out, try regBytes(context.thread_context, register, context.reg_context)); }, .expression => |expression| { context.stack_machine.reset(); const value = try context.stack_machine.run(expression, context.allocator, expression_context, context.cfa.?); const addr = if (value) |v| blk: { if (v != .generic) return error.InvalidExpressionValue; break :blk v.generic; } else return error.NoExpressionValue; if (ma.load(usize, addr) == null) return error.InvalidExpressionAddress; const ptr: *usize = @ptrFromInt(addr); mem.writeInt(usize, out[0..@sizeOf(usize)], ptr.*, native_endian); }, .val_expression => |expression| { context.stack_machine.reset(); const value = try context.stack_machine.run(expression, context.allocator, expression_context, context.cfa.?); if (value) |v| { if (v != .generic) return error.InvalidExpressionValue; mem.writeInt(usize, out[0..@sizeOf(usize)], v.generic, native_endian); } else return error.NoExpressionValue; }, .architectural => return error.UnimplementedRegisterRule, } }