1 : /*
2 : * Copyright (c) 2012 The Native Client Authors. All rights reserved.
3 : * Use of this source code is governed by a BSD-style license that can be
4 : * found in the LICENSE file.
5 : */
6 :
7 : /*
8 : * NaCl service run-time, non-platform specific system call helper
9 : * routines -- for parallel I/O functions (pread/pwrite).
10 : *
11 : * NB: This is likely to be replaced with a preadv/pwritev
12 : * implementation, with an IRT function to build a single-element iov.
13 : */
14 :
15 : #include "native_client/src/trusted/service_runtime/sys_parallel_io.h"
16 :
17 : #include "native_client/src/shared/platform/nacl_host_desc.h"
18 : #include "native_client/src/trusted/desc/nacl_desc_base.h"
19 : #include "native_client/src/trusted/service_runtime/include/sys/errno.h"
20 : #include "native_client/src/trusted/service_runtime/nacl_app_thread.h"
21 : #include "native_client/src/trusted/service_runtime/nacl_copy.h"
22 : #include "native_client/src/trusted/service_runtime/sel_ldr.h"
23 :
24 33 : int32_t NaClSysPRead(struct NaClAppThread *natp,
25 33 : int32_t desc,
26 33 : uint32_t usr_addr,
27 33 : uint32_t buffer_bytes,
28 33 : uint32_t offset_addr) {
29 33 : struct NaClApp *nap = natp->nap;
30 33 : struct NaClDesc *ndp = NULL;
31 33 : uintptr_t sysaddr;
32 33 : nacl_abi_off64_t offset;
33 33 : int32_t retval = -NACL_ABI_EINVAL;
34 33 : ssize_t pread_result;
35 :
36 33 : NaClLog(3,
37 : ("Entered NaClSysPRead(0x%08"NACL_PRIxPTR", %d, 0x%08"NACL_PRIx32
38 : ", %"NACL_PRIu32"[0x%"NACL_PRIx32"], 0(%"NACL_PRIx32"))\n"),
39 : (uintptr_t) natp, (int) desc,
40 : usr_addr, buffer_bytes, buffer_bytes,
41 : offset_addr);
42 33 : ndp = NaClAppGetDesc(nap, (int) desc);
43 33 : if (NULL == ndp) {
44 0 : retval = -NACL_ABI_EBADF;
45 0 : goto cleanup;
46 : }
47 33 : if (!NaClCopyInFromUser(nap, &offset, (uintptr_t) offset_addr,
48 : sizeof offset)) {
49 0 : retval = -NACL_ABI_EFAULT;
50 0 : goto cleanup;
51 : }
52 33 : NaClLog(3,
53 : "... pread offset %"NACL_PRIuNACL_OFF" (0x%"NACL_PRIxNACL_OFF")\n",
54 : offset, offset);
55 33 : sysaddr = NaClUserToSysAddrRange(nap, (uintptr_t) usr_addr, buffer_bytes);
56 33 : if (kNaClBadAddress == sysaddr) {
57 0 : retval = -NACL_ABI_EFAULT;
58 0 : goto cleanup;
59 : }
60 :
61 33 : NaClVmIoWillStart(nap, usr_addr, usr_addr + buffer_bytes - 1);
62 33 : pread_result = (*NACL_VTBL(NaClDesc, ndp)->
63 : PRead)(ndp, (void *) sysaddr, buffer_bytes, offset);
64 33 : NaClVmIoHasEnded(nap, usr_addr, usr_addr + buffer_bytes - 1);
65 :
66 33 : retval = (int32_t) pread_result;
67 :
68 : cleanup:
69 33 : NaClDescSafeUnref(ndp);
70 33 : return retval;
71 : }
72 :
73 10 : int32_t NaClSysPWrite(struct NaClAppThread *natp,
74 10 : int32_t desc,
75 10 : uint32_t usr_addr,
76 10 : uint32_t buffer_bytes,
77 10 : uint32_t offset_addr) {
78 10 : struct NaClApp *nap = natp->nap;
79 10 : struct NaClDesc *ndp = NULL;
80 10 : uintptr_t sysaddr;
81 10 : nacl_abi_off64_t offset;
82 10 : int32_t retval = -NACL_ABI_EINVAL;
83 10 : ssize_t pwrite_result;
84 :
85 10 : NaClLog(3,
86 : ("Entered NaClSysPWrite(0x%08"NACL_PRIxPTR", %d, 0x%08"NACL_PRIx32
87 : ", %"NACL_PRIu32"[0x%"NACL_PRIx32"], 0(%"NACL_PRIx32"))\n"),
88 : (uintptr_t) natp, (int) desc,
89 : usr_addr, buffer_bytes, buffer_bytes,
90 : offset_addr);
91 10 : ndp = NaClAppGetDesc(nap, (int) desc);
92 10 : if (NULL == ndp) {
93 0 : retval = -NACL_ABI_EBADF;
94 0 : goto cleanup;
95 : }
96 10 : if (!NaClCopyInFromUser(nap, &offset, (uintptr_t) offset_addr,
97 : sizeof offset)) {
98 0 : retval = -NACL_ABI_EFAULT;
99 0 : goto cleanup;
100 : }
101 10 : NaClLog(3,
102 : "... pwrite offset %"NACL_PRIuNACL_OFF" (0x%"NACL_PRIxNACL_OFF")\n",
103 : offset, offset);
104 10 : sysaddr = NaClUserToSysAddrRange(nap, (uintptr_t) usr_addr, buffer_bytes);
105 10 : if (kNaClBadAddress == sysaddr) {
106 0 : retval = -NACL_ABI_EFAULT;
107 0 : goto cleanup;
108 : }
109 :
110 10 : NaClVmIoWillStart(nap, usr_addr, usr_addr + buffer_bytes - 1);
111 10 : pwrite_result = (*NACL_VTBL(NaClDesc, ndp)->
112 : PWrite)(ndp, (void *) sysaddr, buffer_bytes, offset);
113 10 : NaClVmIoHasEnded(nap, usr_addr, usr_addr + buffer_bytes - 1);
114 :
115 10 : retval = (int32_t) pwrite_result;
116 :
117 : cleanup:
118 10 : NaClDescSafeUnref(ndp);
119 10 : return retval;
120 : }
|