Skip to content

Commit

Permalink
i#1551 port to ARM: fix TLS swapping bugs
Browse files Browse the repository at this point in the history
Fixes bugs in os_switch_seg_to_context() where it had priv and app mixed up
and on swapping back to DR had the wrong temp var value.

Adds more logging of all the base TLS values.

Review-URL: https://codereview.appspot.com/215890043
  • Loading branch information
derekbruening committed Mar 12, 2015
1 parent cf22490 commit 17e2b7b
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 16 deletions.
2 changes: 1 addition & 1 deletion core/unix/loader.c
Original file line number Diff line number Diff line change
Expand Up @@ -1205,7 +1205,7 @@ privload_tls_init(void *app_tp)
ASSERT(TLS_PRE_TCB_SIZE == LIBC_PTHREAD_SIZE);
ASSERT(LIBC_PTHREAD_TID_OFFSET == offsetof(dr_pthread_t, tid));
#endif
LOG(GLOBAL, LOG_LOADER, 2, "%s: allocates %d at "PFX"\n",
LOG(GLOBAL, LOG_LOADER, 2, "%s: allocated %d at "PFX"\n",
__FUNCTION__, max_client_tls_size, dr_tp);
dr_tp = dr_tp + max_client_tls_size - tcb_size;
dr_tcb = (tcb_head_t *) dr_tp;
Expand Down
41 changes: 32 additions & 9 deletions core/unix/os.c
Original file line number Diff line number Diff line change
Expand Up @@ -1386,9 +1386,11 @@ os_set_app_tls_base(dcontext_t *dcontext, reg_id_t reg, void *base)
os_tls = get_os_tls_from_dc(dcontext);
if (reg == TLS_REG_LIB) {
os_tls->app_lib_tls_base = base;
LOG(THREAD, LOG_THREADS, 1, "TLS app lib base ="PFX"\n", base);
return true;
} else if (reg == TLS_REG_ALT) {
os_tls->app_alt_tls_base = base;
LOG(THREAD, LOG_THREADS, 1, "TLS app alt base ="PFX"\n", base);
return true;
}
ASSERT_NOT_REACHED();
Expand Down Expand Up @@ -1670,6 +1672,7 @@ os_tls_init(void)
os_local_state_t *os_tls = (os_local_state_t *) segment;

LOG(GLOBAL, LOG_THREADS, 1, "os_tls_init for thread "TIDFMT"\n", get_thread_id());
ASSERT(!is_thread_tls_initialized());

/* MUST zero out dcontext slot so uninit access gets NULL */
memset(segment, 0, PAGE_SIZE);
Expand Down Expand Up @@ -1883,6 +1886,13 @@ os_thread_init(dcontext_t *dcontext)
ostd->priv_lib_tls_base = os_tls->os_seg_info.priv_lib_tls_base;
ostd->priv_alt_tls_base = os_tls->os_seg_info.priv_alt_tls_base;
ostd->dr_tls_base = os_tls->os_seg_info.dr_tls_base;

LOG(THREAD, LOG_THREADS, 1, "TLS app lib base ="PFX"\n", os_tls->app_lib_tls_base);
LOG(THREAD, LOG_THREADS, 1, "TLS app alt base ="PFX"\n", os_tls->app_alt_tls_base);
LOG(THREAD, LOG_THREADS, 1, "TLS priv lib base ="PFX"\n", ostd->priv_lib_tls_base);
LOG(THREAD, LOG_THREADS, 1, "TLS priv alt base ="PFX"\n", ostd->priv_alt_tls_base);
LOG(THREAD, LOG_THREADS, 1, "TLS DynamoRIO base="PFX"\n", ostd->dr_tls_base);

#ifdef X86
if (INTERNAL_OPTION(mangle_app_seg)) {
ostd->app_thread_areas =
Expand All @@ -1894,10 +1904,10 @@ os_thread_init(dcontext_t *dcontext)
}
#endif

LOG(THREAD, LOG_THREADS, 1, "cur %s base is "PFX"\n",
LOG(THREAD, LOG_THREADS, 1, "post-TLS-setup, cur %s base is "PFX"\n",
IF_X86_ELSE("gs", "tpidruro"),
get_segment_base(IF_X86_ELSE(SEG_GS, DR_REG_TPIDRURO)));
LOG(THREAD, LOG_THREADS, 1, "cur %s base is "PFX"\n",
LOG(THREAD, LOG_THREADS, 1, "post-TLS-setup, cur %s base is "PFX"\n",
IF_X86_ELSE("fs", "tpidrurw"),
get_segment_base(IF_X86_ELSE(SEG_FS, DR_REG_TPIDRURW)));

Expand Down Expand Up @@ -5592,31 +5602,44 @@ os_switch_seg_to_context(dcontext_t *dcontext, reg_id_t seg, bool to_app)
* The app's TLS slot value is stored into privlib's TLS slot for
* later restore on switching back to privlib's TLS.
*/
byte **app_lib_tls_swap_slot = (byte **)
(os_tls->os_seg_info.priv_lib_tls_base + DR_TLS_BASE_OFFSET);
byte **priv_lib_tls_swap_slot = (byte **)
(os_tls->os_seg_info.priv_lib_tls_base + DR_TLS_BASE_OFFSET);
byte **app_lib_tls_swap_slot = (byte **)
(os_tls->app_lib_tls_base + DR_TLS_BASE_OFFSET);
LOG(THREAD, LOG_LOADER, 3,
"%s: switching to app: app slot=&"PFX" *"PFX", priv slot=&"PFX" *"PFX"\n",
__FUNCTION__, app_lib_tls_swap_slot, *app_lib_tls_swap_slot,
priv_lib_tls_swap_slot, *priv_lib_tls_swap_slot);
byte *dr_tls_base = *priv_lib_tls_swap_slot;
*priv_lib_tls_swap_slot = *app_lib_tls_swap_slot;
*app_lib_tls_swap_slot = dr_tls_base;
LOG(THREAD, LOG_LOADER, 2, "%s: switching to %s, setting coproc reg to 0x%x\n",
__FUNCTION__, (to_app ? "app" : "dr"), os_tls->app_lib_tls_base);
res = dynamorio_syscall(SYS_set_tls, 1, os_tls->app_lib_tls_base) == 0;
} else {
/* Restore the app's TLS slot that we used for storing DR's TLS base,
* and put DR's TLS base back to privlib's TLS slot.
*/
byte **app_lib_tls_swap_slot = (byte **)
(os_tls->os_seg_info.priv_lib_tls_base + DR_TLS_BASE_OFFSET);
byte **priv_lib_tls_swap_slot = (byte **)
(os_tls->os_seg_info.priv_lib_tls_base + DR_TLS_BASE_OFFSET);
byte **app_lib_tls_swap_slot = (byte **)
(os_tls->app_lib_tls_base + DR_TLS_BASE_OFFSET);
byte *dr_tls_base = *priv_lib_tls_swap_slot;
byte *dr_tls_base = *app_lib_tls_swap_slot;
LOG(THREAD, LOG_LOADER, 3,
"%s: switching to DR: app slot=&"PFX" *"PFX", priv slot=&"PFX" *"PFX"\n",
__FUNCTION__, app_lib_tls_swap_slot, *app_lib_tls_swap_slot,
priv_lib_tls_swap_slot, *priv_lib_tls_swap_slot);
*app_lib_tls_swap_slot = *priv_lib_tls_swap_slot;
*priv_lib_tls_swap_slot = dr_tls_base;
LOG(THREAD, LOG_LOADER, 2, "%s: switching to %s, setting coproc reg to 0x%x\n",
__FUNCTION__, (to_app ? "app" : "dr"),
os_tls->os_seg_info.priv_lib_tls_base);
res = dynamorio_syscall(SYS_set_tls, 1,
os_tls->os_seg_info.priv_lib_tls_base) == 0;
}
LOG(THREAD, LOG_LOADER, 2,
"%s %s: set_tls swap successful for thread "TIDFMT"\n",
__FUNCTION__, to_app ? "to app" : "to DR", get_thread_id());
"%s %s: set_tls swap success=%d for thread "TIDFMT"\n",
__FUNCTION__, to_app ? "to app" : "to DR", res, get_thread_id());
#endif /* X86/ARM */
return res;
}
Expand Down
12 changes: 6 additions & 6 deletions core/unix/tls_linux_arm.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/* *******************************************************************************
* Copyright (c) 2014 Google, Inc. All rights reserved.
* Copyright (c) 2014-2015 Google, Inc. All rights reserved.
* *******************************************************************************/

