diff --git a/src/codeview/codeview_parse.c b/src/codeview/codeview_parse.c index e7f3da9c..bab4371f 100644 --- a/src/codeview/codeview_parse.c +++ b/src/codeview/codeview_parse.c @@ -1460,14 +1460,18 @@ cv_c13_parsed_from_data(Arena *arena, String8 c13_data, String8 strtbl, COFF_Sec U32 line_count_unclamped = file->num_lines; U32 block_size = file->block_size; - // file_name from file_off + // file_name / checksum from file_off String8 file_name = {0}; + CV_C13ChecksumKind checksum_kind = CV_C13ChecksumKind_Null; + String8 checksum_value = {0}; if(file_off + sizeof(CV_C13Checksum) <= file_chksms->size) { CV_C13Checksum *checksum = (CV_C13Checksum*)(c13_data.str + file_chksms->off + file_off); U32 name_off = checksum->name_off; - file_name = str8_cstring_capped((char*)(strtbl.str + name_off), - (char*)(strtbl.str + strtbl.size)); + file_name = str8_cstring_capped((char*)(strtbl.str + name_off), (char*)(strtbl.str + strtbl.size)); + checksum_kind = checksum->kind; + checksum_value = str8_skip(c13_data, file_chksms->off + file_off + sizeof(*checksum)); + checksum_value.size = Min(checksum->len, checksum_value.size); } // array layouts @@ -1503,13 +1507,15 @@ cv_c13_parsed_from_data(Arena *arena, String8 c13_data, String8 strtbl, COFF_Sec // emit parsed lines CV_C13LinesParsedNode *lines_parsed_node = push_array(arena, CV_C13LinesParsedNode, 1); CV_C13LinesParsed *lines_parsed = &lines_parsed_node->v; - lines_parsed->sec_idx = sec_idx; - lines_parsed->file_off = file_off; + lines_parsed->sec_idx = sec_idx; + lines_parsed->file_off = file_off; lines_parsed->secrel_base_off = secrel_off; - lines_parsed->file_name = file_name; - lines_parsed->voffs = voffs; - lines_parsed->line_nums = line_nums; - lines_parsed->line_count = line_count; + lines_parsed->file_name = file_name; + lines_parsed->checksum_kind = checksum_kind; + lines_parsed->checksum = checksum_value; + lines_parsed->voffs = voffs; + lines_parsed->line_nums = line_nums; + lines_parsed->line_count = line_count; SLLQueuePush(node->lines_first, node->lines_last, lines_parsed_node); // rjf: advance @@ -1539,12 +1545,16 @@ cv_c13_parsed_from_data(Arena *arena, String8 c13_data, String8 strtbl, COFF_Sec // rjf: file_off -> file_name String8 file_name = {0}; + CV_C13ChecksumKind checksum_kind = CV_C13ChecksumKind_Null; + String8 checksum_value = {0}; if(hdr->file_off + sizeof(CV_C13Checksum) <= file_chksms->size) { CV_C13Checksum *checksum = (CV_C13Checksum*)(c13_data.str + file_chksms->off + hdr->file_off); U32 name_off = checksum->name_off; - file_name = str8_cstring_capped((char*)(strtbl.str + name_off), - (char*)(strtbl.str + strtbl.size)); + file_name = str8_cstring_capped((char*)(strtbl.str + name_off), (char*)(strtbl.str + strtbl.size)); + checksum_kind = checksum->kind; + checksum_value = str8_skip(c13_data, file_chksms->off + hdr->file_off + sizeof(*checksum)); + checksum_value.size = Min(checksum->len, checksum_value.size); } // rjf: parse extra files @@ -1564,8 +1574,10 @@ cv_c13_parsed_from_data(Arena *arena, String8 c13_data, String8 strtbl, COFF_Sec CV_C13InlineeLinesParsedNode *n = push_array(arena, CV_C13InlineeLinesParsedNode, 1); SLLQueuePush(node->inlinee_lines_first, node->inlinee_lines_last, n); n->v.inlinee = hdr->inlinee; - n->v.file_name = file_name; n->v.file_off = hdr->file_off; + n->v.file_name = file_name; + n->v.checksum_kind = checksum_kind; + n->v.checksum = checksum_value; n->v.first_source_ln = hdr->first_source_ln; n->v.extra_file_count = extra_file_count; n->v.extra_files = extra_files; diff --git a/src/codeview/codeview_parse.h b/src/codeview/codeview_parse.h index d77e2913..111d1288 100644 --- a/src/codeview/codeview_parse.h +++ b/src/codeview/codeview_parse.h @@ -150,6 +150,8 @@ struct CV_C13LinesParsed // parsed info String8 file_name; + CV_C13ChecksumKind checksum_kind; + String8 checksum; U64 *voffs; // [line_count + 1] U32 *line_nums; // [line_count] U16 *col_nums; // [2*line_count] @@ -166,12 +168,14 @@ struct CV_C13LinesParsedNode typedef struct CV_C13InlineeLinesParsed CV_C13InlineeLinesParsed; struct CV_C13InlineeLinesParsed { - CV_ItemId inlinee; - U32 file_off; - String8 file_name; - U32 first_source_ln; - U32 extra_file_count; - U32 *extra_files; + CV_ItemId inlinee; + U32 file_off; + String8 file_name; + CV_C13ChecksumKind checksum_kind; + String8 checksum; + U32 first_source_ln; + U32 extra_file_count; + U32 *extra_files; }; typedef struct CV_C13InlineeLinesParsedNode CV_C13InlineeLinesParsedNode; diff --git a/src/lib_rdi/rdi.h b/src/lib_rdi/rdi.h index 20394e53..ef581cb2 100644 --- a/src/lib_rdi/rdi.h +++ b/src/lib_rdi/rdi.h @@ -305,6 +305,16 @@ RDI_BinarySectionFlag_Write = 1<<1, RDI_BinarySectionFlag_Execute = 1<<2, } RDI_BinarySectionFlagsEnum; +typedef RDI_U16 RDI_ChecksumKind; +typedef enum RDI_ChecksumKindEnum +{ +RDI_ChecksumKind_Null = 0, +RDI_ChecksumKind_MD5 = 1, +RDI_ChecksumKind_SHA1 = 2, +RDI_ChecksumKind_SHA256 = 3, +RDI_ChecksumKind_Timestamp = 4, +} RDI_ChecksumKindEnum; + typedef RDI_U32 RDI_Language; typedef enum RDI_LanguageEnum { @@ -790,6 +800,13 @@ X(RDI_U64, voff_opl)\ X(RDI_U64, foff_first)\ X(RDI_U64, foff_opl)\ +#define RDI_ChecksumKind_XList \ +X(Null)\ +X(MD5)\ +X(SHA1)\ +X(SHA256)\ +X(Timestamp)\ + #define RDI_FilePathNode_XList \ X(RDI_U32, name_string_idx)\ X(RDI_U32, parent_path_node)\ diff --git a/src/lib_rdi_make/rdi_make.h b/src/lib_rdi_make/rdi_make.h index 5e872a64..934a3a76 100644 --- a/src/lib_rdi_make/rdi_make.h +++ b/src/lib_rdi_make/rdi_make.h @@ -540,6 +540,8 @@ struct RDIM_SrcFile RDIM_SrcFileLineMapFragment *first_line_map_fragment; RDIM_SrcFileLineMapFragment *last_line_map_fragment; RDI_U64 total_line_count; + RDI_ChecksumKind checksum_kind; + RDIM_String8 checksum; }; typedef struct RDIM_SrcFileChunkNode RDIM_SrcFileChunkNode; diff --git a/src/rdi/rdi.mdesk b/src/rdi/rdi.mdesk index 8abb24e8..7f570eee 100644 --- a/src/rdi/rdi.mdesk +++ b/src/rdi/rdi.mdesk @@ -534,6 +534,29 @@ RDI_BinarySectionMemberTable: @expand(RDI_BinarySectionMemberTable a) `$(a.type) $(a.name)` } +//////////////////////////////// +//~ rjf: Checksum Type Tables + +@table(name value) +RDI_ChecksumKindTable: +{ + {Null 0} + {MD5 1} + {SHA1 2} + {SHA256 3} + {Timestamp 4} +} + +@enum(RDI_U16) RDI_ChecksumKind: +{ + @expand(RDI_ChecksumKindTable a) `$(a.name .. =>10) = $(a.value)` +} + +@xlist RDI_ChecksumKind_XList: +{ + @expand(RDI_ChecksumKindTable a) `$(a.name)`; +} + //////////////////////////////// //~ rjf: File Path Tree Info Type Tables diff --git a/src/rdi_from_pdb/rdi_from_pdb.c b/src/rdi_from_pdb/rdi_from_pdb.c index 37b84abf..ca15f48a 100644 --- a/src/rdi_from_pdb/rdi_from_pdb.c +++ b/src/rdi_from_pdb/rdi_from_pdb.c @@ -264,6 +264,20 @@ p2r_rdi_type_kind_from_cv_basic_type(CV_BasicType basic_type) return result; } +internal RDI_ChecksumKind +p2r_rdi_from_cv_c13_checksum_kind(CV_C13ChecksumKind k) +{ + RDI_ChecksumKind result = RDI_ChecksumKind_Null; + switch((CV_C13ChecksumKindEnum)k) + { + case CV_C13ChecksumKind_Null: {result = RDI_ChecksumKind_Null;}break; + case CV_C13ChecksumKind_MD5: {result = RDI_ChecksumKind_MD5;}break; + case CV_C13ChecksumKind_SHA1: {result = RDI_ChecksumKind_SHA1;}break; + case CV_C13ChecksumKind_SHA256:{result = RDI_ChecksumKind_SHA256;}break; + } + return result; +} + //////////////////////////////// //~ rjf: Location Info Building Helpers @@ -774,7 +788,7 @@ p2r_convert(Arena *arena, P2R_ConvertParams *params) //- rjf: prep outputs ProfScope("prep outputs") if(lane_idx() == 0) { - p2r_shared->unit_file_paths = push_array(arena, String8Array, comp_units->count); + p2r_shared->unit_file_stubs = push_array(arena, P2R_SrcFileStubArray, comp_units->count); p2r_shared->unit_file_paths_hashes = push_array(arena, U64Array, comp_units->count); p2r_shared->sym_lane_take_counter = 0; } @@ -819,8 +833,10 @@ p2r_convert(Arena *arena, P2R_ConvertParams *params) } String8 obj_folder_path = backslashed_from_str8(scratch.arena, str8_chop_last_slash(obj_name)); - //- rjf: find all inline site symbols & gather filenames - String8List src_file_paths = {0}; + //- rjf: find all inline site symbols & gather file stubs + P2R_SrcFileStubNode *first_src_file_stub = 0; + P2R_SrcFileStubNode *last_src_file_stub = 0; + U64 src_file_stub_count = 0; U64 base_voff = 0; for(CV_RecRange *rec_range = rec_ranges_first; rec_range < rec_ranges_opl; @@ -917,11 +933,16 @@ p2r_convert(Arena *arena, P2R_ConvertParams *params) if(last_file_off != max_U32 && last_file_off != curr_file_off) { String8 seq_file_name = {0}; + CV_C13ChecksumKind checksum_kind = CV_C13ChecksumKind_Null; + String8 checksum_value = {0}; if(last_file_off + sizeof(CV_C13Checksum) <= file_chksms->size) { CV_C13Checksum *checksum = (CV_C13Checksum *)(c13->data.str + file_chksms->off + last_file_off); - U32 name_off = checksum->name_off; + U32 name_off = checksum->name_off; seq_file_name = pdb_strtbl_string_from_off(strtbl, name_off); + checksum_kind = checksum->kind; + checksum_value = str8_skip(c13->data, file_chksms->off + last_file_off + sizeof(*checksum)); + checksum_value.size = Min(checksum->len, checksum_value.size); } // rjf: file name -> normalized file path @@ -958,7 +979,12 @@ p2r_convert(Arena *arena, P2R_ConvertParams *params) hit_path_node = push_array(scratch.arena, String8Node, 1); SLLStackPush(hit_path_slots[hit_path_slot], hit_path_node); hit_path_node->string = file_path_normalized; - str8_list_push(arena, &src_file_paths, push_str8_copy(arena, file_path_normalized)); + P2R_SrcFileStubNode *stub_n = push_array(arena, P2R_SrcFileStubNode, 1); + SLLQueuePush(first_src_file_stub, last_src_file_stub, stub_n); + src_file_stub_count += 1; + stub_n->v.file_path = str8_copy(arena, file_path_normalized); + stub_n->v.checksum_kind = checksum_kind; + stub_n->v.checksum = str8_copy(arena, checksum_value); } line_count = 0; } @@ -1026,22 +1052,36 @@ p2r_convert(Arena *arena, P2R_ConvertParams *params) hit_path_node = push_array(scratch.arena, String8Node, 1); SLLStackPush(hit_path_slots[hit_path_slot], hit_path_node); hit_path_node->string = file_path_sanitized; - str8_list_push(scratch.arena, &src_file_paths, push_str8_copy(arena, file_path_sanitized)); + P2R_SrcFileStubNode *stub_n = push_array(arena, P2R_SrcFileStubNode, 1); + SLLQueuePush(first_src_file_stub, last_src_file_stub, stub_n); + src_file_stub_count += 1; + stub_n->v.file_path = str8_copy(arena, file_path_sanitized); + stub_n->v.checksum_kind = lines_n->v.checksum_kind; + stub_n->v.checksum = str8_copy(arena, lines_n->v.checksum); } } } } //- rjf: merge into array for this unit - p2r_shared->unit_file_paths[unit_idx] = str8_array_from_list(arena, &src_file_paths); + p2r_shared->unit_file_stubs[unit_idx].count = src_file_stub_count; + p2r_shared->unit_file_stubs[unit_idx].v = push_array_no_zero(arena, P2R_SrcFileStub, p2r_shared->unit_file_stubs[unit_idx].count); + { + U64 idx = 0; + for EachNode(n, P2R_SrcFileStubNode, first_src_file_stub) + { + p2r_shared->unit_file_stubs[unit_idx].v[idx] = n->v; + idx += 1; + } + } //- rjf: hash this unit's file paths U64Array hashes = {0}; - hashes.count = p2r_shared->unit_file_paths[unit_idx].count; + hashes.count = p2r_shared->unit_file_stubs[unit_idx].count; hashes.v = push_array(arena, U64, hashes.count); - for EachIndex(idx, p2r_shared->unit_file_paths[unit_idx].count) + for EachIndex(idx, p2r_shared->unit_file_stubs[unit_idx].count) { - hashes.v[idx] = rdi_hash(p2r_shared->unit_file_paths[unit_idx].v[idx].str, p2r_shared->unit_file_paths[unit_idx].v[idx].size); + hashes.v[idx] = rdi_hash(p2r_shared->unit_file_stubs[unit_idx].v[idx].file_path.str, p2r_shared->unit_file_stubs[unit_idx].v[idx].file_path.size); } p2r_shared->unit_file_paths_hashes[unit_idx] = hashes; } @@ -1049,7 +1089,7 @@ p2r_convert(Arena *arena, P2R_ConvertParams *params) } } lane_sync(); - String8Array *unit_file_paths = p2r_shared->unit_file_paths; + P2R_SrcFileStubArray *unit_file_stubs = p2r_shared->unit_file_stubs; U64Array *unit_file_paths_hashes = p2r_shared->unit_file_paths_hashes; ////////////////////////////////////////////////////////////// @@ -1065,7 +1105,7 @@ p2r_convert(Arena *arena, P2R_ConvertParams *params) p2r_shared->total_path_count = 0; for EachIndex(idx, comp_units->count) { - p2r_shared->total_path_count += unit_file_paths[idx].count; + p2r_shared->total_path_count += unit_file_stubs[idx].count; } p2r_shared->src_file_map.slots_count = p2r_shared->total_path_count + p2r_shared->total_path_count/2 + 1; p2r_shared->src_file_map.slots = push_array(arena, P2R_SrcFileNode *, p2r_shared->src_file_map.slots_count); @@ -1077,12 +1117,14 @@ p2r_convert(Arena *arena, P2R_ConvertParams *params) { for EachIndex(idx, comp_units->count) { - String8Array paths = unit_file_paths[idx]; + P2R_SrcFileStubArray stubs = unit_file_stubs[idx]; U64Array hashes = unit_file_paths_hashes[idx]; - for EachIndex(path_idx, paths.count) + for EachIndex(stub_idx, stubs.count) { - String8 file_path_sanitized = paths.v[path_idx]; - U64 file_path_sanitized_hash = hashes.v[path_idx]; + String8 file_path_sanitized = stubs.v[stub_idx].file_path; + CV_C13ChecksumKind c13_checksum_kind = stubs.v[stub_idx].checksum_kind; + String8 checksum = stubs.v[stub_idx].checksum; + U64 file_path_sanitized_hash = hashes.v[stub_idx]; U64 src_file_slot = file_path_sanitized_hash%p2r_shared->src_file_map.slots_count; P2R_SrcFileNode *src_file_node = 0; for(P2R_SrcFileNode *n = p2r_shared->src_file_map.slots[src_file_slot]; n != 0; n = n->next) @@ -1098,7 +1140,9 @@ p2r_convert(Arena *arena, P2R_ConvertParams *params) src_file_node = push_array(arena, P2R_SrcFileNode, 1); SLLStackPush(p2r_shared->src_file_map.slots[src_file_slot], src_file_node); src_file_node->src_file = rdim_src_file_chunk_list_push(arena, &p2r_shared->all_src_files__sequenceless, p2r_shared->total_path_count); - src_file_node->src_file->path = push_str8_copy(arena, file_path_sanitized); + src_file_node->src_file->path = str8_copy(arena, file_path_sanitized); + src_file_node->src_file->checksum_kind = p2r_rdi_from_cv_c13_checksum_kind(c13_checksum_kind); + src_file_node->src_file->checksum = str8_copy(arena, checksum); } } } @@ -1369,7 +1413,7 @@ p2r_convert(Arena *arena, P2R_ConvertParams *params) if(last_file_off + sizeof(CV_C13Checksum) <= file_chksms->size) { CV_C13Checksum *checksum = (CV_C13Checksum*)(src_unit_c13->data.str + file_chksms->off + last_file_off); - U32 name_off = checksum->name_off; + U32 name_off = checksum->name_off; seq_file_name = pdb_strtbl_string_from_off(strtbl, name_off); } diff --git a/src/rdi_from_pdb/rdi_from_pdb.h b/src/rdi_from_pdb/rdi_from_pdb.h index bb16e8ee..64939815 100644 --- a/src/rdi_from_pdb/rdi_from_pdb.h +++ b/src/rdi_from_pdb/rdi_from_pdb.h @@ -42,6 +42,28 @@ struct P2R_LinkNameMap //- rjf: normalized file path -> source file map +typedef struct P2R_SrcFileStub P2R_SrcFileStub; +struct P2R_SrcFileStub +{ + String8 file_path; + CV_C13ChecksumKind checksum_kind; + String8 checksum; +}; + +typedef struct P2R_SrcFileStubArray P2R_SrcFileStubArray; +struct P2R_SrcFileStubArray +{ + P2R_SrcFileStub *v; + U64 count; +}; + +typedef struct P2R_SrcFileStubNode P2R_SrcFileStubNode; +struct P2R_SrcFileStubNode +{ + P2R_SrcFileStubNode *next; + P2R_SrcFileStub v; +}; + typedef struct P2R_SrcFileNode P2R_SrcFileNode; struct P2R_SrcFileNode { @@ -109,7 +131,7 @@ struct P2R_Shared U64 sym_lane_take_counter; - String8Array *unit_file_paths; + P2R_SrcFileStubArray *unit_file_stubs; U64Array *unit_file_paths_hashes; U64 total_path_count; @@ -175,10 +197,11 @@ internal RDI_BinarySectionFlags p2r_rdi_binary_section_flags_from_coff_section_f //////////////////////////////// //~ rjf: CodeView => RDI Canonical Conversions -internal RDI_Arch p2r_rdi_arch_from_cv_arch(CV_Arch arch); -internal RDI_RegCode p2r_rdi_reg_code_from_cv_reg_code(RDI_Arch arch, CV_Reg reg_code); -internal RDI_Language p2r_rdi_language_from_cv_language(CV_Language language); -internal RDI_TypeKind p2r_rdi_type_kind_from_cv_basic_type(CV_BasicType basic_type); +internal RDI_Arch p2r_rdi_arch_from_cv_arch(CV_Arch arch); +internal RDI_RegCode p2r_rdi_reg_code_from_cv_reg_code(RDI_Arch arch, CV_Reg reg_code); +internal RDI_Language p2r_rdi_language_from_cv_language(CV_Language language); +internal RDI_TypeKind p2r_rdi_type_kind_from_cv_basic_type(CV_BasicType basic_type); +internal RDI_ChecksumKind p2r_rdi_from_cv_c13_checksum_kind(CV_C13ChecksumKind k); //////////////////////////////// //~ rjf: Location Info Building Helpers