This is point 6 on the list.
1. Cache the DZP bit from mrs dczid_el0 in a new field arm64_data_zero_prohibited of VexArchInfo
2. Use the cached values from VexArchInfo for mrs dczid_el0 rather than a dirty helper
3. Add a check to dc zva that the above DZP wasn't set. If it is then print a message
and stop with a Ijk_SigILL.
extern ULong arm64g_calc_crc32cx ( ULong acc, ULong bits );
/* --- DIRTY HELPERS --- */
-extern ULong arm64g_dirtyhelper_MRS_DCZID_EL0 ( void );
-
extern ULong arm64g_dirtyhelper_MRS_CNTVCT_EL0 ( void );
extern ULong arm64g_dirtyhelper_MRS_CNTFRQ_EL0 ( void );
return crc;
}
-/* CALLED FROM GENERATED CODE */
-/* DIRTY HELPER (non-referentially-transparent) */
-/* Horrible hack. On non-arm64 platforms, return 0. */
-ULong arm64g_dirtyhelper_MRS_DCZID_EL0 ( void )
-{
-# if defined(__aarch64__) && !defined(__arm__)
- ULong w = 0x5555555555555555ULL; /* overwritten */
- __asm__ __volatile__("mrs %0, dczid_el0" : "=r"(w));
- return w;
-# else
- return 0ULL;
-# endif
-}
-
/* CALLED FROM GENERATED CODE */
/* DIRTY HELPER (non-referentially-transparent) */
/* Horrible hack. On non-arm64 platforms, return 0. */
*/
if ((INSN(31,0) & 0xFFFFFFE0) == 0xD53B00E0) {
UInt tt = INSN(4,0);
- IRTemp val = newTemp(Ity_I64);
- IRExpr** args = mkIRExprVec_0();
- IRDirty* d = unsafeIRDirty_1_N (
- val,
- 0/*regparms*/,
- "arm64g_dirtyhelper_MRS_DCZID_EL0",
- &arm64g_dirtyhelper_MRS_DCZID_EL0,
- args
- );
- /* execute the dirty call, dumping the result in val. */
- stmt( IRStmt_Dirty(d) );
+ ULong val_cached = (archinfo->arm64_data_zero_prohibited ? 0x10 : 0) |
+ archinfo->arm64_cache_block_size;
+ IRTemp val = newTemp(Ity_I64);
+ assign(val, mkU64(val_cached));
putIReg64orZR(tt, mkexpr(val));
- DIP("mrs %s, dczid_el0 (FAKED)\n", nameIReg64orZR(tt));
+ DIP("mrs %s, dczid_el0 (cached)\n", nameIReg64orZR(tt));
return True;
}
/* ---- Cases for CTR_EL0 ----
if ((INSN(31,0) & 0xFFFFFFE0) == 0xD50B7420) {
/* Round the requested address, in rT, down to the start of the
containing block. */
+ /* Unless DZP is true */
+ if (archinfo->arm64_data_zero_prohibited) {
+ vex_printf("ARM64 front end: DC ZVA instruction encountered with the DCZID_EL0 DZP flag set.\n");
+ putPC(mkU64( guest_PC_curr_instr));
+ dres->jk_StopHere = Ijk_SigILL;
+ dres->whatNext = Dis_StopHere;
+ return True;
+ }
UInt tt = INSN(4,0);
ULong clearszB = 1UL << (archinfo->arm64_cache_block_size + 2);
IRTemp addr = newTemp(Ity_I64);
void LibVEX_default_VexArchInfo ( /*OUT*/VexArchInfo* vai )
{
vex_bzero(vai, sizeof(*vai));
- vai->hwcaps = 0;
- vai->endness = VexEndness_INVALID;
- vai->ppc_icache_line_szB = 0;
- vai->ppc_dcbz_szB = 0;
- vai->ppc_dcbzl_szB = 0;
- vai->arm64_dMinLine_lg2_szB = 0;
- vai->arm64_iMinLine_lg2_szB = 0;
- vai->arm64_cache_block_size = 0;
+ vai->hwcaps = 0;
+ vai->endness = VexEndness_INVALID;
+ vai->ppc_icache_line_szB = 0;
+ vai->ppc_dcbz_szB = 0;
+ vai->ppc_dcbzl_szB = 0;
+ vai->arm64_dMinLine_lg2_szB = 0;
+ vai->arm64_iMinLine_lg2_szB = 0;
+ vai->arm64_cache_block_size = 0;
+ vai->arm64_data_zero_prohibited = 0;
vai->arm64_requires_fallback_LLSC = False;
- vai->hwcache_info.num_levels = 0;
- vai->hwcache_info.num_caches = 0;
- vai->hwcache_info.caches = NULL;
+ vai->hwcache_info.num_levels = 0;
+ vai->hwcache_info.num_caches = 0;
+ vai->hwcache_info.caches = NULL;
vai->hwcache_info.icaches_maintain_coherence = True; // whatever
}
UInt arm64_dMinLine_lg2_szB;
UInt arm64_iMinLine_lg2_szB;
UChar arm64_cache_block_size;
+ /* ARM64 DCZID_EL0 bit 4 (DZP) means that
+ * use of DC ZVA is prohibited and should produce SIGILL */
+ Bool arm64_data_zero_prohibited;
/* ARM64: does the host require us to use the fallback LLSC
implementation? */
Bool arm64_requires_fallback_LLSC;
#if defined(VGA_arm64)
unsigned long val;
asm volatile("mrs %0, dczid_el0" : "=r" (val));
- val &= 0xf;
// The ARM manual says that 4 bits are used but 9 is the maximum
- vg_assert(val <= 9);
- vai->arm64_cache_block_size = val;
+ vai->arm64_cache_block_size = val & 0xf;
+ vg_assert(vai->arm64_cache_block_size <= 9);
+ vai->arm64_data_zero_prohibited = !!(val & 0x10);
#endif
vai->hwcache_info.icaches_maintain_coherence = False;