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
This commit is contained in:
Nikita Smith
2025-08-10 21:35:13 -07:00
parent 7466da1479
commit 2b02f5cec6
6 changed files with 42 additions and 40 deletions
+28 -26
View File
@@ -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;
}
+1 -1
View File
@@ -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
+4 -4
View File
@@ -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();
}
+2 -2
View File
@@ -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();
+1 -1
View File
@@ -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
+6 -6
View File
@@ -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; }