| OLD | NEW |
| (Empty) |
| 1 /* | |
| 2 * Copyright 2010 The Native Client Authors. All rights reserved. | |
| 3 * Use of this source code is governed by a BSD-style license that can | |
| 4 * be found in the LICENSE file. | |
| 5 */ | |
| 6 | |
| 7 #include "native_client/src/trusted/plugin/srpc/nexe_arch.h" | |
| 8 | |
| 9 #include <stdio.h> | |
| 10 | |
| 11 #include "native_client/src/include/portability.h" | |
| 12 #include "native_client/src/trusted/platform_qualify/nacl_os_qualify.h" | |
| 13 #include "native_client/src/trusted/plugin/srpc/utility.h" | |
| 14 | |
| 15 namespace plugin { | |
| 16 | |
| 17 // Returns the kind of SFI sandbox implemented by sel_ldr on this | |
| 18 // platform: ARM, x86-32, x86-64. | |
| 19 // | |
| 20 // This is a function of the current CPU, OS, browser, installed | |
| 21 // sel_ldr(s). It is not sufficient to derive the result only from | |
| 22 // build-time parameters since, for example, an x86-32 plugin is | |
| 23 // capable of launching a 64-bit NaCl sandbox if a 64-bit sel_ldr is | |
| 24 // installed (and indeed, may only be capable of launching a 64-bit | |
| 25 // sandbox). | |
| 26 // | |
| 27 // TODO(adonovan): this function changes over time as we deploy | |
| 28 // different things. It should be defined once, authoritatively, | |
| 29 // instead of guessed at where it's needed, e.g. here. | |
| 30 static nacl::string GetSandbox(); | |
| 31 | |
| 32 #if NACL_ARCH_CPU_X86_FAMILY | |
| 33 | |
| 34 static nacl::string GetSandbox() { | |
| 35 #if !defined(NACL_STANDALONE) && NACL_ARCH_CPU_X86_64 && NACL_LINUX | |
| 36 return "x86-64"; // 64-bit Chrome on Linux | |
| 37 #else | |
| 38 return NaClOsIs64BitWindows() == 1 | |
| 39 ? "x86-64" // 64-bit Windows (Chrome, Firefox) | |
| 40 : "x86-32"; // everything else. | |
| 41 #endif | |
| 42 } | |
| 43 | |
| 44 #elif NACL_ARCH_CPU_ARM_FAMILY | |
| 45 | |
| 46 static nacl::string GetSandbox() { return "ARM"; } | |
| 47 | |
| 48 #else /* hopefully unreachable */ | |
| 49 | |
| 50 #error GetSandbox() missing on this platform | |
| 51 | |
| 52 #endif | |
| 53 | |
| 54 // Removes leading and trailing ASCII whitespace from |*s|. | |
| 55 static nacl::string TrimWhitespace(const nacl::string& s) { | |
| 56 size_t start = s.find_first_not_of(" \t"); | |
| 57 size_t end = s.find_last_not_of(" \t"); | |
| 58 return start == nacl::string::npos | |
| 59 ? "" | |
| 60 : s.substr(start, end + 1 - start); | |
| 61 } | |
| 62 | |
| 63 // Parse one line of the nexes attribute. | |
| 64 // Returns true iff it's a match, and writes URL to |*url|. | |
| 65 static bool ParseOneNexeLine(const nacl::string& nexe_line, | |
| 66 const nacl::string& sandbox, | |
| 67 nacl::string* url) { | |
| 68 size_t semi = nexe_line.find(':'); | |
| 69 if (semi == nacl::string::npos) { | |
| 70 PLUGIN_PRINTF(("missing colon in line of 'nexes' attribute")); | |
| 71 return false; | |
| 72 } | |
| 73 nacl::string attr_sandbox = TrimWhitespace(nexe_line.substr(0, semi)); | |
| 74 nacl::string attr_url = TrimWhitespace(nexe_line.substr(semi + 1)); | |
| 75 bool match = sandbox == attr_sandbox; | |
| 76 PLUGIN_PRINTF(("ParseOneNexeLine %s %s: match=%d\n", | |
| 77 attr_sandbox.c_str(), | |
| 78 attr_url.c_str(), | |
| 79 match)); | |
| 80 if (match) *url = attr_url; | |
| 81 return match; | |
| 82 } | |
| 83 | |
| 84 // Parses an <embed nexes='...'> attribute and returns the URL of the | |
| 85 // nexe matching |sandbox|. Returns true and assigns |*result| to the | |
| 86 // URL on success; otherwise returns false. | |
| 87 // | |
| 88 // nexes ::= <nexe-line> ( '\n' <nexes> )* | |
| 89 // nexe-line ::= <sandbox> ':' <nexe-url> | |
| 90 // | |
| 91 // Spaces surrounding <sandbox> and <nexe-url> are ignored, but | |
| 92 // <nexe-url> may contain internal spaces. | |
| 93 static bool FindNexeForSandbox(const nacl::string& nexes_attr, | |
| 94 const nacl::string& sandbox, | |
| 95 nacl::string* url) { | |
| 96 size_t pos, oldpos; | |
| 97 for (oldpos = 0, pos = nexes_attr.find('\n', oldpos); | |
| 98 pos != nacl::string::npos; | |
| 99 oldpos = pos + 1, pos = nexes_attr.find('\n', oldpos)) { | |
| 100 if (ParseOneNexeLine(nexes_attr.substr(oldpos, pos - oldpos), sandbox, | |
| 101 url)) { | |
| 102 return true; | |
| 103 } | |
| 104 } | |
| 105 if (oldpos < nexes_attr.size() - 1) { /* attr doesn't end in newline */ | |
| 106 if (ParseOneNexeLine(nexes_attr.substr(oldpos), sandbox, url)) return true; | |
| 107 } | |
| 108 return false; | |
| 109 } | |
| 110 | |
| 111 // See nexe_arch.h. | |
| 112 // An entry point for testing. | |
| 113 bool GetNexeURL(const char* nexes_attr, nacl::string* result) { | |
| 114 const nacl::string sandbox = GetSandbox(); | |
| 115 PLUGIN_PRINTF(("GetNexeURL(): sandbox='%s' nexes='%s'.\n", | |
| 116 sandbox.c_str(), nexes_attr)); | |
| 117 if (FindNexeForSandbox(nexes_attr, sandbox, result)) return true; | |
| 118 *result = "No Native Client executable was provided for the " + sandbox | |
| 119 + " sandbox."; | |
| 120 return false; | |
| 121 } | |
| 122 | |
| 123 } // namespace plugin | |
| OLD | NEW |