Ejemplo n.º 1
0
        /// <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);
        }
Ejemplo n.º 2
0
        /// <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);
        }
Ejemplo n.º 3
0
        /// <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();
        }