Merge branch 'dev' into s390x

This commit is contained in:
lazymio 2022-01-10 15:17:42 +01:00
commit 71f044ca50
No known key found for this signature in database
GPG Key ID: DFF27E34A47CB873
33 changed files with 603 additions and 122 deletions

View File

@ -35,13 +35,14 @@ module Arm =
let UC_CPU_ARM_PXA260 = 23 let UC_CPU_ARM_PXA260 = 23
let UC_CPU_ARM_PXA261 = 24 let UC_CPU_ARM_PXA261 = 24
let UC_CPU_ARM_PXA262 = 25 let UC_CPU_ARM_PXA262 = 25
let UC_CPU_ARM_PXA270A0 = 26 let UC_CPU_ARM_PXA270 = 26
let UC_CPU_ARM_PXA270A1 = 27 let UC_CPU_ARM_PXA270A0 = 27
let UC_CPU_ARM_PXA270B0 = 28 let UC_CPU_ARM_PXA270A1 = 28
let UC_CPU_ARM_PXA270B1 = 29 let UC_CPU_ARM_PXA270B0 = 29
let UC_CPU_ARM_PXA270C0 = 30 let UC_CPU_ARM_PXA270B1 = 30
let UC_CPU_ARM_PXA270C5 = 31 let UC_CPU_ARM_PXA270C0 = 31
let UC_CPU_ARM_MAX = 32 let UC_CPU_ARM_PXA270C5 = 32
let UC_CPU_ARM_MAX = 33
// ARM registers // ARM registers

View File

@ -284,7 +284,12 @@ module X86 =
let UC_X86_REG_GS_BASE = 231 let UC_X86_REG_GS_BASE = 231
let UC_X86_REG_FLAGS = 232 let UC_X86_REG_FLAGS = 232
let UC_X86_REG_RFLAGS = 233 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 // X86 instructions

View File

