mirror of
https://github.com/Ed94/raddebugger.git
synced 2026-08-14 17:28:07 +00:00
reader for STAP arguments
This commit is contained in:
committed by
Ryan Fleury
parent
bda3a71379
commit
e1a46f7d21
@@ -9,6 +9,54 @@
|
|||||||
////////////////////////////////
|
////////////////////////////////
|
||||||
//~ rjf: Helpers
|
//~ rjf: Helpers
|
||||||
|
|
||||||
|
internal REGS_RegCode
|
||||||
|
regs_reg_code_from_name(Arch arch, String8 name)
|
||||||
|
{
|
||||||
|
String8 *name_table = regs_reg_code_string_table_from_arch(arch);
|
||||||
|
U64 name_count = regs_reg_code_count_from_arch(arch);
|
||||||
|
for EachIndex(i, name_count)
|
||||||
|
{
|
||||||
|
if(str8_match(name_table[i], name, StringMatchFlag_CaseInsensitive))
|
||||||
|
{
|
||||||
|
return (REGS_RegCode)i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal REGS_AliasCode
|
||||||
|
regs_alias_code_from_name(Arch arch, String8 name)
|
||||||
|
{
|
||||||
|
String8 *alias_table = regs_alias_code_string_table_from_arch(arch);
|
||||||
|
U64 alias_count = regs_alias_code_count_from_arch(arch);
|
||||||
|
for EachIndex(i, alias_count)
|
||||||
|
{
|
||||||
|
if(str8_match(alias_table[i], name, StringMatchFlag_CaseInsensitive))
|
||||||
|
{
|
||||||
|
return (REGS_RegCode)i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal Rng1U64
|
||||||
|
regs_range_from_code(Arch arch, B32 is_alias, U64 reg_code)
|
||||||
|
{
|
||||||
|
Rng1U64 range = {0};
|
||||||
|
if(is_alias)
|
||||||
|
{
|
||||||
|
REGS_Slice slice = regs_alias_code_slice_table_from_arch(arch)[reg_code];
|
||||||
|
REGS_Rng rng = regs_reg_code_rng_table_from_arch(arch)[reg_code];
|
||||||
|
range = r1u64(rng.byte_off + slice.byte_off, rng.byte_off + slice.byte_off + slice.byte_size);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
REGS_Rng rng = regs_reg_code_rng_table_from_arch(arch)[reg_code];
|
||||||
|
range = r1u64(rng.byte_off, rng.byte_off + rng.byte_size);
|
||||||
|
}
|
||||||
|
return range;
|
||||||
|
}
|
||||||
|
|
||||||
internal U64
|
internal U64
|
||||||
regs_rip_from_arch_block(Arch arch, void *block)
|
regs_rip_from_arch_block(Arch arch, void *block)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -108,6 +108,9 @@ struct REGS_Slice
|
|||||||
////////////////////////////////
|
////////////////////////////////
|
||||||
//~ rjf: Helpers
|
//~ rjf: Helpers
|
||||||
|
|
||||||
|
internal REGS_RegCode regs_reg_code_from_name(Arch arch, String8 name);
|
||||||
|
internal REGS_AliasCode regs_alias_code_from_name(Arch arch, String8 name);
|
||||||
|
internal Rng1U64 regs_range_from_code(Arch arch, B32 is_alias, U64 reg_code);
|
||||||
internal U64 regs_block_size_from_arch(Arch arch);
|
internal U64 regs_block_size_from_arch(Arch arch);
|
||||||
internal U64 regs_reg_code_count_from_arch(Arch arch);
|
internal U64 regs_reg_code_count_from_arch(Arch arch);
|
||||||
internal U64 regs_alias_code_count_from_arch(Arch arch);
|
internal U64 regs_alias_code_count_from_arch(Arch arch);
|
||||||
|
|||||||
+80
-6
@@ -4,9 +4,7 @@
|
|||||||
internal B32
|
internal B32
|
||||||
stap_is_scale_valid(U64 scale)
|
stap_is_scale_valid(U64 scale)
|
||||||
{
|
{
|
||||||
local_persist B8 valid_sizes[9] = { 0, 1, 1, 0, 1, 0, 0, 0, 1 };
|
return IsPow2(scale) && scale <= 8;
|
||||||
B32 is_valid = scale < ArrayCount(valid_sizes) && valid_sizes[scale];
|
|
||||||
return is_valid;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
internal U64
|
internal U64
|
||||||
@@ -52,7 +50,7 @@ stap_size_from_arg(String8 string)
|
|||||||
{
|
{
|
||||||
U64 tag_sep = str8_find_needle(string, 0, str8_lit("@"), 0);
|
U64 tag_sep = str8_find_needle(string, 0, str8_lit("@"), 0);
|
||||||
U64 next_tag_sep = str8_find_needle(string, tag_sep + 1, str8_lit("@"), 0);
|
U64 next_tag_sep = str8_find_needle(string, tag_sep + 1, str8_lit("@"), 0);
|
||||||
U64 arg_end = str8_find_needle_reverse(string, next_tag_sep, str8_lit(" "), 0);
|
U64 arg_end = str8_find_needle_reverse(string, string.size - next_tag_sep, str8_lit(" "), 0);
|
||||||
return arg_end == 0 ? string.size : arg_end;
|
return arg_end == 0 ? string.size : arg_end;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -292,8 +290,8 @@ stap_parse_args_x64(String8 string, STAP_Arg *arg_out)
|
|||||||
}
|
}
|
||||||
// %reg
|
// %reg
|
||||||
else if (str8_match(str8_lit("%"), oper, StringMatchFlag_RightSideSloppy)) {
|
else if (str8_match(str8_lit("%"), oper, StringMatchFlag_RightSideSloppy)) {
|
||||||
// skip %
|
// skip % and strip white space
|
||||||
String8 reg_str = str8_skip(oper, 1);
|
String8 reg_str = str8_skip_chop_whitespace(str8_skip(oper, 1));
|
||||||
if (reg_str.size == 0) {
|
if (reg_str.size == 0) {
|
||||||
goto operand_parse_exit;
|
goto operand_parse_exit;
|
||||||
}
|
}
|
||||||
@@ -361,4 +359,80 @@ stap_arg_array_from_string(Arena *arena, Arch arch, String8 string)
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal B32
|
||||||
|
stap_read_arg(STAP_Arg arg,
|
||||||
|
Arch arch,
|
||||||
|
void *reg_block,
|
||||||
|
STAP_MemoryRead *memory_read,
|
||||||
|
void *memory_read_ctx,
|
||||||
|
void *raw_value)
|
||||||
|
{
|
||||||
|
AssertAlways(arg.value_size <= 8);
|
||||||
|
|
||||||
|
B32 is_value_read = 0;
|
||||||
|
|
||||||
|
switch (arg.type) {
|
||||||
|
case STAP_ArgType_Null: break;
|
||||||
|
case STAP_ArgType_Imm: {
|
||||||
|
MemoryCopy(raw_value, &arg.imm, arg.value_size);
|
||||||
|
is_value_read = 1;
|
||||||
|
} break;
|
||||||
|
case STAP_ArgType_Reg: {
|
||||||
|
Rng1U64 range = regs_range_from_code(arch, arg.reg.is_alias, arg.reg.reg_code);
|
||||||
|
U64 copy_size = Min(arg.value_size, dim_1u64(range));
|
||||||
|
MemoryCopy(raw_value, (U8 *)reg_block + range.min, copy_size);
|
||||||
|
is_value_read = 1;
|
||||||
|
} break;
|
||||||
|
case STAP_ArgType_MemoryRef: {
|
||||||
|
U64 base = 0;
|
||||||
|
if(arg.memory_ref.base.reg_code) {
|
||||||
|
Rng1U64 range = regs_range_from_code(arch, arg.memory_ref.base.is_alias, arg.memory_ref.base.reg_code);
|
||||||
|
U64 copy_size = Min(sizeof(base), dim_1u64(range));
|
||||||
|
MemoryCopy(&base, (U8 *)reg_block + range.min, copy_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
U64 index = 0;
|
||||||
|
if(arg.memory_ref.index.reg_code) {
|
||||||
|
Rng1U64 range = regs_range_from_code(arch, arg.memory_ref.index.is_alias, arg.memory_ref.index.reg_code);
|
||||||
|
U64 copy_size = Min(sizeof(base), dim_1u64(range));
|
||||||
|
MemoryCopy(&index, (U8 *)reg_block + range.min, copy_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
U64 addr = arg.memory_ref.disp + (base + index * arg.memory_ref.scale);
|
||||||
|
if (memory_read(addr, raw_value, arg.value_size, memory_read_ctx)) {
|
||||||
|
is_value_read = 1;
|
||||||
|
}
|
||||||
|
} break;
|
||||||
|
default: { InvalidPath; } break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (arg.value_size < 8) {
|
||||||
|
if (arg.value_type == STAP_ArgValueType_S) {
|
||||||
|
*(U64 *)raw_value = extend_sign64(*(U64 *)raw_value, arg.value_size);
|
||||||
|
} else if (arg.value_type == STAP_ArgValueType_F) {
|
||||||
|
Assert(arg.value_size == 4);
|
||||||
|
*(F64 *)raw_value = *(F32 *)raw_value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return is_value_read;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal B32
|
||||||
|
stap_read_arg_u(STAP_Arg arg, Arch arch, void *reg_block, STAP_MemoryRead *memory_read, void *memory_read_ctx, U64 *u_out)
|
||||||
|
{
|
||||||
|
return stap_read_arg(arg, arch, reg_block, memory_read, memory_read_ctx, u_out);
|
||||||
|
}
|
||||||
|
|
||||||
|
internal B32
|
||||||
|
stap_read_arg_s(STAP_Arg arg, Arch arch, void *reg_block, STAP_MemoryRead *memory_read, void *memory_read_ctx, S64 *s_out)
|
||||||
|
{
|
||||||
|
return stap_read_arg(arg, arch, reg_block, memory_read, memory_read_ctx, s_out);
|
||||||
|
}
|
||||||
|
|
||||||
|
internal B32
|
||||||
|
stap_read_arg_f(STAP_Arg arg, Arch arch, void *reg_block, STAP_MemoryRead *memory_read, void *memory_read_ctx, F64 *f_out)
|
||||||
|
{
|
||||||
|
return stap_read_arg(arg, arch, reg_block, memory_read, memory_read_ctx, f_out);
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -65,10 +65,18 @@ typedef struct STAP_ArgValueArray
|
|||||||
STAP_ArgValue *v;
|
STAP_ArgValue *v;
|
||||||
} STAP_ArgValueArray;
|
} STAP_ArgValueArray;
|
||||||
|
|
||||||
|
#define STAP_MEMORY_READ(name) B32 name(U64 addr, void *buffer, U64 read_size, void *raw_ctx)
|
||||||
|
typedef STAP_MEMORY_READ(STAP_MemoryRead);
|
||||||
|
|
||||||
////////////////////////////////
|
////////////////////////////////
|
||||||
|
|
||||||
internal String8 stap_parse_args_x64(String8 string, STAP_Arg *arg_out);
|
internal String8 stap_parse_args_x64(String8 string, STAP_Arg *arg_out);
|
||||||
internal STAP_ArgArray stap_arg_array_from_string(Arena *arena, Arch arch, String8 string);
|
internal STAP_ArgArray stap_arg_array_from_string(Arena *arena, Arch arch, String8 string);
|
||||||
|
|
||||||
|
internal B32 stap_read_arg(STAP_Arg arg, Arch arch, void *reg_block, STAP_MemoryRead *memory_read, void *memory_read_ctx, void *raw_value);
|
||||||
|
internal B32 stap_read_arg_u(STAP_Arg arg, Arch arch, void *reg_block, STAP_MemoryRead *memory_read, void *memory_read_ctx, U64 *u_out);
|
||||||
|
internal B32 stap_read_arg_s(STAP_Arg arg, Arch arch, void *reg_block, STAP_MemoryRead *memory_read, void *memory_read_ctx, S64 *s_out);
|
||||||
|
internal B32 stap_read_arg_f(STAP_Arg arg, Arch arch, void *reg_block, STAP_MemoryRead *memory_read, void *memory_read_ctx, F64 *f_out);
|
||||||
|
|
||||||
#endif // STAP_PARSE_H
|
#endif // STAP_PARSE_H
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user