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 <henning.sch...@siemens.com>
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 <henning.sch...@siemens.com>

---

 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 <r...@xenomai.org>.
+ *
+ * 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 <holin...@cs.helsinki.fi>.
+ *
+ * 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
Xenomai-git@xenomai.org
https://xenomai.org/mailman/listinfo/xenomai-git

Reply via email to