/// <summary> /// Adds a given ConstantBinding to the current scope. /// </summary> /// <param name="binding">The constant to add to this scope.</param> /* Not supported at this time. Doesn't work correctly. AKB 2007-02-03 * public void BindConstant(ConstantBinding binding) { * * // Check to make sure a scope is open * if (currentScope == null) * throw new Exception("You must have an open scope in order to bind a constant."); * * // Add the constants to the current scope * currentScope.Constants.Add(binding); * * } */ /// <summary> /// Add a new sequnce point. /// </summary> /// <param name="sourceFile">The source file the sequence point is in.</param> /// <param name="docLanguage">The language of the source file.</param> /// <param name="langVendor">The language vendor of the source file.</param> /// <param name="docType">The document type.</param> /// <param name="offset">The offset of the sequence point.</param> /// <param name="line">The starting line for the sequence point.</param> /// <param name="col">The starting column for the sequence point.</param> /// <param name="endLine">The ending line for the sequence point.</param> /// <param name="endCol">The ending column for the sequence point.</param> public void AddSequencePoint(string sourceFile, Guid docLanguage, Guid langVendor, Guid docType, int offset, int line, int col, int endLine, int endCol) { Contract.Requires(sourceFile != null); Document sourceDoc = null; // Make sure we are in a method if (currentMethod == null) { throw new Exception("You can not add sequence points before opening a method."); } // Check if a reference for this source document already exists foreach (Document doc in _docWriters) { if (sourceFile == doc._file && docLanguage == doc._docLanguage && langVendor == doc._langVendor && docType == doc._docType) { sourceDoc = doc; break; } } // If no existing document, create a new one if (sourceDoc == null) { sourceDoc = new Document(); sourceDoc._file = sourceFile; sourceDoc._docLanguage = docLanguage; sourceDoc._langVendor = langVendor; sourceDoc._docType = docType; _docWriters.Add(sourceDoc); } SequencePointList spList = (SequencePointList)currentMethod.SequencePointList[sourceDoc]; if (spList == null) { currentMethod.SequencePointList.Add(sourceDoc, spList = new SequencePointList()); } spList.offsets.Add(offset); spList.lines.Add(line); spList.cols.Add(col); spList.endLines.Add(endLine); spList.endCols.Add(endCol); }
/// <summary> /// Adds a given ConstantBinding to the current scope. /// </summary> /// <param name="binding">The constant to add to this scope.</param> /* Not supported at this time. Doesn't work correctly. AKB 2007-02-03 public void BindConstant(ConstantBinding binding) { // Check to make sure a scope is open if (currentScope == null) throw new Exception("You must have an open scope in order to bind a constant."); // Add the constants to the current scope currentScope.Constants.Add(binding); } */ /// <summary> /// Add a new sequnce point. /// </summary> /// <param name="sourceFile">The source file the sequence point is in.</param> /// <param name="docLanguage">The language of the source file.</param> /// <param name="langVendor">The language vendor of the source file.</param> /// <param name="docType">The document type.</param> /// <param name="offset">The offset of the sequence point.</param> /// <param name="line">The starting line for the sequence point.</param> /// <param name="col">The starting column for the sequence point.</param> /// <param name="endLine">The ending line for the sequence point.</param> /// <param name="endCol">The ending column for the sequence point.</param> public void AddSequencePoint(string sourceFile, Guid docLanguage, Guid langVendor, Guid docType, int offset, int line, int col, int endLine, int endCol) { Contract.Requires(sourceFile != null); Document sourceDoc = null; // Make sure we are in a method if (currentMethod == null) throw new Exception("You can not add sequence points before opening a method."); // Check if a reference for this source document already exists foreach (Document doc in _docWriters) if (sourceFile == doc._file && docLanguage == doc._docLanguage && langVendor == doc._langVendor && docType == doc._docType) { sourceDoc = doc; break; } // If no existing document, create a new one if (sourceDoc == null) { sourceDoc = new Document(); sourceDoc._file = sourceFile; sourceDoc._docLanguage = docLanguage; sourceDoc._langVendor = langVendor; sourceDoc._docType = docType; _docWriters.Add(sourceDoc); } SequencePointList spList = (SequencePointList)currentMethod.SequencePointList[sourceDoc]; if (spList == null) currentMethod.SequencePointList.Add(sourceDoc, spList = new SequencePointList()); spList.offsets.Add(offset); spList.lines.Add(line); spList.cols.Add(col); spList.endLines.Add(endLine); spList.endCols.Add(endCol); }
/// <summary> /// Write the PDB file to disk. /// </summary> public void WritePDBFile() { /* * Write default template PDB file first * * NOTE: This is a dodgy hack so please feel free to change! AKB 06-01-2007 * * For some reason if there isn't a PDB file to start with the * debugger used to step through the resulting PDB file will * jump all over the place. Resulting in incorrect step-throughs. * I have not been able to work out why yet but I think it has * something to do with the call to GetWriterForFile(). * Also, it doesn't happen on all PDB files. * It is interesting to note that if it is writting a debug file * to go with a PE file compiled by csc (MS Compiler) it works fine. */ // Get the blank PDB file from the resource assembly System.Reflection.Assembly currentAssembly = System.Reflection.Assembly.GetExecutingAssembly(); Stream blankPDB = currentAssembly.GetManifestResourceStream("QUT.PERWAPI.Blank.pdb"); // Write the blank PDB file to the disk using (FileStream fs = new FileStream(PDBFilename, FileMode.OpenOrCreate, FileAccess.Write)) { BinaryWriter bw = new BinaryWriter(fs); // Loop through the PDB file and write it to the disk byte[] buffer = new byte[32768]; while (true) { int read = blankPDB.Read(buffer, 0, buffer.Length); if (read <= 0) { break; } bw.Write(buffer, 0, read); } // Close all of the streams we have opened bw.Close(); fs.Close(); } // Create the new Symbol Writer QSy.SymbolWriter symWriter = new QSy.SymbolWriter(PEFilename, PDBFilename); // Add each of the source documents foreach (Document doc in _docWriters) { #if SIMPLEWRITER doc._docWriter = symWriter.DefineDocument( doc._file, doc._docLanguage, doc._langVendor, doc._docType ); // Set the entry point if it exists if (entryPoint.GetToken() != 0) { symWriter.SetUserEntryPoint(entryPoint.GetToken()); } #else doc.docWriter = symWriter.DefineDocument( doc._file, ref doc._docLanguage, ref doc._langVendor, ref doc._docType ); // Set the entry point if it exists if (entryPoint.GetToken() != 0) { symWriter.SetUserEntryPoint(entryPoint); } #endif // SIMPLEWRITER } // Loop through and add each method foreach (Method meth in methods) { #if SIMPLEWRITER symWriter.OpenMethod(meth.Token.GetToken()); #else symWriter.OpenMethod(meth.Token); #endif // Write the scope and the locals if (meth.Scope != null) { WriteScopeAndLocals(symWriter, meth.Scope); } // Add each of the sequence points foreach (Document sourceDoc in meth.SequencePointList.Keys) { SequencePointList spList = (SequencePointList)meth.SequencePointList[sourceDoc]; #if SIMPLEWRITER symWriter.DefineSequencePoints(sourceDoc._docWriter, (uint[])spList.offsets.ToArray(), (uint[])spList.lines.ToArray(), (uint[])spList.cols.ToArray(), (uint[])spList.endLines.ToArray(), (uint[])spList.endCols.ToArray()); #else symWriter.DefineSequencePoints(sourceDoc.docWriter, spList.offsets.ToArray(), spList.lines.ToArray(), spList.cols.ToArray(), spList.endLines.ToArray(), spList.endCols.ToArray()); #endif // SIMPLEWRITER } symWriter.CloseMethod(); } // Get the debug info debugInfo = symWriter.GetDebugInfo(); // Close the PDB file symWriter.Close(); }