From 2b02f5cec6173bcfcabe5ae6fd7b0eeaf67bbc03 Mon Sep 17 00:00:00 2001 From: Nikita Smith Date: Sun, 10 Aug 2025 21:35:13 -0700 Subject: [PATCH] lifetime fixes - fully serialize the lib because we cannot guarantee that its members will have the same lifetime as the serialized lib - put import stub symbols on the symbol table arena --- src/coff/coff_lib_writer.c | 54 ++++++++++++++++++----------------- src/coff/coff_lib_writer.h | 2 +- src/linker/lnk.c | 8 +++--- src/pe/pe_make_export_table.c | 4 +-- src/pe/pe_make_export_table.h | 2 +- src/torture/torture.c | 12 ++++---- 6 files changed, 42 insertions(+), 40 deletions(-) diff --git a/src/coff/coff_lib_writer.c b/src/coff/coff_lib_writer.c index ad7fa781..d61f825c 100644 --- a/src/coff/coff_lib_writer.c +++ b/src/coff/coff_lib_writer.c @@ -165,7 +165,7 @@ coff_lib_writer_push_import(COFF_LibWriter *lib_writer, COFF_MachineType machine } } -internal String8List +internal String8 coff_lib_writer_serialize(Arena *arena, COFF_LibWriter *lib_writer, COFF_TimeStamp time_stamp, U16 mode, B32 emit_second_member) { Temp scratch = scratch_begin(&arena, 1); @@ -215,30 +215,30 @@ coff_lib_writer_serialize(Arena *arena, COFF_LibWriter *lib_writer, COFF_TimeSta member_offsets[member_idx] = member_data_list.total_size; String8 member_data = member->data; - String8 member_header = coff_make_lib_member_header(arena, name, time_stamp, 0, 0, mode, member_data.size); + String8 member_header = coff_make_lib_member_header(scratch.arena, name, time_stamp, 0, 0, mode, member_data.size); - str8_list_push(arena, &member_data_list, member_header); - str8_list_push(arena, &member_data_list, member_data); + str8_list_push(scratch.arena, &member_data_list, member_header); + str8_list_push(scratch.arena, &member_data_list, member_data); { U64 pad_size = AlignPadPow2(member_data_list.total_size, COFF_Archive_MemberAlign); - U8 *pad = push_array(arena, U8, pad_size); - str8_list_push(arena, &member_data_list, str8(pad, pad_size)); + U8 *pad = push_array(scratch.arena, U8, pad_size); + str8_list_push(scratch.arena, &member_data_list, str8(pad, pad_size)); } } } // long names member if (long_names_list.total_size) { - String8 header = coff_make_lib_member_header(arena, str8_lit("//"), time_stamp, 0, 0, mode, long_names_list.total_size); - String8 data = str8_list_join(arena, &long_names_list, 0); + String8 header = coff_make_lib_member_header(scratch.arena, str8_lit("//"), time_stamp, 0, 0, mode, long_names_list.total_size); + String8 data = str8_list_join(scratch.arena, &long_names_list, 0); U64 member_offset = member_data_list.total_size + data.size + header.size; { U64 pad_size = AlignPadPow2(member_offset, COFF_Archive_MemberAlign); - U8 *pad = push_array(arena, U8, pad_size); - str8_list_push_front(arena, &member_data_list, str8(pad, pad_size)); + U8 *pad = push_array(scratch.arena, U8, pad_size); + str8_list_push_front(scratch.arena, &member_data_list, str8(pad, pad_size)); } - str8_list_push_front(arena, &member_data_list, data); - str8_list_push_front(arena, &member_data_list, header); + str8_list_push_front(scratch.arena, &member_data_list, data); + str8_list_push_front(scratch.arena, &member_data_list, header); } // compute size for symbol string table @@ -310,17 +310,17 @@ coff_lib_writer_serialize(Arena *arena, COFF_LibWriter *lib_writer, COFF_TimeSta str8_list_push(scratch.arena, &second_member_data_list, str8_array(member_idx16_arr, symbols_count)); str8_list_push(scratch.arena, &second_member_data_list, str8(name_buffer, name_buffer_size)); - String8 member_data = str8_list_join(arena, &second_member_data_list, 0); - String8 member_header = coff_make_lib_member_header(arena, str8_lit("/"), time_stamp, 0, 0, mode, member_data.size); + String8 member_data = str8_list_join(scratch.arena, &second_member_data_list, 0); + String8 member_header = coff_make_lib_member_header(scratch.arena, str8_lit("/"), time_stamp, 0, 0, mode, member_data.size); U64 member_offset = member_data_list.total_size + member_data.size + member_header.size; { U64 pad_size = AlignPadPow2(member_offset, COFF_Archive_MemberAlign); - U8 *pad = push_array(arena, U8, pad_size); - str8_list_push_front(arena, &member_data_list, str8(pad, pad_size)); + U8 *pad = push_array(scratch.arena, U8, pad_size); + str8_list_push_front(scratch.arena, &member_data_list, str8(pad, pad_size)); } - str8_list_push_front(arena, &member_data_list, member_data); - str8_list_push_front(arena, &member_data_list, member_header); + str8_list_push_front(scratch.arena, &member_data_list, member_data); + str8_list_push_front(scratch.arena, &member_data_list, member_header); } // first linker member (obsolete, but kept for compatability reasons) @@ -343,23 +343,25 @@ coff_lib_writer_serialize(Arena *arena, COFF_LibWriter *lib_writer, COFF_TimeSta str8_list_push(scratch.arena, &first_member_data_list, str8_array(member_off32_arr, symbols_count)); str8_list_push(scratch.arena, &first_member_data_list, str8(name_buffer, name_buffer_size)); - String8 member_data = str8_list_join(arena, &first_member_data_list, 0); - String8 member_header = coff_make_lib_member_header(arena, str8_lit("/"), time_stamp, 0, 0, mode, member_data.size); + String8 member_data = str8_list_join(scratch.arena, &first_member_data_list, 0); + String8 member_header = coff_make_lib_member_header(scratch.arena, str8_lit("/"), time_stamp, 0, 0, mode, member_data.size); U64 member_offset = sizeof(g_coff_archive_sig) + member_header.size + member_data.size; { U64 pad_size = AlignPadPow2(member_offset, COFF_Archive_MemberAlign); - U8 *pad = push_array(arena, U8, pad_size); - str8_list_push_front(arena, &member_data_list, str8(pad, pad_size)); + U8 *pad = push_array(scratch.arena, U8, pad_size); + str8_list_push_front(scratch.arena, &member_data_list, str8(pad, pad_size)); } - str8_list_push_front(arena, &member_data_list, member_data); - str8_list_push_front(arena, &member_data_list, member_header); + str8_list_push_front(scratch.arena, &member_data_list, member_data); + str8_list_push_front(scratch.arena, &member_data_list, member_header); } // archive signature - str8_list_push_front(arena, &member_data_list, str8_struct(&g_coff_archive_sig)); + str8_list_push_front(scratch.arena, &member_data_list, str8_struct(&g_coff_archive_sig)); + + String8 raw_lib = str8_list_join(arena, &member_data_list, 0); scratch_end(scratch); - return member_data_list; + return raw_lib; } diff --git a/src/coff/coff_lib_writer.h b/src/coff/coff_lib_writer.h index 76b283c0..8a8c2327 100644 --- a/src/coff/coff_lib_writer.h +++ b/src/coff/coff_lib_writer.h @@ -63,7 +63,7 @@ internal COFF_LibWriter * coff_lib_writer_alloc(void); internal void coff_lib_writer_release(COFF_LibWriter **writer_ptr); internal U64 coff_lib_writer_push_obj(COFF_LibWriter *writer, String8 obj_path, String8 obj_data); internal void coff_lib_writer_push_import(COFF_LibWriter *lib_writer, COFF_MachineType machine, COFF_TimeStamp time_stamp, String8 dll_name, COFF_ImportByType import_by, String8 name, U16 hint_or_ordinal, COFF_ImportType import_type); -internal String8List coff_lib_writer_serialize(Arena *arena, COFF_LibWriter *lib_writer, COFF_TimeStamp time_stamp, U16 mode, B32 emit_second_member); +internal String8 coff_lib_writer_serialize(Arena *arena, COFF_LibWriter *lib_writer, COFF_TimeStamp time_stamp, U16 mode, B32 emit_second_member); #endif // COFF_LIB_WRITER_H diff --git a/src/linker/lnk.c b/src/linker/lnk.c index 54ee97a0..7d60727a 100644 --- a/src/linker/lnk.c +++ b/src/linker/lnk.c @@ -1394,8 +1394,8 @@ lnk_build_link_context(TP_Context *tp, TP_Arena *tp_arena, LNK_Config *config) // create import stubs (later replaced with acutal imports generated by linker) LNK_Symbol *import_stub = lnk_symbol_table_search(symtab, LNK_SymbolScope_Defined, str8_lit(LNK_IMPORT_STUB)); - LNK_Symbol *thunk_symbol = lnk_make_defined_symbol(scratch.arena, import_header.func_name, import_stub->u.defined.obj, import_stub->u.defined.symbol_idx); - LNK_Symbol *imp_symbol = lnk_make_defined_symbol(scratch.arena, push_str8f(scratch.arena, "__imp_%S", import_header.func_name), import_stub->u.defined.obj, import_stub->u.defined.symbol_idx); + LNK_Symbol *thunk_symbol = lnk_make_defined_symbol(symtab->arena->v[0], import_header.func_name, import_stub->u.defined.obj, import_stub->u.defined.symbol_idx); + LNK_Symbol *imp_symbol = lnk_make_defined_symbol(symtab->arena->v[0], push_str8f(scratch.arena, "__imp_%S", import_header.func_name), import_stub->u.defined.obj, import_stub->u.defined.symbol_idx); lnk_symbol_table_push(symtab, LNK_SymbolScope_Defined, thunk_symbol); lnk_symbol_table_push(symtab, LNK_SymbolScope_Defined, imp_symbol); @@ -4749,8 +4749,8 @@ lnk_run(TP_Context *tp, TP_Arena *arena, LNK_Config *config) ProfBegin("Build Import Library"); lnk_timer_begin(LNK_Timer_Lib); String8 linker_debug_symbols = lnk_make_linker_debug_symbols(scratch.arena, config->machine); - String8List lib_list = pe_make_import_lib(arena->v[0], config->machine, config->time_stamp, str8_skip_last_slash(config->image_name), linker_debug_symbols, config->export_symbol_list); - lnk_write_data_list_to_file_path(config->imp_lib_name, str8_zero(), lib_list); + String8 lib = pe_make_import_lib(arena->v[0], config->machine, config->time_stamp, str8_skip_last_slash(config->image_name), linker_debug_symbols, config->export_symbol_list); + lnk_write_data_to_file_path(config->imp_lib_name, str8_zero(), lib); lnk_timer_end(LNK_Timer_Lib); ProfEnd(); } diff --git a/src/pe/pe_make_export_table.c b/src/pe/pe_make_export_table.c index 761a61ae..6e47b3a0 100644 --- a/src/pe/pe_make_export_table.c +++ b/src/pe/pe_make_export_table.c @@ -324,7 +324,7 @@ pe_make_edata_obj(Arena *arena, return obj; } -internal String8List +internal String8 pe_make_import_lib(Arena *arena, COFF_MachineType machine, COFF_TimeStamp time_stamp, String8 dll_name, String8 debug_symbols, PE_ExportParseList export_list) { ProfBeginFunction(); @@ -354,7 +354,7 @@ pe_make_import_lib(Arena *arena, COFF_MachineType machine, COFF_TimeStamp time_s } // serialize lib - String8List lib = coff_lib_writer_serialize(arena, lib_writer, COFF_TimeStamp_Max, 0, /* emit second member: */ 1); + String8 lib = coff_lib_writer_serialize(arena, lib_writer, COFF_TimeStamp_Max, 0, /* emit second member: */ 1); coff_lib_writer_release(&lib_writer); ProfEnd(); diff --git a/src/pe/pe_make_export_table.h b/src/pe/pe_make_export_table.h index 3249d815..349007b8 100644 --- a/src/pe/pe_make_export_table.h +++ b/src/pe/pe_make_export_table.h @@ -57,6 +57,6 @@ typedef struct PE_FinalizedExports internal PE_ExportParsePtrArray pe_array_from_export_list(Arena *arena, PE_ExportParseList list); internal PE_ExportParseNode * pe_export_parse_list_push(Arena *arena, PE_ExportParseList *list, PE_ExportParse data); -internal String8List pe_make_import_lib(Arena *arena, COFF_MachineType machine, COFF_TimeStamp time_stamp, String8 dll_name, String8 debug_symbols, PE_ExportParseList export_list); +internal String8 pe_make_import_lib(Arena *arena, COFF_MachineType machine, COFF_TimeStamp time_stamp, String8 dll_name, String8 debug_symbols, PE_ExportParseList export_list); #endif // COFF_EXPORT_TABLE_H diff --git a/src/torture/torture.c b/src/torture/torture.c index ebbdb025..b7b960d3 100644 --- a/src/torture/torture.c +++ b/src/torture/torture.c @@ -2010,9 +2010,9 @@ t_simple_lib_test(void) { COFF_LibWriter *lib_writer = coff_lib_writer_alloc(); coff_lib_writer_push_obj(lib_writer, str8_lit("test.obj"), test_obj); - String8List test_lib = coff_lib_writer_serialize(scratch.arena, lib_writer, 0, 0, 1); + String8 test_lib = coff_lib_writer_serialize(scratch.arena, lib_writer, 0, 0, 1); coff_lib_writer_release(&lib_writer); - if (!t_write_file_list(test_lib_name, test_lib)) { + if (!t_write_file(test_lib_name, test_lib)) { goto exit; } } @@ -3304,9 +3304,9 @@ t_include(void) COFF_LibWriter *lib_writer = coff_lib_writer_alloc(); coff_lib_writer_push_obj(lib_writer, str8_lit("include.obj"), obj); - String8List lib = coff_lib_writer_serialize(scratch.arena, lib_writer, 0, 0, 1); + String8 lib = coff_lib_writer_serialize(scratch.arena, lib_writer, 0, 0, 1); coff_lib_writer_release(&lib_writer); - if (!t_write_file_list(str8_lit("include.lib"), lib)) { goto exit; } + if (!t_write_file(str8_lit("include.lib"), lib)) { goto exit; } } { @@ -3944,7 +3944,7 @@ t_opt_ref_dangling_section(void) coff_obj_writer_release(&obj_writer); } - String8List b_lib; + String8 b_lib; { COFF_LibWriter *lib_writer = coff_lib_writer_alloc(); coff_lib_writer_push_obj(lib_writer, str8_lit("b.obj"), b_obj); @@ -3954,7 +3954,7 @@ t_opt_ref_dangling_section(void) if (!t_write_file(str8_lit("entry.obj"), entry_obj)) { goto exit; } if (!t_write_file(str8_lit("a.obj"), a_obj)) { goto exit; } - if (!t_write_file_list(str8_lit("b.lib"), b_lib)) { goto exit; } + if (!t_write_file(str8_lit("b.lib"), b_lib)) { goto exit; } int linker_exit_code = t_invoke_linkerf("/subsystem:console /entry:entry /out:a.exe entry.obj a.obj b.lib"); if (linker_exit_code != 0) { goto exit; }