From 3a7afcd80c6ecd35bd0fed8266641ed191ca15a2 Mon Sep 17 00:00:00 2001 From: Nikita Smith Date: Thu, 8 May 2025 12:42:20 -0700 Subject: [PATCH] replace linker lib writer with one from COFF --- src/linker/lnk.c | 41 +++- src/linker/lnk.h | 4 + src/linker/lnk_lib.c | 468 ------------------------------------------ src/linker/lnk_lib.h | 83 +------- src/torture/torture.c | 12 ++ 5 files changed, 57 insertions(+), 551 deletions(-) diff --git a/src/linker/lnk.c b/src/linker/lnk.c index 975922b1..9eeff7bb 100644 --- a/src/linker/lnk.c +++ b/src/linker/lnk.c @@ -39,6 +39,7 @@ #include "coff/coff_enum.h" #include "coff/coff_parse.h" #include "coff/coff_obj_writer.h" +#include "coff/coff_lib_writer.h" #include "pe/pe.h" #include "codeview/codeview.h" #include "codeview/codeview_parse.h" @@ -56,6 +57,7 @@ #include "coff/coff_enum.c" #include "coff/coff_parse.c" #include "coff/coff_obj_writer.c" +#include "coff/coff_lib_writer.c" #include "pe/pe.c" #include "codeview/codeview.c" #include "codeview/codeview_enum.c" @@ -3077,6 +3079,43 @@ lnk_build_win32_image(TP_Arena *arena, TP_Context *tp, LNK_Config *config, LNK_S return image_data; } +internal String8List +lnk_build_import_lib(Arena *arena, COFF_MachineType machine, COFF_TimeStamp time_stamp, String8 dll_name, LNK_ExportTable *exptab) +{ + ProfBeginFunction(); + Temp scratch = scratch_begin(&arena, 1); + + dll_name = str8_skip_last_slash(dll_name); + + // These objects appear in first three members of any lib that linker produces with /dll. + // Objects are used by MSVC linker to build import table. + String8 import_entry_obj = lnk_build_import_entry_obj(scratch.arena, dll_name, time_stamp, machine); + String8 null_import_descriptor_obj = lnk_build_null_import_descriptor_obj(scratch.arena, time_stamp, machine); + String8 null_thunk_data_obj = lnk_build_null_thunk_data_obj(scratch.arena, dll_name, time_stamp, machine); + + COFF_LibWriter *lib_writer = coff_lib_writer_alloc(); + coff_lib_writer_push_obj(lib_writer, dll_name, import_entry_obj); + coff_lib_writer_push_obj(lib_writer, dll_name, null_import_descriptor_obj); + coff_lib_writer_push_obj(lib_writer, dll_name, null_thunk_data_obj); + + KeyValuePair *raw_export_arr = key_value_pairs_from_hash_table(scratch.arena, exptab->name_export_ht); + for (U64 i = 0; i < exptab->name_export_ht->count; ++i) { + LNK_Export *exp = raw_export_arr[i].value_raw; + if (exp->name.size) { + coff_lib_writer_push_export_by_name(lib_writer, machine, time_stamp, dll_name, exp->type, exp->name, safe_cast_u16(exp->id)); + } else { + coff_lib_writer_push_export_by_ordinal(lib_writer, machine, time_stamp, dll_name, exp->type, exp->ordinal); + } + } + + String8List lib = coff_lib_writer_serialize(arena, lib_writer, COFF_TimeStamp_Max, 0, /* emit second member: */ 1); + coff_lib_writer_release(&lib_writer); + + scratch_end(scratch); + ProfEnd(); + return lib; +} + //////////////////////////////// internal @@ -4304,7 +4343,7 @@ lnk_run(int argc, char **argv) case State_BuildImpLib: { ProfBegin("Build Imp Lib"); lnk_timer_begin(LNK_Timer_Lib); - String8List lib_list = lnk_build_import_lib(tp, tp_arena, config->machine, config->time_stamp, config->imp_lib_name, config->image_name, exptab); + String8List lib_list = lnk_build_import_lib(tp_arena->v[0], config->machine, config->time_stamp, config->image_name, exptab); lnk_write_data_list_to_file_path(config->imp_lib_name, str8_zero(), lib_list); lnk_timer_end(LNK_Timer_Lib); ProfEnd(); diff --git a/src/linker/lnk.h b/src/linker/lnk.h index 3977a20c..2f2ef39f 100644 --- a/src/linker/lnk.h +++ b/src/linker/lnk.h @@ -192,6 +192,10 @@ internal String8List lnk_build_base_relocs(TP_Context *tp, TP_Arena *tp_temp, LN internal String8List lnk_build_win32_image_header(Arena *arena, LNK_SymbolTable *symtab, LNK_Config *config, LNK_SectionArray sect_arr, U64 expected_image_header_size); internal String8 lnk_build_win32_image(TP_Arena *arena, TP_Context *tp, LNK_Config *config, LNK_SymbolTable *symtab, LNK_ExportTable *exptab, LNK_ObjList obj_list); +// --- Import Lib -------------------------------------------------------------- + +internal String8List lnk_build_import_lib(Arena *arena, COFF_MachineType machine, COFF_TimeStamp time_stamp, String8 dll_name, LNK_ExportTable *exptab); + // --- Logger ------------------------------------------------------------------ internal void lnk_log_link_stats(LNK_ObjList obj_list, LNK_LibList *lib_index, LNK_SectionTable *sectab); diff --git a/src/linker/lnk_lib.c b/src/linker/lnk_lib.c index 22aad6c8..a04e6961 100644 --- a/src/linker/lnk_lib.c +++ b/src/linker/lnk_lib.c @@ -15,85 +15,6 @@ lnk_lib_list_reserve(Arena *arena, LNK_LibList *list, U64 count) return arr; } -internal LNK_LibMemberNode * -lnk_lib_member_list_push(Arena *arena, LNK_LibMemberList *list, LNK_LibMember member) -{ - LNK_LibMemberNode *n = push_array_no_zero(arena, LNK_LibMemberNode, 1); - n->next = 0; - n->data = member; - - SLLQueuePush(list->first, list->last, n); - ++list->count; - - return n; -} - -internal LNK_LibMember * -lnk_lib_member_array_from_list(Arena *arena, LNK_LibMemberList list) -{ - ProfBeginFunction(); - LNK_LibMember *arr = push_array_no_zero(arena, LNK_LibMember, list.count); - LNK_LibMember *ptr = arr; - for (LNK_LibMemberNode *i = list.first; i != 0; i = i->next, ptr += 1) { - ptr->name = push_str8_copy(arena, i->data.name); - ptr->data = push_str8_copy(arena, i->data.data); - } - ProfEnd(); - return arr; -} - -internal LNK_LibSymbolNode * -lnk_lib_symbol_list_push(Arena *arena, LNK_LibSymbolList *list, LNK_LibSymbol symbol) -{ - LNK_LibSymbolNode *n = push_array_no_zero(arena, LNK_LibSymbolNode, 1); - n->next = 0; - n->data = symbol; - - SLLQueuePush(list->first, list->last, n); - ++list->count; - - return n; -} - -internal LNK_LibSymbol * -lnk_lib_symbol_array_from_list(Arena *arena, LNK_LibSymbolList list) -{ - LNK_LibSymbol *arr = push_array_no_zero(arena, LNK_LibSymbol, list.count + 2); - LNK_LibSymbol *ptr = arr + 1; - for (LNK_LibSymbolNode *i = list.first; i != 0; i = i->next, ptr += 1) { - ptr->name = push_str8_copy(arena, i->data.name); - ptr->member_idx = i->data.member_idx; - } - MemoryZeroStruct(&arr[0]); - MemoryZeroStruct(&arr[list.count+1]); - return arr; -} - -int -lnk_lib_symbol_name_compar(const void *raw_a, const void *raw_b) -{ - const LNK_Symbol *sa = (const LNK_Symbol *)raw_a; - const LNK_Symbol *sb = (const LNK_Symbol *)raw_b; - return str8_compar_case_sensitive(&sa->name, &sb->name); -} - -int -lnk_lib_symbol_name_compar_is_before(void *raw_a, void *raw_b) -{ - int compar = lnk_lib_symbol_name_compar(raw_a, raw_b); - int is_before = compar < 0; - return is_before; -} - -internal void -lnk_lib_symbol_array_sort(LNK_LibSymbol *arr, U64 count) -{ - Assert(count >= 2); - radsort(arr + 1, count - 2, lnk_lib_symbol_name_compar_is_before); -} - -//////////////////////////////// - internal LNK_Lib lnk_lib_from_data(Arena *arena, String8 data, String8 path) { @@ -208,395 +129,6 @@ lnk_lib_list_push_parallel(TP_Context *tp, TP_Arena *arena, LNK_LibList *list, S return arr; } -//////////////////////////////// - -internal LNK_LibWriter * -lnk_lib_writer_alloc(void) -{ - Arena *arena = arena_alloc(); - LNK_LibWriter *writer = push_array(arena, LNK_LibWriter, 1); - writer->arena = arena; - return writer; -} - -internal void -lnk_lib_writer_release(LNK_LibWriter **writer_ptr) -{ - arena_release((*writer_ptr)->arena); - *writer_ptr = 0; -} - -internal void -lnk_lib_writer_push_obj(LNK_LibWriter *writer, LNK_Obj *obj) -{ - ProfBeginFunction(); - - U64 member_idx = writer->member_list.count; - - // push obj member - LNK_LibMember member = {0}; - member.name = obj->path; - member.data = obj->data; - lnk_lib_member_list_push(writer->arena, &writer->member_list, member); - - // push external symbols - { - COFF_FileHeaderInfo coff_info = coff_file_header_info_from_data(obj->data); - String8 string_table = str8_substr(obj->data, coff_info.string_table_range); - String8 symbol_table = str8_substr(obj->data, coff_info.symbol_table_range); - - COFF_ParsedSymbol symbol; - for (U64 symbol_idx = 0; symbol_idx < coff_info.symbol_count; symbol_idx += (1 + symbol.aux_symbol_count)) { - void *symbol_ptr; - if (coff_info.is_big_obj) { - symbol_ptr = &((COFF_Symbol32 *)symbol_table.str)[symbol_idx]; - symbol = coff_parse_symbol32(string_table, symbol_ptr); - } else { - symbol_ptr = &((COFF_Symbol16 *)symbol_table.str)[symbol_idx]; - symbol = coff_parse_symbol16(string_table, symbol_ptr); - } - - COFF_SymbolValueInterpType interp = coff_interp_symbol(symbol.section_number, symbol.value, symbol.storage_class); - if (interp == COFF_SymbolValueInterp_Regular) { - if (symbol.storage_class == COFF_SymStorageClass_External) { - LNK_LibSymbol lib_symbol = {0}; - lib_symbol.name = symbol.name; - lib_symbol.member_idx = member_idx; - lnk_lib_symbol_list_push(writer->arena, &writer->symbol_list, lib_symbol); - } - } - } - } - - ProfEnd(); -} - -internal void -lnk_lib_writer_push_export(LNK_LibWriter *writer, COFF_MachineType machine, U64 time_stamp, String8 dll_name, LNK_Export *exp) -{ - ProfBeginFunction(); - - U64 member_idx = writer->member_list.count; - - // make import header - String8 import_data; - if (exp->name.size) { - U16 hint = safe_cast_u16(exp->id); - import_data = coff_make_import_header_by_name(writer->arena, dll_name, machine, time_stamp, exp->name, hint, exp->type); - } else { - U16 ordinal = safe_cast_u16(exp->id); - import_data = coff_make_import_header_by_ordinal(writer->arena, dll_name, machine, time_stamp, ordinal, exp->type); - } - - // push import member - LNK_LibMember member = {0}; - member.name = dll_name; - member.data = import_data; - lnk_lib_member_list_push(writer->arena, &writer->member_list, member); - - switch (exp->type) { - case COFF_ImportHeader_Code: { - LNK_LibSymbol def_symbol = {0}; - def_symbol.name = push_str8_copy(writer->arena, exp->name); - def_symbol.member_idx = member_idx; - lnk_lib_symbol_list_push(writer->arena, &writer->symbol_list, def_symbol); - } - case COFF_ImportHeader_Data: { - LNK_LibSymbol imp_symbol = {0}; - imp_symbol.name = push_str8f(writer->arena, "__imp_%S", exp->name); - imp_symbol.member_idx = member_idx; - lnk_lib_symbol_list_push(writer->arena, &writer->symbol_list, imp_symbol); - } break; - case COFF_ImportHeader_Const: { - NotImplemented; - } break; - default: InvalidPath; - } - - ProfEnd(); -} - -internal LNK_LibBuild -lnk_lib_build_from_writer(Arena *arena, LNK_LibWriter *writer) -{ - ProfBeginFunction(); - - LNK_LibBuild lib = {0}; - lib.symbol_count = writer->symbol_list.count + 2; - lib.member_count = writer->member_list.count; - lib.symbol_array = lnk_lib_symbol_array_from_list(arena, writer->symbol_list); - lib.member_array = lnk_lib_member_array_from_list(arena, writer->member_list); - lnk_lib_symbol_array_sort(lib.symbol_array, lib.symbol_count); - - ProfEnd(); - return lib; -} - -internal String8List -lnk_coff_archive_from_lib_build(Arena *arena, LNK_LibBuild *lib, B32 emit_second_member, COFF_TimeStamp time_stamp, U32 mode) -{ - ProfBeginFunction(); - - Temp scratch = scratch_begin(&arena, 1); - - U64 symbol_count = lib->symbol_count - 2; - LNK_LibSymbol *symbol_arr = lib->symbol_array + 1; - - HashTable *name_ht = hash_table_init(scratch.arena, 1024); - U64 *member_off_arr = push_array_no_zero(scratch.arena, U64, lib->member_count); - String8List long_names_list = {0}; - String8List member_data_list = {0}; - - for (U64 member_idx = 0; member_idx < lib->member_count; member_idx += 1) { - LNK_LibMember *member = &lib->member_array[member_idx]; - - // make member name - String8 name; - U64 name_with_slash_size = member->name.size + 1; - if (name_with_slash_size > COFF_Archive_MaxShortNameSize) { - // have we seen this member name before? - KeyValuePair *is_present = hash_table_search_string(name_ht, member->name); - if (is_present) { - name = is_present->value_string; - } else { - name = push_str8f(scratch.arena, "/%u", long_names_list.total_size); - str8_list_pushf(scratch.arena, &long_names_list, "%S/\n", member->name); - hash_table_push_string_string(scratch.arena, name_ht, member->name, name); - } - } else { - name = push_str8f(scratch.arena, "%S/", member->name); - } - - member_off_arr[member_idx] = member_data_list.total_size; - - String8 member_data = member->data; - String8 member_header = lnk_build_lib_member_header(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_pad(arena, &member_data_list, member_data_list.total_size, COFF_Archive_MemberAlign); - } - - // long names member - if (long_names_list.total_size > 0) { - String8 header = lnk_build_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); - U64 member_offset = member_data_list.total_size + data.size + header.size; - str8_list_push_pad_front(arena, &member_data_list, member_offset, COFF_Archive_MemberAlign); - str8_list_push_front(arena, &member_data_list, data); - str8_list_push_front(arena, &member_data_list, header); - } - - // compute size for symbol string table - U32 name_buffer_size = 0; - for (LNK_LibSymbol *ptr = &symbol_arr[0], *opl = ptr + symbol_count; ptr < opl; ptr += 1) { - name_buffer_size += ptr->name.size; - name_buffer_size += 1; // null - } - - // write symbol name buffer - U8 *name_buffer = push_array_no_zero(scratch.arena, U8, name_buffer_size); - { - U64 name_cursor = 0; - for (LNK_LibSymbol *ptr = &symbol_arr[0], *opl = ptr + symbol_count; ptr < opl; ptr += 1) { - MemoryCopy(name_buffer + name_cursor, ptr->name.str, ptr->name.size); - name_buffer[name_cursor + ptr->name.size] = '\0'; - name_cursor += ptr->name.size + 1; - } - } - - U64 member_base_off; - { - U64 sizeof_first_header = sizeof(COFF_ArchiveMemberHeader) + sizeof(U32) + sizeof(U32) * symbol_count + name_buffer_size; - U64 sizeof_second_header = sizeof(COFF_ArchiveMemberHeader) + sizeof(U32) + sizeof(U32) * lib->member_count + sizeof(U32) + sizeof(U16) * symbol_count + name_buffer_size; - U64 sizeof_long_names = sizeof(COFF_ArchiveMemberHeader) + long_names_list.total_size; - - sizeof_first_header = AlignPow2(sizeof_first_header, COFF_Archive_MemberAlign); - sizeof_second_header = AlignPow2(sizeof_second_header, COFF_Archive_MemberAlign); - sizeof_long_names = AlignPow2(sizeof_long_names, COFF_Archive_MemberAlign); - - member_base_off = sizeof(g_coff_archive_sig); - member_base_off += sizeof_first_header; - if (emit_second_member) { - member_base_off += sizeof_second_header; - } - if (long_names_list.total_size > 0) { - member_base_off += sizeof_long_names; - } - } - - // second linker member - if (emit_second_member) { - U32 member_count32 = safe_cast_u32(lib->member_count); - U32 symbol_count32 = safe_cast_u32(symbol_count); - - U32 *member_off32_arr = push_array_no_zero(scratch.arena, U32, lib->member_count); - U16 *member_idx16_arr = push_array_no_zero(scratch.arena, U16, symbol_count); - - // write member offset array - for (U64 member_idx = 0; member_idx < lib->member_count; member_idx += 1) { - U64 member_off = member_base_off + member_off_arr[member_idx]; - U32 member_off32 = safe_cast_u32(member_off); - member_off32_arr[member_idx] = member_off32; - } - - // write member offset indices for each symbol - for (U64 symbol_idx = 0; symbol_idx < symbol_count; symbol_idx += 1) { - // member offset indices are 1-based - U64 member_idx = symbol_arr[symbol_idx].member_idx + 1; - U16 member_idx16 = safe_cast_u16(member_idx); - member_idx16_arr[symbol_idx] = member_idx16; - } - - // layout second member data - String8List second_member_data_list = {0}; - str8_list_push(scratch.arena, &second_member_data_list, str8_struct(&member_count32)); - str8_list_push(scratch.arena, &second_member_data_list, str8_array(member_off32_arr, lib->member_count)); - str8_list_push(scratch.arena, &second_member_data_list, str8_struct(&symbol_count32)); - str8_list_push(scratch.arena, &second_member_data_list, str8_array(member_idx16_arr, symbol_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 = lnk_build_lib_member_header(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; - str8_list_push_pad_front(arena, &member_data_list, member_offset, COFF_Archive_MemberAlign); - str8_list_push_front(arena, &member_data_list, member_data); - str8_list_push_front(arena, &member_data_list, member_header); - } - - // first linker member (obsolete, but kept for compatability reasons) - { - U32 symbol_count_be = from_be_u32(symbol_count); - U32 *member_off32_arr = push_array_no_zero(scratch.arena, U32, symbol_count); - - for (U64 symbol_idx = 0; symbol_idx < symbol_count; symbol_idx += 1) { - LNK_LibSymbol *symbol = &symbol_arr[symbol_idx]; - - // write big endian member offset - U64 member_off = member_base_off + member_off_arr[symbol->member_idx]; - U32 member_off32 = from_be_u32(safe_cast_u32(member_off)); - member_off32_arr[symbol_idx] = member_off32; - } - - // layout first member data - String8List first_member_data_list = {0}; - str8_list_push(scratch.arena, &first_member_data_list, str8_struct(&symbol_count_be)); - str8_list_push(scratch.arena, &first_member_data_list, str8_array(member_off32_arr, symbol_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 = lnk_build_lib_member_header(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; - str8_list_push_pad_front(arena, &member_data_list, member_offset, COFF_Archive_MemberAlign); - str8_list_push_front(arena, &member_data_list, member_data); - str8_list_push_front(arena, &member_data_list, member_header); - } - - // archive signature - str8_list_push_front(arena, &member_data_list, str8_struct(&g_coff_archive_sig)); - - scratch_end(scratch); - ProfEnd(); - return member_data_list; -} - -//////////////////////////////// - -internal LNK_LibBuild -lnk_build_lib(Arena *arena, COFF_MachineType machine, COFF_TimeStamp time_stamp, String8 dll_name, LNK_ObjList obj_list, LNK_ExportTable *exptab) -{ - ProfBeginFunction(); - Temp scratch = scratch_begin(&arena, 1); - - LNK_LibWriter *writer = lnk_lib_writer_alloc(); - for (LNK_ObjNode *obj_node = obj_list.first; obj_node != 0; obj_node = obj_node->next) { - lnk_lib_writer_push_obj(writer, &obj_node->data); - } - - KeyValuePair *raw_export_arr = key_value_pairs_from_hash_table(scratch.arena, exptab->name_export_ht); - for (U64 i = 0; i < exptab->name_export_ht->count; ++i) { - LNK_Export *exp = raw_export_arr[i].value_raw; - lnk_lib_writer_push_export(writer, machine, time_stamp, dll_name, exp); - } - LNK_LibBuild lib = lnk_lib_build_from_writer(arena, writer); - lnk_lib_writer_release(&writer); - - scratch_end(scratch); - ProfEnd(); - return lib; -} - -internal String8 -lnk_build_lib_member_header(Arena *arena, String8 name, COFF_TimeStamp time_stamp, U16 user_id, U16 group_id, U16 mode, U32 size) -{ - ProfBeginFunction(); - - Assert(name.size < 16); - Assert(user_id < 10000); - Assert(group_id < 10000); - Assert(mode < 10000); - Assert(size < 1000000000); - - //U64 sizeof_member_header = /* name */ 16 + /* time */ 12 + /* user_id */ 6 + /* group id */ 6 + /* mode */ 8 + /* size */ 10; - - Temp scratch = scratch_begin(&arena, 1); - String8List list = {0}; - str8_list_pushf(scratch.arena, &list, "%-16.*s", str8_varg(name)); - str8_list_pushf(scratch.arena, &list, "%-12u", time_stamp); - str8_list_pushf(scratch.arena, &list, "%-6u", user_id); - str8_list_pushf(scratch.arena, &list, "%-6u", group_id); - str8_list_pushf(scratch.arena, &list, "%-8u", mode); - str8_list_pushf(scratch.arena, &list, "%-10u", size); - str8_list_pushf(scratch.arena, &list, "`\n"); - String8 result = str8_list_join(arena, &list, 0); - - Assert(result.size == sizeof(COFF_ArchiveMemberHeader)); - scratch_end(scratch); - ProfEnd(); - return result; -} - -internal String8List -lnk_build_import_lib(TP_Context *tp, TP_Arena *arena, COFF_MachineType machine, COFF_TimeStamp time_stamp, String8 lib_name, String8 dll_name, LNK_ExportTable *exptab) -{ - ProfBeginFunction(); - Temp scratch = scratch_begin(arena->v, arena->count); - - dll_name = str8_skip_last_slash(dll_name); - - // These objects appear in first three members of any lib that linker produces with /dll. - // Objects are used by MSVC linker to build import table. - String8 import_obj_array[3]; - import_obj_array[0] = lnk_build_import_entry_obj(scratch.arena, dll_name, time_stamp, machine); - import_obj_array[1] = lnk_build_null_import_descriptor_obj(scratch.arena, time_stamp, machine); - import_obj_array[2] = lnk_build_null_thunk_data_obj(scratch.arena, dll_name, time_stamp, machine); - - // build input list - LNK_InputObjList input_obj_list = {0}; - for (U64 i = 0; i < ArrayCount(import_obj_array); ++i) { - LNK_InputObj *input = lnk_input_obj_list_push(scratch.arena, &input_obj_list); - input->data = import_obj_array[i]; - input->path = dll_name; - input->lib_path = lib_name; - } - - LNK_InputObj **inputs = lnk_array_from_input_obj_list(scratch.arena, input_obj_list); - LNK_ObjList obj_list = {0}; - lnk_obj_list_push_parallel(tp, arena, &obj_list, machine, input_obj_list.count, inputs); - - LNK_LibBuild import_lib = lnk_build_lib(scratch.arena, machine, time_stamp, dll_name, obj_list, exptab); - B32 emit_second_member = 1; - String8List coff_archive_data = lnk_coff_archive_from_lib_build(arena->v[0], &import_lib, emit_second_member, COFF_TimeStamp_Max, 0); - - // cleanup memory - scratch_end(scratch); - - ProfEnd(); - return coff_archive_data; -} - internal THREAD_POOL_TASK_FUNC(lnk_push_lib_symbols_task) { diff --git a/src/linker/lnk_lib.h b/src/linker/lnk_lib.h index 6b3f2cb9..c15d0687 100644 --- a/src/linker/lnk_lib.h +++ b/src/linker/lnk_lib.h @@ -36,61 +36,6 @@ typedef struct LNK_LibList //////////////////////////////// -typedef struct LNK_LibMember -{ - String8 name; - String8 data; -} LNK_LibMember; - -typedef struct LNK_LibMemberNode -{ - struct LNK_LibMemberNode *next; - LNK_LibMember data; -} LNK_LibMemberNode; - -typedef struct LNK_LibMemberList -{ - U64 count; - LNK_LibMemberNode *first; - LNK_LibMemberNode *last; -} LNK_LibMemberList; - -typedef struct LNK_LibSymbol -{ - String8 name; - U64 member_idx; -} LNK_LibSymbol; - -typedef struct LNK_LibSymbolNode -{ - struct LNK_LibSymbolNode *next; - LNK_LibSymbol data; -} LNK_LibSymbolNode; - -typedef struct LNK_LibSymbolList -{ - U64 count; - LNK_LibSymbolNode *first; - LNK_LibSymbolNode *last; -} LNK_LibSymbolList; - -typedef struct LNK_LibWriter -{ - Arena *arena; - LNK_LibMemberList member_list; - LNK_LibSymbolList symbol_list; -} LNK_LibWriter; - -typedef struct LNK_LibBuild -{ - U64 symbol_count; - U64 member_count; - LNK_LibSymbol *symbol_array; - LNK_LibMember *member_array; -} LNK_LibBuild; - -//////////////////////////////// - typedef struct { LNK_LibNode *node_arr; @@ -101,32 +46,6 @@ typedef struct //////////////////////////////// -internal LNK_LibNode * lnk_lib_list_reserve(Arena *arena, LNK_LibList *list, U64 count); -internal LNK_LibMemberNode * lnk_lib_member_list_push(Arena *arena, LNK_LibMemberList *list, LNK_LibMember member); -internal LNK_LibMember * lnk_lib_member_array_from_list(Arena *arena, LNK_LibMemberList list); -internal LNK_LibSymbolNode * lnk_lib_symbol_list_push(Arena *arena, LNK_LibSymbolList *list, LNK_LibSymbol symbol); - -internal LNK_LibSymbol * lnk_lib_symbol_array_from_list(Arena *arena, LNK_LibSymbolList list); -internal void lnk_lib_symbol_array_sort(LNK_LibSymbol *arr, U64 count); - -//////////////////////////////// - -internal LNK_Lib lnk_lib_from_data(Arena *arena, String8 data, String8 path); - +internal LNK_Lib lnk_lib_from_data(Arena *arena, String8 data, String8 path); internal LNK_LibNodeArray lnk_lib_list_push_parallel(TP_Context *tp, TP_Arena *arena, LNK_LibList *list, String8Array data_arr, String8Array path_arr); -//////////////////////////////// - -internal LNK_LibWriter * lnk_lib_writer_alloc(void); -internal void lnk_lib_writer_release(LNK_LibWriter **writer_ptr); -internal void lnk_lib_writer_push_obj(LNK_LibWriter *writer, LNK_Obj *obj); -internal void lnk_lib_writer_push_export(LNK_LibWriter *writer, COFF_MachineType machine, U64 time_stamp, String8 dll_name, LNK_Export *exp); -internal LNK_LibBuild lnk_lib_build_from_writer(Arena *arena, LNK_LibWriter *writer); -internal String8List lnk_coff_archive_from_lib_build(Arena *arena, LNK_LibBuild *lib, B32 emit_second_member, COFF_TimeStamp time_stamp, U32 mode); - -//////////////////////////////// - -internal LNK_LibBuild lnk_build_lib(Arena *arena, COFF_MachineType machine, COFF_TimeStamp time_stamp, String8 dll_name, LNK_ObjList obj_list, LNK_ExportTable *exptab); -internal String8 lnk_build_lib_member_header(Arena *arena, String8 name, COFF_TimeStamp time_stamp, U16 user_id, U16 group_id, U16 mode, U32 size); -internal String8List lnk_build_import_lib(TP_Context *tp, TP_Arena *arena, COFF_MachineType machine, COFF_TimeStamp time_stamp, String8 lib_name, String8 dll_name, LNK_ExportTable *exptab); - diff --git a/src/torture/torture.c b/src/torture/torture.c index 1a9a9f19..f92259d8 100644 --- a/src/torture/torture.c +++ b/src/torture/torture.c @@ -9,21 +9,33 @@ //////////////////////////////// +#include "third_party/xxHash/xxhash.c" +#include "third_party/xxHash/xxhash.h" +#include "third_party/radsort/radsort.h" + +//////////////////////////////// + #include "base/base_inc.h" #include "os/os_inc.h" +#include "path/path.h" #include "coff/coff.h" #include "coff/coff_enum.h" #include "coff/coff_parse.h" #include "coff/coff_obj_writer.h" +#include "coff/coff_lib_writer.h" #include "pe/pe.h" +#include "linker/hash_table.h" #include "base/base_inc.c" #include "os/os_inc.c" +#include "path/path.c" #include "coff/coff.c" #include "coff/coff_enum.c" #include "coff/coff_parse.c" #include "coff/coff_obj_writer.c" +#include "coff/coff_lib_writer.c" #include "pe/pe.c" +#include "linker/hash_table.c" #include "linker/lnk_cmd_line.h" #include "linker/lnk_cmd_line.c"