• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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