private static void LoadManagedLines()

in ClrMemDiag/Utilities/PDB/PdbFile.cs [157:337]


        private static void LoadManagedLines(PdbFunction[] funcs,
                                     Dictionary<int, string> names,
                                     BitAccess bits,
                                     MsfDirectory dir,
                                     Dictionary<string, int> nameIndex,
                                     PdbStreamHelper reader,
                                     uint limit,
                                     Dictionary<string, PdbSource> sources)
        {
            Array.Sort(funcs, PdbFunction.byAddressAndToken);

            Dictionary<int, PdbSource> checks = new Dictionary<int, PdbSource>();

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

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

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

                            string name = names[(int)chk.name];
                            PdbSource src;
                            if (!sources.TryGetValue(name.ToUpperInvariant(), out src))
                            {
                                int guidStream;
                                Guid doctypeGuid = Guid.Empty;
                                Guid languageGuid = Guid.Empty;
                                Guid vendorGuid = Guid.Empty;
                                Guid algorithmId = Guid.Empty;
                                byte[] checksum = null;
                                byte[] source = null;

                                if (nameIndex.TryGetValue("/SRC/FILES/" + name.ToUpperInvariant(), out guidStream))
                                {
                                    var guidBits = new BitAccess(0x100);
                                    dir._streams[guidStream].Read(reader, guidBits);
                                    LoadGuidStream(guidBits, out doctypeGuid, out languageGuid, out vendorGuid, out algorithmId, out checksum, out source);
                                }

                                src = new PdbSource(/*(uint)ni,*/ name, doctypeGuid, languageGuid, vendorGuid, algorithmId, checksum, source);
                                sources.Add(name.ToUpperInvariant(), src);
                            }
                            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);
                int 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);
                            int funcIndex = FindFunction(funcs, sec.sec, sec.off);
                            if (funcIndex < 0) break;
                            var func = funcs[funcIndex];
                            if (func.SequencePoints == null)
                            {
                                while (funcIndex > 0)
                                {
                                    var f = funcs[funcIndex - 1];
                                    if (f.SequencePoints != null || f.Segment != sec.sec || f.Address != sec.off) break;
                                    func = f;
                                    funcIndex--;
                                }
                            }
                            else
                            {
                                while (funcIndex < funcs.Length - 1 && func.SequencePoints != null)
                                {
                                    var f = funcs[funcIndex + 1];
                                    if (f.Segment != sec.sec || f.Address != sec.off) break;
                                    func = f;
                                    funcIndex++;
                                }
                            }
                            if (func.SequencePoints != null) break;

                            // Count the line blocks.
                            int begSym = bits.Position;
                            int 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.
                                int linsiz = (int)file.count * (8 + ((sec.flags & 1) != 0 ? 4 : 0));
                                bits.Position += linsiz;
                                blocks++;
                            }

                            func.SequencePoints = new PdbSequencePointCollection[blocks];
                            int 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.

                                PdbSource src = (PdbSource)checks[(int)file.index];
                                PdbSequencePointCollection tmp = new PdbSequencePointCollection(src, file.count);
                                func.SequencePoints[block++] = tmp;
                                PdbSequencePoint[] lines = tmp.Lines;

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

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

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

                                    uint lineBegin = line.flags & (uint)CV_Line_Flags.linenumStart;
                                    uint delta = (line.flags & (uint)CV_Line_Flags.deltaLineEnd) >> 24;
                                    //bool 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 PdbSequencePoint(line.offset,
                                                           lineBegin,
                                                           column.offColumnStart,
                                                           lineBegin + delta,
                                                           column.offColumnEnd);
                                }
                            }
                            break;
                        }
                }
                bits.Position = endSym;
            }
        }