Skip to content

Commit

Permalink
i#1569 AArch64: Enable -steal_reg_at_reset for AArch64
Browse files Browse the repository at this point in the history
Enables the diagnostic option -steal_reg_at_reset for AArch64,
generalizing the existing ARM code.

Switches -reset_at_fragment_count to work in release build by using
the sum of the release stats num_bbs and num_traces.

Adds a release-build syslog for an informational notification when any
reset occurs.

Adds a test of -steal_reg_at_reset.

Issue: #1569
  • Loading branch information
derekbruening committed Oct 29, 2020
1 parent 6dea756 commit 01280f8
Show file tree
Hide file tree
Showing 6 changed files with 44 additions and 21 deletions.
11 changes: 8 additions & 3 deletions core/arch/arch.c
Original file line number Diff line number Diff line change
Expand Up @@ -593,26 +593,31 @@ arch_reset_stolen_reg(void)
* shared_code, which means we do not need to update each thread's pointers
* to gencode stored in TLS.
*/
# ifdef ARM
dr_isa_mode_t old_mode;
# endif
dcontext_t *dcontext;
# ifdef AARCH64
ASSERT_NOT_IMPLEMENTED(false); /* FIXME i#1569 */
# endif
if (DR_REG_R0 + INTERNAL_OPTION(steal_reg_at_reset) == dr_reg_stolen)
return;
SYSLOG_INTERNAL_INFO("swapping stolen reg from %s to %s", reg_names[dr_reg_stolen],
reg_names[DR_REG_R0 + INTERNAL_OPTION(steal_reg_at_reset)]);
dcontext = get_thread_private_dcontext();
ASSERT(dcontext != NULL);
# ifdef ARM
dr_set_isa_mode(dcontext, DR_ISA_ARM_THUMB, &old_mode);
# endif

SELF_UNPROTECT_DATASEC(DATASEC_RARELY_PROT);
dr_reg_stolen = DR_REG_R0 + INTERNAL_OPTION(steal_reg_at_reset);
ASSERT(dr_reg_stolen >= DR_REG_STOLEN_MIN && dr_reg_stolen <= DR_REG_STOLEN_MAX);
protect_generated_code(shared_code, WRITABLE);
shared_gencode_emit(shared_code);
protect_generated_code(shared_code, READONLY);
SELF_PROTECT_DATASEC(DATASEC_RARELY_PROT);

