Minimal set of diffs from the i386 bits to the AlphaLinux.

Submitted by:	gallatin (content, minimization by me)
This commit is contained in:
David E. O'Brien 2000-09-06 19:26:17 +00:00
parent c5930ee45a
commit 78a7c549ee
3 changed files with 215 additions and 497 deletions

View file

@ -28,10 +28,10 @@
* $FreeBSD$
*/
#ifndef _I386_LINUX_LINUX_H_
#define _I386_LINUX_LINUX_H_
#ifndef _ALPHA_LINUX_LINUX_H_
#define _ALPHA_LINUX_LINUX_H_
#include <i386/linux/linux_syscall.h>
#include <alpha/linux/linux_syscall.h>
#ifdef MALLOC_DECLARE
MALLOC_DECLARE(M_LINUX);
@ -55,19 +55,19 @@ MALLOC_DECLARE(M_LINUX);
#define LINUX_RLIMIT_STACK 3
#define LINUX_RLIMIT_CORE 4
#define LINUX_RLIMIT_RSS 5
#define LINUX_RLIMIT_NPROC 6
#define LINUX_RLIMIT_NOFILE 7
#define LINUX_RLIMIT_MEMLOCK 8
#define LINUX_RLIMIT_AS 9 /* address space limit */
#define LINUX_RLIMIT_NPROC 8
#define LINUX_RLIMIT_NOFILE 6
#define LINUX_RLIMIT_AS 7 /* address space limit */
#define LINUX_RLIMIT_MEMLOCK 9
#define LINUX_RLIM_NLIMITS 10
/* mmap options */
#define LINUX_MAP_SHARED 0x0001
#define LINUX_MAP_PRIVATE 0x0002
#define LINUX_MAP_FIXED 0x0010
#define LINUX_MAP_ANON 0x0020
#define LINUX_MAP_GROWSDOWN 0x0100
#define LINUX_MAP_FIXED 0x0100
#define LINUX_MAP_ANON 0x0010
#define LINUX_MAP_GROWSDOWN 0x1000
typedef char * linux_caddr_t;
typedef long linux_clock_t;
@ -79,12 +79,12 @@ typedef u_short linux_mode_t;
typedef u_short linux_nlink_t;
typedef long linux_off_t;
typedef int linux_pid_t;
typedef u_int linux_size_t;
/*typedef u_int linux_size_t; */
typedef long linux_time_t;
typedef u_short linux_uid_t;
typedef struct {
long val[2];
int val[2];
} linux_fsid_t;
struct linux_new_utsname {
@ -137,15 +137,17 @@ struct linux_new_utsname {
#define LINUX_SIGTBLSZ 31
/* sigaction flags */
#define LINUX_SA_NOCLDSTOP 0x00000001
#define LINUX_SA_NOCLDWAIT 0x00000002
#define LINUX_SA_SIGINFO 0x00000004
#define LINUX_SA_NOCLDSTOP 0x00000004
#define LINUX_SA_NOCLDWAIT 0x00000020
#define LINUX_SA_SIGINFO 0x00000040
#define LINUX_SA_RESTORER 0x04000000
#define LINUX_SA_ONSTACK 0x08000000
#define LINUX_SA_RESTART 0x10000000
#define LINUX_SA_ONSTACK 0x00000001
#define LINUX_SA_RESTART 0x00000002
#define LINUX_SA_INTERRUPT 0x20000000
#define LINUX_SA_NOMASK 0x40000000
#define LINUX_SA_ONESHOT 0x80000000
#define LINUX_SA_NOMASK LINUX_SA_NODEFER
#define LINUX_SA_ONESHOT LINUX_SA_RESETHAND
#define LINUX_SA_NODEFER 0x00000008
#define LINUX_SA_RESETHAND 0x00000010
/* sigprocmask actions */
#define LINUX_SIG_BLOCK 0
@ -157,14 +159,12 @@ struct linux_new_utsname {
#define LINUX_SIGISMEMBER(set, sig) SIGISMEMBER(set, sig)
#define LINUX_SIGADDSET(set, sig) SIGADDSET(set, sig)
/* sigaltstack */
#define LINUX_MINSIGSTKSZ 2048
typedef void (*linux_handler_t)(int);
typedef u_long linux_osigset_t;
typedef struct {
u_int __bits[2];
/* u_long __bits[1];*/
} linux_sigset_t;
typedef struct {
@ -181,36 +181,36 @@ typedef struct {
linux_sigset_t lsa_mask;
} linux_sigaction_t;
#if 0
typedef struct {
void *ss_sp;
int ss_flags;
linux_size_t ss_size;
} linux_stack_t;
#endif
/* The Linux sigcontext, pretty much a standard 386 trapframe. */
/*
* The Linux sigcontext
*/
struct linux_sigcontext {
int sc_gs;
int sc_fs;
int sc_es;
int sc_ds;
int sc_edi;
int sc_esi;
int sc_ebp;
int sc_esp;
int sc_ebx;
int sc_edx;
int sc_ecx;
int sc_eax;
int sc_trapno;
int sc_err;
int sc_eip;
int sc_cs;
int sc_eflags;
int sc_esp_at_signal;
int sc_ss;
int sc_387;
int sc_mask;
int sc_cr2;
long sc_onstack;
long sc_mask;
long sc_pc;
long sc_ps;
long sc_regs[32];
long sc_ownedfp;
long sc_fpregs[32];
u_long sc_fpcr;
u_long sc_fp_control;
u_long sc_reserved1, sc_reserved2;
u_long sc_ssize;
char * sc_sbase;
u_long sc_traparg_a0;
u_long sc_traparg_a1;
u_long sc_traparg_a2;
u_long sc_fp_trap_pc;
u_long sc_fp_trigger_sum;
u_long sc_fp_trigger_inst;
};
/*
@ -225,8 +225,6 @@ struct linux_sigframe {
linux_handler_t sf_handler;
};
extern int bsd_to_linux_signal[];
extern int linux_to_bsd_signal[];
extern struct sysentvec linux_sysvec;
extern struct sysentvec elf_linux_sysvec;
@ -255,14 +253,14 @@ int linux_ioctl_unregister_handlers(struct linker_set *s);
#define LINUX_O_RDONLY 00
#define LINUX_O_WRONLY 01
#define LINUX_O_RDWR 02
#define LINUX_O_CREAT 0100
#define LINUX_O_EXCL 0200
#define LINUX_O_NOCTTY 0400
#define LINUX_O_TRUNC 01000
#define LINUX_O_APPEND 02000
#define LINUX_O_NONBLOCK 04000
#define LINUX_O_CREAT 01000
#define LINUX_O_EXCL 04000
#define LINUX_O_NOCTTY 010000
#define LINUX_O_TRUNC 02000
#define LINUX_O_APPEND 010
#define LINUX_O_NONBLOCK 04
#define LINUX_O_NDELAY LINUX_O_NONBLOCK
#define LINUX_O_SYNC 010000
#define LINUX_O_SYNC 040000
#define LINUX_FASYNC 020000
#define LINUX_F_DUPFD 0
@ -411,11 +409,23 @@ struct linux_ifreq {
int ifru_mtu;
struct linux_ifmap ifru_map;
char ifru_slave[LINUX_IFNAMSIZ]; /* Just fits the size */
linux_caddr_t ifru_data;
/* linux_caddr_t ifru_data; */
caddr_t ifru_data;
} ifr_ifru;
};
#define ifr_name ifr_ifrn.ifrn_name /* interface name */
#define ifr_hwaddr ifr_ifru.ifru_hwaddr /* MAC address */
#endif /* !_I386_LINUX_LINUX_H_ */
extern char linux_sigcode[];
extern int linux_szsigcode;
/*extern const char linux_emul_path[];*/
extern struct sysent linux_sysent[LINUX_SYS_MAXSYSCALL];
/* dummy struct definitions */
struct image_params;
struct trapframe;
#endif /* !_ALPHA_LINUX_LINUX_H_ */

View file

@ -209,56 +209,56 @@
/*
* termio
*/
#define LINUX_TCGETS 0x5401
#define LINUX_TCSETS 0x5402
#define LINUX_TCSETSW 0x5403
#define LINUX_TCSETSF 0x5404
#define LINUX_TCGETA 0x5405
#define LINUX_TCSETA 0x5406
#define LINUX_TCSETAW 0x5407
#define LINUX_TCSETAF 0x5408
#define LINUX_TCSBRK 0x5409
#define LINUX_TCXONC 0x540A
#define LINUX_TCFLSH 0x540B
#define LINUX_TCGETS 0x7413
#define LINUX_TCSETS 0x7414
#define LINUX_TCSETSW 0x7415
#define LINUX_TCSETSF 0x7416
#define LINUX_TCGETA 0x7417
#define LINUX_TCSETA 0x7418
#define LINUX_TCSETAW 0x7419
#define LINUX_TCSETAF 0x741c
#define LINUX_TCSBRK 0x741d
#define LINUX_TCXONC 0x741e
#define LINUX_TCFLSH 0x741f
#define LINUX_TIOCEXCL 0x540C
#define LINUX_TIOCNXCL 0x540D
#define LINUX_TIOCSCTTY 0x540E
#define LINUX_TIOCGPGRP 0x540F
#define LINUX_TIOCSPGRP 0x5410
#define LINUX_TIOCGPGRP 0x7477
#define LINUX_TIOCSPGRP 0x7476
#define LINUX_TIOCOUTQ 0x5411
#define LINUX_TIOCSTI 0x5412
#define LINUX_TIOCGWINSZ 0x5413
#define LINUX_TIOCSWINSZ 0x5414
#define LINUX_TIOCGWINSZ 0x7468
#define LINUX_TIOCSWINSZ 0x7467
#define LINUX_TIOCMGET 0x5415
#define LINUX_TIOCMBIS 0x5416
#define LINUX_TIOCMBIC 0x5417
#define LINUX_TIOCMSET 0x5418
#define LINUX_TIOCGSOFTCAR 0x5419
#define LINUX_TIOCSSOFTCAR 0x541A
#define LINUX_FIONREAD 0x541B
#define LINUX_FIONREAD 0x667f
#define LINUX_TIOCINQ FIONREAD
#define LINUX_TIOCLINUX 0x541C
#define LINUX_TIOCCONS 0x541D
#define LINUX_TIOCGSERIAL 0x541E
#define LINUX_TIOCSSERIAL 0x541F
#define LINUX_TIOCPKT 0x5420
#define LINUX_FIONBIO 0x5421
#define LINUX_FIONBIO 0x667e
#define LINUX_TIOCNOTTY 0x5422
#define LINUX_TIOCSETD 0x5423
#define LINUX_TIOCGETD 0x5424
#define LINUX_TCSBRKP 0x5425
#define LINUX_TIOCTTYGSTRUCT 0x5426
#define LINUX_FIONCLEX 0x5450
#define LINUX_FIOCLEX 0x5451
#define LINUX_FIOASYNC 0x5452
#define LINUX_FIOCLEX 0x6601
#define LINUX_FIONCLEX 0x6602
#define LINUX_FIOASYNC 0x667d
#define LINUX_TIOCSERCONFIG 0x5453
#define LINUX_TIOCSERGWILD 0x5454
#define LINUX_TIOCSERSWILD 0x5455
#define LINUX_TIOCGLCKTRMIOS 0x5456
#define LINUX_TIOCSLCKTRMIOS 0x5457
#define LINUX_IOCTL_TERMIO_MIN LINUX_TCGETS
#define LINUX_IOCTL_TERMIO_MAX LINUX_TIOCSLCKTRMIOS
#define LINUX_IOCTL_TERMIO_MIN LINUX_TIOCEXCL
#define LINUX_IOCTL_TERMIO_MAX LINUX_TIOCGPGRP
/* arguments for tcflow() and LINUX_TCXONC */
#define LINUX_TCOOFF 0
@ -278,26 +278,26 @@
#define LINUX_N_PPP 3
/* Linux termio c_cc values */
#define LINUX_VINTR 0
#define LINUX_VQUIT 1
#define LINUX_VERASE 2
#define LINUX_VKILL 3
#define LINUX_VEOF 4
#define LINUX_VTIME 5
#define LINUX_VMIN 6
#define LINUX_VINTR 8
#define LINUX_VQUIT 9
#define LINUX_VWERASE 4
#define LINUX_VKILL 5
#define LINUX_VEOF 0
#define LINUX_VTIME 17
#define LINUX_VMIN 16
#define LINUX_VSWTC 7
#define LINUX_NCC 8
#define LINUX_NCC 19
/* Linux termios c_cc values */
#define LINUX_VSTART 8
#define LINUX_VSTOP 9
#define LINUX_VSUSP 10
#define LINUX_VEOL 11
#define LINUX_VREPRINT 12
#define LINUX_VDISCARD 13
#define LINUX_VWERASE 14
#define LINUX_VLNEXT 15
#define LINUX_VEOL2 16
#define LINUX_VSTART 12
#define LINUX_VSTOP 13
#define LINUX_VSUSP 10
#define LINUX_VEOL 1
#define LINUX_VREPRINT 6
#define LINUX_VDISCARD 15
#define LINUX_VERASE 3
#define LINUX_VLNEXT 14
#define LINUX_VEOL2 2
#define LINUX_NCCS 19
#define LINUX_POSIX_VDISABLE '\0'
@ -306,53 +306,55 @@
#define LINUX_IGNBRK 0x0000001
#define LINUX_BRKINT 0x0000002
#define LINUX_IGNPAR 0x0000004
#define LINUX_PARMRK 0x0000008
#define LINUX_INPCK 0x0000010
#define LINUX_ISTRIP 0x0000020
#define LINUX_INLCR 0x0000040
#define LINUX_IGNCR 0x0000080
#define LINUX_ICRNL 0x0000100
#define LINUX_IUCLC 0x0000200
#define LINUX_IXON 0x0000400
#define LINUX_IXANY 0x0000800
#define LINUX_IXOFF 0x0001000
#define LINUX_IMAXBEL 0x0002000
#define LINUX_PARMRK 0x0000010
#define LINUX_INPCK 0x0000020
#define LINUX_ISTRIP 0x0000040
#define LINUX_INLCR 0x0000100
#define LINUX_IGNCR 0x0000200
#define LINUX_ICRNL 0x0000400
#define LINUX_IUCLC 0x0010000
#define LINUX_IXON 0x0001000
#define LINUX_IXANY 0x0004000
#define LINUX_IXOFF 0x0002000
#define LINUX_IMAXBEL 0x0020000
/* Linux c_oflag masks */
#define LINUX_OPOST 0x0000001
#define LINUX_OLCUC 0x0000002
#define LINUX_ONLCR 0x0000004
#define LINUX_OCRNL 0x0000008
#define LINUX_ONOCR 0x0000010
#define LINUX_ONLRET 0x0000020
#define LINUX_OFILL 0x0000040
#define LINUX_OFDEL 0x0000080
#define LINUX_NLDLY 0x0000100
#define LINUX_OCRNL 0x0000010
#define LINUX_ONOCR 0x0000020
#define LINUX_ONLRET 0x0000040
#define LINUX_OFILL 0x0000100
#define LINUX_OFDEL 0x0000200
#define LINUX_NLDLY 0x0001400
#define LINUX_NL0 0x0000000
#define LINUX_NL1 0x0000100
#define LINUX_CRDLY 0x0000600
#define LINUX_CR0 0x0000000
#define LINUX_CR1 0x0000200
#define LINUX_CR2 0x0000400
#define LINUX_CR3 0x0000600
#define LINUX_TABDLY 0x0001800
#define LINUX_TAB0 0x0000000
#define LINUX_TAB1 0x0000800
#define LINUX_TAB2 0x0001000
#define LINUX_TAB3 0x0001800
#define LINUX_XTABS 0x0001800
#define LINUX_BSDLY 0x0002000
#define LINUX_BS0 0x0000000
#define LINUX_BS1 0x0002000
#define LINUX_VTDLY 0x0004000
#define LINUX_VT0 0x0000000
#define LINUX_VT1 0x0004000
#define LINUX_FFDLY 0x0008000
#define LINUX_FF0 0x0000000
#define LINUX_FF1 0x0008000
#define LINUX_NL1 00000400
#define LINUX_CRDLY 00030000
#define LINUX_CR0 00000000
#define LINUX_CR1 00010000
#define LINUX_CR2 00020000
#define LINUX_CR3 00030000
#define LINUX_TABDLY 00006000
#define LINUX_TAB0 00000000
#define LINUX_TAB1 00002000
#define LINUX_TAB2 00004000
#define LINUX_TAB3 00006000
#define LINUX_XTABS 01000000 /* Hmm.. Linux/i386 considers this part of TABDLY.. */
#define LINUX_BSDLY 00100000
#define LINUX_BS0 00000000
#define LINUX_BS1 00100000
#define LINUX_VTDLY 00200000
#define LINUX_VT0 00000000
#define LINUX_VT1 00200000
#define LINUX_FFDLY 00040000
#define LINUX_FF0 00000000
#define LINUX_FF1 00040000
#define LINUX_NL2 00001000
#define LINUX_NL3 00001400
#define LINUX_CBAUD 0x0000100f
#define LINUX_CBAUD 0000037
#define LINUX_B0 0x00000000
#define LINUX_B50 0x00000001
#define LINUX_B75 0x00000002
@ -371,39 +373,52 @@
#define LINUX_B38400 0x0000000f
#define LINUX_EXTA LINUX_B19200
#define LINUX_EXTB LINUX_B38400
#define LINUX_CBAUDEX 0x00001000
#define LINUX_B57600 0x00001001
#define LINUX_B115200 0x00001002
#define LINUX_CBAUDEX 0x00000000
#define LINUX_B57600 00020
#define LINUX_B115200 00021
#define LINUX_B230400 00022
#define LINUX_B460800 00023
#define LINUX_B500000 00024
#define LINUX_B576000 00025
#define LINUX_B921600 00026
#define LINUX_B1000000 00027
#define LINUX_B1152000 00030
#define LINUX_B1500000 00031
#define LINUX_B2000000 00032
#define LINUX_B2500000 00033
#define LINUX_B3000000 00034
#define LINUX_B3500000 00035
#define LINUX_B4000000 00036
#define LINUX_CSIZE 0x00000030
#define LINUX_CSIZE 00001400
#define LINUX_CS5 0x00000000
#define LINUX_CS6 0x00000010
#define LINUX_CS7 0x00000020
#define LINUX_CS8 0x00000030
#define LINUX_CSTOPB 0x00000040
#define LINUX_CREAD 0x00000080
#define LINUX_PARENB 0x00000100
#define LINUX_PARODD 0x00000200
#define LINUX_HUPCL 0x00000400
#define LINUX_CLOCAL 0x00000800
#define LINUX_CRTSCTS 0x80000000
#define LINUX_CS6 00000400
#define LINUX_CS7 00001000
#define LINUX_CS8 00001400
#define LINUX_CSTOPB 00002000
#define LINUX_CREAD 00004000
#define LINUX_PARENB 00010000
#define LINUX_PARODD 00020000
#define LINUX_HUPCL 00040000
#define LINUX_CLOCAL 00100000
#define LINUX_CRTSCTS 020000000000
/* Linux c_lflag masks */
#define LINUX_ISIG 0x00000001
#define LINUX_ICANON 0x00000002
#define LINUX_XCASE 0x00000004
#define LINUX_ISIG 0x00000080
#define LINUX_ICANON 0x00000100
#define LINUX_XCASE 0x00004000
#define LINUX_ECHO 0x00000008
#define LINUX_ECHOE 0x00000010
#define LINUX_ECHOK 0x00000020
#define LINUX_ECHONL 0x00000040
#define LINUX_NOFLSH 0x00000080
#define LINUX_TOSTOP 0x00000100
#define LINUX_ECHOCTL 0x00000200
#define LINUX_ECHOPRT 0x00000400
#define LINUX_ECHOKE 0x00000800
#define LINUX_FLUSHO 0x00001000
#define LINUX_PENDIN 0x00002000
#define LINUX_IEXTEN 0x00008000
#define LINUX_ECHOE 0x00000002
#define LINUX_ECHOK 0x00000004
#define LINUX_ECHONL 0x00000010
#define LINUX_NOFLSH 0x80000000
#define LINUX_TOSTOP 0x00400000
#define LINUX_ECHOCTL 0x00000040
#define LINUX_ECHOPRT 0x00000020
#define LINUX_ECHOKE 0x00000001
#define LINUX_FLUSHO 0x00800000
#define LINUX_PENDIN 0x20000000
#define LINUX_IEXTEN 0x00000400
/* serial_struct values for TIOC[GS]SERIAL ioctls */
#define LINUX_ASYNC_CLOSING_WAIT_INF 0

View file

@ -52,12 +52,15 @@
#include <sys/kernel.h>
#include <sys/module.h>
#include <machine/cpu.h>
#include <machine/md_var.h>
#include <i386/linux/linux.h>
#include <i386/linux/linux_proto.h>
#include <alpha/linux/linux.h>
#include <alpha/linux/linux_proto.h>
#include <compat/linux/linux_util.h>
#undef szsigcode
MODULE_VERSION(linux, 1);
MODULE_DEPEND(linux, osf1, 1, 1, 1);
MALLOC_DEFINE(M_LINUX, "linux", "Linux mode structures");
@ -67,103 +70,20 @@ MALLOC_DEFINE(M_LINUX, "linux", "Linux mode structures");
#define SHELLMAGIC 0x2321
#endif
extern char linux_sigcode[];
extern int linux_szsigcode;
extern struct sysent linux_sysent[LINUX_SYS_MAXSYSCALL];
extern struct linker_set linux_ioctl_handler_set;
static int linux_fixup __P((register_t **stack_base,
struct image_params *iparams));
static int elf_linux_fixup __P((register_t **stack_base,
static int elf_linux_fixup __P((long **stack_base,
struct image_params *iparams));
static void linux_prepsyscall __P((struct trapframe *tf, int *args,
u_int *code, caddr_t *params));
static void linux_sendsig __P((sig_t catcher, int sig, sigset_t *mask,
u_long code));
/*
* Linux syscalls return negative errno's, we do positive and map them
*/
static int bsd_to_linux_errno[ELAST + 1] = {
-0, -1, -2, -3, -4, -5, -6, -7, -8, -9,
-10, -35, -12, -13, -14, -15, -16, -17, -18, -19,
-20, -21, -22, -23, -24, -25, -26, -27, -28, -29,
-30, -31, -32, -33, -34, -11,-115,-114, -88, -89,
-90, -91, -92, -93, -94, -95, -96, -97, -98, -99,
-100,-101,-102,-103,-104,-105,-106,-107,-108,-109,
-110,-111, -40, -36,-112,-113, -39, -11, -87,-122,
-116, -66, -6, -6, -6, -6, -6, -37, -38, -9,
-6, -6, -43, -42, -75, -6, -84
};
int bsd_to_linux_signal[LINUX_SIGTBLSZ] = {
LINUX_SIGHUP, LINUX_SIGINT, LINUX_SIGQUIT, LINUX_SIGILL,
LINUX_SIGTRAP, LINUX_SIGABRT, 0, LINUX_SIGFPE,
LINUX_SIGKILL, LINUX_SIGBUS, LINUX_SIGSEGV, 0,
LINUX_SIGPIPE, LINUX_SIGALRM, LINUX_SIGTERM, LINUX_SIGURG,
LINUX_SIGSTOP, LINUX_SIGTSTP, LINUX_SIGCONT, LINUX_SIGCHLD,
LINUX_SIGTTIN, LINUX_SIGTTOU, LINUX_SIGIO, LINUX_SIGXCPU,
LINUX_SIGXFSZ, LINUX_SIGVTALRM, LINUX_SIGPROF, LINUX_SIGWINCH,
0, LINUX_SIGUSR1, LINUX_SIGUSR2
};
int linux_to_bsd_signal[LINUX_SIGTBLSZ] = {
SIGHUP, SIGINT, SIGQUIT, SIGILL,
SIGTRAP, SIGABRT, SIGBUS, SIGFPE,
SIGKILL, SIGUSR1, SIGSEGV, SIGUSR2,
SIGPIPE, SIGALRM, SIGTERM, SIGBUS,
SIGCHLD, SIGCONT, SIGSTOP, SIGTSTP,
SIGTTIN, SIGTTOU, SIGURG, SIGXCPU,
SIGXFSZ, SIGVTALRM, SIGPROF, SIGWINCH,
SIGIO, SIGURG, 0
};
/*
* If FreeBSD & Linux have a difference of opinion about what a trap
* means, deal with it here.
*/
static int
translate_traps(int signal, int trap_code)
{
if (signal != SIGBUS)
return signal;
switch (trap_code) {
case T_PROTFLT:
case T_TSSFLT:
case T_DOUBLEFLT:
case T_PAGEFLT:
return SIGSEGV;
default:
return signal;
}
}
static int
linux_fixup(register_t **stack_base, struct image_params *imgp)
elf_linux_fixup(long **stack_base, struct image_params *imgp)
{
register_t *argv, *envp;
Elf64_Auxargs *args = (Elf64_Auxargs *)imgp->auxargs;
long *pos;
argv = *stack_base;
envp = *stack_base + (imgp->argc + 1);
(*stack_base)--;
**stack_base = (intptr_t)(void *)envp;
(*stack_base)--;
**stack_base = (intptr_t)(void *)argv;
(*stack_base)--;
**stack_base = imgp->argc;
return 0;
}
pos = *stack_base + (imgp->argc + imgp->envc + 2);
static int
elf_linux_fixup(register_t **stack_base, struct image_params *imgp)
{
Elf32_Auxargs *args = (Elf32_Auxargs *)imgp->auxargs;
register_t *pos;
pos = *stack_base + (imgp->argc + imgp->envc + 2);
if (args->trace) {
AUXARGS_ENTRY(pos, AT_DEBUG, 1);
}
@ -193,221 +113,8 @@ elf_linux_fixup(register_t **stack_base, struct image_params *imgp)
extern int _ucodesel, _udatasel;
/*
* Send an interrupt to process.
*
* Stack is set up to allow sigcode stored
* in u. to call routine, followed by kcall
* to sigreturn routine below. After sigreturn
* resets the signal mask, the stack, and the
* frame pointer, it returns to the user
* specified pc, psl.
*/
static void
linux_sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code)
{
register struct proc *p = curproc;
register struct trapframe *regs;
struct linux_sigframe *fp, frame;
struct sigacts *psp = p->p_sigacts;
int oonstack;
regs = p->p_md.md_regs;
oonstack = p->p_sigstk.ss_flags & SS_ONSTACK;
#ifdef DEBUG
printf("Linux-emul(%ld): linux_sendsig(%p, %d, %p, %lu)\n",
(long)p->p_pid, catcher, sig, (void*)mask, code);
#endif
/*
* Allocate space for the signal handler context.
*/
if ((p->p_flag & P_ALTSTACK) && !oonstack &&
SIGISMEMBER(psp->ps_sigonstack, sig)) {
fp = (struct linux_sigframe *)(p->p_sigstk.ss_sp +
p->p_sigstk.ss_size - sizeof(struct linux_sigframe));
p->p_sigstk.ss_flags |= SS_ONSTACK;
} else {
fp = (struct linux_sigframe *)regs->tf_esp - 1;
}
/*
* grow() will return FALSE if the fp will not fit inside the stack
* and the stack can not be grown. useracc will return FALSE
* if access is denied.
*/
if ((grow_stack (p, (int)fp) == FALSE) ||
!useracc((caddr_t)fp, sizeof (struct linux_sigframe),
VM_PROT_WRITE)) {
/*
* Process has trashed its stack; give it an illegal
* instruction to halt it in its tracks.
*/
SIGACTION(p, SIGILL) = SIG_DFL;
SIGDELSET(p->p_sigignore, SIGILL);
SIGDELSET(p->p_sigcatch, SIGILL);
SIGDELSET(p->p_sigmask, SIGILL);
psignal(p, SIGILL);
return;
}
/*
* Build the argument list for the signal handler.
*/
if (p->p_sysent->sv_sigtbl)
if (sig <= p->p_sysent->sv_sigsize)
sig = p->p_sysent->sv_sigtbl[_SIG_IDX(sig)];
frame.sf_handler = catcher;
frame.sf_sig = sig;
/*
* Build the signal context to be used by sigreturn.
*/
frame.sf_sc.sc_mask = mask->__bits[0];
frame.sf_sc.sc_gs = rgs();
frame.sf_sc.sc_fs = regs->tf_fs;
frame.sf_sc.sc_es = regs->tf_es;
frame.sf_sc.sc_ds = regs->tf_ds;
frame.sf_sc.sc_edi = regs->tf_edi;
frame.sf_sc.sc_esi = regs->tf_esi;
frame.sf_sc.sc_ebp = regs->tf_ebp;
frame.sf_sc.sc_ebx = regs->tf_ebx;
frame.sf_sc.sc_edx = regs->tf_edx;
frame.sf_sc.sc_ecx = regs->tf_ecx;
frame.sf_sc.sc_eax = regs->tf_eax;
frame.sf_sc.sc_eip = regs->tf_eip;
frame.sf_sc.sc_cs = regs->tf_cs;
frame.sf_sc.sc_eflags = regs->tf_eflags;
frame.sf_sc.sc_esp_at_signal = regs->tf_esp;
frame.sf_sc.sc_ss = regs->tf_ss;
frame.sf_sc.sc_err = regs->tf_err;
frame.sf_sc.sc_trapno = code; /* XXX ???? */
if (copyout(&frame, fp, sizeof(frame)) != 0) {
/*
* Process has trashed its stack; give it an illegal
* instruction to halt it in its tracks.
*/
sigexit(p, SIGILL);
/* NOTREACHED */
}
/*
* Build context to run handler in.
*/
regs->tf_esp = (int)fp;
regs->tf_eip = PS_STRINGS - *(p->p_sysent->sv_szsigcode);
regs->tf_eflags &= ~PSL_VM;
regs->tf_cs = _ucodesel;
regs->tf_ds = _udatasel;
regs->tf_es = _udatasel;
regs->tf_fs = _udatasel;
load_gs(_udatasel);
regs->tf_ss = _udatasel;
}
/*
* System call to cleanup state after a signal
* has been taken. Reset signal mask and
* stack state from context left by sendsig (above).
* Return to previous pc and psl as specified by
* context left by sendsig. Check carefully to
* make sure that the user has not modified the
* psl to gain improper privileges or to cause
* a machine fault.
*/
int
linux_sigreturn(p, args)
struct proc *p;
struct linux_sigreturn_args *args;
{
struct linux_sigcontext context;
register struct trapframe *regs;
int eflags;
regs = p->p_md.md_regs;
#ifdef DEBUG
printf("Linux-emul(%ld): linux_sigreturn(%p)\n",
(long)p->p_pid, (void *)args->scp);
#endif
/*
* The trampoline code hands us the context.
* It is unsafe to keep track of it ourselves, in the event that a
* program jumps out of a signal handler.
*/
if (copyin((caddr_t)args->scp, &context, sizeof(context)) != 0)
return (EFAULT);
/*
* Check for security violations.
*/
#define EFLAGS_SECURE(ef, oef) ((((ef) ^ (oef)) & ~PSL_USERCHANGE) == 0)
eflags = context.sc_eflags;
/*
* XXX do allow users to change the privileged flag PSL_RF. The
* cpu sets PSL_RF in tf_eflags for faults. Debuggers should
* sometimes set it there too. tf_eflags is kept in the signal
* context during signal handling and there is no other place
* to remember it, so the PSL_RF bit may be corrupted by the
* signal handler without us knowing. Corruption of the PSL_RF
* bit at worst causes one more or one less debugger trap, so
* allowing it is fairly harmless.
*/
if (!EFLAGS_SECURE(eflags & ~PSL_RF, regs->tf_eflags & ~PSL_RF)) {
return(EINVAL);
}
/*
* Don't allow users to load a valid privileged %cs. Let the
* hardware check for invalid selectors, excess privilege in
* other selectors, invalid %eip's and invalid %esp's.
*/
#define CS_SECURE(cs) (ISPL(cs) == SEL_UPL)
if (!CS_SECURE(context.sc_cs)) {
trapsignal(p, SIGBUS, T_PROTFLT);
return(EINVAL);
}
p->p_sigstk.ss_flags &= ~SS_ONSTACK;
SIGSETOLD(p->p_sigmask, context.sc_mask);
SIG_CANTMASK(p->p_sigmask);
/*
* Restore signal context.
*/
/* %gs was restored by the trampoline. */
regs->tf_fs = context.sc_fs;
regs->tf_es = context.sc_es;
regs->tf_ds = context.sc_ds;
regs->tf_edi = context.sc_edi;
regs->tf_esi = context.sc_esi;
regs->tf_ebp = context.sc_ebp;
regs->tf_ebx = context.sc_ebx;
regs->tf_edx = context.sc_edx;
regs->tf_ecx = context.sc_ecx;
regs->tf_eax = context.sc_eax;
regs->tf_eip = context.sc_eip;
regs->tf_cs = context.sc_cs;
regs->tf_eflags = eflags;
regs->tf_esp = context.sc_esp_at_signal;
regs->tf_ss = context.sc_ss;
return (EJUSTRETURN);
}
static void
linux_prepsyscall(struct trapframe *tf, int *args, u_int *code, caddr_t *params)
{
args[0] = tf->tf_ebx;
args[1] = tf->tf_ecx;
args[2] = tf->tf_edx;
args[3] = tf->tf_esi;
args[4] = tf->tf_edi;
*params = NULL; /* no copyin */
}
void osf1_sendsig __P((sig_t, int , sigset_t *, u_long ));
void osendsig(sig_t catcher, int sig, sigset_t *mask, u_long code);
/*
* If a linux binary is exec'ing something, try this image activator
@ -453,59 +160,45 @@ exec_linux_imgact_try(imgp)
return(error);
}
struct sysentvec linux_sysvec = {
LINUX_SYS_MAXSYSCALL,
linux_sysent,
0xff,
LINUX_SIGTBLSZ,
bsd_to_linux_signal,
ELAST + 1,
bsd_to_linux_errno,
translate_traps,
linux_fixup,
linux_sendsig,
linux_sigcode,
&linux_szsigcode,
linux_prepsyscall,
"Linux a.out",
aout_coredump,
exec_linux_imgact_try
};
/*
* To maintain OSF/1 compat, linux uses BSD signals & errnos on their
* alpha port. This greatly simplfies things for us.
*/
struct sysentvec elf_linux_sysvec = {
LINUX_SYS_MAXSYSCALL,
linux_sysent,
0xff,
LINUX_SIGTBLSZ,
bsd_to_linux_signal,
ELAST + 1,
bsd_to_linux_errno,
translate_traps,
0,
0,
0,
0,
0,
0,
elf_linux_fixup,
linux_sendsig,
osendsig,
linux_sigcode,
&linux_szsigcode,
linux_prepsyscall,
0,
"Linux ELF",
elf_coredump,
exec_linux_imgact_try
};
static Elf32_Brandinfo linux_brand = {
static Elf64_Brandinfo linux_brand = {
ELFOSABI_LINUX,
"/compat/linux",
"/lib/ld-linux.so.1",
&elf_linux_sysvec
};
static Elf32_Brandinfo linux_glibc2brand = {
static Elf64_Brandinfo linux_glibc2brand = {
ELFOSABI_LINUX,
"/compat/linux",
"/lib/ld-linux.so.2",
&elf_linux_sysvec
};
Elf32_Brandinfo *linux_brandlist[] = {
Elf64_Brandinfo *linux_brandlist[] = {
&linux_brand,
&linux_glibc2brand,
NULL
@ -514,7 +207,7 @@ Elf32_Brandinfo *linux_brandlist[] = {
static int
linux_elf_modevent(module_t mod, int type, void *data)
{
Elf32_Brandinfo **brandinfo;
Elf64_Brandinfo **brandinfo;
int error;
error = 0;