diff options
Diffstat (limited to 'sysdeps/nacl')
-rw-r--r-- | sysdeps/nacl/Makefile | 2 | ||||
-rw-r--r-- | sysdeps/nacl/Versions | 2 | ||||
-rw-r--r-- | sysdeps/nacl/nacl-interfaces.c | 42 | ||||
-rw-r--r-- | sysdeps/nacl/nacl-interfaces.h | 9 | ||||
-rw-r--r-- | sysdeps/nacl/nacl_interface_ext_supply.c | 42 |
5 files changed, 95 insertions, 2 deletions
diff --git a/sysdeps/nacl/Makefile b/sysdeps/nacl/Makefile index b51156b..6749a44 100644 --- a/sysdeps/nacl/Makefile +++ b/sysdeps/nacl/Makefile @@ -108,7 +108,7 @@ test-wrapper-env = $(test-wrapper-env-only) test-wrapper = $(test-wrapper-env) -- ifeq ($(subdir),csu) -sysdep_routines += nacl_interface_query \ +sysdep_routines += nacl_interface_query nacl_interface_ext_supply \ nacl-interfaces $(call nacl-routines-of,libc) endif diff --git a/sysdeps/nacl/Versions b/sysdeps/nacl/Versions index 4ac56c2..cfc4a08 100644 --- a/sysdeps/nacl/Versions +++ b/sysdeps/nacl/Versions @@ -1,12 +1,14 @@ ld { GLIBC_PRIVATE { __nacl_irt_*; + __nacl_supply_interface_rtld; } } libc { GLIBC_2.22 { nacl_interface_query; + nacl_interface_ext_supply; } GLIBC_PRIVATE { diff --git a/sysdeps/nacl/nacl-interfaces.c b/sysdeps/nacl/nacl-interfaces.c index cb0dcd0..5dbfadd 100644 --- a/sysdeps/nacl/nacl-interfaces.c +++ b/sysdeps/nacl/nacl-interfaces.c @@ -121,3 +121,45 @@ __nacl_initialize_interfaces (void) initialize_mandatory_interfaces (); initialize_optional_interfaces (); } + + +static bool +try_supply (const struct nacl_interface *const start, + const struct nacl_interface *const stop, + uintptr_t *all_tables, + const char *ident, size_t ident_len, + const void *table, size_t tablesize) +{ + const struct nacl_interface *i = start; + uintptr_t *t = all_tables; + while (i < stop) + { + if (i->table_size == tablesize + && i->namelen == ident_len + && !memcmp (i->name, ident, ident_len)) + { + memcpy (t, table, tablesize); + return true; + } + + t = next_nacl_table (t, i); + i = next_nacl_interface (i); + } + + return false; +} + +internal_function +bool +PASTE_NAME (__nacl_supply_interface_, MODULE_NAME) + (const char *ident, size_t ident_len, const void *table, size_t tablesize) +{ + return (try_supply (__start_nacl_mandatory_interface_names, + __stop_nacl_mandatory_interface_names, + __start_nacl_mandatory_interface_tables, + ident, ident_len, table, tablesize) + || try_supply (__start_nacl_optional_interface_names, + __stop_nacl_optional_interface_names, + __start_nacl_optional_interface_tables, + ident, ident_len, table, tablesize)); +} diff --git a/sysdeps/nacl/nacl-interfaces.h b/sysdeps/nacl/nacl-interfaces.h index 0c886a5..36f3808 100644 --- a/sysdeps/nacl/nacl-interfaces.h +++ b/sysdeps/nacl/nacl-interfaces.h @@ -20,6 +20,7 @@ #define _NACL_INTERFACES_H 1 #include <errno.h> +#include <stdbool.h> #include <stddef.h> #include <stdint.h> #include <sys/types.h> @@ -73,7 +74,7 @@ next_nacl_interface (const struct nacl_interface *i) { uintptr_t align = __alignof (*i); return (const void *) (((uintptr_t) &i->name[i->namelen] + align - 1) - & -align); + & -align); } #if IS_IN (libpthread) @@ -94,6 +95,12 @@ next_nacl_interface (const struct nacl_interface *i) #undef NACL_OPTIONAL_INTERFACE extern void __nacl_initialize_interfaces (void) attribute_hidden; +extern bool __nacl_supply_interface_libc (const char *ident, size_t ident_len, + const void *table, size_t tablesize) + internal_function attribute_hidden; +extern bool __nacl_supply_interface_rtld (const char *ident, size_t ident_len, + const void *table, size_t tablesize); + internal_function; /* Convenience function for handling IRT call return values. */ static inline int diff --git a/sysdeps/nacl/nacl_interface_ext_supply.c b/sysdeps/nacl/nacl_interface_ext_supply.c new file mode 100644 index 0000000..a1525be --- /dev/null +++ b/sysdeps/nacl/nacl_interface_ext_supply.c @@ -0,0 +1,42 @@ +/* Interface for the user to replace NaCl IRT interface functions. + Copyright (C) 2015 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#include <nacl-interfaces.h> +#include <string.h> + +size_t +nacl_interface_ext_supply (const char *interface_ident, + const void *table, size_t tablesize) +{ + const size_t ident_len = strlen (interface_ident) + 1; + + /* Most interfaces are in rtld, so try there first. If other + libraries ever get their own tables not used in libc, then we + will need some dynamic registration mechanism here to iterate + over all libraries' __nacl_supply_interface_libfoo calls. */ + if (0 +#ifdef SHARED + || __nacl_supply_interface_rtld (interface_ident, ident_len, + table, tablesize) +#endif + || __nacl_supply_interface_libc (interface_ident, ident_len, + table, tablesize)) + return tablesize; + + return 0; +} |