Compare commits

..

No commits in common. "master" and "v0.1" have entirely different histories.
master ... v0.1

8 changed files with 52 additions and 62 deletions

View File

@ -3,8 +3,7 @@ only under linux (though BSD support would probably be feasable).
### compiling
Configure QEMU for irix/solaris userland emulation and compile (see the original
QEMU README for further instructions):
Configure QEMU for irix/solaris userland emulation and compile:
```
configure --target-list=irix-linux-user,irixn32-linux-user,irix64-linux-user,solaris-linux-user
@ -13,10 +12,31 @@ make && make install
### using
I recommend using binfmt. I have prepared some scripts for this which you can
obtain from my qemu-irix-helpers repository at github. Adapt the wrapper scripts
to your setup and install them somewhere in your executable path. Activate them
with the binfmt install scripts.
I recommend using binfmt. Prepare some wrapper scripts for each of the qemu
binaries for irix/solaris using this template:
```
#! /bin/sh
ex=$1; shift
a0=$1; shift
export QEMU_RESERVED_VA=1G
export QEMU_LD_PREFIX=<target rootfs>
export QEMU_SET_ENV=LANG=C
exec <qemu binary> -0 $a0 $ex "$@"
```
Install the binfmt (replace the QEMU* environment variables by the location of
the wrapper scripts):
```
echo :irix:M::'\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x08\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00':'\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff\xff\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xef':${QEMUIRIX32}:P > /proc/sys/fs/binfmt_misc/register
echo :irixn32:M::'\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x08\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x20':'\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff\xff\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xef':${QEMUIRIXN32}:P > /proc/sys/fs/binfmt_misc/register
echo :irix64:M::'\x7fELF\x02\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x08':'\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff':${QEMUIRIX64}:P > /proc/sys/fs/binfmt_misc/register
echo :solaris:M::'\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x02':'\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff':${QEMUSOLARIS32}:P > /proc/sys/fs/binfmt_misc/register
```
Now you should be able to directly execute irix/solaris binaries from the shell.
As a rather simple test, try:
@ -25,19 +45,4 @@ As a rather simple test, try:
<target rootfs>/bin/ls
```
### notes
IRIX threading uses a local TLS storage area named PRDA which is privately mapped
into each thread at address 0x20000. qemu-irix will emulate this behaviour if
QEMU_IRIXPRDA is set in the environment. You most probably need to do so for any
IRIX software using multithreading. Be aware that this will noticably harm the
performance of the emulation since every memory access is checked for PRDA access
(AFAIK it isn't possible to emulate this directly on linux or BSD).
For conveniance I have also extended the handling of QEMU_LD_PREFIX to allow
the specification of multiple paths separated by ':'. That way you can keep the
target os root separate from additional software. Moreover, for a noticable
speed gain at qemu startup, QEMU_LD_PREFIX is not pre-scanned anymore. Instead,
it is now caching any directories accessed by the emulated program.
send bug reports, fixes etc to Kai-Uwe Bloem (<derkub@gmail.com>)

1
configure vendored
View File

@ -6836,7 +6836,6 @@ case "$target_name" in
solaris)
TARGET_ARCH=sparc
TARGET_ABI_DIR=solaris
TARGET_BASE_ARCH=sparc
echo "TARGET_ABI_SOLARIS=y" >> $config_target_mak
;;
solaris64)

View File

