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);
+}