private static ReaderParameters GetReaderParameters(string assemblyPath) { DefaultAssemblyResolver assemblyResolver = new DefaultAssemblyResolver(); string assemblyLocation = Path.GetDirectoryName(assemblyPath); assemblyResolver.AddSearchDirectory(assemblyLocation); ReaderParameters readerParameters = new ReaderParameters { AssemblyResolver = assemblyResolver, ReadingMode = ReadingMode.Immediate }; string pdbName = Path.ChangeExtension(assemblyPath, "pdb"); if (!File.Exists(pdbName)) { return(readerParameters); } PdbReaderProvider symbolReaderProvider = new PdbReaderProvider(); readerParameters.SymbolReaderProvider = symbolReaderProvider; readerParameters.ReadSymbols = true; return(readerParameters); }
public static AssemblyDefinition GetAssemblyDef(string assemblyPath) { if (assemblies.ContainsKey(assemblyPath)) { return(assemblies[assemblyPath]); } var assemblyResolver = new DefaultAssemblyResolver(); var assemblyLocation = Path.GetDirectoryName(assemblyPath); assemblyResolver.AddSearchDirectory(assemblyLocation); var readerParameters = new ReaderParameters { AssemblyResolver = assemblyResolver }; var pdbName = Path.ChangeExtension(assemblyPath, "pdb"); if (File.Exists(pdbName)) { var symbolReaderProvider = new PdbReaderProvider(); readerParameters.SymbolReaderProvider = symbolReaderProvider; readerParameters.ReadSymbols = true; } var assemblyDef = AssemblyDefinition.ReadAssembly(assemblyPath, readerParameters); assemblies.Add(assemblyPath, assemblyDef); return(assemblyDef); }
private ReaderParameters GetReaderParameters() { DefaultAssemblyResolver assemblyResolver = new DefaultAssemblyResolver(); string assemblyLocation = Path.GetDirectoryName(_assemblyLocation); assemblyResolver.AddSearchDirectory(assemblyLocation); ReaderParameters readerParameters = new ReaderParameters { AssemblyResolver = assemblyResolver, #if DEBUG InMemory = true, #endif ReadingMode = ReadingMode.Immediate }; if (!File.Exists(PdbName)) { return(readerParameters); } PdbReaderProvider symbolReaderProvider = new PdbReaderProvider(); readerParameters.SymbolReaderProvider = symbolReaderProvider; return(readerParameters); }
private AssemblyDefinition LoadAssembly() { try { var assemblyResolver = new DefaultAssemblyResolver(); assemblyResolver.AddSearchDirectory(Path.GetDirectoryName(assemblyPath)); var symbolReaderProvider = new PdbReaderProvider(); logger.Progress($"Loading assembly: '{assemblyPath}'"); var readerParameters = new ReaderParameters(ReadingMode.Immediate) { ReadSymbols = true, AssemblyResolver = assemblyResolver, SymbolReaderProvider = symbolReaderProvider }; var assembly = AssemblyDefinition.ReadAssembly(assemblyPath, readerParameters); logger.Progress("Loading assembly done"); return(assembly); } catch (Exception e) { throw new InvalidOperationException($"Error while loading assembly '{assemblyPath}'.", e); } }
private ReaderParameters CreateDefaultReaderParameters(IEnumerable <string> searchDirectories, string pdbPath = null) { var assemblyResolver = new DefaultAssemblyResolver(); foreach (var searchDirectory in searchDirectories) { if (!string.IsNullOrEmpty(searchDirectory)) { assemblyResolver.AddSearchDirectory(searchDirectory); } } var readerParameters = new ReaderParameters { AssemblyResolver = assemblyResolver }; if (!string.IsNullOrEmpty(pdbPath)) { var pdbReaderProvider = new PdbReaderProvider(); readerParameters.SymbolReaderProvider = pdbReaderProvider; readerParameters.ReadSymbols = true; } return(readerParameters); }
//stripped down version of: https://github.com/Keboo/AutoDI/blob/master/AutoDI.Build/AssemblyRewriteTask.cs private static Stream GetSymbolInformation(string assemblyFile, out ISymbolReaderProvider symbolReaderProvider, out ISymbolWriterProvider symbolWriterProvider) { string pdbPath = FindPdbPath(); if (pdbPath != null) { symbolReaderProvider = new PdbReaderProvider(); symbolWriterProvider = new PdbWriterProvider(); string tempPath = pdbPath + ".tmp"; File.Copy(pdbPath, tempPath, true); return(new FileStream(tempPath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)); } symbolReaderProvider = null; symbolWriterProvider = null; return(null); string FindPdbPath() { string path = Path.ChangeExtension(assemblyFile, "pdb"); if (File.Exists(path)) { return(path); } return(null); } }
private ISymbolReader ResolveSymbolReader() { string symbolLocation = null; string pdbLocation = Path.ChangeExtension(AssemblyLocation, "pdb"); string mdbLocation = AssemblyLocation + ".mdb"; ISymbolReaderProvider provider = null; if (File.Exists(pdbLocation)) { symbolLocation = pdbLocation; provider = new PdbReaderProvider(); } else if (File.Exists(mdbLocation)) { symbolLocation = AssemblyLocation; provider = new MdbReaderProvider(); } if (provider == null) { return(null); } var reader = provider.GetSymbolReader(Definition, symbolLocation); return(reader); }
internal static void Init() { #pragma warning disable 168 // the only purpose of this instruction is to create a reference to Mono.Cecil.Pdb. // Otherwise Visual Studio won't copy that assembly to the output path. var readerProvider = new PdbReaderProvider(); #pragma warning restore 168 }
static ModuleDefinition RoundtripModule(ModuleDefinition module, RoundtripType roundtripType) { if (roundtripType == RoundtripType.None) { return(module); } var file = Path.Combine(Path.GetTempPath(), "TestILProcessor.dll"); if (File.Exists(file)) { File.Delete(file); } ISymbolWriterProvider symbolWriterProvider; switch (roundtripType) { case RoundtripType.Pdb when Platform.HasNativePdbSupport: symbolWriterProvider = new PdbWriterProvider(); break; case RoundtripType.PortablePdb: default: symbolWriterProvider = new PortablePdbWriterProvider(); break; } module.Write(file, new WriterParameters { SymbolWriterProvider = symbolWriterProvider, }); module.Dispose(); ISymbolReaderProvider symbolReaderProvider; switch (roundtripType) { case RoundtripType.Pdb when Platform.HasNativePdbSupport: symbolReaderProvider = new PdbReaderProvider(); break; case RoundtripType.PortablePdb: default: symbolReaderProvider = new PortablePdbReaderProvider(); break; } return(ModuleDefinition.ReadModule(file, new ReaderParameters { SymbolReaderProvider = symbolReaderProvider, InMemory = true })); }
public ILAssembly(Stack <ILAssembly> allAssemblies, string binaryPath, bool loadReferences, DefaultAssemblyResolver assemblyResolver) { allAssemblies.Push(this); // check if core lib string libName = Path.GetFileNameWithoutExtension(binaryPath); isCoreLib = libName == "mscorlib" || //libName == "System.Runtime" || libName == "System.Private.CoreLib" || libName == "netstandard" || (TypeSystem.CustomCoreLibName != null && libName == TypeSystem.CustomCoreLibName); // create reader parameters desc var readerParameters = new ReaderParameters(); readerParameters.AssemblyResolver = assemblyResolver; // check if debug symbol file is avaliable var pdbReaderProvider = new PdbReaderProvider(); string symbolsPath = Path.Combine(Path.GetDirectoryName(binaryPath), Path.GetFileNameWithoutExtension(binaryPath) + ".pdb"); if (File.Exists(symbolsPath)) { readerParameters.SymbolReaderProvider = pdbReaderProvider; readerParameters.ReadSymbols = true; } // read assembly file assemblyDefinition = AssemblyDefinition.ReadAssembly(binaryPath, readerParameters); // load assembly modules modules = new Stack <ILModule>(); foreach (var moduleDef in assemblyDefinition.Modules) { // read debug symbols for module ISymbolReader symbolReader = null; if (readerParameters.ReadSymbols) { symbolReader = pdbReaderProvider.GetSymbolReader(moduleDef, symbolsPath); } // add module var module = new ILModule(allAssemblies, this, loadReferences, moduleDef, symbolReader, assemblyResolver); modules.Push(module); } }
/// <summary> /// /// </summary> /// <param name="assemblyPath"></param> /// <param name="currentPath"></param> /// <param name="savePath"></param> /// <returns></returns> public static bool BuildToFile(string assemblyPath, string currentPath, string savePath = null) { bool setSuccess = false; if (string.IsNullOrEmpty(savePath)) { savePath = assemblyPath; } string pdbFile = Path.ChangeExtension(assemblyPath, "pdb"); PdbReaderProvider readerProvider = null; PdbWriterProvider writerProvider = null; bool debug = false; if (File.Exists(pdbFile)) { debug = true; readerProvider = new PdbReaderProvider(); writerProvider = new PdbWriterProvider(); } //huhu modify reason: Support for model debugging. var ass = AssemblyDefinition.ReadAssembly(assemblyPath, new ReaderParameters { SymbolReaderProvider = readerProvider, ReadSymbols = debug }); BaseAssemblyResolver resolver = ass.MainModule.AssemblyResolver as BaseAssemblyResolver; if (resolver != null) { resolver.AddSearchDirectory(currentPath); } foreach (TypeDefinition type in ass.MainModule.GetTypes()) { if (type.IsEnum) { continue; } setSuccess = ProcessEntityType(type, setSuccess, currentPath); } //modify reason: no model. ass.Write(savePath, new WriterParameters { SymbolWriterProvider = writerProvider, WriteSymbols = debug }); return(true); }
/// <summary> /// /// </summary> /// <param name="assemblyPath"></param> /// <param name="outputAssembly"></param> /// <returns></returns> public static bool BuildToStream(string assemblyPath, out Stream outputAssembly) { bool setSuccess = false; string currentPath = Path.GetDirectoryName(assemblyPath); outputAssembly = new MemoryStream(); using (Stream stream = ReadAssembly(assemblyPath)) { string pdbFile = Path.ChangeExtension(assemblyPath, "pdb"); PdbReaderProvider readerProvider = null; PdbWriterProvider writerProvider = null; bool debug = false; if (File.Exists(pdbFile)) { debug = true; readerProvider = new PdbReaderProvider(); writerProvider = new PdbWriterProvider(); } var ass = AssemblyDefinition.ReadAssembly(stream, new ReaderParameters { SymbolReaderProvider = readerProvider, ReadSymbols = debug }); foreach (TypeDefinition type in ass.MainModule.GetTypes()) { if (type.IsEnum) { continue; } setSuccess = ProcessEntityType(type, setSuccess, currentPath); } if (setSuccess) { ass.Write(outputAssembly, new WriterParameters { SymbolWriterProvider = writerProvider, WriteSymbols = debug }); return(true); } } return(false); }
public void LoadPdbOnDemand() { var assembly = File.ReadAllBytes(GetAssemblyResourcePath("Microsoft.AspNetCore.Components.dll")); var pdb = File.ReadAllBytes(GetAssemblyResourcePath("Microsoft.AspNetCore.Components.pdb")); var module = ModuleDefinition.ReadModule(new MemoryStream(assembly), new ReaderParameters(ReadingMode.Immediate)); var type = module.GetType("Microsoft.AspNetCore.Components.Rendering.ComponentState"); var main = type.GetMethod("RenderIntoBatch"); var debug_info = main.DebugInformation; var pdbReaderProvider = new PdbReaderProvider(); var symbolReader = pdbReaderProvider.GetSymbolReader(module, new MemoryStream(pdb)); module.ReadSymbols(symbolReader); type = module.GetType("Microsoft.AspNetCore.Components.Rendering.ComponentState"); main = type.GetMethod("RenderIntoBatch"); debug_info = main.DebugInformation; Assert.AreEqual(9, debug_info.SequencePoints.Count); }
/// <summary> /// Patches the specified input PDB file. /// </summary> /// <param name="inputExeFile">The input PDB file.</param> /// <param name="outputPdbFile">The output PDB file.</param> /// <param name="sourcePathRewriter">The source path modifier.</param> /// <exception cref="System.ArgumentNullException">inputExeFile</exception> public static void Patch(string inputExeFile, string outputPdbFile, SourcePathRewriterDelegate sourcePathRewriter) { if (inputExeFile == null) { throw new ArgumentNullException("inputExeFile"); } if (outputPdbFile == null) { throw new ArgumentNullException("outputPdbFile"); } if (sourcePathRewriter == null) { throw new ArgumentNullException("sourcePathRewriter"); } // Copy PDB from input assembly to output assembly if any var inputPdbFile = Path.ChangeExtension(inputExeFile, "pdb"); if (!File.Exists(inputPdbFile)) { ShowMessage(string.Format("Warning file [{0}] does not exist", inputPdbFile), ConsoleColor.Yellow); return; } var symbolReaderProvider = new PdbReaderProvider(); var readerParameters = new ReaderParameters { SymbolReaderProvider = symbolReaderProvider, ReadSymbols = true }; // Read Assembly var assembly = AssemblyDefinition.ReadAssembly(inputExeFile, readerParameters); // Write back the assembly and pdb assembly.Write(inputExeFile, new WriterParameters { WriteSymbols = true, SourcePathRewriter = sourcePathRewriter }); }
/// <summary> /// /// </summary> /// <param name="assemblyPath"></param> /// <param name="currentPath"></param> /// <param name="savePath"></param> /// <returns></returns> public static bool BuildToFile(string assemblyPath, string currentPath, string savePath = null) { bool setSuccess = false; if (string.IsNullOrEmpty(savePath)) { savePath = assemblyPath; } string pdbFile = Path.ChangeExtension(assemblyPath, "pdb"); PdbReaderProvider readerProvider = null; PdbWriterProvider writerProvider = null; bool debug = false; if (File.Exists(pdbFile)) { debug = true; readerProvider = new PdbReaderProvider(); writerProvider = new PdbWriterProvider(); } //huhu modify reason: Support for model debugging. var ass = AssemblyDefinition.ReadAssembly(assemblyPath, new ReaderParameters { SymbolReaderProvider = readerProvider, ReadSymbols = debug }); var types = ass.MainModule.Types.Where(p => !p.IsEnum).ToList(); foreach (TypeDefinition type in types) { setSuccess = ProcessEntityType(type, setSuccess, currentPath); } //modify reason: no model. ass.Write(savePath, new WriterParameters { SymbolWriterProvider = writerProvider, WriteSymbols = debug }); return(true); }
/// <summary> /// Patches the file. /// </summary> /// <param name="file">The file.</param> public bool PatchFile(string file) { var fileTime = new FileTime(file); //var fileTimeInteropBuilder = new FileTime(Assembly.GetExecutingAssembly().Location); string checkFile = Path.GetFullPath(file) + ".check"; //string checkInteropBuilderFile = "InteropBuild.check"; // If checkFile and checkInteropBuilderFile up-to-date, then nothing to do if (fileTime.CheckFileUpToDate(checkFile)) { Log("Nothing to do. SharpDX patch was already applied for assembly [{0}]", file); return(false); } // Copy PDB from input assembly to output assembly if any var readerParameters = new ReaderParameters(); var writerParameters = new WriterParameters(); var pdbName = Path.ChangeExtension(file, "pdb"); if (File.Exists(pdbName)) { var symbolReaderProvider = new PdbReaderProvider(); readerParameters.SymbolReaderProvider = symbolReaderProvider; readerParameters.ReadSymbols = true; writerParameters.WriteSymbols = true; } // Read Assembly assembly = AssemblyDefinition.ReadAssembly(file, readerParameters); ((BaseAssemblyResolver)assembly.MainModule.AssemblyResolver).AddSearchDirectory(Path.GetDirectoryName(file)); foreach (var assemblyNameReference in assembly.MainModule.AssemblyReferences) { if (assemblyNameReference.Name.ToLower() == "mscorlib") { mscorlibAssembly = assembly.MainModule.AssemblyResolver.Resolve(assemblyNameReference); break; } } // TODO: Temporary patch to handle correctly 4.5 Core profile if (mscorlibAssembly == null) { foreach (var assemblyNameReference in assembly.MainModule.AssemblyReferences) { if (assemblyNameReference.Name == "System.Runtime") { ((BaseAssemblyResolver)assembly.MainModule.AssemblyResolver).AddSearchDirectory(Path.Combine(ProgramFilesx86(), @"Reference Assemblies\Microsoft\Framework\.NETCore\v4.5")); mscorlibAssembly = assembly.MainModule.AssemblyResolver.Resolve(assemblyNameReference); break; } } } if (mscorlibAssembly == null) { LogError("Missing mscorlib.dll from assembly {0}", file); throw new InvalidOperationException("Missing mscorlib.dll from assembly"); } // Import void* and int32 from assembly using mscorlib specific version (2.0 or 4.0 depending on assembly) voidType = mscorlibAssembly.MainModule.GetType("System.Void"); voidPointerType = new PointerType(assembly.MainModule.Import(voidType)); intType = assembly.MainModule.Import(mscorlibAssembly.MainModule.GetType("System.Int32")); // Remove CompilationRelaxationsAttribute for (int i = 0; i < assembly.CustomAttributes.Count; i++) { var customAttribute = assembly.CustomAttributes[i]; if (customAttribute.AttributeType.FullName == typeof(CompilationRelaxationsAttribute).FullName) { assembly.CustomAttributes.RemoveAt(i); i--; } } Log("SharpDX interop patch for assembly [{0}]", file); foreach (var type in assembly.MainModule.Types) { PatchType(type); } // Remove All Interop classes foreach (var type in classToRemoveList) { assembly.MainModule.Types.Remove(type); } var outputFilePath = file; assembly.Write(outputFilePath, writerParameters); fileTime = new FileTime(file); // Update Check file fileTime.UpdateCheckFile(checkFile); //fileTimeInteropBuilder.UpdateCheckFile(checkInteropBuilderFile); Log("SharpDX patch done for assembly [{0}]", file); return(true); }
public static void MethodInstrument(string targetAssembly, string src, string dst) { var inputAssembly = targetAssembly; var path = Path.GetDirectoryName(inputAssembly); var assemblyResolver = new DefaultAssemblyResolver(); var assemblyLocation = Path.GetDirectoryName(inputAssembly); assemblyResolver.AddSearchDirectory(assemblyLocation); var readerParameters = new ReaderParameters { AssemblyResolver = assemblyResolver }; var writerParameters = new WriterParameters(); var origPdb = Path.ChangeExtension(inputAssembly, "pdb"); bool existpdb = false; if (File.Exists(origPdb)) { existpdb = true; var symbolReaderProvider = new PdbReaderProvider(); readerParameters.SymbolReaderProvider = symbolReaderProvider; readerParameters.ReadSymbols = true; //var symbolWriterProvider = new PdbWriterProvider(); //writerParameters.SymbolWriterProvider = symbolWriterProvider; writerParameters.WriteSymbols = true; } else { Console.WriteLine(".pdb file is unavailable."); } var assemblyDefinition = AssemblyDefinition.ReadAssembly(inputAssembly, readerParameters); var module = assemblyDefinition.MainModule; //Mono.Collections.Generic.Collection<ModuleDefinition> modules = assemblyDefinition.Modules; //var module2 = ModuleDefinition.ReadModule(inputAssembly, readerParameters); //---------------------- bool isChanged = false; //---------------------------- foreach (var typeDefinition in module.Types) { if (typeDefinition.IsInterface) { continue; } foreach (var methodDefinition in typeDefinition.Methods) { ILProcessor ilprocessor = methodDefinition.Body.GetILProcessor(); Mono.Collections.Generic.Collection <Mono.Cecil.Cil.Instruction> allinstructions = methodDefinition.Body.Instructions; int instructioncnt = allinstructions.Count; for (int i = 0; i < instructioncnt; i++) { Mono.Cecil.Cil.Instruction instruction = allinstructions[i]; string instructpresent = instruction.ToString(); OpCode code = instruction.OpCode; string codepresent = code.Name; var operand = instruction.Operand; string methodname = ""; if (operand != null) { methodname = operand.ToString(); //with parameter } if ((code == OpCodes.Callvirt || code == OpCodes.Call) && //codepresent.Contains("call") (isSameMethod(methodname, src))) //or (operand as MethodReference == module.Import(src as MethodInfo)) { Console.WriteLine(codepresent + " " + methodname); //debug //---------------------- remove --------------------------// /**** remove instruction in case of no replacing method is provided ****/ //TODO: 1. I note the stack depth after the call and start removing instructions, beginning with the Code.Call // and moving backward until I get to that stack depth again. // 2. return value handling ilprocessor.Remove(instruction); instructioncnt--; if (allinstructions[i].OpCode == OpCodes.Pop) //TODO: just for test { ilprocessor.Remove(allinstructions[i]); instructioncnt--; } i--; if (dst == "") { continue; } //---------------------- replace (remove + insert) ------------------------// /**** create new MethodInfo ****/ string m_type = getNamespace(dst); string m_name = getMethodName(dst); string [] m_para = getParameters(dst); MethodInfo writeLineMethod; //e.g. MethodInfo writeLineMethod = typeof(Console).GetMethod("WriteLine", new Type[] { typeof(string) }); if (m_para != null) { int paraCnt = m_para.Length; Type[] m_para_type = new Type[paraCnt]; for (int k = 0; k < paraCnt; k++) { m_para_type[k] = Type.GetType(m_para[k]); } writeLineMethod = Type.GetType(m_type).GetMethod(m_name, m_para_type); } else //the method does not have input parameters { writeLineMethod = Type.GetType(m_type).GetMethod(m_name, new Type[] { }); } if (writeLineMethod == null) { throw new InvalidFileFormatException("no MethodInfo is created -- possibly a wrong method delaration."); } /*** Import the new (e.g. Console.WriteLine() method) ***/ MethodReference writeLine; writeLine = module.Import(writeLineMethod); //convert "MethodInfo/MethodDefinition" to "MethodReference" /*** Creates the CIL instruction for calling the new method (e.g. Console.WriteLine(string value) method) ***/ Mono.Cecil.Cil.Instruction callWriteLine; callWriteLine = ilprocessor.Create(OpCodes.Call, writeLine); /*** replace old instruction ***/ //TODO: 1. for simple-type parameters, create one instance and push to stack; // otherwise just a null object?!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! // 2. return value handling ilprocessor.InsertAfter(allinstructions[i], callWriteLine); //----------------------------------------------// isChanged = true; } } //foreach instruction of a method } //foreach method of a type/class } //foreach type/class of loaded assembly if (isChanged) { var temporaryFileName = Path.Combine(path, string.Format("{0}_temp{1}", Path.GetFileNameWithoutExtension(inputAssembly), Path.GetExtension(inputAssembly))); var backupFileName = Path.Combine(path, string.Format("{0}_orig{1}", Path.GetFileNameWithoutExtension(inputAssembly), Path.GetExtension(inputAssembly))); var tmpPdb = Path.Combine(path, string.Format("{0}_temp{1}", Path.GetFileNameWithoutExtension(inputAssembly), ".pdb")); var backupPdb = Path.Combine(path, string.Format("{0}_orig{1}", Path.GetFileNameWithoutExtension(inputAssembly), ".pdb")); //write an assembly with symbol file being rewritten //module.Write(temporaryFileName, writerParameters); assemblyDefinition.Write(temporaryFileName, writerParameters); File.Replace(temporaryFileName, inputAssembly, backupFileName); if (existpdb) { File.Replace(tmpPdb, origPdb, backupPdb); } //TODO: add snkfile in configuration file and parse ([email protected]) // If you have access to the key pair, you can ask Cecil to sign it directly. //if (snkFile != "") //{ //sn -R inputAssembly snkFile //} } }
/// <summary> /// Patches the file. /// </summary> /// <param name="file">The file.</param> public bool PatchFile(string file) { file = Path.Combine(Environment.CurrentDirectory, file); var fileTime = new FileTime(file); //var fileTimeInteropBuilder = new FileTime(Assembly.GetExecutingAssembly().Location); string checkFile = Path.GetFullPath(file) + ".check"; //string checkInteropBuilderFile = "InteropBuild.check"; // If checkFile and checkInteropBuilderFile up-to-date, then nothing to do if (fileTime.CheckFileUpToDate(checkFile)) { Log("Nothing to do. SharpDX patch was already applied for assembly [{0}]", file); return(false); } // Copy PDB from input assembly to output assembly if any var readerParameters = new ReaderParameters(); var resolver = new DefaultAssemblyResolver(); readerParameters.AssemblyResolver = resolver; var writerParameters = new WriterParameters(); var pdbName = Path.ChangeExtension(file, "pdb"); if (File.Exists(pdbName)) { var symbolReaderProvider = new PdbReaderProvider(); readerParameters.SymbolReaderProvider = symbolReaderProvider; readerParameters.ReadSymbols = true; writerParameters.WriteSymbols = true; } // Read Assembly assembly = AssemblyDefinition.ReadAssembly(file, readerParameters); resolver.AddSearchDirectory(Path.GetDirectoryName(file)); // Query the target framework in order to resolve correct assemblies and type forwarding var targetFrameworkAttr = assembly.CustomAttributes.FirstOrDefault( attribute => attribute.Constructor.FullName.Contains("System.Runtime.Versioning.TargetFrameworkAttribute")); if (targetFrameworkAttr != null && targetFrameworkAttr.ConstructorArguments.Count > 0 && targetFrameworkAttr.ConstructorArguments[0].Value != null) { var targetFramework = new FrameworkName(targetFrameworkAttr.ConstructorArguments[0].Value.ToString()); var netcoreAssemblyPath = string.Format(@"Reference Assemblies\Microsoft\Framework\{0}\v{1}", targetFramework.Identifier, targetFramework.Version); netcoreAssemblyPath = Path.Combine(ProgramFilesx86(), netcoreAssemblyPath); if (Directory.Exists(netcoreAssemblyPath)) { resolver.AddSearchDirectory(netcoreAssemblyPath); } } // Import void* and int32 voidType = assembly.MainModule.TypeSystem.Void.Resolve(); voidPointerType = new PointerType(assembly.MainModule.Import(voidType)); intType = assembly.MainModule.Import(assembly.MainModule.TypeSystem.Int32.Resolve()); // Remove CompilationRelaxationsAttribute for (int i = 0; i < assembly.CustomAttributes.Count; i++) { var customAttribute = assembly.CustomAttributes[i]; if (customAttribute.AttributeType.FullName == typeof(CompilationRelaxationsAttribute).FullName) { assembly.CustomAttributes.RemoveAt(i); i--; } } Log("SharpDX interop patch for assembly [{0}]", file); foreach (var type in assembly.MainModule.Types) { PatchType(type); } // Remove All Interop classes foreach (var type in classToRemoveList) { assembly.MainModule.Types.Remove(type); } var outputFilePath = file; assembly.Write(outputFilePath, writerParameters); fileTime = new FileTime(file); // Update Check file fileTime.UpdateCheckFile(checkFile); //fileTimeInteropBuilder.UpdateCheckFile(checkInteropBuilderFile); Log("SharpDX patch done for assembly [{0}]", file); return(true); }
async Task <MethodInfo> LoadSymbolsOnDemand(AssemblyInfo asm, uint method_token, SessionId sessionId, CancellationToken token) { var context = GetContext(sessionId); if (asm.TriedToLoadSymbolsOnDemand) { return(null); } asm.TriedToLoadSymbolsOnDemand = true; ImageDebugHeader header = asm.Image.GetDebugHeader(); for (var i = 0; i < header.Entries.Length; i++) { var entry = header.Entries[i]; if (entry.Directory.Type != ImageDebugType.CodeView) { continue; } var data = entry.Data; if (data.Length < 24) { return(null); } var pdbSignature = (data[0] | (data[1] << 8) | (data[2] << 16) | (data[3] << 24)); if (pdbSignature != 0x53445352) // "SDSR" mono/metadata/debug-mono-ppdb.c#L101 { return(null); } var buffer = new byte[16]; Buffer.BlockCopy(data, 4, buffer, 0, 16); var pdbAge = (data[20] | (data[21] << 8) | (data[22] << 16) | (data[23] << 24)); var pdbGuid = new Guid(buffer); var buffer2 = new byte[(data.Length - 24) - 1]; Buffer.BlockCopy(data, 24, buffer2, 0, (data.Length - 24) - 1); var pdbName = System.Text.Encoding.UTF8.GetString(buffer2, 0, buffer2.Length); pdbName = Path.GetFileName(pdbName); foreach (var urlSymbolServer in urlSymbolServerList) { var downloadURL = $"{urlSymbolServer}/{pdbName}/{pdbGuid.ToString("N").ToUpper() + pdbAge}/{pdbName}"; try { using HttpResponseMessage response = await client.GetAsync(downloadURL); using Stream streamToReadFrom = await response.Content.ReadAsStreamAsync(); var portablePdbReaderProvider = new PdbReaderProvider(); var symbolReader = portablePdbReaderProvider.GetSymbolReader(asm.Image, streamToReadFrom); asm.ClearDebugInfo(); //workaround while cecil PR #686 is not merged asm.Image.ReadSymbols(symbolReader); asm.Populate(); foreach (var source in asm.Sources) { var scriptSource = JObject.FromObject(source.ToScriptSource(context.Id, context.AuxData)); SendEvent(sessionId, "Debugger.scriptParsed", scriptSource, token); } return(asm.GetMethodByToken(method_token)); } catch (Exception e) { Log("info", $"Unable to load symbols on demand exception: {e.ToString()} url:{downloadURL} assembly: {asm.Name}"); } } break; } Log("info", "Unable to load symbols on demand assembly: {asm.Name}"); return(null); }
public bool ProcessFile(string sourceFile, string targetFile = "") { bool result = false; if (string.IsNullOrEmpty(targetFile)) { targetFile = sourceFile; } Stopwatch stopwatch = new Stopwatch(); stopwatch.Start(); try { var resolver = new DefaultAssemblyResolver(); resolver.AddSearchDirectory(GetAssemblyDirectoryFromType(typeof(Resource))); var parameters = new ReaderParameters { AssemblyResolver = resolver }; Assembly = AssemblyDefinition.ReadAssembly(sourceFile, parameters); Log.LogMessage("------ Begin Task: ImplementRdfMapping [{0}]", Assembly.Name); bool assemblyModified = false; // Iterate over all types in the main assembly. foreach (TypeDefinition type in Assembly.MainModule.Types) { // In the following we need to seperate between properties which have the following attribute combinations: // - PropertyAttribute with PropertyChangedAttribute // - PropertyAttribute without PropertyChangedAttribute // - PropertyChangedAttribute only HashSet <PropertyDefinition> mapping = type.GetPropertiesWithAttribute <RdfPropertyAttribute>().ToHashSet(); HashSet <PropertyDefinition> notifying = type.GetPropertiesWithAttribute <NotifyPropertyChangedAttribute>().ToHashSet(); // Implement the GetTypes()-method for the given type. if (mapping.Any() || type.TryGetCustomAttribute <RdfClassAttribute>().Any()) { ImplementRdfClassTask implementClass = new ImplementRdfClassTask(this, type); // RDF types _must_ be implemented for classes with mapped properties. assemblyModified = implementClass.Execute(); } // Properties which do not raise the PropertyChanged-event can be implemented using minimal IL code. if (mapping.Any()) { var implementProperty = new ImplementRdfPropertyTask(this, type); foreach (PropertyDefinition p in mapping.Except(notifying).Where(implementProperty.CanExecute)) { assemblyModified = implementProperty.Execute(p); } } // Properties which raise the PropertyChanged-event may also have the RdfProperty attribute. if (notifying.Any()) { var implementPropertyChanged = new ImplementNotifyPropertyChangedTask(this, type); foreach (PropertyDefinition p in notifying.Where(implementPropertyChanged.CanExecute)) { implementPropertyChanged.IsMappedProperty = mapping.Contains(p); assemblyModified = implementPropertyChanged.Execute(p); } } } if (assemblyModified) { if (WriteSymbols) { // Use the correct debug symbol reader and writer on Mono and .NET if (Type.GetType("Mono.Runtime") != null) { using (ISymbolReader symbolReader = new MdbReaderProvider().GetSymbolReader(Assembly.MainModule, sourceFile)) { ISymbolWriterProvider symbolWriter = new MdbWriterProvider(); WriteSymbolsToAssembly(targetFile, symbolReader, symbolWriter); } } else { using (ISymbolReader symbolReader = new PdbReaderProvider().GetSymbolReader(Assembly.MainModule, sourceFile)) { ISymbolWriterProvider symbolWriter = new PdbWriterProvider(); WriteSymbolsToAssembly(targetFile, symbolReader, symbolWriter); } } } else { Assembly.Write(targetFile, new WriterParameters { WriteSymbols = false }); } } result = true; } catch (Exception ex) { Log.LogError(ex.ToString()); result = false; } stopwatch.Stop(); Log.LogMessage("------ End Task: ImplementRdfMapping [Total time: {0}s]", stopwatch.Elapsed.TotalSeconds); return(result); }
private static int Main(string[] args) { Console.WriteLine("---------------------- CrossSL V1.0 ----------------------"); if (args.Length == 0 || String.IsNullOrEmpty(args[0])) { DebugLog.UsageError("Start CrossSL with a .NET assemly as argument to translate\n" + "shaders from .NET to GLSL, e.g. 'CrossSL.exe Assembly.exe'"); return(-1); } string inputPath = args[0]; var asmName = Path.GetFileName(inputPath); var asmDir = Path.GetDirectoryName(inputPath); if (!File.Exists(inputPath)) { DebugLog.UsageError("Could not find assembly '" + asmName + "' in path:\n\n" + asmDir); return(-1); } // ReSharper disable once AssignNullToNotNullAttribute var metaPath = Path.Combine(asmDir, "CrossSL.Meta.dll"); if (!File.Exists(inputPath) || !File.Exists(metaPath)) { DebugLog.UsageError("Found assembly '" + asmName + "' but meta assembly 'CrossSL.Meta.dll'" + "\nis missing. It needs to be in the same directory:\n\n" + asmDir); return(-1); } Console.WriteLine("\n\nFound assembly '" + asmName + "' and meta assembly 'CrossSL.Meta.dll'."); // check if there is a .pdb file along with the .exe var debugFile = Path.ChangeExtension(inputPath, "pdb"); var debugName = Path.GetFileName(debugFile); DebugLog.Verbose = File.Exists(debugFile); Console.WriteLine(DebugLog.Verbose ? "Found also .pdb file '" + debugName + "'. This allows for better debugging." : "Found no .pdb file '" + debugName + "'. Extended debugging has been disabled."); // read assembly (and symbols) with Mono.Cecil var resolver = new DefaultAssemblyResolver(); resolver.AddSearchDirectory(asmDir); var readParams = new ReaderParameters { ReadSymbols = DebugLog.Verbose, AssemblyResolver = resolver }; var asm = AssemblyDefinition.ReadAssembly(inputPath, readParams); // read meta assembly (without symbols) with Mono.Cecil var metaParams = new ReaderParameters { ReadSymbols = false }; var metaAsm = AssemblyDefinition.ReadAssembly(metaPath, metaParams); // find all types with xSLShader as base type var shaderDescs = new List <ShaderDesc>(); var asmTypes = asm.Modules.SelectMany( asmMod => asmMod.Types.Where(asmType => asmType.BaseType != null)); var asmShaderTypes = asmTypes.Where(asmType => asmType.BaseType.IsType <xSLShader>()); foreach (var asmType in asmShaderTypes) { DebugLog.Reset(); if (DebugLog.Verbose) { // load symbols from pdb file var asmModule = asmType.Module; using (var symbReader = new PdbReaderProvider().GetSymbolReader(asmModule, debugFile)) asmModule.ReadSymbols(symbReader); } var asmTypeName = asmType.Name; Console.WriteLine("\n\nFound a shader called '" + asmTypeName + "':"); var shaderDesc = new ShaderDesc { Name = asmTypeName, Type = asmType }; // check for [xSLDebug] first in case the shader should be ignored var debugAttr = asmType.CustomAttributes.FirstOrDefault( attrType => attrType.AttributeType.IsType <xSLShader.xSLDebugAttribute>()); if (debugAttr != null) { shaderDesc.DebugFlags = (xSLShader.xSLDebug)debugAttr.ConstructorArguments[0].Value; if ((shaderDesc.DebugFlags & xSLShader.xSLDebug.IgnoreShader) != 0) { Console.WriteLine(" => Found [xSLDebug] with 'IgnoreShader' flag. Shader skipped."); continue; } } // check for [xSLTarget] and save settings var targetAttr = asmType.CustomAttributes.FirstOrDefault( attr => attr.AttributeType.IsType <xSLShader.xSLTargetAttribute>()); if (targetAttr == null) { shaderDesc.Target = new ShaderTarget { Envr = SLEnvironment.OpenGL, Version = 110, VersionID = 0 }; DebugLog.Error("Could not find [xSLTarget]. Please specify the targeted shading language"); } else { var typeName = targetAttr.ConstructorArguments[0].Type.Name; var versionID = (int)targetAttr.ConstructorArguments[0].Value; var shaderTarget = new ShaderTarget { VersionID = versionID }; switch (typeName) { case "GLSL": shaderTarget.Envr = SLEnvironment.OpenGL; break; case "GLSLES": shaderTarget.Envr = SLEnvironment.OpenGLES; break; case "GLSLMix": shaderTarget.Envr = SLEnvironment.OpenGLMix; break; } var vStr = SLVersion.VIDs[(int)shaderTarget.Envr][versionID]; shaderTarget.Version = Int32.Parse(vStr); shaderDesc.Target = shaderTarget; if (shaderTarget.Envr == SLEnvironment.OpenGLMix) { typeName = "GLSL 1.10 & GLSLES"; vStr = "100"; } vStr = vStr.Insert(1, "."); Console.WriteLine(" => Found [xSLTarget]. Compiling shader as " + typeName + " " + vStr + "."); } var shaderTranslator = ShaderTranslator.GetTranslator(shaderDesc.Target); shaderTranslator.ShaderDesc = shaderDesc; // save debug settings if (debugAttr == null) { shaderDesc.DebugFlags = xSLShader.xSLDebug.None; Console.WriteLine(" => Could not find [xSLDebug]. Debugging has been disabled."); DebugLog.Disabled = true; } else { if ((shaderDesc.DebugFlags & xSLShader.xSLDebug.None) != 0) { Console.WriteLine(" => Found [xSLDebug] with 'None' flag. Debugging has been disabled."); } else { Console.WriteLine(" => Found [xSLDebug]. Debugging with flags: " + shaderDesc.DebugFlags); } } // check for common mistakes Console.WriteLine("\n 1. Checking shader for obvious mistakes."); // check if vertex or fragment method is missing MethodDefinition vertexMain; if (!MethodExists(asmType, "VertexShader", out vertexMain)) { continue; } MethodDefinition fragmentMain; if (!MethodExists(asmType, "FragmentShader", out fragmentMain)) { continue; } // get their precission attributes var vertPrecAttr = vertexMain.CustomAttributes.FirstOrDefault( attrType => attrType.AttributeType.IsType <xSLShader.xSLPrecisionAttribute>()); var fragPrecAttr = fragmentMain.CustomAttributes.FirstOrDefault( attrType => attrType.AttributeType.IsType <xSLShader.xSLPrecisionAttribute>()); shaderDesc.Precision = new CustomAttribute[2]; shaderDesc.Precision[(int)SLShaderType.VertexShader] = vertPrecAttr; shaderDesc.Precision[(int)SLShaderType.FragmentShader] = fragPrecAttr; // get default file for this shader in case no instructions are available var defaultSeq = vertexMain.Body.Instructions[0].SequencePoint; DebugLog.DefaultFile = defaultSeq != null?Path.GetFileName(defaultSeq.Document.Url) : asmTypeName; // check if there are additional constructors for field/property initialization var ctorMethods = asmType.Methods.Where(asmMethod => asmMethod.IsConstructor); var customCtors = new Collection <MethodDefinition>(); foreach (var ctorMethod in ctorMethods.Where(ctor => ctor.Body.CodeSize > 7)) { // see if there are field initializations (as for "constants") var varInits = ctorMethod.Body.Instructions.Any(instr => instr.OpCode == OpCodes.Stfld); // or property setter calls (as for "constants") var funcCalls = ctorMethod.Body.Instructions.Where(instr => instr.OpCode == OpCodes.Call); var propInits = funcCalls.Any(instr => ((MethodReference)instr.Operand).Resolve().IsSetter); if (varInits || propInits) { customCtors.Add(ctorMethod); } else { var instr = ctorMethod.Body.Instructions[0]; DebugLog.Warning("Found a constructor with no valid content", instr); } } // analyze variables used in shader Console.WriteLine("\n 2. Collecting information about fields and properties."); var variables = new Collection <VariableDesc>(); var varTypes = Enum.GetNames(typeof(SLVariableType)); // read and gather fields and backing fields foreach (var asmField in asmType.Fields) { var varDesc = new VariableDesc { Definition = asmField }; var fdName = asmField.Name; var fdType = asmField.FieldType.ToType(); var fdArray = asmField.FieldType.IsArray; var attrs = asmField.CustomAttributes; var isProp = fdName.Contains("<"); if (isProp) { // ReSharper disable once StringIndexOfIsCultureSpecific.1 fdName = fdName.Remove(0, 1).Remove(fdName.IndexOf('>') - 1); var asmProp = asmType.Properties.First(prop => prop.Name == fdName); varDesc.Definition = asmProp; attrs = asmProp.CustomAttributes; fdType = asmProp.PropertyType.ToType(); fdArray = asmProp.PropertyType.IsArray; } var attrCt = attrs.Count(attr => varTypes.Contains(attr.AttributeType.Name)); var validFd = (asmField.HasConstant || attrCt == 1); var varType = (isProp) ? "Property '" : "Field '"; if (asmField.IsStatic && !asmField.HasConstant) { DebugLog.Error(varType + fdName + "' cannot be static"); } else if (validFd) { var fdAttrName = attrs.First(attr => varTypes.Contains(attr.AttributeType.Name)); var fdAttr = (SLVariableType)Array.IndexOf(varTypes, fdAttrName.AttributeType.Name); if (asmField.HasConstant) { if (fdAttr != SLVariableType.xSLConstAttribute) { DebugLog.Error(varType + "constant " + fdName + "' has an invalid attribute"); } varDesc.Value = asmField.Constant; } varDesc.DataType = fdType; varDesc.Attribute = fdAttr; varDesc.IsArray = fdArray; variables.Add(varDesc); } else { DebugLog.Error(varType + fdName + "' is neither a constant nor has valid attributes"); } } shaderDesc.Variables = variables; shaderTranslator.PreVariableCheck(); // translate main, depending methods and constructors if (shaderDesc.Target.Envr == SLEnvironment.OpenGLMix) { Console.WriteLine("\n 3. Translating shader from C# to GLSL/GLSLES."); } else { Console.WriteLine("\n 3. Translating shader from C# to " + shaderDesc.Target.Envr + "."); } shaderDesc.Funcs = new IEnumerable <FunctionDesc> [2]; var vertexFuncs = shaderTranslator.Translate(shaderDesc.Target, vertexMain); shaderDesc.Funcs[(int)SLShaderType.VertexShader] = vertexFuncs; var fragmentFuncs = shaderTranslator.Translate(shaderDesc.Target, fragmentMain); shaderDesc.Funcs[(int)SLShaderType.FragmentShader] = fragmentFuncs; // check correct use of constants foreach (var ctor in customCtors) { var funcs = shaderTranslator.Translate(shaderDesc.Target, ctor); var allVars = funcs.SelectMany(func => func.Variables).ToList(); var allGlobVars = allVars.Where(variables.Contains).ToList(); var illegalVars = allVars.Except(allGlobVars).ToList(); foreach (var illegalVar in illegalVars) { var name = illegalVar.Definition.Name; var instr = illegalVar.Instruction; DebugLog.Error("Illegal use of '" + name + "' in a constructor", instr); } foreach (var constVar in allGlobVars) { var globVar = shaderDesc.Variables.First(var => var.Equals(constVar)); var index = shaderDesc.Variables.IndexOf(globVar); var name = constVar.Definition.Name; var instr = constVar.Instruction; if (globVar.Attribute != SLVariableType.xSLConstAttribute) { DebugLog.Error("Variable '" + name + "' is used as a constant but not marked as such'", instr); } else if (globVar.Value != null && constVar.Value != null) { DebugLog.Error("Constant '" + name + "' cannot be set more than once", instr); } else if (constVar.Value is String) { DebugLog.Error("Constant '" + name + "' was initialized with an invalid value", instr); } else { shaderDesc.Variables[index].Value = constVar.Value; } } } // build both shaders var vertexResult = shaderTranslator.BuildShader(SLShaderType.VertexShader); var fragmentResult = shaderTranslator.BuildShader(SLShaderType.FragmentShader); shaderDesc = shaderTranslator.ShaderDesc; // see if there are unused fields/properties var unusedVars = shaderDesc.Variables.Where(var => !var.IsReferenced); unusedVars = unusedVars.Where(var => var.Attribute != SLVariableType.xSLConstAttribute); foreach (var unsedVar in unusedVars) { DebugLog.Warning("Variable '" + unsedVar.Definition.Name + "' was declared but not used"); } if (!DebugLog.Abort) { Console.WriteLine("\n 4. Building vertex and fragment shader."); // debugging: save to file first, then precompile Console.WriteLine("\n 5. Applying debugging flags if any."); if (!DebugLog.Abort && (xSLShader.xSLDebug.SaveToFile & shaderDesc.DebugFlags) != 0) { var directory = Path.GetDirectoryName(inputPath); if (directory != null) { var combined = new StringBuilder("---- VertexShader ----").NewLine(2); combined.Append(vertexResult).NewLine(3).Append("---- FragmentShader ----"); combined.NewLine(2).Append(fragmentResult); var filePath = Path.Combine(directory, shaderDesc.Name + ".txt"); File.WriteAllText(filePath, combined.ToString()); Console.WriteLine(" => Saved shader to: '" + filePath + "'"); } } if (!DebugLog.Abort && (xSLShader.xSLDebug.PreCompile & shaderDesc.DebugFlags) != 0) { shaderTranslator.PreCompile(vertexResult, fragmentResult); } } else { Console.WriteLine("\n 4. Shader will not be built due to critical errors."); Console.WriteLine("\n 5. Applying debugging flags if any."); } if (DebugLog.Abort) { if ((xSLShader.xSLDebug.ThrowException & shaderDesc.DebugFlags) != 0) { Console.WriteLine(" => Errors will be thrown when using the shader."); Console.WriteLine("\n 6. Preparing to update meta assembly for this shader."); } } // save shaders or errors into the assembly var genShader = metaAsm.MainModule.Types.First(type => type.ToType() == typeof(xSL <>)); var instShader = new GenericInstanceType(genShader); var asmTypeImport = metaAsm.MainModule.Import(asmType); instShader.GenericArguments.Add(asmTypeImport); var instrList = new List <Instruction>(); if (!DebugLog.Abort) { Console.WriteLine("\n 6. Preparing to update meta assembly for this shader."); var vertField = GenericFieldReference(genShader, instShader, "_vertex"); var fragField = GenericFieldReference(genShader, instShader, "_fragment"); var transField = GenericFieldReference(genShader, instShader, "_translated"); metaAsm.MainModule.Import(vertField); metaAsm.MainModule.Import(fragField); metaAsm.MainModule.Import(transField); instrList.Add(Instruction.Create(OpCodes.Ldstr, vertexResult.ToString())); instrList.Add(Instruction.Create(OpCodes.Stsfld, vertField)); instrList.Add(Instruction.Create(OpCodes.Ldstr, fragmentResult.ToString())); instrList.Add(Instruction.Create(OpCodes.Stsfld, fragField)); instrList.Add(Instruction.Create(OpCodes.Ldc_I4_1)); instrList.Add(Instruction.Create(OpCodes.Stsfld, transField)); } // apply debug mode ThrowException if (DebugLog.Abort && (xSLShader.xSLDebug.ThrowException & shaderDesc.DebugFlags) != 0) { var errors = DebugLog.Errors.ToString().Replace(" =>", "=>"); var errField = GenericFieldReference(genShader, instShader, "_error"); instrList.Add(Instruction.Create(OpCodes.Ldstr, errors)); instrList.Add(Instruction.Create(OpCodes.Stsfld, errField)); } shaderDesc.Instructions = instrList; Console.WriteLine(DebugLog.Abort ? "\n ---- Translation failed ----" : "\n ---- Translation succeeded ----"); shaderDescs.Add(shaderDesc); } // write shaders into assembly var invalidCt = shaderDescs.Count(shader => !shader.Instructions.Any()); if (invalidCt == shaderDescs.Count) { Console.WriteLine("\n\nAssembly will not be updated as no shader was translated successfully."); } else { Console.WriteLine("\n\nUpdating CrossSL meta assembly:"); var asmModule = metaAsm.MainModule; var genShader = asmModule.Types.First(type => type.ToType() == typeof(xSL <>)); var xSLInit = genShader.Methods.First(method => method.Name == "Init"); var ilProc = xSLInit.Body.GetILProcessor(); xSLInit.Body.Instructions.Clear(); foreach (var shaderDesc in shaderDescs) { foreach (var instr in shaderDesc.Instructions) { ilProc.Append(instr); } } var ret = Instruction.Create(OpCodes.Ret); ilProc.Append(ret); try { var writeParams = new WriterParameters { WriteSymbols = false }; asmModule.Write(metaPath, writeParams); foreach (var shaderDesc in shaderDescs) { if (shaderDesc.Instructions.Count() > 2) { Console.WriteLine(" => Added shader '" + shaderDesc.Name + "' to assembly."); } else if (shaderDesc.Instructions.Any()) { Console.WriteLine(" => [ThrowException] mode was applied for shader '" + shaderDesc.Name + "'."); } } Console.WriteLine("\n => Saved assembly as '" + metaPath + "'"); } catch (IOException) { Console.WriteLine(" => Cannot update assembly. File might be missing, read-only or in use."); } } DebugLog.UsageError("\nDone."); return(0); }
private Stream GetSymbolInformation(out ISymbolReaderProvider symbolReaderProvider, out ISymbolWriterProvider symbolWriterProvider) { if (string.Equals("none", DebugType, StringComparison.OrdinalIgnoreCase)) { Logger.Info("No symbols"); symbolReaderProvider = null; symbolWriterProvider = null; return(null); } if (string.Equals("embedded", DebugType, StringComparison.OrdinalIgnoreCase)) { Logger.Info("Using embedded symbols"); symbolReaderProvider = new EmbeddedPortablePdbReaderProvider(); symbolWriterProvider = new EmbeddedPortablePdbWriterProvider(); return(null); } string pdbPath = FindPdbPath(); string mdbPath = FindMdbPath(); if (pdbPath != null && mdbPath != null) { if (File.GetLastWriteTimeUtc(pdbPath) >= File.GetLastWriteTimeUtc(mdbPath)) { mdbPath = null; Logger.Debug("Found mdb and pdb debug symbols. Selected pdb (newer).", DebugLogLevel.Verbose); } else { pdbPath = null; Logger.Debug("Found mdb and pdb debug symbols. Selected mdb (newer).", DebugLogLevel.Verbose); } } if (pdbPath != null) { Logger.Info($"Using symbol file {pdbPath}"); symbolReaderProvider = new PdbReaderProvider(); symbolWriterProvider = new PdbWriterProvider(); string tempPath = pdbPath + ".tmp"; File.Copy(pdbPath, tempPath, true); return(new FileStream(tempPath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)); } else if (mdbPath != null) { Logger.Info($"Using symbol file {mdbPath}"); symbolReaderProvider = new MdbReaderProvider(); symbolWriterProvider = new MdbWriterProvider(); string tempPath = mdbPath + ".tmp"; File.Copy(mdbPath, tempPath, true); return(new FileStream(tempPath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)); } symbolReaderProvider = null; symbolWriterProvider = null; return(null); string FindPdbPath() { // because UWP use a wacky convention for symbols string path = Path.ChangeExtension(AssemblyFile, "compile.pdb"); if (File.Exists(path)) { Logger.Debug($"Found debug symbols at '{path}'.", DebugLogLevel.Verbose); return(path); } path = Path.ChangeExtension(AssemblyFile, "pdb"); if (File.Exists(path)) { Logger.Debug($"Found debug symbols at '{path}'.", DebugLogLevel.Verbose); return(path); } return(null); } string FindMdbPath() { string path = AssemblyFile + ".mdb"; if (File.Exists(path)) { Logger.Debug($"Found debug symbols at '{path}'.", DebugLogLevel.Verbose); return(path); } return(null); } }
/// <summary> /// Patches the file. /// </summary> /// <param name="TargetFile">The file.</param> public Boolean PatchFile(String TargetFile) { TargetFile = Path.Combine(Environment.CurrentDirectory, TargetFile); FileTime FileTime = new FileTime(TargetFile); // var FileTimeInteropBuilder = new FileTime(Assembly.GetExecutingAssembly().Location); String CheckFile = Path.GetFullPath(TargetFile) + ".check"; // String checkInteropBuilderFile = "InteropBuild.check"; // If checkFile and checkInteropBuilderFile up-to-date, then nothing to do if (FileTime.CheckFileUpToDate(CheckFile)) { Log("Nothing to do. SharpDX patch was already applied for assembly [{0}]", TargetFile); return false; } // Copy PDB from input assembly to output assembly if any ReaderParameters ReaderParameters = new ReaderParameters(); DefaultAssemblyResolver Resolver = new DefaultAssemblyResolver(); ReaderParameters.AssemblyResolver = Resolver; WriterParameters WriterParameters = new WriterParameters(); String PdbName = Path.ChangeExtension(TargetFile, "pdb"); if (File.Exists(PdbName)) { PdbReaderProvider SymbolReaderProvider = new PdbReaderProvider(); ReaderParameters.SymbolReaderProvider = SymbolReaderProvider; ReaderParameters.ReadSymbols = true; WriterParameters.WriteSymbols = true; } // Read Assembly Assembly = AssemblyDefinition.ReadAssembly(TargetFile, ReaderParameters); Resolver.AddSearchDirectory(Path.GetDirectoryName(TargetFile)); // Query the target framework in order to resolve correct assemblies and type forwarding CustomAttribute TargetFrameworkAttr = Assembly.CustomAttributes.FirstOrDefault( X => X.Constructor.FullName.Contains("System.Runtime.Versioning.TargetFrameworkAttribute")); if (TargetFrameworkAttr != null && TargetFrameworkAttr.ConstructorArguments.Count > 0 && TargetFrameworkAttr.ConstructorArguments[0].Value != null) { FrameworkName TargetFramework = new FrameworkName(TargetFrameworkAttr.ConstructorArguments[0].Value.ToString()); String NetcoreAssemblyPath = String.Format(@"Reference Assemblies\Microsoft\Framework\{0}\v{1}", TargetFramework.Identifier, TargetFramework.Version); NetcoreAssemblyPath = Path.Combine(ProgramFilesx86(), NetcoreAssemblyPath); if (Directory.Exists(NetcoreAssemblyPath)) { Resolver.AddSearchDirectory(NetcoreAssemblyPath); } } // Import void* and int32 VoidType = Assembly.MainModule.TypeSystem.Void.Resolve(); VoidPointerType = new PointerType(Assembly.MainModule.Import(VoidType)); IntType = Assembly.MainModule.Import(Assembly.MainModule.TypeSystem.Int32.Resolve()); // Remove CompilationRelaxationsAttribute for (Int32 Index = 0; Index < Assembly.CustomAttributes.Count; Index++) { CustomAttribute CustomAttribute = Assembly.CustomAttributes[Index]; if (CustomAttribute.AttributeType.FullName == typeof(CompilationRelaxationsAttribute).FullName) { Assembly.CustomAttributes.RemoveAt(Index); Index--; } } Log("SharpDX interop patch for assembly [{0}]", TargetFile); foreach (TypeDefinition Type in Assembly.MainModule.Types) PatchType(Type); // Remove All Interop classes foreach (TypeDefinition Type in ClassToRemoveList) Assembly.MainModule.Types.Remove(Type); String OutputFilePath = TargetFile; Assembly.Write(OutputFilePath, WriterParameters); FileTime = new FileTime(TargetFile); // Update Check file FileTime.UpdateCheckFile(CheckFile); // FileTimeInteropBuilder.UpdateCheckFile(CheckInteropBuilderFile); Log("SharpDX patch done for assembly [{0}]", TargetFile); return true; }