Files
raddebugger/src/eh/eh_frame.h
T

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