mirror of
https://github.com/Ed94/raddebugger.git
synced 2026-06-13 23:52:22 -07:00
643 lines
14 KiB
C
643 lines
14 KiB
C
// Copyright (c) 2024 Epic Games Tools
|
|
// Licensed under the MIT license (https://opensource.org/license/mit/)
|
|
|
|
#ifndef EVAL_CORE_H
|
|
#define EVAL_CORE_H
|
|
|
|
////////////////////////////////
|
|
//~ rjf: Messages
|
|
|
|
typedef enum E_MsgKind
|
|
{
|
|
E_MsgKind_Null,
|
|
E_MsgKind_MalformedInput,
|
|
E_MsgKind_MissingInfo,
|
|
E_MsgKind_ResolutionFailure,
|
|
E_MsgKind_InterpretationError,
|
|
E_MsgKind_COUNT
|
|
}
|
|
E_MsgKind;
|
|
|
|
typedef struct E_Msg E_Msg;
|
|
struct E_Msg
|
|
{
|
|
E_Msg *next;
|
|
E_MsgKind kind;
|
|
void *location;
|
|
String8 text;
|
|
};
|
|
|
|
typedef struct E_MsgList E_MsgList;
|
|
struct E_MsgList
|
|
{
|
|
E_Msg *first;
|
|
E_Msg *last;
|
|
E_MsgKind max_kind;
|
|
U64 count;
|
|
};
|
|
|
|
////////////////////////////////
|
|
//~ rjf: Register-Sized Value Type
|
|
|
|
typedef union E_Value E_Value;
|
|
union E_Value
|
|
{
|
|
U512 u512;
|
|
U256 u256;
|
|
U128 u128;
|
|
U64 u64;
|
|
U32 u32;
|
|
U16 u16;
|
|
S64 s64;
|
|
S32 s32;
|
|
S32 s16;
|
|
F64 f64;
|
|
F32 f32;
|
|
};
|
|
|
|
////////////////////////////////
|
|
//~ rjf: Operator Info
|
|
|
|
typedef enum E_OpKind
|
|
{
|
|
E_OpKind_Null,
|
|
E_OpKind_UnaryPrefix,
|
|
E_OpKind_Binary,
|
|
}
|
|
E_OpKind;
|
|
|
|
typedef struct E_OpInfo E_OpInfo;
|
|
struct E_OpInfo
|
|
{
|
|
E_OpKind kind;
|
|
S64 precedence;
|
|
String8 pre;
|
|
String8 sep;
|
|
String8 post;
|
|
};
|
|
|
|
////////////////////////////////
|
|
//~ rjf: Evaluation Spaces
|
|
//
|
|
// NOTE(rjf): Evaluations occur within the context of a "space". Each "space"
|
|
// refers to a different offset/address-space, but it's a bit looser of a
|
|
// concept than just address space, since it can also refer to offsets into
|
|
// a register block, and it is also used to refer to spaces of unique IDs for
|
|
// key-value stores, e.g. for information in the debugger.
|
|
//
|
|
// Effectively, when considering the result of an evaluation, you use the
|
|
// value for understanding a key *into* a space, e.g. 1+2 -> 3, in a null
|
|
// space, or &foo, in the space of PID: 1234.
|
|
|
|
typedef U64 E_SpaceKind;
|
|
enum
|
|
{
|
|
E_SpaceKind_Null,
|
|
E_SpaceKind_File,
|
|
E_SpaceKind_FileSystem,
|
|
E_SpaceKind_HashStoreKey,
|
|
E_SpaceKind_FirstUserDefined,
|
|
};
|
|
|
|
typedef struct E_Space E_Space;
|
|
struct E_Space
|
|
{
|
|
E_SpaceKind kind;
|
|
union
|
|
{
|
|
U64 u64s[3];
|
|
struct
|
|
{
|
|
U64 u64_0;
|
|
U128 u128;
|
|
};
|
|
};
|
|
};
|
|
|
|
////////////////////////////////
|
|
//~ rjf: Implicit Type Graph Key Types
|
|
|
|
typedef enum E_TypeKeyKind
|
|
{
|
|
E_TypeKeyKind_Null,
|
|
E_TypeKeyKind_Basic,
|
|
E_TypeKeyKind_Ext,
|
|
E_TypeKeyKind_Cons,
|
|
E_TypeKeyKind_Reg,
|
|
E_TypeKeyKind_RegAlias,
|
|
}
|
|
E_TypeKeyKind;
|
|
|
|
typedef struct E_TypeKey E_TypeKey;
|
|
struct E_TypeKey
|
|
{
|
|
E_TypeKeyKind kind;
|
|
U32 u32[3];
|
|
// [0] -> E_TypeKind (Basic, Cons, Ext); Arch (Reg, RegAlias)
|
|
// [1] -> Type Index In RDI (Ext); Code (Reg, RegAlias); Type Index In Constructed (Cons)
|
|
// [2] -> RDI Index (Ext)
|
|
};
|
|
|
|
typedef struct E_TypeKeyNode E_TypeKeyNode;
|
|
struct E_TypeKeyNode
|
|
{
|
|
E_TypeKeyNode *next;
|
|
E_TypeKey v;
|
|
};
|
|
|
|
typedef struct E_TypeKeyList E_TypeKeyList;
|
|
struct E_TypeKeyList
|
|
{
|
|
E_TypeKeyNode *first;
|
|
E_TypeKeyNode *last;
|
|
U64 count;
|
|
};
|
|
|
|
////////////////////////////////
|
|
//~ rjf: Generated Code
|
|
|
|
#include "generated/eval.meta.h"
|
|
|
|
////////////////////////////////
|
|
//~ rjf: Full Extracted Type Information Types
|
|
|
|
typedef enum E_MemberKind
|
|
{
|
|
E_MemberKind_Null,
|
|
E_MemberKind_DataField,
|
|
E_MemberKind_StaticData,
|
|
E_MemberKind_Method,
|
|
E_MemberKind_StaticMethod,
|
|
E_MemberKind_VirtualMethod,
|
|
E_MemberKind_VTablePtr,
|
|
E_MemberKind_Base,
|
|
E_MemberKind_VirtualBase,
|
|
E_MemberKind_NestedType,
|
|
E_MemberKind_Padding,
|
|
E_MemberKind_Query,
|
|
E_MemberKind_COUNT
|
|
}
|
|
E_MemberKind;
|
|
|
|
typedef U32 E_TypeFlags;
|
|
enum
|
|
{
|
|
E_TypeFlag_Const = (1<<0),
|
|
E_TypeFlag_Volatile = (1<<1),
|
|
E_TypeFlag_External = (1<<2),
|
|
E_TypeFlag_IsPlainText = (1<<3),
|
|
E_TypeFlag_IsCodeText = (1<<4),
|
|
E_TypeFlag_IsPathText = (1<<5),
|
|
E_TypeFlag_EditableChildren = (1<<6),
|
|
};
|
|
|
|
typedef struct E_Member E_Member;
|
|
struct E_Member
|
|
{
|
|
E_MemberKind kind;
|
|
E_TypeKey type_key;
|
|
String8 name;
|
|
U64 off;
|
|
E_TypeKeyList inheritance_key_chain;
|
|
};
|
|
|
|
typedef struct E_MemberNode E_MemberNode;
|
|
struct E_MemberNode
|
|
{
|
|
E_MemberNode *next;
|
|
E_Member v;
|
|
};
|
|
|
|
typedef struct E_MemberList E_MemberList;
|
|
struct E_MemberList
|
|
{
|
|
E_MemberNode *first;
|
|
E_MemberNode *last;
|
|
U64 count;
|
|
};
|
|
|
|
typedef struct E_MemberArray E_MemberArray;
|
|
struct E_MemberArray
|
|
{
|
|
E_Member *v;
|
|
U64 count;
|
|
};
|
|
|
|
typedef struct E_EnumVal E_EnumVal;
|
|
struct E_EnumVal
|
|
{
|
|
String8 name;
|
|
U64 val;
|
|
};
|
|
|
|
typedef struct E_EnumValArray E_EnumValArray;
|
|
struct E_EnumValArray
|
|
{
|
|
E_EnumVal *v;
|
|
U64 count;
|
|
};
|
|
|
|
typedef struct E_Type E_Type;
|
|
struct E_Type
|
|
{
|
|
E_TypeKind kind;
|
|
E_TypeFlags flags;
|
|
String8 name;
|
|
U64 byte_size;
|
|
U64 count;
|
|
U64 depth;
|
|
U32 off;
|
|
Arch arch;
|
|
E_TypeKey direct_type_key;
|
|
E_TypeKey owner_type_key;
|
|
E_TypeKey *param_type_keys;
|
|
E_Member *members;
|
|
E_EnumVal *enum_vals;
|
|
};
|
|
|
|
////////////////////////////////
|
|
//~ rjf: Evaluation Modes
|
|
|
|
typedef enum E_Mode
|
|
{
|
|
E_Mode_Null,
|
|
E_Mode_Value,
|
|
E_Mode_Offset,
|
|
}
|
|
E_Mode;
|
|
|
|
////////////////////////////////
|
|
//~ rjf: Modules
|
|
|
|
typedef struct E_Module E_Module;
|
|
struct E_Module
|
|
{
|
|
RDI_Parsed *rdi;
|
|
Rng1U64 vaddr_range;
|
|
Arch arch;
|
|
E_Space space;
|
|
};
|
|
|
|
////////////////////////////////
|
|
//~ rjf: Token Types
|
|
|
|
typedef struct E_Token E_Token;
|
|
struct E_Token
|
|
{
|
|
E_TokenKind kind;
|
|
Rng1U64 range;
|
|
};
|
|
|
|
typedef struct E_TokenChunkNode E_TokenChunkNode;
|
|
struct E_TokenChunkNode
|
|
{
|
|
E_TokenChunkNode *next;
|
|
E_Token *v;
|
|
U64 count;
|
|
U64 cap;
|
|
};
|
|
|
|
typedef struct E_TokenChunkList E_TokenChunkList;
|
|
struct E_TokenChunkList
|
|
{
|
|
E_TokenChunkNode *first;
|
|
E_TokenChunkNode *last;
|
|
U64 node_count;
|
|
U64 total_count;
|
|
};
|
|
|
|
typedef struct E_TokenArray E_TokenArray;
|
|
struct E_TokenArray
|
|
{
|
|
E_Token *v;
|
|
U64 count;
|
|
};
|
|
|
|
////////////////////////////////
|
|
//~ rjf: Expression Tree Types
|
|
|
|
typedef struct E_Expr E_Expr;
|
|
struct E_Expr
|
|
{
|
|
E_Expr *first;
|
|
E_Expr *last;
|
|
E_Expr *first_tag;
|
|
E_Expr *last_tag;
|
|
E_Expr *next;
|
|
E_Expr *prev;
|
|
E_Expr *ref;
|
|
void *location;
|
|
E_ExprKind kind;
|
|
E_Mode mode;
|
|
E_Space space;
|
|
E_TypeKey type_key;
|
|
E_Value value;
|
|
String8 string;
|
|
String8 qualifier;
|
|
String8 bytecode;
|
|
};
|
|
|
|
typedef struct E_ExprChain E_ExprChain;
|
|
struct E_ExprChain
|
|
{
|
|
E_Expr *first;
|
|
E_Expr *last;
|
|
};
|
|
|
|
typedef struct E_ExprNode E_ExprNode;
|
|
struct E_ExprNode
|
|
{
|
|
E_ExprNode *next;
|
|
E_Expr *v;
|
|
};
|
|
|
|
typedef struct E_ExprList E_ExprList;
|
|
struct E_ExprList
|
|
{
|
|
E_ExprNode *first;
|
|
E_ExprNode *last;
|
|
U64 count;
|
|
};
|
|
|
|
////////////////////////////////
|
|
//~ rjf: IR Tree Types
|
|
|
|
typedef struct E_IRNode E_IRNode;
|
|
struct E_IRNode
|
|
{
|
|
E_IRNode *first;
|
|
E_IRNode *last;
|
|
E_IRNode *next;
|
|
RDI_EvalOp op;
|
|
E_Space space;
|
|
String8 string;
|
|
E_Value value;
|
|
};
|
|
|
|
typedef struct E_IRTreeAndType E_IRTreeAndType;
|
|
struct E_IRTreeAndType
|
|
{
|
|
E_IRNode *root;
|
|
E_TypeKey type_key;
|
|
E_Member member;
|
|
E_Mode mode;
|
|
E_MsgList msgs;
|
|
};
|
|
|
|
////////////////////////////////
|
|
//~ rjf: String -> Num
|
|
|
|
typedef struct E_String2NumMapNode E_String2NumMapNode;
|
|
struct E_String2NumMapNode
|
|
{
|
|
E_String2NumMapNode *order_next;
|
|
E_String2NumMapNode *hash_next;
|
|
String8 string;
|
|
U64 num;
|
|
};
|
|
|
|
typedef struct E_String2NumMapNodeArray E_String2NumMapNodeArray;
|
|
struct E_String2NumMapNodeArray
|
|
{
|
|
E_String2NumMapNode **v;
|
|
U64 count;
|
|
};
|
|
|
|
typedef struct E_String2NumMapSlot E_String2NumMapSlot;
|
|
struct E_String2NumMapSlot
|
|
{
|
|
E_String2NumMapNode *first;
|
|
E_String2NumMapNode *last;
|
|
};
|
|
|
|
typedef struct E_String2NumMap E_String2NumMap;
|
|
struct E_String2NumMap
|
|
{
|
|
U64 slots_count;
|
|
U64 node_count;
|
|
E_String2NumMapSlot *slots;
|
|
E_String2NumMapNode *first;
|
|
E_String2NumMapNode *last;
|
|
};
|
|
|
|
////////////////////////////////
|
|
//~ rjf: String -> Expr
|
|
|
|
typedef struct E_String2ExprMapNode E_String2ExprMapNode;
|
|
struct E_String2ExprMapNode
|
|
{
|
|
E_String2ExprMapNode *hash_next;
|
|
String8 string;
|
|
E_Expr *expr;
|
|
U64 poison_count;
|
|
};
|
|
|
|
typedef struct E_String2ExprMapSlot E_String2ExprMapSlot;
|
|
struct E_String2ExprMapSlot
|
|
{
|
|
E_String2ExprMapNode *first;
|
|
E_String2ExprMapNode *last;
|
|
};
|
|
|
|
typedef struct E_String2ExprMap E_String2ExprMap;
|
|
struct E_String2ExprMap
|
|
{
|
|
U64 slots_count;
|
|
E_String2ExprMapSlot *slots;
|
|
};
|
|
|
|
////////////////////////////////
|
|
//~ rjf: Member/Index Lookup Hooks
|
|
|
|
typedef struct E_LookupInfo E_LookupInfo;
|
|
struct E_LookupInfo
|
|
{
|
|
void *user_data;
|
|
U64 named_expr_count;
|
|
U64 idxed_expr_count;
|
|
};
|
|
|
|
typedef struct E_LookupAccess E_LookupAccess;
|
|
struct E_LookupAccess
|
|
{
|
|
E_IRTreeAndType irtree_and_type;
|
|
};
|
|
|
|
#define E_LOOKUP_INFO_FUNCTION_SIG(name) E_LookupInfo name(Arena *arena, E_IRTreeAndType *lhs, E_Expr *tag, String8 filter)
|
|
#define E_LOOKUP_INFO_FUNCTION_NAME(name) e_lookup_info_##name
|
|
#define E_LOOKUP_INFO_FUNCTION_DEF(name) internal E_LOOKUP_INFO_FUNCTION_SIG(E_LOOKUP_INFO_FUNCTION_NAME(name))
|
|
typedef E_LOOKUP_INFO_FUNCTION_SIG(E_LookupInfoFunctionType);
|
|
E_LOOKUP_INFO_FUNCTION_DEF(default);
|
|
|
|
#define E_LOOKUP_ACCESS_FUNCTION_SIG(name) E_LookupAccess name(Arena *arena, E_ExprKind kind, E_Expr *lhs, E_Expr *rhs, E_Expr *tag, void *user_data)
|
|
#define E_LOOKUP_ACCESS_FUNCTION_NAME(name) e_lookup_access_##name
|
|
#define E_LOOKUP_ACCESS_FUNCTION_DEF(name) internal E_LOOKUP_ACCESS_FUNCTION_SIG(E_LOOKUP_ACCESS_FUNCTION_NAME(name))
|
|
typedef E_LOOKUP_ACCESS_FUNCTION_SIG(E_LookupAccessFunctionType);
|
|
E_LOOKUP_ACCESS_FUNCTION_DEF(default);
|
|
|
|
#define E_LOOKUP_RANGE_FUNCTION_SIG(name) void name(Arena *arena, E_Expr *lhs, E_Expr *tag, String8 filter, Rng1U64 idx_range, E_Expr **exprs, String8 *exprs_strings, void *user_data)
|
|
#define E_LOOKUP_RANGE_FUNCTION_NAME(name) e_lookup_range_##name
|
|
#define E_LOOKUP_RANGE_FUNCTION_DEF(name) internal E_LOOKUP_RANGE_FUNCTION_SIG(E_LOOKUP_RANGE_FUNCTION_NAME(name))
|
|
typedef E_LOOKUP_RANGE_FUNCTION_SIG(E_LookupRangeFunctionType);
|
|
E_LOOKUP_RANGE_FUNCTION_DEF(default);
|
|
|
|
#define E_LOOKUP_ID_FROM_NUM_FUNCTION_SIG(name) U64 name(U64 num, void *user_data)
|
|
#define E_LOOKUP_ID_FROM_NUM_FUNCTION_NAME(name) e_lookup_id_from_num_##name
|
|
#define E_LOOKUP_ID_FROM_NUM_FUNCTION_DEF(name) internal E_LOOKUP_ID_FROM_NUM_FUNCTION_SIG(E_LOOKUP_ID_FROM_NUM_FUNCTION_NAME(name))
|
|
typedef E_LOOKUP_ID_FROM_NUM_FUNCTION_SIG(E_LookupIDFromNumFunctionType);
|
|
E_LOOKUP_ID_FROM_NUM_FUNCTION_DEF(default);
|
|
|
|
#define E_LOOKUP_NUM_FROM_ID_FUNCTION_SIG(name) U64 name(U64 id, void *user_data)
|
|
#define E_LOOKUP_NUM_FROM_ID_FUNCTION_NAME(name) e_lookup_num_from_id_##name
|
|
#define E_LOOKUP_NUM_FROM_ID_FUNCTION_DEF(name) internal E_LOOKUP_NUM_FROM_ID_FUNCTION_SIG(E_LOOKUP_NUM_FROM_ID_FUNCTION_NAME(name))
|
|
typedef E_LOOKUP_NUM_FROM_ID_FUNCTION_SIG(E_LookupNumFromIDFunctionType);
|
|
E_LOOKUP_NUM_FROM_ID_FUNCTION_DEF(default);
|
|
|
|
typedef struct E_LookupRule E_LookupRule;
|
|
struct E_LookupRule
|
|
{
|
|
String8 name;
|
|
E_LookupInfoFunctionType *info;
|
|
E_LookupAccessFunctionType *access;
|
|
E_LookupRangeFunctionType *range;
|
|
E_LookupIDFromNumFunctionType *id_from_num;
|
|
E_LookupNumFromIDFunctionType *num_from_id;
|
|
};
|
|
|
|
typedef struct E_LookupRuleNode E_LookupRuleNode;
|
|
struct E_LookupRuleNode
|
|
{
|
|
E_LookupRuleNode *next;
|
|
E_LookupRule v;
|
|
};
|
|
|
|
typedef struct E_LookupRuleSlot E_LookupRuleSlot;
|
|
struct E_LookupRuleSlot
|
|
{
|
|
E_LookupRuleNode *first;
|
|
E_LookupRuleNode *last;
|
|
};
|
|
|
|
typedef struct E_LookupRuleMap E_LookupRuleMap;
|
|
struct E_LookupRuleMap
|
|
{
|
|
E_LookupRuleSlot *slots;
|
|
U64 slots_count;
|
|
};
|
|
|
|
typedef struct E_LookupRuleTagPair E_LookupRuleTagPair;
|
|
struct E_LookupRuleTagPair
|
|
{
|
|
E_LookupRule *rule;
|
|
E_Expr *tag;
|
|
};
|
|
|
|
////////////////////////////////
|
|
//~ rjf: IR Generation Hooks
|
|
|
|
#define E_IRGEN_FUNCTION_SIG(name) E_IRTreeAndType name(Arena *arena, E_Expr *expr, E_Expr *tag)
|
|
#define E_IRGEN_FUNCTION_NAME(name) e_irgen_##name
|
|
#define E_IRGEN_FUNCTION_DEF(name) internal E_IRGEN_FUNCTION_SIG(E_IRGEN_FUNCTION_NAME(name))
|
|
typedef E_IRGEN_FUNCTION_SIG(E_IRGenFunctionType);
|
|
E_IRGEN_FUNCTION_DEF(default);
|
|
|
|
typedef struct E_IRGenRule E_IRGenRule;
|
|
struct E_IRGenRule
|
|
{
|
|
String8 name;
|
|
E_IRGenFunctionType *irgen;
|
|
};
|
|
|
|
typedef struct E_IRGenRuleNode E_IRGenRuleNode;
|
|
struct E_IRGenRuleNode
|
|
{
|
|
E_IRGenRuleNode *next;
|
|
E_IRGenRule v;
|
|
};
|
|
|
|
typedef struct E_IRGenRuleSlot E_IRGenRuleSlot;
|
|
struct E_IRGenRuleSlot
|
|
{
|
|
E_IRGenRuleNode *first;
|
|
E_IRGenRuleNode *last;
|
|
};
|
|
|
|
typedef struct E_IRGenRuleMap E_IRGenRuleMap;
|
|
struct E_IRGenRuleMap
|
|
{
|
|
U64 slots_count;
|
|
E_IRGenRuleSlot *slots;
|
|
};
|
|
|
|
////////////////////////////////
|
|
//~ rjf: Type Pattern -> Hook Key Data Structure (Auto View Rules)
|
|
|
|
typedef struct E_AutoHookNode E_AutoHookNode;
|
|
struct E_AutoHookNode
|
|
{
|
|
E_AutoHookNode *hash_next;
|
|
E_AutoHookNode *pattern_order_next;
|
|
String8 type_string;
|
|
String8List type_pattern_parts;
|
|
E_ExprChain tag_exprs;
|
|
};
|
|
|
|
typedef struct E_AutoHookSlot E_AutoHookSlot;
|
|
struct E_AutoHookSlot
|
|
{
|
|
E_AutoHookNode *first;
|
|
E_AutoHookNode *last;
|
|
};
|
|
|
|
typedef struct E_AutoHookMap E_AutoHookMap;
|
|
struct E_AutoHookMap
|
|
{
|
|
U64 slots_count;
|
|
E_AutoHookSlot *slots;
|
|
E_AutoHookNode *first_pattern;
|
|
E_AutoHookNode *last_pattern;
|
|
};
|
|
|
|
typedef struct E_AutoHookParams E_AutoHookParams;
|
|
struct E_AutoHookParams
|
|
{
|
|
E_TypeKey type_key;
|
|
String8 type_pattern;
|
|
String8 tag_expr_string;
|
|
};
|
|
|
|
////////////////////////////////
|
|
//~ rjf: Contextual & Implicit Evaluation Parameters
|
|
|
|
typedef B32 E_SpaceRWFunction(void *user_data, E_Space space, void *out, Rng1U64 offset_range);
|
|
|
|
////////////////////////////////
|
|
//~ rjf: Generated Code
|
|
|
|
#include "eval/generated/eval.meta.h"
|
|
|
|
////////////////////////////////
|
|
//~ rjf: Globals
|
|
|
|
global read_only E_Module e_module_nil = {&rdi_parsed_nil};
|
|
|
|
////////////////////////////////
|
|
//~ rjf: Basic Helper Functions
|
|
|
|
internal U64 e_hash_from_string(U64 seed, String8 string);
|
|
#define e_value_u64(v) (E_Value){.u64 = (v)}
|
|
|
|
////////////////////////////////
|
|
//~ rjf: Message Functions
|
|
|
|
internal void e_msg(Arena *arena, E_MsgList *msgs, E_MsgKind kind, void *location, String8 text);
|
|
internal void e_msgf(Arena *arena, E_MsgList *msgs, E_MsgKind kind, void *location, char *fmt, ...);
|
|
internal void e_msg_list_concat_in_place(E_MsgList *dst, E_MsgList *to_push);
|
|
|
|
////////////////////////////////
|
|
//~ rjf: Space Functions
|
|
|
|
internal E_Space e_space_make(E_SpaceKind kind);
|
|
|
|
#endif // EVAL_CORE_H
|