summaryrefslogtreecommitdiffstats
path: root/sys/compat/freebsd32/freebsd32_misc.c
diff options
context:
space:
mode:
authorkib <kib@FreeBSD.org>2011-04-01 11:16:29 +0000
committerkib <kib@FreeBSD.org>2011-04-01 11:16:29 +0000
commit7c2eaa21fe792c26e223a2f36a4f5c00fdaf52d8 (patch)
tree601aa0131bd58a0facc71b1b7c7b138597686fbe /sys/compat/freebsd32/freebsd32_misc.c
parent6d6007bc145d7665435f03f2ff2043e14240d09e (diff)
downloadFreeBSD-src-7c2eaa21fe792c26e223a2f36a4f5c00fdaf52d8.zip
FreeBSD-src-7c2eaa21fe792c26e223a2f36a4f5c00fdaf52d8.tar.gz
Add support for executing the FreeBSD 1/i386 a.out binaries on amd64.
In particular: - implement compat shims for old stat(2) variants and ogetdirentries(2); - implement delivery of signals with ancient stack frame layout and corresponding sigreturn(2); - implement old getpagesize(2); - provide a user-mode trampoline and LDT call gate for lcall $7,$0; - port a.out image activator and connect it to the build as a module on amd64. The changes are hidden under COMPAT_43. MFC after: 1 month
Diffstat (limited to 'sys/compat/freebsd32/freebsd32_misc.c')
-rw-r--r--sys/compat/freebsd32/freebsd32_misc.c100
1 files changed, 97 insertions, 3 deletions
diff --git a/sys/compat/freebsd32/freebsd32_misc.c b/sys/compat/freebsd32/freebsd32_misc.c
index e751147..5772c0e 100644
--- a/sys/compat/freebsd32/freebsd32_misc.c
+++ b/sys/compat/freebsd32/freebsd32_misc.c
@@ -1454,6 +1454,29 @@ freebsd32_ftruncate(struct thread *td, struct freebsd32_ftruncate_args *uap)
return (ftruncate(td, &ap));
}
+#ifdef COMPAT_43
+int
+ofreebsd32_getdirentries(struct thread *td,
+ struct ofreebsd32_getdirentries_args *uap)
+{
+ struct ogetdirentries_args ap;
+ int error;
+ long loff;
+ int32_t loff_cut;
+
+ ap.fd = uap->fd;
+ ap.buf = uap->buf;
+ ap.count = uap->count;
+ ap.basep = NULL;
+ error = kern_ogetdirentries(td, &ap, &loff);
+ if (error == 0) {
+ loff_cut = loff;
+ error = copyout(&loff_cut, uap->basep, sizeof(int32_t));
+ }
+ return (error);
+}
+#endif
+
int
freebsd32_getdirentries(struct thread *td,
struct freebsd32_getdirentries_args *uap)
@@ -1638,6 +1661,29 @@ copy_stat(struct stat *in, struct stat32 *out)
TS_CP(*in, *out, st_birthtim);
}
+#ifdef COMPAT_43
+static void
+copy_ostat(struct stat *in, struct ostat32 *out)
+{
+
+ CP(*in, *out, st_dev);
+ CP(*in, *out, st_ino);
+ CP(*in, *out, st_mode);
+ CP(*in, *out, st_nlink);
+ CP(*in, *out, st_uid);
+ CP(*in, *out, st_gid);
+ CP(*in, *out, st_rdev);
+ CP(*in, *out, st_size);
+ TS_CP(*in, *out, st_atim);
+ TS_CP(*in, *out, st_mtim);
+ TS_CP(*in, *out, st_ctim);
+ CP(*in, *out, st_blksize);
+ CP(*in, *out, st_blocks);
+ CP(*in, *out, st_flags);
+ CP(*in, *out, st_gen);
+}
+#endif
+
int
freebsd32_stat(struct thread *td, struct freebsd32_stat_args *uap)
{
@@ -1653,6 +1699,23 @@ freebsd32_stat(struct thread *td, struct freebsd32_stat_args *uap)
return (error);
}
+#ifdef COMPAT_43
+int
+ofreebsd32_stat(struct thread *td, struct ofreebsd32_stat_args *uap)
+{
+ struct stat sb;
+ struct ostat32 sb32;
+ int error;
+
+ error = kern_stat(td, uap->path, UIO_USERSPACE, &sb);
+ if (error)
+ return (error);
+ copy_ostat(&sb, &sb32);
+ error = copyout(&sb32, uap->ub, sizeof (sb32));
+ return (error);
+}
+#endif
+
int
freebsd32_fstat(struct thread *td, struct freebsd32_fstat_args *uap)
{
@@ -1668,6 +1731,23 @@ freebsd32_fstat(struct thread *td, struct freebsd32_fstat_args *uap)
return (error);
}
+#ifdef COMPAT_43
+int
+ofreebsd32_fstat(struct thread *td, struct ofreebsd32_fstat_args *uap)
+{
+ struct stat ub;
+ struct ostat32 ub32;
+ int error;
+
+ error = kern_fstat(td, uap->fd, &ub);
+ if (error)
+ return (error);
+ copy_ostat(&ub, &ub32);
+ error = copyout(&ub32, uap->ub, sizeof(ub32));
+ return (error);
+}
+#endif
+
int
freebsd32_fstatat(struct thread *td, struct freebsd32_fstatat_args *uap)
{
@@ -1698,9 +1778,23 @@ freebsd32_lstat(struct thread *td, struct freebsd32_lstat_args *uap)
return (error);
}
-/*
- * MPSAFE
- */
+#ifdef COMPAT_43
+int
+ofreebsd32_lstat(struct thread *td, struct ofreebsd32_lstat_args *uap)
+{
+ struct stat sb;
+ struct ostat32 sb32;
+ int error;
+
+ error = kern_lstat(td, uap->path, UIO_USERSPACE, &sb);
+ if (error)
+ return (error);
+ copy_ostat(&sb, &sb32);
+ error = copyout(&sb32, uap->ub, sizeof (sb32));
+ return (error);
+}
+#endif
+
int
freebsd32_sysctl(struct thread *td, struct freebsd32_sysctl_args *uap)
{
OpenPOWER on IntegriCloud