mirror of
https://github.com/Ed94/raddebugger.git
synced 2026-08-14 17:28:07 +00:00
WIP DW_OP_piece
This commit is contained in:
+2
-2
@@ -1548,7 +1548,7 @@ typedef enum
|
|||||||
X(RegX, 0x90, 1, 0, 1, ULEB128, Null) \
|
X(RegX, 0x90, 1, 0, 1, ULEB128, Null) \
|
||||||
X(FBReg, 0x91, 1, 0, 1, SLEB128, Null) \
|
X(FBReg, 0x91, 1, 0, 1, SLEB128, Null) \
|
||||||
X(BRegX, 0x92, 2, 0, 1, ULEB128, SLEB128) \
|
X(BRegX, 0x92, 2, 0, 1, ULEB128, SLEB128) \
|
||||||
X(Piece, 0x93, 1, 0, 0, ULEB128, Null) \
|
X(Piece, 0x93, 1, 1, 0, ULEB128, Null) \
|
||||||
X(DerefSize, 0x94, 1, 1, 1, U8, Null) \
|
X(DerefSize, 0x94, 1, 1, 1, U8, Null) \
|
||||||
X(XDerefSize, 0x95, 1, 2, 1, U8, Null) \
|
X(XDerefSize, 0x95, 1, 2, 1, U8, Null) \
|
||||||
X(Nop, 0x96, 0, 0, 0, Null, Null) \
|
X(Nop, 0x96, 0, 0, 0, Null, Null) \
|
||||||
@@ -1558,7 +1558,7 @@ typedef enum
|
|||||||
X(CallRef, 0x9a, 1, 0, 0, DwarfUInt,Null) \
|
X(CallRef, 0x9a, 1, 0, 0, DwarfUInt,Null) \
|
||||||
X(FormTlsAddress, 0x9b, 0, 0, 1, Null, Null) \
|
X(FormTlsAddress, 0x9b, 0, 0, 1, Null, Null) \
|
||||||
X(CallFrameCfa, 0x9c, 0, 0, 1, Null, Null) \
|
X(CallFrameCfa, 0x9c, 0, 0, 1, Null, Null) \
|
||||||
X(BitPiece, 0x9d, 2, 0, 0, ULEB128, ULEB128)
|
X(BitPiece, 0x9d, 2, 1, 0, ULEB128, ULEB128)
|
||||||
|
|
||||||
#define DW_Expr_V4_XList \
|
#define DW_Expr_V4_XList \
|
||||||
X(ImplicitValue, 0x9e, 2, 0, 1, Block, Null) \
|
X(ImplicitValue, 0x9e, 2, 0, 1, Block, Null) \
|
||||||
|
|||||||
+87
-20
@@ -1269,29 +1269,44 @@ dw_eval_expr(Arena *arena,
|
|||||||
} break;
|
} break;
|
||||||
|
|
||||||
case DW_ExprOp_Piece: {
|
case DW_ExprOp_Piece: {
|
||||||
if (stack->count) {
|
B32 is_undefined = stack->count == 0 || (inst->prev && inst->prev->opcode == DW_ExprOp_Piece);
|
||||||
String8 value = dw_string_from_expr_value(arena, arch, dw_expr_stack_pop(stack));
|
if (is_undefined) {
|
||||||
if (inst->operands[0].u64 <= value.size) {
|
dw_piece_list_push(arena, &pieces, (DW_Piece){ .kind = DW_PieceKind_Undefined, .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 {
|
|
||||||
Assert(0 && "out of bounds size in the piece opcode");
|
|
||||||
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_ExprValue top = dw_expr_stack_pop(stack);
|
||||||
|
|
||||||
|
String8 value;
|
||||||
|
|
||||||
|
// piece is a memory reference
|
||||||
|
if (top.type == DW_ExprValueType_Addr) {
|
||||||
|
U64 value_size = inst->operands[0].u64;
|
||||||
|
U8 *value_buffer = push_array(arena, U8, value_size);
|
||||||
|
MachineOpResult read_result = mem_read(top.addr, value_buffer, value_size, mem_read_ud);
|
||||||
|
if (read_result != MachineOpResult_Ok) { Assert(0 && "failed to read piece memory referece"); goto exit; }
|
||||||
|
}
|
||||||
|
// piece is a value
|
||||||
|
else {
|
||||||
|
value = dw_string_from_expr_value(arena, arch, top);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (inst->operands[0].u64 > value.size) { Assert(0 && "out of bounds size in the piece opcode"); goto exit; }
|
||||||
|
dw_piece_list_push(arena, &pieces, (DW_Piece){ .kind = DW_PieceKind_Value, .bit_size = inst->operands[0].u64 * 8, .value = value.str });
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case DW_ExprOp_BitPiece: {
|
case DW_ExprOp_BitPiece: {
|
||||||
if (stack->count) {
|
B32 is_undefined = stack->count == 0 || (inst->prev && inst->prev->opcode == DW_ExprOp_Piece);
|
||||||
String8 value = dw_string_from_expr_value(arena, arch, dw_expr_stack_pop(stack));
|
if (is_undefined) {
|
||||||
if (inst->operands[0].u64 <= value.size * 8) {
|
dw_piece_list_push(arena, &pieces, (DW_Piece){ .kind = DW_PieceKind_Undefined, .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 {
|
|
||||||
Assert(0 && "out of bounds size in the bit piece opcode");
|
|
||||||
goto exit;
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
dw_piece_list_push(arena, &pieces, (DW_Piece){ .kind = DW_PieceKind_Undefined, .undef_bit_size = inst->operands[0].u64 });
|
String8 value;
|
||||||
|
if (dw_expr_stack_peek(stack).type == DW_ExprValueType_Addr) {
|
||||||
|
NotImplemented;
|
||||||
|
} else {
|
||||||
|
value = dw_string_from_expr_value(arena, arch, dw_expr_stack_pop(stack));
|
||||||
|
}
|
||||||
|
if (inst->operands[0].u64 > value.size * 8) { Assert(0 && "out of bounds size in piece opcode"); goto exit; }
|
||||||
|
dw_piece_list_push(arena, &pieces, (DW_Piece){ .kind = DW_PieceKind_Value, .bit_size = inst->operands[0].u64, .value = value.str });
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
@@ -1485,8 +1500,60 @@ dw_eval_expr(Arena *arena,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (stack->top) {
|
// composite value
|
||||||
*value_out = stack->top->v;
|
if (pieces.count > 0) {
|
||||||
|
#if 0
|
||||||
|
U64 total_bit_size = 0;
|
||||||
|
for EachNode (n, DW_PieceNode, pieces.first) {
|
||||||
|
total_bit_size += n->v.bit_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
U64 value_size = CeilIntegerDiv(total_bit_size, 8);
|
||||||
|
U8 *value = push_array(arena, U8, value_size);
|
||||||
|
Rng1U64 *ranges = push_array(arena, Rng1U64, pieces.count);
|
||||||
|
U64 *offsets = push_array(arena, U64, pieces.count);
|
||||||
|
U64 value_idx = 0;
|
||||||
|
U64 value_cursor = 0;
|
||||||
|
U64 piece_cursor = 0;
|
||||||
|
for EachNode(n, DW_PieceNode, pieces.first) {
|
||||||
|
if (n->v.kind == DW_PieceKind_Value) {
|
||||||
|
ranges[value_idx] = r1u64(piece_cursor, piece_cursor + n->v.bit_size);
|
||||||
|
offsets[value_idx] = value_cursor;
|
||||||
|
for (U64 i = 0; i < n->v.bit_size; i += 8) {
|
||||||
|
U64 to_copy = Min(8, n->v.bit_size - i);
|
||||||
|
if (value_cursor % 8 == 0) {
|
||||||
|
value[value_cursor / 8] = n->v.value[i];
|
||||||
|
} else {
|
||||||
|
value[value_cursor / 8] |= n->v.value[i] << (value_cursor % 8);
|
||||||
|
value[AlignPow2(value_cursor / 8, 8)] |= n->v.value[i] >> (value_cursor % 8);
|
||||||
|
}
|
||||||
|
value_cursor += to_copy;
|
||||||
|
}
|
||||||
|
value_idx += 1;
|
||||||
|
}
|
||||||
|
piece_cursor += n->v.bit_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
value_out->type = DW_ExprValueType_Generic;
|
||||||
|
value_out->ranges = (Rng1U64Array){ .count = pieces.count, .v = ranges };
|
||||||
|
value_out->offsets = offsets;
|
||||||
|
value_out->generic = str8(value, value_size);
|
||||||
|
#else
|
||||||
|
NotImplemented;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
// scalar
|
||||||
|
else {
|
||||||
|
if (stack->top) {
|
||||||
|
*value_out = stack->top->v;
|
||||||
|
|
||||||
|
Rng1U64 *range = push_array(arena, Rng1U64, 1);
|
||||||
|
*range = r1u64(0, max_U64);
|
||||||
|
value_out->ranges = (Rng1U64Array){ .count = 1, .v = range };
|
||||||
|
value_out->offsets = push_array(arena, U64, 1);
|
||||||
|
} else {
|
||||||
|
MemoryZeroStruct(value_out);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
result = DW_ExprEvalResult_Ok;
|
result = DW_ExprEvalResult_Ok;
|
||||||
|
|||||||
+4
-12
@@ -40,6 +40,8 @@ typedef S8 DW_ExprBool;
|
|||||||
typedef struct DW_ExprValue
|
typedef struct DW_ExprValue
|
||||||
{
|
{
|
||||||
DW_ExprValueType type;
|
DW_ExprValueType type;
|
||||||
|
Rng1U64Array ranges;
|
||||||
|
U64 *offsets;
|
||||||
union {
|
union {
|
||||||
U8 u8;
|
U8 u8;
|
||||||
U16 u16;
|
U16 u16;
|
||||||
@@ -77,13 +79,8 @@ typedef enum
|
|||||||
typedef struct DW_Piece
|
typedef struct DW_Piece
|
||||||
{
|
{
|
||||||
DW_PieceKind kind;
|
DW_PieceKind kind;
|
||||||
union {
|
U64 bit_size;
|
||||||
U64 undef_bit_size;
|
U8 *value;
|
||||||
struct {
|
|
||||||
U64 bit_size;
|
|
||||||
void *ptr;
|
|
||||||
} value;
|
|
||||||
};
|
|
||||||
} DW_Piece;
|
} DW_Piece;
|
||||||
|
|
||||||
typedef struct DW_PieceNode
|
typedef struct DW_PieceNode
|
||||||
@@ -105,11 +102,6 @@ typedef struct DW_ExprStack
|
|||||||
DW_ExprValueNode *top;
|
DW_ExprValueNode *top;
|
||||||
} DW_ExprStack;
|
} DW_ExprStack;
|
||||||
|
|
||||||
typedef struct DW_ExprResult
|
|
||||||
{
|
|
||||||
int x;
|
|
||||||
} DW_ExprResult;
|
|
||||||
|
|
||||||
typedef enum
|
typedef enum
|
||||||
{
|
{
|
||||||
DW_ExprEvalResult_Fail,
|
DW_ExprEvalResult_Fail,
|
||||||
|
|||||||
@@ -5163,6 +5163,40 @@ t_plus_uconst(void)
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal T_Result
|
||||||
|
t_reg_split_spill(void)
|
||||||
|
{
|
||||||
|
Temp scratch = scratch_begin(0, 0);
|
||||||
|
T_Result result = T_Result_Fail;
|
||||||
|
|
||||||
|
// setup register context
|
||||||
|
REGS_RegBlockX64 regs = {0};
|
||||||
|
{
|
||||||
|
REGS_RegCode reg_code = reg_code_from_dw_reg(Arch_x64, DW_ExprOp_BReg3 - DW_ExprOp_BReg0);
|
||||||
|
Rng1U64 reg_range = regs_range_from_code(Arch_x64, 0, reg_code);
|
||||||
|
U64 value = 0xaaaa;
|
||||||
|
MemoryCopy((U8 *)®s + reg_range.min, &value, sizeof(value));
|
||||||
|
}
|
||||||
|
{
|
||||||
|
REGS_RegCode reg_code = reg_code_from_dw_reg(Arch_x64, DW_ExprOp_BReg10 - DW_ExprOp_BReg0);
|
||||||
|
Rng1U64 reg_range = regs_range_from_code(Arch_x64, 0, reg_code);
|
||||||
|
U64 value = 0xbbbb;
|
||||||
|
MemoryCopy((U8 *)®s + reg_range.min, &value, sizeof(value));
|
||||||
|
}
|
||||||
|
|
||||||
|
DW_ExprEnc expr_encs[] = { DW_ExprEnc_Op(Reg3), DW_ExprEnc_Op(Piece), DW_ExprEnc_ULEB128(4), DW_ExprEnc_Op(Reg10), DW_ExprEnc_Op(Piece), DW_ExprEnc_ULEB128(2) };
|
||||||
|
String8 expr_data = dw_encode_expr(scratch.arena, Arch_x64, DW_Format_64Bit, expr_encs, ArrayCount(expr_encs));
|
||||||
|
DW_Expr expr = dw_expr_from_data(scratch.arena, DW_Format_64Bit, byte_size_from_arch(Arch_x64), expr_data);
|
||||||
|
|
||||||
|
DW_ExprValue expr_value;
|
||||||
|
DW_ExprEvalResult expr_eval = dw_eval_expr(scratch.arena, Arch_x64, DW_Format_64Bit, 0, 0, 0, max_U64, expr, regs_read_dwarf_x64, ®s, 0, 0, &expr_value);
|
||||||
|
|
||||||
|
result = T_Result_Pass;
|
||||||
|
exit:;
|
||||||
|
scratch_end(scratch);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
internal void
|
internal void
|
||||||
@@ -5251,6 +5285,7 @@ entry_point(CmdLine *cmdline)
|
|||||||
T(frame_relative_variable),
|
T(frame_relative_variable),
|
||||||
T(call_by_reference),
|
T(call_by_reference),
|
||||||
T(plus_uconst),
|
T(plus_uconst),
|
||||||
|
//T(reg_split_spill),
|
||||||
#undef T
|
#undef T
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user