@ -2067,8 +2067,6 @@ abi_ulong sgi_map_elf_image(int image_fd, struct elf_phdr *phdr, int phnum)
}
}
mmap_lock();
/* The image indicates that it can be loaded anywhere. Find a
location that can hold the memory space required. If the
image is pre-linked, LOADDR will be non-zero. Since we do
@ -2115,13 +2113,9 @@ abi_ulong sgi_map_elf_image(int image_fd, struct elf_phdr *phdr, int phnum)
}
}
mmap_unlock();
return load_bias + phdr[0].p_vaddr;
exit_perror:
mmap_unlock();
errmsg = strerror(errno);
fprintf(stderr, "error in syssgi elfmap: %s\n", errmsg);
return -ENOEXEC;

View File

@ -47,7 +47,7 @@
IOCTL(TIOCSETD, IOC_W, MK_PTR(TYPE_INT))
IOCTL(TIOCGPTN, IOC_R, MK_PTR(TYPE_INT))
IOCTL(TIOCSPTLCK, IOC_W, MK_PTR(TYPE_INT))
#if defined TIOCGPTPEER && defined TARGET_TIOCGPTPEER
#ifdef TIOCGPTPEER
IOCTL_SPECIAL(TIOCGPTPEER, 0, do_ioctl_tiocgptpeer, TYPE_INT)
#endif
IOCTL(FIOCLEX, 0, TYPE_NULL)

View File

@ -258,7 +258,6 @@
/* SGI specific syssgi calls */
#define TARGET_NR_syssgi_sysid (1)
#define TARGET_NR_syssgi_elfmap (68)
#define TARGET_NR_syssgi_getprocattr (85)
#define TARGET_NR_syssgi_rldenv (92)
#define TARGET_NR_syssgi_tosstsave (108)
#define TARGET_NR_syssgi_fdhi (109)

View File

