예제 #1
0
 /// <summary>
 /// </summary>
 /// <param name="contentSize">
 /// </param>
 /// <param name="bits">
 /// </param>
 /// <param name="count">
 /// </param>
 internal DataStream(int contentSize, BitAccess bits, int count)
 {
     this.contentSize = contentSize;
     if (count > 0)
     {
         this.pages = new int[count];
         bits.ReadInt32(this.pages);
     }
 }
예제 #2
0
        /// <summary>
        /// </summary>
        /// <param name="read">
        /// </param>
        /// <param name="bits">
        /// </param>
        /// <param name="readAllStrings">
        /// </param>
        /// <returns>
        /// </returns>
        /// <exception cref="PdbException">
        /// </exception>
        internal static PdbFunction[] LoadFunctions(Stream read, BitAccess bits, bool readAllStrings)
        {
            var head = new PdbFileHeader(read, bits);
            var reader = new PdbReader(read, head.pageSize);
            var dir = new MsfDirectory(reader, head, bits);
            DbiModuleInfo[] modules = null;
            DbiDbgHdr header;

            dir.streams[1].Read(reader, bits);
            var nameIndex = LoadNameIndex(bits);
            int nameStream;
            if (!nameIndex.TryGetValue("/names", out nameStream))
            {
                throw new PdbException("No `name' stream");
            }

            dir.streams[nameStream].Read(reader, bits);
            var names = LoadNameStream(bits);

            dir.streams[3].Read(reader, bits);
            LoadDbiStream(bits, out modules, out header, readAllStrings);

            var funcList = new ArrayList();

            if (modules != null)
            {
                for (var m = 0; m < modules.Length; m++)
                {
                    if (modules[m].stream > 0)
                    {
                        dir.streams[modules[m].stream].Read(reader, bits);
                        LoadFuncsFromDbiModule(bits, modules[m], names, funcList, readAllStrings, dir, nameIndex, reader);
                    }
                }
            }

            var funcs = (PdbFunction[])funcList.ToArray(typeof(PdbFunction));

            // After reading the functions, apply the token remapping table if it exists.
            if (header.snTokenRidMap != 0 && header.snTokenRidMap != 0xffff)
            {
                dir.streams[header.snTokenRidMap].Read(reader, bits);
                var ridMap = new uint[dir.streams[header.snTokenRidMap].Length / 4];
                bits.ReadUInt32(ridMap);

                foreach (var func in funcs)
                {
                    func.token = 0x06000000 | ridMap[func.token & 0xffffff];
                }
            }

            //Array.Sort(funcs, PdbFunction.byAddress);
            Array.Sort(funcs, PdbFunction.byToken);

            return funcs;
        }
예제 #3
0
        /// <summary>
        /// </summary>
        /// <param name="reader">
        /// </param>
        /// <param name="bits">
        /// </param>
        internal PdbFileHeader(Stream reader, BitAccess bits)
        {
            bits.MinCapacity(56);
            reader.Seek(0, SeekOrigin.Begin);
            bits.FillBuffer(reader, 56);

            this.magic = new byte[32];
            bits.ReadBytes(this.magic); // 0..31
            bits.ReadInt32(out this.pageSize); // 32..35
            bits.ReadInt32(out this.freePageMap); // 36..39
            bits.ReadInt32(out this.pagesUsed); // 40..43
            bits.ReadInt32(out this.directorySize); // 44..47
            bits.ReadInt32(out this.zero); // 48..51
            bits.ReadInt32(out this.directoryRoot); // 52..55
        }
