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 |