1 // Copyright 2013 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 // Platform-specific code for QNX goes here. For the POSIX-compatible
6 // parts the implementation is in platform-posix.cc.
7
8 #include <backtrace.h>
9 #include <pthread.h>
10 #include <semaphore.h>
11 #include <signal.h>
12 #include <stdlib.h>
13 #include <sys/resource.h>
14 #include <sys/time.h>
15 #include <sys/types.h>
16 #include <ucontext.h>
17
18 // QNX requires memory pages to be marked as executable.
19 // Otherwise, the OS raises an exception when executing code in that page.
20 #include <errno.h>
21 #include <fcntl.h> // open
22 #include <stdarg.h>
23 #include <strings.h> // index
24 #include <sys/mman.h> // mmap & munmap
25 #include <sys/procfs.h>
26 #include <sys/stat.h> // open
27 #include <unistd.h> // sysconf
28
29 #include <cmath>
30
31 #undef MAP_TYPE
32
33 #include "src/base/macros.h"
34 #include "src/base/platform/platform-posix-time.h"
35 #include "src/base/platform/platform-posix.h"
36 #include "src/base/platform/platform.h"
37
38 namespace v8 {
39 namespace base {
40
41 // 0 is never a valid thread id on Qnx since tids and pids share a
42 // name space and pid 0 is reserved (see man 2 kill).
43 static const pthread_t kNoThread = (pthread_t) 0;
44
45
46 #ifdef __arm__
47
ArmUsingHardFloat()48 bool OS::ArmUsingHardFloat() {
49 // GCC versions 4.6 and above define __ARM_PCS or __ARM_PCS_VFP to specify
50 // the Floating Point ABI used (PCS stands for Procedure Call Standard).
51 // We use these as well as a couple of other defines to statically determine
52 // what FP ABI used.
53 // GCC versions 4.4 and below don't support hard-fp.
54 // GCC versions 4.5 may support hard-fp without defining __ARM_PCS or
55 // __ARM_PCS_VFP.
56
57 #define GCC_VERSION (__GNUC__ * 10000 \
58 + __GNUC_MINOR__ * 100 \
59 + __GNUC_PATCHLEVEL__)
60 #if GCC_VERSION >= 40600
61 #if defined(__ARM_PCS_VFP)
62 return true;
63 #else
64 return false;
65 #endif
66
67 #elif GCC_VERSION < 40500
68 return false;
69
70 #else
71 #if defined(__ARM_PCS_VFP)
72 return true;
73 #elif defined(__ARM_PCS) || defined(__SOFTFP__) || defined(__SOFTFP) || \
74 !defined(__VFP_FP__)
75 return false;
76 #else
77 #error "Your version of GCC does not report the FP ABI compiled for." \
78 "Please report it on this issue" \
79 "http://code.google.com/p/v8/issues/detail?id=2140"
80
81 #endif
82 #endif
83 #undef GCC_VERSION
84 }
85
86 #endif // __arm__
87
CreateTimezoneCache()88 TimezoneCache* OS::CreateTimezoneCache() {
89 return new PosixDefaultTimezoneCache();
90 }
91
GetSharedLibraryAddresses()92 std::vector<OS::SharedLibraryAddress> OS::GetSharedLibraryAddresses() {
93 std::vector<SharedLibraryAddress> result;
94 procfs_mapinfo *mapinfos = nullptr, *mapinfo;
95 int proc_fd, num, i;
96
97 struct {
98 procfs_debuginfo info;
99 char buff[PATH_MAX];
100 } map;
101
102 char buf[PATH_MAX + 1];
103 snprintf(buf, PATH_MAX + 1, "/proc/%d/as", getpid());
104
105 if ((proc_fd = open(buf, O_RDONLY)) == -1) {
106 close(proc_fd);
107 return result;
108 }
109
110 /* Get the number of map entries. */
111 if (devctl(proc_fd, DCMD_PROC_MAPINFO, nullptr, 0, &num) != EOK) {
112 close(proc_fd);
113 return result;
114 }
115
116 mapinfos =
117 reinterpret_cast<procfs_mapinfo*>(malloc(num * sizeof(procfs_mapinfo)));
118 if (mapinfos == nullptr) {
119 close(proc_fd);
120 return result;
121 }
122
123 /* Fill the map entries. */
124 if (devctl(proc_fd, DCMD_PROC_PAGEDATA, mapinfos,
125 num * sizeof(procfs_mapinfo), &num) != EOK) {
126 free(mapinfos);
127 close(proc_fd);
128 return result;
129 }
130
131 for (i = 0; i < num; i++) {
132 mapinfo = mapinfos + i;
133 if (mapinfo->flags & MAP_ELF) {
134 map.info.vaddr = mapinfo->vaddr;
135 if (devctl(proc_fd, DCMD_PROC_MAPDEBUG, &map, sizeof(map), 0) != EOK) {
136 continue;
137 }
138 result.push_back(SharedLibraryAddress(map.info.path, mapinfo->vaddr,
139 mapinfo->vaddr + mapinfo->size));
140 }
141 }
142 free(mapinfos);
143 close(proc_fd);
144 return result;
145 }
146
SignalCodeMovingGC()147 void OS::SignalCodeMovingGC() {}
148
AdjustSchedulingParams()149 void OS::AdjustSchedulingParams() {}
150
GetFreeMemoryRangesWithin(OS::Address boundary_start,OS::Address boundary_end,size_t minimum_size,size_t alignment)151 std::vector<OS::MemoryRange> OS::GetFreeMemoryRangesWithin(
152 OS::Address boundary_start, OS::Address boundary_end, size_t minimum_size,
153 size_t alignment) {
154 return {};
155 }
156
157 } // namespace base
158 } // namespace v8
159