merge .bss with custom section to simplify linker output verification

This commit is contained in:
Nikita Smith
2025-06-25 10:53:24 -07:00
committed by Ryan Fleury
parent 15836572f4
commit 95bea877ab
+17 -34
View File
@@ -1632,9 +1632,7 @@ t_common_block(void)
coff_obj_writer_section_push_reloc(obj_writer, data_sect, 0, symbol, COFF_Reloc_X64_Addr32); coff_obj_writer_section_push_reloc(obj_writer, data_sect, 0, symbol, COFF_Reloc_X64_Addr32);
String8 a_obj = coff_obj_writer_serialize(scratch.arena, obj_writer); String8 a_obj = coff_obj_writer_serialize(scratch.arena, obj_writer);
coff_obj_writer_release(&obj_writer); coff_obj_writer_release(&obj_writer);
if (!t_write_file(a_obj_name, a_obj)) { if (!t_write_file(a_obj_name, a_obj)) { goto exit; }
goto exit;
}
} }
String8 b_obj_name = str8_lit("b.obj"); String8 b_obj_name = str8_lit("b.obj");
@@ -1647,9 +1645,7 @@ t_common_block(void)
coff_obj_writer_section_push_reloc(obj_writer, data_sect, 0, symbol, COFF_Reloc_X64_Addr64); coff_obj_writer_section_push_reloc(obj_writer, data_sect, 0, symbol, COFF_Reloc_X64_Addr64);
String8 b_obj = coff_obj_writer_serialize(scratch.arena, obj_writer); String8 b_obj = coff_obj_writer_serialize(scratch.arena, obj_writer);
coff_obj_writer_release(&obj_writer); coff_obj_writer_release(&obj_writer);
if (!t_write_file(b_obj_name, b_obj)) { if (!t_write_file(b_obj_name, b_obj)) { goto exit; }
goto exit;
}
} }
String8 entry_obj_name = str8_lit("entry.obj"); String8 entry_obj_name = str8_lit("entry.obj");
@@ -1660,45 +1656,32 @@ t_common_block(void)
coff_obj_writer_push_symbol_extern(obj_writer, str8_lit("my_entry"), 0, text_sect); coff_obj_writer_push_symbol_extern(obj_writer, str8_lit("my_entry"), 0, text_sect);
String8 entry_obj = coff_obj_writer_serialize(scratch.arena, obj_writer); String8 entry_obj = coff_obj_writer_serialize(scratch.arena, obj_writer);
coff_obj_writer_release(&obj_writer); coff_obj_writer_release(&obj_writer);
if (!t_write_file(entry_obj_name, entry_obj)) { if (!t_write_file(entry_obj_name, entry_obj)) { goto exit; }
goto exit;
}
} }
int linker_exit_code = t_invoke_linkerf("/subsystem:console /entry:my_entry /out:a.exe /fixed /largeaddressaware:no a.obj b.obj entry.obj"); int linker_exit_code = t_invoke_linkerf("/subsystem:console /entry:my_entry /out:a.exe /fixed /largeaddressaware:no /merge:.bss=.comm a.obj b.obj entry.obj");
if (linker_exit_code != 0) { goto exit; }
if (linker_exit_code != 0) {
goto exit;
}
String8 exe = t_read_file(scratch.arena, str8_lit("a.exe")); String8 exe = t_read_file(scratch.arena, str8_lit("a.exe"));
PE_BinInfo pe = pe_bin_info_from_data(scratch.arena, exe); PE_BinInfo pe = pe_bin_info_from_data(scratch.arena, exe);
String8 string_table = str8_substr(exe, pe.string_table_range); String8 string_table = str8_substr(exe, pe.string_table_range);
COFF_SectionHeader *section_table = (COFF_SectionHeader *)str8_substr(exe, pe.section_table_range).str; COFF_SectionHeader *section_table = (COFF_SectionHeader *)str8_substr(exe, pe.section_table_range).str;
COFF_SectionHeader *comm_sect = t_coff_section_header_from_name(string_table, section_table, pe.section_count, str8_lit(".comm"));
COFF_SectionHeader *data_sect = t_coff_section_header_from_name(string_table, section_table, pe.section_count, str8_lit(".data"));
if (comm_sect == 0) { goto exit; }
if (data_sect == 0) { goto exit; }
COFF_SectionHeader *data_sect = t_coff_section_header_from_name(string_table, section_table, pe.section_count, str8_lit(".data")); // blocks must be sorted in descending order to reduce alignment padding
if (data_sect == 0) { if (comm_sect->vsize != 0xB) { goto exit; }
goto exit;
}
// test common block sort, if absent vsize is 0x1D // ensure linker correctly patched addresses for symbols pointing into common block
if (data_sect->vsize != 0x1B) { String8 data = str8_substr(exe, rng_1u64(data_sect->foff, data_sect->foff + data_sect->fsize));
goto exit; U32 *a_addr = (U32 *)data.str;
} U64 *b_addr = (U64 *)(data.str + sizeof(a_data));
if (*a_addr != (pe.image_base + comm_sect->voff + 0x8)) { goto exit; }
String8 data = str8_substr(exe, rng_1u64(data_sect->foff, data_sect->foff + data_sect->fsize)); if (*b_addr != (pe.image_base + comm_sect->voff + 0x0)) { goto exit; }
U32 *a_addr = (U32 *)data.str;
U64 *b_addr = (U64 *)(data.str + sizeof(a_data));
if ((*a_addr) - (pe.image_base + data_sect->voff) != 0x18) {
goto exit;
}
if ((*b_addr) - (pe.image_base + data_sect->voff) != 0x10) {
goto exit;
}
result = T_Result_Pass; result = T_Result_Pass;
exit:; exit:;
scratch_end(scratch); scratch_end(scratch);
return result; return result;