-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__)