mirror of
https://github.com/Ed94/raddebugger.git
synced 2026-09-24 02:00:05 +00:00
WIP: internal and external type servers are functioning except for the
PCH indirection
This commit is contained in:
@@ -396,6 +396,12 @@ cv_make_proc_refs(Arena *arena, CV_ModIndex imod, CV_SymbolList symbol_list)
|
||||
return proc_ref_list;
|
||||
}
|
||||
|
||||
internal B32
|
||||
cv_is_obj_info(CV_Symbol symbol)
|
||||
{
|
||||
return symbol.kind == CV_SymKind_OBJNAME;
|
||||
}
|
||||
|
||||
internal CV_ObjInfo
|
||||
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;
|
||||
str8_deserial_read_cstr(symbol.data, sizeof(CV_SymObjName), &result.name);
|
||||
} break;
|
||||
case CV_SymKind_OBJNAME_ST: {
|
||||
NotImplemented;
|
||||
} break;
|
||||
default: {
|
||||
InvalidPath;
|
||||
} break;
|
||||
default: { InvalidPath; } break;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@@ -1092,76 +1093,123 @@ cv_dedup_symbol_ptr_array(TP_Context *tp, CV_SymbolPtrArray *symbols)
|
||||
internal CV_DebugT
|
||||
cv_debug_t_from_data(Arena *arena, String8 data, U64 align)
|
||||
{
|
||||
ProfBegin("Upfront parse");
|
||||
U64 count = 0;
|
||||
for (U64 cursor = 0; cursor < data.size; count += 1) {
|
||||
CV_Leaf leaf;
|
||||
cursor += cv_read_leaf(data, cursor, align, &leaf);
|
||||
CV_DebugT debug_t = { .data = data };
|
||||
|
||||
ProfBegin("Upfront parse for counts");
|
||||
for (U64 cursor = 0, prev_cursor = 0, ti = CV_MinComplexTypeIndex; cursor < data.size; ti += 1) {
|
||||
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();
|
||||
|
||||
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;) {
|
||||
offsets[idx++] = cursor;
|
||||
|
||||
debug_t.offsets[idx++] = cursor;
|
||||
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
|
||||
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};
|
||||
if (debug_t.count > 0) {
|
||||
Assert(leaf_idx < debug_t.count);
|
||||
cv_read_leaf(debug_t.data, debug_t.offsets[leaf_idx], 1, &leaf);
|
||||
if (debug_t->count > 0) {
|
||||
Assert(leaf_idx < debug_t->count);
|
||||
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);
|
||||
}
|
||||
return leaf;
|
||||
}
|
||||
|
||||
internal String8
|
||||
cv_debug_t_get_raw_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)
|
||||
{
|
||||
Assert(leaf_idx < debug_t.count);
|
||||
U8 *leaf_ptr = debug_t.data.str + debug_t.offsets[leaf_idx];
|
||||
Assert(contains_1u64(debug_t->ti_ranges[source], ti)); // validate TI
|
||||
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);
|
||||
return str8(leaf_ptr, leaf_size + sizeof(leaf_size));
|
||||
}
|
||||
|
||||
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;
|
||||
if (leaf_idx < debug_t.count) {
|
||||
header = (CV_LeafHeader *)(debug_t.data.str + debug_t.offsets[leaf_idx]);
|
||||
if (leaf_idx < debug_t->count) {
|
||||
header = (CV_LeafHeader *)(debug_t->data.str + debug_t->offsets[leaf_idx]);
|
||||
}
|
||||
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
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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
|
||||
|
||||
internal void
|
||||
|
||||
@@ -253,11 +253,27 @@ typedef struct CV_DebugS
|
||||
String8List data_list[CV_C13SubSectionIdxKind_COUNT];
|
||||
} CV_DebugS;
|
||||
|
||||
typedef struct CV_DebugH
|
||||
{
|
||||
U64 count;
|
||||
U64 *v;
|
||||
} CV_DebugH;
|
||||
|
||||
typedef struct CV_DebugT
|
||||
{
|
||||
U64 count;
|
||||
String8 data;
|
||||
U32 *offsets;
|
||||
String8 data;
|
||||
U64 count;
|
||||
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;
|
||||
|
||||
////////////////////////////////
|
||||
@@ -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 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);
|
||||
|
||||
////////////////////////////////
|
||||
@@ -416,13 +433,17 @@ internal String8 cv_file_chksms_from_debug_s(CV_DebugS debug_s);
|
||||
////////////////////////////////
|
||||
//~ .debug$T helpers
|
||||
|
||||
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 String8 cv_debug_t_get_raw_leaf(CV_DebugT debug_t, U64 leaf_idx);
|
||||
internal CV_LeafHeader * cv_debug_t_get_leaf_header(CV_DebugT debug_t, U64 leaf_idx);
|
||||
internal B32 cv_debug_t_is_pch(CV_DebugT debug_t);
|
||||
internal B32 cv_debug_t_is_type_server(CV_DebugT debug_t);
|
||||
internal U64 cv_debug_t_array_count_leaves(U64 count, CV_DebugT *arr);
|
||||
internal CV_DebugT cv_debug_t_from_data (Arena *arena, String8 data, U64 align);
|
||||
internal U64 cv_leaf_idx_from_ti (CV_DebugT *debug_t, CV_TypeIndexSource source, CV_TypeIndex ti);
|
||||
internal CV_TypeIndex cv_ti_from_leaf_idx (CV_DebugT *debug_t, CV_TypeIndexSource source, U64 leaf_idx);
|
||||
internal CV_Leaf cv_debug_t_get_leaf (CV_DebugT *debug_t, U64 leaf_idx);
|
||||
internal CV_Leaf cv_debug_t_get_leaf_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_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
|
||||
|
||||
+8
-10
@@ -5161,14 +5161,13 @@ lnk_run(TP_Context *tp, TP_Arena *arena, LNK_Config *config)
|
||||
rdi_arch_from_coff_machine(config->machine),
|
||||
config->image_name,
|
||||
image_ctx.image_data,
|
||||
input.count,
|
||||
input.obj_arr,
|
||||
debug_info_objs_count,
|
||||
debug_info_objs,
|
||||
input.debug_s_arr,
|
||||
input.total_symbol_input_count,
|
||||
input.symbol_input_count,
|
||||
input.symbol_inputs,
|
||||
input.parsed_symbols,
|
||||
merged_types.count,
|
||||
merged_types.v);
|
||||
merged_types);
|
||||
|
||||
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,
|
||||
config,
|
||||
symtab,
|
||||
input.count,
|
||||
input.obj_arr,
|
||||
debug_info_objs_count,
|
||||
debug_info_objs,
|
||||
input.debug_s_arr,
|
||||
input.total_symbol_input_count,
|
||||
input.symbol_input_count,
|
||||
input.symbol_inputs,
|
||||
input.parsed_symbols,
|
||||
merged_types.count,
|
||||
merged_types.v);
|
||||
merged_types);
|
||||
|
||||
lnk_write_data_list_to_file_path(config->pdb_name, config->temp_pdb_name, pdb_data);
|
||||
lnk_timer_end(LNK_Timer_Pdb);
|
||||
|
||||
+893
-1666
File diff suppressed because it is too large
Load Diff
+106
-184
@@ -3,84 +3,89 @@
|
||||
|
||||
#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 ---------------------------------------------------------
|
||||
|
||||
typedef struct LNK_PchInfo
|
||||
{
|
||||
CV_TypeIndex ti_lo;
|
||||
CV_TypeIndex ti_hi;
|
||||
U64 debug_p_obj_idx;
|
||||
} LNK_PchInfo;
|
||||
|
||||
typedef struct LNK_CodeViewSymbolsInput
|
||||
typedef struct LNK_SymbolInput
|
||||
{
|
||||
U64 obj_idx;
|
||||
CV_DebugS *debug_s;
|
||||
CV_SymbolList *symbol_list;
|
||||
String8 raw_symbols;
|
||||
} LNK_CodeViewSymbolsInput;
|
||||
} LNK_SymbolInput;
|
||||
|
||||
typedef struct LNK_CodeViewInput
|
||||
typedef struct
|
||||
{
|
||||
U64 count;
|
||||
U64 internal_count;
|
||||
U64 external_count;
|
||||
U64 type_server_count;
|
||||
String8 *type_server_path_arr; // [type_server_count]
|
||||
String8 *type_server_data_arr; // [type_server_count]
|
||||
U64List *ts_to_obj_arr; // [type_server_count]
|
||||
LNK_Obj **obj_arr; // [count]
|
||||
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]
|
||||
CV_TypeServerInfo ts_info;
|
||||
U64 ts_idx;
|
||||
String8 ts_path;
|
||||
U64List obj_indices;
|
||||
} LNK_TypeServer;
|
||||
typedef struct LNK_TypeServerNode { LNK_TypeServer v; struct LNK_TypeServerNode *next; } LNK_TypeServerNode;
|
||||
typedef struct LNK_TypeServerList { U64 count; LNK_TypeServerNode *first; LNK_TypeServerNode *last; } LNK_TypeServerList;
|
||||
typedef struct LNK_TypeServerArray { U64 count; LNK_TypeServer *v; } LNK_TypeServerArray;
|
||||
|
||||
U64 total_symbol_input_count;
|
||||
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
|
||||
typedef struct
|
||||
{
|
||||
CV_TypeIndex min_type_indices[CV_TypeIndexSource_COUNT];
|
||||
U64 count[CV_TypeIndexSource_COUNT];
|
||||
U8 **v [CV_TypeIndexSource_COUNT];
|
||||
} 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
|
||||
{
|
||||
U32 enc_loc_idx;
|
||||
U32 enc_leaf_idx;
|
||||
LNK_IO_Flags io_flags;
|
||||
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;
|
||||
|
||||
typedef struct LNK_LeafRange
|
||||
@@ -109,107 +114,43 @@ typedef struct
|
||||
LNK_LeafRef **bucket_arr;
|
||||
} 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
|
||||
{
|
||||
LNK_CodeViewInput *input;
|
||||
LNK_LeafHashes *hashes;
|
||||
Arena **fixed_arenas;
|
||||
Rng1U64 *ranges;
|
||||
CV_DebugS *debug_s_arr;
|
||||
CV_SymbolList *symbol_list_arr;
|
||||
LNK_LeafHashTable leaf_ht_arr[CV_TypeIndexSource_COUNT];
|
||||
CV_DebugT *debug_t_arr;
|
||||
Arena **fixed_arenas;
|
||||
CV_TypeIndexSource ti_source;
|
||||
U32Array indices;
|
||||
Rng1U64 *ranges;
|
||||
|
||||
// count types per source
|
||||
LNK_LeafRangeList *leaf_ranges_per_task;
|
||||
U64 internal_per_source_count[CV_TypeIndexSource_COUNT];
|
||||
U64 external_per_source_count[CV_TypeIndexSource_COUNT];
|
||||
U64 per_source_count[CV_TypeIndexSource_COUNT];
|
||||
|
||||
// extract present buckets
|
||||
U64 *counts [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
|
||||
U64 assigned_type_caps [CV_TypeIndexSource_COUNT];
|
||||
CV_TypeIndex *assigned_type_hts [CV_TypeIndexSource_COUNT];
|
||||
CV_TypeIndex min_type_indices [CV_TypeIndexSource_COUNT];
|
||||
LNK_LeafRefArray unique_leaf_refs_arr[CV_TypeIndexSource_COUNT];
|
||||
|
||||
CV_SymbolList *symbol_list_arr;
|
||||
CV_DebugS *debug_s_arr;
|
||||
|
||||
LNK_MergedTypes merged_types;
|
||||
} LNK_CvImportTypes;
|
||||
LNK_MergedTypes result;
|
||||
} LNK_MergeTypes;
|
||||
|
||||
// --- Code View Processing Trasks ---------------------------------------------
|
||||
|
||||
@@ -226,16 +167,16 @@ typedef struct
|
||||
|
||||
typedef struct
|
||||
{
|
||||
LNK_CodeViewSymbolsInput *inputs;
|
||||
LNK_SymbolInput *inputs;
|
||||
} LNK_ParseCVSymbolsTaskData;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
U64 total_symbol_input_count;
|
||||
U64 symbol_input_count;
|
||||
CV_SymbolListArray *parsed_symbols;
|
||||
U64 *serialized_symbol_data_sizes;
|
||||
|
||||
LNK_CodeViewSymbolsInput *symbol_inputs;
|
||||
LNK_SymbolInput *symbol_inputs;
|
||||
PDB_DbiModule **mod_arr;
|
||||
String8List *symbol_data_arr;
|
||||
CV_SymbolList *gsi_list_arr;
|
||||
@@ -298,7 +239,7 @@ typedef struct
|
||||
{
|
||||
CV_TypeIndex ipi_min_type_index;
|
||||
CV_DebugT ipi_types;
|
||||
LNK_CodeViewSymbolsInput *symbol_inputs;
|
||||
LNK_SymbolInput *symbol_inputs;
|
||||
CV_SymbolListArray *parsed_symbols;
|
||||
} LNK_PostProcessCvSymbolsTask;
|
||||
|
||||
@@ -410,7 +351,7 @@ typedef struct
|
||||
CV_DebugS *debug_s_arr;
|
||||
U64 leaf_arr_count_ipi;
|
||||
U8 **leaf_arr_ipi;
|
||||
LNK_CodeViewSymbolsInput *symbol_inputs;
|
||||
LNK_SymbolInput *symbol_inputs;
|
||||
CV_SymbolListArray *parsed_symbols;
|
||||
Rng1U64 ipi_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_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_LeafRef lnk_leaf_ref (U32 idx, U32 leaf_idx);
|
||||
internal LNK_LeafRef lnk_obj_leaf_ref (U32 obj_idx, U32 leaf_idx);
|
||||
internal LNK_LeafRef lnk_ts_leaf_ref (CV_TypeIndexSource ti_source, U32 ts_idx, U32 leaf_idx);
|
||||
internal LNK_LeafLocType lnk_loc_type_from_leaf_ref(LNK_LeafRef leaf_ref);
|
||||
internal int lnk_leaf_ref_compare (LNK_LeafRef a, LNK_LeafRef b);
|
||||
|
||||
internal LNK_LeafLocType lnk_loc_type_from_obj_idx (LNK_CodeViewInput *input, U64 obj_idx);
|
||||
internal U64 lnk_loc_idx_from_obj_idx (LNK_CodeViewInput *input, U64 obj_idx);
|
||||
internal CV_TypeIndex lnk_ti_lo_from_loc (LNK_CodeViewInput *input, LNK_LeafLocType loc_type, U64 loc_idx, CV_TypeIndexSource ti_source);
|
||||
internal CV_TypeIndex lnk_ti_lo_from_leaf_ref (LNK_CodeViewInput *input, LNK_LeafRef leaf_ref);
|
||||
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);
|
||||
// type merging
|
||||
internal int lnk_leaf_ref_compare (LNK_LeafRef a, LNK_LeafRef b);
|
||||
internal int lnk_leaf_ref_is_before (void *raw_a, void *raw_b);
|
||||
internal B32 lnk_match_leaf_ref (LNK_CodeViewInput *input, 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_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 LNK_LeafRef * lnk_leaf_hash_table_search (LNK_LeafHashTable *ht, LNK_CodeViewInput *input, 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 ----------------------------------------------------------
|
||||
|
||||
@@ -501,11 +425,10 @@ lnk_build_rad_debug_info(TP_Context *tp,
|
||||
U64 obj_count,
|
||||
LNK_Obj **obj_arr,
|
||||
CV_DebugS *debug_s_arr,
|
||||
U64 total_symbol_input_count,
|
||||
LNK_CodeViewSymbolsInput *symbol_inputs,
|
||||
U64 symbol_input_count,
|
||||
LNK_SymbolInput *symbol_inputs,
|
||||
CV_SymbolListArray *parsed_symbols,
|
||||
U64 leaf_count[CV_TypeIndexSource_COUNT],
|
||||
U8 **leaf_arr [CV_TypeIndexSource_COUNT]);
|
||||
LNK_MergedTypes types);
|
||||
|
||||
// --- PDB ---------------------------------------------------------------------
|
||||
|
||||
@@ -522,11 +445,10 @@ internal String8List lnk_build_pdb(TP_Context *tp,
|
||||
U64 obj_count,
|
||||
LNK_Obj **obj_arr,
|
||||
CV_DebugS *debug_s_arr,
|
||||
U64 total_symbol_input_count,
|
||||
LNK_CodeViewSymbolsInput *symbol_inputs,
|
||||
U64 symbol_input_count,
|
||||
LNK_SymbolInput *symbol_inputs,
|
||||
CV_SymbolListArray *parsed_symbols,
|
||||
U64 leaf_count[CV_TypeIndexSource_COUNT],
|
||||
U8 **leaf_arr [CV_TypeIndexSource_COUNT]);
|
||||
LNK_MergedTypes types);
|
||||
|
||||
// --- RAD Debug Info ----------------------------------------------------------
|
||||
|
||||
|
||||
@@ -946,6 +946,39 @@ pdb_type_server_parse_from_data_v80(String8 data, PDB_TypeServerParse *parse)
|
||||
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
|
||||
pdb_type_server_parse_from_data(String8 data, PDB_TypeServerParse *parse_out)
|
||||
{
|
||||
@@ -1027,42 +1060,42 @@ pdb_type_server_open_v80(MSF_Context *msf, MSF_StreamNumber sn, PDB_StringTable
|
||||
if (header.hash_vals.off + header.hash_vals.size > hash_stream_size) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
|
||||
ts = pdb_type_server_alloc(header.hash_bucket_count);
|
||||
|
||||
|
||||
// read & parse code view types
|
||||
String8 types_data = msf_stream_read_block(ts->arena, msf, sn, header.leaf_data_size);
|
||||
CV_DebugT debug_t = cv_debug_t_from_data(scratch.arena, types_data, PDB_LEAF_ALIGN);
|
||||
|
||||
|
||||
// read hash data
|
||||
U8 *hash_buffer = push_array(scratch.arena, U8, header.hash_vals.size);
|
||||
msf_stream_seek(msf, header.hash_sn, header.hash_vals.off);
|
||||
MSF_UInt hash_buffer_size = msf_stream_read(msf, header.hash_sn, hash_buffer, header.hash_vals.size);
|
||||
Assert(hash_buffer_size == header.hash_vals.size);
|
||||
|
||||
|
||||
// rebuild type buckets
|
||||
for (U64 cursor = 0, leaf_idx = 0;
|
||||
cursor + header.hash_key_size <= hash_buffer_size;
|
||||
cursor += header.hash_key_size, leaf_idx += 1) {
|
||||
String8 raw_leaf = cv_debug_t_get_raw_leaf(debug_t, leaf_idx);
|
||||
cursor + header.hash_key_size <= hash_buffer_size;
|
||||
cursor += header.hash_key_size, leaf_idx += 1) {
|
||||
String8 raw_leaf = cv_debug_t_get_raw_leaf(&debug_t, leaf_idx);
|
||||
|
||||
str8_list_push(ts->arena, &ts->leaf_list, raw_leaf);
|
||||
|
||||
|
||||
// read out bucket hash
|
||||
U64 hash = 0;
|
||||
MemoryCopy(&hash, hash_buffer + cursor, header.hash_key_size);
|
||||
|
||||
|
||||
// push bucket
|
||||
PDB_TypeBucket *bucket = push_array(ts->arena, PDB_TypeBucket, 1);
|
||||
bucket->raw_leaf = raw_leaf;
|
||||
bucket->type_index = header.ti_lo + leaf_idx;
|
||||
SLLStackPush(ts->buckets[hash], bucket);
|
||||
}
|
||||
|
||||
|
||||
// adjust type buckets
|
||||
msf_stream_seek(msf, header.hash_sn, header.hash_adj.off);
|
||||
String8 adjust_data = msf_stream_read_block(scratch.arena, msf, header.hash_sn, header.hash_adj.size);
|
||||
|
||||
|
||||
// open adjust hash table
|
||||
PDB_HashTableParseError hash_adj_parse_error = pdb_hash_adj_hash_table_from_data(&ts->hash_adj, adjust_data, strtab, 0);
|
||||
if (hash_adj_parse_error == PDB_HashTableParseError_OUT_OF_BYTES) {
|
||||
@@ -1075,7 +1108,7 @@ pdb_type_server_open_v80(MSF_Context *msf, MSF_StreamNumber sn, PDB_StringTable
|
||||
String8Array key_arr = {0};
|
||||
String8Array value_arr = {0};
|
||||
pdb_hash_table_get_present_keys_and_values(scratch.arena, &ts->hash_adj, &key_arr, &value_arr);
|
||||
|
||||
|
||||
// adjust type buckets
|
||||
for (U64 i = 0; i < ts->hash_adj.count; i += 1) {
|
||||
String8 type_name = key_arr.v[i];
|
||||
@@ -1084,7 +1117,7 @@ pdb_type_server_open_v80(MSF_Context *msf, MSF_StreamNumber sn, PDB_StringTable
|
||||
// name -> hash
|
||||
U64 hash = pdb_hash_v1(type_name);
|
||||
hash %= ts->bucket_cap;
|
||||
|
||||
|
||||
// search for type bucket
|
||||
PDB_TypeBucket *curr, *prev;
|
||||
for (curr = ts->buckets[hash], prev = 0; curr != 0; prev = curr, curr = curr->next) {
|
||||
@@ -1092,18 +1125,18 @@ pdb_type_server_open_v80(MSF_Context *msf, MSF_StreamNumber sn, PDB_StringTable
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// move type to the head
|
||||
if (prev && curr) {
|
||||
prev->next = curr->next;
|
||||
curr->next = ts->buckets[hash];
|
||||
ts->buckets[hash] = curr;
|
||||
}
|
||||
|
||||
|
||||
Assert(curr);
|
||||
}
|
||||
|
||||
exit:;
|
||||
|
||||
exit:
|
||||
scratch_end(scratch);
|
||||
ProfEnd();
|
||||
return ts;
|
||||
|
||||
Reference in New Issue
Block a user