fixup file checksums in the MSF streams

This commit is contained in:
Nikita Smith
2026-04-06 12:04:32 -07:00
parent 6b7cd39ff1
commit b5f0862a91
10 changed files with 360 additions and 606 deletions
+72 -343
View File
@@ -202,6 +202,7 @@ cv_write_symbol_buf(String8Node *buf, U64 *buf_pos, CV_Symbol *symbol, U64 align
CV_SymSize record_size16 = (CV_SymSize)record_size; CV_SymSize record_size16 = (CV_SymSize)record_size;
U64 write_size = 0; U64 write_size = 0;
write_size += str8_buffer_write(buf, buf_pos, str8((U8 *)&(CV_SymbolHeader){ .size = record_size16, .kind = symbol->kind }, sizeof(CV_SymbolHeader))); write_size += str8_buffer_write(buf, buf_pos, str8((U8 *)&(CV_SymbolHeader){ .size = record_size16, .kind = symbol->kind }, sizeof(CV_SymbolHeader)));
write_size += str8_buffer_write(buf, buf_pos, symbol->data); write_size += str8_buffer_write(buf, buf_pos, symbol->data);
write_size += str8_buffer_write_zeroes(buf, buf_pos, AlignPadPow2(symbol->data.size, align)); write_size += str8_buffer_write_zeroes(buf, buf_pos, AlignPadPow2(symbol->data.size, align));
@@ -383,6 +384,43 @@ cv_make_envblock(Arena *arena, String8List string_list)
return result; return result;
} }
internal String8
cv_make_proc32(Arena *arena, CV_SymProc32 proc, String8 name)
{
U64 buf_size = sizeof(proc) + name.size + 1;
U8 *buf = push_array(arena, U8, buf_size);
CV_SymProc32 *proc_dst = (CV_SymProc32 *)buf;
MemoryCopy(proc_dst, &proc, sizeof(proc));
MemoryCopy(proc_dst + 1, name.str, name.size);
MemorySet((U8 *)(proc_dst + 1) + name.size , 0, 1);
String8 result = str8(buf, buf_size);
return result;
}
internal String8
cv_make_end(Arena *arena)
{ (void)arena;
return str8_zero();
}
internal String8
cv_make_inline_site(Arena *arena, CV_SymInlineSite inline_site, String8 annots)
{
U64 buf_size = sizeof(inline_site) + annots.size;
U8 *buf = push_array(arena, U8, buf_size);
CV_SymInlineSite *inline_dst = (CV_SymInlineSite *)buf;
MemoryCopy(inline_dst, &inline_site, sizeof(inline_site));
MemoryCopy(inline_dst + 1, annots.str, annots.size);
String8 result = str8(buf, buf_size);
return result;
}
internal String8
cv_make_inline_site_end(Arena *arena)
{ (void)arena;
return str8_zero();
}
internal CV_Symbol internal CV_Symbol
cv_make_proc_ref(Arena *arena, CV_ModIndex imod, U32 stream_offset, String8 name, B32 is_local) cv_make_proc_ref(Arena *arena, CV_ModIndex imod, U32 stream_offset, String8 name, B32 is_local)
{ {
@@ -428,27 +466,6 @@ cv_make_pub32(Arena *arena, CV_Pub32Flags flags, U32 off, U16 isect, String8 nam
return symbol; return symbol;
} }
internal CV_SymbolList
cv_make_proc_refs(Arena *arena, CV_ModIndex imod, CV_SymbolList symbol_list)
{
CV_SymbolList proc_ref_list = {0};
for (CV_SymbolNode *symbol_node = symbol_list.first; symbol_node != 0; symbol_node = symbol_node->next) {
CV_Symbol *symbol = &symbol_node->data;
if (symbol->kind == CV_SymKind_GPROC32) {
String8 name = cv_name_from_symbol(symbol->kind, symbol->data);
CV_Symbol ref = cv_make_proc_ref(arena, imod, safe_cast_u32(symbol->offset), name, /* is_local: */ 0);
CV_SymbolNode *proc_ref_node = cv_symbol_list_push(arena, &proc_ref_list);
proc_ref_node->data = ref;
} else if (symbol->kind == CV_SymKind_LPROC32) {
String8 name = cv_name_from_symbol(symbol->kind, symbol->data);
CV_Symbol ref = cv_make_proc_ref(arena, imod, safe_cast_u32(symbol->offset), name, /* is_local */ 1);
CV_SymbolNode *proc_ref_node = cv_symbol_list_push(arena, &proc_ref_list);
proc_ref_node->data = ref;
}
}
return proc_ref_list;
}
internal B32 internal B32
cv_is_lproc(CV_Symbol symbol) cv_is_lproc(CV_Symbol symbol)
{ {
@@ -1198,61 +1215,6 @@ cv_debug_t_is_type_server_ref(CV_DebugT *debug_t)
// $$Symbols // $$Symbols
internal void
cv_parse_symbol_sub_section_capped(Arena *arena, CV_SymbolList *list, U64 offset_base, String8 data, U64 align, U64 cap)
{
U64 count = 0;
for (U64 cursor = 0, opl = data.size; cursor < opl && count < cap; count += 1) {
// read symbol header
CV_SymbolHeader header;
cursor += str8_deserial_read_struct(data, cursor, &header);
// size from header has to be larger than 2 bytes
if (header.size < sizeof(header.kind)) {
Assert(!"TODO: error handle invalid symbol data");
break;
}
// is there enough bytes in the range?
U64 symbol_opl = cursor + (header.size - sizeof(header.kind));
if (symbol_opl > opl) {
Assert(!"TODO: error handle corrupted symbol data");
break;
}
// get symbol data
Rng1U64 symbol_data_range = r1u64(cursor, symbol_opl);
String8 symbol_data = str8_substr(data, symbol_data_range);
// init symbol
CV_SymbolNode *node = cv_symbol_list_push(arena, list);
node->data.offset = offset_base + cursor;
node->data.kind = header.kind;
node->data.data = symbol_data;
// advance cursor
cursor = symbol_opl;
cursor = AlignPow2(cursor, align);
}
}
internal void
cv_parse_symbol_sub_section(Arena *arena, CV_SymbolList *list, U64 offset_base, String8 data, U64 align)
{
cv_parse_symbol_sub_section_capped(arena, list, offset_base, data, align, max_U64);
}
internal CV_SymbolList
cv_symbol_list_from_data_list(Arena *arena, String8List data_list, U64 align)
{
CV_SymbolList symbol_list = {0};
U64 cursor = 0;
for (String8Node *sect = data_list.first; sect != 0; cursor += sect->string.size, sect = sect->next) {
cv_parse_symbol_sub_section(arena, &symbol_list, cursor, sect->string, align);
}
return symbol_list;
}
internal void internal void
cv_symbol_list_push_node(CV_SymbolList *list, CV_SymbolNode *node) cv_symbol_list_push_node(CV_SymbolList *list, CV_SymbolNode *node)
{ {
@@ -1263,278 +1225,42 @@ cv_symbol_list_push_node(CV_SymbolList *list, CV_SymbolNode *node)
} }
internal CV_SymbolNode * internal CV_SymbolNode *
cv_symbol_list_push(Arena *arena, CV_SymbolList *list) cv_symbol_list_push(Arena *arena, CV_SymbolList *list, CV_Symbol v)
{ {
CV_SymbolNode *node = push_array(arena, CV_SymbolNode, 1); CV_SymbolNode *node = push_array(arena, CV_SymbolNode, 1);
node->data = v;
cv_symbol_list_push_node(list, node); cv_symbol_list_push_node(list, node);
return node; return node;
} }
internal CV_SymbolNode *
cv_symbol_list_push_data(Arena *arena, CV_SymbolList *list, CV_SymKind kind, String8 data)
{
CV_SymbolNode *node = cv_symbol_list_push(arena, list);
node->data.kind = kind;
node->data.data = data;
return node;
}
internal CV_SymbolNode *
cv_symbol_list_push_many(Arena *arena, CV_SymbolList *list, U64 count)
{
CV_SymbolNode *node_arr = push_array_no_zero(arena, CV_SymbolNode, 1);
for (U64 node_idx = 0; node_idx < count; node_idx += 1) {
cv_symbol_list_push_node(list, &node_arr[node_idx]);
}
return node_arr;
}
internal void
cv_symbol_list_remove_node(CV_SymbolList *list, CV_SymbolNode *node)
{
Assert(list->count > 0);
list->count -= 1;
DLLRemove(list->first, list->last, node);
}
internal void
cv_symbol_list_concat_in_place(CV_SymbolList *list, CV_SymbolList *to_concat)
{
SLLConcatInPlace(list, to_concat);
}
internal void
cv_symbol_list_concat_in_place_arr(CV_SymbolList *list, U64 count, CV_SymbolList *to_concat)
{
SLLConcatInPlaceArray(list, to_concat, count);
}
internal U64 internal U64
cv_symbol_list_arr_get_count(U64 count, CV_SymbolList *list_arr) cv_patch_symbol_tree_offsets(String8List raw_symbols, U64 base_offset, U64 align)
{
U64 result = 0;
for (U64 idx = 0; idx < count; idx += 1) {
result += list_arr[idx].count;
}
return result;
}
internal String8List
cv_write_symbol_list(Arena *arena, CV_SymbolList symbol_list, U64 align)
{
String8List data_list = {0};
for (CV_SymbolNode *node = symbol_list.first; node != 0; node = node->next) {
String8 data = cv_data_from_symbol(arena, &node->data, align);
str8_list_push(arena, &data_list, data);
}
return data_list;
}
internal
THREAD_POOL_TASK_FUNC(cv_symbol_list_syncer)
{
ProfBeginFunction();
CV_SymbolListSyncer *task = raw_task;
// context shortcuts
Rng1U64 list_range = task->list_range_arr[task_id];
U64 symbol_base = task->symbol_base_arr[task_id];
for (U64 list_idx = list_range.min, symbol_idx = symbol_base; list_idx < list_range.max; list_idx += 1) {
// pick up assigned list
CV_SymbolList list = task->list_arr[list_idx];
// fill out assigned range in the symbol array
for (CV_SymbolNode *node = list.first; node != 0; node = node->next, symbol_idx += 1) {
task->symbol_arr[symbol_idx] = node;
}
}
ProfEnd();
}
internal CV_SymbolPtrArray
cv_symbol_ptr_array_from_list(Arena *arena, TP_Context *tp, U64 count, CV_SymbolList *list_arr)
{
ProfBeginFunction();
Temp scratch = scratch_begin(&arena, 1);
U64 total_count = cv_symbol_list_arr_get_count(count, list_arr);
CV_SymbolListSyncer task = {0};
task.list_arr = list_arr;
task.symbol_arr = push_array_no_zero(arena, CV_SymbolNode *, total_count);
task.symbol_base_arr = push_array_no_zero(scratch.arena, U64, tp->worker_count);
task.list_range_arr = tp_divide_work(scratch.arena, count, tp->worker_count);
for (U64 thread_idx = 0, symbol_base = 0; thread_idx < tp->worker_count; thread_idx += 1) {
task.symbol_base_arr[thread_idx] = symbol_base;
Rng1U64 range = task.list_range_arr[thread_idx];
for (U64 list_idx = range.min; list_idx < range.max; list_idx += 1) {
symbol_base += list_arr[list_idx].count;
}
}
tp_for_parallel(tp, 0, tp->worker_count, cv_symbol_list_syncer, &task);
CV_SymbolPtrArray result = {0};
result.count = total_count;
result.v = task.symbol_arr;
scratch_end(scratch);
ProfEnd();
return result;
}
internal CV_Scope *
cv_scope_list_push(Arena *arena, CV_ScopeList *list)
{
CV_Scope *node = push_array(arena, CV_Scope, 1);
SLLQueuePush(list->first, list->last, node);
return node;
}
internal CV_SymbolList
cv_global_scope_symbols_from_list(Arena *arena, CV_SymbolList list)
{
CV_SymbolList gsym_list = {0};
S64 scope_depth = 0;
for (CV_SymbolNode *symbol_n = list.first; symbol_n != 0; symbol_n = symbol_n->next) {
CV_Symbol symbol = symbol_n->data;
if (cv_is_global_symbol(symbol.kind) && scope_depth == 0) {
cv_symbol_list_push_data(arena, &gsym_list, symbol.kind, symbol.data);
} else if (cv_is_scope_symbol(symbol.kind)) {
scope_depth += 1;
} else if (cv_is_end_symbol(symbol.kind)) {
scope_depth -= 1;
if (scope_depth < 0) {
break;
}
}
}
return gsym_list;
}
internal CV_ScopeList
cv_symbol_tree_from_symbol_list(Arena *arena, CV_SymbolList list)
{
Temp scratch = scratch_begin(&arena, 1);
CV_ScopeList root = {0};
// setup root frame
CV_ScopeFrame *stack = push_array(scratch.arena, CV_ScopeFrame, 1);
stack->list = &root;
for (CV_SymbolNode *symbol_node = list.first; symbol_node != 0; symbol_node = symbol_node->next) {
// store symbol in current scope
CV_Scope *scope = cv_scope_list_push(arena, stack->list);
scope->symbol = symbol_node->data;
// does this symbol define a new scope?
if (cv_is_scope_symbol(symbol_node->data.kind)) {
CV_ScopeFrame *frame = push_array(scratch.arena, CV_ScopeFrame, 1);
frame->list = push_array(arena, CV_ScopeList, 1);
SLLStackPush(stack, frame);
}
// does this symbol end current scope?
else if (cv_is_end_symbol(symbol_node->data.kind)) {
CV_ScopeFrame *prev_stack_frame = stack->next;
if (prev_stack_frame) {
// set children in parent scope
CV_Scope *parent_scope = prev_stack_frame->list->last;
parent_scope->children = stack->list;
}
// pop frame
SLLStackPop(stack);
}
}
scratch_end(scratch);
return root;
}
internal U64
cv_patch_symbol_tree_offsets(CV_SymbolList list, U64 base_offset, U64 align)
{
struct Stack {
struct Stack *next;
CV_Symbol *symbol;
U64 offset;
};
Temp scratch = scratch_begin(0, 0);
struct Stack *stack = 0;
struct Stack *free_list = 0;
U32 cursor = safe_cast_u32(base_offset);
for EachNode(symbol_n, CV_SymbolNode, list.first) {
CV_Symbol symbol = symbol_n->data;
if (cv_is_scope_symbol(symbol.kind)) {
// NOTE: We don't patch 'next' offset in PROC symbols because
// it's not used by visual studio and MSVC leaves the offsets
// zeroed. LLD is on the same page.
Assert(symbol.data.size >= sizeof(U32)*2);
// patch parent symbol offset
if (stack) {
memory_write32(symbol.data.str, stack->offset);
}
// reuse/alloc frame
struct Stack *frame;
if (free_list) {
frame = free_list;
SLLStackPop(free_list);
} else {
frame = push_array_no_zero(scratch.arena, struct Stack, 1);
}
// push frame to the stack
frame->symbol = &symbol_n->data;
frame->offset = cursor;
SLLStackPush(stack, frame);
} else if (cv_is_end_symbol(symbol.kind)) {
// patch symbol end
U32 *end_off_ptr = (U32 *)stack->symbol->data.str + /* skip parent off */ 1;
memory_write32(end_off_ptr, cursor);
// recycle frame
struct Stack *free_frame = stack;
SLLStackPop(stack);
SLLStackPush(free_list, free_frame);
}
// advance cursor
cursor += cv_size_from_symbol(&symbol, align);
}
scratch_end(scratch);
U64 serial_size = cursor - base_offset;
return serial_size;
}
internal U64
cv_patch_symbol_tree_offsets_new(String8List raw_symbols, U64 base_offset, U64 align)
{ {
Temp scratch = scratch_begin(0, 0); Temp scratch = scratch_begin(0, 0);
struct Stack { struct Stack *next; CV_Symbol symbol; U64 offset; };
struct Stack { struct Stack *next; String8Node symbol_buf; U64 symbol_pos; U64 offset; };
struct Stack *stack = 0, *free_list = 0; struct Stack *stack = 0, *free_list = 0;
U64 symbol_offset = safe_cast_u32(base_offset);
for EachNode(n, String8Node, raw_symbols.first) {
for (U64 cursor = 0, depth = 0; cursor + sizeof(CV_SymbolHeader) <= n->string.size; ) {
CV_Symbol symbol = {0};
TryReadBreak(cv_read_symbol(n->string, cursor, align, &symbol), cursor);
if (cv_is_scope_symbol(symbol.kind)) { String8Node buf = *raw_symbols.first;
U64 buf_pos = 0;
U64 symbol_offset = base_offset;
U64 depth = 0;
for (;;) {
CV_SymbolHeader symbol_header;
if (str8_buffer_read(&buf, &buf_pos, sizeof(symbol_header), &symbol_header) != sizeof(symbol_header)) { break; }
if (cv_is_scope_symbol(symbol_header.kind)) {
// NOTE: We don't patch 'next' offset in PROC symbols because // NOTE: We don't patch 'next' offset in PROC symbols because
// it's not used by visual studio and MSVC leaves the offsets // it's not used by visual studio and MSVC leaves the offsets
// zeroed. LLD is on the same page. // zeroed. LLD is on the same page.
Assert(symbol.data.size >= sizeof(U32)*2); Assert(symbol_header.size >= sizeof(CV_SymKind) + sizeof(U32)*2);
// patch parent symbol offset // patch parent symbol offset
if (stack) { if (stack) {
memory_write32(symbol.data.str, stack->offset); String8Node temp_buf = buf;
U64 temp_pos = buf_pos;
str8_buffer_write_u32(&temp_buf, &temp_pos, stack->offset);
} }
// reuse/alloc frame // reuse/alloc frame
@@ -1543,29 +1269,33 @@ cv_patch_symbol_tree_offsets_new(String8List raw_symbols, U64 base_offset, U64 a
else { frame = push_array_no_zero(scratch.arena, struct Stack, 1); } else { frame = push_array_no_zero(scratch.arena, struct Stack, 1); }
// push frame to the stack // push frame to the stack
frame->symbol = symbol; frame->symbol_buf = buf;
frame->offset = symbol_offset; frame->symbol_pos = buf_pos;
frame->offset = safe_cast_u32(symbol_offset);
SLLStackPush(stack, frame); SLLStackPush(stack, frame);
depth += 1; depth += 1;
} else if (cv_is_end_symbol(symbol.kind)) { } else if (cv_is_end_symbol(symbol_header.kind)) {
// patch symbol end // patch symbol end
U32 *end_off_ptr = (U32 *)stack->symbol.data.str + /* skip parent off */ 1; String8Node temp_buf = stack->symbol_buf;
memory_write32(end_off_ptr, symbol_offset); U64 temp_pos = stack->symbol_pos;
str8_buffer_skip(&temp_buf, &temp_pos, sizeof(U32)); // skip parent offset
str8_buffer_write_u32(&temp_buf, &temp_pos, symbol_offset);
// recycle frame // recycle frame
struct Stack *free_frame = stack; struct Stack *free_frame = stack;
SLLStackPop(stack); SLLStackPop(stack);
SLLStackPush(free_list, free_frame); SLLStackPush(free_list, free_frame);
if (depth == 0) { Assert(0 && "malformed symbol stream"); goto next_block; } if (depth == 0) { Assert(0 && "malformed symbol stream"); continue; }
depth -= 1; depth -= 1;
} }
// advance tree offset // advance symbol offset
symbol_offset += cv_size_from_symbol(&symbol, align); symbol_offset += sizeof(CV_SymSize) + symbol_header.size;
} symbol_offset = AlignPow2(symbol_offset, align);
next_block:;
str8_buffer_skip(&buf, &buf_pos, symbol_header.size - sizeof(CV_SymKind));
} }
scratch_end(scratch); scratch_end(scratch);
@@ -1618,12 +1348,11 @@ cv_c13_parse_checksum_data_list(Arena *arena, String8List checksum_data_list)
internal void internal void
cv_c13_patch_string_offsets_in_checksum_list(CV_ChecksumList checksum_list, String8 string_data, U64 string_data_base_offset, CV_StringHashTable string_ht) cv_c13_patch_string_offsets_in_checksum_list(CV_ChecksumList checksum_list, String8 string_data, U64 string_data_base_offset, CV_StringHashTable string_ht)
{ {
for (CV_ChecksumNode *node = checksum_list.first; node != 0; node = node->next) { for EachNode(node, CV_ChecksumNode, checksum_list.first) {
CV_Checksum *checksum = &node->data; CV_Checksum *checksum = &node->data;
CV_C13Checksum *header = checksum->header; CV_C13Checksum *header = checksum->header;
String8 name = str8_cstring_capped(string_data.str + header->name_off, string_data.str + string_data.size); String8 name = str8_cstring_capped(string_data.str + header->name_off, string_data.str + string_data.size);
CV_StringBucket *bucket = cv_string_hash_table_lookup(string_ht, name); CV_StringBucket *bucket = cv_string_hash_table_lookup(string_ht, name);
U64 name_off64 = string_data_base_offset + bucket->u.offset; U64 name_off64 = string_data_base_offset + bucket->u.offset;
header->name_off = safe_cast_u32(name_off64); header->name_off = safe_cast_u32(name_off64);
} }
+3 -57
View File
@@ -42,12 +42,6 @@ typedef struct CV_SymbolNode
CV_Symbol data; CV_Symbol data;
} CV_SymbolNode; } CV_SymbolNode;
typedef struct CV_SymbolPtrNode
{
struct CV_SymbolPtrNode *next;
CV_Symbol *data;
} CV_SymbolPtrNode;
typedef struct CV_SymbolList typedef struct CV_SymbolList
{ {
U64 count; U64 count;
@@ -62,36 +56,6 @@ typedef struct CV_SymbolListArray
CV_SymbolList *v; CV_SymbolList *v;
} CV_SymbolListArray; } CV_SymbolListArray;
typedef struct CV_SymbolPtrArray
{
U64 count;
CV_SymbolNode **v;
} CV_SymbolPtrArray;
typedef struct CV_Scope
{
struct CV_ScopeList *children;
struct CV_Scope *next;
struct CV_Scope *prev;
CV_Symbol symbol;
} CV_Scope;
typedef struct CV_ScopeList
{
CV_Scope *first;
CV_Scope *last;
} CV_ScopeList;
typedef struct CV_ScopeFrame
{
struct CV_ScopeFrame *next;
CV_ScopeList *list;
CV_Scope *curr;
U64 symbol_off;
U32 *parent_off_ptr;
U32 *end_off_ptr;
} CV_ScopeFrame;
//- $$FileChksms //- $$FileChksms
typedef struct CV_Checksum typedef struct CV_Checksum
@@ -340,14 +304,6 @@ typedef struct CV_StringHashTableResult
//////////////////////////////// ////////////////////////////////
//~ Task Contexts //~ Task Contexts
typedef struct
{
CV_SymbolList *list_arr;
Rng1U64 *list_range_arr;
U64 *symbol_base_arr;
CV_SymbolNode **symbol_arr;
} CV_SymbolListSyncer;
typedef struct typedef struct
{ {
CV_DebugS *arr; CV_DebugS *arr;
@@ -401,6 +357,7 @@ internal String8 cv_make_symbol(Arena *arena, CV_SymKind kind, String8 dat
internal String8 cv_make_obj_name(Arena *arena, String8 obj_path, U32 sig); internal String8 cv_make_obj_name(Arena *arena, String8 obj_path, U32 sig);
internal String8 cv_make_comp3(Arena *arena, CV_Compile3Flags flags, CV_Language lang, CV_Arch arch, U16 ver_fe_major, U16 ver_fe_minor, U16 ver_fe_build, U16 ver_feqfe, U16 ver_major, U16 ver_minor, U16 ver_build, U16 ver_qfe, String8 version_string); internal String8 cv_make_comp3(Arena *arena, CV_Compile3Flags flags, CV_Language lang, CV_Arch arch, U16 ver_fe_major, U16 ver_fe_minor, U16 ver_fe_build, U16 ver_feqfe, U16 ver_major, U16 ver_minor, U16 ver_build, U16 ver_qfe, String8 version_string);
internal String8 cv_make_envblock(Arena *arena, String8List string_list); internal String8 cv_make_envblock(Arena *arena, String8List string_list);
internal String8 cv_make_end(Arena *arena);
internal CV_Symbol cv_make_proc_ref(Arena *arena, CV_ModIndex imod, U32 stream_offset, String8 name, B32 is_local); internal CV_Symbol cv_make_proc_ref(Arena *arena, CV_ModIndex imod, U32 stream_offset, String8 name, B32 is_local);
internal CV_Symbol cv_make_pub32(Arena *arena, CV_Pub32Flags flags, U32 off, U16 isect, String8 name); internal CV_Symbol cv_make_pub32(Arena *arena, CV_Pub32Flags flags, U32 off, U16 isect, String8 name);
@@ -448,21 +405,10 @@ internal B32 cv_debug_t_is_type_server_ref(CV_DebugT *debug_t);
//~ Sub Section helpers //~ Sub Section helpers
// $$Symbols // $$Symbols
internal void cv_parse_symbol_sub_section_capped(Arena *arena, CV_SymbolList *list, U64 offset_base, String8 data, U64 align, U64 cap);
internal void cv_parse_symbol_sub_section(Arena *arena, CV_SymbolList *list, U64 offset_base, String8 data, U64 align);
internal void cv_symbol_list_push_node(CV_SymbolList *list, CV_SymbolNode *node); internal void cv_symbol_list_push_node(CV_SymbolList *list, CV_SymbolNode *node);
internal CV_SymbolNode * cv_symbol_list_push(Arena *arena, CV_SymbolList *list); internal CV_SymbolNode * cv_symbol_list_push(Arena *arena, CV_SymbolList *list, CV_Symbol v);
internal CV_SymbolNode * cv_symbol_list_push_data(Arena *arena, CV_SymbolList *list, CV_SymKind kind, String8 data);
internal CV_SymbolNode * cv_symbol_list_push_many(Arena *arena, CV_SymbolList *list, U64 count);
internal void cv_symbol_list_remove_node(CV_SymbolList *list, CV_SymbolNode *node);
internal void cv_symbol_list_concat_in_place(CV_SymbolList *list, CV_SymbolList *to_concat);
internal void cv_symbol_list_concat_in_place_arr(CV_SymbolList *list, U64 count, CV_SymbolList *to_concat);
internal U64 cv_symbol_list_arr_get_count(U64 count, CV_SymbolList *list_arr);
internal String8List cv_write_symbol_list(Arena *arena, CV_SymbolList symbol_list, U64 align); internal U64 cv_patch_symbol_tree_offsets(String8List raw_symbols, U64 base_offset, U64 align);
internal CV_SymbolList cv_global_scope_symbols_from_list(Arena *arena, CV_SymbolList list);
internal CV_SymbolPtrArray cv_symbol_ptr_array_from_list(Arena *arena, TP_Context *tp, U64 count, CV_SymbolList *symbol_list_arr);
// $$FileChksms // $$FileChksms
#define CV_MAP_STRING_TO_OFFSET_FUNC(name) U64 name(void *ud, String8 string) #define CV_MAP_STRING_TO_OFFSET_FUNC(name) U64 name(void *ud, String8 string)
+5 -10
View File
@@ -842,15 +842,10 @@ lnk_make_linker_coff_obj(Arena *arena,
String8 debug_symbols = {0}; String8 debug_symbols = {0};
{ {
CV_SymbolList symbol_list = { .signature = CV_Signature_C13 }; String8List symbols = {0};
// S_OBJ str8_list_push(scratch.arena, &symbols, cv_make_symbol(scratch.arena, CV_SymKind_OBJNAME, cv_make_obj_name(scratch.arena, obj_name, 0)));
String8 obj_data = cv_make_obj_name(scratch.arena, obj_name, 0); str8_list_push(scratch.arena, &symbols, cv_make_symbol(scratch.arena, CV_SymKind_COMPILE3, lnk_make_linker_compile3(scratch.arena, machine)));
cv_symbol_list_push_data(scratch.arena, &symbol_list, CV_SymKind_OBJNAME, obj_data);
// S_COMPILE3
String8 comp3_data = lnk_make_linker_compile3(scratch.arena, machine);
cv_symbol_list_push_data(scratch.arena, &symbol_list, CV_SymKind_COMPILE3, comp3_data);
// S_ENVBLOCK // S_ENVBLOCK
String8List env_list = {0}; String8List env_list = {0};
@@ -864,12 +859,12 @@ lnk_make_linker_coff_obj(Arena *arena,
str8_list_push(scratch.arena, &env_list, cmd_line); str8_list_push(scratch.arena, &env_list, cmd_line);
str8_list_push(scratch.arena, &env_list, str8_lit("")); str8_list_push(scratch.arena, &env_list, str8_lit(""));
str8_list_push(scratch.arena, &env_list, str8_lit("")); str8_list_push(scratch.arena, &env_list, str8_lit(""));
cv_symbol_list_push_data(scratch.arena, &symbol_list, CV_SymKind_ENVBLOCK, cv_make_envblock(scratch.arena, env_list)); str8_list_push(scratch.arena, &symbols, cv_make_symbol(scratch.arena, CV_SymKind_ENVBLOCK, cv_make_envblock(scratch.arena, env_list)));
// TODO: emit S_SECTION and S_COFFGROUP // TODO: emit S_SECTION and S_COFFGROUP
// TODO: emit S_TRAMPOLINE // TODO: emit S_TRAMPOLINE
debug_symbols = lnk_make_debug_s(scratch.arena, symbol_list); debug_symbols = lnk_make_debug_s(scratch.arena, symbols);
} }
String8 obj; String8 obj;
+13 -20
View File
@@ -4,7 +4,7 @@
internal String8 internal String8
lnk_make_linker_compile3(Arena *arena, COFF_MachineType machine) lnk_make_linker_compile3(Arena *arena, COFF_MachineType machine)
{ {
String8 comp3_data = cv_make_comp3(arena, return cv_make_comp3(arena,
0, 0,
CV_Language_LINK, CV_Language_LINK,
cv_arch_from_coff_machine(machine), cv_arch_from_coff_machine(machine),
@@ -17,18 +17,16 @@ lnk_make_linker_compile3(Arena *arena, COFF_MachineType machine)
/* ver_build */ 32537, /* ver_build */ 32537,
/* ver_qfe */ 0, /* ver_qfe */ 0,
str8_lit(BUILD_TITLE)); str8_lit(BUILD_TITLE));
return comp3_data;
} }
internal String8 internal String8
lnk_make_debug_s(Arena *arena, CV_SymbolList symbol_list) lnk_make_debug_s(Arena *arena, String8List symbols)
{ {
Temp scratch = scratch_begin(&arena, 1); Temp scratch = scratch_begin(&arena, 1);
CV_DebugS debug_s = {0}; cv_patch_symbol_tree_offsets(symbols, sizeof(CV_Signature), CV_SymbolAlign);
String8List *symbol_list_ptr = cv_sub_section_ptr_from_debug_s(&debug_s, CV_C13SubSectionKind_Symbols);
*symbol_list_ptr = cv_write_symbol_list(scratch.arena, symbol_list, CV_SymbolAlign);
CV_DebugS debug_s = { .data_list[CV_C13SubSectionIdxKind_Symbols] = symbols };
String8List debug_s_data_list = cv_data_from_debug_s_c13(scratch.arena, &debug_s, 1); String8List debug_s_data_list = cv_data_from_debug_s_c13(scratch.arena, &debug_s, 1);
String8 debug_s_data = str8_list_join(arena, &debug_s_data_list, 0); String8 debug_s_data = str8_list_join(arena, &debug_s_data_list, 0);
@@ -40,10 +38,11 @@ internal String8
lnk_make_linker_debug_symbols(Arena *arena, COFF_MachineType machine) lnk_make_linker_debug_symbols(Arena *arena, COFF_MachineType machine)
{ {
Temp scratch = scratch_begin(&arena, 1); Temp scratch = scratch_begin(&arena, 1);
CV_SymbolList symbol_list = { .signature = CV_Signature_C13 };
String8 comp3_data = lnk_make_linker_compile3(scratch.arena, machine); String8List symbols = {0};
cv_symbol_list_push_data(scratch.arena, &symbol_list, CV_SymKind_COMPILE3, comp3_data); str8_list_push(scratch.arena, &symbols, cv_make_symbol(scratch.arena, CV_SymKind_COMPILE3, lnk_make_linker_compile3(scratch.arena, machine)));
String8 debug_symbols = lnk_make_debug_s(arena, symbol_list); String8 debug_symbols = lnk_make_debug_s(arena, symbols);
scratch_end(scratch); scratch_end(scratch);
return debug_symbols; return debug_symbols;
} }
@@ -53,20 +52,14 @@ lnk_make_dll_import_debug_symbols(Arena *arena, COFF_MachineType machine, String
{ {
Temp scratch = scratch_begin(&arena,1); Temp scratch = scratch_begin(&arena,1);
CV_SymbolList symbol_list = { .signature = CV_Signature_C13 }; String8List symbols = {0};
str8_list_push(scratch.arena, &symbols, cv_make_symbol(scratch.arena, CV_SymKind_OBJNAME, cv_make_obj_name(scratch.arena, dll_name, 0)));
// S_OBJ str8_list_push(scratch.arena, &symbols, cv_make_symbol(scratch.arena, CV_SymKind_COMPILE3, lnk_make_linker_compile3(scratch.arena, machine)));
String8 obj_data = cv_make_obj_name(scratch.arena, dll_name, 0);
cv_symbol_list_push_data(scratch.arena, &symbol_list, CV_SymKind_OBJNAME, obj_data);
// S_COMPILE3
String8 comp3_data = lnk_make_linker_compile3(scratch.arena, machine);
cv_symbol_list_push_data(scratch.arena, &symbol_list, CV_SymKind_COMPILE3, comp3_data);
// TODO: add thunks // TODO: add thunks
// serialize symbols // serialize symbols
String8 debug_symbols = lnk_make_debug_s(arena, symbol_list); String8 debug_symbols = lnk_make_debug_s(arena, symbols);
scratch_end(scratch); scratch_end(scratch);
return debug_symbols; return debug_symbols;
+1 -1
View File
@@ -4,5 +4,5 @@
#pragma once #pragma once
internal String8 lnk_make_linker_compile3(Arena *arena, COFF_MachineType machine); internal String8 lnk_make_linker_compile3(Arena *arena, COFF_MachineType machine);
internal String8 lnk_make_debug_s(Arena *arena, CV_SymbolList symbol_list); internal String8 lnk_make_debug_s(Arena *arena, String8List symbols);
+164 -87
View File
@@ -15,6 +15,9 @@ lnk_get_huge_arena(void)
internal void internal void
lnk_discard_cv_debug_info(LNK_CodeViewInput *input, U64 obj_idx) lnk_discard_cv_debug_info(LNK_CodeViewInput *input, U64 obj_idx)
{ {
// discard types
MemoryZeroStruct(&input->debug_t_arr[obj_idx]);
// discard symbols // discard symbols
String8List *symbols_ptr = cv_sub_section_ptr_from_debug_s(&input->debug_s_arr[obj_idx], CV_C13SubSectionKind_Symbols); String8List *symbols_ptr = cv_sub_section_ptr_from_debug_s(&input->debug_s_arr[obj_idx], CV_C13SubSectionKind_Symbols);
MemoryZeroStruct(symbols_ptr); MemoryZeroStruct(symbols_ptr);
@@ -276,6 +279,8 @@ lnk_make_code_view_input(TP_Context *tp, TP_Arena *tp_arena, LNK_IO_Flags io_fla
ProfScope("Set up /Zi") ProfScope("Set up /Zi")
{ {
input.obj_to_ts = push_array(tp_arena->v[0], U64, input.count); input.obj_to_ts = push_array(tp_arena->v[0], U64, input.count);
MemorySet(input.obj_to_ts, 0xff, input.count * sizeof(input.obj_to_ts[0]));
LNK_TypeServerList ts_list = {0}; LNK_TypeServerList ts_list = {0};
HashTable *ts_ht = hash_table_init(scratch.arena, 256); HashTable *ts_ht = hash_table_init(scratch.arena, 256);
@@ -294,6 +299,11 @@ lnk_make_code_view_input(TP_Context *tp, TP_Arena *tp_arena, LNK_IO_Flags io_fla
CV_TypeServerInfo ts_info = cv_type_server_info_from_leaf(leaf); CV_TypeServerInfo ts_info = cv_type_server_info_from_leaf(leaf);
String8 ts_path = lnk_find_first_file(scratch.arena, lib_dir_list, ts_info.name); String8 ts_path = lnk_find_first_file(scratch.arena, lib_dir_list, ts_info.name);
if (ts_path.size == 0) {
lnk_discard_cv_debug_info(&input, obj_idx);
continue;
}
// insert new type server // insert new type server
LNK_TypeServer *ts = hash_table_search_path_raw(ts_ht, ts_path); LNK_TypeServer *ts = hash_table_search_path_raw(ts_ht, ts_path);
if (ts == 0) { if (ts == 0) {
@@ -313,6 +323,7 @@ lnk_make_code_view_input(TP_Context *tp, TP_Arena *tp_arena, LNK_IO_Flags io_fla
obj_arr[obj_idx], obj_arr[obj_idx],
"type server signature conflicts with type server from '%S'", "type server signature conflicts with type server from '%S'",
obj_arr[ts->obj_indices.first->data]->path); obj_arr[ts->obj_indices.first->data]->path);
lnk_discard_cv_debug_info(&input, obj_idx);
continue; continue;
} }
@@ -342,6 +353,7 @@ lnk_make_code_view_input(TP_Context *tp, TP_Arena *tp_arena, LNK_IO_Flags io_fla
MemoryCopyTyped(input.debug_s_arr, prev.debug_s_arr, prev.count); MemoryCopyTyped(input.debug_s_arr, prev.debug_s_arr, prev.count);
MemoryCopyTyped(input.debug_t_arr, prev.debug_t_arr, prev.count); MemoryCopyTyped(input.debug_t_arr, prev.debug_t_arr, prev.count);
MemoryCopyTyped(input.obj_to_ts, prev.obj_to_ts, prev.count); MemoryCopyTyped(input.obj_to_ts, prev.obj_to_ts, prev.count);
MemorySet(input.obj_to_ts + input.obj_count, 0xff, ts_arr.count * sizeof(input.obj_to_ts[0]));
input.ts_obj_range = r1u64(prev.count, input.count); input.ts_obj_range = r1u64(prev.count, input.count);
@@ -522,10 +534,10 @@ lnk_leaf_ref_from_ti(LNK_CodeViewInput *input, U32 obj_idx, CV_TypeIndexSource s
// ti range: external type server // ti range: external type server
U64 ts_idx = input->obj_to_ts[obj_idx]; U64 ts_idx = input->obj_to_ts[obj_idx];
if (ts_idx) { if (ts_idx != max_U64) {
U64 ts_obj_idx = input->ts_obj_range.min + ts_idx; U64 ts_debug_t_idx = input->ts_obj_range.min + ts_idx;
CV_DebugT *ts_debug_t = input->debug_t_arr + ts_obj_idx; CV_DebugT *ts_debug_t = input->debug_t_arr + ts_debug_t_idx;
return (LNK_LeafRef){ ts_obj_idx, cv_leaf_idx_from_ti(ts_debug_t, source, ti) }; return (LNK_LeafRef){ ts_debug_t_idx, cv_leaf_idx_from_ti(ts_debug_t, source, ti) };
} }
// ti range: internal type server // ti range: internal type server
@@ -553,14 +565,10 @@ internal B32
lnk_match_leaf_ref(LNK_CodeViewInput *input, LNK_LeafRef a, LNK_LeafRef b) lnk_match_leaf_ref(LNK_CodeViewInput *input, LNK_LeafRef a, LNK_LeafRef b)
{ {
B32 is_match = 0; B32 is_match = 0;
CV_DebugT *a_debug_t = &input->debug_t_arr[a.obj_idx];
CV_DebugT *b_debug_t = &input->debug_t_arr[b.obj_idx];
U64 a_hash = input->debug_h_arr[a.obj_idx].v[a.leaf_idx]; U64 a_hash = input->debug_h_arr[a.obj_idx].v[a.leaf_idx];
U64 b_hash = input->debug_h_arr[b.obj_idx].v[b.leaf_idx]; U64 b_hash = input->debug_h_arr[b.obj_idx].v[b.leaf_idx];
if (a_hash == b_hash) { if (a_hash == b_hash) {
CV_Leaf a_leaf = cv_debug_t_get_leaf(a_debug_t, a.leaf_idx); Assert(cv_debug_t_get_leaf(&input->debug_t_arr[a.obj_idx], a.leaf_idx).kind == cv_debug_t_get_leaf(&input->debug_t_arr[b.obj_idx], b.leaf_idx).kind);
CV_Leaf b_leaf = cv_debug_t_get_leaf(b_debug_t, b.leaf_idx);
Assert(a_leaf.kind == b_leaf.kind);
is_match = 1; is_match = 1;
} }
return is_match; return is_match;
@@ -633,7 +641,7 @@ lnk_hash_cv_leaf(LNK_CodeViewInput *input, LNK_LeafRef leaf_ref, CV_TypeIndexInf
U32 leaf_idx = curr_ti - debug_t->ti_ranges[curr_ti_source].min; U32 leaf_idx = curr_ti - debug_t->ti_ranges[curr_ti_source].min;
U8 *leaf_header = debug_t->data.str + debug_t->offsets[leaf_idx]; U8 *leaf_header = debug_t->data.str + debug_t->offsets[leaf_idx];
memory_write16(leaf_header + OffsetOf(CV_LeafHeader, kind), CV_LeafKind_NOTYPE); memory_write16(leaf_header + OffsetOf(CV_LeafHeader, kind), CV_LeafKind_NOTYPE);
memory_write16(leaf_header + OffsetOf(CV_LeafHeader, size), 0); memory_write16(leaf_header + OffsetOf(CV_LeafHeader, size), sizeof(CV_LeafKind));
// log error // log error
Temp scratch = scratch_begin(0,0); Temp scratch = scratch_begin(0,0);
@@ -1130,14 +1138,21 @@ lnk_fixup_cv_type_indices(LNK_MergeTypes *ctx, U32 obj_idx, String8 data, CV_Typ
// skip basic types // skip basic types
if (ti < ctx->input->min_type_indices[n->source]) { continue; } if (ti < ctx->input->min_type_indices[n->source]) { continue; }
CV_DebugT *debug_t;
if (ctx->input->obj_to_ts[obj_idx] != max_U64) {
U64 ts_idx = ctx->input->obj_to_ts[obj_idx]; U64 ts_idx = ctx->input->obj_to_ts[obj_idx];
CV_DebugT *debug_t = ts_idx ? &ctx->input->debug_t_arr[ctx->input->ts_obj_range.min + ts_idx] : &ctx->input->debug_t_arr[obj_idx]; U64 debug_t_idx = ctx->input->ts_obj_range.min + ts_idx;
debug_t = ctx->input->debug_t_arr + debug_t_idx;
} else {
debug_t = ctx->input->debug_t_arr + obj_idx;
}
CV_TypeIndex final_ti = 0; CV_TypeIndex final_ti = 0;
if (contains_1u64(debug_t->ti_ranges[n->source], ti)) { if (contains_1u64(debug_t->ti_ranges[n->source], ti)) {
LNK_LeafRef leaf_ref = lnk_leaf_ref_from_ti(ctx->input, obj_idx, n->source, ti); LNK_LeafRef leaf_ref = lnk_leaf_ref_from_ti(ctx->input, obj_idx, n->source, ti);
LNK_LeafHashTable *leaf_ht = &ctx->leaf_ht_arr[n->source]; LNK_LeafHashTable *leaf_ht = &ctx->leaf_ht_arr[n->source];
LNK_LeafRef *final_leaf = lnk_leaf_hash_table_search(leaf_ht, ctx->input, leaf_ref); LNK_LeafRef *final_leaf = lnk_leaf_hash_table_search(leaf_ht, ctx->input, leaf_ref);
if (final_leaf) {
U64 final_hash = u64_hash_from_str8(str8_struct(final_leaf)); U64 final_hash = u64_hash_from_str8(str8_struct(final_leaf));
final_ti = lnk_assigned_type_ht_search(ctx->assigned_type_caps [n->source], final_ti = lnk_assigned_type_ht_search(ctx->assigned_type_caps [n->source],
ctx->assigned_type_hts [n->source], ctx->assigned_type_hts [n->source],
@@ -1145,6 +1160,7 @@ lnk_fixup_cv_type_indices(LNK_MergeTypes *ctx, U32 obj_idx, String8 data, CV_Typ
ctx->unique_leaf_refs_arr[n->source], ctx->unique_leaf_refs_arr[n->source],
final_leaf, final_leaf,
final_hash); final_hash);
}
} else { } else {
Assert(0 && "invalid type index"); Assert(0 && "invalid type index");
} }
@@ -1323,7 +1339,7 @@ lnk_merge_types(TP_Context *tp, TP_Arena *tp_temp, LNK_CodeViewInput *input)
tp_for_parallel(tp, 0, task.indices.count, lnk_hash_debug_t_task, &task); tp_for_parallel(tp, 0, task.indices.count, lnk_hash_debug_t_task, &task);
task.indices = input->type_server_indices; task.indices = input->type_server_indices;
ProfScope("Type Servers [Count: %.*s]", str8_varg(str8_from_count(scratch.arena, task.indices.count))); ProfScope("Type Servers [Count: %.*s]", str8_varg(str8_from_count(scratch.arena, task.indices.count)))
tp_for_parallel(tp, 0, task.indices.count, lnk_hash_debug_t_deep_task, &task); tp_for_parallel(tp, 0, task.indices.count, lnk_hash_debug_t_deep_task, &task);
ProfEnd(); ProfEnd();
@@ -1755,9 +1771,6 @@ THREAD_POOL_TASK_FUNC(lnk_move_global_symbols_to_gsi)
void *ptr = cv_ptr_from_symbol(symbol); void *ptr = cv_ptr_from_symbol(symbol);
void_list_push(scratch.arena, &global_symbols, ptr); void_list_push(scratch.arena, &global_symbols, ptr);
} }
} else if (symbol.kind == 0x1176) {
CV_SymKind *kind_ptr = cv_kind_ptr_from_symbol(symbol);
*kind_ptr = CV_SymKind_SKIP;
} }
if (cv_is_scope_symbol(symbol.kind)) { if (cv_is_scope_symbol(symbol.kind)) {
@@ -1840,7 +1853,7 @@ THREAD_POOL_TASK_FUNC(lnk_move_global_symbols_to_gsi)
CV_DebugS debug_s = task->cv->debug_s_arr[obj_idx]; CV_DebugS debug_s = task->cv->debug_s_arr[obj_idx];
String8List symbols = cv_sub_section_from_debug_s(debug_s, CV_C13SubSectionKind_Symbols); String8List symbols = cv_sub_section_from_debug_s(debug_s, CV_C13SubSectionKind_Symbols);
for EachNode(n, String8Node, symbols.first) { for EachNode(n, String8Node, symbols.first) {
for (U64 cursor = 0, symbol_cursor = 0; cursor + sizeof(CV_SymbolHeader) <= n->string.size; ) { for (U64 cursor = 0; cursor + sizeof(CV_SymbolHeader) <= n->string.size; ) {
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);
@@ -1857,35 +1870,26 @@ THREAD_POOL_TASK_FUNC(lnk_move_global_symbols_to_gsi)
barrier_wait(tp->barrier); barrier_wait(tp->barrier);
if (task_id == 0) { if (task_id == 0) {
// take into account arena header
for EachIndex(i, tp->worker_count) { task->proc_ref_sizes[i] += ARENA_HEADER_SIZE; }
U64 total_proc_ref_count = sum_array_u64(tp->worker_count, task->proc_ref_counts); U64 total_proc_ref_count = sum_array_u64(tp->worker_count, task->proc_ref_counts);
// prealloc output buffer for the proc refs
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_ref_hashes = push_array(scratch.arena, U64, total_proc_ref_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_indices = offsets_from_counts_array_u64(scratch.arena, task->proc_ref_counts, tp->worker_count); task->proc_ref_indices = offsets_from_counts_array_u64(scratch.arena, task->proc_ref_counts, tp->worker_count);
task->proc_ref_arenas = alloc_arena_many(gsi->arena, tp->worker_count, task->proc_ref_sizes);
task->proc_ref_count = sum_array_u64(tp->worker_count, task->proc_ref_counts); 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); task->proc_ref_nodes = push_array(gsi->arena, CV_SymbolNode, task->proc_ref_count);
} }
barrier_wait(tp->barrier); barrier_wait(tp->barrier);
U64 proc_refs_size = task->proc_ref_sizes[task_id];
U64 proc_refs_off = task->proc_ref_offs[task_id];
U64 proc_ref_idx = task->proc_ref_indices[task_id]; U64 proc_ref_idx = task->proc_ref_indices[task_id];
U8 *proc_refs = task->proc_refs.str + proc_refs_off; Arena *proc_ref_arena = task->proc_ref_arenas[task_id];
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 });
for EachIndex(i, obj_indices.count) { for EachIndex(i, obj_indices.count) {
U64 obj_idx = obj_indices.v[i]; U64 obj_idx = obj_indices.v[i];
CV_DebugS debug_s = task->cv->debug_s_arr[obj_idx]; CV_DebugS debug_s = task->cv->debug_s_arr[obj_idx];
String8List symbols = cv_sub_section_from_debug_s(debug_s, CV_C13SubSectionKind_Symbols); String8List symbols = cv_sub_section_from_debug_s(debug_s, CV_C13SubSectionKind_Symbols);
CV_ModIndex imod = task->mod_arr[obj_idx]->imod; CV_ModIndex imod = task->mod_arr[obj_idx]->imod;
U64 symbol_cursor = sizeof(CV_Signature);
for EachNode(n, String8Node, symbols.first) { for EachNode(n, String8Node, symbols.first) {
for (U64 cursor = 0, symbol_cursor = 0; cursor + sizeof(CV_SymbolHeader) <= n->string.size; ) { for (U64 cursor = 0; cursor + sizeof(CV_SymbolHeader) <= n->string.size; ) {
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; } if (symbol.kind == CV_SymKind_SKIP) { continue; }
@@ -1944,25 +1948,16 @@ THREAD_POOL_TASK_FUNC(lnk_move_global_symbols_to_gsi)
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); 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_arenas = alloc_arena_many(psi->gsi->arena, tp->worker_count, task->public_symbol_sizes);
task->public_symbol_nodes = push_array(psi->gsi->arena, CV_SymbolNode, public_symbol_total_count); task->public_symbol_node_arenas = alloc_arena_array(psi->gsi->arena, tp->worker_count, task->public_symbol_node_counts, CV_SymbolNode);
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); task->public_symbol_hashes = push_array(scratch.arena, U32 *, tp->worker_count);
} }
barrier_wait(tp->barrier); barrier_wait(tp->barrier);
// make CV public symbols // 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];
for EachIndex(i, chunk->count) { for EachIndex(i, chunk->count) {
LNK_Symbol *symbol = chunk->v[i].symbol; LNK_Symbol *symbol = chunk->v[i].symbol;
LNK_ObjSymbolRef symbol_ref = lnk_ref_from_symbol(symbol); LNK_ObjSymbolRef symbol_ref = lnk_ref_from_symbol(symbol);
@@ -1975,11 +1970,8 @@ THREAD_POOL_TASK_FUNC(lnk_move_global_symbols_to_gsi)
CV_Pub32Flags flags = COFF_SymbolType_IsFunc(symbol_parsed.type) ? CV_Pub32Flag_Function : 0; CV_Pub32Flags flags = COFF_SymbolType_IsFunc(symbol_parsed.type) ? CV_Pub32Flag_Function : 0;
ISectOff sc = lnk_sc_from_symbol(symbol); ISectOff sc = lnk_sc_from_symbol(symbol);
CV_Symbol pub_symbol = cv_make_pub32(public_symbol_arena, flags, safe_cast_u32(sc.off), safe_cast_u16(sc.isect), symbol->name); CV_Symbol pub_symbol = cv_make_pub32(task->public_symbol_arenas[task_id], flags, safe_cast_u32(sc.off), safe_cast_u16(sc.isect), symbol->name);
cv_symbol_list_push(task->public_symbol_node_arenas[task_id], &task->public_symbols[task_id], pub_symbol);
task->public_symbol_nodes[node_idx].data = pub_symbol;
cv_symbol_list_push_node(&task->public_symbols[task_id], &task->public_symbol_nodes[node_idx]);
node_idx += 1;
} }
} }
barrier_wait(tp->barrier); barrier_wait(tp->barrier);
@@ -1998,11 +1990,11 @@ THREAD_POOL_TASK_FUNC(lnk_move_global_symbols_to_gsi)
// insert public symbols into PSI // 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 k = 0;
for (CV_SymbolNode *curr = task->public_symbols[i].first, *next = 0; curr != 0; curr = next) { for (CV_SymbolNode *curr = task->public_symbols[i].first, *next = 0; curr != 0; curr = next, k += 1) {
next = curr->next; next = curr->next;
gsi_push_(psi->gsi, task->public_symbol_hashes[i][curr_idx], curr); curr->next = 0;
curr_idx += 1; gsi_push_(psi->gsi, task->public_symbol_hashes[i][k], curr);
} }
} }
} }
@@ -2023,15 +2015,26 @@ lnk_write_debug_s_to_pdb_module(PDB_DbiModule *mod, CV_DebugS debug_s, String8No
mod->globrefs_size = 0; mod->globrefs_size = 0;
// signature // signature
mod_cursor += str8_buffer_write_u32(buf, buf_pos, CV_Signature_C13); U64 sig_size = str8_buffer_write_u32(buf, buf_pos, CV_Signature_C13);
mod->sym_data_size += sig_size;
mod_cursor += sig_size;
// write symbols // write symbols
String8List symbols = cv_sub_section_from_debug_s(debug_s, CV_C13SubSectionKind_Symbols); String8List symbols = cv_sub_section_from_debug_s(debug_s, CV_C13SubSectionKind_Symbols);
U64 scope_depth = 0;
for EachNode(n, String8Node, symbols.first) { for EachNode(n, String8Node, symbols.first) {
for (U64 cursor = 0; cursor + sizeof(CV_SymbolHeader) <= n->string.size; ) { for (U64 cursor = 0; cursor + sizeof(CV_SymbolHeader) <= n->string.size; ) {
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; } if (symbol.kind == CV_SymKind_SKIP) { continue; }
if (cv_is_global_symbol(symbol.kind)) { continue; }
else if (cv_is_typedef(symbol.kind) && scope_depth == 0) { continue; }
else if (symbol.kind == 0x1176) { continue; }
if (cv_is_scope_symbol(symbol.kind)) { scope_depth += 1; }
else if (cv_is_end_symbol(symbol.kind)) { scope_depth -= 1; }
U64 symbol_size = cv_write_symbol_buf(buf, buf_pos, &symbol, PDB_SYMBOL_ALIGN); U64 symbol_size = cv_write_symbol_buf(buf, buf_pos, &symbol, PDB_SYMBOL_ALIGN);
mod_cursor += symbol_size; mod_cursor += symbol_size;
mod->sym_data_size += symbol_size; mod->sym_data_size += symbol_size;
@@ -2039,19 +2042,19 @@ lnk_write_debug_s_to_pdb_module(PDB_DbiModule *mod, CV_DebugS debug_s, String8No
} }
// write file checksums, inlinee lines etc. // write file checksums, inlinee lines etc.
CV_C13SubSectionIdxKind mod_c13_layout[] = { CV_C13SubSectionKind mod_c13_layout[] = {
CV_C13SubSectionIdxKind_FileChksms, CV_C13SubSectionKind_FileChksms,
CV_C13SubSectionIdxKind_FrameData, CV_C13SubSectionKind_FrameData,
CV_C13SubSectionIdxKind_InlineeLines, CV_C13SubSectionKind_InlineeLines,
CV_C13SubSectionIdxKind_CrossScopeImports, CV_C13SubSectionKind_CrossScopeImports,
CV_C13SubSectionIdxKind_CrossScopeExports, CV_C13SubSectionKind_CrossScopeExports,
CV_C13SubSectionIdxKind_IlLines, CV_C13SubSectionKind_IlLines,
CV_C13SubSectionIdxKind_FuncMDTokenMap, CV_C13SubSectionKind_FuncMDTokenMap,
CV_C13SubSectionIdxKind_TypeMDTokenMap, CV_C13SubSectionKind_TypeMDTokenMap,
CV_C13SubSectionIdxKind_MergedAssemblyInput, CV_C13SubSectionKind_MergedAssemblyInput,
CV_C13SubSectionIdxKind_CoffSymbolRVA, CV_C13SubSectionKind_CoffSymbolRVA,
CV_C13SubSectionIdxKind_XfgHashType, CV_C13SubSectionKind_XfgHashType,
CV_C13SubSectionIdxKind_XfgHashVirtual, CV_C13SubSectionKind_XfgHashVirtual,
}; };
for EachElement(i, mod_c13_layout) { for EachElement(i, mod_c13_layout) {
String8List data = cv_sub_section_from_debug_s(debug_s, mod_c13_layout[i]); String8List data = cv_sub_section_from_debug_s(debug_s, mod_c13_layout[i]);
@@ -2059,7 +2062,7 @@ lnk_write_debug_s_to_pdb_module(PDB_DbiModule *mod, CV_DebugS debug_s, String8No
U64 ss_size = 0; U64 ss_size = 0;
ss_size += str8_buffer_write(buf, buf_pos, str8_struct((&(CV_C13SubSectionHeader ){ .kind = mod_c13_layout[i], .size = safe_cast_u32(data.total_size) }))); ss_size += str8_buffer_write(buf, buf_pos, str8_struct((&(CV_C13SubSectionHeader ){ .kind = mod_c13_layout[i], .size = safe_cast_u32(data.total_size) })));
ss_size += str8_buffer_write_string_list(buf, buf_pos, data); ss_size += str8_buffer_write_string_list(buf, buf_pos, data);
ss_size += str8_buffer_write_zeroes(buf, buf_pos, AlignPadPow2(mod_cursor, CV_C13SubSectionAlign)); ss_size += str8_buffer_write_zeroes(buf, buf_pos, AlignPadPow2(mod_cursor + ss_size, CV_C13SubSectionAlign));
mod_cursor += ss_size; mod_cursor += ss_size;
mod->c13_data_size += ss_size; mod->c13_data_size += ss_size;
} }
@@ -2071,18 +2074,16 @@ lnk_write_debug_s_to_pdb_module(PDB_DbiModule *mod, CV_DebugS debug_s, String8No
U64 ss_size = 0; U64 ss_size = 0;
ss_size += str8_buffer_write(buf, buf_pos, str8_struct((&(CV_C13SubSectionHeader){ .kind = CV_C13SubSectionKind_Lines, .size = safe_cast_u32(n->string.size) }))); ss_size += str8_buffer_write(buf, buf_pos, str8_struct((&(CV_C13SubSectionHeader){ .kind = CV_C13SubSectionKind_Lines, .size = safe_cast_u32(n->string.size) })));
ss_size += str8_buffer_write(buf, buf_pos, n->string); ss_size += str8_buffer_write(buf, buf_pos, n->string);
ss_size += str8_buffer_write_zeroes(buf, buf_pos, AlignPadPow2(mod_cursor, CV_C13SubSectionAlign)); ss_size += str8_buffer_write_zeroes(buf, buf_pos, AlignPadPow2(mod_cursor + ss_size, CV_C13SubSectionAlign));
mod_cursor += ss_size; mod_cursor += ss_size;
mod->c13_data_size += ss_size; mod->c13_data_size += ss_size;
} }
// write global refs // write global refs
String8List globrefs = cv_sub_section_from_debug_s(debug_s, CV_C13SubSectionKind_GlobalRefs); String8List globrefs = cv_sub_section_from_debug_s(debug_s, CV_C13SubSectionKind_GlobalRefs);
U64 globrefs_size = 0; mod->globrefs_size += str8_buffer_write_u32(buf, buf_pos, safe_cast_u32(globrefs.total_size));
globrefs_size += str8_buffer_write_u32(buf, buf_pos, safe_cast_u32(globrefs.total_size)); mod->globrefs_size += str8_buffer_write_string_list(buf, buf_pos, globrefs);
globrefs_size += str8_buffer_write_string_list(buf, buf_pos, globrefs); mod_cursor += mod->globrefs_size;
mod_cursor += globrefs_size;
mod->globrefs_size += globrefs_size;
return mod_cursor; return mod_cursor;
} }
@@ -2121,38 +2122,111 @@ THREAD_POOL_TASK_FUNC(lnk_write_pdb_modules)
U64 obj_idx = obj_indices.v[i]; U64 obj_idx = obj_indices.v[i];
PDB_DbiModule *mod = task->mod_arr[obj_idx]; PDB_DbiModule *mod = task->mod_arr[obj_idx];
CV_DebugS debug_s = task->cv->debug_s_arr[obj_idx]; CV_DebugS debug_s = task->cv->debug_s_arr[obj_idx];
String8List mod_data = msf_data_from_sn(temp.arena, task->pdb->msf, mod->sn);
String8List mod_pages = msf_raw_pages_from_sn(temp.arena, task->pdb->msf, mod->sn); if (mod_data.node_count) {
if (mod_pages.node_count == 0) { continue; } String8Node buf = *mod_data.first;
String8Node buf = *mod_pages.first;
U64 pos = 0; U64 pos = 0;
lnk_write_debug_s_to_pdb_module(mod, debug_s, &buf, &pos); lnk_write_debug_s_to_pdb_module(mod, debug_s, &buf, &pos);
// sub range symbol data pages and patch symbol tree offsets // sub range symbol data pages and patch symbol tree offsets
String8List mod_symbols = str8_list_substr(temp.arena, mod_pages, r1u64(sizeof(CV_Signature), sizeof(CV_Signature) + mod->sym_data_size)); Rng1U64 sym_data_range = r1u64(sizeof(CV_Signature), mod->sym_data_size);
cv_patch_symbol_tree_offsets_new(mod_symbols, sizeof(CV_Signature), PDB_SYMBOL_ALIGN); String8List mod_symbols = str8_list_substr(temp.arena, mod_data, sym_data_range);
Assert(mod_symbols.total_size == dim_1u64(sym_data_range));
cv_patch_symbol_tree_offsets(mod_symbols, sizeof(CV_Signature), PDB_SYMBOL_ALIGN);
}
temp_end(temp); temp_end(temp);
} }
barrier_wait(tp->barrier); barrier_wait(tp->barrier);
{
// count strings in string tables
{
if (task_id == 0) {
task->string_counts = push_array(scratch.arena, U64, tp->worker_count);
}
barrier_wait(tp->barrier);
for EachIndex(i, obj_indices.count) { for EachIndex(i, obj_indices.count) {
U64 obj_idx = obj_indices.v[i]; U64 obj_idx = obj_indices.v[i];
CV_DebugS debug_s = task->cv->debug_s_arr[obj_idx]; CV_DebugS debug_s = task->cv->debug_s_arr[obj_idx];
String8 string_table = cv_string_table_from_debug_s(debug_s); String8 string_table = cv_string_table_from_debug_s(debug_s);
String8List file_chksms_raw = cv_sub_section_from_debug_s(debug_s, CV_C13SubSectionKind_FileChksms); U64 string_count = 0;
CV_ChecksumList file_chksms = cv_c13_parse_checksum_data_list(scratch.arena, file_chksms_raw); for (U64 cursor = 0; cursor < string_table.size; cursor += 1) {
String8List src_file_names = cv_c13_collect_source_file_names(arena, file_chksms, string_table); if (string_table.str[cursor] == '\0') {
task->string_counts[task_id] += 1;
// collect source files module refs }
str8_list_concat_in_place(&task->mod_arr[obj_idx]->source_file_list, &src_file_names); }
// patch path offsets in file checksum headers (in obj the offsets point to a string table in .debug$S,
// and because linker merges string tables the old offsets need to be fixed up)
cv_c13_patch_string_offsets_in_checksum_list(file_chksms, string_table, task->pdb->info->strtab.size, task->string_ht);
} }
barrier_wait(tp->barrier); barrier_wait(tp->barrier);
}
if (task_id == 0) {
task->string_arenas = alloc_arena_array(task->pdb->dbi->arena, tp->worker_count, task->string_counts, String8Node);
}
barrier_wait(tp->barrier);
for EachIndex(i, obj_indices.count) {
Temp temp = temp_begin(scratch.arena);
U64 obj_idx = obj_indices.v[i];
PDB_DbiModule *mod = task->mod_arr[obj_idx];
String8List mod_data = msf_data_from_sn(temp.arena, task->pdb->msf, mod->sn);
Rng1U64 c13_data_range = r1u64(mod->sym_data_size + mod->c11_data_size, mod->sym_data_size + mod->c11_data_size + mod->c13_data_size);
String8List c13_data = str8_list_substr(temp.arena, mod_data, c13_data_range);
CV_DebugS debug_s = task->cv->debug_s_arr[obj_idx];
String8 string_table = cv_string_table_from_debug_s(debug_s);
// checksum is always at the head of C13 data
String8List file_chksms_raw = {0};
{
String8Node buf = *c13_data.first;
U64 buf_pos = 0;
CV_C13SubSectionHeader header = {0};
str8_buffer_read(&buf, &buf_pos, sizeof(header), &header);
if (header.kind == CV_C13SubSectionKind_FileChksms) {
Rng1U64 file_chksms_range = r1u64(sizeof(CV_C13SubSectionHeader), sizeof(CV_C13SubSectionHeader) + header.size);
file_chksms_raw = str8_list_substr(temp.arena, c13_data, file_chksms_range);
}
}
// fixup file name offsets in checksum headers
if (file_chksms_raw.total_size) {
String8Node buf = *file_chksms_raw.first;
U64 buf_pos = 0;
U64 cursor = 0;
for (;;) {
CV_C13Checksum header = {0};
if (str8_buffer_peek(&buf, &buf_pos, sizeof(header), &header) != sizeof(header)) { break; }
String8 name = str8_cstring_capped(string_table.str + header.name_off, string_table.str + string_table.size);
CV_StringBucket *bucket = cv_string_hash_table_lookup(task->string_ht, name);
U64 name_off = task->pdb->info->strtab.size + bucket->u.offset;
// update name offset
{
String8Node buf_copy = buf;
U64 buf_pos_copy = buf_pos;
str8_buffer_skip(&buf_copy, &buf_pos_copy, OffsetOf(CV_C13Checksum, name_off));
str8_buffer_write_u32(&buf_copy, &buf_pos_copy, safe_cast_u32(name_off));
}
str8_buffer_skip(&buf, &buf_pos, AlignPow2(sizeof(header) + header.len, CV_FileCheckSumsAlign));
}
}
// collect mod source files
String8List source_file_list = str8_split_by_string_chars(task->string_arenas[task_id], string_table, str8_lit("\0"), 0);
str8_list_concat_in_place(&mod->source_file_list, &source_file_list);
temp_end(temp);
}
barrier_wait(tp->barrier);
}
scratch_end(scratch); scratch_end(scratch);
} }
@@ -2275,7 +2349,6 @@ lnk_build_pdb(TP_Context *tp, TP_Arena *tp_arena, String8 image_data, LNK_Config
ProfBegin("Merge String Tables"); ProfBegin("Merge String Tables");
task.string_ht = cv_dedup_string_tables(tp_arena, tp, cv->obj_count, cv->debug_s_arr); task.string_ht = cv_dedup_string_tables(tp_arena, tp, cv->obj_count, cv->debug_s_arr);
cv_string_hash_table_assign_buffer_offsets(tp, task.string_ht); cv_string_hash_table_assign_buffer_offsets(tp, task.string_ht);
pdb_strtab_add_cv_string_hash_table(&task.pdb->info->strtab, task.string_ht);
ProfEnd(); ProfEnd();
ProfScope ("Alloc Modules") for EachIndex(obj_idx, cv->obj_count) { task.mod_arr[obj_idx] = dbi_push_module(task.pdb->dbi, cv->obj_arr[obj_idx]->path, lnk_obj_get_lib_path(cv->obj_arr[obj_idx])); } ProfScope ("Alloc Modules") for EachIndex(obj_idx, cv->obj_count) { task.mod_arr[obj_idx] = dbi_push_module(task.pdb->dbi, cv->obj_arr[obj_idx]->path, lnk_obj_get_lib_path(cv->obj_arr[obj_idx])); }
@@ -2291,6 +2364,10 @@ lnk_build_pdb(TP_Context *tp, TP_Arena *tp_arena, String8 image_data, LNK_Config
} }
ProfScope("Write Modules") tp_for_parallel(tp, 0, tp->worker_count, lnk_write_pdb_modules, &task); ProfScope("Write Modules") tp_for_parallel(tp, 0, tp->worker_count, lnk_write_pdb_modules, &task);
ProfBegin("Add string tables");
pdb_strtab_add_cv_string_hash_table(&task.pdb->info->strtab, task.string_ht);
ProfEnd();
ProfBegin("Build Section Contrib Map"); ProfBegin("Build Section Contrib Map");
{ {
ProfBegin("Build DBI Section Headers"); ProfBegin("Build DBI Section Headers");
+5 -7
View File
@@ -155,25 +155,23 @@ typedef struct
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_indices; // [worker_count] U64 *proc_ref_indices; // [worker_count]
String8 proc_refs; String8 proc_refs;
U64 proc_ref_count; U64 proc_ref_count;
CV_SymbolNode *proc_ref_nodes; // [proc_ref_count] CV_SymbolNode *proc_ref_nodes; // [proc_ref_count]
Arena *proc_ref_arena; Arena **proc_ref_arenas;
U64 *public_symbol_sizes; // [worker_count] U64 *public_symbol_sizes; // [worker_count]
U64 *public_symbol_offs; // [worker_count] Arena **public_symbol_arenas;
U8 *public_symbol_buffer; Arena **public_symbol_node_arenas;
U64 *public_symbol_node_counts; // [worker_count] U64 *public_symbol_node_counts; // [worker_count]
U64 *public_symbol_node_offsets; // [worker_count]
CV_SymbolNode *public_symbol_nodes; // [public_symbol_total_count]
CV_SymbolList *public_symbols; // [worker_count] CV_SymbolList *public_symbols; // [worker_count]
U32 **public_symbol_hashes; // [worker_count][public_symbol.count] U32 **public_symbol_hashes; // [worker_count][public_symbol.count]
// process C13 data // process C13 data
String8List *source_file_names_list_arr;
CV_StringHashTable string_ht; CV_StringHashTable string_ht;
U64 *string_counts;
Arena **string_arenas;
// push DBI SC Map // push DBI SC Map
PE_BinInfo pe; PE_BinInfo pe;
+9 -7
View File
@@ -302,15 +302,17 @@ THREAD_POOL_TASK_FUNC(lnk_obj_initer)
String8 debug_s_data = str8_substr(input->data, rng_1u64(sect_header->foff, sect_header->foff+sect_header->fsize)); String8 debug_s_data = str8_substr(input->data, rng_1u64(sect_header->foff, sect_header->foff+sect_header->fsize));
CV_DebugS debug_s = cv_debug_s_from_data(temp.arena, debug_s_data); CV_DebugS debug_s = cv_debug_s_from_data(temp.arena, debug_s_data);
for EachNode(symbols_n, String8Node, debug_s.data_list[CV_C13SubSectionIdxKind_Symbols].first) { for EachNode(symbols_n, String8Node, debug_s.data_list[CV_C13SubSectionIdxKind_Symbols].first) {
CV_SymbolList symbol_list = {0}; for (U64 cursor = 0, count = 0; cursor < symbols_n->string.size && count < 2; count += 1) {
cv_parse_symbol_sub_section_capped(scratch.arena, &symbol_list, 0, symbols_n->string, CV_SymbolAlign, 2); CV_SymbolHeader symbol_header;
if (symbol_list.first->data.kind == CV_SymKind_COMPILE3) { TryReadBreak(str8_deserial_read_struct(symbols_n->string, cursor, &symbol_header), cursor);
comp_symbol = symbol_list.first->data; if (symbol_header.kind == CV_SymKind_COMPILE3) {
goto found_comp_symbol; String8 raw_symbol = str8_substr(symbols_n->string, r1u64(cursor, cursor + symbol_header.size + sizeof(CV_SymSize)));
} else if (symbol_list.last->data.kind == CV_SymKind_COMPILE3) { comp_symbol = cv_symbol_from_ptr(raw_symbol.str);
comp_symbol = symbol_list.last->data;
goto found_comp_symbol; goto found_comp_symbol;
} }
cursor += symbol_header.size + sizeof(CV_SymSize);
cursor = AlignPow2(cursor, CV_SymbolAlign);
}
} }
temp_end(temp); temp_end(temp);
} }
+24 -10
View File
@@ -830,7 +830,7 @@ msf_stream_resize_ex(MSF_Context *msf, MSF_Stream *stream, MSF_UInt size)
} }
// update stream // update stream
stream->size = Min(stream->size, stream->page_list.count * msf->page_size); stream->size = size;
stream->pos = Min(stream->pos, stream->size); stream->pos = Min(stream->pos, stream->size);
stream->pos_page = 0; stream->pos_page = 0;
@@ -1212,27 +1212,41 @@ msf_stream_write_string_parallel(TP_Context *tp, MSF_Context *msf, MSF_StreamNum
} }
internal String8List internal String8List
msf_raw_pages_from_sn(Arena *arena, MSF_Context *msf, MSF_StreamNumber sn) msf_data_from_sn(Arena *arena, MSF_Context *msf, MSF_StreamNumber sn)
{ {
String8List result = {0}; String8List result = {0};
MSF_Stream *stream = msf_find_stream(msf, sn); MSF_Stream *stream = msf_find_stream(msf, sn);
String8 acc = {0}; String8 acc = {0};
for EachNode(n, MSF_PageNode, stream->page_list.first) {
String8 p = msf_data_from_pn(msf->page_data_list, msf->page_size, n->pn); MSF_PageNode *n;
if (acc.str + acc.size == p.str) { for (n = stream->page_list.first; n != stream->page_list.last; n = n->next) {
acc.size += p.size; String8 page = msf_data_from_pn(msf->page_data_list, msf->page_size, n->pn);
} else {
if (acc.str + acc.size != page.str) {
if (acc.size > 0) {
str8_list_push(arena, &result, acc); str8_list_push(arena, &result, acc);
acc = p; }
acc = page;
} else {
acc.size += page.size;
} }
} }
if (result.node_count && result.last->string.str + result.last->string.size == acc.str) { if (n) {
result.last->string.size += acc.size; String8 page = msf_data_from_pn(msf->page_data_list, msf->page_size, n->pn);
if (acc.str + acc.size != page.str) {
acc = page;
} else { } else {
acc.size += page.size;
}
acc.size = Min(stream->size - result.total_size, acc.size);
if (acc.size > 0) {
str8_list_push(arena, &result, acc); str8_list_push(arena, &result, acc);
} }
}
return result; return result;
} }
+1 -1
View File
@@ -188,7 +188,7 @@ internal B32 msf_stream_write_parallel(TP_Context *tp, MSF_Context *msf, MSF_Str
#define msf_stream_write_array(m, s, v, c) msf_stream_write(m, s, (void*)(v), sizeof(*(v)) * (c)) #define msf_stream_write_array(m, s, v, c) msf_stream_write(m, s, (void*)(v), sizeof(*(v)) * (c))
#define msf_stream_write_struct(m, s, v ) msf_stream_write_array(m, s, v, 1) #define msf_stream_write_struct(m, s, v ) msf_stream_write_array(m, s, v, 1)
internal String8List msf_raw_pages_from_sn(Arena *arena, MSF_Context *msf, MSF_StreamNumber sn); internal String8List msf_data_from_sn(Arena *arena, MSF_Context *msf, MSF_StreamNumber sn);
internal MSF_UInt msf_count_pages(MSF_UInt page_size, U64 data_size); internal MSF_UInt msf_count_pages(MSF_UInt page_size, U64 data_size);
internal MSF_PageNumber msf_get_page_count_cap(MSF_PageDataList page_data_list, MSF_UInt page_size); internal MSF_PageNumber msf_get_page_count_cap(MSF_PageDataList page_data_list, MSF_UInt page_size);