centralize section header reads and writes

This commit is contained in:
Nikita Smith
2026-06-12 11:40:03 -07:00
parent 42cf820972
commit 9ce6b9504b
4 changed files with 126 additions and 90 deletions
+30 -34
View File
@@ -65,9 +65,9 @@ THREAD_POOL_TASK_FUNC(lnk_parse_debug_h_task)
LNK_Obj *obj = task->obj_arr[obj_idx]; LNK_Obj *obj = task->obj_arr[obj_idx];
if (obj->debug_h_sect_idx < obj->header.section_count_no_null) { if (obj->debug_h_sect_idx < obj->header.section_count_no_null) {
COFF_SectionHeader *sect_header = lnk_coff_section_header_from_section_number(obj, obj->debug_h_sect_idx + 1); LNK_ObjSection section = lnk_obj_section_from_sect_idx(obj, obj->debug_h_sect_idx);
String8 raw_debug_h = str8_substr(obj->data, r1u64(sect_header->foff, sect_header->foff + sect_header->fsize)); String8 raw_debug_h = str8_substr(obj->data, section.frange);
CV_DebugH *debug_h = &task->debug_h_arr[obj_idx]; CV_DebugH *debug_h = &task->debug_h_arr[obj_idx];
LLVM_GHash ghash = {0}; LLVM_GHash ghash = {0};
U64 ghash_read_size = str8_deserial_read_struct(raw_debug_h, 0, &ghash); U64 ghash_read_size = str8_deserial_read_struct(raw_debug_h, 0, &ghash);
@@ -706,17 +706,14 @@ 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; } 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) { if (obj->debug_t_sect_idx < obj->header.section_count_no_null) {
COFF_SectionHeader *section_table = lnk_coff_section_table_from_obj(obj); total_debug_t_size += lnk_obj_section_from_sect_idx(obj, obj->debug_t_sect_idx).header->fsize;
total_debug_t_size += section_table[obj->debug_t_sect_idx].fsize;
} }
if (obj->debug_p_sect_idx < obj->header.section_count_no_null) { if (obj->debug_p_sect_idx < obj->header.section_count_no_null) {
COFF_SectionHeader *section_table = lnk_coff_section_table_from_obj(obj); total_debug_p_size += lnk_obj_section_from_sect_idx(obj, obj->debug_p_sect_idx).header->fsize;
total_debug_p_size += section_table[obj->debug_p_sect_idx].fsize;
} }
if (config->ghash) { if (config->ghash) {
if (obj->debug_h_sect_idx < obj->header.section_count_no_null) { if (obj->debug_h_sect_idx < obj->header.section_count_no_null) {
COFF_SectionHeader *section_table = lnk_coff_section_table_from_obj(obj); total_debug_h_size += lnk_obj_section_from_sect_idx(obj, obj->debug_h_sect_idx).header->fsize;
total_debug_h_size += section_table[obj->debug_h_sect_idx].fsize;
} }
} }
} }
@@ -757,16 +754,16 @@ lnk_make_code_view_input(TP_Context *tp, TP_Arena *tp_arena, LNK_Config *config,
LNK_Obj *obj = obj_arr[obj_idx]; LNK_Obj *obj = obj_arr[obj_idx];
if (obj->debug_t_sect_idx < obj->header.section_count_no_null) { if (obj->debug_t_sect_idx < obj->header.section_count_no_null) {
COFF_SectionHeader *debug_t_hdr = &lnk_coff_section_table_from_obj(obj)[obj->debug_t_sect_idx]; LNK_ObjSection section = lnk_obj_section_from_sect_idx(obj, obj->debug_t_sect_idx);
raw_debug_t_arr[obj_idx].count = 1; 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 = push_array(scratch.arena, String8, 1);
raw_debug_t_arr[obj_idx].v[0] = str8_substr(obj->data, r1u64(debug_t_hdr->foff, debug_t_hdr->foff + debug_t_hdr->fsize)); raw_debug_t_arr[obj_idx].v[0] = str8_substr(obj->data, section.frange);
} }
if (obj->debug_p_sect_idx < obj->header.section_count_no_null) { if (obj->debug_p_sect_idx < obj->header.section_count_no_null) {
COFF_SectionHeader *debug_p_hdr = &lnk_coff_section_table_from_obj(obj)[obj->debug_p_sect_idx]; LNK_ObjSection section = lnk_obj_section_from_sect_idx(obj, obj->debug_p_sect_idx);
raw_debug_p_arr[obj_idx].count = 1; 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 = push_array(scratch.arena, String8, 1);
raw_debug_p_arr[obj_idx].v[0] = str8_substr(obj->data, r1u64(debug_p_hdr->foff, debug_p_hdr->foff + debug_p_hdr->fsize)); raw_debug_p_arr[obj_idx].v[0] = str8_substr(obj->data, section.frange);
} }
} }
@@ -3044,42 +3041,41 @@ THREAD_POOL_TASK_FUNC(lnk_push_dbi_sec_contrib_task)
PDB_DbiModule *mod = task->mod_arr [obj_idx]; PDB_DbiModule *mod = task->mod_arr [obj_idx];
LNK_Obj *obj = task->cv->obj_arr[obj_idx]; LNK_Obj *obj = task->cv->obj_arr[obj_idx];
COFF_SectionHeader *obj_section_table = (COFF_SectionHeader *)str8_substr(obj->data, obj->header.section_table_range).str; PDB_DbiSectionContribNode *sc_arr = push_array_no_zero(arena, PDB_DbiSectionContribNode, obj->header.section_count_no_null);
PDB_DbiSectionContribNode *sc_arr = push_array_no_zero(arena, PDB_DbiSectionContribNode, obj->header.section_count_no_null); U64 sc_count = 0;
U64 sc_count = 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->header.section_count_no_null; sect_idx += 1) {
COFF_SectionHeader *obj_sect_header = &obj_section_table[sect_idx]; LNK_ObjSection section = lnk_obj_section_from_sect_idx(obj, sect_idx);
COFF_SectionFlags obj_sect_flags = obj->section_flags[sect_idx];
if (obj_sect_flags & COFF_SectionFlag_LnkInfo) { continue; } if (*section.flags & COFF_SectionFlag_LnkInfo) { continue; }
if (obj_sect_flags & COFF_SectionFlag_LnkRemove) { continue; } if (*section.flags & COFF_SectionFlag_LnkRemove) { continue; }
if (obj_sect_flags & LNK_SECTION_FLAG_DEBUG) { continue; } if (*section.flags & LNK_SECTION_FLAG_DEBUG) { continue; }
String8 header_name = str8_cstring_capped(obj_sect_header->name, obj_sect_header->name + sizeof(obj_sect_header->name)); if (str8_match(section.name, str8_lit(".pdata"), 0)) { continue; }
if (str8_match(header_name, str8_lit(".pdata"), 0)) { continue; }
U64 sect_number; U64 sect_number;
String8 sect_data; String8 sect_data;
U32 sect_off; U32 sect_off;
U32 data_crc; U32 data_crc;
if (obj_sect_flags & COFF_SectionFlag_CntUninitializedData) { if (*section.flags & COFF_SectionFlag_CntUninitializedData) {
if (obj_sect_header->vsize == 0) { continue; } if (dim_1u64(section.vrange) == 0) { continue; }
U64 sect_num = rng1u64_array_num_from_value__binary_search(&task->image_section_virt_ranges, obj_sect_header->voff); U64 search_result = rng1u64_array_num_from_value__binary_search(&task->image_section_virt_ranges, section.vrange.min);
sect_number = sect_num-1; sect_number = search_result-1;
Assert(sect_number < task->image_section_virt_ranges.count); Assert(sect_number < task->image_section_virt_ranges.count);
sect_data = str8_zero(); sect_data = str8_zero();
sect_off = obj_sect_header->voff - task->image_section_virt_ranges.v[sect_number].min; sect_off = section.vrange.min - task->image_section_virt_ranges.v[sect_number].min;
data_crc = 0; data_crc = 0;
} else { } else {
if (obj_sect_header->fsize == 0) { continue; } if (dim_1u64(section.frange) == 0) { continue; }
U64 sect_num = rng1u64_array_num_from_value__binary_search(&task->image_section_file_ranges, obj_sect_header->foff); U64 search_result = rng1u64_array_num_from_value__binary_search(&task->image_section_file_ranges, section.frange.min);
sect_number = sect_num-1; sect_number = search_result-1;
Assert(sect_number < task->image_section_file_ranges.count); Assert(sect_number < task->image_section_file_ranges.count);
sect_data = str8_substr(task->image_data, rng_1u64(obj_sect_header->foff, obj_sect_header->foff + obj_sect_header->fsize));
sect_off = obj_sect_header->foff - task->image_section_file_ranges.v[sect_number].min; sect_data = str8_substr(task->image_data, section.frange);
sect_off = section.frange.min - task->image_section_file_ranges.v[sect_number].min;
data_crc = update_crc32(0, sect_data.str, sect_data.size); data_crc = update_crc32(0, sect_data.str, sect_data.size);
} }
@@ -3088,8 +3084,8 @@ THREAD_POOL_TASK_FUNC(lnk_push_dbi_sec_contrib_task)
sc->data.base.sec = (U16)sect_number; sc->data.base.sec = (U16)sect_number;
sc->data.base.pad0 = 0; sc->data.base.pad0 = 0;
sc->data.base.sec_off = sect_off; sc->data.base.sec_off = sect_off;
sc->data.base.size = obj_sect_header->vsize; sc->data.base.size = dim_1u64(section.vrange);
sc->data.base.flags = obj_sect_flags; sc->data.base.flags = *section.flags;
sc->data.base.mod = mod->imod; sc->data.base.mod = mod->imod;
sc->data.base.pad1 = 0; sc->data.base.pad1 = 0;
sc->data.data_crc = 0; sc->data.data_crc = 0;
+66 -46
View File
@@ -350,15 +350,13 @@ internal
THREAD_POOL_TASK_FUNC(lnk_obj_find_debug_t) THREAD_POOL_TASK_FUNC(lnk_obj_find_debug_t)
{ {
LNK_Obj *obj = &((LNK_ObjNode *)raw_task)[task_id].data; LNK_Obj *obj = &((LNK_ObjNode *)raw_task)[task_id].data;
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->header.section_count_no_null) {
COFF_SectionHeader *sect_header = &section_table[sect_idx]; LNK_ObjSection section = lnk_obj_section_from_sect_idx(obj, sect_idx);
String8 sect_name = coff_name_from_section_header(str8_zero(), sect_header); if (str8_match(section.name, str8_lit(".debug$T"), 0)) {
if (str8_match(sect_name, str8_lit(".debug$T"), 0)) {
obj->debug_t_sect_idx = sect_idx; obj->debug_t_sect_idx = sect_idx;
} else if (str8_match(sect_name, str8_lit(".debug$P"), 0)) { } else if (str8_match(section.name, str8_lit(".debug$P"), 0)) {
obj->debug_p_sect_idx = sect_idx; obj->debug_p_sect_idx = sect_idx;
} else if (str8_match(sect_name, str8_lit(".debug$H"), 0)) { } else if (str8_match(section.name, str8_lit(".debug$H"), 0)) {
obj->debug_h_sect_idx = sect_idx; obj->debug_h_sect_idx = sect_idx;
} }
} }
@@ -417,7 +415,8 @@ THREAD_POOL_TASK_FUNC(lnk_input_coff_symbol_table)
switch (interp) { switch (interp) {
case COFF_SymbolValueInterp_Regular: { case COFF_SymbolValueInterp_Regular: {
if (symbol.storage_class == COFF_SymStorageClass_External) { if (symbol.storage_class == COFF_SymStorageClass_External) {
if (obj->section_flags[symbol.section_number-1] & COFF_SectionFlag_LnkRemove) { LNK_ObjSection section = lnk_obj_section_from_section_number(obj, symbol.section_number);
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, symbol.name, obj, symbol_idx);
@@ -461,7 +460,8 @@ lnk_symlinks_from_obj(Arena *arena, LNK_SymbolTable *symtab, LNK_Obj *obj)
symbol = lnk_parsed_symbol_from_coff_symbol_idx(obj, symbol_idx); symbol = lnk_parsed_symbol_from_coff_symbol_idx(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 && symbol.aux_symbol_count == 0 && symbol.storage_class == COFF_SymStorageClass_External) { if (interp == COFF_SymbolValueInterp_Regular && symbol.aux_symbol_count == 0 && symbol.storage_class == COFF_SymStorageClass_External) {
if (obj->section_flags[symbol.section_number-1] & COFF_SectionFlag_LnkCOMDAT) { LNK_ObjSection section = lnk_obj_section_from_section_number(obj, symbol.section_number);
if (*section.flags & COFF_SectionFlag_LnkCOMDAT) {
if (symlinks[symbol.section_number] == 0 || symbol.value == 0) { if (symlinks[symbol.section_number] == 0 || symbol.value == 0) {
symlinks[symbol.section_number] = lnk_symbol_table_search_(symtab, symbol.name); symlinks[symbol.section_number] = lnk_symbol_table_search_(symtab, symbol.name);
} }
@@ -551,11 +551,47 @@ lnk_obj_get_comdat_symlink(LNK_Obj *obj, U64 section_number)
} }
internal COFF_SectionHeader * internal COFF_SectionHeader *
lnk_coff_section_header_from_section_number(LNK_Obj *obj, U64 section_number) lnk_coff_section_table_from_obj(LNK_Obj *obj)
{ {
COFF_SectionHeader *section_table = (COFF_SectionHeader *)str8_substr(obj->data, obj->header.section_table_range).str; return (COFF_SectionHeader *)str8_substr(obj->data, obj->header.section_table_range).str;
COFF_SectionHeader *section_header = &section_table[section_number-1]; }
return section_header;
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);
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);
return sect_idx+1;
}
internal LNK_ObjSection
lnk_obj_section_from_sect_idx(LNK_Obj *obj, U64 sect_idx)
{
Assert(sect_idx < obj->header.section_count_no_null);
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.name = coff_name_from_section_header(lnk_coff_string_table_from_obj(obj), section.header);
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;
return section;
}
internal LNK_ObjSection
lnk_obj_section_from_section_number(LNK_Obj *obj, U64 section_number)
{
U64 sect_idx = lnk_obj_sect_idx_from_section_number(obj, section_number);
return lnk_obj_section_from_sect_idx(obj, sect_idx);
} }
internal COFF_RelocArray internal COFF_RelocArray
@@ -567,12 +603,6 @@ lnk_coff_relocs_from_section_header(LNK_Obj *obj, COFF_SectionHeader *section_he
return result; return result;
} }
internal COFF_SectionHeader *
lnk_coff_section_table_from_obj(LNK_Obj *obj)
{
return (COFF_SectionHeader *)str8_substr(obj->data, obj->header.section_table_range).str;
}
internal String8 internal String8
lnk_coff_string_table_from_obj(LNK_Obj *obj) lnk_coff_string_table_from_obj(LNK_Obj *obj)
{ {
@@ -588,10 +618,10 @@ lnk_coff_symbol_table_from_obj(LNK_Obj *obj)
internal COFF_RelocArray internal COFF_RelocArray
lnk_coff_reloc_info_from_section_number(LNK_Obj *obj, U64 section_number) lnk_coff_reloc_info_from_section_number(LNK_Obj *obj, U64 section_number)
{ {
COFF_SectionHeader *section_header = lnk_coff_section_header_from_section_number(obj, 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_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_Reloc *relocs = str8_deserial_get_raw_ptr(obj->data, reloc_info.array_off, sizeof(*relocs)*reloc_info.count);
COFF_RelocArray result = { .count = reloc_info.count, .v = relocs }; COFF_RelocArray result = { .count = reloc_info.count, .v = relocs };
return result; return result;
} }
@@ -630,20 +660,17 @@ THREAD_POOL_TASK_FUNC(lnk_collect_obj_chunks_task)
LNK_SectionCollector *task = raw_task; LNK_SectionCollector *task = raw_task;
LNK_Obj *obj = task->objs[task_id]; LNK_Obj *obj = task->objs[task_id];
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);
for (U32 sect_idx = 0; sect_idx < obj->header.section_count_no_null; sect_idx += 1) { for (U32 sect_idx = 0; sect_idx < obj->header.section_count_no_null; sect_idx += 1) {
COFF_SectionHeader *section_header = &section_table[sect_idx]; LNK_ObjSection section = lnk_obj_section_from_sect_idx(obj, sect_idx);
if (obj->section_flags[sect_idx] & COFF_SectionFlag_LnkRemove) { if (*section.flags & COFF_SectionFlag_LnkRemove) {
if (!task->collect_discarded) { if (!task->collect_discarded) {
continue; continue;
} }
} }
String8 section_name = coff_name_from_section_header(string_table, section_header); if (str8_match(section.name, task->name, 0)) {
if (str8_match(section_name, task->name, 0)) { String8 section_data = str8_substr(obj->data, section.frange);
String8 section_data = str8_substr(obj->data, rng_1u64(section_header->foff, section_header->foff + section_header->fsize));
str8_list_push(arena, &task->out_lists[task_id], section_data); str8_list_push(arena, &task->out_lists[task_id], section_data);
} }
} }
@@ -718,28 +745,24 @@ lnk_parse_msvc_linker_directive(Arena *arena, LNK_Obj *obj, LNK_DirectiveInfo *d
internal String8List internal String8List
lnk_raw_directives_from_obj(Arena *arena, LNK_Obj *obj) lnk_raw_directives_from_obj(Arena *arena, LNK_Obj *obj)
{ {
COFF_SectionHeader *section_table = lnk_coff_section_table_from_obj(obj);
String8List drectve_data = {0}; 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->header.section_count_no_null; sect_idx += 1) {
COFF_SectionHeader *sect_header = &section_table[sect_idx]; LNK_ObjSection section = lnk_obj_section_from_sect_idx(obj, sect_idx);
COFF_SectionFlags sect_flags = obj->section_flags[sect_idx]; if (*section.flags & COFF_SectionFlag_LnkInfo) {
if (sect_flags & COFF_SectionFlag_LnkInfo) { if (str8_match(section.name, str8_lit(".drectve"), 0)) {
String8 sect_name = str8_cstring_capped(sect_header->name, sect_header->name + sizeof(sect_header->name)); if (*section.flags & COFF_SectionFlag_CntUninitializedData) {
if (str8_match(sect_name, str8_lit(".drectve"), 0)) {
if (sect_flags & COFF_SectionFlag_CntUninitializedData) {
lnk_error_obj(LNK_Error_IllData, obj, ".drectve section header has flag COFF_SectionFlag_CntUninitializedData"); lnk_error_obj(LNK_Error_IllData, obj, ".drectve section header has flag COFF_SectionFlag_CntUninitializedData");
break; break;
} }
if (sect_header->fsize < 3) { if (dim_1u64(section.frange) < 3) {
lnk_error_obj(LNK_Error_IllData, obj, "not enough bytes to parse .drectve"); lnk_error_obj(LNK_Error_IllData, obj, "not enough bytes to parse .drectve");
break; break;
} }
if (sect_header->reloc_count > 0) { if (section.reloc_count > 0) {
lnk_error_obj(LNK_Error_IllData, obj, ".drectve must not have relocations"); lnk_error_obj(LNK_Error_IllData, obj, ".drectve must not have relocations");
break; break;
} }
Rng1U64 sect_range = rng_1u64(sect_header->foff, sect_header->foff + sect_header->fsize); str8_list_push(arena, &drectve_data, str8_substr(obj->data, section.frange));
str8_list_push(arena, &drectve_data, str8_substr(obj->data, sect_range));
} }
} }
} }
@@ -763,13 +786,10 @@ lnk_debug_s_from_obj(Arena *arena, LNK_Obj *obj)
String8List raw_debug_s = {0}; String8List raw_debug_s = {0};
{ {
COFF_SectionHeader *section_table = lnk_coff_section_table_from_obj(obj);
String8 string_table = lnk_coff_string_table_from_obj(obj);
for EachIndex(sect_idx, obj->header.section_count_no_null) { for EachIndex(sect_idx, obj->header.section_count_no_null) {
COFF_SectionHeader *section_header = &section_table[sect_idx]; LNK_ObjSection section = lnk_obj_section_from_sect_idx(obj, sect_idx);
String8 section_name = coff_name_from_section_header(string_table, section_header); if (str8_match(section.name, str8_lit(".debug$S"), 0)) {
if (str8_match(section_name, str8_lit(".debug$S"), 0)) { String8 debug_s = str8_substr(obj->data, section.frange);
String8 debug_s = str8_substr(obj->data, rng_1u64(section_header->foff, section_header->foff + section_header->fsize));
str8_list_push(scratch.arena, &raw_debug_s, debug_s); str8_list_push(scratch.arena, &raw_debug_s, debug_s);
} }
} }
+17 -2
View File
@@ -40,6 +40,19 @@ typedef struct LNK_Obj
U64 pch_obj_idx; U64 pch_obj_idx;
} LNK_Obj; } LNK_Obj;
typedef struct LNK_ObjSection
{
LNK_Obj *obj;
U64 sect_idx;
U64 section_number;
COFF_SectionHeader *header;
COFF_SectionFlags *flags;
String8 name;
Rng1U64 vrange;
Rng1U64 frange;
U32 reloc_count;
} LNK_ObjSection;
typedef struct LNK_ObjNode typedef struct LNK_ObjNode
{ {
struct LNK_ObjNode *next; struct LNK_ObjNode *next;
@@ -133,9 +146,11 @@ internal LNK_Symbol * lnk_obj_get_comdat_symlink(LNK_Obj *obj, U64 section_n
internal COFF_ParsedSymbol lnk_parsed_symbol_from_coff(LNK_Obj *obj, void *coff_symbol); internal COFF_ParsedSymbol lnk_parsed_symbol_from_coff(LNK_Obj *obj, void *coff_symbol);
internal COFF_ParsedSymbol lnk_parsed_symbol_from_coff_symbol_idx(LNK_Obj *obj, U64 symbol_idx); internal COFF_ParsedSymbol lnk_parsed_symbol_from_coff_symbol_idx(LNK_Obj *obj, U64 symbol_idx);
internal COFF_SectionHeader * lnk_coff_section_header_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 LNK_ObjSection lnk_obj_section_from_sect_idx(LNK_Obj *obj, U64 sect_idx);
internal LNK_ObjSection 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); internal COFF_RelocArray lnk_coff_relocs_from_section_header(LNK_Obj *obj, COFF_SectionHeader *section_header);
internal COFF_SectionHeader * lnk_coff_section_table_from_obj(LNK_Obj *obj);
internal String8 lnk_coff_string_table_from_obj(LNK_Obj *obj); internal String8 lnk_coff_string_table_from_obj(LNK_Obj *obj);
internal String8 lnk_coff_symbol_table_from_obj(LNK_Obj *obj); internal String8 lnk_coff_symbol_table_from_obj(LNK_Obj *obj);
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); 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);
+13 -8
View File
@@ -286,11 +286,12 @@ lnk_can_replace_symbol(LNK_Symbol *dst, LNK_Symbol *src)
} }
} break; } break;
case COFF_ComdatSelect_ExactMatch: { case COFF_ComdatSelect_ExactMatch: {
COFF_SectionHeader *dst_sect_header = lnk_coff_section_header_from_section_number(dst_obj, dst_parsed.section_number); LNK_ObjSection dst_section = lnk_obj_section_from_section_number(dst_obj, dst_parsed.section_number);
COFF_SectionHeader *src_sect_header = lnk_coff_section_header_from_section_number(src_obj, src_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, rng_1u64(dst_sect_header->foff, dst_sect_header->foff + dst_sect_header->fsize)); String8 dst_data = str8_substr(dst_obj->data, dst_section.frange);
String8 src_data = str8_substr(src_obj->data, rng_1u64(src_sect_header->foff, src_sect_header->foff + src_sect_header->fsize)); String8 src_data = str8_substr(src_obj->data, src_section.frange);
B32 is_exact_match = 0;
B32 is_exact_match = 0;
if (dst_check_sum != 0 && src_check_sum != 0) { if (dst_check_sum != 0 && src_check_sum != 0) {
is_exact_match = dst_check_sum == src_check_sum && str8_match(dst_data, src_data, 0); is_exact_match = dst_check_sum == src_check_sum && str8_match(dst_data, src_data, 0);
} else { } else {
@@ -337,13 +338,15 @@ lnk_on_symbol_replace(LNK_Symbol *dst, LNK_Symbol *src)
if (dst_interp == COFF_SymbolValueInterp_Regular) { if (dst_interp == COFF_SymbolValueInterp_Regular) {
// remove replaced section from the output // remove replaced section from the output
dst_ref.obj->section_flags[dst_parsed.section_number-1] |= COFF_SectionFlag_LnkRemove; LNK_ObjSection dst_section = lnk_obj_section_from_section_number(dst_ref.obj, dst_parsed.section_number);
*dst_section.flags |= COFF_SectionFlag_LnkRemove;
// remove associated sections from the output // 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->associated_sections[dst_parsed.section_number];
associated_section != 0; associated_section != 0;
associated_section = associated_section->next) { associated_section = associated_section->next) {
dst_ref.obj->section_flags[associated_section->data-1] |= COFF_SectionFlag_LnkRemove; LNK_ObjSection section = lnk_obj_section_from_section_number(dst_ref.obj, associated_section->data);
*section.flags |= COFF_SectionFlag_LnkRemove;
} }
} }
@@ -360,7 +363,9 @@ lnk_on_symbol_replace(LNK_Symbol *dst, LNK_Symbol *src)
LNK_ObjSymbolRef src_ref = lnk_ref_from_symbol(src); LNK_ObjSymbolRef src_ref = lnk_ref_from_symbol(src);
if (src_interp == COFF_SymbolValueInterp_Regular) { if (src_interp == COFF_SymbolValueInterp_Regular) {
AssertAlways(~src_ref.obj->section_flags[src_parsed.section_number-1] & COFF_SectionFlag_LnkRemove); LNK_ObjSection src_section = lnk_obj_section_from_section_number(src_ref.obj, src_parsed.section_number);
COFF_SectionFlags src_flags = *src_section.flags;
AssertAlways(~src_flags & COFF_SectionFlag_LnkRemove);
} }
} }
#endif #endif