simplify section table

This commit is contained in:
Nikita Smith
2025-06-09 17:02:37 -07:00
committed by Ryan Fleury
parent ecdee57c60
commit 9d93eda3ed
6 changed files with 175 additions and 242 deletions
+15 -18
View File
@@ -3399,7 +3399,7 @@ THREAD_POOL_TASK_FUNC(lnk_patch_virtual_offsets_and_sizes_in_obj_section_headers
if (~sect_header->flags & 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_contribution(sc);
sect_header->vsize = lnk_size_from_section_contrib(sc);
sect_header->voff = sect->voff + sc->u.off;
}
}
@@ -3423,7 +3423,7 @@ THREAD_POOL_TASK_FUNC(lnk_patch_file_offsets_and_sizes_in_obj_section_headers_ta
LNK_SectionContrib *sc = task->sect_map[obj_idx][sect_idx];
LNK_Section *sect = task->image_sects.v[sc->u.sect_idx];
if (~sect->flags & COFF_SectionFlag_CntUninitializedData) {
sect_header->fsize = lnk_size_from_section_contribution(sc);
sect_header->fsize = lnk_size_from_section_contrib(sc);
sect_header->foff = sect->foff + sc->u.off;
}
}
@@ -3885,7 +3885,7 @@ lnk_build_image(TP_Arena *arena, TP_Context *tp, LNK_Config *config, LNK_SymbolT
LNK_BuildImageTask task = {0};
task.symtab = symtab;
task.sectab = sectab;
task.default_align = lnk_default_align_from_machine(config->machine);
task.default_align = coff_default_align_from_machine(config->machine);
task.objs_count = objs_count;
task.objs = objs;
task.sect_map = 0;
@@ -4084,13 +4084,13 @@ lnk_build_image(TP_Arena *arena, TP_Context *tp, LNK_Config *config, LNK_SymbolT
radsort(common_block_contribs, common_block_contribs_count, lnk_common_block_contrib_is_before);
// compute .bss virtual size - this marks start of the common block
lnk_finalize_section_layout(sectab, common_block_sect, config->file_align);
lnk_finalize_section_layout(common_block_sect, config->file_align);
U64 common_block_cursor = common_block_sect->vsize;
// compute and assign offsets into the common block
for (U64 contrib_idx = 0; contrib_idx < common_block_contribs_count; contrib_idx += 1) {
LNK_CommonBlockContrib *contrib = &common_block_contribs[contrib_idx];
U32 size = contrib->u.size;
U32 size = contrib->u.size;
U32 align = Min(32, u64_up_to_pow2(size)); // link.exe caps align at 32 bytes
common_block_cursor = AlignPow2(common_block_cursor, align);
contrib->u.offset = common_block_cursor;
@@ -4124,7 +4124,7 @@ lnk_build_image(TP_Arena *arena, TP_Context *tp, LNK_Config *config, LNK_SymbolT
// assign contribs offsets, sizes, and section indices
for (LNK_SectionNode *sect_n = sectab->list.first; sect_n != 0; sect_n = sect_n->next) {
lnk_finalize_section_layout(sectab, &sect_n->data, config->file_align);
lnk_finalize_section_layout(&sect_n->data, config->file_align);
}
// remove empty sections
@@ -4149,10 +4149,10 @@ lnk_build_image(TP_Arena *arena, TP_Context *tp, LNK_Config *config, LNK_SymbolT
// assing layout offsets and sizes to merged sections
for (LNK_SectionNode *sect_n = sectab->merge_list.first; sect_n != 0; sect_n = sect_n->next) {
LNK_Section *sect = &sect_n->data;
LNK_Section *final_sect = lnk_finalized_section_from_id(sectab, sect->merge_id);
LNK_Section *final_sect = sect->merge_dst;
LNK_SectionContrib *first_sc = lnk_get_first_section_contrib(sect);
LNK_SectionContrib *last_sc = lnk_get_last_section_contrib(sect);
U64 last_sc_size = lnk_size_from_section_contribution(last_sc);
U64 last_sc_size = lnk_size_from_section_contrib(last_sc);
sect->voff = final_sect->voff + first_sc->u.off;
sect->vsize = (last_sc->u.off - first_sc->u.off) + last_sc_size;
sect->foff = final_sect->foff + first_sc->u.off;
@@ -4242,7 +4242,7 @@ lnk_build_image(TP_Arena *arena, TP_Context *tp, LNK_Config *config, LNK_SymbolT
sc->align = 1;
sc->u.obj_idx = max_U32;
lnk_finalize_section_layout(sectab, reloc, config->file_align);
lnk_finalize_section_layout(reloc, config->file_align);
lnk_assign_section_virtual_space(reloc, config->sect_align, &voff_cursor);
lnk_assign_section_index(reloc, sectab->next_sect_idx++);
@@ -4273,7 +4273,7 @@ lnk_build_image(TP_Arena *arena, TP_Context *tp, LNK_Config *config, LNK_SymbolT
image_header_sc->align = config->file_align;
image_header_sc->data_list = image_header_data.first;
lnk_finalize_section_layout(sectab, image_header_sect, config->file_align);
lnk_finalize_section_layout(image_header_sect, config->file_align);
}
ProfBegin("Patch Section Symbols");
@@ -4301,7 +4301,7 @@ lnk_build_image(TP_Arena *arena, TP_Context *tp, LNK_Config *config, LNK_SymbolT
// pick fill pick
U8 fill_byte = 0;
if (sect->flags & COFF_SectionFlag_CntCode) {
fill_byte = lnk_code_align_byte_from_machine(config->machine);
fill_byte = coff_code_align_byte_from_machine(config->machine);
}
// copy section contribution
@@ -4314,7 +4314,7 @@ lnk_build_image(TP_Arena *arena, TP_Context *tp, LNK_Config *config, LNK_SymbolT
Assert(sc->u.off >= prev_sc_opl);
U64 fill_size = sc->u.off - prev_sc_opl;
MemorySet(image_data.str + sect->foff + prev_sc_opl, fill_byte, fill_size);
prev_sc_opl = sc->u.off + lnk_size_from_section_contribution(sc);
prev_sc_opl = sc->u.off + lnk_size_from_section_contrib(sc);
// copy contrib contents
{
@@ -4595,8 +4595,8 @@ lnk_build_rad_map(Arena *arena, String8 image_data, U64 thread_count, U64 objs_c
U64 file_off = image_section_table[sc->u.sect_idx]->foff + sc->u.off;
U64 virt_off = image_section_table[sc->u.sect_idx]->voff + sc->u.off;
U64 virt_size = lnk_size_from_section_contribution(sc);
U64 file_size = lnk_size_from_section_contribution(sc);
U64 virt_size = lnk_size_from_section_contrib(sc);
U64 file_size = lnk_size_from_section_contrib(sc);
String8 sc_data = str8_substr(image_data, rng_1u64(file_off, file_off + virt_size));
U128 sc_hash = {0};
@@ -4804,16 +4804,13 @@ lnk_run(TP_Context *tp, TP_Arena *tp_arena, LNK_Config *config)
//
if (config->rad_debug == LNK_SwitchState_Yes) {
lnk_timer_begin(LNK_Timer_Rdi);
RDI_Arch arch = rdi_arch_from_coff_machine(config->machine);
LNK_SectionArray image_sects = lnk_section_table_get_output_sections(scratch.arena, image_ctx.sectab);
String8List rdi_data = lnk_build_rad_debug_info(tp,
tp_arena,
config->target_os,
arch,
rdi_arch_from_coff_machine(config->machine),
config->image_name,
image_ctx.image_data,
image_sects,
input.count,
input.obj_arr,
input.debug_s_arr,
+20
View File
@@ -14,12 +14,32 @@ typedef struct LNK_LinkContext
LNK_LibList lib_index[LNK_InputSource_Count];
} LNK_LinkContext;
// -- Image --------------------------------------------------------------------
typedef struct LNK_ImageContext
{
String8 image_data;
LNK_SectionTable *sectab;
} LNK_ImageContext;
typedef struct LNK_SectionDefinition
{
String8 name;
COFF_SectionFlags flags;
U64 contribs_count;
struct LNK_Obj *obj;
U64 obj_sect_idx;
} LNK_SectionDefinition;
typedef struct LNK_CommonBlockContrib
{
struct LNK_Symbol *symbol;
union {
U32 size;
U32 offset;
} u;
} LNK_CommonBlockContrib;
// --- Base Reloc --------------------------------------------------------------
typedef struct LNK_BaseRelocPage
+20 -11
View File
@@ -4440,11 +4440,11 @@ lnk_type_from_itype(CV_TypeIndex itype, Rng1U64 tpi_itype_range, RDIB_Type **tpi
}
internal U64
lnk_voff_from_sect_off(U64 sect_idx, U64 sect_off, LNK_SectionArray image_sects, LNK_Obj *obj, CV_SymKind symbol_kind, U64 symbol_offset)
lnk_voff_from_sect_off(U64 sect_idx, U64 sect_off, COFF_SectionHeaderArray image_sects, LNK_Obj *obj, CV_SymKind symbol_kind, U64 symbol_offset)
{
U64 voff = 0;
if (sect_idx < image_sects.count) {
voff = image_sects.v[sect_idx]->voff + sect_off;
voff = image_sects.v[sect_idx].voff + sect_off;
} else {
lnk_error_obj(LNK_Error_CvIllSymbolData, obj, "Out of bounds section index 0x%x in S_%S @ 0x%llx.",
sect_idx, cv_string_from_sym_kind(symbol_kind), symbol_offset);
@@ -4453,11 +4453,11 @@ lnk_voff_from_sect_off(U64 sect_idx, U64 sect_off, LNK_SectionArray image_sects,
}
internal Rng1U64
lnk_virt_range_from_sect_off_size(U64 sect_idx, U64 sect_off, U64 size, LNK_SectionArray image_sects, LNK_Obj *obj, CV_SymKind symbol_kind, U64 symbol_offset)
lnk_virt_range_from_sect_off_size(U64 sect_idx, U64 sect_off, U64 size, COFF_SectionHeaderArray image_sects, LNK_Obj *obj, CV_SymKind symbol_kind, U64 symbol_offset)
{
Rng1U64 virt_range = {0};
if (sect_idx < image_sects.count) {
U64 voff = image_sects.v[sect_idx]->voff + sect_off;
U64 voff = image_sects.v[sect_idx].voff + sect_off;
virt_range = rng_1u64(voff, voff + size);
} else {
lnk_error_obj(LNK_Error_CvIllSymbolData, obj, "Out of bounds section index 0x%x in S_%S @ 0x%llx.",
@@ -4590,8 +4590,8 @@ THREAD_POOL_TASK_FUNC(lnk_convert_line_tables_to_rdi_task)
lnk_error_obj(LNK_Warning_IllData, obj, "Out of bounds section index (%u) in $$LINES; skip line info for \"%S\".", parsed_lines.sec_idx, file_path);
continue;
}
LNK_Section *sect = task->image_sects.v[parsed_lines.sec_idx];
CV_LineArray lines = cv_c13_line_array_from_data(arena, raw_lines, sect->voff, parsed_lines);
COFF_SectionHeader *sect = &task->image_sects.v[parsed_lines.sec_idx];
CV_LineArray lines = cv_c13_line_array_from_data(arena, raw_lines, sect->voff, parsed_lines);
// find source file for this line table
String8 normal_path = lnk_normalize_src_file_path(scratch.arena, file_path);
@@ -5362,7 +5362,6 @@ lnk_build_rad_debug_info(TP_Context *tp,
RDI_Arch arch,
String8 image_name,
String8 image_data,
LNK_SectionArray image_sects,
U64 obj_count,
LNK_Obj *obj_arr,
CV_DebugS *debug_s_arr,
@@ -5372,15 +5371,24 @@ lnk_build_rad_debug_info(TP_Context *tp,
CV_DebugT types[CV_TypeIndexSource_COUNT])
{
ProfBegin("RDI");
Temp scratch = scratch_begin(0,0);
Temp scratch = scratch_begin(tp_arena->v,tp_arena->count);
RDIB_Input input = rdib_init_input(scratch.arena);
COFF_SectionHeaderArray image_sects;
String8 image_strtab;
{
PE_BinInfo pe = pe_bin_info_from_data(scratch.arena, image_data);
image_sects.count = pe.section_count;
image_sects.v = (COFF_SectionHeader *)str8_substr(image_data, pe.section_table_range).str;
image_strtab = str8_substr(image_data, pe.string_table_range);
}
ProfBegin("Top Level Info");
{
U64 image_vsize = 0;
for (U64 sect_idx = 0; sect_idx < image_sects.count; sect_idx++) {
LNK_Section *sect = image_sects.v[sect_idx];
COFF_SectionHeader *sect = &image_sects.v[sect_idx];
image_vsize = Max(image_vsize, sect->voff + sect->vsize);
}
@@ -5397,10 +5405,11 @@ lnk_build_rad_debug_info(TP_Context *tp,
input.sect_count = image_sects.count;
input.sections = push_array(scratch.arena, RDIB_BinarySection, image_sects.count);
for (U64 sect_idx = 0; sect_idx < image_sects.count; ++sect_idx) {
LNK_Section *src = image_sects.v[sect_idx];
COFF_SectionHeader *src = &image_sects.v[sect_idx];
RDIB_BinarySection *dst = &input.sections[sect_idx];
String8 sect_name = coff_name_from_section_header(image_strtab, src);
dst->name = push_str8_copy(scratch.arena, src->name);
dst->name = push_str8_copy(scratch.arena, sect_name);
dst->flags = rdi_binary_section_flags_from_coff_section_flags(src->flags);
dst->voff_first = src->voff;
dst->voff_opl = src->voff + src->vsize;
+1 -2
View File
@@ -453,7 +453,7 @@ typedef struct
typedef struct
{
LNK_SectionArray image_sects;
COFF_SectionHeaderArray image_sects;
LNK_Obj *obj_arr;
CV_DebugS *debug_s_arr;
CV_DebugT ipi;
@@ -555,7 +555,6 @@ internal String8List lnk_build_rad_debug_info(TP_Context *tp,
RDI_Arch arch,
String8 image_name,
String8 image_data,
LNK_SectionArray image_sects,
U64 obj_count,
LNK_Obj *obj_arr,
CV_DebugS *debug_s_arr,
+87 -163
View File
@@ -1,36 +1,6 @@
// Copyright (c) 2025 Epic Games Tools
// Licensed under the MIT license (https://opensource.org/license/mit/)
internal U8
lnk_code_align_byte_from_machine(COFF_MachineType machine)
{
U8 align_byte = 0;
switch (machine) {
case COFF_MachineType_X64:
case COFF_MachineType_X86: {
align_byte = 0xCC;
} break;
default: {
lnk_not_implemented("TODO: set align value for machine %S", coff_string_from_machine_type(machine));
} break;
}
return align_byte;
}
internal U16
lnk_default_align_from_machine(COFF_MachineType machine)
{
U16 align = 0;
switch (machine) {
case COFF_MachineType_Unknown: break;
case COFF_MachineType_X64: {
align = 16;
} break;
default: { NotImplemented; } break;
}
return align;
}
internal LNK_SectionContrib *
lnk_section_contrib_chunk_push(LNK_SectionContribChunk *chunk, U64 count)
{
@@ -100,75 +70,16 @@ lnk_section_array_from_list(Arena *arena, LNK_SectionList list)
return result;
}
internal U64
lnk_size_from_section_contribution(LNK_SectionContrib *sc)
internal String8
lnk_make_name_with_flags(Arena *arena, String8 name, COFF_SectionFlags flags)
{
U64 size = 0;
for (String8Node *n = sc->data_list; n != 0; n = n->next) {
size += n->string.size;
}
return size;
}
internal U64
lnk_voff_from_section_contrib(COFF_SectionHeader **image_section_table, LNK_SectionContrib *sc)
{
COFF_SectionHeader *sect_header = image_section_table[sc->u.sect_idx+1];
U64 voff = sect_header->voff + sc->u.off;
return voff;
}
internal U64
lnk_foff_from_section_contrib(COFF_SectionHeader **image_section_table, LNK_SectionContrib *sc)
{
COFF_SectionHeader *sect_header = image_section_table[sc->u.sect_idx+1];
U64 foff = sect_header->foff + sc->u.off;
return foff;
}
internal U64
lnk_fopl_from_section_contrib(COFF_SectionHeader **image_section_table, LNK_SectionContrib *sc)
{
U64 foff = lnk_foff_from_section_contrib(image_section_table, sc);
return foff + lnk_size_from_section_contribution(sc);
}
internal LNK_SectionContrib *
lnk_get_first_section_contrib(LNK_Section *sect)
{
if (sect->contribs.chunk_count > 0) {
if (sect->contribs.first->count > 0) {
return sect->contribs.first->v[0];
}
}
return 0;
}
internal LNK_SectionContrib *
lnk_get_last_section_contrib(LNK_Section *sect)
{
if (sect->contribs.chunk_count > 0) {
if (sect->contribs.last->count > 0) {
return sect->contribs.last->v[sect->contribs.last->count-1];
}
}
return 0;
}
internal U64
lnk_get_section_contrib_size(LNK_Section *sect)
{
LNK_SectionContrib *first_sc = lnk_get_first_section_contrib(sect);
LNK_SectionContrib *last_sc = lnk_get_last_section_contrib(sect);
U64 size = (last_sc->u.off - first_sc->u.off) + lnk_size_from_section_contribution(last_sc);
return size;
}
internal U64
lnk_get_first_section_contrib_voff(COFF_SectionHeader **image_section_table, LNK_Section *sect)
{
LNK_SectionContrib *sc = lnk_get_first_section_contrib(sect);
return lnk_voff_from_section_contrib(image_section_table, sc);
Temp scratch = scratch_begin(&arena, 1);
String8List l = {0};
str8_list_push(scratch.arena, &l, name);
str8_list_push(scratch.arena, &l, str8_struct(&flags));
String8 name_with_flags = str8_list_join(arena, &l, 0);
scratch_end(scratch);
return name_with_flags;
}
internal LNK_SectionTable *
@@ -184,27 +95,15 @@ lnk_section_table_alloc(void)
}
internal void
lnk_section_table_release(LNK_SectionTable **st_ptr)
lnk_section_table_release(LNK_SectionTable **sectab_ptr)
{
ProfBeginFunction();
LNK_SectionTable *sectab = *st_ptr;
LNK_SectionTable *sectab = *sectab_ptr;
arena_release(sectab->arena);
*st_ptr = 0;
*sectab_ptr = 0;
ProfEnd();
}
internal String8
lnk_make_name_with_flags(Arena *arena, String8 name, COFF_SectionFlags flags)
{
Temp scratch = scratch_begin(&arena, 1);
String8List l = {0};
str8_list_push(scratch.arena, &l, name);
str8_list_push(scratch.arena, &l, str8_struct(&flags));
String8 name_with_flags = str8_list_join(arena, &l, 0);
scratch_end(scratch);
return name_with_flags;
}
internal LNK_Section *
lnk_section_table_push(LNK_SectionTable *sectab, String8 name, COFF_SectionFlags flags)
{
@@ -212,9 +111,8 @@ lnk_section_table_push(LNK_SectionTable *sectab, String8 name, COFF_SectionFlags
LNK_SectionNode *sect_node = push_array(sectab->arena, LNK_SectionNode, 1);
LNK_Section *sect = &sect_node->data;
sect->id = sectab->id_max++;
sect->name = push_str8_copy(sectab->arena, name);
sect->flags = flags;
sect->name = push_str8_copy(sectab->arena, name);
sect->flags = flags;
LNK_SectionList *sect_list = &sectab->list;
SLLQueuePush(sect_list->first, sect_list->last, sect_node);
@@ -277,12 +175,12 @@ lnk_section_table_search(LNK_SectionTable *sectab, String8 full_or_partial_name,
{
Temp scratch = scratch_begin(0,0);
String8 name = {0};
String8 name = {0};
String8 postfix = {0};
coff_parse_section_name(full_or_partial_name, &name, &postfix);
String8 name_with_flags = lnk_make_name_with_flags(scratch.arena, name, flags);
LNK_Section *section= 0;
String8 name_with_flags = lnk_make_name_with_flags(scratch.arena, name, flags);
LNK_Section *section = 0;
hash_table_search_string_raw(sectab->sect_ht, name_with_flags, &section);
scratch_end(scratch);
@@ -292,7 +190,7 @@ lnk_section_table_search(LNK_SectionTable *sectab, String8 full_or_partial_name,
internal LNK_SectionArray
lnk_section_table_search_many(Arena *arena, LNK_SectionTable *sectab, String8 full_or_partial_name)
{
String8 name = {0};
String8 name = {0};
String8 postfix = {0};
coff_parse_section_name(full_or_partial_name, &name, &postfix);
@@ -325,7 +223,6 @@ lnk_section_table_merge(LNK_SectionTable *sectab, LNK_MergeDirectiveList merge_l
ProfBeginFunction();
Temp scratch = scratch_begin(0, 0);
LNK_Section **src_dst = push_array(scratch.arena, LNK_Section *, sectab->id_max);
for (LNK_MergeDirectiveNode *merge_node = merge_list.first; merge_node != 0; merge_node = merge_node->next) {
LNK_MergeDirective *merge = &merge_node->data;
@@ -361,8 +258,8 @@ lnk_section_table_merge(LNK_SectionTable *sectab, LNK_MergeDirectiveList merge_l
// are we trying to merge section that was already merged?
LNK_Section *merge_sect = 0;
hash_table_search_string_raw(sectab->sect_ht, merge->src, &merge_sect);
if (merge_sect && merge_sect->is_merged) {
LNK_Section *dst = src_dst[merge_sect->id];
if (merge_sect && merge_sect->merge_dst) {
LNK_Section *dst = merge_sect->merge_dst;
B32 is_ambiguous_merge = !str8_match(dst->name, merge->dst, 0);
if (is_ambiguous_merge) {
lnk_error(LNK_Warning_AmbiguousMerge, "Detected ambiguous section merge:");
@@ -398,13 +295,9 @@ lnk_section_table_merge(LNK_SectionTable *sectab, LNK_MergeDirectiveList merge_l
for (U64 src_idx = 0; src_idx < src_matches.count; src_idx += 1) {
LNK_Section *src = src_matches.v[src_idx];
// update map
src_dst[src->id] = dst;
// merge section with destination
lnk_section_contrib_chunk_list_concat_in_place(&dst->contribs, &src->contribs);
src->is_merged = 1;
src->merge_id = dst->id;
src->merge_dst = dst;
// remove from output section list
LNK_SectionNode *merge_node = lnk_section_table_remove(sectab, src->name);
@@ -418,25 +311,6 @@ lnk_section_table_merge(LNK_SectionTable *sectab, LNK_MergeDirectiveList merge_l
ProfEnd();
}
internal LNK_SectionArray
lnk_section_table_get_output_sections(Arena *arena, LNK_SectionTable *sectab)
{
LNK_SectionArray result = {0};
result.count = 0;
result.v = push_array(arena, LNK_Section *, sectab->list.count);
for (LNK_SectionNode *sect_node = sectab->list.first; sect_node != 0; sect_node = sect_node->next) {
Assert(result.count < sectab->list.count);
result.v[result.count] = &sect_node->data;
result.count += 1;
}
U64 unused_entry_count = sectab->list.count - result.count;
arena_pop(arena, unused_entry_count * sizeof(result.v[0]));
return result;
}
internal int
lnk_section_contrib_chunk_is_before(void *raw_a, void *raw_b)
{
@@ -445,7 +319,7 @@ lnk_section_contrib_chunk_is_before(void *raw_a, void *raw_b)
}
internal void
lnk_finalize_section_layout(LNK_SectionTable *sectab, LNK_Section *sect, U64 file_align)
lnk_finalize_section_layout(LNK_Section *sect, U64 file_align)
{
Temp scratch = scratch_begin(0,0);
@@ -459,7 +333,7 @@ lnk_finalize_section_layout(LNK_SectionTable *sectab, LNK_Section *sect, U64 fil
// repopulate chunk list in sorted order
sect->contribs.first = 0;
sect->contribs.last = 0;
sect->contribs.last = 0;
for (U64 chunk_idx = 0; chunk_idx < sect->contribs.chunk_count; chunk_idx += 1) {
SLLQueuePush(sect->contribs.first, sect->contribs.last, chunks[chunk_idx]);
}
@@ -478,7 +352,7 @@ lnk_finalize_section_layout(LNK_SectionTable *sectab, LNK_Section *sect, U64 fil
U64 sc_off = cursor;
// compute contrib size
U64 sc_size = lnk_size_from_section_contribution(sc);
U64 sc_size = lnk_size_from_section_contrib(sc);
cursor += sc_size;
// assign offset and size
@@ -495,7 +369,6 @@ lnk_finalize_section_layout(LNK_SectionTable *sectab, LNK_Section *sect, U64 fil
scratch_end(scratch);
}
internal void
lnk_assign_section_index(LNK_Section *sect, U64 sect_idx)
{
@@ -526,22 +399,73 @@ lnk_assign_section_file_space(LNK_Section *sect, U64 *foff_cursor)
}
}
internal LNK_Section *
lnk_finalized_section_from_id(LNK_SectionTable *sectab, U64 id)
internal U64
lnk_size_from_section_contrib(LNK_SectionContrib *sc)
{
for (LNK_SectionNode *sect_n = sectab->list.first; sect_n != 0; sect_n = sect_n->next) {
if (sect_n->data.id == id) {
return &sect_n->data;
U64 size = 0;
for (String8Node *n = sc->data_list; n != 0; n = n->next) {
size += n->string.size;
}
return size;
}
internal U64
lnk_voff_from_section_contrib(COFF_SectionHeader **image_section_table, LNK_SectionContrib *sc)
{
COFF_SectionHeader *sect_header = image_section_table[sc->u.sect_idx+1];
U64 voff = sect_header->voff + sc->u.off;
return voff;
}
internal U64
lnk_foff_from_section_contrib(COFF_SectionHeader **image_section_table, LNK_SectionContrib *sc)
{
COFF_SectionHeader *sect_header = image_section_table[sc->u.sect_idx+1];
U64 foff = sect_header->foff + sc->u.off;
return foff;
}
internal U64
lnk_fopl_from_section_contrib(COFF_SectionHeader **image_section_table, LNK_SectionContrib *sc)
{
U64 foff = lnk_foff_from_section_contrib(image_section_table, sc);
return foff + lnk_size_from_section_contrib(sc);
}
internal LNK_SectionContrib *
lnk_get_first_section_contrib(LNK_Section *sect)
{
if (sect->contribs.chunk_count > 0) {
if (sect->contribs.first->count > 0) {
return sect->contribs.first->v[0];
}
}
for (LNK_SectionNode *sect_n = sectab->merge_list.first; sect_n != 0; sect_n = sect_n->next) {
if (sect_n->data.id == id) {
return lnk_finalized_section_from_id(sectab, sect_n->data.merge_id);
}
}
return 0;
}
internal LNK_SectionContrib *
lnk_get_last_section_contrib(LNK_Section *sect)
{
if (sect->contribs.chunk_count > 0) {
if (sect->contribs.last->count > 0) {
return sect->contribs.last->v[sect->contribs.last->count-1];
}
}
return 0;
}
internal U64
lnk_get_section_contrib_size(LNK_Section *sect)
{
LNK_SectionContrib *first_sc = lnk_get_first_section_contrib(sect);
LNK_SectionContrib *last_sc = lnk_get_last_section_contrib(sect);
U64 size = (last_sc->u.off - first_sc->u.off) + lnk_size_from_section_contrib(last_sc);
return size;
}
internal U64
lnk_get_first_section_contrib_voff(COFF_SectionHeader **image_section_table, LNK_Section *sect)
{
LNK_SectionContrib *sc = lnk_get_first_section_contrib(sect);
return lnk_voff_from_section_contrib(image_section_table, sc);
}
+32 -48
View File
@@ -20,18 +20,9 @@ typedef struct LNK_SectionContrib
U8 unused[2];
};
} u;
U16 align; // alignment of the contribution in the image
U16 align; // contribution alignment in the image
} LNK_SectionContrib;
typedef struct LNK_CommonBlockContrib
{
struct LNK_Symbol *symbol;
union {
U32 size;
U32 offset;
} u;
} LNK_CommonBlockContrib;
typedef struct LNK_SectionContribChunk
{
struct LNK_SectionContribChunk *next;
@@ -49,24 +40,14 @@ typedef struct LNK_SectionContribChunkList
LNK_SectionContribChunk *last;
} LNK_SectionContribChunkList;
typedef struct LNK_SectionDefinition
{
String8 name;
COFF_SectionFlags flags;
U64 contribs_count;
struct LNK_Obj *obj;
U64 obj_sect_idx;
} LNK_SectionDefinition;
typedef struct LNK_Section
{
U64 id;
String8 name;
COFF_SectionFlags flags;
B32 is_merged;
U64 merge_id;
LNK_SectionContribChunkList contribs;
struct LNK_Section *merge_dst;
U64 voff;
U64 vsize;
U64 fsize;
@@ -97,23 +78,44 @@ typedef struct LNK_SectionArray
typedef struct LNK_SectionTable
{
Arena *arena;
U64 id_max;
U64 next_sect_idx;
LNK_SectionList list;
LNK_SectionList merge_list;
HashTable *sect_ht; // name -> LNK_Section *
HashTable *sect_ht; // (name * COFF_SectionFlags) -> LNK_Section *
U64 next_sect_idx;
} LNK_SectionTable;
////////////////////////////////
// --- Section Contrib Chunk List ----------------------------------------------
internal U8 lnk_code_align_byte_from_machine(COFF_MachineType machine);
internal U16 lnk_default_align_from_machine(COFF_MachineType machine);
internal LNK_SectionContrib * lnk_section_contrib_chunk_push(LNK_SectionContribChunk *chunk, U64 count);
internal LNK_SectionContrib * lnk_section_contrib_chunk_push_atomic(LNK_SectionContribChunk *chunk, U64 count);
internal LNK_SectionContribChunk * lnk_section_contrib_chunk_list_push_chunk(Arena *arena, LNK_SectionContribChunkList *list, U64 cap, String8 sort_idx);
internal void lnk_section_contrib_chunk_list_concat_in_place(LNK_SectionContribChunkList *list, LNK_SectionContribChunkList *to_concat);
internal LNK_SectionContribChunk ** lnk_array_from_section_contrib_chunk_list(Arena *arena, LNK_SectionContribChunkList list);
////////////////////////////////
// --- Section List ------------------------------------------------------------
internal LNK_SectionArray lnk_section_array_from_list(Arena *arena, LNK_SectionList list);
////////////////////////////////
// --- Section Table -----------------------------------------------------------
internal String8 lnk_make_name_with_flags(Arena *arena, String8 name, COFF_SectionFlags flags);
internal LNK_SectionTable * lnk_section_table_alloc(void);
internal void lnk_section_table_release(LNK_SectionTable **sectab_ptr);
internal LNK_Section * lnk_section_table_push(LNK_SectionTable *sectab, String8 name, COFF_SectionFlags flags);
internal LNK_SectionNode * lnk_section_table_remove(LNK_SectionTable *sectab, String8 name);
internal LNK_Section * lnk_section_table_search(LNK_SectionTable *sectab, String8 name, COFF_SectionFlags flags);
internal LNK_SectionArray lnk_section_table_search_many(Arena *arena, LNK_SectionTable *sectab, String8 full_or_partial_name);
internal void lnk_section_table_merge(LNK_SectionTable *sectab, LNK_MergeDirectiveList merge_list);
// --- Section Finalization ----------------------------------------------------
internal void lnk_finalize_section_layout (LNK_Section *sect, U64 file_align);
internal void lnk_assign_section_index (LNK_Section *sect, U64 sect_idx);
internal void lnk_assign_section_virtual_space(LNK_Section *sect, U64 sect_align, U64 *voff_cursor);
internal void lnk_assign_section_file_space (LNK_Section *sect, U64 *foff_cursor);
// --- Section Contribution ----------------------------------------------------
internal U64 lnk_size_from_section_contrib(LNK_SectionContrib *sc);
internal U64 lnk_voff_from_section_contrib(COFF_SectionHeader **image_section_table, LNK_SectionContrib *sc);
@@ -124,21 +126,3 @@ internal LNK_SectionContrib * lnk_get_first_section_contrib(LNK_Section *sect);
internal LNK_SectionContrib * lnk_get_last_section_contrib(LNK_Section *sect);
internal U64 lnk_get_section_contrib_size(LNK_Section *sect);
internal U64 lnk_get_first_section_contrib_voff(COFF_SectionHeader **image_section_table, LNK_Section *sect);
////////////////////////////////
internal LNK_SectionTable * lnk_section_table_alloc(void);
internal void lnk_section_table_release(LNK_SectionTable **st_ptr);
internal LNK_Section * lnk_section_table_push(LNK_SectionTable *sectab, String8 name, COFF_SectionFlags flags);
internal LNK_SectionNode * lnk_section_table_remove(LNK_SectionTable *sectab, String8 name);
internal LNK_Section * lnk_section_table_search(LNK_SectionTable *sectab, String8 name, COFF_SectionFlags flags);
internal LNK_SectionArray lnk_section_table_search_many(Arena *arena, LNK_SectionTable *sectab, String8 full_or_partial_name);
internal void lnk_section_table_merge(LNK_SectionTable *sectab, LNK_MergeDirectiveList merge_list);
internal LNK_SectionArray lnk_section_table_get_output_sections(Arena *arena, LNK_SectionTable *sectab);
internal LNK_Section * lnk_finalized_section_from_id(LNK_SectionTable *sectab, U64 id);
internal LNK_SectionArray lnk_section_table_get_output_sections(Arena *arena, LNK_SectionTable *sectab);
internal void lnk_finalize_section_layout(LNK_SectionTable *sectab, LNK_Section *sect, U64 file_align);
internal void lnk_assign_section_index(LNK_Section *sect, U64 sect_idx);
internal void lnk_assign_section_virtual_space(LNK_Section *sect, U64 sect_align, U64 *voff_cursor);
internal void lnk_assign_section_file_space(LNK_Section *sect, U64 *foff_cursor);