示例#1
0
        private StridedInterval MakeInterval_IAdd(Expression left, Constant right)
        {
            if (right == null)
            {
                return(StridedInterval.Empty);
            }
            var cc = this.ccNext;

            if (this.invertCondition)
            {
                cc = cc.Invert();
            }
            switch (cc)
            {
            default:
                return(StridedInterval.Empty);

            case ConditionCode.UGE:
                long max = ~right.ToInt64();
                if (max < 0)
                {
                    return(StridedInterval.Empty);
                }
                return(StridedInterval.Create(1, 0, max));
            }
        }
示例#2
0
        private StridedInterval MakeInterval_ISub(Expression left, Constant right)
        {
            if (right == null)
            {
                return(StridedInterval.Empty);
            }
            var cc = this.ccNext;

            if (this.invertCondition)
            {
                cc = cc.Invert();
            }
            switch (cc)
            {
            case ConditionCode.ULE: return(StridedInterval.Create(1, 0, right.ToInt64()));

            case ConditionCode.ULT: return(StridedInterval.Create(1, 0, right.ToInt64() - 1));

            case ConditionCode.UGE: return(StridedInterval.Create(1, right.ToInt64(), long.MaxValue));

            case ConditionCode.UGT: return(StridedInterval.Create(1, right.ToInt64() + 1, long.MaxValue));

            case ConditionCode.EQ:
            case ConditionCode.NE:
            case ConditionCode.None:
                return(StridedInterval.Empty);

            default:
                throw new NotImplementedException($"Unimplemented condition code {cc}.");
            }
        }
示例#3
0
        public override ValueSet And(Constant right)
        {
            long v = right.ToInt64();

            return(new IntervalValueSet(
                       this.DataType,
                       StridedInterval.Create(1, 0, v)));
        }
示例#4
0
        public override ValueSet Shl(Constant cRight)
        {
            int v = (int)cRight.ToInt64();

            return(new IntervalValueSet(
                       this.DataType,
                       StridedInterval.Create(
                           SI.Stride << v,
                               SI.Low << v,
                               SI.High << v)));
        }
示例#5
0
文件: ValueSet.cs 项目: smx-smx/reko
        public override ValueSet IMul(Constant cRight)
        {
            long v = cRight.ToInt64();

            return(new IntervalValueSet(
                       this.DataType,
                       StridedInterval.Create(
                           SI.Stride * (int)v,
                           SI.Low * v,
                           SI.High * v)));
        }
示例#6
0
        public override ValueSet Sub(Constant right)
        {
            if (SI.Stride < 0)
            {
                return(new IntervalValueSet(
                           this.DataType,
                           StridedInterval.Empty));
            }
            long v = right.ToInt64();

            return(new IntervalValueSet(
                       this.DataType,
                       StridedInterval.Create(
                           SI.Stride,
                           SI.Low - v,
                           SI.High - v)));
        }
示例#7
0
        private StridedInterval MakeInterval_ISub(Expression left, Constant right)
        {
            if (right == null)
            {
                return(StridedInterval.Empty);
            }
            var cc = this.ccNext;

            if (this.invertCondition)
            {
                cc = cc.Invert();
            }
            switch (cc)
            {
            // NOTE: GE and GT should really be modeled with the semi-open range
            // [right,inf) and the open range (right,inf), respectively. See comment
            // for LE/LT.
            case ConditionCode.GE: return(StridedInterval.Create(1, right.ToInt64(), long.MaxValue));

            case ConditionCode.GT: return(StridedInterval.Create(1, right.ToInt64() + 1, long.MaxValue));

            // NOTE: LE and LT should really be modeled with the semi-open range
            // (inf,right] and the open range (inf,right). However, typically compilers
            // make the mistake and use LE/LT for boundary checking in indirect transfers.
            case ConditionCode.LE: return(StridedInterval.Create(1, 0, right.ToInt64()));

            case ConditionCode.LT: return(StridedInterval.Create(1, 0, right.ToInt64() - 1));

            case ConditionCode.ULE: return(StridedInterval.Create(1, 0, right.ToInt64()));

            case ConditionCode.ULT: return(StridedInterval.Create(1, 0, right.ToInt64() - 1));

            case ConditionCode.UGE: return(StridedInterval.Create(1, right.ToInt64(), long.MaxValue));

            case ConditionCode.UGT: return(StridedInterval.Create(1, right.ToInt64() + 1, long.MaxValue));

            case ConditionCode.EQ:
            case ConditionCode.NE:
            case ConditionCode.None:
                return(StridedInterval.Empty);

            default:
                throw new NotImplementedException($"Unimplemented condition code {cc}.");
            }
        }
