blob: 826bc799be9fd86bc0951bc947ac4697683f7dc4 [file] [log] [blame]
/*
* Copyright (c) 2012 The Native Client Authors. All rights reserved.
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#include <string.h>
#include "native_client/src/shared/platform/nacl_check.h"
#include "native_client/src/shared/platform/nacl_log.h"
#include "native_client/src/trusted/service_runtime/include/bits/nacl_syscalls.h"
#include "native_client/src/trusted/service_runtime/load_file.h"
#include "native_client/src/trusted/service_runtime/nacl_all_modules.h"
#include "native_client/src/trusted/service_runtime/nacl_app.h"
#include "native_client/src/trusted/service_runtime/nacl_app_thread.h"
#include "native_client/src/trusted/service_runtime/nacl_copy.h"
#include "native_client/src/trusted/service_runtime/nacl_syscall_register.h"
#include "native_client/src/trusted/service_runtime/sel_ldr.h"
#include "native_client/tests/minnacl/minimal_test_syscalls.h"
static int32_t MySyscallInvoke(struct NaClAppThread *natp) {
UNREFERENCED_PARAMETER(natp);
printf("Inside custom test 'invoke' syscall\n");
fflush(stdout);
/* Return a value that the test guest program checks for. */
return 123;
}
static int32_t MySyscallExit(struct NaClAppThread *natp) {
UNREFERENCED_PARAMETER(natp);
printf("Inside custom test 'exit' syscall\n");
fflush(stdout);
_exit(0);
}
NACL_DEFINE_SYSCALL_0(MySyscallInvoke)
NACL_DEFINE_SYSCALL_0(MySyscallExit)
int main(int argc, char **argv) {
struct NaClApp app;
struct NaClApp *nap = &app;
int use_separate_thread = 0;
NaClHandleBootstrapArgs(&argc, &argv);
if (argc >= 2 && strcmp(argv[1], "--use_separate_thread") == 0) {
use_separate_thread = 1;
argc--;
argv++;
}
if (argc != 2) {
NaClLog(LOG_FATAL, "Expected 1 argument: executable filename\n");
}
NaClAllModulesInit();
CHECK(NaClAppWithEmptySyscallTableCtor(&app));
NACL_REGISTER_SYSCALL(nap, MySyscallInvoke, TEST_SYSCALL_INVOKE);
NACL_REGISTER_SYSCALL(nap, MySyscallExit, TEST_SYSCALL_EXIT);
CHECK(NaClAppLoadFileFromFilename(&app, argv[1]) == LOAD_OK);
/* These are examples of two different ways to run untrusted code. */
if (use_separate_thread) {
/* Create a new host thread that is managed by NaCl. */
CHECK(NaClCreateMainThread(&app, 0, NULL, NULL));
NaClWaitForMainThreadToExit(&app);
NaClLog(LOG_FATAL, "The exit syscall is not supposed to be callable\n");
} else {
/* Reuse the existing host thread for running untrusted code. */
struct NaClAppThread *natp;
uintptr_t stack_ptr = NaClGetInitialStackTop(nap);
/* Ensure the stack pointer is suitably aligned. */
stack_ptr &= ~NACL_STACK_ALIGN_MASK;
stack_ptr -= NACL_STACK_PAD_BELOW_ALIGN;
/* TODO(mseaborn): Make this interface more straightforward to use. */
stack_ptr = NaClSysToUserStackAddr(nap, NaClUserToSys(nap, stack_ptr));
natp = NaClAppThreadMake(nap, nap->initial_entry_pt, stack_ptr, 0, 0);
CHECK(natp != NULL);
NaClAppThreadLauncher(natp);
NaClLog(LOG_FATAL, "NaClThreadLauncher() should not return\n");
}
return 1;
}