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_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
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
@ -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,
|
||||||
|
@ -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
|
||||||
|
@ -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;
|
||||||
|
|
||||||
|
@ -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);
|
||||||
|
|
||||||
|
@ -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;
|
||||||
|
@ -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.*/
|
||||||
|
@ -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);
|
||||||
|
|
||||||
|
@ -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:
|
||||||
|
@ -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;
|
||||||
|
@ -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);
|
||||||
|
@ -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) {
|
||||||
|
@ -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;
|
||||||
|
@ -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;
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
@ -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);
|
||||||
|
@ -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. */
|
||||||
|
@ -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}};
|
@ -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}};
|
||||||
|
@ -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}};
|
Loading…
Reference in New Issue
Block a user