mirror of
https://github.com/Ed94/raddebugger.git
synced 2026-10-14 04:49:41 -07:00
342 lines
13 KiB
C
342 lines
13 KiB
C
// Copyright (c) Epic Games Tools
|
|
// Licensed under the MIT license (https://opensource.org/license/mit/)
|
|
|
|
#pragma once
|
|
|
|
////////////////////////////////
|
|
// CodeView
|
|
|
|
typedef struct
|
|
{
|
|
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, *last; } LNK_TypeServerList;
|
|
typedef struct LNK_TypeServerArray { U64 count; LNK_TypeServer *v; } LNK_TypeServerArray;
|
|
|
|
typedef struct LNK_SymbolInput
|
|
{
|
|
U64 obj_idx;
|
|
String8 raw_symbols;
|
|
} LNK_SymbolInput;
|
|
|
|
typedef struct
|
|
{
|
|
LNK_Config *config;
|
|
U64 obj_count;
|
|
B32 is_stripped;
|
|
|
|
U64 count;
|
|
LNK_Obj **obj_arr;
|
|
CV_DebugS *debug_s_arr;
|
|
CV_DebugT *debug_t_arr;
|
|
CV_DebugH *debug_h_arr;
|
|
U64 *obj_to_ts;
|
|
|
|
String8List *debug_s_list_arr;
|
|
String8List *debug_p_list_arr;
|
|
String8List *debug_t_list_arr;
|
|
String8List *debug_h_list_arr;
|
|
|
|
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]
|
|
Rng1U64 *symbol_input_ranges; // [worker_count]
|
|
} LNK_CodeViewInput;
|
|
|
|
typedef struct
|
|
{
|
|
LNK_CodeViewInput *input;
|
|
String8Array *raw_types; // [obj_count]
|
|
CV_DebugT *out_types; // [obj_count]
|
|
} LNK_ParseCvTypes;
|
|
|
|
////////////////////////////////
|
|
// Type Merging
|
|
|
|
typedef struct { U32 obj_idx; U32 leaf_idx; } LNK_LeafRef;
|
|
typedef struct { U64 count; LNK_LeafRef **v; } LNK_LeafRefArray;
|
|
|
|
typedef struct
|
|
{
|
|
U64 cap;
|
|
LNK_LeafRef **bucket_arr;
|
|
} LNK_LeafHashTable;
|
|
|
|
typedef struct LNK_LeafRange
|
|
{
|
|
struct LNK_LeafRange *next;
|
|
Rng1U64 range;
|
|
CV_DebugT *debug_t;
|
|
} LNK_LeafRange;
|
|
typedef struct { U64 count; LNK_LeafRange *first, *last; } LNK_LeafRangeList;
|
|
|
|
typedef struct
|
|
{
|
|
CV_TypeIndex min_type_indices[CV_TypeIndexSource_COUNT];
|
|
U64 count[CV_TypeIndexSource_COUNT];
|
|
U8 **v [CV_TypeIndexSource_COUNT];
|
|
} LNK_MergedTypes;
|
|
|
|
typedef struct
|
|
{
|
|
LNK_CodeViewInput *input;
|
|
CV_DebugS *debug_s_arr;
|
|
LNK_LeafHashTable leaf_ht_arr[CV_TypeIndexSource_COUNT];
|
|
Arena **fixed_arenas;
|
|
CV_TypeIndexSource ti_source;
|
|
U32Array indices;
|
|
Rng1U64 *ranges;
|
|
|
|
// count types per source
|
|
LNK_LeafRangeList *leaf_ranges_per_task;
|
|
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];
|
|
|
|
LNK_MergedTypes result;
|
|
} LNK_MergeTypes;
|
|
|
|
////////////////////////////////
|
|
// PDB
|
|
|
|
typedef struct
|
|
{
|
|
String8 image_data;
|
|
LNK_SymbolTable *symtab;
|
|
LNK_CodeViewInput *cv;
|
|
PDB_Context *pdb;
|
|
CV_StringHashTable string_ht;
|
|
PDB_DbiModule **mod_arr; // [obj_count]
|
|
U32Array *obj_indices; // [obj_count]
|
|
|
|
U64 symbol_count;
|
|
|
|
// push DBI SC Map
|
|
PE_BinInfo pe;
|
|
COFF_SectionHeader **image_section_table;
|
|
U64 image_section_table_count;
|
|
Rng1U64Array image_section_file_ranges;
|
|
Rng1U64Array image_section_virt_ranges;
|
|
PDB_DbiSectionContribList *sc_list; // [obj_count]
|
|
} LNK_BuildPdb;
|
|
|
|
typedef struct
|
|
{
|
|
U64 leaf_count;
|
|
U8 **leaf_arr;
|
|
Rng1U64 *ranges;
|
|
U64 hash_length;
|
|
B32 make_map;
|
|
TP_Arena *map_arena;
|
|
String8List *maps;
|
|
} LNK_TypeNameReplacer;
|
|
|
|
////////////////////////////////
|
|
// RDI
|
|
|
|
typedef struct
|
|
{
|
|
String8 name;
|
|
U64 leaf_idx;
|
|
} LNK_UDTNameBucket;
|
|
|
|
typedef struct
|
|
{
|
|
U64 leaf_count;
|
|
U8 **leaf_arr;
|
|
Rng1U64 *ranges;
|
|
U64 buckets_cap;
|
|
LNK_UDTNameBucket **buckets;
|
|
} LNK_BuildUDTNameHashTableTask;
|
|
|
|
typedef struct
|
|
{
|
|
CV_DebugT debug_t;
|
|
CV_TypeIndex ti_lo;
|
|
Rng1U64 *ranges;
|
|
U64 udt_name_buckets_cap;
|
|
LNK_UDTNameBucket **udt_name_buckets;
|
|
CV_TypeIndex *fwdmap;
|
|
} LNK_BuildUDTFwdMapTask;
|
|
|
|
typedef struct
|
|
{
|
|
U64 leaf_count[CV_TypeIndexSource_COUNT];
|
|
U8 **leaf_arr[CV_TypeIndexSource_COUNT];
|
|
U64 type_cap;
|
|
U64 udt_cap;
|
|
RDIB_TypeRef variadic_type_ref;
|
|
Rng1U64 *itype_ranges;
|
|
U64 udt_name_bucket_cap;
|
|
LNK_UDTNameBucket **udt_name_buckets;
|
|
RDIB_Type **tpi_itype_map;
|
|
RDIB_TypeChunkList *rdib_types_lists;
|
|
RDIB_TypeChunkList *rdib_types_struct_lists;
|
|
RDIB_TypeChunkList *rdib_types_union_lists;
|
|
RDIB_TypeChunkList *rdib_types_enum_lists;
|
|
RDIB_TypeChunkList *rdib_types_params_lists;
|
|
RDIB_TypeChunkList *rdib_types_udt_members_lists;
|
|
RDIB_TypeChunkList *rdib_types_enum_members_lists;
|
|
RDIB_UDTMemberChunkList *rdib_udt_members_lists;
|
|
RDIB_UDTMemberChunkList *rdib_enum_members_lists;
|
|
Rng1U64 *ranges;
|
|
} LNK_ConvertTypesToRDI;
|
|
|
|
typedef struct
|
|
{
|
|
U64 obj_idx;
|
|
RDIB_SourceFile *src_file;
|
|
} LNK_SourceFileBucket;
|
|
|
|
typedef struct
|
|
{
|
|
LNK_Obj **obj_arr;
|
|
CV_DebugS *debug_s_arr;
|
|
U64 total_src_file_count;
|
|
LNK_SourceFileBucket **src_file_buckets;
|
|
U64 src_file_buckets_cap;
|
|
} LNK_ConvertSourceFilesToRDITask;
|
|
|
|
typedef struct
|
|
{
|
|
CV_Arch arch;
|
|
CV_Language language;
|
|
String8 compiler_name;
|
|
} LNK_CodeViewCompilerInfo;
|
|
|
|
typedef struct
|
|
{
|
|
COFF_SectionHeaderArray image_sects;
|
|
LNK_Obj **obj_arr;
|
|
CV_DebugS *debug_s_arr;
|
|
U64 leaf_arr_count_ipi;
|
|
U8 **leaf_arr_ipi;
|
|
LNK_SymbolInput *symbol_inputs;
|
|
Rng1U64 ipi_itype_range;
|
|
Rng1U64 tpi_itype_range;
|
|
RDIB_Type **tpi_itype_map;
|
|
U64 src_file_buckets_cap;
|
|
LNK_SourceFileBucket **src_file_buckets;
|
|
LNK_UDTNameBucket **udt_name_buckets;
|
|
U64 line_table_cap;
|
|
U64 udt_name_buckets_cap;
|
|
U64 src_file_chunk_cap;
|
|
U64 symbol_chunk_cap;
|
|
U64 unit_chunk_cap;
|
|
U64 inline_site_cap;
|
|
RDIB_LineTable *null_line_table;
|
|
HashTable *extern_symbol_voff_ht;
|
|
LNK_CodeViewCompilerInfo *comp_info_arr;
|
|
CV_InlineeLinesAccel **inlinee_lines_accel_arr;
|
|
|
|
RDIB_InlineSiteChunk **inline_site_chunks;
|
|
|
|
// output
|
|
RDIB_UnitChunk *units;
|
|
RDIB_VariableChunkList *locals;
|
|
RDIB_ScopeChunkList *scopes;
|
|
RDIB_VariableChunkList *extern_gvars;
|
|
RDIB_VariableChunkList *static_gvars;
|
|
RDIB_VariableChunkList *extern_tvars;
|
|
RDIB_VariableChunkList *static_tvars;
|
|
RDIB_ProcedureChunkList *extern_procs;
|
|
RDIB_ProcedureChunkList *static_procs;
|
|
RDIB_InlineSiteChunkList *inline_sites;
|
|
RDIB_LineTableChunkList *line_tables;
|
|
} LNK_ConvertUnitToRDITask;
|
|
|
|
////////////////////////////////
|
|
// CodeView
|
|
|
|
internal LNK_CodeViewInput lnk_make_code_view_input(TP_Context *tp, TP_Arena *tp_arena, LNK_Config *config, U64 objs_count, LNK_Obj **objs);
|
|
|
|
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);
|
|
|
|
////////////////////////////////
|
|
// PDB
|
|
|
|
internal String8List lnk_build_pdb(TP_Context *tp, TP_Arena *tp_arena, String8 image_data, LNK_Config *config, LNK_SymbolTable *symtab, LNK_CodeViewInput *cv, LNK_MergedTypes cv_types);
|
|
|
|
////////////////////////////////
|
|
// RDI
|
|
|
|
internal U64 lnk_udt_name_hash_table_hash (String8 string);
|
|
internal LNK_UDTNameBucket ** lnk_udt_name_hash_table_from_leaf_arr(TP_Context *tp, TP_Arena *arena, U64 leaf_count, U8 **leaf_arr, U64 *buckets_cap_out);
|
|
internal LNK_UDTNameBucket * lnk_udt_name_hash_table_lookup (LNK_UDTNameBucket **buckets, U64 cap, String8 name);
|
|
internal CV_TypeIndex * lnk_build_udt_fwdmap (TP_Context *tp, Arena *arena, CV_DebugT debug_t, CV_TypeIndex ti_lo, LNK_UDTNameBucket **udt_name_buckets, U64 udt_name_buckets_cap);
|
|
|
|
internal RDIB_TypeRef lnk_rdib_type_from_itype (LNK_ConvertTypesToRDI *task, CV_TypeIndex itype);
|
|
internal RDI_MemberKind lnk_rdib_method_kind_from_cv_prop (CV_MethodProp prop);
|
|
internal LNK_SourceFileBucket * lnk_src_file_hash_table_hash (String8 file_path, CV_C13ChecksumKind checksum_kind, String8 checksum_bytes);
|
|
internal LNK_SourceFileBucket * lnk_src_file_hash_table_lookup_slot(LNK_SourceFileBucket **src_file_buckets, U64 src_file_buckets_cap, U64 hash, String8 file_path, CV_C13ChecksumKind checksum_kind, String8 checksum_bytes);
|
|
|
|
internal String8List
|
|
lnk_build_rad_debug_info(TP_Context *tp,
|
|
TP_Arena *tp_arena,
|
|
OperatingSystem os,
|
|
RDI_Arch arch,
|
|
String8 image_name,
|
|
String8 image_data,
|
|
U64 obj_count,
|
|
LNK_Obj **obj_arr,
|
|
CV_DebugS *debug_s_arr,
|
|
U64 symbol_input_count,
|
|
LNK_SymbolInput *symbol_inputs,
|
|
CV_SymbolListArray *parsed_symbols,
|
|
LNK_MergedTypes types);
|
|
|
|
internal U64 lnk_udt_name_hash_table_hash (String8 string);
|
|
internal LNK_UDTNameBucket ** lnk_udt_name_hash_table_from_leaf_arr(TP_Context *tp, TP_Arena *arena, U64 leaf_count, U8 **leaf_arr, U64 *buckets_cap_out);
|
|
internal LNK_UDTNameBucket * lnk_udt_name_hash_table_lookup (LNK_UDTNameBucket **buckets, U64 cap, String8 name);
|
|
|
|
internal CV_TypeIndex * lnk_build_udt_fwdmap(TP_Context *tp,
|
|
Arena *arena,
|
|
CV_DebugT debug_t,
|
|
CV_TypeIndex ti_lo,
|
|
LNK_UDTNameBucket **udt_name_buckets,
|
|
U64 udt_name_buckets_cap);
|
|
|
|
internal void lnk_init_rdib_itype_map (Arena *arena, RDI_Arch arch, RDIB_Type **itype_map, RDIB_TypeChunkList *rdib_types_list);
|
|
internal RDIB_TypeRef lnk_rdib_type_from_itype (LNK_ConvertTypesToRDI *task, CV_TypeIndex itype);
|
|
internal RDI_MemberKind lnk_rdib_method_kind_from_cv_prop(CV_MethodProp prop);
|
|
|