public MsfDirectory(PdbReader reader, PdbFileHeader head, BitAccess bits)
        {
            bits.MinCapacity(head.directorySize);
            int pages = reader.PagesFromSize(head.directorySize);

            // 0..n in page of directory pages.
            reader.Seek(head.directoryRoot, 0);
            bits.FillBuffer(reader.reader, pages * 4);

            DataStream stream = new DataStream(head.directorySize, bits, pages);
            bits.MinCapacity(head.directorySize);
            stream.Read(reader, bits);

            // 0..3 in directory pages
            int count;
            bits.ReadInt32(out count);

            // 4..n
            int[] sizes = new int[count];
            bits.ReadInt32(sizes);

            // n..m
            streams = new DataStream[count];
            for (int i = 0; i < count; i++) {
                if (sizes[i] <= 0) {
                    streams[i] = new DataStream();
                }
                else {
                    streams[i] = new DataStream(sizes[i], bits,
                                                reader.PagesFromSize(sizes[i]));
                }
            }
        }
Пример #2
0
        public void Read(PdbReader reader, int position,
                         byte[] bytes, int offset, int data)
        {
            if (position + data > contentSize) {
                throw new PdbException("DataStream can't read off end of stream. " +
                                       "(pos={0},siz={1})",
                                       position, data);
            }
            if (position == contentSize) {
                return;
            }

            int left = data;
            int page = position / reader.pageSize;
            int rema = position % reader.pageSize;

            // First get remained of first page.
            if (rema != 0) {
                int todo = reader.pageSize - rema;
                if (todo > left) {
                    todo = left;
                }

                reader.Seek(pages[page], rema);
                reader.Read(bytes, offset, todo);

                offset += todo;
                left -= todo;
                page++;
            }

            // Now get the remaining pages.
            while (left > 0) {
                int todo = reader.pageSize;
                if (todo > left) {
                    todo = left;
                }

                reader.Seek(pages[page], 0);
                reader.Read(bytes, offset, todo);

                offset += todo;
                left -= todo;
                page++;
            }
        }
Пример #3
0
 public void Read(PdbReader reader, BitAccess bits)
 {
     bits.MinCapacity(contentSize);
     Read(reader, 0, bits.Buffer, 0, contentSize);
 }
Пример #4
0
        static void DumpVerbose(DataStream stream, PdbReader reader)
        {
            byte[] bytes = new byte[reader.PageSize];

            if (stream.Length <= 0) {
                return;
            }

            int left = stream.Length;
            int pos = 0;

            for (int page = 0; left > 0; page++) {
                int todo = bytes.Length;
                if (todo > left) {
                    todo = left;
                }

                stream.Read(reader, pos, bytes, 0, todo);

                for (int i = 0; i < todo; i += 16) {
                    Console.Write("{0,7}:", pos + i);
                    DumpLineExt(bytes, i, todo);
                    Console.WriteLine();
                }

                left -= todo;
                pos += todo;
            }
        }
Пример #5
0
        static void SplitStreams(Stream read, string split)
        {
            BitAccess bits = new BitAccess(4096);

            // Read the header and directory from the old file.
            // System.Diagnostics.Debugger.Break();
            PdbFileHeader head = new PdbFileHeader(read, bits);
            PdbReader reader = new PdbReader(read, head.pageSize);
            MsfDirectory dir = new MsfDirectory(reader, head, bits);

            byte[] buffer = new byte[head.pageSize];

            // Copy the streams.
            DataStream[] streams = new DataStream [dir.streams.Length];
            for (int i = 0; i < dir.streams.Length; i++) {
                streams[i] = new DataStream();

                DataStream source = dir.streams[i];
                if (source.Length <= 0) {
                    continue;
                }

                string name = String.Format("{0}.{1:d4}", split, i);
                Console.WriteLine("{0,4}: --> {1}", i, name);

                FileStream writer = new FileStream(name,
                                                   FileMode.Create,
                                                   FileAccess.Write);

                int left = source.Length;
                int pos = 0;

                for (int page = 0; left > 0; page++) {
                    int todo = buffer.Length;
                    if (todo > left) {
                        todo = left;
                    }

                    dir.streams[i].Read(reader, pos, buffer, 0, todo);
                    writer.Write(buffer, 0, todo);

                    left -= todo;
                    pos += todo;
                }
                writer.Close();
            }
        }
