summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjvoung@chromium.org <jvoung@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-06-30 16:18:53 +0000
committerjvoung@chromium.org <jvoung@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-06-30 16:18:53 +0000
commit5e64f63863b0218ad30ed859771ef5475b08c6c4 (patch)
tree38e77dba617d1568c74b35c4d6704318eae0a3b2
parent14693e1b149daad671fca474b438c01359bf48c7 (diff)
downloadchromium_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
-rw-r--r--chrome/test/nacl/nacl_browsertest_uma.cc70
-rw-r--r--components/nacl/browser/nacl_browser.cc11
-rw-r--r--components/nacl/browser/nacl_browser.h5
-rw-r--r--components/nacl/browser/nacl_file_host.cc94
-rw-r--r--components/nacl/browser/nacl_file_host.h3
-rw-r--r--components/nacl/browser/nacl_host_message_filter.cc4
-rw-r--r--components/nacl/browser/nacl_host_message_filter.h1
-rw-r--r--components/nacl/browser/nacl_process_host.cc2
-rw-r--r--components/nacl/common/nacl_host_messages.h7
-rw-r--r--components/nacl/renderer/ppb_nacl_private_impl.cc35
-rw-r--r--ppapi/api/private/ppb_nacl_private.idl7
-rw-r--r--ppapi/c/private/ppb_nacl_private.h9
-rw-r--r--ppapi/native_client/src/trusted/plugin/plugin.cc29
-rw-r--r--ppapi/native_client/src/trusted/plugin/plugin.h14
-rw-r--r--ppapi/native_client/src/trusted/plugin/pnacl_resources.cc38
-rw-r--r--ppapi/native_client/src/trusted/plugin/pnacl_resources.h20
-rw-r--r--ppapi/native_client/src/trusted/plugin/pnacl_translate_thread.cc20
-rw-r--r--ppapi/native_client/src/untrusted/pnacl_irt_shim/pnacl_shim.c6
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,