feat(native): add support for win arm64 unwind codes#978
Conversation
Instructions and example for changelogPlease add an entry to Example: ## Unreleased
### Features
- add support for win arm64 unwind codes ([#978](https://github.com/getsentry/symbolic/pull/978))If none of the above apply, you can opt out of this check by adding |
6d605d3 to
08f62b8
Compare
08f62b8 to
614ab8b
Compare
loewenheim
left a comment
There was a problem hiding this comment.
Very impressive! I basically only have some stylistic nits.
| writer: &'a mut dyn Write, | ||
| } | ||
|
|
||
| // The kinds of registers the can be saved for unwinding. |
There was a problem hiding this comment.
| // The kinds of registers the can be saved for unwinding. | |
| // The kinds of registers that can be saved for unwinding. |
| } | ||
| } | ||
|
|
||
| // Computes the memory location relative to CFI, offset above SP |
There was a problem hiding this comment.
These could all be doc comments.
| // Computes the memory location relative to CFI, offset above SP | |
| /// Computes the memory location relative to CFI, offset above SP |
| " .{typ}{first_reg}: .cfa {} + ^ .{typ}{second_reg}: .cfa {} + ^", | ||
| o1, o2 |
There was a problem hiding this comment.
| " .{typ}{first_reg}: .cfa {} + ^ .{typ}{second_reg}: .cfa {} + ^", | |
| o1, o2 | |
| " .{typ}{first_reg}: .cfa {o1} + ^ .{typ}{second_reg}: .cfa {o2} + ^" |
| " .x{reg}: .cfa {} + ^ .lr: .cfa {} + ^", | ||
| o1, o2 |
There was a problem hiding this comment.
| " .x{reg}: .cfa {} + ^ .lr: .cfa {} + ^", | |
| o1, o2 | |
| " .x{reg}: .cfa {o1} + ^ .lr: .cfa {o2} + ^" |
| let second_reg = first_reg + 1; | ||
|
|
||
| self.last_reg_kind = typ; | ||
| self.last_reg_num = first_reg + 1; |
There was a problem hiding this comment.
| self.last_reg_num = first_reg + 1; | |
| self.last_reg_num = second_reg; |
| if matches!(code.code, Arm64UnwindCode::End) | ||
| || matches!(code.code, Arm64UnwindCode::EndC) |
There was a problem hiding this comment.
| if matches!(code.code, Arm64UnwindCode::End) | |
| || matches!(code.code, Arm64UnwindCode::EndC) | |
| if matches!(code.code, Arm64UnwindCode::End | Arm64UnwindCode::EndC) |
| function.function_length(), | ||
| ); | ||
|
|
||
| for (instruction_num, code) in unwind_codes.iter().rev().enumerate() { |
There was a problem hiding this comment.
What is the reason for the rev? Are codes just generally returned in reverse order?
| Arm64UnwindCode::AllocSmall { size_bytes } => { | ||
| enc.alloc_stack(size_bytes)?; | ||
| } | ||
|
|
||
| Arm64UnwindCode::AllocMedium { size_bytes } => { | ||
| enc.alloc_stack(size_bytes)?; | ||
| } | ||
|
|
||
| Arm64UnwindCode::AllocLarge { size_bytes } => { | ||
| enc.alloc_stack(size_bytes)?; | ||
| } |
There was a problem hiding this comment.
Could unify these arms:
| Arm64UnwindCode::AllocSmall { size_bytes } => { | |
| enc.alloc_stack(size_bytes)?; | |
| } | |
| Arm64UnwindCode::AllocMedium { size_bytes } => { | |
| enc.alloc_stack(size_bytes)?; | |
| } | |
| Arm64UnwindCode::AllocLarge { size_bytes } => { | |
| enc.alloc_stack(size_bytes)?; | |
| } | |
| Arm64UnwindCode::AllocSmall { size_bytes } | Arm64UnwindCode::AllocMedium { size_bytes } | Arm64UnwindCode::AllocLarge { size_bytes } => { | |
| enc.alloc_stack(size_bytes)?; | |
| } |
| first_reg, | ||
| offset_bytes, | ||
| } => { | ||
| // save pair <x(19+2*#X),lr> at [sp+#Z*8], offset <= 504 |
There was a problem hiding this comment.
Just to make sure (this applies to some of the other branches too): first_reg is already the number 19 + 2 *#X?
| if pair { | ||
| if preindexed { | ||
| enc.save_pre_indexed_pair(typ, reg, offset_bytes)?; | ||
| } else { | ||
| enc.save_indexed_pair(typ, reg, offset_bytes)?; | ||
| } | ||
| } else { | ||
| if preindexed { | ||
| enc.save_pre_indexed(typ, reg, offset_bytes)?; | ||
| } else { | ||
| enc.save_indexed(typ, reg, offset_bytes)?; | ||
| } | ||
| } |
There was a problem hiding this comment.
Could match on (pair, preindexed) here instead.
(Keeping as a draft for the moment; goblins hasn't pushed a new release w/ arm64 support yet.)