mirror of
https://github.com/Ed94/raddebugger.git
synced 2026-08-14 09:18:09 +00:00
WIP DWARF expression encoder
This commit is contained in:
@@ -145,6 +145,7 @@ if "%mule_main%"=="1" set didbuild=1 && del vc*.pdb mule*.pdb &
|
||||
if "%mule_module%"=="1" set didbuild=1 && %compile% ..\src\mule\mule_module.cpp %compile_link% %link_dll% %out%mule_module.dll || exit /b 1
|
||||
if "%mule_hotload%"=="1" set didbuild=1 && %compile% ..\src\mule\mule_hotload_main.c %compile_link% %out%mule_hotload.exe & %compile% ..\src\mule\mule_hotload_module_main.c %compile_link% %link_dll% %out%mule_hotload_module.dll || exit /b 1
|
||||
if "%torture%"=="1" set didbuild=1 && %compile% ..\src\torture\torture.c %compile_link% %out%torture.exe || exit /b1
|
||||
if "%dwarf_expr_test%"=="1" set didbuild=1 && %compile% ..\src\torture\dwarf_expr_test.c %compile_link% %out%dwarf_expr_test.exe || exit /b1
|
||||
if "%mule_peb_trample%"=="1" (
|
||||
set didbuild=1
|
||||
if exist mule_peb_trample.exe move mule_peb_trample.exe mule_peb_trample_old_%random%.exe
|
||||
|
||||
+33
-19
@@ -400,11 +400,11 @@ internal U64
|
||||
dw_operand_count_from_expr_op(DW_ExprOp op)
|
||||
{
|
||||
switch (op) {
|
||||
#define X(_N, _ID, _OPER_COUNT, _POP_COUNT, _PUSH_COUNT) case _ID: return _OPER_COUNT;
|
||||
DW_Expr_V3_XList(X)
|
||||
DW_Expr_V4_XList(X)
|
||||
DW_Expr_V5_XList(X)
|
||||
DW_Expr_GNU_XList(X)
|
||||
#define X(_N, _ID, _OPER_COUNT, _POP_COUNT, _PUSH_COUNT, ...) case _ID: return _OPER_COUNT;
|
||||
DW_Expr_V3_XList
|
||||
DW_Expr_V4_XList
|
||||
DW_Expr_V5_XList
|
||||
DW_Expr_GNU_XList
|
||||
#undef X
|
||||
default: { NotImplemented; } break;
|
||||
}
|
||||
@@ -415,11 +415,11 @@ internal U64
|
||||
dw_pop_count_from_expr_op(DW_ExprOp op)
|
||||
{
|
||||
switch (op) {
|
||||
#define X(_N, _ID, _OPER_COUNT, _POP_COUNT, _PUSH_COUNT) case _ID: return _POP_COUNT;
|
||||
DW_Expr_V3_XList(X)
|
||||
DW_Expr_V4_XList(X)
|
||||
DW_Expr_V5_XList(X)
|
||||
DW_Expr_GNU_XList(X)
|
||||
#define X(_N, _ID, _OPER_COUNT, _POP_COUNT, _PUSH_COUNT, ...) case _ID: return _POP_COUNT;
|
||||
DW_Expr_V3_XList
|
||||
DW_Expr_V4_XList
|
||||
DW_Expr_V5_XList
|
||||
DW_Expr_GNU_XList
|
||||
#undef X
|
||||
default: { NotImplemented; } break;
|
||||
}
|
||||
@@ -430,11 +430,25 @@ internal U64
|
||||
dw_push_count_from_expr_op(DW_ExprOp op)
|
||||
{
|
||||
switch (op) {
|
||||
#define X(_N, _ID, _OPER_COUNT, _POP_COUNT, _PUSH_COUNT) case _ID: return _PUSH_COUNT;
|
||||
DW_Expr_V3_XList(X)
|
||||
DW_Expr_V4_XList(X)
|
||||
DW_Expr_V5_XList(X)
|
||||
DW_Expr_GNU_XList(X)
|
||||
#define X(_N, _ID, _OPER_COUNT, _POP_COUNT, _PUSH_COUNT, ...) case _ID: return _PUSH_COUNT;
|
||||
DW_Expr_V3_XList
|
||||
DW_Expr_V4_XList
|
||||
DW_Expr_V5_XList
|
||||
DW_Expr_GNU_XList
|
||||
#undef X
|
||||
default: { NotImplemented; } break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
internal DW_ExprOperandType *
|
||||
dw_operand_types_from_expr_opcode(DW_ExprOp op)
|
||||
{
|
||||
#define X(_N, _ID, _OPER_COUNT, _POP_COUNT, _PUSH_COUNT, _OPER_TYPE0, _OPER_TYPE1) case _ID: { local_persist DW_ExprOperandType t[] = { DW_ExprOperandType_##_OPER_TYPE0, DW_ExprOperandType_##_OPER_TYPE1 }; return t; }
|
||||
switch (op) {
|
||||
DW_Expr_V3_XList
|
||||
DW_Expr_V4_XList
|
||||
DW_Expr_V5_XList
|
||||
#undef X
|
||||
default: { NotImplemented; } break;
|
||||
}
|
||||
@@ -528,26 +542,26 @@ dw_string_from_expr_op(Arena *arena, DW_Version ver, DW_Ext ext, DW_ExprOp op)
|
||||
#define X(_N,...) case DW_ExprOp_##_N: result = str8_lit(Stringify(_N)); goto exit;
|
||||
if (ext & DW_Ext_GNU) {
|
||||
switch (op) {
|
||||
DW_Expr_GNU_XList(X);
|
||||
DW_Expr_GNU_XList;
|
||||
}
|
||||
}
|
||||
|
||||
switch (ver) {
|
||||
case DW_Version_5: {
|
||||
switch (op) {
|
||||
DW_Expr_V5_XList(X)
|
||||
DW_Expr_V5_XList
|
||||
}
|
||||
} // fall-through
|
||||
case DW_Version_4: {
|
||||
switch (op) {
|
||||
DW_Expr_V4_XList(X)
|
||||
DW_Expr_V4_XList
|
||||
}
|
||||
} // fall-through
|
||||
case DW_Version_3:
|
||||
case DW_Version_2:
|
||||
case DW_Version_1: {
|
||||
switch (op) {
|
||||
DW_Expr_V3_XList(X)
|
||||
DW_Expr_V3_XList
|
||||
}
|
||||
} // fall-through
|
||||
case DW_Version_Null:
|
||||
|
||||
+208
-189
@@ -1392,199 +1392,217 @@ typedef enum DW_CFA_Enum
|
||||
////////////////////////////////
|
||||
// Expression Opcodes
|
||||
|
||||
// (opcode name, opcode id, operand count, pop count, push count)
|
||||
#define DW_Expr_V3_XList(X) \
|
||||
X(Null, 0x00, 0, 0, 0) \
|
||||
X(Addr, 0x03, 1, 0, 1) \
|
||||
X(Deref, 0x06, 0, 1, 1) \
|
||||
X(Const1U, 0x08, 1, 0, 1) \
|
||||
X(Const1S, 0x09, 1, 0, 1) \
|
||||
X(Const2U, 0x0a, 1, 0, 1) \
|
||||
X(Const2S, 0x0b, 1, 0, 1) \
|
||||
X(Const4U, 0x0c, 1, 0, 1) \
|
||||
X(Const4S, 0x0d, 1, 0, 1) \
|
||||
X(Const8U, 0x0e, 1, 0, 1) \
|
||||
X(Const8S, 0x0f, 1, 0, 1) \
|
||||
X(ConstU, 0x10, 1, 0, 1) \
|
||||
X(ConstS, 0x11, 1, 0, 1) \
|
||||
X(Dup, 0x12, 0, 0, 1) \
|
||||
X(Drop, 0x13, 0, 1, 0) \
|
||||
X(Over, 0x14, 0, 0, 1) \
|
||||
X(Pick, 0x15, 1, 0, 1) \
|
||||
X(Swap, 0x16, 0, 0, 0) \
|
||||
X(Rot, 0x17, 0, 0, 0) \
|
||||
X(XDeref, 0x18, 0, 2, 1) \
|
||||
X(Abs, 0x19, 0, 1, 1) \
|
||||
X(And, 0x1a, 0, 2, 1) \
|
||||
X(Div, 0x1b, 0, 2, 1) \
|
||||
X(Minus, 0x1c, 0, 2, 1) \
|
||||
X(Mod, 0x1d, 0, 2, 1) \
|
||||
X(Mul, 0x1e, 0, 2, 1) \
|
||||
X(Neg, 0x1f, 0, 1, 1) \
|
||||
X(Not, 0x20, 0, 1, 1) \
|
||||
X(Or, 0x21, 0, 2, 1) \
|
||||
X(Plus, 0x22, 0, 2, 1) \
|
||||
X(PlusUConst, 0x23, 1, 1, 1) \
|
||||
X(Shl, 0x24, 0, 2, 1) \
|
||||
X(Shr, 0x25, 0, 2, 1) \
|
||||
X(Shra, 0x26, 0, 2, 1) \
|
||||
X(Xor, 0x27, 0, 2, 1) \
|
||||
X(Bra, 0x28, 1, 1, 0) \
|
||||
X(Eq, 0x29, 0, 2, 1) \
|
||||
X(Ge, 0x2a, 0, 2, 1) \
|
||||
X(Gt, 0x2b, 0, 2, 1) \
|
||||
X(Le, 0x2c, 0, 2, 1) \
|
||||
X(Lt, 0x2d, 0, 2, 1) \
|
||||
X(Ne, 0x2e, 0, 2, 1) \
|
||||
X(Skip, 0x2f, 1, 0, 0) \
|
||||
X(Lit0, 0x30, 0, 0, 0) \
|
||||
X(Lit1, 0x31, 0, 0, 0) \
|
||||
X(Lit2, 0x32, 0, 0, 0) \
|
||||
X(Lit3, 0x33, 0, 0, 0) \
|
||||
X(Lit4, 0x34, 0, 0, 0) \
|
||||
X(Lit5, 0x35, 0, 0, 0) \
|
||||
X(Lit6, 0x36, 0, 0, 0) \
|
||||
X(Lit7, 0x37, 0, 0, 0) \
|
||||
X(Lit8, 0x38, 0, 0, 0) \
|
||||
X(Lit9, 0x39, 0, 0, 0) \
|
||||
X(Lit10, 0x3a, 0, 0, 0) \
|
||||
X(Lit11, 0x3b, 0, 0, 0) \
|
||||
X(Lit12, 0x3c, 0, 0, 0) \
|
||||
X(Lit13, 0x3d, 0, 0, 0) \
|
||||
X(Lit14, 0x3e, 0, 0, 0) \
|
||||
X(Lit15, 0x3f, 0, 0, 0) \
|
||||
X(Lit16, 0x40, 0, 0, 0) \
|
||||
X(Lit17, 0x41, 0, 0, 0) \
|
||||
X(Lit18, 0x42, 0, 0, 0) \
|
||||
X(Lit19, 0x43, 0, 0, 0) \
|
||||
X(Lit20, 0x44, 0, 0, 0) \
|
||||
X(Lit21, 0x45, 0, 0, 0) \
|
||||
X(Lit22, 0x46, 0, 0, 0) \
|
||||
X(Lit23, 0x47, 0, 0, 0) \
|
||||
X(Lit24, 0x48, 0, 0, 0) \
|
||||
X(Lit25, 0x49, 0, 0, 0) \
|
||||
X(Lit26, 0x4a, 0, 0, 0) \
|
||||
X(Lit27, 0x4b, 0, 0, 0) \
|
||||
X(Lit28, 0x4c, 0, 0, 0) \
|
||||
X(Lit29, 0x4d, 0, 0, 0) \
|
||||
X(Lit30, 0x4e, 0, 0, 0) \
|
||||
X(Lit31, 0x4f, 0, 0, 0) \
|
||||
X(Reg0, 0x50, 0, 0, 1) \
|
||||
X(Reg1, 0x51, 0, 0, 1) \
|
||||
X(Reg2, 0x52, 0, 0, 1) \
|
||||
X(Reg3, 0x53, 0, 0, 1) \
|
||||
X(Reg4, 0x54, 0, 0, 1) \
|
||||
X(Reg5, 0x55, 0, 0, 1) \
|
||||
X(Reg6, 0x56, 0, 0, 1) \
|
||||
X(Reg7, 0x57, 0, 0, 1) \
|
||||
X(Reg8, 0x58, 0, 0, 1) \
|
||||
X(Reg9, 0x59, 0, 0, 1) \
|
||||
X(Reg10, 0x5a, 0, 0, 1) \
|
||||
X(Reg11, 0x5b, 0, 0, 1) \
|
||||
X(Reg12, 0x5c, 0, 0, 1) \
|
||||
X(Reg13, 0x5d, 0, 0, 1) \
|
||||
X(Reg14, 0x5e, 0, 0, 1) \
|
||||
X(Reg15, 0x5f, 0, 0, 1) \
|
||||
X(Reg16, 0x60, 0, 0, 1) \
|
||||
X(Reg17, 0x61, 0, 0, 1) \
|
||||
X(Reg18, 0x62, 0, 0, 1) \
|
||||
X(Reg19, 0x63, 0, 0, 1) \
|
||||
X(Reg20, 0x64, 0, 0, 1) \
|
||||
X(Reg21, 0x65, 0, 0, 1) \
|
||||
X(Reg22, 0x66, 0, 0, 1) \
|
||||
X(Reg23, 0x67, 0, 0, 1) \
|
||||
X(Reg24, 0x68, 0, 0, 1) \
|
||||
X(Reg25, 0x69, 0, 0, 1) \
|
||||
X(Reg26, 0x6a, 0, 0, 1) \
|
||||
X(Reg27, 0x6b, 0, 0, 1) \
|
||||
X(Reg28, 0x6c, 0, 0, 1) \
|
||||
X(Reg29, 0x6d, 0, 0, 1) \
|
||||
X(Reg30, 0x6e, 0, 0, 1) \
|
||||
X(Reg31, 0x6f, 0, 0, 1) \
|
||||
X(BReg0, 0x70, 1, 0, 1) \
|
||||
X(BReg1, 0x71, 1, 0, 1) \
|
||||
X(BReg2, 0x72, 1, 0, 1) \
|
||||
X(BReg3, 0x73, 1, 0, 1) \
|
||||
X(BReg4, 0x74, 1, 0, 1) \
|
||||
X(BReg5, 0x75, 1, 0, 1) \
|
||||
X(BReg6, 0x76, 1, 0, 1) \
|
||||
X(BReg7, 0x77, 1, 0, 1) \
|
||||
X(BReg8, 0x78, 1, 0, 1) \
|
||||
X(BReg9, 0x79, 1, 0, 1) \
|
||||
X(BReg10, 0x7a, 1, 0, 1) \
|
||||
X(BReg11, 0x7b, 1, 0, 1) \
|
||||
X(BReg12, 0x7c, 1, 0, 1) \
|
||||
X(BReg13, 0x7d, 1, 0, 1) \
|
||||
X(BReg14, 0x7e, 1, 0, 1) \
|
||||
X(BReg15, 0x7f, 1, 0, 1) \
|
||||
X(BReg16, 0x80, 1, 0, 1) \
|
||||
X(BReg17, 0x81, 1, 0, 1) \
|
||||
X(BReg18, 0x82, 1, 0, 1) \
|
||||
X(BReg19, 0x83, 1, 0, 1) \
|
||||
X(BReg20, 0x84, 1, 0, 1) \
|
||||
X(BReg21, 0x85, 1, 0, 1) \
|
||||
X(BReg22, 0x86, 1, 0, 1) \
|
||||
X(BReg23, 0x87, 1, 0, 1) \
|
||||
X(BReg24, 0x88, 1, 0, 1) \
|
||||
X(BReg25, 0x89, 1, 0, 1) \
|
||||
X(BReg26, 0x8a, 1, 0, 1) \
|
||||
X(BReg27, 0x8b, 1, 0, 1) \
|
||||
X(BReg28, 0x8c, 1, 0, 1) \
|
||||
X(BReg29, 0x8d, 1, 0, 1) \
|
||||
X(BReg30, 0x8e, 1, 0, 1) \
|
||||
X(BReg31, 0x8f, 1, 0, 1) \
|
||||
X(RegX, 0x90, 1, 0, 1) \
|
||||
X(FBReg, 0x91, 1, 0, 1) \
|
||||
X(BRegX, 0x92, 2, 0, 1) \
|
||||
X(Piece, 0x93, 1, 0, 0) \
|
||||
X(DerefSize, 0x94, 1, 1, 1) \
|
||||
X(XDerefSize, 0x95, 1, 2, 1) \
|
||||
X(Nop, 0x96, 0, 0, 0) \
|
||||
X(PushObjectAddress, 0x97, 0, 0, 1) \
|
||||
X(Call2, 0x98, 1, 0, 0) \
|
||||
X(Call4, 0x99, 1, 0, 0) \
|
||||
X(CallRef, 0x9a, 1, 0, 0) \
|
||||
X(FormTlsAddress, 0x9b, 0, 0, 1) \
|
||||
X(CallFrameCfa, 0x9c, 0, 0, 1) \
|
||||
X(BitPiece, 0x9d, 2, 0, 0)
|
||||
typedef enum
|
||||
{
|
||||
DW_ExprOperandType_Null,
|
||||
DW_ExprOperandType_U8,
|
||||
DW_ExprOperandType_U16,
|
||||
DW_ExprOperandType_U32,
|
||||
DW_ExprOperandType_U64,
|
||||
DW_ExprOperandType_S8,
|
||||
DW_ExprOperandType_S16,
|
||||
DW_ExprOperandType_S32,
|
||||
DW_ExprOperandType_S64,
|
||||
DW_ExprOperandType_ULEB128,
|
||||
DW_ExprOperandType_SLEB128,
|
||||
DW_ExprOperandType_Addr,
|
||||
DW_ExprOperandType_Block,
|
||||
DW_ExprOperandType_DwarfUInt,
|
||||
} DW_ExprOperandType;
|
||||
|
||||
#define DW_Expr_V4_XList(X) \
|
||||
X(ImplicitValue, 0x9e, 2, 0, 1) \
|
||||
X(StackValue, 0x9f, 0, 0, 0)
|
||||
// (opcode name, opcode id, operand count, pop count, push count, operand0 type, operand1 type)
|
||||
#define DW_Expr_V3_XList \
|
||||
X(Null, 0x00, 0, 0, 0, Null, Null) \
|
||||
X(Addr, 0x03, 1, 0, 1, Addr, Null) \
|
||||
X(Deref, 0x06, 0, 1, 1, Null, Null) \
|
||||
X(Const1U, 0x08, 1, 0, 1, U8, Null) \
|
||||
X(Const1S, 0x09, 1, 0, 1, S8, Null) \
|
||||
X(Const2U, 0x0a, 1, 0, 1, U16, Null) \
|
||||
X(Const2S, 0x0b, 1, 0, 1, S16, Null) \
|
||||
X(Const4U, 0x0c, 1, 0, 1, U32, Null) \
|
||||
X(Const4S, 0x0d, 1, 0, 1, S32, Null) \
|
||||
X(Const8U, 0x0e, 1, 0, 1, U64, Null) \
|
||||
X(Const8S, 0x0f, 1, 0, 1, S64, Null) \
|
||||
X(ConstU, 0x10, 1, 0, 1, ULEB128, Null) \
|
||||
X(ConstS, 0x11, 1, 0, 1, SLEB128, Null) \
|
||||
X(Dup, 0x12, 0, 0, 1, Null, Null) \
|
||||
X(Drop, 0x13, 0, 1, 0, Null, Null) \
|
||||
X(Over, 0x14, 0, 0, 1, Null, Null) \
|
||||
X(Pick, 0x15, 1, 0, 1, U8, Null) \
|
||||
X(Swap, 0x16, 0, 0, 0, Null, Null) \
|
||||
X(Rot, 0x17, 0, 0, 0, Null, Null) \
|
||||
X(XDeref, 0x18, 0, 2, 1, Null, Null) \
|
||||
X(Abs, 0x19, 0, 1, 1, Null, Null) \
|
||||
X(And, 0x1a, 0, 2, 1, Null, Null) \
|
||||
X(Div, 0x1b, 0, 2, 1, Null, Null) \
|
||||
X(Minus, 0x1c, 0, 2, 1, Null, Null) \
|
||||
X(Mod, 0x1d, 0, 2, 1, Null, Null) \
|
||||
X(Mul, 0x1e, 0, 2, 1, Null, Null) \
|
||||
X(Neg, 0x1f, 0, 1, 1, Null, Null) \
|
||||
X(Not, 0x20, 0, 1, 1, Null, Null) \
|
||||
X(Or, 0x21, 0, 2, 1, Null, Null) \
|
||||
X(Plus, 0x22, 0, 2, 1, Null, Null) \
|
||||
X(PlusUConst, 0x23, 1, 1, 1, ULEB128, Null) \
|
||||
X(Shl, 0x24, 0, 2, 1, Null, Null) \
|
||||
X(Shr, 0x25, 0, 2, 1, Null, Null) \
|
||||
X(Shra, 0x26, 0, 2, 1, Null, Null) \
|
||||
X(Xor, 0x27, 0, 2, 1, Null, Null) \
|
||||
X(Bra, 0x28, 1, 1, 0, S16, Null) \
|
||||
X(Eq, 0x29, 0, 2, 1, Null, Null) \
|
||||
X(Ge, 0x2a, 0, 2, 1, Null, Null) \
|
||||
X(Gt, 0x2b, 0, 2, 1, Null, Null) \
|
||||
X(Le, 0x2c, 0, 2, 1, Null, Null) \
|
||||
X(Lt, 0x2d, 0, 2, 1, Null, Null) \
|
||||
X(Ne, 0x2e, 0, 2, 1, Null, Null) \
|
||||
X(Skip, 0x2f, 1, 0, 0, S16, Null) \
|
||||
X(Lit0, 0x30, 0, 0, 0, Null, Null) \
|
||||
X(Lit1, 0x31, 0, 0, 0, Null, Null) \
|
||||
X(Lit2, 0x32, 0, 0, 0, Null, Null) \
|
||||
X(Lit3, 0x33, 0, 0, 0, Null, Null) \
|
||||
X(Lit4, 0x34, 0, 0, 0, Null, Null) \
|
||||
X(Lit5, 0x35, 0, 0, 0, Null, Null) \
|
||||
X(Lit6, 0x36, 0, 0, 0, Null, Null) \
|
||||
X(Lit7, 0x37, 0, 0, 0, Null, Null) \
|
||||
X(Lit8, 0x38, 0, 0, 0, Null, Null) \
|
||||
X(Lit9, 0x39, 0, 0, 0, Null, Null) \
|
||||
X(Lit10, 0x3a, 0, 0, 0, Null, Null) \
|
||||
X(Lit11, 0x3b, 0, 0, 0, Null, Null) \
|
||||
X(Lit12, 0x3c, 0, 0, 0, Null, Null) \
|
||||
X(Lit13, 0x3d, 0, 0, 0, Null, Null) \
|
||||
X(Lit14, 0x3e, 0, 0, 0, Null, Null) \
|
||||
X(Lit15, 0x3f, 0, 0, 0, Null, Null) \
|
||||
X(Lit16, 0x40, 0, 0, 0, Null, Null) \
|
||||
X(Lit17, 0x41, 0, 0, 0, Null, Null) \
|
||||
X(Lit18, 0x42, 0, 0, 0, Null, Null) \
|
||||
X(Lit19, 0x43, 0, 0, 0, Null, Null) \
|
||||
X(Lit20, 0x44, 0, 0, 0, Null, Null) \
|
||||
X(Lit21, 0x45, 0, 0, 0, Null, Null) \
|
||||
X(Lit22, 0x46, 0, 0, 0, Null, Null) \
|
||||
X(Lit23, 0x47, 0, 0, 0, Null, Null) \
|
||||
X(Lit24, 0x48, 0, 0, 0, Null, Null) \
|
||||
X(Lit25, 0x49, 0, 0, 0, Null, Null) \
|
||||
X(Lit26, 0x4a, 0, 0, 0, Null, Null) \
|
||||
X(Lit27, 0x4b, 0, 0, 0, Null, Null) \
|
||||
X(Lit28, 0x4c, 0, 0, 0, Null, Null) \
|
||||
X(Lit29, 0x4d, 0, 0, 0, Null, Null) \
|
||||
X(Lit30, 0x4e, 0, 0, 0, Null, Null) \
|
||||
X(Lit31, 0x4f, 0, 0, 0, Null, Null) \
|
||||
X(Reg0, 0x50, 0, 0, 1, Null, Null) \
|
||||
X(Reg1, 0x51, 0, 0, 1, Null, Null) \
|
||||
X(Reg2, 0x52, 0, 0, 1, Null, Null) \
|
||||
X(Reg3, 0x53, 0, 0, 1, Null, Null) \
|
||||
X(Reg4, 0x54, 0, 0, 1, Null, Null) \
|
||||
X(Reg5, 0x55, 0, 0, 1, Null, Null) \
|
||||
X(Reg6, 0x56, 0, 0, 1, Null, Null) \
|
||||
X(Reg7, 0x57, 0, 0, 1, Null, Null) \
|
||||
X(Reg8, 0x58, 0, 0, 1, Null, Null) \
|
||||
X(Reg9, 0x59, 0, 0, 1, Null, Null) \
|
||||
X(Reg10, 0x5a, 0, 0, 1, Null, Null) \
|
||||
X(Reg11, 0x5b, 0, 0, 1, Null, Null) \
|
||||
X(Reg12, 0x5c, 0, 0, 1, Null, Null) \
|
||||
X(Reg13, 0x5d, 0, 0, 1, Null, Null) \
|
||||
X(Reg14, 0x5e, 0, 0, 1, Null, Null) \
|
||||
X(Reg15, 0x5f, 0, 0, 1, Null, Null) \
|
||||
X(Reg16, 0x60, 0, 0, 1, Null, Null) \
|
||||
X(Reg17, 0x61, 0, 0, 1, Null, Null) \
|
||||
X(Reg18, 0x62, 0, 0, 1, Null, Null) \
|
||||
X(Reg19, 0x63, 0, 0, 1, Null, Null) \
|
||||
X(Reg20, 0x64, 0, 0, 1, Null, Null) \
|
||||
X(Reg21, 0x65, 0, 0, 1, Null, Null) \
|
||||
X(Reg22, 0x66, 0, 0, 1, Null, Null) \
|
||||
X(Reg23, 0x67, 0, 0, 1, Null, Null) \
|
||||
X(Reg24, 0x68, 0, 0, 1, Null, Null) \
|
||||
X(Reg25, 0x69, 0, 0, 1, Null, Null) \
|
||||
X(Reg26, 0x6a, 0, 0, 1, Null, Null) \
|
||||
X(Reg27, 0x6b, 0, 0, 1, Null, Null) \
|
||||
X(Reg28, 0x6c, 0, 0, 1, Null, Null) \
|
||||
X(Reg29, 0x6d, 0, 0, 1, Null, Null) \
|
||||
X(Reg30, 0x6e, 0, 0, 1, Null, Null) \
|
||||
X(Reg31, 0x6f, 0, 0, 1, Null, Null) \
|
||||
X(BReg0, 0x70, 1, 0, 1, SLEB128, Null) \
|
||||
X(BReg1, 0x71, 1, 0, 1, SLEB128, Null) \
|
||||
X(BReg2, 0x72, 1, 0, 1, SLEB128, Null) \
|
||||
X(BReg3, 0x73, 1, 0, 1, SLEB128, Null) \
|
||||
X(BReg4, 0x74, 1, 0, 1, SLEB128, Null) \
|
||||
X(BReg5, 0x75, 1, 0, 1, SLEB128, Null) \
|
||||
X(BReg6, 0x76, 1, 0, 1, SLEB128, Null) \
|
||||
X(BReg7, 0x77, 1, 0, 1, SLEB128, Null) \
|
||||
X(BReg8, 0x78, 1, 0, 1, SLEB128, Null) \
|
||||
X(BReg9, 0x79, 1, 0, 1, SLEB128, Null) \
|
||||
X(BReg10, 0x7a, 1, 0, 1, SLEB128, Null) \
|
||||
X(BReg11, 0x7b, 1, 0, 1, SLEB128, Null) \
|
||||
X(BReg12, 0x7c, 1, 0, 1, SLEB128, Null) \
|
||||
X(BReg13, 0x7d, 1, 0, 1, SLEB128, Null) \
|
||||
X(BReg14, 0x7e, 1, 0, 1, SLEB128, Null) \
|
||||
X(BReg15, 0x7f, 1, 0, 1, SLEB128, Null) \
|
||||
X(BReg16, 0x80, 1, 0, 1, SLEB128, Null) \
|
||||
X(BReg17, 0x81, 1, 0, 1, SLEB128, Null) \
|
||||
X(BReg18, 0x82, 1, 0, 1, SLEB128, Null) \
|
||||
X(BReg19, 0x83, 1, 0, 1, SLEB128, Null) \
|
||||
X(BReg20, 0x84, 1, 0, 1, SLEB128, Null) \
|
||||
X(BReg21, 0x85, 1, 0, 1, SLEB128, Null) \
|
||||
X(BReg22, 0x86, 1, 0, 1, SLEB128, Null) \
|
||||
X(BReg23, 0x87, 1, 0, 1, SLEB128, Null) \
|
||||
X(BReg24, 0x88, 1, 0, 1, SLEB128, Null) \
|
||||
X(BReg25, 0x89, 1, 0, 1, SLEB128, Null) \
|
||||
X(BReg26, 0x8a, 1, 0, 1, SLEB128, Null) \
|
||||
X(BReg27, 0x8b, 1, 0, 1, SLEB128, Null) \
|
||||
X(BReg28, 0x8c, 1, 0, 1, SLEB128, Null) \
|
||||
X(BReg29, 0x8d, 1, 0, 1, SLEB128, Null) \
|
||||
X(BReg30, 0x8e, 1, 0, 1, SLEB128, Null) \
|
||||
X(BReg31, 0x8f, 1, 0, 1, SLEB128, Null) \
|
||||
X(RegX, 0x90, 1, 0, 1, ULEB128, Null) \
|
||||
X(FBReg, 0x91, 1, 0, 1, SLEB128, Null) \
|
||||
X(BRegX, 0x92, 2, 0, 1, ULEB128, SLEB128) \
|
||||
X(Piece, 0x93, 1, 0, 0, ULEB128, Null) \
|
||||
X(DerefSize, 0x94, 1, 1, 1, U8, Null) \
|
||||
X(XDerefSize, 0x95, 1, 2, 1, U8, Null) \
|
||||
X(Nop, 0x96, 0, 0, 0, Null, Null) \
|
||||
X(PushObjectAddress, 0x97, 0, 0, 1, Null, Null) \
|
||||
X(Call2, 0x98, 1, 0, 0, U16, Null) \
|
||||
X(Call4, 0x99, 1, 0, 0, U32, Null) \
|
||||
X(CallRef, 0x9a, 1, 0, 0, DwarfUInt,Null) \
|
||||
X(FormTlsAddress, 0x9b, 0, 0, 1, Null, Null) \
|
||||
X(CallFrameCfa, 0x9c, 0, 0, 1, Null, Null) \
|
||||
X(BitPiece, 0x9d, 2, 0, 0, ULEB128, ULEB128)
|
||||
|
||||
#define DW_Expr_V5_XList(X) \
|
||||
X(ImplicitPointer, 0xa0, 2, 0, 1) \
|
||||
X(Addrx, 0xa1, 1, 0, 1) \
|
||||
X(Constx, 0xa2, 1, 0, 1) \
|
||||
X(EntryValue, 0xa3, 2, 0, 0) \
|
||||
X(ConstType, 0xa4, 3, 0, 1) \
|
||||
X(RegvalType, 0xa5, 2, 0, 1) \
|
||||
X(DerefType, 0xa6, 2, 1, 1) \
|
||||
X(XDerefType, 0xa7, 2, 2, 1) \
|
||||
X(Convert, 0xa8, 1, 1, 1) \
|
||||
X(Reinterpret, 0xa9, 1, 1, 1)
|
||||
#define DW_Expr_V4_XList \
|
||||
X(ImplicitValue, 0x9e, 2, 0, 1, Block, Null) \
|
||||
X(StackValue, 0x9f, 0, 0, 0, Null, Null)
|
||||
|
||||
#define DW_Expr_GNU_XList(X) \
|
||||
X(GNU_PushTlsAddress, 0xe0, 0, 0, 1) \
|
||||
X(GNU_UnInit, 0xf0, 0, 0, 0) \
|
||||
X(GNU_ImplicitPointer, 0xf2, 2, 0, 1) \
|
||||
X(GNU_EntryValue, 0xf3, 2, 0, 0) \
|
||||
X(GNU_ConstType, 0xf4, 3, 0, 1) \
|
||||
X(GNU_RegvalType, 0xf5, 2, 0, 1) \
|
||||
X(GNU_DerefType, 0xf6, 2, 1, 1) \
|
||||
X(GNU_Convert, 0xf7, 1, 1, 1) \
|
||||
X(GNU_ParameterRef, 0xfa, 1, 0, 0) \
|
||||
X(GNU_AddrIndex, 0xfb, 0, 0, 1) \
|
||||
X(GNU_ConstIndex, 0xfc, 1, 0, 1)
|
||||
#define DW_Expr_V5_XList \
|
||||
X(ImplicitPointer, 0xa0, 2, 0, 1, DwarfUInt, SLEB128) \
|
||||
X(Addrx, 0xa1, 1, 0, 1, ULEB128, Null) \
|
||||
X(Constx, 0xa2, 1, 0, 1, ULEB128, Null) \
|
||||
X(EntryValue, 0xa3, 1, 0, 0, Block, Null) \
|
||||
X(ConstType, 0xa4, 2, 0, 1, ULEB128, Block) \
|
||||
X(RegvalType, 0xa5, 2, 0, 1, ULEB128, ULEB128) \
|
||||
X(DerefType, 0xa6, 2, 1, 1, U8, ULEB128) \
|
||||
X(XDerefType, 0xa7, 2, 2, 1, U8, ULEB128) \
|
||||
X(Convert, 0xa8, 1, 1, 1, ULEB128, Null) \
|
||||
X(Reinterpret, 0xa9, 1, 1, 1, ULEB128, Null)
|
||||
|
||||
#define DW_Expr_GNU_XList \
|
||||
X(GNU_PushTlsAddress, 0xe0, 0, 0, 1, Null, Null) \
|
||||
X(GNU_UnInit, 0xf0, 0, 0, 0, Null, Null) \
|
||||
X(GNU_ImplicitPointer, 0xf2, 2, 0, 1, DwarfUInt, SLEB128) \
|
||||
X(GNU_EntryValue, 0xf3, 1, 0, 0, Block, Null) \
|
||||
X(GNU_ConstType, 0xf4, 2, 0, 1, ULEB128, Block) \
|
||||
X(GNU_RegvalType, 0xf5, 2, 0, 1, ULEB128, ULEB128) \
|
||||
X(GNU_DerefType, 0xf6, 2, 1, 1, U8, ULEB128) \
|
||||
X(GNU_Convert, 0xf7, 1, 1, 1, ULEB128, Null) \
|
||||
X(GNU_ParameterRef, 0xfa, 1, 0, 0, U32, Null) \
|
||||
X(GNU_AddrIndex, 0xfb, 0, 0, 1, Null, Null) \
|
||||
X(GNU_ConstIndex, 0xfc, 1, 0, 1, ULEB128, Null)
|
||||
|
||||
typedef U8 DW_ExprOp;
|
||||
typedef enum DW_ExprOpEnum
|
||||
{
|
||||
#define X(_N, _ID, _OPER_COUNT, _POP_COUNT, _PUSH_COUNT) DW_ExprOp_##_N = _ID,
|
||||
DW_Expr_V3_XList(X)
|
||||
DW_Expr_V4_XList(X)
|
||||
DW_Expr_V5_XList(X)
|
||||
DW_Expr_GNU_XList(X)
|
||||
#define X(_N, _ID, _OPER_COUNT, _POP_COUNT, _PUSH_COUNT, ...) DW_ExprOp_##_N = _ID,
|
||||
DW_Expr_V3_XList
|
||||
DW_Expr_V4_XList
|
||||
DW_Expr_V5_XList
|
||||
DW_Expr_GNU_XList
|
||||
#undef X
|
||||
} DW_ExprOpEnum;
|
||||
|
||||
@@ -1745,9 +1763,10 @@ internal DW_AttribClass dw_pick_attrib_value_class(DW_Version ver, DW_Ext ext, B
|
||||
|
||||
internal U64 dw_pick_default_lower_bound(DW_Language lang);
|
||||
|
||||
internal U64 dw_operand_count_from_expr_op(DW_ExprOp op);
|
||||
internal U64 dw_pop_count_from_expr_op(DW_ExprOp op);
|
||||
internal U64 dw_push_count_from_expr_op(DW_ExprOp op);
|
||||
internal U64 dw_operand_count_from_expr_op(DW_ExprOp op);
|
||||
internal U64 dw_pop_count_from_expr_op(DW_ExprOp op);
|
||||
internal U64 dw_push_count_from_expr_op(DW_ExprOp op);
|
||||
internal DW_ExprOperandType * dw_operand_types_from_expr_opcode(DW_ExprOp op);
|
||||
|
||||
////////////////////////////////
|
||||
//~ CFA
|
||||
|
||||
@@ -1417,3 +1417,104 @@ exit:;
|
||||
return result;
|
||||
}
|
||||
|
||||
internal String8
|
||||
dw_encode_expr(Arena *arena, DW_Format format, U64 addr_size, DW_ExprEnc *encs, U64 encs_count)
|
||||
{
|
||||
Temp scratch = scratch_begin(&arena, 1);
|
||||
String8List *srl = push_array(scratch.arena, String8List, 1);
|
||||
str8_serial_begin(scratch.arena, srl);
|
||||
|
||||
for EachIndex(i, encs_count) {
|
||||
DW_ExprEnc *e = &encs[i];
|
||||
|
||||
switch (e->type) {
|
||||
case DW_ExprEncType_Op: {
|
||||
str8_serial_push_struct(scratch.arena, srl, &e->op);
|
||||
} break;
|
||||
case DW_ExprEncType_U8: {
|
||||
str8_serial_push_struct(scratch.arena, srl, &e->u8);
|
||||
} break;
|
||||
case DW_ExprEncType_U16: {
|
||||
str8_serial_push_struct(scratch.arena, srl, &e->u16);
|
||||
} break;
|
||||
case DW_ExprEncType_U32: {
|
||||
str8_serial_push_struct(scratch.arena, srl, &e->u32);
|
||||
} break;
|
||||
case DW_ExprEncType_U64: {
|
||||
str8_serial_push_struct(scratch.arena, srl, &e->u64);
|
||||
} break;
|
||||
case DW_ExprEncType_S8: {
|
||||
str8_serial_push_struct(scratch.arena, srl, &e->s8);
|
||||
} break;
|
||||
case DW_ExprEncType_S16: {
|
||||
str8_serial_push_struct(scratch.arena, srl, &e->s16);
|
||||
} break;
|
||||
case DW_ExprEncType_S32: {
|
||||
str8_serial_push_struct(scratch.arena, srl, &e->s32);
|
||||
} break;
|
||||
case DW_ExprEncType_S64: {
|
||||
str8_serial_push_struct(scratch.arena, srl, &e->s64);
|
||||
} break;
|
||||
case DW_ExprEncType_ULEB128: {
|
||||
U64 buffer_size = 0;
|
||||
U8 buffer[10];
|
||||
for (U64 value = e->u64; value != 0; ) {
|
||||
U8 byte = value & 0x7f;
|
||||
value >>= 7;
|
||||
if (value != 0) {
|
||||
byte |= 0x80;
|
||||
}
|
||||
Assert(buffer_size < sizeof(buffer));
|
||||
buffer[buffer_size++] = byte;
|
||||
}
|
||||
str8_serial_push_string(scratch.arena, srl, str8(buffer, buffer_size));
|
||||
} break;
|
||||
case DW_ExprEncType_SLEB128: {
|
||||
U64 buffer_size = 0;
|
||||
U8 buffer[10];
|
||||
for (S64 value = e->s64, more = 1; more != 0; ) {
|
||||
U8 byte = value & 0x7f;
|
||||
value >>= 7;
|
||||
U8 sign_bit = byte & 0x40;
|
||||
if ((value == 0 && sign_bit == 0) || (value == -1 && sign_bit != 0)) {
|
||||
more = 0;
|
||||
} else {
|
||||
byte |= 0x80;
|
||||
}
|
||||
Assert(buffer_size < sizeof(buffer));
|
||||
buffer[buffer_size++] = byte;
|
||||
}
|
||||
str8_serial_push_string(scratch.arena, srl, str8(buffer, buffer_size));
|
||||
} break;
|
||||
case DW_ExprEncType_Addr: {
|
||||
Assert(addr_size <= sizeof(e->addr));
|
||||
str8_serial_push_string(scratch.arena, srl, str8((U8 *)&e->addr, addr_size));
|
||||
} break;
|
||||
case DW_ExprEncType_Block: {
|
||||
Assert(e->block.size <= max_U8);
|
||||
str8_serial_push_u8(scratch.arena, srl, (U8)e->block.size);
|
||||
str8_serial_push_string(scratch.arena, srl, e->block);
|
||||
} break;
|
||||
case DW_ExprEncType_DwarfUInt: {
|
||||
switch (format) {
|
||||
case DW_Format_Null: {} break;
|
||||
case DW_Format_32Bit: { str8_serial_push_u32(scratch.arena, srl, e->u32); } break;
|
||||
case DW_Format_64Bit: { str8_serial_push_u64(scratch.arena, srl, e->u64); } break;
|
||||
default: { InvalidPath; } break;
|
||||
}
|
||||
} break;
|
||||
case DW_ExprEncType_Label: {
|
||||
// TODO:
|
||||
} break;
|
||||
case DW_ExprEncType_DeclLabel: {
|
||||
// TODO:
|
||||
} break;
|
||||
default: { InvalidPath; } break;
|
||||
}
|
||||
}
|
||||
|
||||
String8 expr = str8_serial_end(arena, srl);
|
||||
scratch_end(scratch);
|
||||
return expr;
|
||||
}
|
||||
|
||||
|
||||
@@ -4,6 +4,9 @@
|
||||
#ifndef DWARF_EXPR_H
|
||||
#define DWARF_EXPR_H
|
||||
|
||||
////////////////////////////////
|
||||
// evaluator
|
||||
|
||||
typedef struct DW_ExprContext
|
||||
{
|
||||
Arch arch;
|
||||
@@ -115,6 +118,66 @@ typedef struct DW_ExprResult
|
||||
int x;
|
||||
} DW_ExprResult;
|
||||
|
||||
////////////////////////////////
|
||||
// encoder
|
||||
|
||||
typedef enum
|
||||
{
|
||||
DW_ExprEncType_Null,
|
||||
DW_ExprEncType_Op,
|
||||
DW_ExprEncType_U8,
|
||||
DW_ExprEncType_U16,
|
||||
DW_ExprEncType_U32,
|
||||
DW_ExprEncType_U64,
|
||||
DW_ExprEncType_S8,
|
||||
DW_ExprEncType_S16,
|
||||
DW_ExprEncType_S32,
|
||||
DW_ExprEncType_S64,
|
||||
DW_ExprEncType_ULEB128,
|
||||
DW_ExprEncType_SLEB128,
|
||||
DW_ExprEncType_Addr,
|
||||
DW_ExprEncType_Block,
|
||||
DW_ExprEncType_DwarfUInt,
|
||||
DW_ExprEncType_Label,
|
||||
DW_ExprEncType_DeclLabel,
|
||||
} DW_ExprEncType;
|
||||
|
||||
typedef struct DW_ExprEnc
|
||||
{
|
||||
DW_ExprEncType type;
|
||||
union {
|
||||
DW_ExprOp op;
|
||||
U8 u8;
|
||||
U16 u16;
|
||||
U32 u32;
|
||||
U64 u64;
|
||||
S8 s8;
|
||||
S16 s16;
|
||||
S32 s32;
|
||||
S64 s64;
|
||||
U64 addr;
|
||||
String8 block;
|
||||
char *label;
|
||||
};
|
||||
} DW_ExprEnc;
|
||||
|
||||
#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_U16(v) { .type = DW_ExprEncType_U16, .u16 = 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_S8(v) { .type = DW_ExprEncType_S8, .s8 = 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_S64(v) { .type = DW_ExprEncType_S64, .s64 = 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_Addr(v) { .type = DW_ExprEncType_Addr, .addr = 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_Label(v) { .type = DW_ExprEncType_Label, .label = v }
|
||||
#define DW_ExprEnc_DeclLabel(v) { .type = DW_ExprEncType_DeclLabel, .label = v }
|
||||
|
||||
////////////////////////////////
|
||||
|
||||
// pieces
|
||||
@@ -174,5 +237,8 @@ internal String8 dw_string_from_expr_value(Arena *arena, U64 addr_size, DW_ExprV
|
||||
// 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);
|
||||
|
||||
// encoder
|
||||
internal String8 dw_encode_expr(Arena *arena, DW_Format format, U64 addr_size, DW_ExprEnc *encs, U64 encs_count);
|
||||
|
||||
#endif //DWARF_EXPR_H
|
||||
|
||||
|
||||
+40
-191
@@ -3116,210 +3116,59 @@ internal DW_Expr
|
||||
dw_expr_from_data(Arena *arena, DW_Format format, U64 addr_size, String8 data)
|
||||
{
|
||||
DW_Expr expr = {0};
|
||||
for (U64 cursor = 0; cursor < data.size; ) {
|
||||
U64 inst_start = cursor;
|
||||
|
||||
for (U64 cursor = 0, inst_start = 0; cursor < data.size; inst_start = cursor) {
|
||||
// read opcode
|
||||
DW_ExprOp opcode = 0;
|
||||
cursor += str8_deserial_read_struct(data, cursor, &opcode);
|
||||
U64 opcode_size = str8_deserial_read_struct(data, cursor, &opcode);
|
||||
if (opcode_size == 0) { break; }
|
||||
cursor += opcode_size;
|
||||
|
||||
DW_ExprOperand operands[4] = {0};
|
||||
switch (opcode) {
|
||||
case DW_ExprOp_Lit0: case DW_ExprOp_Lit1: case DW_ExprOp_Lit2:
|
||||
case DW_ExprOp_Lit3: case DW_ExprOp_Lit4: case DW_ExprOp_Lit5:
|
||||
case DW_ExprOp_Lit6: case DW_ExprOp_Lit7: case DW_ExprOp_Lit8:
|
||||
case DW_ExprOp_Lit9: case DW_ExprOp_Lit10: case DW_ExprOp_Lit11:
|
||||
case DW_ExprOp_Lit12: case DW_ExprOp_Lit13: case DW_ExprOp_Lit14:
|
||||
case DW_ExprOp_Lit15: case DW_ExprOp_Lit16: case DW_ExprOp_Lit17:
|
||||
case DW_ExprOp_Lit18: case DW_ExprOp_Lit19: case DW_ExprOp_Lit20:
|
||||
case DW_ExprOp_Lit21: case DW_ExprOp_Lit22: case DW_ExprOp_Lit23:
|
||||
case DW_ExprOp_Lit24: case DW_ExprOp_Lit25: case DW_ExprOp_Lit26:
|
||||
case DW_ExprOp_Lit27: case DW_ExprOp_Lit28: case DW_ExprOp_Lit29:
|
||||
case DW_ExprOp_Lit30: case DW_ExprOp_Lit31: {
|
||||
// implicit operands
|
||||
} break;
|
||||
case DW_ExprOp_Const1U: { cursor += str8_deserial_read_struct(data, cursor, &operands[0].u8); } break;
|
||||
case DW_ExprOp_Const2U: { cursor += str8_deserial_read_struct(data, cursor, &operands[0].u16); } break;
|
||||
case DW_ExprOp_Const4U: { cursor += str8_deserial_read_struct(data, cursor, &operands[0].u32); } break;
|
||||
case DW_ExprOp_Const8U: { cursor += str8_deserial_read_struct(data, cursor, &operands[0].u64); } break;
|
||||
case DW_ExprOp_Const1S: { cursor += str8_deserial_read_struct(data, cursor, &operands[0].s8); } break;
|
||||
case DW_ExprOp_Const2S: { cursor += str8_deserial_read_struct(data, cursor, &operands[0].s16); } break;
|
||||
case DW_ExprOp_Const4S: { cursor += str8_deserial_read_struct(data, cursor, &operands[0].s32); } break;
|
||||
case DW_ExprOp_Const8S: { cursor += str8_deserial_read_struct(data, cursor, &operands[0].s64); } break;
|
||||
case DW_ExprOp_ConstU: { cursor += str8_deserial_read_uleb128(data, cursor, &operands[0].u64); } break;
|
||||
case DW_ExprOp_ConstS: { cursor += str8_deserial_read_sleb128(data, cursor, &operands[0].s64); } break;
|
||||
case DW_ExprOp_Addr: { cursor += str8_deserial_read(data, cursor, &operands[0].u64, addr_size, addr_size); } break;
|
||||
case DW_ExprOp_Reg0: case DW_ExprOp_Reg1: case DW_ExprOp_Reg2:
|
||||
case DW_ExprOp_Reg3: case DW_ExprOp_Reg4: case DW_ExprOp_Reg5:
|
||||
case DW_ExprOp_Reg6: case DW_ExprOp_Reg7: case DW_ExprOp_Reg8:
|
||||
case DW_ExprOp_Reg9: case DW_ExprOp_Reg10: case DW_ExprOp_Reg11:
|
||||
case DW_ExprOp_Reg12: case DW_ExprOp_Reg13: case DW_ExprOp_Reg14:
|
||||
case DW_ExprOp_Reg15: case DW_ExprOp_Reg16: case DW_ExprOp_Reg17:
|
||||
case DW_ExprOp_Reg18: case DW_ExprOp_Reg19: case DW_ExprOp_Reg20:
|
||||
case DW_ExprOp_Reg21: case DW_ExprOp_Reg22: case DW_ExprOp_Reg23:
|
||||
case DW_ExprOp_Reg24: case DW_ExprOp_Reg25: case DW_ExprOp_Reg26:
|
||||
case DW_ExprOp_Reg27: case DW_ExprOp_Reg28: case DW_ExprOp_Reg29:
|
||||
case DW_ExprOp_Reg30: case DW_ExprOp_Reg31: {
|
||||
// implicit operands
|
||||
} break;
|
||||
case DW_ExprOp_RegX: { cursor += str8_deserial_read_uleb128(data, cursor, &operands[0].u64); } break;
|
||||
case DW_ExprOp_ImplicitValue: {
|
||||
U64 value_size = 0; String8 value = {0};
|
||||
cursor += str8_deserial_read_uleb128(data, cursor, &value_size);
|
||||
cursor += str8_deserial_read_block(data, cursor, value_size, &operands[0].block);
|
||||
} break;
|
||||
case DW_ExprOp_Piece: {
|
||||
cursor += str8_deserial_read_uleb128(data, cursor, &operands[0].u64);
|
||||
} break;
|
||||
case DW_ExprOp_BitPiece: {
|
||||
cursor += str8_deserial_read_uleb128(data, cursor, &operands[0].u64);
|
||||
cursor += str8_deserial_read_uleb128(data, cursor, &operands[1].u64);
|
||||
} break;
|
||||
case DW_ExprOp_Pick: {
|
||||
cursor += str8_deserial_read_struct(data, cursor, &operands[0].u8);
|
||||
} break;
|
||||
case DW_ExprOp_PlusUConst: {
|
||||
cursor += str8_deserial_read_uleb128(data, cursor, &operands[0].u64);
|
||||
} break;
|
||||
case DW_ExprOp_Skip: {
|
||||
cursor += str8_deserial_read_struct(data, cursor, &operands[0].s16);
|
||||
} break;
|
||||
case DW_ExprOp_Bra: {
|
||||
cursor += str8_deserial_read_struct(data, cursor, &operands[0].s16);
|
||||
} break;
|
||||
case DW_ExprOp_BReg0: case DW_ExprOp_BReg1: case DW_ExprOp_BReg2:
|
||||
case DW_ExprOp_BReg3: case DW_ExprOp_BReg4: case DW_ExprOp_BReg5:
|
||||
case DW_ExprOp_BReg6: case DW_ExprOp_BReg7: case DW_ExprOp_BReg8:
|
||||
case DW_ExprOp_BReg9: case DW_ExprOp_BReg10: case DW_ExprOp_BReg11:
|
||||
case DW_ExprOp_BReg12: case DW_ExprOp_BReg13: case DW_ExprOp_BReg14:
|
||||
case DW_ExprOp_BReg15: case DW_ExprOp_BReg16: case DW_ExprOp_BReg17:
|
||||
case DW_ExprOp_BReg18: case DW_ExprOp_BReg19: case DW_ExprOp_BReg20:
|
||||
case DW_ExprOp_BReg21: case DW_ExprOp_BReg22: case DW_ExprOp_BReg23:
|
||||
case DW_ExprOp_BReg24: case DW_ExprOp_BReg25: case DW_ExprOp_BReg26:
|
||||
case DW_ExprOp_BReg27: case DW_ExprOp_BReg28: case DW_ExprOp_BReg29:
|
||||
case DW_ExprOp_BReg30: case DW_ExprOp_BReg31: {
|
||||
cursor += str8_deserial_read_sleb128(data, cursor, &operands[0].s64);
|
||||
} break;
|
||||
case DW_ExprOp_BRegX: {
|
||||
cursor += str8_deserial_read_uleb128(data, cursor, &operands[0].u64);
|
||||
cursor += str8_deserial_read_sleb128(data, cursor, &operands[1].s64);
|
||||
} break;
|
||||
case DW_ExprOp_FBReg: {
|
||||
cursor += str8_deserial_read_sleb128(data, cursor, &operands[0].s64);
|
||||
} break;
|
||||
case DW_ExprOp_Deref: {
|
||||
// no operands
|
||||
} break;
|
||||
case DW_ExprOp_DerefSize: {
|
||||
cursor += str8_deserial_read_struct(data, cursor, &operands[0].u8);
|
||||
} break;
|
||||
case DW_ExprOp_XDerefSize: {
|
||||
cursor += str8_deserial_read_struct(data, cursor, &operands[0].u8);
|
||||
} break;
|
||||
case DW_ExprOp_Call2: {
|
||||
cursor += str8_deserial_read_struct(data, cursor, &operands[0].u16);
|
||||
} break;
|
||||
case DW_ExprOp_Call4: {
|
||||
cursor += str8_deserial_read_struct(data, cursor, &operands[0].u32);
|
||||
} break;
|
||||
case DW_ExprOp_CallRef: {
|
||||
cursor += str8_deserial_read_dwarf_uint(data, cursor, format, &operands[0].u64);
|
||||
} break;
|
||||
case DW_ExprOp_ImplicitPointer:
|
||||
case DW_ExprOp_GNU_ImplicitPointer: {
|
||||
cursor += str8_deserial_read_dwarf_uint(data, cursor, format, &operands[0].u64);
|
||||
cursor += str8_deserial_read_sleb128(data, cursor, &operands[1].s64);
|
||||
} break;
|
||||
case DW_ExprOp_Convert:
|
||||
case DW_ExprOp_GNU_Convert: {
|
||||
cursor += str8_deserial_read_uleb128(data, cursor, &operands[0].u64);
|
||||
} break;
|
||||
case DW_ExprOp_GNU_ParameterRef: {
|
||||
cursor += str8_deserial_read_struct(data, cursor, &operands[0].u32);
|
||||
} break;
|
||||
case DW_ExprOp_DerefType:
|
||||
case DW_ExprOp_GNU_DerefType: {
|
||||
cursor += str8_deserial_read_struct(data, cursor, &operands[0].u8);
|
||||
cursor += str8_deserial_read_uleb128(data, cursor, &operands[1].u64);
|
||||
} break;
|
||||
case DW_ExprOp_XDerefType: {
|
||||
cursor += str8_deserial_read_struct(data, cursor, &operands[0].u8);
|
||||
cursor += str8_deserial_read_uleb128(data, cursor, &operands[1].u64);
|
||||
} break;
|
||||
case DW_ExprOp_ConstType:
|
||||
case DW_ExprOp_GNU_ConstType: {
|
||||
cursor += str8_deserial_read_uleb128(data, cursor, &operands[0].u64);
|
||||
cursor += str8_deserial_read_struct(data, cursor, &operands[1].u8);
|
||||
cursor += str8_deserial_read_block(data, cursor, operands[1].u8, &operands[2].block);
|
||||
} break;
|
||||
case DW_ExprOp_RegvalType: {
|
||||
cursor += str8_deserial_read_uleb128(data, cursor, &operands[0].u64);
|
||||
cursor += str8_deserial_read_uleb128(data, cursor, &operands[1].u64);
|
||||
} break;
|
||||
case DW_ExprOp_EntryValue:
|
||||
case DW_ExprOp_GNU_EntryValue: {
|
||||
U64 entry_value_expr_size = 0;
|
||||
cursor += str8_deserial_read_uleb128(data, cursor, &entry_value_expr_size);
|
||||
cursor += str8_deserial_read_block(data, cursor, entry_value_expr_size, &operands[0].block);
|
||||
} break;
|
||||
case DW_ExprOp_Addrx: {
|
||||
cursor += str8_deserial_read_uleb128(data, cursor, &operands[0].u64);
|
||||
} break;
|
||||
case DW_ExprOp_Constx: {
|
||||
cursor += str8_deserial_read_uleb128(data, cursor, &operands[0].u64);
|
||||
} break;
|
||||
case DW_ExprOp_CallFrameCfa:
|
||||
case DW_ExprOp_FormTlsAddress:
|
||||
case DW_ExprOp_PushObjectAddress:
|
||||
case DW_ExprOp_Nop:
|
||||
case DW_ExprOp_Eq:
|
||||
case DW_ExprOp_Ge:
|
||||
case DW_ExprOp_Gt:
|
||||
case DW_ExprOp_Le:
|
||||
case DW_ExprOp_Lt:
|
||||
case DW_ExprOp_Ne:
|
||||
case DW_ExprOp_Shl:
|
||||
case DW_ExprOp_Shr:
|
||||
case DW_ExprOp_Shra:
|
||||
case DW_ExprOp_Xor:
|
||||
case DW_ExprOp_XDeref:
|
||||
case DW_ExprOp_Abs:
|
||||
case DW_ExprOp_And:
|
||||
case DW_ExprOp_Div:
|
||||
case DW_ExprOp_Minus:
|
||||
case DW_ExprOp_Mod:
|
||||
case DW_ExprOp_Mul:
|
||||
case DW_ExprOp_Neg:
|
||||
case DW_ExprOp_Not:
|
||||
case DW_ExprOp_Or:
|
||||
case DW_ExprOp_Plus:
|
||||
case DW_ExprOp_Rot:
|
||||
case DW_ExprOp_Swap:
|
||||
case DW_ExprOp_Dup:
|
||||
case DW_ExprOp_Drop:
|
||||
case DW_ExprOp_Over:
|
||||
case DW_ExprOp_StackValue:
|
||||
case DW_ExprOp_GNU_PushTlsAddress: {
|
||||
// no operands
|
||||
} break;
|
||||
case DW_ExprOp_GNU_AddrIndex: {
|
||||
cursor += str8_deserial_read_uleb128(data, cursor, &operands[0].u64);
|
||||
} break;
|
||||
case DW_ExprOp_GNU_ConstIndex: {
|
||||
cursor += str8_deserial_read_uleb128(data, cursor, &operands[0].u64);
|
||||
} break;
|
||||
default: { InvalidPath; } break;
|
||||
// read operands
|
||||
U64 operand_count = dw_operand_count_from_expr_op(opcode);
|
||||
DW_ExprOperandType *operand_types = dw_operand_types_from_expr_opcode(opcode);
|
||||
DW_ExprOperand operands[2] = {0};
|
||||
for EachIndex(operand_idx, operand_count) {
|
||||
U64 operand_size = 0;
|
||||
switch (operand_types[operand_idx]) {
|
||||
case DW_ExprOperandType_Null: { } break;
|
||||
case DW_ExprOperandType_U8: { operand_size = str8_deserial_read_struct(data, cursor, &operands[operand_idx].u8); } break;
|
||||
case DW_ExprOperandType_U16: { operand_size = str8_deserial_read_struct(data, cursor, &operands[operand_idx].u16); } break;
|
||||
case DW_ExprOperandType_U32: { operand_size = str8_deserial_read_struct(data, cursor, &operands[operand_idx].u32); } break;
|
||||
case DW_ExprOperandType_U64: { operand_size = str8_deserial_read_struct(data, cursor, &operands[operand_idx].u64); } break;
|
||||
case DW_ExprOperandType_S8: { operand_size = str8_deserial_read_struct(data, cursor, &operands[operand_idx].s8); } break;
|
||||
case DW_ExprOperandType_S16: { operand_size = str8_deserial_read_struct(data, cursor, &operands[operand_idx].s16); } break;
|
||||
case DW_ExprOperandType_S32: { operand_size = str8_deserial_read_struct(data, cursor, &operands[operand_idx].s32); } break;
|
||||
case DW_ExprOperandType_S64: { operand_size = str8_deserial_read_struct(data, cursor, &operands[operand_idx].s64); } break;
|
||||
case DW_ExprOperandType_ULEB128: { operand_size = str8_deserial_read_uleb128(data, cursor, &operands[operand_idx].u64); } break;
|
||||
case DW_ExprOperandType_SLEB128: { operand_size = str8_deserial_read_sleb128(data, cursor, &operands[operand_idx].s64); } break;
|
||||
case DW_ExprOperandType_Addr: { operand_size = str8_deserial_read(data, cursor, &operands[operand_idx].u64, addr_size, addr_size); } break;
|
||||
case DW_ExprOperandType_DwarfUInt: { operand_size = str8_deserial_read_dwarf_uint(data, cursor, format, &operands[operand_idx].u64); } break;
|
||||
case DW_ExprOperandType_Block: {
|
||||
U8 block_size;
|
||||
U64 block_size_size = str8_deserial_read_struct(data, cursor, &block_size);
|
||||
U64 block_read_size = str8_deserial_read_block(data, cursor + block_size_size, block_size, &operands[operand_idx].block);
|
||||
if(block_read_size == block_size_size) {
|
||||
operand_size = block_size_size + block_read_size;
|
||||
}
|
||||
} break;
|
||||
default: { InvalidPath; } break;
|
||||
}
|
||||
if (operand_size == 0) { goto exit; }
|
||||
cursor += operand_size;
|
||||
}
|
||||
|
||||
U64 operand_count = dw_operand_count_from_expr_op(opcode);
|
||||
// fill out instruction
|
||||
DW_ExprInst *inst = push_array(arena, DW_ExprInst, 1);
|
||||
inst->opcode = opcode;
|
||||
inst->size = cursor - inst_start;
|
||||
inst->operands = push_array(arena, DW_ExprOperand, operand_count);
|
||||
MemoryCopy(inst->operands, operands, operand_count * sizeof(DW_ExprOperand));
|
||||
|
||||
// push instruction
|
||||
DLLPushBack(expr.first, expr.last, inst);
|
||||
expr.count += 1;
|
||||
}
|
||||
exit:;
|
||||
return expr;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
// Copyright (c) Epic Games Tools
|
||||
// Licensed under the MIT license (https://opensource.org/license/mit/)
|
||||
|
||||
#define BUILD_CONSOLE_INFERFACE 1
|
||||
#define BUILD_TITLE "DWARF Expr Test"
|
||||
|
||||
////////////////////////////////
|
||||
|
||||
#include "third_party/xxHash/xxhash.c"
|
||||
#include "third_party/xxHash/xxhash.h"
|
||||
#include "third_party/radsort/radsort.h"
|
||||
|
||||
////////////////////////////////
|
||||
|
||||
#include "base/base_inc.h"
|
||||
#include "os/os_inc.h"
|
||||
#include "linker/hash_table.h"
|
||||
#include "coff/coff.h"
|
||||
#include "elf/elf.h"
|
||||
#include "elf/elf_parse.h"
|
||||
#include "dwarf/dwarf_inc.h"
|
||||
|
||||
#include "base/base_inc.c"
|
||||
#include "os/os_inc.c"
|
||||
#include "coff/coff.c"
|
||||
#include "elf/elf.c"
|
||||
#include "elf/elf_parse.c"
|
||||
#include "linker/hash_table.c"
|
||||
#include "dwarf/dwarf_inc.c"
|
||||
|
||||
////////////////////////////////
|
||||
|
||||
internal void
|
||||
entry_point(CmdLine *cmdline)
|
||||
{
|
||||
Temp scratch = scratch_begin(0, 0);
|
||||
|
||||
{
|
||||
DW_ExprEnc program[] = {
|
||||
DW_ExprEnc_DeclLabel("foo"),
|
||||
DW_ExprEnc_Op(BReg11), DW_ExprEnc_S64(44),
|
||||
DW_ExprEnc_Op(Skip), DW_ExprEnc_Label("foo"),
|
||||
};
|
||||
String8 expr_data = dw_encode_expr(scratch.arena, DW_Format_64Bit, sizeof(U64), program, ArrayCount(program));
|
||||
}
|
||||
|
||||
scratch_end(scratch);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user