mirror of
https://github.com/Ed94/raddebugger.git
synced 2026-08-14 17:28:07 +00:00
outline DWARF expression evaluator
This commit is contained in:
@@ -1682,6 +1682,23 @@ typedef enum DW_RegX64Enum
|
|||||||
|
|
||||||
////////////////////////////////
|
////////////////////////////////
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
DW_UnwindStatus_Ok,
|
||||||
|
DW_UnwindStatus_Fail,
|
||||||
|
DW_UnwindStatus_Maybe
|
||||||
|
} DW_UnwindStatus;
|
||||||
|
|
||||||
|
#define DW_REG_READ(name) DW_UnwindStatus name(DW_Reg reg_id, void *buffer, U64 buffer_max, void *ud)
|
||||||
|
typedef DW_REG_READ(DW_RegRead);
|
||||||
|
|
||||||
|
#define DW_REG_WRITE(name) DW_UnwindStatus name(DW_Reg reg_id, void *value, U64 value_size, void *ud)
|
||||||
|
typedef DW_REG_WRITE(DW_RegWrite);
|
||||||
|
|
||||||
|
#define DW_MEM_READ(name) DW_UnwindStatus name(U64 addr, U64 size, void *buffer, void *ud)
|
||||||
|
typedef DW_MEM_READ(DW_MemRead);
|
||||||
|
|
||||||
|
////////////////////////////////
|
||||||
|
|
||||||
internal U64 dw_reg_size_from_code_x64(DW_Reg reg_code);
|
internal U64 dw_reg_size_from_code_x64(DW_Reg reg_code);
|
||||||
internal U64 dw_reg_pos_from_code_x64(DW_Reg reg_code);
|
internal U64 dw_reg_pos_from_code_x64(DW_Reg reg_code);
|
||||||
internal U64 dw_reg_size_from_code(Arch arch, DW_Reg reg_code);
|
internal U64 dw_reg_size_from_code(Arch arch, DW_Reg reg_code);
|
||||||
|
|||||||
+1375
-1398
File diff suppressed because it is too large
Load Diff
+143
-266
@@ -4,298 +4,175 @@
|
|||||||
#ifndef DWARF_EXPR_H
|
#ifndef DWARF_EXPR_H
|
||||||
#define DWARF_EXPR_H
|
#define DWARF_EXPR_H
|
||||||
|
|
||||||
////////////////////////////////
|
typedef struct DW_ExprContext
|
||||||
//~ Dwarf Register Layout
|
|
||||||
|
|
||||||
typedef struct DW_RegsX64
|
|
||||||
{
|
{
|
||||||
|
Arch arch;
|
||||||
|
DW_Format format;
|
||||||
|
U64 cfa;
|
||||||
|
U64 tls_base;
|
||||||
|
} DW_ExprContext;
|
||||||
|
|
||||||
|
#define DW_ExprValueType_IsSigned(x) ((x) == DW_ExprValueType_S8 || (x) == DW_ExprValueType_S16 || (x) == DW_ExprValueType_S32 || (x) == DW_ExprValueType_S64 || (x) == DW_ExprValueType_S128 || (x) == DW_ExprValueType_S256 || (x) == DW_ExprValueType_S512)
|
||||||
|
#define DW_ExprValueType_IsUnsigned(x) ((x) == DW_ExprValueType_U8 || (x) == DW_ExprValueType_U16 || (x) == DW_ExprValueType_U32 || (x) == DW_ExprValueType_U64 || (x) == DW_ExprValueType_U128 || (x) == DW_ExprValueType_U256 || (x) == DW_ExprValueType_U512)
|
||||||
|
#define DW_ExprValueType_IsFloat(x) ((x) == DW_ExprValueType_F32 || (x) == DW_ExprValueType_F64)
|
||||||
|
#define DW_ExprValueType_IsInt(x) (DW_ExprValueType_IsSigned(x) || DW_ExprValueType_IsUnsigned(x) || (x) == DW_ExprValueType_Addr)
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
DW_ExprValueType_Generic,
|
||||||
|
DW_ExprValueType_U8,
|
||||||
|
DW_ExprValueType_U16,
|
||||||
|
DW_ExprValueType_U32,
|
||||||
|
DW_ExprValueType_U64,
|
||||||
|
DW_ExprValueType_U128,
|
||||||
|
DW_ExprValueType_U256,
|
||||||
|
DW_ExprValueType_U512,
|
||||||
|
DW_ExprValueType_S8,
|
||||||
|
DW_ExprValueType_S16,
|
||||||
|
DW_ExprValueType_S32,
|
||||||
|
DW_ExprValueType_S64,
|
||||||
|
DW_ExprValueType_S128,
|
||||||
|
DW_ExprValueType_S256,
|
||||||
|
DW_ExprValueType_S512,
|
||||||
|
DW_ExprValueType_F32,
|
||||||
|
DW_ExprValueType_F64,
|
||||||
|
DW_ExprValueType_Addr,
|
||||||
|
DW_ExprValueType_Implicit,
|
||||||
|
DW_ExprValueType_Bool,
|
||||||
|
} DW_ExprValueType;
|
||||||
|
|
||||||
|
typedef S8 DW_ExprBool;
|
||||||
|
|
||||||
|
typedef struct DW_ExprValue
|
||||||
|
{
|
||||||
|
DW_ExprValueType type;
|
||||||
union {
|
union {
|
||||||
struct {
|
U8 u8;
|
||||||
U64 rax;
|
U16 u16;
|
||||||
U64 rdx;
|
U32 u32;
|
||||||
U64 rcx;
|
U64 u64;
|
||||||
U64 rbx;
|
U128 u128;
|
||||||
U64 rsi;
|
U256 u256;
|
||||||
U64 rdi;
|
U512 u512;
|
||||||
U64 rbp;
|
S8 s8;
|
||||||
U64 rsp;
|
S16 s16;
|
||||||
U64 r8;
|
S32 s32;
|
||||||
U64 r9;
|
S64 s64;
|
||||||
U64 r10;
|
F32 f32;
|
||||||
U64 r11;
|
F64 f64;
|
||||||
U64 r12;
|
U64 addr;
|
||||||
U64 r13;
|
DW_ExprBool boolean;
|
||||||
U64 r14;
|
String8 implicit;
|
||||||
U64 r15;
|
String8 generic;
|
||||||
U64 rip;
|
|
||||||
};
|
|
||||||
U64 r[17];
|
|
||||||
};
|
};
|
||||||
} DW_RegsX64;
|
} DW_ExprValue;
|
||||||
|
|
||||||
////////////////////////////////
|
typedef struct DW_ExprValueNode
|
||||||
//~ Dwarf Expression Eval Types
|
|
||||||
|
|
||||||
#define DW_READ_MEMORY_SIG(name) U64 name(U64 addr, U64 size, void *out, void *ud)
|
|
||||||
typedef DW_READ_MEMORY_SIG(DW_ReadMemorySig);
|
|
||||||
|
|
||||||
//- machine configuration types
|
|
||||||
typedef String8 DW_ExprResolveCallFunc(void *call_user_ptr, U64 p);
|
|
||||||
|
|
||||||
typedef struct DW_ExprMachineCallConfig
|
|
||||||
{
|
{
|
||||||
void *user_ptr;
|
DW_ExprValue v;
|
||||||
DW_ExprResolveCallFunc *func;
|
struct DW_ExprValueNode *next;
|
||||||
} DW_ExprMachineCallConfig;
|
} DW_ExprValueNode;
|
||||||
|
|
||||||
typedef struct DW_ExprMachineConfig
|
|
||||||
{
|
|
||||||
U64 max_step_count; // (read only in the eval functions)
|
|
||||||
DW_ReadMemorySig *read_memory;
|
|
||||||
void *read_memory_ud;
|
|
||||||
DW_RegsX64 *regs;
|
|
||||||
U64 *text_section_base;
|
|
||||||
U64 *frame_base;
|
|
||||||
U64 *object_address;
|
|
||||||
U64 *tls_address;
|
|
||||||
U64 *cfa;
|
|
||||||
DW_ExprMachineCallConfig call;
|
|
||||||
} DW_ExprMachineConfig;
|
|
||||||
|
|
||||||
|
|
||||||
//- detail analysis types
|
|
||||||
typedef U32 DW_ExprFlags;
|
|
||||||
enum
|
|
||||||
{
|
|
||||||
DW_ExprFlag_UsesTextBase = (1 << 0),
|
|
||||||
DW_ExprFlag_UsesMemory = (1 << 1),
|
|
||||||
DW_ExprFlag_UsesRegisters = (1 << 2),
|
|
||||||
DW_ExprFlag_UsesFrameBase = (1 << 3),
|
|
||||||
DW_ExprFlag_UsesObjectAddress = (1 << 4),
|
|
||||||
DW_ExprFlag_UsesTLSAddress = (1 << 5),
|
|
||||||
DW_ExprFlag_UsesCFA = (1 << 6),
|
|
||||||
DW_ExprFlag_UsesCallResolution = (1 << 7),
|
|
||||||
DW_ExprFlag_UsesComposite = (1 << 8),
|
|
||||||
|
|
||||||
DW_ExprFlag_NotSupported = (1 << 16),
|
|
||||||
DW_ExprFlag_BadData = (1 << 17),
|
|
||||||
DW_ExprFlag_NonLinearFlow = (1 << 18)
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef struct DW_ExprAnalysis
|
|
||||||
{
|
|
||||||
DW_ExprFlags flags;
|
|
||||||
} DW_ExprAnalysis;
|
|
||||||
|
|
||||||
typedef struct DW_ExprAnalysisTask
|
|
||||||
{
|
|
||||||
struct DW_ExprAnalysisTask *next;
|
|
||||||
U64 p;
|
|
||||||
String8 data;
|
|
||||||
} DW_ExprAnalysisTask;
|
|
||||||
|
|
||||||
|
|
||||||
//- location types
|
|
||||||
typedef enum DW_SimpleLocKind
|
|
||||||
{
|
|
||||||
DW_SimpleLocKind_Address,
|
|
||||||
DW_SimpleLocKind_Register,
|
|
||||||
DW_SimpleLocKind_Value,
|
|
||||||
DW_SimpleLocKind_ValueLong,
|
|
||||||
DW_SimpleLocKind_Empty,
|
|
||||||
DW_SimpleLocKind_Fail,
|
|
||||||
} DW_SimpleLocKind;
|
|
||||||
|
|
||||||
typedef enum DW_LocFailKind
|
|
||||||
{
|
|
||||||
// Interpreting Fail Kinds
|
|
||||||
//
|
|
||||||
// BadData: the evaluator detected that the dwarf expression operation is incorrectly formed
|
|
||||||
// NotSupported: the evaluator does not support a dwarf feature that was found in the dwarf expression
|
|
||||||
// TimeOut: the evaluator hit the maximum step count
|
|
||||||
// TooComplicated: used by analyzer when it the expression uses features outside of the analyzer's scope
|
|
||||||
// Missing*: the dwarf machine config was missing necessary information to finish the evaluation
|
|
||||||
|
|
||||||
DW_LocFailKind_BadData,
|
|
||||||
DW_LocFailKind_NotSupported,
|
|
||||||
DW_LocFailKind_TimeOut,
|
|
||||||
DW_LocFailKind_TooComplicated,
|
|
||||||
DW_LocFailKind_MissingTextBase,
|
|
||||||
DW_LocFailKind_MissingMemory,
|
|
||||||
DW_LocFailKind_MissingRegisters,
|
|
||||||
DW_LocFailKind_MissingFrameBase,
|
|
||||||
DW_LocFailKind_MissingObjectAddress,
|
|
||||||
DW_LocFailKind_MissingTLSAddress,
|
|
||||||
DW_LocFailKind_MissingCFA,
|
|
||||||
DW_LocFailKind_MissingCallResolution,
|
|
||||||
DW_LocFailKind_MissingArenaForComposite,
|
|
||||||
} DW_LocFailKind;
|
|
||||||
|
|
||||||
typedef struct DW_SimpleLoc
|
|
||||||
{
|
|
||||||
DW_SimpleLocKind kind;
|
|
||||||
union {
|
|
||||||
U64 addr;
|
|
||||||
U64 reg_idx;
|
|
||||||
U64 val;
|
|
||||||
String8 val_long;
|
|
||||||
struct {
|
|
||||||
DW_LocFailKind fail_kind;
|
|
||||||
U64 fail_data;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
} DW_SimpleLoc;
|
|
||||||
|
|
||||||
typedef struct DW_Piece
|
|
||||||
{
|
|
||||||
// Hint for Interpreting Pieces
|
|
||||||
//
|
|
||||||
// src = decode(loc, is_bit_loc, bit_size);
|
|
||||||
// dst |= (src >> bit_off) << bit_cursor;
|
|
||||||
// bit_cursor += bit_size;
|
|
||||||
|
|
||||||
struct DW_Piece *next;
|
|
||||||
DW_SimpleLoc loc;
|
|
||||||
U64 bit_size;
|
|
||||||
U64 bit_off;
|
|
||||||
B32 is_bit_loc;
|
|
||||||
} DW_Piece;
|
|
||||||
|
|
||||||
typedef struct DW_Location
|
|
||||||
{
|
|
||||||
// Interpreting a Dwarf Location
|
|
||||||
//
|
|
||||||
// CASE (any number of pieces, fail in the non-piece):
|
|
||||||
// this is how errors are reported, error information is in the non-piece
|
|
||||||
// the 'fail' location kind should never show up in a piece
|
|
||||||
// if there are any pieces they can be treated as correct information that
|
|
||||||
// was successfully decoded before the error was encountered
|
|
||||||
//
|
|
||||||
// CASE (no pieces, empty non-piece):
|
|
||||||
// the data is completely optimized out and unrecoverable
|
|
||||||
//
|
|
||||||
// CASE (no pieces, non-empty non-piece):
|
|
||||||
// the size of the data is not known by the location, but something in the
|
|
||||||
// surrounding context of the location (eg type info) should know the size
|
|
||||||
//
|
|
||||||
// CASE (one-or-more pieces, empty non-piece):
|
|
||||||
// the data is described by the pieces
|
|
||||||
//
|
|
||||||
// CASE (one-or-more pieces, non-empty non-fail non-piece):
|
|
||||||
// this is supposed to be impossible; the non-piece either carries an error
|
|
||||||
// or *all* of the location information about the data, there should never
|
|
||||||
// be a mix of piece-based location and non-piece-based location data.
|
|
||||||
|
|
||||||
DW_Piece *first_piece;
|
|
||||||
DW_Piece *last_piece;
|
|
||||||
U64 count;
|
|
||||||
|
|
||||||
DW_SimpleLoc non_piece_loc;
|
|
||||||
} DW_Location;
|
|
||||||
|
|
||||||
|
|
||||||
//- full evaluator state types
|
|
||||||
typedef struct DW_ExprStackNode
|
|
||||||
{
|
|
||||||
struct DW_ExprStackNode *next;
|
|
||||||
U64 val;
|
|
||||||
} DW_ExprStackNode;
|
|
||||||
|
|
||||||
typedef struct DW_ExprStack
|
typedef struct DW_ExprStack
|
||||||
{
|
{
|
||||||
DW_ExprStackNode *stack;
|
|
||||||
DW_ExprStackNode *free_nodes;
|
|
||||||
U64 count;
|
U64 count;
|
||||||
|
DW_ExprValueNode *top;
|
||||||
} DW_ExprStack;
|
} DW_ExprStack;
|
||||||
|
|
||||||
typedef struct DW_ExprCall
|
typedef enum
|
||||||
{
|
{
|
||||||
struct DW_ExprCall *next;
|
DW_PieceKind_Null,
|
||||||
void *ptr;
|
DW_PieceKind_Value,
|
||||||
U64 size;
|
DW_PieceKind_Undefined,
|
||||||
U64 cursor;
|
} DW_PieceKind;
|
||||||
} DW_ExprCall;
|
|
||||||
|
|
||||||
typedef struct DW_ExprCallStack
|
typedef struct DW_Piece
|
||||||
{
|
{
|
||||||
DW_ExprCall *stack;
|
DW_PieceKind kind;
|
||||||
DW_ExprCall *free_calls;
|
union {
|
||||||
U64 depth;
|
U64 undef_bit_size;
|
||||||
} DW_ExprCallStack;
|
struct {
|
||||||
|
U64 bit_size;
|
||||||
|
void *ptr;
|
||||||
|
} value;
|
||||||
|
};
|
||||||
|
} DW_Piece;
|
||||||
|
|
||||||
|
typedef struct DW_PieceNode
|
||||||
|
{
|
||||||
|
DW_Piece v;
|
||||||
|
struct DW_PieceNode *next;
|
||||||
|
} DW_PieceNode;
|
||||||
|
|
||||||
|
typedef struct DW_PieceList
|
||||||
|
{
|
||||||
|
U64 count;
|
||||||
|
DW_PieceNode *first;
|
||||||
|
DW_PieceNode *last;
|
||||||
|
} DW_PieceList;
|
||||||
|
|
||||||
|
typedef struct DW_ExprResult
|
||||||
|
{
|
||||||
|
int x;
|
||||||
|
} DW_ExprResult;
|
||||||
|
|
||||||
////////////////////////////////
|
////////////////////////////////
|
||||||
//~ Dwarf Expression Analysis & Eval Functions
|
|
||||||
|
|
||||||
//- analyzers
|
// pieces
|
||||||
|
internal DW_PieceNode * dw_piece_list_push(Arena *arena, DW_PieceList *list, DW_Piece v);
|
||||||
|
|
||||||
// This analyzer provides the most simplified dwarf expression
|
// size -> type
|
||||||
// decoding. If the expression consists of a single op that can be interpreted
|
internal DW_ExprValueType dw_expr_unsigned_value_type_from_bit_size(U64 bit_size);
|
||||||
// as a valid dwarf expression, then it represents that expression as a simple
|
internal DW_ExprValueType dw_expr_signed_value_type_from_bit_size(U64 bit_size);
|
||||||
// location.
|
internal DW_ExprValueType dw_expr_float_type_from_bit_size(U64 bit_size);
|
||||||
//
|
|
||||||
// If there is a single 'piece' op that is represeted here as an empty simple
|
|
||||||
// location, losing whatever additional size information from the piece.
|
|
||||||
//
|
|
||||||
// If there is an op that requires the machine configuration data the analyzer
|
|
||||||
// fails with "too complicated" - unless the required configuration data is the
|
|
||||||
// text section base which this analyzer treats as a non-optional parameter and
|
|
||||||
// always decodes successfully.
|
|
||||||
//
|
|
||||||
// If the expression contains more than one op than the analyzer fails with
|
|
||||||
// "too complicated".
|
|
||||||
|
|
||||||
internal DW_SimpleLoc dw_expr__analyze_fast(void *base, Rng1U64 range, U64 text_section_base);
|
// type -> size
|
||||||
|
internal U64 dw_expr_byte_size_from_value_type(U64 addr_size, DW_ExprValueType k);
|
||||||
|
|
||||||
// This analyzer does a one-pass scan through the expression to
|
// typer
|
||||||
// help a caller determine what to expect before doing a full evaluation which
|
internal DW_ExprValueType dw_expr_pick_common_value_type(DW_ExprValueType lhs, DW_ExprValueType rhs);
|
||||||
// has to maintain value stacks, perform more checks, and execute any loops
|
internal DW_ExprValueType dw_expr_pick_common_comparison_value_type(DW_ExprValueType lhs, DW_ExprValueType rhs);
|
||||||
// that may appear in the expression, etc.
|
internal DW_ExprValue dw_expr_cast(DW_ExprValue value, DW_ExprValueType type);
|
||||||
//
|
|
||||||
// For each piece of data that can be equipped to a machine config there is a
|
|
||||||
// 'Uses' flag in the analysis. A user can use these flags to determine what to
|
|
||||||
// prepare and equip before a full eval. This can be a lot more efficient than
|
|
||||||
// always preparing everything, or iteratively equipping and retrying after
|
|
||||||
// each failure.
|
|
||||||
//
|
|
||||||
// The analysis can also catch some cases of bad data and unsupported features.
|
|
||||||
// These flags are useful for short circuit style optimizations, but they are
|
|
||||||
// not definitive, some bad data can only be caught by the full evaluator.
|
|
||||||
// Sometimes the full evaluator might miss bad data that this analyzer will see
|
|
||||||
// if control flow in the evaluator completely skips the bad data. A forgiving
|
|
||||||
// interpretation of dwarf expression data would only rely on the results of
|
|
||||||
// the full evaluator. A more strict interpretation would consider it an error
|
|
||||||
// if either this analyzer or the evaluator finds bad data.
|
|
||||||
//
|
|
||||||
// The analyzer also determines if there is any possibility for non-linear
|
|
||||||
// flow. Jumps, branches, and call ops all create non-linear flow. An
|
|
||||||
// expression that doesn't have non-linear flow is trivially gauranteed to
|
|
||||||
// terminate and therefore a good candidate for conversion to a human readable
|
|
||||||
// expression.
|
|
||||||
//
|
|
||||||
// The call config is optional (may be null). If is provided the analysis
|
|
||||||
// includes features seen in all of the expressions that might be reached by
|
|
||||||
// call ops from the initial expression.
|
|
||||||
|
|
||||||
internal DW_ExprAnalysis dw_expr__analyze_details(void *base, Rng1U64 range, DW_ExprMachineCallConfig *call_config);
|
// arithmetic operators
|
||||||
|
internal DW_ExprValue dw_expr_add(DW_ExprValue lhs, DW_ExprValue rhs);
|
||||||
|
internal DW_ExprValue dw_expr_minus(DW_ExprValue lhs, DW_ExprValue rhs);
|
||||||
|
internal DW_ExprValue dw_expr_mul(DW_ExprValue lhs, DW_ExprValue rhs);
|
||||||
|
internal DW_ExprValue dw_expr_div(DW_ExprValue lhs, DW_ExprValue rhs);
|
||||||
|
internal DW_ExprValue dw_expr_mod(DW_ExprValue lhs, DW_ExprValue rhs);
|
||||||
|
|
||||||
//- full eval
|
// comparison operators
|
||||||
internal DW_Location dw_expr__eval(Arena *arena_optional, void *base, Rng1U64 range, DW_ExprMachineConfig *config);
|
internal DW_ExprValue dw_expr_eq(DW_ExprValue lhs, DW_ExprValue rhs);
|
||||||
|
internal DW_ExprValue dw_expr_ge(DW_ExprValue lhs, DW_ExprValue rhs);
|
||||||
|
internal DW_ExprValue dw_expr_gt(DW_ExprValue lhs, DW_ExprValue rhs);
|
||||||
|
internal DW_ExprValue dw_expr_le(DW_ExprValue lhs, DW_ExprValue rhs);
|
||||||
|
internal DW_ExprValue dw_expr_lt(DW_ExprValue lhs, DW_ExprValue rhs);
|
||||||
|
internal DW_ExprValue dw_expr_ne(DW_ExprValue lhs, DW_ExprValue rhs);
|
||||||
|
|
||||||
//- dw expr val stack
|
// bitwise operators
|
||||||
internal DW_ExprStack dw_expr__stack_make(Arena *arena);
|
internal DW_ExprValue dw_expr_xor(DW_ExprValue lhs, DW_ExprValue rhs);
|
||||||
internal void dw_expr__stack_push(Arena *arena, DW_ExprStack *stack, U64 x);
|
internal DW_ExprValue dw_expr_and(DW_ExprValue lhs, DW_ExprValue rhs);
|
||||||
internal U64 dw_expr__stack_pop(DW_ExprStack *stack);
|
internal DW_ExprValue dw_expr_or(DW_ExprValue lhs, DW_ExprValue rhs);
|
||||||
internal U64 dw_expr__stack_pick(DW_ExprStack *stack, U64 idx);
|
internal DW_ExprValue dw_expr_shl(DW_ExprValue lhs, DW_ExprValue rhs);
|
||||||
internal B32 dw_expr__stack_is_empty(DW_ExprStack *stack);
|
internal DW_ExprValue dw_expr_shr(DW_ExprValue lhs, DW_ExprValue rhs);
|
||||||
|
internal DW_ExprValue dw_expr_shra(DW_ExprValue lhs, DW_ExprValue rhs);
|
||||||
|
|
||||||
//- dw expr call stack
|
// unary operators
|
||||||
internal DW_ExprCall* dw_expr__call_top(DW_ExprCallStack *stack);
|
internal DW_ExprValue dw_expr_abs(DW_ExprValue value);
|
||||||
internal void dw_expr__call_push(Arena *arena, DW_ExprCallStack *stack, void *ptr, U64 size);
|
internal DW_ExprValue dw_expr_neg(DW_ExprValue value);
|
||||||
internal void dw_expr__call_pop(DW_ExprCallStack *stack);
|
internal DW_ExprValue dw_expr_not(DW_ExprValue value);
|
||||||
|
|
||||||
|
// stack
|
||||||
|
internal DW_ExprValueNode * dw_expr_stack_push(Arena *arena, DW_ExprStack *stack, DW_ExprValue value);
|
||||||
|
internal DW_ExprValueNode * dw_expr_stack_push_unsigned(Arena *arena, DW_ExprStack *stack, void *value, U64 value_size);
|
||||||
|
internal DW_ExprValue dw_expr_stack_pop(DW_ExprStack *stack);
|
||||||
|
internal DW_ExprValue dw_expr_stack_peek(DW_ExprStack *stack);
|
||||||
|
internal DW_ExprValueNode * dw_expr_stack_pick(DW_ExprStack *stack, U64 idx);
|
||||||
|
|
||||||
//- analysis tasks
|
// value helpers
|
||||||
internal DW_ExprAnalysisTask* dw_expr__analysis_task_from_p(DW_ExprAnalysisTask *first, U64 p);
|
internal String8 dw_string_from_expr_value(Arena *arena, U64 addr_size, DW_ExprValue v);
|
||||||
|
|
||||||
|
// 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);
|
||||||
|
|
||||||
#endif //DWARF_EXPR_H
|
#endif //DWARF_EXPR_H
|
||||||
|
|
||||||
|
|||||||
@@ -2,8 +2,8 @@
|
|||||||
// Licensed under the MIT license (https://opensource.org/license/mit/)
|
// Licensed under the MIT license (https://opensource.org/license/mit/)
|
||||||
|
|
||||||
#include "dwarf/dwarf.c"
|
#include "dwarf/dwarf.c"
|
||||||
#include "dwarf/dwarf_expr.c"
|
|
||||||
#include "dwarf/dwarf_parse.c"
|
#include "dwarf/dwarf_parse.c"
|
||||||
|
#include "dwarf/dwarf_expr.c"
|
||||||
#include "dwarf/dwarf_coff.c"
|
#include "dwarf/dwarf_coff.c"
|
||||||
#include "dwarf/dwarf_elf.c"
|
#include "dwarf/dwarf_elf.c"
|
||||||
#include "dwarf/dwarf_unwind.c"
|
#include "dwarf/dwarf_unwind.c"
|
||||||
|
|||||||
@@ -5,8 +5,8 @@
|
|||||||
#define DWARF_INC_H
|
#define DWARF_INC_H
|
||||||
|
|
||||||
#include "dwarf/dwarf.h"
|
#include "dwarf/dwarf.h"
|
||||||
#include "dwarf/dwarf_expr.h"
|
|
||||||
#include "dwarf/dwarf_parse.h"
|
#include "dwarf/dwarf_parse.h"
|
||||||
|
#include "dwarf/dwarf_expr.h"
|
||||||
#include "dwarf/dwarf_coff.h"
|
#include "dwarf/dwarf_coff.h"
|
||||||
#include "dwarf/dwarf_elf.h"
|
#include "dwarf/dwarf_elf.h"
|
||||||
#include "dwarf/dwarf_unwind.h"
|
#include "dwarf/dwarf_unwind.h"
|
||||||
|
|||||||
@@ -65,21 +65,6 @@ typedef struct DW_CFI_Unwind
|
|||||||
U64 reg_count;
|
U64 reg_count;
|
||||||
} DW_CFI_Unwind;
|
} DW_CFI_Unwind;
|
||||||
|
|
||||||
typedef enum {
|
|
||||||
DW_UnwindStatus_Ok,
|
|
||||||
DW_UnwindStatus_Fail,
|
|
||||||
DW_UnwindStatus_Maybe
|
|
||||||
} DW_UnwindStatus;
|
|
||||||
|
|
||||||
#define DW_REG_READ(name) DW_UnwindStatus name(DW_Reg reg_id, void *buffer, U64 buffer_max, void *ud)
|
|
||||||
typedef DW_REG_READ(DW_RegRead);
|
|
||||||
|
|
||||||
#define DW_REG_WRITE(name) DW_UnwindStatus name(DW_Reg reg_id, void *value, U64 value_size, void *ud)
|
|
||||||
typedef DW_REG_WRITE(DW_RegWrite);
|
|
||||||
|
|
||||||
#define DW_MEM_READ(name) DW_UnwindStatus name(U64 addr, U64 size, void *buffer, void *ud)
|
|
||||||
typedef DW_MEM_READ(DW_MemRead);
|
|
||||||
|
|
||||||
////////////////////////////////
|
////////////////////////////////
|
||||||
|
|
||||||
internal DW_CFI_Row * dw_make_cfi_row(Arena *arena, U64 reg_count);
|
internal DW_CFI_Row * dw_make_cfi_row(Arena *arena, U64 reg_count);
|
||||||
|
|||||||
Reference in New Issue
Block a user