示例#1
0
 //
 // Summary:
 //     Visits the children of the System.Linq.Expressions.IndexExpression.
 //
 // Parameters:
 //   node:
 //     The expression to visit.
 //
 // Returns:
 //     The modified expression, if it or any subexpression was modified; otherwise,
 //     returns the original expression.
 protected override Expression VisitIndex(IndexExpression node)
 {
     Console.WriteLine("VisitIndex:");
     Console.WriteLine('\t' + node.GetType().ToString());
     Console.WriteLine('\t' + node.ToString());
     return(base.VisitIndex(node));
 }
示例#2
0
        public static void ToStringTest()
        {
            IndexExpression e1 = Expression.MakeIndex(Expression.Parameter(typeof(Vector1), "v"), typeof(Vector1).GetProperty("Item"), new[] { Expression.Parameter(typeof(int), "i") });

            Assert.Equal("v.Item[i]", e1.ToString());

            IndexExpression e2 = Expression.MakeIndex(Expression.Parameter(typeof(Vector2), "v"), typeof(Vector2).GetProperty("Item"), new[] { Expression.Parameter(typeof(int), "i"), Expression.Parameter(typeof(int), "j") });

            Assert.Equal("v.Item[i, j]", e2.ToString());

            IndexExpression e3 = Expression.ArrayAccess(Expression.Parameter(typeof(int[, ]), "xs"), Expression.Parameter(typeof(int), "i"), Expression.Parameter(typeof(int), "j"));

            Assert.Equal("xs[i, j]", e3.ToString());
        }
示例#3
0
        public static void Base()
        {
            ParameterExpression a   = Expression.Parameter(typeof(int), "a");
            ParameterExpression b   = Expression.Parameter(typeof(int), "b");
            ParameterExpression i   = Expression.Parameter(typeof(int), "i");
            BinaryExpression    add = Expression.Add(a, b);


            ConstantExpression s         = Expression.Constant(1);
            BinaryExpression   substract = Expression.Subtract(i, s);

            NewArrayExpression arrayint = Expression.NewArrayInit(typeof(int), a, b, add);
            IndexExpression    arracc   = Expression.ArrayAccess(arrayint, substract);

            Console.WriteLine(arracc.ToString());
        }
示例#4
0
        public bool BackwalkInstruction(TInstr instr)
        {
            var ass = host.AsAssignment(instr);

            if (ass.Item1 != null)
            {
                var(assSrc, _) = ass.Item2 !.Accept(eval);
                var assDst = ass.Item1;
                var regSrc = RegisterOf(assSrc);
                if (assSrc is BinaryExpression binSrc)
                {
                    if (RegisterOf(assDst) == Index || assDst == IndexExpression)
                    {
                        regSrc = RegisterOf(binSrc.Left);
                        var immSrc = binSrc.Right as Constant;
                        if (binSrc.Operator == Operator.IAdd || binSrc.Operator == Operator.ISub)
                        {
                            Index = HandleAddition(Index, Index, regSrc, immSrc !, binSrc.Operator == Operator.IAdd);
                            return(true);
                        }
                        if (binSrc.Operator == Operator.And)
                        {
                            if (immSrc != null && Bits.IsEvenPowerOfTwo(immSrc.ToInt32() + 1))
                            {
                                Operations.Add(new BackwalkOperation(BackwalkOperator.cmp, immSrc.ToInt32() + 1));
                            }
                            else
                            {
                                Index = null;
                            }
                            return(false);
                        }
                        if (binSrc.Operator is IMulOperator && immSrc != null)
                        {
                            var m = immSrc.ToInt32();
                            Operations.Add(new BackwalkOperation(BackwalkOperator.mul, m));
                            Stride *= m;
                            return(true);
                        }
                        if (binSrc.Operator is ShlOperator && immSrc != null)
                        {
                            var m = 1 << immSrc.ToInt32();
                            Operations.Add(new BackwalkOperation(BackwalkOperator.mul, m));
                            Stride *= m;
                            return(true);
                        }
                    }
                    if (Index != null &&
                        binSrc.Operator == Operator.Xor &&
                        binSrc.Left == assDst &&
                        binSrc.Right == assDst &&
                        RegisterOf(assDst) == host.GetSubregister(Index, new BitRange(8, 16)))
                    {
                        Operations.Add(new BackwalkOperation(BackwalkOperator.and, 0xFF));
                        Index = host.GetSubregister(Index, new BitRange(0, 8));
                    }
                }
                var cSrc = assSrc as Constant;
                if (Index != null &&
                    cSrc != null &&
                    cSrc.IsIntegerZero &&
                    RegisterOf(assDst) == host.GetSubregister(Index, new BitRange(8, 16)))
                {
                    // mov bh,0 ;; xor bh,bh
                    // jmp [bx...]
                    Operations.Add(new BackwalkOperation(BackwalkOperator.and, 0xFF));
                    Index = host.GetSubregister(Index, new BitRange(0, 8));
                    return(true);
                }
                if (assSrc is ConditionOf cof && UsedFlagIdentifier != null)
                {
                    var grfDef = (((Identifier)assDst).Storage as FlagGroupStorage) !.FlagGroupBits;
                    var grfUse = (UsedFlagIdentifier.Storage as FlagGroupStorage) !.FlagGroupBits;
                    if ((grfDef & grfUse) == 0)
                    {
                        return(true);
                    }
                    var binCmp = cof.Expression as BinaryExpression;
                    binCmp = NegateRight(binCmp);
                    if (binCmp != null &&
                        (binCmp.Operator is ISubOperator ||
                         binCmp.Operator is USubOperator))
                    {
                        var idLeft = RegisterOf(binCmp.Left  as Identifier);
                        if (idLeft != null &&
                            (idLeft == Index || idLeft == host.GetSubregister(Index !, new BitRange(0, 8))) ||
                            (IndexExpression != null && IndexExpression.ToString() == idLeft !.ToString()))  //$HACK: sleazy, but we don't appear to have an expression comparer
                        {
                            if (binCmp.Right is Constant immSrc)
                            {
                                // Found the bound of the table.
                                Operations.Add(new BackwalkOperation(BackwalkOperator.cmp, immSrc.ToInt32()));
                                return(false);
                            }
                        }
                    }
                    if (cof.Expression is Identifier idCof)
                    {
                        IndexExpression    = idCof;
                        Index              = null;
                        UsedFlagIdentifier = null;
                        UsedAsFlag         = idCof;
                        return(true);
                    }
                }

                //$BUG: this is rubbish, the simplifier should _just_
                // perform simplification, no substitutions.
                var src    = assSrc is InvalidConstant ? ass.Item2 : assSrc;
                var cvtSrc = src as Conversion;
                if (cvtSrc != null)
                {
                    src = cvtSrc.Expression;
                }
                var regDst = RegisterOf(assDst);
                if (src is MemoryAccess memSrc &&
                    (regDst == Index ||
                     (Index != null && regDst != null && regDst.Name != "None" && regDst.IsSubRegisterOf(Index))))
                {
                    // R = Mem[xxx]
                    var rIdx = Index;
                    var rDst = RegisterOf(assDst);
                    if ((rDst != host.GetSubregister(rIdx, new BitRange(0, 8)) && cvtSrc == null) &&
                        rDst != rIdx)
                    {
                        Index           = RegisterStorage.None;
                        IndexExpression = src;
                        return(true);
                    }

                    if (!(memSrc.EffectiveAddress is BinaryExpression binEa))
                    {
                        Index           = RegisterStorage.None;
                        IndexExpression = null;
                        return(false);
                    }
                    var scale   = GetMultiplier(binEa.Left);
                    var baseReg = GetBaseRegister(binEa.Left);
                    if (binEa.Right is Constant memOffset && binEa.Operator == Operator.IAdd)
                    {
                        var mOff = memOffset.ToInt32();
                        if (mOff > 0x200)
                        {
                            Operations.Add(new BackwalkDereference(memOffset.ToInt32(), scale));
                            Index = baseReg;
                            return(true);
                        }
                    }

                    // Some architectures have pc-relative addressing, which the rewriters
                    // should convert to an _address_.
                    var addr = binEa.Left as Address;
                    baseReg = GetBaseRegister(binEa.Right);
                    if (!(addr is null || VectorAddress is null))
                    {
                        this.VectorAddress = addr;
                        Index = baseReg;
                        return(true);
                    }
                    Index           = RegisterStorage.None;
                    IndexExpression = ass.Item2;
                    return(true);
                }

                if (regSrc != null && regDst == Index)
                {
                    Index = regSrc;
                    return(true);
                }
                UsedAsFlag = null;
                return(true);
            }

            var bra = host.AsBranch(instr);

            if (bra != null)
            {
                bool fallthrough = host.IsFallthrough(instr, startBlock !);
                return(VisitBranch(bra, fallthrough));
            }

            Debug.WriteLine("Backwalking not supported: " + instr);
            return(true);
        }
示例#5
0
 /// <summary>访问子内容为: <see cref="T:System.Linq.Expressions.IndexExpression"></see>.</summary>
 /// <param name="node">被访问的表达式</param>
 /// <returns>The modified expression, if it or any subexpression was modified; otherwise, returns the original expression.</returns>
 protected override Expression VisitIndex(IndexExpression node)
 {
     Log(node.ToString());
     throw new NotImplementedException();
 }
示例#6
0
        public bool BackwalkInstruction(Instruction instr)
        {
            var ass = instr as Assignment;

            if (ass != null)
            {
                var assSrc = ass.Src.Accept(eval);
                var regSrc = RegisterOf(assSrc as Identifier);
                var binSrc = assSrc as BinaryExpression;
                if (binSrc != null)
                {
                    if (RegisterOf(ass.Dst) == Index || ass.Dst == IndexExpression)
                    {
                        regSrc = RegisterOf(binSrc.Left);
                        var immSrc = binSrc.Right as Constant;
                        if (binSrc.Operator == Operator.IAdd || binSrc.Operator == Operator.ISub)
                        {
                            Index = HandleAddition(Index, Index, regSrc, immSrc, binSrc.Operator == Operator.IAdd);
                            return(true);
                        }
                        if (binSrc.Operator == Operator.And)
                        {
                            if (immSrc != null && IsEvenPowerOfTwo(immSrc.ToInt32() + 1))
                            {
                                Operations.Add(new BackwalkOperation(BackwalkOperator.cmp, immSrc.ToInt32() + 1));
                            }
                            else
                            {
                                Index = null;
                            }
                            return(false);
                        }
                        if (binSrc.Operator is IMulOperator && immSrc != null)
                        {
                            var m = immSrc.ToInt32();
                            Operations.Add(new BackwalkOperation(BackwalkOperator.mul, m));
                            Stride *= m;
                            return(true);
                        }
                        if (binSrc.Operator is ShlOperator && immSrc != null)
                        {
                            var m = 1 << immSrc.ToInt32();
                            Operations.Add(new BackwalkOperation(BackwalkOperator.mul, m));
                            Stride *= m;
                            return(true);
                        }
                    }
                    if (Index != null &&
                        binSrc.Operator == Operator.Xor &&
                        binSrc.Left == ass.Dst &&
                        binSrc.Right == ass.Dst &&
                        RegisterOf(ass.Dst) == host.GetSubregister(Index, 8, 8))
                    {
                        Operations.Add(new BackwalkOperation(BackwalkOperator.and, 0xFF));
                        Index = host.GetSubregister(Index, 0, 8);
                    }
                }
                var cSrc = assSrc as Constant;
                if (Index != null &&
                    cSrc != null &&
                    cSrc.IsIntegerZero &&
                    RegisterOf(ass.Dst) == host.GetSubregister(Index, 8, 8))
                {
                    // mov bh,0 ;; xor bh,bh
                    // jmp [bx...]
                    Operations.Add(new BackwalkOperation(BackwalkOperator.and, 0xFF));
                    Index = host.GetSubregister(Index, 0, 8);
                    return(true);
                }
                var cof = assSrc as ConditionOf;
                if (cof != null && UsedFlagIdentifier != null)
                {
                    var grfDef = (ass.Dst.Storage as FlagGroupStorage).FlagGroupBits;
                    var grfUse = (UsedFlagIdentifier.Storage as FlagGroupStorage).FlagGroupBits;
                    if ((grfDef & grfUse) == 0)
                    {
                        return(true);
                    }
                    var binCmp = cof.Expression as BinaryExpression;
                    if (binCmp != null &&
                        (binCmp.Operator is ISubOperator ||
                         binCmp.Operator is USubOperator))
                    {
                        var idLeft = RegisterOf(binCmp.Left  as Identifier);
                        if (idLeft != null &&
                            (idLeft == Index || idLeft == host.GetSubregister(Index, 0, 8)) ||
                            (IndexExpression != null && IndexExpression.ToString() == idLeft.ToString()))   //$HACK: sleazy, but we don't appear to have an expression comparer
                        {
                            var immSrc = binCmp.Right as Constant;
                            if (immSrc != null)
                            {
                                // Found the bound of the table.
                                Operations.Add(new BackwalkOperation(BackwalkOperator.cmp, immSrc.ToInt32()));
                                return(false);
                            }
                        }
                    }
                    var idCof = cof.Expression as Identifier;
                    if (idCof != null)
                    {
                        IndexExpression    = idCof;
                        Index              = null;
                        UsedFlagIdentifier = null;
                        UsedAsFlag         = idCof;
                        return(true);
                    }
                }

                //$BUG: this is rubbish, the simplifier should _just_
                // perform simplification, no substitutions.
                var src     = assSrc == Constant.Invalid ? ass.Src : assSrc;
                var castSrc = src as Cast;
                if (castSrc != null)
                {
                    src = castSrc.Expression;
                }
                var memSrc = src as MemoryAccess;
                var regDst = RegisterOf(ass.Dst);
                if (memSrc != null &&
                    (regDst == Index ||
                     (Index != null && regDst != null && regDst.Name != "None" && regDst.IsSubRegisterOf(Index))))
                {
                    // R = Mem[xxx]
                    var rIdx = Index;
                    var rDst = RegisterOf(ass.Dst);
                    if ((rDst != host.GetSubregister(rIdx, 0, 8) && castSrc == null) &&
                        rDst != rIdx)
                    {
                        Index           = RegisterStorage.None;
                        IndexExpression = src;
                        return(true);
                    }

                    var binEa = memSrc.EffectiveAddress as BinaryExpression;
                    if (binEa == null)
                    {
                        Index           = RegisterStorage.None;
                        IndexExpression = null;
                        return(false);
                    }
                    var memOffset = binEa.Right as Constant;
                    var scale     = GetMultiplier(binEa.Left);
                    var baseReg   = GetBaseRegister(binEa.Left);
                    if (memOffset != null && binEa.Operator == Operator.IAdd)
                    {
                        var mOff = memOffset.ToInt32();
                        if (mOff > 0x200)
                        {
                            Operations.Add(new BackwalkDereference(memOffset.ToInt32(), scale));
                            Index = baseReg;
                            return(true);
                        }
                    }

                    // Some architectures have pc-relative addressing, which the rewriters
                    // should convert to an _address_.
                    var addr = binEa.Left as Address;
                    baseReg = GetBaseRegister(binEa.Right);
                    if (addr != null && VectorAddress == null)
                    {
                        this.VectorAddress = addr;
                        Index = baseReg;
                        return(true);
                    }
                    Index           = RegisterStorage.None;
                    IndexExpression = ass.Src;
                    return(true);
                }

                if (regSrc != null && regDst == Index)
                {
                    Index = regSrc;
                    return(true);
                }
                UsedAsFlag = null;
                return(true);
            }

            var bra = instr as Branch;

            if (bra != null)
            {
                var cond = bra.Condition as TestCondition;
                if (cond != null)
                {
                    if (cond.ConditionCode == ConditionCode.UGE ||
                        cond.ConditionCode == ConditionCode.UGT ||
                        cond.ConditionCode == ConditionCode.GT)
                    {
                        Operations.Add(new BackwalkBranch(cond.ConditionCode));
                        UsedFlagIdentifier = (Identifier)cond.Expression;
                    }
                }
                return(true);
            }

            Debug.WriteLine("Backwalking not supported: " + instr);
            return(true);
        }
