pass over COFF layer

- updated naming convention on structs, enums, and macros to conform with code base style
- moved related structs closer to each other
- moved parser code to separate file
This commit is contained in:
Nikita Smith
2025-01-20 19:31:52 -08:00
parent 269dc33985
commit 153bbc7b1d
31 changed files with 2659 additions and 2772 deletions
+24 -24
View File
@@ -14,30 +14,30 @@ cv_arch_from_coff_machine(COFF_MachineType machine)
CV_Arch arch = 0;
switch(machine)
{
case COFF_MachineType_X64: arch = CV_Arch_X64; break;
case COFF_MachineType_X86: arch = CV_Arch_8086; break;
case COFF_MachineType_AM33: arch = CV_Arch_AM33; break;
case COFF_MachineType_ARM: NotImplemented; break;
case COFF_MachineType_ARM64: arch = CV_Arch_ARM64; break;
case COFF_MachineType_ARMNT: arch = CV_Arch_ARMNT; break;
case COFF_MachineType_EBC: arch = CV_Arch_EBC; break;
case COFF_MachineType_IA64: arch = CV_Arch_IA64; break;
case COFF_MachineType_M32R: arch = CV_Arch_M32R; break;
case COFF_MachineType_MIPS16: arch = CV_Arch_MIPS16; break;
case COFF_MachineType_MIPSFPU: NotImplemented; break;
case COFF_MachineType_MIPSFPU16: NotImplemented; break;
case COFF_MachineType_POWERPC: NotImplemented; break;
case COFF_MachineType_POWERPCFP: arch = CV_Arch_PPCFP; break;
case COFF_MachineType_R4000: NotImplemented; break;
case COFF_MachineType_RISCV32: NotImplemented; break;
case COFF_MachineType_RISCV64: NotImplemented; break;
case COFF_MachineType_RISCV128: NotImplemented; break;
case COFF_MachineType_SH3: arch = CV_Arch_SH3; break;
case COFF_MachineType_SH3DSP: arch = CV_Arch_SH3DSP; break;
case COFF_MachineType_SH4: arch = CV_Arch_SH4; break;
case COFF_MachineType_SH5: NotImplemented; break;
case COFF_MachineType_THUMB: arch = CV_Arch_THUMB; break;
case COFF_MachineType_WCEMIPSV2: NotImplemented; break;
case COFF_Machine_X64: arch = CV_Arch_X64; break;
case COFF_Machine_X86: arch = CV_Arch_8086; break;
case COFF_Machine_Am33: arch = CV_Arch_AM33; break;
case COFF_Machine_Arm: NotImplemented; break;
case COFF_Machine_Arm64: arch = CV_Arch_ARM64; break;
case COFF_Machine_ArmNt: arch = CV_Arch_ARMNT; break;
case COFF_Machine_Ebc: arch = CV_Arch_EBC; break;
case COFF_Machine_Ia64: arch = CV_Arch_IA64; break;
case COFF_Machine_M32R: arch = CV_Arch_M32R; break;
case COFF_Machine_Mips16: arch = CV_Arch_MIPS16; break;
case COFF_Machine_MipsFpu: NotImplemented; break;
case COFF_Machine_MipsFpu16: NotImplemented; break;
case COFF_Machine_PowerPc: NotImplemented; break;
case COFF_Machine_PowerPcFp: arch = CV_Arch_PPCFP; break;
case COFF_Machine_R4000: NotImplemented; break;
case COFF_Machine_RiscV32: NotImplemented; break;
case COFF_Machine_RiscV64: NotImplemented; break;
case COFF_Machine_RiscV128: NotImplemented; break;
case COFF_Machine_Sh3: arch = CV_Arch_SH3; break;
case COFF_Machine_Sh3Dsp: arch = CV_Arch_SH3DSP; break;
case COFF_Machine_Sh4: arch = CV_Arch_SH4; break;
case COFF_Machine_Sh5: NotImplemented; break;
case COFF_Machine_Thumb: arch = CV_Arch_THUMB; break;
case COFF_Machine_WceMipsV2: NotImplemented; break;
}
return arch;
}
+219 -1230
View File
File diff suppressed because it is too large Load Diff
+400 -711
View File
File diff suppressed because it is too large Load Diff
+226 -241
View File
@@ -21,54 +21,54 @@ read_only struct
String8 string;
COFF_MachineType machine;
} g_coff_machine_map[] = {
{ str8_lit_comp(""), COFF_MachineType_UNKNOWN },
{ str8_lit_comp("X86"), COFF_MachineType_X86 },
{ str8_lit_comp("AMD64"), COFF_MachineType_X64 },
{ str8_lit_comp("X64"), COFF_MachineType_X64 },
{ str8_lit_comp("AM33"), COFF_MachineType_AM33 },
{ str8_lit_comp("ARM"), COFF_MachineType_ARM },
{ str8_lit_comp("ARM64"), COFF_MachineType_ARM64 },
{ str8_lit_comp("ARMNT"), COFF_MachineType_ARMNT },
{ str8_lit_comp("EBC"), COFF_MachineType_EBC },
{ str8_lit_comp("IA64"), COFF_MachineType_IA64 },
{ str8_lit_comp("M32R"), COFF_MachineType_M32R },
{ str8_lit_comp("MIPS16"), COFF_MachineType_MIPS16 },
{ str8_lit_comp("MIPSFPU"), COFF_MachineType_MIPSFPU },
{ str8_lit_comp("MIPSFPU16"), COFF_MachineType_MIPSFPU16 },
{ str8_lit_comp("POWERPC"), COFF_MachineType_POWERPC },
{ str8_lit_comp("POWERPCFP"), COFF_MachineType_POWERPCFP },
{ str8_lit_comp("R4000"), COFF_MachineType_R4000 },
{ str8_lit_comp("RISCV32"), COFF_MachineType_RISCV32 },
{ str8_lit_comp("RISCV64"), COFF_MachineType_RISCV64 },
{ str8_lit_comp("SH3"), COFF_MachineType_SH3 },
{ str8_lit_comp("SH3DSP"), COFF_MachineType_SH3DSP },
{ str8_lit_comp("SH4"), COFF_MachineType_SH4 },
{ str8_lit_comp("SH5"), COFF_MachineType_SH5 },
{ str8_lit_comp("THUMB"), COFF_MachineType_THUMB },
{ str8_lit_comp("WCEMIPSV2"), COFF_MachineType_WCEMIPSV2 },
{ str8_lit_comp(""), COFF_Machine_Unknown },
{ str8_lit_comp("X86"), COFF_Machine_X86 },
{ str8_lit_comp("Amd64"), COFF_Machine_X64 },
{ str8_lit_comp("X64"), COFF_Machine_X64 },
{ str8_lit_comp("Am33"), COFF_Machine_Am33 },
{ str8_lit_comp("Arm"), COFF_Machine_Arm },
{ str8_lit_comp("Arm64"), COFF_Machine_Arm64 },
{ str8_lit_comp("ArmNt"), COFF_Machine_ArmNt },
{ str8_lit_comp("Ebc"), COFF_Machine_Ebc },
{ str8_lit_comp("Ia64"), COFF_Machine_Ia64 },
{ str8_lit_comp("M32r"), COFF_Machine_M32R },
{ str8_lit_comp("Mips16"), COFF_Machine_Mips16 },
{ str8_lit_comp("MipsFpu"), COFF_Machine_MipsFpu },
{ str8_lit_comp("MipsFpu16"), COFF_Machine_MipsFpu16 },
{ str8_lit_comp("PowerPc"), COFF_Machine_PowerPc },
{ str8_lit_comp("PowerPcFp"), COFF_Machine_PowerPcFp },
{ str8_lit_comp("R4000"), COFF_Machine_R4000 },
{ str8_lit_comp("RiscV32"), COFF_Machine_RiscV32 },
{ str8_lit_comp("RiscV64"), COFF_Machine_RiscV64 },
{ str8_lit_comp("Sh3"), COFF_Machine_Sh3 },
{ str8_lit_comp("Sh3Dsp"), COFF_Machine_Sh3Dsp },
{ str8_lit_comp("Sh4"), COFF_Machine_Sh4 },
{ str8_lit_comp("Sh5"), COFF_Machine_Sh5 },
{ str8_lit_comp("Thumb"), COFF_Machine_Thumb },
{ str8_lit_comp("WceMipsV2"), COFF_Machine_WceMipsV2 },
};
read_only static struct {
char * name;
COFF_ImportHeaderType type;
COFF_ImportType type;
} g_coff_import_header_type_map[] = {
{ "CODE", COFF_ImportHeaderType_CODE },
{ "DATA", COFF_ImportHeaderType_DATA },
{ "CONST", COFF_ImportHeaderType_CONST },
{ "Code", COFF_ImportHeader_Code },
{ "Data", COFF_ImportHeader_Data },
{ "Const", COFF_ImportHeader_Const },
};
internal String8
coff_string_from_comdat_select_type(COFF_ComdatSelectType select)
coff_string_from_comdat_select_type(COFF_ComdatSelectType type)
{
String8 result = str8(0,0);
switch (select) {
case COFF_ComdatSelectType_NULL: result = str8_lit("NULL"); break;
case COFF_ComdatSelectType_NODUPLICATES: result = str8_lit("NODUPLICATES"); break;
case COFF_ComdatSelectType_ANY: result = str8_lit("ANY"); break;
case COFF_ComdatSelectType_SAME_SIZE: result = str8_lit("SAME_SIZE"); break;
case COFF_ComdatSelectType_EXACT_MATCH: result = str8_lit("EXACT_MATCH"); break;
case COFF_ComdatSelectType_ASSOCIATIVE: result = str8_lit("ASSOCIATIVE"); break;
case COFF_ComdatSelectType_LARGEST: result = str8_lit("LARGEST"); break;
String8 result = str8_zero();
switch (type) {
case COFF_ComdatSelect_Null: result = str8_lit("Null"); break;
case COFF_ComdatSelect_NoDuplicates: result = str8_lit("NoDuplicates"); break;
case COFF_ComdatSelect_Any: result = str8_lit("Any"); break;
case COFF_ComdatSelect_SameSize: result = str8_lit("SameSize"); break;
case COFF_ComdatSelect_ExactMatch: result = str8_lit("ExactMatch"); break;
case COFF_ComdatSelect_Associative: result = str8_lit("Associative"); break;
case COFF_ComdatSelect_Largest: result = str8_lit("Largest"); break;
}
return result;
}
@@ -85,45 +85,45 @@ coff_string_from_machine_type(COFF_MachineType machine)
}
internal String8
coff_string_from_flags(Arena *arena, COFF_Flags flags)
coff_string_from_flags(Arena *arena, COFF_FileHeaderFlags flags)
{
Temp scratch = scratch_begin(&arena, 1);
String8List list = {0};
if (flags & COFF_Flag_RELOC_STRIPPED) {
if (flags & COFF_FileHeaderFlag_RelocStripped) {
str8_list_pushf(scratch.arena, &list, "Relocs Stripped");
}
if (flags & COFF_Flag_EXECUTABLE_IMAGE) {
if (flags & COFF_FileHeaderFlag_ExecutableImage) {
str8_list_pushf(scratch.arena, &list, "Executable");
}
if (flags & COFF_Flag_LINE_NUMS_STRIPPED) {
if (flags & COFF_FileHeaderFlag_LineNumbersStripped) {
str8_list_pushf(scratch.arena, &list, "Line Numbers Stripped");
}
if (flags & COFF_Flag_SYM_STRIPPED) {
if (flags & COFF_FileHeaderFlag_SymbolsStripped) {
str8_list_pushf(scratch.arena, &list, "Symbols Stripped");
}
if (flags & COFF_Flag_LARGE_ADDRESS_AWARE) {
if (flags & COFF_FileHeaderFlag_LargeAddressAware) {
str8_list_pushf(scratch.arena, &list, "Large Address Aware");
}
if (flags & COFF_Flag_32BIT_MACHINE) {
if (flags & COFF_FileHeaderFlag_32BitMachine) {
str8_list_pushf(scratch.arena, &list, "32-Bit Machine");
}
if (flags & COFF_Flag_DEBUG_STRIPPED) {
if (flags & COFF_FileHeaderFlag_DebugStripped) {
str8_list_pushf(scratch.arena, &list, "Debug Stripped");
}
if (flags & COFF_Flag_REMOVABLE_RUN_FROM_SWAP) {
if (flags & COFF_FileHeaderFlag_RemovableRunFromSwap) {
str8_list_pushf(scratch.arena, &list, "Removeable Run From Swap");
}
if (flags & COFF_Flag_NET_RUN_FROM_SWAP) {
if (flags & COFF_FileHeaderFlag_NetRunFromSwap) {
str8_list_pushf(scratch.arena, &list, "Net Run From Swap");
}
if (flags & COFF_Flag_SYSTEM) {
if (flags & COFF_FileHeaderFlag_System) {
str8_list_pushf(scratch.arena, &list, "System");
}
if (flags & COFF_Flag_DLL) {
if (flags & COFF_FileHeaderFlag_Dll) {
str8_list_pushf(scratch.arena, &list, "DLL");
}
if (flags & COFF_Flag_UP_SYSTEM_ONLY) {
if (flags & COFF_FileHeaderFlag_UpSystemOnly) {
str8_list_pushf(scratch.arena, &list, "Up System Only");
}
@@ -139,62 +139,62 @@ coff_string_from_section_flags(Arena *arena, COFF_SectionFlags flags)
Temp scratch = scratch_begin(&arena, 1);
String8List list = {0};
if (flags & COFF_SectionFlag_TYPE_NO_PAD) {
str8_list_pushf(scratch.arena, &list, "TYPE_NO_PAD");
if (flags & COFF_SectionFlag_TypeNoPad) {
str8_list_pushf(scratch.arena, &list, "TypeNoPad");
}
if (flags & COFF_SectionFlag_CNT_CODE) {
str8_list_pushf(scratch.arena, &list, "CNT_CODE");
if (flags & COFF_SectionFlag_CntCode) {
str8_list_pushf(scratch.arena, &list, "CntCode");
}
if (flags & COFF_SectionFlag_CNT_INITIALIZED_DATA) {
str8_list_pushf(scratch.arena, &list, "CNT_INITIALIZED_DATA");
if (flags & COFF_SectionFlag_CntInitializedData) {
str8_list_pushf(scratch.arena, &list, "CntInitializedData");
}
if (flags & COFF_SectionFlag_CNT_UNINITIALIZED_DATA) {
str8_list_pushf(scratch.arena, &list, "CNT_UNINITIALIZED_DATA");
if (flags & COFF_SectionFlag_CntUninitializedData) {
str8_list_pushf(scratch.arena, &list, "CntUninitializedData");
}
if (flags & COFF_SectionFlag_LNK_OTHER) {
str8_list_pushf(scratch.arena, &list, "LNK_OTHER");
if (flags & COFF_SectionFlag_LnkOther) {
str8_list_pushf(scratch.arena, &list, "LnkOther");
}
if (flags & COFF_SectionFlag_LNK_INFO) {
str8_list_pushf(scratch.arena, &list, "LNK_INFO");
if (flags & COFF_SectionFlag_LnkInfo) {
str8_list_pushf(scratch.arena, &list, "LnkInfo");
}
if (flags & COFF_SectionFlag_LNK_COMDAT) {
str8_list_pushf(scratch.arena, &list, "LNK_COMDAT");
if (flags & COFF_SectionFlag_LnkCOMDAT) {
str8_list_pushf(scratch.arena, &list, "LnkCOMDAT");
}
if (flags & COFF_SectionFlag_GPREL) {
str8_list_pushf(scratch.arena, &list, "GPREL");
if (flags & COFF_SectionFlag_GpRel) {
str8_list_pushf(scratch.arena, &list, "GpRel");
}
if (flags & COFF_SectionFlag_MEM_16BIT) {
str8_list_pushf(scratch.arena, &list, "MEM_16BIT");
if (flags & COFF_SectionFlag_Mem16Bit) {
str8_list_pushf(scratch.arena, &list, "Mem16Bit");
}
if (flags & COFF_SectionFlag_MEM_LOCKED) {
str8_list_pushf(scratch.arena, &list, "MEM_LOCKED");
if (flags & COFF_SectionFlag_MemLocked) {
str8_list_pushf(scratch.arena, &list, "MemLocked");
}
if (flags & COFF_SectionFlag_MEM_PRELOAD) {
str8_list_pushf(scratch.arena, &list, "MEM_PRELOAD");
if (flags & COFF_SectionFlag_MemPreload) {
str8_list_pushf(scratch.arena, &list, "MemPreload");
}
if (flags & COFF_SectionFlag_LNK_NRELOC_OVFL) {
str8_list_pushf(scratch.arena, &list, "LNK_NRELOC_OVFL");
if (flags & COFF_SectionFlag_LnkNRelocOvfl) {
str8_list_pushf(scratch.arena, &list, "LnkNRelocOvfl");
}
if (flags & COFF_SectionFlag_MEM_DISCARDABLE) {
str8_list_pushf(scratch.arena, &list, "MEM_DISCARDABLE");
if (flags & COFF_SectionFlag_MemDiscardable) {
str8_list_pushf(scratch.arena, &list, "MemDiscardable");
}
if (flags & COFF_SectionFlag_MEM_NOT_CACHED) {
str8_list_pushf(scratch.arena, &list, "MEM_NOT_CACHED");
if (flags & COFF_SectionFlag_MemNotCached) {
str8_list_pushf(scratch.arena, &list, "MemNotCached");
}
if (flags & COFF_SectionFlag_MEM_NOT_PAGED) {
str8_list_pushf(scratch.arena, &list, "MEM_NOT_PAGED");
if (flags & COFF_SectionFlag_MemNotPaged) {
str8_list_pushf(scratch.arena, &list, "MemNotPaged");
}
if (flags & COFF_SectionFlag_MEM_SHARED) {
str8_list_pushf(scratch.arena, &list, "MEM_SHARED");
if (flags & COFF_SectionFlag_MemShared) {
str8_list_pushf(scratch.arena, &list, "MemShared");
}
if (flags & COFF_SectionFlag_MEM_EXECUTE) {
str8_list_pushf(scratch.arena, &list, "MEM_EXECUTE");
if (flags & COFF_SectionFlag_MemExecute) {
str8_list_pushf(scratch.arena, &list, "MemExecute");
}
if (flags & COFF_SectionFlag_MEM_READ) {
str8_list_pushf(scratch.arena, &list, "MEM_READ");
if (flags & COFF_SectionFlag_MemRead) {
str8_list_pushf(scratch.arena, &list, "MemRead");
}
if (flags & COFF_SectionFlag_MEM_WRITE) {
str8_list_pushf(scratch.arena, &list, "MEM_WRITE");
if (flags & COFF_SectionFlag_MemWrite) {
str8_list_pushf(scratch.arena, &list, "MemWrite");
}
U64 align = coff_align_size_from_section_flags(flags);
@@ -215,7 +215,7 @@ coff_string_from_section_flags(Arena *arena, COFF_SectionFlags flags)
}
internal String8
coff_string_from_import_header_type(COFF_ImportHeaderType type)
coff_string_from_import_header_type(COFF_ImportType type)
{
for (U64 i = 0; i < ArrayCount(g_coff_import_header_type_map); ++i) {
if (g_coff_import_header_type_map[i].type == type) {
@@ -229,10 +229,10 @@ internal String8
coff_string_from_sym_dtype(COFF_SymDType x)
{
switch (x) {
case COFF_SymDType_NULL: return str8_lit("NULL");
case COFF_SymDType_PTR : return str8_lit("PTR");
case COFF_SymDType_FUNC: return str8_lit("FUNC");
case COFF_SymDType_ARRAY: return str8_lit("ARRAY");
case COFF_SymDType_Null: return str8_lit("Null");
case COFF_SymDType_Ptr : return str8_lit("Ptr");
case COFF_SymDType_Func: return str8_lit("Func");
case COFF_SymDType_Array: return str8_lit("Array");
}
return str8_zero();
}
@@ -241,22 +241,22 @@ internal String8
coff_string_from_sym_type(COFF_SymType x)
{
switch (x) {
case COFF_SymType_NULL: return str8_lit("NULL");
case COFF_SymType_VOID: return str8_lit("VOID");
case COFF_SymType_CHAR: return str8_lit("CHAR");
case COFF_SymType_SHORT: return str8_lit("SHORT");
case COFF_SymType_INT: return str8_lit("INT");
case COFF_SymType_LONG: return str8_lit("LONG");
case COFF_SymType_FLOAT: return str8_lit("FLOAT");
case COFF_SymType_DOUBLE: return str8_lit("DOUBLE");
case COFF_SymType_STRUCT: return str8_lit("STRUCT");
case COFF_SymType_UNION: return str8_lit("UNION");
case COFF_SymType_ENUM: return str8_lit("ENUM");
case COFF_SymType_MOE: return str8_lit("MOE");
case COFF_SymType_BYTE: return str8_lit("BYTE");
case COFF_SymType_WORD: return str8_lit("WORD");
case COFF_SymType_UINT: return str8_lit("UINT");
case COFF_SymType_DWORD: return str8_lit("DWORD");
case COFF_SymType_Null: return str8_lit("Null");
case COFF_SymType_Void: return str8_lit("Void");
case COFF_SymType_Char: return str8_lit("Char");
case COFF_SymType_Short: return str8_lit("Short");
case COFF_SymType_Int: return str8_lit("Int");
case COFF_SymType_Long: return str8_lit("Long");
case COFF_SymType_Float: return str8_lit("Float");
case COFF_SymType_Double: return str8_lit("Double");
case COFF_SymType_Struct: return str8_lit("Struct");
case COFF_SymType_Union: return str8_lit("Union");
case COFF_SymType_Enum: return str8_lit("Enum");
case COFF_SymType_MemberOfEnumeration: return str8_lit("MOE");
case COFF_SymType_Byte: return str8_lit("Byte");
case COFF_SymType_Word: return str8_lit("Word");
case COFF_SymType_UInt: return str8_lit("UInt");
case COFF_SymType_DWord: return str8_lit("DWord");
}
return str8_zero();
}
@@ -265,33 +265,33 @@ internal String8
coff_string_from_sym_storage_class(COFF_SymStorageClass x)
{
switch (x) {
case COFF_SymStorageClass_NULL: break;
case COFF_SymStorageClass_END_OF_FUNCTION: return str8_lit("EOF");
case COFF_SymStorageClass_AUTOMATIC: return str8_lit("AUTOMATIC");
case COFF_SymStorageClass_EXTERNAL: return str8_lit("EXTERNAL");
case COFF_SymStorageClass_STATIC: return str8_lit("STATIC");
case COFF_SymStorageClass_REGISTER: return str8_lit("REGISTER");
case COFF_SymStorageClass_EXTERNAL_DEF: return str8_lit("DEF");
case COFF_SymStorageClass_LABEL: return str8_lit("LABEL");
case COFF_SymStorageClass_UNDEFINED_LABEL: return str8_lit("LABEL");
case COFF_SymStorageClass_MEMBER_OF_STRUCT: return str8_lit("STRUCT");
case COFF_SymStorageClass_ARGUMENT: return str8_lit("ARGUMENT");
case COFF_SymStorageClass_STRUCT_TAG: return str8_lit("TAG");
case COFF_SymStorageClass_MEMBER_OF_UNION: return str8_lit("UNION");
case COFF_SymStorageClass_UNION_TAG: return str8_lit("TAG");
case COFF_SymStorageClass_TYPE_DEFINITION: return str8_lit("DEFINITION");
case COFF_SymStorageClass_UNDEFINED_STATIC: return str8_lit("STATIC");
case COFF_SymStorageClass_ENUM_TAG: return str8_lit("TAG");
case COFF_SymStorageClass_MEMBER_OF_ENUM: return str8_lit("ENUM");
case COFF_SymStorageClass_REGISTER_PARAM: return str8_lit("PARAM");
case COFF_SymStorageClass_BIT_FIELD: return str8_lit("FIELD");
case COFF_SymStorageClass_BLOCK: return str8_lit("BLOCK");
case COFF_SymStorageClass_FUNCTION: return str8_lit("FUNCTION");
case COFF_SymStorageClass_END_OF_STRUCT: return str8_lit("STRUCT");
case COFF_SymStorageClass_FILE: return str8_lit("FILE");
case COFF_SymStorageClass_SECTION: return str8_lit("SECTION");
case COFF_SymStorageClass_WEAK_EXTERNAL: return str8_lit("EXTERNAL");
case COFF_SymStorageClass_CLR_TOKEN: return str8_lit("TOKEN");
case COFF_SymStorageClass_Null: break;
case COFF_SymStorageClass_EndOfFunction: return str8_lit("EndOfFunction");
case COFF_SymStorageClass_Automatic: return str8_lit("Automatic");
case COFF_SymStorageClass_External: return str8_lit("External");
case COFF_SymStorageClass_Static: return str8_lit("Static");
case COFF_SymStorageClass_Register: return str8_lit("Register");
case COFF_SymStorageClass_ExternalDef: return str8_lit("Def");
case COFF_SymStorageClass_Label: return str8_lit("Label");
case COFF_SymStorageClass_UndefinedLabel: return str8_lit("UndefinedLabel");
case COFF_SymStorageClass_MemberOfStruct: return str8_lit("Struct");
case COFF_SymStorageClass_Argument: return str8_lit("Argument");
case COFF_SymStorageClass_StructTag: return str8_lit("Tag");
case COFF_SymStorageClass_MemberOfUnion: return str8_lit("Union");
case COFF_SymStorageClass_UnionTag: return str8_lit("Tag");
case COFF_SymStorageClass_TypeDefinition: return str8_lit("Definition");
case COFF_SymStorageClass_UndefinedStatic: return str8_lit("Static");
case COFF_SymStorageClass_EnumTag: return str8_lit("Tag");
case COFF_SymStorageClass_MemberOfEnum: return str8_lit("Enum");
case COFF_SymStorageClass_RegisterParam: return str8_lit("Param");
case COFF_SymStorageClass_BitField: return str8_lit("Field");
case COFF_SymStorageClass_Block: return str8_lit("Block");
case COFF_SymStorageClass_Function: return str8_lit("Function");
case COFF_SymStorageClass_EndOfStruct: return str8_lit("Struct");
case COFF_SymStorageClass_File: return str8_lit("File");
case COFF_SymStorageClass_Section: return str8_lit("Section");
case COFF_SymStorageClass_WeakExternal: return str8_lit("External");
case COFF_SymStorageClass_CLRToken: return str8_lit("Token");
}
return str8_zero();
}
@@ -300,130 +300,115 @@ internal String8
coff_string_from_weak_ext_type(COFF_WeakExtType x)
{
switch (x) {
case COFF_WeakExtType_NOLIBRARY: return str8_lit("NOLIBRARY");
case COFF_WeakExtType_SEARCH_LIBRARY: return str8_lit("SEARCH_LIBRARY");
case COFF_WeakExtType_SEARCH_ALIAS: return str8_lit("SEARCH_ALIAS");
case COFF_WeakExt_NoLibrary: return str8_lit("NoLibrary");
case COFF_WeakExt_SearchLibrary: return str8_lit("SearchLibrary");
case COFF_WeakExt_SearchAlias: return str8_lit("SearchAlias");
}
return str8_zero();
}
internal String8
coff_string_from_selection(COFF_ComdatSelectType x)
coff_string_from_reloc_x86(COFF_Reloc_X86 x)
{
switch (x) {
case COFF_ComdatSelectType_NULL: break;
case COFF_ComdatSelectType_NODUPLICATES: return str8_lit("NODUPLICATES");
case COFF_ComdatSelectType_ANY: return str8_lit("ANY");
case COFF_ComdatSelectType_SAME_SIZE: return str8_lit("SIZE");
case COFF_ComdatSelectType_EXACT_MATCH: return str8_lit("MATCH");
case COFF_ComdatSelectType_ASSOCIATIVE: return str8_lit("ASSOCIATIVE");
case COFF_ComdatSelectType_LARGEST: return str8_lit("LARGEST");
case COFF_Reloc_X86_Abs: return str8_lit("Abs");
case COFF_Reloc_X86_Dir16: return str8_lit("Dir16");
case COFF_Reloc_X86_Rel16: return str8_lit("Rel16");
case COFF_Reloc_X86_Unknown0: return str8_lit("Unknown0");
case COFF_Reloc_X86_Unknown2: return str8_lit("Unknown2");
case COFF_Reloc_X86_Unknown3: return str8_lit("Unknown3");
case COFF_Reloc_X86_Dir32: return str8_lit("Dir32");
case COFF_Reloc_X86_Dir32Nb: return str8_lit("Dir32Nb");
case COFF_Reloc_X86_Seg12: return str8_lit("Seg12");
case COFF_Reloc_X86_Section: return str8_lit("Section");
case COFF_Reloc_X86_SecRel: return str8_lit("SecRel");
case COFF_Reloc_X86_Token: return str8_lit("Token");
case COFF_Reloc_X86_SecRel7: return str8_lit("SecRel7");
case COFF_Reloc_X86_Unknown4: return str8_lit("Unknown4");
case COFF_Reloc_X86_Unknown5: return str8_lit("Unknown5");
case COFF_Reloc_X86_Unknown6: return str8_lit("Unknown6");
case COFF_Reloc_X86_Unknown7: return str8_lit("Unknown7");
case COFF_Reloc_X86_Unknown8: return str8_lit("Unknown8");
case COFF_Reloc_X86_Unknown9: return str8_lit("Unknown9");
case COFF_Reloc_X86_Rel32: return str8_lit("Rel32");
}
return str8_zero();
}
internal String8
coff_string_from_reloc_x86(COFF_RelocTypeX86 x)
coff_string_from_reloc_x64(COFF_Reloc_X64 x)
{
switch (x) {
case COFF_RelocTypeX86_ABS: return str8_lit("ABS");
case COFF_RelocTypeX86_DIR16: return str8_lit("DIR16");
case COFF_RelocTypeX86_REL16: return str8_lit("REL16");
case COFF_RelocTypeX86_UNKNOWN0: return str8_lit("UNKNOWN0");
case COFF_RelocTypeX86_UNKNOWN2: return str8_lit("UNKNOWN2");
case COFF_RelocTypeX86_UNKNOWN3: return str8_lit("UNKNOWN3");
case COFF_RelocTypeX86_DIR32: return str8_lit("DIR32");
case COFF_RelocTypeX86_DIR32NB: return str8_lit("DIR32NB");
case COFF_RelocTypeX86_SEG12: return str8_lit("SEG12");
case COFF_RelocTypeX86_SECTION: return str8_lit("SECTION");
case COFF_RelocTypeX86_SECREL: return str8_lit("SECREL");
case COFF_RelocTypeX86_TOKEN: return str8_lit("TOKEN");
case COFF_RelocTypeX86_SECREL7: return str8_lit("SECREL7");
case COFF_RelocTypeX86_UNKNOWN4: return str8_lit("UNKNOWN4");
case COFF_RelocTypeX86_UNKNOWN5: return str8_lit("UNKNOWN5");
case COFF_RelocTypeX86_UNKNOWN6: return str8_lit("UNKNOWN6");
case COFF_RelocTypeX86_UNKNOWN7: return str8_lit("UNKNOWN7");
case COFF_RelocTypeX86_UNKNOWN8: return str8_lit("UNKNOWN8");
case COFF_RelocTypeX86_UNKNOWN9: return str8_lit("UNKNOWN9");
case COFF_RelocTypeX86_REL32: return str8_lit("REL32");
case COFF_Reloc_X64_Abs: return str8_lit("Abs");
case COFF_Reloc_X64_Addr64: return str8_lit("Addr64");
case COFF_Reloc_X64_Addr32: return str8_lit("Addr32");
case COFF_Reloc_X64_Addr32Nb: return str8_lit("Addr32Nb");
case COFF_Reloc_X64_Rel32: return str8_lit("Rel32");
case COFF_Reloc_X64_Rel32_1: return str8_lit("Rel32_1");
case COFF_Reloc_X64_Rel32_2: return str8_lit("Rel32_2");
case COFF_Reloc_X64_Rel32_3: return str8_lit("Rel32_3");
case COFF_Reloc_X64_Rel32_4: return str8_lit("Rel32_4");
case COFF_Reloc_X64_Rel32_5: return str8_lit("Rel32_5");
case COFF_Reloc_X64_Section: return str8_lit("Section");
case COFF_Reloc_X64_SecRel: return str8_lit("SecRel");
case COFF_Reloc_X64_SecRel7: return str8_lit("SecRel7");
case COFF_Reloc_X64_Token: return str8_lit("Token");
case COFF_Reloc_X64_SRel32: return str8_lit("SRel32");
case COFF_Reloc_X64_Pair: return str8_lit("Pair");
case COFF_Reloc_X64_SSpan32: return str8_lit("SSpan32");
}
return str8_zero();
}
internal String8
coff_string_from_reloc_x64(COFF_RelocTypeX64 x)
coff_string_from_reloc_arm(COFF_Reloc_Arm x)
{
switch (x) {
case COFF_RelocTypeX64_ABS: return str8_lit("ABS");
case COFF_RelocTypeX64_ADDR64: return str8_lit("ADDR64");
case COFF_RelocTypeX64_ADDR32: return str8_lit("ADDR32");
case COFF_RelocTypeX64_ADDR32NB: return str8_lit("ADDR32NB");
case COFF_RelocTypeX64_REL32: return str8_lit("REL32");
case COFF_RelocTypeX64_REL32_1: return str8_lit("REL32_1");
case COFF_RelocTypeX64_REL32_2: return str8_lit("REL32_2");
case COFF_RelocTypeX64_REL32_3: return str8_lit("REL32_3");
case COFF_RelocTypeX64_REL32_4: return str8_lit("REL32_4");
case COFF_RelocTypeX64_REL32_5: return str8_lit("REL32_5");
case COFF_RelocTypeX64_SECTION: return str8_lit("SECTION");
case COFF_RelocTypeX64_SECREL: return str8_lit("SECREL");
case COFF_RelocTypeX64_SECREL7: return str8_lit("SECREL7");
case COFF_RelocTypeX64_TOKEN: return str8_lit("TOKEN");
case COFF_RelocTypeX64_SREL32: return str8_lit("SREL32");
case COFF_RelocTypeX64_PAIR: return str8_lit("PAIR");
case COFF_RelocTypeX64_SSPAN32: return str8_lit("SSPAN32");
case COFF_Reloc_Arm_Abs: return str8_lit("Abs");
case COFF_Reloc_Arm_Addr32: return str8_lit("Addr32");
case COFF_Reloc_Arm_Addr32Nb: return str8_lit("Addr32Nb");
case COFF_Reloc_Arm_Branch24: return str8_lit("Branch24");
case COFF_Reloc_Arm_Branch11: return str8_lit("Branch11");
case COFF_Reloc_Arm_Unknown1: return str8_lit("Unknown1");
case COFF_Reloc_Arm_Unknown2: return str8_lit("Unknown2");
case COFF_Reloc_Arm_Unknown3: return str8_lit("Unknown3");
case COFF_Reloc_Arm_Unknown4: return str8_lit("Unknown4");
case COFF_Reloc_Arm_Unknown5: return str8_lit("Unknown5");
case COFF_Reloc_Arm_Rel32: return str8_lit("Rel32");
case COFF_Reloc_Arm_Section: return str8_lit("Section");
case COFF_Reloc_Arm_SecRel: return str8_lit("SecRel");
case COFF_Reloc_Arm_Mov32: return str8_lit("Mov32");
case COFF_Reloc_Arm_ThumbMov32: return str8_lit("ThumbMov32");
case COFF_Reloc_Arm_ThumbBranch20: return str8_lit("ThumbBranch20");
case COFF_Reloc_Arm_Unused: return str8_lit("Unused");
case COFF_Reloc_Arm_ThumbBranch24: return str8_lit("ThumbBranch24");
case COFF_Reloc_Arm_ThumbBlx23: return str8_lit("ThumbBlx23");
case COFF_Reloc_Arm_Pair: return str8_lit("Pair");
}
return str8_zero();
}
internal String8
coff_string_from_reloc_arm(COFF_RelocTypeARM x)
coff_string_from_reloc_arm64(COFF_Reloc_Arm64 x)
{
switch (x) {
case COFF_RelocTypeARM_ABS: return str8_lit("ABS");
case COFF_RelocTypeARM_ADDR32: return str8_lit("ADDR32");
case COFF_RelocTypeARM_ADDR32NB: return str8_lit("ADDR32NB");
case COFF_RelocTypeARM_BRANCH24: return str8_lit("BRANCH24");
case COFF_RelocTypeARM_BRANCH11: return str8_lit("BRANCH11");
case COFF_RelocTypeARM_UNKNOWN1: return str8_lit("UNKNOWN1");
case COFF_RelocTypeARM_UNKNOWN2: return str8_lit("UNKNOWN2");
case COFF_RelocTypeARM_UNKNOWN3: return str8_lit("UNKNOWN3");
case COFF_RelocTypeARM_UNKNOWN4: return str8_lit("UNKNOWN4");
case COFF_RelocTypeARM_UNKNOWN5: return str8_lit("UNKNOWN5");
case COFF_RelocTypeARM_REL32: return str8_lit("REL32");
case COFF_RelocTypeARM_SECTION: return str8_lit("SECTION");
case COFF_RelocTypeARM_SECREL: return str8_lit("SECREL");
case COFF_RelocTypeARM_MOV32: return str8_lit("MOV32");
case COFF_RelocTypeARM_THUMB_MOV32: return str8_lit("THUMB_MOV32");
case COFF_RelocTypeARM_THUMB_BRANCH20: return str8_lit("THUMB_BRANCH20");
case COFF_RelocTypeARM_UNUSED: return str8_lit("UNUSED");
case COFF_RelocTypeARM_THUMB_BRANCH24: return str8_lit("THUMB_BRANCH24");
case COFF_RelocTypeARM_THUMB_BLX23: return str8_lit("THUMB_BLX23");
case COFF_RelocTypeARM_PAIR: return str8_lit("PAIR");
}
return str8_zero();
}
internal String8
coff_string_from_reloc_arm64(COFF_RelocTypeARM64 x)
{
switch (x) {
case COFF_RelocTypeARM64_ABS: return str8_lit("ABS");
case COFF_RelocTypeARM64_ADDR32: return str8_lit("ADDR32");
case COFF_RelocTypeARM64_ADDR32NB: return str8_lit("ADDR32NB");
case COFF_RelocTypeARM64_BRANCH26: return str8_lit("BRANCH26");
case COFF_RelocTypeARM64_PAGEBASE_REL21: return str8_lit("PAGEBASE_REL21");
case COFF_RelocTypeARM64_REL21: return str8_lit("REL21");
case COFF_RelocTypeARM64_PAGEOFFSET_12A: return str8_lit("PAGEOFFSET_12A");
case COFF_RelocTypeARM64_SECREL: return str8_lit("SECREL");
case COFF_RelocTypeARM64_SECREL_LOW12A: return str8_lit("SECREL_LOW12A");
case COFF_RelocTypeARM64_SECREL_HIGH12A: return str8_lit("SECREL_HIGH12A");
case COFF_RelocTypeARM64_SECREL_LOW12L: return str8_lit("SECREL_LOW12L");
case COFF_RelocTypeARM64_TOKEN: return str8_lit("TOKEN");
case COFF_RelocTypeARM64_SECTION: return str8_lit("SECTION");
case COFF_RelocTypeARM64_ADDR64: return str8_lit("ADDR64");
case COFF_RelocTypeARM64_BRANCH19: return str8_lit("BRANCH19");
case COFF_RelocTypeARM64_BRANCH14: return str8_lit("BRANCH14");
case COFF_RelocTypeARM64_REL32: return str8_lit("REL32");
case COFF_Reloc_Arm64_Abs: return str8_lit("Abs");
case COFF_Reloc_Arm64_Addr32: return str8_lit("Addr32");
case COFF_Reloc_Arm64_Addr32Nb: return str8_lit("Addr32Nb");
case COFF_Reloc_Arm64_Branch26: return str8_lit("Branch26");
case COFF_Reloc_Arm64_PageBaseRel21: return str8_lit("PageBaseRel21");
case COFF_Reloc_Arm64_Rel21: return str8_lit("Rel21");
case COFF_Reloc_Arm64_PageOffset12a: return str8_lit("PageOffset12a");
case COFF_Reloc_Arm64_SecRel: return str8_lit("SecRel");
case COFF_Reloc_Arm64_SecRelLow12a: return str8_lit("SecRelLow12a");
case COFF_Reloc_Arm64_SecRelHigh12a: return str8_lit("SecRelHigh12a");
case COFF_Reloc_Arm64_SecRelLow12l: return str8_lit("SecRelLow12l");
case COFF_Reloc_Arm64_Token: return str8_lit("Token");
case COFF_Reloc_Arm64_Section: return str8_lit("Section");
case COFF_Reloc_Arm64_Addr64: return str8_lit("Addr64");
case COFF_Reloc_Arm64_Branch19: return str8_lit("Branch19");
case COFF_Reloc_Arm64_Branch14: return str8_lit("Branch14");
case COFF_Reloc_Arm64_Rel32: return str8_lit("Rel32");
}
return str8_zero();
}
@@ -432,10 +417,10 @@ internal String8
coff_string_from_reloc(COFF_MachineType machine, COFF_RelocType x)
{
switch (machine) {
case COFF_MachineType_X86: return coff_string_from_reloc_x86(x);
case COFF_MachineType_X64: return coff_string_from_reloc_x64(x);
case COFF_MachineType_ARM: return coff_string_from_reloc_arm(x);
case COFF_MachineType_ARM64: return coff_string_from_reloc_arm64(x);
case COFF_Machine_X86: return coff_string_from_reloc_x86(x);
case COFF_Machine_X64: return coff_string_from_reloc_x64(x);
case COFF_Machine_Arm: return coff_string_from_reloc_arm(x);
case COFF_Machine_Arm64: return coff_string_from_reloc_arm64(x);
}
return str8_zero();
}
@@ -448,10 +433,10 @@ coff_machine_from_string(String8 string)
return g_coff_machine_map[i].machine;
}
}
return COFF_MachineType_UNKNOWN;
return COFF_Machine_Unknown;
}
internal COFF_ImportHeaderType
internal COFF_ImportType
coff_import_header_type_from_string(String8 name)
{
for (U64 i = 0; i < ArrayCount(g_coff_import_header_type_map); ++i) {
@@ -459,7 +444,7 @@ coff_import_header_type_from_string(String8 name)
return g_coff_import_header_type_map[i].type;
}
}
return COFF_ImportHeaderType_COUNT;
return COFF_ImportType_Invalid;
}
+9 -10
View File
@@ -5,23 +5,22 @@
#define COFF_ENUM_H
internal String8 coff_string_from_time_stamp(Arena *arena, COFF_TimeStamp time_stamp);
internal String8 coff_string_from_comdat_select_type(COFF_ComdatSelectType select);
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_Flags flags);
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_import_header_type(COFF_ImportHeaderType type);
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_selection(COFF_ComdatSelectType x);
internal String8 coff_string_from_reloc_x86(COFF_RelocTypeX86 x);
internal String8 coff_string_from_reloc_x64(COFF_RelocTypeX64 x);
internal String8 coff_string_from_reloc_arm(COFF_RelocTypeARM x);
internal String8 coff_string_from_reloc_arm64(COFF_RelocTypeARM64 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_ImportHeaderType coff_import_header_type_from_string(String8 name);
internal COFF_MachineType coff_machine_from_string(String8 string);
internal COFF_ImportType coff_import_header_type_from_string(String8 name);
#endif // COFF_ENUM_H
+904
View File
@@ -0,0 +1,904 @@
// Copyright (c) 2024 Epic Games Tools
// Licensed under the MIT license (https://opensource.org/license/mit/)
internal B32
coff_is_big_obj(String8 raw_coff)
{
B32 is_big_obj = 0;
if (raw_coff.size >= sizeof(COFF_BigObjHeader)) {
COFF_BigObjHeader *file_header32 = (COFF_BigObjHeader*)(raw_coff.str);
is_big_obj = file_header32->sig1 == COFF_Machine_Unknown &&
file_header32->sig2 == max_U16 &&
file_header32->version >= 2 &&
MemoryCompare(file_header32->magic, g_coff_big_header_magic, sizeof(file_header32->magic)) == 0;
}
return is_big_obj;
}
internal B32
coff_is_obj(String8 raw_coff)
{
B32 is_obj = 0;
if (raw_coff.size >= sizeof(COFF_FileHeader)) {
COFF_FileHeader *header = (COFF_FileHeader*)(raw_coff.str);
// validate machine
B32 is_machine_type_valid = 0;
switch (header->machine) {
case COFF_Machine_Unknown:
case COFF_Machine_X86: case COFF_Machine_X64:
case COFF_Machine_Am33: case COFF_Machine_Arm:
case COFF_Machine_Arm64: case COFF_Machine_ArmNt:
case COFF_Machine_Ebc: case COFF_Machine_Ia64:
case COFF_Machine_M32R: case COFF_Machine_Mips16:
case COFF_Machine_MipsFpu:case COFF_Machine_MipsFpu16:
case COFF_Machine_PowerPc:case COFF_Machine_PowerPcFp:
case COFF_Machine_R4000: case COFF_Machine_RiscV32:
case COFF_Machine_RiscV64:case COFF_Machine_RiscV128:
case COFF_Machine_Sh3: case COFF_Machine_Sh3Dsp:
case COFF_Machine_Sh4: case COFF_Machine_Sh5:
case COFF_Machine_Thumb: case COFF_Machine_WceMipsV2:
{
is_machine_type_valid = 1;
}break;
}
if (is_machine_type_valid) {
// validate section count
U64 section_count = header->section_count;
U64 section_hdr_opl_off = sizeof(*header) + section_count*sizeof(COFF_SectionHeader);
if (raw_coff.size >= section_hdr_opl_off) {
COFF_SectionHeader *section_hdrs = (COFF_SectionHeader*)(raw_coff.str + sizeof(*header));
COFF_SectionHeader *section_hdr_opl = section_hdrs + section_count;
// validate section ranges
B32 is_sect_range_valid = 1;
for (COFF_SectionHeader *sec_hdr = section_hdrs;
sec_hdr < section_hdr_opl;
sec_hdr += 1) {
if (!(sec_hdr->flags & COFF_SectionFlag_CntUninitializedData)) {
U64 min = sec_hdr->foff;
U64 max = min + sec_hdr->fsize;
if (sec_hdr->fsize > 0 && !(section_hdr_opl_off <= min && min <= max && max <= raw_coff.size)) {
is_sect_range_valid = 0;
break;
}
}
}
if (is_sect_range_valid) {
// validate symbol table
U64 symbol_table_off = header->symbol_table_foff;
U64 symbol_table_size = sizeof(COFF_Symbol16)*header->symbol_count;
U64 symbol_table_opl_off = symbol_table_off + symbol_table_size;
// don't validate symbol table when there is none
if (symbol_table_off == 0 && symbol_table_size == 0) {
symbol_table_off = section_hdr_opl_off;
symbol_table_opl_off = section_hdr_opl_off;
}
is_obj = (section_hdr_opl_off <= symbol_table_off &&
symbol_table_off <= symbol_table_opl_off &&
symbol_table_opl_off <= raw_coff.size);
}
}
}
}
return is_obj;
}
internal COFF_FileHeaderInfo
coff_file_header_info_from_data(String8 raw_coff)
{
COFF_FileHeaderInfo info = {0};
if (coff_is_big_obj(raw_coff)) {
COFF_BigObjHeader *header32 = (COFF_BigObjHeader*)raw_coff.str;
info.is_big_obj = 1;
info.machine = header32->machine;
info.header_size = sizeof(COFF_BigObjHeader);
info.section_array_off = sizeof(COFF_BigObjHeader);
info.section_count_no_null = header32->section_count;
info.string_table_off = header32->symbol_table_foff + sizeof(COFF_Symbol32) * header32->symbol_count;
info.symbol_size = sizeof(COFF_Symbol32);
info.symbol_off = header32->symbol_table_foff;
info.symbol_count = header32->symbol_count;
} else if (coff_is_obj(raw_coff)) {
COFF_FileHeader *header16 = (COFF_FileHeader*)raw_coff.str;
info.is_big_obj = 0;
info.machine = header16->machine;
info.header_size = sizeof(COFF_FileHeader);
info.section_array_off = sizeof(COFF_FileHeader);
info.section_count_no_null = header16->section_count;
info.string_table_off = header16->symbol_table_foff + sizeof(COFF_Symbol16) * header16->symbol_count;
info.symbol_size = sizeof(COFF_Symbol16);
info.symbol_off = header16->symbol_table_foff;
info.symbol_count = header16->symbol_count;
}
return info;
}
internal COFF_ParsedSymbol
coff_parse_symbol32(String8 raw_coff, U64 string_table_off, COFF_Symbol32 *sym32)
{
COFF_ParsedSymbol result = {0};
result.name = coff_read_symbol_name(raw_coff, string_table_off, &sym32->name);
result.value = sym32->value;
result.section_number = sym32->section_number;
result.type = sym32->type;
result.storage_class = sym32->storage_class;
result.aux_symbol_count = sym32->aux_symbol_count;
return result;
}
internal COFF_ParsedSymbol
coff_parse_symbol16(String8 raw_coff, U64 string_table_off, COFF_Symbol16 *sym16)
{
COFF_ParsedSymbol result = {0};
result.name = coff_read_symbol_name(raw_coff, string_table_off, &sym16->name);
result.value = sym16->value;
if (sym16->section_number == COFF_Symbol_DebugSection16) {
result.section_number = COFF_Symbol_DebugSection32;
} else if (sym16->section_number == COFF_Symbol_AbsSection16) {
result.section_number = COFF_Symbol_AbsSection32;
} else {
result.section_number = (U32)sym16->section_number;
}
result.type = sym16->type;
result.storage_class = sym16->storage_class;
result.aux_symbol_count = sym16->aux_symbol_count;
return result;
}
internal COFF_Symbol32Array
coff_symbol_array_from_data_16(Arena *arena, String8 raw_coff, U64 symbol_array_off, U64 symbol_count)
{
COFF_Symbol32Array result = {0};
result.count = symbol_count;
result.v = push_array_no_zero_aligned(arena, COFF_Symbol32, result.count, 8);
Rng1U64 sym16_arr_range = rng_1u64(symbol_array_off, symbol_array_off + sizeof(COFF_Symbol16) * symbol_count);
String8 raw_sym16_arr = str8_substr(raw_coff, sym16_arr_range);
COFF_Symbol16 *sym16_arr = (COFF_Symbol16 *)raw_sym16_arr.str;
for (U64 isymbol = 0, count = raw_sym16_arr.size / sizeof(COFF_Symbol16); isymbol < count; isymbol += 1) {
COFF_Symbol16 *sym16 = &sym16_arr[isymbol];
COFF_Symbol32 *sym32 = &result.v[isymbol];
sym32->name = sym16->name;
sym32->value = sym16->value;
if (sym16->section_number == COFF_Symbol_DebugSection16) {
sym32->section_number = COFF_Symbol_DebugSection32;
} else if (sym16->section_number == COFF_Symbol_AbsSection16) {
sym32->section_number = COFF_Symbol_AbsSection32;
} else {
sym32->section_number = (U32)sym16->section_number;
}
sym32->type.v = sym16->type.v;
sym32->storage_class = sym16->storage_class;
sym32->aux_symbol_count = sym16->aux_symbol_count;
// copy aux symbols
for (U64 iaux = isymbol+1, iaux_hi = Min(count, iaux+sym16->aux_symbol_count); iaux < iaux_hi; iaux += 1) {
COFF_Symbol16 *aux16 = sym16_arr + iaux;
COFF_Symbol32 *aux32 = result.v + iaux;
// 32bit COFF uses 16bit aux symbols
MemoryCopy(aux32, aux16, sizeof(COFF_Symbol16));
MemoryZero((U8 *)aux32 + sizeof(COFF_Symbol16), sizeof(COFF_Symbol32)-sizeof(COFF_Symbol16));
}
// take into account aux symbols
isymbol += sym32->aux_symbol_count;
}
return result;
}
internal COFF_Symbol32Array
coff_symbol_array_from_data_32(Arena *arena, String8 data, U64 symbol_array_off, U64 symbol_count)
{
COFF_Symbol32Array result;
result.count = symbol_count;
result.v = (COFF_Symbol32 *)(data.str + symbol_array_off);
return result;
}
internal COFF_Symbol32Array
coff_symbol_array_from_data(Arena *arena, String8 data, U64 symbol_array_off, U64 symbol_count, U64 symbol_size)
{
COFF_Symbol32Array result = {0};
switch (symbol_size) {
case sizeof(COFF_Symbol16): result = coff_symbol_array_from_data_16(arena, data, symbol_array_off, symbol_count); break;
case sizeof(COFF_Symbol32): result = coff_symbol_array_from_data_32(arena, data, symbol_array_off, symbol_count); break;
}
return result;
}
internal COFF_Symbol16Node *
coff_symbol16_list_push(Arena *arena, COFF_Symbol16List *list, COFF_Symbol16 symbol)
{
COFF_Symbol16Node *node = push_array(arena, COFF_Symbol16Node, 1);
node->next = 0;
node->data = symbol;
SLLQueuePush(list->first, list->last, node);
list->count += 1;
return node;
}
internal COFF_SymbolValueInterpType
coff_interp_symbol(U32 section_number, U32 value, COFF_SymStorageClass storage_class)
{
if (storage_class == COFF_SymStorageClass_Section && section_number == COFF_Symbol_UndefinedSection) {
return COFF_SymbolValueInterp_Undefined;
}
if (storage_class == COFF_SymStorageClass_External && value == 0 && section_number == COFF_Symbol_UndefinedSection) {
return COFF_SymbolValueInterp_Undefined;
}
if (storage_class == COFF_SymStorageClass_External && value != 0 && section_number == COFF_Symbol_UndefinedSection) {
return COFF_SymbolValueInterp_Common;
}
if (section_number == COFF_Symbol_AbsSection32) {
return COFF_SymbolValueInterp_Abs;
}
if (section_number == COFF_Symbol_DebugSection32) {
return COFF_SymbolValueInterp_Debug;
}
if (storage_class == COFF_SymStorageClass_WeakExternal) {
return COFF_SymbolValueInterp_Weak;
}
return COFF_SymbolValueInterp_Regular;
}
internal COFF_RelocNode *
coff_reloc_list_push(Arena *arena, COFF_RelocList *list, COFF_Reloc reloc)
{
COFF_RelocNode *node = push_array(arena, COFF_RelocNode, 1);
node->data = reloc;
SLLQueuePush(list->first, list->last, node);
++list->count;
return node;
}
internal COFF_RelocInfo
coff_reloc_info_from_section_header(String8 data, COFF_SectionHeader *header)
{
COFF_RelocInfo result = {0};
if (header->flags & COFF_SectionFlag_LnkNRelocOvfl && header->reloc_count == max_U16) {
COFF_Reloc counter;
U64 read_size = str8_deserial_read_struct(data, header->relocs_foff, &counter);
if (read_size == sizeof(counter) && counter.apply_off > 0) {
result.array_off = header->relocs_foff + sizeof(COFF_Reloc);
result.count = counter.apply_off - 1; // exclude counter entry
}
} else {
result.array_off = header->relocs_foff;
result.count = header->reloc_count;
}
return result;
}
internal String8
coff_resource_string_from_str16(Arena *arena, String16 string)
{
AssertAlways(string.size <= max_U16);
U16 size16 = (U16)string.size;
U16 *buffer = push_array_no_zero(arena, U16, size16 + 1);
MemoryCopy(buffer + 0, &size16, sizeof(size16));
MemoryCopy(buffer + 1, string.str, size16 * sizeof(string.str[0]));
return str8_array(buffer, size16 + 1);
}
internal String8
coff_resource_string_from_str8(Arena *arena, String8 string)
{
Temp scratch = scratch_begin(&arena, 1);
String16 string16 = str16_from_8(scratch.arena, string);
String8 result = coff_resource_string_from_str16(arena, string16);
scratch_end(scratch);
return result;
}
internal String8
coff_resource_number_from_u16(Arena *arena, U16 number)
{
U16 *buffer = push_array_no_zero(arena, U16, 2);
buffer[0] = max_U16;
buffer[1] = number;
return str8_array(buffer, 2);
}
internal COFF_ResourceID
coff_utf8_resource_id_from_utf16(Arena *arena, COFF_ResourceID16 *id_16)
{
COFF_ResourceID id = {0};
id.type = id_16->type;
switch (id_16->type) {
case COFF_ResourceIDType_Null: break;
case COFF_ResourceIDType_Number: {
id.u.number = id_16->u.number;
} break;
case COFF_ResourceIDType_String: {
id.u.string = str8_from_16(arena, id_16->u.string);
} break;
default: InvalidPath;
}
return id;
}
internal U64
coff_read_resource_id_utf16(String8 raw_res, U64 off, COFF_ResourceID16 *id_out)
{
U64 cursor = off;
U16 flag = 0;
str8_deserial_read_struct(raw_res, cursor, &flag);
if (flag == max_U16) {
id_out->type = COFF_ResourceIDType_Number;
cursor += sizeof(flag);
cursor += str8_deserial_read_struct(raw_res, cursor, &id_out->u.number);
} else {
id_out->type = COFF_ResourceIDType_String;
cursor += str8_deserial_read_windows_utf16_string16(raw_res, cursor, &id_out->u.string);
}
U64 read_size = cursor - off;
read_size = AlignPow2(read_size, COFF_ResourceAlign);
return read_size;
}
internal U64
coff_read_resource(Arena *arena, String8 raw_res, U64 off, COFF_ParsedResource *res_out)
{
String8 raw_header = str8_skip(raw_res, off);
U64 header_cursor = 0;
// prefix
COFF_ResourceHeaderPrefix prefix = {0};
header_cursor += str8_deserial_read_struct(raw_header, header_cursor, &prefix);
Assert(prefix.header_size >= sizeof(COFF_ResourceHeaderPrefix));
raw_header = str8_prefix(raw_header, prefix.header_size);
// header
COFF_ResourceID16 type_16 = {0};
COFF_ResourceID16 name_16 = {0};
header_cursor += coff_read_resource_id_utf16(raw_header, header_cursor, &type_16);
header_cursor += coff_read_resource_id_utf16(raw_header, header_cursor, &name_16);
header_cursor += str8_deserial_read_struct(raw_header, header_cursor, &res_out->data_version);
header_cursor += str8_deserial_read_struct(raw_header, header_cursor, &res_out->memory_flags);
header_cursor += str8_deserial_read_struct(raw_header, header_cursor, &res_out->language_id);
header_cursor += str8_deserial_read_struct(raw_header, header_cursor, &res_out->version);
header_cursor += str8_deserial_read_struct(raw_header, header_cursor, &res_out->characteristics);
Assert(prefix.header_size == header_cursor);
// convert utf-16 resource ids to utf-8
res_out->type = coff_utf8_resource_id_from_utf16(arena, &type_16);
res_out->name = coff_utf8_resource_id_from_utf16(arena, &name_16);
// read data
U64 data_read_size = str8_deserial_read_block(raw_res, off + prefix.header_size, prefix.data_size, &res_out->data);
Assert(prefix.data_size == data_read_size);
// compute read size
U64 read_size = Max(prefix.header_size, sizeof(prefix)) + AlignPow2(prefix.data_size, COFF_ResourceAlign);
return read_size;
}
internal COFF_ParsedResourceList
coff_resource_list_from_data(Arena *arena, String8 data)
{
COFF_ParsedResourceList list = {0};
U64 cursor;
for (cursor = 0 ; cursor < data.size; ) {
COFF_ParsedResourceNode *node = push_array(arena, COFF_ParsedResourceNode, 1);
cursor += coff_read_resource(arena, data, cursor, &node->data);
SLLQueuePush(list.first, list.last, node);
++list.count;
}
Assert(cursor == data.size);
return list;
}
internal String8
coff_write_resource_id(Arena *arena, COFF_ResourceID id)
{
String8 result = str8_zero();
switch (id.type) {
case COFF_ResourceIDType_Null: break;
case COFF_ResourceIDType_Number: {
result = coff_resource_number_from_u16(arena, id.u.number);
} break;
case COFF_ResourceIDType_String: {
result = coff_resource_string_from_str8(arena, id.u.string);
} break;
default: InvalidPath;
}
return result;
}
internal String8
coff_write_resource(Arena *arena,
COFF_ResourceID type,
COFF_ResourceID name,
U32 data_version,
COFF_ResourceMemoryFlags memory_flags,
U16 language_id,
U32 version,
U32 characteristics,
String8 data)
{
Temp scratch = scratch_begin(&arena, 1);
String8List list = {0};
COFF_ResourceHeaderPrefix *prefix = push_array(scratch.arena, COFF_ResourceHeaderPrefix, 1);
String8 packed_type = coff_write_resource_id(scratch.arena, type);
String8 packed_name = coff_write_resource_id(scratch.arena, name);
// prefix + header
str8_list_push(scratch.arena, &list, str8_struct(prefix));
str8_list_push(scratch.arena, &list, packed_type);
str8_list_push(scratch.arena, &list, packed_name);
str8_list_push(scratch.arena, &list, str8_struct(&data_version));
str8_list_push(scratch.arena, &list, str8_struct(&memory_flags));
str8_list_push(scratch.arena, &list, str8_struct(&language_id));
str8_list_push(scratch.arena, &list, str8_struct(&version));
str8_list_push(scratch.arena, &list, str8_struct(&characteristics));
prefix->data_size = safe_cast_u32(data.size);
prefix->header_size = safe_cast_u32(list.total_size);
// data
str8_list_push(scratch.arena, &list, data);
// magic
str8_list_push_front(scratch.arena, &list, str8_array_fixed(g_coff_res_magic));
// align
U64 align_size = AlignPow2(list.total_size, COFF_ResourceAlign) - list.total_size;
U8 *align = push_array(scratch.arena, U8, align_size);
str8_list_push(scratch.arena, &list, str8(align, align_size));
// join
String8 res = str8_list_join(arena, &list, 0);
scratch_end(scratch);
return res;
}
internal int
coff_resource_id_compar(void *raw_a, void *raw_b)
{
int cmp;
COFF_ResourceID *a = raw_b;
COFF_ResourceID *b = raw_b;
if (a->type == b->type) {
switch (a->type) {
case COFF_ResourceIDType_Null: break;
case COFF_ResourceIDType_Number: cmp = u16_compar(&a->u.number, &b->u.number); break;
case COFF_ResourceIDType_String: cmp = str8_compar_case_sensitive(&a->u.string, &b->u.string); break;
default: InvalidPath; break;
}
} else {
cmp = u32_compar(&a->type, &b->type);
}
return cmp;
}
internal B32
coff_is_import(String8 raw_archive_member)
{
B32 is_import = 0;
if (raw_archive_member.size >= sizeof(U16)*2) {
U16 *sig1 = (U16*)raw_archive_member.str;
U16 *sig2 = sig1 + 1;
is_import = *sig1 == COFF_Machine_Unknown && *sig2 == 0xffff;
}
return is_import;
}
internal COFF_DataType
coff_data_type_from_data(String8 raw_archive_member)
{
B32 is_big_obj = coff_is_big_obj(raw_archive_member);
if (is_big_obj) {
return COFF_DataType_BigObj;
}
B32 is_import = coff_is_import(raw_archive_member);
if (is_import) {
return COFF_DataType_Import;
}
return COFF_DataType_Obj;
}
internal B32
coff_is_regular_archive(String8 raw_archive)
{
B32 is_archive = 0;
U8 sig[sizeof(g_coff_archive_sig)];
if (str8_deserial_read_struct(raw_archive, 0, &sig) == sizeof(sig)) {
is_archive = MemoryCompare(&sig[0], &g_coff_archive_sig[0], sizeof(g_coff_archive_sig)) == 0;
}
return is_archive;
}
internal B32
coff_is_thin_archive(String8 raw_archive)
{
B32 is_archive = 0;
U8 sig[sizeof(g_coff_thin_archive_sig)];
if (str8_deserial_read_struct(raw_archive, 0, &sig) == sizeof(sig)) {
is_archive = MemoryCompare(&sig[0], &g_coff_thin_archive_sig[0], sizeof(g_coff_thin_archive_sig)) == 0;
}
return is_archive;
}
internal COFF_ArchiveType
coff_archive_type_from_data(String8 raw_archive)
{
if (coff_is_regular_archive(raw_archive)) {
return COFF_Archive_Regular;
} else if (coff_is_thin_archive(raw_archive)) {
return COFF_Archive_Thin;
}
return COFF_Archive_Null;
}
internal U64
coff_parse_archive_member_header(String8 raw_archive, U64 offset, COFF_ParsedArchiveMemberHeader *header_out)
{
COFF_ArchiveMemberHeader *header = str8_deserial_get_raw_ptr(raw_archive, offset, sizeof(*header));
if (header) {
String8 name = str8_skip_chop_whitespace(str8_cstring_capped(header->name, header->name + sizeof(header->name) ));
String8 date = str8_skip_chop_whitespace(str8_cstring_capped(header->date, header->date + sizeof(header->date) ));
String8 user_id = str8_skip_chop_whitespace(str8_cstring_capped(header->user_id, header->user_id + sizeof(header->user_id) ));
String8 group_id = str8_skip_chop_whitespace(str8_cstring_capped(header->group_id, header->group_id + sizeof(header->group_id)));
String8 mode = str8_skip_chop_whitespace(str8_cstring_capped(header->mode, header->mode + sizeof(header->mode) ));
String8 size = str8_skip_chop_whitespace(str8_cstring_capped(header->size, header->size + sizeof(header->size) ));
String8 end = str8_cstring_capped(header->end, header->end + sizeof(header->end));
U32 data_size = u32_from_str8(size, 10);
U64 data_off = offset + sizeof(COFF_ArchiveMemberHeader);
header_out->name = name;
header_out->time_stamp = u32_from_str8(date, 10);
header_out->user_id = u32_from_str8(user_id, 10);
header_out->group_id = u32_from_str8(group_id, 10);
header_out->mode = mode;
header_out->is_end_correct = str8_match_lit("`\n", end, 0);
header_out->data_range = rng_1u64(data_off, data_off + data_size);
return sizeof(*header);
}
return 0;
}
internal COFF_ArchiveFirstMember
coff_parse_first_archive_member(COFF_ArchiveMember *member)
{
Assert(str8_match_lit("/", member->header.name, 0));
U64 cursor = 0;
U32 symbol_count = 0;
cursor += str8_deserial_read_struct(member->data, cursor, &symbol_count);
symbol_count = from_be_u32(symbol_count);
Rng1U64 member_offsets_range = rng_1u64(cursor, cursor + symbol_count * sizeof(U32));
cursor += dim_1u64(member_offsets_range);
Rng1U64 string_table_range = rng_1u64(cursor, member->data.size);
cursor += dim_1u64(string_table_range);
String8 raw_member_offsets = str8_substr(member->data, member_offsets_range);
U32 *member_offsets = (U32 *)raw_member_offsets.str;
U64 member_offset_count = raw_member_offsets.size / sizeof(member_offsets[0]);
COFF_ArchiveFirstMember result = {0};
result.symbol_count = symbol_count;
result.member_offset_count = member_offset_count;
result.member_offsets = member_offsets;
result.string_table = str8_substr(member->data, string_table_range);
return result;
}
internal COFF_ArchiveSecondMember
coff_parse_second_archive_member(COFF_ArchiveMember *member)
{
COFF_ArchiveSecondMember result = {0};
if (str8_match_lit("/", member->header.name, 0)) {
U64 cursor = 0;
U32 member_count = 0;
cursor += str8_deserial_read_struct(member->data, cursor, &member_count);
Rng1U64 member_offsets_range = rng_1u64(cursor, cursor + member_count * sizeof(U32));
cursor += dim_1u64(member_offsets_range);
U32 symbol_count = 0;
cursor += str8_deserial_read_struct(member->data, cursor, &symbol_count);
Rng1U64 symbol_indices_range = rng_1u64(cursor, cursor + symbol_count * sizeof(U16));
cursor += dim_1u64(symbol_indices_range);
Rng1U64 string_table_range = rng_1u64(cursor, member->data.size);
String8 raw_member_offsets = str8_substr(member->data, member_offsets_range);
String8 raw_indices = str8_substr(member->data, symbol_indices_range);
U32 *member_offsets = (U32 *)raw_member_offsets.str;
U64 member_offset_count = raw_member_offsets.size / sizeof(member_offsets[0]);
U16 *symbol_indices = (U16 *)raw_indices.str;
U64 symbol_index_count = raw_indices.size / sizeof(symbol_indices[0]);
result.member_count = member_count;
result.symbol_count = symbol_count;
result.member_offsets = member_offsets;
result.member_offset_count = member_offset_count;
result.symbol_indices = symbol_indices;
result.symbol_index_count = symbol_index_count;
result.string_table = str8_substr(member->data, string_table_range);
}
return result;
}
internal String8
coff_parse_long_name(String8 long_names, String8 name)
{
String8 result = name;
if (name.size > 0 && name.str[0] == '/') {
String8 offset_str = str8(name.str + 1, name.size - 1);
U64 offset = u64_from_str8(offset_str, 10);
if (offset < long_names.size) {
U8 *ptr = long_names.str + offset;
U8 *opl = long_names.str + long_names.size;
for (; ptr < opl; ++ptr) {
if (*ptr == '\0' || *ptr == '\n') {
break;
}
}
result = str8_range(long_names.str + offset, ptr);
}
}
return result;
}
internal U64
coff_parse_import(String8 raw_archive_member, U64 offset, COFF_ParsedArchiveImportHeader *header_out)
{
COFF_ImportHeader *header = str8_deserial_get_raw_ptr(raw_archive_member, offset, sizeof(*header));
if (header) {
Rng1U64 data_range = rng_1u64(offset + sizeof(*header), offset + sizeof(*header) + header->data_size);
String8 raw_data = str8_substr(raw_archive_member, data_range);
U64 data_cursor = 0;
header_out->version = header->version;
header_out->machine = header->machine;
header_out->time_stamp = header->time_stamp;
header_out->data_size = header->data_size;
header_out->hint_or_ordinal = header->hint_or_ordinal;
header_out->type = COFF_ImportHeader_ExtractType(header->flags);
header_out->import_by = COFF_ImportHeader_ExtractImportBy(header->flags);
data_cursor += str8_deserial_read_cstr(raw_data, data_cursor, &header_out->func_name);
data_cursor += str8_deserial_read_cstr(raw_data, data_cursor, &header_out->dll_name);
Assert(header_out->func_name.size + header_out->dll_name.size + /* nulls */ 2 == header_out->data_size);
U64 read_size = sizeof(*header) + header->data_size;
return read_size;
}
return 0;
}
internal COFF_ArchiveMember
coff_archive_member_from_offset(String8 raw_archive, U64 offset)
{
COFF_ArchiveMember member = {0};
coff_regular_archive_member_iter_next(raw_archive, &offset, &member);
return member;
}
internal COFF_ArchiveMember
coff_archive_member_from_data(String8 raw_archive_member)
{
return coff_archive_member_from_offset(raw_archive_member, 0);
}
internal COFF_ParsedArchiveImportHeader
coff_archive_import_from_data(String8 raw_archive_member)
{
COFF_ParsedArchiveImportHeader header = {0};
coff_parse_import(raw_archive_member, 0, &header);
return header;
}
internal U64
coff_regular_archive_member_iter_init(String8 raw_archive)
{
U64 cursor = raw_archive.size;
if (coff_is_regular_archive(raw_archive)) {
cursor = sizeof(g_coff_archive_sig);
}
return cursor;
}
internal B32
coff_regular_archive_member_iter_next(String8 raw_archive, U64 *offset, COFF_ArchiveMember *member_out)
{
B32 is_parsed = 0;
member_out->header.is_end_correct = 0;
U64 header_size = coff_parse_archive_member_header(raw_archive, *offset, &member_out->header);
if (member_out->header.is_end_correct) {
member_out->offset = *offset;
member_out->data = str8_substr(raw_archive, member_out->header.data_range);
U64 read_size = AlignPow2(header_size + dim_1u64(member_out->header.data_range), COFF_Archive_MemberAlign);
*offset += read_size;
is_parsed = 1;
}
return is_parsed;
}
internal U64
coff_thin_archive_member_iter_init(String8 raw_archive)
{
U64 cursor = raw_archive.size;
if (coff_is_thin_archive(raw_archive)) {
cursor = sizeof(g_coff_thin_archive_sig);
}
return cursor;
}
internal B32
coff_thin_archive_member_iter_next(String8 raw_archive, U64 *offset, COFF_ArchiveMember *member_out)
{
B32 is_parsed = 0;
member_out->header.is_end_correct = 0;
U64 header_size = coff_parse_archive_member_header(raw_archive, *offset, &member_out->header);
if (member_out->header.is_end_correct) {
Rng1U64 data_in_archive_range = {0};
if (str8_match_lit("/", member_out->header.name, 0) || str8_match_lit("//", member_out->header.name, 0)) {
data_in_archive_range = member_out->header.data_range;
}
member_out->offset = *offset;
member_out->data = str8_substr(raw_archive, data_in_archive_range);
U64 read_size = AlignPow2(header_size + dim_1u64(data_in_archive_range), COFF_Archive_MemberAlign);
*offset += read_size;
is_parsed = 1;
}
return is_parsed;
}
internal void
coff_archive_member_list_push_node(COFF_ArchiveMemberList *list, COFF_ArchiveMemberNode *node)
{
SLLQueuePush(list->first, list->last, node);
list->count += 1;
}
internal COFF_ArchiveParse
coff_archive_parse_from_member_list(COFF_ArchiveMemberList member_list)
{
String8 error = str8_zero();
B32 has_second_header = 0;
B32 has_long_names = 0;
COFF_ArchiveMember first_header = {0};
COFF_ArchiveMember second_header = {0};
COFF_ArchiveMember long_names_member = {0};
COFF_ArchiveMemberNode *ptr = member_list.first;
if (ptr) {
if (str8_match_lit("/", ptr->data.header.name, 0)) {
if (ptr->data.header.is_end_correct) {
first_header = ptr->data;
ptr = ptr->next;
} else {
error = str8_lit("first header doesn't have correct end");
}
}
} else {
error = str8_lit("missing first header");
}
if (!error.size && ptr) {
if (str8_match_lit("/", ptr->data.header.name, 0)) {
if (ptr->data.header.is_end_correct) {
second_header = ptr->data;
ptr = ptr->next;
has_second_header = 1;
} else {
error = str8_lit("second header doesn't have correct end");
}
}
}
if (!error.size && ptr) {
if (str8_match_lit("//", ptr->data.header.name, 0)) {
if (ptr->data.header.is_end_correct) {
long_names_member = ptr->data;
ptr = ptr->next;
has_long_names;
} else {
error = str8_lit("long names header doesn't have correct end");
}
}
}
COFF_ArchiveParse parse = {0};
parse.has_second_header = has_second_header;
parse.has_long_names = has_long_names;
parse.first_member = coff_parse_first_archive_member(&first_header);
parse.second_member = coff_parse_second_archive_member(&second_header);
parse.long_names = long_names_member.data;
parse.error = error;
return parse;
}
internal COFF_ArchiveParse
coff_regular_archive_parse_from_data(String8 raw_archive)
{
COFF_ArchiveMemberList list = {0};
COFF_ArchiveMemberNode node_arr[3] = {0};
U64 cursor = coff_regular_archive_member_iter_init(raw_archive);
for (U64 i = 0; i < ArrayCount(node_arr); ++i) {
COFF_ArchiveMemberNode *node = &node_arr[i];
if (!coff_regular_archive_member_iter_next(raw_archive, &cursor, &node->data)) {
break;
}
coff_archive_member_list_push_node(&list, node);
}
return coff_archive_parse_from_member_list(list);
}
internal COFF_ArchiveParse
coff_thin_archive_parse_from_data(String8 raw_archive)
{
COFF_ArchiveMemberList list = {0};
COFF_ArchiveMemberNode node_arr[3] = {0};
U64 cursor = coff_thin_archive_member_iter_init(raw_archive);
for (U64 i = 0; i < ArrayCount(node_arr); i += 1) {
COFF_ArchiveMemberNode *node = &node_arr[i];
if (!coff_thin_archive_member_iter_next(raw_archive, &cursor, &node->data)) {
break;
}
coff_archive_member_list_push_node(&list, node);
}
return coff_archive_parse_from_member_list(list);
}
internal COFF_ArchiveParse
coff_archive_parse_from_data(String8 raw_archive)
{
COFF_ArchiveType type = coff_archive_type_from_data(raw_archive);
switch (type) {
case COFF_Archive_Null: break;
case COFF_Archive_Regular: return coff_regular_archive_parse_from_data(raw_archive);
case COFF_Archive_Thin: return coff_thin_archive_parse_from_data(raw_archive);
}
COFF_ArchiveParse null_parse = {0};
return null_parse;
}
+315
View File
@@ -0,0 +1,315 @@
// Copyright (c) 2024 Epic Games Tools
// Licensed under the MIT license (https://opensource.org/license/mit/)
#ifndef COFF_PARSE_H
#define COFF_PARSE_H
typedef struct COFF_FileHeaderInfo
{
B32 is_big_obj;
COFF_MachineType machine;
U64 header_size;
U64 section_array_off;
U64 section_count_no_null;
U64 string_table_off;
U64 symbol_size;
U64 symbol_off;
U64 symbol_count;
} COFF_FileHeaderInfo;
////////////////////////////////
typedef struct COFF_SectionHeaderArray
{
U64 count;
COFF_SectionHeader *v;
} COFF_SectionHeaderArray;
////////////////////////////////
typedef struct COFF_Symbol16Node
{
struct COFF_Symbol16Node *next;
COFF_Symbol16 data;
} COFF_Symbol16Node;
typedef struct COFF_Symbol16List
{
U64 count;
COFF_Symbol16Node *first;
COFF_Symbol16Node *last;
} COFF_Symbol16List;
typedef struct COFF_Symbol32Array
{
U64 count;
COFF_Symbol32 *v;
} COFF_Symbol32Array;
typedef struct COFF_ParsedSymbol
{
String8 name;
U32 value;
U32 section_number;
COFF_SymbolType type;
COFF_SymStorageClass storage_class;
U8 aux_symbol_count;
} COFF_ParsedSymbol;
typedef U32 COFF_SymbolValueInterpType;
enum
{
COFF_SymbolValueInterp_Regular, // symbol has section and offset.
COFF_SymbolValueInterp_Weak, // symbol is overridable.
COFF_SymbolValueInterp_Undefined, // symbol doesn't have a reference section.
COFF_SymbolValueInterp_Common, // symbol has no section but still has size.
COFF_SymbolValueInterp_Abs, // symbol has an absolute (non-relocatable) value and is not an address.
COFF_SymbolValueInterp_Debug // symbol is used to provide general type of debugging information.
};
////////////////////////////////
typedef struct COFF_RelocNode
{
struct COFF_RelocNode *next;
COFF_Reloc data;
} COFF_RelocNode;
typedef struct COFF_RelocList
{
U64 count;
COFF_RelocNode *first;
COFF_RelocNode *last;
} COFF_RelocList;
typedef struct COFF_RelocArray
{
U64 count;
COFF_Reloc *v;
} COFF_RelocArray;
typedef struct COFF_RelocInfo
{
U64 array_off;
U64 count;
} COFF_RelocInfo;
////////////////////////////////
typedef U32 COFF_ResourceIDType;
enum COFF_ResourceIDTypeEnum
{
COFF_ResourceIDType_Null,
COFF_ResourceIDType_Number,
COFF_ResourceIDType_String,
COFF_ResourceIDType_Count
};
typedef struct COFF_ResourceID16
{
COFF_ResourceIDType type;
union {
U16 number;
String16 string;
} u;
} COFF_ResourceID16;
typedef struct COFF_ResourceID
{
COFF_ResourceIDType type;
union {
U16 number;
String8 string;
} u;
} COFF_ResourceID;
typedef struct COFF_ParsedResource
{
COFF_ResourceID type;
COFF_ResourceID name;
U32 data_version;
COFF_ResourceMemoryFlags memory_flags;
U16 language_id;
U32 version;
U32 characteristics;
String8 data;
} COFF_ParsedResource;
typedef struct COFF_ParsedResourceNode
{
struct COFF_ParsedResourceNode *next;
COFF_ParsedResource data;
} COFF_ParsedResourceNode;
typedef struct COFF_ParsedResourceList
{
U64 count;
COFF_ParsedResourceNode *first;
COFF_ParsedResourceNode *last;
} COFF_ParsedResourceList;
////////////////////////////////
typedef enum
{
COFF_DataType_Null,
COFF_DataType_Obj,
COFF_DataType_BigObj,
COFF_DataType_Import
} COFF_DataType;
typedef enum
{
COFF_Archive_Null,
COFF_Archive_Regular,
COFF_Archive_Thin
} COFF_ArchiveType;
typedef struct COFF_ParsedArchiveMemberHeader
{
String8 name; // padded to 16 bytes with spaces
COFF_TimeStamp time_stamp;
U32 user_id; // unix artifact that does not have meaning on windows
U32 group_id; // unix artifact that does not have meaning on windows
String8 mode; // octal representation the members file mode
B32 is_end_correct; // set to true if found correct signature after header
Rng1U64 data_range;
} COFF_ParsedArchiveMemberHeader;
typedef struct COFF_ParsedArchiveImportHeader
{
B32 is_sig_correct;
U16 version;
COFF_MachineType machine;
COFF_TimeStamp time_stamp;
U32 data_size;
U16 hint_or_ordinal;
COFF_ImportType type;
COFF_ImportByType import_by;
String8 func_name;
String8 dll_name;
} COFF_ParsedArchiveImportHeader;
typedef struct COFF_ArchiveMember
{
COFF_ParsedArchiveMemberHeader header;
U64 offset;
String8 data;
} COFF_ArchiveMember;
typedef struct COFF_ArchiveFirstMember
{
U32 symbol_count;
U64 member_offset_count;
U32 *member_offsets;
String8 string_table;
} COFF_ArchiveFirstMember;
typedef struct COFF_ArchiveSecondMember
{
U32 member_count;
U32 symbol_count;
U64 member_offset_count;
U32 *member_offsets;
U64 symbol_index_count;
U16 *symbol_indices;
String8 string_table;
} COFF_ArchiveSecondMember;
typedef struct COFF_ArchiveMemberNode
{
struct COFF_ArchiveMemberNode *next;
COFF_ArchiveMember data;
} COFF_ArchiveMemberNode;
typedef struct COFF_ArchiveMemberList
{
U64 count;
COFF_ArchiveMemberNode *first;
COFF_ArchiveMemberNode *last;
} COFF_ArchiveMemberList;
typedef struct COFF_ArchiveParse
{
B32 has_second_header;
B32 has_long_names;
COFF_ArchiveFirstMember first_member;
COFF_ArchiveSecondMember second_member;
String8 long_names;
String8 error;
} COFF_ArchiveParse;
////////////////////////////////
// Obj Header
internal B32 coff_is_big_obj(String8 raw_coff);
internal B32 coff_is_obj (String8 raw_coff);
internal COFF_FileHeaderInfo coff_file_header_info_from_data(String8 raw_coff);
////////////////////////////////
// Symbol
internal COFF_ParsedSymbol coff_parse_symbol32(String8 raw_coff, U64 string_table_off, COFF_Symbol32 *sym32);
internal COFF_ParsedSymbol coff_parse_symbol16(String8 raw_coff, U64 string_table_off, COFF_Symbol16 *sym16);
internal COFF_Symbol32Array coff_symbol_array_from_data_16(Arena *arena, String8 data, U64 symbol_array_off, U64 symbol_count);
internal COFF_Symbol32Array coff_symbol_array_from_data_32(Arena *arena, String8 data, U64 symbol_array_off, U64 symbol_count);
internal COFF_Symbol32Array coff_symbol_array_from_data (Arena *arena, String8 data, U64 symbol_array_off, U64 symbol_count, U64 symbol_size);
internal COFF_Symbol16Node *coff_symbol16_list_push(Arena *arena, COFF_Symbol16List *list, COFF_Symbol16 symbol);
internal COFF_SymbolValueInterpType coff_interp_symbol(U32 section_number, U32 value, COFF_SymStorageClass storage_class);
////////////////////////////////
// Reloc
internal COFF_RelocInfo coff_reloc_info_from_section_header(String8 data, COFF_SectionHeader *header);
////////////////////////////////
// Resource
internal String8 coff_resource_string_from_str16 (Arena *arena, String16 string);
internal String8 coff_resource_string_from_str8 (Arena *arena, String8 string);
internal String8 coff_resource_number_from_u16 (Arena *arena, U16 number);
internal COFF_ResourceID coff_utf8_resource_id_from_utf16(Arena *arena, COFF_ResourceID16 *id_16);
internal U64 coff_read_resource_id_utf16 (String8 raw_res, U64 off, COFF_ResourceID16 *id_out);
internal U64 coff_read_resource (Arena *arena, String8 raw_res, U64 off, COFF_ParsedResource *res_out);
internal COFF_ParsedResourceList coff_resource_list_from_data(Arena *arena, String8 data);
internal String8 coff_write_resource_id(Arena *arena, COFF_ResourceID id);
internal String8 coff_write_resource (Arena *arena, COFF_ResourceID type, COFF_ResourceID name, U32 data_version, COFF_ResourceMemoryFlags memory_flags, U16 language_id, U32 version, U32 characteristics, String8 data);
internal int coff_resource_id_compar(void *raw_a, void *raw_b); // COFF_ResourceID
////////////////////////////////
// Archive
internal B32 coff_is_import (String8 raw_archive_member);
internal COFF_DataType coff_data_type_from_data (String8 raw_archive_member);
internal B32 coff_is_regular_archive (String8 raw_archive);
internal B32 coff_is_thin_archive (String8 raw_archive);
internal COFF_ArchiveType coff_archive_type_from_data(String8 raw_archive);
internal U64 coff_parse_archive_member_header(String8 raw_archive, U64 offset, COFF_ParsedArchiveMemberHeader *header_out);
internal COFF_ArchiveFirstMember coff_parse_first_archive_member (COFF_ArchiveMember *member);
internal COFF_ArchiveSecondMember coff_parse_second_archive_member(COFF_ArchiveMember *member);
internal String8 coff_parse_long_name (String8 long_names, String8 name);
internal U64 coff_parse_import (String8 raw_archive_member, U64 offset, COFF_ParsedArchiveImportHeader *header_out);
internal COFF_ArchiveMember coff_archive_member_from_offset(String8 raw_archive, U64 offset);
internal COFF_ArchiveMember coff_archive_member_from_data (String8 raw_archive_member);
internal COFF_ParsedArchiveImportHeader coff_archive_import_from_data (String8 raw_archive_member);
internal U64 coff_regular_archive_member_iter_init(String8 raw_archive);
internal B32 coff_regular_archive_member_iter_next(String8 raw_archive, U64 *offset, COFF_ArchiveMember *member_out);
internal U64 coff_thin_archive_member_iter_init(String8 raw_archive);
internal B32 coff_thin_archive_member_iter_next(String8 raw_archive, U64 *offset, COFF_ArchiveMember *member_out);
internal COFF_ArchiveParse coff_regular_archive_parse_from_member_list(COFF_ArchiveMemberList list);
internal COFF_ArchiveParse coff_thin_archive_parse_from_data (String8 raw_archive);
internal COFF_ArchiveParse coff_regular_archive_parse_from_data (String8 raw_archive);
internal COFF_ArchiveParse coff_archive_parse_from_data (String8 raw_archive);
#endif // COFF_PARSE_H
+9 -9
View File
@@ -3489,20 +3489,20 @@ ctrl_thread__module_open(CTRL_Handle process, CTRL_Handle module, Rng1U64 vaddr_
}
//- rjf: read COFF header
U64 coff_header_off = dos_header.coff_file_offset + sizeof(pe_magic);
COFF_Header coff_header = {0};
U64 file_header_off = dos_header.coff_file_offset + sizeof(pe_magic);
COFF_FileHeader file_header = {0};
if(is_valid)
{
if(!dmn_process_read_struct(process.dmn_handle, vaddr_range.min + coff_header_off, &coff_header))
if(!dmn_process_read_struct(process.dmn_handle, vaddr_range.min + file_header_off, &file_header))
{
is_valid = 0;
}
}
//- rjf: unpack range of optional extension header
U32 opt_ext_size = coff_header.optional_header_size;
Rng1U64 opt_ext_off_range = r1u64(coff_header_off + sizeof(coff_header),
coff_header_off + sizeof(coff_header) + opt_ext_size);
U32 opt_ext_size = file_header.optional_header_size;
Rng1U64 opt_ext_off_range = r1u64(file_header_off + sizeof(COFF_FileHeader),
file_header_off + sizeof(COFF_FileHeader) + opt_ext_size);
//- rjf: read optional header
U16 optional_magic = 0;
@@ -3569,10 +3569,10 @@ ctrl_thread__module_open(CTRL_Handle process, CTRL_Handle module, Rng1U64 vaddr_
PE_DataDirectory dir = {0};
dmn_process_read_struct(process.dmn_handle, vaddr_range.min + opt_ext_off_range.min + reported_data_dir_offset + sizeof(PE_DataDirectory)*PE_DataDirectoryIndex_TLS, &dir);
Rng1U64 tls_voff_range = r1u64((U64)dir.virt_off, (U64)dir.virt_off + (U64)dir.virt_size);
switch(coff_header.machine)
switch(file_header.machine)
{
default:{}break;
case COFF_MachineType_X86:
case COFF_Machine_X86:
{
PE_TLSHeader32 tls_header32 = {0};
dmn_process_read_struct(process.dmn_handle, vaddr_range.min + tls_voff_range.min, &tls_header32);
@@ -3583,7 +3583,7 @@ ctrl_thread__module_open(CTRL_Handle process, CTRL_Handle module, Rng1U64 vaddr_
tls_header.zero_fill_size = (U64)tls_header32.zero_fill_size;
tls_header.characteristics = (U64)tls_header32.characteristics;
}break;
case COFF_MachineType_X64:
case COFF_Machine_X64:
{
dmn_process_read_struct(process.dmn_handle, vaddr_range.min + tls_voff_range.min, &tls_header);
}break;
+11 -11
View File
@@ -469,9 +469,9 @@ dmn_w32_image_info_from_process_base_vaddr(HANDLE process, U64 base_vaddr)
}
// rjf: get COFF header
B32 got_coff_header = 0;
U64 coff_header_off = 0;
COFF_Header coff_header = {0};
B32 got_file_header = 0;
U64 file_header_off = 0;
COFF_FileHeader file_header = {0};
if(pe_offset > 0)
{
U64 pe_magic_off = base_vaddr + pe_offset;
@@ -479,28 +479,28 @@ dmn_w32_image_info_from_process_base_vaddr(HANDLE process, U64 base_vaddr)
dmn_w32_process_read_struct(process, pe_magic_off, &pe_magic);
if(pe_magic == PE_MAGIC)
{
coff_header_off = pe_magic_off + sizeof(pe_magic);
if(dmn_w32_process_read_struct(process, coff_header_off, &coff_header))
file_header_off = pe_magic_off + sizeof(pe_magic);
if(dmn_w32_process_read_struct(process, file_header_off, &file_header))
{
got_coff_header = 1;
got_file_header = 1;
}
}
}
// rjf: get arch and size
DMN_W32_ImageInfo result = zero_struct;
if(got_coff_header)
if(got_file_header)
{
U64 optional_size_off = 0;
Arch arch = Arch_Null;
switch(coff_header.machine)
switch(file_header.machine)
{
case COFF_MachineType_X86:
case COFF_Machine_X86:
{
arch = Arch_x86;
optional_size_off = OffsetOf(PE_OptionalHeader32, sizeof_image);
}break;
case COFF_MachineType_X64:
case COFF_Machine_X64:
{
arch = Arch_x64;
optional_size_off = OffsetOf(PE_OptionalHeader32Plus, sizeof_image);
@@ -510,7 +510,7 @@ dmn_w32_image_info_from_process_base_vaddr(HANDLE process, U64 base_vaddr)
}
if(arch != Arch_Null)
{
U64 optional_off = coff_header_off + sizeof(coff_header);
U64 optional_off = file_header_off + sizeof(COFF_FileHeader);
U32 size = 0;
if(dmn_w32_process_read_struct(process, optional_off+optional_size_off, &size) >= sizeof(size))
{
+113 -111
View File
@@ -36,6 +36,7 @@
#include "path/path.h"
#include "coff/coff.h"
#include "coff/coff_enum.h"
#include "coff/coff_parse.h"
#include "pe/pe.h"
#include "codeview/codeview.h"
#include "codeview/codeview_parse.h"
@@ -50,6 +51,7 @@
#include "path/path.c"
#include "coff/coff.c"
#include "coff/coff_enum.c"
#include "coff/coff_parse.c"
#include "pe/pe.c"
#include "codeview/codeview.c"
#include "codeview/codeview_enum.c"
@@ -391,8 +393,8 @@ lnk_res_string_id_is_before(void *raw_a, void *raw_b)
{
PE_Resource *a = raw_a;
PE_Resource *b = raw_b;
Assert(a->id.type == COFF_ResourceIDType_STRING);
Assert(b->id.type == COFF_ResourceIDType_STRING);
Assert(a->id.type == COFF_ResourceIDType_String);
Assert(b->id.type == COFF_ResourceIDType_String);
int is_before = str8_is_before_case_sensitive(&a->id.u.string, &b->id.u.string);
return is_before;
}
@@ -402,8 +404,8 @@ lnk_res_number_id_is_before(void *raw_a, void *raw_b)
{
PE_Resource *a = raw_a;
PE_Resource *b = raw_b;
Assert(a->id.type == COFF_ResourceIDType_NUMBER);
Assert(b->id.type == COFF_ResourceIDType_NUMBER);
Assert(a->id.type == COFF_ResourceIDType_Number);
Assert(b->id.type == COFF_ResourceIDType_Number);
int is_before = u16_is_before(&a->id.u.number, &b->id.u.number);
return is_before;
}
@@ -426,7 +428,7 @@ lnk_serialize_pe_resource_tree(LNK_SectionTable *st, LNK_SymbolTable *symtab, PE
dir_data_chunk->sort_idx = str8_lit("c");
PE_Resource root_wrapper = {0};
root_wrapper.id.type = COFF_ResourceIDType_NUMBER;
root_wrapper.id.type = COFF_ResourceIDType_Number;
root_wrapper.id.u.number = 0;
root_wrapper.kind = PE_ResDataKind_DIR;
root_wrapper.u.dir = root_dir;
@@ -460,11 +462,11 @@ lnk_serialize_pe_resource_tree(LNK_SectionTable *st, LNK_SymbolTable *symtab, PE
stack->coff_entry_chunk = lnk_section_push_chunk_data(dir_sect, stack->coff_entry_array_chunk, str8_struct(entry), str8_zero());
switch (res->id.type) {
case COFF_ResourceIDType_NUMBER: {
case COFF_ResourceIDType_Number: {
entry->name.id = res->id.u.number;
} break;
case COFF_ResourceIDType_STRING: {
case COFF_ResourceIDType_String: {
// TODO: we can make string table smaller by reusing offsets for same strings
// not sure why high bit has to be turned on here since number id and string id entries are
@@ -480,7 +482,7 @@ lnk_serialize_pe_resource_tree(LNK_SectionTable *st, LNK_SymbolTable *symtab, PE
lnk_section_push_reloc(dir_sect, stack->coff_entry_chunk, LNK_Reloc_SECT_REL, OffsetOf(COFF_ResourceDirEntry, name.offset), name_symbol);
} break;
case COFF_ResourceIDType_NULL: break;
case COFF_ResourceIDType_Null: break;
default: InvalidPath;
}
@@ -499,14 +501,14 @@ lnk_serialize_pe_resource_tree(LNK_SectionTable *st, LNK_SymbolTable *symtab, PE
// push sub directory chunk layout
LNK_Chunk *dir_node_chunk = lnk_section_push_chunk_list(dir_sect, dir_tree_chunk, str8_zero());
dir_node_chunk->align = COFF_RES_ALIGN;
dir_node_chunk->align = COFF_ResourceAlign;
LNK_Chunk *dir_header_chunk = lnk_section_push_chunk_data(dir_sect, dir_node_chunk, str8_struct(dir_header), str8_zero());
LNK_Chunk *entry_array_chunk = lnk_section_push_chunk_list(dir_sect, dir_node_chunk, str8_zero());
lnk_chunk_set_debugf(dir_sect->arena, dir_header_chunk, "DIR_HEADER_CHUNK");
lnk_chunk_set_debugf(dir_sect->arena, entry_array_chunk, "DIR_ENTRY_ARRAY_CHUNK");
// push symbols to patch coff entry
LNK_Symbol *flag_symbol = lnk_make_defined_symbol_va(symtab->arena->v[0], flag_name, LNK_DefinedSymbolVisibility_Internal, 0, COFF_RESOURCE_SUB_DIR_FLAG);
LNK_Symbol *flag_symbol = lnk_make_defined_symbol_va(symtab->arena->v[0], flag_name, LNK_DefinedSymbolVisibility_Internal, 0, COFF_Resource_SubDirFlag);
LNK_Symbol *offset_symbol = lnk_make_defined_symbol_chunk(symtab->arena->v[0], offset_name, LNK_DefinedSymbolVisibility_Internal, 0, dir_header_chunk, 0, 0, 0);
lnk_symbol_table_push(symtab, flag_symbol); // set high bit to indicate directory
lnk_symbol_table_push(symtab, offset_symbol); // write offset for this directory
@@ -542,8 +544,8 @@ lnk_serialize_pe_resource_tree(LNK_SectionTable *st, LNK_SymbolTable *symtab, PE
LNK_Chunk *resource_data_chunk = lnk_section_push_chunk_data(data_sect, data_sect->root, res->u.coff_res.data, str8_zero());
// windows errors out on unaligned data
coff_resource_data_entry_chunk->align = COFF_RES_ALIGN;
resource_data_chunk->align = COFF_RES_ALIGN;
coff_resource_data_entry_chunk->align = COFF_ResourceAlign;
resource_data_chunk->align = COFF_ResourceAlign;
// relocate data
String8 resource_data_symbol_name = push_str8f(symtab->arena->v[0], "$R%06X", total_res_count);
@@ -725,8 +727,8 @@ lnk_make_res_obj(TP_Context *tp,
COFF_Symbol16 coff_feat00 = {0};
MemoryCopyStr8(&coff_feat00.name, str8_lit("@feat.00"));
coff_feat00.value = MSCRT_FeatFlag_HAS_SAFE_SEH|MSCRT_FeatFlag_UNKNOWN_4;
coff_feat00.section_number = COFF_SYMBOL_ABS_SECTION_16;
coff_feat00.storage_class = COFF_SymStorageClass_STATIC;
coff_feat00.section_number = COFF_Symbol_AbsSection16;
coff_feat00.storage_class = COFF_SymStorageClass_Static;
coff_symbol16_list_push(scratch.arena, &coff_symbol_list, coff_feat00);
// emit coff symbols for section definitions
@@ -749,7 +751,7 @@ lnk_make_res_obj(TP_Context *tp,
coff_sect_symbol.value = 0;
coff_sect_symbol.section_number = sect->isect;
coff_sect_symbol.aux_symbol_count = 1;
coff_sect_symbol.storage_class = COFF_SymStorageClass_STATIC;
coff_sect_symbol.storage_class = COFF_SymStorageClass_Static;
Assert(sect->isect <= max_U16);
COFF_SymbolSecDef secdef = {0};
@@ -805,7 +807,7 @@ lnk_make_res_obj(TP_Context *tp,
MemoryCopyStr8(&coff_symbol.name, symbol_name);
coff_symbol.value = symbol_offset;
coff_symbol.section_number = symbol_sect->isect;
coff_symbol.storage_class = COFF_SymStorageClass_STATIC;
coff_symbol.storage_class = COFF_SymStorageClass_Static;
coff_symbol16_list_push(scratch.arena, &coff_symbol_list, coff_symbol);
// push coff reloc
@@ -843,7 +845,7 @@ lnk_make_res_obj(TP_Context *tp,
}
}
LNK_Section *misc_sect = lnk_section_table_push(st, str8_lit(".misc"), COFF_SectionFlag_LNK_INFO|COFF_SectionFlag_LNK_REMOVE);
LNK_Section *misc_sect = lnk_section_table_push(st, str8_lit(".misc"), COFF_SectionFlag_LnkInfo|COFF_SectionFlag_LnkRemove);
misc_sect->emit_header = 0;
// serialize coff symbol list
@@ -863,27 +865,27 @@ lnk_make_res_obj(TP_Context *tp,
// build obj header
{
// init header
COFF_Header *coff_header = push_array(header_sect->arena, COFF_Header, 1);
coff_header->machine = machine;
coff_header->section_count = 0; // relocated
coff_header->time_stamp = time_stamp;
coff_header->symbol_table_foff = 0; // relocated
coff_header->symbol_count = 0; // relocated
coff_header->optional_header_size = 0; // no PE header in obj
coff_header->flags = COFF_Flag_32BIT_MACHINE;
COFF_FileHeader *file_header = push_array(header_sect->arena, COFF_FileHeader, 1);
file_header->machine = machine;
file_header->section_count = 0; // relocated
file_header->time_stamp = time_stamp;
file_header->symbol_table_foff = 0; // relocated
file_header->symbol_count = 0; // relocated
file_header->optional_header_size = 0; // no PE header in obj
file_header->flags = COFF_FileHeaderFlag_32BitMachine;
// push coff header chunk
String8 coff_header_data = str8_struct(coff_header);
LNK_Chunk *coff_header_chunk = lnk_section_push_chunk_data(header_sect, header_sect->root, coff_header_data, str8_zero());
String8 file_header_data = str8_struct(file_header);
LNK_Chunk *file_header_chunk = lnk_section_push_chunk_data(header_sect, header_sect->root, file_header_data, str8_zero());
// relocate coff header fields
lnk_section_push_reloc_undefined(header_sect, coff_header_chunk, LNK_Reloc_ADDR_32, OffsetOf(COFF_Header, section_count), str8_lit(LNK_COFF_SECT_HEADER_COUNT_SYMBOL_NAME), LNK_SymbolScopeFlag_Internal);
lnk_section_push_reloc(header_sect, coff_header_chunk, LNK_Reloc_FILE_OFF_32, OffsetOf(COFF_Header, symbol_table_foff), coff_symbol_table_symbol);
lnk_section_push_reloc(header_sect, coff_header_chunk, LNK_Reloc_ADDR_32, OffsetOf(COFF_Header, symbol_count), coff_symbol_count_symbol);
lnk_section_push_reloc_undefined(header_sect, file_header_chunk, LNK_Reloc_ADDR_32, OffsetOf(COFF_FileHeader, section_count), str8_lit(LNK_COFF_SECT_HEADER_COUNT_SYMBOL_NAME), LNK_SymbolScopeFlag_Internal);
lnk_section_push_reloc(header_sect, file_header_chunk, LNK_Reloc_FILE_OFF_32, OffsetOf(COFF_FileHeader, symbol_table_foff), coff_symbol_table_symbol);
lnk_section_push_reloc(header_sect, file_header_chunk, LNK_Reloc_ADDR_32, OffsetOf(COFF_FileHeader, symbol_count), coff_symbol_count_symbol);
// push coff header symbol
LNK_Symbol *coff_header_symbol = lnk_make_defined_symbol_chunk(symtab->arena->v[0], str8_lit(LNK_COFF_HEADER_SYMBOL_NAME), LNK_DefinedSymbolVisibility_Internal, 0, coff_header_chunk, 0, 0, 0);
lnk_symbol_table_push(symtab, coff_header_symbol);
LNK_Symbol *file_header_symbol = lnk_make_defined_symbol_chunk(symtab->arena->v[0], str8_lit(LNK_COFF_FILE_HEADER_SYMBOL_NAME), LNK_DefinedSymbolVisibility_Internal, 0, file_header_chunk, 0, 0, 0);
lnk_symbol_table_push(symtab, file_header_symbol);
}
// build section headers
@@ -923,7 +925,7 @@ lnk_make_res_obj(TP_Context *tp,
}
// patch file fields
if (~sect->flags & COFF_SectionFlag_CNT_UNINITIALIZED_DATA) {
if (~sect->flags & COFF_SectionFlag_CntUninitializedData) {
LNK_Symbol *sect_symbol = lnk_symbol_table_search(symtab, LNK_SymbolScopeFlag_Internal, sect->name);
lnk_section_push_reloc(header_sect, coff_sect_header_chunk, LNK_Reloc_CHUNK_SIZE_FILE_32, OffsetOf(COFF_SectionHeader, fsize), sect_symbol);
lnk_section_push_reloc(header_sect, coff_sect_header_chunk, LNK_Reloc_FILE_OFF_32, OffsetOf(COFF_SectionHeader, foff), sect_symbol);
@@ -1034,13 +1036,13 @@ lnk_make_linker_coff_obj(TP_Context *tp,
header_sect->emit_header = 0;
{
COFF_Header *coff_header = push_array(header_sect->arena, COFF_Header, 1);
coff_header->machine = machine;
coff_header->section_count = 0;
coff_header->time_stamp = time_stamp;
COFF_FileHeader *file_header = push_array(header_sect->arena, COFF_FileHeader, 1);
file_header->machine = machine;
file_header->section_count = 0;
file_header->time_stamp = time_stamp;
LNK_Chunk *coff_header_chunk = lnk_section_push_chunk_raw(header_sect, header_sect->root, coff_header, sizeof(*coff_header), str8_zero());
lnk_section_push_reloc_undefined(header_sect, coff_header_chunk, LNK_Reloc_ADDR_32, OffsetOf(COFF_Header, section_count), str8_lit(LNK_COFF_SECT_HEADER_COUNT_SYMBOL_NAME), LNK_SymbolScopeFlag_Internal);
LNK_Chunk *file_header_chunk = lnk_section_push_chunk_raw(header_sect, header_sect->root, file_header, sizeof(*file_header), str8_zero());
lnk_section_push_reloc_undefined(header_sect, file_header_chunk, LNK_Reloc_ADDR_32, OffsetOf(COFF_FileHeader, section_count), str8_lit(LNK_COFF_SECT_HEADER_COUNT_SYMBOL_NAME), LNK_SymbolScopeFlag_Internal);
}
{
@@ -1139,7 +1141,7 @@ lnk_make_linker_coff_obj(TP_Context *tp,
}
// emit relocs for file fields
if (~sect->flags & COFF_SectionFlag_CNT_UNINITIALIZED_DATA) {
if (~sect->flags & COFF_SectionFlag_CntUninitializedData) {
LNK_Symbol *sect_symbol = lnk_symbol_table_search(symtab, LNK_SymbolScopeFlag_Internal, sect->name);
lnk_section_push_reloc(header_sect, coff_sect_header_chunk, LNK_Reloc_CHUNK_SIZE_FILE_32, OffsetOf(COFF_SectionHeader, fsize), sect_symbol);
lnk_section_push_reloc(header_sect, coff_sect_header_chunk, LNK_Reloc_FILE_OFF_32, OffsetOf(COFF_SectionHeader, foff), sect_symbol);
@@ -1232,12 +1234,12 @@ lnk_push_input_from_lazy(Arena *arena, PathStyle path_style, LNK_LazySymbol *laz
COFF_DataType member_type = coff_data_type_from_data(member_info.data);
switch (member_type) {
case COFF_DataType_IMPORT: {
case COFF_DataType_Import: {
LNK_InputImport *input = lnk_input_import_list_push(arena, input_import_list);
input->import_header = coff_archive_import_from_data(member_info.data);
} break;
case COFF_DataType_BIG_OBJ:
case COFF_DataType_OBJ: {
case COFF_DataType_BigObj:
case COFF_DataType_Obj: {
String8 obj_path = coff_parse_long_name(lazy->lib->long_names, member_info.header.name);
// obj path in thin archive has slash appended which screws up
@@ -1279,12 +1281,12 @@ lnk_push_linker_symbols(LNK_SymbolTable *symtab, COFF_MachineType machine)
// passing it around as a function argument.
//
// 100h: lea rax, [rip + ffffff00h] ; -100h
LNK_Symbol *image_base = lnk_symbol_table_push_defined_chunk(symtab, str8_lit("__ImageBase"), LNK_DefinedSymbolVisibility_Extern, 0, g_null_chunk_ptr, 0, COFF_ComdatSelectType_ANY, 0);
LNK_Symbol *image_base = lnk_symbol_table_push_defined_chunk(symtab, str8_lit("__ImageBase"), LNK_DefinedSymbolVisibility_Extern, 0, g_null_chunk_ptr, 0, COFF_ComdatSelect_Any, 0);
{ // load config symbols
if (machine == COFF_MachineType_X86) {
lnk_symbol_table_push_defined_chunk(symtab, str8_lit(LNK_SAFE_SE_HANDLER_TABLE_SYMBOL_NAME), LNK_DefinedSymbolVisibility_Extern, 0, g_null_chunk_ptr, 0, COFF_ComdatSelectType_NODUPLICATES, 0);
lnk_symbol_table_push_defined_chunk(symtab, str8_lit(LNK_SAFE_SE_HANDLER_COUNT_SYMBOL_NAME), LNK_DefinedSymbolVisibility_Extern, 0, g_null_chunk_ptr, 0, COFF_ComdatSelectType_NODUPLICATES, 0);
if (machine == COFF_Machine_X86) {
lnk_symbol_table_push_defined_chunk(symtab, str8_lit(LNK_SAFE_SE_HANDLER_TABLE_SYMBOL_NAME), LNK_DefinedSymbolVisibility_Extern, 0, g_null_chunk_ptr, 0, COFF_ComdatSelect_NoDuplicates, 0);
lnk_symbol_table_push_defined_chunk(symtab, str8_lit(LNK_SAFE_SE_HANDLER_COUNT_SYMBOL_NAME), LNK_DefinedSymbolVisibility_Extern, 0, g_null_chunk_ptr, 0, COFF_ComdatSelect_NoDuplicates, 0);
}
// TODO: investigate IMAGE_ENCLAVE_CONFIG 32/64
@@ -1409,7 +1411,7 @@ lnk_build_debug_rdi(LNK_SectionTable *st,
{
ProfBeginFunction();
LNK_Section *rdi_sect = lnk_section_table_push(st, str8_lit(".raddbg"), COFF_SectionFlag_CNT_INITIALIZED_DATA|COFF_SectionFlag_MEM_READ);
LNK_Section *rdi_sect = lnk_section_table_push(st, str8_lit(".raddbg"), COFF_SectionFlag_CntInitializedData|COFF_SectionFlag_MemRead);
// push chunks
String8 debug_rdi = pe_make_debug_header_rdi(rdi_sect->arena, guid, rdi_path);
@@ -1488,7 +1490,7 @@ lnk_build_guard_tables(TP_Context *tp,
if (lnk_chunk_is_discarded(chunk)) {
continue;
}
if (~chunk->flags & COFF_SectionFlag_CNT_CODE) {
if (~chunk->flags & COFF_SectionFlag_CntCode) {
continue;
}
Assert(chunk->type == LNK_Chunk_Leaf);
@@ -1508,7 +1510,7 @@ lnk_build_guard_tables(TP_Context *tp,
if (symbol_chunk->type != LNK_Chunk_Leaf) {
continue;
}
if (~symbol_chunk->flags & COFF_SectionFlag_CNT_CODE) {
if (~symbol_chunk->flags & COFF_SectionFlag_CntCode) {
continue;
}
lnk_symbol_list_push(scratch.arena, &guard_symbol_list_table[GUARD_FIDS], symbol);
@@ -1603,7 +1605,7 @@ lnk_build_guard_tables(TP_Context *tp,
}
// TODO: emit table for SEH on X86
if (machine == COFF_MachineType_X86) {
if (machine == COFF_Machine_X86) {
lnk_not_implemented("__safe_se_handler_table");
lnk_not_implemented("__safe_se_handler_count");
}
@@ -2078,7 +2080,7 @@ internal LNK_Chunk *
lnk_build_coff_file_header(LNK_SymbolTable *symtab, LNK_Section *header_sect, LNK_Chunk *parent,
COFF_MachineType machine, COFF_TimeStamp time_stamp, PE_ImageFileCharacteristics file_characteristics)
{
COFF_Header *file_header = push_array_no_zero(header_sect->arena, COFF_Header, 1);
COFF_FileHeader *file_header = push_array_no_zero(header_sect->arena, COFF_FileHeader, 1);
file_header->machine = machine;
file_header->time_stamp = time_stamp;
file_header->symbol_table_foff = 0;
@@ -2088,16 +2090,16 @@ lnk_build_coff_file_header(LNK_SymbolTable *symtab, LNK_Section *header_sect, LN
file_header->flags = file_characteristics;
LNK_Chunk *file_header_chunk = lnk_section_push_chunk_raw(header_sect, parent, file_header, sizeof(*file_header), str8_zero());
lnk_chunk_set_debugf(header_sect->arena, file_header_chunk, LNK_COFF_HEADER_SYMBOL_NAME);
lnk_chunk_set_debugf(header_sect->arena, file_header_chunk, LNK_COFF_FILE_HEADER_SYMBOL_NAME);
lnk_symbol_table_push_defined_chunk(symtab, str8_lit(LNK_COFF_HEADER_SYMBOL_NAME), LNK_DefinedSymbolVisibility_Internal, 0, file_header_chunk, 0, 0, 0);
lnk_symbol_table_push_defined_chunk(symtab, str8_lit(LNK_COFF_FILE_HEADER_SYMBOL_NAME), LNK_DefinedSymbolVisibility_Internal, 0, file_header_chunk, 0, 0, 0);
// :section_count
lnk_section_push_reloc_undefined(header_sect, file_header_chunk, LNK_Reloc_ADDR_16, OffsetOf(COFF_Header, section_count), str8_lit(LNK_COFF_SECT_HEADER_COUNT_SYMBOL_NAME), LNK_SymbolScopeFlag_Internal);
lnk_section_push_reloc_undefined(header_sect, file_header_chunk, LNK_Reloc_ADDR_16, OffsetOf(COFF_FileHeader, section_count), str8_lit(LNK_COFF_SECT_HEADER_COUNT_SYMBOL_NAME), LNK_SymbolScopeFlag_Internal);
// :optional_header_size
lnk_section_push_reloc_undefined(header_sect, file_header_chunk, LNK_Reloc_CHUNK_SIZE_FILE_16, OffsetOf(COFF_Header, optional_header_size), str8_lit(LNK_PE_OPT_HEADER_SYMBOL_NAME), LNK_SymbolScopeFlag_Internal);
lnk_section_push_reloc_undefined(header_sect, file_header_chunk, LNK_Reloc_CHUNK_SIZE_FILE_16, OffsetOf(COFF_Header, optional_header_size), str8_lit(LNK_PE_DIRECTORY_ARRAY_SYMBOL_NAME), LNK_SymbolScopeFlag_Internal);
lnk_section_push_reloc_undefined(header_sect, file_header_chunk, LNK_Reloc_CHUNK_SIZE_FILE_16, OffsetOf(COFF_FileHeader, optional_header_size), str8_lit(LNK_PE_OPT_HEADER_SYMBOL_NAME), LNK_SymbolScopeFlag_Internal);
lnk_section_push_reloc_undefined(header_sect, file_header_chunk, LNK_Reloc_CHUNK_SIZE_FILE_16, OffsetOf(COFF_FileHeader, optional_header_size), str8_lit(LNK_PE_DIRECTORY_ARRAY_SYMBOL_NAME), LNK_SymbolScopeFlag_Internal);
return file_header_chunk;
}
@@ -2173,17 +2175,17 @@ lnk_build_pe_optional_header_x64(LNK_SymbolTable *symtab,
continue;
}
// :sizeof_uninited_data
if (sect->flags & COFF_SectionFlag_CNT_UNINITIALIZED_DATA) {
if (sect->flags & COFF_SectionFlag_CntUninitializedData) {
lnk_section_push_reloc_undefined(header_sect, opt_header_chunk, LNK_Reloc_CHUNK_SIZE_VIRT_32, OffsetOf(PE_OptionalHeader32Plus, sizeof_uninited_data), sect->name, LNK_SymbolScopeFlag_Internal);
}
// :sizeof_inited_data
if (sect->flags & COFF_SectionFlag_CNT_INITIALIZED_DATA) {
if (sect->flags & COFF_SectionFlag_CntInitializedData) {
lnk_section_push_reloc_undefined(header_sect, opt_header_chunk, LNK_Reloc_CHUNK_SIZE_FILE_32, OffsetOf(PE_OptionalHeader32Plus, sizeof_inited_data), sect->name, LNK_SymbolScopeFlag_Internal);
}
// :sizeof_code
if (sect->flags & COFF_SectionFlag_CNT_CODE) {
if (sect->flags & COFF_SectionFlag_CntCode) {
lnk_section_push_reloc_undefined(header_sect, opt_header_chunk, LNK_Reloc_CHUNK_SIZE_FILE_32, OffsetOf(PE_OptionalHeader32Plus, sizeof_code), sect->name, LNK_SymbolScopeFlag_Internal);
}
@@ -2202,7 +2204,7 @@ lnk_build_pe_optional_header_x64(LNK_SymbolTable *symtab,
lnk_section_push_reloc(header_sect, opt_header_chunk, LNK_Reloc_FILE_ALIGN_32, OffsetOf(PE_OptionalHeader32Plus, sizeof_headers), &g_null_symbol);
// :check_sum
lnk_symbol_table_push_defined_chunk(symtab, str8_lit(LNK_PE_CHECKSUM_SYMBOL_NAME), LNK_DefinedSymbolVisibility_Internal, 0, opt_header_chunk, OffsetOf(PE_OptionalHeader32Plus, check_sum), COFF_ComdatSelectType_NODUPLICATES, 0);
lnk_symbol_table_push_defined_chunk(symtab, str8_lit(LNK_PE_CHECKSUM_SYMBOL_NAME), LNK_DefinedSymbolVisibility_Internal, 0, opt_header_chunk, OffsetOf(PE_OptionalHeader32Plus, check_sum), COFF_ComdatSelect_NoDuplicates, 0);
// :data_dir_count
lnk_section_push_reloc_undefined(header_sect, opt_header_chunk, LNK_Reloc_ADDR_32, OffsetOf(PE_OptionalHeader32Plus, data_dir_count), str8_lit(LNK_PE_DIRECTORY_COUNT_SYMBOL_NAME), LNK_SymbolScopeFlag_Internal);
@@ -2272,11 +2274,11 @@ lnk_build_coff_section_table(LNK_SymbolTable *symtab, LNK_Section *header_sect,
}
// push COFF header array chunk
LNK_Chunk *coff_header_array_chunk = lnk_section_push_chunk_list(header_sect, parent_chunk, str8_zero());
lnk_chunk_set_debugf(header_sect->arena, coff_header_array_chunk, LNK_COFF_SECT_HEADER_ARRAY_SYMBOL_NAME);
LNK_Chunk *COFF_FileHeader_array_chunk = lnk_section_push_chunk_list(header_sect, parent_chunk, str8_zero());
lnk_chunk_set_debugf(header_sect->arena, COFF_FileHeader_array_chunk, LNK_COFF_SECT_HEADER_ARRAY_SYMBOL_NAME);
// define symbol for COFF header array
lnk_symbol_table_push_defined_chunk(symtab, str8_lit(LNK_COFF_SECT_HEADER_ARRAY_SYMBOL_NAME), LNK_DefinedSymbolVisibility_Internal, 0, coff_header_array_chunk, 0, 0, 0);
lnk_symbol_table_push_defined_chunk(symtab, str8_lit(LNK_COFF_SECT_HEADER_ARRAY_SYMBOL_NAME), LNK_DefinedSymbolVisibility_Internal, 0, COFF_FileHeader_array_chunk, 0, 0, 0);
// push headers
for (LNK_Section *sect = &sect_arr.v[0], *sect_opl = sect + sect_arr.count; sect < sect_opl; sect += 1) {
@@ -2286,38 +2288,38 @@ lnk_build_coff_section_table(LNK_SymbolTable *symtab, LNK_Section *header_sect,
if (!sect->has_layout) {
continue;
}
COFF_SectionHeader *coff_header = push_array_no_zero(header_sect->arena, COFF_SectionHeader, 1);
COFF_SectionHeader *COFF_FileHeader = push_array_no_zero(header_sect->arena, COFF_SectionHeader, 1);
// TODO: for objs we can store long name in string table and write here /offset
if (sect->name.size > sizeof(coff_header->name)) {
if (sect->name.size > sizeof(COFF_FileHeader->name)) {
lnk_error(LNK_Warning_LongSectionName, "not enough space in COFF section header to store entire name \"%S\"", sect->name);
}
MemorySet(&coff_header->name[0], 0, sizeof(coff_header->name));
MemoryCopy(&coff_header->name[0], sect->name.str, Min(sect->name.size, sizeof(coff_header->name)));
coff_header->vsize = 0; // :vsize
coff_header->voff = 0; // :voff
coff_header->fsize = 0; // :fsize
coff_header->foff = 0; // :foff
coff_header->relocs_foff = 0; // :relocs_foff
coff_header->lines_foff = 0; // obsolete
coff_header->reloc_count = 0; // :reloc_count
coff_header->line_count = 0; // obsolete
coff_header->flags = sect->flags;
MemorySet(&COFF_FileHeader->name[0], 0, sizeof(COFF_FileHeader->name));
MemoryCopy(&COFF_FileHeader->name[0], sect->name.str, Min(sect->name.size, sizeof(COFF_FileHeader->name)));
COFF_FileHeader->vsize = 0; // :vsize
COFF_FileHeader->voff = 0; // :voff
COFF_FileHeader->fsize = 0; // :fsize
COFF_FileHeader->foff = 0; // :foff
COFF_FileHeader->relocs_foff = 0; // :relocs_foff
COFF_FileHeader->lines_foff = 0; // obsolete
COFF_FileHeader->reloc_count = 0; // :reloc_count
COFF_FileHeader->line_count = 0; // obsolete
COFF_FileHeader->flags = sect->flags;
// push chunk
LNK_Chunk *coff_header_chunk = lnk_section_push_chunk_raw(header_sect, coff_header_array_chunk, coff_header, sizeof(*coff_header), str8_zero());
LNK_Chunk *COFF_FileHeader_chunk = lnk_section_push_chunk_raw(header_sect, COFF_FileHeader_array_chunk, COFF_FileHeader, sizeof(*COFF_FileHeader), str8_zero());
// :vsize
lnk_section_push_reloc_undefined(header_sect, coff_header_chunk, LNK_Reloc_CHUNK_SIZE_VIRT_32, OffsetOf(COFF_SectionHeader, vsize), sect->name, LNK_SymbolScopeFlag_Internal);
lnk_section_push_reloc_undefined(header_sect, COFF_FileHeader_chunk, LNK_Reloc_CHUNK_SIZE_VIRT_32, OffsetOf(COFF_SectionHeader, vsize), sect->name, LNK_SymbolScopeFlag_Internal);
// :voff
lnk_section_push_reloc_undefined(header_sect, coff_header_chunk, LNK_Reloc_VIRT_OFF_32, OffsetOf(COFF_SectionHeader, voff), sect->name, LNK_SymbolScopeFlag_Internal);
lnk_section_push_reloc_undefined(header_sect, COFF_FileHeader_chunk, LNK_Reloc_VIRT_OFF_32, OffsetOf(COFF_SectionHeader, voff), sect->name, LNK_SymbolScopeFlag_Internal);
if (~sect->flags & COFF_SectionFlag_CNT_UNINITIALIZED_DATA) {
if (~sect->flags & COFF_SectionFlag_CntUninitializedData) {
// :fsize
lnk_section_push_reloc_undefined(header_sect, coff_header_chunk, LNK_Reloc_CHUNK_SIZE_FILE_32, OffsetOf(COFF_SectionHeader, fsize), sect->name, LNK_SymbolScopeFlag_Internal);
lnk_section_push_reloc_undefined(header_sect, COFF_FileHeader_chunk, LNK_Reloc_CHUNK_SIZE_FILE_32, OffsetOf(COFF_SectionHeader, fsize), sect->name, LNK_SymbolScopeFlag_Internal);
// :foff
lnk_section_push_reloc_undefined(header_sect, coff_header_chunk, LNK_Reloc_FILE_OFF_32, OffsetOf(COFF_SectionHeader, foff), sect->name, LNK_SymbolScopeFlag_Internal);
lnk_section_push_reloc_undefined(header_sect, COFF_FileHeader_chunk, LNK_Reloc_FILE_OFF_32, OffsetOf(COFF_SectionHeader, foff), sect->name, LNK_SymbolScopeFlag_Internal);
}
// TODO: :reloc_off
@@ -2325,10 +2327,10 @@ lnk_build_coff_section_table(LNK_SymbolTable *symtab, LNK_Section *header_sect,
}
// push symbol for section header count
U64 header_count = coff_header_array_chunk->u.list->count;
U64 header_count = COFF_FileHeader_array_chunk->u.list->count;
lnk_symbol_table_push_defined_va(symtab, str8_lit(LNK_COFF_SECT_HEADER_COUNT_SYMBOL_NAME), LNK_DefinedSymbolVisibility_Internal, 0, header_count);
return coff_header_array_chunk;
return COFF_FileHeader_array_chunk;
}
internal LNK_Chunk *
@@ -2371,7 +2373,7 @@ lnk_build_win32_image_header(LNK_SymbolTable *symtab,
lnk_build_pe_magic(symtab, header_sect, pe_magic_chunk);
lnk_build_coff_file_header(symtab, header_sect, coff_file_header_chunk, config->machine, config->time_stamp, config->file_characteristics);
switch (config->machine) {
case COFF_MachineType_X64: {
case COFF_Machine_X64: {
lnk_build_pe_optional_header_x64(symtab,
header_sect,
pe_optional_chunk,
@@ -2455,13 +2457,13 @@ THREAD_POOL_TASK_FUNC(lnk_weak_symbol_finder)
LNK_Symbol *lazy = 0;
switch (weak->lookup_type) {
case COFF_WeakExtType_NOLIBRARY: {
case COFF_WeakExt_NoLibrary: {
// NOLIBRARY means weak symbol should be resolved in case where strong definition pulls in lib member.
} break;
case COFF_WeakExtType_SEARCH_LIBRARY: {
case COFF_WeakExt_SearchLibrary: {
lazy = lnk_symbol_table_search(task->symtab, LNK_SymbolScopeFlag_Lib, symbol->name);
} break;
case COFF_WeakExtType_SEARCH_ALIAS: {
case COFF_WeakExt_SearchAlias: {
lazy = lnk_symbol_table_search(task->symtab, LNK_SymbolScopeFlag_Lib, symbol->name);
if (!lazy) {
if (str8_match_lit(".weak.", symbol->name, StringMatchFlag_RightSideSloppy)) {
@@ -2964,9 +2966,9 @@ lnk_log_size_breakdown(LNK_SectionTable *st, LNK_SymbolTable *symtab)
LNK_Section *sect = &sect_node->data;
if (sect->has_layout) {
U64 sect_size = lnk_file_size_from_chunk_ref(sect_id_map, sect->root->ref);
if (sect->flags & COFF_SectionFlag_CNT_CODE) {
if (sect->flags & COFF_SectionFlag_CntCode) {
code_size += sect_size;
} else if (sect->flags & COFF_SectionFlag_CNT_INITIALIZED_DATA) {
} else if (sect->flags & COFF_SectionFlag_CntInitializedData) {
data_size += sect_size;
}
}
@@ -2974,21 +2976,21 @@ lnk_log_size_breakdown(LNK_SectionTable *st, LNK_SymbolTable *symtab)
LNK_Symbol *dos_header_symbol = lnk_symbol_table_search(symtab, LNK_SymbolScopeFlag_Internal, str8_lit(LNK_DOS_HEADER_SYMBOL_NAME));
LNK_Symbol *dos_program_symbol = lnk_symbol_table_search(symtab, LNK_SymbolScopeFlag_Internal, str8_lit(LNK_DOS_PROGRAM_SYMBOL_NAME));
LNK_Symbol *coff_header_symbol = lnk_symbol_table_search(symtab, LNK_SymbolScopeFlag_Internal, str8_lit(LNK_COFF_HEADER_SYMBOL_NAME));
LNK_Symbol *COFF_FileHeader_symbol = lnk_symbol_table_search(symtab, LNK_SymbolScopeFlag_Internal, str8_lit(LNK_COFF_FILE_HEADER_SYMBOL_NAME));
LNK_Symbol *coff_section_header_symbol = lnk_symbol_table_search(symtab, LNK_SymbolScopeFlag_Internal, str8_lit(LNK_COFF_SECT_HEADER_ARRAY_SYMBOL_NAME));
LNK_Symbol *pe_opt_header_symbol = lnk_symbol_table_search(symtab, LNK_SymbolScopeFlag_Internal, str8_lit(LNK_PE_OPT_HEADER_SYMBOL_NAME));
LNK_Symbol *pe_directories_symbol = lnk_symbol_table_search(symtab, LNK_SymbolScopeFlag_Internal, str8_lit(LNK_PE_DIRECTORY_ARRAY_SYMBOL_NAME));
LNK_Chunk *dos_header_chunk = dos_header_symbol->u.defined.u.chunk;
LNK_Chunk *dos_program_chunk = dos_program_symbol->u.defined.u.chunk;
LNK_Chunk *coff_header_chunk = coff_header_symbol->u.defined.u.chunk;
LNK_Chunk *COFF_FileHeader_chunk = COFF_FileHeader_symbol->u.defined.u.chunk;
LNK_Chunk *coff_section_header_chunk = coff_section_header_symbol->u.defined.u.chunk;
LNK_Chunk *pe_opt_header_chunk = pe_opt_header_symbol->u.defined.u.chunk;
LNK_Chunk *pe_directories_chunk = pe_directories_symbol->u.defined.u.chunk;
U64 dos_header_size = lnk_file_size_from_chunk_ref(sect_id_map, dos_header_chunk->ref);
U64 dos_program_size = lnk_file_size_from_chunk_ref(sect_id_map, dos_program_chunk->ref);
U64 coff_header_size = lnk_file_size_from_chunk_ref(sect_id_map, coff_header_chunk->ref);
U64 COFF_FileHeader_size = lnk_file_size_from_chunk_ref(sect_id_map, COFF_FileHeader_chunk->ref);
U64 coff_section_header_size = lnk_file_size_from_chunk_ref(sect_id_map, coff_section_header_chunk->ref);
U64 pe_opt_header_size = lnk_file_size_from_chunk_ref(sect_id_map, pe_opt_header_chunk->ref);
U64 pe_directories_size = lnk_file_size_from_chunk_ref(sect_id_map, pe_directories_chunk->ref);
@@ -2997,7 +2999,7 @@ lnk_log_size_breakdown(LNK_SectionTable *st, LNK_SymbolTable *symtab)
str8_list_pushf(scratch.arena, &output_list, "--- Image Size Breakdown -------------------------------------------------------");
str8_list_pushf(scratch.arena, &output_list, " DOS Header: %M", dos_header_size);
str8_list_pushf(scratch.arena, &output_list, " DOS Program Stub: %M", dos_program_size);
str8_list_pushf(scratch.arena, &output_list, " COFF Header: %M", coff_header_size);
str8_list_pushf(scratch.arena, &output_list, " COFF Header: %M", COFF_FileHeader_size);
str8_list_pushf(scratch.arena, &output_list, " COFF Section Headers: %M", coff_section_header_size);
str8_list_pushf(scratch.arena, &output_list, " PE Header: %M", pe_opt_header_size);
str8_list_pushf(scratch.arena, &output_list, " Directories: %M", pe_directories_size);
@@ -3403,8 +3405,8 @@ lnk_run(int argc, char **argv)
String8 delay_helper_name = str8_zero();
switch (config->machine) {
case COFF_MachineType_X86: delay_helper_name = str8_cstring(LNK_DELAY_LOAD_HELPER2_X86_SYMBOL_NAME); break;
case COFF_MachineType_X64: delay_helper_name = str8_cstring(LNK_DELAY_LOAD_HELPER2_SYMBOL_NAME); break;
case COFF_Machine_X86: delay_helper_name = str8_cstring(LNK_DELAY_LOAD_HELPER2_X86_SYMBOL_NAME); break;
case COFF_Machine_X64: delay_helper_name = str8_cstring(LNK_DELAY_LOAD_HELPER2_SYMBOL_NAME); break;
default: NotImplemented;
}
@@ -3438,7 +3440,7 @@ lnk_run(int argc, char **argv)
for (String8Node *from_node = alt_name_list.from_list.first, *to_node = alt_name_list.to_list.first;
from_node != 0;
from_node = from_node->next, to_node = to_node->next) {
LNK_Symbol *weak = lnk_symbol_table_push_weak(symtab, from_node->string, COFF_WeakExtType_SEARCH_ALIAS, to_node->string);
LNK_Symbol *weak = lnk_symbol_table_push_weak(symtab, from_node->string, COFF_WeakExt_SearchAlias, to_node->string);
lnk_symbol_list_push(scratch.arena, &input_weak_list, weak);
}
ProfEnd();
@@ -3458,12 +3460,12 @@ lnk_run(int argc, char **argv)
case State_InputImports: {
ProfBegin("Input Imports");
for (LNK_InputImport *input = input_import_list.first; input != 0; input = input->next) {
COFF_ImportHeader *import_header = &input->import_header;
COFF_ParsedArchiveImportHeader *import_header = &input->import_header;
KeyValuePair *is_delayed = hash_table_search_path(delay_load_dll_ht, import_header->dll_name);
if (is_delayed) {
if (!imptab_delayed) {
Assert(config->machine != COFF_MachineType_UNKNOWN);
Assert(config->machine != COFF_Machine_Unknown);
B32 is_unloadable = !!(config->flags & LNK_ConfigFlag_DelayUnload);
B32 is_bindable = !!(config->flags & LNK_ConfigFlag_DelayBind);
imptab_delayed = lnk_import_table_alloc_delayed(st, symtab, config->machine, is_unloadable, is_bindable);
@@ -3478,7 +3480,7 @@ lnk_run(int argc, char **argv)
}
} else {
if (!imptab_static) {
Assert(config->machine != COFF_MachineType_UNKNOWN);
Assert(config->machine != COFF_Machine_Unknown);
imptab_static = lnk_import_table_alloc_static(st, symtab, config->machine);
}
LNK_ImportDLL *dll = lnk_import_table_search_dll(imptab_static, import_header->dll_name);
@@ -3560,14 +3562,14 @@ lnk_run(int argc, char **argv)
LNK_Obj *obj = &obj_node_arr.v[obj_idx].data;
// derive machine from obj
if (config->machine == COFF_MachineType_UNKNOWN) {
if (config->machine == COFF_Machine_Unknown) {
config->machine = obj->machine;
} else if (config->machine != COFF_MachineType_X64) {
} else if (config->machine != COFF_Machine_X64) {
lnk_error_with_loc(LNK_Error_UnsupportedMachine, obj->path, obj->lib_path, "%S machine is supported", coff_string_from_machine_type(obj->machine));
} else {
// is obj machine compatible?
if (config->machine != obj->machine &&
obj->machine != COFF_MachineType_UNKNOWN) { // obj with unknown machine type is compatible with any other machine type
obj->machine != COFF_Machine_Unknown) { // obj with unknown machine type is compatible with any other machine type
lnk_error_obj(LNK_Error_IncompatibleObj, obj,
"conflicting machine types expected %S but got %S",
coff_string_from_machine_type(config->machine),
@@ -3989,18 +3991,18 @@ lnk_run(int argc, char **argv)
if (pdata_symbol) {
String8 pdata = lnk_data_from_chunk_ref_no_pad(sect_id_map, image_data, pdata_symbol->u.defined.u.chunk->ref);
switch (config->machine) {
case COFF_MachineType_X86:
case COFF_MachineType_X64: {
case COFF_Machine_X86:
case COFF_Machine_X64: {
U64 count = pdata.size / sizeof(PE_IntelPdata);
radsort((PE_IntelPdata *)pdata.str, count, lnk_pdata_is_before_x8664);
} break;
case COFF_MachineType_ARM64:
case COFF_MachineType_ARM: {
case COFF_Machine_Arm64:
case COFF_Machine_Arm: {
AssertAlways(!"TOOD: ARM");
} break;
case COFF_MachineType_MIPSFPU:
case COFF_MachineType_MIPS16:
case COFF_MachineType_MIPSFPU16: {
case COFF_Machine_MipsFpu:
case COFF_Machine_Mips16:
case COFF_Machine_MipsFpu16: {
AssertAlways(!"TODO: MIPS");
} break;
}
+8 -8
View File
@@ -49,7 +49,7 @@
#define LNK_DOS_HEADER_SYMBOL_NAME "DOS_HEADER"
#define LNK_DOS_PROGRAM_SYMBOL_NAME "DOS_PROGRAM"
#define LNK_PE_MAGIC_SYMBOL_NAME "PE_MAGIC"
#define LNK_COFF_HEADER_SYMBOL_NAME "COFF_HEADER"
#define LNK_COFF_FILE_HEADER_SYMBOL_NAME "COFF_FILE_HEADER"
#define LNK_PE_DIRECTORY_ARRAY_SYMBOL_NAME "PE_DIRECTORY_ARRAY"
#define LNK_PE_DIRECTORY_COUNT_SYMBOL_NAME "PE_DIRECTORY_COUNT"
#define LNK_PE_OPT_HEADER_SYMBOL_NAME "PE_OPTIONAL_HEADER"
@@ -82,10 +82,10 @@
#define LNK_DELAY_LOAD_HELPER2_SYMBOL_NAME "__delayLoadHelper2"
#define LNK_DELAY_LOAD_HELPER2_X86_SYMBOL_NAME "___delayLoadHelper2@8"
#define LNK_TEXT_SECTION_FLAGS (COFF_SectionFlag_CNT_CODE|COFF_SectionFlag_MEM_EXECUTE|COFF_SectionFlag_MEM_READ)
#define LNK_DATA_SECTION_FLAGS (COFF_SectionFlag_CNT_INITIALIZED_DATA|COFF_SectionFlag_MEM_READ|COFF_SectionFlag_MEM_WRITE)
#define LNK_RDATA_SECTION_FLAGS (COFF_SectionFlag_CNT_INITIALIZED_DATA|COFF_SectionFlag_MEM_READ)
#define LNK_BSS_SECTION_FLAGS (COFF_SectionFlag_CNT_UNINITIALIZED_DATA|COFF_SectionFlag_MEM_READ|COFF_SectionFlag_MEM_WRITE)
#define LNK_TEXT_SECTION_FLAGS (COFF_SectionFlag_CntCode|COFF_SectionFlag_MemExecute|COFF_SectionFlag_MemRead)
#define LNK_DATA_SECTION_FLAGS (COFF_SectionFlag_CntInitializedData|COFF_SectionFlag_MemRead|COFF_SectionFlag_MemWrite)
#define LNK_RDATA_SECTION_FLAGS (COFF_SectionFlag_CntInitializedData|COFF_SectionFlag_MemRead)
#define LNK_BSS_SECTION_FLAGS (COFF_SectionFlag_CntUninitializedData|COFF_SectionFlag_MemRead|COFF_SectionFlag_MemWrite)
#define LNK_IDATA_SECTION_FLAGS LNK_DATA_SECTION_FLAGS
#define LNK_DEBUG_DIR_SECTION_FLAGS LNK_DATA_SECTION_FLAGS
#define LNK_RSRC_SECTION_FLAGS LNK_DATA_SECTION_FLAGS
@@ -96,8 +96,8 @@
#define LNK_GIATS_SECTION_FLAGS LNK_RDATA_SECTION_FLAGS
#define LNK_GLJMP_SECTION_FLAGS LNK_RDATA_SECTION_FLAGS
#define LNK_GEHCONT_SECTION_FLAGS LNK_RDATA_SECTION_FLAGS
#define LNK_RELOC_SECTION_FLAGS (LNK_RDATA_SECTION_FLAGS | COFF_SectionFlag_MEM_DISCARDABLE)
#define LNK_DEBUG_SECTION_FLAGS (LNK_RDATA_SECTION_FLAGS | COFF_SectionFlag_MEM_DISCARDABLE)
#define LNK_RELOC_SECTION_FLAGS (LNK_RDATA_SECTION_FLAGS | COFF_SectionFlag_MemDiscardable)
#define LNK_DEBUG_SECTION_FLAGS (LNK_RDATA_SECTION_FLAGS | COFF_SectionFlag_MemDiscardable)
////////////////////////////////
@@ -114,7 +114,7 @@ typedef String8List LNK_InputLibList;
typedef struct LNK_InputImport
{
COFF_ImportHeader import_header;
COFF_ParsedArchiveImportHeader import_header;
struct LNK_InputImport *next;
} LNK_InputImport;
+25 -25
View File
@@ -352,11 +352,11 @@ lnk_get_default_function_pad_min(COFF_MachineType machine)
{
U64 function_pad_min = 0;
switch (machine) {
case COFF_MachineType_UNKNOWN: break;
case COFF_MachineType_X86: {
case COFF_Machine_Unknown: break;
case COFF_Machine_X86: {
function_pad_min = 5;
} break;
case COFF_MachineType_X64: {
case COFF_Machine_X64: {
function_pad_min = 6;
} break;
default: {
@@ -396,12 +396,12 @@ lnk_get_default_subsystem_version(PE_WindowsSubsystem subsystem, COFF_MachineTyp
case PE_WindowsSubsystem_WINDOWS_CUI: {
switch (machine) {
case COFF_MachineType_X64:
case COFF_MachineType_X86: ver = make_version(6,0); break;
case COFF_Machine_X64:
case COFF_Machine_X86: ver = make_version(6,0); break;
case COFF_MachineType_ARMNT:
case COFF_MachineType_ARM64:
case COFF_MachineType_ARM: ver = make_version(6,2); break;
case COFF_Machine_ArmNt:
case COFF_Machine_Arm64:
case COFF_Machine_Arm: ver = make_version(6,2); break;
default: lnk_not_implemented("define subsystem(%S) version for %S", pe_string_from_subsystem(subsystem), coff_string_from_machine_type(machine)); break;
}
@@ -409,12 +409,12 @@ lnk_get_default_subsystem_version(PE_WindowsSubsystem subsystem, COFF_MachineTyp
case PE_WindowsSubsystem_WINDOWS_GUI: {
switch (machine) {
case COFF_MachineType_X64:
case COFF_MachineType_X86: ver = make_version(6,0); break;
case COFF_Machine_X64:
case COFF_Machine_X86: ver = make_version(6,0); break;
case COFF_MachineType_ARMNT:
case COFF_MachineType_ARM64:
case COFF_MachineType_ARM: ver = make_version(6,2); break;
case COFF_Machine_ArmNt:
case COFF_Machine_Arm64:
case COFF_Machine_Arm: ver = make_version(6,2); break;
default: lnk_not_implemented("define subsystem(%S) version for %S", pe_string_from_subsystem(subsystem), coff_string_from_machine_type(machine)); break;
}
@@ -444,13 +444,13 @@ lnk_get_min_subsystem_version(PE_WindowsSubsystem subsystem, COFF_MachineType ma
case PE_WindowsSubsystem_WINDOWS_CUI: {
switch (machine) {
case COFF_MachineType_X86: ver = make_version(5,1); break;
case COFF_Machine_X86: ver = make_version(5,1); break;
case COFF_MachineType_X64: ver = make_version(5,2); break;
case COFF_Machine_X64: ver = make_version(5,2); break;
case COFF_MachineType_ARMNT:
case COFF_MachineType_ARM64:
case COFF_MachineType_ARM: ver = make_version(6,2); break;
case COFF_Machine_ArmNt:
case COFF_Machine_Arm64:
case COFF_Machine_Arm: ver = make_version(6,2); break;
default: lnk_not_implemented("define min subsystem(%S) version for %S", pe_string_from_subsystem(subsystem), coff_string_from_machine_type(machine)); break;
}
@@ -458,13 +458,13 @@ lnk_get_min_subsystem_version(PE_WindowsSubsystem subsystem, COFF_MachineType ma
case PE_WindowsSubsystem_WINDOWS_GUI: {
switch (machine) {
case COFF_MachineType_X86: ver = make_version(5,1); break;
case COFF_Machine_X86: ver = make_version(5,1); break;
case COFF_MachineType_X64: ver = make_version(5,2); break;
case COFF_Machine_X64: ver = make_version(5,2); break;
case COFF_MachineType_ARMNT:
case COFF_MachineType_ARM64:
case COFF_MachineType_ARM: ver = make_version(6,2); break;
case COFF_Machine_ArmNt:
case COFF_Machine_Arm64:
case COFF_Machine_Arm: ver = make_version(6,2); break;
default: lnk_not_implemented("define min subsystem(%S) version for %S", pe_string_from_subsystem(subsystem), coff_string_from_machine_type(machine)); break;
}
@@ -784,7 +784,7 @@ lnk_parse_export_directive(Arena *arena, LNK_ExportParseList *list, String8List
// parse directive
String8 name = str8_zero();
String8 alias = str8_zero();
String8 type = coff_string_from_import_header_type(COFF_ImportHeaderType_CODE);
String8 type = coff_string_from_import_header_type(COFF_ImportHeader_Code);
if (value_list.node_count > 0) {
String8List dir_split = str8_split_by_string_chars(scratch.arena, value_list.first->string, str8_lit("="), 0);
B32 is_export_valid = value_list.node_count <= 2 && value_list.node_count > 0;
@@ -1193,7 +1193,7 @@ lnk_apply_cmd_option_to_config(Arena *arena, LNK_Config *config, String8 cmd_nam
case LNK_CmdSwitch_Machine: {
if (value_strings.node_count == 1) {
COFF_MachineType machine = coff_machine_from_string(value_strings.first->string);
if (machine != COFF_MachineType_UNKNOWN) {
if (machine != COFF_Machine_Unknown) {
config->machine = machine;
} else {
lnk_error_cmd_switch(LNK_Error_Cmdl, obj_path, lib_path, cmd_switch, "unknown parameter \"%S\"", value_strings.first->string);
+1 -1
View File
@@ -3025,7 +3025,7 @@ THREAD_POOL_TASK_FUNC(lnk_push_dbi_sec_contrib_task)
// Mod1::fUpdateSecContrib
if (sc_count > 0) {
for (U64 sc_idx = 0; sc_idx < sc_count; ++sc_idx) {
if (sc_arr[sc_idx].data.base.flags & COFF_SectionFlag_CNT_CODE) {
if (sc_arr[sc_idx].data.base.flags & COFF_SectionFlag_CntCode) {
mod->first_sc = sc_arr[sc_idx].data;
break;
}
+5 -5
View File
@@ -82,22 +82,22 @@ lnk_export_table_push_export(LNK_ExportTable *exptab, LNK_SymbolTable *symtab, L
// to CODE instead of DATA. But if you try export global variable with:
// #pragma comment(linker, "/export:global_bar,CODE")
// MSVC and LLD issue an error. For compatibility sake we do the same thing too.
COFF_ImportHeaderType type = coff_import_header_type_from_string(exp_parse->type);
COFF_ImportType type = coff_import_header_type_from_string(exp_parse->type);
switch (type) {
case COFF_ImportHeaderType_CODE: {
case COFF_ImportHeader_Code: {
B32 is_export_data = !(def->flags & (LNK_DefinedSymbolFlag_IsFunc|LNK_DefinedSymbolFlag_IsThunk));
if (is_export_data) {
lnk_error(LNK_Error_IllExport, "export \"%S\" is DATA but has specifier CODE", exp_parse->name);
}
} break;
case COFF_ImportHeaderType_DATA: {
case COFF_ImportHeader_Data: {
B32 is_export_code = !!(def->flags & (LNK_DefinedSymbolFlag_IsFunc|LNK_DefinedSymbolFlag_IsThunk));
if (is_export_code) {
lnk_error(LNK_Error_IllExport, "export \"%S\" is CODE but has specifier DATA", exp_parse->name);
}
} break;
case COFF_ImportHeaderType_CONST: {
lnk_not_implemented("TODO: COFF_ImportHeaderType_CONST");
case COFF_ImportHeader_Const: {
lnk_not_implemented("TODO: COFF_ImportHeader_Const");
} break;
default: {
if (exp_parse->type.size) {
+7 -7
View File
@@ -5,13 +5,13 @@
typedef struct LNK_Export
{
struct LNK_Export *next;
String8 name;
LNK_Symbol *symbol;
U32 id;
U16 ordinal;
COFF_ImportHeaderType type;
B32 is_private;
struct LNK_Export *next;
String8 name;
LNK_Symbol *symbol;
U32 id;
U16 ordinal;
COFF_ImportType type;
B32 is_private;
} LNK_Export;
typedef struct LNK_ExportList
+34 -34
View File
@@ -345,7 +345,7 @@ lnk_import_table_push_dll_delayed(LNK_ImportTable *imptab, LNK_SymbolTable *symt
// emit tail merge
LNK_Chunk *tail_merge_chunk = 0;
switch (machine) {
case COFF_MachineType_X64: {
case COFF_Machine_X64: {
LNK_Symbol *delay_load_helper_symbol = lnk_make_undefined_symbol(symtab->arena->v[0], str8_lit(LNK_DELAY_LOAD_HELPER2_SYMBOL_NAME), LNK_SymbolScopeFlag_Main);
tail_merge_chunk = lnk_emit_tail_merge_thunk_x64(code_sect, code_chunk, imp_desc_symbol, delay_load_helper_symbol);
} break;
@@ -375,7 +375,7 @@ lnk_import_table_push_dll_delayed(LNK_ImportTable *imptab, LNK_SymbolTable *symt
}
internal LNK_ImportFunc *
lnk_import_table_push_func_static(LNK_ImportTable *imptab, LNK_SymbolTable *symtab, LNK_ImportDLL *dll, COFF_ImportHeader *header)
lnk_import_table_push_func_static(LNK_ImportTable *imptab, LNK_SymbolTable *symtab, LNK_ImportDLL *dll, COFF_ParsedArchiveImportHeader *header)
{
ProfBeginFunction();
@@ -395,20 +395,20 @@ lnk_import_table_push_func_static(LNK_ImportTable *imptab, LNK_SymbolTable *symt
U64 import_size = coff_word_size_from_machine(dll->machine);
// generate sort index (optional)
String8 sort_index = str8_from_bits_u32(data_sect->arena, header->hint);
String8 sort_index = str8_from_bits_u32(data_sect->arena, header->hint_or_ordinal);
switch (header->name_type) {
case COFF_ImportHeaderNameType_ORDINAL: {
String8 ordinal_data = lnk_ordinal_data_from_hint(data_sect->arena, dll->machine, header->hint);
switch (header->import_by) {
case COFF_ImportBy_Ordinal: {
String8 ordinal_data = lnk_ordinal_data_from_hint(data_sect->arena, dll->machine, header->hint_or_ordinal);
ilt_chunk = lnk_section_push_chunk_data(data_sect, ilt_table_chunk, ordinal_data, sort_index);
iat_chunk = lnk_section_push_chunk_data(data_sect, iat_table_chunk, ordinal_data, sort_index);
// associate chunks
lnk_section_associate_chunks(data_sect, iat_chunk, ilt_chunk);
} break;
case COFF_ImportHeaderNameType_NAME: {
case COFF_ImportBy_Name: {
// put together name look up entry
String8 int_data = coff_make_import_lookup(data_sect->arena, header->hint, header->func_name);
String8 int_data = coff_make_import_lookup(data_sect->arena, header->hint_or_ordinal, header->func_name);
LNK_Chunk *int_chunk = lnk_section_push_chunk_data(data_sect, int_table_chunk, int_data, str8_zero());
// create symbol for lookup chunk
@@ -429,11 +429,11 @@ lnk_import_table_push_func_static(LNK_ImportTable *imptab, LNK_SymbolTable *symt
lnk_section_push_reloc(data_sect, ilt_chunk, LNK_Reloc_VIRT_OFF_32, 0, int_symbol);
lnk_section_push_reloc(data_sect, iat_chunk, LNK_Reloc_VIRT_OFF_32, 0, int_symbol);
} break;
case COFF_ImportHeaderNameType_UNDECORATE: {
lnk_not_implemented("TODO: COFF_ImportHeaderNameType_UNDECORATE");
case COFF_ImportBy_Undecorate: {
lnk_not_implemented("TODO: COFF_ImportBy_Undecorate");
} break;
case COFF_ImportHeaderNameType_NAME_NOPREFIX: {
lnk_not_implemented("TODO: COFF_ImportHeaderNameType_NAME_NOPREFIX");
case COFF_ImportBy_NameNoPrefix: {
lnk_not_implemented("TODO: COFF_ImportBy_NameNoPrefix");
} break;
}
@@ -444,9 +444,9 @@ lnk_import_table_push_func_static(LNK_ImportTable *imptab, LNK_SymbolTable *symt
// generate thunks
LNK_Symbol *jmp_thunk_symbol = g_null_symbol_ptr;
if (header->type == COFF_ImportHeaderType_CODE) {
if (header->type == COFF_ImportHeader_Code) {
switch (dll->machine) {
case COFF_MachineType_X64: {
case COFF_Machine_X64: {
// generate jump thunk
LNK_Chunk *jmp_thunk_chunk = lnk_emit_indirect_jump_thunk_x64(code_sect, code_table_chunk, iat_symbol);
lnk_section_associate_chunks(data_sect, iat_chunk, jmp_thunk_chunk);
@@ -472,7 +472,7 @@ lnk_import_table_push_func_static(LNK_ImportTable *imptab, LNK_SymbolTable *symt
}
internal LNK_ImportFunc *
lnk_import_table_push_func_delayed(LNK_ImportTable *imptab, LNK_SymbolTable *symtab, LNK_ImportDLL *dll, COFF_ImportHeader *header)
lnk_import_table_push_func_delayed(LNK_ImportTable *imptab, LNK_SymbolTable *symtab, LNK_ImportDLL *dll, COFF_ParsedArchiveImportHeader *header)
{
ProfBeginFunction();
@@ -498,16 +498,16 @@ lnk_import_table_push_func_delayed(LNK_ImportTable *imptab, LNK_SymbolTable *sym
LNK_Symbol *int_symbol = 0;
// generate sort index (optional)
String8 sort_index = str8_from_bits_u32(data_sect->arena, header->hint);
String8 sort_index = str8_from_bits_u32(data_sect->arena, header->hint_or_ordinal);
// generate thunks
LNK_Symbol *jmp_thunk_symbol = g_null_symbol_ptr;
LNK_Symbol *load_thunk_symbol = g_null_symbol_ptr;
LNK_Chunk *jmp_thunk_chunk = 0;
LNK_Chunk *load_thunk_chunk = 0;
if (header->type == COFF_ImportHeaderType_CODE) {
if (header->type == COFF_ImportHeader_Code) {
switch (dll->machine) {
case COFF_MachineType_X64: {
case COFF_Machine_X64: {
String8 iat_symbol_name = push_str8f(symtab->arena->v[0], "__imp_%S", header->func_name);
LNK_Symbol *iat_symbol = lnk_make_undefined_symbol(symtab->arena->v[0], iat_symbol_name, LNK_SymbolScopeFlag_Main);
@@ -523,9 +523,9 @@ lnk_import_table_push_func_delayed(LNK_ImportTable *imptab, LNK_SymbolTable *sym
}
}
switch (header->name_type) {
case COFF_ImportHeaderNameType_ORDINAL: {
String8 ordinal_data = lnk_ordinal_data_from_hint(data_sect->arena, dll->machine, header->hint);
switch (header->import_by) {
case COFF_ImportBy_Ordinal: {
String8 ordinal_data = lnk_ordinal_data_from_hint(data_sect->arena, dll->machine, header->hint_or_ordinal);
Assert(ordinal_data.size == import_size);
ilt_chunk = lnk_section_push_chunk_data(data_sect, ilt_table_chunk, ordinal_data, sort_index);
iat_chunk = lnk_section_push_chunk_bss(data_sect, iat_table_chunk, import_size, sort_index);
@@ -543,9 +543,9 @@ lnk_import_table_push_func_delayed(LNK_ImportTable *imptab, LNK_SymbolTable *sym
lnk_section_associate_chunks(data_sect, iat_chunk, uiat_chunk);
}
} break;
case COFF_ImportHeaderNameType_NAME: {
case COFF_ImportBy_Name: {
// put together name look up entry
String8 int_data = coff_make_import_lookup(data_sect->arena, header->hint, header->func_name);
String8 int_data = coff_make_import_lookup(data_sect->arena, header->hint_or_ordinal, header->func_name);
LNK_Chunk *int_chunk = lnk_section_push_chunk_data(data_sect, int_table_chunk, int_data, str8_zero());
// create symbol for lookup chunk
@@ -586,11 +586,11 @@ lnk_import_table_push_func_delayed(LNK_ImportTable *imptab, LNK_SymbolTable *sym
lnk_section_push_reloc(data_sect, uiat_chunk, LNK_Reloc_ADDR_64, 0, load_thunk_symbol);
}
} break;
case COFF_ImportHeaderNameType_UNDECORATE: {
lnk_not_implemented("TODO: COFF_ImportHeaderNameType_UNDECORATE");
case COFF_ImportBy_Undecorate: {
lnk_not_implemented("TODO: COFF_ImportBy_Undecorate");
} break;
case COFF_ImportHeaderNameType_NAME_NOPREFIX: {
lnk_not_implemented("TODO: COFF_ImportHeaderNameType_NAME_NOPREFIX");
case COFF_ImportBy_NameNoPrefix: {
lnk_not_implemented("TODO: COFF_ImportBy_NameNoPrefix");
} break;
}
@@ -624,14 +624,14 @@ lnk_ordinal_data_from_hint(Arena *arena, COFF_MachineType machine, U16 hint)
{
String8 ordinal_data = str8_zero();
switch (machine) {
case COFF_MachineType_X64: {
case COFF_Machine_X64: {
U64 *ordinal = push_array(arena, U64, 1);
*ordinal = coff_make_ordinal_64(hint);
*ordinal = coff_make_ordinal64(hint);
ordinal_data = str8_struct(ordinal);
} break;
case COFF_MachineType_X86: {
case COFF_Machine_X86: {
U32 *ordinal = push_array(arena, U32, 1);
*ordinal = coff_make_ordinal_32(hint);
*ordinal = coff_make_ordinal32(hint);
ordinal_data = str8_struct(ordinal);
} break;
default: lnk_not_implemented("TODO: support for machine 0x%x", machine);
@@ -736,7 +736,7 @@ lnk_emit_load_thunk_symbol(LNK_SymbolTable *symtab, LNK_Chunk *chunk, String8 fu
ProfBeginFunction();
// emit load thunk symbol
String8 load_thunk_name = push_str8f(symtab->arena->v[0], "__imp_load_%S", func_name);
LNK_Symbol *load_thunk_symbol = lnk_symbol_table_push_defined_chunk(symtab, load_thunk_name, LNK_DefinedSymbolVisibility_Extern, LNK_DefinedSymbolFlag_IsFunc|LNK_DefinedSymbolFlag_IsThunk, chunk, 0, COFF_ComdatSelectType_NODUPLICATES, 0);
LNK_Symbol *load_thunk_symbol = lnk_symbol_table_push_defined_chunk(symtab, load_thunk_name, LNK_DefinedSymbolVisibility_Extern, LNK_DefinedSymbolFlag_IsFunc|LNK_DefinedSymbolFlag_IsThunk, chunk, 0, COFF_ComdatSelect_NoDuplicates, 0);
ProfEnd();
return load_thunk_symbol;
}
@@ -746,7 +746,7 @@ lnk_emit_jmp_thunk_symbol(LNK_SymbolTable *symtab, LNK_Chunk *chunk, String8 fun
{
ProfBeginFunction();
String8 jmp_thunk_name = push_str8f(symtab->arena->v[0], "%S", func_name);
LNK_Symbol *jmp_thunk_symbol = lnk_symbol_table_push_defined_chunk(symtab, jmp_thunk_name, LNK_DefinedSymbolVisibility_Extern, LNK_DefinedSymbolFlag_IsFunc|LNK_DefinedSymbolFlag_IsThunk, chunk, 0, COFF_ComdatSelectType_ANY, 0);
LNK_Symbol *jmp_thunk_symbol = lnk_symbol_table_push_defined_chunk(symtab, jmp_thunk_name, LNK_DefinedSymbolVisibility_Extern, LNK_DefinedSymbolFlag_IsFunc|LNK_DefinedSymbolFlag_IsThunk, chunk, 0, COFF_ComdatSelect_Any, 0);
ProfEnd();
return jmp_thunk_symbol;
}
@@ -756,7 +756,7 @@ lnk_emit_tail_merge_symbol(LNK_SymbolTable *symtab, LNK_Chunk *chunk, String8 fu
{
ProfBeginFunction();
String8 tail_merge_name = push_str8f(symtab->arena->v[0], "__tailMerge_%S", func_name);
LNK_Symbol *tail_merge_symbol = lnk_symbol_table_push_defined_chunk(symtab, tail_merge_name, LNK_DefinedSymbolVisibility_Extern, LNK_DefinedSymbolFlag_IsFunc|LNK_DefinedSymbolFlag_IsThunk, chunk, 0, COFF_ComdatSelectType_NODUPLICATES, 0);
LNK_Symbol *tail_merge_symbol = lnk_symbol_table_push_defined_chunk(symtab, tail_merge_name, LNK_DefinedSymbolVisibility_Extern, LNK_DefinedSymbolFlag_IsFunc|LNK_DefinedSymbolFlag_IsThunk, chunk, 0, COFF_ComdatSelect_NoDuplicates, 0);
ProfEnd();
return tail_merge_symbol;
}
+2 -2
View File
@@ -64,8 +64,8 @@ internal LNK_ImportTable * lnk_import_table_alloc_delayed(LNK_SectionTable *st,
internal void lnk_import_table_release(LNK_ImportTable **imptab);
internal LNK_ImportDLL * lnk_import_table_push_dll_static(LNK_ImportTable *imptab, LNK_SymbolTable *symtab, String8 dll_name, COFF_MachineType machine);
internal LNK_ImportDLL * lnk_import_table_push_dll_delayed(LNK_ImportTable *imptab, LNK_SymbolTable *symtab, String8 dll_name, COFF_MachineType machine);
internal LNK_ImportFunc * lnk_import_table_push_func_static(LNK_ImportTable *imptab, LNK_SymbolTable *symtab, LNK_ImportDLL *dll, COFF_ImportHeader *header);
internal LNK_ImportFunc * lnk_import_table_push_func_delayed(LNK_ImportTable *imptab, LNK_SymbolTable *symtab, LNK_ImportDLL *dll, COFF_ImportHeader *header);
internal LNK_ImportFunc * lnk_import_table_push_func_static(LNK_ImportTable *imptab, LNK_SymbolTable *symtab, LNK_ImportDLL *dll, COFF_ParsedArchiveImportHeader *header);
internal LNK_ImportFunc * lnk_import_table_push_func_delayed(LNK_ImportTable *imptab, LNK_SymbolTable *symtab, LNK_ImportDLL *dll, COFF_ParsedArchiveImportHeader *header);
internal LNK_ImportDLL * lnk_import_table_search_dll(LNK_ImportTable *imptab, String8 name);
internal LNK_ImportFunc * lnk_import_table_search_func(LNK_ImportDLL *dll, String8 name);
+49 -49
View File
@@ -303,19 +303,19 @@ lnk_lib_writer_push_export(LNK_LibWriter *writer, COFF_MachineType machine, U64
lnk_lib_member_list_push(writer->arena, &writer->member_list, member);
switch (exp->type) {
case COFF_ImportHeaderType_CODE: {
case COFF_ImportHeader_Code: {
LNK_LibSymbol def_symbol = {0};
def_symbol.name = push_str8_copy(writer->arena, exp->name);
def_symbol.member_idx = member_idx;
lnk_lib_symbol_list_push(writer->arena, &writer->symbol_list, def_symbol);
}
case COFF_ImportHeaderType_DATA: {
case COFF_ImportHeader_Data: {
LNK_LibSymbol imp_symbol = {0};
imp_symbol.name = push_str8f(writer->arena, "__imp_%S", exp->name);
imp_symbol.member_idx = member_idx;
lnk_lib_symbol_list_push(writer->arena, &writer->symbol_list, imp_symbol);
} break;
case COFF_ImportHeaderType_CONST: {
case COFF_ImportHeader_Const: {
NotImplemented;
} break;
default: InvalidPath;
@@ -361,7 +361,7 @@ lnk_coff_archive_from_lib_build(Arena *arena, LNK_LibBuild *lib, B32 emit_second
// make member name
String8 name;
U64 name_with_slash_size = member->name.size + 1;
if (name_with_slash_size > COFF_ARCHIVE_MAX_SHORT_NAME_SIZE) {
if (name_with_slash_size > COFF_Archive_MaxShortNameSize) {
// have we seen this member name before?
KeyValuePair *is_present = hash_table_search_string(name_ht, member->name);
if (is_present) {
@@ -382,7 +382,7 @@ lnk_coff_archive_from_lib_build(Arena *arena, LNK_LibBuild *lib, B32 emit_second
str8_list_push(arena, &member_data_list, member_header);
str8_list_push(arena, &member_data_list, member_data);
str8_list_push_pad(arena, &member_data_list, member_data_list.total_size, COFF_ARCHIVE_ALIGN);
str8_list_push_pad(arena, &member_data_list, member_data_list.total_size, COFF_Archive_MemberAlign);
}
// long names member
@@ -390,7 +390,7 @@ lnk_coff_archive_from_lib_build(Arena *arena, LNK_LibBuild *lib, B32 emit_second
String8 header = lnk_build_lib_member_header(arena, str8_lit("//"), time_stamp, 0, 0, mode, long_names_list.total_size);
String8 data = str8_list_join(arena, &long_names_list, 0);
U64 member_offset = member_data_list.total_size + data.size + header.size;
str8_list_push_pad_front(arena, &member_data_list, member_offset, COFF_ARCHIVE_ALIGN);
str8_list_push_pad_front(arena, &member_data_list, member_offset, COFF_Archive_MemberAlign);
str8_list_push_front(arena, &member_data_list, data);
str8_list_push_front(arena, &member_data_list, header);
}
@@ -415,13 +415,13 @@ lnk_coff_archive_from_lib_build(Arena *arena, LNK_LibBuild *lib, B32 emit_second
U64 member_base_off;
{
U64 sizeof_first_header = COFF_ARCHIVE_MEMBER_HEADER_SIZE + sizeof(U32) + sizeof(U32) * symbol_count + name_buffer_size;
U64 sizeof_second_header = COFF_ARCHIVE_MEMBER_HEADER_SIZE + sizeof(U32) + sizeof(U32) * lib->member_count + sizeof(U32) + sizeof(U16) * symbol_count + name_buffer_size;
U64 sizeof_long_names = COFF_ARCHIVE_MEMBER_HEADER_SIZE + long_names_list.total_size;
U64 sizeof_first_header = sizeof(COFF_ArchiveMemberHeader) + sizeof(U32) + sizeof(U32) * symbol_count + name_buffer_size;
U64 sizeof_second_header = sizeof(COFF_ArchiveMemberHeader) + sizeof(U32) + sizeof(U32) * lib->member_count + sizeof(U32) + sizeof(U16) * symbol_count + name_buffer_size;
U64 sizeof_long_names = sizeof(COFF_ArchiveMemberHeader) + long_names_list.total_size;
sizeof_first_header = AlignPow2(sizeof_first_header, COFF_ARCHIVE_ALIGN);
sizeof_second_header = AlignPow2(sizeof_second_header, COFF_ARCHIVE_ALIGN);
sizeof_long_names = AlignPow2(sizeof_long_names, COFF_ARCHIVE_ALIGN);
sizeof_first_header = AlignPow2(sizeof_first_header, COFF_Archive_MemberAlign);
sizeof_second_header = AlignPow2(sizeof_second_header, COFF_Archive_MemberAlign);
sizeof_long_names = AlignPow2(sizeof_long_names, COFF_Archive_MemberAlign);
member_base_off = sizeof(g_coff_archive_sig);
member_base_off += sizeof_first_header;
@@ -468,7 +468,7 @@ lnk_coff_archive_from_lib_build(Arena *arena, LNK_LibBuild *lib, B32 emit_second
String8 member_header = lnk_build_lib_member_header(arena, str8_lit("/"), time_stamp, 0, 0, mode, member_data.size);
U64 member_offset = member_data_list.total_size + member_data.size + member_header.size;
str8_list_push_pad_front(arena, &member_data_list, member_offset, COFF_ARCHIVE_ALIGN);
str8_list_push_pad_front(arena, &member_data_list, member_offset, COFF_Archive_MemberAlign);
str8_list_push_front(arena, &member_data_list, member_data);
str8_list_push_front(arena, &member_data_list, member_header);
}
@@ -497,7 +497,7 @@ lnk_coff_archive_from_lib_build(Arena *arena, LNK_LibBuild *lib, B32 emit_second
String8 member_header = lnk_build_lib_member_header(arena, str8_lit("/"), time_stamp, 0, 0, mode, member_data.size);
U64 member_offset = sizeof(g_coff_archive_sig) + member_header.size + member_data.size;
str8_list_push_pad_front(arena, &member_data_list, member_offset, COFF_ARCHIVE_ALIGN);
str8_list_push_pad_front(arena, &member_data_list, member_offset, COFF_Archive_MemberAlign);
str8_list_push_front(arena, &member_data_list, member_data);
str8_list_push_front(arena, &member_data_list, member_header);
}
@@ -541,18 +541,18 @@ lnk_build_import_entry_obj(Arena *arena, String8 dll_name, COFF_MachineType mach
{
ProfBeginFunction();
Assert(machine == COFF_MachineType_X64);
Assert(machine == COFF_Machine_X64);
Assert(str8_match_lit("dll", str8_skip_last_dot(dll_name), StringMatchFlag_CaseInsensitive|StringMatchFlag_RightSideSloppy));
String8List list = {0};
COFF_Header *coff_header = push_array(arena, COFF_Header, 1);
coff_header->machine = machine;
str8_list_push(arena, &list, str8_struct(coff_header));
COFF_FileHeader *file_header = push_array(arena, COFF_FileHeader, 1);
file_header->machine = machine;
str8_list_push(arena, &list, str8_struct(file_header));
coff_header->section_count = 2;
COFF_SectionHeader *coff_sect_header_array = push_array(arena, COFF_SectionHeader, coff_header->section_count);
str8_list_push(arena, &list, str8_array(coff_sect_header_array, coff_header->section_count));
file_header->section_count = 2;
COFF_SectionHeader *coff_sect_header_array = push_array(arena, COFF_SectionHeader, file_header->section_count);
str8_list_push(arena, &list, str8_array(coff_sect_header_array, file_header->section_count));
PE_ImportEntry *import_entry = push_array(arena, PE_ImportEntry, 1);
U64 import_entry_off = list.total_size;
@@ -567,10 +567,10 @@ lnk_build_import_entry_obj(Arena *arena, String8 dll_name, COFF_MachineType mach
U64 import_entry_reloc_off = list.total_size;
str8_list_push(arena, &list, str8_array(import_entry_reloc_array, import_entry_reloc_count));
coff_header->symbol_count = 7;
COFF_Symbol16 *symbol_array = push_array(arena, COFF_Symbol16, coff_header->symbol_count);
coff_header->symbol_table_foff = safe_cast_u32(list.total_size);
str8_list_push(arena, &list, str8_array(symbol_array, coff_header->symbol_count));
file_header->symbol_count = 7;
COFF_Symbol16 *symbol_array = push_array(arena, COFF_Symbol16, file_header->symbol_count);
file_header->symbol_table_foff = safe_cast_u32(list.total_size);
str8_list_push(arena, &list, str8_array(symbol_array, file_header->symbol_count));
U64 string_table_base = list.total_size;
U32 *string_table_size_ptr = push_array(arena, U32, 1);
@@ -591,23 +591,23 @@ lnk_build_import_entry_obj(Arena *arena, String8 dll_name, COFF_MachineType mach
sect->foff = import_entry_off;
sect->reloc_count = import_entry_reloc_count;
sect->relocs_foff = import_entry_reloc_off;
sect->flags = COFF_SectionFlag_CNT_INITIALIZED_DATA|(COFF_SectionAlign_4BYTES << COFF_SectionFlag_ALIGN_SHIFT)|COFF_SectionFlag_MEM_READ|COFF_SectionFlag_MEM_WRITE;
sect->flags = COFF_SectionFlag_CntInitializedData|(COFF_SectionAlign_4Bytes << COFF_SectionFlag_AlignShift)|COFF_SectionFlag_MemRead|COFF_SectionFlag_MemWrite;
}
{
COFF_Reloc *lookup_table_voff_reloc = &import_entry_reloc_array[0];
lookup_table_voff_reloc->apply_off = OffsetOf(PE_ImportEntry, lookup_table_voff);
lookup_table_voff_reloc->isymbol = 3;
lookup_table_voff_reloc->type = COFF_RelocTypeX64_ADDR32NB;
lookup_table_voff_reloc->type = COFF_Reloc_X64_Addr32Nb;
COFF_Reloc *name_voff_reloc = &import_entry_reloc_array[1];
name_voff_reloc->apply_off = OffsetOf(PE_ImportEntry, name_voff);
name_voff_reloc->isymbol = 2;
name_voff_reloc->type = COFF_RelocTypeX64_ADDR32NB;
name_voff_reloc->type = COFF_Reloc_X64_Addr32Nb;
COFF_Reloc *import_addr_table_voff = &import_entry_reloc_array[2];
import_addr_table_voff->apply_off = OffsetOf(PE_ImportEntry, import_addr_table_voff);
import_addr_table_voff->isymbol = 4;
import_addr_table_voff->type = COFF_RelocTypeX64_ADDR32NB;
import_addr_table_voff->type = COFF_Reloc_X64_Addr32Nb;
}
// dll name
@@ -623,7 +623,7 @@ lnk_build_import_entry_obj(Arena *arena, String8 dll_name, COFF_MachineType mach
sect->name[7] = '6';
sect->fsize = dll_name_cstr.size;
sect->foff = dll_name_off;
sect->flags = COFF_SectionFlag_CNT_INITIALIZED_DATA|(COFF_SectionAlign_2BYTES << COFF_SectionFlag_ALIGN_SHIFT)|COFF_SectionFlag_MEM_READ|COFF_SectionFlag_MEM_WRITE;
sect->flags = COFF_SectionFlag_CntInitializedData|(COFF_SectionAlign_2Bytes << COFF_SectionFlag_AlignShift)|COFF_SectionFlag_MemRead|COFF_SectionFlag_MemWrite;
}
// import descriptor
@@ -638,7 +638,7 @@ lnk_build_import_entry_obj(Arena *arena, String8 dll_name, COFF_MachineType mach
symbol->name.long_name.zeroes = 0;
symbol->name.long_name.string_table_offset = symbol_name_off;
symbol->section_number = 1;
symbol->storage_class = COFF_SymStorageClass_EXTERNAL;
symbol->storage_class = COFF_SymStorageClass_External;
}
// .idata$2
@@ -653,7 +653,7 @@ lnk_build_import_entry_obj(Arena *arena, String8 dll_name, COFF_MachineType mach
symbol->name.short_name[6] = '$';
symbol->name.short_name[7] = '2';
symbol->section_number = 1;
symbol->storage_class = COFF_SymStorageClass_SECTION;
symbol->storage_class = COFF_SymStorageClass_Section;
}
// .idata$6
@@ -668,7 +668,7 @@ lnk_build_import_entry_obj(Arena *arena, String8 dll_name, COFF_MachineType mach
symbol->name.short_name[6] = '$';
symbol->name.short_name[7] = '6';
symbol->section_number = 2;
symbol->storage_class = COFF_SymStorageClass_STATIC;
symbol->storage_class = COFF_SymStorageClass_Static;
}
// .idata$4
@@ -682,8 +682,8 @@ lnk_build_import_entry_obj(Arena *arena, String8 dll_name, COFF_MachineType mach
symbol->name.short_name[5] = 'a';
symbol->name.short_name[6] = '$';
symbol->name.short_name[7] = '4';
symbol->section_number = COFF_SYMBOL_UNDEFINED_SECTION;
symbol->storage_class = COFF_SymStorageClass_SECTION;
symbol->section_number = COFF_Symbol_UndefinedSection;
symbol->storage_class = COFF_SymStorageClass_Section;
}
// .idata$5
@@ -697,8 +697,8 @@ lnk_build_import_entry_obj(Arena *arena, String8 dll_name, COFF_MachineType mach
symbol->name.short_name[5] = 'a';
symbol->name.short_name[6] = '$';
symbol->name.short_name[7] = '5';
symbol->section_number = COFF_SYMBOL_UNDEFINED_SECTION;
symbol->storage_class = COFF_SymStorageClass_SECTION;
symbol->section_number = COFF_Symbol_UndefinedSection;
symbol->storage_class = COFF_SymStorageClass_Section;
}
// __NULL_IMPORT_DESCRIPTOR
@@ -709,8 +709,8 @@ lnk_build_import_entry_obj(Arena *arena, String8 dll_name, COFF_MachineType mach
COFF_Symbol16 *symbol = &symbol_array[5];
symbol->name.long_name.zeroes = 0;
symbol->name.long_name.string_table_offset = symbol_name_off;
symbol->section_number = COFF_SYMBOL_UNDEFINED_SECTION;
symbol->storage_class = COFF_SymStorageClass_EXTERNAL;
symbol->section_number = COFF_Symbol_UndefinedSection;
symbol->storage_class = COFF_SymStorageClass_External;
}
// NULL_THUNK_DATA
@@ -724,8 +724,8 @@ lnk_build_import_entry_obj(Arena *arena, String8 dll_name, COFF_MachineType mach
COFF_Symbol16 *symbol = &symbol_array[6];
symbol->name.long_name.zeroes = 0;
symbol->name.long_name.string_table_offset = symbol_name_off;
symbol->section_number = COFF_SYMBOL_UNDEFINED_SECTION;
symbol->storage_class = COFF_SymStorageClass_EXTERNAL;
symbol->section_number = COFF_Symbol_UndefinedSection;
symbol->storage_class = COFF_SymStorageClass_External;
}
// update string table size
@@ -742,7 +742,7 @@ lnk_build_null_import_descriptor_obj(Arena *arena, COFF_MachineType machine)
String8List list = {0};
COFF_Header *coff_header = push_array(arena, COFF_Header, 1);
COFF_FileHeader *coff_header = push_array(arena, COFF_FileHeader, 1);
coff_header->machine = machine;
str8_list_push(arena, &list, str8_struct(coff_header));
@@ -776,7 +776,7 @@ lnk_build_null_import_descriptor_obj(Arena *arena, COFF_MachineType machine)
sect->name[7] = '3';
sect->fsize = null_import_data_size;
sect->foff = null_import_data_off;
sect->flags = COFF_SectionFlag_CNT_INITIALIZED_DATA|(COFF_SectionAlign_4BYTES << COFF_SectionFlag_ALIGN_SHIFT)|COFF_SectionFlag_MEM_READ|COFF_SectionFlag_MEM_WRITE;
sect->flags = COFF_SectionFlag_CntInitializedData|(COFF_SectionAlign_4Bytes << COFF_SectionFlag_AlignShift)|COFF_SectionFlag_MemRead|COFF_SectionFlag_MemWrite;
}
{
@@ -787,7 +787,7 @@ lnk_build_null_import_descriptor_obj(Arena *arena, COFF_MachineType machine)
symbol->name.long_name.zeroes = 0;
symbol->name.long_name.string_table_offset = symbol_name_off;
symbol->section_number = 1;
symbol->storage_class = COFF_SymStorageClass_EXTERNAL;
symbol->storage_class = COFF_SymStorageClass_External;
}
// update string table size
@@ -806,7 +806,7 @@ lnk_build_null_thunk_data_obj(Arena *arena, String8 dll_name, COFF_MachineType m
String8List list = {0};
COFF_Header *coff_header = push_array(arena, COFF_Header, 1);
COFF_FileHeader *coff_header = push_array(arena, COFF_FileHeader, 1);
coff_header->machine = machine;
str8_list_push(arena, &list, str8_struct(coff_header));
@@ -845,7 +845,7 @@ lnk_build_null_thunk_data_obj(Arena *arena, String8 dll_name, COFF_MachineType m
sect->name[7] = '5';
sect->fsize = lookup_entry_data_size;
sect->foff = lookup_entry_data_off;
sect->flags = COFF_SectionFlag_CNT_INITIALIZED_DATA|(COFF_SectionAlign_8BYTES << COFF_SectionFlag_ALIGN_SHIFT)|COFF_SectionFlag_MEM_READ|COFF_SectionFlag_MEM_WRITE;
sect->flags = COFF_SectionFlag_CntInitializedData | (COFF_SectionAlign_8Bytes << COFF_SectionFlag_AlignShift)|(COFF_SectionFlag_MemRead|COFF_SectionFlag_MemWrite);
}
{
@@ -860,7 +860,7 @@ lnk_build_null_thunk_data_obj(Arena *arena, String8 dll_name, COFF_MachineType m
sect->name[7] = '4';
sect->fsize = null_thunk_data_size;
sect->foff = null_thunk_data_off;
sect->flags = COFF_SectionFlag_CNT_INITIALIZED_DATA|(COFF_SectionAlign_8BYTES << COFF_SectionFlag_ALIGN_SHIFT)|COFF_SectionFlag_MEM_READ|COFF_SectionFlag_MEM_WRITE;
sect->flags = COFF_SectionFlag_CntInitializedData|(COFF_SectionAlign_8Bytes << COFF_SectionFlag_AlignShift)|COFF_SectionFlag_MemRead|COFF_SectionFlag_MemWrite;
}
{
@@ -874,7 +874,7 @@ lnk_build_null_thunk_data_obj(Arena *arena, String8 dll_name, COFF_MachineType m
symbol->name.long_name.zeroes = 0;
symbol->name.long_name.string_table_offset = symbol_name_off;
symbol->section_number = 1;
symbol->storage_class = COFF_SymStorageClass_EXTERNAL;
symbol->storage_class = COFF_SymStorageClass_External;
}
// update string table size
@@ -908,7 +908,7 @@ lnk_build_lib_member_header(Arena *arena, String8 name, COFF_TimeStamp time_stam
str8_list_pushf(scratch.arena, &list, "`\n");
String8 result = str8_list_join(arena, &list, 0);
Assert(result.size == COFF_ARCHIVE_MEMBER_HEADER_SIZE);
Assert(result.size == sizeof(COFF_ArchiveMemberHeader));
scratch_end(scratch);
ProfEnd();
return result;
+26 -27
View File
@@ -327,7 +327,7 @@ THREAD_POOL_TASK_FUNC(lnk_obj_initer)
String8 cached_lib_path = push_str8_copy(arena, input->lib_path);
// parse coff obj
COFF_HeaderInfo coff_info = coff_header_info_from_data(input->data);
COFF_FileHeaderInfo coff_info = coff_file_header_info_from_data(input->data);
Rng1U64 coff_file_header_range = rng_1u64(0, coff_info.header_size);
Rng1U64 coff_sect_arr_range = rng_1u64(coff_info.section_array_off, coff_info.section_array_off + coff_info.section_count_no_null * sizeof(COFF_SectionHeader));
Rng1U64 coff_symbols_range = rng_1u64(coff_info.symbol_off, coff_info.symbol_off + coff_info.symbol_count * coff_info.symbol_size);
@@ -368,13 +368,13 @@ THREAD_POOL_TASK_FUNC(lnk_obj_initer)
COFF_SectionHeader *coff_sect = &coff_sect_arr[sect_idx];
// read name
String8 sect_name = coff_name_from_section_header(coff_sect, input->data, coff_info.string_table_off);
String8 sect_name = coff_name_from_section_header(input->data, coff_sect, coff_info.string_table_off);
// parse section name
coff_parse_section_name(sect_name, &sect_name_arr[sect_idx], &sect_sort_arr[sect_idx]);
String8 data;
if (coff_sect->flags & COFF_SectionFlag_CNT_UNINITIALIZED_DATA) {
if (coff_sect->flags & COFF_SectionFlag_CntUninitializedData) {
data = str8(0, coff_sect->fsize);
} else {
if (coff_sect->fsize > 0) {
@@ -403,7 +403,7 @@ THREAD_POOL_TASK_FUNC(lnk_obj_initer)
LNK_Chunk *chunk = &chunk_arr[sect_idx];
chunk->align = coff_align_size_from_section_flags(coff_sect->flags);
chunk->is_discarded = !!(coff_sect->flags & COFF_SectionFlag_LNK_REMOVE);
chunk->is_discarded = !!(coff_sect->flags & COFF_SectionFlag_LnkRemove);
chunk->sort_chunk = 1;
chunk->type = LNK_Chunk_Leaf;
chunk->sort_idx = sect_sort_arr[sect_idx];
@@ -433,8 +433,7 @@ THREAD_POOL_TASK_FUNC(lnk_obj_initer)
}
// convert from coff
B32 is_big_obj = coff_info.type == COFF_DataType_BIG_OBJ;
LNK_SymbolArray symbol_arr = lnk_symbol_array_from_coff(arena, input->data, obj, cached_path, cached_lib_path, is_big_obj, function_pad_min, coff_info.string_table_off, coff_info.section_count_no_null, coff_sect_arr, coff_info.symbol_count, coff_symbols, chunk_ptr_arr, master_common_block);
LNK_SymbolArray symbol_arr = lnk_symbol_array_from_coff(arena, input->data, obj, cached_path, cached_lib_path, coff_info.is_big_obj, function_pad_min, coff_info.string_table_off, coff_info.section_count_no_null, coff_sect_arr, coff_info.symbol_count, coff_symbols, chunk_ptr_arr, master_common_block);
LNK_SymbolList symbol_list = lnk_symbol_list_from_array(arena, symbol_arr);
LNK_RelocList *reloc_list_arr = lnk_reloc_list_array_from_coff(arena, coff_info.machine, input->data, coff_info.section_count_no_null, coff_sect_arr, chunk_ptr_arr, symbol_arr);
LNK_DirectiveInfo directive_info = lnk_directive_info_from_sections(arena, cached_path, cached_lib_path, coff_info.section_count_no_null, reloc_list_arr, sect_name_arr, chunk_arr);
@@ -495,7 +494,7 @@ THREAD_POOL_TASK_FUNC(lnk_obj_new_sect_scanner)
for (U64 chunk_idx = 0; chunk_idx < obj->chunk_count; chunk_idx += 1) {
String8 sect_name = obj->sect_name_arr[chunk_idx];
COFF_SectionFlags sect_flags = obj->chunk_arr[chunk_idx]->flags & ~COFF_SectionFlags_LNK_FLAGS;
COFF_SectionFlags sect_flags = obj->chunk_arr[chunk_idx]->flags & ~COFF_SectionFlags_LnkFlags;
KeyValuePair *is_present = hash_table_search_string(ht, sect_name);
if (is_present) {
@@ -675,7 +674,7 @@ lnk_obj_list_push_parallel(TP_Context *tp,
// push new sections for :find_chunk_section
for (LNK_SectDefn *curr = new_list.first; curr != 0; curr = curr->next) {
lnk_section_table_push(st, curr->name, curr->flags & ~COFF_SectionFlags_LNK_FLAGS);
lnk_section_table_push(st, curr->name, curr->flags & ~COFF_SectionFlags_LnkFlags);
}
tp_temp_end(temp);
@@ -763,7 +762,7 @@ lnk_symbol_array_from_coff(Arena *arena,
// is this a function symbol?
COFF_SymbolValueInterpType interp = coff_interp_symbol(symbol.section_number, symbol.value, symbol.storage_class);
if (interp == COFF_SymbolValueInterp_REGULAR && COFF_SymbolType_IsFunc(symbol.type)) {
if (interp == COFF_SymbolValueInterp_Regular && COFF_SymbolType_IsFunc(symbol.type)) {
if (symbol.section_number == 0 || symbol.section_number > sect_count) {
lnk_error_with_loc(LNK_Error_IllData, obj_path, lib_path, "out ouf bounds section index in symbol \"%S (%u)\"", symbol.name, symbol.section_number);
}
@@ -879,7 +878,7 @@ lnk_symbol_array_from_coff(Arena *arena,
COFF_SymbolValueInterpType interp = coff_interp_symbol(parsed_symbol.section_number, parsed_symbol.value, parsed_symbol.storage_class);
switch (interp) {
case COFF_SymbolValueInterp_REGULAR: {
case COFF_SymbolValueInterp_Regular: {
if (parsed_symbol.section_number == 0 || parsed_symbol.section_number > sect_count) {
lnk_error_with_loc(LNK_Error_IllData, obj_path, lib_path, "symbol %S (No. %llx) has out ouf bounds section index %x", parsed_symbol.name, symbol_idx, parsed_symbol.section_number);
}
@@ -889,7 +888,7 @@ lnk_symbol_array_from_coff(Arena *arena,
LNK_DefinedSymbolVisibility visibility = LNK_DefinedSymbolVisibility_Static;
if (parsed_symbol.storage_class == COFF_SymStorageClass_EXTERNAL) {
if (parsed_symbol.storage_class == COFF_SymStorageClass_External) {
visibility = LNK_DefinedSymbolVisibility_Extern;
}
LNK_DefinedSymbolFlags flags = 0;
@@ -900,15 +899,15 @@ lnk_symbol_array_from_coff(Arena *arena,
LNK_Chunk *chunk = chunk_ptr_arr[parsed_symbol.section_number-1];
U64 offset = parsed_symbol.value;
COFF_ComdatSelectType selection = COFF_ComdatSelectType_ANY;
COFF_ComdatSelectType selection = COFF_ComdatSelect_Any;
U64 check_sum = 0;
B32 is_comdat = (coff_sect_arr[parsed_symbol.section_number-1].flags & COFF_SectionFlag_LNK_COMDAT) &&
B32 is_comdat = (coff_sect_arr[parsed_symbol.section_number-1].flags & COFF_SectionFlag_LnkCOMDAT) &&
parsed_symbol.value == 0 &&
parsed_symbol.aux_symbol_count > 0 &&
parsed_symbol.type.u.lsb == COFF_SymType_NULL &&
parsed_symbol.storage_class == COFF_SymStorageClass_STATIC;
parsed_symbol.type.u.lsb == COFF_SymType_Null &&
parsed_symbol.storage_class == COFF_SymStorageClass_Static;
if (is_comdat) {
COFF_SymbolSecDef *secdef = aux_symbols;
@@ -916,7 +915,7 @@ lnk_symbol_array_from_coff(Arena *arena,
check_sum = secdef->check_sum;
// create association link between chunks
if (secdef->selection == COFF_ComdatSelectType_ASSOCIATIVE) {
if (secdef->selection == COFF_ComdatSelect_Associative) {
U32 secdef_number = secdef->number_lo;
// promote secdef number to 32 bits
@@ -955,7 +954,7 @@ lnk_symbol_array_from_coff(Arena *arena,
lnk_init_defined_symbol_chunk(&symbol_array.v[symbol_idx], parsed_symbol.name, visibility, flags, chunk, offset, selection, check_sum);
symbol_array.v[symbol_idx].obj = obj;
} break;
case COFF_SymbolValueInterp_WEAK: {
case COFF_SymbolValueInterp_Weak: {
if (parsed_symbol.aux_symbol_count == 0) {
lnk_error_with_loc(LNK_Error_IllData, obj_path, lib_path, "weak symbol \"%S (%u)\" must at least one aux symbol", parsed_symbol.name, symbol_idx);
}
@@ -972,12 +971,12 @@ lnk_symbol_array_from_coff(Arena *arena,
symbol->obj = obj;
fallback_symbol->obj = obj;
} break;
case COFF_SymbolValueInterp_UNDEFINED: {
case COFF_SymbolValueInterp_Undefined: {
LNK_Symbol *symbol = &symbol_array.v[symbol_idx];
lnk_init_undefined_symbol(symbol, parsed_symbol.name, LNK_SymbolScopeFlag_Main);
symbol->obj = obj;
} break;
case COFF_SymbolValueInterp_COMMON: {
case COFF_SymbolValueInterp_Common: {
// :common_block
//
// TODO: sort chunks on size to reduce bss usage
@@ -995,16 +994,16 @@ lnk_symbol_array_from_coff(Arena *arena,
}
LNK_Symbol *symbol = &symbol_array.v[symbol_idx];
lnk_init_defined_symbol_chunk(symbol, parsed_symbol.name, LNK_DefinedSymbolVisibility_Extern, flags, chunk, 0, COFF_ComdatSelectType_LARGEST, 0);
lnk_init_defined_symbol_chunk(symbol, parsed_symbol.name, LNK_DefinedSymbolVisibility_Extern, flags, chunk, 0, COFF_ComdatSelect_Largest, 0);
symbol->obj = obj;
} break;
case COFF_SymbolValueInterp_ABS: {
case COFF_SymbolValueInterp_Abs: {
// Never code or data, synthetic symbol. COFF spec says bits in value are used
// as flags in symbol @feat.00, other symbols like @comp.id and @vol.md are undocumented.
// LLVM uses undocumented mask 0x4800 on @feat.00 to tell if object was compiled with /guard:cf.
LNK_DefinedSymbolVisibility visibility = LNK_DefinedSymbolVisibility_Static;
if (parsed_symbol.storage_class == COFF_SymStorageClass_EXTERNAL) {
if (parsed_symbol.storage_class == COFF_SymStorageClass_External) {
visibility = LNK_DefinedSymbolVisibility_Extern;
}
@@ -1012,7 +1011,7 @@ lnk_symbol_array_from_coff(Arena *arena,
lnk_init_defined_symbol_va(symbol, parsed_symbol.name, visibility, 0, parsed_symbol.value);
symbol->obj = obj;
} break;
case COFF_SymbolValueInterp_DEBUG: {
case COFF_SymbolValueInterp_Debug: {
} break;
}
}
@@ -1025,8 +1024,8 @@ lnk_reloc_list_array_from_coff(Arena *arena, COFF_MachineType machine, String8 c
{
LNK_RelocList *reloc_list_arr = push_array_no_zero(arena, LNK_RelocList, sect_count);
for (U64 sect_idx = 0; sect_idx < sect_count; ++sect_idx) {
COFF_SectionHeader *coff_header = &coff_sect_arr[sect_idx];
COFF_RelocInfo coff_reloc_info = coff_reloc_info_from_section_header(coff_data, coff_header);
COFF_SectionHeader *COFF_FileHeader = &coff_sect_arr[sect_idx];
COFF_RelocInfo coff_reloc_info = coff_reloc_info_from_section_header(coff_data, COFF_FileHeader);
COFF_Reloc *coff_reloc_v = (COFF_Reloc *)(coff_data.str + coff_reloc_info.array_off);
LNK_Chunk *sect_chunk = chunk_ptr_arr[sect_idx];
reloc_list_arr[sect_idx] = lnk_reloc_list_from_coff_reloc_array(arena, machine, sect_chunk, symbol_array, coff_reloc_v, coff_reloc_info.count);
@@ -1122,8 +1121,8 @@ lnk_directive_info_from_sections(Arena *arena,
if (str8_match_lit(".drectve", sect_name, 0)) {
if (sect_chunk->type == LNK_Chunk_Leaf) {
if (sect_chunk->u.leaf.size >= 3) {
if (~sect_chunk->flags & COFF_SectionFlag_LNK_INFO) {
lnk_error_with_loc(LNK_Warning_IllData, obj_path, lib_path, "%S missing COFF_SectionFlag_LNK_INFO", sect_name);
if (~sect_chunk->flags & COFF_SectionFlag_LnkInfo) {
lnk_error_with_loc(LNK_Warning_IllData, obj_path, lib_path, "%S missing COFF_SectionFlag_LnkInfo", sect_name);
}
if (reloc_list_arr[chunk_idx].count > 0) {
lnk_error_with_loc(LNK_Warning_DirectiveSectionWithRelocs, obj_path, lib_path, "directive section %S(%#x) has relocations", sect_name, (chunk_idx+1));
+32 -32
View File
@@ -117,26 +117,26 @@ lnk_ext_reloc_type_from_coff(COFF_MachineType machine, U32 type)
{
LNK_RelocType result = LNK_Reloc_NULL;
switch (machine) {
case COFF_MachineType_UNKNOWN: break;
case COFF_MachineType_X64: {
case COFF_Machine_Unknown: break;
case COFF_Machine_X64: {
switch (type) {
case COFF_RelocTypeX64_ABS: result = LNK_Reloc_NULL; break;
case COFF_RelocTypeX64_ADDR64: result = LNK_Reloc_ADDR_64; break;
case COFF_RelocTypeX64_ADDR32: result = LNK_Reloc_ADDR_32; break;
case COFF_RelocTypeX64_ADDR32NB: result = LNK_Reloc_VIRT_OFF_32; break;
case COFF_RelocTypeX64_REL32: result = LNK_Reloc_REL32; break;
case COFF_RelocTypeX64_REL32_1: result = LNK_Reloc_REL32_1; break;
case COFF_RelocTypeX64_REL32_2: result = LNK_Reloc_REL32_2; break;
case COFF_RelocTypeX64_REL32_3: result = LNK_Reloc_REL32_3; break;
case COFF_RelocTypeX64_REL32_4: result = LNK_Reloc_REL32_4; break;
case COFF_RelocTypeX64_REL32_5: result = LNK_Reloc_REL32_5; break;
case COFF_RelocTypeX64_SECTION: result = LNK_Reloc_SECT_IDX; break;
case COFF_RelocTypeX64_SECREL: result = LNK_Reloc_SECT_REL; break;
case COFF_RelocTypeX64_SECREL7: lnk_not_implemented("TODO: COFF_RelocTypeX64_SECREL7"); break;
case COFF_RelocTypeX64_TOKEN: lnk_not_implemented("TODO: COFF_RelocTypeX64_TOKEN"); break;
case COFF_RelocTypeX64_SREL32: lnk_not_implemented("TODO: COFF_RelocTypeX64_SREL32"); break;
case COFF_RelocTypeX64_PAIR: lnk_not_implemented("TODO: COFF_RelocTypeX64_PAIR"); break;
case COFF_RelocTypeX64_SSPAN32: lnk_not_implemented("TODO: COFF_RelocTypeX64_SSPAN32"); break;
case COFF_Reloc_X64_Abs: result = LNK_Reloc_NULL; break;
case COFF_Reloc_X64_Addr64: result = LNK_Reloc_ADDR_64; break;
case COFF_Reloc_X64_Addr32: result = LNK_Reloc_ADDR_32; break;
case COFF_Reloc_X64_Addr32Nb: result = LNK_Reloc_VIRT_OFF_32; break;
case COFF_Reloc_X64_Rel32: result = LNK_Reloc_REL32; break;
case COFF_Reloc_X64_Rel32_1: result = LNK_Reloc_REL32_1; break;
case COFF_Reloc_X64_Rel32_2: result = LNK_Reloc_REL32_2; break;
case COFF_Reloc_X64_Rel32_3: result = LNK_Reloc_REL32_3; break;
case COFF_Reloc_X64_Rel32_4: result = LNK_Reloc_REL32_4; break;
case COFF_Reloc_X64_Rel32_5: result = LNK_Reloc_REL32_5; break;
case COFF_Reloc_X64_Section: result = LNK_Reloc_SECT_IDX; break;
case COFF_Reloc_X64_SecRel: result = LNK_Reloc_SECT_REL; break;
case COFF_Reloc_X64_SecRel7: lnk_not_implemented("TODO: COFF_Reloc_X64_SecRel7"); break;
case COFF_Reloc_X64_Token: lnk_not_implemented("TODO: COFF_Reloc_X64_Token"); break;
case COFF_Reloc_X64_SRel32: lnk_not_implemented("TODO: COFF_Reloc_X64_SRel32"); break;
case COFF_Reloc_X64_Pair: lnk_not_implemented("TODO: COFF_Reloc_X64_Pair"); break;
case COFF_Reloc_X64_SSpan32: lnk_not_implemented("TODO: COFF_Reloc_X64_SSpan32"); break;
default: lnk_invalid_path("unknown relocation type 0x%X", type);
}
} break;
@@ -150,20 +150,20 @@ lnk_ext_reloc_type_to_coff(COFF_MachineType machine, LNK_RelocType type)
{
U32 result = 0;
switch (machine) {
case COFF_MachineType_X64: {
case COFF_Machine_X64: {
switch (type) {
case LNK_Reloc_NULL: result = COFF_RelocTypeX64_ABS; break;
case LNK_Reloc_ADDR_64: result = COFF_RelocTypeX64_ADDR64; break;
case LNK_Reloc_ADDR_32: result = COFF_RelocTypeX64_ADDR32; break;
case LNK_Reloc_VIRT_OFF_32: result = COFF_RelocTypeX64_ADDR32NB; break;
case LNK_Reloc_REL32: result = COFF_RelocTypeX64_REL32; break;
case LNK_Reloc_REL32_1: result = COFF_RelocTypeX64_REL32_1; break;
case LNK_Reloc_REL32_2: result = COFF_RelocTypeX64_REL32_2; break;
case LNK_Reloc_REL32_3: result = COFF_RelocTypeX64_REL32_3; break;
case LNK_Reloc_REL32_4: result = COFF_RelocTypeX64_REL32_4; break;
case LNK_Reloc_REL32_5: result = COFF_RelocTypeX64_REL32_5; break;
case LNK_Reloc_SECT_IDX: result = COFF_RelocTypeX64_SECTION; break;
case LNK_Reloc_SECT_REL: result = COFF_RelocTypeX64_SECREL; break;
case LNK_Reloc_NULL: result = COFF_Reloc_X64_Abs; break;
case LNK_Reloc_ADDR_64: result = COFF_Reloc_X64_Addr64; break;
case LNK_Reloc_ADDR_32: result = COFF_Reloc_X64_Addr32; break;
case LNK_Reloc_VIRT_OFF_32: result = COFF_Reloc_X64_Addr32Nb; break;
case LNK_Reloc_REL32: result = COFF_Reloc_X64_Rel32; break;
case LNK_Reloc_REL32_1: result = COFF_Reloc_X64_Rel32_1; break;
case LNK_Reloc_REL32_2: result = COFF_Reloc_X64_Rel32_2; break;
case LNK_Reloc_REL32_3: result = COFF_Reloc_X64_Rel32_3; break;
case LNK_Reloc_REL32_4: result = COFF_Reloc_X64_Rel32_4; break;
case LNK_Reloc_REL32_5: result = COFF_Reloc_X64_Rel32_5; break;
case LNK_Reloc_SECT_IDX: result = COFF_Reloc_X64_Section; break;
case LNK_Reloc_SECT_REL: result = COFF_Reloc_X64_SecRel; break;
default: InvalidPath;
}
} break;
+10 -10
View File
@@ -85,7 +85,7 @@ lnk_make_section_sort_index(Arena *arena, String8 name, COFF_SectionFlags flags,
// pack sections with run-time data closer
String8List sort_index_list = {0};
if (flags & COFF_SectionFlag_MEM_DISCARDABLE) {
if (flags & COFF_SectionFlag_MemDiscardable) {
str8_list_pushf(scratch.arena, &sort_index_list, "b");
} else {
str8_list_pushf(scratch.arena, &sort_index_list, "a");
@@ -102,14 +102,14 @@ lnk_make_section_sort_index(Arena *arena, String8 name, COFF_SectionFlags flags,
}
// sort sections based on the contents
if (flags & COFF_SectionFlag_CNT_CODE) {
if (flags & COFF_SectionFlag_CntCode) {
str8_list_pushf(scratch.arena, &sort_index_list, "a");
if (str8_match_lit(".text", name, 0)) {
str8_list_pushf(scratch.arena, &sort_index_list, "a");
} else {
str8_list_pushf(scratch.arena, &sort_index_list, "b");
}
} else if (flags & COFF_SectionFlag_CNT_INITIALIZED_DATA) {
} else if (flags & COFF_SectionFlag_CntInitializedData) {
str8_list_pushf(scratch.arena, &sort_index_list, "b");
if (str8_match_lit(".data", name, 0)) {
str8_list_pushf(scratch.arena, &sort_index_list, "a");
@@ -120,14 +120,14 @@ lnk_make_section_sort_index(Arena *arena, String8 name, COFF_SectionFlags flags,
} else {
str8_list_pushf(scratch.arena, &sort_index_list, "d");
}
} else if (flags & COFF_SectionFlag_CNT_UNINITIALIZED_DATA) {
} else if (flags & COFF_SectionFlag_CntUninitializedData) {
str8_list_pushf(scratch.arena, &sort_index_list, "c");
} else {
str8_list_pushf(scratch.arena, &sort_index_list, "d");
}
// sort sections based on read/write access so final section layout looks cleaner
if (flags & COFF_SectionFlag_MEM_READ && ~flags & COFF_SectionFlag_MEM_WRITE) {
if (flags & COFF_SectionFlag_MemRead && ~flags & COFF_SectionFlag_MemWrite) {
str8_list_pushf(scratch.arena, &sort_index_list, "a");
} else {
str8_list_pushf(scratch.arena, &sort_index_list, "b");
@@ -236,8 +236,8 @@ lnk_code_align_byte_from_machine(COFF_MachineType machine)
{
U8 align_byte = 0;
switch (machine) {
case COFF_MachineType_X64:
case COFF_MachineType_X86: {
case COFF_Machine_X64:
case COFF_Machine_X86: {
align_byte = 0xCC;
} break;
default: {
@@ -570,7 +570,7 @@ lnk_section_table_assign_file_offsets(LNK_SectionTable *st)
U64 cursor = 0;
for (LNK_SectionNode *sect_node = st->list.first; sect_node != NULL; sect_node = sect_node->next) {
LNK_Section *sect = &sect_node->data;
if (sect->flags & COFF_SectionFlag_CNT_UNINITIALIZED_DATA) {
if (sect->flags & COFF_SectionFlag_CntUninitializedData) {
continue;
}
if (!sect->has_layout) continue;
@@ -617,7 +617,7 @@ lnk_section_table_serialize(TP_Context *tp, Arena *arena, LNK_SectionTable *st,
for (LNK_SectionNode *sect_n = st->list.first; sect_n != 0; sect_n = sect_n->next) {
LNK_Section *sect = &sect_n->data;
if (sect->has_layout) {
if (sect->flags & COFF_SectionFlag_CNT_UNINITIALIZED_DATA) {
if (sect->flags & COFF_SectionFlag_CntUninitializedData) {
continue;
}
@@ -625,7 +625,7 @@ lnk_section_table_serialize(TP_Context *tp, Arena *arena, LNK_SectionTable *st,
String8 sect_data = str8_substr(image, rng_1u64(image_cursor, image_cursor + sect_size));
U8 fill_byte = 0;
if (sect->flags & COFF_SectionFlag_CNT_CODE) {
if (sect->flags & COFF_SectionFlag_CntCode) {
fill_byte = lnk_code_align_byte_from_machine(machine);
}
+12 -12
View File
@@ -271,17 +271,17 @@ lnk_can_replace_symbol(const LNK_Symbol *dst, const LNK_Symbol *src)
COFF_ComdatSelectType src_select = src_defn->u.selection;
// handle objs compiled with /GR- and /GR
if ((src_select == COFF_ComdatSelectType_ANY && dst_select == COFF_ComdatSelectType_LARGEST) ||
(src_select == COFF_ComdatSelectType_LARGEST && dst_select == COFF_ComdatSelectType_ANY)) {
dst_select = COFF_ComdatSelectType_LARGEST;
src_select = COFF_ComdatSelectType_LARGEST;
if ((src_select == COFF_ComdatSelect_Any && dst_select == COFF_ComdatSelect_Largest) ||
(src_select == COFF_ComdatSelect_Largest && dst_select == COFF_ComdatSelect_Any)) {
dst_select = COFF_ComdatSelect_Largest;
src_select = COFF_ComdatSelect_Largest;
}
if (src_select == dst_select) {
switch (src_select) {
default: InvalidPath;
case COFF_ComdatSelectType_NULL:
case COFF_ComdatSelectType_ANY: {
case COFF_ComdatSelect_Null:
case COFF_ComdatSelect_Any: {
LNK_Chunk *dst_chunk = dst_defn->u.chunk;
LNK_Chunk *src_chunk = src_defn->u.chunk;
U64 dst_chunk_size = lnk_chunk_get_size(dst_chunk);
@@ -293,10 +293,10 @@ lnk_can_replace_symbol(const LNK_Symbol *dst, const LNK_Symbol *src)
can_replace = src_chunk_size < dst_chunk_size;
}
} break;
case COFF_ComdatSelectType_NODUPLICATES: {
case COFF_ComdatSelect_NoDuplicates: {
lnk_error_obj(LNK_Error_MultiplyDefinedSymbol, src->obj, "multiply defined symbol %S in %S.", dst->name, dst->obj->path);
} break;
case COFF_ComdatSelectType_SAME_SIZE: {
case COFF_ComdatSelect_SameSize: {
LNK_Chunk *dst_chunk = dst_defn->u.chunk;
LNK_Chunk *src_chunk = src_defn->u.chunk;
U64 dst_chunk_size = lnk_chunk_get_size(dst_chunk);
@@ -306,13 +306,13 @@ lnk_can_replace_symbol(const LNK_Symbol *dst, const LNK_Symbol *src)
lnk_error_obj(LNK_Error_MultiplyDefinedSymbol, src->obj, "multiply defined symbol %S in %S.", dst->name, dst->obj->path);
}
} break;
case COFF_ComdatSelectType_EXACT_MATCH: {
case COFF_ComdatSelect_ExactMatch: {
B32 is_exact_match = (dst_defn->u.check_sum == src_defn->u.check_sum);
if (!is_exact_match) {
lnk_error_obj(LNK_Error_MultiplyDefinedSymbol, src->obj, "multiply defined symbol %S in %S.", dst->name, dst->obj->path);
}
} break;
case COFF_ComdatSelectType_LARGEST: {
case COFF_ComdatSelect_Largest: {
LNK_Chunk *dst_chunk = dst_defn->u.chunk;
LNK_Chunk *src_chunk = src_defn->u.chunk;
U64 dst_chunk_size = lnk_chunk_get_size(dst_chunk);
@@ -330,7 +330,7 @@ lnk_can_replace_symbol(const LNK_Symbol *dst, const LNK_Symbol *src)
can_replace = dst_chunk_size < src_chunk_size;
}
} break;
case COFF_ComdatSelectType_ASSOCIATIVE: {
case COFF_ComdatSelect_Associative: {
// ignore
} break;
}
@@ -630,7 +630,7 @@ lnk_symbol_table_push_weak(LNK_SymbolTable *symtab, String8 weak_name, COFF_Weak
weak_name = push_str8_copy(symtab->arena->v[0], weak_name);
strong_name = push_str8_copy(symtab->arena->v[0], strong_name);
LNK_Symbol *strong_symbol = lnk_make_undefined_symbol(symtab->arena->v[0], strong_name, LNK_SymbolScopeFlag_Main);
LNK_Symbol *weak_symbol = lnk_make_weak_symbol(symtab->arena->v[0], weak_name, COFF_WeakExtType_SEARCH_ALIAS, strong_symbol);
LNK_Symbol *weak_symbol = lnk_make_weak_symbol(symtab->arena->v[0], weak_name, COFF_WeakExt_SearchAlias, strong_symbol);
lnk_symbol_table_push(symtab, weak_symbol);
return weak_symbol;
}
+7 -7
View File
@@ -3270,21 +3270,21 @@ dbi_build_sec_map(Arena *arena, PDB_DbiContext *dbi)
U64 isect = 0;
for (PDB_DbiSectionNode *sect = dbi->section_list.first; sect; sect = sect->next, ++isect) {
PDB_DbiSecMapEntry *s = &entry_array[isect];
COFF_SectionHeader *coff_header = &sect->data;
if (coff_header->flags & COFF_SectionFlag_MEM_READ) {
COFF_SectionHeader *section_header = &sect->data;
if (section_header->flags & COFF_SectionFlag_MemRead) {
s->flags |= PDB_DbiOMF_READ;
}
if (coff_header->flags & COFF_SectionFlag_MEM_WRITE) {
if (section_header->flags & COFF_SectionFlag_MemWrite) {
s->flags |= PDB_DbiOMF_WRITE;
}
if (coff_header->flags & COFF_SectionFlag_MEM_EXECUTE) {
if (section_header->flags & COFF_SectionFlag_MemExecute) {
s->flags |= PDB_DbiOMF_EXEC;
}
if (~coff_header->flags & COFF_SectionFlag_MEM_16BIT) {
if (~section_header->flags & COFF_SectionFlag_Mem16Bit) {
s->flags |= PDB_DbiOMF_IS_32BIT_ADDR;
}
s->flags |= PDB_DbiOMF_IS_SELECTOR; // always set
s->sec_size = coff_header->vsize;
s->sec_size = section_header->vsize;
s->frame = isect + 1;
s->sec_name = max_U16;
s->class_name = max_U16;
@@ -3444,7 +3444,7 @@ dbi_module_push_section_contrib(PDB_DbiContext *dbi,
// Mod1::fUpdateSecContrib
if (mod->first_sc.base.mod == 0) {
if (flags & COFF_SectionFlag_CNT_CODE) {
if (flags & COFF_SectionFlag_CntCode) {
mod->first_sc = sc;
}
}
+27 -27
View File
@@ -5,31 +5,31 @@ internal RDI_Arch
rdi_arch_from_coff_machine(COFF_MachineType machine)
{
switch (machine) {
case COFF_MachineType_X86: return RDI_Arch_X86;
case COFF_MachineType_X64: return RDI_Arch_X64;
case COFF_Machine_X86: return RDI_Arch_X86;
case COFF_Machine_X64: return RDI_Arch_X64;
case COFF_MachineType_UNKNOWN:
case COFF_MachineType_AM33:
case COFF_MachineType_ARM:
case COFF_MachineType_ARM64:
case COFF_MachineType_ARMNT:
case COFF_MachineType_EBC:
case COFF_MachineType_IA64:
case COFF_MachineType_M32R:
case COFF_MachineType_MIPS16:
case COFF_MachineType_MIPSFPU:
case COFF_MachineType_MIPSFPU16:
case COFF_MachineType_POWERPC:
case COFF_MachineType_POWERPCFP:
case COFF_MachineType_R4000:
case COFF_MachineType_RISCV32:
case COFF_MachineType_RISCV64:
case COFF_MachineType_SH3:
case COFF_MachineType_SH3DSP:
case COFF_MachineType_SH4:
case COFF_MachineType_SH5:
case COFF_MachineType_THUMB:
case COFF_MachineType_WCEMIPSV2:
case COFF_Machine_Unknown:
case COFF_Machine_Am33:
case COFF_Machine_Arm:
case COFF_Machine_Arm64:
case COFF_Machine_ArmNt:
case COFF_Machine_Ebc:
case COFF_Machine_Ia64:
case COFF_Machine_M32R:
case COFF_Machine_Mips16:
case COFF_Machine_MipsFpu:
case COFF_Machine_MipsFpu16:
case COFF_Machine_PowerPc:
case COFF_Machine_PowerPcFp:
case COFF_Machine_R4000:
case COFF_Machine_RiscV32:
case COFF_Machine_RiscV64:
case COFF_Machine_Sh3:
case COFF_Machine_Sh3Dsp:
case COFF_Machine_Sh4:
case COFF_Machine_Sh5:
case COFF_Machine_Thumb:
case COFF_Machine_WceMipsV2:
NotImplemented;
default:
return RDI_Arch_NULL;
@@ -40,13 +40,13 @@ internal RDI_BinarySectionFlags
rdi_binary_section_flags_from_coff_section_flags(COFF_SectionFlags flags)
{
RDI_BinarySectionFlags result = 0;
if (flags & COFF_SectionFlag_MEM_READ) {
if (flags & COFF_SectionFlag_MemRead) {
result |= RDI_BinarySectionFlag_Read;
}
if (flags & COFF_SectionFlag_MEM_WRITE) {
if (flags & COFF_SectionFlag_MemWrite) {
result |= RDI_BinarySectionFlag_Write;
}
if (flags & COFF_SectionFlag_MEM_EXECUTE) {
if (flags & COFF_SectionFlag_MemExecute) {
result |= RDI_BinarySectionFlag_Execute;
}
return result;
+40 -40
View File
@@ -438,34 +438,34 @@ pe_bin_info_from_data(Arena *arena, String8 data)
}
// rjf: read coff header
U32 coff_header_off = dos_header.coff_file_offset + sizeof(pe_magic);
COFF_Header coff_header = {0};
U32 file_header_off = dos_header.coff_file_offset + sizeof(pe_magic);
COFF_FileHeader file_header = {0};
if(valid)
{
str8_deserial_read_struct(data, coff_header_off, &coff_header);
str8_deserial_read_struct(data, file_header_off, &file_header);
}
// rjf: range of optional extension header ("optional" for short)
U32 optional_size = coff_header.optional_header_size;
U64 after_coff_header_off = coff_header_off + sizeof(coff_header);
U64 after_optional_header_off = after_coff_header_off + optional_size;
U32 optional_size = file_header.optional_header_size;
U64 after_file_header_off = file_header_off + sizeof(COFF_FileHeader);
U64 after_optional_header_off = after_file_header_off + optional_size;
Rng1U64 optional_range = {0};
if(valid)
{
optional_range.min = ClampTop(after_coff_header_off, data.size);
optional_range.min = ClampTop(after_file_header_off, data.size);
optional_range.max = ClampTop(after_optional_header_off, data.size);
}
// rjf: get sections
U64 sec_array_off = optional_range.max;
U64 sec_array_raw_opl = sec_array_off + coff_header.section_count*sizeof(COFF_SectionHeader);
U64 sec_array_raw_opl = sec_array_off + file_header.section_count*sizeof(COFF_SectionHeader);
U64 sec_array_opl = ClampTop(sec_array_raw_opl, data.size);
U64 clamped_sec_count = (sec_array_opl - sec_array_off)/sizeof(COFF_SectionHeader);
COFF_SectionHeader *sections = (COFF_SectionHeader*)(data.str + sec_array_off);
// rjf: get symbols
U64 symbol_array_off = coff_header.symbol_table_foff;
U64 symbol_count = coff_header.symbol_count;
U64 symbol_array_off = file_header.symbol_table_foff;
U64 symbol_count = file_header.symbol_count;
// rjf: get string table
U64 string_table_off = symbol_array_off + sizeof(COFF_Symbol16) * symbol_count;
@@ -551,11 +551,11 @@ pe_bin_info_from_data(Arena *arena, String8 data)
if(valid && PE_DataDirectoryIndex_TLS < data_dir_count)
{
Rng1U64 tls_header_frng = data_dir_franges[PE_DataDirectoryIndex_TLS];
switch(coff_header.machine)
switch(file_header.machine)
{
default:{ NotImplemented; }break;
case COFF_MachineType_UNKNOWN: break;
case COFF_MachineType_X86:
case COFF_Machine_Unknown: break;
case COFF_Machine_X86:
{
PE_TLSHeader32 tls_header32 = {0};
if(str8_deserial_read_struct(data, tls_header_frng.min, &tls_header32) == sizeof(tls_header32))
@@ -572,7 +572,7 @@ pe_bin_info_from_data(Arena *arena, String8 data)
Assert(!"unable to read TLS Header 32");
}
}break;
case COFF_MachineType_X64:
case COFF_Machine_X64:
{
if(str8_deserial_read_struct(data, tls_header_frng.min, &tls_header) != sizeof(tls_header))
{
@@ -598,7 +598,7 @@ pe_bin_info_from_data(Arena *arena, String8 data)
info.string_table_off = string_table_off;
info.data_dir_franges = data_dir_franges;
info.data_dir_count = data_dir_count;
info.arch = arch_from_coff_machine(coff_header.machine);
info.arch = arch_from_coff_machine(file_header.machine);
info.tls_header = tls_header;
}
@@ -824,7 +824,7 @@ pe_foff_from_voff(String8 data, PE_BinInfo *bin, U64 voff)
COFF_SectionHeader *sect = &sections[sect_idx];
if(sect->voff <= voff && voff < sect->voff + sect->vsize)
{
if(!(sect->flags & COFF_SectionFlag_CNT_UNINITIALIZED_DATA))
if(!(sect->flags & COFF_SectionFlag_CntUninitializedData))
{
foff = sect->foff + (voff - sect->voff);
}
@@ -967,7 +967,7 @@ pe_get_entry_point_names(COFF_MachineType machine,
String8Array entry_point_names = {0};
if (file_characteristics & PE_ImageFileCharacteristic_FILE_DLL) {
if (machine == COFF_MachineType_X86) {
if (machine == COFF_Machine_X86) {
read_only static String8 dll_entry_point_arr[] = {
str8_lit_comp("__DllMainCRTStartup@12"),
};
@@ -1418,8 +1418,8 @@ pe_tls_from_data(Arena *arena,
U64 *callback_addrs = 0;
switch (machine) {
case COFF_MachineType_UNKNOWN: break;
case COFF_MachineType_X86: {
case COFF_Machine_Unknown: break;
case COFF_Machine_X86: {
PE_TLSHeader32 header32 = {0};
str8_deserial_read_struct(raw_tls, 0, &header32);
@@ -1444,7 +1444,7 @@ pe_tls_from_data(Arena *arena,
callback_addrs[i] = (U64)src[i];
}
} break;
case COFF_MachineType_X64: {
case COFF_Machine_X64: {
str8_deserial_read_struct(raw_tls, 0, &header64);
U64 callbacks_voff = header64.callbacks_address - image_base;
@@ -1487,9 +1487,9 @@ pe_resource_dir_push_dir_node(Arena *arena, PE_ResourceDir *dir, COFF_ResourceID
PE_ResourceList *list = 0;
switch (id.type) {
default:
case COFF_ResourceIDType_NULL: break;
case COFF_ResourceIDType_STRING: list = &dir->named_list; break;
case COFF_ResourceIDType_NUMBER: list = &dir->id_list; break;
case COFF_ResourceIDType_Null: break;
case COFF_ResourceIDType_String: list = &dir->named_list; break;
case COFF_ResourceIDType_Number: list = &dir->id_list; break;
}
PE_ResourceNode *res_node = push_array(arena, PE_ResourceNode, 1);
@@ -1516,9 +1516,9 @@ pe_resource_dir_push_entry_node(Arena *arena, PE_ResourceDir *dir, COFF_Resource
PE_ResourceList *list = NULL;
switch (id.type) {
default:
case COFF_ResourceIDType_NULL: break;
case COFF_ResourceIDType_STRING: list = &dir->named_list; break;
case COFF_ResourceIDType_NUMBER: list = &dir->id_list; break;
case COFF_ResourceIDType_Null: break;
case COFF_ResourceIDType_String: list = &dir->named_list; break;
case COFF_ResourceIDType_Number: list = &dir->id_list; break;
}
PE_ResourceNode *res_node = push_array(arena, PE_ResourceNode, 1);
@@ -1555,7 +1555,7 @@ internal PE_ResourceNode *
pe_resource_dir_search_node(PE_ResourceDir *dir, COFF_ResourceID id)
{
for (PE_ResourceNode *i = dir->id_list.first; i != NULL; i = i->next) {
if (coff_resource_id_is_equal(i->data.id, id)) {
if (coff_resource_id_compar(&i->data.id, &id)) {
return i;
}
}
@@ -1586,11 +1586,11 @@ pe_resource_dir_push_res_file(Arena *arena, PE_ResourceDir *root_dir, String8 re
{
// parse file into resource list
String8 res_data = str8_substr(res_file, rng_1u64(sizeof(PE_RES_MAGIC), res_file.size));
COFF_ResourceList list = coff_resource_list_from_data(arena, res_data);
COFF_ParsedResourceList list = coff_resource_list_from_data(arena, res_data);
// move resources to directories based on type
for (COFF_ResourceNode *res_node = list.first; res_node != NULL; res_node = res_node->next) {
COFF_Resource *res = &res_node->data;
for (COFF_ParsedResourceNode *res_node = list.first; res_node != NULL; res_node = res_node->next) {
COFF_ParsedResource *res = &res_node->data;
// search existing directories
PE_Resource *dir_res = pe_resource_dir_search(root_dir, res->type);
@@ -1612,7 +1612,7 @@ pe_resource_dir_push_res_file(Arena *arena, PE_ResourceDir *root_dir, String8 re
// push entry
PE_Resource *sub_dir_res = pe_resource_dir_push_dir(arena, dir, res->name, 0, 0, 0, 0);
COFF_ResourceID id;
id.type = COFF_ResourceIDType_NUMBER;
id.type = COFF_ResourceIDType_Number;
id.u.number = res->language_id;
pe_resource_dir_push_entry(arena, sub_dir_res->u.dir, id, res->type, res->data_version, res->version, res->memory_flags, res->data);
}
@@ -1673,7 +1673,7 @@ pe_resource_table_from_directory_data(Arena *arena, String8 data)
str8_deserial_read_struct(data, entry_offset, &coff_entry);
// NOTE: this is not documented on MSDN but high bit here is set for some reason
U32 name_offset = coff_entry.name.offset & ~COFF_RESOURCE_SUB_DIR_FLAG;
U32 name_offset = coff_entry.name.offset & ~COFF_Resource_SubDirFlag;
U16 name_size = 0;
str8_deserial_read_struct(data, name_offset, &name_size);
@@ -1681,15 +1681,15 @@ pe_resource_table_from_directory_data(Arena *arena, String8 data)
str8_deserial_read_block(data, name_offset + sizeof(name_size), name_size*sizeof(U16), &name_block);
String16 name16 = str16((U16*)name_block.str, name_size);
B32 is_dir = !!(coff_entry.id.data_entry_offset & COFF_RESOURCE_SUB_DIR_FLAG);
B32 is_dir = !!(coff_entry.id.data_entry_offset & COFF_Resource_SubDirFlag);
entry->id.type = COFF_ResourceIDType_STRING;
entry->id.type = COFF_ResourceIDType_String;
entry->id.u.string = str8_from_16(arena, name16);
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);
frame->table_offset = coff_entry.id.sub_dir_offset & ~COFF_RESOURCE_SUB_DIR_FLAG;
frame->table_offset = coff_entry.id.sub_dir_offset & ~COFF_Resource_SubDirFlag;
frame->directory_ptr = &entry->u.dir;
SLLStackPush(stack, frame);
goto yeild;
@@ -1710,15 +1710,15 @@ pe_resource_table_from_directory_data(Arena *arena, String8 data)
COFF_ResourceDirEntry coff_entry = {0};
str8_deserial_read_struct(data, entry_offset, &coff_entry);
B32 is_dir = !!(coff_entry.id.sub_dir_offset & COFF_RESOURCE_SUB_DIR_FLAG);
B32 is_dir = !!(coff_entry.id.sub_dir_offset & COFF_Resource_SubDirFlag);
entry->id.type = COFF_ResourceIDType_NUMBER;
entry->id.type = COFF_ResourceIDType_Number;
entry->id.u.number = coff_entry.name.id;
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);
frame->table_offset = coff_entry.id.sub_dir_offset & ~COFF_RESOURCE_SUB_DIR_FLAG;
frame->table_offset = coff_entry.id.sub_dir_offset & ~COFF_Resource_SubDirFlag;
frame->directory_ptr = &entry->u.dir;
SLLStackPush(stack, frame);
goto yeild;
@@ -1740,11 +1740,11 @@ internal String8
pe_make_manifest_resource(Arena *arena, U32 resource_id, String8 manifest_data)
{
COFF_ResourceID type = {0};
type.type = COFF_ResourceIDType_NUMBER;
type.type = COFF_ResourceIDType_Number;
type.u.number = PE_ResourceKind_MANIFEST;
COFF_ResourceID id = {0};
id.type = COFF_ResourceIDType_NUMBER;
id.type = COFF_ResourceIDType_Number;
id.u.number = resource_id;
String8 res = coff_write_resource(arena, type, id, 1, 0, 1033, 0, 0, manifest_data);
+2
View File
@@ -340,6 +340,7 @@
#include "mutable_text/mutable_text.h"
#include "path/path.h"
#include "coff/coff.h"
#include "coff/coff_parse.h"
#include "pe/pe.h"
#include "codeview/codeview.h"
#include "codeview/codeview_parse.h"
@@ -381,6 +382,7 @@
#include "mutable_text/mutable_text.c"
#include "path/path.c"
#include "coff/coff.c"
#include "coff/coff_parse.c"
#include "pe/pe.c"
#include "codeview/codeview.c"
#include "codeview/codeview_parse.c"
+123 -125
View File
@@ -228,7 +228,7 @@ rd_format_preamble(Arena *arena, String8List *out, String8 indent, String8 input
Temp scratch = scratch_begin(&arena, 1);
char *input_type_string = "???";
if (coff_is_archive(raw_data)) {
if (coff_is_regular_archive(raw_data)) {
input_type_string = "Archive";
} else if (coff_is_thin_archive(raw_data)) {
input_type_string = "Thin Archive";
@@ -360,9 +360,9 @@ rd_section_markers_from_coff_symbol_table(Arena *arena, String8 raw_data, U64 st
COFF_Symbol32 *symbol = &symbols.v[symbol_idx];
COFF_SymbolValueInterpType interp = coff_interp_symbol(symbol->section_number, symbol->value, symbol->storage_class);
B32 is_marker = interp == COFF_SymbolValueInterp_REGULAR &&
B32 is_marker = interp == COFF_SymbolValueInterp_Regular &&
symbol->aux_symbol_count == 0 &&
(symbol->storage_class == COFF_SymStorageClass_EXTERNAL || symbol->storage_class == COFF_SymStorageClass_STATIC);
(symbol->storage_class == COFF_SymStorageClass_External || symbol->storage_class == COFF_SymStorageClass_Static);
if (is_marker) {
String8 name = coff_read_symbol_name(raw_data, string_table_off, &symbol->name);
@@ -411,7 +411,7 @@ rd_dw_sections_from_coff_section_table(Arena *arena,
for (U64 i = 0; i < section_count; ++i) {
COFF_SectionHeader *header = &sections[i];
Rng1U64 raw_data_range = rng_1u64(header->foff, header->foff + header->fsize);
String8 name = coff_name_from_section_header(header, raw_image, string_table_off);
String8 name = coff_name_from_section_header(raw_image, header, string_table_off);
DW_SectionKind s = DW_Section_Null;
B32 is_dwo = 0;
@@ -4496,7 +4496,7 @@ cv_format_debug_sections(Arena *arena, String8List *out, String8 indent, String8
B32 keep_parsing = 1;
for (U64 i = 0; i < section_count && keep_parsing; ++i) {
COFF_SectionHeader *header = &sections[i];
String8 sect_name = coff_name_from_section_header(header, raw_image, string_table_off);
String8 sect_name = coff_name_from_section_header(raw_image, header, string_table_off);
Rng1U64 sect_frange = rng_1u64(header->foff, header->foff+header->fsize);
String8 raw_sect = str8_substr(raw_image, sect_frange);
if (str8_match_lit(".debug$S", sect_name, 0)) {
@@ -4544,7 +4544,7 @@ cv_format_debug_sections(Arena *arena, String8List *out, String8 indent, String8
for (U64 i = 0; i < section_count; ++i) {
COFF_SectionHeader *header = &sections[i];
String8 sect_name = coff_name_from_section_header(header, raw_image, string_table_off);
String8 sect_name = coff_name_from_section_header(raw_image, header, string_table_off);
Rng1U64 sect_frange = rng_1u64(header->foff, header->foff+header->fsize);
String8 raw_sect = str8_substr(raw_image, sect_frange);
if (str8_match_lit(".debug$S", sect_name, 0)) {
@@ -4577,7 +4577,7 @@ cv_format_debug_sections(Arena *arena, String8List *out, String8 indent, String8
// COFF
internal void
coff_print_archive_member_header(Arena *arena, String8List *out, String8 indent, COFF_ArchiveMemberHeader header, String8 long_names)
coff_print_archive_member_header(Arena *arena, String8List *out, String8 indent, COFF_ParsedArchiveMemberHeader header, String8 long_names)
{
Temp scratch = scratch_begin(&arena, 1);
String8 time_stamp = coff_string_from_time_stamp(scratch.arena, header.time_stamp);
@@ -4608,12 +4608,12 @@ coff_print_seciton_table(Arena *arena,
for (U64 i = 0; i < symbols.count; ++i) {
COFF_Symbol32 *symbol = symbols.v+i;
COFF_SymbolValueInterpType interp = coff_interp_symbol(symbol->section_number, symbol->value, symbol->storage_class);
if (interp == COFF_SymbolValueInterp_REGULAR &&
if (interp == COFF_SymbolValueInterp_Regular &&
symbol->aux_symbol_count == 0 &&
(symbol->storage_class == COFF_SymStorageClass_EXTERNAL || symbol->storage_class == COFF_SymStorageClass_STATIC)) {
(symbol->storage_class == COFF_SymStorageClass_External || symbol->storage_class == COFF_SymStorageClass_Static)) {
if (symbol->section_number > 0 && symbol->section_number <= symbols.count) {
COFF_SectionHeader *header = sect_headers+(symbol->section_number-1);
if (header->flags & COFF_SectionFlag_LNK_COMDAT) {
if (header->flags & COFF_SectionFlag_LnkCOMDAT) {
symlinks[symbol->section_number-1] = coff_read_symbol_name(raw_data, string_table_off, &symbol->name);
}
}
@@ -4644,7 +4644,7 @@ coff_print_seciton_table(Arena *arena,
COFF_SectionHeader *header = sect_headers+i;
String8 name = str8_cstring_capped(header->name, header->name+sizeof(header->name));
String8 full_name = coff_name_from_section_header(header, raw_data, string_table_off);
String8 full_name = coff_name_from_section_header(raw_data, header, string_table_off);
String8 align;
{
@@ -4655,69 +4655,69 @@ coff_print_seciton_table(Arena *arena,
String8 flags;
{
String8List mem_flags = {0};
if (header->flags & COFF_SectionFlag_MEM_READ) {
if (header->flags & COFF_SectionFlag_MemRead) {
str8_list_pushf(scratch.arena, &mem_flags, "r");
}
if (header->flags & COFF_SectionFlag_MEM_WRITE) {
if (header->flags & COFF_SectionFlag_MemWrite) {
str8_list_pushf(scratch.arena, &mem_flags, "w");
}
if (header->flags & COFF_SectionFlag_MEM_EXECUTE) {
if (header->flags & COFF_SectionFlag_MemExecute) {
str8_list_pushf(scratch.arena, &mem_flags, "x");
}
String8List cnt_flags = {0};
if (header->flags & COFF_SectionFlag_CNT_CODE) {
if (header->flags & COFF_SectionFlag_CntCode) {
str8_list_pushf(scratch.arena, &cnt_flags, "c");
}
if (header->flags & COFF_SectionFlag_CNT_INITIALIZED_DATA) {
if (header->flags & COFF_SectionFlag_CntInitializedData) {
str8_list_pushf(scratch.arena, &cnt_flags, "d");
}
if (header->flags & COFF_SectionFlag_CNT_UNINITIALIZED_DATA) {
if (header->flags & COFF_SectionFlag_CntUninitializedData) {
str8_list_pushf(scratch.arena, &cnt_flags, "u");
}
String8List mem_extra_flags = {0};
if (header->flags & COFF_SectionFlag_MEM_SHARED) {
if (header->flags & COFF_SectionFlag_MemShared) {
str8_list_pushf(scratch.arena, &mem_flags, "s");
}
if (header->flags & COFF_SectionFlag_MEM_16BIT) {
if (header->flags & COFF_SectionFlag_Mem16Bit) {
str8_list_pushf(scratch.arena, &mem_extra_flags, "h");
}
if (header->flags & COFF_SectionFlag_MEM_LOCKED) {
if (header->flags & COFF_SectionFlag_MemLocked) {
str8_list_pushf(scratch.arena, &mem_extra_flags, "l");
}
if (header->flags & COFF_SectionFlag_MEM_DISCARDABLE) {
if (header->flags & COFF_SectionFlag_MemDiscardable) {
str8_list_pushf(scratch.arena, &mem_extra_flags, "d");
}
if (header->flags & COFF_SectionFlag_MEM_NOT_CACHED) {
if (header->flags & COFF_SectionFlag_MemNotCached) {
str8_list_pushf(scratch.arena, &mem_extra_flags, "c");
}
if (header->flags & COFF_SectionFlag_MEM_NOT_PAGED) {
if (header->flags & COFF_SectionFlag_MemNotPaged) {
str8_list_pushf(scratch.arena, &mem_extra_flags, "p");
}
String8List lnk_flags = {0};
if (header->flags & COFF_SectionFlag_LNK_REMOVE) {
if (header->flags & COFF_SectionFlag_LnkRemove) {
str8_list_pushf(scratch.arena, &lnk_flags, "r");
}
if (header->flags & COFF_SectionFlag_LNK_COMDAT) {
if (header->flags & COFF_SectionFlag_LnkCOMDAT) {
str8_list_pushf(scratch.arena, &lnk_flags, "c");
}
if (header->flags & COFF_SectionFlag_LNK_OTHER) {
if (header->flags & COFF_SectionFlag_LnkOther) {
str8_list_pushf(scratch.arena, &lnk_flags, "o");
}
if (header->flags & COFF_SectionFlag_LNK_INFO) {
if (header->flags & COFF_SectionFlag_LnkInfo) {
str8_list_pushf(scratch.arena, &lnk_flags, "i");
}
if (header->flags & COFF_SectionFlag_LNK_NRELOC_OVFL) {
if (header->flags & COFF_SectionFlag_LnkNRelocOvfl) {
str8_list_pushf(scratch.arena, &lnk_flags, "f");
}
String8List other_flags = {0};
if (header->flags & COFF_SectionFlag_TYPE_NO_PAD) {
if (header->flags & COFF_SectionFlag_TypeNoPad) {
str8_list_pushf(scratch.arena, &other_flags, "n");
}
if (header->flags & COFF_SectionFlag_GPREL) {
if (header->flags & COFF_SectionFlag_GpRel) {
str8_list_pushf(scratch.arena, &other_flags, "g");
}
@@ -4773,11 +4773,11 @@ coff_print_seciton_table(Arena *arena,
rd_newline();
rd_printf("Flags:");
rd_indent();
rd_printf("r = MEM_READ w = MEM_WRITE x = MEM_EXECUTE");
rd_printf("c = CNT_CODE d = INITIALIZED_DATA u = UNINITIALIZED_DATA");
rd_printf("s = MEM_SHARED h = MEM_16BIT l = MEM_LOCKED d = MEM_DISCARDABLE c = MEM_NOT_CACHED p = MEM_NOT_PAGED");
rd_printf("r = LNK_REMOVE c = LNK_COMDAT o = LNK_OTHER i = LNK_INFO f = LNK_NRELOC_OVFL");
rd_printf("g = GPREL n = TYPE_NO_PAD");
rd_printf("r = MemRead w = MemWrite x = MemExecute");
rd_printf("c = CntCode d = InitializedData u = UninitializedData");
rd_printf("s = MemShared h = Mem16bit l = MemLocked d = MemDiscardable c = MemNotCached p = MemNotPaged");
rd_printf("r = LnkRemove c = LnkComdat o = LnkOther i = LnkInfo f = LnkNRelocOvfl");
rd_printf("g = GpRel n = TypeNoPad");
rd_unindent();
rd_unindent();
@@ -4802,7 +4802,7 @@ coff_disasm_sections(Arena *arena,
if (section_count) {
for (U64 sect_idx = 0; sect_idx < section_count; ++sect_idx) {
COFF_SectionHeader *sect = sections+sect_idx;
if (sect->flags & COFF_SectionFlag_CNT_CODE) {
if (sect->flags & COFF_SectionFlag_CntCode) {
U64 sect_off = is_obj ? sect->foff : sect->voff;
U64 sect_size = is_obj ? sect->fsize : sect->vsize;
String8 raw_code = str8_substr(raw_data, rng_1u64(sect->foff, sect->foff+sect_size));
@@ -4950,10 +4950,10 @@ coff_print_symbol_table(Arena *arena,
String8 storage_class = coff_string_from_sym_storage_class(symbol->storage_class);
String8 section_number;
switch (symbol->section_number) {
case COFF_SYMBOL_UNDEFINED_SECTION: section_number = str8_lit("UNDEF"); break;
case COFF_SYMBOL_ABS_SECTION: section_number = str8_lit("ABS"); break;
case COFF_SYMBOL_DEBUG_SECTION: section_number = str8_lit("DEBUG"); break;
default: section_number = push_str8f(scratch.arena, "%010x", symbol->section_number); break;
case COFF_Symbol_UndefinedSection: section_number = str8_lit("UNDEF"); break;
case COFF_Symbol_AbsSection32: section_number = str8_lit("ABS"); break;
case COFF_Symbol_DebugSection32: section_number = str8_lit("DEBUG"); break;
default: section_number = push_str8f(scratch.arena, "%010x", symbol->section_number); break;
}
String8List line = {0};
@@ -4973,28 +4973,28 @@ coff_print_symbol_table(Arena *arena,
for (U64 k=i+1, c = i+symbol->aux_symbol_count; k <= c; ++k) {
void *raw_aux = &symbols.v[k];
switch (symbol->storage_class) {
case COFF_SymStorageClass_EXTERNAL: {
case COFF_SymStorageClass_External: {
COFF_SymbolFuncDef *func_def = (COFF_SymbolFuncDef*)&symbols.v[k];
rd_printf("Tag Index %#x, Total Size %#x, Line Numbers %#x, Next Function %#x",
func_def->tag_index, func_def->total_size, func_def->ptr_to_ln, func_def->ptr_to_next_func);
} break;
case COFF_SymStorageClass_FUNCTION: {
case COFF_SymStorageClass_Function: {
COFF_SymbolFunc *func = raw_aux;
rd_printf("Ordinal Line Number %#x, Next Function %#x", func->ln, func->ptr_to_next_func);
} break;
case COFF_SymStorageClass_WEAK_EXTERNAL: {
case COFF_SymStorageClass_WeakExternal: {
COFF_SymbolWeakExt *weak = raw_aux;
String8 type = coff_string_from_weak_ext_type(weak->characteristics);
rd_printf("Tag Index %#x, Characteristics %S", weak->tag_index, type);
} break;
case COFF_SymStorageClass_FILE: {
case COFF_SymStorageClass_File: {
COFF_SymbolFile *file = raw_aux;
String8 name = str8_cstring_capped(file->name, file->name+sizeof(file->name));
rd_printf("Name %S", name);
} break;
case COFF_SymStorageClass_STATIC: {
case COFF_SymStorageClass_Static: {
COFF_SymbolSecDef *sd = raw_aux;
String8 selection = coff_string_from_selection(sd->selection);
String8 selection = coff_string_from_comdat_select_type(sd->selection);
U32 number = sd->number_lo;
if (is_big_obj) {
number |= (U32)sd->number_hi << 16;
@@ -5025,7 +5025,7 @@ coff_print_symbol_table(Arena *arena,
}
internal void
coff_print_big_obj_header(Arena *arena, String8List *out, String8 indent, COFF_HeaderBigObj *header)
coff_print_big_obj_header(Arena *arena, String8List *out, String8 indent, COFF_BigObjHeader *header)
{
Temp scratch = scratch_begin(&arena, 1);
@@ -5034,20 +5034,18 @@ coff_print_big_obj_header(Arena *arena, String8List *out, String8 indent, COFF_H
rd_printf("# Big Obj");
rd_indent();
rd_printf("Time Stamp: %S", time_stamp );
rd_printf("Machine: %S", machine );
rd_printf("Section Count: %u", header->section_count );
rd_printf("Time Stamp: %S", time_stamp );
rd_printf("Machine: %S", machine );
rd_printf("Section Count: %u", header->section_count );
rd_printf("Symbol Table: %#x", header->symbol_table_foff);
rd_printf("Symbol Count: %u", header->symbol_count );
rd_printf("Symbol Count: %u", header->symbol_count );
rd_unindent();
scratch_end(scratch);
}
internal void
coff_print_header(Arena *arena, String8List *out, String8 indent, COFF_Header *header)
coff_print_file_header(Arena *arena, String8List *out, String8 indent, COFF_FileHeader *header)
{
Temp scratch = scratch_begin(&arena, 1);
@@ -5055,22 +5053,22 @@ coff_print_header(Arena *arena, String8List *out, String8 indent, COFF_Header *h
String8 machine = coff_string_from_machine_type(header->machine);
String8 flags = coff_string_from_flags(scratch.arena, header->flags);
rd_printf("# COFF Header");
rd_printf("# COFF File Header");
rd_indent();
rd_printf("Time Stamp: %S", time_stamp );
rd_printf("Machine: %S", machine );
rd_printf("Section Count: %u", header->section_count );
rd_printf("Time Stamp: %S", time_stamp );
rd_printf("Machine: %S", machine );
rd_printf("Section Count: %u", header->section_count );
rd_printf("Symbol Table: %#x", header->symbol_table_foff );
rd_printf("Symbol Count: %u", header->symbol_count );
rd_printf("Optional Header Size: %m", header->optional_header_size);
rd_printf("Flags: %S", flags );
rd_printf("Symbol Count: %u", header->symbol_count );
rd_printf("Optional Header Size: %m", header->optional_header_size);
rd_printf("Flags: %S", flags );
rd_unindent();
scratch_end(scratch);
}
internal void
coff_print_import(Arena *arena, String8List *out, String8 indent, COFF_ImportHeader *header)
coff_print_import(Arena *arena, String8List *out, String8 indent, COFF_ParsedArchiveImportHeader *header)
{
Temp scratch = scratch_begin(&arena, 1);
@@ -5079,15 +5077,15 @@ coff_print_import(Arena *arena, String8List *out, String8 indent, COFF_ImportHea
rd_printf("# Import");
rd_indent();
rd_printf("Version: %u", header->version );
rd_printf("Machine: %S", machine );
rd_printf("Time Stamp: %S", time_stamp );
rd_printf("Data Size: %m", header->data_size);
rd_printf("Hint: %u", header->hint );
rd_printf("Type: %u", header->type );
rd_printf("Name Type: %u", header->name_type);
rd_printf("Function: %S", header->func_name);
rd_printf("DLL: %S", header->dll_name );
rd_printf("Version: %u", header->version );
rd_printf("Machine: %S", machine );
rd_printf("Time Stamp: %S", time_stamp );
rd_printf("Data Size: %m", header->data_size );
rd_printf("Hint: %u", header->hint_or_ordinal);
rd_printf("Type: %u", header->type );
rd_printf("Import By: %u", header->import_by );
rd_printf("Function: %S", header->func_name );
rd_printf("DLL: %S", header->dll_name );
rd_unindent();
scratch_end(scratch);
@@ -5098,8 +5096,8 @@ coff_print_big_obj(Arena *arena, String8List *out, String8 indent, String8 raw_d
{
Temp scratch = scratch_begin(&arena, 1);
COFF_HeaderBigObj *big_obj = str8_deserial_get_raw_ptr(raw_data, 0, sizeof(COFF_HeaderBigObj));
COFF_SectionHeader *sections = str8_deserial_get_raw_ptr(raw_data, sizeof(COFF_HeaderBigObj), sizeof(COFF_SectionHeader)*big_obj->section_count);
COFF_BigObjHeader *big_obj = str8_deserial_get_raw_ptr(raw_data, 0, sizeof(COFF_BigObjHeader));
COFF_SectionHeader *sections = str8_deserial_get_raw_ptr(raw_data, sizeof(COFF_BigObjHeader), sizeof(COFF_SectionHeader)*big_obj->section_count);
U64 string_table_off = big_obj->symbol_table_foff + sizeof(COFF_Symbol32)*big_obj->symbol_count;
COFF_Symbol32Array symbols = coff_symbol_array_from_data_32(scratch.arena, raw_data, big_obj->symbol_table_foff, big_obj->symbol_count);
@@ -5151,14 +5149,14 @@ coff_print_obj(Arena *arena, String8List *out, String8 indent, String8 raw_data,
{
Temp scratch = scratch_begin(&arena, 1);
COFF_Header *header = (COFF_Header *)raw_data.str;
COFF_FileHeader *header = (COFF_FileHeader *)raw_data.str;
COFF_SectionHeader *sections = (COFF_SectionHeader *)(header+1);
U64 string_table_off = header->symbol_table_foff + sizeof(COFF_Symbol16)*header->symbol_count;
COFF_Symbol32Array symbols = coff_symbol_array_from_data_16(scratch.arena, raw_data, header->symbol_table_foff, header->symbol_count);
Arch arch = arch_from_coff_machine(header->machine);
if (opts & RD_Option_Headers) {
coff_print_header(arena, out, indent, header);
coff_print_file_header(arena, out, indent, header);
rd_newline();
}
@@ -5353,16 +5351,16 @@ coff_print_archive(Arena *arena, String8List *out, String8 indent, String8 raw_a
}
switch (member_type) {
case COFF_DataType_BIG_OBJ: {
coff_print_big_obj(arena, out, indent, member.data, opts);
} break;
case COFF_DataType_OBJ: {
case COFF_DataType_Obj: {
coff_print_obj(arena, out, indent, member.data, opts);
} break;
case COFF_DataType_IMPORT: {
case COFF_DataType_BigObj: {
coff_print_big_obj(arena, out, indent, member.data, opts);
} break;
case COFF_DataType_Import: {
if (opts & RD_Option_Headers) {
COFF_ImportHeader header = {0};
U64 parse_size = coff_parse_archive_import(member.data, 0, &header);
COFF_ParsedArchiveImportHeader header = {0};
U64 parse_size = coff_parse_import(member.data, 0, &header);
if (parse_size) {
coff_print_import(arena, out, indent, &header);
} else {
@@ -5370,7 +5368,7 @@ coff_print_archive(Arena *arena, String8List *out, String8 indent, String8 raw_a
}
}
} break;
case COFF_DataType_NULL: {
case COFF_DataType_Null: {
rd_errorf("unknown member format", member_offset);
} break;
}
@@ -6600,9 +6598,9 @@ pe_print_exceptions(Arena *arena,
rd_indent();
rd_printf("%-8s %-8s %-8s %-8s", "Offset", "Begin", "End", "Unwind Info");
switch (machine) {
case COFF_MachineType_UNKNOWN: break;
case COFF_MachineType_X64:
case COFF_MachineType_X86: {
case COFF_Machine_Unknown: break;
case COFF_Machine_X64:
case COFF_Machine_X86: {
pe_print_exceptions_x8664(arena, out, indent, section_count, sections, raw_data, except_frange, rdi);
} break;
default: NotImplemented; break;
@@ -6635,9 +6633,9 @@ pe_print_base_relocs(Arena *arena,
U32 addr_size = 0;
switch (machine) {
case COFF_MachineType_UNKNOWN: break;
case COFF_MachineType_X86: addr_size = 4; break;
case COFF_MachineType_X64: addr_size = 8; break;
case COFF_Machine_Unknown: break;
case COFF_Machine_X86: addr_size = 4; break;
case COFF_Machine_X64: addr_size = 8; break;
default: NotImplemented;
}
@@ -6667,9 +6665,9 @@ pe_print_base_relocs(Arena *arena,
case PE_BaseRelocKind_DIR64: type_str = "DIR64"; break;
default: {
switch (machine) {
case COFF_MachineType_ARM:
case COFF_MachineType_ARM64:
case COFF_MachineType_ARMNT: {
case COFF_Machine_Arm:
case COFF_Machine_Arm64:
case COFF_Machine_ArmNt: {
switch (type) {
case PE_BaseRelocKind_ARM_MOV32: type_str = "ARM_MOV32"; break;
case PE_BaseRelocKind_THUMB_MOV32: type_str = "THUMB_MOV32"; break;
@@ -6718,14 +6716,14 @@ pe_print(Arena *arena, String8List *out, String8 indent, String8 raw_data, RD_Op
goto exit;
}
U64 coff_header_off = dos_header->coff_file_offset+sizeof(pe_magic);
COFF_Header *coff_header = str8_deserial_get_raw_ptr(raw_data, coff_header_off, sizeof(*coff_header));
if (!coff_header) {
U64 file_header_off = dos_header->coff_file_offset+sizeof(pe_magic);
COFF_FileHeader *file_header = str8_deserial_get_raw_ptr(raw_data, file_header_off, sizeof(*file_header));
if (!file_header) {
rd_errorf("not enough bytes to read COFF header");
goto exit;
}
U64 opt_header_off = coff_header_off + sizeof(*coff_header);
U64 opt_header_off = file_header_off + sizeof(*file_header);
U16 opt_header_magic = 0;
str8_deserial_read_struct(raw_data, opt_header_off, &opt_header_magic);
if (opt_header_magic != PE_PE32_MAGIC && opt_header_magic != PE_PE32PLUS_MAGIC) {
@@ -6733,36 +6731,36 @@ pe_print(Arena *arena, String8List *out, String8 indent, String8 raw_data, RD_Op
goto exit;
}
if (opt_header_magic == PE_PE32_MAGIC && coff_header->optional_header_size < sizeof(PE_OptionalHeader32)) {
rd_errorf("unexpected optional header size in COFF header %m, expected at least %m", coff_header->optional_header_size, sizeof(PE_OptionalHeader32));
if (opt_header_magic == PE_PE32_MAGIC && file_header->optional_header_size < sizeof(PE_OptionalHeader32)) {
rd_errorf("unexpected optional header size in COFF header %m, expected at least %m", file_header->optional_header_size, sizeof(PE_OptionalHeader32));
goto exit;
}
if (opt_header_magic == PE_PE32PLUS_MAGIC && coff_header->optional_header_size < sizeof(PE_OptionalHeader32Plus)) {
rd_errorf("unexpected optional header size %m, expected at least %m", coff_header->optional_header_size, sizeof(PE_OptionalHeader32Plus));
if (opt_header_magic == PE_PE32PLUS_MAGIC && file_header->optional_header_size < sizeof(PE_OptionalHeader32Plus)) {
rd_errorf("unexpected optional header size %m, expected at least %m", file_header->optional_header_size, sizeof(PE_OptionalHeader32Plus));
goto exit;
}
U64 sections_off = coff_header_off + sizeof(*coff_header) + coff_header->optional_header_size;
COFF_SectionHeader *sections = str8_deserial_get_raw_ptr(raw_data, sections_off, sizeof(*sections)*coff_header->section_count);
U64 sections_off = file_header_off + sizeof(*file_header) + file_header->optional_header_size;
COFF_SectionHeader *sections = str8_deserial_get_raw_ptr(raw_data, sections_off, sizeof(*sections)*file_header->section_count);
if (!sections) {
rd_errorf("not enough bytes to read COFF section headers");
goto exit;
}
U64 string_table_off = coff_header->symbol_table_foff + sizeof(COFF_Symbol16) * coff_header->symbol_count;
U64 string_table_off = file_header->symbol_table_foff + sizeof(COFF_Symbol16) * file_header->symbol_count;
COFF_Symbol32Array symbols = coff_symbol_array_from_data_16(scratch.arena, raw_data, coff_header->symbol_table_foff, coff_header->symbol_count);
COFF_Symbol32Array symbols = coff_symbol_array_from_data_16(scratch.arena, raw_data, file_header->symbol_table_foff, file_header->symbol_count);
U8 *raw_opt_header = push_array(scratch.arena, U8, coff_header->optional_header_size);
str8_deserial_read_array(raw_data, opt_header_off, raw_opt_header, coff_header->optional_header_size);
U8 *raw_opt_header = push_array(scratch.arena, U8, file_header->optional_header_size);
str8_deserial_read_array(raw_data, opt_header_off, raw_opt_header, file_header->optional_header_size);
if (opts & RD_Option_Headers) {
coff_print_header(arena, out, indent, coff_header);
coff_print_file_header(arena, out, indent, file_header);
rd_newline();
}
Arch arch = arch_from_coff_machine(coff_header->machine);
Arch arch = arch_from_coff_machine(file_header->machine);
U64 image_base = 0;
U64 dir_count = 0;
PE_DataDirectory *dirs = 0;
@@ -6800,17 +6798,17 @@ pe_print(Arena *arena, String8List *out, String8 indent, String8 raw_data, RD_Op
Rng1U64 *dirs_virt_ranges = push_array(scratch.arena, Rng1U64, dir_count);
for (U64 i = 0; i < dir_count; ++i) {
PE_DataDirectory dir = dirs[i];
U64 file_off = coff_foff_from_voff(sections, coff_header->section_count, dir.virt_off);
U64 file_off = coff_foff_from_voff(sections, file_header->section_count, dir.virt_off);
dirs_file_ranges[i] = r1u64(file_off, file_off+dir.virt_size);
dirs_virt_ranges[i] = r1u64(dir.virt_off, dir.virt_off+dir.virt_size);
}
if (opts & RD_Option_Sections) {
coff_print_seciton_table(arena, out, indent, raw_data, string_table_off, symbols, coff_header->section_count, sections);
coff_print_seciton_table(arena, out, indent, raw_data, string_table_off, symbols, file_header->section_count, sections);
}
if (opts & RD_Option_Relocs) {
coff_print_relocs(arena, out, indent, raw_data, string_table_off, coff_header->machine, coff_header->section_count, sections, symbols);
coff_print_relocs(arena, out, indent, raw_data, string_table_off, file_header->machine, file_header->section_count, sections, symbols);
}
if (opts & RD_Option_Symbols) {
@@ -6819,7 +6817,7 @@ pe_print(Arena *arena, String8List *out, String8 indent, String8 raw_data, RD_Op
if (opts & RD_Option_Exports) {
PE_ParsedExportTable exptab = pe_exports_from_data(arena,
coff_header->section_count,
file_header->section_count,
sections,
raw_data,
dirs_file_ranges[PE_DataDirectoryIndex_EXPORT],
@@ -6829,8 +6827,8 @@ pe_print(Arena *arena, String8List *out, String8 indent, String8 raw_data, RD_Op
if (opts & RD_Option_Imports) {
B32 is_pe32 = opt_header_magic == PE_PE32_MAGIC;
PE_ParsedStaticImportTable static_imptab = pe_static_imports_from_data(arena, is_pe32, coff_header->section_count, sections, raw_data, dirs_file_ranges[PE_DataDirectoryIndex_IMPORT]);
PE_ParsedDelayImportTable delay_imptab = pe_delay_imports_from_data(arena, is_pe32, coff_header->section_count, sections, raw_data, dirs_file_ranges[PE_DataDirectoryIndex_DELAY_IMPORT]);
PE_ParsedStaticImportTable static_imptab = pe_static_imports_from_data(arena, is_pe32, file_header->section_count, sections, raw_data, dirs_file_ranges[PE_DataDirectoryIndex_IMPORT]);
PE_ParsedDelayImportTable delay_imptab = pe_delay_imports_from_data(arena, is_pe32, file_header->section_count, sections, raw_data, dirs_file_ranges[PE_DataDirectoryIndex_DELAY_IMPORT]);
pe_print_static_import_table(arena, out, indent, image_base, static_imptab);
pe_print_delay_import_table(arena, out, indent, image_base, delay_imptab);
}
@@ -6842,11 +6840,11 @@ pe_print(Arena *arena, String8List *out, String8 indent, String8 raw_data, RD_Op
}
if (opts & RD_Option_Exceptions) {
pe_print_exceptions(arena, out, indent, coff_header->machine, coff_header->section_count, sections, raw_data, dirs_file_ranges[PE_DataDirectoryIndex_EXCEPTIONS], rdi);
pe_print_exceptions(arena, out, indent, file_header->machine, file_header->section_count, sections, raw_data, dirs_file_ranges[PE_DataDirectoryIndex_EXCEPTIONS], rdi);
}
if (opts & RD_Option_Relocs) {
pe_print_base_relocs(arena, out, indent, coff_header->machine, image_base, coff_header->section_count, sections, raw_data, dirs_file_ranges[PE_DataDirectoryIndex_BASE_RELOC], rdi);
pe_print_base_relocs(arena, out, indent, file_header->machine, image_base, file_header->section_count, sections, raw_data, dirs_file_ranges[PE_DataDirectoryIndex_BASE_RELOC], rdi);
}
if (opts & RD_Option_Debug) {
@@ -6858,7 +6856,7 @@ pe_print(Arena *arena, String8List *out, String8 indent, String8 raw_data, RD_Op
if (opts & RD_Option_Tls) {
if (dim_1u64(dirs_file_ranges[PE_DataDirectoryIndex_TLS])) {
PE_ParsedTLS tls = pe_tls_from_data(scratch.arena, coff_header->machine, image_base, coff_header->section_count, sections, raw_data, dirs_file_ranges[PE_DataDirectoryIndex_TLS]);
PE_ParsedTLS tls = pe_tls_from_data(scratch.arena, file_header->machine, image_base, file_header->section_count, sections, raw_data, dirs_file_ranges[PE_DataDirectoryIndex_TLS]);
pe_print_tls(arena, out, indent, tls);
}
}
@@ -6866,9 +6864,9 @@ pe_print(Arena *arena, String8List *out, String8 indent, String8 raw_data, RD_Op
if (opts & RD_Option_LoadConfig) {
String8 raw_lc = str8_substr(raw_data, dirs_file_ranges[PE_DataDirectoryIndex_LOAD_CONFIG]);
if (raw_lc.size) {
switch (coff_header->machine) {
case COFF_MachineType_UNKNOWN: break;
case COFF_MachineType_X86: {
switch (file_header->machine) {
case COFF_Machine_Unknown: break;
case COFF_Machine_X86: {
PE_LoadConfig32 *lc = str8_deserial_get_raw_ptr(raw_lc, 0, sizeof(*lc));
if (lc) {
pe_print_load_config32(arena, out, indent, lc);
@@ -6876,7 +6874,7 @@ pe_print(Arena *arena, String8List *out, String8 indent, String8 raw_data, RD_Op
rd_errorf("not enough bytes to parse 32bit load config");
}
} break;
case COFF_MachineType_X64: {
case COFF_Machine_X64: {
PE_LoadConfig64 *lc = str8_deserial_get_raw_ptr(raw_lc, 0, sizeof(*lc));
if (lc) {
pe_print_load_config64(arena, out, indent, lc);
@@ -6894,20 +6892,20 @@ pe_print(Arena *arena, String8List *out, String8 indent, String8 raw_data, RD_Op
if (rdi) {
section_markers = rd_section_markers_from_rdi(scratch.arena, rdi);
} else {
section_markers = rd_section_markers_from_coff_symbol_table(scratch.arena, raw_data, string_table_off, coff_header->section_count, symbols);
section_markers = rd_section_markers_from_coff_symbol_table(scratch.arena, raw_data, string_table_off, file_header->section_count, symbols);
}
}
if (opts & RD_Option_Rawdata) {
coff_raw_data_sections(arena, out, indent, raw_data, 0, section_markers, coff_header->section_count, sections);
coff_raw_data_sections(arena, out, indent, raw_data, 0, section_markers, file_header->section_count, sections);
}
if (opts & RD_Option_Disasm) {
coff_disasm_sections(arena, out, indent, raw_data, coff_header->machine, 0, 1, section_markers, coff_header->section_count, sections);
coff_disasm_sections(arena, out, indent, raw_data, file_header->machine, 0, 1, section_markers, file_header->section_count, sections);
}
if (opts & RD_Option_Dwarf) {
DW_SectionArray dwarf_sections = rd_dw_sections_from_coff_section_table(scratch.arena, raw_data, string_table_off, coff_header->section_count, sections);
DW_SectionArray dwarf_sections = rd_dw_sections_from_coff_section_table(scratch.arena, raw_data, string_table_off, file_header->section_count, sections);
dw_format(arena, out, indent, opts, &dwarf_sections, arch, Image_CoffPe);
}
+11 -10
View File
@@ -120,7 +120,8 @@ typedef struct RD_Line
// raddump
internal B32 rd_is_pe(String8 raw_data);
internal B32 rd_is_pe(String8 raw_data);
internal void rd_format_preamble(Arena *arena, String8List *out, String8 indent, String8 input_path, String8 raw_data);
// Markers
@@ -134,12 +135,12 @@ internal RD_SectionArray rd_sections_from_coff_section_table(Arena *arnea, Strin
// Disasm
internal RD_DisasmResult rd_disasm_next_instruction(Arena *arena, Arch arch, U64 addr, String8 raw_code);
internal void rd_print_disasm (Arena *arena, String8List *out, String8 indent, Arch arch, U64 image_base, U64 sect_off, U64 marker_count, RD_Marker *markers, String8 raw_code);
internal void rd_print_disasm (Arena *arena, String8List *out, String8 indent, Arch arch, U64 image_base, U64 sect_off, U64 marker_count, RD_Marker *markers, String8 raw_code);
// Raw Data
internal String8 rd_format_hex_array(Arena *arena, U8 *ptr, U64 size);
internal void rd_print_raw_data (Arena *arena, String8List *out, String8 indent, U64 bytes_per_row, U64 marker_count, RD_Marker *markers, String8 raw_data);
internal void rd_print_raw_data (Arena *arena, String8List *out, String8 indent, U64 bytes_per_row, U64 marker_count, RD_Marker *markers, String8 raw_data);
// DWARF
@@ -182,15 +183,15 @@ internal void cv_print_symbols_section(Arena *arena, String8List *out, String8 i
// COFF
internal void coff_print_archive_member_header(Arena *arena, String8List *out, String8 indent, COFF_ArchiveMemberHeader header, String8 long_names);
internal void coff_print_archive_member_header(Arena *arena, String8List *out, String8 indent, COFF_ParsedArchiveMemberHeader header, String8 long_names);
internal void coff_print_seciton_table (Arena *arena, String8List *out, String8 indent, String8 raw_data, U64 string_table_off, COFF_Symbol32Array symbols, U64 sect_count, COFF_SectionHeader *sect_headers);
internal void coff_disasm_sections (Arena *arena, String8List *out, String8 indent, String8 raw_data, COFF_MachineType machine, U64 image_base, B32 is_obj, RD_MarkerArray *section_markers, U64 section_count, COFF_SectionHeader *sections);
internal void coff_raw_data_sections (Arena *arena, String8List *out, String8 indent, String8 raw_data, B32 is_obj, RD_MarkerArray *section_markers, U64 section_count, COFF_SectionHeader *sections);
internal void coff_disasm_sections (Arena *arena, String8List *out, String8 indent, String8 raw_data, COFF_MachineType machine, U64 image_base, B32 is_obj, RD_MarkerArray *section_markers, U64 section_count, COFF_SectionHeader *sections);
internal void coff_raw_data_sections (Arena *arena, String8List *out, String8 indent, String8 raw_data, B32 is_obj, RD_MarkerArray *section_markers, U64 section_count, COFF_SectionHeader *sections);
internal void coff_print_relocs (Arena *arena, String8List *out, String8 indent, String8 raw_data, U64 string_table_off, COFF_MachineType machine, U64 sect_count, COFF_SectionHeader *sect_headers, COFF_Symbol32Array symbols);
internal void coff_print_symbol_table (Arena *arena, String8List *out, String8 indent, String8 raw_data, B32 is_big_obj, U64 string_table_off, COFF_Symbol32Array symbols);
internal void coff_print_big_obj_header (Arena *arena, String8List *out, String8 indent, COFF_HeaderBigObj *header);
internal void coff_print_header (Arena *arena, String8List *out, String8 indent, COFF_Header *header);
internal void coff_print_import (Arena *arena, String8List *out, String8 indent, COFF_ImportHeader *header);
internal void coff_print_big_obj_header (Arena *arena, String8List *out, String8 indent, COFF_BigObjHeader *header);
internal void coff_print_file_header (Arena *arena, String8List *out, String8 indent, COFF_FileHeader *header);
internal void coff_print_import (Arena *arena, String8List *out, String8 indent, COFF_ParsedArchiveImportHeader *header);
internal void coff_print_big_obj (Arena *arena, String8List *out, String8 indent, String8 raw_data, RD_Option opts);
internal void coff_print_obj (Arena *arena, String8List *out, String8 indent, String8 raw_data, RD_Option opts);
internal void coff_print_archive (Arena *arena, String8List *out, String8 indent, String8 raw_archive, RD_Option opts);
@@ -207,7 +208,7 @@ internal void pe_print_optional_header32plus(Arena *arena, String8List *out, Str
internal void pe_print_load_config32 (Arena *arena, String8List *out, String8 indent, PE_LoadConfig32 *lc);
internal void pe_print_load_config64 (Arena *arena, String8List *out, String8 indent, PE_LoadConfig64 *lc);
internal void pe_print_tls (Arena *arena, String8List *out, String8 indent, PE_ParsedTLS tls);
internal void pe_print_debug_diretory (Arena *arena, String8List *out, String8 indent, String8 raw_data, String8 raw_dir);
internal void pe_print_debug_diretory (Arena *arena, String8List *out, String8 indent, String8 raw_data, String8 raw_dir);
internal void pe_print_export_table (Arena *arena, String8List *out, String8 indent, PE_ParsedExportTable exptab);
internal void pe_print_static_import_table (Arena *arena, String8List *out, String8 indent, U64 image_base, PE_ParsedStaticImportTable imptab);
internal void pe_print_delay_import_table (Arena *arena, String8List *out, String8 indent, U64 image_base, PE_ParsedDelayImportTable imptab);
+3 -1
View File
@@ -28,6 +28,7 @@
#include "path/path.h"
#include "coff/coff.h"
#include "coff/coff_enum.h"
#include "coff/coff_parse.h"
#include "pe/pe.h"
#include "msvc_crt/msvc_crt.h"
#include "msvc_crt/msvc_crt_enum.h"
@@ -53,6 +54,7 @@
#include "path/path.c"
#include "coff/coff.c"
#include "coff/coff_enum.c"
#include "coff/coff_parse.c"
#include "pe/pe.c"
#include "msvc_crt/msvc_crt.c"
#include "msvc_crt/msvc_crt_enum.c"
@@ -226,7 +228,7 @@ entry_point(CmdLine *cmdline)
// format input
rd_format_preamble(arena, out, indent, file_path, raw_data);
if (coff_is_archive(raw_data) || coff_is_thin_archive(raw_data)) {
if (coff_is_regular_archive(raw_data) || coff_is_thin_archive(raw_data)) {
coff_print_archive(arena, out, indent, raw_data, opts);
} else if (coff_is_big_obj(raw_data)) {
coff_print_big_obj(arena, out, indent, raw_data, opts);
+3 -3
View File
@@ -161,15 +161,15 @@ internal RDI_BinarySectionFlags
p2r_rdi_binary_section_flags_from_coff_section_flags(COFF_SectionFlags flags)
{
RDI_BinarySectionFlags result = 0;
if(flags & COFF_SectionFlag_MEM_READ)
if(flags & COFF_SectionFlag_MemRead)
{
result |= RDI_BinarySectionFlag_Read;
}
if(flags & COFF_SectionFlag_MEM_WRITE)
if(flags & COFF_SectionFlag_MemWrite)
{
result |= RDI_BinarySectionFlag_Write;
}
if(flags & COFF_SectionFlag_MEM_EXECUTE)
if(flags & COFF_SectionFlag_MemExecute)
{
result |= RDI_BinarySectionFlag_Execute;
}
+2
View File
@@ -22,6 +22,7 @@
#include "async/async.h"
#include "rdi_make/rdi_make_local.h"
#include "coff/coff.h"
#include "coff/coff_parse.h"
#include "codeview/codeview.h"
#include "codeview/codeview_parse.h"
#include "msf/msf.h"
@@ -37,6 +38,7 @@
#include "async/async.c"
#include "rdi_make/rdi_make_local.c"
#include "coff/coff.c"
#include "coff/coff_parse.c"
#include "codeview/codeview.c"
#include "codeview/codeview_parse.c"
#include "msf/msf.c"