mirror of
https://github.com/Ed94/raddebugger.git
synced 2026-08-08 06:48:41 +00:00
WIP cache COFF symbol interp
This commit is contained in:
committed by
Ryan Fleury
parent
a779d3f1a5
commit
4cc0f4813b
+14
-25
@@ -1701,35 +1701,24 @@ THREAD_POOL_TASK_FUNC(lnk_search_lib_task)
|
||||
U64 i_begin = (c == start_chunk) ? start_idx : 0;
|
||||
U64 i_end = (c == end_chunk) ? end_count : c->count;
|
||||
for (U64 i = i_begin; i < i_end; i += 1) {
|
||||
LNK_Symbol *symbol = c->v[i].symbol;
|
||||
LNK_ObjSymbolRef symbol_ref = lnk_ref_from_symbol(symbol);
|
||||
COFF_ParsedSymbol symbol_parsed = lnk_parsed_symbol_from_coff_symbol_idx_no_name(symbol_ref.obj, symbol_ref.symbol_idx);
|
||||
COFF_SymbolValueInterpType symbol_interp = coff_interp_from_parsed_symbol(symbol_parsed);
|
||||
LNK_Symbol *symbol = c->v[i].symbol;
|
||||
LNK_SymbolSearchType search_type = lnk_search_type_from_symbol(symbol);
|
||||
|
||||
if (symbol_interp == COFF_SymbolValueInterp_Undefined) {
|
||||
if (search_type == LNK_SymbolSearch_Undefined || search_type == LNK_SymbolSearch_WeakLibrary) {
|
||||
U32 member_idx;
|
||||
if (lnk_search_lib(lib, symbol->name, &member_idx)) {
|
||||
lnk_queue_lib_member(arena, task->imports_hm, task->link->lib_member_infos_hm, member_ref_list, symbol, lib, lib_member_infos, member_idx);
|
||||
}
|
||||
} else if (symbol_interp == COFF_SymbolValueInterp_Weak) {
|
||||
COFF_SymbolWeakExt *weak_ext = coff_parse_weak_tag(symbol_parsed, symbol_ref.obj->header.is_big_obj);
|
||||
if (weak_ext->characteristics == COFF_WeakExt_SearchLibrary) {
|
||||
U32 member_idx;
|
||||
if (lnk_search_lib(lib, symbol->name, &member_idx)) {
|
||||
lnk_queue_lib_member(arena, task->imports_hm, task->link->lib_member_infos_hm, member_ref_list, symbol, lib, lib_member_infos, member_idx);
|
||||
}
|
||||
} else if (weak_ext->characteristics == COFF_WeakExt_AntiDependency) {
|
||||
if (search_anti_deps) {
|
||||
LNK_ObjSymbolRef dep_symbol = {0};
|
||||
if (lnk_resolve_weak_symbol(symtab, symbol_ref, &dep_symbol)) {
|
||||
COFF_ParsedSymbol dep_parsed = lnk_parsed_symbol_from_coff_symbol_idx_no_name(dep_symbol.obj, dep_symbol.symbol_idx);
|
||||
COFF_SymbolValueInterpType dep_interp = coff_interp_from_parsed_symbol(dep_parsed);
|
||||
if (dep_interp == COFF_SymbolValueInterp_Weak) {
|
||||
U32 member_idx;
|
||||
if (lnk_search_lib(lib, symbol->name, &member_idx)) {
|
||||
lnk_queue_lib_member(arena, task->imports_hm, task->link->lib_member_infos_hm, member_ref_list, symbol, lib, lib_member_infos, member_idx);
|
||||
}
|
||||
}
|
||||
} else if (search_type == LNK_SymbolSearch_WeakAntiDependency && search_anti_deps) {
|
||||
LNK_ObjSymbolRef symbol_ref = lnk_ref_from_symbol(symbol);
|
||||
LNK_ObjSymbolRef dep_symbol = {0};
|
||||
if (lnk_resolve_weak_symbol(symtab, symbol_ref, &dep_symbol)) {
|
||||
COFF_ParsedSymbol dep_parsed = lnk_parsed_symbol_from_coff_symbol_idx_no_name(dep_symbol.obj, dep_symbol.symbol_idx);
|
||||
COFF_SymbolValueInterpType dep_interp = coff_interp_from_parsed_symbol(dep_parsed);
|
||||
if (dep_interp == COFF_SymbolValueInterp_Weak) {
|
||||
U32 member_idx;
|
||||
if (lnk_search_lib(lib, symbol->name, &member_idx)) {
|
||||
lnk_queue_lib_member(arena, task->imports_hm, task->link->lib_member_infos_hm, member_ref_list, symbol, lib, lib_member_infos, member_idx);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1979,7 +1968,7 @@ lnk_link_inputs(TP_Context *tp,
|
||||
|
||||
// replace the import symbol with a stub, which is later replaced with the real import symbol once import obj is ready.
|
||||
member_ref->link_symbol->first_ref = import_stub->first_ref;
|
||||
member_ref->link_symbol->last_ref = import_stub->last_ref;
|
||||
member_ref->link_symbol->last_ref_and_search_type = import_stub->last_ref_and_search_type;
|
||||
|
||||
// push import member for import obj generation
|
||||
lnk_lib_member_ref_list_push_node(&link->imports, member_ref);
|
||||
|
||||
@@ -457,6 +457,7 @@ THREAD_POOL_TASK_FUNC(lnk_input_coff_symbol_table)
|
||||
for (U64 symbol_idx = 0; symbol_idx < obj->header.symbol_count; symbol_idx += (1 + symbol.aux_symbol_count)) {
|
||||
symbol = lnk_parsed_symbol_from_coff_symbol_idx_no_name(obj, symbol_idx);
|
||||
COFF_SymbolValueInterpType interp = coff_interp_from_parsed_symbol(symbol);
|
||||
LNK_SymbolSearchType search_type = lnk_symbol_search_type_from_coff(obj, symbol, interp);
|
||||
switch (interp) {
|
||||
case COFF_SymbolValueInterp_Regular: {
|
||||
if (symbol.storage_class == COFF_SymStorageClass_External) {
|
||||
@@ -464,27 +465,27 @@ THREAD_POOL_TASK_FUNC(lnk_input_coff_symbol_table)
|
||||
if (*section.flags & COFF_SectionFlag_LnkRemove) {
|
||||
break;
|
||||
}
|
||||
LNK_Symbol *defn = lnk_make_symbol(arena, lnk_symbol_name_from_coff_symbol_idx(obj, symbol_idx), obj, symbol_idx);
|
||||
LNK_Symbol *defn = lnk_make_symbol(arena, lnk_symbol_name_from_coff_symbol_idx(obj, symbol_idx), obj, symbol_idx, search_type);
|
||||
lnk_symbol_table_push_(task->symtab, arena, worker_id, defn);
|
||||
}
|
||||
} break;
|
||||
case COFF_SymbolValueInterp_Weak: {
|
||||
LNK_Symbol *defn = lnk_make_symbol(arena, lnk_symbol_name_from_coff_symbol_idx(obj, symbol_idx), obj, symbol_idx);
|
||||
LNK_Symbol *defn = lnk_make_symbol(arena, lnk_symbol_name_from_coff_symbol_idx(obj, symbol_idx), obj, symbol_idx, search_type);
|
||||
lnk_symbol_table_push_(task->symtab, arena, worker_id, defn);
|
||||
} break;
|
||||
case COFF_SymbolValueInterp_Undefined: {
|
||||
if (symbol.storage_class == COFF_SymStorageClass_External) {
|
||||
LNK_Symbol *defn = lnk_make_symbol(arena, lnk_symbol_name_from_coff_symbol_idx(obj, symbol_idx), obj, symbol_idx);
|
||||
LNK_Symbol *defn = lnk_make_symbol(arena, lnk_symbol_name_from_coff_symbol_idx(obj, symbol_idx), obj, symbol_idx, search_type);
|
||||
lnk_symbol_table_push_(task->symtab, arena, worker_id, defn);
|
||||
}
|
||||
} break;
|
||||
case COFF_SymbolValueInterp_Common: {
|
||||
LNK_Symbol *defn = lnk_make_symbol(arena, lnk_symbol_name_from_coff_symbol_idx(obj, symbol_idx), obj, symbol_idx);
|
||||
LNK_Symbol *defn = lnk_make_symbol(arena, lnk_symbol_name_from_coff_symbol_idx(obj, symbol_idx), obj, symbol_idx, search_type);
|
||||
lnk_symbol_table_push_(task->symtab, arena, worker_id, defn);
|
||||
} break;
|
||||
case COFF_SymbolValueInterp_Abs: {
|
||||
if (symbol.storage_class == COFF_SymStorageClass_External) {
|
||||
LNK_Symbol *defn = lnk_make_symbol(arena, lnk_symbol_name_from_coff_symbol_idx(obj, symbol_idx), obj, symbol_idx);
|
||||
LNK_Symbol *defn = lnk_make_symbol(arena, lnk_symbol_name_from_coff_symbol_idx(obj, symbol_idx), obj, symbol_idx, search_type);
|
||||
lnk_symbol_table_push_(task->symtab, arena, worker_id, defn);
|
||||
}
|
||||
} break;
|
||||
|
||||
@@ -1,20 +1,68 @@
|
||||
// Copyright (c) Epic Games Tools
|
||||
// Licensed under the MIT license (https://opensource.org/license/mit/)
|
||||
|
||||
#define LNK_SYMBOL_SEARCH_TYPE_MASK 7ull
|
||||
|
||||
internal LNK_SymbolSearchType
|
||||
lnk_symbol_search_type_from_coff(LNK_Obj *obj, COFF_ParsedSymbol symbol, COFF_SymbolValueInterpType interp)
|
||||
{
|
||||
LNK_SymbolSearchType search_type = LNK_SymbolSearch_Null;
|
||||
if (interp == COFF_SymbolValueInterp_Undefined) {
|
||||
search_type = LNK_SymbolSearch_Undefined;
|
||||
} else if (interp == COFF_SymbolValueInterp_Weak) {
|
||||
COFF_SymbolWeakExt *weak_ext = coff_parse_weak_tag(symbol, obj->header.is_big_obj);
|
||||
switch (weak_ext->characteristics) {
|
||||
case COFF_WeakExt_SearchLibrary: search_type = LNK_SymbolSearch_WeakLibrary; break;
|
||||
case COFF_WeakExt_AntiDependency: search_type = LNK_SymbolSearch_WeakAntiDependency; break;
|
||||
default: search_type = LNK_SymbolSearch_WeakOther; break;
|
||||
}
|
||||
}
|
||||
return search_type;
|
||||
}
|
||||
|
||||
internal LNK_Symbol *
|
||||
lnk_make_symbol(Arena *arena, String8 name, LNK_Obj *obj, U32 symbol_idx)
|
||||
lnk_make_symbol(Arena *arena, String8 name, LNK_Obj *obj, U32 symbol_idx, LNK_SymbolSearchType search_type)
|
||||
{
|
||||
LNK_ObjSymbolRefNode *ref = push_array(arena, LNK_ObjSymbolRefNode, 1);
|
||||
ref->v.obj = obj;
|
||||
ref->v.symbol_idx = symbol_idx;
|
||||
|
||||
LNK_Symbol *symbol = push_array(arena, LNK_Symbol, 1);
|
||||
symbol->name = name;
|
||||
SLLQueuePush(symbol->first_ref, symbol->last_ref, ref);
|
||||
LNK_Symbol *symbol = push_array(arena, LNK_Symbol, 1);
|
||||
symbol->name = name;
|
||||
symbol->first_ref = ref;
|
||||
Assert((IntFromPtr(ref) & LNK_SYMBOL_SEARCH_TYPE_MASK) == 0);
|
||||
Assert(search_type <= LNK_SymbolSearch_WeakOther);
|
||||
symbol->last_ref_and_search_type = IntFromPtr(ref) | search_type;
|
||||
|
||||
return symbol;
|
||||
}
|
||||
|
||||
internal LNK_ObjSymbolRefNode *
|
||||
lnk_last_ref_from_symbol(LNK_Symbol *symbol)
|
||||
{
|
||||
return PtrFromInt(symbol->last_ref_and_search_type & ~LNK_SYMBOL_SEARCH_TYPE_MASK);
|
||||
}
|
||||
|
||||
internal LNK_SymbolSearchType
|
||||
lnk_search_type_from_symbol(LNK_Symbol *symbol)
|
||||
{
|
||||
return safe_cast_u32(symbol->last_ref_and_search_type & LNK_SYMBOL_SEARCH_TYPE_MASK);
|
||||
}
|
||||
|
||||
internal void
|
||||
lnk_symbol_set_last_ref(LNK_Symbol *symbol, LNK_ObjSymbolRefNode *last_ref)
|
||||
{
|
||||
Assert((IntFromPtr(last_ref) & LNK_SYMBOL_SEARCH_TYPE_MASK) == 0);
|
||||
symbol->last_ref_and_search_type = IntFromPtr(last_ref) | lnk_search_type_from_symbol(symbol);
|
||||
}
|
||||
|
||||
internal void
|
||||
lnk_symbol_set_search_type(LNK_Symbol *symbol, LNK_SymbolSearchType search_type)
|
||||
{
|
||||
Assert(search_type <= LNK_SymbolSearch_WeakOther);
|
||||
symbol->last_ref_and_search_type = (symbol->last_ref_and_search_type & ~LNK_SYMBOL_SEARCH_TYPE_MASK) | search_type;
|
||||
}
|
||||
|
||||
internal int
|
||||
lnk_obj_symbol_ref_is_before(void *raw_a, void *raw_b)
|
||||
{
|
||||
@@ -357,8 +405,8 @@ lnk_on_symbol_replace(LNK_Symbol *dst, LNK_Symbol *src)
|
||||
}
|
||||
|
||||
// merge symbol refs
|
||||
src->last_ref->next = dst->first_ref;
|
||||
src->last_ref = dst->last_ref;
|
||||
lnk_last_ref_from_symbol(src)->next = dst->first_ref;
|
||||
lnk_symbol_set_last_ref(src, lnk_last_ref_from_symbol(dst));
|
||||
|
||||
// assert leader section is live
|
||||
#if BUILD_DEBUG
|
||||
@@ -561,10 +609,10 @@ lnk_symbol_table_init(TP_Arena *arena)
|
||||
internal void
|
||||
lnk_symbol_table_push_(LNK_SymbolTable *symtab, Arena *arena, U64 worker_id, LNK_Symbol *symbol)
|
||||
{
|
||||
U64 hash = lnk_symbol_table_hasher(symbol->name);
|
||||
COFF_SymbolValueInterpType interp = lnk_interp_from_symbol(symbol);
|
||||
U64 hash = lnk_symbol_table_hasher(symbol->name);
|
||||
LNK_SymbolSearchType search_type = lnk_search_type_from_symbol(symbol);
|
||||
LNK_SymbolHashTrieChunkList *chunks;
|
||||
if (interp == COFF_SymbolValueInterp_Weak || interp == COFF_SymbolValueInterp_Undefined) {
|
||||
if (search_type != LNK_SymbolSearch_Null) {
|
||||
chunks = &symtab->search_chunks[worker_id];
|
||||
} else {
|
||||
chunks = &symtab->chunks[worker_id];
|
||||
@@ -790,8 +838,10 @@ THREAD_POOL_TASK_FUNC(lnk_replace_weak_with_default_symbol_task)
|
||||
symbol16->value = 0;
|
||||
symbol16->storage_class = COFF_SymStorageClass_External;
|
||||
}
|
||||
lnk_symbol_set_search_type(symbol, LNK_SymbolSearch_Undefined);
|
||||
} else {
|
||||
symbol->first_ref->v = resolve;
|
||||
lnk_symbol_set_search_type(symbol, LNK_SymbolSearch_Null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,13 +17,25 @@ typedef struct LNK_ObjSymbolRefNode
|
||||
LNK_ObjSymbolRef v;
|
||||
} LNK_ObjSymbolRefNode;
|
||||
|
||||
typedef U32 LNK_SymbolSearchType;
|
||||
enum
|
||||
{
|
||||
LNK_SymbolSearch_Null,
|
||||
LNK_SymbolSearch_Undefined,
|
||||
LNK_SymbolSearch_WeakLibrary,
|
||||
LNK_SymbolSearch_WeakAntiDependency,
|
||||
LNK_SymbolSearch_WeakOther,
|
||||
};
|
||||
|
||||
typedef struct LNK_Symbol
|
||||
{
|
||||
String8 name;
|
||||
LNK_ObjSymbolRefNode *first_ref;
|
||||
LNK_ObjSymbolRefNode *last_ref;
|
||||
U64 last_ref_and_search_type; // Tail pointer with search type in its low bits.
|
||||
} LNK_Symbol;
|
||||
|
||||
StaticAssert(sizeof(LNK_Symbol) == 32, lnk_symbol_size_check);
|
||||
|
||||
// --- Symbol Containers -------------------------------------------------------
|
||||
|
||||
typedef struct LNK_SymbolNode
|
||||
@@ -89,7 +101,12 @@ typedef struct
|
||||
|
||||
// --- Symbol -----------------------------------------------------------------
|
||||
|
||||
internal LNK_Symbol * lnk_make_symbol(Arena *arena, String8 name, struct LNK_Obj *obj, U32 symbol_idx);
|
||||
internal LNK_SymbolSearchType lnk_symbol_search_type_from_coff(struct LNK_Obj *obj, COFF_ParsedSymbol symbol, COFF_SymbolValueInterpType interp);
|
||||
internal LNK_Symbol * lnk_make_symbol(Arena *arena, String8 name, struct LNK_Obj *obj, U32 symbol_idx, LNK_SymbolSearchType search_type);
|
||||
internal LNK_ObjSymbolRefNode * lnk_last_ref_from_symbol(LNK_Symbol *symbol);
|
||||
internal LNK_SymbolSearchType lnk_search_type_from_symbol(LNK_Symbol *symbol);
|
||||
internal void lnk_symbol_set_last_ref(LNK_Symbol *symbol, LNK_ObjSymbolRefNode *last_ref);
|
||||
internal void lnk_symbol_set_search_type(LNK_Symbol *symbol, LNK_SymbolSearchType search_type);
|
||||
|
||||
internal int lnk_obj_symbol_ref_is_before(void *raw_a, void *raw_b);
|
||||
internal int lnk_obj_symbol_ref_ptr_is_before(void *raw_a, void *raw_b);
|
||||
@@ -138,4 +155,3 @@ internal B32 lnk_resolve_weak_symbol(LNK_SymbolTable *symtab, LNK_ObjSymbolRef s
|
||||
internal B32 lnk_resolve_symbol(LNK_SymbolTable *symtab, LNK_ObjSymbolRef symbol, LNK_ObjSymbolRef *symbol_out);
|
||||
|
||||
internal void lnk_replace_weak_with_default_symbols(TP_Context *tp, LNK_SymbolTable *symtab);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user