mirror of
https://github.com/Ed94/raddebugger.git
synced 2026-09-24 02:00:05 +00:00
123 lines
3.6 KiB
C
123 lines
3.6 KiB
C
// Copyright (c) Epic Games Tools
|
|
// Licensed under the MIT license (https://opensource.org/license/mit/)
|
|
|
|
#ifndef EH_FRAME_H
|
|
#define EH_FRAME_H
|
|
|
|
////////////////////////////////
|
|
//~ Format
|
|
|
|
typedef U8 EH_PtrEnc;
|
|
enum
|
|
{
|
|
EH_PtrEnc_Ptr = 0x00, // Pointer sized unsigned value
|
|
EH_PtrEnc_ULEB128 = 0x01, // Unsigned LE base-128 value
|
|
EH_PtrEnc_UData2 = 0x02, // Unsigned 16-bit value
|
|
EH_PtrEnc_UData4 = 0x03, // Unsigned 32-bit value
|
|
EH_PtrEnc_UData8 = 0x04, // Unsigned 64-bit value
|
|
EH_PtrEnc_Signed = 0x08, // Signed pointer
|
|
EH_PtrEnc_SLEB128 = 0x09, // Signed LE base-128 value
|
|
EH_PtrEnc_SData2 = 0x0A, // Signed 16-bit value
|
|
EH_PtrEnc_SData4 = 0x0B, // Signed 32-bit value
|
|
EH_PtrEnc_SData8 = 0x0C, // Signed 64-bit value
|
|
|
|
EH_PtrEnc_TypeMask = 0x0F,
|
|
};
|
|
|
|
enum
|
|
{
|
|
EH_PtrEnc_PcRel = 0x10, // Value is relative to the current program counter.
|
|
EH_PtrEnc_TextRel = 0x20, // Value is relative to the .text section.
|
|
EH_PtrEnc_DataRel = 0x30, // Value is relative to the .got or .eh_frame_hdr section.
|
|
EH_PtrEnc_FuncRel = 0x40, // Value is relative to the function.
|
|
EH_PtrEnc_Aligned = 0x50, // Value is aligned to an address unit sized boundary.
|
|
|
|
EH_PtrEnc_ModifierMask = 0x70,
|
|
};
|
|
|
|
enum
|
|
{
|
|
EH_PtrEnc_Indirect = 0x80, // Value is stored in virtual memory.
|
|
EH_PtrEnc_Omit = 0xFF,
|
|
};
|
|
|
|
typedef struct EH_PtrCtx
|
|
{
|
|
U64 raw_base_vaddr; // address where pointer is being read
|
|
U64 text_vaddr; // base address of section with instructions (used for encoding pointer on SH and IA64)
|
|
U64 data_vaddr; // base address of data section (used for encoding pointer on x86-64)
|
|
U64 func_vaddr; // base address of function where IP is located
|
|
U64 ptr_align;
|
|
} EH_PtrCtx;
|
|
|
|
typedef U8 EH_AugFlags;
|
|
enum
|
|
{
|
|
EH_AugFlag_HasLSDA = (1 << 0),
|
|
EH_AugFlag_HasHandler = (1 << 1),
|
|
EH_AugFlag_HasAddrEnc = (1 << 2),
|
|
};
|
|
|
|
typedef struct EH_Augmentation
|
|
{
|
|
EH_AugFlags flags;
|
|
U64 handler_ip;
|
|
EH_PtrEnc handler_encoding;
|
|
EH_PtrEnc lsda_encoding;
|
|
EH_PtrEnc addr_encoding;
|
|
} EH_Augmentation;
|
|
|
|
////////////////////////////////
|
|
//~ Parser
|
|
|
|
enum
|
|
{
|
|
EH_CIE_Ext_AddrEnc,
|
|
EH_CIE_Ext_LSDAEnc,
|
|
EH_CIE_Ext_HandlerEnc,
|
|
EH_CIE_Ext_HandlerIp,
|
|
} EH_CIE_Ext;
|
|
|
|
typedef struct EH_FrameHdrEntry
|
|
{
|
|
U64 addr;
|
|
U64 fde_offset;
|
|
} EH_FrameHdrEntry;
|
|
|
|
typedef struct EH_FrameHdr
|
|
{
|
|
U8 version;
|
|
EH_PtrEnc eh_frame_ptr_enc;
|
|
EH_PtrEnc fde_count_enc;
|
|
EH_PtrEnc table_enc;
|
|
U64 field_byte_size;
|
|
U64 entry_byte_size;
|
|
U64 fde_count;
|
|
String8 table;
|
|
} EH_FrameHdr;
|
|
|
|
typedef struct EH_DecodePtrCtx
|
|
{
|
|
EH_PtrEnc addr_enc;
|
|
EH_PtrCtx *ptr_ctx;
|
|
} EH_DecodePtrCtx;
|
|
|
|
////////////////////////////////
|
|
|
|
internal U64 eh_parse_ptr(String8 frame_base, U64 off, EH_PtrCtx *ptr_ctx, EH_PtrEnc encoding, U64 *ptr_out);
|
|
internal EH_FrameHdr eh_parse_frame_hdr(String8 data, U64 address_size, EH_PtrCtx *ptr_ctx);
|
|
internal U64 eh_parse_aug_data(String8 aug_string, String8 aug_data, EH_PtrCtx *ptr_ctx, EH_Augmentation *aug_out);
|
|
internal B32 eh_parse_cfi(String8 eh_frame, U64 fde_offset, Arch arch, EH_PtrCtx *ptr_ctx, struct DW_CIE *cie_out, struct DW_FDE *fde_out);
|
|
internal U64 eh_find_nearest_fde(EH_FrameHdr header, EH_PtrCtx *ptr_ctx, U64 pc);
|
|
internal String8 eh_frame_hdr_from_call_frame_info(Arena *arena, U64 fde_count, U64 *fde_offsets, struct DW_FDE *fde);
|
|
|
|
////////////////////////////////
|
|
//~ Enum -> String
|
|
|
|
internal String8 eh_string_from_ptr_enc_type(EH_PtrEnc type);
|
|
internal String8 eh_string_from_ptr_enc_modifier(EH_PtrEnc modifier);
|
|
internal String8 eh_string_from_ptr_enc(Arena *arena, EH_PtrEnc enc);
|
|
|
|
#endif // EH_FRAME_H
|
|
|