Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(246)

Side by Side Diff: ppapi/native_client/src/trusted/plugin/plugin.cc

Issue 177113009: Support non-SFI mode in NaCl manifest file. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Rebase Created 6 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #ifdef _MSC_VER 5 #ifdef _MSC_VER
6 // Do not warn about use of std::copy with raw pointers. 6 // Do not warn about use of std::copy with raw pointers.
7 #pragma warning(disable : 4996) 7 #pragma warning(disable : 4996)
8 #endif 8 #endif
9 9
10 #include "ppapi/native_client/src/trusted/plugin/plugin.h" 10 #include "ppapi/native_client/src/trusted/plugin/plugin.h"
(...skipping 265 matching lines...) Expand 10 before | Expand all | Expand 10 after
276 HistogramEnumerate(name, sample, 7, 6); 276 HistogramEnumerate(name, sample, 7, 6);
277 } 277 }
278 278
279 bool Plugin::LoadNaClModuleFromBackgroundThread( 279 bool Plugin::LoadNaClModuleFromBackgroundThread(
280 nacl::DescWrapper* wrapper, 280 nacl::DescWrapper* wrapper,
281 NaClSubprocess* subprocess, 281 NaClSubprocess* subprocess,
282 const Manifest* manifest, 282 const Manifest* manifest,
283 const SelLdrStartParams& params) { 283 const SelLdrStartParams& params) {
284 CHECK(!pp::Module::Get()->core()->IsMainThread()); 284 CHECK(!pp::Module::Get()->core()->IsMainThread());
285 ServiceRuntime* service_runtime = 285 ServiceRuntime* service_runtime =
286 new ServiceRuntime(this, manifest, false, 286 new ServiceRuntime(this, manifest, false, uses_nonsfi_mode_,
287 pp::BlockUntilComplete(), pp::BlockUntilComplete()); 287 pp::BlockUntilComplete(), pp::BlockUntilComplete());
288 subprocess->set_service_runtime(service_runtime); 288 subprocess->set_service_runtime(service_runtime);
289 PLUGIN_PRINTF(("Plugin::LoadNaClModuleFromBackgroundThread " 289 PLUGIN_PRINTF(("Plugin::LoadNaClModuleFromBackgroundThread "
290 "(service_runtime=%p)\n", 290 "(service_runtime=%p)\n",
291 static_cast<void*>(service_runtime))); 291 static_cast<void*>(service_runtime)));
292 292
293 // Now start the SelLdr instance. This must be created on the main thread. 293 // Now start the SelLdr instance. This must be created on the main thread.
294 bool service_runtime_started; 294 bool service_runtime_started;
295 pp::CompletionCallback sel_ldr_callback = 295 pp::CompletionCallback sel_ldr_callback =
296 callback_factory_.NewCallback(&Plugin::SignalStartSelLdrDone, 296 callback_factory_.NewCallback(&Plugin::SignalStartSelLdrDone,
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
332 } 332 }
333 333
334 void Plugin::SignalStartSelLdrDone(int32_t pp_error, 334 void Plugin::SignalStartSelLdrDone(int32_t pp_error,
335 bool* started, 335 bool* started,
336 ServiceRuntime* service_runtime) { 336 ServiceRuntime* service_runtime) {
337 *started = (pp_error == PP_OK); 337 *started = (pp_error == PP_OK);
338 service_runtime->SignalStartSelLdrDone(); 338 service_runtime->SignalStartSelLdrDone();
339 } 339 }
340 340
341 void Plugin::LoadNaClModule(nacl::DescWrapper* wrapper, 341 void Plugin::LoadNaClModule(nacl::DescWrapper* wrapper,
342 bool uses_nonsfi_mode,
342 bool enable_dyncode_syscalls, 343 bool enable_dyncode_syscalls,
343 bool enable_exception_handling, 344 bool enable_exception_handling,
344 bool enable_crash_throttling, 345 bool enable_crash_throttling,
345 const pp::CompletionCallback& init_done_cb, 346 const pp::CompletionCallback& init_done_cb,
346 const pp::CompletionCallback& crash_cb) { 347 const pp::CompletionCallback& crash_cb) {
347 nacl::scoped_ptr<nacl::DescWrapper> scoped_wrapper(wrapper); 348 nacl::scoped_ptr<nacl::DescWrapper> scoped_wrapper(wrapper);
348 CHECK(pp::Module::Get()->core()->IsMainThread()); 349 CHECK(pp::Module::Get()->core()->IsMainThread());
349 // Before forking a new sel_ldr process, ensure that we do not leak 350 // Before forking a new sel_ldr process, ensure that we do not leak
350 // the ServiceRuntime object for an existing subprocess, and that any 351 // the ServiceRuntime object for an existing subprocess, and that any
351 // associated listener threads do not go unjoined because if they 352 // associated listener threads do not go unjoined because if they
352 // outlive the Plugin object, they will not be memory safe. 353 // outlive the Plugin object, they will not be memory safe.
353 ShutDownSubprocesses(); 354 ShutDownSubprocesses();
354 SelLdrStartParams params(manifest_base_url(), 355 SelLdrStartParams params(manifest_base_url(),
355 true /* uses_irt */, 356 true /* uses_irt */,
356 true /* uses_ppapi */, 357 true /* uses_ppapi */,
358 uses_nonsfi_mode,
357 enable_dev_interfaces_, 359 enable_dev_interfaces_,
358 enable_dyncode_syscalls, 360 enable_dyncode_syscalls,
359 enable_exception_handling, 361 enable_exception_handling,
360 enable_crash_throttling); 362 enable_crash_throttling);
361 ErrorInfo error_info; 363 ErrorInfo error_info;
362 ServiceRuntime* service_runtime = 364 ServiceRuntime* service_runtime =
363 new ServiceRuntime(this, manifest_.get(), true, init_done_cb, crash_cb); 365 new ServiceRuntime(this, manifest_.get(), true, uses_nonsfi_mode,
366 init_done_cb, crash_cb);
364 main_subprocess_.set_service_runtime(service_runtime); 367 main_subprocess_.set_service_runtime(service_runtime);
365 PLUGIN_PRINTF(("Plugin::LoadNaClModule (service_runtime=%p)\n", 368 PLUGIN_PRINTF(("Plugin::LoadNaClModule (service_runtime=%p)\n",
366 static_cast<void*>(service_runtime))); 369 static_cast<void*>(service_runtime)));
367 if (NULL == service_runtime) { 370 if (NULL == service_runtime) {
368 error_info.SetReport( 371 error_info.SetReport(
369 PP_NACL_ERROR_SEL_LDR_INIT, 372 PP_NACL_ERROR_SEL_LDR_INIT,
370 "sel_ldr init failure " + main_subprocess_.description()); 373 "sel_ldr init failure " + main_subprocess_.description());
371 ReportLoadError(error_info); 374 ReportLoadError(error_info);
372 return; 375 return;
373 } 376 }
(...skipping 17 matching lines...) Expand all
391 bool nexe_loaded = service_runtime->LoadNexeAndStart(wrapper, crash_cb); 394 bool nexe_loaded = service_runtime->LoadNexeAndStart(wrapper, crash_cb);
392 PLUGIN_PRINTF(("Plugin::LoadNaClModule (nexe_loaded=%d)\n", 395 PLUGIN_PRINTF(("Plugin::LoadNaClModule (nexe_loaded=%d)\n",
393 nexe_loaded)); 396 nexe_loaded));
394 if (nexe_loaded) { 397 if (nexe_loaded) {
395 PLUGIN_PRINTF(("Plugin::LoadNaClModule (%s)\n", 398 PLUGIN_PRINTF(("Plugin::LoadNaClModule (%s)\n",
396 main_subprocess_.detailed_description().c_str())); 399 main_subprocess_.detailed_description().c_str()));
397 } 400 }
398 } 401 }
399 402
400 bool Plugin::LoadNaClModuleContinuationIntern(ErrorInfo* error_info) { 403 bool Plugin::LoadNaClModuleContinuationIntern(ErrorInfo* error_info) {
401 if (!main_subprocess_.StartSrpcServices()) { 404 if (!uses_nonsfi_mode_) {
402 // The NaCl process probably crashed. On Linux, a crash causes this error, 405 if (!main_subprocess_.StartSrpcServices()) {
403 // while on other platforms, the error is detected below, when we attempt to 406 // The NaCl process probably crashed. On Linux, a crash causes this
404 // start the proxy. Report a module initialization error here, to make it 407 // error, while on other platforms, the error is detected below, when we
405 // less confusing for developers. 408 // attempt to start the proxy. Report a module initialization error here,
406 NaClLog(LOG_ERROR, "LoadNaClModuleContinuationIntern: " 409 // to make it less confusing for developers.
407 "StartSrpcServices failed\n"); 410 NaClLog(LOG_ERROR, "LoadNaClModuleContinuationIntern: "
408 error_info->SetReport(PP_NACL_ERROR_START_PROXY_MODULE, 411 "StartSrpcServices failed\n");
409 "could not initialize module."); 412 error_info->SetReport(PP_NACL_ERROR_START_PROXY_MODULE,
410 return false; 413 "could not initialize module.");
414 return false;
415 }
411 } 416 }
412 PP_ExternalPluginResult ipc_result = 417 PP_ExternalPluginResult ipc_result =
413 nacl_interface_->StartPpapiProxy(pp_instance()); 418 nacl_interface_->StartPpapiProxy(pp_instance());
414 if (ipc_result == PP_EXTERNAL_PLUGIN_OK) { 419 if (ipc_result == PP_EXTERNAL_PLUGIN_OK) {
415 // Log the amound of time that has passed between the trusted plugin being 420 // Log the amound of time that has passed between the trusted plugin being
416 // initialized and the untrusted plugin being initialized. This is 421 // initialized and the untrusted plugin being initialized. This is
417 // (roughly) the cost of using NaCl, in terms of startup time. 422 // (roughly) the cost of using NaCl, in terms of startup time.
418 HistogramStartupTimeMedium( 423 HistogramStartupTimeMedium(
419 "NaCl.Perf.StartupTime.NaClOverhead", 424 "NaCl.Perf.StartupTime.NaClOverhead",
420 static_cast<float>(NaClGetTimeOfDayMicroseconds() - init_time_) 425 static_cast<float>(NaClGetTimeOfDayMicroseconds() - init_time_)
(...skipping 27 matching lines...) Expand all
448 453
449 // Do not report UMA stats for translator-related nexes. 454 // Do not report UMA stats for translator-related nexes.
450 // TODO(sehr): define new UMA stats for translator related nexe events. 455 // TODO(sehr): define new UMA stats for translator related nexe events.
451 // NOTE: The PNaCl translator nexes are not built to use the IRT. This is 456 // NOTE: The PNaCl translator nexes are not built to use the IRT. This is
452 // done to save on address space and swap space. 457 // done to save on address space and swap space.
453 // TODO(jvoung): See if we still need the uses_ppapi variable, now that 458 // TODO(jvoung): See if we still need the uses_ppapi variable, now that
454 // LaunchSelLdr always happens on the main thread. 459 // LaunchSelLdr always happens on the main thread.
455 SelLdrStartParams params(manifest_base_url(), 460 SelLdrStartParams params(manifest_base_url(),
456 false /* uses_irt */, 461 false /* uses_irt */,
457 false /* uses_ppapi */, 462 false /* uses_ppapi */,
463 false /* uses_nonsfi_mode */,
458 enable_dev_interfaces_, 464 enable_dev_interfaces_,
459 false /* enable_dyncode_syscalls */, 465 false /* enable_dyncode_syscalls */,
460 false /* enable_exception_handling */, 466 false /* enable_exception_handling */,
461 true /* enable_crash_throttling */); 467 true /* enable_crash_throttling */);
462 if (!LoadNaClModuleFromBackgroundThread(wrapper, nacl_subprocess.get(), 468 if (!LoadNaClModuleFromBackgroundThread(wrapper, nacl_subprocess.get(),
463 manifest, params)) { 469 manifest, params)) {
464 return NULL; 470 return NULL;
465 } 471 }
466 // We need not wait for the init_done callback. We can block 472 // We need not wait for the init_done callback. We can block
467 // here in StartSrpcServices, since helper NaCl modules 473 // here in StartSrpcServices, since helper NaCl modules
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after
579 } 585 }
580 } 586 }
581 587
582 PLUGIN_PRINTF(("Plugin::Init (status=%d)\n", status)); 588 PLUGIN_PRINTF(("Plugin::Init (status=%d)\n", status));
583 return status; 589 return status;
584 } 590 }
585 591
586 Plugin::Plugin(PP_Instance pp_instance) 592 Plugin::Plugin(PP_Instance pp_instance)
587 : pp::Instance(pp_instance), 593 : pp::Instance(pp_instance),
588 main_subprocess_("main subprocess", NULL, NULL), 594 main_subprocess_("main subprocess", NULL, NULL),
595 uses_nonsfi_mode_(false),
589 nexe_error_reported_(false), 596 nexe_error_reported_(false),
590 wrapper_factory_(NULL), 597 wrapper_factory_(NULL),
591 enable_dev_interfaces_(false), 598 enable_dev_interfaces_(false),
592 is_installed_(false), 599 is_installed_(false),
593 init_time_(0), 600 init_time_(0),
594 ready_time_(0), 601 ready_time_(0),
595 nexe_size_(0), 602 nexe_size_(0),
596 time_of_last_progress_event_(0), 603 time_of_last_progress_event_(0),
597 exit_status_(-1), 604 exit_status_(-1),
598 nacl_interface_(NULL), 605 nacl_interface_(NULL),
(...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after
753 LENGTH_IS_COMPUTABLE, 760 LENGTH_IS_COMPUTABLE,
754 nexe_bytes_read, 761 nexe_bytes_read,
755 nexe_bytes_read); 762 nexe_bytes_read);
756 763
757 load_start_ = NaClGetTimeOfDayMicroseconds(); 764 load_start_ = NaClGetTimeOfDayMicroseconds();
758 nacl::scoped_ptr<nacl::DescWrapper> 765 nacl::scoped_ptr<nacl::DescWrapper>
759 wrapper(wrapper_factory()->MakeFileDesc(file_desc_ok_to_close, O_RDONLY)); 766 wrapper(wrapper_factory()->MakeFileDesc(file_desc_ok_to_close, O_RDONLY));
760 NaClLog(4, "NexeFileDidOpen: invoking LoadNaClModule\n"); 767 NaClLog(4, "NexeFileDidOpen: invoking LoadNaClModule\n");
761 LoadNaClModule( 768 LoadNaClModule(
762 wrapper.release(), 769 wrapper.release(),
770 uses_nonsfi_mode_,
763 true, /* enable_dyncode_syscalls */ 771 true, /* enable_dyncode_syscalls */
764 true, /* enable_exception_handling */ 772 true, /* enable_exception_handling */
765 false, /* enable_crash_throttling */ 773 false, /* enable_crash_throttling */
766 callback_factory_.NewCallback(&Plugin::NexeFileDidOpenContinuation), 774 callback_factory_.NewCallback(&Plugin::NexeFileDidOpenContinuation),
767 callback_factory_.NewCallback(&Plugin::NexeDidCrash)); 775 callback_factory_.NewCallback(&Plugin::NexeDidCrash));
768 } 776 }
769 777
770 void Plugin::NexeFileDidOpenContinuation(int32_t pp_error) { 778 void Plugin::NexeFileDidOpenContinuation(int32_t pp_error) {
771 ErrorInfo error_info; 779 ErrorInfo error_info;
772 bool was_successful; 780 bool was_successful;
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after
870 // Error should have been reported by pnacl. Just return. 878 // Error should have been reported by pnacl. Just return.
871 PLUGIN_PRINTF(("Plugin::BitcodeDidTranslate error in Pnacl\n")); 879 PLUGIN_PRINTF(("Plugin::BitcodeDidTranslate error in Pnacl\n"));
872 return; 880 return;
873 } 881 }
874 882
875 // Inform JavaScript that we successfully translated the bitcode to a nexe. 883 // Inform JavaScript that we successfully translated the bitcode to a nexe.
876 nacl::scoped_ptr<nacl::DescWrapper> 884 nacl::scoped_ptr<nacl::DescWrapper>
877 wrapper(pnacl_coordinator_.get()->ReleaseTranslatedFD()); 885 wrapper(pnacl_coordinator_.get()->ReleaseTranslatedFD());
878 LoadNaClModule( 886 LoadNaClModule(
879 wrapper.release(), 887 wrapper.release(),
888 false, /* uses_nonsfi_mode */
880 false, /* enable_dyncode_syscalls */ 889 false, /* enable_dyncode_syscalls */
881 false, /* enable_exception_handling */ 890 false, /* enable_exception_handling */
882 true, /* enable_crash_throttling */ 891 true, /* enable_crash_throttling */
883 callback_factory_.NewCallback(&Plugin::BitcodeDidTranslateContinuation), 892 callback_factory_.NewCallback(&Plugin::BitcodeDidTranslateContinuation),
884 callback_factory_.NewCallback(&Plugin::NexeDidCrash)); 893 callback_factory_.NewCallback(&Plugin::NexeDidCrash));
885 } 894 }
886 895
887 void Plugin::BitcodeDidTranslateContinuation(int32_t pp_error) { 896 void Plugin::BitcodeDidTranslateContinuation(int32_t pp_error) {
888 ErrorInfo error_info; 897 ErrorInfo error_info;
889 bool was_successful = LoadNaClModuleContinuationIntern(&error_info); 898 bool was_successful = LoadNaClModuleContinuationIntern(&error_info);
(...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after
1027 ReportLoadError(error_info); 1036 ReportLoadError(error_info);
1028 return; 1037 return;
1029 } 1038 }
1030 1039
1031 ProcessNaClManifest(json_buffer); 1040 ProcessNaClManifest(json_buffer);
1032 } 1041 }
1033 1042
1034 void Plugin::ProcessNaClManifest(const nacl::string& manifest_json) { 1043 void Plugin::ProcessNaClManifest(const nacl::string& manifest_json) {
1035 HistogramSizeKB("NaCl.Perf.Size.Manifest", 1044 HistogramSizeKB("NaCl.Perf.Size.Manifest",
1036 static_cast<int32_t>(manifest_json.length() / 1024)); 1045 static_cast<int32_t>(manifest_json.length() / 1024));
1037 nacl::string program_url;
1038 PnaclOptions pnacl_options;
1039 ErrorInfo error_info; 1046 ErrorInfo error_info;
1040 if (!SetManifestObject(manifest_json, &error_info)) { 1047 if (!SetManifestObject(manifest_json, &error_info)) {
1041 ReportLoadError(error_info); 1048 ReportLoadError(error_info);
1042 return; 1049 return;
1043 } 1050 }
1044 1051
1045 if (manifest_->GetProgramURL(&program_url, &pnacl_options, &error_info)) { 1052 nacl::string program_url;
1053 PnaclOptions pnacl_options;
1054 bool uses_nonsfi_mode;
1055 if (manifest_->GetProgramURL(
1056 &program_url, &pnacl_options, &uses_nonsfi_mode, &error_info)) {
1046 is_installed_ = GetUrlScheme(program_url) == SCHEME_CHROME_EXTENSION; 1057 is_installed_ = GetUrlScheme(program_url) == SCHEME_CHROME_EXTENSION;
1058 uses_nonsfi_mode_ = uses_nonsfi_mode;
1047 set_nacl_ready_state(LOADING); 1059 set_nacl_ready_state(LOADING);
1048 // Inform JavaScript that we found a nexe URL to load. 1060 // Inform JavaScript that we found a nexe URL to load.
1049 EnqueueProgressEvent(PP_NACL_EVENT_PROGRESS); 1061 EnqueueProgressEvent(PP_NACL_EVENT_PROGRESS);
1050 if (pnacl_options.translate()) { 1062 if (pnacl_options.translate()) {
1051 pp::CompletionCallback translate_callback = 1063 pp::CompletionCallback translate_callback =
1052 callback_factory_.NewCallback(&Plugin::BitcodeDidTranslate); 1064 callback_factory_.NewCallback(&Plugin::BitcodeDidTranslate);
1053 // Will always call the callback on success or failure. 1065 // Will always call the callback on success or failure.
1054 pnacl_coordinator_.reset( 1066 pnacl_coordinator_.reset(
1055 PnaclCoordinator::BitcodeToNative(this, 1067 PnaclCoordinator::BitcodeToNative(this,
1056 program_url, 1068 program_url,
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
1130 1142
1131 bool Plugin::SetManifestObject(const nacl::string& manifest_json, 1143 bool Plugin::SetManifestObject(const nacl::string& manifest_json,
1132 ErrorInfo* error_info) { 1144 ErrorInfo* error_info) {
1133 PLUGIN_PRINTF(("Plugin::SetManifestObject(): manifest_json='%s'.\n", 1145 PLUGIN_PRINTF(("Plugin::SetManifestObject(): manifest_json='%s'.\n",
1134 manifest_json.c_str())); 1146 manifest_json.c_str()));
1135 if (error_info == NULL) 1147 if (error_info == NULL)
1136 return false; 1148 return false;
1137 // Determine whether lookups should use portable (i.e., pnacl versions) 1149 // Determine whether lookups should use portable (i.e., pnacl versions)
1138 // rather than platform-specific files. 1150 // rather than platform-specific files.
1139 bool is_pnacl = (mime_type() == kPnaclMIMEType); 1151 bool is_pnacl = (mime_type() == kPnaclMIMEType);
1152 bool nonsfi_mode_enabled =
1153 PP_ToBool(nacl_interface_->IsNonSFIModeEnabled());
1140 bool pnacl_debug = GetNaClInterface()->NaClDebugStubEnabled(); 1154 bool pnacl_debug = GetNaClInterface()->NaClDebugStubEnabled();
1141 nacl::scoped_ptr<JsonManifest> json_manifest( 1155 nacl::scoped_ptr<JsonManifest> json_manifest(
1142 new JsonManifest(url_util_, 1156 new JsonManifest(url_util_,
1143 manifest_base_url(), 1157 manifest_base_url(),
1144 (is_pnacl ? kPortableISA : GetSandboxISA()), 1158 (is_pnacl ? kPortableISA : GetSandboxISA()),
1159 nonsfi_mode_enabled,
1145 pnacl_debug)); 1160 pnacl_debug));
1146 if (!json_manifest->Init(manifest_json, error_info)) { 1161 if (!json_manifest->Init(manifest_json, error_info)) {
1147 return false; 1162 return false;
1148 } 1163 }
1149 manifest_.reset(json_manifest.release()); 1164 manifest_.reset(json_manifest.release());
1150 return true; 1165 return true;
1151 } 1166 }
1152 1167
1153 void Plugin::UrlDidOpenForStreamAsFile(int32_t pp_error, 1168 void Plugin::UrlDidOpenForStreamAsFile(int32_t pp_error,
1154 FileDownloader*& url_downloader, 1169 FileDownloader*& url_downloader,
(...skipping 324 matching lines...) Expand 10 before | Expand all | Expand 10 after
1479 DCHECK(pp::Module::Get()->core()->IsMainThread()); 1494 DCHECK(pp::Module::Get()->core()->IsMainThread());
1480 DCHECK(nacl_interface_); 1495 DCHECK(nacl_interface_);
1481 exit_status_ = exit_status; 1496 exit_status_ = exit_status;
1482 nacl_interface_->SetReadOnlyProperty(pp_instance(), 1497 nacl_interface_->SetReadOnlyProperty(pp_instance(),
1483 pp::Var("exitStatus").pp_var(), 1498 pp::Var("exitStatus").pp_var(),
1484 pp::Var(exit_status_).pp_var()); 1499 pp::Var(exit_status_).pp_var());
1485 } 1500 }
1486 1501
1487 1502
1488 } // namespace plugin 1503 } // namespace plugin
OLDNEW
« no previous file with comments | « ppapi/native_client/src/trusted/plugin/plugin.h ('k') | ppapi/native_client/src/trusted/plugin/pnacl_coordinator.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698