2 * Copyright (c) 2012 The Native Client Authors. All rights reserved.
3 * Use of this source code is governed by a BSD-style license that can be
4 * found in the LICENSE file.
9 #include "native_client/src/include/nacl_compiler_annotations.h"
10 #include "native_client/src/include/nacl_macros.h"
11 #include "native_client/src/public/irt_core.h"
12 #include "native_client/src/trusted/service_runtime/include/sys/unistd.h"
13 #include "native_client/src/untrusted/irt/irt.h"
14 #include "native_client/src/untrusted/irt/irt_dev.h"
15 #include "native_client/src/untrusted/irt/irt_interfaces.h"
16 #include "native_client/src/untrusted/nacl/syscall_bindings_trampoline.h"
18 static int file_access_filter(void) {
19 static int nacl_file_access_enabled = -1;
20 if (NACL_UNLIKELY(-1 == nacl_file_access_enabled)) {
21 NACL_SYSCALL(sysconf)(NACL_ABI__SC_NACL_FILE_ACCESS_ENABLED,
22 &nacl_file_access_enabled);
24 return nacl_file_access_enabled;
27 static int list_mappings_filter(void) {
28 static int nacl_list_mappings_enabled = -1;
29 if (NACL_UNLIKELY(-1 == nacl_list_mappings_enabled)) {
30 NACL_SYSCALL(sysconf)(NACL_ABI__SC_NACL_LIST_MAPPINGS_ENABLED,
31 &nacl_list_mappings_enabled);
33 return nacl_list_mappings_enabled;
36 static int non_pnacl_filter(void) {
37 static int pnacl_mode = -1;
38 if (NACL_UNLIKELY(-1 == pnacl_mode)) {
39 NACL_SYSCALL(sysconf)(NACL_ABI__SC_NACL_PNACL_MODE, &pnacl_mode);
44 static const struct nacl_irt_interface irt_interfaces[] = {
45 { NACL_IRT_BASIC_v0_1, &nacl_irt_basic, sizeof(nacl_irt_basic), NULL },
47 * "irt-fdio" is disabled under PNaCl because file descriptors in
48 * general are not exposed in PNaCl's in-browser ABI (since
49 * open_resource() is also disabled under PNaCl). "irt-fdio" is
50 * only exposed under PNaCl via the "dev" query string since writing
51 * to stdout/stderr is useful for debugging.
53 { NACL_IRT_FDIO_v0_1, &nacl_irt_fdio, sizeof(nacl_irt_fdio),
55 { NACL_IRT_DEV_FDIO_v0_1, &nacl_irt_fdio, sizeof(nacl_irt_fdio), NULL },
56 { NACL_IRT_DEV_FDIO_v0_3, &nacl_irt_dev_fdio, sizeof(nacl_irt_dev_fdio),
59 * "irt-filename" is made available to non-PNaCl NaCl apps only for
60 * compatibility, because existing nexes abort on startup if
61 * "irt-filename" is not available.
63 { NACL_IRT_FILENAME_v0_1, &nacl_irt_filename, sizeof(nacl_irt_filename),
65 { NACL_IRT_DEV_FILENAME_v0_2, &nacl_irt_dev_filename_v0_2,
66 sizeof(nacl_irt_dev_filename_v0_2), file_access_filter },
67 { NACL_IRT_DEV_FILENAME_v0_3, &nacl_irt_dev_filename,
68 sizeof(nacl_irt_dev_filename), file_access_filter },
70 * The old versions of "irt-memory", v0.1 and v0.2, which contain
71 * the deprecated sysbrk() function, are disabled under PNaCl. See:
72 * https://code.google.com/p/nativeclient/issues/detail?id=3542
74 { NACL_IRT_MEMORY_v0_1, &nacl_irt_memory_v0_1, sizeof(nacl_irt_memory_v0_1),
76 { NACL_IRT_MEMORY_v0_2, &nacl_irt_memory_v0_2, sizeof(nacl_irt_memory_v0_2),
78 { NACL_IRT_MEMORY_v0_3, &nacl_irt_memory, sizeof(nacl_irt_memory), NULL },
80 * "irt-dyncode" is not supported under PNaCl because dynamically
81 * loading architecture-specific native code is not portable.
83 { NACL_IRT_DYNCODE_v0_1, &nacl_irt_dyncode, sizeof(nacl_irt_dyncode),
85 { NACL_IRT_THREAD_v0_1, &nacl_irt_thread, sizeof(nacl_irt_thread), NULL },
86 { NACL_IRT_FUTEX_v0_1, &nacl_irt_futex, sizeof(nacl_irt_futex), NULL },
88 * "irt-mutex", "irt-cond" and "irt-sem" are deprecated and
89 * superseded by the "irt-futex" interface, and so are disabled
91 * https://code.google.com/p/nativeclient/issues/detail?id=3484
93 { NACL_IRT_MUTEX_v0_1, &nacl_irt_mutex, sizeof(nacl_irt_mutex),
95 { NACL_IRT_COND_v0_1, &nacl_irt_cond, sizeof(nacl_irt_cond),
97 { NACL_IRT_SEM_v0_1, &nacl_irt_sem, sizeof(nacl_irt_sem),
99 { NACL_IRT_TLS_v0_1, &nacl_irt_tls, sizeof(nacl_irt_tls), NULL },
101 * "irt-blockhook" is deprecated. It was provided for implementing
102 * thread suspension for conservative garbage collection, but this
103 * is probably not a portable use case under PNaCl, so this
104 * interface is disabled under PNaCl. See:
105 * https://code.google.com/p/nativeclient/issues/detail?id=3539
107 { NACL_IRT_BLOCKHOOK_v0_1, &nacl_irt_blockhook, sizeof(nacl_irt_blockhook),
110 * "irt-resource-open" is primarily provided for use by nacl-glibc's
111 * dynamic linker, which is not supported under PNaCl.
112 * open_resource() returns a file descriptor, but it is the only
113 * interface in NaCl to do so inside Chromium. This is inconsistent
114 * with PPAPI, which does not expose file descriptors (except in
115 * private/dev interfaces). See:
116 * https://code.google.com/p/nativeclient/issues/detail?id=3574
118 { NACL_IRT_RESOURCE_OPEN_v0_1, &nacl_irt_resource_open,
119 sizeof(nacl_irt_resource_open), non_pnacl_filter },
120 { NACL_IRT_RANDOM_v0_1, &nacl_irt_random, sizeof(nacl_irt_random), NULL },
121 { NACL_IRT_CLOCK_v0_1, &nacl_irt_clock, sizeof(nacl_irt_clock), NULL },
122 { NACL_IRT_DEV_GETPID_v0_1, &nacl_irt_dev_getpid,
123 sizeof(nacl_irt_dev_getpid), file_access_filter },
125 * "irt-exception-handling" is not supported under PNaCl because it
126 * exposes non-portable, architecture-specific register state. See:
127 * https://code.google.com/p/nativeclient/issues/detail?id=3444
129 { NACL_IRT_EXCEPTION_HANDLING_v0_1, &nacl_irt_exception_handling,
130 sizeof(nacl_irt_exception_handling), non_pnacl_filter },
131 { NACL_IRT_DEV_LIST_MAPPINGS_v0_1, &nacl_irt_dev_list_mappings,
132 sizeof(nacl_irt_dev_list_mappings), list_mappings_filter },
135 size_t nacl_irt_query_list(const char *interface_ident,
136 void *table, size_t tablesize,
137 const struct nacl_irt_interface *available,
138 size_t available_size) {
139 unsigned available_count = available_size / sizeof(*available);
141 for (i = 0; i < available_count; ++i) {
142 if (0 == strcmp(interface_ident, available[i].name)) {
143 if (NULL == available[i].filter || available[i].filter()) {
144 const size_t size = available[i].size;
145 if (size <= tablesize) {
146 memcpy(table, available[i].table, size);
156 size_t nacl_irt_query_core(const char *interface_ident,
157 void *table, size_t tablesize) {
158 return nacl_irt_query_list(interface_ident, table, tablesize,
159 irt_interfaces, sizeof(irt_interfaces));