Support for executing 32 bit SPARC32PLUS files for Sparc64 user emulator
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@3378 c046a42c-6fe2-441c-8c8c-71466251a162
This commit is contained in:
parent
bf367b5409
commit
cb33da57aa
@ -13,6 +13,7 @@
|
||||
- Read-only support for Parallels disk images (Alex Beregszaszi)
|
||||
- SVM (x86 virtualization) support (Alexander Graf)
|
||||
- CRIS emulation (Edgar E. Iglesias)
|
||||
- SPARC32PLUS execution support (Blue Swirl)
|
||||
|
||||
version 0.9.0:
|
||||
|
||||
|
@ -254,6 +254,10 @@ LIBS+= $(AIOLIBS)
|
||||
ifdef TARGET_HAS_BFLT
|
||||
OBJS+= flatload.o
|
||||
endif
|
||||
ifdef TARGET_HAS_ELFLOAD32
|
||||
OBJS+= elfload32.o
|
||||
elfload32.o: elfload.c
|
||||
endif
|
||||
|
||||
ifeq ($(TARGET_ARCH), i386)
|
||||
OBJS+= vm86.o
|
||||
|
7
configure
vendored
7
configure
vendored
@ -999,6 +999,7 @@ echo "include ../config-host.mak" >> $config_mak
|
||||
echo "#include \"../config-host.h\"" >> $config_h
|
||||
|
||||
bflt="no"
|
||||
elfload32="no"
|
||||
interp_prefix1=`echo "$interp_prefix" | sed "s/%M/$target_cpu/g"`
|
||||
echo "#define CONFIG_QEMU_PREFIX \"$interp_prefix1\"" >> $config_h
|
||||
|
||||
@ -1023,6 +1024,7 @@ elif test "$target_cpu" = "sparc64" ; then
|
||||
echo "#define TARGET_ARCH \"sparc64\"" >> $config_h
|
||||
echo "#define TARGET_SPARC 1" >> $config_h
|
||||
echo "#define TARGET_SPARC64 1" >> $config_h
|
||||
elfload32="yes"
|
||||
elif test "$target_cpu" = "ppc" ; then
|
||||
echo "TARGET_ARCH=ppc" >> $config_mak
|
||||
echo "#define TARGET_ARCH \"ppc\"" >> $config_h
|
||||
@ -1112,6 +1114,11 @@ if test "$target_user_only" = "yes" -a "$bflt" = "yes"; then
|
||||
echo "TARGET_HAS_BFLT=yes" >> $config_mak
|
||||
echo "#define TARGET_HAS_BFLT 1" >> $config_h
|
||||
fi
|
||||
# 32 bit ELF loader in addition to native 64 bit loader?
|
||||
if test "$target_user_only" = "yes" -a "$elfload32" = "yes"; then
|
||||
echo "TARGET_HAS_ELFLOAD32=yes" >> $config_mak
|
||||
echo "#define TARGET_HAS_ELFLOAD32 1" >> $config_h
|
||||
fi
|
||||
# sdl defines
|
||||
|
||||
if test "$target_user_only" = "no"; then
|
||||
|
@ -12,6 +12,66 @@
|
||||
#include "qemu.h"
|
||||
#include "disas.h"
|
||||
|
||||
/* from personality.h */
|
||||
|
||||
/*
|
||||
* Flags for bug emulation.
|
||||
*
|
||||
* These occupy the top three bytes.
|
||||
*/
|
||||
enum {
|
||||
ADDR_NO_RANDOMIZE = 0x0040000, /* disable randomization of VA space */
|
||||
FDPIC_FUNCPTRS = 0x0080000, /* userspace function ptrs point to descriptors
|
||||
* (signal handling)
|
||||
*/
|
||||
MMAP_PAGE_ZERO = 0x0100000,
|
||||
ADDR_COMPAT_LAYOUT = 0x0200000,
|
||||
READ_IMPLIES_EXEC = 0x0400000,
|
||||
ADDR_LIMIT_32BIT = 0x0800000,
|
||||
SHORT_INODE = 0x1000000,
|
||||
WHOLE_SECONDS = 0x2000000,
|
||||
STICKY_TIMEOUTS = 0x4000000,
|
||||
ADDR_LIMIT_3GB = 0x8000000,
|
||||
};
|
||||
|
||||
/*
|
||||
* Personality types.
|
||||
*
|
||||
* These go in the low byte. Avoid using the top bit, it will
|
||||
* conflict with error returns.
|
||||
*/
|
||||
enum {
|
||||
PER_LINUX = 0x0000,
|
||||
PER_LINUX_32BIT = 0x0000 | ADDR_LIMIT_32BIT,
|
||||
PER_LINUX_FDPIC = 0x0000 | FDPIC_FUNCPTRS,
|
||||
PER_SVR4 = 0x0001 | STICKY_TIMEOUTS | MMAP_PAGE_ZERO,
|
||||
PER_SVR3 = 0x0002 | STICKY_TIMEOUTS | SHORT_INODE,
|
||||
PER_SCOSVR3 = 0x0003 | STICKY_TIMEOUTS |
|
||||
WHOLE_SECONDS | SHORT_INODE,
|
||||
PER_OSR5 = 0x0003 | STICKY_TIMEOUTS | WHOLE_SECONDS,
|
||||
PER_WYSEV386 = 0x0004 | STICKY_TIMEOUTS | SHORT_INODE,
|
||||
PER_ISCR4 = 0x0005 | STICKY_TIMEOUTS,
|
||||
PER_BSD = 0x0006,
|
||||
PER_SUNOS = 0x0006 | STICKY_TIMEOUTS,
|
||||
PER_XENIX = 0x0007 | STICKY_TIMEOUTS | SHORT_INODE,
|
||||
PER_LINUX32 = 0x0008,
|
||||
PER_LINUX32_3GB = 0x0008 | ADDR_LIMIT_3GB,
|
||||
PER_IRIX32 = 0x0009 | STICKY_TIMEOUTS,/* IRIX5 32-bit */
|
||||
PER_IRIXN32 = 0x000a | STICKY_TIMEOUTS,/* IRIX6 new 32-bit */
|
||||
PER_IRIX64 = 0x000b | STICKY_TIMEOUTS,/* IRIX6 64-bit */
|
||||
PER_RISCOS = 0x000c,
|
||||
PER_SOLARIS = 0x000d | STICKY_TIMEOUTS,
|
||||
PER_UW7 = 0x000e | STICKY_TIMEOUTS | MMAP_PAGE_ZERO,
|
||||
PER_OSF4 = 0x000f, /* OSF/1 v4 */
|
||||
PER_HPUX = 0x0010,
|
||||
PER_MASK = 0x00ff,
|
||||
};
|
||||
|
||||
/*
|
||||
* Return the base personality without flags.
|
||||
*/
|
||||
#define personality(pers) (pers & PER_MASK)
|
||||
|
||||
/* this flag is uneffective under linux too, should be deleted */
|
||||
#ifndef MAP_DENYWRITE
|
||||
#define MAP_DENYWRITE 0
|
||||
@ -154,7 +214,7 @@ enum
|
||||
|
||||
#define ELF_START_MMAP 0x80000000
|
||||
|
||||
#define elf_check_arch(x) ( (x) == EM_SPARCV9 )
|
||||
#define elf_check_arch(x) ( (x) == EM_SPARCV9 || (x) == EM_SPARC32PLUS )
|
||||
|
||||
#define ELF_CLASS ELFCLASS64
|
||||
#define ELF_DATA ELFDATA2MSB
|
||||
@ -168,7 +228,10 @@ static inline void init_thread(struct target_pt_regs *regs, struct image_info *i
|
||||
regs->pc = infop->entry;
|
||||
regs->npc = regs->pc + 4;
|
||||
regs->y = 0;
|
||||
regs->u_regs[14] = infop->start_stack - 16 * 8 - STACK_BIAS;
|
||||
if (personality(infop->personality) == PER_LINUX32)
|
||||
regs->u_regs[14] = infop->start_stack - 16 * 4;
|
||||
else
|
||||
regs->u_regs[14] = infop->start_stack - 16 * 8 - STACK_BIAS;
|
||||
}
|
||||
|
||||
#else
|
||||
@ -412,6 +475,13 @@ static inline void init_thread(struct target_pt_regs *regs, struct image_info *i
|
||||
#define ELF_HWCAP 0
|
||||
#endif
|
||||
|
||||
#ifdef OVERRIDE_ELF_CLASS
|
||||
#undef ELF_CLASS
|
||||
#define ELF_CLASS OVERRIDE_ELF_CLASS
|
||||
#undef bswaptls
|
||||
#define bswaptls(ptr) bswap32s(ptr)
|
||||
#endif
|
||||
|
||||
#include "elf.h"
|
||||
|
||||
struct exec
|
||||
@ -439,25 +509,6 @@ struct exec
|
||||
/* max code+data+bss+brk space allocated to ET_DYN executables */
|
||||
#define ET_DYN_MAP_SIZE (128 * 1024 * 1024)
|
||||
|
||||
/* from personality.h */
|
||||
|
||||
/* Flags for bug emulation. These occupy the top three bytes. */
|
||||
#define STICKY_TIMEOUTS 0x4000000
|
||||
#define WHOLE_SECONDS 0x2000000
|
||||
|
||||
/* Personality types. These go in the low byte. Avoid using the top bit,
|
||||
* it will conflict with error returns.
|
||||
*/
|
||||
#define PER_MASK (0x00ff)
|
||||
#define PER_LINUX (0x0000)
|
||||
#define PER_SVR4 (0x0001 | STICKY_TIMEOUTS)
|
||||
#define PER_SVR3 (0x0002 | STICKY_TIMEOUTS)
|
||||
#define PER_SCOSVR3 (0x0003 | STICKY_TIMEOUTS | WHOLE_SECONDS)
|
||||
#define PER_WYSEV386 (0x0004 | STICKY_TIMEOUTS)
|
||||
#define PER_ISCR4 (0x0005 | STICKY_TIMEOUTS)
|
||||
#define PER_BSD (0x0006)
|
||||
#define PER_XENIX (0x0007 | STICKY_TIMEOUTS)
|
||||
|
||||
/* Necessary parameters */
|
||||
#define TARGET_ELF_EXEC_PAGESIZE TARGET_PAGE_SIZE
|
||||
#define TARGET_ELF_PAGESTART(_v) ((_v) & ~(unsigned long)(TARGET_ELF_EXEC_PAGESIZE-1))
|
||||
@ -587,8 +638,8 @@ static target_ulong copy_elf_strings(int argc,char ** argv, void **page,
|
||||
return p;
|
||||
}
|
||||
|
||||
target_ulong setup_arg_pages(target_ulong p, struct linux_binprm * bprm,
|
||||
struct image_info * info)
|
||||
static target_ulong setup_arg_pages(target_ulong p, struct linux_binprm *bprm,
|
||||
struct image_info *info)
|
||||
{
|
||||
target_ulong stack_base, size, error;
|
||||
int i;
|
||||
|
30
linux-user/elfload32.c
Executable file
30
linux-user/elfload32.c
Executable file
@ -0,0 +1,30 @@
|
||||
#define OVERRIDE_ELF_CLASS ELFCLASS32
|
||||
#define load_elf_binary load_elf_binary32
|
||||
#define do_init_thread do_init_thread32
|
||||
|
||||
#include "elfload.c"
|
||||
|
||||
#undef load_elf_binary
|
||||
#undef do_init_thread
|
||||
|
||||
int load_elf_binary(struct linux_binprm *bprm, struct target_pt_regs *regs,
|
||||
struct image_info *info);
|
||||
|
||||
int load_elf_binary_multi(struct linux_binprm *bprm,
|
||||
struct target_pt_regs *regs,
|
||||
struct image_info *info)
|
||||
{
|
||||
struct elfhdr *elf_ex;
|
||||
int retval;
|
||||
|
||||
elf_ex = (struct elfhdr *) bprm->buf; /* exec-header */
|
||||
if (elf_ex->e_ident[EI_CLASS] == ELFCLASS64) {
|
||||
retval = load_elf_binary(bprm, regs, info);
|
||||
} else {
|
||||
retval = load_elf_binary32(bprm, regs, info);
|
||||
if (personality(info->personality) == PER_LINUX)
|
||||
info->personality = PER_LINUX32;
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
@ -169,7 +169,11 @@ int loader_exec(const char * filename, char ** argv, char ** envp,
|
||||
&& bprm.buf[1] == 'E'
|
||||
&& bprm.buf[2] == 'L'
|
||||
&& bprm.buf[3] == 'F') {
|
||||
#ifndef TARGET_HAS_ELFLOAD32
|
||||
retval = load_elf_binary(&bprm,regs,infop);
|
||||
#else
|
||||
retval = load_elf_binary_multi(&bprm, regs, infop);
|
||||
#endif
|
||||
#if defined(TARGET_HAS_BFLT)
|
||||
} else if (bprm.buf[0] == 'b'
|
||||
&& bprm.buf[1] == 'F'
|
||||
|
@ -564,6 +564,7 @@ void cpu_loop (CPUSPARCState *env)
|
||||
case 0x88:
|
||||
case 0x90:
|
||||
#else
|
||||
case 0x110:
|
||||
case 0x16d:
|
||||
#endif
|
||||
ret = do_syscall (env, env->gregs[1],
|
||||
|
@ -124,6 +124,11 @@ int load_elf_binary(struct linux_binprm * bprm, struct target_pt_regs * regs,
|
||||
struct image_info * info);
|
||||
int load_flt_binary(struct linux_binprm * bprm, struct target_pt_regs * regs,
|
||||
struct image_info * info);
|
||||
#ifdef TARGET_HAS_ELFLOAD32
|
||||
int load_elf_binary_multi(struct linux_binprm *bprm,
|
||||
struct target_pt_regs *regs,
|
||||
struct image_info *info);
|
||||
#endif
|
||||
|
||||
void memcpy_to_target(target_ulong dest, const void *src,
|
||||
unsigned long len);
|
||||
|
@ -29,11 +29,11 @@
|
||||
#define TARGET_NR_sigaltstack 28 /* Common */
|
||||
#define TARGET_NR_pause 29 /* Is sigblock(0)->sigpause() in SunOS */
|
||||
#define TARGET_NR_utime 30 /* Implemented via utimes() under SunOS */
|
||||
/* #define TARGET_NR_lchown32 31 Linux sparc32 specific */
|
||||
/* #define TARGET_NR_fchown32 32 Linux sparc32 specific */
|
||||
#define TARGET_NR_lchown32 31 /* Linux sparc32 specific */
|
||||
#define TARGET_NR_fchown32 32 /* Linux sparc32 specific */
|
||||
#define TARGET_NR_access 33 /* Common */
|
||||
#define TARGET_NR_nice 34 /* Implemented via get/setpriority() in SunOS */
|
||||
/* #define TARGET_NR_chown32 35 Linux sparc32 specific */
|
||||
#define TARGET_NR_chown32 35 /* Linux sparc32 specific */
|
||||
#define TARGET_NR_sync 36 /* Common */
|
||||
#define TARGET_NR_kill 37 /* Common */
|
||||
#define TARGET_NR_stat 38 /* Common */
|
||||
@ -42,7 +42,7 @@
|
||||
#define TARGET_NR_dup 41 /* Common */
|
||||
#define TARGET_NR_pipe 42 /* Common */
|
||||
#define TARGET_NR_times 43 /* Implemented via getrusage() in SunOS */
|
||||
/* #define TARGET_NR_getuid32 44 Linux sparc32 specific */
|
||||
#define TARGET_NR_getuid32 44 /* Linux sparc32 specific */
|
||||
#define TARGET_NR_umount2 45 /* Linux Specific */
|
||||
#define TARGET_NR_setgid 46 /* Implemented via setregid() in SunOS */
|
||||
#define TARGET_NR_getgid 47 /* Common */
|
||||
@ -51,48 +51,48 @@
|
||||
#define TARGET_NR_getegid 50 /* SunOS calls getgid() */
|
||||
#define TARGET_NR_acct 51 /* Common */
|
||||
#define TARGET_NR_memory_ordering 52 /* Linux Specific */
|
||||
/* #define TARGET_NR_getgid32 53 Linux sparc32 specific */
|
||||
#define TARGET_NR_getgid32 53 /* Linux sparc32 specific */
|
||||
#define TARGET_NR_ioctl 54 /* Common */
|
||||
#define TARGET_NR_reboot 55 /* Common */
|
||||
/* #define TARGET_NR_mmap2 56 Linux sparc32 Specific */
|
||||
#define TARGET_NR_mmap2 56 /* Linux sparc32 Specific */
|
||||
#define TARGET_NR_symlink 57 /* Common */
|
||||
#define TARGET_NR_readlink 58 /* Common */
|
||||
#define TARGET_NR_execve 59 /* Common */
|
||||
#define TARGET_NR_umask 60 /* Common */
|
||||
#define TARGET_NR_chroot 61 /* Common */
|
||||
#define TARGET_NR_fstat 62 /* Common */
|
||||
/* #define TARGET_NR_fstat64 63 Linux sparc32 Specific */
|
||||
#define TARGET_NR_fstat64 63 /* Linux sparc32 Specific */
|
||||
#define TARGET_NR_getpagesize 64 /* Common */
|
||||
#define TARGET_NR_msync 65 /* Common in newer 1.3.x revs... */
|
||||
#define TARGET_NR_vfork 66 /* Common */
|
||||
#define TARGET_NR_pread64 67 /* Linux Specific */
|
||||
#define TARGET_NR_pwrite64 68 /* Linux Specific */
|
||||
/* #define TARGET_NR_geteuid32 69 Linux sparc32, sbrk under SunOS */
|
||||
/* #define TARGET_NR_getegid32 70 Linux sparc32, sstk under SunOS */
|
||||
#define TARGET_NR_geteuid32 69 /* Linux sparc32, sbrk under SunOS */
|
||||
#define TARGET_NR_getegid32 70 /* Linux sparc32, sstk under SunOS */
|
||||
#define TARGET_NR_mmap 71 /* Common */
|
||||
/* #define TARGET_NR_setreuid32 72 Linux sparc32, vadvise under SunOS */
|
||||
#define TARGET_NR_setreuid32 72 /* Linux sparc32, vadvise under SunOS */
|
||||
#define TARGET_NR_munmap 73 /* Common */
|
||||
#define TARGET_NR_mprotect 74 /* Common */
|
||||
#define TARGET_NR_madvise 75 /* Common */
|
||||
#define TARGET_NR_vhangup 76 /* Common */
|
||||
/* #define TARGET_NR_truncate64 77 Linux sparc32 Specific */
|
||||
#define TARGET_NR_truncate64 77 /* Linux sparc32 Specific */
|
||||
#define TARGET_NR_mincore 78 /* Common */
|
||||
#define TARGET_NR_getgroups 79 /* Common */
|
||||
#define TARGET_NR_setgroups 80 /* Common */
|
||||
#define TARGET_NR_getpgrp 81 /* Common */
|
||||
/* #define TARGET_NR_setgroups32 82 Linux sparc32, setpgrp under SunOS */
|
||||
#define TARGET_NR_setgroups32 82 /* Linux sparc32, setpgrp under SunOS */
|
||||
#define TARGET_NR_setitimer 83 /* Common */
|
||||
/* #define TARGET_NR_ftruncate64 84 Linux sparc32 Specific */
|
||||
#define TARGET_NR_ftruncate64 84 /* Linux sparc32 Specific */
|
||||
#define TARGET_NR_swapon 85 /* Common */
|
||||
#define TARGET_NR_getitimer 86 /* Common */
|
||||
/* #define TARGET_NR_setuid32 87 Linux sparc32, gethostname under SunOS */
|
||||
#define TARGET_NR_setuid32 87 /* Linux sparc32, gethostname under SunOS */
|
||||
#define TARGET_NR_sethostname 88 /* Common */
|
||||
/* #define TARGET_NR_setgid32 89 Linux sparc32, getdtablesize under SunOS */
|
||||
#define TARGET_NR_setgid32 89 /* Linux sparc32, getdtablesize under SunOS */
|
||||
#define TARGET_NR_dup2 90 /* Common */
|
||||
/* #define TARGET_NR_setfsuid32 91 Linux sparc32, getdopt under SunOS */
|
||||
#define TARGET_NR_setfsuid32 91 /* Linux sparc32, getdopt under SunOS */
|
||||
#define TARGET_NR_fcntl 92 /* Common */
|
||||
#define TARGET_NR_select 93 /* Common */
|
||||
/* #define TARGET_NR_setfsgid32 94 Linux sparc32, setdopt under SunOS */
|
||||
#define TARGET_NR_setfsgid32 94 /* Linux sparc32, setdopt under SunOS */
|
||||
#define TARGET_NR_fsync 95 /* Common */
|
||||
#define TARGET_NR_setpriority 96 /* Common */
|
||||
#define TARGET_NR_socket 97 /* Common */
|
||||
@ -110,10 +110,10 @@
|
||||
#define TARGET_NR_getresuid 109 /* Linux Specific, sigblock under SunOS */
|
||||
#define TARGET_NR_setresgid 110 /* Linux Specific, sigsetmask under SunOS */
|
||||
#define TARGET_NR_getresgid 111 /* Linux Specific, sigpause under SunOS */
|
||||
/* #define TARGET_NR_setregid32 75 Linux sparc32, sigstack under SunOS */
|
||||
/* #define TARGET_NR_setregid32 75 Linux sparc32, sigstack under SunOS */
|
||||
#define TARGET_NR_recvmsg 113 /* Common */
|
||||
#define TARGET_NR_sendmsg 114 /* Common */
|
||||
/* #define TARGET_NR_getgroups32 115 Linux sparc32, vtrace under SunOS */
|
||||
#define TARGET_NR_getgroups32 115 /* Linux sparc32, vtrace under SunOS */
|
||||
#define TARGET_NR_gettimeofday 116 /* Common */
|
||||
#define TARGET_NR_getrusage 117 /* Common */
|
||||
#define TARGET_NR_getsockopt 118 /* Common */
|
||||
@ -130,14 +130,14 @@
|
||||
#define TARGET_NR_truncate 129 /* Common */
|
||||
#define TARGET_NR_ftruncate 130 /* Common */
|
||||
#define TARGET_NR_flock 131 /* Common */
|
||||
/* #define TARGET_NR_lstat64 132 Linux sparc32 Specific */
|
||||
#define TARGET_NR_lstat64 132 /* Linux sparc32 Specific */
|
||||
#define TARGET_NR_sendto 133 /* Common */
|
||||
#define TARGET_NR_shutdown 134 /* Common */
|
||||
#define TARGET_NR_socketpair 135 /* Common */
|
||||
#define TARGET_NR_mkdir 136 /* Common */
|
||||
#define TARGET_NR_rmdir 137 /* Common */
|
||||
#define TARGET_NR_utimes 138 /* SunOS Specific */
|
||||
/* #define TARGET_NR_stat64 139 Linux sparc32 Specific */
|
||||
#define TARGET_NR_stat64 139 /* Linux sparc32 Specific */
|
||||
#define TARGET_NR_sendfile64 140 /* adjtime under SunOS */
|
||||
#define TARGET_NR_getpeername 141 /* Common */
|
||||
#define TARGET_NR_futex 142 /* gethostid under SunOS */
|
||||
@ -153,7 +153,7 @@
|
||||
/* #define TARGET_NR_putmsg 152 SunOS Specific */
|
||||
#define TARGET_NR_poll 153 /* Common */
|
||||
#define TARGET_NR_getdents64 154 /* Linux specific */
|
||||
/* #define TARGET_NR_fcntl64 155 Linux sparc32 Specific */
|
||||
#define TARGET_NR_fcntl64 155 /* Linux sparc32 Specific */
|
||||
/* #define TARGET_NR_getdirentries 156 SunOS Specific */
|
||||
#define TARGET_NR_statfs 157 /* Common */
|
||||
#define TARGET_NR_fstatfs 158 /* Common */
|
||||
@ -229,9 +229,7 @@
|
||||
#define TARGET_NR_setfsuid 228 /* Linux Specific */
|
||||
#define TARGET_NR_setfsgid 229 /* Linux Specific */
|
||||
#define TARGET_NR__newselect 230 /* Linux Specific */
|
||||
#ifdef __KERNEL__
|
||||
#define TARGET_NR_time 231 /* Linux sparc32 */
|
||||
#endif
|
||||
#define TARGET_NR_time 231 /* Linux sparc32 */
|
||||
/* #define TARGET_NR_oldstat 232 Linux Specific */
|
||||
#define TARGET_NR_stime 233 /* Linux Specific */
|
||||
#define TARGET_NR_statfs64 234 /* Linux Specific */
|
||||
|
Loading…
Reference in New Issue
Block a user