| ... | @@ -256,7 +256,18 @@ fn evalInstructions( | ... | @@ -256,7 +256,18 @@ fn evalInstructions( |
| 256 | .offset = cfa.offset_sf * cie.data_alignment_factor, | 256 | .offset = cfa.offset_sf * cie.data_alignment_factor, |
| 257 | } }, | 257 | } }, |
| 258 | .def_cfa_reg => |register| switch (vm.current_row.cfa) { | 258 | .def_cfa_reg => |register| switch (vm.current_row.cfa) { |
| 259 | .none, .expression => return error.InvalidOperation, | 259 | .none => { |
| | 260 | // According to the DWARF specification, this is not valid, because this |
| | 261 | // instruction can only be used to replace the register if the rule is already a |
| | 262 | // `.reg_off`. However, this is emitted in practice by GNU toolchains for some |
| | 263 | // targets, and so by convention is interpreted as equivalent to `.def_cfa` with |
| | 264 | // an offset of 0. |
| | 265 | vm.current_row.cfa = .{ .reg_off = .{ |
| | 266 | .register = register, |
| | 267 | .offset = 0, |
| | 268 | } }; |
| | 269 | }, |
| | 270 | .expression => return error.InvalidOperation, |
| 260 | .reg_off => |*ro| ro.register = register, | 271 | .reg_off => |*ro| ro.register = register, |
| 261 | }, | 272 | }, |
| 262 | .def_cfa_offset => |offset| switch (vm.current_row.cfa) { | 273 | .def_cfa_offset => |offset| switch (vm.current_row.cfa) { |