diff --git a/src/coff/coff.c b/src/coff/coff.c index 2cd9bf29..3e3bf852 100644 --- a/src/coff/coff.c +++ b/src/coff/coff.c @@ -174,11 +174,11 @@ coff_apply_size_from_reloc(COFF_MachineType machine, COFF_RelocType x) internal COFF_RelocValue coff_pick_reloc_value_x64(COFF_Reloc_X64 type, + U64 image_base, U64 reloc_virtual_offset, U32 symbol_section_number, U32 symbol_section_offset, - U32 symbol_virtual_offset, - U64 symbol_address) + U32 symbol_virtual_offset) { U64 reloc_value_size = 0; S64 reloc_value = 0; @@ -187,11 +187,11 @@ coff_pick_reloc_value_x64(COFF_Reloc_X64 type, case COFF_Reloc_X64_Abs: {} break; case COFF_Reloc_X64_Addr64: { reloc_value_size = 8; - reloc_value = symbol_address; + reloc_value = symbol_virtual_offset + image_base; } break; case COFF_Reloc_X64_Addr32: { reloc_value_size = 4; - reloc_value = symbol_address; + reloc_value = symbol_virtual_offset + image_base; } break; case COFF_Reloc_X64_Addr32Nb: { reloc_value_size = 4; diff --git a/src/coff/coff.h b/src/coff/coff.h index c7c59b78..1127b1db 100644 --- a/src/coff/coff.h +++ b/src/coff/coff.h @@ -602,7 +602,7 @@ internal String8 coff_read_symbol_name(String8 string_table, COFF_SymbolName *na internal U64 coff_apply_size_from_reloc_x64(COFF_Reloc_X64 x); internal U64 coff_apply_size_from_reloc_x86(COFF_Reloc_X86 x); -internal COFF_RelocValue coff_pick_reloc_value_x64(COFF_Reloc_X64 type, U64 reloc_virtual_offset, U32 symbol_section_number, U32 symbol_section_offset, U32 symbol_virtual_offset, U64 symbol_address); +internal COFF_RelocValue coff_pick_reloc_value_x64(COFF_Reloc_X64 type, U64 image_base, U64 reloc_virtual_offset, U32 symbol_section_number, U32 symbol_section_offset, U32 symbol_virtual_offset); //////////////////////////////// // Import diff --git a/src/linker/hash_table.c b/src/linker/hash_table.c index 964506aa..e6adec79 100644 --- a/src/linker/hash_table.c +++ b/src/linker/hash_table.c @@ -237,13 +237,6 @@ hash_table_search_path_raw(HashTable *ht, String8 path) return kv ? kv->value_raw : 0; } -internal void * -hash_table_(HashTable *ht, String8 path) -{ - KeyValuePair *result = hash_table_search_path(ht, path); - return result ? result->value_raw : 0; -} - internal B32 hash_table_search_path_u64(HashTable *ht, String8 key, U64 *value_out) { @@ -283,6 +276,19 @@ hash_table_search_string_raw(HashTable *ht, String8 key, void *value_out) return 0; } +internal B32 +hash_table_search_string_string(HashTable *ht, String8 key, String8 *value_out) +{ + KeyValuePair *result = hash_table_search_string(ht, key); + if (result) { + if (value_out) { + *value_out = result->value_string; + } + return 1; + } + return 0; +} + //////////////////////////////// internal int diff --git a/src/linker/hash_table.h b/src/linker/hash_table.h index 504aedc6..2bda690a 100644 --- a/src/linker/hash_table.h +++ b/src/linker/hash_table.h @@ -74,6 +74,9 @@ internal KeyValuePair * hash_table_search_path (HashTable *ht, String8 path internal void * hash_table_search_path_raw(HashTable *ht, String8 path ); internal B32 hash_table_search_path_u64(HashTable *ht, String8 key, U64 *value_out); +internal B32 hash_table_search_string_u64(HashTable *ht, String8 key, U64 *value_out); +internal B32 hash_table_search_string_raw(HashTable *ht, String8 key, void *value_out); +internal B32 hash_table_search_string_string(HashTable *ht, String8 key, String8 *value_out); //- key-value helpers diff --git a/src/linker/lnk.c b/src/linker/lnk.c index d94fe688..32f771e3 100644 --- a/src/linker/lnk.c +++ b/src/linker/lnk.c @@ -1102,14 +1102,13 @@ THREAD_POOL_TASK_FUNC(lnk_obj_reloc_patcher) COFF_Reloc *reloc = &relocs[reloc_idx]; // compute relocation file/virtual offsets - U64 reloc_file_offset = section_header->foff + reloc->apply_off; - U64 reloc_virtual_offset = section_header->voff + reloc->apply_off; + U64 reloc_foff = section_header->foff + reloc->apply_off; + U64 reloc_voff = section_header->voff + reloc->apply_off; // compute symbol location values - U32 symbol_section_number = 0; - U32 symbol_section_offset = 0; - U32 symbol_virtual_offset = 0; - U64 symbol_address = 0; + U32 symbol_secnum = 0; + U32 symbol_secoff = 0; + U32 symbol_voff = 0; { COFF_ParsedSymbol symbol; if (obj_header.is_big_obj) { @@ -1120,15 +1119,13 @@ THREAD_POOL_TASK_FUNC(lnk_obj_reloc_patcher) COFF_SymbolValueInterpType interp = coff_interp_symbol(symbol.section_number, symbol.value, symbol.storage_class); if (interp == COFF_SymbolValueInterp_Regular) { - symbol_section_number = symbol.section_number; - symbol_section_offset = symbol.value; - symbol_virtual_offset = task->image_section_table[symbol.section_number]->voff + symbol_section_offset; - symbol_address = task->base_addr + symbol_virtual_offset; + symbol_secnum = symbol.section_number; + symbol_secoff = symbol.value; + symbol_voff = task->image_section_table[symbol.section_number]->voff + symbol_secoff; } else if (interp == COFF_SymbolValueInterp_Abs) { - symbol_section_number = max_U32; - symbol_section_offset = max_U32; - symbol_virtual_offset = symbol.value - task->base_addr; - symbol_address = symbol.value; + symbol_secnum = 0; + symbol_secoff = 0; + symbol_voff = safe_cast_u32(symbol.value); } else if (interp == COFF_SymbolValueInterp_Weak) { // unresolved weak } else if (interp == COFF_SymbolValueInterp_Undefined) { @@ -1142,21 +1139,21 @@ THREAD_POOL_TASK_FUNC(lnk_obj_reloc_patcher) COFF_RelocValue reloc_value = {0}; switch (obj_header.machine) { case COFF_MachineType_Unknown: {} break; - case COFF_MachineType_X64: { reloc_value = coff_pick_reloc_value_x64(reloc->type, reloc_virtual_offset, symbol_section_number, symbol_section_offset, symbol_virtual_offset, symbol_address); } break; + case COFF_MachineType_X64: { reloc_value = coff_pick_reloc_value_x64(reloc->type, task->image_base, reloc_voff, symbol_secnum, symbol_secoff, symbol_voff); } break; default: { NotImplemented; } break; } // read addend - Assert(reloc_file_offset + reloc_value.size <= task->image_data.size); + Assert(reloc_foff + reloc_value.size <= task->image_data.size); U64 raw_addend = 0; - str8_deserial_read(task->image_data, reloc_file_offset, &raw_addend, reloc_value.size, reloc_value.size); + str8_deserial_read(task->image_data, reloc_foff, &raw_addend, reloc_value.size, reloc_value.size); // compute new reloc value S64 addend = extend_sign64(raw_addend, reloc_value.size); U64 reloc_result = reloc_value.value + addend; // commit new reloc value - MemoryCopy(task->image_data.str + reloc_file_offset, &reloc_result, reloc_value.size); + MemoryCopy(task->image_data.str + reloc_foff, &reloc_result, reloc_value.size); } } } @@ -2270,9 +2267,12 @@ lnk_build_win32_image(TP_Arena *arena, TP_Context *tp, LNK_Config *config, LNK_S for (U64 sect_idx = 0; sect_idx < obj->header.section_count_no_null; sect_idx += 1) { COFF_SectionHeader *sect_header = §ion_table[sect_idx]; if (sect_header->flags & COFF_SectionFlag_LnkCOMDAT) { - LNK_Symbol *defn = lnk_symbol_table_search(symtab, LNK_SymbolScope_Defined, symlinks[sect_idx]); - COFF_ParsedSymbol symbol = lnk_parsed_symbol_from_coff_symbol_idx(defn->u.defined.obj, defn->u.defined.symbol_idx); - sect_map[obj_idx][sect_idx] = sect_map[defn->u.defined.obj->input_idx][symbol.section_number-1]; + String8 comdat_name = symlinks[sect_idx]; + if (comdat_name.size) { + LNK_Symbol *defn = lnk_symbol_table_search(symtab, LNK_SymbolScope_Defined, comdat_name); + COFF_ParsedSymbol symbol = lnk_parsed_symbol_from_coff_symbol_idx(defn->u.defined.obj, defn->u.defined.symbol_idx); + sect_map[obj_idx][sect_idx] = sect_map[defn->u.defined.obj->input_idx][symbol.section_number-1]; + } } } } @@ -2473,15 +2473,25 @@ lnk_build_win32_image(TP_Arena *arena, TP_Context *tp, LNK_Config *config, LNK_S COFF_SymbolValueInterpType interp = coff_interp_symbol(symbol.section_number, symbol.value, symbol.storage_class); if (interp == COFF_SymbolValueInterp_Regular) { - LNK_SectionContrib *sc = sect_map[obj_idx][symbol.section_number-1]; + U32 section_number = 0; + U32 value = 0; + { + COFF_SectionHeader *sect_header = lnk_section_header_from_section_number(obj, symbol.section_number); + if (~sect_header->flags & COFF_SectionFlag_LnkRemove) { + LNK_SectionContrib *sc = sect_map[obj_idx][symbol.section_number-1]; + section_number = safe_cast_u32(sc->u.sect_idx + 1); + value = sc->u.off + symbol.value; + } + } + if (obj->header.is_big_obj) { COFF_Symbol32 *symbol32 = symbol.raw_symbol; - symbol32->section_number = safe_cast_u32(sc->u.sect_idx + 1); - symbol32->value = safe_cast_u32(sc->u.off + symbol32->value); + symbol32->section_number = section_number; + symbol32->value = value; } else { COFF_Symbol16 *symbol16 = symbol.raw_symbol; - symbol16->section_number = safe_cast_u16(sc->u.sect_idx + 1); - symbol16->value = safe_cast_u32(sc->u.off + symbol16->value); + symbol16->section_number = safe_cast_u16(section_number); + symbol16->value = value; } } } @@ -2918,7 +2928,7 @@ lnk_build_win32_image(TP_Arena *arena, TP_Context *tp, LNK_Config *config, LNK_S LNK_ObjRelocPatcher task = {0}; task.image_data = image_data; task.objs = objs; - task.base_addr = pe.image_base; + task.image_base = pe.image_base; task.image_section_table = image_section_table; tp_for_parallel(tp, 0, objs_count, lnk_obj_reloc_patcher, &task); ProfEnd(); @@ -3546,7 +3556,6 @@ lnk_run(int argc, char **argv) String8List manifest_dep_list = str8_list_copy(scratch.arena, &config->manifest_dependency_list); PE_ExportParseList export_symbol_list = config->export_symbol_list; HashTable *export_ht = hash_table_init(scratch.arena, max_U16/2); - LNK_AltNameList alt_name_list = config->alt_name_list; LNK_InputObjList input_obj_list = {0}; LNK_InputImportList input_import_list = {0}; LNK_SymbolList input_weak_list = {0}; @@ -3624,6 +3633,13 @@ lnk_run(int argc, char **argv) for (PE_ExportParseNode *exp_n = config->export_symbol_list.first; exp_n != 0; exp_n = exp_n->next) { lnk_push_export(scratch.arena, export_ht, &export_symbol_list, &include_symbol_list, exp_n->data); } + + // + // Push config alternative names + // + for (LNK_AltNameNode *alt_n = config->alt_name_list.first; alt_n != 0; alt_n = alt_n->next) { + lnk_symbol_table_push_alt_name(symtab, 0, alt_n->data.from, alt_n->data.to); + } ProfBegin("Image"); // :EndImage lnk_timer_begin(LNK_Timer_Image); @@ -3711,21 +3727,6 @@ lnk_run(int argc, char **argv) lnk_symbol_list_push(scratch.arena, &lookup_undef_list, symbol); } ProfEnd(); - -#if 0 - ProfBegin("Push /ALTERNATIVENAME Symbols"); - Assert(alt_name_list.from_list.node_count == alt_name_list.to_list.node_count); - for (String8Node *from_node = alt_name_list.from_list.first, *to_node = alt_name_list.to_list.first; - from_node != 0; - from_node = from_node->next, to_node = to_node->next) { - LNK_Symbol *fallback = lnk_make_undefined_symbol(scratch.arena, to_node->string); - LNK_Symbol *weak = lnk_make_weak_symbol(scratch.arena, from_node->string, COFF_WeakExt_SearchAlias, fallback); - lnk_symbol_list_push(scratch.arena, &lookup_undef_list, fallback); - lnk_symbol_list_push(scratch.arena, &input_weak_list, weak); - lnk_symbol_table_push(symtab, weak); - } - ProfEnd(); -#endif // we defined new symbols, give unresolved symbols another chance to be resolved lnk_symbol_list_concat_in_place(&lookup_undef_list, &unresolved_undef_list); @@ -3734,7 +3735,6 @@ lnk_run(int argc, char **argv) // reset inputs MemoryZeroStruct(&include_symbol_list); - MemoryZeroStruct(&alt_name_list); MemoryZeroStruct(&input_weak_list); ProfEnd(); @@ -3880,10 +3880,16 @@ lnk_run(int argc, char **argv) } // /ALTERNATENAME - for (LNK_Directive *dir = directive_info.v[LNK_CmdSwitch_AlternateName].first; dir != 0; dir = dir->next) { - String8 *invalid_string = lnk_parse_alt_name_directive_list(scratch.arena, dir->value_list, &alt_name_list); - if (invalid_string) { - lnk_error_obj(LNK_Error_Cmdl, obj, "invalid syntax \"%S\", expected format \"FROM=TO\"", *invalid_string); + { + for (LNK_Directive *dir = directive_info.v[LNK_CmdSwitch_AlternateName].first; dir != 0; dir = dir->next) { + for (String8Node *string_n = dir->value_list.first; string_n != 0; string_n = string_n->next) { + LNK_AltName alt_name; + if (lnk_parse_alt_name_directive(string_n->string, &alt_name)) { + lnk_symbol_table_push_alt_name(symtab, obj, alt_name.from, alt_name.to); + } else { + lnk_error_obj(LNK_Error_Cmdl, obj, "syntax error in \"%S\", expected format \"FROM=TO\"", string_n->string); + } + } } } @@ -4573,9 +4579,7 @@ lnk_run(int argc, char **argv) state_list_push(scratch.arena, state_list, State_InputImports); continue; } - if (input_weak_list.count || - include_symbol_list.node_count || - alt_name_list.from_list.node_count) { + if (input_weak_list.count || include_symbol_list.node_count) { state_list_push(scratch.arena, state_list, State_InputSymbols); continue; } diff --git a/src/linker/lnk.h b/src/linker/lnk.h index af76f03e..be0ba71e 100644 --- a/src/linker/lnk.h +++ b/src/linker/lnk.h @@ -102,7 +102,7 @@ typedef struct { String8 image_data; LNK_Obj **objs; - U64 base_addr; + U64 image_base; COFF_SectionHeader **image_section_table; } LNK_ObjRelocPatcher; diff --git a/src/linker/lnk_config.c b/src/linker/lnk_config.c index 3118a91f..35e0665f 100644 --- a/src/linker/lnk_config.c +++ b/src/linker/lnk_config.c @@ -776,40 +776,21 @@ lnk_cmd_switch_parse_string_copy(Arena *arena, String8 obj_path, String8 lib_pat //////////////////////////////// -internal void -lnk_alt_name_list_concat_in_place(LNK_AltNameList *list, LNK_AltNameList *to_concat) -{ - str8_list_concat_in_place(&list->from_list, &to_concat->from_list); - str8_list_concat_in_place(&list->to_list, &to_concat->to_list); -} - internal B32 -lnk_parse_alt_name_directive(Arena *arena, String8 input, LNK_AltNameList *list_out) +lnk_parse_alt_name_directive(String8 input, LNK_AltName *alt_out) { - Temp scratch = scratch_begin(&arena, 1); + Temp scratch = scratch_begin(0,0); B32 is_parse_ok = 0; String8List pair = str8_split_by_string_chars(scratch.arena, input, str8_lit("="), 0); if (pair.node_count == 2) { - str8_list_push(arena, &list_out->from_list, pair.first->string); - str8_list_push(arena, &list_out->to_list, pair.last->string); + alt_out->from = pair.first->string; + alt_out->to = pair.last->string; is_parse_ok = 1; } scratch_end(scratch); return is_parse_ok; } -internal String8 * -lnk_parse_alt_name_directive_list(Arena *arena, String8List list, LNK_AltNameList *list_out) -{ - for (String8Node *str_n = list.first; str_n != 0; str_n = str_n->next) { - B32 is_parse_ok = lnk_parse_alt_name_directive(arena, str_n->string, list_out); - if ( ! is_parse_ok) { - return &str_n->string; - } - } - return 0; -} - internal B32 lnk_parse_export_directive_ex(Arena *arena, String8List directive, String8 obj_path, String8 lib_path, PE_ExportParse *export_out) { @@ -1076,10 +1057,18 @@ lnk_apply_cmd_option_to_config(Arena *arena, LNK_Config *config, String8 cmd_nam } break; case LNK_CmdSwitch_AlternateName: { - String8List value_strings_copy = str8_list_copy(arena, &value_strings); - String8 *error_string = lnk_parse_alt_name_directive_list(arena, value_strings_copy, &config->alt_name_list); - if (error_string != 0) { - lnk_error_cmd_switch(LNK_Error_Cmdl, obj_path, lib_path, cmd_switch, "invalid syntax \"%S\", expected format \"FROM=TO\"", *error_string); + if (value_strings.node_count == 1) { + LNK_AltName alt_name; + if (lnk_parse_alt_name_directive(value_strings.first->string, &alt_name)) { + LNK_AltNameNode *alt_name_n = push_array(arena, LNK_AltNameNode, 1); + alt_name_n->data = alt_name; + SLLQueuePush(config->alt_name_list.first, config->alt_name_list.last, alt_name_n); + config->alt_name_list.count += 1; + } else { + lnk_error_cmd_switch(LNK_Error_Cmdl, obj_path, lib_path, cmd_switch, "syntax error in \"%S\", expected format \"FROM=TO\"", value_strings.first->string); + } + } else { + lnk_error_cmd_switch(LNK_Error_Cmdl, obj_path, lib_path, cmd_switch, "invalid number of parameters"); } } break; diff --git a/src/linker/lnk_config.h b/src/linker/lnk_config.h index 377740db..5a361e1d 100644 --- a/src/linker/lnk_config.h +++ b/src/linker/lnk_config.h @@ -232,10 +232,23 @@ typedef enum LNK_ManifestOpt_No, } LNK_ManifestOpt; +typedef struct LNK_AltName +{ + String8 from; + String8 to; +} LNK_AltName; + +typedef struct LNK_AltNameNode +{ + struct LNK_AltNameNode *next; + LNK_AltName data; +} LNK_AltNameNode; + typedef struct LNK_AltNameList { - String8List from_list; - String8List to_list; + U64 count; + LNK_AltNameNode *first; + LNK_AltNameNode *last; } LNK_AltNameList; typedef struct LNK_MergeDirective @@ -556,10 +569,7 @@ internal void lnk_cmd_switch_parse_string_copy(Arena *arena, String8 obj_path, S //////////////////////////////// -internal void lnk_alt_name_list_concat_in_place(LNK_AltNameList *list, LNK_AltNameList *to_concat); -internal B32 lnk_parse_alt_name_directive (Arena *arena, String8 input, LNK_AltNameList *list_out); -internal String8 * lnk_parse_alt_name_directive_list(Arena *arena, String8List list, LNK_AltNameList *list_out); - +internal B32 lnk_parse_alt_name_directive(String8 input, LNK_AltName *alt_out); internal B32 lnk_parse_export_directive_ex(Arena *arena, String8List directive, String8 obj_path, String8 lib_path, PE_ExportParse *export_out); internal B32 lnk_parse_export_directive(Arena *arena, String8 directive, String8 obj_path, String8 lib_path, PE_ExportParse *export_out); diff --git a/src/linker/lnk_lib.c b/src/linker/lnk_lib.c index a04e6961..b04db0b1 100644 --- a/src/linker/lnk_lib.c +++ b/src/linker/lnk_lib.c @@ -139,7 +139,6 @@ 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); } diff --git a/src/linker/lnk_obj.c b/src/linker/lnk_obj.c index a0c20dc8..c281de88 100644 --- a/src/linker/lnk_obj.c +++ b/src/linker/lnk_obj.c @@ -233,6 +233,16 @@ lnk_parsed_symbol_from_coff_symbol_idx(LNK_Obj *obj, U64 symbol_idx) return result; } +internal COFF_SectionHeader * +lnk_section_header_from_section_number(LNK_Obj *obj, U64 section_number) +{ + COFF_SectionHeader *section_table = (COFF_SectionHeader *)str8_substr(obj->data, obj->header.section_table_range).str; + if (section_number > 0 && section_number <= obj->header.section_count_no_null) { + return §ion_table[section_number-1]; + } + return 0; +} + internal String8List * lnk_collect_obj_chunks_parallel(TP_Context *tp, TP_Arena *arena, U64 obj_count, LNK_Obj **obj_arr, String8 name, String8 postfix, B32 collect_discarded) { diff --git a/src/linker/lnk_section_table.c b/src/linker/lnk_section_table.c index 1d1edf09..ed83c1fa 100644 --- a/src/linker/lnk_section_table.c +++ b/src/linker/lnk_section_table.c @@ -63,7 +63,6 @@ lnk_section_contrib_chunk_list_concat_in_place(LNK_SectionContribChunkList *list list->last->next = to_concat->first; list->last = to_concat->last; list->chunk_count += to_concat->chunk_count; - MemoryZeroStruct(to_concat); } } diff --git a/src/linker/lnk_symbol_table.c b/src/linker/lnk_symbol_table.c index 027e631e..b5053581 100644 --- a/src/linker/lnk_symbol_table.c +++ b/src/linker/lnk_symbol_table.c @@ -457,6 +457,7 @@ lnk_symbol_table_init(TP_Arena *arena) for (U64 i = 0; i < LNK_SymbolScope_Count; ++i) { symtab->chunk_lists[i] = push_array(arena->v[0], LNK_SymbolHashTrieChunkList, arena->count); } + symtab->alt_names = hash_table_init(arena->v[0], 1024); return symtab; } @@ -464,6 +465,13 @@ internal LNK_Symbol * lnk_symbol_table_search_hash(LNK_SymbolTable *symtab, LNK_SymbolScope scope, U64 hash, String8 name) { LNK_SymbolHashTrie *trie = lnk_symbol_hash_trie_search(symtab->scopes[scope], hash, name); + if (trie == 0) { + String8 alt_name = {0}; + if (hash_table_search_string_string(symtab->alt_names, name, &alt_name)) { + U64 alt_hash = lnk_symbol_hash(alt_name); + trie = lnk_symbol_hash_trie_search(symtab->scopes[scope], alt_hash, alt_name); + } + } return trie ? trie->symbol : 0; } @@ -525,4 +533,16 @@ lnk_symbol_table_remove(LNK_SymbolTable *symtab, LNK_SymbolScope scope, String8 } } +internal void +lnk_symbol_table_push_alt_name(LNK_SymbolTable *symtab, LNK_Obj *obj, String8 from, String8 to) +{ + String8 to_extant; + if (hash_table_search_string_string(symtab->alt_names, from, &to_extant)) { + if (!str8_match(to_extant, to, 0)) { + lnk_error_obj(LNK_Error_AlternateNameConflict, obj, "conflicting alternative name: existing '%S=%S' vs. new '%S=%S'", from, to_extant, from, to); + } + } else { + hash_table_push_string_string(symtab->arena->v[0], symtab->alt_names, from, to); + } +} diff --git a/src/linker/lnk_symbol_table.h b/src/linker/lnk_symbol_table.h index 6a355727..5c5ee11b 100644 --- a/src/linker/lnk_symbol_table.h +++ b/src/linker/lnk_symbol_table.h @@ -108,6 +108,7 @@ typedef struct LNK_SymbolTable TP_Arena *arena; LNK_SymbolHashTrie *scopes[LNK_SymbolScope_Count]; LNK_SymbolHashTrieChunkList *chunk_lists[LNK_SymbolScope_Count]; + HashTable *alt_names; } LNK_SymbolTable; //////////////////////////////// @@ -162,3 +163,5 @@ internal void lnk_symbol_table_push_hash(LNK_SymbolTable *symtab, U internal void lnk_symbol_table_push(LNK_SymbolTable *symtab, LNK_Symbol *symbol); internal void lnk_symbol_table_remove(LNK_SymbolTable *symtab, LNK_SymbolScope scope, String8 name); +internal void lnk_symbol_table_push_alt_name(LNK_SymbolTable *symtab, struct LNK_Obj *obj, String8 from, String8 to); +