Merge branch 'dev' into s390x
This commit is contained in:
commit
71f044ca50
@ -35,13 +35,14 @@ module Arm =
|
||||
let UC_CPU_ARM_PXA260 = 23
|
||||
let UC_CPU_ARM_PXA261 = 24
|
||||
let UC_CPU_ARM_PXA262 = 25
|
||||
let UC_CPU_ARM_PXA270A0 = 26
|
||||
let UC_CPU_ARM_PXA270A1 = 27
|
||||
let UC_CPU_ARM_PXA270B0 = 28
|
||||
let UC_CPU_ARM_PXA270B1 = 29
|
||||
let UC_CPU_ARM_PXA270C0 = 30
|
||||
let UC_CPU_ARM_PXA270C5 = 31
|
||||
let UC_CPU_ARM_MAX = 32
|
||||
let UC_CPU_ARM_PXA270 = 26
|
||||
let UC_CPU_ARM_PXA270A0 = 27
|
||||
let UC_CPU_ARM_PXA270A1 = 28
|
||||
let UC_CPU_ARM_PXA270B0 = 29
|
||||
let UC_CPU_ARM_PXA270B1 = 30
|
||||
let UC_CPU_ARM_PXA270C0 = 31
|
||||
let UC_CPU_ARM_PXA270C5 = 32
|
||||
let UC_CPU_ARM_MAX = 33
|
||||
|
||||
// ARM registers
|
||||
|
||||
|
@ -284,7 +284,12 @@ module X86 =
|
||||
let UC_X86_REG_GS_BASE = 231
|
||||
let UC_X86_REG_FLAGS = 232
|
||||
let UC_X86_REG_RFLAGS = 233
|
||||
let UC_X86_REG_ENDING = 234
|
||||
let UC_X86_REG_FIP = 234
|
||||
let UC_X86_REG_FCS = 235
|
||||
let UC_X86_REG_FDP = 236
|
||||
let UC_X86_REG_FDS = 237
|
||||
let UC_X86_REG_FOP = 238
|
||||
let UC_X86_REG_ENDING = 239
|
||||
|
||||
// X86 instructions
|
||||
|
||||
|
@ -30,13 +30,14 @@ const (
|
||||
CPU_ARM_PXA260 = 23
|
||||
CPU_ARM_PXA261 = 24
|
||||
CPU_ARM_PXA262 = 25
|
||||
CPU_ARM_PXA270A0 = 26
|
||||
CPU_ARM_PXA270A1 = 27
|
||||
CPU_ARM_PXA270B0 = 28
|
||||
CPU_ARM_PXA270B1 = 29
|
||||
CPU_ARM_PXA270C0 = 30
|
||||
CPU_ARM_PXA270C5 = 31
|
||||
CPU_ARM_MAX = 32
|
||||
CPU_ARM_PXA270 = 26
|
||||
CPU_ARM_PXA270A0 = 27
|
||||
CPU_ARM_PXA270A1 = 28
|
||||
CPU_ARM_PXA270B0 = 29
|
||||
CPU_ARM_PXA270B1 = 30
|
||||
CPU_ARM_PXA270C0 = 31
|
||||
CPU_ARM_PXA270C5 = 32
|
||||
CPU_ARM_MAX = 33
|
||||
|
||||
// ARM registers
|
||||
|
||||
|
@ -279,7 +279,12 @@ const (
|
||||
X86_REG_GS_BASE = 231
|
||||
X86_REG_FLAGS = 232
|
||||
X86_REG_RFLAGS = 233
|
||||
X86_REG_ENDING = 234
|
||||
X86_REG_FIP = 234
|
||||
X86_REG_FCS = 235
|
||||
X86_REG_FDP = 236
|
||||
X86_REG_FDS = 237
|
||||
X86_REG_FOP = 238
|
||||
X86_REG_ENDING = 239
|
||||
|
||||
// X86 instructions
|
||||
|
||||
|
@ -32,13 +32,14 @@ public interface ArmConst {
|
||||
public static final int UC_CPU_ARM_PXA260 = 23;
|
||||
public static final int UC_CPU_ARM_PXA261 = 24;
|
||||
public static final int UC_CPU_ARM_PXA262 = 25;
|
||||
public static final int UC_CPU_ARM_PXA270A0 = 26;
|
||||
public static final int UC_CPU_ARM_PXA270A1 = 27;
|
||||
public static final int UC_CPU_ARM_PXA270B0 = 28;
|
||||
public static final int UC_CPU_ARM_PXA270B1 = 29;
|
||||
public static final int UC_CPU_ARM_PXA270C0 = 30;
|
||||
public static final int UC_CPU_ARM_PXA270C5 = 31;
|
||||
public static final int UC_CPU_ARM_MAX = 32;
|
||||
public static final int UC_CPU_ARM_PXA270 = 26;
|
||||
public static final int UC_CPU_ARM_PXA270A0 = 27;
|
||||
public static final int UC_CPU_ARM_PXA270A1 = 28;
|
||||
public static final int UC_CPU_ARM_PXA270B0 = 29;
|
||||
public static final int UC_CPU_ARM_PXA270B1 = 30;
|
||||
public static final int UC_CPU_ARM_PXA270C0 = 31;
|
||||
public static final int UC_CPU_ARM_PXA270C5 = 32;
|
||||
public static final int UC_CPU_ARM_MAX = 33;
|
||||
|
||||
// ARM registers
|
||||
|
||||
|
@ -281,7 +281,12 @@ public interface X86Const {
|
||||
public static final int UC_X86_REG_GS_BASE = 231;
|
||||
public static final int UC_X86_REG_FLAGS = 232;
|
||||
public static final int UC_X86_REG_RFLAGS = 233;
|
||||
public static final int UC_X86_REG_ENDING = 234;
|
||||
public static final int UC_X86_REG_FIP = 234;
|
||||
public static final int UC_X86_REG_FCS = 235;
|
||||
public static final int UC_X86_REG_FDP = 236;
|
||||
public static final int UC_X86_REG_FDS = 237;
|
||||
public static final int UC_X86_REG_FOP = 238;
|
||||
public static final int UC_X86_REG_ENDING = 239;
|
||||
|
||||
// X86 instructions
|
||||
|
||||
|
@ -33,13 +33,14 @@ const
|
||||
UC_CPU_ARM_PXA260 = 23;
|
||||
UC_CPU_ARM_PXA261 = 24;
|
||||
UC_CPU_ARM_PXA262 = 25;
|
||||
UC_CPU_ARM_PXA270A0 = 26;
|
||||
UC_CPU_ARM_PXA270A1 = 27;
|
||||
UC_CPU_ARM_PXA270B0 = 28;
|
||||
UC_CPU_ARM_PXA270B1 = 29;
|
||||
UC_CPU_ARM_PXA270C0 = 30;
|
||||
UC_CPU_ARM_PXA270C5 = 31;
|
||||
UC_CPU_ARM_MAX = 32;
|
||||
UC_CPU_ARM_PXA270 = 26;
|
||||
UC_CPU_ARM_PXA270A0 = 27;
|
||||
UC_CPU_ARM_PXA270A1 = 28;
|
||||
UC_CPU_ARM_PXA270B0 = 29;
|
||||
UC_CPU_ARM_PXA270B1 = 30;
|
||||
UC_CPU_ARM_PXA270C0 = 31;
|
||||
UC_CPU_ARM_PXA270C5 = 32;
|
||||
UC_CPU_ARM_MAX = 33;
|
||||
|
||||
// ARM registers
|
||||
|
||||
|
@ -282,7 +282,12 @@ const
|
||||
UC_X86_REG_GS_BASE = 231;
|
||||
UC_X86_REG_FLAGS = 232;
|
||||
UC_X86_REG_RFLAGS = 233;
|
||||
UC_X86_REG_ENDING = 234;
|
||||
UC_X86_REG_FIP = 234;
|
||||
UC_X86_REG_FCS = 235;
|
||||
UC_X86_REG_FDP = 236;
|
||||
UC_X86_REG_FDS = 237;
|
||||
UC_X86_REG_FOP = 238;
|
||||
UC_X86_REG_ENDING = 239;
|
||||
|
||||
// X86 instructions
|
||||
|
||||
|
@ -28,13 +28,14 @@ UC_CPU_ARM_PXA255 = 22
|
||||
UC_CPU_ARM_PXA260 = 23
|
||||
UC_CPU_ARM_PXA261 = 24
|
||||
UC_CPU_ARM_PXA262 = 25
|
||||
UC_CPU_ARM_PXA270A0 = 26
|
||||
UC_CPU_ARM_PXA270A1 = 27
|
||||
UC_CPU_ARM_PXA270B0 = 28
|
||||
UC_CPU_ARM_PXA270B1 = 29
|
||||
UC_CPU_ARM_PXA270C0 = 30
|
||||
UC_CPU_ARM_PXA270C5 = 31
|
||||
UC_CPU_ARM_MAX = 32
|
||||
UC_CPU_ARM_PXA270 = 26
|
||||
UC_CPU_ARM_PXA270A0 = 27
|
||||
UC_CPU_ARM_PXA270A1 = 28
|
||||
UC_CPU_ARM_PXA270B0 = 29
|
||||
UC_CPU_ARM_PXA270B1 = 30
|
||||
UC_CPU_ARM_PXA270C0 = 31
|
||||
UC_CPU_ARM_PXA270C5 = 32
|
||||
UC_CPU_ARM_MAX = 33
|
||||
|
||||
# ARM registers
|
||||
|
||||
|
@ -277,7 +277,12 @@ UC_X86_REG_FS_BASE = 230
|
||||
UC_X86_REG_GS_BASE = 231
|
||||
UC_X86_REG_FLAGS = 232
|
||||
UC_X86_REG_RFLAGS = 233
|
||||
UC_X86_REG_ENDING = 234
|
||||
UC_X86_REG_FIP = 234
|
||||
UC_X86_REG_FCS = 235
|
||||
UC_X86_REG_FDP = 236
|
||||
UC_X86_REG_FDS = 237
|
||||
UC_X86_REG_FOP = 238
|
||||
UC_X86_REG_ENDING = 239
|
||||
|
||||
# X86 instructions
|
||||
|
||||
|
@ -30,13 +30,14 @@ module UnicornEngine
|
||||
UC_CPU_ARM_PXA260 = 23
|
||||
UC_CPU_ARM_PXA261 = 24
|
||||
UC_CPU_ARM_PXA262 = 25
|
||||
UC_CPU_ARM_PXA270A0 = 26
|
||||
UC_CPU_ARM_PXA270A1 = 27
|
||||
UC_CPU_ARM_PXA270B0 = 28
|
||||
UC_CPU_ARM_PXA270B1 = 29
|
||||
UC_CPU_ARM_PXA270C0 = 30
|
||||
UC_CPU_ARM_PXA270C5 = 31
|
||||
UC_CPU_ARM_MAX = 32
|
||||
UC_CPU_ARM_PXA270 = 26
|
||||
UC_CPU_ARM_PXA270A0 = 27
|
||||
UC_CPU_ARM_PXA270A1 = 28
|
||||
UC_CPU_ARM_PXA270B0 = 29
|
||||
UC_CPU_ARM_PXA270B1 = 30
|
||||
UC_CPU_ARM_PXA270C0 = 31
|
||||
UC_CPU_ARM_PXA270C5 = 32
|
||||
UC_CPU_ARM_MAX = 33
|
||||
|
||||
# ARM registers
|
||||
|
||||
|
@ -279,7 +279,12 @@ module UnicornEngine
|
||||
UC_X86_REG_GS_BASE = 231
|
||||
UC_X86_REG_FLAGS = 232
|
||||
UC_X86_REG_RFLAGS = 233
|
||||
UC_X86_REG_ENDING = 234
|
||||
UC_X86_REG_FIP = 234
|
||||
UC_X86_REG_FCS = 235
|
||||
UC_X86_REG_FDP = 236
|
||||
UC_X86_REG_FDS = 237
|
||||
UC_X86_REG_FOP = 238
|
||||
UC_X86_REG_ENDING = 239
|
||||
|
||||
# X86 instructions
|
||||
|
||||
|
@ -43,6 +43,7 @@ typedef enum uc_cpu_arm {
|
||||
UC_CPU_ARM_PXA260,
|
||||
UC_CPU_ARM_PXA261,
|
||||
UC_CPU_ARM_PXA262,
|
||||
UC_CPU_ARM_PXA270,
|
||||
UC_CPU_ARM_PXA270A0,
|
||||
UC_CPU_ARM_PXA270A1,
|
||||
UC_CPU_ARM_PXA270B0,
|
||||
|
@ -370,6 +370,54 @@ typedef enum uc_ppc_reg {
|
||||
UC_PPC_REG_29,
|
||||
UC_PPC_REG_30,
|
||||
UC_PPC_REG_31,
|
||||
|
||||
UC_PPC_REG_CR0,
|
||||
UC_PPC_REG_CR1,
|
||||
UC_PPC_REG_CR2,
|
||||
UC_PPC_REG_CR3,
|
||||
UC_PPC_REG_CR4,
|
||||
UC_PPC_REG_CR5,
|
||||
UC_PPC_REG_CR6,
|
||||
UC_PPC_REG_CR7,
|
||||
|
||||
UC_PPC_REG_FPR0,
|
||||
UC_PPC_REG_FPR1,
|
||||
UC_PPC_REG_FPR2,
|
||||
UC_PPC_REG_FPR3,
|
||||
UC_PPC_REG_FPR4,
|
||||
UC_PPC_REG_FPR5,
|
||||
UC_PPC_REG_FPR6,
|
||||
UC_PPC_REG_FPR7,
|
||||
UC_PPC_REG_FPR8,
|
||||
UC_PPC_REG_FPR9,
|
||||
UC_PPC_REG_FPR10,
|
||||
UC_PPC_REG_FPR11,
|
||||
UC_PPC_REG_FPR12,
|
||||
UC_PPC_REG_FPR13,
|
||||
UC_PPC_REG_FPR14,
|
||||
UC_PPC_REG_FPR15,
|
||||
UC_PPC_REG_FPR16,
|
||||
UC_PPC_REG_FPR17,
|
||||
UC_PPC_REG_FPR18,
|
||||
UC_PPC_REG_FPR19,
|
||||
UC_PPC_REG_FPR20,
|
||||
UC_PPC_REG_FPR21,
|
||||
UC_PPC_REG_FPR22,
|
||||
UC_PPC_REG_FPR23,
|
||||
UC_PPC_REG_FPR24,
|
||||
UC_PPC_REG_FPR25,
|
||||
UC_PPC_REG_FPR26,
|
||||
UC_PPC_REG_FPR27,
|
||||
UC_PPC_REG_FPR28,
|
||||
UC_PPC_REG_FPR29,
|
||||
UC_PPC_REG_FPR30,
|
||||
UC_PPC_REG_FPR31,
|
||||
|
||||
UC_PPC_REG_LR,
|
||||
UC_PPC_REG_XER,
|
||||
UC_PPC_REG_CTR,
|
||||
UC_PPC_REG_MSR,
|
||||
UC_PPC_REG_FPSCR
|
||||
} uc_ppc_reg;
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
@ -319,6 +319,11 @@ typedef enum uc_x86_reg {
|
||||
UC_X86_REG_GS_BASE,
|
||||
UC_X86_REG_FLAGS,
|
||||
UC_X86_REG_RFLAGS,
|
||||
UC_X86_REG_FIP,
|
||||
UC_X86_REG_FCS,
|
||||
UC_X86_REG_FDP,
|
||||
UC_X86_REG_FDS,
|
||||
UC_X86_REG_FOP,
|
||||
UC_X86_REG_ENDING // <-- mark the end of the list of registers
|
||||
} uc_x86_reg;
|
||||
|
||||
|
@ -985,11 +985,22 @@ static void uc_invalidate_tb(struct uc_struct *uc, uint64_t start_addr, size_t l
|
||||
{
|
||||
tb_page_addr_t start, end;
|
||||
|
||||
// GVA to GPA
|
||||
uc->nested_level++;
|
||||
if (sigsetjmp(uc->jmp_bufs[uc->nested_level - 1], 0) != 0) {
|
||||
// We a get cpu fault in get_page_addr_code, ignore it.
|
||||
uc->nested_level--;
|
||||
return;
|
||||
}
|
||||
|
||||
// GPA to GVA
|
||||
// start_addr : GPA
|
||||
// addr: GVA
|
||||
// (GPA -> HVA via memory_region_get_ram_addr(mr) + GPA + block->host,
|
||||
// HVA->HPA via host mmu)
|
||||
start = get_page_addr_code(uc->cpu->env_ptr, start_addr) & (target_ulong)(-1);
|
||||
|
||||
uc->nested_level--;
|
||||
|
||||
// For 32bit target.
|
||||
end = (start + len) & (target_ulong)(-1);
|
||||
|
||||
|
@ -184,13 +184,6 @@ static void arm_cpu_reset(CPUState *dev)
|
||||
} else {
|
||||
env->pstate = PSTATE_MODE_EL1h;
|
||||
}
|
||||
/*
|
||||
* Unicorn: Hack to force to enable EL2/EL3 for aarch64 so that we can
|
||||
* use the full 64bits virtual address space.
|
||||
*
|
||||
* See cpu_aarch64_init for details.
|
||||
*/
|
||||
env->pstate = PSTATE_MODE_EL1h;
|
||||
env->pc = cpu->rvbar;
|
||||
}
|
||||
|
||||
@ -705,6 +698,17 @@ void arm_cpu_post_init(CPUState *obj)
|
||||
cpu->rvbar = 0;
|
||||
}
|
||||
|
||||
if (arm_feature(&cpu->env, ARM_FEATURE_EL3)) {
|
||||
/* Add the has_el3 state CPU property only if EL3 is allowed. This will
|
||||
* prevent "has_el3" from existing on CPUs which cannot support EL3.
|
||||
*/
|
||||
cpu->has_el3 = true;
|
||||
}
|
||||
|
||||
if (arm_feature(&cpu->env, ARM_FEATURE_EL2)) {
|
||||
cpu->has_el2 = true;
|
||||
}
|
||||
|
||||
if (arm_feature(&cpu->env, ARM_FEATURE_PMU)) {
|
||||
cpu->has_pmu = true;
|
||||
}
|
||||
@ -1954,6 +1958,54 @@ static void arm_max_initfn(struct uc_struct *uc, CPUState *obj)
|
||||
|
||||
/* old-style VFP short-vector support */
|
||||
FIELD_DP32(cpu->isar.mvfr0, MVFR0, FPSHVEC, 1, cpu->isar.mvfr0);
|
||||
|
||||
// Unicorn: Enable this on ARM_MAX
|
||||
//#ifdef CONFIG_USER_ONLY
|
||||
/* We don't set these in system emulation mode for the moment,
|
||||
* since we don't correctly set (all of) the ID registers to
|
||||
* advertise them.
|
||||
*/
|
||||
set_feature(&cpu->env, ARM_FEATURE_V8);
|
||||
{
|
||||
uint32_t t;
|
||||
|
||||
t = cpu->isar.id_isar5;
|
||||
FIELD_DP32(t, ID_ISAR5, AES, 2, t);
|
||||
FIELD_DP32(t, ID_ISAR5, SHA1, 1, t);
|
||||
FIELD_DP32(t, ID_ISAR5, SHA2, 1, t);
|
||||
FIELD_DP32(t, ID_ISAR5, CRC32, 1, t);
|
||||
FIELD_DP32(t, ID_ISAR5, RDM, 1, t);
|
||||
FIELD_DP32(t, ID_ISAR5, VCMA, 1, t);
|
||||
cpu->isar.id_isar5 = t;
|
||||
|
||||
t = cpu->isar.id_isar6;
|
||||
FIELD_DP32(t, ID_ISAR6, JSCVT, 1, t);
|
||||
FIELD_DP32(t, ID_ISAR6, DP, 1, t);
|
||||
FIELD_DP32(t, ID_ISAR6, FHM, 1, t);
|
||||
FIELD_DP32(t, ID_ISAR6, SB, 1, t);
|
||||
FIELD_DP32(t, ID_ISAR6, SPECRES, 1, t);
|
||||
cpu->isar.id_isar6 = t;
|
||||
|
||||
t = cpu->isar.mvfr1;
|
||||
FIELD_DP32(t, MVFR1, FPHP, 2, t); /* v8.0 FP support */
|
||||
cpu->isar.mvfr1 = t;
|
||||
|
||||
t = cpu->isar.mvfr2;
|
||||
FIELD_DP32(t, MVFR2, SIMDMISC, 3, t); /* SIMD MaxNum */
|
||||
FIELD_DP32(t, MVFR2, FPMISC, 4, t); /* FP MaxNum */
|
||||
cpu->isar.mvfr2 = t;
|
||||
|
||||
t = cpu->isar.id_mmfr3;
|
||||
FIELD_DP32(t, ID_MMFR3, PAN, 2, t); /* ATS1E1 */
|
||||
cpu->isar.id_mmfr3 = t;
|
||||
|
||||
t = cpu->isar.id_mmfr4;
|
||||
FIELD_DP32(t, ID_MMFR4, HPDS, 1, t); /* AA32HPD */
|
||||
FIELD_DP32(t, ID_MMFR4, AC2, 1, t); /* ACTLR2, HACTLR2 */
|
||||
FIELD_DP32(t, ID_MMFR4, CNP, 1, t); /* TTCNP */
|
||||
cpu->isar.id_mmfr4 = t;
|
||||
}
|
||||
//#endif
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@ -2056,15 +2108,15 @@ ARMCPU *cpu_arm_init(struct uc_struct *uc)
|
||||
|
||||
#if !defined(TARGET_AARCH64)
|
||||
if (uc->mode & UC_MODE_MCLASS) {
|
||||
uc->cpu_model = 11;
|
||||
uc->cpu_model = UC_CPU_ARM_CORTEX_M33;
|
||||
} else if (uc->mode & UC_MODE_ARM926) {
|
||||
uc->cpu_model = 0;
|
||||
uc->cpu_model = UC_CPU_ARM_926;
|
||||
} else if (uc->mode & UC_MODE_ARM946) {
|
||||
uc->cpu_model = 1;
|
||||
uc->cpu_model = UC_CPU_ARM_946;
|
||||
} else if (uc->mode & UC_MODE_ARM1176) {
|
||||
uc->cpu_model = 5;
|
||||
uc->cpu_model = UC_CPU_ARM_1176;
|
||||
} else if (uc->cpu_model == INT_MAX) {
|
||||
uc->cpu_model = 17; // cortex-a15
|
||||
uc->cpu_model = UC_CPU_ARM_CORTEX_A15; // cortex-a15
|
||||
} else if (uc->cpu_model >= ARR_SIZE(arm_cpus)) {
|
||||
free(cpu);
|
||||
return NULL;
|
||||
|
@ -1264,6 +1264,7 @@ typedef enum CPSRWriteType {
|
||||
CPSRWriteExceptionReturn = 1, /* from guest exception return insn */
|
||||
CPSRWriteRaw = 2, /* trust values, do not switch reg banks */
|
||||
CPSRWriteByGDBStub = 3, /* from the GDB stub */
|
||||
CPSRWriteByUnicorn = 4 /* from uc_reg_write */
|
||||
} CPSRWriteType;
|
||||
|
||||
/* Set the CPSR. Note that some bits of mask must be all-set or all-clear.*/
|
||||
|
@ -320,8 +320,6 @@ static const ARMCPUInfo aarch64_cpus[] = {
|
||||
|
||||
ARMCPU *cpu_aarch64_init(struct uc_struct *uc)
|
||||
{
|
||||
int i;
|
||||
char *cpu_model = "cortex-a72";
|
||||
ARMCPU *cpu;
|
||||
CPUState *cs;
|
||||
CPUClass *cc;
|
||||
@ -331,6 +329,13 @@ ARMCPU *cpu_aarch64_init(struct uc_struct *uc)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (uc->cpu_model == INT_MAX) {
|
||||
uc->cpu_model = UC_CPU_AARCH64_A72;
|
||||
} else if (uc->cpu_model >= sizeof(aarch64_cpus)) {
|
||||
free(cpu);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
cs = (CPUState *)cpu;
|
||||
cc = (CPUClass *)&cpu->cc;
|
||||
cs->cc = cc;
|
||||
@ -349,33 +354,13 @@ ARMCPU *cpu_aarch64_init(struct uc_struct *uc)
|
||||
/* init ARMCPU */
|
||||
arm_cpu_initfn(uc, cs);
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(aarch64_cpus); i++) {
|
||||
if (strcmp(cpu_model, aarch64_cpus[i].name) == 0) {
|
||||
if (aarch64_cpus[i].initfn) {
|
||||
aarch64_cpus[i].initfn(uc, cs);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (i == ARRAY_SIZE(aarch64_cpus)) {
|
||||
free(cpu);
|
||||
return NULL;
|
||||
if (aarch64_cpus[uc->cpu_model].initfn) {
|
||||
aarch64_cpus[uc->cpu_model].initfn(uc, cs);
|
||||
}
|
||||
|
||||
/* postinit ARMCPU */
|
||||
arm_cpu_post_init(cs);
|
||||
|
||||
/*
|
||||
* Unicorn: Hack to force to enable EL2/EL3 for aarch64 so that we can
|
||||
* use the full 64bits virtual address space.
|
||||
*
|
||||
* While EL2/EL3 is enabled but running within EL1, we could
|
||||
* get somewhat like "x86 flat mode", though aarch64 only allows
|
||||
* a maximum of 52bits virtual address space.
|
||||
*/
|
||||
ARM_CPU(cs)->has_el2 = true;
|
||||
ARM_CPU(cs)->has_el3 = true;
|
||||
|
||||
/* realize ARMCPU */
|
||||
arm_cpu_realizefn(uc, cs);
|
||||
|
||||
|
@ -7983,9 +7983,12 @@ void cpsr_write(CPUARMState *env, uint32_t val, uint32_t mask,
|
||||
* to switch mode. (Those are caught by translate.c for writes
|
||||
* triggered by guest instructions.)
|
||||
*/
|
||||
// mask &= ~CPSR_M;
|
||||
// Unicorn: No, it can also be uc_reg_write
|
||||
switch_mode(env, val & CPSR_M);
|
||||
// Unicorn: No, it can also be uc_reg_write, let user switch registers banks.
|
||||
if (write_type == CPSRWriteByUnicorn) {
|
||||
switch_mode(env, val & CPSR_M);
|
||||
} else {
|
||||
mask &= ~CPSR_M;
|
||||
}
|
||||
} else if (bad_mode_switch(env, val & CPSR_M, write_type)) {
|
||||
/* Attempt to switch to an invalid mode: this is UNPREDICTABLE in
|
||||
* v7, and has defined behaviour in v8:
|
||||
|
@ -251,17 +251,17 @@ static void reg_write(CPUARMState *env, unsigned int regid, const void *value)
|
||||
case UC_ARM_REG_APSR:
|
||||
if (!arm_feature(env, ARM_FEATURE_M)) {
|
||||
cpsr_write(env, *(uint32_t *)value,
|
||||
(CPSR_NZCV | CPSR_Q | CPSR_GE), CPSRWriteByInstr);
|
||||
(CPSR_NZCV | CPSR_Q | CPSR_GE), CPSRWriteByUnicorn);
|
||||
} else {
|
||||
// Same with UC_ARM_REG_APSR_NZCVQ
|
||||
v7m_msr_xpsr(env, 0b1000, 0, *(uint32_t *)value);
|
||||
}
|
||||
break;
|
||||
case UC_ARM_REG_APSR_NZCV:
|
||||
cpsr_write(env, *(uint32_t *)value, CPSR_NZCV, CPSRWriteByInstr);
|
||||
cpsr_write(env, *(uint32_t *)value, CPSR_NZCV, CPSRWriteByUnicorn);
|
||||
break;
|
||||
case UC_ARM_REG_CPSR:
|
||||
cpsr_write(env, *(uint32_t *)value, ~0, CPSRWriteByInstr);
|
||||
cpsr_write(env, *(uint32_t *)value, ~0, CPSRWriteByUnicorn);
|
||||
break;
|
||||
case UC_ARM_REG_SPSR:
|
||||
env->spsr = *(uint32_t *)value;
|
||||
|
@ -5083,9 +5083,9 @@ X86CPU *cpu_x86_init(struct uc_struct *uc)
|
||||
|
||||
if (uc->cpu_model == INT_MAX) {
|
||||
#ifdef TARGET_X86_64
|
||||
uc->cpu_model = 0; // qemu64
|
||||
uc->cpu_model = UC_CPU_X86_QEMU64; // qemu64
|
||||
#else
|
||||
uc->cpu_model = 4; // qemu32
|
||||
uc->cpu_model = UC_CPU_X86_QEMU32; // qemu32
|
||||
#endif
|
||||
} else if (uc->cpu_model >= ARRAY_SIZE(builtin_x86_defs)) {
|
||||
free(cpu);
|
||||
|
@ -321,6 +321,22 @@ static void reg_read(CPUX86State *env, unsigned int regid, void *value,
|
||||
dst[3] = hi_reg->_d[1];
|
||||
return;
|
||||
}
|
||||
|
||||
case UC_X86_REG_FIP:
|
||||
*(uint64_t *)value = env->fpip;
|
||||
return;
|
||||
case UC_X86_REG_FCS:
|
||||
*(uint16_t *)value = env->fpcs;
|
||||
return;
|
||||
case UC_X86_REG_FDP:
|
||||
*(uint64_t *)value = env->fpdp;
|
||||
return;
|
||||
case UC_X86_REG_FDS:
|
||||
*(uint16_t *)value = env->fpds;
|
||||
return;
|
||||
case UC_X86_REG_FOP:
|
||||
*(uint16_t *)value = env->fpop;
|
||||
return;
|
||||
}
|
||||
|
||||
switch (mode) {
|
||||
@ -912,6 +928,22 @@ static int reg_write(CPUX86State *env, unsigned int regid, const void *value,
|
||||
hi_reg->_d[1] = src[3];
|
||||
return 0;
|
||||
}
|
||||
|
||||
case UC_X86_REG_FIP:
|
||||
env->fpip = *(uint64_t *)value;
|
||||
return 0;
|
||||
case UC_X86_REG_FCS:
|
||||
env->fpcs = *(uint16_t *)value;
|
||||
return 0;
|
||||
case UC_X86_REG_FDP:
|
||||
env->fpdp = *(uint64_t *)value;
|
||||
return 0;
|
||||
case UC_X86_REG_FDS:
|
||||
env->fpds = *(uint16_t *)value;
|
||||
return 0;
|
||||
case UC_X86_REG_FOP:
|
||||
env->fpop = *(uint16_t *)value;
|
||||
return 0;
|
||||
}
|
||||
|
||||
switch (mode) {
|
||||
|
@ -271,7 +271,7 @@ M68kCPU *cpu_m68k_init(struct uc_struct *uc)
|
||||
}
|
||||
|
||||
if (uc->cpu_model == INT_MAX) {
|
||||
uc->cpu_model = 7; // cfv4e
|
||||
uc->cpu_model = UC_CPU_M68K_CFV4E; // cfv4e
|
||||
} else if (uc->cpu_model >= ARRAY_SIZE(m68k_cpus_type_infos)) {
|
||||
free(cpu);
|
||||
return NULL;
|
||||
|
@ -164,14 +164,14 @@ MIPSCPU *cpu_mips_init(struct uc_struct *uc)
|
||||
|
||||
#ifdef TARGET_MIPS64
|
||||
if (uc->cpu_model == INT_MAX) {
|
||||
uc->cpu_model = 17; // R4000
|
||||
uc->cpu_model = UC_CPU_MIPS64_R4000; // R4000
|
||||
} else if (uc->cpu_model + UC_CPU_MIPS32_I7200 + 1 >= mips_defs_number ) {
|
||||
free(cpu);
|
||||
return NULL;
|
||||
}
|
||||
#else
|
||||
if (uc->cpu_model == INT_MAX) {
|
||||
uc->cpu_model = 10; // 74kf
|
||||
uc->cpu_model = UC_CPU_MIPS32_74KF; // 74kf
|
||||
} else if (uc->cpu_model >= mips_defs_number) {
|
||||
free(cpu);
|
||||
return NULL;
|
||||
|
@ -11149,14 +11149,14 @@ PowerPCCPU *cpu_ppc_init(struct uc_struct *uc)
|
||||
memset(cpu, 0, sizeof(*cpu));
|
||||
#ifdef TARGET_PPC64
|
||||
if (uc->cpu_model == INT_MAX) {
|
||||
uc->cpu_model = 18 + UC_CPU_PPC_7457A_V1_2 + 1; // power10_v1.0
|
||||
uc->cpu_model = UC_CPU_PPC_POWER10_V1_0 + UC_CPU_PPC_7457A_V1_2 + 1; // power10_v1.0
|
||||
} else if (uc->cpu_model + UC_CPU_PPC_7457A_V1_2 + 1 >= ARRAY_SIZE(ppc_cpus)) {
|
||||
free(cpu);
|
||||
return NULL;
|
||||
}
|
||||
#else
|
||||
if (uc->cpu_model == INT_MAX) {
|
||||
uc->cpu_model = 289; // 7457a_v1.2
|
||||
uc->cpu_model = UC_CPU_PPC_7457A_V1_2; // 7457a_v1.2
|
||||
} else if (uc->cpu_model >= ARRAY_SIZE(ppc_cpus)) {
|
||||
free(cpu);
|
||||
return NULL;
|
||||
@ -11196,5 +11196,7 @@ PowerPCCPU *cpu_ppc_init(struct uc_struct *uc)
|
||||
|
||||
qemu_init_vcpu(cs);
|
||||
|
||||
ppc_cpu_reset((CPUState *)cpu);
|
||||
|
||||
return cpu;
|
||||
}
|
||||
|
@ -9,6 +9,8 @@
|
||||
#include "unicorn_common.h"
|
||||
#include "uc_priv.h"
|
||||
#include "unicorn.h"
|
||||
#include "helper_regs.h"
|
||||
#include "cpu.h"
|
||||
|
||||
#ifdef TARGET_PPC64
|
||||
typedef uint64_t ppcreg_t;
|
||||
@ -16,6 +18,65 @@ typedef uint64_t ppcreg_t;
|
||||
typedef uint32_t ppcreg_t;
|
||||
#endif
|
||||
|
||||
// Unicorn version to ensure writing MSR without exception
|
||||
static inline int uc_ppc_store_msr(CPUPPCState *env, target_ulong value,
|
||||
int alter_hv)
|
||||
{
|
||||
// int excp;
|
||||
// CPUState *cs = env_cpu(env);
|
||||
|
||||
// excp = 0;
|
||||
value &= env->msr_mask;
|
||||
|
||||
/* Neither mtmsr nor guest state can alter HV */
|
||||
if (!alter_hv || !(env->msr & MSR_HVB)) {
|
||||
value &= ~MSR_HVB;
|
||||
value |= env->msr & MSR_HVB;
|
||||
}
|
||||
if (((value >> MSR_IR) & 1) != msr_ir ||
|
||||
((value >> MSR_DR) & 1) != msr_dr) {
|
||||
// cpu_interrupt_exittb(cs);
|
||||
}
|
||||
if ((env->mmu_model & POWERPC_MMU_BOOKE) &&
|
||||
((value >> MSR_GS) & 1) != msr_gs) {
|
||||
// cpu_interrupt_exittb(cs);
|
||||
}
|
||||
if (unlikely((env->flags & POWERPC_FLAG_TGPR) &&
|
||||
((value ^ env->msr) & (1 << MSR_TGPR)))) {
|
||||
/* Swap temporary saved registers with GPRs */
|
||||
hreg_swap_gpr_tgpr(env);
|
||||
}
|
||||
if (unlikely((value >> MSR_EP) & 1) != msr_ep) {
|
||||
/* Change the exception prefix on PowerPC 601 */
|
||||
env->excp_prefix = ((value >> MSR_EP) & 1) * 0xFFF00000;
|
||||
}
|
||||
/*
|
||||
* If PR=1 then EE, IR and DR must be 1
|
||||
*
|
||||
* Note: We only enforce this on 64-bit server processors.
|
||||
* It appears that:
|
||||
* - 32-bit implementations supports PR=1 and EE/DR/IR=0 and MacOS
|
||||
* exploits it.
|
||||
* - 64-bit embedded implementations do not need any operation to be
|
||||
* performed when PR is set.
|
||||
*/
|
||||
if (is_book3s_arch2x(env) && ((value >> MSR_PR) & 1)) {
|
||||
value |= (1 << MSR_EE) | (1 << MSR_DR) | (1 << MSR_IR);
|
||||
}
|
||||
|
||||
env->msr = value;
|
||||
hreg_compute_hflags(env);
|
||||
|
||||
// if (unlikely(msr_pow == 1)) {
|
||||
// if (!env->pending_interrupts && (*env->check_pow)(env)) {
|
||||
// cs->halted = 1;
|
||||
// excp = EXCP_HALTED;
|
||||
// }
|
||||
// }
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static uint64_t ppc_mem_redirect(uint64_t address)
|
||||
{
|
||||
/* // kseg0 range masks off high address bit
|
||||
@ -79,6 +140,7 @@ void ppc_reg_reset(struct uc_struct *uc)
|
||||
env->nip = 0;
|
||||
}
|
||||
|
||||
// http://www.csit-sun.pub.ro/~cpop/Documentatie_SMP/Motorola_PowerPC/PowerPc/GenInfo/pemch2.pdf
|
||||
static void reg_read(CPUPPCState *env, unsigned int regid, void *value)
|
||||
{
|
||||
if (regid >= UC_PPC_REG_0 && regid <= UC_PPC_REG_31)
|
||||
@ -90,12 +152,65 @@ static void reg_read(CPUPPCState *env, unsigned int regid, void *value)
|
||||
case UC_PPC_REG_PC:
|
||||
*(ppcreg_t *)value = env->nip;
|
||||
break;
|
||||
/* case UC_PPC_REG_CP0_CONFIG3:
|
||||
*(mipsreg_t *)value = env->CP0_Config3;
|
||||
break;
|
||||
case UC_MIPS_REG_CP0_USERLOCAL:
|
||||
*(mipsreg_t *)value = env->active_tc.CP0_UserLocal;
|
||||
break; */
|
||||
case UC_PPC_REG_FPR0:
|
||||
case UC_PPC_REG_FPR1:
|
||||
case UC_PPC_REG_FPR2:
|
||||
case UC_PPC_REG_FPR3:
|
||||
case UC_PPC_REG_FPR4:
|
||||
case UC_PPC_REG_FPR5:
|
||||
case UC_PPC_REG_FPR6:
|
||||
case UC_PPC_REG_FPR7:
|
||||
case UC_PPC_REG_FPR8:
|
||||
case UC_PPC_REG_FPR9:
|
||||
case UC_PPC_REG_FPR10:
|
||||
case UC_PPC_REG_FPR11:
|
||||
case UC_PPC_REG_FPR12:
|
||||
case UC_PPC_REG_FPR13:
|
||||
case UC_PPC_REG_FPR14:
|
||||
case UC_PPC_REG_FPR15:
|
||||
case UC_PPC_REG_FPR16:
|
||||
case UC_PPC_REG_FPR17:
|
||||
case UC_PPC_REG_FPR18:
|
||||
case UC_PPC_REG_FPR19:
|
||||
case UC_PPC_REG_FPR20:
|
||||
case UC_PPC_REG_FPR21:
|
||||
case UC_PPC_REG_FPR22:
|
||||
case UC_PPC_REG_FPR23:
|
||||
case UC_PPC_REG_FPR24:
|
||||
case UC_PPC_REG_FPR25:
|
||||
case UC_PPC_REG_FPR26:
|
||||
case UC_PPC_REG_FPR27:
|
||||
case UC_PPC_REG_FPR28:
|
||||
case UC_PPC_REG_FPR29:
|
||||
case UC_PPC_REG_FPR30:
|
||||
case UC_PPC_REG_FPR31:
|
||||
*(uint64_t *)value = env->vsr[regid - UC_PPC_REG_FPR0].VsrD(0);
|
||||
break;
|
||||
case UC_PPC_REG_CR0:
|
||||
case UC_PPC_REG_CR1:
|
||||
case UC_PPC_REG_CR2:
|
||||
case UC_PPC_REG_CR3:
|
||||
case UC_PPC_REG_CR4:
|
||||
case UC_PPC_REG_CR5:
|
||||
case UC_PPC_REG_CR6:
|
||||
case UC_PPC_REG_CR7:
|
||||
*(uint32_t *)value = env->crf[regid - UC_PPC_REG_CR0];
|
||||
break;
|
||||
case UC_PPC_REG_LR:
|
||||
*(ppcreg_t *)value = env->lr;
|
||||
break;
|
||||
case UC_PPC_REG_CTR:
|
||||
*(ppcreg_t *)value = env->ctr;
|
||||
break;
|
||||
case UC_PPC_REG_MSR:
|
||||
*(ppcreg_t *)value = env->msr;
|
||||
break;
|
||||
case UC_PPC_REG_XER:
|
||||
*(uint32_t *)value = env->xer;
|
||||
break;
|
||||
case UC_PPC_REG_FPSCR:
|
||||
*(uint32_t *)value = env->fpscr;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -113,12 +228,65 @@ static void reg_write(CPUPPCState *env, unsigned int regid, const void *value)
|
||||
case UC_PPC_REG_PC:
|
||||
env->nip = *(ppcreg_t *)value;
|
||||
break;
|
||||
/* case UC_MIPS_REG_CP0_CONFIG3:
|
||||
env->CP0_Config3 = *(mipsreg_t *)value;
|
||||
break;
|
||||
case UC_MIPS_REG_CP0_USERLOCAL:
|
||||
env->active_tc.CP0_UserLocal = *(mipsreg_t *)value;
|
||||
break; */
|
||||
case UC_PPC_REG_FPR0:
|
||||
case UC_PPC_REG_FPR1:
|
||||
case UC_PPC_REG_FPR2:
|
||||
case UC_PPC_REG_FPR3:
|
||||
case UC_PPC_REG_FPR4:
|
||||
case UC_PPC_REG_FPR5:
|
||||
case UC_PPC_REG_FPR6:
|
||||
case UC_PPC_REG_FPR7:
|
||||
case UC_PPC_REG_FPR8:
|
||||
case UC_PPC_REG_FPR9:
|
||||
case UC_PPC_REG_FPR10:
|
||||
case UC_PPC_REG_FPR11:
|
||||
case UC_PPC_REG_FPR12:
|
||||
case UC_PPC_REG_FPR13:
|
||||
case UC_PPC_REG_FPR14:
|
||||
case UC_PPC_REG_FPR15:
|
||||
case UC_PPC_REG_FPR16:
|
||||
case UC_PPC_REG_FPR17:
|
||||
case UC_PPC_REG_FPR18:
|
||||
case UC_PPC_REG_FPR19:
|
||||
case UC_PPC_REG_FPR20:
|
||||
case UC_PPC_REG_FPR21:
|
||||
case UC_PPC_REG_FPR22:
|
||||
case UC_PPC_REG_FPR23:
|
||||
case UC_PPC_REG_FPR24:
|
||||
case UC_PPC_REG_FPR25:
|
||||
case UC_PPC_REG_FPR26:
|
||||
case UC_PPC_REG_FPR27:
|
||||
case UC_PPC_REG_FPR28:
|
||||
case UC_PPC_REG_FPR29:
|
||||
case UC_PPC_REG_FPR30:
|
||||
case UC_PPC_REG_FPR31:
|
||||
env->vsr[regid - UC_PPC_REG_FPR0].VsrD(0) = *(uint64_t *)value;
|
||||
break;
|
||||
case UC_PPC_REG_CR0:
|
||||
case UC_PPC_REG_CR1:
|
||||
case UC_PPC_REG_CR2:
|
||||
case UC_PPC_REG_CR3:
|
||||
case UC_PPC_REG_CR4:
|
||||
case UC_PPC_REG_CR5:
|
||||
case UC_PPC_REG_CR6:
|
||||
case UC_PPC_REG_CR7:
|
||||
env->crf[regid - UC_PPC_REG_CR0] = *(uint32_t *)value;
|
||||
break;
|
||||
case UC_PPC_REG_LR:
|
||||
env->lr = *(ppcreg_t *)value;
|
||||
break;
|
||||
case UC_PPC_REG_CTR:
|
||||
env->ctr = *(ppcreg_t *)value;
|
||||
break;
|
||||
case UC_PPC_REG_MSR:
|
||||
uc_ppc_store_msr(env, *(ppcreg_t *)value, 0);
|
||||
break;
|
||||
case UC_PPC_REG_XER:
|
||||
env->xer = *(uint32_t *)value;
|
||||
break;
|
||||
case UC_PPC_REG_FPSCR:
|
||||
store_fpscr(env, *(uint32_t *)value, 0xffffffff);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -342,12 +342,12 @@ RISCVCPU *cpu_riscv_init(struct uc_struct *uc)
|
||||
|
||||
#ifdef TARGET_RISCV32
|
||||
if (uc->cpu_model == INT_MAX) {
|
||||
uc->cpu_model = 3;
|
||||
uc->cpu_model = UC_CPU_RISCV32_SIFIVE_U34;
|
||||
}
|
||||
#else
|
||||
/* TARGET_RISCV64 */
|
||||
if (uc->cpu_model == INT_MAX) {
|
||||
uc->cpu_model = 3;
|
||||
uc->cpu_model = UC_CPU_RISCV64_SIFIVE_U54;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -525,9 +525,9 @@ SPARCCPU *cpu_sparc_init(struct uc_struct *uc)
|
||||
|
||||
if (uc->cpu_model == INT_MAX) {
|
||||
#ifdef TARGET_SPARC64
|
||||
uc->cpu_model = 11; // Sun UltraSparc IV
|
||||
uc->cpu_model = UC_CPU_SPARC64_SUN_ULTRASPARC_IV; // Sun UltraSparc IV
|
||||
#else
|
||||
uc->cpu_model = 12; // Leon 3
|
||||
uc->cpu_model = UC_CPU_SPARC32_LEON3; // Leon 3
|
||||
#endif
|
||||
} else if (uc->cpu_model >= ARRAY_SIZE(sparc_defs)) {
|
||||
free(cpu);
|
||||
|
@ -58,9 +58,9 @@ static void release_common(void *t)
|
||||
|
||||
// these function is not available outside qemu
|
||||
// so we keep them here instead of outside uc_close.
|
||||
memory_free(s->uc);
|
||||
address_space_destroy(&s->uc->address_space_memory);
|
||||
address_space_destroy(&s->uc->address_space_io);
|
||||
memory_free(s->uc);
|
||||
/* clean up uc->l1_map. */
|
||||
tb_cleanup(s->uc);
|
||||
/* clean up tcg_ctx->code_gen_buffer. */
|
||||
|
@ -325,6 +325,8 @@ static void test_arm_usr32_to_svc32()
|
||||
OK(uc_reg_write(uc, UC_ARM_REG_CPSR, &r_cpsr));
|
||||
r_sp = 0x12345678;
|
||||
OK(uc_reg_write(uc, UC_ARM_REG_SP, &r_sp));
|
||||
r_lr = 0x00102220;
|
||||
OK(uc_reg_write(uc, UC_ARM_REG_LR, &r_lr));
|
||||
|
||||
r_cpsr = 0x4000009b; // UND32
|
||||
OK(uc_reg_write(uc, UC_ARM_REG_CPSR, &r_cpsr));
|
||||
@ -332,18 +334,28 @@ static void test_arm_usr32_to_svc32()
|
||||
OK(uc_reg_write(uc, UC_ARM_REG_SPSR, &r_spsr));
|
||||
r_sp = 0xDEAD0000;
|
||||
OK(uc_reg_write(uc, UC_ARM_REG_SP, &r_sp));
|
||||
r_lr = code_start + 8;
|
||||
r_lr = 0x00509998;
|
||||
OK(uc_reg_write(uc, UC_ARM_REG_LR, &r_lr));
|
||||
|
||||
OK(uc_reg_read(uc, UC_ARM_REG_CPSR, &r_cpsr));
|
||||
TEST_CHECK((r_cpsr & ((1 << 4) - 1)) == 0xb); // We are in UND32
|
||||
|
||||
r_cpsr = 0x40000090; // USR32
|
||||
OK(uc_reg_write(uc, UC_ARM_REG_CPSR, &r_cpsr));
|
||||
r_sp = 0x0010000;
|
||||
OK(uc_reg_write(uc, UC_ARM_REG_R13, &r_sp));
|
||||
r_lr = 0x0001234;
|
||||
OK(uc_reg_write(uc, UC_ARM_REG_LR, &r_lr));
|
||||
|
||||
OK(uc_reg_read(uc, UC_ARM_REG_CPSR, &r_cpsr));
|
||||
TEST_CHECK((r_cpsr & ((1 << 4) - 1)) == 0); // We are in USR32
|
||||
|
||||
r_cpsr = 0x40000093; // SVC32
|
||||
OK(uc_reg_write(uc, UC_ARM_REG_CPSR, &r_cpsr));
|
||||
|
||||
OK(uc_reg_read(uc, UC_ARM_REG_CPSR, &r_cpsr));
|
||||
OK(uc_reg_read(uc, UC_ARM_REG_SP, &r_sp));
|
||||
TEST_CHECK((r_cpsr & ((1 << 4) - 1)) == 3); // We are in SVC32
|
||||
TEST_CHECK(r_sp == 0x12345678);
|
||||
|
||||
OK(uc_close(uc));
|
||||
@ -398,6 +410,67 @@ static void test_arm_thumb_smlabb()
|
||||
OK(uc_close(uc));
|
||||
}
|
||||
|
||||
static void test_arm_not_allow_privilege_escalation()
|
||||
{
|
||||
uc_engine *uc;
|
||||
int r_cpsr, r_sp, r_spsr, r_lr;
|
||||
// E3C6601F : BIC r6, r6, #&1F
|
||||
// E3866013 : ORR r6, r6, #&13
|
||||
// E121F006 : MSR cpsr_c, r6 ; switch to SVC32 (should be ineffective
|
||||
// from USR32)
|
||||
// E1A00000 : MOV r0,r0 EF000011 : SWI OS_Exit
|
||||
char code[] = "\x1f\x60\xc6\xe3\x13\x60\x86\xe3\x06\xf0\x21\xe1\x00\x00\xa0"
|
||||
"\xe1\x11\x00\x00\xef";
|
||||
|
||||
uc_common_setup(&uc, UC_ARCH_ARM, UC_MODE_ARM, code, sizeof(code) - 1,
|
||||
UC_CPU_ARM_CORTEX_A15);
|
||||
|
||||
// https://www.keil.com/pack/doc/CMSIS/Core_A/html/group__CMSIS__CPSR.html
|
||||
r_cpsr = 0x40000013; // SVC32
|
||||
OK(uc_reg_write(uc, UC_ARM_REG_CPSR, &r_cpsr));
|
||||
r_spsr = 0x40000013;
|
||||
OK(uc_reg_write(uc, UC_ARM_REG_SPSR, &r_spsr));
|
||||
r_sp = 0x12345678;
|
||||
OK(uc_reg_write(uc, UC_ARM_REG_SP, &r_sp));
|
||||
r_lr = 0x00102220;
|
||||
OK(uc_reg_write(uc, UC_ARM_REG_LR, &r_lr));
|
||||
|
||||
r_cpsr = 0x40000010; // USR32
|
||||
OK(uc_reg_write(uc, UC_ARM_REG_CPSR, &r_cpsr));
|
||||
r_sp = 0x0010000;
|
||||
OK(uc_reg_write(uc, UC_ARM_REG_SP, &r_sp));
|
||||
r_lr = 0x0001234;
|
||||
OK(uc_reg_write(uc, UC_ARM_REG_LR, &r_lr));
|
||||
|
||||
uc_assert_err(
|
||||
UC_ERR_EXCEPTION,
|
||||
uc_emu_start(uc, code_start, code_start + sizeof(code) - 1, 0, 0));
|
||||
|
||||
OK(uc_reg_read(uc, UC_ARM_REG_SP, &r_sp));
|
||||
OK(uc_reg_read(uc, UC_ARM_REG_LR, &r_lr));
|
||||
OK(uc_reg_read(uc, UC_ARM_REG_CPSR, &r_cpsr));
|
||||
|
||||
TEST_CHECK((r_cpsr & ((1 << 4) - 1)) == 0); // Stay in USR32
|
||||
TEST_CHECK(r_lr == 0x1234);
|
||||
TEST_CHECK(r_sp == 0x10000);
|
||||
|
||||
OK(uc_close(uc));
|
||||
}
|
||||
|
||||
static void test_arm_mrc()
|
||||
{
|
||||
uc_engine *uc;
|
||||
// mrc p15, #0, r0, c1, c1, #0
|
||||
char code[] = "\x11\x0F\x11\xEE";
|
||||
|
||||
uc_common_setup(&uc, UC_ARCH_ARM, UC_MODE_ARM, code, sizeof(code) - 1,
|
||||
UC_CPU_ARM_MAX);
|
||||
|
||||
OK(uc_emu_start(uc, code_start, code_start + sizeof(code) - 1, 0, 0));
|
||||
|
||||
OK(uc_close(uc));
|
||||
}
|
||||
|
||||
TEST_LIST = {{"test_arm_nop", test_arm_nop},
|
||||
{"test_arm_thumb_sub", test_arm_thumb_sub},
|
||||
{"test_armeb_sub", test_armeb_sub},
|
||||
@ -410,4 +483,7 @@ TEST_LIST = {{"test_arm_nop", test_arm_nop},
|
||||
{"test_arm_usr32_to_svc32", test_arm_usr32_to_svc32},
|
||||
{"test_arm_v8", test_arm_v8},
|
||||
{"test_arm_thumb_smlabb", test_arm_thumb_smlabb},
|
||||
{"test_arm_not_allow_privilege_escalation",
|
||||
test_arm_not_allow_privilege_escalation},
|
||||
{"test_arm_mrc", test_arm_mrc},
|
||||
{NULL, NULL}};
|
@ -4,9 +4,10 @@ const uint64_t code_start = 0x1000;
|
||||
const uint64_t code_len = 0x4000;
|
||||
|
||||
static void uc_common_setup(uc_engine **uc, uc_arch arch, uc_mode mode,
|
||||
const char *code, uint64_t size)
|
||||
const char *code, uint64_t size, uc_cpu_arm cpu)
|
||||
{
|
||||
OK(uc_open(arch, mode, uc));
|
||||
OK(uc_ctl_set_cpu_model(*uc, cpu));
|
||||
OK(uc_mem_map(*uc, code_start, code_len, UC_PROT_ALL));
|
||||
OK(uc_mem_write(*uc, code_start, code, size));
|
||||
}
|
||||
@ -27,7 +28,8 @@ static void test_arm64_until()
|
||||
uint64_t r_pc = 0x00000000;
|
||||
uint64_t r_x28 = 0x12341234;
|
||||
|
||||
uc_common_setup(&uc, UC_ARCH_ARM64, UC_MODE_ARM, code, sizeof(code) - 1);
|
||||
uc_common_setup(&uc, UC_ARCH_ARM64, UC_MODE_ARM, code, sizeof(code) - 1,
|
||||
UC_CPU_AARCH64_A72);
|
||||
|
||||
// initialize machine registers
|
||||
OK(uc_reg_write(uc, UC_ARM64_REG_X16, &r_x16));
|
||||
@ -54,7 +56,8 @@ static void test_arm64_code_patching()
|
||||
{
|
||||
uc_engine *uc;
|
||||
char code[] = "\x00\x04\x00\x11"; // add w0, w0, 0x1
|
||||
uc_common_setup(&uc, UC_ARCH_ARM64, UC_MODE_ARM, code, sizeof(code) - 1);
|
||||
uc_common_setup(&uc, UC_ARCH_ARM64, UC_MODE_ARM, code, sizeof(code) - 1,
|
||||
UC_CPU_AARCH64_A72);
|
||||
// zero out x0
|
||||
uint64_t r_x0 = 0x0;
|
||||
OK(uc_reg_write(uc, UC_ARM64_REG_X0, &r_x0));
|
||||
@ -83,7 +86,8 @@ static void test_arm64_code_patching_count()
|
||||
{
|
||||
uc_engine *uc;
|
||||
char code[] = "\x00\x04\x00\x11"; // add w0, w0, 0x1
|
||||
uc_common_setup(&uc, UC_ARCH_ARM64, UC_MODE_ARM, code, sizeof(code) - 1);
|
||||
uc_common_setup(&uc, UC_ARCH_ARM64, UC_MODE_ARM, code, sizeof(code) - 1,
|
||||
UC_CPU_AARCH64_A72);
|
||||
// zero out x0
|
||||
uint64_t r_x0 = 0x0;
|
||||
OK(uc_reg_write(uc, UC_ARM64_REG_X0, &r_x0));
|
||||
@ -109,7 +113,33 @@ static void test_arm64_code_patching_count()
|
||||
OK(uc_close(uc));
|
||||
}
|
||||
|
||||
static void test_arm64_v8_pac()
|
||||
{
|
||||
uc_engine *uc;
|
||||
char code[] = "\x28\xfd\xea\xc8"; // casal x10, x8, [x9]
|
||||
uint64_t r_x9, r_x8, mem;
|
||||
|
||||
uc_common_setup(&uc, UC_ARCH_ARM64, UC_MODE_ARM, code, sizeof(code) - 1,
|
||||
UC_CPU_AARCH64_MAX);
|
||||
|
||||
OK(uc_mem_map(uc, 0x40000, 0x1000, UC_PROT_ALL));
|
||||
OK(uc_mem_write(uc, 0x40000, "\x00\x00\x00\x00\x00\x00\x00\x00", 8));
|
||||
r_x9 = 0x40000;
|
||||
OK(uc_reg_write(uc, UC_ARM64_REG_X9, &r_x9));
|
||||
r_x8 = 0xdeadbeafdeadbeaf;
|
||||
OK(uc_reg_write(uc, UC_ARM64_REG_X8, &r_x8));
|
||||
|
||||
OK(uc_emu_start(uc, code_start, code_start + sizeof(code) - 1, 0, 0));
|
||||
|
||||
OK(uc_mem_read(uc, 0x40000, (void *)&mem, 8));
|
||||
|
||||
TEST_CHECK(mem == r_x8);
|
||||
|
||||
OK(uc_close(uc));
|
||||
}
|
||||
|
||||
TEST_LIST = {{"test_arm64_until", test_arm64_until},
|
||||
{"test_arm64_code_patching", test_arm64_code_patching},
|
||||
{"test_arm64_code_patching_count", test_arm64_code_patching_count},
|
||||
{"test_arm64_v8_pac", test_arm64_v8_pac},
|
||||
{NULL, NULL}};
|
||||
|
@ -34,4 +34,35 @@ static void test_ppc32_add()
|
||||
OK(uc_close(uc));
|
||||
}
|
||||
|
||||
TEST_LIST = {{"test_ppc32_add", test_ppc32_add}, {NULL, NULL}};
|
||||
// https://www.ibm.com/docs/en/aix/7.2?topic=set-fadd-fa-floating-add-instruction
|
||||
static void test_ppc32_fadd()
|
||||
{
|
||||
uc_engine *uc;
|
||||
char code[] = "\xfc\xc4\x28\x2a"; // fadd 6, 4, 5
|
||||
uint32_t r_msr;
|
||||
uint64_t r_fpr4, r_fpr5, r_fpr6;
|
||||
|
||||
uc_common_setup(&uc, UC_ARCH_PPC, UC_MODE_32 | UC_MODE_BIG_ENDIAN, code,
|
||||
sizeof(code) - 1);
|
||||
|
||||
OK(uc_reg_read(uc, UC_PPC_REG_MSR, &r_msr));
|
||||
r_msr |= (1 << 13); // Big endian
|
||||
OK(uc_reg_write(uc, UC_PPC_REG_MSR, &r_msr)); // enable FP
|
||||
|
||||
r_fpr4 = 0xC053400000000000ul;
|
||||
r_fpr5 = 0x400C000000000000ul;
|
||||
OK(uc_reg_write(uc, UC_PPC_REG_FPR4, &r_fpr4));
|
||||
OK(uc_reg_write(uc, UC_PPC_REG_FPR5, &r_fpr5));
|
||||
|
||||
OK(uc_emu_start(uc, code_start, code_start + sizeof(code) - 1, 0, 0));
|
||||
|
||||
OK(uc_reg_read(uc, UC_PPC_REG_FPR6, &r_fpr6));
|
||||
|
||||
TEST_CHECK(r_fpr6 == 0xC052600000000000ul);
|
||||
|
||||
OK(uc_close(uc));
|
||||
}
|
||||
|
||||
TEST_LIST = {{"test_ppc32_add", test_ppc32_add},
|
||||
{"test_ppc32_fadd", test_ppc32_fadd},
|
||||
{NULL, NULL}};
|
Loading…
Reference in New Issue
Block a user