diff --git a/src/linker/lnk_debug_info.c b/src/linker/lnk_debug_info.c index 3ebaed55..e24f314f 100644 --- a/src/linker/lnk_debug_info.c +++ b/src/linker/lnk_debug_info.c @@ -3180,10 +3180,10 @@ THREAD_POOL_TASK_FUNC(lnk_build_udt_name_hash_table_task) U64 bucket_idx = best_idx; if (new_bucket == 0) { - new_bucket = push_array(arena, LNK_UDTNameBucket, 1); - new_bucket->name = name; - new_bucket->leaf_idx = leaf_idx; + new_bucket = push_array(arena, LNK_UDTNameBucket, 1); } + new_bucket->name = name; + new_bucket->leaf_idx = leaf_idx; B32 is_inserted_or_updated = 0; do { @@ -3284,9 +3284,11 @@ lnk_push_converted_codeview_type(Arena *arena, RDIB_TypeChunkList *list, RDIB_Ty { RDIB_Type *type = rdib_type_chunk_list_push(arena, list, 8196); type->final_idx = 0; - type->itype = itype; + type->itype = itype; + Assert(itype_map[itype] == 0); itype_map[itype] = type; + return type; } @@ -3413,35 +3415,40 @@ lnk_push_basic_itypes(Arena *arena, RDIB_DataModel data_model, RDIB_Type **itype internal RDIB_TypeRef lnk_rdib_type_from_itype(LNK_ConvertTypesToRDI *task, CV_TypeIndex itype) { - if (itype < CV_MinComplexTypeIndex) { - // Check for supported CodeView pointer formats: - // - near 64 bit - // - 64 bit - // - 32 bit - AssertAlways((itype >> 8) == /* near */ 0x1 || - (itype >> 8) == /* 64 bit */ 0x6 || - (itype >> 8) == /* 32 bit */ 0x4 || - (itype >> 8) == 0); + RDIB_TypeRef result = &task->tpi_itype_map[0]; + Rng1U64 tpi_range = task->itype_ranges[CV_TypeIndexSource_TPI]; + + if (itype < tpi_range.min) { + // check for supported CodeView pointer formats: + AssertAlways(BitExtract(itype, 8, 8) == /* near */ 0x1 || + BitExtract(itype, 8, 8) == /* 32 bit */ 0x4 || + BitExtract(itype, 8, 8) == /* 64 bit */ 0x6 || + BitExtract(itype, 8, 8) == /* regular */ 0x0); } - RDIB_TypeRef ref = &task->tpi_itype_map[0]; - if (itype < task->itype_ranges[CV_TypeIndexSource_TPI].max) { + if (itype < tpi_range.max) { CV_TypeIndex final_itype = itype; - if (itype > task->itype_ranges[CV_TypeIndexSource_TPI].min) { - CV_Leaf leaf = cv_debug_t_get_leaf(task->types[CV_TypeIndexSource_TPI], itype - task->itype_ranges[CV_TypeIndexSource_TPI].min); + + // try to resovle forward reference (defn might be missing) + if (itype >= tpi_range.min) { + U64 leaf_idx = itype - tpi_range.min; + CV_Leaf leaf = cv_debug_t_get_leaf(task->types[CV_TypeIndexSource_TPI], leaf_idx); if (cv_is_udt(leaf.kind)) { CV_UDTInfo udt_info = cv_get_udt_info(leaf.kind, leaf.data); if (udt_info.props & CV_TypeProp_FwdRef) { - String8 name = cv_name_from_udt_info(udt_info); - final_itype = lnk_udt_name_hash_table_lookup_itype(task->udt_name_buckets, task->udt_name_bucket_cap, name); + String8 name = cv_name_from_udt_info(udt_info); + CV_TypeIndex resolved_itype = lnk_udt_name_hash_table_lookup_itype(task->udt_name_buckets, task->udt_name_bucket_cap, name); + if (resolved_itype != 0) { + final_itype = resolved_itype; + } } } } - ref = &task->tpi_itype_map[final_itype]; + result = &task->tpi_itype_map[final_itype]; } - return ref; + return result; } internal RDI_MemberKind diff --git a/src/linker/rdi/rdi_builder.c b/src/linker/rdi/rdi_builder.c index 79333571..1c338fa7 100644 --- a/src/linker/rdi/rdi_builder.c +++ b/src/linker/rdi/rdi_builder.c @@ -4806,11 +4806,6 @@ rdib_data_sections_from_line_tables(TP_Context *tp, U64 line_table_cursor = 0; U64 line_table_voff_cursor = 0; U64 line_table_line_cursor = 0; - //U64 line_table_col_cursor = 0; - - // fill out null line table - MemoryZeroStruct(&line_tables_rdi[line_table_cursor]); - ++line_table_cursor; for (U64 chunk_idx = 0; chunk_idx < chunk_count; ++chunk_idx) { RDIB_LineTableChunk *chunk = chunks[chunk_idx]; @@ -4824,17 +4819,15 @@ rdib_data_sections_from_line_tables(TP_Context *tp, dst->voffs_base_idx = line_table_voff_cursor; dst->lines_base_idx = line_table_line_cursor; - dst->cols_base_idx = 0; //line_table_cols_cursor; + dst->cols_base_idx = 0; dst->lines_count = task.out_line_table_counts[src_idx] - 1; - dst->cols_count = 0; //src->col_count; + dst->cols_count = 0; str8_list_push(arena->v[0], &line_table_voffs_sect.data, str8_array(task.out_line_table_voffs[src_idx], task.out_line_table_counts[src_idx])); str8_list_push(arena->v[0], &line_table_lines_sect.data, str8_array(task.out_line_table_lines[src_idx], task.out_line_table_counts[src_idx])); - //str8_list_push(arena->v[0], &line_table_cols_sect.data, str8_array(task.out_line_table_cols[src_idx], task.out_line_table_col_counts[src_idx])); line_table_voff_cursor += task.out_line_table_counts[src_idx]; line_table_line_cursor += task.out_line_table_counts[src_idx]; - //line_table_col_cursor += task.out_line_table_col_counts[src_idx]; line_table_cursor += 1; } else { @@ -4983,12 +4976,12 @@ rdib_init_input(Arena *arena) // Unit null_unit->arch = RDI_Arch_NULL; - null_unit->unit_name = str8_lit(""); - null_unit->compiler_name = str8_lit(""); - null_unit->source_file = str8_lit(""); - null_unit->object_file = str8_lit(""); - null_unit->archive_file = str8_lit(""); - null_unit->build_path = str8_lit(""); + null_unit->unit_name = str8_zero(); + null_unit->compiler_name = str8_zero(); + null_unit->source_file = str8_zero(); + null_unit->object_file = str8_zero(); + null_unit->archive_file = str8_zero(); + null_unit->build_path = str8_zero(); null_unit->virt_range_count = 1; null_unit->virt_ranges = push_array(arena, Rng1U64, 1); null_unit->virt_ranges[0] = rng_1u64(0,0); @@ -5165,7 +5158,7 @@ rdib_finish(TP_Context *tp, TP_Arena *arena, RDIB_Input *input) //U64 udt_chunk_count = struct_chunk_count + union_chunk_count + enum_chunk_count; ProfBegin("Assign Type Indices"); - U64 total_type_node_count = 0; + U64 total_type_node_count = 1; { struct TypeNode { struct TypeNode *next; @@ -5173,18 +5166,18 @@ rdib_finish(TP_Context *tp, TP_Arena *arena, RDIB_Input *input) }; struct TypeNode *stack = 0; struct TypeNode *free_nodes = 0; -#define push_node(t) do { \ -if (((RDIB_Type*)(t))->kind == RDI_TypeKindExt_VirtualTable) break; \ - struct TypeNode *n; \ - if (free_nodes == 0) { \ - n = push_array(scratch.arena, struct TypeNode, 1); \ - } else { \ - n = free_nodes; \ - SLLStackPop(free_nodes); \ - } \ - Assert(t); \ - n->type = t; \ - SLLStackPush(stack, n); \ +#define push_node(t) do { \ +if (((RDIB_Type*)(t))->kind == RDI_TypeKindExt_VirtualTable) break; \ + struct TypeNode *n; \ + if (free_nodes == 0) { \ + n = push_array(scratch.arena, struct TypeNode, 1); \ + } else { \ + n = free_nodes; \ + SLLStackPop(free_nodes); \ + } \ + Assert(t); \ + n->type = t; \ + SLLStackPush(stack, n); \ } while (0) for (U64 chunk_idx = 0; chunk_idx < all_types.count; ++chunk_idx) { @@ -5255,7 +5248,7 @@ if (((RDIB_Type*)(t))->kind == RDI_TypeKindExt_VirtualTable) break; \ for (struct TypeNode *cursor = stack; cursor != 0; cursor = cursor->next) { // was this type visisted? - if (cursor->type->final_idx == 0) { + if (cursor->type != input->null_type && cursor->type->final_idx == 0) { cursor->type->final_idx = total_type_node_count; ++total_type_node_count; }