コード例 #1
0
ファイル: ScannerTests.cs プロジェクト: fengjixuchui/reko
        public void Scanner_GlobalDataRecursiveStructs()
        {
            var bytes = new byte[] {
                0x17, 0x00, 0x21, 0x43, 0x00, 0x00, 0x21, 0x43,
                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
            };

            Given_Program(Address.Ptr32(0x43210000), bytes);
            Given_Project();

            var sc = new Scanner(
                this.program,
                project.LoadedMetadata,
                new DynamicLinker(project, program, eventListener),
                this.sc
                );

            var ft = Given_Serialized_Signature(new SerializedSignature
            {
                ReturnValue = new Argument_v1 {
                    Type = Real32()
                },
            });
            var str    = new StructureType();
            var fields = new StructureField[] {
                new StructureField(0, new Pointer(ft, 32), "func"),
                new StructureField(4, new Pointer(str, 32), "next"),
            };

            str.Fields.AddRange(fields);

            sc.EnqueueUserGlobalData(Address.Ptr32(0x43210000), str, null);
            sc.ScanImage();

            var sExpSig =
                @"FpuStack real32 fn43210017()
// stackDelta: 4; fpuStackDelta: 1; fpuMaxParam: -1
";

            Assert.AreEqual(1, program.Procedures.Count);
            Assert.AreEqual(sExpSig, program.Procedures[Address.Ptr32(0x43210017)].Signature.ToString("fn43210017", FunctionType.EmitFlags.AllDetails));
        }
コード例 #2
0
        public override void VisitConstant(Constant c)
        {
            DataType dt     = c.TypeVariable.DataType;
            int      offset = StructureField.ToOffset(c);
            Pointer  ptr    = dt as Pointer;

            if (ptr != null)
            {
                // C is a constant pointer.
                if (offset == 0)
                {
                    return;                                             // null pointer is null (//$REVIEW: except for some platforms + archs)
                }
                var pointee    = ptr.Pointee;
                var segPointee = pointee.ResolveAs <StructureType>();
                if (segPointee != null && segPointee.IsSegment)
                {
                    //$TODO: these are getting merged earlier, perhaps this is the right place to do those merges?
                    return;
                }
                var strGlobals = Globals.TypeVariable.Class.ResolveAs <StructureType>();
                if (strGlobals.Fields.AtOffset(offset) == null)
                {
                    if (!IsInsideArray(strGlobals, offset, pointee))
                    {
                        strGlobals.Fields.Add(offset, pointee);
                    }
                }
                return;
            }
            MemberPointer mptr = dt as MemberPointer;

            if (mptr != null)
            {
                // C is a constant offset into a segment.
                var seg = ((Pointer)mptr.BasePointer).Pointee.ResolveAs <StructureType>();
                if (seg != null && //$DEBUG
                    seg.Fields.AtOffset(offset) == null)
                {
                    seg.Fields.Add(offset, mptr.Pointee);
                }
//				VisitConstantMemberPointer(offset, mptr);
            }
        }
コード例 #3
0
        /// <summary>
        /// Create a property field of a class with get and set.
        /// </summary>
        public void AddField(StructureField field, Type fieldType, int order)
        {
            var fieldBuilder    = m_structureBuilder.DefineField("_" + field.Name, fieldType, FieldAttributes.Private);
            var propertyBuilder = m_structureBuilder.DefineProperty(
                field.Name,
                PropertyAttributes.None,
                fieldType,
                null);
            var methodAttributes =
                System.Reflection.MethodAttributes.Public |
                System.Reflection.MethodAttributes.HideBySig |
                System.Reflection.MethodAttributes.Virtual;

            var setBuilder = m_structureBuilder.DefineMethod("set_" + field.Name, methodAttributes, null, new[] { fieldType });
            var setIl      = setBuilder.GetILGenerator();

            setIl.Emit(OpCodes.Ldarg_0);
            setIl.Emit(OpCodes.Ldarg_1);
            setIl.Emit(OpCodes.Stfld, fieldBuilder);
            if (m_structureType == StructureType.Union)
            {
                // set the union selector to the new field index
                FieldInfo unionField = typeof(UnionComplexType).GetField(
                    "m_switchField",
                    BindingFlags.NonPublic |
                    BindingFlags.Instance);
                setIl.Emit(OpCodes.Ldarg_0);
                setIl.Emit(OpCodes.Ldc_I4, order);
                setIl.Emit(OpCodes.Stfld, unionField);
            }
            setIl.Emit(OpCodes.Ret);

            var getBuilder = m_structureBuilder.DefineMethod("get_" + field.Name, methodAttributes, fieldType, Type.EmptyTypes);
            var getIl      = getBuilder.GetILGenerator();

            getIl.Emit(OpCodes.Ldarg_0);
            getIl.Emit(OpCodes.Ldfld, fieldBuilder);
            getIl.Emit(OpCodes.Ret);

            propertyBuilder.SetGetMethod(getBuilder);
            propertyBuilder.SetSetMethod(setBuilder);
            propertyBuilder.DataMemberAttribute(field.Name, false, order);
            propertyBuilder.StructureFieldAttribute(field);
        }
コード例 #4
0
        public Expression VisitMkSequence(MkSequence seq)
        {
            var ter = new TypedExpressionRewriter(prog);
            //$TODO: identical to TypedExpressionRewriter except for the ceb.Dereferenced statements. How to combine?
            var      head   = seq.Head.Accept(ter);
            var      tail   = seq.Tail.Accept(ter);
            Constant c      = tail as Constant;
            var      ptHead = head.TypeVariable.DataType as PrimitiveType;

            if (head.TypeVariable.DataType is Pointer || (ptHead != null && ptHead.Domain == Domain.Selector))
            {
                if (c != null)
                {
                    ComplexExpressionBuilder ceb = new ComplexExpressionBuilder(
                        seq.TypeVariable.DataType,
                        head.DataType,
                        head.TypeVariable.OriginalDataType,
                        null,
                        head,
                        null,
                        StructureField.ToOffset(c));
                    ceb.Dereferenced = true;
                    return(ceb.BuildComplex());
                }
                else
                {
                    var ceb = new ComplexExpressionBuilder(
                        seq.TypeVariable.DataType,
                        seq.TypeVariable.DataType,
                        seq.TypeVariable.OriginalDataType,
                        head,
                        tail,
                        null,
                        0);
                    ceb.Dereferenced = true;
                    return(ceb.BuildComplex());
                }
            }
            else
            {
            }
            return(new MkSequence(seq.DataType, head, tail));
        }
