Beispiel #1
0
 private bool IsTransfer(RtlInstructionCluster i, RtlInstruction r)
 {
     return r is RtlGoto || r is RtlCall;
 }
Beispiel #2
0
        /// <summary>
        /// Branches need to terminate the current basic block and make links
        /// to the 'true' and 'false' destinations.
        /// </summary>
        /// <param name="b"></param>
        /// <returns></returns>
        public bool VisitBranch(RtlBranch b)
        {
            // We don't know the 'then' block yet, as the following statements may chop up the block
            // we're presently in. Back-patch in when the block target is obtained.
            var branch = new Branch(b.Condition, new Block(blockCur.Procedure, "TMP!"));

            Emit(branch, blockCur);

            // The following statements may chop up the blockCur, so hang on to the essentials.
            var proc = blockCur.Procedure;
            RtlInstructionCluster ricDelayed = null;

            if ((b.Class & RtlClass.Delay) != 0)
            {
                rtlStream.MoveNext();
                ricDelayed = rtlStream.Current;
                ric        = ricDelayed;
            }
            var fallthruAddress = ric.Address + ric.Length;

            Block blockThen;

            if (!program.SegmentMap.IsValidAddress((Address)b.Target))
            {
                blockThen = proc.AddBlock(this.ric.Address.GenerateName("l", "_then"));
                var jmpSite = state.OnBeforeCall(stackReg, arch.PointerType.Size);
                GenerateCallToOutsideProcedure(jmpSite, (Address)b.Target);
                Emit(new ReturnInstruction());
                blockCur.Procedure.ControlGraph.AddEdge(blockCur, blockCur.Procedure.ExitBlock);
            }
            else
            {
                blockThen = BlockFromAddress(ric.Address, (Address)b.Target, proc, state.Clone());
            }

            var blockElse      = FallthroughBlock(ric.Address, proc, fallthruAddress);
            var branchingBlock = blockCur.IsSynthesized
                ? blockCur
                : scanner.FindContainingBlock(ric.Address);

            if ((b.Class & RtlClass.Delay) != 0 &&
                ricDelayed.Instructions.Length > 0)
            {
                // Introduce stubs for the delay slot, but only
                // if the delay slot isn't empty.

                if ((b.Class & RtlClass.Annul) != 0)
                {
                    EnsureEdge(proc, branchingBlock, blockElse);
                }
                else
                {
                    Block blockDsF = null;
                    blockDsF = proc.AddBlock(branchingBlock.Name + "_ds_f");
                    blockDsF.IsSynthesized = true;
                    blockCur = blockDsF;
                    ProcessRtlCluster(ricDelayed);
                    EnsureEdge(proc, blockDsF, blockElse);
                    EnsureEdge(proc, branchingBlock, blockDsF);
                }

                Block blockDsT = proc.AddBlock(branchingBlock.Name + "_ds_t");
                blockDsT.IsSynthesized = true;
                blockCur = blockDsT;
                ProcessRtlCluster(ricDelayed);
                EnsureEdge(proc, blockDsT, blockThen);
                branch.Target = blockDsT;
                EnsureEdge(proc, branchingBlock, blockDsT);
            }
            else
            {
                branch.Target = blockThen;      // The back-patch referred to above.
                EnsureEdge(proc, branchingBlock, blockElse);
                if (blockElse != blockThen)
                {
                    EnsureEdge(proc, branchingBlock, blockThen);
                }
                else
                {
                    proc.ControlGraph.AddEdge(branchingBlock, blockThen);
                }
            }
            if (BlockHasBeenScanned(blockElse))
            {
                return(false);
            }
            else
            {
                blockCur = blockElse;
                return(true);
            }
        }
Beispiel #3
0
 public CodePatch(RtlInstructionCluster cluster)
 {
     this.Code = cluster;
 }
Beispiel #4
0
        /// <summary>
        /// Branches need to terminate the current basic block and make links
        /// to the 'true' and 'false' destinations.
        /// </summary>
        /// <param name="b"></param>
        /// <returns></returns>
        public bool VisitBranch(RtlBranch b)
        {
            // We don't know the 'then' block yet, as the following statements may chop up the block
            // we're presently in. Back-patch in when the block target is obtained.
            var branch = new Branch(b.Condition, new Block(blockCur.Procedure, "TMP!"));

            // The following statements may chop up the blockCur, so hang on to the essentials.
            var proc = blockCur.Procedure;
            RtlInstructionCluster ricDelayed = null;

            if ((b.Class & RtlClass.Delay) != 0)
            {
                rtlStream.MoveNext();
                ricDelayed = rtlStream.Current;
                ric        = ricDelayed;
            }
            var fallthruAddress = ric.Address + ric.Length;

            var blockThen = BlockFromAddress(ric.Address, b.Target, proc, state.Clone());

            var blockElse      = FallthroughBlock(ric.Address, proc, fallthruAddress);
            var branchingBlock = scanner.FindContainingBlock(ric.Address);

            Emit(branch, branchingBlock);

            if ((b.Class & RtlClass.Delay) != 0 &&
                ricDelayed.Instructions.Count > 0)
            {
                // Introduce stubs for the delay slot, but only
                // if the delay slot isn't empty.

                if ((b.Class & RtlClass.Annul) != 0)
                {
                    EnsureEdge(proc, branchingBlock, blockElse);
                }
                else
                {
                    Block blockDsF = null;
                    blockDsF = proc.AddBlock(branchingBlock.Name + "_ds_f");
                    blockDsF.IsSynthesized = true;
                    blockCur = blockDsF;
                    ProcessRtlCluster(ricDelayed);
                    EnsureEdge(proc, blockDsF, blockElse);
                    EnsureEdge(proc, branchingBlock, blockDsF);
                }

                Block blockDsT = proc.AddBlock(branchingBlock.Name + "_ds_t");
                blockDsT.IsSynthesized = true;
                blockCur = blockDsT;
                ProcessRtlCluster(ricDelayed);
                EnsureEdge(proc, blockDsT, blockThen);
                branch.Target = blockDsT;
                EnsureEdge(proc, branchingBlock, blockDsT);
            }
            else
            {
                branch.Target = blockThen;      // The back-patch referred to above.
                EnsureEdge(proc, branchingBlock, blockElse);
                EnsureEdge(proc, branchingBlock, blockThen);
            }

            // Now, switch to the fallthru block and keep rewriting.
            blockCur = blockElse;
            return(!blockElse.IsSynthesized);
        }
Beispiel #5
0
 private bool IsTransfer(RtlInstructionCluster i, RtlInstruction r)
 {
     return(r is RtlGoto || r is RtlCall);
 }