sort import library member refs by input index

This commit is contained in:
Nikita Smith
2026-06-23 12:32:52 -07:00
committed by Ryan Fleury
parent ad20900fc0
commit 765b61152d
3 changed files with 42 additions and 10 deletions
+32 -7
View File
@@ -168,6 +168,7 @@ lnk_make_default_cmd_line(Arena *arena, LNK_CmdLine user_cmd_line)
"/RAD_MAP_LINES_FOR_UNRESOLVED_SYMBOLS",
"/RAD_UNRESOLVED_SYMBOL_LIMIT:1000",
"/RAD_UNRESOLVED_SYMBOL_REF_LIMIT:10",
"/RAD_SORT_IMPORTS",
(char*)str8f(scratch.arena, "/RAD_MT_PATH:%s", LNK_MANIFEST_MERGE_TOOL_NAME).str,
(char*)str8f(scratch.arena, "/RAD_DATA_DIR_COUNT:%u", PE_DataDirectoryIndex_COUNT).str,
};
@@ -1247,11 +1248,27 @@ lnk_lib_member_ref_list_concat_in_place_array(LNK_LibMemberRefList *list, LNK_Li
static LNK_LibMemberInfo *g_sort_lib_member_context;
internal int
force_inline int
lnk_lib_member_ref_is_before(void *raw_a, void *raw_b)
{
LNK_LibMemberRef **a = raw_a, **b = raw_b;
return lnk_symbol_is_before(g_sort_lib_member_context[(*a)->member_idx].link, g_sort_lib_member_context[(*b)->member_idx].link);
return lnk_symbol_is_before(g_sort_lib_member_context[(*a)->member_idx].link,
g_sort_lib_member_context[(*b)->member_idx].link);
}
force_inline int
lnk_import_ref_is_before(void *raw_a, void *raw_b)
{
LNK_LibMemberRef **a_ptr = raw_a, **b_ptr = raw_b;
LNK_LibMemberRef *a = *a_ptr, *b = *b_ptr;
int cmp = u64_compar(&a->lib->input_idx, &b->lib->input_idx);
if (cmp == 0) {
cmp = u32_compar(&a->member_idx, &b->member_idx);
}
#if LNK_PARANOID
if (a != b) Assert(cmp != 0);
#endif
return cmp < 0;
}
internal LNK_LibMemberRef **
@@ -2002,12 +2019,20 @@ lnk_link_image(TP_Context *tp, TP_Arena *arena, LNK_Config *config, LNK_Inputer
// make imports
//
{
HashMap static_imports_hm = {0};
HashMap delayed_imports_hm = {0};
String8List delayed_dll_names = {0};
String8List static_dll_names = {0};
HashMap static_imports_hm = {0};
HashMap delayed_imports_hm = {0};
String8List delayed_dll_names = {0};
String8List static_dll_names = {0};
for EachNode(member_ref, LNK_LibMemberRef, link->imports.first) {
LNK_LibMemberRef **import_member_refs = lnk_array_from_lib_member_list(scratch.arena, link->imports);
// optionally sort import library member refs by input index
if (config->sort_imports == LNK_SwitchState_Yes) {
radsort(import_member_refs, link->imports.count, lnk_import_ref_is_before);
}
for EachIndex(import_member_idx, link->imports.count) {
LNK_LibMemberRef *member_ref = import_member_refs[import_member_idx];
LNK_Lib *lib = member_ref->lib;
U64 member_idx = member_ref->member_idx;
LNK_LibMemberInfo *member_infos = hash_map_search_raw_raw(&link->lib_member_infos_hm, lib);
+5
View File
@@ -92,6 +92,7 @@ global read_only LNK_CmdSwitch g_cmd_switch_map[] =
{ LNK_CmdSwitch_Rad_RemoveSection, 0, "RAD_REMOVE_SECTION", ":NAME", "Removes a section from the image." },
{ LNK_CmdSwitch_Rad_SharedThreadPool, 0, "RAD_SHARED_THREAD_POOL", "[:STRING]", "Default value \"" LNK_DEFAULT_THREAD_POOL_NAME "\"" },
{ LNK_CmdSwitch_Rad_SharedThreadPoolMaxWorkers, 0, "RAD_SHARED_THREAD_POOL_MAX_WORKERS", ":#", "Set maximum number of workers in a thread pool." },
{ LNK_CmdSwitch_Rad_SortImports, 0, "RAD_SORT_IMPORTS", "[:NO]", "Sort static and delayed import tables by their order of appearance in libs, without assuming link order." },
{ LNK_CmdSwitch_Rad_Ignore, 0, "RAD_IGNORE", ":#", "Ignore the specified RAD linker warning." },
{ LNK_CmdSwitch_Rad_ImageAltPath, 0, "RAD_IMAGEALTPATH", ":FILENAME", "Alternative name for the image" },
{ LNK_CmdSwitch_Rad_WriteTempFiles, 0, "RAD_WRITE_TEMP_FILES", "[:NO]", "When speicifed linker writes image and debug info to temporary files and renames after link is done." },
@@ -2081,6 +2082,10 @@ lnk_apply_cmd_option_to_config(LNK_Config *config, String8 cmd_name, String8List
}
} break;
case LNK_CmdSwitch_Rad_SortImports: {
lnk_cmd_switch_parse_flag(obj, cmd_switch, value_strings, &config->sort_imports);
} break;
case LNK_CmdSwitch_Rad_Ignore: {
S64List error_code_list = {0};
if ( ! lnk_cmd_switch_parse_s64_list(scratch.arena, obj, cmd_switch, value_strings, &error_code_list, 0)) {
+5 -3
View File
@@ -96,14 +96,14 @@ typedef enum
LNK_CmdSwitch_WholeArchive,
LNK_CmdSwitch_Rad_Age,
LNK_CmdSwitch_Rad_BootMode,
LNK_CmdSwitch_Rad_BuildExp,
LNK_CmdSwitch_Rad_BuildInfo,
LNK_CmdSwitch_Rad_BuildImpLib,
LNK_CmdSwitch_Rad_BuildInfo,
LNK_CmdSwitch_Rad_CheckUnusedDelayLoadDll,
LNK_CmdSwitch_Rad_DataDirCount,
LNK_CmdSwitch_Rad_Debug,
LNK_CmdSwitch_Rad_DebugAltPath,
LNK_CmdSwitch_Rad_BootMode,
LNK_CmdSwitch_Rad_DebugName,
LNK_CmdSwitch_Rad_DelayBind,
LNK_CmdSwitch_Rad_DoMerge,
@@ -130,13 +130,14 @@ typedef enum
LNK_CmdSwitch_Rad_RemoveSection,
LNK_CmdSwitch_Rad_SharedThreadPool,
LNK_CmdSwitch_Rad_SharedThreadPoolMaxWorkers,
LNK_CmdSwitch_Rad_SortImports,
LNK_CmdSwitch_Rad_TimeStamp,
LNK_CmdSwitch_Rad_TypeHashAlg,
LNK_CmdSwitch_Rad_UnresolvedSymbolLimit,
LNK_CmdSwitch_Rad_UnresolvedSymbolRefLimit,
LNK_CmdSwitch_Rad_Version,
LNK_CmdSwitch_Rad_Workers,
LNK_CmdSwitch_Rad_WorkDir,
LNK_CmdSwitch_Rad_Workers,
LNK_CmdSwitch_Rad_WriteTempFiles,
LNK_CmdSwitch_RadTypeServer,
@@ -385,6 +386,7 @@ typedef struct LNK_Config
LLVM_GHashAlg type_hash_alg;
String8 type_server_name;
LNK_SwitchState type_server;
LNK_SwitchState sort_imports;
} LNK_Config;
// --- MSVC Error Codes --------------------------------------------------------