コード例 #5
0
 private void AddGlobalField(DataType dtField, Address address, string?name)
 {
     if (address.Selector.HasValue)
     {
         if (program.SegmentMap.TryFindSegment(address, out var seg) &&
             program.TypeStore.SegmentTypes.TryGetValue(seg, out var structureType))
         {
             var f = new StructureField((int)address.Offset, dtField, name);
             structureType.Fields.Add(f);
         }
     }
     else
     {
         var offset     = (int)address.ToLinear();
         var f          = new StructureField(offset, dtField, name);
         var ptrGlobals = (Pointer)program.Globals.TypeVariable !.OriginalDataType;
         ((StructureType)ptrGlobals.Pointee).Fields.Add(f);
     }
 }
コード例 #6
0
        public Expression VisitStructure(StructureType str)
        {
            if (++depth > 20)
            {
                Debug.Print("*** recursion too deep, quitting. Determine error then remove this"); //$DEBUG
                return(expComplex);
            }
            if (enclosingPtr != null)
            {
                int strSize = str.GetInferredSize();
                if (str.Size > 0 && // We know the size of the struct, for sure.
                    (offset >= strSize && offset % strSize == 0 && index == null))
                {
                    var exp = CreateArrayAccess(str, enclosingPtr, offset / strSize, index);
                    index = null;
                    --depth;
                    return(exp);
                }
                else if (index != null && offset == 0)
                {
                    var idx = this.ScaleDownIndex(index, strSize);
                    index = null;
                    var exp = CreateArrayAccess(str, enclosingPtr, 0, idx);
                    --depth;
                    return(exp);
                }
            }
            StructureField field = str.Fields.LowerBound(this.offset);

            if (field == null)
            {
                throw new TypeInferenceException("Expected structure type {0} to have a field at offset {1} ({1:X}).", str.Name, offset);
            }

            dtComplex       = field.DataType;
            dtComplexOrig   = field.DataType.ResolveAs <DataType>();
            this.expComplex = CreateFieldAccess(str, field.DataType, expComplex, field);
            offset         -= field.Offset;
            var e = dtComplex.Accept(this);

            --depth;
            return(e);
        }
コード例 #7
0
ファイル: ScannerTests.cs プロジェクト: Godzil/reko
        public void Scanner_GlobalDataRecursiveStructs()
        {
            var bytes = new byte[] {
                0x17, 0x00, 0x21, 0x43, 0x00, 0x00, 0x21, 0x43,
                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
            };

            Given_Program(Address.Ptr32(0x43210000), bytes);
            Given_Project();

            var sc = new Scanner(
                this.program,
                new ImportResolver(project, program, eventListener),
                this.sc
                );

            var ft = new FunctionType(new SerializedSignature
            {
                ReturnValue = new Argument_v1 {
                    Type = Real32()
                },
            });
            var str    = new StructureType();
            var fields = new StructureField[] {
                new StructureField(0, new Pointer(ft, 4), "func"),
                new StructureField(4, new Pointer(str, 4), "next"),
            };

            str.Fields.AddRange(fields);

            sc.EnqueueUserGlobalData(Address.Ptr32(0x43210000), str);
            sc.ScanImage();

            var sExpSig =
                @"Register real32 ()()
// stackDelta: 4; fpuStackDelta: 0; fpuMaxParam: -1
";

            Assert.AreEqual(1, program.Procedures.Count);
            Assert.AreEqual(sExpSig, program.Procedures[Address.Ptr32(0x43210017)].Signature.ToString());
        }
コード例 #8
0
 private Expression VisitConstant(Constant c, bool dereferenced)
 {
     if (basePointer != null)
     {
         ComplexExpressionBuilder ceb = new ComplexExpressionBuilder(
             dtResult,
             basePointer.TypeVariable.DataType,
             basePointer.TypeVariable.OriginalDataType,
             null,
             basePointer,
             null,
             StructureField.ToOffset(c));
         ceb.Dereferenced = dereferenced;
         return(ceb.BuildComplex());
     }
     else
     {
         return(tcr.Rewrite(c, dereferenced));
     }
 }
コード例 #9
0
ファイル: Unifier.cs プロジェクト: nemerle/reko
            public bool Match(StructureField fa, StructureField fb)
            {
                this.fa            = fa;
                this.fb            = fb;
                this.fNestedStruct = null;
                this.fOther        = null;
                this.NextFieldA    = null;
                this.NextFieldB    = null;
                var strFa = fa.DataType.TypeReferenceAs <StructureType>();
                var strFb = fb.DataType.TypeReferenceAs <StructureType>();

                // only one field should be nested structure
                if (
                    (strFa == null && strFb == null) ||
                    (strFa != null && strFb != null))
                {
                    return(false);
                }

                // check which of two fields is nested structure and store it
                // and other field in corresponding variables.
                int strSize;

                if (strFa != null)
                {
                    fNestedStruct = fa;
                    fOther        = fb;
                    strSize       = strFa.GetInferredSize();
                }
                else
                {
                    fNestedStruct = fb;
                    fOther        = fa;
                    strSize       = strFb !.GetInferredSize();
                }

                // check if other field is inside nested structure
                return(
                    fOther.Offset >= fNestedStruct.Offset &&
                    fOther.Offset < fNestedStruct.Offset + strSize);
            }
コード例 #10
0
        private TypeVariable GetTypeVariableForField(DataType fieldType)
        {
            StructureType s = fieldType as StructureType;

            if (s != null)
            {
                StructureField f = s.Fields.AtOffset(0);
                if (f == null)
                {
                    return(null);
                }
                return(f.DataType as TypeVariable);
            }
            FunctionType fn = fieldType as FunctionType;

            if (fn != null)
            {
                throw new NotImplementedException();
            }
            throw new NotImplementedException(string.Format("Don't know how to handle pointers to {0}.", fieldType));
        }
コード例 #11
0
 private void AddFieldToCluster(StructureField field, List <StructureField> overlappingFields)
 {
     if (!(field.DataType is EquivalenceClass eq))
     {
         overlappingFields.Add(field);
         return;
     }
     if (eq.DataType is UnionType u)
     {
         foreach (UnionAlternative alt in u.Alternatives.Values)
         {
             StructureField f = new StructureField(field.Offset, alt.DataType);
             overlappingFields.Add(f);
         }
     }
     else
     {
         overlappingFields.Add(field);
         return;
     }
 }
コード例 #12
0
ファイル: GlobalDataWriter.cs プロジェクト: nemerle/reko
        private void WriteGlobalVariable(StructureField field)
        {
            var name = program.NamingPolicy.GlobalName(field);
            var addr = Address.Ptr32((uint)field.Offset);  //$BUG: this is completely wrong; field.Offsets should be as wide as the platform permits.
            var oneLineDeclaration = IsOneLineDeclaration(field.DataType);

            try
            {
                tw.WriteDeclaration(field.DataType, name);
                if (program.SegmentMap.IsValidAddress(addr))
                {
                    formatter.Write(" = ");
                    if (!oneLineDeclaration && showAddressInComment)
                    {
                        formatter.Write("// {0}", addr);
                    }
                    this.rdr = program.CreateImageReader(program.Architecture, addr);
                    field.DataType.Accept(this);
                }
            }
            catch (Exception ex)
            {
                var dc = services.RequireService <DecompilerEventListener>();
                dc.Error(
                    dc.CreateAddressNavigator(program, addr),
                    ex,
                    "Failed to write global variable {0}.", name);
                formatter.Terminate(";");
                return;
            }
            if (oneLineDeclaration && showAddressInComment)
            {
                formatter.Write("; // {0}", addr);
                formatter.Terminate();
            }
            else
            {
                formatter.Terminate(";");
            }
        }
