don't create BIAT and UIAT sections when not requested

This commit is contained in:
Nikita Smith
2025-05-21 15:36:29 -07:00
committed by Ryan Fleury
parent 9c93ee1579
commit f0a967a15d
5 changed files with 80 additions and 56 deletions
+23
View File
@@ -636,3 +636,26 @@ u64_array_bsearch(U64 *arr, U64 count, U64 value)
return max_U64;
}
////////////////////////////////
internal U64
index_of_zero_u32(U32 *ptr, U64 count)
{
for (U64 i = 0; i < count; i += 1) {
if (ptr[i] == 0) {
return i;
}
}
return max_U64;
}
internal U64
index_of_zero_u64(U64 *ptr, U64 count)
{
for (U64 i = 0; i < count; i += 1) {
if (ptr[i] == 0) {
return i;
}
}
return max_U64;
}
+5
View File
@@ -925,4 +925,9 @@ internal U64 ring_read(U8 *ring_base, U64 ring_size, U64 ring_pos, void *dst_dat
internal U64 u64_array_bsearch(U64 *arr, U64 count, U64 value);
////////////////////////////////
internal U64 index_of_zero_u32(U32 *ptr, U64 count);
internal U64 index_of_zero_u64(U64 *ptr, U64 count);
#endif // BASE_CORE_H
+6 -3
View File
@@ -1190,13 +1190,16 @@ THREAD_POOL_TASK_FUNC(lnk_obj_reloc_patcher)
for (U64 sect_idx = 0; sect_idx < obj_header.section_count_no_null; sect_idx += 1) {
COFF_SectionHeader *section_header = &section_table[sect_idx];
// was section discarded?
if (section_header->flags & COFF_SectionFlag_LnkRemove) {
continue;
}
// find section relocs
COFF_RelocInfo reloc_info = coff_reloc_info_from_section_header(obj->data, section_header);
COFF_Reloc *relocs = (COFF_Reloc *)(obj->data.str + reloc_info.array_off);
// apply relocs
for (U64 reloc_idx = 0; reloc_idx < reloc_info.count; reloc_idx += 1) {
COFF_Reloc *reloc = &relocs[reloc_idx];
@@ -3154,14 +3157,14 @@ lnk_build_win32_image(TP_Arena *arena, TP_Context *tp, LNK_Config *config, LNK_S
{
LNK_Section *didat_sect = lnk_section_table_search(sectab, str8_lit(".didat"), PE_IDATA_SECTION_FLAGS);
LNK_Symbol *null_import_desc = lnk_symbol_table_search(symtab, LNK_SymbolScope_Defined, str8_lit("__NULL_DELAY_IMPORT_DESCRIPTOR"));
LNK_Symbol *last_import_desc = lnk_symbol_table_searchf(symtab, LNK_SymbolScope_Defined, "\x7f%S_NULL_THUNK_DATA_DLA", lnk_get_image_name(config));
if (didat_sect && null_import_desc && last_import_desc) {
LNK_Symbol *last_null_thunk = lnk_symbol_table_searchf(symtab, LNK_SymbolScope_Defined, "\x7f%S_NULL_THUNK_DATA_DLA", lnk_get_image_name(config));
if (didat_sect && null_import_desc && last_null_thunk) {
COFF_ParsedSymbol null_import_desc_parsed = lnk_parsed_symbol_from_coff_symbol_idx(null_import_desc->u.defined.obj, null_import_desc->u.defined.symbol_idx);
LNK_SectionContrib *didat_first_contrib = lnk_get_first_section_contrib(didat_sect);
PE_DataDirectory *import_dir = str8_deserial_get_raw_ptr(image_data, pe.data_dir_range.min + sizeof(PE_DataDirectory)*PE_DataDirectoryIndex_DELAY_IMPORT, sizeof(PE_DataDirectory));
Assert(null_import_desc_parsed.section_number == didat_first_contrib->u.sect_idx+1);
Assert(null_import_desc_parsed.value >= didat_first_contrib->u.off);
import_dir->virt_off = image_section_table[didat_first_contrib->u.sect_idx]->voff + didat_first_contrib->u.off;
import_dir->virt_off = image_section_table[didat_first_contrib->u.sect_idx+1]->voff + didat_first_contrib->u.off;
import_dir->virt_size = null_import_desc_parsed.value - didat_first_contrib->u.off;
}
}
+40 -49
View File
@@ -998,33 +998,24 @@ pe_parsed_imports_from_data(Arena *arena,
{
PE_ParsedImport *imports = 0;
U64 import_count = 0;
U64 name_table_off = coff_foff_from_voff(sections, section_count, name_table_voff);
U64 name_table_foff = coff_foff_from_voff(sections, section_count, name_table_voff);
String8 entries = str8_substr(raw_data, rng_1u64(name_table_foff, raw_data.size));
if (is_pe32) {
for (;; ++import_count) {
U32 raw_entry = 0;
str8_deserial_read_struct(raw_data, name_table_off + import_count*sizeof(raw_entry), &raw_entry);
if (raw_entry == 0) {
break;
}
}
import_count = index_of_zero_u32((U32 *)entries.str, entries.size/sizeof(U32));
if (import_count == max_U64) { import_count = 0; }
imports = push_array(arena, PE_ParsedImport, import_count);
for (U64 imp_idx = 0; imp_idx < import_count; ++imp_idx) {
for (U64 imp_idx = 0; imp_idx < import_count; imp_idx += 1) {
U32 raw_entry = 0;
str8_deserial_read_struct(raw_data, name_table_off + imp_idx*sizeof(raw_entry), &raw_entry);
B32 is_ordinal = raw_entry & (1 << 31);
PE_ParsedImport *imp = imports+imp_idx;
++imp_idx;
str8_deserial_read_struct(entries, imp_idx*sizeof(raw_entry), &raw_entry);
B32 is_ordinal = ExtractBit(raw_entry, 31);
if (is_ordinal) {
// fill out ordinal import
PE_ParsedImport *imp = imports+imp_idx;
imp->type = PE_ParsedImport_Ordinal;
imp->u.ordinal = raw_entry & max_U16;
imp->u.ordinal = Extract16(raw_entry, 0);
} else {
// map voff -> foff
U64 off = coff_foff_from_voff(sections, section_count, raw_entry);
@@ -1036,35 +1027,27 @@ pe_parsed_imports_from_data(Arena *arena,
str8_deserial_read_cstr(raw_data, off+sizeof(hint), &name);
// fill out named import
PE_ParsedImport *imp = imports+imp_idx;
imp->type = PE_ParsedImport_Name;
imp->u.name.hint = hint;
imp->u.name.string = name;
}
}
} else {
for (;; ++import_count) {
U64 raw_entry = 0;
str8_deserial_read_struct(raw_data, name_table_off + import_count*sizeof(raw_entry), &raw_entry);
if (raw_entry == 0) {
break;
}
}
import_count = index_of_zero_u64((U64 *)entries.str, entries.size/sizeof(U64));
if (import_count == max_U64) { import_count = 0; }
imports = push_array(arena, PE_ParsedImport, import_count);
for (U64 imp_idx = 0; imp_idx < import_count; ++imp_idx) {
for (U64 imp_idx = 0; imp_idx < import_count; imp_idx += 1) {
U64 raw_entry = 0;
str8_deserial_read_struct(raw_data, name_table_off + imp_idx*sizeof(raw_entry), &raw_entry);
B32 is_ordinal = raw_entry & (1ull << 63);
PE_ParsedImport *imp = imports+imp_idx;
++imp_idx;
str8_deserial_read_struct(entries, imp_idx*sizeof(raw_entry), &raw_entry);
B32 is_ordinal = ExtractBit(raw_entry, 63);
if (is_ordinal) {
// fill out ordinal import
PE_ParsedImport *imp = imports+imp_idx;
imp->type = PE_ParsedImport_Ordinal;
imp->u.ordinal = raw_entry & max_U16;
imp->u.ordinal = Extract16(raw_entry, 0);
} else {
// map voff -> foff
U64 off = coff_foff_from_voff(sections, section_count, raw_entry);
@@ -1076,6 +1059,7 @@ pe_parsed_imports_from_data(Arena *arena,
str8_deserial_read_cstr(raw_data, off + sizeof(hint), &name);
// fill out named import
PE_ParsedImport *imp = imports+imp_idx;
imp->type = PE_ParsedImport_Name;
imp->u.name.hint = hint;
imp->u.name.string = name;
@@ -1220,18 +1204,25 @@ pe_delay_imports_from_data(Arena *arena,
raw_dll->name_table_voff,
&import_count);
// parse bound table
U64 bound_table_foff = coff_foff_from_voff(sections, section_count, raw_dll->bound_table_voff);
Rng1U64 bound_table_range = rng_1u64(bound_table_foff, raw_data.size);
U64 bound_table_count;
U64 * bound_table = pe_array_from_null_term_addr(arena, is_pe32, raw_data, bound_table_range, &bound_table_count);
Rng1U64 bound_table_range = {0};
if (raw_dll->bound_table_voff) {
U64 bound_table_foff = coff_foff_from_voff(sections, section_count, raw_dll->bound_table_voff);
bound_table_range = rng_1u64(bound_table_foff, raw_data.size);
}
U64 bound_table_count;
U64 *bound_table = pe_array_from_null_term_addr(arena, is_pe32, raw_data, bound_table_range, &bound_table_count);
// parse unload table
U64 unload_table_foff = coff_foff_from_voff(sections, section_count, raw_dll->unload_table_voff);
Rng1U64 unload_table_range = rng_1u64(unload_table_foff, raw_data.size);
U64 unload_table_count;
U64 * unload_table = pe_array_from_null_term_addr(arena, is_pe32, raw_data, unload_table_range, &unload_table_count);
Rng1U64 unload_table_range = {0};
if (raw_dll->unload_table_voff) {
U64 unload_table_foff = coff_foff_from_voff(sections, section_count, raw_dll->unload_table_voff);
unload_table_range = rng_1u64(unload_table_foff, raw_data.size);
}
U64 unload_table_count;
U64 *unload_table = pe_array_from_null_term_addr(arena, is_pe32, raw_data, unload_table_range, &unload_table_count);
// fill out DLL
PE_ParsedDelayDLLImport *dll = dlls+dll_idx;
dll->attributes = raw_dll->attributes;
+6 -4
View File
@@ -341,11 +341,11 @@ pe_make_import_dll_obj_delayed(Arena *arena, COFF_TimeStamp time_stamp, COFF_Mac
COFF_ObjSection *iat_sect = coff_obj_writer_push_section(obj_writer, str8_lit(".didat$5"), PE_IDATA_SECTION_FLAGS|import_align, str8_zero());
COFF_ObjSection *int_sect = coff_obj_writer_push_section(obj_writer, str8_lit(".didat$6"), PE_IDATA_SECTION_FLAGS|COFF_SectionFlag_Align2Bytes, str8_zero());
COFF_ObjSection *dll_name_sect = coff_obj_writer_push_section(obj_writer, str8_lit(".didat$7"), PE_IDATA_SECTION_FLAGS|COFF_SectionFlag_Align2Bytes, dll_name_cstr);
COFF_ObjSection *biat_sect = coff_obj_writer_push_section(obj_writer, str8_lit(".didat$8"), PE_IDATA_SECTION_FLAGS|import_align, str8_zero());
COFF_ObjSection *uiat_sect = coff_obj_writer_push_section(obj_writer, str8_lit(".didat$9"), PE_IDATA_SECTION_FLAGS|import_align, str8_zero());
COFF_ObjSection *code_sect = coff_obj_writer_push_section(obj_writer, str8_lit(".text$i"), PE_TEXT_SECTION_FLAGS, str8_zero());
COFF_ObjSection *handle_sect = coff_obj_writer_push_section(obj_writer, str8_lit(".data$h"), PE_DATA_SECTION_FLAGS, str8_array(handle, handle_size));
COFF_ObjSection *code_sect = coff_obj_writer_push_section(obj_writer, str8_lit(".text$i"), PE_TEXT_SECTION_FLAGS|COFF_SectionFlag_Align1Bytes, str8_zero());
COFF_ObjSection *handle_sect = coff_obj_writer_push_section(obj_writer, str8_lit(".data$h"), PE_DATA_SECTION_FLAGS|COFF_SectionFlag_Align1Bytes, str8_array(handle, handle_size));
COFF_ObjSection *debug_sect = coff_obj_writer_push_section(obj_writer, str8_lit(".debug$S"), PE_DEBUG_SECTION_FLAGS|COFF_SectionFlag_Align1Bytes, debug_symbols);
COFF_ObjSection *biat_sect = 0;
COFF_ObjSection *uiat_sect = 0;
// sections symbols
COFF_ObjSymbol *dll_symbol = coff_obj_writer_push_symbol_static(obj_writer, dll_sect->name, 0, dll_sect);
@@ -362,12 +362,14 @@ pe_make_import_dll_obj_delayed(Arena *arena, COFF_TimeStamp time_stamp, COFF_Mac
// patch BIAT virtual offset in import header
if (emit_biat) {
biat_sect = coff_obj_writer_push_section(obj_writer, str8_lit(".didat$8"), PE_IDATA_SECTION_FLAGS|import_align, str8_zero());
COFF_ObjSymbol *biat_symbol = coff_obj_writer_push_symbol_static(obj_writer, biat_sect->name, 0, biat_sect);
coff_obj_writer_section_push_reloc_voff(obj_writer, dll_sect, OffsetOf(PE_DelayedImportEntry, bound_table_voff), biat_symbol);
}
// patch UIAT virtual offset in import header
if (emit_uiat) {
uiat_sect = coff_obj_writer_push_section(obj_writer, str8_lit(".didat$9"), PE_IDATA_SECTION_FLAGS|import_align, str8_zero());
COFF_ObjSymbol *uiat_symbol = coff_obj_writer_push_symbol_static(obj_writer, uiat_sect->name, 0, uiat_sect);
coff_obj_writer_section_push_reloc_voff(obj_writer, dll_sect, OffsetOf(PE_DelayedImportEntry, unload_table_voff), uiat_symbol);
}