mirror of
https://github.com/Ed94/raddebugger.git
synced 2026-08-06 13:58:40 +00:00
move weak symbol replacer to the symbol table layer
This commit is contained in:
committed by
Ryan Fleury
parent
8d75497bba
commit
43e81b934b
+59
-105
@@ -1676,40 +1676,6 @@ lnk_link_inputs(TP_Context *tp, TP_Arena *arena, LNK_Config *config, LNK_Inputer
|
|||||||
lnk_link_inputs_(tp, arena, config, inputer, symtab, link, imps, 1);
|
lnk_link_inputs_(tp, arena, config, inputer, symtab, link, imps, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal
|
|
||||||
THREAD_POOL_TASK_FUNC(lnk_replace_weak_with_default_symbol_task)
|
|
||||||
{
|
|
||||||
LNK_ReplaceWeakSymbolsWithDefaultSymbolTask *task = raw_task;
|
|
||||||
LNK_SymbolTable *symtab = task->symtab;
|
|
||||||
LNK_SymbolHashTrieChunk *chunk = task->chunks[task_id];
|
|
||||||
for EachIndex(i, chunk->count) {
|
|
||||||
LNK_Symbol *symbol = chunk->v[i].symbol;
|
|
||||||
COFF_ParsedSymbol symbol_parsed = lnk_parsed_symbol_from_defined(symbol);
|
|
||||||
COFF_SymbolValueInterpType symbol_interp = coff_interp_from_parsed_symbol(symbol_parsed);
|
|
||||||
if (symbol_interp == COFF_SymbolValueInterp_Weak) {
|
|
||||||
LNK_SymbolDefined resolve = lnk_resolve_weak_symbol(symtab, symbol->defined);
|
|
||||||
COFF_ParsedSymbol resolve_parsed = lnk_parsed_symbol_from_coff_symbol_idx(resolve.obj, resolve.symbol_idx);
|
|
||||||
COFF_SymbolValueInterpType resolve_interp = coff_interp_from_parsed_symbol(resolve_parsed);
|
|
||||||
if (resolve_interp == COFF_SymbolValueInterp_Weak) {
|
|
||||||
COFF_SymbolWeakExt *weak_ext = coff_parse_weak_tag(resolve_parsed, symbol->defined.obj->header.is_big_obj);
|
|
||||||
if (symbol->defined.obj->header.is_big_obj) {
|
|
||||||
COFF_Symbol32 *symbol32 = symbol_parsed.raw_symbol;
|
|
||||||
symbol32->section_number = COFF_Symbol_UndefinedSection;
|
|
||||||
symbol32->value = 0;
|
|
||||||
symbol32->storage_class = COFF_SymStorageClass_External;
|
|
||||||
} else {
|
|
||||||
COFF_Symbol16 *symbol16 = symbol_parsed.raw_symbol;
|
|
||||||
symbol16->section_number = COFF_Symbol_UndefinedSection;
|
|
||||||
symbol16->value = 0;
|
|
||||||
symbol16->storage_class = COFF_SymStorageClass_External;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
symbol->defined = resolve;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
internal LNK_Link *
|
internal LNK_Link *
|
||||||
lnk_link_image(TP_Context *tp, TP_Arena *arena, LNK_Config *config, LNK_Inputer *inputer, LNK_SymbolTable *symtab)
|
lnk_link_image(TP_Context *tp, TP_Arena *arena, LNK_Config *config, LNK_Inputer *inputer, LNK_SymbolTable *symtab)
|
||||||
{
|
{
|
||||||
@@ -1945,6 +1911,65 @@ lnk_link_image(TP_Context *tp, TP_Arena *arena, LNK_Config *config, LNK_Inputer
|
|||||||
//
|
//
|
||||||
lnk_link_inputs(tp, arena, config, inputer, symtab, link, imps);
|
lnk_link_inputs(tp, arena, config, inputer, symtab, link, imps);
|
||||||
|
|
||||||
|
//
|
||||||
|
// finalize symbol table
|
||||||
|
//
|
||||||
|
lnk_replace_weak_with_default_symbols(tp, symtab);
|
||||||
|
|
||||||
|
//
|
||||||
|
// was entry point resolved?
|
||||||
|
//
|
||||||
|
if (config->entry_point_name.size == 0 || link->try_to_resolve_entry_point) {
|
||||||
|
lnk_error(LNK_Error_EntryPoint, "unable to find entry point symbol");
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// report undefined symbols
|
||||||
|
//
|
||||||
|
{
|
||||||
|
ProfBegin("Report Unresolved Symbols");
|
||||||
|
U64 chunks_count = 0;
|
||||||
|
LNK_SymbolHashTrieChunk **chunks = lnk_array_from_symbol_hash_trie_chunk_list(scratch.arena, symtab->chunks, symtab->arena->count, &chunks_count);
|
||||||
|
|
||||||
|
U64 count = 0;
|
||||||
|
for EachIndex(chunk_idx, chunks_count) {
|
||||||
|
LNK_SymbolHashTrieChunk *chunk = chunks[chunk_idx];
|
||||||
|
for EachIndex(i, chunk->count) {
|
||||||
|
LNK_Symbol *symbol = chunk->v[i].symbol;
|
||||||
|
COFF_SymbolValueInterpType symbol_interp = lnk_interp_from_symbol(symbol);
|
||||||
|
if (symbol_interp == COFF_SymbolValueInterp_Undefined) {
|
||||||
|
count += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
U64 cursor = 0;
|
||||||
|
LNK_Symbol **unresolved = push_array(scratch.arena, LNK_Symbol *, count);
|
||||||
|
for EachIndex(chunk_idx, chunks_count) {
|
||||||
|
LNK_SymbolHashTrieChunk *chunk = chunks[chunk_idx];
|
||||||
|
for EachIndex(i, chunk->count) {
|
||||||
|
LNK_Symbol *symbol = chunk->v[i].symbol;
|
||||||
|
COFF_SymbolValueInterpType symbol_interp = lnk_interp_from_symbol(symbol);
|
||||||
|
if (symbol_interp == COFF_SymbolValueInterp_Undefined) {
|
||||||
|
unresolved[cursor++] = chunk->v[i].symbol;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
radsort(unresolved, count, lnk_symbol_defined_ptr_is_before);
|
||||||
|
|
||||||
|
for EachIndex(i, count) {
|
||||||
|
LNK_Symbol *symbol = unresolved[i];
|
||||||
|
lnk_error_obj(LNK_Error_UnresolvedSymbol, symbol->defined.obj, "unresolved symbol %S", symbol->name);
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: /FORCE
|
||||||
|
if (count) {
|
||||||
|
lnk_exit(LNK_Error_UnresolvedSymbol);
|
||||||
|
}
|
||||||
|
ProfEnd();
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// warn about unused delayloads
|
// warn about unused delayloads
|
||||||
//
|
//
|
||||||
@@ -1956,77 +1981,6 @@ lnk_link_image(TP_Context *tp, TP_Arena *arena, LNK_Config *config, LNK_Inputer
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
|
||||||
// report undefined symbols
|
|
||||||
//
|
|
||||||
{
|
|
||||||
U64 chunks_count = 0;
|
|
||||||
LNK_SymbolHashTrieChunk **chunks = lnk_array_from_symbol_hash_trie_chunk_list(scratch.arena, symtab->chunks, symtab->arena->count, &chunks_count);
|
|
||||||
|
|
||||||
ProfBegin("Replace Unresolved Weak Symbols With Defualt Symbol");
|
|
||||||
{
|
|
||||||
LNK_ReplaceWeakSymbolsWithDefaultSymbolTask task = { .symtab = symtab, .chunks = chunks };
|
|
||||||
tp_for_parallel(tp, 0, chunks_count, lnk_replace_weak_with_default_symbol_task, &task);
|
|
||||||
#if BUILD_DEBUG
|
|
||||||
for EachIndex(chunk_idx, chunks_count) {
|
|
||||||
LNK_SymbolHashTrieChunk *chunk = chunks[chunk_idx];
|
|
||||||
for EachIndex(i, chunk->count) {
|
|
||||||
LNK_Symbol *symbol = chunk->v[i].symbol;
|
|
||||||
COFF_SymbolValueInterpType symbol_interp = lnk_interp_from_symbol(symbol);
|
|
||||||
AssertAlways(symbol_interp != COFF_SymbolValueInterp_Weak);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
ProfEnd();
|
|
||||||
|
|
||||||
|
|
||||||
if (config->entry_point_name.size == 0) {
|
|
||||||
lnk_error(LNK_Error_EntryPoint, "unable to find entry point symbol");
|
|
||||||
}
|
|
||||||
|
|
||||||
ProfBegin("Report Unresolved Symbols");
|
|
||||||
{
|
|
||||||
U64 count = 0;
|
|
||||||
for EachIndex(chunk_idx, chunks_count) {
|
|
||||||
LNK_SymbolHashTrieChunk *chunk = chunks[chunk_idx];
|
|
||||||
for EachIndex(i, chunk->count) {
|
|
||||||
LNK_Symbol *symbol = chunk->v[i].symbol;
|
|
||||||
COFF_SymbolValueInterpType symbol_interp = lnk_interp_from_symbol(symbol);
|
|
||||||
if (symbol_interp == COFF_SymbolValueInterp_Undefined) {
|
|
||||||
count += 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
U64 cursor = 0;
|
|
||||||
LNK_Symbol **unresolved = push_array(scratch.arena, LNK_Symbol *, count);
|
|
||||||
for EachIndex(chunk_idx, chunks_count) {
|
|
||||||
LNK_SymbolHashTrieChunk *chunk = chunks[chunk_idx];
|
|
||||||
for EachIndex(i, chunk->count) {
|
|
||||||
LNK_Symbol *symbol = chunk->v[i].symbol;
|
|
||||||
COFF_SymbolValueInterpType symbol_interp = lnk_interp_from_symbol(symbol);
|
|
||||||
if (symbol_interp == COFF_SymbolValueInterp_Undefined) {
|
|
||||||
unresolved[cursor++] = chunk->v[i].symbol;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
radsort(unresolved, count, lnk_symbol_defined_ptr_is_before);
|
|
||||||
|
|
||||||
for EachIndex(i, count) {
|
|
||||||
LNK_Symbol *symbol = unresolved[i];
|
|
||||||
lnk_error_obj(LNK_Error_UnresolvedSymbol, symbol->defined.obj, "unresolved symbol %S", symbol->name);
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: /FORCE
|
|
||||||
if (count) {
|
|
||||||
lnk_exit(LNK_Error_UnresolvedSymbol);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ProfEnd();
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// discard COMDAT sections that are not referenced
|
// discard COMDAT sections that are not referenced
|
||||||
//
|
//
|
||||||
|
|||||||
@@ -154,12 +154,6 @@ typedef struct LNK_BaseRelocPageArray
|
|||||||
|
|
||||||
// --- Workers Contexts --------------------------------------------------------
|
// --- Workers Contexts --------------------------------------------------------
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
LNK_SymbolTable *symtab;
|
|
||||||
LNK_SymbolHashTrieChunk **chunks;
|
|
||||||
} LNK_ReplaceWeakSymbolsWithDefaultSymbolTask;
|
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
LNK_SymbolTable *symtab;
|
LNK_SymbolTable *symtab;
|
||||||
|
|||||||
@@ -16,9 +16,10 @@ lnk_symbol_defined_is_before(void *raw_a, void *raw_b)
|
|||||||
{
|
{
|
||||||
LNK_Symbol *a = raw_a, *b = raw_b;
|
LNK_Symbol *a = raw_a, *b = raw_b;
|
||||||
|
|
||||||
|
LNK_Lib *a_lib = lnk_obj_get_lib(a->defined.obj);
|
||||||
U32 a_lib_input_idx = a->defined.obj->lib ? a->defined.obj->lib->input_idx : 0;
|
LNK_Lib *b_lib = lnk_obj_get_lib(b->defined.obj);
|
||||||
U32 b_lib_input_idx = b->defined.obj->lib ? b->defined.obj->lib->input_idx : 0;
|
U32 a_lib_input_idx = a_lib ? a_lib->input_idx : 0;
|
||||||
|
U32 b_lib_input_idx = b_lib ? b_lib->input_idx : 0;
|
||||||
|
|
||||||
if (a_lib_input_idx == b_lib_input_idx) {
|
if (a_lib_input_idx == b_lib_input_idx) {
|
||||||
if (a->defined.obj->input_idx == b->defined.obj->input_idx) {
|
if (a->defined.obj->input_idx == b->defined.obj->input_idx) {
|
||||||
@@ -657,6 +658,66 @@ lnk_symbol_table_searchf(LNK_SymbolTable *symtab, char *fmt, ...)
|
|||||||
return symbol;
|
return symbol;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal
|
||||||
|
THREAD_POOL_TASK_FUNC(lnk_replace_weak_with_default_symbol_task)
|
||||||
|
{
|
||||||
|
LNK_ReplaceWeakSymbolsWithDefaultSymbolTask *task = raw_task;
|
||||||
|
LNK_SymbolTable *symtab = task->symtab;
|
||||||
|
LNK_SymbolHashTrieChunk *chunk = task->chunks[task_id];
|
||||||
|
for EachIndex(i, chunk->count) {
|
||||||
|
LNK_Symbol *symbol = chunk->v[i].symbol;
|
||||||
|
COFF_ParsedSymbol symbol_parsed = lnk_parsed_symbol_from_defined(symbol);
|
||||||
|
COFF_SymbolValueInterpType symbol_interp = coff_interp_from_parsed_symbol(symbol_parsed);
|
||||||
|
if (symbol_interp == COFF_SymbolValueInterp_Weak) {
|
||||||
|
LNK_SymbolDefined resolve = lnk_resolve_weak_symbol(symtab, symbol->defined);
|
||||||
|
COFF_ParsedSymbol resolve_parsed = lnk_parsed_symbol_from_coff_symbol_idx(resolve.obj, resolve.symbol_idx);
|
||||||
|
COFF_SymbolValueInterpType resolve_interp = coff_interp_from_parsed_symbol(resolve_parsed);
|
||||||
|
if (resolve_interp == COFF_SymbolValueInterp_Weak) {
|
||||||
|
COFF_SymbolWeakExt *weak_ext = coff_parse_weak_tag(resolve_parsed, symbol->defined.obj->header.is_big_obj);
|
||||||
|
if (symbol->defined.obj->header.is_big_obj) {
|
||||||
|
COFF_Symbol32 *symbol32 = symbol_parsed.raw_symbol;
|
||||||
|
symbol32->section_number = COFF_Symbol_UndefinedSection;
|
||||||
|
symbol32->value = 0;
|
||||||
|
symbol32->storage_class = COFF_SymStorageClass_External;
|
||||||
|
} else {
|
||||||
|
COFF_Symbol16 *symbol16 = symbol_parsed.raw_symbol;
|
||||||
|
symbol16->section_number = COFF_Symbol_UndefinedSection;
|
||||||
|
symbol16->value = 0;
|
||||||
|
symbol16->storage_class = COFF_SymStorageClass_External;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
symbol->defined = resolve;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void
|
||||||
|
lnk_replace_weak_with_default_symbols(TP_Context *tp, LNK_SymbolTable *symtab)
|
||||||
|
{
|
||||||
|
Temp scratch = scratch_begin(0,0);
|
||||||
|
U64 chunks_count = 0;
|
||||||
|
LNK_SymbolHashTrieChunk **chunks = lnk_array_from_symbol_hash_trie_chunk_list(scratch.arena, symtab->chunks, symtab->arena->count, &chunks_count);
|
||||||
|
|
||||||
|
ProfBegin("Replace Unresolved Weak Symbols With Defualt Symbol");
|
||||||
|
LNK_ReplaceWeakSymbolsWithDefaultSymbolTask task = { .symtab = symtab, .chunks = chunks };
|
||||||
|
tp_for_parallel(tp, 0, chunks_count, lnk_replace_weak_with_default_symbol_task, &task);
|
||||||
|
|
||||||
|
#if BUILD_DEBUG
|
||||||
|
for EachIndex(chunk_idx, chunks_count) {
|
||||||
|
LNK_SymbolHashTrieChunk *chunk = chunks[chunk_idx];
|
||||||
|
for EachIndex(i, chunk->count) {
|
||||||
|
LNK_Symbol *symbol = chunk->v[i].symbol;
|
||||||
|
COFF_SymbolValueInterpType symbol_interp = lnk_interp_from_symbol(symbol);
|
||||||
|
AssertAlways(symbol_interp != COFF_SymbolValueInterp_Weak);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
scratch_end(scratch);
|
||||||
|
ProfEnd();
|
||||||
|
}
|
||||||
|
|
||||||
internal ISectOff
|
internal ISectOff
|
||||||
lnk_sc_from_symbol(LNK_Symbol *symbol)
|
lnk_sc_from_symbol(LNK_Symbol *symbol)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -78,6 +78,14 @@ typedef struct LNK_SymbolTable
|
|||||||
LNK_SymbolHashTrieChunkList *chunks;
|
LNK_SymbolHashTrieChunkList *chunks;
|
||||||
} LNK_SymbolTable;
|
} LNK_SymbolTable;
|
||||||
|
|
||||||
|
// --- Workers Contexts --------------------------------------------------------
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
LNK_SymbolTable *symtab;
|
||||||
|
LNK_SymbolHashTrieChunk **chunks;
|
||||||
|
} LNK_ReplaceWeakSymbolsWithDefaultSymbolTask;
|
||||||
|
|
||||||
// --- Symbol Make -------------------------------------------------------------
|
// --- Symbol Make -------------------------------------------------------------
|
||||||
|
|
||||||
internal LNK_Symbol * lnk_make_defined_symbol(Arena *arena, String8 name, struct LNK_Obj *obj, U32 symbol_idx);
|
internal LNK_Symbol * lnk_make_defined_symbol(Arena *arena, String8 name, struct LNK_Obj *obj, U32 symbol_idx);
|
||||||
|
|||||||
Reference in New Issue
Block a user