コード例 #13
0
        public override Expression VisitMkSequence(MkSequence seq)
        {
            var      head   = seq.Head.Accept(this);
            var      tail   = seq.Tail.Accept(this);
            Constant c      = seq.Tail as Constant;
            var      ptHead = head.TypeVariable.DataType as PrimitiveType;

            if (head.TypeVariable.DataType is Pointer || (ptHead != null && ptHead.Domain == Domain.Selector))
            {
                if (c != null)
                {
                    ComplexExpressionBuilder ceb = new ComplexExpressionBuilder(
                        seq.TypeVariable.DataType,
                        head.TypeVariable.DataType,
                        head.TypeVariable.OriginalDataType,
                        null,
                        head,
                        null,
                        StructureField.ToOffset(c));
                    return(ceb.BuildComplex());
                }
                else
                {
                    var ceb = new ComplexExpressionBuilder(
                        seq.TypeVariable.DataType,
                        seq.TypeVariable.DataType,
                        seq.TypeVariable.OriginalDataType,
                        head,
                        new MemberPointerSelector(seq.DataType, head, tail),
                        null,
                        0);
                    return(ceb.BuildComplex());
                }
            }
            else
            {
            }
            return(new MkSequence(seq.DataType, head, tail));
        }
コード例 #14
0
        private Expression RewriteGlobalFieldAccess(
            DataType dt,
            int offset)
        {
            var f = GlobalVars.Fields.LowerBound(offset);

            if (f == null || !IsInsideField(offset, f))
            {
                f = new StructureField(offset, dt);
                GlobalVars.Fields.Add(f);
            }
            var ptrStr = new Pointer(GlobalVars, platform.PointerType.BitSize);
            var fa     = new FieldAccess(f.DataType, new Dereference(ptrStr, globals), f);

            if (f.Offset != offset)
            {
                var ceb = new ComplexExpressionBuilder(
                    null, null, fa, null, offset - f.Offset);
                return(ceb.BuildComplex(false));
            }
            return(fa);
        }
コード例 #15
0
ファイル: TypedConstantRewriter.cs プロジェクト: heruix/reko
        private StructureField EnsureFieldAtOffset(StructureType str, DataType dt, int offset)
        {
            StructureField f = str.Fields.AtOffset(offset);

            if (f == null)
            {
                //$TODO: overlaps and conflicts.
                //$TODO: strings.
                f = new StructureField(offset, dt);
                str.Fields.Add(f);
            }
            return(f);

#if TODO
            var f = GlobalVars.Fields.LowerBound(c.ToInt32());
            //StructureField f = str.Fields.AtOffset(offset);
            if (f != null)
            {
                Unifier u = new Unifier();
                if (u.AreCompatible(f.DataType, dt))
                {
                    return(f);
                }

                // Check for special case when an array ends at the offset.
                f = GlobalVars.Fields.LowerBound(c.ToInt32() - 1);
                var array = f.DataType.ResolveAs <ArrayType>();
                if (array != null && u.AreCompatible(array.ElementType, dt))
                {
                    return(f);
                }
            }
            //$TODO: overlaps and conflicts.
            //$TODO: strings.
            f = new StructureField(offset, dt);
            str.Fields.Add(f);
            return(f);
#endif
        }
コード例 #16
0
        private bool IsInsideField(int offset, StructureField field)
        {
            if (offset < field.Offset)
            {
                return(false);
            }
            if (offset == field.Offset)
            {
                return(true);
            }
            if (offset < field.Offset + field.DataType.Size)
            {
                return(true);
            }
            var str = field.DataType.ResolveAs <StructureType>();

            if (str != null && offset < field.Offset + str.GetInferredSize())
            {
                return(true);
            }
            return(false);
        }
コード例 #17
0
        /// <summary>
        /// Build the StructureField attribute for a complex type.
        /// </summary>
        public static void StructureFieldAttribute(
            this PropertyBuilder typeBuilder,
            StructureField structureField)
        {
            var                    attributeType = typeof(StructureFieldAttribute);
            ConstructorInfo        ctorInfo      = attributeType.GetConstructor(Type.EmptyTypes);
            CustomAttributeBuilder builder       = new CustomAttributeBuilder(
                ctorInfo,
                new object[0],  // constructor arguments
                new[]           // properties to assign
            {
                attributeType.GetProperty("ValueRank"),
                attributeType.GetProperty("MaxStringLength"),
                attributeType.GetProperty("IsOptional")
            },
                new object[]    // values to assign
            {
                structureField.ValueRank,
                structureField.MaxStringLength,
                structureField.IsOptional
            });

            typeBuilder.SetCustomAttribute(builder);
        }
