mirror of
https://github.com/Ed94/raddebugger.git
synced 2026-08-08 14:58:08 +00:00
WIP light COFF symbol table parse
This commit is contained in:
committed by
Ryan Fleury
parent
bd2cbfc127
commit
493241c1da
+43
-17
@@ -166,13 +166,20 @@ coff_section_header_array_from_name(Arena *arena, String8 string_table, COFF_Sec
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
internal COFF_ParsedSymbol
|
internal COFF_ParsedSymbol
|
||||||
coff_parse_symbol32(String8 string_table, COFF_Symbol32 *sym32)
|
coff_parse_symbol32(String8 string_table, COFF_Symbol32 *sym32)
|
||||||
{
|
{
|
||||||
COFF_ParsedSymbol result = {0};
|
COFF_ParsedSymbol result = coff_parse_symbol32_no_name(sym32);
|
||||||
result.name = coff_read_symbol_name(string_table, &sym32->name);
|
result.name = coff_read_symbol_name(string_table, &sym32->name);
|
||||||
result.value = sym32->value;
|
return result;
|
||||||
result.section_number = sym32->section_number;
|
}
|
||||||
|
|
||||||
|
internal force_inline COFF_ParsedSymbol
|
||||||
|
coff_parse_symbol32_no_name(COFF_Symbol32 *sym32)
|
||||||
|
{
|
||||||
|
COFF_ParsedSymbol result = {0};
|
||||||
|
result.value = sym32->value;
|
||||||
|
result.section_number = sym32->section_number;
|
||||||
result.type = sym32->type;
|
result.type = sym32->type;
|
||||||
result.storage_class = sym32->storage_class;
|
result.storage_class = sym32->storage_class;
|
||||||
result.aux_symbol_count = sym32->aux_symbol_count;
|
result.aux_symbol_count = sym32->aux_symbol_count;
|
||||||
@@ -180,12 +187,19 @@ coff_parse_symbol32(String8 string_table, COFF_Symbol32 *sym32)
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal COFF_ParsedSymbol
|
internal COFF_ParsedSymbol
|
||||||
coff_parse_symbol16(String8 string_table, COFF_Symbol16 *sym16)
|
coff_parse_symbol16(String8 string_table, COFF_Symbol16 *sym16)
|
||||||
{
|
{
|
||||||
COFF_ParsedSymbol result = {0};
|
COFF_ParsedSymbol result = coff_parse_symbol16_no_name(sym16);
|
||||||
result.name = coff_read_symbol_name(string_table, &sym16->name);
|
result.name = coff_read_symbol_name(string_table, &sym16->name);
|
||||||
result.value = sym16->value;
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal force_inline COFF_ParsedSymbol
|
||||||
|
coff_parse_symbol16_no_name(COFF_Symbol16 *sym16)
|
||||||
|
{
|
||||||
|
COFF_ParsedSymbol result = {0};
|
||||||
|
result.value = sym16->value;
|
||||||
if (sym16->section_number == COFF_Symbol_DebugSection16) {
|
if (sym16->section_number == COFF_Symbol_DebugSection16) {
|
||||||
result.section_number = COFF_Symbol_DebugSection32;
|
result.section_number = COFF_Symbol_DebugSection32;
|
||||||
} else if (sym16->section_number == COFF_Symbol_AbsSection16) {
|
} else if (sym16->section_number == COFF_Symbol_AbsSection16) {
|
||||||
@@ -200,8 +214,8 @@ coff_parse_symbol16(String8 string_table, COFF_Symbol16 *sym16)
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal COFF_ParsedSymbol
|
internal COFF_ParsedSymbol
|
||||||
coff_parse_symbol(COFF_FileHeaderInfo header, String8 string_table, String8 symbol_table, U32 symbol_idx)
|
coff_parse_symbol(COFF_FileHeaderInfo header, String8 string_table, String8 symbol_table, U32 symbol_idx)
|
||||||
{
|
{
|
||||||
COFF_ParsedSymbol symbol;
|
COFF_ParsedSymbol symbol;
|
||||||
if (header.is_big_obj) {
|
if (header.is_big_obj) {
|
||||||
@@ -209,8 +223,20 @@ coff_parse_symbol(COFF_FileHeaderInfo header, String8 string_table, String8 symb
|
|||||||
} else {
|
} else {
|
||||||
symbol = coff_parse_symbol16(string_table, (COFF_Symbol16 *)symbol_table.str + symbol_idx);
|
symbol = coff_parse_symbol16(string_table, (COFF_Symbol16 *)symbol_table.str + symbol_idx);
|
||||||
}
|
}
|
||||||
return symbol;
|
return symbol;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal force_inline COFF_ParsedSymbol
|
||||||
|
coff_parse_symbol_no_name(COFF_FileHeaderInfo header, String8 symbol_table, U32 symbol_idx)
|
||||||
|
{
|
||||||
|
COFF_ParsedSymbol symbol;
|
||||||
|
if (header.is_big_obj) {
|
||||||
|
symbol = coff_parse_symbol32_no_name((COFF_Symbol32 *)symbol_table.str + symbol_idx);
|
||||||
|
} else {
|
||||||
|
symbol = coff_parse_symbol16_no_name((COFF_Symbol16 *)symbol_table.str + symbol_idx);
|
||||||
|
}
|
||||||
|
return symbol;
|
||||||
|
}
|
||||||
|
|
||||||
internal COFF_Symbol32Array
|
internal COFF_Symbol32Array
|
||||||
coff_symbol_array_from_data_16(Arena *arena, String8 raw_coff, U64 symbol_array_off, U64 symbol_count)
|
coff_symbol_array_from_data_16(Arena *arena, String8 raw_coff, U64 symbol_array_off, U64 symbol_count)
|
||||||
|
|||||||
@@ -259,9 +259,12 @@ internal String8 coff_name_from_section_header (String8 str
|
|||||||
////////////////////////////////
|
////////////////////////////////
|
||||||
// Symbol
|
// Symbol
|
||||||
|
|
||||||
internal COFF_ParsedSymbol coff_parse_symbol32(String8 string_table, COFF_Symbol32 *sym32);
|
internal COFF_ParsedSymbol coff_parse_symbol32(String8 string_table, COFF_Symbol32 *sym32);
|
||||||
internal COFF_ParsedSymbol coff_parse_symbol16(String8 string_table, COFF_Symbol16 *sym16);
|
internal COFF_ParsedSymbol coff_parse_symbol16(String8 string_table, COFF_Symbol16 *sym16);
|
||||||
internal COFF_ParsedSymbol coff_parse_symbol (COFF_FileHeaderInfo header, String8 string_table, String8 symbol_table, U32 symbol_idx);
|
internal COFF_ParsedSymbol coff_parse_symbol (COFF_FileHeaderInfo header, String8 string_table, String8 symbol_table, U32 symbol_idx);
|
||||||
|
internal force_inline COFF_ParsedSymbol coff_parse_symbol32_no_name(COFF_Symbol32 *sym32);
|
||||||
|
internal force_inline COFF_ParsedSymbol coff_parse_symbol16_no_name(COFF_Symbol16 *sym16);
|
||||||
|
internal force_inline COFF_ParsedSymbol coff_parse_symbol_no_name (COFF_FileHeaderInfo header, String8 symbol_table, U32 symbol_idx);
|
||||||
|
|
||||||
internal COFF_Symbol32Array coff_symbol_array_from_data_16(Arena *arena, String8 data, U64 symbol_array_off, U64 symbol_count);
|
internal COFF_Symbol32Array coff_symbol_array_from_data_16(Arena *arena, String8 data, U64 symbol_array_off, U64 symbol_count);
|
||||||
internal COFF_Symbol32Array coff_symbol_array_from_data_32(Arena *arena, String8 data, U64 symbol_array_off, U64 symbol_count);
|
internal COFF_Symbol32Array coff_symbol_array_from_data_32(Arena *arena, String8 data, U64 symbol_array_off, U64 symbol_count);
|
||||||
|
|||||||
+36
-32
@@ -1703,7 +1703,7 @@ THREAD_POOL_TASK_FUNC(lnk_search_lib_task)
|
|||||||
for (U64 i = i_begin; i < i_end; i += 1) {
|
for (U64 i = i_begin; i < i_end; i += 1) {
|
||||||
LNK_Symbol *symbol = c->v[i].symbol;
|
LNK_Symbol *symbol = c->v[i].symbol;
|
||||||
LNK_ObjSymbolRef symbol_ref = lnk_ref_from_symbol(symbol);
|
LNK_ObjSymbolRef symbol_ref = lnk_ref_from_symbol(symbol);
|
||||||
COFF_ParsedSymbol symbol_parsed = lnk_parsed_from_symbol(symbol);
|
COFF_ParsedSymbol symbol_parsed = lnk_parsed_symbol_from_coff_symbol_idx_no_name(symbol_ref.obj, symbol_ref.symbol_idx);
|
||||||
COFF_SymbolValueInterpType symbol_interp = coff_interp_from_parsed_symbol(symbol_parsed);
|
COFF_SymbolValueInterpType symbol_interp = coff_interp_from_parsed_symbol(symbol_parsed);
|
||||||
|
|
||||||
if (symbol_interp == COFF_SymbolValueInterp_Undefined) {
|
if (symbol_interp == COFF_SymbolValueInterp_Undefined) {
|
||||||
@@ -1722,11 +1722,11 @@ THREAD_POOL_TASK_FUNC(lnk_search_lib_task)
|
|||||||
if (search_anti_deps) {
|
if (search_anti_deps) {
|
||||||
LNK_ObjSymbolRef dep_symbol = {0};
|
LNK_ObjSymbolRef dep_symbol = {0};
|
||||||
if (lnk_resolve_weak_symbol(symtab, symbol_ref, &dep_symbol)) {
|
if (lnk_resolve_weak_symbol(symtab, symbol_ref, &dep_symbol)) {
|
||||||
COFF_ParsedSymbol dep_parsed = lnk_parsed_symbol_from_coff_symbol_idx(dep_symbol.obj, dep_symbol.symbol_idx);
|
COFF_ParsedSymbol dep_parsed = lnk_parsed_symbol_from_coff_symbol_idx_no_name(dep_symbol.obj, dep_symbol.symbol_idx);
|
||||||
COFF_SymbolValueInterpType dep_interp = coff_interp_from_parsed_symbol(dep_parsed);
|
COFF_SymbolValueInterpType dep_interp = coff_interp_from_parsed_symbol(dep_parsed);
|
||||||
if (dep_interp == COFF_SymbolValueInterp_Weak) {
|
if (dep_interp == COFF_SymbolValueInterp_Weak) {
|
||||||
U32 member_idx;
|
U32 member_idx;
|
||||||
if (lnk_search_lib(lib, symbol_parsed.name, &member_idx)) {
|
if (lnk_search_lib(lib, symbol->name, &member_idx)) {
|
||||||
lnk_queue_lib_member(arena, task->imports_hm, task->link->lib_member_infos_hm, member_ref_list, symbol, lib, lib_member_infos, member_idx);
|
lnk_queue_lib_member(arena, task->imports_hm, task->link->lib_member_infos_hm, member_ref_list, symbol, lib, lib_member_infos, member_idx);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2668,7 +2668,7 @@ lnk_resolve_reloc_target_symbol(Arena *arena, LNK_SymbolTable *symtab, LNK_ObjSy
|
|||||||
}
|
}
|
||||||
|
|
||||||
// unpack symbol
|
// unpack symbol
|
||||||
COFF_ParsedSymbol result_parsed = lnk_parsed_symbol_from_coff_symbol_idx(result.obj, result.symbol_idx);
|
COFF_ParsedSymbol result_parsed = lnk_parsed_symbol_from_coff_symbol_idx_no_name(result.obj, result.symbol_idx);
|
||||||
COFF_SymbolValueInterpType result_interp = coff_interp_from_parsed_symbol(result_parsed);
|
COFF_SymbolValueInterpType result_interp = coff_interp_from_parsed_symbol(result_parsed);
|
||||||
|
|
||||||
// resolve symbol
|
// resolve symbol
|
||||||
@@ -2803,7 +2803,7 @@ THREAD_POOL_TASK_FUNC(lnk_opt_ref_task)
|
|||||||
if (ref_symbol.obj == 0) { continue; }
|
if (ref_symbol.obj == 0) { continue; }
|
||||||
|
|
||||||
// unpack resolved symbol
|
// unpack resolved symbol
|
||||||
COFF_ParsedSymbol ref_parsed = lnk_parsed_symbol_from_coff_symbol_idx(ref_symbol.obj, ref_symbol.symbol_idx);
|
COFF_ParsedSymbol ref_parsed = lnk_parsed_symbol_from_coff_symbol_idx_no_name(ref_symbol.obj, ref_symbol.symbol_idx);
|
||||||
COFF_SymbolValueInterpType ref_interp = coff_interp_from_parsed_symbol(ref_parsed);
|
COFF_SymbolValueInterpType ref_interp = coff_interp_from_parsed_symbol(ref_parsed);
|
||||||
|
|
||||||
if (ref_interp == COFF_SymbolValueInterp_Regular) {
|
if (ref_interp == COFF_SymbolValueInterp_Regular) {
|
||||||
@@ -3018,8 +3018,8 @@ lnk_icf_color_space_from_section(LNK_Obj *obj, U32 sect_idx)
|
|||||||
// fold MSVC vftables separately from other read-only data
|
// fold MSVC vftables separately from other read-only data
|
||||||
LNK_ObjSymbolRef symlink_ref = {0};
|
LNK_ObjSymbolRef symlink_ref = {0};
|
||||||
if (lnk_obj_get_comdat_symlink(obj, sect_idx + 1, &symlink_ref)) {
|
if (lnk_obj_get_comdat_symlink(obj, sect_idx + 1, &symlink_ref)) {
|
||||||
COFF_ParsedSymbol symlink_symbol = lnk_parsed_symbol_from_coff_symbol_idx(symlink_ref.obj, symlink_ref.symbol_idx);
|
String8 symlink_name = lnk_symbol_name_from_coff_symbol_idx(symlink_ref.obj, symlink_ref.symbol_idx);
|
||||||
if (str8_starts_with(symlink_symbol.name, str8_lit(MSCRT_VFTABLE_SYMBOL_PREFIX))) {
|
if (str8_starts_with(symlink_name, str8_lit(MSCRT_VFTABLE_SYMBOL_PREFIX))) {
|
||||||
result = LNK_ICF_ColorSpace_VFTable;
|
result = LNK_ICF_ColorSpace_VFTable;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -3126,12 +3126,12 @@ THREAD_POOL_TASK_FUNC(lnk_opt_icf_task)
|
|||||||
LNK_ObjSymbolRef target_ref = { .obj = obj, .symbol_idx = symbol_idx };
|
LNK_ObjSymbolRef target_ref = { .obj = obj, .symbol_idx = symbol_idx };
|
||||||
B32 is_symbol_found = lnk_resolve_reloc_target_symbol(scratch.arena, task->symtab, target_ref, str8_lit("/OPT:ICF"), &target_ref);
|
B32 is_symbol_found = lnk_resolve_reloc_target_symbol(scratch.arena, task->symtab, target_ref, str8_lit("/OPT:ICF"), &target_ref);
|
||||||
if (is_symbol_found) {
|
if (is_symbol_found) {
|
||||||
COFF_ParsedSymbol symbol = lnk_parsed_symbol_from_coff_symbol_idx(target_ref.obj, target_ref.symbol_idx);
|
COFF_ParsedSymbol symbol = lnk_parsed_symbol_from_coff_symbol_idx_no_name(target_ref.obj, target_ref.symbol_idx);
|
||||||
if (coff_interp_from_parsed_symbol(symbol) == COFF_SymbolValueInterp_Regular) {
|
if (coff_interp_from_parsed_symbol(symbol) == COFF_SymbolValueInterp_Regular) {
|
||||||
target_ref.obj->section_flags[symbol.section_number - 1] |= LNK_SECTION_FLAG_NOICF;
|
target_ref.obj->section_flags[symbol.section_number - 1] |= LNK_SECTION_FLAG_NOICF;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
COFF_ParsedSymbol original_symbol = lnk_parsed_symbol_from_coff_symbol_idx(obj, symbol_idx);
|
COFF_ParsedSymbol original_symbol = lnk_parsed_symbol_from_coff_symbol_idx_no_name(obj, symbol_idx);
|
||||||
if (coff_interp_from_parsed_symbol(original_symbol) == COFF_SymbolValueInterp_Regular) {
|
if (coff_interp_from_parsed_symbol(original_symbol) == COFF_SymbolValueInterp_Regular) {
|
||||||
obj->section_flags[original_symbol.section_number - 1] |= LNK_SECTION_FLAG_NOICF;
|
obj->section_flags[original_symbol.section_number - 1] |= LNK_SECTION_FLAG_NOICF;
|
||||||
} else {
|
} else {
|
||||||
@@ -3283,7 +3283,7 @@ THREAD_POOL_TASK_FUNC(lnk_opt_icf_task)
|
|||||||
LNK_ObjSymbolRef target_ref = { .obj = obj, .symbol_idx = r->isymbol };
|
LNK_ObjSymbolRef target_ref = { .obj = obj, .symbol_idx = r->isymbol };
|
||||||
B32 is_symbol_found = lnk_resolve_reloc_target_symbol(scratch2.arena, task->symtab, target_ref, str8_lit("/OPT:ICF"), &target_ref);
|
B32 is_symbol_found = lnk_resolve_reloc_target_symbol(scratch2.arena, task->symtab, target_ref, str8_lit("/OPT:ICF"), &target_ref);
|
||||||
if (is_symbol_found) {
|
if (is_symbol_found) {
|
||||||
COFF_ParsedSymbol target_symbol = lnk_parsed_symbol_from_coff_symbol_idx(target_ref.obj, target_ref.symbol_idx);
|
COFF_ParsedSymbol target_symbol = lnk_parsed_symbol_from_coff_symbol_idx_no_name(target_ref.obj, target_ref.symbol_idx);
|
||||||
target->interp = coff_interp_from_parsed_symbol(target_symbol);
|
target->interp = coff_interp_from_parsed_symbol(target_symbol);
|
||||||
target->value = target_symbol.value;
|
target->value = target_symbol.value;
|
||||||
|
|
||||||
@@ -3297,7 +3297,7 @@ THREAD_POOL_TASK_FUNC(lnk_opt_icf_task)
|
|||||||
target_obj->section_flags[target_sect - 1] & COFF_SectionFlag_LnkCOMDAT) {
|
target_obj->section_flags[target_sect - 1] & COFF_SectionFlag_LnkCOMDAT) {
|
||||||
LNK_ObjSymbolRef leader_ref = {0};
|
LNK_ObjSymbolRef leader_ref = {0};
|
||||||
if (lnk_obj_get_comdat_symlink(target_obj, target_sect, &leader_ref)) {
|
if (lnk_obj_get_comdat_symlink(target_obj, target_sect, &leader_ref)) {
|
||||||
COFF_ParsedSymbol leader_symbol = lnk_parsed_symbol_from_coff_symbol_idx(leader_ref.obj, leader_ref.symbol_idx);
|
COFF_ParsedSymbol leader_symbol = lnk_parsed_symbol_from_coff_symbol_idx_no_name(leader_ref.obj, leader_ref.symbol_idx);
|
||||||
if (leader_symbol.section_number != 0 && leader_symbol.section_number <= leader_ref.obj->header.section_count_no_null) {
|
if (leader_symbol.section_number != 0 && leader_symbol.section_number <= leader_ref.obj->header.section_count_no_null) {
|
||||||
target_obj = leader_ref.obj;
|
target_obj = leader_ref.obj;
|
||||||
target_sect = leader_symbol.section_number;
|
target_sect = leader_symbol.section_number;
|
||||||
@@ -3650,7 +3650,7 @@ THREAD_POOL_TASK_FUNC(lnk_opt_icf_task)
|
|||||||
U64 hop_count = 0;
|
U64 hop_count = 0;
|
||||||
U64 hop_cap = 1024;
|
U64 hop_cap = 1024;
|
||||||
for(; hop_count < hop_cap; hop_count += 1) {
|
for(; hop_count < hop_cap; hop_count += 1) {
|
||||||
COFF_ParsedSymbol symlink_parsed = lnk_parsed_symbol_from_coff_symbol_idx(symlink_ref.obj, symlink_ref.symbol_idx);
|
COFF_ParsedSymbol symlink_parsed = lnk_parsed_symbol_from_coff_symbol_idx_no_name(symlink_ref.obj, symlink_ref.symbol_idx);
|
||||||
LNK_ObjSymbolRef next_symlink_ref = {0};
|
LNK_ObjSymbolRef next_symlink_ref = {0};
|
||||||
if (!lnk_obj_get_comdat_symlink(symlink_ref.obj, symlink_parsed.section_number, &next_symlink_ref)) { break; }
|
if (!lnk_obj_get_comdat_symlink(symlink_ref.obj, symlink_parsed.section_number, &next_symlink_ref)) { break; }
|
||||||
if (MemoryMatchStruct(&next_symlink_ref, &symlink_ref)) { break; }
|
if (MemoryMatchStruct(&next_symlink_ref, &symlink_ref)) { break; }
|
||||||
@@ -3944,7 +3944,7 @@ THREAD_POOL_TASK_FUNC(lnk_set_comdat_leaders_contribs_task)
|
|||||||
LNK_ObjSymbolRef symlink_ref = {0};
|
LNK_ObjSymbolRef symlink_ref = {0};
|
||||||
if ( ! lnk_obj_get_comdat_symlink(obj, section_number, &symlink_ref)) { continue; }
|
if ( ! lnk_obj_get_comdat_symlink(obj, section_number, &symlink_ref)) { continue; }
|
||||||
|
|
||||||
COFF_ParsedSymbol symlink_parsed = lnk_parsed_symbol_from_coff_symbol_idx(symlink_ref.obj, symlink_ref.symbol_idx);
|
COFF_ParsedSymbol symlink_parsed = lnk_parsed_symbol_from_coff_symbol_idx_no_name(symlink_ref.obj, symlink_ref.symbol_idx);
|
||||||
task->sect_map[obj_idx][sect_idx] = task->sect_map[symlink_ref.obj->input_idx][symlink_parsed.section_number - 1];
|
task->sect_map[obj_idx][sect_idx] = task->sect_map[symlink_ref.obj->input_idx][symlink_parsed.section_number - 1];
|
||||||
}
|
}
|
||||||
ProfEnd();
|
ProfEnd();
|
||||||
@@ -3959,7 +3959,7 @@ THREAD_POOL_TASK_FUNC(lnk_flag_debug_symbols_task)
|
|||||||
|
|
||||||
COFF_ParsedSymbol symbol;
|
COFF_ParsedSymbol symbol;
|
||||||
for (U64 symbol_idx = 0; symbol_idx < obj->header.symbol_count; symbol_idx += (1 + symbol.aux_symbol_count)) {
|
for (U64 symbol_idx = 0; symbol_idx < obj->header.symbol_count; symbol_idx += (1 + symbol.aux_symbol_count)) {
|
||||||
symbol = lnk_parsed_symbol_from_coff_symbol_idx(obj, symbol_idx);
|
symbol = lnk_parsed_symbol_from_coff_symbol_idx_no_name(obj, symbol_idx);
|
||||||
COFF_SymbolValueInterpType interp = coff_interp_symbol(symbol.section_number, symbol.value, symbol.storage_class);
|
COFF_SymbolValueInterpType interp = coff_interp_symbol(symbol.section_number, symbol.value, symbol.storage_class);
|
||||||
if (interp == COFF_SymbolValueInterp_Regular) {
|
if (interp == COFF_SymbolValueInterp_Regular) {
|
||||||
if (obj->section_flags[symbol.section_number-1] & LNK_SECTION_FLAG_DEBUG) {
|
if (obj->section_flags[symbol.section_number-1] & LNK_SECTION_FLAG_DEBUG) {
|
||||||
@@ -3979,7 +3979,7 @@ THREAD_POOL_TASK_FUNC(lnk_patch_comdat_leaders_task)
|
|||||||
ProfBeginV("Patch COMDAT Offsets in %S", obj->path);
|
ProfBeginV("Patch COMDAT Offsets in %S", obj->path);
|
||||||
COFF_ParsedSymbol symbol;
|
COFF_ParsedSymbol symbol;
|
||||||
for (U64 symbol_idx = 0; symbol_idx < obj->header.symbol_count; symbol_idx += (1 + symbol.aux_symbol_count)) {
|
for (U64 symbol_idx = 0; symbol_idx < obj->header.symbol_count; symbol_idx += (1 + symbol.aux_symbol_count)) {
|
||||||
symbol = lnk_parsed_symbol_from_coff_symbol_idx(obj, symbol_idx);
|
symbol = lnk_parsed_symbol_from_coff_symbol_idx_no_name(obj, symbol_idx);
|
||||||
|
|
||||||
COFF_SymbolValueInterpType interp = coff_interp_from_parsed_symbol(symbol);
|
COFF_SymbolValueInterpType interp = coff_interp_from_parsed_symbol(symbol);
|
||||||
if (interp != COFF_SymbolValueInterp_Regular) { continue; }
|
if (interp != COFF_SymbolValueInterp_Regular) { continue; }
|
||||||
@@ -3987,7 +3987,7 @@ THREAD_POOL_TASK_FUNC(lnk_patch_comdat_leaders_task)
|
|||||||
LNK_ObjSymbolRef symlink_ref = {0};
|
LNK_ObjSymbolRef symlink_ref = {0};
|
||||||
if ( ! lnk_obj_get_comdat_symlink(obj, symbol.section_number, &symlink_ref)) { continue; }
|
if ( ! lnk_obj_get_comdat_symlink(obj, symbol.section_number, &symlink_ref)) { continue; }
|
||||||
|
|
||||||
COFF_ParsedSymbol leader_symbol = lnk_parsed_symbol_from_coff_symbol_idx(symlink_ref.obj, symlink_ref.symbol_idx);
|
COFF_ParsedSymbol leader_symbol = lnk_parsed_symbol_from_coff_symbol_idx_no_name(symlink_ref.obj, symlink_ref.symbol_idx);
|
||||||
if (symlink_ref.obj == obj && leader_symbol.section_number == symbol.section_number) { continue; }
|
if (symlink_ref.obj == obj && leader_symbol.section_number == symbol.section_number) { continue; }
|
||||||
|
|
||||||
B32 is_external = symbol.storage_class == COFF_SymStorageClass_External;
|
B32 is_external = symbol.storage_class == COFF_SymStorageClass_External;
|
||||||
@@ -4012,7 +4012,9 @@ THREAD_POOL_TASK_FUNC(lnk_patch_comdat_leaders_task)
|
|||||||
should_patch = 1;
|
should_patch = 1;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (is_external && str8_match(symbol.name, leader_symbol.name, 0)) {
|
String8 symbol_name = lnk_symbol_name_from_coff_symbol_idx(obj, symbol_idx);
|
||||||
|
String8 leader_name = lnk_symbol_name_from_coff_symbol_idx(symlink_ref.obj, symlink_ref.symbol_idx);
|
||||||
|
if (is_external && str8_match(symbol_name, leader_name, 0)) {
|
||||||
value = leader_symbol.value;
|
value = leader_symbol.value;
|
||||||
should_patch = 1;
|
should_patch = 1;
|
||||||
}
|
}
|
||||||
@@ -4111,10 +4113,10 @@ THREAD_POOL_TASK_FUNC(lnk_patch_common_block_symbols_task)
|
|||||||
ProfBeginV("Patch Common Block Symbols [%S]", obj->path);
|
ProfBeginV("Patch Common Block Symbols [%S]", obj->path);
|
||||||
COFF_ParsedSymbol symbol;
|
COFF_ParsedSymbol symbol;
|
||||||
for (U64 symbol_idx = 0; symbol_idx < obj->header.symbol_count; symbol_idx += (1 + symbol.aux_symbol_count)) {
|
for (U64 symbol_idx = 0; symbol_idx < obj->header.symbol_count; symbol_idx += (1 + symbol.aux_symbol_count)) {
|
||||||
symbol = lnk_parsed_symbol_from_coff_symbol_idx(obj, symbol_idx);
|
symbol = lnk_parsed_symbol_from_coff_symbol_idx_no_name(obj, symbol_idx);
|
||||||
COFF_SymbolValueInterpType interp = coff_interp_symbol(symbol.section_number, symbol.value, symbol.storage_class);
|
COFF_SymbolValueInterpType interp = coff_interp_symbol(symbol.section_number, symbol.value, symbol.storage_class);
|
||||||
if (interp == COFF_SymbolValueInterp_Common) {
|
if (interp == COFF_SymbolValueInterp_Common) {
|
||||||
LNK_Symbol *defn = lnk_symbol_table_search(task->symtab, symbol.name);
|
LNK_Symbol *defn = lnk_symbol_table_search(task->symtab, lnk_symbol_name_from_coff_symbol_idx(obj, symbol_idx));
|
||||||
COFF_ParsedSymbol defn_parsed = lnk_parsed_from_symbol(defn);
|
COFF_ParsedSymbol defn_parsed = lnk_parsed_from_symbol(defn);
|
||||||
Assert(lnk_interp_from_symbol(defn) == COFF_SymbolValueInterp_Regular);
|
Assert(lnk_interp_from_symbol(defn) == COFF_SymbolValueInterp_Regular);
|
||||||
if (defn) {
|
if (defn) {
|
||||||
@@ -4145,7 +4147,7 @@ THREAD_POOL_TASK_FUNC(lnk_patch_regular_symbols_task)
|
|||||||
ProfBeginV("Patch Regular Symbols [%S]", obj->path);
|
ProfBeginV("Patch Regular Symbols [%S]", obj->path);
|
||||||
COFF_ParsedSymbol symbol;
|
COFF_ParsedSymbol symbol;
|
||||||
for (U64 symbol_idx = 0; symbol_idx < obj->header.symbol_count; symbol_idx += (1 + symbol.aux_symbol_count)) {
|
for (U64 symbol_idx = 0; symbol_idx < obj->header.symbol_count; symbol_idx += (1 + symbol.aux_symbol_count)) {
|
||||||
symbol = lnk_parsed_symbol_from_coff_symbol_idx(obj, symbol_idx);
|
symbol = lnk_parsed_symbol_from_coff_symbol_idx_no_name(obj, symbol_idx);
|
||||||
|
|
||||||
if (task->u.patch_symtabs.was_symbol_patched[obj_idx][symbol_idx]) { continue; }
|
if (task->u.patch_symtabs.was_symbol_patched[obj_idx][symbol_idx]) { continue; }
|
||||||
|
|
||||||
@@ -4183,7 +4185,7 @@ lnk_patch_obj_symtab(LNK_SymbolTable *symtab, LNK_Obj *obj, B8 *was_symbol_patch
|
|||||||
|
|
||||||
COFF_ParsedSymbol fixup_dst;
|
COFF_ParsedSymbol fixup_dst;
|
||||||
for (U64 symbol_idx = 0; symbol_idx < obj->header.symbol_count; symbol_idx += (1 + fixup_dst.aux_symbol_count)) {
|
for (U64 symbol_idx = 0; symbol_idx < obj->header.symbol_count; symbol_idx += (1 + fixup_dst.aux_symbol_count)) {
|
||||||
fixup_dst = lnk_parsed_symbol_from_coff_symbol_idx(obj, symbol_idx);
|
fixup_dst = lnk_parsed_symbol_from_coff_symbol_idx_no_name(obj, symbol_idx);
|
||||||
if (was_symbol_patched[symbol_idx]) { continue; }
|
if (was_symbol_patched[symbol_idx]) { continue; }
|
||||||
|
|
||||||
COFF_SymbolValueInterpType fixup_dst_type = coff_interp_symbol(fixup_dst.section_number, fixup_dst.value, fixup_dst.storage_class);
|
COFF_SymbolValueInterpType fixup_dst_type = coff_interp_symbol(fixup_dst.section_number, fixup_dst.value, fixup_dst.storage_class);
|
||||||
@@ -4193,7 +4195,7 @@ lnk_patch_obj_symtab(LNK_SymbolTable *symtab, LNK_Obj *obj, B8 *was_symbol_patch
|
|||||||
LNK_ObjSymbolRef fixup_symbol = {0};
|
LNK_ObjSymbolRef fixup_symbol = {0};
|
||||||
B32 is_resolved = lnk_resolve_symbol(symtab, symbol_to_resolve, &fixup_symbol);
|
B32 is_resolved = lnk_resolve_symbol(symtab, symbol_to_resolve, &fixup_symbol);
|
||||||
if (is_resolved) {
|
if (is_resolved) {
|
||||||
COFF_ParsedSymbol fixup_src = lnk_parsed_symbol_from_coff_symbol_idx(fixup_symbol.obj, fixup_symbol.symbol_idx);
|
COFF_ParsedSymbol fixup_src = lnk_parsed_symbol_from_coff_symbol_idx_no_name(fixup_symbol.obj, fixup_symbol.symbol_idx);
|
||||||
COFF_SymbolValueInterpType fixup_type = coff_interp_symbol(fixup_src.section_number, fixup_src.value, fixup_src.storage_class);
|
COFF_SymbolValueInterpType fixup_type = coff_interp_symbol(fixup_src.section_number, fixup_src.value, fixup_src.storage_class);
|
||||||
B32 was_fixup_removed = fixup_src.section_number == lnk_obj_get_removed_section_number(fixup_symbol.obj);
|
B32 was_fixup_removed = fixup_src.section_number == lnk_obj_get_removed_section_number(fixup_symbol.obj);
|
||||||
|
|
||||||
@@ -4341,13 +4343,14 @@ THREAD_POOL_TASK_FUNC(lnk_obj_reloc_patcher)
|
|||||||
U32 symbol_secoff = 0;
|
U32 symbol_secoff = 0;
|
||||||
S64 symbol_voff = 0;
|
S64 symbol_voff = 0;
|
||||||
{
|
{
|
||||||
COFF_ParsedSymbol symbol = lnk_parsed_symbol_from_coff_symbol_idx(obj, reloc->isymbol);
|
COFF_ParsedSymbol symbol = lnk_parsed_symbol_from_coff_symbol_idx_no_name(obj, reloc->isymbol);
|
||||||
COFF_SymbolValueInterpType interp = coff_interp_from_parsed_symbol(symbol);
|
COFF_SymbolValueInterpType interp = coff_interp_from_parsed_symbol(symbol);
|
||||||
if (interp == COFF_SymbolValueInterp_Regular) {
|
if (interp == COFF_SymbolValueInterp_Regular) {
|
||||||
if (symbol.section_number == lnk_obj_get_removed_section_number(obj)) {
|
if (symbol.section_number == lnk_obj_get_removed_section_number(obj)) {
|
||||||
if (~section_flags & LNK_SECTION_FLAG_DEBUG) {
|
if (~section_flags & LNK_SECTION_FLAG_DEBUG) {
|
||||||
String8 sect_name = coff_name_from_section_header(string_table, §ion_table[sect_idx]);
|
String8 sect_name = coff_name_from_section_header(string_table, §ion_table[sect_idx]);
|
||||||
lnk_error_obj(LNK_Error_RelocationAgainstRemovedSection, obj, "relocating against symbol that is in a removed section (symbol: %S, reloc-section: %S 0x%llx, reloc-index: 0x%llx)", symbol.name, sect_name, sect_idx+1, reloc_idx);
|
String8 symbol_name = lnk_symbol_name_from_coff_symbol_idx(obj, reloc->isymbol);
|
||||||
|
lnk_error_obj(LNK_Error_RelocationAgainstRemovedSection, obj, "relocating against symbol that is in a removed section (symbol: %S, reloc-section: %S 0x%llx, reloc-index: 0x%llx)", symbol_name, sect_name, sect_idx+1, reloc_idx);
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -4358,7 +4361,7 @@ THREAD_POOL_TASK_FUNC(lnk_obj_reloc_patcher)
|
|||||||
// There aren't enough bits in COFF symbol to store full image base address,
|
// There aren't enough bits in COFF symbol to store full image base address,
|
||||||
// so we special case __ImageBase. A better solution would be to add
|
// so we special case __ImageBase. A better solution would be to add
|
||||||
// a 64-bit symbol format to COFF.
|
// a 64-bit symbol format to COFF.
|
||||||
if (str8_match(symbol.name, str8_lit("__ImageBase"), 0)) {
|
if (str8_match(lnk_symbol_name_from_coff_symbol_idx(obj, reloc->isymbol), str8_lit("__ImageBase"), 0)) {
|
||||||
symbol.value = task->image_base;
|
symbol.value = task->image_base;
|
||||||
}
|
}
|
||||||
symbol_secnum = 0;
|
symbol_secnum = 0;
|
||||||
@@ -4447,7 +4450,7 @@ THREAD_POOL_TASK_FUNC(lnk_flag_hotpatch_contribs_task)
|
|||||||
if (obj->hotpatch) {
|
if (obj->hotpatch) {
|
||||||
COFF_ParsedSymbol symbol;
|
COFF_ParsedSymbol symbol;
|
||||||
for (U64 symbol_idx = 0; symbol_idx < obj->header.symbol_count; symbol_idx += (1 + symbol.aux_symbol_count)) {
|
for (U64 symbol_idx = 0; symbol_idx < obj->header.symbol_count; symbol_idx += (1 + symbol.aux_symbol_count)) {
|
||||||
symbol = lnk_parsed_symbol_from_coff_symbol_idx(obj, symbol_idx);
|
symbol = lnk_parsed_symbol_from_coff_symbol_idx_no_name(obj, symbol_idx);
|
||||||
COFF_SymbolValueInterpType interp = coff_interp_symbol(symbol.section_number, symbol.value, symbol.storage_class);
|
COFF_SymbolValueInterpType interp = coff_interp_symbol(symbol.section_number, symbol.value, symbol.storage_class);
|
||||||
if (interp == COFF_SymbolValueInterp_Regular && COFF_SymbolType_IsFunc(symbol.type)) {
|
if (interp == COFF_SymbolValueInterp_Regular && COFF_SymbolType_IsFunc(symbol.type)) {
|
||||||
LNK_SectionContrib *sc = task->sect_map[obj_idx][symbol.section_number-1];
|
LNK_SectionContrib *sc = task->sect_map[obj_idx][symbol.section_number-1];
|
||||||
@@ -4862,7 +4865,7 @@ THREAD_POOL_TASK_FUNC(lnk_patch_section_symbols_task)
|
|||||||
ProfBegin("Patch Section Symbols [%S]", obj->path);
|
ProfBegin("Patch Section Symbols [%S]", obj->path);
|
||||||
COFF_ParsedSymbol symbol;
|
COFF_ParsedSymbol symbol;
|
||||||
for (U64 symbol_idx = 0; symbol_idx < obj->header.symbol_count; symbol_idx += (1 + symbol.aux_symbol_count)) {
|
for (U64 symbol_idx = 0; symbol_idx < obj->header.symbol_count; symbol_idx += (1 + symbol.aux_symbol_count)) {
|
||||||
symbol = lnk_parsed_symbol_from_coff_symbol_idx(obj, symbol_idx);
|
symbol = lnk_parsed_symbol_from_coff_symbol_idx_no_name(obj, symbol_idx);
|
||||||
COFF_SymbolValueInterpType interp = coff_interp_symbol(symbol.section_number, symbol.value, symbol.storage_class);
|
COFF_SymbolValueInterpType interp = coff_interp_symbol(symbol.section_number, symbol.value, symbol.storage_class);
|
||||||
if (interp == COFF_SymbolValueInterp_Undefined) {
|
if (interp == COFF_SymbolValueInterp_Undefined) {
|
||||||
if (symbol.storage_class == COFF_SymStorageClass_Section) {
|
if (symbol.storage_class == COFF_SymStorageClass_Section) {
|
||||||
@@ -4885,7 +4888,8 @@ THREAD_POOL_TASK_FUNC(lnk_patch_section_symbols_task)
|
|||||||
}
|
}
|
||||||
if (!is_referenced) { continue; }
|
if (!is_referenced) { continue; }
|
||||||
|
|
||||||
LNK_Section *sect = lnk_section_table_search(task->sectab, symbol.name, symbol.value);
|
String8 symbol_name = lnk_symbol_name_from_coff_symbol_idx(obj, symbol_idx);
|
||||||
|
LNK_Section *sect = lnk_section_table_search(task->sectab, symbol_name, symbol.value);
|
||||||
if (sect && (~sect->flags & COFF_SectionFlag_LnkRemove)) {
|
if (sect && (~sect->flags & COFF_SectionFlag_LnkRemove)) {
|
||||||
if (~sect->flags & COFF_SectionFlag_MemDiscardable) {
|
if (~sect->flags & COFF_SectionFlag_MemDiscardable) {
|
||||||
LNK_SectionContrib *first_sc = lnk_get_first_section_contrib(sect);
|
LNK_SectionContrib *first_sc = lnk_get_first_section_contrib(sect);
|
||||||
@@ -4901,7 +4905,7 @@ THREAD_POOL_TASK_FUNC(lnk_patch_section_symbols_task)
|
|||||||
symbol16->storage_class = COFF_SymStorageClass_Static;
|
symbol16->storage_class = COFF_SymStorageClass_Static;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
lnk_error_obj(LNK_Error_SectRefsDiscardedMemory, obj, "symbol %S (No. 0x%llx) references section with discard flag", symbol.name, symbol_idx);
|
lnk_error_obj(LNK_Error_SectRefsDiscardedMemory, obj, "symbol %S (No. 0x%llx) references section with discard flag", symbol_name, symbol_idx);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
U64 fallback_voff = 0;
|
U64 fallback_voff = 0;
|
||||||
@@ -4929,7 +4933,7 @@ THREAD_POOL_TASK_FUNC(lnk_patch_section_symbols_task)
|
|||||||
symbol16->storage_class = COFF_SymStorageClass_Static;
|
symbol16->storage_class = COFF_SymStorageClass_Static;
|
||||||
}
|
}
|
||||||
|
|
||||||
lnk_error_obj(LNK_Warning_UndefinedSectionSymbol, obj, "undefined section symbol %S (No. 0x%llx) refers to an image section that doesn't exist; patching to %#llx", symbol.name, symbol_idx, fallback_voff);
|
lnk_error_obj(LNK_Warning_UndefinedSectionSymbol, obj, "undefined section symbol %S (No. 0x%llx) refers to an image section that doesn't exist; patching to %#llx", symbol_name, symbol_idx, fallback_voff);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -4955,7 +4959,7 @@ THREAD_POOL_TASK_FUNC(lnk_gather_base_reloc_pages_task)
|
|||||||
for EachIndex(reloc_idx, relocs.count) {
|
for EachIndex(reloc_idx, relocs.count) {
|
||||||
COFF_Reloc *r = &relocs.v[reloc_idx];
|
COFF_Reloc *r = &relocs.v[reloc_idx];
|
||||||
|
|
||||||
COFF_ParsedSymbol symbol = lnk_parsed_symbol_from_coff_symbol_idx(obj, r->isymbol);
|
COFF_ParsedSymbol symbol = lnk_parsed_symbol_from_coff_symbol_idx_no_name(obj, r->isymbol);
|
||||||
COFF_SymbolValueInterpType symbol_interp = coff_interp_from_parsed_symbol(symbol);
|
COFF_SymbolValueInterpType symbol_interp = coff_interp_from_parsed_symbol(symbol);
|
||||||
if (symbol_interp == COFF_SymbolValueInterp_Abs) { continue; }
|
if (symbol_interp == COFF_SymbolValueInterp_Abs) { continue; }
|
||||||
|
|
||||||
@@ -4983,7 +4987,7 @@ THREAD_POOL_TASK_FUNC(lnk_gather_base_reloc_pages_task)
|
|||||||
switch (is_addr) {
|
switch (is_addr) {
|
||||||
case 4: {
|
case 4: {
|
||||||
if (task->is_large_addr_aware) {
|
if (task->is_large_addr_aware) {
|
||||||
lnk_error_obj(LNK_Error_LargeAddrAwareRequired, obj, "found out of range ADDR32 relocation for '%S', link with /LARGEADDRESSAWARE:NO", symbol.name);
|
lnk_error_obj(LNK_Error_LargeAddrAwareRequired, obj, "found out of range ADDR32 relocation for '%S', link with /LARGEADDRESSAWARE:NO", lnk_symbol_name_from_coff_symbol_idx(obj, r->isymbol));
|
||||||
} else {
|
} else {
|
||||||
u64_list_push(arena, page->v.entries_addr32, reloc_voff);
|
u64_list_push(arena, page->v.entries_addr32, reloc_voff);
|
||||||
}
|
}
|
||||||
|
|||||||
+77
-27
@@ -125,13 +125,38 @@ THREAD_POOL_TASK_FUNC(lnk_obj_initer)
|
|||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// error check symbol table
|
// error check symbol table and cache name lengths for primary symbols
|
||||||
//
|
//
|
||||||
|
U64 primary_symbol_count = 0;
|
||||||
|
{
|
||||||
|
COFF_ParsedSymbol symbol;
|
||||||
|
for (U64 symbol_idx = 0; symbol_idx < header.symbol_count; symbol_idx += 1 + symbol.aux_symbol_count) {
|
||||||
|
symbol = coff_parse_symbol_no_name(header, raw_coff_symbol_table, symbol_idx);
|
||||||
|
primary_symbol_count += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
U64 name_block_count = CeilIntegerDiv(header.symbol_count, 64);
|
||||||
|
LNK_SymbolNameCache symbol_name_cache = {
|
||||||
|
.masks = push_array(arena, U64, name_block_count),
|
||||||
|
.block_bases = push_array_no_zero(arena, U32, name_block_count),
|
||||||
|
.name_sizes = push_array_no_zero(arena, U32, primary_symbol_count),
|
||||||
|
};
|
||||||
{
|
{
|
||||||
COFF_SectionHeader *section_table = (COFF_SectionHeader *)str8_substr(input->data, header.section_table_range).str;
|
COFF_SectionHeader *section_table = (COFF_SectionHeader *)str8_substr(input->data, header.section_table_range).str;
|
||||||
|
U64 next_block = 0;
|
||||||
|
U32 name_count = 0;
|
||||||
COFF_ParsedSymbol symbol;
|
COFF_ParsedSymbol symbol;
|
||||||
for (U64 symbol_idx = 0; symbol_idx < header.symbol_count; symbol_idx += (1 + symbol.aux_symbol_count)) {
|
for (U64 symbol_idx = 0; symbol_idx < header.symbol_count; symbol_idx += (1 + symbol.aux_symbol_count)) {
|
||||||
symbol = coff_parse_symbol(header, raw_coff_string_table, raw_coff_symbol_table, symbol_idx);
|
symbol = coff_parse_symbol(header, raw_coff_string_table, raw_coff_symbol_table, symbol_idx);
|
||||||
|
U64 block_idx = symbol_idx >> 6;
|
||||||
|
while (next_block <= block_idx) {
|
||||||
|
symbol_name_cache.block_bases[next_block++] = name_count;
|
||||||
|
}
|
||||||
|
if (symbol.name.size) {
|
||||||
|
symbol_name_cache.masks[block_idx] |= 1ull << (symbol_idx & 63);
|
||||||
|
symbol_name_cache.name_sizes[name_count++] = safe_cast_u32(symbol.name.size);
|
||||||
|
}
|
||||||
COFF_SymbolValueInterpType interp = coff_interp_symbol(symbol.section_number, symbol.value, symbol.storage_class);
|
COFF_SymbolValueInterpType interp = coff_interp_symbol(symbol.section_number, symbol.value, symbol.storage_class);
|
||||||
if (interp == COFF_SymbolValueInterp_Regular) {
|
if (interp == COFF_SymbolValueInterp_Regular) {
|
||||||
if (symbol.section_number == 0 || symbol.section_number > header.section_count_no_null) {
|
if (symbol.section_number == 0 || symbol.section_number > header.section_count_no_null) {
|
||||||
@@ -149,6 +174,9 @@ THREAD_POOL_TASK_FUNC(lnk_obj_initer)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
while (next_block < name_block_count) {
|
||||||
|
symbol_name_cache.block_bases[next_block++] = name_count;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
@@ -161,7 +189,7 @@ THREAD_POOL_TASK_FUNC(lnk_obj_initer)
|
|||||||
|
|
||||||
COFF_ParsedSymbol symbol;
|
COFF_ParsedSymbol symbol;
|
||||||
for (U64 symbol_idx = 0; symbol_idx < header.symbol_count; symbol_idx += (1 + symbol.aux_symbol_count)) {
|
for (U64 symbol_idx = 0; symbol_idx < header.symbol_count; symbol_idx += (1 + symbol.aux_symbol_count)) {
|
||||||
symbol = coff_parse_symbol(header, raw_coff_string_table, raw_coff_symbol_table, symbol_idx);
|
symbol = coff_parse_symbol_no_name(header, raw_coff_symbol_table, symbol_idx);
|
||||||
|
|
||||||
COFF_SymbolValueInterpType interp = coff_interp_symbol(symbol.section_number, symbol.value, symbol.storage_class);
|
COFF_SymbolValueInterpType interp = coff_interp_symbol(symbol.section_number, symbol.value, symbol.storage_class);
|
||||||
if (interp == COFF_SymbolValueInterp_Regular) {
|
if (interp == COFF_SymbolValueInterp_Regular) {
|
||||||
@@ -208,7 +236,7 @@ THREAD_POOL_TASK_FUNC(lnk_obj_initer)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// extract COMDAT info for current section
|
// extract COMDAT info for current section
|
||||||
COFF_ParsedSymbol symbol = coff_parse_symbol(header, raw_coff_string_table, raw_coff_symbol_table, symbol_idx);
|
COFF_ParsedSymbol symbol = coff_parse_symbol_no_name(header, raw_coff_symbol_table, symbol_idx);
|
||||||
COFF_ComdatSelectType select = COFF_ComdatSelect_Null;
|
COFF_ComdatSelectType select = COFF_ComdatSelect_Null;
|
||||||
U32 section_number = 0;
|
U32 section_number = 0;
|
||||||
coff_parse_secdef(symbol, header.is_big_obj, &select, §ion_number, 0, 0);
|
coff_parse_secdef(symbol, header.is_big_obj, &select, §ion_number, 0, 0);
|
||||||
@@ -247,7 +275,7 @@ THREAD_POOL_TASK_FUNC(lnk_obj_initer)
|
|||||||
{
|
{
|
||||||
COFF_ParsedSymbol symbol;
|
COFF_ParsedSymbol symbol;
|
||||||
for (U32 symbol_idx = 0; symbol_idx < header.symbol_count; symbol_idx += (1 + symbol.aux_symbol_count)) {
|
for (U32 symbol_idx = 0; symbol_idx < header.symbol_count; symbol_idx += (1 + symbol.aux_symbol_count)) {
|
||||||
symbol = coff_parse_symbol(header, raw_coff_string_table, raw_coff_symbol_table, symbol_idx);
|
symbol = coff_parse_symbol_no_name(header, raw_coff_symbol_table, symbol_idx);
|
||||||
COFF_SymbolValueInterpType interp = coff_interp_from_parsed_symbol(symbol);
|
COFF_SymbolValueInterpType interp = coff_interp_from_parsed_symbol(symbol);
|
||||||
if (interp == COFF_SymbolValueInterp_Regular && symbol.storage_class == COFF_SymStorageClass_Static && symbol.aux_symbol_count > 0) {
|
if (interp == COFF_SymbolValueInterp_Regular && symbol.storage_class == COFF_SymStorageClass_Static && symbol.aux_symbol_count > 0) {
|
||||||
COFF_ComdatSelectType selection = COFF_ComdatSelect_Null;
|
COFF_ComdatSelectType selection = COFF_ComdatSelect_Null;
|
||||||
@@ -335,6 +363,7 @@ THREAD_POOL_TASK_FUNC(lnk_obj_initer)
|
|||||||
obj->path = push_str8_copy(arena, input->path);
|
obj->path = push_str8_copy(arena, input->path);
|
||||||
obj->header = header;
|
obj->header = header;
|
||||||
obj->section_flags = section_flags;
|
obj->section_flags = section_flags;
|
||||||
|
obj->symbol_name_cache = symbol_name_cache;
|
||||||
obj->comdats = comdats;
|
obj->comdats = comdats;
|
||||||
obj->exclude_from_debug_info = input->exclude_from_debug_info;
|
obj->exclude_from_debug_info = input->exclude_from_debug_info;
|
||||||
obj->hotpatch = hotpatch;
|
obj->hotpatch = hotpatch;
|
||||||
@@ -426,7 +455,7 @@ THREAD_POOL_TASK_FUNC(lnk_input_coff_symbol_table)
|
|||||||
LNK_Obj *obj = task->objs[task_id];
|
LNK_Obj *obj = task->objs[task_id];
|
||||||
COFF_ParsedSymbol symbol = {0};
|
COFF_ParsedSymbol symbol = {0};
|
||||||
for (U64 symbol_idx = 0; symbol_idx < obj->header.symbol_count; symbol_idx += (1 + symbol.aux_symbol_count)) {
|
for (U64 symbol_idx = 0; symbol_idx < obj->header.symbol_count; symbol_idx += (1 + symbol.aux_symbol_count)) {
|
||||||
symbol = lnk_parsed_symbol_from_coff_symbol_idx(obj, symbol_idx);
|
symbol = lnk_parsed_symbol_from_coff_symbol_idx_no_name(obj, symbol_idx);
|
||||||
COFF_SymbolValueInterpType interp = coff_interp_from_parsed_symbol(symbol);
|
COFF_SymbolValueInterpType interp = coff_interp_from_parsed_symbol(symbol);
|
||||||
switch (interp) {
|
switch (interp) {
|
||||||
case COFF_SymbolValueInterp_Regular: {
|
case COFF_SymbolValueInterp_Regular: {
|
||||||
@@ -435,27 +464,27 @@ THREAD_POOL_TASK_FUNC(lnk_input_coff_symbol_table)
|
|||||||
if (*section.flags & COFF_SectionFlag_LnkRemove) {
|
if (*section.flags & COFF_SectionFlag_LnkRemove) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
LNK_Symbol *defn = lnk_make_symbol(arena, symbol.name, obj, symbol_idx);
|
LNK_Symbol *defn = lnk_make_symbol(arena, lnk_symbol_name_from_coff_symbol_idx(obj, symbol_idx), obj, symbol_idx);
|
||||||
lnk_symbol_table_push_(task->symtab, arena, worker_id, defn);
|
lnk_symbol_table_push_(task->symtab, arena, worker_id, defn);
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
case COFF_SymbolValueInterp_Weak: {
|
case COFF_SymbolValueInterp_Weak: {
|
||||||
LNK_Symbol *defn = lnk_make_symbol(arena, symbol.name, obj, symbol_idx);
|
LNK_Symbol *defn = lnk_make_symbol(arena, lnk_symbol_name_from_coff_symbol_idx(obj, symbol_idx), obj, symbol_idx);
|
||||||
lnk_symbol_table_push_(task->symtab, arena, worker_id, defn);
|
lnk_symbol_table_push_(task->symtab, arena, worker_id, defn);
|
||||||
} break;
|
} break;
|
||||||
case COFF_SymbolValueInterp_Undefined: {
|
case COFF_SymbolValueInterp_Undefined: {
|
||||||
if (symbol.storage_class == COFF_SymStorageClass_External) {
|
if (symbol.storage_class == COFF_SymStorageClass_External) {
|
||||||
LNK_Symbol *defn = lnk_make_symbol(arena, symbol.name, obj, symbol_idx);
|
LNK_Symbol *defn = lnk_make_symbol(arena, lnk_symbol_name_from_coff_symbol_idx(obj, symbol_idx), obj, symbol_idx);
|
||||||
lnk_symbol_table_push_(task->symtab, arena, worker_id, defn);
|
lnk_symbol_table_push_(task->symtab, arena, worker_id, defn);
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
case COFF_SymbolValueInterp_Common: {
|
case COFF_SymbolValueInterp_Common: {
|
||||||
LNK_Symbol *defn = lnk_make_symbol(arena, symbol.name, obj, symbol_idx);
|
LNK_Symbol *defn = lnk_make_symbol(arena, lnk_symbol_name_from_coff_symbol_idx(obj, symbol_idx), obj, symbol_idx);
|
||||||
lnk_symbol_table_push_(task->symtab, arena, worker_id, defn);
|
lnk_symbol_table_push_(task->symtab, arena, worker_id, defn);
|
||||||
} break;
|
} break;
|
||||||
case COFF_SymbolValueInterp_Abs: {
|
case COFF_SymbolValueInterp_Abs: {
|
||||||
if (symbol.storage_class == COFF_SymStorageClass_External) {
|
if (symbol.storage_class == COFF_SymStorageClass_External) {
|
||||||
LNK_Symbol *defn = lnk_make_symbol(arena, symbol.name, obj, symbol_idx);
|
LNK_Symbol *defn = lnk_make_symbol(arena, lnk_symbol_name_from_coff_symbol_idx(obj, symbol_idx), obj, symbol_idx);
|
||||||
lnk_symbol_table_push_(task->symtab, arena, worker_id, defn);
|
lnk_symbol_table_push_(task->symtab, arena, worker_id, defn);
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
@@ -473,7 +502,7 @@ lnk_symlinks_from_obj(Arena *arena, LNK_SymbolTable *symtab, LNK_Obj *obj)
|
|||||||
LNK_ObjSymbolRef *symlinks = push_array(arena, LNK_ObjSymbolRef, obj->header.section_count_no_null + 1);
|
LNK_ObjSymbolRef *symlinks = push_array(arena, LNK_ObjSymbolRef, obj->header.section_count_no_null + 1);
|
||||||
COFF_ParsedSymbol symbol = {0};
|
COFF_ParsedSymbol symbol = {0};
|
||||||
for (U64 symbol_idx = 0; symbol_idx < obj->header.symbol_count; symbol_idx += (1 + symbol.aux_symbol_count)) {
|
for (U64 symbol_idx = 0; symbol_idx < obj->header.symbol_count; symbol_idx += (1 + symbol.aux_symbol_count)) {
|
||||||
symbol = lnk_parsed_symbol_from_coff_symbol_idx(obj, symbol_idx);
|
symbol = lnk_parsed_symbol_from_coff_symbol_idx_no_name(obj, symbol_idx);
|
||||||
COFF_SymbolValueInterpType interp = coff_interp_from_parsed_symbol(symbol);
|
COFF_SymbolValueInterpType interp = coff_interp_from_parsed_symbol(symbol);
|
||||||
if (interp != COFF_SymbolValueInterp_Regular) { continue; }
|
if (interp != COFF_SymbolValueInterp_Regular) { continue; }
|
||||||
|
|
||||||
@@ -484,13 +513,14 @@ lnk_symlinks_from_obj(Arena *arena, LNK_SymbolTable *symtab, LNK_Obj *obj)
|
|||||||
|
|
||||||
// external symbols
|
// external symbols
|
||||||
if (symbol.storage_class == COFF_SymStorageClass_External && symbol.aux_symbol_count == 0) {
|
if (symbol.storage_class == COFF_SymStorageClass_External && symbol.aux_symbol_count == 0) {
|
||||||
|
String8 symbol_name = lnk_symbol_name_from_coff_symbol_idx(obj, symbol_idx);
|
||||||
B32 can_set_symlink = (symlink->obj == 0 || symbol.value == 0);
|
B32 can_set_symlink = (symlink->obj == 0 || symbol.value == 0);
|
||||||
if (!can_set_symlink && symlink->obj == obj) {
|
if (!can_set_symlink && symlink->obj == obj) {
|
||||||
COFF_ParsedSymbol leader = lnk_parsed_symbol_from_coff_symbol_idx(symlink->obj, symlink->symbol_idx);
|
COFF_ParsedSymbol leader = lnk_parsed_symbol_from_coff_symbol_idx_no_name(symlink->obj, symlink->symbol_idx);
|
||||||
B32 leader_is_same_section = leader.section_number == symbol.section_number;
|
B32 leader_is_same_section = leader.section_number == symbol.section_number;
|
||||||
B32 leader_is_static_anchor = (leader_is_same_section && leader.storage_class == COFF_SymStorageClass_Static && leader.aux_symbol_count == 0);
|
B32 leader_is_static_anchor = (leader_is_same_section && leader.storage_class == COFF_SymStorageClass_Static && leader.aux_symbol_count == 0);
|
||||||
B32 leader_is_vftable = str8_starts_with(leader.name, str8_lit(MSCRT_VFTABLE_SYMBOL_PREFIX));
|
B32 leader_is_vftable = str8_starts_with(lnk_symbol_name_from_coff_symbol_idx(symlink->obj, symlink->symbol_idx), str8_lit(MSCRT_VFTABLE_SYMBOL_PREFIX));
|
||||||
B32 current_is_vftable = str8_starts_with(symbol.name, str8_lit(MSCRT_VFTABLE_SYMBOL_PREFIX));
|
B32 current_is_vftable = str8_starts_with(symbol_name, str8_lit(MSCRT_VFTABLE_SYMBOL_PREFIX));
|
||||||
|
|
||||||
// prefer public symbols to local static anchors; prefer vftable public
|
// prefer public symbols to local static anchors; prefer vftable public
|
||||||
// symbols to other public symbols so ICF keeps vftables in their own color space
|
// symbols to other public symbols so ICF keeps vftables in their own color space
|
||||||
@@ -498,7 +528,7 @@ lnk_symlinks_from_obj(Arena *arena, LNK_SymbolTable *symtab, LNK_Obj *obj)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (can_set_symlink) {
|
if (can_set_symlink) {
|
||||||
LNK_SymbolHashTrie *link_symbol = lnk_symbol_table_search_(symtab, symbol.name);
|
LNK_SymbolHashTrie *link_symbol = lnk_symbol_table_search_(symtab, symbol_name);
|
||||||
if (link_symbol) {
|
if (link_symbol) {
|
||||||
*symlink = lnk_ref_from_symbol(link_symbol->symbol);
|
*symlink = lnk_ref_from_symbol(link_symbol->symbol);
|
||||||
}
|
}
|
||||||
@@ -741,7 +771,7 @@ lnk_try_comdat_props_from_section_number(LNK_Obj *obj, U32 section_number, COFF_
|
|||||||
Assert(section_number > 0);
|
Assert(section_number > 0);
|
||||||
U32 symbol_idx = obj->comdats[section_number-1];
|
U32 symbol_idx = obj->comdats[section_number-1];
|
||||||
if (symbol_idx != max_U32) {
|
if (symbol_idx != max_U32) {
|
||||||
COFF_ParsedSymbol secdef = lnk_parsed_symbol_from_coff_symbol_idx(obj, symbol_idx);
|
COFF_ParsedSymbol secdef = lnk_parsed_symbol_from_coff_symbol_idx_no_name(obj, symbol_idx);
|
||||||
coff_parse_secdef(secdef, obj->header.is_big_obj, select_out, section_number_out, section_length_out, check_sum_out);
|
coff_parse_secdef(secdef, obj->header.is_big_obj, select_out, section_number_out, section_length_out, check_sum_out);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@@ -757,19 +787,39 @@ lnk_coff_section_header_from_section_number(LNK_Obj *obj, U64 section_number)
|
|||||||
return §ion_table[sect_idx];
|
return §ion_table[sect_idx];
|
||||||
}
|
}
|
||||||
|
|
||||||
internal COFF_ParsedSymbol
|
internal force_inline COFF_ParsedSymbol
|
||||||
|
lnk_parsed_symbol_from_coff_symbol_idx_no_name(LNK_Obj *obj, U64 symbol_idx)
|
||||||
|
{
|
||||||
|
return coff_parse_symbol_no_name(obj->header, lnk_coff_symbol_table_from_obj(obj), safe_cast_u32(symbol_idx));
|
||||||
|
}
|
||||||
|
|
||||||
|
internal force_inline String8
|
||||||
|
lnk_symbol_name_from_coff_symbol_idx(LNK_Obj *obj, U64 symbol_idx)
|
||||||
|
{
|
||||||
|
String8 result = {0};
|
||||||
|
U64 block_idx = symbol_idx >> 6;
|
||||||
|
U64 bit = 1ull << (symbol_idx & 63);
|
||||||
|
U64 mask = obj->symbol_name_cache.masks[block_idx];
|
||||||
|
if (mask & bit) {
|
||||||
|
U64 name_idx = obj->symbol_name_cache.block_bases[block_idx] + count_bits_set64(mask & (bit - 1));
|
||||||
|
U64 name_size = obj->symbol_name_cache.name_sizes[name_idx];
|
||||||
|
|
||||||
|
String8 symbol_table = lnk_coff_symbol_table_from_obj(obj);
|
||||||
|
COFF_SymbolName *name = obj->header.is_big_obj ? &((COFF_Symbol32 *)symbol_table.str)[symbol_idx].name
|
||||||
|
: &((COFF_Symbol16 *)symbol_table.str)[symbol_idx].name;
|
||||||
|
U8 *name_ptr = name->long_name.zeroes == 0
|
||||||
|
? obj->data.str + obj->header.string_table_range.min + name->long_name.string_table_offset
|
||||||
|
: name->short_name;
|
||||||
|
result = str8(name_ptr, name_size);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal force_inline COFF_ParsedSymbol
|
||||||
lnk_parsed_symbol_from_coff_symbol_idx(LNK_Obj *obj, U64 symbol_idx)
|
lnk_parsed_symbol_from_coff_symbol_idx(LNK_Obj *obj, U64 symbol_idx)
|
||||||
{
|
{
|
||||||
String8 string_table = str8_substr(obj->data, obj->header.string_table_range);
|
COFF_ParsedSymbol result = lnk_parsed_symbol_from_coff_symbol_idx_no_name(obj, symbol_idx);
|
||||||
String8 symbol_table = str8_substr(obj->data, obj->header.symbol_table_range);
|
result.name = lnk_symbol_name_from_coff_symbol_idx(obj, symbol_idx);
|
||||||
|
|
||||||
COFF_ParsedSymbol result = {0};
|
|
||||||
if (obj->header.is_big_obj) {
|
|
||||||
result = coff_parse_symbol32(string_table, (COFF_Symbol32 *)symbol_table.str + symbol_idx);
|
|
||||||
} else {
|
|
||||||
result = coff_parse_symbol16(string_table, (COFF_Symbol16 *)symbol_table.str + symbol_idx);
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+11
-1
@@ -5,6 +5,13 @@
|
|||||||
|
|
||||||
// --- Input -------------------------------------------------------------------
|
// --- Input -------------------------------------------------------------------
|
||||||
|
|
||||||
|
typedef struct LNK_SymbolNameCache
|
||||||
|
{
|
||||||
|
U64 *masks;
|
||||||
|
U32 *block_bases;
|
||||||
|
U32 *name_sizes;
|
||||||
|
} LNK_SymbolNameCache;
|
||||||
|
|
||||||
typedef struct LNK_Obj
|
typedef struct LNK_Obj
|
||||||
{
|
{
|
||||||
String8 path;
|
String8 path;
|
||||||
@@ -12,6 +19,7 @@ typedef struct LNK_Obj
|
|||||||
|
|
||||||
COFF_FileHeaderInfo header;
|
COFF_FileHeaderInfo header;
|
||||||
COFF_SectionFlags *section_flags;
|
COFF_SectionFlags *section_flags;
|
||||||
|
LNK_SymbolNameCache symbol_name_cache;
|
||||||
|
|
||||||
// flags
|
// flags
|
||||||
B8 hotpatch;
|
B8 hotpatch;
|
||||||
@@ -148,7 +156,9 @@ internal U32List lnk_obj_collect_associated_sections(Arena *arena, LNK_
|
|||||||
// --- Symbol & Section Helpers ------------------------------------------------
|
// --- Symbol & Section Helpers ------------------------------------------------
|
||||||
|
|
||||||
internal COFF_SectionHeader * lnk_coff_section_header_from_section_number(LNK_Obj *obj, U64 section_number);
|
internal COFF_SectionHeader * lnk_coff_section_header_from_section_number(LNK_Obj *obj, U64 section_number);
|
||||||
internal COFF_ParsedSymbol lnk_parsed_symbol_from_coff_symbol_idx(LNK_Obj *obj, U64 symbol_idx);
|
internal force_inline COFF_ParsedSymbol lnk_parsed_symbol_from_coff_symbol_idx(LNK_Obj *obj, U64 symbol_idx);
|
||||||
|
internal force_inline COFF_ParsedSymbol lnk_parsed_symbol_from_coff_symbol_idx_no_name(LNK_Obj *obj, U64 symbol_idx);
|
||||||
|
internal force_inline String8 lnk_symbol_name_from_coff_symbol_idx(LNK_Obj *obj, U64 symbol_idx);
|
||||||
internal U64 lnk_obj_sect_idx_from_section_number(LNK_Obj *obj, U64 section_number);
|
internal U64 lnk_obj_sect_idx_from_section_number(LNK_Obj *obj, U64 section_number);
|
||||||
internal U64 lnk_obj_section_number_from_sect_idx(LNK_Obj *obj, U64 sect_idx);
|
internal U64 lnk_obj_section_number_from_sect_idx(LNK_Obj *obj, U64 sect_idx);
|
||||||
internal String8 lnk_obj_section_name_from_section_number(LNK_Obj *obj, U64 section_number);
|
internal String8 lnk_obj_section_name_from_section_number(LNK_Obj *obj, U64 section_number);
|
||||||
|
|||||||
@@ -105,12 +105,12 @@ lnk_can_replace_symbol(LNK_Symbol *dst, LNK_Symbol *src)
|
|||||||
{
|
{
|
||||||
B32 can_replace = 0;
|
B32 can_replace = 0;
|
||||||
|
|
||||||
COFF_ParsedSymbol dst_parsed = lnk_parsed_from_symbol(dst);
|
|
||||||
COFF_ParsedSymbol src_parsed = lnk_parsed_from_symbol(src);
|
|
||||||
COFF_SymbolValueInterpType dst_interp = lnk_interp_from_symbol(dst);
|
|
||||||
COFF_SymbolValueInterpType src_interp = lnk_interp_from_symbol(src);
|
|
||||||
LNK_ObjSymbolRef dst_ref = lnk_ref_from_symbol(dst);
|
LNK_ObjSymbolRef dst_ref = lnk_ref_from_symbol(dst);
|
||||||
LNK_ObjSymbolRef src_ref = lnk_ref_from_symbol(src);
|
LNK_ObjSymbolRef src_ref = lnk_ref_from_symbol(src);
|
||||||
|
COFF_ParsedSymbol dst_parsed = lnk_parsed_symbol_from_coff_symbol_idx_no_name(dst_ref.obj, dst_ref.symbol_idx);
|
||||||
|
COFF_ParsedSymbol src_parsed = lnk_parsed_symbol_from_coff_symbol_idx_no_name(src_ref.obj, src_ref.symbol_idx);
|
||||||
|
COFF_SymbolValueInterpType dst_interp = coff_interp_from_parsed_symbol(dst_parsed);
|
||||||
|
COFF_SymbolValueInterpType src_interp = coff_interp_from_parsed_symbol(src_parsed);
|
||||||
LNK_Obj *dst_obj = dst_ref.obj;
|
LNK_Obj *dst_obj = dst_ref.obj;
|
||||||
LNK_Obj *src_obj = src_ref.obj;
|
LNK_Obj *src_obj = src_ref.obj;
|
||||||
|
|
||||||
@@ -338,9 +338,9 @@ lnk_can_replace_symbol(LNK_Symbol *dst, LNK_Symbol *src)
|
|||||||
internal void
|
internal void
|
||||||
lnk_on_symbol_replace(LNK_Symbol *dst, LNK_Symbol *src)
|
lnk_on_symbol_replace(LNK_Symbol *dst, LNK_Symbol *src)
|
||||||
{
|
{
|
||||||
COFF_ParsedSymbol dst_parsed = lnk_parsed_from_symbol(dst);
|
|
||||||
COFF_SymbolValueInterpType dst_interp = lnk_interp_from_symbol(dst);
|
|
||||||
LNK_ObjSymbolRef dst_ref = lnk_ref_from_symbol(dst);
|
LNK_ObjSymbolRef dst_ref = lnk_ref_from_symbol(dst);
|
||||||
|
COFF_ParsedSymbol dst_parsed = lnk_parsed_symbol_from_coff_symbol_idx_no_name(dst_ref.obj, dst_ref.symbol_idx);
|
||||||
|
COFF_SymbolValueInterpType dst_interp = coff_interp_from_parsed_symbol(dst_parsed);
|
||||||
|
|
||||||
if (dst_interp == COFF_SymbolValueInterp_Regular) {
|
if (dst_interp == COFF_SymbolValueInterp_Regular) {
|
||||||
// remove replaced section from the output
|
// remove replaced section from the output
|
||||||
@@ -537,7 +537,8 @@ lnk_parsed_from_symbol(LNK_Symbol *symbol)
|
|||||||
internal COFF_SymbolValueInterpType
|
internal COFF_SymbolValueInterpType
|
||||||
lnk_interp_from_symbol(LNK_Symbol *symbol)
|
lnk_interp_from_symbol(LNK_Symbol *symbol)
|
||||||
{
|
{
|
||||||
COFF_ParsedSymbol symbol_parsed = lnk_parsed_from_symbol(symbol);
|
LNK_ObjSymbolRef ref = lnk_ref_from_symbol(symbol);
|
||||||
|
COFF_ParsedSymbol symbol_parsed = lnk_parsed_symbol_from_coff_symbol_idx_no_name(ref.obj, ref.symbol_idx);
|
||||||
return coff_interp_from_parsed_symbol(symbol_parsed);
|
return coff_interp_from_parsed_symbol(symbol_parsed);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -662,7 +663,7 @@ lnk_resolve_weak_symbol(LNK_SymbolTable *symtab, LNK_ObjSymbolRef symbol, LNK_Ob
|
|||||||
goto exit;
|
goto exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
COFF_ParsedSymbol current_parsed = lnk_parsed_symbol_from_coff_symbol_idx(current_symbol.obj, current_symbol.symbol_idx);
|
COFF_ParsedSymbol current_parsed = lnk_parsed_symbol_from_coff_symbol_idx_no_name(current_symbol.obj, current_symbol.symbol_idx);
|
||||||
COFF_SymbolValueInterpType current_interp = coff_interp_symbol(current_parsed.section_number, current_parsed.value, current_parsed.storage_class);
|
COFF_SymbolValueInterpType current_interp = coff_interp_symbol(current_parsed.section_number, current_parsed.value, current_parsed.storage_class);
|
||||||
if (current_interp == COFF_SymbolValueInterp_Weak) {
|
if (current_interp == COFF_SymbolValueInterp_Weak) {
|
||||||
// record visited symbol
|
// record visited symbol
|
||||||
@@ -671,7 +672,7 @@ lnk_resolve_weak_symbol(LNK_SymbolTable *symtab, LNK_ObjSymbolRef symbol, LNK_Ob
|
|||||||
SLLQueuePush(sf, sl, s);
|
SLLQueuePush(sf, sl, s);
|
||||||
|
|
||||||
// does weak symbol have a definition?
|
// does weak symbol have a definition?
|
||||||
LNK_Symbol *defn_symbol = lnk_symbol_table_search(symtab, current_parsed.name);
|
LNK_Symbol *defn_symbol = lnk_symbol_table_search(symtab, lnk_symbol_name_from_coff_symbol_idx(current_symbol.obj, current_symbol.symbol_idx));
|
||||||
COFF_ParsedSymbol defn_parsed = lnk_parsed_from_symbol(defn_symbol);
|
COFF_ParsedSymbol defn_parsed = lnk_parsed_from_symbol(defn_symbol);
|
||||||
COFF_SymbolValueInterpType defn_interp = coff_interp_symbol(defn_parsed.section_number, defn_parsed.value, defn_parsed.storage_class);
|
COFF_SymbolValueInterpType defn_interp = coff_interp_symbol(defn_parsed.section_number, defn_parsed.value, defn_parsed.storage_class);
|
||||||
if (defn_interp != COFF_SymbolValueInterp_Weak) {
|
if (defn_interp != COFF_SymbolValueInterp_Weak) {
|
||||||
@@ -682,19 +683,19 @@ lnk_resolve_weak_symbol(LNK_SymbolTable *symtab, LNK_ObjSymbolRef symbol, LNK_Ob
|
|||||||
COFF_SymbolWeakExt *weak_ext = coff_parse_weak_tag(current_parsed, current_symbol.obj->header.is_big_obj);
|
COFF_SymbolWeakExt *weak_ext = coff_parse_weak_tag(current_parsed, current_symbol.obj->header.is_big_obj);
|
||||||
|
|
||||||
// no definition -- fallback to default symbol
|
// no definition -- fallback to default symbol
|
||||||
COFF_ParsedSymbol tag_parsed = lnk_parsed_symbol_from_coff_symbol_idx(current_symbol.obj, weak_ext->tag_index);
|
COFF_ParsedSymbol tag_parsed = lnk_parsed_symbol_from_coff_symbol_idx_no_name(current_symbol.obj, weak_ext->tag_index);
|
||||||
COFF_SymbolValueInterpType tag_interp = coff_interp_symbol(tag_parsed.section_number, tag_parsed.value, tag_parsed.storage_class);
|
COFF_SymbolValueInterpType tag_interp = coff_interp_symbol(tag_parsed.section_number, tag_parsed.value, tag_parsed.storage_class);
|
||||||
current_symbol = (LNK_ObjSymbolRef){ .obj = current_symbol.obj, .symbol_idx = weak_ext->tag_index };
|
current_symbol = (LNK_ObjSymbolRef){ .obj = current_symbol.obj, .symbol_idx = weak_ext->tag_index };
|
||||||
|
|
||||||
if (weak_ext->characteristics == COFF_WeakExt_AntiDependency) {
|
if (weak_ext->characteristics == COFF_WeakExt_AntiDependency) {
|
||||||
if (tag_interp == COFF_SymbolValueInterp_Undefined || tag_interp == COFF_SymbolValueInterp_Weak) {
|
if (tag_interp == COFF_SymbolValueInterp_Undefined || tag_interp == COFF_SymbolValueInterp_Weak) {
|
||||||
LNK_Symbol *dep_symbol = lnk_symbol_table_search(symtab, tag_parsed.name);
|
LNK_Symbol *dep_symbol = lnk_symbol_table_search(symtab, lnk_symbol_name_from_coff_symbol_idx(current_symbol.obj, weak_ext->tag_index));
|
||||||
tag_interp = lnk_interp_from_symbol(dep_symbol);
|
tag_interp = lnk_interp_from_symbol(dep_symbol);
|
||||||
}
|
}
|
||||||
if (tag_interp == COFF_SymbolValueInterp_Weak) { break; }
|
if (tag_interp == COFF_SymbolValueInterp_Weak) { break; }
|
||||||
}
|
}
|
||||||
} else if (current_interp == COFF_SymbolValueInterp_Undefined) {
|
} else if (current_interp == COFF_SymbolValueInterp_Undefined) {
|
||||||
LNK_Symbol *defn_symbol = lnk_symbol_table_search(symtab, current_parsed.name);
|
LNK_Symbol *defn_symbol = lnk_symbol_table_search(symtab, lnk_symbol_name_from_coff_symbol_idx(current_symbol.obj, current_symbol.symbol_idx));
|
||||||
COFF_SymbolValueInterpType defn_interp = lnk_interp_from_symbol(defn_symbol);
|
COFF_SymbolValueInterpType defn_interp = lnk_interp_from_symbol(defn_symbol);
|
||||||
|
|
||||||
// unresolved undefined symbol
|
// unresolved undefined symbol
|
||||||
@@ -719,7 +720,7 @@ internal B32
|
|||||||
lnk_resolve_symbol(LNK_SymbolTable *symtab, LNK_ObjSymbolRef symbol, LNK_ObjSymbolRef *symbol_out)
|
lnk_resolve_symbol(LNK_SymbolTable *symtab, LNK_ObjSymbolRef symbol, LNK_ObjSymbolRef *symbol_out)
|
||||||
{
|
{
|
||||||
B32 is_resolved = 1;
|
B32 is_resolved = 1;
|
||||||
COFF_ParsedSymbol symbol_parsed = lnk_parsed_symbol_from_coff_symbol_idx(symbol.obj, symbol.symbol_idx);
|
COFF_ParsedSymbol symbol_parsed = lnk_parsed_symbol_from_coff_symbol_idx_no_name(symbol.obj, symbol.symbol_idx);
|
||||||
COFF_SymbolValueInterpType symbol_interp = coff_interp_symbol(symbol_parsed.section_number, symbol_parsed.value, symbol_parsed.storage_class);
|
COFF_SymbolValueInterpType symbol_interp = coff_interp_symbol(symbol_parsed.section_number, symbol_parsed.value, symbol_parsed.storage_class);
|
||||||
switch (symbol_interp) {
|
switch (symbol_interp) {
|
||||||
case COFF_SymbolValueInterp_Regular: {
|
case COFF_SymbolValueInterp_Regular: {
|
||||||
@@ -727,7 +728,7 @@ lnk_resolve_symbol(LNK_SymbolTable *symtab, LNK_ObjSymbolRef symbol, LNK_ObjSymb
|
|||||||
*symbol_out = lnk_obj_get_comdat_symlink(symbol.obj, symbol_parsed.section_number, &symlink) ? symlink : symbol;
|
*symbol_out = lnk_obj_get_comdat_symlink(symbol.obj, symbol_parsed.section_number, &symlink) ? symlink : symbol;
|
||||||
} break;
|
} break;
|
||||||
case COFF_SymbolValueInterp_Weak: {
|
case COFF_SymbolValueInterp_Weak: {
|
||||||
LNK_Symbol *defn = lnk_symbol_table_search(symtab, symbol_parsed.name);
|
LNK_Symbol *defn = lnk_symbol_table_search(symtab, lnk_symbol_name_from_coff_symbol_idx(symbol.obj, symbol.symbol_idx));
|
||||||
COFF_ParsedSymbol defn_parsed = lnk_parsed_from_symbol(defn);
|
COFF_ParsedSymbol defn_parsed = lnk_parsed_from_symbol(defn);
|
||||||
COFF_SymbolValueInterpType defn_interp = lnk_interp_from_symbol(defn);
|
COFF_SymbolValueInterpType defn_interp = lnk_interp_from_symbol(defn);
|
||||||
if (defn_interp != COFF_SymbolValueInterp_Undefined) {
|
if (defn_interp != COFF_SymbolValueInterp_Undefined) {
|
||||||
@@ -737,7 +738,7 @@ lnk_resolve_symbol(LNK_SymbolTable *symtab, LNK_ObjSymbolRef symbol, LNK_ObjSymb
|
|||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
case COFF_SymbolValueInterp_Undefined: {
|
case COFF_SymbolValueInterp_Undefined: {
|
||||||
LNK_Symbol *defn = lnk_symbol_table_search(symtab, symbol_parsed.name);
|
LNK_Symbol *defn = lnk_symbol_table_search(symtab, lnk_symbol_name_from_coff_symbol_idx(symbol.obj, symbol.symbol_idx));
|
||||||
if (defn) {
|
if (defn) {
|
||||||
*symbol_out = lnk_ref_from_symbol(defn);
|
*symbol_out = lnk_ref_from_symbol(defn);
|
||||||
} else {
|
} else {
|
||||||
@@ -745,12 +746,12 @@ lnk_resolve_symbol(LNK_SymbolTable *symtab, LNK_ObjSymbolRef symbol, LNK_ObjSymb
|
|||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
case COFF_SymbolValueInterp_Common: {
|
case COFF_SymbolValueInterp_Common: {
|
||||||
LNK_Symbol *defn = lnk_symbol_table_search(symtab, symbol_parsed.name);
|
LNK_Symbol *defn = lnk_symbol_table_search(symtab, lnk_symbol_name_from_coff_symbol_idx(symbol.obj, symbol.symbol_idx));
|
||||||
*symbol_out = lnk_ref_from_symbol(defn);
|
*symbol_out = lnk_ref_from_symbol(defn);
|
||||||
} break;
|
} break;
|
||||||
case COFF_SymbolValueInterp_Abs: {
|
case COFF_SymbolValueInterp_Abs: {
|
||||||
if (symbol_parsed.storage_class == COFF_SymStorageClass_External) {
|
if (symbol_parsed.storage_class == COFF_SymStorageClass_External) {
|
||||||
LNK_Symbol *defn = lnk_symbol_table_search(symtab, symbol_parsed.name);
|
LNK_Symbol *defn = lnk_symbol_table_search(symtab, lnk_symbol_name_from_coff_symbol_idx(symbol.obj, symbol.symbol_idx));
|
||||||
*symbol_out = lnk_ref_from_symbol(defn);
|
*symbol_out = lnk_ref_from_symbol(defn);
|
||||||
} else {
|
} else {
|
||||||
*symbol_out = symbol;
|
*symbol_out = symbol;
|
||||||
@@ -769,12 +770,12 @@ THREAD_POOL_TASK_FUNC(lnk_replace_weak_with_default_symbol_task)
|
|||||||
for EachIndex(i, c->count) {
|
for EachIndex(i, c->count) {
|
||||||
LNK_Symbol *symbol = c->v[i].symbol;
|
LNK_Symbol *symbol = c->v[i].symbol;
|
||||||
LNK_ObjSymbolRef symbol_ref = lnk_ref_from_symbol(symbol);
|
LNK_ObjSymbolRef symbol_ref = lnk_ref_from_symbol(symbol);
|
||||||
COFF_ParsedSymbol symbol_parsed = lnk_parsed_from_symbol(symbol);
|
COFF_ParsedSymbol symbol_parsed = lnk_parsed_symbol_from_coff_symbol_idx_no_name(symbol_ref.obj, symbol_ref.symbol_idx);
|
||||||
COFF_SymbolValueInterpType symbol_interp = coff_interp_from_parsed_symbol(symbol_parsed);
|
COFF_SymbolValueInterpType symbol_interp = coff_interp_from_parsed_symbol(symbol_parsed);
|
||||||
if (symbol_interp == COFF_SymbolValueInterp_Weak) {
|
if (symbol_interp == COFF_SymbolValueInterp_Weak) {
|
||||||
LNK_ObjSymbolRef resolve = {0};
|
LNK_ObjSymbolRef resolve = {0};
|
||||||
if (lnk_resolve_weak_symbol(symtab, symbol_ref, &resolve)) {
|
if (lnk_resolve_weak_symbol(symtab, symbol_ref, &resolve)) {
|
||||||
COFF_ParsedSymbol resolve_parsed = lnk_parsed_symbol_from_coff_symbol_idx(resolve.obj, resolve.symbol_idx);
|
COFF_ParsedSymbol resolve_parsed = lnk_parsed_symbol_from_coff_symbol_idx_no_name(resolve.obj, resolve.symbol_idx);
|
||||||
COFF_SymbolValueInterpType resolve_interp = coff_interp_from_parsed_symbol(resolve_parsed);
|
COFF_SymbolValueInterpType resolve_interp = coff_interp_from_parsed_symbol(resolve_parsed);
|
||||||
if (resolve_interp == COFF_SymbolValueInterp_Weak) {
|
if (resolve_interp == COFF_SymbolValueInterp_Weak) {
|
||||||
COFF_SymbolWeakExt *weak_ext = coff_parse_weak_tag(resolve_parsed, symbol_ref.obj->header.is_big_obj);
|
COFF_SymbolWeakExt *weak_ext = coff_parse_weak_tag(resolve_parsed, symbol_ref.obj->header.is_big_obj);
|
||||||
|
|||||||
Reference in New Issue
Block a user