Skip to content

Commit 45d2c6b

Browse files
authored
i#7585: Make -hw_cache_consistency usable on AArch64. (#7611)
There should be no change to the behaviour except when -hw_cache_consistency is specified. The sandboxing of self-modifying code, a significant piece of work, is not yet implemented. Therefore, when -hw_cache_consistency is specified, code that writes to its own page does not work correctly but other code modifications should work, including modifying code without a cache maintenance operation (issue #2055). Issue: #2055, #7585
1 parent 0215e6f commit 45d2c6b

File tree

7 files changed

+61
-23
lines changed

7 files changed

+61
-23
lines changed

core/arch/aarchxx/mangle.c

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4025,7 +4025,26 @@ mangle_exclusive_monitor_op(dcontext_t *dcontext, instrlist_t *ilist, instr_t *i
40254025
return next_instr;
40264026
}
40274027

4028-
/* END OF MANGLING ROUTINES
4028+
/* END OF CONTROL-FLOW MANGLING ROUTINES
40294029
*###########################################################################
40304030
*###########################################################################
40314031
*/
4032+
4033+
#ifdef ARCH_SUPPORTS_HW_CACHE_CONSISTENCY
4034+
/* SELF-MODIFYING-CODE SANDBOXING
4035+
*
4036+
* When we detect it, we take an exit that targets our own routine
4037+
* fragment_self_write. Dispatch checks for that target and if it
4038+
* finds it, it calls that routine, so don't worry about building a bb
4039+
* for it. Returns false if the bb has invalid instrs or CTIs and
4040+
* should be rebuilt from scratch.
4041+
*/
4042+
bool
4043+
insert_selfmod_sandbox(dcontext_t *dcontext, instrlist_t *ilist, uint flags,
4044+
app_pc start_pc, app_pc end_pc, /* end is open */
4045+
bool record_translation, bool for_cache)
4046+
{
4047+
ASSERT_NOT_IMPLEMENTED(false); /* TODO i#7585 */
4048+
return true;
4049+
}
4050+
#endif /* ARCH_SUPPORTS_HW_CACHE_CONSISTENCY */

core/arch/arch.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -749,11 +749,14 @@ mangle_far_direct_jump(dcontext_t *dcontext, instrlist_t *ilist, instr_t *instr,
749749
instr_t *next_instr, uint flags);
750750
void
751751
set_selfmod_sandbox_offsets(dcontext_t *dcontext);
752+
#endif /* X86 */
753+
754+
#ifdef ARCH_SUPPORTS_HW_CACHE_CONSISTENCY
752755
bool
753756
insert_selfmod_sandbox(dcontext_t *dcontext, instrlist_t *ilist, uint flags,
754757
app_pc start_pc, app_pc end_pc, /* end is open */
755758
bool record_translation, bool for_cache);
756-
#endif /* X86 */
759+
#endif /* ARCH_SUPPORTS_HW_CACHE_CONSISTENCY */
757760

758761
#ifdef ARM
759762
/* mangle the instruction that reads thread register */

core/arch/arch_exports.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1872,4 +1872,9 @@ typedef struct _rseq_entry_state_t {
18721872
# define DCONTEXT_TLS_TO_ACTUAL_OFFSET(x) x
18731873
#endif
18741874

1875+
/* See INTERNAL_OPTION(hw_cache_consistency). */
1876+
#if defined(AARCH64) || defined(X86)
1877+
# define ARCH_SUPPORTS_HW_CACHE_CONSISTENCY
1878+
#endif
1879+
18751880
#endif /* _ARCH_EXPORTS_H_ */

core/arch/interp.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4472,7 +4472,7 @@ expand_should_set_translation(dcontext_t *dcontext)
44724472
static bool
44734473
mangle_bb_ilist(dcontext_t *dcontext, build_bb_t *bb)
44744474
{
4475-
#ifdef X86
4475+
#ifdef ARCH_SUPPORTS_HW_CACHE_CONSISTENCY
44764476
if (TEST(FRAG_SELFMOD_SANDBOXED, bb->flags)) {
44774477
byte *selfmod_start, *selfmod_end;
44784478
/* sandbox requires that bb have no direct cti followings!
@@ -4517,7 +4517,7 @@ mangle_bb_ilist(dcontext_t *dcontext, build_bb_t *bb)
45174517
}
45184518
STATS_INC(num_sandboxed_fragments);
45194519
}
4520-
#endif /* X86 */
4520+
#endif /* ARCH_SUPPORTS_HW_CACHE_CONSISTENCY */
45214521

45224522
/* We make "before mangling" level 5 b/c there's not much there (just final jmp)
45234523
* beyond "after instrumentation".

core/arch/mangle_shared.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1957,7 +1957,8 @@ d_r_mangle(dcontext_t *dcontext, instrlist_t *ilist, uint *flags DR_PARAM_INOUT,
19571957
#endif
19581958

19591959
#ifdef AARCH64
1960-
if (instr_is_icache_op(instr) && instr_is_app(instr)) {
1960+
if (!INTERNAL_OPTION(hw_cache_consistency) && instr_is_icache_op(instr) &&
1961+
instr_is_app(instr)) {
19611962
next_instr = mangle_icache_op(dcontext, ilist, instr, next_instr,
19621963
get_app_instr_xl8(instr) + AARCH64_INSTR_SIZE);
19631964
continue;

core/dispatch.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -939,7 +939,11 @@ dispatch_enter_dynamorio(dcontext_t *dcontext)
939939
#endif
940940

941941
#ifdef AARCH64
942-
if (dcontext->last_exit == get_selfmod_linkstub()) {
942+
if (!INTERNAL_OPTION(hw_cache_consistency) &&
943+
dcontext->last_exit == get_selfmod_linkstub()) {
944+
/* Software cache consistency: we are handling an ISB
945+
* following some IC IVAU instructions.
946+
*/
943947
app_pc begin = (app_pc)dcontext->local_state->spill_space.r2;
944948
app_pc end = (app_pc)dcontext->local_state->spill_space.r3;
945949
dcontext->next_tag = (app_pc)dcontext->local_state->spill_space.r4;

core/unix/signal.c

Lines changed: 23 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -4107,29 +4107,35 @@ transfer_from_sig_handler_to_fcache_return(dcontext_t *dcontext, kernel_ucontext
41074107
*/
41084108
sc->SC_XIP = (ptr_uint_t)fcache_return_routine(dcontext);
41094109
#if defined(AARCHXX) || defined(RISCV64)
4110-
/* We do not have to set dr_reg_stolen in dcontext's mcontext here
4111-
* because dcontext's mcontext is stale and we used the mcontext
4112-
* created from recreate_app_state_internal with the original sigcontext.
4110+
/* If !is_kernel_xfer then we have come here from main_signal_handler
4111+
* via check_for_modified_code and recreate_app_state_internal was
4112+
* called with just_pc so the stolen register still points at TLS.
41134113
*/
4114-
/* We restore dr_reg_stolen's app value in recreate_app_state_internal,
4115-
* so now we need set dr_reg_stolen to hold DR's TLS before sigreturn
4116-
* from DR's handler.
4117-
*/
4118-
ASSERT(get_sigcxt_stolen_reg(sc) != (reg_t)*get_dr_tls_base_addr());
4119-
/* Preserve the translated value. */
4120-
dcontext->local_state->spill_space.reg_stolen = get_sigcxt_stolen_reg(sc);
4121-
/* Now put DR's base in the sigcontext. */
4122-
set_sigcxt_stolen_reg(sc, (reg_t)*get_dr_tls_base_addr());
4114+
if (is_kernel_xfer) {
4115+
/* We do not have to set dr_reg_stolen in dcontext's mcontext here
4116+
* because dcontext's mcontext is stale and we used the mcontext
4117+
* created from recreate_app_state_internal with the original sigcontext.
4118+
*/
4119+
/* We restore dr_reg_stolen's app value in recreate_app_state_internal,
4120+
* so now we need set dr_reg_stolen to hold DR's TLS before sigreturn
4121+
* from DR's handler.
4122+
*/
4123+
ASSERT(get_sigcxt_stolen_reg(sc) != (reg_t)*get_dr_tls_base_addr());
4124+
/* Preserve the translated value. */
4125+
dcontext->local_state->spill_space.reg_stolen = get_sigcxt_stolen_reg(sc);
4126+
/* Now put DR's base in the sigcontext. */
4127+
set_sigcxt_stolen_reg(sc, (reg_t)*get_dr_tls_base_addr());
41234128
# ifdef RISCV64
4124-
os_set_app_tls_base(dcontext, TLS_REG_LIB, (void *)get_sigcxt_tp_reg(sc));
4125-
/* Now put host tp in the sigcontext. */
4126-
set_sigcxt_tp_reg(sc, (reg_t)read_thread_register(TLS_REG_LIB));
4129+
os_set_app_tls_base(dcontext, TLS_REG_LIB, (void *)get_sigcxt_tp_reg(sc));
4130+
/* Now put host tp in the sigcontext. */
4131+
set_sigcxt_tp_reg(sc, (reg_t)read_thread_register(TLS_REG_LIB));
41274132
# endif
41284133

41294134
# ifdef ARM
4130-
/* We're going to our fcache_return gencode which uses DEFAULT_ISA_MODE */
4131-
set_pc_mode_in_cpsr(sc, DEFAULT_ISA_MODE);
4135+
/* We're going to our fcache_return gencode which uses DEFAULT_ISA_MODE */
4136+
set_pc_mode_in_cpsr(sc, DEFAULT_ISA_MODE);
41324137
# endif
4138+
}
41334139
#endif
41344140

41354141
#if defined(X64) || defined(ARM)

0 commit comments

Comments
 (0)