Exemple #1
0
 /// <summary>
 /// </summary>
 /// <param name="function">
 /// </param>
 private void ConvertVariables(PdbFunction function)
 {
     foreach (var scope in function.scopes)
     {
         this.ConvertScope(scope);
     }
 }
Exemple #2
0
        /// <summary>
        /// </summary>
        /// <param name="function">
        /// </param>
        /// <param name="generateFileOnly">
        /// </param>
        private void ConvertFunction(PdbFunction function, bool generateFileOnly = false)
        {
            if (function.lines == null)
            {
                return;
            }

            var method = new SourceMethod
            {
                Token       = (int)function.token,
                Name        = function.name,
                LinkageName = function.name,
                DisplayName = function.name,
                LineNumber  = function.lines.First().lines.First().lineBegin
            };

            var file = this.GetSourceFile(this.symbolWriter, function);

            if (generateFileOnly)
            {
                return;
            }

            var builder = this.symbolWriter.OpenMethod(file.CompilationUnitEntry, method);

            this.ConvertSequencePoints(function, file, builder);

            this.ConvertVariables(function);

            this.symbolWriter.CloseMethod();
        }
Exemple #3
0
        public void ConvertFunction(int token)
        {
            PdbFunction func = null;

            if (this.funcs.TryGetValue((uint)token, out func))
            {
                this.ConvertFunction(func);
                return;
            }

            if (token == -1)
            {
                this.ConvertFunction(this.funcs.Values.First(f => f.lines != null), true);
            }
        }
Exemple #4
0
        /// <summary>
        /// </summary>
        /// <param name="function">
        /// </param>
        /// <param name="file">
        /// </param>
        /// <param name="builder">
        /// </param>
        private void ConvertSequencePoints(PdbFunction function, SourceFile file, ISourceMethodBuilder builder)
        {
            var lastLine = 0;

            foreach (var line in function.lines.SelectMany(lines => lines.lines))
            {
                // 0xfeefee is an MS convention, we can't pass it into ISymbolWriter, so we use the last non-hidden line
                var isHidden = line.lineBegin == 0xfeefee;
                builder.MarkSequencePoint(
                    (int)line.offset, file, isHidden ? lastLine : (int)line.lineBegin, (int)line.colBegin, isHidden);
                if (!isHidden)
                {
                    lastLine = (int)line.lineBegin;
                }
            }
        }
Exemple #5
0
        /// <summary>
        /// </summary>
        /// <param name="symbolWriter">
        /// </param>
        /// <param name="function">
        /// </param>
        /// <returns>
        /// </returns>
        private SourceFile GetSourceFile(ISymbolWriter symbolWriter, PdbFunction function)
        {
            var name = (from l in function.lines where l.file != null select l.file.name).First();

            SourceFile file;

            if (this.files.TryGetValue(name, out file))
            {
                return(file);
            }

            var entry = symbolWriter.DefineDocument(name);
            var unit  = symbolWriter.DefineCompilationUnit(entry);

            file = new SourceFile(unit, entry);
            this.files.Add(name, file);
            return(file);
        }
Exemple #6
0
        /// <summary>
        /// </summary>
        /// <param name="bits">
        /// </param>
        /// <param name="info">
        /// </param>
        /// <param name="names">
        /// </param>
        /// <param name="funcList">
        /// </param>
        /// <param name="readStrings">
        /// </param>
        /// <param name="dir">
        /// </param>
        /// <param name="nameIndex">
        /// </param>
        /// <param name="reader">
        /// </param>
        /// <exception cref="PdbDebugException">
        /// </exception>
        private static void LoadFuncsFromDbiModule(
            BitAccess bits,
            DbiModuleInfo info,
            IntHashTable names,
            ArrayList funcList,
            bool readStrings,
            MsfDirectory dir,
            Dictionary <string, int> nameIndex,
            PdbReader reader)
        {
            PdbFunction[] funcs = null;

            bits.Position = 0;
            int sig;

            bits.ReadInt32(out sig);
            if (sig != 4)
            {
                throw new PdbDebugException("Invalid signature. (sig={0})", sig);
            }

            bits.Position = 4;

            // Console.WriteLine("{0}:", info.moduleName);
            funcs = PdbFunction.LoadManagedFunctions(info.moduleName, bits, (uint)info.cbSyms, readStrings);
            if (funcs != null)
            {
                bits.Position = info.cbSyms + info.cbOldLines;
                LoadManagedLines(funcs, names, bits, dir, nameIndex, reader, (uint)(info.cbSyms + info.cbOldLines + info.cbLines));

                for (var i = 0; i < funcs.Length; i++)
                {
                    funcList.Add(funcs[i]);
                }
            }
        }