コード例 #18
0
        /// <summary>
        /// Exports a DataTypeDefinition
        /// </summary>
        private Opc.Ua.Export.DataTypeDefinition Export(
            DataTypeState dataType,
            ExtensionObject source,
            NamespaceTable namespaceUris,
            bool outputRedundantNames)
        {
            if (source == null || source.Body == null)
            {
                return(null);
            }

            DataTypeDefinition definition = new DataTypeDefinition();

            if (outputRedundantNames || dataType.BrowseName != null)
            {
                definition.Name = Export(dataType.BrowseName, namespaceUris);
            }

            if (dataType.BrowseName.Name != dataType.SymbolicName)
            {
                definition.SymbolicName = dataType.SymbolicName;
            }

            StructureDefinition sd = source.Body as StructureDefinition;

            if (sd != null)
            {
                if (sd.StructureType == StructureType.Union || sd.StructureType == (StructureType)4) // StructureType.UnionWithSubtypedValues)
                {
                    definition.IsUnion = true;
                }

                if (sd.Fields != null)
                {
                    List <Opc.Ua.Export.DataTypeField> fields = new List <DataTypeField>();

                    for (int ii = sd.FirstExplicitFieldIndex; ii < sd.Fields.Count; ii++)
                    {
                        StructureField field = sd.Fields[ii];

                        Opc.Ua.Export.DataTypeField output = new Opc.Ua.Export.DataTypeField();

                        output.Name        = field.Name;
                        output.Description = Export(new Opc.Ua.LocalizedText[] { field.Description });

                        if (sd.StructureType == StructureType.StructureWithOptionalFields)
                        {
                            output.IsOptional    = field.IsOptional;
                            output.AllowSubTypes = false;
                        }
                        else if (sd.StructureType == (StructureType)3 || // StructureType.StructureWithSubtypedValues ||
                                 sd.StructureType == (StructureType)4)   // StructureType.UnionWithSubtypedValues)
                        {
                            output.IsOptional    = false;
                            output.AllowSubTypes = field.IsOptional;
                        }
                        else
                        {
                            output.IsOptional    = false;
                            output.AllowSubTypes = false;
                        }

                        if (NodeId.IsNull(field.DataType))
                        {
                            output.DataType = Export(DataTypeIds.BaseDataType, namespaceUris);
                        }
                        else
                        {
                            output.DataType = Export(field.DataType, namespaceUris);
                        }

                        output.ValueRank = field.ValueRank;

                        fields.Add(output);
                    }

                    definition.Field = fields.ToArray();
                }
            }

            EnumDefinition ed = source.Body as EnumDefinition;

            if (ed != null)
            {
                definition.IsOptionSet = ed.IsOptionSet;

                if (ed.Fields != null)
                {
                    List <Opc.Ua.Export.DataTypeField> fields = new List <DataTypeField>();

                    foreach (EnumField field in ed.Fields)
                    {
                        Opc.Ua.Export.DataTypeField output = new Opc.Ua.Export.DataTypeField();

                        output.Name = field.Name;

                        if (field.DisplayName != null && output.Name != field.DisplayName.Text)
                        {
                            output.DisplayName = Export(new Opc.Ua.LocalizedText[] { field.DisplayName });
                        }
                        else
                        {
                            output.DisplayName = Array.Empty <LocalizedText>();
                        }

                        output.Description = Export(new Opc.Ua.LocalizedText[] { field.Description });
                        output.ValueRank   = ValueRanks.Scalar;
                        output.Value       = (int)field.Value;

                        fields.Add(output);
                    }

                    definition.Field = fields.ToArray();
                }
            }

            return(definition);
        }
コード例 #19
0
 public StructureFieldParameter(StructureField structureField)
 {
     Name        = structureField.Name;
     BuiltInType = TypeInfo.GetBuiltInType(structureField.DataType);
 }
コード例 #20
0
ファイル: ScannerTests.cs プロジェクト: Godzil/reko
        public void Scanner_GlobalData()
        {
            var bytes = new byte[] {
                0x48, 0x00, 0x21, 0x43, 0x00, 0x00, 0x00, 0x01, 0x53, 0x00, 0x21, 0x43,
                0x28, 0x00, 0x21, 0x43, 0x00, 0x00, 0x00, 0x02, 0x63, 0x00, 0x21, 0x43,
                0x38, 0x00, 0x21, 0x43, 0x00, 0x00, 0x00, 0x03, 0x73, 0x00, 0x21, 0x43,
                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
            };

            Given_Program(Address.Ptr32(0x43210000), bytes);
            var project = new Project {
                Programs = { program }
            };

            var sc = new Scanner(
                this.program,
                new ImportResolver(project, program, eventListener),
                this.sc
                );

            var ft1 = new FunctionType(new SerializedSignature
            {
                ReturnValue = new Argument_v1 {
                    Type = Int32()
                }
            });
            var ft2 = new FunctionType(new SerializedSignature
            {
                ReturnValue = new Argument_v1 {
                    Type = Char()
                }
            });
            var str    = new StructureType();
            var fields = new StructureField[] {
                new StructureField(0, new Pointer(ft1, 4), "A"),
                new StructureField(4, PrimitiveType.Int32, "B"),
                new StructureField(8, new Pointer(ft2, 4), "C"),
            };

            str.Fields.AddRange(fields);
            var elementType = new TypeReference("test", str);
            var arrayType   = new ArrayType(elementType, 3);

            sc.EnqueueUserGlobalData(Address.Ptr32(0x43210000), arrayType);
            sc.ScanImage();

            var sExpSig1 =
                @"Register ui32 ()()
// stackDelta: 4; fpuStackDelta: 0; fpuMaxParam: -1
";
            var sExpSig2 =
                @"Register char ()()
// stackDelta: 4; fpuStackDelta: 0; fpuMaxParam: -1
";

            Assert.AreEqual(6, program.Procedures.Count);
            Assert.AreEqual(sExpSig1, program.Procedures[Address.Ptr32(0x43210028)].Signature.ToString());
            Assert.AreEqual(sExpSig1, program.Procedures[Address.Ptr32(0x43210038)].Signature.ToString());
            Assert.AreEqual(sExpSig1, program.Procedures[Address.Ptr32(0x43210048)].Signature.ToString());
            Assert.AreEqual(sExpSig2, program.Procedures[Address.Ptr32(0x43210053)].Signature.ToString());
            Assert.AreEqual(sExpSig2, program.Procedures[Address.Ptr32(0x43210063)].Signature.ToString());
            Assert.AreEqual(sExpSig2, program.Procedures[Address.Ptr32(0x43210073)].Signature.ToString());
        }
コード例 #21
0
ファイル: ScannerTests.cs プロジェクト: relaxar/reko
        public void Scanner_GlobalDataRecursiveStructs()
        {
            var bytes = new byte[] {
                0x17, 0x00, 0x21, 0x43, 0x00, 0x00, 0x21, 0x43,
                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
            };
            Given_Program(Address.Ptr32(0x43210000), bytes);
            Given_Project();

            var sc = new Scanner(
                this.program,
                new ImportResolver(project, program, eventListener),
                this.sc
            );

            var ft = Given_Serialized_Signature(new SerializedSignature
            { 
                 ReturnValue = new Argument_v1 { Type = Real32() },
            });
            var str = new StructureType();
            var fields = new StructureField[] {
                new StructureField(0, new Pointer(ft,  4), "func"),
                new StructureField(4, new Pointer(str, 4), "next"),
            };
            str.Fields.AddRange(fields);

            sc.EnqueueUserGlobalData(Address.Ptr32(0x43210000), str);
            sc.ScanImage();

            var sExpSig =
@"Register real32 fn43210017()
// stackDelta: 4; fpuStackDelta: 0; fpuMaxParam: -1
";
            Assert.AreEqual(1, program.Procedures.Count);
            Assert.AreEqual(sExpSig, program.Procedures[Address.Ptr32(0x43210017)].Signature.ToString("fn43210017", FunctionType.EmitFlags.AllDetails));
        }
