void NaClAppThreadGetSuspendedRegisters(struct NaClAppThread *natp, struct NaClSignalContext *regs) { if ((natp->suspend_state & NACL_APP_THREAD_UNTRUSTED) != 0) { NaClAppThreadGetSuspendedRegistersInternal(natp, regs); } else { NaClThreadContextToSignalContext(&natp->user, regs); } }
static void TrapSignalHandler(int signal, const struct NaClSignalContext *context_ptr, int is_untrusted) { uint32_t prog_ctr; char buf[100]; int len; struct NaClSignalContext *expected_regs = &g_test_shm->expected_regs; struct NaClSignalContext context = *context_ptr; if (signal != SIGTRAP) { SignalSafeLogStringLiteral("Error: Received unexpected signal\n"); _exit(1); } /* Get the prog_ctr value relative to untrusted address space. */ prog_ctr = (uint32_t) context.prog_ctr; /* * The trampoline code is not untrusted code because it is fixed by * the TCB. We don't want thread suspension to report prog_ctr as * being inside the trampoline code because we are not providing any * DWARF unwind info for the trampoline code. We want the CALL * instruction that jumps to a syscall trampoline to appear to be * atomic from the point of view of thread suspension: prog_ctr * should be reported as either at the CALL or after the CALL. * * TODO(mseaborn): Move this range check into the non-test part of * the thread suspension code. */ if (prog_ctr >= NACL_TRAMPOLINE_START && prog_ctr < NACL_TRAMPOLINE_END) { is_untrusted = 0; } if (g_in_untrusted_code != is_untrusted) { g_context_switch_count++; g_in_untrusted_code = is_untrusted; } if (!*(uint32_t *) NaClUserToSys(g_natp->nap, (uintptr_t) g_test_shm->regs_should_match)) return; len = snprintf(buf, sizeof(buf), "prog_ctr=0x%"NACL_PRIxNACL_REG": ", context.prog_ctr); SignalSafeWrite(buf, len); if (is_untrusted) { SignalSafeLogStringLiteral("Untrusted context\n"); RegsUnsetNonCalleeSavedRegisters(&context); /* * Don't compare prog_ctr if we are executing untrusted code. * Untrusted code executes a small loop for calling the syscall, * so there are multiple values that prog_ctr can have here. */ context.prog_ctr = expected_regs->prog_ctr; RegsAssertEqual(&context, expected_regs); } else if ((g_natp->suspend_state & NACL_APP_THREAD_TRUSTED) != 0) { SignalSafeLogStringLiteral("Trusted (syscall) context\n"); NaClThreadContextToSignalContext(&g_natp->user, &context); RegsAssertEqual(&context, expected_regs); } else { enum NaClUnwindCase unwind_case = 0; const char *str; SignalSafeLogStringLiteral("Inside a context switch: "); NaClGetRegistersForContextSwitch(g_natp, &context, &unwind_case); str = NaClUnwindCaseToString(unwind_case); CHECK(str != NULL); SignalSafeWrite(str, strlen(str)); SignalSafeLogStringLiteral("\n"); RegsAssertEqual(&context, expected_regs); } }