@ -30,13 +30,14 @@ const (
CPU_ARM_PXA260 = 23 CPU_ARM_PXA260 = 23
CPU_ARM_PXA261 = 24 CPU_ARM_PXA261 = 24
CPU_ARM_PXA262 = 25 CPU_ARM_PXA262 = 25
CPU_ARM_PXA270A0 = 26 CPU_ARM_PXA270 = 26
CPU_ARM_PXA270A1 = 27 CPU_ARM_PXA270A0 = 27
CPU_ARM_PXA270B0 = 28 CPU_ARM_PXA270A1 = 28
CPU_ARM_PXA270B1 = 29 CPU_ARM_PXA270B0 = 29
CPU_ARM_PXA270C0 = 30 CPU_ARM_PXA270B1 = 30
CPU_ARM_PXA270C5 = 31 CPU_ARM_PXA270C0 = 31
CPU_ARM_MAX = 32 CPU_ARM_PXA270C5 = 32
CPU_ARM_MAX = 33
// ARM registers // ARM registers

View File

@ -279,7 +279,12 @@ const (
X86_REG_GS_BASE = 231 X86_REG_GS_BASE = 231
X86_REG_FLAGS = 232 X86_REG_FLAGS = 232
X86_REG_RFLAGS = 233 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 // X86 instructions

View File

@ -32,13 +32,14 @@ public interface ArmConst {
public static final int UC_CPU_ARM_PXA260 = 23; 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_PXA261 = 24;
public static final int UC_CPU_ARM_PXA262 = 25; 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_PXA270 = 26;
public static final int UC_CPU_ARM_PXA270A1 = 27; public static final int UC_CPU_ARM_PXA270A0 = 27;
public static final int UC_CPU_ARM_PXA270B0 = 28; public static final int UC_CPU_ARM_PXA270A1 = 28;
public static final int UC_CPU_ARM_PXA270B1 = 29; public static final int UC_CPU_ARM_PXA270B0 = 29;
public static final int UC_CPU_ARM_PXA270C0 = 30; public static final int UC_CPU_ARM_PXA270B1 = 30;
public static final int UC_CPU_ARM_PXA270C5 = 31; public static final int UC_CPU_ARM_PXA270C0 = 31;
public static final int UC_CPU_ARM_MAX = 32; public static final int UC_CPU_ARM_PXA270C5 = 32;
public static final int UC_CPU_ARM_MAX = 33;
// ARM registers // ARM registers

View File

@ -281,7 +281,12 @@ public interface X86Const {
public static final int UC_X86_REG_GS_BASE = 231; 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_FLAGS = 232;
public static final int UC_X86_REG_RFLAGS = 233; 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 // X86 instructions

View File

@ -33,13 +33,14 @@ const
UC_CPU_ARM_PXA260 = 23; UC_CPU_ARM_PXA260 = 23;
UC_CPU_ARM_PXA261 = 24; UC_CPU_ARM_PXA261 = 24;
UC_CPU_ARM_PXA262 = 25; UC_CPU_ARM_PXA262 = 25;
UC_CPU_ARM_PXA270A0 = 26; UC_CPU_ARM_PXA270 = 26;
UC_CPU_ARM_PXA270A1 = 27; UC_CPU_ARM_PXA270A0 = 27;
UC_CPU_ARM_PXA270B0 = 28; UC_CPU_ARM_PXA270A1 = 28;
UC_CPU_ARM_PXA270B1 = 29; UC_CPU_ARM_PXA270B0 = 29;
UC_CPU_ARM_PXA270C0 = 30; UC_CPU_ARM_PXA270B1 = 30;
UC_CPU_ARM_PXA270C5 = 31; UC_CPU_ARM_PXA270C0 = 31;
UC_CPU_ARM_MAX = 32; UC_CPU_ARM_PXA270C5 = 32;
UC_CPU_ARM_MAX = 33;
// ARM registers // ARM registers

View File

@ -282,7 +282,12 @@ const
UC_X86_REG_GS_BASE = 231; UC_X86_REG_GS_BASE = 231;
UC_X86_REG_FLAGS = 232; UC_X86_REG_FLAGS = 232;
UC_X86_REG_RFLAGS = 233; 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 // X86 instructions

View File

@ -28,13 +28,14 @@ UC_CPU_ARM_PXA255 = 22
UC_CPU_ARM_PXA260 = 23 UC_CPU_ARM_PXA260 = 23
UC_CPU_ARM_PXA261 = 24 UC_CPU_ARM_PXA261 = 24
UC_CPU_ARM_PXA262 = 25 UC_CPU_ARM_PXA262 = 25
UC_CPU_ARM_PXA270A0 = 26 UC_CPU_ARM_PXA270 = 26
UC_CPU_ARM_PXA270A1 = 27 UC_CPU_ARM_PXA270A0 = 27
UC_CPU_ARM_PXA270B0 = 28 UC_CPU_ARM_PXA270A1 = 28
UC_CPU_ARM_PXA270B1 = 29 UC_CPU_ARM_PXA270B0 = 29
UC_CPU_ARM_PXA270C0 = 30 UC_CPU_ARM_PXA270B1 = 30
UC_CPU_ARM_PXA270C5 = 31 UC_CPU_ARM_PXA270C0 = 31
UC_CPU_ARM_MAX = 32 UC_CPU_ARM_PXA270C5 = 32
UC_CPU_ARM_MAX = 33
# ARM registers # ARM registers

View File

@ -277,7 +277,12 @@ UC_X86_REG_FS_BASE = 230
UC_X86_REG_GS_BASE = 231 UC_X86_REG_GS_BASE = 231
UC_X86_REG_FLAGS = 232 UC_X86_REG_FLAGS = 232
UC_X86_REG_RFLAGS = 233 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 # X86 instructions

View File

@ -30,13 +30,14 @@ module UnicornEngine
UC_CPU_ARM_PXA260 = 23 UC_CPU_ARM_PXA260 = 23
UC_CPU_ARM_PXA261 = 24 UC_CPU_ARM_PXA261 = 24
UC_CPU_ARM_PXA262 = 25 UC_CPU_ARM_PXA262 = 25
UC_CPU_ARM_PXA270A0 = 26 UC_CPU_ARM_PXA270 = 26
UC_CPU_ARM_PXA270A1 = 27 UC_CPU_ARM_PXA270A0 = 27
UC_CPU_ARM_PXA270B0 = 28 UC_CPU_ARM_PXA270A1 = 28
UC_CPU_ARM_PXA270B1 = 29 UC_CPU_ARM_PXA270B0 = 29
UC_CPU_ARM_PXA270C0 = 30 UC_CPU_ARM_PXA270B1 = 30
UC_CPU_ARM_PXA270C5 = 31 UC_CPU_ARM_PXA270C0 = 31
UC_CPU_ARM_MAX = 32 UC_CPU_ARM_PXA270C5 = 32
UC_CPU_ARM_MAX = 33
# ARM registers # ARM registers

View File

@ -279,7 +279,12 @@ module UnicornEngine
UC_X86_REG_GS_BASE = 231 UC_X86_REG_GS_BASE = 231
UC_X86_REG_FLAGS = 232 UC_X86_REG_FLAGS = 232
UC_X86_REG_RFLAGS = 233 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 # X86 instructions

View File

@ -43,6 +43,7 @@ typedef enum uc_cpu_arm {
UC_CPU_ARM_PXA260, UC_CPU_ARM_PXA260,
UC_CPU_ARM_PXA261, UC_CPU_ARM_PXA261,
UC_CPU_ARM_PXA262, UC_CPU_ARM_PXA262,
UC_CPU_ARM_PXA270,
UC_CPU_ARM_PXA270A0, UC_CPU_ARM_PXA270A0,
UC_CPU_ARM_PXA270A1, UC_CPU_ARM_PXA270A1,
UC_CPU_ARM_PXA270B0, UC_CPU_ARM_PXA270B0,

View File

@ -370,6 +370,54 @@ typedef enum uc_ppc_reg {
UC_PPC_REG_29, UC_PPC_REG_29,
UC_PPC_REG_30, UC_PPC_REG_30,
UC_PPC_REG_31, 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; } uc_ppc_reg;
#ifdef __cplusplus #ifdef __cplusplus

View File

@ -319,6 +319,11 @@ typedef enum uc_x86_reg {
UC_X86_REG_GS_BASE, UC_X86_REG_GS_BASE,
UC_X86_REG_FLAGS, UC_X86_REG_FLAGS,
UC_X86_REG_RFLAGS, 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_ENDING // <-- mark the end of the list of registers
} uc_x86_reg; } uc_x86_reg;

View File

@ -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; 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, // (GPA -> HVA via memory_region_get_ram_addr(mr) + GPA + block->host,
// HVA->HPA via host mmu) // HVA->HPA via host mmu)
start = get_page_addr_code(uc->cpu->env_ptr, start_addr) & (target_ulong)(-1); start = get_page_addr_code(uc->cpu->env_ptr, start_addr) & (target_ulong)(-1);
uc->nested_level--;
// For 32bit target. // For 32bit target.
end = (start + len) & (target_ulong)(-1); end = (start + len) & (target_ulong)(-1);

View File

@ -184,13 +184,6 @@ static void arm_cpu_reset(CPUState *dev)
} else { } else {
env->pstate = PSTATE_MODE_EL1h; 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; env->pc = cpu->rvbar;
} }
@ -705,6 +698,17 @@ void arm_cpu_post_init(CPUState *obj)
cpu->rvbar = 0; 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)) { if (arm_feature(&cpu->env, ARM_FEATURE_PMU)) {
cpu->has_pmu = true; 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 */ /* old-style VFP short-vector support */
FIELD_DP32(cpu->isar.mvfr0, MVFR0, FPSHVEC, 1, cpu->isar.mvfr0); 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 #endif
@ -2056,15 +2108,15 @@ ARMCPU *cpu_arm_init(struct uc_struct *uc)
#if !defined(TARGET_AARCH64) #if !defined(TARGET_AARCH64)
if (uc->mode & UC_MODE_MCLASS) { 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) { } 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) { } 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) { } 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) { } 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)) { } else if (uc->cpu_model >= ARR_SIZE(arm_cpus)) {
free(cpu); free(cpu);
return NULL; return NULL;

View File

@ -1264,6 +1264,7 @@ typedef enum CPSRWriteType {
CPSRWriteExceptionReturn = 1, /* from guest exception return insn */ CPSRWriteExceptionReturn = 1, /* from guest exception return insn */
CPSRWriteRaw = 2, /* trust values, do not switch reg banks */ CPSRWriteRaw = 2, /* trust values, do not switch reg banks */
CPSRWriteByGDBStub = 3, /* from the GDB stub */ CPSRWriteByGDBStub = 3, /* from the GDB stub */
CPSRWriteByUnicorn = 4 /* from uc_reg_write */
} CPSRWriteType; } CPSRWriteType;
/* Set the CPSR. Note that some bits of mask must be all-set or all-clear.*/ /* Set the CPSR. Note that some bits of mask must be all-set or all-clear.*/

