NaClErrorCode NaClAllocateSpace(void **mem, size_t addrsp_size) { int result; CHECK(NULL != mem); NaClAddrSpaceBeforeAlloc(addrsp_size); #if NACL_LINUX /* * On 32 bit Linux, a 1 gigabyte block of address space may be reserved at * the zero-end of the address space during process creation, to address * sandbox layout requirements on ARM and performance issues on Intel ATOM. * Look for this prereserved block and if found, pass its address to the * page allocation function. */ if (NaClFindPrereservedSandboxMemory(mem, addrsp_size)) { void *tmp_mem = (void *) NACL_TRAMPOLINE_START; CHECK(*mem == 0); addrsp_size -= NACL_TRAMPOLINE_START; result = NaCl_page_alloc_at_addr(&tmp_mem, addrsp_size); } else { /* Zero-based sandbox not prereserved. Attempt to allocate anyway. */ result = NaCl_page_alloc(mem, addrsp_size); } #elif NACL_WINDOWS /* * On 32 bit Windows, a 1 gigabyte block of address space is reserved before * starting up this process to make sure we can create the sandbox. Look for * this prereserved block and if found, pass its address to the page * allocation function. */ if (0 == NaClFindPrereservedSandboxMemory(mem, addrsp_size)) { result = NaCl_page_alloc_at_addr(mem, addrsp_size); } else { result = NaCl_page_alloc(mem, addrsp_size); } #else result = NaCl_page_alloc(mem, addrsp_size); #endif if (0 != result) { NaClLog(2, "NaClAllocateSpace: NaCl_page_alloc 0x%08"NACL_PRIxPTR " failed\n", (uintptr_t) *mem); return LOAD_NO_MEMORY; } NaClLog(4, "NaClAllocateSpace: %"NACL_PRIxPTR", %"NACL_PRIxS"\n", (uintptr_t) *mem, addrsp_size); return LOAD_OK; }
/* NOTE: This routine is almost identical to the x86_32 version. */ NaClErrorCode NaClAllocateSpaceAslr(void **mem, size_t addrsp_size, enum NaClAslrMode aslr_mode) { int result; void *tmp_mem = (void *) NACL_TRAMPOLINE_START; UNREFERENCED_PARAMETER(aslr_mode); CHECK(NULL != mem); /* * On ARM, we cheat slightly: we add two pages to the requested * allocation! This accomodates the guard region we require at the * top end of untrusted memory. */ addrsp_size += NACL_ADDRSPACE_UPPER_GUARD_SIZE; NaClAddrSpaceBeforeAlloc(addrsp_size); /* * On 32 bit Linux, a 1 gigabyte block of address space may be reserved at * the zero-end of the address space during process creation, to address * sandbox layout requirements on ARM and performance issues on Intel ATOM. * Look for this prereserved block and if found, pass its address to the * page allocation function. */ if (!NaClFindPrereservedSandboxMemory(mem, addrsp_size)) { /* On ARM, we should always have prereserved sandbox memory. */ NaClLog(LOG_ERROR, "NaClAllocateSpace:" " Could not find correct amount of prereserved memory" " (looked for 0x%016"NACL_PRIxS" bytes).\n", addrsp_size); return LOAD_NO_MEMORY; } /* * When creating a zero-based sandbox, we do not allocate the first 64K of * pages beneath the trampolines, because -- on Linux at least -- we cannot. * Instead, we allocate starting at the trampolines, and then coerce the * "mem" out parameter. */ CHECK(*mem == NULL); addrsp_size -= NACL_TRAMPOLINE_START; result = NaCl_page_alloc_at_addr(&tmp_mem, addrsp_size); if (0 != result) { NaClLog(2, "NaClAllocateSpace: NaCl_page_alloc_at_addr 0x%08"NACL_PRIxPTR " failed\n", (uintptr_t) tmp_mem); return LOAD_NO_MEMORY; } NaClLog(4, "NaClAllocateSpace: %"NACL_PRIxPTR", %"NACL_PRIxS"\n", (uintptr_t) *mem, addrsp_size); return LOAD_OK; }