aboutsummaryrefslogtreecommitdiff
path: root/lib/libc/include/libc_private.h
diff options
context:
space:
mode:
authorKonstantin Belousov <kib@FreeBSD.org>2015-01-03 18:38:46 +0000
committerKonstantin Belousov <kib@FreeBSD.org>2015-01-03 18:38:46 +0000
commit8495e8b1e9e13fb707296a486acf7538dbfa12b2 (patch)
treee381919bf3f754392eb9a47b256135a1dbb2b2b1 /lib/libc/include/libc_private.h
parent0e521992a44f909675127096f51621326c540481 (diff)
downloadsrc-8495e8b1e9e13fb707296a486acf7538dbfa12b2.tar.gz
src-8495e8b1e9e13fb707296a486acf7538dbfa12b2.zip
Fix known issues which blow up the process after dlopen("libthr.so")
(or loading a dso linked to libthr.so into process which was not linked against threading library). - Remove libthr interposers of the libc functions, including __error(). Instead, functions calls are indirected through the interposing table, similar to how pthread stubs in libc are already done. Libc by default points either to syscall trampolines or to existing libc implementations. On libthr load, libthr rewrites the pointers to the cancellable implementations already in libthr. The interposition table is separate from pthreads stubs indirection table to not pull pthreads stubs into static binaries. - Postpone the malloc(3) internal mutexes initialization until libthr is loaded. This avoids recursion between calloc(3) and static pthread_mutex_t initialization. - Reinstall signal handlers with wrapper on libthr load. The _rtld_is_dlopened(3) is used to avoid useless calls to sigaction(2) when libthr is statically referenced from the main binary. In the process, fix openat(2), swapcontext(2) and setcontext(2) interposing. The libc symbols were exported at different versions than libthr interposers. Export both libc and libthr versions from libc now, with default set to the higher version from libthr. Remove unused and disconnected swapcontext(3) userspace implementation from libc/gen. No objections from: deischen Tested by: pho, antoine (exp-run) (previous versions) Sponsored by: The FreeBSD Foundation MFC after: 1 week
Notes
Notes: svn path=/head/; revision=276630
Diffstat (limited to 'lib/libc/include/libc_private.h')
-rw-r--r--lib/libc/include/libc_private.h160
1 files changed, 140 insertions, 20 deletions
diff --git a/lib/libc/include/libc_private.h b/lib/libc/include/libc_private.h
index 40a5f7266709..adf342de4e85 100644
--- a/lib/libc/include/libc_private.h
+++ b/lib/libc/include/libc_private.h
@@ -173,6 +173,61 @@ typedef pthread_func_t pthread_func_entry_t[2];
extern pthread_func_entry_t __thr_jtable[];
+extern int *(*__error_selector)(void);
+int _pthread_mutex_init_calloc_cb_stub(pthread_mutex_t *mutex,
+ void *(calloc_cb)(__size_t, __size_t));
+
+typedef int (*interpos_func_t)(void);
+interpos_func_t *__libc_interposing_slot(int interposno);
+extern interpos_func_t __libc_interposing[];
+
+enum {
+ INTERPOS_accept,
+ INTERPOS_accept4,
+ INTERPOS_aio_suspend,
+ INTERPOS_close,
+ INTERPOS_connect,
+ INTERPOS_creat,
+ INTERPOS_fcntl,
+ INTERPOS_fsync,
+ INTERPOS_fork,
+ INTERPOS_msync,
+ INTERPOS_nanosleep,
+ INTERPOS_open,
+ INTERPOS_openat,
+ INTERPOS_poll,
+ INTERPOS_pselect,
+ INTERPOS_raise,
+ INTERPOS_recvfrom,
+ INTERPOS_recvmsg,
+ INTERPOS_select,
+ INTERPOS_sendmsg,
+ INTERPOS_sendto,
+ INTERPOS_setcontext,
+ INTERPOS_sigaction,
+ INTERPOS_sigprocmask,
+ INTERPOS_sigsuspend,
+ INTERPOS_sigwait,
+ INTERPOS_sigtimedwait,
+ INTERPOS_sigwaitinfo,
+ INTERPOS_swapcontext,
+ INTERPOS_system,
+ INTERPOS_sleep,
+ INTERPOS_tcdrain,
+ INTERPOS_usleep,
+ INTERPOS_pause,
+ INTERPOS_read,
+ INTERPOS_readv,
+ INTERPOS_wait,
+ INTERPOS_wait3,
+ INTERPOS_wait4,
+ INTERPOS_waitpid,
+ INTERPOS_write,
+ INTERPOS_writev,
+ INTERPOS__pthread_mutex_init_calloc_cb,
+ INTERPOS_MAX
+};
+
/*
* yplib internal interfaces
*/
@@ -215,42 +270,107 @@ void _malloc_thread_cleanup(void);
void _malloc_prefork(void);
void _malloc_postfork(void);
+void _malloc_first_thread(void);
+
/*
* Function to clean up streams, called from abort() and exit().
*/
-extern void (*__cleanup)(void) __hidden;
+void (*__cleanup)(void) __hidden;
/*
* Get kern.osreldate to detect ABI revisions. Explicitly
* ignores value of $OSVERSION and caches result. Prototypes
* for the wrapped "new" pad-less syscalls are here for now.
*/
-extern int __getosreldate(void);
+int __getosreldate(void);
#include <sys/_types.h>
-/* Without pad */
-extern __off_t __sys_lseek(int, __off_t, int);
-extern int __sys_ftruncate(int, __off_t);
-extern int __sys_truncate(const char *, __off_t);
-extern __ssize_t __sys_pread(int, void *, __size_t, __off_t);
-extern __ssize_t __sys_pwrite(int, const void *, __size_t, __off_t);
-extern void * __sys_mmap(void *, __size_t, int, int, int, __off_t);
+#include <sys/_sigset.h>
/* With pad */
-extern __off_t __sys_freebsd6_lseek(int, int, __off_t, int);
-extern int __sys_freebsd6_ftruncate(int, int, __off_t);
-extern int __sys_freebsd6_truncate(const char *, int, __off_t);
-extern __ssize_t __sys_freebsd6_pread(int, void *, __size_t, int, __off_t);
-extern __ssize_t __sys_freebsd6_pwrite(int, const void *, __size_t, int, __off_t);
-extern void * __sys_freebsd6_mmap(void *, __size_t, int, int, int, int, __off_t);
-
-/* Without back-compat translation */
-extern int __sys_fcntl(int, int, ...);
+__off_t __sys_freebsd6_lseek(int, int, __off_t, int);
+int __sys_freebsd6_ftruncate(int, int, __off_t);
+int __sys_freebsd6_truncate(const char *, int, __off_t);
+__ssize_t __sys_freebsd6_pread(int, void *, __size_t, int, __off_t);
+__ssize_t __sys_freebsd6_pwrite(int, const void *, __size_t, int, __off_t);
+void * __sys_freebsd6_mmap(void *, __size_t, int, int, int, int, __off_t);
+struct aiocb;
+struct fd_set;
+struct iovec;
+struct msghdr;
+struct pollfd;
+struct rusage;
+struct sigaction;
+struct sockaddr;
struct timespec;
struct timeval;
struct timezone;
-int __sys_gettimeofday(struct timeval *, struct timezone *);
-int __sys_clock_gettime(__clockid_t, struct timespec *ts);
+struct __siginfo;
+struct __ucontext;
+int __sys_aio_suspend(const struct aiocb * const[], int,
+ const struct timespec *);
+int __sys_accept(int, struct sockaddr *, __socklen_t *);
+int __sys_accept4(int, struct sockaddr *, __socklen_t *, int);
+int __sys_clock_gettime(__clockid_t, struct timespec *ts);
+int __sys_close(int);
+int __sys_connect(int, const struct sockaddr *, __socklen_t);
+int __sys_fcntl(int, int, ...);
+int __sys_fsync(int);
+__pid_t __sys_fork(void);
+int __sys_ftruncate(int, __off_t);
+int __sys_gettimeofday(struct timeval *, struct timezone *);
+__off_t __sys_lseek(int, __off_t, int);
+void *__sys_mmap(void *, __size_t, int, int, int, __off_t);
+int __sys_msync(void *, __size_t, int);
+int __sys_nanosleep(const struct timespec *, struct timespec *);
+int __sys_open(const char *, int, ...);
+int __sys_openat(int, const char *, int, ...);
+int __sys_pselect(int, struct fd_set *, struct fd_set *,
+ struct fd_set *, const struct timespec *,
+ const __sigset_t *);
+int __sys_poll(struct pollfd *, unsigned, int);
+__ssize_t __sys_pread(int, void *, __size_t, __off_t);
+__ssize_t __sys_pwrite(int, const void *, __size_t, __off_t);
+__ssize_t __sys_read(int, void *, __size_t);
+__ssize_t __sys_readv(int, const struct iovec *, int);
+__ssize_t __sys_recv(int, void *, __size_t, int);
+__ssize_t __sys_recvfrom(int, void *, __size_t, int, struct sockaddr *,
+ __socklen_t *);
+__ssize_t __sys_recvmsg(int, struct msghdr *, int);
+int __sys_select(int, struct fd_set *, struct fd_set *,
+ struct fd_set *, struct timeval *);
+__ssize_t __sys_sendmsg(int, const struct msghdr *, int);
+__ssize_t __sys_sendto(int, const void *, __size_t, int,
+ const struct sockaddr *, __socklen_t);
+int __sys_setcontext(const struct __ucontext *);
+int __sys_sigaction(int, const struct sigaction *,
+ struct sigaction *);
+int __sys_sigprocmask(int, const __sigset_t *, __sigset_t *);
+int __sys_sigsuspend(const __sigset_t *);
+int __sys_sigtimedwait(const __sigset_t *, struct __siginfo *,
+ const struct timespec *);
+int __sys_sigwait(const __sigset_t *, int *);
+int __sys_sigwaitinfo(const __sigset_t *, struct __siginfo *);
+int __sys_swapcontext(struct __ucontext *,
+ const struct __ucontext *);
+int __sys_truncate(const char *, __off_t);
+__pid_t __sys_wait4(__pid_t, int *, int, struct rusage *);
+__ssize_t __sys_write(int, const void *, __size_t);
+__ssize_t __sys_writev(int, const struct iovec *, int);
+
+int __libc_creat(const char *path, __mode_t mode);
+int __libc_pause(void);
+int __libc_raise(int);
+int __libc_sigwait(const __sigset_t * __restrict,
+ int * restrict sig);
+int __libc_system(const char *);
+unsigned int __libc_sleep(unsigned int);
+int __libc_tcdrain(int);
+int __libc_usleep(__useconds_t);
+__pid_t __libc_wait(int *);
+__pid_t __libc_wait3(int *, int, struct rusage *);
+__pid_t __libc_waitpid(__pid_t, int *, int);
+int __fcntl_compat(int fd, int cmd, ...);
/* execve() with PATH processing to implement posix_spawnp() */
int _execvpe(const char *, char * const *, char * const *);