Exemple #7
0
        /// <summary>
        /// </summary>
        /// <param name="funcs">
        /// </param>
        /// <param name="names">
        /// </param>
        /// <param name="bits">
        /// </param>
        /// <param name="dir">
        /// </param>
        /// <param name="nameIndex">
        /// </param>
        /// <param name="reader">
        /// </param>
        /// <param name="limit">
        /// </param>
        private static void LoadManagedLines(
            PdbFunction[] funcs, IntHashTable names, BitAccess bits, MsfDirectory dir, Dictionary<string, int> nameIndex, PdbReader reader, uint limit)
        {
            Array.Sort(funcs, PdbFunction.byAddress);
            var checks = new IntHashTable();

            // Read the files first
            var begin = bits.Position;
            while (bits.Position < limit)
            {
                int sig;
                int siz;
                bits.ReadInt32(out sig);
                bits.ReadInt32(out siz);
                var place = bits.Position;
                var endSym = bits.Position + siz;

                switch ((DEBUG_S_SUBSECTION)sig)
                {
                    case DEBUG_S_SUBSECTION.FILECHKSMS:
                        while (bits.Position < endSym)
                        {
                            CV_FileCheckSum chk;

                            var ni = bits.Position - place;
                            bits.ReadUInt32(out chk.name);
                            bits.ReadUInt8(out chk.len);
                            bits.ReadUInt8(out chk.type);

                            var name = (string)names[(int)chk.name];
                            int guidStream;
                            var doctypeGuid = SymDocumentType.Text;
                            var languageGuid = SymLanguageType.CSharp;
                            var vendorGuid = SymLanguageVendor.Microsoft;
                            if (nameIndex.TryGetValue("/src/files/" + name, out guidStream))
                            {
                                var guidBits = new BitAccess(0x100);
                                dir.streams[guidStream].Read(reader, guidBits);
                                LoadGuidStream(guidBits, out doctypeGuid, out languageGuid, out vendorGuid);
                            }

                            var src = new PdbSource((uint)ni, name, doctypeGuid, languageGuid, vendorGuid);
                            checks.Add(ni, src);
                            bits.Position += chk.len;
                            bits.Align(4);
                        }

                        bits.Position = endSym;
                        break;

                    default:
                        bits.Position = endSym;
                        break;
                }
            }

            // Read the lines next.
            bits.Position = begin;
            while (bits.Position < limit)
            {
                int sig;
                int siz;
                bits.ReadInt32(out sig);
                bits.ReadInt32(out siz);
                var endSym = bits.Position + siz;

                switch ((DEBUG_S_SUBSECTION)sig)
                {
                    case DEBUG_S_SUBSECTION.LINES:
                        {
                            CV_LineSection sec;

                            bits.ReadUInt32(out sec.off);
                            bits.ReadUInt16(out sec.sec);
                            bits.ReadUInt16(out sec.flags);
                            bits.ReadUInt32(out sec.cod);
                            var func = FindFunction(funcs, sec.sec, sec.off);
                            if (func == null)
                            {
                                break;
                            }

                            // Count the line blocks.
                            var begSym = bits.Position;
                            var blocks = 0;
                            while (bits.Position < endSym)
                            {
                                CV_SourceFile file;
                                bits.ReadUInt32(out file.index);
                                bits.ReadUInt32(out file.count);
                                bits.ReadUInt32(out file.linsiz); // Size of payload.
                                var linsiz = (int)file.count * (8 + ((sec.flags & 1) != 0 ? 4 : 0));
                                bits.Position += linsiz;
                                blocks++;
                            }

                            func.lines = new PdbLines[blocks];
                            var block = 0;

                            bits.Position = begSym;
                            while (bits.Position < endSym)
                            {
                                CV_SourceFile file;
                                bits.ReadUInt32(out file.index);
                                bits.ReadUInt32(out file.count);
                                bits.ReadUInt32(out file.linsiz); // Size of payload.

                                var src = (PdbSource)checks[(int)file.index];
                                var tmp = new PdbLines(src, file.count);
                                func.lines[block++] = tmp;
                                var lines = tmp.lines;

                                var plin = bits.Position;
                                var pcol = bits.Position + 8 * (int)file.count;

                                for (var i = 0; i < file.count; i++)
                                {
                                    CV_Line line;
                                    var column = new CV_Column();

                                    bits.Position = plin + 8 * i;
                                    bits.ReadUInt32(out line.offset);
                                    bits.ReadUInt32(out line.flags);

                                    var lineBegin = line.flags & (uint)CV_Line_Flags.linenumStart;
                                    var delta = (line.flags & (uint)CV_Line_Flags.deltaLineEnd) >> 24;
                                    var statement = (line.flags & (uint)CV_Line_Flags.fStatement) == 0;
                                    if ((sec.flags & 1) != 0)
                                    {
                                        bits.Position = pcol + 4 * i;
                                        bits.ReadUInt16(out column.offColumnStart);
                                        bits.ReadUInt16(out column.offColumnEnd);
                                    }

                                    lines[i] = new PdbLine(line.offset, lineBegin, column.offColumnStart, lineBegin + delta, column.offColumnEnd);
                                }
                            }

                            break;
                        }
                }

                bits.Position = endSym;
            }
        }
