diff --git a/src/coff/coff_enum.c b/src/coff/coff_enum.c index 9a8c2874..7636a78b 100644 --- a/src/coff/coff_enum.c +++ b/src/coff/coff_enum.c @@ -214,6 +214,35 @@ coff_string_from_section_flags(Arena *arena, COFF_SectionFlags flags) return result; } +internal String8 +coff_string_from_resource_memory_flags(Arena *arena, COFF_ResourceMemoryFlags flags) +{ + Temp scratch = scratch_begin(&arena, 1); + + String8List list = {0}; + + if (flags & COFF_ResourceMemoryFlag_Moveable) { + flags &= COFF_ResourceMemoryFlag_Moveable; + str8_list_pushf(scratch.arena, &list, "Moveable"); + } + if (flags & COFF_ResourceMemoryFlag_Pure) { + flags &= COFF_ResourceMemoryFlag_Pure; + str8_list_pushf(scratch.arena, &list, "Pure"); + } + if (flags & COFF_ResourceMemoryFlag_Discardable) { + flags &= COFF_ResourceMemoryFlag_Discardable; + str8_list_pushf(scratch.arena, &list, "Discardable"); + } + if (flags != 0) { + str8_list_pushf(scratch.arena, &list, "%#x", flags); + } + + String8 result = str8_list_join(arena, &list, &(StringJoin){.sep=str8_lit(", ")}); + + scratch_end(scratch); + return result; +} + internal String8 coff_string_from_import_header_type(COFF_ImportType type) { diff --git a/src/coff/coff_enum.h b/src/coff/coff_enum.h index a294b5a2..1ea360a7 100644 --- a/src/coff/coff_enum.h +++ b/src/coff/coff_enum.h @@ -9,6 +9,7 @@ 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_FileHeaderFlags flags); internal String8 coff_string_from_section_flags(Arena *arena, COFF_SectionFlags flags); +internal String8 coff_string_from_resource_memory_flags(Arena *arena, COFF_ResourceMemoryFlags flags); 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); diff --git a/src/raddump/raddump.c b/src/raddump/raddump.c index 9cab379d..479ffe1e 100644 --- a/src/raddump/raddump.c +++ b/src/raddump/raddump.c @@ -320,6 +320,8 @@ rd_format_preamble(Arena *arena, String8List *out, String8 indent, String8 input input_type_string = "COFF/PE"; } else if (rd_is_rdi(raw_data)) { input_type_string = "RDI"; + } else if (pe_is_res(raw_data)) { + input_type_string = "RES"; } DateTime universal_dt = os_now_universal_time(); @@ -6385,6 +6387,56 @@ coff_print_archive(Arena *arena, String8List *out, String8 indent, String8 raw_a scratch_end(scratch); } +internal String8 +coff_string_from_resource_id(Arena *arena, COFF_ResourceID id) +{ + String8 result = str8_zero(); + switch (id.type) { + case COFF_ResourceIDType_Null: result = str8_lit("\?\?\?"); break; + case COFF_ResourceIDType_Number: result = push_str8f(arena, "%u", id.u.number); break; + case COFF_ResourceIDType_String: result = id.u.string; break; + } + return result; +} + +internal void +coff_print_parsed_res(Arena *arena, String8List *out, String8 indent, COFF_ParsedResource *res) +{ + Temp scratch = scratch_begin(&arena, 1); + + String8 type; + if (res->type.type == COFF_ResourceIDType_Number) { + type = pe_resource_kind_to_string(res->type.u.number); + } else { + type = coff_string_from_resource_id(scratch.arena, res->type); + } + + String8 name = coff_string_from_resource_id(scratch.arena, res->name); + String8 flags = coff_string_from_resource_memory_flags(scratch.arena, res->memory_flags); + + rd_printf("Type: %S", type); + rd_printf("Name: %S", name); + rd_printf("Language ID: %u", res->language_id); + rd_printf("Data Version: %u", res->data_version); + rd_printf("Version: %u", res->version); + rd_printf("Memory Flags: %S", flags); + rd_printf("Data size: %u (bytes)", res->data.size); + + scratch_end(scratch); +} + +internal void +coff_print_res(Arena *arena, String8List *out, String8 indent, String8 raw_res) +{ + Temp scratch = scratch_begin(&arena, 1); + COFF_ParsedResourceList res_list = coff_resource_list_from_data(scratch.arena, raw_res); + for (COFF_ParsedResourceNode *n = res_list.first; n != 0; n = n->next) { + coff_print_parsed_res(arena, out, indent, &n->data); + rd_newline(); + } + scratch_end(scratch); +} + // MSVC CRT internal void diff --git a/src/raddump/raddump_main.c b/src/raddump/raddump_main.c index 11b876a5..98888163 100644 --- a/src/raddump/raddump_main.c +++ b/src/raddump/raddump_main.c @@ -276,7 +276,7 @@ entry_point(CmdLine *cmdline) } pe_print(arena, out, indent, raw_data, opts, rdi); } else if (pe_is_res(raw_data)) { - //tool_out_coff_res(stdout, file_data); + coff_print_res(arena, out, indent, raw_data); } exit:;