#nullable enable
class DwarfParser
{
- static Regex typeNameRegEx = new Regex(@"^<(?<nesting>\d+)><.*GOFF=0x(?<goff>[0-9a-fA-F]+)><DW_TAG_((class_type)|(structure_type)|(union_type)|(typedef))>(.*DW_AT_name<\u0022(?<name>.+?)\u0022>)?");
- // <1><0x9ad2 GOFF=0x1e17b22><DW_TAG_structure_type> DW_AT_name<"STORAGESIGNATURE"> DW_AT_byte_size<0x00000010> DW_AT_decl_file<0x00000014 /home/stmaclea/git/runtime/src/coreclr/src/md/inc/mdfileformat.h> DW_AT_decl_line<0x0000003f>
- static Regex typeRegEx = new Regex(@"^<(?<nesting>\d+)><.*GOFF=0x(?<goff>[0-9a-fA-F]+)><DW_TAG_((class)|(structure)|(union))_type>(.*DW_AT_name<\u0022(?<name>.+?)\u0022>)?.*?DW_AT_decl_file");
+ static Regex typeNameRegEx = new Regex(@"^<(?<nesting>\d+)><.*GOFF=0x(?<goff>[0-9a-fA-F]+)><DW_TAG_((class_type)|(structure_type)|(union_type)|(typedef))>(.*DW_AT_name<(?<name>[^<>]*(((?'Open'<)[^<>]*)+((?'Close-Open'>)[^<>]*)+)*(?(Open)(?!)))>)?");
+ // <1><0x9ad2 GOFF=0x1e17b22><DW_TAG_structure_type> DW_AT_name<STORAGESIGNATURE> DW_AT_byte_size<0x00000010> DW_AT_decl_file<0x00000014 /home/stmaclea/git/runtime/src/coreclr/src/md/inc/mdfileformat.h> DW_AT_decl_line<0x0000003f>
+ static Regex typeRegEx = new Regex(@"^<(?<nesting>\d+)><.*GOFF=0x(?<goff>[0-9a-fA-F]+)><DW_TAG_((class)|(structure)|(union))_type>(.*DW_AT_name<(?<name>[^<>]*(((?'Open'<)[^<>]*)+((?'Close-Open'>)[^<>]*)+)*(?(Open)(?!)))>)?.*?DW_AT_decl_file");
- // <2><0x4d GOFF=0x1b5a><DW_TAG_member> DW_AT_name<"Data1"> DW_AT_type<<0x00000082 GOFF=0x00001b8f>> DW_AT_decl_file<0x00000001 /home/stmaclea/git/runtime/src/coreclr/src/pal/inc/pal_mstypes.h> DW_AT_decl_line<0x000002ac> DW_AT_data_member_location<0>
- static Regex memberRegEx = new Regex(@"^<(?<nesting>\d+)><.*GOFF=0x(?<goff>[0-9a-fA-F]+)><DW_TAG_member>.*.*?DW_AT_data_member_location<(?<offset>\d+)([(][^)]*[)])?>");
+ // <2><0x4d GOFF=0x1b5a><DW_TAG_member> DW_AT_name<Data1> DW_AT_type<<0x00000082 GOFF=0x00001b8f>> DW_AT_decl_file<0x00000001 /home/stmaclea/git/runtime/src/coreclr/src/pal/inc/pal_mstypes.h> DW_AT_decl_line<0x000002ac> DW_AT_data_member_location<0>
+ static Regex memberRegEx = new Regex(@"^<(?<nesting>\d+)><.*GOFF=0x(?<goff>[0-9a-fA-F]+)><DW_TAG_member>.*.*?DW_AT_data_member_location<(?<offset>\d+) *([(][^)]*[)])?>");
- // DW_AT_name<"Data1">
- static Regex nameRegEx = new Regex(@"DW_AT_name<\u0022(?<name>.+?)\u0022>");
+ // DW_AT_name<Data1>
+ static Regex nameRegEx = new Regex(@"DW_AT_name<(?<name>[^<>]*(((?'Open'<)[^<>]*)+((?'Close-Open'>)[^<>]*)+)*(?(Open)(?!)))>");
// DW_AT_type<<0x00000082 GOFF=0x00001b8f>>
static Regex typeRefRegEx = new Regex(@"DW_AT_type<<[^>]*GOFF=0x(?<goff>[0-9a-fA-F]+)>>");
"RSPtrArray<CordbAppDomain,RSSmartPtr<CordbAppDomain>>",
"RSPtrArray<CordbInternalFrame,RSSmartPtr<CordbInternalFrame>>",
"RSPtrArray<CordbProcess,RSSmartPtr<CordbProcess>>",
+ "Target_CLiteWeightStgdbRW",
// DBI not used in cross OS
"TwoWayPipe",
// Shims
// Not expected to matter
"ShimProcess",
- "ShimRemoteDataTarget"
+ "ShimRemoteDataTarget",
+
+ // Libunwind types 3.1 crossdac uses a different libunwind version
+ "cursor",
+ "dwarf_cie_info",
+ "dwarf_cursor",
+ "dwarf_rs_cache",
+ "map_iterator",
+ "mempool",
+ "ucontext",
+ "unw_addr_space",
+ "unw_tdep_save_loc"
};
return ignoreTypes.Exists(x => String.CompareOrdinal(x, fullName) == 0);
return true;
}
- static void CompareTypes(Type dwarfType, Type pdbType)
+ int ignored;
+ int matched;
+ int mismatched;
+ int dwarfUnique;
+ int pdbUnique;
+
+ Program() {}
+
+ void CompareTypes(Type dwarfType, Type pdbType)
{
- if (IsIgnoreType(pdbType) || AllPbdAlternatesMatch(dwarfType, pdbType))
+ if (IsIgnoreType(pdbType))
+ {
+ ignored++;
+ return;
+ }
+
+ if (AllPbdAlternatesMatch(dwarfType, pdbType))
+ {
+ matched++;
return;
+ }
+
+ mismatched++;
foreach(var p in pdbType.Alternates.Values)
{
}
}
- static void Main(string[] args)
+ int Main(string pdbPath, string dwarfPath)
{
- string pdbPath = @"pdb";
- string dwarfPath = @"dwarf";
-
Dictionary<string, Type> pdbTypes = new Dictionary<string, Type>();
Dictionary<string, Type> dwarfTypes = new Dictionary<string, Type>();
}
}
+ Console.WriteLine($"PDB unique types : {pdbTypes.Keys.Count}");
+
foreach (Type type in DwarfParser.Parse(File.ReadLines(dwarfPath)))
{
if (dwarfTypes.ContainsKey(type.FullName))
}
}
+ Console.WriteLine($"Dwarf unique types : {dwarfTypes.Keys.Count}");
+
foreach (Type type in dwarfTypes.Values.OrderBy(x => x.FullName))
{
if (pdbTypes.ContainsKey(type.FullName))
{
CompareTypes(type, pdbTypes[type.FullName]);
}
+ else
+ {
+ // Console.WriteLine($"dwarf unique type : {type.FullName}");
+ dwarfUnique++;
+ }
+ }
+
+ foreach (Type type in pdbTypes.Values.OrderBy(x => x.FullName))
+ {
+ if (!dwarfTypes.ContainsKey(type.FullName))
+ {
+ // Console.WriteLine($"PDB unique type : {type.FullName}");
+ pdbUnique++;
+ }
}
+
+ Console.WriteLine($"Matches: {matched}");
+ Console.WriteLine($"Ignored: {ignored}");
+ Console.WriteLine($"Mismatched: {mismatched}");
+ Console.WriteLine($"DwarfUnique: {dwarfUnique}");
+ Console.WriteLine($"PdbUnique: {pdbUnique}");
+
+ return mismatched + (matched == 0 ? 1 : 0);
+ }
+
+ static int Main(string[] args)
+ {
+ string pdbPath = @"pdb";
+ string dwarfPath = @"dwarf";
+
+ Program program = new Program();
+
+ return program.Main(pdbPath, dwarfPath);
}
}
}