1 /* Using NaCl interface tables.
2 Copyright (C) 2015 Free Software Foundation, Inc.
3 This file is part of the GNU C Library.
5 The GNU C Library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
10 The GNU C Library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
15 You should have received a copy of the GNU Lesser General Public
16 License along with the GNU C Library; if not, see
17 <http://www.gnu.org/licenses/>. */
20 #include <nacl-interfaces.h>
24 /* These magic symbols are provided implicitly by the linker to
25 give us the bounds of the specially-named sections. */
27 extern const struct nacl_interface __start_nacl_mandatory_interface_names
[]
29 extern const struct nacl_interface __stop_nacl_mandatory_interface_names
[]
32 extern uintptr_t __start_nacl_mandatory_interface_tables
[]
34 extern uintptr_t __stop_nacl_mandatory_interface_tables
[]
37 /* We use weak references for the optional ones, since they
38 might not be included at all in any given statically-linked program. */
40 extern const struct nacl_interface __start_nacl_optional_interface_names
[]
41 attribute_hidden
__attribute__ ((weak
));
42 extern const struct nacl_interface __stop_nacl_optional_interface_names
[]
43 attribute_hidden
__attribute__ ((weak
));
45 extern uintptr_t __start_nacl_optional_interface_tables
[]
46 attribute_hidden
__attribute__ ((weak
));
47 extern uintptr_t __stop_nacl_optional_interface_tables
[]
48 attribute_hidden
__attribute__ ((weak
));
51 next_nacl_table (uintptr_t *t
, const struct nacl_interface
*i
)
53 return (void *) t
+ i
->table_size
;
56 static void __attribute__ ((noreturn
))
57 missing_mandatory_interface (const struct nacl_interface
*i
)
59 static const char before
[] =
60 "FATAL: NaCl IRT interface query failed for essential interface \"";
61 static const char after
[] =
64 if (__nacl_irt_fdio
.write
!= NULL
)
67 (*__nacl_irt_fdio
.write
) (2, before
, sizeof before
- 1, &wrote
);
68 (*__nacl_irt_fdio
.write
) (2, i
->name
, i
->namelen
- 1, &wrote
);
69 (*__nacl_irt_fdio
.write
) (2, after
, sizeof after
- 1, &wrote
);
72 if (__nacl_irt_basic
.exit
!= NULL
)
73 (*__nacl_irt_basic
.exit
) (-1);
79 initialize_mandatory_interfaces (void)
81 const struct nacl_interface
*i
= __start_nacl_mandatory_interface_names
;
82 uintptr_t *t
= __start_nacl_mandatory_interface_tables
;
83 while (i
< __stop_nacl_mandatory_interface_names
)
85 if (__nacl_irt_query (i
->name
, t
, i
->table_size
) != i
->table_size
)
86 missing_mandatory_interface (i
);
88 t
= next_nacl_table (t
, i
);
89 i
= next_nacl_interface (i
);
95 nacl_missing_optional_interface (void)
101 initialize_optional_interfaces (void)
103 const struct nacl_interface
*i
= __start_nacl_optional_interface_names
;
104 uintptr_t *t
= __start_nacl_optional_interface_tables
;
105 while (i
< __stop_nacl_optional_interface_names
)
107 size_t filled
= __nacl_irt_query (i
->name
, t
, i
->table_size
);
108 if (filled
!= i
->table_size
)
109 for (size_t slot
= 0; slot
< i
->table_size
/ sizeof *t
; ++slot
)
110 t
[slot
] = (uintptr_t) &nacl_missing_optional_interface
;
112 t
= next_nacl_table (t
, i
);
113 i
= next_nacl_interface (i
);
118 void attribute_hidden
119 __nacl_initialize_interfaces (void)
121 initialize_mandatory_interfaces ();
122 initialize_optional_interfaces ();
127 try_supply (const struct nacl_interface
*const start
,
128 const struct nacl_interface
*const stop
,
129 uintptr_t *all_tables
,
130 const char *ident
, size_t ident_len
,
131 const void *table
, size_t tablesize
)
133 const struct nacl_interface
*i
= start
;
134 uintptr_t *t
= all_tables
;
137 if (i
->table_size
== tablesize
138 && i
->namelen
== ident_len
139 && !memcmp (i
->name
, ident
, ident_len
))
141 memcpy (t
, table
, tablesize
);
145 t
= next_nacl_table (t
, i
);
146 i
= next_nacl_interface (i
);
154 PASTE_NAME (__nacl_supply_interface_
, MODULE_NAME
)
155 (const char *ident
, size_t ident_len
, const void *table
, size_t tablesize
)
157 return (try_supply (__start_nacl_mandatory_interface_names
,
158 __stop_nacl_mandatory_interface_names
,
159 __start_nacl_mandatory_interface_tables
,
160 ident
, ident_len
, table
, tablesize
)
161 || try_supply (__start_nacl_optional_interface_names
,
162 __stop_nacl_optional_interface_names
,
163 __start_nacl_optional_interface_tables
,
164 ident
, ident_len
, table
, tablesize
));