mirror of
https://github.com/Ed94/raddebugger.git
synced 2026-11-14 10:10:11 -08:00
centralize canonical COFF object data
This commit is contained in:
1 parent
cf67aca7da
commit
646ff97b3c
6 files changed
+306
-253
No files matched your search
+96
-102
@@ -1221,8 +1221,8 @@ lnk_load_objs(TP_Context *tp, TP_Arena *arena, LNK_Config *config, LNK_Inputer *
|
||||
// if machine type was unspecified on the command line, derive it from obj file
|
||||
if (config->machine == COFF_MachineType_Unknown) {
|
||||
for EachIndex(obj_idx, new_input_objs.count) {
|
||||
if (new_objs[obj_idx].data.header.machine != COFF_MachineType_Unknown) {
|
||||
config->machine = new_objs[obj_idx].data.header.machine;
|
||||
if (new_objs[obj_idx].data.coff.header.machine != COFF_MachineType_Unknown) {
|
||||
config->machine = new_objs[obj_idx].data.coff.header.machine;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -1335,7 +1335,6 @@ lnk_load_inputs(TP_Context *tp, TP_Arena *arena, LNK_Config *config, LNK_Inputer
|
||||
lnk_obj_list_push_node(&link->objs, include_obj);
|
||||
}
|
||||
}
|
||||
|
||||
ProfEnd();
|
||||
}
|
||||
|
||||
@@ -2383,8 +2382,8 @@ lnk_link_image(TP_Context *tp, TP_Arena *arena, LNK_Config *config, LNK_Inputer
|
||||
sect_filter |= COFF_SectionFlag_LnkRemove; // skip sections that are discarded from the output
|
||||
if ( ! lnk_do_debug_info(config)) { sect_filter |= LNK_SECTION_FLAG_DEBUG; } // on /DEBUG:NONE linker never invokes the debug info machinery
|
||||
|
||||
for EachIndex(sect_idx, obj->header.section_count_no_null) {
|
||||
if (obj->section_flags[sect_idx] & sect_filter) { continue; }
|
||||
for EachIndex(sect_idx, obj->coff.sections.count) {
|
||||
if (obj->coff.sections.flags[sect_idx] & sect_filter) { continue; }
|
||||
|
||||
// unpack section and relocations
|
||||
COFF_SectionHeader *section_header = §ion_table[sect_idx];
|
||||
@@ -2524,7 +2523,7 @@ lnk_link_image(TP_Context *tp, TP_Arena *arena, LNK_Config *config, LNK_Inputer
|
||||
//
|
||||
if (lnk_get_log_status(LNK_Log_InputObj)) {
|
||||
U64 total_input_size = 0;
|
||||
for (LNK_ObjNode *obj_n = link->objs.first; obj_n != 0; obj_n = obj_n->next) { total_input_size += obj_n->data.data.size; }
|
||||
for (LNK_ObjNode *obj_n = link->objs.first; obj_n != 0; obj_n = obj_n->next) { total_input_size += obj_n->data.coff.data.size; }
|
||||
lnk_log(LNK_Log_InputObj, "[Total Obj Input Size %M]", total_input_size);
|
||||
}
|
||||
if (lnk_get_log_status(LNK_Log_InputLib)) {
|
||||
@@ -2607,7 +2606,7 @@ lnk_obj_indices_from_section_counts(Arena *arena, U64 worker_count, LNK_Obj **ob
|
||||
}
|
||||
}
|
||||
|
||||
worker_section_counts[min_worker_idx] += objs[obj_idx]->header.section_count_no_null;
|
||||
worker_section_counts[min_worker_idx] += objs[obj_idx]->coff.sections.count;
|
||||
worker_obj_counts[min_worker_idx] += 1;
|
||||
}
|
||||
|
||||
@@ -2629,7 +2628,7 @@ lnk_obj_indices_from_section_counts(Arena *arena, U64 worker_count, LNK_Obj **ob
|
||||
U32Array *worker_obj_indices = &obj_indices[min_worker_idx];
|
||||
worker_obj_indices->v[worker_obj_counts[min_worker_idx]++] = (U32)obj_idx;
|
||||
worker_obj_indices->count += 1;
|
||||
worker_section_counts[min_worker_idx] += objs[obj_idx]->header.section_count_no_null;
|
||||
worker_section_counts[min_worker_idx] += objs[obj_idx]->coff.sections.count;
|
||||
}
|
||||
|
||||
scratch_end(scratch);
|
||||
@@ -2706,10 +2705,10 @@ THREAD_POOL_TASK_FUNC(lnk_opt_ref_task)
|
||||
for EachIndex(obj_idx, objs_count) {
|
||||
LNK_Obj *obj = objs[obj_idx];
|
||||
|
||||
is_live[obj_idx] = push_array(scratch.arena, U8, obj->header.section_count_no_null + 1);
|
||||
is_live[obj_idx] = push_array(scratch.arena, U8, obj->coff.sections.count + 1);
|
||||
|
||||
for EachIndex(sect_idx, obj->header.section_count_no_null) {
|
||||
is_live[obj_idx][sect_idx + 1] = !(obj->section_flags[sect_idx] & COFF_SectionFlag_LnkCOMDAT);
|
||||
for EachIndex(sect_idx, obj->coff.sections.count) {
|
||||
is_live[obj_idx][sect_idx + 1] = !(obj->coff.sections.flags[sect_idx] & COFF_SectionFlag_LnkCOMDAT);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2740,9 +2739,9 @@ THREAD_POOL_TASK_FUNC(lnk_opt_ref_task)
|
||||
for EachIndex(obj_idx, objs_count) {
|
||||
LNK_Obj *obj = objs[obj_idx];
|
||||
|
||||
for EachIndex(sect_idx, obj->header.section_count_no_null) {
|
||||
for EachIndex(sect_idx, obj->coff.sections.count) {
|
||||
U32 section_number = sect_idx+1;
|
||||
COFF_SectionFlags section_flags = obj->section_flags[sect_idx];
|
||||
COFF_SectionFlags section_flags = obj->coff.sections.flags[sect_idx];
|
||||
|
||||
// is section eligible for walking?
|
||||
if (section_flags & COFF_SectionFlag_LnkRemove) { continue; }
|
||||
@@ -2807,7 +2806,7 @@ THREAD_POOL_TASK_FUNC(lnk_opt_ref_task)
|
||||
for EachNode(section_n, U32Node, associated_sections.first) {
|
||||
U32 section_number = section_n->data;
|
||||
|
||||
COFF_SectionFlags section_flags = ref_symbol.obj->section_flags[section_number-1];
|
||||
COFF_SectionFlags section_flags = ref_symbol.obj->coff.sections.flags[section_number-1];
|
||||
|
||||
// on first section visit, set live flag and enqueue section
|
||||
U8 was_visited = ins_atomic_u8_eval_assign(&is_live[ref_symbol.obj->input_idx][section_number], 1);
|
||||
@@ -2874,11 +2873,11 @@ THREAD_POOL_TASK_FUNC(lnk_opt_ref_task)
|
||||
|
||||
for EachIndex(obj_idx, objs_count) {
|
||||
LNK_Obj *obj = objs[obj_idx];
|
||||
for EachIndex(sect_idx, obj->header.section_count_no_null) {
|
||||
for EachIndex(sect_idx, obj->coff.sections.count) {
|
||||
U32 section_number = sect_idx+1;
|
||||
COFF_SectionHeader *section_header = lnk_coff_section_header_from_section_number(obj, section_number);
|
||||
if ( ! is_live[obj->input_idx][section_number]) {
|
||||
obj->section_flags[sect_idx] |= COFF_SectionFlag_LnkRemove;
|
||||
obj->coff.sections.flags[sect_idx] |= COFF_SectionFlag_LnkRemove;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2891,24 +2890,24 @@ THREAD_POOL_TASK_FUNC(lnk_opt_ref_task)
|
||||
for EachIndex(obj_idx, objs_count) {
|
||||
LNK_Obj *obj = objs[obj_idx];
|
||||
|
||||
for EachIndex(sect_idx, obj->header.section_count_no_null) {
|
||||
for EachIndex(sect_idx, obj->coff.sections.count) {
|
||||
U32 section_number = sect_idx+1;
|
||||
COFF_SectionHeader *section_header = lnk_coff_section_header_from_section_number(obj, section_number);
|
||||
|
||||
U64 stat_kind = Stat_Null;
|
||||
if (obj->section_flags[sect_idx] & LNK_SECTION_FLAG_DEBUG) { stat_kind = Stat_Debug; }
|
||||
else if (obj->section_flags[sect_idx] & COFF_SectionFlag_CntCode) { stat_kind = Stat_Code; }
|
||||
if (obj->coff.sections.flags[sect_idx] & LNK_SECTION_FLAG_DEBUG) { stat_kind = Stat_Debug; }
|
||||
else if (obj->coff.sections.flags[sect_idx] & COFF_SectionFlag_CntCode) { stat_kind = Stat_Code; }
|
||||
else { stat_kind = Stat_Data; }
|
||||
|
||||
if (is_live[obj->input_idx][section_number]) {
|
||||
stats[stat_kind].live_count += 1;
|
||||
if (obj->section_flags[sect_idx] & COFF_SectionFlag_CntUninitializedData) {
|
||||
if (obj->coff.sections.flags[sect_idx] & COFF_SectionFlag_CntUninitializedData) {
|
||||
stats[stat_kind].live_vsize += section_header->vsize;
|
||||
} else {
|
||||
stats[stat_kind].live_fsize += section_header->fsize;
|
||||
}
|
||||
} else {
|
||||
if (obj->section_flags[sect_idx] & COFF_SectionFlag_CntUninitializedData) {
|
||||
if (obj->coff.sections.flags[sect_idx] & COFF_SectionFlag_CntUninitializedData) {
|
||||
stats[stat_kind].vsize += section_header->vsize;
|
||||
} else {
|
||||
stats[stat_kind].fsize += section_header->fsize;
|
||||
@@ -2979,16 +2978,16 @@ lnk_icf_scope_from_section(LNK_Obj *obj, U32 sect_idx)
|
||||
// * section flags filter *
|
||||
COFF_SectionFlags expected_flags = COFF_SectionFlag_LnkCOMDAT | COFF_SectionFlag_MemRead;
|
||||
COFF_SectionFlags exclude_flags = COFF_SectionFlag_LnkRemove | COFF_SectionFlag_MemWrite | LNK_SECTION_FLAG_NOICF;
|
||||
if ((obj->section_flags[sect_idx] & expected_flags) != expected_flags || (obj->section_flags[sect_idx] & exclude_flags) != 0) {
|
||||
if ((obj->coff.sections.flags[sect_idx] & expected_flags) != expected_flags || (obj->coff.sections.flags[sect_idx] & exclude_flags) != 0) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if (obj->section_flags[sect_idx] & COFF_SectionFlag_CntCode) {
|
||||
if (obj->coff.sections.flags[sect_idx] & COFF_SectionFlag_CntCode) {
|
||||
result = LNK_ICF_Scope_Code;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if (obj->section_flags[sect_idx] & COFF_SectionFlag_CntInitializedData) {
|
||||
if (obj->coff.sections.flags[sect_idx] & COFF_SectionFlag_CntInitializedData) {
|
||||
U64 section_number = sect_idx + 1;
|
||||
COFF_SectionHeader *section_header = lnk_coff_section_header_from_section_number(obj, section_number);
|
||||
String8 section_name = str8_cstring_capped(section_header->name, section_header->name + sizeof(section_header->name));
|
||||
@@ -3043,7 +3042,7 @@ lnk_icf_scope_from_section(LNK_Obj *obj, U32 sect_idx)
|
||||
}
|
||||
|
||||
exit:;
|
||||
Assert(result == LNK_ICF_Scope_Null || obj->comdats[sect_idx] != max_U32); // TODO: are symlinks on COMDATs optional?
|
||||
Assert(result == LNK_ICF_Scope_Null || obj->coff.sections.comdats[sect_idx] != max_U32); // TODO: are symlinks on COMDATs optional?
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -3118,39 +3117,36 @@ THREAD_POOL_TASK_FUNC(lnk_opt_icf_task)
|
||||
|
||||
if (task->config->llvm_addrsig == LNK_SwitchState_Yes) {
|
||||
ProfBegin("Flag significant sections");
|
||||
|
||||
// .llvm_addrsig is an array of ULEB128 symbol indices, which mark sections
|
||||
// whose addresses are significant
|
||||
for EachIndex(i, task->obj_indices[task_id].count) {
|
||||
U64 obj_idx = task->obj_indices[task_id].v[i];
|
||||
LNK_Obj *obj = task->objs[obj_idx];
|
||||
|
||||
if (obj->llvm_addrsig_sect_idx >= obj->header.section_count_no_null) { continue; }
|
||||
|
||||
String8 symbol_table = lnk_coff_symbol_table_from_obj(obj);
|
||||
String8 string_table = lnk_coff_string_table_from_obj(obj);
|
||||
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));
|
||||
if (obj->coff.llvm_addrsig_sect_idx >= obj->coff.sections.count) { continue; }
|
||||
|
||||
// parse symbol indices and mark selected sections with NOICF flag,
|
||||
// the selected symbols maybe undefined/weak which need to be resolved
|
||||
String8 section_data = lnk_obj_section_data_from_sect_idx(obj, obj->coff.llvm_addrsig_sect_idx);
|
||||
for (U64 off = 0; off < section_data.size;) {
|
||||
U64 symbol_off = off;
|
||||
U64 symbol_idx = 0;
|
||||
off += str8_deserial_read_uleb128(section_data, off, &symbol_idx);
|
||||
if (symbol_off == off) { break; }
|
||||
|
||||
if (symbol_idx < obj->header.symbol_count) {
|
||||
if (symbol_idx < obj->coff.header.symbol_count) {
|
||||
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);
|
||||
if (is_symbol_found) {
|
||||
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) {
|
||||
target_ref.obj->section_flags[symbol.section_number - 1] |= LNK_SECTION_FLAG_NOICF;
|
||||
target_ref.obj->coff.sections.flags[symbol.section_number - 1] |= LNK_SECTION_FLAG_NOICF;
|
||||
}
|
||||
} else {
|
||||
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) {
|
||||
obj->section_flags[original_symbol.section_number - 1] |= LNK_SECTION_FLAG_NOICF;
|
||||
obj->coff.sections.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);
|
||||
}
|
||||
@@ -3179,7 +3175,7 @@ THREAD_POOL_TASK_FUNC(lnk_opt_icf_task)
|
||||
for EachIndex(i, task->obj_indices[task_id].count) {
|
||||
U64 obj_idx = task->obj_indices[task_id].v[i];
|
||||
LNK_Obj *obj = objs[obj_idx];
|
||||
for EachIndex(sect_idx, obj->header.section_count_no_null) {
|
||||
for EachIndex(sect_idx, obj->coff.sections.count) {
|
||||
if (lnk_icf_scope_from_section(obj, sect_idx)) {
|
||||
contrib_counts[obj_idx] += 1;
|
||||
}
|
||||
@@ -3209,13 +3205,13 @@ THREAD_POOL_TASK_FUNC(lnk_opt_icf_task)
|
||||
U64 noncontrib_count = 0;
|
||||
for EachIndex(obj_idx, task->objs_count) {
|
||||
shared.noncontrib_offsets[obj_idx] = noncontrib_count;
|
||||
noncontrib_count += objs[obj_idx]->header.section_count_no_null - contrib_counts[obj_idx];
|
||||
noncontrib_count += objs[obj_idx]->coff.sections.count - contrib_counts[obj_idx];
|
||||
}
|
||||
|
||||
shared.color_map = push_array(scratch.arena, U64 *, task->objs_count);
|
||||
for EachIndex(obj_idx, task->objs_count) {
|
||||
LNK_Obj *obj = objs[obj_idx];
|
||||
shared.color_map[obj_idx] = push_array(scratch.arena, U64, obj->header.section_count_no_null);
|
||||
shared.color_map[obj_idx] = push_array(scratch.arena, U64, obj->coff.sections.count);
|
||||
}
|
||||
|
||||
shared.contrib_offsets = offsets_from_counts_array_u64(scratch.arena, contrib_counts, task->objs_count);
|
||||
@@ -3240,7 +3236,7 @@ THREAD_POOL_TASK_FUNC(lnk_opt_icf_task)
|
||||
LNK_Obj *obj = objs[obj_idx];
|
||||
U64 cursor = 0;
|
||||
U64 noncontrib_cursor = 0;
|
||||
for EachIndex(sect_idx, obj->header.section_count_no_null) {
|
||||
for EachIndex(sect_idx, obj->coff.sections.count) {
|
||||
LNK_ICF_Scope scope = lnk_icf_scope_from_section(obj, sect_idx);
|
||||
if (scope == LNK_ICF_Scope_Null) {
|
||||
// assign colors in object order to avoid a contended atomic allocator
|
||||
@@ -3278,7 +3274,7 @@ THREAD_POOL_TASK_FUNC(lnk_opt_icf_task)
|
||||
U64 reloc_cursor = 0;
|
||||
for EachNode(associated_n, U32Node, associated_sections.first) {
|
||||
COFF_SectionHeader *associated_header = lnk_coff_section_header_from_section_number(obj, associated_n->data);
|
||||
String8 associated_data = str8_substr(obj->data, r1u64s(associated_header->foff, associated_header->fsize));
|
||||
String8 associated_data = lnk_obj_section_data_from_sect_idx(obj, associated_n->data - 1);
|
||||
COFF_RelocArray associated_relocs = lnk_coff_relocs_from_section_header(obj, associated_header);
|
||||
|
||||
lnk_hasher_update_string(&hasher, associated_data);
|
||||
@@ -3306,12 +3302,12 @@ THREAD_POOL_TASK_FUNC(lnk_opt_icf_task)
|
||||
U32 target_sect = target_symbol.section_number;
|
||||
|
||||
// use the selected COMDAT leader so equivalent targets hash alike
|
||||
if (target_sect != 0 && target_sect <= target_obj->header.section_count_no_null &&
|
||||
target_obj->section_flags[target_sect - 1] & COFF_SectionFlag_LnkCOMDAT) {
|
||||
if (target_sect != 0 && target_sect <= target_obj->coff.sections.count &&
|
||||
target_obj->coff.sections.flags[target_sect - 1] & COFF_SectionFlag_LnkCOMDAT) {
|
||||
LNK_ObjSymbolRef leader_ref = {0};
|
||||
if (lnk_obj_get_comdat_symlink(target_obj, target_sect, &leader_ref)) {
|
||||
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->coff.sections.count) {
|
||||
target_obj = leader_ref.obj;
|
||||
target_sect = leader_symbol.section_number;
|
||||
}
|
||||
@@ -3606,8 +3602,8 @@ THREAD_POOL_TASK_FUNC(lnk_opt_icf_task)
|
||||
|
||||
// TODO: double-check if discarded section headers should be updated with leaders' alignment,
|
||||
// leaders at this point are resolved
|
||||
U64 contrib_align = coff_align_size_from_section_flags(contrib_obj->section_flags[contrib->sect_idx]);
|
||||
COFF_SectionFlags *leader_flags = &leader_obj->section_flags[leader->sect_idx];
|
||||
U64 contrib_align = coff_align_size_from_section_flags(contrib_obj->coff.sections.flags[contrib->sect_idx]);
|
||||
COFF_SectionFlags *leader_flags = &leader_obj->coff.sections.flags[leader->sect_idx];
|
||||
for (COFF_SectionFlags old_flags = ins_atomic_u32_eval((U32 *)leader_flags);;) {
|
||||
U64 leader_align = coff_align_size_from_section_flags(old_flags);
|
||||
if (leader_align >= contrib_align) { break; }
|
||||
@@ -3622,10 +3618,10 @@ THREAD_POOL_TASK_FUNC(lnk_opt_icf_task)
|
||||
}
|
||||
|
||||
// remove folded section from the image
|
||||
contrib_obj->section_flags[contrib->sect_idx] |= COFF_SectionFlag_LnkRemove;
|
||||
contrib_obj->coff.sections.flags[contrib->sect_idx] |= COFF_SectionFlag_LnkRemove;
|
||||
|
||||
// update folded section COMDAT symlink to point to the leader section
|
||||
contrib_obj->symlinks[contrib->sect_idx + 1] = (LNK_ObjSymbolRef){ leader_obj, leader_obj->comdats[leader->sect_idx] };
|
||||
contrib_obj->symlinks[contrib->sect_idx + 1] = (LNK_ObjSymbolRef){ leader_obj, leader_obj->coff.sections.comdats[leader->sect_idx] };
|
||||
|
||||
#if LNK_PARANOID
|
||||
String8 section_name = lnk_obj_section_name_from_section_number(contrib_obj, contrib->sect_idx+1);
|
||||
@@ -3691,7 +3687,7 @@ THREAD_POOL_TASK_FUNC(lnk_opt_icf_task)
|
||||
for EachIndex(i, task->obj_indices[task_id].count) {
|
||||
U64 obj_idx = task->obj_indices[task_id].v[i];
|
||||
LNK_Obj *obj = objs[obj_idx];
|
||||
for EachIndex(sect_idx, obj->header.section_count_no_null) {
|
||||
for EachIndex(sect_idx, obj->coff.sections.count) {
|
||||
U64 section_number = sect_idx + 1;
|
||||
|
||||
LNK_ObjSymbolRef symlink_ref = {0};
|
||||
@@ -3758,7 +3754,7 @@ lnk_section_definition_is_before(void *raw_a, void *raw_b)
|
||||
internal B32
|
||||
lnk_should_gather_section(LNK_Obj *obj, U64 sect_idx, COFF_SectionHeader *sect_header)
|
||||
{
|
||||
COFF_SectionFlags sect_flags = obj->section_flags[sect_idx];
|
||||
COFF_SectionFlags sect_flags = obj->coff.sections.flags[sect_idx];
|
||||
|
||||
// removed sections were eliminated before image layout
|
||||
if (sect_flags & COFF_SectionFlag_LnkRemove) {
|
||||
@@ -3801,10 +3797,10 @@ THREAD_POOL_TASK_FUNC(lnk_gather_sections_task)
|
||||
ProfBegin("Gather Section Definitions");
|
||||
for EachInRange(obj_idx, range) {
|
||||
LNK_Obj *obj = task->objs[obj_idx];
|
||||
COFF_SectionHeader *section_table = (COFF_SectionHeader *)str8_substr(obj->data, obj->header.section_table_range).str;
|
||||
String8 string_table = str8_substr(obj->data, obj->header.string_table_range);
|
||||
COFF_SectionHeader *section_table = (COFF_SectionHeader *)str8_substr(obj->coff.data, obj->coff.header.section_table_range).str;
|
||||
String8 string_table = str8_substr(obj->coff.data, obj->coff.header.string_table_range);
|
||||
|
||||
for EachIndex(sect_idx, obj->header.section_count_no_null) {
|
||||
for EachIndex(sect_idx, obj->coff.sections.count) {
|
||||
COFF_SectionHeader *sect_header = §ion_table[sect_idx];
|
||||
|
||||
if ( ! lnk_should_gather_section(obj, sect_idx, sect_header)) { continue; }
|
||||
@@ -3812,7 +3808,7 @@ THREAD_POOL_TASK_FUNC(lnk_gather_sections_task)
|
||||
Temp temp = temp_begin(scratch.arena);
|
||||
|
||||
// was section defined?
|
||||
COFF_SectionFlags image_sect_flags = obj->section_flags[sect_idx] & ~(COFF_SectionFlags_LnkFlags | COFF_SectionFlags_Reserved);
|
||||
COFF_SectionFlags image_sect_flags = obj->coff.sections.flags[sect_idx] & ~(COFF_SectionFlags_LnkFlags | COFF_SectionFlags_Reserved);
|
||||
String8 sect_name = coff_name_from_section_header(string_table, sect_header);
|
||||
image_sect_flags = lnk_apply_section_directives_to_flags(task->config, sect_name, image_sect_flags);
|
||||
String8 sect_name_with_flags = lnk_make_name_with_flags(temp.arena, sect_name, image_sect_flags);
|
||||
@@ -3893,7 +3889,7 @@ THREAD_POOL_TASK_FUNC(lnk_gather_sections_task)
|
||||
LNK_Obj *obj = sect_defn->obj;
|
||||
U32 sect_number = sect_defn->obj_sect_idx + 1;
|
||||
COFF_SectionHeader *sect_header = lnk_coff_section_header_from_section_number(obj, sect_number);
|
||||
String8 sect_name = coff_name_from_section_header(str8_substr(obj->data, obj->header.string_table_range), sect_header);
|
||||
String8 sect_name = coff_name_from_section_header(str8_substr(obj->coff.data, obj->coff.header.string_table_range), sect_header);
|
||||
String8 expected_flags_str = coff_string_from_section_flags(main_arena, sect_n->data.flags);
|
||||
String8 current_flags_str = coff_string_from_section_flags(main_arena, sect_defn->flags);
|
||||
lnk_error_obj(LNK_Warning_SectionFlagsConflict, sect_defn->obj, "detected section flags conflict in %S(No. %X); expected {%S} but got {%S}", sect_name, sect_number, expected_flags_str, current_flags_str);
|
||||
@@ -3922,7 +3918,7 @@ THREAD_POOL_TASK_FUNC(lnk_gather_sections_task)
|
||||
|
||||
ProfBegin("Alloc Section Map");
|
||||
task->sect_map = push_array(main_arena, LNK_SectionContrib **, task->objs_count);
|
||||
for EachIndex(obj_idx, task->objs_count) { task->sect_map[obj_idx] = push_array(main_arena, LNK_SectionContrib *, task->objs[obj_idx]->header.section_count_no_null); }
|
||||
for EachIndex(obj_idx, task->objs_count) { task->sect_map[obj_idx] = push_array(main_arena, LNK_SectionContrib *, task->objs[obj_idx]->coff.sections.count); }
|
||||
ProfEnd();
|
||||
}
|
||||
|
||||
@@ -3931,14 +3927,14 @@ THREAD_POOL_TASK_FUNC(lnk_gather_sections_task)
|
||||
ProfBegin("Gather Section Contribs");
|
||||
for EachInRange(obj_idx, range) {
|
||||
LNK_Obj *obj = task->objs[obj_idx];
|
||||
COFF_SectionHeader *section_table = (COFF_SectionHeader *)str8_substr(obj->data, obj->header.section_table_range).str;
|
||||
String8 string_table = str8_substr(obj->data, obj->header.string_table_range);
|
||||
COFF_SectionHeader *section_table = (COFF_SectionHeader *)str8_substr(obj->coff.data, obj->coff.header.section_table_range).str;
|
||||
String8 string_table = str8_substr(obj->coff.data, obj->coff.header.string_table_range);
|
||||
|
||||
ProfBeginV("Gather Section Contribs [%S]", obj->path);
|
||||
for EachIndex(sect_idx, obj->header.section_count_no_null) {
|
||||
for EachIndex(sect_idx, obj->coff.sections.count) {
|
||||
LNK_SectionContrib *sc = task->null_sc;
|
||||
COFF_SectionHeader *sect_header = §ion_table[sect_idx];
|
||||
COFF_SectionFlags sect_flags = obj->section_flags[sect_idx];
|
||||
COFF_SectionFlags sect_flags = obj->coff.sections.flags[sect_idx];
|
||||
task->sect_map[obj_idx][sect_idx] = sc;
|
||||
|
||||
if ( ! lnk_should_gather_section(obj, sect_idx, sect_header)) { continue; }
|
||||
@@ -3959,7 +3955,7 @@ THREAD_POOL_TASK_FUNC(lnk_gather_sections_task)
|
||||
if (sect_flags & COFF_SectionFlag_CntUninitializedData) {
|
||||
data = str8(0, sect_header->fsize);
|
||||
} else {
|
||||
data = str8_substr(obj->data, rng_1u64(sect_header->foff, sect_header->foff + sect_header->fsize));
|
||||
data = lnk_obj_section_data_from_sect_idx(obj, sect_idx);
|
||||
}
|
||||
|
||||
U16 sc_align = coff_align_size_from_section_flags(sect_flags);
|
||||
@@ -3988,10 +3984,10 @@ THREAD_POOL_TASK_FUNC(lnk_set_comdat_leaders_contribs_task)
|
||||
LNK_Obj *obj = task->objs[obj_idx];
|
||||
|
||||
ProfBeginV("Set COMDAT Section Contribs [%S]", obj->path);
|
||||
for EachIndex(sect_idx, obj->header.section_count_no_null) {
|
||||
for EachIndex(sect_idx, obj->coff.sections.count) {
|
||||
U64 section_number = sect_idx+1;
|
||||
|
||||
if (~obj->section_flags[sect_idx] & COFF_SectionFlag_LnkCOMDAT) { continue; }
|
||||
if (~obj->coff.sections.flags[sect_idx] & COFF_SectionFlag_LnkCOMDAT) { continue; }
|
||||
|
||||
LNK_ObjSymbolRef symlink_ref = {0};
|
||||
if ( ! lnk_obj_get_comdat_symlink(obj, section_number, &symlink_ref)) { continue; }
|
||||
@@ -4010,11 +4006,11 @@ THREAD_POOL_TASK_FUNC(lnk_flag_debug_symbols_task)
|
||||
LNK_Obj *obj = task->objs[obj_idx];
|
||||
|
||||
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->coff.header.symbol_count; symbol_idx += (1 + symbol.aux_symbol_count)) {
|
||||
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);
|
||||
if (interp == COFF_SymbolValueInterp_Regular) {
|
||||
if (obj->section_flags[symbol.section_number-1] & LNK_SECTION_FLAG_DEBUG) {
|
||||
if (obj->coff.sections.flags[symbol.section_number-1] & LNK_SECTION_FLAG_DEBUG) {
|
||||
task->u.patch_symtabs.was_symbol_patched[obj_idx][symbol_idx] = 1;
|
||||
}
|
||||
}
|
||||
@@ -4030,7 +4026,7 @@ THREAD_POOL_TASK_FUNC(lnk_patch_comdat_leaders_task)
|
||||
|
||||
ProfBeginV("Patch COMDAT Offsets in %S", obj->path);
|
||||
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->coff.header.symbol_count; symbol_idx += (1 + symbol.aux_symbol_count)) {
|
||||
symbol = lnk_parsed_symbol_from_coff_symbol_idx_no_name(obj, symbol_idx);
|
||||
|
||||
COFF_SymbolValueInterpType interp = coff_interp_from_parsed_symbol(symbol);
|
||||
@@ -4050,7 +4046,7 @@ THREAD_POOL_TASK_FUNC(lnk_patch_comdat_leaders_task)
|
||||
B32 should_patch = 0;
|
||||
|
||||
if (is_same_obj) {
|
||||
B32 is_static_comdat_leader = symbol.storage_class == COFF_SymStorageClass_Static && obj->comdats[symbol.section_number-1] == symbol_idx;
|
||||
B32 is_static_comdat_leader = symbol.storage_class == COFF_SymStorageClass_Static && obj->coff.sections.comdats[symbol.section_number-1] == symbol_idx;
|
||||
if (is_external || is_static_comdat_leader) {
|
||||
section_number = leader_symbol.section_number;
|
||||
value = leader_symbol.value;
|
||||
@@ -4256,7 +4252,7 @@ THREAD_POOL_TASK_FUNC(lnk_patch_common_block_symbols_task)
|
||||
|
||||
ProfBeginV("Patch Common Block Symbols [%S]", obj->path);
|
||||
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->coff.header.symbol_count; symbol_idx += (1 + symbol.aux_symbol_count)) {
|
||||
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);
|
||||
if (interp == COFF_SymbolValueInterp_Common) {
|
||||
@@ -4283,7 +4279,7 @@ THREAD_POOL_TASK_FUNC(lnk_patch_regular_symbols_task)
|
||||
|
||||
ProfBeginV("Patch Regular Symbols [%S]", obj->path);
|
||||
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->coff.header.symbol_count; symbol_idx += (1 + symbol.aux_symbol_count)) {
|
||||
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; }
|
||||
@@ -4315,7 +4311,7 @@ lnk_patch_obj_symtab(LNK_SymbolTable *symtab, LNK_Obj *obj, B8 *was_symbol_patch
|
||||
ProfBeginV("%S\n", obj->path);
|
||||
|
||||
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->coff.header.symbol_count; symbol_idx += (1 + fixup_dst.aux_symbol_count)) {
|
||||
fixup_dst = lnk_parsed_symbol_from_coff_symbol_idx_no_name(obj, symbol_idx);
|
||||
if (was_symbol_patched[symbol_idx]) { continue; }
|
||||
|
||||
@@ -4422,7 +4418,7 @@ THREAD_POOL_TASK_FUNC(lnk_obj_reloc_patcher)
|
||||
LNK_ObjRelocPatcher *task = raw_task;
|
||||
LNK_Obj *obj = task->objs[task_id];
|
||||
|
||||
COFF_FileHeaderInfo obj_header = obj->header;
|
||||
COFF_FileHeaderInfo obj_header = obj->coff.header;
|
||||
COFF_SectionHeader *section_table = lnk_coff_section_table_from_obj(obj);
|
||||
String8 symbol_table = lnk_coff_symbol_table_from_obj(obj);
|
||||
String8 string_table = lnk_coff_string_table_from_obj(obj);
|
||||
@@ -4433,16 +4429,15 @@ THREAD_POOL_TASK_FUNC(lnk_obj_reloc_patcher)
|
||||
|
||||
for EachIndex(sect_idx, obj_header.section_count_no_null) {
|
||||
COFF_SectionHeader *section_header = §ion_table[sect_idx];
|
||||
COFF_SectionFlags section_flags = obj->section_flags[sect_idx];
|
||||
COFF_SectionFlags section_flags = obj->coff.sections.flags[sect_idx];
|
||||
|
||||
if (section_flags & COFF_SectionFlag_LnkInfo) { continue; }
|
||||
if (section_flags & COFF_SectionFlag_LnkRemove) { continue; }
|
||||
if (section_flags & COFF_SectionFlag_CntUninitializedData) { continue; }
|
||||
|
||||
// get section bytes (special case debug info because it is not copied to the image)
|
||||
String8 data = section_flags & LNK_SECTION_FLAG_DEBUG ? obj->data : task->image_data;
|
||||
Rng1U64 section_frange = rng_1u64(section_header->foff, section_header->foff + section_header->fsize);
|
||||
String8 section_data = str8_substr(data, section_frange);
|
||||
String8 section_data = section_flags & LNK_SECTION_FLAG_DEBUG ? lnk_obj_section_data_from_sect_idx(obj, sect_idx) : str8_substr(task->image_data, section_frange);
|
||||
|
||||
// apply relocs
|
||||
COFF_RelocArray relocs = lnk_coff_relocs_from_section_header(obj, section_header);
|
||||
@@ -4450,12 +4445,12 @@ THREAD_POOL_TASK_FUNC(lnk_obj_reloc_patcher)
|
||||
COFF_Reloc *reloc = &relocs.v[reloc_idx];
|
||||
|
||||
// error check relocation
|
||||
if (obj->header.machine == COFF_MachineType_X64) {
|
||||
if (obj->coff.header.machine == COFF_MachineType_X64) {
|
||||
if (reloc->type > COFF_Reloc_X64_Last) {
|
||||
lnk_error_obj(LNK_Error_IllegalRelocation, obj, "unknown relocation type 0x%x", reloc->type);
|
||||
}
|
||||
} else if (obj->header.machine != COFF_MachineType_Unknown) {
|
||||
lnk_not_implemented("relocation patching is not implemented for %S", coff_string_from_machine_type(obj->header.machine));
|
||||
} else if (obj->coff.header.machine != COFF_MachineType_Unknown) {
|
||||
lnk_not_implemented("relocation patching is not implemented for %S", coff_string_from_machine_type(obj->coff.header.machine));
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -4571,15 +4566,15 @@ THREAD_POOL_TASK_FUNC(lnk_flag_hotpatch_contribs_task)
|
||||
U64 obj_idx = task_id;
|
||||
LNK_Obj *obj = task->objs[obj_idx];
|
||||
|
||||
if (obj->hotpatch) {
|
||||
if (obj->coff.hotpatch) {
|
||||
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->coff.header.symbol_count; symbol_idx += (1 + symbol.aux_symbol_count)) {
|
||||
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);
|
||||
if (interp == COFF_SymbolValueInterp_Regular && COFF_SymbolType_IsFunc(symbol.type)) {
|
||||
LNK_SectionContrib *sc = task->sect_map[obj_idx][symbol.section_number-1];
|
||||
if (sc != task->null_sc) {
|
||||
sc->hotpatch = !!(obj->section_flags[symbol.section_number-1] & COFF_SectionFlag_CntCode);
|
||||
sc->hotpatch = !!(obj->coff.sections.flags[symbol.section_number-1] & COFF_SectionFlag_CntCode);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4941,9 +4936,9 @@ THREAD_POOL_TASK_FUNC(lnk_patch_virtual_offsets_and_sizes_in_obj_section_headers
|
||||
|
||||
ProfBeginV("Patch Virtual Offset And Size In Section Headers [%S]", obj->path);
|
||||
COFF_SectionHeader *section_table = lnk_coff_section_table_from_obj(obj);
|
||||
for (U64 sect_idx = 0; sect_idx < obj->header.section_count_no_null; sect_idx += 1) {
|
||||
for (U64 sect_idx = 0; sect_idx < obj->coff.sections.count; sect_idx += 1) {
|
||||
COFF_SectionHeader *sect_header = §ion_table[sect_idx];
|
||||
if (~obj->section_flags[sect_idx] & COFF_SectionFlag_LnkRemove) {
|
||||
if (~obj->coff.sections.flags[sect_idx] & COFF_SectionFlag_LnkRemove) {
|
||||
LNK_SectionContrib *sc = task->sect_map[obj_idx][sect_idx];
|
||||
LNK_Section *sect = task->image_sects.v[sc->u.sect_idx];
|
||||
sect_header->vsize = lnk_size_from_section_contrib(sc);
|
||||
@@ -4962,9 +4957,9 @@ THREAD_POOL_TASK_FUNC(lnk_patch_file_offsets_and_sizes_in_obj_section_headers_ta
|
||||
|
||||
ProfBeginV("Patch File Offsets And Sizes In Obj Section Headers [%S]", obj->path);
|
||||
COFF_SectionHeader *section_table = lnk_coff_section_table_from_obj(obj);
|
||||
for (U64 sect_idx = 0; sect_idx < obj->header.section_count_no_null; sect_idx += 1) {
|
||||
for (U64 sect_idx = 0; sect_idx < obj->coff.sections.count; sect_idx += 1) {
|
||||
COFF_SectionHeader *sect_header = §ion_table[sect_idx];
|
||||
COFF_SectionFlags sect_flags = obj->section_flags[sect_idx];
|
||||
COFF_SectionFlags sect_flags = obj->coff.sections.flags[sect_idx];
|
||||
B32 patch_section_header = (~sect_flags & COFF_SectionFlag_LnkRemove) &&
|
||||
(~sect_flags & LNK_SECTION_FLAG_DEBUG);
|
||||
if (patch_section_header) {
|
||||
@@ -4988,16 +4983,16 @@ THREAD_POOL_TASK_FUNC(lnk_patch_section_symbols_task)
|
||||
|
||||
ProfBegin("Patch Section Symbols [%S]", obj->path);
|
||||
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->coff.header.symbol_count; symbol_idx += (1 + symbol.aux_symbol_count)) {
|
||||
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);
|
||||
if (interp == COFF_SymbolValueInterp_Undefined) {
|
||||
if (symbol.storage_class == COFF_SymStorageClass_Section) {
|
||||
B32 is_referenced = 0;
|
||||
COFF_SectionHeader *section_table = lnk_coff_section_table_from_obj(obj);
|
||||
for EachIndex(sect_idx, obj->header.section_count_no_null) {
|
||||
for EachIndex(sect_idx, obj->coff.sections.count) {
|
||||
COFF_SectionHeader *section_header = §ion_table[sect_idx];
|
||||
COFF_SectionFlags section_flags = obj->section_flags[sect_idx];
|
||||
COFF_SectionFlags section_flags = obj->coff.sections.flags[sect_idx];
|
||||
if (section_flags & COFF_SectionFlag_LnkRemove) { continue; }
|
||||
if (section_flags & COFF_SectionFlag_LnkInfo) { continue; }
|
||||
if (section_flags & LNK_SECTION_FLAG_DEBUG) { continue; }
|
||||
@@ -5061,9 +5056,9 @@ THREAD_POOL_TASK_FUNC(lnk_gather_base_reloc_pages_task)
|
||||
COFF_SectionHeader *sect_table = lnk_coff_section_table_from_obj(obj);
|
||||
|
||||
ProfBeginV("%S", obj->path);
|
||||
for EachIndex(sect_idx, obj->header.section_count_no_null) {
|
||||
for EachIndex(sect_idx, obj->coff.sections.count) {
|
||||
COFF_SectionHeader *sect_header = §_table[sect_idx];
|
||||
if (obj->section_flags[sect_idx] & COFF_SectionFlag_LnkRemove) { continue; }
|
||||
if (obj->coff.sections.flags[sect_idx] & COFF_SectionFlag_LnkRemove) { continue; }
|
||||
|
||||
COFF_RelocArray relocs = lnk_coff_relocs_from_section_header(obj, sect_header);
|
||||
for EachIndex(reloc_idx, relocs.count) {
|
||||
@@ -5073,7 +5068,7 @@ THREAD_POOL_TASK_FUNC(lnk_gather_base_reloc_pages_task)
|
||||
COFF_SymbolValueInterpType symbol_interp = coff_interp_from_parsed_symbol(symbol);
|
||||
if (symbol_interp == COFF_SymbolValueInterp_Abs) { continue; }
|
||||
|
||||
U64 is_addr = coff_is_addr_reloc(obj->header.machine, r->type);
|
||||
U64 is_addr = coff_is_addr_reloc(obj->coff.header.machine, r->type);
|
||||
if (is_addr == 0) { continue; }
|
||||
|
||||
U64 reloc_voff = sect_header->voff + r->apply_off;
|
||||
@@ -5759,7 +5754,7 @@ lnk_build_image(TP_Arena *arena, TP_Context *tp, LNK_Config *config, LNK_SymbolT
|
||||
task.u.patch_symtabs.common_block_ranges = tp_divide_work(temp.arena, common_block_contribs_count, tp->worker_count);
|
||||
task.u.patch_symtabs.common_block_contribs = common_block_contribs;
|
||||
task.u.patch_symtabs.was_symbol_patched = push_array(temp.arena, B8 *, objs_count);
|
||||
for EachIndex(obj_idx, objs_count) { task.u.patch_symtabs.was_symbol_patched[obj_idx] = push_array(temp.arena, B8, objs[obj_idx]->header.symbol_count); }
|
||||
for EachIndex(obj_idx, objs_count) { task.u.patch_symtabs.was_symbol_patched[obj_idx] = push_array(temp.arena, B8, objs[obj_idx]->coff.header.symbol_count); }
|
||||
|
||||
// flag debug symbols to prevent them from being patched in subsequent passes
|
||||
tp_for_parallel_prof(tp, 0, objs_count, lnk_flag_debug_symbols_task, &task, "Flag Debug Symbols");
|
||||
@@ -6139,15 +6134,15 @@ lnk_obj_sect_idx_from_section(Arena *arena, U64 objs_count, LNK_Obj **objs, LNK_
|
||||
PairU32 *obj_sect_idxs = push_array(arena, PairU32, max_contribs);
|
||||
for (U64 obj_idx = 0; obj_idx < objs_count; obj_idx += 1) {
|
||||
LNK_Obj *obj = objs[obj_idx];
|
||||
COFF_SectionHeader *section_table = str8_deserial_get_raw_ptr(obj->data, obj->header.section_table_range.min, 0);
|
||||
String8 string_table = str8_substr(obj->data, obj->header.string_table_range);
|
||||
for (U64 sect_idx = 0; sect_idx < obj->header.section_count_no_null; sect_idx += 1) {
|
||||
COFF_SectionHeader *section_table = str8_deserial_get_raw_ptr(obj->coff.data, obj->coff.header.section_table_range.min, 0);
|
||||
String8 string_table = str8_substr(obj->coff.data, obj->coff.header.string_table_range);
|
||||
for (U64 sect_idx = 0; sect_idx < obj->coff.sections.count; sect_idx += 1) {
|
||||
COFF_SectionHeader *section_header = §ion_table[sect_idx];
|
||||
String8 full_section_name = coff_name_from_section_header(string_table, section_header);
|
||||
String8 section_name, section_postfix;
|
||||
coff_parse_section_name(full_section_name, §ion_name, §ion_postfix);
|
||||
|
||||
if (obj->section_flags[sect_idx] & COFF_SectionFlag_LnkRemove) { continue; }
|
||||
if (obj->coff.sections.flags[sect_idx] & COFF_SectionFlag_LnkRemove) { continue; }
|
||||
if (section_header->fsize == 0) { continue; }
|
||||
if (lnk_is_section_removed(config, section_name)) { continue; }
|
||||
|
||||
@@ -6172,7 +6167,7 @@ internal COFF_SectionHeader *
|
||||
lnk_coff_section_header_from_obj_sect_idx_pair(LNK_Obj **objs, PairU32 p)
|
||||
{
|
||||
LNK_Obj *obj = objs[p.v0];
|
||||
COFF_SectionHeader *section_table = str8_deserial_get_raw_ptr(obj->data, obj->header.section_table_range.min, 0);
|
||||
COFF_SectionHeader *section_table = str8_deserial_get_raw_ptr(obj->coff.data, obj->coff.header.section_table_range.min, 0);
|
||||
return §ion_table[p.v1];
|
||||
}
|
||||
|
||||
@@ -6287,7 +6282,7 @@ 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 string_table = str8_substr(obj->coff.data, obj->coff.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) {
|
||||
@@ -6315,10 +6310,10 @@ lnk_build_rad_map(Arena *arena, String8 image_data, LNK_Config *config, U64 objs
|
||||
str8_list_pushf(arena, &map, "# DEBUG\n");
|
||||
for (U64 obj_idx = 0; obj_idx < objs_count; obj_idx += 1) {
|
||||
LNK_Obj *obj = objs[obj_idx];
|
||||
COFF_SectionHeader *section_table = str8_deserial_get_raw_ptr(obj->data, obj->header.section_table_range.min, 0);
|
||||
for (U64 sect_idx = 0; sect_idx < obj->header.section_count_no_null; sect_idx += 1) {
|
||||
COFF_SectionHeader *section_table = str8_deserial_get_raw_ptr(obj->coff.data, obj->coff.header.section_table_range.min, 0);
|
||||
for (U64 sect_idx = 0; sect_idx < obj->coff.sections.count; sect_idx += 1) {
|
||||
COFF_SectionHeader *section_header = §ion_table[sect_idx];
|
||||
COFF_SectionFlags section_flags = obj->section_flags[sect_idx];
|
||||
COFF_SectionFlags section_flags = obj->coff.sections.flags[sect_idx];
|
||||
if (~section_flags & COFF_SectionFlag_LnkRemove && section_flags & LNK_SECTION_FLAG_DEBUG) {
|
||||
LNK_Lib *lib = lnk_obj_get_lib(obj);
|
||||
if (lib) {
|
||||
@@ -6812,12 +6807,11 @@ lnk_run_type_server(TP_Context *tp, TP_Arena *arena, LNK_Config *config)
|
||||
if (obj->link_member) { continue; }
|
||||
|
||||
// does obj have debug types?
|
||||
if (obj->debug_p_sect_idx < obj->header.section_count_no_null) {
|
||||
if (obj->coff.debug_p_sect_idx < obj->coff.sections.count) {
|
||||
u64_list_push(scratch.arena, &include_obj_list, obj_idx);
|
||||
} else if (obj->debug_t_sect_idx < obj->header.section_count_no_null) {
|
||||
} else if (obj->coff.debug_t_sect_idx < obj->coff.sections.count) {
|
||||
// read first leaf
|
||||
LNK_ObjSection section = lnk_obj_section_from_sect_idx(obj, obj->debug_t_sect_idx);
|
||||
String8 raw_debug_t = str8_substr(obj->data, section.frange);
|
||||
String8 raw_debug_t = lnk_obj_section_data_from_sect_idx(obj, obj->coff.debug_t_sect_idx);
|
||||
CV_Leaf leaf = {0};
|
||||
cv_read_leaf(raw_debug_t, 0, 1, &leaf);
|
||||
|
||||
|
||||
+20
-23
@@ -76,10 +76,8 @@ THREAD_POOL_TASK_FUNC(lnk_parse_debug_h_task)
|
||||
LNK_CodeViewInput *task = raw_task;
|
||||
|
||||
LNK_Obj *obj = task->obj_arr[obj_idx];
|
||||
if (obj->debug_h_sect_idx < obj->header.section_count_no_null) {
|
||||
LNK_ObjSection section = lnk_obj_section_from_sect_idx(obj, obj->debug_h_sect_idx);
|
||||
|
||||
String8 raw_debug_h = str8_substr(obj->data, section.frange);
|
||||
if (obj->coff.debug_h_sect_idx < obj->coff.sections.count) {
|
||||
String8 raw_debug_h = lnk_obj_section_data_from_sect_idx(obj, obj->coff.debug_h_sect_idx);
|
||||
CV_DebugH *debug_h = &task->debug_h_arr[obj_idx];
|
||||
LLVM_GHash ghash = {0};
|
||||
U64 ghash_read_size = str8_deserial_read_struct(raw_debug_h, 0, &ghash);
|
||||
@@ -599,6 +597,7 @@ lnk_rrt_from_string(Arena *arena, String8 rrt_data, String8 path, LNK_RRT *rrt_o
|
||||
}
|
||||
|
||||
// unpack type data
|
||||
type_data_raw = push_str8_copy(arena, type_data_raw);
|
||||
String8 type_data[CV_TypeIndexSource_COUNT] = {0};
|
||||
for EachIndex(ti_source, CV_TypeIndexSource_COUNT) {
|
||||
type_data[ti_source] = str8_substr(type_data_raw, type_data_ranges[ti_source]);
|
||||
@@ -700,9 +699,9 @@ lnk_make_code_view_input(TP_Context *tp, TP_Arena *tp_arena, LNK_Config *config,
|
||||
if (rrt->obj_time_stamps[rrt_obj_idx] != obj_file_props.modified) { continue; }
|
||||
|
||||
// invalidate debug section pointers
|
||||
obj->debug_t_sect_idx = ~0;
|
||||
obj->debug_p_sect_idx = ~0;
|
||||
obj->debug_h_sect_idx = ~0;
|
||||
obj->coff.debug_t_sect_idx = ~0;
|
||||
obj->coff.debug_p_sect_idx = ~0;
|
||||
obj->coff.debug_h_sect_idx = ~0;
|
||||
|
||||
// apply type index map
|
||||
obj->ti_range = rrt->obj_ti_ranges[rrt_obj_idx];
|
||||
@@ -734,15 +733,15 @@ lnk_make_code_view_input(TP_Context *tp, TP_Arena *tp_arena, LNK_Config *config,
|
||||
|
||||
for EachNode(n, String8Node, input.debug_s_list_arr[obj_idx].first) { total_debug_s_size += n->string.size; }
|
||||
|
||||
if (obj->debug_t_sect_idx < obj->header.section_count_no_null) {
|
||||
total_debug_t_size += lnk_obj_section_from_sect_idx(obj, obj->debug_t_sect_idx).header->fsize;
|
||||
if (obj->coff.debug_t_sect_idx < obj->coff.sections.count) {
|
||||
total_debug_t_size += lnk_obj_section_from_sect_idx(obj, obj->coff.debug_t_sect_idx).header->fsize;
|
||||
}
|
||||
if (obj->debug_p_sect_idx < obj->header.section_count_no_null) {
|
||||
total_debug_p_size += lnk_obj_section_from_sect_idx(obj, obj->debug_p_sect_idx).header->fsize;
|
||||
if (obj->coff.debug_p_sect_idx < obj->coff.sections.count) {
|
||||
total_debug_p_size += lnk_obj_section_from_sect_idx(obj, obj->coff.debug_p_sect_idx).header->fsize;
|
||||
}
|
||||
if (config->ghash) {
|
||||
if (obj->debug_h_sect_idx < obj->header.section_count_no_null) {
|
||||
total_debug_h_size += lnk_obj_section_from_sect_idx(obj, obj->debug_h_sect_idx).header->fsize;
|
||||
if (obj->coff.debug_h_sect_idx < obj->coff.sections.count) {
|
||||
total_debug_h_size += lnk_obj_section_from_sect_idx(obj, obj->coff.debug_h_sect_idx).header->fsize;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -784,18 +783,16 @@ lnk_make_code_view_input(TP_Context *tp, TP_Arena *tp_arena, LNK_Config *config,
|
||||
for EachIndex(obj_idx, obj_count) {
|
||||
LNK_Obj *obj = obj_arr[obj_idx];
|
||||
|
||||
if (obj->debug_t_sect_idx < obj->header.section_count_no_null) {
|
||||
LNK_ObjSection debug_t_sect = lnk_obj_section_from_sect_idx(obj, obj->debug_t_sect_idx);
|
||||
if (obj->coff.debug_t_sect_idx < obj->coff.sections.count) {
|
||||
raw_debug_t_arr[obj_idx].count = 1;
|
||||
raw_debug_t_arr[obj_idx].v = push_array(scratch.arena, String8, 1);
|
||||
raw_debug_t_arr[obj_idx].v[0] = str8_substr(obj->data, debug_t_sect.frange);
|
||||
raw_debug_t_arr[obj_idx].v[0] = lnk_obj_section_data_from_sect_idx(obj, obj->coff.debug_t_sect_idx);
|
||||
}
|
||||
|
||||
if (obj->debug_p_sect_idx < obj->header.section_count_no_null) {
|
||||
LNK_ObjSection debug_p_sect = lnk_obj_section_from_sect_idx(obj, obj->debug_p_sect_idx);
|
||||
if (obj->coff.debug_p_sect_idx < obj->coff.sections.count) {
|
||||
raw_debug_p_arr[obj_idx].count = 1;
|
||||
raw_debug_p_arr[obj_idx].v = push_array(scratch.arena, String8, 1);
|
||||
raw_debug_p_arr[obj_idx].v[0] = str8_substr(obj->data, debug_p_sect.frange);
|
||||
raw_debug_p_arr[obj_idx].v[0] = lnk_obj_section_data_from_sect_idx(obj, obj->coff.debug_p_sect_idx);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2852,13 +2849,13 @@ THREAD_POOL_TASK_FUNC(lnk_push_dbi_sec_contrib_task)
|
||||
LNK_Obj *obj = task->cv->obj_arr[obj_idx];
|
||||
|
||||
PDB_DbiSCArray *sc_array = &task->sc_arrays[obj_idx];
|
||||
sc_array->v = push_array_no_zero(arena, PDB_DbiSC, obj->header.section_count_no_null);
|
||||
sc_array->cap = obj->header.section_count_no_null;
|
||||
sc_array->v = push_array_no_zero(arena, PDB_DbiSC, obj->coff.sections.count);
|
||||
sc_array->cap = obj->coff.sections.count;
|
||||
|
||||
for EachIndex(sect_idx, obj->header.section_count_no_null) {
|
||||
for EachIndex(sect_idx, obj->coff.sections.count) {
|
||||
|
||||
// filter by section flags
|
||||
if (obj->section_flags[sect_idx] & (COFF_SectionFlag_LnkInfo | COFF_SectionFlag_LnkRemove | LNK_SECTION_FLAG_DEBUG)) { continue; }
|
||||
if (obj->coff.sections.flags[sect_idx] & (COFF_SectionFlag_LnkInfo | COFF_SectionFlag_LnkRemove | LNK_SECTION_FLAG_DEBUG)) { continue; }
|
||||
|
||||
// skip unwind info for the section contribution
|
||||
String8 section_name = lnk_obj_section_name_from_sect_idx(obj, sect_idx);
|
||||
|
||||
+128
-86
@@ -156,6 +156,13 @@ THREAD_POOL_TASK_FUNC(lnk_obj_initer)
|
||||
}
|
||||
}
|
||||
|
||||
String8 *section_data = push_array(arena, String8, header.section_count_no_null);
|
||||
for EachIndex(sect_idx, header.section_count_no_null) {
|
||||
COFF_SectionHeader *sect_header = &coff_section_table[sect_idx];
|
||||
String8 data = str8_substr(input->data, r1u64s(sect_header->foff, sect_header->fsize));
|
||||
section_data[sect_idx] = section_flags[sect_idx] & LNK_SECTION_FLAG_DEBUG ? push_str8_copy(arena, data) : data;
|
||||
}
|
||||
|
||||
//
|
||||
// error check symbol table and cache name lengths for primary symbols
|
||||
//
|
||||
@@ -168,38 +175,46 @@ THREAD_POOL_TASK_FUNC(lnk_obj_initer)
|
||||
}
|
||||
}
|
||||
|
||||
U64 symbol_block_count = CeilIntegerDiv(header.symbol_count, 64);
|
||||
U64 symbol_block_count = CeilIntegerDiv(header.symbol_count, 64);
|
||||
LNK_ObjSymbolArray symbols = {
|
||||
.count = primary_symbol_count,
|
||||
.primary_masks = push_array(arena, U64, symbol_block_count),
|
||||
.block_bases = push_array_no_zero(arena, U32, symbol_block_count),
|
||||
.values = push_array_no_zero(arena, U64, primary_symbol_count),
|
||||
.section_numbers = push_array_no_zero(arena, U32, primary_symbol_count),
|
||||
.types = push_array_no_zero(arena, COFF_SymbolType, primary_symbol_count),
|
||||
.block_bases = push_array_no_zero(arena, U32, symbol_block_count),
|
||||
.values = push_array_no_zero(arena, U64, primary_symbol_count),
|
||||
.section_numbers = push_array_no_zero(arena, U32, primary_symbol_count),
|
||||
.types = push_array_no_zero(arena, COFF_SymbolType, primary_symbol_count),
|
||||
.storage_classes = push_array_no_zero(arena, COFF_SymStorageClass, primary_symbol_count),
|
||||
.aux_counts = push_array_no_zero(arena, U8, primary_symbol_count),
|
||||
.name_offsets = push_array_no_zero(arena, U32, primary_symbol_count),
|
||||
.name_sizes = push_array_no_zero(arena, U32, primary_symbol_count),
|
||||
.aux_counts = push_array_no_zero(arena, U8, primary_symbol_count),
|
||||
.name_offsets = push_array_no_zero(arena, U32, primary_symbol_count),
|
||||
.name_sizes = push_array_no_zero(arena, U32, primary_symbol_count),
|
||||
};
|
||||
{
|
||||
U64 next_block = 0;
|
||||
U64 next_block = 0;
|
||||
U32 primary_idx = 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(header, raw_coff_string_table, raw_coff_symbol_table, symbol_idx);
|
||||
U64 block_idx = symbol_idx >> 6;
|
||||
while (next_block <= block_idx) {
|
||||
symbols.block_bases[next_block++] = primary_idx;
|
||||
|
||||
// copy out primary symbols
|
||||
{
|
||||
U64 block_idx = symbol_idx >> 6;
|
||||
while (next_block <= block_idx) {
|
||||
symbols.block_bases[next_block++] = primary_idx;
|
||||
}
|
||||
|
||||
symbols.primary_masks[block_idx] |= 1ull << (symbol_idx & 63);
|
||||
|
||||
symbols.values [primary_idx] = symbol.value;
|
||||
symbols.section_numbers[primary_idx] = symbol.section_number;
|
||||
symbols.types [primary_idx] = symbol.type;
|
||||
symbols.storage_classes[primary_idx] = symbol.storage_class;
|
||||
symbols.aux_counts [primary_idx] = symbol.aux_symbol_count;
|
||||
symbols.name_offsets [primary_idx] = symbol.name.size ? safe_cast_u32(symbol.name.str - input->data.str) : 0;
|
||||
symbols.name_sizes [primary_idx] = safe_cast_u32(symbol.name.size);
|
||||
primary_idx += 1;
|
||||
}
|
||||
symbols.primary_masks[block_idx] |= 1ull << (symbol_idx & 63);
|
||||
symbols.values[primary_idx] = symbol.value;
|
||||
symbols.section_numbers[primary_idx] = symbol.section_number;
|
||||
symbols.types[primary_idx] = symbol.type;
|
||||
symbols.storage_classes[primary_idx] = symbol.storage_class;
|
||||
symbols.aux_counts[primary_idx] = symbol.aux_symbol_count;
|
||||
symbols.name_offsets[primary_idx] = symbol.name.size ? safe_cast_u32(symbol.name.str - input->data.str) : 0;
|
||||
symbols.name_sizes[primary_idx] = safe_cast_u32(symbol.name.size);
|
||||
primary_idx += 1;
|
||||
|
||||
COFF_SymbolValueInterpType interp = coff_interp_symbol(symbol.section_number, symbol.value, symbol.storage_class);
|
||||
if (interp == COFF_SymbolValueInterp_Regular) {
|
||||
if (symbol.section_number == 0 || symbol.section_number > header.section_count_no_null) {
|
||||
@@ -381,22 +396,28 @@ THREAD_POOL_TASK_FUNC(lnk_obj_initer)
|
||||
}
|
||||
|
||||
// fill out obj
|
||||
obj->data = input->data;
|
||||
obj->coff = (LNK_ObjCoff){
|
||||
.data = input->data,
|
||||
.header = header,
|
||||
.sections = {
|
||||
.count = header.section_count_no_null,
|
||||
.headers = section_headers,
|
||||
.flags = section_flags,
|
||||
.data = section_data,
|
||||
.comdats = comdats,
|
||||
.associations = associated_sections,
|
||||
},
|
||||
.symbols = symbols,
|
||||
.debug_t_sect_idx = debug_t_sect_idx,
|
||||
.debug_p_sect_idx = debug_p_sect_idx,
|
||||
.debug_h_sect_idx = debug_h_sect_idx,
|
||||
.llvm_addrsig_sect_idx = llvm_addrsig_sect_idx,
|
||||
.hotpatch = hotpatch,
|
||||
};
|
||||
obj->path = push_str8_copy(arena, input->path);
|
||||
obj->header = header;
|
||||
obj->section_headers = section_headers;
|
||||
obj->section_flags = section_flags;
|
||||
obj->symbols = symbols;
|
||||
obj->comdats = comdats;
|
||||
obj->exclude_from_debug_info = input->exclude_from_debug_info;
|
||||
obj->hotpatch = hotpatch;
|
||||
obj->associated_sections = associated_sections;
|
||||
obj->self = &task->objs[task_id];
|
||||
obj->link_member = input->link_member;
|
||||
obj->debug_t_sect_idx = debug_t_sect_idx;
|
||||
obj->debug_p_sect_idx = debug_p_sect_idx;
|
||||
obj->debug_h_sect_idx = debug_h_sect_idx;
|
||||
obj->llvm_addrsig_sect_idx = llvm_addrsig_sect_idx;
|
||||
}
|
||||
|
||||
internal LNK_ObjNode *
|
||||
@@ -447,7 +468,7 @@ THREAD_POOL_TASK_FUNC(lnk_input_coff_symbol_table)
|
||||
LNK_InputCoffSymbolTable *task = raw_task;
|
||||
LNK_Obj *obj = task->objs[task_id];
|
||||
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->coff.header.symbol_count; symbol_idx += (1 + symbol.aux_symbol_count)) {
|
||||
symbol = lnk_parsed_symbol_from_coff_symbol_idx_no_name(obj, symbol_idx);
|
||||
COFF_SymbolValueInterpType interp = coff_interp_from_parsed_symbol(symbol);
|
||||
LNK_SymbolSearchType search_type = lnk_symbol_search_type_from_coff(obj, symbol, interp);
|
||||
@@ -493,14 +514,14 @@ THREAD_POOL_TASK_FUNC(lnk_input_coff_symbol_table)
|
||||
internal LNK_ObjSymbolRef *
|
||||
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->coff.sections.count + 1);
|
||||
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->coff.header.symbol_count; symbol_idx += (1 + symbol.aux_symbol_count)) {
|
||||
symbol = lnk_parsed_symbol_from_coff_symbol_idx_no_name(obj, symbol_idx);
|
||||
COFF_SymbolValueInterpType interp = coff_interp_from_parsed_symbol(symbol);
|
||||
if (interp != COFF_SymbolValueInterp_Regular) { continue; }
|
||||
|
||||
COFF_SectionFlags section_flags = obj->section_flags[symbol.section_number - 1];
|
||||
COFF_SectionFlags section_flags = obj->coff.sections.flags[symbol.section_number - 1];
|
||||
if (~section_flags & COFF_SectionFlag_LnkCOMDAT) { continue; }
|
||||
|
||||
LNK_ObjSymbolRef *symlink = &symlinks[symbol.section_number];
|
||||
@@ -556,12 +577,12 @@ lnk_obj_collect_associated_sections(Arena *arena, LNK_Obj *obj, U32 root_section
|
||||
|
||||
// walk the complete descendant chain because associated COMDATs can nest
|
||||
for EachNode(parent_n, U32Node, queue.first) {
|
||||
for EachNode(associated_n, U32Node, obj->associated_sections[parent_n->data]) {
|
||||
for EachNode(associated_n, U32Node, obj->coff.sections.associations[parent_n->data]) {
|
||||
U32 child_section = associated_n->data;
|
||||
|
||||
if (child_section == 0) { continue; }
|
||||
if (hash_map_search_u64_u64(&seen_hm, child_section)) { continue; }
|
||||
if (obj->section_flags[child_section - 1] & skip_flags) { continue; }
|
||||
if (obj->coff.sections.flags[child_section - 1] & skip_flags) { continue; }
|
||||
|
||||
hash_map_push_u64_u64(scratch.arena, &seen_hm, child_section, 1);
|
||||
u32_list_push(arena, &queue, child_section);
|
||||
@@ -610,7 +631,7 @@ internal COFF_ParsedSymbol
|
||||
lnk_obj_match_symbol(LNK_Obj *obj, String8 match_name)
|
||||
{
|
||||
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->coff.header.symbol_count; symbol_idx += (1 + symbol.aux_symbol_count)) {
|
||||
symbol = lnk_parsed_symbol_from_coff_symbol_idx(obj, symbol_idx);
|
||||
if (str8_match(symbol.name, match_name, 0)) {
|
||||
return symbol;
|
||||
@@ -657,7 +678,7 @@ lnk_obj_get_lib_path(LNK_Obj *obj)
|
||||
internal U32
|
||||
lnk_obj_get_removed_section_number(LNK_Obj *obj)
|
||||
{
|
||||
return obj->header.is_big_obj ? LNK_REMOVED_SECTION_NUMBER_32 : LNK_REMOVED_SECTION_NUMBER_16;
|
||||
return obj->coff.header.is_big_obj ? LNK_REMOVED_SECTION_NUMBER_32 : LNK_REMOVED_SECTION_NUMBER_16;
|
||||
}
|
||||
|
||||
internal B32
|
||||
@@ -674,20 +695,42 @@ lnk_obj_get_comdat_symlink(LNK_Obj *obj, U64 section_number, LNK_ObjSymbolRef *s
|
||||
internal COFF_SectionHeader *
|
||||
lnk_coff_section_table_from_obj(LNK_Obj *obj)
|
||||
{
|
||||
return obj->section_headers;
|
||||
return obj->coff.sections.headers;
|
||||
}
|
||||
|
||||
internal String8
|
||||
lnk_obj_section_data_from_sect_idx(LNK_Obj *obj, U64 sect_idx)
|
||||
{
|
||||
Assert(sect_idx < obj->coff.sections.count);
|
||||
return obj->coff.sections.data[sect_idx];
|
||||
}
|
||||
|
||||
internal U64
|
||||
lnk_obj_foff_from_section_data_ptr(LNK_Obj *obj, void *ptr)
|
||||
{
|
||||
U64 ptr_v = IntFromPtr(ptr);
|
||||
for EachIndex(sect_idx, obj->coff.sections.count) {
|
||||
String8 data = obj->coff.sections.data[sect_idx];
|
||||
U64 data_min = IntFromPtr(data.str);
|
||||
if (data_min <= ptr_v && ptr_v < data_min + data.size) {
|
||||
return obj->coff.sections.headers[sect_idx].foff + ptr_v - data_min;
|
||||
}
|
||||
}
|
||||
InvalidPath;
|
||||
return 0;
|
||||
}
|
||||
|
||||
internal U64
|
||||
lnk_obj_sect_idx_from_section_number(LNK_Obj *obj, U64 section_number)
|
||||
{
|
||||
Assert(1 <= section_number && section_number <= obj->header.section_count_no_null);
|
||||
Assert(1 <= section_number && section_number <= obj->coff.sections.count);
|
||||
return section_number-1;
|
||||
}
|
||||
|
||||
internal U64
|
||||
lnk_obj_section_number_from_sect_idx(LNK_Obj *obj, U64 sect_idx)
|
||||
{
|
||||
Assert(sect_idx < obj->header.section_count_no_null);
|
||||
Assert(sect_idx < obj->coff.sections.count);
|
||||
return sect_idx+1;
|
||||
}
|
||||
|
||||
@@ -708,13 +751,13 @@ lnk_obj_section_name_from_section_number(LNK_Obj *obj, U64 section_number)
|
||||
internal LNK_ObjSection
|
||||
lnk_obj_section_from_sect_idx(LNK_Obj *obj, U64 sect_idx)
|
||||
{
|
||||
Assert(sect_idx < obj->header.section_count_no_null);
|
||||
Assert(sect_idx < obj->coff.sections.count);
|
||||
LNK_ObjSection section = {0};
|
||||
section.obj = obj;
|
||||
section.sect_idx = sect_idx;
|
||||
section.section_number = sect_idx+1;
|
||||
section.header = &lnk_coff_section_table_from_obj(obj)[sect_idx];
|
||||
section.flags = &obj->section_flags[sect_idx];
|
||||
section.flags = &obj->coff.sections.flags[sect_idx];
|
||||
section.vrange = rng_1u64(section.header->voff, section.header->voff + section.header->vsize);
|
||||
section.frange = rng_1u64(section.header->foff, section.header->foff + section.header->fsize);
|
||||
section.reloc_count = section.header->reloc_count;
|
||||
@@ -731,8 +774,8 @@ lnk_obj_section_from_section_number(LNK_Obj *obj, U64 section_number)
|
||||
internal COFF_RelocArray
|
||||
lnk_coff_relocs_from_section_header(LNK_Obj *obj, COFF_SectionHeader *section_header)
|
||||
{
|
||||
COFF_RelocInfo reloc_info = coff_reloc_info_from_section_header(obj->data, section_header);
|
||||
COFF_Reloc *relocs = (COFF_Reloc *)(obj->data.str + reloc_info.array_off);
|
||||
COFF_RelocInfo reloc_info = coff_reloc_info_from_section_header(obj->coff.data, section_header);
|
||||
COFF_Reloc *relocs = (COFF_Reloc *)(obj->coff.data.str + reloc_info.array_off);
|
||||
COFF_RelocArray result = { .count = reloc_info.count, .v = relocs };
|
||||
return result;
|
||||
}
|
||||
@@ -740,21 +783,21 @@ lnk_coff_relocs_from_section_header(LNK_Obj *obj, COFF_SectionHeader *section_he
|
||||
internal String8
|
||||
lnk_coff_string_table_from_obj(LNK_Obj *obj)
|
||||
{
|
||||
return str8_substr(obj->data, obj->header.string_table_range);
|
||||
return str8_substr(obj->coff.data, obj->coff.header.string_table_range);
|
||||
}
|
||||
|
||||
internal String8
|
||||
lnk_coff_symbol_table_from_obj(LNK_Obj *obj)
|
||||
{
|
||||
return str8_substr(obj->data, obj->header.symbol_table_range);
|
||||
return str8_substr(obj->coff.data, obj->coff.header.symbol_table_range);
|
||||
}
|
||||
|
||||
internal COFF_RelocArray
|
||||
lnk_coff_reloc_info_from_section_number(LNK_Obj *obj, U64 section_number)
|
||||
{
|
||||
LNK_ObjSection section = lnk_obj_section_from_section_number(obj, section_number);
|
||||
COFF_RelocInfo reloc_info = coff_reloc_info_from_section_header(obj->data, section.header);
|
||||
COFF_Reloc *relocs = str8_deserial_get_raw_ptr(obj->data, reloc_info.array_off, sizeof(*relocs)*reloc_info.count);
|
||||
COFF_RelocInfo reloc_info = coff_reloc_info_from_section_header(obj->coff.data, section.header);
|
||||
COFF_Reloc *relocs = str8_deserial_get_raw_ptr(obj->coff.data, reloc_info.array_off, sizeof(*relocs)*reloc_info.count);
|
||||
COFF_RelocArray result = { .count = reloc_info.count, .v = relocs };
|
||||
return result;
|
||||
}
|
||||
@@ -763,10 +806,10 @@ internal B32
|
||||
lnk_try_comdat_props_from_section_number(LNK_Obj *obj, U32 section_number, COFF_ComdatSelectType *select_out, U32 *section_number_out, U32 *section_length_out, U32 *check_sum_out)
|
||||
{
|
||||
Assert(section_number > 0);
|
||||
U32 symbol_idx = obj->comdats[section_number-1];
|
||||
U32 symbol_idx = obj->coff.sections.comdats[section_number-1];
|
||||
if (symbol_idx != max_U32) {
|
||||
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->coff.header.is_big_obj, select_out, section_number_out, section_length_out, check_sum_out);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
@@ -777,7 +820,7 @@ lnk_coff_section_header_from_section_number(LNK_Obj *obj, U64 section_number)
|
||||
{
|
||||
Assert(section_number > 0);
|
||||
U64 sect_idx = section_number - 1;
|
||||
return &obj->section_headers[sect_idx];
|
||||
return &obj->coff.sections.headers[sect_idx];
|
||||
}
|
||||
|
||||
internal force_inline U64
|
||||
@@ -785,22 +828,22 @@ lnk_obj_primary_symbol_idx_from_coff_symbol_idx(LNK_Obj *obj, U64 symbol_idx)
|
||||
{
|
||||
U64 block_idx = symbol_idx >> 6;
|
||||
U64 bit = 1ull << (symbol_idx & 63);
|
||||
U64 block_mask = obj->symbols.primary_masks[block_idx];
|
||||
U64 block_mask = obj->coff.symbols.primary_masks[block_idx];
|
||||
Assert(block_mask & bit);
|
||||
return obj->symbols.block_bases[block_idx] + count_bits_set64(block_mask & (bit - 1));
|
||||
return obj->coff.symbols.block_bases[block_idx] + count_bits_set64(block_mask & (bit - 1));
|
||||
}
|
||||
|
||||
internal force_inline COFF_ParsedSymbol
|
||||
lnk_parsed_symbol_from_coff_symbol_idx_no_name(LNK_Obj *obj, U64 symbol_idx)
|
||||
{
|
||||
U64 primary_idx = lnk_obj_primary_symbol_idx_from_coff_symbol_idx(obj, symbol_idx);
|
||||
U64 symbol_size = obj->header.is_big_obj ? sizeof(COFF_Symbol32) : sizeof(COFF_Symbol16);
|
||||
U64 symbol_size = obj->coff.header.is_big_obj ? sizeof(COFF_Symbol32) : sizeof(COFF_Symbol16);
|
||||
COFF_ParsedSymbol result = {
|
||||
.value = obj->symbols.values[primary_idx],
|
||||
.section_number = obj->symbols.section_numbers[primary_idx],
|
||||
.type = obj->symbols.types[primary_idx],
|
||||
.storage_class = obj->symbols.storage_classes[primary_idx],
|
||||
.aux_symbol_count = obj->symbols.aux_counts[primary_idx],
|
||||
.value = obj->coff.symbols.values[primary_idx],
|
||||
.section_number = obj->coff.symbols.section_numbers[primary_idx],
|
||||
.type = obj->coff.symbols.types[primary_idx],
|
||||
.storage_class = obj->coff.symbols.storage_classes[primary_idx],
|
||||
.aux_symbol_count = obj->coff.symbols.aux_counts[primary_idx],
|
||||
.raw_symbol = lnk_coff_symbol_table_from_obj(obj).str + symbol_idx * symbol_size,
|
||||
};
|
||||
return result;
|
||||
@@ -810,7 +853,7 @@ internal force_inline String8
|
||||
lnk_symbol_name_from_coff_symbol_idx(LNK_Obj *obj, U64 symbol_idx)
|
||||
{
|
||||
U64 primary_idx = lnk_obj_primary_symbol_idx_from_coff_symbol_idx(obj, symbol_idx);
|
||||
return str8(obj->data.str + obj->symbols.name_offsets[primary_idx], obj->symbols.name_sizes[primary_idx]);
|
||||
return str8(obj->coff.data.str + obj->coff.symbols.name_offsets[primary_idx], obj->coff.symbols.name_sizes[primary_idx]);
|
||||
}
|
||||
|
||||
internal force_inline COFF_ParsedSymbol
|
||||
@@ -826,13 +869,13 @@ lnk_obj_symbol_patch(LNK_Obj *obj, U64 symbol_idx, COFF_ParsedSymbol patch, LNK_
|
||||
{
|
||||
U64 primary_idx = lnk_obj_primary_symbol_idx_from_coff_symbol_idx(obj, symbol_idx);
|
||||
if (flags & LNK_ObjSymbolPatch_Value) {
|
||||
obj->symbols.values[primary_idx] = patch.value;
|
||||
obj->coff.symbols.values[primary_idx] = patch.value;
|
||||
}
|
||||
if (flags & LNK_ObjSymbolPatch_Section) {
|
||||
obj->symbols.section_numbers[primary_idx] = patch.section_number;
|
||||
obj->coff.symbols.section_numbers[primary_idx] = patch.section_number;
|
||||
}
|
||||
if (flags & LNK_ObjSymbolPatch_StorageClass) {
|
||||
obj->symbols.storage_classes[primary_idx] = patch.storage_class;
|
||||
obj->coff.symbols.storage_classes[primary_idx] = patch.storage_class;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -842,7 +885,7 @@ THREAD_POOL_TASK_FUNC(lnk_collect_obj_chunks_task)
|
||||
LNK_SectionCollector *task = raw_task;
|
||||
LNK_Obj *obj = task->objs[task_id];
|
||||
|
||||
for EachIndex(sect_idx, obj->header.section_count_no_null) {
|
||||
for EachIndex(sect_idx, obj->coff.sections.count) {
|
||||
LNK_ObjSection section = lnk_obj_section_from_sect_idx(obj, sect_idx);
|
||||
|
||||
if (*section.flags & COFF_SectionFlag_LnkRemove && !task->collect_discarded) {
|
||||
@@ -851,7 +894,7 @@ THREAD_POOL_TASK_FUNC(lnk_collect_obj_chunks_task)
|
||||
|
||||
String8 section_name = lnk_obj_section_name_from_sect_idx(obj, sect_idx);
|
||||
if (str8_match(section_name, task->name, 0)) {
|
||||
String8 section_data = str8_substr(obj->data, section.frange);
|
||||
String8 section_data = lnk_obj_section_data_from_sect_idx(obj, sect_idx);
|
||||
str8_list_push(arena, &task->out_lists[task_id], section_data);
|
||||
}
|
||||
}
|
||||
@@ -927,7 +970,7 @@ internal String8List
|
||||
lnk_raw_directives_from_obj(Arena *arena, LNK_Obj *obj)
|
||||
{
|
||||
String8List drectve_data = {0};
|
||||
for (U64 sect_idx = 0; sect_idx < obj->header.section_count_no_null; sect_idx += 1) {
|
||||
for (U64 sect_idx = 0; sect_idx < obj->coff.sections.count; sect_idx += 1) {
|
||||
LNK_ObjSection section = lnk_obj_section_from_sect_idx(obj, sect_idx);
|
||||
if (*section.flags & COFF_SectionFlag_LnkInfo) {
|
||||
String8 section_name = lnk_obj_section_name_from_sect_idx(obj, sect_idx);
|
||||
@@ -944,7 +987,7 @@ lnk_raw_directives_from_obj(Arena *arena, LNK_Obj *obj)
|
||||
lnk_error_obj(LNK_Error_IllData, obj, ".drectve must not have relocations");
|
||||
break;
|
||||
}
|
||||
str8_list_push(arena, &drectve_data, str8_substr(obj->data, section.frange));
|
||||
str8_list_push(arena, &drectve_data, lnk_obj_section_data_from_sect_idx(obj, sect_idx));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -977,7 +1020,7 @@ lnk_symbol_map_from_obj(Arena *arena, LNK_Obj *obj)
|
||||
// count functions
|
||||
U64 count = 0;
|
||||
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->coff.header.symbol_count; symbol_idx += 1 + symbol.aux_symbol_count) {
|
||||
symbol = lnk_parsed_symbol_from_coff_symbol_idx_no_name(obj, symbol_idx);
|
||||
if (coff_interp_from_parsed_symbol(symbol) == COFF_SymbolValueInterp_Regular && COFF_SymbolType_IsFunc(symbol.type)) {
|
||||
count += 1;
|
||||
@@ -988,7 +1031,7 @@ lnk_symbol_map_from_obj(Arena *arena, LNK_Obj *obj)
|
||||
map->v = push_array_no_zero(arena, LNK_SectionOffsetSymbol, count);
|
||||
|
||||
U64 map_idx = 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->coff.header.symbol_count; symbol_idx += 1 + symbol.aux_symbol_count) {
|
||||
symbol = lnk_parsed_symbol_from_coff_symbol_idx_no_name(obj, symbol_idx);
|
||||
if (coff_interp_from_parsed_symbol(symbol) == COFF_SymbolValueInterp_Regular && COFF_SymbolType_IsFunc(symbol.type)) {
|
||||
LNK_SectionOffsetSymbol *entry = &map->v[map->count++];
|
||||
@@ -1036,11 +1079,11 @@ lnk_debug_s_from_obj(Arena *arena, LNK_Obj *obj)
|
||||
|
||||
String8List raw_debug_s = {0};
|
||||
{
|
||||
for EachIndex(sect_idx, obj->header.section_count_no_null) {
|
||||
for EachIndex(sect_idx, obj->coff.sections.count) {
|
||||
LNK_ObjSection section = lnk_obj_section_from_sect_idx(obj, sect_idx);
|
||||
String8 section_name = lnk_obj_section_name_from_sect_idx(obj, sect_idx);
|
||||
if (str8_match(section_name, str8_lit(".debug$S"), 0)) {
|
||||
String8 debug_s = str8_substr(obj->data, section.frange);
|
||||
String8 debug_s = lnk_obj_section_data_from_sect_idx(obj, sect_idx);
|
||||
str8_list_push(scratch.arena, &raw_debug_s, debug_s);
|
||||
}
|
||||
}
|
||||
@@ -1099,11 +1142,11 @@ lnk_line_map_from_obj(Arena *arena, LNK_Obj *obj)
|
||||
//
|
||||
#define DebugRelocValueFromFileOffset(foff) hash_map_search_u64_u64(&debug_reloc_hm, foff)
|
||||
HashMap debug_reloc_hm = {0};
|
||||
for EachIndex(sect_idx, obj->header.section_count_no_null) {
|
||||
for EachIndex(sect_idx, obj->coff.sections.count) {
|
||||
LNK_ObjSection section = lnk_obj_section_from_sect_idx(obj, sect_idx);
|
||||
if (!str8_match(lnk_obj_section_name_from_sect_idx(obj, sect_idx), str8_lit(".debug$S"), 0)) { continue; }
|
||||
|
||||
String8 section_data = str8_substr(obj->data, section.frange);
|
||||
String8 section_data = lnk_obj_section_data_from_sect_idx(obj, sect_idx);
|
||||
COFF_RelocArray relocs = lnk_coff_relocs_from_section_header(obj, section.header);
|
||||
for EachIndex(reloc_idx, relocs.count) {
|
||||
COFF_Reloc *reloc = &relocs.v[reloc_idx];
|
||||
@@ -1112,12 +1155,12 @@ lnk_line_map_from_obj(Arena *arena, LNK_Obj *obj)
|
||||
|
||||
U64 reloc_size = 0;
|
||||
U64 reloc_value = 0;
|
||||
if ((obj->header.machine == COFF_MachineType_X64 && reloc->type == COFF_Reloc_X64_Section) ||
|
||||
(obj->header.machine == COFF_MachineType_X86 && reloc->type == COFF_Reloc_X86_Section)) {
|
||||
if ((obj->coff.header.machine == COFF_MachineType_X64 && reloc->type == COFF_Reloc_X64_Section) ||
|
||||
(obj->coff.header.machine == COFF_MachineType_X86 && reloc->type == COFF_Reloc_X86_Section)) {
|
||||
reloc_size = sizeof(U16);
|
||||
reloc_value = symbol.section_number;
|
||||
} else if ((obj->header.machine == COFF_MachineType_X64 && reloc->type == COFF_Reloc_X64_SecRel) ||
|
||||
(obj->header.machine == COFF_MachineType_X86 && reloc->type == COFF_Reloc_X86_SecRel)) {
|
||||
} else if ((obj->coff.header.machine == COFF_MachineType_X64 && reloc->type == COFF_Reloc_X64_SecRel) ||
|
||||
(obj->coff.header.machine == COFF_MachineType_X86 && reloc->type == COFF_Reloc_X86_SecRel)) {
|
||||
reloc_size = sizeof(U32);
|
||||
reloc_value = symbol.value;
|
||||
}
|
||||
@@ -1174,7 +1217,7 @@ lnk_line_map_from_obj(Arena *arena, LNK_Obj *obj)
|
||||
// resovle lines header
|
||||
{
|
||||
CV_C13LinesHeader *header = block->header;
|
||||
U64 header_foff = (U64)(raw_lines.str - obj->data.str) + header->header_off;
|
||||
U64 header_foff = lnk_obj_foff_from_section_data_ptr(obj, raw_lines.str) + header->header_off;
|
||||
|
||||
U64 *sec_off = DebugRelocValueFromFileOffset(header_foff + OffsetOf(CV_C13SubSecLinesHeader, sec_off));
|
||||
if (sec_off) {
|
||||
@@ -1223,9 +1266,8 @@ lnk_line_map_from_obj(Arena *arena, LNK_Obj *obj)
|
||||
// build inlinee id -> inlinee name
|
||||
//
|
||||
HashMap inlinee_hm = {0};
|
||||
if (obj->debug_t_sect_idx < obj->header.section_count_no_null) {
|
||||
LNK_ObjSection debug_t_section = lnk_obj_section_from_sect_idx(obj, obj->debug_t_sect_idx);
|
||||
String8 raw_debug_t = str8_substr(obj->data, debug_t_section.frange);
|
||||
if (obj->coff.debug_t_sect_idx < obj->coff.sections.count) {
|
||||
String8 raw_debug_t = lnk_obj_section_data_from_sect_idx(obj, obj->coff.debug_t_sect_idx);
|
||||
CV_Signature debug_t_sig = cv_signature_from_debug_s(raw_debug_t);
|
||||
if (debug_t_sig == CV_Signature_C13) {
|
||||
CV_DebugT debug_t = cv_debug_t_from_data(scratch.arena, str8_skip(raw_debug_t, sizeof(CV_Signature)), CV_LeafAlign);
|
||||
@@ -1304,7 +1346,7 @@ lnk_line_map_from_obj(Arena *arena, LNK_Obj *obj)
|
||||
if (CV_IsProc32(symbol.kind)) {
|
||||
CV_SymProc32 *proc = str8_deserial_get_raw_ptr(symbol.data, 0, sizeof(*proc));
|
||||
if (proc) {
|
||||
U64 proc_foff = IntFromPtr(symbol.data.str - obj->data.str);
|
||||
U64 proc_foff = lnk_obj_foff_from_section_data_ptr(obj, symbol.data.str);
|
||||
U64 *off_reloc = DebugRelocValueFromFileOffset(proc_foff + OffsetOf(CV_SymProc32, off));
|
||||
U64 *sec_reloc = DebugRelocValueFromFileOffset(proc_foff + OffsetOf(CV_SymProc32, sec));
|
||||
proc_offset = off_reloc ? safe_cast_u32(*off_reloc) : proc->off;
|
||||
|
||||
+42
-32
@@ -5,20 +5,6 @@
|
||||
|
||||
// --- Input -------------------------------------------------------------------
|
||||
|
||||
typedef struct LNK_ObjSymbolArray
|
||||
{
|
||||
U64 count;
|
||||
U64 *primary_masks;
|
||||
U32 *block_bases;
|
||||
U64 *values;
|
||||
U32 *section_numbers;
|
||||
COFF_SymbolType *types;
|
||||
COFF_SymStorageClass *storage_classes;
|
||||
U8 *aux_counts;
|
||||
U32 *name_offsets;
|
||||
U32 *name_sizes;
|
||||
} LNK_ObjSymbolArray;
|
||||
|
||||
typedef U32 LNK_ObjSymbolPatchFlags;
|
||||
enum
|
||||
{
|
||||
@@ -27,39 +13,61 @@ enum
|
||||
LNK_ObjSymbolPatch_StorageClass = (1 << 2),
|
||||
};
|
||||
|
||||
typedef struct LNK_ObjSymbolArray
|
||||
{
|
||||
U64 count;
|
||||
U64 *primary_masks;
|
||||
U32 *block_bases;
|
||||
U64 *values;
|
||||
U32 *section_numbers;
|
||||
COFF_SymbolType *types;
|
||||
COFF_SymStorageClass *storage_classes;
|
||||
U8 *aux_counts;
|
||||
U32 *name_offsets;
|
||||
U32 *name_sizes;
|
||||
} LNK_ObjSymbolArray;
|
||||
|
||||
typedef struct LNK_ObjSectionArray
|
||||
{
|
||||
U64 count;
|
||||
COFF_SectionHeader *headers;
|
||||
COFF_SectionFlags *flags;
|
||||
String8 *data;
|
||||
U32 *comdats;
|
||||
U32Node **associations;
|
||||
} LNK_ObjSectionArray;
|
||||
|
||||
typedef struct LNK_ObjCoff
|
||||
{
|
||||
String8 data;
|
||||
COFF_FileHeaderInfo header;
|
||||
LNK_ObjSectionArray sections;
|
||||
LNK_ObjSymbolArray symbols;
|
||||
U32 debug_t_sect_idx;
|
||||
U32 debug_p_sect_idx;
|
||||
U32 debug_h_sect_idx;
|
||||
U32 llvm_addrsig_sect_idx;
|
||||
B8 hotpatch;
|
||||
} LNK_ObjCoff;
|
||||
|
||||
typedef struct LNK_Obj
|
||||
{
|
||||
String8 path;
|
||||
String8 data;
|
||||
|
||||
COFF_FileHeaderInfo header;
|
||||
COFF_SectionHeader *section_headers;
|
||||
COFF_SectionFlags *section_flags;
|
||||
LNK_ObjSymbolArray symbols;
|
||||
LNK_ObjCoff coff;
|
||||
|
||||
// flags
|
||||
B8 hotpatch;
|
||||
B8 exclude_from_debug_info;
|
||||
|
||||
U32 input_idx;
|
||||
|
||||
// COMDAT
|
||||
U32 *comdats;
|
||||
U32Node **associated_sections;
|
||||
LNK_ObjSymbolRef *symlinks;
|
||||
// link state
|
||||
LNK_ObjSymbolRef *symlinks;
|
||||
|
||||
// link
|
||||
struct LNK_LibMemberRef *link_member;
|
||||
struct LNK_ObjNode *self;
|
||||
|
||||
// type info
|
||||
U32 debug_t_sect_idx;
|
||||
U32 debug_p_sect_idx;
|
||||
U32 debug_h_sect_idx;
|
||||
|
||||
// ICF
|
||||
U32 llvm_addrsig_sect_idx;
|
||||
|
||||
// @type_server
|
||||
Rng1U64 ti_range;
|
||||
CV_TypeIndex *ti_map;
|
||||
@@ -242,6 +250,8 @@ internal force_inline String8 lnk_symbol_name_from_coff_symbol_idx(LNK
|
||||
internal void lnk_obj_symbol_patch(LNK_Obj *obj, U64 symbol_idx, COFF_ParsedSymbol patch, LNK_ObjSymbolPatchFlags flags);
|
||||
|
||||
internal COFF_SectionHeader * lnk_coff_section_header_from_section_number(LNK_Obj *obj, U64 section_number);
|
||||
internal String8 lnk_obj_section_data_from_sect_idx(LNK_Obj *obj, U64 sect_idx);
|
||||
internal U64 lnk_obj_foff_from_section_data_ptr(LNK_Obj *obj, void *ptr);
|
||||
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 String8 lnk_obj_section_name_from_section_number(LNK_Obj *obj, U64 section_number);
|
||||
|
||||
@@ -10,7 +10,7 @@ lnk_symbol_search_type_from_coff(LNK_Obj *obj, COFF_ParsedSymbol symbol, COFF_Sy
|
||||
if (interp == COFF_SymbolValueInterp_Undefined) {
|
||||
search_type = LNK_SymbolSearch_Undefined;
|
||||
} else if (interp == COFF_SymbolValueInterp_Weak) {
|
||||
COFF_SymbolWeakExt *weak_ext = coff_parse_weak_tag(symbol, obj->header.is_big_obj);
|
||||
COFF_SymbolWeakExt *weak_ext = coff_parse_weak_tag(symbol, obj->coff.header.is_big_obj);
|
||||
switch (weak_ext->characteristics) {
|
||||
case COFF_WeakExt_SearchLibrary: search_type = LNK_SymbolSearch_WeakLibrary; break;
|
||||
case COFF_WeakExt_AntiDependency: search_type = LNK_SymbolSearch_WeakAntiDependency; break;
|
||||
@@ -179,7 +179,7 @@ lnk_can_replace_symbol(LNK_Symbol *dst, LNK_Symbol *src)
|
||||
}
|
||||
|
||||
LNK_ObjSymbolRef weak_symbol_ref = lnk_ref_from_symbol(weak);
|
||||
COFF_SymbolWeakExt *weak_ext = coff_parse_weak_tag(weak_parsed, weak_symbol_ref.obj->header.is_big_obj);
|
||||
COFF_SymbolWeakExt *weak_ext = coff_parse_weak_tag(weak_parsed, weak_symbol_ref.obj->coff.header.is_big_obj);
|
||||
if (weak_ext->characteristics == COFF_WeakExt_SearchLibrary) {
|
||||
// NOTE: MSVC does not let a weak symbol to replace an undefined one,
|
||||
// but LLD links without errors or warnings, meaning undefined symbols
|
||||
@@ -242,8 +242,8 @@ lnk_can_replace_symbol(LNK_Symbol *dst, LNK_Symbol *src)
|
||||
}
|
||||
// weak vs weak
|
||||
else if (dst_interp == COFF_SymbolValueInterp_Weak && src_interp == COFF_SymbolValueInterp_Weak) {
|
||||
COFF_SymbolWeakExt *dst_ext = coff_parse_weak_tag(dst_parsed, dst_ref.obj->header.is_big_obj);
|
||||
COFF_SymbolWeakExt *src_ext = coff_parse_weak_tag(src_parsed, src_ref.obj->header.is_big_obj);
|
||||
COFF_SymbolWeakExt *dst_ext = coff_parse_weak_tag(dst_parsed, dst_ref.obj->coff.header.is_big_obj);
|
||||
COFF_SymbolWeakExt *src_ext = coff_parse_weak_tag(src_parsed, src_ref.obj->coff.header.is_big_obj);
|
||||
if ((dst_ext->characteristics == COFF_WeakExt_SearchAlias && src_ext->characteristics != COFF_WeakExt_SearchAlias)) {
|
||||
if (lnk_symbol_is_before(dst, src) || src_ext->characteristics == COFF_WeakExt_AntiDependency) {
|
||||
can_replace = 0;
|
||||
@@ -342,8 +342,8 @@ lnk_can_replace_symbol(LNK_Symbol *dst, LNK_Symbol *src)
|
||||
case COFF_ComdatSelect_ExactMatch: {
|
||||
LNK_ObjSection dst_section = lnk_obj_section_from_section_number(dst_obj, dst_parsed.section_number);
|
||||
LNK_ObjSection src_section = lnk_obj_section_from_section_number(src_obj, src_parsed.section_number);
|
||||
String8 dst_data = str8_substr(dst_obj->data, dst_section.frange);
|
||||
String8 src_data = str8_substr(src_obj->data, src_section.frange);
|
||||
String8 dst_data = lnk_obj_section_data_from_sect_idx(dst_obj, dst_section.sect_idx);
|
||||
String8 src_data = lnk_obj_section_data_from_sect_idx(src_obj, src_section.sect_idx);
|
||||
|
||||
B32 is_exact_match = 0;
|
||||
if (dst_check_sum != 0 && src_check_sum != 0) {
|
||||
@@ -396,7 +396,7 @@ lnk_on_symbol_replace(LNK_Symbol *dst, LNK_Symbol *src)
|
||||
*dst_section.flags |= COFF_SectionFlag_LnkRemove;
|
||||
|
||||
// remove associated sections from the output
|
||||
for (U32Node *associated_section = dst_ref.obj->associated_sections[dst_parsed.section_number];
|
||||
for (U32Node *associated_section = dst_ref.obj->coff.sections.associations[dst_parsed.section_number];
|
||||
associated_section != 0;
|
||||
associated_section = associated_section->next) {
|
||||
LNK_ObjSection section = lnk_obj_section_from_section_number(dst_ref.obj, associated_section->data);
|
||||
@@ -728,7 +728,7 @@ lnk_resolve_weak_symbol(LNK_SymbolTable *symtab, LNK_ObjSymbolRef symbol, LNK_Ob
|
||||
break;
|
||||
}
|
||||
|
||||
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->coff.header.is_big_obj);
|
||||
|
||||
// no definition -- fallback to default symbol
|
||||
COFF_ParsedSymbol tag_parsed = lnk_parsed_symbol_from_coff_symbol_idx_no_name(current_symbol.obj, weak_ext->tag_index);
|
||||
|
||||
@@ -5881,8 +5881,12 @@ TEST(debug_p_sig_mismatch)
|
||||
T_Ok(t_write_file(str8_lit("b.obj"), b_obj));
|
||||
T_Ok(t_write_entry_obj());
|
||||
|
||||
t_invoke_linkerf("/subsystem:console /entry:entry /out:a.exe /debug:full a.obj b.obj entry.obj");
|
||||
String8 a_obj_before = t_read_file(arena, str8_lit("a.obj"));
|
||||
String8 b_obj_before = t_read_file(arena, str8_lit("b.obj"));
|
||||
t_invoke_linkerf("/RAD_MEMORY_MAP_FILES:READ_WRITE /subsystem:console /entry:entry /out:a.exe /debug:full a.obj b.obj entry.obj");
|
||||
T_Ok(g_last_exit_code == 0);
|
||||
T_Ok(str8_match(a_obj_before, t_read_file(arena, str8_lit("a.obj")), 0));
|
||||
T_Ok(str8_match(b_obj_before, t_read_file(arena, str8_lit("b.obj")), 0));
|
||||
|
||||
B32 found_error = 0;
|
||||
String8 a_obj_path = t_make_file_path(arena, str8_lit("a.obj"));
|
||||
@@ -6271,8 +6275,14 @@ TEST(gen_rrt)
|
||||
t_invoke_linkerf("/subsystem:console /entry:entry /out:a.exe /debug:full /rad_type_server:foo.rrt a.obj b.obj entry.obj");
|
||||
T_Ok(g_last_exit_code == 0);
|
||||
|
||||
t_invoke_linkerf("/subsystem:console /entry:entry /out:a.exe /debug:ghash a.obj foo.rrt b.obj entry.obj");
|
||||
String8 a_obj_before = t_read_file(arena, a_obj_file_path);
|
||||
String8 b_obj_before = t_read_file(arena, b_obj_file_path);
|
||||
String8 rrt_before = t_read_file(arena, str8_lit("foo.rrt"));
|
||||
t_invoke_linkerf("/RAD_MEMORY_MAP_FILES:READ_WRITE /subsystem:console /entry:entry /out:a.exe /debug:ghash a.obj foo.rrt b.obj entry.obj");
|
||||
T_Ok(g_last_exit_code == 0);
|
||||
T_Ok(str8_match(a_obj_before, t_read_file(arena, a_obj_file_path), 0));
|
||||
T_Ok(str8_match(b_obj_before, t_read_file(arena, b_obj_file_path), 0));
|
||||
T_Ok(str8_match(rrt_before, t_read_file(arena, str8_lit("foo.rrt")), 0));
|
||||
}
|
||||
|
||||
TEST(debug_p_and_debug_t_in_obj)
|
||||
|
||||
Reference in new issue
Block a user