示例#8
0
        private StridedInterval MakeInterval_And(Expression left, Constant right)
        {
            if (right == null)
            {
                return(StridedInterval.Empty);
            }
            long n = right.ToInt64();

            if (Bits.IsEvenPowerOfTwo(n + 1))
            {
                // n is a mask (0000...00111..111)
                return(StridedInterval.Create(1, 0, n));
            }
            else
            {
                return(StridedInterval.Empty);
            }
        }
示例#9
0
        /// <summary>
        /// Returns a valueset whose values are the truncation of this valueset's
        /// values.
        /// </summary>
        /// <param name="dt"></param>
        /// <returns></returns>
        public override ValueSet Truncate(DataType dt)
        {
            if (SI.Stride < 0)
            {
                return(this);
            }

            var             mask = (1 << dt.BitSize) - 1;
            StridedInterval siNew;

            if (SI.Low == SI.High)
            {
                siNew = StridedInterval.Constant(
                    Constant.Create(dt, SI.Low & mask));
            }
            else
            {
                siNew = StridedInterval.Create(
                    SI.Stride, 0, Math.Min(mask, SI.High));
            }
            return(new IntervalValueSet(dt, siNew));
        }
示例#10
0
        public TableExtent DiscoverTableExtent(Address addrSwitch, RtlTransfer xfer, DecompilerEventListener listener)
        {
            if (!Start(rtlBlock, host.BlockInstructionCount(rtlBlock) - 1, xfer.Target))
            {
                // No registers were found, so we can't trace back.
                return(null);
            }
            while (Step())
            {
                ;
            }

            var jumpExpr = this.JumpTableFormat;
            var interval = this.JumpTableIndexInterval;
            var index    = this.JumpTableIndexToUse;
            var ctx      = new Dictionary <Expression, ValueSet>(new ExpressionValueComparer());

            if (index == null)
            {
                // Weren't able to find the index register,
                // try finding it by blind pattern matching.
                index = this.FindIndexWithPatternMatch(this.JumpTableFormat);
                if (index == null)
                {
                    // This is likely an indirect call like a C++
                    // vtable dispatch. Since these are common, we don't
                    // spam the user with warnings.
                    return(null);
                }

                // We have a jump table, and we've guessed the index expression.
                // At this point we've given up on knowing the exact size
                // of the table, but we do know that it must be at least
                // more than one entry. The safest assumption is that it
                // has two entries.
                listener.Warn(
                    listener.CreateAddressNavigator(host.Program, addrSwitch),
                    "Unable to determine size of call or jump table; there may be more than 2 entries.");
                ctx.Add(index, new IntervalValueSet(index.DataType, StridedInterval.Create(1, 0, 1)));
            }
            else if (interval.IsEmpty)
            {
                return(null);
            }
            else if (interval.High == Int64.MaxValue)
            {
                // We have no reasonable upper bound. We make the arbitrary
                // assumption that the jump table has 2 items; it wouldn't
                // make sense to be indexing otherwise.
                listener.Warn(
                    listener.CreateAddressNavigator(host.Program, addrSwitch),
                    "Unable to determine the upper bound of an indirect call or jump; there may be more than 2 entries.");
                var vs = new IntervalValueSet(
                    this.JumpTableIndex.DataType,
                    StridedInterval.Create(1, interval.Low, interval.Low + 1));
                ctx.Add(this.JumpTableIndexToUse, vs);
            }
            else
            {
                ctx.Add(this.JumpTableIndex, new IntervalValueSet(this.JumpTableIndex.DataType, interval));
            }
            var vse = new ValueSetEvaluator(host.Architecture, host.SegmentMap, ctx, this.processorState);

            var(values, accesses) = vse.Evaluate(jumpExpr);
            var vector = values.Values
                         .TakeWhile(c => c != Constant.Invalid)
                         .Take(2000)    // Arbitrary limit
                         .Select(ForceToAddress)
                         .TakeWhile(a => a != null)
                         .ToList();

            if (vector.Count == 0)
            {
                return(null);
            }
            return(new TableExtent
            {
                Targets = vector,
                Accesses = accesses,
                Index = index,
            });
        }
示例#11
0
 private ValueSet IVS(int stride, long low, long high)
 {
     return(new IntervalValueSet(PrimitiveType.Word32, StridedInterval.Create(stride, low, high)));
 }