diff options
author | Ralf Baechle <ralf@linux-mips.org> | 1997-09-12 01:29:55 +0000 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 1997-09-12 01:29:55 +0000 |
commit | 545f435ebcfd94a1e7c20b46efe81b4d6ac4e698 (patch) | |
tree | e9ce4bc598d06374bda906f18365984bf22a526a /arch/sparc64/solaris | |
parent | 4291a610eef89d0d5c69d9a10ee6560e1aa36c74 (diff) |
Merge with Linux 2.1.55. More bugfixes and goodies from my private
CVS archive.
Diffstat (limited to 'arch/sparc64/solaris')
-rw-r--r-- | arch/sparc64/solaris/Makefile | 26 | ||||
-rw-r--r-- | arch/sparc64/solaris/conv.h | 28 | ||||
-rw-r--r-- | arch/sparc64/solaris/entry64.S | 202 | ||||
-rw-r--r-- | arch/sparc64/solaris/fs.c | 711 | ||||
-rw-r--r-- | arch/sparc64/solaris/ioctl.c | 316 | ||||
-rw-r--r-- | arch/sparc64/solaris/ipc.c | 122 | ||||
-rw-r--r-- | arch/sparc64/solaris/misc.c | 463 | ||||
-rw-r--r-- | arch/sparc64/solaris/signal.c | 419 | ||||
-rw-r--r-- | arch/sparc64/solaris/signal.h | 109 | ||||
-rw-r--r-- | arch/sparc64/solaris/socksys.c | 127 | ||||
-rw-r--r-- | arch/sparc64/solaris/systbl.S | 289 |
11 files changed, 2812 insertions, 0 deletions
diff --git a/arch/sparc64/solaris/Makefile b/arch/sparc64/solaris/Makefile new file mode 100644 index 000000000..56d252962 --- /dev/null +++ b/arch/sparc64/solaris/Makefile @@ -0,0 +1,26 @@ +# +# Makefile for the Solaris binary emulation. +# +# Note! Dependencies are done automagically by 'make dep', which also +# removes any old dependencies. DON'T put your own dependencies here +# unless it's something special (ie not a .c file). +# +# Note 2! The CFLAGS definition is now in the main makefile... + +O_TARGET := solaris.o +O_OBJS := entry64.o fs.o misc.o signal.o systbl.o ioctl.o ipc.o socksys.o +ifeq ($(CONFIG_SOLARIS_EMUL),m) +M_OBJS := $(O_TARGET) +endif + +.S.s: + $(CPP) -D__ASSEMBLY__ -ansi $< -o $*.s + +.S.o: + $(CC) -D__ASSEMBLY__ -ansi -c $< -o $*.o + +ifneq ($(CONFIG_SOLARIS_EMUL),y) +do_it_all: +endif + +include $(TOPDIR)/Rules.make diff --git a/arch/sparc64/solaris/conv.h b/arch/sparc64/solaris/conv.h new file mode 100644 index 000000000..c806d3dc1 --- /dev/null +++ b/arch/sparc64/solaris/conv.h @@ -0,0 +1,28 @@ +/* $Id: conv.h,v 1.2 1997/09/03 12:29:13 jj Exp $ + * conv.h: Utility macros for Solaris emulation + * + * Copyright (C) 1997 Jakub Jelinek (jj@sunsite.mff.cuni.cz) + */ + +/* #define DEBUG_SOLARIS */ + +#ifndef __ASSEMBLY__ + +#include <asm/unistd.h> + +/* As gcc will warn about casting u32 to some ptr, we have to cast it to + * unsigned long first, and that's what is A() for. + * You just do (void *)A(x), instead of having to + * type (void *)((unsigned long)x) or instead of just (void *)x, which will + * produce warnings. + */ +#define A(x) ((unsigned long)x) + +extern unsigned sys_call_table[]; +extern unsigned sys_call_table32[]; +extern unsigned sunos_sys_table[]; + +#define SYS(name) ((long)sys_call_table[__NR_##name]) +#define SUNOS(x) ((long)sunos_sys_table[x]) + +#endif /* __ASSEMBLY__ */ diff --git a/arch/sparc64/solaris/entry64.S b/arch/sparc64/solaris/entry64.S new file mode 100644 index 000000000..e983010d1 --- /dev/null +++ b/arch/sparc64/solaris/entry64.S @@ -0,0 +1,202 @@ +/* $Id: entry64.S,v 1.3 1997/09/03 12:29:12 jj Exp $ + * entry64.S: Solaris syscall emulation entry point. + * + * Copyright (C) 1996,1997 Jakub Jelinek (jj@sunsite.mff.cuni.cz) + * Copyright (C) 1995,1997 David S. Miller (davem@caip.rutgers.edu) + * Copyright (C) 1996 Miguel de Icaza (miguel@nuclecu.unam.mx) + */ + +#include <linux/errno.h> + +#include <asm/head.h> +#include <asm/asi.h> +#include <asm/smp.h> +#include <asm/ptrace.h> +#include <asm/page.h> +#include <asm/signal.h> +#include <asm/pgtable.h> +#include <asm/processor.h> + +#include "conv.h" + +#define NR_SYSCALLS 256 + + .text +solaris_syscall_trace: + call syscall_trace + nop + mov %i0, %o0 + mov %i1, %o1 + mov %i2, %o2 + mov %i3, %o3 + b,pt %xcc, 2f + mov %i4, %o4 + +solaris_sucks: +/* Solaris is a big system which needs to be able to do all the things + * in Inf+1 different ways */ + add %i6, 0x5c, %o0 + mov %i0, %g1 + mov %i1, %i0 + mov %i2, %i1 + srl %o0, 0, %o0 + mov %i3, %i2 + mov %i4, %i3 + mov %i5, %i4 + ba,pt %xcc, solaris_sparc_syscall +exen: lduwa [%o0] ASI_S, %i5 + +exenf: ba,pt %xcc, solaris_sparc_syscall + clr %i5 + +/* For shared binaries, binfmt_elf32 already sets up personality + and exec_domain. This is to handle static binaries as well */ +solaris_reg: + call solaris_register + nop + ba,pt %xcc, 1f + mov %i0, %o0 + +linux_syscall_for_solaris: + sll %l7, 2, %l4 + ba,pt %xcc, 10f + lduw [%l6 + %l4], %l7 + + /* Solaris system calls enter here... */ + .align 32 + .globl solaris_sparc_syscall +solaris_sparc_syscall: +#ifdef DEBUG_SOLARIS + mov %g1, %o0 + call entry_printk + add %sp, STACK_BIAS + REGWIN_SZ, %o1 +#endif + ldub [%g6 + AOFF_task_personality + ASIZ_task_personality - 1], %l0 + cmp %g1, 255 + bg,pn %icc, solaris_unimplemented + srl %g1, 0, %g1 + sethi %hi(solaris_sys_table), %l7 + brz,pn %g1, solaris_sucks + mov %i0, %o0 + sll %g1, 2, %l4 + cmp %l0, 1 + bne,pn %icc, solaris_reg +1: mov %i1, %o1 + lduw [%l7 + %l4], %l7 + mov %i2, %o2 + ldx [%g6 + AOFF_task_flags], %l5 +! st %g0, [%sp + STACK_BIAS + REGWIN_SZ + PT_V9_FPRS] + cmp %l7, NR_SYSCALLS + bleu,a,pn %xcc, linux_syscall_for_solaris + sethi %hi(sys_call_table32), %l6 + andcc %l7, 1, %g0 + bne,a,pn %icc, 10f + add %sp, STACK_BIAS + REGWIN_SZ, %o0 +10: mov %i3, %o3 + mov %i4, %o4 + andn %l7, 3, %l7 + andcc %l5, 0x20, %g0 + bne,pn %icc, solaris_syscall_trace + mov %i0, %l5 +2: call %l7 + mov %i5, %o5 +ret_from_solaris: +#ifdef DEBUG_SOLARIS + call exit_printk + mov %o0, %l0 + mov %l0, %o0 +#endif + stx %o0, [%sp + STACK_BIAS + REGWIN_SZ + PT_V9_I0] + ldx [%g6 + AOFF_task_flags], %l6 + sra %o0, 0, %o0 + mov %ulo(TSTATE_XCARRY | TSTATE_ICARRY), %g2 + ldx [%sp + STACK_BIAS + REGWIN_SZ + PT_V9_TSTATE], %g3 + cmp %o0, -ENOIOCTLCMD + sllx %g2, 32, %g2 + bgeu,pn %xcc, 1f + andcc %l6, 0x20, %l6 + + /* System call success, clear Carry condition code. */ + andn %g3, %g2, %g3 + stx %g3, [%sp + STACK_BIAS + REGWIN_SZ + PT_V9_TSTATE] + bne,pn %icc, solaris_syscall_trace2 + ldx [%sp + STACK_BIAS + REGWIN_SZ + PT_V9_TNPC], %l1 ! pc = npc + add %l1, 0x4, %l2 !npc = npc+4 + stx %l1, [%sp + STACK_BIAS + REGWIN_SZ + PT_V9_TPC] + clr %l6 + call rtrap + stx %l2, [%sp + STACK_BIAS + REGWIN_SZ + PT_V9_TNPC] +1: + /* System call failure, set Carry condition code. + * Also, get abs(errno) to return to the process. + */ + sub %g0, %o0, %o0 + or %g3, %g2, %g3 + cmp %o0, ERANGE /* 0-ERANGE are identity mapped */ + bleu,pt %icc, 1f + cmp %o0, EMEDIUMTYPE + bgu,pn %icc, 1f + sethi %hi(solaris_err_table), %l6 + sll %o0, 2, %o0 + or %l6, %lo(solaris_err_table), %l6 + ldsw [%l6 + %o0], %o0 +1: stx %o0, [%sp + STACK_BIAS + REGWIN_SZ + PT_V9_I0] + mov 1, %l6 + stx %g3, [%sp + STACK_BIAS + REGWIN_SZ + PT_V9_TSTATE] + bne,pn %icc, solaris_syscall_trace2 + ldx [%sp + STACK_BIAS + REGWIN_SZ + PT_V9_TNPC], %l1 ! pc = npc + add %l1, 0x4, %l2 !npc = npc+4 + + stx %l1, [%sp + STACK_BIAS + REGWIN_SZ + PT_V9_TPC] + call rtrap + stx %l2, [%sp + STACK_BIAS + REGWIN_SZ + PT_V9_TNPC] +solaris_syscall_trace2: + call syscall_trace + add %l1, 0x4, %l2 /* npc = npc+4 */ + stx %l1, [%sp + STACK_BIAS + REGWIN_SZ + PT_V9_TPC] + call rtrap + stx %l2, [%sp + STACK_BIAS + REGWIN_SZ + PT_V9_TNPC] + + /* This one is tricky, so that's why we do it in assembly */ + .globl solaris_sigsuspend +solaris_sigsuspend: + call do_sol_sigsuspend + nop + brlz,pn %o0, ret_from_solaris + nop + call sys_sigsuspend + stx %o0, [%sp + STACK_BIAS + REGWIN_SZ + PT_V9_I0] + + .globl solaris_getpid +solaris_getpid: + call sys_getppid /* This is tricky, so don't do it in assembly */ + nop + stx %o0, [%sp + STACK_BIAS + REGWIN_SZ + PT_V9_I1] + b,pt %xcc, ret_from_solaris + lduw [%g6 + AOFF_task_pid], %o0 + + .globl solaris_getuid +solaris_getuid: + lduh [%g6 + AOFF_task_euid], %o1 + lduh [%g6 + AOFF_task_uid], %o0 + b,pt %xcc, ret_from_solaris + stx %o1, [%sp + STACK_BIAS + REGWIN_SZ + PT_V9_I1] + + .globl solaris_getgid +solaris_getgid: + lduh [%g6 + AOFF_task_egid], %o1 + lduh [%g6 + AOFF_task_gid], %o0 + b,pt %xcc, ret_from_solaris + stx %o1, [%sp + STACK_BIAS + REGWIN_SZ + PT_V9_I1] + + .globl solaris_unimplemented +solaris_unimplemented: + call do_sol_unimplemented + add %sp, STACK_BIAS + REGWIN_SZ, %o0 + ba,pt %xcc, ret_from_solaris + nop + + .section __ex_table,#alloc + .align 4 + .word exen, exenf + diff --git a/arch/sparc64/solaris/fs.c b/arch/sparc64/solaris/fs.c new file mode 100644 index 000000000..9d0905adc --- /dev/null +++ b/arch/sparc64/solaris/fs.c @@ -0,0 +1,711 @@ +/* $Id: fs.c,v 1.4 1997/09/04 15:46:26 jj Exp $ + * fs.c: fs related syscall emulation for Solaris + * + * Copyright (C) 1997 Jakub Jelinek (jj@sunsite.mff.cuni.cz) + */ + +#include <linux/types.h> +#include <linux/fs.h> +#include <linux/stat.h> +#include <linux/smp_lock.h> +#include <linux/limits.h> +#include <linux/resource.h> + +#include <asm/uaccess.h> +#include <asm/string.h> +#include <asm/ptrace.h> + +#include "conv.h" + +extern char * getname32(u32 filename); +#define putname32 putname + +#define R4_DEV(DEV) ((DEV & 0xff) | ((DEV & 0xff00) << 10)) +#define R4_MAJOR(DEV) (((DEV) >> 18) & 0x3fff) +#define R4_MINOR(DEV) ((DEV) & 0x3ffff) +#define R3_VERSION 1 +#define R4_VERSION 2 + +typedef struct { + s32 tv_sec; + s32 tv_nsec; +} timestruct_t; + +struct sol_stat { + u32 st_dev; + s32 st_pad1[3]; /* network id */ + u32 st_ino; + u32 st_mode; + u32 st_nlink; + u32 st_uid; + u32 st_gid; + u32 st_rdev; + s32 st_pad2[2]; + s32 st_size; + s32 st_pad3; /* st_size, off_t expansion */ + timestruct_t st_atime; + timestruct_t st_mtime; + timestruct_t st_ctime; + s32 st_blksize; + s32 st_blocks; + char st_fstype[16]; + s32 st_pad4[8]; /* expansion area */ +}; + +#define UFSMAGIC (((unsigned)'u'<<24)||((unsigned)'f'<<16)||((unsigned)'s'<<8)) + +static inline int putstat(struct sol_stat *ubuf, struct stat *kbuf) +{ + if (put_user (R4_DEV(kbuf->st_dev), &ubuf->st_dev) || + __put_user (kbuf->st_ino, &ubuf->st_ino) || + __put_user (kbuf->st_mode, &ubuf->st_mode) || + __put_user (kbuf->st_nlink, &ubuf->st_nlink) || + __put_user (kbuf->st_uid, &ubuf->st_uid) || + __put_user (kbuf->st_gid, &ubuf->st_gid) || + __put_user (R4_DEV(kbuf->st_rdev), &ubuf->st_rdev) || + __put_user (kbuf->st_size, &ubuf->st_size) || + __put_user (kbuf->st_atime, &ubuf->st_atime.tv_sec) || + __put_user (0, &ubuf->st_atime.tv_nsec) || + __put_user (kbuf->st_mtime, &ubuf->st_mtime.tv_sec) || + __put_user (0, &ubuf->st_mtime.tv_nsec) || + __put_user (kbuf->st_ctime, &ubuf->st_ctime.tv_sec) || + __put_user (0, &ubuf->st_ctime.tv_nsec) || + __put_user (kbuf->st_blksize, &ubuf->st_blksize) || + __put_user (kbuf->st_blocks, &ubuf->st_blocks) || + __put_user (UFSMAGIC, (unsigned *)ubuf->st_fstype)) + return -EFAULT; + return 0; +} + +asmlinkage int solaris_stat(u32 filename, u32 statbuf) +{ + int ret; + struct stat s; + char *filenam; + unsigned long old_fs = get_fs(); + int (*sys_newstat)(char *,struct stat *) = + (int (*)(char *,struct stat *))SYS(stat); + + filenam = getname32 (filename); + ret = PTR_ERR(filenam); + if (!IS_ERR(filenam)) { + set_fs (KERNEL_DS); + ret = sys_newstat(filenam, &s); + set_fs (old_fs); + putname32 (filenam); + if (putstat ((struct sol_stat *)A(statbuf), &s)) + return -EFAULT; + } + return ret; +} + +asmlinkage int solaris_xstat(int vers, u32 filename, u32 statbuf) +{ + /* Solaris doesn't bother with looking at vers, so we do neither */ + return solaris_stat(filename, statbuf); +} + +asmlinkage int solaris_lstat(u32 filename, u32 statbuf) +{ + int ret; + struct stat s; + char *filenam; + unsigned long old_fs = get_fs(); + int (*sys_newlstat)(char *,struct stat *) = + (int (*)(char *,struct stat *))SYS(lstat); + + filenam = getname32 (filename); + ret = PTR_ERR(filenam); + if (!IS_ERR(filenam)) { + set_fs (KERNEL_DS); + ret = sys_newlstat(filenam, &s); + set_fs (old_fs); + putname32 (filenam); + if (putstat ((struct sol_stat *)A(statbuf), &s)) + return -EFAULT; + } + return ret; +} + +asmlinkage int solaris_lxstat(int vers, u32 filename, u32 statbuf) +{ + return solaris_lstat(filename, statbuf); +} + +asmlinkage int solaris_fstat(unsigned int fd, u32 statbuf) +{ + int ret; + struct stat s; + unsigned long old_fs = get_fs(); + int (*sys_newfstat)(unsigned,struct stat *) = + (int (*)(unsigned,struct stat *))SYS(fstat); + + set_fs (KERNEL_DS); + ret = sys_newfstat(fd, &s); + set_fs (old_fs); + if (putstat ((struct sol_stat *)A(statbuf), &s)) + return -EFAULT; + return ret; +} + +asmlinkage int solaris_fxstat(int vers, u32 fd, u32 statbuf) +{ + return solaris_fstat(fd, statbuf); +} + +asmlinkage int solaris_mknod(u32 path, u32 mode, s32 dev) +{ + int (*sys_mknod)(const char *,int,dev_t) = + (int (*)(const char *,int,dev_t))SYS(mknod); + int major, minor; + + if ((major = R4_MAJOR(dev)) > 255 || + (minor = R4_MINOR(dev)) > 255) return -EINVAL; + return sys_mknod((const char *)A(path), mode, MKDEV(major,minor)); +} + +asmlinkage int solaris_xmknod(int vers, u32 path, u32 mode, s32 dev) +{ + return solaris_mknod(path, mode, dev); +} + +/* This statfs thingie probably will go in the near future, but... */ + +struct sol_statfs { + short f_type; + s32 f_bsize; + s32 f_frsize; + s32 f_blocks; + s32 f_bfree; + u32 f_files; + u32 f_ffree; + char f_fname[6]; + char f_fpack[6]; +}; + +asmlinkage int solaris_statfs(u32 path, u32 buf, int len, int fstype) +{ + int ret; + struct statfs s; + unsigned long old_fs = get_fs(); + int (*sys_statfs)(const char *,struct statfs *) = + (int (*)(const char *,struct statfs *))SYS(statfs); + struct sol_statfs *ss = (struct sol_statfs *)A(buf); + + if (len != sizeof(struct sol_statfs)) return -EINVAL; + if (!fstype) { + set_fs (KERNEL_DS); + ret = sys_statfs((const char *)A(path), &s); + set_fs (old_fs); + if (!ret) { + if (put_user (s.f_type, &ss->f_type) || + __put_user (s.f_bsize, &ss->f_bsize) || + __put_user (0, &ss->f_frsize) || + __put_user (s.f_blocks, &ss->f_blocks) || + __put_user (s.f_bfree, &ss->f_bfree) || + __put_user (s.f_files, &ss->f_files) || + __put_user (s.f_ffree, &ss->f_ffree) || + __clear_user (&ss->f_fname, 12)) + return -EFAULT; + } + return ret; + } +/* Linux can't stat unmounted filesystems so we + * simply lie and claim 100MB of 1GB is free. Sorry. + */ + if (put_user (fstype, &ss->f_type) || + __put_user (1024, &ss->f_bsize) || + __put_user (0, &ss->f_frsize) || + __put_user (1024*1024, &ss->f_blocks) || + __put_user (100*1024, &ss->f_bfree) || + __put_user (60000, &ss->f_files) || + __put_user (50000, &ss->f_ffree) || + __clear_user (&ss->f_fname, 12)) + return -EFAULT; + return 0; +} + +asmlinkage int solaris_fstatfs(u32 fd, u32 buf, int len, int fstype) +{ + int ret; + struct statfs s; + unsigned long old_fs = get_fs(); + int (*sys_fstatfs)(unsigned,struct statfs *) = + (int (*)(unsigned,struct statfs *))SYS(fstatfs); + struct sol_statfs *ss = (struct sol_statfs *)A(buf); + + if (len != sizeof(struct sol_statfs)) return -EINVAL; + if (!fstype) { + set_fs (KERNEL_DS); + ret = sys_fstatfs(fd, &s); + set_fs (old_fs); + if (!ret) { + if (put_user (s.f_type, &ss->f_type) || + __put_user (s.f_bsize, &ss->f_bsize) || + __put_user (0, &ss->f_frsize) || + __put_user (s.f_blocks, &ss->f_blocks) || + __put_user (s.f_bfree, &ss->f_bfree) || + __put_user (s.f_files, &ss->f_files) || + __put_user (s.f_ffree, &ss->f_ffree) || + __clear_user (&ss->f_fname, 12)) + return -EFAULT; + } + return ret; + } + /* Otherwise fstatfs is the same as statfs */ + return solaris_statfs(0, buf, len, fstype); +} + +struct sol_statvfs { + u32 f_bsize; + u32 f_frsize; + u32 f_blocks; + u32 f_bfree; + u32 f_bavail; + u32 f_files; + u32 f_ffree; + u32 f_favail; + u32 f_fsid; + char f_basetype[16]; + u32 f_flag; + u32 f_namemax; + char f_fstr[32]; + u32 f_filler[16]; +}; + +static int report_statvfs(struct inode *inode, u32 buf) +{ + struct statfs s; + unsigned long old_fs = get_fs(); + int error; + struct sol_statvfs *ss = (struct sol_statvfs *)A(buf); + + set_fs (KERNEL_DS); + error = inode->i_sb->s_op->statfs(inode->i_sb, &s, sizeof(struct statfs)); + set_fs (old_fs); + if (!error) { + const char *p = inode->i_sb->s_type->name; + int i = 0; + int j = strlen (p); + + if (j > 15) j = 15; + if (IS_RDONLY(inode)) i = 1; + if (IS_NOSUID(inode)) i |= 2; + if (put_user (s.f_bsize, &ss->f_bsize) || + __put_user (0, &ss->f_frsize) || + __put_user (s.f_blocks, &ss->f_blocks) || + __put_user (s.f_bfree, &ss->f_bfree) || + __put_user (s.f_bavail, &ss->f_bavail) || + __put_user (s.f_files, &ss->f_files) || + __put_user (s.f_ffree, &ss->f_ffree) || + __put_user (s.f_ffree, &ss->f_favail) || + __put_user (R4_DEV(inode->i_sb->s_dev), &ss->f_fsid) || + __copy_to_user (ss->f_basetype,p,j) || + __put_user (0, (char *)&ss->f_basetype[j]) || + __put_user (s.f_namelen, &ss->f_namemax) || + __put_user (i, &ss->f_flag) || + __clear_user (&ss->f_fstr, 32)) + return -EFAULT; + } + return error; +} + +asmlinkage int solaris_statvfs(u32 path, u32 buf) +{ + struct dentry * dentry; + int error; + + lock_kernel(); + dentry = namei((const char *)A(path)); + error = PTR_ERR(dentry); + if (!IS_ERR(dentry)) { + struct inode * inode = dentry->d_inode; + + error = -ENOSYS; + if (inode->i_sb->s_op->statfs) + error = report_statvfs(inode, buf); + dput(dentry); + } + unlock_kernel(); + return error; +} + +asmlinkage int solaris_fstatvfs(unsigned int fd, u32 buf) +{ + struct inode * inode; + struct dentry * dentry; + struct file * file; + int error; + + lock_kernel(); + if (fd >= NR_OPEN || !(file = current->files->fd[fd])) + error = -EBADF; + else if (!(dentry = file->f_dentry)) + error = -ENOENT; + else if (!(inode = dentry->d_inode)) + error = -ENOENT; + else if (!inode->i_sb) + error = -ENODEV; + else if (!inode->i_sb->s_op->statfs) + error = -ENOSYS; + else + error = report_statvfs(inode, buf); + unlock_kernel(); + return error; +} + +asmlinkage int solaris_open(u32 filename, int flags, u32 mode) +{ + int (*sys_open)(const char *,int,int) = + (int (*)(const char *,int,int))SYS(open); + int fl = flags & 0xf; + + if (flags & 0x8050) fl |= O_SYNC; + if (flags & 0x80) fl |= O_NONBLOCK; + if (flags & 0x100) fl |= O_CREAT; + if (flags & 0x200) fl |= O_TRUNC; + if (flags & 0x400) fl |= O_EXCL; + if (flags & 0x800) fl |= O_NOCTTY; + return sys_open((const char *)A(filename), fl, mode); +} + +#define SOL_F_SETLK 6 +#define SOL_F_SETLKW 7 +#define SOL_F_FREESP 11 +#define SOL_F_ISSTREAM 13 +#define SOL_F_GETLK 14 +#define SOL_F_PRIV 15 +#define SOL_F_NPRIV 16 +#define SOL_F_QUOTACTL 17 +#define SOL_F_BLOCKS 18 +#define SOL_F_BLKSIZE 19 +#define SOL_F_GETOWN 23 +#define SOL_F_SETOWN 24 + +struct sol_flock { + short l_type; + short l_whence; + u32 l_start; + u32 l_len; + s32 l_sysid; + s32 l_pid; + s32 l_pad[4]; +}; + +asmlinkage int solaris_fcntl(unsigned fd, unsigned cmd, u32 arg) +{ + int (*sys_fcntl)(unsigned,unsigned,unsigned long) = + (int (*)(unsigned,unsigned,unsigned long))SYS(fcntl); + int ret, flags; + + switch (cmd) { + case F_DUPFD: + case F_GETFD: + case F_SETFD: return sys_fcntl(fd, cmd, (unsigned long)arg); + case F_GETFL: + flags = sys_fcntl(fd, cmd, 0); + ret = flags & 0xf; + if (flags & O_SYNC) ret |= 0x8050; + if (flags & O_NONBLOCK) ret |= 0x80; + return ret; + case F_SETFL: + flags = arg & 0xf; + if (arg & 0x8050) flags |= O_SYNC; + if (arg & 0x80) flags |= O_NONBLOCK; + return sys_fcntl(fd, cmd, (long)flags); + case SOL_F_GETLK: + case SOL_F_SETLK: + case SOL_F_SETLKW: + { + struct flock f; + unsigned long old_fs = get_fs(); + + switch (cmd) { + case SOL_F_GETLK: cmd = F_GETLK; break; + case SOL_F_SETLK: cmd = F_SETLK; break; + case SOL_F_SETLKW: cmd = F_SETLKW; break; + } + + get_user_ret (f.l_type, &((struct sol_flock *)A(arg))->l_type, -EFAULT); + __get_user_ret (f.l_whence, &((struct sol_flock *)A(arg))->l_whence, -EFAULT); + __get_user_ret (f.l_start, &((struct sol_flock *)A(arg))->l_start, -EFAULT); + __get_user_ret (f.l_len, &((struct sol_flock *)A(arg))->l_len, -EFAULT); + __get_user_ret (f.l_pid, &((struct sol_flock *)A(arg))->l_sysid, -EFAULT); + set_fs(KERNEL_DS); + ret = sys_fcntl(fd, cmd, (unsigned long)&f); + set_fs(old_fs); + __put_user_ret (f.l_type, &((struct sol_flock *)A(arg))->l_type, -EFAULT); + __put_user_ret (f.l_whence, &((struct sol_flock *)A(arg))->l_whence, -EFAULT); + __put_user_ret (f.l_start, &((struct sol_flock *)A(arg))->l_start, -EFAULT); + __put_user_ret (f.l_len, &((struct sol_flock *)A(arg))->l_len, -EFAULT); + __put_user_ret (f.l_pid, &((struct sol_flock *)A(arg))->l_pid, -EFAULT); + __put_user_ret (0, &((struct sol_flock *)A(arg))->l_sysid, -EFAULT); + return ret; + } + } + return -EINVAL; +} + +asmlinkage int solaris_ulimit(int cmd, int val) +{ + switch (cmd) { + case 1: /* UL_GETFSIZE - in 512B chunks */ + return current->rlim[RLIMIT_FSIZE].rlim_cur >> 9; + case 2: /* UL_SETFSIZE */ + if ((unsigned long)val > (LONG_MAX>>9)) return -ERANGE; + val <<= 9; + lock_kernel(); + if (val > current->rlim[RLIMIT_FSIZE].rlim_max) { + if (!suser()) { + unlock_kernel(); + return -EPERM; + } + current->rlim[RLIMIT_FSIZE].rlim_max = val; + } + current->rlim[RLIMIT_FSIZE].rlim_cur = val; + unlock_kernel(); + return 0; + case 3: /* UL_GMEMLIM */ + return current->rlim[RLIMIT_DATA].rlim_cur; + case 4: /* UL_GDESLIM */ + return NR_OPEN; + } + return -EINVAL; +} + +static int chown_common(struct dentry * dentry, uid_t user, gid_t group) +{ + struct inode * inode; + struct iattr newattrs; + int error; + + error = -ENOENT; + if (!(inode = dentry->d_inode)) { + printk("chown_common: NULL inode\n"); + goto out; + } + error = -EROFS; + if (IS_RDONLY(inode)) + goto out; + error = -EPERM; + if (IS_IMMUTABLE(inode) || IS_APPEND(inode)) + goto out; + if (user == (uid_t) -1) + user = inode->i_uid; + if (group == (gid_t) -1) + group = inode->i_gid; + newattrs.ia_mode = inode->i_mode; + newattrs.ia_uid = user; + newattrs.ia_gid = group; + newattrs.ia_valid = ATTR_UID | ATTR_GID | ATTR_CTIME; + /* + * If the owner has been changed, remove the setuid bit + */ + if (inode->i_mode & S_ISUID) { + newattrs.ia_mode &= ~S_ISUID; + newattrs.ia_valid |= ATTR_MODE; + } + /* + * If the group has been changed, remove the setgid bit + * + * Don't remove the setgid bit if no group execute bit. + * This is a file marked for mandatory locking. + */ + if (((inode->i_mode & (S_ISGID | S_IXGRP)) == (S_ISGID | S_IXGRP))) { + newattrs.ia_mode &= ~S_ISGID; + newattrs.ia_valid |= ATTR_MODE; + } + if (inode->i_sb && inode->i_sb->dq_op) { + inode->i_sb->dq_op->initialize(inode, -1); + error = -EDQUOT; + if (inode->i_sb->dq_op->transfer(inode, &newattrs, 0)) + goto out; + error = notify_change(inode, &newattrs); + if (error) + inode->i_sb->dq_op->transfer(inode, &newattrs, 1); + } else + error = notify_change(inode, &newattrs); +out: + return error; +} + +/* Linux chown works like Solaris lchown. Solaris chown does follow symlink */ +asmlinkage int solaris_chown(u32 filename, s32 user, s32 group) +{ + struct dentry * dentry; + int error; + + lock_kernel(); + dentry = namei((const char *)A(filename)); + + error = PTR_ERR(dentry); + if (!IS_ERR(dentry)) { + error = chown_common(dentry, user, group); + dput(dentry); + } + unlock_kernel(); + return error; +} + +/* At least at the time I'm writing this, Linux doesn't have ACLs, so we + just fake this */ +asmlinkage int solaris_acl(u32 filename, int cmd, int nentries, u32 aclbufp) +{ + return -ENOSYS; +} + +asmlinkage int solaris_facl(unsigned int fd, int cmd, int nentries, u32 aclbufp) +{ + return -ENOSYS; +} + +asmlinkage int solaris_pread(int fd, u32 buf, u32 nbyte, s32 offset) +{ + off_t temp; + int retval; + struct file * file; + long (*sys_read)(unsigned int, char *, unsigned long) = + (long (*)(unsigned int, char *, unsigned long))SYS(read); + long (*sys_lseek)(unsigned int, off_t, unsigned int) = + (long (*)(unsigned int, off_t, unsigned int))SYS(lseek); + + lock_kernel(); + retval = -EBADF; + if (fd >= NR_OPEN || + !(file = current->files->fd[fd])) + goto bad; + temp = file->f_pos; + if (temp != offset) { + retval = sys_lseek(fd, offset, 0); + if (retval < 0) goto bad; + } + retval = sys_read(fd, (char *)A(buf), nbyte); + if (file->f_pos != temp) { + if (!retval) + retval = sys_lseek(fd, temp, 0); + else + sys_lseek(fd, temp, 0); + } +bad: + unlock_kernel(); + return retval; +} + +asmlinkage int solaris_pwrite(int fd, u32 buf, u32 nbyte, s32 offset) +{ + off_t temp; + int retval; + struct file * file; + long (*sys_write)(unsigned int, char *, unsigned long) = + (long (*)(unsigned int, char *, unsigned long))SYS(read); + long (*sys_lseek)(unsigned int, off_t, unsigned int) = + (long (*)(unsigned int, off_t, unsigned int))SYS(lseek); + + lock_kernel(); + retval = -EBADF; + if (fd >= NR_OPEN || + !(file = current->files->fd[fd])) + goto bad; + temp = file->f_pos; + if (temp != offset) { + retval = sys_lseek(fd, offset, 0); + if (retval < 0) goto bad; + } + retval = sys_write(fd, (char *)A(buf), nbyte); + if (file->f_pos != temp) { + if (!retval) + retval = sys_lseek(fd, temp, 0); + else + sys_lseek(fd, temp, 0); + } +bad: + unlock_kernel(); + return retval; +} + +/* POSIX.1 names */ +#define _PC_LINK_MAX 1 +#define _PC_MAX_CANON 2 +#define _PC_MAX_INPUT 3 +#define _PC_NAME_MAX 4 +#define _PC_PATH_MAX 5 +#define _PC_PIPE_BUF 6 +#define _PC_NO_TRUNC 7 +#define _PC_VDISABLE 8 +#define _PC_CHOWN_RESTRICTED 9 +/* POSIX.4 names */ +#define _PC_ASYNC_IO 10 +#define _PC_PRIO_IO 11 +#define _PC_SYNC_IO 12 +#define _PC_LAST 12 + +/* This is not a real and complete implementation yet, just to keep + * the easy Solaris binaries happy. + */ +asmlinkage int solaris_fpathconf(int fd, int name) +{ + int ret; + + switch(name) { + case _PC_LINK_MAX: + ret = LINK_MAX; + break; + case _PC_MAX_CANON: + ret = MAX_CANON; + break; + case _PC_MAX_INPUT: + ret = MAX_INPUT; + break; + case _PC_NAME_MAX: + ret = NAME_MAX; + break; + case _PC_PATH_MAX: + ret = PATH_MAX; + break; + case _PC_PIPE_BUF: + ret = PIPE_BUF; + break; + case _PC_CHOWN_RESTRICTED: + ret = 1; + break; + case _PC_NO_TRUNC: + case _PC_VDISABLE: + ret = 0; + break; + default: + ret = -EINVAL; + break; + } + return ret; +} + +asmlinkage int solaris_pathconf(u32 path, int name) +{ + return solaris_fpathconf(0, name); +} + +/* solaris_llseek returns long long - quite difficult */ +asmlinkage long solaris_llseek(struct pt_regs *regs, u32 off_hi, u32 off_lo, int whence) +{ + int (*sys_llseek)(unsigned int, unsigned long, unsigned long, loff_t *, unsigned int) = + (int (*)(unsigned int, unsigned long, unsigned long, loff_t *, unsigned int))SYS(_llseek); + int ret; + unsigned long old_fs = get_fs(); + loff_t retval; + + set_fs(KERNEL_DS); + ret = sys_llseek((unsigned int)regs->u_regs[UREG_I0], off_hi, off_lo, &retval, whence); + set_fs(old_fs); + if (ret < 0) return ret; + regs->u_regs[UREG_I1] = (u32)retval; + return (retval >> 32); +} + +/* Have to mask out all but lower 3 bits */ +asmlinkage int solaris_access(u32 filename, long mode) +{ + int (*sys_access)(const char *, int) = + (int (*)(const char *, int))SYS(access); + + return sys_access((const char *)A(filename), mode & 7); +} diff --git a/arch/sparc64/solaris/ioctl.c b/arch/sparc64/solaris/ioctl.c new file mode 100644 index 000000000..43b844caf --- /dev/null +++ b/arch/sparc64/solaris/ioctl.c @@ -0,0 +1,316 @@ +/* $Id: ioctl.c,v 1.2 1997/09/04 00:59:22 davem Exp $ + * ioctl.c: Solaris ioctl emulation. + * + * Copyright (C) 1997 Jakub Jelinek (jj@sunsite.mff.cuni.cz) + * + * Streams & timod emulation based on code + * Copyright (C) 1995, 1996 Mike Jagdis (jaggy@purplet.demon.co.uk) + * + */ + +#include <linux/types.h> +#include <linux/kernel.h> +#include <linux/sched.h> +#include <linux/smp.h> +#include <linux/smp_lock.h> +#include <linux/ioctl.h> +#include <linux/fs.h> + +#include <asm/uaccess.h> +#include <asm/termios.h> + +#include "conv.h" + +extern char * getname32(u32 filename); +#define putname32 putname + +extern asmlinkage int sys_ioctl(unsigned int fd, unsigned int cmd, + unsigned long arg); +extern asmlinkage int sys32_ioctl(unsigned int fd, unsigned int cmd, + u32 arg); +asmlinkage int solaris_ioctl(unsigned int fd, unsigned int cmd, u32 arg); + +/* termio* stuff {{{ */ + +struct solaris_termios { + u32 c_iflag; + u32 c_oflag; + u32 c_cflag; + u32 c_lflag; + u8 c_cc[19]; +}; + +struct solaris_termio { + u16 c_iflag; + u16 c_oflag; + u16 c_cflag; + u16 c_lflag; + s8 c_line; + u8 c_cc[8]; +}; + +struct solaris_termiox { + u16 x_hflag; + u16 x_cflag; + u16 x_rflag[5]; + u16 x_sflag; +}; + +static u32 solaris_to_linux_cflag(u32 cflag) +{ + cflag &= 0x7fdff000; + if (cflag & 0x200000) { + int baud = cflag & 0xf; + cflag &= ~0x20000f; + switch (baud) { + case 0: baud = B57600; break; + case 1: baud = B76800; break; + case 2: baud = B115200; break; + case 3: baud = B153600; break; + case 4: baud = B230400; break; + case 5: baud = B307200; break; + case 6: baud = B460800; break; + } + cflag |= CBAUDEX | baud; + } + return cflag; +} + +static u32 linux_to_solaris_cflag(u32 cflag) +{ + cflag &= ~(CMSPAR | CIBAUD); + if (cflag & CBAUDEX) { + int baud = cflag & CBAUD; + cflag &= ~CBAUD; + switch (baud) { + case B57600: baud = 0; break; + case B76800: baud = 1; break; + case B115200: baud = 2; break; + case B153600: baud = 3; break; + case B230400: baud = 4; break; + case B307200: baud = 5; break; + case B460800: baud = 6; break; + case B614400: baud = 7; break; + case B921600: baud = 8; break; + /* case B1843200: baud = 9; break; */ + } + cflag |= 0x200000 | baud; + } + return cflag; +} + +static inline int linux_to_solaris_termio(unsigned int fd, unsigned int cmd, u32 arg) +{ + int ret; + + ret = sys_ioctl(fd, cmd, A(arg)); + if (!ret) { + u32 cflag; + + if (__get_user (cflag, &((struct solaris_termio *)A(arg))->c_cflag)) + return -EFAULT; + cflag = linux_to_solaris_cflag(cflag); + if (__put_user (cflag, &((struct solaris_termio *)A(arg))->c_cflag)) + return -EFAULT; + } + return ret; +} + +static int solaris_to_linux_termio(unsigned int fd, unsigned int cmd, u32 arg) +{ + int ret; + struct solaris_termio s; + unsigned long old_fs = get_fs(); + + if (copy_from_user (&s, (struct solaris_termio *)A(arg), sizeof(struct solaris_termio))) + return -EFAULT; + s.c_cflag = solaris_to_linux_cflag(s.c_cflag); + set_fs(KERNEL_DS); + ret = sys_ioctl(fd, cmd, (unsigned long)&s); + set_fs(old_fs); + return ret; +} + +static inline int linux_to_solaris_termios(unsigned int fd, unsigned int cmd, u32 arg) +{ + int ret; + struct solaris_termios s; + unsigned long old_fs = get_fs(); + + set_fs(KERNEL_DS); + ret = sys_ioctl(fd, cmd, (unsigned long)&s); + set_fs(old_fs); + if (!ret) { + if (put_user (s.c_iflag, &((struct solaris_termios *)A(arg))->c_iflag) || + __put_user (s.c_oflag, &((struct solaris_termios *)A(arg))->c_oflag) || + __put_user (linux_to_solaris_cflag(s.c_cflag), &((struct solaris_termios *)A(arg))->c_cflag) || + __put_user (s.c_lflag, &((struct solaris_termios *)A(arg))->c_lflag) || + __copy_to_user (((struct solaris_termios *)A(arg))->c_cc, s.c_cc, 16) || + __clear_user (((struct solaris_termios *)A(arg))->c_cc + 16, 2)) + return -EFAULT; + } + return ret; +} + +static int solaris_to_linux_termios(unsigned int fd, unsigned int cmd, u32 arg) +{ + int ret; + struct solaris_termios s; + unsigned long old_fs = get_fs(); + + set_fs(KERNEL_DS); + ret = sys_ioctl(fd, TCGETS, (unsigned long)&s); + set_fs(old_fs); + if (ret) return ret; + if (put_user (s.c_iflag, &((struct solaris_termios *)A(arg))->c_iflag) || + __put_user (s.c_oflag, &((struct solaris_termios *)A(arg))->c_oflag) || + __put_user (s.c_cflag, &((struct solaris_termios *)A(arg))->c_cflag) || + __put_user (s.c_lflag, &((struct solaris_termios *)A(arg))->c_lflag) || + __copy_from_user (s.c_cc, ((struct solaris_termios *)A(arg))->c_cc, 16)) + return -EFAULT; + s.c_cflag = solaris_to_linux_cflag(s.c_cflag); + set_fs(KERNEL_DS); + ret = sys_ioctl(fd, cmd, (unsigned long)&s); + set_fs(old_fs); + return ret; +} + +static inline int solaris_T(unsigned int fd, unsigned int cmd, u32 arg) +{ + switch (cmd & 0xff) { + case 1: /* TCGETA */ + return linux_to_solaris_termio(fd, TCGETA, arg); + case 2: /* TCSETA */ + return solaris_to_linux_termio(fd, TCSETA, arg); + case 3: /* TCSETAW */ + return solaris_to_linux_termio(fd, TCSETAW, arg); + case 4: /* TCSETAF */ + return solaris_to_linux_termio(fd, TCSETAF, arg); + case 5: /* TCSBRK */ + return sys_ioctl(fd, TCSBRK, arg); + case 6: /* TCXONC */ + return sys_ioctl(fd, TCXONC, arg); + case 7: /* TCFLSH */ + return sys_ioctl(fd, TCFLSH, arg); + case 13: /* TCGETS */ + return linux_to_solaris_termios(fd, TCGETS, arg); + case 14: /* TCSETS */ + return solaris_to_linux_termios(fd, TCSETS, arg); + case 15: /* TCSETSW */ + return solaris_to_linux_termios(fd, TCSETSW, arg); + case 16: /* TCSETSF */ + return solaris_to_linux_termios(fd, TCSETSF, arg); + case 103: /* TIOCSWINSZ */ + return sys_ioctl(fd, TIOCSWINSZ, arg); + case 104: /* TIOCGWINSZ */ + return sys_ioctl(fd, TIOCGWINSZ, arg); + } + return -ENOSYS; +} + +static inline int solaris_t(unsigned int fd, unsigned int cmd, u32 arg) +{ + switch (cmd & 0xff) { + case 20: /* TIOCGPGRP */ + return sys_ioctl(fd, TIOCGPGRP, arg); + case 21: /* TIOCSPGRP */ + return sys_ioctl(fd, TIOCSPGRP, arg); + } + return -ENOSYS; +} + +/* }}} */ + +/* A pseudo STREAMS support {{{ */ + +struct strioctl { + int cmd, timeout, len; + u32 data; +}; + +static inline int solaris_S(unsigned int fd, unsigned int cmd, u32 arg) +{ + char *p; + int ret; + unsigned long old_fs; + struct strioctl si; + + switch (cmd & 0xff) { + case 1: /* I_NREAD */ + return -ENOSYS; + case 2: /* I_PUSH */ + p = getname32 (arg); + if (IS_ERR (p)) + return PTR_ERR(p); + putname32 (p); + return 0; + case 3: /* I_POP */ + return 0; + case 5: /* I_FLUSH */ + return 0; + case 8: /* I_STR */ + if (copy_from_user (&si, (struct strioctl *)A(arg), sizeof(struct strioctl))) + return -EFAULT; + switch ((si.cmd >> 8) & 0xff) { + case 'T': + default: + return solaris_ioctl(fd, si.cmd, si.data); + } + case 9: /* I_SETSIG */ + return sys_ioctl(fd, FIOSETOWN, current->pid); + case 10: /* I_GETSIG */ + old_fs = get_fs(); + set_fs(KERNEL_DS); + sys_ioctl(fd, FIOGETOWN, (unsigned long)&ret); + set_fs(old_fs); + if (ret == current->pid) return 0x3ff; + else return -EINVAL; + case 11: /* I_FIND */ + p = getname32 (arg); + if (IS_ERR (p)) + return PTR_ERR(p); + ret = !strcmp(p, "timod"); + putname32 (p); + return ret; + } + return -ENOSYS; +} +/* }}} */ + +asmlinkage int solaris_ioctl(unsigned int fd, unsigned int cmd, u32 arg) +{ + struct file * filp; + int error = -EBADF; + + lock_kernel(); + if(fd >= NR_OPEN) goto out; + + filp = current->files->fd[fd]; + if(!filp) goto out; + + if (!filp->f_op || !filp->f_op->ioctl) { + error = sys_ioctl (fd, cmd, (unsigned long)arg); + goto out; + } + + error = -EFAULT; + switch ((cmd >> 8) & 0xff) { + case 'S': error = solaris_S(fd, cmd, arg); break; + case 'T': error = solaris_T(fd, cmd, arg); break; + case 't': error = solaris_t(fd, cmd, arg); break; + default: + error = -ENOSYS; + break; + } +out: + if (error == -ENOSYS) { + unsigned char c = cmd>>8; + + if (c < ' ' || c > 126) c = '.'; + printk("solaris_ioctl: Unknown cmd fd(%d) cmd(%08x '%c') arg(%08x)\n", + (int)fd, (unsigned int)cmd, c, (unsigned int)arg); + error = -EINVAL; + } + unlock_kernel(); + return error; +} diff --git a/arch/sparc64/solaris/ipc.c b/arch/sparc64/solaris/ipc.c new file mode 100644 index 000000000..132028447 --- /dev/null +++ b/arch/sparc64/solaris/ipc.c @@ -0,0 +1,122 @@ +/* $Id: ipc.c,v 1.1 1997/09/03 12:29:29 jj Exp $ + * ipc.c: Solaris IPC emulation + * + * Copyright (C) 1997 Jakub Jelinek (jj@sunsite.mff.cuni.cz) + */ + +#include <linux/types.h> +#include <linux/smp_lock.h> +#include <linux/shm.h> +#include <linux/sem.h> +#include <linux/msg.h> + +#include <asm/uaccess.h> +#include <asm/string.h> +#include <asm/ipc.h> + +#include "conv.h" + +struct solaris_ipc_perm { + s32 uid; + s32 gid; + s32 cuid; + s32 cgid; + u32 mode; + u32 seq; + int key; + s32 pad[4]; +}; + +struct solaris_shmid_ds { + struct solaris_ipc_perm shm_perm; + int shm_segsz; + u32 shm_amp; + unsigned short shm_lkcnt; + char __padxx[2]; + s32 shm_lpid; + s32 shm_cpid; + u32 shm_nattch; + u32 shm_cnattch; + s32 shm_atime; + s32 shm_pad1; + s32 shm_dtime; + s32 shm_pad2; + s32 shm_ctime; + s32 shm_pad3; + unsigned short shm_cv; + char shm_pad4[2]; + u32 shm_sptas; + s32 shm_pad5[2]; +}; + +asmlinkage long solaris_shmsys(int cmd, u32 arg1, u32 arg2, u32 arg3) +{ + int (*sys_ipc)(unsigned,int,int,unsigned long,void *,long) = + (int (*)(unsigned,int,int,unsigned long,void *,long))SYS(ipc); + unsigned long old_fs; + unsigned long raddr; + int ret; + + switch (cmd) { + case 0: /* shmat */ + old_fs = get_fs(); + set_fs(KERNEL_DS); + ret = sys_ipc(SHMAT, arg1, arg3 & ~0x4000, (unsigned long)&raddr, (void *)A(arg2), 0); + set_fs(old_fs); + if (ret >= 0) return (u32)raddr; + else return ret; + case 1: /* shmctl */ + switch (arg2) { + case 3: /* SHM_LOCK */ + case 4: /* SHM_UNLOCK */ + return sys_ipc(SHMCTL, arg1, (arg2 == 3) ? SHM_LOCK : SHM_UNLOCK, 0, NULL, 0); + case 10: /* IPC_RMID */ + return sys_ipc(SHMCTL, arg1, IPC_RMID, 0, NULL, 0); + case 11: /* IPC_SET */ + { + struct shmid_ds s; + + if (get_user (s.shm_perm.uid, &(((struct solaris_shmid_ds *)A(arg3))->shm_perm.uid)) || + __get_user (s.shm_perm.gid, &(((struct solaris_shmid_ds *)A(arg3))->shm_perm.gid)) || + __get_user (s.shm_perm.mode, &(((struct solaris_shmid_ds *)A(arg3))->shm_perm.mode))) + return -EFAULT; + old_fs = get_fs(); + set_fs(KERNEL_DS); + ret = sys_ipc(SHMCTL, arg1, IPC_SET, 0, &s, 0); + set_fs(old_fs); + return ret; + } + case 12: /* IPC_STAT */ + { + struct shmid_ds s; + + old_fs = get_fs(); + set_fs(KERNEL_DS); + ret = sys_ipc(SHMCTL, arg1, IPC_SET, 0, &s, 0); + set_fs(old_fs); + if (get_user (s.shm_perm.uid, &(((struct solaris_shmid_ds *)A(arg3))->shm_perm.uid)) || + __get_user (s.shm_perm.gid, &(((struct solaris_shmid_ds *)A(arg3))->shm_perm.gid)) || + __get_user (s.shm_perm.cuid, &(((struct solaris_shmid_ds *)A(arg3))->shm_perm.cuid)) || + __get_user (s.shm_perm.cgid, &(((struct solaris_shmid_ds *)A(arg3))->shm_perm.cgid)) || + __get_user (s.shm_perm.mode, &(((struct solaris_shmid_ds *)A(arg3))->shm_perm.mode)) || + __get_user (s.shm_perm.seq, &(((struct solaris_shmid_ds *)A(arg3))->shm_perm.seq)) || + __get_user (s.shm_perm.key, &(((struct solaris_shmid_ds *)A(arg3))->shm_perm.key)) || + __get_user (s.shm_segsz, &(((struct solaris_shmid_ds *)A(arg3))->shm_segsz)) || + __get_user (s.shm_lpid, &(((struct solaris_shmid_ds *)A(arg3))->shm_lpid)) || + __get_user (s.shm_cpid, &(((struct solaris_shmid_ds *)A(arg3))->shm_cpid)) || + __get_user (s.shm_nattch, &(((struct solaris_shmid_ds *)A(arg3))->shm_nattch)) || + __get_user (s.shm_atime, &(((struct solaris_shmid_ds *)A(arg3))->shm_atime)) || + __get_user (s.shm_dtime, &(((struct solaris_shmid_ds *)A(arg3))->shm_dtime)) || + __get_user (s.shm_ctime, &(((struct solaris_shmid_ds *)A(arg3))->shm_ctime))) + return -EFAULT; + return ret; + } + default: return -EINVAL; + } + case 2: /* shmdt */ + return sys_ipc(SHMDT, 0, 0, 0, (void *)A(arg1), 0); + case 3: /* shmget */ + return sys_ipc(SHMGET, arg1, arg2, arg3, NULL, 0); + } + return -EINVAL; +} diff --git a/arch/sparc64/solaris/misc.c b/arch/sparc64/solaris/misc.c new file mode 100644 index 000000000..fdabd0e26 --- /dev/null +++ b/arch/sparc64/solaris/misc.c @@ -0,0 +1,463 @@ +/* $Id: misc.c,v 1.4 1997/09/04 14:57:31 jj Exp $ + * misc.c: Miscelaneous syscall emulation for Solaris + * + * Copyright (C) 1997 Jakub Jelinek (jj@sunsite.mff.cuni.cz) + */ + +#include <linux/module.h> +#include <linux/types.h> +#include <linux/smp_lock.h> +#include <linux/utsname.h> +#include <linux/limits.h> +#include <linux/mm.h> +#include <linux/smp.h> + +#include <asm/uaccess.h> +#include <asm/string.h> +#include <asm/oplib.h> +#include <asm/idprom.h> +#include <asm/machines.h> + +#include "conv.h" + +/* Conversion from Linux to Solaris errnos. 0-34 are identity mapped. + Some Linux errnos (EPROCLIM, EDOTDOT, ERREMOTE, EUCLEAN, ENOTNAM, + ENAVAIL, EISNAM, EREMOTEIO, ENOMEDIUM, EMEDIUMTYPE) have no Solaris + equivalents. I return EINVAL in that case, which is very wrong. If + someone suggest a better value for them, you're welcomed. + On the other side, Solaris ECANCELED and ENOTSUP have no Linux equivalents, + but that doesn't matter here. --jj */ +int solaris_err_table[] = { +/* 0 */ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, +/* 10 */ 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, +/* 20 */ 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, +/* 30 */ 30, 31, 32, 33, 34, 22, 150, 149, 95, 96, +/* 40 */ 97, 98, 99, 120, 121, 122, 123, 124, 125, 126, +/* 50 */ 127, 128, 129, 130, 131, 132, 133, 134, 143, 144, +/* 60 */ 145, 146, 90, 78, 147, 148, 93, 22, 94, 49, +/* 70 */ 151, 66, 60, 62, 63, 35, 77, 36, 45, 46, +/* 80 */ 64, 22, 67, 68, 69, 70, 71, 74, 22, 82, +/* 90 */ 89, 92, 79, 81, 37, 38, 39, 40, 41, 42, +/* 100 */ 43, 44, 50, 51, 52, 53, 54, 55, 56, 57, +/* 110 */ 87, 61, 84, 65, 83, 80, 91, 22, 22, 22, +/* 120 */ 22, 22, 88, 86, 85, 22, 22, +}; + +asmlinkage u32 solaris_mmap(u32 addr, u32 len, u32 prot, u32 flags, u32 fd, u32 off) +{ + u32 (*sunos_mmap)(u32,u32,u32,u32,u32,u32) = + (u32 (*)(u32,u32,u32,u32,u32,u32))SUNOS(71); + u32 ret; + + ret = sunos_mmap(addr,len,prot,flags,fd,off); + /* sunos_mmap sets personality to PER_BSD */ + current->personality = PER_SVR4; + return ret; +} + +asmlinkage int solaris_brk(u32 brk) +{ + int (*sunos_brk)(u32) = (int (*)(u32))SUNOS(17); + + return sunos_brk(brk); +} + +#define set_utsfield(to, from, dotchop, countfrom) { \ + char *p; \ + int i, len = (countfrom) ? \ + ((sizeof(to) > sizeof(from) ? \ + sizeof(from) : sizeof(to))) : sizeof(to); \ + copy_to_user_ret(to, from, len, -EFAULT); \ + if (dotchop) \ + for (p=from,i=0; *p && *p != '.' && --len; p++,i++); \ + else \ + i = len - 1; \ + __put_user_ret('\0', (char *)(to+i), -EFAULT); \ +} + +struct sol_uname { + char sysname[9]; + char nodename[9]; + char release[9]; + char version[9]; + char machine[9]; +}; + +struct sol_utsname { + char sysname[257]; + char nodename[257]; + char release[257]; + char version[257]; + char machine[257]; +}; + +static char *machine(void) +{ + switch (sparc_cpu_model) { + case sun4: return "sun4"; + case sun4c: return "sun4c"; + case sun4e: return "sun4e"; + case sun4m: return "sun4m"; + case sun4d: return "sun4d"; + case sun4u: return "sun4u"; + default: return "sparc"; + } +} + +static char *platform(char *buffer) +{ + int i; + struct { + char *platform; + int id_machtype; + } platforms [] = { + { "sun4", (SM_SUN4 | SM_4_110) }, + { "sun4", (SM_SUN4 | SM_4_260) }, + { "sun4", (SM_SUN4 | SM_4_330) }, + { "sun4", (SM_SUN4 | SM_4_470) }, + { "SUNW,Sun_4_60", (SM_SUN4C | SM_4C_SS1) }, + { "SUNW,Sun_4_40", (SM_SUN4C | SM_4C_IPC) }, + { "SUNW,Sun_4_65", (SM_SUN4C | SM_4C_SS1PLUS) }, + { "SUNW,Sun_4_20", (SM_SUN4C | SM_4C_SLC) }, + { "SUNW,Sun_4_75", (SM_SUN4C | SM_4C_SS2) }, + { "SUNW,Sun_4_25", (SM_SUN4C | SM_4C_ELC) }, + { "SUNW,Sun_4_50", (SM_SUN4C | SM_4C_IPX) }, + { "SUNW,Sun_4_600", (SM_SUN4M | SM_4M_SS60) }, + { "SUNW,SPARCstation-5", (SM_SUN4M | SM_4M_SS50) }, + { "SUNW,SPARCstation-20", (SM_SUN4M | SM_4M_SS40) } + }; + + *buffer = 0; + prom_getproperty(prom_root_node, "name", buffer, 256); + if (*buffer) { + char *p; + + for (p = buffer; *p; p++) + if (*p == '/' || *p == ' ') *p = '_'; + return buffer; + } + for (i = 0; i < sizeof (platforms)/sizeof (platforms[0]); i++) + if (platforms[i].id_machtype == idprom->id_machtype) + return platforms[i].platform; + return "sun4c"; +} + +static char *serial(char *buffer) +{ + int node = prom_getchild(prom_root_node); + + node = prom_searchsiblings(node, "options"); + *buffer = 0; + prom_getproperty(node, "system-board-serial#", buffer, 256); + if (!*buffer) + return "4512348717234"; + else + return buffer; +} + +asmlinkage int solaris_utssys(u32 buf, u32 flags, int which, u32 buf2) +{ + switch (which) { + case 0: /* old uname */ + /* Lets cheat */ + set_utsfield(((struct sol_uname *)A(buf))->sysname, + "SunOS", 1, 0); + set_utsfield(((struct sol_uname *)A(buf))->nodename, + system_utsname.nodename, 1, 1); + set_utsfield(((struct sol_uname *)A(buf))->release, + "2.6", 0, 0); + set_utsfield(((struct sol_uname *)A(buf))->version, + "Generic", 0, 0); + set_utsfield(((struct sol_uname *)A(buf))->machine, + machine(), 0, 0); + return 0; + case 2: /* ustat */ + return -ENOSYS; + case 3: /* fusers */ + return -ENOSYS; + default: + return -ENOSYS; + } +} + +asmlinkage int solaris_utsname(u32 buf) +{ + /* Why should we not lie a bit? */ + set_utsfield(((struct sol_utsname *)A(buf))->sysname, + "SunOS", 0, 0); + set_utsfield(((struct sol_utsname *)A(buf))->nodename, + system_utsname.nodename, 1, 1); + set_utsfield(((struct sol_utsname *)A(buf))->release, + "5.6", 0, 0); + set_utsfield(((struct sol_utsname *)A(buf))->version, + "Generic", 0, 0); + set_utsfield(((struct sol_utsname *)A(buf))->machine, + machine(), 0, 0); + return 0; +} + +#define SI_SYSNAME 1 /* return name of operating system */ +#define SI_HOSTNAME 2 /* return name of node */ +#define SI_RELEASE 3 /* return release of operating system */ +#define SI_VERSION 4 /* return version field of utsname */ +#define SI_MACHINE 5 /* return kind of machine */ +#define SI_ARCHITECTURE 6 /* return instruction set arch */ +#define SI_HW_SERIAL 7 /* return hardware serial number */ +#define SI_HW_PROVIDER 8 /* return hardware manufacturer */ +#define SI_SRPC_DOMAIN 9 /* return secure RPC domain */ +#define SI_PLATFORM 513 /* return platform identifier */ + +asmlinkage int solaris_sysinfo(int cmd, u32 buf, s32 count) +{ + char *p, *q, *r; + char buffer[256]; + int len; + + /* Again, we cheat :)) */ + switch (cmd) { + case SI_SYSNAME: r = "SunOS"; break; + case SI_HOSTNAME: + r = buffer + 256; + for (p = system_utsname.nodename, q = buffer; + q < r && *p && *p != '.'; *q++ = *p++); + *q = 0; + r = buffer; + break; + case SI_RELEASE: r = "5.6"; break; + case SI_MACHINE: r = machine(); break; + case SI_ARCHITECTURE: r = "sparc"; break; + case SI_HW_PROVIDER: r = "Sun_Microsystems"; break; + case SI_HW_SERIAL: r = serial(buffer); break; + case SI_PLATFORM: r = platform(buffer); break; + case SI_SRPC_DOMAIN: r = ""; break; + case SI_VERSION: r = "Generic"; break; + default: return -EINVAL; + } + len = strlen(r) + 1; + if (count < len) { + copy_to_user_ret((char *)A(buf), r, count - 1, -EFAULT); + __put_user_ret(0, (char *)A(buf) + count - 1, -EFAULT); + } else + copy_to_user_ret((char *)A(buf), r, len, -EFAULT); + return len; +} + +#define SOLARIS_CONFIG_NGROUPS 2 +#define SOLARIS_CONFIG_CHILD_MAX 3 +#define SOLARIS_CONFIG_OPEN_FILES 4 +#define SOLARIS_CONFIG_POSIX_VER 5 +#define SOLARIS_CONFIG_PAGESIZE 6 +#define SOLARIS_CONFIG_CLK_TCK 7 +#define SOLARIS_CONFIG_XOPEN_VER 8 +#define SOLARIS_CONFIG_PROF_TCK 10 +#define SOLARIS_CONFIG_NPROC_CONF 11 +#define SOLARIS_CONFIG_NPROC_ONLN 12 +#define SOLARIS_CONFIG_AIO_LISTIO_MAX 13 +#define SOLARIS_CONFIG_AIO_MAX 14 +#define SOLARIS_CONFIG_AIO_PRIO_DELTA_MAX 15 +#define SOLARIS_CONFIG_DELAYTIMER_MAX 16 +#define SOLARIS_CONFIG_MQ_OPEN_MAX 17 +#define SOLARIS_CONFIG_MQ_PRIO_MAX 18 +#define SOLARIS_CONFIG_RTSIG_MAX 19 +#define SOLARIS_CONFIG_SEM_NSEMS_MAX 20 +#define SOLARIS_CONFIG_SEM_VALUE_MAX 21 +#define SOLARIS_CONFIG_SIGQUEUE_MAX 22 +#define SOLARIS_CONFIG_SIGRT_MIN 23 +#define SOLARIS_CONFIG_SIGRT_MAX 24 +#define SOLARIS_CONFIG_TIMER_MAX 25 +#define SOLARIS_CONFIG_PHYS_PAGES 26 +#define SOLARIS_CONFIG_AVPHYS_PAGES 27 + +asmlinkage int solaris_sysconf(int id) +{ + switch (id) { + case SOLARIS_CONFIG_NGROUPS: return NGROUPS_MAX; + case SOLARIS_CONFIG_CHILD_MAX: return CHILD_MAX; + case SOLARIS_CONFIG_OPEN_FILES: return OPEN_MAX; + case SOLARIS_CONFIG_POSIX_VER: return 199309; + case SOLARIS_CONFIG_PAGESIZE: return PAGE_SIZE; + case SOLARIS_CONFIG_XOPEN_VER: return 3; + case SOLARIS_CONFIG_CLK_TCK: + case SOLARIS_CONFIG_PROF_TCK: + return prom_getintdefault( + linux_cpus[smp_processor_id()].prom_node, + "clock-frequency", 167000000); +#ifdef __SMP__ + case SOLARIS_CONFIG_NPROC_CONF: return NCPUS; + case SOLARIS_CONFIG_NPROC_ONLN: return smp_num_cpus; +#else + case SOLARIS_CONFIG_NPROC_CONF: return 1; + case SOLARIS_CONFIG_NPROC_ONLN: return 1; +#endif + case SOLARIS_CONFIG_SIGRT_MIN: return 37; + case SOLARIS_CONFIG_SIGRT_MAX: return 44; + case SOLARIS_CONFIG_PHYS_PAGES: + case SOLARIS_CONFIG_AVPHYS_PAGES: + { + struct sysinfo s; + + si_meminfo(&s); + if (id == SOLARIS_CONFIG_PHYS_PAGES) + return s.totalram >>= PAGE_SHIFT; + else + return s.freeram >>= PAGE_SHIFT; + } + /* XXX support these as well -jj */ + case SOLARIS_CONFIG_AIO_LISTIO_MAX: return -EINVAL; + case SOLARIS_CONFIG_AIO_MAX: return -EINVAL; + case SOLARIS_CONFIG_AIO_PRIO_DELTA_MAX: return -EINVAL; + case SOLARIS_CONFIG_DELAYTIMER_MAX: return -EINVAL; + case SOLARIS_CONFIG_MQ_OPEN_MAX: return -EINVAL; + case SOLARIS_CONFIG_MQ_PRIO_MAX: return -EINVAL; + case SOLARIS_CONFIG_RTSIG_MAX: return -EINVAL; + case SOLARIS_CONFIG_SEM_NSEMS_MAX: return -EINVAL; + case SOLARIS_CONFIG_SEM_VALUE_MAX: return -EINVAL; + case SOLARIS_CONFIG_SIGQUEUE_MAX: return -EINVAL; + case SOLARIS_CONFIG_TIMER_MAX: return -EINVAL; + default: return -EINVAL; + } +} + +asmlinkage int solaris_procids(int cmd, s32 pid, s32 pgid) +{ + int ret; + + switch (cmd) { + case 0: /* getpgrp */ + return current->pgrp; + case 1: /* setpgrp */ + { + int (*sys_setpgid)(pid_t,pid_t) = + (int (*)(pid_t,pid_t))SYS(setpgid); + + /* can anyone explain me the difference between + Solaris setpgrp and setsid? */ + ret = sys_setpgid(0, 0); + if (ret) return ret; + current->tty = NULL; + return current->pgrp; + } + case 2: /* getsid */ + { + int (*sys_getsid)(pid_t) = (int (*)(pid_t))SYS(getsid); + return sys_getsid(pid); + } + case 3: /* setsid */ + { + int (*sys_setsid)(void) = (int (*)(void))SYS(setsid); + return sys_setsid(); + } + case 4: /* getpgid */ + { + int (*sys_getpgid)(pid_t) = (int (*)(pid_t))SYS(getpgid); + return sys_getpgid(pid); + } + case 5: /* setpgid */ + { + int (*sys_setpgid)(pid_t,pid_t) = + (int (*)(pid_t,pid_t))SYS(setpgid); + return sys_setpgid(pid,pgid); + } + } + return -EINVAL; +} + +asmlinkage int do_sol_unimplemented(struct pt_regs *regs) +{ + printk ("Unimplemented Solaris syscall %d %08x %08x %08x %08x\n", + (int)regs->u_regs[UREG_G1], + (int)regs->u_regs[UREG_I0], + (int)regs->u_regs[UREG_I1], + (int)regs->u_regs[UREG_I2], + (int)regs->u_regs[UREG_I3]); + return -ENOSYS; +} + +asmlinkage void solaris_register(void) +{ + lock_kernel(); + current->personality = PER_SVR4; + if (current->exec_domain && current->exec_domain->module) + __MOD_DEC_USE_COUNT(current->exec_domain->module); + current->exec_domain = lookup_exec_domain(current->personality); + if (current->exec_domain && current->exec_domain->module) + __MOD_INC_USE_COUNT(current->exec_domain->module); + unlock_kernel(); +} + +extern long solaris_to_linux_signals[], linux_to_solaris_signals[]; + +struct exec_domain solaris_exec_domain = { + "Solaris", + (lcall7_func)NULL, + 1, 1, /* PER_SVR4 personality */ + solaris_to_linux_signals, + linux_to_solaris_signals, +#ifdef MODULE + &__this_module, +#else + NULL, +#endif + NULL +}; + +#ifdef MODULE + +MODULE_AUTHOR("Jakub Jelinek (jj@sunsite.mff.cuni.cz)"); +MODULE_DESCRIPTION("Solaris binary emulation module"); + +#ifdef __sparc_v9__ +extern u32 tl0_solaris[8]; +#define update_ttable(x) \ + tl0_solaris[3] = (((long)(x) - (long)tl0_solaris - 3) >> 2) | 0x40000000; \ + __asm__ __volatile__ ("membar #StoreStore; flush %0" : : "r" (&tl0_solaris[3])) +#else +#endif + +extern u32 solaris_sparc_syscall[]; +extern u32 solaris_syscall[]; +extern int init_socksys(void); +extern void cleanup_socksys(void); + +int init_module(void) +{ + int ret; + register_exec_domain(&solaris_exec_domain); + if ((ret = init_socksys())) { + unregister_exec_domain(&solaris_exec_domain); + return ret; + } + update_ttable(solaris_sparc_syscall); + return 0; +} + +void cleanup_module(void) +{ + update_ttable(solaris_syscall); + cleanup_socksys(); + unregister_exec_domain(&solaris_exec_domain); +} + +#else +int init_solaris_emul(void) +{ + register_exec_domain(&solaris_exec_domain); + init_socksys(); +} +#endif + +#ifdef DEBUG_SOLARIS +void entry_printk(int sysno, struct pt_regs *regs) +{ + printk ("Entering %d\n", sysno); + printk ("%08x %08x %08x %08x\n", (int)regs->u_regs[UREG_I0], + (int)regs->u_regs[UREG_I1], + (int)regs->u_regs[UREG_I2], + (int)regs->u_regs[UREG_I3]); +} + +void exit_printk(unsigned long ret) +{ + printk ("Returning %016lx\n", ret); +} +#endif diff --git a/arch/sparc64/solaris/signal.c b/arch/sparc64/solaris/signal.c new file mode 100644 index 000000000..6d3081c03 --- /dev/null +++ b/arch/sparc64/solaris/signal.c @@ -0,0 +1,419 @@ +/* $Id: signal.c,v 1.2 1997/09/03 12:29:19 jj Exp $ + * signal.c: Signal emulation for Solaris + * + * Copyright (C) 1997 Jakub Jelinek (jj@sunsite.mff.cuni.cz) + */ + +#include <linux/types.h> +#include <linux/smp_lock.h> + +#include <asm/uaccess.h> +#include <asm/svr4.h> +#include <asm/string.h> + +#include "conv.h" +#include "signal.h" + +#define _S(nr) (1L<<((nr)-1)) + +#define _BLOCKABLE (~(_S(SIGKILL) | _S(SIGSTOP))) + +long linux_to_solaris_signals[] = { + 0, + SOLARIS_SIGHUP, SOLARIS_SIGINT, + SOLARIS_SIGQUIT, SOLARIS_SIGILL, + SOLARIS_SIGTRAP, SOLARIS_SIGIOT, + SOLARIS_SIGEMT, SOLARIS_SIGFPE, + SOLARIS_SIGKILL, SOLARIS_SIGBUS, + SOLARIS_SIGSEGV, SOLARIS_SIGSYS, + SOLARIS_SIGPIPE, SOLARIS_SIGALRM, + SOLARIS_SIGTERM, SOLARIS_SIGURG, + SOLARIS_SIGSTOP, SOLARIS_SIGTSTP, + SOLARIS_SIGCONT, SOLARIS_SIGCLD, + SOLARIS_SIGTTIN, SOLARIS_SIGTTOU, + SOLARIS_SIGPOLL, SOLARIS_SIGXCPU, + SOLARIS_SIGXFSZ, SOLARIS_SIGVTALRM, + SOLARIS_SIGPROF, SOLARIS_SIGWINCH, + SOLARIS_SIGUSR1, SOLARIS_SIGUSR1, + SOLARIS_SIGUSR2, -1, +}; + +long solaris_to_linux_signals[] = { + 0, + SIGHUP, SIGINT, SIGQUIT, SIGILL, + SIGTRAP, SIGIOT, SIGEMT, SIGFPE, + SIGKILL, SIGBUS, SIGSEGV, SIGSYS, + SIGPIPE, SIGALRM, SIGTERM, SIGUSR1, + SIGUSR2, SIGCHLD, -1, SIGWINCH, + SIGURG, SIGPOLL, SIGSTOP, SIGTSTP, + SIGCONT, SIGTTIN, SIGTTOU, SIGVTALRM, + SIGPROF, SIGXCPU, SIGXFSZ, -1, + -1, -1, -1, -1, + -1, -1, -1, -1, + -1, -1, -1, -1, +}; + +static inline long mapsig(long sig) +{ + if ((unsigned long)sig > SOLARIS_NSIGNALS) + return -EINVAL; + return solaris_to_linux_signals[sig]; +} + +asmlinkage int solaris_kill(int pid, int sig) +{ + int (*sys_kill)(int,int) = + (int (*)(int,int))SYS(kill); + int s = mapsig(sig); + + if (s < 0) return s; + return sys_kill(pid, s); +} + +static long sig_handler(int sig, u32 arg, int one_shot) +{ + struct sigaction sa, old; + int ret; + unsigned long old_fs = get_fs(); + int (*sys_sigaction)(int,struct sigaction *,struct sigaction *) = + (int (*)(int,struct sigaction *,struct sigaction *))SYS(sigaction); + + sa.sa_mask = 0L; + sa.sa_restorer = NULL; + sa.sa_handler = (__sighandler_t)A(arg); + sa.sa_flags = 0; + if (one_shot) sa.sa_flags = SA_ONESHOT | SA_NOMASK; + set_fs (KERNEL_DS); + ret = sys_sigaction(sig, &sa, &old); + set_fs (old_fs); + if (ret < 0) return ret; + return (u32)(long)old.sa_handler; +} + +static inline long solaris_signal(int sig, u32 arg) +{ + return sig_handler (sig, arg, 1); +} + +static long solaris_sigset(int sig, u32 arg) +{ + if (arg != 2) /* HOLD */ { + spin_lock_irq(¤t->sigmask_lock); + current->blocked &= ~_S(sig); + spin_unlock_irq(¤t->sigmask_lock); + return sig_handler (sig, arg, 0); + } else { + sigset_t n = _S(sig) & _BLOCKABLE; + spin_lock_irq(¤t->sigmask_lock); + current->blocked |= n; + spin_unlock_irq(¤t->sigmask_lock); + return 0; + } +} + +static inline long solaris_sighold(int sig) +{ + return solaris_sigset(sig, 2); +} + +static inline long solaris_sigrelse(int sig) +{ + spin_lock_irq(¤t->sigmask_lock); + current->blocked &= ~_S(sig); + spin_unlock_irq(¤t->sigmask_lock); + return 0; +} + +static inline long solaris_sigignore(int sig) +{ + return sig_handler (sig, (u32)SIG_IGN, 0); +} + +static inline long solaris_sigpause(int sig) +{ + printk ("Need to support solaris sigpause\n"); + return -ENOSYS; +} + +asmlinkage long solaris_sigfunc(int sig, u32 arg) +{ + int func = sig & ~0xff; + + sig = mapsig(sig & 0xff); + if (sig < 0) return sig; + switch (func) { + case 0: return solaris_signal(sig, arg); + case 0x100: return solaris_sigset(sig, arg); + case 0x200: return solaris_sighold(sig); + case 0x400: return solaris_sigrelse(sig); + case 0x800: return solaris_sigignore(sig); + case 0x1000: return solaris_sigpause(sig); + } + return -EINVAL; +} + +typedef struct { + u32 __sigbits[4]; +} sol_sigset_t; + +static inline int mapin(u32 *p, sigset_t *q) +{ + int i; + u32 x; + int sig; + + *q = 0L; + x = p[0]; + for (i = 1; i <= SOLARIS_NSIGNALS; i++) { + if (x & 1) { + sig = solaris_to_linux_signals[i]; + if (sig == -1) + return -EINVAL; + *q |= 1L << (sig - 1); + } + x >>= 1; + if (i == 32) + x = p[1]; + } + return 0; +} + +static inline int mapout(sigset_t *q, u32 *p) +{ + int i; + sigset_t x; + int sig; + + p[0] = 0; + p[1] = 0; + x = *q; + for (i = 1; i <= 32; i++, x >>= 1) { + if (x & 1) { + sig = linux_to_solaris_signals[i]; + if (sig == -1) + return -EINVAL; + if (sig > 32) + p[1] |= 1L << (sig - 33); + else + p[0] |= 1L << (sig - 1); + } + } + return 0; + +} + +asmlinkage int solaris_sigprocmask(int how, u32 in, u32 out) +{ + sigset_t in_s, *ins, out_s, *outs; + unsigned long old_fs = get_fs(); + int ret; + int (*sys_sigprocmask)(int,sigset_t *,sigset_t *) = + (int (*)(int,sigset_t *,sigset_t *))SYS(sigprocmask); + + ins = NULL; outs = NULL; + if (in) { + u32 tmp[2]; + + if (copy_from_user (tmp, (sol_sigset_t *)A(in), 2*sizeof(u32))) + return -EFAULT; + ins = &in_s; + if (mapin (tmp, ins)) return -EINVAL; + } + if (out) outs = &out_s; + set_fs (KERNEL_DS); + ret = sys_sigprocmask((how == 3) ? SIG_SETMASK : how, ins, outs); + set_fs (old_fs); + if (ret) return ret; + if (out) { + u32 tmp[4]; + + tmp[2] = 0; tmp[3] = 0; + if (mapout (outs, tmp)) return -EINVAL; + if (copy_to_user((sol_sigset_t *)A(out), tmp, 4*sizeof(u32))) + return -EFAULT; + } + return 0; +} + +asmlinkage long do_sol_sigsuspend(u32 mask) +{ + sigset_t s; + u32 tmp[2]; + + if (copy_from_user (tmp, (sol_sigset_t *)A(mask), 2*sizeof(u32))) + return -EFAULT; + if (mapin (tmp, &s)) return -EINVAL; + return (long)s; +} + +struct sol_sigaction { + int sa_flags; + u32 sa_handler; + u32 sa_mask[4]; + int sa_resv[2]; +}; + +asmlinkage int solaris_sigaction(int sig, u32 act, u32 old) +{ + u32 tmp, tmp2[4]; + struct sigaction s, s2; + int ret; + unsigned long old_fs = get_fs(); + int (*sys_sigaction)(int,struct sigaction *,struct sigaction *) = + (int (*)(int,struct sigaction *,struct sigaction *))SYS(sigaction); + + sig = mapsig(sig); + if (sig < 0) { + /* We cheat a little bit for Solaris only signals */ + if (old && clear_user((struct sol_sigaction *)A(old), sizeof(struct sol_sigaction))) + return -EFAULT; + return 0; + } + if (act) { + if (get_user (tmp, &((struct sol_sigaction *)A(act))->sa_flags)) + return -EFAULT; + s.sa_flags = 0; + if (tmp & SOLARIS_SA_ONSTACK) s.sa_flags |= SA_STACK; + if (tmp & SOLARIS_SA_RESTART) s.sa_flags |= SA_RESTART; + if (tmp & SOLARIS_SA_NODEFER) s.sa_flags |= SA_NOMASK; + if (tmp & SOLARIS_SA_RESETHAND) s.sa_flags |= SA_ONESHOT; + if (tmp & SOLARIS_SA_NOCLDSTOP) s.sa_flags |= SA_NOCLDSTOP; + if (get_user (tmp, &((struct sol_sigaction *)A(act))->sa_handler) || + copy_from_user (tmp2, &((struct sol_sigaction *)A(act))->sa_mask, 2*sizeof(u32))) + return -EFAULT; + s.sa_handler = (__sighandler_t)A(tmp); + if (mapin (tmp2, &s.sa_mask)) return -EINVAL; + s.sa_restorer = 0; + } + set_fs(KERNEL_DS); + ret = sys_sigaction(sig, act ? &s : NULL, old ? &s2 : NULL); + set_fs(old_fs); + if (ret) return ret; + if (old) { + if (mapout (&s2.sa_mask, tmp2)) return -EINVAL; + tmp = 0; tmp2[2] = 0; tmp2[3] = 0; + if (s2.sa_flags & SA_STACK) tmp |= SOLARIS_SA_ONSTACK; + if (s2.sa_flags & SA_RESTART) tmp |= SOLARIS_SA_RESTART; + if (s2.sa_flags & SA_NOMASK) tmp |= SOLARIS_SA_NODEFER; + if (s2.sa_flags & SA_ONESHOT) tmp |= SOLARIS_SA_RESETHAND; + if (s2.sa_flags & SA_NOCLDSTOP) tmp |= SOLARIS_SA_NOCLDSTOP; + if (put_user (tmp, &((struct sol_sigaction *)A(old))->sa_flags) || + __put_user ((u32)(long)s2.sa_handler, &((struct sol_sigaction *)A(old))->sa_handler) || + copy_to_user (&((struct sol_sigaction *)A(old))->sa_mask, tmp2, 4*sizeof(u32))) + return -EFAULT; + } + return 0; +} + +asmlinkage int solaris_sigpending(int which, u32 set) +{ + sigset_t s; + u32 tmp[4]; + switch (which) { + case 1: /* sigpending */ + lock_kernel(); + s = current->blocked & current->signal; + unlock_kernel(); + break; + case 2: /* sigfillset - I just set signals which have linux equivalents */ + s = 0x7fffffff; + break; + default: return -EINVAL; + } + if (mapout (&s, tmp)) return -EINVAL; + tmp[2] = 0; tmp[3] = 0; + if (copy_to_user ((u32 *)A(set), tmp, sizeof(tmp))) + return -EFAULT; + return 0; +} + +asmlinkage int solaris_wait(u32 stat_loc) +{ + int (*sys_wait4)(pid_t,unsigned int *, int, struct rusage *) = + (int (*)(pid_t,unsigned int *, int, struct rusage *))SYS(wait4); + int ret, status; + + ret = sys_wait4(-1, (unsigned int *)A(stat_loc), WUNTRACED, NULL); + if (ret >= 0 && stat_loc) { + if (get_user (status, (unsigned int *)A(stat_loc))) + return -EFAULT; + if (((status - 1) & 0xffff) < 0xff) + status = linux_to_solaris_signals[status & 0x7f] & 0x7f; + else if ((status & 0xff) == 0x7f) + status = (linux_to_solaris_signals[(status >> 8) & 0xff] << 8) | 0x7f; + if (__put_user (status, (unsigned int *)A(stat_loc))) + return -EFAULT; + } + return ret; +} + +asmlinkage int solaris_waitid(int idtype, s32 pid, u32 info, int options) +{ + int (*sys_wait4)(pid_t,unsigned int *, int, struct rusage *) = + (int (*)(pid_t,unsigned int *, int, struct rusage *))SYS(wait4); + int opts, status, ret; + + switch (idtype) { + case 0: /* P_PID */ break; + case 1: /* P_PGID */ pid = -pid; break; + case 7: /* P_ALL */ pid = -1; break; + default: return -EINVAL; + } + opts = 0; + if (options & SOLARIS_WUNTRACED) opts |= WUNTRACED; + if (options & SOLARIS_WNOHANG) opts |= WNOHANG; + current->state = TASK_RUNNING; + ret = sys_wait4(pid, (unsigned int *)A(info), opts, NULL); + if (ret < 0) return ret; + if (info) { + struct sol_siginfo *s = (struct sol_siginfo *)A(info); + + if (get_user (status, (unsigned int *)A(info))) return -EFAULT; + __put_user_ret (SOLARIS_SIGCLD, &s->si_signo, -EFAULT); + __put_user_ret (ret, &s->_data._proc._pid, -EFAULT); + switch (status & 0xff) { + case 0: ret = SOLARIS_CLD_EXITED; + status = (status >> 8) & 0xff; + break; + case 0x7f: + status = (status >> 8) & 0xff; + switch (status) { + case SIGSTOP: + case SIGTSTP: ret = SOLARIS_CLD_STOPPED; + default: ret = SOLARIS_CLD_EXITED; + } + status = linux_to_solaris_signals[status]; + break; + default: + if (status & 0x80) ret = SOLARIS_CLD_DUMPED; + else ret = SOLARIS_CLD_KILLED; + status = linux_to_solaris_signals[status & 0x7f]; + break; + } + __put_user_ret (ret, &s->si_code, -EFAULT); + __put_user_ret (status, &s->_data._proc._pdata._cld._status, -EFAULT); + } + return 0; +} + +extern int svr4_setcontext(svr4_ucontext_t *c, struct pt_regs *regs); +extern int svr4_getcontext(svr4_ucontext_t *c, struct pt_regs *regs); + +asmlinkage int solaris_context(struct pt_regs *regs) +{ + switch ((unsigned)regs->u_regs[UREG_I0]) { + case 0: /* getcontext */ + return svr4_getcontext((svr4_ucontext_t *)(long)(u32)regs->u_regs[UREG_I1], regs); + case 1: /* setcontext */ + return svr4_setcontext((svr4_ucontext_t *)(long)(u32)regs->u_regs[UREG_I1], regs); + default: + return -EINVAL; + + } +} + +asmlinkage int solaris_sigaltstack(u32 ss, u32 oss) +{ +/* XXX Implement this soon */ + return 0; +} diff --git a/arch/sparc64/solaris/signal.h b/arch/sparc64/solaris/signal.h new file mode 100644 index 000000000..2e948c788 --- /dev/null +++ b/arch/sparc64/solaris/signal.h @@ -0,0 +1,109 @@ +/* $Id: signal.h,v 1.2 1997/09/03 12:29:21 jj Exp $ + * signal.h: Signal emulation for Solaris + * + * Copyright (C) 1997 Jakub Jelinek (jj@sunsite.mff.cuni.cz) + */ + +#define SOLARIS_SIGHUP 1 +#define SOLARIS_SIGINT 2 +#define SOLARIS_SIGQUIT 3 +#define SOLARIS_SIGILL 4 +#define SOLARIS_SIGTRAP 5 +#define SOLARIS_SIGIOT 6 +#define SOLARIS_SIGEMT 7 +#define SOLARIS_SIGFPE 8 +#define SOLARIS_SIGKILL 9 +#define SOLARIS_SIGBUS 10 +#define SOLARIS_SIGSEGV 11 +#define SOLARIS_SIGSYS 12 +#define SOLARIS_SIGPIPE 13 +#define SOLARIS_SIGALRM 14 +#define SOLARIS_SIGTERM 15 +#define SOLARIS_SIGUSR1 16 +#define SOLARIS_SIGUSR2 17 +#define SOLARIS_SIGCLD 18 +#define SOLARIS_SIGPWR 19 +#define SOLARIS_SIGWINCH 20 +#define SOLARIS_SIGURG 21 +#define SOLARIS_SIGPOLL 22 +#define SOLARIS_SIGSTOP 23 +#define SOLARIS_SIGTSTP 24 +#define SOLARIS_SIGCONT 25 +#define SOLARIS_SIGTTIN 26 +#define SOLARIS_SIGTTOU 27 +#define SOLARIS_SIGVTALRM 28 +#define SOLARIS_SIGPROF 29 +#define SOLARIS_SIGXCPU 30 +#define SOLARIS_SIGXFSZ 31 +#define SOLARIS_SIGWAITING 32 +#define SOLARIS_SIGLWP 33 +#define SOLARIS_SIGFREEZE 34 +#define SOLARIS_SIGTHAW 35 +#define SOLARIS_SIGCANCEL 36 +#define SOLARIS_SIGRTMIN 37 +#define SOLARIS_SIGRTMAX 44 +#define SOLARIS_NSIGNALS 44 + + +#define SOLARIS_SA_ONSTACK 1 +#define SOLARIS_SA_RESETHAND 2 +#define SOLARIS_SA_RESTART 4 +#define SOLARIS_SA_SIGINFO 8 +#define SOLARIS_SA_NODEFER 16 +#define SOLARIS_SA_NOCLDWAIT 0x10000 +#define SOLARIS_SA_NOCLDSTOP 0x20000 + +struct sol_siginfo { + int si_signo; + int si_code; + int si_errno; + union { + char pad[128-3*sizeof(int)]; + struct { + s32 _pid; + union { + struct { + s32 _uid; + s32 _value; + } _kill; + struct { + s32 _utime; + int _status; + s32 _stime; + } _cld; + } _pdata; + } _proc; + struct { /* SIGSEGV, SIGBUS, SIGILL and SIGFPE */ + u32 _addr; + int _trapno; + } _fault; + struct { /* SIGPOLL, SIGXFSZ */ + int _fd; + s32 _band; + } _file; + } _data; +}; + +#define SOLARIS_WUNTRACED 0x04 +#define SOLARIS_WNOHANG 0x40 +#define SOLARIS_WEXITED 0x01 +#define SOLARIS_WTRAPPED 0x02 +#define SOLARIS_WSTOPPED WUNTRACED +#define SOLARIS_WCONTINUED 0x08 +#define SOLARIS_WNOWAIT 0x80 + +#define SOLARIS_TRAP_BRKPT 1 +#define SOLARIS_TRAP_TRACE 2 +#define SOLARIS_CLD_EXITED 1 +#define SOLARIS_CLD_KILLED 2 +#define SOLARIS_CLD_DUMPED 3 +#define SOLARIS_CLD_TRAPPED 4 +#define SOLARIS_CLD_STOPPED 5 +#define SOLARIS_CLD_CONTINUED 6 +#define SOLARIS_POLL_IN 1 +#define SOLARIS_POLL_OUT 2 +#define SOLARIS_POLL_MSG 3 +#define SOLARIS_POLL_ERR 4 +#define SOLARIS_POLL_PRI 5 +#define SOLARIS_POLL_HUP 6 + diff --git a/arch/sparc64/solaris/socksys.c b/arch/sparc64/solaris/socksys.c new file mode 100644 index 000000000..984b1bdb5 --- /dev/null +++ b/arch/sparc64/solaris/socksys.c @@ -0,0 +1,127 @@ +/* $Id: socksys.c,v 1.1 1997/09/03 12:29:27 jj Exp $ + * socksys.c: /dev/inet/ stuff for Solaris emulation. + * + * Copyright (C) 1997 Jakub Jelinek (jj@sunsite.mff.cuni.cz) + * Copyright (C) 1995, 1996 Mike Jagdis (jaggy@purplet.demon.co.uk) + */ + +#include <linux/types.h> +#include <linux/kernel.h> +#include <linux/sched.h> +#include <linux/smp.h> +#include <linux/smp_lock.h> +#include <linux/ioctl.h> +#include <linux/fs.h> +#include <linux/init.h> +#include <linux/poll.h> + +#include <asm/uaccess.h> +#include <asm/termios.h> + +#include "conv.h" + +extern asmlinkage int sys_ioctl(unsigned int fd, unsigned int cmd, + unsigned long arg); + +static int af_inet_protocols[] = { +IPPROTO_ICMP, IPPROTO_ICMP, IPPROTO_IGMP, IPPROTO_IPIP, IPPROTO_TCP, +IPPROTO_EGP, IPPROTO_PUP, IPPROTO_UDP, IPPROTO_IDP, IPPROTO_RAW, +0, 0, 0, 0, 0, 0, +}; + +static struct file_operations socksys_file_ops = { + NULL, /* lseek */ + NULL, /* read */ + NULL, /* write */ + NULL, /* readdir */ + NULL, /* poll */ + NULL, /* ioctl */ + NULL, /* mmap */ + NULL, /* open */ + NULL, /* release */ +}; + +static int socksys_open(struct inode * inode, struct file * filp) +{ + int family, type, protocol, fd; + int (*sys_socket)(int,int,int) = + (int (*)(int,int,int))SUNOS(97); + + family = ((MINOR(inode->i_rdev) >> 4) & 0xf); + switch (family) { + case AF_UNIX: + type = SOCK_STREAM; + protocol = 0; + break; + case AF_INET: + protocol = af_inet_protocols[MINOR(inode->i_rdev) & 0xf]; + switch (protocol) { + case IPPROTO_TCP: type = SOCK_STREAM; break; + case IPPROTO_UDP: type = SOCK_DGRAM; break; + default: type = SOCK_RAW; break; + } + break; + default: + type = SOCK_RAW; + protocol = 0; + break; + } + fd = sys_socket(family, type, protocol); + if (fd < 0) return fd; + return 0; +} + +static int socksys_release(struct inode * inode, struct file * filp) +{ + return 0; +} + +static unsigned int socksys_poll(struct file * filp, poll_table * wait) +{ + return 0; +} + +static struct file_operations socksys_fops = { + NULL, /* lseek */ + NULL, /* read */ + NULL, /* write */ + NULL, /* readdir */ + NULL, /* poll */ + NULL, /* ioctl */ + NULL, /* mmap */ + socksys_open, /* open */ + socksys_release,/* release */ +}; + +__initfunc(int +init_socksys(void)) +{ + int ret; + int (*sys_socket)(int,int,int) = + (int (*)(int,int,int))SUNOS(97); + int (*sys_close)(unsigned int) = + (int (*)(unsigned int))SYS(close); + + ret = register_chrdev (30, "socksys", &socksys_fops); + if (ret < 0) { + printk ("Couldn't register socksys character device\n"); + return ret; + } + ret = sys_socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (ret < 0) { + printk ("Couldn't create socket\n"); + return ret; + } + socksys_file_ops = *current->files->fd[ret]->f_op; + sys_close(ret); + socksys_file_ops.poll = socksys_poll; + socksys_file_ops.release = socksys_release; + return 0; +} + +void +cleanup_socksys(void) +{ + if (unregister_chrdev (30, "socksys")) + printk ("Couldn't unregister socksys character device\n"); +} diff --git a/arch/sparc64/solaris/systbl.S b/arch/sparc64/solaris/systbl.S new file mode 100644 index 000000000..c425fb721 --- /dev/null +++ b/arch/sparc64/solaris/systbl.S @@ -0,0 +1,289 @@ +/* $Id: systbl.S,v 1.5 1997/09/04 15:46:24 jj Exp $ + * systbl.S: System call entry point table for Solaris compatibility. + * + * Copyright (C) 1997 Jakub Jelinek (jj@sunsite.mff.cuni.cz) + * Copyright (C) 1996 Miguel de Icaza (miguel@nuclecu.unam.mx) + */ + +#include <asm/unistd.h> + +/* Fall back to sys_call_table32 entry */ +#define CHAIN(name) __NR_##name + +/* Pass pt_regs pointer as first argument */ +#define REGS(name) name+1 + +/* Hack till all be implemented */ +#define solaris_getmsg solaris_unimplemented +#define solaris_getpmsg solaris_unimplemented +#define solaris_hrtsys solaris_unimplemented +#define solaris_msgsys solaris_unimplemented +#define solaris_putmsg solaris_unimplemented +#define solaris_putpmsg solaris_unimplemented +#define solaris_semsys solaris_unimplemented + + .data + .align 1024 + .globl solaris_sys_table +solaris_sys_table: + .word solaris_unimplemented /* nosys 0 */ + .word CHAIN(exit) /* exit d 1 */ + .word CHAIN(fork) /* fork 2 */ + .word CHAIN(read) /* read dpd 3 */ + .word CHAIN(write) /* write dpd 4 */ + .word solaris_open /* open soo 5 */ + .word CHAIN(close) /* close d 6 */ + .word solaris_wait /* wait xxx 7 */ + .word CHAIN(creat) /* creat so 8 */ + .word CHAIN(link) /* link ss 9 */ + .word CHAIN(unlink) /* unlink s 10 */ + .word solaris_unimplemented /* exec sxx 11 */ + .word CHAIN(chdir) /* chdir s 12 */ + .word CHAIN(time) /* time 13 */ + .word solaris_mknod /* mknod sox 14 */ + .word CHAIN(chmod) /* chmod so 15 */ + .word solaris_chown /* chown sdd 16 */ + .word solaris_brk /* brk/break x 17 */ + .word solaris_stat /* stat sp 18 */ + .word CHAIN(lseek) /* seek/lseek ddd 19 */ + .word solaris_getpid /* getpid 20 */ + .word solaris_unimplemented /* mount 21 */ + .word CHAIN(umount) /* umount s 22 */ + .word CHAIN(setuid) /* setuid d 23 */ + .word solaris_getuid /* getuid 24 */ + .word CHAIN(stime) /* stime d 25 */ +#if 0 + .word solaris_ptrace /* ptrace xdxx 26 */ +#else + .word CHAIN(ptrace) /* ptrace xdxx 26 */ +#endif + .word CHAIN(alarm) /* alarm d 27 */ + .word solaris_fstat /* fstat dp 28 */ + .word CHAIN(pause) /* pause 29 */ + .word CHAIN(utime) /* utime xx 30 */ + .word solaris_unimplemented /* stty 31 */ + .word solaris_unimplemented /* gtty 32 */ + .word solaris_access /* access so 33 */ + .word CHAIN(nice) /* nice d 34 */ + .word solaris_statfs /* statfs spdd 35 */ + .word CHAIN(sync) /* sync 36 */ + .word solaris_kill /* kill dd 37 */ + .word solaris_fstatfs /* fstatfs dpdd 38 */ + .word solaris_procids /* pgrpsys ddd 39 */ + .word solaris_unimplemented /* xenix 40 */ + .word CHAIN(dup) /* dup d 41 */ + .word CHAIN(pipe) /* pipe 42 */ + .word CHAIN(times) /* times p 43 */ + .word CHAIN(profil) /* prof xxxx 44 */ + .word solaris_unimplemented /* lock/plock 45 */ + .word CHAIN(setgid) /* setgid d 46 */ + .word solaris_getgid /* getgid 47 */ + .word solaris_sigfunc /* sigfunc xx 48 */ + .word REGS(solaris_msgsys) /* msgsys dxddd 49 */ + .word solaris_unimplemented /* syssun/3b 50 */ + .word CHAIN(acct) /* acct/sysacct x 51 */ + .word solaris_shmsys /* shmsys ddxo 52 */ + .word REGS(solaris_semsys) /* semsys dddx 53 */ + .word solaris_ioctl /* ioctl dxx 54 */ + .word solaris_unimplemented /* uadmin xxx 55 */ + .word solaris_unimplemented /* reserved:exch 56 */ + .word solaris_utssys /* utssys x 57 */ + .word CHAIN(fsync) /* fsync d 58 */ + .word CHAIN(execve) /* execv spp 59 */ + .word CHAIN(umask) /* umask o 60 */ + .word CHAIN(chroot) /* chroot s 61 */ + .word solaris_fcntl /* fcntl dxx 62 */ + .word solaris_ulimit /* ulimit xx 63 */ + .word solaris_unimplemented /* ? 64 */ + .word solaris_unimplemented /* ? 65 */ + .word solaris_unimplemented /* ? 66 */ + .word solaris_unimplemented /* ? 67 */ + .word solaris_unimplemented /* ? 68 */ + .word solaris_unimplemented /* ? 69 */ + .word solaris_unimplemented /* advfs 70 */ + .word solaris_unimplemented /* unadvfs 71 */ + .word solaris_unimplemented /* rmount 72 */ + .word solaris_unimplemented /* rumount 73 */ + .word solaris_unimplemented /* rfstart 74 */ + .word solaris_unimplemented /* ? 75 */ + .word solaris_unimplemented /* rdebug 76 */ + .word solaris_unimplemented /* rfstop 77 */ + .word solaris_unimplemented /* rfsys 78 */ + .word CHAIN(rmdir) /* rmdir s 79 */ + .word CHAIN(mkdir) /* mkdir so 80 */ + .word CHAIN(getdents) /* getdents dxd 81 */ + .word solaris_unimplemented /* libattach 82 */ + .word solaris_unimplemented /* libdetach 83 */ + .word CHAIN(sysfs) /* sysfs dxx 84 */ + .word REGS(solaris_getmsg) /* getmsg dxxx 85 */ + .word REGS(solaris_putmsg) /* putmsg dxxd 86 */ + .word CHAIN(poll) /* poll xdd 87 */ + .word solaris_lstat /* lstat sp 88 */ + .word CHAIN(symlink) /* symlink ss 89 */ + .word CHAIN(readlink) /* readlink spd 90 */ + .word CHAIN(setgroups) /* setgroups dp 91 */ + .word CHAIN(getgroups) /* getgroups dp 92 */ + .word CHAIN(fchmod) /* fchmod do 93 */ + .word CHAIN(fchown) /* fchown ddd 94 */ + .word solaris_sigprocmask /* sigprocmask dxx 95 */ + .word solaris_sigsuspend /* sigsuspend x 96 */ + .word solaris_sigaltstack /* sigaltstack xx 97 */ + .word solaris_sigaction /* sigaction dxx 98 */ + .word solaris_sigpending /* sigpending dd 99 */ + .word REGS(solaris_context) /* context 100 */ + .word solaris_unimplemented /* evsys 101 */ + .word solaris_unimplemented /* evtrapret 102 */ + .word solaris_statvfs /* statvfs sp 103 */ + .word solaris_fstatvfs /* fstatvfs dp 104 */ + .word solaris_unimplemented /* unknown 105 */ + .word solaris_unimplemented /* nfssys 106 */ + .word solaris_waitid /* waitid ddxd 107 */ + .word solaris_unimplemented /* sigsendsys ddd 108 */ + .word REGS(solaris_hrtsys) /* hrtsys xxx 109 */ + .word solaris_unimplemented /* acancel dxd 110 */ + .word solaris_unimplemented /* async 111 */ + .word solaris_unimplemented /* priocntlsys 112 */ + .word solaris_pathconf /* pathconf sd 113 */ + .word solaris_unimplemented /* mincore xdx 114 */ + .word solaris_mmap /* mmap xxxxdx 115 */ + .word CHAIN(mprotect) /* mprotect xdx 116 */ + .word CHAIN(munmap) /* munmap xd 117 */ + .word solaris_fpathconf /* fpathconf dd 118 */ + .word CHAIN(fork) /* fork 119 */ + .word solaris_unimplemented /* fchdir d 120 */ + .word CHAIN(readv) /* readv dxd 121 */ + .word CHAIN(writev) /* writev dxd 122 */ + .word solaris_xstat /* xstat dsx 123 */ + .word solaris_lxstat /* lxstat dsx 124 */ + .word solaris_fxstat /* fxstat ddx 125 */ + .word solaris_xmknod /* xmknod dsox 126 */ + .word solaris_unimplemented /* syslocal d 127 */ + .word solaris_unimplemented /* setrlimit 128 */ + .word solaris_unimplemented /* getrlimit 129 */ + .word CHAIN(chown) /* lchown sdd 130 */ + .word solaris_unimplemented /* memcntl 131 */ + .word solaris_getpmsg /* getpmsg dxxxx 132 */ + .word solaris_putpmsg /* putpmsg dxxdd 133 */ + .word CHAIN(rename) /* rename ss 134 */ + .word solaris_utsname /* uname x 135 */ + .word solaris_unimplemented /* setegid 136 */ + .word solaris_sysconf /* sysconfig d 137 */ + .word solaris_unimplemented /* adjtime 138 */ + .word solaris_sysinfo /* systeminfo dsd 139 */ + .word solaris_unimplemented /* ? 140 */ + .word solaris_unimplemented /* seteuid 141 */ + .word solaris_unimplemented /* ? 142 */ + .word solaris_unimplemented /* ? 143 */ + .word solaris_unimplemented /* secsys dx 144 */ + .word solaris_unimplemented /* filepriv sdxd 145 */ + .word solaris_unimplemented /* procpriv dxd 146 */ + .word solaris_unimplemented /* devstat sdx 147 */ + .word solaris_unimplemented /* aclipc ddddx 148 */ + .word solaris_unimplemented /* fdevstat ddx 149 */ + .word solaris_unimplemented /* flvlfile ddx 150 */ + .word solaris_unimplemented /* lvlfile sdx 151 */ + .word solaris_unimplemented /* ? 152 */ + .word solaris_unimplemented /* fchroot d 153 */ + .word solaris_unimplemented /* lvlproc dx 154 */ + .word solaris_unimplemented /* ? 155 */ + .word CHAIN(gettimeofday) /* gettimeofday xx 156 */ + .word CHAIN(getitimer) /* getitimer dx 157 */ + .word CHAIN(setitimer) /* setitimer dxx 158 */ + .word solaris_unimplemented /* lwp-xxx 159 */ + .word solaris_unimplemented /* lwp-xxx 160 */ + .word solaris_unimplemented /* lwp-xxx 161 */ + .word solaris_unimplemented /* lwp-xxx 162 */ + .word solaris_unimplemented /* lwp-xxx 163 */ + .word solaris_unimplemented /* lwp-xxx 164 */ + .word solaris_unimplemented /* lwp-xxx 165 */ + .word solaris_unimplemented /* lwp-xxx 166 */ + .word solaris_unimplemented /* lwp-xxx 167 */ + .word solaris_unimplemented /* lwp-xxx 168 */ + .word solaris_unimplemented /* lwp-xxx 169 */ + .word solaris_unimplemented /* lwp-xxx 170 */ + .word solaris_unimplemented /* lwp-xxx 171 */ + .word solaris_unimplemented /* lwp-xxx 172 */ + .word solaris_pread /* pread dpdd 173 */ + .word solaris_pwrite /* pwrite dpdd 174 */ + .word REGS(solaris_llseek) /* llseek dLd 175 */ + .word solaris_unimplemented /* lwpself 176 */ + .word solaris_unimplemented /* lwpinfo 177 */ + .word solaris_unimplemented /* lwpprivate 178 */ + .word solaris_unimplemented /* processorbind 179 */ + .word solaris_unimplemented /* processorexbind 180 */ + .word solaris_unimplemented /* 181 */ + .word solaris_unimplemented /* sync_mailbox 182 */ + .word solaris_unimplemented /* prepblock 183 */ + .word solaris_unimplemented /* block 184 */ + .word solaris_acl /* acl sddp 185 */ + .word solaris_unimplemented /* unblock 186 */ + .word solaris_unimplemented /* cancelblock 187 */ + .word solaris_unimplemented /* ? 188 */ + .word solaris_unimplemented /* xxxxx 189 */ + .word solaris_unimplemented /* xxxxxe 190 */ + .word solaris_unimplemented /* 191 */ + .word solaris_unimplemented /* 192 */ + .word solaris_unimplemented /* 193 */ + .word solaris_unimplemented /* 194 */ + .word solaris_unimplemented /* 195 */ + .word solaris_unimplemented /* 196 */ + .word solaris_unimplemented /* 197 */ + .word solaris_unimplemented /* 198 */ + .word CHAIN(nanosleep) /* nanosleep dd 199 */ + .word solaris_facl /* facl dddp 200 */ + .word solaris_unimplemented /* 201 */ + .word solaris_unimplemented /* 202 */ + .word solaris_unimplemented /* 203 */ + .word solaris_unimplemented /* 204 */ + .word solaris_unimplemented /* 205 */ + .word solaris_unimplemented /* 206 */ + .word solaris_unimplemented /* 207 */ + .word solaris_unimplemented /* 208 */ + .word solaris_unimplemented /* 209 */ + .word solaris_unimplemented /* 210 */ + .word solaris_unimplemented /* 211 */ + .word solaris_unimplemented /* 212 */ + .word solaris_unimplemented /* 213 */ + .word solaris_unimplemented /* 214 */ + .word solaris_unimplemented /* 215 */ + .word solaris_unimplemented /* 216 */ + .word solaris_unimplemented /* 217 */ + .word solaris_unimplemented /* 218 */ + .word solaris_unimplemented /* 219 */ + .word solaris_unimplemented /* 220 */ + .word solaris_unimplemented /* 221 */ + .word solaris_unimplemented /* 222 */ + .word solaris_unimplemented /* 223 */ + .word solaris_unimplemented /* 224 */ + .word solaris_unimplemented /* 225 */ + .word solaris_unimplemented /* 226 */ + .word solaris_unimplemented /* 227 */ + .word solaris_unimplemented /* 228 */ + .word solaris_unimplemented /* 229 */ + .word solaris_unimplemented /* 230 */ + .word solaris_unimplemented /* 231 */ + .word solaris_unimplemented /* 232 */ + .word solaris_unimplemented /* 233 */ + .word solaris_unimplemented /* 234 */ + .word solaris_unimplemented /* 235 */ + .word solaris_unimplemented /* 236 */ + .word solaris_unimplemented /* 237 */ + .word solaris_unimplemented /* 238 */ + .word solaris_unimplemented /* 239 */ + .word solaris_unimplemented /* 240 */ + .word solaris_unimplemented /* 241 */ + .word solaris_unimplemented /* 242 */ + .word solaris_unimplemented /* 243 */ + .word solaris_unimplemented /* 244 */ + .word solaris_unimplemented /* 245 */ + .word solaris_unimplemented /* 246 */ + .word solaris_unimplemented /* 247 */ + .word solaris_unimplemented /* 248 */ + .word solaris_unimplemented /* 249 */ + .word solaris_unimplemented /* 250 */ + .word solaris_unimplemented /* 251 */ + .word solaris_unimplemented /* 252 */ + .word solaris_unimplemented /* 253 */ + .word solaris_unimplemented /* 254 */ + .word solaris_unimplemented /* 255 */ + |