Example #1
0
        void createUnconditionalBranch(BasicBlock deadCodeBasicBlock, ITransformationMetadata basicBlockMetadata)
        {
            // Branch to some other basic block in our method (or to a newly created dead code block).
            var exitBranch = new UnconditionalBranchTarget();

            exitBranch.sourceBasicBlock   = deadCodeBasicBlock;
            deadCodeBasicBlock.exitBranch = exitBranch;

            deadCodeBasicBlock.operations.Add(createNewOperation(OperationCode.Br, 0));

            // TODO: Decrease possibility for dead code to be added?
            if (prng.Next(2) == 0)
            {
                // Random BB as dead code block target.
                var targetBlock = randomTargetBlock();

                targetBlock.entryBranches.Add(exitBranch);
                exitBranch.takenTarget = targetBlock;
            }
            else
            {
                // New dead code BB as dead code block target.
                var targetBlock = new BasicBlock();
                targetBlock.startIdx = targetBlock.endIdx = 0;

                targetBlock.entryBranches.Add(exitBranch);
                exitBranch.takenTarget = targetBlock;

                generateDeadCode(targetBlock, basicBlockMetadata);
            }
        }
        // insert the given new target basic block (given by start and end block) between the given unconditional branch to manipulate
        public void insertBasicBlockBetweenBranch(UnconditionalBranchTarget branchToManipulate, BasicBlock newTargetStart, BasicBlock newTargetEnd, UnconditionalBranchTarget exitBranch)
        {
            // get the basic block from that the branch is taken and the basic block to that the branch is taken
            BasicBlock introBasicBlock = branchToManipulate.sourceBasicBlock;
            BasicBlock outroBasicBlock = branchToManipulate.takenTarget;

            this.insertBasicBlockBetweenBranch(introBasicBlock, outroBasicBlock, branchToManipulate, ref branchToManipulate.takenTarget, newTargetStart, newTargetEnd, exitBranch, ref exitBranch.takenTarget);
        }
        // insert the given new target basic block between the given unconditional branch to manipulate
        public void insertBasicBlockBetweenBranch(UnconditionalBranchTarget branchToManipulate, BasicBlock newTarget, ConditionalBranchTarget exitBranch, bool useTakenBranch)
        {
            // get the basic block from that the branch is taken and the basic block to that the branch is taken
            BasicBlock introBasicBlock = branchToManipulate.sourceBasicBlock;
            BasicBlock outroBasicBlock = branchToManipulate.takenTarget;

            // check wether to use the taken or not taken part of the exit branch
            if (useTakenBranch)
            {
                this.insertBasicBlockBetweenBranch(introBasicBlock, outroBasicBlock, branchToManipulate, ref branchToManipulate.takenTarget, newTarget, newTarget, exitBranch, ref exitBranch.takenTarget);
            }
            else
            {
                this.insertBasicBlockBetweenBranch(introBasicBlock, outroBasicBlock, branchToManipulate, ref branchToManipulate.takenTarget, newTarget, newTarget, exitBranch, ref exitBranch.notTakenTarget);
            }
        }
        // insert the given new target basic block between the given conditional branch to manipulate
        public void insertBasicBlockBetweenBranch(UnconditionalBranchTarget branchToManipulate, BasicBlock newTarget, SwitchBranchTarget exitBranch, int switchTakenBranchIdx)
        {
            // get the basic block from that the branch is taken and the basic block to that the branch is taken
            BasicBlock introBasicBlock = branchToManipulate.sourceBasicBlock;
            BasicBlock outroBasicBlock = branchToManipulate.takenTarget;
            BasicBlock tempTakenTarget = null;

            this.insertBasicBlockBetweenBranch(introBasicBlock, outroBasicBlock, branchToManipulate, ref branchToManipulate.takenTarget, newTarget, newTarget, exitBranch, ref tempTakenTarget);

            // fill switch taken branch list with null when index is out of range
            while (exitBranch.takenTarget.Count() <= switchTakenBranchIdx)
            {
                exitBranch.takenTarget.Add(null);
            }

            exitBranch.takenTarget[switchTakenBranchIdx] = tempTakenTarget;
        }