View File

@ -320,8 +320,6 @@ static const ARMCPUInfo aarch64_cpus[] = {
ARMCPU *cpu_aarch64_init(struct uc_struct *uc) ARMCPU *cpu_aarch64_init(struct uc_struct *uc)
{ {
int i;
char *cpu_model = "cortex-a72";
ARMCPU *cpu; ARMCPU *cpu;
CPUState *cs; CPUState *cs;
CPUClass *cc; CPUClass *cc;
@ -331,6 +329,13 @@ ARMCPU *cpu_aarch64_init(struct uc_struct *uc)
return NULL; 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; cs = (CPUState *)cpu;
cc = (CPUClass *)&cpu->cc; cc = (CPUClass *)&cpu->cc;
cs->cc = cc; cs->cc = cc;
@ -349,33 +354,13 @@ ARMCPU *cpu_aarch64_init(struct uc_struct *uc)
/* init ARMCPU */ /* init ARMCPU */
arm_cpu_initfn(uc, cs); arm_cpu_initfn(uc, cs);
for (i = 0; i < ARRAY_SIZE(aarch64_cpus); i++) { if (aarch64_cpus[uc->cpu_model].initfn) {
if (strcmp(cpu_model, aarch64_cpus[i].name) == 0) { aarch64_cpus[uc->cpu_model].initfn(uc, cs);
if (aarch64_cpus[i].initfn) {
aarch64_cpus[i].initfn(uc, cs);
}
break;
}
}
if (i == ARRAY_SIZE(aarch64_cpus)) {
free(cpu);
return NULL;
} }
/* postinit ARMCPU */ /* postinit ARMCPU */
arm_cpu_post_init(cs); 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 */ /* realize ARMCPU */
arm_cpu_realizefn(uc, cs); arm_cpu_realizefn(uc, cs);

View File

@ -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 * to switch mode. (Those are caught by translate.c for writes
* triggered by guest instructions.) * triggered by guest instructions.)
*/ */
// mask &= ~CPSR_M; // Unicorn: No, it can also be uc_reg_write, let user switch registers banks.
// Unicorn: No, it can also be uc_reg_write if (write_type == CPSRWriteByUnicorn) {
switch_mode(env, val & CPSR_M); switch_mode(env, val & CPSR_M);
} else {
mask &= ~CPSR_M;
}
} else if (bad_mode_switch(env, val & CPSR_M, write_type)) { } else if (bad_mode_switch(env, val & CPSR_M, write_type)) {
/* Attempt to switch to an invalid mode: this is UNPREDICTABLE in /* Attempt to switch to an invalid mode: this is UNPREDICTABLE in
* v7, and has defined behaviour in v8: * v7, and has defined behaviour in v8:

View File

@ -251,17 +251,17 @@ static void reg_write(CPUARMState *env, unsigned int regid, const void *value)
case UC_ARM_REG_APSR: case UC_ARM_REG_APSR:
if (!arm_feature(env, ARM_FEATURE_M)) { if (!arm_feature(env, ARM_FEATURE_M)) {
cpsr_write(env, *(uint32_t *)value, cpsr_write(env, *(uint32_t *)value,
(CPSR_NZCV | CPSR_Q | CPSR_GE), CPSRWriteByInstr); (CPSR_NZCV | CPSR_Q | CPSR_GE), CPSRWriteByUnicorn);
} else { } else {
// Same with UC_ARM_REG_APSR_NZCVQ // Same with UC_ARM_REG_APSR_NZCVQ
v7m_msr_xpsr(env, 0b1000, 0, *(uint32_t *)value); v7m_msr_xpsr(env, 0b1000, 0, *(uint32_t *)value);
} }
break; break;
case UC_ARM_REG_APSR_NZCV: 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; break;
case UC_ARM_REG_CPSR: case UC_ARM_REG_CPSR:
cpsr_write(env, *(uint32_t *)value, ~0, CPSRWriteByInstr); cpsr_write(env, *(uint32_t *)value, ~0, CPSRWriteByUnicorn);
break; break;
case UC_ARM_REG_SPSR: case UC_ARM_REG_SPSR:
env->spsr = *(uint32_t *)value; env->spsr = *(uint32_t *)value;

View File

@ -5083,9 +5083,9 @@ X86CPU *cpu_x86_init(struct uc_struct *uc)
if (uc->cpu_model == INT_MAX) { if (uc->cpu_model == INT_MAX) {
#ifdef TARGET_X86_64 #ifdef TARGET_X86_64
uc->cpu_model = 0; // qemu64 uc->cpu_model = UC_CPU_X86_QEMU64; // qemu64
#else #else
uc->cpu_model = 4; // qemu32 uc->cpu_model = UC_CPU_X86_QEMU32; // qemu32
#endif #endif
} else if (uc->cpu_model >= ARRAY_SIZE(builtin_x86_defs)) { } else if (uc->cpu_model >= ARRAY_SIZE(builtin_x86_defs)) {
free(cpu); free(cpu);

View File

@ -321,6 +321,22 @@ static void reg_read(CPUX86State *env, unsigned int regid, void *value,
dst[3] = hi_reg->_d[1]; dst[3] = hi_reg->_d[1];
return; 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) { switch (mode) {
@ -912,6 +928,22 @@ static int reg_write(CPUX86State *env, unsigned int regid, const void *value,
hi_reg->_d[1] = src[3]; hi_reg->_d[1] = src[3];
return 0; 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) { switch (mode) {

View File

@ -271,7 +271,7 @@ M68kCPU *cpu_m68k_init(struct uc_struct *uc)
} }
if (uc->cpu_model == INT_MAX) { 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)) { } else if (uc->cpu_model >= ARRAY_SIZE(m68k_cpus_type_infos)) {
free(cpu); free(cpu);
return NULL; return NULL;

View File

@ -164,14 +164,14 @@ MIPSCPU *cpu_mips_init(struct uc_struct *uc)
#ifdef TARGET_MIPS64 #ifdef TARGET_MIPS64
if (uc->cpu_model == INT_MAX) { 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 ) { } else if (uc->cpu_model + UC_CPU_MIPS32_I7200 + 1 >= mips_defs_number ) {
free(cpu); free(cpu);
return NULL; return NULL;
} }
#else #else
if (uc->cpu_model == INT_MAX) { 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) { } else if (uc->cpu_model >= mips_defs_number) {
free(cpu); free(cpu);
return NULL; return NULL;

View File

@ -11149,14 +11149,14 @@ PowerPCCPU *cpu_ppc_init(struct uc_struct *uc)
memset(cpu, 0, sizeof(*cpu)); memset(cpu, 0, sizeof(*cpu));
#ifdef TARGET_PPC64 #ifdef TARGET_PPC64
if (uc->cpu_model == INT_MAX) { 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)) { } else if (uc->cpu_model + UC_CPU_PPC_7457A_V1_2 + 1 >= ARRAY_SIZE(ppc_cpus)) {
free(cpu); free(cpu);
return NULL; return NULL;
} }
#else #else
if (uc->cpu_model == INT_MAX) { 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)) { } else if (uc->cpu_model >= ARRAY_SIZE(ppc_cpus)) {
free(cpu); free(cpu);
return NULL; return NULL;
@ -11196,5 +11196,7 @@ PowerPCCPU *cpu_ppc_init(struct uc_struct *uc)
qemu_init_vcpu(cs); qemu_init_vcpu(cs);
ppc_cpu_reset((CPUState *)cpu);
return cpu; return cpu;
} }

View File

@ -9,6 +9,8 @@
#include "unicorn_common.h" #include "unicorn_common.h"
#include "uc_priv.h" #include "uc_priv.h"
#include "unicorn.h" #include "unicorn.h"
#include "helper_regs.h"
#include "cpu.h"
#ifdef TARGET_PPC64 #ifdef TARGET_PPC64
typedef uint64_t ppcreg_t; typedef uint64_t ppcreg_t;
@ -16,6 +18,65 @@ typedef uint64_t ppcreg_t;
typedef uint32_t ppcreg_t; typedef uint32_t ppcreg_t;
#endif #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) static uint64_t ppc_mem_redirect(uint64_t address)
{ {
/* // kseg0 range masks off high address bit /* // kseg0 range masks off high address bit
@ -79,6 +140,7 @@ void ppc_reg_reset(struct uc_struct *uc)
env->nip = 0; 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) static void reg_read(CPUPPCState *env, unsigned int regid, void *value)
{ {
if (regid >= UC_PPC_REG_0 && regid <= UC_PPC_REG_31) 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: case UC_PPC_REG_PC:
*(ppcreg_t *)value = env->nip; *(ppcreg_t *)value = env->nip;
break; break;
/* case UC_PPC_REG_CP0_CONFIG3: case UC_PPC_REG_FPR0:
*(mipsreg_t *)value = env->CP0_Config3; case UC_PPC_REG_FPR1:
break; case UC_PPC_REG_FPR2:
case UC_MIPS_REG_CP0_USERLOCAL: case UC_PPC_REG_FPR3:
*(mipsreg_t *)value = env->active_tc.CP0_UserLocal; case UC_PPC_REG_FPR4:
break; */ 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: case UC_PPC_REG_PC:
env->nip = *(ppcreg_t *)value; env->nip = *(ppcreg_t *)value;
break; break;
/* case UC_MIPS_REG_CP0_CONFIG3: case UC_PPC_REG_FPR0:
env->CP0_Config3 = *(mipsreg_t *)value; case UC_PPC_REG_FPR1:
break; case UC_PPC_REG_FPR2:
case UC_MIPS_REG_CP0_USERLOCAL: case UC_PPC_REG_FPR3:
env->active_tc.CP0_UserLocal = *(mipsreg_t *)value; case UC_PPC_REG_FPR4:
break; */ 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;
} }
} }

