Module: xenomai-3 Branch: stable-3.0.x Commit: 0b66d5e9bf392ff68c82e2fede92627a4ddb5550 URL: http://git.xenomai.org/?p=xenomai-3.git;a=commit;h=0b66d5e9bf392ff68c82e2fede92627a4ddb5550
Author: Henning Schild <[email protected]> Date: Wed Jan 25 16:08:00 2017 +0100 lib/cobalt: wrap CXXABI One-time Constructor functions The implementation of these functions uses locks and has the potential to trigger a SIGXCPU when contended. Wrap them with assert_nrt so they reliably cause a switch when used in the rt context. Signed-off-by: Henning Schild <[email protected]> --- lib/cobalt/assert.wrappers | 3 + lib/cobalt/assert_context.c | 19 ++ lib/cobalt/internal.h | 12 + lib/cobalt/internal.h.orig | 76 ++++++ lib/cobalt/wrappers.c | 37 +++ lib/cobalt/wrappers.c.orig | 534 +++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 681 insertions(+) diff --git a/lib/cobalt/assert.wrappers b/lib/cobalt/assert.wrappers index 7164858..65320ab 100644 --- a/lib/cobalt/assert.wrappers +++ b/lib/cobalt/assert.wrappers @@ -1,2 +1,5 @@ --wrap malloc --wrap free +--wrap __cxa_guard_acquire +--wrap __cxa_guard_release +--wrap __cxa_guard_abort diff --git a/lib/cobalt/assert_context.c b/lib/cobalt/assert_context.c index 2085953..fd18d6b 100644 --- a/lib/cobalt/assert_context.c +++ b/lib/cobalt/assert_context.c @@ -66,3 +66,22 @@ COBALT_IMPL(void, free, (void *ptr)) assert_nrt(); __STD(free(ptr)); } + +/* CXXABI 3.3.2 One-time Construction API */ +COBALT_IMPL(int, __cxa_guard_acquire, (__guard *g)) +{ + assert_nrt(); + return __STD(__cxa_guard_acquire(g)); +} + +COBALT_IMPL(void, __cxa_guard_release, (__guard *g)) +{ + assert_nrt(); + __STD(__cxa_guard_release(g)); +} + +COBALT_IMPL(void, __cxa_guard_abort, (__guard *g)) +{ + assert_nrt(); + __STD(__cxa_guard_abort(g)); +} diff --git a/lib/cobalt/internal.h b/lib/cobalt/internal.h index fee3fe1..9f58c6a 100644 --- a/lib/cobalt/internal.h +++ b/lib/cobalt/internal.h @@ -73,4 +73,16 @@ void cobalt_check_features(struct cobalt_featinfo *finfo); extern struct sigaction __cobalt_orig_sigdebug; +#ifdef __ARM_EABI__ +typedef uint32_t __guard; +#else +typedef uint64_t __guard; +#endif +int __real___cxa_guard_acquire(__guard*); +void __real___cxa_guard_release(__guard*); +void __real___cxa_guard_abort(__guard*); +int __cxa_guard_acquire(__guard*); +void __cxa_guard_release(__guard*); +void __cxa_guard_abort(__guard*); + #endif /* _LIB_COBALT_INTERNAL_H */ diff --git a/lib/cobalt/internal.h.orig b/lib/cobalt/internal.h.orig new file mode 100644 index 0000000..fee3fe1 --- /dev/null +++ b/lib/cobalt/internal.h.orig @@ -0,0 +1,76 @@ +/* + * Copyright (C) 2008 Philippe Gerum <[email protected]>. + * + * This 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 of the License, or (at your option) any later version. + * + * This 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 this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ +#ifndef _LIB_COBALT_INTERNAL_H +#define _LIB_COBALT_INTERNAL_H + +#include <limits.h> +#include <cobalt/sys/cobalt.h> +#include <boilerplate/ancillaries.h> +#include "current.h" + +extern void *cobalt_umm_private; + +extern void *cobalt_umm_shared; + +static inline int cobalt_is_relaxed(void) +{ + return cobalt_get_current_mode() & XNRELAX; +} + +static inline +struct cobalt_mutex_state *mutex_get_state(struct cobalt_mutex_shadow *shadow) +{ + if (shadow->attr.pshared) + return cobalt_umm_shared + shadow->state_offset; + + return cobalt_umm_private + shadow->state_offset; +} + +static inline atomic_t *mutex_get_ownerp(struct cobalt_mutex_shadow *shadow) +{ + return &mutex_get_state(shadow)->owner; +} + +void cobalt_sigshadow_install_once(void); + +void cobalt_thread_init(void); + +int cobalt_thread_probe(pid_t pid); + +void cobalt_print_init(void); + +void cobalt_print_init_atfork(void); + +void cobalt_ticks_init(unsigned long long freq); + +void cobalt_mutex_init(void); + +void cobalt_default_condattr_init(void); + +int cobalt_xlate_schedparam(int policy, + const struct sched_param_ex *param_ex, + struct sched_param *param); +int cobalt_init(void); + +struct cobalt_featinfo; + +void cobalt_check_features(struct cobalt_featinfo *finfo); + +extern struct sigaction __cobalt_orig_sigdebug; + +#endif /* _LIB_COBALT_INTERNAL_H */ diff --git a/lib/cobalt/wrappers.c b/lib/cobalt/wrappers.c index 09c74e5..65dc3bd 100644 --- a/lib/cobalt/wrappers.c +++ b/lib/cobalt/wrappers.c @@ -43,6 +43,7 @@ #include <unistd.h> #include <malloc.h> #include <boilerplate/compiler.h> +#include <internal.h> /* sched */ __weak @@ -532,3 +533,39 @@ unsigned int __real_sleep(unsigned int seconds) { return sleep(seconds); } + +__weak +int __real___cxa_guard_acquire(__guard *g) +{ + return __cxa_guard_acquire(g); +} + +__weak +void __real___cxa_guard_release(__guard *g) +{ + return __cxa_guard_release(g); +} + +__weak +void __real___cxa_guard_abort(__guard *g) +{ + return __cxa_guard_abort(g); +} + +__weak +int __cxa_guard_acquire(__guard *g) +{ + return 0; +} + +__weak +void __cxa_guard_release(__guard *g) +{ + return; +} + +__weak +void __cxa_guard_abort(__guard *g) +{ + return; +} diff --git a/lib/cobalt/wrappers.c.orig b/lib/cobalt/wrappers.c.orig new file mode 100644 index 0000000..09c74e5 --- /dev/null +++ b/lib/cobalt/wrappers.c.orig @@ -0,0 +1,534 @@ +/* + * Copyright (C) 2005 Heikki Lindholm <[email protected]>. + * + * This 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 of the License, or (at your option) any later version. + * + * This 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 this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ + +/* + * NOTE: functions in dynamically linked libraries aren't + * wrapped. These are fallback functions for __real* functions used by + * the library itself. + */ +#include <xeno_config.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <sys/ioctl.h> +#include <sys/select.h> +#include <sys/socket.h> +#include <sys/time.h> +#include <sys/mman.h> +#include <stdio.h> +#include <stdarg.h> +#include <stdlib.h> +#include <signal.h> +#include <syslog.h> +#include <pthread.h> +#include <semaphore.h> +#include <limits.h> +#include <fcntl.h> +#include <sched.h> +#include <memory.h> +#include <unistd.h> +#include <malloc.h> +#include <boilerplate/compiler.h> + +/* sched */ +__weak +int __real_pthread_setschedparam(pthread_t thread, + int policy, const struct sched_param *param) +{ + return pthread_setschedparam(thread, policy, param); +} + +__weak +int __real_pthread_getschedparam(pthread_t thread, + int *policy, struct sched_param *param) +{ + return pthread_getschedparam(thread, policy, param); +} + +__weak +int __real_sched_yield(void) +{ + return sched_yield(); +} + +__weak +int __real_sched_get_priority_min(int policy) +{ + return sched_get_priority_min(policy); +} + +__weak +int __real_sched_get_priority_max(int policy) +{ + return sched_get_priority_max(policy); +} + +__weak +int __real_sched_setscheduler(pid_t pid, int policy, + const struct sched_param *param) +{ + return sched_setscheduler(pid, policy, param); +} + +__weak +int __real_sched_getscheduler(pid_t pid) +{ + return sched_getscheduler(pid); +} + +/* pthread */ +__weak +int __real_pthread_create(pthread_t *ptid_r, + const pthread_attr_t * attr, + void *(*start) (void *), void *arg) +{ + return pthread_create(ptid_r, attr, start, arg); +} + +__weak +int __real_pthread_kill(pthread_t ptid, int sig) +{ + return pthread_kill(ptid, sig); +} + +__weak +int __real_pthread_join(pthread_t ptid, void **retval) +{ + return pthread_join(ptid, retval); +} + +/* attr */ +__weak +int __real_pthread_attr_init(pthread_attr_t *attr) +{ + return pthread_attr_init(attr); +} + +/* semaphores */ +__weak +int __real_sem_init(sem_t * sem, int pshared, unsigned value) +{ + return sem_init(sem, pshared, value); +} + +__weak +int __real_sem_destroy(sem_t * sem) +{ + return sem_destroy(sem); +} + +__weak +int __real_sem_post(sem_t * sem) +{ + return sem_post(sem); +} + +__weak +int __real_sem_wait(sem_t * sem) +{ + return sem_wait(sem); +} + +__weak +int __real_sem_trywait(sem_t * sem) +{ + return sem_trywait(sem); +} + +__weak +int __real_sem_timedwait(sem_t * sem, const struct timespec *abs_timeout) +{ + return sem_timedwait(sem, abs_timeout); +} + +__weak +int __real_sem_getvalue(sem_t * sem, int *sval) +{ + return sem_getvalue(sem, sval); +} + +/* rtdm */ +__weak +int __real_open(const char *path, int oflag, ...) +{ + mode_t mode = 0; + va_list ap; + + if (oflag & O_CREAT) { + va_start(ap, oflag); + mode = va_arg(ap, mode_t); + va_end(ap); + } + + return open(path, oflag, mode); +} + +/* rtdm */ +__weak +int __real_open64(const char *path, int oflag, ...) +{ + mode_t mode = 0; + va_list ap; + + if (oflag & O_CREAT) { + va_start(ap, oflag); + mode = va_arg(ap, mode_t); + va_end(ap); + } + + return open64(path, oflag, mode); +} + +__weak +int __real_socket(int protocol_family, int socket_type, int protocol) +{ + return socket(protocol_family, socket_type, protocol); +} + +__weak +int __real_close(int fd) +{ + return close(fd); +} + +__weak +int __real_fcntl(int fd, int cmd, ...) +{ + va_list ap; + int arg; + + va_start(ap, cmd); + arg = va_arg(ap, int); + va_end(ap); + + return fcntl(fd, cmd, arg); +} + +__weak +int __real_ioctl(int fd, unsigned int request, ...) +{ + va_list ap; + void *arg; + + va_start(ap, request); + arg = va_arg(ap, void *); + va_end(ap); + + return ioctl(fd, request, arg); +} + +__weak +ssize_t __real_read(int fd, void *buf, size_t nbyte) +{ + return read(fd, buf, nbyte); +} + +__weak +ssize_t __real_write(int fd, const void *buf, size_t nbyte) +{ + return write(fd, buf, nbyte); +} + +__weak +ssize_t __real_recvmsg(int fd, struct msghdr * msg, int flags) +{ + return recvmsg(fd, msg, flags); +} + +__weak +ssize_t __real_sendmsg(int fd, const struct msghdr * msg, int flags) +{ + return sendmsg(fd, msg, flags); +} + +__weak +ssize_t __real_recvfrom(int fd, void *buf, size_t len, int flags, + struct sockaddr * from, socklen_t * fromlen) +{ + return recvfrom(fd, buf, len, flags, from, fromlen); +} + +__weak +ssize_t __real_sendto(int fd, const void *buf, size_t len, int flags, + const struct sockaddr * to, socklen_t tolen) +{ + return sendto(fd, buf, len, flags, to, tolen); +} + +__weak +ssize_t __real_recv(int fd, void *buf, size_t len, int flags) +{ + return recv(fd, buf, len, flags); +} + +__weak +ssize_t __real_send(int fd, const void *buf, size_t len, int flags) +{ + return send(fd, buf, len, flags); +} + +__weak +int __real_getsockopt(int fd, int level, int optname, void *optval, + socklen_t * optlen) +{ + return getsockopt(fd, level, optname, optval, optlen); +} + +__weak +int __real_setsockopt(int fd, int level, int optname, const void *optval, + socklen_t optlen) +{ + return setsockopt(fd, level, optname, optval, optlen); +} + +__weak +int __real_bind(int fd, const struct sockaddr *my_addr, socklen_t addrlen) +{ + return bind(fd, my_addr, addrlen); +} + +__weak +int __real_connect(int fd, const struct sockaddr *serv_addr, socklen_t addrlen) +{ + return connect(fd, serv_addr, addrlen); +} + +__weak +int __real_listen(int fd, int backlog) +{ + return listen(fd, backlog); +} + +__weak +int __real_accept(int fd, struct sockaddr *addr, socklen_t * addrlen) +{ + return accept(fd, addr, addrlen); +} + +__weak +int __real_getsockname(int fd, struct sockaddr *name, socklen_t * namelen) +{ + return getsockname(fd, name, namelen); +} + +__weak +int __real_getpeername(int fd, struct sockaddr *name, socklen_t * namelen) +{ + return getpeername(fd, name, namelen); +} + +__weak +int __real_shutdown(int fd, int how) +{ + return shutdown(fd, how); +} + +__weak +int __real_select (int __nfds, fd_set *__restrict __readfds, + fd_set *__restrict __writefds, + fd_set *__restrict __exceptfds, + struct timeval *__restrict __timeout) +{ + return select(__nfds, __readfds, __writefds, __exceptfds, __timeout); +} + +__weak +void *__real_mmap(void *addr, size_t length, int prot, int flags, + int fd, off_t offset) +{ + return mmap(addr, length, prot, flags, fd, offset); +} + +__weak +void *__real_mmap64(void *addr, size_t length, int prot, int flags, + int fd, off64_t offset) +{ + return mmap64(addr, length, prot, flags, fd, offset); +} + +__weak +int __real_vfprintf(FILE *stream, const char *fmt, va_list args) +{ + return vfprintf(stream, fmt, args); +} + +__weak +int __real_vprintf(const char *fmt, va_list args) +{ + return vprintf(fmt, args); +} + +__weak +int __real_fprintf(FILE *stream, const char *fmt, ...) +{ + va_list args; + int rc; + + va_start(args, fmt); + rc = vfprintf(stream, fmt, args); + va_end(args); + + return rc; +} + +__weak +int __real_printf(const char *fmt, ...) +{ + va_list args; + int rc; + + va_start(args, fmt); + rc = vprintf(fmt, args); + va_end(args); + + return rc; +} + +#ifdef CONFIG_XENO_FORTIFY + +__weak +int __real___vfprintf_chk(FILE *stream, int level, const char *fmt, va_list ap) +{ + return __vfprintf_chk(stream, level, fmt, ap); +} + +__weak +void __real___vsyslog_chk(int priority, int level, const char *fmt, va_list ap) +{ + extern void __vsyslog_chk(int, int, const char *, va_list); + + __vsyslog_chk(priority, level, fmt, ap); +} + +#endif + +__weak +int __real_puts(const char *s) +{ + return puts(s); +} + +__weak +int __real_fputs(const char *s, FILE *stream) +{ + return fputs(s, stream); +} + +#if !defined(__UCLIBC__) || !defined(__STDIO_PUTC_MACRO) + +__weak +int __real_fputc(int c, FILE *stream) +{ + return fputc(c, stream); +} + +__weak +int __real_putchar(int c) +{ + return putchar(c); +} + +#endif /* !(__UCLIBC__ && __STDIO_PUTC_MACRO) */ + +__weak +size_t __real_fwrite(const void *ptr, size_t sz, size_t nmemb, FILE *stream) +{ + return fwrite(ptr, sz, nmemb, stream); +} + +__weak +int __real_fclose(FILE *stream) +{ + return fclose(stream); +} + +__weak +void __real_syslog(int priority, const char *fmt, ...) +{ + va_list args; + + va_start(args, fmt); + vsyslog(priority, fmt, args); + va_end(args); +} + +__weak +void __real_vsyslog(int priority, const char *fmt, va_list ap) +{ + vsyslog(priority, fmt, ap); +} + +__weak +void *__real_malloc(size_t size) +{ + return malloc(size); +} + +__weak +void __real_free(void *ptr) +{ + free(ptr); +} + +__weak +int __real_gettimeofday(struct timeval *tv, struct timezone *tz) +{ + return gettimeofday(tv, tz); +} + +__weak +int __real_clock_gettime(clockid_t clk_id, struct timespec *tp) +{ + return clock_gettime(clk_id, tp); +} + +__weak +int __real_sigwait(const sigset_t *set, int *sig) +{ + return sigwait(set, sig); +} + +__weak +int __real_sigwaitinfo(const sigset_t *set, siginfo_t *si) +{ + return sigwaitinfo(set, si); +} + +__weak +int __real_sigtimedwait(const sigset_t *set, siginfo_t *si, + const struct timespec *timeout) +{ + return sigtimedwait(set, si, timeout); +} + +__weak +int __real_sigpending(sigset_t *set) +{ + return sigpending(set); +} + +__weak +int __real_kill(pid_t pid, int sig) +{ + return kill(pid, sig); +} + +__weak +unsigned int __real_sleep(unsigned int seconds) +{ + return sleep(seconds); +} _______________________________________________ Xenomai-git mailing list [email protected] https://xenomai.org/mailman/listinfo/xenomai-git
