⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 syscall.c

📁 qemu虚拟机代码
💻 C
📖 第 1 页 / 共 5 页
字号:
/* *  Linux syscalls *  *  Copyright (c) 2003 Fabrice Bellard * *  This program is free software; you can redistribute it and/or modify *  it under the terms of the GNU General Public License as published by *  the Free Software Foundation; either version 2 of the License, or *  (at your option) any later version. * *  This program is distributed in the hope that it will be useful, *  but WITHOUT ANY WARRANTY; without even the implied warranty of *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the *  GNU General Public License for more details. * *  You should have received a copy of the GNU General Public License *  along with this program; if not, write to the Free Software *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */#include <stdlib.h>#include <stdio.h>#include <stdarg.h>#include <string.h>#include <elf.h>#include <endian.h>#include <errno.h>#include <unistd.h>#include <fcntl.h>#include <time.h>#include <sys/types.h>#include <sys/wait.h>#include <sys/time.h>#include <sys/stat.h>#include <sys/mount.h>#include <sys/resource.h>#include <sys/mman.h>#include <sys/swap.h>#include <signal.h>#include <sched.h>#include <sys/socket.h>#include <sys/uio.h>#include <sys/poll.h>#include <sys/times.h>#include <sys/shm.h>#include <sys/statfs.h>#include <utime.h>#include <sys/sysinfo.h>//#include <sys/user.h>#include <netinet/ip.h>#include <netinet/tcp.h>#define termios host_termios#define winsize host_winsize#define termio host_termio#define sgttyb host_sgttyb /* same as target */#define tchars host_tchars /* same as target */#define ltchars host_ltchars /* same as target */#include <linux/termios.h>#include <linux/unistd.h>#include <linux/utsname.h>#include <linux/cdrom.h>#include <linux/hdreg.h>#include <linux/soundcard.h>#include <linux/dirent.h>#include <linux/kd.h>#include "qemu.h"//#define DEBUG#if defined(TARGET_I386) || defined(TARGET_ARM) || defined(TARGET_SPARC)/* 16 bit uid wrappers emulation */#define USE_UID16#endif//#include <linux/msdos_fs.h>#define	VFAT_IOCTL_READDIR_BOTH		_IOR('r', 1, struct dirent [2])#define	VFAT_IOCTL_READDIR_SHORT	_IOR('r', 2, struct dirent [2])#if defined(__powerpc__)#undef __syscall_nr#undef __sc_loadargs_0#undef __sc_loadargs_1#undef __sc_loadargs_2#undef __sc_loadargs_3#undef __sc_loadargs_4#undef __sc_loadargs_5#undef __sc_asm_input_0#undef __sc_asm_input_1#undef __sc_asm_input_2#undef __sc_asm_input_3#undef __sc_asm_input_4#undef __sc_asm_input_5#undef _syscall0#undef _syscall1#undef _syscall2#undef _syscall3#undef _syscall4#undef _syscall5/* need to redefine syscalls as Linux kernel defines are incorrect for   the clobber list *//* On powerpc a system call basically clobbers the same registers like a * function call, with the exception of LR (which is needed for the * "sc; bnslr" sequence) and CR (where only CR0.SO is clobbered to signal * an error return status). */#define __syscall_nr(nr, type, name, args...)				\	unsigned long __sc_ret, __sc_err;				\	{								\		register unsigned long __sc_0  __asm__ ("r0");		\		register unsigned long __sc_3  __asm__ ("r3");		\		register unsigned long __sc_4  __asm__ ("r4");		\		register unsigned long __sc_5  __asm__ ("r5");		\		register unsigned long __sc_6  __asm__ ("r6");		\		register unsigned long __sc_7  __asm__ ("r7");		\									\		__sc_loadargs_##nr(name, args);				\		__asm__ __volatile__					\			("sc           \n\t"				\			 "mfcr %0      "				\			: "=&r" (__sc_0),				\			  "=&r" (__sc_3),  "=&r" (__sc_4),		\			  "=&r" (__sc_5),  "=&r" (__sc_6),		\			  "=&r" (__sc_7)				\			: __sc_asm_input_##nr				\			: "cr0", "ctr", "memory",			\			  "r8", "r9", "r10","r11", "r12");		\		__sc_ret = __sc_3;					\		__sc_err = __sc_0;					\	}								\	if (__sc_err & 0x10000000)					\	{								\		errno = __sc_ret;					\		__sc_ret = -1;						\	}								\	return (type) __sc_ret#define __sc_loadargs_0(name, dummy...)					\	__sc_0 = __NR_##name#define __sc_loadargs_1(name, arg1)					\	__sc_loadargs_0(name);						\	__sc_3 = (unsigned long) (arg1)#define __sc_loadargs_2(name, arg1, arg2)				\	__sc_loadargs_1(name, arg1);					\	__sc_4 = (unsigned long) (arg2)#define __sc_loadargs_3(name, arg1, arg2, arg3)				\	__sc_loadargs_2(name, arg1, arg2);				\	__sc_5 = (unsigned long) (arg3)#define __sc_loadargs_4(name, arg1, arg2, arg3, arg4)			\	__sc_loadargs_3(name, arg1, arg2, arg3);			\	__sc_6 = (unsigned long) (arg4)#define __sc_loadargs_5(name, arg1, arg2, arg3, arg4, arg5)		\	__sc_loadargs_4(name, arg1, arg2, arg3, arg4);			\	__sc_7 = (unsigned long) (arg5)#define __sc_asm_input_0 "0" (__sc_0)#define __sc_asm_input_1 __sc_asm_input_0, "1" (__sc_3)#define __sc_asm_input_2 __sc_asm_input_1, "2" (__sc_4)#define __sc_asm_input_3 __sc_asm_input_2, "3" (__sc_5)#define __sc_asm_input_4 __sc_asm_input_3, "4" (__sc_6)#define __sc_asm_input_5 __sc_asm_input_4, "5" (__sc_7)#define _syscall0(type,name)						\type name(void)								\{									\	__syscall_nr(0, type, name);					\}#define _syscall1(type,name,type1,arg1)					\type name(type1 arg1)							\{									\	__syscall_nr(1, type, name, arg1);				\}#define _syscall2(type,name,type1,arg1,type2,arg2)			\type name(type1 arg1, type2 arg2)					\{									\	__syscall_nr(2, type, name, arg1, arg2);			\}#define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3)		\type name(type1 arg1, type2 arg2, type3 arg3)				\{									\	__syscall_nr(3, type, name, arg1, arg2, arg3);			\}#define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4)		\{									\	__syscall_nr(4, type, name, arg1, arg2, arg3, arg4);		\}#define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4,type5,arg5) \type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5)	\{									\	__syscall_nr(5, type, name, arg1, arg2, arg3, arg4, arg5);	\}#endif#define __NR_sys_uname __NR_uname#define __NR_sys_getcwd1 __NR_getcwd#define __NR_sys_getdents __NR_getdents#define __NR_sys_getdents64 __NR_getdents64#define __NR_sys_rt_sigqueueinfo __NR_rt_sigqueueinfo#if defined(__alpha__) || defined (__ia64__) || defined(__x86_64__)#define __NR__llseek __NR_lseek#endif#ifdef __NR_gettid_syscall0(int, gettid)#elsestatic int gettid(void) {    return -ENOSYS;}#endif_syscall1(int,sys_uname,struct new_utsname *,buf)_syscall2(int,sys_getcwd1,char *,buf,size_t,size)_syscall3(int, sys_getdents, uint, fd, struct dirent *, dirp, uint, count);_syscall3(int, sys_getdents64, uint, fd, struct dirent64 *, dirp, uint, count);_syscall5(int, _llseek,  uint,  fd, ulong, hi, ulong, lo,          loff_t *, res, uint, wh);_syscall3(int,sys_rt_sigqueueinfo,int,pid,int,sig,siginfo_t *,uinfo)#ifdef __NR_exit_group_syscall1(int,exit_group,int,error_code)#endifextern int personality(int);extern int flock(int, int);extern int setfsuid(int);extern int setfsgid(int);extern int setresuid(uid_t, uid_t, uid_t);extern int getresuid(uid_t *, uid_t *, uid_t *);extern int setresgid(gid_t, gid_t, gid_t);extern int getresgid(gid_t *, gid_t *, gid_t *);extern int setgroups(int, gid_t *);static inline long get_errno(long ret){    if (ret == -1)        return -errno;    else        return ret;}static inline int is_error(long ret){    return (unsigned long)ret >= (unsigned long)(-4096);}static target_ulong target_brk;static target_ulong target_original_brk;void target_set_brk(target_ulong new_brk){    target_original_brk = target_brk = new_brk;}long do_brk(target_ulong new_brk){    target_ulong brk_page;    long mapped_addr;    int	new_alloc_size;    if (!new_brk)        return target_brk;    if (new_brk < target_original_brk)        return -ENOMEM;        brk_page = HOST_PAGE_ALIGN(target_brk);    /* If the new brk is less than this, set it and we're done... */    if (new_brk < brk_page) {	target_brk = new_brk;    	return target_brk;    }    /* We need to allocate more memory after the brk... */    new_alloc_size = HOST_PAGE_ALIGN(new_brk - brk_page + 1);    mapped_addr = get_errno(target_mmap(brk_page, new_alloc_size,                                         PROT_READ|PROT_WRITE,                                        MAP_ANON|MAP_FIXED|MAP_PRIVATE, 0, 0));    if (is_error(mapped_addr)) {	return mapped_addr;    } else {	target_brk = new_brk;    	return target_brk;    }}static inline fd_set *target_to_host_fds(fd_set *fds,                                          target_long *target_fds, int n){#if !defined(BSWAP_NEEDED) && !defined(WORDS_BIGENDIAN)    return (fd_set *)target_fds;#else    int i, b;    if (target_fds) {        FD_ZERO(fds);        for(i = 0;i < n; i++) {            b = (tswapl(target_fds[i / TARGET_LONG_BITS]) >>                 (i & (TARGET_LONG_BITS - 1))) & 1;            if (b)                FD_SET(i, fds);        }        return fds;    } else {        return NULL;    }#endif}static inline void host_to_target_fds(target_long *target_fds,                                       fd_set *fds, int n){#if !defined(BSWAP_NEEDED) && !defined(WORDS_BIGENDIAN)    /* nothing to do */#else    int i, nw, j, k;    target_long v;    if (target_fds) {        nw = (n + TARGET_LONG_BITS - 1) / TARGET_LONG_BITS;        k = 0;        for(i = 0;i < nw; i++) {            v = 0;            for(j = 0; j < TARGET_LONG_BITS; j++) {                v |= ((FD_ISSET(k, fds) != 0) << j);                k++;            }            target_fds[i] = tswapl(v);        }    }#endif}#if defined(__alpha__)#define HOST_HZ 1024#else#define HOST_HZ 100#endifstatic inline long host_to_target_clock_t(long ticks){#if HOST_HZ == TARGET_HZ    return ticks;#else    return ((int64_t)ticks * TARGET_HZ) / HOST_HZ;#endif}static inline void host_to_target_rusage(target_ulong target_addr,                                         const struct rusage *rusage){    struct target_rusage *target_rusage;    lock_user_struct(target_rusage, target_addr, 0);    target_rusage->ru_utime.tv_sec = tswapl(rusage->ru_utime.tv_sec);    target_rusage->ru_utime.tv_usec = tswapl(rusage->ru_utime.tv_usec);    target_rusage->ru_stime.tv_sec = tswapl(rusage->ru_stime.tv_sec);    target_rusage->ru_stime.tv_usec = tswapl(rusage->ru_stime.tv_usec);    target_rusage->ru_maxrss = tswapl(rusage->ru_maxrss);    target_rusage->ru_ixrss = tswapl(rusage->ru_ixrss);    target_rusage->ru_idrss = tswapl(rusage->ru_idrss);    target_rusage->ru_isrss = tswapl(rusage->ru_isrss);    target_rusage->ru_minflt = tswapl(rusage->ru_minflt);    target_rusage->ru_majflt = tswapl(rusage->ru_majflt);    target_rusage->ru_nswap = tswapl(rusage->ru_nswap);    target_rusage->ru_inblock = tswapl(rusage->ru_inblock);    target_rusage->ru_oublock = tswapl(rusage->ru_oublock);    target_rusage->ru_msgsnd = tswapl(rusage->ru_msgsnd);    target_rusage->ru_msgrcv = tswapl(rusage->ru_msgrcv);    target_rusage->ru_nsignals = tswapl(rusage->ru_nsignals);    target_rusage->ru_nvcsw = tswapl(rusage->ru_nvcsw);    target_rusage->ru_nivcsw = tswapl(rusage->ru_nivcsw);    unlock_user_struct(target_rusage, target_addr, 1);}static inline void target_to_host_timeval(struct timeval *tv,                                          target_ulong target_addr){    struct target_timeval *target_tv;    lock_user_struct(target_tv, target_addr, 1);    tv->tv_sec = tswapl(target_tv->tv_sec);    tv->tv_usec = tswapl(target_tv->tv_usec);    unlock_user_struct(target_tv, target_addr, 0);}static inline void host_to_target_timeval(target_ulong target_addr,                                          const struct timeval *tv){    struct target_timeval *target_tv;    lock_user_struct(target_tv, target_addr, 0);    target_tv->tv_sec = tswapl(tv->tv_sec);    target_tv->tv_usec = tswapl(tv->tv_usec);    unlock_user_struct(target_tv, target_addr, 1);}static long do_select(long n,                       target_ulong rfd_p, target_ulong wfd_p,                       target_ulong efd_p, target_ulong target_tv){    fd_set rfds, wfds, efds;    fd_set *rfds_ptr, *wfds_ptr, *efds_ptr;    target_long *target_rfds, *target_wfds, *target_efds;    struct timeval tv, *tv_ptr;    long ret;    int ok;    if (rfd_p) {        target_rfds = lock_user(rfd_p, sizeof(target_long) * n, 1);        rfds_ptr = target_to_host_fds(&rfds, target_rfds, n);    } else {        target_rfds = NULL;        rfds_ptr = NULL;    }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -