//////////////////////////////// // Functions: COFF / PE // properties MR4TH_SYM_COMPTIME U32 pe_unwind_num_code_slot_from_opcode_opinfo(PE_UnwindOpCode opcode, U8 opinfo){ U32 num = 1; switch (opcode){ case PE_UnwindOpCode_PUSH_NONVOL: case PE_UnwindOpCode_ALLOC_SMALL: case PE_UnwindOpCode_SET_FPREG: case PE_UnwindOpCode_PUSH_MACHFRAME: case PE_UnwindOpCode_EPILOG: case PE_UnwindOpCode_SPARE: { num = 1; }break; case PE_UnwindOpCode_ALLOC_LARGE: { if (opinfo == 0){ num = 2; } else{ num = 3; } }break; case PE_UnwindOpCode_SAVE_NONVOL: case PE_UnwindOpCode_SAVE_XMM128: { num = 2; }break; case PE_UnwindOpCode_SAVE_NONVOL_FAR: case PE_UnwindOpCode_SAVE_XMM128_FAR: { num = 3; }break; } return(num); } // checks MR4TH_SYM_COMPTIME B32 pe_machine_type_is_valid(PE_MachineType machine_type){ B32 result = 0; switch (machine_type){ #define X(N,C) case C: PE_MachineType_XList(X) #undef X result = 1; break; } return(result); } // strings MR4TH_SYM_COMPTIME String8 pe_str8_from_machine_type(PE_MachineType machine_type){ String8 result = str8_lit("ERROR"); switch (machine_type){ #define X(N,C) case C: result = str8_lit(#N); break; PE_MachineType_XList(X) #undef X } return(result); } MR4TH_SYM_COMPTIME void pe_str8list_from_flags(Arena *arena, String8List *out, PE_Flags flags){ U32 f = 1; for (U32 i = 0; i < 8*sizeof(flags); i += 1){ if ((flags & f) != 0){ switch (f){ #define X(N,C) case C: str8_list_push(arena, out, str8_lit(#N)); break; PE_Flags_XList(X) #undef X } } f <<= 1; } } MR4TH_SYM_COMPTIME String8 pe_str8_from_flags(Arena *arena, PE_Flags flags){ ArenaTemp scratch = arena_get_scratch(&arena, 1); String8List list = {0}; pe_str8list_from_flags(scratch.arena, &list, flags); String8 result = str8_join_flags(arena, &list); arena_release_scratch(&scratch); return(result); } MR4TH_SYM_COMPTIME String8 pe_str8_from_optional_header_magic(PE_OptionalHeaderMagic magic){ String8 result = str8_lit("ERROR"); switch (magic){ #define X(N,C) case C: result = str8_lit(#N); break; PE_OptionalHeaderMagic_XList(X) #undef X } return(result); } MR4TH_SYM_COMPTIME String8 pe_str8_from_windows_subsystem(PE_WindowsSubsystem subsystem){ String8 result = str8_lit("ERROR"); switch (subsystem){ #define X(N,C) case C: result = str8_lit(#N); break; PE_WindowsSubsystem_XList(X) #undef X } return(result); } MR4TH_SYM_COMPTIME void pe_str8list_from_dll_flags(Arena *arena, String8List *out, PE_DLLFlags dll_flags){ U32 f = 1; for (U32 i = 0; i < 8*sizeof(dll_flags); i += 1){ if ((dll_flags & f) != 0){ switch (f){ #define X(N,C) case C: str8_list_push(arena, out, str8_lit(#N)); break; PE_DLLFlags_XList(X) #undef X } } f <<= 1; } } MR4TH_SYM_COMPTIME String8 pe_str8_from_dll_flags(Arena *arena, PE_DLLFlags dll_flags){ ArenaTemp scratch = arena_get_scratch(&arena, 1); String8List list = {0}; pe_str8list_from_dll_flags(scratch.arena, &list, dll_flags); String8 result = str8_join_flags(arena, &list); arena_release_scratch(&scratch); return(result); } MR4TH_SYM_COMPTIME String8 pe_str8_from_data_directory_idx(PE_DataDirectoryIdx idx){ String8 result = {0}; switch (idx){ #define X(N,D,C) case C: result = str8_lit(#N); break; PE_DataDirectoryIdx_XList(X) #undef X } return(result); } MR4TH_SYM_COMPTIME String8 pe_str8_display_string_from_data_directory_idx(PE_DataDirectoryIdx idx){ String8 result = {0}; switch (idx){ #define X(N,D,C) case C: result = str8_lit(D); break; PE_DataDirectoryIdx_XList(X) #undef X } return(result); } MR4TH_SYM_COMPTIME String8 pe_str8_from_sec_alignment(U32 alignment){ String8 result = {0}; switch (alignment){ #define X(Z,C) case C: result = str8_lit("ALIGN_" #Z "BYTES"); break; PE_SectionAlign_XList(X) #undef X } return(result); } MR4TH_SYM_COMPTIME void pe_str8list_from_sec_flags(Arena *arena, String8List *out, PE_SectionFlags sec_flags){ // align U32 section_align = PE_SectionAlignFromSectionFlags(sec_flags); String8 align_str = pe_str8_from_sec_alignment(section_align); if (align_str.size > 0){ str8_list_push(arena, out, align_str); } // other flags U32 f = 1; for (U32 i = 0; i < 8*sizeof(sec_flags); i += 1){ if ((sec_flags & f) != 0){ switch (f){ #define X(N,C) case C: str8_list_push(arena, out, str8_lit(#N)); break; PE_SectionFlags_XList(X) #undef X } } f <<= 1; } } MR4TH_SYM_COMPTIME String8 pe_str8_from_sec_flags(Arena *arena, PE_SectionFlags sec_flags){ ArenaTemp scratch = arena_get_scratch(&arena, 1); String8List list = {0}; pe_str8list_from_sec_flags(scratch.arena, &list, sec_flags); String8 result = str8_join_flags(arena, &list); arena_release_scratch(&scratch); return(result); } MR4TH_SYM_COMPTIME String8 pe_str8_from_coff_relocation_type(PE_CoffRelocationType type){ String8 result = str8_lit("ERROR"); switch (type){ #define X(N,C) case C: result = str8_lit(#N); break; PE_CoffRelocationType_XList(X) #undef X } return(result); } MR4TH_SYM_COMPTIME String8 pe_str8_from_coff_symbol_type(Arena *arena, PE_CoffSymbolType type){ String8 lo = str8_lit("ERROR"); switch (type & 0xF){ #define X(N,C) case C: lo = str8_lit(#N); break; PE_CoffSymbolTypeLo_XList(X) #undef X } String8 result = lo; switch ((type >> 4) & 0xF){ case PE_CoffSymbolTypeHi_NULL: break; case PE_CoffSymbolTypeHi_POINTER: result = str8_pushf(arena, "POINTER %S", lo); break; case PE_CoffSymbolTypeHi_FUNCTION: result = str8_pushf(arena, "FUNCTION %S", lo); break; case PE_CoffSymbolTypeHi_ARRAY: result = str8_pushf(arena, "ARRAY %S", lo); break; } return(result); } MR4TH_SYM_COMPTIME String8 pe_str8_from_coff_symbol_storage_class(PE_CoffSymbolStorageClass storage_class){ String8 result = str8_lit("ERROR"); switch (storage_class){ #define X(N,C) case C: result = str8_lit(#N); break; PE_CoffSymbolStorageClass_XList(X) #undef X } return(result); } MR4TH_SYM_COMPTIME String8 pe_str8_from_base_relocation_type(PE_BaseRelocationType type){ String8 result = str8_lit("ERROR"); switch (type){ #define X(N,C) case C: result = str8_lit(#N); break; PE_BaseRelocationType_XList(X) #undef X } return(result); } MR4TH_SYM_COMPTIME String8 pe_str8_from_debug_type(PE_DebugType debug_type){ String8 result = str8_lit("ERROR"); switch (debug_type){ #define X(N,C) case C: result = str8_lit(#N); break; PE_DebugType_XList(X) #undef X } return(result); }