mirror of
https://github.com/Ed94/raddebugger.git
synced 2026-06-17 09:32:22 -07:00
switch to thread safe hash trie map
Initial implementation of the symbol table allowed us to push symbols from one thread at a time and required a wonky lock-step and spread out logic for replacing symbols. And because it was a externally chained hash table we had to guesstimate optimal capacity for small and big targets. We erred on the side of larger capacity to prevent degradation and rehashing, however this meant small targets had to spent unreasonable amount of time memory allocing slots. With hash trie we can dynamically scale up to 4 ^ 32 items and atomically replace symbols when needed. Neat!
This commit is contained in:
+258
-287
File diff suppressed because it is too large
Load Diff
+9
-8
@@ -172,13 +172,6 @@ typedef struct
|
||||
HashTable **page_ht_arr;
|
||||
} LNK_ObjBaseRelocTask;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
Rng1U64 *range_arr;
|
||||
LNK_LibNode *lib_arr;
|
||||
LNK_Symbol **symbol_arr_arr;
|
||||
} LNK_LazyIniter;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
LNK_InputObjList input_obj_list;
|
||||
@@ -195,6 +188,15 @@ typedef struct
|
||||
Rng1U64 *range_arr;
|
||||
} LNK_SymbolFinder;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
LNK_SymbolTable *symtab;
|
||||
union {
|
||||
LNK_ObjNodeArray objs;
|
||||
LNK_LibNodeArray libs;
|
||||
} u;
|
||||
} LNK_SymbolPusher;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
LNK_SymbolTable *symtab;
|
||||
@@ -214,7 +216,6 @@ typedef struct
|
||||
LNK_Obj **obj_arr;
|
||||
} LNK_ObjRelocPatcher;
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
String8 path;
|
||||
|
||||
@@ -43,6 +43,8 @@ typedef struct LNK_Chunk
|
||||
#if LNK_DEBUG_CHUNKS
|
||||
String8 debug;
|
||||
#endif
|
||||
|
||||
int debug;
|
||||
} LNK_Chunk, * LNK_ChunkPtr;
|
||||
|
||||
typedef struct LNK_ChunkNode
|
||||
|
||||
+31
-26
@@ -2827,20 +2827,23 @@ THREAD_POOL_TASK_FUNC(lnk_push_dbi_sec_contrib_task)
|
||||
////////////////////////////////
|
||||
|
||||
internal
|
||||
THREAD_POOL_TASK_FUNC(lnk_build_pdb_public_symbols_task)
|
||||
THREAD_POOL_TASK_FUNC(lnk_build_pdb_public_symbols_defined_task)
|
||||
{
|
||||
U64 bucket_idx = task_id;
|
||||
LNK_BuildPublicSymbolsTaskData *task = raw_task;
|
||||
ProfBeginFunction();
|
||||
|
||||
LNK_Section **sect_id_map = task->sect_id_map;
|
||||
LNK_SymbolScopeIndex scope_idx = task->scope_idx;
|
||||
LNK_SymbolList bucket = task->bucket_arr[scope_idx][bucket_idx];
|
||||
CV_SymbolList *pub_list = &task->pub_list_arr[bucket_idx];
|
||||
LNK_BuildPublicSymbolsTask *task = raw_task;
|
||||
LNK_Section **sect_id_map = task->sect_id_map;
|
||||
CV_SymbolList *pub_list = &task->pub_list_arr[task_id];
|
||||
LNK_SymbolHashTrieChunkList chunk_list = task->chunk_lists[task_id];
|
||||
|
||||
for (LNK_SymbolNode *symbol_node = bucket.first; symbol_node != 0; symbol_node = symbol_node->next) {
|
||||
LNK_Symbol *symbol = symbol_node->data;
|
||||
for (LNK_SymbolHashTrieChunk *chunk = chunk_list.first; chunk != 0; chunk = chunk->next) {
|
||||
CV_SymbolNode *nodes = push_array_no_zero(arena, CV_SymbolNode, chunk->count);
|
||||
|
||||
for (U64 i = 0, node_idx = 0; i < chunk->count; ++i) {
|
||||
LNK_Symbol *symbol = chunk->v[i].symbol;
|
||||
|
||||
Assert(LNK_Symbol_IsDefined(symbol->type));
|
||||
|
||||
if (LNK_Symbol_IsDefined(symbol->type)) {
|
||||
LNK_DefinedSymbol *defined_symbol = &symbol->u.defined;
|
||||
if (defined_symbol->value_type == LNK_DefinedSymbolValue_Chunk) {
|
||||
CV_Pub32Flags flags = 0;
|
||||
@@ -2854,11 +2857,15 @@ THREAD_POOL_TASK_FUNC(lnk_build_pdb_public_symbols_task)
|
||||
U32 symbol_off32 = safe_cast_u32(symbol_off);
|
||||
U16 symbol_isect16 = safe_cast_u16(symbol_isect);
|
||||
|
||||
CV_SymbolNode *pub_node = cv_symbol_list_push(arena, pub_list);
|
||||
pub_node->data = cv_make_pub32(arena, flags, symbol_off32, symbol_isect16, symbol->name);
|
||||
nodes[node_idx].data = cv_make_pub32(arena, flags, symbol_off32, symbol_isect16, symbol->name);
|
||||
cv_symbol_list_push_node(pub_list, &nodes[node_idx]);
|
||||
|
||||
++node_idx;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ProfEnd();
|
||||
}
|
||||
|
||||
internal
|
||||
@@ -2866,8 +2873,8 @@ THREAD_POOL_TASK_FUNC(lnk_gsi_hash_cv_list_task)
|
||||
{
|
||||
ProfBeginFunction();
|
||||
|
||||
LNK_BuildPublicSymbolsTaskData *task = raw_task;
|
||||
Rng1U64 range = task->symbol_ranges[task_id];
|
||||
LNK_BuildPublicSymbolsTask *task = raw_task;
|
||||
Rng1U64 range = task->symbol_ranges[task_id];
|
||||
|
||||
for (U64 symbol_idx = range.min; symbol_idx < range.max; ++symbol_idx) {
|
||||
CV_Symbol *symbol = &task->symbols.v[symbol_idx]->data;
|
||||
@@ -2883,22 +2890,20 @@ lnk_build_pdb_public_symbols(TP_Context *tp,
|
||||
TP_Arena *arena,
|
||||
LNK_SymbolTable *symtab,
|
||||
LNK_Section **sect_id_map,
|
||||
PDB_PsiContext *psi,
|
||||
LNK_SymbolScopeIndex scope_idx)
|
||||
PDB_PsiContext *psi)
|
||||
{
|
||||
ProfBeginFunction();
|
||||
Temp scratch = scratch_begin(arena->v, arena->count);
|
||||
|
||||
ProfBegin("Make Public Symbols");
|
||||
LNK_BuildPublicSymbolsTaskData task = {0};
|
||||
task.sect_id_map = sect_id_map;
|
||||
task.scope_idx = scope_idx;
|
||||
task.bucket_arr = symtab->buckets;
|
||||
task.pub_list_arr = push_array(scratch.arena, CV_SymbolList, symtab->bucket_count[scope_idx]);
|
||||
tp_for_parallel(tp, arena, symtab->bucket_count[scope_idx], lnk_build_pdb_public_symbols_task, &task);
|
||||
ProfBegin("Defined");
|
||||
LNK_BuildPublicSymbolsTask task = {0};
|
||||
task.sect_id_map = sect_id_map;
|
||||
task.pub_list_arr = push_array(scratch.arena, CV_SymbolList, tp->worker_count);
|
||||
task.chunk_lists = symtab->chunk_lists[LNK_SymbolScopeIndex_Defined];
|
||||
tp_for_parallel(tp, arena, tp->worker_count, lnk_build_pdb_public_symbols_defined_task, &task);
|
||||
ProfEnd();
|
||||
|
||||
CV_SymbolPtrArray symbols = cv_symbol_ptr_array_from_list(scratch.arena, tp, symtab->bucket_count[scope_idx], task.pub_list_arr);
|
||||
CV_SymbolPtrArray symbols = cv_symbol_ptr_array_from_list(scratch.arena, tp, tp->worker_count, task.pub_list_arr);
|
||||
|
||||
ProfBegin("GSI Push");
|
||||
gsi_push_many_arr(tp, psi->gsi, symbols.count, symbols.v);
|
||||
@@ -3070,7 +3075,7 @@ lnk_build_pdb(TP_Context *tp,
|
||||
ProfBegin("Build DBI Section Headers");
|
||||
{
|
||||
LNK_Symbol *coff_sect_array_symbol = lnk_symbol_table_searchf(symtab, LNK_SymbolScopeFlag_Internal, LNK_COFF_SECT_HEADER_ARRAY_SYMBOL_NAME);
|
||||
LNK_Chunk *coff_sect_chunk = lnk_defined_symbol_get_chunk(&coff_sect_array_symbol->u.defined);
|
||||
LNK_Chunk *coff_sect_chunk = lnk_chunk_from_symbol(coff_sect_array_symbol);
|
||||
String8 coff_sect_chunk_data = lnk_data_from_chunk_ref(sect_id_map, coff_sect_chunk->ref);
|
||||
U64 coff_sect_count = coff_sect_chunk_data.size / sizeof(COFF_SectionHeader);
|
||||
COFF_SectionHeader *coff_sect_ptr = (COFF_SectionHeader*)coff_sect_chunk_data.str;
|
||||
@@ -3125,7 +3130,7 @@ lnk_build_pdb(TP_Context *tp,
|
||||
}
|
||||
ProfEnd();
|
||||
|
||||
lnk_build_pdb_public_symbols(tp, tp_arena, symtab, sect_id_map, pdb->psi, LNK_SymbolScopeIndex_Defined);
|
||||
lnk_build_pdb_public_symbols(tp, tp_arena, symtab, sect_id_map, pdb->psi);
|
||||
|
||||
pdb_build(tp, tp_arena, pdb, string_ht);
|
||||
|
||||
|
||||
@@ -333,16 +333,15 @@ typedef struct
|
||||
|
||||
typedef struct
|
||||
{
|
||||
LNK_Section **sect_id_map;
|
||||
LNK_SymbolScopeIndex scope_idx;
|
||||
LNK_SymbolList **bucket_arr;
|
||||
CV_SymbolList *pub_list_arr;
|
||||
LNK_Section **sect_id_map;
|
||||
LNK_SymbolHashTrieChunkList *chunk_lists;
|
||||
CV_SymbolList *pub_list_arr;
|
||||
|
||||
Rng1U64 *symbol_ranges;
|
||||
PDB_GsiContext *gsi;
|
||||
CV_SymbolPtrArray symbols;
|
||||
U32 *hashes;
|
||||
} LNK_BuildPublicSymbolsTaskData;
|
||||
} LNK_BuildPublicSymbolsTask;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
@@ -566,8 +565,7 @@ internal void lnk_build_pdb_public_symbols(TP_Context *tp,
|
||||
TP_Arena *arena,
|
||||
LNK_SymbolTable *symtab,
|
||||
LNK_Section **sect_id_map,
|
||||
PDB_PsiContext *psi,
|
||||
LNK_SymbolScopeIndex scope_idx);
|
||||
PDB_PsiContext *psi);
|
||||
|
||||
internal String8List lnk_build_pdb(TP_Context *tp,
|
||||
TP_Arena *tp_arena,
|
||||
|
||||
@@ -70,6 +70,12 @@ lnk_parse_directives(Arena *arena, LNK_DirectiveInfo *directive_info, String8 bu
|
||||
for (U64 i = 0; i < ArrayCount(directive_table); ++i) {
|
||||
if (str8_match(directive_table[i].name, opt->string, StringMatchFlag_CaseInsensitive)) {
|
||||
kind = directive_table[i].kind;
|
||||
<<<<<<< HEAD
|
||||
=======
|
||||
if (kind == LNK_Directive_Merge) {
|
||||
String8 v = str8_list_join(scratch.arena, &opt->value_strings, &(StringJoin){ .sep = str8_lit_comp(" ")});
|
||||
}
|
||||
>>>>>>> 9e2d09f (switch to thread safe hash trie map)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -218,20 +218,16 @@ lnk_build_edata(LNK_ExportTable *exptab, LNK_SectionTable *st, LNK_SymbolTable *
|
||||
lnk_chunk_set_debugf(edata->arena, string_buffer_chunk, "EXPORT_STRING_BUFFER");
|
||||
lnk_chunk_set_debugf(edata->arena, image_name_chunk, "EXPORT_IMAGE_NAME");
|
||||
|
||||
LNK_Symbol *image_name_symbol = lnk_make_defined_symbol_chunk(symtab->arena, str8_lit("export_table.name_voff"), LNK_DefinedSymbolVisibility_Internal, 0, image_name_chunk, 0, 0, 0);
|
||||
LNK_Symbol *address_table_symbol = lnk_make_defined_symbol_chunk(symtab->arena, str8_lit("export_table.export_address_table_voff"), LNK_DefinedSymbolVisibility_Internal, 0, voff_table_chunk, 0, 0, 0);
|
||||
LNK_Symbol *name_table_symbol = lnk_make_defined_symbol_chunk(symtab->arena, str8_lit("export_table.name_pointer_table_voff"), LNK_DefinedSymbolVisibility_Internal, 0, name_voff_table_chunk, 0, 0, 0);
|
||||
LNK_Symbol *ordinal_table_symbol = lnk_make_defined_symbol_chunk(symtab->arena, str8_lit("export_table.ordinal_table_voff"), LNK_DefinedSymbolVisibility_Internal, 0, ordinal_table_chunk, 0, 0, 0);
|
||||
lnk_symbol_table_push(symtab, image_name_symbol);
|
||||
lnk_symbol_table_push(symtab, address_table_symbol);
|
||||
lnk_symbol_table_push(symtab, name_table_symbol);
|
||||
lnk_symbol_table_push(symtab, ordinal_table_symbol);
|
||||
LNK_Symbol *image_name_symbol = lnk_symbol_table_push_defined_chunk(symtab, str8_lit("export_table.name_voff"), LNK_DefinedSymbolVisibility_Internal, 0, image_name_chunk, 0, 0, 0);
|
||||
LNK_Symbol *address_table_symbol = lnk_symbol_table_push_defined_chunk(symtab, str8_lit("export_table.export_address_table_voff"), LNK_DefinedSymbolVisibility_Internal, 0, voff_table_chunk, 0, 0, 0);
|
||||
LNK_Symbol *name_table_symbol = lnk_symbol_table_push_defined_chunk(symtab, str8_lit("export_table.name_pointer_table_voff"), LNK_DefinedSymbolVisibility_Internal, 0, name_voff_table_chunk, 0, 0, 0);
|
||||
LNK_Symbol *ordinal_table_symbol = lnk_symbol_table_push_defined_chunk(symtab, str8_lit("export_table.ordinal_table_voff"), LNK_DefinedSymbolVisibility_Internal, 0, ordinal_table_chunk, 0, 0, 0);
|
||||
|
||||
// patch header fields
|
||||
lnk_section_push_reloc(edata, header_chunk, LNK_Reloc_VIRT_OFF_32, OffsetOf(PE_ExportTable, name_voff), image_name_symbol);
|
||||
lnk_section_push_reloc(edata, header_chunk, LNK_Reloc_VIRT_OFF_32, OffsetOf(PE_ExportTable, name_voff), image_name_symbol);
|
||||
lnk_section_push_reloc(edata, header_chunk, LNK_Reloc_VIRT_OFF_32, OffsetOf(PE_ExportTable, export_address_table_voff), address_table_symbol);
|
||||
lnk_section_push_reloc(edata, header_chunk, LNK_Reloc_VIRT_OFF_32, OffsetOf(PE_ExportTable, name_pointer_table_voff), name_table_symbol);
|
||||
lnk_section_push_reloc(edata, header_chunk, LNK_Reloc_VIRT_OFF_32, OffsetOf(PE_ExportTable, ordinal_table_voff), ordinal_table_symbol);
|
||||
lnk_section_push_reloc(edata, header_chunk, LNK_Reloc_VIRT_OFF_32, OffsetOf(PE_ExportTable, name_pointer_table_voff), name_table_symbol);
|
||||
lnk_section_push_reloc(edata, header_chunk, LNK_Reloc_VIRT_OFF_32, OffsetOf(PE_ExportTable, ordinal_table_voff), ordinal_table_symbol);
|
||||
|
||||
// reserve virtual offset chunks
|
||||
LNK_Chunk **ordinal_voff_map = push_array(scratch.arena, LNK_Chunk *, exptab->max_ordinal);
|
||||
@@ -254,9 +250,8 @@ lnk_build_edata(LNK_ExportTable *exptab, LNK_SectionTable *st, LNK_SymbolTable *
|
||||
lnk_chunk_set_debugf(edata->arena, name_chunk, "export: %S", name_cstr);
|
||||
|
||||
// push name symbol
|
||||
String8 name_export_name = push_str8f(symtab->arena, "export.%S", name_cstr);
|
||||
LNK_Symbol *name_symbol = lnk_make_defined_symbol_chunk(symtab->arena, name_export_name, LNK_DefinedSymbolVisibility_Internal, 0, name_chunk, 0, 0, 0);
|
||||
lnk_symbol_table_push(symtab, name_symbol);
|
||||
String8 name_export_name = push_str8f(symtab->arena->v[0], "export.%S", name_cstr);
|
||||
LNK_Symbol *name_symbol = lnk_symbol_table_push_defined_chunk(symtab, name_export_name, LNK_DefinedSymbolVisibility_Internal, 0, name_chunk, 0, 0, 0);
|
||||
|
||||
// name voff
|
||||
LNK_Chunk *voff_chunk = lnk_section_push_chunk_bss(edata, name_voff_table_chunk, exptab->voff_size, /* export table must be sorted lexically: */ name_cstr);
|
||||
|
||||
+63
-102
@@ -18,17 +18,11 @@ lnk_import_table_alloc_static(LNK_SectionTable *st, LNK_SymbolTable *symtab, COF
|
||||
LNK_Chunk *null_dll_import = lnk_section_push_chunk_data(data_sect, dll_table_chunk, str8(0, sizeof(PE_ImportEntry)), str8_lit("zzzzz"));
|
||||
lnk_chunk_set_debugf(data_sect->arena, null_dll_import, "DLL_DIRECTORY_TERMINATOR");
|
||||
|
||||
LNK_Symbol *dll_table_symbol = lnk_make_defined_symbol_chunk(symtab->arena, str8_cstring(LNK_IMPORT_DLL_TABLE_SYMBOL_NAME) , LNK_DefinedSymbolVisibility_Internal, 0, dll_table_chunk, 0, 0, 0);
|
||||
LNK_Symbol *int_symbol = lnk_make_defined_symbol_chunk(symtab->arena, str8_cstring(LNK_IMPORT_NAME_TABLE_SYMBOL_NAME), LNK_DefinedSymbolVisibility_Internal, 0, int_chunk , 0, 0, 0);
|
||||
LNK_Symbol *iat_symbol = lnk_make_defined_symbol_chunk(symtab->arena, str8_cstring(LNK_IMPORT_IAT_SYMBOL_NAME) , LNK_DefinedSymbolVisibility_Internal, 0, iat_chunk , 0, 0, 0);
|
||||
LNK_Symbol *ilt_symbol = lnk_make_defined_symbol_chunk(symtab->arena, str8_cstring(LNK_IMPORT_ILT_SYMBOL_NAME) , LNK_DefinedSymbolVisibility_Internal, 0, ilt_chunk , 0, 0, 0);
|
||||
LNK_Symbol *code_symbol = lnk_make_defined_symbol_chunk(symtab->arena, str8_cstring(LNK_IMPORT_JMP_SYMBOL_NAME) , LNK_DefinedSymbolVisibility_Internal, 0, code_chunk , 0, 0, 0);
|
||||
|
||||
lnk_symbol_table_push(symtab, dll_table_symbol);
|
||||
lnk_symbol_table_push(symtab, int_symbol);
|
||||
lnk_symbol_table_push(symtab, iat_symbol);
|
||||
lnk_symbol_table_push(symtab, ilt_symbol);
|
||||
lnk_symbol_table_push(symtab, code_symbol);
|
||||
lnk_symbol_table_push_defined_chunk(symtab, str8_cstring(LNK_IMPORT_DLL_TABLE_SYMBOL_NAME) , LNK_DefinedSymbolVisibility_Internal, 0, dll_table_chunk, 0, 0, 0);
|
||||
lnk_symbol_table_push_defined_chunk(symtab, str8_cstring(LNK_IMPORT_NAME_TABLE_SYMBOL_NAME), LNK_DefinedSymbolVisibility_Internal, 0, int_chunk , 0, 0, 0);
|
||||
lnk_symbol_table_push_defined_chunk(symtab, str8_cstring(LNK_IMPORT_IAT_SYMBOL_NAME) , LNK_DefinedSymbolVisibility_Internal, 0, iat_chunk , 0, 0, 0);
|
||||
lnk_symbol_table_push_defined_chunk(symtab, str8_cstring(LNK_IMPORT_ILT_SYMBOL_NAME) , LNK_DefinedSymbolVisibility_Internal, 0, ilt_chunk , 0, 0, 0);
|
||||
lnk_symbol_table_push_defined_chunk(symtab, str8_cstring(LNK_IMPORT_JMP_SYMBOL_NAME) , LNK_DefinedSymbolVisibility_Internal, 0, code_chunk , 0, 0, 0);
|
||||
|
||||
Arena *arena = arena_alloc();
|
||||
LNK_ImportTable *imptab = push_array(arena, LNK_ImportTable, 1);
|
||||
@@ -79,23 +73,14 @@ lnk_import_table_alloc_delayed(LNK_SectionTable *st, LNK_SymbolTable *symtab, CO
|
||||
lnk_chunk_set_debugf(data_sect->arena, null_biat_chunk, "BIAT_TERMINATOR");
|
||||
}
|
||||
|
||||
LNK_Symbol *dll_table_symbol = lnk_make_defined_symbol_chunk(symtab->arena, str8_cstring(LNK_DELAYED_IMPORT_DLL_TABLE_SYMBOL_NAME) , LNK_DefinedSymbolVisibility_Internal, 0, dll_table_chunk , 0, 0, 0);
|
||||
LNK_Symbol *int_symbol = lnk_make_defined_symbol_chunk(symtab->arena, str8_cstring(LNK_DELAYED_IMPORT_INT_SYMBOL_NAME) , LNK_DefinedSymbolVisibility_Internal, 0, int_chunk , 0, 0, 0);
|
||||
LNK_Symbol *handle_table_symbol = lnk_make_defined_symbol_chunk(symtab->arena, str8_cstring(LNK_DELAYED_IMPORT_HANDLE_TABLE_SYMBOL_NAME), LNK_DefinedSymbolVisibility_Internal, 0, handle_table_chunk, 0, 0, 0);
|
||||
LNK_Symbol *iat_symbol = lnk_make_defined_symbol_chunk(symtab->arena, str8_cstring(LNK_DELAYED_IMPORT_IAT_SYMBOL_NAME) , LNK_DefinedSymbolVisibility_Internal, 0, iat_chunk , 0, 0, 0);
|
||||
LNK_Symbol *ilt_symbol = lnk_make_defined_symbol_chunk(symtab->arena, str8_cstring(LNK_DELAYED_IMPORT_ILT_SYMBOL_NAME) , LNK_DefinedSymbolVisibility_Internal, 0, ilt_chunk , 0, 0, 0);
|
||||
LNK_Symbol *biat_symbol = lnk_make_defined_symbol_chunk(symtab->arena, str8_cstring(LNK_DELAYED_IMPORT_BIAT_SYMBOL_NAME) , LNK_DefinedSymbolVisibility_Internal, 0, biat_chunk , 0, 0, 0);
|
||||
LNK_Symbol *uiat_symbol = lnk_make_defined_symbol_chunk(symtab->arena, str8_cstring(LNK_DELAYED_IMPORT_UIAT_SYMBOL_NAME) , LNK_DefinedSymbolVisibility_Internal, 0, uiat_chunk , 0, 0, 0);
|
||||
LNK_Symbol *code_symbol = lnk_make_defined_symbol_chunk(symtab->arena, str8_cstring(LNK_DELAYED_IMPORT_CODE_SYMBOL_NAME) , LNK_DefinedSymbolVisibility_Internal, 0, code_chunk , 0, 0, 0);
|
||||
|
||||
lnk_symbol_table_push(symtab, dll_table_symbol);
|
||||
lnk_symbol_table_push(symtab, int_symbol);
|
||||
lnk_symbol_table_push(symtab, handle_table_symbol);
|
||||
lnk_symbol_table_push(symtab, iat_symbol);
|
||||
lnk_symbol_table_push(symtab, ilt_symbol);
|
||||
lnk_symbol_table_push(symtab, biat_symbol);
|
||||
lnk_symbol_table_push(symtab, uiat_symbol);
|
||||
lnk_symbol_table_push(symtab, code_symbol);
|
||||
lnk_symbol_table_push_defined_chunk(symtab, str8_cstring(LNK_DELAYED_IMPORT_DLL_TABLE_SYMBOL_NAME) , LNK_DefinedSymbolVisibility_Internal, 0, dll_table_chunk , 0, 0, 0);
|
||||
lnk_symbol_table_push_defined_chunk(symtab, str8_cstring(LNK_DELAYED_IMPORT_INT_SYMBOL_NAME) , LNK_DefinedSymbolVisibility_Internal, 0, int_chunk , 0, 0, 0);
|
||||
lnk_symbol_table_push_defined_chunk(symtab, str8_cstring(LNK_DELAYED_IMPORT_HANDLE_TABLE_SYMBOL_NAME), LNK_DefinedSymbolVisibility_Internal, 0, handle_table_chunk, 0, 0, 0);
|
||||
lnk_symbol_table_push_defined_chunk(symtab, str8_cstring(LNK_DELAYED_IMPORT_IAT_SYMBOL_NAME) , LNK_DefinedSymbolVisibility_Internal, 0, iat_chunk , 0, 0, 0);
|
||||
lnk_symbol_table_push_defined_chunk(symtab, str8_cstring(LNK_DELAYED_IMPORT_ILT_SYMBOL_NAME) , LNK_DefinedSymbolVisibility_Internal, 0, ilt_chunk , 0, 0, 0);
|
||||
lnk_symbol_table_push_defined_chunk(symtab, str8_cstring(LNK_DELAYED_IMPORT_BIAT_SYMBOL_NAME) , LNK_DefinedSymbolVisibility_Internal, 0, biat_chunk , 0, 0, 0);
|
||||
lnk_symbol_table_push_defined_chunk(symtab, str8_cstring(LNK_DELAYED_IMPORT_UIAT_SYMBOL_NAME) , LNK_DefinedSymbolVisibility_Internal, 0, uiat_chunk , 0, 0, 0);
|
||||
lnk_symbol_table_push_defined_chunk(symtab, str8_cstring(LNK_DELAYED_IMPORT_CODE_SYMBOL_NAME) , LNK_DefinedSymbolVisibility_Internal, 0, code_chunk , 0, 0, 0);
|
||||
|
||||
LNK_ImportTableFlags flags = 0;
|
||||
if (is_unloadable) {
|
||||
@@ -193,21 +178,18 @@ lnk_import_table_push_dll_static(LNK_ImportTable *imptab, LNK_SymbolTable *symta
|
||||
LNK_Chunk *iat_table_chunk = lnk_section_push_chunk_list(data_sect, imptab->iat_chunk, str8_zero());
|
||||
LNK_Chunk *code_table_chunk = lnk_section_push_chunk_list(code_sect, imptab->code_chunk, str8_zero());
|
||||
|
||||
String8 ilt_symbol_name = push_str8f(symtab->arena, "%S.lookup_table_voff", dll_name);
|
||||
LNK_Symbol *ilt_symbol = lnk_make_defined_symbol_chunk(symtab->arena, ilt_symbol_name, LNK_DefinedSymbolVisibility_Internal, 0, ilt_table_chunk, 0, 0, 0);
|
||||
lnk_symbol_table_push(symtab, ilt_symbol);
|
||||
String8 ilt_symbol_name = push_str8f(symtab->arena->v[0], "%S.lookup_table_voff", dll_name);
|
||||
LNK_Symbol *ilt_symbol = lnk_symbol_table_push_defined_chunk(symtab, ilt_symbol_name, LNK_DefinedSymbolVisibility_Internal, 0, ilt_table_chunk, 0, 0, 0);
|
||||
|
||||
String8 iat_symbol_name = push_str8f(symtab->arena, "%S.import_addr_table_voff", dll_name);
|
||||
LNK_Symbol *iat_symbol = lnk_make_defined_symbol_chunk(symtab->arena, iat_symbol_name, LNK_DefinedSymbolVisibility_Internal, 0, iat_table_chunk, 0, 0, 0);
|
||||
lnk_symbol_table_push(symtab, iat_symbol);
|
||||
String8 iat_symbol_name = push_str8f(symtab->arena->v[0], "%S.import_addr_table_voff", dll_name);
|
||||
LNK_Symbol *iat_symbol = lnk_symbol_table_push_defined_chunk(symtab, iat_symbol_name, LNK_DefinedSymbolVisibility_Internal, 0, iat_table_chunk, 0, 0, 0);
|
||||
|
||||
String8 dll_name_cstr = push_cstr(data_sect->arena, dll_name);
|
||||
String8 dll_name_cstr = push_cstr(data_sect->arena, dll_name);
|
||||
LNK_Chunk *dll_name_chunk = lnk_section_push_chunk_data(data_sect, int_table_chunk, dll_name_cstr, str8_zero());
|
||||
lnk_chunk_set_debugf(data_sect->arena, dll_name_chunk, "DLL name chunk (%S)", dll_name);
|
||||
|
||||
String8 dll_name_voff_name = push_str8f(symtab->arena, "%S.name_voff", dll_name);
|
||||
LNK_Symbol *dll_name_voff_symbol = lnk_make_defined_symbol_chunk(symtab->arena, dll_name_voff_name, LNK_DefinedSymbolVisibility_Internal, 0, dll_name_chunk, 0, 0, 0);
|
||||
lnk_symbol_table_push(symtab, dll_name_voff_symbol);
|
||||
String8 dll_name_voff_name = push_str8f(symtab->arena->v[0], "%S.name_voff", dll_name);
|
||||
LNK_Symbol *dll_name_voff_symbol = lnk_symbol_table_push_defined_chunk(symtab, dll_name_voff_name, LNK_DefinedSymbolVisibility_Internal, 0, dll_name_chunk, 0, 0, 0);
|
||||
|
||||
// chunk for dll directory entry
|
||||
PE_ImportEntry *dir = push_array(imptab->arena, PE_ImportEntry, 1);
|
||||
@@ -272,32 +254,29 @@ lnk_import_table_push_dll_delayed(LNK_ImportTable *imptab, LNK_SymbolTable *symt
|
||||
imp_desc->time_stamp = 0;
|
||||
|
||||
// emit entry chunk
|
||||
String8 imp_desc_data = str8_struct(imp_desc);
|
||||
String8 imp_desc_data = str8_struct(imp_desc);
|
||||
LNK_Chunk *imp_desc_chunk = lnk_section_push_chunk_data(data_sect, imptab->dll_table_chunk, imp_desc_data, str8_zero());
|
||||
|
||||
// emit entry symbol
|
||||
String8 imp_desc_name = push_str8f(symtab->arena, "__DELAY_IMPORT_DESCRIPTOR_%S", dll_name);
|
||||
LNK_Symbol *imp_desc_symbol = lnk_make_defined_symbol_chunk(symtab->arena, imp_desc_name, LNK_DefinedSymbolVisibility_Extern, 0, imp_desc_chunk, 0, 0, 0);
|
||||
lnk_symbol_table_push(symtab, imp_desc_symbol);
|
||||
String8 imp_desc_name = push_str8f(symtab->arena->v[0], "__DELAY_IMPORT_DESCRIPTOR_%S", dll_name);
|
||||
LNK_Symbol *imp_desc_symbol = lnk_symbol_table_push_defined_chunk(symtab, imp_desc_name, LNK_DefinedSymbolVisibility_Extern, 0, imp_desc_chunk, 0, 0, 0);
|
||||
|
||||
// emit string table chunk
|
||||
String8 int_table_chunk_debug = push_str8f(data_sect->arena, "delayed.%S.int", dll_name);
|
||||
LNK_Chunk *int_table_chunk = lnk_section_push_chunk_list(data_sect, imptab->int_chunk, int_table_chunk_debug);
|
||||
String8 int_table_chunk_debug = push_str8f(data_sect->arena, "delayed.%S.int", dll_name);
|
||||
LNK_Chunk *int_table_chunk = lnk_section_push_chunk_list(data_sect, imptab->int_chunk, int_table_chunk_debug);
|
||||
|
||||
String8 int_table_symbol_name = push_str8f(symtab->arena, "delayed.%S.int", dll_name);
|
||||
LNK_Symbol *int_table_symbol = lnk_make_defined_symbol_chunk(symtab->arena, int_table_symbol_name, LNK_DefinedSymbolVisibility_Internal, 0, int_table_chunk, 0, 0, 0);
|
||||
lnk_symbol_table_push(symtab, int_table_symbol);
|
||||
String8 int_table_symbol_name = push_str8f(symtab->arena->v[0], "delayed.%S.int", dll_name);
|
||||
LNK_Symbol *int_table_symbol = lnk_symbol_table_push_defined_chunk(symtab, int_table_symbol_name, LNK_DefinedSymbolVisibility_Internal, 0, int_table_chunk, 0, 0, 0);
|
||||
|
||||
LNK_Chunk *null_string_chunk = lnk_section_push_chunk_list(data_sect, int_table_chunk, str8_lit("zzzzz"));
|
||||
lnk_chunk_set_debugf(data_sect->arena, null_string_chunk, "string table null");
|
||||
|
||||
// emit DLL name chunk
|
||||
String8 name_chunk_data = push_cstr(data_sect->arena, dll_name);
|
||||
LNK_Chunk *name_chunk = lnk_section_push_chunk_data(data_sect, int_table_chunk, name_chunk_data, str8_zero());
|
||||
String8 name_chunk_data = push_cstr(data_sect->arena, dll_name);
|
||||
LNK_Chunk *name_chunk = lnk_section_push_chunk_data(data_sect, int_table_chunk, name_chunk_data, str8_zero());
|
||||
|
||||
String8 name_symbol_name = push_str8f(symtab->arena, "delayed.%S.name", dll_name);
|
||||
LNK_Symbol *name_symbol = lnk_make_defined_symbol_chunk(symtab->arena, name_symbol_name, LNK_DefinedSymbolVisibility_Internal, 0, name_chunk, 0, 0, 0);
|
||||
lnk_symbol_table_push(symtab, name_symbol);
|
||||
String8 name_symbol_name = push_str8f(symtab->arena->v[0], "delayed.%S.name", dll_name);
|
||||
LNK_Symbol *name_symbol = lnk_symbol_table_push_defined_chunk(symtab, name_symbol_name, LNK_DefinedSymbolVisibility_Internal, 0, name_chunk, 0, 0, 0);
|
||||
|
||||
// patch DLL name voff
|
||||
lnk_section_push_reloc(data_sect, imp_desc_chunk, LNK_Reloc_VIRT_OFF_32, OffsetOf(PE_DelayedImportEntry, name_voff), name_symbol);
|
||||
@@ -305,9 +284,8 @@ lnk_import_table_push_dll_delayed(LNK_ImportTable *imptab, LNK_SymbolTable *symt
|
||||
// emit DLL handle chunk
|
||||
LNK_Chunk *handle_chunk = lnk_section_push_chunk_bss(data_sect, imptab->handle_table_chunk, handle_size, str8_zero());
|
||||
|
||||
String8 handle_name = push_str8f(symtab->arena, "delayed.%S.handle", dll_name);
|
||||
LNK_Symbol *handle_symbol = lnk_make_defined_symbol_chunk(symtab->arena, handle_name, LNK_DefinedSymbolVisibility_Internal, 0, handle_chunk, 0, 0, 0);
|
||||
lnk_symbol_table_push(symtab, handle_symbol);
|
||||
String8 handle_name = push_str8f(symtab->arena->v[0], "delayed.%S.handle", dll_name);
|
||||
LNK_Symbol *handle_symbol = lnk_symbol_table_push_defined_chunk(symtab, handle_name, LNK_DefinedSymbolVisibility_Internal, 0, handle_chunk, 0, 0, 0);
|
||||
|
||||
// patch DLL handle voff
|
||||
lnk_section_push_reloc(data_sect, imp_desc_chunk, LNK_Reloc_VIRT_OFF_32, OffsetOf(PE_DelayedImportEntry, module_handle_voff), handle_symbol);
|
||||
@@ -315,9 +293,8 @@ lnk_import_table_push_dll_delayed(LNK_ImportTable *imptab, LNK_SymbolTable *symt
|
||||
// emit IAT chunk
|
||||
LNK_Chunk *iat_table_chunk = lnk_section_push_chunk_list(data_sect, imptab->iat_chunk, str8_zero());
|
||||
|
||||
String8 iat_table_name = push_str8f(symtab->arena, "delayed.%S.iat", dll_name);
|
||||
LNK_Symbol *iat_table_symbol = lnk_make_defined_symbol_chunk(symtab->arena, iat_table_name, LNK_DefinedSymbolVisibility_Internal, 0, iat_table_chunk, 0, 0, 0);
|
||||
lnk_symbol_table_push(symtab, iat_table_symbol);
|
||||
String8 iat_table_name = push_str8f(symtab->arena->v[0], "delayed.%S.iat", dll_name);
|
||||
LNK_Symbol *iat_table_symbol = lnk_symbol_table_push_defined_chunk(symtab, iat_table_name, LNK_DefinedSymbolVisibility_Internal, 0, iat_table_chunk, 0, 0, 0);
|
||||
|
||||
LNK_Chunk *null_iat_chunk = lnk_section_push_chunk_bss(data_sect, iat_table_chunk, import_size, str8_lit("zzzzzz"));
|
||||
lnk_chunk_set_debugf(data_sect->arena, null_iat_chunk, "%S: IAT terminator", dll_name);
|
||||
@@ -328,9 +305,8 @@ lnk_import_table_push_dll_delayed(LNK_ImportTable *imptab, LNK_SymbolTable *symt
|
||||
LNK_Chunk *null_ilt_chunk = lnk_section_push_chunk_bss(data_sect, ilt_table_chunk, import_size, str8_lit("zzzzzz"));
|
||||
lnk_chunk_set_debugf(data_sect->arena, null_ilt_chunk, "%S: ILT terminator", dll_name);
|
||||
|
||||
String8 ilt_table_name = push_str8f(symtab->arena, "delayed.%S.ilt", dll_name);
|
||||
LNK_Symbol *ilt_table_symbol = lnk_make_defined_symbol_chunk(symtab->arena, ilt_table_name, LNK_DefinedSymbolVisibility_Extern, 0, ilt_table_chunk, 0, 0, 0);
|
||||
lnk_symbol_table_push(symtab, ilt_table_symbol);
|
||||
String8 ilt_table_name = push_str8f(symtab->arena->v[0], "delayed.%S.ilt", dll_name);
|
||||
LNK_Symbol *ilt_table_symbol = lnk_symbol_table_push_defined_chunk(symtab, ilt_table_name, LNK_DefinedSymbolVisibility_Extern, 0, ilt_table_chunk, 0, 0, 0);
|
||||
|
||||
// patch import address table voff
|
||||
lnk_section_push_reloc(data_sect, imp_desc_chunk, LNK_Reloc_VIRT_OFF_32, OffsetOf(PE_DelayedImportEntry, iat_voff), iat_table_symbol);
|
||||
@@ -343,9 +319,8 @@ lnk_import_table_push_dll_delayed(LNK_ImportTable *imptab, LNK_SymbolTable *symt
|
||||
if (imptab->flags & LNK_ImportTableFlag_EmitBiat) {
|
||||
biat_chunk = lnk_section_push_chunk_list(data_sect, imptab->biat_chunk, str8_zero());
|
||||
|
||||
String8 biat_symbol_name = push_str8f(symtab->arena, "delayed.%S.BIAT", dll_name);
|
||||
LNK_Symbol *biat_symbol = lnk_make_defined_symbol_chunk(symtab->arena, biat_symbol_name, LNK_DefinedSymbolVisibility_Internal, 0, biat_chunk, 0, 0, 0);
|
||||
lnk_symbol_table_push(symtab, biat_symbol);
|
||||
String8 biat_symbol_name = push_str8f(symtab->arena->v[0], "delayed.%S.BIAT", dll_name);
|
||||
LNK_Symbol *biat_symbol = lnk_symbol_table_push_defined_chunk(symtab, biat_symbol_name, LNK_DefinedSymbolVisibility_Internal, 0, biat_chunk, 0, 0, 0);
|
||||
|
||||
// patch BIAT field off
|
||||
lnk_section_push_reloc(data_sect, imp_desc_chunk, LNK_Reloc_VIRT_OFF_32, OffsetOf(PE_DelayedImportEntry, bound_table_voff), biat_symbol);
|
||||
@@ -356,9 +331,8 @@ lnk_import_table_push_dll_delayed(LNK_ImportTable *imptab, LNK_SymbolTable *symt
|
||||
if (imptab->flags & LNK_ImportTableFlag_EmitUiat) {
|
||||
uiat_chunk = lnk_section_push_chunk_list(data_sect, imptab->uiat_chunk, str8_zero());
|
||||
|
||||
String8 uiat_symbol_name = push_str8f(symtab->arena, "delayed.%S.UIAT", dll_name);
|
||||
LNK_Symbol *uiat_symbol = lnk_make_defined_symbol_chunk(symtab->arena, uiat_symbol_name, LNK_DefinedSymbolVisibility_Internal, 0, uiat_chunk, 0, 0, 0);
|
||||
lnk_symbol_table_push(symtab, uiat_symbol);
|
||||
String8 uiat_symbol_name = push_str8f(symtab->arena->v[0], "delayed.%S.UIAT", dll_name);
|
||||
LNK_Symbol *uiat_symbol = lnk_symbol_table_push_defined_chunk(symtab, uiat_symbol_name, LNK_DefinedSymbolVisibility_Internal, 0, uiat_chunk, 0, 0, 0);
|
||||
|
||||
// patch UIAT field voff
|
||||
lnk_section_push_reloc(data_sect, imp_desc_chunk, LNK_Reloc_VIRT_OFF_32, OffsetOf(PE_DelayedImportEntry, unload_table_voff), uiat_symbol);
|
||||
@@ -372,7 +346,7 @@ lnk_import_table_push_dll_delayed(LNK_ImportTable *imptab, LNK_SymbolTable *symt
|
||||
LNK_Chunk *tail_merge_chunk = 0;
|
||||
switch (machine) {
|
||||
case COFF_MachineType_X64: {
|
||||
LNK_Symbol *delay_load_helper_symbol = lnk_make_undefined_symbol(symtab->arena, str8_lit(LNK_DELAY_LOAD_HELPER2_SYMBOL_NAME), LNK_SymbolScopeFlag_Main);
|
||||
LNK_Symbol *delay_load_helper_symbol = lnk_make_undefined_symbol(symtab->arena->v[0], str8_lit(LNK_DELAY_LOAD_HELPER2_SYMBOL_NAME), LNK_SymbolScopeFlag_Main);
|
||||
tail_merge_chunk = lnk_emit_tail_merge_thunk_x64(code_sect, code_chunk, imp_desc_symbol, delay_load_helper_symbol);
|
||||
} break;
|
||||
default: {
|
||||
@@ -438,9 +412,8 @@ lnk_import_table_push_func_static(LNK_ImportTable *imptab, LNK_SymbolTable *symt
|
||||
LNK_Chunk *int_chunk = lnk_section_push_chunk_data(data_sect, int_table_chunk, int_data, str8_zero());
|
||||
|
||||
// create symbol for lookup chunk
|
||||
String8 int_symbol_name = push_str8f(symtab->arena, "static.%S.%S.name", dll->name, header->func_name);
|
||||
LNK_Symbol *int_symbol = lnk_make_defined_symbol_chunk(symtab->arena, int_symbol_name, LNK_DefinedSymbolVisibility_Internal, 0, int_chunk, 0, 0, 0);
|
||||
lnk_symbol_table_push(symtab, int_symbol);
|
||||
String8 int_symbol_name = push_str8f(symtab->arena->v[0], "static.%S.%S.name", dll->name, header->func_name);
|
||||
LNK_Symbol *int_symbol = lnk_symbol_table_push_defined_chunk(symtab, int_symbol_name, LNK_DefinedSymbolVisibility_Internal, 0, int_chunk, 0, 0, 0);
|
||||
|
||||
// in the file IAT mirrors ILT, dynamic linker later overwrites it with imported function addresses.
|
||||
ilt_chunk = lnk_section_push_chunk_bss(data_sect, ilt_table_chunk, import_size, sort_index);
|
||||
@@ -464,12 +437,10 @@ lnk_import_table_push_func_static(LNK_ImportTable *imptab, LNK_SymbolTable *symt
|
||||
} break;
|
||||
}
|
||||
|
||||
String8 ilt_symbol_name = push_str8f(symtab->arena, "static.%S.%S.ilt", dll->name, header->func_name);
|
||||
String8 iat_symbol_name = push_str8f(symtab->arena, "__imp_%S", header->func_name);
|
||||
LNK_Symbol *ilt_symbol = lnk_make_defined_symbol_chunk(symtab->arena, ilt_symbol_name, LNK_DefinedSymbolVisibility_Internal, 0, ilt_chunk, 0, 0, 0);
|
||||
LNK_Symbol *iat_symbol = lnk_make_defined_symbol_chunk(symtab->arena, iat_symbol_name, LNK_DefinedSymbolVisibility_Extern, 0, iat_chunk, 0, 0, 0);
|
||||
lnk_symbol_table_push(symtab, ilt_symbol);
|
||||
lnk_symbol_table_push(symtab, iat_symbol);
|
||||
String8 ilt_symbol_name = push_str8f(symtab->arena->v[0], "static.%S.%S.ilt", dll->name, header->func_name);
|
||||
String8 iat_symbol_name = push_str8f(symtab->arena->v[0], "__imp_%S", header->func_name);
|
||||
LNK_Symbol *ilt_symbol = lnk_symbol_table_push_defined_chunk(symtab, ilt_symbol_name, LNK_DefinedSymbolVisibility_Internal, 0, ilt_chunk, 0, 0, 0);
|
||||
LNK_Symbol *iat_symbol = lnk_symbol_table_push_defined_chunk(symtab, iat_symbol_name, LNK_DefinedSymbolVisibility_Extern, 0, iat_chunk, 0, 0, 0);
|
||||
|
||||
// generate thunks
|
||||
LNK_Symbol *jmp_thunk_symbol = g_null_symbol_ptr;
|
||||
@@ -481,9 +452,8 @@ lnk_import_table_push_func_static(LNK_ImportTable *imptab, LNK_SymbolTable *symt
|
||||
lnk_section_associate_chunks(data_sect, iat_chunk, jmp_thunk_chunk);
|
||||
|
||||
// push jump thunk symbol
|
||||
String8 jmp_thunk_symbol_name = push_str8_copy(symtab->arena, header->func_name);
|
||||
String8 jmp_thunk_symbol_name = push_str8_copy(symtab->arena->v[0], header->func_name);
|
||||
jmp_thunk_symbol = lnk_emit_jmp_thunk_symbol(symtab, jmp_thunk_chunk, jmp_thunk_symbol_name);
|
||||
lnk_symbol_set_debugf(symtab->arena, jmp_thunk_symbol, "x64 jmp thunk %S.%S", dll->name, header->func_name);
|
||||
} break;
|
||||
default: lnk_not_implemented("TODO: support for machine 0x%X", dll->machine); break;
|
||||
}
|
||||
@@ -538,19 +508,16 @@ lnk_import_table_push_func_delayed(LNK_ImportTable *imptab, LNK_SymbolTable *sym
|
||||
if (header->type == COFF_ImportHeaderType_CODE) {
|
||||
switch (dll->machine) {
|
||||
case COFF_MachineType_X64: {
|
||||
String8 iat_symbol_name = push_str8f(symtab->arena, "__imp_%S", header->func_name);
|
||||
LNK_Symbol *iat_symbol = lnk_make_undefined_symbol(symtab->arena, iat_symbol_name, LNK_SymbolScopeFlag_Main);
|
||||
lnk_symbol_set_debugf(symtab->arena, iat_symbol, "x64 IAT (delayed) %S.%S", dll->name, header->func_name);
|
||||
String8 iat_symbol_name = push_str8f(symtab->arena->v[0], "__imp_%S", header->func_name);
|
||||
LNK_Symbol *iat_symbol = lnk_make_undefined_symbol(symtab->arena->v[0], iat_symbol_name, LNK_SymbolScopeFlag_Main);
|
||||
|
||||
// emit jmp thunk chunk
|
||||
jmp_thunk_chunk = lnk_emit_indirect_jump_thunk_x64(code_sect, code_table_chunk, iat_symbol);
|
||||
jmp_thunk_symbol = lnk_emit_jmp_thunk_symbol(symtab, jmp_thunk_chunk, header->func_name);
|
||||
lnk_symbol_set_debugf(symtab->arena, jmp_thunk_symbol, "x64 jmp thunk (delayed) %S.%S", dll->name, header->func_name);
|
||||
|
||||
// emit load thunk
|
||||
load_thunk_chunk = lnk_emit_load_thunk_x64(code_sect, code_table_chunk, iat_symbol, dll->tail_merge_symbol);
|
||||
load_thunk_symbol = lnk_emit_load_thunk_symbol(symtab, load_thunk_chunk, header->func_name);
|
||||
lnk_symbol_set_debugf(symtab->arena, load_thunk_symbol, "x64 load thunk (delayed) %S.%S", dll->name, header->func_name);
|
||||
} break;
|
||||
default: lnk_not_implemented("TODO: support for machine 0x%X", dll->machine); break;
|
||||
}
|
||||
@@ -582,9 +549,8 @@ lnk_import_table_push_func_delayed(LNK_ImportTable *imptab, LNK_SymbolTable *sym
|
||||
LNK_Chunk *int_chunk = lnk_section_push_chunk_data(data_sect, int_table_chunk, int_data, str8_zero());
|
||||
|
||||
// create symbol for lookup chunk
|
||||
String8 int_symbol_name = push_str8f(symtab->arena, "%S.%S.name.delayed", dll->name, header->func_name);
|
||||
int_symbol = lnk_make_defined_symbol_chunk(symtab->arena, int_symbol_name, LNK_DefinedSymbolVisibility_Internal, 0, int_chunk, 0, 0, 0);
|
||||
lnk_symbol_table_push(symtab, int_symbol);
|
||||
String8 int_symbol_name = push_str8f(symtab->arena->v[0], "%S.%S.name.delayed", dll->name, header->func_name);
|
||||
int_symbol = lnk_symbol_table_push_defined_chunk(symtab, int_symbol_name, LNK_DefinedSymbolVisibility_Internal, 0, int_chunk, 0, 0, 0);
|
||||
|
||||
// dynamic linker patches this voff on DLL load event
|
||||
ilt_chunk = lnk_section_push_chunk_bss(data_sect, ilt_table_chunk, import_size, sort_index);
|
||||
@@ -635,13 +601,11 @@ lnk_import_table_push_func_delayed(LNK_ImportTable *imptab, LNK_SymbolTable *sym
|
||||
lnk_section_associate_chunks(data_sect, iat_chunk, load_thunk_chunk);
|
||||
}
|
||||
|
||||
String8 iat_symbol_name = push_str8f(symtab->arena, "__imp_%S", header->func_name);
|
||||
LNK_Symbol *iat_symbol = lnk_make_defined_symbol_chunk(symtab->arena, iat_symbol_name, LNK_DefinedSymbolVisibility_Extern, 0, iat_chunk, 0, 0, 0);
|
||||
lnk_symbol_table_push(symtab, iat_symbol);
|
||||
String8 iat_symbol_name = push_str8f(symtab->arena->v[0], "__imp_%S", header->func_name);
|
||||
LNK_Symbol *iat_symbol = lnk_symbol_table_push_defined_chunk(symtab, iat_symbol_name, LNK_DefinedSymbolVisibility_Extern, 0, iat_chunk, 0, 0, 0);
|
||||
|
||||
String8 ilt_symbol_name = push_str8f(symtab->arena, "%S.%S.ilt.delayed", dll->name, header->func_name);
|
||||
LNK_Symbol *ilt_symbol = lnk_make_defined_symbol_chunk(symtab->arena, ilt_symbol_name, LNK_DefinedSymbolVisibility_Internal, 0, ilt_chunk, 0, 0, 0);
|
||||
lnk_symbol_table_push(symtab, ilt_symbol);
|
||||
String8 ilt_symbol_name = push_str8f(symtab->arena->v[0], "%S.%S.ilt.delayed", dll->name, header->func_name);
|
||||
LNK_Symbol *ilt_symbol = lnk_symbol_table_push_defined_chunk(symtab, ilt_symbol_name, LNK_DefinedSymbolVisibility_Internal, 0, ilt_chunk, 0, 0, 0);
|
||||
|
||||
// fill out import
|
||||
LNK_ImportFunc *func = push_array(imptab->arena, LNK_ImportFunc, 1);
|
||||
@@ -771,9 +735,8 @@ lnk_emit_load_thunk_symbol(LNK_SymbolTable *symtab, LNK_Chunk *chunk, String8 fu
|
||||
{
|
||||
ProfBeginFunction();
|
||||
// emit load thunk symbol
|
||||
String8 load_thunk_name = push_str8f(symtab->arena, "__imp_load_%S", func_name);
|
||||
LNK_Symbol *load_thunk_symbol = lnk_make_defined_symbol_chunk(symtab->arena, load_thunk_name, LNK_DefinedSymbolVisibility_Extern, LNK_DefinedSymbolFlag_IsFunc|LNK_DefinedSymbolFlag_IsThunk, chunk, 0, 0, 0);
|
||||
lnk_symbol_table_push(symtab, load_thunk_symbol);
|
||||
String8 load_thunk_name = push_str8f(symtab->arena->v[0], "__imp_load_%S", func_name);
|
||||
LNK_Symbol *load_thunk_symbol = lnk_symbol_table_push_defined_chunk(symtab, load_thunk_name, LNK_DefinedSymbolVisibility_Extern, LNK_DefinedSymbolFlag_IsFunc|LNK_DefinedSymbolFlag_IsThunk, chunk, 0, 0, 0);
|
||||
ProfEnd();
|
||||
return load_thunk_symbol;
|
||||
}
|
||||
@@ -782,9 +745,8 @@ internal LNK_Symbol *
|
||||
lnk_emit_jmp_thunk_symbol(LNK_SymbolTable *symtab, LNK_Chunk *chunk, String8 func_name)
|
||||
{
|
||||
ProfBeginFunction();
|
||||
String8 jmp_thunk_name = push_str8f(symtab->arena, "%S", func_name);
|
||||
LNK_Symbol *jmp_thunk_symbol = lnk_make_defined_symbol_chunk(symtab->arena, jmp_thunk_name, LNK_DefinedSymbolVisibility_Extern, LNK_DefinedSymbolFlag_IsFunc|LNK_DefinedSymbolFlag_IsThunk, chunk, 0, 0, 0);
|
||||
lnk_symbol_table_push(symtab, jmp_thunk_symbol);
|
||||
String8 jmp_thunk_name = push_str8f(symtab->arena->v[0], "%S", func_name);
|
||||
LNK_Symbol *jmp_thunk_symbol = lnk_symbol_table_push_defined_chunk(symtab, jmp_thunk_name, LNK_DefinedSymbolVisibility_Extern, LNK_DefinedSymbolFlag_IsFunc|LNK_DefinedSymbolFlag_IsThunk, chunk, 0, 0, 0);
|
||||
ProfEnd();
|
||||
return jmp_thunk_symbol;
|
||||
}
|
||||
@@ -793,9 +755,8 @@ internal LNK_Symbol *
|
||||
lnk_emit_tail_merge_symbol(LNK_SymbolTable *symtab, LNK_Chunk *chunk, String8 func_name)
|
||||
{
|
||||
ProfBeginFunction();
|
||||
String8 tail_merge_name = push_str8f(symtab->arena, "__tailMerge_%S", func_name);
|
||||
LNK_Symbol *tail_merge_symbol = lnk_make_defined_symbol_chunk(symtab->arena, tail_merge_name, LNK_DefinedSymbolVisibility_Extern, LNK_DefinedSymbolFlag_IsFunc|LNK_DefinedSymbolFlag_IsThunk, chunk, 0, 0, 0);
|
||||
lnk_symbol_table_push(symtab, tail_merge_symbol);
|
||||
String8 tail_merge_name = push_str8f(symtab->arena->v[0], "__tailMerge_%S", func_name);
|
||||
LNK_Symbol *tail_merge_symbol = lnk_symbol_table_push_defined_chunk(symtab, tail_merge_name, LNK_DefinedSymbolVisibility_Extern, LNK_DefinedSymbolFlag_IsFunc|LNK_DefinedSymbolFlag_IsThunk, chunk, 0, 0, 0);
|
||||
ProfEnd();
|
||||
return tail_merge_symbol;
|
||||
}
|
||||
|
||||
+14
-8
@@ -97,6 +97,8 @@ lnk_lib_symbol_array_sort(LNK_LibSymbol *arr, U64 count)
|
||||
internal LNK_Lib
|
||||
lnk_lib_from_data(Arena *arena, String8 data, String8 path)
|
||||
{
|
||||
ProfBeginFunction();
|
||||
|
||||
U64 symbol_count;
|
||||
String8 string_table;
|
||||
U32 *member_off_arr;
|
||||
@@ -167,9 +169,11 @@ lnk_lib_from_data(Arena *arena, String8 data, String8 path)
|
||||
lib.symbol_name_list = symbol_name_list;
|
||||
lib.long_names = parse.long_names;
|
||||
|
||||
ProfEnd();
|
||||
return lib;
|
||||
}
|
||||
|
||||
internal
|
||||
THREAD_POOL_TASK_FUNC(lnk_lib_initer)
|
||||
{
|
||||
LNK_LibIniter *task = raw_task;
|
||||
@@ -179,6 +183,7 @@ THREAD_POOL_TASK_FUNC(lnk_lib_initer)
|
||||
String8 path = task->path_arr[task_id];
|
||||
|
||||
*lib = lnk_lib_from_data(arena, data, path);
|
||||
lib->input_idx = task->base_input_idx + task_id;
|
||||
}
|
||||
|
||||
internal LNK_LibNodeArray
|
||||
@@ -187,15 +192,16 @@ lnk_lib_list_push_parallel(TP_Context *tp, TP_Arena *arena, LNK_LibList *list, S
|
||||
Assert(data_arr.count == path_arr.count);
|
||||
U64 lib_count = data_arr.count;
|
||||
|
||||
LNK_LibIniter lib_initer = {0};
|
||||
lib_initer.node_arr = lnk_lib_list_reserve(arena->v[0], list, lib_count);
|
||||
lib_initer.data_arr = data_arr.v;
|
||||
lib_initer.path_arr = path_arr.v;
|
||||
tp_for_parallel(tp, arena, lib_count, lnk_lib_initer, &lib_initer);
|
||||
LNK_LibIniter task = {0};
|
||||
task.node_arr = lnk_lib_list_reserve(arena->v[0], list, lib_count);
|
||||
task.data_arr = data_arr.v;
|
||||
task.path_arr = path_arr.v;
|
||||
task.base_input_idx = list->count;
|
||||
tp_for_parallel(tp, arena, lib_count, lnk_lib_initer, &task);
|
||||
|
||||
LNK_LibNodeArray arr;
|
||||
arr.count = lib_count;
|
||||
arr.v = lib_initer.node_arr;
|
||||
LNK_LibNodeArray arr = {0};
|
||||
arr.count = lib_count;
|
||||
arr.v = task.node_arr;
|
||||
return arr;
|
||||
}
|
||||
|
||||
|
||||
@@ -12,6 +12,7 @@ typedef struct LNK_Lib
|
||||
U32 * member_off_arr;
|
||||
String8List symbol_name_list;
|
||||
String8 long_names;
|
||||
U64 input_idx;
|
||||
} LNK_Lib;
|
||||
|
||||
typedef struct LNK_LibNode
|
||||
@@ -92,9 +93,10 @@ typedef struct LNK_LibBuild
|
||||
|
||||
typedef struct
|
||||
{
|
||||
LNK_LibNode *node_arr;
|
||||
String8 *data_arr;
|
||||
String8 *path_arr;
|
||||
LNK_LibNode *node_arr;
|
||||
String8 *data_arr;
|
||||
String8 *path_arr;
|
||||
U64 base_input_idx;
|
||||
} LNK_LibIniter;
|
||||
|
||||
////////////////////////////////
|
||||
|
||||
@@ -417,7 +417,7 @@ THREAD_POOL_TASK_FUNC(lnk_obj_initer)
|
||||
lnk_chunk_set_debugf(arena, master_common_block, "%S: master common block", path);
|
||||
|
||||
// convert from coff
|
||||
LNK_SymbolArray symbol_arr = lnk_symbol_array_from_coff(arena, input->data, cached_path, coff_info.string_table_off, coff_info.section_count_no_null, coff_sect_arr, coff_symbols, chunk_arr, master_common_block);
|
||||
LNK_SymbolArray symbol_arr = lnk_symbol_array_from_coff(arena, input->data, obj, cached_path, coff_info.string_table_off, coff_info.section_count_no_null, coff_sect_arr, coff_symbols, chunk_arr, master_common_block);
|
||||
LNK_SymbolList symbol_list = lnk_symbol_list_from_array(arena, symbol_arr);
|
||||
LNK_RelocList *reloc_list_arr = lnk_reloc_list_array_from_coff(arena, coff_info.machine, input->data, coff_info.section_count_no_null, coff_sect_arr, chunk_arr, symbol_arr);
|
||||
|
||||
@@ -425,6 +425,7 @@ THREAD_POOL_TASK_FUNC(lnk_obj_initer)
|
||||
obj->data = input->data;
|
||||
obj->path = cached_path;
|
||||
obj->lib_path = cached_lib_path;
|
||||
obj->input_idx = obj_idx;
|
||||
obj->machine = coff_info.machine;
|
||||
obj->chunk_count = chunk_count;
|
||||
obj->sect_count = coff_info.section_count_no_null;
|
||||
@@ -712,6 +713,7 @@ lnk_obj_list_push_parallel(TP_Context *tp, TP_Arena *arena, LNK_ObjList *obj_lis
|
||||
internal LNK_SymbolArray
|
||||
lnk_symbol_array_from_coff(Arena *arena,
|
||||
String8 coff_data,
|
||||
LNK_Obj *obj,
|
||||
String8 obj_path,
|
||||
U64 string_table_off,
|
||||
U64 sect_count,
|
||||
@@ -729,7 +731,8 @@ lnk_symbol_array_from_coff(Arena *arena,
|
||||
for (U64 symbol_idx = 0; symbol_idx < coff_symbols.count; symbol_idx += 1) {
|
||||
COFF_Symbol32 *coff_symbol = &coff_symbols.v[symbol_idx];
|
||||
LNK_Symbol *symbol = &symbol_array.v[symbol_idx];
|
||||
lnk_symbol_set_debug(symbol, obj_path);
|
||||
|
||||
symbol->obj = obj;
|
||||
|
||||
String8 name = coff_read_symbol_name(coff_data, string_table_off, &coff_symbol->name);
|
||||
|
||||
|
||||
@@ -32,6 +32,7 @@ typedef struct LNK_Obj
|
||||
String8 data;
|
||||
String8 path;
|
||||
String8 lib_path;
|
||||
U64 input_idx;
|
||||
U64 common_symbol_size;
|
||||
COFF_MachineType machine;
|
||||
U64 chunk_count;
|
||||
@@ -179,7 +180,7 @@ internal LNK_ChunkList * lnk_collect_obj_chunks(TP_Context *tp, TP_Arena *arena
|
||||
internal LNK_ObjNodeArray lnk_obj_list_push_parallel(TP_Context *tp, TP_Arena *tp_arena, LNK_ObjList *obj_list, LNK_SectionTable *st, U64 input_count, LNK_InputObj **inputs);
|
||||
|
||||
internal LNK_Chunk * lnk_sect_chunk_array_from_coff(Arena *arena, U64 obj_id, String8 obj_path, String8 coff_data, U64 sect_count, COFF_SectionHeader *coff_sect_arr, String8 *sect_name_arr, String8 *sect_postfix_arr);
|
||||
internal LNK_SymbolArray lnk_symbol_array_from_coff(Arena *arena, String8 coff_data, String8 obj_path, U64 string_table_off, U64 sect_count, COFF_SectionHeader *coff_sect_arr, COFF_Symbol32Array coff_symbols, LNK_Chunk *chunk_arr, LNK_Chunk *master_common_block);
|
||||
internal LNK_SymbolArray lnk_symbol_array_from_coff(Arena *arena, String8 coff_data, LNK_Obj *obj, String8 obj_path, U64 string_table_off, U64 sect_count, COFF_SectionHeader *coff_sect_arr, COFF_Symbol32Array coff_symbols, LNK_Chunk *chunk_arr, LNK_Chunk *master_common_block);
|
||||
internal LNK_RelocList lnk_reloc_list_from_coff_reloc_array(Arena *arena, COFF_MachineType machine, LNK_Chunk *chunk, LNK_SymbolArray symbol_array, COFF_Reloc *reloc_v, U64 reloc_count);
|
||||
internal LNK_RelocList * lnk_reloc_list_array_from_coff(Arena *arena, COFF_MachineType machine, String8 coff_data, U64 sect_count, COFF_SectionHeader *coff_sect_arr, LNK_Chunk *sect_chunk_arr, LNK_SymbolArray symbol_array);
|
||||
internal LNK_DirectiveInfo lnk_init_directives(Arena *arena, String8 obj_path, U64 chunk_count, String8 *sect_name_arr, LNK_Chunk *chunk_arr);
|
||||
|
||||
+420
-509
File diff suppressed because it is too large
Load Diff
@@ -90,27 +90,22 @@ typedef enum
|
||||
LNK_Symbol_Undefined,
|
||||
} LNK_SymbolType;
|
||||
|
||||
#define LNK_DEBUG_SYMBOLS 1
|
||||
typedef struct LNK_Symbol
|
||||
{
|
||||
String8 name;
|
||||
LNK_SymbolType type;
|
||||
String8 name;
|
||||
LNK_SymbolType type;
|
||||
struct LNK_Obj *obj;
|
||||
union {
|
||||
LNK_DefinedSymbol defined;
|
||||
LNK_WeakSymbol weak;
|
||||
LNK_UndefinedSymbol undefined;
|
||||
LNK_LazySymbol lazy;
|
||||
} u;
|
||||
#if LNK_DEBUG_SYMBOLS
|
||||
String8 debug;
|
||||
#endif
|
||||
} LNK_Symbol;
|
||||
|
||||
typedef struct LNK_SymbolNode
|
||||
{
|
||||
struct LNK_SymbolNode *next;
|
||||
struct LNK_SymbolNode *prev;
|
||||
U64 hash;
|
||||
LNK_Symbol *data;
|
||||
} LNK_SymbolNode;
|
||||
|
||||
@@ -133,55 +128,45 @@ typedef struct LNK_SymbolArray
|
||||
LNK_Symbol *v;
|
||||
} LNK_SymbolArray;
|
||||
|
||||
typedef struct LNK_SymbolHashTrie
|
||||
{
|
||||
String8 *name;
|
||||
LNK_Symbol *symbol;
|
||||
struct LNK_SymbolHashTrie *child[4];
|
||||
} LNK_SymbolHashTrie;
|
||||
|
||||
typedef struct LNK_SymbolHashTrieChunk
|
||||
{
|
||||
struct LNK_SymbolHashTrieChunk *next;
|
||||
U64 count;
|
||||
U64 cap;
|
||||
LNK_SymbolHashTrie *v;
|
||||
} LNK_SymbolHashTrieChunk;
|
||||
|
||||
typedef struct LNK_SymbolHashTrieChunkList
|
||||
{
|
||||
U64 count;
|
||||
LNK_SymbolHashTrieChunk *first;
|
||||
LNK_SymbolHashTrieChunk *last;
|
||||
} LNK_SymbolHashTrieChunkList;
|
||||
|
||||
typedef struct LNK_SymbolTable
|
||||
{
|
||||
Arena *arena;
|
||||
U64 bucket_count[LNK_SymbolScopeIndex_Count];
|
||||
LNK_SymbolList *buckets[LNK_SymbolScopeIndex_Count];
|
||||
TP_Arena *arena;
|
||||
LNK_SymbolHashTrie *scopes[LNK_SymbolScopeIndex_Count];
|
||||
LNK_SymbolHashTrieChunkList *chunk_lists[LNK_SymbolScopeIndex_Count];
|
||||
} LNK_SymbolTable;
|
||||
|
||||
////////////////////////////////
|
||||
// parallel for wrappers
|
||||
|
||||
typedef struct
|
||||
{
|
||||
LNK_Symbol *symbol_arr;
|
||||
Rng1U64 *range_arr;
|
||||
U64 *hash_arr;
|
||||
} LNK_SymbolNameHasher;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
LNK_SymbolNode **input_arr;
|
||||
Rng1U64 *range_arr;
|
||||
} LNK_SymbolNodePtrHasher;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
LNK_SymbolNode *input_arr;
|
||||
Rng1U64 *range_arr;
|
||||
} LNK_SymbolNodeHasher;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
LNK_SymbolTable *symtab;
|
||||
LNK_SymbolList *bucket_arr;
|
||||
Rng1U64 *range_arr;
|
||||
} LNK_DefinedSymbolInserter;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
LNK_SymbolTable *symtab;
|
||||
LNK_SymbolList *bucket_arr;
|
||||
Rng1U64 *range_arr;
|
||||
Rng1U64 *ranges;
|
||||
LNK_Symbol *arr;
|
||||
} LNK_LazySymbolInserter;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
LNK_SymbolTable *symtab;
|
||||
Rng1U64 *range_arr;
|
||||
} LNK_ComdatFolder;
|
||||
|
||||
////////////////////////////////
|
||||
|
||||
extern LNK_Symbol g_null_symbol;
|
||||
@@ -201,53 +186,34 @@ internal LNK_Symbol * lnk_make_undefined_symbol(Arena *arena, String8 name, LNK_
|
||||
internal LNK_Symbol * lnk_make_weak_symbol(Arena *arena, String8 name, COFF_WeakExtType lookup, LNK_Symbol *fallback);
|
||||
internal LNK_Symbol * lnk_make_lazy_symbol(Arena *arena, String8 name, struct LNK_Lib *lib, U64 member_offset);
|
||||
|
||||
#if LNK_DEBUG_SYMBOLS
|
||||
#define lnk_symbol_set_debugf(a, s, fmt, ...) do { (s)->debug = push_str8f((a), fmt, __VA_ARGS__); } while (0)
|
||||
#define lnk_symbol_set_debug(s, str) do { (s)->debug = str; } while (0)
|
||||
#else
|
||||
#define lnk_symbol_set_debugf(...)
|
||||
#define lnk_symbol_set_debug(...)
|
||||
#endif
|
||||
internal LNK_Chunk * lnk_chunk_from_symbol(LNK_Symbol *symbol);
|
||||
|
||||
internal LNK_Chunk * lnk_defined_symbol_get_chunk(LNK_DefinedSymbol *symbol);
|
||||
|
||||
internal void lnk_symbol_update_chunk_ref(LNK_Symbol *symbol, U64 src_sect_id, U64 dst_sect_id, U64 *id_map, U64 id_count);
|
||||
////////////////////////////////
|
||||
|
||||
internal void lnk_symbol_list_push_node(LNK_SymbolList *list, LNK_SymbolNode *node);
|
||||
internal LNK_SymbolNode * lnk_symbol_list_push(Arena *arena, LNK_SymbolList *list, LNK_Symbol *symbol);
|
||||
internal void lnk_symbol_list_push_list(LNK_SymbolList *list, LNK_SymbolList *to_push);
|
||||
internal void lnk_symbol_list_insert_after(LNK_SymbolList *list, LNK_SymbolNode *node, LNK_SymbolNode *insert);
|
||||
internal LNK_SymbolNode * lnk_symbol_list_pop_node(LNK_SymbolList *list);
|
||||
internal LNK_Symbol * lnk_symbol_list_pop(LNK_SymbolList *list);
|
||||
internal void lnk_symbol_list_remove(LNK_SymbolList *list, LNK_SymbolNode *node);
|
||||
internal void lnk_symbol_list_concat_in_place(LNK_SymbolList *list, LNK_SymbolList *to_concat);
|
||||
internal LNK_SymbolNodeArray lnk_symbol_node_array_from_list(Arena *arena, LNK_SymbolList list);
|
||||
|
||||
internal LNK_SymbolList lnk_symbol_list_from_array(Arena *arena, LNK_SymbolArray arr);
|
||||
internal LNK_SymbolNodeArray lnk_symbol_node_array_from_list(Arena *arena, LNK_SymbolList list);
|
||||
internal LNK_SymbolArray lnk_symbol_array_from_list(Arena *arena, LNK_SymbolList list);
|
||||
internal LNK_Symbol * lnk_symbol_array_search(LNK_SymbolArray symarr, String8 name, StringMatchFlags flags);
|
||||
internal U64 * lnk_symbol_array_hash(TP_Context *tp, Arena *arena, LNK_Symbol *arr, U64 count);
|
||||
|
||||
internal LNK_SymbolTable * lnk_symbol_table_alloc(void);
|
||||
internal LNK_SymbolTable * lnk_symbol_table_alloc_ex(U64 defined_cap, U64 internal_cap, U64 weak_cap, U64 lib_cap);
|
||||
internal void lnk_symbol_table_release(LNK_SymbolTable **symtab);
|
||||
internal U64 lnk_symbol_table_hash(String8 string);
|
||||
internal LNK_SymbolNode * lnk_symbol_table_search_bucket(LNK_SymbolTable *symtab, LNK_SymbolScopeIndex scope_idx, U64 bucket_idx, String8 name, U64 hash);
|
||||
internal LNK_SymbolNode * lnk_symbol_table_search_node_hash(LNK_SymbolTable *symtab, LNK_SymbolScopeFlags scope_flags, String8 name, U64 hash);
|
||||
internal LNK_SymbolNode * lnk_symbol_table_search_node(LNK_SymbolTable *symtab, LNK_SymbolScopeFlags scope, String8 name);
|
||||
internal LNK_Symbol * lnk_symbol_table_search(LNK_SymbolTable *symtab, LNK_SymbolScopeFlags scope_flags, String8 name);
|
||||
internal LNK_Symbol * lnk_symbol_table_searchf(LNK_SymbolTable *symtab, LNK_SymbolScopeFlags scope_flags, char *fmt, ...);
|
||||
internal void lnk_symbol_table_push_node_hash(LNK_SymbolTable *symtab, LNK_SymbolNode *node, U64 hash);
|
||||
internal void lnk_symbol_table_push_node(LNK_SymbolTable *symtab, LNK_SymbolNode *node);
|
||||
internal LNK_SymbolNode * lnk_symbol_table_push(LNK_SymbolTable *symtab, LNK_Symbol *symbol);
|
||||
internal void lnk_symbol_table_push_lazy_arr(TP_Context *tp, LNK_SymbolTable *symtab, LNK_Symbol *arr, U64 count);
|
||||
////////////////////////////////
|
||||
|
||||
internal void lnk_symbol_hash_trie_insert_or_replace(Arena *arena, LNK_SymbolHashTrieChunkList *chunk_list, LNK_SymbolHashTrie **trie, U64 hash, LNK_Symbol *new_symbol);
|
||||
internal LNK_SymbolHashTrie * lnk_symbol_hash_trie_search(LNK_SymbolHashTrie *trie, U64 hash, String8 name);
|
||||
internal void lnk_symbol_hash_trie_remove(LNK_SymbolHashTrie *trie);
|
||||
|
||||
////////////////////////////////
|
||||
|
||||
internal U64 lnk_symbol_hash(String8 string);
|
||||
|
||||
internal LNK_SymbolTable * lnk_symbol_table_init(TP_Arena *arena);
|
||||
internal LNK_Symbol * lnk_symbol_table_search_hash(LNK_SymbolTable *symtab, LNK_SymbolScopeFlags scope, U64 hash, String8 name);
|
||||
internal LNK_Symbol * lnk_symbol_table_search(LNK_SymbolTable *symtab, LNK_SymbolScopeFlags scope, String8 name);
|
||||
internal LNK_Symbol * lnk_symbol_table_searchf(LNK_SymbolTable *symtab, LNK_SymbolScopeFlags scope, char *fmt, ...);
|
||||
internal void lnk_symbol_table_push_hash(LNK_SymbolTable *symtab, U64 hash, LNK_Symbol *symbol);
|
||||
internal void lnk_symbol_table_push(LNK_SymbolTable *symtab, LNK_Symbol *symbol);
|
||||
internal void lnk_symbol_table_remove(LNK_SymbolTable *symtab, LNK_SymbolScopeIndex scope, String8 name);
|
||||
internal void lnk_symbol_table_replace(LNK_SymbolTable *symtab, LNK_SymbolScopeIndex iscope, LNK_Symbol *symbol);
|
||||
|
||||
internal LNK_Symbol * lnk_resolve_symbol(LNK_SymbolTable *symtab, LNK_Symbol *resolve_symbol);
|
||||
|
||||
internal LNK_SymbolList lnk_pop_comdat_chain(LNK_SymbolList *bucket, LNK_SymbolNode **cursor);
|
||||
internal LNK_SymbolNode * lnk_fold_comdat_chain(LNK_SymbolList chain_list);
|
||||
internal void lnk_fold_comdat_chunks(TP_Context *tp, LNK_SymbolTable *symtab);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user