summaryrefslogtreecommitdiffstats
path: root/sys/kern/imgact_aout.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/kern/imgact_aout.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/kern/imgact_aout.c')
-rw-r--r--sys/kern/imgact_aout.c83
1 files changed, 69 insertions, 14 deletions
diff --git a/sys/kern/imgact_aout.c b/sys/kern/imgact_aout.c
index a783c41..2f168d8 100644
--- a/sys/kern/imgact_aout.c
+++ b/sys/kern/imgact_aout.c
@@ -32,6 +32,7 @@ __FBSDID("$FreeBSD$");
#include <sys/imgact.h>
#include <sys/imgact_aout.h>
#include <sys/kernel.h>
+#include <sys/limits.h>
#include <sys/lock.h>
#include <sys/malloc.h>
#include <sys/mutex.h>
@@ -52,9 +53,18 @@ __FBSDID("$FreeBSD$");
#include <vm/vm_object.h>
#include <vm/vm_param.h>
+#ifdef __amd64__
+#include <compat/freebsd32/freebsd32_signal.h>
+#include <compat/freebsd32/freebsd32_util.h>
+#include <compat/freebsd32/freebsd32_proto.h>
+#include <compat/freebsd32/freebsd32_syscall.h>
+#include <compat/ia32/ia32_signal.h>
+#endif
+
static int exec_aout_imgact(struct image_params *imgp);
static int aout_fixup(register_t **stack_base, struct image_params *imgp);
+#if defined(__i386__)
struct sysentvec aout_sysvec = {
.sv_size = SYS_MAXSYSCALL,
.sv_table = sysent,
@@ -83,31 +93,69 @@ struct sysentvec aout_sysvec = {
.sv_setregs = exec_setregs,
.sv_fixlimit = NULL,
.sv_maxssiz = NULL,
- .sv_flags = SV_ABI_FREEBSD | SV_AOUT |
-#if defined(__i386__)
- SV_IA32 | SV_ILP32
-#else
-#error Choose SV_XXX flags for the platform
-#endif
- ,
+ .sv_flags = SV_ABI_FREEBSD | SV_AOUT | SV_IA32 | SV_ILP32,
.sv_set_syscall_retval = cpu_set_syscall_retval,
.sv_fetch_syscall_args = cpu_fetch_syscall_args,
.sv_syscallnames = syscallnames,
.sv_schedtail = NULL,
};
+#elif defined(__amd64__)
+
+#define AOUT32_USRSTACK 0xbfc0000
+#define AOUT32_PS_STRINGS \
+ (AOUT32_USRSTACK - sizeof(struct freebsd32_ps_strings))
+
+extern const char *freebsd32_syscallnames[];
+extern u_long ia32_maxssiz;
+
+struct sysentvec aout_sysvec = {
+ .sv_size = FREEBSD32_SYS_MAXSYSCALL,
+ .sv_table = freebsd32_sysent,
+ .sv_mask = 0,
+ .sv_sigsize = 0,
+ .sv_sigtbl = NULL,
+ .sv_errsize = 0,
+ .sv_errtbl = NULL,
+ .sv_transtrap = NULL,
+ .sv_fixup = aout_fixup,
+ .sv_sendsig = ia32_sendsig,
+ .sv_sigcode = ia32_sigcode,
+ .sv_szsigcode = &sz_ia32_sigcode,
+ .sv_prepsyscall = NULL,
+ .sv_name = "FreeBSD a.out",
+ .sv_coredump = NULL,
+ .sv_imgact_try = NULL,
+ .sv_minsigstksz = MINSIGSTKSZ,
+ .sv_pagesize = IA32_PAGE_SIZE,
+ .sv_minuser = 0,
+ .sv_maxuser = AOUT32_USRSTACK,
+ .sv_usrstack = AOUT32_USRSTACK,
+ .sv_psstrings = AOUT32_PS_STRINGS,
+ .sv_stackprot = VM_PROT_ALL,
+ .sv_copyout_strings = freebsd32_copyout_strings,
+ .sv_setregs = ia32_setregs,
+ .sv_fixlimit = ia32_fixlimit,
+ .sv_maxssiz = &ia32_maxssiz,
+ .sv_flags = SV_ABI_FREEBSD | SV_AOUT | SV_IA32 | SV_ILP32,
+ .sv_set_syscall_retval = ia32_set_syscall_retval,
+ .sv_fetch_syscall_args = ia32_fetch_syscall_args,
+ .sv_syscallnames = freebsd32_syscallnames,
+};
+#else
+#error "Port me"
+#endif
+
static int
-aout_fixup(stack_base, imgp)
- register_t **stack_base;
- struct image_params *imgp;
+aout_fixup(register_t **stack_base, struct image_params *imgp)
{
- return (suword(--(*stack_base), imgp->args->argc));
+ *(char **)stack_base -= sizeof(uint32_t);
+ return (suword(*stack_base, imgp->args->argc));
}
static int
-exec_aout_imgact(imgp)
- struct image_params *imgp;
+exec_aout_imgact(struct image_params *imgp)
{
const struct exec *a_out = (const struct exec *) imgp->image_header;
struct vmspace *vmspace;
@@ -175,7 +223,14 @@ exec_aout_imgact(imgp)
a_out->a_entry >= virtual_offset + a_out->a_text ||
/* text and data size must each be page rounded */
- a_out->a_text & PAGE_MASK || a_out->a_data & PAGE_MASK)
+ a_out->a_text & PAGE_MASK || a_out->a_data & PAGE_MASK
+
+#ifdef __amd64__
+ ||
+ /* overflows */
+ virtual_offset + a_out->a_text + a_out->a_data + bss_size > UINT_MAX
+#endif
+ )
return (-1);
/* text + data can't exceed file size */
OpenPOWER on IntegriCloud