1 : /*
2 : * Copyright 2008 The Native Client Authors. All rights reserved.
3 : * Use of this source code is governed by a BSD-style license that can
4 : * be found in the LICENSE file.
5 : */
6 :
7 : /*
8 : * NaCl Service Runtime. I/O Descriptor / Handle abstraction. Memory
9 : * mapping using descriptors.
10 : */
11 :
12 : #ifndef NATIVE_CLIENT_SRC_TRUSTED_PLATFORM_NACL_HOST_DESC_H__
13 : #define NATIVE_CLIENT_SRC_TRUSTED_PLATFORM_NACL_HOST_DESC_H__
14 :
15 : #include "native_client/src/include/portability.h"
16 : #include "native_client/src/shared/platform/nacl_sync.h"
17 :
18 : #if NACL_LINUX || NACL_OSX
19 : # include "native_client/src/shared/platform/linux/nacl_host_desc_types.h"
20 : #elif NACL_WINDOWS
21 : # include "native_client/src/shared/platform/win/nacl_host_desc_types.h"
22 : #endif
23 :
24 :
25 :
26 : /*
27 : * see NACL_MAP_PAGESIZE from nacl_config.h; map operations must be aligned
28 : */
29 :
30 : EXTERN_C_BEGIN
31 :
32 : struct nacl_abi_stat;
33 : struct NaClHostDesc;
34 :
35 : /*
36 : * off64_t in linux, off_t in osx and __int64_t in win
37 : */
38 : typedef int64_t nacl_off64_t;
39 :
40 : /*
41 : * We do not explicitly provide an abstracted version of a
42 : * host-independent stat64 structure. Instead, it is up to the user
43 : * of the nacl_host_desc code to not use anything but the
44 : * POSIX-blessed fields, to know that the shape/size may differ across
45 : * platforms, and to know that the st_size field is a 64-bit value
46 : * compatible w/ nacl_off64_t above.
47 : */
48 : #if NACL_LINUX
49 : typedef struct stat64 nacl_host_stat_t;
50 : #elif NACL_OSX
51 : typedef struct stat nacl_host_stat_t;
52 : #elif NACL_WINDOWS
53 : typedef struct _stati64 nacl_host_stat_t;
54 : #elif defined __native_client__
55 : /* nacl_host_stat_t not exposed to NaCl module code */
56 : #else
57 : # error "what OS?"
58 : #endif
59 :
60 : /* TODO(ilewis, bsy): it seems like these error functions are useful in more
61 : * places than just the NaClDesc library. Move them to a more central header.
62 : * When that's done, it should be possible to include this header *only* from
63 : * host code, removing the need for the #ifdef __native_client__ directives.
64 : *
65 : * Currently that's not possible, unless we want to forego NaClIsNegErrno in
66 : * trusted code, and go back to writing if(retval < 0) to check for errors.
67 : */
68 :
69 : /*
70 : * On 64-bit Linux, the app has the entire 32-bit address space
71 : * (kernel no longer occupies the top 1G), so what is an errno and
72 : * what is an address is trickier: we require that our NACL_ABI_
73 : * errno values be at most 64K.
74 : *
75 : * NB: The runtime assumes that valid errno values can ALWAYS be
76 : * represented using no more than 16 bits. If this assumption
77 : * changes, all code dealing with error number should be reviewed.
78 : *
79 : * NB 2010-02-03: The original code for this function did not work:
80 : * return ((uint64_t) val) >= ~((uint64_t) 0xffff);
81 : * Macintosh optimized builds were not able to recognize negative values.
82 : * All other platforms as well as Macintosh debug builds worked fine.
83 : *
84 : * NB the 3rd, 2010-10-19: these functions take pointer arguments
85 : * to discourage accidental use of narrowing/widening conversions,
86 : * which have caused problems in the past. We assume without proof
87 : * that the compiler will do the right thing when inlining.
88 : */
89 11 : static INLINE int NaClPtrIsNegErrno(const uintptr_t *val) {
90 11 : return (*val & ~((uintptr_t) 0xffff)) == ~((uintptr_t) 0xffff);
91 : }
92 :
93 18673 : static INLINE int NaClSSizeIsNegErrno(const ssize_t *val) {
94 18673 : return (*val & ~((ssize_t) 0xffff)) == ~((ssize_t) 0xffff);
95 : }
96 :
97 8 : static INLINE int NaClOff64IsNegErrno(const nacl_off64_t *val) {
98 8 : return (*val & ~((nacl_off64_t) 0xffff)) == ~((nacl_off64_t) 0xffff);
99 : }
100 :
101 : extern int NaClXlateErrno(int errnum);
102 :
103 : extern int NaClXlateNaClSyncStatus(NaClSyncStatus status);
104 :
105 : #ifndef __native_client__ /* these functions are not exposed to NaCl modules
106 : * (see TODO comment above)
107 : */
108 : /*
109 : * Mapping data from a file.
110 : *
111 : * start_addr and len must be multiples of NACL_MAP_PAGESIZE.
112 : *
113 : * Of prot bits, only PROT_READ and PROT_WRITE are allowed. Of flags,
114 : * only MAP_ANONYMOUS is allowed. start_addr must be specified, and
115 : * this code will add in MAP_FIXED. start_address, len, and offset
116 : * must be a multiple of NACL_MAP_PAGESIZE.
117 : *
118 : * Note that in Windows, in order for the mapping to be coherent, the
119 : * mapping must arise from the same mapping handle and just using the
120 : * same file handle won't ensure coherence. If the file mapping
121 : * object were created and destroyed inside of NaClHostDescMap, there
122 : * would never be any chance at coherence. One alternative is to
123 : * create a file mapping object for each mapping mode. Native
124 : * descriptors are then shareable, but only when the mode matches (!).
125 : * A read-only shared mapping not seeing the changes made by a
126 : * read-write mapping seem rather ugly.
127 : *
128 : * Instead of this ugliness, we just say that a map operation cannot
129 : * request MAP_SHARED. Anonymous mappings ignore the descriptor
130 : * argument.
131 : *
132 : * Underlying host-OS syscalls: mmap / MapViewOfFileEx
133 : *
134 : * 4GB file max
135 : */
136 : extern uintptr_t NaClHostDescMap(struct NaClHostDesc *d,
137 : void *start_addr,
138 : size_t len,
139 : int prot,
140 : int flags,
141 : nacl_off64_t offset);
142 :
143 : /*
144 : * Undo a file mapping. The memory range specified by start_address,
145 : * len must be memory that came from NaClHostDescMap.
146 : *
147 : * start_addr and len must be multiples of NACL_MAP_PAGESIZE.
148 : *
149 : * Underlying host-OS syscalls: mmap / UnmapViewOfFile/VirtualAlloc
150 : */
151 : extern int NaClHostDescUnmap(void *start_addr,
152 : size_t len);
153 :
154 : /*
155 : * Undo a file mapping. The memory range specified by start_address,
156 : * len must be memory that came from NaClHostDescMap.
157 : *
158 : * start_addr and len must be multiples of NACL_MAP_PAGESIZE.
159 : *
160 : * Underlying host-OS syscalls: munmap / UnmapViewOfFile
161 : */
162 : extern int NaClHostDescUnmapUnsafe(void *start_addr,
163 : size_t len);
164 :
165 :
166 : /*
167 : * These are the flags that are permitted.
168 : */
169 : #define NACL_ALLOWED_OPEN_FLAGS \
170 : (NACL_ABI_O_ACCMODE | NACL_ABI_O_CREAT \
171 : | NACL_ABI_O_TRUNC | NACL_ABI_O_APPEND)
172 :
173 : /*
174 : * Constructor for a NaClHostDesc object.
175 : *
176 : * path should be a host-OS pathname to a file. No validation is
177 : * done. flags should contain one of O_RDONLY, O_WRONLY, and O_RDWR,
178 : * and can additionally contain O_CREAT, O_TRUNC, and O_APPEND.
179 : *
180 : * Uses raw syscall return convention, so returns 0 for success and
181 : * non-zero (usually -NACL_ABI_EINVAL) for failure.
182 : *
183 : * We cannot return the platform descriptor/handle and be consistent
184 : * with a largely POSIX-ish interface, since e.g. windows handles may
185 : * be negative and might look like negative errno returns. Currently
186 : * we use the posix API on windows, so it could work, but we may need
187 : * to change later.
188 : *
189 : * Underlying host-OS functions: open / _s_open_s
190 : */
191 : extern int NaClHostDescOpen(struct NaClHostDesc *d,
192 : char const *path,
193 : int flags,
194 : int perms);
195 :
196 : /*
197 : * Constructor for a NaClHostDesc object.
198 : *
199 : * Uses raw syscall return convention, so returns 0 for success and
200 : * non-zero (usually -NACL_ABI_EINVAL) for failure.
201 : *
202 : * d is a POSIX-interface descriptor
203 : *
204 : * flags may only contain one of NACL_ABI_O_RDONLY, NACL_ABI_O_WRONLY,
205 : * or NACL_ABI_O_RDWR, and must be the NACL_ABI_* versions of the
206 : * actual mode that d was opened with. NACL_ABI_O_CREAT/APPEND are
207 : * permitted, but ignored, so it is safe to pass the same flags value
208 : * used in NaClHostDescOpen and pass it to NaClHostDescPosixDup.
209 : *
210 : * Underlying host-OS functions: dup / _dup; mode is what posix_d was
211 : * opened with
212 : */
213 : extern int NaClHostDescPosixDup(struct NaClHostDesc *d,
214 : int posix_d,
215 : int flags);
216 :
217 : /*
218 : * Essentially the same as NaClHostDescPosixDup, but without the dup
219 : * -- takes ownership of the descriptor rather than making a dup.
220 : */
221 : extern int NaClHostDescPosixTake(struct NaClHostDesc *d,
222 : int posix_d,
223 : int flags);
224 :
225 :
226 : /*
227 : * Allocates a NaClHostDesc and invokes NaClHostDescPosixTake on it.
228 : * Aborts process if no memory.
229 : */
230 : extern struct NaClHostDesc *NaClHostDescPosixMake(int posix_d,
231 : int flags);
232 : /*
233 : * Read data from an opened file into a memory buffer.
234 : *
235 : * buf is not validated.
236 : *
237 : * Underlying host-OS functions: read / _read
238 : */
239 : extern ssize_t NaClHostDescRead(struct NaClHostDesc *d,
240 : void *buf,
241 : size_t len);
242 :
243 :
244 : /*
245 : * Write data from a memory buffer into an opened file.
246 : *
247 : * buf is not validated.
248 : *
249 : * Underlying host-OS functions: write / _write
250 : */
251 : extern ssize_t NaClHostDescWrite(struct NaClHostDesc *d,
252 : void const *buf,
253 : size_t count);
254 :
255 : extern nacl_off64_t NaClHostDescSeek(struct NaClHostDesc *d,
256 : nacl_off64_t offset,
257 : int whence);
258 :
259 : /*
260 : * TODO(bsy): Need to enumerate which request is supported and the
261 : * size of the argument, as well as whether the arg is input or
262 : * output.
263 : */
264 : extern int NaClHostDescIoctl(struct NaClHostDesc *d,
265 : int request,
266 : void *arg);
267 :
268 : /*
269 : * Fstat.
270 : */
271 : extern int NaClHostDescFstat(struct NaClHostDesc *d,
272 : nacl_host_stat_t *nasp);
273 :
274 : /*
275 : * Dtor for the NaClHostFile object. Close the file.
276 : *
277 : * Underlying host-OS functions: close(2) / _close
278 : */
279 : extern int NaClHostDescClose(struct NaClHostDesc *d);
280 :
281 : extern int NaClHostDescStat(char const *host_os_pathname,
282 : nacl_host_stat_t *nasp);
283 :
284 : /*
285 : * Maps NACI_ABI_ versions of the mmap prot argument to host ABI versions
286 : * of the bit values
287 : */
288 :
289 : extern int NaClProtMap(int abi_prot);
290 :
291 : EXTERN_C_END
292 :
293 : #endif /* defined __native_client__ */
294 :
295 : #endif /* NATIVE_CLIENT_SRC_TRUSTED_PLATFORM_NACL_HOST_DESC_H__ */
|