reading & organization pass over unwinding layer; deduplicate PE info with PE layer, move dwarf info to in-progress dwarf layer

This commit is contained in:
Ryan Fleury
2024-03-25 14:42:54 -07:00
parent 1c3792a3da
commit 55146b547b
4 changed files with 645 additions and 718 deletions
+161
View File
@@ -1260,6 +1260,167 @@ if (success__) \
(x) = dwarf_leb128_decode(T,first__, (p)); \
}while(0)
////////////////////////////////
//~ allen: ELF/DW Unwind Types
//
// TODO(rjf): OLD TYPES FROM UNWINDER CODE. bucketing this here, and deferring dwarf-based
// unwinding info to future DWARF/linux work.
//
#if 0
// * applies to (any X: unwind(ELF/DW, X))
// EH: Exception Frames
typedef U8 UNW_DW_EhPtrEnc;
enum{
UNW_DW_EhPtrEnc_TYPE_MASK = 0x0F,
UNW_DW_EhPtrEnc_PTR = 0x00, // Pointer sized unsigned value
UNW_DW_EhPtrEnc_ULEB128 = 0x01, // Unsigned LE base-128 value
UNW_DW_EhPtrEnc_UDATA2 = 0x02, // Unsigned 16-bit value
UNW_DW_EhPtrEnc_UDATA4 = 0x03, // Unsigned 32-bit value
UNW_DW_EhPtrEnc_UDATA8 = 0x04, // Unsigned 64-bit value
UNW_DW_EhPtrEnc_SIGNED = 0x08, // Signed pointer
UNW_DW_EhPtrEnc_SLEB128 = 0x09, // Signed LE base-128 value
UNW_DW_EhPtrEnc_SDATA2 = 0x0A, // Signed 16-bit value
UNW_DW_EhPtrEnc_SDATA4 = 0x0B, // Signed 32-bit value
UNW_DW_EhPtrEnc_SDATA8 = 0x0C, // Signed 64-bit value
};
enum{
UNW_DW_EhPtrEnc_MODIF_MASK = 0x70,
UNW_DW_EhPtrEnc_PCREL = 0x10, // Value is relative to the current program counter.
UNW_DW_EhPtrEnc_TEXTREL = 0x20, // Value is relative to the .text section.
UNW_DW_EhPtrEnc_DATAREL = 0x30, // Value is relative to the .got or .eh_frame_hdr section.
UNW_DW_EhPtrEnc_FUNCREL = 0x40, // Value is relative to the function.
UNW_DW_EhPtrEnc_ALIGNED = 0x50, // Value is aligned to an address unit sized boundary.
};
enum{
UNW_DW_EhPtrEnc_INDIRECT = 0x80, // This flag indicates that value is stored in virtual memory.
UNW_DW_EhPtrEnc_OMIT = 0xFF,
};
typedef struct UNW_DW_EhPtrCtx{
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
} UNW_DW_EhPtrCtx;
// CIE: Common Information Entry
typedef struct UNW_DW_CIEUnpacked{
U8 version;
UNW_DW_EhPtrEnc lsda_encoding;
UNW_DW_EhPtrEnc addr_encoding;
B8 has_augmentation_size;
U64 augmentation_size;
String8 augmentation;
U64 code_align_factor;
S64 data_align_factor;
U64 ret_addr_reg;
U64 handler_ip;
U64 cfi_range_min;
U64 cfi_range_max;
} UNW_DW_CIEUnpacked;
typedef struct UNW_DW_CIEUnpackedNode{
struct UNW_DW_CIEUnpackedNode *next;
UNW_DW_CIEUnpacked cie;
U64 offset;
} UNW_DW_CIEUnpackedNode;
// FDE: Frame Description Entry
typedef struct UNW_DW_FDEUnpacked{
U64 ip_voff_min;
U64 ip_voff_max;
U64 lsda_ip;
U64 cfi_range_min;
U64 cfi_range_max;
} UNW_DW_FDEUnpacked;
// CFI: Call Frame Information
typedef struct UNW_DW_CFIRecords{
B32 valid;
UNW_DW_CIEUnpacked cie;
UNW_DW_FDEUnpacked fde;
} UNW_DW_CFIRecords;
typedef enum UNW_DW_CFICFARule{
UNW_DW_CFICFARule_REGOFF,
UNW_DW_CFICFARule_EXPR,
} UNW_DW_CFICFARule;
typedef struct UNW_DW_CFICFACell{
UNW_DW_CFICFARule rule;
union{
struct{
U64 reg_idx;
S64 offset;
};
U64 expr_min;
U64 expr_max;
};
} UNW_DW_CFICFACell;
typedef enum UNW_DW_CFIRegisterRule{
UNW_DW_CFIRegisterRule_SAME_VALUE,
UNW_DW_CFIRegisterRule_UNDEFINED,
UNW_DW_CFIRegisterRule_OFFSET,
UNW_DW_CFIRegisterRule_VAL_OFFSET,
UNW_DW_CFIRegisterRule_REGISTER,
UNW_DW_CFIRegisterRule_EXPRESSION,
UNW_DW_CFIRegisterRule_VAL_EXPRESSION,
} UNW_DW_CFIRegisterRule;
typedef struct UNW_DW_CFICell{
UNW_DW_CFIRegisterRule rule;
union{
S64 n;
struct{
U64 expr_min;
U64 expr_max;
};
};
} UNW_DW_CFICell;
typedef struct UNW_DW_CFIRow{
struct UNW_DW_CFIRow *next;
UNW_DW_CFICell *cells;
UNW_DW_CFICFACell cfa_cell;
} UNW_DW_CFIRow;
typedef struct UNW_DW_CFIMachine{
U64 cells_per_row;
UNW_DW_CIEUnpacked *cie;
UNW_DW_EhPtrCtx *ptr_ctx;
UNW_DW_CFIRow *initial_row;
U64 fde_ip;
} UNW_DW_CFIMachine;
typedef U8 UNW_DW_CFADecode;
enum{
UNW_DW_CFADecode_NOP = 0x0,
// 1,2,4,8 reserved for literal byte sizes
UNW_DW_CFADecode_ADDRESS = 0x9,
UNW_DW_CFADecode_ULEB128 = 0xA,
UNW_DW_CFADecode_SLEB128 = 0xB,
};
typedef U16 UNW_DW_CFAControlBits;
enum{
UNW_DW_CFAControlBits_DEC1_MASK = 0x00F,
UNW_DW_CFAControlBits_DEC2_MASK = 0x0F0,
UNW_DW_CFAControlBits_IS_REG_0 = 0x100,
UNW_DW_CFAControlBits_IS_REG_1 = 0x200,
UNW_DW_CFAControlBits_IS_REG_2 = 0x400,
UNW_DW_CFAControlBits_NEW_ROW = 0x800,
};
#endif
////////////////////////////////
//~ Dwarf Parser Functions