Skip to content

Commit

Permalink
dynamorio: adopt better patch for fp saving issue
Browse files Browse the repository at this point in the history
  • Loading branch information
ndrewh committed Aug 19, 2024
1 parent 5299ff5 commit fb8fcda
Showing 1 changed file with 33 additions and 174 deletions.
207 changes: 33 additions & 174 deletions patches/dynamorio-10.0.patch
Original file line number Diff line number Diff line change
@@ -1,100 +1,3 @@
diff --git a/api/samples/memtrace_x86.c b/api/samples/memtrace_x86.c
index 4e726c5b2..b229086bf 100644
--- a/api/samples/memtrace_x86.c
+++ b/api/samples/memtrace_x86.c
@@ -260,6 +260,20 @@ event_thread_exit(void *drcontext)

memtrace(drcontext);
data = drmgr_get_tls_field(drcontext, tls_index);
+
+#ifdef OUTPUT_TEXT
+ const char *dump_modules[0x4] = { "libc.so.6", "daydream", "ld-linux-x86-64.so.2", NULL };
+ for (int i = 0; i < 0x4; i++) {
+ if (dump_modules[i] == NULL) break;
+ module_data_t *mod = dr_lookup_module_by_name(dump_modules[i]);
+ if (mod) {
+ fprintf(data->logf, "BASE %s %p %p\n", dump_modules[i], mod->start, mod->end);
+ } else {
+ fprintf(data->logf, "Could not get base for %s\n", dump_modules[i]);
+ }
+ }
+#endif
+
dr_mutex_lock(mutex);
global_num_refs += data->num_refs;
dr_mutex_unlock(mutex);
diff --git a/core/arch/interp.c b/core/arch/interp.c
index dc786a904..80e350399 100644
--- a/core/arch/interp.c
+++ b/core/arch/interp.c
@@ -2700,6 +2700,8 @@ client_check_syscall(instrlist_t *ilist, instr_t *inst, bool *found_syscall,
return true;
}

+void print_xmm0(int);
+
/* Pass bb to client, and afterward check for criteria we require and rescan for
* eflags and other flags that might have changed.
* Returns true normally; returns false to indicate "go native".
@@ -2707,6 +2709,7 @@ client_check_syscall(instrlist_t *ilist, instr_t *inst, bool *found_syscall,
static bool
client_process_bb(dcontext_t *dcontext, build_bb_t *bb)
{
+
dr_emit_flags_t emitflags = DR_EMIT_DEFAULT;
instr_t *inst;
bool found_exit_cti = false;
@@ -5110,6 +5113,7 @@ build_basic_block_fragment(dcontext_t *dcontext, app_pc start, uint initial_flag
KSTART(bb_building);
dcontext->whereami = DR_WHERE_INTERP;

+
/* Neither thin_client nor hotp_only should be building any bbs. */
ASSERT(!RUNNING_WITHOUT_CODE_CACHE());

