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:
blueswir1 2007-10-09 16:34:29 +00:00
parent bf367b5409
commit cb33da57aa
9 changed files with 149 additions and 48 deletions

View File

@ -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:

View File

@ -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
View File

@ -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

View File

@ -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
View 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;
}

View File

@ -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'

View File

@ -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],

View File

@ -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);

View File

@ -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 */