store library pointer in the obj instead of path; required for prioritized symbol lookup implementation

This commit is contained in:
Nikita Smith
2025-07-28 17:28:52 -07:00
parent 4cb09e73c2
commit 1e1d903878
6 changed files with 55 additions and 44 deletions
+11 -9
View File
@@ -1053,7 +1053,7 @@ lnk_queue_lib_member_input(Arena *arena,
input->dedup_id = push_str8f(arena, "%S/%S", lib->path, obj_path);
input->path = obj_path;
input->data = member_info.data;
input->lib_path = lib->path;
input->lib = lib;
input->input_idx = input_idx;
} break;
}
@@ -1534,7 +1534,7 @@ lnk_build_link_context(TP_Context *tp, TP_Arena *tp_arena, LNK_Config *config)
{
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, obj->lib_path, &export_parse);
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);
}
}
@@ -1591,17 +1591,17 @@ lnk_build_link_context(TP_Context *tp, TP_Arena *tp_arena, LNK_Config *config)
// /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, obj->lib_path);
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, obj->lib_path);
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, obj->lib_path);
lnk_apply_cmd_option_to_config(scratch.arena, config, dir->id, dir->value_list, obj->path, lnk_obj_get_lib_path(obj));
}
}
ProfEnd();
@@ -4812,8 +4812,9 @@ lnk_build_rad_map(Arena *arena, String8 image_data, LNK_Config *config, U64 objs
COFF_SectionHeader *section_header = lnk_coff_section_header_from_section_number(obj, sect_idx+1);
String8 string_table = str8_substr(obj->data, obj->header.string_table_range);
String8 section_name = coff_name_from_section_header(string_table, section_header);
if (obj->lib_path.size) {
String8 lib_name = str8_chop_last_dot(str8_skip_last_slash(obj->lib_path));
if (obj->lib) {
String8 lib_path = lnk_obj_get_lib_path(obj);
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(temp.arena, &source_list, "%S(%S) SECT%X (%S)", lib_name, obj_name, sect_idx+1, section_name);
} else {
@@ -4842,8 +4843,9 @@ lnk_build_rad_map(Arena *arena, String8 image_data, LNK_Config *config, U64 objs
if (lnk_is_coff_section_debug(obj, sect_idx)) {
COFF_SectionHeader *section_header = &section_table[sect_idx];
if (~section_header->flags & COFF_SectionFlag_LnkRemove) {
if (obj->lib_path.size) {
String8 lib_name = str8_chop_last_dot(str8_skip_last_slash(obj->lib_path));
if (obj->lib) {
String8 lib_path = lnk_obj_get_lib_path(obj);
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 {
+2 -2
View File
@@ -3133,7 +3133,7 @@ lnk_build_pdb(TP_Context *tp,
PDB_DbiModule **mod_arr = push_array(tp_arena->v[0], PDB_DbiModule *, obj_count);
for (U64 obj_idx = 0; obj_idx < obj_count; ++obj_idx) {
LNK_Obj *obj = obj_arr + obj_idx;
mod_arr[obj_idx] = dbi_push_module(pdb->dbi, obj->path, obj->lib_path);
mod_arr[obj_idx] = dbi_push_module(pdb->dbi, obj->path, lnk_obj_get_lib_path(obj));
// we don't support symbol append
Assert(mod_arr[obj_idx]->sn == MSF_INVALID_STREAM_NUMBER);
@@ -4502,7 +4502,7 @@ THREAD_POOL_TASK_FUNC(lnk_find_obj_compiler_info_task)
dst->compiler_name = comp_info->compiler_name;
dst->source_file = str8_zero();
dst->object_file = push_str8_copy(arena, obj->path);
dst->archive_file = push_str8_copy(arena, obj->lib_path);
dst->archive_file = lnk_obj_get_lib_path(obj);
dst->build_path = str8_zero();
dst->language = rdi_language_from_cv_language(comp_info->language);
+8
View File
@@ -1,6 +1,14 @@
// Copyright (c) 2025 Epic Games Tools
// Licensed under the MIT license (https://opensource.org/license/mit/)
internal void
lnk_error_input_obj(LNK_ErrorCode code, LNK_InputObj *input, char *fmt, ...)
{
va_list args; va_start(args, fmt);
lnk_error_with_loc_fv(code, input->path, input->lib ? input->lib->path : str8_zero(), fmt, args);
va_end(args);
}
internal String8
lnk_string_from_input_source(LNK_InputSourceType input_source)
{
+3 -1
View File
@@ -42,7 +42,7 @@ typedef struct LNK_InputObj
String8 dedup_id;
String8 path;
String8 data;
String8 lib_path;
struct LNK_Lib *lib;
U64 input_idx;
} LNK_InputObj;
@@ -55,6 +55,8 @@ typedef struct LNK_InputObjList
////////////////////////////////
internal void lnk_error_input_obj(LNK_ErrorCode code, LNK_InputObj *input, char *fmt, ...);
internal String8 lnk_string_from_input_source(LNK_InputSourceType input_source);
internal void lnk_input_obj_list_push_node(LNK_InputObjList *list, LNK_InputObj *node);
+26 -27
View File
@@ -6,7 +6,7 @@ lnk_error_obj(LNK_ErrorCode code, LNK_Obj *obj, char *fmt, ...)
{
va_list args; va_start(args, fmt);
String8 obj_path = obj ? obj->path : str8_lit("RADLINK");
String8 lib_path = obj ? obj->lib_path : str8_zero();
String8 lib_path = lnk_obj_get_lib_path(obj);
lnk_error_with_loc_fv(code, obj_path, lib_path, fmt, args);
va_end(args);
}
@@ -43,7 +43,7 @@ THREAD_POOL_TASK_FUNC(lnk_obj_initer)
if (header.machine != COFF_MachineType_Unknown) {
COFF_MachineType current_machine = ins_atomic_u32_eval_cond_assign(&task->machine, header.machine, COFF_MachineType_Unknown);
if (current_machine != COFF_MachineType_Unknown && current_machine != header.machine) {
lnk_error_with_loc(LNK_Error_IncompatibleMachine, input->path, input->lib_path,
lnk_error_input_obj(LNK_Error_IncompatibleMachine, input,
"conflicting machine types expected %S but got %S",
coff_string_from_machine_type(current_machine),
coff_string_from_machine_type(header.machine));
@@ -61,13 +61,13 @@ THREAD_POOL_TASK_FUNC(lnk_obj_initer)
// error check: section table / symbol table / string table
//
if (raw_coff_section_table.size != dim_1u64(header.section_table_range)) {
lnk_error_with_loc(LNK_Error_IllData, input->path, input->lib_path, "corrupted file, unable to read section header table");
lnk_error_input_obj(LNK_Error_IllData, input, "corrupted file, unable to read section header table");
}
if (raw_coff_symbol_table.size != dim_1u64(header.symbol_table_range)) {
lnk_error_with_loc(LNK_Error_IllData, input->path, input->lib_path, "corrupted file, unable to read symbol table");
lnk_error_input_obj(LNK_Error_IllData, input, "corrupted file, unable to read symbol table");
}
if (raw_coff_string_table.size != dim_1u64(header.string_table_range)) {
lnk_error_with_loc(LNK_Error_IllData, input->path, input->lib_path, "corrupted file, unable to read string table");
lnk_error_input_obj(LNK_Error_IllData, input, "corrupted file, unable to read string table");
}
//
@@ -86,18 +86,18 @@ THREAD_POOL_TASK_FUNC(lnk_obj_initer)
if (contains_1u64(header.header_range, coff_sect_header->foff) ||
(coff_sect_header->fsize > 0 && contains_1u64(header.header_range, sect_range.max-1))) {
lnk_error_with_loc(LNK_Error_IllData, input->path, input->lib_path, "header (%S No. %#llx) defines out of bounds section data (file offsets point into file header)", sect_name, sect_idx+1);
lnk_error_input_obj(LNK_Error_IllData, input, "header (%S No. %#llx) defines out of bounds section data (file offsets point into file header)", sect_name, sect_idx+1);
}
if (contains_1u64(header.section_table_range, coff_sect_header->foff) ||
(coff_sect_header->fsize > 0 && contains_1u64(header.section_table_range, sect_range.max-1))) {
lnk_error_with_loc(LNK_Error_IllData, input->path, input->lib_path, "header (%S No. %#llx) defines out of bounds section data (file offsets point into section header table)", sect_name, sect_idx+1);
lnk_error_input_obj(LNK_Error_IllData, input, "header (%S No. %#llx) defines out of bounds section data (file offsets point into section header table)", sect_name, sect_idx+1);
}
if (contains_1u64(header.symbol_table_range, coff_sect_header->foff) ||
(coff_sect_header->fsize > 0 && contains_1u64(header.symbol_table_range, sect_range.max-1))) {
lnk_error_with_loc(LNK_Error_IllData, input->path, input->lib_path, "header (%S No. %#llx) defines out of bounds section data (file offsets point into symbol table)", sect_name, sect_idx+1);
lnk_error_input_obj(LNK_Error_IllData, input, "header (%S No. %#llx) defines out of bounds section data (file offsets point into symbol table)", sect_name, sect_idx+1);
}
if (dim_1u64(sect_range) != coff_sect_header->fsize) {
lnk_error_with_loc(LNK_Error_IllData, input->path, input->lib_path, "header (%S No. %#llx) defines out of bounds section data", sect_name, sect_idx+1);
lnk_error_input_obj(LNK_Error_IllData, input, "header (%S No. %#llx) defines out of bounds section data", sect_name, sect_idx+1);
}
}
}
@@ -116,7 +116,7 @@ THREAD_POOL_TASK_FUNC(lnk_obj_initer)
COFF_SymbolValueInterpType interp = coff_interp_symbol(symbol.section_number, symbol.value, symbol.storage_class);
if (interp == COFF_SymbolValueInterp_Regular) {
if (symbol.section_number == 0 || symbol.section_number > header.section_count_no_null) {
lnk_error_with_loc(LNK_Error_IllData, input->path, input->lib_path, "symbol %S (No. 0x%x) points to an out of bounds section 0x%x", symbol.name, symbol_idx, symbol.section_number);
lnk_error_input_obj(LNK_Error_IllData, input, "symbol %S (No. 0x%x) points to an out of bounds section 0x%x", symbol.name, symbol_idx, symbol.section_number);
}
if (symbol.storage_class == COFF_SymStorageClass_Static && symbol.aux_symbol_count > 0) {
COFF_ComdatSelectType select;
@@ -124,7 +124,7 @@ THREAD_POOL_TASK_FUNC(lnk_obj_initer)
coff_parse_secdef(symbol, header.is_big_obj, &select, &section_number, 0, 0);
if (select == COFF_ComdatSelect_Associative) {
if (section_number == 0 || section_number > header.section_count_no_null) {
lnk_error_with_loc(LNK_Error_IllData, input->path, input->lib_path, "section definition symbol %S (No. 0x%x) associates with an out of bounds section 0x%x", symbol.name, symbol_idx, symbol.section_number);
lnk_error_input_obj(LNK_Error_IllData, input, "section definition symbol %S (No. 0x%x) associates with an out of bounds section 0x%x", symbol.name, symbol_idx, symbol.section_number);
}
}
}
@@ -159,15 +159,15 @@ THREAD_POOL_TASK_FUNC(lnk_obj_initer)
if (comdats[symbol.section_number-1] == ~0) {
comdats[symbol.section_number-1] = symbol_idx;
} else {
lnk_error_with_loc(LNK_Error_IllData, input->path, input->lib_path, "section definition symbo (No. 0x%llx) tries to ovewrite comdat", symbol_idx);
lnk_error_input_obj(LNK_Error_IllData, input, "section definition symbo (No. 0x%llx) tries to ovewrite comdat", symbol_idx);
}
} else {
lnk_error_with_loc(LNK_Error_IllData, input->path, input->lib_path, "section size specified by section definition symbol (No 0x%llx) doesn't match size in section header (No. 0x%x); expected 0x%x got 0x%x", symbol_idx, symbol.section_number, section_length, sect_header->fsize);
lnk_error_input_obj(LNK_Error_IllData, input, "section size specified by section definition symbol (No 0x%llx) doesn't match size in section header (No. 0x%x); expected 0x%x got 0x%x", symbol_idx, symbol.section_number, section_length, sect_header->fsize);
}
}
}
} else {
lnk_error_with_loc(LNK_Error_IllData, input->path, input->lib_path, "section definition symbol (No. 0x%llx) has out of bounds section number 0x%x", symbol_idx, symbol.section_number);
lnk_error_input_obj(LNK_Error_IllData, input, "section definition symbol (No. 0x%llx) has out of bounds section number 0x%x", symbol_idx, symbol.section_number);
}
}
}
@@ -206,7 +206,7 @@ THREAD_POOL_TASK_FUNC(lnk_obj_initer)
// was section visited? -- loop found
if (hash_table_search_u64(visited_sections, curr_section)) {
COFF_ParsedSymbol symbol = coff_parse_symbol(header, string_table, symbol_table, comdats[sect_idx]);
lnk_error_with_loc(LNK_Error_AssociativeLoop, input->path, input->lib_path, "section symbol %S (No. 0x%x) does not terminate on a non-associate COMDAT symbol", symbol.name, comdats[sect_idx]);
lnk_error_input_obj(LNK_Error_AssociativeLoop, input, "section symbol %S (No. 0x%x) does not terminate on a non-associate COMDAT symbol", symbol.name, comdats[sect_idx]);
break;
}
@@ -294,7 +294,7 @@ THREAD_POOL_TASK_FUNC(lnk_obj_initer)
// fill out obj
obj->data = input->data;
obj->path = push_str8_copy(arena, input->path);
obj->lib_path = push_str8_copy(arena, input->lib_path);
obj->lib = input->lib;
obj->input_idx = obj_idx;
obj->header = header;
obj->comdats = comdats;
@@ -483,6 +483,16 @@ lnk_obj_get_vol_md(LNK_Obj *obj)
return lnk_obj_match_symbol(obj, str8_lit("@vol.md")).value;
}
internal String8
lnk_obj_get_lib_path(LNK_Obj *obj)
{
String8 lib_path = {0};
if (obj && obj->lib) {
lib_path = obj->lib->path;
}
return lib_path;
}
internal COFF_SectionHeader *
lnk_coff_section_header_from_section_number(LNK_Obj *obj, U64 section_number)
{
@@ -517,17 +527,6 @@ lnk_symlinks_from_obj(Arena *arena, LNK_SymbolTable *symtab, LNK_Obj *obj)
return symlinks;
}
internal String8
lnk_symlink_from_section_number(LNK_Obj *obj, U64 section_number)
{
COFF_ParsedSymbol symbol = {0};
U32 symbol_idx = obj->symlinks[section_number];
if (symbol_idx != max_U32) {
symbol = lnk_parsed_symbol_from_coff_symbol_idx(obj, symbol_idx);
}
return symbol.name;
}
internal COFF_RelocArray
lnk_coff_reloc_info_from_section_number(LNK_Obj *obj, U64 section_number)
{
+5 -5
View File
@@ -9,13 +9,12 @@ typedef struct LNK_Obj
{
String8 data;
String8 path;
String8 lib_path;
struct LNK_Lib *lib;
U32 input_idx;
COFF_FileHeaderInfo header;
U32 *comdats;
B8 hotpatch;
U32Node **associated_sections;
U32 *symlinks;
} LNK_Obj;
typedef struct LNK_ObjNode
@@ -102,9 +101,10 @@ internal LNK_SymbolInputResult lnk_input_obj_symbols(TP_Context *tp, TP_Arena *a
// --- Metadata ----------------------------------------------------------------
internal U32 lnk_obj_get_features(LNK_Obj *obj);
internal U32 lnk_obj_get_comp_id(LNK_Obj *obj);
internal U32 lnk_obj_get_vol_md(LNK_Obj *obj);
internal U32 lnk_obj_get_features(LNK_Obj *obj);
internal U32 lnk_obj_get_comp_id(LNK_Obj *obj);
internal U32 lnk_obj_get_vol_md(LNK_Obj *obj);
internal String8 lnk_obj_get_lib_path(LNK_Obj *obj);
// --- Symbol & Section Helpers ------------------------------------------------