diff options
author | nwhitehorn <nwhitehorn@FreeBSD.org> | 2010-03-11 14:49:06 +0000 |
---|---|---|
committer | nwhitehorn <nwhitehorn@FreeBSD.org> | 2010-03-11 14:49:06 +0000 |
commit | 142a4d29938aa4f7dde8d4ae621c479cc53fda36 (patch) | |
tree | e7bb2301107c48074cb0dbfffd43ee1f7e425d97 /sys/kern/sys_generic.c | |
parent | d937b522a1d72eb6b270db5bf368d3fd1a79ebcf (diff) | |
download | FreeBSD-src-142a4d29938aa4f7dde8d4ae621c479cc53fda36.zip FreeBSD-src-142a4d29938aa4f7dde8d4ae621c479cc53fda36.tar.gz |
Provide groundwork for 32-bit binary compatibility on non-x86 platforms,
for upcoming 64-bit PowerPC and MIPS support. This renames the COMPAT_IA32
option to COMPAT_FREEBSD32, removes some IA32-specific code from MI parts
of the kernel and enhances the freebsd32 compatibility code to support
big-endian platforms.
Reviewed by: kib, jhb
Diffstat (limited to 'sys/kern/sys_generic.c')
-rw-r--r-- | sys/kern/sys_generic.c | 34 |
1 files changed, 32 insertions, 2 deletions
diff --git a/sys/kern/sys_generic.c b/sys/kern/sys_generic.c index b34af61..eaefd9c 100644 --- a/sys/kern/sys_generic.c +++ b/sys/kern/sys_generic.c @@ -878,9 +878,10 @@ kern_select(struct thread *td, int nd, fd_set *fd_in, fd_set *fd_ou, sbp = selbits; #define getbits(name, x) \ do { \ - if (name == NULL) \ + if (name == NULL) { \ ibits[x] = NULL; \ - else { \ + obits[x] = NULL; \ + } else { \ ibits[x] = sbp + nbufbytes / 2 / sizeof *sbp; \ obits[x] = sbp; \ sbp += ncpbytes / sizeof *sbp; \ @@ -895,6 +896,28 @@ kern_select(struct thread *td, int nd, fd_set *fd_in, fd_set *fd_ou, getbits(fd_ou, 1); getbits(fd_ex, 2); #undef getbits + +#if BYTE_ORDER == BIG_ENDIAN && defined(__LP64__) + /* + * XXX: swizzle_fdset assumes that if abi_nfdbits != NFDBITS, + * we are running under 32-bit emulation. This should be more + * generic. + */ +#define swizzle_fdset(bits) \ + if (abi_nfdbits != NFDBITS && bits != NULL) { \ + int i; \ + for (i = 0; i < ncpbytes / sizeof *sbp; i++) \ + bits[i] = (bits[i] >> 32) | (bits[i] << 32); \ + } +#else +#define swizzle_fdset(bits) +#endif + + /* Make sure the bit order makes it through an ABI transition */ + swizzle_fdset(ibits[0]); + swizzle_fdset(ibits[1]); + swizzle_fdset(ibits[2]); + if (nbufbytes != 0) bzero(selbits, nbufbytes / 2); @@ -941,6 +964,13 @@ done: error = EINTR; if (error == EWOULDBLOCK) error = 0; + + /* swizzle bit order back, if necessary */ + swizzle_fdset(obits[0]); + swizzle_fdset(obits[1]); + swizzle_fdset(obits[2]); +#undef swizzle_fdset + #define putbits(name, x) \ if (name && (error2 = copyout(obits[x], name, ncpubytes))) \ error = error2; |