Exemple #8
0
        /// <summary>
        /// </summary>
        /// <param name="funcs">
        /// </param>
        /// <param name="sec">
        /// </param>
        /// <param name="off">
        /// </param>
        /// <returns>
        /// </returns>
        private static PdbFunction FindFunction(PdbFunction[] funcs, ushort sec, uint off)
        {
            match.segment = sec;
            match.address = off;

            var item = Array.BinarySearch(funcs, match, PdbFunction.byAddress);
            if (item >= 0)
            {
                return funcs[item];
            }

            return null;
        }
Exemple #9
0
        /// <summary>
        /// </summary>
        /// <param name="module">
        /// </param>
        /// <param name="bits">
        /// </param>
        /// <param name="limit">
        /// </param>
        /// <param name="readStrings">
        /// </param>
        /// <returns>
        /// </returns>
        internal static PdbFunction[] LoadManagedFunctions(string module, BitAccess bits, uint limit, bool readStrings)
        {
            var mod = StripNamespace(module);
            var begin = bits.Position;
            var count = 0;

            while (bits.Position < limit)
            {
                ushort siz;
                ushort rec;

                bits.ReadUInt16(out siz);
                var star = bits.Position;
                var stop = bits.Position + siz;
                bits.Position = star;
                bits.ReadUInt16(out rec);

                switch ((SYM)rec)
                {
                    case SYM.S_GMANPROC:
                    case SYM.S_LMANPROC:
                        ManProcSym proc;
                        bits.ReadUInt32(out proc.parent);
                        bits.ReadUInt32(out proc.end);
                        bits.Position = (int)proc.end;
                        count++;
                        break;

                    case SYM.S_END:
                        bits.Position = stop;
                        break;

                    default:

                        // Console.WriteLine("{0,6}: {1:x2} {2}",
                        // bits.Position, rec, (SYM)rec);
                        bits.Position = stop;
                        break;
                }
            }

            if (count == 0)
            {
                return null;
            }

            bits.Position = begin;
            var funcs = new PdbFunction[count];
            var func = 0;

            while (bits.Position < limit)
            {
                ushort siz;
                ushort rec;

                bits.ReadUInt16(out siz);
                var star = bits.Position;
                var stop = bits.Position + siz;
                bits.ReadUInt16(out rec);

                switch ((SYM)rec)
                {
                    case SYM.S_GMANPROC:
                    case SYM.S_LMANPROC:
                        ManProcSym proc;
                        var offset = bits.Position;

                        bits.ReadUInt32(out proc.parent);
                        bits.ReadUInt32(out proc.end);
                        bits.ReadUInt32(out proc.next);
                        bits.ReadUInt32(out proc.len);
                        bits.ReadUInt32(out proc.dbgStart);
                        bits.ReadUInt32(out proc.dbgEnd);
                        bits.ReadUInt32(out proc.token);
                        bits.ReadUInt32(out proc.off);
                        bits.ReadUInt16(out proc.seg);
                        bits.ReadUInt8(out proc.flags);
                        bits.ReadUInt16(out proc.retReg);
                        if (readStrings)
                        {
                            bits.ReadCString(out proc.name);
                        }
                        else
                        {
                            bits.SkipCString(out proc.name);
                        }

                        // Console.WriteLine("token={0:X8} [{1}::{2}]", proc.token, module, proc.name);
                        bits.Position = stop;
                        funcs[func++] = new PdbFunction(module, proc, bits);
                        break;

                    default:
                        {
                            // throw new PdbDebugException("Unknown SYMREC {0}", (SYM)rec);
                            bits.Position = stop;
                            break;
                        }
                }
            }

            return funcs;
        }
