mirror of
https://github.com/Ed94/raddebugger.git
synced 2026-11-14 10:10:11 -08:00
prune dead static imports with /OPT:REF
This commit is contained in:
1 parent
5894d3eaa2
commit
e8aaf00629
2 files changed
+71
-34
No files matched your search
@@ -4783,21 +4783,55 @@ TEST(import_kernel32)
|
|||||||
{0},
|
{0},
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"dead", ".text$dead", str8(0, 4),
|
||||||
|
.flags = "rx:code@1",
|
||||||
|
.raw_flags = COFF_SectionFlag_LnkCOMDAT,
|
||||||
|
.relocs = (T_COFF_DefReloc[]){
|
||||||
|
T_COFF_DefReloc(X64_Addr32Nb, 0, "__imp_CompareStringW"),
|
||||||
|
{0},
|
||||||
|
}
|
||||||
|
},
|
||||||
{0},
|
{0},
|
||||||
},
|
},
|
||||||
.symbols = (T_COFF_DefSymbol[]){
|
.symbols = (T_COFF_DefSymbol[]){
|
||||||
|
T_COFF_DefSymbol_Secdef("dead", COFF_ComdatSelect_Any),
|
||||||
T_COFF_DefSymbol_Extern("test", "data", 0),
|
T_COFF_DefSymbol_Extern("test", "data", 0),
|
||||||
T_COFF_DefSymbol_Extern("entry", "text", 0),
|
T_COFF_DefSymbol_Extern("entry", "text", 0),
|
||||||
|
T_COFF_DefSymbol_ExternFunc("dead", "dead", 0),
|
||||||
T_COFF_DefSymbol_Undef("__imp_CreateFileA"),
|
T_COFF_DefSymbol_Undef("__imp_CreateFileA"),
|
||||||
T_COFF_DefSymbol_Undef("__imp_CloseHandle"),
|
T_COFF_DefSymbol_Undef("__imp_CloseHandle"),
|
||||||
|
T_COFF_DefSymbol_Undef("__imp_CompareStringW"),
|
||||||
{0},
|
{0},
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
|
|
||||||
t_invoke_linkerf("/subsystem:console /entry:entry /out:a.exe /fixed import.obj kernel32.lib");
|
t_invoke_linkerf("/subsystem:console /entry:entry /out:a.exe /fixed /opt:ref import.obj kernel32.lib");
|
||||||
T_Ok(g_last_exit_code == 0);
|
T_Ok(g_last_exit_code == 0);
|
||||||
|
|
||||||
{
|
{
|
||||||
|
String8 exe = t_read_file(arena, str8_lit("a.exe"));
|
||||||
|
PE_BinInfo pe = pe_bin_info_from_data(arena, exe);
|
||||||
|
COFF_SectionHeader *section_table = (COFF_SectionHeader *)str8_substr(exe, pe.section_table_range).str;
|
||||||
|
PE_ParsedStaticImportTable imports = pe_static_imports_from_data(arena, pe.is_pe32, pe.section_count, section_table, exe, pe.data_dir_franges[PE_DataDirectoryIndex_IMPORT]);
|
||||||
|
B32 found_create = 0;
|
||||||
|
B32 found_close = 0;
|
||||||
|
B32 found_dead = 0;
|
||||||
|
for EachIndex(dll_idx, imports.count) {
|
||||||
|
PE_ParsedStaticDLLImport *dll = &imports.v[dll_idx];
|
||||||
|
for EachIndex(import_idx, dll->import_count) {
|
||||||
|
PE_ParsedImport *import = &dll->imports[import_idx];
|
||||||
|
if (import->type == PE_ParsedImport_Name) {
|
||||||
|
found_create |= str8_match(import->u.name.string, str8_lit("CreateFileA"), 0);
|
||||||
|
found_close |= str8_match(import->u.name.string, str8_lit("CloseHandle"), 0);
|
||||||
|
found_dead |= str8_match(import->u.name.string, str8_lit("CompareStringW"), 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
T_Ok(found_create);
|
||||||
|
T_Ok(found_close);
|
||||||
|
T_Ok(!found_dead);
|
||||||
|
|
||||||
String8 test_file_path = push_str8f(arena, "%S/test", g_wdir);
|
String8 test_file_path = push_str8f(arena, "%S/test", g_wdir);
|
||||||
delete_file_at_path(test_file_path);
|
delete_file_at_path(test_file_path);
|
||||||
|
|
||||||
|
|||||||
@@ -261,51 +261,41 @@ pe_make_import_dll_obj_static(Arena *arena, COFF_TimeStamp time_stamp, COFF_Mach
|
|||||||
COFF_SectionFlags import_align = coff_section_flag_from_align_size(import_size);
|
COFF_SectionFlags import_align = coff_section_flag_from_align_size(import_size);
|
||||||
|
|
||||||
PE_ImportEntry *impdesc = push_array(obj_writer->arena, PE_ImportEntry, 1);
|
PE_ImportEntry *impdesc = push_array(obj_writer->arena, PE_ImportEntry, 1);
|
||||||
String8 dll_name_cstr = push_cstr(obj_writer->arena, dll_name);
|
COFF_ObjSection *dll_sect = coff_obj_writer_push_section(obj_writer, str8_lit(".idata$2"), PE_IDATA_SECTION_FLAGS|COFF_SectionFlag_Align4Bytes, str8_struct(impdesc));
|
||||||
|
COFF_ObjSymbol *ilt_symbol = 0;
|
||||||
COFF_ObjSection *dll_sect = coff_obj_writer_push_section(obj_writer, str8_lit(".idata$2"), PE_IDATA_SECTION_FLAGS|COFF_SectionFlag_Align4Bytes, str8_struct(impdesc));
|
COFF_ObjSymbol *iat_symbol = 0;
|
||||||
COFF_ObjSection *ilt_sect = coff_obj_writer_push_section(obj_writer, str8_lit(".idata$4"), PE_IDATA_SECTION_FLAGS|import_align, str8_zero());
|
|
||||||
COFF_ObjSection *iat_sect = coff_obj_writer_push_section(obj_writer, str8_lit(".idata$5"), PE_IDATA_SECTION_FLAGS|import_align, str8_zero());
|
|
||||||
COFF_ObjSection *int_sect = coff_obj_writer_push_section(obj_writer, str8_lit(".idata$6"), PE_IDATA_SECTION_FLAGS|COFF_SectionFlag_Align2Bytes, str8_zero());
|
|
||||||
COFF_ObjSection *dll_name_sect = coff_obj_writer_push_section(obj_writer, str8_lit(".idata$6"), PE_IDATA_SECTION_FLAGS|COFF_SectionFlag_Align2Bytes, dll_name_cstr);
|
|
||||||
COFF_ObjSection *code_sect = coff_obj_writer_push_section(obj_writer, str8_lit(".text$zz"), PE_TEXT_SECTION_FLAGS |COFF_SectionFlag_Align1Bytes, str8_zero());
|
|
||||||
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_ObjSymbol *ilt_symbol = coff_obj_writer_push_symbol_static(obj_writer, ilt_sect->name, 0, ilt_sect);
|
|
||||||
COFF_ObjSymbol *iat_symbol = coff_obj_writer_push_symbol_static(obj_writer, iat_sect->name, 0, iat_sect);
|
|
||||||
COFF_ObjSymbol *dll_name_symbol = coff_obj_writer_push_symbol_static(obj_writer, dll_name_sect->name, 0, dll_name_sect);
|
|
||||||
|
|
||||||
// patch import DLL header
|
|
||||||
coff_obj_writer_section_push_reloc_voff(obj_writer, dll_sect, OffsetOf(PE_ImportEntry, lookup_table_voff), ilt_symbol);
|
|
||||||
coff_obj_writer_section_push_reloc_voff(obj_writer, dll_sect, OffsetOf(PE_ImportEntry, name_voff), dll_name_symbol);
|
|
||||||
coff_obj_writer_section_push_reloc_voff(obj_writer, dll_sect, OffsetOf(PE_ImportEntry, import_addr_table_voff), iat_symbol);
|
|
||||||
|
|
||||||
for (PE_MakeImportNode *import_header_n = import_headers.first; import_header_n != 0; import_header_n = import_header_n->next) {
|
for (PE_MakeImportNode *import_header_n = import_headers.first; import_header_n != 0; import_header_n = import_header_n->next) {
|
||||||
COFF_ParsedArchiveImportHeader import_header = coff_archive_import_from_data(import_header_n->v.header);
|
COFF_ParsedArchiveImportHeader import_header = coff_archive_import_from_data(import_header_n->v.header);
|
||||||
|
|
||||||
COFF_ObjSymbol *iat_symbol = 0;
|
COFF_SectionFlags comdat_flags = COFF_SectionFlag_LnkCOMDAT;
|
||||||
|
COFF_ObjSection *ilt_sect = coff_obj_writer_push_section(obj_writer, str8_lit(".idata$4"), PE_IDATA_SECTION_FLAGS|import_align|comdat_flags, str8_zero());
|
||||||
|
COFF_ObjSection *iat_sect = coff_obj_writer_push_section(obj_writer, str8_lit(".idata$5"), PE_IDATA_SECTION_FLAGS|import_align|comdat_flags, str8_zero());
|
||||||
|
coff_obj_writer_push_symbol_secdef(obj_writer, iat_sect, COFF_ComdatSelect_Any);
|
||||||
|
coff_obj_writer_push_symbol_associative(obj_writer, ilt_sect, iat_sect);
|
||||||
|
|
||||||
|
String8 iat_symbol_name = push_str8f(obj_writer->arena, "__imp_%S", import_header.func_name);
|
||||||
|
COFF_ObjSymbol *func_iat_symbol = coff_obj_writer_push_symbol_extern(obj_writer, iat_symbol_name, 0, iat_sect);
|
||||||
|
if (ilt_symbol == 0) {
|
||||||
|
ilt_symbol = coff_obj_writer_push_symbol_static(obj_writer, ilt_sect->name, 0, ilt_sect);
|
||||||
|
iat_symbol = func_iat_symbol;
|
||||||
|
}
|
||||||
switch (import_header.import_by) {
|
switch (import_header.import_by) {
|
||||||
case COFF_ImportBy_Ordinal: {
|
case COFF_ImportBy_Ordinal: {
|
||||||
String8 ordinal_data = coff_ordinal_data_from_hint(obj_writer->arena, import_header.machine, import_header.hint_or_ordinal);
|
String8 ordinal_data = coff_ordinal_data_from_hint(obj_writer->arena, import_header.machine, import_header.hint_or_ordinal);
|
||||||
String8 iat_symbol_name = push_str8f(obj_writer->arena, "__imp_%S", import_header.func_name);
|
|
||||||
iat_symbol = coff_obj_writer_push_symbol_extern(obj_writer, iat_symbol_name, iat_sect->data.total_size, iat_sect);
|
|
||||||
str8_list_push(obj_writer->arena, &ilt_sect->data, ordinal_data);
|
str8_list_push(obj_writer->arena, &ilt_sect->data, ordinal_data);
|
||||||
str8_list_push(obj_writer->arena, &iat_sect->data, ordinal_data);
|
str8_list_push(obj_writer->arena, &iat_sect->data, ordinal_data);
|
||||||
} break;
|
} break;
|
||||||
case COFF_ImportBy_Name: {
|
case COFF_ImportBy_Name: {
|
||||||
// put together name look up entry
|
COFF_ObjSection *int_sect = coff_obj_writer_push_section(obj_writer, str8_lit(".idata$6"), PE_IDATA_SECTION_FLAGS|COFF_SectionFlag_Align2Bytes|comdat_flags, str8_zero());
|
||||||
COFF_ObjSymbol *int_symbol = coff_obj_writer_push_symbol_static(obj_writer, int_sect->name, int_sect->data.total_size, int_sect);
|
coff_obj_writer_push_symbol_associative(obj_writer, int_sect, iat_sect);
|
||||||
|
COFF_ObjSymbol *int_symbol = coff_obj_writer_push_symbol_static(obj_writer, int_sect->name, 0, int_sect);
|
||||||
String8 int_data = coff_make_import_lookup(obj_writer->arena, import_header.hint_or_ordinal, import_header.func_name);
|
String8 int_data = coff_make_import_lookup(obj_writer->arena, import_header.hint_or_ordinal, import_header.func_name);
|
||||||
str8_list_push(obj_writer->arena, &int_sect->data, int_data);
|
str8_list_push(obj_writer->arena, &int_sect->data, int_data);
|
||||||
str8_list_push_aligner(obj_writer->arena, &int_sect->data, 0, 2);
|
str8_list_push_aligner(obj_writer->arena, &int_sect->data, 0, 2);
|
||||||
|
|
||||||
// in the file IAT mirrors ILT, dynamic linker later overwrites it with imported function addresses
|
coff_obj_writer_section_push_reloc_voff(obj_writer, ilt_sect, 0, int_symbol);
|
||||||
String8 iat_symbol_name = push_str8f(obj_writer->arena, "__imp_%S", import_header.func_name);
|
coff_obj_writer_section_push_reloc_voff(obj_writer, iat_sect, 0, int_symbol);
|
||||||
iat_symbol = coff_obj_writer_push_symbol_extern(obj_writer, iat_symbol_name, iat_sect->data.total_size, iat_sect);
|
|
||||||
|
|
||||||
// patch IAT and ILT
|
|
||||||
coff_obj_writer_section_push_reloc_voff(obj_writer, ilt_sect, ilt_sect->data.total_size, int_symbol);
|
|
||||||
coff_obj_writer_section_push_reloc_voff(obj_writer, iat_sect, iat_sect->data.total_size, int_symbol);
|
|
||||||
|
|
||||||
U64 import_size = coff_word_size_from_machine(import_header.machine);
|
U64 import_size = coff_word_size_from_machine(import_header.machine);
|
||||||
U8 *import_entry = push_array(obj_writer->arena, U8, import_size);
|
U8 *import_entry = push_array(obj_writer->arena, U8, import_size);
|
||||||
@@ -320,9 +310,11 @@ pe_make_import_dll_obj_static(Arena *arena, COFF_TimeStamp time_stamp, COFF_Mach
|
|||||||
// emit thunks
|
// emit thunks
|
||||||
if (import_header_n->v.make_jump_thunk) {
|
if (import_header_n->v.make_jump_thunk) {
|
||||||
if (import_header.type == COFF_ImportHeader_Code) {
|
if (import_header.type == COFF_ImportHeader_Code) {
|
||||||
|
COFF_ObjSection *code_sect = coff_obj_writer_push_section(obj_writer, str8_lit(".text$zz"), PE_TEXT_SECTION_FLAGS|COFF_SectionFlag_Align1Bytes|comdat_flags, str8_zero());
|
||||||
|
coff_obj_writer_push_symbol_secdef(obj_writer, code_sect, COFF_ComdatSelect_Any);
|
||||||
switch (import_header.machine) {
|
switch (import_header.machine) {
|
||||||
case COFF_MachineType_Unknown: {} break;
|
case COFF_MachineType_Unknown: {} break;
|
||||||
case COFF_MachineType_X64: { pe_make_indirect_jump_thunk_x64(obj_writer, code_sect, iat_symbol, import_header.func_name); } break;
|
case COFF_MachineType_X64: { pe_make_indirect_jump_thunk_x64(obj_writer, code_sect, func_iat_symbol, import_header.func_name); } break;
|
||||||
default: { NotImplemented; } break;
|
default: { NotImplemented; } break;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -332,10 +324,21 @@ pe_make_import_dll_obj_static(Arena *arena, COFF_TimeStamp time_stamp, COFF_Mach
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (emit_null_thunk) {
|
if (emit_null_thunk) {
|
||||||
str8_list_push(obj_writer->arena, &ilt_sect->data, str8(0, coff_word_size_from_machine(machine)));
|
String8 null_entry = str8(0, coff_word_size_from_machine(machine));
|
||||||
str8_list_push(obj_writer->arena, &iat_sect->data, str8(0, coff_word_size_from_machine(machine)));
|
coff_obj_writer_push_section(obj_writer, str8_lit(".idata$4"), PE_IDATA_SECTION_FLAGS|import_align, null_entry);
|
||||||
|
coff_obj_writer_push_section(obj_writer, str8_lit(".idata$5"), PE_IDATA_SECTION_FLAGS|import_align, null_entry);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
String8 dll_name_cstr = push_cstr(obj_writer->arena, dll_name);
|
||||||
|
COFF_ObjSection *dll_name_sect = coff_obj_writer_push_section(obj_writer, str8_lit(".idata$6"), PE_IDATA_SECTION_FLAGS|COFF_SectionFlag_Align2Bytes, dll_name_cstr);
|
||||||
|
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_ObjSymbol *dll_name_symbol = coff_obj_writer_push_symbol_static(obj_writer, dll_name_sect->name, 0, dll_name_sect);
|
||||||
|
|
||||||
|
Assert(ilt_symbol != 0 && iat_symbol != 0);
|
||||||
|
coff_obj_writer_section_push_reloc_voff(obj_writer, dll_sect, OffsetOf(PE_ImportEntry, lookup_table_voff), ilt_symbol);
|
||||||
|
coff_obj_writer_section_push_reloc_voff(obj_writer, dll_sect, OffsetOf(PE_ImportEntry, name_voff), dll_name_symbol);
|
||||||
|
coff_obj_writer_section_push_reloc_voff(obj_writer, dll_sect, OffsetOf(PE_ImportEntry, import_addr_table_voff), iat_symbol);
|
||||||
|
|
||||||
String8 dll_obj = coff_obj_writer_serialize(arena, obj_writer);
|
String8 dll_obj = coff_obj_writer_serialize(arena, obj_writer);
|
||||||
|
|
||||||
coff_obj_writer_release(&obj_writer);
|
coff_obj_writer_release(&obj_writer);
|
||||||
|
|||||||
Reference in new issue
Block a user