mirror of
https://github.com/Ed94/raddebugger.git
synced 2026-08-14 17:28:07 +00:00
serialize symbols directly into MSF streams
This commit is contained in:
@@ -545,6 +545,40 @@ cv_data_c13_from_debug_s(Arena *arena, CV_DebugS *debug_s, B32 write_sig)
|
|||||||
return srl;
|
return srl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal U64
|
||||||
|
cv_size_from_debug_s(CV_DebugS *debug_s, U64 align)
|
||||||
|
{
|
||||||
|
U64 size = 0;
|
||||||
|
for EachElement(i, debug_s->data_list) {
|
||||||
|
if (i == CV_C13SubSectionIdxKind_Lines) { continue; }
|
||||||
|
if (debug_s->data_list[i].total_size == 0) { continue; }
|
||||||
|
size += sizeof(CV_C13SubSectionKind) + sizeof(U32); // header
|
||||||
|
size += debug_s->data_list[i].total_size;
|
||||||
|
size = AlignPow2(size, align);
|
||||||
|
}
|
||||||
|
|
||||||
|
String8List *line_data = cv_sub_section_ptr_from_debug_s(debug_s, CV_C13SubSectionKind_Lines);
|
||||||
|
for EachNode(line_n, String8Node, line_data->first) {
|
||||||
|
if (line_n->string.size == 0) { continue; }
|
||||||
|
size += sizeof(CV_C13SubSectionKind) + sizeof(U32); // header
|
||||||
|
size += line_n->string.size;
|
||||||
|
size = AlignPow2(size, align);
|
||||||
|
}
|
||||||
|
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal CV_C13SubSectionKind
|
||||||
|
cv_c13_sub_section_kind_from_idx(CV_C13SubSectionIdxKind idx)
|
||||||
|
{
|
||||||
|
switch (idx) {
|
||||||
|
#define X(n, c) case CV_C13SubSectionIdxKind_##n: return c;
|
||||||
|
CV_C13SubSectionKindXList(X)
|
||||||
|
#undef X
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
internal CV_C13SubSectionIdxKind
|
internal CV_C13SubSectionIdxKind
|
||||||
cv_c13_sub_section_idx_from_kind(CV_C13SubSectionKind kind)
|
cv_c13_sub_section_idx_from_kind(CV_C13SubSectionKind kind)
|
||||||
{
|
{
|
||||||
@@ -1520,8 +1554,8 @@ internal CV_ChecksumList
|
|||||||
cv_c13_parse_checksum_data_list(Arena *arena, String8List checksum_data_list)
|
cv_c13_parse_checksum_data_list(Arena *arena, String8List checksum_data_list)
|
||||||
{
|
{
|
||||||
CV_ChecksumList result = {0};
|
CV_ChecksumList result = {0};
|
||||||
for (String8Node *node = checksum_data_list.first; node != 0; node = node->next) {
|
for EachNode(n, String8Node, checksum_data_list.first) {
|
||||||
cv_parse_checksum_data(arena, &result, node->string);
|
cv_parse_checksum_data(arena, &result, n->string);
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -403,8 +403,11 @@ internal CV_Signature cv_signature_from_debug_s(String8 raw_debug_s);
|
|||||||
internal CV_DebugS cv_parse_debug_s(Arena *arena, String8 raw_debug_s);
|
internal CV_DebugS cv_parse_debug_s(Arena *arena, String8 raw_debug_s);
|
||||||
internal void cv_debug_s_concat_in_place(CV_DebugS *dst, CV_DebugS *src);
|
internal void cv_debug_s_concat_in_place(CV_DebugS *dst, CV_DebugS *src);
|
||||||
internal String8List cv_data_c13_from_debug_s(Arena *arena, CV_DebugS *debug_s, B32 write_sig);
|
internal String8List cv_data_c13_from_debug_s(Arena *arena, CV_DebugS *debug_s, B32 write_sig);
|
||||||
|
internal U64 cv_size_from_debug_s(CV_DebugS *debug_s, U64 align);
|
||||||
|
|
||||||
|
internal CV_C13SubSectionKind cv_c13_sub_section_kind_from_idx(CV_C13SubSectionIdxKind idx);
|
||||||
internal CV_C13SubSectionIdxKind cv_c13_sub_section_idx_from_kind(CV_C13SubSectionKind kind);
|
internal CV_C13SubSectionIdxKind cv_c13_sub_section_idx_from_kind(CV_C13SubSectionKind kind);
|
||||||
|
|
||||||
internal String8List * cv_sub_section_ptr_from_debug_s(CV_DebugS *debug_s, CV_C13SubSectionKind kind);
|
internal String8List * cv_sub_section_ptr_from_debug_s(CV_DebugS *debug_s, CV_C13SubSectionKind kind);
|
||||||
internal String8List cv_sub_section_from_debug_s(CV_DebugS debug_s, CV_C13SubSectionKind kind);
|
internal String8List cv_sub_section_from_debug_s(CV_DebugS debug_s, CV_C13SubSectionKind kind);
|
||||||
internal String8 cv_string_table_from_debug_s(CV_DebugS debug_s);
|
internal String8 cv_string_table_from_debug_s(CV_DebugS debug_s);
|
||||||
|
|||||||
+141
-181
@@ -517,11 +517,7 @@ lnk_make_code_view_input(TP_Context *tp, TP_Arena *tp_arena, LNK_IO_Flags io_fla
|
|||||||
}
|
}
|
||||||
ProfEnd();
|
ProfEnd();
|
||||||
|
|
||||||
ProfBegin("Symbol Parse");
|
tp_for_parallel_prof(tp, tp_arena, total_symbol_input_count, lnk_parse_cv_symbols_task, &(LNK_ParseCVSymbolsTaskData){ .inputs = symbol_inputs }, "Symbol Parse");
|
||||||
LNK_ParseCVSymbolsTaskData task = {0};
|
|
||||||
task.inputs = symbol_inputs;
|
|
||||||
tp_for_parallel(tp, tp_arena, total_symbol_input_count, lnk_parse_cv_symbols_task, &task);
|
|
||||||
ProfEnd();
|
|
||||||
|
|
||||||
// TODO: do we rely on this behaviour?
|
// TODO: do we rely on this behaviour?
|
||||||
//
|
//
|
||||||
@@ -2670,63 +2666,23 @@ THREAD_POOL_TASK_FUNC(lnk_make_proc_refs_task)
|
|||||||
}
|
}
|
||||||
|
|
||||||
internal
|
internal
|
||||||
THREAD_POOL_TASK_FUNC(lnk_process_sym_data_task)
|
THREAD_POOL_TASK_FUNC(lnk_fixup_symbol_offsets_task)
|
||||||
{
|
{
|
||||||
ProfBeginFunction();
|
ProfBeginFunction();
|
||||||
|
|
||||||
U64 obj_idx = task_id;
|
LNK_ProcessSymDataTaskData *task = raw_task;
|
||||||
LNK_ProcessSymDataTaskData *task = raw_task;
|
CV_SymbolListArray symbols = task->parsed_symbols[task_id];
|
||||||
CV_SymbolListArray parsed_symbols = task->parsed_symbols[obj_idx];
|
|
||||||
|
|
||||||
static CV_Signature MODULE_SYMBOL_SIGNATURE = CV_Signature_C13;
|
// fixup symbol offsets and estimate symbol data size
|
||||||
|
U64 size = sizeof(CV_Signature);
|
||||||
ProfBegin("Compute Buffer Size");
|
for EachIndex(i, symbols.count) {
|
||||||
U64 buffer_size = sizeof(MODULE_SYMBOL_SIGNATURE);
|
size += cv_patch_symbol_tree_offsets(symbols.v[i], size, PDB_SYMBOL_ALIGN);
|
||||||
for (U64 i = 0; i < parsed_symbols.count; ++i) {
|
|
||||||
CV_SymbolList list = parsed_symbols.v[i];
|
|
||||||
U64 data_size = cv_patch_symbol_tree_offsets(list, buffer_size, PDB_SYMBOL_ALIGN);
|
|
||||||
buffer_size += data_size;
|
|
||||||
}
|
}
|
||||||
ProfEnd();
|
task->serialized_symbol_data_sizes[task_id] = AlignPow2(size, CV_C13SubSectionAlign);
|
||||||
|
|
||||||
// alloc buffer
|
|
||||||
U8 *buffer = push_array_no_zero(arena, U8, buffer_size);
|
|
||||||
U64 buffer_cursor = 0;
|
|
||||||
|
|
||||||
// MS Symbol and Type Information p.4:
|
|
||||||
// "The first four bytes of the $$SYMBOLS segment is used as a signature to specify the version of
|
|
||||||
// the Symbol and Type OMF contained in the $$SYMBOLS segment."
|
|
||||||
CV_Signature *sig_ptr = (CV_Signature *) (buffer + buffer_cursor);
|
|
||||||
*sig_ptr = MODULE_SYMBOL_SIGNATURE;
|
|
||||||
buffer_cursor += sizeof(*sig_ptr);
|
|
||||||
|
|
||||||
ProfBegin("Serialize Symbols");
|
|
||||||
for (U64 i = 0; i < parsed_symbols.count; ++i) {
|
|
||||||
CV_SymbolList list = parsed_symbols.v[i];
|
|
||||||
for (CV_SymbolNode *symbol_n = list.first; symbol_n != 0; symbol_n = symbol_n->next) {
|
|
||||||
symbol_n->data.offset = buffer_cursor;
|
|
||||||
buffer_cursor += cv_serialize_symbol_to_buffer(buffer, buffer_cursor, buffer_size, &symbol_n->data, PDB_SYMBOL_ALIGN);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ProfEnd();
|
|
||||||
|
|
||||||
// output
|
|
||||||
Assert(task->symbol_data_arr[obj_idx].total_size == 0);
|
|
||||||
str8_list_push(arena, &task->symbol_data_arr[obj_idx], str8(buffer, buffer_size));
|
|
||||||
|
|
||||||
ProfEnd();
|
ProfEnd();
|
||||||
}
|
}
|
||||||
|
|
||||||
internal LNK_ProcessedCodeViewC11Data
|
|
||||||
lnk_process_c11_data(TP_Context *tp, TP_Arena *arena, U64 obj_count, CV_DebugS *debug_s_arr, U64 string_data_base_offset, CV_StringHashTable string_ht, MSF_Context *msf, PDB_DbiModule **mod_arr)
|
|
||||||
{
|
|
||||||
// TODO: handle c11 data
|
|
||||||
String8List *data_list_arr = push_array(arena->v[0], String8List, obj_count);
|
|
||||||
LNK_ProcessedCodeViewC11Data result;
|
|
||||||
result.data_list_arr = data_list_arr;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
internal
|
internal
|
||||||
THREAD_POOL_TASK_FUNC(lnk_process_c13_data_task)
|
THREAD_POOL_TASK_FUNC(lnk_process_c13_data_task)
|
||||||
{
|
{
|
||||||
@@ -2750,108 +2706,114 @@ THREAD_POOL_TASK_FUNC(lnk_process_c13_data_task)
|
|||||||
// relocate checksum data
|
// relocate checksum data
|
||||||
cv_c13_patch_string_offsets_in_checksum_list(checksum_list, string_data, task->string_data_base_offset, task->string_ht);
|
cv_c13_patch_string_offsets_in_checksum_list(checksum_list, string_data, task->string_data_base_offset, task->string_ht);
|
||||||
|
|
||||||
// get module sub-sections
|
|
||||||
PDB_DbiModule *mod = task->dbi_mod_arr[obj_idx];
|
|
||||||
String8 mod_c13_data = dbi_module_read_c13_data(scratch.arena, task->msf, mod);
|
|
||||||
CV_DebugS mod_debug_s = cv_parse_debug_s_c13(scratch.arena, mod_c13_data);
|
|
||||||
|
|
||||||
// relocate line and frame data
|
|
||||||
String8List *mod_checksum_data = cv_sub_section_ptr_from_debug_s(&mod_debug_s, CV_C13SubSectionKind_FileChksms);
|
|
||||||
U64 checksum_base = mod_checksum_data->total_size;
|
|
||||||
B32 is_checksum_patch_needed = checksum_base > 0;
|
|
||||||
if (is_checksum_patch_needed) {
|
|
||||||
String8List line_data = cv_sub_section_from_debug_s(debug_s, CV_C13SubSectionKind_Lines);
|
|
||||||
String8List frame_data = cv_sub_section_from_debug_s(debug_s, CV_C13SubSectionKind_FrameData);
|
|
||||||
cv_c13_patch_checksum_offsets_in_line_data_list(line_data, checksum_base);
|
|
||||||
cv_c13_patch_checksum_offsets_in_frame_data_list(frame_data, checksum_base);
|
|
||||||
}
|
|
||||||
|
|
||||||
// push obj c13 data to module
|
|
||||||
cv_debug_s_concat_in_place(&mod_debug_s, &debug_s);
|
|
||||||
|
|
||||||
// serialize c13 data
|
|
||||||
B32 include_sig = 0;
|
|
||||||
String8List c13_data = cv_data_c13_from_debug_s(arena, &mod_debug_s, include_sig);
|
|
||||||
|
|
||||||
// store for later pass
|
// store for later pass
|
||||||
task->c13_data_arr[obj_idx] = c13_data;
|
|
||||||
task->source_file_names_list_arr[obj_idx] = source_file_names_list;
|
task->source_file_names_list_arr[obj_idx] = source_file_names_list;
|
||||||
|
|
||||||
scratch_end(scratch);
|
scratch_end(scratch);
|
||||||
ProfEnd();
|
ProfEnd();
|
||||||
}
|
}
|
||||||
|
|
||||||
internal LNK_ProcessedCodeViewC13Data
|
|
||||||
lnk_process_c13_data(TP_Context *tp, TP_Arena *arena, U64 obj_count, CV_DebugS *debug_s_arr, U64 string_data_base_offset, CV_StringHashTable string_ht, MSF_Context *msf, PDB_DbiModule **mod_arr)
|
|
||||||
{
|
|
||||||
ProfBeginFunction();
|
|
||||||
|
|
||||||
LNK_ProcessC13DataTask task = {0};
|
|
||||||
task.debug_s_arr = debug_s_arr;
|
|
||||||
task.msf = msf;
|
|
||||||
task.dbi_mod_arr = mod_arr;
|
|
||||||
task.c13_data_arr = push_array_no_zero(arena->v[0], String8List, obj_count);
|
|
||||||
task.source_file_names_list_arr = push_array_no_zero(arena->v[0], String8List, obj_count);
|
|
||||||
task.string_data_base_offset = string_data_base_offset;
|
|
||||||
task.string_ht = string_ht;
|
|
||||||
tp_for_parallel(tp, arena, obj_count, lnk_process_c13_data_task, &task);
|
|
||||||
|
|
||||||
// fill out result
|
|
||||||
LNK_ProcessedCodeViewC13Data result = {0};
|
|
||||||
result.data_list_arr = task.c13_data_arr;
|
|
||||||
result.source_file_names_list_arr = task.source_file_names_list_arr;
|
|
||||||
|
|
||||||
ProfEnd();
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
internal
|
internal
|
||||||
THREAD_POOL_TASK_FUNC(lnk_write_module_data_task)
|
THREAD_POOL_TASK_FUNC(lnk_write_module_data_task)
|
||||||
{
|
{
|
||||||
U64 obj_idx = task_id;
|
|
||||||
LNK_WriteModuleDataTask *task = raw_task;
|
LNK_WriteModuleDataTask *task = raw_task;
|
||||||
|
|
||||||
PDB_DbiModule *mod = task->mod_arr[obj_idx];
|
U64 obj_idx = task_id;
|
||||||
String8List sym_data = task->symbol_data_arr[obj_idx];
|
PDB_DbiModule *mod = task->mod_arr [obj_idx];
|
||||||
String8List c11_data = task->c11_data_list_arr[obj_idx];
|
CV_DebugS *debug_s = &task->debug_s_arr [obj_idx];
|
||||||
String8List c13_data = task->c13_data_list_arr[obj_idx];
|
CV_SymbolListArray parsed_symbols = task->parsed_symbols [obj_idx];
|
||||||
String8List globrefs = task->globrefs_arr[obj_idx];
|
String8List globrefs = task->globrefs_arr [obj_idx];
|
||||||
|
U64 sym_data_size = task->serialized_symbol_data_sizes[obj_idx];
|
||||||
|
|
||||||
U32 sym_data_size32 = safe_cast_u32(sym_data.total_size);
|
MSF_UInt stream_cap = msf_stream_get_cap(task->msf, mod->sn);
|
||||||
U32 c11_data_size32 = safe_cast_u32(c11_data.total_size);
|
|
||||||
U32 c13_data_size32 = safe_cast_u32(c13_data.total_size);
|
|
||||||
U32 globrefs_size32 = safe_cast_u32(globrefs.total_size);
|
|
||||||
|
|
||||||
// layout module data
|
// write symbols
|
||||||
String8List module_data = {0};
|
if (sym_data_size > 0) {
|
||||||
str8_list_concat_in_place(&module_data, &sym_data);
|
Temp scratch = scratch_begin(&arena, 1);
|
||||||
str8_list_concat_in_place(&module_data, &c11_data);
|
|
||||||
str8_list_concat_in_place(&module_data, &c13_data);
|
U64 temp_max = max_U16;
|
||||||
str8_list_concat_in_place(&module_data, &globrefs);
|
U64 temp_size = 0;
|
||||||
|
U8 *temp = push_array(scratch.arena, U8, temp_max);
|
||||||
|
|
||||||
|
msf_stream_write_u32(task->msf, mod->sn, CV_Signature_C13);
|
||||||
|
|
||||||
|
for EachIndex(i, parsed_symbols.count) {
|
||||||
|
for EachNode(symbol_n, CV_SymbolNode, parsed_symbols.v[i].first) {
|
||||||
|
U64 symbol_size = cv_compute_symbol_record_size(&symbol_n->data, PDB_SYMBOL_ALIGN);
|
||||||
|
|
||||||
|
// flush temp
|
||||||
|
if (temp_size + symbol_size > temp_max) {
|
||||||
|
Assert(temp_size <= (stream_cap - msf_stream_get_pos(task->msf, mod->sn)));
|
||||||
|
msf_stream_write(task->msf, mod->sn, temp, temp_size);
|
||||||
|
temp_size = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
U64 serial_size = cv_serialize_symbol_to_buffer(temp, temp_size, temp_max, &symbol_n->data, PDB_SYMBOL_ALIGN);
|
||||||
|
Assert(serial_size == symbol_size);
|
||||||
|
temp_size += serial_size;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// flush remaining temp
|
||||||
|
Assert(temp_size <= (stream_cap - msf_stream_get_pos(task->msf, mod->sn)));
|
||||||
|
msf_stream_write(task->msf, mod->sn, temp, temp_size);
|
||||||
|
msf_stream_align(task->msf, mod->sn, CV_C13SubSectionAlign);
|
||||||
|
|
||||||
|
U64 size = msf_stream_get_pos(task->msf, mod->sn);
|
||||||
|
// assert our symbol size estimate was correct
|
||||||
|
Assert(sym_data_size == msf_stream_get_pos(task->msf, mod->sn));
|
||||||
|
|
||||||
|
scratch_end(scratch);
|
||||||
|
}
|
||||||
|
|
||||||
|
// write rest of c13 data
|
||||||
|
U64 c13_data_size;
|
||||||
|
{
|
||||||
|
U64 c13_start_pos = msf_stream_get_pos(task->msf, mod->sn);
|
||||||
|
|
||||||
|
for EachElement(layout_idx, debug_s->data_list) {
|
||||||
|
if (layout_idx == CV_C13SubSectionIdxKind_Lines || layout_idx == CV_C13SubSectionIdxKind_Symbols) { continue; }
|
||||||
|
|
||||||
|
CV_C13SubSectionKind kind = cv_c13_sub_section_kind_from_idx(layout_idx);
|
||||||
|
String8List *data = cv_sub_section_ptr_from_debug_s(debug_s, kind);
|
||||||
|
if (data->total_size == 0) { continue; }
|
||||||
|
|
||||||
|
Assert(AlignPow2(sizeof(U32)*2 + data->total_size, PDB_SYMBOL_ALIGN) <= (stream_cap - msf_stream_get_pos(task->msf, mod->sn)));
|
||||||
|
msf_stream_write_u32 (task->msf, mod->sn, kind);
|
||||||
|
msf_stream_write_u32 (task->msf, mod->sn, safe_cast_u32(data->total_size));
|
||||||
|
msf_stream_write_list(task->msf, mod->sn, *data);
|
||||||
|
msf_stream_align(task->msf, mod->sn, CV_C13SubSectionAlign);
|
||||||
|
}
|
||||||
|
|
||||||
|
String8List *line_data = cv_sub_section_ptr_from_debug_s(debug_s, CV_C13SubSectionKind_Lines);
|
||||||
|
for EachNode(line_n, String8Node, line_data->first) {
|
||||||
|
if (line_n->string.size == 0) { continue; }
|
||||||
|
|
||||||
|
Assert(AlignPow2(sizeof(U32)*2 + line_n->string.size, PDB_SYMBOL_ALIGN) <= (stream_cap - msf_stream_get_pos(task->msf, mod->sn)));
|
||||||
|
msf_stream_write_u32 (task->msf, mod->sn, CV_C13SubSectionKind_Lines);
|
||||||
|
msf_stream_write_u32 (task->msf, mod->sn, safe_cast_u32(line_n->string.size));
|
||||||
|
msf_stream_write_string(task->msf, mod->sn, line_n->string);
|
||||||
|
msf_stream_align(task->msf, mod->sn, CV_C13SubSectionAlign);
|
||||||
|
}
|
||||||
|
|
||||||
|
U64 c13_end_pos = msf_stream_get_pos(task->msf, mod->sn);
|
||||||
|
c13_data_size = c13_end_pos - c13_start_pos;
|
||||||
|
Assert(c13_data_size == cv_size_from_debug_s(debug_s, CV_C13SubSectionAlign));
|
||||||
|
}
|
||||||
|
|
||||||
|
// write global refs
|
||||||
|
Assert(globrefs.total_size <= (stream_cap - msf_stream_get_pos(task->msf, mod->sn)));
|
||||||
|
msf_stream_write_list(task->msf, mod->sn, globrefs);
|
||||||
|
|
||||||
|
// update module data sizes
|
||||||
|
mod->sym_data_size = safe_cast_u32(sym_data_size);
|
||||||
|
mod->c11_data_size = 0;
|
||||||
|
mod->c13_data_size = safe_cast_u32(c13_data_size);
|
||||||
|
mod->globrefs_size = safe_cast_u32(globrefs.total_size);
|
||||||
|
|
||||||
// make stream has enough memory so it doens't trigger memory allocations in MSF
|
// make stream has enough memory so it doens't trigger memory allocations in MSF
|
||||||
// during multi-thread write
|
// during multi-thread write
|
||||||
MSF_UInt stream_pos = msf_stream_get_pos(task->msf, mod->sn);
|
AssertAlways(task->mod_sizes[obj_idx] == msf_stream_get_pos(task->msf, mod->sn));
|
||||||
if (stream_pos != 0) {
|
|
||||||
Assert(!"stream must be at start position");
|
|
||||||
}
|
|
||||||
MSF_UInt stream_cap = msf_stream_get_cap(task->msf, mod->sn);
|
|
||||||
if (stream_cap < module_data.total_size) {
|
|
||||||
Assert(!"not enough bytes in destination stream to copy module data");
|
|
||||||
}
|
|
||||||
|
|
||||||
// write data
|
|
||||||
B32 is_write_ok = msf_stream_write_list(task->msf, mod->sn, module_data);
|
|
||||||
|
|
||||||
// update module data sizes
|
|
||||||
if (is_write_ok) {
|
|
||||||
mod->sym_data_size = sym_data_size32;
|
|
||||||
mod->c11_data_size = c11_data_size32;
|
|
||||||
mod->c13_data_size = c13_data_size32;
|
|
||||||
mod->globrefs_size = globrefs_size32;
|
|
||||||
} else {
|
|
||||||
// TODO: error handle
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
internal
|
internal
|
||||||
@@ -3078,7 +3040,7 @@ lnk_build_pdb(TP_Context *tp,
|
|||||||
|
|
||||||
ProfBegin("Reserve DBI Modules");
|
ProfBegin("Reserve DBI Modules");
|
||||||
PDB_DbiModule **mod_arr = push_array(tp_arena->v[0], PDB_DbiModule *, obj_count);
|
PDB_DbiModule **mod_arr = push_array(tp_arena->v[0], PDB_DbiModule *, obj_count);
|
||||||
for (U64 obj_idx = 0; obj_idx < obj_count; ++obj_idx) {
|
for EachIndex(obj_idx, obj_count) {
|
||||||
LNK_Obj *obj = obj_arr[obj_idx];
|
LNK_Obj *obj = obj_arr[obj_idx];
|
||||||
mod_arr[obj_idx] = dbi_push_module(pdb->dbi, obj->path, lnk_obj_get_lib_path(obj));
|
mod_arr[obj_idx] = dbi_push_module(pdb->dbi, obj->path, lnk_obj_get_lib_path(obj));
|
||||||
|
|
||||||
@@ -3094,33 +3056,41 @@ lnk_build_pdb(TP_Context *tp,
|
|||||||
pdb_strtab_add_cv_string_hash_table(&pdb->info->strtab, string_ht);
|
pdb_strtab_add_cv_string_hash_table(&pdb->info->strtab, string_ht);
|
||||||
ProfEnd();
|
ProfEnd();
|
||||||
|
|
||||||
|
ProfBegin("Build Source Files List");
|
||||||
|
{
|
||||||
|
// push source files per module info
|
||||||
|
LNK_ProcessC13DataTask task = {0};
|
||||||
|
task.debug_s_arr = debug_s_arr;
|
||||||
|
task.string_data_base_offset = string_data_base_offset;
|
||||||
|
task.source_file_names_list_arr = push_array_no_zero(tp_arena->v[0], String8List, obj_count);
|
||||||
|
task.string_ht = string_ht;
|
||||||
|
tp_for_parallel(tp, tp_arena, obj_count, lnk_process_c13_data_task, &task);
|
||||||
|
|
||||||
|
for EachIndex(obj_idx, obj_count) {
|
||||||
|
String8List source_file_list = str8_list_copy(pdb->dbi->arena, &task.source_file_names_list_arr[obj_idx]);
|
||||||
|
str8_list_concat_in_place(&mod_arr[obj_idx]->source_file_list, &source_file_list);
|
||||||
|
}
|
||||||
|
|
||||||
|
// zero out string table sub section
|
||||||
|
for EachIndex(obj_idx, obj_count) {
|
||||||
|
MemoryZeroStruct(&debug_s_arr[obj_idx].data_list[CV_C13SubSectionIdxKind_StringTable]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ProfEnd();
|
||||||
|
|
||||||
ProfBegin("Build DBI Modules");
|
ProfBegin("Build DBI Modules");
|
||||||
{
|
{
|
||||||
TP_Temp temp = tp_temp_begin(tp_arena);
|
TP_Temp temp = tp_temp_begin(tp_arena);
|
||||||
{
|
{
|
||||||
ProfBegin("Reloc Module Data");
|
ProfBegin("Fixup Symbol Offsets");
|
||||||
|
U64 *serialized_symbol_data_sizes = push_array(scratch.arena, U64, obj_count);
|
||||||
ProfBegin("Serialize Symbols");
|
tp_for_parallel(tp, tp_arena, obj_count, lnk_fixup_symbol_offsets_task, &(LNK_ProcessSymDataTaskData){ .parsed_symbols = parsed_symbols, .serialized_symbol_data_sizes = serialized_symbol_data_sizes });
|
||||||
String8List *serialized_symbol_data = push_array(scratch.arena, String8List, obj_count);
|
|
||||||
{
|
|
||||||
LNK_ProcessSymDataTaskData task = {0};
|
|
||||||
task.symbol_inputs = symbol_inputs;
|
|
||||||
task.parsed_symbols = parsed_symbols;
|
|
||||||
task.mod_arr = mod_arr;
|
|
||||||
task.symbol_data_arr = serialized_symbol_data;
|
|
||||||
tp_for_parallel(tp, tp_arena, obj_count, lnk_process_sym_data_task, &task);
|
|
||||||
}
|
|
||||||
ProfEnd();
|
|
||||||
|
|
||||||
LNK_ProcessedCodeViewC11Data processed_c11 = lnk_process_c11_data(tp, tp_arena, obj_count, debug_s_arr, string_data_base_offset, string_ht, pdb->msf, mod_arr);
|
|
||||||
LNK_ProcessedCodeViewC13Data processed_c13 = lnk_process_c13_data(tp, tp_arena, obj_count, debug_s_arr, string_data_base_offset, string_ht, pdb->msf, mod_arr);
|
|
||||||
|
|
||||||
ProfEnd();
|
ProfEnd();
|
||||||
|
|
||||||
// TODO: actually collect offsets and pass them here
|
// TODO: actually collect offsets and pass them here
|
||||||
ProfBegin("Build Empty Global Reference Array");
|
ProfBegin("Build Empty Global Reference Array");
|
||||||
String8List *globrefs_arr = push_array(tp_arena->v[0], String8List, obj_count);
|
String8List *globrefs_arr = push_array(tp_arena->v[0], String8List, obj_count);
|
||||||
for (U64 obj_idx = 0; obj_idx < obj_count; ++obj_idx) {
|
for EachIndex(obj_idx, obj_count) {
|
||||||
String8List *globrefs = &globrefs_arr[obj_idx];
|
String8List *globrefs = &globrefs_arr[obj_idx];
|
||||||
str8_serial_begin(tp_arena->v[0], globrefs);
|
str8_serial_begin(tp_arena->v[0], globrefs);
|
||||||
Assert(globrefs->total_size == 0);
|
Assert(globrefs->total_size == 0);
|
||||||
@@ -3130,43 +3100,33 @@ lnk_build_pdb(TP_Context *tp,
|
|||||||
|
|
||||||
// reserve memory for module streams
|
// reserve memory for module streams
|
||||||
ProfBegin("Reserve Modules Memory");
|
ProfBegin("Reserve Modules Memory");
|
||||||
for (U64 obj_idx = 0; obj_idx < obj_count; ++obj_idx) {
|
U32 *mod_sizes = push_array(scratch.arena, U32, obj_count);
|
||||||
|
for EachIndex(obj_idx, obj_count) {
|
||||||
// compute number of bytes needed for module data
|
// compute number of bytes needed for module data
|
||||||
U64 mod_size = 0;
|
U64 mod_size = 0;
|
||||||
mod_size += serialized_symbol_data[obj_idx].total_size;
|
mod_size += cv_size_from_debug_s(&debug_s_arr[obj_idx], CV_C13SubSectionAlign);
|
||||||
mod_size += processed_c11.data_list_arr[obj_idx].total_size;
|
mod_size += serialized_symbol_data_sizes[obj_idx];
|
||||||
mod_size += processed_c13.data_list_arr[obj_idx].total_size;
|
|
||||||
mod_size += globrefs_arr[obj_idx].total_size;
|
mod_size += globrefs_arr[obj_idx].total_size;
|
||||||
|
|
||||||
U32 mod_size32 = safe_cast_u32(mod_size);
|
mod_sizes[obj_idx] = safe_cast_u32(mod_size);
|
||||||
|
|
||||||
// allocate stream for module
|
// allocate stream for module
|
||||||
PDB_DbiModule *mod = mod_arr[obj_idx];
|
mod_arr[obj_idx]->sn = msf_stream_alloc_ex(pdb->msf, mod_sizes[obj_idx]);
|
||||||
mod->sn = msf_stream_alloc_ex(pdb->msf, mod_size32);
|
|
||||||
}
|
}
|
||||||
ProfEnd();
|
ProfEnd();
|
||||||
|
|
||||||
// copy data to module streams
|
// copy data to module streams
|
||||||
ProfBegin("Write Modules Data");
|
ProfBegin("Write Modules Data");
|
||||||
LNK_WriteModuleDataTask write_module_data_task_data;
|
LNK_WriteModuleDataTask write_module_data_task_data = {0};
|
||||||
write_module_data_task_data.msf = pdb->msf;
|
write_module_data_task_data.msf = pdb->msf;
|
||||||
write_module_data_task_data.mod_arr = mod_arr;
|
write_module_data_task_data.mod_arr = mod_arr;
|
||||||
write_module_data_task_data.symbol_data_arr = serialized_symbol_data;
|
write_module_data_task_data.debug_s_arr = debug_s_arr;
|
||||||
write_module_data_task_data.c11_data_list_arr = processed_c11.data_list_arr;
|
write_module_data_task_data.serialized_symbol_data_sizes = serialized_symbol_data_sizes;
|
||||||
write_module_data_task_data.c13_data_list_arr = processed_c13.data_list_arr;
|
write_module_data_task_data.parsed_symbols = parsed_symbols;
|
||||||
write_module_data_task_data.globrefs_arr = globrefs_arr;
|
write_module_data_task_data.globrefs_arr = globrefs_arr;
|
||||||
|
write_module_data_task_data.mod_sizes = mod_sizes;
|
||||||
tp_for_parallel(tp, 0, obj_count, lnk_write_module_data_task, &write_module_data_task_data);
|
tp_for_parallel(tp, 0, obj_count, lnk_write_module_data_task, &write_module_data_task_data);
|
||||||
ProfEnd();
|
ProfEnd();
|
||||||
|
|
||||||
// push source files per module info
|
|
||||||
ProfBegin("Build Source Files List");
|
|
||||||
for (U64 obj_idx = 0; obj_idx < obj_count; ++obj_idx) {
|
|
||||||
PDB_DbiModule *mod = mod_arr[obj_idx];
|
|
||||||
String8List source_file_list_scratch = processed_c13.source_file_names_list_arr[obj_idx];
|
|
||||||
String8List source_file_list = str8_list_copy(pdb->dbi->arena, &source_file_list_scratch);
|
|
||||||
str8_list_concat_in_place(&mod->source_file_list, &source_file_list);
|
|
||||||
}
|
|
||||||
ProfEnd();
|
|
||||||
}
|
}
|
||||||
tp_temp_end(temp);
|
tp_temp_end(temp);
|
||||||
}
|
}
|
||||||
|
|||||||
+10
-12
@@ -232,8 +232,10 @@ typedef struct
|
|||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
U64 total_symbol_input_count;
|
U64 total_symbol_input_count;
|
||||||
LNK_CodeViewSymbolsInput *symbol_inputs;
|
|
||||||
CV_SymbolListArray *parsed_symbols;
|
CV_SymbolListArray *parsed_symbols;
|
||||||
|
U64 *serialized_symbol_data_sizes;
|
||||||
|
|
||||||
|
LNK_CodeViewSymbolsInput *symbol_inputs;
|
||||||
PDB_DbiModule **mod_arr;
|
PDB_DbiModule **mod_arr;
|
||||||
String8List *symbol_data_arr;
|
String8List *symbol_data_arr;
|
||||||
CV_SymbolList *gsi_list_arr;
|
CV_SymbolList *gsi_list_arr;
|
||||||
@@ -242,9 +244,6 @@ typedef struct
|
|||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
CV_DebugS *debug_s_arr;
|
CV_DebugS *debug_s_arr;
|
||||||
MSF_Context *msf;
|
|
||||||
PDB_DbiModule **dbi_mod_arr;
|
|
||||||
String8List *c13_data_arr;
|
|
||||||
String8List *source_file_names_list_arr;
|
String8List *source_file_names_list_arr;
|
||||||
U64 string_data_base_offset;
|
U64 string_data_base_offset;
|
||||||
CV_StringHashTable string_ht;
|
CV_StringHashTable string_ht;
|
||||||
@@ -252,12 +251,13 @@ typedef struct
|
|||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
MSF_Context *msf;
|
MSF_Context *msf;
|
||||||
PDB_DbiModule **mod_arr;
|
PDB_DbiModule **mod_arr;
|
||||||
String8List *symbol_data_arr;
|
CV_DebugS *debug_s_arr;
|
||||||
String8List *c11_data_list_arr;
|
U64 *serialized_symbol_data_sizes;
|
||||||
String8List *c13_data_list_arr;
|
CV_SymbolListArray *parsed_symbols;
|
||||||
String8List *globrefs_arr;
|
String8List *globrefs_arr;
|
||||||
|
U32 *mod_sizes;
|
||||||
} LNK_WriteModuleDataTask;
|
} LNK_WriteModuleDataTask;
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
@@ -509,8 +509,6 @@ lnk_build_rad_debug_info(TP_Context *tp,
|
|||||||
|
|
||||||
// --- PDB ---------------------------------------------------------------------
|
// --- PDB ---------------------------------------------------------------------
|
||||||
|
|
||||||
internal LNK_ProcessedCodeViewC11Data lnk_process_c11_data (TP_Context *tp, TP_Arena *arena, U64 obj_count, CV_DebugS *debug_s_arr, U64 string_data_base_offset, CV_StringHashTable string_ht, MSF_Context *msf, PDB_DbiModule **mod_arr);
|
|
||||||
internal LNK_ProcessedCodeViewC13Data lnk_process_c13_data (TP_Context *tp, TP_Arena *arena, U64 obj_count, CV_DebugS *debug_s_arr, U64 string_data_base_offset, CV_StringHashTable string_ht, MSF_Context *msf, PDB_DbiModule **mod_arr);
|
|
||||||
internal U64 * lnk_hash_cv_symbol_ptr_arr(TP_Context *tp, Arena *arena, CV_SymbolPtrArray arr);
|
internal U64 * lnk_hash_cv_symbol_ptr_arr(TP_Context *tp, Arena *arena, CV_SymbolPtrArray arr);
|
||||||
internal CV_SymbolPtrArray lnk_dedup_gsi_symbols (TP_Context *tp, Arena *arena, PDB_GsiContext *gsi, U64 obj_count, CV_SymbolList *symbol_list_arr);
|
internal CV_SymbolPtrArray lnk_dedup_gsi_symbols (TP_Context *tp, Arena *arena, PDB_GsiContext *gsi, U64 obj_count, CV_SymbolList *symbol_list_arr);
|
||||||
|
|
||||||
|
|||||||
@@ -1335,9 +1335,16 @@ msf_stream_read_string(Arena *arena, MSF_Context *msf, MSF_StreamNumber sn)
|
|||||||
internal void
|
internal void
|
||||||
msf_stream_align(MSF_Context *msf, MSF_StreamNumber sn, MSF_UInt align)
|
msf_stream_align(MSF_Context *msf, MSF_StreamNumber sn, MSF_UInt align)
|
||||||
{
|
{
|
||||||
|
local_persist U8 zeroes[64];
|
||||||
MSF_UInt pos = msf_stream_get_pos(msf, sn);
|
MSF_UInt pos = msf_stream_get_pos(msf, sn);
|
||||||
MSF_UInt pos_aligned = AlignPow2(pos, align);
|
MSF_UInt pad = AlignPadPow2(pos, align);
|
||||||
msf_stream_seek(msf, sn, pos_aligned);
|
if (pad > 0) {
|
||||||
|
if (pad < sizeof(zeroes)) {
|
||||||
|
msf_stream_write(msf, sn, zeroes, pad);
|
||||||
|
} else {
|
||||||
|
NotImplemented;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////
|
////////////////////////////////
|
||||||
|
|||||||
Reference in New Issue
Block a user