};
#undef UWRAP_SYMBOL_ENTRY
+#define UWRAP_SYMBOL_ENTRY(i) \
+ union { \
+ __rtld_default_##i f; \
+ void *obj; \
+ } _rtld_default_##i
+
+#ifdef HAVE_SYSCALL
+typedef bool (*__rtld_default_socket_wrapper_syscall_valid)(long int sysno);
+typedef long int (*__rtld_default_socket_wrapper_syscall_va)(long int sysno,
+ va_list va);
+#endif
+
+struct uwrap_rtld_default_symbols {
+#ifdef HAVE_SYSCALL
+ UWRAP_SYMBOL_ENTRY(socket_wrapper_syscall_valid);
+ UWRAP_SYMBOL_ENTRY(socket_wrapper_syscall_va);
+#else
+ uint8_t dummy;
+#endif
+};
+#undef UWRAP_SYMBOL_ENTRY
+
/*****************
* LIBPTHREAD
*****************/
struct uwrap_libc_symbols symbols;
} libc;
+ struct {
+ struct uwrap_rtld_default_symbols symbols;
+ } rtld_default;
+
struct {
void *handle;
struct uwrap_libpthread_symbols symbols;
_uwrap_bind_symbol(UWRAP_LIBPTHREAD, #sym_name); \
}
+#define uwrap_bind_symbol_rtld_default_optional(sym_name) \
+ if (uwrap.rtld_default.symbols._rtld_default_##sym_name.obj == NULL) { \
+ uwrap.rtld_default.symbols._rtld_default_##sym_name.obj = \
+ dlsym(RTLD_DEFAULT, #sym_name); \
+ }
+
/* DO NOT call this function during library initialization! */
static void __uwrap_bind_symbol_all_once(void)
{
uwrap_bind_symbol_libc(setgroups);
#ifdef HAVE_SYSCALL
uwrap_bind_symbol_libc(syscall);
+ uwrap_bind_symbol_rtld_default_optional(socket_wrapper_syscall_valid);
+ uwrap_bind_symbol_rtld_default_optional(socket_wrapper_syscall_va);
#endif
uwrap_bind_symbol_libpthread(pthread_create);
uwrap_bind_symbol_libpthread(pthread_exit);
return rc;
}
+
+static bool uwrap_swrap_syscall_valid(long int sysno)
+{
+ uwrap_bind_symbol_all();
+
+ if (uwrap.rtld_default.symbols._rtld_default_socket_wrapper_syscall_valid.f == NULL) {
+ return false;
+ }
+
+ return uwrap.rtld_default.symbols._rtld_default_socket_wrapper_syscall_valid.f(
+ sysno);
+}
+
+DO_NOT_SANITIZE_ADDRESS_ATTRIBUTE
+static long int uwrap_swrap_syscall_va(long int sysno, va_list va)
+{
+ uwrap_bind_symbol_all();
+
+ if (uwrap.rtld_default.symbols._rtld_default_socket_wrapper_syscall_va.f == NULL) {
+ /*
+ * Fallback to libc, if socket_wrapper_vsyscall is not
+ * available.
+ */
+ return libc_vsyscall(sysno, va);
+ }
+
+ return uwrap.rtld_default.symbols._rtld_default_socket_wrapper_syscall_va.f(
+ sysno,
+ va);
+}
#endif
static int libpthread_pthread_create(pthread_t *thread,
* fork() which calls syscall() after invoking uwrap_thread_prepare().
*/
if (!uwrap_is_uwrap_related_syscall(sysno)) {
+ /*
+ * We need to give socket_wrapper a
+ * chance to take over...
+ */
+ if (uwrap_swrap_syscall_valid(sysno)) {
+ rc = uwrap_swrap_syscall_va(sysno, va);
+ va_end(va);
+ return rc;
+ }
+
rc = libc_vsyscall(sysno, va);
va_end(va);
return rc;