Skip to content

Commit

Permalink
i#4474: Port client.flush and client.cbr-retarget tests to AARCH64
Browse files Browse the repository at this point in the history
Issue: #4474
  • Loading branch information
philramsey-arm committed Jun 18, 2024
1 parent 3af401b commit 9db33a3
Show file tree
Hide file tree
Showing 4 changed files with 53 additions and 24 deletions.
8 changes: 5 additions & 3 deletions suite/tests/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2641,9 +2641,9 @@ if (UNIX)
tobuild_ci(client.signal client-interface/signal.c "" "" "")
link_with_pthread(client.signal)
endif ()
if (X86) # FIXME i#1551, i#1569: port asm to ARM and AArch64
if (X86 OR AARCH64) # FIXME i#1551: port asm to ARM
tobuild_ci(client.cbr-retarget client-interface/cbr-retarget.c "" "" "")
endif (X86)
endif (X86 OR AARCH64)
tobuild_ci(client.cleancallsig client-interface/cleancallsig.c "" "" "")
if (X64 AND NOT RISCV64) # XXX i#3173 Improve testing of emulation API functions
# TODO i#3544: Port tests to RISC-V 64
Expand Down Expand Up @@ -2687,11 +2687,13 @@ if (NOT APPLE OR NOT AARCH64) # TODO i#5383: Port to Mac M1.
tobuild_ci(client.file_io client-interface/file_io.c
"${CMAKE_CURRENT_SOURCE_DIR}/client-interface/file_io_data.txt" "" "")
endif ()
if (X86) # FIXME i#1551, i#1569: port asm to ARM and AArch64
if (X86 OR AARCH64) # FIXME i#1551: port asm to ARM
if (DEBUG) # FIXME i#1806: fails in release; also in OSX list below.
# we add custom option to flush test based on dr ops in torun_ci()
tobuild_ci(client.flush client-interface/flush.c "" "" "")
endif ()
endif ()
if (X86) # FIXME i#1551, i#1569: port asm to ARM and AArch64
tobuild_ci(client.thread client-interface/thread.c "-paramx -paramy" "" "")
tobuild_appdll(client.thread client-interface/thread.c)
tobuild_ci(client.strace client-interface/strace.c "" "" "")
Expand Down
4 changes: 4 additions & 0 deletions suite/tests/client-interface/cbr-retarget.c
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,10 @@ main(void)
skip:
}
;
#elif defined(AARCH64)
__asm("cbnz xzr, skip");
__asm("bl foo");
__asm("skip:");
#else
__asm("movl $0x0, %ecx");
__asm("cmp $0x0, %ecx");
Expand Down
7 changes: 7 additions & 0 deletions suite/tests/client-interface/flush.c
Original file line number Diff line number Diff line change
Expand Up @@ -74,9 +74,16 @@ main()
START_FILE
DECLARE_FUNC(marker)
GLOBAL_LABEL(marker:)
#ifdef X86
nop
xchg REG_XBP, REG_XBP
ret
#elif defined (AARCH64)
nop
yield
yield
ret
#endif
END_FUNC(marker)
END_FILE
/* clang-format on */
Expand Down
58 changes: 37 additions & 21 deletions suite/tests/client-interface/flush.dll.c
Original file line number Diff line number Diff line change
Expand Up @@ -241,6 +241,34 @@ module_load_event(void *dcontext, const module_data_t *data, bool loaded)
}
#endif

static bool
check_for_marker(instr_t *first_inst)
{
if (instr_is_nop(first_inst)) {
instr_t *second = instr_get_next(first_inst);

if (second != NULL) {
#ifdef X86
/* The test app uses two nops as a marker to identify a specific bb. Since
* 2 nop instructions in a row aren't that uncommon on Linux (where we can't
* restrict our search to just the test.exe module) we use an unusual nop
* for the second one: xchg xbp, xbp */
if (instr_is_nop(second) && instr_get_opcode(second) == OP_xchg &&
instr_writes_to_exact_reg(second, REG_XBP, DR_QUERY_DEFAULT))
return true;
#elif defined(AARCH64)
/* For AARCH64 look for a nop followed by two yield instructions */
if (instr_get_opcode(second) == OP_yield) {
instr_t *third = instr_get_next(second);
if (third != NULL && instr_get_opcode(third) == OP_yield)
return true;
}
#endif
}
}
return false;
}

static dr_emit_flags_t
bb_event(void *drcontext, void *tag, instrlist_t *bb, bool for_trace, bool translating)
{
Expand All @@ -256,29 +284,17 @@ bb_event(void *drcontext, void *tag, instrlist_t *bb, bool for_trace, bool trans
#endif
instr = instrlist_first(bb);

if (instr_is_nop(instr)) {
instr_t *next = instr_get_next(instr);

/* The test app uses two nops as a marker to identify a specific bb. Since
* 2 nop instructions in a row aren't that uncommon on Linux (where we can't
* restrict our search to just the test.exe module) we use an unusual nop
* for the second one: xchg xbp, xbp */
if (next != NULL && instr_is_nop(next) && instr_get_opcode(next) == OP_xchg &&
instr_writes_to_exact_reg(next, REG_XBP, DR_QUERY_DEFAULT)) {

bb_build_count++;
if (check_for_marker(instr)) {
bb_build_count++;

if (delay_flush_at_next_build) {
delay_flush_at_next_build = false;
dr_delay_flush_region((app_pc)tag - 20, 30, callback_count,
flush_event);
}

dr_insert_clean_call_ex(drcontext, bb, instr, (void *)callback,
DR_CLEANCALL_READS_APP_CONTEXT, 2,
OPND_CREATE_INTPTR(tag),
OPND_CREATE_INTPTR(instr_get_app_pc(instr)));
if (delay_flush_at_next_build) {
delay_flush_at_next_build = false;
dr_delay_flush_region((app_pc)tag - 20, 30, callback_count, flush_event);
}

dr_insert_clean_call_ex(
drcontext, bb, instr, (void *)callback, DR_CLEANCALL_READS_APP_CONTEXT, 2,
OPND_CREATE_INTPTR(tag), OPND_CREATE_INTPTR(instr_get_app_pc(instr)));
}
#ifdef WINDOWS
}
Expand Down

0 comments on commit 9db33a3

Please sign in to comment.