Esempio n. 1
0
        void WriteSignedLeb(MappedFileCursor cur, int i)
        {
            byte b;

            do
            {
                b   = (byte)(i & 0x7F);
                i >>= 7;
                if ((i != 0 || (b & 0x40) != 0) && (i != -1 || (b & 0x40) == 0))
                {
                    b |= 0x80;
                }
                cur.WriteByte(b);
            } while ((b & 0x80) != 0);
        }
Esempio n. 2
0
        void WriteLeb(MappedFileCursor cur, int i)
        {
            byte b;

            do
            {
                b   = (byte)(i & 0x7F);
                i >>= 7;
                if (i != 0)
                {
                    b |= 0x80;
                }

                cur.WriteByte(b);
            } while (i != 0);
        }
Esempio n. 3
0
        void MakeLineProgram(MappedFileCursor cur, LineItem[] lines)
        {
            LineItem line;
            LineItem lineLast;
            int      iLine;
            int      iOpcode;
            int      iConstAddPc;
            int      iAddrDif;
            int      iLineDif;
            bool     fFixIt;

            iConstAddPc = (255 - m_lineHead.opcode_base) / m_lineHead.line_range;
            iLine       = 0;
            fFixIt      = false;

            for (; ;)
            {
                if (iLine >= lines.Length)
                {
                    break;
                }

                lineLast.Address = 0;
                lineLast.File    = 1;
                lineLast.Line    = 1;
                lineLast.Column  = 0;
                lineLast.Discr   = 0;
                lineLast.IsStmt  = m_lineHead.default_is_stmt != 0;

                for (; ;)
                {
                    line = lines[iLine++];

                    if (line.IsStmt != lineLast.IsStmt)
                    {
                        cur.WriteByte((byte)StdLineOp.DW_LNS_negate_stmt);
                    }

                    if (line.Discr != lineLast.Discr)
                    {
                        cur.WriteByte((byte)StdLineOp.DW_LNS_extended_op);
                        // count of following bytes depends on size of LEB128
                        byte cb  = 2;
                        uint val = (uint)line.Discr;
                        while ((val >>= 7) != 0)
                        {
                            cb++;
                        }
                        cur.WriteByte(cb);
                        cur.WriteByte((byte)ExtLineOp.DW_LNE_set_discriminator);
                        WriteLeb(cur, line.Discr);
                    }

                    if (line.File != lineLast.File)
                    {
                        cur.WriteByte((byte)StdLineOp.DW_LNS_set_file);
                        WriteLeb(cur, line.File);
                    }
                    if (line.Column != lineLast.Column)
                    {
                        cur.WriteByte((byte)StdLineOp.DW_LNS_set_column);
                        WriteLeb(cur, line.Column);
                    }

                    iLineDif = line.Line - lineLast.Line;
                    iAddrDif = (line.Address - lineLast.Address) / m_lineHead.minimum_instruction_length;

                    if (iAddrDif < 0)
                    {
                        cur.WriteByte((byte)StdLineOp.DW_LNS_extended_op);
                        cur.WriteByte(5);
                        cur.WriteByte((byte)ExtLineOp.DW_LNE_set_address);
                        cur.WriteUint((uint)line.Discr);
                        iAddrDif = 0;
                    }

                    if (line.IsEnd)
                    {
                        if (iLineDif != 0)
                        {
                            cur.WriteByte((byte)StdLineOp.DW_LNS_advance_line);
                            WriteSignedLeb(cur, iLineDif);
                        }
                        if (iAddrDif != 0)
                        {
                            cur.WriteByte((byte)StdLineOp.DW_LNS_advance_pc);
                            WriteLeb(cur, iAddrDif);
                        }
                        cur.WriteByte((byte)StdLineOp.DW_LNS_extended_op);
                        cur.WriteByte(1);                               // count of following bytes
                        cur.WriteByte((byte)ExtLineOp.DW_LNE_end_sequence);
                        break;
                    }

                    if (iLineDif < m_lineHead.line_base || iLineDif >= m_lineHead.line_base + m_lineHead.line_range)
                    {
                        // line dif exceeds range of special opcode
                        cur.WriteByte((byte)StdLineOp.DW_LNS_advance_line);
                        WriteSignedLeb(cur, iLineDif);
                        iLineDif = 0;
                    }

FixOpcode:
                    if (fFixIt || iAddrDif > iConstAddPc)
                    {
                        // address dif exceeds range of special opcode
                        if (fFixIt || iAddrDif > iConstAddPc * 2)
                        {
                            // Big dif, use multi-byte opcode
                            cur.WriteByte((byte)StdLineOp.DW_LNS_advance_pc);
                            WriteLeb(cur, iAddrDif);
                            iAddrDif = 0;
                        }
                        else
                        {
                            // Within range of single byte opcode
                            cur.WriteByte((byte)StdLineOp.DW_LNS_const_add_pc);
                            iAddrDif -= iConstAddPc;
                        }
                        fFixIt = false;
                    }

                    if (iAddrDif == 0 && iLineDif == 0)
                    {
                        cur.WriteByte((byte)StdLineOp.DW_LNS_copy);
                    }
                    else
                    {
                        // Compute special opcode
                        iOpcode = iLineDif - m_lineHead.line_base + m_lineHead.line_range * iAddrDif + m_lineHead.opcode_base;
                        if (iOpcode > 255)
                        {
                            fFixIt = true;
                            goto FixOpcode;
                        }
                        cur.WriteByte((byte)iOpcode);
                    }

                    // Move on to next line
                    if (iLine >= lines.Length)
                    {
                        throw new Exception("Line list did not end with End Sequence");
                    }
                    lineLast = line;
                }
            }
        }