コード例 #22
0
        /// <summary>
        /// Imports a DataTypeDefinition
        /// </summary>
        private Opc.Ua.DataTypeDefinition Import(UADataType dataType, Opc.Ua.Export.DataTypeDefinition source, NamespaceTable namespaceUris)
        {
            if (source == null)
            {
                return(null);
            }

            Opc.Ua.DataTypeDefinition definition = null;

            if (source.Field != null)
            {
                // check if definition is for enumeration or structure.
                bool isStructure = Array.Exists <DataTypeField>(source.Field, delegate(DataTypeField fieldLookup)
                {
                    return(fieldLookup.Value == -1);
                });

                if (isStructure)
                {
                    StructureDefinition structureDefinition = new StructureDefinition();
                    structureDefinition.BaseDataType = ImportNodeId(source.BaseType, namespaceUris, true);

                    if (source.IsUnion)
                    {
                        structureDefinition.StructureType = StructureType.Union;
                    }

                    if (source.Field != null)
                    {
                        List <StructureField> fields = new List <StructureField>();

                        foreach (DataTypeField field in source.Field)
                        {
                            if (field.IsOptional)
                            {
                                structureDefinition.StructureType = StructureType.StructureWithOptionalFields;
                            }

                            StructureField output = new StructureField();

                            output.Name        = field.Name;
                            output.Description = Import(field.Description);
                            output.DataType    = ImportNodeId(field.DataType, namespaceUris, true);
                            output.ValueRank   = field.ValueRank;
                            output.IsOptional  = field.IsOptional;

                            fields.Add(output);
                        }

                        structureDefinition.Fields = fields.ToArray();
                    }
                    definition = structureDefinition;
                }
                else
                {
                    EnumDefinition enumDefinition = new EnumDefinition();
                    if (source.Field != null)
                    {
                        List <EnumField> fields = new List <EnumField>();

                        foreach (DataTypeField field in source.Field)
                        {
                            EnumField output = new EnumField();

                            output.Name        = field.Name;
                            output.DisplayName = Import(field.DisplayName);
                            output.Description = Import(field.Description);
                            output.Value       = field.Value;

                            fields.Add(output);
                        }

                        enumDefinition.Fields = fields.ToArray();
                    }
                    definition = enumDefinition;
                }
            }

            return(definition);
        }
コード例 #23
0
ファイル: TypeFactory.cs プロジェクト: relaxar/reko
		public StructureType CreateStructureType(string name, int size, StructureField field)
		{
            return new StructureType(name, size) { Fields = { field } };
		}
コード例 #24
0
        public Expression VisitBinaryExpression(BinaryExpression binExp)
        {
            Expression   left    = binExp.Left;
            Expression   right   = binExp.Right;
            TypeVariable tvLeft  = left.TypeVariable;
            TypeVariable tvRight = right.TypeVariable;

            if (!tvLeft.DataType.IsComplex)
            {
                if (!tvRight.DataType.IsComplex)
                {
                    throw new NotImplementedException(string.Format("Neither subexpression is complex in {0}: [[{1}]] and [[{2}]]",
                                                                    binExp,
                                                                    tvLeft.DataType,
                                                                    tvRight.DataType));
                }
                return(VisitBinaryExpression(binExp.Commute()));
            }
            else if (tvRight.DataType.IsComplex)
            {
                throw new TypeInferenceException("Both subexpressions are complex in {0}. Left type: {1}, right type {2}",
                                                 binExp, tvLeft.DataType, tvRight.DataType);
            }

            var ter = new TypedExpressionRewriter(prog);
            ComplexExpressionBuilder ceb;
            Constant cLeft = left as Constant;

            if (cLeft != null)
            {
                binExp.Right = binExp.Right.Accept(ter);
                if (basePointer == null)
                {
                    basePointer = globals;
                }
                ceb = new ComplexExpressionBuilder(
                    dtResult,
                    basePointer.TypeVariable.DataType,
                    basePointer.TypeVariable.OriginalDataType,
                    null,
                    basePointer,
                    binExp.Right,
                    StructureField.ToOffset(cLeft));
            }
            else
            {
                var binLeft  = binExp.Left.Accept(ter);
                var binRight = binExp.Right.Accept(ter);
                var cRight   = binRight as Constant;
                ceb = new ComplexExpressionBuilder(
                    binExp.DataType,
                    tvLeft.DataType,
                    tvLeft.OriginalDataType,
                    basePointer,
                    binLeft,
                    cRight != null ? null : binRight,
                    StructureField.ToOffset(binRight as Constant));
            }
            ceb.Dereferenced = true;
            return(ceb.BuildComplex());
        }
コード例 #25
0
ファイル: ScannerTests.cs プロジェクト: relaxar/reko
        public void Scanner_GlobalData()
        {
            var bytes = new byte[] {
                0x48, 0x00, 0x21, 0x43, 0x00, 0x00, 0x00, 0x01, 0x53, 0x00, 0x21, 0x43,
                0x28, 0x00, 0x21, 0x43, 0x00, 0x00, 0x00, 0x02, 0x63, 0x00, 0x21, 0x43,
                0x38, 0x00, 0x21, 0x43, 0x00, 0x00, 0x00, 0x03, 0x73, 0x00, 0x21, 0x43,
                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
            };
            Given_Program(Address.Ptr32(0x43210000), bytes);
            var project = new Project { Programs = { program } };

            var sc = new Scanner(
                this.program,
                new ImportResolver(project, program, eventListener),
                this.sc
            );

            var ft1 = Given_Serialized_Signature(new SerializedSignature
            {
                ReturnValue = new Argument_v1 { Type = Int32() },
            });
            var ft2 = Given_Serialized_Signature(new SerializedSignature
            {
                ReturnValue = new Argument_v1 { Type = Char() }
            });
            var str = new StructureType();
            var fields = new StructureField[] {
                new StructureField(0, new Pointer(ft1, 4), "A"),
                new StructureField(4, PrimitiveType.Int32, "B"),
                new StructureField(8, new Pointer(ft2, 4), "C"),
            };
            str.Fields.AddRange(fields);
            var elementType = new TypeReference("test", str);
            var arrayType = new ArrayType(elementType, 3);

            sc.EnqueueUserGlobalData(Address.Ptr32(0x43210000), arrayType);
            sc.ScanImage();

            var sExpSig1 =
@"Register ui32 sig1()
// stackDelta: 4; fpuStackDelta: 0; fpuMaxParam: -1
";
            var sExpSig2 =
@"Register char sig2()
// stackDelta: 4; fpuStackDelta: 0; fpuMaxParam: -1
";
            Assert.AreEqual(6, program.Procedures.Count);
            Assert.AreEqual(sExpSig1, program.Procedures[Address.Ptr32(0x43210028)].Signature.ToString("sig1", FunctionType.EmitFlags.AllDetails));
            Assert.AreEqual(sExpSig1, program.Procedures[Address.Ptr32(0x43210038)].Signature.ToString("sig1", FunctionType.EmitFlags.AllDetails));
            Assert.AreEqual(sExpSig1, program.Procedures[Address.Ptr32(0x43210048)].Signature.ToString("sig1", FunctionType.EmitFlags.AllDetails));
            Assert.AreEqual(sExpSig2, program.Procedures[Address.Ptr32(0x43210053)].Signature.ToString("sig2", FunctionType.EmitFlags.AllDetails));
            Assert.AreEqual(sExpSig2, program.Procedures[Address.Ptr32(0x43210063)].Signature.ToString("sig2", FunctionType.EmitFlags.AllDetails));
            Assert.AreEqual(sExpSig2, program.Procedures[Address.Ptr32(0x43210073)].Signature.ToString("sig2", FunctionType.EmitFlags.AllDetails));
        }
