diff options
author | jvoung@chromium.org <jvoung@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-06-30 16:18:53 +0000 |
---|---|---|
committer | jvoung@chromium.org <jvoung@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-06-30 16:18:53 +0000 |
commit | 5e64f63863b0218ad30ed859771ef5475b08c6c4 (patch) | |
tree | 38e77dba617d1568c74b35c4d6704318eae0a3b2 | |
parent | 14693e1b149daad671fca474b438c01359bf48c7 (diff) | |
download | chromium_src-5e64f63863b0218ad30ed859771ef5475b08c6c4.zip chromium_src-5e64f63863b0218ad30ed859771ef5475b08c6c4.tar.gz chromium_src-5e64f63863b0218ad30ed859771ef5475b08c6c4.tar.bz2 |
Enable mmap and identity-based validation caching on pnacl-{llc,ld}.nexe
Register the executables w/ the validation cache on open and hook up the
file info just like the other NaCl module loads.
The non-executable files are still opened without the windows-specific
FLAG_EXEC.
BUG= https://code.google.com/p/nativeclient/issues/detail?id=3614
TEST= ValidationCacheOfTranslatorNexes
Review URL: https://codereview.chromium.org/356923004
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@280605 0039d316-1c4b-4281-b951-d872f2087c98
18 files changed, 232 insertions, 143 deletions
diff --git a/chrome/test/nacl/nacl_browsertest_uma.cc b/chrome/test/nacl/nacl_browsertest_uma.cc index 0f91ca4..fb7a463 100644 --- a/chrome/test/nacl/nacl_browsertest_uma.cc +++ b/chrome/test/nacl/nacl_browsertest_uma.cc @@ -28,15 +28,29 @@ NACL_BROWSER_TEST_F(NaClBrowserTest, SuccessfulLoadUMA, { LOAD_OK, 1); // Check validation cache usage: - // For the open-web, only the IRT is considered a "safe" and - // identity-cachable file. The nexes and .so files are not. - // Should have one cache query for the IRT. - histograms.ExpectBucketCount("NaCl.ValidationCache.Query", - nacl::NaClBrowser::CACHE_MISS, 1); - // TOTAL should then be 1 query so far. - histograms.ExpectTotalCount("NaCl.ValidationCache.Query", 1); - // Should have received a cache setting afterwards for IRT. - histograms.ExpectTotalCount("NaCl.ValidationCache.Set", 1); + if (IsAPnaclTest()) { + // Should have received 3 validation queries: + // - One for IRT for actual application + // - Two for two translator nexes + // The translators don't currently use the IRT, so there is no IRT cache + // query for those two loads. The PNaCl main nexe comes from a + // delete-on-close temp file, so it doesn't have a stable identity + // for validation caching. All three query results should be misses. + histograms.ExpectUniqueSample("NaCl.ValidationCache.Query", + nacl::NaClBrowser::CACHE_MISS, 3); + // Should have received a cache setting afterwards for IRT and translators. + histograms.ExpectUniqueSample("NaCl.ValidationCache.Set", + nacl::NaClBrowser::CACHE_HIT, 3); + } else { + // For the open-web, only the IRT is considered a "safe" and + // identity-cachable file. The nexes and .so files are not. + // Should have one cache query for the IRT. + histograms.ExpectUniqueSample("NaCl.ValidationCache.Query", + nacl::NaClBrowser::CACHE_MISS, 1); + // Should have received a cache setting afterwards for IRT and translators. + histograms.ExpectUniqueSample("NaCl.ValidationCache.Set", + nacl::NaClBrowser::CACHE_HIT, 1); + } // Make sure we have other important histograms. if (!IsAPnaclTest()) { @@ -110,6 +124,44 @@ IN_PROC_BROWSER_TEST_F(NaClBrowserTestVcacheExtension, histograms.ExpectTotalCount("NaCl.ValidationCache.Set", 2); } +// Test that validation for the 2 PNaCl translator nexes can be cached. +IN_PROC_BROWSER_TEST_F(NaClBrowserTestPnacl, + ValidationCacheOfTranslatorNexes) { + // Run a load test w/ one pexe cache identity. + RunLoadTest(FILE_PATH_LITERAL("pnacl_options.html?use_nmf=o_0")); + + UMAHistogramHelper histograms; + histograms.Fetch(); + // Should have received 3 validation queries: + // - One for IRT for actual application + // - Two for two translator nexes + // The translators don't currently use the IRT, so there is no IRT cache + // query for those two loads. The PNaCl main nexe comes from a + // delete-on-close temp file, so it doesn't have a stable identity + // for validation caching. All three query results should be misses. + histograms.ExpectUniqueSample("NaCl.ValidationCache.Query", + nacl::NaClBrowser::CACHE_MISS, 3); + // Should have received a cache setting afterwards for IRT and translators. + histograms.ExpectUniqueSample("NaCl.ValidationCache.Set", + nacl::NaClBrowser::CACHE_HIT, 3); + + // Load the same pexe, but with a different cache identity. + // This means that translation will actually be redone, + // forcing the translators to be loaded a second time (but now with + // cache hits!) + RunLoadTest(FILE_PATH_LITERAL("pnacl_options.html?use_nmf=o_2")); + + // Should now have 3 more queries on top of the previous ones. + histograms.ExpectTotalCount("NaCl.ValidationCache.Query", 6); + // With the 3 extra queries being cache hits. + histograms.ExpectBucketCount("NaCl.ValidationCache.Query", + nacl::NaClBrowser::CACHE_HIT, 3); + // No extra cache settings. + histograms.ExpectUniqueSample("NaCl.ValidationCache.Set", + nacl::NaClBrowser::CACHE_HIT, 3); +} + + // TODO(ncbray) convert the rest of nacl_uma.py (currently in the NaCl repo.) // Test validation failures and crashes. diff --git a/components/nacl/browser/nacl_browser.cc b/components/nacl/browser/nacl_browser.cc index 45c7648..2982fdc 100644 --- a/components/nacl/browser/nacl_browser.cc +++ b/components/nacl/browser/nacl_browser.cc @@ -113,15 +113,16 @@ const int64 kCrashesIntervalInSeconds = 120; namespace nacl { -base::File OpenNaClExecutableImpl(const base::FilePath& file_path) { +base::File OpenNaClReadExecImpl(const base::FilePath& file_path, + bool is_executable) { // Get a file descriptor. On Windows, we need 'GENERIC_EXECUTE' in order to // memory map the executable. // IMPORTANT: This file descriptor must not have write access - that could // allow a NaCl inner sandbox escape. - base::File file(file_path, - (base::File::FLAG_OPEN | - base::File::FLAG_READ | - base::File::FLAG_EXECUTE)); // Windows only flag. + uint32 flags = base::File::FLAG_OPEN | base::File::FLAG_READ; + if (is_executable) + flags |= base::File::FLAG_EXECUTE; // Windows only flag. + base::File file(file_path, flags); if (!file.IsValid()) return file.Pass(); diff --git a/components/nacl/browser/nacl_browser.h b/components/nacl/browser/nacl_browser.h index 93dcb42..8e3e9ef 100644 --- a/components/nacl/browser/nacl_browser.h +++ b/components/nacl/browser/nacl_browser.h @@ -28,9 +28,10 @@ namespace nacl { static const int kGdbDebugStubPortUnknown = -1; static const int kGdbDebugStubPortUnused = 0; -// Open an immutable executable file that can be mmapped. +// Open an immutable executable file that can be mmapped (or a read-only file). // This function should only be called on a thread that can perform file IO. -base::File OpenNaClExecutableImpl(const base::FilePath& file_path); +base::File OpenNaClReadExecImpl(const base::FilePath& file_path, + bool is_executable); // Represents shared state for all NaClProcessHost objects in the browser. class NaClBrowser { diff --git a/components/nacl/browser/nacl_file_host.cc b/components/nacl/browser/nacl_file_host.cc index 0a0f10c..eb5a19b 100644 --- a/components/nacl/browser/nacl_file_host.cc +++ b/components/nacl/browser/nacl_file_host.cc @@ -38,14 +38,37 @@ void NotifyRendererOfError( nacl_host_message_filter->Send(reply_msg); } -base::File PnaclDoOpenFile(const base::FilePath& file_to_open) { - return base::File(file_to_open, - base::File::FLAG_OPEN | base::File::FLAG_READ); +typedef void (*WriteFileInfoReply)(IPC::Message* reply_msg, + IPC::PlatformFileForTransit file_desc, + uint64 file_token_lo, + uint64 file_token_hi); + +void DoRegisterOpenedNaClExecutableFile( + scoped_refptr<nacl::NaClHostMessageFilter> nacl_host_message_filter, + base::File file, + base::FilePath file_path, + IPC::Message* reply_msg, + WriteFileInfoReply write_reply_message) { + // IO thread owns the NaClBrowser singleton. + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); + + nacl::NaClBrowser* nacl_browser = nacl::NaClBrowser::GetInstance(); + uint64 file_token_lo = 0; + uint64 file_token_hi = 0; + nacl_browser->PutFilePath(file_path, &file_token_lo, &file_token_hi); + + IPC::PlatformFileForTransit file_desc = IPC::TakeFileHandleForProcess( + file.Pass(), + nacl_host_message_filter->PeerHandle()); + + write_reply_message(reply_msg, file_desc, file_token_lo, file_token_hi); + nacl_host_message_filter->Send(reply_msg); } void DoOpenPnaclFile( scoped_refptr<nacl::NaClHostMessageFilter> nacl_host_message_filter, const std::string& filename, + bool is_executable, IPC::Message* reply_msg) { DCHECK(BrowserThread::GetBlockingPool()->RunsTasksOnCurrentThread()); base::FilePath full_filepath; @@ -64,46 +87,34 @@ void DoOpenPnaclFile( return; } - base::File file_to_open = PnaclDoOpenFile(full_filepath); + base::File file_to_open = nacl::OpenNaClReadExecImpl(full_filepath, + is_executable); if (!file_to_open.IsValid()) { NotifyRendererOfError(nacl_host_message_filter.get(), reply_msg); return; } - // Send the reply! - // Do any DuplicateHandle magic that is necessary first. - IPC::PlatformFileForTransit target_desc = - IPC::TakeFileHandleForProcess(file_to_open.Pass(), - nacl_host_message_filter->PeerHandle()); - if (target_desc == IPC::InvalidPlatformFileForTransit()) { - NotifyRendererOfError(nacl_host_message_filter.get(), reply_msg); - return; + // This function is running on the blocking pool, but the path needs to be + // registered in a structure owned by the IO thread. + // Not all PNaCl files are executable. Only register those that are + // executable in the NaCl file_path cache. + if (is_executable) { + BrowserThread::PostTask( + BrowserThread::IO, FROM_HERE, + base::Bind(&DoRegisterOpenedNaClExecutableFile, + nacl_host_message_filter, + Passed(file_to_open.Pass()), full_filepath, reply_msg, + static_cast<WriteFileInfoReply>( + NaClHostMsg_GetReadonlyPnaclFD::WriteReplyParams))); + } else { + IPC::PlatformFileForTransit target_desc = + IPC::TakeFileHandleForProcess(file_to_open.Pass(), + nacl_host_message_filter->PeerHandle()); + uint64_t dummy_file_token = 0; + NaClHostMsg_GetReadonlyPnaclFD::WriteReplyParams( + reply_msg, target_desc, dummy_file_token, dummy_file_token); + nacl_host_message_filter->Send(reply_msg); } - NaClHostMsg_GetReadonlyPnaclFD::WriteReplyParams( - reply_msg, target_desc); - nacl_host_message_filter->Send(reply_msg); -} - -void DoRegisterOpenedNaClExecutableFile( - scoped_refptr<nacl::NaClHostMessageFilter> nacl_host_message_filter, - base::File file, - base::FilePath file_path, - IPC::Message* reply_msg) { - // IO thread owns the NaClBrowser singleton. - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); - - nacl::NaClBrowser* nacl_browser = nacl::NaClBrowser::GetInstance(); - uint64 file_token_lo = 0; - uint64 file_token_hi = 0; - nacl_browser->PutFilePath(file_path, &file_token_lo, &file_token_hi); - - IPC::PlatformFileForTransit file_desc = IPC::TakeFileHandleForProcess( - file.Pass(), - nacl_host_message_filter->PeerHandle()); - - NaClHostMsg_OpenNaClExecutable::WriteReplyParams( - reply_msg, file_desc, file_token_lo, file_token_hi); - nacl_host_message_filter->Send(reply_msg); } // Convert the file URL into a file descriptor. @@ -125,7 +136,8 @@ void DoOpenNaClExecutableOnThreadPool( return; } - base::File file = nacl::OpenNaClExecutableImpl(file_path); + base::File file = nacl::OpenNaClReadExecImpl(file_path, + true /* is_executable */); if (file.IsValid()) { // This function is running on the blocking pool, but the path needs to be // registered in a structure owned by the IO thread. @@ -134,7 +146,9 @@ void DoOpenNaClExecutableOnThreadPool( base::Bind( &DoRegisterOpenedNaClExecutableFile, nacl_host_message_filter, - Passed(file.Pass()), file_path, reply_msg)); + Passed(file.Pass()), file_path, reply_msg, + static_cast<WriteFileInfoReply>( + NaClHostMsg_OpenNaClExecutable::WriteReplyParams))); } else { NotifyRendererOfError(nacl_host_message_filter.get(), reply_msg); return; @@ -148,12 +162,14 @@ namespace nacl_file_host { void GetReadonlyPnaclFd( scoped_refptr<nacl::NaClHostMessageFilter> nacl_host_message_filter, const std::string& filename, + bool is_executable, IPC::Message* reply_msg) { if (!BrowserThread::PostBlockingPoolTask( FROM_HERE, base::Bind(&DoOpenPnaclFile, nacl_host_message_filter, filename, + is_executable, reply_msg))) { NotifyRendererOfError(nacl_host_message_filter.get(), reply_msg); } diff --git a/components/nacl/browser/nacl_file_host.h b/components/nacl/browser/nacl_file_host.h index abe75b1..11f5333 100644 --- a/components/nacl/browser/nacl_file_host.h +++ b/components/nacl/browser/nacl_file_host.h @@ -28,9 +28,12 @@ class NaClHostMessageFilter; namespace nacl_file_host { // Open a PNaCl file (readonly) on behalf of the NaCl plugin. +// If it is executable, registers the executable for validation caching. +// Otherwise, just opens the file read-only. void GetReadonlyPnaclFd( scoped_refptr<nacl::NaClHostMessageFilter> nacl_host_message_filter, const std::string& filename, + bool is_executable, IPC::Message* reply_msg); // Return true if the filename requested is valid for opening. diff --git a/components/nacl/browser/nacl_host_message_filter.cc b/components/nacl/browser/nacl_host_message_filter.cc index d98ac71..94d8ae8 100644 --- a/components/nacl/browser/nacl_host_message_filter.cc +++ b/components/nacl/browser/nacl_host_message_filter.cc @@ -169,10 +169,10 @@ void NaClHostMessageFilter::LaunchNaClContinuation( } void NaClHostMessageFilter::OnGetReadonlyPnaclFd( - const std::string& filename, IPC::Message* reply_msg) { + const std::string& filename, bool is_executable, IPC::Message* reply_msg) { // This posts a task to another thread, but the renderer will // block until the reply is sent. - nacl_file_host::GetReadonlyPnaclFd(this, filename, reply_msg); + nacl_file_host::GetReadonlyPnaclFd(this, filename, is_executable, reply_msg); // This is the first message we receive from the renderer once it knows we // want to use PNaCl, so start the translation cache initialization here. diff --git a/components/nacl/browser/nacl_host_message_filter.h b/components/nacl/browser/nacl_host_message_filter.h index 73ec13f..341cc64 100644 --- a/components/nacl/browser/nacl_host_message_filter.h +++ b/components/nacl/browser/nacl_host_message_filter.h @@ -55,6 +55,7 @@ class NaClHostMessageFilter : public content::BrowserMessageFilter { IPC::Message* reply_msg, ppapi::PpapiPermissions permissions); void OnGetReadonlyPnaclFd(const std::string& filename, + bool is_executable, IPC::Message* reply_msg); void OnNaClCreateTemporaryFile(IPC::Message* reply_msg); void OnNaClGetNumProcessors(int* num_processors); diff --git a/components/nacl/browser/nacl_process_host.cc b/components/nacl/browser/nacl_process_host.cc index e174e83..0a3a0c9 100644 --- a/components/nacl/browser/nacl_process_host.cc +++ b/components/nacl/browser/nacl_process_host.cc @@ -1068,7 +1068,7 @@ void NaClProcessHost::OnResolveFileToken(uint64 file_token_lo, if (!base::PostTaskAndReplyWithResult( content::BrowserThread::GetBlockingPool(), FROM_HERE, - base::Bind(OpenNaClExecutableImpl, file_path), + base::Bind(OpenNaClReadExecImpl, file_path, true /* is_executable */), base::Bind(&NaClProcessHost::FileResolved, weak_factory_.GetWeakPtr(), file_path, diff --git a/components/nacl/common/nacl_host_messages.h b/components/nacl/common/nacl_host_messages.h index 5525454..a998f37 100644 --- a/components/nacl/common/nacl_host_messages.h +++ b/components/nacl/common/nacl_host_messages.h @@ -62,9 +62,12 @@ IPC_SYNC_MESSAGE_CONTROL1_2(NaClHostMsg_LaunchNaCl, // A renderer sends this to the browser process when it wants to // open a file for from the Pnacl component directory. -IPC_SYNC_MESSAGE_CONTROL1_1(NaClHostMsg_GetReadonlyPnaclFD, +IPC_SYNC_MESSAGE_CONTROL2_3(NaClHostMsg_GetReadonlyPnaclFD, std::string /* name of requested PNaCl file */, - IPC::PlatformFileForTransit /* output file */) + bool /* is_executable */, + IPC::PlatformFileForTransit /* output file */, + uint64_t /* file_token_lo */, + uint64_t /* file_token_hi */) // A renderer sends this to the browser process when it wants to // create a temporary file. diff --git a/components/nacl/renderer/ppb_nacl_private_impl.cc b/components/nacl/renderer/ppb_nacl_private_impl.cc index cb94ca2..eeaca78 100644 --- a/components/nacl/renderer/ppb_nacl_private_impl.cc +++ b/components/nacl/renderer/ppb_nacl_private_impl.cc @@ -530,14 +530,17 @@ std::string PnaclComponentURLToFilename(const std::string& url) { return r; } -PP_FileHandle GetReadonlyPnaclFd(const char* url) { +PP_FileHandle GetReadonlyPnaclFd(const char* url, + bool is_executable, + uint64_t* nonce_lo, + uint64_t* nonce_hi) { std::string filename = PnaclComponentURLToFilename(url); IPC::PlatformFileForTransit out_fd = IPC::InvalidPlatformFileForTransit(); IPC::Sender* sender = content::RenderThread::Get(); DCHECK(sender); if (!sender->Send(new NaClHostMsg_GetReadonlyPnaclFD( - std::string(filename), - &out_fd))) { + std::string(filename), is_executable, + &out_fd, nonce_lo, nonce_hi))) { return PP_kInvalidFileHandle; } if (out_fd == IPC::InvalidPlatformFileForTransit()) { @@ -546,6 +549,14 @@ PP_FileHandle GetReadonlyPnaclFd(const char* url) { return IPC::PlatformFileForTransitToPlatformFile(out_fd); } +void GetReadExecPnaclFd(const char* url, + PP_NaClFileInfo* out_file_info) { + *out_file_info = kInvalidNaClFileInfo; + out_file_info->handle = GetReadonlyPnaclFd(url, true /* is_executable */, + &out_file_info->token_lo, + &out_file_info->token_hi); +} + PP_FileHandle CreateTemporaryFile(PP_Instance instance) { IPC::PlatformFileForTransit transit_fd = IPC::InvalidPlatformFileForTransit(); IPC::Sender* sender = content::RenderThread::Get(); @@ -1108,7 +1119,10 @@ PP_Bool GetPNaClResourceInfo(PP_Instance instance, if (!load_manager) return PP_FALSE; - base::File file(GetReadonlyPnaclFd(filename)); + uint64_t nonce_lo = 0; + uint64_t nonce_hi = 0; + base::File file(GetReadonlyPnaclFd(filename, false /* is_executable */, + &nonce_lo, &nonce_hi)); if (!file.IsValid()) { load_manager->ReportLoadError( PP_NACL_ERROR_PNACL_RESOURCE_FETCH, @@ -1434,7 +1448,11 @@ void DownloadFile(PP_Instance instance, // Handle special PNaCl support files which are installed on the user's // machine. if (url.find(kPNaClTranslatorBaseUrl, 0) == 0) { - PP_FileHandle handle = GetReadonlyPnaclFd(url.c_str()); + PP_NaClFileInfo file_info = kInvalidNaClFileInfo; + PP_FileHandle handle = GetReadonlyPnaclFd(url.c_str(), + false /* is_executable */, + &file_info.token_lo, + &file_info.token_hi); if (handle == PP_kInvalidFileHandle) { base::MessageLoop::current()->PostTask( FROM_HERE, @@ -1443,12 +1461,7 @@ void DownloadFile(PP_Instance instance, kInvalidNaClFileInfo)); return; } - // TODO(ncbray): enable the fast loading and validation paths for this type - // of file. - PP_NaClFileInfo file_info; file_info.handle = handle; - file_info.token_lo = 0; - file_info.token_hi = 0; base::MessageLoop::current()->PostTask( FROM_HERE, base::Bind(callback, static_cast<int32_t>(PP_OK), file_info)); @@ -1587,7 +1600,7 @@ const PPB_NaCl_Private nacl_interface = { &UrandomFD, &Are3DInterfacesDisabled, &BrokerDuplicateHandle, - &GetReadonlyPnaclFd, + &GetReadExecPnaclFd, &CreateTemporaryFile, &GetNumberOfProcessors, &PPIsNonSFIModeEnabled, diff --git a/ppapi/api/private/ppb_nacl_private.idl b/ppapi/api/private/ppb_nacl_private.idl index 944f87c..e07a262 100644 --- a/ppapi/api/private/ppb_nacl_private.idl +++ b/ppapi/api/private/ppb_nacl_private.idl @@ -219,10 +219,11 @@ interface PPB_NaCl_Private { [in] uint32_t desired_access, [in] uint32_t options); - /* Returns a read-only file descriptor for a url for pnacl translator tools, - * or an invalid handle on failure. + /* Returns a read-only (but executable) file descriptor / file info for + * a url for pnacl translator tools. Returns an invalid handle on failure. */ - PP_FileHandle GetReadonlyPnaclFd([in] str_t url); + void GetReadExecPnaclFd([in] str_t url, + [out] PP_NaClFileInfo out_file_info); /* This creates a temporary file that will be deleted by the time * the last handle is closed (or earlier on POSIX systems), and diff --git a/ppapi/c/private/ppb_nacl_private.h b/ppapi/c/private/ppb_nacl_private.h index 8e754f9..ca7c7fe 100644 --- a/ppapi/c/private/ppb_nacl_private.h +++ b/ppapi/c/private/ppb_nacl_private.h @@ -3,7 +3,7 @@ * found in the LICENSE file. */ -/* From private/ppb_nacl_private.idl modified Thu Jun 26 14:23:46 2014. */ +/* From private/ppb_nacl_private.idl modified Fri Jun 27 15:10:18 2014. */ #ifndef PPAPI_C_PRIVATE_PPB_NACL_PRIVATE_H_ #define PPAPI_C_PRIVATE_PPB_NACL_PRIVATE_H_ @@ -256,10 +256,11 @@ struct PPB_NaCl_Private_1_0 { PP_FileHandle* target_handle, uint32_t desired_access, uint32_t options); - /* Returns a read-only file descriptor for a url for pnacl translator tools, - * or an invalid handle on failure. + /* Returns a read-only (but executable) file descriptor / file info for + * a url for pnacl translator tools. Returns an invalid handle on failure. */ - PP_FileHandle (*GetReadonlyPnaclFd)(const char* url); + void (*GetReadExecPnaclFd)(const char* url, + struct PP_NaClFileInfo* out_file_info); /* This creates a temporary file that will be deleted by the time * the last handle is closed (or earlier on POSIX systems), and * returns a posix handle to that temporary file. diff --git a/ppapi/native_client/src/trusted/plugin/plugin.cc b/ppapi/native_client/src/trusted/plugin/plugin.cc index f102fc7..6820224 100644 --- a/ppapi/native_client/src/trusted/plugin/plugin.cc +++ b/ppapi/native_client/src/trusted/plugin/plugin.cc @@ -41,12 +41,6 @@ const int64_t kTimeSmallMin = 1; // in ms const int64_t kTimeSmallMax = 20000; // in ms const uint32_t kTimeSmallBuckets = 100; -const PP_NaClFileInfo kInvalidNaClFileInfo = { - PP_kInvalidFileHandle, - 0, // token_lo - 0, // token_hi -}; - } // namespace void Plugin::ShutDownSubprocesses() { @@ -72,7 +66,7 @@ void Plugin::HistogramTimeSmall(const std::string& name, kTimeSmallBuckets); } -bool Plugin::LoadHelperNaClModule(PP_FileHandle file_handle, +bool Plugin::LoadHelperNaClModule(PP_NaClFileInfo file_info, NaClSubprocess* subprocess, const SelLdrStartParams& params) { CHECK(!pp::Module::Get()->core()->IsMainThread()); @@ -108,11 +102,6 @@ bool Plugin::LoadHelperNaClModule(PP_FileHandle file_handle, if (!service_runtime_started) return false; - PP_NaClFileInfo info; - info.handle = file_handle; - info.token_lo = 0; - info.token_hi = 0; - // Now actually load the nexe, which can happen on a background thread. // // We can't use pp::BlockUntilComplete() inside an in-process plugin, so we @@ -123,7 +112,7 @@ bool Plugin::LoadHelperNaClModule(PP_FileHandle file_handle, callback_factory_.NewCallback( &Plugin::LoadNexeAndStart, service_runtime, - info)); + file_info)); return service_runtime->WaitForNexeStart(); } @@ -239,7 +228,7 @@ bool Plugin::LoadNaClModuleContinuationIntern() { } NaClSubprocess* Plugin::LoadHelperNaClModule(const nacl::string& helper_url, - PP_FileHandle file_handle, + PP_NaClFileInfo file_info, ErrorInfo* error_info) { nacl::scoped_ptr<NaClSubprocess> nacl_subprocess( new NaClSubprocess("helper module", NULL, NULL)); @@ -255,9 +244,9 @@ NaClSubprocess* Plugin::LoadHelperNaClModule(const nacl::string& helper_url, // done to save on address space and swap space. // // Currently, this works only in SFI-mode. So, LoadModule SRPC is still used. - // So, pass kInvalidNaClFileInfo here, and instead |file_handle| is passed + // So, pass kInvalidNaClFileInfo here, and instead |file_info| is passed // to LoadNaClModuleFromBackgroundThread() below. - // TODO(teravest, hidehiko): Pass file_handle to params, so that LaunchSelLdr + // TODO(teravest, hidehiko): Pass file_info to params, so that LaunchSelLdr // will look at the info. SelLdrStartParams params(helper_url, kInvalidNaClFileInfo, @@ -269,7 +258,9 @@ NaClSubprocess* Plugin::LoadHelperNaClModule(const nacl::string& helper_url, // Helper NaCl modules always use the PNaCl manifest, as there is no // corresponding NMF. - if (!LoadHelperNaClModule(file_handle, nacl_subprocess.get(), params)) { + if (!LoadHelperNaClModule(file_info, + nacl_subprocess.get(), + params)) { return NULL; } // We need not wait for the init_done callback. We can block @@ -331,9 +322,7 @@ Plugin::Plugin(PP_Instance pp_instance) // We call set_exit_status() here to ensure that the 'exitStatus' property is // set. This can only be called when nacl_interface_ is not NULL. set_exit_status(-1); - nexe_file_info_.handle = PP_kInvalidFileHandle; - nexe_file_info_.token_lo = 0; - nexe_file_info_.token_hi = 0; + nexe_file_info_ = kInvalidNaClFileInfo; } diff --git a/ppapi/native_client/src/trusted/plugin/plugin.h b/ppapi/native_client/src/trusted/plugin/plugin.h index 94d9614..85ff49c 100644 --- a/ppapi/native_client/src/trusted/plugin/plugin.h +++ b/ppapi/native_client/src/trusted/plugin/plugin.h @@ -52,6 +52,12 @@ class Manifest; int32_t ConvertFileDescriptor(PP_FileHandle handle); +const PP_NaClFileInfo kInvalidNaClFileInfo = { + PP_kInvalidFileHandle, + 0, // token_lo + 0, // token_hi +}; + class Plugin : public pp::Instance { public: explicit Plugin(PP_Instance instance); @@ -102,12 +108,12 @@ class Plugin : public pp::Instance { bool LoadNaClModuleContinuation(int32_t pp_error); // Load support. - // A helper SRPC NaCl module can be loaded given a PP_FileHandle. + // A helper SRPC NaCl module can be loaded given a PP_NaClFileInfo. // Blocks until the helper module signals initialization is done. // Does not update nacl_module_origin(). // Returns NULL or the NaClSubprocess of the new helper NaCl module. NaClSubprocess* LoadHelperNaClModule(const nacl::string& helper_url, - PP_FileHandle file_handle, + PP_NaClFileInfo file_info, ErrorInfo* error_info); // Report an error that was encountered while loading a module. @@ -140,11 +146,11 @@ class Plugin : public pp::Instance { // uma_interface_ normally. void HistogramTimeSmall(const std::string& name, int64_t ms); - // Load a nacl module from the file specified in file_handle. + // Load a nacl module from the file specified in file_info. // Only to be used from a background (non-main) thread for the PNaCl // translator. This will fully initialize the |subprocess| if the load was // successful. - bool LoadHelperNaClModule(PP_FileHandle file_handle, + bool LoadHelperNaClModule(PP_NaClFileInfo file_info, NaClSubprocess* subprocess, const SelLdrStartParams& params); diff --git a/ppapi/native_client/src/trusted/plugin/pnacl_resources.cc b/ppapi/native_client/src/trusted/plugin/pnacl_resources.cc index 8b5f4cf..18eccea 100644 --- a/ppapi/native_client/src/trusted/plugin/pnacl_resources.cc +++ b/ppapi/native_client/src/trusted/plugin/pnacl_resources.cc @@ -24,11 +24,17 @@ nacl::string GetFullUrl(const nacl::string& partial_url) { } // namespace +PnaclResources::PnaclResources(Plugin* plugin) + : plugin_(plugin) { + llc_file_info_ = kInvalidNaClFileInfo; + ld_file_info_ = kInvalidNaClFileInfo; +} + PnaclResources::~PnaclResources() { - if (llc_file_handle_ != PP_kInvalidFileHandle) - CloseFileHandle(llc_file_handle_); - if (ld_file_handle_ != PP_kInvalidFileHandle) - CloseFileHandle(ld_file_handle_); + if (llc_file_info_.handle != PP_kInvalidFileHandle) + CloseFileHandle(llc_file_info_.handle); + if (ld_file_info_.handle != PP_kInvalidFileHandle) + CloseFileHandle(ld_file_info_.handle); } bool PnaclResources::ReadResourceInfo() { @@ -48,15 +54,15 @@ bool PnaclResources::ReadResourceInfo() { return true; } -PP_FileHandle PnaclResources::TakeLlcFileHandle() { - PP_FileHandle to_return = llc_file_handle_; - llc_file_handle_ = PP_kInvalidFileHandle; +PP_NaClFileInfo PnaclResources::TakeLlcFileInfo() { + PP_NaClFileInfo to_return = llc_file_info_; + llc_file_info_ = kInvalidNaClFileInfo; return to_return; } -PP_FileHandle PnaclResources::TakeLdFileHandle() { - PP_FileHandle to_return = ld_file_handle_; - ld_file_handle_ = PP_kInvalidFileHandle; +PP_NaClFileInfo PnaclResources::TakeLdFileInfo() { + PP_NaClFileInfo to_return = ld_file_info_; + ld_file_info_ = kInvalidNaClFileInfo; return to_return; } @@ -64,12 +70,12 @@ bool PnaclResources::StartLoad() { PLUGIN_PRINTF(("PnaclResources::StartLoad\n")); // Do a blocking load of each of the resources. - llc_file_handle_ = - plugin_->nacl_interface()->GetReadonlyPnaclFd(llc_tool_name_.c_str()); - ld_file_handle_ = - plugin_->nacl_interface()->GetReadonlyPnaclFd(ld_tool_name_.c_str()); - return (llc_file_handle_ != PP_kInvalidFileHandle && - ld_file_handle_ != PP_kInvalidFileHandle); + plugin_->nacl_interface()->GetReadExecPnaclFd(llc_tool_name_.c_str(), + &llc_file_info_); + plugin_->nacl_interface()->GetReadExecPnaclFd(ld_tool_name_.c_str(), + &ld_file_info_); + return (llc_file_info_.handle != PP_kInvalidFileHandle && + ld_file_info_.handle != PP_kInvalidFileHandle); } } // namespace plugin diff --git a/ppapi/native_client/src/trusted/plugin/pnacl_resources.h b/ppapi/native_client/src/trusted/plugin/pnacl_resources.h index dcc521e..ff70b12 100644 --- a/ppapi/native_client/src/trusted/plugin/pnacl_resources.h +++ b/ppapi/native_client/src/trusted/plugin/pnacl_resources.h @@ -12,7 +12,7 @@ #include "native_client/src/include/nacl_string.h" #include "native_client/src/trusted/desc/nacl_desc_wrapper.h" -#include "ppapi/c/private/pp_file_handle.h" +#include "ppapi/c/private/ppb_nacl_private.h" #include "ppapi/cpp/completion_callback.h" #include "ppapi/native_client/src/trusted/plugin/plugin_error.h" @@ -26,11 +26,7 @@ class Plugin; // and point to pnacl component filesystem resources. class PnaclResources { public: - explicit PnaclResources(Plugin* plugin) - : plugin_(plugin), - llc_file_handle_(PP_kInvalidFileHandle), - ld_file_handle_(PP_kInvalidFileHandle) { - } + explicit PnaclResources(Plugin* plugin); virtual ~PnaclResources(); // Read the resource info JSON file. This is the first step after @@ -43,8 +39,8 @@ class PnaclResources { const nacl::string& GetLlcUrl() { return llc_tool_name_; } const nacl::string& GetLdUrl() { return ld_tool_name_; } - PP_FileHandle TakeLlcFileHandle(); - PP_FileHandle TakeLdFileHandle(); + PP_NaClFileInfo TakeLlcFileInfo(); + PP_NaClFileInfo TakeLdFileInfo(); private: NACL_DISALLOW_COPY_AND_ASSIGN(PnaclResources); @@ -56,11 +52,11 @@ class PnaclResources { nacl::string llc_tool_name_; nacl::string ld_tool_name_; - // File handles for llc and ld executables, after they've been opened. + // File info for llc and ld executables, after they've been opened. // Only valid after the callback for StartLoad() has been called, and until - // TakeLlcFileHandle()/TakeLdFileHandle() is called. - PP_FileHandle llc_file_handle_; - PP_FileHandle ld_file_handle_; + // TakeLlcFileInfo()/TakeLdFileInfo() is called. + PP_NaClFileInfo llc_file_info_; + PP_NaClFileInfo ld_file_info_; }; } // namespace plugin; diff --git a/ppapi/native_client/src/trusted/plugin/pnacl_translate_thread.cc b/ppapi/native_client/src/trusted/plugin/pnacl_translate_thread.cc index 5f3c4f0..f6fea1e 100644 --- a/ppapi/native_client/src/trusted/plugin/pnacl_translate_thread.cc +++ b/ppapi/native_client/src/trusted/plugin/pnacl_translate_thread.cc @@ -162,13 +162,13 @@ void PnaclTranslateThread::DoTranslate() { pp::Core* core = pp::Module::Get()->core(); int64_t llc_start_time = NaClGetTimeOfDayMicroseconds(); - PP_FileHandle llc_file_handle = resources_->TakeLlcFileHandle(); - // On success, ownership of llc_file_handle is transferred. + PP_NaClFileInfo llc_file_info = resources_->TakeLlcFileInfo(); + // On success, ownership of llc_file_info is transferred. NaClSubprocess* llc_subprocess = plugin_->LoadHelperNaClModule( - resources_->GetLlcUrl(), llc_file_handle, &error_info); + resources_->GetLlcUrl(), llc_file_info, &error_info); if (llc_subprocess == NULL) { - if (llc_file_handle != PP_kInvalidFileHandle) - CloseFileHandle(llc_file_handle); + if (llc_file_info.handle != PP_kInvalidFileHandle) + CloseFileHandle(llc_file_info.handle); TranslateFailed(PP_NACL_ERROR_PNACL_LLC_SETUP, "Compile process could not be created: " + error_info.message()); @@ -334,15 +334,15 @@ bool PnaclTranslateThread::RunLdSubprocess() { nacl::DescWrapper* ld_out_file = nexe_file_->write_wrapper(); int64_t ld_start_time = NaClGetTimeOfDayMicroseconds(); - PP_FileHandle ld_file_handle = resources_->TakeLdFileHandle(); - // On success, ownership of ld_file_handle is transferred. + PP_NaClFileInfo ld_file_info = resources_->TakeLdFileInfo(); + // On success, ownership of ld_file_info is transferred. nacl::scoped_ptr<NaClSubprocess> ld_subprocess( plugin_->LoadHelperNaClModule(resources_->GetLlcUrl(), - ld_file_handle, + ld_file_info, &error_info)); if (ld_subprocess.get() == NULL) { - if (ld_file_handle != PP_kInvalidFileHandle) - CloseFileHandle(ld_file_handle); + if (ld_file_info.handle != PP_kInvalidFileHandle) + CloseFileHandle(ld_file_info.handle); TranslateFailed(PP_NACL_ERROR_PNACL_LD_SETUP, "Link process could not be created: " + error_info.message()); diff --git a/ppapi/native_client/src/untrusted/pnacl_irt_shim/pnacl_shim.c b/ppapi/native_client/src/untrusted/pnacl_irt_shim/pnacl_shim.c index c7b0e35..9e7ea18 100644 --- a/ppapi/native_client/src/untrusted/pnacl_irt_shim/pnacl_shim.c +++ b/ppapi/native_client/src/untrusted/pnacl_irt_shim/pnacl_shim.c @@ -3302,9 +3302,9 @@ static int32_t Pnacl_M25_PPB_NaCl_Private_BrokerDuplicateHandle(PP_FileHandle so return iface->BrokerDuplicateHandle(source_handle, process_id, target_handle, desired_access, options); } -static PP_FileHandle Pnacl_M25_PPB_NaCl_Private_GetReadonlyPnaclFd(const char* url) { +static void Pnacl_M25_PPB_NaCl_Private_GetReadExecPnaclFd(const char* url, struct PP_NaClFileInfo* out_file_info) { const struct PPB_NaCl_Private_1_0 *iface = Pnacl_WrapperInfo_PPB_NaCl_Private_1_0.real_iface; - return iface->GetReadonlyPnaclFd(url); + iface->GetReadExecPnaclFd(url, out_file_info); } static PP_FileHandle Pnacl_M25_PPB_NaCl_Private_CreateTemporaryFile(PP_Instance instance) { @@ -5224,7 +5224,7 @@ static const struct PPB_NaCl_Private_1_0 Pnacl_Wrappers_PPB_NaCl_Private_1_0 = { .UrandomFD = (int32_t (*)(void))&Pnacl_M25_PPB_NaCl_Private_UrandomFD, .Are3DInterfacesDisabled = (PP_Bool (*)(void))&Pnacl_M25_PPB_NaCl_Private_Are3DInterfacesDisabled, .BrokerDuplicateHandle = (int32_t (*)(PP_FileHandle source_handle, uint32_t process_id, PP_FileHandle* target_handle, uint32_t desired_access, uint32_t options))&Pnacl_M25_PPB_NaCl_Private_BrokerDuplicateHandle, - .GetReadonlyPnaclFd = (PP_FileHandle (*)(const char* url))&Pnacl_M25_PPB_NaCl_Private_GetReadonlyPnaclFd, + .GetReadExecPnaclFd = (void (*)(const char* url, struct PP_NaClFileInfo* out_file_info))&Pnacl_M25_PPB_NaCl_Private_GetReadExecPnaclFd, .CreateTemporaryFile = (PP_FileHandle (*)(PP_Instance instance))&Pnacl_M25_PPB_NaCl_Private_CreateTemporaryFile, .GetNumberOfProcessors = (int32_t (*)(void))&Pnacl_M25_PPB_NaCl_Private_GetNumberOfProcessors, .IsNonSFIModeEnabled = (PP_Bool (*)(void))&Pnacl_M25_PPB_NaCl_Private_IsNonSFIModeEnabled, |