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 errno | 8 import errno |
9 import os.path | 9 import os.path |
10 import sys | 10 import sys |
(...skipping 216 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
227 name = self.param.name | 227 name = self.param.name |
228 if self.param.is_optional: | 228 if self.param.is_optional: |
229 code << 'if (%s_ptr != NULL) {' % (name) | 229 code << 'if (%s_ptr != NULL) {' % (name) |
230 with code.Indent(): | 230 with code.Indent(): |
231 code << '*%s_ptr = %s_value;' % (name, name) | 231 code << '*%s_ptr = %s_value;' % (name, name) |
232 code << '}' | 232 code << '}' |
233 else: | 233 else: |
234 code << '*%s_ptr = %s_value;' % (name, name) | 234 code << '*%s_ptr = %s_value;' % (name, name) |
235 | 235 |
236 | 236 |
| 237 class PointerInputImpl(ParamImpl): |
| 238 def DeclareVars(self, code): |
| 239 code << '%s %s_value;' % (self.param.base_type, self.param.name) |
| 240 |
| 241 def ConvertParam(self): |
| 242 p = self.param |
| 243 return ('ConvertPointerInput(nap, params[%d], &%s_value)' % |
| 244 (p.uid + 1, p.name)) |
| 245 |
| 246 def CallParam(self): |
| 247 return '%s_value' % self.param.name |
| 248 |
| 249 |
| 250 class PointerInOutImpl(ParamImpl): |
| 251 def DeclareVars(self, code): |
| 252 code << 'uint32_t volatile* %s_ptr;' % (self.param.name,) |
| 253 code << '%s %s_value;' % (self.param.base_type, self.param.name) |
| 254 |
| 255 def ConvertParam(self): |
| 256 p = self.param |
| 257 return ('ConvertPointerInOut(nap, params[%d], %s, &%s_value, &%s_ptr)' % |
| 258 (p.uid + 1, CBool(p.is_optional), p.name, p.name)) |
| 259 |
| 260 def CallParam(self): |
| 261 name = self.param.name |
| 262 expr = '&%s_value' % name |
| 263 if self.param.is_optional: |
| 264 expr = '%s_ptr ? %s : NULL' % (name, expr) |
| 265 return expr |
| 266 |
| 267 def CopyOut(self, code): |
| 268 assert not self.param.is_optional |
| 269 name = self.param.name |
| 270 if self.param.is_optional: |
| 271 code << 'if (%s_ptr != NULL) {' % (name) |
| 272 with code.Indent(): |
| 273 code << 'CopyOutPointer(nap, %s_value, %s_ptr);' % (name, name) |
| 274 code << '}' |
| 275 else: |
| 276 code << 'CopyOutPointer(nap, %s_value, %s_ptr);' % (name, name) |
| 277 |
237 class ArrayImpl(ParamImpl): | 278 class ArrayImpl(ParamImpl): |
238 def DeclareVars(self, code): | 279 def DeclareVars(self, code): |
239 code << '%s %s;' % (self.param.param_type, self.param.name) | 280 code << '%s %s;' % (self.param.param_type, self.param.name) |
240 | 281 |
241 def ConvertParam(self): | 282 def ConvertParam(self): |
242 p = self.param | 283 p = self.param |
243 if p.base_type == 'void': | 284 if p.base_type == 'void': |
244 element_size = '1' | 285 element_size = '1' |
245 else: | 286 else: |
246 element_size = 'sizeof(*%s)' % p.name | 287 element_size = 'sizeof(*%s)' % p.name |
(...skipping 14 matching lines...) Expand all Loading... |
261 code << '%s %s;' % (self.param.param_type, self.param.name) | 302 code << '%s %s;' % (self.param.param_type, self.param.name) |
262 | 303 |
263 def ConvertParam(self): | 304 def ConvertParam(self): |
264 p = self.param | 305 p = self.param |
265 return ('ConvertExtensibleStructInput(nap, params[%d], %s, &%s)' % | 306 return ('ConvertExtensibleStructInput(nap, params[%d], %s, &%s)' % |
266 (p.uid + 1, CBool(p.is_optional), p.name)) | 307 (p.uid + 1, CBool(p.is_optional), p.name)) |
267 | 308 |
268 def CallParam(self): | 309 def CallParam(self): |
269 return self.param.name | 310 return self.param.name |
270 | 311 |
| 312 |
271 def ImplForParam(p): | 313 def ImplForParam(p): |
272 if p.IsScalar(): | 314 if p.IsScalar(): |
273 if p.is_output: | 315 if p.is_output: |
274 if p.is_input: | 316 if p.is_pointer: |
| 317 return PointerInOutImpl(p) |
| 318 elif p.is_input: |
275 return ScalarInOutImpl(p) | 319 return ScalarInOutImpl(p) |
276 else: | 320 else: |
277 if p.is_always_written: | 321 if p.is_always_written: |
278 return ScalarOutputImpl(p) | 322 return ScalarOutputImpl(p) |
279 else: | 323 else: |
280 # Mojo defines that some of its outputs will not be set in specific | 324 # Mojo defines that some of its outputs will not be set in specific |
281 # cases. To avoid the complexity of determining if the output was set | 325 # cases. To avoid the complexity of determining if the output was set |
282 # by Mojo, copy the output's current value (possibly junk) and copy it | 326 # by Mojo, copy the output's current value (possibly junk) and copy it |
283 # back to untrusted memory afterwards. | 327 # back to untrusted memory afterwards. |
284 return ScalarInOutImpl(p) | 328 return ScalarInOutImpl(p) |
285 else: | 329 else: |
286 return ScalarInputImpl(p) | 330 if p.is_pointer: |
| 331 return PointerInputImpl(p) |
| 332 else: |
| 333 return ScalarInputImpl(p) |
287 elif p.is_array: | 334 elif p.is_array: |
288 return ArrayImpl(p) | 335 return ArrayImpl(p) |
289 elif p.is_struct: | 336 elif p.is_struct: |
290 if p.is_input and not p.is_output and p.is_extensible: | 337 if p.is_input and not p.is_output and p.is_extensible: |
291 return ExtensibleStructInputImpl(p) | 338 return ExtensibleStructInputImpl(p) |
292 if not p.is_input and p.is_output and not p.is_extensible: | 339 if not p.is_input and p.is_output and not p.is_extensible: |
293 return ScalarOutputImpl(p) | 340 return ScalarOutputImpl(p) |
294 assert False, p.name | 341 assert False, p.name |
295 | 342 |
296 | 343 |
297 def CBool(value): | 344 def CBool(value): |
298 return 'true' if value else 'false' | 345 return 'true' if value else 'false' |
299 | 346 |
300 | 347 |
301 # A trusted wrapper that validates the arguments passed from untrusted code | 348 # A trusted wrapper that validates the arguments passed from untrusted code |
302 # before passing them to the underlying public Mojo API. | 349 # before passing them to the underlying public Mojo API. |
303 def GenerateMojoSyscall(functions, common_vars, out): | 350 def GenerateMojoSyscall(functions, common_vars, out): |
304 template = jinja_env.get_template('mojo_syscall.cc.tmpl') | 351 template = jinja_env.get_template('mojo_syscall.cc.tmpl') |
305 | 352 |
306 code = CodeWriter() | 353 code = CodeWriter() |
307 code.PushMargin() | 354 code.PushMargin() |
308 | 355 |
309 for f in functions: | 356 for f in functions: |
310 is_implemented = True | 357 is_implemented = not f.broken_in_nacl |
311 | |
312 # Mojo API calls that take or return pointers are currently not supported. | |
313 # The underlying Mojo implementation is unaware of NaCl's address space. In | |
314 # addition, if we pass blindly pass the parameters through to the underlying | |
315 # Mojo API, memory corruption can result from pointer-size mistmatches. | |
316 for p in f.params: | |
317 if p.base_type.endswith("*"): | |
318 is_implemented = False | |
319 | 358 |
320 impls = [ImplForParam(p) for p in f.params] | 359 impls = [ImplForParam(p) for p in f.params] |
321 impls.append(ImplForParam(f.result_param)) | 360 impls.append(ImplForParam(f.result_param)) |
322 | 361 |
323 code << 'case %d:' % f.uid | 362 code << 'case %d:' % f.uid |
324 | 363 |
325 if not is_implemented: | 364 if not is_implemented: |
326 with code.Indent(): | 365 with code.Indent(): |
327 code << 'fprintf(stderr, "%s not implemented\\n");' % f.name | 366 code << 'fprintf(stderr, "%s not implemented\\n");' % f.name |
328 code << 'return -1;' | 367 code << 'return -1;' |
(...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
515 GenerateMojoSyscall(mojo.functions, common_vars, out) | 554 GenerateMojoSyscall(mojo.functions, common_vars, out) |
516 | 555 |
517 out = OutFile(full_platform_dir, 'mojo_irt.h') | 556 out = OutFile(full_platform_dir, 'mojo_irt.h') |
518 GenerateMojoIrtHeader(mojo.functions, common_vars, out) | 557 GenerateMojoIrtHeader(mojo.functions, common_vars, out) |
519 | 558 |
520 out = OutFile(full_bindings_dir, 'mojo_irt.c') | 559 out = OutFile(full_bindings_dir, 'mojo_irt.c') |
521 GenerateMojoIrtImplementation(mojo.functions, common_vars, out) | 560 GenerateMojoIrtImplementation(mojo.functions, common_vars, out) |
522 | 561 |
523 if __name__ == '__main__': | 562 if __name__ == '__main__': |
524 main() | 563 main() |
OLD | NEW |