mirror of
https://github.com/Ed94/raddebugger.git
synced 2026-08-06 05:48:40 +00:00
begin process of moving pe unwinding info into pe layer; more demon2 work checkpoint
This commit is contained in:
+52
-44
@@ -1,6 +1,54 @@
|
||||
// Copyright (c) 2024 Epic Games Tools
|
||||
// Licensed under the MIT license (https://opensource.org/license/mit/)
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Basic Enum Functions
|
||||
|
||||
internal U32
|
||||
pe_slot_count_from_unwind_op_code(PE_UnwindOpCode opcode)
|
||||
{
|
||||
U32 result = 0;
|
||||
switch(opcode)
|
||||
{
|
||||
case PE_UnwindOpCode_PUSH_NONVOL: result = 1; break;
|
||||
case PE_UnwindOpCode_ALLOC_LARGE: result = 2; break;
|
||||
case PE_UnwindOpCode_ALLOC_SMALL: result = 1; break;
|
||||
case PE_UnwindOpCode_SET_FPREG: result = 1; break;
|
||||
case PE_UnwindOpCode_SAVE_NONVOL: result = 2; break;
|
||||
case PE_UnwindOpCode_SAVE_NONVOL_FAR: result = 3; break;
|
||||
case PE_UnwindOpCode_EPILOG: result = 2; break;
|
||||
case PE_UnwindOpCode_SPARE_CODE: result = 3; break;
|
||||
case PE_UnwindOpCode_SAVE_XMM128: result = 2; break;
|
||||
case PE_UnwindOpCode_SAVE_XMM128_FAR: result = 3; break;
|
||||
case PE_UnwindOpCode_PUSH_MACHFRAME: result = 1; break;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
internal String8
|
||||
pe_string_from_windows_subsystem(PE_WindowsSubsystem subsystem)
|
||||
{
|
||||
String8 result = {0};
|
||||
switch(subsystem)
|
||||
{
|
||||
default:{}break;
|
||||
case PE_WindowsSubsystem_UNKNOWN: result = str8_lit("UNKNOWN"); break;
|
||||
case PE_WindowsSubsystem_NATIVE: result = str8_lit("NATIVE"); break;
|
||||
case PE_WindowsSubsystem_WINDOWS_GUI: result = str8_lit("WINDOWS_GUI"); break;
|
||||
case PE_WindowsSubsystem_WINDOWS_CUI: result = str8_lit("WINDOWS_CUI"); break;
|
||||
case PE_WindowsSubsystem_OS2_CUI: result = str8_lit("OS2_CUI"); break;
|
||||
case PE_WindowsSubsystem_POSIX_CUI: result = str8_lit("POSIX_CUI"); break;
|
||||
case PE_WindowsSubsystem_NATIVE_WINDOWS: result = str8_lit("NATIVE_WINDOWS"); break;
|
||||
case PE_WindowsSubsystem_WINDOWS_CE_GUI: result = str8_lit("WINDOWS_CE_GUID"); break;
|
||||
case PE_WindowsSubsystem_EFI_APPLICATION: result = str8_lit("EFI_APPLICATION"); break;
|
||||
case PE_WindowsSubsystem_EFI_BOOT_SERVICE_DRIVER: result = str8_lit("EFI_BOOT_SERVICE_DRIVER"); break;
|
||||
case PE_WindowsSubsystem_EFI_ROM: result = str8_lit("EFI_ROM"); break;
|
||||
case PE_WindowsSubsystem_XBOX: result = str8_lit("XBOX"); break;
|
||||
case PE_WindowsSubsystem_WINDOWS_BOOT_APPLICATION: result = str8_lit("WINDOWS_BOOT_APPLICATION"); break;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Parser Functions
|
||||
|
||||
@@ -535,7 +583,7 @@ pe_resource_dir_push_dir_node(Arena *arena, PE_ResourceDir *dir, COFF_ResourceID
|
||||
|
||||
PE_Resource *res = &res_node->data;
|
||||
res->id = id;
|
||||
res->type = PE_ResData_DIR;
|
||||
res->kind = PE_ResDataKind_DIR;
|
||||
res->u.dir = sub_dir;
|
||||
|
||||
return res_node;
|
||||
@@ -558,7 +606,7 @@ pe_resource_dir_push_entry_node(Arena *arena, PE_ResourceDir *dir, COFF_Resource
|
||||
|
||||
PE_Resource *res = &res_node->data;
|
||||
res->id = id;
|
||||
res->type = PE_ResData_COFF_RESOURCE;
|
||||
res->kind = PE_ResDataKind_COFF_RESOURCE;
|
||||
res->u.coff_res.type = type;
|
||||
res->u.coff_res.data_version = data_version;
|
||||
res->u.coff_res.version = version;
|
||||
@@ -716,7 +764,7 @@ pe_resource_table_from_directory_data(Arena *arena, String8 data)
|
||||
|
||||
entry->id.type = COFF_ResourceIDType_STRING;
|
||||
entry->id.u.string = str8_from_16(arena, name16);
|
||||
entry->type = is_dir ? PE_ResData_DIR : PE_ResData_COFF_LEAF;
|
||||
entry->kind = is_dir ? PE_ResDataKind_DIR : PE_ResDataKind_COFF_LEAF;
|
||||
|
||||
if (is_dir) {
|
||||
struct stack_s *frame = push_array(scratch.arena, struct stack_s, 1);
|
||||
@@ -745,7 +793,7 @@ pe_resource_table_from_directory_data(Arena *arena, String8 data)
|
||||
|
||||
entry->id.type = COFF_ResourceIDType_NUMBER;
|
||||
entry->id.u.number = coff_entry.name.id;
|
||||
entry->type = is_dir ? PE_ResData_DIR : PE_ResData_COFF_LEAF;
|
||||
entry->kind = is_dir ? PE_ResDataKind_DIR : PE_ResDataKind_COFF_LEAF;
|
||||
|
||||
if (is_dir) {
|
||||
struct stack_s *frame = push_array(scratch.arena, struct stack_s, 1);
|
||||
@@ -766,43 +814,3 @@ pe_resource_table_from_directory_data(Arena *arena, String8 data)
|
||||
scratch_end(scratch);
|
||||
return bottom_frame->table;
|
||||
}
|
||||
|
||||
////////////////////////////////
|
||||
|
||||
internal String8
|
||||
pe_get_dos_program(void)
|
||||
{
|
||||
// generated from pe/dos_program.asm
|
||||
static U8 program[] = {
|
||||
0x0E, 0x1F, 0xBA, 0x0E, 0x00, 0xB4, 0x09, 0xCD, 0x21, 0xB8, 0x01, 0x4C, 0xCD, 0x21, 0x54, 0x68,
|
||||
0x69, 0x73, 0x20, 0x70, 0x72, 0x6F, 0x67, 0x72, 0x61, 0x6D, 0x20, 0x63, 0x61, 0x6E, 0x6E, 0x6F,
|
||||
0x74, 0x20, 0x62, 0x65, 0x20, 0x72, 0x75, 0x6E, 0x20, 0x69, 0x6E, 0x20, 0x44, 0x4F, 0x53, 0x20,
|
||||
0x6D, 0x6F, 0x64, 0x65, 0x2E, 0x24, 0x00, 0x00
|
||||
};
|
||||
return str8(program, sizeof(program));
|
||||
}
|
||||
|
||||
////////////////////////////////
|
||||
|
||||
internal String8
|
||||
pe_string_from_subsystem(PE_WindowsSubsystem subsystem)
|
||||
{
|
||||
switch (subsystem) {
|
||||
case PE_WindowsSubsystem_UNKNOWN: return str8_lit("UNKNOWN");
|
||||
case PE_WindowsSubsystem_NATIVE: return str8_lit("NATIVE");
|
||||
case PE_WindowsSubsystem_WINDOWS_GUI: return str8_lit("WINDOWS_GUI");
|
||||
case PE_WindowsSubsystem_WINDOWS_CUI: return str8_lit("WINDOWS_CUI");
|
||||
case PE_WindowsSubsystem_OS2_CUI: return str8_lit("OS2_CUI");
|
||||
case PE_WindowsSubsystem_POSIX_CUI: return str8_lit("POSIX_CUI");
|
||||
case PE_WindowsSubsystem_NATIVE_WINDOWS: return str8_lit("NATIVE_WINDOWS");
|
||||
case PE_WindowsSubsystem_WINDOWS_CE_GUI: return str8_lit("WINDOWS_CE_GUID");
|
||||
case PE_WindowsSubsystem_EFI_APPLICATION: return str8_lit("EFI_APPLICATION");
|
||||
case PE_WindowsSubsystem_EFI_BOOT_SERVICE_DRIVER: return str8_lit("EFI_BOOT_SERVICE_DRIVER");
|
||||
case PE_WindowsSubsystem_EFI_ROM: return str8_lit("EFI_ROM");
|
||||
case PE_WindowsSubsystem_XBOX: return str8_lit("XBOX");
|
||||
case PE_WindowsSubsystem_WINDOWS_BOOT_APPLICATION: return str8_lit("WINDOWS_BOOT_APPLICATION");
|
||||
default: break;
|
||||
}
|
||||
return str8(0,0);
|
||||
}
|
||||
|
||||
|
||||
+268
-167
@@ -1,13 +1,11 @@
|
||||
// Copyright (c) 2024 Epic Games Tools
|
||||
// Licensed under the MIT license (https://opensource.org/license/mit/)
|
||||
|
||||
/* date = September 6th 2023 8:54 am */
|
||||
|
||||
#ifndef PE_H
|
||||
#define PE_H
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: PE Format Types
|
||||
//~ rjf: PE Format-Defined Types/Constants
|
||||
|
||||
#pragma pack(push,1)
|
||||
|
||||
@@ -287,7 +285,7 @@ enum
|
||||
PE_GlobalFlags_HEAP_ENABLE_TAG_BY_DLL = (1 << 15),
|
||||
PE_GlobalFlags_DISABLE_STACK_EXTENSION = (1 << 16),
|
||||
PE_GlobalFlags_ENABLE_CSRDEBUG = (1 << 17),
|
||||
PE_GlobalFlags_ENABLE_KDEBUG_SYMBOL_LOAD = (1 << 18),
|
||||
PE_GlobalFlags_ENABLE_KDEBUG_SYMBOL_LOAD = (1 << 18),
|
||||
PE_GlobalFlags_DISABLE_PAGE_KERNEL_STACKS = (1 << 19),
|
||||
PE_GlobalFlags_ENABLE_SYSTEM_CRIT_BREAKS = (1 << 20),
|
||||
PE_GlobalFlags_HEAP_DISABLE_COALESCING = (1 << 21),
|
||||
@@ -445,11 +443,273 @@ struct PE_TLSHeader64
|
||||
U32 characteristics; // COFF_SectionFlags but only align flags are used.
|
||||
};
|
||||
|
||||
#define PE_RES_ALIGN 4u
|
||||
|
||||
global read_only U8 PE_RES_MAGIC[] =
|
||||
{
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x20, 0x00, 0x00, 0x00,
|
||||
0xFF, 0xFF, 0x00, 0x00,
|
||||
0xFF, 0xFF, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00
|
||||
};
|
||||
|
||||
typedef U32 PE_ResourceKind;
|
||||
enum
|
||||
{
|
||||
PE_ResourceKind_CURSOR = 0x1,
|
||||
PE_ResourceKind_BITMAP = 0x2,
|
||||
PE_ResourceKind_ICON = 0x3,
|
||||
PE_ResourceKind_MENU = 0x4,
|
||||
PE_ResourceKind_DIALOG = 0x5,
|
||||
PE_ResourceKind_STRING = 0x6,
|
||||
PE_ResourceKind_FONTDIR = 0x7,
|
||||
PE_ResourceKind_FONT = 0x8,
|
||||
PE_ResourceKind_ACCELERATOR = 0x9,
|
||||
PE_ResourceKind_RCDATA = 0xA,
|
||||
PE_ResourceKind_MESSAGETABLE = 0xB,
|
||||
PE_ResourceKind_GROUP_CURSOR = 0xC,
|
||||
PE_ResourceKind_GROUP_ICON = 0xE,
|
||||
PE_ResourceKind_VERSION = 0x10,
|
||||
PE_ResourceKind_DLGINCLUDE = 0x11,
|
||||
PE_ResourceKind_PLUGPLAY = 0x13,
|
||||
PE_ResourceKind_VXD = 0x14,
|
||||
PE_ResourceKind_ANICURSOR = 0x15,
|
||||
PE_ResourceKind_ANIICON = 0x16,
|
||||
PE_ResourceKind_HTML = 0x17,
|
||||
PE_ResourceKind_MANIFEST = 0x18,
|
||||
PE_ResourceKind_BITMAP_NEW = 0x2002,
|
||||
PE_ResourceKind_MENU_NEW = 0x2004,
|
||||
PE_ResourceKind_DIALOG_NEW = 0x2005,
|
||||
};
|
||||
|
||||
typedef enum PE_ResDataKind
|
||||
{
|
||||
PE_ResDataKind_NULL,
|
||||
PE_ResDataKind_DIR,
|
||||
PE_ResDataKind_COFF_LEAF,
|
||||
PE_ResDataKind_COFF_RESOURCE,
|
||||
}
|
||||
PE_ResDataKind;
|
||||
|
||||
typedef struct PE_ResourceHeader PE_ResourceHeader;
|
||||
struct PE_ResourceHeader
|
||||
{
|
||||
COFF_ResourceHeaderPrefix prefix;
|
||||
U16 type;
|
||||
U16 pad0;
|
||||
U16 name;
|
||||
U16 pad1;
|
||||
U32 data_version;
|
||||
COFF_ResourceMemoryFlags memory_flags;
|
||||
U16 language_id;
|
||||
U32 version;
|
||||
U32 characteristics;
|
||||
};
|
||||
|
||||
typedef U16 PE_BaseRelocKind;
|
||||
enum
|
||||
{
|
||||
PE_BaseRelocKind_ABSOLUTE = 0, // No reallocation is applied. Can be used as padding.
|
||||
PE_BaseRelocKind_HIGH = 1,
|
||||
PE_BaseRelocKind_LOW = 2,
|
||||
PE_BaseRelocKind_HIGHLOW = 3,
|
||||
PE_BaseRelocKind_HIGHADJ = 4,
|
||||
PE_BaseRelocKind_MIPS_JMPADDR = 5,
|
||||
PE_BaseRelocKind_ARM_MOV32 = 5,
|
||||
PE_BaseRelocKind_RISCV_HIGH20 = 5,
|
||||
// 6 is reserved
|
||||
PE_BaseRelocKind_THUMB_MOV32 = 7,
|
||||
PE_BaseRelocKind_RISCV_LOW12I = 7,
|
||||
PE_BaseRelocKind_RISCV_LOW12S = 8,
|
||||
PE_BaseRelocKind_LOONGARCH32_MARK_LA = 8,
|
||||
PE_BaseRelocKind_LOONGARCH64_MARK_LA = 8,
|
||||
PE_BaseRelocKind_MIPS_JMPADDR16 = 9,
|
||||
PE_BaseRelocKind_DIR64 = 10,
|
||||
};
|
||||
#define PE_BaseRelocOffsetFromEntry(x) ((x) & 0x1fff)
|
||||
#define PE_BaseRelocKindFromEntry(x) (((x) >> 12) & 0xf)
|
||||
#define PE_BaseRelocMake(k, off) ((((U16)(k) & 0xf) << 12) | (U16)((off) & 0x1fff))
|
||||
|
||||
typedef U32 PE_UnwindOpCode;
|
||||
enum
|
||||
{
|
||||
PE_UnwindOpCode_PUSH_NONVOL = 0,
|
||||
PE_UnwindOpCode_ALLOC_LARGE = 1,
|
||||
PE_UnwindOpCode_ALLOC_SMALL = 2,
|
||||
PE_UnwindOpCode_SET_FPREG = 3,
|
||||
PE_UnwindOpCode_SAVE_NONVOL = 4,
|
||||
PE_UnwindOpCode_SAVE_NONVOL_FAR = 5,
|
||||
PE_UnwindOpCode_EPILOG = 6,
|
||||
PE_UnwindOpCode_SPARE_CODE = 7,
|
||||
PE_UnwindOpCode_SAVE_XMM128 = 8,
|
||||
PE_UnwindOpCode_SAVE_XMM128_FAR = 9,
|
||||
PE_UnwindOpCode_PUSH_MACHFRAME = 10,
|
||||
};
|
||||
|
||||
typedef U8 PE_UnwindGprRegX64;
|
||||
enum
|
||||
{
|
||||
PE_UnwindGprRegX64_RAX = 0,
|
||||
PE_UnwindGprRegX64_RCX = 1,
|
||||
PE_UnwindGprRegX64_RDX = 2,
|
||||
PE_UnwindGprRegX64_RBX = 3,
|
||||
PE_UnwindGprRegX64_RSP = 4,
|
||||
PE_UnwindGprRegX64_RBP = 5,
|
||||
PE_UnwindGprRegX64_RSI = 6,
|
||||
PE_UnwindGprRegX64_RDI = 7,
|
||||
PE_UnwindGprRegX64_R8 = 8,
|
||||
PE_UnwindGprRegX64_R9 = 9,
|
||||
PE_UnwindGprRegX64_R10 = 10,
|
||||
PE_UnwindGprRegX64_R11 = 11,
|
||||
PE_UnwindGprRegX64_R12 = 12,
|
||||
PE_UnwindGprRegX64_R13 = 13,
|
||||
PE_UnwindGprRegX64_R14 = 14,
|
||||
PE_UnwindGprRegX64_R15 = 15,
|
||||
};
|
||||
|
||||
typedef U8 PE_UnwindInfoFlags;
|
||||
enum
|
||||
{
|
||||
PE_UnwindInfoFlag_EHANDLER = (1<<0),
|
||||
PE_UnwindInfoFlag_UHANDLER = (1<<1),
|
||||
PE_UnwindInfoFlag_FHANDLER = 3,
|
||||
PE_UnwindInfoFlag_CHAINED = (1<<2),
|
||||
};
|
||||
|
||||
#define PE_UNWIND_OPCODE_FROM_FLAGS(f) ((f)&0xF)
|
||||
#define PE_UNWIND_INFO_FROM_FLAGS(f) (((f) >> 4)&0xF)
|
||||
|
||||
typedef union PE_UnwindCode PE_UnwindCode;
|
||||
union PE_UnwindCode
|
||||
{
|
||||
struct
|
||||
{
|
||||
U8 off_in_prolog;
|
||||
U8 flags;
|
||||
};
|
||||
U16 u16;
|
||||
};
|
||||
|
||||
#define PE_UNWIND_INFO_VERSION_FROM_HDR(x) ((x)&0x7)
|
||||
#define PE_UNWIND_INFO_FLAGS_FROM_HDR(x) (((x) >> 3)&0x1F)
|
||||
#define PE_UNWIND_INFO_REG_FROM_FRAME(x) ((x)&0xF)
|
||||
#define PE_UNWIND_INFO_OFF_FROM_FRAME(x) (((x) >> 4)&0xF)
|
||||
|
||||
typedef struct PE_UnwindInfo PE_UnwindInfo;
|
||||
struct PE_UnwindInfo
|
||||
{
|
||||
U8 header;
|
||||
U8 prolog_size;
|
||||
U8 codes_num;
|
||||
U8 frame;
|
||||
};
|
||||
|
||||
#pragma pack(pop)
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: DOS Program
|
||||
|
||||
// generated from pe/dos_program.asm
|
||||
read_only global U8 pe_dos_program_data[] =
|
||||
{
|
||||
0x0E, 0x1F, 0xBA, 0x0E, 0x00, 0xB4, 0x09, 0xCD, 0x21, 0xB8, 0x01, 0x4C, 0xCD, 0x21, 0x54, 0x68,
|
||||
0x69, 0x73, 0x20, 0x70, 0x72, 0x6F, 0x67, 0x72, 0x61, 0x6D, 0x20, 0x63, 0x61, 0x6E, 0x6E, 0x6F,
|
||||
0x74, 0x20, 0x62, 0x65, 0x20, 0x72, 0x75, 0x6E, 0x20, 0x69, 0x6E, 0x20, 0x44, 0x4F, 0x53, 0x20,
|
||||
0x6D, 0x6F, 0x64, 0x65, 0x2E, 0x24, 0x00, 0x00
|
||||
};
|
||||
read_only global String8 pe_dos_program = {pe_dos_program_data, sizeof(pe_dos_program_data)};
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Parsed Info Types
|
||||
|
||||
//- rjf: relocation blocks
|
||||
|
||||
typedef struct PE_BaseRelocBlock PE_BaseRelocBlock;
|
||||
struct PE_BaseRelocBlock
|
||||
{
|
||||
U64 page_virt_off;
|
||||
U64 entry_count;
|
||||
U16 *entries;
|
||||
};
|
||||
|
||||
typedef struct PE_BaseRelocBlockNode PE_BaseRelocBlockNode;
|
||||
struct PE_BaseRelocBlockNode
|
||||
{
|
||||
PE_BaseRelocBlockNode *next;
|
||||
PE_BaseRelocBlock v;
|
||||
};
|
||||
|
||||
typedef struct PE_BaseRelocBlockList PE_BaseRelocBlockList;
|
||||
struct PE_BaseRelocBlockList
|
||||
{
|
||||
PE_BaseRelocBlockNode *first;
|
||||
PE_BaseRelocBlockNode *last;
|
||||
U64 count;
|
||||
};
|
||||
|
||||
//- rjf: resources
|
||||
|
||||
typedef struct PE_Resource PE_Resource;
|
||||
struct PE_Resource
|
||||
{
|
||||
COFF_ResourceID id;
|
||||
PE_ResDataKind kind;
|
||||
union
|
||||
{
|
||||
COFF_ResourceDataEntry leaf;
|
||||
struct PE_ResourceDir *dir;
|
||||
struct
|
||||
{
|
||||
COFF_ResourceID type;
|
||||
U32 data_version;
|
||||
U32 version;
|
||||
COFF_ResourceMemoryFlags memory_flags;
|
||||
String8 data;
|
||||
}
|
||||
coff_res;
|
||||
}
|
||||
u;
|
||||
};
|
||||
|
||||
typedef struct PE_ResourceNode PE_ResourceNode;
|
||||
struct PE_ResourceNode
|
||||
{
|
||||
PE_ResourceNode *next;
|
||||
PE_Resource data;
|
||||
};
|
||||
|
||||
typedef struct PE_ResourceList PE_ResourceList;
|
||||
struct PE_ResourceList
|
||||
{
|
||||
PE_ResourceNode *first;
|
||||
PE_ResourceNode *last;
|
||||
U64 count;
|
||||
};
|
||||
|
||||
typedef struct PE_ResourceArray PE_ResourceArray;
|
||||
struct PE_ResourceArray
|
||||
{
|
||||
PE_Resource *v;
|
||||
U64 count;
|
||||
};
|
||||
|
||||
typedef struct PE_ResourceDir PE_ResourceDir;
|
||||
struct PE_ResourceDir
|
||||
{
|
||||
U32 characteristics;
|
||||
COFF_TimeStamp time_stamp;
|
||||
U16 major_version;
|
||||
U16 minor_version;
|
||||
PE_ResourceList named_list;
|
||||
PE_ResourceList id_list;
|
||||
};
|
||||
|
||||
//- rjf: bundle
|
||||
|
||||
typedef struct PE_BinInfo PE_BinInfo;
|
||||
struct PE_BinInfo
|
||||
{
|
||||
@@ -475,161 +735,10 @@ struct PE_BinInfo
|
||||
};
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Parsed Info Extraction Helper Types
|
||||
//~ rjf: Basic Enum Functions
|
||||
|
||||
typedef U16 PE_BaseRelocKind;
|
||||
enum
|
||||
{
|
||||
PE_BaseRelocKind_ABSOLUTE = 0, // No reallocation is applied. Can be used as padding.
|
||||
PE_BaseRelocKind_HIGH = 1,
|
||||
PE_BaseRelocKind_LOW = 2,
|
||||
PE_BaseRelocKind_HIGHLOW = 3,
|
||||
PE_BaseRelocKind_HIGHADJ = 4,
|
||||
PE_BaseRelocKind_MIPS_JMPADDR = 5,
|
||||
PE_BaseRelocKind_ARM_MOV32 = 5,
|
||||
PE_BaseRelocKind_RISCV_HIGH20 = 5,
|
||||
// 6 is reserved
|
||||
PE_BaseRelocKind_THUMB_MOV32 = 7,
|
||||
PE_BaseRelocKind_RISCV_LOW12I = 7,
|
||||
PE_BaseRelocKind_RISCV_LOW12S = 8,
|
||||
PE_BaseRelocKind_LOONGARCH32_MARK_LA = 8,
|
||||
PE_BaseRelocKind_LOONGARCH64_MARK_LA = 8,
|
||||
PE_BaseRelocKind_MIPS_JMPADDR16 = 9,
|
||||
PE_BaseRelocKind_DIR64 = 10,
|
||||
};
|
||||
#define PE_BaseRelocOffsetFromEntry(x) ((x) & 0x1fff)
|
||||
#define PE_BaseRelocKindFromEntry(x) (((x) >> 12) & 0xf)
|
||||
#define PE_BaseRelocMake(k, off) ((((U16)(k) & 0xf) << 12) | (U16)((off) & 0x1fff))
|
||||
|
||||
typedef struct PE_BaseRelocBlock PE_BaseRelocBlock;
|
||||
struct PE_BaseRelocBlock
|
||||
{
|
||||
U64 page_virt_off;
|
||||
U64 entry_count;
|
||||
U16 *entries;
|
||||
};
|
||||
|
||||
typedef struct PE_BaseRelocBlockNode PE_BaseRelocBlockNode;
|
||||
struct PE_BaseRelocBlockNode
|
||||
{
|
||||
PE_BaseRelocBlockNode *next;
|
||||
PE_BaseRelocBlock v;
|
||||
};
|
||||
|
||||
typedef struct PE_BaseRelocBlockList PE_BaseRelocBlockList;
|
||||
struct PE_BaseRelocBlockList
|
||||
{
|
||||
PE_BaseRelocBlockNode *first;
|
||||
PE_BaseRelocBlockNode *last;
|
||||
U64 count;
|
||||
};
|
||||
|
||||
////////////////////////////////
|
||||
//~ Resources
|
||||
|
||||
#define PE_RES_ALIGN 4u
|
||||
|
||||
read_only U8 PE_RES_MAGIC[] = { 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
|
||||
|
||||
enum
|
||||
{
|
||||
PE_Resource_CURSOR = 0x1,
|
||||
PE_Resource_BITMAP = 0x2,
|
||||
PE_Resource_ICON = 0x3,
|
||||
PE_Resource_MENU = 0x4,
|
||||
PE_Resource_DIALOG = 0x5,
|
||||
PE_Resource_STRING = 0x6,
|
||||
PE_Resource_FONTDIR = 0x7,
|
||||
PE_Resource_FONT = 0x8,
|
||||
PE_Resource_ACCELERATOR = 0x9,
|
||||
PE_Resource_RCDATA = 0xA,
|
||||
PE_Resource_MESSAGETABLE = 0xB,
|
||||
PE_Resource_GROUP_CURSOR = 0xC,
|
||||
PE_Resource_GROUP_ICON = 0xE,
|
||||
PE_Resource_VERSION = 0x10,
|
||||
PE_Resource_DLGINCLUDE = 0x11,
|
||||
PE_Resource_PLUGPLAY = 0x13,
|
||||
PE_Resource_VXD = 0x14,
|
||||
PE_Resource_ANICURSOR = 0x15,
|
||||
PE_Resource_ANIICON = 0x16,
|
||||
PE_Resource_HTML = 0x17,
|
||||
PE_Resource_MANIFEST = 0x18,
|
||||
PE_Resource_BITMAP_NEW = 0x2002,
|
||||
PE_Resource_MENU_NEW = 0x2004,
|
||||
PE_Resource_DIALOG_NEW = 0x2005,
|
||||
};
|
||||
typedef U32 PE_ResourceType;
|
||||
|
||||
#pragma pack(push, 1)
|
||||
typedef struct PE_ResourceHeader
|
||||
{
|
||||
COFF_ResourceHeaderPrefix prefix;
|
||||
U16 type;
|
||||
U16 pad0;
|
||||
U16 name;
|
||||
U16 pad1;
|
||||
U32 data_version;
|
||||
COFF_ResourceMemoryFlags memory_flags;
|
||||
U16 language_id;
|
||||
U32 version;
|
||||
U32 characteristics;
|
||||
} PE_ResourceHeader;
|
||||
#pragma pack(pop)
|
||||
|
||||
typedef enum
|
||||
{
|
||||
PE_ResData_NULL,
|
||||
PE_ResData_DIR,
|
||||
PE_ResData_COFF_LEAF,
|
||||
PE_ResData_COFF_RESOURCE,
|
||||
} PE_ResDataType;
|
||||
|
||||
typedef struct PE_Resource
|
||||
{
|
||||
COFF_ResourceID id;
|
||||
PE_ResDataType type;
|
||||
union {
|
||||
COFF_ResourceDataEntry leaf;
|
||||
struct PE_ResourceDir *dir;
|
||||
struct {
|
||||
COFF_ResourceID type;
|
||||
U32 data_version;
|
||||
U32 version;
|
||||
COFF_ResourceMemoryFlags memory_flags;
|
||||
String8 data;
|
||||
} coff_res;
|
||||
} u;
|
||||
} PE_Resource;
|
||||
|
||||
typedef struct PE_ResourceNode
|
||||
{
|
||||
struct PE_ResourceNode *next;
|
||||
PE_Resource data;
|
||||
} PE_ResourceNode;
|
||||
|
||||
typedef struct PE_ResourceList
|
||||
{
|
||||
U64 count;
|
||||
PE_ResourceNode *first;
|
||||
PE_ResourceNode *last;
|
||||
} PE_ResourceList;
|
||||
|
||||
typedef struct PE_ResourceArray
|
||||
{
|
||||
U64 count;
|
||||
PE_Resource *v;
|
||||
} PE_ResourceArray;
|
||||
|
||||
typedef struct PE_ResourceDir
|
||||
{
|
||||
U32 characteristics;
|
||||
COFF_TimeStamp time_stamp;
|
||||
U16 major_version;
|
||||
U16 minor_version;
|
||||
PE_ResourceList named_list;
|
||||
PE_ResourceList id_list;
|
||||
} PE_ResourceDir;
|
||||
internal U32 pe_slot_count_from_unwind_op_code(PE_UnwindOpCode opcode);
|
||||
internal String8 pe_string_from_windows_subsystem(PE_WindowsSubsystem subsystem);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Parser Functions
|
||||
@@ -661,12 +770,4 @@ internal PE_Resource * pe_resource_dir_search(PE_ResourceDir *dir, COFF_Reso
|
||||
internal PE_ResourceArray pe_resource_list_to_array(Arena *arena, PE_ResourceList *list);
|
||||
internal PE_ResourceDir * pe_resource_table_from_directory_data(Arena *arena, String8 data);
|
||||
|
||||
////////////////////////////////
|
||||
|
||||
internal String8 pe_get_dos_program(void);
|
||||
|
||||
////////////////////////////////
|
||||
|
||||
internal String8 pe_string_from_subsystem(PE_WindowsSubsystem subsystem);
|
||||
|
||||
#endif //PE_H
|
||||
#endif // PE_H
|
||||
|
||||
Reference in New Issue
Block a user