예제 #4
0
        /// <summary>
        /// </summary>
        /// <param name="bits">
        /// </param>
        /// <returns>
        /// </returns>
        /// <exception cref="PdbDebugException">
        /// </exception>
        private static IntHashTable LoadNameStream(BitAccess bits)
        {
            var ht = new IntHashTable();

            uint sig;
            int ver;
            bits.ReadUInt32(out sig); // 0..3  Signature
            bits.ReadInt32(out ver); // 4..7  Version

            // Read (or skip) string buffer.
            int buf;
            bits.ReadInt32(out buf); // 8..11 Bytes of Strings

            if (sig != 0xeffeeffe || ver != 1)
            {
                throw new PdbDebugException("Unsupported Name Stream version. " + "(sig={0:x8}, ver={1})", sig, ver);
            }

            var beg = bits.Position;
            var nxt = bits.Position + buf;
            bits.Position = nxt;

            // Read hash table.
            int siz;
            bits.ReadInt32(out siz); // n+0..3 Number of hash buckets.
            nxt = bits.Position;

            for (var i = 0; i < siz; i++)
            {
                int ni;
                string name;

                bits.ReadInt32(out ni);

                if (ni != 0)
                {
                    var saved = bits.Position;
                    bits.Position = beg + ni;
                    bits.ReadCString(out name);
                    bits.Position = saved;

                    ht.Add(ni, name);
                }
            }

            bits.Position = nxt;

            return ht;
        }
예제 #5
0
 /// <summary>
 /// </summary>
 /// <param name="read">
 /// </param>
 /// <param name="readAllStrings">
 /// </param>
 /// <returns>
 /// </returns>
 internal static PdbFunction[] LoadFunctions(Stream read, bool readAllStrings)
 {
     var bits = new BitAccess(512 * 1024);
     return LoadFunctions(read, bits, readAllStrings);
 }
예제 #6
0
 /// <summary>
 /// </summary>
 /// <param name="bits">
 /// </param>
 /// <param name="doctype">
 /// </param>
 /// <param name="language">
 /// </param>
 /// <param name="vendor">
 /// </param>
 private static void LoadGuidStream(BitAccess bits, out Guid doctype, out Guid language, out Guid vendor)
 {
     bits.ReadGuid(out language);
     bits.ReadGuid(out vendor);
     bits.ReadGuid(out doctype);
 }
예제 #7
0
        /// <summary>
        /// </summary>
        /// <param name="bits">
        /// </param>
        /// <param name="modules">
        /// </param>
        /// <param name="header">
        /// </param>
        /// <param name="readStrings">
        /// </param>
        /// <exception cref="PdbException">
        /// </exception>
        /// <exception cref="PdbDebugException">
        /// </exception>
        private static void LoadDbiStream(BitAccess bits, out DbiModuleInfo[] modules, out DbiDbgHdr header, bool readStrings)
        {
            var dh = new DbiHeader(bits);
            header = new DbiDbgHdr();

            if (dh.sig != -1 || dh.ver != 19990903)
            {
                throw new PdbException("Unsupported DBI Stream version, sig={0}, ver={1}", dh.sig, dh.ver);
            }

            // Read gpmod section.
            var modList = new ArrayList();
            var end = bits.Position + dh.gpmodiSize;
            while (bits.Position < end)
            {
                var mod = new DbiModuleInfo(bits, readStrings);
                modList.Add(mod);
            }

            if (bits.Position != end)
            {
                throw new PdbDebugException("Error reading DBI stream, pos={0} != {1}", bits.Position, end);
            }

            if (modList.Count > 0)
            {
                modules = (DbiModuleInfo[])modList.ToArray(typeof(DbiModuleInfo));
            }
            else
            {
                modules = null;
            }

            // Skip the Section Contribution substream.
            bits.Position += dh.secconSize;

            // Skip the Section Map substream.
            bits.Position += dh.secmapSize;

            // Skip the File Info substream.
            bits.Position += dh.filinfSize;

            // Skip the TSM substream.
            bits.Position += dh.tsmapSize;

            // Skip the EC substream.
            bits.Position += dh.ecinfoSize;

            // Read the optional header.
            end = bits.Position + dh.dbghdrSize;
            if (dh.dbghdrSize > 0)
            {
                header = new DbiDbgHdr(bits);
            }

            bits.Position = end;
        }
