From 8b29dcc4be8f4f3a55543c27403f71cf33b493ec Mon Sep 17 00:00:00 2001 From: edeiana Date: Wed, 6 Mar 2024 03:40:56 -0800 Subject: [PATCH] Using x86 encode/decode for synthetic encoding/decoding through setting of instr ISA mode. --- core/ir/instr.h | 6 ++++++ core/ir/x86/decode.c | 11 +++++++++++ core/ir/x86/encode.c | 5 ++--- core/ir/x86/instr.c | 8 ++++++++ 4 files changed, 27 insertions(+), 3 deletions(-) diff --git a/core/ir/instr.h b/core/ir/instr.h index b26e83017cb..7e54a5d7ee1 100644 --- a/core/ir/instr.h +++ b/core/ir/instr.h @@ -215,6 +215,12 @@ enum { #endif /* PR 267260: distinguish our own mangling from client-added instrs */ INSTR_OUR_MANGLING = 0x80000000, + /* + * Synthetic ISA mode. + * TOFIX: we're exceeding 4 bytes, this is an issue on 32 bits arch + * where uint flags of instr_t is only 4 bytes. + */ + INSTR_SYNTH_MODE = 0x100000000, }; #define DR_TUPLE_TYPE_BITS 4 diff --git a/core/ir/x86/decode.c b/core/ir/x86/decode.c index f01137e3f4a..33fd9d37385 100644 --- a/core/ir/x86/decode.c +++ b/core/ir/x86/decode.c @@ -38,6 +38,7 @@ /* decode.c -- a full x86 decoder */ #include "../globals.h" +#include "../synthetic/decode.h" #include "arch.h" #include "instr.h" #include "decode.h" @@ -2579,6 +2580,16 @@ check_is_variable_size(opnd_t op) static byte * decode_common(dcontext_t *dcontext, byte *pc, byte *orig_pc, instr_t *instr) { + /* + * If we're dealing with decoding from synthetic ISA, we don't care about returning + * the pc of the next instruction (?), so we just write the encoding in final_pc and + * return it. + */ + if (instr_get_isa_mode(instr) == DR_ISA_SYNTH) { + decode_from_synth(dcontext, orig_pc, instr); + return orig_pc; + } + const instr_info_t *info; decode_info_t di; byte *next_pc; diff --git a/core/ir/x86/encode.c b/core/ir/x86/encode.c index 44ff55c8105..862149f24ee 100644 --- a/core/ir/x86/encode.c +++ b/core/ir/x86/encode.c @@ -2760,13 +2760,12 @@ instr_encode_arch(dcontext_t *dcontext, instr_t *instr, byte *copy_pc, byte *fin bool *has_instr_opnds /*OUT OPTIONAL*/ _IF_DEBUG(bool assert_reachable)) { - /* * If we're dealing with encoding to synthetic ISA, we don't care about returning - * the pc of the next instruction, so we just write the encoding in final_pc and + * the pc of the next instruction (?), so we just write the encoding in final_pc and * return it. */ - if (dr_get_isa_mode(dcontext) == DR_ISA_SYNTH) { + if (instr_get_isa_mode(instr) == DR_ISA_SYNTH) { encode_to_synth(dcontext, instr, final_pc); return final_pc; } diff --git a/core/ir/x86/instr.c b/core/ir/x86/instr.c index 9db609e7e81..b7a2e688f81 100644 --- a/core/ir/x86/instr.c +++ b/core/ir/x86/instr.c @@ -40,6 +40,7 @@ #include "instr.h" #include "decode.h" #include "decode_private.h" +#include "encode_api.h" #include "instr_create_shared.h" #ifdef X64 @@ -70,6 +71,10 @@ instr_get_x86_mode(instr_t *instr) bool instr_set_isa_mode(instr_t *instr, dr_isa_mode_t mode) { + if (mode == DR_ISA_SYNTH) { + instr->flags |= INSTR_SYNTH_MODE; + return true; + } #ifdef X64 if (mode == DR_ISA_IA32) instr_set_x86_mode(instr, true); @@ -87,6 +92,9 @@ instr_set_isa_mode(instr_t *instr, dr_isa_mode_t mode) dr_isa_mode_t instr_get_isa_mode(instr_t *instr) { + if (TEST(INSTR_SYNTH_MODE, instr->flags)) { + return DR_ISA_SYNTH; + } #ifdef X64 return TEST(INSTR_X86_MODE, instr->flags) ? DR_ISA_IA32 : DR_ISA_AMD64; #else