collapse obj directive directive code paths

This commit is contained in:
Nikita Smith
2025-07-28 20:07:48 -07:00
parent 18f83521e4
commit 92e6069104
4 changed files with 117 additions and 208 deletions
+69 -198
View File
@@ -913,48 +913,6 @@ lnk_push_loaded_lib(Arena *arena, HashTable *loaded_lib_ht, String8 path)
}
}
internal void
lnk_push_export(Arena *arena, HashTable *export_ht, PE_ExportParseList *export_list, String8List *include_symbol_list, PE_ExportParse export_parse)
{
PE_ExportParseNode *exp_n = 0;
String8 export_name = pe_name_from_export_parse(&export_parse);
hash_table_search_string_raw(export_ht, export_name, &exp_n);
if (exp_n == 0) {
// make sure export is defined
if (!export_parse.is_forwarder) {
str8_list_push(arena, include_symbol_list, export_parse.name);
}
// push new export
exp_n = pe_export_parse_list_push(arena, export_list, export_parse);
hash_table_push_string_raw(arena, export_ht, export_name, exp_n);
} else {
B32 is_ambiguous = 1;
PE_ExportParse *extant_export = &exp_n->data;
if (extant_export->alias.size && export_parse.alias.size && !str8_match(extant_export->alias, export_parse.alias, 0)) {
goto report;
}
if (extant_export->ordinal != export_parse.ordinal) {
goto report;
}
is_ambiguous = 0;
if (extant_export->alias.size == 0 && export_parse.alias.size != 0) {
extant_export->alias = export_parse.alias;
}
report:;
if (is_ambiguous) {
lnk_error_with_loc(LNK_Error_IllExport, export_parse.obj_path, export_parse.lib_path, "ambiguous symbol export %S", export_parse.name);
}
}
}
internal String8
lnk_make_linker_obj(Arena *arena, LNK_Config *config)
{
@@ -1063,6 +1021,10 @@ THREAD_POOL_TASK_FUNC(lnk_undef_symbol_finder)
for (U64 symbol_idx = range.min; symbol_idx < range.max; symbol_idx += 1) {
LNK_SymbolNode *symbol_n = task->lookup_node_arr.v[symbol_idx];
LNK_Symbol *symbol = symbol_n->data;
if (str8_match(symbol->name, str8_lit("return_1"), 0)) {
int x = 0;
}
LNK_Symbol *has_defn = lnk_symbol_table_search(task->symtab, LNK_SymbolScope_Defined, symbol->name);
if (has_defn) {
@@ -1217,6 +1179,7 @@ lnk_build_link_context(TP_Context *tp, TP_Arena *tp_arena, LNK_Config *config)
State_InputSymbols,
State_InputObjs,
State_InputLibs,
State_InputAlternateNames,
State_PushDllHelperUndefSymbol,
State_InputLinkerObjs,
State_PushLoadConfigUndefSymbol,
@@ -1239,17 +1202,18 @@ lnk_build_link_context(TP_Context *tp, TP_Arena *tp_arena, LNK_Config *config)
Temp scratch = scratch_begin(tp_arena->v, tp_arena->count);
// inputs
String8List include_symbol_list = config->include_symbol_list;
String8List input_disallow_lib_list = config->disallow_lib_list;
String8List input_manifest_path_list = str8_list_copy(scratch.arena, &config->input_list[LNK_Input_Manifest]);
String8List manifest_dep_list = str8_list_copy(scratch.arena, &config->manifest_dependency_list);
PE_ExportParseList export_symbol_list = {0};
HashTable *export_ht = hash_table_init(scratch.arena, max_U16/2);
String8Node **last_include_symbol = &config->include_symbol_list.first;
String8Node **last_disallow_lib = &config->disallow_lib_list.first;
LNK_AltNameNode **last_alt_name = &config->alt_name_list.first;
LNK_InputObjList input_obj_list = {0};
LNK_InputImportList input_import_list = {0};
LNK_SymbolList input_weak_list = {0};
LNK_InputLibList input_libs[LNK_InputSource_Count] = { config->input_list[LNK_Input_Lib], config->input_default_lib_list };
LNK_InputLib **input_libs[LNK_InputSource_Count] = {
&config->input_list[LNK_Input_Lib].first,
&config->input_default_lib_list.first,
&config->input_obj_lib_list.first
};
// input :null_obj
{
LNK_InputObj *null_obj_input = lnk_input_obj_list_push(scratch.arena, &input_obj_list);
@@ -1302,20 +1266,6 @@ lnk_build_link_context(TP_Context *tp, TP_Arena *tp_arena, LNK_Config *config)
if (config->guard_flags != LNK_Guard_None) {
state_list_push(scratch.arena, state_list, State_PushLoadConfigUndefSymbol);
}
//
// Push config exports
//
for (PE_ExportParseNode *exp_n = config->export_symbol_list.first; exp_n != 0; exp_n = exp_n->next) {
lnk_push_export(tp_arena->v[0], 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);
}
//
// Run states
@@ -1328,16 +1278,11 @@ lnk_build_link_context(TP_Context *tp, TP_Arena *tp_arena, LNK_Config *config)
case State_InputDisallowLibs: {
ProfBegin("Input /disallowlib");
for (String8Node *name_n = input_disallow_lib_list.first; name_n != 0; name_n = name_n->next) {
if ( ! lnk_is_lib_disallowed(disallow_lib_ht, name_n->string)) {
lnk_push_disallow_lib(scratch.arena, disallow_lib_ht, name_n->string);
for (; *last_disallow_lib; last_disallow_lib = &(*last_disallow_lib)->next) {
if ( ! lnk_is_lib_disallowed(disallow_lib_ht, (*last_disallow_lib)->string)) {
lnk_push_disallow_lib(scratch.arena, disallow_lib_ht, (*last_disallow_lib)->string);
}
}
// reset input
MemoryZeroStruct(&input_disallow_lib_list);
ProfEnd();
} break;
case State_InputImports: {
@@ -1396,8 +1341,8 @@ lnk_build_link_context(TP_Context *tp, TP_Arena *tp_arena, LNK_Config *config)
ProfBegin("Input Symbols");
ProfBegin("Push /INCLUDE Symbols");
for (String8Node *include_node = include_symbol_list.first; include_node != 0; include_node = include_node->next) {
String8 name = push_str8_copy(symtab->arena->v[0], include_node->string);
for (; *last_include_symbol; last_include_symbol = &(*last_include_symbol)->next) {
String8 name = push_str8_copy(symtab->arena->v[0], (*last_include_symbol)->string);
LNK_Symbol *symbol = lnk_make_undefined_symbol(symtab->arena->v[0], name, 0);
lnk_symbol_list_push(scratch.arena, &lookup_undef_list, symbol);
}
@@ -1409,7 +1354,6 @@ lnk_build_link_context(TP_Context *tp, TP_Arena *tp_arena, LNK_Config *config)
lnk_symbol_list_concat_in_place(&lookup_weak_list, &unresolved_weak_list);
// reset inputs
MemoryZeroStruct(&include_symbol_list);
MemoryZeroStruct(&input_weak_list);
ProfEnd();
@@ -1447,7 +1391,7 @@ lnk_build_link_context(TP_Context *tp, TP_Arena *tp_arena, LNK_Config *config)
LNK_InputObj **thin_inputs = lnk_thin_array_from_input_obj_list(scratch.arena, unique_obj_input_list, &thin_inputs_count);
String8Array thin_input_paths = lnk_path_array_from_input_obj_array(scratch.arena, thin_inputs, thin_inputs_count);
String8Array thin_input_datas = lnk_read_data_from_file_path_parallel(tp, tp_arena->v[0], config->io_flags, thin_input_paths);
for (U64 thin_input_idx = 0; thin_input_idx < thin_inputs_count; thin_input_idx += 1) {
for EachIndex(thin_input_idx, thin_inputs_count) {
thin_inputs[thin_input_idx]->has_disk_read_failed = thin_input_datas.v[thin_input_idx].size == 0;
thin_inputs[thin_input_idx]->data = thin_input_datas.v[thin_input_idx];
}
@@ -1455,7 +1399,7 @@ lnk_build_link_context(TP_Context *tp, TP_Arena *tp_arena, LNK_Config *config)
ProfBegin("Disk Read Check");
LNK_InputObj **input_obj_arr = lnk_array_from_input_obj_list(scratch.arena, unique_obj_input_list);
for (U64 input_idx = 0; input_idx < unique_obj_input_list.count; ++input_idx) {
for EachIndex(input_idx, unique_obj_input_list.count) {
if (input_obj_arr[input_idx]->has_disk_read_failed) {
lnk_error(LNK_Error_InvalidPath, "unable to find obj \"%S\"", input_obj_arr[input_idx]->path);
}
@@ -1464,7 +1408,7 @@ lnk_build_link_context(TP_Context *tp, TP_Arena *tp_arena, LNK_Config *config)
if (lnk_get_log_status(LNK_Log_InputObj)) {
U64 input_size = 0;
for (U64 i = 0; i < unique_obj_input_list.count; ++i) { input_size += input_obj_arr[i]->data.size; }
for EachIndex(i, unique_obj_input_list.count) { input_size += input_obj_arr[i]->data.size; }
lnk_log(LNK_Log_InputObj, "[ Obj Input Size %M ]", input_size);
}
@@ -1486,80 +1430,20 @@ lnk_build_link_context(TP_Context *tp, TP_Arena *tp_arena, LNK_Config *config)
config->infer_function_pad_min = 0;
}
ProfBegin("Handle Directives");
ProfBegin("Apply Directives");
for EachIndex(obj_idx, obj_node_arr.count) {
LNK_Obj *obj = &obj_node_arr.v[obj_idx].data;
String8List raw_directives = lnk_raw_directives_from_obj(scratch.arena, obj);
LNK_DirectiveInfo directive_info = lnk_directive_info_from_raw_directives(scratch.arena, obj, raw_directives);
// /EXPORT
for (LNK_Directive *dir = directive_info.v[LNK_CmdSwitch_Export].first; dir != 0; dir = dir->next) {
PE_ExportParse export_parse = {0};
lnk_parse_export_directive_ex(scratch.arena, dir->value_list, obj->path, lnk_obj_get_lib_path(obj), &export_parse);
lnk_push_export(tp_arena->v[0], export_ht, &export_symbol_list, &include_symbol_list, export_parse);
}
// /INCLUDESYMBOL
for (LNK_Directive *dir = directive_info.v[LNK_CmdSwitch_Include].first; dir != 0; dir = dir->next) {
str8_list_concat_in_place(&include_symbol_list, &dir->value_list);
}
// /MERGE
for (LNK_Directive *dir = directive_info.v[LNK_CmdSwitch_Merge].first; dir != 0; dir = dir->next) {
for (String8Node *value_n = dir->value_list.first; value_n != 0; value_n = value_n->next) {
LNK_MergeDirective merge_dir;
if (lnk_parse_merge_directive(value_n->string, obj->path, lnk_obj_get_lib_path(obj), &merge_dir)) {
merge_dir.src = push_str8_copy(tp_arena->v[0], merge_dir.src);
merge_dir.dst = push_str8_copy(tp_arena->v[0], merge_dir.dst);
lnk_merge_directive_list_push(tp_arena->v[0], &config->merge_list, merge_dir);
}
for EachIndex(i, ArrayCount(directive_info.v)) {
for (LNK_Directive *dir = directive_info.v[i].first; dir != 0; dir = dir->next) {
lnk_apply_cmd_option_to_config(tp_arena->v[0], config, dir->id, dir->value_list, obj->path, lnk_obj_get_lib_path(obj));
}
}
// /MANIFESTDEPENDENCY
for (LNK_Directive *dir = directive_info.v[LNK_CmdSwitch_ManifestDependency].first; dir != 0; dir = dir->next) {
str8_list_concat_in_place(&manifest_dep_list, &dir->value_list);
}
// /DISALLOWLIB
for (LNK_Directive *dir = directive_info.v[LNK_CmdSwitch_DisallowLib].first; dir != 0; dir = dir->next) {
str8_list_concat_in_place(&input_disallow_lib_list, &dir->value_list);
}
// /DEFAULTLIB
for (LNK_Directive *dir = directive_info.v[LNK_CmdSwitch_DefaultLib].first; dir != 0; dir = dir->next) {
str8_list_concat_in_place(&input_libs[LNK_InputSource_Obj], &dir->value_list);
}
// /ALTERNATENAME
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, obj->path, lnk_obj_get_lib_path(obj), &alt_name)) {
alt_name.from = push_str8_copy(tp_arena->v[0], alt_name.from);
alt_name.to = push_str8_copy(tp_arena->v[0], alt_name.to);
lnk_symbol_table_push_alt_name(symtab, obj, alt_name.from, alt_name.to);
}
}
}
// /ENTRY
for (LNK_Directive *dir = directive_info.v[LNK_CmdSwitch_Entry].first; dir != 0; dir = dir->next) {
lnk_apply_cmd_option_to_config(scratch.arena, config, dir->id, dir->value_list, obj->path, lnk_obj_get_lib_path(obj));
}
// /SUBSYSTEM
for (LNK_Directive *dir = directive_info.v[LNK_CmdSwitch_SubSystem].first; dir != 0; dir = dir->next) {
lnk_apply_cmd_option_to_config(scratch.arena, config, dir->id, dir->value_list, obj->path, lnk_obj_get_lib_path(obj));
}
// /STACK
for (LNK_Directive *dir = directive_info.v[LNK_CmdSwitch_Stack].first; dir != 0; dir = dir->next) {
lnk_apply_cmd_option_to_config(scratch.arena, config, dir->id, dir->value_list, obj->path, lnk_obj_get_lib_path(obj));
}
}
ProfEnd();
// input extern symbols from each obj to the symbol table
LNK_SymbolInputResult input_result = lnk_input_obj_symbols(tp, tp_arena, symtab, obj_node_arr);
// schedule symbol input
@@ -1584,12 +1468,11 @@ lnk_build_link_context(TP_Context *tp, TP_Arena *tp_arena, LNK_Config *config)
ProfBeginV("Input Source %S", lnk_string_from_input_source(input_source));
Temp temp = temp_begin(scratch.arena);
LNK_InputLibList input_lib_list = input_libs[input_source];
LNK_InputLibList unique_input_lib_list = {0};
ProfBegin("Collect unique input libs");
for (LNK_InputLib *input = input_lib_list.first; input != 0; input = input->next) {
String8 path = input->string;
for (; *input_libs[input_source] != 0; input_libs[input_source] = &(*input_libs[input_source])->next) {
String8 path = (*input_libs[input_source])->string;
if (input_source == LNK_InputSource_Default || input_source == LNK_InputSource_Obj) {
if (!str8_ends_with(path, str8_lit(".lib"), StringMatchFlag_CaseInsensitive)) {
@@ -1664,21 +1547,33 @@ lnk_build_link_context(TP_Context *tp, TP_Arena *tp_arena, LNK_Config *config)
ProfEnd();
}
// reset input libs
MemoryZeroArray(input_libs);
ProfEnd();
} break;
case State_InputAlternateNames: {
for (; *last_alt_name; last_alt_name = &(*last_alt_name)->next) {
lnk_symbol_table_push_alt_name(symtab, 0, (*last_alt_name)->data.from, (*last_alt_name)->data.to);
}
} break;
case State_PushDllHelperUndefSymbol: {
ProfBegin("Push Dll Helper Undef Symbol");
delay_load_helper_name = mscrt_delay_load_helper_name_from_machine(config->machine);
str8_list_push(scratch.arena, &include_symbol_list, delay_load_helper_name);
// TODO: config_refactor
String8List value_strings = {0};
str8_list_push(scratch.arena, &value_strings, delay_load_helper_name);
lnk_apply_cmd_option_to_config(tp_arena->v[0], config, str8_lit("include"), value_strings, str8_zero(), str8_zero());
ProfEnd();
} break;
case State_PushLoadConfigUndefSymbol: {
ProfBegin("Push Load Config Undef Symbol");
String8 load_config_name = str8_lit(MSCRT_LOAD_CONFIG_SYMBOL_NAME);
str8_list_push(scratch.arena, &include_symbol_list, load_config_name);
// TODO: config_refactor
String8List value_strings = {0};
str8_list_push(scratch.arena, &value_strings, load_config_name);
lnk_apply_cmd_option_to_config(tp_arena->v[0], config, str8_lit("include"), value_strings, str8_zero(), str8_zero());
ProfEnd();
} break;
case State_LookupUndef: {
@@ -1799,7 +1694,10 @@ lnk_build_link_context(TP_Context *tp, TP_Arena *tp_arena, LNK_Config *config)
// generate undefined symbol so in case obj is in lib it will be linked
if (config->entry_point_name.size) {
str8_list_push(scratch.arena, &include_symbol_list, config->entry_point_name);
// TODO: config_refactor
String8List value_strings = {0};
str8_list_push(scratch.arena, &value_strings, config->entry_point_name);
lnk_apply_cmd_option_to_config(tp_arena->v[0], config, str8_lit("include"), value_strings, str8_zero(), str8_zero());
}
// no entry point, error and exit
else {
@@ -1933,11 +1831,11 @@ lnk_build_link_context(TP_Context *tp, TP_Arena *tp_arena, LNK_Config *config)
ProfEnd();
}
if (export_symbol_list.count) {
if (config->export_symbol_list.count) {
ProfBegin("Build Export Table");
PE_ExportParseList resolved_exports = {0};
for (PE_ExportParseNode *exp_n = export_symbol_list.first, *exp_n_next; exp_n != 0; exp_n = exp_n_next) {
for (PE_ExportParseNode *exp_n = config->export_symbol_list.first, *exp_n_next; exp_n != 0; exp_n = exp_n_next) {
exp_n_next = exp_n->next;
PE_ExportParse *exp = &exp_n->data;
@@ -1979,7 +1877,7 @@ lnk_build_link_context(TP_Context *tp, TP_Arena *tp_arena, LNK_Config *config)
// do we have manifest deps passed through pragma alone?
LNK_ManifestOpt manifest_opt = config->manifest_opt;
if (manifest_dep_list.node_count > 0 && manifest_opt == LNK_ManifestOpt_Null) {
if (config->manifest_dependency_list.node_count > 0 && manifest_opt == LNK_ManifestOpt_Null) {
manifest_opt = LNK_ManifestOpt_Embed;
}
@@ -1988,7 +1886,7 @@ lnk_build_link_context(TP_Context *tp, TP_Arena *tp_arena, LNK_Config *config)
ProfBegin("Embed Manifest");
// TODO: currently we convert manifest to res and parse res again, this unnecessary instead push manifest
// resource to the tree directly
String8 manifest_data = lnk_manifest_from_inputs(scratch.arena, config->io_flags, config->mt_path, config->manifest_name, config->manifest_uac, config->manifest_level, config->manifest_ui_access, input_manifest_path_list, manifest_dep_list);
String8 manifest_data = lnk_manifest_from_inputs(scratch.arena, config->io_flags, config->mt_path, config->manifest_name, config->manifest_uac, config->manifest_level, config->manifest_ui_access, config->input_list[LNK_Input_Manifest], config->manifest_dependency_list);
String8 manifest_res = pe_make_manifest_resource(scratch.arena, *config->manifest_resource_id, manifest_data);
str8_list_push(scratch.arena, &res_data_list, manifest_res);
str8_list_push(scratch.arena, &res_path_list, str8_lit("* Manifest *"));
@@ -1997,14 +1895,14 @@ lnk_build_link_context(TP_Context *tp, TP_Arena *tp_arena, LNK_Config *config)
case LNK_ManifestOpt_WriteToFile: {
ProfBeginDynamic("Write Manifest To: %.*s", str8_varg(config->manifest_name));
Temp temp = temp_begin(scratch.arena);
String8 manifest_data = lnk_manifest_from_inputs(temp.arena, config->io_flags, config->mt_path, config->manifest_name, config->manifest_uac, config->manifest_level, config->manifest_ui_access, input_manifest_path_list, manifest_dep_list);
String8 manifest_data = lnk_manifest_from_inputs(temp.arena, config->io_flags, config->mt_path, config->manifest_name, config->manifest_uac, config->manifest_level, config->manifest_ui_access, config->input_list[LNK_Input_Manifest], config->manifest_dependency_list);
lnk_write_data_to_file_path(config->manifest_name, str8_zero(), manifest_data);
temp_end(temp);
ProfEnd();
} break;
case LNK_ManifestOpt_Null: {
Assert(input_manifest_path_list.node_count == 0);
Assert(manifest_dep_list.node_count == 0);
Assert(config->input_list[LNK_Input_Manifest].node_count == 0);
Assert(config->manifest_dependency_list.node_count == 0);
} break;
case LNK_ManifestOpt_No: {
// omit manifest generation
@@ -2087,7 +1985,7 @@ lnk_build_link_context(TP_Context *tp, TP_Arena *tp_arena, LNK_Config *config)
}
}
if (input_disallow_lib_list.node_count) {
if (*last_disallow_lib != 0) {
state_list_push(scratch.arena, state_list, State_InputDisallowLibs);
continue;
}
@@ -2095,7 +1993,7 @@ lnk_build_link_context(TP_Context *tp, TP_Arena *tp_arena, LNK_Config *config)
state_list_push(scratch.arena, state_list, State_InputImports);
continue;
}
if (input_weak_list.count || include_symbol_list.node_count) {
if (input_weak_list.count || *last_include_symbol != 0) {
state_list_push(scratch.arena, state_list, State_InputSymbols);
continue;
}
@@ -2106,7 +2004,7 @@ lnk_build_link_context(TP_Context *tp, TP_Arena *tp_arena, LNK_Config *config)
{
B32 have_pending_lib_inputs = 0;
for (U64 i = 0; i < ArrayCount(input_libs); ++i) {
if (input_libs[i].node_count) {
if (*input_libs[i] != 0) {
have_pending_lib_inputs = 1;
break;
}
@@ -2116,6 +2014,10 @@ lnk_build_link_context(TP_Context *tp, TP_Arena *tp_arena, LNK_Config *config)
continue;
}
}
if (*last_alt_name != 0) {
state_list_push(scratch.arena, state_list, State_InputAlternateNames);
continue;
}
if (lookup_undef_list.count) {
state_list_push(scratch.arena, state_list, State_LookupUndef);
continue;
@@ -2177,8 +2079,6 @@ lnk_build_link_context(TP_Context *tp, TP_Arena *tp_arena, LNK_Config *config)
link_ctx.symtab = symtab;
link_ctx.objs_count = obj_list.count;
link_ctx.objs = lnk_array_from_obj_list(tp_arena->v[0], obj_list);
link_ctx.export_symbol_list = export_symbol_list;
link_ctx.delay_load_helper_name = delay_load_helper_name;
MemoryCopyTyped(&link_ctx.lib_index[0], &lib_index[0], ArrayCount(lib_index));
ProfEnd();
@@ -2242,10 +2142,7 @@ lnk_gc_comdats(TP_Context *tp,
U64 objs_count,
LNK_Obj **objs,
LNK_Symbol ***symlinks,
LNK_Config *config,
PE_ExportParseList export_symbol_list,
String8List include_symbol_list,
String8 delay_load_helper_name)
LNK_Config *config)
{
ProfBeginFunction();
Temp scratch = scratch_begin(0,0);
@@ -2258,27 +2155,7 @@ lnk_gc_comdats(TP_Context *tp,
// define roots
//
{
String8List roots = {0};
// entry point
str8_list_push(scratch.arena, &roots, config->entry_point_name);
// exports
for (PE_ExportParseNode *exp_n = export_symbol_list.first; exp_n != 0; exp_n = exp_n->next) {
PE_ExportParse *exp = &exp_n->data;
str8_list_push(scratch.arena, &roots, exp->name);
}
// load config
LNK_Symbol *load_config_symbol = lnk_symbol_table_searchf(symtab, LNK_SymbolScope_Defined, MSCRT_LOAD_CONFIG_SYMBOL_NAME);
if (load_config_symbol) {
str8_list_push(scratch.arena, &roots, load_config_symbol->name);
}
// delay load helper
if (delay_load_helper_name.size) {
str8_list_push(scratch.arena, &roots, delay_load_helper_name);
}
String8List roots = str8_list_copy(scratch.arena, &config->include_symbol_list);
// tls
LNK_Symbol *tls_symbol = lnk_symbol_table_searchf(symtab, LNK_SymbolScope_Defined, MSCRT_TLS_SYMBOL_NAME);
@@ -2286,9 +2163,6 @@ lnk_gc_comdats(TP_Context *tp,
str8_list_pushf(scratch.arena, &roots, MSCRT_TLS_SYMBOL_NAME);
}
// include symbols
str8_list_concat_in_place(&roots, &include_symbol_list);
// push tasks for each root symbol
for (String8Node *root_n = roots.first; root_n != 0; root_n = root_n->next) {
LNK_Symbol *root = lnk_symbol_table_search(symtab, LNK_SymbolScope_Defined, root_n->string);
@@ -3947,9 +3821,6 @@ lnk_build_image(TP_Arena *arena,
TP_Context *tp,
LNK_Config *config,
LNK_SymbolTable *symtab,
PE_ExportParseList export_symbol_list,
String8List include_symbol_list,
String8 delay_load_helper_name,
U64 objs_count,
LNK_Obj **objs)
{
@@ -3968,7 +3839,7 @@ lnk_build_image(TP_Arena *arena,
// remove unreachable COMDAT sections
//
if (config->opt_ref == LNK_SwitchState_Yes) {
lnk_gc_comdats(tp, symtab, objs_count, objs, symlinks, config, export_symbol_list, include_symbol_list, delay_load_helper_name);
lnk_gc_comdats(tp, symtab, objs_count, objs, symlinks, config);
}
//
@@ -4880,7 +4751,7 @@ lnk_run(TP_Context *tp, TP_Arena *arena, LNK_Config *config)
//
// Image
//
LNK_ImageContext image_ctx = lnk_build_image(arena, tp, config, link_ctx.symtab, link_ctx.export_symbol_list, link_ctx.include_symbol_list, link_ctx.delay_load_helper_name, link_ctx.objs_count, link_ctx.objs);
LNK_ImageContext image_ctx = lnk_build_image(arena, tp, config, link_ctx.symtab, link_ctx.objs_count, link_ctx.objs);
// Write image in the background
LNK_WriteThreadContext *image_write_ctx = push_array(scratch.arena, LNK_WriteThreadContext, 1);
@@ -4904,7 +4775,7 @@ lnk_run(TP_Context *tp, TP_Arena *arena, LNK_Config *config)
ProfBegin("Build Import Library");
lnk_timer_begin(LNK_Timer_Lib);
String8 linker_debug_symbols = lnk_make_linker_debug_symbols(scratch.arena, config->machine);
String8List lib_list = pe_make_import_lib(arena->v[0], config->machine, config->time_stamp, str8_skip_last_slash(config->image_name), linker_debug_symbols, link_ctx.export_symbol_list);
String8List lib_list = pe_make_import_lib(arena->v[0], config->machine, config->time_stamp, str8_skip_last_slash(config->image_name), linker_debug_symbols, config->export_symbol_list);
lnk_write_data_list_to_file_path(config->imp_lib_name, str8_zero(), lib_list);
lnk_timer_end(LNK_Timer_Lib);
ProfEnd();
+1 -4
View File
@@ -10,9 +10,6 @@ typedef struct LNK_LinkContext
LNK_SymbolTable *symtab;
U64 objs_count;
LNK_Obj **objs;
PE_ExportParseList export_symbol_list;
String8List include_symbol_list;
String8 delay_load_helper_name;
LNK_LibList lib_index[LNK_InputSource_Count];
} LNK_LinkContext;
@@ -224,7 +221,7 @@ internal LNK_LinkContext lnk_build_link_context(TP_Context *tp, TP_Arena *tp_are
internal String8List lnk_build_guard_tables(TP_Context *tp, LNK_SectionTable *sectab, LNK_SymbolTable *symtab, U64 objs_count, LNK_Obj **objs, COFF_MachineType machine, String8 entry_point_name, LNK_GuardFlags guard_flags, B32 emit_suppress_flag);
internal String8List lnk_build_base_relocs(TP_Context *tp, TP_Arena *tp_temp, LNK_Config *config, U64 objs_count, LNK_Obj **objs);
internal String8List lnk_build_win32_image_header(Arena *arena, LNK_SymbolTable *symtab, LNK_Config *config, LNK_SectionArray sect_arr, U64 expected_image_header_size);
internal LNK_ImageContext lnk_build_image(TP_Arena *arena, TP_Context *tp, LNK_Config *config, LNK_SymbolTable *symtab, PE_ExportParseList export_symbol_list, String8List include_symbol_list, String8 delay_load_helper_name, U64 obj_count, LNK_Obj **objs);
internal LNK_ImageContext lnk_build_image(TP_Arena *arena, TP_Context *tp, LNK_Config *config, LNK_SymbolTable *symtab, U64 obj_count, LNK_Obj **objs);
// --- Logger ------------------------------------------------------------------
+45 -6
View File
@@ -609,6 +609,7 @@ lnk_parse_alt_name_directive(String8 string, String8 obj_path, String8 lib_path,
if (pair.node_count == 2) {
alt_out->from = pair.first->string;
alt_out->to = pair.last->string;
is_parse_ok = 1;
} else {
lnk_error_cmd_switch(LNK_Error_Cmdl, obj_path, lib_path, LNK_CmdSwitch_AlternateName, "syntax error in \"%S\", expected format \"FROM=TO\"", string);
}
@@ -1163,7 +1164,11 @@ lnk_apply_cmd_option_to_config(Arena *arena, LNK_Config *config, String8 cmd_nam
case LNK_CmdSwitch_DefaultLib: {
String8List default_lib_list = str8_list_copy(arena, &value_strings);
str8_list_concat_in_place(&config->input_default_lib_list, &default_lib_list);
if (obj_path.size) {
str8_list_concat_in_place(&config->input_obj_lib_list, &default_lib_list);
} else {
str8_list_concat_in_place(&config->input_default_lib_list, &default_lib_list);
}
} break;
case LNK_CmdSwitch_Delay: {
@@ -1190,10 +1195,6 @@ lnk_apply_cmd_option_to_config(Arena *arena, LNK_Config *config, String8 cmd_nam
config->file_characteristics |= PE_ImageFileCharacteristic_FILE_DLL;
} break;
case LNK_CmdSwitch_DisallowLib: {
lnk_not_implemented("TODO: how is this switch different from /nodefaultlib?");
} break;
case LNK_CmdSwitch_DynamicBase: {
lnk_cmd_switch_set_flag_16(obj_path, lib_path, cmd_switch, value_strings, &config->dll_characteristics, PE_DllCharacteristic_DYNAMIC_BASE);
} break;
@@ -1217,7 +1218,43 @@ lnk_apply_cmd_option_to_config(Arena *arena, LNK_Config *config, String8 cmd_nam
case LNK_CmdSwitch_Export: {
PE_ExportParse export_parse = {0};
if (lnk_parse_export_directive_ex(arena, value_strings, obj_path, lib_path, &export_parse)) {
pe_export_parse_list_push(arena, &config->export_symbol_list, export_parse);
PE_ExportParseNode *exp_n = 0;
String8 export_name = pe_name_from_export_parse(&export_parse);
hash_table_search_string_raw(config->export_ht, export_name, &exp_n);
if (exp_n == 0) {
// make sure export is defined
if (!export_parse.is_forwarder) {
str8_list_push(arena, &config->include_symbol_list, export_parse.name);
}
// push new export
exp_n = pe_export_parse_list_push(arena, &config->export_symbol_list, export_parse);
hash_table_push_string_raw(arena, config->export_ht, export_name, exp_n);
} else {
B32 is_ambiguous = 1;
PE_ExportParse *extant_export = &exp_n->data;
if (extant_export->alias.size && export_parse.alias.size && !str8_match(extant_export->alias, export_parse.alias, 0)) {
goto report;
}
if (extant_export->ordinal != export_parse.ordinal) {
goto report;
}
is_ambiguous = 0;
if (extant_export->alias.size == 0 && export_parse.alias.size != 0) {
extant_export->alias = export_parse.alias;
}
report:;
if (is_ambiguous) {
lnk_error_with_loc(LNK_Error_IllExport, export_parse.obj_path, export_parse.lib_path, "ambiguous symbol export %S", export_parse.name);
}
}
}
} break;
@@ -1485,6 +1522,7 @@ lnk_apply_cmd_option_to_config(Arena *arena, LNK_Config *config, String8 cmd_nam
str8_list_concat_in_place(&config->natvis_list, &natvis_list);
} break;
case LNK_CmdSwitch_DisallowLib:
case LNK_CmdSwitch_NoDefaultLib: {
if (value_strings.node_count == 0) {
config->no_default_libs = 1;
@@ -1939,6 +1977,7 @@ lnk_config_from_cmd_line(Arena *arena, String8List raw_cmd_line, LNK_CmdLine cmd
config->pdb_hash_type_names = LNK_TypeNameHashMode_None;
config->pdb_hash_type_name_length = 8;
config->data_dir_count = PE_DataDirectoryIndex_COUNT;
config->export_ht = hash_table_init(scratch.arena, max_U16/2);
// process command line switches
for (LNK_CmdOption *cmd = cmd_line.first_option; cmd != 0; cmd = cmd->next) {
+2
View File
@@ -359,6 +359,7 @@ typedef struct LNK_Config
U64 pdb_hash_type_name_length;
PE_ExportParseList export_symbol_list;
String8List input_list[LNK_Input_Count];
String8List input_obj_lib_list;
String8List input_default_lib_list;
String8List disallow_lib_list;
String8List delay_load_dll_list;
@@ -390,6 +391,7 @@ typedef struct LNK_Config
String8 temp_rad_chunk_map_name;
String8List remove_sections;
LNK_IO_Flags io_flags;
HashTable *export_ht;
} LNK_Config;
// --- MSVC Error Codes --------------------------------------------------------