diff --git a/src/torture/torture.c b/src/torture/torture.c index 1bf492a2..ff175d87 100644 --- a/src/torture/torture.c +++ b/src/torture/torture.c @@ -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;