Compare commits
12 Commits
Author | SHA1 | Date |
---|---|---|
![]() |
6d7d1fde2f | |
![]() |
364524131d | |
![]() |
23b58bb197 | |
![]() |
939acda8af | |
![]() |
d233430274 | |
![]() |
32ab296eef | |
![]() |
1882f0cb4b | |
![]() |
a2ba448e6b | |
![]() |
5db1913741 | |
![]() |
9dbbf36224 | |
![]() |
b9d1f49337 | |
![]() |
4cb644d4b0 |
47
README.md
47
README.md
|
@ -3,7 +3,8 @@ only under linux (though BSD support would probably be feasable).
|
|||
|
||||
### compiling
|
||||
|
||||
Configure QEMU for irix/solaris userland emulation and compile:
|
||||
Configure QEMU for irix/solaris userland emulation and compile (see the original
|
||||
QEMU README for further instructions):
|
||||
|
||||
```
|
||||
configure --target-list=irix-linux-user,irixn32-linux-user,irix64-linux-user,solaris-linux-user
|
||||
|
@ -12,31 +13,10 @@ make && make install
|
|||
|
||||
### using
|
||||
|
||||
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
|
||||
```
|
||||
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.
|
||||
|
||||
Now you should be able to directly execute irix/solaris binaries from the shell.
|
||||
As a rather simple test, try:
|
||||
|
@ -45,4 +25,19 @@ 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>)
|
||||
|
|
|
@ -6836,6 +6836,7 @@ 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)
|
||||
|
|
|
@ -2067,6 +2067,8 @@ 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
|
||||
|
@ -2113,9 +2115,13 @@ 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;
|
||||
|
|
|
@ -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))
|
||||
#ifdef TIOCGPTPEER
|
||||
#if defined TIOCGPTPEER && defined TARGET_TIOCGPTPEER
|
||||
IOCTL_SPECIAL(TIOCGPTPEER, 0, do_ioctl_tiocgptpeer, TYPE_INT)
|
||||
#endif
|
||||
IOCTL(FIOCLEX, 0, TYPE_NULL)
|
||||
|
|
|
@ -258,6 +258,7 @@
|
|||
/* 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)
|
||||
|
|
|
@ -40,6 +40,7 @@
|
|||
#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>
|
||||
|
@ -258,15 +259,9 @@ static inline type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5,
|
|||
#define TARGET_NR__llseek TARGET_NR_llseek
|
||||
#endif
|
||||
|
||||
#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
|
||||
#define __NR_sys_gettid __NR_gettid
|
||||
_syscall0(int, sys_gettid)
|
||||
|
||||
#if defined(TARGET_NR_getdents) && defined(__NR_getdents)
|
||||
_syscall3(int, sys_getdents, uint, fd, struct linux_dirent *, dirp, uint, count);
|
||||
#endif
|
||||
|
@ -5787,7 +5782,7 @@ static abi_long do_ioctl_kdsigaccept(const IOCTLEntry *ie, uint8_t *buf_temp,
|
|||
}
|
||||
#endif
|
||||
|
||||
#ifdef TIOCGPTPEER
|
||||
#if defined TIOCGPTPEER && defined TARGET_TIOCGPTPEER
|
||||
static abi_long do_ioctl_tiocgptpeer(const IOCTLEntry *ie, uint8_t *buf_temp,
|
||||
int fd, int cmd, abi_long arg)
|
||||
{
|
||||
|
@ -6447,7 +6442,7 @@ static void *clone_func(void *arg)
|
|||
cpu = ENV_GET_CPU(env);
|
||||
thread_cpu = cpu;
|
||||
ts = (TaskState *)cpu->opaque;
|
||||
info->tid = gettid();
|
||||
info->tid = sys_gettid();
|
||||
task_settid(ts);
|
||||
#ifdef TARGET_ABI_IRIX
|
||||
/* TODO: which fields in the PRDA are filled in by the IRIX kernel? */
|
||||
|
@ -6609,9 +6604,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(gettid(), child_tidptr);
|
||||
put_user_u32(sys_gettid(), child_tidptr);
|
||||
if (flags & CLONE_PARENT_SETTID)
|
||||
put_user_u32(gettid(), parent_tidptr);
|
||||
put_user_u32(sys_gettid(), parent_tidptr);
|
||||
if (flags & CLONE_SETTLS)
|
||||
cpu_set_tls (env, newtls);
|
||||
if (flags & CLONE_CHILD_CLEARTID)
|
||||
|
@ -8866,10 +8861,11 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
|
|||
#ifdef TARGET_NR_stime /* not on alpha */
|
||||
case TARGET_NR_stime:
|
||||
{
|
||||
time_t host_time;
|
||||
if (get_user_sal(host_time, arg1))
|
||||
struct timespec ts;
|
||||
ts.tv_nsec = 0;
|
||||
if (get_user_sal(ts.tv_sec, arg1))
|
||||
goto efault;
|
||||
ret = get_errno(stime(&host_time));
|
||||
ret = get_errno(clock_settime(CLOCK_REALTIME, &ts));
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
|
@ -12588,7 +12584,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(gettid());
|
||||
ret = get_errno(sys_gettid());
|
||||
break;
|
||||
#endif
|
||||
#ifdef TARGET_NR_readahead
|
||||
|
@ -13861,9 +13857,10 @@ 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;
|
||||
|
@ -14606,6 +14603,7 @@ 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:
|
||||
|
|
|
@ -1622,7 +1622,7 @@ struct target_stat {
|
|||
abi_long target_st_ctime;
|
||||
abi_ulong __unused3;
|
||||
abi_int st_blksize;
|
||||
int64_t st_blocks;
|
||||
abi_llong 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];
|
||||
uint64_t st_ino;
|
||||
abi_ullong 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];
|
||||
int64_t st_size;
|
||||
abi_llong 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;
|
||||
int64_t st_blocks;
|
||||
abi_llong 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 */
|
||||
uint64_t st_ino;
|
||||
abi_ullong 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 */
|
||||
int64_t st_size;
|
||||
abi_llong st_size;
|
||||
abi_long st_pad2;
|
||||
|
||||
/*
|
||||
|
@ -2004,7 +2004,7 @@ struct target_stat64 {
|
|||
abi_long target_st_ctime_nsec;
|
||||
|
||||
abi_long st_blksize;
|
||||
int64_t st_blocks;
|
||||
abi_llong st_blocks;
|
||||
char st_fstype[16];
|
||||
abi_long st_projid;
|
||||
abi_long st_pad[7];
|
||||
|
|
|
@ -2696,6 +2696,12 @@ 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) {
|
||||
|
@ -3045,6 +3051,9 @@ 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:
|
||||
|
|
Loading…
Reference in New Issue