Exemple #10
0
        /// <summary>
        /// </summary>
        /// <param name="block">
        /// </param>
        /// <param name="bits">
        /// </param>
        /// <param name="typind">
        /// </param>
        /// <exception cref="PdbException">
        /// </exception>
        /// <exception cref="Exception">
        /// </exception>
        internal PdbScope(BlockSym32 block, BitAccess bits, out uint typind)
        {
            this.segment = block.seg;
            this.address = block.off;
            this.length  = block.len;
            typind       = 0;

            int constantCount;
            int scopeCount;
            int slotCount;
            int namespaceCount;

            PdbFunction.CountScopesAndSlots(bits, block.end, out constantCount, out scopeCount, out slotCount, out namespaceCount);
            this.constants      = new PdbConstant[constantCount];
            this.scopes         = new PdbScope[scopeCount];
            this.slots          = new PdbSlot[slotCount];
            this.usedNamespaces = new string[namespaceCount];
            var constant = 0;
            var scope    = 0;
            var slot     = 0;
            var usedNs   = 0;

            while (bits.Position < block.end)
            {
                ushort siz;
                ushort rec;

                bits.ReadUInt16(out siz);
                var star = bits.Position;
                var stop = bits.Position + siz;
                bits.Position = star;
                bits.ReadUInt16(out rec);

                switch ((SYM)rec)
                {
                case SYM.S_BLOCK32:
                {
                    var sub = new BlockSym32();

                    bits.ReadUInt32(out sub.parent);
                    bits.ReadUInt32(out sub.end);
                    bits.ReadUInt32(out sub.len);
                    bits.ReadUInt32(out sub.off);
                    bits.ReadUInt16(out sub.seg);
                    bits.SkipCString(out sub.name);

                    bits.Position        = stop;
                    this.scopes[scope++] = new PdbScope(sub, bits, out typind);
                    break;
                }

                case SYM.S_MANSLOT:
                    this.slots[slot++] = new PdbSlot(bits, out typind);
                    bits.Position      = stop;
                    break;

                case SYM.S_UNAMESPACE:
                    bits.ReadCString(out this.usedNamespaces[usedNs++]);
                    bits.Position = stop;
                    break;

                case SYM.S_END:
                    bits.Position = stop;
                    break;

                case SYM.S_MANCONSTANT:
                    this.constants[constant++] = new PdbConstant(bits);
                    bits.Position = stop;
                    break;

                default:
                    throw new PdbException("Unknown SYM in scope {0}", (SYM)rec);

                    // bits.Position = stop;
                }
            }

            if (bits.Position != block.end)
            {
                throw new Exception("Not at S_END");
            }

            ushort esiz;
            ushort erec;

            bits.ReadUInt16(out esiz);
            bits.ReadUInt16(out erec);

            if (erec != (ushort)SYM.S_END)
            {
                throw new Exception("Missing S_END");
            }
        }