コード例 #26
0
ファイル: DataTypeBuilder.cs プロジェクト: relaxar/reko
        public DataType MemoryAccessCommon(Expression tBase, Expression tStruct, int offset, DataType tField, int structPtrSize)
        {
            var s = factory.CreateStructureType(null, 0);
            var field = new StructureField(offset, tField);
            s.Fields.Add(field);

            var pointer = tBase != null
                ? (DataType)factory.CreateMemberPointer(tBase.TypeVariable, s, structPtrSize)
                : (DataType)factory.CreatePointer(s, structPtrSize);
            return MergeIntoDataType(tStruct, pointer);
        }
コード例 #27
0
ファイル: DataTypeBuilder.cs プロジェクト: relaxar/reko
		public DataType MemFieldTrait(Expression tBase, Expression tStruct, Expression tField, int offset)
        {
            var s = factory.CreateStructureType(null, 0);
            var field = new StructureField(offset, tField.TypeVariable);
            s.Fields.Add(field);
            return MergeIntoDataType(tStruct, s);
        }
コード例 #28
0
ファイル: TypeStore.cs プロジェクト: killbug2004/reko
 public TypeVariable EnsureFieldTypeVariable(TypeFactory factory, StructureField field)
 {
     throw new NotImplementedException();
 }
コード例 #29
0
 private bool FieldOverlaps(StructureField field, int clusterEndOffset)
 {
     return(field.Offset < clusterEndOffset);
 }
コード例 #30
0
ファイル: ExpressionEmitter.cs プロジェクト: relaxar/reko
 public FieldAccess Field(DataType dt, Expression e, string fieldName)
 {
     var field = new StructureField(0, dt, fieldName);
     return new FieldAccess(dt, e, field);
 }
コード例 #31
0
        /// <summary>
        /// Exports a DataTypeDefinition
        /// </summary>
        private Opc.Ua.Export.DataTypeDefinition Export(
            DataTypeState dataType,
            ExtensionObject source,
            NamespaceTable namespaceUris,
            bool outputRedundantNames)
        {
            if (source == null || source.Body == null)
            {
                return(null);
            }

            DataTypeDefinition definition = new DataTypeDefinition();

            if (outputRedundantNames || dataType.BrowseName != null)
            {
                definition.Name = Export(dataType.BrowseName, namespaceUris);
            }

            if (dataType.BrowseName.Name != dataType.SymbolicName)
            {
                definition.SymbolicName = dataType.SymbolicName;
            }

            switch (dataType.DataTypeModifier)
            {
            case DataTypeModifier.Union: { definition.IsUnion = true; break; }

            case DataTypeModifier.OptionSet: { definition.IsOptionSet = true; break; }
            }

            StructureDefinition structureDefinition = source.Body as StructureDefinition;

            if (structureDefinition != null)
            {
                if (structureDefinition.StructureType == StructureType.Union)
                {
                    definition.IsUnion = true;
                }

                if (structureDefinition.Fields != null)
                {
                    List <Opc.Ua.Export.DataTypeField> fields = new List <DataTypeField>();

                    for (int ii = structureDefinition.FirstExplicitFieldIndex; ii < structureDefinition.Fields.Count; ii++)
                    {
                        StructureField field = structureDefinition.Fields[ii];

                        Opc.Ua.Export.DataTypeField output = new Opc.Ua.Export.DataTypeField();

                        output.Name        = field.Name;
                        output.Description = Export(new Opc.Ua.LocalizedText[] { field.Description });

                        if (NodeId.IsNull(field.DataType))
                        {
                            output.DataType = Export(DataTypeIds.BaseDataType, namespaceUris);
                        }
                        else
                        {
                            output.DataType = Export(field.DataType, namespaceUris);
                        }

                        output.ValueRank = field.ValueRank;

                        fields.Add(output);
                    }

                    definition.Field = fields.ToArray();
                }
            }

            EnumDefinition enumDefinition = source.Body as EnumDefinition;

            if (enumDefinition != null)
            {
                if (enumDefinition.Fields != null)
                {
                    List <Opc.Ua.Export.DataTypeField> fields = new List <DataTypeField>();

                    foreach (EnumField field in enumDefinition.Fields)
                    {
                        Opc.Ua.Export.DataTypeField output = new Opc.Ua.Export.DataTypeField();

                        output.Name        = field.Name;
                        output.Description = Export(new Opc.Ua.LocalizedText[] { field.Description });
                        output.ValueRank   = ValueRanks.Scalar;
                        output.Value       = (int)field.Value;

                        fields.Add(output);
                    }

                    definition.Field = fields.ToArray();
                }
            }

            return(definition);
        }
コード例 #32
0
        public void CreateField()
        {
            int off = StructureField.ToOffset(Constant.Word16(4));

            Assert.AreEqual(4, off);
        }
コード例 #33
0
 private StructureType FindStructureToFitIn(StructureField field,int commonOffset, List<StructureType> types)
 {
     foreach (StructureType type in types)
     {
         int offset = field.Offset - commonOffset;
         StructureField low = type.Fields.LowerBound(offset);
         if (low == null)
             return type;
         if (low.DataType.Size + low.Offset <= offset)
             return type;
     }
     return null;
 }
コード例 #34
0
ファイル: Unifier.cs プロジェクト: relaxar/reko
 private bool TryMakeFieldName(StructureField fa, StructureField fb, out string name)
 {
     name = null;
     if (fa.IsNameSet && fb.IsNameSet && fa.Name != fb.Name)
         return false;
     if (fa.IsNameSet)
         name = fa.Name;
     if (fb.IsNameSet)
         name = fb.Name;
     return true;
 }
コード例 #35
0
 private void AddFieldToCluster(StructureField field, List<StructureField> overlappingFields)
 {
     EquivalenceClass eq = field.DataType as EquivalenceClass;
     if (eq == null)
     {
         overlappingFields.Add(field);
         return;
     }
     UnionType u = (UnionType) eq.DataType;
     foreach (UnionAlternative alt in u.Alternatives.Values)
     {
         StructureField f = new StructureField(field.Offset, alt.DataType);
         overlappingFields.Add(f);
     }
 }
