SHA256
1
0
forked from pool/qemu
OBS User unknown 2007-07-10 16:55:54 +00:00 committed by Git OBS Bridge
parent c828f62526
commit 7718c724e8
51 changed files with 8851 additions and 4199 deletions

View File

@ -1,380 +0,0 @@
diff -rpu qemu-0.9.0.orig/block.c qemu-0.9.0/block.c
--- qemu-0.9.0.orig/block.c 2007-02-05 23:01:54.000000000 +0000
+++ qemu-0.9.0/block.c 2007-02-20 22:41:03.000000000 +0000
@@ -539,13 +539,22 @@ int bdrv_write(BlockDriverState *bs, int
return -ENOMEDIUM;
if (bs->read_only)
return -EACCES;
+ if (sector_num < 0)
+ return -EINVAL;
if (sector_num == 0 && bs->boot_sector_enabled && nb_sectors > 0) {
memcpy(bs->boot_sector_data, buf, 512);
}
if (drv->bdrv_pwrite) {
int ret, len;
+ unsigned ns;
+
+ ns = sector_num * 512;
len = nb_sectors * 512;
- ret = drv->bdrv_pwrite(bs, sector_num * 512, buf, len);
+
+ if (ns < 0)
+ return -EINVAL;
+
+ ret = drv->bdrv_pwrite(bs, ns, buf, len);
if (ret < 0)
return ret;
else if (ret != len)
diff -rpu qemu-0.9.0.orig/hw/cirrus_vga.c qemu-0.9.0/hw/cirrus_vga.c
--- qemu-0.9.0.orig/hw/cirrus_vga.c 2007-02-05 23:01:54.000000000 +0000
+++ qemu-0.9.0/hw/cirrus_vga.c 2007-02-21 17:00:09.585042632 +0000
@@ -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)
vga_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;
@@ -1857,7 +1887,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;
@@ -1880,7 +1910,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;
diff -rpu qemu-0.9.0.orig/hw/cirrus_vga_rop.h qemu-0.9.0/hw/cirrus_vga_rop.h
--- qemu-0.9.0.orig/hw/cirrus_vga_rop.h 2007-02-05 23:01:54.000000000 +0000
+++ qemu-0.9.0/hw/cirrus_vga_rop.h 2007-02-21 01:45:32.000000000 +0000
@@ -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);
diff -rpu qemu-0.9.0.orig/hw/dma.c qemu-0.9.0/hw/dma.c
--- qemu-0.9.0.orig/hw/dma.c 2007-02-05 23:01:54.000000000 +0000
+++ qemu-0.9.0/hw/dma.c 2007-02-20 21:53:41.000000000 +0000
@@ -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);
}
diff -rpu qemu-0.9.0.orig/hw/fdc.c qemu-0.9.0/hw/fdc.c
--- qemu-0.9.0.orig/hw/fdc.c 2007-02-05 23:01:54.000000000 +0000
+++ qemu-0.9.0/hw/fdc.c 2007-02-20 23:41:01.000000000 +0000
@@ -1100,8 +1100,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];
diff -rpu qemu-0.9.0.orig/hw/i8259.c qemu-0.9.0/hw/i8259.c
--- qemu-0.9.0.orig/hw/i8259.c 2007-02-05 23:01:54.000000000 +0000
+++ qemu-0.9.0/hw/i8259.c 2007-02-20 21:53:41.000000000 +0000
@@ -299,9 +299,11 @@ static void pic_ioport_write(void *opaqu
s->init_state = 1;
s->init4 = val & 1;
if (val & 0x02)
- hw_error("single mode not supported");
+ /* hw_error("single mode not supported"); */
+ return;
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;
diff -rpu qemu-0.9.0.orig/hw/ne2000.c qemu-0.9.0/hw/ne2000.c
--- qemu-0.9.0.orig/hw/ne2000.c 2007-02-05 23:01:54.000000000 +0000
+++ qemu-0.9.0/hw/ne2000.c 2007-02-20 21:53:41.000000000 +0000
@@ -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;
diff -rpu qemu-0.9.0.orig/hw/pc.c qemu-0.9.0/hw/pc.c
--- qemu-0.9.0.orig/hw/pc.c 2007-02-05 23:01:54.000000000 +0000
+++ qemu-0.9.0/hw/pc.c 2007-02-20 21:53:41.000000000 +0000
@@ -299,7 +299,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
@@ -322,8 +323,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
diff -rpu qemu-0.9.0.orig/hw/sb16.c qemu-0.9.0/hw/sb16.c
--- qemu-0.9.0.orig/hw/sb16.c 2007-02-05 23:01:54.000000000 +0000
+++ qemu-0.9.0/hw/sb16.c 2007-02-20 21:53:41.000000000 +0000
@@ -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;
diff -rpu qemu-0.9.0.orig/slirp/slirp.c qemu-0.9.0/slirp/slirp.c
--- qemu-0.9.0.orig/slirp/slirp.c 2007-02-05 23:01:54.000000000 +0000
+++ qemu-0.9.0/slirp/slirp.c 2007-02-20 21:53:41.000000000 +0000
@@ -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);
diff -rpu qemu-0.9.0.orig/target-i386/translate.c qemu-0.9.0/target-i386/translate.c
--- qemu-0.9.0.orig/target-i386/translate.c 2007-02-05 23:01:54.000000000 +0000
+++ qemu-0.9.0/target-i386/translate.c 2007-02-20 21:53:41.000000000 +0000
@@ -5326,7 +5326,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 */
@@ -5374,6 +5379,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);
@@ -5383,6 +5389,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) {
diff -rpu qemu-0.9.0.orig/vl.c qemu-0.9.0/vl.c
--- qemu-0.9.0.orig/vl.c 2007-02-05 23:01:54.000000000 +0000
+++ qemu-0.9.0/vl.c 2007-02-20 21:53:41.000000000 +0000
@@ -3329,8 +3329,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;
@@ -3361,7 +3361,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;
@@ -3400,7 +3401,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;

View File

@ -274,309 +274,3 @@
- /* These must appear regardless of . */
+ /DISCARD/ : { *(.note.GNU-stack) }
}
--- ppc.ld
+++ ppc.ld
@@ -1,116 +1,200 @@
-/* ld script to make i386 Linux kernel
- * Written by Martin Mares <mj@atrey.karlin.mff.cuni.cz>;
- */
-OUTPUT_FORMAT("elf32-powerpc", "elf32-powerpc", "elf32-powerpc")
-OUTPUT_ARCH(powerpc)
-SEARCH_DIR(/lib); SEARCH_DIR(/usr/lib); SEARCH_DIR(/usr/local/lib); SEARCH_DIR(/usr/alpha-unknown-linux-gnu/lib);
+/* Default linker script, for normal executables */
+OUTPUT_FORMAT("elf32-powerpc", "elf32-powerpc",
+ "elf32-powerpc")
+OUTPUT_ARCH(powerpc:common)
ENTRY(_start)
+SEARCH_DIR("/usr/powerpc-suse-linux/lib"); SEARCH_DIR("/usr/local/lib"); SEARCH_DIR("/lib"); SEARCH_DIR("/usr/lib");
SECTIONS
{
/* Read-only sections, merged into text segment: */
- . = 0x60000000 + SIZEOF_HEADERS;
- .interp : { *(.interp) }
- .hash : { *(.hash) }
- .dynsym : { *(.dynsym) }
- .dynstr : { *(.dynstr) }
- .gnu.version : { *(.gnu.version) }
- .gnu.version_d : { *(.gnu.version_d) }
- .gnu.version_r : { *(.gnu.version_r) }
- .rel.text :
- { *(.rel.text) *(.rel.gnu.linkonce.t*) }
- .rela.text :
- { *(.rela.text) *(.rela.gnu.linkonce.t*) }
- .rel.data :
- { *(.rel.data) *(.rel.gnu.linkonce.d*) }
- .rela.data :
- { *(.rela.data) *(.rela.gnu.linkonce.d*) }
- .rel.rodata :
- { *(.rel.rodata) *(.rel.gnu.linkonce.r*) }
- .rela.rodata :
- { *(.rela.rodata) *(.rela.gnu.linkonce.r*) }
- .rel.got : { *(.rel.got) }
- .rela.got : { *(.rela.got) }
- .rel.ctors : { *(.rel.ctors) }
- .rela.ctors : { *(.rela.ctors) }
- .rel.dtors : { *(.rel.dtors) }
- .rela.dtors : { *(.rela.dtors) }
- .rel.init : { *(.rel.init) }
- .rela.init : { *(.rela.init) }
- .rel.fini : { *(.rel.fini) }
- .rela.fini : { *(.rela.fini) }
- .rel.bss : { *(.rel.bss) }
- .rela.bss : { *(.rela.bss) }
- .rel.plt : { *(.rel.plt) }
- .rela.plt : { *(.rela.plt) }
- .init : { *(.init) } =0x47ff041f
- .text :
+ PROVIDE (__executable_start = 0x60000000); . = 0x60000000 + SIZEOF_HEADERS;
+ .interp : { *(.interp) }
+ .hash : { *(.hash) }
+ .dynsym : { *(.dynsym) }
+ .dynstr : { *(.dynstr) }
+ .gnu.version : { *(.gnu.version) }
+ .gnu.version_d : { *(.gnu.version_d) }
+ .gnu.version_r : { *(.gnu.version_r) }
+ .rel.init : { *(.rel.init) }
+ .rela.init : { *(.rela.init) }
+ .rel.text : { *(.rel.text .rel.text.* .rel.gnu.linkonce.t.*) }
+ .rela.text : { *(.rela.text .rela.text.* .rela.gnu.linkonce.t.*) }
+ .rel.fini : { *(.rel.fini) }
+ .rela.fini : { *(.rela.fini) }
+ .rel.rodata : { *(.rel.rodata .rel.rodata.* .rel.gnu.linkonce.r.*) }
+ .rela.rodata : { *(.rela.rodata .rela.rodata.* .rela.gnu.linkonce.r.*) }
+ .rel.data.rel.ro : { *(.rel.data.rel.ro*) }
+ .rela.data.rel.ro : { *(.rel.data.rel.ro*) }
+ .rel.data : { *(.rel.data .rel.data.* .rel.gnu.linkonce.d.*) }
+ .rela.data : { *(.rela.data .rela.data.* .rela.gnu.linkonce.d.*) }
+ .rel.tdata : { *(.rel.tdata .rel.tdata.* .rel.gnu.linkonce.td.*) }
+ .rela.tdata : { *(.rela.tdata .rela.tdata.* .rela.gnu.linkonce.td.*) }
+ .rel.tbss : { *(.rel.tbss .rel.tbss.* .rel.gnu.linkonce.tb.*) }
+ .rela.tbss : { *(.rela.tbss .rela.tbss.* .rela.gnu.linkonce.tb.*) }
+ .rel.ctors : { *(.rel.ctors) }
+ .rela.ctors : { *(.rela.ctors) }
+ .rel.dtors : { *(.rel.dtors) }
+ .rela.dtors : { *(.rela.dtors) }
+ .rel.got : { *(.rel.got) }
+ .rela.got : { *(.rela.got) }
+ .rela.got1 : { *(.rela.got1) }
+ .rela.got2 : { *(.rela.got2) }
+ .rel.sdata : { *(.rel.sdata .rel.sdata.* .rel.gnu.linkonce.s.*) }
+ .rela.sdata : { *(.rela.sdata .rela.sdata.* .rela.gnu.linkonce.s.*) }
+ .rel.sbss : { *(.rel.sbss .rel.sbss.* .rel.gnu.linkonce.sb.*) }
+ .rela.sbss : { *(.rela.sbss .rela.sbss.* .rela.gnu.linkonce.sb.*) }
+ .rel.sdata2 : { *(.rel.sdata2 .rel.sdata2.* .rel.gnu.linkonce.s2.*) }
+ .rela.sdata2 : { *(.rela.sdata2 .rela.sdata2.* .rela.gnu.linkonce.s2.*) }
+ .rel.sbss2 : { *(.rel.sbss2 .rel.sbss2.* .rel.gnu.linkonce.sb2.*) }
+ .rela.sbss2 : { *(.rela.sbss2 .rela.sbss2.* .rela.gnu.linkonce.sb2.*) }
+ .rel.bss : { *(.rel.bss .rel.bss.* .rel.gnu.linkonce.b.*) }
+ .rela.bss : { *(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*) }
+ .rel.plt : { *(.rel.plt) }
+ .rela.plt : { *(.rela.plt) }
+ .init :
{
- *(.text)
+ KEEP (*(.init))
+ } =0
+ .text :
+ {
+ *(.text .stub .text.* .gnu.linkonce.t.*)
+ KEEP (*(.text.*personality*))
/* .gnu.warning sections are handled specially by elf32.em. */
*(.gnu.warning)
- *(.gnu.linkonce.t*)
- } =0x47ff041f
- _etext = .;
+ *(.glink)
+ } =0
+ .fini :
+ {
+ KEEP (*(.fini))
+ } =0
+ PROVIDE (__etext = .);
+ PROVIDE (_etext = .);
PROVIDE (etext = .);
- .fini : { *(.fini) } =0x47ff041f
- . = ALIGN(32 / 8);
- PROVIDE (__preinit_array_start = .);
- .preinit_array : { *(.preinit_array) }
- PROVIDE (__preinit_array_end = .);
- PROVIDE (__init_array_start = .);
- .init_array : { *(.init_array) }
- PROVIDE (__init_array_end = .);
- PROVIDE (__fini_array_start = .);
- .fini_array : { *(.fini_array) }
- PROVIDE (__fini_array_end = .);
- .rodata : { *(.rodata) *(.gnu.linkonce.r*) }
- .rodata1 : { *(.rodata1) }
- .reginfo : { *(.reginfo) }
+ .rodata : { *(.rodata .rodata.* .gnu.linkonce.r.*) }
+ .rodata1 : { *(.rodata1) }
+ .sdata2 :
+ {
+ PROVIDE (_SDA2_BASE_ = 32768);
+ *(.sdata2 .sdata2.* .gnu.linkonce.s2.*)
+ }
+ .sbss2 : { *(.sbss2 .sbss2.* .gnu.linkonce.sb2.*) }
+ .eh_frame_hdr : { *(.eh_frame_hdr) }
+ .eh_frame : ONLY_IF_RO { KEEP (*(.eh_frame)) }
+ .gcc_except_table : ONLY_IF_RO { *(.gcc_except_table .gcc_except_table.*) }
/* Adjust the address for the data segment. We want to adjust up to
the same address within the page on the next page up. */
- . = ALIGN(0x100000) + (. & (0x100000 - 1));
- .data :
+ . = ALIGN (0x10000) - ((0x10000 - .) & (0x10000 - 1)); . = DATA_SEGMENT_ALIGN (0x10000, 0x1000);
+ /* Exception handling */
+ .eh_frame : ONLY_IF_RW { KEEP (*(.eh_frame)) }
+ .gcc_except_table : ONLY_IF_RW { *(.gcc_except_table .gcc_except_table.*) }
+ /* Thread Local Storage sections */
+ .tdata : { *(.tdata .tdata.* .gnu.linkonce.td.*) }
+ .tbss : { *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon) }
+ .preinit_array :
+ {
+ PROVIDE_HIDDEN (__preinit_array_start = .);
+ KEEP (*(.preinit_array))
+ PROVIDE_HIDDEN (__preinit_array_end = .);
+ }
+ .init_array :
+ {
+ PROVIDE_HIDDEN (__init_array_start = .);
+ KEEP (*(.init_array))
+ PROVIDE_HIDDEN (__init_array_end = .);
+ }
+ .fini_array :
{
- *(.data)
- *(.gnu.linkonce.d*)
- CONSTRUCTORS
+ PROVIDE_HIDDEN (__fini_array_start = .);
+ KEEP (*(.fini_array))
+ PROVIDE_HIDDEN (__fini_array_end = .);
}
- .data1 : { *(.data1) }
- .ctors :
+ .ctors :
{
- *(.ctors)
+ /* gcc uses crtbegin.o to find the start of
+ the constructors, so we make sure it is
+ first. Because this is a wildcard, it
+ doesn't matter if the user does not
+ actually link against crtbegin.o; the
+ linker won't look for a file to match a
+ wildcard. The wildcard also means that it
+ doesn't matter which directory crtbegin.o
+ is in. */
+ KEEP (*crtbegin*.o(.ctors))
+ /* We don't want to include the .ctor section from
+ from the crtend.o file until after the sorted ctors.
+ The .ctor section from the crtend file contains the
+ end of ctors marker and it must be last */
+ KEEP (*(EXCLUDE_FILE (*crtend*.o ) .ctors))
+ KEEP (*(SORT(.ctors.*)))
+ KEEP (*(.ctors))
}
- .dtors :
+ .dtors :
{
- *(.dtors)
+ KEEP (*crtbegin*.o(.dtors))
+ KEEP (*(EXCLUDE_FILE (*crtend*.o ) .dtors))
+ KEEP (*(SORT(.dtors.*)))
+ KEEP (*(.dtors))
}
- .plt : { *(.plt) }
- .got : { *(.got.plt) *(.got) }
- .dynamic : { *(.dynamic) }
+ .jcr : { KEEP (*(.jcr)) }
+ .data.rel.ro : { *(.data.rel.ro.local) *(.data.rel.ro*) }
+ .got1 : { *(.got1) }
+ .got2 : { *(.got2) }
+ .dynamic : { *(.dynamic) }
+ .got : SPECIAL { *(.got) }
+ . = DATA_SEGMENT_RELRO_END (0, .);
+ .plt : SPECIAL { *(.plt) }
+ .data :
+ {
+ *(.data .data.* .gnu.linkonce.d.*)
+ KEEP (*(.gnu.linkonce.d.*personality*))
+ SORT(CONSTRUCTORS)
+ }
+ .data1 : { *(.data1) }
+ .got : SPECIAL { *(.got) }
/* We want the small data sections together, so single-instruction offsets
can access them all, and initialized data all before uninitialized, so
we can shorten the on-disk segment size. */
- .sdata : { *(.sdata) }
- _edata = .;
- PROVIDE (edata = .);
+ .sdata :
+ {
+ PROVIDE (_SDA_BASE_ = 32768);
+ *(.sdata .sdata.* .gnu.linkonce.s.*)
+ }
+ _edata = .; PROVIDE (edata = .);
__bss_start = .;
- .sbss : { *(.sbss) *(.scommon) }
- .bss :
+ .sbss :
+ {
+ PROVIDE (__sbss_start = .); PROVIDE (___sbss_start = .);
+ *(.dynsbss)
+ *(.sbss .sbss.* .gnu.linkonce.sb.*)
+ *(.scommon)
+ PROVIDE (__sbss_end = .); PROVIDE (___sbss_end = .);
+ }
+ .plt : SPECIAL { *(.plt) }
+ .bss :
{
*(.dynbss)
- *(.bss)
+ *(.bss .bss.* .gnu.linkonce.b.*)
*(COMMON)
+ /* Align here to ensure that the .bss section occupies space up to
+ _end. Align after .bss to ensure correct alignment even if the
+ .bss section disappears because there are no input sections.
+ FIXME: Why do we need it? When there is no .bss section, we don't
+ pad the .data section. */
+ . = ALIGN(. != 0 ? 32 / 8 : 1);
}
- _end = . ;
+ . = ALIGN(32 / 8);
+ . = ALIGN(32 / 8);
+ _end = .;
PROVIDE (end = .);
+ . = DATA_SEGMENT_END (.);
/* Stabs debugging sections. */
- .stab 0 : { *(.stab) }
- .stabstr 0 : { *(.stabstr) }
- .stab.excl 0 : { *(.stab.excl) }
- .stab.exclstr 0 : { *(.stab.exclstr) }
- .stab.index 0 : { *(.stab.index) }
+ .stab 0 : { *(.stab) }
+ .stabstr 0 : { *(.stabstr) }
+ .stab.excl 0 : { *(.stab.excl) }
+ .stab.exclstr 0 : { *(.stab.exclstr) }
+ .stab.index 0 : { *(.stab.index) }
.stab.indexstr 0 : { *(.stab.indexstr) }
- .comment 0 : { *(.comment) }
+ .comment 0 : { *(.comment) }
/* DWARF debug sections.
Symbols in the DWARF debugging sections are relative to the beginning
of the section so we begin them at 0. */
@@ -124,7 +208,7 @@
.debug_aranges 0 : { *(.debug_aranges) }
.debug_pubnames 0 : { *(.debug_pubnames) }
/* DWARF 2 */
- .debug_info 0 : { *(.debug_info) }
+ .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) }
.debug_abbrev 0 : { *(.debug_abbrev) }
.debug_line 0 : { *(.debug_line) }
.debug_frame 0 : { *(.debug_frame) }
@@ -136,5 +220,6 @@
.debug_funcnames 0 : { *(.debug_funcnames) }
.debug_typenames 0 : { *(.debug_typenames) }
.debug_varnames 0 : { *(.debug_varnames) }
- /* These must appear regardless of . */
+ /DISCARD/ : { *(.fixup) }
+ /DISCARD/ : { *(.note.GNU-stack) }
}

View File

@ -1,17 +1,8 @@
--- qemu-binfmt-conf.sh
+++ qemu-binfmt-conf.sh
@@ -2,38 +2,46 @@
# enable automatic i386/ARM/SPARC/PPC program execution by the kernel
# load the binfmt_misc module
-/sbin/modprobe binfmt_misc
+
+if test ! -e /proc/sys/fs/binfmt_misc/register
+then
+ /sbin/modprobe binfmt_misc
+ mount -t binfmt_misc none /proc/sys/fs/binfmt_misc
+fi
Index: qemu-0.9.0/qemu-binfmt-conf.sh
===================================================================
--- qemu-0.9.0.orig/qemu-binfmt-conf.sh
+++ qemu-0.9.0/qemu-binfmt-conf.sh
@@ -12,7 +12,7 @@ fi
# probe cpu type
cpu=`uname -m`
case "$cpu" in
@ -19,6 +10,8 @@
+ i386|i486|i586|i686|i86pc|BePC|x86_64)
cpu="i386"
;;
m68k)
@@ -24,32 +24,34 @@ case "$cpu" in
"Power Macintosh"|ppc|ppc64)
cpu="ppc"
;;
@ -28,7 +21,6 @@
;;
+ sparc*)
+ cpu="sparc"
+ ;;
esac
# register the interpreter for each cpu except for the native one
@ -51,8 +43,14 @@
if [ $cpu != "ppc" ] ; then
- echo ':ppc:M::\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x14:\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/local/bin/qemu-ppc:' > /proc/sys/fs/binfmt_misc/register
+ echo ':ppc:M::\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x14:\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/bin/qemu-ppc:' > /proc/sys/fs/binfmt_misc/register
fi
if [ $cpu != "m68k" ] ; then
echo 'Please check cpu value and header information for m68k!'
- echo ':m68k:M::\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x08:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/local/bin/qemu-m68k:' > /proc/sys/fs/binfmt_misc/register
+ echo ':m68k:M::\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x08:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/bin/qemu-m68k:' > /proc/sys/fs/binfmt_misc/register
fi
if [ $cpu != "mips" ] ; then
# FIXME: We could use the other endianness on a MIPS host.
- echo ':mips:M::\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x08:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/local/bin/qemu-mips:' > /proc/sys/fs/binfmt_misc/register
- echo ':mipsel:M::\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x08\x00:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/local/bin/qemu-mipsel:' > /proc/sys/fs/binfmt_misc/register
+ echo ':mips:M::\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x08:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/bin/qemu-mips:' > /proc/sys/fs/binfmt_misc/register

View File

@ -1,117 +0,0 @@
--- kqemu/kqemu.h
+++ kqemu/kqemu.h
@@ -0,0 +1,114 @@
+/*
+ * KQEMU header
+ *
+ * Copyright (c) 2004-2005 Fabrice Bellard
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+#ifndef KQEMU_H
+#define KQEMU_H
+
+#define KQEMU_VERSION 0x010200
+
+struct kqemu_segment_cache {
+ uint32_t selector;
+ unsigned long base;
+ uint32_t limit;
+ uint32_t flags;
+};
+
+struct kqemu_cpu_state {
+#ifdef __x86_64__
+ unsigned long regs[16];
+#else
+ unsigned long regs[8];
+#endif
+ unsigned long eip;
+ unsigned long eflags;
+
+ uint32_t dummy0, dummy1, dumm2, dummy3, dummy4;
+
+ struct kqemu_segment_cache segs[6]; /* selector values */
+ struct kqemu_segment_cache ldt;
+ struct kqemu_segment_cache tr;
+ struct kqemu_segment_cache gdt; /* only base and limit are used */
+ struct kqemu_segment_cache idt; /* only base and limit are used */
+
+ unsigned long cr0;
+ unsigned long dummy5;
+ unsigned long cr2;
+ unsigned long cr3;
+ unsigned long cr4;
+ uint32_t a20_mask;
+
+ uint64_t efer __attribute__((aligned(8)));
+
+ unsigned long dr0;
+ unsigned long dr1;
+ unsigned long dr2;
+ unsigned long dr3;
+ unsigned long dr6;
+ unsigned long dr7;
+
+ uint8_t cpl;
+ uint8_t user_only;
+
+ uint32_t error_code; /* error_code when exiting with an exception */
+ unsigned long next_eip; /* next eip value when exiting with an interrupt */
+ unsigned int nb_pages_to_flush; /* number of pages to flush,
+ KQEMU_FLUSH_ALL means full flush */
+#define KQEMU_MAX_PAGES_TO_FLUSH 512
+#define KQEMU_FLUSH_ALL (KQEMU_MAX_PAGES_TO_FLUSH + 1)
+
+ long retval;
+
+ /* number of ram_dirty entries to update */
+ unsigned int nb_ram_pages_to_update;
+#define KQEMU_MAX_RAM_PAGES_TO_UPDATE 512
+#define KQEMU_RAM_PAGES_UPDATE_ALL (KQEMU_MAX_RAM_PAGES_TO_UPDATE + 1)
+};
+
+struct kqemu_init {
+ uint8_t *ram_base; /* must be page aligned */
+ unsigned long ram_size; /* must be multiple of 4 KB */
+ uint8_t *ram_dirty; /* must be page aligned */
+ uint32_t **phys_to_ram_map; /* must be page aligned */
+ unsigned long *pages_to_flush; /* must be page aligned */
+ unsigned long *ram_pages_to_update; /* must be page aligned */
+};
+
+#define KQEMU_RET_ABORT (-1)
+#define KQEMU_RET_EXCEPTION 0x0000 /* 8 low order bit are the exception */
+#define KQEMU_RET_INT 0x0100 /* 8 low order bit are the interrupt */
+#define KQEMU_RET_SOFTMMU 0x0200 /* emulation needed (I/O or
+ unsupported INSN) */
+#define KQEMU_RET_INTR 0x0201 /* interrupted by a signal */
+#define KQEMU_RET_SYSCALL 0x0300 /* syscall insn */
+
+#ifdef _WIN32
+#define KQEMU_EXEC CTL_CODE(FILE_DEVICE_UNKNOWN, 1, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS)
+#define KQEMU_INIT CTL_CODE(FILE_DEVICE_UNKNOWN, 2, METHOD_BUFFERED, FILE_WRITE_ACCESS)
+#define KQEMU_GET_VERSION CTL_CODE(FILE_DEVICE_UNKNOWN, 3, METHOD_BUFFERED, FILE_READ_ACCESS)
+#else
+#define KQEMU_EXEC _IOWR('q', 1, struct kqemu_cpu_state)
+#define KQEMU_INIT _IOW('q', 2, struct kqemu_init)
+#define KQEMU_GET_VERSION _IOR('q', 3, int)
+#endif
+
+#endif /* KQEMU_H */

