debug log unresolved symbols specified in .llvm_addrsig

This commit is contained in:
Nikita Smith
2026-07-27 14:47:11 -07:00
committed by Ryan Fleury
parent 3eeae8d365
commit 541727b819
+21 -17
View File
@@ -2967,22 +2967,18 @@ lnk_icf_color_space_from_section(LNK_Obj *obj, U32 sect_idx)
return result; return result;
} }
internal // NOTE: OPT uses a color-refinement algorithm for folding duplicate sections.
// If a color group contains multiple distinct hashes, the group is split
// and a new refinement round is run. By default, the algorithm loops until
// partitions stabilize. Equivalence is established by comparing cryptographic
// 128-bit hashes; in theory, the chance of collisions are near the birthday
// paradox with BLAKE3 and the other downside it is susceptible to adversarial
// inputs.
THREAD_POOL_TASK_FUNC(lnk_opt_icf_task) THREAD_POOL_TASK_FUNC(lnk_opt_icf_task)
{ {
ProfBeginFunction(); ProfBeginFunction();
Temp scratch = scratch_begin(&arena,1); Temp scratch = scratch_begin(&arena,1);
//
// OPT uses a color-refinement algorithm for folding duplicate sections.
// If a color group contains multiple distinct hashes, the group is split
// and a new refinement pass is run. By default, the algorithm loops until
// partitions stabilize. Equivalence is established by comparing cryptographic
// 128-bit hashes; in theory, the chance of collisions are near the birthday
// paradox with BLAKE3 and the other downside it is susceptible to adversarial
// inputs.
//
LNK_OptTask *task = raw_task; LNK_OptTask *task = raw_task;
LNK_Obj **objs = task->objs; LNK_Obj **objs = task->objs;
@@ -3004,7 +3000,8 @@ THREAD_POOL_TASK_FUNC(lnk_opt_icf_task)
COFF_SectionHeader *section_header = lnk_coff_section_header_from_section_number(obj, obj->llvm_addrsig_sect_idx + 1); COFF_SectionHeader *section_header = lnk_coff_section_header_from_section_number(obj, obj->llvm_addrsig_sect_idx + 1);
String8 section_data = str8_substr(obj->data, r1u64s(section_header->foff, section_header->fsize)); String8 section_data = str8_substr(obj->data, r1u64s(section_header->foff, section_header->fsize));
// parse symbol indices and mark selected sections with NOICF flag // parse symbol indices and mark selected sections with NOICF flag,
// the selected symbols maybe undefined/weak which need to be resolved
for (U64 off = 0; off < section_data.size;) { for (U64 off = 0; off < section_data.size;) {
U64 symbol_off = off; U64 symbol_off = off;
U64 symbol_idx = 0; U64 symbol_idx = 0;
@@ -3015,11 +3012,16 @@ 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 = coff_parse_symbol(target_ref.obj->header, string_table, symbol_table, target_ref.symbol_idx); COFF_ParsedSymbol symbol = lnk_parsed_symbol_from_coff_symbol_idx(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) {
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 {
lnk_error_obj(LNK_Error_IllData, obj, ".llvm_addrsig: skip symbol 0x%x at offset 0x%x; symbol index must address a section-based symbol\n", symbol_idx, symbol_off); COFF_ParsedSymbol original_symbol = lnk_parsed_symbol_from_coff_symbol_idx(obj, symbol_idx);
if (coff_interp_from_parsed_symbol(original_symbol) == COFF_SymbolValueInterp_Regular) {
obj->section_flags[original_symbol.section_number - 1] |= LNK_SECTION_FLAG_NOICF;
} else {
lnk_log(LNK_Log_Debug, "%S: .llvm_addrsig: contains an unresolved symbol index 0x%x at offset 0x%x", lnk_loc_from_obj(scratch.arena, obj), symbol_idx, symbol_off);
} }
} }
} else { } else {
@@ -3034,8 +3036,9 @@ THREAD_POOL_TASK_FUNC(lnk_opt_icf_task)
// step 1: fill out color map and contributions // step 1: fill out color map and contributions
// //
// alloc total section counter
U64 *contrib_counts = 0; U64 *contrib_counts = 0;
{
// alloc total section counter
if (task_id == 0) { if (task_id == 0) {
contrib_counts = push_array(scratch.arena, U64, task->objs_count); contrib_counts = push_array(scratch.arena, U64, task->objs_count);
} }
@@ -3052,6 +3055,7 @@ THREAD_POOL_TASK_FUNC(lnk_opt_icf_task)
} }
} }
barrier_wait(tp->barrier); barrier_wait(tp->barrier);
}
typedef struct { typedef struct {
struct { struct {
@@ -3244,7 +3248,7 @@ THREAD_POOL_TASK_FUNC(lnk_opt_icf_task)
} }
U64 split_count = *next_color - start_next_color; U64 split_count = *next_color - start_next_color;
lnk_log(LNK_Log_Debug, " Pass %llu found %S splits", iter_count, str8_from_count(scratch.arena, split_count)); lnk_log(LNK_Log_Debug, " Round %llu found %S splits", iter_count, str8_from_count(scratch.arena, split_count));
temp_end(temp); temp_end(temp);
} }