Exemplo n.º 1
0
        private void FindUseOfFunctionPointers(InstrumentationRegion region, int regionIndex,
                                               IdentifierExpr constant, HashSet <InstrumentationRegion> alreadyFound)
        {
            if (alreadyFound.Contains(region))
            {
                return;
            }
            alreadyFound.Add(region);

            var id = region.Implementation().InParams[regionIndex];

            if (region.FunctionPointers.Contains(id))
            {
                return;
            }
            region.FunctionPointers.Add(id);

            foreach (var block in region.Blocks())
            {
                for (int idx = 0; idx < block.Cmds.Count; idx++)
                {
                    if (!(block.Cmds[idx] is CallCmd))
                    {
                        continue;
                    }

                    var call         = block.Cmds[idx] as CallCmd;
                    var calleeRegion = this.AC.InstrumentationRegions.Find(val =>
                                                                           val.Implementation().Name.Equals(call.callee));
                    if (calleeRegion == null)
                    {
                        continue;
                    }

                    var indexes = new HashSet <int>();
                    for (int i = 0; i < call.Ins.Count; i++)
                    {
                        if (!(call.Ins[i] is IdentifierExpr))
                        {
                            continue;
                        }

                        if (id.Name.Equals((call.Ins[i] as IdentifierExpr).Name))
                        {
                            indexes.Add(i);
                        }
                    }

                    if (indexes.Count == 0)
                    {
                        continue;
                    }

                    foreach (var index in indexes)
                    {
                        this.FindUseOfFunctionPointers(calleeRegion, index, constant, alreadyFound);
                    }
                }
            }
        }
Exemplo n.º 2
0
 private void CleanUpRegion(InstrumentationRegion region)
 {
     region.Implementation().Proc.Modifies.RemoveAll(val =>
                                                     val.Name.Contains("_in_LS_$M.") ||
                                                     val.Name.StartsWith("WRITTEN_$M.") ||
                                                     val.Name.StartsWith("READ_$M."));
 }
Exemplo n.º 3
0
        protected void SliceRegion(InstrumentationRegion region)
        {
            foreach (var write in region.HasWriteAccess)
            {
                if (!this.EP.HasWriteAccess.ContainsKey(write.Key))
                {
                    continue;
                }
                this.EP.HasWriteAccess[write.Key] = this.EP.HasWriteAccess[write.Key] - write.Value;
                if (this.EP.HasWriteAccess[write.Key] <= 0)
                {
                    this.EP.HasWriteAccess.Remove(write.Key);
                }
            }

            foreach (var read in region.HasReadAccess)
            {
                if (!this.EP.HasReadAccess.ContainsKey(read.Key))
                {
                    continue;
                }
                this.EP.HasReadAccess[read.Key] = this.EP.HasReadAccess[read.Key] - read.Value;
                if (this.EP.HasReadAccess[read.Key] <= 0)
                {
                    this.EP.HasReadAccess.Remove(read.Key);
                }
            }

            this.AC.TopLevelDeclarations.RemoveAll(val =>
                                                   (val is Procedure && (val as Procedure).Name.Equals(region.Implementation().Name)) ||
                                                   (val is Implementation && (val as Implementation).Name.Equals(region.Implementation().Name)) ||
                                                   (val is Constant && (val as Constant).Name.Equals(region.Implementation().Name)));
            this.AC.InstrumentationRegions.Remove(region);
            this.EP.CallGraph.Remove(region);
        }
Exemplo n.º 4
0
 private void CleanUpReadInRegion(InstrumentationRegion region)
 {
     region.Implementation().Proc.Modifies.RemoveAll(val =>
                                                     val.Name.StartsWith("READ_$M."));
 }
Exemplo n.º 5
0
 private void CleanUpWriteInRegion(InstrumentationRegion region)
 {
     region.Implementation().Proc.Modifies.RemoveAll(val =>
                                                     val.Name.StartsWith("WRITTEN_$M."));
 }
