1b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Copyright 2013 the V8 project authors. All rights reserved. 2b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Use of this source code is governed by a BSD-style license that can be 3b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// found in the LICENSE file. 4b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Platform-specific code for QNX goes here. For the POSIX-compatible 6b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// parts the implementation is in platform-posix.cc. 7b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 8b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include <backtrace.h> 9b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include <pthread.h> 10b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include <semaphore.h> 11b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include <signal.h> 12b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include <stdlib.h> 13b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include <sys/resource.h> 14b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include <sys/time.h> 15b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include <sys/types.h> 16b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include <ucontext.h> 17b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 18b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// QNX requires memory pages to be marked as executable. 19b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Otherwise, the OS raises an exception when executing code in that page. 20b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include <errno.h> 21b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include <fcntl.h> // open 22b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include <stdarg.h> 23b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include <strings.h> // index 24b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include <sys/mman.h> // mmap & munmap 25b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include <sys/procfs.h> 26b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include <sys/stat.h> // open 27b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include <sys/types.h> // mmap & munmap 28b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include <unistd.h> // sysconf 29b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 30b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include <cmath> 31b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 32b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#undef MAP_TYPE 33b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 34b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/base/macros.h" 35b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/base/platform/platform.h" 36b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 37b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 38b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochnamespace v8 { 39b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochnamespace base { 40b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 41b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// 0 is never a valid thread id on Qnx since tids and pids share a 42b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// name space and pid 0 is reserved (see man 2 kill). 43b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic const pthread_t kNoThread = (pthread_t) 0; 44b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 45b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 46b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#ifdef __arm__ 47b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 48b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool OS::ArmUsingHardFloat() { 49b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // GCC versions 4.6 and above define __ARM_PCS or __ARM_PCS_VFP to specify 50b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // the Floating Point ABI used (PCS stands for Procedure Call Standard). 51b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // We use these as well as a couple of other defines to statically determine 52b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // what FP ABI used. 53b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // GCC versions 4.4 and below don't support hard-fp. 54b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // GCC versions 4.5 may support hard-fp without defining __ARM_PCS or 55b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // __ARM_PCS_VFP. 56b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 57b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#define GCC_VERSION (__GNUC__ * 10000 \ 58b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch + __GNUC_MINOR__ * 100 \ 59b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch + __GNUC_PATCHLEVEL__) 60b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#if GCC_VERSION >= 40600 61b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#if defined(__ARM_PCS_VFP) 62b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return true; 63b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#else 64b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return false; 65b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif 66b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 67b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#elif GCC_VERSION < 40500 68b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return false; 69b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 70b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#else 71b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#if defined(__ARM_PCS_VFP) 72b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return true; 73b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#elif defined(__ARM_PCS) || defined(__SOFTFP__) || defined(__SOFTFP) || \ 74b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch !defined(__VFP_FP__) 75b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return false; 76b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#else 77b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#error "Your version of GCC does not report the FP ABI compiled for." \ 78b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "Please report it on this issue" \ 79b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "http://code.google.com/p/v8/issues/detail?id=2140" 80b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 81b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif 82b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif 83b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#undef GCC_VERSION 84b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 85b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 86b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif // __arm__ 87b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 88b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 89b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochconst char* OS::LocalTimezone(double time, TimezoneCache* cache) { 90b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (std::isnan(time)) return ""; 91b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch time_t tv = static_cast<time_t>(std::floor(time/msPerSecond)); 92b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch struct tm* t = localtime(&tv); 93b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (NULL == t) return ""; 94b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return t->tm_zone; 95b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 96b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 97b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 98b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochdouble OS::LocalTimeOffset(TimezoneCache* cache) { 99b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch time_t tv = time(NULL); 100b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch struct tm* t = localtime(&tv); 101b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // tm_gmtoff includes any daylight savings offset, so subtract it. 102b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return static_cast<double>(t->tm_gmtoff * msPerSecond - 103b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch (t->tm_isdst > 0 ? 3600 * msPerSecond : 0)); 104b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 105b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 106b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 107b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid* OS::Allocate(const size_t requested, 108b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch size_t* allocated, 109b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool is_executable) { 110b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const size_t msize = RoundUp(requested, AllocateAlignment()); 111b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int prot = PROT_READ | PROT_WRITE | (is_executable ? PROT_EXEC : 0); 112b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void* addr = OS::GetRandomMmapAddr(); 113b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void* mbase = mmap(addr, msize, prot, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); 114b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (mbase == MAP_FAILED) return NULL; 115b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch *allocated = msize; 116b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return mbase; 117b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 118b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 119b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 120b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass PosixMemoryMappedFile : public OS::MemoryMappedFile { 121b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public: 122b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PosixMemoryMappedFile(FILE* file, void* memory, int size) 123b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch : file_(file), memory_(memory), size_(size) { } 124b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch virtual ~PosixMemoryMappedFile(); 125b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch virtual void* memory() { return memory_; } 126b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch virtual int size() { return size_; } 127b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch private: 128b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FILE* file_; 129b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void* memory_; 130b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int size_; 131b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}; 132b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 133b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 134b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochOS::MemoryMappedFile* OS::MemoryMappedFile::open(const char* name) { 135b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FILE* file = fopen(name, "r+"); 136b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (file == NULL) return NULL; 137b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 138b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch fseek(file, 0, SEEK_END); 139b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int size = ftell(file); 140b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 141b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void* memory = 142b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch mmap(OS::GetRandomMmapAddr(), 143b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch size, 144b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PROT_READ | PROT_WRITE, 145b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch MAP_SHARED, 146b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch fileno(file), 147b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 0); 148b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return new PosixMemoryMappedFile(file, memory, size); 149b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 150b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 151b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 152b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochOS::MemoryMappedFile* OS::MemoryMappedFile::create(const char* name, int size, 153b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void* initial) { 154b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FILE* file = fopen(name, "w+"); 155b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (file == NULL) return NULL; 156b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int result = fwrite(initial, size, 1, file); 157b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (result < 1) { 158b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch fclose(file); 159b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return NULL; 160b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 161b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void* memory = 162b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch mmap(OS::GetRandomMmapAddr(), 163b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch size, 164b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PROT_READ | PROT_WRITE, 165b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch MAP_SHARED, 166b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch fileno(file), 167b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 0); 168b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return new PosixMemoryMappedFile(file, memory, size); 169b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 170b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 171b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 172b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochPosixMemoryMappedFile::~PosixMemoryMappedFile() { 173b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (memory_) OS::Free(memory_, size_); 174b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch fclose(file_); 175b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 176b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 177b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 178b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstd::vector<OS::SharedLibraryAddress> OS::GetSharedLibraryAddresses() { 179b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch std::vector<SharedLibraryAddress> result; 180b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch procfs_mapinfo *mapinfos = NULL, *mapinfo; 181b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int proc_fd, num, i; 182b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 183b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch struct { 184b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch procfs_debuginfo info; 185b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch char buff[PATH_MAX]; 186b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } map; 187b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 188b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch char buf[PATH_MAX + 1]; 189b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch snprintf(buf, PATH_MAX + 1, "/proc/%d/as", getpid()); 190b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 191b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if ((proc_fd = open(buf, O_RDONLY)) == -1) { 192b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch close(proc_fd); 193b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return result; 194b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 195b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 196b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch /* Get the number of map entries. */ 197b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (devctl(proc_fd, DCMD_PROC_MAPINFO, NULL, 0, &num) != EOK) { 198b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch close(proc_fd); 199b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return result; 200b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 201b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 202b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch mapinfos = reinterpret_cast<procfs_mapinfo *>( 203b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch malloc(num * sizeof(procfs_mapinfo))); 204b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (mapinfos == NULL) { 205b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch close(proc_fd); 206b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return result; 207b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 208b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 209b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch /* Fill the map entries. */ 210b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (devctl(proc_fd, DCMD_PROC_PAGEDATA, 211b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch mapinfos, num * sizeof(procfs_mapinfo), &num) != EOK) { 212b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch free(mapinfos); 213b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch close(proc_fd); 214b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return result; 215b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 216b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 217b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (i = 0; i < num; i++) { 218b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch mapinfo = mapinfos + i; 219b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (mapinfo->flags & MAP_ELF) { 220b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch map.info.vaddr = mapinfo->vaddr; 221b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (devctl(proc_fd, DCMD_PROC_MAPDEBUG, &map, sizeof(map), 0) != EOK) { 222b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch continue; 223b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 224b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch result.push_back(SharedLibraryAddress( 225b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch map.info.path, mapinfo->vaddr, mapinfo->vaddr + mapinfo->size)); 226b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 227b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 228b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch free(mapinfos); 229b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch close(proc_fd); 230b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return result; 231b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 232b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 233b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 234b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid OS::SignalCodeMovingGC() { 235b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 236b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 237b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 238b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Constants used for mmap. 239b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic const int kMmapFd = -1; 240b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic const int kMmapFdOffset = 0; 241b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 242b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 243b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochVirtualMemory::VirtualMemory() : address_(NULL), size_(0) { } 244b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 245b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 246b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochVirtualMemory::VirtualMemory(size_t size) 247b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch : address_(ReserveRegion(size)), size_(size) { } 248b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 249b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 250b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochVirtualMemory::VirtualMemory(size_t size, size_t alignment) 251b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch : address_(NULL), size_(0) { 252b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK((alignment % OS::AllocateAlignment()) == 0); 253b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch size_t request_size = RoundUp(size + alignment, 254b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static_cast<intptr_t>(OS::AllocateAlignment())); 255b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void* reservation = mmap(OS::GetRandomMmapAddr(), 256b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch request_size, 257b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PROT_NONE, 258b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch MAP_PRIVATE | MAP_ANONYMOUS | MAP_LAZY, 259b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch kMmapFd, 260b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch kMmapFdOffset); 261b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (reservation == MAP_FAILED) return; 262b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 263b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch uint8_t* base = static_cast<uint8_t*>(reservation); 264b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch uint8_t* aligned_base = RoundUp(base, alignment); 265b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK_LE(base, aligned_base); 266b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 267b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Unmap extra memory reserved before and after the desired block. 268b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (aligned_base != base) { 269b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch size_t prefix_size = static_cast<size_t>(aligned_base - base); 270b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch OS::Free(base, prefix_size); 271b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch request_size -= prefix_size; 272b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 273b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 274b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch size_t aligned_size = RoundUp(size, OS::AllocateAlignment()); 275b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK_LE(aligned_size, request_size); 276b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 277b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (aligned_size != request_size) { 278b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch size_t suffix_size = request_size - aligned_size; 279b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch OS::Free(aligned_base + aligned_size, suffix_size); 280b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch request_size -= suffix_size; 281b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 282b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 283b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(aligned_size == request_size); 284b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 285b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch address_ = static_cast<void*>(aligned_base); 286b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch size_ = aligned_size; 287b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 288b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 289b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 290b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochVirtualMemory::~VirtualMemory() { 291b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (IsReserved()) { 292b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool result = ReleaseRegion(address(), size()); 293b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(result); 294b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch USE(result); 295b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 296b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 297b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 298b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 299b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool VirtualMemory::IsReserved() { 300b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return address_ != NULL; 301b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 302b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 303b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 304b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid VirtualMemory::Reset() { 305b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch address_ = NULL; 306b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch size_ = 0; 307b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 308b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 309b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 310b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool VirtualMemory::Commit(void* address, size_t size, bool is_executable) { 311b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return CommitRegion(address, size, is_executable); 312b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 313b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 314b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 315b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool VirtualMemory::Uncommit(void* address, size_t size) { 316b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return UncommitRegion(address, size); 317b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 318b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 319b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 320b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool VirtualMemory::Guard(void* address) { 321b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch OS::Guard(address, OS::CommitPageSize()); 322b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return true; 323b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 324b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 325b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 326b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid* VirtualMemory::ReserveRegion(size_t size) { 327b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void* result = mmap(OS::GetRandomMmapAddr(), 328b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch size, 329b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PROT_NONE, 330b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch MAP_PRIVATE | MAP_ANONYMOUS | MAP_LAZY, 331b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch kMmapFd, 332b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch kMmapFdOffset); 333b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 334b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (result == MAP_FAILED) return NULL; 335b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 336b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return result; 337b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 338b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 339b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 340b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool VirtualMemory::CommitRegion(void* base, size_t size, bool is_executable) { 341b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int prot = PROT_READ | PROT_WRITE | (is_executable ? PROT_EXEC : 0); 342b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (MAP_FAILED == mmap(base, 343b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch size, 344b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch prot, 345b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED, 346b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch kMmapFd, 347b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch kMmapFdOffset)) { 348b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return false; 349b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 350b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 351b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return true; 352b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 353b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 354b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 355b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool VirtualMemory::UncommitRegion(void* base, size_t size) { 356b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return mmap(base, 357b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch size, 358b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PROT_NONE, 359b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED | MAP_LAZY, 360b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch kMmapFd, 361b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch kMmapFdOffset) != MAP_FAILED; 362b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 363b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 364b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 365b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool VirtualMemory::ReleaseRegion(void* base, size_t size) { 366b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return munmap(base, size) == 0; 367b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 368b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 369b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 370b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool VirtualMemory::HasLazyCommits() { 371b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return false; 372b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 373b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 374b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} } // namespace v8::base 375