📄 emul_unix.c
字号:
static voiddo_unix_dup2(os_emul_data *emul, unsigned call, const int arg0, cpu *processor, unsigned_word cia){ int oldd = cpu_registers(processor)->gpr[arg0]; int newd = cpu_registers(processor)->gpr[arg0+1]; int status = dup2(oldd, newd); int err = errno; if (WITH_TRACE && ppc_trace[trace_os_emul]) printf_filtered ("%d, %d", oldd, newd); emul_write_status(processor, status, err);}#endif#ifndef HAVE_LSEEK#define do_unix_lseek 0#elsestatic voiddo_unix_lseek(os_emul_data *emul, unsigned call, const int arg0, cpu *processor, unsigned_word cia){ int fildes = (int)cpu_registers(processor)->gpr[arg0]; off_t offset = (off_t)cpu_registers(processor)->gpr[arg0+1]; int whence = (int)cpu_registers(processor)->gpr[arg0+2]; off_t status; if (WITH_TRACE && ppc_trace[trace_os_emul]) printf_filtered ("%d %ld %d", fildes, (long)offset, whence); status = lseek(fildes, offset, whence); emul_write_status(processor, (int)status, errno);}#endif#if !defined(HAVE_GETGID) || !defined(HAVE_GETEGID)#define do_unix_getgid2 0#elsestatic voiddo_unix_getgid2(os_emul_data *emul, unsigned call, const int arg0, cpu *processor, unsigned_word cia){ gid_t gid = getgid(); gid_t egid = getegid(); emul_write2_status(processor, (int)gid, (int)egid, errno);}#endif#ifndef HAVE_GETGID#define do_unix_getgid 0#elsestatic voiddo_unix_getgid(os_emul_data *emul, unsigned call, const int arg0, cpu *processor, unsigned_word cia){ gid_t status = getgid(); emul_write_status(processor, (int)status, errno);}#endif#ifndef HAVE_GETEGID#define do_unix_getegid 0#elsestatic voiddo_unix_getegid(os_emul_data *emul, unsigned call, const int arg0, cpu *processor, unsigned_word cia){ gid_t status = getegid(); emul_write_status(processor, (int)status, errno);}#endif#ifndef HAVE_UMASK#define do_unix_umask 0#elsestatic voiddo_unix_umask(os_emul_data *emul, unsigned call, const int arg0, cpu *processor, unsigned_word cia){ mode_t mask = (mode_t)cpu_registers(processor)->gpr[arg0]; int status = umask(mask); if (WITH_TRACE && ppc_trace[trace_os_emul]) printf_filtered ("0%o", (unsigned int)mask); emul_write_status(processor, status, errno);}#endif#ifndef HAVE_CHDIR#define do_unix_chdir 0#elsestatic voiddo_unix_chdir(os_emul_data *emul, unsigned call, const int arg0, cpu *processor, unsigned_word cia){ unsigned_word path_addr = cpu_registers(processor)->gpr[arg0]; char path_buf[PATH_MAX]; char *path = emul_read_string(path_buf, path_addr, PATH_MAX, processor, cia); int status; if (WITH_TRACE && ppc_trace[trace_os_emul]) printf_filtered ("0x%lx [%s]", (long)path_addr, path); status = chdir(path); emul_write_status(processor, status, errno);}#endif#ifndef HAVE_LINK#define do_unix_link 0#elsestatic voiddo_unix_link(os_emul_data *emul, unsigned call, const int arg0, cpu *processor, unsigned_word cia){ unsigned_word path1_addr = cpu_registers(processor)->gpr[arg0]; char path1_buf[PATH_MAX]; char *path1 = emul_read_string(path1_buf, path1_addr, PATH_MAX, processor, cia); unsigned_word path2_addr = cpu_registers(processor)->gpr[arg0+1]; char path2_buf[PATH_MAX]; char *path2 = emul_read_string(path2_buf, path2_addr, PATH_MAX, processor, cia); int status; if (WITH_TRACE && ppc_trace[trace_os_emul]) printf_filtered ("0x%lx [%s], 0x%lx [%s]", (long)path1_addr, path1, (long)path2_addr, path2); status = link(path1, path2); emul_write_status(processor, status, errno);}#endif#ifndef HAVE_SYMLINK#define do_unix_symlink 0#elsestatic voiddo_unix_symlink(os_emul_data *emul, unsigned call, const int arg0, cpu *processor, unsigned_word cia){ unsigned_word path1_addr = cpu_registers(processor)->gpr[arg0]; char path1_buf[PATH_MAX]; char *path1 = emul_read_string(path1_buf, path1_addr, PATH_MAX, processor, cia); unsigned_word path2_addr = cpu_registers(processor)->gpr[arg0+1]; char path2_buf[PATH_MAX]; char *path2 = emul_read_string(path2_buf, path2_addr, PATH_MAX, processor, cia); int status; if (WITH_TRACE && ppc_trace[trace_os_emul]) printf_filtered ("0x%lx [%s], 0x%lx [%s]", (long)path1_addr, path1, (long)path2_addr, path2); status = symlink(path1, path2); emul_write_status(processor, status, errno);}#endif#ifndef HAVE_UNLINK#define do_unix_unlink 0#elsestatic voiddo_unix_unlink(os_emul_data *emul, unsigned call, const int arg0, cpu *processor, unsigned_word cia){ unsigned_word path_addr = cpu_registers(processor)->gpr[arg0]; char path_buf[PATH_MAX]; char *path = emul_read_string(path_buf, path_addr, PATH_MAX, processor, cia); int status; if (WITH_TRACE && ppc_trace[trace_os_emul]) printf_filtered ("0x%lx [%s]", (long)path_addr, path); status = unlink(path); emul_write_status(processor, status, errno);}#endif#ifndef HAVE_MKDIR#define do_unix_mkdir 0#elsestatic voiddo_unix_mkdir(os_emul_data *emul, unsigned call, const int arg0, cpu *processor, unsigned_word cia){ unsigned_word path_addr = cpu_registers(processor)->gpr[arg0]; char path_buf[PATH_MAX]; char *path = emul_read_string(path_buf, path_addr, PATH_MAX, processor, cia); int mode = (int)cpu_registers(processor)->gpr[arg0+1]; int status; if (WITH_TRACE && ppc_trace[trace_os_emul]) printf_filtered ("0x%lx [%s], 0%3o", (long)path_addr, path, mode); status = mkdir(path, mode); emul_write_status(processor, status, errno);}#endif#ifndef HAVE_RMDIR#define do_unix_rmdir 0#elsestatic voiddo_unix_rmdir(os_emul_data *emul, unsigned call, const int arg0, cpu *processor, unsigned_word cia){ unsigned_word path_addr = cpu_registers(processor)->gpr[arg0]; char path_buf[PATH_MAX]; char *path = emul_read_string(path_buf, path_addr, PATH_MAX, processor, cia); int status; if (WITH_TRACE && ppc_trace[trace_os_emul]) printf_filtered ("0x%lx [%s]", (long)path_addr, path); status = rmdir(path); emul_write_status(processor, status, errno);}#endif#ifndef HAVE_TIME#define do_unix_time 0#elsestatic voiddo_unix_time(os_emul_data *emul, unsigned call, const int arg0, cpu *processor, unsigned_word cia){ unsigned_word tp = cpu_registers(processor)->gpr[arg0]; time_t now = time ((time_t *)0); unsigned_word status = H2T_4(now); if (WITH_TRACE && ppc_trace[trace_os_emul]) printf_filtered ("0x%lx", (long)tp); emul_write_status(processor, (int)status, errno); if (tp) emul_write_buffer(&status, tp, sizeof(status), processor, cia);}#endif#if !defined(HAVE_GETTIMEOFDAY) || !defined(HAVE_SYS_TIME_H)#define do_unix_gettimeofday 0#elsestatic voiddo_unix_gettimeofday(os_emul_data *emul, unsigned call, const int arg0, cpu *processor, unsigned_word cia){ unsigned_word tv = cpu_registers(processor)->gpr[arg0]; unsigned_word tz = cpu_registers(processor)->gpr[arg0+1]; struct unix_timeval target_timeval; struct timeval host_timeval; struct unix_timezone target_timezone; struct timezone host_timezone; int status; if (WITH_TRACE && ppc_trace[trace_os_emul]) printf_filtered ("0x%lx, 0x%lx", (long)tv, (long)tz); /* Just in case the system doesn't set the timezone structure */ host_timezone.tz_minuteswest = 0; host_timezone.tz_dsttime = 0; status = gettimeofday(&host_timeval, &host_timezone); if (status >= 0) { if (tv) { target_timeval.tv_sec = H2T_4(host_timeval.tv_sec); target_timeval.tv_usec = H2T_4(host_timeval.tv_usec); emul_write_buffer((void *) &target_timeval, tv, sizeof(target_timeval), processor, cia); } if (tz) { target_timezone.tz_minuteswest = H2T_4(host_timezone.tz_minuteswest); target_timezone.tz_dsttime = H2T_4(host_timezone.tz_dsttime); emul_write_buffer((void *) &target_timezone, tv, sizeof(target_timezone), processor, cia); } } emul_write_status(processor, (int)status, errno);}#endif#ifndef HAVE_GETRUSAGE#define do_unix_getrusage 0#elsestatic voiddo_unix_getrusage(os_emul_data *emul, unsigned call, const int arg0, cpu *processor, unsigned_word cia){ signed_word who = (signed_word)cpu_registers(processor)->gpr[arg0]; unsigned_word usage = cpu_registers(processor)->gpr[arg0+1]; struct rusage host_rusage, host_rusage2; struct unix_rusage target_rusage; int status; if (WITH_TRACE && ppc_trace[trace_os_emul]) printf_filtered ("%ld, 0x%lx", (long)who, (long)usage); switch (who) { default: status = -1; errno = EINVAL; break; case UNIX_RUSAGE_SELF: status = getrusage(RUSAGE_SELF, &host_rusage); break; case UNIX_RUSAGE_CHILDREN: status = getrusage(RUSAGE_CHILDREN, &host_rusage); break; case UNIX_RUSAGE_BOTH: status = getrusage(RUSAGE_SELF, &host_rusage); if (status >= 0) { status = getrusage(RUSAGE_CHILDREN, &host_rusage2); if (status >= 0) { host_rusage.ru_utime.tv_sec += host_rusage2.ru_utime.tv_sec; host_rusage.ru_utime.tv_usec += host_rusage2.ru_utime.tv_usec; host_rusage.ru_stime.tv_sec += host_rusage2.ru_stime.tv_sec; host_rusage.ru_stime.tv_usec += host_rusage2.ru_stime.tv_usec; host_rusage.ru_maxrss += host_rusage2.ru_maxrss; host_rusage.ru_ixrss += host_rusage2.ru_ixrss; host_rusage.ru_idrss += host_rusage2.ru_idrss; host_rusage.ru_isrss += host_rusage2.ru_isrss; host_rusage.ru_minflt += host_rusage2.ru_minflt; host_rusage.ru_majflt += host_rusage2.ru_majflt; host_rusage.ru_nswap += host_rusage2.ru_nswap; host_rusage.ru_inblock += host_rusage2.ru_inblock; host_rusage.ru_oublock += host_rusage2.ru_oublock; host_rusage.ru_msgsnd += host_rusage2.ru_msgsnd; host_rusage.ru_msgrcv += host_rusage2.ru_msgrcv; host_rusage.ru_nsignals += host_rusage2.ru_nsignals; host_rusage.ru_nvcsw += host_rusage2.ru_nvcsw; host_rusage.ru_nivcsw += host_rusage2.ru_nivcsw; } } } if (status >= 0) { target_rusage.ru_utime.tv_sec = H2T_4(host_rusage2.ru_utime.tv_sec); target_rusage.ru_utime.tv_usec = H2T_4(host_rusage2.ru_utime.tv_usec); target_rusage.ru_stime.tv_sec = H2T_4(host_rusage2.ru_stime.tv_sec); target_rusage.ru_stime.tv_usec = H2T_4(host_rusage2.ru_stime.tv_usec); target_rusage.ru_maxrss = H2T_4(host_rusage2.ru_maxrss); target_rusage.ru_ixrss = H2T_4(host_rusage2.ru_ixrss); target_rusage.ru_idrss = H2T_4(host_rusage2.ru_idrss); target_rusage.ru_isrss = H2T_4(host_rusage2.ru_isrss); target_rusage.ru_minflt = H2T_4(host_rusage2.ru_minflt); target_rusage.ru_majflt = H2T_4(host_rusage2.ru_majflt); target_rusage.ru_nswap = H2T_4(host_rusage2.ru_nswap); target_rusage.ru_inblock = H2T_4(host_rusage2.ru_inblock); target_rusage.ru_oublock = H2T_4(host_rusage2.ru_oublock); target_rusage.ru_msgsnd = H2T_4(host_rusage2.ru_msgsnd); target_rusage.ru_msgrcv = H2T_4(host_rusage2.ru_msgrcv); target_rusage.ru_nsignals = H2T_4(host_rusage2.ru_nsignals); target_rusage.ru_nvcsw = H2T_4(host_rusage2.ru_nvcsw); target_rusage.ru_nivcsw = H2T_4(host_rusage2.ru_nivcsw); emul_write_buffer((void *) &target_rusage, usage, sizeof(target_rusage), processor, cia); } emul_write_status(processor, status, errno);}#endifstatic voiddo_unix_nop(os_emul_data *emul, unsigned call, const int arg0, cpu *processor, unsigned_word cia){ if (WITH_TRACE && ppc_trace[trace_os_emul]) printf_filtered ("0x%lx 0x%lx 0x%lx 0x%lx 0x%lx 0x%lx", (long)cpu_registers(processor)->gpr[arg0], (long)cpu_registers(processor)->gpr[arg0+1], (long)cpu_registers(processor)->gpr[arg0+2], (long)cpu_registers(processor)->gpr[arg0+3], (long)cpu_registers(processor)->gpr[arg0+4], (long)cpu_registers(processor)->gpr[arg0+5]); emul_write_status(processor, 0, errno);}/* Common code for initializing the system call stuff */static os_emul_data *emul_unix_create(device *root, bfd *image, const char *name, emul_syscall *syscall){ unsigned_word top_of_stack; unsigned stack_size; int elf_binary; os_emul_data *data; device *vm; /* merge any emulation specific entries into the device tree */ /* establish a few defaults */ if (image->xvec->flavour == bfd_target_elf_flavour) { elf_binary = 1; top_of_stack = 0xe0000000; stack_size = 0x00100000; } else { elf_binary = 0; top_of_stack = 0x20000000; stack_size = 0x00100000; } /* options */ emul_add_tree_options(root, image, name, (WITH_ENVIRONMENT == USER_ENVIRONMENT ? "user" : "virtual"), 0 /*oea-interrupt-prefix*/); /* virtual memory - handles growth of stack/heap */ vm = tree_parse(root, "/openprom/vm@0x%lx", (unsigned long)(top_of_stack - stack_size)); tree_parse(vm, "./stack-base 0x%lx", (unsigned long)(top_of_stack - stack_size)); tree_parse(vm, "./nr-bytes 0x%x", stack_size); tree_parse(root, "/openprom/vm/map-binary/file-name %s", bfd_get_filename(image)); /* finish the init */ tree_parse(root, "/openprom/init/register/pc 0x%lx", (unsigned long)bfd_get_start_address(image)); tree_parse(root, "/openprom/init/register/sp 0x%lx", (unsigned long)top_of_stack); tree_parse(root, "/openprom/init/register/msr 0x%x", ((tree_find_boolean_property(root, "/options/little-endian?") ? msr_little_endian_mode : 0) | (tree_find_boolean_property(root, "/openprom/options/floating-point?") ? (msr_floating_point_available | msr_floating_point_exception_mode_0 | msr_floating_point_exception_mode_1) : 0))); tree_parse(root, "/openprom/init/stack/stack-type %s", (elf_binary ? "ppc-elf" : "ppc-xcoff")); /* finally our emulation data */ data = ZALLOC(os_emul_data); data->vm = vm; data->syscalls = syscall; return data;}/* EMULATION Solaris - Emulation of user programs for Solaris/PPC DESCRIPTION */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -