OLD | NEW |
---|---|
1 #!/usr/bin/python | 1 #!/usr/bin/python |
2 # Copyright 2014 The Chromium Authors. All rights reserved. | 2 # Copyright 2014 The Chromium Authors. All rights reserved. |
3 # Use of this source code is governed by a BSD-style license that can be | 3 # Use of this source code is governed by a BSD-style license that can be |
4 # found in the LICENSE file. | 4 # found in the LICENSE file. |
5 | 5 |
6 # pylint: disable=W0104,W0106,F0401,R0201 | 6 # pylint: disable=W0104,W0106,F0401,R0201 |
7 | 7 |
8 import optparse | 8 import optparse |
9 import os.path | 9 import os.path |
10 import sys | 10 import sys |
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
150 # Parameters passed into trusted code are handled differently depending on | 150 # Parameters passed into trusted code are handled differently depending on |
151 # details of the parameter. ParamImpl instances encapsulate these differences | 151 # details of the parameter. ParamImpl instances encapsulate these differences |
152 # and are used to generate the code that transfers parameters across the | 152 # and are used to generate the code that transfers parameters across the |
153 # untrusted/trusted boundary. | 153 # untrusted/trusted boundary. |
154 class ParamImpl(object): | 154 class ParamImpl(object): |
155 def __init__(self, param): | 155 def __init__(self, param): |
156 self.param = param | 156 self.param = param |
157 | 157 |
158 # Declare whatever variables are needed to handle this particular parameter. | 158 # Declare whatever variables are needed to handle this particular parameter. |
159 def DeclareVars(self, code): | 159 def DeclareVars(self, code): |
160 raise NotImplementedError() | 160 raise NotImplementedError(type(self)) |
161 | 161 |
162 # Convert the untrusted representation of the parameter into a trusted | 162 # Convert the untrusted representation of the parameter into a trusted |
163 # representation, such as a scalar value or a trusted pointer into the | 163 # representation, such as a scalar value or a trusted pointer into the |
164 # untrusted address space. | 164 # untrusted address space. |
165 def ConvertParam(self): | 165 def ConvertParam(self): |
166 raise NotImplementedError() | 166 raise NotImplementedError(type(self)) |
167 | 167 |
168 # For this particular parameter, what expression should be passed when | 168 # For this particular parameter, what expression should be passed when |
169 # invoking the trusted Mojo API function? | 169 # invoking the trusted Mojo API function? |
170 def CallParam(self): | 170 def CallParam(self): |
171 raise NotImplementedError() | 171 raise NotImplementedError(type(self)) |
172 | 172 |
173 # After invoking the trusted Mojo API function, transfer data back into | 173 # After invoking the trusted Mojo API function, transfer data back into |
174 # untrusted memory. Overriden for Out and InOut parameters. | 174 # untrusted memory. Overriden for Out and InOut parameters. |
175 def CopyOut(self, code): | 175 def CopyOut(self, code): |
176 pass | 176 pass |
177 | 177 |
178 # Converting array parameters needs to be defered until after the scalar | 178 # Converting array parameters needs to be defered until after the scalar |
179 # parameter containing the size of the array has itself been converted. | 179 # parameter containing the size of the array has itself been converted. |
180 def IsArray(self): | 180 def IsArray(self): |
181 return False | 181 return False |
(...skipping 12 matching lines...) Expand all Loading... | |
194 return '%s_value' % self.param.name | 194 return '%s_value' % self.param.name |
195 | 195 |
196 | 196 |
197 class ScalarOutputImpl(ParamImpl): | 197 class ScalarOutputImpl(ParamImpl): |
198 def DeclareVars(self, code): | 198 def DeclareVars(self, code): |
199 code << '%s volatile* %s_ptr;' % (self.param.base_type, self.param.name) | 199 code << '%s volatile* %s_ptr;' % (self.param.base_type, self.param.name) |
200 code << '%s %s_value;' % (self.param.base_type, self.param.name) | 200 code << '%s %s_value;' % (self.param.base_type, self.param.name) |
201 | 201 |
202 def ConvertParam(self): | 202 def ConvertParam(self): |
203 p = self.param | 203 p = self.param |
204 return 'ConvertScalarOutput(nap, params[%d], &%s_ptr)' % (p.uid + 1, p.name) | 204 return ('ConvertScalarOutput(nap, params[%d], %s, &%s_ptr)' % |
205 (p.uid + 1,CBool(p.is_optional), p.name)) | |
Mark Seaborn
2014/12/08 22:24:12
Add space after ','
Nick Bray (chromium)
2014/12/09 22:14:31
Done.
| |
205 | 206 |
206 def CallParam(self): | 207 def CallParam(self): |
207 return '&%s_value' % self.param.name | 208 name = self.param.name |
209 expr = '&%s_value' % name | |
210 if self.param.is_optional: | |
211 expr = '%s_ptr ? %s : NULL' % (name, expr) | |
212 return expr | |
208 | 213 |
209 def CopyOut(self, code): | 214 def CopyOut(self, code): |
210 name = self.param.name | 215 name = self.param.name |
211 code << '*%s_ptr = %s_value;' % (name, name) | 216 if self.param.is_struct: |
217 # C++ errors when you try to copy a volatile struct pointer. | |
218 # (There are no default copy constructors for this case.) | |
219 # memcpy instead. | |
220 copy_stmt = ('memcpy_volatile_out(%s_ptr, &%s_value, sizeof(%s));' % | |
221 (name, name, self.param.base_type)) | |
222 else: | |
223 copy_stmt = '*%s_ptr = %s_value;' % (name, name) | |
224 | |
225 if self.param.is_optional: | |
226 code << 'if (%s_ptr != NULL) {' % (name) | |
227 with code.Indent(): | |
228 code << copy_stmt | |
229 code << '}' | |
230 else: | |
231 code << copy_stmt | |
212 | 232 |
213 | 233 |
214 class ScalarInOutImpl(ParamImpl): | 234 class ScalarInOutImpl(ParamImpl): |
215 def DeclareVars(self, code): | 235 def DeclareVars(self, code): |
216 code << '%s volatile* %s_ptr;' % (self.param.base_type, self.param.name) | 236 code << '%s volatile* %s_ptr;' % (self.param.base_type, self.param.name) |
217 code << '%s %s_value;' % (self.param.base_type, self.param.name) | 237 code << '%s %s_value;' % (self.param.base_type, self.param.name) |
218 | 238 |
219 def ConvertParam(self): | 239 def ConvertParam(self): |
220 p = self.param | 240 p = self.param |
221 return ('ConvertScalarInOut(nap, params[%d], %s, &%s_value, &%s_ptr)' % | 241 return ('ConvertScalarInOut(nap, params[%d], %s, &%s_value, &%s_ptr)' % |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
254 (p.uid + 1, p.size + '_value', element_size, CBool(p.is_optional), | 274 (p.uid + 1, p.size + '_value', element_size, CBool(p.is_optional), |
255 p.name)) | 275 p.name)) |
256 | 276 |
257 def CallParam(self): | 277 def CallParam(self): |
258 return self.param.name | 278 return self.param.name |
259 | 279 |
260 def IsArray(self): | 280 def IsArray(self): |
261 return True | 281 return True |
262 | 282 |
263 | 283 |
264 class StructInputImpl(ParamImpl): | 284 class ExtensibleStructInputImpl(ParamImpl): |
265 def DeclareVars(self, code): | 285 def DeclareVars(self, code): |
266 code << '%s %s;' % (self.param.param_type, self.param.name) | 286 code << '%s %s;' % (self.param.param_type, self.param.name) |
267 | 287 |
268 def ConvertParam(self): | 288 def ConvertParam(self): |
269 p = self.param | 289 p = self.param |
270 return ('ConvertStruct(nap, params[%d], %s, &%s)' % | 290 return ('ConvertExtensibleStructInput(nap, params[%d], %s, &%s)' % |
271 (p.uid + 1, CBool(p.is_optional), p.name)) | 291 (p.uid + 1, CBool(p.is_optional), p.name)) |
272 | 292 |
273 def CallParam(self): | 293 def CallParam(self): |
274 return self.param.name | 294 return self.param.name |
275 | 295 |
276 | |
277 def ImplForParam(p): | 296 def ImplForParam(p): |
278 if p.IsScalar(): | 297 if p.IsScalar(): |
279 if p.is_output: | 298 if p.is_output: |
280 if p.is_input: | 299 if p.is_input: |
281 return ScalarInOutImpl(p) | 300 return ScalarInOutImpl(p) |
282 else: | 301 else: |
283 return ScalarOutputImpl(p) | 302 return ScalarOutputImpl(p) |
284 else: | 303 else: |
285 return ScalarInputImpl(p) | 304 return ScalarInputImpl(p) |
286 elif p.is_array: | 305 elif p.is_array: |
287 return ArrayImpl(p) | 306 return ArrayImpl(p) |
288 elif p.is_struct: | 307 elif p.is_struct: |
289 return StructInputImpl(p) | 308 if p.is_input and not p.is_output and p.is_extensible: |
Mark Seaborn
2014/12/08 22:24:12
Fix indentation
Nick Bray (chromium)
2014/12/09 22:14:31
Done.
| |
290 else: | 309 return ExtensibleStructInputImpl(p) |
291 assert False, p | 310 if not p.is_input and p.is_output and not p.is_extensible: |
311 return ScalarOutputImpl(p) | |
312 assert False, p.name | |
292 | 313 |
293 | 314 |
294 def CBool(value): | 315 def CBool(value): |
295 return 'true' if value else 'false' | 316 return 'true' if value else 'false' |
296 | 317 |
297 | 318 |
298 # A trusted wrapper that validates the arguments passed from untrusted code | 319 # A trusted wrapper that validates the arguments passed from untrusted code |
299 # before passing them to the underlying public Mojo API. | 320 # before passing them to the underlying public Mojo API. |
300 def GenerateMojoSyscall(functions, out): | 321 def GenerateMojoSyscall(functions, out): |
301 template = jinja_env.get_template('mojo_syscall.cc.tmpl') | 322 template = jinja_env.get_template('mojo_syscall.cc.tmpl') |
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
395 | 416 |
396 out = OutFile(options.out_dir, 'libmojo.cc') | 417 out = OutFile(options.out_dir, 'libmojo.cc') |
397 GenerateLibMojo(mojo.functions, out) | 418 GenerateLibMojo(mojo.functions, out) |
398 | 419 |
399 out = OutFile(options.out_dir, 'mojo_syscall.cc') | 420 out = OutFile(options.out_dir, 'mojo_syscall.cc') |
400 GenerateMojoSyscall(mojo.functions, out) | 421 GenerateMojoSyscall(mojo.functions, out) |
401 | 422 |
402 | 423 |
403 if __name__ == '__main__': | 424 if __name__ == '__main__': |
404 main(sys.argv[1:]) | 425 main(sys.argv[1:]) |
OLD | NEW |