コード例 #36
0
ファイル: TypedConstantRewriter.cs プロジェクト: heruix/reko
        public Expression VisitPointer(Pointer ptr)
        {
            Expression e = c;

            if (IsSegmentPointer(ptr))
            {
                Identifier segID;
                if (mpSelectorToSegId.TryGetValue(c.ToUInt16(), out segID))
                {
                    return(segID);
                }
                return(e);
            }
            else if (GlobalVars != null)
            {
                // Null pointer.
                if (c.IsZero)
                {
                    var np = Address.Create(ptr, 0);
                    np.TypeVariable = c.TypeVariable;
                    np.DataType     = c.DataType;
                    return(np);
                }

                var addr = program.Platform.MakeAddressFromConstant(c);
                // An invalid pointer -- often used as sentinels in code.
                if (!program.SegmentMap.IsValidAddress(addr))
                {
                    //$TODO: probably should use a reinterpret_cast here.
                    var ce = new Cast(ptr, c)
                    {
                        TypeVariable = c.TypeVariable
                    };
                    return(ce);
                }

                var dt       = ptr.Pointee.ResolveAs <DataType>();
                var charType = MaybeCharType(dt);
                if (charType != null && IsPtrToReadonlySection(c, dt))
                {
                    PromoteToCString(c, charType);
                    return(ReadNullTerminatedString(c, charType));
                }
                StructureField f          = EnsureFieldAtOffset(GlobalVars, dt, c.ToInt32());
                var            ptrGlobals = new Pointer(GlobalVars, platform.PointerType.BitSize);
                e = new FieldAccess(ptr.Pointee, new Dereference(ptrGlobals, globals), f);
                if (dereferenced)
                {
                    e.DataType = ptr.Pointee;
                }
                else
                {
                    var array = f.DataType as ArrayType;
                    if (array != null) // C language rules 'promote' arrays to pointers.
                    {
                        e.DataType = program.TypeFactory.CreatePointer(
                            array.ElementType,
                            platform.PointerType.BitSize);
                    }
                    else
                    {
                        e = new UnaryExpression(Operator.AddrOf, ptr, e);
                    }
                }
            }
            return(e);
        }
コード例 #37
0
 private bool FieldOverlaps(StructureField field, int clusterEndOffset)
 {
     return field.Offset < clusterEndOffset;
 }
コード例 #38
0
        /// <summary>
        /// Convert a binary schema type definition to a
        /// StructureDefinition.
        /// </summary>
        /// <remarks>
        /// Support for:
        /// - Structures, structures with optional fields and unions.
        /// - Nested types and typed arrays with length field.
        /// The converter has the following known restrictions:
        /// - Support only for V1.03 structured types which can be mapped to the V1.04
        /// structured type definition.
        /// The following dictionary tags cause bail out for a structure:
        /// - use of a terminator of length in bytes
        /// - an array length field is not a direct predecessor of the array
        /// - The switch value of a union is not the first field.
        /// - The selector bits of optional fields are not stored in a 32 bit variable
        ///   and do not add up to 32 bits.
        /// </remarks>
        public static StructureDefinition ToStructureDefinition(
            this Schema.Binary.StructuredType structuredType,
            ExpandedNodeId defaultEncodingId,
            Dictionary <XmlQualifiedName, NodeId> typeDictionary,
            NamespaceTable namespaceTable,
            NodeId dataTypeNodeId)
        {
            var structureDefinition = new StructureDefinition()
            {
                BaseDataType      = null,
                DefaultEncodingId = ExpandedNodeId.ToNodeId(defaultEncodingId, namespaceTable),
                Fields            = new StructureFieldCollection(),
                StructureType     = StructureType.Structure
            };

            bool isSupportedType = true;
            bool hasBitField     = false;
            bool isUnionType     = false;

            foreach (var field in structuredType.Field)
            {
                // check for yet unsupported properties
                if (field.IsLengthInBytes ||
                    field.Terminator != null)
                {
                    isSupportedType = false;
                }

                if (field.SwitchValue != 0)
                {
                    isUnionType = true;
                }

                if (field.TypeName.Namespace == Namespaces.OpcBinarySchema ||
                    field.TypeName.Namespace == Namespaces.OpcUa)
                {
                    if (field.TypeName.Name == "Bit")
                    {
                        hasBitField = true;
                        continue;
                    }
                }
                if (field.Length != 0)
                {
                    isSupportedType = false;
                }
            }

            // test forbidden combinations
            if (!isSupportedType)
            {
                throw new DataTypeNotSupportedException(
                          "The structure definition uses a Terminator or LengthInBytes, which are not supported.");
            }

            if (isUnionType && hasBitField)
            {
                throw new DataTypeNotSupportedException(
                          "The structure definition combines a Union and a bit filed, both of which are not supported in a single structure.");
            }

            if (isUnionType)
            {
                structureDefinition.StructureType = StructureType.Union;
            }

            if (hasBitField)
            {
                structureDefinition.StructureType = StructureType.StructureWithOptionalFields;
            }

            byte  switchFieldBitPosition = 0;
            Int32 dataTypeFieldPosition  = 0;
            var   switchFieldBits        = new Dictionary <string, byte>();

            // convert fields
            foreach (var field in structuredType.Field)
            {
                // consume optional bits
                if (field.TypeName.IsXmlBitType())
                {
                    var count = structureDefinition.Fields.Count;
                    if (count == 0 &&
                        switchFieldBitPosition < 32)
                    {
                        structureDefinition.StructureType = StructureType.StructureWithOptionalFields;
                        byte fieldLength = (byte)((field.Length == 0) ? 1u : field.Length);
                        switchFieldBits[field.Name] = switchFieldBitPosition;
                        switchFieldBitPosition     += fieldLength;
                    }
                    else
                    {
                        throw new DataTypeNotSupportedException(
                                  "Options for bit selectors must be 32 bit in size, use the Int32 datatype and must be the first element in the structure.");
                    }
                    continue;
                }

                if (switchFieldBitPosition != 0 &&
                    switchFieldBitPosition != 32)
                {
                    throw new DataTypeNotSupportedException(
                              "Bitwise option selectors must have 32 bits.");
                }
                NodeId fieldDataTypeNodeId;
                if (field.TypeName == structuredType.QName)
                {
                    // recursive type
                    fieldDataTypeNodeId = dataTypeNodeId;
                }
                else
                {
                    fieldDataTypeNodeId = field.TypeName.ToNodeId(typeDictionary);
                }
                var dataTypeField = new StructureField()
                {
                    Name            = field.Name,
                    Description     = null,
                    DataType        = fieldDataTypeNodeId,
                    IsOptional      = false,
                    MaxStringLength = 0,
                    ArrayDimensions = null,
                    ValueRank       = -1
                };

                if (field.LengthField != null)
                {
                    // handle array length
                    var lastField = structureDefinition.Fields.Last();
                    if (lastField.Name != field.LengthField)
                    {
                        throw new DataTypeNotSupportedException(
                                  "The length field must precede the type field of an array.");
                    }
                    lastField.Name      = field.Name;
                    lastField.DataType  = fieldDataTypeNodeId;
                    lastField.ValueRank = 1;
                }
                else
                {
                    if (isUnionType)
                    {
                        // ignore the switchfield
                        if (field.SwitchField == null)
                        {
                            if (structureDefinition.Fields.Count != 0)
                            {
                                throw new DataTypeNotSupportedException(
                                          "The switch field of a union must be the first field in the complex type.");
                            }
                            continue;
                        }
                        if (structureDefinition.Fields.Count != dataTypeFieldPosition)
                        {
                            throw new DataTypeNotSupportedException(
                                      "The count of the switch field of the union member is not matching the field position.");
                        }
                        dataTypeFieldPosition++;
                    }
                    else
                    {
                        if (field.SwitchField != null)
                        {
                            dataTypeField.IsOptional = true;
                            byte value;
                            if (!switchFieldBits.TryGetValue(field.SwitchField, out value))
                            {
                                throw new DataTypeNotSupportedException(
                                          $"The switch field for {field.SwitchField} does not exist.");
                            }
                        }
                    }
                    structureDefinition.Fields.Add(dataTypeField);
                }
            }

            return(structureDefinition);
        }
