diff -urN qemu-0.8.2/block.c qemu-new/block.c --- qemu-0.8.2/block.c 2006-07-22 18:23:34.000000000 +0100 +++ qemu-new/block.c 2006-09-11 15:46:30.000000000 +0100 @@ -23,6 +23,7 @@ */ #include "vl.h" #include "block_int.h" +#include "cpu-pretend.h" #ifdef _BSD #include @@ -423,24 +424,27 @@ while (nb_sectors > 0) { if (sector_num == 0 && bs->boot_sector_enabled) { - memcpy(buf, bs->boot_sector_data, 512); + cpu_memcpy(buf, bs->boot_sector_data, 512); n = 1; } else if (bs->backing_hd) { if (drv->bdrv_is_allocated(bs, sector_num, nb_sectors, &n)) { ret = drv->bdrv_read(bs, sector_num, buf, n); if (ret < 0) return -1; + cpu_pretend_write(buf, n * 512); } else { /* read from the base image */ ret = bdrv_read(bs->backing_hd, sector_num, buf, n); if (ret < 0) return -1; + cpu_pretend_write(buf, n * 512); } } else { ret = drv->bdrv_read(bs, sector_num, buf, nb_sectors); if (ret < 0) return -1; /* no need to loop */ + cpu_pretend_write(buf, nb_sectors * 512); break; } nb_sectors -= n; @@ -459,8 +463,9 @@ if (bs->read_only) return -1; if (sector_num == 0 && bs->boot_sector_enabled && nb_sectors > 0) { - memcpy(bs->boot_sector_data, buf, 512); + cpu_memcpy(bs->boot_sector_data, buf, 512); } + cpu_pretend_read(buf, nb_sectors * 512); return bs->drv->bdrv_write(bs, sector_num, buf, nb_sectors); } diff -urN qemu-0.8.2/cpu-all.h qemu-new/cpu-all.h --- qemu-0.8.2/cpu-all.h 2006-07-22 18:23:34.000000000 +0100 +++ qemu-new/cpu-all.h 2006-09-11 17:16:28.000000000 +0100 @@ -20,6 +20,8 @@ #ifndef CPU_ALL_H #define CPU_ALL_H +#include "cpu-pretend.h" + #if defined(__arm__) || defined(__sparc__) #define WORDS_ALIGNED #endif @@ -595,30 +597,30 @@ #define g2h(x) ((void *)((unsigned long)(x) + GUEST_BASE)) #define h2g(x) ((target_ulong)(x - GUEST_BASE)) -#define saddr(x) g2h(x) -#define laddr(x) g2h(x) +#define saddr(x, l) g2h(x) +#define laddr(x, l) g2h(x) #else /* !CONFIG_USER_ONLY */ /* NOTE: we use double casts if pointers and target_ulong have different sizes */ -#define saddr(x) (uint8_t *)(long)(x) -#define laddr(x) (uint8_t *)(long)(x) +#define saddr(x, l) (cpu_pretend_write((void *)x, l), (uint8_t *)(long)(x)) +#define laddr(x, l) (cpu_pretend_read((void *)x, l), (uint8_t *)(long)(x)) #endif -#define ldub_raw(p) ldub_p(laddr((p))) -#define ldsb_raw(p) ldsb_p(laddr((p))) -#define lduw_raw(p) lduw_p(laddr((p))) -#define ldsw_raw(p) ldsw_p(laddr((p))) -#define ldl_raw(p) ldl_p(laddr((p))) -#define ldq_raw(p) ldq_p(laddr((p))) -#define ldfl_raw(p) ldfl_p(laddr((p))) -#define ldfq_raw(p) ldfq_p(laddr((p))) -#define stb_raw(p, v) stb_p(saddr((p)), v) -#define stw_raw(p, v) stw_p(saddr((p)), v) -#define stl_raw(p, v) stl_p(saddr((p)), v) -#define stq_raw(p, v) stq_p(saddr((p)), v) -#define stfl_raw(p, v) stfl_p(saddr((p)), v) -#define stfq_raw(p, v) stfq_p(saddr((p)), v) +#define ldub_raw(p) ldub_p(laddr((p), 1)) +#define ldsb_raw(p) ldsb_p(laddr((p), 1)) +#define lduw_raw(p) lduw_p(laddr((p), 2)) +#define ldsw_raw(p) ldsw_p(laddr((p), 2)) +#define ldl_raw(p) ldl_p(laddr((p), 4)) +#define ldq_raw(p) ldq_p(laddr((p), 8)) +#define ldfl_raw(p) ldfl_p(laddr((p), 4)) +#define ldfq_raw(p) ldfq_p(laddr((p), 8)) +#define stb_raw(p, v) stb_p(saddr((p), 1), v) +#define stw_raw(p, v) stw_p(saddr((p), 2), v) +#define stl_raw(p, v) stl_p(saddr((p), 4), v) +#define stq_raw(p, v) stq_p(saddr((p), 8), v) +#define stfl_raw(p, v) stfl_p(saddr((p), 4), v) +#define stfq_raw(p, v) stfq_p(saddr((p), 8), v) #if defined(CONFIG_USER_ONLY) @@ -818,6 +820,7 @@ extern int phys_ram_fd; extern uint8_t *phys_ram_base; extern uint8_t *phys_ram_dirty; +extern uint8_t *phys_ram_valid; /* physical memory access */ #define TLB_INVALID_MASK (1 << 3) diff -urN qemu-0.8.2/cpu-pretend.h qemu-new/cpu-pretend.h --- qemu-0.8.2/cpu-pretend.h 1970-01-01 01:00:00.000000000 +0100 +++ qemu-new/cpu-pretend.h 2006-09-11 17:47:30.000000000 +0100 @@ -0,0 +1,23 @@ +#ifndef CPU_PRETEND_H +#define CPU_PRETEND_H + +#include +#include + +void cpu_pretend_read(const void * p, size_t size); +void cpu_pretend_write(const void * p, size_t size); +static inline void * cpu_memcpy(void * dest, const void * src, size_t n) +{ + cpu_pretend_read(src, n); + cpu_pretend_write(dest, n); + return memcpy(dest, src, n); +} +static inline char * cpu_strcpy(char * dest, const char * src) +{ + size_t len_src = strlen(src) + 1; + cpu_pretend_read(src, len_src); + cpu_pretend_write(dest, len_src); + return strcpy(dest, src); +} + +#endif diff -urN qemu-0.8.2/exec.c qemu-new/exec.c --- qemu-0.8.2/exec.c 2006-07-22 18:23:34.000000000 +0100 +++ qemu-new/exec.c 2006-09-12 03:55:44.000000000 +0100 @@ -81,6 +81,7 @@ int phys_ram_fd; uint8_t *phys_ram_base; uint8_t *phys_ram_dirty; +uint8_t *phys_ram_valid; CPUState *first_cpu; /* current CPU in the current thread. It is only valid inside @@ -2049,6 +2050,7 @@ addr1 = (pd & TARGET_PAGE_MASK) + (addr & ~TARGET_PAGE_MASK); /* RAM case */ ptr = phys_ram_base + addr1; + cpu_pretend_write(ptr, l); memcpy(ptr, buf, l); if (!cpu_physical_memory_is_dirty(addr1)) { /* invalidate code */ @@ -2083,7 +2085,7 @@ /* RAM case */ ptr = phys_ram_base + (pd & TARGET_PAGE_MASK) + (addr & ~TARGET_PAGE_MASK); - memcpy(buf, ptr, l); + cpu_memcpy(buf, ptr, l); } } len -= l; @@ -2123,6 +2125,7 @@ addr1 = (pd & TARGET_PAGE_MASK) + (addr & ~TARGET_PAGE_MASK); /* ROM/RAM case */ ptr = phys_ram_base + addr1; + cpu_pretend_write(ptr, l); memcpy(ptr, buf, l); } len -= l; @@ -2157,6 +2160,7 @@ /* RAM case */ ptr = phys_ram_base + (pd & TARGET_PAGE_MASK) + (addr & ~TARGET_PAGE_MASK); + cpu_pretend_read(ptr, 4); val = ldl_p(ptr); } return val; @@ -2193,6 +2197,7 @@ /* RAM case */ ptr = phys_ram_base + (pd & TARGET_PAGE_MASK) + (addr & ~TARGET_PAGE_MASK); + cpu_pretend_read(ptr, 8); val = ldq_p(ptr); } return val; @@ -2323,6 +2328,31 @@ return 0; } +void cpu_pretend_write(const void * p, size_t size) +{ + unsigned long from = (unsigned long)p - (unsigned long)phys_ram_base; + unsigned long i; + for (i = from; i < from + size && i < phys_ram_size; i++) + phys_ram_valid[i] = 0xff; +} + +void cpu_pretend_read(const void * p, size_t size) +{ + unsigned long from = (unsigned long)p - (unsigned long)phys_ram_base; + unsigned long i; + for (i = from; i < from + size && i < phys_ram_size; i++) + if (phys_ram_valid[i] != 0xff) { + fprintf(stderr, + "Uninitialised read of address %lx, size %x", + from, size); + if (cpu_single_env) + fprintf(stderr, " with PC approximately %lx", GET_PC(cpu_single_env)); + fprintf(stderr, "\n"); + cpu_pretend_write(p, size); + return; + } +} + void dump_exec_info(FILE *f, int (*cpu_fprintf)(FILE *f, const char *fmt, ...)) { diff -urN qemu-0.8.2/hw/acpi.c qemu-new/hw/acpi.c --- qemu-0.8.2/hw/acpi.c 2006-07-22 18:23:34.000000000 +0100 +++ qemu-new/hw/acpi.c 2006-09-11 14:33:29.000000000 +0100 @@ -539,6 +539,7 @@ cpu_register_physical_memory(base_addr, acpi_tables_size, base_addr | IO_MEM_ROM); + cpu_pretend_write(phys_ram_base + base_addr, acpi_tables_size); /* RSDP */ memset(rsdp, 0, sizeof(*rsdp)); diff -urN qemu-0.8.2/hw/arm_boot.c qemu-new/hw/arm_boot.c --- qemu-0.8.2/hw/arm_boot.c 2006-07-22 18:23:34.000000000 +0100 +++ qemu-new/hw/arm_boot.c 2006-09-11 14:20:20.000000000 +0100 @@ -53,7 +53,7 @@ int cmdline_size; cmdline_size = strlen(kernel_cmdline); - memcpy (p + 2, kernel_cmdline, cmdline_size + 1); + cpu_memcpy (p + 2, kernel_cmdline, cmdline_size + 1); cmdline_size = (cmdline_size >> 2) + 1; stl_raw(p++, cmdline_size + 2); stl_raw(p++, 0x54410009); diff -urN qemu-0.8.2/hw/mips_r4k.c qemu-new/hw/mips_r4k.c --- qemu-0.8.2/hw/mips_r4k.c 2006-07-22 18:23:34.000000000 +0100 +++ qemu-new/hw/mips_r4k.c 2006-09-11 14:24:47.000000000 +0100 @@ -252,10 +252,11 @@ } /* Store command line. */ - strcpy (phys_ram_base + (16 << 20) - 256, kernel_cmdline); + cpu_strcpy (phys_ram_base + (16 << 20) - 256, kernel_cmdline); /* FIXME: little endian support */ *(int *)(phys_ram_base + (16 << 20) - 260) = tswap32 (0x12345678); *(int *)(phys_ram_base + (16 << 20) - 264) = tswap32 (ram_size); + cpu_pretend_write(phys_ram_base + (16 << 20) - 264, 8); } /* Init internal devices */ diff -urN qemu-0.8.2/hw/pc.c qemu-new/hw/pc.c --- qemu-0.8.2/hw/pc.c 2006-07-22 18:23:34.000000000 +0100 +++ qemu-new/hw/pc.c 2006-09-11 15:20:40.000000000 +0100 @@ -386,6 +386,8 @@ if (size < 0) goto fail; close(fd); + cpu_pretend_write(real_addr, (setup_sects + 1) * 512); + cpu_pretend_write(addr, size); return size; fail: close(fd); @@ -739,6 +741,7 @@ } pstrcpy(phys_ram_base + KERNEL_CMDLINE_ADDR, 4096, kernel_cmdline); + cpu_pretend_write(phys_ram_base + KERNEL_CMDLINE_ADDR, 4096); stw_raw(phys_ram_base + KERNEL_PARAMS_ADDR + 0x20, 0xA33F); stw_raw(phys_ram_base + KERNEL_PARAMS_ADDR + 0x22, KERNEL_CMDLINE_ADDR - KERNEL_PARAMS_ADDR); diff -urN qemu-0.8.2/hw/ppc.c qemu-new/hw/ppc.c --- qemu-0.8.2/hw/ppc.c 2006-07-22 18:23:34.000000000 +0100 +++ qemu-new/hw/ppc.c 2006-09-11 14:36:18.000000000 +0100 @@ -407,7 +407,7 @@ NVRAM_set_lword(nvram, 0x3C, kernel_size); if (cmdline) { /* XXX: put the cmdline in NVRAM too ? */ - strcpy(phys_ram_base + CMDLINE_ADDR, cmdline); + cpu_strcpy(phys_ram_base + CMDLINE_ADDR, cmdline); NVRAM_set_lword(nvram, 0x40, CMDLINE_ADDR); NVRAM_set_lword(nvram, 0x44, strlen(cmdline)); } else { diff -urN qemu-0.8.2/hw/ppc_chrp.c qemu-new/hw/ppc_chrp.c --- qemu-0.8.2/hw/ppc_chrp.c 2006-07-22 18:23:34.000000000 +0100 +++ qemu-new/hw/ppc_chrp.c 2006-09-11 14:23:48.000000000 +0100 @@ -378,6 +378,7 @@ phys_ram_base[vga_bios_offset + 3] = 'V'; cpu_to_be32w((uint32_t *)(phys_ram_base + vga_bios_offset + 4), vga_bios_size); + cpu_pretend_write(phys_ram_base + vga_bios_offset, vga_bios_size + 4); vga_bios_size += 8; } vga_bios_size = (vga_bios_size + 0xfff) & ~0xfff; diff -urN qemu-0.8.2/hw/sun4m.c qemu-new/hw/sun4m.c --- qemu-0.8.2/hw/sun4m.c 2006-07-22 18:23:34.000000000 +0100 +++ qemu-new/hw/sun4m.c 2006-09-11 14:25:06.000000000 +0100 @@ -137,7 +137,7 @@ nvram_set_lword(nvram, 0x38, KERNEL_LOAD_ADDR); nvram_set_lword(nvram, 0x3C, kernel_size); if (cmdline) { - strcpy(phys_ram_base + CMDLINE_ADDR, cmdline); + cpu_strcpy(phys_ram_base + CMDLINE_ADDR, cmdline); nvram_set_lword(nvram, 0x40, CMDLINE_ADDR); nvram_set_lword(nvram, 0x44, strlen(cmdline)); } diff -urN qemu-0.8.2/hw/sun4u.c qemu-new/hw/sun4u.c --- qemu-0.8.2/hw/sun4u.c 2006-07-22 18:23:34.000000000 +0100 +++ qemu-new/hw/sun4u.c 2006-09-11 14:26:31.000000000 +0100 @@ -195,7 +195,7 @@ NVRAM_set_lword(nvram, 0x3C, kernel_size); if (cmdline) { /* XXX: put the cmdline in NVRAM too ? */ - strcpy(phys_ram_base + CMDLINE_ADDR, cmdline); + cpu_strcpy(phys_ram_base + CMDLINE_ADDR, cmdline); NVRAM_set_lword(nvram, 0x40, CMDLINE_ADDR); NVRAM_set_lword(nvram, 0x44, strlen(cmdline)); } else { diff -urN qemu-0.8.2/hw/tcx.c qemu-new/hw/tcx.c --- qemu-0.8.2/hw/tcx.c 2006-07-22 18:23:34.000000000 +0100 +++ qemu-new/hw/tcx.c 2006-09-11 15:02:32.000000000 +0100 @@ -276,6 +276,8 @@ { TCXState *s; int io_memory; + + cpu_pretend_write(vram_base, vram_size); s = qemu_mallocz(sizeof(TCXState)); if (!s) diff -urN qemu-0.8.2/hw/vga.c qemu-new/hw/vga.c --- qemu-0.8.2/hw/vga.c 2006-07-22 18:23:34.000000000 +0100 +++ qemu-new/hw/vga.c 2006-09-11 15:44:47.000000000 +0100 @@ -1727,6 +1727,8 @@ { int i, j, v, b; + cpu_pretend_write(vga_ram_base, vga_ram_size); + for(i = 0;i < 256; i++) { v = 0; for(j = 0; j < 8; j++) { diff -urN qemu-0.8.2/loader.c qemu-new/loader.c --- qemu-0.8.2/loader.c 2006-07-22 18:23:34.000000000 +0100 +++ qemu-new/loader.c 2006-09-11 14:59:12.000000000 +0100 @@ -50,6 +50,7 @@ return -1; } close(fd); + cpu_pretend_write(addr, size); return size; } diff -urN qemu-0.8.2/qemu-img.c qemu-new/qemu-img.c --- qemu-0.8.2/qemu-img.c 2006-07-22 18:23:34.000000000 +0100 +++ qemu-new/qemu-img.c 2006-09-11 15:29:13.000000000 +0100 @@ -129,6 +129,9 @@ printf(" %s", name); } +void cpu_pretend_read(const void * p, size_t size) { } +void cpu_pretend_write(const void * p, size_t size) { } + void help(void) { printf("qemu-img version " QEMU_VERSION ", Copyright (c) 2004-2005 Fabrice Bellard\n" diff -urN qemu-0.8.2/target-arm/cpu.h qemu-new/target-arm/cpu.h --- qemu-0.8.2/target-arm/cpu.h 2006-07-22 18:23:34.000000000 +0100 +++ qemu-new/target-arm/cpu.h 2006-09-12 03:54:00.000000000 +0100 @@ -22,6 +22,8 @@ #define TARGET_LONG_BITS 32 +#define GET_PC(env) env->regs[15] + #include "cpu-defs.h" #include "softfloat.h" diff -urN qemu-0.8.2/target-i386/cpu.h qemu-new/target-i386/cpu.h --- qemu-0.8.2/target-i386/cpu.h 2006-07-22 18:23:34.000000000 +0100 +++ qemu-new/target-i386/cpu.h 2006-09-12 03:53:47.000000000 +0100 @@ -20,6 +20,8 @@ #ifndef CPU_I386_H #define CPU_I386_H +#define GET_PC(env) env->eip + #include "config.h" #ifdef TARGET_X86_64 diff -urN qemu-0.8.2/target-i386/helper.c qemu-new/target-i386/helper.c --- qemu-0.8.2/target-i386/helper.c 2006-07-22 18:23:34.000000000 +0100 +++ qemu-new/target-i386/helper.c 2006-09-11 20:37:52.000000000 +0100 @@ -3538,3 +3538,5 @@ } env = saved_env; } + +unsigned long get_pc(void) { return cpu_single_env->eip; } diff -urN qemu-0.8.2/target-i386/op.c qemu-new/target-i386/op.c --- qemu-0.8.2/target-i386/op.c 2006-07-22 18:23:34.000000000 +0100 +++ qemu-new/target-i386/op.c 2006-09-11 17:27:49.000000000 +0100 @@ -18,7 +18,6 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#define ASM_SOFTMMU #include "exec.h" /* n must be a constant to be efficient */ diff -urN qemu-0.8.2/target-mips/cpu.h qemu-new/target-mips/cpu.h --- qemu-0.8.2/target-mips/cpu.h 2006-07-22 18:23:34.000000000 +0100 +++ qemu-new/target-mips/cpu.h 2006-09-12 03:54:53.000000000 +0100 @@ -3,6 +3,8 @@ #define TARGET_HAS_ICE 1 +#define GET_PC(env) env->PC + #include "config.h" #include "mips-defs.h" #include "cpu-defs.h" diff -urN qemu-0.8.2/target-ppc/cpu.h qemu-new/target-ppc/cpu.h --- qemu-0.8.2/target-ppc/cpu.h 2006-07-22 18:23:34.000000000 +0100 +++ qemu-new/target-ppc/cpu.h 2006-09-12 03:54:20.000000000 +0100 @@ -22,6 +22,8 @@ #include "config.h" +#define GET_PC(env) env->nip + #define TARGET_LONG_BITS 32 #include "cpu-defs.h" diff -urN qemu-0.8.2/target-sh4/cpu.h qemu-new/target-sh4/cpu.h --- qemu-0.8.2/target-sh4/cpu.h 2006-07-22 18:23:34.000000000 +0100 +++ qemu-new/target-sh4/cpu.h 2006-09-12 03:54:36.000000000 +0100 @@ -22,6 +22,8 @@ #include "config.h" +#define GET_PC(env) env->pc + #define TARGET_LONG_BITS 32 #define TARGET_HAS_ICE 1 diff -urN qemu-0.8.2/target-sparc/cpu.h qemu-new/target-sparc/cpu.h --- qemu-0.8.2/target-sparc/cpu.h 2006-07-22 18:23:34.000000000 +0100 +++ qemu-new/target-sparc/cpu.h 2006-09-12 03:55:05.000000000 +0100 @@ -3,6 +3,8 @@ #include "config.h" +#define GET_PC(env) env->pc + #if !defined(TARGET_SPARC64) #define TARGET_LONG_BITS 32 #define TARGET_FPREGS 32 diff -urN qemu-0.8.2/vl.c qemu-new/vl.c --- qemu-0.8.2/vl.c 2006-07-22 18:23:34.000000000 +0100 +++ qemu-new/vl.c 2006-09-11 15:23:20.000000000 +0100 @@ -4768,6 +4768,8 @@ if (ret) return ret; } + /* Forget about phys_ram_valid. */ + memset(phys_ram_valid, 0xff, phys_ram_size); return 0; } @@ -6073,10 +6075,12 @@ phys_ram_size = ram_size + vga_ram_size + bios_size; phys_ram_base = qemu_vmalloc(phys_ram_size); - if (!phys_ram_base) { + phys_ram_valid = qemu_vmalloc(phys_ram_size); + if (!phys_ram_base || !phys_ram_valid) { fprintf(stderr, "Could not allocate physical memory\n"); exit(1); } + memset(phys_ram_valid, 0, phys_ram_size); /* we always create the cdrom drive, even if no disk is there */ bdrv_init();