Exemple #11
0
        /// <summary>
        /// </summary>
        /// <param name="module">
        /// </param>
        /// <param name="bits">
        /// </param>
        /// <param name="limit">
        /// </param>
        /// <param name="readStrings">
        /// </param>
        /// <returns>
        /// </returns>
        internal static PdbFunction[] LoadManagedFunctions(string module, BitAccess bits, uint limit, bool readStrings)
        {
            var mod   = StripNamespace(module);
            var begin = bits.Position;
            var count = 0;

            while (bits.Position < limit)
            {
                ushort siz;
                ushort rec;

                bits.ReadUInt16(out siz);
                var star = bits.Position;
                var stop = bits.Position + siz;
                bits.Position = star;
                bits.ReadUInt16(out rec);

                switch ((SYM)rec)
                {
                case SYM.S_GMANPROC:
                case SYM.S_LMANPROC:
                    ManProcSym proc;
                    bits.ReadUInt32(out proc.parent);
                    bits.ReadUInt32(out proc.end);
                    bits.Position = (int)proc.end;
                    count++;
                    break;

                case SYM.S_END:
                    bits.Position = stop;
                    break;

                default:

                    // Console.WriteLine("{0,6}: {1:x2} {2}",
                    // bits.Position, rec, (SYM)rec);
                    bits.Position = stop;
                    break;
                }
            }

            if (count == 0)
            {
                return(null);
            }

            bits.Position = begin;
            var funcs = new PdbFunction[count];
            var func  = 0;

            while (bits.Position < limit)
            {
                ushort siz;
                ushort rec;

                bits.ReadUInt16(out siz);
                var star = bits.Position;
                var stop = bits.Position + siz;
                bits.ReadUInt16(out rec);

                switch ((SYM)rec)
                {
                case SYM.S_GMANPROC:
                case SYM.S_LMANPROC:
                    ManProcSym proc;
                    var        offset = bits.Position;

                    bits.ReadUInt32(out proc.parent);
                    bits.ReadUInt32(out proc.end);
                    bits.ReadUInt32(out proc.next);
                    bits.ReadUInt32(out proc.len);
                    bits.ReadUInt32(out proc.dbgStart);
                    bits.ReadUInt32(out proc.dbgEnd);
                    bits.ReadUInt32(out proc.token);
                    bits.ReadUInt32(out proc.off);
                    bits.ReadUInt16(out proc.seg);
                    bits.ReadUInt8(out proc.flags);
                    bits.ReadUInt16(out proc.retReg);
                    if (readStrings)
                    {
                        bits.ReadCString(out proc.name);
                    }
                    else
                    {
                        bits.SkipCString(out proc.name);
                    }

                    // Console.WriteLine("token={0:X8} [{1}::{2}]", proc.token, module, proc.name);
                    bits.Position = stop;
                    funcs[func++] = new PdbFunction(module, proc, bits);
                    break;

                default:
                {
                    // throw new PdbDebugException("Unknown SYMREC {0}", (SYM)rec);
                    bits.Position = stop;
                    break;
                }
                }
            }

            return(funcs);
        }
Exemple #12
0
        /// <summary>
        /// </summary>
        /// <param name="symbolWriter">
        /// </param>
        /// <param name="function">
        /// </param>
        /// <returns>
        /// </returns>
        private SourceFile GetSourceFile(ISymbolWriter symbolWriter, PdbFunction function)
        {
            var name = (from l in function.lines where l.file != null select l.file.name).First();

            SourceFile file;
            if (this.files.TryGetValue(name, out file))
            {
                return file;
            }

            var entry = symbolWriter.DefineDocument(name);
            var unit = symbolWriter.DefineCompilationUnit(entry);

            file = new SourceFile(unit, entry);
            this.files.Add(name, file);
            return file;
        }
Exemple #13
0
 /// <summary>
 /// </summary>
 /// <param name="function">
 /// </param>
 private void ConvertVariables(PdbFunction function)
 {
     foreach (var scope in function.scopes)
     {
         this.ConvertScope(scope);
     }
 }
Exemple #14
0
 /// <summary>
 /// </summary>
 /// <param name="function">
 /// </param>
 /// <param name="file">
 /// </param>
 /// <param name="builder">
 /// </param>
 private void ConvertSequencePoints(PdbFunction function, SourceFile file, ISourceMethodBuilder builder)
 {
     var lastLine = 0;
     foreach (var line in function.lines.SelectMany(lines => lines.lines))
     {
         // 0xfeefee is an MS convention, we can't pass it into ISymbolWriter, so we use the last non-hidden line
         var isHidden = line.lineBegin == 0xfeefee;
         builder.MarkSequencePoint(
             (int)line.offset, file, isHidden ? lastLine : (int)line.lineBegin, (int)line.colBegin, isHidden);
         if (!isHidden)
         {
             lastLine = (int)line.lineBegin;
         }
     }
 }
Exemple #15
0
        /// <summary>
        /// </summary>
        /// <param name="function">
        /// </param>
        /// <param name="generateFileOnly">
        /// </param>
        private void ConvertFunction(PdbFunction function, bool generateFileOnly = false)
        {
            if (function.lines == null)
            {
                return;
            }

            var method = new SourceMethod
            {
                Token = (int)function.token,
                Name = function.name,
                LinkageName = function.name,
                DisplayName = function.name,
                LineNumber = function.lines.First().lines.First().lineBegin
            };

            var file = this.GetSourceFile(this.symbolWriter, function);
            if (generateFileOnly)
            {
                return;
            }

            var builder = this.symbolWriter.OpenMethod(file.CompilationUnitEntry, method);

            this.ConvertSequencePoints(function, file, builder);

            this.ConvertVariables(function);

            this.symbolWriter.CloseMethod();
        }