コード例 #39
0
        /// <summary>
        /// Imports a DataTypeDefinition
        /// </summary>
        private Opc.Ua.DataTypeDefinition Import(UADataType dataType, Opc.Ua.Export.DataTypeDefinition source, NamespaceTable namespaceUris)
        {
            if (source == null)
            {
                return(null);
            }

            Opc.Ua.DataTypeDefinition definition = null;

            if (source.Field != null)
            {
                // check if definition is for enumeration or structure.
                bool isStructure = Array.Exists <DataTypeField>(source.Field, delegate(DataTypeField fieldLookup) {
                    return(fieldLookup.Value == -1);
                });

                if (isStructure)
                {
                    StructureDefinition sd = new StructureDefinition();
                    sd.BaseDataType = ImportNodeId(source.BaseType, namespaceUris, true);

                    if (source.IsUnion)
                    {
                        sd.StructureType = StructureType.Union;
                    }

                    if (source.Field != null)
                    {
                        List <StructureField> fields = new List <StructureField>();

                        foreach (DataTypeField field in source.Field)
                        {
                            if (sd.StructureType == StructureType.Structure ||
                                sd.StructureType == StructureType.Union)
                            {
                                if (field.IsOptional)
                                {
                                    sd.StructureType = StructureType.StructureWithOptionalFields;
                                }
                                else if (field.AllowSubTypes)
                                {
                                    if (source.IsUnion)
                                    {
                                        sd.StructureType = (StructureType)4; // StructureType.UnionWithSubtypedValues;
                                    }
                                    else
                                    {
                                        sd.StructureType = (StructureType)3; // StructureType.StructureWithSubtypedValues;
                                    }
                                }
                            }

                            StructureField output = new StructureField();

                            output.Name        = field.Name;
                            output.Description = Import(field.Description);
                            output.DataType    = ImportNodeId(field.DataType, namespaceUris, true);
                            output.ValueRank   = field.ValueRank;

                            if (sd.StructureType == StructureType.Structure ||
                                sd.StructureType == StructureType.Union)
                            {
                                output.IsOptional = false;
                            }
                            else if (sd.StructureType == (StructureType)3 || //StructureType.StructureWithSubtypedValues ||
                                     sd.StructureType == (StructureType)4)   //StructureType.UnionWithSubtypedValues)
                            {
                                output.IsOptional = field.AllowSubTypes;
                            }
                            else
                            {
                                output.IsOptional = field.IsOptional;
                            }

                            fields.Add(output);
                        }

                        sd.Fields = fields.ToArray();
                    }

                    definition = sd;
                }
                else
                {
                    EnumDefinition ed = new EnumDefinition();
                    ed.IsOptionSet = source.IsOptionSet;

                    if (source.Field != null)
                    {
                        List <EnumField> fields = new List <EnumField>();

                        foreach (DataTypeField field in source.Field)
                        {
                            EnumField output = new EnumField();

                            output.Name        = field.Name;
                            output.DisplayName = Import(field.DisplayName);
                            output.Description = Import(field.Description);
                            output.Value       = field.Value;

                            fields.Add(output);
                        }

                        ed.Fields = fields.ToArray();
                    }

                    definition = ed;
                }
            }

            return(definition);
        }
コード例 #40
0
        public FieldAccess Field(DataType dt, Expression e, string fieldName)
        {
            var field = new StructureField(0, dt, fieldName);

            return(new FieldAccess(dt, e, field));
        }
コード例 #41
0
        public Expression Rewrite(Address addr, Expression?basePtr, bool dereferenced)
        {
            if (addr.Selector.HasValue)
            {
                if (!mpSelectorToSegId.TryGetValue(addr.Selector.Value, out Identifier segId))
                {
                    eventListener.Warn(
                        "Selector {0:X4} has no known segment.",
                        addr.Selector.Value);
                    return(addr);
                }
                var ptrSeg = segId.TypeVariable !.DataType.ResolveAs <Pointer>();
                if (ptrSeg == null)
                {
                    //$TODO: what should the warning be?
                    //$BUG: create a fake field for now.
                    var        field = new StructureField((int)addr.Offset, new UnknownType());
                    Expression x     = new FieldAccess(new UnknownType(), new Dereference(segId.DataType, segId), field);
                    if (!dereferenced)
                    {
                        x = new UnaryExpression(Operator.AddrOf, addr.DataType, x);
                    }
                    return(x);
                }
                var baseType = ptrSeg.Pointee.ResolveAs <StructureType>() !;
                var dt       = addr.TypeVariable !.DataType.ResolveAs <Pointer>() !;
                this.c = Constant.Create(
                    PrimitiveType.CreateWord(addr.DataType.BitSize - ptrSeg.BitSize),
                    addr.Offset);
                DataType pointee;
                if (dt != null)
                {
                    pointee = dt.Pointee;
                }
                else
                {
                    pointee = new UnknownType();
                }

                var        f  = EnsureFieldAtOffset(baseType, pointee, c.ToInt32());
                Expression ex = new FieldAccess(f.DataType, new Dereference(ptrSeg, segId), f);
                if (dereferenced || pointee is ArrayType)
                {
                    return(ex);
                }
                else
                {
                    var un = new UnaryExpression(Operator.AddrOf, addr.TypeVariable !.DataType, ex);
                    return(un);
                }
            }
            else
            {
                this.c = addr.ToConstant();
                this.c.TypeVariable = addr.TypeVariable;
                var dtInferred = addr.TypeVariable !.DataType.ResolveAs <DataType>() !;
                this.pOrig        = addr.TypeVariable.OriginalDataType as PrimitiveType;
                this.dereferenced = dereferenced;
                return(dtInferred.Accept(this));
            }
        }