Exemplo n.º 6
0
        private bool IdentifyCallAccessesInRegion(InstrumentationRegion region)
        {
            int numberOfCalls           = 0;
            int numberOfNonCheckedCalls = 0;

            foreach (var block in region.Implementation().Blocks)
            {
                for (int idx = 0; idx < block.Cmds.Count; idx++)
                {
                    if (!(block.Cmds[idx] is CallCmd))
                    {
                        continue;
                    }

                    var  call = block.Cmds[idx] as CallCmd;
                    bool isInstrumentedCall = false;

                    if (idx + 1 < block.Cmds.Count && block.Cmds[idx + 1] is AssumeCmd)
                    {
                        isInstrumentedCall = QKeyValue.FindStringAttribute((block.Cmds[idx + 1]
                                                                            as AssumeCmd).Attributes, "captureState") != null;
                    }

                    if (!isInstrumentedCall)
                    {
                        numberOfCalls++;

                        var calleeRegion = this.AC.InstrumentationRegions.Find(val =>
                                                                               val.Implementation().Name.Equals(call.callee));
                        if (calleeRegion == null)
                        {
                            numberOfNonCheckedCalls++;
                            continue;
                        }

                        if (calleeRegion.GetResourceAccesses().Count == 0 &&
                            calleeRegion.IsNotAccessingResources)
                        {
                            numberOfNonCheckedCalls++;
                            continue;
                        }

                        if (!region.CallInformation.ContainsKey(call))
                        {
                            region.CallInformation.Add(call, new Dictionary <int, Tuple <Expr, Expr> >());
                            region.ExternallyReceivedAccesses.Add(call, new Dictionary <string, HashSet <Expr> >());

                            for (int i = 0; i < call.Ins.Count; i++)
                            {
                                var id = calleeRegion.Implementation().InParams[i];

                                HashSet <Expr> ptrExprs = null;
                                this.PtrAnalysisCache[region].TryComputeRootPointers(call.Ins[i], out ptrExprs);
                                foreach (var ptrExpr in ptrExprs)
                                {
                                    region.CallInformation[call].Add(i, new Tuple <Expr, Expr>(ptrExpr, new IdentifierExpr(id.tok, id)));
                                    break;
                                }
                            }
                        }
                    }
                }
            }

            if (numberOfCalls == numberOfNonCheckedCalls &&
                region.HasWriteAccess.Count == 0 &&
                this.EP.ForceWriteResource.Count == 0)
            {
                this.CleanUpWriteInRegion(region);
                region.IsNotWriteAccessingResources = true;
            }

            if (numberOfCalls == numberOfNonCheckedCalls &&
                region.HasReadAccess.Count == 0 &&
                this.EP.ForceReadResource.Count == 0)
            {
                this.CleanUpReadInRegion(region);
                region.IsNotReadAccessingResources = true;
            }

            if (numberOfCalls == numberOfNonCheckedCalls &&
                region.GetResourceAccesses().Count == 0 &&
                this.EP.ForceWriteResource.Count == 0 &&
                this.EP.ForceReadResource.Count == 0)
            {
                this.CleanUpRegion(region);
                region.IsNotAccessingResources = true;
                return(false);
            }

            return(true);
        }
