From 723c950c01f06655aa9d438ff40d25f9e4a40bdf Mon Sep 17 00:00:00 2001 From: Nikita Smith Date: Mon, 9 Dec 2024 14:23:59 -0800 Subject: [PATCH] add default params for /FUNCTIONPADMIN --- src/linker/lnk_config.c | 83 +++++++++++++++++++++++++++-------------- src/linker/lnk_config.h | 3 +- src/linker/lnk_obj.c | 18 ++++++++- src/linker/lnk_obj.h | 4 +- 4 files changed, 76 insertions(+), 32 deletions(-) diff --git a/src/linker/lnk_config.c b/src/linker/lnk_config.c index 3227103c..b7610398 100644 --- a/src/linker/lnk_config.c +++ b/src/linker/lnk_config.c @@ -349,6 +349,28 @@ lnk_error_invalid_uac_ui_access_param(LNK_ErrorCode error_code, LNK_CmdSwitchTyp //////////////////////////////// +internal U64 +lnk_get_default_function_pad_min(COFF_MachineType machine) +{ + U64 function_pad_min = 0; + switch (machine) { + case COFF_MachineType_UNKNOWN: break; + case COFF_MachineType_X86: { + function_pad_min = 5; + } break; + case COFF_MachineType_X64: { + function_pad_min = 6; + } break; + default: { + lnk_error_cmd_switch(LNK_Error_Cmdl, + LNK_CmdSwitch_FunctionPadMin, + "default paramter is not defined for: %S", + coff_string_from_machine_type(machine)); + } break; + } + return function_pad_min; +} + internal U64 lnk_get_base_addr(LNK_Config *config) { @@ -878,33 +900,34 @@ lnk_config_from_cmd_line(Arena *arena, String8List raw_cmd_line) if (lnk_cmd_line_has_switch(cmd_line, LNK_CmdSwitch_Dll)) { lnk_cmd_line_push_option_if_not_presentf(scratch.arena, &cmd_line, LNK_CmdSwitch_SubSystem, "%S", pe_string_from_subsystem(PE_WindowsSubsystem_WINDOWS_GUI)); } - lnk_cmd_line_push_option_if_not_presentf(scratch.arena, &cmd_line, LNK_CmdSwitch_HighEntropyVa, ""); - lnk_cmd_line_push_option_if_not_presentf(scratch.arena, &cmd_line, LNK_CmdSwitch_ManifestUac, "\"level='asInvoker' uiAccess='false'\""); - lnk_cmd_line_push_option_if_not_presentf(scratch.arena, &cmd_line, LNK_CmdSwitch_NxCompat, ""); - lnk_cmd_line_push_option_if_not_presentf(scratch.arena, &cmd_line, LNK_CmdSwitch_LargeAddressAware, ""); - lnk_cmd_line_push_option_if_not_presentf(scratch.arena, &cmd_line, LNK_CmdSwitch_PdbAltPath, "%%_RAD_PDB_PATH%%"); - lnk_cmd_line_push_option_if_not_presentf(scratch.arena, &cmd_line, LNK_CmdSwitch_PdbPageSize, "%u", KB(4)); - lnk_cmd_line_push_option_if_not_presentf(scratch.arena, &cmd_line, LNK_CmdSwitch_Rad_TimeStamp, "%u", os_get_process_start_time_unix()); - lnk_cmd_line_push_option_if_not_presentf(scratch.arena, &cmd_line, LNK_CmdSwitch_Rad_Age, "%u", 1); + lnk_cmd_line_push_option_if_not_presentf(scratch.arena, &cmd_line, LNK_CmdSwitch_HighEntropyVa, ""); + lnk_cmd_line_push_option_if_not_presentf(scratch.arena, &cmd_line, LNK_CmdSwitch_ManifestUac, "\"level='asInvoker' uiAccess='false'\""); + lnk_cmd_line_push_option_if_not_presentf(scratch.arena, &cmd_line, LNK_CmdSwitch_NxCompat, ""); + lnk_cmd_line_push_option_if_not_presentf(scratch.arena, &cmd_line, LNK_CmdSwitch_FunctionPadMin, "0"); + lnk_cmd_line_push_option_if_not_presentf(scratch.arena, &cmd_line, LNK_CmdSwitch_LargeAddressAware, ""); + lnk_cmd_line_push_option_if_not_presentf(scratch.arena, &cmd_line, LNK_CmdSwitch_PdbAltPath, "%%_RAD_PDB_PATH%%"); + lnk_cmd_line_push_option_if_not_presentf(scratch.arena, &cmd_line, LNK_CmdSwitch_PdbPageSize, "%u", KB(4)); + lnk_cmd_line_push_option_if_not_presentf(scratch.arena, &cmd_line, LNK_CmdSwitch_Rad_TimeStamp, "%u", os_get_process_start_time_unix()); + lnk_cmd_line_push_option_if_not_presentf(scratch.arena, &cmd_line, LNK_CmdSwitch_Rad_Age, "%u", 1); lnk_cmd_line_push_option_if_not_presentf(scratch.arena, &cmd_line, LNK_CmdSwitch_Rad_CheckUnusedDelayLoadDll, ""); - lnk_cmd_line_push_option_if_not_presentf(scratch.arena, &cmd_line, LNK_CmdSwitch_Rad_DelayBind, ""); - lnk_cmd_line_push_option_if_not_presentf(scratch.arena, &cmd_line, LNK_CmdSwitch_Rad_DoMerge, ""); - lnk_cmd_line_push_option_if_not_presentf(scratch.arena, &cmd_line, LNK_CmdSwitch_Rad_EnvLib, ""); - lnk_cmd_line_push_option_if_not_presentf(scratch.arena, &cmd_line, LNK_CmdSwitch_Rad_Exe, ""); - lnk_cmd_line_push_option_if_not_presentf(scratch.arena, &cmd_line, LNK_CmdSwitch_Rad_Guid, "imageblake3"); - lnk_cmd_line_push_option_if_not_presentf(scratch.arena, &cmd_line, LNK_CmdSwitch_Rad_LargePages, "no"); - lnk_cmd_line_push_option_if_not_presentf(scratch.arena, &cmd_line, LNK_CmdSwitch_Rad_LinkVer, "14.0"); - lnk_cmd_line_push_option_if_not_presentf(scratch.arena, &cmd_line, LNK_CmdSwitch_Rad_OsVer, "6.0"); - lnk_cmd_line_push_option_if_not_presentf(scratch.arena, &cmd_line, LNK_CmdSwitch_Rad_PageSize, "%u", KB(4)); - lnk_cmd_line_push_option_if_not_presentf(scratch.arena, &cmd_line, LNK_CmdSwitch_Rad_PathStyle, "system"); - lnk_cmd_line_push_option_if_not_presentf(scratch.arena, &cmd_line, LNK_CmdSwitch_Rad_SectVirtOff, "0x1000"); - lnk_cmd_line_push_option_if_not_presentf(scratch.arena, &cmd_line, LNK_CmdSwitch_Rad_Workers, "%u", os_get_system_info()->logical_processor_count); - lnk_cmd_line_push_option_if_not_presentf(scratch.arena, &cmd_line, LNK_CmdSwitch_Rad_TargetOs, "windows"); - lnk_cmd_line_push_option_if_not_presentf(scratch.arena, &cmd_line, LNK_CmdSwitch_Rad_SymbolTableCapDefined, "0x3ffff"); - lnk_cmd_line_push_option_if_not_presentf(scratch.arena, &cmd_line, LNK_CmdSwitch_Rad_SymbolTableCapInternal, "0x1000"); - lnk_cmd_line_push_option_if_not_presentf(scratch.arena, &cmd_line, LNK_CmdSwitch_Rad_SymbolTableCapWeak, "0x3ffff"); - lnk_cmd_line_push_option_if_not_presentf(scratch.arena, &cmd_line, LNK_CmdSwitch_Rad_SymbolTableCapLib, "0x3ffff"); - lnk_cmd_line_push_option_if_not_presentf(scratch.arena, &cmd_line, LNK_CmdSwitch_Rad_DebugAltPath, "%%_RAD_RDI_PATH%%"); + lnk_cmd_line_push_option_if_not_presentf(scratch.arena, &cmd_line, LNK_CmdSwitch_Rad_DelayBind, ""); + lnk_cmd_line_push_option_if_not_presentf(scratch.arena, &cmd_line, LNK_CmdSwitch_Rad_DoMerge, ""); + lnk_cmd_line_push_option_if_not_presentf(scratch.arena, &cmd_line, LNK_CmdSwitch_Rad_EnvLib, ""); + lnk_cmd_line_push_option_if_not_presentf(scratch.arena, &cmd_line, LNK_CmdSwitch_Rad_Exe, ""); + lnk_cmd_line_push_option_if_not_presentf(scratch.arena, &cmd_line, LNK_CmdSwitch_Rad_Guid, "imageblake3"); + lnk_cmd_line_push_option_if_not_presentf(scratch.arena, &cmd_line, LNK_CmdSwitch_Rad_LargePages, "no"); + lnk_cmd_line_push_option_if_not_presentf(scratch.arena, &cmd_line, LNK_CmdSwitch_Rad_LinkVer, "14.0"); + lnk_cmd_line_push_option_if_not_presentf(scratch.arena, &cmd_line, LNK_CmdSwitch_Rad_OsVer, "6.0"); + lnk_cmd_line_push_option_if_not_presentf(scratch.arena, &cmd_line, LNK_CmdSwitch_Rad_PageSize, "%u", KB(4)); + lnk_cmd_line_push_option_if_not_presentf(scratch.arena, &cmd_line, LNK_CmdSwitch_Rad_PathStyle, "system"); + lnk_cmd_line_push_option_if_not_presentf(scratch.arena, &cmd_line, LNK_CmdSwitch_Rad_SectVirtOff, "0x1000"); + lnk_cmd_line_push_option_if_not_presentf(scratch.arena, &cmd_line, LNK_CmdSwitch_Rad_Workers, "%u", os_get_system_info()->logical_processor_count); + lnk_cmd_line_push_option_if_not_presentf(scratch.arena, &cmd_line, LNK_CmdSwitch_Rad_TargetOs, "windows"); + lnk_cmd_line_push_option_if_not_presentf(scratch.arena, &cmd_line, LNK_CmdSwitch_Rad_SymbolTableCapDefined, "0x3ffff"); + lnk_cmd_line_push_option_if_not_presentf(scratch.arena, &cmd_line, LNK_CmdSwitch_Rad_SymbolTableCapInternal, "0x1000"); + lnk_cmd_line_push_option_if_not_presentf(scratch.arena, &cmd_line, LNK_CmdSwitch_Rad_SymbolTableCapWeak, "0x3ffff"); + lnk_cmd_line_push_option_if_not_presentf(scratch.arena, &cmd_line, LNK_CmdSwitch_Rad_SymbolTableCapLib, "0x3ffff"); + lnk_cmd_line_push_option_if_not_presentf(scratch.arena, &cmd_line, LNK_CmdSwitch_Rad_DebugAltPath, "%%_RAD_RDI_PATH%%"); #if BUILD_DEBUG lnk_cmd_line_push_optionf(scratch.arena, &cmd_line, LNK_CmdSwitch_Rad_Log, "debug"); @@ -1072,7 +1095,13 @@ lnk_config_from_cmd_line(Arena *arena, String8List raw_cmd_line) } break; case LNK_CmdSwitch_FunctionPadMin: { - lnk_cmd_switch_parse_u64(cmd->value_strings, cmd_switch, &config->function_pad_min, LNK_ParseU64Flag_CheckUnder32bit); + if (cmd->value_strings.node_count == 0) { + config->function_pad_min = 0; // :function_pad_min + } else { + local_persist U64 function_pad_min; + lnk_cmd_switch_parse_u64(cmd->value_strings, cmd_switch, &function_pad_min, LNK_ParseU64Flag_CheckUnder32bit); + config->function_pad_min = &function_pad_min; + } } break; case LNK_CmdSwitch_Heap: { diff --git a/src/linker/lnk_config.h b/src/linker/lnk_config.h index ed5578fd..01518cbe 100644 --- a/src/linker/lnk_config.h +++ b/src/linker/lnk_config.h @@ -269,7 +269,7 @@ typedef struct LNK_Config U64 pdb_page_size; U64 worker_count; U64 idle_worker_count; - U64 function_pad_min; + U64 *function_pad_min; U64 *manifest_resource_id; B32 no_default_libs; Version link_ver; @@ -478,6 +478,7 @@ internal void lnk_error_cmd_switch_invalid_param(LNK_ErrorCode code, LNK_CmdSwit //////////////////////////////// // Getters +internal U64 lnk_get_default_function_pad_min(COFF_MachineType machine); internal U64 lnk_get_base_addr(LNK_Config *config); internal Version lnk_get_default_subsystem_version(PE_WindowsSubsystem subsystem, COFF_MachineType machine); internal Version lnk_get_min_subsystem_version(PE_WindowsSubsystem subsystem, COFF_MachineType machine); diff --git a/src/linker/lnk_obj.c b/src/linker/lnk_obj.c index 311dde28..7af15d2f 100644 --- a/src/linker/lnk_obj.c +++ b/src/linker/lnk_obj.c @@ -346,6 +346,14 @@ THREAD_POOL_TASK_FUNC(lnk_obj_initer) lnk_error(LNK_Error_UnsupportedMachine, "%S: %S machine is supported", input->path, coff_string_from_machine_type(coff_info.machine)); } + // :function_pad_min + U64 function_pad_min; + if (task->function_pad_min) { + function_pad_min = *task->function_pad_min; + } else { + function_pad_min = lnk_get_default_function_pad_min(coff_info.machine); + } + U64 chunk_count = 0; chunk_count += coff_info.section_count_no_null; chunk_count += 1; // :common_block @@ -421,7 +429,7 @@ THREAD_POOL_TASK_FUNC(lnk_obj_initer) // convert from coff B32 is_big_obj = coff_info.type == COFF_DataType_BIG_OBJ; - LNK_SymbolArray symbol_arr = lnk_symbol_array_from_coff(arena, input->data, obj, cached_path, is_big_obj, task->function_pad_min, coff_info.string_table_off, coff_info.section_count_no_null, coff_sect_arr, coff_info.symbol_count, coff_symbols, chunk_ptr_arr, master_common_block); + LNK_SymbolArray symbol_arr = lnk_symbol_array_from_coff(arena, input->data, obj, cached_path, is_big_obj, function_pad_min, coff_info.string_table_off, coff_info.section_count_no_null, coff_sect_arr, coff_info.symbol_count, coff_symbols, chunk_ptr_arr, master_common_block); LNK_SymbolList symbol_list = lnk_symbol_list_from_array(arena, symbol_arr); LNK_RelocList *reloc_list_arr = lnk_reloc_list_array_from_coff(arena, coff_info.machine, input->data, coff_info.section_count_no_null, coff_sect_arr, chunk_ptr_arr, symbol_arr); @@ -573,7 +581,13 @@ THREAD_POOL_TASK_FUNC(lnk_chunk_ref_assigner) } internal LNK_ObjNodeArray -lnk_obj_list_push_parallel(TP_Context *tp, TP_Arena *arena, LNK_ObjList *obj_list, LNK_SectionTable *st, U64 function_pad_min, U64 input_count, LNK_InputObj **inputs) +lnk_obj_list_push_parallel(TP_Context *tp, + TP_Arena *arena, + LNK_ObjList *obj_list, + LNK_SectionTable *st, + U64 *function_pad_min, + U64 input_count, + LNK_InputObj **inputs) { ProfBeginFunction(); Temp scratch = scratch_begin(arena->v, arena->count); diff --git a/src/linker/lnk_obj.h b/src/linker/lnk_obj.h index bbdd5806..ce316b0e 100644 --- a/src/linker/lnk_obj.h +++ b/src/linker/lnk_obj.h @@ -92,7 +92,7 @@ typedef struct U64 obj_id_base; LNK_SectDefnList *defn_arr; LNK_SectionTable *st; - U64 function_pad_min; + U64 *function_pad_min; } LNK_ObjIniter; typedef struct @@ -178,7 +178,7 @@ internal LNK_InputObjList lnk_input_obj_list_from_string_list(Arena *arena, Stri internal LNK_Obj ** lnk_obj_arr_from_list(Arena *arena, LNK_ObjList list); internal LNK_ObjNodeArray lnk_obj_list_reserve(Arena *arena, LNK_ObjList *list, U64 count); internal LNK_ChunkList * lnk_collect_obj_chunks(TP_Context *tp, TP_Arena *arena, U64 obj_count, LNK_Obj **obj_arr, String8 name, String8 postfix, B32 collect_discarded); -internal LNK_ObjNodeArray lnk_obj_list_push_parallel(TP_Context *tp, TP_Arena *tp_arena, LNK_ObjList *obj_list, LNK_SectionTable *st, U64 function_pad_min, U64 input_count, LNK_InputObj **inputs); +internal LNK_ObjNodeArray lnk_obj_list_push_parallel(TP_Context *tp, TP_Arena *tp_arena, LNK_ObjList *obj_list, LNK_SectionTable *st, U64 *function_pad_min, U64 input_count, LNK_InputObj **inputs); internal LNK_Chunk * lnk_sect_chunk_array_from_coff(Arena *arena, U64 obj_id, String8 obj_path, String8 coff_data, U64 sect_count, COFF_SectionHeader *coff_sect_arr, String8 *sect_name_arr, String8 *sect_postfix_arr); internal LNK_SymbolArray lnk_symbol_array_from_coff(Arena *arena, String8 coff_data, LNK_Obj *obj, String8 obj_path, B32 is_big_obj, U64 function_pad_min, U64 string_table_off, U64 sect_count, COFF_SectionHeader *coff_sect_arr, U64 coff_symbol_count, void *coff_symbols, LNK_ChunkPtr *chunk_ptr_arr, LNK_Chunk *master_common_block);