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 |