mirror of
https://github.com/Ed94/raddebugger.git
synced 2026-06-13 07:32:23 -07: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);
|
||||
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) {
|
||||
LNK_LibMemberRef *member_ref = member_refs[i];
|
||||
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_LibMemberRef *member_ref = member_refs[i];
|
||||
LNK_Lib *lib = member_ref->lib;
|
||||
LNK_Symbol *link_symbol = lib->was_member_linked[member_ref->member_idx];
|
||||
|
||||
// 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);
|
||||
|
||||
switch (member_type) {
|
||||
@@ -1564,44 +1564,54 @@ lnk_link_inputs_(TP_Context *tp,
|
||||
|
||||
// import machine compat check
|
||||
if (import_header.machine != config->machine) {
|
||||
lnk_error(LNK_Error_IncompatibleMachine, "symbol %S pulled in import with incompatible machine %S (expected %S)",
|
||||
import_header.func_name,
|
||||
coff_string_from_machine_type(import_header.machine),
|
||||
coff_string_from_machine_type(config->machine));
|
||||
LNK_ObjSymbolRef ref = lnk_ref_from_symbol(link_symbol);
|
||||
lnk_error_obj(LNK_Error_IncompatibleMachine,
|
||||
ref.obj,
|
||||
"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;
|
||||
}
|
||||
|
||||
// skip duplicate import inputer
|
||||
if (hash_table_search_string_raw(imps->import_stub_ht, import_header.func_name)) { break; }
|
||||
hash_table_push_string_raw(imps->arena, imps->import_stub_ht, import_header.func_name, 0);
|
||||
// was import already created?
|
||||
LNK_Symbol *is_import_loaded = lnk_symbol_table_search(symtab, link_symbol->name);
|
||||
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_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_table_push(symtab, import_symbol);
|
||||
|
||||
// search DLL symbol list
|
||||
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;
|
||||
HashTable *imports_ht = is_delay_load ? imps->delayed_imports : imps->static_imports;
|
||||
// find DLL with import symbols
|
||||
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;
|
||||
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);
|
||||
|
||||
// create record for a first time-DLL
|
||||
if (import_symbols == 0) {
|
||||
import_symbols = push_array(imps->arena, PE_MakeImportList, 1);
|
||||
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);
|
||||
}
|
||||
|
||||
// push symbol
|
||||
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, make_import);
|
||||
// push make import info
|
||||
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_")) });
|
||||
} break;
|
||||
case COFF_DataType_BigObj:
|
||||
case COFF_DataType_Obj: {
|
||||
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
|
||||
// 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
|
||||
String8 slash = str8_lit("/");
|
||||
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;
|
||||
if (is_thin) {
|
||||
|
||||
// obj path in thin archive is relative to directory with archive
|
||||
// obj path in thin archive is relative to the directory with archive
|
||||
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, 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->static_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
|
||||
|
||||
@@ -82,7 +82,6 @@ typedef struct LNK_ImportTables
|
||||
String8List static_dll_names;
|
||||
HashTable *static_imports;
|
||||
HashTable *delayed_imports;
|
||||
HashTable *import_stub_ht;
|
||||
} LNK_ImportTables;
|
||||
|
||||
typedef struct LNK_Link
|
||||
|
||||
Reference in New Issue
Block a user