c-scripting/src/binary/pe/mr4th_pe.c

278 lines
6.6 KiB
C

////////////////////////////////
// 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);
}