901
qemu-0.8.3-gcc4.patch Normal file
View File

@ -0,0 +1,901 @@
2007-02-17 Gwenole Beauchesne <gbeauchesne@mandriva.com>
* target-i386/op.c (op_imull_EAX_T0, op_imulw_T0_T1,
op_imull_T0_T1): Add FORCE_RET() since CC_SRC involves a
compare-branch that may be optimized into a beqlr on ppc.
2005-06-02 Gwenole Beauchesne <gbeauchesne@mandriva.com>
* dyngen.c (trace_i386_insn): Fix push/imul case with 8-bit
immediate.
2005-05-11 Paul Brook <paul@codesourcery.com>
* gcc4 host support.
--- qemu-0.8.3/dyngen-exec.h.gcc4 2006-12-23 01:49:32.000000000 +0100
+++ qemu-0.8.3/dyngen-exec.h 2007-01-30 18:14:25.000000000 +0100
@@ -188,7 +188,12 @@ extern int printf(const char *, ...);
#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" : : : "memory");
+#else
#define FORCE_RET() __asm__ __volatile__("" : : : "memory");
+#endif
#ifndef OPPROTO
#define OPPROTO
@@ -238,9 +243,16 @@ extern int __op_jmp0, __op_jmp1, __op_jm
#endif
#if defined(__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:")
#elif defined(__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:")
#elif defined(__powerpc__)
--- qemu-0.8.3/dyngen.c.gcc4 2006-12-21 17:49:27.000000000 +0100
+++ qemu-0.8.3/dyngen.c 2007-01-30 18:11:21.000000000 +0100
@@ -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)
@@ -1414,6 +1416,644 @@ int arm_emit_ldr_info(const char *name,
#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 */
@@ -1427,6 +2067,11 @@ void gen_code(const char *name, host_ulo
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 +2082,12 @@ void gen_code(const char *name, host_ulo
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 +2299,13 @@ void gen_code(const char *name, host_ulo
}
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) {
@@ -1879,7 +2510,43 @@ void gen_code(const char *name, host_ulo
#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)
{
@@ -1913,6 +2580,42 @@ void gen_code(const char *name, host_ulo
}
}
}
+ /* 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)
{
--- qemu-0.8.3/exec-all.h.gcc4 2006-11-12 21:40:55.000000000 +0100
+++ qemu-0.8.3/exec-all.h 2007-01-30 18:11:21.000000000 +0100
@@ -326,14 +326,15 @@ do {\
#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)
--- qemu-0.8.3/target-i386/op.c~ 2007-02-17 17:12:48.000000000 +0100
+++ qemu-0.8.3/target-i386/op.c 2007-02-17 17:48:46.000000000 +0100
@@ -303,6 +303,7 @@
EDX = (uint32_t)(res >> 32);
CC_DST = res;
CC_SRC = (res != (int32_t)res);
+ FORCE_RET();
}
void OPPROTO op_imulw_T0_T1(void)
@@ -312,6 +313,7 @@
T0 = res;
CC_DST = res;
CC_SRC = (res != (int16_t)res);
+ FORCE_RET();
}
void OPPROTO op_imull_T0_T1(void)
@@ -321,6 +323,7 @@
T0 = res;
CC_DST = res;
CC_SRC = (res != (int32_t)res);
+ FORCE_RET();
}
#ifdef TARGET_X86_64

View File

@ -1,47 +0,0 @@
Index: qemu-0.9.0/linux-user/syscall.c
===================================================================
--- qemu-0.9.0.orig/linux-user/syscall.c
+++ qemu-0.9.0/linux-user/syscall.c
@@ -144,6 +144,7 @@ type name (type1 arg1,type2 arg2,type3 a
#define __NR_sys_getdents64 __NR_getdents64
#define __NR_sys_rt_sigqueueinfo __NR_rt_sigqueueinfo
#define __NR_sys_syslog __NR_syslog
+#define __NR_sys_fadvise64 __NR_fadvise64
#if defined(__alpha__) || defined (__ia64__) || defined(__x86_64__)
#define __NR__llseek __NR_lseek
@@ -164,6 +165,7 @@ _syscall5(int, _llseek, uint, fd, ulon
loff_t *, res, uint, wh);
_syscall3(int,sys_rt_sigqueueinfo,int,pid,int,sig,siginfo_t *,uinfo)
_syscall3(int,sys_syslog,int,type,char*,bufp,int,len)
+_syscall4(int,sys_fadvise64,int,fd,loff_t,offset,loff_t,len,int,advice)
#ifdef __NR_exit_group
_syscall1(int,exit_group,int,error_code)
#endif
@@ -4151,6 +4153,17 @@ long do_syscall(void *cpu_env, int num,
break;
}
#endif
+#ifdef TARGET_NR_fadvise64
+ case TARGET_NR_fadvise64:
+ ret = get_errno(sys_fadvise64((int)arg1, arg2, arg3, (int)arg4));
+ break;
+#endif
+#ifdef TARGET_NR_fadvise64_64
+ case TARGET_NR_fadvise64_64:
+ // fadvise64_64 should be just a wrapper for fadvise_64
+ ret = get_errno(sys_fadvise64((int)arg1, arg2, arg3, (int)arg4));
+ break;
+#endif
default:
unimplemented:
gemu_log("qemu: Unsupported syscall: %d\n", num);
Index: qemu-0.9.0/linux-user/i386/syscall_nr.h
===================================================================
--- qemu-0.9.0.orig/linux-user/i386/syscall_nr.h
+++ qemu-0.9.0/linux-user/i386/syscall_nr.h
@@ -272,3 +272,4 @@
#define TARGET_NR_clock_nanosleep (TARGET_NR_timer_create+8)
#define TARGET_NR_utimes 271
+#define TARGET_NR_fadvise64_64 272

View File

@ -1,46 +0,0 @@
From gbeauchesne@mandriva.com Tue Mar 13 17:01:17 2007
Date: Tue, 20 Feb 2007 01:44:37 +0100 (CET)
From: Gwenole Beauchesne <gbeauchesne@mandriva.com>
Reply-To: qemu-devel@nongnu.org
To: qemu-devel@nongnu.org
Subject: [Qemu-devel] [PATCH] Fix CPU chaining in linux-user emulation
Hi,
This patch fixes chaining of CPU instances. It was simply trashed with the
memcpy() thus causing problems in threaded programs (N > 2): an infinite
loop in next cpu_init().
================================================================================
--- qemu-0.9.0/cpu-all.h
+++ qemu-0.9.0/cpu-all.h
@@ -760,6 +760,8 @@
#endif /* SINGLE_CPU_DEFINES */
+CPUState *cpu_copy(CPUState *env);
+
void cpu_dump_state(CPUState *env, FILE *f,
int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
int flags);
--- qemu-0.9.0/exec.c
+++ qemu-0.9.0/exec.c
@@ -1221,6 +1221,18 @@
abort();
}
+CPUState *cpu_copy(CPUState *env)
+{
+ CPUState *new_env = cpu_init();
+ /* preserve chaining and index */
+ CPUState *next_cpu = new_env->next_cpu;
+ int cpu_index = new_env->cpu_index;
+ memcpy(new_env, env, sizeof(CPUState));
+ new_env->next_cpu = next_cpu;
+ new_env->cpu_index = cpu_index;
+ return new_env;
+}
+
#if !defined(CONFIG_USER_ONLY)
/* NOTE: if flush_global is true, also flush global entries (not

View File

@ -1,151 +0,0 @@
From jseward@acm.org Tue Mar 27 18:05:53 2007
Date: Sat, 17 Mar 2007 17:35:38 +0000
From: Julian Seward <jseward@acm.org>
Reply-To: qemu-devel@nongnu.org
To: qemu-devel@nongnu.org
Subject: [Qemu-devel] [PATCH] Fix guest x86/amd64 helper_fprem/helper_fprem1
The helpers for x86/amd64 fprem and fprem1 in target-i386/helper.c are
significantly borked and, for example, cause konqueror in RedHat8 (x86
guest) to go into an infinite loop when displaying http://news.bbc.co.uk.
helper_fprem has the following borkage:
- various Inf/Nan/zero inputs not handled correctly
- incorrect rounding when converting negative 'dblq' to 'q'
- incorrect order of assignment to C bits (0,3,1 not 0,1,3)
helper_fprem1 has those problems and is also incorrect about the points
at which its rounding needs to differ from that of helper_fprem.
Patch below fixes all these. It brings the fprem and fprem1 behaviour
very much closer to the hardware -- not identical, but close. Some
+0.0 results should really be -0.0 and there may still be other differences.
Anyway konquerer no longer loops with the patch applied.
--- qemu-0.9.0/target-i386/helper.c.fix-x86-fprem 2007-03-27 13:48:10.000000000 -0400
+++ qemu-0.9.0/target-i386/helper.c 2007-03-27 14:03:06.000000000 -0400
@@ -3124,30 +3124,51 @@ void helper_fprem1(void)
CPU86_LDouble dblq, fpsrcop, fptemp;
CPU86_LDoubleU fpsrcop1, fptemp1;
int expdif;
- int q;
+ signed long long int q;
+
+ if (isinf(ST0) || isnan(ST0) || isnan(ST1) || (ST1 == 0.0)) {
+ ST0 = 0.0 / 0.0; /* NaN */
+ env->fpus &= (~0x4700); /* (C3,C2,C1,C0) <-- 0000 */
+ return;
+ }
fpsrcop = ST0;
fptemp = ST1;
fpsrcop1.d = fpsrcop;
fptemp1.d = fptemp;
expdif = EXPD(fpsrcop1) - EXPD(fptemp1);
+
+ if (expdif < 0) {
+ /* optimisation? taken from the AMD docs */
+ env->fpus &= (~0x4700); /* (C3,C2,C1,C0) <-- 0000 */
+ /* ST0 is unchanged */
+ return;
+ }
+
if (expdif < 53) {
dblq = fpsrcop / fptemp;
- dblq = (dblq < 0.0)? ceil(dblq): floor(dblq);
+ /* round dblq towards nearest integer */
+ dblq = rint(dblq);
ST0 = fpsrcop - fptemp*dblq;
- q = (int)dblq; /* cutting off top bits is assumed here */
+
+ /* convert dblq to q by truncating towards zero */
+ if (dblq < 0.0)
+ q = (signed long long int)(-dblq);
+ else
+ q = (signed long long int)dblq;
+
env->fpus &= (~0x4700); /* (C3,C2,C1,C0) <-- 0000 */
- /* (C0,C1,C3) <-- (q2,q1,q0) */
- env->fpus |= (q&0x4) << 6; /* (C0) <-- q2 */
- env->fpus |= (q&0x2) << 8; /* (C1) <-- q1 */
- env->fpus |= (q&0x1) << 14; /* (C3) <-- q0 */
+ /* (C0,C3,C1) <-- (q2,q1,q0) */
+ env->fpus |= (q&0x4) << (8-2); /* (C0) <-- q2 */
+ env->fpus |= (q&0x2) << (14-1); /* (C3) <-- q1 */
+ env->fpus |= (q&0x1) << (9-0); /* (C1) <-- q0 */
} else {
env->fpus |= 0x400; /* C2 <-- 1 */
fptemp = pow(2.0, expdif-50);
fpsrcop = (ST0 / ST1) / fptemp;
- /* fpsrcop = integer obtained by rounding to the nearest */
- fpsrcop = (fpsrcop-floor(fpsrcop) < ceil(fpsrcop)-fpsrcop)?
- floor(fpsrcop): ceil(fpsrcop);
+ /* fpsrcop = integer obtained by chopping */
+ fpsrcop = (fpsrcop < 0.0)?
+ -(floor(fabs(fpsrcop))): floor(fpsrcop);
ST0 -= (ST1 * fpsrcop * fptemp);
}
}
@@ -3157,26 +3178,48 @@ void helper_fprem(void)
CPU86_LDouble dblq, fpsrcop, fptemp;
CPU86_LDoubleU fpsrcop1, fptemp1;
int expdif;
- int q;
-
- fpsrcop = ST0;
- fptemp = ST1;
+ signed long long int q;
+
+ if (isinf(ST0) || isnan(ST0) || isnan(ST1) || (ST1 == 0.0)) {
+ ST0 = 0.0 / 0.0; /* NaN */
+ env->fpus &= (~0x4700); /* (C3,C2,C1,C0) <-- 0000 */
+ return;
+ }
+
+ fpsrcop = (CPU86_LDouble)ST0;
+ fptemp = (CPU86_LDouble)ST1;
fpsrcop1.d = fpsrcop;
fptemp1.d = fptemp;
expdif = EXPD(fpsrcop1) - EXPD(fptemp1);
+
+ if (expdif < 0) {
+ /* optimisation? taken from the AMD docs */
+ env->fpus &= (~0x4700); /* (C3,C2,C1,C0) <-- 0000 */
+ /* ST0 is unchanged */
+ return;
+ }
+
if ( expdif < 53 ) {
- dblq = fpsrcop / fptemp;
+ dblq = fpsrcop/*ST0*/ / fptemp/*ST1*/;
+ /* round dblq towards zero */
dblq = (dblq < 0.0)? ceil(dblq): floor(dblq);
- ST0 = fpsrcop - fptemp*dblq;
- q = (int)dblq; /* cutting off top bits is assumed here */
+ ST0 = fpsrcop/*ST0*/ - fptemp*dblq;
+
+ /* convert dblq to q by truncating towards zero */
+ if (dblq < 0.0)
+ q = (signed long long int)(-dblq);
+ else
+ q = (signed long long int)dblq;
+
env->fpus &= (~0x4700); /* (C3,C2,C1,C0) <-- 0000 */
- /* (C0,C1,C3) <-- (q2,q1,q0) */
- env->fpus |= (q&0x4) << 6; /* (C0) <-- q2 */
- env->fpus |= (q&0x2) << 8; /* (C1) <-- q1 */
- env->fpus |= (q&0x1) << 14; /* (C3) <-- q0 */
+ /* (C0,C3,C1) <-- (q2,q1,q0) */
+ env->fpus |= (q&0x4) << (8-2); /* (C0) <-- q2 */
+ env->fpus |= (q&0x2) << (14-1); /* (C3) <-- q1 */
+ env->fpus |= (q&0x1) << (9-0); /* (C1) <-- q0 */
} else {
+ int N = 32 + (expdif % 32); /* as per AMD docs */
env->fpus |= 0x400; /* C2 <-- 1 */
- fptemp = pow(2.0, expdif-50);
+ fptemp = pow(2.0, (double)(expdif-N));
fpsrcop = (ST0 / ST1) / fptemp;
/* fpsrcop = integer obtained by chopping */
fpsrcop = (fpsrcop < 0.0)?

View File

@ -1,114 +0,0 @@
Index: qemu-0.9.0/linux-user/syscall.c
===================================================================
--- qemu-0.9.0.orig/linux-user/syscall.c
+++ qemu-0.9.0/linux-user/syscall.c
@@ -2127,11 +2127,40 @@ static inline void host_to_target_timesp
unlock_user_struct(target_ts, target_addr, 1);
}
+#ifdef BSWAP_NEEDED
+static int futex_op(int oldval, int op, int oparg)
+{
+ int retval = oparg;
+ switch(op) {
+ case FUTEX_OP_SET: break;
+ case FUTEX_OP_ADD: retval += oparg; break;
+ case FUTEX_OP_OR: retval |= oparg; break;
+ case FUTEX_OP_ANDN: retval &= oparg; break;
+ case FUTEX_OP_XOR: retval ^= oparg; break;
+ }
+ return retval;
+}
+
+static int futex_cmp(int oldval, int cmp, int cmparg)
+{
+ switch(cmp) {
+ case FUTEX_OP_CMP_EQ: return oldval == cmparg;
+ case FUTEX_OP_CMP_NE: return oldval != cmparg;
+ case FUTEX_OP_CMP_LT: return oldval < cmparg;
+ case FUTEX_OP_CMP_LE: return oldval <= cmparg;
+ case FUTEX_OP_CMP_GT: return oldval > cmparg;
+ case FUTEX_OP_CMP_GE: return oldval >= cmparg;
+ }
+ return -1;
+}
+#endif
+
static long do_futex(target_ulong uaddr, int op, uint32_t val,
target_ulong utime, target_ulong uaddr2,
uint32_t val3)
{
struct timespec host_utime;
unsigned long val2 = utime;
+ long retval;
if (utime && (op == FUTEX_WAIT || op == FUTEX_LOCK_PI)) {
@@ -2141,6 +2170,7 @@ static long do_futex(target_ulong uaddr,
}
#ifdef BSWAP_NEEDED
+// if( op == FUTEX_WAKE_OP ) { gemu_log("FUTEX_WAKE_OP -> FUTEX_WAKE\n"); op = FUTEX_WAKE; sleep(1); }
switch(op) {
case FUTEX_CMP_REQUEUE:
val3 = tswap32(val3);
@@ -2148,41 +2178,40 @@ static long do_futex(target_ulong uaddr,
val2 = tswap32(val2);
case FUTEX_WAIT:
case FUTEX_WAKE:
+ case FUTEX_WAKE_OP:
val = tswap32(val);
case FUTEX_LOCK_PI: /* This one's icky, but comes out OK */
case FUTEX_UNLOCK_PI:
break;
default:
gemu_log("qemu: Unsupported futex op %d\n", op);
+ spin_unlock(&mmap_lock);
return -ENOSYS;
}
-#if 0 /* No, it's worse than this */
if (op == FUTEX_WAKE_OP) {
/* Need to munge the secondary operation (val3) */
val3 = tswap32(val3);
- int op2 = (val3 >> 28) & 7;
- int cmp = (val3 >> 24) & 15;
- int oparg = (val3 << 8) >> 20;
- int cmparg = (val3 << 20) >> 20;
+ int op2 = (val3 >> 28) & 0xf;
+ int cmp = (val3 >> 24) & 0xf;
+ int oparg = (val3 >> 12) & 0xfff;
+ int cmparg = val3 & 0xfff;
int shift = val3 & (FUTEX_OP_OPARG_SHIFT << 28);
-
+ int oldval = tget32(uaddr2);
if (shift)
- oparg = (oparg & 7) + 24 - (oparg & 24);
- else oparg =
- if (op2 == FUTEX_OP_ADD) {
- gemu_log("qemu: Unsupported wrong-endian FUTEX_OP_ADD\n");
- return -ENOSYS;
- }
- if (cmparg == FUTEX_OP_CMP_LT || cmparg == FUTEX_OP_CMP_GE ||
- cmparg == FUTEX_OP_CMP_LE || cmparg == FUTEX_OP_CMP_GT) {
- gemu_log("qemu: Unsupported wrong-endian futex cmparg %d\n", cmparg);
- return -ENOSYS;
- }
- val3 = shift | (op2<<28) | (cmp<<24) | (oparg<<12) | cmparg;
+ oparg = 1 << oparg;
+
+ tput32(uaddr2,futex_op(oldval, op2, oparg));
+ retval = syscall(__NR_futex, g2h(uaddr), FUTEX_WAKE, val, 0, 0, 0);
+ if(futex_cmp(oldval, cmp, cmparg)) {
+ retval = syscall(__NR_futex, g2h(uaddr2), FUTEX_WAKE, val2, 0, 0, 0);
+ }
+ } else {
+ retval = syscall(__NR_futex, g2h(uaddr), op, val, val2, g2h(uaddr2), val3);
}
-#endif
+#else
+ retval = syscall(__NR_futex, g2h(uaddr), op, val, val2, g2h(uaddr2), val3);
#endif
- return syscall(__NR_futex, g2h(uaddr), op, val, val2, g2h(uaddr2), val3);
+ return retval;
}
int do_set_tid_address(target_ulong tidptr)

View File

@ -1,64 +0,0 @@
Index: qemu-0.9.0/hw/pc.c
===================================================================
--- qemu-0.9.0.orig/hw/pc.c
+++ qemu-0.9.0/hw/pc.c
@@ -32,9 +32,11 @@
#define LINUX_BOOT_FILENAME "linux_boot.bin"
#define KERNEL_LOAD_ADDR 0x00100000
-#define INITRD_LOAD_ADDR 0x00600000
+#define MAX_INITRD_LOAD_ADDR 0x38000000
#define KERNEL_PARAMS_ADDR 0x00090000
#define KERNEL_CMDLINE_ADDR 0x00099000
+/* Leave a chunk of memory at the top of RAM for the BIOS ACPI tables. */
+#define ACPI_DATA_SIZE 0x10000
static fdctrl_t *floppy_controller;
static RTCState *rtc_state;
@@ -452,6 +454,7 @@ static void pc_init1(int ram_size, int v
char buf[1024];
int ret, linux_boot, initrd_size, i;
unsigned long bios_offset, vga_bios_offset, option_rom_offset;
+ unsigned long initrd_offset;
int bios_size, isa_bios_size;
PCIBus *pci_bus;
int piix3_devfn = -1;
@@ -576,8 +579,28 @@ static void pc_init1(int ram_size, int v
/* load initrd */
initrd_size = 0;
+ initrd_offset = 0;
if (initrd_filename) {
- initrd_size = load_image(initrd_filename, phys_ram_base + INITRD_LOAD_ADDR);
+ initrd_size = get_image_size (initrd_filename);
+ if (initrd_size > 0) {
+ initrd_offset = (ram_size - initrd_size) & TARGET_PAGE_MASK;
+ /* Leave space for BIOS ACPI tables. */
+ initrd_offset -= ACPI_DATA_SIZE;
+ /* Avoid the last 64k to avoid 2.2.x kernel bugs. */
+ initrd_offset -= 0x10000;
+ if (initrd_offset > MAX_INITRD_LOAD_ADDR)
+ initrd_offset = MAX_INITRD_LOAD_ADDR;
+
+ if (initrd_size > ram_size
+ || initrd_offset < KERNEL_LOAD_ADDR + ret) {
+ fprintf(stderr,
+ "qemu: memory too small for initial ram disk '%s'\n",
+ initrd_filename);
+ exit(1);
+ }
+ initrd_size = load_image(initrd_filename,
+ phys_ram_base + initrd_offset);
+ }
if (initrd_size < 0) {
fprintf(stderr, "qemu: could not load initial ram disk '%s'\n",
initrd_filename);
@@ -585,7 +608,7 @@ static void pc_init1(int ram_size, int v
}
}
if (initrd_size > 0) {
- stl_raw(phys_ram_base + KERNEL_PARAMS_ADDR + 0x218, INITRD_LOAD_ADDR);
+ stl_raw(phys_ram_base + KERNEL_PARAMS_ADDR + 0x218, initrd_offset);
stl_raw(phys_ram_base + KERNEL_PARAMS_ADDR + 0x21c, initrd_size);
}
pstrcpy(phys_ram_base + KERNEL_CMDLINE_ADDR, 4096,

View File

@ -1,36 +0,0 @@
--- qemu-0.9.0/hw/pc.c.kernel-option-vga 2007-02-13 14:41:12.000000000 +0100
+++ qemu-0.9.0/hw/pc.c 2007-02-14 17:01:57.000000000 +0100
@@ -567,6 +567,7 @@ static void pc_init1(int ram_size, int v
if (linux_boot) {
uint8_t bootsect[512];
uint8_t old_bootsect[512];
+ char *vmode;
if (bs_table[0] == NULL) {
fprintf(stderr, "A disk image must be given for 'hda' when booting a Linux kernel\n");
@@ -618,6 +619,25 @@ static void pc_init1(int ram_size, int v
KERNEL_CMDLINE_ADDR - KERNEL_PARAMS_ADDR);
/* loader type */
stw_raw(phys_ram_base + KERNEL_PARAMS_ADDR + 0x210, 0x01);
+
+ /* handle vga= parameter */
+ vmode = strstr(kernel_cmdline, "vga=");
+ if (vmode) {
+ char *space;
+ unsigned int video_mode;
+ /* skip "vga=" */
+ vmode += 4;
+ if (!strncmp(vmode, "normal", 6)) {
+ video_mode = 0xffff;
+ } else if (!strncmp(vmode, "ext", 3)) {
+ video_mode = 0xfffe;
+ } else if (!strncmp(vmode, "ask", 3)) {
+ video_mode = 0xfffd;
+ } else {
+ video_mode = strtol(vmode, NULL, 0);
+ }
+ stw_raw(phys_ram_base + KERNEL_PARAMS_ADDR + 0x1fa, video_mode);
+ }
}
if (pci_enabled) {

View File

@ -1,203 +0,0 @@
Index: qemu-0.9.0/linux-user/syscall.c
===================================================================
--- qemu-0.9.0.orig/linux-user/syscall.c
+++ qemu-0.9.0/linux-user/syscall.c
@@ -185,6 +185,9 @@ extern int getresgid(gid_t *, gid_t *, g
extern int setgroups(int, gid_t *);
extern int uselib(const char*);
+#include "exec-all.h"
+long mmap_lock;
+
static inline long get_errno(long ret)
{
if (ret == -1)
@@ -227,9 +235,11 @@ long do_brk(target_ulong new_brk)
/* We need to allocate more memory after the brk... */
new_alloc_size = HOST_PAGE_ALIGN(new_brk - brk_page + 1);
+ spin_lock(&mmap_lock);
mapped_addr = get_errno(target_mmap(brk_page, new_alloc_size,
PROT_READ|PROT_WRITE,
MAP_ANON|MAP_FIXED|MAP_PRIVATE, 0, 0));
+ spin_unlock(&mmap_lock);
if (is_error(mapped_addr)) {
return mapped_addr;
} else {
@@ -2985,15 +3021,19 @@ long do_syscall(void *cpu_env, int num,
v5 = tswapl(v[4]);
v6 = tswapl(v[5]);
unlock_user(v, arg1, 0);
+ spin_lock(&mmap_lock);
ret = get_errno(target_mmap(v1, v2, v3,
target_to_host_bitmask(v4, mmap_flags_tbl),
v5, v6));
+ spin_unlock(&mmap_lock);
}
#else
+ spin_lock(&mmap_lock);
ret = get_errno(target_mmap(arg1, arg2, arg3,
target_to_host_bitmask(arg4, mmap_flags_tbl),
arg5,
arg6));
+ spin_unlock(&mmap_lock);
#endif
break;
#ifdef TARGET_NR_mmap2
@@ -3003,36 +3043,54 @@ long do_syscall(void *cpu_env, int num,
#else
#define MMAP_SHIFT TARGET_PAGE_BITS
#endif
+ spin_lock(&mmap_lock);
ret = get_errno(target_mmap(arg1, arg2, arg3,
target_to_host_bitmask(arg4, mmap_flags_tbl),
arg5,
arg6 << MMAP_SHIFT));
+ spin_unlock(&mmap_lock);
break;
#endif
case TARGET_NR_munmap:
+ spin_lock(&mmap_lock);
ret = get_errno(target_munmap(arg1, arg2));
+ spin_unlock(&mmap_lock);
break;
case TARGET_NR_mprotect:
+ spin_lock(&mmap_lock);
ret = get_errno(target_mprotect(arg1, arg2, arg3));
+ spin_unlock(&mmap_lock);
break;
case TARGET_NR_mremap:
+ spin_lock(&mmap_lock);
ret = get_errno(target_mremap(arg1, arg2, arg3, arg4, arg5));
+ spin_unlock(&mmap_lock);
break;
/* ??? msync/mlock/munlock are broken for softmmu. */
case TARGET_NR_msync:
+ spin_lock(&mmap_lock);
ret = get_errno(msync(g2h(arg1), arg2, arg3));
+ spin_unlock(&mmap_lock);
break;
case TARGET_NR_mlock:
+ spin_lock(&mmap_lock);
ret = get_errno(mlock(g2h(arg1), arg2));
+ spin_unlock(&mmap_lock);
break;
case TARGET_NR_munlock:
+ spin_lock(&mmap_lock);
ret = get_errno(munlock(g2h(arg1), arg2));
+ spin_unlock(&mmap_lock);
break;
case TARGET_NR_mlockall:
+ spin_lock(&mmap_lock);
ret = get_errno(mlockall(arg1));
+ spin_unlock(&mmap_lock);
break;
case TARGET_NR_munlockall:
+ spin_lock(&mmap_lock);
ret = get_errno(munlockall());
+ spin_unlock(&mmap_lock);
break;
case TARGET_NR_truncate:
p = lock_user_string(arg1);
Index: qemu-0.9.0/exec.c
===================================================================
--- qemu-0.9.0.orig/exec.c
+++ qemu-0.9.0/exec.c
@@ -1676,6 +1684,50 @@ void page_dump(FILE *f)
}
}
+/* dump memory mappings */
+target_ulong page_find_end()
+{
+ unsigned long start, end;
+ int i, j, prot, prot1;
+ void *firsttb;
+ PageDesc *p;
+ target_ulong last = 0;
+
+ start = -1;
+ end = -1;
+ prot = 0;
+ for(i = 0; i <= L1_SIZE; i++) {
+ if (i < L1_SIZE)
+ p = l1_map[i];
+ else
+ p = NULL;
+ for(j = 0;j < L2_SIZE; j++) {
+ if (!p) {
+ firsttb = NULL;
+ prot1 = 0;
+ }
+ else {
+ prot1 = p[j].flags;
+ firsttb = p[j].first_tb;
+ }
+ if (prot1 != prot) {
+ end = (i << (32 - L1_BITS)) | (j << TARGET_PAGE_BITS);
+ if (start != -1) {
+ last = end;
+ }
+ if (prot1 != 0)
+ start = end;
+ else
+ start = -1;
+ prot = prot1;
+ }
+ if (!p)
+ break;
+ }
+ }
+ return last;
+}
+
int page_get_flags(target_ulong address)
{
PageDesc *p;
Index: qemu-0.9.0/linux-user/mmap.c
===================================================================
--- qemu-0.9.0.orig/linux-user/mmap.c
+++ qemu-0.9.0/linux-user/mmap.c
@@ -48,8 +48,14 @@ int target_mprotect(target_ulong start,
end = start + len;
if (end < start)
return -EINVAL;
- if (prot & ~(PROT_READ | PROT_WRITE | PROT_EXEC))
- return -EINVAL;
+ if (prot & ~(PROT_READ | PROT_WRITE | PROT_EXEC)) {
+#ifdef DEBUG_MMAP
+ gemu_log("mprotect: ERROR (prot & ~(PROT_READ | PROT_WRITE | PROT_EXEC)\n");
+#endif
+ // dirty hack to get mplayer running (sets PROT_GROWSDOWN) we just ignore advanced flags
+ prot &= (PROT_READ | PROT_WRITE | PROT_EXEC);
+// return -EINVAL;
+ }
if (len == 0)
return 0;
@@ -205,9 +233,23 @@ long target_mmap(target_ulong start, tar
defined(__ia64) || defined(__CYGWIN__)
/* tell the kenel to search at the same place as i386 */
if (real_start == 0) {
- real_start = last_start;
- last_start += HOST_PAGE_ALIGN(len);
+ target_ulong curend = page_find_end();
+
+ if(curend > last_start) {
+#ifdef DEBUG_MMAP
+ gemu_log("qemu: set last_start from %p to %p\n", last_start, curend + HOST_PAGE_ALIGN(len)); fflush(stdout); fflush(stderr);
+#endif
+ last_start = curend;
+#ifdef DEBUG_MMAP
+ } else {
+ gemu_log("qemu: curend(%p) <= last_start(%p)\n", curend, last_start); fflush(stdout); fflush(stderr);
+#endif
+ }
+
+ real_start = last_start;
+ last_start += HOST_PAGE_ALIGN(len);
}
+
#endif
if (0 && qemu_host_page_size != qemu_real_host_page_size) {
/* NOTE: this code is only for debugging with '-p' option */

View File

@ -1,12 +0,0 @@
Index: qemu-0.9.0/linux-user/syscall.c
===================================================================
--- qemu-0.9.0.orig/linux-user/syscall.c
+++ qemu-0.9.0/linux-user/syscall.c
@@ -791,6 +791,7 @@ static long do_socket(int domain, int ty
break;
}
#endif
+ if(domain == PF_NETLINK) return -EAFNOSUPPORT;
return get_errno(socket(domain, type, protocol));
}

View File

@ -1,300 +0,0 @@
Index: qemu-0.9.0/linux-user/main.c
===================================================================
--- qemu-0.9.0.orig/linux-user/main.c
+++ qemu-0.9.0/linux-user/main.c
@@ -156,7 +156,7 @@ static void set_gate(void *ptr, unsigned
p[1] = tswapl(e2);
}
-uint64_t gdt_table[6];
+uint64_t gdt_table[9];
uint64_t idt_table[256];
/* only dpl matters as we do only user space emulation */
@@ -1604,7 +1604,11 @@ int main(int argc, char **argv)
int optind;
const char *r;
int gdbstub_port = 0;
-
+ char *assume_kernel = getenv("QEMU_ASSUME_KERNEL");
+
+ if (assume_kernel)
+ setenv("LD_ASSUME_KERNEL", assume_kernel, 1);
+
if (argc <= 1)
usage();
Index: qemu-0.9.0/linux-user/syscall.c
===================================================================
--- qemu-0.9.0.orig/linux-user/syscall.c
+++ qemu-0.9.0/linux-user/syscall.c
@@ -17,6 +17,8 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
+
+#define __user
#include <stdlib.h>
#include <stdio.h>
#include <stdarg.h>
@@ -57,6 +59,7 @@
#define tchars host_tchars /* same as target */
#define ltchars host_ltchars /* same as target */
+#include <linux/futex.h>
#include <linux/termios.h>
#include <linux/unistd.h>
#include <linux/utsname.h>
@@ -1690,6 +1693,80 @@ int do_modify_ldt(CPUX86State *env, int
return ret;
}
+int do_set_thread_area(CPUX86State *env, target_ulong ptr)
+{
+ uint64_t *gdt_table = g2h(env->gdt.base);
+ struct target_modify_ldt_ldt_s ldt_info;
+ struct target_modify_ldt_ldt_s *target_ldt_info;
+ int seg_32bit, contents, read_exec_only, limit_in_pages;
+ int seg_not_present, useable;
+ uint32_t *lp, entry_1, entry_2;
+ int i;
+
+ lock_user_struct(target_ldt_info, ptr, 1);
+ ldt_info.entry_number = tswap32(target_ldt_info->entry_number);
+ ldt_info.base_addr = tswapl(target_ldt_info->base_addr);
+ ldt_info.limit = tswap32(target_ldt_info->limit);
+ ldt_info.flags = tswap32(target_ldt_info->flags);
+ if (ldt_info.entry_number == -1) {
+ for (i=6; i<8; i++)
+ if (gdt_table[i] == 0) {
+ ldt_info.entry_number = i;
+ target_ldt_info->entry_number = tswap32(i);
+ break;
+ }
+ }
+ unlock_user_struct(target_ldt_info, ptr, 0);
+
+ if (ldt_info.entry_number < 6 || ldt_info.entry_number > 8)
+ return -EINVAL;
+ seg_32bit = ldt_info.flags & 1;
+ contents = (ldt_info.flags >> 1) & 3;
+ read_exec_only = (ldt_info.flags >> 3) & 1;
+ limit_in_pages = (ldt_info.flags >> 4) & 1;
+ seg_not_present = (ldt_info.flags >> 5) & 1;
+ useable = (ldt_info.flags >> 6) & 1;
+
+ if (contents == 3) {
+ if (seg_not_present == 0)
+ return -EINVAL;
+ }
+
+ /* NOTE: same code as Linux kernel */
+ /* Allow LDTs to be cleared by the user. */
+ if (ldt_info.base_addr == 0 && ldt_info.limit == 0) {
+ if ((contents == 0 &&
+ read_exec_only == 1 &&
+ seg_32bit == 0 &&
+ limit_in_pages == 0 &&
+ seg_not_present == 1 &&
+ useable == 0 )) {
+ entry_1 = 0;
+ entry_2 = 0;
+ goto install;
+ }
+ }
+
+ entry_1 = ((ldt_info.base_addr & 0x0000ffff) << 16) |
+ (ldt_info.limit & 0x0ffff);
+ entry_2 = (ldt_info.base_addr & 0xff000000) |
+ ((ldt_info.base_addr & 0x00ff0000) >> 16) |
+ (ldt_info.limit & 0xf0000) |
+ ((read_exec_only ^ 1) << 9) |
+ (contents << 10) |
+ ((seg_not_present ^ 1) << 15) |
+ (seg_32bit << 22) |
+ (limit_in_pages << 23) |
+ (useable << 20) |
+ 0x7000;
+
+ /* Install the new entry ... */
+install:
+ lp = (uint32_t *)(gdt_table + ldt_info.entry_number);
+ lp[0] = tswap32(entry_1);
+ lp[1] = tswap32(entry_2);
+ return 0;
+}
#endif /* defined(TARGET_I386) */
/* this stack is the equivalent of the kernel stack associated with a
@@ -1710,9 +1787,13 @@ int do_fork(CPUState *env, unsigned int
TaskState *ts;
uint8_t *new_stack;
CPUState *new_env;
-
+#if defined(TARGET_I386)
+ uint64_t *new_gdt_table;
+#endif
if (flags & CLONE_VM) {
ts = malloc(sizeof(TaskState) + NEW_STACK_SIZE);
+ if (!ts)
+ return -ENOMEM;
memset(ts, 0, sizeof(TaskState));
new_stack = ts->stack;
ts->used = 1;
@@ -1725,6 +1807,29 @@ int do_fork(CPUState *env, unsigned int
#if defined(TARGET_I386)
if (!newsp)
newsp = env->regs[R_ESP];
+ new_gdt_table = malloc(9 * 8);
+ if (!new_gdt_table) {
+ free(new_env);
+ return -ENOMEM;
+ }
+ /* Copy main GDT table from parent, but clear TLS entries */
+ memcpy(new_gdt_table, g2h(env->gdt.base), 6 * 8);
+ memset(&new_gdt_table[6], 0, 3 * 8);
+ new_env->gdt.base = h2g(new_gdt_table);
+ if (flags & 0x00080000 /* CLONE_SETTLS */) {
+ ret = do_set_thread_area(new_env, new_env->regs[R_ESI]);
+ if (ret) {
+ free(new_gdt_table);
+ free(new_env);
+ return ret;
+ }
+ }
+ cpu_x86_load_seg(env, R_CS, new_env->regs[R_CS]);
+ cpu_x86_load_seg(env, R_DS, new_env->regs[R_DS]);
+ cpu_x86_load_seg(env, R_ES, new_env->regs[R_ES]);
+ cpu_x86_load_seg(env, R_SS, new_env->regs[R_SS]);
+ cpu_x86_load_seg(env, R_FS, new_env->regs[R_FS]);
+ cpu_x86_load_seg(env, R_GS, new_env->regs[R_GS]);
new_env->regs[R_ESP] = newsp;
new_env->regs[R_EAX] = 0;
#elif defined(TARGET_ARM)
@@ -1991,6 +2096,68 @@ static inline void host_to_target_timesp
unlock_user_struct(target_ts, target_addr, 1);
}
+static long do_futex(target_ulong uaddr, int op, uint32_t val,
+ target_ulong utime, target_ulong uaddr2,
+ uint32_t val3)
+{
+ struct timespec host_utime;
+ unsigned long val2 = utime;
+
+ if (utime && (op == FUTEX_WAIT || op == FUTEX_LOCK_PI)) {
+ target_to_host_timespec(&host_utime, utime);
+ val2 = (unsigned long)&host_utime;
+ }
+
+#ifdef BSWAP_NEEDED
+ switch(op) {
+ case FUTEX_CMP_REQUEUE:
+ val3 = tswap32(val3);
+ case FUTEX_REQUEUE:
+ val2 = tswap32(val2);
+ case FUTEX_WAIT:
+ case FUTEX_WAKE:
+ val = tswap32(val);
+ case FUTEX_LOCK_PI: /* This one's icky, but comes out OK */
+ case FUTEX_UNLOCK_PI:
+ break;
+ default:
+ gemu_log("qemu: Unsupported futex op %d\n", op);
+ return -ENOSYS;
+ }
+#if 0 /* No, it's worse than this */
+ if (op == FUTEX_WAKE_OP) {
+ /* Need to munge the secondary operation (val3) */
+ val3 = tswap32(val3);
+ int op2 = (val3 >> 28) & 7;
+ int cmp = (val3 >> 24) & 15;
+ int oparg = (val3 << 8) >> 20;
+ int cmparg = (val3 << 20) >> 20;
+ int shift = val3 & (FUTEX_OP_OPARG_SHIFT << 28);
+
+ if (shift)
+ oparg = (oparg & 7) + 24 - (oparg & 24);
+ else oparg =
+ if (op2 == FUTEX_OP_ADD) {
+ gemu_log("qemu: Unsupported wrong-endian FUTEX_OP_ADD\n");
+ return -ENOSYS;
+ }
+ if (cmparg == FUTEX_OP_CMP_LT || cmparg == FUTEX_OP_CMP_GE ||
+ cmparg == FUTEX_OP_CMP_LE || cmparg == FUTEX_OP_CMP_GT) {
+ gemu_log("qemu: Unsupported wrong-endian futex cmparg %d\n", cmparg);
+ return -ENOSYS;
+ }
+ val3 = shift | (op2<<28) | (cmp<<24) | (oparg<<12) | cmparg;
+ }
+#endif
+#endif
+ return syscall(__NR_futex, g2h(uaddr), op, val, val2, g2h(uaddr2), val3);
+}
+
+int do_set_tid_address(target_ulong tidptr)
+{
+ return syscall(__NR_set_tid_address, g2h(tidptr));
+}
+
long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3,
long arg4, long arg5, long arg6)
{
@@ -2008,7 +2175,7 @@ long do_syscall(void *cpu_env, int num,
_mcleanup();
#endif
gdb_exit(cpu_env, arg1);
- /* XXX: should free thread stack and CPU env */
+ /* XXX: should free thread stack, GDT and CPU env */
_exit(arg1);
ret = 0; /* avoid warning */
break;
@@ -3153,6 +3320,9 @@ long do_syscall(void *cpu_env, int num,
case TARGET_NR_vm86:
ret = do_vm86(cpu_env, arg1, arg2);
break;
+ case TARGET_NR_set_thread_area:
+ ret = get_errno(do_set_thread_area(cpu_env, arg1));
+ break;
#endif
case TARGET_NR_adjtimex:
goto unimplemented;
@@ -3947,15 +4117,24 @@ long do_syscall(void *cpu_env, int num,
case TARGET_NR_fremovexattr:
goto unimplemented_nowarn;
#endif
-#ifdef TARGET_NR_set_thread_area
- case TARGET_NR_set_thread_area:
- case TARGET_NR_get_thread_area:
- goto unimplemented_nowarn;
-#endif
#ifdef TARGET_NR_getdomainname
case TARGET_NR_getdomainname:
goto unimplemented_nowarn;
#endif
+#ifdef TARGET_NR_futex
+ case TARGET_NR_futex:
+ ret = get_errno(do_futex(arg1, arg2, arg3, arg4, arg5, arg6));
+ break;
+#endif
+#ifdef TARGET_NR_set_tid_address
+ case TARGET_NR_set_tid_address:
+ ret = get_errno(do_set_tid_address(arg1));
+ break;
+#endif
+#ifdef TARGET_NR_set_robust_list
+ case TARGET_NR_set_robust_list:
+ goto unimplemented_nowarn;
+#endif
#ifdef TARGET_NR_clock_gettime
case TARGET_NR_clock_gettime:
{
@@ -3975,7 +4154,7 @@ long do_syscall(void *cpu_env, int num,
default:
unimplemented:
gemu_log("qemu: Unsupported syscall: %d\n", num);
-#if defined(TARGET_NR_setxattr) || defined(TARGET_NR_set_thread_area) || defined(TARGET_NR_getdomainname)
+#if defined(TARGET_NR_setxattr) || defined(TARGET_NR_set_thread_area) || defined(TARGET_NR_set_robust_list) || defined(TARGET_NR_getdomainname)
unimplemented_nowarn:
#endif
ret = -ENOSYS;

View File

@ -1,219 +0,0 @@
Index: qemu-0.9.0/linux-user/i386/syscall_nr.h
===================================================================
--- qemu-0.9.0.orig/linux-user/i386/syscall_nr.h
+++ qemu-0.9.0/linux-user/i386/syscall_nr.h
@@ -271,5 +271,6 @@
#define TARGET_NR_clock_getres (TARGET_NR_timer_create+7)
#define TARGET_NR_clock_nanosleep (TARGET_NR_timer_create+8)
+#define TARGET_NR_tgkill 270
#define TARGET_NR_utimes 271
#define TARGET_NR_fadvise64_64 272
Index: qemu-0.9.0/linux-user/syscall.c
===================================================================
--- qemu-0.9.0.orig/linux-user/syscall.c
+++ qemu-0.9.0/linux-user/syscall.c
@@ -145,6 +145,8 @@ type name (type1 arg1,type2 arg2,type3 a
#define __NR_sys_rt_sigqueueinfo __NR_rt_sigqueueinfo
#define __NR_sys_syslog __NR_syslog
#define __NR_sys_fadvise64 __NR_fadvise64
+#define __NR_sys_tgkill __NR_tgkill
+#define __NR_sys_clone __NR_clone
#if defined(__alpha__) || defined (__ia64__) || defined(__x86_64__)
#define __NR__llseek __NR_lseek
@@ -166,6 +168,8 @@ _syscall5(int, _llseek, uint, fd, ulon
_syscall3(int,sys_rt_sigqueueinfo,int,pid,int,sig,siginfo_t *,uinfo)
_syscall3(int,sys_syslog,int,type,char*,bufp,int,len)
_syscall4(int,sys_fadvise64,int,fd,loff_t,offset,loff_t,len,int,advice)
+_syscall3(int,sys_tgkill,int,tgid,int,pid,int,sig)
+_syscall5(int,sys_clone, int, flags, void *, child_stack, int *, parent_tidptr, struct user_desc *, newtls, int *, child_tidptr)
#ifdef __NR_exit_group
_syscall1(int,exit_group,int,error_code)
#endif
@@ -1699,7 +1704,7 @@ int do_modify_ldt(CPUX86State *env, int
return ret;
}
-int do_set_thread_area(CPUX86State *env, target_ulong ptr)
+int do_set_thread_area(CPUX86State *env, target_ulong ptr, int set_shadow_registers)
{
uint64_t *gdt_table = g2h(env->gdt.base);
struct target_modify_ldt_ldt_s ldt_info;
@@ -1708,6 +1713,7 @@ int do_set_thread_area(CPUX86State *env,
int seg_not_present, useable;
uint32_t *lp, entry_1, entry_2;
int i;
+ SegmentCache *sc = &env->segs[R_GS];
lock_user_struct(target_ldt_info, ptr, 1);
ldt_info.entry_number = tswap32(target_ldt_info->entry_number);
@@ -1767,6 +1767,12 @@ int do_set_thread_area(CPUX86State *env,
(useable << 20) |
0x7000;
+ if(set_shadow_registers) {
+ sc->selector = env->regs[R_GS];
+ sc->base = ldt_info.base_addr;
+ sc->limit = ldt_info.limit;
+ sc->flags = entry_2;
+ }
/* Install the new entry ... */
install:
lp = (uint32_t *)(gdt_table + ldt_info.entry_number);
@@ -1779,20 +1802,21 @@ install:
thread/process */
#define NEW_STACK_SIZE 8192
-static int clone_func(void *arg)
+static int clone_func(CPUState *cloneenv)
{
- CPUState *env = arg;
- cpu_loop(env);
+ cpu_loop(cloneenv);
/* never exits */
return 0;
}
-int do_fork(CPUState *env, unsigned int flags, unsigned long newsp)
+int do_fork(CPUState *env, unsigned int flags, target_ulong newsp, target_ulong parent_tidptr, target_ulong newtls, target_ulong child_tidptr)
{
int ret;
+ int cpu_index;
+ unsigned long parent_tid=gettid();
TaskState *ts;
uint8_t *new_stack;
- CPUState *new_env;
+ CPUState *new_env, *next_cpu;
#if defined(TARGET_I386)
uint64_t *new_gdt_table;
#endif
@@ -1807,9 +1835,14 @@ int do_fork(CPUState *env, unsigned int
/* add in task state list */
ts->next = first_task_state;
first_task_state = ts;
- /* we create a new CPU instance. */
- new_env = cpu_init();
- memcpy(new_env, env, sizeof(CPUState));
+ /* we create a new CPU instance. (cpu_copy() in cvs) */
+ new_env = cpu_init();
+ /* preserve chaining and index */
+ next_cpu = new_env->next_cpu;
+ cpu_index = new_env->cpu_index;
+ memcpy(new_env, env, sizeof(CPUState));
+ new_env->next_cpu = next_cpu;
+ new_env->cpu_index = cpu_index;
#if defined(TARGET_I386)
if (!newsp)
newsp = env->regs[R_ESP];
@@ -1818,26 +1851,20 @@ int do_fork(CPUState *env, unsigned int
free(new_env);
return -ENOMEM;
}
/* Copy main GDT table from parent, but clear TLS entries */
memcpy(new_gdt_table, g2h(env->gdt.base), 6 * 8);
memset(&new_gdt_table[6], 0, 3 * 8);
new_env->gdt.base = h2g(new_gdt_table);
- if (flags & 0x00080000 /* CLONE_SETTLS */) {
- ret = do_set_thread_area(new_env, new_env->regs[R_ESI]);
+ if (flags & CLONE_SETTLS) {
+ ret = do_set_thread_area(new_env, newtls, 1);
if (ret) {
free(new_gdt_table);
free(new_env);
return ret;
}
}
- cpu_x86_load_seg(env, R_CS, new_env->regs[R_CS]);
- cpu_x86_load_seg(env, R_DS, new_env->regs[R_DS]);
- cpu_x86_load_seg(env, R_ES, new_env->regs[R_ES]);
- cpu_x86_load_seg(env, R_SS, new_env->regs[R_SS]);
- cpu_x86_load_seg(env, R_FS, new_env->regs[R_FS]);
- cpu_x86_load_seg(env, R_GS, new_env->regs[R_GS]);
new_env->regs[R_ESP] = newsp;
new_env->regs[R_EAX] = 0;
#elif defined(TARGET_ARM)
if (!newsp)
newsp = env->regs[13];
@@ -1877,16 +1933,28 @@ int do_fork(CPUState *env, unsigned int
#endif
new_env->opaque = ts;
#ifdef __ia64__
- ret = __clone2(clone_func, new_stack + NEW_STACK_SIZE, flags, new_env);
+ ret = __clone2(clone_func, new_stack + NEW_STACK_SIZE, flags & ~(CLONE_SETTLS|CLONE_PARENT_SETTID|CLONE_CHILD_CLEARTID), new_env);
#else
- ret = clone(clone_func, new_stack + NEW_STACK_SIZE, flags, new_env);
+ ret = clone(clone_func, new_stack + NEW_STACK_SIZE, flags & ~(CLONE_SETTLS|CLONE_PARENT_SETTID|CLONE_CHILD_CLEARTID), new_env);
#endif
} else {
/* if no CLONE_VM, we consider it is a fork */
- if ((flags & ~CSIGNAL) != 0)
- return -EINVAL;
- ret = fork();
+ ret = sys_clone(flags & ~(CLONE_SETTLS|CLONE_PARENT_SETTID|CLONE_CHILD_CLEARTID), 0, g2h(parent_tidptr), NULL, g2h(child_tidptr));
+ }
+ /* Store child thread ID at location parent_tidptr in parent and child memory.
+ Currently this is only done in client memory*/
+ if(flags & CLONE_PARENT_SETTID) {
+ tput32(parent_tidptr, parent_tid);
+ }
+
+ /* Store child thread ID at location child_tidptr in child memory. */
+ if(flags & CLONE_CHILD_SETTID) {
+ if(ret==0) { // only in client memory for fork()
+ tput32(child_tidptr, gettid());
+ } else if(flags & CLONE_VM) { // real threads need it too
+ tput32(child_tidptr, ret);
+ }
}
return ret;
}
@@ -2206,7 +2221,7 @@ long do_syscall(void *cpu_env, int num,
ret = do_brk(arg1);
break;
case TARGET_NR_fork:
- ret = get_errno(do_fork(cpu_env, SIGCHLD, 0));
+ ret = get_errno(do_fork(cpu_env, SIGCHLD, 0, 0,0,0));
break;
case TARGET_NR_waitpid:
{
@@ -3281,7 +3297,7 @@ long do_syscall(void *cpu_env, int num,
ret = get_errno(fsync(arg1));
break;
case TARGET_NR_clone:
- ret = get_errno(do_fork(cpu_env, arg1, arg2));
+ ret = get_errno(do_fork(cpu_env, arg1, arg2,arg3,arg4,arg5));
break;
#ifdef __NR_exit_group
/* new thread calls */
@@ -3339,7 +3397,7 @@ long do_syscall(void *cpu_env, int num,
ret = do_vm86(cpu_env, arg1, arg2);
break;
case TARGET_NR_set_thread_area:
- ret = get_errno(do_set_thread_area(cpu_env, arg1));
+ ret = get_errno(do_set_thread_area(cpu_env, arg1, 0));
break;
#endif
case TARGET_NR_adjtimex:
@@ -3635,7 +3651,7 @@ long do_syscall(void *cpu_env, int num,
#endif
#ifdef TARGET_NR_vfork
case TARGET_NR_vfork:
- ret = get_errno(do_fork(cpu_env, CLONE_VFORK | CLONE_VM | SIGCHLD, 0));
+ ret = get_errno(do_fork(cpu_env, CLONE_VFORK | CLONE_VM | SIGCHLD, 0, 0,0,0));
break;
#endif
#ifdef TARGET_NR_ugetrlimit
@@ -4164,6 +4180,11 @@ long do_syscall(void *cpu_env, int num,
ret = get_errno(sys_fadvise64((int)arg1, arg2, arg3, (int)arg4));
break;
#endif
+#ifdef TARGET_NR_tgkill
+ case TARGET_NR_tgkill:
+ ret = get_errno(sys_tgkill((int)arg1, (int)arg2, (int)arg3));
+ break;
+#endif
default:
unimplemented:
gemu_log("qemu: Unsupported syscall: %d\n", num);

View File

@ -1,10 +0,0 @@
Index: qemu-0.9.0/linux-user/i386/syscall_nr.h
===================================================================
--- qemu-0.9.0.orig/linux-user/i386/syscall_nr.h
+++ qemu-0.9.0/linux-user/i386/syscall_nr.h
@@ -274,3 +274,5 @@
#define TARGET_NR_tgkill 270
#define TARGET_NR_utimes 271
#define TARGET_NR_fadvise64_64 272
+
+#define TARGET_NR_set_robust_list 311

View File

@ -1,32 +0,0 @@
Index: qemu-0.9.0/linux-user/syscall.c
===================================================================
--- qemu-0.9.0.orig/linux-user/syscall.c
+++ qemu-0.9.0/linux-user/syscall.c
@@ -147,6 +147,7 @@ type name (type1 arg1,type2 arg2,type3 a
#define __NR_sys_fadvise64 __NR_fadvise64
#define __NR_sys_tgkill __NR_tgkill
#define __NR_sys_clone __NR_clone
+#define __NR_sys_sched_getaffinity __NR_sched_getaffinity
#if defined(__alpha__) || defined (__ia64__) || defined(__x86_64__)
#define __NR__llseek __NR_lseek
@@ -170,6 +171,7 @@ _syscall3(int,sys_syslog,int,type,char*,
_syscall4(int,sys_fadvise64,int,fd,loff_t,offset,loff_t,len,int,advice)
_syscall3(int,sys_tgkill,int,tgid,int,pid,int,sig)
_syscall5(int,sys_clone, int, flags, void *, child_stack, int *, parent_tidptr, struct user_desc *, newtls, int *, child_tidptr)
+_syscall3(int,sys_sched_getaffinity,pid_t,pid,unsigned int,cpusetsize,void*,mask)
#ifdef __NR_exit_group
_syscall1(int,exit_group,int,error_code)
#endif
@@ -4248,6 +4250,11 @@ long do_syscall(void *cpu_env, int num,
ret = get_errno(sys_tgkill((int)arg1, (int)arg2, (int)arg3));
break;
#endif
+#ifdef TARGET_NR_sched_getaffinity
+ case TARGET_NR_sched_getaffinity:
+ ret = get_errno(sys_sched_getaffinity((pid_t)arg1, (unsigned int)arg2, (void*)arg3));
+ break;
+#endif
default:
unimplemented:
gemu_log("qemu: Unsupported syscall: %d\n", num);

View File

@ -1,22 +0,0 @@
Index: qemu-0.9.0/linux-user/syscall.c
===================================================================
--- qemu-0.9.0.orig/linux-user/syscall.c
+++ qemu-0.9.0/linux-user/syscall.c
@@ -869,7 +869,7 @@ static long do_getpeername(int fd, targe
target_ulong target_addrlen)
{
socklen_t addrlen = tget32(target_addrlen);
- void *addr = alloca(target_addrlen);
+ void *addr = alloca(addrlen);
long ret;
gemu_log("getpeername(%d,0x%lx,0x%lx)\n", fd, addr, addrlen);
@@ -887,7 +887,7 @@ static long do_getsockname(int fd, targe
target_ulong target_addrlen)
{
socklen_t addrlen = tget32(target_addrlen);
- void *addr = alloca(target_addrlen);
+ void *addr = alloca(addrlen);
long ret;
ret = get_errno(getsockname(fd, addr, &addrlen));

File diff suppressed because it is too large Load Diff

View File

@ -1,92 +0,0 @@
--- linux-user/syscall.c
+++ linux-user/syscall.c
@@ -140,6 +140,7 @@
#define __NR_sys_getdents __NR_getdents
#define __NR_sys_getdents64 __NR_getdents64
#define __NR_sys_rt_sigqueueinfo __NR_rt_sigqueueinfo
+#define __NR_sys_syslog __NR_syslog
#if defined(__alpha__) || defined (__ia64__) || defined(__x86_64__)
#define __NR__llseek __NR_lseek
@@ -159,6 +160,7 @@
_syscall5(int, _llseek, uint, fd, ulong, hi, ulong, lo,
loff_t *, res, uint, wh);
_syscall3(int,sys_rt_sigqueueinfo,int,pid,int,sig,siginfo_t *,uinfo)
+_syscall3(int,sys_syslog,int,type,char*,bufp,int,len)
#ifdef __NR_exit_group
_syscall1(int,exit_group,int,error_code)
#endif
@@ -172,6 +174,7 @@
extern int setresgid(gid_t, gid_t, gid_t);
extern int getresgid(gid_t *, gid_t *, gid_t *);
extern int setgroups(int, gid_t *);
+extern int uselib(const char*);
static inline long get_errno(long ret)
{
@@ -2709,7 +2712,9 @@
}
break;
case TARGET_NR_uselib:
- goto unimplemented;
+ ret = get_errno(uselib(path((const char*)arg1)));
+ break;
+
case TARGET_NR_swapon:
p = lock_user_string(arg1);
ret = get_errno(swapon(p, arg2));
@@ -2949,7 +2954,9 @@
#endif
case TARGET_NR_syslog:
- goto unimplemented;
+ ret = get_errno(sys_syslog((int)arg1, (char*)arg2, (int)arg3));
+ break;
+
case TARGET_NR_setitimer:
{
struct itimerval value, ovalue, *pvalue;
@@ -3824,7 +3831,9 @@
goto unimplemented;
#ifdef TARGET_NR_mincore
case TARGET_NR_mincore:
- goto unimplemented;
+ page_unprotect_range((void*)arg3, ((size_t)arg2 + TARGET_PAGE_SIZE - 1) / TARGET_PAGE_SIZE);
+ ret = get_errno(mincore((void*)arg1, (size_t)arg2, (unsigned char*)arg3));
+ break;
#endif
#ifdef TARGET_NR_madvise
case TARGET_NR_madvise:
@@ -3921,7 +3930,8 @@
ret = get_errno(gettid());
break;
case TARGET_NR_readahead:
- goto unimplemented;
+ ret = get_errno(readahead((int)arg1, (off64_t)arg2, (size_t)arg3));
+ break;
#ifdef TARGET_NR_setxattr
case TARGET_NR_setxattr:
case TARGET_NR_lsetxattr:
@@ -3946,6 +3956,22 @@
case TARGET_NR_getdomainname:
goto unimplemented_nowarn;
#endif
+#ifdef TARGET_NR_clock_gettime
+ case TARGET_NR_clock_gettime:
+ {
+ struct target_timespec* ttp = (struct target_timespec*)arg2;
+ struct timespec htp;
+ if(ttp) {
+ htp.tv_sec = tswapl(ttp->tv_sec);
+ htp.tv_nsec = tswapl(ttp->tv_nsec);
+ ret = get_errno(clock_gettime((clockid_t)arg1, &htp));
+ ttp->tv_sec = tswapl(htp.tv_sec);
+ ttp->tv_nsec = tswapl(htp.tv_nsec);
+ } else
+ ret = get_errno(clock_gettime((clockid_t)arg1, NULL));
+ break;
+ }
+#endif
default:
unimplemented:
gemu_log("qemu: Unsupported syscall: %d\n", num);

View File

@ -1,12 +0,0 @@
Index: qemu-0.9.0/linux-user/main.c
===================================================================
--- qemu-0.9.0.orig/linux-user/main.c
+++ qemu-0.9.0/linux-user/main.c
@@ -1787,6 +1787,7 @@ int main(int argc, char **argv)
cpu_x86_load_seg(env, R_FS, __USER_DS);
cpu_x86_load_seg(env, R_GS, __USER_DS);
+ env->segs[R_FS].selector = 0;
#elif defined(TARGET_ARM)
{
int i;

View File

@ -1,79 +0,0 @@
2007-03-13 Gwenole Beauchesne <gbeauchesne@mandriva.com>
* dyngen-exec.h (AREG4, AREG5): Temporarily disable for KVM support.
2007-02-03 Gwenole Beauchesne <gbeauchesne@mandriva.com>
* dyngen-exec.h (AREG4, AREG5): Enable when building with GCC4.
2005-06-04 Gwenole Beauchesne <gbeauchesne@mandriva.com>
* Add direct jump support to x86-64.
================================================================================
--- qemu-0.9.0/dyngen-exec.h
+++ qemu-0.9.0/dyngen-exec.h
@@ -95,8 +95,11 @@
#define AREG1 "rbx"
#define AREG2 "r12"
#define AREG3 "r13"
-//#define AREG4 "r14"
-//#define AREG5 "r15"
+#if __GNUC__ >= 4 && ! USE_KVM
+/* XXX: earlier GCC crashes */
+#define AREG4 "r14"
+#define AREG5 "r15"
+#endif
#endif
#ifdef __powerpc__
#define AREG0 "r27"
--- qemu-0.9.0/dyngen.c
+++ qemu-0.9.0/dyngen.c
@@ -2614,6 +2614,17 @@
if (rel->r_offset >= start_offset &&
rel->r_offset < start_offset + copy_size) {
sym_name = strtab + symtab[ELFW(R_SYM)(rel->r_info)].st_name;
+ if (strstart(sym_name, "__op_jmp", &p)) {
+ int n;
+ n = strtol(p, NULL, 10);
+ /* __op_jmp relocations are done at
+ runtime to do translated block
+ chaining: the offset of the instruction
+ needs to be stored */
+ fprintf(outfile, " jmp_offsets[%d] = %d + (gen_code_ptr - gen_code_buf);\n",
+ n, rel->r_offset - start_offset);
+ continue;
+ }
get_reloc_expr(name, sizeof(name), sym_name);
type = ELF32_R_TYPE(rel->r_info);
addend = rel->r_addend;
--- qemu-0.9.0/exec-all.h
+++ qemu-0.9.0/exec-all.h
@@ -159,6 +159,9 @@
#if defined(__i386__) && !defined(_WIN32)
#define USE_DIRECT_JUMP
#endif
+#if defined(__x86_64__)
+#define USE_DIRECT_JUMP
+#endif
typedef struct TranslationBlock {
target_ulong pc; /* simulated PC corresponding to this block (EIP + CS base) */
@@ -245,7 +248,7 @@
asm volatile ("sync" : : : "memory");
asm volatile ("isync" : : : "memory");
}
-#elif defined(__i386__)
+#elif defined(__i386__) || defined(__x86_64__)
static inline void tb_set_jmp_target1(unsigned long jmp_addr, unsigned long addr)
{
/* patch the branch destination */
@@ -324,7 +327,7 @@
"1:\n");\
} while (0)
-#elif defined(__i386__) && defined(USE_DIRECT_JUMP)
+#elif (defined(__i386__) || defined(__x86_64__)) && defined(USE_DIRECT_JUMP)
/* we patch the jump instruction directly. Use sti in place of the actual
jmp instruction so that dyngen can patch in the correct result. */

3
qemu-0.9.0.cvs.tar.bz2 Normal file
View File

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:b21915f6e941724eba05dce9b0f96295e4f7ff69b7ea0f743f5798c678b8839e
size 2043438

View File

@ -1,35 +0,0 @@
--- linux-user/signal.c
+++ linux-user/signal.c 2007/02/12 12:47:45
@@ -389,6 +389,8 @@
{
int sig;
target_siginfo_t tinfo;
+
+ //printf("host_signal_handler, signum %d\n",host_signum);
/* the CPU emulator uses some host signals to detect exceptions,
we we forward to it some signals */
--- Makefile
+++ Makefile 2007/02/12 12:48:38
@@ -27,7 +27,7 @@
ifndef CONFIG_DARWIN
ifndef CONFIG_WIN32
ifndef CONFIG_SOLARIS
-LIBS+=-lrt
+LIBS+=-lrt -lpthread
endif
endif
endif
--- Makefile.target
+++ Makefile.target 2007/02/12 12:47:45
@@ -181,8 +181,8 @@
#########################################################
-CPPFLAGS+=-D_GNU_SOURCE -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE
-LIBS+=-lm
+CPPFLAGS+=-D_GNU_SOURCE -D_BSD_SOURCE -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE
+LIBS+=-lm -lrt -lpthread
ifndef CONFIG_USER_ONLY
LIBS+=-lz
endif

View File

@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:1ce3d34e3fafde6a3802f3c6317dac14f6b482fa918df0d3af54edd8b0314242
size 1625107

View File

@ -0,0 +1,67 @@
Index: qemu/thunk.h
===================================================================
--- qemu.orig/thunk.h
+++ qemu/thunk.h
@@ -38,6 +38,7 @@ typedef enum argtype {
TYPE_PTR,
TYPE_ARRAY,
TYPE_STRUCT,
+ TYPE_INTBITFIELD,
} argtype;
#define MK_PTR(type) TYPE_PTR, type
@@ -87,6 +88,7 @@ static inline int thunk_type_size(const
case TYPE_SHORT:
return 2;
case TYPE_INT:
+ case TYPE_INTBITFIELD:
return 4;
case TYPE_LONGLONG:
case TYPE_ULONGLONG:
@@ -124,6 +126,7 @@ static inline int thunk_type_align(const
case TYPE_SHORT:
return 2;
case TYPE_INT:
+ case TYPE_INTBITFIELD:
return 4;
case TYPE_LONGLONG:
case TYPE_ULONGLONG:
Index: qemu/thunk.c
===================================================================
--- qemu.orig/thunk.c
+++ qemu/thunk.c
@@ -40,6 +40,7 @@ static inline const argtype *thunk_type_
case TYPE_CHAR:
case TYPE_SHORT:
case TYPE_INT:
+ case TYPE_INTBITFIELD:
case TYPE_LONGLONG:
case TYPE_ULONGLONG:
case TYPE_LONG:
@@ -132,6 +133,26 @@ const argtype *thunk_convert(void *dst,
case TYPE_INT:
*(uint32_t *)dst = tswap32(*(uint32_t *)src);
break;
+ case TYPE_INTBITFIELD:
+#if defined(TARGET_I386) && defined(__powerpc__)
+ /* powerpc uses the MSB, whereas i386 uses the LSB
+ * to store the first bit in a field */
+ {
+ unsigned char byte = *(uint8_t *)src;
+ *(uint8_t *)dst = ((byte >> 7) & 1)
+ | ((byte >> 5) & 2)
+ | ((byte >> 3) & 4)
+ | ((byte >> 1) & 8)
+ | ((byte << 1) & 16)
+ | ((byte << 3) & 32)
+ | ((byte << 5) & 64)
+ | ((byte << 7) & 128);
+ /* FIXME: implement for bitfields > 1 byte and other archs */
+ }
+#else
+ *(uint32_t *)dst = tswap32(*(uint32_t *)src);
+#endif
+ break;
case TYPE_LONGLONG:
case TYPE_ULONGLONG:
*(uint64_t *)dst = tswap64(*(uint64_t *)src);

3592
qemu-cvs-alsa_ioctl.patch Normal file

File diff suppressed because it is too large Load Diff

32
qemu-cvs-alsa_mmap.patch Normal file
View File

@ -0,0 +1,32 @@
Index: qemu/linux-user/mmap.c
===================================================================
--- qemu.orig/linux-user/mmap.c
+++ qemu/linux-user/mmap.c
@@ -152,6 +152,9 @@ static int mmap_frag(target_ulong real_s
return 0;
}
+#define SNDRV_PCM_MMAP_OFFSET_STATUS 0x80000000
+#define SNDRV_PCM_MMAP_OFFSET_CONTROL 0x81000000
+
/* NOTE: all the constants are the HOST ones */
long target_mmap(target_ulong start, target_ulong len, int prot,
int flags, int fd, target_ulong offset)
@@ -192,6 +195,17 @@ long target_mmap(target_ulong start, tar
}
#endif
+ /* Alsa tries to communcate with the kernel via mmap. This usually
+ * is a good idea when user- and kernelspace are running on the
+ * same architecture but does not work out when not. To make alsa
+ * not to use mmap, we can just have it fail on the mmap calls that
+ * would initiate this.
+ */
+ if(offset == SNDRV_PCM_MMAP_OFFSET_STATUS || offset == SNDRV_PCM_MMAP_OFFSET_CONTROL) {
+ errno = EINVAL;
+ return -1;
+ }
+
if (offset & ~TARGET_PAGE_MASK) {
errno = EINVAL;
return -1;

13
qemu-cvs-flash.patch Normal file
View File

@ -0,0 +1,13 @@
Index: qemu/linux-user/syscall.c
===================================================================
--- qemu.orig/linux-user/syscall.c
+++ qemu/linux-user/syscall.c
@@ -1736,6 +1736,8 @@ static long do_ipc(long call, long first
switch (call) {
case IPCOP_semop:
+ ret = -EINVAL;
+ break;
{
struct sembuf *target_sops;
int i;

125
qemu-cvs-futex.patch Normal file
View File

@ -0,0 +1,125 @@
Index: qemu.bkp/linux-user/syscall.c
===================================================================
--- qemu.bkp.orig/linux-user/syscall.c
+++ qemu.bkp/linux-user/syscall.c
@@ -17,6 +17,8 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
+
+#define __user
#include <stdlib.h>
#include <stdio.h>
#include <stdarg.h>
@@ -60,6 +62,7 @@
#define tchars host_tchars /* same as target */
#define ltchars host_ltchars /* same as target */
+#include <linux/futex.h>
#include <linux/termios.h>
#include <linux/unistd.h>
#include <linux/utsname.h>
@@ -2554,6 +2557,91 @@ static inline void host_to_target_timesp
unlock_user_struct(target_ts, target_addr, 1);
}
+#ifdef BSWAP_NEEDED
+static int futex_op(int oldval, int op, int oparg)
+{
+ int retval = oparg;
+ switch(op) {
+ case FUTEX_OP_SET: break;
+ case FUTEX_OP_ADD: retval += oparg; break;
+ case FUTEX_OP_OR: retval |= oparg; break;
+ case FUTEX_OP_ANDN: retval &= oparg; break;
+ case FUTEX_OP_XOR: retval ^= oparg; break;
+ }
+ return retval;
+}
+
+static int futex_cmp(int oldval, int cmp, int cmparg)
+{
+ switch(cmp) {
+ case FUTEX_OP_CMP_EQ: return oldval == cmparg;
+ case FUTEX_OP_CMP_NE: return oldval != cmparg;
+ case FUTEX_OP_CMP_LT: return oldval < cmparg;
+ case FUTEX_OP_CMP_LE: return oldval <= cmparg;
+ case FUTEX_OP_CMP_GT: return oldval > cmparg;
+ case FUTEX_OP_CMP_GE: return oldval >= cmparg;
+ }
+ return -1;
+}
+#endif
+
+static long do_futex(target_ulong uaddr, int op, uint32_t val,
+ target_ulong utime, target_ulong uaddr2,
+ uint32_t val3)
+{
+ struct timespec host_utime;
+ unsigned long val2 = utime;
+ long retval;
+
+ if (utime && (op == FUTEX_WAIT || op == FUTEX_LOCK_PI)) {
+ target_to_host_timespec(&host_utime, utime);
+ val2 = (unsigned long)&host_utime;
+ }
+
+#ifdef BSWAP_NEEDED
+ switch(op) {
+ case FUTEX_CMP_REQUEUE:
+ val3 = tswap32(val3);
+ case FUTEX_REQUEUE:
+ val2 = tswap32(val2);
+ case FUTEX_WAIT:
+ case FUTEX_WAKE:
+ case FUTEX_WAKE_OP:
+ val = tswap32(val);
+ case FUTEX_LOCK_PI: /* This one's icky, but comes out OK */
+ case FUTEX_UNLOCK_PI:
+ break;
+ default:
+ gemu_log("qemu: Unsupported futex op %d\n", op);
+ return -ENOSYS;
+ }
+ if (op == FUTEX_WAKE_OP) {
+ /* Need to munge the secondary operation (val3) */
+ gemu_log("qemu: Tricky FUTEX_WAKE_OP - trying to emulate it\n");
+ val3 = tswap32(val3);
+ int op2 = (val3 >> 28) & 0xf;
+ int cmp = (val3 >> 24) & 0xf;
+ int oparg = (val3 >> 12) & 0xfff;
+ int cmparg = val3 & 0xfff;
+ int shift = val3 & (FUTEX_OP_OPARG_SHIFT << 28);
+ int oldval = tget32(uaddr2);
+ if (shift)
+ oparg = 1 << oparg;
+
+ tput32(uaddr2,futex_op(oldval, op2, oparg));
+ retval = syscall(__NR_futex, g2h(uaddr), FUTEX_WAKE, val, 0, 0, 0);
+ if(futex_cmp(oldval, cmp, cmparg)) {
+ retval = syscall(__NR_futex, g2h(uaddr2), FUTEX_WAKE, val2, 0, 0, 0);
+ }
+ } else {
+ retval = syscall(__NR_futex, g2h(uaddr), op, val, val2, g2h(uaddr2), val3);
+ }
+#else
+ retval = syscall(__NR_futex, g2h(uaddr), op, val, val2, g2h(uaddr2), val3);
+#endif
+ return retval;
+}
+
long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3,
long arg4, long arg5, long arg6)
{
@@ -4713,6 +4801,11 @@ long do_syscall(void *cpu_env, int num,
}
#endif
+#ifdef TARGET_NR_futex
+ case TARGET_NR_futex:
+ ret = get_errno(do_futex(arg1, arg2, arg3, arg4, arg5, arg6));
+ break;
+#endif
#if defined(TARGET_NR_set_tid_address) && defined(__NR_set_tid_address)
case TARGET_NR_set_tid_address:
ret = get_errno(set_tid_address((int *) arg1));

View File

@ -0,0 +1,34 @@
Index: qemu/linux-user/syscall.c
===================================================================
--- qemu.orig/linux-user/syscall.c
+++ qemu/linux-user/syscall.c
@@ -3596,6 +3596,7 @@ long do_syscall(void *cpu_env, int num,
case TARGET_NR_gettimeofday:
{
struct timeval tv;
+ target_to_host_timeval(&tv, arg1);
ret = get_errno(gettimeofday(&tv, NULL));
if (!is_error(ret)) {
host_to_target_timeval(arg1, &tv);
Index: qemu/linux-user/signal.c
===================================================================
--- qemu.orig/linux-user/signal.c
+++ qemu/linux-user/signal.c
@@ -207,6 +207,8 @@ static inline void host_to_target_siginf
/* should never come here, but who knows. The information for
the target is irrelevant */
tinfo->_sifields._sigfault._addr = 0;
+ } else if (sig == SIGIO) {
+ tinfo->_sifields._sigpoll._fd = info->si_fd;
} else if (sig >= TARGET_SIGRTMIN) {
tinfo->_sifields._rt._pid = info->si_pid;
tinfo->_sifields._rt._uid = info->si_uid;
@@ -228,6 +230,8 @@ static void tswap_siginfo(target_siginfo
sig == SIGBUS || sig == SIGTRAP) {
tinfo->_sifields._sigfault._addr =
tswapl(info->_sifields._sigfault._addr);
+ } else if (sig == SIGIO) {
+ tinfo->_sifields._sigpoll._fd = tswap32(info->_sifields._sigpoll._fd);
} else if (sig >= TARGET_SIGRTMIN) {
tinfo->_sifields._rt._pid = tswap32(info->_sifields._rt._pid);
tinfo->_sifields._rt._uid = tswap32(info->_sifields._rt._uid);

47
qemu-cvs-ia64.patch Normal file
View File

@ -0,0 +1,47 @@
--- Makefile.target.~1.186.~ 2007-07-02 17:08:34.000000000 +0200
+++ Makefile.target 2007-07-09 19:13:35.000000000 +0200
@@ -92,6 +92,8 @@ cc-option = $(shell if $(CC) $(OP_CFLAGS
OP_CFLAGS+=$(call cc-option, -fno-reorder-blocks, "")
OP_CFLAGS+=$(call cc-option, -fno-gcse, "")
OP_CFLAGS+=$(call cc-option, -fno-tree-ch, "")
+OP_CFLAGS+=$(call cc-option, -fno-tree-dominator-opts, "")
+OP_CFLAGS+=$(call cc-option, -fno-tree-vrp, "")
OP_CFLAGS+=$(call cc-option, -fno-optimize-sibling-calls, "")
OP_CFLAGS+=$(call cc-option, -fno-crossjumping, "")
OP_CFLAGS+=$(call cc-option, -fno-align-labels, "")
@@ -165,8 +167,9 @@ BASE_LDFLAGS+=-Wl,-T,$(SRC_PATH)/$(ARCH)
endif
ifeq ($(ARCH),ia64)
-BASE_CFLAGS+=-mno-sdata
-OP_CFLAGS+=-mno-sdata
+OP_CFLAGS+=$(call cc-option, -mno-sched-ar-data-spec, "")
+BASE_CFLAGS+=-G0 -mno-sdata
+OP_CFLAGS+=-G0 -mno-sdata
BASE_LDFLAGS+=-Wl,-G0 -Wl,-T,$(SRC_PATH)/$(ARCH).ld
endif
--- target-alpha/op.c.~1.1.~ 2007-04-05 08:58:33.000000000 +0200
+++ target-alpha/op.c 2007-07-09 20:11:42.000000000 +0200
@@ -18,8 +18,6 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#define DEBUG_OP
-
#include "config.h"
#include "exec.h"
@@ -125,8 +123,12 @@
void OPPROTO op_no_op (void)
{
#if !defined (DEBUG_OP)
+#ifdef __ia64__
+ __asm__ __volatile__("nop 0" : : : "memory");
+#else
__asm__ __volatile__("nop" : : : "memory");
#endif
+#endif
RETURN();
}

11
qemu-cvs-img.patch Normal file
View File

@ -0,0 +1,11 @@
--- Makefile.orig 2007-07-05 14:43:40.000000000 +0000
+++ Makefile 2007-07-05 14:46:50.000000000 +0000
@@ -33,7 +33,7 @@
recurse-all: $(patsubst %,subdir-%, $(TARGET_DIRS))
qemu-img$(EXESUF): qemu-img.c cutils.c block.c block-raw.c block-cow.c block-qcow.c aes.c block-vmdk.c block-cloop.c block-dmg.c block-bochs.c block-vpc.c block-vvfat.c block-qcow2.c
- $(CC) -DQEMU_TOOL $(CFLAGS) $(CPPFLAGS) $(BASE_CFLAGS) $(LDFLAGS) $(BASE_LDFLAGS) -o $@ $^ -lz $(LIBS)
+ $(CC) -DQEMU_TOOL $(CFLAGS) $(CPPFLAGS) $(BASE_CFLAGS) $(LDFLAGS) -o $@ $^ -lz $(LIBS)
dyngen$(EXESUF): dyngen.c
$(HOST_CC) $(CFLAGS) $(CPPFLAGS) $(BASE_CFLAGS) -o $@ $^

View File

@ -0,0 +1,18 @@
Index: qemu/linux-user/syscall.c
===================================================================
--- qemu.orig/linux-user/syscall.c
+++ qemu/linux-user/syscall.c
@@ -1950,7 +1950,12 @@ static long do_ioctl(long fd, long cmd,
ie = ioctl_entries;
for(;;) {
if (ie->target_cmd == 0) {
- gemu_log("Unsupported ioctl: cmd=0x%04lx\n", cmd);
+ int i;
+ gemu_log("Unsupported ioctl: cmd=0x%04lx (%x)\n", cmd, (cmd & (TARGET_IOC_SIZEMASK << TARGET_IOC_SIZESHIFT)) >> TARGET_IOC_SIZESHIFT);
+ for(i=0;ioctl_entries[i].target_cmd;i++) {
+ if((ioctl_entries[i].target_cmd & ~(TARGET_IOC_SIZEMASK << TARGET_IOC_SIZESHIFT)) == (cmd & ~(TARGET_IOC_SIZEMASK << TARGET_IOC_SIZESHIFT)))
+ gemu_log("%p\t->\t%s (%x)\n", ioctl_entries[i].host_cmd, ioctl_entries[i].name, (ioctl_entries[i].target_cmd & (TARGET_IOC_SIZEMASK << TARGET_IOC_SIZESHIFT)) >> TARGET_IOC_SIZESHIFT);
+ }
return -ENOSYS;
}
if (ie->target_cmd == cmd)

View File

@ -0,0 +1,24 @@
Index: qemu/linux-user/syscall.c
===================================================================
--- qemu.orig/linux-user/syscall.c
+++ qemu/linux-user/syscall.c
@@ -1980,6 +1980,11 @@ static long do_ioctl(long fd, long cmd,
arg_type++;
target_size = thunk_type_size(arg_type, 0);
switch(ie->access) {
+ /* FIXME: actually the direction given in the ioctl should be
+ * correct so we can assume the communication is uni-directional.
+ * The alsa developers did not like this concept though and
+ * declared ioctls IOC_R and IOC_W even though they were IOC_RW.*/
+/*
case IOC_R:
ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp));
if (!is_error(ret)) {
@@ -1994,6 +1999,7 @@ static long do_ioctl(long fd, long cmd,
unlock_user(argptr, arg, 0);
ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp));
break;
+*/
default:
case IOC_RW:
argptr = lock_user(arg, target_size, 1);

341
qemu-cvs-ipc.patch Normal file
View File

@ -0,0 +1,341 @@
Index: qemu/linux-user/syscall.c
===================================================================
--- qemu.orig/linux-user/syscall.c
+++ qemu/linux-user/syscall.c
@@ -29,7 +29,7 @@
#include <unistd.h>
#include <fcntl.h>
#include <time.h>
-#include <sys/types.h>
+#include <linux/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <sys/wait.h>
@@ -46,6 +46,9 @@
#include <sys/uio.h>
#include <sys/poll.h>
#include <sys/times.h>
+#include <asm/ipcbuf.h>
+#include <asm/shmbuf.h>
+#include <asm/sembuf.h>
#include <sys/shm.h>
#include <sys/sem.h>
#include <sys/statfs.h>
@@ -150,6 +153,7 @@ type name (type1 arg1,type2 arg2,type3 a
#define __NR_sys_tgkill __NR_tgkill
#define __NR_sys_clone __NR_clone
#define __NR_sys_sched_getaffinity __NR_sched_getaffinity
+#define __NR_sys_ipc __NR_ipc
#if defined(__alpha__) || defined (__ia64__) || defined(__x86_64__)
#define __NR__llseek __NR_lseek
@@ -172,6 +176,10 @@ _syscall3(int,sys_rt_sigqueueinfo,int,pi
_syscall3(int,sys_syslog,int,type,char*,bufp,int,len)
_syscall3(int,sys_tgkill,int,tgid,int,pid,int,sig)
_syscall5(int,sys_clone, int, flags, void *, child_stack, int *, parent_tidptr, void *, newtls, int *, child_tidptr)
+#ifdef __NR_ipc
+_syscall6(int,sys_ipc, long, call, long, first, long, second, long, third, void *, ptr, long, fifth)
+#define semctl(a,b,c,d) sys_ipc(IPCOP_semctl,a,b,c,&d,0l)
+#endif
_syscall3(int,sys_sched_getaffinity,pid_t,pid,unsigned int,cpusetsize,void*,mask)
#ifdef __NR_exit_group
_syscall1(int,exit_group,int,error_code)
@@ -1255,6 +1263,21 @@ struct target_ipc_perm
target_ulong __unused2;
};
+struct target_ipc64_perm
+{
+ int key;
+ unsigned int uid;
+ unsigned int gid;
+ unsigned int cuid;
+ unsigned int cgid;
+ unsigned short mode;
+ unsigned short __pad1;
+ unsigned short seq;
+ unsigned short __pad2;
+ target_ulong __unused1;
+ target_ulong __unused2;
+};
+
struct target_semid_ds
{
struct target_ipc_perm sem_perm;
@@ -1267,6 +1290,18 @@ struct target_semid_ds
target_ulong __unused4;
};
+struct target_semid64_ds
+{
+ struct target_ipc64_perm sem_perm;
+ target_ulong sem_otime;
+ target_ulong __unused1;
+ target_ulong sem_ctime;
+ target_ulong __unused2;
+ target_ulong sem_nsems;
+ target_ulong __unused3;
+ target_ulong __unused4;
+};
+
static inline void target_to_host_ipc_perm(struct ipc_perm *host_ip,
target_ulong target_addr)
{
@@ -1301,6 +1336,41 @@ static inline void host_to_target_ipc_pe
unlock_user_struct(target_sd, target_addr, 1);
}
+static inline void target_to_host_ipc64_perm( struct ipc64_perm *host_ip, target_ulong target_addr )
+{
+ struct target_ipc64_perm *target_ip;
+ struct target_semid64_ds *target_sd;
+
+ lock_user_struct(target_sd, target_addr, 1);
+ target_ip=&(target_sd->sem_perm);
+ host_ip->key = tswapl(target_ip->key);
+ host_ip->uid = tswapl(target_ip->uid);
+ host_ip->gid = tswapl(target_ip->gid);
+ host_ip->cuid = tswapl(target_ip->cuid);
+ host_ip->cgid = tswapl(target_ip->cgid);
+ host_ip->mode = tswap16(target_ip->mode);
+ host_ip->seq = tswap16(target_ip->seq);
+ unlock_user_struct(target_sd, target_addr, 1);
+}
+
+static inline void host_to_target_ipc64_perm(target_ulong target_addr,
+ struct ipc64_perm *host_ip)
+{
+ struct target_ipc64_perm *target_ip;
+ struct target_semid64_ds *target_sd;
+
+ lock_user_struct(target_sd, target_addr, 0);
+ target_ip = &(target_sd->sem_perm);
+ target_ip->key = tswapl(host_ip->key);
+ target_ip->uid = tswapl(host_ip->uid);
+ target_ip->gid = tswapl(host_ip->gid);
+ target_ip->cuid = tswapl(host_ip->cuid);
+ target_ip->cgid = tswapl(host_ip->cgid);
+ target_ip->mode = tswap16(host_ip->mode);
+ target_ip->seq = tswap16(host_ip->seq);
+ unlock_user_struct(target_sd, target_addr, 1);
+}
+
static inline void target_to_host_semid_ds(struct semid_ds *host_sd,
target_ulong target_addr)
{
@@ -1327,6 +1397,32 @@ static inline void host_to_target_semid_
unlock_user_struct(target_sd, target_addr, 1);
}
+static inline void target_to_host_semid64_ds(struct semid64_ds *host_sd,
+ target_ulong target_addr)
+{
+ struct target_semid64_ds *target_sd;
+
+ lock_user_struct(target_sd, target_addr, 1);
+ target_to_host_ipc64_perm(&(host_sd->sem_perm),target_addr);
+ host_sd->sem_nsems = tswapl(target_sd->sem_nsems);
+ host_sd->sem_otime = tswapl(target_sd->sem_otime);
+ host_sd->sem_ctime = tswapl(target_sd->sem_ctime);
+ unlock_user_struct(target_sd, target_addr, 0);
+}
+
+static inline void host_to_target_semid64_ds(target_ulong target_addr,
+ struct semid64_ds *host_sd)
+{
+ struct target_semid64_ds *target_sd;
+
+ lock_user_struct(target_sd, target_addr, 0);
+ host_to_target_ipc64_perm(target_addr,&(host_sd->sem_perm));
+ target_sd->sem_nsems = tswapl(host_sd->sem_nsems);
+ target_sd->sem_otime = tswapl(host_sd->sem_otime);
+ target_sd->sem_ctime = tswapl(host_sd->sem_ctime);
+ unlock_user_struct(target_sd, target_addr, 1);
+}
+
union semun {
int val;
struct semid_ds *buf;
@@ -1339,6 +1435,10 @@ union target_semun {
unsigned short int *array;
};
+#ifndef IPC_64
+#define IPC_64 0x100
+#endif
+
static inline void target_to_host_semun(unsigned long cmd,
union semun *host_su,
target_ulong target_addr,
@@ -1350,7 +1450,16 @@ static inline void target_to_host_semun(
case IPC_STAT:
case IPC_SET:
lock_user_struct(target_su, target_addr, 1);
- target_to_host_semid_ds(ds,target_su->buf);
+ target_to_host_semid_ds(ds,tswapl(target_su->buf));
+ host_su->buf = ds;
+ unlock_user_struct(target_su, target_addr, 0);
+ break;
+ case IPC_STAT + IPC_64:
+ case IPC_SET + IPC_64:
+ lock_user_struct(target_su, target_addr, 1);
+
+ //target_to_host_semid_ds(ds,tswapl(target_su->buf));
+ target_to_host_semid64_ds((struct semid64_ds *)ds,tswapl(target_su->buf));
host_su->buf = ds;
unlock_user_struct(target_su, target_addr, 0);
break;
@@ -1382,7 +1491,14 @@ static inline void host_to_target_semun(
case IPC_STAT:
case IPC_SET:
lock_user_struct(target_su, target_addr, 0);
- host_to_target_semid_ds(target_su->buf,ds);
+ host_to_target_semid_ds(tswapl(target_su->buf),ds);
+ unlock_user_struct(target_su, target_addr, 1);
+ break;
+ case IPC_STAT + IPC_64:
+ case IPC_SET + IPC_64:
+ lock_user_struct(target_su, target_addr, 0);
+ //host_to_target_semid_ds(tswapl(target_su->buf),ds);
+ host_to_target_semid64_ds(tswapl(target_su->buf),(struct semid64_ds *)ds);
unlock_user_struct(target_su, target_addr, 1);
break;
case GETVAL:
@@ -1406,7 +1522,8 @@ static inline long do_semctl(long first,
{
union semun arg;
struct semid_ds dsarg;
- int cmd = third&0xff;
+ struct semid64_ds dsarg64;
+ int cmd = third; // & 0xff;
long ret = 0;
switch( cmd ) {
@@ -1435,13 +1552,23 @@ static inline long do_semctl(long first,
ret = get_errno(semctl(first, second, cmd, arg));
host_to_target_semun(cmd,ptr,&arg,&dsarg);
break;
+ case IPC_STAT + IPC_64:
+ target_to_host_semun(cmd,&arg,ptr,(struct semid_ds *)&dsarg64);
+ ret = get_errno(semctl(first, second, cmd, arg));
+ host_to_target_semun(cmd,ptr,&arg,(struct semid_ds *)&dsarg64);
+ break;
case IPC_SET:
target_to_host_semun(cmd,&arg,ptr,&dsarg);
ret = get_errno(semctl(first, second, cmd, arg));
host_to_target_semun(cmd,ptr,&arg,&dsarg);
break;
- default:
+ case IPC_SET + IPC_64:
+ target_to_host_semun(cmd,&arg,ptr,(struct semid_ds *)&dsarg64);
ret = get_errno(semctl(first, second, cmd, arg));
+ host_to_target_semun(cmd,ptr,&arg,(struct semid_ds *)&dsarg64);
+ break;
+ default:
+ ret = get_errno(semctl(first, second, cmd & 0xff, arg));
}
return ret;
@@ -1465,6 +1592,42 @@ struct target_msqid_ds
target_ulong __unused5;
};
+
+struct target_shmid64_ds {
+ struct target_ipc64_perm shm_perm; /* operation perms */
+ target_ulong shm_segsz; /* size of segment (bytes) */
+ target_ulong shm_atime; /* last attach time */
+ target_ulong __unused1;
+ target_ulong shm_dtime; /* last detach time */
+ target_ulong __unused2;
+ target_ulong shm_ctime; /* last change time */
+ target_ulong __unused3;
+ int32_t shm_cpid; /* pid of creator */
+ int32_t shm_lpid; /* pid of last operator */
+ target_ulong shm_nattch; /* no. of current attaches */
+ target_ulong __unused4;
+ target_ulong __unused5;
+};
+
+/* Data structure describing a set of semaphores. */
+struct target_shmid_ds
+ {
+ struct target_ipc_perm shm_perm; /* operation permission struct */
+ unsigned int __unused1;
+ target_ulong shm_atime; /* time of last shmat() */
+ unsigned int __unused2;
+ target_ulong shm_dtime; /* time of last shmdt() */
+ unsigned int __unused3;
+ target_ulong shm_ctime; /* time of last change by shmctl() */
+ unsigned int __unused4;
+ target_ulong shm_segsz; /* size of segment in bytes */
+ unsigned int shm_cpid; /* pid of creator */
+ unsigned int shm_lpid; /* pid of last shmop */
+ target_ulong shm_nattch; /* number of current attaches */
+ unsigned long __unused5;
+ unsigned long __unused6;
+ };
+
static inline void target_to_host_msqid_ds(struct msqid_ds *host_md,
target_ulong target_addr)
{
@@ -1665,11 +1828,59 @@ static long do_ipc(long call, long first
case IPCOP_shmctl:
switch(second) {
case IPC_RMID:
+ case IPC_RMID + IPC_64:
case SHM_LOCK:
+ case SHM_LOCK + IPC_64:
case SHM_UNLOCK:
+ case SHM_UNLOCK + IPC_64:
ret = get_errno(shmctl(first, second, NULL));
break;
+ case IPC_STAT + IPC_64:
+ {
+ struct shmid64_ds buf;
+ struct target_shmid64_ds *target_buf;
+#ifdef DEBUG
+ gemu_log("qemu: doing IPC_STAT\n");
+#endif
+ lock_user_struct(target_buf, ptr, 1);
+ ret = get_errno(shmctl(first, second, (struct shmid_ds*)&buf));
+
+ host_to_target_ipc64_perm(ptr, &buf.shm_perm);
+ target_buf->shm_atime = tswapl(buf.shm_atime);
+ target_buf->shm_dtime = tswapl(buf.shm_dtime);
+ target_buf->shm_ctime = tswapl(buf.shm_ctime);
+ target_buf->shm_segsz = tswapl(buf.shm_segsz);
+ target_buf->shm_cpid = tswap32(buf.shm_cpid);
+ target_buf->shm_lpid = tswap32(buf.shm_lpid);
+ target_buf->shm_nattch = tswapl(buf.shm_nattch);
+ unlock_user_struct(target_buf, ptr, 0);
+ break;
+ }
+ case IPC_SET + IPC_64:
+ {
+ struct shmid64_ds buf;
+ struct target_shmid64_ds *target_buf;
+#ifdef DEBUG
+ gemu_log("qemu: doing IPC_SET\n");
+#endif
+ lock_user_struct(target_buf, ptr, 1);
+
+ target_to_host_ipc64_perm(&buf.shm_perm, ptr);
+ buf.shm_atime = tswapl(target_buf->shm_atime);
+ buf.shm_dtime = tswapl(target_buf->shm_dtime);
+ buf.shm_ctime = tswapl(target_buf->shm_ctime);
+ buf.shm_segsz = tswapl(target_buf->shm_segsz);
+ buf.shm_cpid = tswap32(target_buf->shm_cpid);
+ buf.shm_lpid = tswap32(target_buf->shm_lpid);
+ buf.shm_nattch = tswapl(target_buf->shm_nattch);
+
+ ret = get_errno(shmctl(first, second, (struct shmid_ds*)&buf));
+
+ unlock_user_struct(target_buf, ptr, 0);
+ break;
+ }
default:
+ gemu_log("Unsopported shmctl(%ld,%#lx)\n", second, second);
goto unimplemented;
}
break;

26
qemu-cvs-ipc_semop.patch Normal file
View File

@ -0,0 +1,26 @@
Index: qemu/linux-user/syscall.c
===================================================================
--- qemu.orig/linux-user/syscall.c
+++ qemu/linux-user/syscall.c
@@ -1573,9 +1732,19 @@ static long do_ipc(long call, long first
switch (call) {
case IPCOP_semop:
- ret = get_errno(semop(first,(struct sembuf *) ptr, second));
+ {
+ struct sembuf *target_sops;
+ int i;
+ lock_user_struct(target_sops, ptr, 0);
+ for(i=0; i<second; i++) {
+ target_sops[i].sem_num = tswap16(target_sops[i].sem_num);
+ target_sops[i].sem_op = tswap16(target_sops[i].sem_op);
+ target_sops[i].sem_flg = tswap16(target_sops[i].sem_flg);
+ }
+ ret = get_errno(semop(first, target_sops, second));
+ unlock_user_struct(target_sops, ptr, 0);
break;
-
+ }
case IPCOP_semget:
ret = get_errno(semget(first, second, third));
break;

View File

@ -1,6 +1,7 @@
diff -uNr qemu-0.8.2.orig/linux-user/mmap.c qemu-0.8.2/linux-user/mmap.c
--- qemu-0.8.2.orig/linux-user/mmap.c 2007-01-16 16:05:33 +0200
+++ qemu-0.8.2/linux-user/mmap.c 2007-01-16 16:27:28 +0200
Index: qemu/linux-user/mmap.c
===================================================================
--- qemu.orig/linux-user/mmap.c
+++ qemu/linux-user/mmap.c
@@ -27,6 +27,10 @@
#include "qemu.h"
@ -12,7 +13,7 @@ diff -uNr qemu-0.8.2.orig/linux-user/mmap.c qemu-0.8.2/linux-user/mmap.c
//#define DEBUG_MMAP
/* NOTE: all the constants are the HOST ones, but addresses are target. */
@@ -116,7 +120,7 @@
@@ -118,7 +122,7 @@ static int mmap_frag(target_ulong real_s
if (prot1 == 0) {
/* no page was there, so we allocate one */
ret = (long)mmap(host_start, qemu_host_page_size, prot,
@ -21,7 +22,7 @@ diff -uNr qemu-0.8.2.orig/linux-user/mmap.c qemu-0.8.2/linux-user/mmap.c
if (ret == -1)
return ret;
prot1 = prot;
@@ -217,7 +221,8 @@
@@ -219,7 +223,8 @@ long target_mmap(target_ulong start, tar
abort();
host_len = HOST_PAGE_ALIGN(len) + qemu_host_page_size - TARGET_PAGE_SIZE;
real_start = (long)mmap(g2h(real_start), host_len, PROT_NONE,
@ -31,7 +32,7 @@ diff -uNr qemu-0.8.2.orig/linux-user/mmap.c qemu-0.8.2/linux-user/mmap.c
if (real_start == -1)
return real_start;
real_end = real_start + host_len;
@@ -234,7 +239,7 @@
@@ -236,7 +241,7 @@ abort();
host_offset = offset & qemu_host_page_mask;
host_len = len + offset - host_offset;
host_start = (long)mmap(real_start ? g2h(real_start) : NULL,
@ -40,7 +41,7 @@ diff -uNr qemu-0.8.2.orig/linux-user/mmap.c qemu-0.8.2/linux-user/mmap.c
if (host_start == -1)
return host_start;
/* update start so that it points to the file position at 'offset' */
@@ -312,7 +317,7 @@
@@ -314,7 +319,7 @@ abort();
else
offset1 = offset + real_start - start;
ret = (long)mmap(g2h(real_start), real_end - real_start,
@ -49,7 +50,7 @@ diff -uNr qemu-0.8.2.orig/linux-user/mmap.c qemu-0.8.2/linux-user/mmap.c
if (ret == -1)
return ret;
}
@@ -388,7 +393,7 @@
@@ -390,7 +395,7 @@ long target_mremap(target_ulong old_addr
int prot;
/* XXX: use 5 args syscall */

17
qemu-cvs-mplayer.patch Normal file
View File

@ -0,0 +1,17 @@
Index: qemu/linux-user/mmap.c
===================================================================
--- qemu.orig/linux-user/mmap.c
+++ qemu/linux-user/mmap.c
@@ -48,8 +48,10 @@ int target_mprotect(target_ulong start,
end = start + len;
if (end < start)
return -EINVAL;
- if (prot & ~(PROT_READ | PROT_WRITE | PROT_EXEC))
- return -EINVAL;
+ if (prot & ~(PROT_READ | PROT_WRITE | PROT_EXEC)) {
+ gemu_log("WARNING: dirty hack in mprotect: setting prot (%#x -> %#x)\n", prot, prot & (PROT_READ | PROT_WRITE | PROT_EXEC));
+ prot &= (PROT_READ | PROT_WRITE | PROT_EXEC);
+ }
if (len == 0)
return 0;

12
qemu-cvs-netlink.patch Normal file
View File

@ -0,0 +1,12 @@
Index: qemu/linux-user/syscall.c
===================================================================
--- qemu.orig/linux-user/syscall.c
+++ qemu/linux-user/syscall.c
@@ -898,6 +906,7 @@ static long do_socket(int domain, int ty
break;
}
#endif
+ if(domain == PF_NETLINK) return -EAFNOSUPPORT; /* do not make NETLINK socket connections possible */
return get_errno(socket(domain, type, protocol));
}

View File

@ -1,6 +1,8 @@
--- qemu/linux-user/path.c
+++ qemu/linux-user/path.c
@@ -1,147 +1,81 @@
Index: qemu.bkp/linux-user/path.c
===================================================================
--- qemu.bkp.orig/linux-user/path.c
+++ qemu.bkp/linux-user/path.c
@@ -1,159 +1,81 @@
/* Code to mangle pathnames into those matching a given prefix.
eg. open("/lib/foo.so") => open("/usr/gnemul/i386-linux/lib/foo.so");
-
@ -98,28 +100,7 @@
- for (i = 0; i < child->num_entries; i++)
- set_parents(child->entries[i], child);
-}
+static struct path_list_head* list_head;
void init_paths(const char *prefix)
{
if (prefix[0] != '/' ||
- prefix[0] == '\0' ||
- !strcmp(prefix, "/"))
+ prefix[0] == '\0' ||
+ !strcmp(prefix, "/"))
return;
- base = new_entry("", NULL, prefix+1);
- base = add_dir_maybe(base);
- if (base->num_entries == 0) {
- free (base);
- base = NULL;
- } else {
- set_parents(base, base);
- }
-}
+ list_head = malloc(sizeof(struct path_list_head));
-
-/* FIXME: Doesn't handle DIR/.. where DIR is not in emulated dir. */
-static const char *
-follow_path(const struct pathelem *cursor, const char *name)
@ -144,6 +125,41 @@
-
- /* Not found */
- return NULL;
-}
+static struct path_list_head* list_head;
void init_paths(const char *prefix)
{
- char pref_buf[PATH_MAX];
-
- if (prefix[0] == '\0' ||
- !strcmp(prefix, "/"))
+ if (prefix[0] != '/' ||
+ prefix[0] == '\0' ||
+ !strcmp(prefix, "/"))
return;
- if (prefix[0] != '/') {
- char *cwd = get_current_dir_name();
- if (!cwd)
- abort();
- strcpy(pref_buf, cwd);
- strcat(pref_buf, "/");
- strcat(pref_buf, prefix);
- free(cwd);
- } else
- strcpy(pref_buf,prefix + 1);
-
- base = new_entry("", NULL, pref_buf);
- base = add_dir_maybe(base);
- if (base->num_entries == 0) {
- free (base);
- base = NULL;
- } else {
- set_parents(base, base);
- }
+ list_head = malloc(sizeof(struct path_list_head));
+
+ /* first element of list is prefix */
+ list_head->path = strdup(prefix);
+ list_head->next = NULL;
@ -162,14 +178,13 @@
Could do relative by tracking cwd. */
- if (!base || name[0] != '/')
- return name;
-
- return follow_path(base, name) ?: name;
+ if (!list_head || result[0] != '/')
+ goto exit;
+
+ strncpy(newname, list_head->path, path_length);
+ strncat(newname, name, path_length);
+
- return follow_path(base, name) ?: name;
+ /* look for place where path should be present */
+ while ( list->next && (strcmp(list->next->path, newname) < 0) )
+ list = list->next;

View File

@ -0,0 +1,16 @@
Index: qemu/linux-user/syscall.c
===================================================================
--- qemu.orig/linux-user/syscall.c
+++ qemu/linux-user/syscall.c
@@ -5059,6 +5059,11 @@ long do_syscall(void *cpu_env, int num,
goto unimplemented_nowarn;
#endif
+#ifdef TARGET_NR_fadvise64
+ case TARGET_NR_fadvise64:
+ goto unimplemented_nowarn;
+#endif
+
#ifdef TARGET_NR_sched_getaffinity
case TARGET_NR_sched_getaffinity:
{

13
qemu-cvs-noppcemb.patch Normal file
View File

@ -0,0 +1,13 @@
Index: qemu-0.9.0/configure
===================================================================
--- qemu-0.9.0.orig/configure
+++ qemu-0.9.0/configure
@@ -473,7 +473,7 @@ fi
if test -z "$target_list" ; then
# these targets are portable
if [ "$softmmu" = "yes" ] ; then
- target_list="i386-softmmu ppc-softmmu sparc-softmmu x86_64-softmmu mips-softmmu mipsel-softmmu mips64-softmmu mips64el-softmmu arm-softmmu ppc64-softmmu ppcemb-softmmu m68k-softmmu z80-softmmu"
+ target_list="i386-softmmu ppc-softmmu sparc-softmmu x86_64-softmmu mips-softmmu mipsel-softmmu mips64-softmmu mips64el-softmmu arm-softmmu ppc64-softmmu m68k-softmmu z80-softmmu"
fi
# the following are Linux specific
if [ "$linux_user" = "yes" ] ; then

13
qemu-cvs-pthread.patch Normal file
View File

@ -0,0 +1,13 @@
Index: qemu-0.9.0/Makefile
===================================================================
--- qemu-0.9.0.orig/Makefile
+++ qemu-0.9.0/Makefile
@@ -12,7 +12,7 @@ BASE_CFLAGS += $(OS_CFLAGS) $(ARCH_CFLAG
BASE_LDFLAGS += $(OS_LDFLAGS) $(ARCH_LDFLAGS)
CPPFLAGS += -I. -D_GNU_SOURCE -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE
-LIBS=
+LIBS=-lpthread
TOOLS=qemu-img$(EXESUF)
ifdef CONFIG_STATIC
BASE_LDFLAGS += -static

View File

@ -0,0 +1,38 @@
Index: qemu.bkp/linux-user/syscall.c
===================================================================
--- qemu.bkp.orig/linux-user/syscall.c
+++ qemu.bkp/linux-user/syscall.c
@@ -149,6 +149,7 @@ type name (type1 arg1,type2 arg2,type3 a
#define __NR_sys_syslog __NR_syslog
#define __NR_sys_tgkill __NR_tgkill
#define __NR_sys_clone __NR_clone
+#define __NR_sys_sched_getaffinity __NR_sched_getaffinity
#if defined(__alpha__) || defined (__ia64__) || defined(__x86_64__)
#define __NR__llseek __NR_lseek
@@ -171,6 +172,7 @@ _syscall3(int,sys_rt_sigqueueinfo,int,pi
_syscall3(int,sys_syslog,int,type,char*,bufp,int,len)
_syscall3(int,sys_tgkill,int,tgid,int,pid,int,sig)
_syscall5(int,sys_clone, int, flags, void *, child_stack, int *, parent_tidptr, void *, newtls, int *, child_tidptr)
+_syscall3(int,sys_sched_getaffinity,pid_t,pid,unsigned int,cpusetsize,void*,mask)
#ifdef __NR_exit_group
_syscall1(int,exit_group,int,error_code)
#endif
@@ -4823,6 +4825,17 @@ long do_syscall(void *cpu_env, int num,
goto unimplemented_nowarn;
#endif
+#ifdef TARGET_NR_sched_getaffinity
+ case TARGET_NR_sched_getaffinity:
+ {
+ cpu_set_t *mask;
+ lock_user_struct(mask, arg3, 1);
+ ret = get_errno(sys_sched_getaffinity((pid_t)arg1, (unsigned int)arg2, mask));
+ unlock_user_struct(mask, arg3, 0);
+ break;
+ }
+#endif
+
default:
unimplemented:
gemu_log("qemu: Unsupported syscall: %d\n", num);

260
qemu-cvs-tls.patch Normal file
View File

@ -0,0 +1,260 @@
Index: qemu.bkp/linux-user/main.c
===================================================================
--- qemu.bkp.orig/linux-user/main.c
+++ qemu.bkp/linux-user/main.c
@@ -156,7 +156,7 @@ static void set_gate(void *ptr, unsigned
p[1] = tswapl(e2);
}
-uint64_t gdt_table[6];
+uint64_t gdt_table[9];
uint64_t idt_table[256];
/* only dpl matters as we do only user space emulation */
Index: qemu.bkp/linux-user/syscall.c
===================================================================
--- qemu.bkp.orig/linux-user/syscall.c
+++ qemu.bkp/linux-user/syscall.c
@@ -145,6 +145,7 @@ type name (type1 arg1,type2 arg2,type3 a
#define __NR_sys_rt_sigqueueinfo __NR_rt_sigqueueinfo
#define __NR_sys_syslog __NR_syslog
#define __NR_sys_tgkill __NR_tgkill
+#define __NR_sys_clone __NR_clone
#if defined(__alpha__) || defined (__ia64__) || defined(__x86_64__)
#define __NR__llseek __NR_lseek
@@ -166,6 +167,7 @@ _syscall5(int, _llseek, uint, fd, ulon
_syscall3(int,sys_rt_sigqueueinfo,int,pid,int,sig,siginfo_t *,uinfo)
_syscall3(int,sys_syslog,int,type,char*,bufp,int,len)
_syscall3(int,sys_tgkill,int,tgid,int,pid,int,sig)
+_syscall5(int,sys_clone, int, flags, void *, child_stack, int *, parent_tidptr, void *, newtls, int *, child_tidptr)
#ifdef __NR_exit_group
_syscall1(int,exit_group,int,error_code)
#endif
@@ -2115,29 +2117,107 @@ int do_modify_ldt(CPUX86State *env, int
return ret;
}
+int do_set_thread_area(CPUX86State *env, target_ulong ptr)
+{
+ uint64_t *gdt_table = g2h(env->gdt.base);
+ struct target_modify_ldt_ldt_s ldt_info;
+ struct target_modify_ldt_ldt_s *target_ldt_info;
+ int seg_32bit, contents, read_exec_only, limit_in_pages;
+ int seg_not_present, useable;
+ uint32_t *lp, entry_1, entry_2;
+ int i;
+
+ lock_user_struct(target_ldt_info, ptr, 1);
+ ldt_info.entry_number = tswap32(target_ldt_info->entry_number);
+ ldt_info.base_addr = tswapl(target_ldt_info->base_addr);
+ ldt_info.limit = tswap32(target_ldt_info->limit);
+ ldt_info.flags = tswap32(target_ldt_info->flags);
+ if (ldt_info.entry_number == -1) {
+ for (i=6; i<8; i++)
+ if (gdt_table[i] == 0) {
+ ldt_info.entry_number = i;
+ target_ldt_info->entry_number = tswap32(i);
+ break;
+ }
+ }
+ unlock_user_struct(target_ldt_info, ptr, 0);
+
+ if (ldt_info.entry_number < 6 || ldt_info.entry_number > 8)
+ return -EINVAL;
+ seg_32bit = ldt_info.flags & 1;
+ contents = (ldt_info.flags >> 1) & 3;
+ read_exec_only = (ldt_info.flags >> 3) & 1;
+ limit_in_pages = (ldt_info.flags >> 4) & 1;
+ seg_not_present = (ldt_info.flags >> 5) & 1;
+ useable = (ldt_info.flags >> 6) & 1;
+
+ if (contents == 3) {
+ if (seg_not_present == 0)
+ return -EINVAL;
+ }
+
+ /* NOTE: same code as Linux kernel */
+ /* Allow LDTs to be cleared by the user. */
+ if (ldt_info.base_addr == 0 && ldt_info.limit == 0) {
+ if ((contents == 0 &&
+ read_exec_only == 1 &&
+ seg_32bit == 0 &&
+ limit_in_pages == 0 &&
+ seg_not_present == 1 &&
+ useable == 0 )) {
+ entry_1 = 0;
+ entry_2 = 0;
+ goto install;
+ }
+ }
+
+ entry_1 = ((ldt_info.base_addr & 0x0000ffff) << 16) |
+ (ldt_info.limit & 0x0ffff);
+ entry_2 = (ldt_info.base_addr & 0xff000000) |
+ ((ldt_info.base_addr & 0x00ff0000) >> 16) |
+ (ldt_info.limit & 0xf0000) |
+ ((read_exec_only ^ 1) << 9) |
+ (contents << 10) |
+ ((seg_not_present ^ 1) << 15) |
+ (seg_32bit << 22) |
+ (limit_in_pages << 23) |
+ (useable << 20) |
+ 0x7000;
+
+ /* Install the new entry ... */
+install:
+ lp = (uint32_t *)(gdt_table + ldt_info.entry_number);
+ lp[0] = tswap32(entry_1);
+ lp[1] = tswap32(entry_2);
+ return 0;
+}
#endif /* defined(TARGET_I386) */
/* this stack is the equivalent of the kernel stack associated with a
thread/process */
#define NEW_STACK_SIZE 8192
-static int clone_func(void *arg)
+static int clone_func(void *cloneenv)
{
- CPUState *env = arg;
- cpu_loop(env);
+ cpu_loop((CPUState *)cloneenv);
/* never exits */
return 0;
}
-int do_fork(CPUState *env, unsigned int flags, unsigned long newsp)
+int do_fork(CPUState *env, unsigned int flags, target_ulong newsp, target_ulong parent_tidptr, target_ulong newtls, target_ulong child_tidptr)
{
int ret;
+ unsigned long parent_tid=gettid();
TaskState *ts;
uint8_t *new_stack;
CPUState *new_env;
-
+#if defined(TARGET_I386)
+ uint64_t *new_gdt_table;
+#endif
if (flags & CLONE_VM) {
ts = malloc(sizeof(TaskState) + NEW_STACK_SIZE);
+ if (!ts)
+ return -ENOMEM;
memset(ts, 0, sizeof(TaskState));
new_stack = ts->stack;
ts->used = 1;
@@ -2149,6 +2229,27 @@ int do_fork(CPUState *env, unsigned int
#if defined(TARGET_I386)
if (!newsp)
newsp = env->regs[R_ESP];
+ new_gdt_table = malloc(9 * 8);
+ if (!new_gdt_table) {
+ free(new_env);
+ return -ENOMEM;
+ }
+ /* Copy main GDT table from parent, but clear TLS entries */
+ memcpy(new_gdt_table, g2h(env->gdt.base), 6 * 8);
+ memset(&new_gdt_table[6], 0, 3 * 8);
+ new_env->gdt.base = h2g(new_gdt_table);
+ if (flags & CLONE_SETTLS) {
+ ret = do_set_thread_area(new_env, newtls);
+ if (ret) {
+ free(new_gdt_table);
+ free(new_env);
+ return ret;
+ }
+ }
+
+ cpu_x86_load_seg(new_env, R_FS, new_env->segs[R_FS].selector);
+ cpu_x86_load_seg(new_env, R_GS, new_env->segs[R_GS].selector);
+
new_env->regs[R_ESP] = newsp;
new_env->regs[R_EAX] = 0;
#elif defined(TARGET_ARM)
@@ -2202,15 +2303,27 @@ int do_fork(CPUState *env, unsigned int
#endif
new_env->opaque = ts;
#ifdef __ia64__
- ret = __clone2(clone_func, new_stack + NEW_STACK_SIZE, flags, new_env);
+ ret = __clone2(clone_func, new_stack + NEW_STACK_SIZE, flags & ~(CLONE_SETTLS|CLONE_PARENT_SETTID|CLONE_CHILD_CLEARTID), new_env);
#else
- ret = clone(clone_func, new_stack + NEW_STACK_SIZE, flags, new_env);
+ ret = clone(clone_func, new_stack + NEW_STACK_SIZE, flags & ~(CLONE_SETTLS|CLONE_PARENT_SETTID|CLONE_CHILD_CLEARTID), new_env);
#endif
} else {
/* if no CLONE_VM, we consider it is a fork */
- if ((flags & ~CSIGNAL) != 0)
- return -EINVAL;
- ret = fork();
+ ret = sys_clone(flags & ~(CLONE_SETTLS|CLONE_PARENT_SETTID|CLONE_CHILD_CLEARTID), 0, g2h(parent_tidptr), NULL, g2h(child_tidptr));
+ }
+ /* Store child thread ID at location parent_tidptr in parent and child memory.
+ Currently this is only done in client memory */
+ if(flags & CLONE_PARENT_SETTID) {
+ tput32(parent_tidptr, parent_tid);
+ }
+
+ /* Store child thread ID at location child_tidptr in child memory. */
+ if(flags & CLONE_CHILD_SETTID) {
+ if(ret==0) { /* only in client memory for fork() */
+ tput32(child_tidptr, gettid());
+ } else if(flags & CLONE_VM) { /* real threads need it too */
+ tput32(child_tidptr, ret);
+ }
}
return ret;
}
@@ -2458,7 +2571,7 @@ long do_syscall(void *cpu_env, int num,
_mcleanup();
#endif
gdb_exit(cpu_env, arg1);
- /* XXX: should free thread stack and CPU env */
+ /* XXX: should free thread stack, GDT and CPU env */
_exit(arg1);
ret = 0; /* avoid warning */
break;
@@ -2487,7 +2600,7 @@ long do_syscall(void *cpu_env, int num,
ret = do_brk(arg1);
break;
case TARGET_NR_fork:
- ret = get_errno(do_fork(cpu_env, SIGCHLD, 0));
+ ret = get_errno(do_fork(cpu_env, SIGCHLD, 0, 0,0,0));
break;
#ifdef TARGET_NR_waitpid
case TARGET_NR_waitpid:
@@ -3651,7 +3764,7 @@ long do_syscall(void *cpu_env, int num,
ret = get_errno(fsync(arg1));
break;
case TARGET_NR_clone:
- ret = get_errno(do_fork(cpu_env, arg1, arg2));
+ ret = get_errno(do_fork(cpu_env, arg1, arg2,arg3,arg4,arg5));
break;
#ifdef __NR_exit_group
/* new thread calls */
@@ -4039,7 +4152,7 @@ long do_syscall(void *cpu_env, int num,
#endif
#ifdef TARGET_NR_vfork
case TARGET_NR_vfork:
- ret = get_errno(do_fork(cpu_env, CLONE_VFORK | CLONE_VM | SIGCHLD, 0));
+ ret = get_errno(do_fork(cpu_env, CLONE_VFORK | CLONE_VM | SIGCHLD, 0, 0,0,0));
break;
#endif
#ifdef TARGET_NR_ugetrlimit
@@ -4561,12 +4674,12 @@ long do_syscall(void *cpu_env, int num,
#ifdef TARGET_NR_set_thread_area
case TARGET_NR_set_thread_area:
#ifdef TARGET_MIPS
- ((CPUMIPSState *) cpu_env)->tls_value = arg1;
- ret = 0;
- break;
+ ((CPUMIPSState *) cpu_env)->tls_value = arg1;
+ ret = 0;
#else
- goto unimplemented_nowarn;
+ ret = get_errno(do_set_thread_area(cpu_env, arg1));
#endif
+ break;
#endif
#ifdef TARGET_NR_get_thread_area
case TARGET_NR_get_thread_area:

2766
qemu-m68k.diff Normal file

File diff suppressed because it is too large Load Diff

View File

@ -1,19 +1,63 @@
diff -urN qemu-0.9.0/configure qemu-z80/configure
--- qemu-0.9.0/configure 2007-02-05 23:01:54.000000000 +0000
+++ qemu-z80/configure 2007-03-27 21:07:11.000000000 +0100
@@ -415,7 +415,7 @@
diff --exclude='*.orig' --exclude=CVS -ruN qemu/configure qemu-z80/configure
--- qemu/configure 2007-06-23 18:03:35.000000000 +0200
+++ qemu-z80/configure 2007-07-06 13:07:47.000000000 +0200
@@ -86,6 +86,7 @@
dsound="no"
coreaudio="no"
alsa="no"
+libspectrum="no"
fmod="no"
fmod_lib=""
fmod_inc=""
@@ -245,6 +246,8 @@
;;
--fmod-inc=*) fmod_inc="$optarg"
;;
+ --enable-libspectrum) libspectrum="yes"
+ ;;
--enable-mingw32) mingw32="yes" ; cross_prefix="i386-mingw32-" ; linux_user="no"
;;
--disable-slirp) slirp="no"
@@ -355,6 +358,7 @@
echo " --enable-alsa enable ALSA audio driver"
echo " --enable-fmod enable FMOD audio driver"
echo " --enable-dsound enable DirectSound audio driver"
+echo " --enable-libspectrum enable ZX Spectrum snapshot loading"
echo " --enable-system enable all system emulation targets"
echo " --disable-system disable all system emulation targets"
echo " --enable-linux-user enable all linux usermode emulation targets"
@@ -473,7 +477,7 @@
if test -z "$target_list" ; then
# these targets are portable
if [ "$softmmu" = "yes" ] ; then
- target_list="i386-softmmu ppc-softmmu sparc-softmmu x86_64-softmmu mips-softmmu mipsel-softmmu arm-softmmu"
+ target_list="i386-softmmu ppc-softmmu sparc-softmmu x86_64-softmmu mips-softmmu mipsel-softmmu arm-softmmu z80-softmmu"
- target_list="i386-softmmu ppc-softmmu sparc-softmmu x86_64-softmmu mips-softmmu mipsel-softmmu mips64-softmmu mips64el-softmmu arm-softmmu ppc64-softmmu ppcemb-softmmu m68k-softmmu"
+ target_list="i386-softmmu ppc-softmmu sparc-softmmu x86_64-softmmu mips-softmmu mipsel-softmmu mips64-softmmu mips64el-softmmu arm-softmmu ppc64-softmmu ppcemb-softmmu m68k-softmmu z80-softmmu"
fi
# the following are Linux specific
if [ "$linux_user" = "yes" ] ; then
@@ -911,6 +911,11 @@
echo "#define TARGET_ARCH \"m68k\"" >> $config_h
echo "#define TARGET_M68K 1" >> $config_h
bflt="yes"
@@ -680,6 +684,7 @@
if test -n "$sparc_cpu"; then
echo "Target Sparc Arch $sparc_cpu"
fi
+echo "libspec. support $libspectrum"
echo "kqemu support $kqemu"
echo "Documentation $build_docs"
[ ! -z "$uname_release" ] && \
@@ -841,6 +846,10 @@
echo "CONFIG_FMOD_INC=$fmod_inc" >> $config_mak
echo "#define CONFIG_FMOD 1" >> $config_h
fi
+if test "$libspectrum" = "yes" ; then
+ echo "CONFIG_LIBSPECTRUM=yes" >> $config_mak
+ echo "#define CONFIG_LIBSPECTRUM 1" >> $config_h
+fi
qemu_version=`head $source_path/VERSION`
echo "VERSION=$qemu_version" >>$config_mak
echo "#define QEMU_VERSION \"$qemu_version\"" >> $config_h
@@ -1008,6 +1017,11 @@
echo "TARGET_ARCH=alpha" >> $config_mak
echo "#define TARGET_ARCH \"alpha\"" >> $config_h
echo "#define TARGET_ALPHA 1" >> $config_h
+elif test "$target_cpu" = "z80" ; then
+ echo "TARGET_ARCH=z80" >> $config_mak
+ echo "#define TARGET_ARCH \"z80\"" >> $config_h
@ -22,29 +66,12 @@ diff -urN qemu-0.9.0/configure qemu-z80/configure
else
echo "Unsupported target CPU"
exit 1
diff -urN qemu-0.9.0/cpu-all.h qemu-z80/cpu-all.h
--- qemu-0.9.0/cpu-all.h 2007-02-05 23:01:54.000000000 +0000
+++ qemu-z80/cpu-all.h 2007-03-27 21:07:11.000000000 +0100
@@ -746,6 +746,13 @@
#define cpu_gen_code cpu_sh4_gen_code
#define cpu_signal_handler cpu_sh4_signal_handler
+#elif defined(TARGET_Z80)
+#define CPUState CPUZ80State
+#define cpu_init cpu_z80_init
+#define cpu_exec cpu_z80_exec
+#define cpu_gen_code cpu_z80_gen_code
+#define cpu_signal_handler cpu_z80_signal_handler
+
#else
#error unsupported target CPU
diff -urN qemu-0.9.0/cpu-exec.c qemu-z80/cpu-exec.c
--- qemu-0.9.0/cpu-exec.c 2007-02-05 23:01:54.000000000 +0000
+++ qemu-z80/cpu-exec.c 2007-04-17 21:14:13.000000000 +0100
@@ -202,6 +202,10 @@
flags = env->sr & (SR_MD | SR_RB);
cs_base = 0; /* XXXXX */
diff --exclude='*.orig' --exclude=CVS -ruN qemu/cpu-exec.c qemu-z80/cpu-exec.c
--- qemu/cpu-exec.c 2007-06-03 20:52:15.000000000 +0200
+++ qemu-z80/cpu-exec.c 2007-07-05 18:36:50.000000000 +0200
@@ -209,6 +209,10 @@
flags = env->ps;
cs_base = 0;
pc = env->pc;
+#elif defined(TARGET_Z80)
+ flags = env->hflags;
@ -53,7 +80,7 @@ diff -urN qemu-0.9.0/cpu-exec.c qemu-z80/cpu-exec.c
#else
#error unsupported CPU
#endif
@@ -325,6 +329,12 @@
@@ -284,6 +288,15 @@
#elif defined(TARGET_MIPS)
#elif defined(TARGET_SH4)
/* XXXXX */
@ -63,13 +90,16 @@ diff -urN qemu-0.9.0/cpu-exec.c qemu-z80/cpu-exec.c
+ CC_SRC = env->eflags & (CC_S | CC_Z | CC_P | CC_C);
+ CC_OP = CC_OP_EFLAGS;
+ env->eflags &= ~(CC_S | CC_Z | CC_P | CC_C);
+#elif defined(TARGET_Z80)
+ /* restore flags in standard format */
+// env->eflags = env->eflags | cc_table[CC_OP].compute_all();
#else
#error unsupported target CPU
#endif
@@ -525,6 +535,13 @@
@@ -500,6 +513,13 @@
env->exception_index = env->pending_vector;
do_interrupt(1);
}
#elif defined(TARGET_SH4)
/* XXXXX */
+#elif defined(TARGET_Z80)
+ if (interrupt_request & CPU_INTERRUPT_HARD) {
+ env->interrupt_request &= ~CPU_INTERRUPT_HARD;
@ -80,18 +110,18 @@ diff -urN qemu-0.9.0/cpu-exec.c qemu-z80/cpu-exec.c
#endif
/* Don't use the cached interupt_request value,
do_interrupt may have updated the EXITTB flag. */
@@ -593,6 +610,8 @@
@@ -547,6 +567,8 @@
cpu_dump_state(env, logfile, fprintf, 0);
#elif defined(TARGET_SH4)
#elif defined(TARGET_ALPHA)
cpu_dump_state(env, logfile, fprintf, 0);
+#elif defined(TARGET_Z80)
+ cpu_dump_state(env, logfile, fprintf, 0);
#else
#error unsupported target CPU
#endif
@@ -785,6 +804,9 @@
#elif defined(TARGET_MIPS)
@@ -741,6 +763,9 @@
#elif defined(TARGET_SH4)
#elif defined(TARGET_ALPHA)
/* XXXXX */
+#elif defined(TARGET_Z80)
+ /* restore flags in standard format */
@ -99,32 +129,32 @@ diff -urN qemu-0.9.0/cpu-exec.c qemu-z80/cpu-exec.c
#else
#error unsupported target CPU
#endif
diff -urN qemu-0.9.0/disas.c qemu-z80/disas.c
--- qemu-0.9.0/disas.c 2007-02-05 23:01:54.000000000 +0000
+++ qemu-z80/disas.c 2007-03-27 21:07:11.000000000 +0100
@@ -197,6 +197,8 @@
#elif defined(TARGET_SH4)
disasm_info.mach = bfd_mach_sh4;
print_insn = print_insn_sh;
diff --exclude='*.orig' --exclude=CVS -ruN qemu/disas.c qemu-z80/disas.c
--- qemu/disas.c 2007-06-03 21:16:42.000000000 +0200
+++ qemu-z80/disas.c 2007-07-05 18:03:59.000000000 +0200
@@ -200,6 +200,8 @@
#elif defined(TARGET_ALPHA)
disasm_info.mach = bfd_mach_alpha;
print_insn = print_insn_alpha;
+#elif defined(TARGET_Z80)
+ print_insn = print_insn_z80;
#else
fprintf(out, "0x" TARGET_FMT_lx
": Asm output not supported on this arch\n", code);
diff -urN qemu-0.9.0/dis-asm.h qemu-z80/dis-asm.h
--- qemu-0.9.0/dis-asm.h 2007-02-05 23:01:54.000000000 +0000
+++ qemu-z80/dis-asm.h 2007-03-27 21:07:11.000000000 +0100
@@ -377,6 +377,7 @@
extern int print_insn_v850 PARAMS ((bfd_vma, disassemble_info*));
diff --exclude='*.orig' --exclude=CVS -ruN qemu/dis-asm.h qemu-z80/dis-asm.h
--- qemu/dis-asm.h 2007-04-05 09:22:49.000000000 +0200
+++ qemu-z80/dis-asm.h 2007-07-05 18:05:17.000000000 +0200
@@ -379,6 +379,7 @@
extern int print_insn_tic30 PARAMS ((bfd_vma, disassemble_info*));
extern int print_insn_ppc PARAMS ((bfd_vma, disassemble_info*));
extern int print_insn_alpha PARAMS ((bfd_vma, disassemble_info*));
+extern int print_insn_z80 PARAMS ((bfd_vma, disassemble_info*));
#if 0
/* Fetch the disassembler for a given BFD, if that support is available. */
diff -urN qemu-0.9.0/exec-all.h qemu-z80/exec-all.h
--- qemu-0.9.0/exec-all.h 2007-02-05 23:01:54.000000000 +0000
+++ qemu-z80/exec-all.h 2007-04-17 21:26:41.000000000 +0100
diff --exclude='*.orig' --exclude=CVS -ruN qemu/exec-all.h qemu-z80/exec-all.h
--- qemu/exec-all.h 2007-07-02 16:06:26.000000000 +0200
+++ qemu-z80/exec-all.h 2007-07-05 18:04:44.000000000 +0200
@@ -69,7 +69,7 @@
typedef void (GenOpFunc2)(long, long);
typedef void (GenOpFunc3)(long, long, long);
@ -134,19 +164,19 @@ diff -urN qemu-0.9.0/exec-all.h qemu-z80/exec-all.h
void optimize_flags_init(void);
@@ -572,6 +572,8 @@
is_user = ((env->uncached_cpsr & CPSR_M) == ARM_CPU_MODE_USR);
#elif defined (TARGET_SH4)
is_user = ((env->sr & SR_MD) == 0);
@@ -586,6 +586,8 @@
is_user = ((env->ps >> 3) & 3);
#elif defined (TARGET_M68K)
is_user = ((env->sr & SR_S) == 0);
+#elif defined (TARGET_Z80)
+ is_user = 0; /* no user-mode */
#else
#error unimplemented CPU
#endif
diff -urN qemu-0.9.0/exec.c qemu-z80/exec.c
--- qemu-0.9.0/exec.c 2007-02-05 23:01:54.000000000 +0000
+++ qemu-z80/exec.c 2007-04-15 22:54:52.000000000 +0100
@@ -679,6 +679,9 @@
diff --exclude='*.orig' --exclude=CVS -ruN qemu/exec.c qemu-z80/exec.c
--- qemu/exec.c 2007-07-01 20:21:11.000000000 +0200
+++ qemu-z80/exec.c 2007-07-06 12:04:38.000000000 +0200
@@ -709,6 +709,9 @@
current_flags |= (env->eflags & (IOPL_MASK | TF_MASK | VM_MASK));
current_cs_base = (target_ulong)env->segs[R_CS].base;
current_pc = current_cs_base + env->eip;
@ -156,12 +186,12 @@ diff -urN qemu-0.9.0/exec.c qemu-z80/exec.c
#else
#error unsupported CPU
#endif
diff -urN qemu-0.9.0/gdbstub.c qemu-z80/gdbstub.c
--- qemu-0.9.0/gdbstub.c 2007-02-05 23:01:54.000000000 +0000
+++ qemu-z80/gdbstub.c 2007-04-04 21:35:14.000000000 +0100
@@ -700,6 +700,34 @@
LOAD (env->macl);
LOAD (env->sr);
diff --exclude='*.orig' --exclude=CVS -ruN qemu/gdbstub.c qemu-z80/gdbstub.c
--- qemu/gdbstub.c 2007-06-03 19:08:32.000000000 +0200
+++ qemu-z80/gdbstub.c 2007-07-05 18:03:12.000000000 +0200
@@ -718,6 +718,34 @@
for (i = 0; i < 8; i++) LOAD(env->gregs[i]);
for (i = 0; i < 8; i++) LOAD(env->gregs[i + 16]);
}
+#elif defined(TARGET_Z80)
+/* Z80 FIXME Z80 TODO Z80 */
@ -194,10 +224,10 @@ diff -urN qemu-0.9.0/gdbstub.c qemu-z80/gdbstub.c
#else
static int cpu_gdb_read_registers(CPUState *env, uint8_t *mem_buf)
{
diff -urN qemu-0.9.0/hw/zx_spectrum.c qemu-z80/hw/zx_spectrum.c
--- qemu-0.9.0/hw/zx_spectrum.c 1970-01-01 01:00:00.000000000 +0100
+++ qemu-z80/hw/zx_spectrum.c 2007-04-17 20:27:16.000000000 +0100
@@ -0,0 +1,236 @@
diff --exclude='*.orig' --exclude=CVS -ruN qemu/hw/zx_spectrum.c qemu-z80/hw/zx_spectrum.c
--- qemu/hw/zx_spectrum.c 1970-01-01 01:00:00.000000000 +0100
+++ qemu-z80/hw/zx_spectrum.c 2007-07-06 13:17:46.000000000 +0200
@@ -0,0 +1,303 @@
+/*
+ * QEMU ZX Spectrum Emulator
+ *
@ -223,6 +253,9 @@ diff -urN qemu-0.9.0/hw/zx_spectrum.c qemu-z80/hw/zx_spectrum.c
+ * THE SOFTWARE.
+ */
+#include "vl.h"
+#ifdef CONFIG_LIBSPECTRUM
+#include <libspectrum.h>
+#endif
+
+/* output Bochs bios info messages */
+//#define DEBUG_BIOS
@ -259,12 +292,14 @@ diff -urN qemu-0.9.0/hw/zx_spectrum.c qemu-z80/hw/zx_spectrum.c
+ return io_keyboard_read(opaque, addr);
+}
+
+#if 0
+/* MSDOS compatibility mode FPU exception support */
+/* XXX: add IGNNE support */
+void cpu_set_ferr(CPUZ80State *s)
+{
+ pic_set_irq(13, 1);
+}
+#endif
+
+/* TSC handling */
+uint64_t cpu_get_tsc(CPUZ80State *env)
@ -380,7 +415,7 @@ diff -urN qemu-0.9.0/hw/zx_spectrum.c qemu-z80/hw/zx_spectrum.c
+ register_savevm("cpu", 0, 4, cpu_save, cpu_load, env);
+ qemu_register_reset(main_cpu_reset, env);
+
+ cpu_register_physical_memory(0, 0x10000, 0);
+ cpu_register_physical_memory(0x4000, 0x10000 - 0x4000, 0 | IO_MEM_RAM);
+
+ /* allocate RAM */
+// ram_addr = qemu_ram_alloc(0x10000 - 0x5b00);
@ -412,8 +447,70 @@ diff -urN qemu-0.9.0/hw/zx_spectrum.c qemu-z80/hw/zx_spectrum.c
+ register_ioport_read(0, 0x10000, 1, io_spectrum_read, NULL);
+
+ zx_ula_init(ds, phys_ram_base + ram_size, ram_size);
+
+ zx_keyboard_init();
+ zx_timer_init(ds);
+
+#ifdef CONFIG_LIBSPECTRUM
+ if(kernel_filename) {
+ libspectrum_id_t type;
+ libspectrum_class_t cls;
+ libspectrum_snap* snap;
+ uint8_t* snapmem;
+ libspectrum_byte* page;
+ int length;
+ int i;
+ if(libspectrum_init() != LIBSPECTRUM_ERROR_NONE ||
+ libspectrum_identify_file(&type, kernel_filename, NULL, 0) != LIBSPECTRUM_ERROR_NONE ||
+ libspectrum_identify_class(&cls, type) != LIBSPECTRUM_ERROR_NONE ||
+ libspectrum_snap_alloc(&snap) != LIBSPECTRUM_ERROR_NONE) {
+ fprintf(stderr, "%s: libspectrum error\n", __FUNCTION__);
+ exit(1);
+ }
+ if(cls != LIBSPECTRUM_CLASS_SNAPSHOT) {
+ fprintf(stderr, "%s: %s is not a snapshot\n", __FUNCTION__, kernel_filename);
+ exit(1);
+ }
+ snapmem = malloc(65536);
+ length = load_image(kernel_filename, snapmem);
+ //printf("loaded %d bytes from %s\n",length, kernel_filename);
+ if(libspectrum_snap_read(snap, snapmem, length, type, NULL) != LIBSPECTRUM_ERROR_NONE) {
+ fprintf(stderr, "%s: failed to load snapshot %s\n", __FUNCTION__, kernel_filename);
+ exit(1);
+ }
+ //printf("snap pc = %d\n",libspectrum_snap_pc(snap));
+ page = libspectrum_snap_pages(snap, 5);
+ for(i = 0x4000; i < 0x8000; i++) {
+ //printf("storing 0x%x in 0x%x\n",page[i-0x4000],i);
+ stb_phys(i, page[i - 0x4000]);
+ }
+ page = libspectrum_snap_pages(snap, 2);
+ for(i = 0x8000; i < 0xc000; i++)
+ stb_phys(i, page[i - 0x8000]);
+ page = libspectrum_snap_pages(snap, 0);
+ for(i = 0xc000; i < 0x10000; i++)
+ stb_phys(i, page[i - 0xc000]);
+ env->regs[R_A] = libspectrum_snap_a(snap);
+ env->regs[R_F] = libspectrum_snap_f(snap);
+ env->regs[R_BC] = libspectrum_snap_bc(snap);
+ env->regs[R_DE] = libspectrum_snap_de(snap);
+ env->regs[R_HL] = libspectrum_snap_hl(snap);
+ env->regs[R_AFX] = libspectrum_snap_a_(snap) << 8 | libspectrum_snap_f_(snap);
+ env->regs[R_BCX] = libspectrum_snap_bc_(snap);
+ env->regs[R_DEX] = libspectrum_snap_de_(snap);
+ env->regs[R_HLX] = libspectrum_snap_hl_(snap);
+ env->regs[R_IX] = libspectrum_snap_ix(snap);
+ env->regs[R_IY] = libspectrum_snap_iy(snap);
+ env->regs[R_I] = libspectrum_snap_i(snap);
+ env->regs[R_R] = libspectrum_snap_r(snap);
+ env->regs[R_SP] = libspectrum_snap_sp(snap);
+ env->pc = libspectrum_snap_pc(snap);
+ env->iff1 = libspectrum_snap_iff1(snap);
+ env->iff2 = libspectrum_snap_iff2(snap);
+ env->imode = libspectrum_snap_im(snap);
+
+ }
+#endif
+}
+
+static void zx_spectrum_init(int ram_size, int vga_ram_size, int boot_device,
@ -434,9 +531,9 @@ diff -urN qemu-0.9.0/hw/zx_spectrum.c qemu-z80/hw/zx_spectrum.c
+ "Z80 Machine",
+ zx_spectrum_init,
+};
diff -urN qemu-0.9.0/hw/zx_ula.c qemu-z80/hw/zx_ula.c
--- qemu-0.9.0/hw/zx_ula.c 1970-01-01 01:00:00.000000000 +0100
+++ qemu-z80/hw/zx_ula.c 2007-04-17 20:55:28.000000000 +0100
diff --exclude='*.orig' --exclude=CVS -ruN qemu/hw/zx_ula.c qemu-z80/hw/zx_ula.c
--- qemu/hw/zx_ula.c 1970-01-01 01:00:00.000000000 +0100
+++ qemu-z80/hw/zx_ula.c 2007-07-06 13:01:14.000000000 +0200
@@ -0,0 +1,355 @@
+/*
+ * QEMU ZX Spectrum Video Emulation.
@ -652,8 +749,8 @@ diff -urN qemu-0.9.0/hw/zx_ula.c qemu-z80/hw/zx_ula.c
+ ZXVState *s = (ZXVState *)opaque;
+ uint32_t addr, attrib;
+
+ if (!s->dirty)
+ return;
+ //if (!s->dirty)
+ // return;
+
+ d = s->ds->data;
+ d += s->bheight * s->ds->linesize;
@ -783,43 +880,46 @@ diff -urN qemu-0.9.0/hw/zx_ula.c qemu-z80/hw/zx_ula.c
+ s->border = 0;
+ dpy_resize(s->ds, s->twidth, s->theight);
+
+ zx_io_memory = cpu_register_io_memory(0, zx_mem_read, zx_mem_write, s);
+ cpu_register_physical_memory(0x4000, 0x1b00, zx_io_memory);
+ //zx_io_memory = cpu_register_io_memory(0, zx_mem_read, zx_mem_write, s);
+ //cpu_register_physical_memory(0x4000, 0x2000, zx_io_memory);
+// cpu_register_physical_memory(0x4000, 0x2000, zx_io_memory);
+// cpu_register_physical_memory(0x4000, 0xc000, zx_io_memory);
+ s->vram_ptr = phys_ram_base + zx_io_memory;
+ s->vram_offset = zx_io_memory;
+ s->vram_ptr = phys_ram_base + 0;//x4000;//zx_io_memory;
+ s->vram_offset = 0;//x4000;//zx_io_memory;
+
+ /* ZX Spectrum ULA */
+ register_ioport_write(0, 0x10000, 1, io_spectrum_write, s);
+}
diff -urN qemu-0.9.0/Makefile qemu-z80/Makefile
--- qemu-0.9.0/Makefile 2007-02-05 23:01:54.000000000 +0000
+++ qemu-z80/Makefile 2007-03-27 21:07:11.000000000 +0100
@@ -79,7 +79,7 @@
diff --exclude='*.orig' --exclude=CVS -ruN qemu/Makefile qemu-z80/Makefile
--- qemu/Makefile 2007-06-17 18:41:04.000000000 +0200
+++ qemu-z80/Makefile 2007-07-05 18:07:36.000000000 +0200
@@ -72,7 +72,7 @@
mkdir -p "$(DESTDIR)$(datadir)"
for x in bios.bin vgabios.bin vgabios-cirrus.bin ppc_rom.bin \
video.x openbios-sparc32 linux_boot.bin pxe-ne2k_pci.bin \
video.x openbios-sparc32 pxe-ne2k_pci.bin \
- pxe-rtl8139.bin pxe-pcnet.bin; do \
+ pxe-rtl8139.bin pxe-pcnet.bin zx-rom.bin ; do \
$(INSTALL) -m 644 $(SRC_PATH)/pc-bios/$$x "$(DESTDIR)$(datadir)"; \
done
ifndef CONFIG_WIN32
diff -urN qemu-0.9.0/Makefile.target qemu-z80/Makefile.target
--- qemu-0.9.0/Makefile.target 2007-02-05 23:01:54.000000000 +0000
+++ qemu-z80/Makefile.target 2007-04-15 19:35:13.000000000 +0100
@@ -271,6 +271,10 @@
LIBOBJS+= helper.o
diff --exclude='*.orig' --exclude=CVS -ruN qemu/Makefile.target qemu-z80/Makefile.target
--- qemu/Makefile.target 2007-06-30 19:32:17.000000000 +0200
+++ qemu-z80/Makefile.target 2007-07-06 14:59:02.000000000 +0200
@@ -315,6 +315,13 @@
LIBOBJS+= op_helper.o helper.o alpha_palcode.o
endif
+ifeq ($(TARGET_BASE_ARCH), z80)
+LIBOBJS+=helper.o helper2.o
+ifdef CONFIG_LIBSPECTRUM
+LIBS+=-lspectrum
+endif
+endif
+
# NOTE: the disassembler code is only needed for debugging
LIBOBJS+=disas.o
ifeq ($(findstring i386, $(TARGET_ARCH) $(ARCH)),i386)
@@ -303,6 +307,9 @@
@@ -347,6 +354,9 @@
ifeq ($(findstring sh4, $(TARGET_ARCH) $(ARCH)),sh4)
LIBOBJS+=sh4-dis.o
endif
@ -829,9 +929,9 @@ diff -urN qemu-0.9.0/Makefile.target qemu-z80/Makefile.target
ifdef CONFIG_GDBSTUB
OBJS+=gdbstub.o
@@ -407,6 +414,10 @@
ifeq ($(TARGET_BASE_ARCH), sh4)
VL_OBJS+= shix.o sh7750.o sh7750_regnames.o tc58128.o
@@ -472,6 +482,10 @@
VL_OBJS+= an5206.o mcf5206.o ptimer.o mcf_uart.o mcf_intc.o mcf5208.o mcf_fec.o
VL_OBJS+= m68k-semi.o
endif
+ifeq ($(TARGET_BASE_ARCH), z80)
+VL_OBJS+= zx_spectrum.o zx_ula.o dma.o $(AUDIODRV)
@ -840,7 +940,7 @@ diff -urN qemu-0.9.0/Makefile.target qemu-z80/Makefile.target
ifdef CONFIG_GDBSTUB
VL_OBJS+=gdbstub.o
endif
@@ -514,9 +525,15 @@
@@ -582,9 +596,15 @@
helper.o: helper.c
$(CC) $(HELPER_CFLAGS) $(CPPFLAGS) $(BASE_CFLAGS) -c -o $@ $<
else
@ -856,7 +956,7 @@ diff -urN qemu-0.9.0/Makefile.target qemu-z80/Makefile.target
cpu-exec.o: cpu-exec.c
$(CC) $(HELPER_CFLAGS) $(CPPFLAGS) $(BASE_CFLAGS) -c -o $@ $<
@@ -529,6 +546,9 @@
@@ -601,6 +621,9 @@
ifeq ($(TARGET_BASE_ARCH), i386)
op.o: op.c opreg_template.h ops_template.h ops_template_mem.h ops_mem.h ops_sse.h
endif
@ -866,32 +966,32 @@ diff -urN qemu-0.9.0/Makefile.target qemu-z80/Makefile.target
ifeq ($(TARGET_ARCH), arm)
op.o: op.c op_template.h
Binary files qemu-0.9.0/pc-bios/zx-rom.bin and qemu-z80/pc-bios/zx-rom.bin differ
diff -urN qemu-0.9.0/softmmu_header.h qemu-z80/softmmu_header.h
--- qemu-0.9.0/softmmu_header.h 2007-02-05 23:01:54.000000000 +0000
+++ qemu-z80/softmmu_header.h 2007-03-27 21:07:11.000000000 +0100
@@ -63,6 +63,8 @@
#define CPU_MEM_INDEX ((env->uncached_cpsr & CPSR_M) == ARM_CPU_MODE_USR)
#elif defined (TARGET_SH4)
#define CPU_MEM_INDEX ((env->sr & SR_MD) == 0)
Files qemu/school.z80 and qemu-z80/school.z80 differ
diff --exclude='*.orig' --exclude=CVS -ruN qemu/softmmu_header.h qemu-z80/softmmu_header.h
--- qemu/softmmu_header.h 2007-05-23 21:58:10.000000000 +0200
+++ qemu-z80/softmmu_header.h 2007-07-05 18:11:08.000000000 +0200
@@ -67,6 +67,8 @@
#define CPU_MEM_INDEX ((env->ps >> 3) & 3)
#elif defined (TARGET_M68K)
#define CPU_MEM_INDEX ((env->sr & SR_S) == 0)
+#elif defined (TARGET_Z80)
+#define CPU_MEM_INDEX ((env->hflags & HF_CPL_MASK) == 3)
#else
#error unsupported CPU
#endif
@@ -82,6 +84,8 @@
#define CPU_MEM_INDEX ((env->uncached_cpsr & CPSR_M) == ARM_CPU_MODE_USR)
#elif defined (TARGET_SH4)
#define CPU_MEM_INDEX ((env->sr & SR_MD) == 0)
@@ -90,6 +92,8 @@
#define CPU_MEM_INDEX ((env->ps >> 3) & 3)
#elif defined (TARGET_M68K)
#define CPU_MEM_INDEX ((env->sr & SR_S) == 0)
+#elif defined (TARGET_Z80)
+#define CPU_MEM_INDEX ((env->hflags & HF_CPL_MASK) == 3)
#else
#error unsupported CPU
#endif
diff -urN qemu-0.9.0/target-z80/cpu.h qemu-z80/target-z80/cpu.h
--- qemu-0.9.0/target-z80/cpu.h 1970-01-01 01:00:00.000000000 +0100
+++ qemu-z80/target-z80/cpu.h 2007-04-17 21:05:57.000000000 +0100
@@ -0,0 +1,235 @@
diff --exclude='*.orig' --exclude=CVS -ruN qemu/target-z80/cpu.h qemu-z80/target-z80/cpu.h
--- qemu/target-z80/cpu.h 1970-01-01 01:00:00.000000000 +0100
+++ qemu-z80/target-z80/cpu.h 2007-07-06 11:59:06.000000000 +0200
@@ -0,0 +1,243 @@
+/*
+ * Z80 virtual CPU header
+ *
@ -1083,6 +1183,7 @@ diff -urN qemu-0.9.0/target-z80/cpu.h qemu-z80/target-z80/cpu.h
+ uint32_t smbase;
+ int interrupt_request;
+ int user_mode_only; /* user mode only simulation */
+ int halted;
+
+ CPU_COMMON
+
@ -1124,13 +1225,20 @@ diff -urN qemu-0.9.0/target-z80/cpu.h qemu-z80/target-z80/cpu.h
+void cpu_smm_update(CPUZ80State *env);
+
+#define TARGET_PAGE_BITS 12
+
+#define CPUState CPUZ80State
+#define cpu_init cpu_z80_init
+#define cpu_exec cpu_z80_exec
+#define cpu_gen_code cpu_z80_gen_code
+#define cpu_signal_handler cpu_z80_signal_handler
+
+#include "cpu-all.h"
+
+#endif /* CPU_Z80_H */
diff -urN qemu-0.9.0/target-z80/exec.h qemu-z80/target-z80/exec.h
--- qemu-0.9.0/target-z80/exec.h 1970-01-01 01:00:00.000000000 +0100
+++ qemu-z80/target-z80/exec.h 2007-04-17 21:02:26.000000000 +0100
@@ -0,0 +1,361 @@
diff --exclude='*.orig' --exclude=CVS -ruN qemu/target-z80/exec.h qemu-z80/target-z80/exec.h
--- qemu/target-z80/exec.h 1970-01-01 01:00:00.000000000 +0100
+++ qemu-z80/target-z80/exec.h 2007-07-05 18:30:59.000000000 +0200
@@ -0,0 +1,372 @@
+/*
+ * Z80 execution defines
+ *
@ -1492,9 +1600,20 @@ diff -urN qemu-0.9.0/target-z80/exec.h qemu-z80/target-z80/exec.h
+ env->regs[R_HLX] = HLX;
+#endif
+}
diff -urN qemu-0.9.0/target-z80/helper2.c qemu-z80/target-z80/helper2.c
--- qemu-0.9.0/target-z80/helper2.c 1970-01-01 01:00:00.000000000 +0100
+++ qemu-z80/target-z80/helper2.c 2007-04-17 21:29:49.000000000 +0100
+
+static inline int cpu_halted(CPUState* env) {
+ if (!env->halted)
+ return 0;
+ if (env->interrupt_request & CPU_INTERRUPT_HARD) {
+ env->halted = 0;
+ env->hflags &= ~HF_HALTED_MASK;
+ return 0;
+ }
+ return EXCP_HALTED;
+}
diff --exclude='*.orig' --exclude=CVS -ruN qemu/target-z80/helper2.c qemu-z80/target-z80/helper2.c
--- qemu/target-z80/helper2.c 1970-01-01 01:00:00.000000000 +0100
+++ qemu-z80/target-z80/helper2.c 2007-07-05 18:37:36.000000000 +0200
@@ -0,0 +1,170 @@
+/*
+ * Z80 helpers (without register variable usage)
@ -1655,7 +1774,7 @@ diff -urN qemu-0.9.0/target-z80/helper2.c qemu-z80/target-z80/helper2.c
+ return ret;
+}
+
+target_ulong cpu_get_phys_page_debug(CPUState *env, target_ulong addr)
+target_phys_addr_t cpu_get_phys_page_debug(CPUState *env, target_ulong addr)
+{
+ uint32_t pte, paddr, page_offset, page_size;
+
@ -1666,10 +1785,10 @@ diff -urN qemu-0.9.0/target-z80/helper2.c qemu-z80/target-z80/helper2.c
+ paddr = (pte & TARGET_PAGE_MASK) + page_offset;
+ return paddr;
+}
diff -urN qemu-0.9.0/target-z80/helper.c qemu-z80/target-z80/helper.c
--- qemu-0.9.0/target-z80/helper.c 1970-01-01 01:00:00.000000000 +0100
+++ qemu-z80/target-z80/helper.c 2007-04-25 17:54:06.000000000 +0100
@@ -0,0 +1,283 @@
diff --exclude='*.orig' --exclude=CVS -ruN qemu/target-z80/helper.c qemu-z80/target-z80/helper.c
--- qemu/target-z80/helper.c 1970-01-01 01:00:00.000000000 +0100
+++ qemu-z80/target-z80/helper.c 2007-07-05 18:38:49.000000000 +0200
@@ -0,0 +1,276 @@
+/*
+ * Z80 helpers
+ *
@ -1760,14 +1879,6 @@ diff -urN qemu-0.9.0/target-z80/helper.c qemu-z80/target-z80/helper.c
+ spin_unlock(&global_cpu_lock);
+}
+
+void cpu_loop_exit(void)
+{
+ /* NOTE: the register at this point must be saved by hand because
+ longjmp restore them */
+ regs_to_env();
+ longjmp(env->jmp_env, 1);
+}
+
+void do_interrupt(CPUZ80State *env)
+{
+// printf("z80: do_interrupt()\n");
@ -1849,6 +1960,7 @@ diff -urN qemu-0.9.0/target-z80/helper.c qemu-z80/target-z80/helper.c
+
+void helper_hlt(void)
+{
+ env->halted = 1;
+ env->hflags &= ~HF_INHIBIT_IRQ_MASK; /* needed if sti is just before */
+ env->hflags |= HF_HALTED_MASK;
+ env->exception_index = EXCP_HLT;
@ -1953,9 +2065,9 @@ diff -urN qemu-0.9.0/target-z80/helper.c qemu-z80/target-z80/helper.c
+ fl & 0x01 ? 'C' : '-',
+ env->imode, env->iff1, env->iff2, env->regs[R_I], env->regs[R_R]);
+}
diff -urN qemu-0.9.0/target-z80/op.c qemu-z80/target-z80/op.c
--- qemu-0.9.0/target-z80/op.c 1970-01-01 01:00:00.000000000 +0100
+++ qemu-z80/target-z80/op.c 2007-04-25 17:41:33.000000000 +0100
diff --exclude='*.orig' --exclude=CVS -ruN qemu/target-z80/op.c qemu-z80/target-z80/op.c
--- qemu/target-z80/op.c 1970-01-01 01:00:00.000000000 +0100
+++ qemu-z80/target-z80/op.c 2007-07-05 18:03:12.000000000 +0200
@@ -0,0 +1,1175 @@
+/*
+ * Z80 micro operations
@ -3132,9 +3244,9 @@ diff -urN qemu-0.9.0/target-z80/op.c qemu-z80/target-z80/op.c
+{
+ cpu_unlock();
+}
diff -urN qemu-0.9.0/target-z80/opreg_template2.h qemu-z80/target-z80/opreg_template2.h
--- qemu-0.9.0/target-z80/opreg_template2.h 1970-01-01 01:00:00.000000000 +0100
+++ qemu-z80/target-z80/opreg_template2.h 2007-03-27 21:42:55.000000000 +0100
diff --exclude='*.orig' --exclude=CVS -ruN qemu/target-z80/opreg_template2.h qemu-z80/target-z80/opreg_template2.h
--- qemu/target-z80/opreg_template2.h 1970-01-01 01:00:00.000000000 +0100
+++ qemu-z80/target-z80/opreg_template2.h 2007-07-05 18:03:12.000000000 +0200
@@ -0,0 +1,63 @@
+/*
+ * Z80 micro operations (templates for various register related
@ -3199,9 +3311,9 @@ diff -urN qemu-0.9.0/target-z80/opreg_template2.h qemu-z80/target-z80/opreg_temp
+ REGHIGH = (uint16_t)(T1 >> 8);
+ REGLOW = (uint16_t)T1;
+}
diff -urN qemu-0.9.0/target-z80/opreg_template.h qemu-z80/target-z80/opreg_template.h
--- qemu-0.9.0/target-z80/opreg_template.h 1970-01-01 01:00:00.000000000 +0100
+++ qemu-z80/target-z80/opreg_template.h 2007-03-27 21:43:07.000000000 +0100
diff --exclude='*.orig' --exclude=CVS -ruN qemu/target-z80/opreg_template.h qemu-z80/target-z80/opreg_template.h
--- qemu/target-z80/opreg_template.h 1970-01-01 01:00:00.000000000 +0100
+++ qemu-z80/target-z80/opreg_template.h 2007-07-05 18:03:12.000000000 +0200
@@ -0,0 +1,74 @@
+/*
+ * Z80 micro operations (templates for various register related
@ -3277,9 +3389,9 @@ diff -urN qemu-0.9.0/target-z80/opreg_template.h qemu-z80/target-z80/opreg_templ
+{
+ REG = (uint16_t)T1;
+}
diff -urN qemu-0.9.0/target-z80/ops_mem.h qemu-z80/target-z80/ops_mem.h
--- qemu-0.9.0/target-z80/ops_mem.h 1970-01-01 01:00:00.000000000 +0100
+++ qemu-z80/target-z80/ops_mem.h 2007-04-15 19:39:49.000000000 +0100
diff --exclude='*.orig' --exclude=CVS -ruN qemu/target-z80/ops_mem.h qemu-z80/target-z80/ops_mem.h
--- qemu/target-z80/ops_mem.h 1970-01-01 01:00:00.000000000 +0100
+++ qemu-z80/target-z80/ops_mem.h 2007-07-05 18:03:12.000000000 +0200
@@ -0,0 +1,59 @@
+void OPPROTO glue(glue(op_ldub, MEMSUFFIX), _T0_A0)(void)
+{
@ -3340,9 +3452,9 @@ diff -urN qemu-0.9.0/target-z80/ops_mem.h qemu-z80/target-z80/ops_mem.h
+}
+
+#undef MEMSUFFIX
diff -urN qemu-0.9.0/target-z80/translate.c qemu-z80/target-z80/translate.c
--- qemu-0.9.0/target-z80/translate.c 1970-01-01 01:00:00.000000000 +0100
+++ qemu-z80/target-z80/translate.c 2007-04-25 17:54:16.000000000 +0100
diff --exclude='*.orig' --exclude=CVS -ruN qemu/target-z80/translate.c qemu-z80/target-z80/translate.c
--- qemu/target-z80/translate.c 1970-01-01 01:00:00.000000000 +0100
+++ qemu-z80/target-z80/translate.c 2007-07-05 18:03:12.000000000 +0200
@@ -0,0 +1,1600 @@
+/*
+ * Z80 translation
@ -4944,10 +5056,10 @@ diff -urN qemu-0.9.0/target-z80/translate.c qemu-z80/target-z80/translate.c
+ return gen_intermediate_code_internal(env, tb, 1);
+}
+
diff -urN qemu-0.9.0/vl.c qemu-z80/vl.c
--- qemu-0.9.0/vl.c 2007-02-05 23:01:54.000000000 +0000
+++ qemu-z80/vl.c 2007-04-25 17:58:06.000000000 +0100
@@ -5201,6 +5201,7 @@
diff --exclude='*.orig' --exclude=CVS -ruN qemu/vl.c qemu-z80/vl.c
--- qemu/vl.c 2007-07-02 17:03:13.000000000 +0200
+++ qemu-z80/vl.c 2007-07-05 18:09:48.000000000 +0200
@@ -5595,6 +5595,7 @@
qemu_get_be64s(f, &env->fmask);
qemu_get_be64s(f, &env->kernelgsbase);
#endif
@ -4955,7 +5067,7 @@ diff -urN qemu-0.9.0/vl.c qemu-z80/vl.c
if (version_id >= 4)
qemu_get_be32s(f, &env->smbase);
@@ -5319,6 +5320,19 @@
@@ -5846,6 +5847,19 @@
return 0;
}
@ -4975,20 +5087,20 @@ diff -urN qemu-0.9.0/vl.c qemu-z80/vl.c
#else
#warning No CPU save/restore functions
@@ -6368,6 +6382,8 @@
qemu_register_machine(&realview_machine);
#elif defined(TARGET_SH4)
qemu_register_machine(&shix_machine);
@@ -6997,6 +7011,8 @@
#elif defined(TARGET_M68K)
qemu_register_machine(&mcf5208evb_machine);
qemu_register_machine(&an5206_machine);
+#elif defined(TARGET_Z80)
+ qemu_register_machine(&z80pc_machine);
#else
#error unsupported CPU
#endif
diff -urN qemu-0.9.0/vl.h qemu-z80/vl.h
--- qemu-0.9.0/vl.h 2007-02-05 23:01:54.000000000 +0000
+++ qemu-z80/vl.h 2007-04-17 20:16:51.000000000 +0100
@@ -901,6 +901,11 @@
void isa_cirrus_vga_init(DisplayState *ds, uint8_t *vga_ram_base,
diff --exclude='*.orig' --exclude=CVS -ruN qemu/vl.h qemu-z80/vl.h
--- qemu/vl.h 2007-06-30 19:32:17.000000000 +0200
+++ qemu-z80/vl.h 2007-07-05 18:03:12.000000000 +0200
@@ -959,6 +959,11 @@
void pci_vmsvga_init(PCIBus *bus, DisplayState *ds, uint8_t *vga_ram_base,
unsigned long vga_ram_offset, int vga_ram_size);
+/* zx_ula.c */
@ -4997,9 +5109,9 @@ diff -urN qemu-0.9.0/vl.h qemu-z80/vl.h
+void zx_set_flash_dirty(void);
+
/* sdl.c */
void sdl_display_init(DisplayState *ds, int full_screen);
void sdl_display_init(DisplayState *ds, int full_screen, int no_frame);
@@ -1065,6 +1070,9 @@
@@ -1150,6 +1155,9 @@
extern QEMUMachine isapc_machine;
extern int fd_bootchk;
@ -5009,9 +5121,9 @@ diff -urN qemu-0.9.0/vl.h qemu-z80/vl.h
void ioport_set_a20(int enable);
int ioport_get_a20(void);
diff -urN qemu-0.9.0/z80-dis.c qemu-z80/z80-dis.c
--- qemu-0.9.0/z80-dis.c 1970-01-01 01:00:00.000000000 +0100
+++ qemu-z80/z80-dis.c 2007-02-01 15:20:38.000000000 +0000
diff --exclude='*.orig' --exclude=CVS -ruN qemu/z80-dis.c qemu-z80/z80-dis.c
--- qemu/z80-dis.c 1970-01-01 01:00:00.000000000 +0100
+++ qemu-z80/z80-dis.c 2007-07-05 18:03:12.000000000 +0200
@@ -0,0 +1,621 @@
+/* Print Z80 and R800 instructions
+ Copyright 2005 Free Software Foundation, Inc.

View File

@ -1,3 +1,27 @@
-------------------------------------------------------------------
Tue Jul 10 15:44:03 CEST 2007 - schwab@suse.de
- Add (incomplete) m68k emulation.
-------------------------------------------------------------------
Mon Jul 9 17:02:48 CEST 2007 - agraf@suse.de
- included alsa support in qemu-user
- update to current cvs
- TFTP booting from host directory (Anthony Liguori, Erwan Velu)
- Tap device emulation for Solaris (Sittichai Palanisong)
- Monitor multiplexing to several I/O channels (Jason Wessel)
- ds1225y nvram support (Herve Poussineau)
- CPU model selection support (J. Mayer, Paul Brook, Herve Poussineau)
- Several Sparc fixes (Aurelien Jarno, Blue Swirl)
- MIPS 64-bit FPU support (Thiemo Seufer)
- Xscale PDA emulation (Andrzei Zaborowski)
- ColdFire system emulation (Paul Brook)
- Improved SH4 support (Magnus Damm)
- MIPS64 support (Aurelien Jarno, Thiemo Seufer)
- Preliminary Alpha guest support (J. Mayer)
- IPC fixes
-------------------------------------------------------------------
Wed Jun 20 14:38:47 CEST 2007 - agraf@suse.de

214
qemu.spec
View File

@ -1,5 +1,5 @@
#
# spec file for package qemu (Version 0.9.0)
# spec file for package qemu (Version 0.9.0.cvs)
#
# Copyright (c) 2007 SUSE LINUX Products GmbH, Nuernberg, Germany.
# This file and all modifications and additions to the pristine
@ -13,11 +13,11 @@
Name: qemu
BuildRequires: SDL-devel bison e2fsprogs-devel
URL: http://fabrice.bellard.free.fr/qemu/
License: BSD License and BSD-like, GNU General Public License (GPL)
Group: System/Emulators/Other
License: BSD 3-Clause, GPL v2 or later
Group: System/Emulators/PC
Summary: Universal CPU emulator
Version: 0.9.0
Release: 38
Version: 0.9.0.cvs
Release: 1
Source: %name-%version.tar.bz2
#Patch400: qemu-0.7.0-gcc4-dot-syms.patch
#Patch401: qemu-0.8.0-gcc4-hacks.patch
@ -25,38 +25,39 @@ Source: %name-%version.tar.bz2
Patch1: qemu-0.7.0-binfmt.patch
Patch5: qemu-0.7.0-sigaltstackhack.patch
Patch6: qemu-0.7.0-amd64.patch
Patch8: qemu-0.9.0.patch
Patch8: qemu-cvs-pthread.patch
Patch10: linkerscripts.patch
Patch11: qemu-0.7.2-kqemu.patch
Patch14: qemu-0.7.1-jobsignals.patch
Patch15: qemu-0.9.0-syscalls.patch
Patch16: qemu-0.7.1-armfpaex.patch
Patch19: qemu-0.9.0-nousbdevfs.patch
Patch20: qemu-0.9.0-usbheaders.patch
Patch21: qemu-0.9.0-initrd.patch
Patch22: qemu-0.9.0-nptl.patch
Patch23: qemu-0.9.0-fadvise64.patch
Patch25: qemu-0.9.0-nptl2.patch
Patch26: qemu-0.9.0-socket.patch
Patch27: qemu-0.9.0-strace.patch
Patch28: qemu-0.9.0-mmap.patch
Patch29: qemu-0.9.0-alt-path.patch
Patch30: qemu-0.9.0-nonetlink.patch
Patch31: qemu-0.9.0-kernel-option-vga.patch
Patch32: qemu-0.9.0-x86_64-opts.patch
Patch33: qemu-0.9.0-fix-cpus-chaining.patch
Patch34: qemu-0.9.0-migration.patch
Patch36: qemu-0.9.0-fix-x86-fprem.patch
Patch37: qemu-0.9.0-kvm.patch
Patch38: qemu-0.9.0-kvm-bios.patch
Patch39: qemu-0.9.0-kvm-kqemu-window-caption.patch
Patch40: qemu-z80.diff
Patch41: qemu-0.9.0-sched.patch
Patch42: qemu-0.8.2-alt-mmap.patch
Patch43: qemu-0.9.0-futex.patch
Patch44: qemu-0.9.0-robust_list.patch
Patch45: qemu-0.9.0-wine.patch
Patch46: bug-252519_goo-qemu-sec-0.9.0.diff
Patch48: qemu-z80.diff
Patch49: qemu-cvs-img.patch
Patch50: qemu-cvs-newpath.patch
Patch51: qemu-cvs-tls.patch
Patch52: qemu-cvs-futex.patch
Patch53: qemu-cvs-sched_getaffinity.patch
Patch54: qemu-cvs-mplayer.patch
Patch55: qemu-cvs-netlink.patch
Patch56: qemu-cvs-ipc.patch
Patch57: qemu-cvs-ipc_semop.patch
Patch58: qemu-cvs-ioctl_debug.patch
Patch59: qemu-cvs-alsa_bitfield.patch
Patch60: qemu-cvs-alsa_ioctl.patch
Patch61: qemu-cvs-ioctl_nodirection.patch
Patch62: qemu-cvs-alsa_mmap.patch
Patch63: qemu-cvs-gettimeofday.patch
Patch64: qemu-cvs-nofadvise64.patch
Patch65: qemu-cvs-flash.patch
Patch66: qemu-cvs-mmap-amd64.patch
Patch67: qemu-cvs-noppcemb.patch
Patch68: qemu-0.8.3-gcc4.patch
Patch69: qemu-cvs-ia64.patch
Patch70: qemu-m68k.diff
Source200: kvm_bios.bin
Source201: zx-rom.bin
Source202: COPYING.zx-rom
@ -98,6 +99,8 @@ Patch663: gcc-ppc-nostartfileprefix.patch
Patch664: gcc-ppc-nof.patch
Patch700: gcc-abuildappease.patch
Patch701: gcc-3.3.5.dif
# this is to make lint happy
Source300: rpmlintrc
BuildRoot: %{_tmppath}/%{name}-%{version}-build
ExclusiveArch: %ix86 ppc sparc x86_64 ia64
@ -119,41 +122,45 @@ Authors:
#%patch400 -p1
#%patch401 -p1
#%patch402 -p1
%patch1
%patch1 -p1
%patch5
%patch6
%patch8
%patch8 -p1
%patch10
%patch11
%patch14
%patch15
%patch16
%patch19
%patch20
%patch21 -p1
%patch22 -p1
%patch23 -p1
%patch25 -p1
%patch26 -p1
%patch27 -p1
%patch28 -p1
%patch29 -p1
%patch30 -p1
%patch31 -p1
%patch32 -p1
%patch33 -p1
%patch34 -p1
%patch36 -p1
%patch37 -p1
%patch38 -p1
%patch39 -p1
%patch40 -p1
%patch41 -p1
%patch42 -p1
%patch43 -p1
%patch44 -p1
%patch45 -p1
%patch46 -p1
#%patch34 -p1
#%patch37 -p1
#%patch38 -p1
#%patch39 -p1
%patch48 -p1
%patch49
%patch50 -p1
%patch51 -p1
%patch52 -p1
%patch53 -p1
%patch54 -p1
%patch55 -p1
%patch56 -p1
%patch57 -p1
%patch58 -p1
%patch59 -p1
%patch60 -p1
%patch61 -p1
%patch62 -p1
%patch63 -p1
%patch64 -p1
%patch65 -p1
%patch66 -p1
%patch67 -p1
%patch69
%patch70
%ifarch ia64 ppc64
#this is the dyngen for gcc4 patch (does not work on x86)
%patch68 -p1
%endif
cp -p %SOURCE200 pc-bios/
cp -p %SOURCE202 .
cd gcc-3.3.5
@ -192,9 +199,12 @@ cd gcc-3.3.5
cd ..
%build
QEMU_OPT_FLAGS="$RPM_OPT_FLAGS"
%ifarch ia64 ppc64
%define qemucc gcc
%else
%define gcc33tmp /tmp/gcc33
%define qemucc %{gcc33tmp}/bin/gcc
QEMU_OPT_FLAGS="$RPM_OPT_FLAGS"
# fix opt flags for gcc3
%ifarch %ix86
QEMU_OPT_FLAGS="${RPM_OPT_FLAGS/-mtune=/-mcpu=}"
@ -214,57 +224,26 @@ cd gcc-3.3.5
make bootstrap-lean BOOT_CFLAGS="$QEMU_OPT_FLAGS" STAGE1_CFLAGS="$QEMU_OPT_FLAGS" CFLAGS="$QEMU_OPT_FLAGS" %{?jobs:-j%{jobs}}
make install
cd ..
QEMU_OPT_FLAGS="$QEMU_OPT_FLAGS -fno-strict-aliasing"
%endif
# build QEMU
mkdir -p dynamic
# build qemu-system without kqemu support
./configure --prefix=/usr \
--interp-prefix=/usr/share/qemu/qemu-i386 \
--cc=%qemucc --enable-adlib --disable-gcc-check \
--extra-cflags="$QEMU_OPT_FLAGS" --enable-system --disable-linux-user
make %{?jobs:-j%{jobs}}
mv */qemu */qemu-* dynamic || true
make clean
# build qemu-system with kqemu support
# kqemu target
%ifarch %ix86 x86_64
%ifarch x86_64
target_list_kqemu="x86_64-softmmu"
%else
target_list_kqemu="i386-softmmu"
%endif
# targets for all platforms
target_list="ppc-softmmu sparc-softmmu mips-softmmu mipsel-softmmu arm-softmmu z80-softmmu"
# AMD64 -> i386 without kqemu
# x86 -> AMD64 without kqemu
# others -> both without kqemu
%ifarch x86_64
target_list="$target_list i386-softmmu"
%else
%ifarch %ix86
target_list="$target_list x86_64-softmmu"
%else
target_list="$target_list i386-softmmu x86_64-softmmu"
%endif
%endif
# linux-user targets
target_list_user=""
%ifnarch %ix86 x86_64
target_list_user="$target_list_user i386-linux-user"
%endif
%ifnarch armv4l
target_list_user="$target_list_user arm-linux-user"
%endif
%ifnarch armv4b
target_list_user="$target_list_user armeb-linux-user"
%endif
%ifnarch sparc sparc64
target_list_user="$target_list_user sparc-linux-user"
%endif
%ifnarch ppc ppc64
target_list_user="$target_list_user ppc-linux-user"
%endif
%ifnarch mips
target_list_user="$target_list_user mips-linux-user"
%endif
%ifnarch mipsel
target_list_user="$target_list_user mipsel-linux-user"
%endif
%ifnarch m68k
target_list_user="$target_list_user m68k-linux-user"
%endif
QEMU_OPT_FLAGS="$QEMU_OPT_FLAGS -fno-strict-aliasing"
mkdir -p dynamic
%ifarch %ix86 x86_64
# build i386/x86_64 system with kqemu support
./configure --prefix=/usr \
--interp-prefix=/usr/share/qemu/qemu-i386 \
--target-list="$target_list_kqemu" --cc=%qemucc \
@ -274,19 +253,12 @@ make %{?jobs:-j%{jobs}}
mv */qemu */qemu-* dynamic || true
make clean
%endif
# build system emus without kqemu support
./configure --prefix=/usr \
--interp-prefix=/usr/share/qemu/qemu-i386 \
--target-list="$target_list" --cc=%qemucc \
--enable-adlib --extra-cflags="$QEMU_OPT_FLAGS"
make %{?jobs:-j%{jobs}}
mv */qemu *-*/qemu-* dynamic || true
make clean
# build userland emus
./configure --prefix=/usr \
--interp-prefix=/usr/share/qemu/qemu-i386 \
--target-list="$target_list_user" --cc=%qemucc \
--static --extra-cflags="$QEMU_OPT_FLAGS"
--enable-linux-user --disable-system --cc=%qemucc \
--static --disable-gcc-check \
--extra-cflags="$QEMU_OPT_FLAGS"
make %{?jobs:-j%{jobs}}
%install
@ -299,7 +271,7 @@ install -m 755 */qemu-*[^.]? $RPM_BUILD_ROOT/usr/bin
install -d -m 755 $RPM_BUILD_ROOT/%{_mandir}/man1
install -m 644 qemu.1 $RPM_BUILD_ROOT/%{_mandir}/man1
install -d -m 755 $RPM_BUILD_ROOT/usr/share/qemu
install -m 644 pc-bios/*.bin pc-bios/video.x pc-bios/openbios-sparc32 $RPM_BUILD_ROOT/usr/share/qemu
install -m 644 pc-bios/*.bin pc-bios/video.x pc-bios/openbios-sparc* $RPM_BUILD_ROOT/usr/share/qemu
install -d -m 755 $RPM_BUILD_ROOT/usr/sbin
install -m 755 qemu-binfmt-conf.sh $RPM_BUILD_ROOT/usr/sbin
install -m 755 qemu-img $RPM_BUILD_ROOT/usr/bin
@ -332,6 +304,24 @@ rm -rf %{gcc33tmp}
%endif
%changelog
* Tue Jul 10 2007 - schwab@suse.de
- Add (incomplete) m68k emulation.
* Mon Jul 09 2007 - agraf@suse.de
- included alsa support in qemu-user
- update to current cvs
- TFTP booting from host directory (Anthony Liguori, Erwan Velu)
- Tap device emulation for Solaris (Sittichai Palanisong)
- Monitor multiplexing to several I/O channels (Jason Wessel)
- ds1225y nvram support (Herve Poussineau)
- CPU model selection support (J. Mayer, Paul Brook, Herve Poussineau)
- Several Sparc fixes (Aurelien Jarno, Blue Swirl)
- MIPS 64-bit FPU support (Thiemo Seufer)
- Xscale PDA emulation (Andrzei Zaborowski)
- ColdFire system emulation (Paul Brook)
- Improved SH4 support (Magnus Damm)
- MIPS64 support (Aurelien Jarno, Thiemo Seufer)
- Preliminary Alpha guest support (J. Mayer)
- IPC fixes
* Wed Jun 20 2007 - agraf@suse.de
- applied proper fix for x86_64 and the MAP_32BIT flag
* Wed Jun 20 2007 - uli@suse.de

5
rpmlintrc Normal file
View File

@ -0,0 +1,5 @@
# This line is mandatory to access the configuration functions
from Config import *
addFilter("qemu arch-dependent-file-in-usr-share")