1 // -*- c++ -*- 2 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 3 // Use of this source code is governed by a BSD-style license that can be 4 // found in the LICENSE file. 5 6 // The portable representation of an instance and root scriptable object. 7 // The PPAPI version of the plugin instantiates a subclass of this class. 8 9 #ifndef NATIVE_CLIENT_SRC_TRUSTED_PLUGIN_PLUGIN_H_ 10 #define NATIVE_CLIENT_SRC_TRUSTED_PLUGIN_PLUGIN_H_ 11 12 #include <stdio.h> 13 14 #include <string> 15 16 #include "native_client/src/include/nacl_macros.h" 17 #include "native_client/src/include/nacl_scoped_ptr.h" 18 19 #include "ppapi/c/private/ppb_nacl_private.h" 20 #include "ppapi/cpp/instance.h" 21 #include "ppapi/cpp/private/uma_private.h" 22 #include "ppapi/cpp/url_loader.h" 23 #include "ppapi/cpp/var.h" 24 #include "ppapi/cpp/view.h" 25 26 #include "ppapi/native_client/src/trusted/plugin/nacl_subprocess.h" 27 #include "ppapi/native_client/src/trusted/plugin/pnacl_coordinator.h" 28 #include "ppapi/native_client/src/trusted/plugin/service_runtime.h" 29 #include "ppapi/native_client/src/trusted/plugin/utility.h" 30 31 #include "ppapi/utility/completion_callback_factory.h" 32 33 namespace nacl { 34 class DescWrapper; 35 class DescWrapperFactory; 36 } // namespace nacl 37 38 namespace pp { 39 class CompletionCallback; 40 class URLLoader; 41 class URLUtil_Dev; 42 } 43 44 namespace plugin { 45 46 class ErrorInfo; 47 class Manifest; 48 49 int32_t ConvertFileDescriptor(PP_FileHandle handle); 50 51 const PP_NaClFileInfo kInvalidNaClFileInfo = { 52 PP_kInvalidFileHandle, 53 0, // token_lo 54 0, // token_hi 55 }; 56 57 class Plugin : public pp::Instance { 58 public: 59 explicit Plugin(PP_Instance instance); 60 61 // ----- Methods inherited from pp::Instance: 62 63 // Initializes this plugin with <embed/object ...> tag attribute count |argc|, 64 // names |argn| and values |argn|. Returns false on failure. 65 // Gets called by the browser right after New(). 66 virtual bool Init(uint32_t argc, const char* argn[], const char* argv[]); 67 68 // Handles document load, when the plugin is a MIME type handler. 69 virtual bool HandleDocumentLoad(const pp::URLLoader& url_loader); 70 71 // Load support. 72 // 73 // Starts NaCl module but does not wait until low-level 74 // initialization (e.g. ld.so dynamic loading of manifest files) is 75 // done. The module will become ready later, asynchronously. Other 76 // event handlers should block until the module is ready before 77 // trying to communicate with it, i.e., until nacl_ready_state is 78 // DONE. 79 // 80 // NB: currently we do not time out, so if the untrusted code 81 // does not signal that it is ready, then we will deadlock the main 82 // thread of the renderer on this subsequent event delivery. We 83 // should include a time-out at which point we declare the 84 // nacl_ready_state to be done, and let the normal crash detection 85 // mechanism(s) take over. 86 void LoadNaClModule(PP_NaClFileInfo file_info, 87 bool uses_nonsfi_mode, 88 bool enable_dyncode_syscalls, 89 bool enable_exception_handling, 90 bool enable_crash_throttling, 91 const pp::CompletionCallback& init_done_cb); 92 93 // Finish hooking interfaces up, after low-level initialization is 94 // complete. 95 bool LoadNaClModuleContinuationIntern(); 96 97 // Continuation for starting SRPC/JSProxy services as appropriate. 98 // This is invoked as a callback when the NaCl module makes the 99 // init_done reverse RPC to tell us that low-level initialization 100 // such as ld.so processing is done. That initialization requires 101 // that the main thread be free in order to do Pepper 102 // main-thread-only operations such as file processing. 103 bool LoadNaClModuleContinuation(int32_t pp_error); 104 105 // Load support. 106 // A helper SRPC NaCl module can be loaded given a PP_NaClFileInfo. 107 // Blocks until the helper module signals initialization is done. 108 // Does not update nacl_module_origin(). 109 // Returns NULL or the NaClSubprocess of the new helper NaCl module. 110 NaClSubprocess* LoadHelperNaClModule(const std::string& helper_url, 111 PP_NaClFileInfo file_info, 112 ErrorInfo* error_info); 113 114 // Report an error that was encountered while loading a module. 115 void ReportLoadError(const ErrorInfo& error_info); 116 117 nacl::DescWrapperFactory* wrapper_factory() const { return wrapper_factory_; } 118 119 const PPB_NaCl_Private* nacl_interface() const { return nacl_interface_; } 120 pp::UMAPrivate& uma_interface() { return uma_interface_; } 121 122 private: 123 NACL_DISALLOW_COPY_AND_ASSIGN(Plugin); 124 // The browser will invoke the destructor via the pp::Instance 125 // pointer to this object, not from base's Delete(). 126 ~Plugin(); 127 128 // Shuts down socket connection, service runtime, and receive thread, 129 // in this order, for the main nacl subprocess. 130 void ShutDownSubprocesses(); 131 132 // Histogram helper functions, internal to Plugin so they can use 133 // uma_interface_ normally. 134 void HistogramTimeSmall(const std::string& name, int64_t ms); 135 136 // Loads and starts a helper (e.g. llc, ld) NaCl module. 137 // Only to be used from a background (non-main) thread for the PNaCl 138 // translator. This will fully initialize the |subprocess| if the load was 139 // successful. 140 bool LoadHelperNaClModuleInternal(NaClSubprocess* subprocess, 141 const SelLdrStartParams& params); 142 143 // Start sel_ldr from the main thread, given the start params. 144 // |pp_error| is set by CallOnMainThread (should be PP_OK). 145 void StartSelLdrOnMainThread(int32_t pp_error, 146 ServiceRuntime* service_runtime, 147 const SelLdrStartParams& params, 148 pp::CompletionCallback callback); 149 150 // Signals that StartSelLdr has finished. 151 // This is invoked on the main thread. 152 void SignalStartSelLdrDone(int32_t pp_error, 153 bool* started, 154 ServiceRuntime* service_runtime); 155 156 // This is invoked on the main thread. 157 void StartNexe(int32_t pp_error, ServiceRuntime* service_runtime); 158 159 // Callback used when getting the URL for the .nexe file. If the URL loading 160 // is successful, the file descriptor is opened and can be passed to sel_ldr 161 // with the sandbox on. 162 void NexeFileDidOpen(int32_t pp_error); 163 void NexeFileDidOpenContinuation(int32_t pp_error); 164 165 // Callback used when a .nexe is translated from bitcode. If the translation 166 // is successful, the file descriptor is opened and can be passed to sel_ldr 167 // with the sandbox on. 168 void BitcodeDidTranslate(int32_t pp_error); 169 void BitcodeDidTranslateContinuation(int32_t pp_error); 170 171 // NaCl ISA selection manifest file support. The manifest file is specified 172 // using the "nacl" attribute in the <embed> tag. First, the manifest URL (or 173 // data: URI) is fetched, then the JSON is parsed. Once a valid .nexe is 174 // chosen for the sandbox ISA, any current service runtime is shut down, the 175 // .nexe is loaded and run. 176 177 // Callback used when getting the manifest file as a local file descriptor. 178 void NaClManifestFileDidOpen(int32_t pp_error); 179 180 // Processes the JSON manifest string and starts loading the nexe. 181 void ProcessNaClManifest(const std::string& manifest_json); 182 183 // Keep track of the NaCl module subprocess that was spun up in the plugin. 184 NaClSubprocess main_subprocess_; 185 186 bool uses_nonsfi_mode_; 187 188 nacl::DescWrapperFactory* wrapper_factory_; 189 190 pp::CompletionCallbackFactory<Plugin> callback_factory_; 191 192 nacl::scoped_ptr<PnaclCoordinator> pnacl_coordinator_; 193 194 int exit_status_; 195 196 PP_NaClFileInfo nexe_file_info_; 197 198 const PPB_NaCl_Private* nacl_interface_; 199 pp::UMAPrivate uma_interface_; 200 }; 201 202 } // namespace plugin 203 204 #endif // NATIVE_CLIENT_SRC_TRUSTED_PLUGIN_PLUGIN_H_ 205