Exemplo n.º 7
0
        private void AnalyseLocalAccessesInRegion(InstrumentationRegion region)
        {
            foreach (var block in region.Implementation().Blocks)
            {
                for (int idx = 0; idx < block.Cmds.Count; idx++)
                {
                    if (!(block.Cmds[idx] is CallCmd))
                    {
                        continue;
                    }

                    var    call = block.Cmds[idx] as CallCmd;
                    bool   isInstrumentedCall = false;
                    string resource           = null;
                    string accessType         = null;

                    if (idx + 1 < block.Cmds.Count && block.Cmds[idx + 1] is AssumeCmd)
                    {
                        isInstrumentedCall = QKeyValue.FindStringAttribute((block.Cmds[idx + 1]
                                                                            as AssumeCmd).Attributes, "captureState") != null;
                        resource = QKeyValue.FindStringAttribute((block.Cmds[idx + 1]
                                                                  as AssumeCmd).Attributes, "resource");
                        accessType = QKeyValue.FindStringAttribute((block.Cmds[idx + 1]
                                                                    as AssumeCmd).Attributes, "access");
                    }

                    if (isInstrumentedCall && resource != null && accessType != null)
                    {
                        if ((this.EP.ForceWriteResource.Contains(resource) && accessType.Equals("write")) ||
                            (this.EP.ForceReadResource.Contains(resource) && accessType.Equals("read")))
                        {
                            continue;
                        }

                        if (call.Ins.Count == 0)
                        {
                            region.TryAddLocalResourceAccess(resource, new LiteralExpr(Token.NoToken, BigNum.FromInt(0)));
                            continue;
                        }

                        HashSet <Expr> ptrExprs = null;
                        var            result   = this.PtrAnalysisCache[region].TryComputeRootPointers(call.Ins[0], out ptrExprs);
                        foreach (var ptrExpr in ptrExprs)
                        {
                            var id = this.PtrAnalysisCache[region].GetIdentifier(ptrExpr);
                            if (result == PointerArithmeticAnalyser.ResultType.Const)
                            {
                                region.TryAddLocalResourceAccess(resource, ptrExpr);
                            }
                            else if (!WhoopCommandLineOptions.Get().CheckInParamAliasing&&
                                     region.FunctionPointers.Any(val => val.Name.Equals(id.Name)))
                            {
                                call.callee = "_NO_OP_$" + this.EP.Name;
                                call.Ins.Clear();
                                call.Outs.Clear();
                            }
                            else if (this.PtrAnalysisCache[region].IsAxiom(id))
                            {
                                if (!this.AC.AxiomAccessesMap.ContainsKey(resource))
                                {
                                    this.AC.AxiomAccessesMap.Add(resource, new HashSet <Expr>());
                                }
                                if (!this.AC.AxiomAccessesMap[resource].Any(val =>
                                                                            val.ToString().Equals(ptrExpr.ToString())))
                                {
                                    this.AC.AxiomAccessesMap[resource].Add(ptrExpr);
                                }
                                region.TryAddLocalResourceAccess(resource, ptrExpr);
                            }
                            else
                            {
                                region.TryAddLocalResourceAccess(resource, ptrExpr);
                            }
                        }

                        if (ptrExprs.Count == 0 && accessType.Equals("write"))
                        {
                            this.EP.ForceWriteResource.Add(resource);
                        }
                        else if (ptrExprs.Count == 0 && accessType.Equals("read"))
                        {
                            this.EP.ForceReadResource.Add(resource);
                        }
                    }
                }
            }
        }
Exemplo n.º 8
0
        private void AnalyseDomainSpecificEnableUsage(string type)
        {
            if ((type.Equals("register_netdev") || type.Equals("misc_register") ||
                 type.Equals("nfc_register_device")) &&
                this.DeviceRegisterRegion == null)
            {
                return;
            }
            if (type.Equals("network") && this.NetworkEnableRegion == null)
            {
                return;
            }

            InstrumentationRegion hotRegion = null;

            if (type.Equals("register_netdev") || type.Equals("misc_register") ||
                type.Equals("nfc_register_device"))
            {
                hotRegion = this.DeviceRegisterRegion;
            }
            if (type.Equals("network"))
            {
                hotRegion = this.NetworkEnableRegion;
            }

            var predecessorCallees = new HashSet <InstrumentationRegion>();
            var successorCallees   = new HashSet <InstrumentationRegion>();

            if (type.Equals("register_netdev") || type.Equals("misc_register") ||
                type.Equals("nfc_register_device"))
            {
                this.AnalyseBlocksForDeviceRegisterRegion(hotRegion, true,
                                                          predecessorCallees, successorCallees);
            }

            var  checkedPredecessors = new HashSet <InstrumentationRegion>();
            bool foundCall           = false;

            var predecessors = this.EP.CallGraph.Predecessors(hotRegion);

            while (predecessors.Count > 0)
            {
                var newPredecessors = new HashSet <InstrumentationRegion>();
                foreach (var pred in predecessors)
                {
                    if (checkedPredecessors.Contains(pred))
                    {
                        continue;
                    }

                    checkedPredecessors.Add(pred);

                    foreach (var block in pred.Blocks())
                    {
                        foreach (var call in block.Cmds.OfType <CallCmd>())
                        {
                            if (!foundCall && call.callee.Equals(hotRegion.Implementation().Name))
                            {
                                foundCall = true;
                            }

                            var region = this.AC.InstrumentationRegions.Find(val =>
                                                                             val.Name().Equals(call.callee + "$instrumented"));
                            if (region == null)
                            {
                                continue;
                            }

                            if (foundCall && !predecessorCallees.Contains(region))
                            {
                                successorCallees.Add(region);
                            }
                            else
                            {
                                predecessorCallees.Add(region);
                            }
                        }
                    }

                    foreach (var nestedPred in this.EP.CallGraph.Predecessors(pred))
                    {
                        if (!checkedPredecessors.Contains(nestedPred))
                        {
                            newPredecessors.Add(nestedPred);
                        }
                    }

                    foundCall = false;
                }

                predecessors.Clear();
                predecessors = checkedPredecessors;
            }

            var successors = this.EP.CallGraph.NestedSuccessors(hotRegion);

            successorCallees.UnionWith(successors);
            predecessorCallees.RemoveWhere(val => successorCallees.Contains(val));

            foreach (var pred in predecessorCallees.ToList())
            {
                var succs = this.EP.CallGraph.NestedSuccessors(pred);
                succs.RemoveWhere(val => successorCallees.Contains(val));
                predecessorCallees.UnionWith(succs);
            }

            foreach (var pred in predecessorCallees)
            {
                if (pred.Equals(hotRegion))
                {
                    continue;
                }
                if (type.Equals("register_netdev") || type.Equals("misc_register") ||
                    type.Equals("nfc_register_device"))
                {
                    pred.IsDeviceRegistered = false;
                }
                if (type.Equals("network"))
                {
                    pred.IsDisablingNetwork = true;
                }
            }

            foreach (var succ in successorCallees)
            {
                if (succ.Equals(hotRegion))
                {
                    continue;
                }
                if (type.Equals("network"))
                {
                    succ.IsEnablingNetwork = true;
                }
            }
        }
