emit jump thunks for imports only when needed

This commit is contained in:
Nikita Smith
2025-09-02 22:20:34 -07:00
committed by Ryan Fleury
parent 43e81b934b
commit 580303b0dd
4 changed files with 110 additions and 90 deletions
+74 -65
View File
@@ -998,31 +998,31 @@ lnk_inputer_push_thin(Arena *arena, LNK_InputList *list, HashTable *ht, String8
}
internal LNK_Input *
lnk_inputer_push_obj(LNK_Inputer *inputer, LNK_LibMemberRef *trigger, String8 path, String8 data)
lnk_inputer_push_obj(LNK_Inputer *inputer, LNK_LibMemberRef *link_member, String8 path, String8 data)
{
lnk_log(LNK_Log_InputObj, "Input Obj: %S", path);
LNK_Input *input = lnk_input_push(inputer->arena, &inputer->new_objs, path, data);
input->trigger = trigger;
input->link_member = link_member;
return input;
}
internal LNK_Input *
lnk_inputer_push_obj_linkgen(LNK_Inputer *inputer, LNK_LibMemberRef *trigger, String8 path, String8 data)
lnk_inputer_push_obj_linkgen(LNK_Inputer *inputer, LNK_LibMemberRef *link_member, String8 path, String8 data)
{
lnk_log(LNK_Log_InputObj, "Input Obj: %S", path);
LNK_Input *input = lnk_inputer_push_linkgen(inputer->arena, &inputer->new_objs, path, data);
input->trigger = trigger;
input->link_member = link_member;
return input;
}
internal LNK_Input *
lnk_inputer_push_obj_thin(LNK_Inputer *inputer, LNK_LibMemberRef *trigger, String8 path)
lnk_inputer_push_obj_thin(LNK_Inputer *inputer, LNK_LibMemberRef *link_member, String8 path)
{
lnk_log(LNK_Log_InputObj, "Input Obj: %S", path);
Temp scratch = scratch_begin(0,0);
String8 full_path = os_full_path_from_path(scratch.arena, path);
LNK_Input *input = lnk_inputer_push_thin(inputer->arena, &inputer->new_objs, inputer->objs_ht, full_path);
input->trigger = trigger;
input->link_member = link_member;
scratch_end(scratch);
return input;
}
@@ -1257,7 +1257,7 @@ internal void
lnk_load_libs(TP_Context *tp, TP_Arena *arena, LNK_Config *config, LNK_Inputer *inputer, LNK_Link *link)
{
for EachIndex(input_source, LNK_InputSource_Count) {
ProfBegin("Input Libs [Count %llu]", inputer->new_libs[i].count);
//ProfBegin("Input Libs [Count %llu]", inputer->new_libs[i].count);
LNK_InputPtrArray new_input_libs = lnk_inputer_flush(arena->v[0], tp, inputer, config->io_flags, &inputer->libs, &inputer->new_libs[input_source]);
@@ -1315,7 +1315,7 @@ lnk_load_inputs(TP_Context *tp, TP_Arena *arena, LNK_Config *config, LNK_Inputer
LNK_Obj *obj_with_includes = objs_with_includes[i];
String8 include_obj_path = obj_with_includes ? obj_with_includes->path : str8_lit("RADLINK");
String8 include_obj_data = lnk_make_obj_with_undefined_symbols(arena->v[0], *include_names[i]);
lnk_inputer_push_obj_linkgen(inputer, obj_with_includes ? obj_with_includes->trigger_symbol : 0, include_obj_path, include_obj_data);
lnk_inputer_push_obj_linkgen(inputer, obj_with_includes ? obj_with_includes->link_member : 0, include_obj_path, include_obj_data);
U64 include_obj_count = 0;
LNK_ObjNode *include_obj = lnk_load_objs(tp, arena, config, inputer, symtab, link, &include_obj_count);
@@ -1462,7 +1462,7 @@ subsystem_inferred_from_entry:;
internal void
lnk_queue_lib_member(Arena *arena, LNK_LibMemberRefList *queued_members, LNK_Symbol *trigger_symbol, LNK_Lib *lib, U32 member_idx)
{
if (lnk_flag_member_as_queued(lib, member_idx, trigger_symbol)) {
if (lnk_lib_set_link_symbol(lib, member_idx, trigger_symbol)) {
LNK_LibMemberRef *member_ref = push_array(arena, LNK_LibMemberRef, 1);
member_ref->lib = lib;
member_ref->member_idx = member_idx;
@@ -1494,6 +1494,8 @@ lnk_link_inputs_(TP_Context *tp,
for (LNK_LibNode *lib_n = link->libs.first; lib_n != 0; lib_n = lib_n->next) {
do {
lnk_load_inputs(tp, arena, config, inputer, symtab, link);
LNK_LibMemberRefList queued_members = {0};
for EachIndex(worker_id, symtab->arena->count) {
for (LNK_SymbolHashTrieChunk *c = symtab->chunks[worker_id].first; c != 0; c = c->next) {
@@ -1539,6 +1541,7 @@ lnk_link_inputs_(TP_Context *tp,
LNK_LibMemberRef *member_ref = member_refs[i];
LNK_Lib *lib = member_ref->lib;
U32 member_offset = lib->member_offsets[member_ref->member_idx];
LNK_Symbol *link_symbol = lib->was_member_linked[member_ref->member_idx];
// parse member
COFF_ArchiveMember member_info = coff_archive_member_from_offset(lib->data, member_offset);
@@ -1565,23 +1568,25 @@ lnk_link_inputs_(TP_Context *tp,
if (hash_table_search_string_raw(imps->import_stub_ht, import_header.func_name, 0)) { break; }
hash_table_push_string_raw(imps->arena, imps->import_stub_ht, import_header.func_name, 0);
// create import stubs (later replaced with acutal imports generated by linker)
LNK_Symbol *import_stub = lnk_symbol_table_search(symtab, str8_lit(LNK_IMPORT_STUB));
LNK_Symbol *thunk_symbol = lnk_make_defined_symbol(symtab->arena->v[0], import_header.func_name, import_stub->defined.obj, import_stub->defined.symbol_idx);
LNK_Symbol *imp_symbol = lnk_make_defined_symbol(symtab->arena->v[0], push_str8f(symtab->arena->v[0], "__imp_%S", import_header.func_name), import_stub->defined.obj, import_stub->defined.symbol_idx);
lnk_symbol_table_push(symtab, thunk_symbol);
lnk_symbol_table_push(symtab, imp_symbol);
// create import stub (later replaced with acutal import generated by linker)
LNK_Symbol *import_stub = lnk_symbol_table_search(symtab, str8_lit(LNK_IMPORT_STUB));
LNK_Symbol *import_symbol = lnk_make_defined_symbol(symtab->arena->v[0], link_symbol->name, import_stub->defined.obj, import_stub->defined.symbol_idx);
lnk_symbol_table_push(symtab, import_symbol);
// search DLL symbol list
HashTable *imports_ht = lnk_is_dll_delay_load(config, import_header.dll_name) ? imps->delayed_imports : imps->static_imports;
String8List *import_symbols = hash_table_search_path_raw(imports_ht, import_header.dll_name);
B32 is_delay_load = lnk_is_dll_delay_load(config, import_header.dll_name);
String8List *dll_names = is_delay_load ? &imps->delayed_dll_names : &imps->static_dll_names;
HashTable *imports_ht = is_delay_load ? imps->delayed_imports : imps->static_imports;
PE_MakeImportList *import_symbols = hash_table_search_path_raw(imports_ht, import_header.dll_name);
if (import_symbols == 0) {
import_symbols = push_array(imps->arena, String8List, 1);
import_symbols = push_array(imps->arena, PE_MakeImportList, 1);
str8_list_push(imps->arena, dll_names, import_header.dll_name);
hash_table_push_path_raw(imps->arena, imports_ht, import_header.dll_name, import_symbols);
}
// push symbol
str8_list_push(imps->arena, import_symbols, member_info.data);
PE_MakeImport make_import = { .header = member_info.data, .make_jump_thunk = !str8_starts_with(link_symbol->name, str8_lit("__imp_")) };
pe_make_import_header_list_push(imps->arena, import_symbols, make_import);
} break;
case COFF_DataType_BigObj:
case COFF_DataType_Obj: {
@@ -1614,8 +1619,6 @@ lnk_link_inputs_(TP_Context *tp,
}
}
lnk_load_inputs(tp, arena, config, inputer, symtab, link);
resolved_members_count += queued_members.count;
} while (lnk_inputer_has_items(inputer));
}
@@ -1631,7 +1634,7 @@ lnk_link_inputs(TP_Context *tp, TP_Arena *arena, LNK_Config *config, LNK_Inputer
{
lnk_link_inputs_(tp, arena, config, inputer, symtab, link, imps, 0);
// input /ALTERNATENAME
// handle /ALTERNATENAME
{
// replace undefined symbols that have an alternate name with a weak symbol
for (LNK_AltNameNode *alt_name_n = config->alt_name_list.first; alt_name_n != 0; alt_name_n = alt_name_n->next) {
@@ -1641,6 +1644,7 @@ lnk_link_inputs(TP_Context *tp, TP_Arena *arena, LNK_Config *config, LNK_Inputer
if (interp == COFF_SymbolValueInterp_Undefined) {
// clear out slot so weak symbol can replace undefined symbol (general rule is
// weak symbol is not allowed to replace undefined)
LNK_Symbol *undef_symbol = symbol_ht->symbol;
symbol_ht->symbol = 0;
// make obj with alternamte name symbol
@@ -1654,10 +1658,11 @@ lnk_link_inputs(TP_Context *tp, TP_Arena *arena, LNK_Config *config, LNK_Inputer
coff_obj_writer_release(&obj_writer);
}
// input alt name obj
LNK_Obj *obj_with_alt_name = alt_name_n->data.obj;
String8 alt_name_obj_path = obj_with_alt_name ? obj_with_alt_name->path : str8_lit("RADLINK");
lnk_inputer_push_obj_linkgen(inputer, 0, alt_name_obj_path, alt_name_obj_data);
LNK_Obj *obj_with_alt_name = alt_name_n->data.obj;
String8 obj_with_alt_name_path = obj_with_alt_name ? obj_with_alt_name->path : str8_lit("RADLINK");
lnk_inputer_push_obj_linkgen(inputer, obj_with_alt_name ? obj_with_alt_name->link_member : 0, obj_with_alt_name_path, alt_name_obj_data);
lnk_load_inputs(tp, arena, config, inputer, symtab, link);
}
}
}
@@ -1721,7 +1726,7 @@ lnk_link_image(TP_Context *tp, TP_Arena *arena, LNK_Config *config, LNK_Inputer
// link inputer
lnk_link_inputs(tp, arena, config, inputer, symtab, link, imps);
// TODO: need to know under which condition to include load config
// TODO: need to figure out under what condition to include load config
//lnk_include_symbol(config, str8_lit(MSCRT_LOAD_CONFIG_SYMBOL_NAME), 0);
{
@@ -1733,27 +1738,28 @@ lnk_link_image(TP_Context *tp, TP_Arena *arena, LNK_Config *config, LNK_Inputer
// make and input delayed imports
{
HashTable *delayed_imports = imps->delayed_imports;
if (delayed_imports->count) {
String8List delayed_dll_names = imps->delayed_dll_names;
HashTable *delayed_imports_ht = imps->delayed_imports;
AssertAlways(delayed_dll_names.node_count == delayed_imports_ht->count);
if (delayed_imports_ht->count) {
ProfBegin("Build Delay Import Table");
COFF_TimeStamp time_stamp = COFF_TimeStamp_Max;
B32 emit_biat = config->import_table_emit_biat == LNK_SwitchState_Yes;
B32 emit_uiat = config->import_table_emit_uiat == LNK_SwitchState_Yes;
String8 *dll_names = keys_from_hash_table_string(scratch.arena, delayed_imports);
String8List **dll_import_headers = values_from_hash_table_raw(scratch.arena, delayed_imports);
COFF_TimeStamp time_stamp = COFF_TimeStamp_Max;
B32 emit_biat = config->import_table_emit_biat == LNK_SwitchState_Yes;
B32 emit_uiat = config->import_table_emit_uiat == LNK_SwitchState_Yes;
for EachIndex(dll_idx, delayed_imports->count) {
String8 import_debug_symbols = lnk_make_dll_import_debug_symbols(scratch.arena, config->machine, dll_names[dll_idx]);
String8 import_obj = pe_make_import_dll_obj_delayed(arena->v[0], time_stamp, config->machine, dll_names[dll_idx], config->delay_load_helper_name, import_debug_symbols, *dll_import_headers[dll_idx], emit_biat, emit_uiat);
lnk_inputer_push_obj(inputer, 0, dll_names[dll_idx], import_obj);
for (String8Node *dll_name_n = delayed_dll_names.first; dll_name_n != 0; dll_name_n = dll_name_n->next) {
PE_MakeImportList *imports = hash_table_search_path_raw(delayed_imports_ht, dll_name_n->string);
String8 import_debug_symbols = lnk_make_dll_import_debug_symbols(scratch.arena, config->machine, dll_name_n->string);
String8 import_obj = pe_make_import_dll_obj_delayed(arena->v[0], time_stamp, config->machine, dll_name_n->string, config->delay_load_helper_name, import_debug_symbols, *imports, emit_biat, emit_uiat);
lnk_inputer_push_obj(inputer, 0, dll_name_n->string, import_obj);
}
String8 linker_debug_symbols = lnk_make_linker_debug_symbols(arena->v[0], config->machine);
String8 null_desc_obj = pe_make_null_import_descriptor_delayed(arena->v[0], time_stamp, config->machine, linker_debug_symbols);
String8 null_thunk_obj = pe_make_null_thunk_data_obj_delayed(arena->v[0], lnk_get_image_name(config), time_stamp, config->machine, linker_debug_symbols);
lnk_inputer_push_obj(inputer, 0, str8_lit("* Delayed Null Import Descriptor *"), null_desc_obj);
lnk_inputer_push_obj(inputer, 0, str8_lit("* Delayed Null Thunk Data *"), null_thunk_obj);
lnk_inputer_push_obj(inputer, 0, str8_lit("* Delayed Null Thunk Data *"), null_thunk_obj);
ProfEnd();
}
@@ -1761,24 +1767,26 @@ lnk_link_image(TP_Context *tp, TP_Arena *arena, LNK_Config *config, LNK_Inputer
// make and input static imports
{
HashTable *static_imports = imps->static_imports;
if (static_imports->count) {
String8List static_dll_names = imps->static_dll_names;
HashTable *static_imports_ht = imps->static_imports;
AssertAlways(static_dll_names.node_count == static_imports_ht->count);
if (static_imports_ht->count) {
ProfBegin("Build Static Import Table");
COFF_TimeStamp time_stamp = COFF_TimeStamp_Max;
String8 *dll_names = keys_from_hash_table_string(scratch.arena, static_imports);
String8List **dll_import_headers = values_from_hash_table_raw(scratch.arena, static_imports);
for EachIndex(dll_idx, static_imports->count) {
String8 import_debug_symbols = lnk_make_dll_import_debug_symbols(scratch.arena, config->machine, dll_names[dll_idx]);
String8 import_obj = pe_make_import_dll_obj_static(arena->v[0], time_stamp, config->machine, dll_names[dll_idx], import_debug_symbols, *dll_import_headers[dll_idx]);
lnk_inputer_push_obj(inputer, 0, dll_names[dll_idx], import_obj);
COFF_TimeStamp time_stamp = COFF_TimeStamp_Max;
for (String8Node *dll_name_n = static_dll_names.first; dll_name_n != 0; dll_name_n = dll_name_n->next) {
PE_MakeImportList *imports = hash_table_search_path_raw(static_imports_ht, dll_name_n->string);
String8 import_debug_symbols = lnk_make_dll_import_debug_symbols(scratch.arena, config->machine, dll_name_n->string);
String8 import_obj = pe_make_import_dll_obj_static(arena->v[0], time_stamp, config->machine, dll_name_n->string, import_debug_symbols, *imports);
lnk_inputer_push_obj(inputer, 0, dll_name_n->string, import_obj);
}
String8 linker_debug_symbols = lnk_make_linker_debug_symbols(scratch.arena, config->machine);
String8 null_desc_obj = pe_make_null_import_descriptor_obj(arena->v[0], time_stamp, config->machine, linker_debug_symbols);
String8 null_thunk_obj = pe_make_null_thunk_data_obj(arena->v[0], lnk_get_image_name(config), time_stamp, config->machine, linker_debug_symbols);
String8 null_desc_obj = pe_make_null_import_descriptor_obj(arena->v[0], time_stamp, config->machine, linker_debug_symbols);
String8 null_thunk_obj = pe_make_null_thunk_data_obj(arena->v[0], lnk_get_image_name(config), time_stamp, config->machine, linker_debug_symbols);
lnk_inputer_push_obj_linkgen(inputer, 0, str8_lit("* Null Import Descriptor *"), null_desc_obj);
lnk_inputer_push_obj_linkgen(inputer, 0, str8_lit("* Null Thunk Data *"), null_thunk_obj);
lnk_inputer_push_obj_linkgen(inputer, 0, str8_lit("* Null Thunk Data *"), null_thunk_obj);
ProfEnd();
}
@@ -2272,7 +2280,7 @@ THREAD_POOL_TASK_FUNC(lnk_gather_section_definitions_task)
for (U64 sect_idx = 0; sect_idx < obj->header.section_count_no_null; sect_idx += 1) {
COFF_SectionHeader *sect_header = &section_table[sect_idx];
if (~sect_header->flags & COFF_SectionFlag_LnkRemove && sect_header->fsize > 0) {
if (~sect_header->flags & COFF_SectionFlag_LnkRemove && ~sect_header->flags & COFF_SectionFlag_LnkInfo && sect_header->fsize > 0) {
Temp temp = temp_begin(scratch.arena);
// was section defined?
@@ -2319,7 +2327,7 @@ THREAD_POOL_TASK_FUNC(lnk_gather_section_contribs_task)
for (U64 sect_idx = 0; sect_idx < obj->header.section_count_no_null; sect_idx += 1) {
LNK_SectionContrib *sc = task->null_sc;
COFF_SectionHeader *sect_header = &section_table[sect_idx];
if (~sect_header->flags & COFF_SectionFlag_LnkRemove && sect_header->fsize > 0) {
if (~sect_header->flags & COFF_SectionFlag_LnkRemove && ~sect_header->flags & COFF_SectionFlag_LnkInfo && sect_header->fsize > 0) {
LNK_SectionContribChunk *sc_chunk = 0;
{
Temp temp = temp_begin(scratch.arena);
@@ -4029,13 +4037,12 @@ lnk_build_image(TP_Arena *arena, TP_Context *tp, LNK_Config *config, LNK_SymbolT
{
String8List empty_sect_list = {0};
for (LNK_SectionNode *sect_n = sectab->list.first; sect_n != 0; sect_n = sect_n->next) {
LNK_Section *sect = &sect_n->data;
if (sect->vsize == 0) {
str8_list_push(scratch.arena, &empty_sect_list, sect->name);
if (sect_n->data.vsize == 0) {
str8_list_push(scratch.arena, &empty_sect_list, sect_n->data.name);
}
}
for (String8Node *name_n = empty_sect_list.first; name_n != 0; name_n = name_n->next) {
lnk_section_table_remove(sectab, name_n->string);
lnk_section_table_purge(sectab, name_n->string);
}
}
@@ -4579,11 +4586,11 @@ lnk_build_rad_map(Arena *arena, String8 image_data, LNK_Config *config, U64 objs
String8List source_list = {0};
if (obj) {
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) {
String8 lib_path = lnk_obj_get_lib_path(obj);
String8 lib_name = str8_chop_last_dot(str8_skip_last_slash(lib_path));
String8 string_table = str8_substr(obj->data, obj->header.string_table_range);
String8 section_name = coff_name_from_section_header(string_table, section_header);
LNK_Lib *lib = lnk_obj_get_lib(obj);
if (lib) {
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 {
@@ -4612,9 +4619,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) {
String8 lib_path = lnk_obj_get_lib_path(obj);
String8 lib_name = str8_chop_last_dot(str8_skip_last_slash(lib_path));
LNK_Lib *lib = lnk_obj_get_lib(obj);
if (lib) {
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 {
@@ -4844,6 +4851,8 @@ entry_point(CmdLine *cmdline)
TP_Context *tp = tp_alloc(scratch.arena, config->worker_count, config->max_worker_count, config->shared_thread_pool_name);
TP_Arena *tp_arena = tp_arena_alloc(tp);
lnk_run(tp, tp_arena, config);
exit:;
scratch_end(scratch);
}
+6 -5
View File
@@ -9,7 +9,6 @@ typedef struct LNK_LibMemberRef
{
LNK_Lib *lib;
U32 member_idx;
struct LNK_LibMemberRef *next;
} LNK_LibMemberRef;
@@ -36,7 +35,7 @@ typedef struct LNK_Input
B32 is_thin;
B32 has_disk_read_failed;
B32 exclude_from_debug_info;
LNK_LibMemberRef *trigger;
LNK_LibMemberRef *link_member;
void *loaded_input;
struct LNK_Input *next;
@@ -79,6 +78,8 @@ typedef struct LNK_Inputer
typedef struct LNK_ImportTables
{
Arena *arena;
String8List delayed_dll_names;
String8List static_dll_names;
HashTable *static_imports;
HashTable *delayed_imports;
HashTable *import_stub_ht;
@@ -269,9 +270,9 @@ internal LNK_Input * lnk_input_push(Arena *arena, LNK_InputList *list, String8 p
internal LNK_Input * lnk_inputer_push_linkgen(Arena *arena, LNK_InputList *list, String8 path, String8 data);
internal LNK_Input * lnk_inputer_push_thin(Arena *arena, LNK_InputList *list, HashTable *ht, String8 full_path);
internal LNK_Input * lnk_inputer_push_obj(LNK_Inputer *inputer, LNK_LibMemberRef *trigger, String8 path, String8 data);
internal LNK_Input * lnk_inputer_push_obj_linkgen(LNK_Inputer *inputer, LNK_LibMemberRef *trigger, String8 path, String8 data);
internal LNK_Input * lnk_inputer_push_obj_thin(LNK_Inputer *inputer, LNK_LibMemberRef *trigger, String8 path);
internal LNK_Input * lnk_inputer_push_obj(LNK_Inputer *inputer, LNK_LibMemberRef *link_member, String8 path, String8 data);
internal LNK_Input * lnk_inputer_push_obj_linkgen(LNK_Inputer *inputer, LNK_LibMemberRef *link_member, String8 path, String8 data);
internal LNK_Input * lnk_inputer_push_obj_thin(LNK_Inputer *inputer, LNK_LibMemberRef *link_member, String8 path);
internal LNK_Input * lnk_inputer_push_lib(LNK_Inputer *inputer, LNK_InputSourceType input_source, String8 path, String8 data);
internal LNK_Input * lnk_inputer_push_lib_linkgen(LNK_Inputer *inputer, LNK_InputSourceType input_source, String8 path, String8 data);
+21 -12
View File
@@ -15,7 +15,9 @@ internal void
lnk_error_input_obj(LNK_ErrorCode code, LNK_Input *input, char *fmt, ...)
{
va_list args; va_start(args, fmt);
lnk_error_with_loc_fv(code, input->path, input->trigger->lib ? input->trigger->lib->path : str8_zero(), fmt, args);
LNK_LibMemberRef *link_member = input->link_member;
LNK_Lib *link_lib = link_member ? link_member->lib : 0;
lnk_error_with_loc_fv(code, input->path, link_lib ? link_lib->path : str8_zero(), fmt, args);
va_end(args);
}
@@ -37,7 +39,7 @@ THREAD_POOL_TASK_FUNC(lnk_obj_initer)
LNK_Input *input = task->inputs[task_id];
LNK_Obj *obj = &task->objs[task_id].data;
ProfBeginV("Init Obj [%S%s%S]", input->lib_path, (input->lib_path.size ? ": " : 0), input->path);
//ProfBeginV("Init Obj [%S%s%S]", input->lib_path, (input->lib_path.size ? ": " : 0), input->path);
//
// parse obj header
@@ -244,19 +246,20 @@ THREAD_POOL_TASK_FUNC(lnk_obj_initer)
}
}
//
// extract obj features from compile symbol in .debug$S
//
B8 hotpatch = 0;
if (header.machine == COFF_MachineType_X64) {
hotpatch = 1;
} else {
}
//
// extract obj features from compile symbol in .debug$S
//
else {
Temp scratch = scratch_begin(&arena, 1);
CV_Symbol comp_symbol = {0};
for (U64 sect_idx = 0; sect_idx < obj->header.section_count_no_null; sect_idx += 1) {
for (U64 sect_idx = 0; sect_idx < header.section_count_no_null; sect_idx += 1) {
COFF_SectionHeader *sect_header = &coff_section_table[sect_idx];
String8 name = str8_cstring_capped_reverse(sect_header->name, sect_header->name+sizeof(sect_header->name));
String8 name = str8_cstring_capped(sect_header->name, sect_header->name+sizeof(sect_header->name));
if (str8_match(name, str8_lit(".debug$S"), 0)) {
Temp temp = temp_begin(scratch.arena);
String8 debug_s_data = str8_substr(input->data, rng_1u64(sect_header->foff, sect_header->foff+sect_header->fsize));
@@ -288,14 +291,13 @@ THREAD_POOL_TASK_FUNC(lnk_obj_initer)
// fill out obj
obj->data = input->data;
obj->path = push_str8_copy(arena, input->path);
obj->lib = input->trigger ? input->trigger->lib : 0;
obj->header = header;
obj->comdats = comdats;
obj->exclude_from_debug_info = input->exclude_from_debug_info;
obj->hotpatch = hotpatch;
obj->associated_sections = associated_sections;
obj->node = &task->objs[task_id];
obj->trigger_symbol = input->trigger;
obj->link_member = input->link_member;
ProfEnd();
}
@@ -454,12 +456,19 @@ lnk_obj_get_vol_md(LNK_Obj *obj)
return lnk_obj_match_symbol(obj, str8_lit("@vol.md")).value;
}
internal LNK_Lib *
lnk_obj_get_lib(LNK_Obj *obj)
{
return obj->link_member ? obj->link_member->lib : 0;
}
internal String8
lnk_obj_get_lib_path(LNK_Obj *obj)
{
String8 lib_path = {0};
if (obj && obj->lib) {
lib_path = obj->lib->path;
if (obj) {
LNK_Lib *lib = lnk_obj_get_lib(obj);
lib_path = lib ? lib->path : str8_zero();
}
return lib_path;
}
+9 -8
View File
@@ -9,8 +9,6 @@ typedef struct LNK_Obj
{
String8 path;
String8 data;
struct LNK_Lib *lib;
struct LNK_LibMemberRef *trigger_symbol;
U32 input_idx;
COFF_FileHeaderInfo header;
U32 *comdats;
@@ -19,6 +17,8 @@ typedef struct LNK_Obj
U32Node **associated_sections;
LNK_SymbolHashTrie **symlinks;
struct LNK_LibMemberRef *link_member;
struct LNK_ObjNode *node;
} LNK_Obj;
@@ -102,12 +102,13 @@ internal void lnk_inputer_push_obj_symbols(TP_Context *tp, TP_Arena *arena
// --- 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 String8 lnk_obj_get_lib_path(LNK_Obj *obj);
internal U32 lnk_obj_get_removed_section_number(LNK_Obj *obj);
internal LNK_Symbol * lnk_obj_get_comdat_symlink(LNK_Obj *obj, U64 section_number);
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 struct LNK_Lib * lnk_obj_get_lib(LNK_Obj *obj);
internal String8 lnk_obj_get_lib_path(LNK_Obj *obj);
internal U32 lnk_obj_get_removed_section_number(LNK_Obj *obj);
internal LNK_Symbol * lnk_obj_get_comdat_symlink(LNK_Obj *obj, U64 section_number);
// --- Symbol & Section Helpers ------------------------------------------------