mirror of
https://github.com/Ed94/raddebugger.git
synced 2026-08-14 17:28:07 +00:00
sketch out first pass of autos evaluation
This commit is contained in:
+3
-135
@@ -7,11 +7,6 @@
|
|||||||
////////////////////////////////
|
////////////////////////////////
|
||||||
//~ rjf: Instruction Decoding/Disassembling Type Functions
|
//~ 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
|
internal DASM_Inst
|
||||||
dasm_inst_from_code(Arena *arena, Arch arch, U64 vaddr, String8 code, DASM_Syntax syntax)
|
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)
|
switch(arch)
|
||||||
{
|
{
|
||||||
default:{}break;
|
default:{}break;
|
||||||
|
#if defined(X64_H)
|
||||||
//- rjf: x86/x64 disassembly
|
|
||||||
case Arch_x86:
|
|
||||||
case Arch_x64:
|
case Arch_x64:
|
||||||
{
|
{
|
||||||
// rjf: determine zydis formatter style
|
inst = x64_dasm_inst_from_code(arena, vaddr, code, syntax);
|
||||||
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;
|
|
||||||
}
|
|
||||||
}break;
|
}break;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
return inst;
|
return inst;
|
||||||
}
|
}
|
||||||
|
|||||||
+4
-4
@@ -38,10 +38,10 @@ struct DASM_Inst
|
|||||||
U32 size;
|
U32 size;
|
||||||
String8 string;
|
String8 string;
|
||||||
U64 dst_vaddr;
|
U64 dst_vaddr;
|
||||||
ARCH_RegCode dst_base_reg;
|
ARCH_RegCode dst_reg_code;
|
||||||
U64 dst_off;
|
S64 dst_reg_off;
|
||||||
ARCH_RegCode src_base_reg;
|
ARCH_RegCode src_reg_code;
|
||||||
U64 src_off;
|
S64 src_reg_off;
|
||||||
};
|
};
|
||||||
|
|
||||||
////////////////////////////////
|
////////////////////////////////
|
||||||
|
|||||||
@@ -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
|
||||||
@@ -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
|
||||||
@@ -11782,15 +11782,19 @@ rd_frame(void)
|
|||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
String8 name;
|
String8 name;
|
||||||
|
E_TypeIRExtFunctionType *irext;
|
||||||
E_TypeExpandInfoFunctionType *info;
|
E_TypeExpandInfoFunctionType *info;
|
||||||
E_TypeExpandRangeFunctionType *range;
|
E_TypeExpandRangeFunctionType *range;
|
||||||
}
|
}
|
||||||
collection_infos[] =
|
collection_infos[] =
|
||||||
{
|
{
|
||||||
#define Collection(name) {str8_lit_comp(#name), E_TYPE_EXPAND_INFO_FUNCTION_NAME(name), E_TYPE_EXPAND_RANGE_FUNCTION_NAME(name)}
|
#define Collection1(name) {str8_lit_comp(#name), 0, E_TYPE_EXPAND_INFO_FUNCTION_NAME(name), E_TYPE_EXPAND_RANGE_FUNCTION_NAME(name)}
|
||||||
Collection(locals),
|
#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)}
|
||||||
Collection(registers),
|
Collection1(locals),
|
||||||
#undef Collection
|
Collection1(registers),
|
||||||
|
Collection2(autos),
|
||||||
|
#undef Collection1
|
||||||
|
#undef Collection2
|
||||||
};
|
};
|
||||||
for EachElement(idx, collection_infos)
|
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));
|
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,
|
expr->type_key = e_type_key_cons(.kind = E_TypeKind_Set,
|
||||||
.name = collection_name,
|
.name = collection_name,
|
||||||
|
.irext = collection_infos[idx].irext,
|
||||||
.expand =
|
.expand =
|
||||||
{
|
{
|
||||||
.info = collection_infos[idx].info,
|
.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;
|
}break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -495,6 +495,19 @@ struct RD_State
|
|||||||
RD_Regs *next_hover_regs;
|
RD_Regs *next_hover_regs;
|
||||||
RD_RegSlot next_hover_regs_slot;
|
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
|
// rjf: icon texture
|
||||||
R_Handle icon_texture;
|
R_Handle icon_texture;
|
||||||
|
|
||||||
|
|||||||
@@ -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, ®_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
|
//~ rjf: Schema Type Hooks
|
||||||
|
|
||||||
|
|||||||
@@ -37,6 +37,13 @@ E_TYPE_EXPAND_RANGE_FUNCTION_DEF(locals);
|
|||||||
E_TYPE_EXPAND_INFO_FUNCTION_DEF(registers);
|
E_TYPE_EXPAND_INFO_FUNCTION_DEF(registers);
|
||||||
E_TYPE_EXPAND_RANGE_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
|
//~ rjf: Schema Type Hooks
|
||||||
|
|
||||||
|
|||||||
@@ -4,6 +4,9 @@
|
|||||||
////////////////////////////////
|
////////////////////////////////
|
||||||
//~ rjf: post-0.9.26 TODO notes
|
//~ rjf: post-0.9.26 TODO notes
|
||||||
//
|
//
|
||||||
|
// [ ] symbol server
|
||||||
|
// [ ] core dump saving/loading
|
||||||
|
//
|
||||||
// [ ] "autos" collection, which can be evaluated
|
// [ ] "autos" collection, which can be evaluated
|
||||||
// [ ] show "autos" inline in source code near thread?
|
// [ ] show "autos" inline in source code near thread?
|
||||||
// [ ] memory_size(...) view for quickly evaluating memory sizes
|
// [ ] memory_size(...) view for quickly evaluating memory sizes
|
||||||
@@ -173,7 +176,6 @@
|
|||||||
//
|
//
|
||||||
//- control improvements
|
//- control improvements
|
||||||
// [ ] debug info overrides (both path-based AND module-based)
|
// [ ] debug info overrides (both path-based AND module-based)
|
||||||
// [ ] symbol server
|
|
||||||
// [ ] can it ignore stepping into _RTC_CheckStackVars generated functions?
|
// [ ] can it ignore stepping into _RTC_CheckStackVars generated functions?
|
||||||
// [ ] jump table thunks, on code w/o /INCREMENTAL:NO
|
// [ ] jump table thunks, on code w/o /INCREMENTAL:NO
|
||||||
// [ ] investigate /DEBUG:FASTLINK - can we somehow alert that we do not
|
// [ ] investigate /DEBUG:FASTLINK - can we somehow alert that we do not
|
||||||
@@ -195,7 +197,6 @@
|
|||||||
//
|
//
|
||||||
//- longer-term future features
|
//- longer-term future features
|
||||||
// [ ] long-term future notes from martins
|
// [ ] long-term future notes from martins
|
||||||
// [ ] core dump saving/loading
|
|
||||||
// [ ] parallel call stacks view
|
// [ ] parallel call stacks view
|
||||||
// [ ] parallel watch view
|
// [ ] parallel watch view
|
||||||
// [ ] mixed native/interpreted/jit debugging
|
// [ ] mixed native/interpreted/jit debugging
|
||||||
@@ -328,7 +329,7 @@
|
|||||||
#include "radbin/radbin.h"
|
#include "radbin/radbin.h"
|
||||||
#include "arch/arch_inc.h"
|
#include "arch/arch_inc.h"
|
||||||
#include "dbg_info/dbg_info.h"
|
#include "dbg_info/dbg_info.h"
|
||||||
#include "disasm/disasm.h"
|
#include "disasm/disasm_inc.h"
|
||||||
#include "stap/stap_parse.h"
|
#include "stap/stap_parse.h"
|
||||||
#include "demon/demon_inc.h"
|
#include "demon/demon_inc.h"
|
||||||
#include "eval/eval_inc.h"
|
#include "eval/eval_inc.h"
|
||||||
@@ -381,7 +382,7 @@
|
|||||||
#include "radbin/radbin.c"
|
#include "radbin/radbin.c"
|
||||||
#include "arch/arch_inc.c"
|
#include "arch/arch_inc.c"
|
||||||
#include "dbg_info/dbg_info.c"
|
#include "dbg_info/dbg_info.c"
|
||||||
#include "disasm/disasm.c"
|
#include "disasm/disasm_inc.c"
|
||||||
#include "stap/stap_parse.c"
|
#include "stap/stap_parse.c"
|
||||||
#include "demon/demon_inc.c"
|
#include "demon/demon_inc.c"
|
||||||
#include "eval/eval_inc.c"
|
#include "eval/eval_inc.c"
|
||||||
|
|||||||
@@ -64,7 +64,7 @@
|
|||||||
#include "radbin/radbin.h"
|
#include "radbin/radbin.h"
|
||||||
#include "arch/arch_inc.h"
|
#include "arch/arch_inc.h"
|
||||||
#include "dbg_info/dbg_info.h"
|
#include "dbg_info/dbg_info.h"
|
||||||
#include "disasm/disasm.h"
|
#include "disasm/disasm_inc.h"
|
||||||
#include "stap/stap_parse.h"
|
#include "stap/stap_parse.h"
|
||||||
#include "demon/demon_inc.h"
|
#include "demon/demon_inc.h"
|
||||||
#include "eval/eval_inc.h"
|
#include "eval/eval_inc.h"
|
||||||
@@ -137,7 +137,7 @@
|
|||||||
#include "radbin/radbin.c"
|
#include "radbin/radbin.c"
|
||||||
#include "arch/arch_inc.c"
|
#include "arch/arch_inc.c"
|
||||||
#include "dbg_info/dbg_info.c"
|
#include "dbg_info/dbg_info.c"
|
||||||
#include "disasm/disasm.c"
|
#include "disasm/disasm_inc.c"
|
||||||
#include "stap/stap_parse.c"
|
#include "stap/stap_parse.c"
|
||||||
#include "demon/demon_inc.c"
|
#include "demon/demon_inc.c"
|
||||||
#include "eval/eval_inc.c"
|
#include "eval/eval_inc.c"
|
||||||
|
|||||||
@@ -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;
|
||||||
|
}
|
||||||
@@ -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
|
||||||
Reference in New Issue
Block a user