merge .bss with custom section to simplify linker output verification

This commit is contained in:
Nikita Smith
2025-06-06 20:09:37 -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);
String8 a_obj = coff_obj_writer_serialize(scratch.arena, obj_writer);
coff_obj_writer_release(&obj_writer);
if (!t_write_file(a_obj_name, a_obj)) {
goto exit;
}
if (!t_write_file(a_obj_name, a_obj)) { goto exit; }
}
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);
String8 b_obj = coff_obj_writer_serialize(scratch.arena, obj_writer);
coff_obj_writer_release(&obj_writer);
if (!t_write_file(b_obj_name, b_obj)) {
goto exit;
}
if (!t_write_file(b_obj_name, b_obj)) { goto exit; }
}
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);
String8 entry_obj = coff_obj_writer_serialize(scratch.arena, obj_writer);
coff_obj_writer_release(&obj_writer);
if (!t_write_file(entry_obj_name, entry_obj)) {
goto exit;
}
if (!t_write_file(entry_obj_name, entry_obj)) { 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");
if (linker_exit_code != 0) {
goto exit;
}
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; }
String8 exe = t_read_file(scratch.arena, str8_lit("a.exe"));
PE_BinInfo pe = pe_bin_info_from_data(scratch.arena, exe);
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 *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"));
if (data_sect == 0) {
goto exit;
}
// blocks must be sorted in descending order to reduce alignment padding
if (comm_sect->vsize != 0xB) { goto exit; }
// test common block sort, if absent vsize is 0x1D
if (data_sect->vsize != 0x1B) {
goto exit;
}
String8 data = str8_substr(exe, rng_1u64(data_sect->foff, data_sect->foff + data_sect->fsize));
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;
}
// ensure linker correctly patched addresses for symbols pointing into common block
String8 data = str8_substr(exe, rng_1u64(data_sect->foff, data_sect->foff + data_sect->fsize));
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; }
if (*b_addr != (pe.image_base + comm_sect->voff + 0x0)) { goto exit; }
result = T_Result_Pass;
exit:;
scratch_end(scratch);
return result;