@ -40,7 +40,6 @@
#include <sys/resource.h>
#include <sys/swap.h>
#include <linux/capability.h>
#include <linux/sockios.h>
#include <sched.h>
#include <sys/timex.h>
#include <sys/socket.h>
@ -259,9 +258,15 @@ static inline type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5,
#define TARGET_NR__llseek TARGET_NR_llseek
#endif
#define __NR_sys_gettid __NR_gettid
_syscall0(int, sys_gettid)
#ifdef __NR_gettid
_syscall0(int, gettid)
#else
/* This is a replacement for the host gettid() and must return a host
errno. */
static int gettid(void) {
return -ENOSYS;
}
#endif
#if defined(TARGET_NR_getdents) && defined(__NR_getdents)
_syscall3(int, sys_getdents, uint, fd, struct linux_dirent *, dirp, uint, count);
#endif
@ -5782,7 +5787,7 @@ static abi_long do_ioctl_kdsigaccept(const IOCTLEntry *ie, uint8_t *buf_temp,
}
#endif
#if defined TIOCGPTPEER && defined TARGET_TIOCGPTPEER
#ifdef TIOCGPTPEER
static abi_long do_ioctl_tiocgptpeer(const IOCTLEntry *ie, uint8_t *buf_temp,
int fd, int cmd, abi_long arg)
{
@ -6442,7 +6447,7 @@ static void *clone_func(void *arg)
cpu = ENV_GET_CPU(env);
thread_cpu = cpu;
ts = (TaskState *)cpu->opaque;
info->tid = sys_gettid();
info->tid = gettid();
task_settid(ts);
#ifdef TARGET_ABI_IRIX
/* TODO: which fields in the PRDA are filled in by the IRIX kernel? */
@ -6604,9 +6609,9 @@ static int do_fork(CPUArchState *env, unsigned int flags, abi_ulong newsp,
mapping. We can't repeat the spinlock hack used above because
the child process gets its own copy of the lock. */
if (flags & CLONE_CHILD_SETTID)
put_user_u32(sys_gettid(), child_tidptr);
put_user_u32(gettid(), child_tidptr);
if (flags & CLONE_PARENT_SETTID)
put_user_u32(sys_gettid(), parent_tidptr);
put_user_u32(gettid(), parent_tidptr);
if (flags & CLONE_SETTLS)
cpu_set_tls (env, newtls);
if (flags & CLONE_CHILD_CLEARTID)
@ -8861,11 +8866,10 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
#ifdef TARGET_NR_stime /* not on alpha */
case TARGET_NR_stime:
{
struct timespec ts;
ts.tv_nsec = 0;
if (get_user_sal(ts.tv_sec, arg1))
time_t host_time;
if (get_user_sal(host_time, arg1))
goto efault;
ret = get_errno(clock_settime(CLOCK_REALTIME, &ts));
ret = get_errno(stime(&host_time));
}
break;
#endif
@ -12584,7 +12588,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
#endif
#ifdef TARGET_NR_gettid
case TARGET_NR_gettid:
ret = get_errno(sys_gettid());
ret = get_errno(gettid());
break;
#endif
#ifdef TARGET_NR_readahead
@ -13857,10 +13861,9 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
if (arg4) {
if (copy_from_user_timeval(&tv[0], arg4) ||
copy_from_user_timeval(&tv[1],
arg4 + sizeof(struct target_timeval))) {
arg4 + sizeof(struct target_timeval)))
unlock_user(p, arg3, 0);
goto efault;
}
tvp = tv;
} else {
tvp = NULL;
@ -14603,7 +14606,6 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
case TARGET_NR_syssgi_rldenv:
case TARGET_NR_syssgi_tosstsave:
case TARGET_NR_syssgi_fpbcopy:
case TARGET_NR_syssgi_getprocattr: /* ? 2nd=string 3rd=result ptr */
ret = 0;
break;
case TARGET_NR_syssgi_setgroups:

View File

@ -1622,7 +1622,7 @@ struct target_stat {
abi_long target_st_ctime;
abi_ulong __unused3;
abi_int st_blksize;
abi_llong st_blocks;
int64_t st_blocks;
char st_fstype[16];
abi_long __unused4[8];
};
@ -1631,14 +1631,14 @@ struct target_stat {
struct target_stat64 {
abi_ulong st_dev;
abi_long st_pad1[3];
abi_ullong st_ino;
uint64_t st_ino;
abi_uint st_mode;
abi_uint st_nlink;
abi_int st_uid;
abi_int st_gid;
abi_ulong st_rdev;
abi_long st_pad2[2];
abi_llong st_size;
int64_t st_size;
abi_long target_st_atime;
abi_ulong __unused1;
abi_long target_st_mtime;
@ -1646,7 +1646,7 @@ struct target_stat64 {
abi_long target_st_ctime;
abi_ulong __unused3;
abi_int st_blksize;
abi_llong st_blocks;
int64_t st_blocks;
char st_fstype[16];
abi_long __unused4[8];
};
@ -1977,7 +1977,7 @@ struct target_stat {
struct target_stat64 {
uint32_t st_dev;
abi_long st_pad0[3]; /* Reserved for st_dev expansion */
abi_ullong st_ino;
uint64_t st_ino;
uint32_t st_mode;
uint32_t st_nlink;
@ -1987,7 +1987,7 @@ struct target_stat64 {
uint32_t st_rdev;
abi_long st_pad1[2]; /* Reserved for st_rdev expansion */
abi_llong st_size;
int64_t st_size;
abi_long st_pad2;
/*
@ -2004,7 +2004,7 @@ struct target_stat64 {
abi_long target_st_ctime_nsec;
abi_long st_blksize;
abi_llong st_blocks;
int64_t st_blocks;
char st_fstype[16];
abi_long st_projid;
abi_long st_pad[7];

View File

@ -2696,12 +2696,6 @@ static void tcg_out_vec_op(TCGContext *s, TCGOpcode opc,
case INDEX_op_x86_packus_vec:
insn = packus_insn[vece];
goto gen_simd;
#if TCG_TARGET_REG_BITS == 32
case INDEX_op_dup2_vec:
/* Constraints have already placed both 32-bit inputs in xmm regs. */
insn = OPC_PUNPCKLDQ;
goto gen_simd;
#endif
gen_simd:
tcg_debug_assert(insn != OPC_UD2);
if (type == TCG_TYPE_V256) {
@ -3051,9 +3045,6 @@ static const TCGTargetOpDef *tcg_target_op_def(TCGOpcode op)
case INDEX_op_x86_vperm2i128_vec:
case INDEX_op_x86_punpckl_vec:
case INDEX_op_x86_punpckh_vec:
#if TCG_TARGET_REG_BITS == 32
case INDEX_op_dup2_vec:
#endif
return &x_x_x;
case INDEX_op_dup_vec:
case INDEX_op_shli_vec: