| OLD | NEW |
| (Empty) |
| 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 #include <map> | |
| 9 | |
| 10 #include "native_client/src/include/checked_cast.h" | |
| 11 #include "native_client/src/shared/platform/nacl_exit.h" | |
| 12 #include "native_client/src/shared/platform/nacl_log.h" | |
| 13 #include "native_client/src/trusted/desc/nacl_desc_base.h" | |
| 14 #include "native_client/src/trusted/nonnacl_util/sel_ldr_launcher.h" | |
| 15 #include "native_client/src/trusted/plugin/method_map.h" | |
| 16 #include "native_client/src/trusted/plugin/plugin.h" | |
| 17 #include "native_client/src/trusted/plugin/srpc_client.h" | |
| 18 #include "native_client/src/trusted/plugin/utility.h" | |
| 19 | |
| 20 using nacl::assert_cast; | |
| 21 | |
| 22 namespace { | |
| 23 | |
| 24 uint32_t ArgsLength(NaClSrpcArg** index) { | |
| 25 uint32_t i; | |
| 26 for (i = 0; (i < NACL_SRPC_MAX_ARGS) && NULL != index[i]; ++i) { | |
| 27 // Empty body. Avoids warning. | |
| 28 } | |
| 29 return i; | |
| 30 } | |
| 31 | |
| 32 } // namespace | |
| 33 | |
| 34 namespace plugin { | |
| 35 | |
| 36 bool SrpcParams::Init(const char* in_types, const char* out_types) { | |
| 37 if (!FillVec(ins_, in_types)) { | |
| 38 return false; | |
| 39 } | |
| 40 if (!FillVec(outs_, out_types)) { | |
| 41 FreeArguments(ins_); | |
| 42 return false; | |
| 43 } | |
| 44 return true; | |
| 45 } | |
| 46 | |
| 47 uint32_t SrpcParams::InputLength() const { | |
| 48 return ArgsLength(const_cast<NaClSrpcArg**>(ins_)); | |
| 49 } | |
| 50 | |
| 51 uint32_t SrpcParams::OutputLength() const { | |
| 52 return ArgsLength(const_cast<NaClSrpcArg**>(outs_)); | |
| 53 } | |
| 54 | |
| 55 uint32_t SrpcParams::SignatureLength() const { | |
| 56 uint32_t in_length = ArgsLength(const_cast<NaClSrpcArg**>(ins_)); | |
| 57 uint32_t out_length = ArgsLength(const_cast<NaClSrpcArg**>(outs_)); | |
| 58 uint32_t array_outs = 0; | |
| 59 | |
| 60 for (uint32_t i = 0; i < out_length; ++i) { | |
| 61 switch (outs_[i]->tag) { | |
| 62 case NACL_SRPC_ARG_TYPE_CHAR_ARRAY: | |
| 63 case NACL_SRPC_ARG_TYPE_DOUBLE_ARRAY: | |
| 64 case NACL_SRPC_ARG_TYPE_INT_ARRAY: | |
| 65 case NACL_SRPC_ARG_TYPE_LONG_ARRAY: | |
| 66 ++array_outs; | |
| 67 break; | |
| 68 case NACL_SRPC_ARG_TYPE_STRING: | |
| 69 case NACL_SRPC_ARG_TYPE_BOOL: | |
| 70 case NACL_SRPC_ARG_TYPE_DOUBLE: | |
| 71 case NACL_SRPC_ARG_TYPE_INT: | |
| 72 case NACL_SRPC_ARG_TYPE_LONG: | |
| 73 case NACL_SRPC_ARG_TYPE_HANDLE: | |
| 74 case NACL_SRPC_ARG_TYPE_INVALID: | |
| 75 case NACL_SRPC_ARG_TYPE_OBJECT: | |
| 76 case NACL_SRPC_ARG_TYPE_VARIANT_ARRAY: | |
| 77 default: | |
| 78 break; | |
| 79 } | |
| 80 } | |
| 81 return in_length + array_outs; | |
| 82 } | |
| 83 | |
| 84 void SrpcParams::FreeAll() { | |
| 85 FreeArguments(ins_); | |
| 86 FreeArguments(outs_); | |
| 87 memset(ins_, 0, sizeof(ins_)); | |
| 88 memset(outs_, 0, sizeof(outs_)); | |
| 89 } | |
| 90 | |
| 91 bool SrpcParams::FillVec(NaClSrpcArg* vec[], const char* types) { | |
| 92 const size_t kLength = strlen(types); | |
| 93 if (kLength > NACL_SRPC_MAX_ARGS) { | |
| 94 return false; | |
| 95 } | |
| 96 // We use malloc/new here rather than new/delete, because the SRPC layer | |
| 97 // is written in C and hence will use malloc/free. | |
| 98 // This array will get deallocated by FreeArguments(). | |
| 99 if (kLength > 0) { | |
| 100 NaClSrpcArg* args = | |
| 101 reinterpret_cast<NaClSrpcArg*>(malloc(kLength * sizeof(*args))); | |
| 102 if (NULL == args) { | |
| 103 return false; | |
| 104 } | |
| 105 | |
| 106 memset(static_cast<void*>(args), 0, kLength * sizeof(*args)); | |
| 107 for (size_t i = 0; i < kLength; ++i) { | |
| 108 vec[i] = &args[i]; | |
| 109 args[i].tag = static_cast<NaClSrpcArgType>(types[i]); | |
| 110 } | |
| 111 } | |
| 112 vec[kLength] = NULL; | |
| 113 return true; | |
| 114 } | |
| 115 | |
| 116 void SrpcParams::FreeArguments(NaClSrpcArg* vec[]) { | |
| 117 if (NULL == vec[0]) { | |
| 118 return; | |
| 119 } | |
| 120 for (NaClSrpcArg** argp = vec; *argp; ++argp) { | |
| 121 FreeSrpcArg(*argp); | |
| 122 } | |
| 123 // Free the vector containing the arguments themselves that was | |
| 124 // allocated with FillVec(). | |
| 125 free(vec[0]); | |
| 126 } | |
| 127 | |
| 128 MethodInfo::~MethodInfo() { | |
| 129 free(reinterpret_cast<void*>(name_)); | |
| 130 free(reinterpret_cast<void*>(ins_)); | |
| 131 free(reinterpret_cast<void*>(outs_)); | |
| 132 } | |
| 133 | |
| 134 bool InitSrpcArgArray(NaClSrpcArg* arr, int size) { | |
| 135 arr->tag = NACL_SRPC_ARG_TYPE_VARIANT_ARRAY; | |
| 136 arr->arrays.varr = reinterpret_cast<NaClSrpcArg*>( | |
| 137 calloc(size, sizeof(*(arr->arrays.varr)))); | |
| 138 if (NULL == arr->arrays.varr) { | |
| 139 arr->u.count = 0; | |
| 140 return false; | |
| 141 } | |
| 142 arr->u.count = size; | |
| 143 return true; | |
| 144 } | |
| 145 | |
| 146 void FreeSrpcArg(NaClSrpcArg* arg) { | |
| 147 switch (arg->tag) { | |
| 148 case NACL_SRPC_ARG_TYPE_CHAR_ARRAY: | |
| 149 free(arg->arrays.carr); | |
| 150 break; | |
| 151 case NACL_SRPC_ARG_TYPE_DOUBLE_ARRAY: | |
| 152 free(arg->arrays.darr); | |
| 153 break; | |
| 154 case NACL_SRPC_ARG_TYPE_HANDLE: | |
| 155 break; | |
| 156 case NACL_SRPC_ARG_TYPE_INT_ARRAY: | |
| 157 free(arg->arrays.iarr); | |
| 158 break; | |
| 159 case NACL_SRPC_ARG_TYPE_LONG_ARRAY: | |
| 160 free(arg->arrays.larr); | |
| 161 break; | |
| 162 case NACL_SRPC_ARG_TYPE_STRING: | |
| 163 // All strings that are passed in SrpcArg must be allocated using | |
| 164 // malloc! We cannot use browser's allocation API | |
| 165 // since some of SRPC arguments is handled outside of the plugin code. | |
| 166 free(arg->arrays.str); | |
| 167 break; | |
| 168 case NACL_SRPC_ARG_TYPE_VARIANT_ARRAY: | |
| 169 if (arg->arrays.varr) { | |
| 170 for (uint32_t i = 0; i < arg->u.count; i++) { | |
| 171 FreeSrpcArg(&arg->arrays.varr[i]); | |
| 172 } | |
| 173 } | |
| 174 break; | |
| 175 case NACL_SRPC_ARG_TYPE_OBJECT: | |
| 176 // This is a pointer to a scriptable object and should be released | |
| 177 // by the browser | |
| 178 break; | |
| 179 case NACL_SRPC_ARG_TYPE_BOOL: | |
| 180 case NACL_SRPC_ARG_TYPE_DOUBLE: | |
| 181 case NACL_SRPC_ARG_TYPE_INT: | |
| 182 case NACL_SRPC_ARG_TYPE_LONG: | |
| 183 case NACL_SRPC_ARG_TYPE_INVALID: | |
| 184 default: | |
| 185 break; | |
| 186 } | |
| 187 } | |
| 188 | |
| 189 MethodMap::~MethodMap() { | |
| 190 MethodMapStorage::iterator it; | |
| 191 while ((it = method_map_.begin()) != method_map_.end()) { | |
| 192 delete(it->second); | |
| 193 method_map_.erase(it); | |
| 194 } | |
| 195 } | |
| 196 | |
| 197 MethodInfo* MethodMap::GetMethod(uintptr_t method_id) { | |
| 198 return method_map_[method_id]; | |
| 199 } | |
| 200 | |
| 201 void MethodMap::AddMethod(uintptr_t method_id, MethodInfo *info) { | |
| 202 if (method_map_.find(method_id) != method_map_.end()) { | |
| 203 // the method already exists | |
| 204 NaClAbort(); | |
| 205 } | |
| 206 method_map_[method_id] = info; | |
| 207 method_map_keys_.push_back(method_id); | |
| 208 } | |
| 209 | |
| 210 } // namespace plugin | |
| OLD | NEW |