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
+5
-16
@@ -1702,24 +1702,15 @@ THREAD_POOL_TASK_FUNC(lnk_search_lib_task)
|
|||||||
U64 i_end = (c == end_chunk) ? end_count : c->count;
|
U64 i_end = (c == end_chunk) ? end_count : c->count;
|
||||||
for (U64 i = i_begin; i < i_end; i += 1) {
|
for (U64 i = i_begin; i < i_end; i += 1) {
|
||||||
LNK_Symbol *symbol = c->v[i].symbol;
|
LNK_Symbol *symbol = c->v[i].symbol;
|
||||||
LNK_ObjSymbolRef symbol_ref = lnk_ref_from_symbol(symbol);
|
LNK_SymbolSearchType search_type = lnk_search_type_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);
|
|
||||||
|
|
||||||
if (symbol_interp == COFF_SymbolValueInterp_Undefined) {
|
if (search_type == LNK_SymbolSearch_Undefined || search_type == LNK_SymbolSearch_WeakLibrary) {
|
||||||
U32 member_idx;
|
U32 member_idx;
|
||||||
if (lnk_search_lib(lib, symbol->name, &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);
|
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) {
|
} else if (search_type == LNK_SymbolSearch_WeakAntiDependency && search_anti_deps) {
|
||||||
COFF_SymbolWeakExt *weak_ext = coff_parse_weak_tag(symbol_parsed, symbol_ref.obj->header.is_big_obj);
|
LNK_ObjSymbolRef symbol_ref = lnk_ref_from_symbol(symbol);
|
||||||
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};
|
LNK_ObjSymbolRef dep_symbol = {0};
|
||||||
if (lnk_resolve_weak_symbol(symtab, symbol_ref, &dep_symbol)) {
|
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_ParsedSymbol dep_parsed = lnk_parsed_symbol_from_coff_symbol_idx_no_name(dep_symbol.obj, dep_symbol.symbol_idx);
|
||||||
@@ -1734,8 +1725,6 @@ THREAD_POOL_TASK_FUNC(lnk_search_lib_task)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// cache search cursors
|
// cache search cursors
|
||||||
lib->search_cursor_chunks[task_id] = end_chunk;
|
lib->search_cursor_chunks[task_id] = end_chunk;
|
||||||
@@ -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.
|
// 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->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
|
// push import member for import obj generation
|
||||||
lnk_lib_member_ref_list_push_node(&link->imports, member_ref);
|
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)) {
|
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);
|
symbol = lnk_parsed_symbol_from_coff_symbol_idx_no_name(obj, symbol_idx);
|
||||||
COFF_SymbolValueInterpType interp = coff_interp_from_parsed_symbol(symbol);
|
COFF_SymbolValueInterpType interp = coff_interp_from_parsed_symbol(symbol);
|
||||||
|
LNK_SymbolSearchType search_type = lnk_symbol_search_type_from_coff(obj, symbol, interp);
|
||||||
switch (interp) {
|
switch (interp) {
|
||||||
case COFF_SymbolValueInterp_Regular: {
|
case COFF_SymbolValueInterp_Regular: {
|
||||||
if (symbol.storage_class == COFF_SymStorageClass_External) {
|
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) {
|
if (*section.flags & COFF_SectionFlag_LnkRemove) {
|
||||||
break;
|
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);
|
lnk_symbol_table_push_(task->symtab, arena, worker_id, defn);
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
case COFF_SymbolValueInterp_Weak: {
|
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);
|
lnk_symbol_table_push_(task->symtab, arena, worker_id, defn);
|
||||||
} break;
|
} break;
|
||||||
case COFF_SymbolValueInterp_Undefined: {
|
case COFF_SymbolValueInterp_Undefined: {
|
||||||
if (symbol.storage_class == COFF_SymStorageClass_External) {
|
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);
|
lnk_symbol_table_push_(task->symtab, arena, worker_id, defn);
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
case COFF_SymbolValueInterp_Common: {
|
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);
|
lnk_symbol_table_push_(task->symtab, arena, worker_id, defn);
|
||||||
} break;
|
} break;
|
||||||
case COFF_SymbolValueInterp_Abs: {
|
case COFF_SymbolValueInterp_Abs: {
|
||||||
if (symbol.storage_class == COFF_SymStorageClass_External) {
|
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);
|
lnk_symbol_table_push_(task->symtab, arena, worker_id, defn);
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
|
|||||||
@@ -1,8 +1,27 @@
|
|||||||
// Copyright (c) Epic Games Tools
|
// Copyright (c) Epic Games Tools
|
||||||
// Licensed under the MIT license (https://opensource.org/license/mit/)
|
// 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 *
|
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);
|
LNK_ObjSymbolRefNode *ref = push_array(arena, LNK_ObjSymbolRefNode, 1);
|
||||||
ref->v.obj = obj;
|
ref->v.obj = obj;
|
||||||
@@ -10,11 +29,40 @@ lnk_make_symbol(Arena *arena, String8 name, LNK_Obj *obj, U32 symbol_idx)
|
|||||||
|
|
||||||
LNK_Symbol *symbol = push_array(arena, LNK_Symbol, 1);
|
LNK_Symbol *symbol = push_array(arena, LNK_Symbol, 1);
|
||||||
symbol->name = name;
|
symbol->name = name;
|
||||||
SLLQueuePush(symbol->first_ref, symbol->last_ref, ref);
|
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;
|
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
|
internal int
|
||||||
lnk_obj_symbol_ref_is_before(void *raw_a, void *raw_b)
|
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
|
// merge symbol refs
|
||||||
src->last_ref->next = dst->first_ref;
|
lnk_last_ref_from_symbol(src)->next = dst->first_ref;
|
||||||
src->last_ref = dst->last_ref;
|
lnk_symbol_set_last_ref(src, lnk_last_ref_from_symbol(dst));
|
||||||
|
|
||||||
// assert leader section is live
|
// assert leader section is live
|
||||||
#if BUILD_DEBUG
|
#if BUILD_DEBUG
|
||||||
@@ -562,9 +610,9 @@ internal void
|
|||||||
lnk_symbol_table_push_(LNK_SymbolTable *symtab, Arena *arena, U64 worker_id, LNK_Symbol *symbol)
|
lnk_symbol_table_push_(LNK_SymbolTable *symtab, Arena *arena, U64 worker_id, LNK_Symbol *symbol)
|
||||||
{
|
{
|
||||||
U64 hash = lnk_symbol_table_hasher(symbol->name);
|
U64 hash = lnk_symbol_table_hasher(symbol->name);
|
||||||
COFF_SymbolValueInterpType interp = lnk_interp_from_symbol(symbol);
|
LNK_SymbolSearchType search_type = lnk_search_type_from_symbol(symbol);
|
||||||
LNK_SymbolHashTrieChunkList *chunks;
|
LNK_SymbolHashTrieChunkList *chunks;
|
||||||
if (interp == COFF_SymbolValueInterp_Weak || interp == COFF_SymbolValueInterp_Undefined) {
|
if (search_type != LNK_SymbolSearch_Null) {
|
||||||
chunks = &symtab->search_chunks[worker_id];
|
chunks = &symtab->search_chunks[worker_id];
|
||||||
} else {
|
} else {
|
||||||
chunks = &symtab->chunks[worker_id];
|
chunks = &symtab->chunks[worker_id];
|
||||||
@@ -790,8 +838,10 @@ THREAD_POOL_TASK_FUNC(lnk_replace_weak_with_default_symbol_task)
|
|||||||
symbol16->value = 0;
|
symbol16->value = 0;
|
||||||
symbol16->storage_class = COFF_SymStorageClass_External;
|
symbol16->storage_class = COFF_SymStorageClass_External;
|
||||||
}
|
}
|
||||||
|
lnk_symbol_set_search_type(symbol, LNK_SymbolSearch_Undefined);
|
||||||
} else {
|
} else {
|
||||||
symbol->first_ref->v = resolve;
|
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_ObjSymbolRef v;
|
||||||
} LNK_ObjSymbolRefNode;
|
} 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
|
typedef struct LNK_Symbol
|
||||||
{
|
{
|
||||||
String8 name;
|
String8 name;
|
||||||
LNK_ObjSymbolRefNode *first_ref;
|
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;
|
} LNK_Symbol;
|
||||||
|
|
||||||
|
StaticAssert(sizeof(LNK_Symbol) == 32, lnk_symbol_size_check);
|
||||||
|
|
||||||
// --- Symbol Containers -------------------------------------------------------
|
// --- Symbol Containers -------------------------------------------------------
|
||||||
|
|
||||||
typedef struct LNK_SymbolNode
|
typedef struct LNK_SymbolNode
|
||||||
@@ -89,7 +101,12 @@ typedef struct
|
|||||||
|
|
||||||
// --- Symbol -----------------------------------------------------------------
|
// --- 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_is_before(void *raw_a, void *raw_b);
|
||||||
internal int lnk_obj_symbol_ref_ptr_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 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);
|
internal void lnk_replace_weak_with_default_symbols(TP_Context *tp, LNK_SymbolTable *symtab);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user