blob: 67dff9993d0b053c0ffa7aaa3bfaf68768226181 [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.
*/
/*
* This test program creates two NaCl sandboxes within the same host process.
*/
#include "native_client/src/include/build_config.h"
#include "native_client/src/shared/platform/nacl_check.h"
#include "native_client/src/shared/platform/nacl_exit.h"
#include "native_client/src/shared/platform/nacl_log.h"
#include "native_client/src/shared/platform/nacl_sync_checked.h"
#include "native_client/src/trusted/desc/nacl_desc_base.h"
#include "native_client/src/trusted/desc/nacl_desc_io.h"
#include "native_client/src/trusted/service_runtime/include/sys/fcntl.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_valgrind_hooks.h"
#include "native_client/src/trusted/service_runtime/sel_ldr.h"
#define SEND_DESC 3
#define RECEIVE_DESC 3
int main(int argc, char **argv) {
struct NaClApp app[2];
struct NaClDesc *nd;
NaClHandle handle_pair[2];
int i;
char *domain1_args[] = {"prog", "domain1"};
char *domain2_args[] = {"prog", "domain2"};
int return_code;
if (argc != 2)
NaClLog(LOG_FATAL, "Expected 1 argument: executable filename\n");
NaClAllModulesInit();
NaClFileNameForValgrind(argv[1]);
nd = (struct NaClDesc *) NaClDescIoDescOpen(argv[1], NACL_ABI_O_RDONLY, 0);
CHECK(NULL != nd);
for (i = 0; i < 2; i++) {
CHECK(NaClAppCtor(&app[i]));
/* Use a smaller guest address space size, because 32-bit Windows
does not let us allocate 2GB of address space. We don't do this
for x86-64 because there is an assertion in NaClAllocateSpace()
that requires 4GB. */
#if NACL_ARCH(NACL_BUILD_ARCH) == NACL_x86 && NACL_BUILD_SUBARCH == 32
app[i].addr_bits = 29; /* 512MB per process */
#endif
/*
* On x86-32, we cannot enable ASLR even when the address space is
* 512MB. In particular, when on Windows where the available
* contiguous address space is tight, if the random choice for the
* base of the first 512MB address space puts that address space
* in the middle of the available address space region, the
* address space allocation code might not be able to (randomly)
* find another contiguous 512MB region for the second NaCl
* module.
*/
NaClXMutexLock(&app[i].mu);
CHECK(NaClAppLoadFileAslr(nd, &app[i],
NACL_DISABLE_ASLR) == LOAD_OK);
NaClXMutexUnlock(&app[i].mu);
NaClAppInitialDescriptorHookup(&app[i]);
CHECK(NaClAppPrepareToLaunch(&app[i]) == LOAD_OK);
}
/* Set up an IMC connection between the two guests. This allows us
to test communications between the two and also synchronise the
output for the purpose of checking against the golden file. */
CHECK(NaClSocketPair(handle_pair) == 0);
NaClAddImcHandle(&app[0], handle_pair[0], SEND_DESC);
NaClAddImcHandle(&app[1], handle_pair[1], RECEIVE_DESC);
CHECK(NaClCreateMainThread(&app[0], 2, domain1_args, NULL));
CHECK(NaClCreateMainThread(&app[1], 2, domain2_args, NULL));
return_code = NaClWaitForMainThreadToExit(&app[0]);
CHECK(return_code == 101);
return_code = NaClWaitForMainThreadToExit(&app[1]);
CHECK(return_code == 102);
/*
* Avoid calling exit() because it runs process-global destructors
* which might break code that is running in our unjoined threads.
*/
NaClExit(0);
}