/*
Expand Down Expand Up @@ -65,12 +65,12 @@ tls_thread_init(os_local_state_t *os_tls, byte *segment)
{
ASSERT((byte *)(os_tls->self) == segment);
LOG(GLOBAL, LOG_THREADS, 2,
"tls_thread_init: cur priv lib tls base is"PFX"\n",
"tls_thread_init: cur priv lib tls base is "PFX"\n",
os_tls->os_seg_info.priv_lib_tls_base);
dynamorio_syscall(SYS_set_tls, 1, os_tls->os_seg_info.priv_lib_tls_base);
ASSERT(get_segment_base(TLS_REG_LIB) == os_tls->os_seg_info.priv_lib_tls_base);
ASSERT(*get_dr_tls_base_addr() == NULL);
*get_dr_tls_base_addr() = segment;
dynamorio_syscall(SYS_set_tls, 1, os_tls->os_seg_info.priv_lib_tls_base);
ASSERT(get_segment_base(TLS_REG_LIB) == os_tls->os_seg_info.priv_lib_tls_base);
ASSERT(*get_dr_tls_base_addr() == NULL);
*get_dr_tls_base_addr() = segment;
os_tls->tls_type = TLS_TYPE_SLOT;
}

Expand Down

0 comments on commit 17e2b7b

Please sign in to comment.