Emits the unwind information into the given mutable byte slice. This function will panic if the slice is not at least `emit_size` in length.
(&self, buf: &mut [u8])
| 92 | /// |
| 93 | /// This function will panic if the slice is not at least `emit_size` in length. |
| 94 | pub fn emit(&self, buf: &mut [u8]) { |
| 95 | fn encode_stack_offset<const BITS: u8>(stack_offset: u16) -> u16 { |
| 96 | let encoded = (stack_offset / 8) - 1; |
| 97 | assert!(encoded < (1 << BITS), "Stack offset too large"); |
| 98 | encoded |
| 99 | } |
| 100 | |
| 101 | // NOTE: Unwind codes are written in big-endian! |
| 102 | |
| 103 | let mut writer = Writer::new(buf); |
| 104 | for code in self.unwind_codes.iter().rev() { |
| 105 | match code { |
| 106 | &UnwindCode::SaveReg { |
| 107 | reg, |
| 108 | stack_offset, |
| 109 | is_pair, |
| 110 | } => { |
| 111 | assert!(reg >= 19, "Can't save registers before X19"); |
| 112 | let reg = u16::from(reg - 19); |
| 113 | let encoding = if is_pair { |
| 114 | let mut encoding = 0b11001100_00000000u16; |
| 115 | encoding |= reg << 6; |
| 116 | encoding |= encode_stack_offset::<6>(stack_offset); |
| 117 | encoding |
| 118 | } else { |
| 119 | let mut encoding = 0b11010100_00000000u16; |
| 120 | encoding |= reg << 5; |
| 121 | encoding |= encode_stack_offset::<5>(stack_offset); |
| 122 | encoding |
| 123 | }; |
| 124 | writer.write_u16_be(encoding); |
| 125 | } |
| 126 | &UnwindCode::SaveFReg { |
| 127 | reg, |
| 128 | stack_offset, |
| 129 | is_pair, |
| 130 | } => { |
| 131 | assert!(reg >= 8, "Can't save registers before D8"); |
| 132 | let reg = u16::from(reg - 8); |
| 133 | let encoding = if is_pair { |
| 134 | let mut encoding = 0b11011010_00000000u16; |
| 135 | encoding |= reg << 6; |
| 136 | encoding |= encode_stack_offset::<6>(stack_offset); |
| 137 | encoding |
| 138 | } else { |
| 139 | let mut encoding = 0b11011110_00000000u16; |
| 140 | encoding |= reg << 5; |
| 141 | encoding |= encode_stack_offset::<5>(stack_offset); |
| 142 | encoding |
| 143 | }; |
| 144 | writer.write_u16_be(encoding); |
| 145 | } |
| 146 | &UnwindCode::SaveFpLrPair { stack_offset } => { |
| 147 | if stack_offset == 0 { |
| 148 | writer.write_u8(0b01000000); |
| 149 | } else { |
| 150 | let encoding = 0b10000000u8 |
| 151 | | u8::try_from(encode_stack_offset::<6>(stack_offset)).unwrap(); |
nothing calls this directly
no test coverage detected