Heikki Lindholm kirjoitti:
Philippe Gerum kirjoitti:

Heikki Lindholm wrote:

Philippe Gerum kirjoitti:

Heikki Lindholm wrote:

libpthread_rt won't produce usable exec apps on ppc64 if it uses --wrap.
There seems to be no reason to use --wrap for building the lib itself.





Good catch for the lib flags. However, substituting __real calls with the genuine ones seems wrong to me. You'd just end up causing the same issue.




I don't think so. Although, I'm not sure how ld is supposed to handle --wrap case for libraries, this works in the dynamic case, at least, for the ppc32 and ppc64 (tested on debian sarge and gentoo ppc64), whereas leaving the __real*'s in dynamic library will fail with unrelocatable symbols.



Ok, that's another issue. We still need to call __real entry points, but we also have to care for the specific issue of dynamic linking which does not substitute the calls:

Excerpt from ld's info page, talking about wrapping malloc:

You may wish to provide a `__real_malloc' function as well, so that
     links without the `--wrap' option will succeed.  If you do this,
     you should not put the definition of `__real_malloc' in the same
     file as `__wrap_malloc'; if you do, the assembler may resolve the
     call before the linker has a chance to wrap it to `malloc'.

So we need a separate .c file glued to the lib, which basically does:

__real_foo ()
{
    foo();
}

For all __real symbols referenced.


Right. Indeed, it seems to be the case that --wrap does not work the same way for dynamic linking as static. Fortunately, there aren't too many __real's used in there.

Here's a corrected patch that should take care of both cases more cleanly.

-- Heikki Lindholm
diff -Nru --exclude=GNUmakefile.in 
../../../cvs-versions/fusion/skins/posix/lib/GNUmakefile.am ./lib/GNUmakefile.am
--- ../../../cvs-versions/fusion/skins/posix/lib/GNUmakefile.am 2005-08-11 
10:45:39.000000000 +0300
+++ ./lib/GNUmakefile.am        2005-09-06 16:55:50.915185648 +0300
@@ -2,10 +2,7 @@
 
 lib_LTLIBRARIES = libpthread_rt.la
 
-posix_wrappers := $(shell cat $(srcdir)/posix.wrappers | \
-                   while read symbol; do echo -n "-Wl,--wrap -Wl,$$symbol " ; 
done )
-
-libpthread_rt_la_LDFLAGS = $(posix_wrappers) -module -version-info 0:0:0
+libpthread_rt_la_LDFLAGS = -module -version-info 0:0:0
 
 libpthread_rt_la_SOURCES = \
        init.c \
@@ -17,7 +14,8 @@
        mq.c \
        mutex.c \
        interrupt.c \
-       rtdm.c
+       rtdm.c \
+       wrappers.c
 
 include_HEADERS = \
        mqueue.h \
diff -Nru --exclude=GNUmakefile.in 
../../../cvs-versions/fusion/skins/posix/lib/wrappers.c ./lib/wrappers.c
--- ../../../cvs-versions/fusion/skins/posix/lib/wrappers.c     1970-01-01 
02:00:00.000000000 +0200
+++ ./lib/wrappers.c    2005-09-06 18:08:14.645838000 +0300
@@ -0,0 +1,218 @@
+/*
+ * 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 <stdarg.h>
+#include <pthread.h>
+#include <semaphore.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <sys/socket.h>
+#include <unistd.h>
+#include <sys/ioctl.h>
+
+/* pthread */
+int __real_pthread_setschedparam(pthread_t thread,
+                                int policy,
+                                const struct sched_param *param)
+{
+    return pthread_setschedparam(thread, policy, param);
+}
+ 
+int __real_pthread_create(pthread_t *tid,
+                         const pthread_attr_t *attr,
+                         void *(*start) (void *),
+                         void *arg)
+{
+    return pthread_create(tid, attr, start, arg);
+}
+
+/* semaphores */
+int __real_sem_init(sem_t *sem,
+                   int pshared,
+                   unsigned value)
+{
+    return sem_init(sem, pshared, value);
+}
+
+int __real_sem_destroy(sem_t *sem)
+{
+    return sem_destroy(sem);
+}
+
+int __real_sem_post(sem_t *sem)
+{
+    return sem_post(sem);
+}
+
+int __real_sem_wait(sem_t *sem)
+{
+    return sem_wait(sem);
+}
+
+/* rtdm */
+int __real_open(const char *path, int oflag, ...)
+{
+    va_list ap;
+    mode_t mode;
+
+    if (oflag & O_CREAT)
+    {
+        va_start(ap, oflag);
+        mode = va_arg(ap, mode_t);
+        va_end(ap);
+        return open(path, oflag, mode);
+    }
+    else
+        return open(path, oflag);
+}
+
+int __real_socket(int protocol_family, int socket_type, int protocol)
+{
+    return socket(protocol_family, socket_type, protocol);
+}
+
+int __real_close(int fd)
+{
+    return close(fd);
+}
+
+int __real_ioctl(int fd, int request, ...)
+{
+    va_list ap;
+    void    *arg;
+
+    va_start(ap, request);
+    arg = va_arg(ap, void*);
+    va_end(ap);
+
+    return ioctl(fd, request, arg);
+}
+
+
+ssize_t __real_read(int fd, void *buf, size_t nbyte)
+{
+    return read(fd, buf, nbyte);
+}
+
+
+ssize_t __real_write(int fd, const void *buf, size_t nbyte)
+{
+    return write(fd, buf, nbyte);
+}
+
+
+ssize_t __real_recvmsg(int fd, struct msghdr *msg, int flags)
+{
+    return recvmsg(fd, msg, flags);
+}
+
+
+ssize_t __real_sendmsg(int fd, const struct msghdr *msg, int flags)
+{
+    return sendmsg(fd, msg, flags);
+}
+
+
+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);
+}
+
+
+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);
+}
+
+
+ssize_t __real_recv(int fd, void *buf, size_t len, int flags)
+{
+    return recv(fd, buf, len, flags);
+}
+
+
+ssize_t __real_send(int fd, const void *buf, size_t len, int flags)
+{
+    return send(fd, buf, len, flags);
+}
+
+
+int __real_getsockopt(int fd, int level, int optname, void *optval,
+                      socklen_t *optlen)
+{
+    return getsockopt(fd, level, optname, optval, optlen);
+}
+
+
+int __real_setsockopt(int fd, int level, int optname, const void *optval,
+                     socklen_t optlen)
+{
+    return setsockopt(fd, level, optname, optval, optlen);
+}
+
+
+int __real_bind(int fd, const struct sockaddr *my_addr, socklen_t addrlen)
+{
+    return bind(fd, my_addr, addrlen);
+}
+
+
+int __real_connect(int fd, const struct sockaddr *serv_addr,
+                   socklen_t addrlen)
+{
+    return connect(fd, serv_addr, addrlen);
+}
+
+
+int __real_listen(int fd, int backlog)
+{
+    return listen(fd, backlog);
+}
+
+
+int __real_accept(int fd, struct sockaddr *addr, socklen_t *addrlen)
+{
+    return accept(fd, addr, addrlen);
+}
+
+
+int __real_getsockname(int fd, struct sockaddr *name, socklen_t *namelen
+ )
+{
+    return getsockname(fd, name, namelen);
+}
+
+
+int __real_getpeername(int fd, struct sockaddr *name, socklen_t *namelen
+ )
+{
+    return getpeername(fd, name, namelen);
+}
+
+
+int __real_shutdown(int fd, int how)
+{
+    return shutdown(fd, how);
+}

Reply via email to