Пример #6
0
        static void CopyFile(Stream read, PdbWriter writer)
        {
            BitAccess bits = new BitAccess(4096);

            // Read the header and directory from the old file.
            // System.Diagnostics.Debugger.Break();
            PdbFileHeader head = new PdbFileHeader(read, bits);
            PdbReader reader = new PdbReader(read, head.pageSize);
            MsfDirectory dir = new MsfDirectory(reader, head, bits);

            byte[] buffer = new byte[head.pageSize];

            // Copy the streams.
            DataStream[] streams = new DataStream [dir.streams.Length];
            for (int i = 0; i < dir.streams.Length; i++) {
                streams[i] = new DataStream();

                DataStream source = dir.streams[i];
                if (source.Length <= 0) {
                    continue;
                }

                int left = source.Length;
                int pos = 0;

                for (int page = 0; left > 0; page++) {
                    int todo = buffer.Length;
                    if (todo > left) {
                        todo = left;
                    }

                    dir.streams[i].Read(reader, pos, buffer, 0, todo);
                    streams[i].Write(writer, buffer, todo);

                    left -= todo;
                    pos += todo;
                }
            }

            writer.WriteMeta(streams, bits);
        }
Пример #7
0
        static void DumpFile(Stream read, bool verbose)
        {
            BitAccess bits = new BitAccess(4096);
            PdbFileHeader head = new PdbFileHeader(read, bits);
            PdbReader reader = new PdbReader(read, head.pageSize);
            MsfDirectory dir = new MsfDirectory(reader, head, bits);

            Console.WriteLine("  PDB Processing[{0}]:", head.Magic);
            Console.WriteLine("    cbPage: {0}, fmap: {1}, pages: {2}, dirs: {3}, streams: {4}",
                              head.pageSize,
                              head.freePageMap,
                              head.pagesUsed,
                              head.directoryRoot,
                              dir.streams.Length);

            byte[] buffer = new byte[head.pageSize];

            int linkStream = 0;
            int nameStream = 0;
            int srchStream = 0;
            int tiHashStream = 0;
            int tiHPadStream = 0;
            int globalsStream = 0;
            int publicsStream = 0;
            int symbolsStream = 0;
            DbiModuleInfo[] modules = null;

            for (int i = 0; i < dir.streams.Length; i++) {
                if (dir.streams[i].Length <= 0) {
                    Console.WriteLine("{0,4}:{1,7} bytes", i, dir.streams[i].Length);
                }
                else {
                    Console.Write("{0,4}:{1,7} bytes {2,5}:",
                                  i,
                                  dir.streams[i].Length,
                                  dir.streams[i].GetPage(0));

                    int todo = 16;
                    if (todo > dir.streams[i].Length) {
                        todo = dir.streams[i].Length;
                    }
                    dir.streams[i].Read(reader, 0, buffer, 0, todo);

                    DumpLine(buffer, 0, todo);
                    Console.WriteLine();


                    DbiModuleInfo module = null;
                    if (modules != null) {
                        for (int m = 0; m < modules.Length; m++) {
                            if (modules[m].stream == i) {
                                module = modules[m];
                                break;
                            }
                        }
                    }

                    if (i == 1) {                   // <pdb>
                        dir.streams[i].Read(reader, bits);
                        DumpPdbStream(bits, out linkStream, out nameStream, out srchStream);
                        Console.WriteLine();
                    }
                    else if (i == 2) {
                        dir.streams[i].Read(reader, bits);
                        DumpTpiStream(bits, out tiHashStream, out tiHPadStream);
                        Console.WriteLine();
                    }
                    else if (i == 3) {
                        dir.streams[i].Read(reader, bits);
                        DumpDbiStream(bits,
                                      out globalsStream,
                                      out publicsStream,
                                      out symbolsStream,
                                      out modules);
                        Console.WriteLine();
                    }
                    else if (linkStream > 0 && i == linkStream) {
                        Console.WriteLine("   ** LNK");
                        if (verbose) {
                            DumpVerbose(dir.streams[i], reader);
                        }
                        Console.WriteLine();
                    }
                    else if (nameStream > 0 && i == nameStream) {
                        dir.streams[i].Read(reader, bits);
                        DumpNameStream(bits);
                        Console.WriteLine();
                    }
                    else if (srchStream > 0 && i == srchStream) {
                        Console.WriteLine("   ** SRC");
                        if (verbose) {
                            DumpVerbose(dir.streams[i], reader);
                        }
                        Console.WriteLine();
                    }
                    else if (tiHashStream > 0 && i == tiHashStream) {
                        Console.WriteLine("   ** TI#");
                        if (verbose) {
                            DumpVerbose(dir.streams[i], reader);
                        }
                        Console.WriteLine();
                    }
                    else if (tiHPadStream > 0 && i == tiHPadStream) {
                        Console.WriteLine("   ** TI#PAD");
                        if (verbose) {
                            DumpVerbose(dir.streams[i], reader);
                        }
                        Console.WriteLine();
                    }
                    else if (globalsStream > 0 && i == globalsStream) {
                        Console.WriteLine("   ** GLOBALS");
                        if (verbose) {
                            DumpVerbose(dir.streams[i], reader);
                        }
                        Console.WriteLine();
                    }
                    else if (publicsStream > 0 && i == publicsStream) {
                        Console.WriteLine("   ** PUBLICS");
                        if (verbose) {
                            DumpVerbose(dir.streams[i], reader);
                        }
                        Console.WriteLine();
                    }
                    else if (symbolsStream > 0 && i == symbolsStream) {
                        Console.WriteLine("   ** SYMBOLS");
                        if (verbose) {
                            dir.streams[i].Read(reader, bits);
                            DumpCvInfo(bits, 0, dir.streams[i].Length);
                        }
                        Console.WriteLine();
                    }
                    else if (module != null) {
                        dir.streams[i].Read(reader, bits);
                        DumpDbiModule(bits, module);
                        Console.WriteLine();
                    }
                    else if (verbose) {
                        DumpVerbose(dir.streams[i], reader);
                        Console.WriteLine();
                    }

                }
                if (i == 0) {
                    Console.WriteLine("+------------------------------------------------------------------------------");
                }
            }
        }
Пример #8
0
        public static PdbFunction[] LoadFunctions(Stream read, BitAccess bits,
                                                  bool readAllStrings)
        {
            PdbFileHeader head = new PdbFileHeader(read, bits);
            PdbReader reader = new PdbReader(read, head.pageSize);
            MsfDirectory dir = new MsfDirectory(reader, head, bits);
            DbiModuleInfo[] modules = null;
            DbiDbgHdr header;

            dir.streams[1].Read(reader, bits);
            int nameStream = LoadPdbStream(bits);
            if (nameStream <= 0) {
                throw new PdbException("No `name' stream");
            }

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

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

            ArrayList funcList = new ArrayList();

            if (modules != null) {
                for (int 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);
                    }
                }
            }

            PdbFunction[] 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);
                uint[] ridMap = new uint [dir.streams[header.snTokenRidMap].Length / 4];
                bits.ReadUInt32(ridMap);

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

            //
            Array.Sort(funcs, PdbFunction.byAddress);
            //Array.Sort(funcs, PdbFunction.byToken);
            return funcs;
        }
Пример #9
0
 public void Read(PdbReader reader, BitAccess bits)
 {
     bits.MinCapacity(contentSize);
     Read(reader, 0, bits.Buffer, 0, contentSize);
 }