# ifdef ARM
dr_set_isa_mode(dcontext, old_mode, NULL);
# endif
DOLOG(3, LOG_EMIT, {
dump_emitted_routines(GLOBAL_DCONTEXT, GLOBAL, "swap stolen reg", shared_code,
shared_code->gen_end_pc);
Expand Down
12 changes: 7 additions & 5 deletions core/fcache.c
Original file line number Diff line number Diff line change
Expand Up @@ -4228,10 +4228,12 @@ fcache_reset_all_caches_proactively(uint target)

LOG(GLOBAL, LOG_CACHE, 2,
"fcache_reset_all_caches_proactively: walking the threads\n");
DOSTATS({
SYSLOG_INTERNAL_INFO("proactive reset @ %d fragments",
GLOBAL_STAT(num_fragments));
});
char buf[16];
snprintf(buf, BUFFER_SIZE_ELEMENTS(buf), "%d",
GLOBAL_STAT(num_bbs) + GLOBAL_STAT(num_traces));
NULL_TERMINATE_BUFFER(buf);
SYSLOG(SYSLOG_INFORMATION, INFO_RESET_IN_PROGRESS, 3, buf, get_application_name(),
get_application_pid());

/* reset_free and reset_init may write to .data.
* All threads are suspended so no security risk.
Expand All @@ -4241,7 +4243,7 @@ fcache_reset_all_caches_proactively(uint target)
/* no lock needed */
dynamo_resetting = true;

IF_ARM({
IF_AARCHXX({
if (INTERNAL_OPTION(steal_reg_at_reset) != 0)
arch_reset_stolen_reg();
});
Expand Down
18 changes: 7 additions & 11 deletions core/fragment.c
Original file line number Diff line number Diff line change
Expand Up @@ -2403,17 +2403,13 @@ fragment_create(dcontext_t *dcontext, app_pc tag, int body_size, int direct_exit
if (!fragment_lookup_deleted(dcontext, tag) && !TEST(FRAG_COARSE_GRAIN, flags))
STATS_INC(num_unique_fragments);
});
/* FIXME: make fragment count a release-build stat so we can do this in
* release builds
*/
DOSTATS({
if (d_r_stats != NULL &&
(uint)GLOBAL_STAT(num_fragments) ==
INTERNAL_OPTION(reset_at_fragment_count)) {
ASSERT(INTERNAL_OPTION(reset_at_fragment_count) != 0);
schedule_reset(RESET_ALL);
}
});
if (d_r_stats != NULL &&
/* num_fragments is debug-only so we use the two release-build stats. */
(uint)GLOBAL_STAT(num_bbs) + GLOBAL_STAT(num_traces) ==
INTERNAL_OPTION(reset_at_fragment_count)) {
ASSERT(INTERNAL_OPTION(reset_at_fragment_count) != 0);
schedule_reset(RESET_ALL);
}
DODEBUG({
if ((uint)GLOBAL_STAT(num_fragments) == INTERNAL_OPTION(log_at_fragment_count)) {
/* we started at loglevel 1 and now we raise to the requested level */
Expand Down
6 changes: 4 additions & 2 deletions core/synch.c
Original file line number Diff line number Diff line change
Expand Up @@ -1714,7 +1714,7 @@ translate_from_synchall_to_dispatch(thread_record_t *tr, thread_synch_state_t sy
free_cxt = false;
}
#endif
IF_ARM({
IF_AARCHXX({
if (INTERNAL_OPTION(steal_reg_at_reset) != 0) {
/* We don't want to translate, just update the stolen reg values */
arch_mcontext_reset_stolen_reg(dcontext, mc);
Expand All @@ -1741,7 +1741,7 @@ translate_from_synchall_to_dispatch(thread_record_t *tr, thread_synch_state_t sy
}
LOG(GLOBAL, LOG_CACHE, 2, "\ttranslation pc = " PFX "\n", mc->pc);
ASSERT(!is_dynamo_address((app_pc)mc->pc) && !in_fcache((app_pc)mc->pc));
IF_ARM({
IF_AARCHXX({
if (INTERNAL_OPTION(steal_reg_at_reset) != 0) {
/* XXX: do we need this? Will signal.c will fix it up prior
* to sigreturn from suspend handler?
Expand Down Expand Up @@ -1815,6 +1815,8 @@ translate_from_synchall_to_dispatch(thread_record_t *tr, thread_synch_state_t sy
*/
mc->pc = (app_pc)get_reset_exit_stub(dcontext);
LOG(GLOBAL, LOG_CACHE, 2, "\tsent to reset exit stub " PFX "\n", mc->pc);
/* TODO i#4497: Replace with the official fix from PR#4498. */
IF_AARCHXX(set_stolen_reg_val(mc, (reg_t)os_get_dr_tls_base(dcontext)));
#ifdef WINDOWS
/* i#25: we could have interrupted thread in DR, where has priv fls data
* in TEB, and fcache_return blindly copies into app fls: so swap to app
Expand Down
7 changes: 7 additions & 0 deletions core/win32/events.mc
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,13 @@ Language=English
Attached to %1!s! threads in application %2!s! (%3!s!)
.
MessageId =
Severity = Informational
Facility = DRCore
SymbolicName = MSG_INFO_RESET_IN_PROGRESS
Language=English
Resetting caches and non-persistent memory @ %1!s! fragments in application %2!s! (%3!s!).
;//;;;;;;;;;;;;;;;;;;; Security
MessageId =
Expand Down
11 changes: 11 additions & 0 deletions suite/tests/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4073,6 +4073,17 @@ if (UNIX)
"-enable_reset -reset_at_fragment_count 100" "")
torunonly(linux.clone-reset linux.clone linux/clone.c
"-enable_reset -reset_at_fragment_count 100" "")
if (AARCHXX)
# Test our diagnostic option -steal_reg_at_reset, which is also a stress
# test of reset and register stealing.
if (ARM)
set(new_reg 9)
else ()
set(new_reg 29)
endif ()
torunonly(linux.steal-switch linux.thread linux/thread.c
"-enable_reset -reset_at_fragment_count 100 -steal_reg_at_reset ${new_reg}" "")
endif ()
tobuild(pthreads.pthreads pthreads/pthreads.c)
tobuild(pthreads.pthreads_exit pthreads/pthreads_exit.c)
tobuild(pthreads.ptsig pthreads/ptsig.c)
Expand Down

0 comments on commit 01280f8

Please sign in to comment.