sketch out first pass of autos evaluation

This commit is contained in:
Ryan Fleury
2026-05-14 13:50:34 -07:00
parent 54fc7deafa
commit a60502d765
12 changed files with 778 additions and 149 deletions
+3 -135
View File
@@ -7,11 +7,6 @@
////////////////////////////////
//~ rjf: Instruction Decoding/Disassembling Type Functions
#if !defined(ZYDIS_H)
#include "third_party/zydis/zydis.h"
#include "third_party/zydis/zydis.c"
#endif
internal DASM_Inst
dasm_inst_from_code(Arena *arena, Arch arch, U64 vaddr, String8 code, DASM_Syntax syntax)
{
@@ -19,139 +14,12 @@ dasm_inst_from_code(Arena *arena, Arch arch, U64 vaddr, String8 code, DASM_Synta
switch(arch)
{
default:{}break;
//- rjf: x86/x64 disassembly
case Arch_x86:
#if defined(X64_H)
case Arch_x64:
{
// rjf: determine zydis formatter style
ZydisFormatterStyle style = ZYDIS_FORMATTER_STYLE_INTEL;
switch(syntax)
{
default:{}break;
case DASM_Syntax_Intel:{style = ZYDIS_FORMATTER_STYLE_INTEL;}break;
case DASM_Syntax_ATT: {style = ZYDIS_FORMATTER_STYLE_ATT;}break;
}
// rjf: disassemble one instruction
ZydisDisassembledInstruction zinst = {0};
ZyanStatus status = ZydisDisassemble(ZYDIS_MACHINE_MODE_LONG_64, vaddr, code.str, code.size, &zinst, style);
// rjf: analyze
DASM_InstFlags flags = 0;
U64 dst_vaddr = 0;
{
ZydisDecodedOperand *first_visible_op = (zinst.info.operand_count_visible > 0 ? &zinst.operands[0] : 0);
ZydisDecodedOperand *first_op = (zinst.info.operand_count > 0 ? &zinst.operands[0] : 0);
ZydisDecodedOperand *second_op = (zinst.info.operand_count > 1 ? &zinst.operands[1] : 0);
if(first_op != 0 &&
first_op->actions & ZYDIS_OPERAND_ACTION_WRITE)
{
// TODO(rjf): need to pass back register + offset
}
if(second_op != 0 &&
second_op->actions & ZYDIS_OPERAND_ACTION_READ)
{
// TODO(rjf): need to pass back register + offset
}
if(first_visible_op != 0 &&
(first_visible_op->encoding == ZYDIS_OPERAND_ENCODING_JIMM8 ||
first_visible_op->encoding == ZYDIS_OPERAND_ENCODING_JIMM16 ||
first_visible_op->encoding == ZYDIS_OPERAND_ENCODING_JIMM32 ||
first_visible_op->encoding == ZYDIS_OPERAND_ENCODING_JIMM64 ||
first_visible_op->encoding == ZYDIS_OPERAND_ENCODING_JIMM16_32_64 ||
first_visible_op->encoding == ZYDIS_OPERAND_ENCODING_JIMM32_32_64 ||
first_visible_op->encoding == ZYDIS_OPERAND_ENCODING_JIMM16_32_32))
{
ZydisCalcAbsoluteAddress(&zinst.info, first_visible_op, vaddr, &dst_vaddr);
}
if(first_op != 0 && second_op != 0 && first_op->type == ZYDIS_OPERAND_TYPE_REGISTER &&
(first_op->reg.value == ZYDIS_REGISTER_RSP ||
first_op->reg.value == ZYDIS_REGISTER_ESP ||
first_op->reg.value == ZYDIS_REGISTER_SP))
{
flags |= DASM_InstFlag_ChangesStackPointer;
if(second_op->type != ZYDIS_OPERAND_TYPE_IMMEDIATE)
{
flags |= DASM_InstFlag_ChangesStackPointerVariably;
}
}
if(zinst.info.attributes & (ZYDIS_ATTRIB_HAS_REP|
ZYDIS_ATTRIB_HAS_REPE|
ZYDIS_ATTRIB_HAS_REPZ|
ZYDIS_ATTRIB_HAS_REPNZ|
ZYDIS_ATTRIB_HAS_REPNE))
{
flags |= DASM_InstFlag_Repeats;
}
switch(zinst.info.mnemonic)
{
case ZYDIS_MNEMONIC_CALL:
{
flags |= DASM_InstFlag_Call;
}break;
case ZYDIS_MNEMONIC_JB:
case ZYDIS_MNEMONIC_JBE:
case ZYDIS_MNEMONIC_JCXZ:
case ZYDIS_MNEMONIC_JECXZ:
case ZYDIS_MNEMONIC_JKNZD:
case ZYDIS_MNEMONIC_JKZD:
case ZYDIS_MNEMONIC_JL:
case ZYDIS_MNEMONIC_JLE:
case ZYDIS_MNEMONIC_JNB:
case ZYDIS_MNEMONIC_JNBE:
case ZYDIS_MNEMONIC_JNL:
case ZYDIS_MNEMONIC_JNLE:
case ZYDIS_MNEMONIC_JNO:
case ZYDIS_MNEMONIC_JNP:
case ZYDIS_MNEMONIC_JNS:
case ZYDIS_MNEMONIC_JNZ:
case ZYDIS_MNEMONIC_JO:
case ZYDIS_MNEMONIC_JP:
case ZYDIS_MNEMONIC_JRCXZ:
case ZYDIS_MNEMONIC_JS:
case ZYDIS_MNEMONIC_JZ:
case ZYDIS_MNEMONIC_LOOP:
case ZYDIS_MNEMONIC_LOOPE:
case ZYDIS_MNEMONIC_LOOPNE:
{
flags |= DASM_InstFlag_Branch;
}break;
case ZYDIS_MNEMONIC_JMP:
{
flags |= DASM_InstFlag_UnconditionalJump;
}break;
case ZYDIS_MNEMONIC_RET:
{
flags |= DASM_InstFlag_Return;
}break;
case ZYDIS_MNEMONIC_PUSH:
case ZYDIS_MNEMONIC_POP:
{
flags |= DASM_InstFlag_ChangesStackPointer;
}break;
default:
{
flags |= DASM_InstFlag_NonFlow;
}break;
}
}
// rjf: convert
{
inst.flags = flags;
inst.size = zinst.info.length;
inst.string = str8_copy(arena, str8_cstring(zinst.text));
inst.dst_vaddr = dst_vaddr;
// inst.src_vaddr = src_vaddr;
}
inst = x64_dasm_inst_from_code(arena, vaddr, code, syntax);
}break;
#endif
}
return inst;
}
+4 -4
View File
@@ -38,10 +38,10 @@ struct DASM_Inst
U32 size;
String8 string;
U64 dst_vaddr;
ARCH_RegCode dst_base_reg;
U64 dst_off;
ARCH_RegCode src_base_reg;
U64 src_off;
ARCH_RegCode dst_reg_code;
S64 dst_reg_off;
ARCH_RegCode src_reg_code;
S64 src_reg_off;
};
////////////////////////////////
+7
View File
@@ -0,0 +1,7 @@
// Copyright (c) Epic Games Tools
// Licensed under the MIT license (https://opensource.org/license/mit/)
#include "disasm/disasm.c"
#if defined(X64_H)
# include "x64/disasm/x64_disasm.c"
#endif
+12
View File
@@ -0,0 +1,12 @@
// Copyright (c) Epic Games Tools
// Licensed under the MIT license (https://opensource.org/license/mit/)
#ifndef DISASM_INC_H
#define DISASM_INC_H
#include "disasm/disasm.h"
#if defined(X64_H)
# include "x64/disasm/x64_disasm.h"
#endif
#endif // DISASM_INC_H
+31 -4
View File
@@ -11782,15 +11782,19 @@ rd_frame(void)
struct
{
String8 name;
E_TypeIRExtFunctionType *irext;
E_TypeExpandInfoFunctionType *info;
E_TypeExpandRangeFunctionType *range;
}
collection_infos[] =
{
#define Collection(name) {str8_lit_comp(#name), E_TYPE_EXPAND_INFO_FUNCTION_NAME(name), E_TYPE_EXPAND_RANGE_FUNCTION_NAME(name)}
Collection(locals),
Collection(registers),
#undef Collection
#define Collection1(name) {str8_lit_comp(#name), 0, E_TYPE_EXPAND_INFO_FUNCTION_NAME(name), E_TYPE_EXPAND_RANGE_FUNCTION_NAME(name)}
#define Collection2(name) {str8_lit_comp(#name), E_TYPE_IREXT_FUNCTION_NAME(name), E_TYPE_EXPAND_INFO_FUNCTION_NAME(name), E_TYPE_EXPAND_RANGE_FUNCTION_NAME(name)}
Collection1(locals),
Collection1(registers),
Collection2(autos),
#undef Collection1
#undef Collection2
};
for EachElement(idx, collection_infos)
{
@@ -11798,6 +11802,7 @@ rd_frame(void)
E_Expr *expr = e_push_expr(scratch.arena, E_ExprKind_LeafOffset, r1u64(0, 0));
expr->type_key = e_type_key_cons(.kind = E_TypeKind_Set,
.name = collection_name,
.irext = collection_infos[idx].irext,
.expand =
{
.info = collection_infos[idx].info,
@@ -16539,6 +16544,28 @@ rd_frame(void)
}
}
}
// rjf: update the autos-determining code range
{
D_Handle new_thread_handle = thread->handle;
U64 new_sp = d_rsp_from_thread(&d_user_state->ctrl_entity_store->ctx, new_thread_handle);
if(thread == &d_entity_nil)
{
new_thread_handle = selected_thread->handle;
}
if(d_handle_match(new_thread_handle, rd_state->last_stop_selected_thread) &&
new_sp == rd_state->last_stop_selected_thread_sp)
{
rd_state->autos_determining_vaddr_range = r1u64(rd_state->last_stop_selected_thread_ip, vaddr);
}
else
{
MemoryZeroStruct(&rd_state->autos_determining_vaddr_range);
}
rd_state->last_stop_selected_thread = new_thread_handle;
rd_state->last_stop_selected_thread_ip = vaddr;
rd_state->last_stop_selected_thread_sp = new_sp;
}
}break;
}
}
+13
View File
@@ -495,6 +495,19 @@ struct RD_State
RD_Regs *next_hover_regs;
RD_RegSlot next_hover_regs_slot;
// rjf: autos-determining code range
//
// NOTE(rjf): this includes only instructions that we've observed the
// selected thread passed. autos are *also* computed from disassembling
// the line at which any thread sits, but we only want to collect autos
// from larger ranges of instructions when we directly observer this
// on a particular selected thread within a single function.
//
D_Handle last_stop_selected_thread;
U64 last_stop_selected_thread_ip;
U64 last_stop_selected_thread_sp;
Rng1U64 autos_determining_vaddr_range;
// rjf: icon texture
R_Handle icon_texture;
+216
View File
@@ -306,6 +306,222 @@ E_TYPE_EXPAND_RANGE_FUNCTION_DEF(registers)
}
}
////////////////////////////////
//~ rjf: `autos` Type Hooks
typedef struct RD_AutosAccel RD_AutosAccel;
struct RD_AutosAccel
{
String8Array exprs;
};
E_TYPE_IREXT_FUNCTION_DEF(autos)
{
E_IRExt irext = {0};
{
Temp scratch = scratch_begin(&arena, 1);
//- rjf: compute all autos
String8List auto_exprs = {0};
ProfScope("compute all autos")
{
Access *access = access_open();
U64 seen_expr_slots_count = 16;
String8Node **seen_expr_slots = push_array(scratch.arena, String8Node *, seen_expr_slots_count);
D_Handle thread_handle = rd_regs()->thread;
D_Entity *thread = d_entity_from_handle(&d_user_state->ctrl_entity_store->ctx, thread_handle);
D_CallStack call_stack = d_call_stack_from_thread(access, thread->handle, 0, 0);
if(call_stack.frames_count != 0)
{
//- rjf: unpack thread / module / debug info / lines
ARCH_Info *arch_info = arch_info_from_arch(thread->arch);
D_Entity *process = d_entity_ancestor_from_kind(thread, D_EntityKind_Process);
U64 thread_ip_vaddr = d_rip_from_thread(&d_user_state->ctrl_entity_store->ctx, thread_handle);
D_Entity *module = d_module_from_process_vaddr(process, thread_ip_vaddr);
DI_Key dbgi_key = d_dbgi_key_from_module(module);
RDI_Parsed *rdi = di_rdi_from_key(access, dbgi_key, 0, 0);
U64 thread_ip_voff = d_voff_from_vaddr(module, thread_ip_vaddr);
D_LineList thread_ip_lines = d_lines_from_dbgi_key_voff(scratch.arena, dbgi_key, thread_ip_voff);
//- rjf: gather all relevant code vaddr ranges
Rng1U64List code_vaddr_ranges = {0};
{
U64 line_range_limit = 0;
for EachNode(n, D_LineNode, thread_ip_lines.first)
{
Rng1U64 line_voff_range = n->v.voff_range;
Rng1U64 line_vaddr_range = d_vaddr_range_from_voff_range(module, line_voff_range);
rng1u64_list_push(scratch.arena, &code_vaddr_ranges, line_vaddr_range);
line_range_limit += 1;
if(line_range_limit >= 16)
{
break;
}
}
rng1u64_list_push(scratch.arena, &code_vaddr_ranges, rd_state->autos_determining_vaddr_range);
}
//- rjf: for each code vaddr range -> disassemble, look at src/dest of instructions,
// map back to location info, & gather expressions for affected symbols
for EachNode(n, Rng1U64Node, code_vaddr_ranges.first)
{
Rng1U64 vaddr_range = n->v;
vaddr_range.max = Min(vaddr_range.min+64, vaddr_range.max);
D_ProcessMemorySlice slice = d_process_memory_slice_from_vaddr_range(scratch.arena, process->handle, vaddr_range, 0, 0);
for(U64 off = 0, next_off = 0; off < slice.data.size; off = next_off)
{
next_off = slice.data.size;
// rjf: disassemble next instruction
DASM_Inst inst = dasm_inst_from_code(scratch.arena, thread->arch, vaddr_range.min + off, str8_skip(slice.data, off), DASM_Syntax_Intel);
next_off = off + inst.size;
// rjf: gather locations from instruction
struct
{
ARCH_RegCode reg_code;
U64 reg_off;
}
inst_locations[] =
{
{inst.dst_reg_code, inst.dst_reg_off},
{inst.src_reg_code, inst.src_reg_off},
};
// rjf: for each location -> map to symbols, gather
for EachElement(location_idx, inst_locations)
{
if(inst_locations[location_idx].reg_code != 0)
{
U64 reg_value = 0;
void *regs = call_stack.frames[0].regs;
Rng1U16 reg_rng = arch_info->reg_code_rng_table[inst_locations[location_idx].reg_code];
reg_rng.max = Min(reg_rng.max, reg_rng.min + sizeof(reg_value));
if(arch_reg_block_read_range(arch_info, regs, reg_rng, &reg_value))
{
U64 affected_vaddr = reg_value + inst_locations[location_idx].reg_off;
// rjf: compare against locals
{
E_String2NumMap *locals_map = e_ir_ctx->locals_map;
for(E_String2NumMapNode *n = locals_map->first; n != 0; n = n->order_next)
{
U64 local_num = n->num;
if(local_num != 0)
{
U64 local_idx = local_num-1;
RDI_Symbol *local = rdi_element_from_name_idx(rdi, LocalVariables, local_idx);
if(rdi_kind_from_location(local->location) == RDI_LocationKind_AddrBytecodeStream ||
rdi_kind_from_location(local->location) == RDI_LocationKind_AddrRegPlusOff ||
rdi_kind_from_location(local->location) == RDI_LocationKind_AddrAddrRegPlusOff)
{
RDI_TypeNode *type_node = rdi_element_from_name_idx(rdi, TypeNodes, local->type_idx);
E_OpList local_ops = e_oplist_from_location(scratch.arena, rdi, local->location);
String8 local_bytecode = e_bytecode_from_oplist(scratch.arena, &local_ops);
E_Interpretation local_addr_interpret = e_interpret(local_bytecode);
U64 local_vaddr = local_addr_interpret.value.u64;
Rng1U64 local_vaddr_range = r1u64(local_vaddr, local_vaddr+type_node->byte_size);
if(contains_1u64(local_vaddr_range, affected_vaddr))
{
String8 local_name = str8_from_rdi_string_idx(rdi, local->name_string_idx);
U64 hash = u64_hash_from_str8(local_name);
U64 slot_idx = hash%seen_expr_slots_count;
B32 already_seen = 0;
for(String8Node *n = seen_expr_slots[slot_idx]; n != 0; n = n->next)
{
if(str8_match(n->string, local_name, 0))
{
already_seen = 1;
break;
}
}
if(!already_seen)
{
str8_list_push(scratch.arena, &auto_exprs, local_name);
String8Node *n = push_array(scratch.arena, String8Node, 1);
SLLStackPush(seen_expr_slots[slot_idx], n);
n->string = local_name;
}
}
}
}
}
}
// rjf: compare against global variables
{
D_Entity *affected_module = d_module_from_process_vaddr(process, affected_vaddr);
U64 affected_voff = d_voff_from_vaddr(affected_module, affected_vaddr);
DI_Key affected_dbgi_key = d_dbgi_key_from_module(affected_module);
RDI_Parsed *affected_rdi = di_rdi_from_key(access, affected_dbgi_key, 0, 0);
RDI_Symbol *affected_gvar = rdi_global_variable_from_voff(affected_rdi, affected_voff);
if(affected_gvar->name_string_idx != 0)
{
String8 gvar_name = fully_qualified_str8_from_rdi_symbol(arena, affected_rdi, affected_gvar);
U64 hash = u64_hash_from_str8(gvar_name);
U64 slot_idx = hash%seen_expr_slots_count;
B32 already_seen = 0;
for(String8Node *n = seen_expr_slots[slot_idx]; n != 0; n = n->next)
{
if(str8_match(n->string, gvar_name, 0))
{
already_seen = 1;
break;
}
}
if(!already_seen)
{
str8_list_push(scratch.arena, &auto_exprs, gvar_name);
String8Node *n = push_array(scratch.arena, String8Node, 1);
SLLStackPush(seen_expr_slots[slot_idx], n);
n->string = gvar_name;
}
}
}
}
}
}
}
}
}
access_close(access);
}
//- rjf: gather
RD_AutosAccel *accel = push_array(arena, RD_AutosAccel, 1);
{
accel->exprs = str8_array_from_list(arena, &auto_exprs);
}
irext.user_data = accel;
scratch_end(scratch);
}
return irext;
}
E_TYPE_EXPAND_INFO_FUNCTION_DEF(autos)
{
E_TypeExpandInfo info = {0};
RD_AutosAccel *accel = (RD_AutosAccel *)eval.irtree.user_data;
if(accel != 0)
{
info.expr_count = accel->exprs.count;
}
return info;
}
E_TYPE_EXPAND_RANGE_FUNCTION_DEF(autos)
{
RD_AutosAccel *accel = (RD_AutosAccel *)eval.irtree.user_data;
if(accel != 0)
{
for EachInRange(idx, idx_range)
{
evals_out[idx - idx_range.min] = e_eval_from_string(accel->exprs.v[idx]);
}
}
}
////////////////////////////////
//~ rjf: Schema Type Hooks
+7
View File
@@ -37,6 +37,13 @@ E_TYPE_EXPAND_RANGE_FUNCTION_DEF(locals);
E_TYPE_EXPAND_INFO_FUNCTION_DEF(registers);
E_TYPE_EXPAND_RANGE_FUNCTION_DEF(registers);
////////////////////////////////
//~ rjf: `autos` Type Hooks
E_TYPE_IREXT_FUNCTION_DEF(autos);
E_TYPE_EXPAND_INFO_FUNCTION_DEF(autos);
E_TYPE_EXPAND_RANGE_FUNCTION_DEF(autos);
////////////////////////////////
//~ rjf: Schema Type Hooks
+5 -4
View File
@@ -4,6 +4,9 @@
////////////////////////////////
//~ rjf: post-0.9.26 TODO notes
//
// [ ] symbol server
// [ ] core dump saving/loading
//
// [ ] "autos" collection, which can be evaluated
// [ ] show "autos" inline in source code near thread?
// [ ] memory_size(...) view for quickly evaluating memory sizes
@@ -173,7 +176,6 @@
//
//- control improvements
// [ ] debug info overrides (both path-based AND module-based)
// [ ] symbol server
// [ ] can it ignore stepping into _RTC_CheckStackVars generated functions?
// [ ] jump table thunks, on code w/o /INCREMENTAL:NO
// [ ] investigate /DEBUG:FASTLINK - can we somehow alert that we do not
@@ -195,7 +197,6 @@
//
//- longer-term future features
// [ ] long-term future notes from martins
// [ ] core dump saving/loading
// [ ] parallel call stacks view
// [ ] parallel watch view
// [ ] mixed native/interpreted/jit debugging
@@ -328,7 +329,7 @@
#include "radbin/radbin.h"
#include "arch/arch_inc.h"
#include "dbg_info/dbg_info.h"
#include "disasm/disasm.h"
#include "disasm/disasm_inc.h"
#include "stap/stap_parse.h"
#include "demon/demon_inc.h"
#include "eval/eval_inc.h"
@@ -381,7 +382,7 @@
#include "radbin/radbin.c"
#include "arch/arch_inc.c"
#include "dbg_info/dbg_info.c"
#include "disasm/disasm.c"
#include "disasm/disasm_inc.c"
#include "stap/stap_parse.c"
#include "demon/demon_inc.c"
#include "eval/eval_inc.c"
+2 -2
View File
@@ -64,7 +64,7 @@
#include "radbin/radbin.h"
#include "arch/arch_inc.h"
#include "dbg_info/dbg_info.h"
#include "disasm/disasm.h"
#include "disasm/disasm_inc.h"
#include "stap/stap_parse.h"
#include "demon/demon_inc.h"
#include "eval/eval_inc.h"
@@ -137,7 +137,7 @@
#include "radbin/radbin.c"
#include "arch/arch_inc.c"
#include "dbg_info/dbg_info.c"
#include "disasm/disasm.c"
#include "disasm/disasm_inc.c"
#include "stap/stap_parse.c"
#include "demon/demon_inc.c"
#include "eval/eval_inc.c"
+469
View File
@@ -0,0 +1,469 @@
// Copyright (c) Epic Games Tools
// Licensed under the MIT license (https://opensource.org/license/mit/)
#if !defined(ZYDIS_H)
#include "third_party/zydis/zydis.h"
#include "third_party/zydis/zydis.c"
#endif
internal DASM_Inst
x64_dasm_inst_from_code(Arena *arena, U64 vaddr, String8 code, DASM_Syntax syntax)
{
DASM_Inst inst = {0};
//////////////////////////////
//- rjf: determine zydis formatter style
//
ZydisFormatterStyle style = ZYDIS_FORMATTER_STYLE_INTEL;
switch(syntax)
{
default:{}break;
case DASM_Syntax_Intel:{style = ZYDIS_FORMATTER_STYLE_INTEL;}break;
case DASM_Syntax_ATT: {style = ZYDIS_FORMATTER_STYLE_ATT;}break;
}
//////////////////////////////
//- rjf: disassemble one instruction
//
ZydisDisassembledInstruction zinst = {0};
ZyanStatus status = ZydisDisassemble(ZYDIS_MACHINE_MODE_LONG_64, vaddr, code.str, code.size, &zinst, style);
//////////////////////////////
//- rjf: analyze
//
DASM_InstFlags flags = 0;
U64 dst_vaddr = 0;
X64_RegCode src_reg_code = 0;
X64_RegCode dst_reg_code = 0;
S64 src_reg_off = 0;
S64 dst_reg_off = 0;
{
//- rjf: unpack operands
ZydisDecodedOperand *first_visible_op = (zinst.info.operand_count_visible > 0 ? &zinst.operands[0] : 0);
ZydisDecodedOperand *first_op = (zinst.info.operand_count > 0 ? &zinst.operands[0] : 0);
ZydisDecodedOperand *second_op = (zinst.info.operand_count > 1 ? &zinst.operands[1] : 0);
//- rjf: extract registers from operands
ZydisRegister zydis_reg_codes[2] = {0};
if(first_op != 0 && first_op->type == ZYDIS_OPERAND_TYPE_REGISTER)
{
zydis_reg_codes[0] = first_op->reg.value;
}
if(first_op != 0 && first_op->type == ZYDIS_OPERAND_TYPE_MEMORY)
{
zydis_reg_codes[0] = first_op->mem.base;
}
if(second_op != 0 && second_op->type == ZYDIS_OPERAND_TYPE_REGISTER)
{
zydis_reg_codes[1] = second_op->reg.value;
}
if(second_op != 0 && second_op->type == ZYDIS_OPERAND_TYPE_MEMORY)
{
zydis_reg_codes[1] = second_op->mem.base;
}
//- rjf: map zydis registers -> x64 layer
X64_RegCode x64_reg_codes[2] = {0};
for EachElement(reg_code_idx, zydis_reg_codes)
{
ZydisRegister src_reg = zydis_reg_codes[reg_code_idx];
X64_RegCode dst_reg = 0;
switch(src_reg)
{
default:{}break;
case ZYDIS_REGISTER_AL:{dst_reg = X64_RegCode_al;}break;
case ZYDIS_REGISTER_CL:{dst_reg = X64_RegCode_cl;}break;
case ZYDIS_REGISTER_DL:{dst_reg = X64_RegCode_dl;}break;
case ZYDIS_REGISTER_BL:{dst_reg = X64_RegCode_bl;}break;
case ZYDIS_REGISTER_AH:{dst_reg = X64_RegCode_ah;}break;
case ZYDIS_REGISTER_CH:{dst_reg = X64_RegCode_ch;}break;
case ZYDIS_REGISTER_DH:{dst_reg = X64_RegCode_dh;}break;
case ZYDIS_REGISTER_BH:{dst_reg = X64_RegCode_bh;}break;
case ZYDIS_REGISTER_SPL:{dst_reg = X64_RegCode_spl;}break;
case ZYDIS_REGISTER_BPL:{dst_reg = X64_RegCode_bpl;}break;
case ZYDIS_REGISTER_SIL:{dst_reg = X64_RegCode_sil;}break;
case ZYDIS_REGISTER_DIL:{dst_reg = X64_RegCode_dil;}break;
case ZYDIS_REGISTER_R8B:{dst_reg = X64_RegCode_r8b;}break;
case ZYDIS_REGISTER_R9B:{dst_reg = X64_RegCode_r9b;}break;
case ZYDIS_REGISTER_R10B:{dst_reg = X64_RegCode_r10b;}break;
case ZYDIS_REGISTER_R11B:{dst_reg = X64_RegCode_r11b;}break;
case ZYDIS_REGISTER_R12B:{dst_reg = X64_RegCode_r12b;}break;
case ZYDIS_REGISTER_R13B:{dst_reg = X64_RegCode_r13b;}break;
case ZYDIS_REGISTER_R14B:{dst_reg = X64_RegCode_r14b;}break;
case ZYDIS_REGISTER_R15B:{dst_reg = X64_RegCode_r15b;}break;
case ZYDIS_REGISTER_AX:{dst_reg = X64_RegCode_ax;}break;
case ZYDIS_REGISTER_CX:{dst_reg = X64_RegCode_cx;}break;
case ZYDIS_REGISTER_DX:{dst_reg = X64_RegCode_dx;}break;
case ZYDIS_REGISTER_BX:{dst_reg = X64_RegCode_bx;}break;
case ZYDIS_REGISTER_SP:{dst_reg = X64_RegCode_sp;}break;
case ZYDIS_REGISTER_BP:{dst_reg = X64_RegCode_bp;}break;
case ZYDIS_REGISTER_SI:{dst_reg = X64_RegCode_si;}break;
case ZYDIS_REGISTER_DI:{dst_reg = X64_RegCode_di;}break;
case ZYDIS_REGISTER_R8W:{dst_reg = X64_RegCode_r8w;}break;
case ZYDIS_REGISTER_R9W:{dst_reg = X64_RegCode_r9w;}break;
case ZYDIS_REGISTER_R10W:{dst_reg = X64_RegCode_r10w;}break;
case ZYDIS_REGISTER_R11W:{dst_reg = X64_RegCode_r11w;}break;
case ZYDIS_REGISTER_R12W:{dst_reg = X64_RegCode_r12w;}break;
case ZYDIS_REGISTER_R13W:{dst_reg = X64_RegCode_r13w;}break;
case ZYDIS_REGISTER_R14W:{dst_reg = X64_RegCode_r14w;}break;
case ZYDIS_REGISTER_R15W:{dst_reg = X64_RegCode_r15w;}break;
case ZYDIS_REGISTER_EAX:{dst_reg = X64_RegCode_eax;}break;
case ZYDIS_REGISTER_ECX:{dst_reg = X64_RegCode_ecx;}break;
case ZYDIS_REGISTER_EDX:{dst_reg = X64_RegCode_edx;}break;
case ZYDIS_REGISTER_EBX:{dst_reg = X64_RegCode_ebx;}break;
case ZYDIS_REGISTER_ESP:{dst_reg = X64_RegCode_esp;}break;
case ZYDIS_REGISTER_EBP:{dst_reg = X64_RegCode_ebp;}break;
case ZYDIS_REGISTER_ESI:{dst_reg = X64_RegCode_esi;}break;
case ZYDIS_REGISTER_EDI:{dst_reg = X64_RegCode_edi;}break;
case ZYDIS_REGISTER_R8D:{dst_reg = X64_RegCode_r8d;}break;
case ZYDIS_REGISTER_R9D:{dst_reg = X64_RegCode_r9d;}break;
case ZYDIS_REGISTER_R10D:{dst_reg = X64_RegCode_r10d;}break;
case ZYDIS_REGISTER_R11D:{dst_reg = X64_RegCode_r11d;}break;
case ZYDIS_REGISTER_R12D:{dst_reg = X64_RegCode_r12d;}break;
case ZYDIS_REGISTER_R13D:{dst_reg = X64_RegCode_r13d;}break;
case ZYDIS_REGISTER_R14D:{dst_reg = X64_RegCode_r14d;}break;
case ZYDIS_REGISTER_R15D:{dst_reg = X64_RegCode_r15d;}break;
case ZYDIS_REGISTER_RAX:{dst_reg = X64_RegCode_rax;}break;
case ZYDIS_REGISTER_RCX:{dst_reg = X64_RegCode_rcx;}break;
case ZYDIS_REGISTER_RDX:{dst_reg = X64_RegCode_rdx;}break;
case ZYDIS_REGISTER_RBX:{dst_reg = X64_RegCode_rbx;}break;
case ZYDIS_REGISTER_RSP:{dst_reg = X64_RegCode_rsp;}break;
case ZYDIS_REGISTER_RBP:{dst_reg = X64_RegCode_rbp;}break;
case ZYDIS_REGISTER_RSI:{dst_reg = X64_RegCode_rsi;}break;
case ZYDIS_REGISTER_RDI:{dst_reg = X64_RegCode_rdi;}break;
case ZYDIS_REGISTER_R8:{dst_reg = X64_RegCode_r8;}break;
case ZYDIS_REGISTER_R9:{dst_reg = X64_RegCode_r9;}break;
case ZYDIS_REGISTER_R10:{dst_reg = X64_RegCode_r10;}break;
case ZYDIS_REGISTER_R11:{dst_reg = X64_RegCode_r11;}break;
case ZYDIS_REGISTER_R12:{dst_reg = X64_RegCode_r12;}break;
case ZYDIS_REGISTER_R13:{dst_reg = X64_RegCode_r13;}break;
case ZYDIS_REGISTER_R14:{dst_reg = X64_RegCode_r14;}break;
case ZYDIS_REGISTER_R15:{dst_reg = X64_RegCode_r15;}break;
case ZYDIS_REGISTER_ST0:{dst_reg = X64_RegCode_st0;}break;
case ZYDIS_REGISTER_ST1:{dst_reg = X64_RegCode_st1;}break;
case ZYDIS_REGISTER_ST2:{dst_reg = X64_RegCode_st2;}break;
case ZYDIS_REGISTER_ST3:{dst_reg = X64_RegCode_st3;}break;
case ZYDIS_REGISTER_ST4:{dst_reg = X64_RegCode_st4;}break;
case ZYDIS_REGISTER_ST5:{dst_reg = X64_RegCode_st5;}break;
case ZYDIS_REGISTER_ST6:{dst_reg = X64_RegCode_st6;}break;
case ZYDIS_REGISTER_ST7:{dst_reg = X64_RegCode_st7;}break;
case ZYDIS_REGISTER_MM0:{dst_reg = X64_RegCode_mm0;}break;
case ZYDIS_REGISTER_MM1:{dst_reg = X64_RegCode_mm1;}break;
case ZYDIS_REGISTER_MM2:{dst_reg = X64_RegCode_mm2;}break;
case ZYDIS_REGISTER_MM3:{dst_reg = X64_RegCode_mm3;}break;
case ZYDIS_REGISTER_MM4:{dst_reg = X64_RegCode_mm4;}break;
case ZYDIS_REGISTER_MM5:{dst_reg = X64_RegCode_mm5;}break;
case ZYDIS_REGISTER_MM6:{dst_reg = X64_RegCode_mm6;}break;
case ZYDIS_REGISTER_MM7:{dst_reg = X64_RegCode_mm7;}break;
case ZYDIS_REGISTER_XMM0:{dst_reg = X64_RegCode_xmm0;}break;
case ZYDIS_REGISTER_XMM1:{dst_reg = X64_RegCode_xmm1;}break;
case ZYDIS_REGISTER_XMM2:{dst_reg = X64_RegCode_xmm2;}break;
case ZYDIS_REGISTER_XMM3:{dst_reg = X64_RegCode_xmm3;}break;
case ZYDIS_REGISTER_XMM4:{dst_reg = X64_RegCode_xmm4;}break;
case ZYDIS_REGISTER_XMM5:{dst_reg = X64_RegCode_xmm5;}break;
case ZYDIS_REGISTER_XMM6:{dst_reg = X64_RegCode_xmm6;}break;
case ZYDIS_REGISTER_XMM7:{dst_reg = X64_RegCode_xmm7;}break;
case ZYDIS_REGISTER_XMM8:{dst_reg = X64_RegCode_xmm8;}break;
case ZYDIS_REGISTER_XMM9:{dst_reg = X64_RegCode_xmm9;}break;
case ZYDIS_REGISTER_XMM10:{dst_reg = X64_RegCode_xmm10;}break;
case ZYDIS_REGISTER_XMM11:{dst_reg = X64_RegCode_xmm11;}break;
case ZYDIS_REGISTER_XMM12:{dst_reg = X64_RegCode_xmm12;}break;
case ZYDIS_REGISTER_XMM13:{dst_reg = X64_RegCode_xmm13;}break;
case ZYDIS_REGISTER_XMM14:{dst_reg = X64_RegCode_xmm14;}break;
case ZYDIS_REGISTER_XMM15:{dst_reg = X64_RegCode_xmm15;}break;
case ZYDIS_REGISTER_YMM0:{dst_reg = X64_RegCode_ymm0;}break;
case ZYDIS_REGISTER_YMM1:{dst_reg = X64_RegCode_ymm1;}break;
case ZYDIS_REGISTER_YMM2:{dst_reg = X64_RegCode_ymm2;}break;
case ZYDIS_REGISTER_YMM3:{dst_reg = X64_RegCode_ymm3;}break;
case ZYDIS_REGISTER_YMM4:{dst_reg = X64_RegCode_ymm4;}break;
case ZYDIS_REGISTER_YMM5:{dst_reg = X64_RegCode_ymm5;}break;
case ZYDIS_REGISTER_YMM6:{dst_reg = X64_RegCode_ymm6;}break;
case ZYDIS_REGISTER_YMM7:{dst_reg = X64_RegCode_ymm7;}break;
case ZYDIS_REGISTER_YMM8:{dst_reg = X64_RegCode_ymm8;}break;
case ZYDIS_REGISTER_YMM9:{dst_reg = X64_RegCode_ymm9;}break;
case ZYDIS_REGISTER_YMM10:{dst_reg = X64_RegCode_ymm10;}break;
case ZYDIS_REGISTER_YMM11:{dst_reg = X64_RegCode_ymm11;}break;
case ZYDIS_REGISTER_YMM12:{dst_reg = X64_RegCode_ymm12;}break;
case ZYDIS_REGISTER_YMM13:{dst_reg = X64_RegCode_ymm13;}break;
case ZYDIS_REGISTER_YMM14:{dst_reg = X64_RegCode_ymm14;}break;
case ZYDIS_REGISTER_YMM15:{dst_reg = X64_RegCode_ymm15;}break;
case ZYDIS_REGISTER_ZMM0:{dst_reg = X64_RegCode_zmm0;}break;
case ZYDIS_REGISTER_ZMM1:{dst_reg = X64_RegCode_zmm1;}break;
case ZYDIS_REGISTER_ZMM2:{dst_reg = X64_RegCode_zmm2;}break;
case ZYDIS_REGISTER_ZMM3:{dst_reg = X64_RegCode_zmm3;}break;
case ZYDIS_REGISTER_ZMM4:{dst_reg = X64_RegCode_zmm4;}break;
case ZYDIS_REGISTER_ZMM5:{dst_reg = X64_RegCode_zmm5;}break;
case ZYDIS_REGISTER_ZMM6:{dst_reg = X64_RegCode_zmm6;}break;
case ZYDIS_REGISTER_ZMM7:{dst_reg = X64_RegCode_zmm7;}break;
case ZYDIS_REGISTER_ZMM8:{dst_reg = X64_RegCode_zmm8;}break;
case ZYDIS_REGISTER_ZMM9:{dst_reg = X64_RegCode_zmm9;}break;
case ZYDIS_REGISTER_ZMM10:{dst_reg = X64_RegCode_zmm10;}break;
case ZYDIS_REGISTER_ZMM11:{dst_reg = X64_RegCode_zmm11;}break;
case ZYDIS_REGISTER_ZMM12:{dst_reg = X64_RegCode_zmm12;}break;
case ZYDIS_REGISTER_ZMM13:{dst_reg = X64_RegCode_zmm13;}break;
case ZYDIS_REGISTER_ZMM14:{dst_reg = X64_RegCode_zmm14;}break;
case ZYDIS_REGISTER_ZMM15:{dst_reg = X64_RegCode_zmm15;}break;
case ZYDIS_REGISTER_ZMM16:{dst_reg = X64_RegCode_zmm16;}break;
case ZYDIS_REGISTER_ZMM17:{dst_reg = X64_RegCode_zmm17;}break;
case ZYDIS_REGISTER_ZMM18:{dst_reg = X64_RegCode_zmm18;}break;
case ZYDIS_REGISTER_ZMM19:{dst_reg = X64_RegCode_zmm19;}break;
case ZYDIS_REGISTER_ZMM20:{dst_reg = X64_RegCode_zmm20;}break;
case ZYDIS_REGISTER_ZMM21:{dst_reg = X64_RegCode_zmm21;}break;
case ZYDIS_REGISTER_ZMM22:{dst_reg = X64_RegCode_zmm22;}break;
case ZYDIS_REGISTER_ZMM23:{dst_reg = X64_RegCode_zmm23;}break;
case ZYDIS_REGISTER_ZMM24:{dst_reg = X64_RegCode_zmm24;}break;
case ZYDIS_REGISTER_ZMM25:{dst_reg = X64_RegCode_zmm25;}break;
case ZYDIS_REGISTER_ZMM26:{dst_reg = X64_RegCode_zmm26;}break;
case ZYDIS_REGISTER_ZMM27:{dst_reg = X64_RegCode_zmm27;}break;
case ZYDIS_REGISTER_ZMM28:{dst_reg = X64_RegCode_zmm28;}break;
case ZYDIS_REGISTER_ZMM29:{dst_reg = X64_RegCode_zmm29;}break;
case ZYDIS_REGISTER_ZMM30:{dst_reg = X64_RegCode_zmm30;}break;
case ZYDIS_REGISTER_ZMM31:{dst_reg = X64_RegCode_zmm31;}break;
case ZYDIS_REGISTER_EFLAGS:{dst_reg = X64_RegCode_eflags;}break;
case ZYDIS_REGISTER_RFLAGS:{dst_reg = X64_RegCode_rflags;}break;
case ZYDIS_REGISTER_IP:{dst_reg = X64_RegCode_ip;}break;
case ZYDIS_REGISTER_RIP:{dst_reg = X64_RegCode_rip;}break;
case ZYDIS_REGISTER_ES:{dst_reg = X64_RegCode_es;}break;
case ZYDIS_REGISTER_CS:{dst_reg = X64_RegCode_cs;}break;
case ZYDIS_REGISTER_SS:{dst_reg = X64_RegCode_ss;}break;
case ZYDIS_REGISTER_DS:{dst_reg = X64_RegCode_ds;}break;
case ZYDIS_REGISTER_FS:{dst_reg = X64_RegCode_fs;}break;
case ZYDIS_REGISTER_GS:{dst_reg = X64_RegCode_gs;}break;
case ZYDIS_REGISTER_DR0:{dst_reg = X64_RegCode_dr0;}break;
case ZYDIS_REGISTER_DR1:{dst_reg = X64_RegCode_dr1;}break;
case ZYDIS_REGISTER_DR2:{dst_reg = X64_RegCode_dr2;}break;
case ZYDIS_REGISTER_DR3:{dst_reg = X64_RegCode_dr3;}break;
case ZYDIS_REGISTER_DR4:{dst_reg = X64_RegCode_dr4;}break;
case ZYDIS_REGISTER_DR5:{dst_reg = X64_RegCode_dr5;}break;
case ZYDIS_REGISTER_DR6:{dst_reg = X64_RegCode_dr6;}break;
case ZYDIS_REGISTER_DR7:{dst_reg = X64_RegCode_dr7;}break;
case ZYDIS_REGISTER_K0:{dst_reg = X64_RegCode_k0;}break;
case ZYDIS_REGISTER_K1:{dst_reg = X64_RegCode_k1;}break;
case ZYDIS_REGISTER_K2:{dst_reg = X64_RegCode_k2;}break;
case ZYDIS_REGISTER_K3:{dst_reg = X64_RegCode_k3;}break;
case ZYDIS_REGISTER_K4:{dst_reg = X64_RegCode_k4;}break;
case ZYDIS_REGISTER_K5:{dst_reg = X64_RegCode_k5;}break;
case ZYDIS_REGISTER_K6:{dst_reg = X64_RegCode_k6;}break;
case ZYDIS_REGISTER_K7:{dst_reg = X64_RegCode_k7;}break;
case ZYDIS_REGISTER_MXCSR:{dst_reg = X64_RegCode_mxcsr;}break;
// rjf: currently unsupported by debugger:
#if 0
case ZYDIS_REGISTER_EIP:{dst_reg = X64_RegCode_eip;}break;
case ZYDIS_REGISTER_X87CONTROL:{dst_reg = X64_RegCode_x87control;}break;
case ZYDIS_REGISTER_X87STATUS:{dst_reg = X64_RegCode_x87status;}break;
case ZYDIS_REGISTER_X87TAG:{dst_reg = X64_RegCode_x87tag;}break;
case ZYDIS_REGISTER_XMM16:{dst_reg = X64_RegCode_xmm16;}break;
case ZYDIS_REGISTER_XMM17:{dst_reg = X64_RegCode_xmm17;}break;
case ZYDIS_REGISTER_XMM18:{dst_reg = X64_RegCode_xmm18;}break;
case ZYDIS_REGISTER_XMM19:{dst_reg = X64_RegCode_xmm19;}break;
case ZYDIS_REGISTER_XMM20:{dst_reg = X64_RegCode_xmm20;}break;
case ZYDIS_REGISTER_XMM21:{dst_reg = X64_RegCode_xmm21;}break;
case ZYDIS_REGISTER_XMM22:{dst_reg = X64_RegCode_xmm22;}break;
case ZYDIS_REGISTER_XMM23:{dst_reg = X64_RegCode_xmm23;}break;
case ZYDIS_REGISTER_XMM24:{dst_reg = X64_RegCode_xmm24;}break;
case ZYDIS_REGISTER_XMM25:{dst_reg = X64_RegCode_xmm25;}break;
case ZYDIS_REGISTER_XMM26:{dst_reg = X64_RegCode_xmm26;}break;
case ZYDIS_REGISTER_XMM27:{dst_reg = X64_RegCode_xmm27;}break;
case ZYDIS_REGISTER_XMM28:{dst_reg = X64_RegCode_xmm28;}break;
case ZYDIS_REGISTER_XMM29:{dst_reg = X64_RegCode_xmm29;}break;
case ZYDIS_REGISTER_XMM30:{dst_reg = X64_RegCode_xmm30;}break;
case ZYDIS_REGISTER_XMM31:{dst_reg = X64_RegCode_xmm31;}break;
case ZYDIS_REGISTER_YMM16:{dst_reg = X64_RegCode_ymm16;}break;
case ZYDIS_REGISTER_YMM17:{dst_reg = X64_RegCode_ymm17;}break;
case ZYDIS_REGISTER_YMM18:{dst_reg = X64_RegCode_ymm18;}break;
case ZYDIS_REGISTER_YMM19:{dst_reg = X64_RegCode_ymm19;}break;
case ZYDIS_REGISTER_YMM20:{dst_reg = X64_RegCode_ymm20;}break;
case ZYDIS_REGISTER_YMM21:{dst_reg = X64_RegCode_ymm21;}break;
case ZYDIS_REGISTER_YMM22:{dst_reg = X64_RegCode_ymm22;}break;
case ZYDIS_REGISTER_YMM23:{dst_reg = X64_RegCode_ymm23;}break;
case ZYDIS_REGISTER_YMM24:{dst_reg = X64_RegCode_ymm24;}break;
case ZYDIS_REGISTER_YMM25:{dst_reg = X64_RegCode_ymm25;}break;
case ZYDIS_REGISTER_YMM26:{dst_reg = X64_RegCode_ymm26;}break;
case ZYDIS_REGISTER_YMM27:{dst_reg = X64_RegCode_ymm27;}break;
case ZYDIS_REGISTER_YMM28:{dst_reg = X64_RegCode_ymm28;}break;
case ZYDIS_REGISTER_YMM29:{dst_reg = X64_RegCode_ymm29;}break;
case ZYDIS_REGISTER_YMM30:{dst_reg = X64_RegCode_ymm30;}break;
case ZYDIS_REGISTER_YMM31:{dst_reg = X64_RegCode_ymm31;}break;
case ZYDIS_REGISTER_TMM0:{dst_reg = X64_RegCode_tmm0;}break;
case ZYDIS_REGISTER_TMM1:{dst_reg = X64_RegCode_tmm1;}break;
case ZYDIS_REGISTER_TMM2:{dst_reg = X64_RegCode_tmm2;}break;
case ZYDIS_REGISTER_TMM3:{dst_reg = X64_RegCode_tmm3;}break;
case ZYDIS_REGISTER_TMM4:{dst_reg = X64_RegCode_tmm4;}break;
case ZYDIS_REGISTER_TMM5:{dst_reg = X64_RegCode_tmm5;}break;
case ZYDIS_REGISTER_TMM6:{dst_reg = X64_RegCode_tmm6;}break;
case ZYDIS_REGISTER_TMM7:{dst_reg = X64_RegCode_tmm7;}break;
case ZYDIS_REGISTER_FLAGS:{dst_reg = X64_RegCode_flags;}break;
case ZYDIS_REGISTER_GDTR:{dst_reg = X64_RegCode_gdtr;}break;
case ZYDIS_REGISTER_LDTR:{dst_reg = X64_RegCode_ldtr;}break;
case ZYDIS_REGISTER_IDTR:{dst_reg = X64_RegCode_idtr;}break;
case ZYDIS_REGISTER_TR:{dst_reg = X64_RegCode_tr;}break;
case ZYDIS_REGISTER_TR0:{dst_reg = X64_RegCode_tr0;}break;
case ZYDIS_REGISTER_TR1:{dst_reg = X64_RegCode_tr1;}break;
case ZYDIS_REGISTER_TR2:{dst_reg = X64_RegCode_tr2;}break;
case ZYDIS_REGISTER_TR3:{dst_reg = X64_RegCode_tr3;}break;
case ZYDIS_REGISTER_TR4:{dst_reg = X64_RegCode_tr4;}break;
case ZYDIS_REGISTER_TR5:{dst_reg = X64_RegCode_tr5;}break;
case ZYDIS_REGISTER_TR6:{dst_reg = X64_RegCode_tr6;}break;
case ZYDIS_REGISTER_TR7:{dst_reg = X64_RegCode_tr7;}break;
case ZYDIS_REGISTER_CR0:{dst_reg = X64_RegCode_cr0;}break;
case ZYDIS_REGISTER_CR1:{dst_reg = X64_RegCode_cr1;}break;
case ZYDIS_REGISTER_CR2:{dst_reg = X64_RegCode_cr2;}break;
case ZYDIS_REGISTER_CR3:{dst_reg = X64_RegCode_cr3;}break;
case ZYDIS_REGISTER_CR4:{dst_reg = X64_RegCode_cr4;}break;
case ZYDIS_REGISTER_CR5:{dst_reg = X64_RegCode_cr5;}break;
case ZYDIS_REGISTER_CR6:{dst_reg = X64_RegCode_cr6;}break;
case ZYDIS_REGISTER_CR7:{dst_reg = X64_RegCode_cr7;}break;
case ZYDIS_REGISTER_CR8:{dst_reg = X64_RegCode_cr8;}break;
case ZYDIS_REGISTER_CR9:{dst_reg = X64_RegCode_cr9;}break;
case ZYDIS_REGISTER_CR10:{dst_reg = X64_RegCode_cr10;}break;
case ZYDIS_REGISTER_CR11:{dst_reg = X64_RegCode_cr11;}break;
case ZYDIS_REGISTER_CR12:{dst_reg = X64_RegCode_cr12;}break;
case ZYDIS_REGISTER_CR13:{dst_reg = X64_RegCode_cr13;}break;
case ZYDIS_REGISTER_CR14:{dst_reg = X64_RegCode_cr14;}break;
case ZYDIS_REGISTER_CR15:{dst_reg = X64_RegCode_cr15;}break;
case ZYDIS_REGISTER_DR8:{dst_reg = X64_RegCode_dr8;}break;
case ZYDIS_REGISTER_DR9:{dst_reg = X64_RegCode_dr9;}break;
case ZYDIS_REGISTER_DR10:{dst_reg = X64_RegCode_dr10;}break;
case ZYDIS_REGISTER_DR11:{dst_reg = X64_RegCode_dr11;}break;
case ZYDIS_REGISTER_DR12:{dst_reg = X64_RegCode_dr12;}break;
case ZYDIS_REGISTER_DR13:{dst_reg = X64_RegCode_dr13;}break;
case ZYDIS_REGISTER_DR14:{dst_reg = X64_RegCode_dr14;}break;
case ZYDIS_REGISTER_DR15:{dst_reg = X64_RegCode_dr15;}break;
case ZYDIS_REGISTER_BND0:{dst_reg = X64_RegCode_bnd0;}break;
case ZYDIS_REGISTER_BND1:{dst_reg = X64_RegCode_bnd1;}break;
case ZYDIS_REGISTER_BND2:{dst_reg = X64_RegCode_bnd2;}break;
case ZYDIS_REGISTER_BND3:{dst_reg = X64_RegCode_bnd3;}break;
case ZYDIS_REGISTER_BNDCFG:{dst_reg = X64_RegCode_bndcfg;}break;
case ZYDIS_REGISTER_BNDSTATUS:{dst_reg = X64_RegCode_bndstatus;}break;
case ZYDIS_REGISTER_PKRU:{dst_reg = X64_RegCode_pkru;}break;
case ZYDIS_REGISTER_XCR0:{dst_reg = X64_RegCode_xcr0;}break;
case ZYDIS_REGISTER_UIF:{dst_reg = X64_RegCode_uif;}break;
#endif
}
x64_reg_codes[reg_code_idx] = dst_reg;
}
//- rjf: extract info from operands
if(first_op != 0 &&
first_op->actions & ZYDIS_OPERAND_ACTION_WRITE)
{
dst_reg_code = x64_reg_codes[0];
if(first_op->type == ZYDIS_OPERAND_TYPE_MEMORY)
{
dst_reg_off = first_op->mem.disp.value;
}
}
if(second_op != 0 &&
second_op->actions & ZYDIS_OPERAND_ACTION_READ)
{
src_reg_code = x64_reg_codes[0];
if(second_op->type == ZYDIS_OPERAND_TYPE_MEMORY)
{
src_reg_off = second_op->mem.disp.value;
}
}
if(first_visible_op != 0 &&
(first_visible_op->encoding == ZYDIS_OPERAND_ENCODING_JIMM8 ||
first_visible_op->encoding == ZYDIS_OPERAND_ENCODING_JIMM16 ||
first_visible_op->encoding == ZYDIS_OPERAND_ENCODING_JIMM32 ||
first_visible_op->encoding == ZYDIS_OPERAND_ENCODING_JIMM64 ||
first_visible_op->encoding == ZYDIS_OPERAND_ENCODING_JIMM16_32_64 ||
first_visible_op->encoding == ZYDIS_OPERAND_ENCODING_JIMM32_32_64 ||
first_visible_op->encoding == ZYDIS_OPERAND_ENCODING_JIMM16_32_32))
{
ZydisCalcAbsoluteAddress(&zinst.info, first_visible_op, vaddr, &dst_vaddr);
}
if(first_op != 0 && second_op != 0 && first_op->type == ZYDIS_OPERAND_TYPE_REGISTER &&
(first_op->reg.value == ZYDIS_REGISTER_RSP ||
first_op->reg.value == ZYDIS_REGISTER_ESP ||
first_op->reg.value == ZYDIS_REGISTER_SP))
{
flags |= DASM_InstFlag_ChangesStackPointer;
if(second_op->type != ZYDIS_OPERAND_TYPE_IMMEDIATE)
{
flags |= DASM_InstFlag_ChangesStackPointerVariably;
}
}
if(zinst.info.attributes & (ZYDIS_ATTRIB_HAS_REP|
ZYDIS_ATTRIB_HAS_REPE|
ZYDIS_ATTRIB_HAS_REPZ|
ZYDIS_ATTRIB_HAS_REPNZ|
ZYDIS_ATTRIB_HAS_REPNE))
{
flags |= DASM_InstFlag_Repeats;
}
switch(zinst.info.mnemonic)
{
case ZYDIS_MNEMONIC_CALL:
{
flags |= DASM_InstFlag_Call;
}break;
case ZYDIS_MNEMONIC_JB:
case ZYDIS_MNEMONIC_JBE:
case ZYDIS_MNEMONIC_JCXZ:
case ZYDIS_MNEMONIC_JECXZ:
case ZYDIS_MNEMONIC_JKNZD:
case ZYDIS_MNEMONIC_JKZD:
case ZYDIS_MNEMONIC_JL:
case ZYDIS_MNEMONIC_JLE:
case ZYDIS_MNEMONIC_JNB:
case ZYDIS_MNEMONIC_JNBE:
case ZYDIS_MNEMONIC_JNL:
case ZYDIS_MNEMONIC_JNLE:
case ZYDIS_MNEMONIC_JNO:
case ZYDIS_MNEMONIC_JNP:
case ZYDIS_MNEMONIC_JNS:
case ZYDIS_MNEMONIC_JNZ:
case ZYDIS_MNEMONIC_JO:
case ZYDIS_MNEMONIC_JP:
case ZYDIS_MNEMONIC_JRCXZ:
case ZYDIS_MNEMONIC_JS:
case ZYDIS_MNEMONIC_JZ:
case ZYDIS_MNEMONIC_LOOP:
case ZYDIS_MNEMONIC_LOOPE:
case ZYDIS_MNEMONIC_LOOPNE:
{
flags |= DASM_InstFlag_Branch;
}break;
case ZYDIS_MNEMONIC_JMP:
{
flags |= DASM_InstFlag_UnconditionalJump;
}break;
case ZYDIS_MNEMONIC_RET:
{
flags |= DASM_InstFlag_Return;
}break;
case ZYDIS_MNEMONIC_PUSH:
case ZYDIS_MNEMONIC_POP:
{
flags |= DASM_InstFlag_ChangesStackPointer;
}break;
default:
{
flags |= DASM_InstFlag_NonFlow;
}break;
}
}
//////////////////////////////
//- rjf: bundle
//
{
inst.flags = flags;
inst.size = zinst.info.length;
inst.string = str8_copy(arena, str8_cstring(zinst.text));
inst.dst_vaddr = dst_vaddr;
inst.dst_reg_code = dst_reg_code;
inst.dst_reg_off = dst_reg_off;
inst.src_reg_code = src_reg_code;
inst.src_reg_off = src_reg_off;
}
return inst;
}
+9
View File
@@ -0,0 +1,9 @@
// Copyright (c) Epic Games Tools
// Licensed under the MIT license (https://opensource.org/license/mit/)
#ifndef X64_DISASM_H
#define X64_DISASM_H
internal DASM_Inst x64_dasm_inst_from_code(Arena *arena, U64 vaddr, String8 code, DASM_Syntax syntax);
#endif // X64_DISASM_H