-rw-r--r-- 9295 saferewrite-20260206/unicorn-patch raw
diff --git a/include/unicorn/sparc.h b/include/unicorn/sparc.h index 776cd2cd..66f6b026 100644 --- a/include/unicorn/sparc.h +++ b/include/unicorn/sparc.h @@ -158,6 +158,8 @@ typedef enum uc_sparc_reg { // pseudo register UC_SPARC_REG_PC, // program counter register + UC_SPARC_REG_PSR, + UC_SPARC_REG_ENDING, // <-- mark the end of the list of registers // extras diff --git a/qemu/accel/tcg/cpu-exec.c b/qemu/accel/tcg/cpu-exec.c index 09148f1d..0642af14 100644 --- a/qemu/accel/tcg/cpu-exec.c +++ b/qemu/accel/tcg/cpu-exec.c @@ -397,6 +397,11 @@ static inline bool cpu_handle_exception(CPUState *cpu, int *ret) #if defined(TARGET_PPC) CPUPPCState *env = &(POWERPC_CPU(uc->cpu)->env); env->nip += 4; +#endif +#if defined(TARGET_SPARC) + CPUSPARCState *env = &(SPARC_CPU(uc->cpu)->env); + env->pc = env->npc; + env->npc += 4; #endif // Unicorn: call registered interrupt callbacks catched = false; diff --git a/qemu/accel/tcg/translate-all.c b/qemu/accel/tcg/translate-all.c index 3f6d2630..33a4dbb4 100644 --- a/qemu/accel/tcg/translate-all.c +++ b/qemu/accel/tcg/translate-all.c @@ -741,7 +741,7 @@ static void page_lock_pair(struct uc_struct *uc, PageDesc **ret_p1, tb_page_addr /* Minimum size of the code gen buffer. This number is randomly chosen, but not so small that we can't have a fair number of TB's live. */ -#define MIN_CODE_GEN_BUFFER_SIZE (1 * MiB) +#define MIN_CODE_GEN_BUFFER_SIZE (32 * KiB) /* Maximum size of the code gen buffer we'd like to use. Unless otherwise indicated, this is constrained by the range of direct branches on the @@ -768,14 +768,14 @@ static void page_lock_pair(struct uc_struct *uc, PageDesc **ret_p1, tb_page_addr #endif #if TCG_TARGET_REG_BITS == 32 -#define DEFAULT_CODE_GEN_BUFFER_SIZE_1 (32 * MiB) +#define DEFAULT_CODE_GEN_BUFFER_SIZE_1 (32 * KiB) #else /* TCG_TARGET_REG_BITS == 64 */ /* * We expect most system emulation to run one or two guests per host. * Users running large scale system emulation may want to tweak their * runtime setup via the tb-size control on the command line. */ -#define DEFAULT_CODE_GEN_BUFFER_SIZE_1 (1 * GiB) +#define DEFAULT_CODE_GEN_BUFFER_SIZE_1 (32 * KiB) #endif #define DEFAULT_CODE_GEN_BUFFER_SIZE \ @@ -999,6 +999,7 @@ static inline void *alloc_code_gen_buffer(struct uc_struct *uc) } void free_code_gen_buffer(struct uc_struct *uc) { + if (getenv("SKIPMMAP")) return; TCGContext *tcg_ctx = uc->tcg_ctx; if (tcg_ctx->initial_buffer) { may_remove_handler(uc); @@ -1008,6 +1009,7 @@ void free_code_gen_buffer(struct uc_struct *uc) #else void free_code_gen_buffer(struct uc_struct *uc) { + if (getenv("SKIPMMAP")) return; TCGContext *tcg_ctx = uc->tcg_ctx; if (tcg_ctx->initial_buffer) { if (munmap(tcg_ctx->initial_buffer, tcg_ctx->initial_buffer_size)) { @@ -1022,6 +1024,7 @@ static inline void *alloc_code_gen_buffer(struct uc_struct *uc) int prot = PROT_WRITE | PROT_READ | PROT_EXEC; int flags = MAP_PRIVATE | MAP_ANONYMOUS; size_t size = tcg_ctx->code_gen_buffer_size; + if (getenv("SKIPMMAP")) return qemu_memalign(8192,size); void *buf; #ifdef USE_MAP_JIT flags |= MAP_JIT; diff --git a/qemu/include/exec/tb-context.h b/qemu/include/exec/tb-context.h index 834747d1..cd3cff06 100644 --- a/qemu/include/exec/tb-context.h +++ b/qemu/include/exec/tb-context.h @@ -23,7 +23,7 @@ #include "qemu/thread.h" #include "qemu/qht.h" -#define CODE_GEN_HTABLE_BITS 15 +#define CODE_GEN_HTABLE_BITS 10 #define CODE_GEN_HTABLE_SIZE (1 << CODE_GEN_HTABLE_BITS) typedef struct TranslationBlock TranslationBlock; diff --git a/qemu/target/arm/helper.c b/qemu/target/arm/helper.c index 60c9db9e..e7ef0795 100644 --- a/qemu/target/arm/helper.c +++ b/qemu/target/arm/helper.c @@ -6107,10 +6107,10 @@ static void define_pmu_regs(ARMCPU *cpu) define_one_arm_cp_reg(cpu, &pmcr); define_one_arm_cp_reg(cpu, &pmcr64); for (i = 0; i < pmcrn; i++) { - char *pmevcntr_name = g_strdup_printf("PMEVCNTR%d", i); - char *pmevcntr_el0_name = g_strdup_printf("PMEVCNTR%d_EL0", i); - char *pmevtyper_name = g_strdup_printf("PMEVTYPER%d", i); - char *pmevtyper_el0_name = g_strdup_printf("PMEVTYPER%d_EL0", i); + const char *pmevcntr_name = ("PMEVCNTR"); + const char *pmevcntr_el0_name = ("PMEVCNTR_EL0"); + const char *pmevtyper_name = ("PMEVTYPER"); + const char *pmevtyper_el0_name = ("PMEVTYPER_EL0"); ARMCPRegInfo pmev_regs[] = { { .name = pmevcntr_name, .cp = 15, .crn = 14, .crm = 8 | (3 & (i >> 3)), .opc1 = 0, .opc2 = i & 7, @@ -6138,10 +6138,6 @@ static void define_pmu_regs(ARMCPU *cpu) REGINFO_SENTINEL }; define_arm_cp_regs(cpu, pmev_regs); - g_free(pmevcntr_name); - g_free(pmevcntr_el0_name); - g_free(pmevtyper_name); - g_free(pmevtyper_el0_name); } if (cpu_isar_feature(aa32_pmu_8_1, cpu)) { ARMCPRegInfo v81_pmu_regs[] = { @@ -7733,8 +7729,6 @@ void define_one_arm_cp_reg_with_opaque(ARMCPU *cpu, /* Under AArch32 CP registers can be common * (same for secure and non-secure world) or banked. */ - char *name; - switch (r->secure) { case ARM_CP_SECSTATE_S: case ARM_CP_SECSTATE_NS: @@ -7743,11 +7737,6 @@ void define_one_arm_cp_reg_with_opaque(ARMCPU *cpu, r->name); break; default: - name = g_strdup_printf("%s_S", r->name); - add_cpreg_to_hashtable(cpu, r, opaque, state, - ARM_CP_SECSTATE_S, - crm, opc1, opc2, name); - g_free(name); add_cpreg_to_hashtable(cpu, r, opaque, state, ARM_CP_SECSTATE_NS, crm, opc1, opc2, r->name); diff --git a/qemu/target/sparc/cpu.c b/qemu/target/sparc/cpu.c index e0e1962d..de7ff76f 100644 --- a/qemu/target/sparc/cpu.c +++ b/qemu/target/sparc/cpu.c @@ -36,6 +36,12 @@ static void sparc_cpu_reset(CPUState *dev) env->wim = 1; #endif env->regwptr = env->regbase + (env->cwp * 16); +#ifdef TARGET_SPARC64 + env->cleanwin = env->nwindows - 2; + env->cansave = env->nwindows - 2; + env->pstate = PS_RMO | PS_PEF | PS_IE; + env->asi = 0x82; /* Primary no-fault */ +#endif CC_OP = CC_OP_FLAGS; #if !defined(TARGET_SPARC64) env->psret = 0; @@ -555,6 +561,7 @@ SPARCCPU *cpu_sparc_init(struct uc_struct *uc) /* realize SPARCCPU */ sparc_cpu_realizefn(uc, cs); /* realize CPUState */ + sparc_cpu_reset(cs); // init address space cpu_address_space_init(cs, 0, cs->memory); diff --git a/qemu/target/sparc/unicorn.c b/qemu/target/sparc/unicorn.c index 33ed8def..a02beba4 100644 --- a/qemu/target/sparc/unicorn.c +++ b/qemu/target/sparc/unicorn.c @@ -80,6 +80,10 @@ uc_err reg_read(void *_env, int mode, unsigned int regid, void *value, } else if (regid >= UC_SPARC_REG_I0 && regid <= UC_SPARC_REG_I7) { CHECK_REG_TYPE(uint32_t); *(uint32_t *)value = env->regwptr[16 + regid - UC_SPARC_REG_I0]; + } else if (regid == UC_SPARC_REG_PSR) { + CHECK_REG_TYPE(uint32_t); + if (env->cc_op != CC_OP_FLAGS) cpu_get_psr(env); + *(uint32_t *)value = env->psr; } else { switch (regid) { default: @@ -114,6 +118,10 @@ uc_err reg_write(void *_env, int mode, unsigned int regid, const void *value, } else if (regid >= UC_SPARC_REG_I0 && regid <= UC_SPARC_REG_I7) { CHECK_REG_TYPE(uint32_t); env->regwptr[16 + regid - UC_SPARC_REG_I0] = *(uint32_t *)value; + } else if (regid == UC_SPARC_REG_PSR) { + CHECK_REG_TYPE(uint32_t); + env->psr = *(uint32_t *)value; + env->cc_op = CC_OP_FLAGS; } else { switch (regid) { default: diff --git a/qemu/util/oslib-posix.c b/qemu/util/oslib-posix.c index 615e477e..f3fadfa3 100644 --- a/qemu/util/oslib-posix.c +++ b/qemu/util/oslib-posix.c @@ -137,6 +137,7 @@ void *qemu_anon_ram_alloc(struct uc_struct *uc, size_t size, uint64_t *alignment void qemu_vfree(void *ptr) { + if (getenv("SKIPMMAP")) return; #ifdef __MINGW32__ if (ptr) { __mingw_aligned_free(ptr); @@ -188,6 +189,8 @@ static void *qemu_ram_mmap(struct uc_struct *uc, void *guardptr; void *ptr; + if (getenv("SKIPMMAP")) return malloc(size); + /* * Note: this always allocates at least one extra page of virtual address * space, even if size is already aligned. @@ -271,6 +274,8 @@ static void qemu_ram_munmap(struct uc_struct *uc, void *ptr, size_t size) { size_t pagesize; + if (getenv("SKIPMMAP")) return; + if (ptr) { /* Unmap both the RAM block and the guard page */ #if defined(__powerpc64__) && defined(__linux__)