1// Copyright 2014 The Chromium 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#ifndef MOJO_NACL_MOJO_SYSCALL_INTERNAL_H_ 6#define MOJO_NACL_MOJO_SYSCALL_INTERNAL_H_ 7 8#include "native_client/src/trusted/service_runtime/nacl_copy.h" 9#include "native_client/src/trusted/service_runtime/sel_ldr.h" 10 11namespace { 12 13class ScopedCopyLock { 14 public: 15 explicit ScopedCopyLock(struct NaClApp* nap) : nap_(nap) { 16 NaClCopyTakeLock(nap_); 17 } 18 ~ScopedCopyLock() { 19 NaClCopyDropLock(nap_); 20 } 21 private: 22 struct NaClApp* nap_; 23}; 24 25static inline uintptr_t NaClUserToSysAddrArray( 26 struct NaClApp* nap, 27 uint32_t uaddr, 28 size_t count, 29 size_t size) { 30 // TODO(ncbray): overflow checking 31 size_t range = count * size; 32 return NaClUserToSysAddrRange(nap, uaddr, range); 33} 34 35template <typename T> bool ConvertScalarInput( 36 struct NaClApp* nap, 37 uint32_t user_ptr, 38 T* value) { 39 if (user_ptr) { 40 uintptr_t temp = NaClUserToSysAddrRange(nap, user_ptr, sizeof(T)); 41 if (temp != kNaClBadAddress) { 42 *value = *reinterpret_cast<T volatile*>(temp); 43 return true; 44 } 45 } 46 return false; 47} 48 49template <typename T> bool ConvertScalarOutput( 50 struct NaClApp* nap, 51 uint32_t user_ptr, 52 T volatile** sys_ptr) { 53 if (user_ptr) { 54 uintptr_t temp = NaClUserToSysAddrRange(nap, user_ptr, sizeof(T)); 55 if (temp != kNaClBadAddress) { 56 *sys_ptr = reinterpret_cast<T volatile*>(temp); 57 return true; 58 } 59 } 60 *sys_ptr = 0; // Paranoia. 61 return false; 62} 63 64template <typename T> bool ConvertScalarInOut( 65 struct NaClApp* nap, 66 uint32_t user_ptr, 67 bool optional, 68 T* value, 69 T volatile** sys_ptr) { 70 if (user_ptr) { 71 uintptr_t temp = NaClUserToSysAddrRange(nap, user_ptr, sizeof(T)); 72 if (temp != kNaClBadAddress) { 73 T volatile* converted = reinterpret_cast<T volatile*>(temp); 74 *sys_ptr = converted; 75 *value = *converted; 76 return true; 77 } 78 } else if (optional) { 79 *sys_ptr = 0; 80 *value = static_cast<T>(0); // Paranoia. 81 return true; 82 } 83 *sys_ptr = 0; // Paranoia. 84 *value = static_cast<T>(0); // Paranoia. 85 return false; 86} 87 88template <typename T> bool ConvertArray( 89 struct NaClApp* nap, 90 uint32_t user_ptr, 91 uint32_t length, 92 size_t element_size, 93 bool optional, 94 T** sys_ptr) { 95 if (user_ptr) { 96 uintptr_t temp = NaClUserToSysAddrArray(nap, user_ptr, length, 97 element_size); 98 if (temp != kNaClBadAddress) { 99 *sys_ptr = reinterpret_cast<T*>(temp); 100 return true; 101 } 102 } else if (optional) { 103 *sys_ptr = 0; 104 return true; 105 } 106 return false; 107} 108 109template <typename T> bool ConvertBytes( 110 struct NaClApp* nap, 111 uint32_t user_ptr, 112 uint32_t length, 113 bool optional, 114 T** sys_ptr) { 115 if (user_ptr) { 116 uintptr_t temp = NaClUserToSysAddrRange(nap, user_ptr, length); 117 if (temp != kNaClBadAddress) { 118 *sys_ptr = reinterpret_cast<T*>(temp); 119 return true; 120 } 121 } else if (optional) { 122 *sys_ptr = 0; 123 return true; 124 } 125 return false; 126} 127 128// TODO(ncbray): size validation and complete copy. 129// TODO(ncbray): ensure non-null / missized structs are covered by a test case. 130template <typename T> bool ConvertStruct( 131 struct NaClApp* nap, 132 uint32_t user_ptr, 133 bool optional, 134 T** sys_ptr) { 135 if (user_ptr) { 136 uintptr_t temp = NaClUserToSysAddrRange(nap, user_ptr, sizeof(T)); 137 if (temp != kNaClBadAddress) { 138 *sys_ptr = reinterpret_cast<T*>(temp); 139 return true; 140 } 141 } else if (optional) { 142 *sys_ptr = 0; 143 return true; 144 } 145 return false; 146} 147 148} // namespace 149 150#endif // MOJO_NACL_MOJO_SYSCALL_INTERNAL_H_ 151