diff options
author | eliben@chromium.org <eliben@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-05-24 07:14:56 +0000 |
---|---|---|
committer | eliben@chromium.org <eliben@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-05-24 07:14:56 +0000 |
commit | b1672516eae42a19195f0fe7e29f3e4a1fff2fce (patch) | |
tree | 18f82cf38fbcd33d31d25b15d8fe91f96c8cf703 /ppapi/native_client | |
parent | 4cc63fc8670f96870f69a6e1b42d28b8763fdaa7 (diff) | |
download | chromium_src-b1672516eae42a19195f0fe7e29f3e4a1fff2fce.zip chromium_src-b1672516eae42a19195f0fe7e29f3e4a1fff2fce.tar.gz chromium_src-b1672516eae42a19195f0fe7e29f3e4a1fff2fce.tar.bz2 |
Parametrize names of llc and ld nexes by reading them from the resource info JSON file.
At Chrome build-time, the pnacl_component_crx_gen.py script generates a "resource info" JSON file that's placed alongside the translator nexes. We were not actually reading this file so far, but with this CL, we are. The first use is not hard-coding the ld.nexe and llc.nexe tool names in the plugin code. Instead, the tool names are read from the info file. This will allow us, in the future, to move the tool names into the native client directory so we can change them without touching Chrome at all.
BUG=None
Review URL: https://chromiumcodereview.appspot.com/15697019
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@202002 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ppapi/native_client')
10 files changed, 352 insertions, 118 deletions
diff --git a/ppapi/native_client/src/trusted/plugin/file_utils.cc b/ppapi/native_client/src/trusted/plugin/file_utils.cc new file mode 100644 index 0000000..50600a2a --- /dev/null +++ b/ppapi/native_client/src/trusted/plugin/file_utils.cc @@ -0,0 +1,77 @@ +// Copyright (c) 2013 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Some common file utilities for plugin code. + +#include "native_client/src/trusted/plugin/file_utils.h" + +#include <fcntl.h> +#include <stdio.h> +#include <stdlib.h> + +#include <sys/stat.h> +#include <sys/types.h> + +#include "native_client/src/include/nacl_scoped_ptr.h" +#include "native_client/src/include/portability_io.h" +#include "native_client/src/include/portability_string.h" + + +namespace plugin { +namespace file_utils { + +StatusCode SlurpFile(int32_t fd, + nacl::string& out_buf, + size_t max_size_to_read) { + struct stat stat_buf; + if (fstat(fd, &stat_buf) != 0) { + CLOSE(fd); + return PLUGIN_FILE_ERROR_STAT; + } + + // Figure out how large a buffer we need to slurp the whole file (with a + // '\0' at the end). + size_t bytes_to_read = static_cast<size_t>(stat_buf.st_size); + if (bytes_to_read > max_size_to_read - 1) { + CLOSE(fd); + return PLUGIN_FILE_ERROR_FILE_TOO_LARGE; + } + + FILE* input_file = fdopen(fd, "rb"); + if (!input_file) { + CLOSE(fd); + return PLUGIN_FILE_ERROR_OPEN; + } + // From here on, closing input_file will automatically close fd. + + nacl::scoped_array<char> buffer(new char[bytes_to_read + 1]); + if (buffer == NULL) { + fclose(input_file); + return PLUGIN_FILE_ERROR_MEM_ALLOC; + } + + size_t total_bytes_read = 0; + while (bytes_to_read > 0) { + size_t bytes_this_read = fread(&buffer[total_bytes_read], + sizeof(char), + bytes_to_read, + input_file); + if (bytes_this_read < bytes_to_read && (feof(input_file) || + ferror(input_file))) { + fclose(input_file); + return PLUGIN_FILE_ERROR_READ; + } + total_bytes_read += bytes_this_read; + bytes_to_read -= bytes_this_read; + } + + fclose(input_file); + buffer[total_bytes_read] = '\0'; + out_buf = buffer.get(); + return PLUGIN_FILE_SUCCESS; +} + +} // namespace file_utils +} // namespace plugin + diff --git a/ppapi/native_client/src/trusted/plugin/file_utils.h b/ppapi/native_client/src/trusted/plugin/file_utils.h new file mode 100644 index 0000000..223bf66 --- /dev/null +++ b/ppapi/native_client/src/trusted/plugin/file_utils.h @@ -0,0 +1,38 @@ +// Copyright (c) 2013 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Some common file utilities for plugin code. + +#ifndef NATIVE_CLIENT_SRC_TRUSTED_PLUGIN_FILE_UTILS_H_ +#define NATIVE_CLIENT_SRC_TRUSTED_PLUGIN_FILE_UTILS_H_ + +#include "native_client/src/include/nacl_string.h" +#include "native_client/src/include/portability_io.h" +#include "ppapi/c/pp_stdint.h" + +namespace plugin { +namespace file_utils { + +enum StatusCode { + PLUGIN_FILE_SUCCESS = 0, + PLUGIN_FILE_ERROR_MEM_ALLOC = 1, + PLUGIN_FILE_ERROR_OPEN = 2, + PLUGIN_FILE_ERROR_FILE_TOO_LARGE = 3, + PLUGIN_FILE_ERROR_STAT = 4, + PLUGIN_FILE_ERROR_READ = 5 +}; + +// Slurp the whole contents of the given file (|fd| - open file descriptor) into +// |out_buf|. |max_size_to_read| is the maximal allowed size of the file. +// If the file turns out to be larger, an error is returned. In any case, +// |fd| is closed. +StatusCode SlurpFile(int32_t fd, + nacl::string& out_buf, + size_t max_size_to_read = (1 << 20)); + +} // namespace file_utils +} // namespace plugin + +#endif // NATIVE_CLIENT_SRC_TRUSTED_PLUGIN_FILE_UTILS_H_ + diff --git a/ppapi/native_client/src/trusted/plugin/plugin.cc b/ppapi/native_client/src/trusted/plugin/plugin.cc index de70eaf..34b487d 100644 --- a/ppapi/native_client/src/trusted/plugin/plugin.cc +++ b/ppapi/native_client/src/trusted/plugin/plugin.cc @@ -9,11 +9,6 @@ #include "native_client/src/trusted/plugin/plugin.h" -#include <fcntl.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> - #include <sys/stat.h> #include <sys/types.h> @@ -32,6 +27,7 @@ #include "native_client/src/shared/platform/nacl_check.h" #include "native_client/src/trusted/desc/nacl_desc_wrapper.h" #include "native_client/src/trusted/nonnacl_util/sel_ldr_launcher.h" +#include "native_client/src/trusted/plugin/file_utils.h" #include "native_client/src/trusted/plugin/json_manifest.h" #include "native_client/src/trusted/plugin/nacl_entry_points.h" #include "native_client/src/trusted/plugin/nacl_subprocess.h" @@ -1104,75 +1100,44 @@ void Plugin::NaClManifestFileDidOpen(int32_t pp_error) { } return; } - // Duplicate the file descriptor in order to create a FILE stream with it - // that can later be closed without closing the original descriptor. The - // browser will take care of the original descriptor. + // SlurpFile closes the file descriptor after reading (or on error). + // Duplicate our file descriptor since it will be handled by the browser. int dup_file_desc = DUP(file_desc); - struct stat stat_buf; - if (0 != fstat(dup_file_desc, &stat_buf)) { - CLOSE(dup_file_desc); - error_info.SetReport(ERROR_MANIFEST_STAT, - "could not stat manifest file."); - ReportLoadError(error_info); - return; - } - size_t bytes_to_read = static_cast<size_t>(stat_buf.st_size); - if (bytes_to_read > kNaClManifestMaxFileBytes) { - CLOSE(dup_file_desc); - error_info.SetReport(ERROR_MANIFEST_TOO_LARGE, - "manifest file too large."); - ReportLoadError(error_info); - return; - } - FILE* json_file = fdopen(dup_file_desc, "rb"); - PLUGIN_PRINTF(("Plugin::NaClManifestFileDidOpen " - "(dup_file_desc=%"NACL_PRId32", json_file=%p)\n", - dup_file_desc, static_cast<void*>(json_file))); - if (json_file == NULL) { - CLOSE(dup_file_desc); - error_info.SetReport(ERROR_MANIFEST_OPEN, - "could not open manifest file."); - ReportLoadError(error_info); - return; - } - nacl::scoped_array<char> json_buffer(new char[bytes_to_read + 1]); - if (json_buffer == NULL) { - fclose(json_file); - error_info.SetReport(ERROR_MANIFEST_MEMORY_ALLOC, - "could not allocate manifest memory."); + nacl::string json_buffer; + file_utils::StatusCode status = file_utils::SlurpFile( + dup_file_desc, json_buffer, kNaClManifestMaxFileBytes); + + if (status != file_utils::PLUGIN_FILE_SUCCESS) { + switch (status) { + case file_utils::PLUGIN_FILE_SUCCESS: + CHECK(0); + break; + case file_utils::PLUGIN_FILE_ERROR_MEM_ALLOC: + error_info.SetReport(ERROR_MANIFEST_MEMORY_ALLOC, + "could not allocate manifest memory."); + break; + case file_utils::PLUGIN_FILE_ERROR_OPEN: + error_info.SetReport(ERROR_MANIFEST_OPEN, + "could not open manifest file."); + break; + case file_utils::PLUGIN_FILE_ERROR_FILE_TOO_LARGE: + error_info.SetReport(ERROR_MANIFEST_TOO_LARGE, + "manifest file too large."); + break; + case file_utils::PLUGIN_FILE_ERROR_STAT: + error_info.SetReport(ERROR_MANIFEST_STAT, + "could not stat manifest file."); + break; + case file_utils::PLUGIN_FILE_ERROR_READ: + error_info.SetReport(ERROR_MANIFEST_READ, + "could not read manifest file."); + break; + } ReportLoadError(error_info); return; } - // json_buffer could hold a large enough buffer that the system might need - // multiple reads to fill it, so iterate through reads. - size_t total_bytes_read = 0; - while (0 < bytes_to_read) { - size_t bytes_this_read = fread(&json_buffer[total_bytes_read], - sizeof(char), - bytes_to_read, - json_file); - if (bytes_this_read < bytes_to_read && - (feof(json_file) || ferror(json_file))) { - PLUGIN_PRINTF(("Plugin::NaClManifestFileDidOpen failed: " - "total_bytes_read=%"NACL_PRIuS" " - "bytes_to_read=%"NACL_PRIuS"\n", - total_bytes_read, bytes_to_read)); - fclose(json_file); - error_info.SetReport(ERROR_MANIFEST_READ, - "could not read manifest file."); - ReportLoadError(error_info); - return; - } - total_bytes_read += bytes_this_read; - bytes_to_read -= bytes_this_read; - } - // Once the bytes are read, the FILE is no longer needed, so close it. This - // allows for early returns without leaking the |json_file| FILE object. - fclose(json_file); - // No need to close |file_desc|, that is handled by |nexe_downloader_|. - json_buffer[total_bytes_read] = '\0'; // Force null termination. - ProcessNaClManifest(json_buffer.get()); + ProcessNaClManifest(json_buffer); } void Plugin::ProcessNaClManifest(const nacl::string& manifest_json) { diff --git a/ppapi/native_client/src/trusted/plugin/plugin.gypi b/ppapi/native_client/src/trusted/plugin/plugin.gypi index 4532f2f..756ebce 100644 --- a/ppapi/native_client/src/trusted/plugin/plugin.gypi +++ b/ppapi/native_client/src/trusted/plugin/plugin.gypi @@ -7,6 +7,7 @@ 'chromium_code': 1, # Use higher warning level. 'common_sources': [ 'file_downloader.cc', + 'file_utils.cc', 'json_manifest.cc', 'local_temp_file.cc', 'module_ppapi.cc', diff --git a/ppapi/native_client/src/trusted/plugin/pnacl_coordinator.cc b/ppapi/native_client/src/trusted/plugin/pnacl_coordinator.cc index a938b77..613abd4 100644 --- a/ppapi/native_client/src/trusted/plugin/pnacl_coordinator.cc +++ b/ppapi/native_client/src/trusted/plugin/pnacl_coordinator.cc @@ -90,9 +90,11 @@ class PnaclManifest : public Manifest { "key did not start with files/"); return false; } - // Append what follows files to the pnacl URL prefix. + // Resolve the full URL to the file. Provide it with a platform-specific + // prefix. nacl::string key_basename = key.substr(kFilesPrefix.length()); - return ResolveURL(key_basename, full_url, error_info); + return ResolveURL(PnaclUrls::PrependPlatformPrefix(key_basename), + full_url, error_info); } private: @@ -237,22 +239,19 @@ PnaclCoordinator* PnaclCoordinator::BitcodeToNative( reinterpret_cast<const void*>(coordinator->manifest_.get()), coordinator->off_the_record_)); - // Load llc and ld. - std::vector<nacl::string> resource_urls; - resource_urls.push_back(PnaclUrls::GetLlcUrl()); - resource_urls.push_back(PnaclUrls::GetLdUrl()); - pp::CompletionCallback resources_cb = - coordinator->callback_factory_.NewCallback( - &PnaclCoordinator::ResourcesDidLoad); + // Loading resources (e.g. llc and ld nexes) is done with PnaclResources. coordinator->resources_.reset( new PnaclResources(plugin, coordinator, - coordinator->manifest_.get(), - resource_urls, - resources_cb)); + coordinator->manifest_.get())); CHECK(coordinator->resources_ != NULL); - coordinator->resources_->StartLoad(); - // ResourcesDidLoad will be invoked when all resources have been received. + + // The first step of loading resources: read the resource info file. + pp::CompletionCallback resource_info_read_cb = + coordinator->callback_factory_.NewCallback( + &PnaclCoordinator::ResourceInfoWasRead); + coordinator->resources_->ReadResourceInfo(PnaclUrls::GetResourceInfoUrl(), + resource_info_read_cb); return coordinator; } @@ -649,6 +648,15 @@ void PnaclCoordinator::NexeReadDidOpen(int32_t pp_error) { translate_notify_callback_.Run(pp_error); } +void PnaclCoordinator::ResourceInfoWasRead(int32_t pp_error) { + PLUGIN_PRINTF(("PluginCoordinator::ResourceInfoWasRead (pp_error=%" + NACL_PRId32")\n", pp_error)); + // Second step of loading resources: call StartLoad. + pp::CompletionCallback resources_cb = + callback_factory_.NewCallback(&PnaclCoordinator::ResourcesDidLoad); + resources_->StartLoad(resources_cb); +} + void PnaclCoordinator::ResourcesDidLoad(int32_t pp_error) { PLUGIN_PRINTF(("PnaclCoordinator::ResourcesDidLoad (pp_error=%" NACL_PRId32")\n", pp_error)); diff --git a/ppapi/native_client/src/trusted/plugin/pnacl_coordinator.h b/ppapi/native_client/src/trusted/plugin/pnacl_coordinator.h index 963fd1e..d6ee015 100644 --- a/ppapi/native_client/src/trusted/plugin/pnacl_coordinator.h +++ b/ppapi/native_client/src/trusted/plugin/pnacl_coordinator.h @@ -158,8 +158,10 @@ class PnaclCoordinator: public CallbackSource<FileStreamData> { const PnaclOptions& pnacl_options, const pp::CompletionCallback& translate_notify_callback); + // Callback for when the resource info JSON file has been read. + void ResourceInfoWasRead(int32_t pp_error); + // Callback for when llc and ld have been downloaded. - // This is the first callback invoked in response to BitcodeToNative. void ResourcesDidLoad(int32_t pp_error); // Callbacks for temporary file related stages. diff --git a/ppapi/native_client/src/trusted/plugin/pnacl_resources.cc b/ppapi/native_client/src/trusted/plugin/pnacl_resources.cc index af2944f..119d53a 100644 --- a/ppapi/native_client/src/trusted/plugin/pnacl_resources.cc +++ b/ppapi/native_client/src/trusted/plugin/pnacl_resources.cc @@ -7,22 +7,29 @@ #include "native_client/src/include/portability_io.h" #include "native_client/src/shared/platform/nacl_check.h" #include "native_client/src/trusted/desc/nacl_desc_wrapper.h" +#include "native_client/src/trusted/plugin/file_utils.h" #include "native_client/src/trusted/plugin/manifest.h" #include "native_client/src/trusted/plugin/plugin.h" #include "native_client/src/trusted/plugin/pnacl_coordinator.h" #include "native_client/src/trusted/plugin/utility.h" - #include "ppapi/c/pp_errors.h" +#include "third_party/jsoncpp/source/include/json/reader.h" +#include "third_party/jsoncpp/source/include/json/value.h" namespace plugin { -static const char kPnaclComponentScheme[] = - "pnacl-component://"; -const char PnaclUrls::kLlcUrl[] = "llc.nexe"; -const char PnaclUrls::kLdUrl[] = "ld.nexe"; +static const char kPnaclComponentScheme[] = "pnacl-component://"; +const char PnaclUrls::kResourceInfoUrl[] = "pnacl.json"; + +const char PnaclResources::kDefaultLlcName[] = "llc.nexe"; +const char PnaclResources::kDefaultLdName[] = "ld.nexe"; nacl::string PnaclUrls::GetBaseUrl() { - return nacl::string(kPnaclComponentScheme) + GetSandboxISA() + "/"; + return nacl::string(kPnaclComponentScheme); +} + +nacl::string PnaclUrls::PrependPlatformPrefix(const nacl::string& url) { + return nacl::string(GetSandboxISA()) + "/" + url; } // Determine if a URL is for a pnacl-component file, or if it is some other @@ -92,22 +99,118 @@ nacl::DescWrapper* PnaclResources::WrapperForUrl(const nacl::string& url) { return resource_wrappers_[url]; } -void PnaclResources::StartLoad() { +void PnaclResources::ReadResourceInfo( + const nacl::string& resource_info_url, + const pp::CompletionCallback& resource_info_read_cb) { + PLUGIN_PRINTF(("PnaclResources::ReadResourceInfo\n")); + + nacl::string full_url; + ErrorInfo error_info; + if (!manifest_->ResolveURL(resource_info_url, &full_url, &error_info)) { + ReadResourceInfoError(nacl::string("failed to resolve ") + + resource_info_url + ": " + + error_info.message() + "."); + return; + } + PLUGIN_PRINTF(("Resolved resources info url: %s\n", full_url.c_str())); + nacl::string resource_info_filename = + PnaclUrls::PnaclComponentURLToFilename(full_url); + + PLUGIN_PRINTF(("Pnacl-converted resources info url: %s\n", + resource_info_filename.c_str())); + + int32_t fd = GetPnaclFD(plugin_, resource_info_filename.c_str()); + if (fd < 0) { + ReadResourceInfoError( + nacl::string("PnaclResources::ReadResourceInfo failed for: ") + + resource_info_filename); + return; + } + + nacl::string json_buffer; + file_utils::StatusCode status = file_utils::SlurpFile(fd, json_buffer); + if (status != file_utils::PLUGIN_FILE_SUCCESS) { + ReadResourceInfoError( + nacl::string("PnaclResources::ReadResourceInfo reading " + "failed for: ") + resource_info_filename); + return; + } + + // Finally, we have the resource info JSON data in json_buffer. + PLUGIN_PRINTF(("Resource info JSON data:\n%s\n", json_buffer.c_str())); + nacl::string error_message; + if (!ParseResourceInfo(json_buffer, error_message)) { + ReadResourceInfoError(nacl::string("Parsing resource info failed: ") + + error_message + "\n"); + return; + } + + // Done. Queue the completion callback. + pp::Core* core = pp::Module::Get()->core(); + core->CallOnMainThread(0, resource_info_read_cb, PP_OK); +} + +void PnaclResources::ReadResourceInfoError(const nacl::string& msg) { + coordinator_->ReportNonPpapiError(ERROR_PNACL_RESOURCE_FETCH, msg); +} + +bool PnaclResources::ParseResourceInfo(const nacl::string& buf, + nacl::string& errmsg) { + // Expect the JSON file to contain a top-level object (dictionary). + Json::Reader json_reader; + Json::Value json_data; + if (!json_reader.parse(buf, json_data)) { + errmsg = nacl::string("JSON parse error: ") + + json_reader.getFormatedErrorMessages(); + return false; + } + + if (!json_data.isObject()) { + errmsg = nacl::string("Malformed JSON dictionary"); + return false; + } + + if (json_data.isMember("pnacl-llc-name")) { + Json::Value json_name = json_data["pnacl-llc-name"]; + if (json_name.isString()) { + llc_tool_name = json_name.asString(); + PLUGIN_PRINTF(("Set llc_tool_name=%s\n", llc_tool_name.c_str())); + } + } + + if (json_data.isMember("pnacl-ld-name")) { + Json::Value json_name = json_data["pnacl-ld-name"]; + if (json_name.isString()) { + ld_tool_name = json_name.asString(); + PLUGIN_PRINTF(("Set ld_tool_name=%s\n", ld_tool_name.c_str())); + } + } + + return true; +} + +void PnaclResources::StartLoad( + const pp::CompletionCallback& all_loaded_callback) { PLUGIN_PRINTF(("PnaclResources::StartLoad\n")); - CHECK(resource_urls_.size() > 0); + std::vector<nacl::string> resource_urls; + resource_urls.push_back(GetLlcUrl()); + resource_urls.push_back(GetLdUrl()); + PLUGIN_PRINTF(("PnaclResources::StartLoad -- local install of PNaCl.\n")); // Do a blocking load of each of the resources. int32_t result = PP_OK; - for (size_t i = 0; i < resource_urls_.size(); ++i) { - const nacl::string& url = resource_urls_[i]; + for (size_t i = 0; i < resource_urls.size(); ++i) { + const nacl::string& url_with_platform_prefix = + PnaclUrls::PrependPlatformPrefix(resource_urls[i]); nacl::string full_url; ErrorInfo error_info; - if (!manifest_->ResolveURL(resource_urls_[i], &full_url, &error_info)) { + if (!manifest_->ResolveURL(url_with_platform_prefix, &full_url, + &error_info)) { coordinator_->ReportNonPpapiError( ERROR_PNACL_RESOURCE_FETCH, nacl::string("failed to resolve ") + - url + ": " + + url_with_platform_prefix + ": " + error_info.message() + "."); break; } @@ -117,18 +220,18 @@ void PnaclResources::StartLoad() { if (fd < 0) { coordinator_->ReportNonPpapiError( ERROR_PNACL_RESOURCE_FETCH, - nacl::string("PnaclLocalResources::StartLoad failed for: ") + + nacl::string("PnaclResources::StartLoad failed for: ") + filename + " (PNaCl not installed? Check chrome://nacl)"); result = PP_ERROR_FILENOTFOUND; break; } else { - resource_wrappers_[url] = + resource_wrappers_[resource_urls[i]] = plugin_->wrapper_factory()->MakeFileDesc(fd, O_RDONLY); } } // We're done! Queue the callback. pp::Core* core = pp::Module::Get()->core(); - core->CallOnMainThread(0, all_loaded_callback_, result); + core->CallOnMainThread(0, all_loaded_callback, result); } } // 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 54e6399..10dbd35 100644 --- a/ppapi/native_client/src/trusted/plugin/pnacl_resources.h +++ b/ppapi/native_client/src/trusted/plugin/pnacl_resources.h @@ -26,15 +26,23 @@ class PnaclCoordinator; // Constants for loading LLC and LD. class PnaclUrls { public: + // Get the base URL prefix for Pnacl resources (without platform prefix). static nacl::string GetBaseUrl(); + + // Return {platform_prefix}/url + static nacl::string PrependPlatformPrefix(const nacl::string& url); + static bool IsPnaclComponent(const nacl::string& full_url); static nacl::string PnaclComponentURLToFilename( const nacl::string& full_url); - static const nacl::string GetLlcUrl() { return nacl::string(kLlcUrl); } - static const nacl::string GetLdUrl() { return nacl::string(kLdUrl); } + + // Get the URL for the resource info JSON file that contains information + // about loadable resources. + static const nacl::string GetResourceInfoUrl() { + return nacl::string(kResourceInfoUrl); + } private: - static const char kLlcUrl[]; - static const char kLdUrl[]; + static const char kResourceInfoUrl[]; }; // Loads a list of resources, providing a way to get file descriptors for @@ -44,20 +52,35 @@ class PnaclResources { public: PnaclResources(Plugin* plugin, PnaclCoordinator* coordinator, - const Manifest* manifest, - const std::vector<nacl::string>& resource_urls, - const pp::CompletionCallback& all_loaded_callback) + const Manifest* manifest) : plugin_(plugin), coordinator_(coordinator), manifest_(manifest), - resource_urls_(resource_urls), - all_loaded_callback_(all_loaded_callback) { + llc_tool_name(kDefaultLlcName), + ld_tool_name(kDefaultLdName) { } virtual ~PnaclResources(); - // Start loading the resources. After construction, this is the first step. - virtual void StartLoad(); - // Get file descs by name. Only valid after all_loaded_callback_ has been run. + // Read the resource info JSON file. This is the first step after + // construction; it has to be completed before StartLoad is called. + virtual void ReadResourceInfo( + const nacl::string& resource_info_url, + const pp::CompletionCallback& resource_info_read_cb); + + // Start loading the resources. + virtual void StartLoad( + const pp::CompletionCallback& all_loaded_callback); + + const nacl::string& GetLlcUrl() { + return llc_tool_name; + } + + const nacl::string& GetLdUrl() { + return ld_tool_name; + } + + // Get file descs by name. Only valid after StartLoad's completion callback + // fired. nacl::DescWrapper* WrapperForUrl(const nacl::string& url); static int32_t GetPnaclFD(Plugin* plugin, const char* filename); @@ -71,13 +94,28 @@ class PnaclResources { PnaclCoordinator* coordinator_; // The manifest for looking up resource URLs. const Manifest* manifest_; - // The list of resource URLs (relative to resource_base_url_) to load. - std::vector<nacl::string> resource_urls_; - // Callback to be invoked when all resources can be guaranteed available. - pp::CompletionCallback all_loaded_callback_; // The descriptor wrappers for the downloaded URLs. Only valid // once all_loaded_callback_ has been invoked. std::map<nacl::string, nacl::DescWrapper*> resource_wrappers_; + + // The names of the llc and ld nexes are read from the resource info file. + // These are default values if the resource file does not contain the names. + // TODO(eliben): this should be eventually removed, once all nacl deps + // propagate - the names should always exist in the resource info JSON file. + static const char kDefaultLlcName[]; + static const char kDefaultLdName[]; + + // Tool names for llc and ld; read from the resource info file. + nacl::string llc_tool_name; + nacl::string ld_tool_name; + + // Parses resource info json data in |buf|. Returns true if successful. + // Otherwise returns false and places an error message in |errmsg|. + bool ParseResourceInfo(const nacl::string& buf, nacl::string& errmsg); + + // Convenience function for reporting an error while reading the resource + // info file. + void ReadResourceInfoError(const nacl::string& msg); }; } // 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 e035ce1..7b1a680 100644 --- a/ppapi/native_client/src/trusted/plugin/pnacl_translate_thread.cc +++ b/ppapi/native_client/src/trusted/plugin/pnacl_translate_thread.cc @@ -135,7 +135,7 @@ void PnaclTranslateThread::DoTranslate() { nacl::MutexLocker ml(&subprocess_mu_); int64_t llc_start_time = NaClGetTimeOfDayMicroseconds(); llc_subprocess_.reset( - StartSubprocess(PnaclUrls::GetLlcUrl(), manifest_, &error_info)); + StartSubprocess(resources_->GetLlcUrl(), manifest_, &error_info)); if (llc_subprocess_ == NULL) { TranslateFailed(ERROR_PNACL_LLC_SETUP, "Compile process could not be created: " + @@ -278,7 +278,7 @@ bool PnaclTranslateThread::RunLdSubprocess(int is_shared_library, nacl::MutexLocker ml(&subprocess_mu_); int64_t ld_start_time = NaClGetTimeOfDayMicroseconds(); ld_subprocess_.reset( - StartSubprocess(PnaclUrls::GetLdUrl(), manifest_, &error_info)); + StartSubprocess(resources_->GetLdUrl(), manifest_, &error_info)); if (ld_subprocess_ == NULL) { TranslateFailed(ERROR_PNACL_LD_SETUP, "Link process could not be created: " + diff --git a/ppapi/native_client/src/untrusted/pnacl_support_extension/pnacl_info_template.json b/ppapi/native_client/src/untrusted/pnacl_support_extension/pnacl_info_template.json index 380fc6b..0aa66e9 100644 --- a/ppapi/native_client/src/untrusted/pnacl_support_extension/pnacl_info_template.json +++ b/ppapi/native_client/src/untrusted/pnacl_support_extension/pnacl_info_template.json @@ -1,4 +1,6 @@ { "abi-version": "%(abi-version)s", - "pnacl-arch": "%(arch)s" + "pnacl-arch": "%(arch)s", + "pnacl-llc-name": "llc.nexe", + "pnacl-ld-name": "ld.nexe" } |