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 |