(
syscall_array,
libkernel_web_base,
max_search_size,
)
| 179 | } |
| 180 | |
| 181 | export function init_syscall_array( |
| 182 | syscall_array, |
| 183 | libkernel_web_base, |
| 184 | max_search_size, |
| 185 | ) { |
| 186 | if (!Number.isInteger(max_search_size)) { |
| 187 | throw TypeError( |
| 188 | `max_search_size is not a integer: ${max_search_size}`); |
| 189 | } |
| 190 | if (max_search_size < 0) { |
| 191 | throw Error(`max_search_size is less than 0: ${max_search_size}`); |
| 192 | } |
| 193 | |
| 194 | const libkernel_web_buffer = make_buffer( |
| 195 | libkernel_web_base, |
| 196 | max_search_size, |
| 197 | ); |
| 198 | const kbuf = new BufferView(libkernel_web_buffer); |
| 199 | |
| 200 | // Search 'rdlo' string from libkernel_web's .rodata section to gain an |
| 201 | // upper bound on the size of the .text section. |
| 202 | let text_size = 0; |
| 203 | let found = false; |
| 204 | for (let i = 0; i < max_search_size; i++) { |
| 205 | if (kbuf[i] === 0x72 |
| 206 | && kbuf[i + 1] === 0x64 |
| 207 | && kbuf[i + 2] === 0x6c |
| 208 | && kbuf[i + 3] === 0x6f |
| 209 | ) { |
| 210 | text_size = i; |
| 211 | found = true; |
| 212 | break; |
| 213 | } |
| 214 | } |
| 215 | if (!found) { |
| 216 | throw Error( |
| 217 | '"rdlo" string not found in libkernel_web, base address:' |
| 218 | + ` ${libkernel_web_base}`); |
| 219 | } |
| 220 | |
| 221 | // search for the instruction sequence: |
| 222 | // syscall_X: |
| 223 | // mov rax, X |
| 224 | // mov r10, rcx |
| 225 | // syscall |
| 226 | for (let i = 0; i < text_size; i++) { |
| 227 | if (kbuf[i] === 0x48 |
| 228 | && kbuf[i + 1] === 0xc7 |
| 229 | && kbuf[i + 2] === 0xc0 |
| 230 | && kbuf[i + 7] === 0x49 |
| 231 | && kbuf[i + 8] === 0x89 |
| 232 | && kbuf[i + 9] === 0xca |
| 233 | && kbuf[i + 10] === 0x0f |
| 234 | && kbuf[i + 11] === 0x05 |
| 235 | ) { |
| 236 | const syscall_num = kbuf.read32(i + 3); |
| 237 | syscall_array[syscall_num] = libkernel_web_base.add(i); |
| 238 | // skip the sequence |
no test coverage detected