mirror of
https://github.com/Ed94/raddebugger.git
synced 2026-08-05 13:28:40 +00:00
switch to thread safe hash trie map
Initial implementation of the symbol table allowed us to push symbols from one thread at a time and required a wonky lock-step and spread out logic for replacing symbols. And because it was a externally chained hash table we had to guesstimate optimal capacity for small and big targets. We erred on the side of larger capacity to prevent degradation and rehashing, however this meant small targets had to spent unreasonable amount of time memory allocing slots. With hash trie we can dynamically scale up to 4 ^ 32 items and atomically replace symbols when needed. Neat!
This commit is contained in:
+253
-282
@@ -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 = §_node->data;
|
LNK_Section *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 = §_node->data;
|
LNK_Section *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 = §_node->data;
|
LNK_Section *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 = §_node->data;
|
LNK_Section *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 = §_arr.v[0], *sect_opl = sect + sect_arr.count; sect < sect_opl; sect += 1) {
|
for (LNK_Section *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
@@ -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;
|
||||||
|
|||||||
@@ -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
@@ -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);
|
||||||
|
|
||||||
|
|||||||
@@ -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,
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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
@@ -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
@@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|
||||||
////////////////////////////////
|
////////////////////////////////
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
+420
-509
File diff suppressed because it is too large
Load Diff
@@ -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);
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user