View File

@ -342,12 +342,12 @@ RISCVCPU *cpu_riscv_init(struct uc_struct *uc)
#ifdef TARGET_RISCV32 #ifdef TARGET_RISCV32
if (uc->cpu_model == INT_MAX) { if (uc->cpu_model == INT_MAX) {
uc->cpu_model = 3; uc->cpu_model = UC_CPU_RISCV32_SIFIVE_U34;
} }
#else #else
/* TARGET_RISCV64 */ /* TARGET_RISCV64 */
if (uc->cpu_model == INT_MAX) { if (uc->cpu_model == INT_MAX) {
uc->cpu_model = 3; uc->cpu_model = UC_CPU_RISCV64_SIFIVE_U54;
} }
#endif #endif

View File

@ -525,9 +525,9 @@ SPARCCPU *cpu_sparc_init(struct uc_struct *uc)
if (uc->cpu_model == INT_MAX) { if (uc->cpu_model == INT_MAX) {
#ifdef TARGET_SPARC64 #ifdef TARGET_SPARC64
uc->cpu_model = 11; // Sun UltraSparc IV uc->cpu_model = UC_CPU_SPARC64_SUN_ULTRASPARC_IV; // Sun UltraSparc IV
#else #else
uc->cpu_model = 12; // Leon 3 uc->cpu_model = UC_CPU_SPARC32_LEON3; // Leon 3
#endif #endif
} else if (uc->cpu_model >= ARRAY_SIZE(sparc_defs)) { } else if (uc->cpu_model >= ARRAY_SIZE(sparc_defs)) {
free(cpu); free(cpu);

View File

@ -58,9 +58,9 @@ static void release_common(void *t)
// these function is not available outside qemu // these function is not available outside qemu
// so we keep them here instead of outside uc_close. // 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_memory);
address_space_destroy(&s->uc->address_space_io); address_space_destroy(&s->uc->address_space_io);
memory_free(s->uc);
/* clean up uc->l1_map. */ /* clean up uc->l1_map. */
tb_cleanup(s->uc); tb_cleanup(s->uc);
/* clean up tcg_ctx->code_gen_buffer. */ /* clean up tcg_ctx->code_gen_buffer. */

View File

@ -325,6 +325,8 @@ static void test_arm_usr32_to_svc32()
OK(uc_reg_write(uc, UC_ARM_REG_CPSR, &r_cpsr)); OK(uc_reg_write(uc, UC_ARM_REG_CPSR, &r_cpsr));
r_sp = 0x12345678; r_sp = 0x12345678;
OK(uc_reg_write(uc, UC_ARM_REG_SP, &r_sp)); 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 r_cpsr = 0x4000009b; // UND32
OK(uc_reg_write(uc, UC_ARM_REG_CPSR, &r_cpsr)); 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)); OK(uc_reg_write(uc, UC_ARM_REG_SPSR, &r_spsr));
r_sp = 0xDEAD0000; r_sp = 0xDEAD0000;
OK(uc_reg_write(uc, UC_ARM_REG_SP, &r_sp)); 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_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 r_cpsr = 0x40000090; // USR32
OK(uc_reg_write(uc, UC_ARM_REG_CPSR, &r_cpsr)); OK(uc_reg_write(uc, UC_ARM_REG_CPSR, &r_cpsr));
r_sp = 0x0010000; r_sp = 0x0010000;
OK(uc_reg_write(uc, UC_ARM_REG_R13, &r_sp)); 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 r_cpsr = 0x40000093; // SVC32
OK(uc_reg_write(uc, UC_ARM_REG_CPSR, &r_cpsr)); 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)); 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); TEST_CHECK(r_sp == 0x12345678);
OK(uc_close(uc)); OK(uc_close(uc));
@ -398,6 +410,67 @@ static void test_arm_thumb_smlabb()
OK(uc_close(uc)); 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_LIST = {{"test_arm_nop", test_arm_nop},
{"test_arm_thumb_sub", test_arm_thumb_sub}, {"test_arm_thumb_sub", test_arm_thumb_sub},
{"test_armeb_sub", test_armeb_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_usr32_to_svc32", test_arm_usr32_to_svc32},
{"test_arm_v8", test_arm_v8}, {"test_arm_v8", test_arm_v8},
{"test_arm_thumb_smlabb", test_arm_thumb_smlabb}, {"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}}; {NULL, NULL}};

View File

@ -4,9 +4,10 @@ const uint64_t code_start = 0x1000;
const uint64_t code_len = 0x4000; const uint64_t code_len = 0x4000;
static void uc_common_setup(uc_engine **uc, uc_arch arch, uc_mode mode, 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_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_map(*uc, code_start, code_len, UC_PROT_ALL));
OK(uc_mem_write(*uc, code_start, code, size)); 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_pc = 0x00000000;
uint64_t r_x28 = 0x12341234; 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 // initialize machine registers
OK(uc_reg_write(uc, UC_ARM64_REG_X16, &r_x16)); OK(uc_reg_write(uc, UC_ARM64_REG_X16, &r_x16));
@ -54,7 +56,8 @@ static void test_arm64_code_patching()
{ {
uc_engine *uc; uc_engine *uc;
char code[] = "\x00\x04\x00\x11"; // add w0, w0, 0x1 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 // zero out x0
uint64_t r_x0 = 0x0; uint64_t r_x0 = 0x0;
OK(uc_reg_write(uc, UC_ARM64_REG_X0, &r_x0)); 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; uc_engine *uc;
char code[] = "\x00\x04\x00\x11"; // add w0, w0, 0x1 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 // zero out x0
uint64_t r_x0 = 0x0; uint64_t r_x0 = 0x0;
OK(uc_reg_write(uc, UC_ARM64_REG_X0, &r_x0)); 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)); 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_LIST = {{"test_arm64_until", test_arm64_until},
{"test_arm64_code_patching", test_arm64_code_patching}, {"test_arm64_code_patching", test_arm64_code_patching},
{"test_arm64_code_patching_count", test_arm64_code_patching_count}, {"test_arm64_code_patching_count", test_arm64_code_patching_count},
{"test_arm64_v8_pac", test_arm64_v8_pac},
{NULL, NULL}}; {NULL, NULL}};

View File

@ -34,4 +34,35 @@ static void test_ppc32_add()
OK(uc_close(uc)); 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}};