pass over COFF, added symbol for function definitions, updated names

and types in structs, added enum to and from string helpers
This commit is contained in:
Nikita Smith
2024-12-03 11:14:10 -08:00
parent 53a5f6ab06
commit e22bd33275
2 changed files with 340 additions and 30 deletions
+287 -3
View File
@@ -101,10 +101,10 @@ coff_header_info_from_data(String8 data)
info.machine = big_header->machine;
info.section_array_off = sizeof(COFF_HeaderBigObj);
info.section_count_no_null = big_header->section_count;
info.string_table_off = big_header->pointer_to_symbol_table + sizeof(COFF_Symbol32) * big_header->number_of_symbols;
info.string_table_off = big_header->symbol_table_foff + sizeof(COFF_Symbol32) * big_header->symbol_count;
info.symbol_size = sizeof(COFF_Symbol32);
info.symbol_off = big_header->pointer_to_symbol_table;
info.symbol_count = big_header->number_of_symbols;
info.symbol_off = big_header->symbol_table_foff;
info.symbol_count = big_header->symbol_count;
} else if (coff_is_obj(data)) {
COFF_Header *header = (COFF_Header*)data.str;
info.type = COFF_DataType_OBJ;
@@ -408,6 +408,75 @@ coff_reloc_info_from_section_header(String8 data, COFF_SectionHeader *header)
return result;
}
internal U64
coff_apply_size_from_reloc_x64(COFF_RelocTypeX64 x)
{
switch (x) {
case COFF_RelocTypeX64_ABS: return 4;
case COFF_RelocTypeX64_ADDR64: return 8;
case COFF_RelocTypeX64_ADDR32: return 4;
case COFF_RelocTypeX64_ADDR32NB: return 4;
case COFF_RelocTypeX64_REL32: return 4;
case COFF_RelocTypeX64_REL32_1: return 4;
case COFF_RelocTypeX64_REL32_2: return 4;
case COFF_RelocTypeX64_REL32_3: return 4;
case COFF_RelocTypeX64_REL32_4: return 4;
case COFF_RelocTypeX64_REL32_5: return 4;
case COFF_RelocTypeX64_SECTION: return 2;
case COFF_RelocTypeX64_SECREL: return 4;
case COFF_RelocTypeX64_SREL32: return 4;
case COFF_RelocTypeX64_SECREL7:
case COFF_RelocTypeX64_TOKEN:
case COFF_RelocTypeX64_PAIR:
case COFF_RelocTypeX64_SSPAN32:
NotImplemented;
break;
}
return 0;
}
internal U64
coff_apply_size_from_reloc_x86(COFF_RelocTypeX86 x)
{
switch (x) {
case COFF_RelocTypeX86_ABS: return 4;
case COFF_RelocTypeX86_DIR16: return 2;
case COFF_RelocTypeX86_REL16: return 2;
case COFF_RelocTypeX86_DIR32: return 4;
case COFF_RelocTypeX86_DIR32NB: return 4;
case COFF_RelocTypeX86_SEG12: return 0;
case COFF_RelocTypeX86_SECTION: return 2;
case COFF_RelocTypeX86_SECREL: return 4;
case COFF_RelocTypeX86_TOKEN: return 4;
case COFF_RelocTypeX86_SECREL7: return 1;
case COFF_RelocTypeX86_REL32: return 4;
case COFF_RelocTypeX86_UNKNOWN0:
case COFF_RelocTypeX86_UNKNOWN2:
case COFF_RelocTypeX86_UNKNOWN3:
case COFF_RelocTypeX86_UNKNOWN4:
case COFF_RelocTypeX86_UNKNOWN6:
case COFF_RelocTypeX86_UNKNOWN7:
case COFF_RelocTypeX86_UNKNOWN8:
case COFF_RelocTypeX86_UNKNOWN9:
NotImplemented;
break;
}
return 0;
}
internal U64
coff_apply_size_from_reloc(COFF_MachineType machine, COFF_RelocType x)
{
switch (machine) {
case COFF_MachineType_X64: return coff_apply_size_from_reloc_x64(x);
case COFF_MachineType_X86: return coff_apply_size_from_reloc_x86(x);
default: NotImplemented;
}
return 0;
}
internal U64
coff_word_size_from_machine(COFF_MachineType machine)
{
@@ -1371,6 +1440,221 @@ coff_string_from_import_header_type(COFF_ImportHeaderType type)
return str8(0,0);
}
internal String8
coff_string_from_sym_dtype(COFF_SymDType x)
{
switch (x) {
case COFF_SymDType_NULL: break;
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();
}
internal String8
coff_string_from_sym_type(COFF_SymType x)
{
switch (x) {
case COFF_SymType_NULL: break;
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");
}
return str8_zero();
}
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");
}
return str8_zero();
}
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");
}
return str8_zero();
}
internal String8
coff_string_from_selection(COFF_ComdatSelectType 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");
}
return str8_zero();
}
internal String8
coff_string_from_reloc_x86(COFF_RelocTypeX86 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");
}
return str8_zero();
}
internal String8
coff_string_from_reloc_x64(COFF_RelocTypeX64 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");
}
return str8_zero();
}
internal String8
coff_string_from_reloc_arm(COFF_RelocTypeARM 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");
}
return str8_zero();
}
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);
}
return str8_zero();
}
internal COFF_MachineType
coff_machine_from_string(String8 string)
{
+53 -27
View File
@@ -149,7 +149,9 @@ struct COFF_SectionHeader
COFF_SectionFlags flags;
};
typedef U16 COFF_RelocTypeX64;
typedef U16 COFF_RelocType;
typedef COFF_RelocType COFF_RelocTypeX64;
enum
{
COFF_RelocTypeX64_ABS = 0x0,
@@ -172,7 +174,7 @@ enum
COFF_RelocTypeX64_COUNT = 17
};
typedef U16 COFF_RelocTypeX86;
typedef COFF_RelocType COFF_RelocTypeX86;
enum
{
COFF_RelocTypeX86_ABS = 0x0, // relocation is ignored
@@ -198,7 +200,7 @@ enum
COFF_RelocTypeX86_COUNT = 20
};
typedef U16 COFF_RelocTypeARM;
typedef COFF_RelocType COFF_RelocTypeARM;
enum
{
COFF_RelocTypeARM_ABS = 0x0,
@@ -224,7 +226,7 @@ enum
COFF_RelocTypeARM_COUNT = 20
};
typedef U16 COFF_RelocTypeARM64;
typedef COFF_RelocType COFF_RelocTypeARM64;
enum
{
COFF_RelocTypeARM64_ABS = 0x0,
@@ -392,16 +394,16 @@ enum
typedef struct COFF_HeaderBigObj COFF_HeaderBigObj;
struct COFF_HeaderBigObj
{
U16 sig1; // COFF_MachineType_UNKNOWN
U16 sig2; // U16_MAX
U16 version;
U16 machine;
U32 time_stamp;
U8 magic[16];
U32 unused[4];
U32 section_count;
U32 pointer_to_symbol_table;
U32 number_of_symbols;
U16 sig1; // COFF_MachineType_UNKNOWN
U16 sig2; // U16_MAX
U16 version; // COFF_MIN_BIG_OBJ_VERSION
COFF_MachineType machine;
COFF_TimeStamp time_stamp;
U8 magic[16];
U32 unused[4];
U32 section_count;
U32 symbol_table_foff;
U32 symbol_count;
};
// Special values for section number field in coff symbol
@@ -422,7 +424,7 @@ union COFF_SymbolName
// and we need to use the offset to look it up...
U32 zeroes;
U32 string_table_offset;
}long_name;
} long_name;
};
#define COFF_SymbolType_IsFunc(x) ((x).u.lsb == COFF_SymType_NULL && (x).u.msb == COFF_SymDType_FUNC)
@@ -463,6 +465,16 @@ struct COFF_Symbol32
// Auxilary symbols are allocated with fixed size so that symbol table could be maintaned as array of regular size.
#define COFF_AUX_SYMBOL_SIZE 18
// storage class: EXTERNAL
typedef struct COFF_SymbolFuncDef
{
U32 tag_index;
U32 total_size;
U32 ptr_to_ln;
U32 ptr_to_next_func;
U8 unused[2];
} COFF_SymbolFuncDef;
// storage class: FUNCTION
typedef struct COFF_SymbolFunc
{
@@ -476,9 +488,9 @@ typedef struct COFF_SymbolFunc
// storage class: WEAK_EXTERNAL
typedef struct COFF_SymbolWeakExt
{
U32 tag_index;
U32 characteristics;
U8 unused[10];
U32 tag_index;
COFF_WeakExtType characteristics;
U8 unused[10];
} COFF_SymbolWeakExt;
typedef struct COFF_SymbolFile
@@ -490,14 +502,14 @@ typedef struct COFF_SymbolFile
// storage class: STATIC
typedef struct COFF_SymbolSecDef
{
U32 length;
U16 number_of_relocations;
U16 number_of_ln;
U32 check_sum;
U16 number_lo; // one-based section index
U8 selection;
U8 unused;
U16 number_hi;
U32 length;
U16 number_of_relocations;
U16 number_of_ln;
U32 check_sum;
U16 number_lo; // one-based section index
COFF_ComdatSelectType selection;
U8 unused;
U16 number_hi;
} COFF_SymbolSecDef;
// specifies how section data should be modified when placed in the image file.
@@ -827,6 +839,10 @@ internal COFF_Symbol32Array coff_symbol_array_from_data(Arena *arena, String8 d
internal COFF_Symbol16Node * coff_symbol16_list_push(Arena *arena, COFF_Symbol16List *list, COFF_Symbol16 symbol);
internal COFF_RelocInfo coff_reloc_info_from_section_header(String8 data, COFF_SectionHeader *header);
internal U64 coff_apply_size_from_reloc_x64(COFF_RelocTypeX64 x);
internal U64 coff_apply_size_from_reloc_x86(COFF_RelocTypeX86 x);
internal U64 coff_apply_size_from_reloc(COFF_MachineType machine, COFF_RelocType x);
internal U64 coff_word_size_from_machine(COFF_MachineType machine);
internal U64 coff_default_exe_base_from_machine(COFF_MachineType machine);
internal U64 coff_default_dll_base_from_machine(COFF_MachineType machine);
@@ -894,8 +910,18 @@ internal String8 coff_string_from_comdat_select_type(COFF_ComdatSelectType selec
internal String8 coff_string_from_machine_type(COFF_MachineType machine);
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_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(COFF_MachineType machine, COFF_RelocType x);
internal COFF_MachineType coff_machine_from_string(String8 string);
internal COFF_MachineType coff_machine_from_string(String8 string);
internal COFF_ImportHeaderType coff_import_header_type_from_string(String8 name);
#endif //COFF_H