[27270] trunk/dports/emulators

source_changes at macosforge.org source_changes at macosforge.org
Thu Jul 26 09:36:57 PDT 2007


Revision: 27270
          http://trac.macosforge.org/projects/macports/changeset/27270
Author:   mww at macports.org
Date:     2007-07-26 09:36:57 -0700 (Thu, 26 Jul 2007)

Log Message:
-----------
new port emulators/qemu-usermode (usermode only qemu)

Added Paths:
-----------
    trunk/dports/emulators/qemu-usermode/
    trunk/dports/emulators/qemu-usermode/files/
    trunk/dports/emulators/qemu-usermode/files/patch-90_security
    trunk/dports/emulators/qemu-usermode/files/patch-configure
    trunk/dports/emulators/qemu-usermode/files/patch-i386
    trunk/dports/emulators/qemu-usermode/files/patch-q-i386
    trunk/dports/emulators/qemu-usermode/files/sparc-fp.patch

Added: trunk/dports/emulators/qemu-usermode/files/patch-90_security
===================================================================
--- trunk/dports/emulators/qemu-usermode/files/patch-90_security	                        (rev 0)
+++ trunk/dports/emulators/qemu-usermode/files/patch-90_security	2007-07-26 16:36:57 UTC (rev 27270)
@@ -0,0 +1,374 @@
+Index: qemu-0.8.2/hw/cirrus_vga.c
+===================================================================
+--- qemu-0.8.2.orig/hw/cirrus_vga.c	2007-04-20 06:05:59.000000000 +0300
++++ qemu-0.8.2/hw/cirrus_vga.c	2007-04-20 06:05:59.000000000 +0300
+@@ -217,6 +217,20 @@
+ #define CIRRUS_HOOK_NOT_HANDLED 0
+ #define CIRRUS_HOOK_HANDLED 1
+ 
++#define BLTUNSAFE(s) \
++    ( \
++        ( /* check dst is within bounds */ \
++            (s)->cirrus_blt_height * (s)->cirrus_blt_dstpitch \
++                + ((s)->cirrus_blt_dstaddr & (s)->cirrus_addr_mask) > \
++                    (s)->vram_size \
++        ) || \
++        ( /* check src is within bounds */ \
++            (s)->cirrus_blt_height * (s)->cirrus_blt_srcpitch \
++                + ((s)->cirrus_blt_srcaddr & (s)->cirrus_addr_mask) > \
++                    (s)->vram_size \
++        ) \
++    )
++
+ struct CirrusVGAState;
+ typedef void (*cirrus_bitblt_rop_t) (struct CirrusVGAState *s,
+                                      uint8_t * dst, const uint8_t * src,
+@@ -589,7 +603,7 @@ static void cirrus_invalidate_region(Cir
+ 
+     for (y = 0; y < lines; y++) {
+ 	off_cur = off_begin;
+-	off_cur_end = off_cur + bytesperline;
++	off_cur_end = (off_cur + bytesperline) & s->cirrus_addr_mask;
+ 	off_cur &= TARGET_PAGE_MASK;
+ 	while (off_cur < off_cur_end) {
+ 	    cpu_physical_memory_set_dirty(s->vram_offset + off_cur);
+@@ -604,7 +618,11 @@ static int cirrus_bitblt_common_patternc
+ {
+     uint8_t *dst;
+ 
+-    dst = s->vram_ptr + s->cirrus_blt_dstaddr;
++    dst = s->vram_ptr + (s->cirrus_blt_dstaddr & s->cirrus_addr_mask);
++    
++    if (BLTUNSAFE(s))
++        return 0;
++
+     (*s->cirrus_rop) (s, dst, src,
+                       s->cirrus_blt_dstpitch, 0, 
+                       s->cirrus_blt_width, s->cirrus_blt_height);
+@@ -620,8 +638,11 @@ static int cirrus_bitblt_solidfill(Cirru
+ {
+     cirrus_fill_t rop_func;
+ 
++    if (BLTUNSAFE(s))
++        return 0;
++
+     rop_func = cirrus_fill[rop_to_index[blt_rop]][s->cirrus_blt_pixelwidth - 1];
+-    rop_func(s, s->vram_ptr + s->cirrus_blt_dstaddr, 
++    rop_func(s, s->vram_ptr + (s->cirrus_blt_dstaddr & s->cirrus_addr_mask), 
+              s->cirrus_blt_dstpitch,
+              s->cirrus_blt_width, s->cirrus_blt_height);
+     cirrus_invalidate_region(s, s->cirrus_blt_dstaddr,
+@@ -640,8 +661,8 @@ static int cirrus_bitblt_solidfill(Cirru
+ static int cirrus_bitblt_videotovideo_patterncopy(CirrusVGAState * s)
+ {
+     return cirrus_bitblt_common_patterncopy(s,
+-					    s->vram_ptr + 
+-                                            (s->cirrus_blt_srcaddr & ~7));
++					    s->vram_ptr + ((s->cirrus_blt_srcaddr & ~7) & 
++                        s->cirrus_addr_mask));
+ }
+ 
+ static void cirrus_do_copy(CirrusVGAState *s, int dst, int src, int w, int h)
+@@ -691,8 +712,10 @@ static void cirrus_do_copy(CirrusVGAStat
+     if (notify)
+ 	video_hw_update();
+ 
+-    (*s->cirrus_rop) (s, s->vram_ptr + s->cirrus_blt_dstaddr,
+-		      s->vram_ptr + s->cirrus_blt_srcaddr,
++    (*s->cirrus_rop) (s, s->vram_ptr + 
++                (s->cirrus_blt_dstaddr & s->cirrus_addr_mask),
++		      s->vram_ptr + 
++                (s->cirrus_blt_srcaddr & s->cirrus_addr_mask),
+ 		      s->cirrus_blt_dstpitch, s->cirrus_blt_srcpitch,
+ 		      s->cirrus_blt_width, s->cirrus_blt_height);
+ 
+@@ -718,8 +741,14 @@ static int cirrus_bitblt_videotovideo_co
+ 		       s->cirrus_blt_srcaddr - s->start_addr,
+ 		       s->cirrus_blt_width, s->cirrus_blt_height);
+     } else {
+-	(*s->cirrus_rop) (s, s->vram_ptr + s->cirrus_blt_dstaddr,
+-			  s->vram_ptr + s->cirrus_blt_srcaddr,
++
++    if (BLTUNSAFE(s))
++        return 0;
++
++	(*s->cirrus_rop) (s, s->vram_ptr + 
++                (s->cirrus_blt_dstaddr & s->cirrus_addr_mask),
++			  s->vram_ptr + 
++                (s->cirrus_blt_srcaddr & s->cirrus_addr_mask),
+ 			  s->cirrus_blt_dstpitch, s->cirrus_blt_srcpitch,
+ 			  s->cirrus_blt_width, s->cirrus_blt_height);
+ 
+@@ -751,8 +780,9 @@ static void cirrus_bitblt_cputovideo_nex
+         } else {
+             /* at least one scan line */
+             do {
+-                (*s->cirrus_rop)(s, s->vram_ptr + s->cirrus_blt_dstaddr,
+-                                 s->cirrus_bltbuf, 0, 0, s->cirrus_blt_width, 1);
++                (*s->cirrus_rop)(s, s->vram_ptr + 
++                    (s->cirrus_blt_dstaddr & s->cirrus_addr_mask),
++                        s->cirrus_bltbuf, 0, 0, s->cirrus_blt_width, 1);
+                 cirrus_invalidate_region(s, s->cirrus_blt_dstaddr, 0,
+                                          s->cirrus_blt_width, 1);
+                 s->cirrus_blt_dstaddr += s->cirrus_blt_dstpitch;
+@@ -1852,7 +1882,7 @@ static void cirrus_mem_writeb_mode4and5_
+     unsigned val = mem_value;
+     uint8_t *dst;
+ 
+-    dst = s->vram_ptr + offset;
++    dst = s->vram_ptr + (offset &= s->cirrus_addr_mask);
+     for (x = 0; x < 8; x++) {
+ 	if (val & 0x80) {
+ 	    *dst = s->cirrus_shadow_gr1;
+@@ -1875,7 +1905,7 @@ static void cirrus_mem_writeb_mode4and5_
+     unsigned val = mem_value;
+     uint8_t *dst;
+ 
+-    dst = s->vram_ptr + offset;
++    dst = s->vram_ptr + (offset &= s->cirrus_addr_mask);
+     for (x = 0; x < 8; x++) {
+ 	if (val & 0x80) {
+ 	    *dst = s->cirrus_shadow_gr1;
+Index: qemu-0.8.2/hw/cirrus_vga_rop.h
+===================================================================
+--- qemu-0.8.2.orig/hw/cirrus_vga_rop.h	2006-07-22 20:23:34.000000000 +0300
++++ qemu-0.8.2/hw/cirrus_vga_rop.h	2007-04-20 06:05:59.000000000 +0300
+@@ -31,6 +31,12 @@ glue(cirrus_bitblt_rop_fwd_, ROP_NAME)(C
+     int x,y;
+     dstpitch -= bltwidth;
+     srcpitch -= bltwidth;
++
++    if (dstpitch < 0 || srcpitch < 0) {
++        /* is 0 valid? srcpitch == 0 could be useful */
++        return;
++    }
++
+     for (y = 0; y < bltheight; y++) {
+         for (x = 0; x < bltwidth; x++) {
+             ROP_OP(*dst, *src);
+Index: qemu-0.8.2/hw/dma.c
+===================================================================
+--- qemu-0.8.2.orig/hw/dma.c	2006-07-22 20:23:34.000000000 +0300
++++ qemu-0.8.2/hw/dma.c	2007-04-20 06:05:59.000000000 +0300
+@@ -340,9 +340,11 @@ static void channel_run (int ncont, int 
+ #endif
+ 
+     r = dma_controllers[ncont].regs + ichan;
+-    n = r->transfer_handler (r->opaque, ichan + (ncont << 2),
+-                             r->now[COUNT], (r->base[COUNT] + 1) << ncont);
+-    r->now[COUNT] = n;
++    if (r->transfer_handler) {
++        n = r->transfer_handler (r->opaque, ichan + (ncont << 2),
++                                 r->now[COUNT], (r->base[COUNT] + 1) << ncont);
++        r->now[COUNT] = n;
++    }
+     ldebug ("dma_pos %d size %d\n", n, (r->base[COUNT] + 1) << ncont);
+ }
+ 
+Index: qemu-0.8.2/hw/fdc.c
+===================================================================
+--- qemu-0.8.2.orig/hw/fdc.c	2006-07-22 20:23:34.000000000 +0300
++++ qemu-0.8.2/hw/fdc.c	2007-04-20 06:05:59.000000000 +0300
+@@ -1110,8 +1110,13 @@ static uint32_t fdctrl_read_data (fdctrl
+             len = fdctrl->data_len - fdctrl->data_pos;
+             if (len > FD_SECTOR_LEN)
+                 len = FD_SECTOR_LEN;
+-            bdrv_read(cur_drv->bs, fd_sector(cur_drv),
+-                      fdctrl->fifo, len);
++            if (cur_drv->bs) {
++                bdrv_read(cur_drv->bs, fd_sector(cur_drv),
++                          fdctrl->fifo, len);
++            } else {
++                FLOPPY_ERROR("can't read data from drive\n");
++                return 0;
++            }
+         }
+     }
+     retval = fdctrl->fifo[pos];
+Index: qemu-0.8.2/hw/ne2000.c
+===================================================================
+--- qemu-0.8.2.orig/hw/ne2000.c	2007-04-20 06:05:59.000000000 +0300
++++ qemu-0.8.2/hw/ne2000.c	2007-04-20 06:05:59.000000000 +0300
+@@ -230,7 +230,7 @@ static void ne2000_receive(void *opaque,
+ {
+     NE2000State *s = opaque;
+     uint8_t *p;
+-    int total_len, next, avail, len, index, mcast_idx;
++    unsigned int total_len, next, avail, len, index, mcast_idx;
+     uint8_t buf1[60];
+     static const uint8_t broadcast_macaddr[6] = 
+         { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
+@@ -299,7 +299,11 @@ static void ne2000_receive(void *opaque,
+ 
+     /* write packet data */
+     while (size > 0) {
+-        avail = s->stop - index;
++        /* taviso: this can wrap, so check its okay. */
++        if (index <= s->stop)
++            avail = s->stop - index;
++        else
++            avail = 0;
+         len = size;
+         if (len > avail)
+             len = avail;
+Index: qemu-0.8.2/hw/pc.c
+===================================================================
+--- qemu-0.8.2.orig/hw/pc.c	2007-04-20 06:05:58.000000000 +0300
++++ qemu-0.8.2/hw/pc.c	2007-04-20 06:05:59.000000000 +0300
+@@ -312,7 +312,8 @@ void bochs_bios_write(void *opaque, uint
+     case 0x400:
+     case 0x401:
+         fprintf(stderr, "BIOS panic at rombios.c, line %d\n", val);
+-        exit(1);
++        /* according to documentation, these can be safely ignored */
++        break;
+     case 0x402:
+     case 0x403:
+ #ifdef DEBUG_BIOS
+@@ -335,8 +336,9 @@ void bochs_bios_write(void *opaque, uint
+         /* LGPL'ed VGA BIOS messages */
+     case 0x501:
+     case 0x502:
++        /* according to documentation, these can be safely ignored */
+         fprintf(stderr, "VGA BIOS panic, line %d\n", val);
+-        exit(1);
++        break;
+     case 0x500:
+     case 0x503:
+ #ifdef DEBUG_BIOS
+Index: qemu-0.8.2/hw/sb16.c
+===================================================================
+--- qemu-0.8.2.orig/hw/sb16.c	2006-07-22 20:23:34.000000000 +0300
++++ qemu-0.8.2/hw/sb16.c	2007-04-20 06:05:59.000000000 +0300
+@@ -1235,8 +1235,10 @@ static int SB_read_DMA (void *opaque, in
+             s->block_size);
+ #endif
+ 
+-    while (s->left_till_irq <= 0) {
+-        s->left_till_irq = s->block_size + s->left_till_irq;
++    if (s->block_size) {
++        while (s->left_till_irq <= 0) {
++            s->left_till_irq = s->block_size + s->left_till_irq;
++        }
+     }
+ 
+     return dma_pos;
+Index: qemu-0.8.2/slirp/slirp.c
+===================================================================
+--- qemu-0.8.2.orig/slirp/slirp.c	2006-07-22 20:23:34.000000000 +0300
++++ qemu-0.8.2/slirp/slirp.c	2007-04-20 06:05:59.000000000 +0300
+@@ -611,6 +611,10 @@ void slirp_input(const uint8_t *pkt, int
+         if (!m)
+             return;
+         /* Note: we add to align the IP header */
++        /* taviso: large values in ne2k TCNT register may exceed msize on transmit */
++        if (M_FREEROOM(m) < pkt_len + 2) {
++            m_inc(m, pkt_len + 2);
++        }
+         m->m_len = pkt_len + 2;
+         memcpy(m->m_data + 2, pkt, pkt_len);
+ 
+Index: qemu-0.8.2/target-i386/translate.c
+===================================================================
+--- qemu-0.8.2.orig/target-i386/translate.c	2006-07-22 20:23:34.000000000 +0300
++++ qemu-0.8.2/target-i386/translate.c	2007-04-20 06:05:59.000000000 +0300
+@@ -5244,7 +5244,12 @@ static target_ulong disas_insn(DisasCont
+         if (CODE64(s))
+             goto illegal_op;
+         val = ldub_code(s->pc++);
+-        gen_op_aam(val);
++        /* taviso: operand can be zero */
++        if (val) {
++            gen_op_aam(val);
++        } else {
++            gen_exception(s, EXCP00_DIVZ, s->pc - s->cs_base);
++        }
+         s->cc_op = CC_OP_LOGICB;
+         break;
+     case 0xd5: /* aad */
+@@ -5292,6 +5297,7 @@ static target_ulong disas_insn(DisasCont
+         gen_jmp_im(pc_start - s->cs_base);
+         gen_op_into(s->pc - pc_start);
+         break;
++#ifdef WANT_ICEBP
+     case 0xf1: /* icebp (undocumented, exits to external debugger) */
+ #if 1
+         gen_debug(s, pc_start - s->cs_base);
+@@ -5301,6 +5307,7 @@ static target_ulong disas_insn(DisasCont
+         cpu_set_log(CPU_LOG_INT | CPU_LOG_TB_IN_ASM);
+ #endif
+         break;
++#endif /* icebp */
+     case 0xfa: /* cli */
+         if (!s->vm86) {
+             if (s->cpl <= s->iopl) {
+Index: qemu-0.8.2/vl.c
+===================================================================
+--- qemu-0.8.2.orig/vl.c	2007-04-20 06:05:59.000000000 +0300
++++ qemu-0.8.2/vl.c	2007-04-20 06:05:59.000000000 +0300
+@@ -3139,8 +3139,8 @@ typedef struct NetSocketState {
+     VLANClientState *vc;
+     int fd;
+     int state; /* 0 = getting length, 1 = getting data */
+-    int index;
+-    int packet_len;
++    unsigned int index;
++    unsigned int packet_len;
+     uint8_t buf[4096];
+     struct sockaddr_in dgram_dst; /* contains inet host and port destination iff connectionless (SOCK_DGRAM) */
+ } NetSocketState;
+@@ -3171,7 +3171,8 @@ static void net_socket_receive_dgram(voi
+ static void net_socket_send(void *opaque)
+ {
+     NetSocketState *s = opaque;
+-    int l, size, err;
++    int size, err;
++    unsigned l;
+     uint8_t buf1[4096];
+     const uint8_t *buf;
+ 
+@@ -3210,7 +3211,15 @@ static void net_socket_send(void *opaque
+             l = s->packet_len - s->index;
+             if (l > size)
+                 l = size;
+-            memcpy(s->buf + s->index, buf, l);
++            if (s->index + l <= sizeof(s->buf)) {
++                memcpy(s->buf + s->index, buf, l);
++            } else {
++                fprintf(stderr, "serious error: oversized packet received,"
++                    "connection terminated.\n");
++                s->state = 0;
++                goto eoc;
++            }
++
+             s->index += l;
+             buf += l;
+             size -= l;
+Index: qemu/block.c
+@@ -539,8 +539,15 @@
+         return -ENOMEDIUM;
+     if (bs->read_only)
+         return -EACCES;
++    if (sector_num < 0)
++	return -EACCES;
+     if (sector_num == 0 && bs->boot_sector_enabled && nb_sectors > 0) {
+         memcpy(bs->boot_sector_data, buf, 512);   
++    }
++    {
++	unsigned int ns = sector_num * 512;
++	if (ns < 0)
++	    return -EACCES;
+     }
+     if (drv->bdrv_pwrite) {
+         int ret, len;
+Index: qemu/hw/i8259.c
+@@ -302,7 +302,8 @@
+             s->init4 = val & 1;
+             s->single_mode = val & 2;
+             if (val & 0x08)
+-                hw_error("level sensitive irq not supported");
++                /* hw_error("level sensitive irq not supported"); */
++		return;
+         } else if (val & 0x08) {
+             if (val & 0x04)
+                 s->poll = 1;

Added: trunk/dports/emulators/qemu-usermode/files/patch-configure
===================================================================
--- trunk/dports/emulators/qemu-usermode/files/patch-configure	                        (rev 0)
+++ trunk/dports/emulators/qemu-usermode/files/patch-configure	2007-07-26 16:36:57 UTC (rev 27270)
@@ -0,0 +1,11 @@
+--- configure	2007-02-06 00:01:54.000000000 +0100
++++ configure	2007-07-25 20:03:03.000000000 +0200
+@@ -236,6 +236,8 @@
+   ;;
+   --enable-cocoa) cocoa="yes" ; coreaudio="yes" ; sdl="no"
+   ;;
++  --disable-cocoa) cocoa="no" ; coreaudio="no" ; sdl="no"
++  ;;
+   --disable-gfx-check) check_gfx="no"
+   ;;
+   --disable-gcc-check) check_gcc="no"

Added: trunk/dports/emulators/qemu-usermode/files/patch-i386
===================================================================
--- trunk/dports/emulators/qemu-usermode/files/patch-i386	                        (rev 0)
+++ trunk/dports/emulators/qemu-usermode/files/patch-i386	2007-07-26 16:36:57 UTC (rev 27270)
@@ -0,0 +1,859 @@
+diff -u -r dyngen-exec.h dyngen-exec.h
+--- dyngen-exec.h	2006-07-22 19:23:34.000000000 +0200
++++ dyngen-exec.h	2007-07-25 18:16:29.000000000 +0200
+@@ -238,12 +238,19 @@
+ #endif
+ 
+ #ifdef __i386__
+-#define EXIT_TB() asm volatile ("ret")
+-#define GOTO_LABEL_PARAM(n) asm volatile ("jmp " ASM_NAME(__op_gen_label) #n)
++/* Dyngen will replace hlt instructions with a ret instruction.  Inserting a
++   ret directly would confuse dyngen.  */
++#define EXIT_TB() asm volatile ("hlt")
++/* Dyngen will replace cli with 0x9e (jmp). 
++   We generate the offset manually.  */
++#define GOTO_LABEL_PARAM(n) \
++  asm volatile ("cli;.long " ASM_NAME(__op_gen_label) #n " - 1f;1:")
+ #endif
+ #ifdef __x86_64__
+-#define EXIT_TB() asm volatile ("ret")
+-#define GOTO_LABEL_PARAM(n) asm volatile ("jmp " ASM_NAME(__op_gen_label) #n)
++/* The same as i386.  */
++#define EXIT_TB() asm volatile ("hlt")
++#define GOTO_LABEL_PARAM(n) \
++  asm volatile ("cli;.long " ASM_NAME(__op_gen_label) #n " - 1f;1:")
+ #endif
+ #ifdef __powerpc__
+ #define EXIT_TB() asm volatile ("blr")
+Only in qemu-0.8.2.new: dyngen-exec.h.orig
+Only in qemu-0.8.2.new: dyngen-exec.h.rej
+diff -u -r dyngen.c dyngen.c
+--- dyngen.c	2006-07-22 19:23:34.000000000 +0200
++++ dyngen.c	2007-07-25 18:16:29.000000000 +0200
+@@ -32,6 +32,8 @@
+ 
+ #include "config-host.h"
+ 
++//#define DEBUG_OP
++
+ /* NOTE: we test CONFIG_WIN32 instead of _WIN32 to enabled cross
+    compilation */
+ #if defined(CONFIG_WIN32)
+@@ -1343,6 +1345,644 @@
+ #endif
+ 
+ 
++#if defined(HOST_I386) || defined(HOST_X86_64)
++
++/* This byte is the first byte of an instruction.  */
++#define FLAG_INSN     (1 << 0)
++/* This byte has been processed as part of an instruction.  */
++#define FLAG_SCANNED  (1 << 1)
++/* This instruction is a return instruction.  Gcc cometimes generates prefix
++   bytes, so may be more than one byte long.  */
++#define FLAG_RET      (1 << 2)
++/* This is either the target of a jump, or the preceeding instruction uses
++   a pc-relative offset.  */
++#define FLAG_TARGET   (1 << 3)
++/* This is a magic instruction that needs fixing up.  */
++#define FLAG_EXIT     (1 << 4)
++#define MAX_EXITS     5
++
++static void
++bad_opcode(const char *name, uint32_t op)
++{
++    error("Unsupported opcode %0*x in %s", (op > 0xff) ? 4 : 2, op, name);
++}
++
++/* Mark len bytes as scanned,  Returns insn_size + len.  Reports an error
++   if these bytes have already been scanned.  */
++static int
++eat_bytes(const char *name, char *flags, int insn, int insn_size, int len)
++{
++    while (len > 0) {
++        /* This should never occur in sane code.  */
++        if (flags[insn + insn_size] & FLAG_SCANNED)
++            error ("Overlapping instructions in %s", name);
++        flags[insn + insn_size] |= FLAG_SCANNED;
++        insn_size++;
++        len--;
++    }
++    return insn_size;
++}
++
++static void
++trace_i386_insn (const char *name, uint8_t *start_p, char *flags, int insn,
++                 int len)
++{
++    uint8_t *ptr;
++    uint8_t op;
++    int modrm;
++    int is_prefix;
++    int op_size;
++    int addr_size;
++    int insn_size;
++    int is_ret;
++    int is_condjmp;
++    int is_jmp;
++    int is_exit;
++    int is_pcrel;
++    int immed;
++    int seen_rexw;
++    int32_t disp;
++
++    ptr = start_p + insn;
++    /* nonzero if this insn has a ModR/M byte.  */
++    modrm = 1;
++    /* The size of the immediate value in this instruction.  */
++    immed = 0;
++    /* The operand size.  */
++    op_size = 4;
++    /* The address size */
++    addr_size = 4;
++    /* The total length of this instruction.  */
++    insn_size = 0;
++    is_prefix = 1;
++    is_ret = 0;
++    is_condjmp = 0;
++    is_jmp = 0;
++    is_exit = 0;
++    seen_rexw = 0;
++    is_pcrel = 0;
++
++    while (is_prefix) {
++        op = ptr[insn_size];
++        insn_size = eat_bytes(name, flags, insn, insn_size, 1);
++        is_prefix = 0;
++        switch (op >> 4) {
++        case 0:
++        case 1:
++        case 2:
++        case 3:
++            if (op == 0x0f) {
++                /* two-byte opcode.  */
++                op = ptr[insn_size];
++                insn_size = eat_bytes(name, flags, insn, insn_size, 1);
++                switch (op >> 4) {
++                case 0:
++                    if ((op & 0xf) > 3)
++                      modrm = 0;
++                    break;
++                case 1: /* vector move or prefetch */
++                case 2: /* various moves and vector compares.  */
++                case 4: /* cmov */
++                case 5: /* vector instructions */
++                case 6:
++                case 13:
++                case 14:
++                case 15:
++                    break;
++                case 7: /* mmx */
++                    if (op & 0x77) /* emms */
++                      modrm = 0;
++                    break;
++                case 3: /* wrmsr, rdtsc, rdmsr, rdpmc, sysenter, sysexit */
++                    modrm = 0;
++                    break;
++                case 8: /* long conditional jump */
++                    is_condjmp = 1;
++                    immed = op_size;
++                    modrm = 0;
++                    break;
++                case 9: /* setcc */
++                    break;
++                case 10:
++                    switch (op & 0x7) {
++                    case 0: /* push fs/gs */
++                    case 1: /* pop fs/gs */
++                    case 2: /* cpuid/rsm */
++                        modrm = 0;
++                        break;
++                    case 4: /* shld/shrd immediate */
++                        immed = 1;
++                        break;
++                    default: /* Normal instructions with a ModR/M byte.  */
++                        break;
++                    }
++                    break;
++                case 11:
++                    switch (op & 0xf) {
++                    case 10: /* bt, bts, btr, btc */
++                        immed = 1;
++                        break;
++                    default:
++                        /* cmpxchg, lss, btr, lfs, lgs, movzx, btc, bsf, bsr
++                           undefined, and movsx */
++                        break;
++                    }
++                    break;
++                case 12:
++                    if (op & 8) {
++                        /* bswap */
++                        modrm = 0;
++                    } else {
++                        switch (op & 0x7) {
++                        case 2:
++                        case 4:
++                        case 5:
++                        case 6:
++                            immed = 1;
++                            break;
++                        default:
++                            break;
++                        }
++                    }
++                    break;
++                }
++            } else if ((op & 0x07) <= 0x3) {
++                /* General arithmentic ax.  */
++            } else if ((op & 0x07) <= 0x5) {
++                /* General arithmetic ax, immediate.  */
++                if (op & 0x01)
++                    immed = op_size;
++                else
++                    immed = 1;
++                modrm = 0;
++            } else if ((op & 0x23) == 0x22) {
++                /* Segment prefix.  */
++                is_prefix = 1;
++            } else {
++                /* Segment register push/pop or DAA/AAA/DAS/AAS.  */
++                modrm = 0;
++            }
++            break;
++
++#if defined(HOST_X86_64)
++        case 4: /* rex prefix.  */
++            is_prefix = 1;
++            /* The address/operand size is actually 64-bit, but the immediate
++               values in the instruction are still 32-bit.  */
++            op_size = 4;
++            addr_size = 4;
++            if (op & 8)
++                seen_rexw = 1;
++            break;
++#else
++        case 4: /* inc/dec register.  */
++#endif
++        case 5: /* push/pop general register.  */
++            modrm = 0;
++            break;
++
++        case 6:
++            switch (op & 0x0f) {
++            case 0: /* pusha */
++            case 1: /* popa */
++                modrm = 0;
++                break;
++            case 2: /* bound */
++            case 3: /* arpl */
++                break;
++            case 4: /* FS */
++            case 5: /* GS */
++                is_prefix = 1;
++                break;
++            case 6: /* opcode size prefix.  */
++                op_size = 2;
++                is_prefix = 1;
++                break;
++            case 7: /* Address size prefix.  */
++                addr_size = 2;
++                is_prefix = 1;
++                break;
++            case 8: /* push immediate */
++                immed = op_size;
++                modrm = 0;
++                break;
++            case 10: /* push 8-bit immediate */
++                immed = 1;
++                modrm = 0;
++                break;
++            case 9: /* imul immediate */
++                immed = op_size;
++                break;
++            case 11: /* imul 8-bit immediate */
++                immed = 1;
++                break;
++            case 12: /* insb */
++            case 13: /* insw */
++            case 14: /* outsb */
++            case 15: /* outsw */
++                modrm = 0;
++                break;
++            }
++            break;
++
++        case 7: /* Short conditional jump.  */
++            is_condjmp = 1;
++            immed = 1;
++            modrm = 0;
++            break;
++          
++        case 8:
++            if ((op & 0xf) <= 3) {
++                /* arithmetic immediate.  */
++                if ((op & 3) == 1)
++                    immed = op_size;
++                else
++                    immed = 1;
++            }
++            /* else test, xchg, mov, lea or pop general.  */
++            break;
++
++        case 9:
++            /* Various single-byte opcodes with no modrm byte.  */
++            modrm = 0;
++            if (op == 10) {
++                /* Call */
++                immed = 4;
++            }
++            break;
++
++        case 10:
++            switch ((op & 0xe) >> 1) {
++            case 0: /* mov absoliute immediate.  */
++            case 1:
++                if (seen_rexw)
++                    immed = 8;
++                else
++                    immed = addr_size;
++                break;
++            case 4: /* test immediate.  */
++                if (op & 1)
++                    immed = op_size;
++                else
++                    immed = 1;
++                break;
++            default: /* Various string ops.  */
++                break;
++            }
++            modrm = 0;
++            break;
++
++        case 11: /* move immediate to register */
++            if (op & 8) {
++                if (seen_rexw)
++                    immed = 8;
++                else
++                    immed = op_size;
++            } else {
++                immed = 1;
++            }
++            modrm = 0;
++            break;
++
++          case 12:
++            switch (op & 0xf) {
++            case 0: /* shift immediate */
++            case 1:
++                immed = 1;
++                break;
++            case 2: /* ret immediate */
++                immed = 2;
++                modrm = 0;
++                bad_opcode(name, op);
++                break;
++            case 3: /* ret */
++                modrm = 0;
++                is_ret = 1;
++            case 4: /* les */
++            case 5: /* lds */
++                break;
++            case 6: /* mov immediate byte */
++                immed = 1;
++                break;
++            case 7: /* mov immediate */
++                immed = op_size;
++                break;
++            case 8: /* enter */
++                /* TODO: Is this right?  */
++                immed = 3;
++                modrm = 0;
++                break;
++            case 10: /* retf immediate */
++                immed = 2;
++                modrm = 0;
++                bad_opcode(name, op);
++                break;
++            case 13: /* int */
++                immed = 1;
++                modrm = 0;
++                break;
++            case 11: /* retf */
++            case 15: /* iret */
++                modrm = 0;
++                bad_opcode(name, op);
++                break;
++            default: /* leave, int3 or into */
++                modrm = 0;
++                break;
++            }
++            break;
++
++        case 13:
++            if ((op & 0xf) >= 8) {
++                /* Coprocessor escape.  For our purposes this is just a normal
++                   instruction with a ModR/M byte.  */
++            } else if ((op & 0xf) >= 4) {
++                /* AAM, AAD or XLAT */
++                modrm = 0;
++            }
++            /* else shift instruction */
++            break;
++
++        case 14:
++            switch ((op & 0xc) >> 2) {
++            case 0: /* loop or jcxz */
++                is_condjmp = 1;
++                immed = 1;
++                break;
++            case 1: /* in/out immed */
++                immed = 1;
++                break;
++            case 2: /* call or jmp */
++                switch (op & 3) {
++                case 0: /* call */
++                    immed = op_size;
++                    break;
++                case 1: /* long jump */
++                    immed = 4;
++                    is_jmp = 1;
++                    break;
++                case 2: /* far jmp */
++                    bad_opcode(name, op);
++                    break;
++                case 3: /* short jmp */
++                    immed = 1;
++                    is_jmp = 1;
++                    break;
++                }
++                break;
++            case 3: /* in/out register */
++                break;
++            }
++            modrm = 0;
++            break;
++
++        case 15:
++            switch ((op & 0xe) >> 1) {
++            case 0:
++            case 1:
++                is_prefix = 1;
++                break;
++            case 2:
++            case 4:
++            case 5:
++            case 6:
++                modrm = 0;
++                /* Some privileged insns are used as markers.  */
++                switch (op) {
++                case 0xf4: /* hlt: Exit translation block.  */
++                    is_exit = 1;
++                    break;
++                case 0xfa: /* cli: Jump to label.  */
++                    is_exit = 1;
++                    immed = 4;
++                    break;
++                case 0xfb: /* sti: TB patch jump.  */
++                    /* Mark the insn for patching, but continue sscanning.  */
++                    flags[insn] |= FLAG_EXIT;
++                    immed = 4;
++                    break;
++                }
++                break;
++            case 3: /* unary grp3 */
++                if ((ptr[insn_size] & 0x38) == 0) {
++                    if (op == 0xf7)
++                        immed = op_size;
++                    else
++                        immed = 1; /* test immediate */
++                }
++                break;
++            case 7: /* inc/dec grp4/5 */
++                /* TODO: This includes indirect jumps.  We should fail if we
++                   encounter one of these. */
++                break;
++            }
++            break;
++        }
++    }
++
++    if (modrm) {
++        if (addr_size != 4)
++            error("16-bit addressing mode used in %s", name);
++
++        disp = 0;
++        modrm = ptr[insn_size];
++        insn_size = eat_bytes(name, flags, insn, insn_size, 1);
++        modrm &= 0xc7;
++        switch ((modrm & 0xc0) >> 6) {
++        case 0:
++            if (modrm == 5)
++              disp = 4;
++            break;
++        case 1:
++            disp = 1;
++            break;
++        case 2:
++            disp = 4;
++            break;
++        }
++        if ((modrm & 0xc0) != 0xc0 && (modrm & 0x7) == 4) {
++            /* SIB byte */
++            if (modrm == 4 && (ptr[insn_size] & 0x7) == 5) {
++                disp = 4;
++                is_pcrel = 1;
++            }
++            insn_size = eat_bytes(name, flags, insn, insn_size, 1);
++        }
++        insn_size = eat_bytes(name, flags, insn, insn_size, disp);
++    }
++    insn_size = eat_bytes(name, flags, insn, insn_size, immed);
++    if (is_condjmp || is_jmp) {
++        if (immed == 1) {
++            disp = (int8_t)*(ptr + insn_size - 1);
++        } else {
++            disp = (((int32_t)*(ptr + insn_size - 1)) << 24)
++                   | (((int32_t)*(ptr + insn_size - 2)) << 16)
++                   | (((int32_t)*(ptr + insn_size - 3)) << 8)
++                   | *(ptr + insn_size - 4);
++        }
++        disp += insn_size;
++        /* Jumps to external symbols point to the address of the offset
++           before relocation.  */
++        /* ??? These are probably a tailcall.  We could fix them up by
++           replacing them with jmp to EOB + call, but it's easier to just
++           prevent the compiler generating them.  */
++        if (disp == 1)
++            error("Unconditional jump (sibcall?) in %s", name);
++        disp += insn;
++        if (disp < 0 || disp > len)
++            error("Jump outside instruction in %s", name);
++
++        if ((flags[disp] & (FLAG_INSN | FLAG_SCANNED)) == FLAG_SCANNED)
++            error("Overlapping instructions in %s", name);
++
++        flags[disp] |= (FLAG_INSN | FLAG_TARGET);
++        is_pcrel = 1; 
++    }
++    if (is_pcrel) {
++        /* Mark the following insn as a jump target.  This will stop
++           this instruction being moved.  */
++        flags[insn + insn_size] |= FLAG_TARGET;
++    }
++    if (is_ret)
++      flags[insn] |= FLAG_RET;
++
++    if (is_exit)
++      flags[insn] |= FLAG_EXIT;
++
++    if (!(is_jmp || is_ret || is_exit))
++      flags[insn + insn_size] |= FLAG_INSN;
++}
++
++/* Scan a function body.  Returns the position of the return sequence.
++   Sets *patch_bytes to the number of bytes that need to be copied from that
++   location.  If no patching is required (ie. the return is the last insn)
++   *patch_bytes will be set to -1.  *plen is the number of code bytes to copy.
++ */
++static int trace_i386_op(const char * name, uint8_t *start_p, int *plen,
++                         int *patch_bytes, int *exit_addrs)
++{
++    char *flags;
++    int more;
++    int insn;
++    int retpos;
++    int bytes;
++    int num_exits;
++    int len;
++    int last_insn;
++
++    len = *plen;
++    flags = malloc(len + 1);
++    memset(flags, 0, len + 1);
++    flags[0] |= FLAG_INSN;
++    more = 1;
++    while (more) {
++        more = 0;
++        for (insn = 0; insn < len; insn++) {
++            if ((flags[insn] & (FLAG_INSN | FLAG_SCANNED)) == FLAG_INSN) {
++                trace_i386_insn(name, start_p, flags, insn, len);
++                more = 1;
++            }
++        }
++    }
++
++    /* Strip any unused code at the end of the function.  */
++    while (len > 0 && flags[len - 1] == 0)
++      len--;
++
++    retpos = -1;
++    num_exits = 0;
++    last_insn = 0;
++    for (insn = 0; insn < len; insn++) {
++        if (flags[insn] & FLAG_RET) {
++            /* ??? In theory it should be possible to handle multiple return
++               points.  In practice it's not worth the effort.  */
++            if (retpos != -1)
++                error("Multiple return instructions in %s", name);
++            retpos = insn;
++        }
++        if (flags[insn] & FLAG_EXIT) {
++            if (num_exits == MAX_EXITS)
++                error("Too many block exits in %s", name);
++            exit_addrs[num_exits] = insn;
++            num_exits++;
++        }
++        if (flags[insn] & FLAG_INSN)
++            last_insn = insn;
++    }
++
++    exit_addrs[num_exits] = -1;
++    if (retpos == -1) {
++        if (num_exits == 0) {
++            error ("No return instruction found in %s", name);
++        } else {
++            retpos = len;
++            last_insn = len;
++        }
++    }
++    
++    /* If the return instruction is the last instruction we can just 
++       remove it.  */
++    if (retpos == last_insn)
++        *patch_bytes = -1;
++    else
++        *patch_bytes = 0;
++
++    /* Back up over any nop instructions.  */
++    while (retpos > 0
++           && (flags[retpos] & FLAG_TARGET) == 0
++           && (flags[retpos - 1] & FLAG_INSN) != 0
++           && start_p[retpos - 1] == 0x90) {
++        retpos--;
++    }
++
++    if (*patch_bytes == -1) {
++        *plen = retpos;
++        free (flags);
++        return retpos;
++    }
++    *plen = len;
++
++    /* The ret is in the middle of the function.  Find four more bytes that
++       so the ret can be replaced by a jmp. */
++    /* ??? Use a short jump where possible. */
++    bytes = 4;
++    insn = retpos + 1;
++    /* We can clobber everything up to the next jump target.  */
++    while (insn < len && bytes > 0 && (flags[insn] & FLAG_TARGET) == 0) {
++        insn++;
++        bytes--;
++    }
++    if (bytes > 0) {
++        /* ???: Strip out nop blocks.  */
++        /* We can't do the replacement without clobbering anything important.
++           Copy preceeding instructions(s) to give us some space.  */
++        while (retpos > 0) {
++            /* If this byte is the target of a jmp we can't move it.  */
++            if (flags[retpos] & FLAG_TARGET)
++                break;
++
++            (*patch_bytes)++;
++            bytes--;
++            retpos--;
++
++            /* Break out of the loop if we have enough space and this is either 
++               the first byte of an instruction or a pad byte.  */
++            if ((flags[retpos] & (FLAG_INSN | FLAG_SCANNED)) != FLAG_SCANNED
++                && bytes <= 0) {
++                break;
++            }
++        }
++    }
++
++    if (bytes > 0)
++        error("Unable to replace ret with jmp in %s\n", name);
++
++    free(flags);
++    return retpos;
++}
++
++#endif
++
+ #define MAX_ARGS 3
+ 
+ /* generate op code */
+@@ -1356,6 +1996,11 @@
+     uint8_t args_present[MAX_ARGS];
+     const char *sym_name, *p;
+     EXE_RELOC *rel;
++#if defined(HOST_I386) || defined(HOST_X86_64)
++    int patch_bytes;
++    int retpos;
++    int exit_addrs[MAX_EXITS];
++#endif
+ 
+     /* Compute exact size excluding prologue and epilogue instructions.
+      * Increment start_offset to skip epilogue instructions, then compute
+@@ -1366,33 +2011,12 @@
+     p_end = p_start + size;
+     start_offset = offset;
+ #if defined(HOST_I386) || defined(HOST_X86_64)
+-#ifdef CONFIG_FORMAT_COFF
+-    {
+-        uint8_t *p;
+-        p = p_end - 1;
+-        if (p == p_start)
+-            error("empty code for %s", name);
+-        while (*p != 0xc3) {
+-            p--;
+-            if (p <= p_start)
+-                error("ret or jmp expected at the end of %s", name);
+-        }
+-        copy_size = p - p_start;
+-    }
+-#else
+     {
+         int len;
+         len = p_end - p_start;
+-        if (len == 0)
+-            error("empty code for %s", name);
+-        if (p_end[-1] == 0xc3) {
+-            len--;
+-        } else {
+-            error("ret or jmp expected at the end of %s", name);
+-        }
++        retpos = trace_i386_op(name, p_start, &len, &patch_bytes, exit_addrs);
+         copy_size = len;
+     }
+-#endif    
+ #elif defined(HOST_PPC)
+     {
+         uint8_t *p;
+@@ -1596,6 +2220,13 @@
+     }
+ 
+     if (gen_switch == 2) {
++#if defined(HOST_I386) || defined(HOST_X86_64)
++        if (patch_bytes != -1)
++            copy_size += patch_bytes;
++#ifdef DEBUG_OP
++        copy_size += 2;
++#endif
++#endif
+         fprintf(outfile, "DEF(%s, %d, %d)\n", name + 3, nb_args, copy_size);
+     } else if (gen_switch == 1) {
+ 
+@@ -1800,7 +2431,43 @@
+ #error unsupport object format
+ #endif
+                 }
++               }
++                /* Replace the marker instructions with the actual opcodes.  */
++                for (i = 0; exit_addrs[i] != -1; i++) {
++                    int op;
++                    switch (p_start[exit_addrs[i]])
++                      {
++                      case 0xf4: op = 0xc3; break; /* hlt -> ret */
++                      case 0xfa: op = 0xe9; break; /* cli -> jmp */
++                      case 0xfb: op = 0xe9; break; /* sti -> jmp */
++                      default: error("Internal error");
++                      }
++                    fprintf(outfile, 
++                            "    *(uint8_t *)(gen_code_ptr + %d) = 0x%x;\n",
++                            exit_addrs[i], op);
+                 }
++                /* Fix up the return instruction.  */
++                if (patch_bytes != -1) {
++                    if (patch_bytes) {
++                        fprintf(outfile, "    memcpy(gen_code_ptr + %d,"
++                                "gen_code_ptr + %d, %d);\n",
++                                copy_size, retpos, patch_bytes);
++                    }
++                    fprintf(outfile,
++                            "    *(uint8_t *)(gen_code_ptr + %d) = 0xe9;\n",
++                            retpos);
++                    fprintf(outfile,
++                            "    *(uint32_t *)(gen_code_ptr + %d) = 0x%x;\n",
++                            retpos + 1, copy_size - (retpos + 5));
++                    
++                    copy_size += patch_bytes;
++                }
++#ifdef DEBUG_OP
++                fprintf(outfile,
++                        "    *(uint16_t *)(gen_code_ptr + %d) = 0x9090;\n",
++                        copy_size);
++                copy_size += 2;
++#endif
+             }
+ #elif defined(HOST_X86_64)
+             {
+@@ -1834,6 +2501,42 @@
+                     }
+                 }
+                 }
++                /* Replace the marker instructions with the actual opcodes.  */
++                for (i = 0; exit_addrs[i] != -1; i++) {
++                    int op;
++                    switch (p_start[exit_addrs[i]])
++                      {
++                      case 0xf4: op = 0xc3; break; /* hlt -> ret */
++                      case 0xfa: op = 0xe9; break; /* cli -> jmp */
++                      case 0xfb: op = 0xe9; break; /* sti -> jmp */
++                      default: error("Internal error");
++                      }
++                    fprintf(outfile, 
++                            "    *(uint8_t *)(gen_code_ptr + %d) = 0x%x;\n",
++                            exit_addrs[i], op);
++                }
++                /* Fix up the return instruction.  */
++                if (patch_bytes != -1) {
++                    if (patch_bytes) {
++                        fprintf(outfile, "    memcpy(gen_code_ptr + %d,"
++                                "gen_code_ptr + %d, %d);\n",
++                                copy_size, retpos, patch_bytes);
++                    }
++                    fprintf(outfile,
++                            "    *(uint8_t *)(gen_code_ptr + %d) = 0xe9;\n",
++                            retpos);
++                    fprintf(outfile,
++                            "    *(uint32_t *)(gen_code_ptr + %d) = 0x%x;\n",
++                            retpos + 1, copy_size - (retpos + 5));
++                    
++                    copy_size += patch_bytes;
++                }
++#ifdef DEBUG_OP
++                fprintf(outfile,
++                        "    *(uint16_t *)(gen_code_ptr + %d) = 0x9090;\n",
++                        copy_size);
++                copy_size += 2;
++#endif
+             }
+ #elif defined(HOST_PPC)
+             {
+Only in qemu-0.8.2.new: dyngen.c.orig
+diff -u -r exec-all.h exec-all.h
+--- exec-all.h	2006-07-22 19:23:34.000000000 +0200
++++ exec-all.h	2007-07-25 18:16:29.000000000 +0200
+@@ -316,14 +316,15 @@
+ 
+ #elif defined(__i386__) && defined(USE_DIRECT_JUMP)
+ 
+-/* we patch the jump instruction directly */
++/* we patch the jump instruction directly.  Use sti in place of the actual
++   jmp instruction so that dyngen can patch in the correct result.  */
+ #define GOTO_TB(opname, tbparam, n)\
+ do {\
+     asm volatile (".section .data\n"\
+ 		  ASM_OP_LABEL_NAME(n, opname) ":\n"\
+ 		  ".long 1f\n"\
+ 		  ASM_PREVIOUS_SECTION \
+-                  "jmp " ASM_NAME(__op_jmp) #n "\n"\
++                  "sti;.long " ASM_NAME(__op_jmp) #n " - 1f\n"\
+ 		  "1:\n");\
+ } while (0)
+ 
+Only in qemu-0.8.2.new: exec-all.h.orig
+Only in target-ppc: exec.h.orig
+Only in target-ppc: exec.h.rej

Added: trunk/dports/emulators/qemu-usermode/files/patch-q-i386
===================================================================
--- trunk/dports/emulators/qemu-usermode/files/patch-q-i386	                        (rev 0)
+++ trunk/dports/emulators/qemu-usermode/files/patch-q-i386	2007-07-26 16:36:57 UTC (rev 27270)
@@ -0,0 +1,1772 @@
+diff -u -r Makefile.target Makefile.target
+--- Makefile.target	2007-02-06 00:01:54.000000000 +0100
++++ Makefile.target	2007-07-25 19:21:53.000000000 +0200
+@@ -23,6 +23,9 @@
+ endif
+ BASE_CFLAGS=
+ BASE_LDFLAGS=
++ifeq ($(CONFIG_DARWIN),yes)
++CFLAGS+=-mdynamic-no-pic
++endif
+ #CFLAGS+=-Werror
+ LIBS=
+ HELPER_CFLAGS=$(CFLAGS)
+@@ -68,13 +71,17 @@
+ ifdef CONFIG_STATIC
+ BASE_LDFLAGS+=-static
+ endif
++ifeq ($(TARGET_ARCH), x86_64)
++# XXX globally save %ebx, %esi, %edi on entry to generated function
++OP_CFLAGS+= -fcall-used-ebx -fcall-used-esi -fcall-used-edi
++endif
+ 
+ # We require -O2 to avoid the stack setup prologue in EXIT_TB
+ OP_CFLAGS = -Wall -O2 -g -fno-strict-aliasing
+ 
+ ifeq ($(ARCH),i386)
+ HELPER_CFLAGS+=-fomit-frame-pointer
+-OP_CFLAGS+=-mpreferred-stack-boundary=2 -fomit-frame-pointer
++OP_CFLAGS+=-fomit-frame-pointer
+ ifeq ($(HAVE_GCC3_OPTIONS),yes)
+ OP_CFLAGS+= -falign-functions=0 -fno-gcse
+ else
+@@ -415,8 +422,8 @@
+ endif
+ VL_OBJS+=vnc.o
+ ifdef CONFIG_COCOA
+-VL_OBJS+=cocoa.o
+-COCOA_LIBS=-F/System/Library/Frameworks -framework Cocoa -framework IOKit
++VL_OBJS+=cocoaQemuMain.o cocoaQemuController.o cocoaQemu.o cocoaQemuProgressWindow.o cocoaQemuWindow.o cocoaQemuOpenGLView.o cocoaQemuQuartzView.o cocoaQemuQuickDrawView.o cocoaPopUpView.o cocoaCpuView.o FSController.o FSRoundedView.o FSToolbarController.o FSTransparentButton.o
++COCOA_LIBS=-F/System/Library/Frameworks -framework Cocoa -framework IOKit -framework CoreFoundation -framework OpenGL -framework ApplicationServices
+ ifdef CONFIG_COREAUDIO
+ COCOA_LIBS+=-framework CoreAudio
+ endif
+@@ -465,7 +472,11 @@
+ $(QEMU_SYSTEM): $(VL_OBJS) libqemu.a
+ 	$(CC) $(VL_LDFLAGS) -o $@ $^ $(LIBS) $(SDL_LIBS) $(COCOA_LIBS) $(VL_LIBS)
+ 
+-cocoa.o: cocoa.m
++
++cocoa%.o: host-cocoa/cocoa%.m
++	$(CC) $(CFLAGS) $(CPPFLAGS) $(BASE_CFLAGS) -c -o $@ $<
++
++FS%.o: host-cocoa/FSControls/FS%.m
+ 	$(CC) $(CFLAGS) $(CPPFLAGS) $(BASE_CFLAGS) -c -o $@ $<
+ 
+ sdl.o: sdl.c keymaps.c sdl_keysym.h
+diff -u -r block-qcow2.c block-qcow2.c
+--- block-qcow2.c	2007-02-06 00:01:54.000000000 +0100
++++ block-qcow2.c	2007-07-25 19:21:53.000000000 +0200
+@@ -1886,6 +1886,8 @@
+     int64_t table_offset;
+     uint64_t data64;
+     uint32_t data32;
++    int old_table_size;
++    int64_t old_table_offset;
+ 
+     if (min_size <= s->refcount_table_size)
+         return 0;
+@@ -1931,10 +1933,14 @@
+                     &data32, sizeof(data32)) != sizeof(data32))
+         goto fail;
+     qemu_free(s->refcount_table);
++    old_table_offset = s->refcount_table_offset;
++    old_table_size = s->refcount_table_size;
+     s->refcount_table = new_table;
+     s->refcount_table_size = new_table_size;
++    s->refcount_table_offset = table_offset;
+ 
+     update_refcount(bs, table_offset, new_table_size2, 1);
++    free_clusters(bs, old_table_offset, old_table_size * sizeof(uint64_t));
+     return 0;
+  fail:
+     free_clusters(bs, table_offset, new_table_size2);
+diff -u -r block.c block.c
+--- block.c	2007-02-06 00:01:54.000000000 +0100
++++ block.c	2007-07-25 19:21:53.000000000 +0200
+@@ -497,6 +497,7 @@
+ int bdrv_read(BlockDriverState *bs, int64_t sector_num, 
+               uint8_t *buf, int nb_sectors)
+ {
++    bs->activityLED = 1;
+     BlockDriver *drv = bs->drv;
+ 
+     if (!drv)
+@@ -534,6 +535,7 @@
+ int bdrv_write(BlockDriverState *bs, int64_t sector_num, 
+                const uint8_t *buf, int nb_sectors)
+ {
++    bs->activityLED = 1;
+     BlockDriver *drv = bs->drv;
+     if (!bs->drv)
+         return -ENOMEDIUM;
+@@ -1058,6 +1060,7 @@
+                                 uint8_t *buf, int nb_sectors,
+                                 BlockDriverCompletionFunc *cb, void *opaque)
+ {
++    bs->activityLED = 1;
+     BlockDriver *drv = bs->drv;
+ 
+     if (!drv)
+@@ -1078,6 +1081,7 @@
+                                  const uint8_t *buf, int nb_sectors,
+                                  BlockDriverCompletionFunc *cb, void *opaque)
+ {
++    bs->activityLED = 1;
+     BlockDriver *drv = bs->drv;
+ 
+     if (!drv)
+diff -u -r block_int.h block_int.h
+--- block_int.h	2007-02-06 00:01:54.000000000 +0100
++++ block_int.h	2007-07-25 19:21:53.000000000 +0200
+@@ -87,6 +87,7 @@
+     int removable; /* if true, the media can be removed */
+     int locked;    /* if true, the media cannot temporarily be ejected */
+     int encrypted; /* if true, the media is encrypted */
++    int activityLED; /* if true, the media is accessed atm */
+     /* event callback when inserting/removing */
+     void (*change_cb)(void *opaque);
+     void *change_opaque;
+diff -u -r cpu-all.h cpu-all.h
+--- cpu-all.h	2007-02-06 00:01:54.000000000 +0100
++++ cpu-all.h	2007-07-25 19:21:53.000000000 +0200
+@@ -339,7 +339,13 @@
+ 
+ static inline void stq_le_p(void *ptr, uint64_t v)
+ {
++#if defined(__i386__) && __GNUC__ >= 4
++    const union { uint64_t v; uint32_t p[2]; } x = { .v = v };
++    ((uint32_t *)ptr)[0] = x.p[0];
++    ((uint32_t *)ptr)[1] = x.p[1];
++#else
+     *(uint64_t *)ptr = v;
++#endif
+ }
+ 
+ /* float access */
+diff -u -r cpu-exec.c cpu-exec.c
+--- cpu-exec.c	2007-02-06 00:01:54.000000000 +0100
++++ cpu-exec.c	2007-07-25 19:21:53.000000000 +0200
+@@ -652,6 +652,15 @@
+                               : /* no outputs */
+                               : "r" (gen_func)
+                               : "r1", "r2", "r3", "r8", "r9", "r10", "r12", "r14");
++#elif defined(TARGET_X86_64) && defined(__i386__)
++                asm volatile ("push %%ebx\n"
++                              "push %%esi\n"
++                              "push %%edi\n"
++                              "call *%0\n"
++                              "pop %%edi\n"
++                              "pop %%esi\n"
++                              "pop %%ebx\n"
++                              : : "r" (gen_func) : "ebx", "esi", "edi");
+ #elif defined(TARGET_I386) && defined(USE_CODE_COPY)
+ {
+     if (!(tb->cflags & CF_CODE_COPY)) {
+diff -u -r dyngen-exec.h dyngen-exec.h
+--- dyngen-exec.h	2007-02-06 00:01:54.000000000 +0100
++++ dyngen-exec.h	2007-07-25 19:21:53.000000000 +0200
+@@ -191,7 +191,12 @@
+ #endif
+ 
+ /* force GCC to generate only one epilog at the end of the function */
++#if defined(__i386__) || defined(__x86_64__)
++/* Also add 4 bytes of padding so that we can replace the ret with a jmp.  */
++#define FORCE_RET() asm volatile ("nop;nop;nop;nop");
++#else
+ #define FORCE_RET() __asm__ __volatile__("" : : : "memory");
++#endif
+ 
+ #ifndef OPPROTO
+ #define OPPROTO
+@@ -241,12 +246,26 @@
+ #endif
+ 
+ #ifdef __i386__
+-#define EXIT_TB() asm volatile ("ret")
+-#define GOTO_LABEL_PARAM(n) asm volatile ("jmp " ASM_NAME(__op_gen_label) #n)
++/* Dyngen will replace hlt instructions with a ret instruction.  Inserting a
++   ret directly would confuse dyngen.  */
++#define EXIT_TB() asm volatile ("hlt")
++/* Dyngen will replace cli with 0x9e (jmp). 
++   We generate the offset manually.  */
++#if defined(__APPLE__)
++/* XXX Different relocations are generated for MacOS X for Intel
++   (please as from cctools).  */
++#define GOTO_LABEL_PARAM(n) \
++  asm volatile ("cli;.long " ASM_NAME(__op_gen_label) #n)
++#else
++#define GOTO_LABEL_PARAM(n) \
++  asm volatile ("cli;.long " ASM_NAME(__op_gen_label) #n " - 1f;1:")
++#endif
+ #endif
+ #ifdef __x86_64__
+-#define EXIT_TB() asm volatile ("ret")
+-#define GOTO_LABEL_PARAM(n) asm volatile ("jmp " ASM_NAME(__op_gen_label) #n)
++/* The same as i386.  */
++#define EXIT_TB() asm volatile ("hlt")
++#define GOTO_LABEL_PARAM(n) \
++  asm volatile ("cli;.long " ASM_NAME(__op_gen_label) #n " - 1f;1:")
+ #endif
+ #ifdef __powerpc__
+ #define EXIT_TB() asm volatile ("blr")
+diff -u -r dyngen.c dyngen.c
+--- dyngen.c	2007-02-06 00:01:54.000000000 +0100
++++ dyngen.c	2007-07-25 19:21:53.000000000 +0200
+@@ -32,6 +32,8 @@
+ 
+ #include "config-host.h"
+ 
++//#define DEBUG_OP
++
+ /* NOTE: we test CONFIG_WIN32 instead of _WIN32 to enabled cross
+    compilation */
+ #if defined(CONFIG_WIN32)
+@@ -182,6 +184,20 @@
+ #include <mach-o/reloc.h>
+ #include <mach-o/ppc/reloc.h>
+ 
++#ifdef HOST_PPC
++
++#define MACH_CPU_TYPE CPU_TYPE_POWERPC
++#define mach_check_cputype(x) ((x) == CPU_TYPE_POWERPC)
++
++#elif defined(HOST_I386)
++
++#define MACH_CPU_TYPE CPU_TYPE_I386
++#define mach_check_cputype(x) ((x) == CPU_TYPE_I386)
++
++#else
++#error unsupported CPU - please update the code
++#endif
++
+ # define check_mach_header(x) (x.magic == MH_MAGIC)
+ typedef int32_t host_long;
+ typedef uint32_t host_ulong;
+@@ -938,22 +954,23 @@
+ {
+     unsigned int tocindex, symindex, size;
+     const char *name = 0;
++	int section_type;
+     
+     /* Sanity check */
+     if(!( address >= sec_hdr->addr && address < (sec_hdr->addr + sec_hdr->size) ) )
+         return (char*)0;
+-		
+-	if( sec_hdr->flags & S_SYMBOL_STUBS ){
++
++	section_type = sec_hdr->flags & SECTION_TYPE;
++	if( section_type == S_SYMBOL_STUBS ){
+ 		size = sec_hdr->reserved2;
+ 		if(size == 0)
+ 		    error("size = 0");
+-		
+ 	}
+-	else if( sec_hdr->flags & S_LAZY_SYMBOL_POINTERS ||
+-	            sec_hdr->flags & S_NON_LAZY_SYMBOL_POINTERS)
++	else if( section_type == S_LAZY_SYMBOL_POINTERS ||
++			 section_type == S_NON_LAZY_SYMBOL_POINTERS)
+ 		size = sizeof(unsigned long);
+ 	else
+-		return 0;
++		return NULL;
+ 		
+     /* Compute our index in toc */
+ 	tocindex = (address - sec_hdr->addr)/size;
+@@ -987,8 +1004,27 @@
+ 	/* init the slide value */
+ 	*sslide = 0;
+ 	
+-	if(R_SCATTERED & rel->r_address)
+-		return (char *)find_reloc_name_given_its_address(sca_rel->r_value);
++	if (R_SCATTERED & rel->r_address) {
++        char *name = (char *)find_reloc_name_given_its_address(sca_rel->r_value);
++
++        /* search it in the full symbol list, if not found */
++        if (!name) {
++            int i;
++            for (i = 0; i < nb_syms; i++) {
++                EXE_SYM *sym = &symtab[i];
++                if (sym->st_value == sca_rel->r_value) {
++                    name = get_sym_name(sym);
++                    switch (sca_rel->r_type) {
++                    case GENERIC_RELOC_VANILLA:
++                        *sslide = *(uint32_t *)(text + sca_rel->r_address) - sca_rel->r_value;
++                        break;
++                    }
++                    break;
++                }
++            }
++        }
++        return name;
++    }
+ 
+ 	if(rel->r_extern)
+ 	{
+@@ -1020,14 +1056,21 @@
+ 			sectoffset = ( *(uint32_t *)(text + rel->r_address) & 0x03fffffc );
+ 			if (sectoffset & 0x02000000) sectoffset |= 0xfc000000;
+ 			break;
++        case GENERIC_RELOC_VANILLA:
++            sectoffset  = *(uint32_t *)(text + rel->r_address);
++            break;
+ 		default:
+-			error("switch(rel->type) not found");
++			error("switch(rel->type=%d) not found", rel->r_type);
+ 	}
+ 
+-	if(rel->r_pcrel)
++	if(rel->r_pcrel) {
+ 		sectoffset += rel->r_address;
+-			
+-	if (rel->r_type == PPC_RELOC_BR24)
++#ifdef HOST_I386
++        sectoffset += (1 << rel->r_length);
++#endif
++    }
++
++	if (rel->r_type == PPC_RELOC_BR24 || rel->r_pcrel)
+ 		name = (char *)find_reloc_name_in_sec_ptr((int)sectoffset, &section_hdr[sectnum-1]);
+ 
+ 	/* search it in the full symbol list, if not found */
+@@ -1079,7 +1122,7 @@
+         error("bad Mach header");
+     }
+     
+-    if (mach_hdr.cputype != CPU_TYPE_POWERPC)
++    if (!mach_check_cputype(mach_hdr.cputype))
+         error("Unsupported CPU");
+         
+     if (mach_hdr.filetype != MH_OBJECT)
+@@ -1414,6 +1457,677 @@
+ #endif
+ 
+ 
++#if defined(HOST_I386) || defined(HOST_X86_64)
++
++/* This byte is the first byte of an instruction.  */
++#define FLAG_INSN     (1 << 0)
++/* This byte has been processed as part of an instruction.  */
++#define FLAG_SCANNED  (1 << 1)
++/* This instruction is a return instruction.  Gcc cometimes generates prefix
++   bytes, so may be more than one byte long.  */
++#define FLAG_RET      (1 << 2)
++/* This is either the target of a jump, or the preceeding instruction uses
++   a pc-relative offset.  */
++#define FLAG_TARGET   (1 << 3)
++/* This is a magic instruction that needs fixing up.  */
++#define FLAG_EXIT     (1 << 4)
++/* This instruction clobbers the stack pointer.  */
++/* XXX only supports push, pop, add/sub $imm,%esp  */
++#define FLAG_STACK    (1 << 5)
++#define MAX_EXITS     5
++
++static void
++bad_opcode(const char *name, uint32_t op)
++{
++    error("Unsupported opcode %0*x in %s", (op > 0xff) ? 4 : 2, op, name);
++}
++
++/* Mark len bytes as scanned,  Returns insn_size + len.  Reports an error
++   if these bytes have already been scanned.  */
++static int
++eat_bytes(const char *name, char *flags, int insn, int insn_size, int len)
++{
++    while (len > 0) {
++        /* This should never occur in sane code.  */
++        if (flags[insn + insn_size] & FLAG_SCANNED)
++            error ("Overlapping instructions in %s", name);
++        flags[insn + insn_size] |= FLAG_SCANNED;
++        insn_size++;
++        len--;
++    }
++    return insn_size;
++}
++
++static void
++trace_i386_insn (const char *name, uint8_t *start_p, char *flags, int insn,
++                 int len)
++{
++    uint8_t *ptr;
++    uint8_t op;
++    int modrm;
++    int is_prefix;
++    int op_size;
++    int addr_size;
++    int insn_size;
++    int is_ret;
++    int is_condjmp;
++    int is_jmp;
++    int is_exit;
++    int is_pcrel;
++    int is_stack;
++    int immed;
++    int seen_rexw;
++    int32_t disp;
++
++    ptr = start_p + insn;
++    /* nonzero if this insn has a ModR/M byte.  */
++    modrm = 1;
++    /* The size of the immediate value in this instruction.  */
++    immed = 0;
++    /* The operand size.  */
++    op_size = 4;
++    /* The address size */
++    addr_size = 4;
++    /* The total length of this instruction.  */
++    insn_size = 0;
++    is_prefix = 1;
++    is_ret = 0;
++    is_condjmp = 0;
++    is_jmp = 0;
++    is_exit = 0;
++    seen_rexw = 0;
++    is_pcrel = 0;
++    is_stack = 0;
++
++    while (is_prefix) {
++        op = ptr[insn_size];
++        insn_size = eat_bytes(name, flags, insn, insn_size, 1);
++        is_prefix = 0;
++        switch (op >> 4) {
++        case 0:
++        case 1:
++        case 2:
++        case 3:
++            if (op == 0x0f) {
++                /* two-byte opcode.  */
++                op = ptr[insn_size];
++                insn_size = eat_bytes(name, flags, insn, insn_size, 1);
++                switch (op >> 4) {
++                case 0:
++                    if ((op & 0xf) > 3)
++                      modrm = 0;
++                    break;
++                case 1: /* vector move or prefetch */
++                case 2: /* various moves and vector compares.  */
++                case 4: /* cmov */
++                case 5: /* vector instructions */
++                case 6:
++                case 13:
++                case 14:
++                case 15:
++                    break;
++                case 7: /* mmx */
++                    if (op & 0x77) /* emms */
++                      modrm = 0;
++                    break;
++                case 3: /* wrmsr, rdtsc, rdmsr, rdpmc, sysenter, sysexit */
++                    modrm = 0;
++                    break;
++                case 8: /* long conditional jump */
++                    is_condjmp = 1;
++                    immed = op_size;
++                    modrm = 0;
++                    break;
++                case 9: /* setcc */
++                    break;
++                case 10:
++                    switch (op & 0x7) {
++                    case 0: /* push fs/gs */
++                    case 1: /* pop fs/gs */
++                        is_stack = 1;
++                    case 2: /* cpuid/rsm */
++                        modrm = 0;
++                        break;
++                    case 4: /* shld/shrd immediate */
++                        immed = 1;
++                        break;
++                    default: /* Normal instructions with a ModR/M byte.  */
++                        break;
++                    }
++                    break;
++                case 11:
++                    switch (op & 0xf) {
++                    case 10: /* bt, bts, btr, btc */
++                        immed = 1;
++                        break;
++                    default:
++                        /* cmpxchg, lss, btr, lfs, lgs, movzx, btc, bsf, bsr
++                           undefined, and movsx */
++                        break;
++                    }
++                    break;
++                case 12:
++                    if (op & 8) {
++                        /* bswap */
++                        modrm = 0;
++                    } else {
++                        switch (op & 0x7) {
++                        case 2:
++                        case 4:
++                        case 5:
++                        case 6:
++                            immed = 1;
++                            break;
++                        default:
++                            break;
++                        }
++                    }
++                    break;
++                }
++            } else if ((op & 0x07) <= 0x3) {
++                /* General arithmentic ax.  */
++            } else if ((op & 0x07) <= 0x5) {
++                /* General arithmetic ax, immediate.  */
++                if (op & 0x01)
++                    immed = op_size;
++                else
++                    immed = 1;
++                modrm = 0;
++            } else if ((op & 0x23) == 0x22) {
++                /* Segment prefix.  */
++                is_prefix = 1;
++            } else {
++                /* Segment register push/pop or DAA/AAA/DAS/AAS.  */
++                modrm = 0;
++            }
++            break;
++
++#if defined(HOST_X86_64)
++        case 4: /* rex prefix.  */
++            is_prefix = 1;
++            /* The address/operand size is actually 64-bit, but the immediate
++               values in the instruction are still 32-bit.  */
++            op_size = 4;
++            addr_size = 4;
++            if (op & 8)
++                seen_rexw = 1;
++            break;
++#else
++        case 4: /* inc/dec register.  */
++#endif
++        case 5: /* push/pop general register.  */
++            modrm = 0;
++            is_stack = 1;
++            break;
++
++        case 6:
++            switch (op & 0x0f) {
++            case 0: /* pusha */
++            case 1: /* popa */
++                modrm = 0;
++                is_stack = 1;
++                break;
++            case 2: /* bound */
++            case 3: /* arpl */
++                break;
++            case 4: /* FS */
++            case 5: /* GS */
++                is_prefix = 1;
++                break;
++            case 6: /* opcode size prefix.  */
++                op_size = 2;
++                is_prefix = 1;
++                break;
++            case 7: /* Address size prefix.  */
++                addr_size = 2;
++                is_prefix = 1;
++                break;
++            case 8: /* push immediate */
++                immed = op_size;
++                modrm = 0;
++                is_stack = 1;
++                break;
++            case 10: /* push 8-bit immediate */
++                immed = 1;
++                modrm = 0;
++                is_stack = 1;
++                break;
++            case 9: /* imul immediate */
++                immed = op_size;
++                break;
++            case 11: /* imul 8-bit immediate */
++                immed = 1;
++                break;
++            case 12: /* insb */
++            case 13: /* insw */
++            case 14: /* outsb */
++            case 15: /* outsw */
++                modrm = 0;
++                break;
++            }
++            break;
++
++        case 7: /* Short conditional jump.  */
++            is_condjmp = 1;
++            immed = 1;
++            modrm = 0;
++            break;
++          
++        case 8:
++            if ((op & 0xf) <= 3) {
++                /* arithmetic immediate.  */
++                if ((op & 3) == 1)
++                    immed = op_size;
++                else
++                    immed = 1;
++                if (op == 0x81 || op == 0x83) {
++                    /* add, sub */
++                    op = ptr[insn_size];
++                    switch ((op >> 3) & 7) {
++                    case 0:
++                    case 5:
++                        is_stack = (op & 7) == 4;
++                        break;
++                    }
++                }
++            }
++            else if ((op & 0xf) == 0xf) {
++                /* pop general.  */
++                is_stack = 1;
++            }
++            /* else test, xchg, mov, lea.  */
++            break;
++
++        case 9:
++            /* Various single-byte opcodes with no modrm byte.  */
++            modrm = 0;
++            if (op == 10) {
++                /* Call */
++                immed = 4;
++            }
++            break;
++
++        case 10:
++            switch ((op & 0xe) >> 1) {
++            case 0: /* mov absoliute immediate.  */
++            case 1:
++                if (seen_rexw)
++                    immed = 8;
++                else
++                    immed = addr_size;
++                break;
++            case 4: /* test immediate.  */
++                if (op & 1)
++                    immed = op_size;
++                else
++                    immed = 1;
++                break;
++            default: /* Various string ops.  */
++                break;
++            }
++            modrm = 0;
++            break;
++
++        case 11: /* move immediate to register */
++            if (op & 8) {
++                if (seen_rexw)
++                    immed = 8;
++                else
++                    immed = op_size;
++            } else {
++                immed = 1;
++            }
++            modrm = 0;
++            break;
++
++          case 12:
++            switch (op & 0xf) {
++            case 0: /* shift immediate */
++            case 1:
++                immed = 1;
++                break;
++            case 2: /* ret immediate */
++                immed = 2;
++                modrm = 0;
++                bad_opcode(name, op);
++                break;
++            case 3: /* ret */
++                modrm = 0;
++                is_ret = 1;
++            case 4: /* les */
++            case 5: /* lds */
++                break;
++            case 6: /* mov immediate byte */
++                immed = 1;
++                break;
++            case 7: /* mov immediate */
++                immed = op_size;
++                break;
++            case 8: /* enter */
++                /* TODO: Is this right?  */
++                immed = 3;
++                modrm = 0;
++                break;
++            case 10: /* retf immediate */
++                immed = 2;
++                modrm = 0;
++                bad_opcode(name, op);
++                break;
++            case 13: /* int */
++                immed = 1;
++                modrm = 0;
++                break;
++            case 11: /* retf */
++            case 15: /* iret */
++                modrm = 0;
++                bad_opcode(name, op);
++                break;
++            default: /* leave, int3 or into */
++                modrm = 0;
++                break;
++            }
++            break;
++
++        case 13:
++            if ((op & 0xf) >= 8) {
++                /* Coprocessor escape.  For our purposes this is just a normal
++                   instruction with a ModR/M byte.  */
++            } else if ((op & 0xf) >= 4) {
++                /* AAM, AAD or XLAT */
++                modrm = 0;
++            }
++            /* else shift instruction */
++            break;
++
++        case 14:
++            switch ((op & 0xc) >> 2) {
++            case 0: /* loop or jcxz */
++                is_condjmp = 1;
++                immed = 1;
++                break;
++            case 1: /* in/out immed */
++                immed = 1;
++                break;
++            case 2: /* call or jmp */
++                switch (op & 3) {
++                case 0: /* call */
++                    immed = op_size;
++                    break;
++                case 1: /* long jump */
++                    immed = 4;
++                    is_jmp = 1;
++                    break;
++                case 2: /* far jmp */
++                    bad_opcode(name, op);
++                    break;
++                case 3: /* short jmp */
++                    immed = 1;
++                    is_jmp = 1;
++                    break;
++                }
++                break;
++            case 3: /* in/out register */
++                break;
++            }
++            modrm = 0;
++            break;
++
++        case 15:
++            switch ((op & 0xe) >> 1) {
++            case 0:
++            case 1:
++                is_prefix = 1;
++                break;
++            case 2:
++            case 4:
++            case 5:
++            case 6:
++                modrm = 0;
++                /* Some privileged insns are used as markers.  */
++                switch (op) {
++                case 0xf4: /* hlt: Exit translation block.  */
++                    is_exit = 1;
++                    break;
++                case 0xfa: /* cli: Jump to label.  */
++                    is_exit = 1;
++                    immed = 4;
++                    break;
++                case 0xfb: /* sti: TB patch jump.  */
++                    /* Mark the insn for patching, but continue sscanning.  */
++                    flags[insn] |= FLAG_EXIT;
++                    immed = 4;
++                    break;
++                }
++                break;
++            case 3: /* unary grp3 */
++                if ((ptr[insn_size] & 0x38) == 0) {
++                    if (op == 0xf7)
++                        immed = op_size;
++                    else
++                        immed = 1; /* test immediate */
++                }
++                break;
++            case 7: /* inc/dec grp4/5 */
++                /* TODO: This includes indirect jumps.  We should fail if we
++                   encounter one of these. */
++                break;
++            }
++            break;
++        }
++    }
++
++    if (modrm) {
++        if (addr_size != 4)
++            error("16-bit addressing mode used in %s", name);
++
++        disp = 0;
++        modrm = ptr[insn_size];
++        insn_size = eat_bytes(name, flags, insn, insn_size, 1);
++        modrm &= 0xc7;
++        switch ((modrm & 0xc0) >> 6) {
++        case 0:
++            if (modrm == 5)
++              disp = 4;
++            break;
++        case 1:
++            disp = 1;
++            break;
++        case 2:
++            disp = 4;
++            break;
++        }
++        if ((modrm & 0xc0) != 0xc0 && (modrm & 0x7) == 4) {
++            /* SIB byte */
++            if (modrm == 4 && (ptr[insn_size] & 0x7) == 5) {
++                disp = 4;
++                is_pcrel = 1;
++            }
++            insn_size = eat_bytes(name, flags, insn, insn_size, 1);
++        }
++        insn_size = eat_bytes(name, flags, insn, insn_size, disp);
++    }
++    insn_size = eat_bytes(name, flags, insn, insn_size, immed);
++    if (is_condjmp || is_jmp) {
++        if (immed == 1) {
++            disp = (int8_t)*(ptr + insn_size - 1);
++        } else {
++            disp = (((int32_t)*(ptr + insn_size - 1)) << 24)
++                   | (((int32_t)*(ptr + insn_size - 2)) << 16)
++                   | (((int32_t)*(ptr + insn_size - 3)) << 8)
++                   | *(ptr + insn_size - 4);
++        }
++        disp += insn_size;
++        /* Jumps to external symbols point to the address of the offset
++           before relocation.  */
++        /* ??? These are probably a tailcall.  We could fix them up by
++           replacing them with jmp to EOB + call, but it's easier to just
++           prevent the compiler generating them.  */
++        if (disp == 1)
++            error("Unconditional jump (sibcall?) in %s", name);
++        disp += insn;
++        if (disp < 0 || disp > len)
++            error("Jump outside instruction in %s", name);
++
++        if ((flags[disp] & (FLAG_INSN | FLAG_SCANNED)) == FLAG_SCANNED)
++            error("Overlapping instructions in %s", name);
++
++        flags[disp] |= (FLAG_INSN | FLAG_TARGET);
++        is_pcrel = 1; 
++    }
++    if (is_pcrel) {
++        /* Mark the following insn as a jump target.  This will stop
++           this instruction being moved.  */
++        flags[insn + insn_size] |= FLAG_TARGET;
++    }
++    if (is_ret)
++      flags[insn] |= FLAG_RET;
++
++    if (is_exit)
++      flags[insn] |= FLAG_EXIT;
++
++    if (is_stack)
++      flags[insn] |= FLAG_STACK;
++
++    if (!(is_jmp || is_ret || is_exit))
++      flags[insn + insn_size] |= FLAG_INSN;
++}
++
++/* Scan a function body.  Returns the position of the return sequence.
++   Sets *patch_bytes to the number of bytes that need to be copied from that
++   location.  If no patching is required (ie. the return is the last insn)
++   *patch_bytes will be set to -1.  *plen is the number of code bytes to copy.
++ */
++static int trace_i386_op(const char * name, uint8_t *start_p, int *plen,
++                         int *patch_bytes, int *exit_addrs)
++{
++    char *flags;
++    int more;
++    int insn;
++    int retpos;
++    int bytes;
++    int num_exits;
++    int len;
++    int last_insn;
++    int stack_clobbered;
++
++    len = *plen;
++    flags = malloc(len + 1);
++    memset(flags, 0, len + 1);
++    flags[0] |= FLAG_INSN;
++    more = 1;
++    while (more) {
++        more = 0;
++        for (insn = 0; insn < len; insn++) {
++            if ((flags[insn] & (FLAG_INSN | FLAG_SCANNED)) == FLAG_INSN) {
++                trace_i386_insn(name, start_p, flags, insn, len);
++                more = 1;
++            }
++        }
++    }
++
++    /* Strip any unused code at the end of the function.  */
++    while (len > 0 && flags[len - 1] == 0)
++      len--;
++
++    retpos = -1;
++    num_exits = 0;
++    last_insn = 0;
++    stack_clobbered = 0;
++    for (insn = 0; insn < len; insn++) {
++        if (flags[insn] & FLAG_RET) {
++            /* ??? In theory it should be possible to handle multiple return
++               points.  In practice it's not worth the effort.  */
++            if (retpos != -1)
++                error("Multiple return instructions in %s", name);
++            retpos = insn;
++        }
++        if (flags[insn] & FLAG_EXIT) {
++            if (stack_clobbered)
++                error("Stack clobbered in %s", name);
++            if (num_exits == MAX_EXITS)
++                error("Too many block exits in %s", name);
++            exit_addrs[num_exits] = insn;
++            num_exits++;
++        }
++        if (flags[insn] & FLAG_INSN)
++            last_insn = insn;
++        if (flags[insn] & FLAG_STACK)
++            stack_clobbered = 1;
++    }
++
++    exit_addrs[num_exits] = -1;
++    if (retpos == -1) {
++        if (num_exits == 0) {
++            error ("No return instruction found in %s", name);
++        } else {
++            retpos = len;
++            last_insn = len;
++        }
++    }
++    
++    /* If the return instruction is the last instruction we can just 
++       remove it.  */
++    if (retpos == last_insn)
++        *patch_bytes = -1;
++    else
++        *patch_bytes = 0;
++
++    /* Back up over any nop instructions.  */
++    while (retpos > 0
++           && (flags[retpos] & FLAG_TARGET) == 0
++           && (flags[retpos - 1] & FLAG_INSN) != 0
++           && start_p[retpos - 1] == 0x90) {
++        retpos--;
++    }
++
++    if (*patch_bytes == -1) {
++        *plen = retpos;
++        free (flags);
++        return retpos;
++    }
++    *plen = len;
++
++    /* The ret is in the middle of the function.  Find four more bytes that
++       so the ret can be replaced by a jmp. */
++    /* ??? Use a short jump where possible. */
++    bytes = 4;
++    insn = retpos + 1;
++    /* We can clobber everything up to the next jump target.  */
++    while (insn < len && bytes > 0 && (flags[insn] & FLAG_TARGET) == 0) {
++        insn++;
++        bytes--;
++    }
++    if (bytes > 0) {
++        /* ???: Strip out nop blocks.  */
++        /* We can't do the replacement without clobbering anything important.
++           Copy preceeding instructions(s) to give us some space.  */
++        while (retpos > 0) {
++            /* If this byte is the target of a jmp we can't move it.  */
++            if (flags[retpos] & FLAG_TARGET)
++                break;
++
++            (*patch_bytes)++;
++            bytes--;
++            retpos--;
++
++            /* Break out of the loop if we have enough space and this is either 
++               the first byte of an instruction or a pad byte.  */
++            if ((flags[retpos] & (FLAG_INSN | FLAG_SCANNED)) != FLAG_SCANNED
++                && bytes <= 0) {
++                break;
++            }
++        }
++    }
++
++    if (bytes > 0)
++        error("Unable to replace ret with jmp in %s\n", name);
++
++    free(flags);
++    return retpos;
++}
++
++#endif
++
+ #define MAX_ARGS 3
+ 
+ /* generate op code */
+@@ -1427,6 +2141,11 @@
+     uint8_t args_present[MAX_ARGS];
+     const char *sym_name, *p;
+     EXE_RELOC *rel;
++#if defined(HOST_I386) || defined(HOST_X86_64)
++    int patch_bytes;
++    int retpos;
++    int exit_addrs[MAX_EXITS];
++#endif
+ 
+     /* Compute exact size excluding prologue and epilogue instructions.
+      * Increment start_offset to skip epilogue instructions, then compute
+@@ -1437,33 +2156,12 @@
+     p_end = p_start + size;
+     start_offset = offset;
+ #if defined(HOST_I386) || defined(HOST_X86_64)
+-#ifdef CONFIG_FORMAT_COFF
+-    {
+-        uint8_t *p;
+-        p = p_end - 1;
+-        if (p == p_start)
+-            error("empty code for %s", name);
+-        while (*p != 0xc3) {
+-            p--;
+-            if (p <= p_start)
+-                error("ret or jmp expected at the end of %s", name);
+-        }
+-        copy_size = p - p_start;
+-    }
+-#else
+     {
+         int len;
+         len = p_end - p_start;
+-        if (len == 0)
+-            error("empty code for %s", name);
+-        if (p_end[-1] == 0xc3) {
+-            len--;
+-        } else {
+-            error("ret or jmp expected at the end of %s", name);
+-        }
++        retpos = trace_i386_op(name, p_start, &len, &patch_bytes, exit_addrs);
+         copy_size = len;
+     }
+-#endif    
+ #elif defined(HOST_PPC)
+     {
+         uint8_t *p;
+@@ -1675,6 +2373,13 @@
+     }
+ 
+     if (gen_switch == 2) {
++#if defined(HOST_I386) || defined(HOST_X86_64)
++        if (patch_bytes != -1)
++            copy_size += patch_bytes;
++#ifdef DEBUG_OP
++        copy_size += 2;
++#endif
++#endif
+         fprintf(outfile, "DEF(%s, %d, %d)\n", name + 3, nb_args, copy_size);
+     } else if (gen_switch == 1) {
+ 
+@@ -1809,6 +2514,82 @@
+         /* patch relocations */
+ #if defined(HOST_I386)
+             {
++#ifdef CONFIG_FORMAT_MACH
++                struct scattered_relocation_info *scarel;
++                struct relocation_info * rel;
++				char final_sym_name[256];
++				const char *sym_name;
++				const char *p;
++				int slide, sslide;
++				int i;
++	
++				for (i = 0, rel = relocs; i < nb_relocs; i++, rel++) {
++					unsigned int offset, length, value = 0;
++					unsigned int type, pcrel, isym = 0;
++					unsigned int usesym = 0;
++				
++					if (R_SCATTERED & rel->r_address) {
++						scarel = (struct scattered_relocation_info*)rel;
++						offset = (unsigned int)scarel->r_address;
++						length = scarel->r_length;
++						pcrel = scarel->r_pcrel;
++						type = scarel->r_type;
++						value = scarel->r_value;
++					}
++                    else {
++						value = isym = rel->r_symbolnum;
++						usesym = (rel->r_extern);
++						offset = rel->r_address;
++						length = rel->r_length;
++						pcrel = rel->r_pcrel;
++						type = rel->r_type;
++					}
++				
++					slide = offset - start_offset;
++		
++					if (!(offset >= start_offset && offset < start_offset + size)) 
++						continue;  /* not in our range */
++
++					sym_name = get_reloc_name(rel, &sslide);
++					
++					if (usesym && symtab[isym].n_type & N_STAB)
++						continue; /* don't handle STAB (debug sym) */
++					
++					if (sym_name && strstart(sym_name, "__op_jmp", &p)) {
++						int n;
++						n = strtol(p, NULL, 10);
++						fprintf(outfile, "    jmp_offsets[%d] = %d + (gen_code_ptr - gen_code_buf);\n", n, slide);
++						continue; /* Nothing more to do */
++					}
++					
++					if (!sym_name) {
++						fprintf(outfile, "/* #warning relocation not handled in %s (value 0x%x, %s, offset 0x%x, length 0x%x, %s, type 0x%x) */\n",
++                                name, value, usesym ? "use sym" : "don't use sym", offset, length, pcrel ? "pcrel":"", type);
++						continue; /* dunno how to handle without final_sym_name */
++					}
++
++                    get_reloc_expr(final_sym_name, sizeof(final_sym_name),
++                                   sym_name);
++
++                    if (length != 2)
++                        error("unsupported %d-bit relocation", 8 * (1 << length));
++
++					switch (type) {
++					case GENERIC_RELOC_VANILLA:
++                        if (pcrel || strstart(sym_name,"__op_gen_label",&p)) {
++                            fprintf(outfile, "    *(uint32_t *)(gen_code_ptr + %d) = %s - (long)(gen_code_ptr + %d) - 4;\n",
++                                    slide, final_sym_name, slide);
++                        }
++                        else {
++                            fprintf(outfile, "    *(uint32_t *)(gen_code_ptr + %d) = (%s + %d);\n", 
++                                    slide, final_sym_name, sslide);
++                        }
++                        break;
++                    default:
++                        error("unsupported i386 relocation (%d)", type);
++                    }
++                }
++#else
+                 char name[256];
+                 int type;
+                 int addend;
+@@ -1879,7 +2660,44 @@
+ #error unsupport object format
+ #endif
+                 }
++               }
++#endif
++                /* Replace the marker instructions with the actual opcodes.  */
++                for (i = 0; exit_addrs[i] != -1; i++) {
++                    int op;
++                    switch (p_start[exit_addrs[i]])
++                      {
++                      case 0xf4: op = 0xc3; break; /* hlt -> ret */
++                      case 0xfa: op = 0xe9; break; /* cli -> jmp */
++                      case 0xfb: op = 0xe9; break; /* sti -> jmp */
++                      default: error("Internal error");
++                      }
++                    fprintf(outfile, 
++                            "    *(uint8_t *)(gen_code_ptr + %d) = 0x%x;\n",
++                            exit_addrs[i], op);
++                }
++                /* Fix up the return instruction.  */
++                if (patch_bytes != -1) {
++                    if (patch_bytes) {
++                        fprintf(outfile, "    memcpy(gen_code_ptr + %d,"
++                                "gen_code_ptr + %d, %d);\n",
++                                copy_size, retpos, patch_bytes);
++                    }
++                    fprintf(outfile,
++                            "    *(uint8_t *)(gen_code_ptr + %d) = 0xe9;\n",
++                            retpos);
++                    fprintf(outfile,
++                            "    *(uint32_t *)(gen_code_ptr + %d) = 0x%x;\n",
++                            retpos + 1, copy_size - (retpos + 5));
++                    
++                    copy_size += patch_bytes;
+                 }
++#ifdef DEBUG_OP
++                fprintf(outfile,
++                        "    *(uint16_t *)(gen_code_ptr + %d) = 0x9090;\n",
++                        copy_size);
++                copy_size += 2;
++#endif
+             }
+ #elif defined(HOST_X86_64)
+             {
+@@ -1913,6 +2731,42 @@
+                     }
+                 }
+                 }
++                /* Replace the marker instructions with the actual opcodes.  */
++                for (i = 0; exit_addrs[i] != -1; i++) {
++                    int op;
++                    switch (p_start[exit_addrs[i]])
++                      {
++                      case 0xf4: op = 0xc3; break; /* hlt -> ret */
++                      case 0xfa: op = 0xe9; break; /* cli -> jmp */
++                      case 0xfb: op = 0xe9; break; /* sti -> jmp */
++                      default: error("Internal error");
++                      }
++                    fprintf(outfile, 
++                            "    *(uint8_t *)(gen_code_ptr + %d) = 0x%x;\n",
++                            exit_addrs[i], op);
++                }
++                /* Fix up the return instruction.  */
++                if (patch_bytes != -1) {
++                    if (patch_bytes) {
++                        fprintf(outfile, "    memcpy(gen_code_ptr + %d,"
++                                "gen_code_ptr + %d, %d);\n",
++                                copy_size, retpos, patch_bytes);
++                    }
++                    fprintf(outfile,
++                            "    *(uint8_t *)(gen_code_ptr + %d) = 0xe9;\n",
++                            retpos);
++                    fprintf(outfile,
++                            "    *(uint32_t *)(gen_code_ptr + %d) = 0x%x;\n",
++                            retpos + 1, copy_size - (retpos + 5));
++                    
++                    copy_size += patch_bytes;
++                }
++#ifdef DEBUG_OP
++                fprintf(outfile,
++                        "    *(uint16_t *)(gen_code_ptr + %d) = 0x9090;\n",
++                        copy_size);
++                copy_size += 2;
++#endif
+             }
+ #elif defined(HOST_PPC)
+             {
+diff -u -r exec-all.h exec-all.h
+--- exec-all.h	2007-02-06 00:01:54.000000000 +0100
++++ exec-all.h	2007-07-25 19:21:53.000000000 +0200
+@@ -326,16 +326,31 @@
+ 
+ #elif defined(__i386__) && defined(USE_DIRECT_JUMP)
+ 
+-/* we patch the jump instruction directly */
++/* we patch the jump instruction directly.  Use sti in place of the actual
++   jmp instruction so that dyngen can patch in the correct result.  */
++#if defined(__APPLE__)
++/* XXX Different relocations are generated for MacOS X for Intel
++   (please as from cctools).  */
+ #define GOTO_TB(opname, tbparam, n)\
+ do {\
+-    asm volatile (".section .data\n"\
++    asm volatile (ASM_DATA_SECTION\
+ 		  ASM_OP_LABEL_NAME(n, opname) ":\n"\
+ 		  ".long 1f\n"\
+ 		  ASM_PREVIOUS_SECTION \
+-                  "jmp " ASM_NAME(__op_jmp) #n "\n"\
++                  "sti;.long " ASM_NAME(__op_jmp) #n "\n"\
+ 		  "1:\n");\
+ } while (0)
++#else
++#define GOTO_TB(opname, tbparam, n)\
++do {\
++    asm volatile (ASM_DATA_SECTION\
++		  ASM_OP_LABEL_NAME(n, opname) ":\n"\
++		  ".long 1f\n"\
++		  ASM_PREVIOUS_SECTION \
++                  "sti;.long " ASM_NAME(__op_jmp) #n " - 1f\n"\
++		  "1:\n");\
++} while (0)
++#endif
+ 
+ #else
+ 
+diff -u -r hw/pc.c hw/pc.c
+--- hw/pc.c	2007-02-06 00:01:54.000000000 +0100
++++ hw/pc.c	2007-07-25 19:21:53.000000000 +0200
+@@ -154,7 +154,7 @@
+ }
+ 
+ /* hd_table must contain 4 block drivers */
+-static void cmos_init(int ram_size, int boot_device, BlockDriverState **hd_table)
++static void cmos_init(int ram_size, int boot_device, int boot_device_2, BlockDriverState **hd_table)
+ {
+     RTCState *s = rtc_state;
+     int val;
+@@ -185,19 +185,32 @@
+     rtc_set_memory(s, 0x34, val);
+     rtc_set_memory(s, 0x35, val >> 8);
+     
++    int bd2_val;
++    switch(boot_device_2) {
++    case 'a':
++        bd2_val = 0x10; 
++        break;
++    case 'c':
++        bd2_val = 0x20; 
++        break;
++    case 'd':
++        bd2_val = 0x30; 
++        break;
++    }
++    
+     switch(boot_device) {
+     case 'a':
+     case 'b':
+-        rtc_set_memory(s, 0x3d, 0x01); /* floppy boot */
++        rtc_set_memory(s, 0x3d, bd2_val | 0x01); /* floppy boot */
+         if (!fd_bootchk)
+-            rtc_set_memory(s, 0x38, 0x01); /* disable signature check */
++            rtc_set_memory(s, 0x38, bd2_val | 0x01); /* disable signature check */
+         break;
+     default:
+     case 'c':
+-        rtc_set_memory(s, 0x3d, 0x02); /* hard drive boot */
++        rtc_set_memory(s, 0x3d, bd2_val | 0x02); /* hard drive boot */
+         break;
+     case 'd':
+-        rtc_set_memory(s, 0x3d, 0x03); /* CD-ROM boot */
++        rtc_set_memory(s, 0x3d, bd2_val | 0x03); /* CD-ROM boot */
+         break;
+     }
+ 
+@@ -443,7 +456,8 @@
+ }
+ 
+ /* PC hardware initialisation */
+-static void pc_init1(int ram_size, int vga_ram_size, int boot_device,
++static void pc_init1(int ram_size, int vga_ram_size,
++                     int boot_device, int boot_device_2,
+                      DisplayState *ds, const char **fd_filename, int snapshot,
+                      const char *kernel_filename, const char *kernel_cmdline,
+                      const char *initrd_filename,
+@@ -692,7 +706,7 @@
+ 
+     floppy_controller = fdctrl_init(6, 2, 0, 0x3f0, fd_table);
+ 
+-    cmos_init(ram_size, boot_device, bs_table);
++    cmos_init(ram_size, boot_device, boot_device_2, bs_table);
+ 
+     if (pci_enabled && usb_enabled) {
+         usb_uhci_init(pci_bus, piix3_devfn + 2);
+@@ -730,27 +744,29 @@
+ #endif
+ }
+ 
+-static void pc_init_pci(int ram_size, int vga_ram_size, int boot_device,
++static void pc_init_pci(int ram_size, int vga_ram_size,
++                        int boot_device, int boot_device_2,
+                         DisplayState *ds, const char **fd_filename, 
+                         int snapshot, 
+                         const char *kernel_filename, 
+                         const char *kernel_cmdline,
+                         const char *initrd_filename)
+ {
+-    pc_init1(ram_size, vga_ram_size, boot_device,
++    pc_init1(ram_size, vga_ram_size, boot_device, boot_device_2,
+              ds, fd_filename, snapshot,
+              kernel_filename, kernel_cmdline,
+              initrd_filename, 1);
+ }
+ 
+-static void pc_init_isa(int ram_size, int vga_ram_size, int boot_device,
++static void pc_init_isa(int ram_size, int vga_ram_size,
++                        int boot_device, int boot_device_2,
+                         DisplayState *ds, const char **fd_filename, 
+                         int snapshot, 
+                         const char *kernel_filename, 
+                         const char *kernel_cmdline,
+                         const char *initrd_filename)
+ {
+-    pc_init1(ram_size, vga_ram_size, boot_device,
++    pc_init1(ram_size, vga_ram_size, boot_device, boot_device_2,
+              ds, fd_filename, snapshot,
+              kernel_filename, kernel_cmdline,
+              initrd_filename, 0);
+diff -u -r hw/vga.c hw/vga.c
+--- hw/vga.c	2007-02-06 00:01:54.000000000 +0100
++++ hw/vga.c	2007-07-25 19:21:53.000000000 +0200
+@@ -814,22 +814,38 @@
+ 
+ static inline unsigned int rgb_to_pixel8(unsigned int r, unsigned int g, unsigned b)
+ {
++#if __LITTLE_ENDIAN__
++    return ((b >> 5) << 5) | ((g >> 5) << 2) | (r >> 6);
++#else
+     return ((r >> 5) << 5) | ((g >> 5) << 2) | (b >> 6);
++#endif
+ }
+ 
+ static inline unsigned int rgb_to_pixel15(unsigned int r, unsigned int g, unsigned b)
+ {
++#if __LITTLE_ENDIAN__
++    return ((b >> 3) << 10) | ((g >> 3) << 5) | (r >> 3);
++#else
+     return ((r >> 3) << 10) | ((g >> 3) << 5) | (b >> 3);
++#endif
+ }
+ 
+ static inline unsigned int rgb_to_pixel16(unsigned int r, unsigned int g, unsigned b)
+ {
++#if __LITTLE_ENDIAN__
++    return ((b >> 3) << 11) | ((g >> 2) << 5) | (r >> 3);
++#else
+     return ((r >> 3) << 11) | ((g >> 2) << 5) | (b >> 3);
++#endif
+ }
+ 
+ static inline unsigned int rgb_to_pixel32(unsigned int r, unsigned int g, unsigned b)
+ {
++#if __LITTLE_ENDIAN__
++    return (b << 16) | (g << 8) | r;
++#else
+     return (r << 16) | (g << 8) | b;
++#endif
+ }
+ 
+ static inline unsigned int rgb_to_pixel32bgr(unsigned int r, unsigned int g, unsigned b)
+diff -u -r softmmu_header.h softmmu_header.h
+--- softmmu_header.h	2007-02-06 00:01:54.000000000 +0100
++++ softmmu_header.h	2007-07-25 19:21:53.000000000 +0200
+@@ -108,7 +108,7 @@
+ void REGPARM(2) glue(glue(__st, SUFFIX), MMUSUFFIX)(target_ulong addr, DATA_TYPE v, int is_user);
+ 
+ #if (DATA_SIZE <= 4) && (TARGET_LONG_BITS == 32) && defined(__i386__) && \
+-    (ACCESS_TYPE <= 1) && defined(ASM_SOFTMMU)
++    (ACCESS_TYPE <= 1) && defined(ASM_SOFTMMU) && (__GNUC__ < 4)
+ 
+ #define CPU_TLB_ENTRY_BITS 4
+ 
+@@ -150,7 +150,7 @@
+                   "m" (*(uint32_t *)offsetof(CPUState, tlb_table[CPU_MEM_INDEX][0].addr_read)),
+                   "i" (CPU_MEM_INDEX),
+                   "m" (*(uint8_t *)&glue(glue(__ld, SUFFIX), MMUSUFFIX))
+-                  : "%eax", "%ecx", "%edx", "memory", "cc");
++                  : "%eax", "%edx", "memory", "cc");
+     return res;
+ }
+ 
+@@ -197,13 +197,14 @@
+                   "m" (*(uint32_t *)offsetof(CPUState, tlb_table[CPU_MEM_INDEX][0].addr_read)),
+                   "i" (CPU_MEM_INDEX),
+                   "m" (*(uint8_t *)&glue(glue(__ld, SUFFIX), MMUSUFFIX))
+-                  : "%eax", "%ecx", "%edx", "memory", "cc");
++                  : "%eax", "%edx", "memory", "cc");
+     return res;
+ }
+ #endif
+ 
+-static inline void glue(glue(st, SUFFIX), MEMSUFFIX)(target_ulong ptr, RES_TYPE v)
++static inline void glue(glue(st, SUFFIX), MEMSUFFIX)(target_ulong ptr, RES_TYPE val)
+ {
++    RES_TYPE v = val;
+     asm volatile ("movl %0, %%edx\n"
+                   "movl %0, %%eax\n"
+                   "shrl %3, %%edx\n"
+@@ -240,16 +241,14 @@
+                   "2:\n"
+                   : 
+                   : "r" (ptr), 
+-/* NOTE: 'q' would be needed as constraint, but we could not use it
+-   with T1 ! */
+-                  "r" (v), 
++                  "q" (v), 
+                   "i" ((CPU_TLB_SIZE - 1) << CPU_TLB_ENTRY_BITS), 
+                   "i" (TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS), 
+                   "i" (TARGET_PAGE_MASK | (DATA_SIZE - 1)),
+                   "m" (*(uint32_t *)offsetof(CPUState, tlb_table[CPU_MEM_INDEX][0].addr_write)),
+                   "i" (CPU_MEM_INDEX),
+                   "m" (*(uint8_t *)&glue(glue(__st, SUFFIX), MMUSUFFIX))
+-                  : "%eax", "%ecx", "%edx", "memory", "cc");
++                  : "%eax", "%edx", "memory", "cc");
+ }
+ 
+ #else
+diff -u -r target-i386/helper.c target-i386/helper.c
+--- target-i386/helper.c	2007-02-06 00:01:54.000000000 +0100
++++ target-i386/helper.c	2007-07-25 19:21:53.000000000 +0200
+@@ -29,68 +29,6 @@
+     (raise_exception_err)(a, b);\
+ } while (0)
+ #endif
+-
+-const uint8_t parity_table[256] = {
+-    CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,
+-    0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,
+-    0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,
+-    CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,
+-    0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,
+-    CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,
+-    CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,
+-    0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,
+-    0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,
+-    CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,
+-    CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,
+-    0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,
+-    CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,
+-    0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,
+-    0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,
+-    CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,
+-    0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,
+-    CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,
+-    CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,
+-    0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,
+-    CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,
+-    0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,
+-    0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,
+-    CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,
+-    CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,
+-    0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,
+-    0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,
+-    CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,
+-    0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,
+-    CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,
+-    CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,
+-    0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,
+-};
+-
+-/* modulo 17 table */
+-const uint8_t rclw_table[32] = {
+-    0, 1, 2, 3, 4, 5, 6, 7, 
+-    8, 9,10,11,12,13,14,15,
+-   16, 0, 1, 2, 3, 4, 5, 6,
+-    7, 8, 9,10,11,12,13,14,
+-};
+-
+-/* modulo 9 table */
+-const uint8_t rclb_table[32] = {
+-    0, 1, 2, 3, 4, 5, 6, 7, 
+-    8, 0, 1, 2, 3, 4, 5, 6,
+-    7, 8, 0, 1, 2, 3, 4, 5, 
+-    6, 7, 8, 0, 1, 2, 3, 4,
+-};
+-
+-const CPU86_LDouble f15rk[7] =
+-{
+-    0.00000000000000000000L,
+-    1.00000000000000000000L,
+-    3.14159265358979323851L,  /*pi*/
+-    0.30102999566398119523L,  /*lg2*/
+-    0.69314718055994530943L,  /*ln2*/
+-    1.44269504088896340739L,  /*l2e*/
+-    3.32192809488736234781L,  /*l2t*/
+-};
+     
+ /* thread support */
+ 
+@@ -3452,8 +3390,15 @@
+         nb_xmm_regs = 8 << data64;
+         addr = ptr + 0xa0;
+         for(i = 0; i < nb_xmm_regs; i++) {
++#if defined(__i386__) && __GNUC__ >= 4
++            env->xmm_regs[i].XMM_L(0) = ldl(addr);
++            env->xmm_regs[i].XMM_L(1) = ldl(addr + 4);
++            env->xmm_regs[i].XMM_L(2) = ldl(addr + 8);
++            env->xmm_regs[i].XMM_L(3) = ldl(addr + 12);
++#else
+             env->xmm_regs[i].XMM_Q(0) = ldq(addr);
+             env->xmm_regs[i].XMM_Q(1) = ldq(addr + 8);
++#endif
+             addr += 16;
+         }
+     }
+diff -u -r target-i386/op.c target-i386/op.c
+--- target-i386/op.c	2007-02-06 00:01:54.000000000 +0100
++++ target-i386/op.c	2007-07-25 19:21:53.000000000 +0200
+@@ -21,6 +21,69 @@
+ #define ASM_SOFTMMU
+ #include "exec.h"
+ 
++const uint8_t parity_table[256] = {
++    CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,
++    0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,
++    0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,
++    CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,
++    0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,
++    CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,
++    CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,
++    0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,
++    0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,
++    CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,
++    CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,
++    0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,
++    CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,
++    0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,
++    0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,
++    CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,
++    0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,
++    CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,
++    CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,
++    0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,
++    CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,
++    0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,
++    0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,
++    CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,
++    CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,
++    0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,
++    0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,
++    CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,
++    0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,
++    CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,
++    CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,
++    0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,
++};
++
++/* modulo 17 table */
++const uint8_t rclw_table[32] = {
++    0, 1, 2, 3, 4, 5, 6, 7, 
++    8, 9,10,11,12,13,14,15,
++   16, 0, 1, 2, 3, 4, 5, 6,
++    7, 8, 9,10,11,12,13,14,
++};
++
++/* modulo 9 table */
++const uint8_t rclb_table[32] = {
++    0, 1, 2, 3, 4, 5, 6, 7, 
++    8, 0, 1, 2, 3, 4, 5, 6,
++    7, 8, 0, 1, 2, 3, 4, 5, 
++    6, 7, 8, 0, 1, 2, 3, 4,
++};
++
++const CPU86_LDouble f15rk[7] =
++{
++    0.00000000000000000000L,
++    1.00000000000000000000L,
++    3.14159265358979323851L,  /*pi*/
++    0.30102999566398119523L,  /*lg2*/
++    0.69314718055994530943L,  /*ln2*/
++    1.44269504088896340739L,  /*l2e*/
++    3.32192809488736234781L,  /*l2t*/
++};
++
++    
+ /* n must be a constant to be efficient */
+ static inline target_long lshift(target_long x, int n)
+ {
+@@ -1531,6 +1594,7 @@
+     eflags = cc_table[CC_OP].compute_all();
+     eflags &= ~CC_C;
+     CC_SRC = eflags;
++    FORCE_RET();
+ }
+ 
+ void OPPROTO op_stc(void)
+@@ -1547,6 +1611,7 @@
+     eflags = cc_table[CC_OP].compute_all();
+     eflags ^= CC_C;
+     CC_SRC = eflags;
++    FORCE_RET();
+ }
+ 
+ void OPPROTO op_salc(void)
+diff -u -r target-i386/ops_sse.h target-i386/ops_sse.h
+--- target-i386/ops_sse.h	2007-02-06 00:01:54.000000000 +0100
++++ target-i386/ops_sse.h	2007-07-25 19:21:53.000000000 +0200
+@@ -34,6 +34,12 @@
+ #define Q(n) XMM_Q(n)
+ #define SUFFIX _xmm
+ #endif
++#if defined(__i386__) && __GNUC__ >= 4
++#define RegCopy(d, s) __builtin_memcpy(&(d), &(s), sizeof(d))
++#endif
++#ifndef RegCopy
++#define RegCopy(d, s) d = s
++#endif
+ 
+ void OPPROTO glue(op_psrlw, SUFFIX)(void)
+ {
+@@ -589,7 +595,7 @@
+     r.W(1) = s->W((order >> 2) & 3);
+     r.W(2) = s->W((order >> 4) & 3);
+     r.W(3) = s->W((order >> 6) & 3);
+-    *d = r;
++    RegCopy(*d, r);
+ }
+ #else
+ void OPPROTO op_shufps(void)
+diff -u -r target-ppc/exec.h target-ppc/exec.h
+--- target-ppc/exec.h	2007-02-06 00:01:54.000000000 +0100
++++ target-ppc/exec.h	2007-07-25 19:21:53.000000000 +0200
+@@ -37,11 +37,7 @@
+ #define FT1 (env->ft1)
+ #define FT2 (env->ft2)
+ 
+-#if defined (DEBUG_OP)
+-# define RETURN() __asm__ __volatile__("nop" : : : "memory");
+-#else
+-# define RETURN() __asm__ __volatile__("" : : : "memory");
+-#endif
++#define RETURN() FORCE_RET()
+ 
+ #include "cpu.h"
+ #include "exec-all.h"
+diff -u -r vl.c vl.c
+--- vl.c	2007-02-06 00:01:54.000000000 +0100
++++ vl.c	2007-07-25 19:21:53.000000000 +0200
+@@ -131,6 +131,7 @@
+ const char* keyboard_layout = NULL;
+ int64_t ticks_per_sec;
+ int boot_device = 'c';
++int boot_device_2 = 'd';
+ int ram_size;
+ int pit_min_timer_count = 0;
+ int nb_nics;
+@@ -6021,7 +6022,11 @@
+            "-hda/-hdb file  use 'file' as IDE hard disk 0/1 image\n"
+            "-hdc/-hdd file  use 'file' as IDE hard disk 2/3 image\n"
+            "-cdrom file     use 'file' as IDE cdrom image (cdrom is ide1 master)\n"
++#ifdef TARGET_I386
++           "-boot d1(,d2)   boot on floppy (a), hard disk (c), CD-ROM (d), or network (n)\n"
++#else
+            "-boot [a|c|d|n] boot on floppy (a), hard disk (c), CD-ROM (d), or network (n)\n"
++#endif
+            "-snapshot       write to temporary files instead of disk image files\n"
+ #ifdef CONFIG_SDL
+            "-no-quit        disable SDL window close capability\n"
+@@ -6721,6 +6726,15 @@
+                 break;
+             case QEMU_OPTION_boot:
+                 boot_device = optarg[0];
++#ifdef TARGET_I386
++                if (strlen(optarg) == 3) { //we have a second bootdevice
++                    boot_device_2 = optarg[2];
++                    if (boot_device_2 != 'a' && boot_device_2 != 'c' && boot_device_2 != 'd') {
++                        fprintf(stderr, "qemu: invalid second boot device '%c'\n", boot_device_2);
++                        exit(1);
++                    }
++                }
++#endif
+                 if (boot_device != 'a' && 
+ #if defined(TARGET_SPARC) || defined(TARGET_I386)
+ 		    // Network boot
+@@ -7199,8 +7213,11 @@
+                 qemu_chr_printf(parallel_hds[i], "parallel%d console\r\n", i);
+         }
+     }
+-
++#ifdef TARGET_I386
++    machine->init(ram_size, vga_ram_size, boot_device, boot_device_2,
++#else
+     machine->init(ram_size, vga_ram_size, boot_device,
++#endif
+                   ds, fd_filename, snapshot,
+                   kernel_filename, kernel_cmdline, initrd_filename);
+ 
+diff -u -r vl.h vl.h
+--- vl.h	2007-02-06 00:01:54.000000000 +0100
++++ vl.h	2007-07-25 19:21:53.000000000 +0200
+@@ -683,6 +683,9 @@
+ 
+ typedef void QEMUMachineInitFunc(int ram_size, int vga_ram_size, 
+                                  int boot_device,
++#ifdef TARGET_I386
++                                 int boot_device_2,
++#endif
+              DisplayState *ds, const char **fd_filename, int snapshot,
+              const char *kernel_filename, const char *kernel_cmdline,
+              const char *initrd_filename);

Added: trunk/dports/emulators/qemu-usermode/files/sparc-fp.patch
===================================================================
--- trunk/dports/emulators/qemu-usermode/files/sparc-fp.patch	                        (rev 0)
+++ trunk/dports/emulators/qemu-usermode/files/sparc-fp.patch	2007-07-26 16:36:57 UTC (rev 27270)
@@ -0,0 +1,18 @@
+diff -urN qemu-0.8.2.old/target-sparc/op_helper.c qemu-0.8.2/target-sparc/op_helper.c
+--- target-sparc/op_helper.c.orig	2006-07-22 19:23:34.000000000 +0200
++++ target-sparc/op_helper.c	2006-08-01 09:46:34.000000000 +0200
+@@ -12,12 +12,12 @@
+ #ifdef USE_INT_TO_FLOAT_HELPERS
+ void do_fitos(void)
+ {
+-    FT0 = int32_to_float32(*((int32_t *)&FT1));
++    FT0 = int32_to_float32(*((int32_t *)&FT1), &env->fp_status);
+ }
+ 
+ void do_fitod(void)
+ {
+-    DT0 = int32_to_float64(*((int32_t *)&FT1));
++    DT0 = int32_to_float64(*((int32_t *)&FT1), &env->fp_status);
+ }
+ #endif
+ 

-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.macosforge.org/pipermail/macports-changes/attachments/20070726/92345e8a/attachment.html


More information about the macports-changes mailing list