Darwin patch (initial patch by Pierre d'Herbemont)

git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@980 c046a42c-6fe2-441c-8c8c-71466251a162
This commit is contained in:
bellard 2004-07-05 21:25:26 +00:00
parent 1d43a71773
commit 83fb7adf6c
14 changed files with 185 additions and 106 deletions

View File

@ -1,6 +1,9 @@
include config-host.mak include config-host.mak
CFLAGS=-Wall -O2 -g CFLAGS=-Wall -O2 -g
ifdef CONFIG_DARWIN
CFLAGS+= -mdynamic-no-pic
endif
ifdef CONFIG_WIN32 ifdef CONFIG_WIN32
CFLAGS+=-fpack-struct CFLAGS+=-fpack-struct
endif endif

View File

@ -100,6 +100,7 @@ LDFLAGS+=-Wl,-T,$(SRC_PATH)/amd64.ld
endif endif
ifeq ($(ARCH),ppc) ifeq ($(ARCH),ppc)
CFLAGS+= -D__powerpc__
OP_CFLAGS=$(CFLAGS) OP_CFLAGS=$(CFLAGS)
LDFLAGS+=-Wl,-T,$(SRC_PATH)/ppc.ld LDFLAGS+=-Wl,-T,$(SRC_PATH)/ppc.ld
endif endif
@ -152,6 +153,10 @@ ifeq ($(HAVE_GCC3_OPTIONS),yes)
OP_CFLAGS+=-fno-reorder-blocks -fno-optimize-sibling-calls OP_CFLAGS+=-fno-reorder-blocks -fno-optimize-sibling-calls
endif endif
ifeq ($(CONFIG_DARWIN),yes)
OP_CFLAGS+= -mdynamic-no-pic
endif
######################################################### #########################################################
DEFINES+=-D_GNU_SOURCE DEFINES+=-D_GNU_SOURCE
@ -267,9 +272,11 @@ endif
ifndef CONFIG_SOFTMMU ifndef CONFIG_SOFTMMU
VL_LDFLAGS+=-Wl,-T,$(SRC_PATH)/i386-vl.ld VL_LDFLAGS+=-Wl,-T,$(SRC_PATH)/i386-vl.ld
endif endif
ifndef CONFIG_DARWIN
ifndef CONFIG_WIN32 ifndef CONFIG_WIN32
VL_LIBS=-lutil VL_LIBS=-lutil
endif endif
endif
$(QEMU_SYSTEM): $(VL_OBJS) libqemu.a $(QEMU_SYSTEM): $(VL_OBJS) libqemu.a
$(CC) $(VL_LDFLAGS) -o $@ $^ $(LIBS) $(SDL_LIBS) $(VL_LIBS) $(CC) $(VL_LDFLAGS) -o $@ $^ $(LIBS) $(SDL_LIBS) $(VL_LIBS)

17
configure vendored
View File

@ -88,12 +88,18 @@ bsd="yes"
OpenBSD) OpenBSD)
bsd="yes" bsd="yes"
;; ;;
Darwin)
bsd="yes"
darwin="yes"
;;
*) ;; *) ;;
esac esac
if [ "$bsd" = "yes" ] ; then if [ "$bsd" = "yes" ] ; then
make="gmake" if [ ! "$darwin" = "yes" ] ; then
target_list="i386-softmmu" make="gmake"
fi
target_list="i386-softmmu ppc-softmmu"
fi fi
# find source path # find source path
@ -391,6 +397,10 @@ if test "$mingw32" = "yes" ; then
elif test -f "/usr/include/byteswap.h" ; then elif test -f "/usr/include/byteswap.h" ; then
echo "#define HAVE_BYTESWAP_H 1" >> $config_h echo "#define HAVE_BYTESWAP_H 1" >> $config_h
fi fi
if test "$darwin" = "yes" ; then
echo "CONFIG_DARWIN=yes" >> $config_mak
echo "#define CONFIG_DARWIN 1" >> $config_h
fi
if test "$gdbstub" = "yes" ; then if test "$gdbstub" = "yes" ; then
echo "CONFIG_GDBSTUB=yes" >> $config_mak echo "CONFIG_GDBSTUB=yes" >> $config_mak
echo "#define CONFIG_GDBSTUB 1" >> $config_h echo "#define CONFIG_GDBSTUB 1" >> $config_h
@ -417,10 +427,13 @@ echo "\"" >> $config_h
echo "SRC_PATH=$source_path" >> $config_mak echo "SRC_PATH=$source_path" >> $config_mak
echo "TARGET_DIRS=$target_list" >> $config_mak echo "TARGET_DIRS=$target_list" >> $config_mak
# XXX: suppress that
if [ "$bsd" = "yes" ] ; then if [ "$bsd" = "yes" ] ; then
echo "#define O_LARGEFILE 0" >> $config_h echo "#define O_LARGEFILE 0" >> $config_h
echo "#define lseek64 lseek" >> $config_h echo "#define lseek64 lseek" >> $config_h
echo "#define mkstemp64 mkstemp" >> $config_h
echo "#define ftruncate64 ftruncate" >> $config_h echo "#define ftruncate64 ftruncate" >> $config_h
echo "#define off64_t off_t" >> $config_h
echo "#define MAP_ANONYMOUS MAP_ANON" >> $config_h echo "#define MAP_ANONYMOUS MAP_ANON" >> $config_h
echo "#define _BSD 1" >> $config_h echo "#define _BSD 1" >> $config_h
fi fi

