mirror of
https://github.com/Ed94/raddebugger.git
synced 2026-08-14 17:28:07 +00:00
WIP DWARF expression eval
- fixup jump offsets after expression is serialized - use generalized machine ops for register reads - add option to limit number of executed opcodes
This commit is contained in:
+43
-43
@@ -6,7 +6,7 @@ dw_reg_size_from_code_x64(DW_Reg reg_code)
|
|||||||
{
|
{
|
||||||
switch (reg_code) {
|
switch (reg_code) {
|
||||||
#define X(reg_name_dw, reg_code_dw, reg_name_rdi, reg_pos, reg_size) case DW_RegX64_##reg_name_dw: return reg_size;
|
#define X(reg_name_dw, reg_code_dw, reg_name_rdi, reg_pos, reg_size) case DW_RegX64_##reg_name_dw: return reg_size;
|
||||||
DW_Regs_X64_XList(X)
|
DW_Regs_X64_XList
|
||||||
#undef X
|
#undef X
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
@@ -17,7 +17,7 @@ dw_reg_pos_from_code_x64(DW_Reg reg_code)
|
|||||||
{
|
{
|
||||||
switch (reg_code) {
|
switch (reg_code) {
|
||||||
#define X(reg_name_dw, reg_code_dw, reg_name_rdi, reg_pos, reg_size) case DW_RegX64_##reg_name_dw: return reg_pos;
|
#define X(reg_name_dw, reg_code_dw, reg_name_rdi, reg_pos, reg_size) case DW_RegX64_##reg_name_dw: return reg_pos;
|
||||||
DW_Regs_X64_XList(X)
|
DW_Regs_X64_XList
|
||||||
#undef X
|
#undef X
|
||||||
}
|
}
|
||||||
return max_U64;
|
return max_U64;
|
||||||
@@ -84,7 +84,7 @@ dw_attrib_class_from_attrib_v2(DW_AttribKind k)
|
|||||||
{
|
{
|
||||||
switch (k) {
|
switch (k) {
|
||||||
#define X(_N,_C) case DW_AttribKind_##_N: return _C;
|
#define X(_N,_C) case DW_AttribKind_##_N: return _C;
|
||||||
DW_AttribKind_ClassFlags_V2_XList(X)
|
DW_AttribKind_ClassFlags_V2_XList
|
||||||
#undef X
|
#undef X
|
||||||
}
|
}
|
||||||
return DW_AttribClass_Null;
|
return DW_AttribClass_Null;
|
||||||
@@ -95,7 +95,7 @@ dw_attrib_class_from_attrib_v3(DW_AttribKind k)
|
|||||||
{
|
{
|
||||||
switch (k) {
|
switch (k) {
|
||||||
#define X(_N,_C) case DW_AttribKind_##_N: return _C;
|
#define X(_N,_C) case DW_AttribKind_##_N: return _C;
|
||||||
DW_AttribKind_ClassFlags_V3_XList(X)
|
DW_AttribKind_ClassFlags_V3_XList
|
||||||
#undef X
|
#undef X
|
||||||
}
|
}
|
||||||
return DW_AttribClass_Null;
|
return DW_AttribClass_Null;
|
||||||
@@ -106,7 +106,7 @@ dw_attrib_class_from_attrib_v4(DW_AttribKind k)
|
|||||||
{
|
{
|
||||||
switch (k) {
|
switch (k) {
|
||||||
#define X(_N,_C) case DW_AttribKind_##_N: return _C;
|
#define X(_N,_C) case DW_AttribKind_##_N: return _C;
|
||||||
DW_AttribKind_ClassFlags_V4_XList(X)
|
DW_AttribKind_ClassFlags_V4_XList
|
||||||
#undef X
|
#undef X
|
||||||
}
|
}
|
||||||
return DW_AttribClass_Null;
|
return DW_AttribClass_Null;
|
||||||
@@ -117,7 +117,7 @@ dw_attrib_class_from_attrib_v5(DW_AttribKind k)
|
|||||||
{
|
{
|
||||||
switch (k) {
|
switch (k) {
|
||||||
#define X(_N,_C) case DW_AttribKind_##_N: return _C;
|
#define X(_N,_C) case DW_AttribKind_##_N: return _C;
|
||||||
DW_AttribKind_ClassFlags_V5_XList(X)
|
DW_AttribKind_ClassFlags_V5_XList
|
||||||
#undef X
|
#undef X
|
||||||
}
|
}
|
||||||
return DW_AttribClass_Null;
|
return DW_AttribClass_Null;
|
||||||
@@ -128,7 +128,7 @@ dw_attrib_class_from_attrib_gnu(DW_AttribKind k)
|
|||||||
{
|
{
|
||||||
switch (k) {
|
switch (k) {
|
||||||
#define X(_N,_C) case DW_AttribKind_##_N: return _C;
|
#define X(_N,_C) case DW_AttribKind_##_N: return _C;
|
||||||
DW_AttribKind_ClassFlags_GNU_XList(X)
|
DW_AttribKind_ClassFlags_GNU_XList
|
||||||
#undef X
|
#undef X
|
||||||
}
|
}
|
||||||
return DW_AttribClass_Null;
|
return DW_AttribClass_Null;
|
||||||
@@ -139,7 +139,7 @@ dw_attrib_class_from_attrib_llvm(DW_AttribKind k)
|
|||||||
{
|
{
|
||||||
switch (k) {
|
switch (k) {
|
||||||
#define X(_N,_C) case DW_AttribKind_##_N: return _C;
|
#define X(_N,_C) case DW_AttribKind_##_N: return _C;
|
||||||
DW_AttribKind_ClassFlags_LLVM_XList(X)
|
DW_AttribKind_ClassFlags_LLVM_XList
|
||||||
#undef X
|
#undef X
|
||||||
}
|
}
|
||||||
return DW_AttribClass_Null;
|
return DW_AttribClass_Null;
|
||||||
@@ -150,7 +150,7 @@ dw_attrib_class_from_attrib_apple(DW_AttribKind k)
|
|||||||
{
|
{
|
||||||
switch (k) {
|
switch (k) {
|
||||||
#define X(_N,_C) case DW_AttribKind_##_N: return _C;
|
#define X(_N,_C) case DW_AttribKind_##_N: return _C;
|
||||||
DW_AttribKind_ClassFlags_APPLE_XList(X)
|
DW_AttribKind_ClassFlags_APPLE_XList
|
||||||
#undef X
|
#undef X
|
||||||
}
|
}
|
||||||
return DW_AttribClass_Null;
|
return DW_AttribClass_Null;
|
||||||
@@ -161,7 +161,7 @@ dw_attrib_class_from_attrib_mips(DW_AttribKind k)
|
|||||||
{
|
{
|
||||||
switch (k) {
|
switch (k) {
|
||||||
#define X(_N,_C) case DW_AttribKind_##_N: return _C;
|
#define X(_N,_C) case DW_AttribKind_##_N: return _C;
|
||||||
DW_AttribKind_ClassFlags_MIPS_XList(X)
|
DW_AttribKind_ClassFlags_MIPS_XList
|
||||||
#undef X
|
#undef X
|
||||||
}
|
}
|
||||||
return DW_AttribClass_Null;
|
return DW_AttribClass_Null;
|
||||||
@@ -215,28 +215,28 @@ dw_attrib_class_from_form_kind(DW_Version ver, DW_FormKind k)
|
|||||||
#define X(_N,_C) case DW_Form_##_N: return _C;
|
#define X(_N,_C) case DW_Form_##_N: return _C;
|
||||||
|
|
||||||
switch (k) {
|
switch (k) {
|
||||||
DW_Form_AttribClass_GNU_XList(X)
|
DW_Form_AttribClass_GNU_XList
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (ver) {
|
switch (ver) {
|
||||||
case DW_Version_5: {
|
case DW_Version_5: {
|
||||||
switch (k) {
|
switch (k) {
|
||||||
DW_Form_AttribClass_V5_XList(X)
|
DW_Form_AttribClass_V5_XList
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
case DW_Version_4: {
|
case DW_Version_4: {
|
||||||
switch (k) {
|
switch (k) {
|
||||||
DW_Form_AttribClass_V4_XList(X)
|
DW_Form_AttribClass_V4_XList
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
case DW_Version_3: {
|
case DW_Version_3: {
|
||||||
switch (k) {
|
switch (k) {
|
||||||
DW_Form_AttribClass_V2_XList(X)
|
DW_Form_AttribClass_V2_XList
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
case DW_Version_2: {
|
case DW_Version_2: {
|
||||||
switch (k) {
|
switch (k) {
|
||||||
DW_Form_AttribClass_V2_XList(X)
|
DW_Form_AttribClass_V2_XList
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
case DW_Version_1: {
|
case DW_Version_1: {
|
||||||
@@ -261,7 +261,7 @@ dw_name_string_from_section_kind(DW_SectionKind k)
|
|||||||
{
|
{
|
||||||
switch (k) {
|
switch (k) {
|
||||||
#define X(_N,_L,_M,_D) case DW_Section_##_N: return str8_lit(_L);
|
#define X(_N,_L,_M,_D) case DW_Section_##_N: return str8_lit(_L);
|
||||||
DW_SectionKind_XList(X)
|
DW_SectionKind_XList
|
||||||
#undef X
|
#undef X
|
||||||
}
|
}
|
||||||
return str8_zero();
|
return str8_zero();
|
||||||
@@ -272,7 +272,7 @@ dw_mach_name_string_from_section_kind(DW_SectionKind k)
|
|||||||
{
|
{
|
||||||
switch (k) {
|
switch (k) {
|
||||||
#define X(_N,_L,_M,_D) case DW_Section_##_N: return str8_lit(_M);
|
#define X(_N,_L,_M,_D) case DW_Section_##_N: return str8_lit(_M);
|
||||||
DW_SectionKind_XList(X)
|
DW_SectionKind_XList
|
||||||
#undef X
|
#undef X
|
||||||
}
|
}
|
||||||
return str8_zero();
|
return str8_zero();
|
||||||
@@ -283,7 +283,7 @@ dw_dwo_name_string_from_section_kind(DW_SectionKind k)
|
|||||||
{
|
{
|
||||||
switch (k) {
|
switch (k) {
|
||||||
#define X(_N,_L,_M,_D) case DW_Section_##_N: return str8_lit(_D);
|
#define X(_N,_L,_M,_D) case DW_Section_##_N: return str8_lit(_D);
|
||||||
DW_SectionKind_XList(X)
|
DW_SectionKind_XList
|
||||||
#undef X
|
#undef X
|
||||||
}
|
}
|
||||||
return str8_zero();
|
return str8_zero();
|
||||||
@@ -460,7 +460,7 @@ dw_operand_count_from_cfa_opcode(DW_CFA_Opcode opcode)
|
|||||||
{
|
{
|
||||||
switch (opcode) {
|
switch (opcode) {
|
||||||
#define X(_N, _ID, ...) case _ID: { local_persist DW_CFA_OperandType t[] = { DW_CFA_OperandType_Null, __VA_ARGS__ }; return ArrayCount(t)-1; }
|
#define X(_N, _ID, ...) case _ID: { local_persist DW_CFA_OperandType t[] = { DW_CFA_OperandType_Null, __VA_ARGS__ }; return ArrayCount(t)-1; }
|
||||||
DW_CFA_Kind_XList(X)
|
DW_CFA_Kind_XList
|
||||||
#undef X
|
#undef X
|
||||||
default: { NotImplemented; } break;
|
default: { NotImplemented; } break;
|
||||||
}
|
}
|
||||||
@@ -513,7 +513,7 @@ dw_operand_types_from_cfa_op(DW_CFA_Opcode opcode)
|
|||||||
{
|
{
|
||||||
switch (opcode) {
|
switch (opcode) {
|
||||||
#define X(_N, _ID, ...) case _ID: { local_persist DW_CFA_OperandType t[] = { DW_CFA_OperandType_Null, __VA_ARGS__ }; return &t[0] + 1; }
|
#define X(_N, _ID, ...) case _ID: { local_persist DW_CFA_OperandType t[] = { DW_CFA_OperandType_Null, __VA_ARGS__ }; return &t[0] + 1; }
|
||||||
DW_CFA_Kind_XList(X)
|
DW_CFA_Kind_XList
|
||||||
#undef X
|
#undef X
|
||||||
default: { NotImplemented; } break;
|
default: { NotImplemented; } break;
|
||||||
}
|
}
|
||||||
@@ -581,9 +581,9 @@ dw_string_from_tag_kind(Arena *arena, DW_TagKind kind)
|
|||||||
switch (kind) {
|
switch (kind) {
|
||||||
case DW_TagKind_Null: return str8_lit("Null");
|
case DW_TagKind_Null: return str8_lit("Null");
|
||||||
#define X(_N,_ID) case DW_TagKind_##_N: return str8_lit(Stringify(_N));
|
#define X(_N,_ID) case DW_TagKind_##_N: return str8_lit(Stringify(_N));
|
||||||
DW_TagKind_V3_XList(X)
|
DW_TagKind_V3_XList
|
||||||
DW_TagKind_V5_XList(X)
|
DW_TagKind_V5_XList
|
||||||
DW_TagKind_GNU_XList(X)
|
DW_TagKind_GNU_XList
|
||||||
#undef X
|
#undef X
|
||||||
}
|
}
|
||||||
return push_str8f(arena, "%llx", kind);
|
return push_str8f(arena, "%llx", kind);
|
||||||
@@ -611,10 +611,10 @@ dw_string_from_attrib_kind(Arena *arena, DW_Version ver, DW_Ext ext, DW_AttribKi
|
|||||||
{
|
{
|
||||||
default:{}break;
|
default:{}break;
|
||||||
case DW_Ext_Null: break;
|
case DW_Ext_Null: break;
|
||||||
case DW_Ext_GNU: switch (kind) { DW_AttribKind_GNU_XList(X) } break;
|
case DW_Ext_GNU: switch (kind) { DW_AttribKind_GNU_XList } break;
|
||||||
case DW_Ext_LLVM: switch (kind) { DW_AttribKind_LLVM_XList(X) } break;
|
case DW_Ext_LLVM: switch (kind) { DW_AttribKind_LLVM_XList } break;
|
||||||
case DW_Ext_APPLE: switch (kind) { DW_AttribKind_APPLE_XList(X) } break;
|
case DW_Ext_APPLE: switch (kind) { DW_AttribKind_APPLE_XList } break;
|
||||||
case DW_Ext_MIPS: switch (kind) { DW_AttribKind_MIPS_XList(X) } break;
|
case DW_Ext_MIPS: switch (kind) { DW_AttribKind_MIPS_XList } break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -627,10 +627,10 @@ dw_string_from_attrib_kind(Arena *arena, DW_Version ver, DW_Ext ext, DW_AttribKi
|
|||||||
DW_Version version = retry ? DW_Version_5 : ver;
|
DW_Version version = retry ? DW_Version_5 : ver;
|
||||||
switch(version)
|
switch(version)
|
||||||
{
|
{
|
||||||
case DW_Version_5: { switch(kind) { DW_AttribKind_V5_XList(X) } } // fall-through
|
case DW_Version_5: { switch(kind) { DW_AttribKind_V5_XList } } // fall-through
|
||||||
case DW_Version_4: { switch(kind) { DW_AttribKind_V4_XList(X) } } // fall-through
|
case DW_Version_4: { switch(kind) { DW_AttribKind_V4_XList } } // fall-through
|
||||||
case DW_Version_3: { switch(kind) { DW_AttribKind_V3_XList(X) } } // fall-through
|
case DW_Version_3: { switch(kind) { DW_AttribKind_V3_XList } } // fall-through
|
||||||
case DW_Version_2: { switch(kind) { DW_AttribKind_V2_XList(X) } } // fall-through
|
case DW_Version_2: { switch(kind) { DW_AttribKind_V2_XList } } // fall-through
|
||||||
case DW_Version_1: {}break;
|
case DW_Version_1: {}break;
|
||||||
case DW_Version_Null:{}break;
|
case DW_Version_Null:{}break;
|
||||||
default:{}break;
|
default:{}break;
|
||||||
@@ -655,18 +655,18 @@ dw_string_from_form_kind(Arena *arena, DW_Version ver, DW_FormKind kind)
|
|||||||
switch (ver) {
|
switch (ver) {
|
||||||
case DW_Version_5: {
|
case DW_Version_5: {
|
||||||
switch (kind) {
|
switch (kind) {
|
||||||
DW_Form_V5_XList(X)
|
DW_Form_V5_XList
|
||||||
}
|
}
|
||||||
} // fall-through
|
} // fall-through
|
||||||
case DW_Version_4: {
|
case DW_Version_4: {
|
||||||
switch (kind) {
|
switch (kind) {
|
||||||
DW_Form_V4_XList(X)
|
DW_Form_V4_XList
|
||||||
}
|
}
|
||||||
} // fall-through
|
} // fall-through
|
||||||
case DW_Version_3:
|
case DW_Version_3:
|
||||||
case DW_Version_2: {
|
case DW_Version_2: {
|
||||||
switch (kind) {
|
switch (kind) {
|
||||||
DW_Form_V2_XList(X)
|
DW_Form_V2_XList
|
||||||
}
|
}
|
||||||
} // fall-through
|
} // fall-through
|
||||||
case DW_Version_Null: break;
|
case DW_Version_Null: break;
|
||||||
@@ -681,7 +681,7 @@ dw_string_from_language(Arena *arena, DW_Language kind)
|
|||||||
{
|
{
|
||||||
switch (kind) {
|
switch (kind) {
|
||||||
#define X(_N,_ID) case DW_Language_##_N: return str8_lit(Stringify(_N));
|
#define X(_N,_ID) case DW_Language_##_N: return str8_lit(Stringify(_N));
|
||||||
DW_Language_XList(X)
|
DW_Language_XList
|
||||||
#undef X
|
#undef X
|
||||||
}
|
}
|
||||||
return push_str8f(arena, "%x", kind);
|
return push_str8f(arena, "%x", kind);
|
||||||
@@ -692,7 +692,7 @@ dw_string_from_inl(Arena *arena, DW_InlKind kind)
|
|||||||
{
|
{
|
||||||
switch (kind) {
|
switch (kind) {
|
||||||
#define X(_N,_ID) case _ID: return str8_lit(Stringify(_N));
|
#define X(_N,_ID) case _ID: return str8_lit(Stringify(_N));
|
||||||
DW_Inl_XList(X)
|
DW_Inl_XList
|
||||||
#undef X
|
#undef X
|
||||||
}
|
}
|
||||||
return push_str8f(arena, "%x", kind);
|
return push_str8f(arena, "%x", kind);
|
||||||
@@ -703,7 +703,7 @@ dw_string_from_access_kind(Arena *arena, DW_AccessKind kind)
|
|||||||
{
|
{
|
||||||
switch (kind) {
|
switch (kind) {
|
||||||
#define X(_N,_ID) case _ID: return str8_lit(Stringify(_N));
|
#define X(_N,_ID) case _ID: return str8_lit(Stringify(_N));
|
||||||
DW_AccessKind_XList(X)
|
DW_AccessKind_XList
|
||||||
#undef X
|
#undef X
|
||||||
}
|
}
|
||||||
return push_str8f(arena, "%llx", kind);
|
return push_str8f(arena, "%llx", kind);
|
||||||
@@ -714,7 +714,7 @@ dw_string_from_calling_convetion(Arena *arena, DW_CallingConventionKind kind)
|
|||||||
{
|
{
|
||||||
switch (kind) {
|
switch (kind) {
|
||||||
#define X(_N,_ID) case _ID: return str8_lit(Stringify(_N));
|
#define X(_N,_ID) case _ID: return str8_lit(Stringify(_N));
|
||||||
DW_CallingConventionKind_XList(X)
|
DW_CallingConventionKind_XList
|
||||||
#undef X
|
#undef X
|
||||||
}
|
}
|
||||||
return push_str8f(arena, "%llx", kind);
|
return push_str8f(arena, "%llx", kind);
|
||||||
@@ -725,7 +725,7 @@ dw_string_from_attrib_type_encoding(Arena *arena, DW_ATE kind)
|
|||||||
{
|
{
|
||||||
switch (kind) {
|
switch (kind) {
|
||||||
#define X(_N,_ID) case _ID: return str8_lit(Stringify(_N));
|
#define X(_N,_ID) case _ID: return str8_lit(Stringify(_N));
|
||||||
DW_ATE_XList(X)
|
DW_ATE_XList
|
||||||
#undef X
|
#undef X
|
||||||
}
|
}
|
||||||
return push_str8f(arena, "%llx", kind);
|
return push_str8f(arena, "%llx", kind);
|
||||||
@@ -736,7 +736,7 @@ dw_string_from_std_opcode(Arena *arena, DW_StdOpcode kind)
|
|||||||
{
|
{
|
||||||
switch (kind) {
|
switch (kind) {
|
||||||
#define X(_N,_ID) case DW_StdOpcode_##_N: return str8_lit(Stringify(_N));
|
#define X(_N,_ID) case DW_StdOpcode_##_N: return str8_lit(Stringify(_N));
|
||||||
DW_StdOpcode_XList(X)
|
DW_StdOpcode_XList
|
||||||
#undef X
|
#undef X
|
||||||
}
|
}
|
||||||
return push_str8f(arena, "%x", kind);
|
return push_str8f(arena, "%x", kind);
|
||||||
@@ -747,7 +747,7 @@ dw_string_from_ext_opcode(Arena *arena, DW_ExtOpcode kind)
|
|||||||
{
|
{
|
||||||
switch (kind) {
|
switch (kind) {
|
||||||
#define X(_N,_ID) case DW_ExtOpcode_##_N: return str8_lit(Stringify(_N));
|
#define X(_N,_ID) case DW_ExtOpcode_##_N: return str8_lit(Stringify(_N));
|
||||||
DW_ExtOpcode_XList(X)
|
DW_ExtOpcode_XList
|
||||||
#undef X
|
#undef X
|
||||||
default: InvalidPath; break;
|
default: InvalidPath; break;
|
||||||
}
|
}
|
||||||
@@ -784,7 +784,7 @@ dw_string_from_register(Arena *arena, Arch arch, U64 reg_id)
|
|||||||
case Arch_x64: {
|
case Arch_x64: {
|
||||||
switch (reg_id) {
|
switch (reg_id) {
|
||||||
#define X(_N, _ID, ...) case DW_RegX64_##_N: reg_str = str8_lit(Stringify(_N)); break;
|
#define X(_N, _ID, ...) case DW_RegX64_##_N: reg_str = str8_lit(Stringify(_N)); break;
|
||||||
DW_Regs_X64_XList(X)
|
DW_Regs_X64_XList
|
||||||
#undef X
|
#undef X
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
@@ -804,7 +804,7 @@ dw_string_from_cfa_opcode(DW_CFA_Opcode opcode)
|
|||||||
{
|
{
|
||||||
switch (opcode) {
|
switch (opcode) {
|
||||||
#define X(_NAME, _ID, ...) case _ID: return str8_lit(Stringify(_NAME));
|
#define X(_NAME, _ID, ...) case _ID: return str8_lit(Stringify(_NAME));
|
||||||
DW_CFA_Kind_XList(X)
|
DW_CFA_Kind_XList
|
||||||
#undef X
|
#undef X
|
||||||
default: InvalidPath; break;
|
default: InvalidPath; break;
|
||||||
}
|
}
|
||||||
|
|||||||
+1186
-1209
File diff suppressed because it is too large
Load Diff
+73
-38
@@ -1127,23 +1127,30 @@ dw_expr_inst_from_delta(DW_ExprInst *inst, S16 delta)
|
|||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal DW_UnwindStatus
|
internal DW_ExprEvalResult
|
||||||
dw_eval_expr(Arena *arena, DW_ExprContext *ctx, DW_Expr expr, DW_RegRead *reg_read, void *reg_read_ud, DW_ExprValue *value_out)
|
dw_eval_expr(Arena *arena, Arch arch, DW_Format format, U64 cfa, U64 tls, U64 exec_op_limit, DW_Expr expr, MachineOp_RegRead *reg_read, void *reg_read_ud, DW_ExprValue *value_out)
|
||||||
{
|
{
|
||||||
Temp scratch = scratch_begin(&arena, 1);
|
Temp scratch = scratch_begin(&arena, 1);
|
||||||
DW_UnwindStatus result = DW_UnwindStatus_Ok;
|
|
||||||
DW_PieceList pieces = {0};
|
DW_ExprEvalResult result = DW_ExprEvalResult_Fail;
|
||||||
DW_ExprStack *stack = push_array(scratch.arena, DW_ExprStack, 1);
|
DW_PieceList pieces = {0};
|
||||||
B32 is_ok = 1;
|
DW_ExprStack *stack = push_array(scratch.arena, DW_ExprStack, 1);
|
||||||
|
U64 exec_op_count = 0;
|
||||||
|
|
||||||
for EachNode(inst, DW_ExprInst, expr.first) {
|
for EachNode(inst, DW_ExprInst, expr.first) {
|
||||||
again:;
|
again:;
|
||||||
|
|
||||||
|
exec_op_count += 1;
|
||||||
|
if (exec_op_count > exec_op_limit) {
|
||||||
|
Assert(0 && "reached opcode exec limit on the expression");
|
||||||
|
result = DW_ExprEvalResult_ExecOpLimitReached;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
U64 pop_count = dw_pop_count_from_expr_op(inst->opcode);
|
U64 pop_count = dw_pop_count_from_expr_op(inst->opcode);
|
||||||
if (pop_count >= stack->count) {
|
if (pop_count > stack->count) {
|
||||||
Assert(0 && "not enough values on the stack to evaluate the instruction");
|
Assert(0 && "not enough values on the stack to evaluate the instruction");
|
||||||
is_ok = 0;
|
goto exit;
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (inst->opcode) {
|
switch (inst->opcode) {
|
||||||
@@ -1187,18 +1194,18 @@ dw_eval_expr(Arena *arena, DW_ExprContext *ctx, DW_Expr expr, DW_RegRead *reg_re
|
|||||||
case DW_ExprOp_Reg27: case DW_ExprOp_Reg28: case DW_ExprOp_Reg29:
|
case DW_ExprOp_Reg27: case DW_ExprOp_Reg28: case DW_ExprOp_Reg29:
|
||||||
case DW_ExprOp_Reg30: case DW_ExprOp_Reg31: {
|
case DW_ExprOp_Reg30: case DW_ExprOp_Reg31: {
|
||||||
DW_Reg reg_id = inst->opcode - DW_ExprOp_Reg0;
|
DW_Reg reg_id = inst->opcode - DW_ExprOp_Reg0;
|
||||||
U64 reg_size = dw_reg_size_from_code(ctx->arch, reg_id);
|
U64 reg_size = dw_reg_size_from_code(arch, reg_id);
|
||||||
U8 *reg_value = push_array(scratch.arena, U8, reg_size);
|
U8 *reg_value = push_array(scratch.arena, U8, reg_size);
|
||||||
result = reg_read(reg_id, reg_value, reg_size, reg_read_ud);
|
MachineOpResult reg_read_result = reg_read(reg_id, reg_value, reg_size, reg_read_ud);
|
||||||
if (result != DW_UnwindStatus_Ok) { goto exit; }
|
if (reg_read_result != MachineOpResult_Ok) { goto exit; }
|
||||||
dw_expr_stack_push_unsigned(scratch.arena, stack, reg_value, reg_size);
|
dw_expr_stack_push_unsigned(scratch.arena, stack, reg_value, reg_size);
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case DW_ExprOp_RegX: {
|
case DW_ExprOp_RegX: {
|
||||||
U64 reg_size = dw_reg_size_from_code(ctx->arch, inst->operands[0].u64);
|
U64 reg_size = dw_reg_size_from_code(arch, inst->operands[0].u64);
|
||||||
U8 *reg_value = push_array(scratch.arena, U8, reg_size);
|
U8 *reg_value = push_array(scratch.arena, U8, reg_size);
|
||||||
result = reg_read(inst->operands[0].u64, reg_value, reg_size, reg_read_ud);
|
MachineOpResult reg_read_result = reg_read(inst->operands[0].u64, reg_value, reg_size, reg_read_ud);
|
||||||
if (result != DW_UnwindStatus_Ok) { goto exit; }
|
if (reg_read_result != MachineOpResult_Ok) { goto exit; }
|
||||||
dw_expr_stack_push_unsigned(scratch.arena, stack, reg_value, reg_size);
|
dw_expr_stack_push_unsigned(scratch.arena, stack, reg_value, reg_size);
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
@@ -1212,12 +1219,12 @@ dw_eval_expr(Arena *arena, DW_ExprContext *ctx, DW_Expr expr, DW_RegRead *reg_re
|
|||||||
|
|
||||||
case DW_ExprOp_Piece: {
|
case DW_ExprOp_Piece: {
|
||||||
if (stack->count) {
|
if (stack->count) {
|
||||||
String8 value = dw_string_from_expr_value(arena, ctx->arch, dw_expr_stack_pop(stack));
|
String8 value = dw_string_from_expr_value(arena, arch, dw_expr_stack_pop(stack));
|
||||||
if (inst->operands[0].u64 <= value.size) {
|
if (inst->operands[0].u64 <= value.size) {
|
||||||
dw_piece_list_push(arena, &pieces, (DW_Piece){ .kind = DW_PieceKind_Value, .value = { .ptr = value.str, .bit_size = inst->operands[0].u64 * 8 }});
|
dw_piece_list_push(arena, &pieces, (DW_Piece){ .kind = DW_PieceKind_Value, .value = { .ptr = value.str, .bit_size = inst->operands[0].u64 * 8 }});
|
||||||
} else {
|
} else {
|
||||||
Assert(0 && "out of bounds size in the piece opcode");
|
Assert(0 && "out of bounds size in the piece opcode");
|
||||||
result = DW_UnwindStatus_Fail;
|
goto exit;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
dw_piece_list_push(arena, &pieces, (DW_Piece){ .kind = DW_PieceKind_Undefined, .undef_bit_size = inst->operands[0].u64 * 8 });
|
dw_piece_list_push(arena, &pieces, (DW_Piece){ .kind = DW_PieceKind_Undefined, .undef_bit_size = inst->operands[0].u64 * 8 });
|
||||||
@@ -1225,12 +1232,12 @@ dw_eval_expr(Arena *arena, DW_ExprContext *ctx, DW_Expr expr, DW_RegRead *reg_re
|
|||||||
} break;
|
} break;
|
||||||
case DW_ExprOp_BitPiece: {
|
case DW_ExprOp_BitPiece: {
|
||||||
if (stack->count) {
|
if (stack->count) {
|
||||||
String8 value = dw_string_from_expr_value(arena, ctx->arch, dw_expr_stack_pop(stack));
|
String8 value = dw_string_from_expr_value(arena, arch, dw_expr_stack_pop(stack));
|
||||||
if (inst->operands[0].u64 <= value.size * 8) {
|
if (inst->operands[0].u64 <= value.size * 8) {
|
||||||
dw_piece_list_push(arena, &pieces, (DW_Piece){ .kind = DW_PieceKind_Value, .value = { .ptr = value.str, .bit_size = inst->operands[0].u64 }});
|
dw_piece_list_push(arena, &pieces, (DW_Piece){ .kind = DW_PieceKind_Value, .value = { .ptr = value.str, .bit_size = inst->operands[0].u64 }});
|
||||||
} else {
|
} else {
|
||||||
Assert(0 && "out of bounds size in the bit piece opcode");
|
Assert(0 && "out of bounds size in the bit piece opcode");
|
||||||
result = DW_UnwindStatus_Fail;
|
goto exit;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
dw_piece_list_push(arena, &pieces, (DW_Piece){ .kind = DW_PieceKind_Undefined, .undef_bit_size = inst->operands[0].u64 });
|
dw_piece_list_push(arena, &pieces, (DW_Piece){ .kind = DW_PieceKind_Undefined, .undef_bit_size = inst->operands[0].u64 });
|
||||||
@@ -1243,7 +1250,7 @@ dw_eval_expr(Arena *arena, DW_ExprContext *ctx, DW_Expr expr, DW_RegRead *reg_re
|
|||||||
dw_expr_stack_push(scratch.arena, stack, src->v);
|
dw_expr_stack_push(scratch.arena, stack, src->v);
|
||||||
} else {
|
} else {
|
||||||
Assert(0 && "out of bounds stack index");
|
Assert(0 && "out of bounds stack index");
|
||||||
result = DW_UnwindStatus_Fail;
|
goto exit;
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
@@ -1253,7 +1260,7 @@ dw_eval_expr(Arena *arena, DW_ExprContext *ctx, DW_Expr expr, DW_RegRead *reg_re
|
|||||||
dw_expr_stack_push(scratch.arena, stack, src->v);
|
dw_expr_stack_push(scratch.arena, stack, src->v);
|
||||||
} else {
|
} else {
|
||||||
Assert(0 && "out of bounds stack index");
|
Assert(0 && "out of bounds stack index");
|
||||||
result = DW_UnwindStatus_Fail;
|
goto exit;
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
@@ -1269,8 +1276,7 @@ dw_eval_expr(Arena *arena, DW_ExprContext *ctx, DW_Expr expr, DW_RegRead *reg_re
|
|||||||
|
|
||||||
if (i == 0) {
|
if (i == 0) {
|
||||||
Assert(0 && "seeking to an invalid offset");
|
Assert(0 && "seeking to an invalid offset");
|
||||||
result = DW_UnwindStatus_Fail;
|
goto exit;
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
inst = i;
|
inst = i;
|
||||||
@@ -1282,16 +1288,14 @@ dw_eval_expr(Arena *arena, DW_ExprContext *ctx, DW_Expr expr, DW_RegRead *reg_re
|
|||||||
|
|
||||||
if (cond.type != DW_ExprValueType_S16) {
|
if (cond.type != DW_ExprValueType_S16) {
|
||||||
Assert(0 && "unexpected value");
|
Assert(0 && "unexpected value");
|
||||||
result = DW_UnwindStatus_Fail;
|
goto exit;
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
DW_ExprInst *i = dw_expr_inst_from_delta(inst, inst->operands[0].s16);
|
DW_ExprInst *i = dw_expr_inst_from_delta(inst, inst->operands[0].s16);
|
||||||
|
|
||||||
if (i == 0) {
|
if (i == 0) {
|
||||||
Assert(0 && "seeking to an invalid offset");
|
Assert(0 && "seeking to an invalid offset");
|
||||||
result = DW_UnwindStatus_Fail;
|
goto exit;
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
inst = i;
|
inst = i;
|
||||||
@@ -1334,18 +1338,17 @@ dw_eval_expr(Arena *arena, DW_ExprContext *ctx, DW_Expr expr, DW_RegRead *reg_re
|
|||||||
|
|
||||||
case DW_ExprOp_EntryValue:
|
case DW_ExprOp_EntryValue:
|
||||||
case DW_ExprOp_GNU_EntryValue: {
|
case DW_ExprOp_GNU_EntryValue: {
|
||||||
DW_Expr entry_value_expr = dw_expr_from_data(scratch.arena, ctx->format, byte_size_from_arch(ctx->arch), inst->operands[0].block);
|
DW_Expr entry_value_expr = dw_expr_from_data(scratch.arena, format, byte_size_from_arch(arch), inst->operands[0].block);
|
||||||
DW_ExprValue entry_value;
|
DW_ExprValue entry_value;
|
||||||
result = dw_eval_expr(scratch.arena, ctx, entry_value_expr, reg_read, reg_read_ud, &entry_value);
|
result = dw_eval_expr(scratch.arena, arch, format, cfa, tls, exec_op_limit, entry_value_expr, reg_read, reg_read_ud, &entry_value);
|
||||||
if (result == DW_UnwindStatus_Ok) {
|
if (result != DW_ExprEvalResult_Ok) { goto exit; }
|
||||||
dw_expr_stack_push(scratch.arena, stack, entry_value);
|
dw_expr_stack_push(scratch.arena, stack, entry_value);
|
||||||
}
|
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case DW_ExprOp_Addrx: { NotImplemented; } break;
|
case DW_ExprOp_Addrx: { NotImplemented; } break;
|
||||||
|
|
||||||
case DW_ExprOp_CallFrameCfa: {
|
case DW_ExprOp_CallFrameCfa: {
|
||||||
dw_expr_stack_push(scratch.arena, stack, (DW_ExprValue){ .type = DW_ExprValueType_U64, .u64 = ctx->cfa });
|
dw_expr_stack_push(scratch.arena, stack, (DW_ExprValue){ .type = DW_ExprValueType_U64, .u64 = cfa });
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case DW_ExprOp_PushObjectAddress: { NotImplemented; } break;
|
case DW_ExprOp_PushObjectAddress: { NotImplemented; } break;
|
||||||
@@ -1399,35 +1402,43 @@ dw_eval_expr(Arena *arena, DW_ExprContext *ctx, DW_Expr expr, DW_RegRead *reg_re
|
|||||||
} break;
|
} break;
|
||||||
|
|
||||||
case DW_ExprOp_StackValue: {
|
case DW_ExprOp_StackValue: {
|
||||||
stack->top->v.type = dw_expr_unsigned_value_type_from_bit_size(byte_size_from_arch(ctx->arch) * 8);
|
stack->top->v.type = dw_expr_unsigned_value_type_from_bit_size(bit_size_from_arch(arch));
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case DW_ExprOp_GNU_PushTlsAddress:
|
case DW_ExprOp_GNU_PushTlsAddress:
|
||||||
case DW_ExprOp_FormTlsAddress: {
|
case DW_ExprOp_FormTlsAddress: {
|
||||||
DW_ExprValue tls_off = dw_expr_stack_pop(stack);
|
DW_ExprValue tls_off = dw_expr_stack_pop(stack);
|
||||||
DW_ExprValue tls_base = { .type = DW_ExprValueType_Addr, .addr = ctx->tls_base };
|
DW_ExprValue tls_base = { .type = DW_ExprValueType_Addr, .addr = tls };
|
||||||
DW_ExprValue tls_addr = dw_expr_add(tls_base, tls_off);
|
DW_ExprValue tls_addr = dw_expr_add(tls_base, tls_off);
|
||||||
dw_expr_stack_push(scratch.arena, stack, tls_addr);
|
dw_expr_stack_push(scratch.arena, stack, tls_addr);
|
||||||
} break;
|
} break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
result = DW_ExprEvalResult_Ok;
|
||||||
exit:;
|
exit:;
|
||||||
scratch_end(scratch);
|
scratch_end(scratch);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal String8
|
internal String8
|
||||||
dw_encode_expr(Arena *arena, DW_Format format, U64 addr_size, DW_ExprEnc *encs, U64 encs_count)
|
dw_encode_expr(Arena *arena, Arch arch, DW_Format format, DW_ExprEnc *encs, U64 encs_count)
|
||||||
{
|
{
|
||||||
Temp scratch = scratch_begin(&arena, 1);
|
Temp scratch = scratch_begin(&arena, 1);
|
||||||
|
|
||||||
String8List *srl = push_array(scratch.arena, String8List, 1);
|
String8List *srl = push_array(scratch.arena, String8List, 1);
|
||||||
str8_serial_begin(scratch.arena, srl);
|
str8_serial_begin(scratch.arena, srl);
|
||||||
|
|
||||||
|
HashTable *label_map = hash_table_init(scratch.arena, 128);
|
||||||
|
|
||||||
|
struct Fixup { U64 offset; String8 label; struct Fixup *next; };
|
||||||
|
struct Fixup *first_fixup = 0, *last_fixup = 0;
|
||||||
|
|
||||||
for EachIndex(i, encs_count) {
|
for EachIndex(i, encs_count) {
|
||||||
DW_ExprEnc *e = &encs[i];
|
DW_ExprEnc *e = &encs[i];
|
||||||
|
|
||||||
switch (e->type) {
|
switch (e->type) {
|
||||||
|
case DW_ExprEncType_Null: {} break;
|
||||||
case DW_ExprEncType_Op: {
|
case DW_ExprEncType_Op: {
|
||||||
str8_serial_push_struct(scratch.arena, srl, &e->op);
|
str8_serial_push_struct(scratch.arena, srl, &e->op);
|
||||||
} break;
|
} break;
|
||||||
@@ -1487,6 +1498,7 @@ dw_encode_expr(Arena *arena, DW_Format format, U64 addr_size, DW_ExprEnc *encs,
|
|||||||
str8_serial_push_string(scratch.arena, srl, str8(buffer, buffer_size));
|
str8_serial_push_string(scratch.arena, srl, str8(buffer, buffer_size));
|
||||||
} break;
|
} break;
|
||||||
case DW_ExprEncType_Addr: {
|
case DW_ExprEncType_Addr: {
|
||||||
|
U64 addr_size = byte_size_from_arch(arch);
|
||||||
Assert(addr_size <= sizeof(e->addr));
|
Assert(addr_size <= sizeof(e->addr));
|
||||||
str8_serial_push_string(scratch.arena, srl, str8((U8 *)&e->addr, addr_size));
|
str8_serial_push_string(scratch.arena, srl, str8((U8 *)&e->addr, addr_size));
|
||||||
} break;
|
} break;
|
||||||
@@ -1504,16 +1516,39 @@ dw_encode_expr(Arena *arena, DW_Format format, U64 addr_size, DW_ExprEnc *encs,
|
|||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
case DW_ExprEncType_Label: {
|
case DW_ExprEncType_Label: {
|
||||||
// TODO:
|
struct Fixup *fixup = push_array(scratch.arena, struct Fixup, 1);
|
||||||
|
fixup->offset = srl->total_size;
|
||||||
|
fixup->label = e->label;
|
||||||
|
SLLQueuePush(first_fixup, last_fixup, fixup);
|
||||||
|
|
||||||
|
S16 delta_placeholder = 0;
|
||||||
|
str8_serial_push_struct(scratch.arena, srl, &delta_placeholder);
|
||||||
} break;
|
} break;
|
||||||
case DW_ExprEncType_DeclLabel: {
|
case DW_ExprEncType_DeclLabel: {
|
||||||
// TODO:
|
hash_table_push_string_u64(scratch.arena, label_map, e->label, srl->total_size);
|
||||||
} break;
|
} break;
|
||||||
default: { InvalidPath; } break;
|
default: { InvalidPath; } break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// finalize expression
|
||||||
String8 expr = str8_serial_end(arena, srl);
|
String8 expr = str8_serial_end(arena, srl);
|
||||||
|
|
||||||
|
// apply fixups
|
||||||
|
for EachNode(fixup, struct Fixup, first_fixup) {
|
||||||
|
U64 label_offset;
|
||||||
|
if (!hash_table_search_string_u64(label_map, fixup->label, &label_offset)) {
|
||||||
|
Assert(0 && "undefined label");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
S64 delta = (S64)label_offset - (S64)fixup->offset;
|
||||||
|
AssertAlways(min_S16 <= delta && delta <= max_S16);
|
||||||
|
|
||||||
|
S16 *delta_ptr = (S16 *)(expr.str + fixup->offset);
|
||||||
|
*delta_ptr = delta;
|
||||||
|
}
|
||||||
|
|
||||||
scratch_end(scratch);
|
scratch_end(scratch);
|
||||||
return expr;
|
return expr;
|
||||||
}
|
}
|
||||||
|
|||||||
+33
-33
@@ -7,14 +7,6 @@
|
|||||||
////////////////////////////////
|
////////////////////////////////
|
||||||
// evaluator
|
// evaluator
|
||||||
|
|
||||||
typedef struct DW_ExprContext
|
|
||||||
{
|
|
||||||
Arch arch;
|
|
||||||
DW_Format format;
|
|
||||||
U64 cfa;
|
|
||||||
U64 tls_base;
|
|
||||||
} DW_ExprContext;
|
|
||||||
|
|
||||||
#define DW_ExprValueType_IsSigned(x) ((x) == DW_ExprValueType_S8 || (x) == DW_ExprValueType_S16 || (x) == DW_ExprValueType_S32 || (x) == DW_ExprValueType_S64 || (x) == DW_ExprValueType_S128 || (x) == DW_ExprValueType_S256 || (x) == DW_ExprValueType_S512)
|
#define DW_ExprValueType_IsSigned(x) ((x) == DW_ExprValueType_S8 || (x) == DW_ExprValueType_S16 || (x) == DW_ExprValueType_S32 || (x) == DW_ExprValueType_S64 || (x) == DW_ExprValueType_S128 || (x) == DW_ExprValueType_S256 || (x) == DW_ExprValueType_S512)
|
||||||
#define DW_ExprValueType_IsUnsigned(x) ((x) == DW_ExprValueType_U8 || (x) == DW_ExprValueType_U16 || (x) == DW_ExprValueType_U32 || (x) == DW_ExprValueType_U64 || (x) == DW_ExprValueType_U128 || (x) == DW_ExprValueType_U256 || (x) == DW_ExprValueType_U512)
|
#define DW_ExprValueType_IsUnsigned(x) ((x) == DW_ExprValueType_U8 || (x) == DW_ExprValueType_U16 || (x) == DW_ExprValueType_U32 || (x) == DW_ExprValueType_U64 || (x) == DW_ExprValueType_U128 || (x) == DW_ExprValueType_U256 || (x) == DW_ExprValueType_U512)
|
||||||
#define DW_ExprValueType_IsFloat(x) ((x) == DW_ExprValueType_F32 || (x) == DW_ExprValueType_F64)
|
#define DW_ExprValueType_IsFloat(x) ((x) == DW_ExprValueType_F32 || (x) == DW_ExprValueType_F64)
|
||||||
@@ -75,12 +67,6 @@ typedef struct DW_ExprValueNode
|
|||||||
struct DW_ExprValueNode *next;
|
struct DW_ExprValueNode *next;
|
||||||
} DW_ExprValueNode;
|
} DW_ExprValueNode;
|
||||||
|
|
||||||
typedef struct DW_ExprStack
|
|
||||||
{
|
|
||||||
U64 count;
|
|
||||||
DW_ExprValueNode *top;
|
|
||||||
} DW_ExprStack;
|
|
||||||
|
|
||||||
typedef enum
|
typedef enum
|
||||||
{
|
{
|
||||||
DW_PieceKind_Null,
|
DW_PieceKind_Null,
|
||||||
@@ -113,11 +99,25 @@ typedef struct DW_PieceList
|
|||||||
DW_PieceNode *last;
|
DW_PieceNode *last;
|
||||||
} DW_PieceList;
|
} DW_PieceList;
|
||||||
|
|
||||||
|
typedef struct DW_ExprStack
|
||||||
|
{
|
||||||
|
U64 count;
|
||||||
|
DW_ExprValueNode *top;
|
||||||
|
} DW_ExprStack;
|
||||||
|
|
||||||
typedef struct DW_ExprResult
|
typedef struct DW_ExprResult
|
||||||
{
|
{
|
||||||
int x;
|
int x;
|
||||||
} DW_ExprResult;
|
} DW_ExprResult;
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
DW_ExprEvalResult_Fail,
|
||||||
|
DW_ExprEvalResult_Ok,
|
||||||
|
DW_ExprEvalResult_Maybe,
|
||||||
|
DW_ExprEvalResult_ExecOpLimitReached,
|
||||||
|
} DW_ExprEvalResult;
|
||||||
|
|
||||||
////////////////////////////////
|
////////////////////////////////
|
||||||
// encoder
|
// encoder
|
||||||
|
|
||||||
@@ -157,26 +157,26 @@ typedef struct DW_ExprEnc
|
|||||||
S64 s64;
|
S64 s64;
|
||||||
U64 addr;
|
U64 addr;
|
||||||
String8 block;
|
String8 block;
|
||||||
char *label;
|
String8 label;
|
||||||
};
|
};
|
||||||
} DW_ExprEnc;
|
} DW_ExprEnc;
|
||||||
|
|
||||||
#define DW_ExprEnc_Op(v) { .type = DW_ExprEncType_Op, .op = DW_ExprOp_##v }
|
#define DW_ExprEnc_Op(v) { .type = DW_ExprEncType_Op, .op = DW_ExprOp_##v }
|
||||||
#define DW_ExprEnc_U8(v) { .type = DW_ExprEncType_U8, .u8 = v }
|
#define DW_ExprEnc_U8(v) { .type = DW_ExprEncType_U8, .u8 = v }
|
||||||
#define DW_ExprEnc_U16(v) { .type = DW_ExprEncType_U16, .u16 = v }
|
#define DW_ExprEnc_U16(v) { .type = DW_ExprEncType_U16, .u16 = v }
|
||||||
#define DW_ExprEnc_U32(v) { .type = DW_ExprEncType_U32, .u32 = v }
|
#define DW_ExprEnc_U32(v) { .type = DW_ExprEncType_U32, .u32 = v }
|
||||||
#define DW_ExprEnc_U64(v) { .type = DW_ExprEncType_U64, .u64 = v }
|
#define DW_ExprEnc_U64(v) { .type = DW_ExprEncType_U64, .u64 = v }
|
||||||
#define DW_ExprEnc_S8(v) { .type = DW_ExprEncType_S8, .s8 = v }
|
#define DW_ExprEnc_S8(v) { .type = DW_ExprEncType_S8, .s8 = v }
|
||||||
#define DW_ExprEnc_S16(v) { .type = DW_ExprEncType_S16, .s16 = v }
|
#define DW_ExprEnc_S16(v) { .type = DW_ExprEncType_S16, .s16 = v }
|
||||||
#define DW_ExprEnc_S32(v) { .type = DW_ExprEncType_S32, .s32 = v }
|
#define DW_ExprEnc_S32(v) { .type = DW_ExprEncType_S32, .s32 = v }
|
||||||
#define DW_ExprEnc_S64(v) { .type = DW_ExprEncType_S64, .s64 = v }
|
#define DW_ExprEnc_S64(v) { .type = DW_ExprEncType_S64, .s64 = v }
|
||||||
#define DW_ExprEnc_ULEB128(v) { .type = DW_ExprEncType_ULEB128, .u64 = v }
|
#define DW_ExprEnc_ULEB128(v) { .type = DW_ExprEncType_ULEB128, .u64 = v }
|
||||||
#define DW_ExprEnc_SLEB128(v) { .type = DW_ExprEncType_SLEB128, .s64 = v }
|
#define DW_ExprEnc_SLEB128(v) { .type = DW_ExprEncType_SLEB128, .s64 = v }
|
||||||
#define DW_ExprEnc_Addr(v) { .type = DW_ExprEncType_Addr, .addr = v }
|
#define DW_ExprEnc_Addr(v) { .type = DW_ExprEncType_Addr, .addr = v }
|
||||||
#define DW_ExprEnc_Block(v) { .type = DW_ExprEncType_Block, .block = v }
|
#define DW_ExprEnc_Block(v) { .type = DW_ExprEncType_Block, .block = v }
|
||||||
#define DW_ExprEnc_UInt(v) { .type = DW_ExprEncType_DwarfUInt, .u64 = v }
|
#define DW_ExprEnc_UInt(v) { .type = DW_ExprEncType_DwarfUInt, .u64 = v }
|
||||||
#define DW_ExprEnc_Label(v) { .type = DW_ExprEncType_Label, .label = v }
|
#define DW_ExprEnc_Label(v) { .type = DW_ExprEncType_Label, .label = str8_lit_comp(v) }
|
||||||
#define DW_ExprEnc_DeclLabel(v) { .type = DW_ExprEncType_DeclLabel, .label = v }
|
#define DW_ExprEnc_DeclLabel(v) { .type = DW_ExprEncType_DeclLabel, .label = str8_lit_comp(v) }
|
||||||
|
|
||||||
////////////////////////////////
|
////////////////////////////////
|
||||||
|
|
||||||
@@ -235,10 +235,10 @@ internal DW_ExprValueNode * dw_expr_stack_pick(DW_ExprStack *stack, U64 idx);
|
|||||||
internal String8 dw_string_from_expr_value(Arena *arena, U64 addr_size, DW_ExprValue v);
|
internal String8 dw_string_from_expr_value(Arena *arena, U64 addr_size, DW_ExprValue v);
|
||||||
|
|
||||||
// evaluator
|
// evaluator
|
||||||
internal DW_UnwindStatus dw_eval_expr(Arena *arena, DW_ExprContext *ctx, DW_Expr expr, DW_RegRead *reg_read, void *reg_read_ud, DW_ExprValue *value_out);
|
internal DW_ExprEvalResult dw_eval_expr(Arena *arena, Arch arch, DW_Format format, U64 cfa, U64 tls_base, U64 op_limit, DW_Expr expr, MachineOp_RegRead *reg_read, void *reg_read_ud, DW_ExprValue *value_out);
|
||||||
|
|
||||||
// encoder
|
// encoder
|
||||||
internal String8 dw_encode_expr(Arena *arena, DW_Format format, U64 addr_size, DW_ExprEnc *encs, U64 encs_count);
|
internal String8 dw_encode_expr(Arena *arena, Arch arch, DW_Format format, DW_ExprEnc *encs, U64 encs_count);
|
||||||
|
|
||||||
#endif //DWARF_EXPR_H
|
#endif //DWARF_EXPR_H
|
||||||
|
|
||||||
|
|||||||
@@ -176,7 +176,7 @@ dw_section_kind_from_string(String8 string)
|
|||||||
#define X(_K,_L,_M,_W) \
|
#define X(_K,_L,_M,_W) \
|
||||||
if (str8_match_lit(_L, string, 0)) { s = DW_Section_##_K; } \
|
if (str8_match_lit(_L, string, 0)) { s = DW_Section_##_K; } \
|
||||||
if (str8_match_lit(_M, string, 0)) { s = DW_Section_##_K; }
|
if (str8_match_lit(_M, string, 0)) { s = DW_Section_##_K; }
|
||||||
DW_SectionKind_XList(X)
|
DW_SectionKind_XList
|
||||||
#undef X
|
#undef X
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
@@ -187,7 +187,7 @@ dw_section_dwo_kind_from_string(String8 string)
|
|||||||
DW_SectionKind s = DW_Section_Null;
|
DW_SectionKind s = DW_Section_Null;
|
||||||
#define X(_K,_L,_M,_W) \
|
#define X(_K,_L,_M,_W) \
|
||||||
if (str8_match_lit(_W, string, 0)) { s = DW_Section_##_K; }
|
if (str8_match_lit(_W, string, 0)) { s = DW_Section_##_K; }
|
||||||
DW_SectionKind_XList(X)
|
DW_SectionKind_XList
|
||||||
#undef X
|
#undef X
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -73,7 +73,7 @@ d2r_rdi_reg_code_from_dw_reg_x64(DW_RegX64 v)
|
|||||||
{
|
{
|
||||||
default:{}break;
|
default:{}break;
|
||||||
#define X(reg_dw, val_dw, reg_rdi, off, size) case DW_RegX64_##reg_dw:{result = RDI_RegCodeX64_##reg_rdi;}break;
|
#define X(reg_dw, val_dw, reg_rdi, off, size) case DW_RegX64_##reg_dw:{result = RDI_RegCodeX64_##reg_rdi;}break;
|
||||||
DW_Regs_X64_XList(X)
|
DW_Regs_X64_XList
|
||||||
#undef X
|
#undef X
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
|
|||||||
Reference in New Issue
Block a user