| OLD | NEW |
| 1 // Copyright (c) 2012 The Native Client Authors. All rights reserved. | 1 // Copyright (c) 2012 The Native Client 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 | 5 |
| 6 #include "native_client/src/trusted/sel_universal/reverse_emulate.h" | 6 #include "native_client/src/trusted/sel_universal/reverse_emulate.h" |
| 7 #include <stdio.h> | 7 #include <stdio.h> |
| 8 #include <map> | 8 #include <map> |
| 9 #include <set> | 9 #include <set> |
| 10 #include <string> | 10 #include <string> |
| 11 | 11 |
| 12 #include "native_client/src/include/portability_io.h" | 12 #include "native_client/src/include/portability_io.h" |
| 13 #include "native_client/src/shared/platform/nacl_check.h" | 13 #include "native_client/src/shared/platform/nacl_check.h" |
| 14 #include "native_client/src/shared/platform/nacl_log.h" | 14 #include "native_client/src/shared/platform/nacl_log.h" |
| 15 #include "native_client/src/shared/platform/nacl_sync.h" |
| 16 #include "native_client/src/shared/platform/nacl_threads.h" |
| 15 #include "native_client/src/shared/platform/scoped_ptr_refcount.h" | 17 #include "native_client/src/shared/platform/scoped_ptr_refcount.h" |
| 16 #include "native_client/src/shared/srpc/nacl_srpc.h" | 18 #include "native_client/src/shared/srpc/nacl_srpc.h" |
| 17 #include "native_client/src/trusted/desc/nacl_desc_wrapper.h" | 19 #include "native_client/src/trusted/desc/nacl_desc_wrapper.h" |
| 18 #include "native_client/src/trusted/nonnacl_util/sel_ldr_launcher.h" | 20 #include "native_client/src/trusted/nonnacl_util/sel_ldr_launcher.h" |
| 19 #include "native_client/src/trusted/reverse_service/reverse_service.h" | 21 #include "native_client/src/trusted/reverse_service/reverse_service.h" |
| 20 #include "native_client/src/trusted/sel_universal/rpc_universal.h" | 22 #include "native_client/src/trusted/sel_universal/rpc_universal.h" |
| 21 #include "native_client/src/trusted/sel_universal/srpc_helper.h" | 23 #include "native_client/src/trusted/sel_universal/srpc_helper.h" |
| 22 | 24 |
| 23 | 25 |
| 24 // Mock of ReverseInterface for use by nexes. | 26 // Mock of ReverseInterface for use by nexes. |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 77 HandleToLauncherMap; | 79 HandleToLauncherMap; |
| 78 | 80 |
| 79 /* | 81 /* |
| 80 * TODO(phosek): Rather than using global ctor, SelLdrLauncher shall inherit | 82 * TODO(phosek): Rather than using global ctor, SelLdrLauncher shall inherit |
| 81 * from RefCountBase class and we shall use nacl::scoped_ptr_refcount to | 83 * from RefCountBase class and we shall use nacl::scoped_ptr_refcount to |
| 82 * automatically manage the reference and dispose it once it's no longer | 84 * automatically manage the reference and dispose it once it's no longer |
| 83 * being used (http://code.google.com/p/nativeclient/issues/detail?id=3050). | 85 * being used (http://code.google.com/p/nativeclient/issues/detail?id=3050). |
| 84 */ | 86 */ |
| 85 HandleToLauncherMap g_handle_to_launcher; | 87 HandleToLauncherMap g_handle_to_launcher; |
| 86 | 88 |
| 89 /* |
| 90 * TODO(phosek): These variables should be instance variables of Reverse |
| 91 * Emulate. However, we cannot make them such at the moment because they're |
| 92 * also being used by command handlers. This will require more significant |
| 93 * redesign/refactoring. |
| 94 */ |
| 95 int g_exited; |
| 96 NaClMutex g_exit_mu; |
| 97 NaClCondVar g_exit_cv; |
| 98 |
| 87 } // end namespace | 99 } // end namespace |
| 88 | 100 |
| 89 | 101 |
| 90 bool ReverseEmulateInit(NaClSrpcChannel* command_channel, | 102 bool ReverseEmulateInit(NaClSrpcChannel* command_channel, |
| 91 nacl::SelLdrLauncherStandalone* launcher) { | 103 nacl::SelLdrLauncherStandalone* launcher) { |
| 92 // Do the SRPC to the command channel to set up the reverse channel. | 104 // Do the SRPC to the command channel to set up the reverse channel. |
| 93 // This returns a NaClDesc* containing a socket address. | 105 // This returns a NaClDesc* containing a socket address. |
| 94 NaClLog(1, "ReverseEmulateInit: launching reverse RPC service\n"); | 106 NaClLog(1, "ReverseEmulateInit: launching reverse RPC service\n"); |
| 95 NaClDesc* h; | 107 NaClDesc* h; |
| 96 NaClSrpcResultCodes rpc_result = | 108 NaClSrpcResultCodes rpc_result = |
| 97 NaClSrpcInvokeBySignature(command_channel, "reverse_setup::h", &h); | 109 NaClSrpcInvokeBySignature(command_channel, "reverse_setup::h", &h); |
| 98 if (NACL_SRPC_RESULT_OK != rpc_result) { | 110 if (NACL_SRPC_RESULT_OK != rpc_result) { |
| 99 NaClLog(LOG_ERROR, "ReverseEmulateInit: reverse setup failed\n"); | 111 NaClLog(LOG_ERROR, "ReverseEmulateInit: reverse setup failed\n"); |
| 100 return false; | 112 return false; |
| 101 } | 113 } |
| 102 // Make a nacl::DescWrapper* from the NaClDesc* | 114 // Make a nacl::DescWrapper* from the NaClDesc* |
| 103 nacl::scoped_ptr<nacl::DescWrapper> conn_cap(launcher->WrapCleanup(h)); | 115 nacl::scoped_ptr<nacl::DescWrapper> conn_cap(launcher->WrapCleanup(h)); |
| 104 if (conn_cap == NULL) { | 116 if (conn_cap == NULL) { |
| 105 NaClLog(LOG_ERROR, "ReverseEmulateInit: reverse desc wrap failed\n"); | 117 NaClLog(LOG_ERROR, "ReverseEmulateInit: reverse desc wrap failed\n"); |
| 106 return false; | 118 return false; |
| 107 } | 119 } |
| 108 // The implementation of the ReverseInterface is our emulator class. | 120 // The implementation of the ReverseInterface is our emulator class. |
| 109 nacl::scoped_ptr<ReverseEmulate> reverse_interface(new ReverseEmulate()); | 121 nacl::scoped_ptr<ReverseEmulate> reverse_interface(new ReverseEmulate()); |
| 122 // Construct locks guarding exit status. |
| 123 NaClXMutexCtor(&g_exit_mu); |
| 124 NaClXCondVarCtor(&g_exit_cv); |
| 125 g_exited = false; |
| 110 // Create an instance of ReverseService, which connects to the socket | 126 // Create an instance of ReverseService, which connects to the socket |
| 111 // address and exports the services from our emulator. | 127 // address and exports the services from our emulator. |
| 112 g_reverse_service.reset(new nacl::ReverseService(conn_cap.get(), | 128 g_reverse_service.reset(new nacl::ReverseService(conn_cap.get(), |
| 113 reverse_interface->Ref())); | 129 reverse_interface->Ref())); |
| 114 if (g_reverse_service == NULL) { | 130 if (g_reverse_service == NULL) { |
| 115 NaClLog(LOG_ERROR, "ReverseEmulateInit: reverse service ctor failed\n"); | 131 NaClLog(LOG_ERROR, "ReverseEmulateInit: reverse service ctor failed\n"); |
| 116 return false; | 132 return false; |
| 117 } | 133 } |
| 118 // Successful creation of ReverseService took ownership of these. | 134 // Successful creation of ReverseService took ownership of these. |
| 119 reverse_interface.release(); | 135 reverse_interface.release(); |
| 120 conn_cap.release(); | 136 conn_cap.release(); |
| 121 // Starts the RPC handler for the reverse interface. | 137 // Starts the RPC handler for the reverse interface. |
| 122 if (!g_reverse_service->Start()) { | 138 if (!g_reverse_service->Start()) { |
| 123 NaClLog(LOG_ERROR, "ReverseEmulateInit: reverse service start failed\n"); | 139 NaClLog(LOG_ERROR, "ReverseEmulateInit: reverse service start failed\n"); |
| 124 return false; | 140 return false; |
| 125 } | 141 } |
| 126 return true; | 142 return true; |
| 127 } | 143 } |
| 128 | 144 |
| 129 void ReverseEmulateFini() { | 145 void ReverseEmulateFini() { |
| 130 CHECK(g_reverse_service != NULL); | 146 CHECK(g_reverse_service != NULL); |
| 131 g_reverse_service->WaitForServiceThreadsToExit(); | 147 g_reverse_service->WaitForServiceThreadsToExit(); |
| 132 g_reverse_service.reset(NULL); | 148 g_reverse_service.reset(NULL); |
| 149 NaClMutexDtor(&g_exit_mu); |
| 150 NaClCondVarDtor(&g_exit_cv); |
| 133 } | 151 } |
| 134 | 152 |
| 135 bool HandlerReverseEmuAddManifestMapping(NaClCommandLoop* ncl, | 153 bool HandlerReverseEmuAddManifestMapping(NaClCommandLoop* ncl, |
| 136 const std::vector<string>& args) { | 154 const std::vector<string>& args) { |
| 137 UNREFERENCED_PARAMETER(ncl); | 155 UNREFERENCED_PARAMETER(ncl); |
| 138 if (args.size() < 3) { | 156 if (args.size() < 3) { |
| 139 NaClLog(LOG_ERROR, "not enough args\n"); | 157 NaClLog(LOG_ERROR, "not enough args\n"); |
| 140 return false; | 158 return false; |
| 141 } | 159 } |
| 142 NaClLog(1, "HandlerReverseEmulateAddManifestMapping(%s) -> %s\n", | 160 NaClLog(1, "HandlerReverseEmulateAddManifestMapping(%s) -> %s\n", |
| (...skipping 12 matching lines...) Expand all Loading... |
| 155 } | 173 } |
| 156 printf("ReverseEmulate manifest mappings:\n"); | 174 printf("ReverseEmulate manifest mappings:\n"); |
| 157 for (KeyToFileMap::iterator i = g_key_to_file.begin(); | 175 for (KeyToFileMap::iterator i = g_key_to_file.begin(); |
| 158 i != g_key_to_file.end(); | 176 i != g_key_to_file.end(); |
| 159 ++i) { | 177 ++i) { |
| 160 printf("'%s': '%s'\n", i->first.c_str(), i->second.c_str()); | 178 printf("'%s': '%s'\n", i->first.c_str(), i->second.c_str()); |
| 161 } | 179 } |
| 162 return true; | 180 return true; |
| 163 } | 181 } |
| 164 | 182 |
| 183 bool HandlerWaitForExit(NaClCommandLoop* ncl, |
| 184 const std::vector<string>& args) { |
| 185 UNREFERENCED_PARAMETER(ncl); |
| 186 UNREFERENCED_PARAMETER(args); |
| 187 |
| 188 NaClXMutexLock(&g_exit_mu); |
| 189 while (!g_exited) { |
| 190 NaClXCondVarWait(&g_exit_cv, &g_exit_mu); |
| 191 } |
| 192 NaClXMutexUnlock(&g_exit_mu); |
| 193 |
| 194 return true; |
| 195 } |
| 196 |
| 165 ReverseEmulate::ReverseEmulate() { | 197 ReverseEmulate::ReverseEmulate() { |
| 166 NaClLog(1, "ReverseEmulate::ReverseEmulate\n"); | 198 NaClLog(1, "ReverseEmulate::ReverseEmulate\n"); |
| 167 } | 199 } |
| 168 | 200 |
| 169 ReverseEmulate::~ReverseEmulate() { | 201 ReverseEmulate::~ReverseEmulate() { |
| 170 NaClLog(1, "ReverseEmulate::~ReverseEmulate\n"); | 202 NaClLog(1, "ReverseEmulate::~ReverseEmulate\n"); |
| 171 } | 203 } |
| 172 | 204 |
| 173 void ReverseEmulate::Log(nacl::string message) { | 205 void ReverseEmulate::Log(nacl::string message) { |
| 174 NaClLog(1, "ReverseEmulate::Log (message=%s)\n", message.c_str()); | 206 NaClLog(1, "ReverseEmulate::Log (message=%s)\n", message.c_str()); |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 209 } | 241 } |
| 210 | 242 |
| 211 bool ReverseEmulate::CloseManifestEntry(int32_t desc) { | 243 bool ReverseEmulate::CloseManifestEntry(int32_t desc) { |
| 212 NaClLog(1, "ReverseEmulate::CloseManifestEntry (desc=%d)\n", desc); | 244 NaClLog(1, "ReverseEmulate::CloseManifestEntry (desc=%d)\n", desc); |
| 213 CLOSE(desc); | 245 CLOSE(desc); |
| 214 return true; | 246 return true; |
| 215 } | 247 } |
| 216 | 248 |
| 217 void ReverseEmulate::ReportCrash() { | 249 void ReverseEmulate::ReportCrash() { |
| 218 NaClLog(1, "ReverseEmulate::ReportCrash\n"); | 250 NaClLog(1, "ReverseEmulate::ReportCrash\n"); |
| 251 NaClXMutexLock(&g_exit_mu); |
| 252 g_exited = true; |
| 253 NaClXCondVarBroadcast(&g_exit_cv); |
| 254 NaClXMutexUnlock(&g_exit_mu); |
| 219 } | 255 } |
| 220 | 256 |
| 221 void ReverseEmulate::ReportExitStatus(int exit_status) { | 257 void ReverseEmulate::ReportExitStatus(int exit_status) { |
| 222 NaClLog(1, "ReverseEmulate::ReportExitStatus (exit_status=%d)\n", | 258 NaClLog(1, "ReverseEmulate::ReportExitStatus (exit_status=%d)\n", |
| 223 exit_status); | 259 exit_status); |
| 260 NaClXMutexLock(&g_exit_mu); |
| 261 g_exited = true; |
| 262 NaClXCondVarBroadcast(&g_exit_cv); |
| 263 NaClXMutexUnlock(&g_exit_mu); |
| 224 } | 264 } |
| 225 | 265 |
| 226 void ReverseEmulate::DoPostMessage(nacl::string message) { | 266 void ReverseEmulate::DoPostMessage(nacl::string message) { |
| 227 NaClLog(1, "ReverseEmulate::DoPostMessage (message=%s)\n", message.c_str()); | 267 NaClLog(1, "ReverseEmulate::DoPostMessage (message=%s)\n", message.c_str()); |
| 228 } | 268 } |
| 229 | 269 |
| 230 int ReverseEmulate::CreateProcess(nacl::DescWrapper** out_sock_addr, | 270 int ReverseEmulate::CreateProcess(nacl::DescWrapper** out_sock_addr, |
| 231 nacl::DescWrapper** out_app_addr) { | 271 nacl::DescWrapper** out_app_addr) { |
| 232 NaClLog(1, "ReverseEmulate::CreateProcess)\n"); | 272 NaClLog(1, "ReverseEmulate::CreateProcess)\n"); |
| 233 vector<nacl::string> command_prefix; | 273 vector<nacl::string> command_prefix; |
| (...skipping 27 matching lines...) Expand all Loading... |
| 261 } | 301 } |
| 262 | 302 |
| 263 int64_t ReverseEmulate::RequestQuotaForWrite(nacl::string file_id, | 303 int64_t ReverseEmulate::RequestQuotaForWrite(nacl::string file_id, |
| 264 int64_t offset, | 304 int64_t offset, |
| 265 int64_t length) { | 305 int64_t length) { |
| 266 NaClLog(1, "ReverseEmulate::RequestQuotaForWrite (file_id=%s, offset=%" | 306 NaClLog(1, "ReverseEmulate::RequestQuotaForWrite (file_id=%s, offset=%" |
| 267 NACL_PRId64", length=%"NACL_PRId64")\n", file_id.c_str(), offset, | 307 NACL_PRId64", length=%"NACL_PRId64")\n", file_id.c_str(), offset, |
| 268 length); | 308 length); |
| 269 return length; | 309 return length; |
| 270 } | 310 } |
| OLD | NEW |