diff --git a/src/base/base_context_cracking.h b/src/base/base_context_cracking.h index 7edbd59b6..0605377db 100644 --- a/src/base/base_context_cracking.h +++ b/src/base/base_context_cracking.h @@ -110,9 +110,9 @@ //////////////////////////////// //~ rjf: Arch Cracking -#if defined(ARCH_X64) +#if defined(ARCH_X64) || defined(ARCH_ARM64) # define ARCH_64BIT 1 -#elif defined(ARCH_X86) +#elif defined(ARCH_X86) || defined(ARCH_ARM32) # define ARCH_32BIT 1 #endif diff --git a/src/linker/lnk.c b/src/linker/lnk.c index 910ccbe74..05f4da839 100644 --- a/src/linker/lnk.c +++ b/src/linker/lnk.c @@ -1083,10 +1083,10 @@ lnk_inputer_push_lib_thin(LNK_Inputer *inputer, LNK_Config *config, LNK_InputSou } // search disk for library - String8List matches = lnk_file_search(scratch.arena, config->lib_dir_list, path); + String8 first_match = lnk_find_first_file(scratch.arena, config->lib_dir_list, path); // warn about missing library - if (matches.node_count == 0) { + if (first_match.size == 0) { KeyValuePair *was_reported = hash_table_search_path(inputer->missing_lib_ht, path); if (was_reported == 0) { hash_table_push_path_u64(inputer->arena, inputer->missing_lib_ht, path, 0); @@ -1095,21 +1095,20 @@ lnk_inputer_push_lib_thin(LNK_Inputer *inputer, LNK_Config *config, LNK_InputSou goto exit; } - String8 first_match = matches.first->string; + // was input with full path already loaded? input = hash_table_search_path_raw(inputer->libs_ht, first_match); if (input) { goto exit; } - // warn about multiple matches - if (matches.node_count > 1) { - lnk_error(LNK_Warning_MultipleLibMatch, "multiple libraries match `%S` (picking first match)", path); - lnk_supplement_error_list(matches); - } - lnk_log(LNK_Log_InputLib, "Input Lib: %S", first_match); input = lnk_inputer_push_thin(inputer->arena, &inputer->new_libs[input_source], inputer->libs_ht, first_match); + // store input path to early-out of file searches for default libs + if (!str8_match(first_match, path, StringMatchFlag_CaseInsensitive)) { + hash_table_push_path_raw(inputer->arena, inputer->libs_ht, path, input); + } + exit:; scratch_end(scratch); return input; @@ -1134,6 +1133,8 @@ lnk_inputer_has_items(LNK_Inputer *inputer) internal LNK_InputPtrArray lnk_inputer_flush(Arena *arena, TP_Context *tp, LNK_Inputer *inputer, LNK_IO_Flags io_flags, LNK_InputList *all_inputs, LNK_InputList *new_inputs) { + ProfBeginFunction(); + Temp scratch = scratch_begin(&arena, 1); ProfBegin("Gather Thin Inputs"); @@ -1179,6 +1180,7 @@ lnk_inputer_flush(Arena *arena, TP_Context *tp, LNK_Inputer *inputer, LNK_IO_Fla lnk_input_list_concat_in_place(all_inputs, new_inputs); scratch_end(scratch); + ProfEnd(); return result; } @@ -1218,7 +1220,7 @@ lnk_array_from_lib_member_list(Arena *arena, LNK_LibMemberRefList list) internal LNK_ObjNode * lnk_load_objs(TP_Context *tp, TP_Arena *arena, LNK_Config *config, LNK_Inputer *inputer, LNK_SymbolTable *symtab, LNK_Link *link, U64 *objs_count_out) { - ProfBegin("Input Objs [Count %llu]", inputer->new_objs.count); + ProfBeginV("Load Objs [Count %llu]", inputer->new_objs.count); Temp scratch = scratch_begin(arena->v, arena->count); // load obj inputer from disk @@ -1287,6 +1289,7 @@ lnk_load_libs(TP_Context *tp, TP_Arena *arena, LNK_Config *config, LNK_Inputer * internal void lnk_load_inputs(TP_Context *tp, TP_Arena *arena, LNK_Config *config, LNK_Inputer *inputer, LNK_SymbolTable *symtab, LNK_Link *link) { + ProfBeginFunction(); Temp scratch = scratch_begin(arena->v, arena->count); U64 obj_id_base = link->objs.count; @@ -1303,12 +1306,13 @@ lnk_load_inputs(TP_Context *tp, TP_Arena *arena, LNK_Config *config, LNK_Inputer } } - // handle /INCLUDE { + ProfBegin("Process /INCLUDE"); + // group include symbols by obj HashTable *ht = hash_table_init(scratch.arena, 64); - for (LNK_IncludeSymbolNode *node = config->include_symbol_list.first; node != 0; node = node->next) { - LNK_IncludeSymbol *include_symbol = &node->v; + for (; *link->last_include; link->last_include = &(*link->last_include)->next) { + LNK_IncludeSymbol *include_symbol = &(*link->last_include)->v; // skip, include symbol is already in the global symbol table if (lnk_symbol_table_search(symtab, include_symbol->name)) { @@ -1347,27 +1351,22 @@ lnk_load_inputs(TP_Context *tp, TP_Arena *arena, LNK_Config *config, LNK_Inputer lnk_obj_list_push_node(&link->objs, include_obj); } } + + ProfEnd(); } - // assign input indices to objs + // finalize input indices on new objs and push external symbols to the symbol table { U64 node_idx = 0; - for (LNK_ObjNode *node = objs; node != 0; node = node->next, node_idx += 1) { - node->data.input_idx = obj_id_base + node_idx; + for (LNK_ObjNode **n = link->last_symbol_input; *n; n = &(*n)->next, node_idx += 1) { + (*n)->data.input_idx = obj_id_base + node_idx; } - } - // input indices on objs are finalized, push external symbols to the global symbol table - { - U64 new_objs_count = 0; - for (LNK_ObjNode *node = objs; node != 0; node = node->next) { new_objs_count += 1; } - - LNK_Obj **new_objs = push_array(scratch.arena, LNK_Obj *, new_objs_count); - { - U64 node_idx = 0; - for (LNK_ObjNode *node = objs; node != 0; node = node->next) { - new_objs[node_idx++] = &node->data; - } + U64 new_objs_count = node_idx; + LNK_Obj **new_objs = push_array(scratch.arena, LNK_Obj *, node_idx); + node_idx = 0; + for (; *link->last_symbol_input; link->last_symbol_input = &(*link->last_symbol_input)->next, node_idx += 1) { + new_objs[node_idx] = &(*link->last_symbol_input)->data; } lnk_push_obj_symbols(tp, arena, symtab, new_objs_count, new_objs); @@ -1479,6 +1478,7 @@ lnk_load_inputs(TP_Context *tp, TP_Arena *arena, LNK_Config *config, LNK_Inputer } scratch_end(scratch); + ProfEnd(); } internal void @@ -1499,8 +1499,6 @@ lnk_queue_lib_member(Arena *arena, LNK_LibMemberRefList *queued_members, LNK_Sym internal THREAD_POOL_TASK_FUNC(lnk_search_lib_task) { - ProfBeginFunction(); - LNK_SearchLibTask *task = raw_task; LNK_Lib *lib = task->lib; LNK_SymbolTable *symtab = task->symtab; @@ -1514,7 +1512,6 @@ THREAD_POOL_TASK_FUNC(lnk_search_lib_task) LNK_ObjSymbolRef symbol_ref = lnk_ref_from_symbol(symbol); COFF_ParsedSymbol symbol_parsed = lnk_parsed_from_symbol(symbol); COFF_SymbolValueInterpType symbol_interp = coff_interp_from_parsed_symbol(symbol_parsed); - if (symbol_interp == COFF_SymbolValueInterp_Undefined) { U32 member_idx; if (lnk_search_lib(lib, symbol->name, &member_idx)) { @@ -1543,8 +1540,6 @@ THREAD_POOL_TASK_FUNC(lnk_search_lib_task) } } } - - ProfEnd(); } internal void @@ -1556,6 +1551,7 @@ lnk_link_inputs(TP_Context *tp, LNK_Link *link, LNK_ImportTables *imps) { + ProfBeginFunction(); Temp scratch = scratch_begin(arena->v, arena->count); B32 search_anti_deps = 0; @@ -1563,17 +1559,15 @@ lnk_link_inputs(TP_Context *tp, lnk_load_inputs(tp, arena, config, inputer, symtab, link); for (LNK_LibNode *lib_n = link->libs.first; lib_n != 0; lib_n = lib_n->next) { + ProfBeginV("Search %S", str8_skip_last_slash(lib_n->data.path)); do { lnk_load_inputs(tp, arena, config, inputer, symtab, link); LNK_LibMemberRefList queued_members = {0}; { - LNK_SearchLibTask task = {0}; - task.search_anti_deps = search_anti_deps; - task.lib = &lib_n->data; - task.symtab = symtab; + LNK_SearchLibTask task = { .search_anti_deps = search_anti_deps, .lib = &lib_n->data, .symtab = symtab }; task.member_ref_lists = push_array(scratch.arena, LNK_LibMemberRefList, tp->worker_count); - tp_for_parallel_prof(tp, arena, tp->worker_count, lnk_search_lib_task, &task, "Search Lib"); + tp_for_parallel(tp, arena, tp->worker_count, lnk_search_lib_task, &task); lnk_lib_member_ref_list_concat_in_place_array(&queued_members, task.member_ref_lists, tp->worker_count); } @@ -1601,7 +1595,7 @@ lnk_link_inputs(TP_Context *tp, for EachIndex(i, refs_count) { lnk_log(LNK_Log_Links, "\t\tReferenced in %S", lnk_loc_from_obj(temp.arena, refs[i]->obj)); } - + temp_end(temp); } } @@ -1686,6 +1680,7 @@ lnk_link_inputs(TP_Context *tp, resolved_members_count += queued_members.count; } while (lnk_inputer_has_items(inputer)); + ProfEnd(); } if (resolved_members_count == 0) { @@ -1729,17 +1724,20 @@ lnk_link_inputs(TP_Context *tp, } scratch_end(scratch); + ProfEnd(); } internal LNK_Link * lnk_link_image(TP_Context *tp, TP_Arena *arena, LNK_Config *config, LNK_Inputer *inputer, LNK_SymbolTable *symtab) { + ProfBeginFunction(); Temp scratch = scratch_begin(arena->v, arena->count); // // init link context // LNK_Link *link = push_array(arena->v[0], LNK_Link, 1); + link->last_symbol_input = &link->objs.first; link->last_include = &config->include_symbol_list.first; link->last_default_lib = &config->input_default_lib_list.first; link->last_obj_lib = &config->input_obj_lib_list.first; @@ -1981,7 +1979,7 @@ lnk_link_image(TP_Context *tp, TP_Arena *arena, LNK_Config *config, LNK_Inputer } // - // report undefined symbols + // report unresolved symbols // { ProfBegin("Report Unresolved Symbols"); @@ -2045,13 +2043,15 @@ lnk_link_image(TP_Context *tp, TP_Arena *arena, LNK_Config *config, LNK_Inputer for EachIndex(sect_idx, obj->header.section_count_no_null) { COFF_SectionHeader *section_header = §ion_table[sect_idx]; + if (section_header->flags & LNK_SECTION_FLAG_DEBUG_INFO) { continue; } + String8 section_name = coff_name_from_section_header(string_table, section_header); U64 section_number = sect_idx+1; COFF_RelocArray relocs = lnk_coff_relocs_from_section_header(obj, section_header); for EachIndex(reloc_idx, relocs.count) { if (supp_info.node_count > config->unresolved_symbol_ref_limit) { str8_list_pushf(scratch.arena, &supp_info, "too many unresolved symbol references reported, stopping now"); - break; + goto next_undefined_symbol; } COFF_Reloc *reloc = &relocs.v[reloc_idx]; if (reloc->isymbol == ref->symbol_idx) { @@ -2059,9 +2059,9 @@ lnk_link_image(TP_Context *tp, TP_Arena *arena, LNK_Config *config, LNK_Inputer CV_Line *line_matches = 0; if (config->map_lines_for_unresolved_symbols == LNK_SwitchState_Yes) { if (debug_lines == 0) { + debug_s = lnk_debug_s_from_obj(scratch.arena, obj); String8List raw_checksums = cv_sub_section_from_debug_s(debug_s, CV_C13SubSectionKind_FileChksms); String8List raw_strings = cv_sub_section_from_debug_s(debug_s, CV_C13SubSectionKind_StringTable); - debug_s = lnk_debug_s_from_obj(scratch.arena, obj); debug_lines = cv_lines_accel_from_debug_s(scratch.arena, debug_s); debug_checksums = str8_list_first(&raw_checksums); debug_strings = str8_list_first(&raw_strings); @@ -2086,6 +2086,7 @@ lnk_link_image(TP_Context *tp, TP_Arena *arena, LNK_Config *config, LNK_Inputer } } } + next_undefined_symbol:; } lnk_error(LNK_Error_UnresolvedSymbol, "unresolved symbol %S", symbol->name); @@ -2141,6 +2142,7 @@ lnk_link_image(TP_Context *tp, TP_Arena *arena, LNK_Config *config, LNK_Inputer } scratch_end(scratch); + ProfEnd(); return link; } @@ -2196,9 +2198,9 @@ lnk_opt_ref(TP_Context *tp, LNK_SymbolTable *symtab, LNK_Config *config, LNK_Obj COFF_SectionHeader *section_header = lnk_coff_section_header_from_section_number(obj, section_number); // is section eligible for walking? - if (lnk_is_coff_section_debug(obj, sect_idx)) { continue; } - if (section_header->flags & COFF_SectionFlag_LnkRemove) { continue; } - if (section_header->flags & COFF_SectionFlag_LnkCOMDAT) { continue; } + if (section_header->flags & LNK_SECTION_FLAG_DEBUG_INFO) { continue; } + if (section_header->flags & COFF_SectionFlag_LnkRemove) { continue; } + if (section_header->flags & COFF_SectionFlag_LnkCOMDAT) { continue; } // divide relocs and push task for each reloc block COFF_RelocArray relocs = lnk_coff_reloc_info_from_section_number(obj, section_number); @@ -2280,9 +2282,9 @@ lnk_opt_ref(TP_Context *tp, LNK_SymbolTable *symtab, LNK_Config *config, LNK_Obj COFF_SectionHeader *section_header = lnk_coff_section_header_from_section_number(ref_obj, section_number); // is section eligible for walking? - if (section_header->flags & COFF_SectionFlag_LnkRemove) { continue; } - if (section_header->flags & LNK_SECTION_FLAG_IS_LIVE) { continue; } - if (lnk_is_coff_section_debug(ref_obj, section_number-1)) { continue; } + if (section_header->flags & COFF_SectionFlag_LnkRemove) { continue; } + if (section_header->flags & LNK_SECTION_FLAG_IS_LIVE) { continue; } + if (section_header->flags & LNK_SECTION_FLAG_DEBUG_INFO) { continue; } // mark section section_header->flags |= LNK_SECTION_FLAG_IS_LIVE; @@ -2312,8 +2314,7 @@ lnk_opt_ref(TP_Context *tp, LNK_SymbolTable *symtab, LNK_Config *config, LNK_Obj U32 section_number = sect_idx+1; COFF_SectionHeader *section_header = lnk_coff_section_header_from_section_number(obj, section_number); - - if (lnk_is_coff_section_debug(obj, sect_idx)) { continue; } + if (section_header->flags & LNK_SECTION_FLAG_DEBUG_INFO) { continue; } // remove unreferenced sections if (~section_header->flags & LNK_SECTION_FLAG_IS_LIVE && section_header->flags & COFF_SectionFlag_LnkCOMDAT) { @@ -2520,7 +2521,8 @@ THREAD_POOL_TASK_FUNC(lnk_flag_debug_symbols_task) symbol = lnk_parsed_symbol_from_coff_symbol_idx(obj, symbol_idx); COFF_SymbolValueInterpType interp = coff_interp_symbol(symbol.section_number, symbol.value, symbol.storage_class); if (interp == COFF_SymbolValueInterp_Regular) { - if (lnk_is_coff_section_debug(obj, symbol.section_number-1)) { + COFF_SectionHeader *section_header = lnk_coff_section_header_from_section_number(obj, symbol.section_number); + if (section_header->flags & LNK_SECTION_FLAG_DEBUG_INFO) { task->u.patch_symtabs.was_symbol_patched[obj_idx][symbol_idx] = 1; } } @@ -2827,9 +2829,9 @@ THREAD_POOL_TASK_FUNC(lnk_obj_reloc_patcher) LNK_Obj *obj = task->objs[task_id]; COFF_FileHeaderInfo obj_header = obj->header; - COFF_SectionHeader *section_table = (COFF_SectionHeader *)str8_substr(obj->data, obj_header.section_table_range).str; - String8 symbol_table = str8_substr(obj->data, obj_header.symbol_table_range); - String8 string_table = str8_substr(obj->data, obj_header.string_table_range); + COFF_SectionHeader *section_table = lnk_coff_section_table_from_obj(obj); + String8 symbol_table = lnk_coff_symbol_table_from_obj(obj); + String8 string_table = lnk_coff_string_table_from_obj(obj); U32 closest_sect = 0; U32 closest_reloc = 0; @@ -2838,11 +2840,12 @@ THREAD_POOL_TASK_FUNC(lnk_obj_reloc_patcher) for EachIndex(sect_idx, obj_header.section_count_no_null) { COFF_SectionHeader *section_header = §ion_table[sect_idx]; + if (section_header->flags & COFF_SectionFlag_LnkInfo) { continue; } if (section_header->flags & COFF_SectionFlag_LnkRemove) { continue; } if (section_header->flags & COFF_SectionFlag_CntUninitializedData) { continue; } // get section bytes (special case debug info because it is not copied to the image) - String8 data = lnk_is_coff_section_debug(obj, sect_idx) ? obj->data : task->image_data; + String8 data = section_header->flags & LNK_SECTION_FLAG_DEBUG_INFO ? obj->data : task->image_data; Rng1U64 section_frange = rng_1u64(section_header->foff, section_header->foff + section_header->fsize); String8 section_data = str8_substr(data, section_frange); @@ -2857,7 +2860,8 @@ THREAD_POOL_TASK_FUNC(lnk_obj_reloc_patcher) lnk_error_obj(LNK_Error_IllegalRelocation, obj, "unknown relocation type 0x%x", reloc->type); } } else if (obj->header.machine != COFF_MachineType_Unknown) { - NotImplemented; + lnk_not_implemented("relocation patching is not implemented for %S", coff_string_from_machine_type(obj->header.machine)); + continue; } // compute virtual offsets @@ -2869,16 +2873,15 @@ THREAD_POOL_TASK_FUNC(lnk_obj_reloc_patcher) S64 symbol_voff = 0; { COFF_ParsedSymbol symbol = lnk_parsed_symbol_from_coff_symbol_idx(obj, reloc->isymbol); - COFF_SymbolValueInterpType interp = coff_interp_symbol(symbol.section_number, symbol.value, symbol.storage_class); + COFF_SymbolValueInterpType interp = coff_interp_from_parsed_symbol(symbol); if (interp == COFF_SymbolValueInterp_Regular) { if (symbol.section_number == lnk_obj_get_removed_section_number(obj)) { - if (!lnk_is_coff_section_debug(obj, sect_idx)) { + if (~section_header->flags & LNK_SECTION_FLAG_DEBUG_INFO) { String8 sect_name = coff_name_from_section_header(string_table, §ion_table[sect_idx]); lnk_error_obj(LNK_Error_RelocationAgainstRemovedSection, obj, "relocating against symbol that is in a removed section (symbol: %S, reloc-section: %S 0x%llx, reloc-index: 0x%llx)", symbol.name, sect_name, sect_idx+1, reloc_idx); } continue; } - symbol_secnum = symbol.section_number; symbol_secoff = symbol.value; symbol_voff = safe_cast_u32((U64)task->image_section_table[symbol.section_number]->voff + (U64)symbol_secoff); @@ -2889,7 +2892,6 @@ THREAD_POOL_TASK_FUNC(lnk_obj_reloc_patcher) if (str8_match(symbol.name, str8_lit("__ImageBase"), 0)) { symbol.value = task->image_base; } - symbol_secnum = 0; symbol_secoff = 0; symbol_voff = (S64)symbol.value - (S64)task->image_base; @@ -3459,7 +3461,7 @@ THREAD_POOL_TASK_FUNC(lnk_patch_file_offsets_and_sizes_in_obj_section_headers_ta for (U64 sect_idx = 0; sect_idx < obj->header.section_count_no_null; sect_idx += 1) { COFF_SectionHeader *sect_header = §ion_table[sect_idx]; B32 patch_section_header = (~sect_header->flags & COFF_SectionFlag_LnkRemove) && - !lnk_is_coff_section_debug(obj, sect_idx); + (~sect_header->flags & LNK_SECTION_FLAG_DEBUG_INFO); if (patch_section_header) { LNK_SectionContrib *sc = task->sect_map[obj_idx][sect_idx]; LNK_Section *sect = task->image_sects.v[sc->u.sect_idx]; @@ -4732,17 +4734,15 @@ lnk_build_rad_map(Arena *arena, String8 image_data, LNK_Config *config, U64 objs LNK_Obj *obj = objs[obj_idx]; COFF_SectionHeader *section_table = str8_deserial_get_raw_ptr(obj->data, obj->header.section_table_range.min, 0); for (U64 sect_idx = 0; sect_idx < obj->header.section_count_no_null; sect_idx += 1) { - if (lnk_is_coff_section_debug(obj, sect_idx)) { - COFF_SectionHeader *section_header = §ion_table[sect_idx]; - if (~section_header->flags & COFF_SectionFlag_LnkRemove) { - LNK_Lib *lib = lnk_obj_get_lib(obj); - if (lib) { - String8 lib_name = str8_chop_last_dot(str8_skip_last_slash(lib->path)); - String8 obj_name = str8_skip_last_slash(obj->path); - str8_list_pushf(arena, &map, "%S(%S) SECT%X\n", lib_name, obj_name, sect_idx+1); - } else { - str8_list_pushf(arena, &map, "%S SECT%X\n", obj->path, sect_idx+1); - } + COFF_SectionHeader *section_header = §ion_table[sect_idx]; + if (~section_header->flags & COFF_SectionFlag_LnkRemove && section_header->flags & LNK_SECTION_FLAG_DEBUG_INFO) { + LNK_Lib *lib = lnk_obj_get_lib(obj); + if (lib) { + String8 lib_name = str8_chop_last_dot(str8_skip_last_slash(lib->path)); + String8 obj_name = str8_skip_last_slash(obj->path); + str8_list_pushf(arena, &map, "%S(%S) SECT%X\n", lib_name, obj_name, sect_idx+1); + } else { + str8_list_pushf(arena, &map, "%S SECT%X\n", obj->path, sect_idx+1); } } } diff --git a/src/linker/lnk.h b/src/linker/lnk.h index afe090da0..a3f7909c5 100644 --- a/src/linker/lnk.h +++ b/src/linker/lnk.h @@ -73,21 +73,23 @@ typedef struct LNK_Inputer #define LNK_IMPORT_STUB "*** RAD_IMPORT_STUB ***" #define LNK_NULL_SYMBOL "*** RAD_NULL_SYMBOL ***" -#define LNK_SECTION_FLAG_IS_LIVE (1 << 0) +#define LNK_SECTION_FLAG_IS_LIVE (1 << 0) +#define LNK_SECTION_FLAG_DEBUG_INFO (1 << 1) typedef struct LNK_ImportTables { - Arena *arena; + Arena *arena; String8List delayed_dll_names; String8List static_dll_names; - HashTable *static_imports; - HashTable *delayed_imports; + HashTable *static_imports; + HashTable *delayed_imports; } LNK_ImportTables; typedef struct LNK_Link { LNK_ObjList objs; LNK_LibList libs; + LNK_ObjNode **last_symbol_input; LNK_IncludeSymbolNode **last_include; String8Node **last_cmd_lib; String8Node **last_default_lib; diff --git a/src/linker/lnk_debug_info.c b/src/linker/lnk_debug_info.c index acc4ac15c..1e99fa7f5 100644 --- a/src/linker/lnk_debug_info.c +++ b/src/linker/lnk_debug_info.c @@ -549,29 +549,11 @@ lnk_make_code_view_input(TP_Context *tp, TP_Arena *tp_arena, LNK_IO_Flags io_fla CV_TypeServerInfo ts = cv_type_server_info_from_leaf(leaf); // search disk for type server - String8List match_list = lnk_file_search(scratch.arena, lib_dir_list, ts.name); - - // chop file name from path and search on it - // - // TODO: check if ts.name is a path and in that case do file search - if (match_list.node_count == 0) { - String8 file_name = str8_skip_last_slash(ts.name); - match_list = lnk_file_search(scratch.arena, lib_dir_list, file_name); - } + String8 type_server_path = lnk_find_first_file(scratch.arena, lib_dir_list, ts.name); + // report no match B32 do_debug_info_discard = 0; - - // too many matches? - if (match_list.node_count > 1) { - if (!hash_table_search_path(ignored_path_ht, ts.name)) { - hash_table_push_path_u64(scratch.arena, ignored_path_ht, ts.name, 0); - lnk_error_obj(LNK_Warning_MultipleExternalTypeServers, obj_arr[obj_idx], "located multiple external type servers:"); - lnk_supplement_error_list(match_list); - } - do_debug_info_discard = 1; - } - // no match? - else if (match_list.node_count == 0) { + if (type_server_path.size == 0) { if (!hash_table_search_path(ignored_path_ht, ts.name)) { hash_table_push_string_u64(scratch.arena, ignored_path_ht, ts.name, 0); lnk_error_obj(LNK_Warning_MissingExternalTypeServer, obj_arr[obj_idx], "unable to open external type server %S", ts.name); @@ -585,7 +567,6 @@ lnk_make_code_view_input(TP_Context *tp, TP_Arena *tp_arena, LNK_IO_Flags io_fla continue; } - String8 path = match_list.first->string; { struct HT_Value { CV_TypeServerInfo ts; @@ -594,7 +575,7 @@ lnk_make_code_view_input(TP_Context *tp, TP_Arena *tp_arena, LNK_IO_Flags io_fla }; // was this type server queued? - KeyValuePair *is_path_queued = hash_table_search_path(type_server_path_ht, path); + KeyValuePair *is_path_queued = hash_table_search_path(type_server_path_ht, type_server_path); if (is_path_queued) { struct HT_Value *present = is_path_queued->value_raw; @@ -616,12 +597,12 @@ lnk_make_code_view_input(TP_Context *tp, TP_Arena *tp_arena, LNK_IO_Flags io_fla // when we search matches on disk we store path on scratch, // make path copy in case we need it for error reporting - path = push_str8_copy(tp_arena->v[0], path); + type_server_path = push_str8_copy(tp_arena->v[0], type_server_path); // fill out type server info we read from obj CV_TypeServerInfoNode *ts_info_node = push_array(scratch.arena, CV_TypeServerInfoNode, 1); ts_info_node->data = ts; - ts_info_node->data.name = path; + ts_info_node->data.name = type_server_path; // push to type server info list SLLQueuePush(ts_info_list.first, ts_info_list.last, ts_info_node); @@ -640,7 +621,7 @@ lnk_make_code_view_input(TP_Context *tp, TP_Arena *tp_arena, LNK_IO_Flags io_fla value->ts_idx = ts_idx; // update hash table - hash_table_push_path_raw(scratch.arena, type_server_path_ht, path, value); + hash_table_push_path_raw(scratch.arena, type_server_path_ht, type_server_path, value); } } } @@ -2953,12 +2934,9 @@ THREAD_POOL_TASK_FUNC(lnk_push_dbi_sec_contrib_task) for (U64 sect_idx = 0; sect_idx < obj->header.section_count_no_null; sect_idx += 1) { COFF_SectionHeader *obj_sect_header = &obj_section_table[sect_idx]; - if (obj_sect_header->flags & COFF_SectionFlag_LnkRemove) { - continue; - } - if (lnk_is_coff_section_debug(obj, sect_idx)) { - continue; - } + if (obj_sect_header->flags & COFF_SectionFlag_LnkInfo) { continue; } + if (obj_sect_header->flags & COFF_SectionFlag_LnkRemove) { continue; } + if (obj_sect_header->flags & LNK_SECTION_FLAG_DEBUG_INFO) { continue; } U64 sect_number; String8 sect_data; diff --git a/src/linker/lnk_io.c b/src/linker/lnk_io.c index c96266173..49172cfec 100644 --- a/src/linker/lnk_io.c +++ b/src/linker/lnk_io.c @@ -48,51 +48,27 @@ lnk_write_file(void *raw_handle, uint64_t offset, void *buffer, uint64_t buffer_ return write_size; } -internal String8List -lnk_file_search(Arena *arena, String8List dir_list, String8 file_path) +internal String8 +lnk_find_first_file(Arena *arena, String8List dir_list, String8 path) { ProfBeginFunction(); - Temp scratch = scratch_begin(&arena, 1); - String8List match_list; MemoryZeroStruct(&match_list); - - if (os_file_path_exists(file_path)) { - String8 str = push_str8_copy(arena, file_path); - str8_list_push(arena, &match_list, str); - } - - PathStyle file_path_style = path_style_from_str8(file_path); - B32 is_relative = file_path_style != PathStyle_WindowsAbsolute && - file_path_style != PathStyle_UnixAbsolute; - - if (is_relative) { - for (String8Node *i = dir_list.first; i != 0; i = i->next) { - String8List path_list = {0}; - str8_list_push(scratch.arena, &path_list, i->string); - str8_list_push(scratch.arena, &path_list, file_path); - String8 path = str8_path_list_join_by_style(scratch.arena, &path_list, PathStyle_SystemAbsolute); - B32 file_exists = os_file_path_exists(path); - if (file_exists) { - B32 is_unique = 1; - OS_FileID file_id = os_id_from_file_path(path); - for (String8Node *k = match_list.first; k != 0; k = k->next) { - OS_FileID test_id = os_id_from_file_path(k->string); - int cmp = os_file_id_compare(test_id, file_id) != 0; - if (cmp == 0) { - is_unique = 0; - break; - } - } - if (is_unique) { - String8 str = push_str8_copy(arena, path); - str8_list_push(arena, &match_list, str); - } + String8 result = {0}; + if (os_file_path_exists(path)) { + result = path; + } else { + Temp scratch = scratch_begin(&arena, 1); + String8 file_name = str8_skip_last_slash(path); + for EachNode(n, String8Node, dir_list.first) { + String8 full_path = push_str8f(scratch.arena, "%S/%S", n->string, file_name); + if (os_file_path_exists(full_path)) { + result = push_str8_copy(arena, full_path); + break; } } + scratch_end(scratch); } - - scratch_end(scratch); ProfEnd(); - return match_list; + return result; } internal OS_Handle diff --git a/src/linker/lnk_io.h b/src/linker/lnk_io.h index 3e1b1705f..767954278 100644 --- a/src/linker/lnk_io.h +++ b/src/linker/lnk_io.h @@ -28,8 +28,6 @@ shared_function uint64_t lnk_write_file(void *raw_handle, uint64_t offset, void // --- IO Functions ------------------------------------------------------------ -internal String8List lnk_file_search(Arena *arena, String8List dir_list, String8 file_path); - internal OS_Handle lnk_file_open_with_rename_permissions(String8 path); internal B32 lnk_file_set_delete_on_close(OS_Handle handle, B32 delete_file); internal B32 lnk_file_rename(OS_Handle handle, String8 new_name); diff --git a/src/linker/lnk_lib.c b/src/linker/lnk_lib.c index 1f317a161..bcf06da7d 100644 --- a/src/linker/lnk_lib.c +++ b/src/linker/lnk_lib.c @@ -23,8 +23,6 @@ lnk_first_member_sort_key_is_before(void *raw_a, void *raw_b) internal B32 lnk_lib_from_data(Arena *arena, String8 data, String8 path, U64 input_idx, LNK_Lib *lib_out) { - ProfBeginFunction(); - // is data archive? COFF_ArchiveType type = coff_archive_type_from_data(data); if (type == COFF_Archive_Null) { @@ -112,7 +110,7 @@ lnk_lib_from_data(Arena *arena, String8 data, String8 path, U64 input_idx, LNK_L // parse symbol names { Temp scratch = scratch_begin(&arena, 1); - String8List symbol_name_list = str8_split_by_string_chars(scratch.arena, first_member.string_table, str8_lit("\0"), StringSplitFlag_KeepEmpties); + String8List symbol_name_list = str8_split_by_string_chars(scratch.arena, first_member.string_table, str8_lit("\0"), 0); Assert(symbol_name_list.node_count >= first_member.symbol_count); symbol_names = str8_array_from_list(arena, &symbol_name_list); scratch_end(scratch); @@ -147,7 +145,6 @@ lnk_lib_from_data(Arena *arena, String8 data, String8 path, U64 input_idx, LNK_L lib_out->long_names = parse.long_names; lib_out->input_idx = input_idx; - ProfEnd(); return 1; } @@ -228,13 +225,22 @@ lnk_lib_set_link_symbol(LNK_Lib *lib, U32 member_idx, LNK_Symbol *link_symbol) { local_persist LNK_Symbol null_symbol; - LNK_Symbol *slot = ins_atomic_ptr_eval_assign(&lib->was_member_linked[member_idx], &null_symbol); - B32 is_first_set = (slot == 0); + B32 is_first_set; + + LNK_Symbol *slot = ins_atomic_ptr_eval_assign(&lib->was_member_linked[member_idx], &null_symbol); for (;;) { + is_first_set = (slot == 0); + // update slot symbol if it is empty or link symbol comes before symbol in the slot if (slot && slot != &null_symbol) { - if (lnk_symbol_is_before(slot, link_symbol)) { + if (!str8_starts_with(link_symbol->name, str8_lit("__imp_")) && str8_starts_with(slot->name, str8_lit("__imp_"))) { + // replace import address symbol with jump thunk symbol + slot = link_symbol; + is_first_set = 1; + } else if (str8_starts_with(link_symbol->name, str8_lit("__imp_")) && !str8_starts_with(slot->name, str8_lit("__imp_"))) { + // no need to replace + } else if (lnk_symbol_is_before(slot, link_symbol)) { slot = link_symbol; } } else { diff --git a/src/linker/lnk_obj.c b/src/linker/lnk_obj.c index ac4ca13f9..d16155be8 100644 --- a/src/linker/lnk_obj.c +++ b/src/linker/lnk_obj.c @@ -259,6 +259,19 @@ THREAD_POOL_TASK_FUNC(lnk_obj_initer) } } } + + // + // mark debug info sections + // + { + for EachIndex(sect_idx, header.section_count_no_null) { + COFF_SectionHeader *sect_header = &coff_section_table[sect_idx]; + String8 sect_name = str8_cstring_capped(sect_header->name, sect_header->name + sizeof(sect_header->name)); + if (str8_starts_with(sect_name, str8_lit(".debug$"))) { + sect_header->flags |= LNK_SECTION_FLAG_DEBUG_INFO; + } + } + } B8 hotpatch = 0; if (header.machine == COFF_MachineType_X64) { @@ -271,25 +284,27 @@ THREAD_POOL_TASK_FUNC(lnk_obj_initer) Temp scratch = scratch_begin(&arena, 1); CV_Symbol comp_symbol = {0}; - for (U64 sect_idx = 0; sect_idx < header.section_count_no_null; sect_idx += 1) { + for EachIndex(sect_idx, header.section_count_no_null) { COFF_SectionHeader *sect_header = &coff_section_table[sect_idx]; - String8 name = str8_cstring_capped(sect_header->name, sect_header->name+sizeof(sect_header->name)); - if (str8_match(name, str8_lit(".debug$S"), 0)) { - Temp temp = temp_begin(scratch.arena); - String8 debug_s_data = str8_substr(input->data, rng_1u64(sect_header->foff, sect_header->foff+sect_header->fsize)); - CV_DebugS debug_s = cv_parse_debug_s(temp.arena, debug_s_data); - for (String8Node *symbols_n = debug_s.data_list[CV_C13SubSectionIdxKind_Symbols].first; symbols_n != 0; symbols_n = symbols_n->next) { - CV_SymbolList symbol_list = {0}; - cv_parse_symbol_sub_section_capped(scratch.arena, &symbol_list, 0, symbols_n->string, CV_SymbolAlign, 2); - if (symbol_list.first->data.kind == CV_SymKind_COMPILE3) { - comp_symbol = symbol_list.first->data; - goto found_comp_symbol; - } else if (symbol_list.last->data.kind == CV_SymKind_COMPILE3) { - comp_symbol = symbol_list.last->data; - goto found_comp_symbol; + if (sect_header->flags & LNK_SECTION_FLAG_DEBUG_INFO) { + String8 name = str8_cstring_capped(sect_header->name, sect_header->name+sizeof(sect_header->name)); + if (str8_match(name, str8_lit(".debug$S"), 0)) { + Temp temp = temp_begin(scratch.arena); + String8 debug_s_data = str8_substr(input->data, rng_1u64(sect_header->foff, sect_header->foff+sect_header->fsize)); + CV_DebugS debug_s = cv_parse_debug_s(temp.arena, debug_s_data); + for EachNode(symbols_n, String8Node, debug_s.data_list[CV_C13SubSectionIdxKind_Symbols].first) { + CV_SymbolList symbol_list = {0}; + cv_parse_symbol_sub_section_capped(scratch.arena, &symbol_list, 0, symbols_n->string, CV_SymbolAlign, 2); + if (symbol_list.first->data.kind == CV_SymKind_COMPILE3) { + comp_symbol = symbol_list.first->data; + goto found_comp_symbol; + } else if (symbol_list.last->data.kind == CV_SymKind_COMPILE3) { + comp_symbol = symbol_list.last->data; + goto found_comp_symbol; + } } + temp_end(temp); } - temp_end(temp); } } found_comp_symbol:; @@ -312,8 +327,6 @@ THREAD_POOL_TASK_FUNC(lnk_obj_initer) obj->associated_sections = associated_sections; obj->node = &task->objs[task_id]; obj->link_member = input->link_member; - - ProfEnd(); } internal LNK_ObjNode * @@ -529,6 +542,12 @@ lnk_coff_string_table_from_obj(LNK_Obj *obj) return str8_substr(obj->data, obj->header.string_table_range); } +internal String8 +lnk_coff_symbol_table_from_obj(LNK_Obj *obj) +{ + return str8_substr(obj->data, obj->header.symbol_table_range); +} + internal COFF_RelocArray lnk_coff_reloc_info_from_section_number(LNK_Obj *obj, U64 section_number) { @@ -552,20 +571,6 @@ lnk_try_comdat_props_from_section_number(LNK_Obj *obj, U32 section_number, COFF_ return 0; } -internal B32 -lnk_is_coff_section_debug(LNK_Obj *obj, U64 sect_idx) -{ - String8 string_table = str8_substr(obj->data, obj->header.string_table_range); - COFF_SectionHeader *section_header = lnk_coff_section_header_from_section_number(obj, sect_idx+1); - - String8 full_name = coff_name_from_section_header(string_table, section_header); - String8 name, postfix; - coff_parse_section_name(full_name, &name, &postfix); - - B32 is_debug = str8_match(name, str8_lit(".debug"), 0); - return is_debug; -} - internal COFF_ParsedSymbol lnk_parsed_symbol_from_coff_symbol_idx(LNK_Obj *obj, U64 symbol_idx) { diff --git a/src/linker/lnk_obj.h b/src/linker/lnk_obj.h index 3f4497258..9fca1cb59 100644 --- a/src/linker/lnk_obj.h +++ b/src/linker/lnk_obj.h @@ -119,8 +119,8 @@ internal COFF_SectionHeader * lnk_coff_section_header_from_section_number(LNK_Ob internal COFF_RelocArray lnk_coff_relocs_from_section_header(LNK_Obj *obj, COFF_SectionHeader *section_header); internal COFF_SectionHeader * lnk_coff_section_table_from_obj(LNK_Obj *obj); internal String8 lnk_coff_string_table_from_obj(LNK_Obj *obj); +internal String8 lnk_coff_symbol_table_from_obj(LNK_Obj *obj); internal B32 lnk_try_comdat_props_from_section_number(LNK_Obj *obj, U32 section_number, COFF_ComdatSelectType *select_out, U32 *section_number_out, U32 *section_length_out, U32 *check_sum_out); -internal B32 lnk_is_coff_section_debug(LNK_Obj *obj, U64 sect_idx); // --- Helpers ----------------------------------------------------------------- diff --git a/src/linker/lnk_symbol_table.c b/src/linker/lnk_symbol_table.c index 270a4c57b..94bc4ddb3 100644 --- a/src/linker/lnk_symbol_table.c +++ b/src/linker/lnk_symbol_table.c @@ -675,7 +675,7 @@ lnk_resolve_weak_symbol(LNK_SymbolTable *symtab, LNK_ObjSymbolRef symbol, LNK_Ob LNK_Symbol *dep_symbol = lnk_symbol_table_search(symtab, tag_parsed.name); tag_interp = lnk_interp_from_symbol(dep_symbol); } - if (tag_interp == COFF_SymbolValueInterp_Weak) { goto exit; } + if (tag_interp == COFF_SymbolValueInterp_Weak) { break; } } } else if (current_interp == COFF_SymbolValueInterp_Undefined) { LNK_Symbol *defn_symbol = lnk_symbol_table_search(symtab, current_parsed.name); diff --git a/src/os/core/win32/os_core_win32.c b/src/os/core/win32/os_core_win32.c index d90d68ffd..510d85c46 100644 --- a/src/os/core/win32/os_core_win32.c +++ b/src/os/core/win32/os_core_win32.c @@ -1158,6 +1158,7 @@ internal void os_mutex_release(Mutex mutex) { OS_W32_Entity *entity = (OS_W32_Entity*)PtrFromInt(mutex.u64[0]); + DeleteCriticalSection(&entity->mutex); os_w32_entity_release(entity); } diff --git a/src/os/gfx/win32/os_gfx_win32.c b/src/os/gfx/win32/os_gfx_win32.c index dac8bde75..fbd9cdbf9 100644 --- a/src/os/gfx/win32/os_gfx_win32.c +++ b/src/os/gfx/win32/os_gfx_win32.c @@ -507,10 +507,6 @@ os_w32_wnd_proc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) if(character >= 32 && character != 127) { OS_Event *event = os_w32_push_event(OS_EventKind_Text, window); - if(lParam & bit29) - { - event->modifiers |= OS_Modifier_Alt; - } event->character = character; } }break; diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 21bec84af..cbcc65e86 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -11833,10 +11833,6 @@ rd_frame(void) rd_cmd(RD_CmdKind_InsertText, .string = insertion8); rd_request_frame(); take = 1; - if(event->modifiers & OS_Modifier_Alt) - { - ws->menu_bar_focus_press_started = 0; - } } //- rjf: do fall-through