View File

@ -538,12 +538,12 @@ static inline void stfq_raw(void *ptr, double v)
#define TARGET_PAGE_MASK ~(TARGET_PAGE_SIZE - 1) #define TARGET_PAGE_MASK ~(TARGET_PAGE_SIZE - 1)
#define TARGET_PAGE_ALIGN(addr) (((addr) + TARGET_PAGE_SIZE - 1) & TARGET_PAGE_MASK) #define TARGET_PAGE_ALIGN(addr) (((addr) + TARGET_PAGE_SIZE - 1) & TARGET_PAGE_MASK)
extern unsigned long real_host_page_size; extern unsigned long qemu_real_host_page_size;
extern unsigned long host_page_bits; extern unsigned long qemu_host_page_bits;
extern unsigned long host_page_size; extern unsigned long qemu_host_page_size;
extern unsigned long host_page_mask; extern unsigned long qemu_host_page_mask;
#define HOST_PAGE_ALIGN(addr) (((addr) + host_page_size - 1) & host_page_mask) #define HOST_PAGE_ALIGN(addr) (((addr) + qemu_host_page_size - 1) & qemu_host_page_mask)
/* same as PROT_xxx */ /* same as PROT_xxx */
#define PAGE_READ 0x0001 #define PAGE_READ 0x0001

View File

