mirror of
https://github.com/Ed94/raddebugger.git
synced 2026-08-14 09:18:09 +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(FBReg, 0x91, 1, 0, 1, SLEB128, Null) \
|
||||
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(XDerefSize, 0x95, 1, 2, 1, U8, Null) \
|
||||
X(Nop, 0x96, 0, 0, 0, Null, Null) \
|
||||
@@ -1558,7 +1558,7 @@ typedef enum
|
||||
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)
|
||||
X(BitPiece, 0x9d, 2, 1, 0, ULEB128, ULEB128)
|
||||
|
||||
#define DW_Expr_V4_XList \
|
||||
X(ImplicitValue, 0x9e, 2, 0, 1, Block, Null) \
|
||||
|
||||
+87
-20
@@ -1269,29 +1269,44 @@ dw_eval_expr(Arena *arena,
|
||||
} break;
|
||||
|
||||
case DW_ExprOp_Piece: {
|
||||
if (stack->count) {
|
||||
String8 value = dw_string_from_expr_value(arena, arch, dw_expr_stack_pop(stack));
|
||||
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 }});
|
||||
} else {
|
||||
Assert(0 && "out of bounds size in the piece opcode");
|
||||
goto exit;
|
||||
}
|
||||
B32 is_undefined = stack->count == 0 || (inst->prev && inst->prev->opcode == DW_ExprOp_Piece);
|
||||
if (is_undefined) {
|
||||
dw_piece_list_push(arena, &pieces, (DW_Piece){ .kind = DW_PieceKind_Undefined, .bit_size = inst->operands[0].u64 * 8 });
|
||||
} 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;
|
||||
|
||||
case DW_ExprOp_BitPiece: {
|
||||
if (stack->count) {
|
||||
String8 value = dw_string_from_expr_value(arena, arch, dw_expr_stack_pop(stack));
|
||||
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 }});
|
||||
} else {
|
||||
Assert(0 && "out of bounds size in the bit piece opcode");
|
||||
goto exit;
|
||||
}
|
||||
B32 is_undefined = stack->count == 0 || (inst->prev && inst->prev->opcode == DW_ExprOp_Piece);
|
||||
if (is_undefined) {
|
||||
dw_piece_list_push(arena, &pieces, (DW_Piece){ .kind = DW_PieceKind_Undefined, .bit_size = inst->operands[0].u64 });
|
||||
} 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;
|
||||
|
||||
@@ -1485,8 +1500,60 @@ dw_eval_expr(Arena *arena,
|
||||
}
|
||||
}
|
||||
|
||||
if (stack->top) {
|
||||
*value_out = stack->top->v;
|
||||
// composite value
|
||||
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;
|
||||
|
||||
+4
-12
@@ -40,6 +40,8 @@ typedef S8 DW_ExprBool;
|
||||
typedef struct DW_ExprValue
|
||||
{
|
||||
DW_ExprValueType type;
|
||||
Rng1U64Array ranges;
|
||||
U64 *offsets;
|
||||
union {
|
||||
U8 u8;
|
||||
U16 u16;
|
||||
@@ -77,13 +79,8 @@ typedef enum
|
||||
typedef struct DW_Piece
|
||||
{
|
||||
DW_PieceKind kind;
|
||||
union {
|
||||
U64 undef_bit_size;
|
||||
struct {
|
||||
U64 bit_size;
|
||||
void *ptr;
|
||||
} value;
|
||||
};
|
||||
U64 bit_size;
|
||||
U8 *value;
|
||||
} DW_Piece;
|
||||
|
||||
typedef struct DW_PieceNode
|
||||
@@ -105,11 +102,6 @@ typedef struct DW_ExprStack
|
||||
DW_ExprValueNode *top;
|
||||
} DW_ExprStack;
|
||||
|
||||
typedef struct DW_ExprResult
|
||||
{
|
||||
int x;
|
||||
} DW_ExprResult;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
DW_ExprEvalResult_Fail,
|
||||
|
||||
@@ -5163,6 +5163,40 @@ t_plus_uconst(void)
|
||||
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
|
||||
@@ -5251,6 +5285,7 @@ entry_point(CmdLine *cmdline)
|
||||
T(frame_relative_variable),
|
||||
T(call_by_reference),
|
||||
T(plus_uconst),
|
||||
//T(reg_split_spill),
|
||||
#undef T
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user