예제 #8
0
        /// <summary>
        /// </summary>
        /// <param name="streams">
        /// </param>
        /// <param name="directoryRoot">
        /// </param>
        /// <param name="directorySize">
        /// </param>
        /// <param name="bits">
        /// </param>
        private void WriteDirectory(DataStream[] streams, out int directoryRoot, out int directorySize, BitAccess bits)
        {
            var directory = new DataStream();

            var pages = 0;
            for (var s = 0; s < streams.Length; s++)
            {
                if (streams[s].Length > 0)
                {
                    pages += streams[s].Pages;
                }
            }

            var use = 4 * (1 + streams.Length + pages);
            bits.MinCapacity(use);
            bits.WriteInt32(streams.Length);
            for (var s = 0; s < streams.Length; s++)
            {
                bits.WriteInt32(streams[s].Length);
            }

            for (var s = 0; s < streams.Length; s++)
            {
                if (streams[s].Length > 0)
                {
                    bits.WriteInt32(streams[s].pages);
                }
            }

            directory.Write(this, bits.Buffer, use);
            directorySize = directory.Length;

            use = 4 * directory.Pages;
            bits.MinCapacity(use);
            bits.WriteInt32(directory.pages);

            var ddir = new DataStream();
            ddir.Write(this, bits.Buffer, use);

            directoryRoot = ddir.pages[0];
        }
예제 #9
0
 /// <summary>
 /// </summary>
 /// <param name="bits">
 /// </param>
 private void ReadUsingInfo(BitAccess bits)
 {
     ushort numberOfNamespaces;
     bits.ReadUInt16(out numberOfNamespaces);
     this.usingCounts = new ushort[numberOfNamespaces];
     for (ushort i = 0; i < numberOfNamespaces; i++)
     {
         bits.ReadUInt16(out this.usingCounts[i]);
     }
 }
예제 #10
0
 /// <summary>
 /// </summary>
 /// <param name="bits">
 /// </param>
 private void ReadForwardIterator(BitAccess bits)
 {
     this.iteratorClass = bits.ReadString();
 }
예제 #11
0
 /// <summary>
 /// </summary>
 /// <param name="bits">
 /// </param>
 private void ReadForwardInfo(BitAccess bits)
 {
 }
예제 #12
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);
        }
