mirror of
https://github.com/Ed94/raddebugger.git
synced 2026-06-14 08:02:23 -07:00
switch ctrl flow analysis etc. to zydis from udis86; unify disassembling path in dasm_cache layer, use single instruction decode path in frontend for ctrl flow analysis; use in dasm cache layer for disassembly textualization
This commit is contained in:
+165
-71
@@ -2,19 +2,137 @@
|
||||
// Licensed under the MIT license (https://opensource.org/license/mit/)
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Third Party Includes
|
||||
//~ rjf: Instruction Decoding/Disassembling Type Functions
|
||||
|
||||
#if !defined(ZYDIS_H)
|
||||
#include "third_party/zydis/zydis.h"
|
||||
#include "third_party/zydis/zydis.c"
|
||||
#endif
|
||||
|
||||
#include "third_party/udis86/config.h"
|
||||
#include "third_party/udis86/udis86.h"
|
||||
#include "third_party/udis86/libudis86/decode.c"
|
||||
#include "third_party/udis86/libudis86/itab.c"
|
||||
#include "third_party/udis86/libudis86/syn-att.c"
|
||||
#include "third_party/udis86/libudis86/syn-intel.c"
|
||||
#include "third_party/udis86/libudis86/syn.c"
|
||||
#include "third_party/udis86/libudis86/udis86.c"
|
||||
internal DASM_Inst
|
||||
dasm_inst_from_code(Arena *arena, Architecture arch, U64 vaddr, String8 code, DASM_Syntax syntax)
|
||||
{
|
||||
DASM_Inst inst = {0};
|
||||
switch(arch)
|
||||
{
|
||||
default:{}break;
|
||||
|
||||
//- rjf: x86/x64 disassembly
|
||||
case Architecture_x86:
|
||||
case Architecture_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 jump_dest_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_visible_op != 0)
|
||||
{
|
||||
ZydisCalcAbsoluteAddress(&zinst.info, first_visible_op, vaddr, &jump_dest_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 = push_str8_copy(arena, str8_cstring(zinst.text));
|
||||
inst.jump_dest_vaddr = jump_dest_vaddr;
|
||||
}
|
||||
}break;
|
||||
}
|
||||
return inst;
|
||||
}
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Parameter Type Functions
|
||||
@@ -32,42 +150,42 @@ dasm_params_match(DASM_Params *a, DASM_Params *b)
|
||||
}
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Instruction Type Functions
|
||||
//~ rjf: Line Type Functions
|
||||
|
||||
internal void
|
||||
dasm_inst_chunk_list_push(Arena *arena, DASM_InstChunkList *list, U64 cap, DASM_Inst *inst)
|
||||
dasm_line_chunk_list_push(Arena *arena, DASM_LineChunkList *list, U64 cap, DASM_Line *inst)
|
||||
{
|
||||
DASM_InstChunkNode *node = list->last;
|
||||
DASM_LineChunkNode *node = list->last;
|
||||
if(node == 0 || node->count >= node->cap)
|
||||
{
|
||||
node = push_array(arena, DASM_InstChunkNode, 1);
|
||||
node->v = push_array_no_zero(arena, DASM_Inst, cap);
|
||||
node = push_array(arena, DASM_LineChunkNode, 1);
|
||||
node->v = push_array_no_zero(arena, DASM_Line, cap);
|
||||
node->cap = cap;
|
||||
SLLQueuePush(list->first, list->last, node);
|
||||
list->node_count += 1;
|
||||
}
|
||||
MemoryCopyStruct(&node->v[node->count], inst);
|
||||
node->count += 1;
|
||||
list->inst_count += 1;
|
||||
list->line_count += 1;
|
||||
}
|
||||
|
||||
internal DASM_InstArray
|
||||
dasm_inst_array_from_chunk_list(Arena *arena, DASM_InstChunkList *list)
|
||||
internal DASM_LineArray
|
||||
dasm_line_array_from_chunk_list(Arena *arena, DASM_LineChunkList *list)
|
||||
{
|
||||
DASM_InstArray array = {0};
|
||||
array.count = list->inst_count;
|
||||
array.v = push_array_no_zero(arena, DASM_Inst, array.count);
|
||||
DASM_LineArray array = {0};
|
||||
array.count = list->line_count;
|
||||
array.v = push_array_no_zero(arena, DASM_Line, array.count);
|
||||
U64 idx = 0;
|
||||
for(DASM_InstChunkNode *n = list->first; n != 0; n = n->next)
|
||||
for(DASM_LineChunkNode *n = list->first; n != 0; n = n->next)
|
||||
{
|
||||
MemoryCopy(array.v+idx, n->v, sizeof(DASM_Inst)*n->count);
|
||||
MemoryCopy(array.v+idx, n->v, sizeof(DASM_Line)*n->count);
|
||||
idx += n->count;
|
||||
}
|
||||
return array;
|
||||
}
|
||||
|
||||
internal U64
|
||||
dasm_inst_array_idx_from_code_off__linear_scan(DASM_InstArray *array, U64 off)
|
||||
dasm_line_array_idx_from_code_off__linear_scan(DASM_LineArray *array, U64 off)
|
||||
{
|
||||
U64 result = 0;
|
||||
for(U64 idx = 0; idx < array->count; idx += 1)
|
||||
@@ -76,7 +194,7 @@ dasm_inst_array_idx_from_code_off__linear_scan(DASM_InstArray *array, U64 off)
|
||||
if(array->v[idx].code_off <= off && off < next_off)
|
||||
{
|
||||
result = idx;
|
||||
if(!(array->v[idx].flags & DASM_InstFlag_Decorative))
|
||||
if(!(array->v[idx].flags & DASM_LineFlag_Decorative))
|
||||
{
|
||||
break;
|
||||
}
|
||||
@@ -86,7 +204,7 @@ dasm_inst_array_idx_from_code_off__linear_scan(DASM_InstArray *array, U64 off)
|
||||
}
|
||||
|
||||
internal U64
|
||||
dasm_inst_array_code_off_from_idx(DASM_InstArray *array, U64 idx)
|
||||
dasm_line_array_code_off_from_idx(DASM_LineArray *array, U64 idx)
|
||||
{
|
||||
U64 off = 0;
|
||||
if(idx < array->count)
|
||||
@@ -288,7 +406,7 @@ dasm_info_from_key_params(DASM_Scope *scope, U128 key, DASM_Params *params, U128
|
||||
{
|
||||
U128 hash = hs_hash_from_key(key, rewind_idx);
|
||||
result = dasm_info_from_hash_params(scope, hash, params);
|
||||
if(result.insts.count != 0)
|
||||
if(result.lines.count != 0)
|
||||
{
|
||||
if(hash_out)
|
||||
{
|
||||
@@ -419,7 +537,7 @@ dasm_parse_thread__entry_point(void *p)
|
||||
}
|
||||
|
||||
//- rjf: data * arch * addr * dbg -> decode artifacts
|
||||
DASM_InstChunkList inst_list = {0};
|
||||
DASM_LineChunkList line_list = {0};
|
||||
String8List inst_strings = {0};
|
||||
if(got_task)
|
||||
{
|
||||
@@ -431,42 +549,18 @@ dasm_parse_thread__entry_point(void *p)
|
||||
case Architecture_x64:
|
||||
case Architecture_x86:
|
||||
{
|
||||
// rjf: determine zydis formatter style
|
||||
ZydisFormatterStyle style = ZYDIS_FORMATTER_STYLE_INTEL;
|
||||
switch(params.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
|
||||
RDI_SourceFile *last_file = &rdi_nil_element_union.source_file;
|
||||
RDI_Line *last_line = 0;
|
||||
for(U64 off = 0; off < data.size;)
|
||||
{
|
||||
// rjf: disassemble one instruction
|
||||
ZydisDisassembledInstruction zinst = {0};
|
||||
ZyanStatus status = ZydisDisassemble(ZYDIS_MACHINE_MODE_LONG_64,
|
||||
params.vaddr+off,
|
||||
data.str+off,
|
||||
data.size-off,
|
||||
&zinst,
|
||||
style);
|
||||
if(zinst.info.length == 0)
|
||||
DASM_Inst inst = dasm_inst_from_code(scratch.arena, params.arch, params.vaddr+off, str8_skip(data, off), params.syntax);
|
||||
if(inst.size == 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
// rjf: analyze
|
||||
ZydisDecodedOperand *first_op = (zinst.info.operand_count_visible > 0 ? &zinst.operands[0] : 0);
|
||||
U64 rel_voff = 0;
|
||||
if(first_op != 0)
|
||||
{
|
||||
ZydisCalcAbsoluteAddress(&zinst.info, first_op, params.vaddr+off, &rel_voff);
|
||||
}
|
||||
U64 jump_dst_vaddr = rel_voff;
|
||||
|
||||
// rjf: push strings derived from voff -> line info
|
||||
if(params.style_flags & (DASM_StyleFlag_SourceFilesNames|DASM_StyleFlag_SourceLines))
|
||||
{
|
||||
@@ -491,17 +585,17 @@ dasm_parse_thread__entry_point(void *p)
|
||||
file->normal_full_path_string_idx != 0 && file_normalized_full_path.size != 0)
|
||||
{
|
||||
String8 inst_string = push_str8f(scratch.arena, "> %S", file_normalized_full_path);
|
||||
DASM_Inst inst = {u32_from_u64_saturate(off), DASM_InstFlag_Decorative, 0, r1u64(inst_strings.total_size + inst_strings.node_count,
|
||||
DASM_Line inst = {u32_from_u64_saturate(off), DASM_LineFlag_Decorative, 0, r1u64(inst_strings.total_size + inst_strings.node_count,
|
||||
inst_strings.total_size + inst_strings.node_count + inst_string.size)};
|
||||
dasm_inst_chunk_list_push(scratch.arena, &inst_list, 1024, &inst);
|
||||
dasm_line_chunk_list_push(scratch.arena, &line_list, 1024, &inst);
|
||||
str8_list_push(scratch.arena, &inst_strings, inst_string);
|
||||
}
|
||||
if(params.style_flags & DASM_StyleFlag_SourceFilesNames && file->normal_full_path_string_idx == 0)
|
||||
{
|
||||
String8 inst_string = str8_lit(">");
|
||||
DASM_Inst inst = {u32_from_u64_saturate(off), DASM_InstFlag_Decorative, 0, r1u64(inst_strings.total_size + inst_strings.node_count,
|
||||
DASM_Line inst = {u32_from_u64_saturate(off), DASM_LineFlag_Decorative, 0, r1u64(inst_strings.total_size + inst_strings.node_count,
|
||||
inst_strings.total_size + inst_strings.node_count + inst_string.size)};
|
||||
dasm_inst_chunk_list_push(scratch.arena, &inst_list, 1024, &inst);
|
||||
dasm_line_chunk_list_push(scratch.arena, &line_list, 1024, &inst);
|
||||
str8_list_push(scratch.arena, &inst_strings, inst_string);
|
||||
}
|
||||
last_file = file;
|
||||
@@ -535,9 +629,9 @@ dasm_parse_thread__entry_point(void *p)
|
||||
if(line_text.size != 0)
|
||||
{
|
||||
String8 inst_string = push_str8f(scratch.arena, "> %S", line_text);
|
||||
DASM_Inst inst = {u32_from_u64_saturate(off), DASM_InstFlag_Decorative, 0, r1u64(inst_strings.total_size + inst_strings.node_count,
|
||||
DASM_Line inst = {u32_from_u64_saturate(off), DASM_LineFlag_Decorative, 0, r1u64(inst_strings.total_size + inst_strings.node_count,
|
||||
inst_strings.total_size + inst_strings.node_count + inst_string.size)};
|
||||
dasm_inst_chunk_list_push(scratch.arena, &inst_list, 1024, &inst);
|
||||
dasm_line_chunk_list_push(scratch.arena, &line_list, 1024, &inst);
|
||||
str8_list_push(scratch.arena, &inst_strings, inst_string);
|
||||
}
|
||||
}
|
||||
@@ -548,7 +642,7 @@ dasm_parse_thread__entry_point(void *p)
|
||||
}
|
||||
}
|
||||
|
||||
// rjf: push
|
||||
// rjf: push line
|
||||
String8 addr_part = {0};
|
||||
if(params.style_flags & DASM_StyleFlag_Addresses)
|
||||
{
|
||||
@@ -559,11 +653,11 @@ dasm_parse_thread__entry_point(void *p)
|
||||
{
|
||||
String8List code_bytes_strings = {0};
|
||||
str8_list_push(scratch.arena, &code_bytes_strings, str8_lit("{"));
|
||||
for(U64 byte_idx = 0; byte_idx < zinst.info.length || byte_idx < 16; byte_idx += 1)
|
||||
for(U64 byte_idx = 0; byte_idx < inst.size || byte_idx < 16; byte_idx += 1)
|
||||
{
|
||||
if(byte_idx < zinst.info.length)
|
||||
if(byte_idx < inst.size)
|
||||
{
|
||||
str8_list_pushf(scratch.arena, &code_bytes_strings, "%02x%s ", (U32)data.str[off+byte_idx], byte_idx == zinst.info.length-1 ? "}" : "");
|
||||
str8_list_pushf(scratch.arena, &code_bytes_strings, "%02x%s ", (U32)data.str[off+byte_idx], byte_idx == inst.size-1 ? "}" : "");
|
||||
}
|
||||
else if(byte_idx < 8)
|
||||
{
|
||||
@@ -574,9 +668,9 @@ dasm_parse_thread__entry_point(void *p)
|
||||
code_bytes_part = str8_list_join(scratch.arena, &code_bytes_strings, 0);
|
||||
}
|
||||
String8 symbol_part = {0};
|
||||
if(jump_dst_vaddr != 0 && rdi != &di_rdi_parsed_nil && params.style_flags & DASM_StyleFlag_SymbolNames)
|
||||
if(inst.jump_dest_vaddr != 0 && rdi != &di_rdi_parsed_nil && params.style_flags & DASM_StyleFlag_SymbolNames)
|
||||
{
|
||||
RDI_U32 scope_idx = rdi_vmap_idx_from_section_kind_voff(rdi, RDI_SectionKind_ScopeVMap, jump_dst_vaddr-params.base_vaddr);
|
||||
RDI_U32 scope_idx = rdi_vmap_idx_from_section_kind_voff(rdi, RDI_SectionKind_ScopeVMap, inst.jump_dest_vaddr-params.base_vaddr);
|
||||
if(scope_idx != 0)
|
||||
{
|
||||
RDI_Scope *scope = rdi_element_from_name_idx(rdi, Scopes, scope_idx);
|
||||
@@ -590,14 +684,14 @@ dasm_parse_thread__entry_point(void *p)
|
||||
}
|
||||
}
|
||||
}
|
||||
String8 inst_string = push_str8f(scratch.arena, "%S%S%s%S", addr_part, code_bytes_part, zinst.text, symbol_part);
|
||||
DASM_Inst inst = {u32_from_u64_saturate(off), 0, rel_voff, r1u64(inst_strings.total_size + inst_strings.node_count,
|
||||
inst_strings.total_size + inst_strings.node_count + inst_string.size)};
|
||||
dasm_inst_chunk_list_push(scratch.arena, &inst_list, 1024, &inst);
|
||||
String8 inst_string = push_str8f(scratch.arena, "%S%S%S%S", addr_part, code_bytes_part, inst.string, symbol_part);
|
||||
DASM_Line line = {u32_from_u64_saturate(off), 0, inst.jump_dest_vaddr, r1u64(inst_strings.total_size + inst_strings.node_count,
|
||||
inst_strings.total_size + inst_strings.node_count + inst_string.size)};
|
||||
dasm_line_chunk_list_push(scratch.arena, &line_list, 1024, &line);
|
||||
str8_list_push(scratch.arena, &inst_strings, inst_string);
|
||||
|
||||
// rjf: increment
|
||||
off += zinst.info.length;
|
||||
off += inst.size;
|
||||
}
|
||||
}break;
|
||||
}
|
||||
@@ -637,7 +731,7 @@ dasm_parse_thread__entry_point(void *p)
|
||||
//- rjf: produce value bundle
|
||||
info_arena = arena_alloc();
|
||||
info.text_key = text_key;
|
||||
info.insts = dasm_inst_array_from_chunk_list(info_arena, &inst_list);
|
||||
info.lines = dasm_line_array_from_chunk_list(info_arena, &line_list);
|
||||
}
|
||||
|
||||
//- rjf: commit results to cache
|
||||
|
||||
+301
-258
@@ -1,258 +1,301 @@
|
||||
// Copyright (c) 2024 Epic Games Tools
|
||||
// Licensed under the MIT license (https://opensource.org/license/mit/)
|
||||
|
||||
#ifndef DASM_CACHE_H
|
||||
#define DASM_CACHE_H
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Stringification Types
|
||||
|
||||
typedef U32 DASM_StyleFlags;
|
||||
enum
|
||||
{
|
||||
DASM_StyleFlag_Addresses = (1<<0),
|
||||
DASM_StyleFlag_CodeBytes = (1<<1),
|
||||
DASM_StyleFlag_SourceFilesNames = (1<<2),
|
||||
DASM_StyleFlag_SourceLines = (1<<3),
|
||||
DASM_StyleFlag_SymbolNames = (1<<4),
|
||||
};
|
||||
|
||||
typedef enum DASM_Syntax
|
||||
{
|
||||
DASM_Syntax_Intel,
|
||||
DASM_Syntax_ATT,
|
||||
DASM_Syntax_COUNT
|
||||
}
|
||||
DASM_Syntax;
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Disassembling Parameters Bundle
|
||||
|
||||
typedef struct DASM_Params DASM_Params;
|
||||
struct DASM_Params
|
||||
{
|
||||
U64 vaddr;
|
||||
Architecture arch;
|
||||
DASM_StyleFlags style_flags;
|
||||
DASM_Syntax syntax;
|
||||
U64 base_vaddr;
|
||||
DI_Key dbgi_key;
|
||||
};
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Instruction Types
|
||||
|
||||
typedef U32 DASM_InstFlags;
|
||||
enum
|
||||
{
|
||||
DASM_InstFlag_Decorative = (1<<0),
|
||||
};
|
||||
|
||||
typedef struct DASM_Inst DASM_Inst;
|
||||
struct DASM_Inst
|
||||
{
|
||||
U32 code_off;
|
||||
DASM_InstFlags flags;
|
||||
U64 addr;
|
||||
Rng1U64 text_range;
|
||||
};
|
||||
|
||||
typedef struct DASM_InstChunkNode DASM_InstChunkNode;
|
||||
struct DASM_InstChunkNode
|
||||
{
|
||||
DASM_InstChunkNode *next;
|
||||
DASM_Inst *v;
|
||||
U64 cap;
|
||||
U64 count;
|
||||
};
|
||||
|
||||
typedef struct DASM_InstChunkList DASM_InstChunkList;
|
||||
struct DASM_InstChunkList
|
||||
{
|
||||
DASM_InstChunkNode *first;
|
||||
DASM_InstChunkNode *last;
|
||||
U64 node_count;
|
||||
U64 inst_count;
|
||||
};
|
||||
|
||||
typedef struct DASM_InstArray DASM_InstArray;
|
||||
struct DASM_InstArray
|
||||
{
|
||||
DASM_Inst *v;
|
||||
U64 count;
|
||||
};
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Value Bundle Type
|
||||
|
||||
typedef struct DASM_Info DASM_Info;
|
||||
struct DASM_Info
|
||||
{
|
||||
U128 text_key;
|
||||
DASM_InstArray insts;
|
||||
};
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Cache Types
|
||||
|
||||
typedef struct DASM_Node DASM_Node;
|
||||
struct DASM_Node
|
||||
{
|
||||
// rjf: links
|
||||
DASM_Node *next;
|
||||
DASM_Node *prev;
|
||||
|
||||
// rjf: key
|
||||
U128 hash;
|
||||
DASM_Params params;
|
||||
|
||||
// rjf: generations
|
||||
U64 change_gen;
|
||||
|
||||
// rjf: value
|
||||
Arena *info_arena;
|
||||
DASM_Info info;
|
||||
|
||||
// rjf: metadata
|
||||
B32 is_working;
|
||||
U64 scope_ref_count;
|
||||
U64 last_time_touched_us;
|
||||
U64 last_user_clock_idx_touched;
|
||||
U64 load_count;
|
||||
U64 last_time_requested_us;
|
||||
U64 last_user_clock_idx_requested;
|
||||
};
|
||||
|
||||
typedef struct DASM_Slot DASM_Slot;
|
||||
struct DASM_Slot
|
||||
{
|
||||
DASM_Node *first;
|
||||
DASM_Node *last;
|
||||
};
|
||||
|
||||
typedef struct DASM_Stripe DASM_Stripe;
|
||||
struct DASM_Stripe
|
||||
{
|
||||
Arena *arena;
|
||||
OS_Handle rw_mutex;
|
||||
OS_Handle cv;
|
||||
DASM_Node *free_node;
|
||||
};
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Scoped Access Types
|
||||
|
||||
typedef struct DASM_Touch DASM_Touch;
|
||||
struct DASM_Touch
|
||||
{
|
||||
DASM_Touch *next;
|
||||
U128 hash;
|
||||
DASM_Params params;
|
||||
};
|
||||
|
||||
typedef struct DASM_Scope DASM_Scope;
|
||||
struct DASM_Scope
|
||||
{
|
||||
DASM_Scope *next;
|
||||
DASM_Touch *top_touch;
|
||||
U64 base_pos;
|
||||
};
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Thread Context
|
||||
|
||||
typedef struct DASM_TCTX DASM_TCTX;
|
||||
struct DASM_TCTX
|
||||
{
|
||||
Arena *arena;
|
||||
};
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Shared State
|
||||
|
||||
typedef struct DASM_Shared DASM_Shared;
|
||||
struct DASM_Shared
|
||||
{
|
||||
Arena *arena;
|
||||
|
||||
// rjf: user clock
|
||||
U64 user_clock_idx;
|
||||
|
||||
// rjf: cache
|
||||
U64 slots_count;
|
||||
U64 stripes_count;
|
||||
DASM_Slot *slots;
|
||||
DASM_Stripe *stripes;
|
||||
|
||||
// rjf: user -> parse thread
|
||||
U64 u2p_ring_size;
|
||||
U8 *u2p_ring_base;
|
||||
U64 u2p_ring_write_pos;
|
||||
U64 u2p_ring_read_pos;
|
||||
OS_Handle u2p_ring_cv;
|
||||
OS_Handle u2p_ring_mutex;
|
||||
|
||||
// rjf: parse threads
|
||||
U64 parse_thread_count;
|
||||
OS_Handle *parse_threads;
|
||||
|
||||
// rjf: evictor/detector thread
|
||||
OS_Handle evictor_detector_thread;
|
||||
};
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Globals
|
||||
|
||||
thread_static DASM_TCTX *dasm_tctx = 0;
|
||||
global DASM_Shared *dasm_shared = 0;
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Parameter Type Functions
|
||||
|
||||
internal B32 dasm_params_match(DASM_Params *a, DASM_Params *b);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Instruction Type Functions
|
||||
|
||||
internal void dasm_inst_chunk_list_push(Arena *arena, DASM_InstChunkList *list, U64 cap, DASM_Inst *inst);
|
||||
internal DASM_InstArray dasm_inst_array_from_chunk_list(Arena *arena, DASM_InstChunkList *list);
|
||||
internal U64 dasm_inst_array_idx_from_code_off__linear_scan(DASM_InstArray *array, U64 off);
|
||||
internal U64 dasm_inst_array_code_off_from_idx(DASM_InstArray *array, U64 idx);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Main Layer Initialization
|
||||
|
||||
internal void dasm_init(void);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: User Clock
|
||||
|
||||
internal void dasm_user_clock_tick(void);
|
||||
internal U64 dasm_user_clock_idx(void);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Scoped Access
|
||||
|
||||
internal DASM_Scope *dasm_scope_open(void);
|
||||
internal void dasm_scope_close(DASM_Scope *scope);
|
||||
internal void dasm_scope_touch_node__stripe_r_guarded(DASM_Scope *scope, DASM_Node *node);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Cache Lookups
|
||||
|
||||
internal DASM_Info dasm_info_from_hash_params(DASM_Scope *scope, U128 hash, DASM_Params *params);
|
||||
internal DASM_Info dasm_info_from_key_params(DASM_Scope *scope, U128 key, DASM_Params *params, U128 *hash_out);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Parse Threads
|
||||
|
||||
internal B32 dasm_u2p_enqueue_req(U128 hash, DASM_Params *params, U64 endt_us);
|
||||
internal void dasm_u2p_dequeue_req(Arena *arena, U128 *hash_out, DASM_Params *params_out);
|
||||
internal void dasm_parse_thread__entry_point(void *p);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Evictor/Detector Thread
|
||||
|
||||
internal void dasm_evictor_detector_thread__entry_point(void *p);
|
||||
|
||||
#endif // DASM_CACHE_H
|
||||
// Copyright (c) 2024 Epic Games Tools
|
||||
// Licensed under the MIT license (https://opensource.org/license/mit/)
|
||||
|
||||
#ifndef DASM_CACHE_H
|
||||
#define DASM_CACHE_H
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Disassembly Syntax Types
|
||||
|
||||
typedef enum DASM_Syntax
|
||||
{
|
||||
DASM_Syntax_Intel,
|
||||
DASM_Syntax_ATT,
|
||||
DASM_Syntax_COUNT
|
||||
}
|
||||
DASM_Syntax;
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Disassembly Instruction Info Types
|
||||
|
||||
typedef U32 DASM_InstFlags;
|
||||
enum
|
||||
{
|
||||
DASM_InstFlag_Call = (1<<0),
|
||||
DASM_InstFlag_Branch = (1<<1),
|
||||
DASM_InstFlag_UnconditionalJump = (1<<2),
|
||||
DASM_InstFlag_Return = (1<<3),
|
||||
DASM_InstFlag_NonFlow = (1<<4),
|
||||
DASM_InstFlag_Repeats = (1<<5),
|
||||
DASM_InstFlag_ChangesStackPointer = (1<<6),
|
||||
DASM_InstFlag_ChangesStackPointerVariably = (1<<7),
|
||||
};
|
||||
|
||||
typedef struct DASM_Inst DASM_Inst;
|
||||
struct DASM_Inst
|
||||
{
|
||||
DASM_InstFlags flags;
|
||||
U32 size;
|
||||
String8 string;
|
||||
U64 jump_dest_vaddr;
|
||||
};
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Disassembly Text Decoration Types
|
||||
|
||||
typedef U32 DASM_StyleFlags;
|
||||
enum
|
||||
{
|
||||
DASM_StyleFlag_Addresses = (1<<0),
|
||||
DASM_StyleFlag_CodeBytes = (1<<1),
|
||||
DASM_StyleFlag_SourceFilesNames = (1<<2),
|
||||
DASM_StyleFlag_SourceLines = (1<<3),
|
||||
DASM_StyleFlag_SymbolNames = (1<<4),
|
||||
};
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Disassembling Parameters Bundle
|
||||
|
||||
typedef struct DASM_Params DASM_Params;
|
||||
struct DASM_Params
|
||||
{
|
||||
U64 vaddr;
|
||||
Architecture arch;
|
||||
DASM_StyleFlags style_flags;
|
||||
DASM_Syntax syntax;
|
||||
U64 base_vaddr;
|
||||
DI_Key dbgi_key;
|
||||
};
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Disassembly Text Line Types
|
||||
|
||||
typedef U32 DASM_LineFlags;
|
||||
enum
|
||||
{
|
||||
DASM_LineFlag_Decorative = (1<<0),
|
||||
};
|
||||
|
||||
typedef struct DASM_Line DASM_Line;
|
||||
struct DASM_Line
|
||||
{
|
||||
U32 code_off;
|
||||
DASM_LineFlags flags;
|
||||
U64 addr;
|
||||
Rng1U64 text_range;
|
||||
};
|
||||
|
||||
typedef struct DASM_LineChunkNode DASM_LineChunkNode;
|
||||
struct DASM_LineChunkNode
|
||||
{
|
||||
DASM_LineChunkNode *next;
|
||||
DASM_Line *v;
|
||||
U64 cap;
|
||||
U64 count;
|
||||
};
|
||||
|
||||
typedef struct DASM_LineChunkList DASM_LineChunkList;
|
||||
struct DASM_LineChunkList
|
||||
{
|
||||
DASM_LineChunkNode *first;
|
||||
DASM_LineChunkNode *last;
|
||||
U64 node_count;
|
||||
U64 line_count;
|
||||
};
|
||||
|
||||
typedef struct DASM_LineArray DASM_LineArray;
|
||||
struct DASM_LineArray
|
||||
{
|
||||
DASM_Line *v;
|
||||
U64 count;
|
||||
};
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Disassembly Result Bundle
|
||||
|
||||
typedef struct DASM_Result DASM_Result;
|
||||
struct DASM_Result
|
||||
{
|
||||
String8 text;
|
||||
DASM_LineArray lines;
|
||||
};
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Value Bundle Type
|
||||
|
||||
typedef struct DASM_Info DASM_Info;
|
||||
struct DASM_Info
|
||||
{
|
||||
U128 text_key;
|
||||
DASM_LineArray lines;
|
||||
};
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Cache Types
|
||||
|
||||
typedef struct DASM_Node DASM_Node;
|
||||
struct DASM_Node
|
||||
{
|
||||
// rjf: links
|
||||
DASM_Node *next;
|
||||
DASM_Node *prev;
|
||||
|
||||
// rjf: key
|
||||
U128 hash;
|
||||
DASM_Params params;
|
||||
|
||||
// rjf: generations
|
||||
U64 change_gen;
|
||||
|
||||
// rjf: value
|
||||
Arena *info_arena;
|
||||
DASM_Info info;
|
||||
|
||||
// rjf: metadata
|
||||
B32 is_working;
|
||||
U64 scope_ref_count;
|
||||
U64 last_time_touched_us;
|
||||
U64 last_user_clock_idx_touched;
|
||||
U64 load_count;
|
||||
U64 last_time_requested_us;
|
||||
U64 last_user_clock_idx_requested;
|
||||
};
|
||||
|
||||
typedef struct DASM_Slot DASM_Slot;
|
||||
struct DASM_Slot
|
||||
{
|
||||
DASM_Node *first;
|
||||
DASM_Node *last;
|
||||
};
|
||||
|
||||
typedef struct DASM_Stripe DASM_Stripe;
|
||||
struct DASM_Stripe
|
||||
{
|
||||
Arena *arena;
|
||||
OS_Handle rw_mutex;
|
||||
OS_Handle cv;
|
||||
DASM_Node *free_node;
|
||||
};
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Scoped Access Types
|
||||
|
||||
typedef struct DASM_Touch DASM_Touch;
|
||||
struct DASM_Touch
|
||||
{
|
||||
DASM_Touch *next;
|
||||
U128 hash;
|
||||
DASM_Params params;
|
||||
};
|
||||
|
||||
typedef struct DASM_Scope DASM_Scope;
|
||||
struct DASM_Scope
|
||||
{
|
||||
DASM_Scope *next;
|
||||
DASM_Touch *top_touch;
|
||||
U64 base_pos;
|
||||
};
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Thread Context
|
||||
|
||||
typedef struct DASM_TCTX DASM_TCTX;
|
||||
struct DASM_TCTX
|
||||
{
|
||||
Arena *arena;
|
||||
};
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Shared State
|
||||
|
||||
typedef struct DASM_Shared DASM_Shared;
|
||||
struct DASM_Shared
|
||||
{
|
||||
Arena *arena;
|
||||
|
||||
// rjf: user clock
|
||||
U64 user_clock_idx;
|
||||
|
||||
// rjf: cache
|
||||
U64 slots_count;
|
||||
U64 stripes_count;
|
||||
DASM_Slot *slots;
|
||||
DASM_Stripe *stripes;
|
||||
|
||||
// rjf: user -> parse thread
|
||||
U64 u2p_ring_size;
|
||||
U8 *u2p_ring_base;
|
||||
U64 u2p_ring_write_pos;
|
||||
U64 u2p_ring_read_pos;
|
||||
OS_Handle u2p_ring_cv;
|
||||
OS_Handle u2p_ring_mutex;
|
||||
|
||||
// rjf: parse threads
|
||||
U64 parse_thread_count;
|
||||
OS_Handle *parse_threads;
|
||||
|
||||
// rjf: evictor/detector thread
|
||||
OS_Handle evictor_detector_thread;
|
||||
};
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Globals
|
||||
|
||||
thread_static DASM_TCTX *dasm_tctx = 0;
|
||||
global DASM_Shared *dasm_shared = 0;
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Instruction Decoding/Disassembling Type Functions
|
||||
|
||||
internal DASM_Inst dasm_inst_from_code(Arena *arena, Architecture arch, U64 vaddr, String8 code, DASM_Syntax syntax);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Parameter Type Functions
|
||||
|
||||
internal B32 dasm_params_match(DASM_Params *a, DASM_Params *b);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Line Type Functions
|
||||
|
||||
internal void dasm_line_chunk_list_push(Arena *arena, DASM_LineChunkList *list, U64 cap, DASM_Line *line);
|
||||
internal DASM_LineArray dasm_line_array_from_chunk_list(Arena *arena, DASM_LineChunkList *list);
|
||||
internal U64 dasm_line_array_idx_from_code_off__linear_scan(DASM_LineArray *array, U64 off);
|
||||
internal U64 dasm_line_array_code_off_from_idx(DASM_LineArray *array, U64 idx);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Main Layer Initialization
|
||||
|
||||
internal void dasm_init(void);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: User Clock
|
||||
|
||||
internal void dasm_user_clock_tick(void);
|
||||
internal U64 dasm_user_clock_idx(void);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Scoped Access
|
||||
|
||||
internal DASM_Scope *dasm_scope_open(void);
|
||||
internal void dasm_scope_close(DASM_Scope *scope);
|
||||
internal void dasm_scope_touch_node__stripe_r_guarded(DASM_Scope *scope, DASM_Node *node);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Cache Lookups
|
||||
|
||||
internal DASM_Info dasm_info_from_hash_params(DASM_Scope *scope, U128 hash, DASM_Params *params);
|
||||
internal DASM_Info dasm_info_from_key_params(DASM_Scope *scope, U128 key, DASM_Params *params, U128 *hash_out);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Parse Threads
|
||||
|
||||
internal B32 dasm_u2p_enqueue_req(U128 hash, DASM_Params *params, U64 endt_us);
|
||||
internal void dasm_u2p_dequeue_req(Arena *arena, U128 *hash_out, DASM_Params *params_out);
|
||||
internal void dasm_parse_thread__entry_point(void *p);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Evictor/Detector Thread
|
||||
|
||||
internal void dasm_evictor_detector_thread__entry_point(void *p);
|
||||
|
||||
#endif // DASM_CACHE_H
|
||||
|
||||
+26
-216
@@ -668,175 +668,6 @@ df_string_from_cfg_node_key(DF_CfgNode *node, String8 key, StringMatchFlags flag
|
||||
return child->first->string;
|
||||
}
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Disassembling
|
||||
|
||||
#include "third_party/udis86/config.h"
|
||||
#include "third_party/udis86/udis86.h"
|
||||
#include "third_party/udis86/libudis86/syn.h"
|
||||
|
||||
internal DF_Inst
|
||||
df_single_inst_from_machine_code__x64(Arena *arena, U64 start_voff, String8 string)
|
||||
{
|
||||
Architecture arch = Architecture_x64;
|
||||
|
||||
//- rjf: prep ud state
|
||||
struct ud ud_ctx_;
|
||||
struct ud *ud_ctx = &ud_ctx_;
|
||||
ud_init(ud_ctx);
|
||||
ud_set_mode(ud_ctx, bit_size_from_arch(arch));
|
||||
ud_set_pc(ud_ctx, start_voff);
|
||||
ud_set_input_buffer(ud_ctx, string.str, string.size);
|
||||
ud_set_vendor(ud_ctx, UD_VENDOR_ANY);
|
||||
ud_set_syntax(ud_ctx, UD_SYN_INTEL);
|
||||
|
||||
//- rjf: disassembly + get info
|
||||
U32 bytes_disassembled = ud_disassemble(ud_ctx);
|
||||
struct ud_operand *first_op = (struct ud_operand *)ud_insn_opr(ud_ctx, 0);
|
||||
U64 rel_voff = (first_op != 0 && first_op->type == UD_OP_JIMM) ? ud_syn_rel_target(ud_ctx, first_op) : 0;
|
||||
DF_InstFlags flags = 0;
|
||||
enum ud_mnemonic_code code = ud_insn_mnemonic(ud_ctx);
|
||||
switch(code)
|
||||
{
|
||||
case UD_Icall:
|
||||
{
|
||||
flags |= DF_InstFlag_Call;
|
||||
}break;
|
||||
|
||||
/* TODO(wonchun)
|
||||
case UD_Iiretd:
|
||||
case UD_Iiretw:
|
||||
*/
|
||||
|
||||
case UD_Ija:
|
||||
case UD_Ijae:
|
||||
case UD_Ijb:
|
||||
case UD_Ijbe:
|
||||
case UD_Ijcxz:
|
||||
case UD_Ijecxz:
|
||||
case UD_Ijg:
|
||||
case UD_Ijge:
|
||||
case UD_Ijl:
|
||||
case UD_Ijle:
|
||||
{
|
||||
flags |= DF_InstFlag_Branch;
|
||||
}break;
|
||||
|
||||
case UD_Ijmp:
|
||||
{
|
||||
flags |= DF_InstFlag_UnconditionalJump;
|
||||
}break;
|
||||
|
||||
case UD_Ijno:
|
||||
case UD_Ijnp:
|
||||
case UD_Ijns:
|
||||
case UD_Ijnz:
|
||||
case UD_Ijo:
|
||||
case UD_Ijp:
|
||||
case UD_Ijrcxz:
|
||||
case UD_Ijs:
|
||||
case UD_Ijz:
|
||||
case UD_Iloop:
|
||||
case UD_Iloope:
|
||||
case UD_Iloopne:
|
||||
{
|
||||
flags |= DF_InstFlag_Branch;
|
||||
}break;
|
||||
|
||||
case UD_Iret:
|
||||
case UD_Iretf:
|
||||
{
|
||||
flags |= DF_InstFlag_Return;
|
||||
}break;
|
||||
|
||||
/* TODO(wonchun)
|
||||
case UD_Isyscall:
|
||||
case UD_Isysenter:
|
||||
case UD_Isysexit:
|
||||
case UD_Isysret:
|
||||
case UD_Ivmcall:
|
||||
case UD_Ivmmcall:
|
||||
*/
|
||||
default:
|
||||
{
|
||||
flags |= DF_InstFlag_NonFlow;
|
||||
}break;
|
||||
}
|
||||
|
||||
//- rjf: check for stack pointer modifications
|
||||
S64 sp_delta = 0;
|
||||
{
|
||||
struct ud_operand *dst_op = (struct ud_operand *)ud_insn_opr(ud_ctx, 0);
|
||||
struct ud_operand *src_op = (struct ud_operand *)ud_insn_opr(ud_ctx, 1);
|
||||
|
||||
// rjf: direct additions/subtractions to RSP
|
||||
if(dst_op && src_op && dst_op->base == UD_R_RSP && dst_op->type == UD_OP_REG)
|
||||
{
|
||||
flags |= DF_InstFlag_ChangesStackPointer;
|
||||
// TODO(rjf): does the library report constant changes to the stack pointer
|
||||
// as UD_OP_CONST too? what does UD_OP_JIMM refer to?
|
||||
if(src_op->base == UD_NONE && src_op->type == UD_OP_IMM && code == UD_Isub)
|
||||
{
|
||||
S64 sign = -1;
|
||||
sp_delta = sign * src_op->lval.sqword;
|
||||
}
|
||||
else if(src_op->base == UD_NONE && src_op->type == UD_OP_IMM && code == UD_Iadd)
|
||||
{
|
||||
S64 sign = +1;
|
||||
sp_delta = sign * src_op->lval.sqword;
|
||||
}
|
||||
else
|
||||
{
|
||||
flags |= DF_InstFlag_ChangesStackPointerVariably;
|
||||
}
|
||||
}
|
||||
|
||||
// rjf: push/pop
|
||||
if(code == UD_Ipush)
|
||||
{
|
||||
flags |= DF_InstFlag_ChangesStackPointer;
|
||||
sp_delta = -8;
|
||||
}
|
||||
else if(code == UD_Ipop)
|
||||
{
|
||||
flags |= DF_InstFlag_ChangesStackPointer;
|
||||
sp_delta = +8;
|
||||
}
|
||||
|
||||
// rjf: mark extra flags
|
||||
if(ud_ctx->pfx_rep != 0 ||
|
||||
ud_ctx->pfx_repe != 0 ||
|
||||
ud_ctx->pfx_repne != 0)
|
||||
{
|
||||
flags |= DF_InstFlag_Repeats;
|
||||
}
|
||||
}
|
||||
|
||||
//- rjf: fill+return
|
||||
DF_Inst inst = {0};
|
||||
inst.size = bytes_disassembled;
|
||||
inst.string = push_str8_copy(arena, str8_cstring((char *)ud_insn_asm(ud_ctx)));
|
||||
inst.rel_voff = rel_voff;
|
||||
inst.sp_delta = sp_delta;
|
||||
inst.flags = flags;
|
||||
return inst;
|
||||
}
|
||||
|
||||
internal DF_Inst
|
||||
df_single_inst_from_machine_code(Arena *arena, Architecture arch, U64 start_voff, String8 string)
|
||||
{
|
||||
DF_Inst result = {0};
|
||||
switch(arch)
|
||||
{
|
||||
default:{}break;
|
||||
case Architecture_x64:
|
||||
{
|
||||
result = df_single_inst_from_machine_code__x64(arena, start_voff, string);
|
||||
}break;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Debug Info Extraction Type Pure Functions
|
||||
|
||||
@@ -859,15 +690,14 @@ df_line_list_copy(Arena *arena, DF_LineList *list)
|
||||
//~ rjf: Control Flow Analysis Functions
|
||||
|
||||
internal DF_CtrlFlowInfo
|
||||
df_ctrl_flow_info_from_vaddr_code__x64(Arena *arena, DF_InstFlags exit_points_mask, U64 vaddr, String8 code)
|
||||
df_ctrl_flow_info_from_arch_vaddr_code(Arena *arena, DASM_InstFlags exit_points_mask, Architecture arch, U64 vaddr, String8 code)
|
||||
{
|
||||
Temp scratch = scratch_begin(&arena, 1);
|
||||
DF_CtrlFlowInfo info = {0};
|
||||
for(U64 offset = 0; offset < code.size;)
|
||||
{
|
||||
DF_Inst inst = df_single_inst_from_machine_code__x64(scratch.arena, 0, str8_skip(code, offset));
|
||||
DASM_Inst inst = dasm_inst_from_code(scratch.arena, arch, vaddr+offset, str8_skip(code, offset), DASM_Syntax_Intel);
|
||||
U64 inst_vaddr = vaddr+offset;
|
||||
info.cumulative_sp_delta += inst.sp_delta;
|
||||
offset += inst.size;
|
||||
info.total_size += inst.size;
|
||||
if(inst.flags & exit_points_mask)
|
||||
@@ -875,12 +705,7 @@ df_ctrl_flow_info_from_vaddr_code__x64(Arena *arena, DF_InstFlags exit_points_ma
|
||||
DF_CtrlFlowPoint point = {0};
|
||||
point.inst_flags = inst.flags;
|
||||
point.vaddr = inst_vaddr;
|
||||
point.jump_dest_vaddr = 0;
|
||||
point.expected_sp_delta = info.cumulative_sp_delta;
|
||||
if(inst.rel_voff != 0)
|
||||
{
|
||||
point.jump_dest_vaddr = (U64)(point.vaddr + (S64)((S32)inst.rel_voff));
|
||||
}
|
||||
point.jump_dest_vaddr = inst.jump_dest_vaddr;
|
||||
DF_CtrlFlowPointNode *node = push_array(arena, DF_CtrlFlowPointNode, 1);
|
||||
node->v = point;
|
||||
SLLQueuePush(info.exit_points.first, info.exit_points.last, node);
|
||||
@@ -891,21 +716,6 @@ df_ctrl_flow_info_from_vaddr_code__x64(Arena *arena, DF_InstFlags exit_points_ma
|
||||
return info;
|
||||
}
|
||||
|
||||
internal DF_CtrlFlowInfo
|
||||
df_ctrl_flow_info_from_arch_vaddr_code(Arena *arena, DF_InstFlags exit_points_mask, Architecture arch, U64 vaddr, String8 code)
|
||||
{
|
||||
DF_CtrlFlowInfo result = {0};
|
||||
switch(arch)
|
||||
{
|
||||
default:{}break;
|
||||
case Architecture_x64:
|
||||
{
|
||||
result = df_ctrl_flow_info_from_vaddr_code__x64(arena, exit_points_mask, vaddr, code);
|
||||
}break;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Command Type Pure Functions
|
||||
|
||||
@@ -2833,10 +2643,10 @@ df_trap_net_from_thread__step_over_inst(Arena *arena, DF_Entity *thread)
|
||||
if(machine_code.size != 0)
|
||||
{
|
||||
// rjf: decode instruction
|
||||
DF_Inst inst = df_single_inst_from_machine_code(scratch.arena, arch, ip_vaddr, machine_code);
|
||||
DASM_Inst inst = dasm_inst_from_code(scratch.arena, arch, ip_vaddr, machine_code, DASM_Syntax_Intel);
|
||||
|
||||
// rjf: call => run until call returns
|
||||
if(inst.flags & DF_InstFlag_Call || inst.flags & DF_InstFlag_Repeats)
|
||||
if(inst.flags & DASM_InstFlag_Call || inst.flags & DASM_InstFlag_Repeats)
|
||||
{
|
||||
CTRL_Trap trap = {CTRL_TrapFlag_EndStepping, ip_vaddr+inst.size};
|
||||
ctrl_trap_list_push(arena, &result, &trap);
|
||||
@@ -2925,11 +2735,11 @@ df_trap_net_from_thread__step_over_line(Arena *arena, DF_Entity *thread)
|
||||
if(good_line_info)
|
||||
{
|
||||
ctrl_flow_info = df_ctrl_flow_info_from_arch_vaddr_code(scratch.arena,
|
||||
DF_InstFlag_Call|
|
||||
DF_InstFlag_Branch|
|
||||
DF_InstFlag_UnconditionalJump|
|
||||
DF_InstFlag_ChangesStackPointer|
|
||||
DF_InstFlag_Return,
|
||||
DASM_InstFlag_Call|
|
||||
DASM_InstFlag_Branch|
|
||||
DASM_InstFlag_UnconditionalJump|
|
||||
DASM_InstFlag_ChangesStackPointer|
|
||||
DASM_InstFlag_Return,
|
||||
arch,
|
||||
line_vaddr_rng.min,
|
||||
machine_code);
|
||||
@@ -2938,7 +2748,7 @@ df_trap_net_from_thread__step_over_line(Arena *arena, DF_Entity *thread)
|
||||
log_infof("flags: %x\n", ctrl_flow_info.flags);
|
||||
LogInfoNamedBlockF("exit_points") for(DF_CtrlFlowPointNode *n = ctrl_flow_info.exit_points.first; n != 0; n = n->next)
|
||||
{
|
||||
log_infof("{vaddr:0x%I64x, jump_dest_vaddr:0x%I64x, expected_sp_delta:0x%I64x, inst_flags:%x}\n", n->v.vaddr, n->v.jump_dest_vaddr, n->v.expected_sp_delta, n->v.inst_flags);
|
||||
log_infof("{vaddr:0x%I64x, jump_dest_vaddr:0x%I64x, inst_flags:%x}\n", n->v.vaddr, n->v.jump_dest_vaddr, n->v.inst_flags);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2952,9 +2762,9 @@ df_trap_net_from_thread__step_over_line(Arena *arena, DF_Entity *thread)
|
||||
U64 trap_addr = point->vaddr;
|
||||
|
||||
// rjf: branches/jumps/returns => single-step & end, OR trap @ destination.
|
||||
if(point->inst_flags & (DF_InstFlag_Branch|
|
||||
DF_InstFlag_UnconditionalJump|
|
||||
DF_InstFlag_Return))
|
||||
if(point->inst_flags & (DASM_InstFlag_Branch|
|
||||
DASM_InstFlag_UnconditionalJump|
|
||||
DASM_InstFlag_Return))
|
||||
{
|
||||
flags |= (CTRL_TrapFlag_SingleStepAfterHit|CTRL_TrapFlag_EndStepping);
|
||||
|
||||
@@ -2974,13 +2784,13 @@ df_trap_net_from_thread__step_over_line(Arena *arena, DF_Entity *thread)
|
||||
}
|
||||
|
||||
// rjf: call => place spoof at return spot in stack, single-step after hitting
|
||||
else if(point->inst_flags & DF_InstFlag_Call)
|
||||
else if(point->inst_flags & DASM_InstFlag_Call)
|
||||
{
|
||||
flags |= (CTRL_TrapFlag_BeginSpoofMode|CTRL_TrapFlag_SingleStepAfterHit);
|
||||
}
|
||||
|
||||
// rjf: instruction changes stack pointer => save off the stack pointer, single-step over, keep stepping
|
||||
else if(point->inst_flags & DF_InstFlag_ChangesStackPointer)
|
||||
else if(point->inst_flags & DASM_InstFlag_ChangesStackPointer)
|
||||
{
|
||||
flags |= (CTRL_TrapFlag_SingleStepAfterHit|CTRL_TrapFlag_SaveStackPointer);
|
||||
}
|
||||
@@ -3066,11 +2876,11 @@ df_trap_net_from_thread__step_into_line(Arena *arena, DF_Entity *thread)
|
||||
if(good_line_info)
|
||||
{
|
||||
ctrl_flow_info = df_ctrl_flow_info_from_arch_vaddr_code(scratch.arena,
|
||||
DF_InstFlag_Call|
|
||||
DF_InstFlag_Branch|
|
||||
DF_InstFlag_UnconditionalJump|
|
||||
DF_InstFlag_ChangesStackPointer|
|
||||
DF_InstFlag_Return,
|
||||
DASM_InstFlag_Call|
|
||||
DASM_InstFlag_Branch|
|
||||
DASM_InstFlag_UnconditionalJump|
|
||||
DASM_InstFlag_ChangesStackPointer|
|
||||
DASM_InstFlag_Return,
|
||||
arch,
|
||||
line_vaddr_rng.min,
|
||||
machine_code);
|
||||
@@ -3085,10 +2895,10 @@ df_trap_net_from_thread__step_into_line(Arena *arena, DF_Entity *thread)
|
||||
U64 trap_addr = point->vaddr;
|
||||
|
||||
// rjf: branches/jumps/returns => single-step & end, OR trap @ destination.
|
||||
if(point->inst_flags & (DF_InstFlag_Call|
|
||||
DF_InstFlag_Branch|
|
||||
DF_InstFlag_UnconditionalJump|
|
||||
DF_InstFlag_Return))
|
||||
if(point->inst_flags & (DASM_InstFlag_Call|
|
||||
DASM_InstFlag_Branch|
|
||||
DASM_InstFlag_UnconditionalJump|
|
||||
DASM_InstFlag_Return))
|
||||
{
|
||||
flags |= (CTRL_TrapFlag_SingleStepAfterHit|CTRL_TrapFlag_EndStepping|CTRL_TrapFlag_IgnoreStackPointerCheck);
|
||||
|
||||
@@ -3107,7 +2917,7 @@ df_trap_net_from_thread__step_into_line(Arena *arena, DF_Entity *thread)
|
||||
}
|
||||
|
||||
// rjf: instruction changes stack pointer => save off the stack pointer, single-step over, keep stepping
|
||||
else if(point->inst_flags & DF_InstFlag_ChangesStackPointer)
|
||||
else if(point->inst_flags & DASM_InstFlag_ChangesStackPointer)
|
||||
{
|
||||
flags |= (CTRL_TrapFlag_SingleStepAfterHit|CTRL_TrapFlag_SaveStackPointer);
|
||||
}
|
||||
|
||||
+2
-74
@@ -138,69 +138,6 @@ typedef enum DF_RunKind
|
||||
}
|
||||
DF_RunKind;
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Disassembly Types
|
||||
|
||||
typedef U32 DF_InstFlags;
|
||||
enum
|
||||
{
|
||||
DF_InstFlag_Call = (1<<0),
|
||||
DF_InstFlag_Branch = (1<<1),
|
||||
DF_InstFlag_UnconditionalJump = (1<<2),
|
||||
DF_InstFlag_Return = (1<<3),
|
||||
DF_InstFlag_NonFlow = (1<<4),
|
||||
DF_InstFlag_Repeats = (1<<5),
|
||||
DF_InstFlag_ChangesStackPointer = (1<<6),
|
||||
DF_InstFlag_ChangesStackPointerVariably = (1<<7),
|
||||
};
|
||||
|
||||
typedef struct DF_Inst DF_Inst;
|
||||
struct DF_Inst
|
||||
{
|
||||
DF_InstFlags flags;
|
||||
U64 size;
|
||||
String8 string;
|
||||
U64 rel_voff;
|
||||
S64 sp_delta;
|
||||
};
|
||||
|
||||
typedef struct DF_InstNode DF_InstNode;
|
||||
struct DF_InstNode
|
||||
{
|
||||
DF_InstNode *next;
|
||||
DF_Inst inst;
|
||||
};
|
||||
|
||||
typedef struct DF_InstList DF_InstList;
|
||||
struct DF_InstList
|
||||
{
|
||||
DF_InstNode *first;
|
||||
DF_InstNode *last;
|
||||
U64 count;
|
||||
};
|
||||
|
||||
typedef struct DF_InstArray DF_InstArray;
|
||||
struct DF_InstArray
|
||||
{
|
||||
DF_InstArray *v;
|
||||
U64 count;
|
||||
};
|
||||
|
||||
typedef struct DF_InstMemVOffTuple DF_InstMemVOffTuple;
|
||||
struct DF_InstMemVOffTuple
|
||||
{
|
||||
DF_Inst inst;
|
||||
String8 mem;
|
||||
U64 voff;
|
||||
};
|
||||
|
||||
typedef struct DF_InstMemVOffTupleArray DF_InstMemVOffTupleArray;
|
||||
struct DF_InstMemVOffTupleArray
|
||||
{
|
||||
DF_InstMemVOffTuple *v;
|
||||
U64 count;
|
||||
};
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Control Flow Analysis Types
|
||||
|
||||
@@ -215,8 +152,7 @@ struct DF_CtrlFlowPoint
|
||||
{
|
||||
U64 vaddr;
|
||||
U64 jump_dest_vaddr;
|
||||
S64 expected_sp_delta;
|
||||
DF_InstFlags inst_flags;
|
||||
DASM_InstFlags inst_flags;
|
||||
};
|
||||
|
||||
typedef struct DF_CtrlFlowPointNode DF_CtrlFlowPointNode;
|
||||
@@ -240,7 +176,6 @@ struct DF_CtrlFlowInfo
|
||||
DF_CtrlFlowFlags flags;
|
||||
DF_CtrlFlowPointList exit_points;
|
||||
U64 total_size;
|
||||
S64 cumulative_sp_delta;
|
||||
};
|
||||
|
||||
////////////////////////////////
|
||||
@@ -1456,12 +1391,6 @@ internal String8 df_string_from_cfg_node_children(Arena *arena, DF_CfgNode *node
|
||||
internal Vec4F32 df_hsva_from_cfg_node(DF_CfgNode *node);
|
||||
internal String8 df_string_from_cfg_node_key(DF_CfgNode *node, String8 key, StringMatchFlags flags);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Disassembly Pure Functions
|
||||
|
||||
internal DF_Inst df_single_inst_from_machine_code__x64(Arena *arena, U64 start_voff, String8 string);
|
||||
internal DF_Inst df_single_inst_from_machine_code(Arena *arena, Architecture arch, U64 start_voff, String8 string);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Debug Info Extraction Type Pure Functions
|
||||
|
||||
@@ -1470,8 +1399,7 @@ internal DF_LineList df_line_list_copy(Arena *arena, DF_LineList *list);
|
||||
////////////////////////////////
|
||||
//~ rjf: Control Flow Analysis Pure Functions
|
||||
|
||||
internal DF_CtrlFlowInfo df_ctrl_flow_info_from_vaddr_code__x64(Arena *arena, DF_InstFlags exit_points_mask, U64 vaddr, String8 code);
|
||||
internal DF_CtrlFlowInfo df_ctrl_flow_info_from_arch_vaddr_code(Arena *arena, DF_InstFlags exit_points_mask, Architecture arch, U64 vaddr, String8 code);
|
||||
internal DF_CtrlFlowInfo df_ctrl_flow_info_from_arch_vaddr_code(Arena *arena, DASM_InstFlags exit_points_mask, Architecture arch, U64 vaddr, String8 code);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Command Type Pure Functions
|
||||
|
||||
+1444
-1444
File diff suppressed because it is too large
Load Diff
+17
-17
@@ -410,7 +410,7 @@ df_code_view_init(DF_CodeViewState *cv, DF_View *view)
|
||||
}
|
||||
|
||||
internal void
|
||||
df_code_view_cmds(DF_Window *ws, DF_Panel *panel, DF_View *view, DF_CodeViewState *cv, DF_CmdList *cmds, String8 text_data, TXT_TextInfo *text_info, DASM_InstArray *dasm_insts, Rng1U64 dasm_vaddr_range, DI_Key dasm_dbgi_key)
|
||||
df_code_view_cmds(DF_Window *ws, DF_Panel *panel, DF_View *view, DF_CodeViewState *cv, DF_CmdList *cmds, String8 text_data, TXT_TextInfo *text_info, DASM_LineArray *dasm_lines, Rng1U64 dasm_vaddr_range, DI_Key dasm_dbgi_key)
|
||||
{
|
||||
for(DF_CmdNode *n = cmds->first; n != 0; n = n->next)
|
||||
{
|
||||
@@ -459,7 +459,7 @@ df_code_view_cmds(DF_Window *ws, DF_Panel *panel, DF_View *view, DF_CodeViewStat
|
||||
}
|
||||
|
||||
internal DF_CodeViewBuildResult
|
||||
df_code_view_build(Arena *arena, DF_Window *ws, DF_Panel *panel, DF_View *view, DF_CodeViewState *cv, DF_CodeViewBuildFlags flags, Rng2F32 rect, String8 text_data, TXT_TextInfo *text_info, DASM_InstArray *dasm_insts, Rng1U64 dasm_vaddr_range, DI_Key dasm_dbgi_key)
|
||||
df_code_view_build(Arena *arena, DF_Window *ws, DF_Panel *panel, DF_View *view, DF_CodeViewState *cv, DF_CodeViewBuildFlags flags, Rng2F32 rect, String8 text_data, TXT_TextInfo *text_info, DASM_LineArray *dasm_lines, Rng1U64 dasm_vaddr_range, DI_Key dasm_dbgi_key)
|
||||
{
|
||||
ProfBeginFunction();
|
||||
Temp scratch = scratch_begin(&arena, 1);
|
||||
@@ -669,7 +669,7 @@ df_code_view_build(Arena *arena, DF_Window *ws, DF_Panel *panel, DF_View *view,
|
||||
}
|
||||
|
||||
// rjf: find live threads mapping to disasm
|
||||
if(dasm_insts) ProfScope("find live threads mapping to this disassembly")
|
||||
if(dasm_lines) ProfScope("find live threads mapping to this disassembly")
|
||||
{
|
||||
DF_Entity *selected_thread = df_entity_from_handle(ctrl_ctx.thread);
|
||||
DF_EntityList threads = df_query_cached_entity_list_with_kind(DF_EntityKind_Thread);
|
||||
@@ -681,7 +681,7 @@ df_code_view_build(Arena *arena, DF_Window *ws, DF_Panel *panel, DF_View *view,
|
||||
if(df_entity_ancestor_from_kind(thread, DF_EntityKind_Process) == process && contains_1u64(dasm_vaddr_range, rip_vaddr))
|
||||
{
|
||||
U64 rip_off = rip_vaddr - dasm_vaddr_range.min;
|
||||
S64 line_num = dasm_inst_array_idx_from_code_off__linear_scan(dasm_insts, rip_off)+1;
|
||||
S64 line_num = dasm_line_array_idx_from_code_off__linear_scan(dasm_lines, rip_off)+1;
|
||||
if(contains_1s64(visible_line_num_range, line_num))
|
||||
{
|
||||
U64 slice_line_idx = (line_num-visible_line_num_range.min);
|
||||
@@ -692,7 +692,7 @@ df_code_view_build(Arena *arena, DF_Window *ws, DF_Panel *panel, DF_View *view,
|
||||
}
|
||||
|
||||
// rjf: find breakpoints mapping to this disasm
|
||||
if(dasm_insts) ProfScope("find breakpoints mapping to this disassembly")
|
||||
if(dasm_lines) ProfScope("find breakpoints mapping to this disassembly")
|
||||
{
|
||||
DF_EntityList bps = df_query_cached_entity_list_with_kind(DF_EntityKind_Breakpoint);
|
||||
for(DF_EntityNode *n = bps.first; n != 0; n = n->next)
|
||||
@@ -701,7 +701,7 @@ df_code_view_build(Arena *arena, DF_Window *ws, DF_Panel *panel, DF_View *view,
|
||||
if(bp->flags & DF_EntityFlag_HasVAddr && contains_1u64(dasm_vaddr_range, bp->vaddr))
|
||||
{
|
||||
U64 off = bp->vaddr-dasm_vaddr_range.min;
|
||||
U64 idx = dasm_inst_array_idx_from_code_off__linear_scan(dasm_insts, off);
|
||||
U64 idx = dasm_line_array_idx_from_code_off__linear_scan(dasm_lines, off);
|
||||
S64 line_num = (S64)(idx+1);
|
||||
if(contains_1s64(visible_line_num_range, line_num))
|
||||
{
|
||||
@@ -713,7 +713,7 @@ df_code_view_build(Arena *arena, DF_Window *ws, DF_Panel *panel, DF_View *view,
|
||||
}
|
||||
|
||||
// rjf: find watch pins mapping to this disasm
|
||||
if(dasm_insts) ProfScope("find watch pins mapping to this disassembly")
|
||||
if(dasm_lines) ProfScope("find watch pins mapping to this disassembly")
|
||||
{
|
||||
DF_EntityList pins = df_query_cached_entity_list_with_kind(DF_EntityKind_WatchPin);
|
||||
for(DF_EntityNode *n = pins.first; n != 0; n = n->next)
|
||||
@@ -722,7 +722,7 @@ df_code_view_build(Arena *arena, DF_Window *ws, DF_Panel *panel, DF_View *view,
|
||||
if(pin->flags & DF_EntityFlag_HasVAddr && contains_1u64(dasm_vaddr_range, pin->vaddr))
|
||||
{
|
||||
U64 off = pin->vaddr-dasm_vaddr_range.min;
|
||||
U64 idx = dasm_inst_array_idx_from_code_off__linear_scan(dasm_insts, off);
|
||||
U64 idx = dasm_line_array_idx_from_code_off__linear_scan(dasm_lines, off);
|
||||
S64 line_num = (S64)(idx+1);
|
||||
if(contains_1s64(visible_line_num_range, line_num))
|
||||
{
|
||||
@@ -734,13 +734,13 @@ df_code_view_build(Arena *arena, DF_Window *ws, DF_Panel *panel, DF_View *view,
|
||||
}
|
||||
|
||||
// rjf: fill dasm -> src info
|
||||
if(dasm_insts)
|
||||
if(dasm_lines)
|
||||
{
|
||||
DF_Entity *module = df_module_from_process_vaddr(process, dasm_vaddr_range.min);
|
||||
DI_Key dbgi_key = df_dbgi_key_from_module(module);
|
||||
for(S64 line_num = visible_line_num_range.min; line_num < visible_line_num_range.max; line_num += 1)
|
||||
{
|
||||
U64 vaddr = dasm_vaddr_range.min + dasm_inst_array_code_off_from_idx(dasm_insts, line_num-1);
|
||||
U64 vaddr = dasm_vaddr_range.min + dasm_line_array_code_off_from_idx(dasm_lines, line_num-1);
|
||||
U64 voff = df_voff_from_vaddr(module, vaddr);
|
||||
U64 slice_idx = line_num-visible_line_num_range.min;
|
||||
code_slice_params.line_vaddrs[slice_idx] = vaddr;
|
||||
@@ -749,7 +749,7 @@ df_code_view_build(Arena *arena, DF_Window *ws, DF_Panel *panel, DF_View *view,
|
||||
}
|
||||
|
||||
// rjf: add dasm dbgi key to relevant dbgis
|
||||
if(dasm_insts != 0)
|
||||
if(dasm_lines != 0)
|
||||
{
|
||||
di_key_list_push(scratch.arena, &code_slice_params.relevant_dbgi_keys, &dasm_dbgi_key);
|
||||
}
|
||||
@@ -6691,7 +6691,7 @@ DF_VIEW_CMD_FUNCTION_DEF(Disassembly)
|
||||
String8 dasm_text_data = hs_data_from_hash(hs_scope, dasm_text_hash);
|
||||
|
||||
//- rjf: process general code-view commands
|
||||
df_code_view_cmds(ws, panel, view, &dv->cv, cmds, dasm_text_data, &dasm_text_info, &dasm_info.insts, dasm_vaddr_range, dasm_dbgi_key);
|
||||
df_code_view_cmds(ws, panel, view, &dv->cv, cmds, dasm_text_data, &dasm_text_info, &dasm_info.lines, dasm_vaddr_range, dasm_dbgi_key);
|
||||
|
||||
//- rjf: process disassembly-specific commands
|
||||
for(DF_CmdNode *n = cmds->first; n != 0; n = n->next)
|
||||
@@ -6798,7 +6798,7 @@ DF_VIEW_UI_FUNCTION_DEF(Disassembly)
|
||||
U128 dasm_text_hash = {0};
|
||||
TXT_TextInfo dasm_text_info = txt_text_info_from_key_lang(txt_scope, df_interact_regs()->text_key, df_interact_regs()->lang_kind, &dasm_text_hash);
|
||||
String8 dasm_text_data = hs_data_from_hash(hs_scope, dasm_text_hash);
|
||||
B32 has_disasm = (dasm_info.insts.count != 0 && dasm_text_info.lines_count != 0);
|
||||
B32 has_disasm = (dasm_info.lines.count != 0 && dasm_text_info.lines_count != 0);
|
||||
B32 is_loading = (!has_disasm && !df_entity_is_nil(process) && dim_1u64(dasm_vaddr_range) != 0);
|
||||
|
||||
//////////////////////////////
|
||||
@@ -6816,7 +6816,7 @@ DF_VIEW_UI_FUNCTION_DEF(Disassembly)
|
||||
{
|
||||
U64 vaddr = dv->goto_vaddr;
|
||||
dv->goto_vaddr = 0;
|
||||
U64 line_idx = dasm_inst_array_idx_from_code_off__linear_scan(&dasm_info.insts, vaddr-dasm_vaddr_range.min);
|
||||
U64 line_idx = dasm_line_array_idx_from_code_off__linear_scan(&dasm_info.lines, vaddr-dasm_vaddr_range.min);
|
||||
S64 line_num = (S64)(line_idx+1);
|
||||
cv->goto_line_num = line_num;
|
||||
}
|
||||
@@ -6826,7 +6826,7 @@ DF_VIEW_UI_FUNCTION_DEF(Disassembly)
|
||||
//
|
||||
if(!is_loading && has_disasm)
|
||||
{
|
||||
df_code_view_build(scratch.arena, ws, panel, view, cv, DF_CodeViewBuildFlag_All, code_area_rect, dasm_text_data, &dasm_text_info, &dasm_info.insts, dasm_vaddr_range, dasm_dbgi_key);
|
||||
df_code_view_build(scratch.arena, ws, panel, view, cv, DF_CodeViewBuildFlag_All, code_area_rect, dasm_text_data, &dasm_text_info, &dasm_info.lines, dasm_vaddr_range, dasm_dbgi_key);
|
||||
}
|
||||
|
||||
//////////////////////////////
|
||||
@@ -6834,7 +6834,7 @@ DF_VIEW_UI_FUNCTION_DEF(Disassembly)
|
||||
//
|
||||
if(!is_loading && has_disasm)
|
||||
{
|
||||
U64 off = dasm_inst_array_code_off_from_idx(&dasm_info.insts, df_interact_regs()->cursor.line-1);
|
||||
U64 off = dasm_line_array_code_off_from_idx(&dasm_info.lines, df_interact_regs()->cursor.line-1);
|
||||
df_interact_regs()->vaddr_range = r1u64(dasm_base_vaddr+off, dasm_base_vaddr+off);
|
||||
df_interact_regs()->voff_range = df_voff_range_from_vaddr_range(dasm_module, df_interact_regs()->vaddr_range);
|
||||
df_interact_regs()->lines = df_lines_from_dbgi_key_voff(df_frame_arena(), &dasm_dbgi_key, df_interact_regs()->voff_range.min);
|
||||
@@ -6854,7 +6854,7 @@ DF_VIEW_UI_FUNCTION_DEF(Disassembly)
|
||||
DF_Font(ws, DF_FontSlot_Code)
|
||||
{
|
||||
DF_Entity *module = df_module_from_process_vaddr(process, dasm_vaddr_range.min);
|
||||
U64 cursor_vaddr = (1 <= view->cursor.line && view->cursor.line <= dasm_info.insts.count) ? (dasm_vaddr_range.min+dasm_info.insts.v[view->cursor.line-1].code_off) : 0;
|
||||
U64 cursor_vaddr = (1 <= view->cursor.line && view->cursor.line <= dasm_info.lines.count) ? (dasm_vaddr_range.min+dasm_info.lines.v[view->cursor.line-1].code_off) : 0;
|
||||
ui_labelf("%S", path_normalized_from_string(scratch.arena, module->name));
|
||||
ui_spacer(ui_em(1.5f, 1));
|
||||
ui_labelf("Address: 0x%I64x, Line: %I64d, Column: %I64d", cursor_vaddr, view->cursor.line, view->cursor.column);
|
||||
|
||||
+571
-571
File diff suppressed because it is too large
Load Diff
Vendored
-47
@@ -1,47 +0,0 @@
|
||||
v1.7.2
|
||||
|
||||
* Clean up input handling, removing unnecessary caching
|
||||
of input, which should speed up things.
|
||||
* Add the missing ud_insn_mnemonic api function.
|
||||
* Rename ud_opr_isgpr to ud_opr_is_gpr.
|
||||
* Fix decoding of relative jumps.
|
||||
* Fix build with automake-1.14
|
||||
* Minor fix to AT&T syntax (missing "$" prefix for immedaites)
|
||||
* Add a new api checker (tests/libcheck.c).
|
||||
* Add a standalone script for diff-testing (tests/difftest.sh)
|
||||
* Refinements to the documentation.
|
||||
|
||||
Acknowledgements:
|
||||
|
||||
Brendan Long (https://github.com/brendanlong)
|
||||
radare (https://github.com/radare)
|
||||
Sergey Basalaev (https://github.com/SBasalaev)
|
||||
ebfe (https://github.com/ebfe)
|
||||
|
||||
v1.7.1
|
||||
|
||||
* Full support for SSSE3, SSE4.1, SSE4.2, SMX, AES.
|
||||
* New Sphinx-doc/RST based documentation.
|
||||
* New api for client size symbol resolver.
|
||||
* Visual Studio 2010 Build Support.
|
||||
* Added an operand tester.
|
||||
* Python 3.0 compatibility changes.
|
||||
* Minor fixes to AT&T syntax.
|
||||
* Fix install directory for data files.
|
||||
* Many bug fixes, and optable updates.
|
||||
* Add Texinfo document (make install-info).
|
||||
|
||||
Acknowledgements:
|
||||
|
||||
L Peter Deutsch (https://github.com/ghghost)
|
||||
Bjoern Doebel (https://github.com/bjoernd)
|
||||
Justin Stenning (http://github.com/spazzarama)
|
||||
Jamie Iles (https://github.com/jamieiles)
|
||||
Stephen Fewer (https://github.com/stephenfewer)
|
||||
Piotr Gaczkowski (https://github.com/DoomHammer)
|
||||
Evan Pheonix
|
||||
mbarbu (https://github.com/mbarbu)
|
||||
|
||||
|
||||
|
||||
Please see the commit logs for change information for older releases
|
||||
Vendored
-22
@@ -1,22 +0,0 @@
|
||||
Copyright (c) 2002-2012, Vivek Thampi <vivek.mt@gmail.com>
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
Vendored
-91
@@ -1,91 +0,0 @@
|
||||
Udis86
|
||||
======
|
||||
|
||||
Udis86 is a disassembler for the x86 and x86-64 class of instruction set
|
||||
architectures. It consists of a C library called libudis86 which
|
||||
provides a clean and simple interface to decode a stream of raw binary
|
||||
data, and to inspect the disassembled instructions in a structured
|
||||
manner.
|
||||
|
||||
|
||||
LICENSE
|
||||
-------
|
||||
|
||||
Udis86 is distributed under the terms of the 2-clause "Simplified BSD
|
||||
License". A copy of the license is included with the source in LICENSE.
|
||||
|
||||
|
||||
libudis86
|
||||
---------
|
||||
|
||||
o Supports all x86 and x86-64 (AMD64) General purpose and
|
||||
System instructions.
|
||||
o Supported ISA extensions:
|
||||
- MMX, FPU (x87), AMD 3DNow
|
||||
- SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2, AES,
|
||||
- AMD-V, INTEL-VMX, SMX
|
||||
o Instructions are defined in an XML document, with opcode
|
||||
tables generated for performance.
|
||||
o Supports output in both INTEL (NASM) as well as AT&T (GNU as) style
|
||||
assembly language syntax.
|
||||
o Supports a variety of input methods: Files, Memory Buffers, and
|
||||
Function Callback hooks.
|
||||
o Re-entrant, no dynamic memory allocation.
|
||||
o Fully documented API
|
||||
|
||||
|
||||
-- EXAMPLE -----------------------------------------------------------
|
||||
|
||||
ud_t u;
|
||||
|
||||
ud_init(&u);
|
||||
ud_set_input_file(&u, stdin);
|
||||
ud_set_mode(&u, 64);
|
||||
ud_set_syntax(&u, UD_SYN_INTEL);
|
||||
|
||||
while (ud_disassemble(&u)) {
|
||||
printf("\t%s\n", ud_insn_asm(&ud_obj));
|
||||
}
|
||||
|
||||
----------------------------------------------------------------------
|
||||
|
||||
|
||||
udcli
|
||||
-----
|
||||
|
||||
udcli is a small command-line tool for your quick disassembly needs.
|
||||
|
||||
-- EXAMPLE -----------------------------------------------------------
|
||||
|
||||
$ echo "65 67 89 87 76 65 54 56 78 89 09 00 90" | udcli -32 -x
|
||||
0000000080000800 656789877665 mov [gs:bx+0x6576], eax
|
||||
0000000080000806 54 push esp
|
||||
0000000080000807 56 push esi
|
||||
0000000080000808 7889 js 0x80000793
|
||||
000000008000080a 0900 or [eax], eax
|
||||
000000008000080c 90 nop
|
||||
|
||||
----------------------------------------------------------------------
|
||||
|
||||
|
||||
Documentation
|
||||
-------------
|
||||
|
||||
The libudis86 api is fully documented. The package distribution contains
|
||||
a Texinfo file which can be installed by invoking "make install-info".
|
||||
You can also find an online html version of the documentation available
|
||||
at http://udis86.sourceforge.net/.
|
||||
|
||||
|
||||
Autotools Build
|
||||
---------------
|
||||
|
||||
You need autotools if building from sources cloned form version control
|
||||
system, or if you need to regenerate the build system. The wrapper
|
||||
script 'autogen.sh' is provided that'll generate the build system.
|
||||
|
||||
|
||||
AUTHOR
|
||||
------
|
||||
|
||||
Udis86 is written and maintained by Vivek Thampi (vivek.mt@gmail.com).
|
||||
Vendored
-24
@@ -1,24 +0,0 @@
|
||||
udis86 Version 1.7.2
|
||||
Disassembler library written in C, by vivek.mt@gmail.com
|
||||
2-clause BSD license (see LICENSE)
|
||||
|
||||
Documentation: http://udis86.sourceforge.net/
|
||||
|
||||
Checked out from https://github.com/vmt/udis86
|
||||
commit b24baf1e32bdd9ea12cc9f6dc4882b6ba04de0d7
|
||||
Date: Thu Nov 14 12:28:33 2013 -0800
|
||||
|
||||
Various unnecessary parts, like unittests, bootstrapping scripts and a
|
||||
command-line utility have been stripped out. This is just the bare
|
||||
library.
|
||||
|
||||
In a normal build, libudis86/itab.h libudis86/itab.c are actually
|
||||
generated from XML tables and a python script, but I've simply checked
|
||||
in the generated results to keep things smaller and avoid that
|
||||
bootstrapping step.
|
||||
|
||||
I did something similar with config.h, which would normally be
|
||||
generated through automake/configure. This is probably less OK, but
|
||||
will do for now.
|
||||
|
||||
-Won (wonc@radgametools.com)
|
||||
Vendored
-72
@@ -1,72 +0,0 @@
|
||||
/* config.h. Generated from config.h.in by configure. */
|
||||
/* config.h.in. Generated from configure.ac by autoheader. */
|
||||
|
||||
/* Define to 1 if you have the <assert.h> header file. */
|
||||
#define HAVE_ASSERT_H 1
|
||||
|
||||
/* Define to 1 if you have the <dlfcn.h> header file. */
|
||||
#define HAVE_DLFCN_H 1
|
||||
|
||||
/* Define to 1 if you have the <inttypes.h> header file. */
|
||||
#define HAVE_INTTYPES_H 1
|
||||
|
||||
/* Define to 1 if you have the <memory.h> header file. */
|
||||
#define HAVE_MEMORY_H 1
|
||||
|
||||
/* Define to 1 if you have the <stdint.h> header file. */
|
||||
#define HAVE_STDINT_H 1
|
||||
|
||||
/* Define to 1 if you have the <stdio.h> header file. */
|
||||
#define HAVE_STDIO_H 1
|
||||
|
||||
/* Define to 1 if you have the <stdlib.h> header file. */
|
||||
#define HAVE_STDLIB_H 1
|
||||
|
||||
/* Define to 1 if you have the <strings.h> header file. */
|
||||
#define HAVE_STRINGS_H 1
|
||||
|
||||
/* Define to 1 if you have the <string.h> header file. */
|
||||
#define HAVE_STRING_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/stat.h> header file. */
|
||||
#define HAVE_SYS_STAT_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/types.h> header file. */
|
||||
#define HAVE_SYS_TYPES_H 1
|
||||
|
||||
/* Define to 1 if you have the <unistd.h> header file. */
|
||||
#define HAVE_UNISTD_H 1
|
||||
|
||||
/* Define to the sub-directory in which libtool stores uninstalled libraries.
|
||||
*/
|
||||
#define LT_OBJDIR ".libs/"
|
||||
|
||||
/* Define to 1 if your C compiler doesn't accept -c and -o together. */
|
||||
/* #undef NO_MINUS_C_MINUS_O */
|
||||
|
||||
/* Name of package */
|
||||
#define PACKAGE "udis86"
|
||||
|
||||
/* Define to the address where bug reports for this package should be sent. */
|
||||
#define PACKAGE_BUGREPORT "vivek.mt@gmail.com"
|
||||
|
||||
/* Define to the full name of this package. */
|
||||
#define PACKAGE_NAME "udis86"
|
||||
|
||||
/* Define to the full name and version of this package. */
|
||||
#define PACKAGE_STRING "udis86 1.7.2"
|
||||
|
||||
/* Define to the one symbol short name of this package. */
|
||||
#define PACKAGE_TARNAME "udis86"
|
||||
|
||||
/* Define to the home page for this package. */
|
||||
#define PACKAGE_URL ""
|
||||
|
||||
/* Define to the version of this package. */
|
||||
#define PACKAGE_VERSION "1.7.2"
|
||||
|
||||
/* Define to 1 if you have the ANSI C header files. */
|
||||
#define STDC_HEADERS 1
|
||||
|
||||
/* Version number of package */
|
||||
#define VERSION "1.7.2"
|
||||
-1264
File diff suppressed because it is too large
Load Diff
-197
@@ -1,197 +0,0 @@
|
||||
/* udis86 - libudis86/decode.h
|
||||
*
|
||||
* Copyright (c) 2002-2009 Vivek Thampi
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#ifndef UD_DECODE_H
|
||||
#define UD_DECODE_H
|
||||
|
||||
#include "types.h"
|
||||
#include "udint.h"
|
||||
#include "itab.h"
|
||||
|
||||
#define MAX_INSN_LENGTH 15
|
||||
|
||||
/* itab prefix bits */
|
||||
#define P_none ( 0 )
|
||||
|
||||
#define P_inv64 ( 1 << 0 )
|
||||
#define P_INV64(n) ( ( n >> 0 ) & 1 )
|
||||
#define P_def64 ( 1 << 1 )
|
||||
#define P_DEF64(n) ( ( n >> 1 ) & 1 )
|
||||
|
||||
#define P_oso ( 1 << 2 )
|
||||
#define P_OSO(n) ( ( n >> 2 ) & 1 )
|
||||
#define P_aso ( 1 << 3 )
|
||||
#define P_ASO(n) ( ( n >> 3 ) & 1 )
|
||||
|
||||
#define P_rexb ( 1 << 4 )
|
||||
#define P_REXB(n) ( ( n >> 4 ) & 1 )
|
||||
#define P_rexw ( 1 << 5 )
|
||||
#define P_REXW(n) ( ( n >> 5 ) & 1 )
|
||||
#define P_rexr ( 1 << 6 )
|
||||
#define P_REXR(n) ( ( n >> 6 ) & 1 )
|
||||
#define P_rexx ( 1 << 7 )
|
||||
#define P_REXX(n) ( ( n >> 7 ) & 1 )
|
||||
|
||||
#define P_seg ( 1 << 8 )
|
||||
#define P_SEG(n) ( ( n >> 8 ) & 1 )
|
||||
|
||||
#define P_vexl ( 1 << 9 )
|
||||
#define P_VEXL(n) ( ( n >> 9 ) & 1 )
|
||||
#define P_vexw ( 1 << 10 )
|
||||
#define P_VEXW(n) ( ( n >> 10 ) & 1 )
|
||||
|
||||
#define P_str ( 1 << 11 )
|
||||
#define P_STR(n) ( ( n >> 11 ) & 1 )
|
||||
#define P_strz ( 1 << 12 )
|
||||
#define P_STR_ZF(n) ( ( n >> 12 ) & 1 )
|
||||
|
||||
/* operand type constants -- order is important! */
|
||||
|
||||
enum ud_operand_code {
|
||||
OP_NONE,
|
||||
|
||||
OP_A, OP_E, OP_M, OP_G,
|
||||
OP_I, OP_F,
|
||||
|
||||
OP_R0, OP_R1, OP_R2, OP_R3,
|
||||
OP_R4, OP_R5, OP_R6, OP_R7,
|
||||
|
||||
OP_AL, OP_CL, OP_DL,
|
||||
OP_AX, OP_CX, OP_DX,
|
||||
OP_eAX, OP_eCX, OP_eDX,
|
||||
OP_rAX, OP_rCX, OP_rDX,
|
||||
|
||||
OP_ES, OP_CS, OP_SS, OP_DS,
|
||||
OP_FS, OP_GS,
|
||||
|
||||
OP_ST0, OP_ST1, OP_ST2, OP_ST3,
|
||||
OP_ST4, OP_ST5, OP_ST6, OP_ST7,
|
||||
|
||||
OP_J, OP_S, OP_O,
|
||||
OP_I1, OP_I3, OP_sI,
|
||||
|
||||
OP_V, OP_W, OP_Q, OP_P,
|
||||
OP_U, OP_N, OP_MU, OP_H,
|
||||
OP_L,
|
||||
|
||||
OP_R, OP_C, OP_D,
|
||||
|
||||
OP_MR
|
||||
} UD_ATTR_PACKED;
|
||||
|
||||
|
||||
/*
|
||||
* Operand size constants
|
||||
*
|
||||
* Symbolic constants for various operand sizes. Some of these constants
|
||||
* are given a value equal to the width of the data (SZ_B == 8), such
|
||||
* that they maybe used interchangeably in the internals. Modifying them
|
||||
* will most certainly break things!
|
||||
*/
|
||||
typedef uint16_t ud_operand_size_t;
|
||||
|
||||
#define SZ_NA 0
|
||||
#define SZ_Z 1
|
||||
#define SZ_V 2
|
||||
#define SZ_Y 3
|
||||
#define SZ_X 4
|
||||
#define SZ_RDQ 7
|
||||
#define SZ_B 8
|
||||
#define SZ_W 16
|
||||
#define SZ_D 32
|
||||
#define SZ_Q 64
|
||||
#define SZ_T 80
|
||||
#define SZ_O 12
|
||||
#define SZ_DQ 128 /* double quad */
|
||||
#define SZ_QQ 256 /* quad quad */
|
||||
|
||||
/*
|
||||
* Complex size types; that encode sizes for operands of type MR (memory or
|
||||
* register); for internal use only. Id space above 256.
|
||||
*/
|
||||
#define SZ_BD ((SZ_B << 8) | SZ_D)
|
||||
#define SZ_BV ((SZ_B << 8) | SZ_V)
|
||||
#define SZ_WD ((SZ_W << 8) | SZ_D)
|
||||
#define SZ_WV ((SZ_W << 8) | SZ_V)
|
||||
#define SZ_WY ((SZ_W << 8) | SZ_Y)
|
||||
#define SZ_DY ((SZ_D << 8) | SZ_Y)
|
||||
#define SZ_WO ((SZ_W << 8) | SZ_O)
|
||||
#define SZ_DO ((SZ_D << 8) | SZ_O)
|
||||
#define SZ_QO ((SZ_Q << 8) | SZ_O)
|
||||
|
||||
|
||||
/* resolve complex size type.
|
||||
*/
|
||||
static UD_INLINE ud_operand_size_t
|
||||
Mx_mem_size(ud_operand_size_t size)
|
||||
{
|
||||
return (size >> 8) & 0xff;
|
||||
}
|
||||
|
||||
static UD_INLINE ud_operand_size_t
|
||||
Mx_reg_size(ud_operand_size_t size)
|
||||
{
|
||||
return size & 0xff;
|
||||
}
|
||||
|
||||
/* A single operand of an entry in the instruction table.
|
||||
* (internal use only)
|
||||
*/
|
||||
struct ud_itab_entry_operand
|
||||
{
|
||||
enum ud_operand_code type;
|
||||
ud_operand_size_t size;
|
||||
};
|
||||
|
||||
|
||||
/* A single entry in an instruction table.
|
||||
*(internal use only)
|
||||
*/
|
||||
struct ud_itab_entry
|
||||
{
|
||||
enum ud_mnemonic_code mnemonic;
|
||||
struct ud_itab_entry_operand operand1;
|
||||
struct ud_itab_entry_operand operand2;
|
||||
struct ud_itab_entry_operand operand3;
|
||||
struct ud_itab_entry_operand operand4;
|
||||
uint32_t prefix;
|
||||
};
|
||||
|
||||
struct ud_lookup_table_list_entry {
|
||||
const uint16_t *table;
|
||||
enum ud_table_type type;
|
||||
const char *meta;
|
||||
};
|
||||
|
||||
extern struct ud_itab_entry ud_itab[];
|
||||
extern struct ud_lookup_table_list_entry ud_lookup_table_list[];
|
||||
|
||||
#endif /* UD_DECODE_H */
|
||||
|
||||
/* vim:cindent
|
||||
* vim:expandtab
|
||||
* vim:ts=4
|
||||
* vim:sw=4
|
||||
*/
|
||||
-113
@@ -1,113 +0,0 @@
|
||||
/* udis86 - libudis86/extern.h
|
||||
*
|
||||
* Copyright (c) 2002-2009, 2013 Vivek Thampi
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#ifndef UD_EXTERN_H
|
||||
#define UD_EXTERN_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "types.h"
|
||||
|
||||
#if defined(_MSC_VER) && defined(_USRDLL)
|
||||
# ifdef LIBUDIS86_EXPORTS
|
||||
# define LIBUDIS86_DLLEXTERN __declspec(dllexport)
|
||||
# else
|
||||
# define LIBUDIS86_DLLEXTERN __declspec(dllimport)
|
||||
# endif
|
||||
#else
|
||||
# define LIBUDIS86_DLLEXTERN
|
||||
#endif
|
||||
|
||||
/* ============================= PUBLIC API ================================= */
|
||||
|
||||
extern LIBUDIS86_DLLEXTERN void ud_init(struct ud*);
|
||||
|
||||
extern LIBUDIS86_DLLEXTERN void ud_set_mode(struct ud*, uint8_t);
|
||||
|
||||
extern LIBUDIS86_DLLEXTERN void ud_set_pc(struct ud*, uint64_t);
|
||||
|
||||
extern LIBUDIS86_DLLEXTERN void ud_set_input_hook(struct ud*, int (*)(struct ud*));
|
||||
|
||||
extern LIBUDIS86_DLLEXTERN void ud_set_input_buffer(struct ud*, const uint8_t*, size_t);
|
||||
|
||||
#ifndef __UD_STANDALONE__
|
||||
extern LIBUDIS86_DLLEXTERN void ud_set_input_file(struct ud*, FILE*);
|
||||
#endif /* __UD_STANDALONE__ */
|
||||
|
||||
extern LIBUDIS86_DLLEXTERN void ud_set_vendor(struct ud*, unsigned);
|
||||
|
||||
extern LIBUDIS86_DLLEXTERN void ud_set_syntax(struct ud*, void (*)(struct ud*));
|
||||
|
||||
extern LIBUDIS86_DLLEXTERN void ud_input_skip(struct ud*, size_t);
|
||||
|
||||
extern LIBUDIS86_DLLEXTERN int ud_input_end(const struct ud*);
|
||||
|
||||
extern LIBUDIS86_DLLEXTERN unsigned int ud_decode(struct ud*);
|
||||
|
||||
extern LIBUDIS86_DLLEXTERN unsigned int ud_disassemble(struct ud*);
|
||||
|
||||
extern LIBUDIS86_DLLEXTERN void ud_translate_intel(struct ud*);
|
||||
|
||||
extern LIBUDIS86_DLLEXTERN void ud_translate_att(struct ud*);
|
||||
|
||||
extern LIBUDIS86_DLLEXTERN const char* ud_insn_asm(const struct ud* u);
|
||||
|
||||
extern LIBUDIS86_DLLEXTERN const uint8_t* ud_insn_ptr(const struct ud* u);
|
||||
|
||||
extern LIBUDIS86_DLLEXTERN uint64_t ud_insn_off(const struct ud*);
|
||||
|
||||
extern LIBUDIS86_DLLEXTERN const char* ud_insn_hex(struct ud*);
|
||||
|
||||
extern LIBUDIS86_DLLEXTERN unsigned int ud_insn_len(const struct ud* u);
|
||||
|
||||
extern LIBUDIS86_DLLEXTERN const struct ud_operand* ud_insn_opr(const struct ud *u, unsigned int n);
|
||||
|
||||
extern LIBUDIS86_DLLEXTERN int ud_opr_is_sreg(const struct ud_operand *opr);
|
||||
|
||||
extern LIBUDIS86_DLLEXTERN int ud_opr_is_gpr(const struct ud_operand *opr);
|
||||
|
||||
extern LIBUDIS86_DLLEXTERN enum ud_mnemonic_code ud_insn_mnemonic(const struct ud *u);
|
||||
|
||||
extern LIBUDIS86_DLLEXTERN const char* ud_lookup_mnemonic(enum ud_mnemonic_code c);
|
||||
|
||||
extern LIBUDIS86_DLLEXTERN void ud_set_user_opaque_data(struct ud*, void*);
|
||||
|
||||
extern LIBUDIS86_DLLEXTERN void* ud_get_user_opaque_data(const struct ud*);
|
||||
|
||||
extern LIBUDIS86_DLLEXTERN void ud_set_asm_buffer(struct ud *u, char *buf, size_t size);
|
||||
|
||||
extern LIBUDIS86_DLLEXTERN void ud_set_sym_resolver(struct ud *u,
|
||||
const char* (*resolver)(struct ud*,
|
||||
uint64_t addr,
|
||||
int64_t *offset));
|
||||
|
||||
/* ========================================================================== */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /* UD_EXTERN_H */
|
||||
-5937
File diff suppressed because it is too large
Load Diff
-935
@@ -1,935 +0,0 @@
|
||||
#ifndef UD_ITAB_H
|
||||
#define UD_ITAB_H
|
||||
|
||||
/* itab.h -- generated by udis86:scripts/ud_itab.py, do no edit */
|
||||
|
||||
/* ud_table_type -- lookup table types (see decode.c) */
|
||||
enum ud_table_type {
|
||||
UD_TAB__OPC_VEX,
|
||||
UD_TAB__OPC_TABLE,
|
||||
UD_TAB__OPC_X87,
|
||||
UD_TAB__OPC_MOD,
|
||||
UD_TAB__OPC_RM,
|
||||
UD_TAB__OPC_OSIZE,
|
||||
UD_TAB__OPC_MODE,
|
||||
UD_TAB__OPC_VEX_L,
|
||||
UD_TAB__OPC_3DNOW,
|
||||
UD_TAB__OPC_REG,
|
||||
UD_TAB__OPC_ASIZE,
|
||||
UD_TAB__OPC_VEX_W,
|
||||
UD_TAB__OPC_SSE,
|
||||
UD_TAB__OPC_VENDOR
|
||||
};
|
||||
|
||||
/* ud_mnemonic -- mnemonic constants */
|
||||
enum ud_mnemonic_code {
|
||||
UD_Iaaa,
|
||||
UD_Iaad,
|
||||
UD_Iaam,
|
||||
UD_Iaas,
|
||||
UD_Iadc,
|
||||
UD_Iadd,
|
||||
UD_Iaddpd,
|
||||
UD_Iaddps,
|
||||
UD_Iaddsd,
|
||||
UD_Iaddss,
|
||||
UD_Iaddsubpd,
|
||||
UD_Iaddsubps,
|
||||
UD_Iaesdec,
|
||||
UD_Iaesdeclast,
|
||||
UD_Iaesenc,
|
||||
UD_Iaesenclast,
|
||||
UD_Iaesimc,
|
||||
UD_Iaeskeygenassist,
|
||||
UD_Iand,
|
||||
UD_Iandnpd,
|
||||
UD_Iandnps,
|
||||
UD_Iandpd,
|
||||
UD_Iandps,
|
||||
UD_Iarpl,
|
||||
UD_Iblendpd,
|
||||
UD_Iblendps,
|
||||
UD_Iblendvpd,
|
||||
UD_Iblendvps,
|
||||
UD_Ibound,
|
||||
UD_Ibsf,
|
||||
UD_Ibsr,
|
||||
UD_Ibswap,
|
||||
UD_Ibt,
|
||||
UD_Ibtc,
|
||||
UD_Ibtr,
|
||||
UD_Ibts,
|
||||
UD_Icall,
|
||||
UD_Icbw,
|
||||
UD_Icdq,
|
||||
UD_Icdqe,
|
||||
UD_Iclc,
|
||||
UD_Icld,
|
||||
UD_Iclflush,
|
||||
UD_Iclgi,
|
||||
UD_Icli,
|
||||
UD_Iclts,
|
||||
UD_Icmc,
|
||||
UD_Icmova,
|
||||
UD_Icmovae,
|
||||
UD_Icmovb,
|
||||
UD_Icmovbe,
|
||||
UD_Icmovg,
|
||||
UD_Icmovge,
|
||||
UD_Icmovl,
|
||||
UD_Icmovle,
|
||||
UD_Icmovno,
|
||||
UD_Icmovnp,
|
||||
UD_Icmovns,
|
||||
UD_Icmovnz,
|
||||
UD_Icmovo,
|
||||
UD_Icmovp,
|
||||
UD_Icmovs,
|
||||
UD_Icmovz,
|
||||
UD_Icmp,
|
||||
UD_Icmppd,
|
||||
UD_Icmpps,
|
||||
UD_Icmpsb,
|
||||
UD_Icmpsd,
|
||||
UD_Icmpsq,
|
||||
UD_Icmpss,
|
||||
UD_Icmpsw,
|
||||
UD_Icmpxchg,
|
||||
UD_Icmpxchg16b,
|
||||
UD_Icmpxchg8b,
|
||||
UD_Icomisd,
|
||||
UD_Icomiss,
|
||||
UD_Icpuid,
|
||||
UD_Icqo,
|
||||
UD_Icrc32,
|
||||
UD_Icvtdq2pd,
|
||||
UD_Icvtdq2ps,
|
||||
UD_Icvtpd2dq,
|
||||
UD_Icvtpd2pi,
|
||||
UD_Icvtpd2ps,
|
||||
UD_Icvtpi2pd,
|
||||
UD_Icvtpi2ps,
|
||||
UD_Icvtps2dq,
|
||||
UD_Icvtps2pd,
|
||||
UD_Icvtps2pi,
|
||||
UD_Icvtsd2si,
|
||||
UD_Icvtsd2ss,
|
||||
UD_Icvtsi2sd,
|
||||
UD_Icvtsi2ss,
|
||||
UD_Icvtss2sd,
|
||||
UD_Icvtss2si,
|
||||
UD_Icvttpd2dq,
|
||||
UD_Icvttpd2pi,
|
||||
UD_Icvttps2dq,
|
||||
UD_Icvttps2pi,
|
||||
UD_Icvttsd2si,
|
||||
UD_Icvttss2si,
|
||||
UD_Icwd,
|
||||
UD_Icwde,
|
||||
UD_Idaa,
|
||||
UD_Idas,
|
||||
UD_Idec,
|
||||
UD_Idiv,
|
||||
UD_Idivpd,
|
||||
UD_Idivps,
|
||||
UD_Idivsd,
|
||||
UD_Idivss,
|
||||
UD_Idppd,
|
||||
UD_Idpps,
|
||||
UD_Iemms,
|
||||
UD_Ienter,
|
||||
UD_Iextractps,
|
||||
UD_If2xm1,
|
||||
UD_Ifabs,
|
||||
UD_Ifadd,
|
||||
UD_Ifaddp,
|
||||
UD_Ifbld,
|
||||
UD_Ifbstp,
|
||||
UD_Ifchs,
|
||||
UD_Ifclex,
|
||||
UD_Ifcmovb,
|
||||
UD_Ifcmovbe,
|
||||
UD_Ifcmove,
|
||||
UD_Ifcmovnb,
|
||||
UD_Ifcmovnbe,
|
||||
UD_Ifcmovne,
|
||||
UD_Ifcmovnu,
|
||||
UD_Ifcmovu,
|
||||
UD_Ifcom,
|
||||
UD_Ifcom2,
|
||||
UD_Ifcomi,
|
||||
UD_Ifcomip,
|
||||
UD_Ifcomp,
|
||||
UD_Ifcomp3,
|
||||
UD_Ifcomp5,
|
||||
UD_Ifcompp,
|
||||
UD_Ifcos,
|
||||
UD_Ifdecstp,
|
||||
UD_Ifdiv,
|
||||
UD_Ifdivp,
|
||||
UD_Ifdivr,
|
||||
UD_Ifdivrp,
|
||||
UD_Ifemms,
|
||||
UD_Iffree,
|
||||
UD_Iffreep,
|
||||
UD_Ifiadd,
|
||||
UD_Ificom,
|
||||
UD_Ificomp,
|
||||
UD_Ifidiv,
|
||||
UD_Ifidivr,
|
||||
UD_Ifild,
|
||||
UD_Ifimul,
|
||||
UD_Ifincstp,
|
||||
UD_Ifist,
|
||||
UD_Ifistp,
|
||||
UD_Ifisttp,
|
||||
UD_Ifisub,
|
||||
UD_Ifisubr,
|
||||
UD_Ifld,
|
||||
UD_Ifld1,
|
||||
UD_Ifldcw,
|
||||
UD_Ifldenv,
|
||||
UD_Ifldl2e,
|
||||
UD_Ifldl2t,
|
||||
UD_Ifldlg2,
|
||||
UD_Ifldln2,
|
||||
UD_Ifldpi,
|
||||
UD_Ifldz,
|
||||
UD_Ifmul,
|
||||
UD_Ifmulp,
|
||||
UD_Ifninit,
|
||||
UD_Ifnop,
|
||||
UD_Ifnsave,
|
||||
UD_Ifnstcw,
|
||||
UD_Ifnstenv,
|
||||
UD_Ifnstsw,
|
||||
UD_Ifpatan,
|
||||
UD_Ifprem,
|
||||
UD_Ifprem1,
|
||||
UD_Ifptan,
|
||||
UD_Ifrndint,
|
||||
UD_Ifrstor,
|
||||
UD_Ifscale,
|
||||
UD_Ifsin,
|
||||
UD_Ifsincos,
|
||||
UD_Ifsqrt,
|
||||
UD_Ifst,
|
||||
UD_Ifstp,
|
||||
UD_Ifstp1,
|
||||
UD_Ifstp8,
|
||||
UD_Ifstp9,
|
||||
UD_Ifsub,
|
||||
UD_Ifsubp,
|
||||
UD_Ifsubr,
|
||||
UD_Ifsubrp,
|
||||
UD_Iftst,
|
||||
UD_Ifucom,
|
||||
UD_Ifucomi,
|
||||
UD_Ifucomip,
|
||||
UD_Ifucomp,
|
||||
UD_Ifucompp,
|
||||
UD_Ifxam,
|
||||
UD_Ifxch,
|
||||
UD_Ifxch4,
|
||||
UD_Ifxch7,
|
||||
UD_Ifxrstor,
|
||||
UD_Ifxsave,
|
||||
UD_Ifxtract,
|
||||
UD_Ifyl2x,
|
||||
UD_Ifyl2xp1,
|
||||
UD_Igetsec,
|
||||
UD_Ihaddpd,
|
||||
UD_Ihaddps,
|
||||
UD_Ihlt,
|
||||
UD_Ihsubpd,
|
||||
UD_Ihsubps,
|
||||
UD_Iidiv,
|
||||
UD_Iimul,
|
||||
UD_Iin,
|
||||
UD_Iinc,
|
||||
UD_Iinsb,
|
||||
UD_Iinsd,
|
||||
UD_Iinsertps,
|
||||
UD_Iinsw,
|
||||
UD_Iint,
|
||||
UD_Iint1,
|
||||
UD_Iint3,
|
||||
UD_Iinto,
|
||||
UD_Iinvd,
|
||||
UD_Iinvept,
|
||||
UD_Iinvlpg,
|
||||
UD_Iinvlpga,
|
||||
UD_Iinvvpid,
|
||||
UD_Iiretd,
|
||||
UD_Iiretq,
|
||||
UD_Iiretw,
|
||||
UD_Ija,
|
||||
UD_Ijae,
|
||||
UD_Ijb,
|
||||
UD_Ijbe,
|
||||
UD_Ijcxz,
|
||||
UD_Ijecxz,
|
||||
UD_Ijg,
|
||||
UD_Ijge,
|
||||
UD_Ijl,
|
||||
UD_Ijle,
|
||||
UD_Ijmp,
|
||||
UD_Ijno,
|
||||
UD_Ijnp,
|
||||
UD_Ijns,
|
||||
UD_Ijnz,
|
||||
UD_Ijo,
|
||||
UD_Ijp,
|
||||
UD_Ijrcxz,
|
||||
UD_Ijs,
|
||||
UD_Ijz,
|
||||
UD_Ilahf,
|
||||
UD_Ilar,
|
||||
UD_Ilddqu,
|
||||
UD_Ildmxcsr,
|
||||
UD_Ilds,
|
||||
UD_Ilea,
|
||||
UD_Ileave,
|
||||
UD_Iles,
|
||||
UD_Ilfence,
|
||||
UD_Ilfs,
|
||||
UD_Ilgdt,
|
||||
UD_Ilgs,
|
||||
UD_Ilidt,
|
||||
UD_Illdt,
|
||||
UD_Ilmsw,
|
||||
UD_Ilock,
|
||||
UD_Ilodsb,
|
||||
UD_Ilodsd,
|
||||
UD_Ilodsq,
|
||||
UD_Ilodsw,
|
||||
UD_Iloop,
|
||||
UD_Iloope,
|
||||
UD_Iloopne,
|
||||
UD_Ilsl,
|
||||
UD_Ilss,
|
||||
UD_Iltr,
|
||||
UD_Imaskmovdqu,
|
||||
UD_Imaskmovq,
|
||||
UD_Imaxpd,
|
||||
UD_Imaxps,
|
||||
UD_Imaxsd,
|
||||
UD_Imaxss,
|
||||
UD_Imfence,
|
||||
UD_Iminpd,
|
||||
UD_Iminps,
|
||||
UD_Iminsd,
|
||||
UD_Iminss,
|
||||
UD_Imonitor,
|
||||
UD_Imontmul,
|
||||
UD_Imov,
|
||||
UD_Imovapd,
|
||||
UD_Imovaps,
|
||||
UD_Imovbe,
|
||||
UD_Imovd,
|
||||
UD_Imovddup,
|
||||
UD_Imovdq2q,
|
||||
UD_Imovdqa,
|
||||
UD_Imovdqu,
|
||||
UD_Imovhlps,
|
||||
UD_Imovhpd,
|
||||
UD_Imovhps,
|
||||
UD_Imovlhps,
|
||||
UD_Imovlpd,
|
||||
UD_Imovlps,
|
||||
UD_Imovmskpd,
|
||||
UD_Imovmskps,
|
||||
UD_Imovntdq,
|
||||
UD_Imovntdqa,
|
||||
UD_Imovnti,
|
||||
UD_Imovntpd,
|
||||
UD_Imovntps,
|
||||
UD_Imovntq,
|
||||
UD_Imovq,
|
||||
UD_Imovq2dq,
|
||||
UD_Imovsb,
|
||||
UD_Imovsd,
|
||||
UD_Imovshdup,
|
||||
UD_Imovsldup,
|
||||
UD_Imovsq,
|
||||
UD_Imovss,
|
||||
UD_Imovsw,
|
||||
UD_Imovsx,
|
||||
UD_Imovsxd,
|
||||
UD_Imovupd,
|
||||
UD_Imovups,
|
||||
UD_Imovzx,
|
||||
UD_Impsadbw,
|
||||
UD_Imul,
|
||||
UD_Imulpd,
|
||||
UD_Imulps,
|
||||
UD_Imulsd,
|
||||
UD_Imulss,
|
||||
UD_Imwait,
|
||||
UD_Ineg,
|
||||
UD_Inop,
|
||||
UD_Inot,
|
||||
UD_Ior,
|
||||
UD_Iorpd,
|
||||
UD_Iorps,
|
||||
UD_Iout,
|
||||
UD_Ioutsb,
|
||||
UD_Ioutsd,
|
||||
UD_Ioutsw,
|
||||
UD_Ipabsb,
|
||||
UD_Ipabsd,
|
||||
UD_Ipabsw,
|
||||
UD_Ipackssdw,
|
||||
UD_Ipacksswb,
|
||||
UD_Ipackusdw,
|
||||
UD_Ipackuswb,
|
||||
UD_Ipaddb,
|
||||
UD_Ipaddd,
|
||||
UD_Ipaddq,
|
||||
UD_Ipaddsb,
|
||||
UD_Ipaddsw,
|
||||
UD_Ipaddusb,
|
||||
UD_Ipaddusw,
|
||||
UD_Ipaddw,
|
||||
UD_Ipalignr,
|
||||
UD_Ipand,
|
||||
UD_Ipandn,
|
||||
UD_Ipavgb,
|
||||
UD_Ipavgusb,
|
||||
UD_Ipavgw,
|
||||
UD_Ipblendvb,
|
||||
UD_Ipblendw,
|
||||
UD_Ipclmulqdq,
|
||||
UD_Ipcmpeqb,
|
||||
UD_Ipcmpeqd,
|
||||
UD_Ipcmpeqq,
|
||||
UD_Ipcmpeqw,
|
||||
UD_Ipcmpestri,
|
||||
UD_Ipcmpestrm,
|
||||
UD_Ipcmpgtb,
|
||||
UD_Ipcmpgtd,
|
||||
UD_Ipcmpgtq,
|
||||
UD_Ipcmpgtw,
|
||||
UD_Ipcmpistri,
|
||||
UD_Ipcmpistrm,
|
||||
UD_Ipextrb,
|
||||
UD_Ipextrd,
|
||||
UD_Ipextrq,
|
||||
UD_Ipextrw,
|
||||
UD_Ipf2id,
|
||||
UD_Ipf2iw,
|
||||
UD_Ipfacc,
|
||||
UD_Ipfadd,
|
||||
UD_Ipfcmpeq,
|
||||
UD_Ipfcmpge,
|
||||
UD_Ipfcmpgt,
|
||||
UD_Ipfmax,
|
||||
UD_Ipfmin,
|
||||
UD_Ipfmul,
|
||||
UD_Ipfnacc,
|
||||
UD_Ipfpnacc,
|
||||
UD_Ipfrcp,
|
||||
UD_Ipfrcpit1,
|
||||
UD_Ipfrcpit2,
|
||||
UD_Ipfrsqit1,
|
||||
UD_Ipfrsqrt,
|
||||
UD_Ipfsub,
|
||||
UD_Ipfsubr,
|
||||
UD_Iphaddd,
|
||||
UD_Iphaddsw,
|
||||
UD_Iphaddw,
|
||||
UD_Iphminposuw,
|
||||
UD_Iphsubd,
|
||||
UD_Iphsubsw,
|
||||
UD_Iphsubw,
|
||||
UD_Ipi2fd,
|
||||
UD_Ipi2fw,
|
||||
UD_Ipinsrb,
|
||||
UD_Ipinsrd,
|
||||
UD_Ipinsrq,
|
||||
UD_Ipinsrw,
|
||||
UD_Ipmaddubsw,
|
||||
UD_Ipmaddwd,
|
||||
UD_Ipmaxsb,
|
||||
UD_Ipmaxsd,
|
||||
UD_Ipmaxsw,
|
||||
UD_Ipmaxub,
|
||||
UD_Ipmaxud,
|
||||
UD_Ipmaxuw,
|
||||
UD_Ipminsb,
|
||||
UD_Ipminsd,
|
||||
UD_Ipminsw,
|
||||
UD_Ipminub,
|
||||
UD_Ipminud,
|
||||
UD_Ipminuw,
|
||||
UD_Ipmovmskb,
|
||||
UD_Ipmovsxbd,
|
||||
UD_Ipmovsxbq,
|
||||
UD_Ipmovsxbw,
|
||||
UD_Ipmovsxdq,
|
||||
UD_Ipmovsxwd,
|
||||
UD_Ipmovsxwq,
|
||||
UD_Ipmovzxbd,
|
||||
UD_Ipmovzxbq,
|
||||
UD_Ipmovzxbw,
|
||||
UD_Ipmovzxdq,
|
||||
UD_Ipmovzxwd,
|
||||
UD_Ipmovzxwq,
|
||||
UD_Ipmuldq,
|
||||
UD_Ipmulhrsw,
|
||||
UD_Ipmulhrw,
|
||||
UD_Ipmulhuw,
|
||||
UD_Ipmulhw,
|
||||
UD_Ipmulld,
|
||||
UD_Ipmullw,
|
||||
UD_Ipmuludq,
|
||||
UD_Ipop,
|
||||
UD_Ipopa,
|
||||
UD_Ipopad,
|
||||
UD_Ipopcnt,
|
||||
UD_Ipopfd,
|
||||
UD_Ipopfq,
|
||||
UD_Ipopfw,
|
||||
UD_Ipor,
|
||||
UD_Iprefetch,
|
||||
UD_Iprefetchnta,
|
||||
UD_Iprefetcht0,
|
||||
UD_Iprefetcht1,
|
||||
UD_Iprefetcht2,
|
||||
UD_Ipsadbw,
|
||||
UD_Ipshufb,
|
||||
UD_Ipshufd,
|
||||
UD_Ipshufhw,
|
||||
UD_Ipshuflw,
|
||||
UD_Ipshufw,
|
||||
UD_Ipsignb,
|
||||
UD_Ipsignd,
|
||||
UD_Ipsignw,
|
||||
UD_Ipslld,
|
||||
UD_Ipslldq,
|
||||
UD_Ipsllq,
|
||||
UD_Ipsllw,
|
||||
UD_Ipsrad,
|
||||
UD_Ipsraw,
|
||||
UD_Ipsrld,
|
||||
UD_Ipsrldq,
|
||||
UD_Ipsrlq,
|
||||
UD_Ipsrlw,
|
||||
UD_Ipsubb,
|
||||
UD_Ipsubd,
|
||||
UD_Ipsubq,
|
||||
UD_Ipsubsb,
|
||||
UD_Ipsubsw,
|
||||
UD_Ipsubusb,
|
||||
UD_Ipsubusw,
|
||||
UD_Ipsubw,
|
||||
UD_Ipswapd,
|
||||
UD_Iptest,
|
||||
UD_Ipunpckhbw,
|
||||
UD_Ipunpckhdq,
|
||||
UD_Ipunpckhqdq,
|
||||
UD_Ipunpckhwd,
|
||||
UD_Ipunpcklbw,
|
||||
UD_Ipunpckldq,
|
||||
UD_Ipunpcklqdq,
|
||||
UD_Ipunpcklwd,
|
||||
UD_Ipush,
|
||||
UD_Ipusha,
|
||||
UD_Ipushad,
|
||||
UD_Ipushfd,
|
||||
UD_Ipushfq,
|
||||
UD_Ipushfw,
|
||||
UD_Ipxor,
|
||||
UD_Ircl,
|
||||
UD_Ircpps,
|
||||
UD_Ircpss,
|
||||
UD_Ircr,
|
||||
UD_Irdmsr,
|
||||
UD_Irdpmc,
|
||||
UD_Irdrand,
|
||||
UD_Irdtsc,
|
||||
UD_Irdtscp,
|
||||
UD_Irep,
|
||||
UD_Irepne,
|
||||
UD_Iret,
|
||||
UD_Iretf,
|
||||
UD_Irol,
|
||||
UD_Iror,
|
||||
UD_Iroundpd,
|
||||
UD_Iroundps,
|
||||
UD_Iroundsd,
|
||||
UD_Iroundss,
|
||||
UD_Irsm,
|
||||
UD_Irsqrtps,
|
||||
UD_Irsqrtss,
|
||||
UD_Isahf,
|
||||
UD_Isalc,
|
||||
UD_Isar,
|
||||
UD_Isbb,
|
||||
UD_Iscasb,
|
||||
UD_Iscasd,
|
||||
UD_Iscasq,
|
||||
UD_Iscasw,
|
||||
UD_Iseta,
|
||||
UD_Isetae,
|
||||
UD_Isetb,
|
||||
UD_Isetbe,
|
||||
UD_Isetg,
|
||||
UD_Isetge,
|
||||
UD_Isetl,
|
||||
UD_Isetle,
|
||||
UD_Isetno,
|
||||
UD_Isetnp,
|
||||
UD_Isetns,
|
||||
UD_Isetnz,
|
||||
UD_Iseto,
|
||||
UD_Isetp,
|
||||
UD_Isets,
|
||||
UD_Isetz,
|
||||
UD_Isfence,
|
||||
UD_Isgdt,
|
||||
UD_Ishl,
|
||||
UD_Ishld,
|
||||
UD_Ishr,
|
||||
UD_Ishrd,
|
||||
UD_Ishufpd,
|
||||
UD_Ishufps,
|
||||
UD_Isidt,
|
||||
UD_Iskinit,
|
||||
UD_Isldt,
|
||||
UD_Ismsw,
|
||||
UD_Isqrtpd,
|
||||
UD_Isqrtps,
|
||||
UD_Isqrtsd,
|
||||
UD_Isqrtss,
|
||||
UD_Istc,
|
||||
UD_Istd,
|
||||
UD_Istgi,
|
||||
UD_Isti,
|
||||
UD_Istmxcsr,
|
||||
UD_Istosb,
|
||||
UD_Istosd,
|
||||
UD_Istosq,
|
||||
UD_Istosw,
|
||||
UD_Istr,
|
||||
UD_Isub,
|
||||
UD_Isubpd,
|
||||
UD_Isubps,
|
||||
UD_Isubsd,
|
||||
UD_Isubss,
|
||||
UD_Iswapgs,
|
||||
UD_Isyscall,
|
||||
UD_Isysenter,
|
||||
UD_Isysexit,
|
||||
UD_Isysret,
|
||||
UD_Itest,
|
||||
UD_Iucomisd,
|
||||
UD_Iucomiss,
|
||||
UD_Iud2,
|
||||
UD_Iunpckhpd,
|
||||
UD_Iunpckhps,
|
||||
UD_Iunpcklpd,
|
||||
UD_Iunpcklps,
|
||||
UD_Ivaddpd,
|
||||
UD_Ivaddps,
|
||||
UD_Ivaddsd,
|
||||
UD_Ivaddss,
|
||||
UD_Ivaddsubpd,
|
||||
UD_Ivaddsubps,
|
||||
UD_Ivaesdec,
|
||||
UD_Ivaesdeclast,
|
||||
UD_Ivaesenc,
|
||||
UD_Ivaesenclast,
|
||||
UD_Ivaesimc,
|
||||
UD_Ivaeskeygenassist,
|
||||
UD_Ivandnpd,
|
||||
UD_Ivandnps,
|
||||
UD_Ivandpd,
|
||||
UD_Ivandps,
|
||||
UD_Ivblendpd,
|
||||
UD_Ivblendps,
|
||||
UD_Ivblendvpd,
|
||||
UD_Ivblendvps,
|
||||
UD_Ivbroadcastsd,
|
||||
UD_Ivbroadcastss,
|
||||
UD_Ivcmppd,
|
||||
UD_Ivcmpps,
|
||||
UD_Ivcmpsd,
|
||||
UD_Ivcmpss,
|
||||
UD_Ivcomisd,
|
||||
UD_Ivcomiss,
|
||||
UD_Ivcvtdq2pd,
|
||||
UD_Ivcvtdq2ps,
|
||||
UD_Ivcvtpd2dq,
|
||||
UD_Ivcvtpd2ps,
|
||||
UD_Ivcvtps2dq,
|
||||
UD_Ivcvtps2pd,
|
||||
UD_Ivcvtsd2si,
|
||||
UD_Ivcvtsd2ss,
|
||||
UD_Ivcvtsi2sd,
|
||||
UD_Ivcvtsi2ss,
|
||||
UD_Ivcvtss2sd,
|
||||
UD_Ivcvtss2si,
|
||||
UD_Ivcvttpd2dq,
|
||||
UD_Ivcvttps2dq,
|
||||
UD_Ivcvttsd2si,
|
||||
UD_Ivcvttss2si,
|
||||
UD_Ivdivpd,
|
||||
UD_Ivdivps,
|
||||
UD_Ivdivsd,
|
||||
UD_Ivdivss,
|
||||
UD_Ivdppd,
|
||||
UD_Ivdpps,
|
||||
UD_Iverr,
|
||||
UD_Iverw,
|
||||
UD_Ivextractf128,
|
||||
UD_Ivextractps,
|
||||
UD_Ivhaddpd,
|
||||
UD_Ivhaddps,
|
||||
UD_Ivhsubpd,
|
||||
UD_Ivhsubps,
|
||||
UD_Ivinsertf128,
|
||||
UD_Ivinsertps,
|
||||
UD_Ivlddqu,
|
||||
UD_Ivmaskmovdqu,
|
||||
UD_Ivmaskmovpd,
|
||||
UD_Ivmaskmovps,
|
||||
UD_Ivmaxpd,
|
||||
UD_Ivmaxps,
|
||||
UD_Ivmaxsd,
|
||||
UD_Ivmaxss,
|
||||
UD_Ivmcall,
|
||||
UD_Ivmclear,
|
||||
UD_Ivminpd,
|
||||
UD_Ivminps,
|
||||
UD_Ivminsd,
|
||||
UD_Ivminss,
|
||||
UD_Ivmlaunch,
|
||||
UD_Ivmload,
|
||||
UD_Ivmmcall,
|
||||
UD_Ivmovapd,
|
||||
UD_Ivmovaps,
|
||||
UD_Ivmovd,
|
||||
UD_Ivmovddup,
|
||||
UD_Ivmovdqa,
|
||||
UD_Ivmovdqu,
|
||||
UD_Ivmovhlps,
|
||||
UD_Ivmovhpd,
|
||||
UD_Ivmovhps,
|
||||
UD_Ivmovlhps,
|
||||
UD_Ivmovlpd,
|
||||
UD_Ivmovlps,
|
||||
UD_Ivmovmskpd,
|
||||
UD_Ivmovmskps,
|
||||
UD_Ivmovntdq,
|
||||
UD_Ivmovntdqa,
|
||||
UD_Ivmovntpd,
|
||||
UD_Ivmovntps,
|
||||
UD_Ivmovq,
|
||||
UD_Ivmovsd,
|
||||
UD_Ivmovshdup,
|
||||
UD_Ivmovsldup,
|
||||
UD_Ivmovss,
|
||||
UD_Ivmovupd,
|
||||
UD_Ivmovups,
|
||||
UD_Ivmpsadbw,
|
||||
UD_Ivmptrld,
|
||||
UD_Ivmptrst,
|
||||
UD_Ivmread,
|
||||
UD_Ivmresume,
|
||||
UD_Ivmrun,
|
||||
UD_Ivmsave,
|
||||
UD_Ivmulpd,
|
||||
UD_Ivmulps,
|
||||
UD_Ivmulsd,
|
||||
UD_Ivmulss,
|
||||
UD_Ivmwrite,
|
||||
UD_Ivmxoff,
|
||||
UD_Ivmxon,
|
||||
UD_Ivorpd,
|
||||
UD_Ivorps,
|
||||
UD_Ivpabsb,
|
||||
UD_Ivpabsd,
|
||||
UD_Ivpabsw,
|
||||
UD_Ivpackssdw,
|
||||
UD_Ivpacksswb,
|
||||
UD_Ivpackusdw,
|
||||
UD_Ivpackuswb,
|
||||
UD_Ivpaddb,
|
||||
UD_Ivpaddd,
|
||||
UD_Ivpaddq,
|
||||
UD_Ivpaddsb,
|
||||
UD_Ivpaddsw,
|
||||
UD_Ivpaddusb,
|
||||
UD_Ivpaddusw,
|
||||
UD_Ivpaddw,
|
||||
UD_Ivpalignr,
|
||||
UD_Ivpand,
|
||||
UD_Ivpandn,
|
||||
UD_Ivpavgb,
|
||||
UD_Ivpavgw,
|
||||
UD_Ivpblendvb,
|
||||
UD_Ivpblendw,
|
||||
UD_Ivpclmulqdq,
|
||||
UD_Ivpcmpeqb,
|
||||
UD_Ivpcmpeqd,
|
||||
UD_Ivpcmpeqq,
|
||||
UD_Ivpcmpeqw,
|
||||
UD_Ivpcmpestri,
|
||||
UD_Ivpcmpestrm,
|
||||
UD_Ivpcmpgtb,
|
||||
UD_Ivpcmpgtd,
|
||||
UD_Ivpcmpgtq,
|
||||
UD_Ivpcmpgtw,
|
||||
UD_Ivpcmpistri,
|
||||
UD_Ivpcmpistrm,
|
||||
UD_Ivperm2f128,
|
||||
UD_Ivpermilpd,
|
||||
UD_Ivpermilps,
|
||||
UD_Ivpextrb,
|
||||
UD_Ivpextrd,
|
||||
UD_Ivpextrq,
|
||||
UD_Ivpextrw,
|
||||
UD_Ivphaddd,
|
||||
UD_Ivphaddsw,
|
||||
UD_Ivphaddw,
|
||||
UD_Ivphminposuw,
|
||||
UD_Ivphsubd,
|
||||
UD_Ivphsubsw,
|
||||
UD_Ivphsubw,
|
||||
UD_Ivpinsrb,
|
||||
UD_Ivpinsrd,
|
||||
UD_Ivpinsrq,
|
||||
UD_Ivpinsrw,
|
||||
UD_Ivpmaddubsw,
|
||||
UD_Ivpmaddwd,
|
||||
UD_Ivpmaxsb,
|
||||
UD_Ivpmaxsd,
|
||||
UD_Ivpmaxsw,
|
||||
UD_Ivpmaxub,
|
||||
UD_Ivpmaxud,
|
||||
UD_Ivpmaxuw,
|
||||
UD_Ivpminsb,
|
||||
UD_Ivpminsd,
|
||||
UD_Ivpminsw,
|
||||
UD_Ivpminub,
|
||||
UD_Ivpminud,
|
||||
UD_Ivpminuw,
|
||||
UD_Ivpmovmskb,
|
||||
UD_Ivpmovsxbd,
|
||||
UD_Ivpmovsxbq,
|
||||
UD_Ivpmovsxbw,
|
||||
UD_Ivpmovsxwd,
|
||||
UD_Ivpmovsxwq,
|
||||
UD_Ivpmovzxbd,
|
||||
UD_Ivpmovzxbq,
|
||||
UD_Ivpmovzxbw,
|
||||
UD_Ivpmovzxdq,
|
||||
UD_Ivpmovzxwd,
|
||||
UD_Ivpmovzxwq,
|
||||
UD_Ivpmuldq,
|
||||
UD_Ivpmulhrsw,
|
||||
UD_Ivpmulhuw,
|
||||
UD_Ivpmulhw,
|
||||
UD_Ivpmulld,
|
||||
UD_Ivpmullw,
|
||||
UD_Ivpor,
|
||||
UD_Ivpsadbw,
|
||||
UD_Ivpshufb,
|
||||
UD_Ivpshufd,
|
||||
UD_Ivpshufhw,
|
||||
UD_Ivpshuflw,
|
||||
UD_Ivpsignb,
|
||||
UD_Ivpsignd,
|
||||
UD_Ivpsignw,
|
||||
UD_Ivpslld,
|
||||
UD_Ivpslldq,
|
||||
UD_Ivpsllq,
|
||||
UD_Ivpsllw,
|
||||
UD_Ivpsrad,
|
||||
UD_Ivpsraw,
|
||||
UD_Ivpsrld,
|
||||
UD_Ivpsrldq,
|
||||
UD_Ivpsrlq,
|
||||
UD_Ivpsrlw,
|
||||
UD_Ivpsubb,
|
||||
UD_Ivpsubd,
|
||||
UD_Ivpsubq,
|
||||
UD_Ivpsubsb,
|
||||
UD_Ivpsubsw,
|
||||
UD_Ivpsubusb,
|
||||
UD_Ivpsubusw,
|
||||
UD_Ivpsubw,
|
||||
UD_Ivptest,
|
||||
UD_Ivpunpckhbw,
|
||||
UD_Ivpunpckhdq,
|
||||
UD_Ivpunpckhqdq,
|
||||
UD_Ivpunpckhwd,
|
||||
UD_Ivpunpcklbw,
|
||||
UD_Ivpunpckldq,
|
||||
UD_Ivpunpcklqdq,
|
||||
UD_Ivpunpcklwd,
|
||||
UD_Ivpxor,
|
||||
UD_Ivrcpps,
|
||||
UD_Ivrcpss,
|
||||
UD_Ivroundpd,
|
||||
UD_Ivroundps,
|
||||
UD_Ivroundsd,
|
||||
UD_Ivroundss,
|
||||
UD_Ivrsqrtps,
|
||||
UD_Ivrsqrtss,
|
||||
UD_Ivshufpd,
|
||||
UD_Ivshufps,
|
||||
UD_Ivsqrtpd,
|
||||
UD_Ivsqrtps,
|
||||
UD_Ivsqrtsd,
|
||||
UD_Ivsqrtss,
|
||||
UD_Ivstmxcsr,
|
||||
UD_Ivsubpd,
|
||||
UD_Ivsubps,
|
||||
UD_Ivsubsd,
|
||||
UD_Ivsubss,
|
||||
UD_Ivtestpd,
|
||||
UD_Ivtestps,
|
||||
UD_Ivucomisd,
|
||||
UD_Ivucomiss,
|
||||
UD_Ivunpckhpd,
|
||||
UD_Ivunpckhps,
|
||||
UD_Ivunpcklpd,
|
||||
UD_Ivunpcklps,
|
||||
UD_Ivxorpd,
|
||||
UD_Ivxorps,
|
||||
UD_Ivzeroall,
|
||||
UD_Ivzeroupper,
|
||||
UD_Iwait,
|
||||
UD_Iwbinvd,
|
||||
UD_Iwrmsr,
|
||||
UD_Ixadd,
|
||||
UD_Ixchg,
|
||||
UD_Ixcryptcbc,
|
||||
UD_Ixcryptcfb,
|
||||
UD_Ixcryptctr,
|
||||
UD_Ixcryptecb,
|
||||
UD_Ixcryptofb,
|
||||
UD_Ixgetbv,
|
||||
UD_Ixlatb,
|
||||
UD_Ixor,
|
||||
UD_Ixorpd,
|
||||
UD_Ixorps,
|
||||
UD_Ixrstor,
|
||||
UD_Ixsave,
|
||||
UD_Ixsetbv,
|
||||
UD_Ixsha1,
|
||||
UD_Ixsha256,
|
||||
UD_Ixstore,
|
||||
UD_Iinvalid,
|
||||
UD_I3dnow,
|
||||
UD_Inone,
|
||||
UD_Idb,
|
||||
UD_Ipause,
|
||||
UD_MAX_MNEMONIC_CODE
|
||||
} UD_ATTR_PACKED;
|
||||
|
||||
extern const char * ud_mnemonics_str[];
|
||||
|
||||
#endif /* UD_ITAB_H */
|
||||
-228
@@ -1,228 +0,0 @@
|
||||
/* udis86 - libudis86/syn-att.c
|
||||
*
|
||||
* Copyright (c) 2002-2009 Vivek Thampi
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#include "types.h"
|
||||
#include "extern.h"
|
||||
#include "decode.h"
|
||||
#include "itab.h"
|
||||
#include "syn.h"
|
||||
#include "udint.h"
|
||||
|
||||
/* -----------------------------------------------------------------------------
|
||||
* opr_cast_att() - Prints an operand cast.
|
||||
* -----------------------------------------------------------------------------
|
||||
*/
|
||||
static void
|
||||
opr_cast_att(struct ud* u, struct ud_operand* op)
|
||||
{
|
||||
switch(op->size) {
|
||||
case 16 : case 32 :
|
||||
ud_asmprintf(u, "*"); break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
|
||||
/* -----------------------------------------------------------------------------
|
||||
* gen_operand_att() - Generates assembly output for each operand.
|
||||
* -----------------------------------------------------------------------------
|
||||
*/
|
||||
static void
|
||||
gen_operand_att(struct ud* u, struct ud_operand* op)
|
||||
{
|
||||
switch(op->type) {
|
||||
case UD_OP_CONST:
|
||||
ud_asmprintf(u, "$0x%x", op->lval.udword);
|
||||
break;
|
||||
|
||||
case UD_OP_REG:
|
||||
ud_asmprintf(u, "%%%s", ud_reg_tab[op->base - UD_R_AL]);
|
||||
break;
|
||||
|
||||
case UD_OP_MEM:
|
||||
if (u->br_far) {
|
||||
opr_cast_att(u, op);
|
||||
}
|
||||
if (u->pfx_seg) {
|
||||
ud_asmprintf(u, "%%%s:", ud_reg_tab[u->pfx_seg - UD_R_AL]);
|
||||
}
|
||||
if (op->offset != 0) {
|
||||
ud_syn_print_mem_disp(u, op, 0);
|
||||
}
|
||||
if (op->base) {
|
||||
ud_asmprintf(u, "(%%%s", ud_reg_tab[op->base - UD_R_AL]);
|
||||
}
|
||||
if (op->index) {
|
||||
if (op->base) {
|
||||
ud_asmprintf(u, ",");
|
||||
} else {
|
||||
ud_asmprintf(u, "(");
|
||||
}
|
||||
ud_asmprintf(u, "%%%s", ud_reg_tab[op->index - UD_R_AL]);
|
||||
}
|
||||
if (op->scale) {
|
||||
ud_asmprintf(u, ",%d", op->scale);
|
||||
}
|
||||
if (op->base || op->index) {
|
||||
ud_asmprintf(u, ")");
|
||||
}
|
||||
break;
|
||||
|
||||
case UD_OP_IMM:
|
||||
ud_asmprintf(u, "$");
|
||||
ud_syn_print_imm(u, op);
|
||||
break;
|
||||
|
||||
case UD_OP_JIMM:
|
||||
ud_syn_print_addr(u, ud_syn_rel_target(u, op));
|
||||
break;
|
||||
|
||||
case UD_OP_PTR:
|
||||
switch (op->size) {
|
||||
case 32:
|
||||
ud_asmprintf(u, "$0x%x, $0x%x", op->lval.ptr.seg,
|
||||
op->lval.ptr.off & 0xFFFF);
|
||||
break;
|
||||
case 48:
|
||||
ud_asmprintf(u, "$0x%x, $0x%x", op->lval.ptr.seg,
|
||||
op->lval.ptr.off);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
default: return;
|
||||
}
|
||||
}
|
||||
|
||||
/* =============================================================================
|
||||
* translates to AT&T syntax
|
||||
* =============================================================================
|
||||
*/
|
||||
extern void
|
||||
ud_translate_att(struct ud *u)
|
||||
{
|
||||
int size = 0;
|
||||
int star = 0;
|
||||
|
||||
/* check if P_OSO prefix is used */
|
||||
if (! P_OSO(u->itab_entry->prefix) && u->pfx_opr) {
|
||||
switch (u->dis_mode) {
|
||||
case 16:
|
||||
ud_asmprintf(u, "o32 ");
|
||||
break;
|
||||
case 32:
|
||||
case 64:
|
||||
ud_asmprintf(u, "o16 ");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* check if P_ASO prefix was used */
|
||||
if (! P_ASO(u->itab_entry->prefix) && u->pfx_adr) {
|
||||
switch (u->dis_mode) {
|
||||
case 16:
|
||||
ud_asmprintf(u, "a32 ");
|
||||
break;
|
||||
case 32:
|
||||
ud_asmprintf(u, "a16 ");
|
||||
break;
|
||||
case 64:
|
||||
ud_asmprintf(u, "a32 ");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (u->pfx_lock)
|
||||
ud_asmprintf(u, "lock ");
|
||||
if (u->pfx_rep) {
|
||||
ud_asmprintf(u, "rep ");
|
||||
} else if (u->pfx_rep) {
|
||||
ud_asmprintf(u, "repe ");
|
||||
} else if (u->pfx_repne) {
|
||||
ud_asmprintf(u, "repne ");
|
||||
}
|
||||
|
||||
/* special instructions */
|
||||
switch (u->mnemonic) {
|
||||
case UD_Iretf:
|
||||
ud_asmprintf(u, "lret ");
|
||||
break;
|
||||
case UD_Idb:
|
||||
ud_asmprintf(u, ".byte 0x%x", u->operand[0].lval.ubyte);
|
||||
return;
|
||||
case UD_Ijmp:
|
||||
case UD_Icall:
|
||||
if (u->br_far) ud_asmprintf(u, "l");
|
||||
if (u->operand[0].type == UD_OP_REG) {
|
||||
star = 1;
|
||||
}
|
||||
ud_asmprintf(u, "%s", ud_lookup_mnemonic(u->mnemonic));
|
||||
break;
|
||||
case UD_Ibound:
|
||||
case UD_Ienter:
|
||||
if (u->operand[0].type != UD_NONE)
|
||||
gen_operand_att(u, &u->operand[0]);
|
||||
if (u->operand[1].type != UD_NONE) {
|
||||
ud_asmprintf(u, ",");
|
||||
gen_operand_att(u, &u->operand[1]);
|
||||
}
|
||||
return;
|
||||
default:
|
||||
ud_asmprintf(u, "%s", ud_lookup_mnemonic(u->mnemonic));
|
||||
}
|
||||
|
||||
if (size == 8) {
|
||||
ud_asmprintf(u, "b");
|
||||
} else if (size == 16) {
|
||||
ud_asmprintf(u, "w");
|
||||
} else if (size == 64) {
|
||||
ud_asmprintf(u, "q");
|
||||
}
|
||||
|
||||
if (star) {
|
||||
ud_asmprintf(u, " *");
|
||||
} else {
|
||||
ud_asmprintf(u, " ");
|
||||
}
|
||||
|
||||
if (u->operand[3].type != UD_NONE) {
|
||||
gen_operand_att(u, &u->operand[3]);
|
||||
ud_asmprintf(u, ", ");
|
||||
}
|
||||
if (u->operand[2].type != UD_NONE) {
|
||||
gen_operand_att(u, &u->operand[2]);
|
||||
ud_asmprintf(u, ", ");
|
||||
}
|
||||
if (u->operand[1].type != UD_NONE) {
|
||||
gen_operand_att(u, &u->operand[1]);
|
||||
ud_asmprintf(u, ", ");
|
||||
}
|
||||
if (u->operand[0].type != UD_NONE) {
|
||||
gen_operand_att(u, &u->operand[0]);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
vim: set ts=2 sw=2 expandtab
|
||||
*/
|
||||
-225
@@ -1,225 +0,0 @@
|
||||
/* udis86 - libudis86/syn-intel.c
|
||||
*
|
||||
* Copyright (c) 2002-2013 Vivek Thampi
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#include "types.h"
|
||||
#include "extern.h"
|
||||
#include "decode.h"
|
||||
#include "itab.h"
|
||||
#include "syn.h"
|
||||
#include "udint.h"
|
||||
|
||||
/* -----------------------------------------------------------------------------
|
||||
* opr_cast_intel() - Prints an operand cast.
|
||||
* -----------------------------------------------------------------------------
|
||||
*/
|
||||
static void
|
||||
opr_cast_intel(struct ud* u, struct ud_operand* op)
|
||||
{
|
||||
if (u->br_far) {
|
||||
ud_asmprintf(u, "far ");
|
||||
}
|
||||
switch(op->size) {
|
||||
case 8: ud_asmprintf(u, "byte " ); break;
|
||||
case 16: ud_asmprintf(u, "word " ); break;
|
||||
case 32: ud_asmprintf(u, "dword "); break;
|
||||
case 64: ud_asmprintf(u, "qword "); break;
|
||||
case 80: ud_asmprintf(u, "tword "); break;
|
||||
case 128: ud_asmprintf(u, "oword "); break;
|
||||
case 256: ud_asmprintf(u, "yword "); break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
|
||||
/* -----------------------------------------------------------------------------
|
||||
* gen_operand_intel() - Generates assembly output for each operand.
|
||||
* -----------------------------------------------------------------------------
|
||||
*/
|
||||
static void gen_operand_intel(struct ud* u, struct ud_operand* op, int syn_cast)
|
||||
{
|
||||
switch(op->type) {
|
||||
case UD_OP_REG:
|
||||
ud_asmprintf(u, "%s", ud_reg_tab[op->base - UD_R_AL]);
|
||||
break;
|
||||
|
||||
case UD_OP_MEM:
|
||||
{
|
||||
opr_cast_intel(u, op);
|
||||
ud_asmprintf(u, "ptr ");
|
||||
}
|
||||
ud_asmprintf(u, "[");
|
||||
if (u->pfx_seg) {
|
||||
ud_asmprintf(u, "%s:", ud_reg_tab[u->pfx_seg - UD_R_AL]);
|
||||
}
|
||||
if (op->base) {
|
||||
ud_asmprintf(u, "%s", ud_reg_tab[op->base - UD_R_AL]);
|
||||
}
|
||||
if (op->index) {
|
||||
ud_asmprintf(u, "%s%s", op->base != UD_NONE? "+" : "",
|
||||
ud_reg_tab[op->index - UD_R_AL]);
|
||||
if (op->scale) {
|
||||
ud_asmprintf(u, "*%d", op->scale);
|
||||
}
|
||||
}
|
||||
if (op->offset != 0) {
|
||||
ud_syn_print_mem_disp(u, op, (op->base != UD_NONE ||
|
||||
op->index != UD_NONE) ? 1 : 0);
|
||||
}
|
||||
ud_asmprintf(u, "]");
|
||||
break;
|
||||
|
||||
case UD_OP_IMM:
|
||||
ud_syn_print_imm(u, op);
|
||||
break;
|
||||
|
||||
|
||||
case UD_OP_JIMM:
|
||||
ud_syn_print_addr(u, ud_syn_rel_target(u, op));
|
||||
break;
|
||||
|
||||
case UD_OP_PTR:
|
||||
switch (op->size) {
|
||||
case 32:
|
||||
ud_asmprintf(u, "word 0x%x:0x%x", op->lval.ptr.seg,
|
||||
op->lval.ptr.off & 0xFFFF);
|
||||
break;
|
||||
case 48:
|
||||
ud_asmprintf(u, "dword 0x%x:0x%x", op->lval.ptr.seg,
|
||||
op->lval.ptr.off);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case UD_OP_CONST:
|
||||
opr_cast_intel(u, op);
|
||||
ud_asmprintf(u, "%d", op->lval.udword);
|
||||
break;
|
||||
|
||||
default: return;
|
||||
}
|
||||
}
|
||||
|
||||
/* =============================================================================
|
||||
* translates to intel syntax
|
||||
* =============================================================================
|
||||
*/
|
||||
extern void
|
||||
ud_translate_intel(struct ud* u)
|
||||
{
|
||||
/* check if P_OSO prefix is used */
|
||||
if (!P_OSO(u->itab_entry->prefix) && u->pfx_opr) {
|
||||
switch (u->dis_mode) {
|
||||
case 16: ud_asmprintf(u, "o32 "); break;
|
||||
case 32:
|
||||
case 64: ud_asmprintf(u, "o16 "); break;
|
||||
}
|
||||
}
|
||||
|
||||
/* check if P_ASO prefix was used */
|
||||
if (!P_ASO(u->itab_entry->prefix) && u->pfx_adr) {
|
||||
switch (u->dis_mode) {
|
||||
case 16: ud_asmprintf(u, "a32 "); break;
|
||||
case 32: ud_asmprintf(u, "a16 "); break;
|
||||
case 64: ud_asmprintf(u, "a32 "); break;
|
||||
}
|
||||
}
|
||||
|
||||
if (u->pfx_seg &&
|
||||
u->operand[0].type != UD_OP_MEM &&
|
||||
u->operand[1].type != UD_OP_MEM ) {
|
||||
ud_asmprintf(u, "%s ", ud_reg_tab[u->pfx_seg - UD_R_AL]);
|
||||
}
|
||||
|
||||
if (u->pfx_lock) {
|
||||
ud_asmprintf(u, "lock ");
|
||||
}
|
||||
if (u->pfx_rep) {
|
||||
ud_asmprintf(u, "rep ");
|
||||
} else if (u->pfx_repe) {
|
||||
ud_asmprintf(u, "repe ");
|
||||
} else if (u->pfx_repne) {
|
||||
ud_asmprintf(u, "repne ");
|
||||
}
|
||||
|
||||
/* print the instruction mnemonic */
|
||||
ud_asmprintf(u, "%s", ud_lookup_mnemonic(u->mnemonic));
|
||||
|
||||
if (u->operand[0].type != UD_NONE) {
|
||||
int cast = 0;
|
||||
ud_asmprintf(u, " ");
|
||||
if (u->operand[0].type == UD_OP_MEM) {
|
||||
if (u->operand[1].type == UD_OP_IMM ||
|
||||
u->operand[1].type == UD_OP_CONST ||
|
||||
u->operand[1].type == UD_NONE ||
|
||||
(u->operand[0].size != u->operand[1].size)) {
|
||||
cast = 1;
|
||||
} else if (u->operand[1].type == UD_OP_REG &&
|
||||
u->operand[1].base == UD_R_CL) {
|
||||
switch (u->mnemonic) {
|
||||
case UD_Ircl:
|
||||
case UD_Irol:
|
||||
case UD_Iror:
|
||||
case UD_Ircr:
|
||||
case UD_Ishl:
|
||||
case UD_Ishr:
|
||||
case UD_Isar:
|
||||
cast = 1;
|
||||
break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
}
|
||||
gen_operand_intel(u, &u->operand[0], cast);
|
||||
}
|
||||
|
||||
if (u->operand[1].type != UD_NONE) {
|
||||
int cast = 0;
|
||||
ud_asmprintf(u, ", ");
|
||||
if (u->operand[1].type == UD_OP_MEM &&
|
||||
u->operand[0].size != u->operand[1].size &&
|
||||
!ud_opr_is_sreg(&u->operand[0])) {
|
||||
cast = 1;
|
||||
}
|
||||
gen_operand_intel(u, &u->operand[1], cast);
|
||||
}
|
||||
|
||||
if (u->operand[2].type != UD_NONE) {
|
||||
int cast = 0;
|
||||
ud_asmprintf(u, ", ");
|
||||
if (u->operand[2].type == UD_OP_MEM &&
|
||||
u->operand[2].size != u->operand[1].size) {
|
||||
cast = 1;
|
||||
}
|
||||
gen_operand_intel(u, &u->operand[2], cast);
|
||||
}
|
||||
|
||||
if (u->operand[3].type != UD_NONE) {
|
||||
ud_asmprintf(u, ", ");
|
||||
gen_operand_intel(u, &u->operand[3], 0);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
vim: set ts=2 sw=2 expandtab
|
||||
*/
|
||||
-212
@@ -1,212 +0,0 @@
|
||||
/* udis86 - libudis86/syn.c
|
||||
*
|
||||
* Copyright (c) 2002-2013 Vivek Thampi
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#include "types.h"
|
||||
#include "decode.h"
|
||||
#include "syn.h"
|
||||
#include "udint.h"
|
||||
|
||||
/*
|
||||
* Register Table - Order Matters (types.h)!
|
||||
*
|
||||
*/
|
||||
const char* ud_reg_tab[] =
|
||||
{
|
||||
"al", "cl", "dl", "bl",
|
||||
"ah", "ch", "dh", "bh",
|
||||
"spl", "bpl", "sil", "dil",
|
||||
"r8b", "r9b", "r10b", "r11b",
|
||||
"r12b", "r13b", "r14b", "r15b",
|
||||
|
||||
"ax", "cx", "dx", "bx",
|
||||
"sp", "bp", "si", "di",
|
||||
"r8w", "r9w", "r10w", "r11w",
|
||||
"r12w", "r13w", "r14w", "r15w",
|
||||
|
||||
"eax", "ecx", "edx", "ebx",
|
||||
"esp", "ebp", "esi", "edi",
|
||||
"r8d", "r9d", "r10d", "r11d",
|
||||
"r12d", "r13d", "r14d", "r15d",
|
||||
|
||||
"rax", "rcx", "rdx", "rbx",
|
||||
"rsp", "rbp", "rsi", "rdi",
|
||||
"r8", "r9", "r10", "r11",
|
||||
"r12", "r13", "r14", "r15",
|
||||
|
||||
"es", "cs", "ss", "ds",
|
||||
"fs", "gs",
|
||||
|
||||
"cr0", "cr1", "cr2", "cr3",
|
||||
"cr4", "cr5", "cr6", "cr7",
|
||||
"cr8", "cr9", "cr10", "cr11",
|
||||
"cr12", "cr13", "cr14", "cr15",
|
||||
|
||||
"dr0", "dr1", "dr2", "dr3",
|
||||
"dr4", "dr5", "dr6", "dr7",
|
||||
"dr8", "dr9", "dr10", "dr11",
|
||||
"dr12", "dr13", "dr14", "dr15",
|
||||
|
||||
"mm0", "mm1", "mm2", "mm3",
|
||||
"mm4", "mm5", "mm6", "mm7",
|
||||
|
||||
"st0", "st1", "st2", "st3",
|
||||
"st4", "st5", "st6", "st7",
|
||||
|
||||
"xmm0", "xmm1", "xmm2", "xmm3",
|
||||
"xmm4", "xmm5", "xmm6", "xmm7",
|
||||
"xmm8", "xmm9", "xmm10", "xmm11",
|
||||
"xmm12", "xmm13", "xmm14", "xmm15",
|
||||
|
||||
"ymm0", "ymm1", "ymm2", "ymm3",
|
||||
"ymm4", "ymm5", "ymm6", "ymm7",
|
||||
"ymm8", "ymm9", "ymm10", "ymm11",
|
||||
"ymm12", "ymm13", "ymm14", "ymm15",
|
||||
|
||||
"rip"
|
||||
};
|
||||
|
||||
|
||||
uint64_t
|
||||
ud_syn_rel_target(struct ud *u, struct ud_operand *opr)
|
||||
{
|
||||
const uint64_t trunc_mask = 0xffffffffffffffffull >> (64 - u->opr_mode);
|
||||
switch (opr->size) {
|
||||
case 8 : return (u->pc + opr->lval.sbyte) & trunc_mask;
|
||||
case 16: return (u->pc + opr->lval.sword) & trunc_mask;
|
||||
case 32: return (u->pc + opr->lval.sdword) & trunc_mask;
|
||||
default: UD_ASSERT(!"invalid relative offset size.");
|
||||
return 0ull;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* asmprintf
|
||||
* Printf style function for printing translated assembly
|
||||
* output. Returns the number of characters written and
|
||||
* moves the buffer pointer forward. On an overflow,
|
||||
* returns a negative number and truncates the output.
|
||||
*/
|
||||
int
|
||||
ud_asmprintf(struct ud *u, const char *fmt, ...)
|
||||
{
|
||||
int ret;
|
||||
int avail;
|
||||
va_list ap;
|
||||
va_start(ap, fmt);
|
||||
avail = u->asm_buf_size - u->asm_buf_fill - 1 /* nullchar */;
|
||||
ret = vsnprintf((char*) u->asm_buf + u->asm_buf_fill, avail, fmt, ap);
|
||||
if (ret < 0 || ret > avail) {
|
||||
u->asm_buf_fill = u->asm_buf_size - 1;
|
||||
} else {
|
||||
u->asm_buf_fill += ret;
|
||||
}
|
||||
va_end(ap);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ud_syn_print_addr(struct ud *u, uint64_t addr)
|
||||
{
|
||||
const char *name = 0;
|
||||
if (u->sym_resolver) {
|
||||
int64_t offset = 0;
|
||||
name = u->sym_resolver(u, addr, &offset);
|
||||
if (name) {
|
||||
if (offset) {
|
||||
ud_asmprintf(u, "%s%+" FMT64 "d", name, offset);
|
||||
} else {
|
||||
ud_asmprintf(u, "%s", name);
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
ud_asmprintf(u, "0x%" FMT64 "x", addr);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ud_syn_print_imm(struct ud* u, const struct ud_operand *op)
|
||||
{
|
||||
uint64_t v;
|
||||
if (op->_oprcode == OP_sI && op->size != u->opr_mode) {
|
||||
if (op->size == 8) {
|
||||
v = (int64_t)op->lval.sbyte;
|
||||
} else {
|
||||
UD_ASSERT(op->size == 32);
|
||||
v = (int64_t)op->lval.sdword;
|
||||
}
|
||||
if (u->opr_mode < 64) {
|
||||
v = v & ((1ull << u->opr_mode) - 1ull);
|
||||
}
|
||||
} else {
|
||||
switch (op->size) {
|
||||
case 8 : v = op->lval.ubyte; break;
|
||||
case 16: v = op->lval.uword; break;
|
||||
case 32: v = op->lval.udword; break;
|
||||
case 64: v = op->lval.uqword; break;
|
||||
default: UD_ASSERT(!"invalid offset"); v = 0; /* keep cc happy */
|
||||
}
|
||||
}
|
||||
ud_asmprintf(u, "0x%" FMT64 "x", v);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ud_syn_print_mem_disp(struct ud* u, const struct ud_operand *op, int sign)
|
||||
{
|
||||
UD_ASSERT(op->offset != 0);
|
||||
if (op->base == UD_NONE && op->index == UD_NONE) {
|
||||
uint64_t v;
|
||||
UD_ASSERT(op->scale == UD_NONE && op->offset != 8);
|
||||
/* unsigned mem-offset */
|
||||
switch (op->offset) {
|
||||
case 16: v = op->lval.uword; break;
|
||||
case 32: v = op->lval.udword; break;
|
||||
case 64: v = op->lval.uqword; break;
|
||||
default: UD_ASSERT(!"invalid offset"); v = 0; /* keep cc happy */
|
||||
}
|
||||
ud_asmprintf(u, "0x%" FMT64 "x", v);
|
||||
} else {
|
||||
int64_t v;
|
||||
UD_ASSERT(op->offset != 64);
|
||||
switch (op->offset) {
|
||||
case 8 : v = op->lval.sbyte; break;
|
||||
case 16: v = op->lval.sword; break;
|
||||
case 32: v = op->lval.sdword; break;
|
||||
default: UD_ASSERT(!"invalid offset"); v = 0; /* keep cc happy */
|
||||
}
|
||||
if (v < 0) {
|
||||
ud_asmprintf(u, "-0x%" FMT64 "x", -v);
|
||||
} else if (v > 0) {
|
||||
ud_asmprintf(u, "%s0x%" FMT64 "x", sign? "+" : "", v);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
vim: set ts=2 sw=2 expandtab
|
||||
*/
|
||||
-53
@@ -1,53 +0,0 @@
|
||||
/* udis86 - libudis86/syn.h
|
||||
*
|
||||
* Copyright (c) 2002-2009
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#ifndef UD_SYN_H
|
||||
#define UD_SYN_H
|
||||
|
||||
#include "types.h"
|
||||
#ifndef __UD_STANDALONE__
|
||||
# include <stdarg.h>
|
||||
#endif /* __UD_STANDALONE__ */
|
||||
|
||||
extern const char* ud_reg_tab[];
|
||||
|
||||
uint64_t ud_syn_rel_target(struct ud*, struct ud_operand*);
|
||||
|
||||
#ifdef __GNUC__
|
||||
int ud_asmprintf(struct ud *u, const char *fmt, ...)
|
||||
__attribute__ ((format (gnu_printf, 2, 3)));
|
||||
#else
|
||||
int ud_asmprintf(struct ud *u, const char *fmt, ...);
|
||||
#endif
|
||||
|
||||
void ud_syn_print_addr(struct ud *u, uint64_t addr);
|
||||
void ud_syn_print_imm(struct ud* u, const struct ud_operand *op);
|
||||
void ud_syn_print_mem_disp(struct ud* u, const struct ud_operand *, int sign);
|
||||
|
||||
#endif /* UD_SYN_H */
|
||||
|
||||
/*
|
||||
vim: set ts=2 sw=2 expandtab
|
||||
*/
|
||||
-259
@@ -1,259 +0,0 @@
|
||||
/* udis86 - libudis86/types.h
|
||||
*
|
||||
* Copyright (c) 2002-2013 Vivek Thampi
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#ifndef UD_TYPES_H
|
||||
#define UD_TYPES_H
|
||||
|
||||
#ifdef __KERNEL__
|
||||
/*
|
||||
* -D__KERNEL__ is automatically passed on the command line when
|
||||
* building something as part of the Linux kernel. Assume standalone
|
||||
* mode.
|
||||
*/
|
||||
# include <linux/kernel.h>
|
||||
# include <linux/string.h>
|
||||
# ifndef __UD_STANDALONE__
|
||||
# define __UD_STANDALONE__ 1
|
||||
# endif
|
||||
#endif /* __KERNEL__ */
|
||||
|
||||
#if !defined(__UD_STANDALONE__)
|
||||
# include <stdint.h>
|
||||
# include <stdio.h>
|
||||
#endif
|
||||
|
||||
/* gcc specific extensions */
|
||||
#ifdef __GNUC__
|
||||
# define UD_ATTR_PACKED __attribute__((packed))
|
||||
#else
|
||||
# define UD_ATTR_PACKED
|
||||
#endif /* UD_ATTR_PACKED */
|
||||
|
||||
|
||||
/* -----------------------------------------------------------------------------
|
||||
* All possible "types" of objects in udis86. Order is Important!
|
||||
* -----------------------------------------------------------------------------
|
||||
*/
|
||||
enum ud_type
|
||||
{
|
||||
UD_NONE,
|
||||
|
||||
/* 8 bit GPRs */
|
||||
UD_R_AL, UD_R_CL, UD_R_DL, UD_R_BL,
|
||||
UD_R_AH, UD_R_CH, UD_R_DH, UD_R_BH,
|
||||
UD_R_SPL, UD_R_BPL, UD_R_SIL, UD_R_DIL,
|
||||
UD_R_R8B, UD_R_R9B, UD_R_R10B, UD_R_R11B,
|
||||
UD_R_R12B, UD_R_R13B, UD_R_R14B, UD_R_R15B,
|
||||
|
||||
/* 16 bit GPRs */
|
||||
UD_R_AX, UD_R_CX, UD_R_DX, UD_R_BX,
|
||||
UD_R_SP, UD_R_BP, UD_R_SI, UD_R_DI,
|
||||
UD_R_R8W, UD_R_R9W, UD_R_R10W, UD_R_R11W,
|
||||
UD_R_R12W, UD_R_R13W, UD_R_R14W, UD_R_R15W,
|
||||
|
||||
/* 32 bit GPRs */
|
||||
UD_R_EAX, UD_R_ECX, UD_R_EDX, UD_R_EBX,
|
||||
UD_R_ESP, UD_R_EBP, UD_R_ESI, UD_R_EDI,
|
||||
UD_R_R8D, UD_R_R9D, UD_R_R10D, UD_R_R11D,
|
||||
UD_R_R12D, UD_R_R13D, UD_R_R14D, UD_R_R15D,
|
||||
|
||||
/* 64 bit GPRs */
|
||||
UD_R_RAX, UD_R_RCX, UD_R_RDX, UD_R_RBX,
|
||||
UD_R_RSP, UD_R_RBP, UD_R_RSI, UD_R_RDI,
|
||||
UD_R_R8, UD_R_R9, UD_R_R10, UD_R_R11,
|
||||
UD_R_R12, UD_R_R13, UD_R_R14, UD_R_R15,
|
||||
|
||||
/* segment registers */
|
||||
UD_R_ES, UD_R_CS, UD_R_SS, UD_R_DS,
|
||||
UD_R_FS, UD_R_GS,
|
||||
|
||||
/* control registers*/
|
||||
UD_R_CR0, UD_R_CR1, UD_R_CR2, UD_R_CR3,
|
||||
UD_R_CR4, UD_R_CR5, UD_R_CR6, UD_R_CR7,
|
||||
UD_R_CR8, UD_R_CR9, UD_R_CR10, UD_R_CR11,
|
||||
UD_R_CR12, UD_R_CR13, UD_R_CR14, UD_R_CR15,
|
||||
|
||||
/* debug registers */
|
||||
UD_R_DR0, UD_R_DR1, UD_R_DR2, UD_R_DR3,
|
||||
UD_R_DR4, UD_R_DR5, UD_R_DR6, UD_R_DR7,
|
||||
UD_R_DR8, UD_R_DR9, UD_R_DR10, UD_R_DR11,
|
||||
UD_R_DR12, UD_R_DR13, UD_R_DR14, UD_R_DR15,
|
||||
|
||||
/* mmx registers */
|
||||
UD_R_MM0, UD_R_MM1, UD_R_MM2, UD_R_MM3,
|
||||
UD_R_MM4, UD_R_MM5, UD_R_MM6, UD_R_MM7,
|
||||
|
||||
/* x87 registers */
|
||||
UD_R_ST0, UD_R_ST1, UD_R_ST2, UD_R_ST3,
|
||||
UD_R_ST4, UD_R_ST5, UD_R_ST6, UD_R_ST7,
|
||||
|
||||
/* extended multimedia registers */
|
||||
UD_R_XMM0, UD_R_XMM1, UD_R_XMM2, UD_R_XMM3,
|
||||
UD_R_XMM4, UD_R_XMM5, UD_R_XMM6, UD_R_XMM7,
|
||||
UD_R_XMM8, UD_R_XMM9, UD_R_XMM10, UD_R_XMM11,
|
||||
UD_R_XMM12, UD_R_XMM13, UD_R_XMM14, UD_R_XMM15,
|
||||
|
||||
/* 256B multimedia registers */
|
||||
UD_R_YMM0, UD_R_YMM1, UD_R_YMM2, UD_R_YMM3,
|
||||
UD_R_YMM4, UD_R_YMM5, UD_R_YMM6, UD_R_YMM7,
|
||||
UD_R_YMM8, UD_R_YMM9, UD_R_YMM10, UD_R_YMM11,
|
||||
UD_R_YMM12, UD_R_YMM13, UD_R_YMM14, UD_R_YMM15,
|
||||
|
||||
UD_R_RIP,
|
||||
|
||||
/* Operand Types */
|
||||
UD_OP_REG, UD_OP_MEM, UD_OP_PTR, UD_OP_IMM,
|
||||
UD_OP_JIMM, UD_OP_CONST
|
||||
};
|
||||
|
||||
#include "itab.h"
|
||||
|
||||
union ud_lval {
|
||||
int8_t sbyte;
|
||||
uint8_t ubyte;
|
||||
int16_t sword;
|
||||
uint16_t uword;
|
||||
int32_t sdword;
|
||||
uint32_t udword;
|
||||
int64_t sqword;
|
||||
uint64_t uqword;
|
||||
struct {
|
||||
uint16_t seg;
|
||||
uint32_t off;
|
||||
} ptr;
|
||||
};
|
||||
|
||||
/* -----------------------------------------------------------------------------
|
||||
* struct ud_operand - Disassembled instruction Operand.
|
||||
* -----------------------------------------------------------------------------
|
||||
*/
|
||||
struct ud_operand {
|
||||
enum ud_type type;
|
||||
uint16_t size;
|
||||
enum ud_type base;
|
||||
enum ud_type index;
|
||||
uint8_t scale;
|
||||
uint8_t offset;
|
||||
union ud_lval lval;
|
||||
/*
|
||||
* internal use only
|
||||
*/
|
||||
uint64_t _legacy; /* this will be removed in 1.8 */
|
||||
uint8_t _oprcode;
|
||||
};
|
||||
|
||||
/* -----------------------------------------------------------------------------
|
||||
* struct ud - The udis86 object.
|
||||
* -----------------------------------------------------------------------------
|
||||
*/
|
||||
struct ud
|
||||
{
|
||||
/*
|
||||
* input buffering
|
||||
*/
|
||||
int (*inp_hook) (struct ud*);
|
||||
#ifndef __UD_STANDALONE__
|
||||
FILE* inp_file;
|
||||
#endif
|
||||
const uint8_t* inp_buf;
|
||||
size_t inp_buf_size;
|
||||
size_t inp_buf_index;
|
||||
uint8_t inp_curr;
|
||||
size_t inp_ctr;
|
||||
uint8_t inp_sess[64];
|
||||
int inp_end;
|
||||
int inp_peek;
|
||||
|
||||
void (*translator)(struct ud*);
|
||||
uint64_t insn_offset;
|
||||
char insn_hexcode[64];
|
||||
|
||||
/*
|
||||
* Assembly output buffer
|
||||
*/
|
||||
char *asm_buf;
|
||||
size_t asm_buf_size;
|
||||
size_t asm_buf_fill;
|
||||
char asm_buf_int[128];
|
||||
|
||||
/*
|
||||
* Symbol resolver for use in the translation phase.
|
||||
*/
|
||||
const char* (*sym_resolver)(struct ud*, uint64_t addr, int64_t *offset);
|
||||
|
||||
uint8_t dis_mode;
|
||||
uint64_t pc;
|
||||
uint8_t vendor;
|
||||
enum ud_mnemonic_code mnemonic;
|
||||
struct ud_operand operand[4];
|
||||
uint8_t error;
|
||||
uint8_t _rex;
|
||||
uint8_t pfx_rex;
|
||||
uint8_t pfx_seg;
|
||||
uint8_t pfx_opr;
|
||||
uint8_t pfx_adr;
|
||||
uint8_t pfx_lock;
|
||||
uint8_t pfx_str;
|
||||
uint8_t pfx_rep;
|
||||
uint8_t pfx_repe;
|
||||
uint8_t pfx_repne;
|
||||
uint8_t opr_mode;
|
||||
uint8_t adr_mode;
|
||||
uint8_t br_far;
|
||||
uint8_t br_near;
|
||||
uint8_t have_modrm;
|
||||
uint8_t modrm;
|
||||
uint8_t vex_op;
|
||||
uint8_t vex_b1;
|
||||
uint8_t vex_b2;
|
||||
uint8_t primary_opcode;
|
||||
void * user_opaque_data;
|
||||
struct ud_itab_entry * itab_entry;
|
||||
struct ud_lookup_table_list_entry *le;
|
||||
};
|
||||
|
||||
/* -----------------------------------------------------------------------------
|
||||
* Type-definitions
|
||||
* -----------------------------------------------------------------------------
|
||||
*/
|
||||
typedef enum ud_type ud_type_t;
|
||||
typedef enum ud_mnemonic_code ud_mnemonic_code_t;
|
||||
|
||||
typedef struct ud ud_t;
|
||||
typedef struct ud_operand ud_operand_t;
|
||||
|
||||
#define UD_SYN_INTEL ud_translate_intel
|
||||
#define UD_SYN_ATT ud_translate_att
|
||||
#define UD_EOI (-1)
|
||||
#define UD_INP_CACHE_SZ 32
|
||||
#define UD_VENDOR_AMD 0
|
||||
#define UD_VENDOR_INTEL 1
|
||||
#define UD_VENDOR_ANY 2
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
vim: set ts=2 sw=2 expandtab
|
||||
*/
|
||||
-97
@@ -1,97 +0,0 @@
|
||||
/* udis86 - libudis86/udint.h -- definitions for internal use only
|
||||
*
|
||||
* Copyright (c) 2002-2009 Vivek Thampi
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#ifndef _UDINT_H_
|
||||
#define _UDINT_H_
|
||||
|
||||
#if defined(HAVE_CONFIG_H) // || true // < Simplification for our (RAD Debugger) build process
|
||||
# include <config.h>
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
|
||||
#if defined(UD_DEBUG) && HAVE_ASSERT_H
|
||||
# include <assert.h>
|
||||
# define UD_ASSERT(_x) assert(_x)
|
||||
#else
|
||||
# define UD_ASSERT(_x)
|
||||
#endif /* !HAVE_ASSERT_H */
|
||||
|
||||
#if defined(UD_DEBUG)
|
||||
#define UDERR(u, msg) \
|
||||
do { \
|
||||
(u)->error = 1; \
|
||||
fprintf(stderr, "decode-error: %s:%d: %s", \
|
||||
__FILE__, __LINE__, (msg)); \
|
||||
} while (0)
|
||||
#else
|
||||
#define UDERR(u, m) \
|
||||
do { \
|
||||
(u)->error = 1; \
|
||||
} while (0)
|
||||
#endif /* !LOGERR */
|
||||
|
||||
#define UD_RETURN_ON_ERROR(u) \
|
||||
do { \
|
||||
if ((u)->error != 0) { \
|
||||
return (u)->error; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define UD_RETURN_WITH_ERROR(u, m) \
|
||||
do { \
|
||||
UDERR(u, m); \
|
||||
return (u)->error; \
|
||||
} while (0)
|
||||
|
||||
#ifndef __UD_STANDALONE__
|
||||
# define UD_NON_STANDALONE(x) x
|
||||
#else
|
||||
# define UD_NON_STANDALONE(x)
|
||||
#endif
|
||||
|
||||
/* printf formatting int64 specifier */
|
||||
#ifdef FMT64
|
||||
# undef FMT64
|
||||
#endif
|
||||
#if defined(_MSC_VER) || defined(__BORLANDC__)
|
||||
# define FMT64 "I64"
|
||||
#else
|
||||
# if defined(__APPLE__) || defined(_WIN32) // RJM added this
|
||||
# define FMT64 "ll"
|
||||
# elif defined(__amd64__) || defined(__x86_64__)
|
||||
# define FMT64 "l"
|
||||
# else
|
||||
# define FMT64 "ll"
|
||||
# endif /* !x64 */
|
||||
#endif
|
||||
|
||||
/* define an inline macro */
|
||||
#if defined(_MSC_VER) || defined(__BORLANDC__)
|
||||
# define UD_INLINE __inline /* MS Visual Studio requires __inline
|
||||
instead of inline for C code */
|
||||
#else
|
||||
# define UD_INLINE inline
|
||||
#endif
|
||||
|
||||
#endif /* _UDINT_H_ */
|
||||
-458
@@ -1,458 +0,0 @@
|
||||
/* udis86 - libudis86/udis86.c
|
||||
*
|
||||
* Copyright (c) 2002-2013 Vivek Thampi
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "udint.h"
|
||||
#include "extern.h"
|
||||
#include "decode.h"
|
||||
|
||||
#if !defined(__UD_STANDALONE__)
|
||||
# if HAVE_STRING_H
|
||||
# include <string.h>
|
||||
# endif
|
||||
#endif /* !__UD_STANDALONE__ */
|
||||
|
||||
static void ud_inp_init(struct ud *u);
|
||||
|
||||
/* =============================================================================
|
||||
* ud_init
|
||||
* Initializes ud_t object.
|
||||
* =============================================================================
|
||||
*/
|
||||
extern void
|
||||
ud_init(struct ud* u)
|
||||
{
|
||||
memset((void*)u, 0, sizeof(struct ud));
|
||||
ud_set_mode(u, 16);
|
||||
u->mnemonic = UD_Iinvalid;
|
||||
ud_set_pc(u, 0);
|
||||
#ifndef __UD_STANDALONE__
|
||||
ud_set_input_file(u, stdin);
|
||||
#endif /* __UD_STANDALONE__ */
|
||||
|
||||
ud_set_asm_buffer(u, u->asm_buf_int, sizeof(u->asm_buf_int));
|
||||
}
|
||||
|
||||
|
||||
/* =============================================================================
|
||||
* ud_disassemble
|
||||
* Disassembles one instruction and returns the number of
|
||||
* bytes disassembled. A zero means end of disassembly.
|
||||
* =============================================================================
|
||||
*/
|
||||
extern unsigned int
|
||||
ud_disassemble(struct ud* u)
|
||||
{
|
||||
int len;
|
||||
if (u->inp_end) {
|
||||
return 0;
|
||||
}
|
||||
if ((len = ud_decode(u)) > 0) {
|
||||
if (u->translator != 0) {
|
||||
u->asm_buf[0] = '\0';
|
||||
u->translator(u);
|
||||
}
|
||||
}
|
||||
return len;
|
||||
}
|
||||
|
||||
|
||||
/* =============================================================================
|
||||
* ud_set_mode() - Set Disassemly Mode.
|
||||
* =============================================================================
|
||||
*/
|
||||
extern void
|
||||
ud_set_mode(struct ud* u, uint8_t m)
|
||||
{
|
||||
switch(m) {
|
||||
case 16:
|
||||
case 32:
|
||||
case 64: u->dis_mode = m ; return;
|
||||
default: u->dis_mode = 16; return;
|
||||
}
|
||||
}
|
||||
|
||||
/* =============================================================================
|
||||
* ud_set_vendor() - Set vendor.
|
||||
* =============================================================================
|
||||
*/
|
||||
extern void
|
||||
ud_set_vendor(struct ud* u, unsigned v)
|
||||
{
|
||||
switch(v) {
|
||||
case UD_VENDOR_INTEL:
|
||||
u->vendor = v;
|
||||
break;
|
||||
case UD_VENDOR_ANY:
|
||||
u->vendor = v;
|
||||
break;
|
||||
default:
|
||||
u->vendor = UD_VENDOR_AMD;
|
||||
}
|
||||
}
|
||||
|
||||
/* =============================================================================
|
||||
* ud_set_pc() - Sets code origin.
|
||||
* =============================================================================
|
||||
*/
|
||||
extern void
|
||||
ud_set_pc(struct ud* u, uint64_t o)
|
||||
{
|
||||
u->pc = o;
|
||||
}
|
||||
|
||||
/* =============================================================================
|
||||
* ud_set_syntax() - Sets the output syntax.
|
||||
* =============================================================================
|
||||
*/
|
||||
extern void
|
||||
ud_set_syntax(struct ud* u, void (*t)(struct ud*))
|
||||
{
|
||||
u->translator = t;
|
||||
}
|
||||
|
||||
/* =============================================================================
|
||||
* ud_insn() - returns the disassembled instruction
|
||||
* =============================================================================
|
||||
*/
|
||||
const char*
|
||||
ud_insn_asm(const struct ud* u)
|
||||
{
|
||||
return u->asm_buf;
|
||||
}
|
||||
|
||||
/* =============================================================================
|
||||
* ud_insn_offset() - Returns the offset.
|
||||
* =============================================================================
|
||||
*/
|
||||
uint64_t
|
||||
ud_insn_off(const struct ud* u)
|
||||
{
|
||||
return u->insn_offset;
|
||||
}
|
||||
|
||||
|
||||
/* =============================================================================
|
||||
* ud_insn_hex() - Returns hex form of disassembled instruction.
|
||||
* =============================================================================
|
||||
*/
|
||||
const char*
|
||||
ud_insn_hex(struct ud* u)
|
||||
{
|
||||
u->insn_hexcode[0] = 0;
|
||||
if (!u->error) {
|
||||
unsigned int i;
|
||||
const unsigned char *src_ptr = ud_insn_ptr(u);
|
||||
char* src_hex;
|
||||
src_hex = (char*) u->insn_hexcode;
|
||||
/* for each byte used to decode instruction */
|
||||
for (i = 0; i < ud_insn_len(u) && i < sizeof(u->insn_hexcode) / 2;
|
||||
++i, ++src_ptr) {
|
||||
sprintf(src_hex, "%02x", *src_ptr & 0xFF);
|
||||
src_hex += 2;
|
||||
}
|
||||
}
|
||||
return u->insn_hexcode;
|
||||
}
|
||||
|
||||
|
||||
/* =============================================================================
|
||||
* ud_insn_ptr
|
||||
* Returns a pointer to buffer containing the bytes that were
|
||||
* disassembled.
|
||||
* =============================================================================
|
||||
*/
|
||||
extern const uint8_t*
|
||||
ud_insn_ptr(const struct ud* u)
|
||||
{
|
||||
return (u->inp_buf == 0) ?
|
||||
u->inp_sess : u->inp_buf + (u->inp_buf_index - u->inp_ctr);
|
||||
}
|
||||
|
||||
|
||||
/* =============================================================================
|
||||
* ud_insn_len
|
||||
* Returns the count of bytes disassembled.
|
||||
* =============================================================================
|
||||
*/
|
||||
extern unsigned int
|
||||
ud_insn_len(const struct ud* u)
|
||||
{
|
||||
return u->inp_ctr;
|
||||
}
|
||||
|
||||
|
||||
/* =============================================================================
|
||||
* ud_insn_get_opr
|
||||
* Return the operand struct representing the nth operand of
|
||||
* the currently disassembled instruction. Returns 0 if
|
||||
* there's no such operand.
|
||||
* =============================================================================
|
||||
*/
|
||||
const struct ud_operand*
|
||||
ud_insn_opr(const struct ud *u, unsigned int n)
|
||||
{
|
||||
if (n > 3 || u->operand[n].type == UD_NONE) {
|
||||
return 0;
|
||||
} else {
|
||||
return &u->operand[n];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* =============================================================================
|
||||
* ud_opr_is_sreg
|
||||
* Returns non-zero if the given operand is of a segment register type.
|
||||
* =============================================================================
|
||||
*/
|
||||
int
|
||||
ud_opr_is_sreg(const struct ud_operand *opr)
|
||||
{
|
||||
return opr->type == UD_OP_REG &&
|
||||
opr->base >= UD_R_ES &&
|
||||
opr->base <= UD_R_GS;
|
||||
}
|
||||
|
||||
|
||||
/* =============================================================================
|
||||
* ud_opr_is_sreg
|
||||
* Returns non-zero if the given operand is of a general purpose
|
||||
* register type.
|
||||
* =============================================================================
|
||||
*/
|
||||
int
|
||||
ud_opr_is_gpr(const struct ud_operand *opr)
|
||||
{
|
||||
return opr->type == UD_OP_REG &&
|
||||
opr->base >= UD_R_AL &&
|
||||
opr->base <= UD_R_R15;
|
||||
}
|
||||
|
||||
|
||||
/* =============================================================================
|
||||
* ud_set_user_opaque_data
|
||||
* ud_get_user_opaque_data
|
||||
* Get/set user opaqute data pointer
|
||||
* =============================================================================
|
||||
*/
|
||||
void
|
||||
ud_set_user_opaque_data(struct ud * u, void* opaque)
|
||||
{
|
||||
u->user_opaque_data = opaque;
|
||||
}
|
||||
|
||||
void*
|
||||
ud_get_user_opaque_data(const struct ud *u)
|
||||
{
|
||||
return u->user_opaque_data;
|
||||
}
|
||||
|
||||
|
||||
/* =============================================================================
|
||||
* ud_set_asm_buffer
|
||||
* Allow the user to set an assembler output buffer. If `buf` is 0,
|
||||
* we switch back to the internal buffer.
|
||||
* =============================================================================
|
||||
*/
|
||||
void
|
||||
ud_set_asm_buffer(struct ud *u, char *buf, size_t size)
|
||||
{
|
||||
if (buf == 0) {
|
||||
ud_set_asm_buffer(u, u->asm_buf_int, sizeof(u->asm_buf_int));
|
||||
} else {
|
||||
u->asm_buf = buf;
|
||||
u->asm_buf_size = size;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* =============================================================================
|
||||
* ud_set_sym_resolver
|
||||
* Set symbol resolver for relative targets used in the translation
|
||||
* phase.
|
||||
*
|
||||
* The resolver is a function that takes a uint64_t address and returns a
|
||||
* symbolic name for the that address. The function also takes a second
|
||||
* argument pointing to an integer that the client can optionally set to a
|
||||
* non-zero value for offsetted targets. (symbol+offset) The function may
|
||||
* also return 0, in which case the translator only prints the target
|
||||
* address.
|
||||
*
|
||||
* The function pointer maybe 0 which resets symbol resolution.
|
||||
* =============================================================================
|
||||
*/
|
||||
void
|
||||
ud_set_sym_resolver(struct ud *u, const char* (*resolver)(struct ud*,
|
||||
uint64_t addr,
|
||||
int64_t *offset))
|
||||
{
|
||||
u->sym_resolver = resolver;
|
||||
}
|
||||
|
||||
|
||||
/* =============================================================================
|
||||
* ud_insn_mnemonic
|
||||
* Return the current instruction mnemonic.
|
||||
* =============================================================================
|
||||
*/
|
||||
enum ud_mnemonic_code
|
||||
ud_insn_mnemonic(const struct ud *u)
|
||||
{
|
||||
return u->mnemonic;
|
||||
}
|
||||
|
||||
|
||||
/* =============================================================================
|
||||
* ud_lookup_mnemonic
|
||||
* Looks up mnemonic code in the mnemonic string table.
|
||||
* Returns 0 if the mnemonic code is invalid.
|
||||
* =============================================================================
|
||||
*/
|
||||
const char*
|
||||
ud_lookup_mnemonic(enum ud_mnemonic_code c)
|
||||
{
|
||||
if (c < UD_MAX_MNEMONIC_CODE) {
|
||||
return ud_mnemonics_str[c];
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* ud_inp_init
|
||||
* Initializes the input system.
|
||||
*/
|
||||
static void
|
||||
ud_inp_init(struct ud *u)
|
||||
{
|
||||
u->inp_hook = 0;
|
||||
u->inp_buf = 0;
|
||||
u->inp_buf_size = 0;
|
||||
u->inp_buf_index = 0;
|
||||
u->inp_curr = 0;
|
||||
u->inp_ctr = 0;
|
||||
u->inp_end = 0;
|
||||
u->inp_peek = UD_EOI;
|
||||
UD_NON_STANDALONE(u->inp_file = 0);
|
||||
}
|
||||
|
||||
|
||||
/* =============================================================================
|
||||
* ud_inp_set_hook
|
||||
* Sets input hook.
|
||||
* =============================================================================
|
||||
*/
|
||||
void
|
||||
ud_set_input_hook(register struct ud* u, int (*hook)(struct ud*))
|
||||
{
|
||||
ud_inp_init(u);
|
||||
u->inp_hook = hook;
|
||||
}
|
||||
|
||||
/* =============================================================================
|
||||
* ud_inp_set_buffer
|
||||
* Set buffer as input.
|
||||
* =============================================================================
|
||||
*/
|
||||
void
|
||||
ud_set_input_buffer(register struct ud* u, const uint8_t* buf, size_t len)
|
||||
{
|
||||
ud_inp_init(u);
|
||||
u->inp_buf = buf;
|
||||
u->inp_buf_size = len;
|
||||
u->inp_buf_index = 0;
|
||||
}
|
||||
|
||||
|
||||
#ifndef __UD_STANDALONE__
|
||||
/* =============================================================================
|
||||
* ud_input_set_file
|
||||
* Set FILE as input.
|
||||
* =============================================================================
|
||||
*/
|
||||
static int
|
||||
inp_file_hook(struct ud* u)
|
||||
{
|
||||
return fgetc(u->inp_file);
|
||||
}
|
||||
|
||||
void
|
||||
ud_set_input_file(register struct ud* u, FILE* f)
|
||||
{
|
||||
ud_inp_init(u);
|
||||
u->inp_hook = inp_file_hook;
|
||||
u->inp_file = f;
|
||||
}
|
||||
#endif /* __UD_STANDALONE__ */
|
||||
|
||||
|
||||
/* =============================================================================
|
||||
* ud_input_skip
|
||||
* Skip n input bytes.
|
||||
* ============================================================================
|
||||
*/
|
||||
void
|
||||
ud_input_skip(struct ud* u, size_t n)
|
||||
{
|
||||
if (u->inp_end) {
|
||||
return;
|
||||
}
|
||||
if (u->inp_buf == 0) {
|
||||
while (n--) {
|
||||
int c = u->inp_hook(u);
|
||||
if (c == UD_EOI) {
|
||||
goto eoi;
|
||||
}
|
||||
}
|
||||
return;
|
||||
} else {
|
||||
if (n > u->inp_buf_size ||
|
||||
u->inp_buf_index > u->inp_buf_size - n) {
|
||||
u->inp_buf_index = u->inp_buf_size;
|
||||
goto eoi;
|
||||
}
|
||||
u->inp_buf_index += n;
|
||||
return;
|
||||
}
|
||||
eoi:
|
||||
u->inp_end = 1;
|
||||
UDERR(u, "cannot skip, eoi received\b");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/* =============================================================================
|
||||
* ud_input_end
|
||||
* Returns non-zero on end-of-input.
|
||||
* =============================================================================
|
||||
*/
|
||||
int
|
||||
ud_input_end(const struct ud *u)
|
||||
{
|
||||
return u->inp_end;
|
||||
}
|
||||
|
||||
/* vim:set ts=2 sw=2 expandtab */
|
||||
Vendored
-33
@@ -1,33 +0,0 @@
|
||||
/* udis86 - udis86.h
|
||||
*
|
||||
* Copyright (c) 2002-2009 Vivek Thampi
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#ifndef UDIS86_H
|
||||
#define UDIS86_H
|
||||
|
||||
#include "libudis86/types.h"
|
||||
#include "libudis86/extern.h"
|
||||
#include "libudis86/itab.h"
|
||||
|
||||
#endif
|
||||
-27
@@ -1,27 +0,0 @@
|
||||
================================================================================
|
||||
Software Name: udis86
|
||||
Version: 56ff6c8
|
||||
URL:https://github.com/vmt/udis86/blob/master/LICENSE
|
||||
===========================================================================================
|
||||
Copyright (c) 2002-2012, Vivek Thampi <vivek.mt@gmail.com>
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
-19
@@ -1,19 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<TpsData xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||
<Name>udis86</Name>
|
||||
<!-- Software Name and Version -->
|
||||
<!-- Software Name:udis86
|
||||
Version: 56ff6c8 -->
|
||||
<!-- Notes:
|
||||
-->
|
||||
<Location>Rad Games Github</Location>
|
||||
<Function>Disassembles x86 object code.</Function>
|
||||
<Eula>https://github.com/jpcy/xatlas/blob/master/LICENSE</Eula>
|
||||
<RedistributeTo>
|
||||
<EndUserGroup>Licencees</EndUserGroup>
|
||||
<EndUserGroup>P4</EndUserGroup>
|
||||
<EndUserGroup>Git</EndUserGroup>
|
||||
</RedistributeTo>
|
||||
<LicenseFolder>/Engine/Source/ThirdParty/Licenses</LicenseFolder>
|
||||
</TpsData>
|
||||
|
||||
Vendored
+5
-3
@@ -1,7 +1,7 @@
|
||||
// DO NOT EDIT. This file is auto-generated by `amalgamate.py`.
|
||||
|
||||
#include "Zydis.h"
|
||||
|
||||
#ifndef ZYDIS_C
|
||||
#define ZYDIS_C
|
||||
|
||||
//
|
||||
// Source file: /home/ath/devel/zydis/src/Decoder.c
|
||||
@@ -54987,4 +54987,6 @@ ZyanStatus ZydisIsFeatureEnabled(ZydisFeature feature)
|
||||
}
|
||||
}
|
||||
|
||||
/* ============================================================================================== */
|
||||
/* ============================================================================================== */
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user