diff --git a/build.bat b/build.bat index 4df25f43..8dc8dbb1 100644 --- a/build.bat +++ b/build.bat @@ -164,7 +164,7 @@ if "%didbuild%"=="" ( if "%pgo_run%"=="1" ( if "%radlink%"=="1" ( pushd local\lyra_pgo - call %~dp0build\radlink @lyra.rsp /rad_alt_pch_dir:%~dp0local\lyra_pgo || exit /b 1 + call %~dp0build\radlink @lyra.rsp || exit /b 1 popd ) goto restart diff --git a/src/linker/lnk_config.c b/src/linker/lnk_config.c index 3d27012c..c3e17e6b 100644 --- a/src/linker/lnk_config.c +++ b/src/linker/lnk_config.c @@ -62,7 +62,6 @@ global read_only LNK_CmdSwitch g_cmd_switch_map[] = { LNK_CmdSwitch_WholeArchive, 0, "WHOLEARCHIVE", "[:LIBNAME]", "Force linker to pull in all objs from the specified lib." }, { LNK_CmdSwitch_Rad_Age, 0, "RAD_AGE", ":#", "Age embeded in EXE and PDB, used to validate incremental build. Default is 1." }, - { LNK_CmdSwitch_Rad_AltPchDir, 0, "RAD_ALT_PCH_DIR", ":PATH", "Alternative directory to search for PCH object files." }, //{ LNK_CmdSwitch_Rad_BuildExp, 0, "RAD_BUILD_EXP", "[:NO]", "Build export data." }, { LNK_CmdSwitch_Rad_BuildInfo, 0, "RAD_BUILD_INFO", "", "Print build info and exit." }, { LNK_CmdSwitch_Rad_BuildImpLib, 0, "RAD_BUILD_IMPLIB", "[:NO]", "Build import library." }, @@ -1805,15 +1804,6 @@ lnk_apply_cmd_option_to_config(LNK_Config *config, String8 cmd_name, String8List lnk_cmd_switch_parse_u32(obj, cmd_switch, value_strings, &config->age, 0); } break; - case LNK_CmdSwitch_Rad_AltPchDir: { - if (value_strings.node_count == 0) { - lnk_error_cmd_switch(LNK_Error_Cmdl, obj, cmd_switch, "missing parameters"); - break; - } - String8List dirs = str8_list_copy(config->arena, &value_strings); - str8_list_concat_in_place(&config->alt_pch_dirs, &dirs); - } break; - //case LNK_CmdSwitch_Rad_BuildExp: { // LNK_SwitchState state; // if (lnk_cmd_switch_parse_flag(obj, cmd_switch, value_strings, &state)) { diff --git a/src/linker/lnk_config.h b/src/linker/lnk_config.h index 0b6d7964..267124c8 100644 --- a/src/linker/lnk_config.h +++ b/src/linker/lnk_config.h @@ -96,7 +96,6 @@ typedef enum LNK_CmdSwitch_WholeArchive, LNK_CmdSwitch_Rad_Age, - LNK_CmdSwitch_Rad_AltPchDir, LNK_CmdSwitch_Rad_BuildExp, LNK_CmdSwitch_Rad_BuildInfo, LNK_CmdSwitch_Rad_BuildImpLib, @@ -383,7 +382,6 @@ typedef struct LNK_Config U64 unresolved_symbol_limit; U64 unresolved_symbol_ref_limit; LNK_SwitchState map_lines_for_unresolved_symbols; - String8List alt_pch_dirs; LLVM_GHashAlg type_hash_alg; String8 type_server_name; LNK_SwitchState type_server; diff --git a/src/linker/lnk_debug_info.c b/src/linker/lnk_debug_info.c index 3b6eabb4..fe125133 100644 --- a/src/linker/lnk_debug_info.c +++ b/src/linker/lnk_debug_info.c @@ -954,38 +954,29 @@ lnk_make_code_view_input(TP_Context *tp, TP_Arena *tp_arena, LNK_Config *config, ProfBegin("Set up PCH"); { - // pre-build PCH obj hash map (obj_path, obj_idx) + // register PCH file paths HashMap debug_p_hm_path = {0}; - HashMap debug_p_hm_sig = {0}; + HashMap debug_p_hm_name = {0}; // (obj name, U64List of PCH obj indices) for EachIndex(i, input.debug_p_indices.count) { U64 obj_idx = input.debug_p_indices.v[i]; LNK_Obj *obj = obj_arr[obj_idx]; - // register PCH signature - CV_DebugT debug_p = input.debug_t_arr[obj_idx]; - if (debug_p.count > 0) { - CV_Leaf lf = cv_debug_t_get_leaf(&debug_p, debug_p.count - 1); - if (lf.kind == CV_LeafKind_ENDPRECOMP && lf.data.size <= sizeof(CV_LeafEndPreComp)) { - CV_LeafEndPreComp *ender = str8_deserial_get_raw_ptr(lf.data, 0, sizeof(*ender)); - if (ender->sig) { - U64 *extant_obj_idx = hash_map_search_u64_u64(&debug_p_hm_sig, ender->sig); - if (extant_obj_idx == 0) { - hash_map_push_u64_u64(scratch.arena, &debug_p_hm_sig, ender->sig, obj_idx); - } else { - LNK_Obj *extant_obj = obj_arr[*extant_obj_idx]; - lnk_log(LNK_Log_Debug, "%S: PCH signature is already defined in %S", lnk_loc_from_obj(scratch.arena, obj), lnk_loc_from_obj(scratch.arena, extant_obj)); - } - } - } - } - - // register PCH path + // register file path -> obj idx map String8 obj_path = path_absolute_dst_from_relative_dst_src(scratch.arena, obj_arr[obj_idx]->path, config->work_dir); if (hash_map_search_path_u64(&debug_p_hm_path, obj_path)) { lnk_error_obj(LNK_Warning_DuplicateObjPath, obj, "duplicate obj path %S", obj_path); } else { hash_map_push_path_u64(scratch.arena, &debug_p_hm_path, obj_path, obj_idx); } + + // register file name -> obj idx map + String8 obj_name = str8_skip_last_slash(obj_path); + U64List *match_indices = hash_map_search_path_raw(&debug_p_hm_name, obj_name); + if (match_indices == 0) { + match_indices = push_array(scratch.arena, U64List, 1); + hash_map_push_path_raw(scratch.arena, &debug_p_hm_name, obj_name, match_indices); + } + u64_list_push(scratch.arena, match_indices, obj_idx); } for EachIndex(i, input.int_obj_indices.count) { @@ -995,32 +986,37 @@ lnk_make_code_view_input(TP_Context *tp, TP_Arena *tp_arena, LNK_Config *config, // skip objs that do not depend on PCH if ( ! cv_debug_t_is_pch(debug_t)) { continue; } - // find PCH obj + // find PCH obj by file path CV_PrecompInfo precomp = cv_precomp_info_from_leaf(cv_debug_t_get_leaf(debug_t, 0)); String8 obj_path = path_absolute_dst_from_relative_dst_src(scratch.arena, precomp.obj_name, config->work_dir); U64 *debug_p_obj_idx_ptr = hash_map_search_path_u64(&debug_p_hm_path, obj_path); - if (debug_p_obj_idx_ptr == 0) { - debug_p_obj_idx_ptr = hash_map_search_u64_u64(&debug_p_hm_sig, precomp.sig); - } + U64 debug_p_obj_idx = debug_p_obj_idx_ptr ? *debug_p_obj_idx_ptr : max_U64; - // try alternative directory for the PCH + // find PCH obj by signature if (debug_p_obj_idx_ptr == 0) { - String8 obj_name = str8_skip_last_slash(obj_path); - for EachNode(alt_dir_n, String8Node, config->alt_pch_dirs.first) { - String8 alt_obj_path = str8f(scratch.arena, "%S/%S", alt_dir_n->string, obj_name); - debug_p_obj_idx_ptr = hash_map_search_path_u64(&debug_p_hm_path, alt_obj_path); - if (debug_p_obj_idx_ptr) { break; } + for EachIndex(pch_i, input.debug_p_indices.count) { + U64 pch_obj_idx = input.debug_p_indices.v[pch_i]; + CV_DebugT *pch_debug_t = &input.debug_t_arr[pch_obj_idx]; + if (precomp.leaf_count >= pch_debug_t->count) { continue; } + + CV_Leaf end_leaf = cv_debug_t_get_leaf(pch_debug_t, precomp.leaf_count); + if (end_leaf.kind != CV_LeafKind_ENDPRECOMP) { continue; } + if (end_leaf.data.size < sizeof(CV_LeafEndPreComp)) { continue; } + + CV_LeafEndPreComp *end_precomp = str8_deserial_get_raw_ptr(end_leaf.data, 0, sizeof(*end_precomp)); + if (end_precomp->sig != precomp.sig) { continue; } + + debug_p_obj_idx = pch_obj_idx; + break; } } - if (debug_p_obj_idx_ptr == 0) { + if (debug_p_obj_idx > input.obj_count) { lnk_error_obj(LNK_Error_PrecompObjNotFound, obj_arr[obj_idx], "LF_PRECOMP references non-existent obj %S; discarding debug info", obj_path); lnk_discard_cv_debug_info(&input, obj_idx); continue; } - U64 debug_p_obj_idx = *debug_p_obj_idx_ptr; - // get PCH leaf data CV_DebugT *debug_p = &input.debug_t_arr[debug_p_obj_idx]; diff --git a/src/linker/lnk_log.h b/src/linker/lnk_log.h index 7f24bb30..8c087009 100644 --- a/src/linker/lnk_log.h +++ b/src/linker/lnk_log.h @@ -43,7 +43,6 @@ typedef enum LNK_Error_NoAccess, LNK_Error_NoSubsystem, LNK_Error_OutOfExportOrdinals, - LNK_Error_PrecompObjNotFound, LNK_Error_Telemetry, LNK_Error_UnsupportedMachine, LNK_Error_Mt, @@ -78,6 +77,7 @@ typedef enum LNK_Error_InvalidLib, LNK_Error_UnresolvedSymbol, LNK_Error_PrecompSigMismatch, + LNK_Error_PrecompObjNotFound, LNK_Error_ContinueLast, LNK_Warning_First,