예제 #13
0
        /// <summary>
        /// </summary>
        /// <param name="module">
        /// </param>
        /// <param name="proc">
        /// </param>
        /// <param name="bits">
        /// </param>
        /// <exception cref="PdbDebugException">
        /// </exception>
        internal PdbFunction(string module, ManProcSym proc, BitAccess bits)
        {
            this.token     = proc.token;
            this.module    = module;
            this.name      = proc.name;
            this.flags     = proc.flags;
            this.segment   = proc.seg;
            this.address   = proc.off;
            this.length    = proc.len;
            this.slotToken = 0;

            if (proc.seg != 1)
            {
                throw new PdbDebugException("Segment is {0}, not 1.", proc.seg);
            }

            if (proc.parent != 0 || proc.next != 0)
            {
                throw new PdbDebugException("Warning parent={0}, next={1}", proc.parent, proc.next);
            }

            if (proc.dbgStart != 0 || proc.dbgEnd != 0)
            {
                throw new PdbDebugException("Warning DBG start={0}, end={1}", proc.dbgStart, proc.dbgEnd);
            }

            int constantCount;
            int scopeCount;
            int slotCount;
            int usedNamespacesCount;

            CountScopesAndSlots(bits, proc.end, out constantCount, out scopeCount, out slotCount, out usedNamespacesCount);
            this.scopes = new PdbScope[scopeCount];
            var scope = 0;

            while (bits.Position < proc.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_OEM:
                {
                    // 0x0404
                    OemSymbol oem;

                    bits.ReadGuid(out oem.idOem);
                    bits.ReadUInt32(out oem.typind);

                    // internal byte[]   rgl;        // user data, force 4-byte alignment
                    if (oem.idOem == msilMetaData)
                    {
                        var name = bits.ReadString();
                        if (name == "MD2")
                        {
                            byte version;
                            bits.ReadUInt8(out version);
                            if (version == 4)
                            {
                                byte count;
                                bits.ReadUInt8(out count);
                                bits.Align(4);
                                while (count-- > 0)
                                {
                                    this.ReadCustomMetadata(bits);
                                }
                            }
                        }

                        bits.Position = stop;
                        break;
                    }
                    else
                    {
                        throw new PdbDebugException("OEM section: guid={0} ti={1}", oem.idOem, oem.typind);

                        // bits.Position = stop;
                    }
                }

                case SYM.S_BLOCK32:
                {
                    var block = new BlockSym32();

                    bits.ReadUInt32(out block.parent);
                    bits.ReadUInt32(out block.end);
                    bits.ReadUInt32(out block.len);
                    bits.ReadUInt32(out this.address);
                    bits.ReadUInt16(out block.seg);
                    bits.SkipCString(out block.name);
                    bits.Position = stop;

                    this.scopes[scope] = new PdbScope(block, bits, out this.slotToken);
                    bits.Position      = (int)block.end;
                    break;
                }

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

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

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

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

            ushort esiz;
            ushort erec;

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

            if (erec != (ushort)SYM.S_END)
            {
                throw new PdbDebugException("Missing S_END");
            }
        }
예제 #14
0
 /// <summary>
 /// </summary>
 /// <param name="reader">
 /// </param>
 /// <param name="bits">
 /// </param>
 internal void Read(PdbReader reader, BitAccess bits)
 {
     bits.MinCapacity(this.contentSize);
     this.Read(reader, 0, bits.Buffer, 0, this.contentSize);
 }
예제 #15
0
        /// <summary>
        /// </summary>
        /// <param name="writer">
        /// </param>
        /// <param name="bits">
        /// </param>
        internal void Write(Stream writer, BitAccess bits)
        {
            bits.MinCapacity(56);
            bits.WriteBytes(this.magic); // 0..31
            bits.WriteInt32(this.pageSize); // 32..35
            bits.WriteInt32(this.freePageMap); // 36..39
            bits.WriteInt32(this.pagesUsed); // 40..43
            bits.WriteInt32(this.directorySize); // 44..47
            bits.WriteInt32(this.zero); // 48..51
            bits.WriteInt32(this.directoryRoot); // 52..55

            writer.Seek(0, SeekOrigin.Begin);
            bits.WriteBuffer(writer, 56);
        }
예제 #16
0
 /// <summary>
 /// </summary>
 /// <param name="bits">
 /// </param>
 private void ReadIteratorLocals(BitAccess bits)
 {
     uint numberOfLocals;
     bits.ReadUInt32(out numberOfLocals);
     this.iteratorScopes = new List<ILocalScope>((int)numberOfLocals);
     while (numberOfLocals-- > 0)
     {
         uint ilStartOffset;
         uint ilEndOffset;
         bits.ReadUInt32(out ilStartOffset);
         bits.ReadUInt32(out ilEndOffset);
         this.iteratorScopes.Add(new PdbIteratorScope(ilStartOffset, ilEndOffset - ilStartOffset));
     }
 }
예제 #17
0
 /// <summary>
 /// </summary>
 /// <param name="bits">
 /// </param>
 private void ReadForwardedToModuleInfo(BitAccess bits)
 {
 }
예제 #18
0
        /// <summary>
        /// </summary>
        /// <param name="streams">
        /// </param>
        /// <param name="bits">
        /// </param>
        internal void WriteMeta(DataStream[] streams, BitAccess bits)
        {
            var head = new PdbFileHeader(this.pageSize);

            this.WriteDirectory(streams, out head.directoryRoot, out head.directorySize, bits);
            this.WriteFreeMap();

            head.freePageMap = 2;
            head.pagesUsed = this.usedBytes / this.pageSize;

            this.writer.Seek(0, SeekOrigin.Begin);
            head.Write(this.writer, bits);
        }
예제 #19
0
        /// <summary>
        /// </summary>
        /// <param name="module">
        /// </param>
        /// <param name="proc">
        /// </param>
        /// <param name="bits">
        /// </param>
        /// <exception cref="PdbDebugException">
        /// </exception>
        internal PdbFunction(string module, ManProcSym proc, BitAccess bits)
        {
            this.token = proc.token;
            this.module = module;
            this.name = proc.name;
            this.flags = proc.flags;
            this.segment = proc.seg;
            this.address = proc.off;
            this.length = proc.len;
            this.slotToken = 0;

            if (proc.seg != 1)
            {
                throw new PdbDebugException("Segment is {0}, not 1.", proc.seg);
            }

            if (proc.parent != 0 || proc.next != 0)
            {
                throw new PdbDebugException("Warning parent={0}, next={1}", proc.parent, proc.next);
            }

            if (proc.dbgStart != 0 || proc.dbgEnd != 0)
            {
                throw new PdbDebugException("Warning DBG start={0}, end={1}", proc.dbgStart, proc.dbgEnd);
            }

            int constantCount;
            int scopeCount;
            int slotCount;
            int usedNamespacesCount;
            CountScopesAndSlots(bits, proc.end, out constantCount, out scopeCount, out slotCount, out usedNamespacesCount);
            this.scopes = new PdbScope[scopeCount];
            var scope = 0;

            while (bits.Position < proc.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_OEM:
                        {
                            // 0x0404
                            OemSymbol oem;

                            bits.ReadGuid(out oem.idOem);
                            bits.ReadUInt32(out oem.typind);

                            // internal byte[]   rgl;        // user data, force 4-byte alignment
                            if (oem.idOem == msilMetaData)
                            {
                                var name = bits.ReadString();
                                if (name == "MD2")
                                {
                                    byte version;
                                    bits.ReadUInt8(out version);
                                    if (version == 4)
                                    {
                                        byte count;
                                        bits.ReadUInt8(out count);
                                        bits.Align(4);
                                        while (count-- > 0)
                                        {
                                            this.ReadCustomMetadata(bits);
                                        }
                                    }
                                }

                                bits.Position = stop;
                                break;
                            }
                            else
                            {
                                throw new PdbDebugException("OEM section: guid={0} ti={1}", oem.idOem, oem.typind);

                                // bits.Position = stop;
                            }
                        }

                    case SYM.S_BLOCK32:
                        {
                            var block = new BlockSym32();

                            bits.ReadUInt32(out block.parent);
                            bits.ReadUInt32(out block.end);
                            bits.ReadUInt32(out block.len);
                            bits.ReadUInt32(out this.address);
                            bits.ReadUInt16(out block.seg);
                            bits.SkipCString(out block.name);
                            bits.Position = stop;

                            this.scopes[scope] = new PdbScope(block, bits, out this.slotToken);
                            bits.Position = (int)block.end;
                            break;
                        }

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

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

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

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

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

            if (erec != (ushort)SYM.S_END)
            {
                throw new PdbDebugException("Missing S_END");
            }
        }
예제 #20
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");
            }
        }
