| 109 | } |
| 110 | |
| 111 | void VMCodeGen::emit_state_init(X64Emitter& e, std::size_t, std::size_t data_island_size, |
| 112 | std::uint32_t block_table_count, bool skip_regs_zero) { |
| 113 | const auto& cfg = vm_.dispatcher_regs(); |
| 114 | const auto& st = vm_.state_layout(); |
| 115 | |
| 116 | // zero VM regs[] |
| 117 | if (!skip_regs_zero) { |
| 118 | const std::uint8_t zpool[7] = {rx::rax, rx::rcx, rx::rdx, rx::r8, rx::r9, rx::r10, rx::r11}; |
| 119 | SeedRng zero_rng(vm_.cipher_init_state() ^ 0x2E07117EU); |
| 120 | |
| 121 | for (std::uint8_t i = 0; i < vm_.reg_count(); ++i) { |
| 122 | const std::uint8_t Z = zpool[zero_rng.pick(7)]; |
| 123 | e.xor_reg_reg(Z, Z); |
| 124 | e.mov_mem_reg( |
| 125 | cfg.state_ptr, |
| 126 | static_cast<std::int32_t>(st.regs_base + i * 8), |
| 127 | Z, |
| 128 | true |
| 129 | ); |
| 130 | } |
| 131 | } |
| 132 | |
| 133 | // cipher state init, random per seed |
| 134 | e.mov_reg_imm64(rx::rax, vm_.cipher_init_state()); |
| 135 | e.mov_reg_reg(cfg.cipher_state, rx::rax); |
| 136 | e.mov_mem_reg( |
| 137 | cfg.state_ptr, |
| 138 | static_cast<std::int32_t>(st.cipher_extra) + 48, |
| 139 | rx::rax, |
| 140 | true |
| 141 | ); |
| 142 | |
| 143 | // mult/add constants into VMState slots |
| 144 | std::uint64_t mult = 0, add = 0; |
| 145 | switch (vm_.cipher_kind()) { |
| 146 | case CipherKind::ARX: mult = 0; add = vm_.cipher_k1(); break; |
| 147 | case CipherKind::LcgSub: mult = 0x5851F42D4C957F2DULL; add = vm_.cipher_k1(); break; |
| 148 | case CipherKind::SBoxAdd: mult = 0x100000001B3ULL; add = vm_.cipher_k1(); break; |
| 149 | case CipherKind::FeistelByte: mult = vm_.cipher_k1(); add = vm_.cipher_k2(); break; |
| 150 | } |
| 151 | constexpr std::int32_t kCipherAddOff = 0; |
| 152 | constexpr std::int32_t kCipherMultOff = 8; |
| 153 | |
| 154 | e.mov_reg_imm64(rx::rax, add); |
| 155 | e.mov_mem_reg( |
| 156 | cfg.state_ptr, |
| 157 | static_cast<std::int32_t>(st.cipher_extra) + kCipherAddOff, |
| 158 | rx::rax, |
| 159 | true |
| 160 | ); |
| 161 | |
| 162 | e.mov_reg_imm64(rx::rax, mult); |
| 163 | e.mov_mem_reg( |
| 164 | cfg.state_ptr, |
| 165 | static_cast<std::int32_t>(st.cipher_extra) + kCipherMultOff, |
| 166 | rx::rax, |
| 167 | true |
| 168 | ); |
nothing calls this directly
no test coverage detected