// Copyright (c) Epic Games Tools // Licensed under the MIT license (https://opensource.org/license/mit/) #ifndef COFF_H #define COFF_H //////////////////////////////// //~ rjf: COFF Format Types read_only global U8 g_coff_big_header_magic[] = { 0xc7, 0xa1, 0xba, 0xd1, 0xee, 0xba, 0xa9, 0x4b, 0xaf, 0x20, 0xfa, 0xf6, 0x6a, 0xa4, 0xdc, 0xb8 }; read_only global U8 g_coff_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 }; read_only global U8 g_coff_archive_sig[8] = "!\n"; read_only global U8 g_coff_thin_archive_sig[8] = "!\n"; #pragma pack(push, 1) #define COFF_TimeStamp_Max max_U32 typedef U32 COFF_TimeStamp; typedef U16 COFF_FileHeaderFlags; enum { COFF_FileHeaderFlag_RelocStripped = (1 << 0), COFF_FileHeaderFlag_ExecutableImage = (1 << 1), COFF_FileHeaderFlag_LineNumbersStripped = (1 << 2), COFF_FileHeaderFlag_SymbolsStripped = (1 << 3), COFF_FileHeaderFlag_Reserved0 = (1 << 4), COFF_FileHeaderFlag_LargeAddressAware = (1 << 5), COFF_FileHeaderFlag_Reserved1 = (1 << 6), COFF_FileHeaderFlag_Reserved2 = (1 << 7), COFF_FileHeaderFlag_32BitMachine = (1 << 8), COFF_FileHeaderFlag_DebugStripped = (1 << 9), COFF_FileHeaderFlag_RemovableRunFromSwap = (1 << 10), COFF_FileHeaderFlag_NetRunFromSwap = (1 << 11), COFF_FileHeaderFlag_System = (1 << 12), COFF_FileHeaderFlag_Dll = (1 << 13), COFF_FileHeaderFlag_UpSystemOnly = (1 << 14), COFF_FileHeaderFlag_BytesReservedHi = (1 << 15) }; typedef U16 COFF_MachineType; enum { COFF_MachineType_Unknown = 0x0, COFF_MachineType_X86 = 0x14c, COFF_MachineType_X64 = 0x8664, COFF_MachineType_Am33 = 0x1d3, COFF_MachineType_Arm = 0x1c0, COFF_MachineType_Arm64 = 0xaa64, COFF_MachineType_ArmNt = 0x1c4, COFF_MachineType_Ebc = 0xebc, COFF_MachineType_Ia64 = 0x200, COFF_MachineType_M32R = 0x9041, COFF_MachineType_Mips16 = 0x266, COFF_MachineType_MipsFpu = 0x366, COFF_MachineType_MipsFpu16 = 0x466, COFF_MachineType_PowerPc = 0x1f0, COFF_MachineType_PowerPcFp = 0x1f1, COFF_MachineType_R4000 = 0x166, COFF_MachineType_RiscV32 = 0x5032, COFF_MachineType_RiscV64 = 0x5064, COFF_MachineType_RiscV128 = 0x5128, COFF_MachineType_Sh3 = 0x1a2, COFF_MachineType_Sh3Dsp = 0x1a3, COFF_MachineType_Sh4 = 0x1a6, COFF_MachineType_Sh5 = 0x1a8, COFF_MachineType_Thumb = 0x1c2, COFF_MachineType_WceMipsV2 = 0x169 }; typedef struct COFF_FileHeader { COFF_MachineType machine; U16 section_count; COFF_TimeStamp time_stamp; U32 symbol_table_foff; U32 symbol_count; U16 optional_header_size; COFF_FileHeaderFlags flags; } COFF_FileHeader; typedef struct COFF_BigObjHeader { U16 sig1; // COFF_MachineType_Unknown U16 sig2; // max_U16 U16 version; // 2 COFF_MachineType machine; COFF_TimeStamp time_stamp; U8 magic[16]; // g_coff_big_header_magic U8 unused[16]; U32 section_count; U32 symbol_table_foff; U32 symbol_count; } COFF_BigObjHeader; typedef U32 COFF_SectionAlign; enum { COFF_SectionAlign_None = 0x0, COFF_SectionAlign_1Bytes = 0x1, COFF_SectionAlign_2Bytes = 0x2, COFF_SectionAlign_4Bytes = 0x3, COFF_SectionAlign_8Bytes = 0x4, COFF_SectionAlign_16Bytes = 0x5, COFF_SectionAlign_32Bytes = 0x6, COFF_SectionAlign_64Bytes = 0x7, COFF_SectionAlign_128Bytes = 0x8, COFF_SectionAlign_256Bytes = 0x9, COFF_SectionAlign_512Bytes = 0xa, COFF_SectionAlign_1024Bytes = 0xb, COFF_SectionAlign_2048Bytes = 0xc, COFF_SectionAlign_4096Bytes = 0xd, COFF_SectionAlign_8192Bytes = 0xe }; typedef U32 COFF_SectionFlags; enum { COFF_SectionFlag_TypeNoPad = (1 << 3), COFF_SectionFlag_CntCode = (1 << 5), COFF_SectionFlag_CntInitializedData = (1 << 6), COFF_SectionFlag_CntUninitializedData = (1 << 7), COFF_SectionFlag_LnkOther = (1 << 8), COFF_SectionFlag_LnkInfo = (1 << 9), COFF_SectionFlag_LnkRemove = (1 << 11), COFF_SectionFlag_LnkCOMDAT = (1 << 12), COFF_SectionFlag_GpRel = (1 << 15), COFF_SectionFlag_Mem16Bit = (1 << 17), COFF_SectionFlag_MemLocked = (1 << 18), COFF_SectionFlag_MemPreload = (1 << 19), COFF_SectionFlag_AlignShift = 20, COFF_SectionFlag_AlignMask = 0xf, COFF_SectionFlag_Align1Bytes = (COFF_SectionAlign_1Bytes << COFF_SectionFlag_AlignShift), COFF_SectionFlag_Align2Bytes = (COFF_SectionAlign_2Bytes << COFF_SectionFlag_AlignShift), COFF_SectionFlag_Align4Bytes = (COFF_SectionAlign_4Bytes << COFF_SectionFlag_AlignShift), COFF_SectionFlag_Align8Bytes = (COFF_SectionAlign_8Bytes << COFF_SectionFlag_AlignShift), COFF_SectionFlag_Align16Bytes = (COFF_SectionAlign_16Bytes << COFF_SectionFlag_AlignShift), COFF_SectionFlag_Align32Bytes = (COFF_SectionAlign_32Bytes << COFF_SectionFlag_AlignShift), COFF_SectionFlag_Align64Bytes = (COFF_SectionAlign_64Bytes << COFF_SectionFlag_AlignShift), COFF_SectionFlag_Align128Bytes = (COFF_SectionAlign_128Bytes << COFF_SectionFlag_AlignShift), COFF_SectionFlag_Align256Bytes = (COFF_SectionAlign_256Bytes << COFF_SectionFlag_AlignShift), COFF_SectionFlag_Align512Bytes = (COFF_SectionAlign_512Bytes << COFF_SectionFlag_AlignShift), COFF_SectionFlag_Align1024Bytes = (COFF_SectionAlign_1024Bytes << COFF_SectionFlag_AlignShift), COFF_SectionFlag_Align2048Bytes = (COFF_SectionAlign_2048Bytes << COFF_SectionFlag_AlignShift), COFF_SectionFlag_Align4096Bytes = (COFF_SectionAlign_4096Bytes << COFF_SectionFlag_AlignShift), COFF_SectionFlag_Align8192Bytes = (COFF_SectionAlign_8192Bytes << COFF_SectionFlag_AlignShift), COFF_SectionFlag_LnkNRelocOvfl = (1 << 24), COFF_SectionFlag_MemDiscardable = (1 << 25), COFF_SectionFlag_MemNotCached = (1 << 26), COFF_SectionFlag_MemNotPaged = (1 << 27), COFF_SectionFlag_MemShared = (1 << 28), COFF_SectionFlag_MemExecute = (1 << 29), COFF_SectionFlag_MemRead = (1 << 30), COFF_SectionFlag_MemWrite = (1 << 31) }; #define COFF_SectionFlags_ExtractAlign(f) (COFF_SectionAlign)(((f) >> COFF_SectionFlag_AlignShift) & COFF_SectionFlag_AlignMask) #define COFF_SectionFlags_LnkFlags ((COFF_SectionFlag_AlignMask << COFF_SectionFlag_AlignShift) | COFF_SectionFlag_LnkCOMDAT | COFF_SectionFlag_LnkInfo | COFF_SectionFlag_LnkOther | COFF_SectionFlag_LnkRemove | COFF_SectionFlag_LnkNRelocOvfl) typedef struct COFF_SectionHeader { U8 name[8]; U32 vsize; U32 voff; U32 fsize; U32 foff; U32 relocs_foff; U32 lines_foff; U16 reloc_count; U16 line_count; COFF_SectionFlags flags; } COFF_SectionHeader; //////////////////////////////// typedef U8 COFF_SymType; enum { COFF_SymType_Null, COFF_SymType_Void, COFF_SymType_Char, COFF_SymType_Short, COFF_SymType_Int, COFF_SymType_Long, COFF_SymType_Float, COFF_SymType_Double, COFF_SymType_Struct, COFF_SymType_Union, COFF_SymType_Enum, COFF_SymType_MemberOfEnumeration, COFF_SymType_Byte, COFF_SymType_Word, COFF_SymType_UInt, COFF_SymType_DWord }; typedef U8 COFF_SymStorageClass; enum { COFF_SymStorageClass_Null = 0x00, COFF_SymStorageClass_Automatic = 0x01, COFF_SymStorageClass_External = 0x02, COFF_SymStorageClass_Static = 0x03, COFF_SymStorageClass_Register = 0x04, COFF_SymStorageClass_ExternalDef = 0x05, COFF_SymStorageClass_Label = 0x06, COFF_SymStorageClass_UndefinedLabel = 0x07, COFF_SymStorageClass_MemberOfStruct = 0x08, COFF_SymStorageClass_Argument = 0x09, COFF_SymStorageClass_StructTag = 0x0a, COFF_SymStorageClass_MemberOfUnion = 0x0b, COFF_SymStorageClass_UnionTag = 0x0c, COFF_SymStorageClass_TypeDefinition = 0x0d, COFF_SymStorageClass_UndefinedStatic = 0x0e, COFF_SymStorageClass_EnumTag = 0x0f, COFF_SymStorageClass_MemberOfEnum = 0x10, COFF_SymStorageClass_RegisterParam = 0x11, COFF_SymStorageClass_BitField = 0x12, COFF_SymStorageClass_Block = 0x64, COFF_SymStorageClass_Function = 0x65, COFF_SymStorageClass_EndOfStruct = 0x66, COFF_SymStorageClass_File = 0x67, COFF_SymStorageClass_Section = 0x68, COFF_SymStorageClass_WeakExternal = 0x69, COFF_SymStorageClass_CLRToken = 0x6b, COFF_SymStorageClass_EndOfFunction = 0xff }; typedef U8 COFF_SymDType; enum { COFF_SymDType_Null = 0x00, COFF_SymDType_Ptr = 0x10, COFF_SymDType_Func = 0x20, COFF_SymDType_Array = 0x30 }; // Special values for section number field in coff symbol #define COFF_Symbol_UndefinedSection 0 #define COFF_Symbol_AbsSection32 ((U32)-1) #define COFF_Symbol_DebugSection32 ((U32)-2) #define COFF_Symbol_AbsSection16 ((U16)-1) #define COFF_Symbol_DebugSection16 ((U16)-2) typedef union COFF_SymbolName { U8 short_name[8]; struct { // if this field is filled with zeroes we have a long name, // which means name is stored in the string table // and we need to use the offset to look it up... U32 zeroes; U32 string_table_offset; } long_name; } COFF_SymbolName; #define COFF_SymbolType_IsFunc(x) ((x).u.lsb == COFF_SymType_Null && (x).u.msb == COFF_SymDType_Func) typedef union COFF_SymbolType { struct { COFF_SymDType msb; COFF_SymType lsb; } u; U16 v; } COFF_SymbolType; typedef struct COFF_Symbol16 { COFF_SymbolName name; U32 value; U16 section_number; COFF_SymbolType type; COFF_SymStorageClass storage_class; U8 aux_symbol_count; } COFF_Symbol16; typedef struct COFF_Symbol32 { COFF_SymbolName name; U32 value; U32 section_number; COFF_SymbolType type; COFF_SymStorageClass storage_class; U8 aux_symbol_count; } COFF_Symbol32; typedef U32 COFF_WeakExtType; enum { COFF_WeakExt_Null = 0, COFF_WeakExt_NoLibrary = 1, COFF_WeakExt_SearchLibrary = 2, COFF_WeakExt_SearchAlias = 3, COFF_WeakExt_AntiDependency = 4, // search libraries only if the default symbol is weak, even if the weak symbol points to itself }; // storage class: External typedef struct COFF_SymbolFuncDef { U32 tag_index; U32 total_size; U32 ptr_to_ln; U32 ptr_to_next_func; U8 unused[2]; } COFF_SymbolFuncDef; // storage class: Function typedef struct COFF_SymbolFunc { U8 unused[4]; U16 ln; U8 unused2[2]; U32 ptr_to_next_func; U8 unused3[2]; } COFF_SymbolFunc; // storage class: WeakExternal typedef struct COFF_SymbolWeakExt { U32 tag_index; COFF_WeakExtType characteristics; U8 unused[10]; } COFF_SymbolWeakExt; typedef struct COFF_SymbolFile { U8 name[18]; } COFF_SymbolFile; typedef U8 COFF_ComdatSelectType; enum { COFF_ComdatSelect_Null = 0, COFF_ComdatSelect_NoDuplicates = 1, // Only one symbol is allowed to be in global symbol table, otherwise multiply defintion error is thrown. COFF_ComdatSelect_Any = 2, // Select any symbol, even if there are multiple definitions. (we default to first declaration) COFF_ComdatSelect_SameSize = 3, // Sections that symbols reference must match in size, otherwise multiply definition error is thrown. COFF_ComdatSelect_ExactMatch = 4, // Sections that symbols reference must have identical checksums, otherwise multiply defintion error is thrown. COFF_ComdatSelect_Associative = 5, // Symbols with associative type form a chain of sections are related to each other. (next link is indicated in COFF_SecDef in 'number') COFF_ComdatSelect_Largest = 6 // Linker selects section with largest size. }; // provides information about section to which symbol refers to. // storage class: Static typedef struct COFF_SymbolSecDef { U32 length; U16 number_of_relocations; U16 number_of_ln; U32 check_sum; U16 number_lo; // low 16 bits of one-based section index COFF_ComdatSelectType selection; U8 unused; U16 number_hi; } COFF_SymbolSecDef; //////////////////////////////// typedef U16 COFF_RelocType; typedef COFF_RelocType COFF_Reloc_X64; enum { COFF_Reloc_X64_Abs = 0x0, COFF_Reloc_X64_Addr64 = 0x1, COFF_Reloc_X64_Addr32 = 0x2, COFF_Reloc_X64_Addr32Nb = 0x3, // NB => No Base COFF_Reloc_X64_Rel32 = 0x4, COFF_Reloc_X64_Rel32_1 = 0x5, COFF_Reloc_X64_Rel32_2 = 0x6, COFF_Reloc_X64_Rel32_3 = 0x7, COFF_Reloc_X64_Rel32_4 = 0x8, COFF_Reloc_X64_Rel32_5 = 0x9, COFF_Reloc_X64_Section = 0xA, COFF_Reloc_X64_SecRel = 0xB, COFF_Reloc_X64_SecRel7 = 0xC, // TODO(nick): MSDN doesn't specify size for CLR token COFF_Reloc_X64_Token = 0xD, COFF_Reloc_X64_SRel32 = 0xE, // TODO(nick): MSDN doesn't specify size for PAIR COFF_Reloc_X64_Pair = 0xF, COFF_Reloc_X64_SSpan32 = 0x10, COFF_Reloc_X64_Unknown_11 = 0x11, COFF_Reloc_X64_Last = COFF_Reloc_X64_Unknown_11, }; typedef COFF_RelocType COFF_Reloc_X86; enum { COFF_Reloc_X86_Abs = 0x0, // relocation is ignored COFF_Reloc_X86_Dir16 = 0x1, // no support COFF_Reloc_X86_Rel16 = 0x2, // no support COFF_Reloc_X86_Unknown0 = 0x3, COFF_Reloc_X86_Unknown2 = 0x4, COFF_Reloc_X86_Unknown3 = 0x5, COFF_Reloc_X86_Dir32 = 0x6, // 32-bit virtual address COFF_Reloc_X86_Dir32Nb = 0x7, // 32-bit virtual offset COFF_Reloc_X86_Seg12 = 0x9, // no support COFF_Reloc_X86_Section = 0xa, // 16-bit section index, used for debug info purposes COFF_Reloc_X86_SecRel = 0xb, // 32-bit offset from start of a section COFF_Reloc_X86_Token = 0xc, // CLR token? (for managed languages) COFF_Reloc_X86_SecRel7 = 0xd, // 7-bit offset from the base of the section that contains the target. COFF_Reloc_X86_Unknown4 = 0xe, COFF_Reloc_X86_Unknown5 = 0xf, COFF_Reloc_X86_Unknown6 = 0x10, COFF_Reloc_X86_Unknown7 = 0x11, COFF_Reloc_X86_Unknown8 = 0x12, COFF_Reloc_X86_Unknown9 = 0x13, COFF_Reloc_X86_Rel32 = 0x14 }; typedef COFF_RelocType COFF_Reloc_Arm; enum { COFF_Reloc_Arm_Abs = 0x0, COFF_Reloc_Arm_Addr32 = 0x1, COFF_Reloc_Arm_Addr32Nb = 0x2, COFF_Reloc_Arm_Branch24 = 0x3, COFF_Reloc_Arm_Branch11 = 0x4, COFF_Reloc_Arm_Unknown1 = 0x5, COFF_Reloc_Arm_Unknown2 = 0x6, COFF_Reloc_Arm_Unknown3 = 0x7, COFF_Reloc_Arm_Unknown4 = 0x8, COFF_Reloc_Arm_Unknown5 = 0x9, COFF_Reloc_Arm_Rel32 = 0xa, COFF_Reloc_Arm_Section = 0xe, COFF_Reloc_Arm_SecRel = 0xf, COFF_Reloc_Arm_Mov32 = 0x10, COFF_Reloc_Arm_ThumbMov32 = 0x11, COFF_Reloc_Arm_ThumbBranch20 = 0x12, COFF_Reloc_Arm_Unused = 0x13, COFF_Reloc_Arm_ThumbBranch24 = 0x14, COFF_Reloc_Arm_ThumbBlx23 = 0x15, COFF_Reloc_Arm_Pair = 0x16 }; typedef COFF_RelocType COFF_Reloc_Arm64; enum { COFF_Reloc_Arm64_Abs = 0x0, COFF_Reloc_Arm64_Addr32 = 0x1, COFF_Reloc_Arm64_Addr32Nb = 0x2, COFF_Reloc_Arm64_Branch26 = 0x3, COFF_Reloc_Arm64_PageBaseRel21 = 0x4, COFF_Reloc_Arm64_Rel21 = 0x5, COFF_Reloc_Arm64_PageOffset12a = 0x6, COFF_Reloc_Arm64_SecRel = 0x8, COFF_Reloc_Arm64_SecRelLow12a = 0x9, COFF_Reloc_Arm64_SecRelHigh12a = 0xa, COFF_Reloc_Arm64_SecRelLow12l = 0xb, COFF_Reloc_Arm64_Token = 0xc, COFF_Reloc_Arm64_Section = 0xd, COFF_Reloc_Arm64_Addr64 = 0xe, COFF_Reloc_Arm64_Branch19 = 0xf, COFF_Reloc_Arm64_Branch14 = 0x10, COFF_Reloc_Arm64_Rel32 = 0x11 }; typedef struct COFF_Reloc { U32 apply_off; // section relative offset where relocation is placed U32 isymbol; // zero based index into coff symbol table COFF_RelocType type; // relocation type that depends on the arch } COFF_Reloc; //////////////////////////////// #define COFF_ResourceAlign 4u typedef struct COFF_ResourceHeaderPrefix { U32 data_size; U32 header_size; } COFF_ResourceHeaderPrefix; typedef U16 COFF_ResourceMemoryFlags; enum { COFF_ResourceMemoryFlag_Moveable = 0x10, COFF_ResourceMemoryFlag_Pure = 0x20, COFF_ResourceMemoryFlag_PreLoad = 0x40, COFF_ResourceMemoryFlag_Discardable = 0x1000 }; typedef struct COFF_ResourceDataEntry { U32 data_voff; U32 data_size; U32 code_page; U32 reserved; } COFF_ResourceDataEntry; typedef struct COFF_ResourceDirTable { U32 characteristics; COFF_TimeStamp time_stamp; U16 major_version; U16 minor_version; U16 name_entry_count; U16 id_entry_count; } COFF_ResourceDirTable; #define COFF_Resource_SubDirFlag (1u << 31u) typedef struct COFF_ResourceDirEntry { union { U32 offset; U32 id; } name; union { U32 data_entry_offset; U32 sub_dir_offset; } id; } COFF_ResourceDirEntry; //////////////////////////////// #define COFF_Archive_MemberAlign 2 #define COFF_Archive_MaxShortNameSize 15 typedef struct COFF_ArchiveMemberHeader { U8 name[16]; U8 date[12]; U8 user_id[6]; U8 group_id[6]; U8 mode[8]; U8 size[10]; U8 end[2]; } COFF_ArchiveMemberHeader; #define COFF_ImportType_Invalid max_U16 typedef U16 COFF_ImportType; enum { COFF_ImportHeader_Code = 0, COFF_ImportHeader_Data = 1, COFF_ImportHeader_Const = 2 }; typedef U32 COFF_ImportByType; enum { COFF_ImportBy_Ordinal = 0, COFF_ImportBy_Name = 1, COFF_ImportBy_NameNoPrefix = 2, COFF_ImportBy_Undecorate = 3 }; typedef U16 COFF_ImportHeaderFlags; enum { COFF_ImportHeader_TypeShift = 0, COFF_ImportHeader_TypeMask = 3, COFF_ImportHeader_ImportByShift = 2, COFF_ImportHeader_ImportByMask = 3, }; #define COFF_ImportHeader_ExtractType(x) (((x) >> COFF_ImportHeader_TypeShift ) & COFF_ImportHeader_TypeMask ) #define COFF_ImportHeader_ExtractImportBy(x) (((x) >> COFF_ImportHeader_ImportByShift) & COFF_ImportHeader_ImportByMask) typedef struct COFF_ImportHeader { U16 sig1; // COFF_MachineType_Unknown U16 sig2; // max_U16 U16 version; // 0 COFF_MachineType machine; COFF_TimeStamp time_stamp; U32 data_size; U16 hint_or_ordinal; COFF_ImportHeaderFlags flags; // char *func_name; // char *dll_name; } COFF_ImportHeader; #pragma pack(pop) typedef struct COFF_RelocValue { U64 size; S64 value; } COFF_RelocValue; //////////////////////////////// // Section internal U64 coff_align_size_from_section_flags(COFF_SectionFlags flags); internal COFF_SectionFlags coff_section_flag_from_align_size (U64 align); internal String8 coff_name_from_section_header(String8 string_table, COFF_SectionHeader *header); internal void coff_parse_section_name (String8 full_name, String8 *name_out, String8 *postfix_out); //////////////////////////////// // Symbol internal String8 coff_read_symbol_name(String8 string_table, COFF_SymbolName *name); //////////////////////////////// // Reloc internal U64 coff_apply_size_from_reloc_x64(COFF_Reloc_X64 x); internal U64 coff_apply_size_from_reloc_x86(COFF_Reloc_X86 x); internal COFF_RelocValue coff_pick_reloc_value_x64(COFF_Reloc_X64 type, U64 image_base, U64 reloc_virtual_offset, U32 symbol_section_number, U32 symbol_section_offset, S64 symbol_virtual_offset); //////////////////////////////// // Import internal U32 coff_make_ordinal32(U16 hint); internal U64 coff_make_ordinal64(U16 hint); internal String8 coff_ordinal_data_from_hint(Arena *arena, COFF_MachineType machine, U16 hint); internal String8 coff_make_lib_member_header(Arena *arena, String8 name, COFF_TimeStamp time_stamp, U16 user_id, U16 group_id, U16 mode, U32 size); internal String8 coff_make_import_lookup(Arena *arena, U16 hint, String8 name); internal String8 coff_make_import_header(Arena *arena, COFF_MachineType machine, COFF_TimeStamp time_stamp, String8 dll_name, COFF_ImportByType import_by, String8 name, U16 hint_or_ordinal, COFF_ImportType type); //////////////////////////////// // Misc internal U16 coff_default_align_from_machine (COFF_MachineType machine); internal U8 coff_code_align_byte_from_machine (COFF_MachineType machine); internal U64 coff_word_size_from_machine (COFF_MachineType machine); internal U64 coff_default_exe_base_from_machine(COFF_MachineType machine); internal U64 coff_default_dll_base_from_machine(COFF_MachineType machine); internal Arch arch_from_coff_machine(COFF_MachineType machine); internal U64 coff_foff_from_voff(COFF_SectionHeader *sections, U64 section_count, U64 voff); //////////////////////////////// //~ rjf: Enum <=> String internal String8 coff_string_from_time_stamp(Arena *arena, COFF_TimeStamp time_stamp); internal String8 coff_string_from_comdat_select_type(COFF_ComdatSelectType type); internal String8 coff_string_from_machine_type(COFF_MachineType machine); internal String8 coff_string_from_flags(Arena *arena, COFF_FileHeaderFlags flags); internal String8 coff_string_from_section_flags(Arena *arena, COFF_SectionFlags flags); internal String8 coff_string_from_resource_memory_flags(Arena *arena, COFF_ResourceMemoryFlags flags); internal String8 coff_string_from_import_header_type(COFF_ImportType type); internal String8 coff_string_from_sym_dtype(COFF_SymDType x); internal String8 coff_string_from_sym_type(COFF_SymType x); internal String8 coff_string_from_sym_storage_class(COFF_SymStorageClass x); internal String8 coff_string_from_weak_ext_type(COFF_WeakExtType x); internal String8 coff_string_from_reloc_x86(COFF_Reloc_X86 x); internal String8 coff_string_from_reloc_x64(COFF_Reloc_X64 x); internal String8 coff_string_from_reloc_arm(COFF_Reloc_Arm x); internal String8 coff_string_from_reloc_arm64(COFF_Reloc_Arm64 x); internal String8 coff_string_from_reloc(COFF_MachineType machine, COFF_RelocType x); internal COFF_MachineType coff_machine_from_string(String8 string); internal COFF_ImportType coff_import_header_type_from_string(String8 name); #endif // COFF_H