format file preamble and warn about unknown argument

This commit is contained in:
Nikita Smith
2024-12-09 17:16:44 -08:00
parent dd3b4a025d
commit cd3fd4df16
+79 -24
View File
@@ -42,11 +42,14 @@
//////////////////////////////// ////////////////////////////////
#define COFF_INDENT_WIDTH 4
#define COFF_INDENT_MAX 4096
#define coff_printf(f, ...) str8_list_pushf(arena, out, "%S" f, indent, __VA_ARGS__) #define coff_printf(f, ...) str8_list_pushf(arena, out, "%S" f, indent, __VA_ARGS__)
#define coff_newline() str8_list_pushf(arena, out, ""); #define coff_newline() str8_list_pushf(arena, out, "");
#define coff_errorf(f, ...) coff_printf("ERROR: "f, __VA_ARGS__) #define coff_errorf(f, ...) coff_printf("ERROR: "f, __VA_ARGS__)
#define coff_indent() indent.size += 4 #define coff_indent() do { if (indent.size + COFF_INDENT_WIDTH <= COFF_INDENT_MAX) { indent.size += COFF_INDENT_WIDTH; } else { Assert(!"indent overflow"); } } while (0)
#define coff_unindent() indent.size -= 4 #define coff_unindent() do { if (indent.size >= COFF_INDENT_WIDTH) { indent.size -= COFF_INDENT_WIDTH; } else { Assert(!"unbalanced indent"); } } while (0)
//////////////////////////////// ////////////////////////////////
@@ -1474,12 +1477,12 @@ pe_format_resources(Arena *arena, String8List *out, String8 indent, PE_ResourceD
if (stack) { if (stack) {
coff_printf("# Resources"); coff_printf("# Resources");
coff_indent();
// traverse resource tree // traverse resource tree
while (stack) { while (stack) {
if (stack->print_table) { if (stack->print_table) {
stack->print_table = 0; stack->print_table = 0;
coff_indent();
if (stack->is_named) { if (stack->is_named) {
coff_printf("[%u] %S { Time Stamp: %u, Version %u.%u Name Count: %u, ID Count %u, Characteristics: %u }", coff_printf("[%u] %S { Time Stamp: %u, Version %u.%u Name Count: %u, ID Count %u, Characteristics: %u }",
@@ -1530,11 +1533,10 @@ pe_format_resources(Arena *arena, String8List *out, String8 indent, PE_ResourceD
frame->curr_name_node = frame->table->named_list.first; frame->curr_name_node = frame->table->named_list.first;
frame->curr_id_node = frame->table->id_list.first; frame->curr_id_node = frame->table->id_list.first;
SLLStackPush(stack, frame); SLLStackPush(stack, frame);
coff_indent();
goto yield; goto yield;
} else if (res->kind == PE_ResDataKind_COFF_LEAF) { } else if (res->kind == PE_ResDataKind_COFF_LEAF) {
COFF_ResourceDataEntry *entry = &res->u.leaf; COFF_ResourceDataEntry *entry = &res->u.leaf;
coff_printf("[%u] %S Data VOFF: %#08X, Data Size: %#08X, Code Page: %u", coff_printf("[%u] %S Data VOFF: %#08x, Data Size: %#08x, Code Page: %u",
name_idx, res->id.u.string, entry->data_voff, entry->data_size, entry->code_page); name_idx, res->id.u.string, entry->data_voff, entry->data_size, entry->code_page);
} else { } else {
InvalidPath; InvalidPath;
@@ -1543,7 +1545,7 @@ pe_format_resources(Arena *arena, String8List *out, String8 indent, PE_ResourceD
while (stack->curr_id_node) { while (stack->curr_id_node) {
PE_ResourceNode *id_node = stack->curr_id_node; PE_ResourceNode *id_node = stack->curr_id_node;
PE_Resource *res = &id_node->data; PE_Resource *res = &id_node->data;
stack->curr_id_node = stack->curr_id_node->next; stack->curr_id_node = stack->curr_id_node->next;
U64 id_idx = stack->id_idx++; U64 id_idx = stack->id_idx++;
@@ -1556,27 +1558,27 @@ pe_format_resources(Arena *arena, String8List *out, String8 indent, PE_ResourceD
frame->curr_name_node = frame->table->named_list.first; frame->curr_name_node = frame->table->named_list.first;
frame->curr_id_node = frame->table->id_list.first; frame->curr_id_node = frame->table->id_list.first;
SLLStackPush(stack, frame); SLLStackPush(stack, frame);
coff_indent();
goto yield; goto yield;
} else if (res->kind == PE_ResDataKind_COFF_LEAF) { } else if (res->kind == PE_ResDataKind_COFF_LEAF) {
COFF_ResourceDataEntry *entry = &res->u.leaf; COFF_ResourceDataEntry *entry = &res->u.leaf;
coff_printf("[%u] ID: %u Data VOFF: %#08X, Data Size: %#08X, Code Page: %u", id_idx, res->id.u.number, entry->data_voff, entry->data_size, entry->code_page); coff_printf("[%u] ID: %u Data VOFF: %#08x, Data Size: %#08x, Code Page: %u", id_idx, res->id.u.number, entry->data_voff, entry->data_size, entry->code_page);
} else { } else {
InvalidPath; InvalidPath;
} }
} }
if (stack->curr_id_node == 0 && stack->curr_name_node == 0) {
coff_unindent();
}
SLLStackPop(stack); SLLStackPop(stack);
coff_unindent();
yield:; yield:;
} }
coff_unindent(); coff_newline();
} }
coff_newline();
scratch_end(scratch); scratch_end(scratch);
} }
@@ -2353,6 +2355,40 @@ exit:;
//////////////////////////////// ////////////////////////////////
internal void
format_preamble(Arena *arena, String8List *out, String8 indent, String8 input_path, String8 raw_data)
{
Temp scratch = scratch_begin(&arena, 1);
char *input_type_string = "???";
if (coff_is_archive(raw_data)) {
input_type_string = "Archive";
} else if (coff_is_thin_archive(raw_data)) {
input_type_string = "Thin Archive";
} else if (coff_is_big_obj(raw_data)) {
input_type_string = "Big Obj";
} else if (coff_is_obj(raw_data)) {
input_type_string = "Obj";
} else if (is_pe(raw_data)) {
input_type_string = "COFF/PE";
}
DateTime universal_dt = os_now_universal_time();
DateTime local_dt = os_local_time_from_universal(&universal_dt);
String8 time = push_date_time_string(scratch.arena, &local_dt);
coff_printf("# Input");
coff_indent();
coff_printf("Path: %S", input_path);
coff_printf("Type: %s", input_type_string);
coff_printf("Time: %S", time);
coff_unindent();
coff_newline();
scratch_end(scratch);
}
internal void internal void
entry_point(CmdLine *cmdline) entry_point(CmdLine *cmdline)
{ {
@@ -2361,15 +2397,25 @@ entry_point(CmdLine *cmdline)
// parse options // parse options
CoffdumpOption opts = 0; CoffdumpOption opts = 0;
{ {
for (U64 opt_idx = 0; opt_idx < ArrayCount(g_coffdump_option_map); ++opt_idx) { for (CmdLineOpt *cmd = cmdline->options.first; cmd != 0; cmd = cmd->next) {
String8 opt_name = str8_cstring(g_coffdump_option_map[opt_idx].name); CoffdumpOption opt = 0;
if (cmd_line_has_flag(cmdline, opt_name)) { for (U64 opt_idx = 0; opt_idx < ArrayCount(g_coffdump_option_map); ++opt_idx) {
opts |= g_coffdump_option_map[opt_idx].opt; String8 opt_name = str8_cstring(g_coffdump_option_map[opt_idx].name);
if (str8_match(cmd->string, opt_name, StringMatchFlag_CaseInsensitive)) {
opt = g_coffdump_option_map[opt_idx].opt;
break;
} else if (str8_match(cmd->string, str8_lit("all"), StringMatchFlag_CaseInsensitive)) {
opt = ~0ull & ~(CoffdumpOption_Help|CoffdumpOption_Version);
break;
}
} }
}
if (cmd_line_has_flag(cmdline, str8_lit("all"))) { if (opt == 0) {
opts = ~0ull; fprintf(stderr, "Unknown argument: \"%.*s\"\n", str8_varg(cmd->string));
opts &= ~(CoffdumpOption_Help|CoffdumpOption_Version); os_abort(1);
}
opts |= opt;
} }
} }
@@ -2384,7 +2430,7 @@ entry_point(CmdLine *cmdline)
// print version // print version
if (opts & CoffdumpOption_Version) { if (opts & CoffdumpOption_Version) {
fprintf(stdout, BUILD_TITLE_STRING_LITERAL "\n"); fprintf(stdout, BUILD_TITLE_STRING_LITERAL "\n");
fprintf(stdout, "\tCOFFDUMP <OPTIONS> <INPUTS>\n"); fprintf(stdout, "\tcoffdump <options> <inputs>\n");
os_abort(0); os_abort(0);
} }
@@ -2407,11 +2453,20 @@ entry_point(CmdLine *cmdline)
os_abort(1); os_abort(1);
} }
// make indent
String8 indent;
{
U64 indent_buffer_size = COFF_INDENT_WIDTH * COFF_INDENT_MAX;
U8 *indent_buffer = push_array(scratch.arena, U8, indent_buffer_size);
MemorySet(indent_buffer, ' ', indent_buffer_size);
indent = str8(indent_buffer, 0);
}
// format input // format input
String8List out = {0}; String8List out = {0};
{ {
String8 indent = str8_lit(" "); format_preamble(scratch.arena, &out, indent, file_path, raw_data);
indent.size = 0;
if (coff_is_archive(raw_data) || coff_is_thin_archive(raw_data)) { if (coff_is_archive(raw_data) || coff_is_thin_archive(raw_data)) {
coff_format_archive(scratch.arena, &out, indent, raw_data, opts); coff_format_archive(scratch.arena, &out, indent, raw_data, opts);
} else if (coff_is_big_obj(raw_data)) { } else if (coff_is_big_obj(raw_data)) {
@@ -2426,7 +2481,7 @@ entry_point(CmdLine *cmdline)
} }
// print formatted string // print formatted string
String8 out_string = str8_list_join(scratch.arena, &out, &(StringJoin){ .sep = str8_lit("\n"), .post = str8_lit("\n") }); String8 out_string = str8_list_join(scratch.arena, &out, &(StringJoin){ .sep = str8_lit("\n"),});
fprintf(stdout, "%.*s", str8_varg(out_string)); fprintf(stdout, "%.*s", str8_varg(out_string));
scratch_end(scratch); scratch_end(scratch);