示例#1
0
        public RoutineInfo FindRoutine(int pc)
        {
            int start = 0, end = routines.Count;

            while (start < end)
            {
                int mid = (start + end) / 2;

                RoutineInfo ri = routines[mid];
                if (pc >= ri.CodeStart && pc < ri.CodeStart + ri.CodeLength)
                {
                    return(ri);
                }

                if (pc > ri.CodeStart)
                {
                    start = mid + 1;
                }
                else
                {
                    end = mid;
                }
            }

            return(null);
        }
示例#2
0
        public LineInfo?FindLine(int pc)
        {
            RoutineInfo rtn = FindRoutine(pc);

            if (rtn == null)
            {
                return(null);
            }

            ushort offset = (ushort)(pc - rtn.CodeStart);
            int    idx    = Array.BinarySearch(rtn.LineOffsets, offset);

            if (idx >= 0)
            {
                return(rtn.LineInfos[idx]);
            }

            idx = ~idx - 1;
            if (idx >= 0 && idx < rtn.LineInfos.Length)
            {
                return(rtn.LineInfos[idx]);
            }

            return(null);
        }
示例#3
0
        public int FindCodeAddress(string filename, int line)
        {
            for (int i = 0; i < routines.Count; i++)
            {
                RoutineInfo rtn = routines[i];
                for (int j = 0; j < rtn.LineInfos.Length; j++)
                {
                    if (rtn.LineInfos[j].File == filename && rtn.LineInfos[j].Line == line)
                    {
                        return(rtn.CodeStart + rtn.LineOffsets[j]);
                    }
                }
            }

            return(-1);
        }
示例#4
0
        public DebugInfo(Stream fromStream)
        {
            using (BinaryReader br = new BinaryReader(fromStream))
            {
                if (ReadWord(br) != 0xDEBF)
                    throw new ArgumentException("Invalid debug file header");
                if (ReadWord(br) != 0)
                    throw new ArgumentException("Unrecognized debug file version");
                ReadWord(br); // skip Inform version

                Dictionary<byte, string> filenames = new Dictionary<byte, string>(5);
                Dictionary<ushort, int> routineStarts = new Dictionary<ushort, int>();

                int i, codeArea = 0;
                byte b;
                ushort w;
                string str;
                LineRef line;
                RoutineInfo routine = null;

                while (fromStream.Position < fromStream.Length)
                {
                    byte type = br.ReadByte();
                    switch (type)
                    {
                        case 0:
                            // EOF_DBR
                            fromStream.Seek(0, SeekOrigin.End);
                            break;

                        case 1:
                            // FILE_DBR
                            b = br.ReadByte();
                            ReadString(br); // skip include name
                            str = ReadString(br);
                            filenames[b] = str;
                            break;

                        case 2:
                            // CLASS_DBR
                            ReadString(br);
                            ReadLineRef(br);
                            ReadLineRef(br);
                            break;

                        case 3:
                            // OBJECT_DBR
                            ReadWord(br);
                            ReadString(br);
                            ReadLineRef(br);
                            ReadLineRef(br);
                            break;

                        case 4:
                            // GLOBAL_DBR
                            br.ReadByte();
                            ReadString(br);
                            break;

                        case 12: // ARRAY_DBR
                        case 5: // ATTR_DBR
                        case 6: // PROP_DBR
                        case 7: // FAKE_ACTION_DBR
                        case 8: // ACTION_DBR
                            ReadWord(br);
                            ReadString(br);
                            break;

                        case 9:
                            // HEADER_DBR
                            matchingHeader = br.ReadBytes(64);
                            break;

                        case 11:
                            // ROUTINE_DBR
                            routine = new RoutineInfo();
                            routines.Add(routine);
                            w = ReadWord(br);
                            line = ReadLineRef(br);
                            if (line.IsValid)
                                routine.DefinedAt = new LineInfo(
                                    filenames[line.FileNum],
                                    line.LineNum,
                                    line.Column);
                            routine.CodeStart = ReadAddress(br);
                            routineStarts[w] = routine.CodeStart;
                            routine.Name = ReadString(br);
                            while (ReadString(br) != "")
                            {
                                // skip local variable names
                            }
                            break;

                        case 10:
                            // LINEREF_DBR
                            ReadWord(br);
                            w = ReadWord(br);
                            while (w-- > 0)
                            {
                                ReadLineRef(br);
                                ReadWord(br);
                            }
                            break;

                        case 14:
                            // ROUTINE_END_DBR
                            // assume routine is still set from earlier...
                            ReadWord(br); // skip routine number
                            ReadLineRef(br); // skip defn end
                            i = ReadAddress(br);
                            routine.CodeLength = i - routine.CodeStart;
                            break;

                        case 13:
                            // MAP_DBR
                            do
                            {
                                str = ReadString(br);
                                if (str != "")
                                {
                                    i = ReadAddress(br);
                                    if (str == "code area")
                                        codeArea = i;
                                }
                            } while (str != "");
                            break;
                    }
                }

                // patch routine addresses
                foreach (RoutineInfo ri in routines)
                    ri.CodeStart += codeArea;

                routines.Sort(delegate(RoutineInfo r1, RoutineInfo r2) { return r1.CodeStart - r2.CodeStart; });
            }
        }
