WIP: internal and external type servers are functioning except for the

PCH indirection
This commit is contained in:
Nikita Smith
2026-04-06 12:04:31 -07:00
parent 401ba47ac2
commit c0418b736d
9 changed files with 1301 additions and 1960 deletions
+85 -37
View File
@@ -396,6 +396,12 @@ cv_make_proc_refs(Arena *arena, CV_ModIndex imod, CV_SymbolList symbol_list)
return proc_ref_list; return proc_ref_list;
} }
internal B32
cv_is_obj_info(CV_Symbol symbol)
{
return symbol.kind == CV_SymKind_OBJNAME;
}
internal CV_ObjInfo internal CV_ObjInfo
cv_obj_info_from_symbol(CV_Symbol symbol) cv_obj_info_from_symbol(CV_Symbol symbol)
{ {
@@ -406,12 +412,7 @@ cv_obj_info_from_symbol(CV_Symbol symbol)
result.sig = obj_name->sig; result.sig = obj_name->sig;
str8_deserial_read_cstr(symbol.data, sizeof(CV_SymObjName), &result.name); str8_deserial_read_cstr(symbol.data, sizeof(CV_SymObjName), &result.name);
} break; } break;
case CV_SymKind_OBJNAME_ST: { default: { InvalidPath; } break;
NotImplemented;
} break;
default: {
InvalidPath;
} break;
} }
return result; return result;
} }
@@ -1092,76 +1093,123 @@ cv_dedup_symbol_ptr_array(TP_Context *tp, CV_SymbolPtrArray *symbols)
internal CV_DebugT internal CV_DebugT
cv_debug_t_from_data(Arena *arena, String8 data, U64 align) cv_debug_t_from_data(Arena *arena, String8 data, U64 align)
{ {
ProfBegin("Upfront parse"); CV_DebugT debug_t = { .data = data };
U64 count = 0;
for (U64 cursor = 0; cursor < data.size; count += 1) { ProfBegin("Upfront parse for counts");
CV_Leaf leaf; for (U64 cursor = 0, prev_cursor = 0, ti = CV_MinComplexTypeIndex; cursor < data.size; ti += 1) {
cursor += cv_read_leaf(data, cursor, align, &leaf); CV_Leaf leaf = {0};
TryRead(cv_read_leaf(data, cursor, align, &leaf), cursor, count_stop);
debug_t.source_counts[cv_type_index_source_from_leaf_kind(leaf.kind)] += 1;
} }
count_stop:
ProfEnd(); ProfEnd();
U32 *offsets = push_array_no_zero(arena, U32, count); for EachElement(i, debug_t.source_counts) { debug_t.count += debug_t.source_counts[i]; }
ProfBegin("store leaf offsets");
debug_t.offsets = push_array_no_zero(arena, U32, debug_t.count);
for (U64 cursor = 0, idx = 0; cursor < data.size;) { for (U64 cursor = 0, idx = 0; cursor < data.size;) {
offsets[idx++] = cursor; debug_t.offsets[idx++] = cursor;
CV_Leaf leaf; CV_Leaf leaf;
cursor += cv_read_leaf(data, cursor, align, &leaf); TryRead(cv_read_leaf(data, cursor, align, &leaf), cursor, store_stop);
} }
store_stop:
return (CV_DebugT){ .count = count, .data = data, .offsets = offsets }; for EachElement(i, debug_t.ti_ranges) { debug_t.ti_ranges[i] = r1u64(CV_MinComplexTypeIndex, CV_MinComplexTypeIndex + debug_t.count); }
ProfEnd();
return debug_t;
} }
internal CV_Leaf internal CV_Leaf
cv_debug_t_get_leaf(CV_DebugT debug_t, U64 leaf_idx) cv_debug_t_get_leaf(CV_DebugT *debug_t, U64 leaf_idx)
{ {
CV_Leaf leaf = {0}; CV_Leaf leaf = {0};
if (debug_t.count > 0) { if (debug_t->count > 0) {
Assert(leaf_idx < debug_t.count); Assert(leaf_idx < debug_t->count);
cv_read_leaf(debug_t.data, debug_t.offsets[leaf_idx], 1, &leaf); cv_read_leaf(debug_t->data, debug_t->offsets[leaf_idx], 1, &leaf);
Assert(cv_header_struct_size_from_leaf_kind(leaf.kind) <= leaf.data.size); Assert(cv_header_struct_size_from_leaf_kind(leaf.kind) <= leaf.data.size);
} }
return leaf; return leaf;
} }
internal String8 internal U64
cv_debug_t_get_raw_leaf(CV_DebugT debug_t, U64 leaf_idx) cv_leaf_idx_from_ti(CV_DebugT *debug_t, CV_TypeIndexSource source, CV_TypeIndex ti)
{ {
Assert(leaf_idx < debug_t.count); Assert(contains_1u64(debug_t->ti_ranges[source], ti)); // validate TI
U8 *leaf_ptr = debug_t.data.str + debug_t.offsets[leaf_idx]; Assert(!contains_1u64(debug_t->pch_ti_range[source], ti)); // no PCH indirection
U64 leaf_idx = ti;
Assert(leaf_idx >= debug_t->ti_ranges[source].min);
leaf_idx -= debug_t->ti_ranges[source].min; // strip type index range
Assert(leaf_idx >= dim_1u64(debug_t->pch_ti_range[source]));
leaf_idx -= dim_1u64(debug_t->pch_ti_range[source]); // strip PCH indirection
leaf_idx += debug_t->source_offsets[source];
Assert(leaf_idx < debug_t->count);
return leaf_idx;
}
internal CV_TypeIndex
cv_ti_from_leaf_idx(CV_DebugT *debug_t, CV_TypeIndexSource source, U64 leaf_idx)
{
U64 pch_count = dim_1u64(debug_t->pch_ti_range[source]);
CV_TypeIndex ti = debug_t->ti_ranges[source].min + pch_count + leaf_idx;
return ti;
}
internal CV_Leaf
cv_leaf_from_ti(CV_DebugT *debug_t, CV_TypeIndexSource source, CV_TypeIndex ti)
{
U64 leaf_idx = cv_leaf_idx_from_ti(debug_t, source, ti);
return cv_debug_t_get_leaf(debug_t, leaf_idx);
}
internal String8
cv_debug_t_get_raw_leaf(CV_DebugT *debug_t, U64 leaf_idx)
{
Assert(leaf_idx < debug_t->count);
U8 *leaf_ptr = debug_t->data.str + debug_t->offsets[leaf_idx];
CV_LeafSize leaf_size = memory_read16(leaf_ptr); CV_LeafSize leaf_size = memory_read16(leaf_ptr);
return str8(leaf_ptr, leaf_size + sizeof(leaf_size)); return str8(leaf_ptr, leaf_size + sizeof(leaf_size));
} }
internal CV_LeafHeader * internal CV_LeafHeader *
cv_debug_t_get_leaf_header(CV_DebugT debug_t, U64 leaf_idx) cv_debug_t_get_leaf_header(CV_DebugT *debug_t, U64 leaf_idx)
{ {
CV_LeafHeader *header = 0; CV_LeafHeader *header = 0;
if (leaf_idx < debug_t.count) { if (leaf_idx < debug_t->count) {
header = (CV_LeafHeader *)(debug_t.data.str + debug_t.offsets[leaf_idx]); header = (CV_LeafHeader *)(debug_t->data.str + debug_t->offsets[leaf_idx]);
} }
return header; return header;
} }
internal CV_TypeIndex
cv_debug_t_get_type_index(CV_DebugT *debug_t, CV_TypeIndexSource ti_source, U64 leaf_idx)
{
CV_TypeIndex ti = debug_t->ti_ranges[ti_source].min + leaf_idx;
Assert(contains_1u64(debug_t->ti_ranges[ti_source], ti));
return ti;
}
internal U64
cv_debug_t_get_leaf_index(CV_DebugT *debug_t, CV_TypeIndexSource ti_source, CV_TypeIndex ti)
{
Assert(contains_1u64(debug_t->ti_ranges[ti_source], ti));
U64 leaf_idx = ti - debug_t->ti_ranges[ti_source].min;
return leaf_idx;
}
internal B32 internal B32
cv_debug_t_is_pch(CV_DebugT debug_t) cv_debug_t_is_pch(CV_DebugT *debug_t)
{ {
return cv_is_leaf_pch(cv_debug_t_get_leaf(debug_t, 0).kind); return cv_is_leaf_pch(cv_debug_t_get_leaf(debug_t, 0).kind);
} }
internal B32 internal B32
cv_debug_t_is_type_server(CV_DebugT debug_t) cv_debug_t_is_type_server_ref(CV_DebugT *debug_t)
{ {
return cv_is_leaf_type_server(cv_debug_t_get_leaf(debug_t, 0).kind); return cv_is_leaf_type_server(cv_debug_t_get_leaf(debug_t, 0).kind);
} }
internal U64
cv_debug_t_array_count_leaves(U64 count, CV_DebugT *debug_t)
{
U64 total = 0;
for EachIndex(i, count) { total += debug_t[i].count; }
return total;
}
// $$Symbols // $$Symbols
internal void internal void
+31 -10
View File
@@ -253,11 +253,27 @@ typedef struct CV_DebugS
String8List data_list[CV_C13SubSectionIdxKind_COUNT]; String8List data_list[CV_C13SubSectionIdxKind_COUNT];
} CV_DebugS; } CV_DebugS;
typedef struct CV_DebugH
{
U64 count;
U64 *v;
} CV_DebugH;
typedef struct CV_DebugT typedef struct CV_DebugT
{ {
U64 count; String8 data;
String8 data; U64 count;
U32 *offsets; U32 *offsets;
// type server
U64 source_counts [CV_TypeIndexSource_COUNT];
U64 source_offsets[CV_TypeIndexSource_COUNT];
U32 ti_base [CV_TypeIndexSource_COUNT];
Rng1U64 ti_ranges [CV_TypeIndexSource_COUNT];
// PCH
Rng1U64 pch_ti_range[CV_TypeIndexSource_COUNT];
U32 pch_obj_idx;
} CV_DebugT; } CV_DebugT;
//////////////////////////////// ////////////////////////////////
@@ -393,6 +409,7 @@ internal CV_SymbolList cv_make_proc_refs(Arena *arena, CV_ModIndex imod, CV_Symb
internal U64 cv_read_symbol(String8 raw_data, U64 off, U64 align, CV_Symbol *symbol_out); internal U64 cv_read_symbol(String8 raw_data, U64 off, U64 align, CV_Symbol *symbol_out);
internal CV_Symbol cv_symbol_from_string(String8 raw_data); internal CV_Symbol cv_symbol_from_string(String8 raw_data);
internal B32 cv_is_obj_info(CV_Symbol symbol);
internal CV_ObjInfo cv_obj_info_from_symbol(CV_Symbol symbol); internal CV_ObjInfo cv_obj_info_from_symbol(CV_Symbol symbol);
//////////////////////////////// ////////////////////////////////
@@ -416,13 +433,17 @@ internal String8 cv_file_chksms_from_debug_s(CV_DebugS debug_s);
//////////////////////////////// ////////////////////////////////
//~ .debug$T helpers //~ .debug$T helpers
internal CV_DebugT cv_debug_t_from_data(Arena *arena, String8 data, U64 align); internal CV_DebugT cv_debug_t_from_data (Arena *arena, String8 data, U64 align);
internal CV_Leaf cv_debug_t_get_leaf(CV_DebugT debug_t, U64 leaf_idx); internal U64 cv_leaf_idx_from_ti (CV_DebugT *debug_t, CV_TypeIndexSource source, CV_TypeIndex ti);
internal String8 cv_debug_t_get_raw_leaf(CV_DebugT debug_t, U64 leaf_idx); internal CV_TypeIndex cv_ti_from_leaf_idx (CV_DebugT *debug_t, CV_TypeIndexSource source, U64 leaf_idx);
internal CV_LeafHeader * cv_debug_t_get_leaf_header(CV_DebugT debug_t, U64 leaf_idx); internal CV_Leaf cv_debug_t_get_leaf (CV_DebugT *debug_t, U64 leaf_idx);
internal B32 cv_debug_t_is_pch(CV_DebugT debug_t); internal CV_Leaf cv_debug_t_get_leaf_from_ti (CV_DebugT *debug_t, CV_TypeIndexSource source, CV_TypeIndex ti);
internal B32 cv_debug_t_is_type_server(CV_DebugT debug_t); internal String8 cv_debug_t_get_raw_leaf (CV_DebugT *debug_t, U64 leaf_idx);
internal U64 cv_debug_t_array_count_leaves(U64 count, CV_DebugT *arr); internal CV_LeafHeader * cv_debug_t_get_leaf_header (CV_DebugT *debug_t, U64 leaf_idx);
internal CV_TypeIndex cv_debug_t_get_type_index (CV_DebugT *debug_t, CV_TypeIndexSource ti_source, U64 leaf_idx);
internal U64 cv_debug_t_get_leaf_index (CV_DebugT *debug_t, CV_TypeIndexSource ti_source, CV_TypeIndex ti);
internal B32 cv_debug_t_is_pch (CV_DebugT *debug_t);
internal B32 cv_debug_t_is_type_server_ref(CV_DebugT *debug_t);
//////////////////////////////// ////////////////////////////////
//~ Sub Section helpers //~ Sub Section helpers
+8 -10
View File
@@ -5161,14 +5161,13 @@ lnk_run(TP_Context *tp, TP_Arena *arena, LNK_Config *config)
rdi_arch_from_coff_machine(config->machine), rdi_arch_from_coff_machine(config->machine),
config->image_name, config->image_name,
image_ctx.image_data, image_ctx.image_data,
input.count, debug_info_objs_count,
input.obj_arr, debug_info_objs,
input.debug_s_arr, input.debug_s_arr,
input.total_symbol_input_count, input.symbol_input_count,
input.symbol_inputs, input.symbol_inputs,
input.parsed_symbols, input.parsed_symbols,
merged_types.count, merged_types);
merged_types.v);
lnk_write_data_list_to_file_path(config->rad_debug_name, config->temp_rad_debug_name, rdi_data); lnk_write_data_list_to_file_path(config->rad_debug_name, config->temp_rad_debug_name, rdi_data);
@@ -5198,14 +5197,13 @@ lnk_run(TP_Context *tp, TP_Arena *arena, LNK_Config *config)
image_ctx.image_data, image_ctx.image_data,
config, config,
symtab, symtab,
input.count, debug_info_objs_count,
input.obj_arr, debug_info_objs,
input.debug_s_arr, input.debug_s_arr,
input.total_symbol_input_count, input.symbol_input_count,
input.symbol_inputs, input.symbol_inputs,
input.parsed_symbols, input.parsed_symbols,
merged_types.count, merged_types);
merged_types.v);
lnk_write_data_list_to_file_path(config->pdb_name, config->temp_pdb_name, pdb_data); lnk_write_data_list_to_file_path(config->pdb_name, config->temp_pdb_name, pdb_data);
lnk_timer_end(LNK_Timer_Pdb); lnk_timer_end(LNK_Timer_Pdb);
+881 -1654
View File
File diff suppressed because it is too large Load Diff
+106 -184
View File
@@ -3,84 +3,89 @@
#pragma once #pragma once
// --- Symbol Parsing Tasks ----------------------------------------------------
typedef struct
{
LNK_Obj **obj_arr;
String8List *sect_list_arr;
CV_DebugS *debug_s_arr;
} LNK_ParseDebugSTaskData;
typedef struct
{
LNK_Obj **obj_arr;
String8Array *data_arr_arr;
} LNK_CheckDebugTSigTaskData;
typedef struct
{
LNK_Obj **obj_arr;
String8Array *data_arr_arr;
CV_DebugT *debug_t_arr;
} LNK_ParseDebugTTaskData;
// --- Code View Input --------------------------------------------------------- // --- Code View Input ---------------------------------------------------------
typedef struct LNK_PchInfo typedef struct LNK_SymbolInput
{
CV_TypeIndex ti_lo;
CV_TypeIndex ti_hi;
U64 debug_p_obj_idx;
} LNK_PchInfo;
typedef struct LNK_CodeViewSymbolsInput
{ {
U64 obj_idx; U64 obj_idx;
CV_DebugS *debug_s;
CV_SymbolList *symbol_list; CV_SymbolList *symbol_list;
String8 raw_symbols; String8 raw_symbols;
} LNK_CodeViewSymbolsInput; } LNK_SymbolInput;
typedef struct LNK_CodeViewInput typedef struct
{ {
U64 count; CV_TypeServerInfo ts_info;
U64 internal_count; U64 ts_idx;
U64 external_count; String8 ts_path;
U64 type_server_count; U64List obj_indices;
String8 *type_server_path_arr; // [type_server_count] } LNK_TypeServer;
String8 *type_server_data_arr; // [type_server_count] typedef struct LNK_TypeServerNode { LNK_TypeServer v; struct LNK_TypeServerNode *next; } LNK_TypeServerNode;
U64List *ts_to_obj_arr; // [type_server_count] typedef struct LNK_TypeServerList { U64 count; LNK_TypeServerNode *first; LNK_TypeServerNode *last; } LNK_TypeServerList;
LNK_Obj **obj_arr; // [count] typedef struct LNK_TypeServerArray { U64 count; LNK_TypeServer *v; } LNK_TypeServerArray;
LNK_PchInfo *pch_arr; // [count]
CV_DebugS *debug_s_arr; // [count]
CV_DebugT *debug_p_arr; // [count]
CV_DebugT *debug_t_arr; // [count]
CV_DebugT *merged_debug_t_p_arr; // [count]
U64 total_symbol_input_count; typedef struct
LNK_CodeViewSymbolsInput *symbol_inputs; // [total_symbol_input_count]
CV_SymbolListArray *parsed_symbols; // [count]
LNK_Obj **internal_obj_arr; // [internal_count]
CV_DebugS *internal_debug_s_arr; // [internal_count]
CV_DebugT *internal_debug_t_arr; // [internal_count]
CV_DebugT *internal_debug_p_arr; // [internal_count]
U64 internal_total_symbol_input_count;
LNK_CodeViewSymbolsInput *internal_symbol_inputs; // [internal_total_symbol_input_count]
CV_SymbolListArray *internal_parsed_symbols; // [internal_count]
LNK_Obj **external_obj_arr; // [external_count]
CV_DebugS *external_debug_s_arr; // [external_count]
CV_DebugT *external_debug_t_arr; // [external_count]
CV_DebugT *external_debug_p_arr; // [external_count]
U64 external_total_symbol_input_count;
LNK_CodeViewSymbolsInput *external_symbol_inputs; // [exteranl_total_symbol_input_count]
CV_SymbolListArray *external_parsed_symbols; // [external_count]
Rng1U64 **external_ti_ranges; // [type_server_count]
CV_DebugT **external_leaves; // [type_server_count]
U64 *external_obj_to_ts_idx_arr; // [external_count]
Rng1U64 external_obj_range;
} LNK_CodeViewInput;
typedef struct LNK_MergedTypes
{ {
CV_TypeIndex min_type_indices[CV_TypeIndexSource_COUNT];
U64 count[CV_TypeIndexSource_COUNT]; U64 count[CV_TypeIndexSource_COUNT];
U8 **v [CV_TypeIndexSource_COUNT]; U8 **v [CV_TypeIndexSource_COUNT];
} LNK_MergedTypes; } LNK_MergedTypes;
// --- Leaf Ref ----------------------------------------------------------------
typedef enum
{
LNK_LeafLocType_Internal,
LNK_LeafLocType_External,
LNK_LeafLocType_Count
} LNK_LeafLocType;
#define LNK_LeafRefFlag_LocIdxExternal (1u << 31)
#define LNK_LeafRefFlag_LeafIdxIPI (1u << 31)
typedef struct typedef struct
{ {
U32 enc_loc_idx; LNK_IO_Flags io_flags;
U32 enc_leaf_idx; U64 count;
LNK_Obj **obj_arr;
CV_DebugS *debug_s_arr;
CV_DebugT *debug_p_arr;
CV_DebugT *debug_t_arr;
CV_DebugH *debug_h_arr;
U64 *obj_to_ts;
CV_SymbolListArray *parsed_symbols; // [count]
U32Array int_obj_indices;
U32Array ext_obj_indices;
U32Array debug_p_indices;
U32Array type_server_indices;
Rng1U64 ts_obj_range;
LNK_TypeServerArray ts_arr;
B32 *is_type_server_discarded; // [ts_arr.count]
CV_TypeIndex min_type_indices[CV_TypeIndexSource_COUNT];
U64 symbol_input_count;
LNK_SymbolInput *symbol_inputs; // [symbol_input_count]
} LNK_CodeViewInput;
// --- Leaf Deduping Tasks -----------------------------------------------------
typedef struct
{
U32 obj_idx;
U32 leaf_idx;
} LNK_LeafRef; } LNK_LeafRef;
typedef struct LNK_LeafRange typedef struct LNK_LeafRange
@@ -109,107 +114,43 @@ typedef struct
LNK_LeafRef **bucket_arr; LNK_LeafRef **bucket_arr;
} LNK_LeafHashTable; } LNK_LeafHashTable;
typedef union
{
struct {
U64 ***internal_hashes;
U64 ***external_hashes;
};
U64 ***v[CV_TypeIndexSource_COUNT];
} LNK_LeafHashes;
// --- Symbol Parsing Tasks ----------------------------------------------------
typedef struct
{
LNK_Obj **obj_arr;
String8List *sect_list_arr;
CV_DebugS *debug_s_arr;
} LNK_ParseDebugSTaskData;
typedef struct
{
LNK_Obj **obj_arr;
String8Array *data_arr_arr;
} LNK_CheckDebugTSigTaskData;
typedef struct
{
LNK_Obj **obj_arr;
String8Array *data_arr_arr;
CV_DebugT *debug_t_arr;
} LNK_ParseDebugTTaskData;
typedef struct
{
String8Array data_arr;
MSF_Parsed **msf_parse_arr;
} LNK_MsfParsedFromDataTask;
typedef struct
{
CV_TypeServerInfo *ts_info_arr;
MSF_Parsed **msf_parse_arr;
Rng1U64 **external_ti_ranges;
CV_DebugT **external_leaves;
B8 *is_corrupted;
} LNK_GetExternalLeavesTask;
// --- Leaf Deduping Tasks -----------------------------------------------------
typedef struct
{
U64 loc_idx_bit_count_0;
U64 loc_idx_bit_count_1;
U64 loc_idx_bit_count_2;
U64 counts_max;
U32 **counts_arr;
Rng1U64 *ranges;
LNK_LeafRef **dst;
LNK_LeafRef **src;
U64 loc_idx_max;
U64 pass_idx;
} LNK_LeafRadixSortTask;
typedef struct
{
U32 *counts;
U32 *offsets;
LNK_LeafRef **dst;
LNK_LeafRef **src;
Rng1U64 *ranges;
} LNK_LeafLocRadixSortTask;
typedef struct typedef struct
{ {
LNK_CodeViewInput *input; LNK_CodeViewInput *input;
LNK_LeafHashes *hashes; CV_DebugS *debug_s_arr;
Arena **fixed_arenas; CV_SymbolList *symbol_list_arr;
Rng1U64 *ranges;
LNK_LeafHashTable leaf_ht_arr[CV_TypeIndexSource_COUNT]; LNK_LeafHashTable leaf_ht_arr[CV_TypeIndexSource_COUNT];
CV_DebugT *debug_t_arr; Arena **fixed_arenas;
CV_TypeIndexSource ti_source; CV_TypeIndexSource ti_source;
U32Array indices;
Rng1U64 *ranges;
// count types per source // count types per source
LNK_LeafRangeList *leaf_ranges_per_task; LNK_LeafRangeList *leaf_ranges_per_task;
U64 internal_per_source_count[CV_TypeIndexSource_COUNT]; U64 per_source_count[CV_TypeIndexSource_COUNT];
U64 external_per_source_count[CV_TypeIndexSource_COUNT];
// extract present buckets // extract present buckets
U64 *counts [CV_TypeIndexSource_COUNT]; U64 *counts [CV_TypeIndexSource_COUNT];
U64 *offsets[CV_TypeIndexSource_COUNT]; U64 *offsets[CV_TypeIndexSource_COUNT];
// leaf ref radix sort
U64 obj_idx_bit_count_0;
U64 obj_idx_bit_count_1;
U64 obj_idx_bit_count_2;
U64 counts_max;
U32 **counts_arr;
LNK_LeafRef **dst;
LNK_LeafRef **src;
U64 pass_idx;
// assign type indices // assign type indices
U64 assigned_type_caps [CV_TypeIndexSource_COUNT]; U64 assigned_type_caps [CV_TypeIndexSource_COUNT];
CV_TypeIndex *assigned_type_hts [CV_TypeIndexSource_COUNT]; CV_TypeIndex *assigned_type_hts [CV_TypeIndexSource_COUNT];
CV_TypeIndex min_type_indices [CV_TypeIndexSource_COUNT]; CV_TypeIndex min_type_indices [CV_TypeIndexSource_COUNT];
LNK_LeafRefArray unique_leaf_refs_arr[CV_TypeIndexSource_COUNT]; LNK_LeafRefArray unique_leaf_refs_arr[CV_TypeIndexSource_COUNT];
CV_SymbolList *symbol_list_arr; LNK_MergedTypes result;
CV_DebugS *debug_s_arr; } LNK_MergeTypes;
LNK_MergedTypes merged_types;
} LNK_CvImportTypes;
// --- Code View Processing Trasks --------------------------------------------- // --- Code View Processing Trasks ---------------------------------------------
@@ -226,16 +167,16 @@ typedef struct
typedef struct typedef struct
{ {
LNK_CodeViewSymbolsInput *inputs; LNK_SymbolInput *inputs;
} LNK_ParseCVSymbolsTaskData; } LNK_ParseCVSymbolsTaskData;
typedef struct typedef struct
{ {
U64 total_symbol_input_count; U64 symbol_input_count;
CV_SymbolListArray *parsed_symbols; CV_SymbolListArray *parsed_symbols;
U64 *serialized_symbol_data_sizes; U64 *serialized_symbol_data_sizes;
LNK_CodeViewSymbolsInput *symbol_inputs; LNK_SymbolInput *symbol_inputs;
PDB_DbiModule **mod_arr; PDB_DbiModule **mod_arr;
String8List *symbol_data_arr; String8List *symbol_data_arr;
CV_SymbolList *gsi_list_arr; CV_SymbolList *gsi_list_arr;
@@ -298,7 +239,7 @@ typedef struct
{ {
CV_TypeIndex ipi_min_type_index; CV_TypeIndex ipi_min_type_index;
CV_DebugT ipi_types; CV_DebugT ipi_types;
LNK_CodeViewSymbolsInput *symbol_inputs; LNK_SymbolInput *symbol_inputs;
CV_SymbolListArray *parsed_symbols; CV_SymbolListArray *parsed_symbols;
} LNK_PostProcessCvSymbolsTask; } LNK_PostProcessCvSymbolsTask;
@@ -410,7 +351,7 @@ typedef struct
CV_DebugS *debug_s_arr; CV_DebugS *debug_s_arr;
U64 leaf_arr_count_ipi; U64 leaf_arr_count_ipi;
U8 **leaf_arr_ipi; U8 **leaf_arr_ipi;
LNK_CodeViewSymbolsInput *symbol_inputs; LNK_SymbolInput *symbol_inputs;
CV_SymbolListArray *parsed_symbols; CV_SymbolListArray *parsed_symbols;
Rng1U64 ipi_itype_range; Rng1U64 ipi_itype_range;
Rng1U64 tpi_itype_range; Rng1U64 tpi_itype_range;
@@ -449,35 +390,18 @@ typedef struct
internal CV_DebugS * lnk_parse_debug_s_sections(TP_Context *tp, TP_Arena *arena, U64 obj_count, LNK_Obj **obj_arr, String8List *sect_list_arr); internal CV_DebugS * lnk_parse_debug_s_sections(TP_Context *tp, TP_Arena *arena, U64 obj_count, LNK_Obj **obj_arr, String8List *sect_list_arr);
internal CV_DebugT * lnk_parse_debug_t_sections(TP_Context *tp, TP_Arena *arena, U64 obj_count, LNK_Obj **obj_arr, String8List *debug_t_list_arr); internal CV_DebugT * lnk_parse_debug_t_sections(TP_Context *tp, TP_Arena *arena, U64 obj_count, LNK_Obj **obj_arr, String8List *debug_t_list_arr);
internal LNK_PchInfo * lnk_setup_pch (Arena *arena, U64 obj_count, LNK_Obj **obj_arr, CV_DebugT *debug_t_arr, CV_DebugT *debug_p_arr, CV_SymbolListArray *parsed_symbols, String8List alt_pch_dirs);
internal LNK_CodeViewInput lnk_make_code_view_input(TP_Context *tp, TP_Arena *tp_arena, LNK_IO_Flags io_flags, String8List lib_dir_list, String8List alt_pch_dirs, U64 objs_count, LNK_Obj **objs); internal LNK_CodeViewInput lnk_make_code_view_input(TP_Context *tp, TP_Arena *tp_arena, LNK_IO_Flags io_flags, String8List lib_dir_list, String8List alt_pch_dirs, U64 objs_count, LNK_Obj **objs);
internal LNK_LeafRef lnk_leaf_ref (U32 idx, U32 leaf_idx); // type merging
internal LNK_LeafRef lnk_obj_leaf_ref (U32 obj_idx, U32 leaf_idx); internal int lnk_leaf_ref_compare (LNK_LeafRef a, LNK_LeafRef b);
internal LNK_LeafRef lnk_ts_leaf_ref (CV_TypeIndexSource ti_source, U32 ts_idx, U32 leaf_idx); internal int lnk_leaf_ref_is_before (void *raw_a, void *raw_b);
internal LNK_LeafLocType lnk_loc_type_from_leaf_ref(LNK_LeafRef leaf_ref); internal B32 lnk_match_leaf_ref (LNK_CodeViewInput *input, LNK_LeafRef a, LNK_LeafRef b);
internal int lnk_leaf_ref_compare (LNK_LeafRef a, LNK_LeafRef b); internal U64 lnk_hash_cv_leaf (LNK_CodeViewInput *input, LNK_LeafRef leaf_ref, CV_TypeIndexInfoList ti_info_list, B32 discard_cycles);
internal void lnk_hash_cv_leaf_deep (Arena *arena, LNK_CodeViewInput *input, LNK_LeafRef leaf_ref, CV_TypeIndexInfoList ti_info_list);
internal LNK_LeafLocType lnk_loc_type_from_obj_idx (LNK_CodeViewInput *input, U64 obj_idx); internal LNK_LeafRef * lnk_leaf_hash_table_insert_or_update(LNK_LeafHashTable *leaf_ht, LNK_CodeViewInput *input, CV_DebugH *hashes, U64 hash, LNK_LeafRef *new_bucket);
internal U64 lnk_loc_idx_from_obj_idx (LNK_CodeViewInput *input, U64 obj_idx); internal LNK_LeafRef * lnk_leaf_hash_table_search (LNK_LeafHashTable *ht, LNK_CodeViewInput *input, LNK_LeafRef leaf_ref);
internal CV_TypeIndex lnk_ti_lo_from_loc (LNK_CodeViewInput *input, LNK_LeafLocType loc_type, U64 loc_idx, CV_TypeIndexSource ti_source); internal LNK_MergedTypes lnk_merge_types (TP_Context *tp, TP_Arena *tp_temp, LNK_CodeViewInput *input);
internal CV_TypeIndex lnk_ti_lo_from_leaf_ref (LNK_CodeViewInput *input, LNK_LeafRef leaf_ref); internal void lnk_replace_type_names_with_hashes (TP_Context *tp, TP_Arena *arena, U64 leaf_count, U8 **leaf_arr, LNK_TypeNameHashMode mode, U64 hash_length, String8 map_name);
internal String8 lnk_data_from_leaf_ref (LNK_CodeViewInput *input, LNK_LeafRef leaf_ref);
internal LNK_LeafRef lnk_leaf_ref_from_loc_idx_and_ti(LNK_CodeViewInput *input, LNK_LeafLocType loc_type, CV_TypeIndexSource ti_source, U64 loc_idx, CV_TypeIndex obj_ti);
internal B32 lnk_match_leaf_ref (LNK_CodeViewInput *input, LNK_LeafHashes *hashes, LNK_LeafRef a, LNK_LeafRef b);
// leaf hashing
internal U64 lnk_hash_cv_leaf (LNK_CodeViewInput *input, LNK_LeafHashes *hashes, LNK_LeafLocType loc_type, U32 loc_idx, Rng1U64 *ti_ranges, CV_TypeIndex curr_ti, CV_Leaf leaf, CV_TypeIndexInfoList ti_info_list);
internal void lnk_hash_cv_leaf_deep(Arena *arena, LNK_CodeViewInput *input, Rng1U64 *ti_ranges, CV_DebugT *leaves, LNK_LeafHashes *hashes, CV_TypeIndexSource ti_source, CV_TypeIndex ti, LNK_LeafLocType loc_type, U32 loc_idx, CV_TypeIndexInfoList ti_info_list, CV_Leaf leaf);
internal U64 lnk_hash_from_leaf_ref(LNK_LeafHashes *hashes, LNK_LeafRef leaf_ref);
// leaf hash table
internal LNK_LeafRef * lnk_leaf_hash_table_insert_or_update(LNK_LeafHashTable *leaf_ht, LNK_CodeViewInput *input, LNK_LeafHashes *hashes, U64 hash, LNK_LeafRef *new_bucket);
internal LNK_LeafRef * lnk_leaf_hash_table_search(LNK_LeafHashTable *ht, LNK_CodeViewInput *input, LNK_LeafHashes *hashes, LNK_LeafRef leaf_ref);
internal LNK_MergedTypes lnk_merge_types(TP_Context *tp, TP_Arena *tp_temp, LNK_CodeViewInput *input);
internal void lnk_replace_type_names_with_hashes(TP_Context *tp, TP_Arena *arena, U64 leaf_count, U8 **leaf_arr, LNK_TypeNameHashMode mode, U64 hash_length, String8 map_name);
// --- RAD Debug info ---------------------------------------------------------- // --- RAD Debug info ----------------------------------------------------------
@@ -501,11 +425,10 @@ lnk_build_rad_debug_info(TP_Context *tp,
U64 obj_count, U64 obj_count,
LNK_Obj **obj_arr, LNK_Obj **obj_arr,
CV_DebugS *debug_s_arr, CV_DebugS *debug_s_arr,
U64 total_symbol_input_count, U64 symbol_input_count,
LNK_CodeViewSymbolsInput *symbol_inputs, LNK_SymbolInput *symbol_inputs,
CV_SymbolListArray *parsed_symbols, CV_SymbolListArray *parsed_symbols,
U64 leaf_count[CV_TypeIndexSource_COUNT], LNK_MergedTypes types);
U8 **leaf_arr [CV_TypeIndexSource_COUNT]);
// --- PDB --------------------------------------------------------------------- // --- PDB ---------------------------------------------------------------------
@@ -522,11 +445,10 @@ internal String8List lnk_build_pdb(TP_Context *tp,
U64 obj_count, U64 obj_count,
LNK_Obj **obj_arr, LNK_Obj **obj_arr,
CV_DebugS *debug_s_arr, CV_DebugS *debug_s_arr,
U64 total_symbol_input_count, U64 symbol_input_count,
LNK_CodeViewSymbolsInput *symbol_inputs, LNK_SymbolInput *symbol_inputs,
CV_SymbolListArray *parsed_symbols, CV_SymbolListArray *parsed_symbols,
U64 leaf_count[CV_TypeIndexSource_COUNT], LNK_MergedTypes types);
U8 **leaf_arr [CV_TypeIndexSource_COUNT]);
// --- RAD Debug Info ---------------------------------------------------------- // --- RAD Debug Info ----------------------------------------------------------
+37 -4
View File
@@ -946,6 +946,39 @@ pdb_type_server_parse_from_data_v80(String8 data, PDB_TypeServerParse *parse)
return error; return error;
} }
internal B32
pdb_extract_type_server_info(String8 raw_msf, MSF_RawStreamTable *st, MSF_StreamNumber sn, Rng1U64 *ti_range_out, Rng1U64 *leaf_range_out)
{
Temp scratch = scratch_begin(0,0);
B32 is_ok = 0;
String8 version_data = msf_data_from_stream_number_ex(scratch.arena, raw_msf, st, sn, r1u64(0, sizeof(PDB_TpiVersion)), 8);
PDB_TpiVersion *version = str8_deserial_get_raw_ptr(version_data, 0, sizeof(*version));
if (version) {
switch (*version) {
case PDB_TpiVersion_IMPV80: {
String8 header_size_data = msf_data_from_stream_number_ex(scratch.arena, raw_msf, st, sn, r1u64(sizeof(*version), sizeof(*version) + sizeof(U32)), 8);
U32 *header_size = str8_deserial_get_raw_ptr(header_size_data, 0, sizeof(*header_size));
if (header_size && *header_size >= sizeof(PDB_TpiVersion) + sizeof(U32)) {
String8 header_data = msf_data_from_stream_number_ex(scratch.arena, raw_msf, st, sn, r1u64(0, *header_size), 8);
PDB_TpiHeader *header = str8_deserial_get_raw_ptr(header_data, 0, sizeof(*header));
if (*header_size + header->leaf_data_size <= st->streams[sn].size) {
*ti_range_out = r1u64(header->ti_lo, header->ti_hi);
*leaf_range_out = r1u64(*header_size, *header_size + header->leaf_data_size);
is_ok = 1;
} else {
NotImplemented; // TODO: handle error
}
} else {
NotImplemented; // TODO: handle error
}
} break;
default: break;
}
}
scratch_end(scratch);
return is_ok;
}
internal PDB_OpenTypeServerError internal PDB_OpenTypeServerError
pdb_type_server_parse_from_data(String8 data, PDB_TypeServerParse *parse_out) pdb_type_server_parse_from_data(String8 data, PDB_TypeServerParse *parse_out)
{ {
@@ -1042,9 +1075,9 @@ pdb_type_server_open_v80(MSF_Context *msf, MSF_StreamNumber sn, PDB_StringTable
// rebuild type buckets // rebuild type buckets
for (U64 cursor = 0, leaf_idx = 0; for (U64 cursor = 0, leaf_idx = 0;
cursor + header.hash_key_size <= hash_buffer_size; cursor + header.hash_key_size <= hash_buffer_size;
cursor += header.hash_key_size, leaf_idx += 1) { cursor += header.hash_key_size, leaf_idx += 1) {
String8 raw_leaf = cv_debug_t_get_raw_leaf(debug_t, leaf_idx); String8 raw_leaf = cv_debug_t_get_raw_leaf(&debug_t, leaf_idx);
str8_list_push(ts->arena, &ts->leaf_list, raw_leaf); str8_list_push(ts->arena, &ts->leaf_list, raw_leaf);
@@ -1103,7 +1136,7 @@ pdb_type_server_open_v80(MSF_Context *msf, MSF_StreamNumber sn, PDB_StringTable
Assert(curr); Assert(curr);
} }
exit:; exit:
scratch_end(scratch); scratch_end(scratch);
ProfEnd(); ProfEnd();
return ts; return ts;
+39 -27
View File
@@ -227,51 +227,63 @@ msf_raw_stream_table_from_data(Arena *arena, String8 msf_data)
} }
internal String8 internal String8
msf_data_from_stream_number(Arena *arena, String8 msf_data, MSF_RawStreamTable *st, MSF_StreamNumber sn) msf_data_from_stream_number_ex(Arena *arena, String8 msf_data, MSF_RawStreamTable *st, MSF_StreamNumber sn, Rng1U64 range, U64 align)
{ {
ProfBeginFunction(); ProfBeginFunction();
String8 result = {0}; String8 result = {0};
if(sn < st->stream_count) if(sn < st->stream_count)
{ {
MSF_RawStream stream = st->streams[sn]; MSF_RawStream stream = st->streams[sn];
U8 *stream_buf = push_array_no_zero(arena, U8, stream.size); Rng1U64 range_clamped = { .min = Min(range.min, stream.size), .max = Min(range.max, stream.size) };
U8 *stream_out_ptr = stream_buf; U64 page_count = CeilIntegerDiv(dim_1u64(range_clamped), st->page_size);
for (U32 i = 0; i < stream.page_count; ++i) { U64 pn_base = range_clamped.min / st->page_size;
U64 page_idx;
if (st->index_size == 4) { result = (String8){ .str = push_array_aligned(arena, U8, dim_1u64(range_clamped), align) };
page_idx = stream.u.page_indices_u32[i];
} else { for EachIndex(page_idx, page_count) {
page_idx = stream.u.page_indices_u16[i]; U64 pn_begin;
if (st->index_size == 4) { pn_begin = stream.u.page_indices_u32[pn_base + page_idx]; }
else { pn_begin = stream.u.page_indices_u16[pn_base + page_idx]; }
U64 pn_end = pn_begin;
for (; page_idx+1 < page_count; page_idx += 1) {
U64 next_pn = 0;
if (st->index_size == 4) { next_pn = stream.u.page_indices_u32[pn_base + page_idx + 1]; }
else { next_pn = stream.u.page_indices_u16[pn_base + page_idx + 1]; }
if ((pn_end + 1) != next_pn) { break; }
pn_end = next_pn;
} }
pn_end += 1;
U64 stream_page_off = (U64)page_idx * st->page_size; U64 read_off = result.size + range_clamped.min;
if (stream_page_off + st->page_size > msf_data.size) { U64 to_read = dim_1u64(range_clamped) - result.size;
break; U64 read_size = Min(to_read, (pn_end - pn_begin) * st->page_size - (read_off % st->page_size));
}
U8 *stream_page_base = msf_data.str + stream_page_off; U64 page_off = (pn_begin * st->page_size) + (read_off % st->page_size);
String8 page = str8_substr(msf_data, r1u64(page_off, page_off + read_size));
// clamp copy size by end of stream if (page.size != read_size) { break; }
U32 stream_pos = (U32) (stream_out_ptr - stream_buf);
U32 remaining_size = stream.size - stream_pos;
U32 copy_size = ClampTop(st->page_size, remaining_size);
// copy page data // copy page data
MemoryCopy(stream_out_ptr, stream_page_base, copy_size); Assert(result.size + read_size <= dim_1u64(range_clamped));
stream_out_ptr += copy_size; U8 *ptr = result.str + result.size;
MemoryCopy(ptr, page.str, read_size);
result.size += read_size;
} }
U64 copy_size = (U64)(stream_out_ptr - stream_buf); // release unused bytes
U64 unused_buf_size = dim_1u64(range_clamped) - result.size;
U64 unused_buf_size = stream.size - copy_size;
arena_pop(arena, unused_buf_size); arena_pop(arena, unused_buf_size);
result = str8(stream_buf, copy_size);
} }
ProfEnd(); ProfEnd();
return result; return result;
} }
internal String8
msf_data_from_stream_number(Arena *arena, String8 msf_data, MSF_RawStreamTable *st, MSF_StreamNumber sn)
{
return msf_data_from_stream_number_ex(arena, msf_data, st, sn, r1u64(0, max_U64), 8);
}
internal MSF_Parsed * internal MSF_Parsed *
msf_parsed_from_data(Arena *arena, String8 msf_data) msf_parsed_from_data(Arena *arena, String8 msf_data)
{ {
+2
View File
@@ -41,6 +41,8 @@ struct MSF_Parsed
//~ rjf: MSF Parser Functions //~ rjf: MSF Parser Functions
internal MSF_RawStreamTable* msf_raw_stream_table_from_data(Arena *arena, String8 msf_data); internal MSF_RawStreamTable* msf_raw_stream_table_from_data(Arena *arena, String8 msf_data);
internal U64 msf_size_from_stream_number(MSF_RawStreamTable *st, MSF_StreamNumber sn);
internal String8 msf_data_from_stream_number_ex(Arena *arena, String8 msf_data, MSF_RawStreamTable *st, MSF_StreamNumber sn, Rng1U64 range, U64 align);
internal String8 msf_data_from_stream_number(Arena *arena, String8 msf_data, MSF_RawStreamTable *st, MSF_StreamNumber sn); internal String8 msf_data_from_stream_number(Arena *arena, String8 msf_data, MSF_RawStreamTable *st, MSF_StreamNumber sn);
internal MSF_Parsed* msf_parsed_from_data(Arena *arena, String8 msf_data); internal MSF_Parsed* msf_parsed_from_data(Arena *arena, String8 msf_data);
internal String8 msf_data_from_stream(MSF_Parsed *msf, MSF_StreamNumber sn); internal String8 msf_data_from_stream(MSF_Parsed *msf, MSF_StreamNumber sn);
+83 -5
View File
@@ -3943,6 +3943,67 @@ T_EndTest;
T_BeginTest(merge_duplicate_types) T_BeginTest(merge_duplicate_types)
{ {
{ {
U32 pch_sig = 0xCAFEBABE;
String8 debug_s;
{
String8List srl;
str8_serial_begin(scratch.arena, &srl);
CV_Signature sig = CV_Signature_C13;
str8_serial_push_struct(scratch.arena, &srl, &sig);
CV_C13SubSectionHeader *ss_header = str8_serial_push_size(scratch.arena, &srl, sizeof(*ss_header));
U64 ss_start_off = srl.total_size;
CV_SymObjName obj_name = {0};
obj_name.sig = pch_sig;
String8 obj_name_string = str8_lit("a.obj");
str8_serial_push_u16(scratch.arena, &srl, sizeof(CV_SymKind) + sizeof(obj_name) + obj_name_string.size + 1);
str8_serial_push_u16(scratch.arena, &srl, CV_SymKind_OBJNAME);
str8_serial_push_struct(scratch.arena, &srl, &obj_name);
str8_serial_push_cstr(scratch.arena, &srl, obj_name_string);
str8_serial_push_align(scratch.arena, &srl, CV_SymbolAlign);
ss_header->kind = CV_C13SubSectionKind_Symbols;
ss_header->size = srl.total_size - ss_start_off;
str8_serial_push_align(scratch.arena, &srl, CV_C13SubSectionAlign);
debug_s = str8_serial_end(scratch.arena, &srl);
}
String8 debug_p;
{
String8List srl;
str8_serial_begin(scratch.arena, &srl);
// signature
CV_Signature sig = CV_Signature_C13;
str8_serial_push_struct(scratch.arena, &srl, &sig);
// duplicate in a.obj
CV_LeafPointer ptr = { .itype = CV_BasicType_VOID };
str8_serial_push_u16(scratch.arena, &srl, sizeof(CV_LeafKind) + sizeof(ptr));
str8_serial_push_u16(scratch.arena, &srl, CV_LeafKind_POINTER);
str8_serial_push_struct(scratch.arena, &srl, &ptr);
str8_serial_push_align(scratch.arena, &srl, CV_LeafAlign);
// unique procedure type
CV_LeafProcedure proc = { .ret_itype = 0x1000, .call_kind = CV_CallKind_NearPascal };
str8_serial_push_u16(scratch.arena, &srl, sizeof(CV_LeafKind) + sizeof(proc));
str8_serial_push_u16(scratch.arena, &srl, CV_LeafKind_PROCEDURE);
str8_serial_push_struct(scratch.arena, &srl, &proc);
str8_serial_push_align(scratch.arena, &srl, CV_LeafAlign);
// PCH ender
CV_LeafEndPreComp endprecomp = { .sig = pch_sig };
str8_serial_push_u16(scratch.arena, &srl, sizeof(CV_LeafKind) + sizeof(endprecomp));
str8_serial_push_u16(scratch.arena, &srl, CV_LeafKind_ENDPRECOMP);
str8_serial_push_struct(scratch.arena, &srl, &endprecomp);
str8_serial_push_align(scratch.arena, &srl, CV_LeafAlign);
debug_p = str8_serial_end(scratch.arena, &srl);
}
String8 debug_t; String8 debug_t;
{ {
String8List srl; String8List srl;
@@ -3951,17 +4012,25 @@ T_BeginTest(merge_duplicate_types)
CV_Signature sig = CV_Signature_C13; CV_Signature sig = CV_Signature_C13;
str8_serial_push_struct(scratch.arena, &srl, &sig); str8_serial_push_struct(scratch.arena, &srl, &sig);
CV_LeafPreComp precomp = { .start_index = CV_MinComplexTypeIndex, .count = 3, sig = pch_sig };
String8 pch_obj_name = str8_lit("pch.obj");
str8_serial_push_u16(scratch.arena, &srl, sizeof(CV_LeafKind) + sizeof(CV_LeafPreComp) + pch_obj_name.size + 1);
str8_serial_push_u16(scratch.arena, &srl, CV_LeafKind_PRECOMP);
str8_serial_push_struct(scratch.arena, &srl, &precomp);
str8_serial_push_cstr(scratch.arena, &srl, pch_obj_name);
str8_serial_push_align(scratch.arena, &srl, CV_LeafAlign);
CV_LeafPointer ptr = { .itype = CV_BasicType_VOID }; CV_LeafPointer ptr = { .itype = CV_BasicType_VOID };
str8_serial_push_u16(scratch.arena, &srl, sizeof(CV_LeafKind) + sizeof(CV_LeafPointer)); str8_serial_push_u16(scratch.arena, &srl, sizeof(CV_LeafKind) + sizeof(CV_LeafPointer));
str8_serial_push_u16(scratch.arena, &srl, CV_LeafKind_POINTER); str8_serial_push_u16(scratch.arena, &srl, CV_LeafKind_POINTER);
str8_serial_push_struct(scratch.arena, &srl, &ptr); str8_serial_push_struct(scratch.arena, &srl, &ptr);
str8_serial_push_align(scratch.arena, &srl, 4); str8_serial_push_align(scratch.arena, &srl, CV_LeafAlign);
CV_LeafProcedure proc = { .ret_itype = 0x1000, .call_kind = CV_CallKind_NearC }; CV_LeafProcedure proc = { .ret_itype = 0x1000, .call_kind = CV_CallKind_NearC };
str8_serial_push_u16(scratch.arena, &srl, sizeof(CV_LeafKind) + sizeof(CV_LeafProcedure)); str8_serial_push_u16(scratch.arena, &srl, sizeof(CV_LeafKind) + sizeof(CV_LeafProcedure));
str8_serial_push_u16(scratch.arena, &srl, CV_LeafKind_PROCEDURE); str8_serial_push_u16(scratch.arena, &srl, CV_LeafKind_PROCEDURE);
str8_serial_push_struct(scratch.arena, &srl, &proc); str8_serial_push_struct(scratch.arena, &srl, &proc);
str8_serial_push_align(scratch.arena, &srl, 4); str8_serial_push_align(scratch.arena, &srl, CV_LeafAlign);
debug_t = str8_serial_end(scratch.arena, &srl); debug_t = str8_serial_end(scratch.arena, &srl);
} }
@@ -3978,17 +4047,25 @@ T_BeginTest(merge_duplicate_types)
str8_serial_push_u16(scratch.arena, &srl, sizeof(CV_LeafKind) + sizeof(CV_LeafPointer)); str8_serial_push_u16(scratch.arena, &srl, sizeof(CV_LeafKind) + sizeof(CV_LeafPointer));
str8_serial_push_u16(scratch.arena, &srl, CV_LeafKind_POINTER); str8_serial_push_u16(scratch.arena, &srl, CV_LeafKind_POINTER);
str8_serial_push_struct(scratch.arena, &srl, &ptr); str8_serial_push_struct(scratch.arena, &srl, &ptr);
str8_serial_push_align(scratch.arena, &srl, 4); str8_serial_push_align(scratch.arena, &srl, CV_LeafAlign);
CV_LeafProcedure proc = { .ret_itype = 0x1000, .call_kind = CV_CallKind_NearC }; CV_LeafProcedure proc = { .ret_itype = 0x1000, .call_kind = CV_CallKind_NearC };
str8_serial_push_u16(scratch.arena, &srl, sizeof(CV_LeafKind) + sizeof(CV_LeafProcedure)); str8_serial_push_u16(scratch.arena, &srl, sizeof(CV_LeafKind) + sizeof(CV_LeafProcedure));
str8_serial_push_u16(scratch.arena, &srl, CV_LeafKind_PROCEDURE); str8_serial_push_u16(scratch.arena, &srl, CV_LeafKind_PROCEDURE);
str8_serial_push_struct(scratch.arena, &srl, &proc); str8_serial_push_struct(scratch.arena, &srl, &proc);
str8_serial_push_align(scratch.arena, &srl, 4); str8_serial_push_align(scratch.arena, &srl, CV_LeafAlign);
same_but_different = str8_serial_end(scratch.arena, &srl); same_but_different = str8_serial_end(scratch.arena, &srl);
} }
String8 pch_obj;
{
COFF_ObjWriter *cow = coff_obj_writer_alloc(0, COFF_MachineType_X64);
coff_obj_writer_push_section(cow, str8_lit(".debug$P"), PE_DEBUG_SECTION_FLAGS|COFF_SectionFlag_Align1Bytes, debug_p);
coff_obj_writer_push_section(cow, str8_lit(".debug$S"), PE_DEBUG_SECTION_FLAGS|COFF_SectionFlag_Align1Bytes, debug_s);
pch_obj = coff_obj_writer_serialize(scratch.arena, cow);
}
String8 a_obj; String8 a_obj;
{ {
COFF_ObjWriter *cow = coff_obj_writer_alloc(0, COFF_MachineType_X64); COFF_ObjWriter *cow = coff_obj_writer_alloc(0, COFF_MachineType_X64);
@@ -4013,11 +4090,12 @@ T_BeginTest(merge_duplicate_types)
String8 entry_obj = t_make_entry_obj(scratch.arena); String8 entry_obj = t_make_entry_obj(scratch.arena);
T_Ok(t_write_file(str8_lit("entry.obj"), entry_obj)); T_Ok(t_write_file(str8_lit("entry.obj"), entry_obj));
T_Ok(t_write_file(str8_lit("pch.obj"), pch_obj));
T_Ok(t_write_file(str8_lit("a.obj"), a_obj)); T_Ok(t_write_file(str8_lit("a.obj"), a_obj));
T_Ok(t_write_file(str8_lit("b.obj"), b_obj)); T_Ok(t_write_file(str8_lit("b.obj"), b_obj));
T_Ok(t_write_file(str8_lit("c.obj"), c_obj)); T_Ok(t_write_file(str8_lit("c.obj"), c_obj));
t_invoke_linkerf("/subsystem:console /entry:entry /debug:full /out:a.exe a.obj b.obj c.obj entry.obj"); t_invoke_linkerf("/subsystem:console /entry:entry /debug:full /out:a.exe a.obj b.obj c.obj pch.obj entry.obj");
T_Ok(g_last_exit_code == 0); T_Ok(g_last_exit_code == 0);
} }