| ... | ... | @@ -15,14 +15,14 @@ cfi_vm: Dwarf.Unwind.VirtualMachine, |
| 15 | 15 | expr_vm: Dwarf.expression.StackMachine(.{ .call_frame_context = true }), |
| 16 | 16 | |
| 17 | 17 | pub const CacheEntry = struct { |
| 18 | | const max_regs = 32; |
| 18 | const max_rules = 32; |
| 19 | 19 | |
| 20 | 20 | pc: usize, |
| 21 | 21 | cie: *const Dwarf.Unwind.CommonInformationEntry, |
| 22 | 22 | cfa_rule: Dwarf.Unwind.VirtualMachine.CfaRule, |
| 23 | 23 | num_rules: u8, |
| 24 | | rules_regs: [max_regs]u16, |
| 25 | | rules: [max_regs]Dwarf.Unwind.VirtualMachine.RegisterRule, |
| 24 | rules_regs: [max_rules]u16, |
| 25 | rules: [max_rules]Dwarf.Unwind.VirtualMachine.RegisterRule, |
| 26 | 26 | |
| 27 | 27 | pub fn find(entries: []const CacheEntry, pc: usize) ?*const CacheEntry { |
| 28 | 28 | assert(pc != 0); |
| ... | ... | @@ -108,22 +108,30 @@ pub fn computeRules( |
| 108 | 108 | |
| 109 | 109 | unwinder.cfi_vm.reset(); |
| 110 | 110 | const row = try unwinder.cfi_vm.runTo(gpa, pc_vaddr, cie, &fde, @sizeOf(usize), native_endian); |
| 111 | | const cols = unwinder.cfi_vm.rowColumns(&row); |
| 112 | | |
| 113 | | if (cols.len > CacheEntry.max_regs) return error.UnsupportedDebugInfo; |
| 114 | 111 | |
| 115 | 112 | var entry: CacheEntry = .{ |
| 116 | 113 | .pc = unwinder.pc, |
| 117 | 114 | .cie = cie, |
| 118 | 115 | .cfa_rule = row.cfa, |
| 119 | | .num_rules = @intCast(cols.len), |
| 116 | .num_rules = undefined, |
| 120 | 117 | .rules_regs = undefined, |
| 121 | 118 | .rules = undefined, |
| 122 | 119 | }; |
| 123 | | for (cols, 0..) |col, i| { |
| 120 | var i: usize = 0; |
| 121 | for (unwinder.cfi_vm.rowColumns(&row)) |col| { |
| 122 | if (i == CacheEntry.max_rules) return error.UnsupportedDebugInfo; |
| 123 | |
| 124 | _ = unwinder.cpu_state.dwarfRegisterBytes(col.register) catch |err| switch (err) { |
| 125 | // Reading an unsupported register during unwinding will result in an error, so there is |
| 126 | // no point wasting a rule slot in the cache entry for it. |
| 127 | error.UnsupportedRegister => continue, |
| 128 | error.InvalidRegister => return error.InvalidDebugInfo, |
| 129 | }; |
| 124 | 130 | entry.rules_regs[i] = col.register; |
| 125 | 131 | entry.rules[i] = col.rule; |
| 132 | i += 1; |
| 126 | 133 | } |
| 134 | entry.num_rules = @intCast(i); |
| 127 | 135 | return entry; |
| 128 | 136 | } |
| 129 | 137 | |