Ejemplo n.º 1
0
 /// <summary>
 /// Returns a list of AggregateField objects, each of which represents
 /// the aggregate fields that the input aggregate access overlaps.
 /// </summary>
 ///
 /// <param name="aggregateExpr">Expression that represents the aggregate
 /// that is being accessed.</param>
 /// <param name="offset">Offset of the access from the start of the aggregate,
 /// in bits.</param>
 /// <param name="accessType">Type of the aggregate access.</param>
 /// <param name="getArrayElements">True if, and only if, the elements of
 /// a fixed-size array should be treated as separate fields of the aggregate.</param>
 /// <param name="path">Path that contains the aggregate.</param>
 /// <returns>List of AggregateField objects, each of which represents
 /// the aggregate fields that the input aggregate access overlaps.</returns>
 public static List <AggregateField> GetAggregateFields(Expression aggregateExpr,
                                                        int offset, Phx.Types.Type accessType, bool getArrayElements, Path path)
 {
     return(PhoenixHelper.GetAggregateFieldsHelper(aggregateExpr.Type.AsAggregateType,
                                                   offset, accessType, (int)accessType.BitSize, getArrayElements,
                                                   aggregateExpr.Clone(), path));
 }
Ejemplo n.º 2
0
        /// <summary>
        /// Returns a variable Expression with the input value, which represents the variable
        /// corresponding to the input operand.
        /// </summary>
        ///
        /// <param name="operand">Operand for the variable Expression.</param>
        /// <param name="value">Value of the variable Expression.</param>
        /// <param name="path">Path that contains the operand.</param>
        /// <returns>Variable Expression with value <paramref name="value"/>,
        /// which represents the operand <paramref name="operand"/>.</returns>
        public static Expression MakeVariableExpression(Phx.IR.Operand operand,
                                                        string value, Path path)
        {
            uint       nativeWordBitSize = path.Config.WORD_BITSIZE;
            Expression result            = null;

            /* Find the type of this variable, if the operand is not an address, or
             * the type of the variable the operand refers to, otherwise. */
            Phx.Types.Type variableType = operand.IsAddress ?
                                          operand.Type.AsPointerType.ReferentType : operand.Type;
            /* Add an identifier to the names of aggregate objects. */
            value = variableType.IsAggregateType ? path.Config.IDENT_AGGREGATE + value : value;

            result = ExpressionHelper.IsPointerExpressionType(variableType) ?
                     new Expression(OperatorStore.ArrayVariableOp, value, nativeWordBitSize) :
                     new Expression(OperatorStore.VariableOp, value,
                                    operand.IsAggregate ? nativeWordBitSize : operand.BitSize);
            result.Type = variableType;

            /* Replace a pointer Expression with the corresponding "dereferencing function". */
            result = ExpressionHelper.IsPointerExpression(result) ?
                     ExpressionHelper.MakeDereferencingFunction(result, path) : result;

            /* If the operand uses the address of an existing variable, determine if there
             * is already a temporary pointer that points to this "address-taken" variable.
             * If not, make a new temporary pointer that points to this variable. */
            if (operand.IsAddress)
            {
                if (path.AddressTaken.ContainsKey(result))
                {
                    result = path.AddressTaken[result].Clone();
                }
                else
                {
                    Phx.Types.Type referentType =
                        ExpressionHelper.GetPointerReferentType(operand.Type);

                    /* Determine the basic block that contains the operand and the associated
                     * information. */
                    BasicBlock         operandBasicBlock         = operand.Instruction.BasicBlock;
                    BasicBlockAddendum operandBasicBlockAddendum =
                        operandBasicBlock.FindExtensionObject(typeof(BasicBlockAddendum))
                        as BasicBlockAddendum;

                    /* Generate a new temporary pointer and log the relationship between
                     * the temporary pointer and the "address-taken" variable. */
                    Expression newTempPtr = path.GetNewTemporaryPointer(operand.Type);
                    path.AddressTaken[result] = newTempPtr;

                    /* Generate and log the assignment between the dereferenced temporary pointer
                     * and the "address-taken" variable. This way, the generated SMT queries will
                     * never have to use the Address-Of operator. */
                    Expression dereferencedNewTempPtr =
                        ExpressionHelper.DereferencePointer(newTempPtr, operand.Type,
                                                            false, path);
                    List <Expression> assignExprs =
                        path.GenerateAndLogAssignment(dereferencedNewTempPtr, result,
                                                      operandBasicBlock);

                    /* Add the conditional Expressions that correspond to this new assignment. */
                    foreach (Expression assignExpr in assignExprs)
                    {
                        path.AddCondition(assignExpr, operandBasicBlock.Id);
                    }

                    result = newTempPtr;
                }
            }

            /* If the variable is an "address-taken" variable, which means that its address
             * has been taken before, then we replace the variable with a dereference of
             * the temporary pointer that refers to the variable. */
            if (path.AddressTaken.ContainsKey(result))
            {
                result = ExpressionHelper.DereferencePointer(path.AddressTaken[result],
                                                             operand.Type, false, path);
            }

            path.AddVariable(result);
            return(result);
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Recursive workhorse method for the method <see cref="GetAggregateFields"/>.
        /// </summary>
        ///
        /// <param name="aggregateType">Type of the aggregate that is being accessed.</param>
        /// <param name="offset">Offset of the access from the start of the aggregate,
        /// in bits.</param>
        /// <param name="accessType">Type of the aggregate access.</param>
        /// <param name="accessBitSize">Bit-size of the aggregate access.</param>
        /// <param name="getArrayElements">True if, and only if, the elements of
        /// a fixed-size array should be treated as separate fields of the aggregate.</param>
        /// <param name="accessSoFar">Expression that represents the access so far.</param>
        /// <param name="path">Path that contains the aggregate.</param>
        /// <returns>List of AggregateField objects, each of which represents
        /// the aggregate fields that the input aggregate access overlaps.</returns>
        private static List <AggregateField> GetAggregateFieldsHelper(AggregateType aggregateType,
                                                                      int offset, Phx.Types.Type accessType, int accessBitSize, bool getArrayElements,
                                                                      Expression accessSoFar, Path path)
        {
            Utilities.Configuration config = path.Config;
            List <AggregateField>   result = new List <AggregateField>();

            int         completedOffset    = 0;
            FieldSymbol currentFieldSymbol = aggregateType.FieldSymbolList;

            while (currentFieldSymbol != null)
            {
                /* Obtain the necessary information from the current field symbol. */
                string         fieldName        = currentFieldSymbol.ToString();
                int            fieldStartOffset = currentFieldSymbol.BitOffset;
                Phx.Types.Type fieldType        = currentFieldSymbol.Type;
                int            fieldEndOffset   = (fieldStartOffset + (int)fieldType.BitSize) - 1;

                /* Move to the next field symbol for the subsequent iteration. */
                currentFieldSymbol = currentFieldSymbol.NextFieldSymbol;
                if (fieldStartOffset < completedOffset)
                {
                    /* Skip this field if it starts at an offset in the part of
                     * the aggregate that has already been examined. */
                    continue;
                }
                else
                {
                    /* Move the completed offset pointer to the end of the field currently
                     * being examined. This indicates that, after this iteration
                     * is complete, the part of the aggregate prior to the pointer
                     * has already been examined. */
                    completedOffset = fieldEndOffset;
                }

                if (((offset <= fieldStartOffset) &&
                     (fieldStartOffset <= (offset + accessBitSize) - 1)) ||
                    ((offset > fieldStartOffset) && (offset <= fieldEndOffset)))
                {
                    /* Attach a unique identifier to each field name. */
                    string newFieldName = String.Format("{0}{1}{2}{3}",
                                                        config.IDENT_FIELD, fieldName,
                                                        config.IDENT_AGGREGATE, GetAggregateName(aggregateType));

                    /* Make an array variable Expression for the field, since we represent
                     * aggregate accesses as accesses into an array. */
                    Expression newArrayVar =
                        new Expression(OperatorStore.ArrayVariableOp, newFieldName);
                    newArrayVar.Type = Phx.Types.PointerType.New(aggregateType.TypeTable,
                                                                 Phx.Types.PointerTypeKind.UnmanagedPointer, path.Config.WORD_BITSIZE,
                                                                 fieldType, fieldType.TypeSymbol);
                    path.AddVariable(newArrayVar);

                    /* Convert the array variable Expression into the equivalent
                     * pointer Expression, represented as a dereferencing function. */
                    newArrayVar = ExpressionHelper.MakeDereferencingFunction(newArrayVar, path);

                    /* Apply the dereferencing function on the Expression generated so far. */
                    List <Expression> argExprs = new List <Expression>();
                    argExprs.Add(accessSoFar);
                    argExprs.Add(new Constant(0, config.WORD_BITSIZE));

                    Expression fieldAccessExpr =
                        ExpressionHelper.ApplyFunction(newArrayVar, argExprs, path);
                    fieldAccessExpr = ExpressionHelper.LookupAndReplaceOffset(fieldAccessExpr,
                                                                              fieldType, false, path);

                    if (fieldType.IsAggregateType)
                    {
                        /* Recurse into the field, if the field is itself an aggregate. */
                        AggregateType         innerAggregateType   = fieldType.AsAggregateType;
                        List <AggregateField> innerAggregateFields =
                            GetAggregateFieldsHelper(innerAggregateType,
                                                     Math.Max((offset - fieldStartOffset), 0),
                                                     accessType,
                                                     (accessBitSize - Math.Max(fieldStartOffset - offset, 0)),
                                                     getArrayElements, fieldAccessExpr, path);
                        foreach (AggregateField innerAggregateField in innerAggregateFields)
                        {
                            /* Include the offset of the field inside
                             * the enclosing aggregate type. */
                            innerAggregateField.StartOffset += fieldStartOffset;
                            result.Add(innerAggregateField);
                        }
                    }
                    else if (fieldType.IsUnmanagedArrayType &&
                             !ExpressionHelper.AreSameTypes(fieldType, accessType) &&
                             getArrayElements)
                    {
                        List <Pair <Expression, int> > arrayElements =
                            ExpressionHelper.GetArrayElementsInRange(fieldAccessExpr,
                                                                     Math.Max((offset - fieldStartOffset), 0),
                                                                     (accessBitSize - Math.Max(fieldStartOffset - offset, 0)),
                                                                     path);
                        foreach (Pair <Expression, int> arrayElementAndOffset in arrayElements)
                        {
                            Expression arrayElementExpr   = arrayElementAndOffset.First;
                            int        arrayElementOffset = arrayElementAndOffset.Second;

                            result.Add(new AggregateField(aggregateType,
                                                          arrayElementExpr, (fieldStartOffset + arrayElementOffset),
                                                          arrayElementExpr.BitSize));
                        }
                    }
                    else
                    {
                        result.Add(new AggregateField(aggregateType,
                                                      fieldAccessExpr, fieldStartOffset, fieldType.BitSize));
                    }
                }
            }

            Trace.Assert(result.Count > 0, "PHOENIX: Field(s) not found.");
            return(result);
        }