diff --git a/src/linker/lnk.c b/src/linker/lnk.c index ca0cc77e..dbac54f8 100644 --- a/src/linker/lnk.c +++ b/src/linker/lnk.c @@ -1358,8 +1358,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 *thunk_symbol = lnk_make_import_symbol(scratch.arena, import_header.func_name, input->data.coff_import); LNK_Symbol *imp_symbol = lnk_make_import_symbol(scratch.arena, push_str8f(scratch.arena, "__imp_%S", import_header.func_name), input->data.coff_import); - lnk_symbol_table_push(symtab, thunk_symbol); - lnk_symbol_table_push(symtab, imp_symbol); + lnk_symbol_table_push(symtab, LNK_SymbolScope_Import, thunk_symbol); + lnk_symbol_table_push(symtab, LNK_SymbolScope_Import, imp_symbol); // pick imports hash table HashTable *imports_ht; diff --git a/src/linker/lnk_debug_info.c b/src/linker/lnk_debug_info.c index f19dff44..ecb147c3 100644 --- a/src/linker/lnk_debug_info.c +++ b/src/linker/lnk_debug_info.c @@ -3037,7 +3037,6 @@ THREAD_POOL_TASK_FUNC(lnk_build_pdb_public_symbols_defined_task) for (U64 i = 0, node_idx = 0; i < chunk->count; ++i) { LNK_Symbol *symbol = chunk->v[i].symbol; - Assert(symbol->type == LNK_Symbol_Defined); COFF_ParsedSymbol parsed_symbol = lnk_parsed_symbol_from_coff_symbol_idx(symbol->u.defined.obj, symbol->u.defined.symbol_idx); COFF_SymbolValueInterpType interp = coff_interp_symbol(parsed_symbol.section_number, parsed_symbol.value, parsed_symbol.storage_class); diff --git a/src/linker/lnk_lib.c b/src/linker/lnk_lib.c index c3ec1625..14d69774 100644 --- a/src/linker/lnk_lib.c +++ b/src/linker/lnk_lib.c @@ -199,8 +199,7 @@ THREAD_POOL_TASK_FUNC(lnk_push_lib_symbols_task) String8Node *name_node = lib->symbol_name_list.first; for (U64 symbol_idx = 0; symbol_idx < lib->symbol_count; ++symbol_idx, name_node = name_node->next) { LNK_Symbol *symbol = lnk_make_lib_symbol(arena, name_node->string, lib, lib->member_off_arr[symbol_idx]); - U64 hash = lnk_symbol_hash(symbol->name); - lnk_symbol_table_push_(symtab, arena, worker_id, LNK_SymbolScope_Lib, hash, symbol); + lnk_symbol_table_push_(symtab, arena, worker_id, LNK_SymbolScope_Lib, symbol); } } diff --git a/src/linker/lnk_obj.c b/src/linker/lnk_obj.c index b3590d8a..98f8e08a 100644 --- a/src/linker/lnk_obj.c +++ b/src/linker/lnk_obj.c @@ -346,27 +346,23 @@ THREAD_POOL_TASK_FUNC(lnk_input_coff_symbol_table) break; } LNK_Symbol *defn = lnk_make_defined_symbol(arena, symbol.name, obj, symbol_idx); - U64 hash = lnk_symbol_hash(symbol.name); - lnk_symbol_table_push_(task->symtab, arena, worker_id, LNK_SymbolScope_Defined, hash, defn); + lnk_symbol_table_push_(task->symtab, arena, worker_id, LNK_SymbolScope_Defined, defn); } } break; case COFF_SymbolValueInterp_Weak: { LNK_Symbol *defn = lnk_make_defined_symbol(arena, symbol.name, obj, symbol_idx); - U64 hash = lnk_symbol_hash(symbol.name); - lnk_symbol_table_push_(task->symtab, arena, worker_id, LNK_SymbolScope_Defined, hash, defn); + lnk_symbol_table_push_(task->symtab, arena, worker_id, LNK_SymbolScope_Defined, defn); lnk_symbol_list_push(arena, &task->weak_lists[worker_id], defn); } break; case COFF_SymbolValueInterp_Common: { LNK_Symbol *defn = lnk_make_defined_symbol(arena, symbol.name, obj, symbol_idx); - U64 hash = lnk_symbol_hash(symbol.name); - lnk_symbol_table_push_(task->symtab, arena, worker_id, LNK_SymbolScope_Defined, hash, defn); + lnk_symbol_table_push_(task->symtab, arena, worker_id, LNK_SymbolScope_Defined, defn); } break; case COFF_SymbolValueInterp_Abs: { if (symbol.storage_class == COFF_SymStorageClass_External) { LNK_Symbol *defn = lnk_make_defined_symbol(arena, symbol.name, obj, symbol_idx); - U64 hash = lnk_symbol_hash(symbol.name); - lnk_symbol_table_push_(task->symtab, arena, worker_id, LNK_SymbolScope_Defined, hash, defn); + lnk_symbol_table_push_(task->symtab, arena, worker_id, LNK_SymbolScope_Defined, defn); } } break; case COFF_SymbolValueInterp_Undefined: { diff --git a/src/linker/lnk_symbol_table.c b/src/linker/lnk_symbol_table.c index bf86be2c..da34ed4c 100644 --- a/src/linker/lnk_symbol_table.c +++ b/src/linker/lnk_symbol_table.c @@ -6,7 +6,6 @@ lnk_make_defined_symbol(Arena *arena, String8 name, struct LNK_Obj *obj, U32 sym { LNK_Symbol *symbol = push_array(arena, LNK_Symbol, 1); symbol->name = name; - symbol->type = LNK_Symbol_Defined; symbol->u.defined.obj = obj; symbol->u.defined.symbol_idx = symbol_idx; return symbol; @@ -17,32 +16,29 @@ lnk_make_lib_symbol(Arena *arena, String8 name, struct LNK_Lib *lib, U64 member_ { LNK_Symbol *symbol = push_array(arena, LNK_Symbol, 1); symbol->name = name; - symbol->type = LNK_Symbol_Lib; symbol->u.lib.lib = lib; symbol->u.lib.member_offset = member_offset; return symbol; } -internal LNK_Symbol * -lnk_make_undefined_symbol(Arena *arena, String8 name, struct LNK_Obj *obj) -{ - LNK_Symbol *symbol = push_array(arena, LNK_Symbol, 1); - symbol->name = name; - symbol->type = LNK_Symbol_Undefined; - symbol->u.undef.obj = obj; - return symbol; -} - internal LNK_Symbol * lnk_make_import_symbol(Arena *arena, String8 name, String8 import_header) { LNK_Symbol *symbol = push_array(arena, LNK_Symbol, 1); symbol->name = name; - symbol->type = LNK_Symbol_Import; symbol->u.imp.import_header = import_header; return symbol; } +internal LNK_Symbol * +lnk_make_undefined_symbol(Arena *arena, String8 name, struct LNK_Obj *obj) +{ + LNK_Symbol *symbol = push_array(arena, LNK_Symbol, 1); + symbol->name = name; + symbol->u.undef.obj = obj; + return symbol; +} + internal void lnk_symbol_list_push_node(LNK_SymbolList *list, LNK_SymbolNode *node) { @@ -125,26 +121,23 @@ lnk_error_multiply_defined_symbol(LNK_Symbol *dst, LNK_Symbol *src) } internal B32 -lnk_can_replace_symbol(LNK_Symbol *dst, LNK_Symbol *src) +lnk_can_replace_symbol(LNK_SymbolScope scope, LNK_Symbol *dst, LNK_Symbol *src) { - Assert(src->type != LNK_Symbol_Undefined); + //Assert(src->type != LNK_Symbol_Undefined); Assert(dst != src); Assert(str8_match(dst->name, src->name, 0)); B32 can_replace = 0; - - // lib vs lib - if (dst->type == LNK_Symbol_Lib && src->type == LNK_Symbol_Lib) { + switch (scope) { + case LNK_SymbolScope_Lib: { // link.exe picks symbol from lib that is discovered first can_replace = src->u.lib.lib->input_idx < dst->u.lib.lib->input_idx; - } - else if (dst->type == LNK_Symbol_Import) { - AssertAlways(src->type != LNK_Symbol_Import); + } break; + case LNK_SymbolScope_Import: { can_replace = 1; - } - // defined vs defined - else if (dst->type == LNK_Symbol_Defined && src->type == LNK_Symbol_Defined) { + } break; + case LNK_SymbolScope_Defined: { LNK_Obj *dst_obj = dst->u.defined.obj; LNK_Obj *src_obj = src->u.defined.obj; @@ -319,20 +312,20 @@ lnk_can_replace_symbol(LNK_Symbol *dst, LNK_Symbol *src) } else { lnk_error(LNK_Error_InvalidPath, "unable to find a suitable replacement logic for symbol combination"); } - } else { - lnk_error(LNK_Error_InvalidPath, "unable to find a suitable replacement logic for symbol combination"); + } break; + default: { InvalidPath; } } return can_replace; } internal void -lnk_on_symbol_replace(LNK_Symbol *dst, LNK_Symbol *src) +lnk_on_symbol_replace(LNK_SymbolScope scope, LNK_Symbol *dst, LNK_Symbol *src) { Assert(dst != src); - if (dst->type == LNK_Symbol_Lib && src->type == LNK_Symbol_Lib) { + if (scope == LNK_SymbolScope_Lib) { dst->u.lib = src->u.lib; - } else if (dst->type == LNK_Symbol_Defined && src->type == LNK_Symbol_Defined) { + } else if (scope == LNK_SymbolScope_Defined) { COFF_ParsedSymbol dst_parsed = lnk_parsed_symbol_from_coff_symbol_idx(dst->u.defined.obj, dst->u.defined.symbol_idx); COFF_ParsedSymbol src_parsed = lnk_parsed_symbol_from_coff_symbol_idx(src->u.defined.obj, src->u.defined.symbol_idx); COFF_SymbolValueInterpType dst_interp = coff_interp_symbol(dst_parsed.section_number, dst_parsed.value, dst_parsed.storage_class); @@ -346,8 +339,6 @@ lnk_on_symbol_replace(LNK_Symbol *dst, LNK_Symbol *src) COFF_SectionHeader *src_sect = lnk_coff_section_header_from_section_number(src->u.defined.obj, src_parsed.section_number); AssertAlways(~src_sect->flags & COFF_SectionFlag_LnkRemove); } - } else { - InvalidPath; } } @@ -356,6 +347,7 @@ lnk_symbol_hash_trie_insert_or_replace(Arena *arena, LNK_SymbolHashTrieChunkList *chunks, LNK_SymbolHashTrie **trie, U64 hash, + LNK_SymbolScope scope, LNK_Symbol *symbol) { LNK_SymbolHashTrie **curr_trie_ptr = trie; @@ -395,13 +387,13 @@ lnk_symbol_hash_trie_insert_or_replace(Arena *arena, // apply replacement if (leader) { - if (lnk_can_replace_symbol(leader, src)) { + if (lnk_can_replace_symbol(scope, leader, src)) { // discard leader - lnk_on_symbol_replace(leader, src); + lnk_on_symbol_replace(scope, leader, src); leader = src; } else { // discard source - lnk_on_symbol_replace(src, leader); + lnk_on_symbol_replace(scope, src, leader); src = leader; } } else { @@ -473,22 +465,16 @@ lnk_symbol_table_init(TP_Arena *arena) } internal void -lnk_symbol_table_push_(LNK_SymbolTable *symtab, Arena *arena, U64 worker_id, LNK_SymbolScope scope, U64 hash, LNK_Symbol *symbol) +lnk_symbol_table_push_(LNK_SymbolTable *symtab, Arena *arena, U64 worker_id, LNK_SymbolScope scope, LNK_Symbol *symbol) { - lnk_symbol_hash_trie_insert_or_replace(arena, &symtab->chunk_lists[scope][worker_id], &symtab->scopes[scope], hash, symbol); + U64 hash = lnk_symbol_hash(symbol->name); + lnk_symbol_hash_trie_insert_or_replace(arena, &symtab->chunk_lists[scope][worker_id], &symtab->scopes[scope], hash, scope, symbol); } internal void -lnk_symbol_table_push(LNK_SymbolTable *symtab, LNK_Symbol *symbol) +lnk_symbol_table_push(LNK_SymbolTable *symtab, LNK_SymbolScope scope, LNK_Symbol *symbol) { - U64 hash = lnk_symbol_hash(symbol->name); - switch (symbol->type) { - case LNK_Symbol_Null: break; - case LNK_Symbol_Defined: { lnk_symbol_table_push_(symtab, symtab->arena->v[0], 0, LNK_SymbolScope_Defined, hash, symbol); } break; - case LNK_Symbol_Import: { lnk_symbol_table_push_(symtab, symtab->arena->v[0], 0, LNK_SymbolScope_Import, hash, symbol); } break; - case LNK_Symbol_Lib: { lnk_symbol_table_push_(symtab, symtab->arena->v[0], 0, LNK_SymbolScope_Lib, hash, symbol); } break; - default: { InvalidPath; } break; - } + lnk_symbol_table_push_(symtab, symtab->arena->v[0], 0, scope, symbol); } internal LNK_Symbol * diff --git a/src/linker/lnk_symbol_table.h b/src/linker/lnk_symbol_table.h index 41d2c3c4..eec6c878 100644 --- a/src/linker/lnk_symbol_table.h +++ b/src/linker/lnk_symbol_table.h @@ -5,14 +5,13 @@ // --- Symbol ------------------------------------------------------------------ -typedef enum +typedef enum { - LNK_Symbol_Null, - LNK_Symbol_Defined, - LNK_Symbol_Import, - LNK_Symbol_Lib, - LNK_Symbol_Undefined, -} LNK_SymbolType; + LNK_SymbolScope_Defined, + LNK_SymbolScope_Import, + LNK_SymbolScope_Lib, + LNK_SymbolScope_Count +} LNK_SymbolScope; typedef struct LNK_SymbolDefined { @@ -38,8 +37,7 @@ typedef struct LNK_SymbolImport typedef struct LNK_Symbol { - String8 name; - LNK_SymbolType type; + String8 name; union { LNK_SymbolDefined defined; LNK_SymbolLib lib; @@ -101,14 +99,6 @@ typedef struct LNK_SymbolHashTrieChunkList // --- Symbol Table ------------------------------------------------------------ -typedef enum -{ - LNK_SymbolScope_Defined, - LNK_SymbolScope_Import, - LNK_SymbolScope_Lib, - LNK_SymbolScope_Count -} LNK_SymbolScope; - typedef struct LNK_SymbolTable { TP_Arena *arena; @@ -135,7 +125,7 @@ internal LNK_SymbolArray lnk_symbol_array_from_list(Arena *arena, LNK_Symbol // --- Symbol Hash Trie -------------------------------------------------------- -internal void lnk_symbol_hash_trie_insert_or_replace(Arena *arena, LNK_SymbolHashTrieChunkList *chunks, LNK_SymbolHashTrie **trie, U64 hash, LNK_Symbol *symbol); +internal void lnk_symbol_hash_trie_insert_or_replace(Arena *arena, LNK_SymbolHashTrieChunkList *chunks, LNK_SymbolHashTrie **trie, U64 hash, LNK_SymbolScope scope, LNK_Symbol *symbol); internal LNK_SymbolHashTrie * lnk_symbol_hash_trie_search(LNK_SymbolHashTrie *trie, U64 hash, String8 name); internal void lnk_symbol_hash_trie_remove(LNK_SymbolHashTrie *trie); @@ -144,7 +134,7 @@ internal void lnk_symbol_hash_trie_remove(LNK_SymbolHashTrie *tr internal U64 lnk_symbol_hash(String8 string); internal LNK_SymbolTable * lnk_symbol_table_init(TP_Arena *arena); -internal void lnk_symbol_table_push(LNK_SymbolTable *symtab, LNK_Symbol *symbol); +internal void lnk_symbol_table_push(LNK_SymbolTable *symtab, LNK_SymbolScope scope, LNK_Symbol *symbol); internal LNK_Symbol * lnk_symbol_table_search(LNK_SymbolTable *symtab, LNK_SymbolScope scope, String8 name); internal LNK_Symbol * lnk_symbol_table_searchf(LNK_SymbolTable *symtab, LNK_SymbolScope scope, char *fmt, ...);