private void AddModuleMembers(XElement element, IModule module, string symbolModuleName) { AddMembers(element, typeof(IModule), module, nameof(IModule.ModuleIndex), nameof(IModule.PdbFileInfos), nameof(IModule.VersionString)); if (symbolModuleName != null && IsModuleEqual(module, symbolModuleName)) { IExportSymbols exportSymbols = module.Services.GetService <IExportSymbols>(); if (exportSymbols is not null) { XElement exportSymbolsElement = null; string symbol1 = "coreclr_initialize"; if (exportSymbols.TryGetSymbolAddress(symbol1, out ulong offset1)) { XElement symbolElement = AddExportSymbolSection(); symbolElement.Add(new XElement("Name", symbol1)); symbolElement.Add(new XElement("Value", ToHex(offset1))); } string symbol2 = "coreclr_execute_assembly"; if (exportSymbols.TryGetSymbolAddress(symbol2, out ulong offset2)) { XElement symbolElement = AddExportSymbolSection(); symbolElement.Add(new XElement("Name", symbol2)); symbolElement.Add(new XElement("Value", ToHex(offset2))); } XElement AddExportSymbolSection() { if (exportSymbolsElement == null) { exportSymbolsElement = new XElement("ExportSymbols"); element.Add(exportSymbolsElement); } var symbolElement = new XElement("Symbol"); exportSymbolsElement.Add(symbolElement); return(symbolElement); } } IModuleSymbols moduleSymbols = module.Services.GetService <IModuleSymbols>(); if (moduleSymbols is not null) { XElement symbolsElement = null; string symbol1 = "coreclr_initialize"; if (moduleSymbols.TryGetSymbolAddress(symbol1, out ulong offset1)) { XElement symbolElement = AddExportSymbolSection(); symbolElement.Add(new XElement("Name", symbol1)); symbolElement.Add(new XElement("Value", ToHex(offset1))); symbolElement.Add(new XElement("Displacement", "0")); } XElement AddExportSymbolSection() { if (symbolsElement == null) { symbolsElement = new XElement("Symbols"); element.Add(symbolsElement); } var symbolElement = new XElement("Symbol"); symbolsElement.Add(symbolElement); return(symbolElement); } } } }
public void ModuleTests(TestHost host) { var moduleService = host.Target.Services.GetService <IModuleService>(); Assert.NotNull(moduleService); foreach (ImmutableDictionary <string, TestDataReader.Value> moduleData in host.TestData.Modules) { if (moduleData.TryGetValue("FileName", out string moduleFileName)) { if (s_excludedModules.Contains(Path.GetFileName(moduleFileName))) { continue; } } // Test the module service's GetModuleFromBaseAddress() and GetModuleFromAddress() Assert.True(moduleData.TryGetValue("ImageBase", out ulong imageBase)); IModule module = null; try { module = moduleService.GetModuleFromBaseAddress(imageBase); } catch (DiagnosticsException) { Trace.TraceInformation($"GetModuleFromBaseAddress({imageBase:X16}) {moduleFileName} FAILED"); // Skip modules not found when running under lldb if (host.Target.Host.HostType == HostType.Lldb) { continue; } } Assert.NotNull(module); if (host.Target.Host.HostType != HostType.Lldb) { // Check that the resulting module matches the test data moduleData.CompareMembers(module); } IModule module1 = moduleService.GetModuleFromIndex(module.ModuleIndex); Assert.NotNull(module1); Assert.Equal(module, module1); // Test GetModuleFromAddress on various address in module IModule module2 = moduleService.GetModuleFromAddress(imageBase); Assert.NotNull(module2); Assert.True(module.ModuleIndex == module2.ModuleIndex); Assert.Equal(module, module2); module2 = moduleService.GetModuleFromAddress(imageBase + 0x100); Assert.NotNull(module2); Assert.True(module.ModuleIndex == module2.ModuleIndex); Assert.Equal(module, module2); module2 = moduleService.GetModuleFromAddress(imageBase + module.ImageSize - 1); Assert.NotNull(module2); Assert.True(module.ModuleIndex == module2.ModuleIndex); Assert.Equal(module, module2); // Find this module in the list of all modules Assert.NotNull(moduleService.EnumerateModules().SingleOrDefault((mod) => mod.ImageBase == imageBase)); if (host.Target.Host.HostType != HostType.Lldb) { // Test the module service's GetModuleFromName() if (!string.IsNullOrEmpty(moduleFileName)) { IEnumerable <IModule> modules = moduleService.GetModuleFromModuleName(moduleFileName); Assert.NotNull(modules); Assert.True(modules.Any()); foreach (IModule mod in modules) { if (mod.ImageBase == imageBase) { // Check that the resulting module matches the test data moduleData.CompareMembers(mod); } } } } // Test the symbol lookup module interfaces if (host.Target.Host.HostType != HostType.DotnetDump) { if (moduleData.TryGetValue("ExportSymbols", out TestDataReader.Value testExportSymbols)) { IExportSymbols exportSymbols = module.Services.GetService <IExportSymbols>(); Assert.NotNull(exportSymbols); foreach (ImmutableDictionary <string, TestDataReader.Value> symbol in testExportSymbols.Values) { Assert.True(symbol.TryGetValue("Name", out string name)); Assert.True(symbol.TryGetValue("Value", out ulong value)); Trace.TraceInformation("IExportSymbols.GetSymbolAddress({0}) == {1:X16}", name, value); Assert.True(exportSymbols.TryGetSymbolAddress(name, out ulong offset)); Assert.Equal(value, offset); } } if (moduleData.TryGetValue("Symbols", out TestDataReader.Value testSymbols)) { IModuleSymbols moduleSymbols = module.Services.GetService <IModuleSymbols>(); Assert.NotNull(moduleSymbols); foreach (ImmutableDictionary <string, TestDataReader.Value> symbol in testSymbols.Values) { Assert.True(symbol.TryGetValue("Name", out string symbolName)); Assert.True(symbol.TryGetValue("Value", out ulong symbolValue)); Trace.TraceInformation("IModuleSymbols.GetSymbolAddress({0}) == {1:X16}", symbolName, symbolValue); Assert.True(moduleSymbols.TryGetSymbolName(symbolValue, out string name, out ulong displacement)); Assert.Equal(symbolName, name); Assert.True(moduleSymbols.TryGetSymbolAddress(symbolName, out ulong value)); Assert.Equal(symbolValue, value); if (symbol.TryGetValue("Displacement", out ulong symbolDisplacement)) { Assert.Equal(symbolDisplacement, displacement); } } } } } }