@@ -5118,7 +5122,10 @@ build_basic_block_fragment(dcontext_t *dcontext, app_pc start, uint initial_flag
*/
image_entry = check_for_image_entry(start);

+
init_interp_build_bb(dcontext, &bb, start, initial_flags, for_trace, unmangled_ilist);
+
+
if (at_native_exec_gateway(dcontext, start,
&bb.native_call _IF_DEBUG(false /*not xfer tgt*/))) {
DODEBUG({ report_native_module(dcontext, bb.start_pc); });
@@ -5161,11 +5168,13 @@ build_basic_block_fragment(dcontext_t *dcontext, app_pc start, uint initial_flag
jitopt_add_dgc_bb(bb.start_pc, bb.end_pc, TEST(FRAG_IS_TRACE_HEAD, bb.flags));
}

+
/* emit fragment into fcache */
KSTART(bb_emit);
f = emit_fragment_ex(dcontext, start, bb.ilist, bb.flags, bb.vmlist, link, visible);
KSTOP(bb_emit);

+
#ifdef CUSTOM_TRACES_RET_REMOVAL
f->num_calls = dcontext->num_calls;
f->num_rets = dcontext->num_rets;
diff --git a/core/dispatch.c b/core/dispatch.c
index 37e6bb531..c91394ea9 100644
--- a/core/dispatch.c
+++ b/core/dispatch.c
@@ -121,6 +121,13 @@ exited_due_to_ni_syscall(dcontext_t *dcontext)
return false;
}

+void print_xmm0(int id) {
+ unsigned long xmm0, xmm1;
+ asm volatile("movq %%xmm0, %0" : "=r" (xmm0));
+ asm volatile("movq %%xmm1, %0" : "=r" (xmm1));
+ dr_fprintf(STDERR, "xmm0 @ %d: %lx, xmm1: %lx\n", id, xmm0, xmm1);
+ dr_flush_file(STDERR);
+}
/* This is the central hub of control management in DynamoRIO.
* It is entered with a clean dstack at startup and after every cache
* exit, whether normal or kernel-mediated via a trampoline context switch.
diff --git a/core/heap.c b/core/heap.c
index 8a0c440cf..f596108da 100644
--- a/core/heap.c
Expand All @@ -108,42 +11,6 @@ index 8a0c440cf..f596108da 100644
});
#endif

diff --git a/core/ir/disassemble_shared.c b/core/ir/disassemble_shared.c
index 19241476c..778b0532f 100644
--- a/core/ir/disassemble_shared.c
+++ b/core/ir/disassemble_shared.c
@@ -611,6 +611,13 @@ print_known_pc_target(char *buf, size_t bufsz, size_t *sofar INOUT, dcontext_t *
return printed;
}

+static void double_print2(opnd_t opnd, uint *top, uint *bottom, const char **sign, bool double_type) {
+ if (double_type)
+ double_print(opnd_get_immed_double(opnd), 6, top, bottom, sign);
+ else
+ double_print(opnd_get_immed_float(opnd), 6, top, bottom, sign);
+}
+
void
internal_opnd_disassemble(char *buf, size_t bufsz, size_t *sofar INOUT,
dcontext_t *dcontext, opnd_t opnd, bool use_size_sfx)
@@ -667,7 +674,7 @@ internal_opnd_disassemble(char *buf, size_t bufsz, size_t *sofar INOUT,
uint top;
uint bottom;
const char *sign;
- double_print(opnd_get_immed_float(opnd), 6, &top, &bottom, &sign);
+ double_print2(opnd, &top, &bottom, &sign, false);
print_to_buffer(buf, bufsz, sofar, "%s%s%u.%.6u", immed_prefix(), sign, top,
bottom);
});
@@ -683,7 +690,7 @@ internal_opnd_disassemble(char *buf, size_t bufsz, size_t *sofar INOUT,
uint top;
uint bottom;
const char *sign;
- double_print(opnd_get_immed_double(opnd), 6, &top, &bottom, &sign);
+ double_print2(opnd, &top, &bottom, &sign, true);
print_to_buffer(buf, bufsz, sofar, "%s%s%u.%.6u", immed_prefix(), sign, top,
bottom);
});
diff --git a/core/lib/dr_tools.h b/core/lib/dr_tools.h
index efbb1c636..b7ab5d060 100644
--- a/core/lib/dr_tools.h
Expand Down Expand Up @@ -378,7 +245,7 @@ index f5eef1e5c..91f5a16bd 100644
/* grab all_threads_synch_lock */
/* since all_threads synch doesn't give any permissions this is necessary
diff --git a/core/unix/loader.c b/core/unix/loader.c
index 10c4518b0..37aa2aa0c 100644
index 10c4518b0..b27284a8e 100644
--- a/core/unix/loader.c
+++ b/core/unix/loader.c
@@ -158,7 +158,7 @@ privload_locate_and_load(const char *impname, privmod_t *dependent, bool reachab
Expand Down Expand Up @@ -489,13 +356,10 @@ index 10c4518b0..37aa2aa0c 100644
{ "dlsym", (app_pc)redirect_dlsym },
/* We need these for clients that don't use libc (i#1747) */
{ "strlen", (app_pc)strlen },
@@ -1569,7 +1577,15 @@ static const redirect_import_t redirect_imports[] = {
@@ -1569,7 +1577,12 @@ static const redirect_import_t redirect_imports[] = {
{ "memset_chk", (app_pc)memset },
{ "memmove_chk", (app_pc)memmove },
{ "strncpy_chk", (app_pc)strncpy },
+ { "__memcpy_chk", (app_pc)memcpy },
+ { "__memset_chk", (app_pc)memset },
+ { "__memmove_chk", (app_pc)memmove },
+ /* { "__errno_location", (app_pc)__errno_location } */
};
+
Expand All @@ -505,7 +369,7 @@ index 10c4518b0..37aa2aa0c 100644
#define REDIRECT_IMPORTS_NUM (sizeof(redirect_imports) / sizeof(redirect_imports[0]))

#ifdef DEBUG
@@ -1599,6 +1615,15 @@ privload_redirect_sym(os_privmod_data_t *opd, ptr_uint_t *r_addr, const char *na
@@ -1599,6 +1612,15 @@ privload_redirect_sym(os_privmod_data_t *opd, ptr_uint_t *r_addr, const char *na
}
}
#endif
Expand Down Expand Up @@ -817,14 +681,14 @@ index d98df70db..f106ce611 100644
bool
privload_redirect_sym(os_privmod_data_t *opd, ptr_uint_t *r_addr, const char *name);
diff --git a/core/unix/os.c b/core/unix/os.c
index d5133bf16..0efaa2140 100644
index d5133bf16..106d0672a 100644
--- a/core/unix/os.c
+++ b/core/unix/os.c
@@ -3761,8 +3761,13 @@ os_thread_sleep(uint64 milliseconds)
/* not unusual for client threads to use itimers and have their run
* routine sleep forever
*/
+
+
if (count++ > 3 && !IS_CLIENT_THREAD(get_thread_private_dcontext())) {
- ASSERT_NOT_REACHED();
+ // ATH: We are hitting this case in release builds, and it seems to be breaking
Expand Down Expand Up @@ -869,43 +733,38 @@ index 4d3b9e60f..4ce713450 100644

int
diff --git a/core/unix/signal.c b/core/unix/signal.c
index 0cbc94337..a73aa85bf 100644
index 0cbc94337..51ef52f80 100644
--- a/core/unix/signal.c
+++ b/core/unix/signal.c
@@ -3197,12 +3197,12 @@ thread_set_self_context(void *cxt)
dcontext_t *dcontext = get_thread_private_dcontext();
@@ -3193,20 +3193,10 @@ thread_set_self_context(void *cxt)
ASSERT_NOT_IMPLEMENTED(false); /* PR 405694: can't use regular sigreturn! */
#endif
memset(&frame, 0, sizeof(frame));
-#if defined(X86)
- dcontext_t *dcontext = get_thread_private_dcontext();
-#endif
#ifdef LINUX
+ frame.uc.uc_mcontext = *sc;
# ifdef X86
-# ifdef X86
- byte *xstate = get_and_initialize_xstate_buffer(dcontext);
- frame.uc.uc_mcontext.fpstate = &((kernel_xstate_t *)xstate)->fpstate;
+ frame.uc.uc_mcontext.fpstate = (void*)get_and_initialize_xstate_buffer(dcontext);
# endif /* X86 */
- frame.uc.uc_mcontext = *sc;
-#endif
+#endif /* inlux*/
+
-# endif /* X86 */
frame.uc.uc_mcontext = *sc;
#endif
IF_ARM(ASSERT_NOT_TESTED());
#if defined(X86)
save_fpstate(dcontext, &frame);
@@ -8552,15 +8552,19 @@ handle_suspend_signal(dcontext_t *dcontext, kernel_siginfo_t *siginfo,
dcontext->whereami = prior_whereami;

if (ostd->retakeover) {
+ LOG(THREAD, LOG_ASYNCH, 2, "->retakeover\n");
ostd->retakeover = false;
sig_take_over(ucxt); /* shouldn't return for this case */
ASSERT_NOT_REACHED();
} else if (ostd->do_detach) {
+ LOG(THREAD, LOG_ASYNCH, 2, "->do_detach\n");
ostd->do_detach = false;
sig_detach(dcontext, frame, &ostd->detached); /* no return */
ASSERT_NOT_REACHED();
}

+ LOG(THREAD, LOG_ASYNCH, 2, "->return\n");
+
return false; /* do not pass to app */
}

-#if defined(X86)
- save_fpstate(dcontext, &frame);
-#endif
/* The kernel calls do_sigaltstack on sys_rt_sigreturn primarily to ensure
* the frame is ok, but the side effect is we can mess up our own altstack
* settings if we're not careful. Having invalid ss_size looks good for
@@ -3295,7 +3285,9 @@ thread_set_self_mcontext(priv_mcontext_t *mc)
sig_full_cxt_t sc_full;
sig_full_initialize(&sc_full, &ucxt);
#if defined(LINUX) && defined(X86)
- sc_full.sc->fpstate = NULL; /* for mcontext_to_sigcontext */
+ /* for mcontext_to_sigcontext to fill in with saved fp state */
+ sc_full.sc->fpstate = (kernel_fpstate_t *)get_and_initialize_xstate_buffer(
+ get_thread_private_dcontext());
#endif
mcontext_to_sigcontext(&sc_full, mc, DR_MC_ALL);
thread_set_segment_registers(sc_full.sc);

0 comments on commit fb8fcda

Please sign in to comment.