serialize symbols directly into MSF streams

This commit is contained in:
Nikita Smith
2026-02-16 20:32:44 -08:00
parent 442f41b51a
commit 2083c1ed87
5 changed files with 202 additions and 200 deletions
+36 -2
View File
@@ -545,6 +545,40 @@ cv_data_c13_from_debug_s(Arena *arena, CV_DebugS *debug_s, B32 write_sig)
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
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_ChecksumList result = {0};
for (String8Node *node = checksum_data_list.first; node != 0; node = node->next) {
cv_parse_checksum_data(arena, &result, node->string);
for EachNode(n, String8Node, checksum_data_list.first) {
cv_parse_checksum_data(arena, &result, n->string);
}
return result;
}
+3
View File
@@ -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 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 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 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 String8 cv_string_table_from_debug_s(CV_DebugS debug_s);
+137 -177
View File
@@ -517,11 +517,7 @@ lnk_make_code_view_input(TP_Context *tp, TP_Arena *tp_arena, LNK_IO_Flags io_fla
}
ProfEnd();
ProfBegin("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();
tp_for_parallel_prof(tp, tp_arena, total_symbol_input_count, lnk_parse_cv_symbols_task, &(LNK_ParseCVSymbolsTaskData){ .inputs = symbol_inputs }, "Symbol Parse");
// TODO: do we rely on this behaviour?
//
@@ -2670,63 +2666,23 @@ THREAD_POOL_TASK_FUNC(lnk_make_proc_refs_task)
}
internal
THREAD_POOL_TASK_FUNC(lnk_process_sym_data_task)
THREAD_POOL_TASK_FUNC(lnk_fixup_symbol_offsets_task)
{
ProfBeginFunction();
U64 obj_idx = task_id;
LNK_ProcessSymDataTaskData *task = raw_task;
CV_SymbolListArray parsed_symbols = task->parsed_symbols[obj_idx];
CV_SymbolListArray symbols = task->parsed_symbols[task_id];
static CV_Signature MODULE_SYMBOL_SIGNATURE = CV_Signature_C13;
ProfBegin("Compute Buffer Size");
U64 buffer_size = sizeof(MODULE_SYMBOL_SIGNATURE);
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;
// fixup symbol offsets and estimate symbol data size
U64 size = sizeof(CV_Signature);
for EachIndex(i, symbols.count) {
size += cv_patch_symbol_tree_offsets(symbols.v[i], size, PDB_SYMBOL_ALIGN);
}
ProfEnd();
// 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));
task->serialized_symbol_data_sizes[task_id] = AlignPow2(size, CV_C13SubSectionAlign);
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
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
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
task->c13_data_arr[obj_idx] = c13_data;
task->source_file_names_list_arr[obj_idx] = source_file_names_list;
scratch_end(scratch);
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
THREAD_POOL_TASK_FUNC(lnk_write_module_data_task)
{
U64 obj_idx = task_id;
LNK_WriteModuleDataTask *task = raw_task;
PDB_DbiModule *mod = task->mod_arr[obj_idx];
String8List sym_data = task->symbol_data_arr[obj_idx];
String8List c11_data = task->c11_data_list_arr[obj_idx];
String8List c13_data = task->c13_data_list_arr[obj_idx];
String8List globrefs = task->globrefs_arr[obj_idx];
U64 obj_idx = task_id;
PDB_DbiModule *mod = task->mod_arr [obj_idx];
CV_DebugS *debug_s = &task->debug_s_arr [obj_idx];
CV_SymbolListArray parsed_symbols = task->parsed_symbols [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);
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);
MSF_UInt stream_cap = msf_stream_get_cap(task->msf, mod->sn);
// layout module data
String8List module_data = {0};
str8_list_concat_in_place(&module_data, &sym_data);
str8_list_concat_in_place(&module_data, &c11_data);
str8_list_concat_in_place(&module_data, &c13_data);
str8_list_concat_in_place(&module_data, &globrefs);
// write symbols
if (sym_data_size > 0) {
Temp scratch = scratch_begin(&arena, 1);
U64 temp_max = max_U16;
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
// during multi-thread write
MSF_UInt stream_pos = 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
}
AssertAlways(task->mod_sizes[obj_idx] == msf_stream_get_pos(task->msf, mod->sn));
}
internal
@@ -3078,7 +3040,7 @@ lnk_build_pdb(TP_Context *tp,
ProfBegin("Reserve DBI Modules");
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];
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);
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");
{
TP_Temp temp = tp_temp_begin(tp_arena);
{
ProfBegin("Reloc Module Data");
ProfBegin("Serialize Symbols");
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);
ProfBegin("Fixup Symbol Offsets");
U64 *serialized_symbol_data_sizes = push_array(scratch.arena, U64, obj_count);
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 });
ProfEnd();
// TODO: actually collect offsets and pass them here
ProfBegin("Build Empty Global Reference Array");
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];
str8_serial_begin(tp_arena->v[0], globrefs);
Assert(globrefs->total_size == 0);
@@ -3130,43 +3100,33 @@ lnk_build_pdb(TP_Context *tp,
// reserve memory for module streams
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
U64 mod_size = 0;
mod_size += serialized_symbol_data[obj_idx].total_size;
mod_size += processed_c11.data_list_arr[obj_idx].total_size;
mod_size += processed_c13.data_list_arr[obj_idx].total_size;
mod_size += cv_size_from_debug_s(&debug_s_arr[obj_idx], CV_C13SubSectionAlign);
mod_size += serialized_symbol_data_sizes[obj_idx];
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
PDB_DbiModule *mod = mod_arr[obj_idx];
mod->sn = msf_stream_alloc_ex(pdb->msf, mod_size32);
mod_arr[obj_idx]->sn = msf_stream_alloc_ex(pdb->msf, mod_sizes[obj_idx]);
}
ProfEnd();
// copy data to module streams
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.mod_arr = mod_arr;
write_module_data_task_data.symbol_data_arr = serialized_symbol_data;
write_module_data_task_data.c11_data_list_arr = processed_c11.data_list_arr;
write_module_data_task_data.c13_data_list_arr = processed_c13.data_list_arr;
write_module_data_task_data.debug_s_arr = debug_s_arr;
write_module_data_task_data.serialized_symbol_data_sizes = serialized_symbol_data_sizes;
write_module_data_task_data.parsed_symbols = parsed_symbols;
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);
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);
}
+7 -9
View File
@@ -232,8 +232,10 @@ typedef struct
typedef struct
{
U64 total_symbol_input_count;
LNK_CodeViewSymbolsInput *symbol_inputs;
CV_SymbolListArray *parsed_symbols;
U64 *serialized_symbol_data_sizes;
LNK_CodeViewSymbolsInput *symbol_inputs;
PDB_DbiModule **mod_arr;
String8List *symbol_data_arr;
CV_SymbolList *gsi_list_arr;
@@ -242,9 +244,6 @@ typedef struct
typedef struct
{
CV_DebugS *debug_s_arr;
MSF_Context *msf;
PDB_DbiModule **dbi_mod_arr;
String8List *c13_data_arr;
String8List *source_file_names_list_arr;
U64 string_data_base_offset;
CV_StringHashTable string_ht;
@@ -254,10 +253,11 @@ typedef struct
{
MSF_Context *msf;
PDB_DbiModule **mod_arr;
String8List *symbol_data_arr;
String8List *c11_data_list_arr;
String8List *c13_data_list_arr;
CV_DebugS *debug_s_arr;
U64 *serialized_symbol_data_sizes;
CV_SymbolListArray *parsed_symbols;
String8List *globrefs_arr;
U32 *mod_sizes;
} LNK_WriteModuleDataTask;
typedef struct
@@ -509,8 +509,6 @@ lnk_build_rad_debug_info(TP_Context *tp,
// --- 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 CV_SymbolPtrArray lnk_dedup_gsi_symbols (TP_Context *tp, Arena *arena, PDB_GsiContext *gsi, U64 obj_count, CV_SymbolList *symbol_list_arr);
+9 -2
View File
@@ -1335,9 +1335,16 @@ msf_stream_read_string(Arena *arena, MSF_Context *msf, MSF_StreamNumber sn)
internal void
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_aligned = AlignPow2(pos, align);
msf_stream_seek(msf, sn, pos_aligned);
MSF_UInt pad = AlignPadPow2(pos, align);
if (pad > 0) {
if (pad < sizeof(zeroes)) {
msf_stream_write(msf, sn, zeroes, pad);
} else {
NotImplemented;
}
}
}
////////////////////////////////