278 lines
6.6 KiB
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);
|
|
}
|