Example #5
0
        private void mutateRet(BasicBlock block, int index)
        {
            if (prng.Next(3) == 0)
            {
                return;
            }

            var exitBranch = new UnconditionalBranchTarget();

            exitBranch.takenTarget      = returnBlock;
            exitBranch.sourceBasicBlock = block;

            block.exitBranch = exitBranch;
            returnBlock.entryBranches.Add(exitBranch);

            var branchToReturn = createNewOperation(OperationCode.Br, 0);

            block.operations[index] = branchToReturn;
            block.semanticId        = -1;
        }
        // ################################################### SWITCH BRANCHES TO MANIPULATE ###################################################


        // insert the given new target basic block between the given switch branch to manipulate
        public void insertBasicBlockBetweenBranch(SwitchBranchTarget branchToManipulate, int manipulateTakenBranchIdx, BasicBlock newTarget, UnconditionalBranchTarget exitBranch)
        {
            // get the basic block from that the branch is taken and the basic block to that the branch is taken
            BasicBlock introBasicBlock = branchToManipulate.sourceBasicBlock;
            BasicBlock outroBasicBlock = null;


            outroBasicBlock = branchToManipulate.takenTarget.ElementAt(manipulateTakenBranchIdx);
            BasicBlock tempTakenTarget = null;

            this.insertBasicBlockBetweenBranch(introBasicBlock, outroBasicBlock, branchToManipulate, ref tempTakenTarget, newTarget, newTarget, exitBranch, ref exitBranch.takenTarget);

            branchToManipulate.takenTarget[manipulateTakenBranchIdx] = tempTakenTarget;
        }
        // insert the given new target basic block (given by start and end block) between the given conditional branch to manipulate
        public void insertBasicBlockBetweenBranch(ConditionalBranchTarget branchToManipulate, bool manipulateTakenBranch, BasicBlock newTargetStart, BasicBlock newTargetEnd, UnconditionalBranchTarget exitBranch)
        {
            // get the basic block from that the branch is taken and the basic block to that the branch is taken
            BasicBlock introBasicBlock = branchToManipulate.sourceBasicBlock;
            BasicBlock outroBasicBlock = null;

            // manipulate the correct branch
            if (manipulateTakenBranch)
            {
                outroBasicBlock = branchToManipulate.takenTarget;
                this.insertBasicBlockBetweenBranch(introBasicBlock, outroBasicBlock, branchToManipulate, ref branchToManipulate.takenTarget, newTargetStart, newTargetEnd, exitBranch, ref exitBranch.takenTarget);
            }
            else
            {
                outroBasicBlock = branchToManipulate.notTakenTarget;
                this.insertBasicBlockBetweenBranch(introBasicBlock, outroBasicBlock, branchToManipulate, ref branchToManipulate.notTakenTarget, newTargetStart, newTargetEnd, exitBranch, ref exitBranch.takenTarget);
            }
        }
        // this function replaces a basic block inside the cfg (oldBasicBlock) with a construction of new basic blocks (newBasicBlockStart and newBasicBlockEnd)
        public void replaceBasicBlock(BasicBlock oldBasicBlock, BasicBlock newBasicBlockStart, BasicBlock newBasicBlockEnd)
        {
            // add new basic blocks to cfg
            this.addBasicBlockToCfgRecursively(newBasicBlockStart);


            // add entry branches that enter the old basic block to the new basic block
            newBasicBlockStart.entryBranches.AddRange(oldBasicBlock.entryBranches);

            // exchange the target of the entry branches from the old basic block to the new one
            foreach (IBranchTarget entryBranch in new List <IBranchTarget>(oldBasicBlock.entryBranches))
            {
                if ((entryBranch as NoBranchTarget) != null)
                {
                    NoBranchTarget tempEntryBranch = (entryBranch as NoBranchTarget);

                    // check sanity of entry branch
                    if (tempEntryBranch.takenTarget != oldBasicBlock)
                    {
                        throw new ArgumentException("Entry branch must have old basic block as target.");
                    }

                    // set new basic block as target
                    tempEntryBranch.takenTarget = newBasicBlockStart;
                }
                else if ((entryBranch as UnconditionalBranchTarget) != null)
                {
                    UnconditionalBranchTarget tempEntryBranch = (entryBranch as UnconditionalBranchTarget);

                    // check sanity of entry branch
                    if (tempEntryBranch.takenTarget != oldBasicBlock)
                    {
                        throw new ArgumentException("Entry branch must have old basic block as target.");
                    }

                    // set new basic block as target
                    tempEntryBranch.takenTarget = newBasicBlockStart;
                }
                else if ((entryBranch as ConditionalBranchTarget) != null)
                {
                    ConditionalBranchTarget tempEntryBranch = (entryBranch as ConditionalBranchTarget);
                    bool sanity = false;

                    // change all branches to the old basic block to the new basic block
                    if (tempEntryBranch.takenTarget == oldBasicBlock)
                    {
                        tempEntryBranch.takenTarget = newBasicBlockStart;
                        sanity = true;
                    }
                    if (tempEntryBranch.notTakenTarget == oldBasicBlock)
                    {
                        tempEntryBranch.notTakenTarget = newBasicBlockStart;
                        sanity = true;
                    }

                    // check sanity of entry branch
                    if (!sanity)
                    {
                        throw new ArgumentException("Entry branch must have old basic block as target.");
                    }
                }
                else if ((entryBranch as SwitchBranchTarget) != null)
                {
                    SwitchBranchTarget tempEntryBranch = (entryBranch as SwitchBranchTarget);
                    bool sanity = false;

                    // change all branches to the old basic block to the new basic block
                    if (tempEntryBranch.notTakenTarget == oldBasicBlock)
                    {
                        tempEntryBranch.notTakenTarget = newBasicBlockStart;
                        sanity = true;
                    }
                    for (int idx = 0; idx < tempEntryBranch.takenTarget.Count(); idx++)
                    {
                        if (tempEntryBranch.takenTarget.ElementAt(idx) == oldBasicBlock)
                        {
                            tempEntryBranch.takenTarget[idx] = newBasicBlockStart;
                            sanity = true;
                        }
                    }

                    // check sanity of entry branch
                    if (!sanity)
                    {
                        throw new ArgumentException("Entry branch must have old basic block as target.");
                    }
                }
                else
                {
                    throw new ArgumentException("Not yet implemented.");
                }

                // remove entry branch from the old basic block entry branches list
                oldBasicBlock.entryBranches.Remove(entryBranch);
            }


            IBranchTarget exitBranch = oldBasicBlock.exitBranch;

            // change the exit branch of the old basic block to be the exit branch of the new one
            exitBranch.sourceBasicBlock = newBasicBlockEnd;
            newBasicBlockEnd.exitBranch = exitBranch;


            // check if the old basic block was the start basic block of the cfg
            // => change it to the new basic block
            if (this.methodCfg.startBasicBlock == oldBasicBlock)
            {
                this.methodCfg.startBasicBlock = newBasicBlockStart;
            }

            // remove old basic block if it still belongs to the cfg
            if (this.methodCfg.basicBlocks.Contains(oldBasicBlock))
            {
                this.methodCfg.basicBlocks.Remove(oldBasicBlock);
            }
        }