| 172 | } |
| 173 | |
| 174 | export function init_syscall_array(syscall_array, libkernel_web_base, max_search_size) { |
| 175 | if (!Number.isInteger(max_search_size)) { |
| 176 | throw TypeError(`max_search_size is not a integer: ${max_search_size}`); |
| 177 | } |
| 178 | if (max_search_size < 0) { |
| 179 | throw Error(`max_search_size is less than 0: ${max_search_size}`); |
| 180 | } |
| 181 | |
| 182 | const libkernel_web_buffer = make_buffer(libkernel_web_base, max_search_size); |
| 183 | const kbuf = new BufferView(libkernel_web_buffer); |
| 184 | |
| 185 | // Search 'rdlo' string from libkernel_web's .rodata section to gain an |
| 186 | // upper bound on the size of the .text section. |
| 187 | let text_size = 0; |
| 188 | let found = false; |
| 189 | for (let i = 0; i < max_search_size; i++) { |
| 190 | if (kbuf[i] === 0x72 && kbuf[i + 1] === 0x64 && kbuf[i + 2] === 0x6c && kbuf[i + 3] === 0x6f) { |
| 191 | text_size = i; |
| 192 | found = true; |
| 193 | break; |
| 194 | } |
| 195 | } |
| 196 | if (!found) { |
| 197 | throw Error(`"rdlo" string not found in libkernel_web, base address: ${libkernel_web_base}`); |
| 198 | } |
| 199 | |
| 200 | // search for the instruction sequence: |
| 201 | // syscall_X: |
| 202 | // mov rax, X |
| 203 | // mov r10, rcx |
| 204 | // syscall |
| 205 | for (let i = 0; i < text_size; i++) { |
| 206 | if (kbuf[i] === 0x48 && kbuf[i + 1] === 0xc7 && kbuf[i + 2] === 0xc0 && kbuf[i + 7] === 0x49 && kbuf[i + 8] === 0x89 && kbuf[i + 9] === 0xca && kbuf[i + 10] === 0x0f && kbuf[i + 11] === 0x05) { |
| 207 | const syscall_num = kbuf.read32(i + 3); |
| 208 | syscall_array[syscall_num] = libkernel_web_base.add(i); |
| 209 | // skip the sequence |
| 210 | i += 11; |
| 211 | } |
| 212 | } |
| 213 | } |
| 214 | |
| 215 | // create a char array like in the C language |
| 216 | // |