mirror of
https://github.com/Ed94/raddebugger.git
synced 2026-08-14 17:28:07 +00:00
WIP symbol plumbing
This commit is contained in:
@@ -457,6 +457,25 @@ cv_make_proc_refs(Arena *arena, CV_ModIndex imod, CV_SymbolList symbol_list)
|
|||||||
return proc_ref_list;
|
return proc_ref_list;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal B32
|
||||||
|
cv_is_lproc(CV_Symbol symbol)
|
||||||
|
{
|
||||||
|
return symbol.kind == CV_SymKind_LPROC32 ||
|
||||||
|
symbol.kind == CV_SymKind_LPROCMIPS ||
|
||||||
|
symbol.kind == CV_SymKind_LPROCIA64 ||
|
||||||
|
symbol.kind == CV_SymKind_LPROC32_ID ||
|
||||||
|
symbol.kind == CV_SymKind_LPROCMIPS_ID ||
|
||||||
|
symbol.kind == CV_SymKind_LPROCIA64_ID ||
|
||||||
|
symbol.kind == CV_SymKind_LPROC32_DPC ||
|
||||||
|
symbol.kind == CV_SymKind_LPROC32_DPC_ID ||
|
||||||
|
symbol.kind == CV_SymKind_LPROC16 ||
|
||||||
|
symbol.kind == CV_SymKind_LPROC32_16t ||
|
||||||
|
symbol.kind == CV_SymKind_LPROCMIPS_16t ||
|
||||||
|
symbol.kind == CV_SymKind_LPROC32_ST ||
|
||||||
|
symbol.kind == CV_SymKind_LPROCMIPS_ST ||
|
||||||
|
symbol.kind == CV_SymKind_LPROCIA64_ST;
|
||||||
|
}
|
||||||
|
|
||||||
internal B32
|
internal B32
|
||||||
cv_is_obj_info(CV_Symbol symbol)
|
cv_is_obj_info(CV_Symbol symbol)
|
||||||
{
|
{
|
||||||
@@ -1020,7 +1039,7 @@ cv_symbol_deduper_insert_or_update(void **buckets, U64 bucket_cap, U64 hash, voi
|
|||||||
U64 bucket_idx = best_idx;
|
U64 bucket_idx = best_idx;
|
||||||
do {
|
do {
|
||||||
retry:;
|
retry:;
|
||||||
void *curr_ptr = buckets + bucket_idx;
|
void *curr_ptr = buckets[bucket_idx];
|
||||||
Assert(curr_ptr != symbol_ptr);
|
Assert(curr_ptr != symbol_ptr);
|
||||||
|
|
||||||
if (curr_ptr == 0) {
|
if (curr_ptr == 0) {
|
||||||
@@ -1513,9 +1532,7 @@ cv_patch_symbol_tree_offsets_new(String8List raw_symbols, U64 base_offset, U64 a
|
|||||||
for EachNode(n, String8Node, raw_symbols.first) {
|
for EachNode(n, String8Node, raw_symbols.first) {
|
||||||
for (U64 cursor = 0, depth = 0; cursor + sizeof(CV_SymbolHeader) <= n->string.size; ) {
|
for (U64 cursor = 0, depth = 0; cursor + sizeof(CV_SymbolHeader) <= n->string.size; ) {
|
||||||
CV_Symbol symbol = {0};
|
CV_Symbol symbol = {0};
|
||||||
U64 read_size = cv_read_symbol(n->string, cursor, CV_SymbolAlign, &symbol);
|
TryReadBreak(cv_read_symbol(n->string, cursor, CV_SymbolAlign, &symbol), cursor);
|
||||||
if (read_size == 0) { break; }
|
|
||||||
cursor += read_size;
|
|
||||||
|
|
||||||
if (symbol.kind == CV_SymKind_SKIP) { continue; }
|
if (symbol.kind == CV_SymKind_SKIP) { continue; }
|
||||||
|
|
||||||
|
|||||||
@@ -408,6 +408,7 @@ internal CV_SymbolList cv_make_proc_refs(Arena *arena, CV_ModIndex imod, CV_Symb
|
|||||||
internal U64 cv_read_symbol(String8 raw_data, U64 off, U64 align, CV_Symbol *symbol_out);
|
internal U64 cv_read_symbol(String8 raw_data, U64 off, U64 align, CV_Symbol *symbol_out);
|
||||||
internal CV_Symbol cv_symbol_from_string(String8 raw_data);
|
internal CV_Symbol cv_symbol_from_string(String8 raw_data);
|
||||||
|
|
||||||
|
internal B32 cv_is_lproc(CV_Symbol symbol);
|
||||||
internal B32 cv_is_obj_info(CV_Symbol symbol);
|
internal B32 cv_is_obj_info(CV_Symbol symbol);
|
||||||
internal CV_ObjInfo cv_obj_info_from_symbol(CV_Symbol symbol);
|
internal CV_ObjInfo cv_obj_info_from_symbol(CV_Symbol symbol);
|
||||||
|
|
||||||
|
|||||||
+181
-196
@@ -30,7 +30,6 @@ THREAD_POOL_TASK_FUNC(lnk_parse_debug_s_task)
|
|||||||
U64 obj_idx = task_id;
|
U64 obj_idx = task_id;
|
||||||
LNK_CodeViewInput *task = raw_task;
|
LNK_CodeViewInput *task = raw_task;
|
||||||
|
|
||||||
LNK_Obj *obj = task->obj_arr [obj_idx];
|
|
||||||
String8List sect_list = task->debug_s_list_arr[obj_idx];
|
String8List sect_list = task->debug_s_list_arr[obj_idx];
|
||||||
CV_DebugS *debug_s = &task->debug_s_arr [obj_idx];
|
CV_DebugS *debug_s = &task->debug_s_arr [obj_idx];
|
||||||
|
|
||||||
@@ -43,14 +42,14 @@ THREAD_POOL_TASK_FUNC(lnk_parse_debug_s_task)
|
|||||||
String8List string_data_list = cv_sub_section_from_debug_s(*debug_s, CV_C13SubSectionKind_StringTable);
|
String8List string_data_list = cv_sub_section_from_debug_s(*debug_s, CV_C13SubSectionKind_StringTable);
|
||||||
if (string_data_list.node_count > 1) {
|
if (string_data_list.node_count > 1) {
|
||||||
// TODO: print section index
|
// TODO: print section index
|
||||||
lnk_error_obj(LNK_Warning_IllData, obj, ".debug$S has %u string table sub-sections defined, picking first sub-section", string_data_list.node_count);
|
lnk_error_obj(LNK_Warning_IllData, task->obj_arr[obj_idx], ".debug$S has %u string table sub-sections defined, picking first sub-section", string_data_list.node_count);
|
||||||
}
|
}
|
||||||
|
|
||||||
// make sure there is one file checksum table
|
// make sure there is one file checksum table
|
||||||
String8List checksum_data_list = cv_sub_section_from_debug_s(*debug_s, CV_C13SubSectionKind_FileChksms);
|
String8List checksum_data_list = cv_sub_section_from_debug_s(*debug_s, CV_C13SubSectionKind_FileChksms);
|
||||||
if (checksum_data_list.node_count > 1) {
|
if (checksum_data_list.node_count > 1) {
|
||||||
// TODO: print section index
|
// TODO: print section index
|
||||||
lnk_error_obj(LNK_Warning_IllData, obj, ".debug$S has %u file checksum sub-sections defined, picking first sub-section", checksum_data_list.node_count);
|
lnk_error_obj(LNK_Warning_IllData, task->obj_arr[obj_idx], ".debug$S has %u file checksum sub-sections defined, picking first sub-section", checksum_data_list.node_count);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -244,14 +243,14 @@ lnk_make_code_view_input(TP_Context *tp, TP_Arena *tp_arena, LNK_IO_Flags io_fla
|
|||||||
debug_p_arr = push_array(tp_arena->v[0], CV_DebugT, obj_count);
|
debug_p_arr = push_array(tp_arena->v[0], CV_DebugT, obj_count);
|
||||||
parse_types.raw_types = str8_array_from_list_arr(scratch.arena, input.debug_p_list_arr, obj_count);
|
parse_types.raw_types = str8_array_from_list_arr(scratch.arena, input.debug_p_list_arr, obj_count);
|
||||||
parse_types.out_types = debug_p_arr;
|
parse_types.out_types = debug_p_arr;
|
||||||
tp_for_parallel_prof(tp, 0, obj_count, lnk_strip_debug_t_sig_task, &parse_types, "Strip .debug$P");
|
tp_for_parallel_prof(tp, 0, obj_count, lnk_strip_debug_t_sig_task, &parse_types, "Strip .debug$P");
|
||||||
tp_for_parallel_prof(tp, 0, obj_count, lnk_parse_debug_t_task, &parse_types, "Parse .debug$P");
|
tp_for_parallel_prof(tp, tp_arena, obj_count, lnk_parse_debug_t_task, &parse_types, "Parse .debug$P");
|
||||||
|
|
||||||
input.debug_t_arr = push_array(tp_arena->v[0], CV_DebugT, obj_count);
|
input.debug_t_arr = push_array(tp_arena->v[0], CV_DebugT, obj_count);
|
||||||
parse_types.raw_types = str8_array_from_list_arr(scratch.arena, input.debug_t_list_arr, obj_count);
|
parse_types.raw_types = str8_array_from_list_arr(scratch.arena, input.debug_t_list_arr, obj_count);
|
||||||
parse_types.out_types = input.debug_t_arr;
|
parse_types.out_types = input.debug_t_arr;
|
||||||
tp_for_parallel_prof(tp, 0, obj_count, lnk_strip_debug_t_sig_task, &parse_types, "Strip .debug$T");
|
tp_for_parallel_prof(tp, 0, obj_count, lnk_strip_debug_t_sig_task, &parse_types, "Strip .debug$T");
|
||||||
tp_for_parallel_prof(tp, 0, obj_count, lnk_parse_debug_t_task, &parse_types, "Parse .debug$T");
|
tp_for_parallel_prof(tp, tp_arena, obj_count, lnk_parse_debug_t_task, &parse_types, "Parse .debug$T");
|
||||||
}
|
}
|
||||||
ProfEnd();
|
ProfEnd();
|
||||||
|
|
||||||
@@ -482,29 +481,25 @@ lnk_make_code_view_input(TP_Context *tp, TP_Arena *tp_arena, LNK_IO_Flags io_fla
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// :zero_out_symbol_sub_section
|
|
||||||
ProfBegin("Zero-out Symbols Sub-sections");
|
|
||||||
for EachIndex(i, obj_count) { MemoryZeroStruct(cv_sub_section_ptr_from_debug_s(&input.debug_s_arr[i], CV_C13SubSectionKind_Symbols)); }
|
|
||||||
ProfEnd();
|
|
||||||
|
|
||||||
ProfBegin("Make Symbol Inputs");
|
ProfBegin("Make Symbol Inputs");
|
||||||
{
|
{
|
||||||
|
// count symbol blocks
|
||||||
for EachIndex(obj_idx, input.count) {
|
for EachIndex(obj_idx, input.count) {
|
||||||
String8List s = cv_sub_section_from_debug_s(input.debug_s_arr[obj_idx], CV_C13SubSectionKind_Symbols);
|
String8List s = cv_sub_section_from_debug_s(input.debug_s_arr[obj_idx], CV_C13SubSectionKind_Symbols);
|
||||||
input.symbol_input_count += s.node_count;
|
input.symbol_input_count += s.node_count;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// alloc block pointers
|
||||||
input.symbol_inputs = push_array_no_zero(tp_arena->v[0], LNK_SymbolInput, input.symbol_input_count);
|
input.symbol_inputs = push_array_no_zero(tp_arena->v[0], LNK_SymbolInput, input.symbol_input_count);
|
||||||
|
|
||||||
U64 symbol_input_count = 0;
|
U64 symbol_input_count = 0;
|
||||||
for EachIndex(obj_idx, input.count) {
|
for EachIndex(obj_idx, input.count) {
|
||||||
String8List s = cv_sub_section_from_debug_s(input.debug_s_arr[obj_idx], CV_C13SubSectionKind_Symbols);
|
String8List s = cv_sub_section_from_debug_s(input.debug_s_arr[obj_idx], CV_C13SubSectionKind_Symbols);
|
||||||
for EachNode(block_n, String8Node, s.first) {
|
for EachNode(n, String8Node, s.first) {
|
||||||
Assert(symbol_input_count < input.symbol_input_count);
|
Assert(symbol_input_count < input.symbol_input_count);
|
||||||
LNK_SymbolInput *in = input.symbol_inputs + symbol_input_count;
|
LNK_SymbolInput *in = &input.symbol_inputs[symbol_input_count++];
|
||||||
in->obj_idx = obj_idx;
|
in->obj_idx = obj_idx;
|
||||||
in->raw_symbols = block_n->string;
|
in->raw_symbols = n->string;
|
||||||
symbol_input_count += 1;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1234,61 +1229,59 @@ THREAD_POOL_TASK_FUNC(lnk_fixup_symbols_task)
|
|||||||
{
|
{
|
||||||
LNK_MergeTypes *task = raw_task;
|
LNK_MergeTypes *task = raw_task;
|
||||||
|
|
||||||
U64 leaf_count_ipi = task->result.count [CV_TypeIndexSource_IPI];
|
LNK_SymbolInput symbols = task->input->symbol_inputs[task_id];
|
||||||
U8 **leaf_arr_ipi = task->result.v [CV_TypeIndexSource_IPI];
|
U64 leaf_count_ipi = task->result.count [CV_TypeIndexSource_IPI];
|
||||||
CV_TypeIndex min_ti_ipi = task->min_type_indices[CV_TypeIndexSource_IPI];
|
U8 **leaf_arr_ipi = task->result.v [CV_TypeIndexSource_IPI];
|
||||||
|
CV_TypeIndex min_ti_ipi = task->min_type_indices[CV_TypeIndexSource_IPI];
|
||||||
|
|
||||||
for EachInRange(i, task->input->symbol_input_ranges[task_id]) {
|
for (U64 cursor = 0; cursor + sizeof(CV_SymbolHeader) <= symbols.raw_symbols.size; ) {
|
||||||
LNK_SymbolInput symbols = task->input->symbol_inputs[i];
|
CV_Symbol symbol = {0};
|
||||||
|
TryReadBreak(cv_read_symbol(symbols.raw_symbols, cursor, CV_SymbolAlign, &symbol), cursor);
|
||||||
|
|
||||||
for (U64 cursor = 0; cursor + sizeof(CV_SymbolHeader) <= symbols.raw_symbols.size; ) {
|
// convert symbol to final type
|
||||||
CV_Symbol symbol = {0};
|
CV_SymKind *sym_kind_ptr = cv_kind_ptr_from_symbol(symbol);
|
||||||
TryReadBreak(cv_read_symbol(symbols.raw_symbols, cursor, CV_SymbolAlign, &symbol), cursor);
|
switch (*sym_kind_ptr) {
|
||||||
|
case CV_SymKind_PROC_ID_END: *sym_kind_ptr = CV_SymKind_END; break;
|
||||||
|
|
||||||
// convert symbol to final type
|
case CV_SymKind_LPROC32_ID: *sym_kind_ptr = CV_SymKind_LPROC32; goto fixup_id;
|
||||||
switch (symbol.kind) {
|
case CV_SymKind_GPROC32_ID: *sym_kind_ptr = CV_SymKind_GPROC32; goto fixup_id;
|
||||||
case CV_SymKind_LPROC32_ID: symbol.kind = CV_SymKind_LPROC32; goto fixup_id;
|
case CV_SymKind_LPROC32_DPC_ID: *sym_kind_ptr = CV_SymKind_LPROC32_DPC; goto fixup_id;
|
||||||
case CV_SymKind_GPROC32_ID: symbol.kind = CV_SymKind_GPROC32; goto fixup_id;
|
case CV_SymKind_LPROCMIPS_ID: *sym_kind_ptr = CV_SymKind_LPROCMIPS; goto fixup_id;
|
||||||
case CV_SymKind_LPROC32_DPC_ID: symbol.kind = CV_SymKind_LPROC32_DPC; goto fixup_id;
|
case CV_SymKind_GPROCMIPS_ID: *sym_kind_ptr = CV_SymKind_GPROCMIPS; goto fixup_id;
|
||||||
case CV_SymKind_LPROCMIPS_ID: symbol.kind = CV_SymKind_LPROCMIPS; goto fixup_id;
|
case CV_SymKind_LPROCIA64_ID: *sym_kind_ptr = CV_SymKind_LPROCIA64; goto fixup_id;
|
||||||
case CV_SymKind_GPROCMIPS_ID: symbol.kind = CV_SymKind_GPROCMIPS; goto fixup_id;
|
case CV_SymKind_GPROCIA64_ID: *sym_kind_ptr = CV_SymKind_GPROCIA64; goto fixup_id;
|
||||||
case CV_SymKind_LPROCIA64_ID: symbol.kind = CV_SymKind_LPROCIA64; goto fixup_id;
|
fixup_id:; {
|
||||||
case CV_SymKind_GPROCIA64_ID: symbol.kind = CV_SymKind_GPROCIA64; goto fixup_id;
|
CV_SymProc32 *proc32 = str8_deserial_get_raw_ptr(symbol.data, 0, sizeof(*proc32));
|
||||||
fixup_id:; {
|
if (proc32->itype < min_ti_ipi) {
|
||||||
CV_SymProc32 *proc32 = (CV_SymProc32 *) symbol.data.str;
|
// TODO: in some cases destructors don't have a type, need a repro
|
||||||
if (proc32->itype < min_ti_ipi) {
|
break;
|
||||||
// TODO: in some cases destructors don't have a type, need a repro
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((proc32->itype - min_ti_ipi) > leaf_count_ipi) {
|
|
||||||
Assert("TODO: error handle corrupted type index");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
U64 leaf_idx = proc32->itype - min_ti_ipi;
|
|
||||||
String8 leaf_data = str8(leaf_arr_ipi[leaf_idx], max_U64);
|
|
||||||
|
|
||||||
CV_Leaf leaf;
|
|
||||||
cv_read_leaf(leaf_data, 0, 1, &leaf);
|
|
||||||
|
|
||||||
U64 min_leaf_size = cv_header_struct_size_from_leaf_kind(leaf.kind);
|
|
||||||
if (min_leaf_size > leaf.data.size) {
|
|
||||||
Assert(!"TODO: error handle corrupt leaf");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (leaf.kind == CV_LeafKind_FUNC_ID) {
|
|
||||||
proc32->itype = ((CV_LeafFuncId *) leaf.data.str)->itype;
|
|
||||||
} else if (leaf.kind == CV_LeafKind_MFUNC_ID) {
|
|
||||||
proc32->itype = ((CV_LeafMFuncId *) leaf.data.str)->itype;
|
|
||||||
} else {
|
|
||||||
Assert(!"TODO: erorr handle unexpected leaf type");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} break;
|
|
||||||
case CV_SymKind_PROC_ID_END: symbol.kind = CV_SymKind_END; break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ((proc32->itype - min_ti_ipi) > leaf_count_ipi) {
|
||||||
|
Assert(0 && "TODO: error handle corrupted type index");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
U64 leaf_idx = proc32->itype - min_ti_ipi;
|
||||||
|
String8 leaf_data = str8(leaf_arr_ipi[leaf_idx], max_U64);
|
||||||
|
|
||||||
|
CV_Leaf leaf;
|
||||||
|
if (cv_read_leaf(leaf_data, 0, 1, &leaf) == 0) { InvalidPath; }
|
||||||
|
|
||||||
|
U64 min_leaf_size = cv_header_struct_size_from_leaf_kind(leaf.kind);
|
||||||
|
if (min_leaf_size > leaf.data.size) { Assert(!"TODO: error handle corrupt leaf"); break; }
|
||||||
|
|
||||||
|
if (leaf.kind == CV_LeafKind_FUNC_ID) {
|
||||||
|
CV_LeafFuncId *func_id = str8_deserial_get_raw_ptr(leaf.data, 0, sizeof(*func_id));
|
||||||
|
proc32->itype = func_id->itype;
|
||||||
|
} else if (leaf.kind == CV_LeafKind_MFUNC_ID) {
|
||||||
|
CV_LeafMFuncId *mfunc_id = str8_deserial_get_raw_ptr(leaf.data, 0, sizeof(*mfunc_id));
|
||||||
|
proc32->itype = mfunc_id->itype;
|
||||||
|
} else {
|
||||||
|
Assert(!"TODO: erorr handle unexpected leaf type");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1486,30 +1479,30 @@ lnk_merge_types(TP_Context *tp, TP_Arena *tp_temp, LNK_CodeViewInput *input)
|
|||||||
|
|
||||||
ProfEnd();
|
ProfEnd();
|
||||||
|
|
||||||
ProfBegin("Assign type indices");
|
ProfBegin("Fixup Type Indices");
|
||||||
for EachIndex(ti_source, CV_TypeIndexSource_COUNT) {
|
|
||||||
task.ti_source = ti_source;
|
|
||||||
task.assigned_type_caps[ti_source] = (task.unique_leaf_refs_arr[ti_source].count * 13) / 10;
|
|
||||||
task.assigned_type_hts [ti_source] = push_array(scratch.arena, CV_TypeIndex, task.assigned_type_caps[ti_source]);
|
|
||||||
task.min_type_indices [ti_source] = CV_MinComplexTypeIndex;
|
|
||||||
task.ranges = tp_divide_work(scratch.arena, task.unique_leaf_refs_arr[ti_source].count, tp->worker_count);
|
|
||||||
tp_for_parallel_prof(tp, 0, tp->worker_count, lnk_assign_type_indices_task, &task, "Assign Type Indices");
|
|
||||||
}
|
|
||||||
ProfEnd();
|
|
||||||
|
|
||||||
ProfBegin("Patch Type Indices");
|
|
||||||
{
|
{
|
||||||
|
ProfBegin("Assign type indices");
|
||||||
|
for EachIndex(ti_source, CV_TypeIndexSource_COUNT) {
|
||||||
|
task.ti_source = ti_source;
|
||||||
|
task.assigned_type_caps[ti_source] = (task.unique_leaf_refs_arr[ti_source].count * 13) / 10;
|
||||||
|
task.assigned_type_hts [ti_source] = push_array(scratch.arena, CV_TypeIndex, task.assigned_type_caps[ti_source]);
|
||||||
|
task.min_type_indices [ti_source] = CV_MinComplexTypeIndex;
|
||||||
|
task.ranges = tp_divide_work(scratch.arena, task.unique_leaf_refs_arr[ti_source].count, tp->worker_count);
|
||||||
|
tp_for_parallel_prof(tp, 0, tp->worker_count, lnk_assign_type_indices_task, &task, "Assign Type Indices");
|
||||||
|
}
|
||||||
|
ProfEnd();
|
||||||
|
|
||||||
task.ranges = tp_divide_work(scratch.arena, input->symbol_input_count, tp->worker_count);
|
task.ranges = tp_divide_work(scratch.arena, input->symbol_input_count, tp->worker_count);
|
||||||
tp_for_parallel_prof(tp, 0, tp->worker_count, lnk_cv_patcher_symbols_task, &task, "Symbols");
|
tp_for_parallel_prof(tp, 0, tp->worker_count, lnk_cv_patcher_symbols_task, &task, "Fixup Symbol Type Indices");
|
||||||
|
|
||||||
task.ranges = 0;
|
task.ranges = 0;
|
||||||
task.debug_s_arr = input->debug_s_arr;
|
task.debug_s_arr = input->debug_s_arr;
|
||||||
tp_for_parallel_prof(tp, 0, input->count, lnk_cv_patcher_inlines_task, &task, "Inlines");
|
tp_for_parallel_prof(tp, 0, input->count, lnk_cv_patcher_inlines_task, &task, "Fixup Inlines Type Indices");
|
||||||
|
|
||||||
for EachIndex(ti_source, CV_TypeIndexSource_COUNT) {
|
for EachIndex(ti_source, CV_TypeIndexSource_COUNT) {
|
||||||
task.ti_source = ti_source;
|
task.ti_source = ti_source;
|
||||||
task.ranges = tp_divide_work(scratch.arena, task.unique_leaf_refs_arr[ti_source].count, tp->worker_count);
|
task.ranges = tp_divide_work(scratch.arena, task.unique_leaf_refs_arr[ti_source].count, tp->worker_count);
|
||||||
tp_for_parallel_prof(tp, 0, tp->worker_count, lnk_cv_patcher_leaves_task, &task, "Leaves");
|
tp_for_parallel_prof(tp, 0, tp->worker_count, lnk_cv_patcher_leaves_task, &task, "Fixup Types Type Indices");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ProfEnd();
|
ProfEnd();
|
||||||
@@ -1523,7 +1516,7 @@ lnk_merge_types(TP_Context *tp, TP_Arena *tp_temp, LNK_CodeViewInput *input)
|
|||||||
tp_for_parallel(tp, 0, tp->worker_count, lnk_unbucket_raw_leaves_task, &task);
|
tp_for_parallel(tp, 0, tp->worker_count, lnk_unbucket_raw_leaves_task, &task);
|
||||||
}
|
}
|
||||||
|
|
||||||
tp_for_parallel_prof(tp, 0, input->symbol_input_count, lnk_fixup_symbols_task, &task, "fixup type indices in symbols");
|
tp_for_parallel_prof(tp, 0, input->symbol_input_count, lnk_fixup_symbols_task, &task, "Fixup ID Symbols");
|
||||||
|
|
||||||
MemoryCopyTyped(task.result.min_type_indices, input->min_type_indices, CV_TypeIndexSource_COUNT);
|
MemoryCopyTyped(task.result.min_type_indices, input->min_type_indices, CV_TypeIndexSource_COUNT);
|
||||||
|
|
||||||
@@ -1736,7 +1729,7 @@ lnk_replace_type_names_with_hashes(TP_Context *tp, TP_Arena *arena, U64 leaf_cou
|
|||||||
}
|
}
|
||||||
|
|
||||||
internal
|
internal
|
||||||
THREAD_POOL_TASK_FUNC(lnk_process_and_populate_gsi_and_psi_task)
|
THREAD_POOL_TASK_FUNC(lnk_build_gsi_psi)
|
||||||
{
|
{
|
||||||
Temp scratch = scratch_begin(&arena, 1);
|
Temp scratch = scratch_begin(&arena, 1);
|
||||||
|
|
||||||
@@ -1757,9 +1750,7 @@ THREAD_POOL_TASK_FUNC(lnk_process_and_populate_gsi_and_psi_task)
|
|||||||
LNK_SymbolInput symbols = task->cv->symbol_inputs[i];
|
LNK_SymbolInput symbols = task->cv->symbol_inputs[i];
|
||||||
for (U64 cursor = 0, depth = 0; cursor + sizeof(CV_SymbolHeader) <= symbols.raw_symbols.size; ) {
|
for (U64 cursor = 0, depth = 0; cursor + sizeof(CV_SymbolHeader) <= symbols.raw_symbols.size; ) {
|
||||||
CV_Symbol symbol = {0};
|
CV_Symbol symbol = {0};
|
||||||
U64 symbol_read_size = cv_read_symbol(symbols.raw_symbols, cursor, CV_SymbolAlign, &symbol);
|
TryReadBreak(cv_read_symbol(symbols.raw_symbols, cursor, CV_SymbolAlign, &symbol), cursor);
|
||||||
if (symbol_read_size == 0) { break; }
|
|
||||||
cursor += symbol_read_size;
|
|
||||||
|
|
||||||
if (cv_is_global_symbol(symbol.kind)) {
|
if (cv_is_global_symbol(symbol.kind)) {
|
||||||
void *ptr = cv_ptr_from_symbol(symbol);
|
void *ptr = cv_ptr_from_symbol(symbol);
|
||||||
@@ -1774,7 +1765,10 @@ THREAD_POOL_TASK_FUNC(lnk_process_and_populate_gsi_and_psi_task)
|
|||||||
*kind_ptr = CV_SymKind_SKIP;
|
*kind_ptr = CV_SymKind_SKIP;
|
||||||
} else if (symbol.kind == CV_SymKind_GPROC32 || symbol.kind == CV_SymKind_LPROC32) {
|
} else if (symbol.kind == CV_SymKind_GPROC32 || symbol.kind == CV_SymKind_LPROC32) {
|
||||||
String8 name = cv_name_from_symbol(symbol.kind, symbol.data);
|
String8 name = cv_name_from_symbol(symbol.kind, symbol.data);
|
||||||
task->proc_ref_sizes[task_id] += sizeof(CV_SymRef2) + name.size + 1;
|
task->proc_ref_sizes[task_id] += sizeof(CV_SymbolHeader);
|
||||||
|
task->proc_ref_sizes[task_id] += sizeof(CV_SymRef2);
|
||||||
|
task->proc_ref_sizes[task_id] += name.size + 1;
|
||||||
|
task->proc_ref_sizes[task_id] = AlignPow2(task->proc_ref_sizes[task_id], sizeof(void *));
|
||||||
task->proc_ref_counts[task_id] += 1;
|
task->proc_ref_counts[task_id] += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1786,11 +1780,11 @@ THREAD_POOL_TASK_FUNC(lnk_process_and_populate_gsi_and_psi_task)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ins_atomic_u64_add_eval(&task->total_symbol_count, global_symbols.count);
|
ins_atomic_u64_add_eval(&task->global_symbol_count, global_symbols.count);
|
||||||
barrier_wait(tp->barrier);
|
barrier_wait(tp->barrier);
|
||||||
|
|
||||||
if (task_id == 0) {
|
if (task_id == 0) {
|
||||||
task->bucket_cap = (U64)((F64)task->total_symbol_count * 1.3);
|
task->bucket_cap = (U64)((F64)task->global_symbol_count * 1.3);
|
||||||
task->buckets = push_array(scratch.arena, void *, task->bucket_cap);
|
task->buckets = push_array(scratch.arena, void *, task->bucket_cap);
|
||||||
task->insert_count = push_array(scratch.arena, U64, tp->worker_count);
|
task->insert_count = push_array(scratch.arena, U64, tp->worker_count);
|
||||||
}
|
}
|
||||||
@@ -1838,21 +1832,18 @@ THREAD_POOL_TASK_FUNC(lnk_process_and_populate_gsi_and_psi_task)
|
|||||||
barrier_wait(tp->barrier);
|
barrier_wait(tp->barrier);
|
||||||
|
|
||||||
if (task_id == 0) {
|
if (task_id == 0) {
|
||||||
// prealloc symbol nodes
|
// take into account arena header
|
||||||
CV_SymbolNode *nodes = push_array_no_zero(gsi->arena, CV_SymbolNode, task->symbol_count);
|
for EachIndex(i, tp->worker_count) { task->proc_ref_sizes[i] += ARENA_HEADER_SIZE; }
|
||||||
|
|
||||||
// push symbols to GSI
|
|
||||||
for EachIndex(i, task->symbol_count) {
|
|
||||||
CV_SymbolNode *n = &nodes[i];
|
|
||||||
n->prev = n->next = 0;
|
|
||||||
n->data = cv_symbol_from_ptr(task->symbol_arr[i]);
|
|
||||||
gsi_push_(gsi, task->symbol_hashes[i], n);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
U64 total_proc_ref_count = sum_array_u64(tp->worker_count, task->proc_ref_counts);
|
||||||
// prealloc output buffer for the proc refs
|
// prealloc output buffer for the proc refs
|
||||||
task->proc_refs.size = sum_array_u64(tp->worker_count, task->proc_ref_sizes);
|
task->proc_refs.size = sum_array_u64(tp->worker_count, task->proc_ref_sizes);
|
||||||
task->proc_refs.str = push_array(gsi->arena, U8, task->proc_refs.size);
|
task->proc_refs.str = push_array(gsi->arena, U8, task->proc_refs.size);
|
||||||
task->proc_ref_offs = offsets_from_counts_array_u64(scratch.arena, task->proc_ref_sizes, tp->worker_count);
|
task->proc_ref_hashes = push_array(scratch.arena, U64, total_proc_ref_count);
|
||||||
|
task->proc_ref_offs = offsets_from_counts_array_u64(scratch.arena, task->proc_ref_sizes, tp->worker_count);
|
||||||
|
|
||||||
|
task->proc_ref_count = sum_array_u64(tp->worker_count, task->proc_ref_counts);
|
||||||
|
task->proc_ref_nodes = push_array(gsi->arena, CV_SymbolNode, task->proc_ref_count);
|
||||||
}
|
}
|
||||||
barrier_wait(tp->barrier);
|
barrier_wait(tp->barrier);
|
||||||
|
|
||||||
@@ -1860,61 +1851,100 @@ THREAD_POOL_TASK_FUNC(lnk_process_and_populate_gsi_and_psi_task)
|
|||||||
U64 proc_refs_size = task->proc_ref_sizes[task_id];
|
U64 proc_refs_size = task->proc_ref_sizes[task_id];
|
||||||
U64 proc_refs_off = task->proc_ref_offs[task_id];
|
U64 proc_refs_off = task->proc_ref_offs[task_id];
|
||||||
U8 *proc_refs = task->proc_refs.str + proc_refs_off;
|
U8 *proc_refs = task->proc_refs.str + proc_refs_off;
|
||||||
Arena *proc_ref_arena = arena_alloc_(&(ArenaParams){ .optional_backing_buffer = proc_refs,
|
Arena *proc_ref_arena = arena_alloc_(&(ArenaParams){ .flags = ArenaFlag_NoChain, .optional_backing_buffer = proc_refs, .reserve_size = proc_refs_size, .commit_size = proc_refs_size });
|
||||||
.reserve_size = proc_refs_size,
|
|
||||||
.commit_size = proc_refs_size
|
U64 proc_ref_idx = task->proc_ref_offs[task_id];
|
||||||
});
|
|
||||||
U64 hash_idx = 0;
|
|
||||||
for EachInRange(i, task->cv->symbol_input_ranges[task_id]) {
|
for EachInRange(i, task->cv->symbol_input_ranges[task_id]) {
|
||||||
LNK_SymbolInput *in = &task->cv->symbol_inputs[i];
|
LNK_SymbolInput *in = &task->cv->symbol_inputs[i];
|
||||||
String8 raw_symbols = in->raw_symbols;
|
String8 raw_symbols = in->raw_symbols;
|
||||||
CV_ModIndex imod = task->mod_arr[in->obj_idx]->imod;
|
CV_ModIndex imod = task->mod_arr[in->obj_idx]->imod;
|
||||||
for (U64 cursor = 0, depth = 0; cursor + sizeof(CV_SymbolHeader) <= raw_symbols.size; ) {
|
for (U64 cursor = 0; cursor + sizeof(CV_SymbolHeader) <= raw_symbols.size; ) {
|
||||||
CV_Symbol symbol = {0};
|
CV_Symbol symbol = {0};
|
||||||
U64 read_size = cv_read_symbol(raw_symbols, cursor, CV_SymbolAlign, &symbol);
|
TryReadBreak(cv_read_symbol(raw_symbols, cursor, CV_SymbolAlign, &symbol), cursor);
|
||||||
if (read_size == 0) { break; }
|
|
||||||
cursor += read_size;
|
|
||||||
if (symbol.kind == CV_SymKind_GPROC32 || symbol.kind == CV_SymKind_LPROC32) {
|
if (symbol.kind == CV_SymKind_GPROC32 || symbol.kind == CV_SymKind_LPROC32) {
|
||||||
String8 name = cv_name_from_symbol(symbol.kind, symbol.data);
|
Temp temp = temp_begin(task->fixed_arenas[task_id]);
|
||||||
CV_Symbol proc_ref = cv_make_proc_ref(proc_ref_arena, imod, safe_cast_u32(symbol.offset), name, /* is_local */ 1);
|
|
||||||
task->proc_ref_hashes[hash_idx] = hash_from_cv_symbol(&proc_ref);
|
String8 name = cv_name_from_symbol(symbol.kind, symbol.data);
|
||||||
hash_idx += 1;
|
CV_Symbol proc_ref_symbol = cv_make_proc_ref(temp.arena, imod, safe_cast_u32(symbol.offset), name, cv_is_lproc(symbol));
|
||||||
|
String8 proc_ref_raw = cv_data_from_symbol(proc_ref_arena, &proc_ref_symbol, 1);
|
||||||
|
|
||||||
|
CV_SymbolNode *n = &task->proc_ref_nodes[proc_ref_idx++];
|
||||||
|
n->data = cv_symbol_from_ptr(proc_ref_raw.str);
|
||||||
|
|
||||||
|
task->proc_ref_hashes[proc_ref_idx] = hash_from_cv_symbol(&n->data);
|
||||||
|
|
||||||
|
temp_end(temp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
barrier_wait(tp->barrier);
|
barrier_wait(tp->barrier);
|
||||||
|
|
||||||
if (task_id == 0) {
|
if (task_id == 0) {
|
||||||
U64 *offsets = offsets_from_counts_array_u64(scratch.arena, task->proc_ref_sizes, tp->worker_count);
|
// push global symbols
|
||||||
for EachIndex(i, tp->worker_count) {
|
{
|
||||||
CV_SymbolNode *nodes = push_array(gsi->arena, CV_SymbolNode, task->proc_ref_counts[i]);
|
CV_SymbolNode *nodes = push_array_no_zero(gsi->arena, CV_SymbolNode, task->symbol_count);
|
||||||
U64 node_idx = 0;
|
for EachIndex(i, task->symbol_count) {
|
||||||
for (U64 cursor = offsets[i]; cursor < offsets[i+1]; ) {
|
CV_SymbolNode *n = &nodes[i];
|
||||||
U64 read_size = cv_read_symbol(task->proc_refs, cursor, PDB_SYMBOL_ALIGN, &nodes[node_idx].data);
|
n->prev = n->next = 0;
|
||||||
if (read_size == 0) { break; }
|
n->data = cv_symbol_from_ptr(task->symbol_arr[i]);
|
||||||
cursor += read_size;
|
gsi_push_(gsi, task->symbol_hashes[i], n);
|
||||||
gsi_push_(gsi, task->proc_ref_hashes[node_idx], &nodes[node_idx]);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// push proc refs
|
||||||
|
for EachIndex(i, task->proc_ref_count) {
|
||||||
|
gsi_push_(gsi, task->proc_ref_hashes[i], &task->proc_ref_nodes[i]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
barrier_wait(tp->barrier);
|
barrier_wait(tp->barrier);
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
|
if (task_id == 0) {
|
||||||
|
task->public_symbol_sizes = push_array(scratch.arena, U64, tp->worker_count);
|
||||||
|
task->public_symbol_node_counts = push_array(scratch.arena, U64, tp->worker_count);
|
||||||
|
}
|
||||||
|
barrier_wait(tp->barrier);
|
||||||
|
|
||||||
|
// compute buffer size for CV public symbols
|
||||||
for EachNode(chunk, LNK_SymbolHashTrieChunk, task->symtab->chunks[task_id].first) {
|
for EachNode(chunk, LNK_SymbolHashTrieChunk, task->symtab->chunks[task_id].first) {
|
||||||
task->public_symbol_node_counts[task_id] += chunk->count;
|
for EachIndex(i, chunk->count) {
|
||||||
|
LNK_Symbol *symbol = chunk->v[i].symbol;
|
||||||
|
LNK_ObjSymbolRef symbol_ref = lnk_ref_from_symbol(symbol);
|
||||||
|
COFF_ParsedSymbol symbol_parsed = lnk_parsed_from_symbol(symbol);
|
||||||
|
|
||||||
|
if (symbol_parsed.section_number == lnk_obj_get_removed_section_number(symbol_ref.obj)) { continue; }
|
||||||
|
COFF_SymbolValueInterpType symbol_interp = coff_interp_from_parsed_symbol(symbol_parsed);
|
||||||
|
if (symbol_interp != COFF_SymbolValueInterp_Regular) { continue; }
|
||||||
|
|
||||||
|
task->public_symbol_sizes[task_id] += sizeof(CV_SymbolHeader);
|
||||||
|
task->public_symbol_sizes[task_id] += sizeof(CV_SymPub32);
|
||||||
|
task->public_symbol_sizes[task_id] += symbol->name.size + 1;
|
||||||
|
task->public_symbol_sizes[task_id] = AlignPow2(task->public_symbol_sizes[task_id], sizeof(void *));
|
||||||
|
|
||||||
|
task->public_symbol_node_counts[task_id] += 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
barrier_wait(tp->barrier);
|
barrier_wait(tp->barrier);
|
||||||
|
|
||||||
if (task_id == 0) {
|
if (task_id == 0) {
|
||||||
|
for EachIndex(i, tp->worker_count) { task->public_symbol_sizes[i] += ARENA_HEADER_SIZE; }
|
||||||
|
U64 public_symbol_buffer_size = sum_array_u64(tp->worker_count, task->public_symbol_sizes);
|
||||||
|
task->public_symbol_offs = offsets_from_counts_array_u64(scratch.arena, task->public_symbol_sizes, tp->worker_count);
|
||||||
|
task->public_symbol_buffer = push_array(task->pdb->psi->arena, U8, public_symbol_buffer_size);
|
||||||
|
|
||||||
|
U64 public_symbol_total_count = sum_array_u64(tp->worker_count, task->public_symbol_node_counts);
|
||||||
task->public_symbol_node_offsets = offsets_from_counts_array_u64(scratch.arena, task->public_symbol_node_counts, tp->worker_count);
|
task->public_symbol_node_offsets = offsets_from_counts_array_u64(scratch.arena, task->public_symbol_node_counts, tp->worker_count);
|
||||||
U64 public_symbol_total_count = sum_array_u64(tp->worker_count, task->public_symbol_node_offsets);
|
|
||||||
task->public_symbol_nodes = push_array(psi->gsi->arena, CV_SymbolNode, public_symbol_total_count);
|
task->public_symbol_nodes = push_array(psi->gsi->arena, CV_SymbolNode, public_symbol_total_count);
|
||||||
task->public_symbols = push_array(scratch.arena, CV_SymbolList, tp->worker_count);
|
task->public_symbols = push_array(scratch.arena, CV_SymbolList, tp->worker_count);
|
||||||
task->public_symbols = push_array(scratch.arena, CV_SymbolList, tp->worker_count);
|
task->public_symbol_hashes = push_array(scratch.arena, U32 *, tp->worker_count);
|
||||||
}
|
}
|
||||||
barrier_wait(tp->barrier);
|
barrier_wait(tp->barrier);
|
||||||
|
|
||||||
|
// make CV public symbols
|
||||||
|
U64 public_symbol_buffer_chunk_size = task->public_symbol_sizes[task_id];
|
||||||
|
U8 *public_symbol_buffer_chunk = task->public_symbol_buffer + task->public_symbol_offs[task_id];
|
||||||
|
Arena *public_symbol_arena = arena_alloc_(&(ArenaParams){ .flags = ArenaFlag_NoChain, .optional_backing_buffer = public_symbol_buffer_chunk, .reserve_size = public_symbol_buffer_chunk_size, .commit_size = public_symbol_buffer_chunk_size });
|
||||||
for EachNode(chunk, LNK_SymbolHashTrieChunk, task->symtab->chunks[task_id].first) {
|
for EachNode(chunk, LNK_SymbolHashTrieChunk, task->symtab->chunks[task_id].first) {
|
||||||
U64 node_idx = task->public_symbol_node_offsets[task_id];
|
U64 node_idx = task->public_symbol_node_offsets[task_id];
|
||||||
for EachIndex(i, chunk->count) {
|
for EachIndex(i, chunk->count) {
|
||||||
@@ -1922,47 +1952,46 @@ THREAD_POOL_TASK_FUNC(lnk_process_and_populate_gsi_and_psi_task)
|
|||||||
LNK_ObjSymbolRef symbol_ref = lnk_ref_from_symbol(symbol);
|
LNK_ObjSymbolRef symbol_ref = lnk_ref_from_symbol(symbol);
|
||||||
COFF_ParsedSymbol symbol_parsed = lnk_parsed_from_symbol(symbol);
|
COFF_ParsedSymbol symbol_parsed = lnk_parsed_from_symbol(symbol);
|
||||||
|
|
||||||
|
// discard removed and non-section symbols
|
||||||
if (symbol_parsed.section_number == lnk_obj_get_removed_section_number(symbol_ref.obj)) { continue; }
|
if (symbol_parsed.section_number == lnk_obj_get_removed_section_number(symbol_ref.obj)) { continue; }
|
||||||
|
|
||||||
COFF_SymbolValueInterpType symbol_interp = coff_interp_from_parsed_symbol(symbol_parsed);
|
COFF_SymbolValueInterpType symbol_interp = coff_interp_from_parsed_symbol(symbol_parsed);
|
||||||
if (symbol_interp != COFF_SymbolValueInterp_Regular) { continue; }
|
if (symbol_interp != COFF_SymbolValueInterp_Regular) { continue; }
|
||||||
|
|
||||||
CV_Pub32Flags flags = 0;
|
Temp temp = temp_begin(task->fixed_arenas[task_id]);
|
||||||
if (COFF_SymbolType_IsFunc(symbol_parsed.type)) { flags |= CV_Pub32Flag_Function; }
|
|
||||||
|
|
||||||
ISectOff sc = lnk_sc_from_symbol(symbol);
|
CV_Pub32Flags flags = COFF_SymbolType_IsFunc(symbol_parsed.type) ? CV_Pub32Flag_Function : 0;
|
||||||
U16 symbol_isect16 = safe_cast_u16(sc.isect);
|
ISectOff sc = lnk_sc_from_symbol(symbol);
|
||||||
U32 symbol_off32 = safe_cast_u32(sc.off);
|
CV_Symbol pub_symbol = cv_make_pub32(temp.arena, flags, safe_cast_u32(sc.off), safe_cast_u16(sc.isect), symbol->name);
|
||||||
|
String8 pub_raw = cv_data_from_symbol(public_symbol_arena, &pub_symbol, 1);
|
||||||
|
|
||||||
task->public_symbol_nodes[node_idx].data = cv_make_pub32(arena, flags, symbol_off32, symbol_isect16, symbol->name);
|
task->public_symbol_nodes[node_idx].data = cv_symbol_from_ptr(pub_raw.str);
|
||||||
cv_symbol_list_push_node(&task->public_symbols[task_id], &task->public_symbol_nodes[node_idx]);
|
cv_symbol_list_push_node(&task->public_symbols[task_id], &task->public_symbol_nodes[node_idx]);
|
||||||
node_idx += 1;
|
node_idx += 1;
|
||||||
|
|
||||||
|
temp_end(temp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
barrier_wait(tp->barrier);
|
barrier_wait(tp->barrier);
|
||||||
|
|
||||||
if (task_id == 0) {
|
// hash public symbols
|
||||||
task->public_symbol_hashes = push_array(scratch.arena, U32 *, tp->worker_count);
|
|
||||||
}
|
|
||||||
barrier_wait(tp->barrier);
|
|
||||||
|
|
||||||
{
|
{
|
||||||
U64 n_idx = 0;
|
U64 n_idx = 0;
|
||||||
task->public_symbol_hashes[task_id] = push_array(scratch.arena, U32, task->public_symbols[task_id].count);
|
task->public_symbol_hashes[task_id] = push_array(scratch.arena, U32, task->public_symbols[task_id].count);
|
||||||
for EachNode(n, CV_SymbolNode, task->public_symbols[task_id].first) {
|
for EachNode(n, CV_SymbolNode, task->public_symbols[task_id].first) {
|
||||||
String8 name = cv_name_from_symbol(n->data.kind, n->data.data);
|
String8 name = cv_name_from_symbol(n->data.kind, n->data.data);
|
||||||
task->public_symbol_hashes[task_id][n_idx] = gsi_hash(gsi, name);
|
task->public_symbol_hashes[task_id][n_idx++] = gsi_hash(gsi, name);
|
||||||
n += 1;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
barrier_wait(tp->barrier);
|
barrier_wait(tp->barrier);
|
||||||
|
|
||||||
|
// insert public symbols into PSI
|
||||||
if (task_id == 0) {
|
if (task_id == 0) {
|
||||||
for EachIndex(i, tp->worker_count) {
|
for EachIndex(i, tp->worker_count) {
|
||||||
U64 curr_idx = 0;
|
U64 curr_idx = 0;
|
||||||
for (CV_SymbolNode *curr = task->public_symbols[i].first, *next = 0; curr != 0; curr = next, curr_idx += 1) {
|
for (CV_SymbolNode *curr = task->public_symbols[i].first, *next = 0; curr != 0; curr = next) {
|
||||||
next = curr->next;
|
next = curr->next;
|
||||||
gsi_push_(psi->gsi, task->public_symbol_hashes[i][curr_idx], curr);
|
gsi_push_(psi->gsi, task->public_symbol_hashes[i][curr_idx], curr);
|
||||||
|
curr_idx += 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2043,6 +2072,8 @@ THREAD_POOL_TASK_FUNC(lnk_write_pdb_module_stream)
|
|||||||
CV_Symbol symbol = {0};
|
CV_Symbol symbol = {0};
|
||||||
TryReadBreak(cv_read_symbol(n->string, cursor, CV_SymbolAlign, &symbol), cursor);
|
TryReadBreak(cv_read_symbol(n->string, cursor, CV_SymbolAlign, &symbol), cursor);
|
||||||
|
|
||||||
|
if (symbol.kind == CV_SymKind_SKIP) { continue; }
|
||||||
|
|
||||||
U64 symbol_size = cv_size_from_symbol(&symbol, PDB_SYMBOL_ALIGN);
|
U64 symbol_size = cv_size_from_symbol(&symbol, PDB_SYMBOL_ALIGN);
|
||||||
|
|
||||||
// flush temp to MSF
|
// flush temp to MSF
|
||||||
@@ -2194,41 +2225,6 @@ THREAD_POOL_TASK_FUNC(lnk_push_dbi_sec_contrib_task)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal
|
|
||||||
THREAD_POOL_TASK_FUNC(lnk_build_pdb_public_symbols_defined_task)
|
|
||||||
{
|
|
||||||
ProfBeginFunction();
|
|
||||||
|
|
||||||
LNK_BuildPdb *task = raw_task;
|
|
||||||
for EachNode(chunk, LNK_SymbolHashTrieChunk, task->symtab->chunks[task_id].first) {
|
|
||||||
CV_SymbolNode *nodes = push_array_no_zero(arena, CV_SymbolNode, chunk->count);
|
|
||||||
U64 node_idx = 0;
|
|
||||||
for EachIndex(i, chunk->count) {
|
|
||||||
LNK_Symbol *symbol = chunk->v[i].symbol;
|
|
||||||
LNK_ObjSymbolRef symbol_ref = lnk_ref_from_symbol(symbol);
|
|
||||||
COFF_ParsedSymbol symbol_parsed = lnk_parsed_from_symbol(symbol);
|
|
||||||
|
|
||||||
if (symbol_parsed.section_number == lnk_obj_get_removed_section_number(symbol_ref.obj)) { continue; }
|
|
||||||
|
|
||||||
COFF_SymbolValueInterpType symbol_interp = coff_interp_from_parsed_symbol(symbol_parsed);
|
|
||||||
if (symbol_interp != COFF_SymbolValueInterp_Regular) { continue; }
|
|
||||||
|
|
||||||
CV_Pub32Flags flags = 0;
|
|
||||||
if (COFF_SymbolType_IsFunc(symbol_parsed.type)) { flags |= CV_Pub32Flag_Function; }
|
|
||||||
|
|
||||||
ISectOff sc = lnk_sc_from_symbol(symbol);
|
|
||||||
U16 symbol_isect16 = safe_cast_u16(sc.isect);
|
|
||||||
U32 symbol_off32 = safe_cast_u32(sc.off);
|
|
||||||
|
|
||||||
nodes[node_idx].data = cv_make_pub32(arena, flags, symbol_off32, symbol_isect16, symbol->name);
|
|
||||||
cv_symbol_list_push_node(&task->pub_list_arr[task_id], &nodes[node_idx]);
|
|
||||||
node_idx += 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ProfEnd();
|
|
||||||
}
|
|
||||||
|
|
||||||
internal String8List
|
internal String8List
|
||||||
lnk_build_pdb(TP_Context *tp, TP_Arena *tp_arena, String8 image_data, LNK_Config *config, LNK_SymbolTable *symtab, LNK_CodeViewInput *cv, LNK_MergedTypes cv_types)
|
lnk_build_pdb(TP_Context *tp, TP_Arena *tp_arena, String8 image_data, LNK_Config *config, LNK_SymbolTable *symtab, LNK_CodeViewInput *cv, LNK_MergedTypes cv_types)
|
||||||
{
|
{
|
||||||
@@ -2240,10 +2236,11 @@ lnk_build_pdb(TP_Context *tp, TP_Arena *tp_arena, String8 image_data, LNK_Config
|
|||||||
U64 obj_count = cv->obj_count;
|
U64 obj_count = cv->obj_count;
|
||||||
|
|
||||||
LNK_BuildPdb task = {
|
LNK_BuildPdb task = {
|
||||||
.image_data = image_data,
|
.image_data = image_data,
|
||||||
.symtab = symtab,
|
.symtab = symtab,
|
||||||
.cv = cv,
|
.cv = cv,
|
||||||
.pdb = pdb_alloc_(huge_arena_temp.arena, config->pdb_page_size, config->machine, config->time_stamp, config->age, config->guid),
|
.pdb = pdb_alloc_(huge_arena_temp.arena, config->pdb_page_size, config->machine, config->time_stamp, config->age, config->guid),
|
||||||
|
.fixed_arenas = alloc_fixed_size_arena_array(scratch.arena, tp->worker_count, max_U16, max_U16),
|
||||||
};
|
};
|
||||||
|
|
||||||
// set min type indices
|
// set min type indices
|
||||||
@@ -2263,7 +2260,7 @@ lnk_build_pdb(TP_Context *tp, TP_Arena *tp_arena, String8 image_data, LNK_Config
|
|||||||
task.serialized_symbol_data_sizes = push_array(scratch.arena, U64, obj_count);
|
task.serialized_symbol_data_sizes = push_array(scratch.arena, U64, obj_count);
|
||||||
ProfScope("Make GSI/PSI")
|
ProfScope("Make GSI/PSI")
|
||||||
{
|
{
|
||||||
ProfScope("Process & Populate GSI/PSI") tp_for_parallel(tp, 0, tp->worker_count, lnk_process_and_populate_gsi_and_psi_task, &task);
|
ProfScope("Process & Populate GSI/PSI") tp_for_parallel(tp, 0, tp->worker_count, lnk_build_gsi_psi, &task);
|
||||||
|
|
||||||
ProfBegin("Build and write GSI/PSI");
|
ProfBegin("Build and write GSI/PSI");
|
||||||
PDB_Context *pdb = task.pdb;
|
PDB_Context *pdb = task.pdb;
|
||||||
@@ -2369,18 +2366,6 @@ lnk_build_pdb(TP_Context *tp, TP_Arena *tp_arena, String8 image_data, LNK_Config
|
|||||||
dbi_sec_list_concat_arr(&task.pdb->dbi->sec_contrib_list, obj_count, task.sc_list);
|
dbi_sec_list_concat_arr(&task.pdb->dbi->sec_contrib_list, obj_count, task.sc_list);
|
||||||
}
|
}
|
||||||
ProfEnd();
|
ProfEnd();
|
||||||
|
|
||||||
ProfBegin("Make Public Symbols");
|
|
||||||
{
|
|
||||||
task.pub_list_arr = push_array(scratch.arena, CV_SymbolList, tp->worker_count);
|
|
||||||
tp_for_parallel_prof(tp, tp_arena, tp->worker_count, lnk_build_pdb_public_symbols_defined_task, &task, "Defined");
|
|
||||||
|
|
||||||
ProfBegin("GSI Push");
|
|
||||||
CV_SymbolPtrArray symbols = cv_symbol_ptr_array_from_list(scratch.arena, tp, tp->worker_count, task.pub_list_arr);
|
|
||||||
gsi_push_many_arr(tp, task.pdb->psi->gsi, symbols.count, symbols.v);
|
|
||||||
ProfEnd();
|
|
||||||
}
|
|
||||||
ProfEnd();
|
|
||||||
|
|
||||||
ProfBegin("Build NatVis");
|
ProfBegin("Build NatVis");
|
||||||
{
|
{
|
||||||
|
|||||||
+30
-18
@@ -3,7 +3,8 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
// --- Code View Input ---------------------------------------------------------
|
////////////////////////////////
|
||||||
|
// CodeView
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
@@ -48,9 +49,9 @@ typedef struct
|
|||||||
B32 *is_type_server_discarded; // [ts_arr.count]
|
B32 *is_type_server_discarded; // [ts_arr.count]
|
||||||
CV_TypeIndex min_type_indices[CV_TypeIndexSource_COUNT];
|
CV_TypeIndex min_type_indices[CV_TypeIndexSource_COUNT];
|
||||||
|
|
||||||
U64 symbol_input_count;
|
U64 symbol_input_count;
|
||||||
struct LNK_SymbolInput *symbol_inputs; // [symbol_input_count]
|
LNK_SymbolInput *symbol_inputs; // [symbol_input_count]
|
||||||
Rng1U64 *symbol_input_ranges; // [worker_count]
|
Rng1U64 *symbol_input_ranges; // [worker_count]
|
||||||
} LNK_CodeViewInput;
|
} LNK_CodeViewInput;
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
@@ -60,7 +61,8 @@ typedef struct
|
|||||||
CV_DebugT *out_types; // [obj_count]
|
CV_DebugT *out_types; // [obj_count]
|
||||||
} LNK_ParseCvTypes;
|
} LNK_ParseCvTypes;
|
||||||
|
|
||||||
// --- Leaf Deduping Tasks -----------------------------------------------------
|
////////////////////////////////
|
||||||
|
// Type Merging
|
||||||
|
|
||||||
typedef struct { U32 obj_idx; U32 leaf_idx; } LNK_LeafRef;
|
typedef struct { U32 obj_idx; U32 leaf_idx; } LNK_LeafRef;
|
||||||
typedef struct { U64 count; LNK_LeafRef **v; } LNK_LeafRefArray;
|
typedef struct { U64 count; LNK_LeafRef **v; } LNK_LeafRefArray;
|
||||||
@@ -123,7 +125,8 @@ typedef struct
|
|||||||
LNK_MergedTypes result;
|
LNK_MergedTypes result;
|
||||||
} LNK_MergeTypes;
|
} LNK_MergeTypes;
|
||||||
|
|
||||||
// --- Build PDB ---------------------------------------------
|
////////////////////////////////
|
||||||
|
// PDB
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
@@ -134,9 +137,10 @@ typedef struct
|
|||||||
PDB_Context *pdb;
|
PDB_Context *pdb;
|
||||||
PDB_DbiModule **mod_arr; // [obj_count]
|
PDB_DbiModule **mod_arr; // [obj_count]
|
||||||
|
|
||||||
U64 total_symbol_count;
|
Arena **fixed_arenas;
|
||||||
|
|
||||||
// GSI symbol dedup
|
// GSI symbol dedup
|
||||||
|
U64 global_symbol_count;
|
||||||
U64 bucket_cap;
|
U64 bucket_cap;
|
||||||
void **buckets; // [bucket_count]
|
void **buckets; // [bucket_count]
|
||||||
U64 *insert_count; // [worker_count]
|
U64 *insert_count; // [worker_count]
|
||||||
@@ -146,12 +150,18 @@ typedef struct
|
|||||||
void **symbol_arr;
|
void **symbol_arr;
|
||||||
U32 *symbol_hashes; // [symbol_count]
|
U32 *symbol_hashes; // [symbol_count]
|
||||||
|
|
||||||
U64 *proc_ref_counts; // [worker_count]
|
U64 *proc_ref_counts; // [worker_count]
|
||||||
U64 *proc_ref_sizes; // [worker_count]
|
U64 *proc_ref_sizes; // [worker_count]
|
||||||
U64 *proc_ref_hashes; // [total_proc_ref_count]
|
U64 *proc_ref_hashes; // [total_proc_ref_count]
|
||||||
U64 *proc_ref_offs; // [worker_count]
|
U64 *proc_ref_offs; // [worker_count]
|
||||||
String8 proc_refs;
|
String8 proc_refs;
|
||||||
|
U64 proc_ref_count;
|
||||||
|
CV_SymbolNode *proc_ref_nodes; // [proc_ref_count]
|
||||||
|
Arena *proc_ref_arena;
|
||||||
|
|
||||||
|
U64 *public_symbol_sizes; // [worker_count]
|
||||||
|
U64 *public_symbol_offs; // [worker_count]
|
||||||
|
U8 *public_symbol_buffer;
|
||||||
U64 *public_symbol_node_counts; // [worker_count]
|
U64 *public_symbol_node_counts; // [worker_count]
|
||||||
U64 *public_symbol_node_offsets; // [worker_count]
|
U64 *public_symbol_node_offsets; // [worker_count]
|
||||||
CV_SymbolNode *public_symbol_nodes; // [public_symbol_total_count]
|
CV_SymbolNode *public_symbol_nodes; // [public_symbol_total_count]
|
||||||
@@ -192,7 +202,8 @@ typedef struct
|
|||||||
String8List *maps;
|
String8List *maps;
|
||||||
} LNK_TypeNameReplacer;
|
} LNK_TypeNameReplacer;
|
||||||
|
|
||||||
// --- RAD Debug Info ----------------------------------------------------------
|
////////////////////////////////
|
||||||
|
// RDI
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
@@ -219,8 +230,6 @@ typedef struct
|
|||||||
CV_TypeIndex *fwdmap;
|
CV_TypeIndex *fwdmap;
|
||||||
} LNK_BuildUDTFwdMapTask;
|
} LNK_BuildUDTFwdMapTask;
|
||||||
|
|
||||||
// --- RDI Conversion Tasks ----------------------------------------------------
|
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
U64 leaf_count[CV_TypeIndexSource_COUNT];
|
U64 leaf_count[CV_TypeIndexSource_COUNT];
|
||||||
@@ -307,7 +316,8 @@ typedef struct
|
|||||||
RDIB_LineTableChunkList *line_tables;
|
RDIB_LineTableChunkList *line_tables;
|
||||||
} LNK_ConvertUnitToRDITask;
|
} LNK_ConvertUnitToRDITask;
|
||||||
|
|
||||||
// --- CodeView ----------------------------------------------------------------
|
////////////////////////////////
|
||||||
|
// CodeView
|
||||||
|
|
||||||
internal LNK_CodeViewInput lnk_make_code_view_input(TP_Context *tp, TP_Arena *tp_arena, LNK_IO_Flags io_flags, String8List lib_dir_list, String8List alt_pch_dirs, U64 objs_count, LNK_Obj **objs);
|
internal LNK_CodeViewInput lnk_make_code_view_input(TP_Context *tp, TP_Arena *tp_arena, LNK_IO_Flags io_flags, String8List lib_dir_list, String8List alt_pch_dirs, U64 objs_count, LNK_Obj **objs);
|
||||||
|
|
||||||
@@ -321,11 +331,13 @@ internal LNK_LeafRef * lnk_leaf_hash_table_search (LNK_LeafHashTable
|
|||||||
internal LNK_MergedTypes lnk_merge_types (TP_Context *tp, TP_Arena *tp_temp, LNK_CodeViewInput *input);
|
internal LNK_MergedTypes lnk_merge_types (TP_Context *tp, TP_Arena *tp_temp, LNK_CodeViewInput *input);
|
||||||
internal void lnk_replace_type_names_with_hashes (TP_Context *tp, TP_Arena *arena, U64 leaf_count, U8 **leaf_arr, LNK_TypeNameHashMode mode, U64 hash_length, String8 map_name);
|
internal void lnk_replace_type_names_with_hashes (TP_Context *tp, TP_Arena *arena, U64 leaf_count, U8 **leaf_arr, LNK_TypeNameHashMode mode, U64 hash_length, String8 map_name);
|
||||||
|
|
||||||
// --- PDB ---------------------------------------------------------------------
|
////////////////////////////////
|
||||||
|
// PDB
|
||||||
|
|
||||||
internal String8List lnk_build_pdb(TP_Context *tp, TP_Arena *tp_arena, String8 image_data, LNK_Config *config, LNK_SymbolTable *symtab, LNK_CodeViewInput *cv, LNK_MergedTypes cv_types);
|
internal String8List lnk_build_pdb(TP_Context *tp, TP_Arena *tp_arena, String8 image_data, LNK_Config *config, LNK_SymbolTable *symtab, LNK_CodeViewInput *cv, LNK_MergedTypes cv_types);
|
||||||
|
|
||||||
// --- RDI ---------------------------------------------------------------------
|
////////////////////////////////
|
||||||
|
// RDI
|
||||||
|
|
||||||
internal U64 lnk_udt_name_hash_table_hash (String8 string);
|
internal U64 lnk_udt_name_hash_table_hash (String8 string);
|
||||||
internal LNK_UDTNameBucket ** lnk_udt_name_hash_table_from_leaf_arr(TP_Context *tp, TP_Arena *arena, U64 leaf_count, U8 **leaf_arr, U64 *buckets_cap_out);
|
internal LNK_UDTNameBucket ** lnk_udt_name_hash_table_from_leaf_arr(TP_Context *tp, TP_Arena *arena, U64 leaf_count, U8 **leaf_arr, U64 *buckets_cap_out);
|
||||||
|
|||||||
Reference in New Issue
Block a user