mirror of
https://github.com/Ed94/raddebugger.git
synced 2026-08-06 22:08:41 +00:00
use global symbol table to detect duplicate imports
This commit is contained in:
committed by
Ryan Fleury
parent
7cea036bc1
commit
8f749f4239
+33
-25
@@ -1544,18 +1544,18 @@ lnk_link_inputs_(TP_Context *tp,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// sort library member refs to match the order of their appearance in the respective obj symbol tables
|
||||||
LNK_LibMemberRef **member_refs = lnk_array_from_lib_member_list(scratch.arena, queued_members);
|
LNK_LibMemberRef **member_refs = lnk_array_from_lib_member_list(scratch.arena, queued_members);
|
||||||
radsort(member_refs, queued_members.count, lnk_lib_member_ref_is_before);
|
radsort(member_refs, queued_members.count, lnk_lib_member_ref_is_before);
|
||||||
|
|
||||||
// load lib member refs
|
// push inputs for lib member refs
|
||||||
for EachIndex(i, queued_members.count) {
|
for EachIndex(i, queued_members.count) {
|
||||||
LNK_LibMemberRef *member_ref = member_refs[i];
|
LNK_LibMemberRef *member_ref = member_refs[i];
|
||||||
LNK_Lib *lib = member_ref->lib;
|
LNK_Lib *lib = member_ref->lib;
|
||||||
U32 member_offset = lib->member_offsets[member_ref->member_idx];
|
LNK_Symbol *link_symbol = lib->was_member_linked[member_ref->member_idx];
|
||||||
LNK_Symbol *link_symbol = lib->was_member_linked[member_ref->member_idx];
|
|
||||||
|
|
||||||
// parse member
|
// parse member
|
||||||
COFF_ArchiveMember member_info = coff_archive_member_from_offset(lib->data, member_offset);
|
COFF_ArchiveMember member_info = coff_archive_member_from_offset(lib->data, lib->member_offsets[member_ref->member_idx]);
|
||||||
COFF_DataType member_type = coff_data_type_from_data(member_info.data);
|
COFF_DataType member_type = coff_data_type_from_data(member_info.data);
|
||||||
|
|
||||||
switch (member_type) {
|
switch (member_type) {
|
||||||
@@ -1564,44 +1564,54 @@ lnk_link_inputs_(TP_Context *tp,
|
|||||||
|
|
||||||
// import machine compat check
|
// import machine compat check
|
||||||
if (import_header.machine != config->machine) {
|
if (import_header.machine != config->machine) {
|
||||||
lnk_error(LNK_Error_IncompatibleMachine, "symbol %S pulled in import with incompatible machine %S (expected %S)",
|
LNK_ObjSymbolRef ref = lnk_ref_from_symbol(link_symbol);
|
||||||
import_header.func_name,
|
lnk_error_obj(LNK_Error_IncompatibleMachine,
|
||||||
coff_string_from_machine_type(import_header.machine),
|
ref.obj,
|
||||||
coff_string_from_machine_type(config->machine));
|
"symbol %S pulls-in import from %S for an incompatible machine %S (expected machine %S)",
|
||||||
|
link_symbol->name,
|
||||||
|
str8_chop_last_slash(lib->path),
|
||||||
|
coff_string_from_machine_type(import_header.machine),
|
||||||
|
coff_string_from_machine_type(config->machine));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// skip duplicate import inputer
|
// was import already created?
|
||||||
if (hash_table_search_string_raw(imps->import_stub_ht, import_header.func_name)) { break; }
|
LNK_Symbol *is_import_loaded = lnk_symbol_table_search(symtab, link_symbol->name);
|
||||||
hash_table_push_string_raw(imps->arena, imps->import_stub_ht, import_header.func_name, 0);
|
if (is_import_loaded) {
|
||||||
|
COFF_SymbolValueInterpType interp = lnk_interp_from_symbol(is_import_loaded);
|
||||||
|
if (interp != COFF_SymbolValueInterp_Undefined) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// create import stub (later replaced with acutal import generated by linker)
|
// create import stub symbol (later replaced with actual import)
|
||||||
LNK_Symbol *import_stub = lnk_symbol_table_search(symtab, str8_lit(LNK_IMPORT_STUB));
|
LNK_Symbol *import_stub = lnk_symbol_table_search(symtab, str8_lit(LNK_IMPORT_STUB));
|
||||||
LNK_ObjSymbolRef import_symbol_ref = lnk_ref_from_symbol(import_stub);
|
LNK_ObjSymbolRef import_symbol_ref = lnk_ref_from_symbol(import_stub);
|
||||||
LNK_Symbol *import_symbol = lnk_make_symbol(symtab->arena->v[0], link_symbol->name, import_symbol_ref.obj, import_symbol_ref.symbol_idx);
|
LNK_Symbol *import_symbol = lnk_make_symbol(symtab->arena->v[0], link_symbol->name, import_symbol_ref.obj, import_symbol_ref.symbol_idx);
|
||||||
lnk_symbol_table_push(symtab, import_symbol);
|
lnk_symbol_table_push(symtab, import_symbol);
|
||||||
|
|
||||||
// search DLL symbol list
|
// find DLL with import symbols
|
||||||
B32 is_delay_load = lnk_is_dll_delay_load(config, import_header.dll_name);
|
B32 is_delay_load = lnk_is_dll_delay_load(config, import_header.dll_name);
|
||||||
String8List *dll_names = is_delay_load ? &imps->delayed_dll_names : &imps->static_dll_names;
|
String8List *dll_names = is_delay_load ? &imps->delayed_dll_names : &imps->static_dll_names;
|
||||||
HashTable *imports_ht = is_delay_load ? imps->delayed_imports : imps->static_imports;
|
HashTable *imports_ht = is_delay_load ? imps->delayed_imports : imps->static_imports;
|
||||||
PE_MakeImportList *import_symbols = hash_table_search_path_raw(imports_ht, import_header.dll_name);
|
PE_MakeImportList *import_symbols = hash_table_search_path_raw(imports_ht, import_header.dll_name);
|
||||||
|
|
||||||
|
// create record for a first time-DLL
|
||||||
if (import_symbols == 0) {
|
if (import_symbols == 0) {
|
||||||
import_symbols = push_array(imps->arena, PE_MakeImportList, 1);
|
import_symbols = push_array(imps->arena, PE_MakeImportList, 1);
|
||||||
str8_list_push(imps->arena, dll_names, import_header.dll_name);
|
str8_list_push(imps->arena, dll_names, import_header.dll_name);
|
||||||
hash_table_push_path_raw(imps->arena, imports_ht, import_header.dll_name, import_symbols);
|
hash_table_push_path_raw(imps->arena, imports_ht, import_header.dll_name, import_symbols);
|
||||||
}
|
}
|
||||||
|
|
||||||
// push symbol
|
// push make import info
|
||||||
PE_MakeImport make_import = { .header = member_info.data, .make_jump_thunk = !str8_starts_with(link_symbol->name, str8_lit("__imp_")) };
|
pe_make_import_header_list_push(imps->arena, import_symbols, (PE_MakeImport){ .header = member_info.data, .make_jump_thunk = !str8_starts_with(link_symbol->name, str8_lit("__imp_")) });
|
||||||
pe_make_import_header_list_push(imps->arena, import_symbols, make_import);
|
|
||||||
} break;
|
} break;
|
||||||
case COFF_DataType_BigObj:
|
case COFF_DataType_BigObj:
|
||||||
case COFF_DataType_Obj: {
|
case COFF_DataType_Obj: {
|
||||||
String8 obj_path = coff_parse_long_name(lib->long_names, member_info.header.name);
|
String8 obj_path = coff_parse_long_name(lib->long_names, member_info.header.name);
|
||||||
|
|
||||||
// obj path in thin archive has slash appended which screws up
|
// obj path in thin archive has slash appended which screws up
|
||||||
// file lookup on disk; it couble be there to enable paths to symbols
|
// file lookup on disk; it could be there to enable paths to symbols
|
||||||
// but we don't use this feature
|
// but we don't use this feature
|
||||||
String8 slash = str8_lit("/");
|
String8 slash = str8_lit("/");
|
||||||
if (str8_ends_with(obj_path, slash, 0)) {
|
if (str8_ends_with(obj_path, slash, 0)) {
|
||||||
@@ -1610,8 +1620,7 @@ lnk_link_inputs_(TP_Context *tp,
|
|||||||
|
|
||||||
B32 is_thin = lib->type == COFF_Archive_Thin;
|
B32 is_thin = lib->type == COFF_Archive_Thin;
|
||||||
if (is_thin) {
|
if (is_thin) {
|
||||||
|
// obj path in thin archive is relative to the directory with archive
|
||||||
// obj path in thin archive is relative to directory with archive
|
|
||||||
String8List obj_path_list = {0};
|
String8List obj_path_list = {0};
|
||||||
str8_list_push(scratch.arena, &obj_path_list, str8_chop_last_slash(lib->path));
|
str8_list_push(scratch.arena, &obj_path_list, str8_chop_last_slash(lib->path));
|
||||||
str8_list_push(scratch.arena, &obj_path_list, obj_path);
|
str8_list_push(scratch.arena, &obj_path_list, obj_path);
|
||||||
@@ -1714,7 +1723,6 @@ lnk_link_image(TP_Context *tp, TP_Arena *arena, LNK_Config *config, LNK_Inputer
|
|||||||
imps->arena = imps_arena;
|
imps->arena = imps_arena;
|
||||||
imps->static_imports = hash_table_init(imps->arena, 0x1000);
|
imps->static_imports = hash_table_init(imps->arena, 0x1000);
|
||||||
imps->delayed_imports = hash_table_init(imps->arena, 0x1000);
|
imps->delayed_imports = hash_table_init(imps->arena, 0x1000);
|
||||||
imps->import_stub_ht = hash_table_init(imps->arena, 0x10000);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// input :null_obj
|
// input :null_obj
|
||||||
|
|||||||
@@ -82,7 +82,6 @@ typedef struct LNK_ImportTables
|
|||||||
String8List static_dll_names;
|
String8List static_dll_names;
|
||||||
HashTable *static_imports;
|
HashTable *static_imports;
|
||||||
HashTable *delayed_imports;
|
HashTable *delayed_imports;
|
||||||
HashTable *import_stub_ht;
|
|
||||||
} LNK_ImportTables;
|
} LNK_ImportTables;
|
||||||
|
|
||||||
typedef struct LNK_Link
|
typedef struct LNK_Link
|
||||||
|
|||||||
Reference in New Issue
Block a user