Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/lib/librumphijack Rewrite to declare most dual-kernel calls ...
details: https://anonhg.NetBSD.org/src/rev/1a8256b94c6a
branches: trunk
changeset: 761356:1a8256b94c6a
user: pooka <pooka%NetBSD.org@localhost>
date: Tue Jan 25 12:18:33 2011 +0000
description:
Rewrite to declare most dual-kernel calls with macros. This helps
with adding new calls and makes all existing fd-accepting hijacked
calls dual-kernel. It would be better to autogenerate the code
from syscalls.master, but this is easier for now.
diffstat:
lib/librumphijack/hijack.c | 742 +++++++++++++++++---------------------------
1 files changed, 293 insertions(+), 449 deletions(-)
diffs (truncated from 954 to 300 lines):
diff -r 6cd4fee703bd -r 1a8256b94c6a lib/librumphijack/hijack.c
--- a/lib/librumphijack/hijack.c Tue Jan 25 12:14:02 2011 +0000
+++ b/lib/librumphijack/hijack.c Tue Jan 25 12:18:33 2011 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: hijack.c,v 1.16 2011/01/19 11:27:01 pooka Exp $ */
+/* $NetBSD: hijack.c,v 1.17 2011/01/25 12:18:33 pooka Exp $ */
/*-
* Copyright (c) 2011 Antti Kantee. All Rights Reserved.
@@ -26,7 +26,7 @@
*/
#include <sys/cdefs.h>
-__RCSID("$NetBSD: hijack.c,v 1.16 2011/01/19 11:27:01 pooka Exp $");
+__RCSID("$NetBSD: hijack.c,v 1.17 2011/01/25 12:18:33 pooka Exp $");
#include <sys/param.h>
#include <sys/types.h>
@@ -53,160 +53,81 @@
#include <time.h>
#include <unistd.h>
-enum { RUMPCALL_SOCKET, RUMPCALL_ACCEPT, RUMPCALL_BIND, RUMPCALL_CONNECT,
- RUMPCALL_GETPEERNAME, RUMPCALL_GETSOCKNAME, RUMPCALL_LISTEN,
- RUMPCALL_RECVFROM, RUMPCALL_RECVMSG,
- RUMPCALL_SENDTO, RUMPCALL_SENDMSG,
- RUMPCALL_GETSOCKOPT, RUMPCALL_SETSOCKOPT,
- RUMPCALL_SHUTDOWN,
- RUMPCALL_READ, RUMPCALL_READV,
- RUMPCALL_WRITE, RUMPCALL_WRITEV,
- RUMPCALL_IOCTL, RUMPCALL_FCNTL,
- RUMPCALL_CLOSE,
- RUMPCALL_POLLTS,
- RUMPCALL__NUM
+enum dualcall {
+ DUALCALL_WRITE, DUALCALL_WRITEV,
+ DUALCALL_IOCTL, DUALCALL_FCNTL,
+ DUALCALL_SOCKET, DUALCALL_ACCEPT, DUALCALL_BIND, DUALCALL_CONNECT,
+ DUALCALL_GETPEERNAME, DUALCALL_GETSOCKNAME, DUALCALL_LISTEN,
+ DUALCALL_RECVFROM, DUALCALL_RECVMSG,
+ DUALCALL_SENDTO, DUALCALL_SENDMSG,
+ DUALCALL_GETSOCKOPT, DUALCALL_SETSOCKOPT,
+ DUALCALL_SHUTDOWN,
+ DUALCALL_READ, DUALCALL_READV,
+ DUALCALL_DUP2, DUALCALL_CLOSE,
+ DUALCALL_POLLTS,
+ DUALCALL__NUM
};
#define RSYS_STRING(a) __STRING(a)
#define RSYS_NAME(a) RSYS_STRING(__CONCAT(RUMP_SYS_RENAME_,a))
-const char *sysnames[] = {
- RSYS_NAME(SOCKET),
- RSYS_NAME(ACCEPT),
- RSYS_NAME(BIND),
- RSYS_NAME(CONNECT),
- RSYS_NAME(GETPEERNAME),
- RSYS_NAME(GETSOCKNAME),
- RSYS_NAME(LISTEN),
- RSYS_NAME(RECVFROM),
- RSYS_NAME(RECVMSG),
- RSYS_NAME(SENDTO),
- RSYS_NAME(SENDMSG),
- RSYS_NAME(GETSOCKOPT),
- RSYS_NAME(SETSOCKOPT),
- RSYS_NAME(SHUTDOWN),
- RSYS_NAME(READ),
- RSYS_NAME(READV),
- RSYS_NAME(WRITE),
- RSYS_NAME(WRITEV),
- RSYS_NAME(IOCTL),
- RSYS_NAME(FCNTL),
- RSYS_NAME(CLOSE),
- RSYS_NAME(POLLTS),
-};
-
-static int (*host_socket)(int, int, int);
-static int (*host_connect)(int, const struct sockaddr *, socklen_t);
-static int (*host_bind)(int, const struct sockaddr *, socklen_t);
-static int (*host_listen)(int, int);
-static int (*host_accept)(int, struct sockaddr *, socklen_t *);
-static int (*host_getpeername)(int, struct sockaddr *, socklen_t *);
-static int (*host_getsockname)(int, struct sockaddr *, socklen_t *);
-static int (*host_setsockopt)(int, int, int, const void *, socklen_t);
-
-static ssize_t (*host_read)(int, void *, size_t);
-static ssize_t (*host_readv)(int, const struct iovec *, int);
-static ssize_t (*host_write)(int, const void *, size_t);
-static ssize_t (*host_writev)(int, const struct iovec *, int);
-static int (*host_ioctl)(int, unsigned long, ...);
-static int (*host_fcntl)(int, int, ...);
-static int (*host_close)(int);
-static int (*host_pollts)(struct pollfd *, nfds_t,
- const struct timespec *, const sigset_t *);
-static pid_t (*host_fork)(void);
-static int (*host_dup2)(int, int);
-static int (*host_shutdown)(int, int);
-/* XXX */
-static void *host_sendto;
-static void *host_recvfrom;
-
-static void *rumpcalls[RUMPCALL__NUM];
-
/*
* Would be nice to get this automatically in sync with libc.
* Also, this does not work for compat-using binaries!
*/
-
#if !__NetBSD_Prereq__(5,99,7)
-#define SELECT select
-#define POLLTS pollts
-#define POLL poll
+#define LIBCSELECT select
+#define LIBCPOLLTS pollts
+#define LIBCPOLL poll
#else
-#define SELECT __select50
-#define POLLTS __pollts50
-#define POLL __poll50
+#define LIBCSELECT __select50
+#define LIBCPOLLTS __pollts50
+#define LIBCPOLL __poll50
+#endif
int SELECT(int, fd_set *, fd_set *, fd_set *, struct timeval *);
int POLLTS(struct pollfd *, nfds_t, const struct timespec *, const sigset_t *);
int POLL(struct pollfd *, nfds_t, int);
-#endif
-
-/*
- * This is called from librumpclient in case of LD_PRELOAD.
- * It ensures correct RTLD_NEXT.
- */
-static void *
-hijackdlsym(void *handle, const char *symbol)
-{
-
- return dlsym(handle, symbol);
-}
-
-/* low calorie sockets? */
-static bool hostlocalsockets = true;
-
-static void __attribute__((constructor))
-rcinit(void)
-{
- int (*rumpcinit)(void);
- void **rumpcdlsym;
- void *hand;
- int i;
-
- hand = dlopen("librumpclient.so", RTLD_LAZY|RTLD_GLOBAL);
- if (!hand)
- err(1, "cannot open librumpclient.so");
- rumpcinit = dlsym(hand, "rumpclient_init");
- _DIAGASSERT(rumpcinit);
-
- rumpcdlsym = dlsym(hand, "rumpclient_dlsym");
- *rumpcdlsym = hijackdlsym;
- host_socket = dlsym(RTLD_NEXT, "__socket30");
- host_listen = dlsym(RTLD_NEXT, "listen");
- host_connect = dlsym(RTLD_NEXT, "connect");
- host_bind = dlsym(RTLD_NEXT, "bind");
- host_accept = dlsym(RTLD_NEXT, "accept");
- host_getpeername = dlsym(RTLD_NEXT, "getpeername");
- host_getsockname = dlsym(RTLD_NEXT, "getsockname");
- host_setsockopt = dlsym(RTLD_NEXT, "setsockopt");
+#define S(a) __STRING(a)
+struct sysnames {
+ enum dualcall scm_callnum;
+ const char *scm_hostname;
+ const char *scm_rumpname;
+} syscnames[] = {
+ { DUALCALL_SOCKET, "__socket30", RSYS_NAME(SOCKET) },
+ { DUALCALL_ACCEPT, "accept", RSYS_NAME(ACCEPT) },
+ { DUALCALL_BIND, "bind", RSYS_NAME(BIND) },
+ { DUALCALL_CONNECT, "connect", RSYS_NAME(CONNECT) },
+ { DUALCALL_GETPEERNAME, "getpeername", RSYS_NAME(GETPEERNAME) },
+ { DUALCALL_GETSOCKNAME, "getsockname", RSYS_NAME(GETSOCKNAME) },
+ { DUALCALL_LISTEN, "listen", RSYS_NAME(LISTEN) },
+ { DUALCALL_RECVFROM, "recvfrom", RSYS_NAME(RECVFROM) },
+ { DUALCALL_RECVMSG, "recvmsg", RSYS_NAME(RECVMSG) },
+ { DUALCALL_SENDTO, "sendto", RSYS_NAME(SENDTO) },
+ { DUALCALL_SENDMSG, "sendmsg", RSYS_NAME(SENDMSG) },
+ { DUALCALL_GETSOCKOPT, "getsockopt", RSYS_NAME(GETSOCKOPT) },
+ { DUALCALL_SETSOCKOPT, "setsockopt", RSYS_NAME(SETSOCKOPT) },
+ { DUALCALL_SHUTDOWN, "shutdown", RSYS_NAME(SHUTDOWN) },
+ { DUALCALL_READ, "read", RSYS_NAME(READ) },
+ { DUALCALL_READV, "readv", RSYS_NAME(READV) },
+ { DUALCALL_WRITE, "write", RSYS_NAME(WRITE) },
+ { DUALCALL_WRITEV, "writev", RSYS_NAME(WRITEV) },
+ { DUALCALL_IOCTL, "ioctl", RSYS_NAME(IOCTL) },
+ { DUALCALL_FCNTL, "fcntl", RSYS_NAME(FCNTL) },
+ { DUALCALL_DUP2, "dup2", RSYS_NAME(DUP2) },
+ { DUALCALL_CLOSE, "close", RSYS_NAME(CLOSE) },
+ { DUALCALL_POLLTS, S(LIBCPOLLTS), RSYS_NAME(POLLTS) },
+};
+#undef S
- host_read = dlsym(RTLD_NEXT, "read");
- host_readv = dlsym(RTLD_NEXT, "readv");
- host_write = dlsym(RTLD_NEXT, "write");
- host_writev = dlsym(RTLD_NEXT, "writev");
- host_ioctl = dlsym(RTLD_NEXT, "ioctl");
- host_fcntl = dlsym(RTLD_NEXT, "fcntl");
- host_close = dlsym(RTLD_NEXT, "close");
- host_pollts = dlsym(RTLD_NEXT, "pollts");
- host_fork = dlsym(RTLD_NEXT, "fork");
- host_dup2 = dlsym(RTLD_NEXT, "dup2");
- host_shutdown = dlsym(RTLD_NEXT, "shutdown");
- host_sendto = dlsym(RTLD_NEXT, "sendto");
- host_recvfrom = dlsym(RTLD_NEXT, "recvfrom");
+struct bothsys {
+ void *bs_host;
+ void *bs_rump;
+} syscalls[DUALCALL__NUM];
+#define GETSYSCALL(which, name) syscalls[DUALCALL_##name].bs_##which
- for (i = 0; i < RUMPCALL__NUM; i++) {
- rumpcalls[i] = dlsym(hand, sysnames[i]);
- if (!rumpcalls[i]) {
- fprintf(stderr, "rumphijack: cannot find symbol: %s\n",
- sysnames[i]);
- exit(1);
- }
- }
-
- if (rumpcinit() == -1)
- err(1, "rumpclient init");
-}
+pid_t (*host_fork)(void);
static unsigned dup2mask;
#define ISDUP2D(fd) (1<<(fd) & dup2mask)
@@ -231,6 +152,84 @@
#define DPRINTF(x)
#endif
+#define FDCALL(type, name, rcname, args, proto, vars) \
+type name args \
+{ \
+ type (*fun) proto; \
+ \
+ if (fd_isrump(fd)) { \
+ fun = syscalls[rcname].bs_rump; \
+ fd = fd_host2rump(fd); \
+ } else { \
+ fun = syscalls[rcname].bs_host; \
+ } \
+ \
+ return fun vars; \
+}
+
+/*
+ * This is called from librumpclient in case of LD_PRELOAD.
+ * It ensures correct RTLD_NEXT.
+ */
+static void *
+hijackdlsym(void *handle, const char *symbol)
+{
+
+ return dlsym(handle, symbol);
+}
+
+/* low calorie sockets? */
+static bool hostlocalsockets = true;
+
+static void __attribute__((constructor))
+rcinit(void)
+{
+ int (*rumpcinit)(void);
+ void **rumpcdlsym;
+ void *hand;
+ int i, j;
+
+ hand = dlopen("librumpclient.so", RTLD_LAZY|RTLD_GLOBAL);
+ if (!hand)
+ err(1, "cannot open librumpclient.so");
+ rumpcinit = dlsym(hand, "rumpclient_init");
+ _DIAGASSERT(rumpcinit);
+
+ rumpcdlsym = dlsym(hand, "rumpclient_dlsym");
+ *rumpcdlsym = hijackdlsym;
+ host_fork = dlsym(RTLD_NEXT, "fork");
+
+ /*
+ * In theory cannot print anything during lookups because
+ * we might not have the call vector set up. so, the errx()
+ * is a bit of a strech, but it might work.
+ */
+
+ for (i = 0; i < DUALCALL__NUM; i++) {
+ /* build runtime O(1) access */
+ for (j = 0; j < __arraycount(syscnames); j++) {
+ if (syscnames[j].scm_callnum == i)
+ break;
+ }
+
Home |
Main Index |
Thread Index |
Old Index