Exemplo n.º 9
0
        private void InstrumentRaceCheckingCaptureStates(InstrumentationRegion region)
        {
            if (region.Implementation().Name.Equals(this.EP.Name))
            {
                AssumeCmd assumeLogHead = new AssumeCmd(Token.NoToken, Expr.True);
                assumeLogHead.Attributes = new QKeyValue(Token.NoToken, "captureState",
                                                         new List <object>()
                {
                    this.EP.Name + "_header_state"
                }, assumeLogHead.Attributes);
                region.Header().Cmds.Add(assumeLogHead);
            }

            foreach (var b in region.Blocks())
            {
                List <Cmd> newCmds = new List <Cmd>();

                foreach (var c in b.Cmds)
                {
                    if (!(c is CallCmd))
                    {
                        newCmds.Add(c);
                        continue;
                    }

                    CallCmd call = c as CallCmd;

                    if (!(call.callee.Contains("_WRITE_LS_") ||
                          call.callee.Contains("_READ_LS_")))
                    {
                        newCmds.Add(call);
                        continue;
                    }

                    AssumeCmd assume = new AssumeCmd(Token.NoToken, Expr.True);

                    assume.Attributes = new QKeyValue(Token.NoToken, "column",
                                                      new List <object>()
                    {
                        new LiteralExpr(Token.NoToken,
                                        BigNum.FromInt(QKeyValue.FindIntAttribute(call.Attributes, "column", -1)))
                    }, null);
                    assume.Attributes = new QKeyValue(Token.NoToken, "line",
                                                      new List <object>()
                    {
                        new LiteralExpr(Token.NoToken,
                                        BigNum.FromInt(QKeyValue.FindIntAttribute(call.Attributes, "line", -1)))
                    }, assume.Attributes);

                    if (call.callee.Contains("WRITE"))
                    {
                        assume.Attributes = new QKeyValue(Token.NoToken, "access",
                                                          new List <object>()
                        {
                            "write"
                        }, assume.Attributes);
                    }
                    else if (call.callee.Contains("READ"))
                    {
                        assume.Attributes = new QKeyValue(Token.NoToken, "access",
                                                          new List <object>()
                        {
                            "read"
                        }, assume.Attributes);
                    }

                    assume.Attributes = new QKeyValue(Token.NoToken, "entrypoint",
                                                      new List <object>()
                    {
                        this.EP.Name
                    }, assume.Attributes);

                    assume.Attributes = new QKeyValue(Token.NoToken, "captureState",
                                                      new List <object>()
                    {
                        "access_state_" + this.LogCounter++
                    }, assume.Attributes);

                    assume.Attributes = new QKeyValue(Token.NoToken, "resource",
                                                      new List <object>()
                    {
                        "$" + call.callee.Split(new char[] { '$', '_' })[4]
                    }, assume.Attributes);

                    newCmds.Add(call);
                    newCmds.Add(assume);
                }

                b.Cmds = newCmds;
            }
        }