예제 #21
0
        /// <summary>
        /// </summary>
        /// <param name="bits">
        /// </param>
        /// <param name="limit">
        /// </param>
        /// <param name="constants">
        /// </param>
        /// <param name="scopes">
        /// </param>
        /// <param name="slots">
        /// </param>
        /// <param name="usedNamespaces">
        /// </param>
        internal static void CountScopesAndSlots(BitAccess bits, uint limit, out int constants, out int scopes, out int slots, out int usedNamespaces)
        {
            var pos = bits.Position;
            BlockSym32 block;
            constants = 0;
            slots = 0;
            scopes = 0;
            usedNamespaces = 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_BLOCK32:
                        {
                            bits.ReadUInt32(out block.parent);
                            bits.ReadUInt32(out block.end);

                            scopes++;
                            bits.Position = (int)block.end;
                            break;
                        }

                    case SYM.S_MANSLOT:
                        slots++;
                        bits.Position = stop;
                        break;

                    case SYM.S_UNAMESPACE:
                        usedNamespaces++;
                        bits.Position = stop;
                        break;

                    case SYM.S_MANCONSTANT:
                        constants++;
                        bits.Position = stop;
                        break;

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

            bits.Position = pos;
        }
예제 #22
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]);
                }
            }
        }
예제 #23
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;
        }
예제 #24
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;
            }
        }
