| 306 | } |
| 307 | |
| 308 | bool StackFrame::checkInterruptedSyscall() { |
| 309 | #ifdef __APPLE__ |
| 310 | // We are not interested in syscalls that do not check error code, e.g. semaphore_wait_trap |
| 311 | if (*(instruction_t*)pc() == 0xd65f03c0) { |
| 312 | return true; |
| 313 | } |
| 314 | // If carry flag is set, the error code is in low byte of x0 |
| 315 | if (REG(pstate, cpsr) & (1 << 29)) { |
| 316 | return (retval() & 0xff) == EINTR || (retval() & 0xff) == ETIMEDOUT; |
| 317 | } else { |
| 318 | return retval() == (uintptr_t)-EINTR; |
| 319 | } |
| 320 | #else |
| 321 | if (retval() == (uintptr_t)-EINTR) { |
| 322 | // Workaround for JDK-8237858: restart the interrupted poll / epoll_wait manually |
| 323 | uintptr_t nr = (uintptr_t)REG(regs[8], x[8]); |
| 324 | if (nr == SYS_ppoll || (nr == SYS_epoll_pwait && (int)arg3() == -1)) { |
| 325 | // Check against unreadable page for the loop below |
| 326 | const uintptr_t max_distance = 24; |
| 327 | if ((pc() & 0xfff) < max_distance && SafeAccess::load32((int32_t*)(pc() - max_distance)) == 0) { |
| 328 | return true; |
| 329 | } |
| 330 | // Try to restore the original value of x0 saved in another register |
| 331 | for (uintptr_t prev_pc = pc() - 4; pc() - prev_pc <= max_distance; prev_pc -= 4) { |
| 332 | instruction_t insn = *(instruction_t*)prev_pc; |
| 333 | unsigned int reg = (insn >> 16) & 31; |
| 334 | if ((insn & 0xffe0ffff) == 0xaa0003e0 && reg >= 6) { |
| 335 | // mov x0, reg |
| 336 | REG(regs[0], x[0]) = REG(regs[reg], x[reg]); |
| 337 | pc() -= sizeof(instruction_t); |
| 338 | break; |
| 339 | } |
| 340 | } |
| 341 | } |
| 342 | return true; |
| 343 | } |
| 344 | return false; |
| 345 | #endif |
| 346 | } |
| 347 | |
| 348 | bool StackFrame::isSyscall(instruction_t* pc) { |
| 349 | // svc #0 or svc #80 |
nothing calls this directly
no outgoing calls
no test coverage detected