Exemplo n.º 10
0
        private bool InstrumentAssumes(InstrumentationRegion checkRegion, IdentifierExpr id1,
                                       IdentifierExpr id2, LiteralExpr num1, LiteralExpr num2)
        {
            foreach (var region in this.AC.InstrumentationRegions)
            {
                if (region.IsNotAccessingResources)
                {
                    continue;
                }
                if (!region.CallInformation.Any(val => val.Key.callee.Equals(checkRegion.Implementation().Name)))
                {
                    continue;
                }

                foreach (var block in region.Blocks())
                {
                    for (int idx = 0; idx < block.Cmds.Count; idx++)
                    {
                        if (!(block.Cmds[idx] is CallCmd))
                        {
                            continue;
                        }

                        var call = block.Cmds[idx] as CallCmd;
                        if (!call.callee.Equals(checkRegion.Implementation().Name))
                        {
                            continue;
                        }

                        IdentifierExpr callId1 = null;
                        IdentifierExpr callId2 = null;

                        for (int i = 0; i < call.Ins.Count; i++)
                        {
                            if (!(call.Ins[i] is IdentifierExpr))
                            {
                                continue;
                            }
                            if (checkRegion.Implementation().InParams[i].Name.Equals(id1.Name))
                            {
                                callId1 = call.Ins[i] as IdentifierExpr;
                            }
                            else if (checkRegion.Implementation().InParams[i].Name.Equals(id2.Name))
                            {
                                callId2 = call.Ins[i] as IdentifierExpr;
                            }
                        }

                        if (callId1 == null || callId2 == null)
                        {
                            continue;
                        }

                        if (callId1 != null && !this.AC.TopLevelDeclarations.OfType <Constant>().Any(val =>
                                                                                                     val.Name.Equals(callId1.Name)) && !region.Implementation().InParams.Exists(val =>
                                                                                                                                                                                val.Name.Equals(callId1.Name)))
                        {
                            HashSet <Expr> ptrExprs = null;
                            this.PtrAnalysisCache[region].TryComputeRootPointers(callId1, out ptrExprs);
                            if (ptrExprs.Count == 0)
                            {
                                return(false);
                            }
                        }

                        if (callId2 != null && !this.AC.TopLevelDeclarations.OfType <Constant>().Any(val =>
                                                                                                     val.Name.Equals(callId2.Name)) && !region.Implementation().InParams.Exists(val =>
                                                                                                                                                                                val.Name.Equals(callId2.Name)))
                        {
                            HashSet <Expr> ptrExprs = null;
                            this.PtrAnalysisCache[region].TryComputeRootPointers(callId2, out ptrExprs);
                            if (ptrExprs.Count == 0)
                            {
                                return(false);
                            }
                        }

                        Expr lexpr = Expr.Lt(new NAryExpr(Token.NoToken, new BinaryOperator(Token.NoToken,
                                                                                            BinaryOperator.Opcode.Add), new List <Expr> {
                            callId1, num1
                        }), callId2);
                        Expr rexpr = Expr.Lt(new NAryExpr(Token.NoToken, new BinaryOperator(Token.NoToken,
                                                                                            BinaryOperator.Opcode.Add), new List <Expr> {
                            callId2, num2
                        }), callId1);

                        var assume = new AssumeCmd(Token.NoToken, Expr.Or(lexpr, rexpr));

                        if (!this.AssumesMap.ContainsKey(region))
                        {
                            this.AssumesMap.Add(region, new Dictionary <Block, HashSet <Tuple <AssumeCmd, int> > >());
                        }
                        if (!this.AssumesMap[region].ContainsKey(block))
                        {
                            this.AssumesMap[region].Add(block, new HashSet <Tuple <AssumeCmd, int> >());
                        }
                        this.AssumesMap[region][block].Add(new Tuple <AssumeCmd, int>(assume, idx));
                    }
                }
            }

            return(true);
        }