예제 #25
0
        /// <summary>
        /// </summary>
        /// <param name="bits">
        /// </param>
        /// <exception cref="PdbDebugException">
        /// </exception>
        private void ReadCustomMetadata(BitAccess bits)
        {
            var savedPosition = bits.Position;
            byte version;
            bits.ReadUInt8(out version);
            if (version != 4)
            {
                throw new PdbDebugException("Unknown custom metadata item version: {0}", version);
            }

            byte kind;
            bits.ReadUInt8(out kind);
            bits.Align(4);
            uint numberOfBytesInItem;
            bits.ReadUInt32(out numberOfBytesInItem);
            switch (kind)
            {
                case 0:
                    this.ReadUsingInfo(bits);
                    break;
                case 1:
                    this.ReadForwardInfo(bits);
                    break;
                case 2:
                    this.ReadForwardedToModuleInfo(bits);
                    break;
                case 3:
                    this.ReadIteratorLocals(bits);
                    break;
                case 4:
                    this.ReadForwardIterator(bits);
                    break;
                default:
                    throw new PdbDebugException("Unknown custom metadata item kind: {0}", kind);
            }

            bits.Position = savedPosition + (int)numberOfBytesInItem;
        }
예제 #26
0
        /// <summary>
        /// </summary>
        /// <param name="bits">
        /// </param>
        /// <returns>
        /// </returns>
        /// <exception cref="PdbDebugException">
        /// </exception>
        private static Dictionary<string, int> LoadNameIndex(BitAccess bits)
        {
            var result = new Dictionary<string, int>();
            int ver;
            int sig;
            int age;
            Guid guid;
            bits.ReadInt32(out ver); // 0..3  Version
            bits.ReadInt32(out sig); // 4..7  Signature
            bits.ReadInt32(out age); // 8..11 Age
            bits.ReadGuid(out guid); // 12..27 GUID

            if (ver != 20000404)
            {
                throw new PdbDebugException("Unsupported PDB Stream version {0}", ver);
            }

            // Read string buffer.
            int buf;
            bits.ReadInt32(out buf); // 28..31 Bytes of Strings

            var beg = bits.Position;
            var nxt = bits.Position + buf;

            bits.Position = nxt;

            // Read map index.
            int cnt; // n+0..3 hash size.
            int max; // n+4..7 maximum ni.

            bits.ReadInt32(out cnt);
            bits.ReadInt32(out max);

            var present = new BitSet(bits);
            var deleted = new BitSet(bits);
            if (!deleted.IsEmpty)
            {
                throw new PdbDebugException("Unsupported PDB deleted bitset is not empty.");
            }

            var j = 0;
            for (var i = 0; i < max; i++)
            {
                if (present.IsSet(i))
                {
                    int ns;
                    int ni;
                    bits.ReadInt32(out ns);
                    bits.ReadInt32(out ni);

                    string name;
                    var saved = bits.Position;
                    bits.Position = beg + ns;
                    bits.ReadCString(out name);
                    bits.Position = saved;

                    result.Add(name, ni);
                    j++;
                }
            }

            if (j != cnt)
            {
                throw new PdbDebugException("Count mismatch. ({0} != {1})", j, cnt);
            }

            return result;
        }
예제 #27
0
 /// <summary>
 /// </summary>
 /// <param name="bits">
 /// </param>
 private void ReadForwardInfo(BitAccess bits)
 {
 }
예제 #28
0
 /// <summary>
 /// </summary>
 /// <param name="bits">
 /// </param>
 private void ReadForwardIterator(BitAccess bits)
 {
     this.iteratorClass = bits.ReadString();
 }
예제 #29
0
 /// <summary>
 /// </summary>
 /// <param name="bits">
 /// </param>
 private void ReadForwardedToModuleInfo(BitAccess bits)
 {
 }
예제 #30
0
 /// <summary>
 /// </summary>
 /// <param name="reader">
 /// </param>
 /// <param name="bits">
 /// </param>
 internal void Read(PdbReader reader, BitAccess bits)
 {
     bits.MinCapacity(this.contentSize);
     this.Read(reader, 0, bits.Buffer, 0, this.contentSize);
 }
예제 #31
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");
            }
        }