From c82b98cd49bb316954dc7c7b2d404bdc13944a16 Mon Sep 17 00:00:00 2001 From: Nikita Smith Date: Thu, 29 May 2025 23:07:18 -0700 Subject: [PATCH] assign section index to .reloc --- src/linker/lnk.c | 35 +++++++++++++--------------------- src/linker/lnk_debug_info.c | 6 ++++-- src/linker/lnk_section_table.c | 14 ++++++++++++++ src/linker/lnk_section_table.h | 5 +++++ 4 files changed, 36 insertions(+), 24 deletions(-) diff --git a/src/linker/lnk.c b/src/linker/lnk.c index 855b9477..14ca6ef0 100644 --- a/src/linker/lnk.c +++ b/src/linker/lnk.c @@ -1843,19 +1843,22 @@ lnk_build_base_relocs(TP_Context *tp, TP_Arena *tp_arena, LNK_Config *config, U6 U64 total_entry_count = 0; total_entry_count += page->entries_addr32.count; total_entry_count += page->entries_addr64.count; + + U32 *page_voff_ptr; + U32 *block_size_ptr; + U16 *reloc_arr_base; // push buffer - U64 buf_align = sizeof(U32); - U64 buf_size = AlignPow2(sizeof(U32)*2 + sizeof(U16)*total_entry_count, buf_align); - U8 *buf = push_array_no_zero(arena, U8, buf_size); + U64 buf_size = AlignPow2(sizeof(*page_voff_ptr) + sizeof(*block_size_ptr) + sizeof(*reloc_arr_base)*total_entry_count, sizeof(U32)); + void *buf = push_array_no_zero(arena, U8, buf_size); // setup pointers into buffer - U32 *page_voff_ptr = (U32*)buf; - U32 *block_size_ptr = page_voff_ptr + 1; - U16 *reloc_arr_base = (U16*)(block_size_ptr + 1); - U16 *reloc_arr_ptr = reloc_arr_base; + page_voff_ptr = buf; + block_size_ptr = page_voff_ptr + 1; + reloc_arr_base = (U16*)(block_size_ptr + 1); // write 32-bit relocations + U16 *reloc_arr_ptr = reloc_arr_base; for (U64Node *i = page->entries_addr32.first; i != 0; i = i->next) { // was base reloc_entry made? if (hash_table_search_u64(voff_ht, i->data)) { @@ -1898,7 +1901,7 @@ lnk_build_base_relocs(TP_Context *tp, TP_Arena *tp_arena, LNK_Config *config, U6 Assert(*block_size_ptr <= buf_size); // push page - str8_list_push(arena, &result, str8(buf, block_size)); + str8_list_push(arena, &result, str8(buf, buf_size)); // purge voffs for next page hash_table_purge(voff_ht); @@ -2431,21 +2434,8 @@ lnk_build_win32_image(TP_Arena *arena, TP_Context *tp, LNK_Config *config, LNK_S } // assign section indices to sections - { - U64 sect_idx = 0; - for (LNK_SectionNode *sect_n = sectab->list.first; sect_n != 0; sect_n = sect_n->next) { - sect_n->data.sect_idx = sect_idx++; - } - } - - // assign section indices to contribs for (LNK_SectionNode *sect_n = sectab->list.first; sect_n != 0; sect_n = sect_n->next) { - LNK_Section *sect = §_n->data; - for (LNK_SectionContribChunk *sc_chunk = sect->contribs.first; sc_chunk != 0; sc_chunk = sc_chunk->next) { - for (U64 sc_idx = 0; sc_idx < sc_chunk->count; sc_idx += 1) { - sc_chunk->v[sc_idx]->u.sect_idx = sect->sect_idx; - } - } + lnk_assign_section_index(§_n->data, sectab->next_sect_idx++); } // assing layout offsets and sizes to merged sections @@ -2889,6 +2879,7 @@ lnk_build_win32_image(TP_Arena *arena, TP_Context *tp, LNK_Config *config, LNK_S lnk_finalize_section_layout(sectab, reloc, config->file_align); lnk_assign_section_virtual_space(reloc, config->sect_align, &voff_cursor); + lnk_assign_section_index(reloc, sectab->next_sect_idx++); sects = lnk_section_array_from_list(scratch.arena, sectab->list); expected_image_header_size = lnk_compute_win32_image_header_size(config, sects.count); diff --git a/src/linker/lnk_debug_info.c b/src/linker/lnk_debug_info.c index 1d0341ec..451f7377 100644 --- a/src/linker/lnk_debug_info.c +++ b/src/linker/lnk_debug_info.c @@ -3284,14 +3284,16 @@ lnk_build_pdb(TP_Context *tp, { Rng1U64Array image_section_file_ranges = {0}; - image_section_file_ranges.count = image_section_table_count; + image_section_file_ranges.count = 0; image_section_file_ranges.v = push_array(scratch.arena, Rng1U64, image_section_table_count); Rng1U64Array image_section_virt_ranges = {0}; image_section_virt_ranges.count = image_section_table_count; image_section_virt_ranges.v = push_array(scratch.arena, Rng1U64, image_section_table_count); for (U64 i = 0; i < image_section_table_count; i += 1) { COFF_SectionHeader *sect_header = image_section_table[i]; - image_section_file_ranges.v[i] = rng_1u64(sect_header->foff, sect_header->foff + sect_header->fsize); + if (~sect_header->flags & COFF_SectionFlag_CntUninitializedData) { + image_section_file_ranges.v[image_section_file_ranges.count++] = rng_1u64(sect_header->foff, sect_header->foff + sect_header->fsize); + } image_section_virt_ranges.v[i] = rng_1u64(sect_header->voff, sect_header->voff + sect_header->vsize); } diff --git a/src/linker/lnk_section_table.c b/src/linker/lnk_section_table.c index d6898a51..dd902632 100644 --- a/src/linker/lnk_section_table.c +++ b/src/linker/lnk_section_table.c @@ -442,6 +442,20 @@ lnk_finalize_section_layout(LNK_SectionTable *sectab, LNK_Section *sect, U64 fil sect->vsize = cursor; } + +internal void +lnk_assign_section_index(LNK_Section *sect, U64 sect_idx) +{ + sect->sect_idx = sect_idx; + + // assign section indices to contribs + for (LNK_SectionContribChunk *sc_chunk = sect->contribs.first; sc_chunk != 0; sc_chunk = sc_chunk->next) { + for (U64 sc_idx = 0; sc_idx < sc_chunk->count; sc_idx += 1) { + sc_chunk->v[sc_idx]->u.sect_idx = sect_idx; + } + } +} + internal void lnk_assign_section_virtual_space(LNK_Section *sect, U64 sect_align, U64 *voff_cursor) { diff --git a/src/linker/lnk_section_table.h b/src/linker/lnk_section_table.h index de8d988c..28d603eb 100644 --- a/src/linker/lnk_section_table.h +++ b/src/linker/lnk_section_table.h @@ -138,3 +138,8 @@ internal void lnk_section_table_merge(LNK_SectionTable *sectab, L 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);