void cpu_abort(CPUState *env, const char *fmt, ...)
{
va_list ap;
+ va_list ap2;
va_start(ap, fmt);
+ va_copy(ap2, ap);
fprintf(stderr, "qemu: fatal: ");
vfprintf(stderr, fmt, ap);
fprintf(stderr, "\n");
#endif
if (logfile) {
fprintf(logfile, "qemu: fatal: ");
- vfprintf(logfile, fmt, ap);
+ vfprintf(logfile, fmt, ap2);
fprintf(logfile, "\n");
#ifdef TARGET_I386
cpu_dump_state(env, logfile, fprintf, X86_DUMP_FPU | X86_DUMP_CCOP);
fflush(logfile);
fclose(logfile);
}
+ va_end(ap2);
va_end(ap);
abort();
}
CPUState *cpu_copy(CPUState *env)
{
-#if 0
- /* XXX: broken, must be handled by each CPU */
- CPUState *new_env = cpu_init();
+ CPUState *new_env = cpu_init(env->cpu_model_str);
/* preserve chaining and index */
CPUState *next_cpu = new_env->next_cpu;
int cpu_index = new_env->cpu_index;
new_env->next_cpu = next_cpu;
new_env->cpu_index = cpu_index;
return new_env;
-#else
- return NULL;
-#endif
}
#if !defined(CONFIG_USER_ONLY)
if( !(p->flags & PAGE_VALID) )
return -1;
- if (!(p->flags & PAGE_READ) && (flags & PAGE_READ) )
- return -1;
- if (!(p->flags & PAGE_WRITE) && (flags & PAGE_WRITE) )
+ if ((flags & PAGE_READ) && !(p->flags & PAGE_READ))
return -1;
+ if (flags & PAGE_WRITE) {
+ if (!(p->flags & PAGE_WRITE_ORG))
+ return -1;
+ /* unprotect the page if it was put read-only because it
+ contains translated code */
+ if (!(p->flags & PAGE_WRITE)) {
+ if (!page_unprotect(addr, 0, NULL))
+ return -1;
+ }
+ return 0;
+ }
}
return 0;
}
return 0;
}
-/* call this function when system calls directly modify a memory area */
-/* ??? This should be redundant now we have lock_user. */
-void page_unprotect_range(target_ulong data, target_ulong data_size)
-{
- target_ulong start, end, addr;
-
- start = data;
- end = start + data_size;
- start &= TARGET_PAGE_MASK;
- end = TARGET_PAGE_ALIGN(end);
- for(addr = start; addr < end; addr += TARGET_PAGE_SIZE) {
- page_unprotect(addr, 0, NULL);
- }
-}
-
static inline void tlb_set_dirty(CPUState *env,
unsigned long addr, target_ulong vaddr)
{