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