Пример #1
0
        // 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);
            }
        }
Пример #2
0
        // insert the given new target basic block between the given conditional branch to manipulate
        public void insertBasicBlockBetweenBranch(ConditionalBranchTarget branchToManipulate, bool manipulateTakenBranch, 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 = null;

            // check wether to use the taken or not taken part of the exit branch
            if (useTakenBranch)
            {
                // check wether to manipulate the taken or not taken branch of the branch to manipulate
                if (manipulateTakenBranch)
                {
                    outroBasicBlock = branchToManipulate.takenTarget;
                    this.insertBasicBlockBetweenBranch(introBasicBlock, outroBasicBlock, branchToManipulate, ref branchToManipulate.takenTarget, newTarget, newTarget, exitBranch, ref exitBranch.takenTarget);
                }
                else
                {
                    outroBasicBlock = branchToManipulate.notTakenTarget;
                    this.insertBasicBlockBetweenBranch(introBasicBlock, outroBasicBlock, branchToManipulate, ref branchToManipulate.notTakenTarget, newTarget, newTarget, exitBranch, ref exitBranch.takenTarget);
                }
            }
            else
            {
                // check wether to manipulate the taken or not taken branch of the branch to manipulate
                if (manipulateTakenBranch)
                {
                    outroBasicBlock = branchToManipulate.takenTarget;
                    this.insertBasicBlockBetweenBranch(introBasicBlock, outroBasicBlock, branchToManipulate, ref branchToManipulate.takenTarget, newTarget, newTarget, exitBranch, ref exitBranch.notTakenTarget);
                }
                else
                {
                    outroBasicBlock = branchToManipulate.notTakenTarget;
                    this.insertBasicBlockBetweenBranch(introBasicBlock, outroBasicBlock, branchToManipulate, ref branchToManipulate.notTakenTarget, newTarget, newTarget, exitBranch, ref exitBranch.notTakenTarget);
                }
            }
        }
Пример #3
0
        // insert the given new target basic block between the given conditional branch to manipulate
        public void insertBasicBlockBetweenBranch(ConditionalBranchTarget branchToManipulate, bool manipulateTakenBranch, 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 = null;

            // check wether to manipulate the taken or not taken branch of the branch to manipulate
            if (manipulateTakenBranch)
            {
                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;
            }
            else
            {
                BasicBlock tempTakenTarget = null;
                outroBasicBlock = branchToManipulate.notTakenTarget;
                this.insertBasicBlockBetweenBranch(introBasicBlock, outroBasicBlock, branchToManipulate, ref branchToManipulate.notTakenTarget, 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;
            }
        }
Пример #4
0
        // insert the given new target basic block between the given switch branch to manipulate
        public void insertBasicBlockBetweenBranch(SwitchBranchTarget branchToManipulate, int manipulateTakenBranchIdx, 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 = null;

            // check wether to use the taken or not taken part of the exit branch
            if (useTakenBranch)
            {
                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;
            }
            else
            {
                outroBasicBlock = branchToManipulate.takenTarget.ElementAt(manipulateTakenBranchIdx);
                BasicBlock tempTakenTarget = null;

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

                branchToManipulate.takenTarget[manipulateTakenBranchIdx] = tempTakenTarget;
            }
        }
Пример #5
0
        // 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);
            }
        }