示例#5
0
        public DebugInfo(Stream fromStream)
        {
            using (BinaryReader br = new BinaryReader(fromStream))
            {
                if (ReadWord(br) != 0xDEBF)
                {
                    throw new ArgumentException("Invalid debug file header");
                }
                if (ReadWord(br) != 0)
                {
                    throw new ArgumentException("Unrecognized debug file version");
                }
                ReadWord(br); // skip Inform version

                Dictionary <byte, string> filenames     = new Dictionary <byte, string>(5);
                Dictionary <ushort, int>  routineStarts = new Dictionary <ushort, int>();

                int         i, codeArea = 0;
                byte        b;
                ushort      w;
                string      str;
                LineRef     line;
                RoutineInfo routine = null;

                while (fromStream.Position < fromStream.Length)
                {
                    byte type = br.ReadByte();
                    switch (type)
                    {
                    case 0:
                        // EOF_DBR
                        fromStream.Seek(0, SeekOrigin.End);
                        break;

                    case 1:
                        // FILE_DBR
                        b = br.ReadByte();
                        ReadString(br);     // skip include name
                        str          = ReadString(br);
                        filenames[b] = str;
                        break;

                    case 2:
                        // CLASS_DBR
                        ReadString(br);
                        ReadLineRef(br);
                        ReadLineRef(br);
                        break;

                    case 3:
                        // OBJECT_DBR
                        ReadWord(br);
                        ReadString(br);
                        ReadLineRef(br);
                        ReadLineRef(br);
                        break;

                    case 4:
                        // GLOBAL_DBR
                        br.ReadByte();
                        ReadString(br);
                        break;

                    case 12:    // ARRAY_DBR
                    case 5:     // ATTR_DBR
                    case 6:     // PROP_DBR
                    case 7:     // FAKE_ACTION_DBR
                    case 8:     // ACTION_DBR
                        ReadWord(br);
                        ReadString(br);
                        break;

                    case 9:
                        // HEADER_DBR
                        matchingHeader = br.ReadBytes(64);
                        break;

                    case 11:
                        // ROUTINE_DBR
                        routine = new RoutineInfo();
                        routines.Add(routine);
                        w    = ReadWord(br);
                        line = ReadLineRef(br);
                        if (line.IsValid)
                        {
                            routine.DefinedAt = new LineInfo(
                                filenames[line.FileNum],
                                line.LineNum,
                                line.Column);
                        }
                        routine.CodeStart = ReadAddress(br);
                        routineStarts[w]  = routine.CodeStart;
                        routine.Name      = ReadString(br);
                        while (ReadString(br) != "")
                        {
                            // skip local variable names
                        }
                        break;

                    case 10:
                        // LINEREF_DBR
                        ReadWord(br);
                        w = ReadWord(br);
                        while (w-- > 0)
                        {
                            ReadLineRef(br);
                            ReadWord(br);
                        }
                        break;

                    case 14:
                        // ROUTINE_END_DBR
                        // assume routine is still set from earlier...
                        ReadWord(br);     // skip routine number
                        ReadLineRef(br);  // skip defn end
                        i = ReadAddress(br);
                        routine.CodeLength = i - routine.CodeStart;
                        break;

                    case 13:
                        // MAP_DBR
                        do
                        {
                            str = ReadString(br);
                            if (str != "")
                            {
                                i = ReadAddress(br);
                                if (str == "code area")
                                {
                                    codeArea = i;
                                }
                            }
                        } while (str != "");
                        break;
                    }
                }

                // patch routine addresses
                foreach (RoutineInfo ri in routines)
                {
                    ri.CodeStart += codeArea;
                }

                routines.Sort(delegate(RoutineInfo r1, RoutineInfo r2) { return(r1.CodeStart - r2.CodeStart); });
            }
        }