示例#7
0
文件: Backwalker.cs 项目: mmyydd/reko
        public bool BackwalkInstruction(Instruction instr)
        {
            var ass = instr as Assignment;

            if (ass != null)
            {
                var regSrc = RegisterOf(ass.Src as Identifier);
                var binSrc = ass.Src as BinaryExpression;
                if (binSrc != null)
                {
                    if (RegisterOf(ass.Dst) == Index)
                    {
                        regSrc = RegisterOf(binSrc.Left as Identifier);
                        var immSrc = binSrc.Right as Constant;
                        if (binSrc.Operator == Operator.IAdd || binSrc.Operator == Operator.ISub)
                        {
                            Index = HandleAddition(Index, Index, regSrc, immSrc, binSrc.Operator == Operator.IAdd);
                            return(true);
                        }
                        if (binSrc.Operator == Operator.And)
                        {
                            if (immSrc != null && IsEvenPowerOfTwo(immSrc.ToInt32() + 1))
                            {
                                Operations.Add(new BackwalkOperation(BackwalkOperator.cmp, immSrc.ToInt32() + 1));
                            }
                            else
                            {
                                Index = null;
                            }
                            return(false);
                        }
                        if (binSrc.Operator is IMulOperator && immSrc != null)
                        {
                            Operations.Add(new BackwalkOperation(BackwalkOperator.mul, immSrc.ToInt32()));
                            return(true);
                        }
                    }
                    if (Index != null &&
                        binSrc.Operator == Operator.Xor &&
                        binSrc.Left == ass.Dst &&
                        binSrc.Right == ass.Dst &&
                        RegisterOf(ass.Dst) == Index.GetSubregister(8, 8))
                    {
                        Operations.Add(new BackwalkOperation(BackwalkOperator.and, 0xFF));
                        Index = Index.GetSubregister(0, 8);
                    }
                }

                var cof = ass.Src as ConditionOf;
                if (cof != null && UsedFlagIdentifier != null)
                {
                    var grfDef = (ass.Dst.Storage as FlagGroupStorage).FlagGroupBits;
                    var grfUse = (UsedFlagIdentifier.Storage as FlagGroupStorage).FlagGroupBits;
                    if ((grfDef & grfUse) == 0)
                    {
                        return(true);
                    }
                    var binCmp = cof.Expression as BinaryExpression;
                    if (binCmp != null &&
                        (binCmp.Operator is ISubOperator ||
                         binCmp.Operator is USubOperator))
                    {
                        var idLeft = RegisterOf(binCmp.Left  as Identifier);
                        if (idLeft != null &&
                            (idLeft == Index || idLeft == Index.GetPart(PrimitiveType.Byte)) ||
                            (IndexExpression != null && IndexExpression.ToString() == idLeft.ToString()))   //$HACK: sleazy, but we don't appear to have an expression comparer
                        {
                            var immSrc = binCmp.Right as Constant;
                            if (immSrc != null)
                            {
                                Operations.Add(new BackwalkOperation(BackwalkOperator.cmp, immSrc.ToInt32()));
                                return(false);
                            }
                        }
                    }
                }

                var src     = ass.Src;
                var castSrc = src as Cast;
                if (castSrc != null)
                {
                    src = castSrc.Expression;
                }
                var memSrc = src as MemoryAccess;
                var regDst = RegisterOf(ass.Dst);
                if (memSrc != null && (regDst == Index || regDst.IsSubRegisterOf(Index)))
                {
                    // R = Mem[xxx]
                    var rIdx = Index;
                    var rDst = RegisterOf(ass.Dst);
                    if (rDst != rIdx.GetSubregister(0, 8) && castSrc == null)
                    {
                        Index           = RegisterStorage.None;
                        IndexExpression = src;
                        return(true);
                    }

                    var binEa = memSrc.EffectiveAddress as BinaryExpression;
                    if (binEa == null)
                    {
                        return(false);
                    }
                    var memOffset = binEa.Right as Constant;
                    var scale     = GetMultiplier(binEa.Left);
                    var baseReg   = GetBaseRegister(binEa.Left);
                    if (memOffset != null && binEa.Operator == Operator.IAdd)
                    {
                        var mOff = memOffset.ToInt32();
                        if (mOff > 0x200)
                        {
                            Operations.Add(new BackwalkDereference(memOffset.ToInt32(), scale));
                            Index = baseReg;
                            return(true);
                        }
                    }
                    return(false);
                }

                if (regSrc != null && regDst == Index)
                {
                    Index = regSrc;
                    return(true);
                }
                return(true);
            }

            var bra = instr as Branch;

            if (bra != null)
            {
                var cond = bra.Condition as TestCondition;
                if (cond != null && cond.ConditionCode == ConditionCode.UGT)
                {
                    Operations.Add(new BackwalkBranch(ConditionCode.UGT));
                    UsedFlagIdentifier = (Identifier)cond.Expression;
                }
                return(true);
            }

            Debug.WriteLine("Backwalking not supported: " + instr);
            return(true);
        }