@ -852,24 +852,72 @@ int cpu_signal_handler(int host_signum, struct siginfo *info,
&uc->uc_sigmask, puc); &uc->uc_sigmask, puc);
} }
#elif defined(__powerpc) #elif defined(__powerpc__)
int cpu_signal_handler(int host_signum, struct siginfo *info, /***********************************************************************
* signal context platform-specific definitions
* From Wine
*/
#ifdef linux
/* All Registers access - only for local access */
# define REG_sig(reg_name, context) ((context)->uc_mcontext.regs->reg_name)
/* Gpr Registers access */
# define GPR_sig(reg_num, context) REG_sig(gpr[reg_num], context)
# define IAR_sig(context) REG_sig(nip, context) /* Program counter */
# define MSR_sig(context) REG_sig(msr, context) /* Machine State Register (Supervisor) */
# define CTR_sig(context) REG_sig(ctr, context) /* Count register */
# define XER_sig(context) REG_sig(xer, context) /* User's integer exception register */
# define LR_sig(context) REG_sig(link, context) /* Link register */
# define CR_sig(context) REG_sig(ccr, context) /* Condition register */
/* Float Registers access */
# define FLOAT_sig(reg_num, context) (((double*)((char*)((context)->uc_mcontext.regs+48*4)))[reg_num])
# define FPSCR_sig(context) (*(int*)((char*)((context)->uc_mcontext.regs+(48+32*2)*4)))
/* Exception Registers access */
# define DAR_sig(context) REG_sig(dar, context)
# define DSISR_sig(context) REG_sig(dsisr, context)
# define TRAP_sig(context) REG_sig(trap, context)
#endif /* linux */
#ifdef __APPLE__
# include <sys/ucontext.h>
typedef struct ucontext SIGCONTEXT;
/* All Registers access - only for local access */
# define REG_sig(reg_name, context) ((context)->uc_mcontext->ss.reg_name)
# define FLOATREG_sig(reg_name, context) ((context)->uc_mcontext->fs.reg_name)
# define EXCEPREG_sig(reg_name, context) ((context)->uc_mcontext->es.reg_name)
# define VECREG_sig(reg_name, context) ((context)->uc_mcontext->vs.reg_name)
/* Gpr Registers access */
# define GPR_sig(reg_num, context) REG_sig(r##reg_num, context)
# define IAR_sig(context) REG_sig(srr0, context) /* Program counter */
# define MSR_sig(context) REG_sig(srr1, context) /* Machine State Register (Supervisor) */
# define CTR_sig(context) REG_sig(ctr, context)
# define XER_sig(context) REG_sig(xer, context) /* Link register */
# define LR_sig(context) REG_sig(lr, context) /* User's integer exception register */
# define CR_sig(context) REG_sig(cr, context) /* Condition register */
/* Float Registers access */
# define FLOAT_sig(reg_num, context) FLOATREG_sig(fpregs[reg_num], context)
# define FPSCR_sig(context) ((double)FLOATREG_sig(fpscr, context))
/* Exception Registers access */
# define DAR_sig(context) EXCEPREG_sig(dar, context) /* Fault registers for coredump */
# define DSISR_sig(context) EXCEPREG_sig(dsisr, context)
# define TRAP_sig(context) EXCEPREG_sig(exception, context) /* number of powerpc exception taken */
#endif /* __APPLE__ */
int cpu_signal_handler(int host_signum, siginfo *info,
void *puc) void *puc)
{ {
struct ucontext *uc = puc; struct ucontext *uc = puc;
struct pt_regs *regs = uc->uc_mcontext.regs;
unsigned long pc; unsigned long pc;
int is_write; int is_write;
pc = regs->nip; pc = IAR_sig(uc);
is_write = 0; is_write = 0;
#if 0 #if 0
/* ppc 4xx case */ /* ppc 4xx case */
if (regs->dsisr & 0x00800000) if (DSISR_sig(uc) & 0x00800000)
is_write = 1; is_write = 1;
#else #else
if (regs->trap != 0x400 && (regs->dsisr & 0x02000000)) if (TRAP_sig(uc) != 0x400 && (DSISR_sig(uc) & 0x02000000))
is_write = 1; is_write = 1;
#endif #endif
return handle_cpu_signal(pc, (unsigned long)info->si_addr, return handle_cpu_signal(pc, (unsigned long)info->si_addr,

View File

@ -59,8 +59,14 @@ extern int fprintf(FILE *, const char *, ...);
extern int printf(const char *, ...); extern int printf(const char *, ...);
#undef NULL #undef NULL
#define NULL 0 #define NULL 0
#ifdef _BSD #if defined(_BSD) && !defined(__APPLE__)
#include <ieeefp.h> #include <ieeefp.h>
#define FE_TONEAREST FP_RN
#define FE_DOWNWARD FP_RM
#define FE_UPWARD FP_RP
#define FE_TOWARDZERO FP_RZ
#define fesetround(x) fpsetround(x)
#else #else
#include <fenv.h> #include <fenv.h>
#endif #endif

42
exec.c
View File

@ -100,10 +100,10 @@ typedef struct VirtPageDesc {
static void io_mem_init(void); static void io_mem_init(void);
unsigned long real_host_page_size; unsigned long qemu_real_host_page_size;
unsigned long host_page_bits; unsigned long qemu_host_page_bits;
unsigned long host_page_size; unsigned long qemu_host_page_size;
unsigned long host_page_mask; unsigned long qemu_host_page_mask;
/* XXX: for system emulation, it could just be an array */ /* XXX: for system emulation, it could just be an array */
static PageDesc *l1_map[L1_SIZE]; static PageDesc *l1_map[L1_SIZE];
@ -127,21 +127,21 @@ int loglevel;
static void page_init(void) static void page_init(void)
{ {
/* NOTE: we can always suppose that host_page_size >= /* NOTE: we can always suppose that qemu_host_page_size >=
TARGET_PAGE_SIZE */ TARGET_PAGE_SIZE */
#ifdef _WIN32 #ifdef _WIN32
real_host_page_size = 4096; qemu_real_host_page_size = 4096;
#else #else
real_host_page_size = getpagesize(); qemu_real_host_page_size = getpagesize();
#endif #endif
if (host_page_size == 0) if (qemu_host_page_size == 0)
host_page_size = real_host_page_size; qemu_host_page_size = qemu_real_host_page_size;
if (host_page_size < TARGET_PAGE_SIZE) if (qemu_host_page_size < TARGET_PAGE_SIZE)
host_page_size = TARGET_PAGE_SIZE; qemu_host_page_size = TARGET_PAGE_SIZE;
host_page_bits = 0; qemu_host_page_bits = 0;
while ((1 << host_page_bits) < host_page_size) while ((1 << qemu_host_page_bits) < qemu_host_page_size)
host_page_bits++; qemu_host_page_bits++;
host_page_mask = ~(host_page_size - 1); qemu_host_page_mask = ~(qemu_host_page_size - 1);
#if !defined(CONFIG_USER_ONLY) #if !defined(CONFIG_USER_ONLY)
virt_valid_tag = 1; virt_valid_tag = 1;
#endif #endif
@ -831,12 +831,12 @@ static inline void tb_alloc_page(TranslationBlock *tb,
/* force the host page as non writable (writes will have a /* force the host page as non writable (writes will have a
page fault + mprotect overhead) */ page fault + mprotect overhead) */
host_start = page_addr & host_page_mask; host_start = page_addr & qemu_host_page_mask;
host_end = host_start + host_page_size; host_end = host_start + qemu_host_page_size;
prot = 0; prot = 0;
for(addr = host_start; addr < host_end; addr += TARGET_PAGE_SIZE) for(addr = host_start; addr < host_end; addr += TARGET_PAGE_SIZE)
prot |= page_get_flags(addr); prot |= page_get_flags(addr);
mprotect((void *)host_start, host_page_size, mprotect((void *)host_start, qemu_host_page_size,
(prot & PAGE_BITS) & ~PAGE_WRITE); (prot & PAGE_BITS) & ~PAGE_WRITE);
#ifdef DEBUG_TB_INVALIDATE #ifdef DEBUG_TB_INVALIDATE
printf("protecting code page: 0x%08lx\n", printf("protecting code page: 0x%08lx\n",
@ -1737,12 +1737,12 @@ int page_unprotect(unsigned long address, unsigned long pc, void *puc)
PageDesc *p, *p1; PageDesc *p, *p1;
unsigned long host_start, host_end, addr; unsigned long host_start, host_end, addr;
host_start = address & host_page_mask; host_start = address & qemu_host_page_mask;
page_index = host_start >> TARGET_PAGE_BITS; page_index = host_start >> TARGET_PAGE_BITS;
p1 = page_find(page_index); p1 = page_find(page_index);
if (!p1) if (!p1)
return 0; return 0;
host_end = host_start + host_page_size; host_end = host_start + qemu_host_page_size;
p = p1; p = p1;
prot = 0; prot = 0;
for(addr = host_start;addr < host_end; addr += TARGET_PAGE_SIZE) { for(addr = host_start;addr < host_end; addr += TARGET_PAGE_SIZE) {
@ -1754,7 +1754,7 @@ int page_unprotect(unsigned long address, unsigned long pc, void *puc)
if (prot & PAGE_WRITE_ORG) { if (prot & PAGE_WRITE_ORG) {
pindex = (address - host_start) >> TARGET_PAGE_BITS; pindex = (address - host_start) >> TARGET_PAGE_BITS;
if (!(p1[pindex].flags & PAGE_WRITE)) { if (!(p1[pindex].flags & PAGE_WRITE)) {
mprotect((void *)host_start, host_page_size, mprotect((void *)host_start, qemu_host_page_size,
(prot & PAGE_BITS) | PAGE_WRITE); (prot & PAGE_BITS) | PAGE_WRITE);
p1[pindex].flags |= PAGE_WRITE; p1[pindex].flags |= PAGE_WRITE;
/* and since the content will be modified, we must invalidate /* and since the content will be modified, we must invalidate

View File

@ -13,6 +13,16 @@
#include "qemu.h" #include "qemu.h"
#include "disas.h" #include "disas.h"
/* this flag is uneffective under linux too, should be deleted */
#ifndef MAP_DENYWRITE
#define MAP_DENYWRITE 0
#endif
/* should probably go in elf.h */
#ifndef ELIBBAD
#define ELIBBAD 80
#endif
#ifdef TARGET_I386 #ifdef TARGET_I386
#define ELF_START_MMAP 0x80000000 #define ELF_START_MMAP 0x80000000
@ -332,7 +342,7 @@ static void * get_free_page(void)
/* User-space version of kernel get_free_page. Returns a page-aligned /* User-space version of kernel get_free_page. Returns a page-aligned
* page-sized chunk of memory. * page-sized chunk of memory.
*/ */
retval = (void *)target_mmap(0, host_page_size, PROT_READ|PROT_WRITE, retval = (void *)target_mmap(0, qemu_host_page_size, PROT_READ|PROT_WRITE,
MAP_PRIVATE|MAP_ANONYMOUS, -1, 0); MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
if((long)retval == -1) { if((long)retval == -1) {
@ -346,7 +356,7 @@ static void * get_free_page(void)
static void free_page(void * pageaddr) static void free_page(void * pageaddr)
{ {
target_munmap((unsigned long)pageaddr, host_page_size); target_munmap((unsigned long)pageaddr, qemu_host_page_size);
} }
/* /*
@ -502,7 +512,7 @@ unsigned long setup_arg_pages(unsigned long p, struct linux_binprm * bprm,
if (size < MAX_ARG_PAGES*TARGET_PAGE_SIZE) if (size < MAX_ARG_PAGES*TARGET_PAGE_SIZE)
size = MAX_ARG_PAGES*TARGET_PAGE_SIZE; size = MAX_ARG_PAGES*TARGET_PAGE_SIZE;
error = target_mmap(0, error = target_mmap(0,
size + host_page_size, size + qemu_host_page_size,
PROT_READ | PROT_WRITE, PROT_READ | PROT_WRITE,
MAP_PRIVATE | MAP_ANONYMOUS, MAP_PRIVATE | MAP_ANONYMOUS,
-1, 0); -1, 0);
@ -511,7 +521,7 @@ unsigned long setup_arg_pages(unsigned long p, struct linux_binprm * bprm,
exit(-1); exit(-1);
} }
/* we reserve one extra page at the top of the stack as guard */ /* we reserve one extra page at the top of the stack as guard */
target_mprotect(error + size, host_page_size, PROT_NONE); target_mprotect(error + size, qemu_host_page_size, PROT_NONE);
stack_base = error + size - MAX_ARG_PAGES*TARGET_PAGE_SIZE; stack_base = error + size - MAX_ARG_PAGES*TARGET_PAGE_SIZE;
p += stack_base; p += stack_base;
@ -562,10 +572,10 @@ static void padzero(unsigned long elf_bss)
of the file may not be mapped. A better fix would be to of the file may not be mapped. A better fix would be to
patch target_mmap(), but it is more complicated as the file patch target_mmap(), but it is more complicated as the file
size must be known */ size must be known */
if (real_host_page_size < host_page_size) { if (qemu_real_host_page_size < qemu_host_page_size) {
unsigned long end_addr, end_addr1; unsigned long end_addr, end_addr1;
end_addr1 = (elf_bss + real_host_page_size - 1) & end_addr1 = (elf_bss + qemu_real_host_page_size - 1) &
~(real_host_page_size - 1); ~(qemu_real_host_page_size - 1);
end_addr = HOST_PAGE_ALIGN(elf_bss); end_addr = HOST_PAGE_ALIGN(elf_bss);
if (end_addr1 < end_addr) { if (end_addr1 < end_addr) {
mmap((void *)end_addr1, end_addr - end_addr1, mmap((void *)end_addr1, end_addr - end_addr1,
@ -574,9 +584,9 @@ static void padzero(unsigned long elf_bss)
} }
} }
nbyte = elf_bss & (host_page_size-1); nbyte = elf_bss & (qemu_host_page_size-1);
if (nbyte) { if (nbyte) {
nbyte = host_page_size - nbyte; nbyte = qemu_host_page_size - nbyte;
fpnt = (char *) elf_bss; fpnt = (char *) elf_bss;
do { do {
*fpnt++ = 0; *fpnt++ = 0;
@ -811,7 +821,7 @@ static unsigned long load_elf_interp(struct elfhdr * interp_elf_ex,
* bss page. * bss page.
*/ */
padzero(elf_bss); padzero(elf_bss);
elf_bss = TARGET_ELF_PAGESTART(elf_bss + host_page_size - 1); /* What we have mapped so far */ elf_bss = TARGET_ELF_PAGESTART(elf_bss + qemu_host_page_size - 1); /* What we have mapped so far */
/* Map the last of the bss segment */ /* Map the last of the bss segment */
if (last_bss > elf_bss) { if (last_bss > elf_bss) {
@ -1252,7 +1262,7 @@ static int load_elf_binary(struct linux_binprm * bprm, struct target_pt_regs * r
and some applications "depend" upon this behavior. and some applications "depend" upon this behavior.
Since we do not have the power to recompile these, we Since we do not have the power to recompile these, we
emulate the SVr4 behavior. Sigh. */ emulate the SVr4 behavior. Sigh. */
mapped_addr = target_mmap(0, host_page_size, PROT_READ | PROT_EXEC, mapped_addr = target_mmap(0, qemu_host_page_size, PROT_READ | PROT_EXEC,
MAP_FIXED | MAP_PRIVATE, -1, 0); MAP_FIXED | MAP_PRIVATE, -1, 0);
} }

View File

@ -28,6 +28,11 @@
#define DEBUG_LOGFILE "/tmp/qemu.log" #define DEBUG_LOGFILE "/tmp/qemu.log"
#ifdef __APPLE__
#include <crt_externs.h>
# define environ (*_NSGetEnviron())
#endif
static const char *interp_prefix = CONFIG_QEMU_PREFIX; static const char *interp_prefix = CONFIG_QEMU_PREFIX;
#if defined(__i386__) && !defined(CONFIG_STATIC) #if defined(__i386__) && !defined(CONFIG_STATIC)
@ -977,9 +982,9 @@ int main(int argc, char **argv)
} else if (!strcmp(r, "L")) { } else if (!strcmp(r, "L")) {
interp_prefix = argv[optind++]; interp_prefix = argv[optind++];
} else if (!strcmp(r, "p")) { } else if (!strcmp(r, "p")) {
host_page_size = atoi(argv[optind++]); qemu_host_page_size = atoi(argv[optind++]);
if (host_page_size == 0 || if (qemu_host_page_size == 0 ||
(host_page_size & (host_page_size - 1)) != 0) { (qemu_host_page_size & (qemu_host_page_size - 1)) != 0) {
fprintf(stderr, "page size must be a power of two\n"); fprintf(stderr, "page size must be a power of two\n");
exit(1); exit(1);
} }
@ -1006,8 +1011,8 @@ int main(int argc, char **argv)
/* Scan interp_prefix dir for replacement files. */ /* Scan interp_prefix dir for replacement files. */
init_paths(interp_prefix); init_paths(interp_prefix);
/* NOTE: we need to init the CPU at this stage to get the /* NOTE: we need to init the CPU at this stage to get
host_page_size */ qemu_host_page_size */
env = cpu_init(); env = cpu_init();
if (elf_exec(filename, argv+optind, environ, regs, info) != 0) { if (elf_exec(filename, argv+optind, environ, regs, info) != 0) {

View File

@ -53,7 +53,7 @@ int target_mprotect(unsigned long start, unsigned long len, int prot)
if (len == 0) if (len == 0)
return 0; return 0;
host_start = start & host_page_mask; host_start = start & qemu_host_page_mask;
host_end = HOST_PAGE_ALIGN(end); host_end = HOST_PAGE_ALIGN(end);
if (start > host_start) { if (start > host_start) {
/* handle host page containing start */ /* handle host page containing start */
@ -61,27 +61,27 @@ int target_mprotect(unsigned long start, unsigned long len, int prot)
for(addr = host_start; addr < start; addr += TARGET_PAGE_SIZE) { for(addr = host_start; addr < start; addr += TARGET_PAGE_SIZE) {
prot1 |= page_get_flags(addr); prot1 |= page_get_flags(addr);
} }
if (host_end == host_start + host_page_size) { if (host_end == host_start + qemu_host_page_size) {
for(addr = end; addr < host_end; addr += TARGET_PAGE_SIZE) { for(addr = end; addr < host_end; addr += TARGET_PAGE_SIZE) {
prot1 |= page_get_flags(addr); prot1 |= page_get_flags(addr);
} }
end = host_end; end = host_end;
} }
ret = mprotect((void *)host_start, host_page_size, prot1 & PAGE_BITS); ret = mprotect((void *)host_start, qemu_host_page_size, prot1 & PAGE_BITS);
if (ret != 0) if (ret != 0)
return ret; return ret;
host_start += host_page_size; host_start += qemu_host_page_size;
} }
if (end < host_end) { if (end < host_end) {
prot1 = prot; prot1 = prot;
for(addr = end; addr < host_end; addr += TARGET_PAGE_SIZE) { for(addr = end; addr < host_end; addr += TARGET_PAGE_SIZE) {
prot1 |= page_get_flags(addr); prot1 |= page_get_flags(addr);
} }
ret = mprotect((void *)(host_end - host_page_size), host_page_size, ret = mprotect((void *)(host_end - qemu_host_page_size), qemu_host_page_size,
prot1 & PAGE_BITS); prot1 & PAGE_BITS);
if (ret != 0) if (ret != 0)
return ret; return ret;
host_end -= host_page_size; host_end -= qemu_host_page_size;
} }
/* handle the pages in the middle */ /* handle the pages in the middle */
@ -102,7 +102,7 @@ int mmap_frag(unsigned long host_start,
unsigned long host_end, ret, addr; unsigned long host_end, ret, addr;
int prot1, prot_new; int prot1, prot_new;
host_end = host_start + host_page_size; host_end = host_start + qemu_host_page_size;
/* get the protection of the target pages outside the mapping */ /* get the protection of the target pages outside the mapping */
prot1 = 0; prot1 = 0;
@ -113,7 +113,7 @@ int mmap_frag(unsigned long host_start,
if (prot1 == 0) { if (prot1 == 0) {
/* no page was there, so we allocate one */ /* no page was there, so we allocate one */
ret = (long)mmap((void *)host_start, host_page_size, prot, ret = (long)mmap((void *)host_start, qemu_host_page_size, prot,
flags | MAP_ANONYMOUS, -1, 0); flags | MAP_ANONYMOUS, -1, 0);
if (ret == -1) if (ret == -1)
return ret; return ret;
@ -130,18 +130,18 @@ int mmap_frag(unsigned long host_start,
/* adjust protection to be able to read */ /* adjust protection to be able to read */
if (!(prot1 & PROT_WRITE)) if (!(prot1 & PROT_WRITE))
mprotect((void *)host_start, host_page_size, prot1 | PROT_WRITE); mprotect((void *)host_start, qemu_host_page_size, prot1 | PROT_WRITE);
/* read the corresponding file data */ /* read the corresponding file data */
pread(fd, (void *)start, end - start, offset); pread(fd, (void *)start, end - start, offset);
/* put final protection */ /* put final protection */
if (prot_new != (prot1 | PROT_WRITE)) if (prot_new != (prot1 | PROT_WRITE))
mprotect((void *)host_start, host_page_size, prot_new); mprotect((void *)host_start, qemu_host_page_size, prot_new);
} else { } else {
/* just update the protection */ /* just update the protection */
if (prot_new != prot1) { if (prot_new != prot1) {
mprotect((void *)host_start, host_page_size, prot_new); mprotect((void *)host_start, qemu_host_page_size, prot_new);
} }
} }
return 0; return 0;
@ -188,7 +188,7 @@ long target_mmap(unsigned long start, unsigned long len, int prot,
len = TARGET_PAGE_ALIGN(len); len = TARGET_PAGE_ALIGN(len);
if (len == 0) if (len == 0)
return start; return start;
host_start = start & host_page_mask; host_start = start & qemu_host_page_mask;
if (!(flags & MAP_FIXED)) { if (!(flags & MAP_FIXED)) {
#if defined(__alpha__) || defined(__sparc__) || defined(__x86_64__) #if defined(__alpha__) || defined(__sparc__) || defined(__x86_64__)
@ -198,10 +198,10 @@ long target_mmap(unsigned long start, unsigned long len, int prot,
last_start += HOST_PAGE_ALIGN(len); last_start += HOST_PAGE_ALIGN(len);
} }
#endif #endif
if (host_page_size != real_host_page_size) { if (qemu_host_page_size != qemu_real_host_page_size) {
/* NOTE: this code is only for debugging with '-p' option */ /* NOTE: this code is only for debugging with '-p' option */
/* reserve a memory area */ /* reserve a memory area */
host_len = HOST_PAGE_ALIGN(len) + host_page_size - TARGET_PAGE_SIZE; host_len = HOST_PAGE_ALIGN(len) + qemu_host_page_size - TARGET_PAGE_SIZE;
host_start = (long)mmap((void *)host_start, host_len, PROT_NONE, host_start = (long)mmap((void *)host_start, host_len, PROT_NONE,
MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
if (host_start == -1) if (host_start == -1)
@ -217,7 +217,7 @@ long target_mmap(unsigned long start, unsigned long len, int prot,
flags |= MAP_FIXED; flags |= MAP_FIXED;
} else { } else {
/* if not fixed, no need to do anything */ /* if not fixed, no need to do anything */
host_offset = offset & host_page_mask; host_offset = offset & qemu_host_page_mask;
host_len = len + offset - host_offset; host_len = len + offset - host_offset;
start = (long)mmap((void *)host_start, host_len, start = (long)mmap((void *)host_start, host_len,
prot, flags, fd, host_offset); prot, flags, fd, host_offset);
@ -238,7 +238,7 @@ long target_mmap(unsigned long start, unsigned long len, int prot,
/* worst case: we cannot map the file because the offset is not /* worst case: we cannot map the file because the offset is not
aligned, so we read it */ aligned, so we read it */
if (!(flags & MAP_ANONYMOUS) && if (!(flags & MAP_ANONYMOUS) &&
(offset & ~host_page_mask) != (start & ~host_page_mask)) { (offset & ~qemu_host_page_mask) != (start & ~qemu_host_page_mask)) {
/* msync() won't work here, so we return an error if write is /* msync() won't work here, so we return an error if write is
possible while it is a shared mapping */ possible while it is a shared mapping */
if ((flags & MAP_TYPE) == MAP_SHARED && if ((flags & MAP_TYPE) == MAP_SHARED &&
@ -260,7 +260,7 @@ long target_mmap(unsigned long start, unsigned long len, int prot,
/* handle the start of the mapping */ /* handle the start of the mapping */
if (start > host_start) { if (start > host_start) {
if (host_end == host_start + host_page_size) { if (host_end == host_start + qemu_host_page_size) {
/* one single host page */ /* one single host page */
ret = mmap_frag(host_start, start, end, ret = mmap_frag(host_start, start, end,
prot, flags, fd, offset); prot, flags, fd, offset);
@ -268,21 +268,21 @@ long target_mmap(unsigned long start, unsigned long len, int prot,
return ret; return ret;
goto the_end1; goto the_end1;
} }
ret = mmap_frag(host_start, start, host_start + host_page_size, ret = mmap_frag(host_start, start, host_start + qemu_host_page_size,
prot, flags, fd, offset); prot, flags, fd, offset);
if (ret == -1) if (ret == -1)
return ret; return ret;
host_start += host_page_size; host_start += qemu_host_page_size;
} }
/* handle the end of the mapping */ /* handle the end of the mapping */
if (end < host_end) { if (end < host_end) {
ret = mmap_frag(host_end - host_page_size, ret = mmap_frag(host_end - qemu_host_page_size,
host_end - host_page_size, host_end, host_end - qemu_host_page_size, host_end,
prot, flags, fd, prot, flags, fd,
offset + host_end - host_page_size - start); offset + host_end - qemu_host_page_size - start);
if (ret == -1) if (ret == -1)
return ret; return ret;
host_end -= host_page_size; host_end -= qemu_host_page_size;
} }
/* map the middle (easier) */ /* map the middle (easier) */
@ -322,7 +322,7 @@ int target_munmap(unsigned long start, unsigned long len)
if (len == 0) if (len == 0)
return -EINVAL; return -EINVAL;
end = start + len; end = start + len;
host_start = start & host_page_mask; host_start = start & qemu_host_page_mask;
host_end = HOST_PAGE_ALIGN(end); host_end = HOST_PAGE_ALIGN(end);
if (start > host_start) { if (start > host_start) {
@ -331,14 +331,14 @@ int target_munmap(unsigned long start, unsigned long len)
for(addr = host_start; addr < start; addr += TARGET_PAGE_SIZE) { for(addr = host_start; addr < start; addr += TARGET_PAGE_SIZE) {
prot |= page_get_flags(addr); prot |= page_get_flags(addr);
} }
if (host_end == host_start + host_page_size) { if (host_end == host_start + qemu_host_page_size) {
for(addr = end; addr < host_end; addr += TARGET_PAGE_SIZE) { for(addr = end; addr < host_end; addr += TARGET_PAGE_SIZE) {
prot |= page_get_flags(addr); prot |= page_get_flags(addr);
} }
end = host_end; end = host_end;
} }
if (prot != 0) if (prot != 0)
host_start += host_page_size; host_start += qemu_host_page_size;
} }
if (end < host_end) { if (end < host_end) {
prot = 0; prot = 0;
@ -346,7 +346,7 @@ int target_munmap(unsigned long start, unsigned long len)
prot |= page_get_flags(addr); prot |= page_get_flags(addr);
} }
if (prot != 0) if (prot != 0)
host_end -= host_page_size; host_end -= qemu_host_page_size;
} }
/* unmap what we can */ /* unmap what we can */
@ -391,7 +391,7 @@ int target_msync(unsigned long start, unsigned long len, int flags)
if (end == start) if (end == start)
return 0; return 0;
start &= host_page_mask; start &= qemu_host_page_mask;
return msync((void *)start, end - start, flags); return msync((void *)start, end - start, flags);
} }

2
oss.c
View File

@ -23,7 +23,7 @@
*/ */
#include "vl.h" #include "vl.h"
#ifndef _WIN32 #if !defined(_WIN32) && !defined(__APPLE__)
#include <ctype.h> #include <ctype.h>
#include <fcntl.h> #include <fcntl.h>
#include <errno.h> #include <errno.h>

View File

@ -498,7 +498,7 @@ static inline void helper_fstt(CPU86_LDouble f, uint8_t *ptr)
#define FPUC_EM 0x3f #define FPUC_EM 0x3f
const CPU86_LDouble f15rk[7]; extern const CPU86_LDouble f15rk[7];
void helper_fldt_ST0_A0(void); void helper_fldt_ST0_A0(void);
void helper_fstt_ST0_A0(void); void helper_fstt_ST0_A0(void);
@ -528,9 +528,9 @@ void helper_frstor(uint8_t *ptr, int data32);
void restore_native_fp_state(CPUState *env); void restore_native_fp_state(CPUState *env);
void save_native_fp_state(CPUState *env); void save_native_fp_state(CPUState *env);
const uint8_t parity_table[256]; extern const uint8_t parity_table[256];
const uint8_t rclw_table[32]; extern const uint8_t rclw_table[32];
const uint8_t rclb_table[32]; extern const uint8_t rclb_table[32];
static inline uint32_t compute_eflags(void) static inline uint32_t compute_eflags(void)
{ {

View File

@ -1955,24 +1955,6 @@ void OPPROTO op_fldcw_A0(void)
int rnd_type; int rnd_type;
env->fpuc = lduw((void *)A0); env->fpuc = lduw((void *)A0);
/* set rounding mode */ /* set rounding mode */
#ifdef _BSD
switch(env->fpuc & RC_MASK) {
default:
case RC_NEAR:
rnd_type = FP_RN;
break;
case RC_DOWN:
rnd_type = FP_RM;
break;
case RC_UP:
rnd_type = FP_RP;
break;
case RC_CHOP:
rnd_type = FP_RZ;
break;
}
fpsetround(rnd_type);
#else
switch(env->fpuc & RC_MASK) { switch(env->fpuc & RC_MASK) {
default: default:
case RC_NEAR: case RC_NEAR:
@ -1989,7 +1971,6 @@ void OPPROTO op_fldcw_A0(void)
break; break;
} }
fesetround(rnd_type); fesetround(rnd_type);
#endif
} }
void OPPROTO op_fclex(void) void OPPROTO op_fclex(void)

12
vl.c
View File

@ -40,7 +40,9 @@
#include <sys/socket.h> #include <sys/socket.h>
#ifdef _BSD #ifdef _BSD
#include <sys/stat.h> #include <sys/stat.h>
#ifndef __APPLE__
#include <libutil.h> #include <libutil.h>
#endif
#else #else
#include <linux/if.h> #include <linux/if.h>
#include <linux/if_tun.h> #include <linux/if_tun.h>
@ -63,6 +65,7 @@
#endif #endif
#ifdef CONFIG_SDL #ifdef CONFIG_SDL
#include <SDL/SDL.h>
#if defined(__linux__) #if defined(__linux__)
/* SDL use the pthreads and they modify sigaction. We don't /* SDL use the pthreads and they modify sigaction. We don't
want that. */ want that. */
@ -909,6 +912,7 @@ static void init_timers(void)
the emulated kernel requested a too high timer frequency */ the emulated kernel requested a too high timer frequency */
getitimer(ITIMER_REAL, &itv); getitimer(ITIMER_REAL, &itv);
#if defined(__linux__)
if (itv.it_interval.tv_usec > 1000) { if (itv.it_interval.tv_usec > 1000) {
/* try to use /dev/rtc to have a faster timer */ /* try to use /dev/rtc to have a faster timer */
if (start_rtc_timer() < 0) if (start_rtc_timer() < 0)
@ -924,7 +928,9 @@ static void init_timers(void)
sigaction(SIGIO, &act, NULL); sigaction(SIGIO, &act, NULL);
fcntl(rtc_fd, F_SETFL, O_ASYNC); fcntl(rtc_fd, F_SETFL, O_ASYNC);
fcntl(rtc_fd, F_SETOWN, getpid()); fcntl(rtc_fd, F_SETOWN, getpid());
} else { } else
#endif /* defined(__linux__) */
{
use_itimer: use_itimer:
pit_min_timer_count = ((uint64_t)itv.it_interval.tv_usec * pit_min_timer_count = ((uint64_t)itv.it_interval.tv_usec *
PIT_FREQ) / 1000000; PIT_FREQ) / 1000000;
@ -2622,8 +2628,8 @@ int main(int argc, char **argv)
#ifdef CONFIG_SOFTMMU #ifdef CONFIG_SOFTMMU
#ifdef _BSD #ifdef _BSD
/* mallocs are always aligned on BSD. */ /* mallocs are always aligned on BSD. valloc is better for correctness */
phys_ram_base = malloc(phys_ram_size); phys_ram_base = valloc(phys_ram_size);
#else #else
phys_ram_base = memalign(TARGET_PAGE_SIZE, phys_ram_size); phys_ram_base = memalign(TARGET_PAGE_SIZE, phys_ram_size);
#endif #endif