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:
Nikita Smith
2024-10-30 15:43:53 -07:00
parent ee65ea3692
commit 4a2e1dd8d0
14 changed files with 877 additions and 1049 deletions
+253 -282
View File
@@ -258,6 +258,7 @@ lnk_make_linker_manifest(Arena *arena,
"<assembly xmlns=\"urn:schemas-microsoft-com:asm.v1\"\n" "<assembly xmlns=\"urn:schemas-microsoft-com:asm.v1\"\n"
" manifestVersion=\"1.0\">\n")); " manifestVersion=\"1.0\">\n"));
if (manifest_uac) { if (manifest_uac) {
#if 1
String8 uac = push_str8f(scratch.arena, String8 uac = push_str8f(scratch.arena,
" <trustInfo>\n" " <trustInfo>\n"
" <security>\n" " <security>\n"
@@ -268,6 +269,17 @@ lnk_make_linker_manifest(Arena *arena,
" </trustInfo>\n", " </trustInfo>\n",
manifest_level, manifest_level,
manifest_ui_access); manifest_ui_access);
#else
String8 uac = push_str8f(scratch.arena,
"<ms_asmv2:trustInfo xmlns:ms_asmv2="urn:schemas-microsoft-com:asm.v2" xmlns="urn:schemas-microsoft-com:asm.v3">\n"
"<ms_asmv2:security>"
"<ms_asmv2:requestedPrivileges>"
"<ms_asmv2:requestedExecutionLevel level=%S uiAccess=%S>"
"</ms_asmv2:requestedExecutionLevel>"
"</ms_asmv2:requestedPrivileges>"
"</ms_asmv2:security>"
"</ms_asmv2:trustInfo>", manifest_level, manifest_ui_access);
#endif
str8_serial_push_string(scratch.arena, &srl, uac); str8_serial_push_string(scratch.arena, &srl, uac);
} }
for (String8Node *node = manifest_dependency_list.first; node != 0; node = node->next) { for (String8Node *node = manifest_dependency_list.first; node != 0; node = node->next) {
@@ -448,8 +460,8 @@ lnk_serialize_pe_resource_tree(LNK_SectionTable *st, LNK_SymbolTable *symtab, PE
PE_Resource *res = &stack->res_arr[stack->arr_idx].v[stack->res_idx[stack->arr_idx]]; PE_Resource *res = &stack->res_arr[stack->arr_idx].v[stack->res_idx[stack->arr_idx]];
++stack->res_idx[stack->arr_idx]; ++stack->res_idx[stack->arr_idx];
String8 flag_name = push_str8f(symtab->arena, "flag_%u", total_res_count); String8 flag_name = push_str8f(symtab->arena->v[0], "flag_%u", total_res_count);
String8 offset_name = push_str8f(symtab->arena, "offset_%u", total_res_count); String8 offset_name = push_str8f(symtab->arena->v[0], "offset_%u", total_res_count);
++total_res_count; ++total_res_count;
if (stack->coff_entry_array_chunk) { if (stack->coff_entry_array_chunk) {
@@ -471,7 +483,7 @@ lnk_serialize_pe_resource_tree(LNK_SectionTable *st, LNK_SymbolTable *symtab, PE
// make chunk and symbol // make chunk and symbol
String8 res_name = coff_resource_string_from_str8(dir_sect->arena, res->id.u.string); String8 res_name = coff_resource_string_from_str8(dir_sect->arena, res->id.u.string);
LNK_Chunk *name_chunk = lnk_section_push_chunk_data(dir_sect, dir_string_chunk, res_name, str8_zero()); LNK_Chunk *name_chunk = lnk_section_push_chunk_data(dir_sect, dir_string_chunk, res_name, str8_zero());
LNK_Symbol *name_symbol = lnk_make_defined_symbol_chunk(symtab->arena, str8_lit("COFF_RESOURCE_ID_STRING"), LNK_DefinedSymbolVisibility_Static, 0, name_chunk, 0, 0, 0); LNK_Symbol *name_symbol = lnk_make_defined_symbol_chunk(symtab->arena->v[0], str8_lit("COFF_RESOURCE_ID_STRING"), LNK_DefinedSymbolVisibility_Static, 0, name_chunk, 0, 0, 0);
// patch COFF_ResourceDirEntry.name.offset // patch COFF_ResourceDirEntry.name.offset
lnk_section_push_reloc(dir_sect, stack->coff_entry_chunk, LNK_Reloc_SECT_REL, OffsetOf(COFF_ResourceDirEntry, name.offset), name_symbol); lnk_section_push_reloc(dir_sect, stack->coff_entry_chunk, LNK_Reloc_SECT_REL, OffsetOf(COFF_ResourceDirEntry, name.offset), name_symbol);
@@ -503,8 +515,8 @@ lnk_serialize_pe_resource_tree(LNK_SectionTable *st, LNK_SymbolTable *symtab, PE
lnk_chunk_set_debugf(dir_sect->arena, entry_array_chunk, "DIR_ENTRY_ARRAY_CHUNK"); lnk_chunk_set_debugf(dir_sect->arena, entry_array_chunk, "DIR_ENTRY_ARRAY_CHUNK");
// push symbols to patch coff entry // push symbols to patch coff entry
LNK_Symbol *flag_symbol = lnk_make_defined_symbol_va(symtab->arena, flag_name, LNK_DefinedSymbolVisibility_Internal, 0, COFF_RESOURCE_SUB_DIR_FLAG); LNK_Symbol *flag_symbol = lnk_make_defined_symbol_va(symtab->arena->v[0], flag_name, LNK_DefinedSymbolVisibility_Internal, 0, COFF_RESOURCE_SUB_DIR_FLAG);
LNK_Symbol *offset_symbol = lnk_make_defined_symbol_chunk(symtab->arena, offset_name, LNK_DefinedSymbolVisibility_Internal, 0, dir_header_chunk, 0, 0, 0); LNK_Symbol *offset_symbol = lnk_make_defined_symbol_chunk(symtab->arena->v[0], offset_name, LNK_DefinedSymbolVisibility_Internal, 0, dir_header_chunk, 0, 0, 0);
lnk_symbol_table_push(symtab, flag_symbol); // set high bit to indicate directory lnk_symbol_table_push(symtab, flag_symbol); // set high bit to indicate directory
lnk_symbol_table_push(symtab, offset_symbol); // write offset for this directory lnk_symbol_table_push(symtab, offset_symbol); // write offset for this directory
@@ -543,12 +555,12 @@ lnk_serialize_pe_resource_tree(LNK_SectionTable *st, LNK_SymbolTable *symtab, PE
resource_data_chunk->align = COFF_RES_ALIGN; resource_data_chunk->align = COFF_RES_ALIGN;
// relocate data // relocate data
String8 resource_data_symbol_name = push_str8f(symtab->arena, "$R%06X", total_res_count); String8 resource_data_symbol_name = push_str8f(symtab->arena->v[0], "$R%06X", total_res_count);
LNK_Symbol *resource_data_symbol = lnk_make_defined_symbol_chunk(symtab->arena, resource_data_symbol_name, LNK_DefinedSymbolVisibility_Static, 0, resource_data_chunk, 0, 0, 0); LNK_Symbol *resource_data_symbol = lnk_make_defined_symbol_chunk(symtab->arena->v[0], resource_data_symbol_name, LNK_DefinedSymbolVisibility_Static, 0, resource_data_chunk, 0, 0, 0);
lnk_section_push_reloc(dir_sect, coff_resource_data_entry_chunk, LNK_Reloc_VIRT_OFF_32, OffsetOf(COFF_ResourceDataEntry, data_voff), resource_data_symbol); lnk_section_push_reloc(dir_sect, coff_resource_data_entry_chunk, LNK_Reloc_VIRT_OFF_32, OffsetOf(COFF_ResourceDataEntry, data_voff), resource_data_symbol);
// push symbol for data offset relocation // push symbol for data offset relocation
LNK_Symbol *coff_data_offset_symbol = lnk_make_defined_symbol_chunk(symtab->arena, offset_name, LNK_DefinedSymbolVisibility_Internal, 0, coff_resource_data_entry_chunk, 0, 0, 0); LNK_Symbol *coff_data_offset_symbol = lnk_make_defined_symbol_chunk(symtab->arena->v[0], offset_name, LNK_DefinedSymbolVisibility_Internal, 0, coff_resource_data_entry_chunk, 0, 0, 0);
lnk_symbol_table_push(symtab, coff_data_offset_symbol); lnk_symbol_table_push(symtab, coff_data_offset_symbol);
Assert(stack->coff_entry_chunk); Assert(stack->coff_entry_chunk);
@@ -692,7 +704,12 @@ lnk_make_res_obj(TP_Context *tp,
static const U64 sect_virt_align = 1; static const U64 sect_virt_align = 1;
static const U64 sect_file_align = 1; static const U64 sect_file_align = 1;
LNK_SymbolTable *symtab = lnk_symbol_table_alloc(); TP_Arena *temp_tp_arena = push_array(scratch.arena, TP_Arena, 1);
temp_tp_arena->v = push_array(scratch.arena, Arena *, 1);
temp_tp_arena->count = 1;
temp_tp_arena->v[0] = arena_alloc();
LNK_SymbolTable *symtab = lnk_symbol_table_init(temp_tp_arena);
LNK_SectionTable *st = lnk_section_table_alloc(0, sect_virt_align, sect_file_align); LNK_SectionTable *st = lnk_section_table_alloc(0, sect_virt_align, sect_file_align);
LNK_Section *header_sect = lnk_section_table_push(st, str8_lit(".null"), 0); LNK_Section *header_sect = lnk_section_table_push(st, str8_lit(".null"), 0);
@@ -703,9 +720,8 @@ lnk_make_res_obj(TP_Context *tp,
// register section symbols (after this point don't push new sections) // register section symbols (after this point don't push new sections)
for (LNK_SectionNode *sect_node = st->list.first; sect_node != 0; sect_node = sect_node->next) { for (LNK_SectionNode *sect_node = st->list.first; sect_node != 0; sect_node = sect_node->next) {
LNK_Section *sect = &sect_node->data; LNK_Section *sect = &sect_node->data;
LNK_Symbol *sect_symbol = lnk_make_defined_symbol_chunk(symtab->arena, sect->name, LNK_DefinedSymbolVisibility_Internal, 0, sect->root, 0, 0, 0); lnk_symbol_table_push_defined_chunk(symtab, sect->name, LNK_DefinedSymbolVisibility_Internal, 0, sect->root, 0, 0, 0);
lnk_symbol_table_push(symtab, sect_symbol);
} }
st->null_sect = lnk_section_list_remove(&st->list, str8_lit(".null")); st->null_sect = lnk_section_list_remove(&st->list, str8_lit(".null"));
lnk_section_table_build_data(tp, st, machine); lnk_section_table_build_data(tp, st, machine);
@@ -826,10 +842,10 @@ lnk_make_res_obj(TP_Context *tp,
} }
// emit symbols for coff section header patch // emit symbols for coff section header patch
String8 coff_reloc_symbol_name = push_str8f(symtab->arena, "%S.coff_reloc[]", sect->name); String8 coff_reloc_symbol_name = push_str8f(symtab->arena->v[0], "%S.coff_reloc[]", sect->name);
String8 coff_reloc_count_symbol_name = push_str8f(symtab->arena, "%S.coff_reloc[].count", sect->name); String8 coff_reloc_count_symbol_name = push_str8f(symtab->arena->v[0], "%S.coff_reloc[].count", sect->name);
LNK_Symbol *coff_reloc_symbol = lnk_make_defined_symbol_chunk(symtab->arena, coff_reloc_symbol_name, LNK_DefinedSymbolVisibility_Internal, 0, reloc_array_chunk, 0, 0, 0); LNK_Symbol *coff_reloc_symbol = lnk_make_defined_symbol_chunk(symtab->arena->v[0], coff_reloc_symbol_name, LNK_DefinedSymbolVisibility_Internal, 0, reloc_array_chunk, 0, 0, 0);
LNK_Symbol *coff_reloc_count_symbol = lnk_make_defined_symbol_va(symtab->arena, coff_reloc_count_symbol_name, LNK_DefinedSymbolVisibility_Internal, 0, coff_reloc_list.count); LNK_Symbol *coff_reloc_count_symbol = lnk_make_defined_symbol_va(symtab->arena->v[0], coff_reloc_count_symbol_name, LNK_DefinedSymbolVisibility_Internal, 0, coff_reloc_list.count);
lnk_symbol_table_push(symtab, coff_reloc_symbol); lnk_symbol_table_push(symtab, coff_reloc_symbol);
lnk_symbol_table_push(symtab, coff_reloc_count_symbol); lnk_symbol_table_push(symtab, coff_reloc_count_symbol);
} }
@@ -846,10 +862,10 @@ lnk_make_res_obj(TP_Context *tp,
} }
String8 coff_symbol_table_data = str8_serial_end(scratch.arena, &srl); String8 coff_symbol_table_data = str8_serial_end(scratch.arena, &srl);
LNK_Chunk *coff_symbol_table_chunk = lnk_section_push_chunk_data(misc_sect, misc_sect->root, coff_symbol_table_data, str8_zero()); LNK_Chunk *coff_symbol_table_chunk = lnk_section_push_chunk_data(misc_sect, misc_sect->root, coff_symbol_table_data, str8_zero());
LNK_Symbol *coff_symbol_table_symbol = lnk_make_defined_symbol_chunk(symtab->arena, str8_lit("COFF_SYMBOL_TABLE"), LNK_DefinedSymbolVisibility_Internal, 0, coff_symbol_table_chunk, 0, 0, 0); LNK_Symbol *coff_symbol_table_symbol = lnk_make_defined_symbol_chunk(symtab->arena->v[0], str8_lit("COFF_SYMBOL_TABLE"), LNK_DefinedSymbolVisibility_Internal, 0, coff_symbol_table_chunk, 0, 0, 0);
lnk_symbol_table_push(symtab, coff_symbol_table_symbol); lnk_symbol_table_push(symtab, coff_symbol_table_symbol);
LNK_Symbol *coff_symbol_count_symbol = lnk_make_defined_symbol_va(symtab->arena, str8_lit("COFF_SYMBOL_COUNT"), LNK_DefinedSymbolVisibility_Internal, 0, coff_symbol_list.count); LNK_Symbol *coff_symbol_count_symbol = lnk_make_defined_symbol_va(symtab->arena->v[0], str8_lit("COFF_SYMBOL_COUNT"), LNK_DefinedSymbolVisibility_Internal, 0, coff_symbol_list.count);
lnk_symbol_table_push(symtab, coff_symbol_count_symbol); lnk_symbol_table_push(symtab, coff_symbol_count_symbol);
// build obj header // build obj header
@@ -874,7 +890,7 @@ lnk_make_res_obj(TP_Context *tp,
lnk_section_push_reloc(header_sect, coff_header_chunk, LNK_Reloc_ADDR_32, OffsetOf(COFF_Header, symbol_count), coff_symbol_count_symbol); lnk_section_push_reloc(header_sect, coff_header_chunk, LNK_Reloc_ADDR_32, OffsetOf(COFF_Header, symbol_count), coff_symbol_count_symbol);
// push coff header symbol // push coff header symbol
LNK_Symbol *coff_header_symbol = lnk_make_defined_symbol_chunk(symtab->arena, str8_lit(LNK_COFF_HEADER_SYMBOL_NAME), LNK_DefinedSymbolVisibility_Internal, 0, coff_header_chunk, 0, 0, 0); LNK_Symbol *coff_header_symbol = lnk_make_defined_symbol_chunk(symtab->arena->v[0], str8_lit(LNK_COFF_HEADER_SYMBOL_NAME), LNK_DefinedSymbolVisibility_Internal, 0, coff_header_chunk, 0, 0, 0);
lnk_symbol_table_push(symtab, coff_header_symbol); lnk_symbol_table_push(symtab, coff_header_symbol);
} }
@@ -882,7 +898,7 @@ lnk_make_res_obj(TP_Context *tp,
{ {
LNK_Chunk *coff_section_header_array_chunk = lnk_section_push_chunk_list(header_sect, header_sect->root, str8_zero()); LNK_Chunk *coff_section_header_array_chunk = lnk_section_push_chunk_list(header_sect, header_sect->root, str8_zero());
for (LNK_SectionNode *sect_node = st->list.first; sect_node != 0; sect_node = sect_node->next) { for (LNK_SectionNode *sect_node = st->list.first; sect_node != 0; sect_node = sect_node->next) {
if (sect_node == st->null_sect) continue; if (sect_node == st->null_sect) continue;
if (!sect_node->data.emit_header) continue; if (!sect_node->data.emit_header) continue;
LNK_Section *sect = &sect_node->data; LNK_Section *sect = &sect_node->data;
@@ -924,7 +940,7 @@ lnk_make_res_obj(TP_Context *tp,
// push section header count symbol // push section header count symbol
U64 symbol_count = coff_section_header_array_chunk->u.list->count; U64 symbol_count = coff_section_header_array_chunk->u.list->count;
LNK_Symbol *coff_section_header_count_symbol = lnk_make_defined_symbol_va(symtab->arena, str8_lit(LNK_COFF_SECT_HEADER_COUNT_SYMBOL_NAME), LNK_DefinedSymbolVisibility_Internal, 0, symbol_count); LNK_Symbol *coff_section_header_count_symbol = lnk_make_defined_symbol_va(symtab->arena->v[0], str8_lit(LNK_COFF_SECT_HEADER_COUNT_SYMBOL_NAME), LNK_DefinedSymbolVisibility_Internal, 0, symbol_count);
lnk_symbol_table_push(symtab, coff_section_header_count_symbol); lnk_symbol_table_push(symtab, coff_section_header_count_symbol);
} }
@@ -936,8 +952,8 @@ lnk_make_res_obj(TP_Context *tp,
String8 res_obj = lnk_section_table_serialize(arena, st); String8 res_obj = lnk_section_table_serialize(arena, st);
lnk_section_table_release(&st); lnk_section_table_release(&st);
lnk_symbol_table_release(&symtab);
arena_release(temp_tp_arena->v[0]);
scratch_end(scratch); scratch_end(scratch);
ProfEnd(); ProfEnd();
return res_obj; return res_obj;
@@ -1013,8 +1029,12 @@ lnk_make_linker_coff_obj(TP_Context *tp,
{ {
Temp scratch = scratch_begin(&arena, 1); Temp scratch = scratch_begin(&arena, 1);
LNK_SymbolTable *symtab = lnk_symbol_table_alloc(); TP_Arena *temp_tp_arena = push_array(scratch.arena, TP_Arena, 1);
LNK_SectionTable *st = lnk_section_table_alloc(0, 1, 1); temp_tp_arena->v = &scratch.arena;
temp_tp_arena->count = 1;
LNK_SymbolTable *symtab = lnk_symbol_table_init(temp_tp_arena);
LNK_SectionTable *st = lnk_section_table_alloc(0, 1, 1);
LNK_Section *header_sect = lnk_section_table_push(st, str8_lit(".coffhdr"), 0); LNK_Section *header_sect = lnk_section_table_push(st, str8_lit(".coffhdr"), 0);
LNK_Section *debug_s_sect = lnk_section_table_push(st, str8_lit(".debug$S"), LNK_DEBUG_SECTION_FLAGS); LNK_Section *debug_s_sect = lnk_section_table_push(st, str8_lit(".debug$S"), LNK_DEBUG_SECTION_FLAGS);
@@ -1023,10 +1043,10 @@ lnk_make_linker_coff_obj(TP_Context *tp,
header_sect->emit_header = 0; header_sect->emit_header = 0;
{ {
COFF_Header *coff_header = push_array(header_sect->arena, COFF_Header, 1); COFF_Header *coff_header = push_array(header_sect->arena, COFF_Header, 1);
coff_header->machine = machine; coff_header->machine = machine;
coff_header->section_count = 0; coff_header->section_count = 0;
coff_header->time_stamp = time_stamp; coff_header->time_stamp = time_stamp;
LNK_Chunk *coff_header_chunk = lnk_section_push_chunk_raw(header_sect, header_sect->root, coff_header, sizeof(*coff_header), str8_zero()); LNK_Chunk *coff_header_chunk = lnk_section_push_chunk_raw(header_sect, header_sect->root, coff_header, sizeof(*coff_header), str8_zero());
lnk_section_push_reloc_undefined(header_sect, coff_header_chunk, LNK_Reloc_ADDR_32, OffsetOf(COFF_Header, section_count), str8_lit(LNK_COFF_SECT_HEADER_COUNT_SYMBOL_NAME), LNK_SymbolScopeFlag_Internal); lnk_section_push_reloc_undefined(header_sect, coff_header_chunk, LNK_Reloc_ADDR_32, OffsetOf(COFF_Header, section_count), str8_lit(LNK_COFF_SECT_HEADER_COUNT_SYMBOL_NAME), LNK_SymbolScopeFlag_Internal);
@@ -1045,13 +1065,13 @@ lnk_make_linker_coff_obj(TP_Context *tp,
U64 ver_fe_major = 0; U64 ver_fe_major = 0;
U64 ver_fe_minor = 0; U64 ver_fe_minor = 0;
U64 ver_fe_build = 0; U64 ver_fe_build = 0;
U64 ver_feqfe = 0; U64 ver_feqfe = 0;
U64 ver_major = 14; U64 ver_major = 14;
U64 ver_minor = 36; U64 ver_minor = 36;
U64 ver_build = 32537; U64 ver_build = 32537;
U64 ver_qfe = 0; U64 ver_qfe = 0;
String8 version_string = push_str8f(scratch.arena, "Epic Games Tools (R) RAD Linker"); String8 version_string = push_str8f(scratch.arena, "Epic Games Tools (R) RAD Linker");
String8 comp3_data = cv_make_comp3(scratch.arena, 0, CV_Language_LINK, cv_arch, ver_fe_major, ver_fe_minor, ver_fe_build, ver_feqfe, ver_major, ver_minor, ver_build, ver_qfe, version_string); String8 comp3_data = cv_make_comp3(scratch.arena, 0, CV_Language_LINK, cv_arch, ver_fe_major, ver_fe_minor, ver_fe_build, ver_feqfe, ver_major, ver_minor, ver_build, ver_qfe, version_string);
cv_symbol_list_push_data(scratch.arena, &symbol_list, CV_SymKind_COMPILE3, comp3_data); cv_symbol_list_push_data(scratch.arena, &symbol_list, CV_SymKind_COMPILE3, comp3_data);
// S_ENVBLOCK // S_ENVBLOCK
@@ -1091,13 +1111,12 @@ lnk_make_linker_coff_obj(TP_Context *tp,
// register section symbols (after this point don't push new sections) // register section symbols (after this point don't push new sections)
for (LNK_SectionNode *sect_node = st->list.first; sect_node != NULL; sect_node = sect_node->next) { for (LNK_SectionNode *sect_node = st->list.first; sect_node != NULL; sect_node = sect_node->next) {
LNK_Section *sect = &sect_node->data; LNK_Section *sect = &sect_node->data;
LNK_Symbol *sect_symbol = lnk_make_defined_symbol_chunk(symtab->arena, sect->name, LNK_DefinedSymbolVisibility_Internal, 0, sect->root, 0, 0, 0); lnk_symbol_table_push_defined_chunk(symtab, sect->name, LNK_DefinedSymbolVisibility_Internal, 0, sect->root, 0, 0, 0);
lnk_symbol_table_push(symtab, sect_symbol);
} }
LNK_Chunk *coff_section_header_array_chunk = lnk_section_push_chunk_list(header_sect, header_sect->root, str8_zero()); LNK_Chunk *coff_section_header_array_chunk = lnk_section_push_chunk_list(header_sect, header_sect->root, str8_zero());
for (LNK_SectionNode *sect_node = st->list.first; sect_node != NULL; sect_node = sect_node->next) { for (LNK_SectionNode *sect_node = st->list.first; sect_node != NULL; sect_node = sect_node->next) {
if (sect_node == st->null_sect) continue; if (sect_node == st->null_sect) continue;
if (!sect_node->data.emit_header) continue; if (!sect_node->data.emit_header) continue;
LNK_Section *sect = &sect_node->data; LNK_Section *sect = &sect_node->data;
@@ -1138,7 +1157,7 @@ lnk_make_linker_coff_obj(TP_Context *tp,
// push section header count symbol // push section header count symbol
U64 symbol_count = coff_section_header_array_chunk->u.list->count; U64 symbol_count = coff_section_header_array_chunk->u.list->count;
LNK_Symbol *coff_section_header_count_symbol = lnk_make_defined_symbol_va(symtab->arena, str8_lit(LNK_COFF_SECT_HEADER_COUNT_SYMBOL_NAME), LNK_DefinedSymbolVisibility_Internal, 0, symbol_count); LNK_Symbol *coff_section_header_count_symbol = lnk_make_defined_symbol_va(symtab->arena->v[0], str8_lit(LNK_COFF_SECT_HEADER_COUNT_SYMBOL_NAME), LNK_DefinedSymbolVisibility_Internal, 0, symbol_count);
lnk_symbol_table_push(symtab, coff_section_header_count_symbol); lnk_symbol_table_push(symtab, coff_section_header_count_symbol);
} }
@@ -1228,21 +1247,6 @@ lnk_push_loaded_lib(Arena *arena,
} }
} }
internal
THREAD_POOL_TASK_FUNC(lnk_lazy_initer)
{
LNK_LazyIniter *task = raw_task;
Rng1U64 range = task->range_arr[task_id];
for (U64 lib_idx = range.min; lib_idx < range.max; lib_idx += 1) {
LNK_Lib *lib = &task->lib_arr[lib_idx].data;
String8Node *name_node = lib->symbol_name_list.first;
for (U64 symbol_idx = 0; symbol_idx < lib->symbol_count; symbol_idx += 1, name_node = name_node->next) {
LNK_Symbol *symbol = &task->symbol_arr_arr[lib_idx][symbol_idx];
lnk_init_lazy_symbol(symbol, name_node->string, lib, lib->member_off_arr[symbol_idx]);
}
}
}
internal void internal void
lnk_push_input_from_lazy(Arena *arena, PathStyle path_style, LNK_LazySymbol *lazy, LNK_InputImportList *input_import_list, LNK_InputObjList *input_obj_list) lnk_push_input_from_lazy(Arena *arena, PathStyle path_style, LNK_LazySymbol *lazy, LNK_InputImportList *input_import_list, LNK_InputObjList *input_obj_list)
{ {
@@ -1298,40 +1302,26 @@ lnk_push_linker_symbols(LNK_SymbolTable *symtab, COFF_MachineType machine)
// passing it around as a function argument. // passing it around as a function argument.
// //
// 100h: lea rax, [rip + ffffff00h] ; -100h // 100h: lea rax, [rip + ffffff00h] ; -100h
LNK_Symbol *image_base = lnk_make_defined_symbol_chunk(symtab->arena, str8_lit("__ImageBase"), LNK_DefinedSymbolVisibility_Extern, 0, g_null_chunk_ptr, 0, COFF_ComdatSelectType_ANY, 0); LNK_Symbol *image_base = lnk_symbol_table_push_defined_chunk(symtab, str8_lit("__ImageBase"), LNK_DefinedSymbolVisibility_Extern, 0, g_null_chunk_ptr, 0, COFF_ComdatSelectType_ANY, 0);
lnk_symbol_table_push(symtab, image_base);
{ // load config symbols { // load config symbols
if (machine == COFF_MachineType_X86) { if (machine == COFF_MachineType_X86) {
LNK_Symbol *safe_se_handler_table = lnk_make_defined_symbol_chunk(symtab->arena, str8_lit(LNK_SAFE_SE_HANDLER_TABLE_SYMBOL_NAME), LNK_DefinedSymbolVisibility_Extern, 0, g_null_chunk_ptr, 0, COFF_ComdatSelectType_NODUPLICATES, 0); lnk_symbol_table_push_defined_chunk(symtab, str8_lit(LNK_SAFE_SE_HANDLER_TABLE_SYMBOL_NAME), LNK_DefinedSymbolVisibility_Extern, 0, g_null_chunk_ptr, 0, COFF_ComdatSelectType_NODUPLICATES, 0);
LNK_Symbol *safe_se_handler_count = lnk_make_defined_symbol_chunk(symtab->arena, str8_lit(LNK_SAFE_SE_HANDLER_COUNT_SYMBOL_NAME), LNK_DefinedSymbolVisibility_Extern, 0, g_null_chunk_ptr, 0, COFF_ComdatSelectType_NODUPLICATES, 0); lnk_symbol_table_push_defined_chunk(symtab, str8_lit(LNK_SAFE_SE_HANDLER_COUNT_SYMBOL_NAME), LNK_DefinedSymbolVisibility_Extern, 0, g_null_chunk_ptr, 0, COFF_ComdatSelectType_NODUPLICATES, 0);
lnk_symbol_table_push(symtab, safe_se_handler_table);
lnk_symbol_table_push(symtab, safe_se_handler_count);
} }
// TODO: investigate IMAGE_ENCLAVE_CONFIG 32/64 // TODO: investigate IMAGE_ENCLAVE_CONFIG 32/64
LNK_Symbol *enclave_config = lnk_make_defined_symbol_va(symtab->arena, str8_lit(LNK_ENCLAVE_CONFIG_SYMBOL_NAME), LNK_DefinedSymbolVisibility_Extern, 0, 0); lnk_symbol_table_push_defined_va(symtab, str8_lit(LNK_ENCLAVE_CONFIG_SYMBOL_NAME), LNK_DefinedSymbolVisibility_Extern, 0, 0);
LNK_Symbol *guard_flags = lnk_make_defined_symbol(symtab->arena, str8_lit(LNK_GUARD_FLAGS_SYMBOL_NAME) , LNK_DefinedSymbolVisibility_Extern, 0); lnk_symbol_table_push_defined(symtab, str8_lit(LNK_GUARD_FLAGS_SYMBOL_NAME) , LNK_DefinedSymbolVisibility_Extern, 0);
LNK_Symbol *guard_fids_table = lnk_make_defined_symbol(symtab->arena, str8_lit(LNK_GUARD_FIDS_TABLE_SYMBOL_NAME) , LNK_DefinedSymbolVisibility_Extern, 0); lnk_symbol_table_push_defined(symtab, str8_lit(LNK_GUARD_FIDS_TABLE_SYMBOL_NAME) , LNK_DefinedSymbolVisibility_Extern, 0);
LNK_Symbol *guard_fids_count = lnk_make_defined_symbol(symtab->arena, str8_lit(LNK_GUARD_FIDS_COUNT_SYMBOL_NAME) , LNK_DefinedSymbolVisibility_Extern, 0); lnk_symbol_table_push_defined(symtab, str8_lit(LNK_GUARD_FIDS_COUNT_SYMBOL_NAME) , LNK_DefinedSymbolVisibility_Extern, 0);
LNK_Symbol *guard_iat_table = lnk_make_defined_symbol(symtab->arena, str8_lit(LNK_GUARD_IAT_TABLE_SYMBOL_NAME) , LNK_DefinedSymbolVisibility_Extern, 0); lnk_symbol_table_push_defined(symtab, str8_lit(LNK_GUARD_IAT_TABLE_SYMBOL_NAME) , LNK_DefinedSymbolVisibility_Extern, 0);
LNK_Symbol *guard_iat_count = lnk_make_defined_symbol(symtab->arena, str8_lit(LNK_GUARD_IAT_COUNT_SYMBOL_NAME) , LNK_DefinedSymbolVisibility_Extern, 0); lnk_symbol_table_push_defined(symtab, str8_lit(LNK_GUARD_IAT_COUNT_SYMBOL_NAME) , LNK_DefinedSymbolVisibility_Extern, 0);
LNK_Symbol *guard_longjmp_table = lnk_make_defined_symbol(symtab->arena, str8_lit(LNK_GUARD_LONGJMP_TABLE_SYMBOL_NAME), LNK_DefinedSymbolVisibility_Extern, 0); lnk_symbol_table_push_defined(symtab, str8_lit(LNK_GUARD_LONGJMP_TABLE_SYMBOL_NAME), LNK_DefinedSymbolVisibility_Extern, 0);
LNK_Symbol *guard_longjmp_count = lnk_make_defined_symbol(symtab->arena, str8_lit(LNK_GUARD_LONGJMP_COUNT_SYMBOL_NAME), LNK_DefinedSymbolVisibility_Extern, 0); lnk_symbol_table_push_defined(symtab, str8_lit(LNK_GUARD_LONGJMP_COUNT_SYMBOL_NAME), LNK_DefinedSymbolVisibility_Extern, 0);
LNK_Symbol *guard_ehcont_table = lnk_make_defined_symbol(symtab->arena, str8_lit(LNK_GUARD_EHCONT_TABLE_SYMBOL_NAME) , LNK_DefinedSymbolVisibility_Extern, 0); lnk_symbol_table_push_defined(symtab, str8_lit(LNK_GUARD_EHCONT_TABLE_SYMBOL_NAME) , LNK_DefinedSymbolVisibility_Extern, 0);
LNK_Symbol *guard_ehcont_count = lnk_make_defined_symbol(symtab->arena, str8_lit(LNK_GUARD_EHCONT_COUNT_SYMBOL_NAME) , LNK_DefinedSymbolVisibility_Extern, 0); lnk_symbol_table_push_defined(symtab, str8_lit(LNK_GUARD_EHCONT_COUNT_SYMBOL_NAME) , LNK_DefinedSymbolVisibility_Extern, 0);
lnk_symbol_table_push(symtab, enclave_config);
lnk_symbol_table_push(symtab, guard_flags);
lnk_symbol_table_push(symtab, guard_fids_table);
lnk_symbol_table_push(symtab, guard_fids_count);
lnk_symbol_table_push(symtab, guard_iat_table);
lnk_symbol_table_push(symtab, guard_iat_count);
lnk_symbol_table_push(symtab, guard_longjmp_table);
lnk_symbol_table_push(symtab, guard_longjmp_count);
lnk_symbol_table_push(symtab, guard_ehcont_table);
lnk_symbol_table_push(symtab, guard_ehcont_count);
} }
} }
@@ -1422,11 +1412,8 @@ lnk_build_debug_pdb(LNK_SectionTable *st,
lnk_chunk_set_debugf(sect->arena, debug_pdb_chunk, LNK_CV_HEADER_PDB70_SYMBOL_NAME); lnk_chunk_set_debugf(sect->arena, debug_pdb_chunk, LNK_CV_HEADER_PDB70_SYMBOL_NAME);
// push symbols // push symbols
LNK_Symbol *debug_pdb_symbol = lnk_make_defined_symbol_chunk(symtab->arena, str8_lit(LNK_CV_HEADER_PDB70_SYMBOL_NAME), LNK_DefinedSymbolVisibility_Internal, 0, debug_pdb_chunk, 0, 0, 0); LNK_Symbol *debug_pdb_symbol = lnk_symbol_table_push_defined_chunk(symtab, str8_lit(LNK_CV_HEADER_PDB70_SYMBOL_NAME), LNK_DefinedSymbolVisibility_Internal, 0, debug_pdb_chunk, 0, 0, 0);
lnk_symbol_table_push(symtab, debug_pdb_symbol); LNK_Symbol *guid_symbol = lnk_symbol_table_push_defined_chunk(symtab, str8_lit(LNK_CV_HEADER_GUID_SYMBOL_NAME), LNK_DefinedSymbolVisibility_Internal, 0, debug_pdb_chunk, OffsetOf(PE_CvHeaderPDB70, guid), 0, 0);
LNK_Symbol *guid_symbol = lnk_make_defined_symbol_chunk(symtab->arena, str8_lit(LNK_CV_HEADER_GUID_SYMBOL_NAME), LNK_DefinedSymbolVisibility_Internal, 0, debug_pdb_chunk, OffsetOf(PE_CvHeaderPDB70, guid), 0, 0);
lnk_symbol_table_push(symtab, guid_symbol);
// push debug directory // push debug directory
lnk_push_pe_debug_data_directory(sect, dir_array_chunk, debug_pdb_symbol, PE_DebugDirectoryType_CODEVIEW, time_stamp); lnk_push_pe_debug_data_directory(sect, dir_array_chunk, debug_pdb_symbol, PE_DebugDirectoryType_CODEVIEW, time_stamp);
@@ -1452,11 +1439,8 @@ lnk_build_debug_rdi(LNK_SectionTable *st,
LNK_Chunk *debug_rdi_chunk = lnk_section_push_chunk_data(rdi_sect, rdi_sect->root, debug_rdi, str8_zero()); lnk_chunk_set_debugf(rdi_sect->arena, debug_rdi, LNK_CV_HEADER_RDI_SYMBOL_NAME); LNK_Chunk *debug_rdi_chunk = lnk_section_push_chunk_data(rdi_sect, rdi_sect->root, debug_rdi, str8_zero()); lnk_chunk_set_debugf(rdi_sect->arena, debug_rdi, LNK_CV_HEADER_RDI_SYMBOL_NAME);
// push symbols // push symbols
LNK_Symbol *debug_rdi_symbol = lnk_make_defined_symbol_chunk(symtab->arena, str8_lit(LNK_CV_HEADER_RDI_SYMBOL_NAME), LNK_DefinedSymbolVisibility_Internal, 0, debug_rdi_chunk, 0, 0, 0); LNK_Symbol *debug_rdi_symbol = lnk_symbol_table_push_defined_chunk(symtab, str8_lit(LNK_CV_HEADER_RDI_SYMBOL_NAME), LNK_DefinedSymbolVisibility_Internal, 0, debug_rdi_chunk, 0, 0, 0);
lnk_symbol_table_push(symtab, debug_rdi_symbol); LNK_Symbol *guid_symbol = lnk_symbol_table_push_defined_chunk(symtab, str8_lit(LNK_CV_HEADER_GUID_SYMBOL_NAME), LNK_DefinedSymbolVisibility_Internal, 0, debug_rdi_chunk, OffsetOf(PE_CvHeaderRDI, guid), 0, 0);
LNK_Symbol *guid_symbol = lnk_make_defined_symbol_chunk(symtab->arena, str8_lit(LNK_CV_HEADER_GUID_SYMBOL_NAME), LNK_DefinedSymbolVisibility_Internal, 0, debug_rdi_chunk, OffsetOf(PE_CvHeaderRDI, guid), 0, 0);
lnk_symbol_table_push(symtab, guid_symbol);
// push debug directory // push debug directory
lnk_push_pe_debug_data_directory(debug_sect, debug_dir_array_chunk, debug_rdi_symbol, PE_DebugDirectoryType_CODEVIEW, time_stamp); lnk_push_pe_debug_data_directory(debug_sect, debug_dir_array_chunk, debug_rdi_symbol, PE_DebugDirectoryType_CODEVIEW, time_stamp);
@@ -1566,6 +1550,8 @@ lnk_build_guard_tables(TP_Context *tp,
// TODO: push noname exports // TODO: push noname exports
NotImplemented;
#if 0
// push thunks // push thunks
LNK_SymbolScopeIndex scope_array[] = { LNK_SymbolScopeIndex_Defined, LNK_SymbolScopeIndex_Internal }; LNK_SymbolScopeIndex scope_array[] = { LNK_SymbolScopeIndex_Defined, LNK_SymbolScopeIndex_Internal };
for (U64 iscope = 0; iscope < ArrayCount(scope_array); ++iscope) { for (U64 iscope = 0; iscope < ArrayCount(scope_array); ++iscope) {
@@ -1582,6 +1568,7 @@ lnk_build_guard_tables(TP_Context *tp,
} }
} }
} }
#endif
// build section data // build section data
lnk_section_table_build_data(tp, st, machine); lnk_section_table_build_data(tp, st, machine);
@@ -1628,8 +1615,7 @@ lnk_build_guard_tables(TP_Context *tp,
}; };
for (U64 i = 0; i < ArrayCount(sect_layout); ++i) { for (U64 i = 0; i < ArrayCount(sect_layout); ++i) {
LNK_Section *sect = lnk_section_table_push(st, str8_cstring(sect_layout[i].name), sect_layout[i].flags); LNK_Section *sect = lnk_section_table_push(st, str8_cstring(sect_layout[i].name), sect_layout[i].flags);
LNK_Symbol *symbol = lnk_make_defined_symbol_chunk(symtab->arena, str8_cstring(sect_layout[i].symbol), LNK_DefinedSymbolVisibility_Internal, 0, sect->root, 0, 0, 0); lnk_symbol_table_push_defined_chunk(symtab, str8_cstring(sect_layout[i].symbol), LNK_DefinedSymbolVisibility_Internal, 0, sect->root, 0, 0, 0);
lnk_symbol_table_push(symtab, symbol);
} }
// TODO: emit table for SEH on X86 // TODO: emit table for SEH on X86
@@ -1769,6 +1755,13 @@ lnk_emit_base_reloc_info(Arena *arena,
U64 reloc_voff = lnk_virt_off_from_reloc(sect_id_map, reloc); U64 reloc_voff = lnk_virt_off_from_reloc(sect_id_map, reloc);
U64 page_voff = AlignDownPow2(reloc_voff, page_size); U64 page_voff = AlignDownPow2(reloc_voff, page_size);
if (str8_match(reloc->symbol->name, str8_lit("_mi_heap_empty"), 0)) {
int x = 0;
}
if (page_voff == 0x21C7000) {
int x = 0;
}
LNK_BaseRelocPageNode *page; LNK_BaseRelocPageNode *page;
{ {
KeyValuePair *is_page_present = hash_table_search_u64(page_ht, page_voff); KeyValuePair *is_page_present = hash_table_search_u64(page_ht, page_voff);
@@ -1945,8 +1938,7 @@ lnk_build_base_relocs(TP_Context *tp,
if (main_page_list->count > 0) { if (main_page_list->count > 0) {
LNK_Section *base_reloc_sect = lnk_section_table_push(st, str8_lit(".reloc"), LNK_RELOC_SECTION_FLAGS); LNK_Section *base_reloc_sect = lnk_section_table_push(st, str8_lit(".reloc"), LNK_RELOC_SECTION_FLAGS);
LNK_Symbol *base_reloc_symbol = lnk_make_defined_symbol_chunk(symtab->arena, str8_lit(LNK_BASE_RELOC_SYMBOL_NAME), LNK_DefinedSymbolVisibility_Internal, 0, base_reloc_sect->root, 0, 0, 0); lnk_symbol_table_push_defined_chunk(symtab, str8_lit(LNK_BASE_RELOC_SYMBOL_NAME), LNK_DefinedSymbolVisibility_Internal, 0, base_reloc_sect->root, 0, 0, 0);
lnk_symbol_table_push(symtab, base_reloc_symbol);
ProfBegin("Page List -> Array"); ProfBegin("Page List -> Array");
LNK_BaseRelocPageArray page_arr = lnk_base_reloc_page_array_from_list(base_reloc_sect->arena, *main_page_list); LNK_BaseRelocPageArray page_arr = lnk_base_reloc_page_array_from_list(base_reloc_sect->arena, *main_page_list);
@@ -2046,10 +2038,8 @@ lnk_build_dos_header(LNK_SymbolTable *symtab, LNK_Section *header_sect, LNK_Chun
lnk_chunk_set_debugf(header_sect->arena, dos_header_chunk, LNK_DOS_HEADER_SYMBOL_NAME); lnk_chunk_set_debugf(header_sect->arena, dos_header_chunk, LNK_DOS_HEADER_SYMBOL_NAME);
lnk_chunk_set_debugf(header_sect->arena, dos_program_chunk, LNK_DOS_PROGRAM_SYMBOL_NAME); lnk_chunk_set_debugf(header_sect->arena, dos_program_chunk, LNK_DOS_PROGRAM_SYMBOL_NAME);
LNK_Symbol *dos_header_symbol = lnk_make_defined_symbol_chunk(symtab->arena, str8_lit(LNK_DOS_HEADER_SYMBOL_NAME), LNK_DefinedSymbolVisibility_Internal, 0, dos_header_chunk, 0, 0, 0); lnk_symbol_table_push_defined_chunk(symtab, str8_lit(LNK_DOS_HEADER_SYMBOL_NAME), LNK_DefinedSymbolVisibility_Internal, 0, dos_header_chunk, 0, 0, 0);
LNK_Symbol *dos_program_symbol = lnk_make_defined_symbol_chunk(symtab->arena, str8_lit(LNK_DOS_PROGRAM_SYMBOL_NAME), LNK_DefinedSymbolVisibility_Internal, 0, dos_program_chunk, 0, 0, 0); lnk_symbol_table_push_defined_chunk(symtab, str8_lit(LNK_DOS_PROGRAM_SYMBOL_NAME), LNK_DefinedSymbolVisibility_Internal, 0, dos_program_chunk, 0, 0, 0);
lnk_symbol_table_push(symtab, dos_header_symbol);
lnk_symbol_table_push(symtab, dos_program_symbol);
// :coff_file_offset // :coff_file_offset
lnk_section_push_reloc_undefined(header_sect, dos_header_chunk, LNK_Reloc_FILE_OFF_32, OffsetOf(PE_DosHeader, coff_file_offset), str8_lit(LNK_NT_HEADERS_SYMBOL_NAME), LNK_SymbolScopeFlag_Internal); lnk_section_push_reloc_undefined(header_sect, dos_header_chunk, LNK_Reloc_FILE_OFF_32, OffsetOf(PE_DosHeader, coff_file_offset), str8_lit(LNK_NT_HEADERS_SYMBOL_NAME), LNK_SymbolScopeFlag_Internal);
@@ -2066,8 +2056,7 @@ lnk_build_pe_magic(LNK_SymbolTable *symtab, LNK_Section *header_sect, LNK_Chunk
LNK_Chunk *pe_magic_chunk = lnk_section_push_chunk_raw(header_sect, parent, pe_magic, sizeof(*pe_magic), str8_zero()); LNK_Chunk *pe_magic_chunk = lnk_section_push_chunk_raw(header_sect, parent, pe_magic, sizeof(*pe_magic), str8_zero());
lnk_chunk_set_debugf(header_sect->arena, pe_magic_chunk, LNK_PE_MAGIC_SYMBOL_NAME); lnk_chunk_set_debugf(header_sect->arena, pe_magic_chunk, LNK_PE_MAGIC_SYMBOL_NAME);
LNK_Symbol *pe_magic_symbol = lnk_make_defined_symbol_chunk(symtab->arena, str8_lit(LNK_PE_MAGIC_SYMBOL_NAME), LNK_DefinedSymbolVisibility_Internal, 0, pe_magic_chunk, 0, 0, 0); lnk_symbol_table_push_defined_chunk(symtab, str8_lit(LNK_PE_MAGIC_SYMBOL_NAME), LNK_DefinedSymbolVisibility_Internal, 0, pe_magic_chunk, 0, 0, 0);
lnk_symbol_table_push(symtab, pe_magic_symbol);
return pe_magic_chunk; return pe_magic_chunk;
} }
@@ -2088,8 +2077,7 @@ lnk_build_coff_file_header(LNK_SymbolTable *symtab, LNK_Section *header_sect, LN
LNK_Chunk *file_header_chunk = lnk_section_push_chunk_raw(header_sect, parent, file_header, sizeof(*file_header), str8_zero()); LNK_Chunk *file_header_chunk = lnk_section_push_chunk_raw(header_sect, parent, file_header, sizeof(*file_header), str8_zero());
lnk_chunk_set_debugf(header_sect->arena, file_header_chunk, LNK_COFF_HEADER_SYMBOL_NAME); lnk_chunk_set_debugf(header_sect->arena, file_header_chunk, LNK_COFF_HEADER_SYMBOL_NAME);
LNK_Symbol *file_header_symbol = lnk_make_defined_symbol_chunk(symtab->arena, str8_lit(LNK_COFF_HEADER_SYMBOL_NAME), LNK_DefinedSymbolVisibility_Internal, 0, file_header_chunk, 0, 0, 0); lnk_symbol_table_push_defined_chunk(symtab, str8_lit(LNK_COFF_HEADER_SYMBOL_NAME), LNK_DefinedSymbolVisibility_Internal, 0, file_header_chunk, 0, 0, 0);
lnk_symbol_table_push(symtab, file_header_symbol);
// :section_count // :section_count
lnk_section_push_reloc_undefined(header_sect, file_header_chunk, LNK_Reloc_ADDR_16, OffsetOf(COFF_Header, section_count), str8_lit(LNK_COFF_SECT_HEADER_COUNT_SYMBOL_NAME), LNK_SymbolScopeFlag_Internal); lnk_section_push_reloc_undefined(header_sect, file_header_chunk, LNK_Reloc_ADDR_16, OffsetOf(COFF_Header, section_count), str8_lit(LNK_COFF_SECT_HEADER_COUNT_SYMBOL_NAME), LNK_SymbolScopeFlag_Internal);
@@ -2158,8 +2146,7 @@ lnk_build_pe_optional_header_x64(LNK_SymbolTable *symtab,
lnk_chunk_set_debugf(header_sect->arena, opt_header_chunk, LNK_PE_OPT_HEADER_SYMBOL_NAME); lnk_chunk_set_debugf(header_sect->arena, opt_header_chunk, LNK_PE_OPT_HEADER_SYMBOL_NAME);
// define optional header symbol // define optional header symbol
LNK_Symbol *opt_header_symbol = lnk_make_defined_symbol_chunk(symtab->arena, str8_lit(LNK_PE_OPT_HEADER_SYMBOL_NAME), LNK_DefinedSymbolVisibility_Internal, 0, opt_header_chunk, 0, 0, 0); lnk_symbol_table_push_defined_chunk(symtab, str8_lit(LNK_PE_OPT_HEADER_SYMBOL_NAME), LNK_DefinedSymbolVisibility_Internal, 0, opt_header_chunk, 0, 0, 0);
lnk_symbol_table_push(symtab, opt_header_symbol);
// :entry_point_va // :entry_point_va
lnk_section_push_reloc_undefined(header_sect, opt_header_chunk, LNK_Reloc_VIRT_OFF_32, OffsetOf(PE_OptionalHeader32Plus, entry_point_va), entry_point_name, LNK_SymbolScopeFlag_Main); lnk_section_push_reloc_undefined(header_sect, opt_header_chunk, LNK_Reloc_VIRT_OFF_32, OffsetOf(PE_OptionalHeader32Plus, entry_point_va), entry_point_name, LNK_SymbolScopeFlag_Main);
@@ -2202,8 +2189,7 @@ lnk_build_pe_optional_header_x64(LNK_SymbolTable *symtab,
lnk_section_push_reloc(header_sect, opt_header_chunk, LNK_Reloc_FILE_ALIGN_32, OffsetOf(PE_OptionalHeader32Plus, sizeof_headers), &g_null_symbol); lnk_section_push_reloc(header_sect, opt_header_chunk, LNK_Reloc_FILE_ALIGN_32, OffsetOf(PE_OptionalHeader32Plus, sizeof_headers), &g_null_symbol);
// :check_sum // :check_sum
LNK_Symbol *checksum_symbol = lnk_make_defined_symbol_chunk(symtab->arena, str8_lit(LNK_PE_CHECKSUM_SYMBOL_NAME), LNK_DefinedSymbolVisibility_Internal, 0, opt_header_chunk, OffsetOf(PE_OptionalHeader32Plus, check_sum), COFF_ComdatSelectType_NODUPLICATES, 0); lnk_symbol_table_push_defined_chunk(symtab, str8_lit(LNK_PE_CHECKSUM_SYMBOL_NAME), LNK_DefinedSymbolVisibility_Internal, 0, opt_header_chunk, OffsetOf(PE_OptionalHeader32Plus, check_sum), COFF_ComdatSelectType_NODUPLICATES, 0);
lnk_symbol_table_push(symtab, checksum_symbol);
// :data_dir_count // :data_dir_count
lnk_section_push_reloc_undefined(header_sect, opt_header_chunk, LNK_Reloc_ADDR_32, OffsetOf(PE_OptionalHeader32Plus, data_dir_count), str8_lit(LNK_PE_DIRECTORY_COUNT_SYMBOL_NAME), LNK_SymbolScopeFlag_Internal); lnk_section_push_reloc_undefined(header_sect, opt_header_chunk, LNK_Reloc_ADDR_32, OffsetOf(PE_OptionalHeader32Plus, data_dir_count), str8_lit(LNK_PE_DIRECTORY_COUNT_SYMBOL_NAME), LNK_SymbolScopeFlag_Internal);
@@ -2215,18 +2201,18 @@ internal LNK_Chunk *
lnk_build_pe_directories(LNK_SymbolTable *symtab, LNK_Section *header_sect, LNK_Chunk *parent) lnk_build_pe_directories(LNK_SymbolTable *symtab, LNK_Section *header_sect, LNK_Chunk *parent)
{ {
static struct { static struct {
char *name; char *name;
PE_DataDirectoryIndex index; PE_DataDirectoryIndex index;
LNK_SymbolScopeFlags scope; LNK_SymbolScopeFlags scope;
} directory_map[] = { } directory_map[] = {
{ LNK_LOAD_CONFIG_SYMBOL_NAME , PE_DataDirectoryIndex_LOAD_CONFIG , LNK_SymbolScopeFlag_Main }, { LNK_LOAD_CONFIG_SYMBOL_NAME , PE_DataDirectoryIndex_LOAD_CONFIG , LNK_SymbolScopeFlag_Main },
{ LNK_PDATA_SYMBOL_NAME , PE_DataDirectoryIndex_EXCEPTIONS , LNK_SymbolScopeFlag_Internal }, { LNK_PDATA_SYMBOL_NAME , PE_DataDirectoryIndex_EXCEPTIONS , LNK_SymbolScopeFlag_Internal },
{ LNK_EDATA_SYMBOL_NAME , PE_DataDirectoryIndex_EXPORT , LNK_SymbolScopeFlag_Internal }, { LNK_EDATA_SYMBOL_NAME , PE_DataDirectoryIndex_EXPORT , LNK_SymbolScopeFlag_Internal },
{ LNK_BASE_RELOC_SYMBOL_NAME , PE_DataDirectoryIndex_BASE_RELOC , LNK_SymbolScopeFlag_Internal }, { LNK_BASE_RELOC_SYMBOL_NAME , PE_DataDirectoryIndex_BASE_RELOC , LNK_SymbolScopeFlag_Internal },
{ LNK_IMPORT_DLL_TABLE_SYMBOL_NAME , PE_DataDirectoryIndex_IMPORT , LNK_SymbolScopeFlag_Internal }, { LNK_IMPORT_DLL_TABLE_SYMBOL_NAME , PE_DataDirectoryIndex_IMPORT , LNK_SymbolScopeFlag_Internal },
{ LNK_IMPORT_IAT_SYMBOL_NAME , PE_DataDirectoryIndex_IMPORT_ADDR , LNK_SymbolScopeFlag_Internal }, { LNK_IMPORT_IAT_SYMBOL_NAME , PE_DataDirectoryIndex_IMPORT_ADDR , LNK_SymbolScopeFlag_Internal },
{ LNK_DELAYED_IMPORT_DLL_TABLE_SYMBOL_NAME, PE_DataDirectoryIndex_DELAY_IMPORT, LNK_SymbolScopeFlag_Internal }, { LNK_DELAYED_IMPORT_DLL_TABLE_SYMBOL_NAME, PE_DataDirectoryIndex_DELAY_IMPORT, LNK_SymbolScopeFlag_Internal },
{ LNK_TLS_SYMBOL_NAME , PE_DataDirectoryIndex_TLS , LNK_SymbolScopeFlag_Main }, { LNK_TLS_SYMBOL_NAME , PE_DataDirectoryIndex_TLS , LNK_SymbolScopeFlag_Main },
{ LNK_DEBUG_DIR_SYMBOL_NAME , PE_DataDirectoryIndex_DEBUG , LNK_SymbolScopeFlag_Internal }, { LNK_DEBUG_DIR_SYMBOL_NAME , PE_DataDirectoryIndex_DEBUG , LNK_SymbolScopeFlag_Internal },
{ LNK_RSRC_SYMBOL_NAME , PE_DataDirectoryIndex_RESOURCES , LNK_SymbolScopeFlag_Internal }, { LNK_RSRC_SYMBOL_NAME , PE_DataDirectoryIndex_RESOURCES , LNK_SymbolScopeFlag_Internal },
}; };
@@ -2239,10 +2225,8 @@ lnk_build_pe_directories(LNK_SymbolTable *symtab, LNK_Section *header_sect, LNK_
lnk_chunk_set_debugf(header_sect->arena, directory_array_chunk, LNK_PE_DIRECTORY_ARRAY_SYMBOL_NAME); lnk_chunk_set_debugf(header_sect->arena, directory_array_chunk, LNK_PE_DIRECTORY_ARRAY_SYMBOL_NAME);
// define PE directory symbols // define PE directory symbols
LNK_Symbol *directory_array_symbol = lnk_make_defined_symbol_chunk(symtab->arena, str8_lit(LNK_PE_DIRECTORY_ARRAY_SYMBOL_NAME), LNK_DefinedSymbolVisibility_Internal, 0, directory_array_chunk, 0, 0, 0); LNK_Symbol *directory_array_symbol = lnk_symbol_table_push_defined_chunk(symtab, str8_lit(LNK_PE_DIRECTORY_ARRAY_SYMBOL_NAME), LNK_DefinedSymbolVisibility_Internal, 0, directory_array_chunk, 0, 0, 0);
LNK_Symbol *directory_count_symbol = lnk_make_defined_symbol_va(symtab->arena, str8_lit(LNK_PE_DIRECTORY_COUNT_SYMBOL_NAME), LNK_DefinedSymbolVisibility_Internal, 0, directory_count); LNK_Symbol *directory_count_symbol = lnk_symbol_table_push_defined_va(symtab, str8_lit(LNK_PE_DIRECTORY_COUNT_SYMBOL_NAME), LNK_DefinedSymbolVisibility_Internal, 0, directory_count);
lnk_symbol_table_push(symtab, directory_array_symbol);
lnk_symbol_table_push(symtab, directory_count_symbol);
for (U64 dir_idx = 0; dir_idx < ArrayCount(directory_map); dir_idx += 1) { for (U64 dir_idx = 0; dir_idx < ArrayCount(directory_map); dir_idx += 1) {
String8 symbol_name = str8_cstring(directory_map[dir_idx].name); String8 symbol_name = str8_cstring(directory_map[dir_idx].name);
@@ -2270,9 +2254,8 @@ lnk_build_coff_section_table(LNK_SymbolTable *symtab, LNK_Section *header_sect,
Assert(!test_symbol); (void)test_symbol; Assert(!test_symbol); (void)test_symbol;
// define symbol // define symbol
String8 sect_symbol_name = push_str8_copy(symtab->arena, sect->name); String8 sect_symbol_name = push_str8_copy(symtab->arena->v[0], sect->name);
LNK_Symbol *sect_symbol = lnk_make_defined_symbol_chunk(symtab->arena, sect_symbol_name, LNK_DefinedSymbolVisibility_Internal, 0, sect->root, 0, 0, 0); lnk_symbol_table_push_defined_chunk(symtab, sect_symbol_name, LNK_DefinedSymbolVisibility_Internal, 0, sect->root, 0, 0, 0);
lnk_symbol_table_push(symtab, sect_symbol);
} }
// push COFF header array chunk // push COFF header array chunk
@@ -2280,8 +2263,7 @@ lnk_build_coff_section_table(LNK_SymbolTable *symtab, LNK_Section *header_sect,
lnk_chunk_set_debugf(header_sect->arena, coff_header_array_chunk, LNK_COFF_SECT_HEADER_ARRAY_SYMBOL_NAME); lnk_chunk_set_debugf(header_sect->arena, coff_header_array_chunk, LNK_COFF_SECT_HEADER_ARRAY_SYMBOL_NAME);
// define symbol for COFF header array // define symbol for COFF header array
LNK_Symbol *coff_header_array_symbol = lnk_make_defined_symbol_chunk(symtab->arena, str8_lit(LNK_COFF_SECT_HEADER_ARRAY_SYMBOL_NAME), LNK_DefinedSymbolVisibility_Internal, 0, coff_header_array_chunk, 0, 0, 0); lnk_symbol_table_push_defined_chunk(symtab, str8_lit(LNK_COFF_SECT_HEADER_ARRAY_SYMBOL_NAME), LNK_DefinedSymbolVisibility_Internal, 0, coff_header_array_chunk, 0, 0, 0);
lnk_symbol_table_push(symtab, coff_header_array_symbol);
// push headers // push headers
for (LNK_Section *sect = &sect_arr.v[0], *sect_opl = sect + sect_arr.count; sect < sect_opl; sect += 1) { for (LNK_Section *sect = &sect_arr.v[0], *sect_opl = sect + sect_arr.count; sect < sect_opl; sect += 1) {
@@ -2331,8 +2313,7 @@ lnk_build_coff_section_table(LNK_SymbolTable *symtab, LNK_Section *header_sect,
// push symbol for section header count // push symbol for section header count
U64 header_count = coff_header_array_chunk->u.list->count; U64 header_count = coff_header_array_chunk->u.list->count;
LNK_Symbol *header_symbol = lnk_make_defined_symbol_va(symtab->arena, str8_lit(LNK_COFF_SECT_HEADER_COUNT_SYMBOL_NAME), LNK_DefinedSymbolVisibility_Internal, 0, header_count); lnk_symbol_table_push_defined_va(symtab, str8_lit(LNK_COFF_SECT_HEADER_COUNT_SYMBOL_NAME), LNK_DefinedSymbolVisibility_Internal, 0, header_count);
lnk_symbol_table_push(symtab, header_symbol);
return coff_header_array_chunk; return coff_header_array_chunk;
} }
@@ -2365,21 +2346,13 @@ lnk_build_win32_image_header(LNK_SymbolTable *symtab,
lnk_chunk_set_debugf(header_sect->arena, pe_optional_chunk , "PE Optional Header Container" ); lnk_chunk_set_debugf(header_sect->arena, pe_optional_chunk , "PE Optional Header Container" );
lnk_chunk_set_debugf(header_sect->arena, coff_sect_header_chunk, "COFF Section Headers Container"); lnk_chunk_set_debugf(header_sect->arena, coff_sect_header_chunk, "COFF Section Headers Container");
LNK_Symbol *win32_header_symbol = lnk_make_defined_symbol_chunk(symtab->arena, str8_lit(LNK_WIN32_HEADER_SYMBOL_NAME) , LNK_DefinedSymbolVisibility_Internal, 0, win32_header_chunk , 0, 0, 0); lnk_symbol_table_push_defined_chunk(symtab, str8_lit(LNK_WIN32_HEADER_SYMBOL_NAME) , LNK_DefinedSymbolVisibility_Internal, 0, win32_header_chunk , 0, 0, 0);
LNK_Symbol *dos_symbol = lnk_make_defined_symbol_chunk(symtab->arena, str8_lit(LNK_DOS_SYMBOL_NAME) , LNK_DefinedSymbolVisibility_Internal, 0, dos_chunk , 0, 0, 0); lnk_symbol_table_push_defined_chunk(symtab, str8_lit(LNK_DOS_SYMBOL_NAME) , LNK_DefinedSymbolVisibility_Internal, 0, dos_chunk , 0, 0, 0);
LNK_Symbol *nt_headers_symbol = lnk_make_defined_symbol_chunk(symtab->arena, str8_lit(LNK_NT_HEADERS_SYMBOL_NAME) , LNK_DefinedSymbolVisibility_Internal, 0, nt_chunk , 0, 0, 0); lnk_symbol_table_push_defined_chunk(symtab, str8_lit(LNK_NT_HEADERS_SYMBOL_NAME) , LNK_DefinedSymbolVisibility_Internal, 0, nt_chunk , 0, 0, 0);
LNK_Symbol *pe_magic_symbol = lnk_make_defined_symbol_chunk(symtab->arena, str8_lit(LNK_PE_MAGIC_CONTAINER_SYMBOL_NAME) , LNK_DefinedSymbolVisibility_Internal, 0, pe_magic_chunk , 0, 0, 0); lnk_symbol_table_push_defined_chunk(symtab, str8_lit(LNK_PE_MAGIC_CONTAINER_SYMBOL_NAME) , LNK_DefinedSymbolVisibility_Internal, 0, pe_magic_chunk , 0, 0, 0);
LNK_Symbol *coff_file_header_symbol = lnk_make_defined_symbol_chunk(symtab->arena, str8_lit(LNK_COFF_FILE_HEADER_CONTAINER_SYMBOL_NAME) , LNK_DefinedSymbolVisibility_Internal, 0, coff_file_header_chunk, 0, 0, 0); lnk_symbol_table_push_defined_chunk(symtab, str8_lit(LNK_COFF_FILE_HEADER_CONTAINER_SYMBOL_NAME) , LNK_DefinedSymbolVisibility_Internal, 0, coff_file_header_chunk, 0, 0, 0);
LNK_Symbol *pe_optional_symbol = lnk_make_defined_symbol_chunk(symtab->arena, str8_lit(LNK_PE_OPT_HEADER_CONTAINER_SYMBOL_NAME) , LNK_DefinedSymbolVisibility_Internal, 0, pe_optional_chunk , 0, 0, 0); lnk_symbol_table_push_defined_chunk(symtab, str8_lit(LNK_PE_OPT_HEADER_CONTAINER_SYMBOL_NAME) , LNK_DefinedSymbolVisibility_Internal, 0, pe_optional_chunk , 0, 0, 0);
LNK_Symbol *coff_sect_header_symbol = lnk_make_defined_symbol_chunk(symtab->arena, str8_lit(LNK_COFF_SECTION_HEADER_CONTAINER_SYMBOL_NAME), LNK_DefinedSymbolVisibility_Internal, 0, coff_sect_header_chunk, 0, 0, 0); lnk_symbol_table_push_defined_chunk(symtab, str8_lit(LNK_COFF_SECTION_HEADER_CONTAINER_SYMBOL_NAME), LNK_DefinedSymbolVisibility_Internal, 0, coff_sect_header_chunk, 0, 0, 0);
lnk_symbol_table_push(symtab, win32_header_symbol );
lnk_symbol_table_push(symtab, dos_symbol );
lnk_symbol_table_push(symtab, nt_headers_symbol );
lnk_symbol_table_push(symtab, pe_magic_symbol );
lnk_symbol_table_push(symtab, coff_file_header_symbol);
lnk_symbol_table_push(symtab, pe_optional_symbol );
lnk_symbol_table_push(symtab, coff_sect_header_symbol);
lnk_build_dos_header(symtab, header_sect, dos_chunk); lnk_build_dos_header(symtab, header_sect, dos_chunk);
lnk_build_pe_magic(symtab, header_sect, pe_magic_chunk); lnk_build_pe_magic(symtab, header_sect, pe_magic_chunk);
@@ -2432,15 +2405,15 @@ THREAD_POOL_TASK_FUNC(lnk_undef_symbol_finder)
Assert(symbol->type == LNK_Symbol_Undefined); Assert(symbol->type == LNK_Symbol_Undefined);
LNK_UndefinedSymbol *undef = &symbol->u.undefined; LNK_UndefinedSymbol *undef = &symbol->u.undefined;
LNK_SymbolNode *has_defn = lnk_symbol_table_search_node(task->symtab, undef->scope_flags, symbol->name); LNK_Symbol *has_defn = lnk_symbol_table_search(task->symtab, undef->scope_flags, symbol->name);
if (has_defn) { if (has_defn) {
Assert(LNK_Symbol_IsDefined(has_defn->data->type) || has_defn->data->type == LNK_Symbol_Weak); Assert(LNK_Symbol_IsDefined(has_defn->type) || has_defn->type == LNK_Symbol_Weak);
continue; continue;
} }
LNK_SymbolNode *lazy = lnk_symbol_table_search_node(task->symtab, LNK_SymbolScopeFlag_Lib, symbol->name); LNK_Symbol *lazy = lnk_symbol_table_search(task->symtab, LNK_SymbolScopeFlag_Lib, symbol->name);
if (lazy) { if (lazy) {
lnk_push_input_from_lazy(arena, task->path_style, &lazy->data->u.lazy, &result->input_import_list, &result->input_obj_list); lnk_push_input_from_lazy(arena, task->path_style, &lazy->u.lazy, &result->input_import_list, &result->input_obj_list);
} else { } else {
lnk_symbol_list_push_node(&result->unresolved_symbol_list, symbol_node); lnk_symbol_list_push_node(&result->unresolved_symbol_list, symbol_node);
} }
@@ -2461,22 +2434,22 @@ THREAD_POOL_TASK_FUNC(lnk_weak_symbol_finder)
LNK_WeakSymbol *weak = &symbol->u.weak; LNK_WeakSymbol *weak = &symbol->u.weak;
Assert((weak->scope_flags & ~(LNK_SymbolScopeFlag_Defined | LNK_SymbolScopeFlag_Internal)) == 0); Assert((weak->scope_flags & ~(LNK_SymbolScopeFlag_Defined | LNK_SymbolScopeFlag_Internal)) == 0);
LNK_SymbolNode *has_strong_defn = lnk_symbol_table_search_node(task->symtab, weak->scope_flags, symbol->name); LNK_Symbol *has_strong_defn = lnk_symbol_table_search(task->symtab, weak->scope_flags, symbol->name);
if (has_strong_defn) { if (has_strong_defn) {
Assert(LNK_Symbol_IsDefined(has_strong_defn->data->type)); Assert(LNK_Symbol_IsDefined(has_strong_defn->type));
continue; continue;
} }
LNK_SymbolNode *lazy = 0; LNK_Symbol *lazy = 0;
switch (weak->lookup_type) { switch (weak->lookup_type) {
case COFF_WeakExtType_NOLIBRARY: { case COFF_WeakExtType_NOLIBRARY: {
// NOLIBRARY means weak symbol should be resolved in case where strong definition pulls in lib member. // NOLIBRARY means weak symbol should be resolved in case where strong definition pulls in lib member.
} break; } break;
case COFF_WeakExtType_SEARCH_LIBRARY: { case COFF_WeakExtType_SEARCH_LIBRARY: {
lazy = lnk_symbol_table_search_node(task->symtab, LNK_SymbolScopeFlag_Lib, symbol->name); lazy = lnk_symbol_table_search(task->symtab, LNK_SymbolScopeFlag_Lib, symbol->name);
} break; } break;
case COFF_WeakExtType_SEARCH_ALIAS: { case COFF_WeakExtType_SEARCH_ALIAS: {
lazy = lnk_symbol_table_search_node(task->symtab, LNK_SymbolScopeFlag_Lib, symbol->name); lazy = lnk_symbol_table_search(task->symtab, LNK_SymbolScopeFlag_Lib, symbol->name);
if (!lazy) { if (!lazy) {
if (str8_match(str8_lit(".weak."), symbol->name, StringMatchFlag_RightSideSloppy)) { if (str8_match(str8_lit(".weak."), symbol->name, StringMatchFlag_RightSideSloppy)) {
// TODO: Clang and MingGW encode extra info in alias // TODO: Clang and MingGW encode extra info in alias
@@ -2495,14 +2468,14 @@ THREAD_POOL_TASK_FUNC(lnk_weak_symbol_finder)
// In this case linker needs to parse .weak.bar.default.foo and search for bar and foo as well. // In this case linker needs to parse .weak.bar.default.foo and search for bar and foo as well.
Assert("TODO: MinGW weak symbol"); Assert("TODO: MinGW weak symbol");
} else { } else {
lazy = lnk_symbol_table_search_node(task->symtab, LNK_SymbolScopeFlag_Lib, weak->fallback_symbol->name); lazy = lnk_symbol_table_search(task->symtab, LNK_SymbolScopeFlag_Lib, weak->fallback_symbol->name);
} }
} }
} break; } break;
} }
if (lazy) { if (lazy) {
lnk_push_input_from_lazy(arena, task->path_style, &lazy->data->u.lazy, &result->input_import_list, &result->input_obj_list); lnk_push_input_from_lazy(arena, task->path_style, &lazy->u.lazy, &result->input_import_list, &result->input_obj_list);
} else { } else {
lnk_symbol_list_push_node(&result->unresolved_symbol_list, symbol_node); lnk_symbol_list_push_node(&result->unresolved_symbol_list, symbol_node);
} }
@@ -2564,26 +2537,66 @@ lnk_run_symbol_finder(TP_Context *tp,
} }
internal internal
THREAD_POOL_TASK_FUNC(lnk_defined_symbol_inserter) THREAD_POOL_TASK_FUNC(lnk_defined_symbol_pusher_task)
{ {
LNK_DefinedSymbolInserter *task = raw_task; LNK_SymbolPusher *task = raw_task;
LNK_SymbolTable *symtab = task->symtab; LNK_SymbolTable *symtab = task->symtab;
Rng1U64 range = task->range_arr[task_id]; LNK_Obj *obj = &task->u.objs.v[task_id].data;
for (U64 bucket_idx = range.min; bucket_idx < range.max; bucket_idx += 1) {
LNK_SymbolList *bucket = &task->bucket_arr[bucket_idx]; LNK_SymbolHashTrieChunkList **chunk_lists = symtab->chunk_lists;
for (LNK_SymbolNode *curr = bucket->first, *next; curr != 0; curr = next) {
next = curr->next; for (LNK_SymbolNode *symnode = obj->symbol_list.first; symnode != 0; symnode = symnode->next) {
LNK_SymbolNode *extant_node = lnk_symbol_table_search_bucket(symtab, LNK_SymbolScopeIndex_Defined, bucket_idx, curr->data->name, curr->hash); if (symnode->data->type == LNK_Symbol_DefinedExtern) {
if (extant_node) { U64 hash = lnk_symbol_hash(symnode->data->name);
LNK_SymbolList *symtab_bucket = lnk_symbol_table_bucket_from_hash(symtab, LNK_SymbolScopeIndex_Defined, curr->hash); lnk_symbol_table_push_(symtab, arena, &chunk_lists[LNK_SymbolScopeIndex_Defined][worker_id], LNK_SymbolScopeIndex_Defined, hash, symnode->data);
lnk_symbol_list_insert_after(symtab_bucket, extant_node, curr); } else if (symnode->data->type == LNK_Symbol_Weak) {
} else { U64 hash = lnk_symbol_hash(symnode->data->name);
lnk_symbol_table_push_(symtab, LNK_SymbolScopeIndex_Defined, curr, curr->hash); lnk_symbol_table_push_(symtab, arena, &chunk_lists[LNK_SymbolScopeIndex_Weak][worker_id], LNK_SymbolScopeIndex_Weak, hash, symnode->data);
}
} }
} }
} }
internal void
lnk_push_defined_symbols(TP_Context *tp, LNK_SymbolTable *symtab, LNK_ObjNodeArray objs)
{
ProfBeginFunction();
LNK_SymbolPusher task = {0};
task.symtab = symtab;
task.u.objs = objs;
tp_for_parallel(tp, symtab->arena, objs.count, lnk_defined_symbol_pusher_task, &task);
ProfEnd();
}
internal
THREAD_POOL_TASK_FUNC(lnk_lazy_symbol_pusher_task)
{
LNK_SymbolPusher *task = raw_task;
LNK_SymbolTable *symtab = task->symtab;
LNK_Lib *lib = &task->u.libs.v[task_id].data;
String8Node *name_node = lib->symbol_name_list.first;
LNK_Symbol *lazy_symbols = push_array_no_zero(arena, LNK_Symbol, lib->symbol_count);
for (U64 symbol_idx = 0; symbol_idx < lib->symbol_count; ++symbol_idx, name_node = name_node->next) {
LNK_Symbol *symbol = &lazy_symbols[symbol_idx];
lnk_init_lazy_symbol(symbol, name_node->string, lib, lib->member_off_arr[symbol_idx]);
U64 hash = lnk_symbol_hash(symbol->name);
lnk_symbol_table_push_(symtab, arena, &symtab->chunk_lists[LNK_SymbolScopeIndex_Lib][worker_id], LNK_SymbolScopeIndex_Lib, hash, symbol);
}
}
internal void
lnk_push_lazy_symbols(TP_Context *tp, LNK_SymbolTable *symtab, LNK_LibNodeArray libs)
{
ProfBeginFunction();
LNK_SymbolPusher task = {0};
task.symtab = symtab;
task.u.libs = libs;
tp_for_parallel(tp, symtab->arena, libs.count, lnk_lazy_symbol_pusher_task, &task);
ProfEnd();
}
//////////////////////////////// ////////////////////////////////
internal void internal void
@@ -2872,6 +2885,7 @@ lnk_init_section_table(LNK_SymbolTable *symtab, U64 section_virt_off, U64 sect_a
{ ".edata", LNK_EDATA_SYMBOL_NAME, LNK_EDATA_SECTION_FLAGS }, { ".edata", LNK_EDATA_SYMBOL_NAME, LNK_EDATA_SECTION_FLAGS },
{ ".rsrc", LNK_RSRC_SYMBOL_NAME, LNK_RSRC_SECTION_FLAGS }, { ".rsrc", LNK_RSRC_SYMBOL_NAME, LNK_RSRC_SECTION_FLAGS },
{ ".debug", LNK_DEBUG_SYMBOL_NAME, LNK_DEBUG_SECTION_FLAGS }, { ".debug", LNK_DEBUG_SYMBOL_NAME, LNK_DEBUG_SECTION_FLAGS },
{ ".tls", LNK_TLS_SYMBOL_NAME, LNK_TLS_SECTION_FLAGS },
}; };
LNK_SectionTable *st = lnk_section_table_alloc(section_virt_off, sect_align, file_align); LNK_SectionTable *st = lnk_section_table_alloc(section_virt_off, sect_align, file_align);
@@ -2880,8 +2894,7 @@ lnk_init_section_table(LNK_SymbolTable *symtab, U64 section_virt_off, U64 sect_a
sect->symbol_name = str8_cstring(sect_layout[i].symbol); sect->symbol_name = str8_cstring(sect_layout[i].symbol);
sect->symbol_name = push_str8_copy(sect->arena, sect->symbol_name); sect->symbol_name = push_str8_copy(sect->arena, sect->symbol_name);
LNK_Symbol *symbol = lnk_make_defined_symbol_chunk(symtab->arena, sect->symbol_name, LNK_DefinedSymbolVisibility_Internal, 0, sect->root, 0, 0, 0); lnk_symbol_table_push_defined_chunk(symtab, sect->symbol_name, LNK_DefinedSymbolVisibility_Internal, 0, sect->root, 0, 0, 0);
lnk_symbol_table_push(symtab, symbol);
} }
st->null_sect = lnk_section_list_remove(&st->list, str8_lit(".null")); st->null_sect = lnk_section_list_remove(&st->list, str8_lit(".null"));
@@ -2903,6 +2916,7 @@ lnk_init_merge_directive_list(Arena *arena, LNK_ObjList obj_list)
LNK_MergeDirectiveList result = {0}; LNK_MergeDirectiveList result = {0};
lnk_merge_directive_list_push(arena, &result, (LNK_MergeDirective){ str8_lit_comp(".xdata") , str8_lit_comp(".rdata") }); lnk_merge_directive_list_push(arena, &result, (LNK_MergeDirective){ str8_lit_comp(".xdata") , str8_lit_comp(".rdata") });
//lnk_merge_directive_list_push(arena, &result, (LNK_MergeDirective){ str8_lit_comp(".tls"), str8_lit_comp(".data") });
// collect merge directives from objs // collect merge directives from objs
for (LNK_ObjNode *obj_node = obj_list.first; obj_node != 0; obj_node = obj_node->next) { for (LNK_ObjNode *obj_node = obj_list.first; obj_node != 0; obj_node = obj_node->next) {
@@ -3130,6 +3144,15 @@ lnk_blake3_hash_parallel(TP_Context *tp, U64 chunk_count, String8 data)
return result; return result;
} }
LNK_CHUNK_VISITOR_SIG(lnk_max_tls_align)
{
if (chunk->type == LNK_Chunk_Leaf) {
U64 *max_align = ud;
*max_align = Max(*max_align, chunk->align);
}
return 0;
}
internal void internal void
lnk_run(int argc, char **argv) lnk_run(int argc, char **argv)
{ {
@@ -3150,7 +3173,6 @@ lnk_run(int argc, char **argv)
State_SearchEntryPoint, State_SearchEntryPoint,
State_CheckUnusedDelayLoads, State_CheckUnusedDelayLoads,
State_ReportUnresolvedSymbols, State_ReportUnresolvedSymbols,
State_RewireComdats,
State_DiscardMetaDataSections, State_DiscardMetaDataSections,
State_BuildDebugDirectory, State_BuildDebugDirectory,
State_BuildExportTable, State_BuildExportTable,
@@ -3207,7 +3229,6 @@ l.count += 1; \
LNK_InputLibList input_libs[LNK_InputSource_Count] = {0}; LNK_InputLibList input_libs[LNK_InputSource_Count] = {0};
LNK_InputObjList input_obj_list = {0}; LNK_InputObjList input_obj_list = {0};
LNK_InputImportList input_import_list = {0}; LNK_InputImportList input_import_list = {0};
LNK_SymbolList input_defn_list = {0};
LNK_SymbolList input_weak_list = {0}; LNK_SymbolList input_weak_list = {0};
// :null_obj // :null_obj
@@ -3222,7 +3243,7 @@ l.count += 1; \
input_libs[LNK_InputSource_Default] = config->input_default_lib_list; input_libs[LNK_InputSource_Default] = config->input_default_lib_list;
// state // state
LNK_SymbolTable *symtab = lnk_symbol_table_alloc_ex(config->symbol_table_cap_defined, config->symbol_table_cap_internal, config->symbol_table_cap_weak, config->symbol_table_cap_lib); LNK_SymbolTable *symtab = lnk_symbol_table_init(tp_arena);
LNK_SectionTable *st = lnk_init_section_table(symtab, config->section_virt_off, config->sect_align, config->file_align); LNK_SectionTable *st = lnk_init_section_table(symtab, config->section_virt_off, config->sect_align, config->file_align);
LNK_ImportTable *imptab_static = 0; LNK_ImportTable *imptab_static = 0;
LNK_ImportTable *imptab_delayed = 0; LNK_ImportTable *imptab_delayed = 0;
@@ -3249,11 +3270,10 @@ l.count += 1; \
B32 build_base_relocs = !(config->flags & LNK_ConfigFlag_Fixed); B32 build_base_relocs = !(config->flags & LNK_ConfigFlag_Fixed);
B32 report_unresolved_symbols = 1; B32 report_unresolved_symbols = 1;
B32 check_unused_delay_loads = !!(config->flags & LNK_ConfigFlag_CheckUnusedDelayLoadDll); B32 check_unused_delay_loads = !!(config->flags & LNK_ConfigFlag_CheckUnusedDelayLoadDll);
B32 do_comdat_rewire = 1;
B32 build_win32_header = 1; B32 build_win32_header = 1;
B32 patch_relocs = 1; B32 patch_relocs = 1;
B32 sort_exception_info = 1; B32 sort_exception_info = 1;
B32 build_imp_lib = config->build_imp_lib; B32 build_imp_lib = 1; //config->build_imp_lib;
LNK_ObjList obj_list = {0}; LNK_ObjList obj_list = {0};
LNK_LibList lib_index[LNK_InputSource_Count] = {0}; LNK_LibList lib_index[LNK_InputSource_Count] = {0};
String8 image_data = str8_zero(); String8 image_data = str8_zero();
@@ -3332,8 +3352,8 @@ l.count += 1; \
if (entry_point_symbol) { if (entry_point_symbol) {
lnk_error(LNK_Error_EntryPoint, lnk_error(LNK_Error_EntryPoint,
"multiple entry point symbols found: %S(%S) and %S(%S)", "multiple entry point symbols found: %S(%S) and %S(%S)",
entry_point_symbol->name, entry_point_symbol->debug, entry_point_symbol->name, entry_point_symbol->obj->path,
symbol->name, symbol->debug); symbol->name, symbol->obj->path);
} else { } else {
entry_point_symbol = symbol; entry_point_symbol = symbol;
} }
@@ -3432,8 +3452,8 @@ l.count += 1; \
ProfBegin("Push /INCLUDE Symbols"); ProfBegin("Push /INCLUDE Symbols");
for (String8Node *include_node = include_symbol_list.first; include_node != 0; include_node = include_node->next) { for (String8Node *include_node = include_symbol_list.first; include_node != 0; include_node = include_node->next) {
String8 name = push_str8_copy(symtab->arena, include_node->string); String8 name = push_str8_copy(symtab->arena->v[0], include_node->string);
LNK_Symbol *symbol = lnk_make_undefined_symbol(symtab->arena, name, LNK_SymbolScopeFlag_Main); LNK_Symbol *symbol = lnk_make_undefined_symbol(symtab->arena->v[0], name, LNK_SymbolScopeFlag_Main);
lnk_symbol_list_push(scratch.arena, &lookup_undef_list, symbol); lnk_symbol_list_push(scratch.arena, &lookup_undef_list, symbol);
} }
ProfEnd(); ProfEnd();
@@ -3443,64 +3463,19 @@ l.count += 1; \
for (String8Node *from_node = alt_name_list.from_list.first, *to_node = alt_name_list.to_list.first; for (String8Node *from_node = alt_name_list.from_list.first, *to_node = alt_name_list.to_list.first;
from_node != 0; from_node != 0;
from_node = from_node->next, to_node = to_node->next) { from_node = from_node->next, to_node = to_node->next) {
String8 to_name = push_str8_copy(symtab->arena, to_node->string); LNK_Symbol *weak = lnk_symbol_table_push_weak(symtab, from_node->string, COFF_WeakExtType_SEARCH_ALIAS, to_node->string);
String8 from_name = push_str8_copy(symtab->arena, from_node->string);
LNK_Symbol *fallback = lnk_make_undefined_symbol(symtab->arena, to_name, LNK_SymbolScopeFlag_Main);
LNK_Symbol *weak = lnk_make_weak_symbol(symtab->arena, from_name, COFF_WeakExtType_SEARCH_ALIAS, fallback);
lnk_symbol_list_push(scratch.arena, &input_weak_list, weak); lnk_symbol_list_push(scratch.arena, &input_weak_list, weak);
} }
ProfEnd(); ProfEnd();
ProfBegin("Push Defined Symbols");
{
Temp temp = temp_begin(scratch.arena);
ProfBegin("List -> Array");
LNK_SymbolNodeArray symbol_arr = lnk_symbol_node_array_from_list(temp.arena, input_defn_list);
ProfEnd();
ProfBegin("Hash Symbol Names");
lnk_symbol_node_ptr_array_hash(tp, symbol_arr.v, symbol_arr.count);
ProfEnd();
ProfBegin("Populate Buckets");
LNK_SymbolList *bucket_arr = push_array(temp.arena, LNK_SymbolList, symtab->bucket_count[LNK_SymbolScopeIndex_Defined]);
for (U64 symbol_idx = 0; symbol_idx < symbol_arr.count; symbol_idx += 1) {
LNK_SymbolNode *symbol_node = symbol_arr.v[symbol_idx];
U64 bucket_idx = symbol_node->hash % symtab->bucket_count[LNK_SymbolScopeIndex_Defined];
lnk_symbol_list_push_node(&bucket_arr[bucket_idx], symbol_node);
}
ProfEnd();
ProfBegin("Insert Defined Symbols");
LNK_DefinedSymbolInserter symbol_inserter = {0};
symbol_inserter.symtab = symtab;
symbol_inserter.bucket_arr = bucket_arr;
symbol_inserter.range_arr = tp_divide_work(temp.arena, symtab->bucket_count[LNK_SymbolScopeIndex_Defined], tp->worker_count);
tp_for_parallel(tp, 0, tp->worker_count, lnk_defined_symbol_inserter, &symbol_inserter);
ProfEnd();
temp_end(temp);
}
ProfEnd();
ProfBegin("Push Weak Symbols");
for (LNK_SymbolNode *curr = input_weak_list.first; curr != 0; curr = curr->next) {
lnk_symbol_table_push(symtab, curr->data);
}
ProfEnd();
LNK_SymbolList new_weak_symbols = lnk_symbol_list_copy(scratch.arena, input_weak_list);
// we defined new symbols, give unresolved symbols another chance to be resolved // we defined new symbols, give unresolved symbols another chance to be resolved
lnk_symbol_list_concat_in_place(&lookup_undef_list, &unresolved_undef_list); lnk_symbol_list_concat_in_place(&lookup_undef_list, &unresolved_undef_list);
lnk_symbol_list_concat_in_place(&lookup_weak_list, &new_weak_symbols); lnk_symbol_list_concat_in_place(&lookup_weak_list, &input_weak_list);
lnk_symbol_list_concat_in_place(&lookup_weak_list, &unresolved_weak_list); lnk_symbol_list_concat_in_place(&lookup_weak_list, &unresolved_weak_list);
// reset inputs // reset inputs
MemoryZeroStruct(&include_symbol_list); MemoryZeroStruct(&include_symbol_list);
MemoryZeroStruct(&alt_name_list); MemoryZeroStruct(&alt_name_list);
MemoryZeroStruct(&input_defn_list);
MemoryZeroStruct(&input_weak_list); MemoryZeroStruct(&input_weak_list);
ProfEnd(); ProfEnd();
@@ -3612,16 +3587,15 @@ l.count += 1; \
// derive machine from obj // derive machine from obj
if (config->machine == COFF_MachineType_UNKNOWN) { if (config->machine == COFF_MachineType_UNKNOWN) {
config->machine = obj->machine; config->machine = obj->machine;
} } else {
// is obj machine compatible?
// is obj machine compatible? if (config->machine != obj->machine &&
if (obj->machine != COFF_MachineType_UNKNOWN && // obj with unknown machine type is compatible with any other machine type obj->machine != COFF_MachineType_UNKNOWN) { // obj with unknown machine type is compatible with any other machine type
config->machine != obj->machine) { lnk_error_obj(LNK_Error_IncompatibleObj, obj,
lnk_error_obj(LNK_Error_IncompatibleObj, "conflicting machine types expected %S but got %S",
obj, coff_string_from_machine_type(config->machine),
"conflicting machine types expected %S but got %S", coff_string_from_machine_type(obj->machine));
coff_string_from_machine_type(config->machine), }
coff_string_from_machine_type(obj->machine));
} }
} }
ProfEnd(); ProfEnd();
@@ -3645,13 +3619,14 @@ l.count += 1; \
LNK_InputLibList lib_list = lnk_collect_default_lib_obj_arr(tp, tp_arena, obj_node_arr); // TODO: put these on temp arena LNK_InputLibList lib_list = lnk_collect_default_lib_obj_arr(tp, tp_arena, obj_node_arr); // TODO: put these on temp arena
str8_list_concat_in_place(&input_libs[LNK_InputSource_Obj], &lib_list); str8_list_concat_in_place(&input_libs[LNK_InputSource_Obj], &lib_list);
// update symbol table
lnk_push_defined_symbols(tp, symtab, obj_node_arr);
// collect symbols for input // collect symbols for input
LNK_SymbolList new_defn_list = lnk_run_symbol_collector(tp, tp_arena, obj_node_arr, LNK_Symbol_DefinedExtern);
LNK_SymbolList new_weak_list = lnk_run_symbol_collector(tp, tp_arena, obj_node_arr, LNK_Symbol_Weak); LNK_SymbolList new_weak_list = lnk_run_symbol_collector(tp, tp_arena, obj_node_arr, LNK_Symbol_Weak);
LNK_SymbolList new_undef_list = lnk_run_symbol_collector(tp, tp_arena, obj_node_arr, LNK_Symbol_Undefined); // TODO: allocate these on temp arena LNK_SymbolList new_undef_list = lnk_run_symbol_collector(tp, tp_arena, obj_node_arr, LNK_Symbol_Undefined); // TODO: allocate these on temp arena
// schedule symbol input // schedule symbol input
lnk_symbol_list_concat_in_place(&input_defn_list, &new_defn_list);
lnk_symbol_list_concat_in_place(&input_weak_list, &new_weak_list); lnk_symbol_list_concat_in_place(&input_weak_list, &new_weak_list);
lnk_symbol_list_concat_in_place(&lookup_undef_list, &new_undef_list); lnk_symbol_list_concat_in_place(&lookup_undef_list, &new_undef_list);
@@ -3723,43 +3698,16 @@ l.count += 1; \
} }
ProfEnd(); ProfEnd();
LNK_LibNodeArray lib_arr; ProfBegin("Disk Read Libs");
{ String8Array path_arr = str8_array_from_list(scratch.arena, &unique_input_lib_list);
ProfBegin("Disk Read Libs"); String8Array data_arr = lnk_read_data_from_file_path_parallel(tp, tp_arena->v[0], path_arr);
String8Array path_arr = str8_array_from_list(scratch.arena, &unique_input_lib_list); ProfEnd();
String8Array data_arr = lnk_read_data_from_file_path_parallel(tp, tp_arena->v[0], path_arr);
ProfEnd();
ProfBegin("Lib Init"); ProfBegin("Lib Init");
lib_arr = lnk_lib_list_push_parallel(tp, tp_arena, &lib_index[input_source], data_arr, path_arr); LNK_LibNodeArray lib_arr = lnk_lib_list_push_parallel(tp, tp_arena, &lib_index[input_source], data_arr, path_arr);
ProfEnd(); ProfEnd();
ProfBegin("Count Symbols"); lnk_push_lazy_symbols(tp, symtab, lib_arr);
U64 total_symbol_count = 0;
for (U64 lib_idx = 0; lib_idx < lib_arr.count; lib_idx += 1) {
total_symbol_count += lib_arr.v[lib_idx].data.symbol_count;
}
ProfEnd();
ProfBegin("Setup Symbol Array Pointers");
LNK_Symbol *symbol_arr = push_array_no_zero(symtab->arena, LNK_Symbol, total_symbol_count);
LNK_Symbol **symbol_arr_arr = push_array_no_zero(scratch.arena, LNK_Symbol *, lib_arr.count);
for (U64 lib_idx = 0, cursor = 0; lib_idx < lib_arr.count; lib_idx += 1) {
symbol_arr_arr[lib_idx] = &symbol_arr[cursor];
cursor += lib_arr.v[lib_idx].data.symbol_count;
}
ProfEnd();
ProfBegin("Lazy Symbol Init");
LNK_LazyIniter lazy_initer_ctx = {0};
lazy_initer_ctx.range_arr = tp_divide_work(scratch.arena, lib_arr.count, tp->worker_count);
lazy_initer_ctx.lib_arr = lib_arr.v;
lazy_initer_ctx.symbol_arr_arr = symbol_arr_arr;
tp_for_parallel(tp, 0, tp->worker_count, lnk_lazy_initer, &lazy_initer_ctx);
ProfEnd();
lnk_symbol_table_push_lazy_arr(tp, symtab, symbol_arr, total_symbol_count);
}
if (lnk_get_log_status(LNK_Log_InputLib)) { if (lnk_get_log_status(LNK_Log_InputLib)) {
if (lib_arr.count > 0) { if (lib_arr.count > 0) {
@@ -3925,11 +3873,6 @@ l.count += 1; \
goto exit; goto exit;
} }
} break; } break;
case State_RewireComdats: {
ProfBegin("Fold COMDAT symbols");
lnk_fold_comdat_chunks(tp, symtab);
ProfEnd();
} break;
case State_DiscardMetaDataSections: { case State_DiscardMetaDataSections: {
ProfBegin("Discard Meta Data Sections"); ProfBegin("Discard Meta Data Sections");
@@ -3945,8 +3888,7 @@ l.count += 1; \
LNK_Chunk *debug_dir_array_chunk = lnk_section_push_chunk_list(debug_sect, debug_chunk, str8_zero()); LNK_Chunk *debug_dir_array_chunk = lnk_section_push_chunk_list(debug_sect, debug_chunk, str8_zero());
// push symbols for PE directory patch // push symbols for PE directory patch
LNK_Symbol *dir_array_symbol = lnk_make_defined_symbol_chunk(symtab->arena, str8_lit(LNK_DEBUG_DIR_SYMBOL_NAME), LNK_DefinedSymbolVisibility_Internal, 0, debug_dir_array_chunk, 0, 0, 0); lnk_symbol_table_push_defined_chunk(symtab, str8_lit(LNK_DEBUG_DIR_SYMBOL_NAME), LNK_DefinedSymbolVisibility_Internal, 0, debug_dir_array_chunk, 0, 0, 0);
lnk_symbol_table_push(symtab, dir_array_symbol);
// debug entry for PDB // debug entry for PDB
if (config->debug_mode != LNK_DebugMode_None && config->debug_mode != LNK_DebugMode_Null) { if (config->debug_mode != LNK_DebugMode_None && config->debug_mode != LNK_DebugMode_Null) {
@@ -4062,12 +4004,45 @@ l.count += 1; \
lnk_log(LNK_Log_InputLib, "[Total Lib Input Size %S]", size_string); lnk_log(LNK_Log_InputLib, "[Total Lib Input Size %S]", size_string);
} }
//lnk_symbol_hash_trie_debug(symtab->scopes[LNK_SymbolScopeIndex_Lib]);
ProfBegin("Image Serialize"); ProfBegin("Image Serialize");
image_data = lnk_section_table_serialize(scratch.arena, st); image_data = lnk_section_table_serialize(scratch.arena, st);
ProfEnd(); ProfEnd();
LNK_Section **sect_id_map = lnk_sect_id_map_from_section_table(scratch.arena, st); LNK_Section **sect_id_map = lnk_sect_id_map_from_section_table(scratch.arena, st);
LNK_Symbol *tls_used_symbol = lnk_symbol_table_searchf(symtab, LNK_SymbolScopeFlag_Main, "_tls_used");
if (tls_used_symbol) {
ProfBegin("Patch TLS Align");
// loop over .tls sections and extract max alignment
LNK_Symbol *tls_sect_symbol = lnk_symbol_table_searchf(symtab, LNK_SymbolScopeFlag_Internal, LNK_TLS_SYMBOL_NAME);
LNK_Chunk *tls_root_chunk = tls_sect_symbol->u.defined.u.chunk;
U64 tls_align = 0;
lnk_visit_chunks(0, tls_root_chunk, lnk_max_tls_align, &tls_align);
if (IsPow2(tls_align)) {
// compute TLS header offset
U64 tls_header_foff = lnk_file_off_from_symbol(sect_id_map, tls_used_symbol);
// patch TLS header
if (coff_word_size_from_machine(config->machine) == 8) {
String8 raw_tls_used = str8_substr(image_data, rng_1u64(tls_header_foff, tls_header_foff + sizeof(PE_TLSHeader64)));
PE_TLSHeader64 *tls_header = (PE_TLSHeader64 *) raw_tls_used.str;
tls_header->characteristics |= coff_section_flag_from_align_size(tls_align);
} else {
String8 raw_tls_used = str8_substr(image_data, rng_1u64(tls_header_foff, tls_header_foff + sizeof(PE_TLSHeader32)));
PE_TLSHeader32 *tls_header = (PE_TLSHeader32 *) raw_tls_used.str;
tls_header->characteristics |= coff_section_flag_from_align_size(tls_align);
}
} else {
lnk_error(LNK_Warning_TLSAlign, "unable to patch TLS Header characteristics, alignment must be power of two, align inferred from section flags: %llu", tls_align);
}
ProfEnd();
}
if (config->flags & LNK_ConfigFlag_WriteImageChecksum) { if (config->flags & LNK_ConfigFlag_WriteImageChecksum) {
ProfBegin("Image Checksum"); ProfBegin("Image Checksum");
@@ -4196,8 +4171,7 @@ l.count += 1; \
state_list_push(scratch.arena, state_list, State_InputImports); state_list_push(scratch.arena, state_list, State_InputImports);
continue; continue;
} }
if (input_defn_list.count || if (input_weak_list.count ||
input_weak_list.count ||
include_symbol_list.node_count || include_symbol_list.node_count ||
alt_name_list.from_list.node_count) { alt_name_list.from_list.node_count) {
state_list_push(scratch.arena, state_list, State_InputSymbols); state_list_push(scratch.arena, state_list, State_InputSymbols);
@@ -4264,11 +4238,6 @@ l.count += 1; \
state_list_push(scratch.arena, state_list, State_BuildAndInputLinkerObj); state_list_push(scratch.arena, state_list, State_BuildAndInputLinkerObj);
continue; continue;
} }
if (do_comdat_rewire) {
do_comdat_rewire = 0;
state_list_push(scratch.arena, state_list, State_RewireComdats);
continue;
}
if (check_unused_delay_loads) { if (check_unused_delay_loads) {
check_unused_delay_loads = 0; check_unused_delay_loads = 0;
state_list_push(scratch.arena, state_list, State_CheckUnusedDelayLoads); state_list_push(scratch.arena, state_list, State_CheckUnusedDelayLoads);
@@ -4359,7 +4328,6 @@ l.count += 1; \
// linker is done punt memory release to OS // linker is done punt memory release to OS
//lnk_section_table_release(&st); //lnk_section_table_release(&st);
//lnk_symbol_table_release(&symtab);
//lnk_export_table_release(&export_table); //lnk_export_table_release(&export_table);
//lnk_import_table_release(&imptab_static); //lnk_import_table_release(&imptab_static);
//lnk_import_table_release(&imptab_delayed); //lnk_import_table_release(&imptab_delayed);
@@ -4377,6 +4345,9 @@ entry_point(CmdLine *cmdline)
{ {
Temp scratch = scratch_begin(0,0); Temp scratch = scratch_begin(0,0);
int a = 123;
int asdasd = 2;
#if PROFILE_TELEMETRY #if PROFILE_TELEMETRY
tmMessage(0, TMMF_ICON_NOTE, BUILD_TITLE); tmMessage(0, TMMF_ICON_NOTE, BUILD_TITLE);
#endif #endif
+9 -8
View File
@@ -172,13 +172,6 @@ typedef struct
HashTable **page_ht_arr; HashTable **page_ht_arr;
} LNK_ObjBaseRelocTask; } LNK_ObjBaseRelocTask;
typedef struct
{
Rng1U64 *range_arr;
LNK_LibNode *lib_arr;
LNK_Symbol **symbol_arr_arr;
} LNK_LazyIniter;
typedef struct typedef struct
{ {
LNK_InputObjList input_obj_list; LNK_InputObjList input_obj_list;
@@ -195,6 +188,15 @@ typedef struct
Rng1U64 *range_arr; Rng1U64 *range_arr;
} LNK_SymbolFinder; } LNK_SymbolFinder;
typedef struct
{
LNK_SymbolTable *symtab;
union {
LNK_ObjNodeArray objs;
LNK_LibNodeArray libs;
} u;
} LNK_SymbolPusher;
typedef struct typedef struct
{ {
LNK_SymbolTable *symtab; LNK_SymbolTable *symtab;
@@ -214,7 +216,6 @@ typedef struct
LNK_Obj **obj_arr; LNK_Obj **obj_arr;
} LNK_ObjRelocPatcher; } LNK_ObjRelocPatcher;
typedef struct typedef struct
{ {
String8 path; String8 path;
+2
View File
@@ -43,6 +43,8 @@ typedef struct LNK_Chunk
#if LNK_DEBUG_CHUNKS #if LNK_DEBUG_CHUNKS
String8 debug; String8 debug;
#endif #endif
int debug;
} LNK_Chunk, * LNK_ChunkPtr; } LNK_Chunk, * LNK_ChunkPtr;
typedef struct LNK_ChunkNode typedef struct LNK_ChunkNode
+31 -26
View File
@@ -2827,20 +2827,23 @@ THREAD_POOL_TASK_FUNC(lnk_push_dbi_sec_contrib_task)
//////////////////////////////// ////////////////////////////////
internal 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; ProfBeginFunction();
LNK_BuildPublicSymbolsTaskData *task = raw_task;
LNK_Section **sect_id_map = task->sect_id_map; LNK_BuildPublicSymbolsTask *task = raw_task;
LNK_SymbolScopeIndex scope_idx = task->scope_idx; LNK_Section **sect_id_map = task->sect_id_map;
LNK_SymbolList bucket = task->bucket_arr[scope_idx][bucket_idx]; CV_SymbolList *pub_list = &task->pub_list_arr[task_id];
CV_SymbolList *pub_list = &task->pub_list_arr[bucket_idx]; LNK_SymbolHashTrieChunkList chunk_list = task->chunk_lists[task_id];
for (LNK_SymbolNode *symbol_node = bucket.first; symbol_node != 0; symbol_node = symbol_node->next) { for (LNK_SymbolHashTrieChunk *chunk = chunk_list.first; chunk != 0; chunk = chunk->next) {
LNK_Symbol *symbol = symbol_node->data; 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; LNK_DefinedSymbol *defined_symbol = &symbol->u.defined;
if (defined_symbol->value_type == LNK_DefinedSymbolValue_Chunk) { if (defined_symbol->value_type == LNK_DefinedSymbolValue_Chunk) {
CV_Pub32Flags flags = 0; 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); U32 symbol_off32 = safe_cast_u32(symbol_off);
U16 symbol_isect16 = safe_cast_u16(symbol_isect); U16 symbol_isect16 = safe_cast_u16(symbol_isect);
CV_SymbolNode *pub_node = cv_symbol_list_push(arena, pub_list); nodes[node_idx].data = cv_make_pub32(arena, flags, symbol_off32, symbol_isect16, symbol->name);
pub_node->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 internal
@@ -2866,8 +2873,8 @@ THREAD_POOL_TASK_FUNC(lnk_gsi_hash_cv_list_task)
{ {
ProfBeginFunction(); ProfBeginFunction();
LNK_BuildPublicSymbolsTaskData *task = raw_task; LNK_BuildPublicSymbolsTask *task = raw_task;
Rng1U64 range = task->symbol_ranges[task_id]; Rng1U64 range = task->symbol_ranges[task_id];
for (U64 symbol_idx = range.min; symbol_idx < range.max; ++symbol_idx) { for (U64 symbol_idx = range.min; symbol_idx < range.max; ++symbol_idx) {
CV_Symbol *symbol = &task->symbols.v[symbol_idx]->data; CV_Symbol *symbol = &task->symbols.v[symbol_idx]->data;
@@ -2883,22 +2890,20 @@ lnk_build_pdb_public_symbols(TP_Context *tp,
TP_Arena *arena, TP_Arena *arena,
LNK_SymbolTable *symtab, LNK_SymbolTable *symtab,
LNK_Section **sect_id_map, LNK_Section **sect_id_map,
PDB_PsiContext *psi, PDB_PsiContext *psi)
LNK_SymbolScopeIndex scope_idx)
{ {
ProfBeginFunction(); ProfBeginFunction();
Temp scratch = scratch_begin(arena->v, arena->count); Temp scratch = scratch_begin(arena->v, arena->count);
ProfBegin("Make Public Symbols"); ProfBegin("Defined");
LNK_BuildPublicSymbolsTaskData task = {0}; LNK_BuildPublicSymbolsTask task = {0};
task.sect_id_map = sect_id_map; task.sect_id_map = sect_id_map;
task.scope_idx = scope_idx; task.pub_list_arr = push_array(scratch.arena, CV_SymbolList, tp->worker_count);
task.bucket_arr = symtab->buckets; task.chunk_lists = symtab->chunk_lists[LNK_SymbolScopeIndex_Defined];
task.pub_list_arr = push_array(scratch.arena, CV_SymbolList, symtab->bucket_count[scope_idx]); tp_for_parallel(tp, arena, tp->worker_count, lnk_build_pdb_public_symbols_defined_task, &task);
tp_for_parallel(tp, arena, symtab->bucket_count[scope_idx], lnk_build_pdb_public_symbols_task, &task);
ProfEnd(); 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"); ProfBegin("GSI Push");
gsi_push_many_arr(tp, psi->gsi, symbols.count, symbols.v); 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"); 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_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); 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); U64 coff_sect_count = coff_sect_chunk_data.size / sizeof(COFF_SectionHeader);
COFF_SectionHeader *coff_sect_ptr = (COFF_SectionHeader*)coff_sect_chunk_data.str; COFF_SectionHeader *coff_sect_ptr = (COFF_SectionHeader*)coff_sect_chunk_data.str;
@@ -3125,7 +3130,7 @@ lnk_build_pdb(TP_Context *tp,
} }
ProfEnd(); 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); pdb_build(tp, tp_arena, pdb, string_ht);
+5 -7
View File
@@ -333,16 +333,15 @@ typedef struct
typedef struct typedef struct
{ {
LNK_Section **sect_id_map; LNK_Section **sect_id_map;
LNK_SymbolScopeIndex scope_idx; LNK_SymbolHashTrieChunkList *chunk_lists;
LNK_SymbolList **bucket_arr; CV_SymbolList *pub_list_arr;
CV_SymbolList *pub_list_arr;
Rng1U64 *symbol_ranges; Rng1U64 *symbol_ranges;
PDB_GsiContext *gsi; PDB_GsiContext *gsi;
CV_SymbolPtrArray symbols; CV_SymbolPtrArray symbols;
U32 *hashes; U32 *hashes;
} LNK_BuildPublicSymbolsTaskData; } LNK_BuildPublicSymbolsTask;
typedef struct typedef struct
{ {
@@ -566,8 +565,7 @@ internal void lnk_build_pdb_public_symbols(TP_Context *tp,
TP_Arena *arena, TP_Arena *arena,
LNK_SymbolTable *symtab, LNK_SymbolTable *symtab,
LNK_Section **sect_id_map, LNK_Section **sect_id_map,
PDB_PsiContext *psi, PDB_PsiContext *psi);
LNK_SymbolScopeIndex scope_idx);
internal String8List lnk_build_pdb(TP_Context *tp, internal String8List lnk_build_pdb(TP_Context *tp,
TP_Arena *tp_arena, TP_Arena *tp_arena,
+6
View File
@@ -70,6 +70,12 @@ lnk_parse_directives(Arena *arena, LNK_DirectiveInfo *directive_info, String8 bu
for (U64 i = 0; i < ArrayCount(directive_table); ++i) { for (U64 i = 0; i < ArrayCount(directive_table); ++i) {
if (str8_match(directive_table[i].name, opt->string, StringMatchFlag_CaseInsensitive)) { if (str8_match(directive_table[i].name, opt->string, StringMatchFlag_CaseInsensitive)) {
kind = directive_table[i].kind; 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; break;
} }
} }
+9 -14
View File
@@ -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, string_buffer_chunk, "EXPORT_STRING_BUFFER");
lnk_chunk_set_debugf(edata->arena, image_name_chunk, "EXPORT_IMAGE_NAME"); 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 *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_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 *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_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 *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_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 *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);
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);
// patch header fields // 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, 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, 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, ordinal_table_voff), ordinal_table_symbol);
// reserve virtual offset chunks // reserve virtual offset chunks
LNK_Chunk **ordinal_voff_map = push_array(scratch.arena, LNK_Chunk *, exptab->max_ordinal); 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); lnk_chunk_set_debugf(edata->arena, name_chunk, "export: %S", name_cstr);
// push name symbol // push name symbol
String8 name_export_name = push_str8f(symtab->arena, "export.%S", name_cstr); String8 name_export_name = push_str8f(symtab->arena->v[0], "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 *name_symbol = lnk_symbol_table_push_defined_chunk(symtab, name_export_name, LNK_DefinedSymbolVisibility_Internal, 0, name_chunk, 0, 0, 0);
lnk_symbol_table_push(symtab, name_symbol);
// name voff // 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); 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
View File
@@ -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 *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_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_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 *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_table_push_defined_chunk(symtab, 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_table_push_defined_chunk(symtab, 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_table_push_defined_chunk(symtab, 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_defined_chunk(symtab, 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);
Arena *arena = arena_alloc(); Arena *arena = arena_alloc();
LNK_ImportTable *imptab = push_array(arena, LNK_ImportTable, 1); 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_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_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 *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_table_push_defined_chunk(symtab, 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_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 *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_table_push_defined_chunk(symtab, 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_table_push_defined_chunk(symtab, 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_table_push_defined_chunk(symtab, 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_table_push_defined_chunk(symtab, 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_defined_chunk(symtab, 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_ImportTableFlags flags = 0; LNK_ImportTableFlags flags = 0;
if (is_unloadable) { 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 *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()); 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); String8 ilt_symbol_name = push_str8f(symtab->arena->v[0], "%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 *ilt_symbol = lnk_symbol_table_push_defined_chunk(symtab, ilt_symbol_name, LNK_DefinedSymbolVisibility_Internal, 0, ilt_table_chunk, 0, 0, 0);
lnk_symbol_table_push(symtab, ilt_symbol);
String8 iat_symbol_name = push_str8f(symtab->arena, "%S.import_addr_table_voff", dll_name); String8 iat_symbol_name = push_str8f(symtab->arena->v[0], "%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 *iat_symbol = lnk_symbol_table_push_defined_chunk(symtab, iat_symbol_name, LNK_DefinedSymbolVisibility_Internal, 0, iat_table_chunk, 0, 0, 0);
lnk_symbol_table_push(symtab, iat_symbol);
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 *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); 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); String8 dll_name_voff_name = push_str8f(symtab->arena->v[0], "%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 *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);
lnk_symbol_table_push(symtab, dll_name_voff_symbol);
// chunk for dll directory entry // chunk for dll directory entry
PE_ImportEntry *dir = push_array(imptab->arena, PE_ImportEntry, 1); 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; imp_desc->time_stamp = 0;
// emit entry chunk // 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()); LNK_Chunk *imp_desc_chunk = lnk_section_push_chunk_data(data_sect, imptab->dll_table_chunk, imp_desc_data, str8_zero());
// emit entry symbol // emit entry symbol
String8 imp_desc_name = push_str8f(symtab->arena, "__DELAY_IMPORT_DESCRIPTOR_%S", dll_name); String8 imp_desc_name = push_str8f(symtab->arena->v[0], "__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 *imp_desc_symbol = lnk_symbol_table_push_defined_chunk(symtab, imp_desc_name, LNK_DefinedSymbolVisibility_Extern, 0, imp_desc_chunk, 0, 0, 0);
lnk_symbol_table_push(symtab, imp_desc_symbol);
// emit string table chunk // emit string table chunk
String8 int_table_chunk_debug = push_str8f(data_sect->arena, "delayed.%S.int", dll_name); 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); 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); String8 int_table_symbol_name = push_str8f(symtab->arena->v[0], "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 *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_symbol_table_push(symtab, int_table_symbol);
LNK_Chunk *null_string_chunk = lnk_section_push_chunk_list(data_sect, int_table_chunk, str8_lit("zzzzz")); 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"); lnk_chunk_set_debugf(data_sect->arena, null_string_chunk, "string table null");
// emit DLL name chunk // emit DLL name chunk
String8 name_chunk_data = push_cstr(data_sect->arena, dll_name); 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()); 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); String8 name_symbol_name = push_str8f(symtab->arena->v[0], "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 *name_symbol = lnk_symbol_table_push_defined_chunk(symtab, name_symbol_name, LNK_DefinedSymbolVisibility_Internal, 0, name_chunk, 0, 0, 0);
lnk_symbol_table_push(symtab, name_symbol);
// patch DLL name voff // 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); 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 // emit DLL handle chunk
LNK_Chunk *handle_chunk = lnk_section_push_chunk_bss(data_sect, imptab->handle_table_chunk, handle_size, str8_zero()); 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); String8 handle_name = push_str8f(symtab->arena->v[0], "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 *handle_symbol = lnk_symbol_table_push_defined_chunk(symtab, handle_name, LNK_DefinedSymbolVisibility_Internal, 0, handle_chunk, 0, 0, 0);
lnk_symbol_table_push(symtab, handle_symbol);
// patch DLL handle voff // 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); 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 // emit IAT chunk
LNK_Chunk *iat_table_chunk = lnk_section_push_chunk_list(data_sect, imptab->iat_chunk, str8_zero()); 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); String8 iat_table_name = push_str8f(symtab->arena->v[0], "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 *iat_table_symbol = lnk_symbol_table_push_defined_chunk(symtab, iat_table_name, LNK_DefinedSymbolVisibility_Internal, 0, iat_table_chunk, 0, 0, 0);
lnk_symbol_table_push(symtab, iat_table_symbol);
LNK_Chunk *null_iat_chunk = lnk_section_push_chunk_bss(data_sect, iat_table_chunk, import_size, str8_lit("zzzzzz")); 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); 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 *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); 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); String8 ilt_table_name = push_str8f(symtab->arena->v[0], "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 *ilt_table_symbol = lnk_symbol_table_push_defined_chunk(symtab, ilt_table_name, LNK_DefinedSymbolVisibility_Extern, 0, ilt_table_chunk, 0, 0, 0);
lnk_symbol_table_push(symtab, ilt_table_symbol);
// patch import address table voff // 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); 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) { if (imptab->flags & LNK_ImportTableFlag_EmitBiat) {
biat_chunk = lnk_section_push_chunk_list(data_sect, imptab->biat_chunk, str8_zero()); 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); String8 biat_symbol_name = push_str8f(symtab->arena->v[0], "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 *biat_symbol = lnk_symbol_table_push_defined_chunk(symtab, biat_symbol_name, LNK_DefinedSymbolVisibility_Internal, 0, biat_chunk, 0, 0, 0);
lnk_symbol_table_push(symtab, biat_symbol);
// patch BIAT field off // 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); 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) { if (imptab->flags & LNK_ImportTableFlag_EmitUiat) {
uiat_chunk = lnk_section_push_chunk_list(data_sect, imptab->uiat_chunk, str8_zero()); 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); String8 uiat_symbol_name = push_str8f(symtab->arena->v[0], "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 *uiat_symbol = lnk_symbol_table_push_defined_chunk(symtab, uiat_symbol_name, LNK_DefinedSymbolVisibility_Internal, 0, uiat_chunk, 0, 0, 0);
lnk_symbol_table_push(symtab, uiat_symbol);
// patch UIAT field voff // 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); 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; LNK_Chunk *tail_merge_chunk = 0;
switch (machine) { switch (machine) {
case COFF_MachineType_X64: { 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); tail_merge_chunk = lnk_emit_tail_merge_thunk_x64(code_sect, code_chunk, imp_desc_symbol, delay_load_helper_symbol);
} break; } break;
default: { 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()); LNK_Chunk *int_chunk = lnk_section_push_chunk_data(data_sect, int_table_chunk, int_data, str8_zero());
// create symbol for lookup chunk // create symbol for lookup chunk
String8 int_symbol_name = push_str8f(symtab->arena, "static.%S.%S.name", dll->name, header->func_name); String8 int_symbol_name = push_str8f(symtab->arena->v[0], "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 *int_symbol = lnk_symbol_table_push_defined_chunk(symtab, int_symbol_name, LNK_DefinedSymbolVisibility_Internal, 0, int_chunk, 0, 0, 0);
lnk_symbol_table_push(symtab, int_symbol);
// in the file IAT mirrors ILT, dynamic linker later overwrites it with imported function addresses. // 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); 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; } break;
} }
String8 ilt_symbol_name = push_str8f(symtab->arena, "static.%S.%S.ilt", dll->name, header->func_name); 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, "__imp_%S", header->func_name); String8 iat_symbol_name = push_str8f(symtab->arena->v[0], "__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 *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_make_defined_symbol_chunk(symtab->arena, iat_symbol_name, LNK_DefinedSymbolVisibility_Extern, 0, iat_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);
lnk_symbol_table_push(symtab, ilt_symbol);
lnk_symbol_table_push(symtab, iat_symbol);
// generate thunks // generate thunks
LNK_Symbol *jmp_thunk_symbol = g_null_symbol_ptr; 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); lnk_section_associate_chunks(data_sect, iat_chunk, jmp_thunk_chunk);
// push jump thunk symbol // 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); 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; } break;
default: lnk_not_implemented("TODO: support for machine 0x%X", dll->machine); 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) { if (header->type == COFF_ImportHeaderType_CODE) {
switch (dll->machine) { switch (dll->machine) {
case COFF_MachineType_X64: { case COFF_MachineType_X64: {
String8 iat_symbol_name = push_str8f(symtab->arena, "__imp_%S", 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, iat_symbol_name, LNK_SymbolScopeFlag_Main); LNK_Symbol *iat_symbol = lnk_make_undefined_symbol(symtab->arena->v[0], iat_symbol_name, LNK_SymbolScopeFlag_Main);
lnk_symbol_set_debugf(symtab->arena, iat_symbol, "x64 IAT (delayed) %S.%S", dll->name, header->func_name);
// emit jmp thunk chunk // emit jmp thunk chunk
jmp_thunk_chunk = lnk_emit_indirect_jump_thunk_x64(code_sect, code_table_chunk, iat_symbol); 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); 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 // emit load thunk
load_thunk_chunk = lnk_emit_load_thunk_x64(code_sect, code_table_chunk, iat_symbol, dll->tail_merge_symbol); 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); 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; } break;
default: lnk_not_implemented("TODO: support for machine 0x%X", dll->machine); 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()); LNK_Chunk *int_chunk = lnk_section_push_chunk_data(data_sect, int_table_chunk, int_data, str8_zero());
// create symbol for lookup chunk // create symbol for lookup chunk
String8 int_symbol_name = push_str8f(symtab->arena, "%S.%S.name.delayed", dll->name, header->func_name); String8 int_symbol_name = push_str8f(symtab->arena->v[0], "%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); int_symbol = lnk_symbol_table_push_defined_chunk(symtab, int_symbol_name, LNK_DefinedSymbolVisibility_Internal, 0, int_chunk, 0, 0, 0);
lnk_symbol_table_push(symtab, int_symbol);
// dynamic linker patches this voff on DLL load event // 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); 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); lnk_section_associate_chunks(data_sect, iat_chunk, load_thunk_chunk);
} }
String8 iat_symbol_name = push_str8f(symtab->arena, "__imp_%S", header->func_name); String8 iat_symbol_name = push_str8f(symtab->arena->v[0], "__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 *iat_symbol = lnk_symbol_table_push_defined_chunk(symtab, iat_symbol_name, LNK_DefinedSymbolVisibility_Extern, 0, iat_chunk, 0, 0, 0);
lnk_symbol_table_push(symtab, iat_symbol);
String8 ilt_symbol_name = push_str8f(symtab->arena, "%S.%S.ilt.delayed", dll->name, header->func_name); String8 ilt_symbol_name = push_str8f(symtab->arena->v[0], "%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 *ilt_symbol = lnk_symbol_table_push_defined_chunk(symtab, ilt_symbol_name, LNK_DefinedSymbolVisibility_Internal, 0, ilt_chunk, 0, 0, 0);
lnk_symbol_table_push(symtab, ilt_symbol);
// fill out import // fill out import
LNK_ImportFunc *func = push_array(imptab->arena, LNK_ImportFunc, 1); 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(); ProfBeginFunction();
// emit load thunk symbol // emit load thunk symbol
String8 load_thunk_name = push_str8f(symtab->arena, "__imp_load_%S", func_name); String8 load_thunk_name = push_str8f(symtab->arena->v[0], "__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 *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);
lnk_symbol_table_push(symtab, load_thunk_symbol);
ProfEnd(); ProfEnd();
return load_thunk_symbol; 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) lnk_emit_jmp_thunk_symbol(LNK_SymbolTable *symtab, LNK_Chunk *chunk, String8 func_name)
{ {
ProfBeginFunction(); ProfBeginFunction();
String8 jmp_thunk_name = push_str8f(symtab->arena, "%S", func_name); String8 jmp_thunk_name = push_str8f(symtab->arena->v[0], "%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 *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);
lnk_symbol_table_push(symtab, jmp_thunk_symbol);
ProfEnd(); ProfEnd();
return jmp_thunk_symbol; 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) lnk_emit_tail_merge_symbol(LNK_SymbolTable *symtab, LNK_Chunk *chunk, String8 func_name)
{ {
ProfBeginFunction(); ProfBeginFunction();
String8 tail_merge_name = push_str8f(symtab->arena, "__tailMerge_%S", func_name); String8 tail_merge_name = push_str8f(symtab->arena->v[0], "__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 *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);
lnk_symbol_table_push(symtab, tail_merge_symbol);
ProfEnd(); ProfEnd();
return tail_merge_symbol; return tail_merge_symbol;
} }
+14 -8
View File
@@ -97,6 +97,8 @@ lnk_lib_symbol_array_sort(LNK_LibSymbol *arr, U64 count)
internal LNK_Lib internal LNK_Lib
lnk_lib_from_data(Arena *arena, String8 data, String8 path) lnk_lib_from_data(Arena *arena, String8 data, String8 path)
{ {
ProfBeginFunction();
U64 symbol_count; U64 symbol_count;
String8 string_table; String8 string_table;
U32 *member_off_arr; 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.symbol_name_list = symbol_name_list;
lib.long_names = parse.long_names; lib.long_names = parse.long_names;
ProfEnd();
return lib; return lib;
} }
internal
THREAD_POOL_TASK_FUNC(lnk_lib_initer) THREAD_POOL_TASK_FUNC(lnk_lib_initer)
{ {
LNK_LibIniter *task = raw_task; LNK_LibIniter *task = raw_task;
@@ -179,6 +183,7 @@ THREAD_POOL_TASK_FUNC(lnk_lib_initer)
String8 path = task->path_arr[task_id]; String8 path = task->path_arr[task_id];
*lib = lnk_lib_from_data(arena, data, path); *lib = lnk_lib_from_data(arena, data, path);
lib->input_idx = task->base_input_idx + task_id;
} }
internal LNK_LibNodeArray 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); Assert(data_arr.count == path_arr.count);
U64 lib_count = data_arr.count; U64 lib_count = data_arr.count;
LNK_LibIniter lib_initer = {0}; LNK_LibIniter task = {0};
lib_initer.node_arr = lnk_lib_list_reserve(arena->v[0], list, lib_count); task.node_arr = lnk_lib_list_reserve(arena->v[0], list, lib_count);
lib_initer.data_arr = data_arr.v; task.data_arr = data_arr.v;
lib_initer.path_arr = path_arr.v; task.path_arr = path_arr.v;
tp_for_parallel(tp, arena, lib_count, lnk_lib_initer, &lib_initer); task.base_input_idx = list->count;
tp_for_parallel(tp, arena, lib_count, lnk_lib_initer, &task);
LNK_LibNodeArray arr; LNK_LibNodeArray arr = {0};
arr.count = lib_count; arr.count = lib_count;
arr.v = lib_initer.node_arr; arr.v = task.node_arr;
return arr; return arr;
} }
+5 -3
View File
@@ -12,6 +12,7 @@ typedef struct LNK_Lib
U32 * member_off_arr; U32 * member_off_arr;
String8List symbol_name_list; String8List symbol_name_list;
String8 long_names; String8 long_names;
U64 input_idx;
} LNK_Lib; } LNK_Lib;
typedef struct LNK_LibNode typedef struct LNK_LibNode
@@ -92,9 +93,10 @@ typedef struct LNK_LibBuild
typedef struct typedef struct
{ {
LNK_LibNode *node_arr; LNK_LibNode *node_arr;
String8 *data_arr; String8 *data_arr;
String8 *path_arr; String8 *path_arr;
U64 base_input_idx;
} LNK_LibIniter; } LNK_LibIniter;
//////////////////////////////// ////////////////////////////////
+5 -2
View File
@@ -417,7 +417,7 @@ THREAD_POOL_TASK_FUNC(lnk_obj_initer)
lnk_chunk_set_debugf(arena, master_common_block, "%S: master common block", path); lnk_chunk_set_debugf(arena, master_common_block, "%S: master common block", path);
// convert from coff // 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_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); 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->data = input->data;
obj->path = cached_path; obj->path = cached_path;
obj->lib_path = cached_lib_path; obj->lib_path = cached_lib_path;
obj->input_idx = obj_idx;
obj->machine = coff_info.machine; obj->machine = coff_info.machine;
obj->chunk_count = chunk_count; obj->chunk_count = chunk_count;
obj->sect_count = coff_info.section_count_no_null; 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 internal LNK_SymbolArray
lnk_symbol_array_from_coff(Arena *arena, lnk_symbol_array_from_coff(Arena *arena,
String8 coff_data, String8 coff_data,
LNK_Obj *obj,
String8 obj_path, String8 obj_path,
U64 string_table_off, U64 string_table_off,
U64 sect_count, 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) { for (U64 symbol_idx = 0; symbol_idx < coff_symbols.count; symbol_idx += 1) {
COFF_Symbol32 *coff_symbol = &coff_symbols.v[symbol_idx]; COFF_Symbol32 *coff_symbol = &coff_symbols.v[symbol_idx];
LNK_Symbol *symbol = &symbol_array.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); String8 name = coff_read_symbol_name(coff_data, string_table_off, &coff_symbol->name);
+2 -1
View File
@@ -32,6 +32,7 @@ typedef struct LNK_Obj
String8 data; String8 data;
String8 path; String8 path;
String8 lib_path; String8 lib_path;
U64 input_idx;
U64 common_symbol_size; U64 common_symbol_size;
COFF_MachineType machine; COFF_MachineType machine;
U64 chunk_count; 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_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_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_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_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); internal LNK_DirectiveInfo lnk_init_directives(Arena *arena, String8 obj_path, U64 chunk_count, String8 *sect_name_arr, LNK_Chunk *chunk_arr);
File diff suppressed because it is too large Load Diff
+48 -82
View File
@@ -90,27 +90,22 @@ typedef enum
LNK_Symbol_Undefined, LNK_Symbol_Undefined,
} LNK_SymbolType; } LNK_SymbolType;
#define LNK_DEBUG_SYMBOLS 1
typedef struct LNK_Symbol typedef struct LNK_Symbol
{ {
String8 name; String8 name;
LNK_SymbolType type; LNK_SymbolType type;
struct LNK_Obj *obj;
union { union {
LNK_DefinedSymbol defined; LNK_DefinedSymbol defined;
LNK_WeakSymbol weak; LNK_WeakSymbol weak;
LNK_UndefinedSymbol undefined; LNK_UndefinedSymbol undefined;
LNK_LazySymbol lazy; LNK_LazySymbol lazy;
} u; } u;
#if LNK_DEBUG_SYMBOLS
String8 debug;
#endif
} LNK_Symbol; } LNK_Symbol;
typedef struct LNK_SymbolNode typedef struct LNK_SymbolNode
{ {
struct LNK_SymbolNode *next; struct LNK_SymbolNode *next;
struct LNK_SymbolNode *prev;
U64 hash;
LNK_Symbol *data; LNK_Symbol *data;
} LNK_SymbolNode; } LNK_SymbolNode;
@@ -133,55 +128,45 @@ typedef struct LNK_SymbolArray
LNK_Symbol *v; LNK_Symbol *v;
} LNK_SymbolArray; } 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 typedef struct LNK_SymbolTable
{ {
Arena *arena; TP_Arena *arena;
U64 bucket_count[LNK_SymbolScopeIndex_Count]; LNK_SymbolHashTrie *scopes[LNK_SymbolScopeIndex_Count];
LNK_SymbolList *buckets[LNK_SymbolScopeIndex_Count]; LNK_SymbolHashTrieChunkList *chunk_lists[LNK_SymbolScopeIndex_Count];
} LNK_SymbolTable; } LNK_SymbolTable;
//////////////////////////////// ////////////////////////////////
// parallel for wrappers // 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 typedef struct
{ {
LNK_SymbolTable *symtab; LNK_SymbolTable *symtab;
LNK_SymbolList *bucket_arr; Rng1U64 *ranges;
Rng1U64 *range_arr; LNK_Symbol *arr;
} LNK_DefinedSymbolInserter;
typedef struct
{
LNK_SymbolTable *symtab;
LNK_SymbolList *bucket_arr;
Rng1U64 *range_arr;
} LNK_LazySymbolInserter; } LNK_LazySymbolInserter;
typedef struct
{
LNK_SymbolTable *symtab;
Rng1U64 *range_arr;
} LNK_ComdatFolder;
//////////////////////////////// ////////////////////////////////
extern LNK_Symbol g_null_symbol; 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_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); internal LNK_Symbol * lnk_make_lazy_symbol(Arena *arena, String8 name, struct LNK_Lib *lib, U64 member_offset);
#if LNK_DEBUG_SYMBOLS internal LNK_Chunk * lnk_chunk_from_symbol(LNK_Symbol *symbol);
#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_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 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 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 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_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_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_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 void lnk_symbol_hash_trie_insert_or_replace(Arena *arena, LNK_SymbolHashTrieChunkList *chunk_list, LNK_SymbolHashTrie **trie, U64 hash, LNK_Symbol *new_symbol);
internal U64 lnk_symbol_table_hash(String8 string); internal LNK_SymbolHashTrie * lnk_symbol_hash_trie_search(LNK_SymbolHashTrie *trie, U64 hash, String8 name);
internal LNK_SymbolNode * lnk_symbol_table_search_bucket(LNK_SymbolTable *symtab, LNK_SymbolScopeIndex scope_idx, U64 bucket_idx, String8 name, U64 hash); internal void lnk_symbol_hash_trie_remove(LNK_SymbolHashTrie *trie);
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 U64 lnk_symbol_hash(String8 string);
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_SymbolTable * lnk_symbol_table_init(TP_Arena *arena);
internal LNK_SymbolNode * lnk_symbol_table_push(LNK_SymbolTable *symtab, LNK_Symbol *symbol); internal LNK_Symbol * lnk_symbol_table_search_hash(LNK_SymbolTable *symtab, LNK_SymbolScopeFlags scope, U64 hash, String8 name);
internal void lnk_symbol_table_push_lazy_arr(TP_Context *tp, LNK_SymbolTable *symtab, LNK_Symbol *arr, U64 count); 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_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_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);