diff options
author | teravest@chromium.org <teravest@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-05-05 21:46:36 +0000 |
---|---|---|
committer | teravest@chromium.org <teravest@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-05-05 21:46:36 +0000 |
commit | 4103bb0f0d318dafbb9d274bad4af236bbf79eb4 (patch) | |
tree | 2175cdb9452e98a9a2e135b01ec1b1fdec4b14f8 /ppapi | |
parent | 39ab7058d339186f71f7c6345d60084e44c1540a (diff) | |
download | chromium_src-4103bb0f0d318dafbb9d274bad4af236bbf79eb4.zip chromium_src-4103bb0f0d318dafbb9d274bad4af236bbf79eb4.tar.gz chromium_src-4103bb0f0d318dafbb9d274bad4af236bbf79eb4.tar.bz2 |
Pepper: Move manifest logic to components/nacl.
The goal of the trusted plugin refactor is to move as much code as possible out of ppapi/native_client/src/trusted/plugin. This change moves all the manifest parsing and lookup logic out of the trusted plugin at once; it's hard to move piecemeal.
BUG=353592
R=bbudge@chromium.org, mallinath@chromium.org
Committed: https://src.chromium.org/viewvc/chrome?view=rev&revision=268250
Review URL: https://codereview.chromium.org/264943003
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@268280 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ppapi')
16 files changed, 124 insertions, 969 deletions
diff --git a/ppapi/api/private/ppb_nacl_private.idl b/ppapi/api/private/ppb_nacl_private.idl index 04b6758..a1fcb45 100644 --- a/ppapi/api/private/ppb_nacl_private.idl +++ b/ppapi/api/private/ppb_nacl_private.idl @@ -411,4 +411,25 @@ interface PPB_NaCl_Private { void DownloadManifestToBuffer([in] PP_Instance instance, [out] PP_Var data, [in] PP_CompletionCallback callback); + + int32_t CreatePnaclManifest([in] PP_Instance instance); + int32_t CreateJsonManifest([in] PP_Instance instance, + [in] str_t manifest_base_url, + [in] str_t sandbox_isa, + [in] str_t manifest_data); + + void DestroyManifest([in] PP_Instance instance, + [in] int32_t manifest_id); + + PP_Bool GetManifestProgramURL([in] PP_Instance instance, + [in] int32_t manifest_id, + [out] PP_Var full_url, + [out] PP_PNaClOptions pnacl_options, + [out] PP_Bool uses_nonsfi_mode); + + PP_Bool ManifestResolveKey([in] PP_Instance instance, + [in] int32_t manifest_id, + [in] str_t key, + [out] PP_Var full_url, + [out] PP_PNaClOptions pnacl_options); }; diff --git a/ppapi/c/private/ppb_nacl_private.h b/ppapi/c/private/ppb_nacl_private.h index 9ac540a..bc4a182 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 Sat May 3 04:07:13 2014. */ +/* From private/ppb_nacl_private.idl modified Mon May 5 10:57:38 2014. */ #ifndef PPAPI_C_PRIVATE_PPB_NACL_PRIVATE_H_ #define PPAPI_C_PRIVATE_PPB_NACL_PRIVATE_H_ @@ -407,6 +407,22 @@ struct PPB_NaCl_Private_1_0 { void (*DownloadManifestToBuffer)(PP_Instance instance, struct PP_Var* data, struct PP_CompletionCallback callback); + int32_t (*CreatePnaclManifest)(PP_Instance instance); + int32_t (*CreateJsonManifest)(PP_Instance instance, + const char* manifest_base_url, + const char* sandbox_isa, + const char* manifest_data); + void (*DestroyManifest)(PP_Instance instance, int32_t manifest_id); + PP_Bool (*GetManifestProgramURL)(PP_Instance instance, + int32_t manifest_id, + struct PP_Var* full_url, + struct PP_PNaClOptions* pnacl_options, + PP_Bool* uses_nonsfi_mode); + PP_Bool (*ManifestResolveKey)(PP_Instance instance, + int32_t manifest_id, + const char* key, + struct PP_Var* full_url, + struct PP_PNaClOptions* pnacl_options); }; typedef struct PPB_NaCl_Private_1_0 PPB_NaCl_Private; diff --git a/ppapi/native_client/src/trusted/plugin/json_manifest.cc b/ppapi/native_client/src/trusted/plugin/json_manifest.cc deleted file mode 100644 index 418339c..0000000 --- a/ppapi/native_client/src/trusted/plugin/json_manifest.cc +++ /dev/null @@ -1,674 +0,0 @@ -/* - * Copyright (c) 2012 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. - */ - -#include <algorithm> - -#include "ppapi/native_client/src/trusted/plugin/json_manifest.h" - -#include <stdlib.h> - -#include "native_client/src/include/nacl_base.h" -#include "native_client/src/include/nacl_macros.h" -#include "native_client/src/include/nacl_string.h" -#include "native_client/src/include/portability.h" -#include "native_client/src/shared/platform/nacl_check.h" -#include "ppapi/c/private/ppb_nacl_private.h" -#include "ppapi/cpp/dev/url_util_dev.h" -#include "ppapi/cpp/var.h" -#include "ppapi/native_client/src/trusted/plugin/plugin_error.h" -#include "ppapi/native_client/src/trusted/plugin/utility.h" -#include "third_party/jsoncpp/source/include/json/reader.h" - -namespace plugin { - -namespace { -// Top-level section name keys -const char* const kProgramKey = "program"; -const char* const kInterpreterKey = "interpreter"; -const char* const kFilesKey = "files"; - -// ISA Dictionary keys -const char* const kX8632Key = "x86-32"; -const char* const kX8632NonSFIKey = "x86-32-nonsfi"; -const char* const kX8664Key = "x86-64"; -const char* const kX8664NonSFIKey = "x86-64-nonsfi"; -const char* const kArmKey = "arm"; -const char* const kArmNonSFIKey = "arm-nonsfi"; -const char* const kPortableKey = "portable"; - -// Url Resolution keys -const char* const kPnaclDebugKey = "pnacl-debug"; -const char* const kPnaclTranslateKey = "pnacl-translate"; -const char* const kUrlKey = "url"; - -// PNaCl keys -const char* const kOptLevelKey = "optlevel"; - -// Sample NaCl manifest file: -// { -// "program": { -// "x86-32": {"url": "myprogram_x86-32.nexe"}, -// "x86-64": {"url": "myprogram_x86-64.nexe"}, -// "arm": {"url": "myprogram_arm.nexe"} -// }, -// "interpreter": { -// "x86-32": {"url": "interpreter_x86-32.nexe"}, -// "x86-64": {"url": "interpreter_x86-64.nexe"}, -// "arm": {"url": "interpreter_arm.nexe"} -// }, -// "files": { -// "foo.txt": { -// "portable": {"url": "foo.txt"} -// }, -// "bar.txt": { -// "x86-32": {"url": "x86-32/bar.txt"}, -// "portable": {"url": "bar.txt"} -// }, -// "libfoo.so": { -// "x86-64" : { "url": "..." } -// } -// } -// } - -// Sample PNaCl manifest file: -// { -// "program": { -// "portable": { -// "pnacl-translate": { -// "url": "myprogram.pexe" -// }, -// "pnacl-debug": { -// "url": "myprogram.debug.pexe", -// "opt_level": 0 -// } -// } -// }, -// "files": { -// "foo.txt": { -// "portable": {"url": "foo.txt"} -// }, -// "bar.txt": { -// "portable": {"url": "bar.txt"} -// } -// } -// } - -// Returns the key for the architecture in non-SFI mode. -nacl::string GetNonSFIKey(const nacl::string& sandbox_isa) { - return sandbox_isa + "-nonsfi"; -} - -// Looks up |property_name| in the vector |valid_names| with length -// |valid_name_count|. Returns true if |property_name| is found. -bool FindMatchingProperty(const nacl::string& property_name, - const char** valid_names, - size_t valid_name_count) { - for (size_t i = 0; i < valid_name_count; ++i) { - if (property_name == valid_names[i]) { - return true; - } - } - return false; -} - -// Return true if this is a valid dictionary. Having only keys present in -// |valid_keys| and having at least the keys in |required_keys|. -// Error messages will be placed in |error_string|, given that the dictionary -// was the property value of |container_key|. -// E.g., "container_key" : dictionary -bool IsValidDictionary(const Json::Value& dictionary, - const nacl::string& container_key, - const nacl::string& parent_key, - const char** valid_keys, - size_t valid_key_count, - const char** required_keys, - size_t required_key_count, - nacl::string* error_string) { - if (!dictionary.isObject()) { - nacl::stringstream error_stream; - error_stream << parent_key << " property '" << container_key - << "' is non-dictionary value '" - << dictionary.toStyledString() << "'."; - *error_string = error_stream.str(); - return false; - } - // Check for unknown dictionary members. - Json::Value::Members members = dictionary.getMemberNames(); - for (size_t i = 0; i < members.size(); ++i) { - nacl::string property_name = members[i]; - if (!FindMatchingProperty(property_name, - valid_keys, - valid_key_count)) { - // For forward compatibility, we do not prohibit other keys being in - // the dictionary. - PLUGIN_PRINTF(("WARNING: '%s' property '%s' has unknown key '%s'.\n", - parent_key.c_str(), - container_key.c_str(), property_name.c_str())); - } - } - // Check for required members. - for (size_t i = 0; i < required_key_count; ++i) { - if (!dictionary.isMember(required_keys[i])) { - nacl::stringstream error_stream; - error_stream << parent_key << " property '" << container_key - << "' does not have required key: '" - << required_keys[i] << "'."; - *error_string = error_stream.str(); - return false; - } - } - return true; -} - -// Validate a "url" dictionary assuming it was resolved from container_key. -// E.g., "container_key" : { "url": "foo.txt" } -bool IsValidUrlSpec(const Json::Value& url_spec, - const nacl::string& container_key, - const nacl::string& parent_key, - const nacl::string& sandbox_isa, - nacl::string* error_string) { - static const char* kManifestUrlSpecRequired[] = { - kUrlKey - }; - const char** urlSpecPlusOptional; - size_t urlSpecPlusOptionalLength; - if (sandbox_isa == kPortableKey) { - static const char* kPnaclUrlSpecPlusOptional[] = { - kUrlKey, - kOptLevelKey, - }; - urlSpecPlusOptional = kPnaclUrlSpecPlusOptional; - urlSpecPlusOptionalLength = NACL_ARRAY_SIZE(kPnaclUrlSpecPlusOptional); - } else { - // URL specifications must not contain "pnacl-translate" keys. - // This prohibits NaCl clients from invoking PNaCl. - if (url_spec.isMember(kPnaclTranslateKey)) { - nacl::stringstream error_stream; - error_stream << "PNaCl-like NMF with application/x-nacl mimetype instead " - << "of x-pnacl mimetype (has " << kPnaclTranslateKey << ")."; - *error_string = error_stream.str(); - return false; - } - urlSpecPlusOptional = kManifestUrlSpecRequired; - urlSpecPlusOptionalLength = NACL_ARRAY_SIZE(kManifestUrlSpecRequired); - } - if (!IsValidDictionary(url_spec, container_key, parent_key, - urlSpecPlusOptional, - urlSpecPlusOptionalLength, - kManifestUrlSpecRequired, - NACL_ARRAY_SIZE(kManifestUrlSpecRequired), - error_string)) { - return false; - } - // Verify the correct types of the fields if they exist. - Json::Value url = url_spec[kUrlKey]; - if (!url.isString()) { - nacl::stringstream error_stream; - error_stream << parent_key << " property '" << container_key << - "' has non-string value '" << url.toStyledString() << - "' for key '" << kUrlKey << "'."; - *error_string = error_stream.str(); - return false; - } - Json::Value opt_level = url_spec[kOptLevelKey]; - if (!opt_level.empty() && !opt_level.isNumeric()) { - nacl::stringstream error_stream; - error_stream << parent_key << " property '" << container_key << - "' has non-numeric value '" << opt_level.toStyledString() << - "' for key '" << kOptLevelKey << "'."; - *error_string = error_stream.str(); - return false; - } - return true; -} - -// Validate a "pnacl-translate" or "pnacl-debug" dictionary, assuming -// it was resolved from container_key. -// E.g., "container_key" : { "pnacl-translate" : URLSpec } -bool IsValidPnaclTranslateSpec(const Json::Value& pnacl_spec, - const nacl::string& container_key, - const nacl::string& parent_key, - const nacl::string& sandbox_isa, - nacl::string* error_string) { - static const char* kManifestPnaclSpecValid[] = { - kPnaclDebugKey, - kPnaclTranslateKey - }; - static const char* kManifestPnaclSpecRequired[] = { - kPnaclTranslateKey - }; - if (!IsValidDictionary(pnacl_spec, container_key, parent_key, - kManifestPnaclSpecValid, - NACL_ARRAY_SIZE(kManifestPnaclSpecValid), - kManifestPnaclSpecRequired, - NACL_ARRAY_SIZE(kManifestPnaclSpecRequired), - error_string)) { - return false; - } - Json::Value url_spec = pnacl_spec[kPnaclTranslateKey]; - if (!IsValidUrlSpec(url_spec, kPnaclTranslateKey, - container_key, sandbox_isa, error_string)) { - return false; - } - return true; -} - -// Validates that |dictionary| is a valid ISA dictionary. An ISA dictionary -// is validated to have keys from within the set of recognized ISAs. Unknown -// ISAs are allowed, but ignored and warnings are produced. It is also validated -// that it must have an entry to match the ISA specified in |sandbox_isa| or -// have a fallback 'portable' entry if there is no match. Returns true if -// |dictionary| is an ISA to URL map. Sets |error_info| to something -// descriptive if it fails. -bool IsValidISADictionary(const Json::Value& dictionary, - const nacl::string& parent_key, - const nacl::string& sandbox_isa, - bool must_find_matching_entry, - bool nonsfi_enabled, - ErrorInfo* error_info) { - if (error_info == NULL) return false; - - // An ISA to URL dictionary has to be an object. - if (!dictionary.isObject()) { - error_info->SetReport(PP_NACL_ERROR_MANIFEST_SCHEMA_VALIDATE, - nacl::string("manifest: ") + parent_key + - " property is not an ISA to URL dictionary"); - return false; - } - // Build the set of reserved ISA dictionary keys. - const char** isaProperties; - size_t isaPropertiesLength; - if (sandbox_isa == kPortableKey) { - // The known values for PNaCl ISA dictionaries in the manifest. - static const char* kPnaclManifestISAProperties[] = { - kPortableKey - }; - isaProperties = kPnaclManifestISAProperties; - isaPropertiesLength = NACL_ARRAY_SIZE(kPnaclManifestISAProperties); - } else { - // The known values for NaCl ISA dictionaries in the manifest. - static const char* kNaClManifestISAProperties[] = { - kX8632Key, - kX8632NonSFIKey, - kX8664Key, - kX8664NonSFIKey, - kArmKey, - kArmNonSFIKey, - // "portable" is here to allow checking that, if present, it can - // only refer to an URL, such as for a data file, and not to - // "pnacl-translate", which would cause the creation of a nexe. - kPortableKey - }; - isaProperties = kNaClManifestISAProperties; - isaPropertiesLength = NACL_ARRAY_SIZE(kNaClManifestISAProperties); - } - // Check that entries in the dictionary are structurally correct. - Json::Value::Members members = dictionary.getMemberNames(); - for (size_t i = 0; i < members.size(); ++i) { - nacl::string property_name = members[i]; - Json::Value property_value = dictionary[property_name]; - nacl::string error_string; - if (FindMatchingProperty(property_name, - isaProperties, - isaPropertiesLength)) { - // For NaCl, arch entries can only be - // "arch/portable" : URLSpec - // For PNaCl arch in "program" dictionary entries can be - // "portable" : { "pnacl-translate": URLSpec } - // or "portable" : { "pnacl-debug": URLSpec } - // For PNaCl arch elsewhere, dictionary entries can only be - // "portable" : URLSpec - if ((sandbox_isa != kPortableKey && - !IsValidUrlSpec(property_value, property_name, parent_key, - sandbox_isa, &error_string)) || - (sandbox_isa == kPortableKey && - parent_key == kProgramKey && - !IsValidPnaclTranslateSpec(property_value, property_name, parent_key, - sandbox_isa, &error_string)) || - (sandbox_isa == kPortableKey && - parent_key != kProgramKey && - !IsValidUrlSpec(property_value, property_name, parent_key, - sandbox_isa, &error_string))) { - error_info->SetReport(PP_NACL_ERROR_MANIFEST_SCHEMA_VALIDATE, - nacl::string("manifest: ") + error_string); - return false; - } - } else { - // For forward compatibility, we do not prohibit other keys being in - // the dictionary, as they may be architectures supported in later - // versions. However, the value of these entries must be an URLSpec. - PLUGIN_PRINTF(("IsValidISADictionary: unrecognized key '%s'.\n", - property_name.c_str())); - if (!IsValidUrlSpec(property_value, property_name, parent_key, - sandbox_isa, &error_string)) { - error_info->SetReport(PP_NACL_ERROR_MANIFEST_SCHEMA_VALIDATE, - nacl::string("manifest: ") + error_string); - return false; - } - } - } - - if (sandbox_isa == kPortableKey) { - bool has_portable = dictionary.isMember(kPortableKey); - - if (!has_portable) { - error_info->SetReport( - PP_NACL_ERROR_MANIFEST_PROGRAM_MISSING_ARCH, - nacl::string("manifest: no version of ") + parent_key + - " given for portable."); - return false; - } - } else if (must_find_matching_entry) { - // TODO(elijahtaylor) add ISA resolver here if we expand ISAs to include - // micro-architectures that can resolve to multiple valid sandboxes. - bool has_isa = dictionary.isMember(sandbox_isa); - bool has_nonsfi_isa = - nonsfi_enabled && dictionary.isMember(GetNonSFIKey(sandbox_isa)); - bool has_portable = dictionary.isMember(kPortableKey); - - if (!has_isa && !has_nonsfi_isa && !has_portable) { - error_info->SetReport( - PP_NACL_ERROR_MANIFEST_PROGRAM_MISSING_ARCH, - nacl::string("manifest: no version of ") + parent_key + - " given for current arch and no portable version found."); - return false; - } - } - - return true; -} - -void GrabUrlAndPNaClOptions(const Json::Value& url_spec, - nacl::string* url, - PP_PNaClOptions* pnacl_options) { - *url = url_spec[kUrlKey].asString(); - pnacl_options->translate = PP_TRUE; - if (url_spec.isMember(kOptLevelKey)) { - int32_t opt_raw = url_spec[kOptLevelKey].asInt(); - int32_t opt_level; - // Currently only allow 0 or 2, since that is what we test. - if (opt_raw <= 0) - opt_level = 0; - else - opt_level = 2; - pnacl_options->opt_level = opt_level; - } -} - -} // namespace - -bool JsonManifest::Init(const nacl::string& manifest_json, - ErrorInfo* error_info) { - if (error_info == NULL) { - return false; - } - Json::Reader reader; - if (!reader.parse(manifest_json, dictionary_)) { - std::string json_error = reader.getFormatedErrorMessages(); - error_info->SetReport(PP_NACL_ERROR_MANIFEST_PARSING, - "manifest JSON parsing failed: " + json_error); - return false; - } - // Parse has ensured the string was valid JSON. Check that it matches the - // manifest schema. - return MatchesSchema(error_info); -} - -bool JsonManifest::MatchesSchema(ErrorInfo* error_info) { - pp::Var exception; - if (error_info == NULL) { - return false; - } - if (!dictionary_.isObject()) { - error_info->SetReport( - PP_NACL_ERROR_MANIFEST_SCHEMA_VALIDATE, - "manifest: is not a json dictionary."); - return false; - } - Json::Value::Members members = dictionary_.getMemberNames(); - for (size_t i = 0; i < members.size(); ++i) { - // The top level dictionary entries valid in the manifest file. - static const char* kManifestTopLevelProperties[] = { kProgramKey, - kInterpreterKey, - kFilesKey }; - nacl::string property_name = members[i]; - if (!FindMatchingProperty(property_name, - kManifestTopLevelProperties, - NACL_ARRAY_SIZE(kManifestTopLevelProperties))) { - PLUGIN_PRINTF(("JsonManifest::MatchesSchema: WARNING: unknown top-level " - "section '%s' in manifest.\n", property_name.c_str())); - } - } - - // A manifest file must have a program section. - if (!dictionary_.isMember(kProgramKey)) { - error_info->SetReport( - PP_NACL_ERROR_MANIFEST_SCHEMA_VALIDATE, - nacl::string("manifest: missing '") + kProgramKey + "' section."); - return false; - } - - // Validate the program section. - // There must be a matching (portable or sandbox_isa_) entry for program for - // NaCl. - if (!IsValidISADictionary(dictionary_[kProgramKey], - kProgramKey, - sandbox_isa_, - true, - nonsfi_enabled_, - error_info)) { - return false; - } - - // Validate the interpreter section (if given). - // There must be a matching (portable or sandbox_isa_) entry for interpreter - // for NaCl. - if (dictionary_.isMember(kInterpreterKey)) { - if (!IsValidISADictionary(dictionary_[kInterpreterKey], - kInterpreterKey, - sandbox_isa_, - true, - nonsfi_enabled_, - error_info)) { - return false; - } - } - - // Validate the file dictionary (if given). - // The "files" key does not require a matching (portable or sandbox_isa_) - // entry at schema validation time for NaCl. This allows manifests to specify - // resources that are only loaded for a particular sandbox_isa. - if (dictionary_.isMember(kFilesKey)) { - const Json::Value& files = dictionary_[kFilesKey]; - if (!files.isObject()) { - error_info->SetReport( - PP_NACL_ERROR_MANIFEST_SCHEMA_VALIDATE, - nacl::string("manifest: '") + kFilesKey + "' is not a dictionary."); - } - Json::Value::Members members = files.getMemberNames(); - for (size_t i = 0; i < members.size(); ++i) { - nacl::string file_name = members[i]; - if (!IsValidISADictionary(files[file_name], - file_name, - sandbox_isa_, - false, - nonsfi_enabled_, - error_info)) { - return false; - } - } - } - - return true; -} - -bool JsonManifest::GetURLFromISADictionary(const Json::Value& dictionary, - const nacl::string& parent_key, - nacl::string* url, - PP_PNaClOptions* pnacl_options, - bool* uses_nonsfi_mode, - ErrorInfo* error_info) const { - DCHECK(url != NULL && pnacl_options != NULL && error_info != NULL); - - // When the application actually requests a resolved URL, we must have - // a matching entry (sandbox_isa_ or portable) for NaCl. - ErrorInfo ignored_error_info; - if (!IsValidISADictionary(dictionary, parent_key, sandbox_isa_, true, - nonsfi_enabled_, &ignored_error_info)) { - error_info->SetReport(PP_NACL_ERROR_MANIFEST_RESOLVE_URL, - "architecture " + sandbox_isa_ + - " is not found for file " + parent_key); - return false; - } - - // The call to IsValidISADictionary() above guarantees that either - // sandbox_isa_, its nonsfi mode, or kPortableKey is present in the - // dictionary. - *uses_nonsfi_mode = false; - nacl::string chosen_isa; - if (sandbox_isa_ == kPortableKey) { - chosen_isa = kPortableKey; - } else { - nacl::string nonsfi_isa = GetNonSFIKey(sandbox_isa_); - if (nonsfi_enabled_ && dictionary.isMember(nonsfi_isa)) { - chosen_isa = nonsfi_isa; - *uses_nonsfi_mode = true; - } else if (dictionary.isMember(sandbox_isa_)) { - chosen_isa = sandbox_isa_; - } else if (dictionary.isMember(kPortableKey)) { - chosen_isa = kPortableKey; - } else { - // Should not reach here, because the earlier IsValidISADictionary() - // call checked that the manifest covers the current architecture. - DCHECK(false); - } - } - - const Json::Value& isa_spec = dictionary[chosen_isa]; - // If the PNaCl debug flag is turned on, look for pnacl-debug entries first. - // If found, mark that it is a debug URL. Otherwise, fall back to - // checking for pnacl-translate URLs, etc. and don't mark it as a debug URL. - if (pnacl_debug_ && isa_spec.isMember(kPnaclDebugKey)) { - GrabUrlAndPNaClOptions(isa_spec[kPnaclDebugKey], url, pnacl_options); - pnacl_options->is_debug = PP_TRUE; - } else if (isa_spec.isMember(kPnaclTranslateKey)) { - GrabUrlAndPNaClOptions(isa_spec[kPnaclTranslateKey], url, pnacl_options); - } else { - // NaCl - *url = isa_spec[kUrlKey].asString(); - pnacl_options->translate = PP_FALSE; - } - - return true; -} - -bool JsonManifest::GetKeyUrl(const Json::Value& dictionary, - const nacl::string& key, - nacl::string* full_url, - PP_PNaClOptions* pnacl_options) const { - DCHECK(full_url != NULL && pnacl_options != NULL); - if (!dictionary.isMember(key)) { - PLUGIN_PRINTF(("file key not found in manifest")); - return false; - } - const Json::Value& isa_dict = dictionary[key]; - nacl::string relative_url; - bool uses_nonsfi_mode; - - // We ignore the error_info we receive here but it's needed for the calls - // below. - ErrorInfo error_info; - - if (!GetURLFromISADictionary(isa_dict, key, &relative_url, - pnacl_options, &uses_nonsfi_mode, &error_info)) { - return false; - } - return ResolveURL(relative_url, full_url, &error_info); -} - -bool JsonManifest::GetProgramURL(nacl::string* full_url, - PP_PNaClOptions* pnacl_options, - bool* uses_nonsfi_mode, - ErrorInfo* error_info) const { - if (full_url == NULL || pnacl_options == NULL || error_info == NULL) - return false; - - const Json::Value& program = dictionary_[kProgramKey]; - nacl::string nexe_url; - if (!GetURLFromISADictionary(program, - kProgramKey, - &nexe_url, - pnacl_options, - uses_nonsfi_mode, - error_info)) { - return false; - } - return ResolveURL(nexe_url, full_url, error_info); -} - -bool JsonManifest::ResolveKey(const nacl::string& key, - nacl::string* full_url, - PP_PNaClOptions* pnacl_options) const { - NaClLog(3, "JsonManifest::ResolveKey(%s)\n", key.c_str()); - // key must be one of kProgramKey or kFileKey '/' file-section-key - - if (full_url == NULL || pnacl_options == NULL) - return false; - - if (key == kProgramKey) - return GetKeyUrl(dictionary_, key, full_url, pnacl_options); - nacl::string::const_iterator p = find(key.begin(), key.end(), '/'); - if (p == key.end()) { - std::string err = "ResolveKey: invalid key, no slash: " + key; - PLUGIN_PRINTF((err.c_str())); - return false; - } - - // generalize to permit other sections? - nacl::string prefix(key.begin(), p); - if (prefix != kFilesKey) { - std::string err = "ResolveKey: invalid key: no \"files\" prefix: " + key; - PLUGIN_PRINTF((err.c_str())); - return false; - } - - nacl::string rest(p + 1, key.end()); - - const Json::Value& files = dictionary_[kFilesKey]; - if (!files.isObject()) { - std::string err = "ResolveKey: no \"files\" dictionary"; - PLUGIN_PRINTF((err.c_str())); - return false; - } - if (!files.isMember(rest)) { - std::string err = "ResolveKey: no such \"files\" entry: " + key; - PLUGIN_PRINTF((err.c_str())); - return false; - } - return GetKeyUrl(files, rest, full_url, pnacl_options); -} - -bool JsonManifest::ResolveURL(const nacl::string& relative_url, - nacl::string* full_url, - ErrorInfo* error_info) const { - // The contents of the manifest are resolved relative to the manifest URL. - CHECK(url_util_ != NULL); - pp::Var resolved_url = - url_util_->ResolveRelativeToURL(pp::Var(manifest_base_url_), - relative_url); - if (!resolved_url.is_string()) { - error_info->SetReport( - PP_NACL_ERROR_MANIFEST_RESOLVE_URL, - "could not resolve url '" + relative_url + - "' relative to manifest base url '" + manifest_base_url_.c_str() + - "'."); - return false; - } - *full_url = resolved_url.AsString(); - return true; -} - -} // namespace plugin diff --git a/ppapi/native_client/src/trusted/plugin/json_manifest.h b/ppapi/native_client/src/trusted/plugin/json_manifest.h deleted file mode 100644 index cf02798..0000000 --- a/ppapi/native_client/src/trusted/plugin/json_manifest.h +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Copyright (c) 2012 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. - */ - -// Manifest processing for JSON manifests. - -#ifndef NATIVE_CLIENT_SRC_TRUSTED_PLUGIN_JSON_MANIFEST_H_ -#define NATIVE_CLIENT_SRC_TRUSTED_PLUGIN_JSON_MANIFEST_H_ - -#include <map> -#include <set> -#include <string> - -#include "native_client/src/include/nacl_macros.h" -#include "native_client/src/include/nacl_string.h" -#include "ppapi/native_client/src/trusted/plugin/manifest.h" -#include "third_party/jsoncpp/source/include/json/value.h" - -struct PP_PNaClOptions; - -namespace pp { -class URLUtil_Dev; -} // namespace pp - -namespace plugin { - -class ErrorInfo; - -class JsonManifest : public Manifest { - public: - JsonManifest(const pp::URLUtil_Dev* url_util, - const nacl::string& manifest_base_url, - const nacl::string& sandbox_isa, - bool nonsfi_enabled, - bool pnacl_debug) - : url_util_(url_util), - manifest_base_url_(manifest_base_url), - sandbox_isa_(sandbox_isa), - nonsfi_enabled_(nonsfi_enabled), - pnacl_debug_(pnacl_debug), - dictionary_(Json::nullValue) { } - virtual ~JsonManifest() { } - - // Initialize the manifest object for use by later lookups. The return - // value is true if the manifest parses correctly and matches the schema. - bool Init(const nacl::string& json, ErrorInfo* error_info); - - // Gets the full program URL for the current sandbox ISA from the - // manifest file. - virtual bool GetProgramURL(nacl::string* full_url, - PP_PNaClOptions* pnacl_options, - bool* uses_nonsfi_mode, - ErrorInfo* error_info) const; - - // Resolves a key from the "files" section to a fully resolved URL, - // i.e., relative URL values are fully expanded relative to the - // manifest's URL (via ResolveURL). - virtual bool ResolveKey(const nacl::string& key, - nacl::string* full_url, - PP_PNaClOptions* pnacl_options) const; - - private: - NACL_DISALLOW_COPY_AND_ASSIGN(JsonManifest); - - // Resolves a URL relative to the manifest base URL - bool ResolveURL(const nacl::string& relative_url, - nacl::string* full_url, - ErrorInfo* error_info) const; - - // Checks that |dictionary_| is a valid manifest, according to the schema. - // Returns true on success, and sets |error_info| to a detailed message - // if not. - bool MatchesSchema(ErrorInfo* error_info); - - bool GetKeyUrl(const Json::Value& dictionary, - const nacl::string& key, - nacl::string* full_url, - PP_PNaClOptions* pnacl_options) const; - - bool GetURLFromISADictionary(const Json::Value& dictionary, - const nacl::string& parent_key, - nacl::string* url, - PP_PNaClOptions* pnacl_options, - bool* uses_nonsfi_mode, - ErrorInfo* error_info) const; - - const pp::URLUtil_Dev* url_util_; - nacl::string manifest_base_url_; - nacl::string sandbox_isa_; - bool nonsfi_enabled_; - bool pnacl_debug_; - - Json::Value dictionary_; -}; - -} // namespace plugin - -#endif // NATIVE_CLIENT_SRC_TRUSTED_PLUGIN_JSON_MANIFEST_H_ diff --git a/ppapi/native_client/src/trusted/plugin/manifest.h b/ppapi/native_client/src/trusted/plugin/manifest.h deleted file mode 100644 index 6a74dd6..0000000 --- a/ppapi/native_client/src/trusted/plugin/manifest.h +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright (c) 2012 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. - */ - -// Manifest interface class. - -#ifndef NATIVE_CLIENT_SRC_TRUSTED_PLUGIN_MANIFEST_H_ -#define NATIVE_CLIENT_SRC_TRUSTED_PLUGIN_MANIFEST_H_ - -#include <map> -#include <set> -#include <string> - -#include "native_client/src/include/nacl_macros.h" -#include "native_client/src/include/nacl_string.h" -#include "third_party/jsoncpp/source/include/json/value.h" - -struct PP_PNaClOptions; - -namespace pp { -class URLUtil_Dev; -} // namespace pp - -namespace plugin { - -class ErrorInfo; - -class Manifest { - public: - Manifest() { } - virtual ~Manifest() { } - - // A convention in the interfaces below regarding permit_extension_url: - // Some manifests (e.g., the pnacl coordinator manifest) need to access - // resources from an extension origin distinct from the plugin's origin - // (e.g., the pnacl coordinator needs to load llc, ld, and some libraries). - // This out-parameter is true if this manifest lookup confers access to - // a resource in the extension origin. - - // Gets the full program URL for the current sandbox ISA from the - // manifest file. Fills in |pnacl_options| if the program requires - // PNaCl translation. - virtual bool GetProgramURL(nacl::string* full_url, - PP_PNaClOptions* pnacl_options, - bool* uses_nonsfi_mode, - ErrorInfo* error_info) const = 0; - - // Resolves a key from the "files" section to a fully resolved URL, - // i.e., relative URL values are fully expanded relative to the - // manifest's URL. Fills in |pnacl_options| if - // the resolved key requires a pnacl translation step to obtain - // the final requested resource. - virtual bool ResolveKey(const nacl::string& key, - nacl::string* full_url, - PP_PNaClOptions* pnacl_options) const = 0; - - protected: - NACL_DISALLOW_COPY_AND_ASSIGN(Manifest); -}; - - -} // namespace plugin - -#endif // NATIVE_CLIENT_SRC_TRUSTED_PLUGIN_MANIFEST_H_ diff --git a/ppapi/native_client/src/trusted/plugin/plugin.cc b/ppapi/native_client/src/trusted/plugin/plugin.cc index 071e534..ce2d4ba 100644 --- a/ppapi/native_client/src/trusted/plugin/plugin.cc +++ b/ppapi/native_client/src/trusted/plugin/plugin.cc @@ -34,7 +34,6 @@ #include "ppapi/cpp/dev/url_util_dev.h" #include "ppapi/cpp/module.h" -#include "ppapi/native_client/src/trusted/plugin/json_manifest.h" #include "ppapi/native_client/src/trusted/plugin/nacl_entry_points.h" #include "ppapi/native_client/src/trusted/plugin/nacl_subprocess.h" #include "ppapi/native_client/src/trusted/plugin/plugin_error.h" @@ -136,11 +135,11 @@ void Plugin::HistogramHTTPStatusCode(const std::string& name, int status) { bool Plugin::LoadNaClModuleFromBackgroundThread( nacl::DescWrapper* wrapper, NaClSubprocess* subprocess, - const Manifest* manifest, + int32_t manifest_id, const SelLdrStartParams& params) { CHECK(!pp::Module::Get()->core()->IsMainThread()); ServiceRuntime* service_runtime = - new ServiceRuntime(this, manifest, false, uses_nonsfi_mode_, + new ServiceRuntime(this, manifest_id, false, uses_nonsfi_mode_, pp::BlockUntilComplete(), pp::BlockUntilComplete()); subprocess->set_service_runtime(service_runtime); PLUGIN_PRINTF(("Plugin::LoadNaClModuleFromBackgroundThread " @@ -228,7 +227,7 @@ void Plugin::LoadNaClModule(nacl::DescWrapper* wrapper, enable_crash_throttling); ErrorInfo error_info; ServiceRuntime* service_runtime = - new ServiceRuntime(this, manifest_.get(), true, uses_nonsfi_mode, + new ServiceRuntime(this, manifest_id_, true, uses_nonsfi_mode, init_done_cb, crash_cb); main_subprocess_.set_service_runtime(service_runtime); PLUGIN_PRINTF(("Plugin::LoadNaClModule (service_runtime=%p)\n", @@ -293,7 +292,7 @@ bool Plugin::LoadNaClModuleContinuationIntern() { NaClSubprocess* Plugin::LoadHelperNaClModule(const nacl::string& helper_url, nacl::DescWrapper* wrapper, - const Manifest* manifest, + int32_t manifest_id, ErrorInfo* error_info) { nacl::scoped_ptr<NaClSubprocess> nacl_subprocess( new NaClSubprocess("helper module", NULL, NULL)); @@ -320,7 +319,7 @@ NaClSubprocess* Plugin::LoadHelperNaClModule(const nacl::string& helper_url, false /* enable_exception_handling */, true /* enable_crash_throttling */); if (!LoadNaClModuleFromBackgroundThread(wrapper, nacl_subprocess.get(), - manifest, params)) { + manifest_id, params)) { return NULL; } // We need not wait for the init_done callback. We can block @@ -370,6 +369,7 @@ Plugin::Plugin(PP_Instance pp_instance) wrapper_factory_(NULL), time_of_last_progress_event_(0), nexe_open_time_(-1), + manifest_id_(-1), nacl_interface_(NULL), uma_interface_(this) { PLUGIN_PRINTF(("Plugin::Plugin (this=%p, pp_instance=%" @@ -580,20 +580,19 @@ void Plugin::ProcessNaClManifest(const nacl::string& manifest_json) { if (!SetManifestObject(manifest_json)) return; - nacl::string program_url; + PP_Var pp_program_url; PP_PNaClOptions pnacl_options = {PP_FALSE, PP_FALSE, 2}; - bool uses_nonsfi_mode; - ErrorInfo error_info; - if (manifest_->GetProgramURL( - &program_url, &pnacl_options, &uses_nonsfi_mode, &error_info)) { + PP_Bool uses_nonsfi_mode; + if (nacl_interface_->GetManifestProgramURL(pp_instance(), + manifest_id_, &pp_program_url, &pnacl_options, &uses_nonsfi_mode)) { + std::string program_url = pp::Var(pp::PASS_REF, pp_program_url).AsString(); // TODO(teravest): Make ProcessNaClManifest take responsibility for more of // this function. nacl_interface_->ProcessNaClManifest(pp_instance(), program_url.c_str()); - uses_nonsfi_mode_ = uses_nonsfi_mode; + uses_nonsfi_mode_ = PP_ToBool(uses_nonsfi_mode); if (pnacl_options.translate) { pp::CompletionCallback translate_callback = callback_factory_.NewCallback(&Plugin::BitcodeDidTranslate); - // Will always call the callback on success or failure. pnacl_coordinator_.reset( PnaclCoordinator::BitcodeToNative(this, program_url, @@ -619,8 +618,6 @@ void Plugin::ProcessNaClManifest(const nacl::string& manifest_json) { return; } } - // Failed to select the program and/or the translator. - ReportLoadError(error_info); } void Plugin::RequestNaClManifest(const nacl::string& url) { @@ -663,30 +660,22 @@ void Plugin::RequestNaClManifest(const nacl::string& url) { bool Plugin::SetManifestObject(const nacl::string& manifest_json) { PLUGIN_PRINTF(("Plugin::SetManifestObject(): manifest_json='%s'.\n", manifest_json.c_str())); - ErrorInfo error_info; - // Determine whether lookups should use portable (i.e., pnacl versions) // rather than platform-specific files. bool is_pnacl = nacl_interface_->IsPNaCl(pp_instance()); - bool nonsfi_mode_enabled = - PP_ToBool(nacl_interface_->IsNonSFIModeEnabled()); pp::Var manifest_base_url = pp::Var(pp::PASS_REF, nacl_interface_->GetManifestBaseURL(pp_instance())); std::string manifest_base_url_str = manifest_base_url.AsString(); - bool pnacl_debug = GetNaClInterface()->NaClDebugEnabledForURL( - manifest_base_url_str.c_str()); const char* sandbox_isa = nacl_interface_->GetSandboxArch(); - nacl::scoped_ptr<JsonManifest> json_manifest( - new JsonManifest(pp::URLUtil_Dev::Get(), - manifest_base_url_str, - (is_pnacl ? kPortableArch : sandbox_isa), - nonsfi_mode_enabled, - pnacl_debug)); - if (!json_manifest->Init(manifest_json, &error_info)) { - ReportLoadError(error_info); + + int32_t manifest_id = nacl_interface_->CreateJsonManifest( + pp_instance(), + manifest_base_url_str.c_str(), + is_pnacl ? kPortableArch : sandbox_isa, + manifest_json.c_str()); + if (manifest_id == -1) return false; - } - manifest_.reset(json_manifest.release()); + manifest_id_ = manifest_id; return true; } diff --git a/ppapi/native_client/src/trusted/plugin/plugin.gypi b/ppapi/native_client/src/trusted/plugin/plugin.gypi index d9de561..15e2d19 100644 --- a/ppapi/native_client/src/trusted/plugin/plugin.gypi +++ b/ppapi/native_client/src/trusted/plugin/plugin.gypi @@ -8,7 +8,6 @@ 'common_sources': [ 'file_downloader.cc', 'file_utils.cc', - 'json_manifest.cc', 'module_ppapi.cc', 'nacl_subprocess.cc', 'plugin.cc', diff --git a/ppapi/native_client/src/trusted/plugin/plugin.h b/ppapi/native_client/src/trusted/plugin/plugin.h index c573bd2..1978be7 100644 --- a/ppapi/native_client/src/trusted/plugin/plugin.h +++ b/ppapi/native_client/src/trusted/plugin/plugin.h @@ -111,7 +111,7 @@ class Plugin : public pp::Instance { // Returns NULL or the NaClSubprocess of the new helper NaCl module. NaClSubprocess* LoadHelperNaClModule(const nacl::string& helper_url, nacl::DescWrapper* wrapper, - const Manifest* manifest, + int32_t manifest_id, ErrorInfo* error_info); enum LengthComputable { @@ -164,8 +164,6 @@ class Plugin : public pp::Instance { // document to request the URL using CORS even if this function returns false. bool DocumentCanRequest(const std::string& url); - Manifest const* manifest() const { return manifest_.get(); } - // set_exit_status may be called off the main thread. void set_exit_status(int exit_status); @@ -206,7 +204,7 @@ class Plugin : public pp::Instance { // This will fully initialize the |subprocess| if the load was successful. bool LoadNaClModuleFromBackgroundThread(nacl::DescWrapper* wrapper, NaClSubprocess* subprocess, - const Manifest* manifest, + int32_t manifest_id, const SelLdrStartParams& params); // Start sel_ldr from the main thread, given the start params. @@ -304,9 +302,6 @@ class Plugin : public pp::Instance { nacl::scoped_ptr<PnaclCoordinator> pnacl_coordinator_; - // The manifest dictionary. Used for looking up resources to be loaded. - nacl::scoped_ptr<Manifest> manifest_; - // Keep track of the FileDownloaders created to fetch urls. std::set<FileDownloader*> url_downloaders_; // Keep track of file descriptors opened by StreamAsFile(). @@ -334,6 +329,7 @@ class Plugin : public pp::Instance { int64_t nexe_open_time_; PP_Var manifest_data_var_; + int32_t manifest_id_; const PPB_NaCl_Private* nacl_interface_; pp::UMAPrivate uma_interface_; diff --git a/ppapi/native_client/src/trusted/plugin/pnacl_coordinator.cc b/ppapi/native_client/src/trusted/plugin/pnacl_coordinator.cc index 93d2220..626536a 100644 --- a/ppapi/native_client/src/trusted/plugin/pnacl_coordinator.cc +++ b/ppapi/native_client/src/trusted/plugin/pnacl_coordinator.cc @@ -16,7 +16,6 @@ #include "ppapi/c/pp_errors.h" #include "ppapi/c/private/ppb_uma_private.h" -#include "ppapi/native_client/src/trusted/plugin/manifest.h" #include "ppapi/native_client/src/trusted/plugin/plugin.h" #include "ppapi/native_client/src/trusted/plugin/plugin_error.h" #include "ppapi/native_client/src/trusted/plugin/pnacl_translate_thread.h" @@ -26,62 +25,6 @@ namespace plugin { ////////////////////////////////////////////////////////////////////// -// Pnacl-specific manifest support. -////////////////////////////////////////////////////////////////////// - -// The PNaCl linker gets file descriptors via the service runtime's -// reverse service lookup. The reverse service lookup requires a manifest. -// Normally, that manifest is an NMF containing mappings for shared libraries. -// Here, we provide a manifest that redirects to PNaCl component files -// that are part of Chrome. -class PnaclManifest : public Manifest { - public: - PnaclManifest(const nacl::string& sandbox_arch) - : sandbox_arch_(sandbox_arch) { } - - virtual ~PnaclManifest() { } - - virtual bool GetProgramURL(nacl::string* full_url, - PP_PNaClOptions* pnacl_options, - bool* uses_nonsfi_mode, - ErrorInfo* error_info) const { - // Does not contain program urls. - UNREFERENCED_PARAMETER(full_url); - UNREFERENCED_PARAMETER(pnacl_options); - UNREFERENCED_PARAMETER(uses_nonsfi_mode); - UNREFERENCED_PARAMETER(error_info); - PLUGIN_PRINTF(("PnaclManifest does not contain a program\n")); - error_info->SetReport(PP_NACL_ERROR_MANIFEST_GET_NEXE_URL, - "pnacl manifest does not contain a program."); - return false; - } - - virtual bool ResolveKey(const nacl::string& key, - nacl::string* full_url, - PP_PNaClOptions* pnacl_options) const { - // All of the component files are native (do not require pnacl translate). - pnacl_options->translate = PP_FALSE; - // We can only resolve keys in the files/ namespace. - const nacl::string kFilesPrefix = "files/"; - size_t files_prefix_pos = key.find(kFilesPrefix); - if (files_prefix_pos == nacl::string::npos) { - PLUGIN_PRINTF(("key did not start with files/")); - return false; - } - // Resolve the full URL to the file. Provide it with a platform-specific - // prefix. - nacl::string key_basename = key.substr(kFilesPrefix.length()); - *full_url = PnaclUrls::GetBaseUrl() + sandbox_arch_ + "/" + key_basename; - return true; - } - - private: - NACL_DISALLOW_COPY_AND_ASSIGN(PnaclManifest); - - nacl::string sandbox_arch_; -}; - -////////////////////////////////////////////////////////////////////// // UMA stat helpers. ////////////////////////////////////////////////////////////////////// @@ -180,10 +123,10 @@ PnaclCoordinator* PnaclCoordinator::BitcodeToNative( new PnaclCoordinator(plugin, pexe_url, pnacl_options, translate_notify_callback); - coordinator->pnacl_init_time_ = NaClGetTimeOfDayMicroseconds(); - PLUGIN_PRINTF(("PnaclCoordinator::BitcodeToNative (manifest=%p, ", - reinterpret_cast<const void*>(coordinator->manifest_.get()))); + PLUGIN_PRINTF(("PnaclCoordinator::BitcodeToNative (manifest_id=%d)\n", + coordinator->manifest_id_)); + coordinator->pnacl_init_time_ = NaClGetTimeOfDayMicroseconds(); int cpus = plugin->nacl_interface()->GetNumberOfProcessors(); coordinator->split_module_count_ = std::min(4, std::max(1, cpus)); @@ -204,7 +147,8 @@ PnaclCoordinator::PnaclCoordinator( plugin_(plugin), translate_notify_callback_(translate_notify_callback), translation_finished_reported_(false), - manifest_(new PnaclManifest(plugin->nacl_interface()->GetSandboxArch())), + manifest_id_( + GetNaClInterface()->CreatePnaclManifest(plugin->pp_instance())), pexe_url_(pexe_url), pnacl_options_(pnacl_options), split_module_count_(1), @@ -668,7 +612,7 @@ void PnaclCoordinator::RunTranslate(int32_t pp_error) { CHECK(translate_thread_ != NULL); translate_thread_->RunTranslate(report_translate_finished, - manifest_.get(), + manifest_id_, &obj_files_, temp_nexe_file_.get(), invalid_desc_wrapper_.get(), diff --git a/ppapi/native_client/src/trusted/plugin/pnacl_coordinator.h b/ppapi/native_client/src/trusted/plugin/pnacl_coordinator.h index 99d6e70..954bb09 100644 --- a/ppapi/native_client/src/trusted/plugin/pnacl_coordinator.h +++ b/ppapi/native_client/src/trusted/plugin/pnacl_coordinator.h @@ -27,7 +27,6 @@ struct PP_PNaClOptions; namespace plugin { -class Manifest; class Plugin; class PnaclCoordinator; class PnaclTranslateThread; @@ -204,7 +203,7 @@ class PnaclCoordinator: public CallbackSource<FileStreamData> { // The manifest used by resource loading and ld + llc's reverse service // to look up objects and libraries. - nacl::scoped_ptr<const Manifest> manifest_; + int32_t manifest_id_; // An auxiliary class that manages downloaded resources (llc and ld nexes). nacl::scoped_ptr<PnaclResources> resources_; diff --git a/ppapi/native_client/src/trusted/plugin/pnacl_resources.cc b/ppapi/native_client/src/trusted/plugin/pnacl_resources.cc index 160066b..747d147 100644 --- a/ppapi/native_client/src/trusted/plugin/pnacl_resources.cc +++ b/ppapi/native_client/src/trusted/plugin/pnacl_resources.cc @@ -9,7 +9,6 @@ #include "native_client/src/trusted/desc/nacl_desc_wrapper.h" #include "ppapi/c/pp_errors.h" #include "ppapi/native_client/src/trusted/plugin/file_utils.h" -#include "ppapi/native_client/src/trusted/plugin/manifest.h" #include "ppapi/native_client/src/trusted/plugin/plugin.h" #include "ppapi/native_client/src/trusted/plugin/pnacl_coordinator.h" #include "ppapi/native_client/src/trusted/plugin/utility.h" 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 10f01bb..947bf1c7 100644 --- a/ppapi/native_client/src/trusted/plugin/pnacl_translate_thread.cc +++ b/ppapi/native_client/src/trusted/plugin/pnacl_translate_thread.cc @@ -39,7 +39,7 @@ PnaclTranslateThread::PnaclTranslateThread() : llc_subprocess_active_(false), ld_subprocess_active_(false), done_(false), compile_time_(0), - manifest_(NULL), + manifest_id_(0), obj_files_(NULL), nexe_file_(NULL), coordinator_error_info_(NULL), @@ -53,7 +53,7 @@ PnaclTranslateThread::PnaclTranslateThread() : llc_subprocess_active_(false), void PnaclTranslateThread::RunTranslate( const pp::CompletionCallback& finish_callback, - const Manifest* manifest, + int32_t manifest_id, const std::vector<TempFile*>* obj_files, TempFile* nexe_file, nacl::DescWrapper* invalid_desc_wrapper, @@ -63,7 +63,7 @@ void PnaclTranslateThread::RunTranslate( PnaclCoordinator* coordinator, Plugin* plugin) { PLUGIN_PRINTF(("PnaclStreamingTranslateThread::RunTranslate)\n")); - manifest_ = manifest; + manifest_id_ = manifest_id; obj_files_ = obj_files; nexe_file_ = nexe_file; invalid_desc_wrapper_ = invalid_desc_wrapper; @@ -129,7 +129,7 @@ void PnaclTranslateThread::PutBytes(std::vector<char>* bytes, NaClSubprocess* PnaclTranslateThread::StartSubprocess( const nacl::string& url_for_nexe, - const Manifest* manifest, + int32_t manifest_id, ErrorInfo* error_info) { PLUGIN_PRINTF(("PnaclTranslateThread::StartSubprocess (url_for_nexe=%s)\n", url_for_nexe.c_str())); @@ -140,8 +140,8 @@ NaClSubprocess* PnaclTranslateThread::StartSubprocess( // string gets silently dropped by GURL. nacl::string full_url = resources_->GetFullUrl( url_for_nexe, plugin_->nacl_interface()->GetSandboxArch()); - nacl::scoped_ptr<NaClSubprocess> subprocess( - plugin_->LoadHelperNaClModule(full_url, wrapper, manifest, error_info)); + nacl::scoped_ptr<NaClSubprocess> subprocess(plugin_->LoadHelperNaClModule( + full_url, wrapper, manifest_id, error_info)); if (subprocess.get() == NULL) { PLUGIN_PRINTF(( "PnaclTranslateThread::StartSubprocess: subprocess creation failed\n")); @@ -173,7 +173,7 @@ void PnaclTranslateThread::DoTranslate() { nacl::MutexLocker ml(&subprocess_mu_); int64_t llc_start_time = NaClGetTimeOfDayMicroseconds(); llc_subprocess_.reset( - StartSubprocess(resources_->GetLlcUrl(), manifest_, &error_info)); + StartSubprocess(resources_->GetLlcUrl(), manifest_id_, &error_info)); if (llc_subprocess_ == NULL) { TranslateFailed(PP_NACL_ERROR_PNACL_LLC_SETUP, "Compile process could not be created: " + @@ -350,7 +350,7 @@ bool PnaclTranslateThread::RunLdSubprocess() { nacl::MutexLocker ml(&subprocess_mu_); int64_t ld_start_time = NaClGetTimeOfDayMicroseconds(); ld_subprocess_.reset( - StartSubprocess(resources_->GetLdUrl(), manifest_, &error_info)); + StartSubprocess(resources_->GetLdUrl(), manifest_id_, &error_info)); if (ld_subprocess_ == NULL) { TranslateFailed(PP_NACL_ERROR_PNACL_LD_SETUP, "Link process could not be created: " + diff --git a/ppapi/native_client/src/trusted/plugin/pnacl_translate_thread.h b/ppapi/native_client/src/trusted/plugin/pnacl_translate_thread.h index db1dbf0..84ce392 100644 --- a/ppapi/native_client/src/trusted/plugin/pnacl_translate_thread.h +++ b/ppapi/native_client/src/trusted/plugin/pnacl_translate_thread.h @@ -28,7 +28,6 @@ class DescWrapper; namespace plugin { -class Manifest; class NaClSubprocess; class Plugin; class PnaclCoordinator; @@ -43,7 +42,7 @@ class PnaclTranslateThread { // Start the translation process. It will continue to run and consume data // as it is passed in with PutBytes. void RunTranslate(const pp::CompletionCallback& finish_callback, - const Manifest* manifest, + int32_t manifest_id, const std::vector<TempFile*>* obj_files, TempFile* nexe_file, nacl::DescWrapper* invalid_desc_wrapper, @@ -69,7 +68,7 @@ class PnaclTranslateThread { private: // Starts an individual llc or ld subprocess used for translation. NaClSubprocess* StartSubprocess(const nacl::string& url, - const Manifest* manifest, + int32_t manifest_id, ErrorInfo* error_info); // Helper thread entry point for translation. Takes a pointer to // PnaclTranslateThread and calls DoTranslate(). @@ -114,7 +113,7 @@ class PnaclTranslateThread { int64_t compile_time_; // Data about the translation files, owned by the coordinator - const Manifest* manifest_; + int32_t manifest_id_; const std::vector<TempFile*>* obj_files_; TempFile* nexe_file_; nacl::DescWrapper* invalid_desc_wrapper_; diff --git a/ppapi/native_client/src/trusted/plugin/service_runtime.cc b/ppapi/native_client/src/trusted/plugin/service_runtime.cc index d7c8683..c3a7f94 100644 --- a/ppapi/native_client/src/trusted/plugin/service_runtime.cc +++ b/ppapi/native_client/src/trusted/plugin/service_runtime.cc @@ -47,7 +47,6 @@ #include "ppapi/cpp/core.h" #include "ppapi/cpp/completion_callback.h" -#include "ppapi/native_client/src/trusted/plugin/manifest.h" #include "ppapi/native_client/src/trusted/plugin/plugin.h" #include "ppapi/native_client/src/trusted/plugin/plugin_error.h" #include "ppapi/native_client/src/trusted/plugin/pnacl_resources.h" @@ -198,13 +197,13 @@ void OpenManifestEntryResource::MaybeRunCallback(int32_t pp_error) { PluginReverseInterface::PluginReverseInterface( nacl::WeakRefAnchor* anchor, Plugin* plugin, - const Manifest* manifest, + int32_t manifest_id, ServiceRuntime* service_runtime, pp::CompletionCallback init_done_cb, pp::CompletionCallback crash_cb) : anchor_(anchor), plugin_(plugin), - manifest_(manifest), + manifest_id_(manifest_id), service_runtime_(service_runtime), shutting_down_(false), init_done_cb_(init_done_cb), @@ -347,9 +346,13 @@ void PluginReverseInterface::OpenManifestEntry_MainThreadContinuation( NaClLog(4, "Entered OpenManifestEntry_MainThreadContinuation\n"); - std::string mapped_url; + PP_Var pp_mapped_url; PP_PNaClOptions pnacl_options = {PP_FALSE, PP_FALSE, 2}; - if (!manifest_->ResolveKey(p->url, &mapped_url, &pnacl_options)) { + if (!GetNaClInterface()->ManifestResolveKey(plugin_->pp_instance(), + manifest_id_, + p->url.c_str(), + &pp_mapped_url, + &pnacl_options)) { NaClLog(4, "OpenManifestEntry_MainThreadContinuation: ResolveKey failed\n"); // Failed, and error_info has the details on what happened. Wake // up requesting thread -- we are done. @@ -362,6 +365,7 @@ void PluginReverseInterface::OpenManifestEntry_MainThreadContinuation( p->MaybeRunCallback(PP_OK); return; } + nacl::string mapped_url = pp::Var(pp_mapped_url).AsString(); NaClLog(4, "OpenManifestEntry_MainThreadContinuation: " "ResolveKey: %s -> %s (pnacl_translate(%d))\n", @@ -560,7 +564,7 @@ void PluginReverseInterface::AddTempQuotaManagedFile( } ServiceRuntime::ServiceRuntime(Plugin* plugin, - const Manifest* manifest, + int32_t manifest_id, bool main_service_runtime, bool uses_nonsfi_mode, pp::CompletionCallback init_done_cb, @@ -571,7 +575,7 @@ ServiceRuntime::ServiceRuntime(Plugin* plugin, reverse_service_(NULL), anchor_(new nacl::WeakRefAnchor()), rev_interface_(new PluginReverseInterface(anchor_, plugin, - manifest, + manifest_id, this, init_done_cb, crash_cb)), exit_status_(-1), diff --git a/ppapi/native_client/src/trusted/plugin/service_runtime.h b/ppapi/native_client/src/trusted/plugin/service_runtime.h index ca12764..74dc68d 100644 --- a/ppapi/native_client/src/trusted/plugin/service_runtime.h +++ b/ppapi/native_client/src/trusted/plugin/service_runtime.h @@ -40,7 +40,6 @@ class FileIO; namespace plugin { class ErrorInfo; -class Manifest; class OpenManifestEntryAsyncCallback; class Plugin; class SrpcClient; @@ -147,7 +146,7 @@ class PluginReverseInterface: public nacl::ReverseInterface { public: PluginReverseInterface(nacl::WeakRefAnchor* anchor, Plugin* plugin, - const Manifest* manifest, + int32_t manifest_id, ServiceRuntime* service_runtime, pp::CompletionCallback init_done_cb, pp::CompletionCallback crash_cb); @@ -206,7 +205,7 @@ class PluginReverseInterface: public nacl::ReverseInterface { nacl::WeakRefAnchor* anchor_; // holds a ref Plugin* plugin_; // value may be copied, but should be used only in // main thread in WeakRef-protected callbacks. - const Manifest* manifest_; + int32_t manifest_id_; ServiceRuntime* service_runtime_; NaClMutex mu_; NaClCondVar cv_; @@ -223,7 +222,7 @@ class ServiceRuntime { // TODO(sehr): This class should also implement factory methods, using the // Start method below. ServiceRuntime(Plugin* plugin, - const Manifest* manifest, + int32_t manifest_id, bool main_service_runtime, bool uses_nonsfi_mode, pp::CompletionCallback init_done_cb, 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 4713148..7005c05 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 @@ -3281,6 +3281,31 @@ static void Pnacl_M25_PPB_NaCl_Private_DownloadManifestToBuffer(PP_Instance inst iface->DownloadManifestToBuffer(instance, data, *callback); } +static int32_t Pnacl_M25_PPB_NaCl_Private_CreatePnaclManifest(PP_Instance instance) { + const struct PPB_NaCl_Private_1_0 *iface = Pnacl_WrapperInfo_PPB_NaCl_Private_1_0.real_iface; + return iface->CreatePnaclManifest(instance); +} + +static int32_t Pnacl_M25_PPB_NaCl_Private_CreateJsonManifest(PP_Instance instance, const char* manifest_base_url, const char* sandbox_isa, const char* manifest_data) { + const struct PPB_NaCl_Private_1_0 *iface = Pnacl_WrapperInfo_PPB_NaCl_Private_1_0.real_iface; + return iface->CreateJsonManifest(instance, manifest_base_url, sandbox_isa, manifest_data); +} + +static void Pnacl_M25_PPB_NaCl_Private_DestroyManifest(PP_Instance instance, int32_t manifest_id) { + const struct PPB_NaCl_Private_1_0 *iface = Pnacl_WrapperInfo_PPB_NaCl_Private_1_0.real_iface; + iface->DestroyManifest(instance, manifest_id); +} + +static PP_Bool Pnacl_M25_PPB_NaCl_Private_GetManifestProgramURL(PP_Instance instance, int32_t manifest_id, struct PP_Var* full_url, struct PP_PNaClOptions* pnacl_options, PP_Bool* uses_nonsfi_mode) { + const struct PPB_NaCl_Private_1_0 *iface = Pnacl_WrapperInfo_PPB_NaCl_Private_1_0.real_iface; + return iface->GetManifestProgramURL(instance, manifest_id, full_url, pnacl_options, uses_nonsfi_mode); +} + +static PP_Bool Pnacl_M25_PPB_NaCl_Private_ManifestResolveKey(PP_Instance instance, int32_t manifest_id, const char* key, struct PP_Var* full_url, struct PP_PNaClOptions* pnacl_options) { + const struct PPB_NaCl_Private_1_0 *iface = Pnacl_WrapperInfo_PPB_NaCl_Private_1_0.real_iface; + return iface->ManifestResolveKey(instance, manifest_id, key, full_url, pnacl_options); +} + /* End wrapper methods for PPB_NaCl_Private_1_0 */ /* Begin wrapper methods for PPB_NetAddress_Private_0_1 */ @@ -5012,7 +5037,12 @@ static const struct PPB_NaCl_Private_1_0 Pnacl_Wrappers_PPB_NaCl_Private_1_0 = { .GetManifestURLArgument = (struct PP_Var (*)(PP_Instance instance))&Pnacl_M25_PPB_NaCl_Private_GetManifestURLArgument, .IsPNaCl = (PP_Bool (*)(PP_Instance instance))&Pnacl_M25_PPB_NaCl_Private_IsPNaCl, .DevInterfacesEnabled = (PP_Bool (*)(PP_Instance instance))&Pnacl_M25_PPB_NaCl_Private_DevInterfacesEnabled, - .DownloadManifestToBuffer = (void (*)(PP_Instance instance, struct PP_Var* data, struct PP_CompletionCallback callback))&Pnacl_M25_PPB_NaCl_Private_DownloadManifestToBuffer + .DownloadManifestToBuffer = (void (*)(PP_Instance instance, struct PP_Var* data, struct PP_CompletionCallback callback))&Pnacl_M25_PPB_NaCl_Private_DownloadManifestToBuffer, + .CreatePnaclManifest = (int32_t (*)(PP_Instance instance))&Pnacl_M25_PPB_NaCl_Private_CreatePnaclManifest, + .CreateJsonManifest = (int32_t (*)(PP_Instance instance, const char* manifest_base_url, const char* sandbox_isa, const char* manifest_data))&Pnacl_M25_PPB_NaCl_Private_CreateJsonManifest, + .DestroyManifest = (void (*)(PP_Instance instance, int32_t manifest_id))&Pnacl_M25_PPB_NaCl_Private_DestroyManifest, + .GetManifestProgramURL = (PP_Bool (*)(PP_Instance instance, int32_t manifest_id, struct PP_Var* full_url, struct PP_PNaClOptions* pnacl_options, PP_Bool* uses_nonsfi_mode))&Pnacl_M25_PPB_NaCl_Private_GetManifestProgramURL, + .ManifestResolveKey = (PP_Bool (*)(PP_Instance instance, int32_t manifest_id, const char* key, struct PP_Var* full_url, struct PP_PNaClOptions* pnacl_options))&Pnacl_M25_PPB_NaCl_Private_ManifestResolveKey }; static const struct PPB_NetAddress_Private_0_1 Pnacl_Wrappers_PPB_NetAddress_Private_0_1 = { |