示例#1
0
        public uint GetLineInfoSize(MappedFileCursor cur)
        {
            cur.Read(out m_linePrefix);
            if (m_linePrefix.unit_length >= SkipUnit)
            {
                // A special length value means we've processed this file
                // before and have a gap between units. Skip ahead
                // to the next unit and return 0 to inform the caller.
                cur.Next -= (uint)Marshal.SizeOf <LineHeaderPrefix>();
                uint u = m_linePrefix.unit_length - SkipUnit;
                if (u < (uint)Marshal.SizeOf <LineHeaderPrefix>())
                {
                    cur.Next += u;
                }
                else
                {
                    cur.Next += m_linePrefix.header_length;
                }
                return(0);
            }

            // Don't count version or header_length field we just read
            return(m_linePrefix.unit_length - sizeof(ushort) - sizeof(uint));
        }
示例#2
0
        LineResult RunLineProgram(MappedFileCursor cur)
        {
            byte[]          arbOpLen;
            List <string>   arstrFolders;
            List <string>   arstrFiles;
            List <LineItem> lstLine;
            string          str;
            byte            op;
            int             iConstAddPc;
            int             iLen;
            LineItem        line;
            LineResult      res;

            if (m_linePrefix.version == 4)
            {
                cur.Read(out m_lineHeadV4);
                if (m_lineHeadV4.maximum_operations_per_instruction != 1)
                {
                    Debug.WriteLine("Incompatible file format");
                }
                m_lineHead.minimum_instruction_length = m_lineHeadV4.minimum_instruction_length;
                m_lineHead.default_is_stmt            = m_lineHeadV4.default_is_stmt;
                m_lineHead.line_base   = m_lineHeadV4.line_base;
                m_lineHead.line_range  = m_lineHeadV4.line_range;
                m_lineHead.opcode_base = m_lineHeadV4.opcode_base;
            }
            else
            {
                cur.Read(out m_lineHead);
            }

            arbOpLen = new byte[m_lineHead.opcode_base];
            for (int i = 1; i < arbOpLen.Length; i++)
            {
                arbOpLen[i] = cur.ReadByte();
            }

            arstrFolders = new List <string>();
            for (; ;)
            {
                str = cur.ReadString();
                if (str.Length == 0)
                {
                    break;
                }
                arstrFolders.Add(str);
            }

            arstrFiles = new List <string>();
            while (AddFile(cur, arstrFiles, arstrFolders))
            {
                ;
            }

            iConstAddPc = (255 - m_lineHead.opcode_base) / m_lineHead.line_range * m_lineHead.minimum_instruction_length;
            lstLine     = new List <LineItem>();

            while (!cur.AtEnd)
            {
                line.Address = 0;
                line.File    = 1;
                line.Line    = 1;
                line.Column  = 0;
                line.Discr   = 0;
                line.IsStmt  = m_lineHead.default_is_stmt != 0;
                line.IsEnd   = false;
                m_lineLast   = line;

                while (!cur.AtEnd)
                {
                    op = cur.ReadByte();
                    if (op >= m_lineHead.opcode_base)
                    {
                        // Special opcode
                        op           -= m_lineHead.opcode_base;
                        line.Address += op / m_lineHead.line_range * m_lineHead.minimum_instruction_length;
                        line.Line    += op % m_lineHead.line_range + m_lineHead.line_base;
                        lstLine.Add(line);
                        m_lineLast = line;
                    }
                    else
                    {
                        switch ((StdLineOp)op)
                        {
                        case StdLineOp.DW_LNS_extended_op:
                            iLen = GetLeb(cur) - 1;
                            op   = cur.ReadByte();
                            switch ((ExtLineOp)op)
                            {
                            case ExtLineOp.DW_LNE_end_sequence:
                                line.IsEnd = true;
                                lstLine.Add(line);
                                goto NextSequence;

                            case ExtLineOp.DW_LNE_set_address:
                                line.Address = (int)cur.ReadUint();
                                break;

                            case ExtLineOp.DW_LNE_define_file:
                                AddFile(cur, arstrFiles, arstrFolders);
                                Debug.WriteLine("File added inline");
                                break;

                            case ExtLineOp.DW_LNE_set_discriminator:
                                line.Discr = GetLeb(cur);
                                break;

                            default:
                                Debug.WriteLine($"Ignored extended opcode {op}");
                                cur.Next += (uint)iLen;
                                break;
                            }
                            break;

                        case StdLineOp.DW_LNS_copy:
                            lstLine.Add(line);
                            m_lineLast = line;
                            break;

                        case StdLineOp.DW_LNS_advance_pc:
                            line.Address += GetLeb(cur) * m_lineHead.minimum_instruction_length;
                            break;

                        case StdLineOp.DW_LNS_advance_line:
                            line.Line += GetSignedLeb(cur);
                            break;

                        case StdLineOp.DW_LNS_set_file:
                            line.File = GetLeb(cur);
                            break;

                        case StdLineOp.DW_LNS_set_column:
                            line.Column = GetLeb(cur);
                            break;

                        case StdLineOp.DW_LNS_negate_stmt:
                            line.IsStmt = !line.IsStmt;
                            break;

                        case StdLineOp.DW_LNS_const_add_pc:
                            line.Address += iConstAddPc;
                            break;

                        case StdLineOp.DW_LNS_fixed_advance_pc:
                            line.Address += cur.ReadUshort();
                            break;

                        case StdLineOp.DW_LNS_set_basic_block:
                        case StdLineOp.DW_LNS_set_prologue_end:
                        case StdLineOp.DW_LNS_set_epilogue_begin:
                        default:
                            Debug.WriteLine($"Ignored opcode {Enum.GetName(typeof(StdLineOp), op)}");
                            for (int i = arbOpLen[op]; i > 0; i--)
                            {
                                GetLeb(cur);
                            }
                            break;
                        }
                    }
                }
                NextSequence :;
            }

            res.lines = lstLine.ToArray();
            res.files = arstrFiles.ToArray();
            return(res);
        }