From patchwork Wed Jun 3 20:52:42 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Roland McGrath X-Patchwork-Id: 7037 Received: (qmail 56435 invoked by alias); 3 Jun 2015 20:52:48 -0000 Mailing-List: contact libc-alpha-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: libc-alpha-owner@sourceware.org Delivered-To: mailing list libc-alpha@sourceware.org Received: (qmail 56425 invoked by uid 89); 3 Jun 2015 20:52:47 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-0.7 required=5.0 tests=AWL, BAYES_40, KAM_LAZY_DOMAIN_SECURITY autolearn=no version=3.3.2 X-HELO: topped-with-meat.com MIME-Version: 1.0 From: Roland McGrath To: "GNU C. Library" Subject: [COMMITTED PATCH] NaCl: Implement nacl_interface_ext_supply entry point. Message-Id: <20150603205242.5A2E92C3A9B@topped-with-meat.com> Date: Wed, 3 Jun 2015 13:52:42 -0700 (PDT) X-CMAE-Score: 0 X-CMAE-Analysis: v=2.1 cv=SvUDtp+0 c=1 sm=1 tr=0 a=WkljmVdYkabdwxfqvArNOQ==:117 a=14OXPxybAAAA:8 a=kj9zAlcOel0A:10 a=hOe2yjtxAAAA:8 a=mDV3o1hIAAAA:8 a=4f9l_7uW8uOmFxTy85oA:9 a=CjuIK1q_8ugA:10 2015-06-03 Roland McGrath * sysdeps/nacl/nacl-interfaces.c (try_supply): New static function. (PASTE_NAME (__nacl_supply_interface_, MODULE_NAME)): New function. * sysdeps/nacl/nacl-interfaces.h: Declare __nacl_supply_interface_libc and __nacl_supply_interface_rtld. * sysdeps/nacl/nacl_interface_ext_supply.c: New file. * sysdeps/nacl/Makefile [$(subdir) = csu] (sysdep_routines): Add it. * sysdeps/nacl/Versions (ld: GLIBC_PRIVATE): Add __nacl_supply_interface_rtld. (libc: GLIBC_2.22): Add nacl_interface_ext_supply. 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 +#include #include #include #include @@ -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 + . */ + +#include +#include + +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; +}