예제 #1
0
파일: TpmTypes.cs 프로젝트: rgl/TSS.MSR
 internal static void Replace(TpmType tpmType, string insertAfter)
 {
     Debug.Assert(TypeIndex.ContainsKey(tpmType.SpecName));
     TheTypes.Remove(TypeIndex[tpmType.SpecName]);
     TypeIndex.Remove(tpmType.SpecName);
     Add(tpmType, insertAfter);
 }
예제 #2
0
        void GenEnum(TpmType e, List <TpmNamedConstant> elements)
        {
            WriteComment(e);
            Write($"export enum {e.Name} // {e.UnderlyingType.SpecName}");
            TabIn("{");

            foreach (var elt in elements)
            {
                // Skip TPM_RC.H enumerator (an alias hiding SUCCESS value)
                if (elt.Name == "H")
                {
                    continue;
                }

                string sep = Separator(elt, elements);
                WriteComment(elt);
                Write($"{elt.Name} = {elt.Value}{sep}");

                // Backward compat
                if (elt.Name == "PW")
                {
                    WriteComment("@deprecated Use TPM_RH.PW instead");
                    Write($"RS_PW = {elt.Value},");
                }
                if (sep != "")
                {
                    Write("");
                }
            }
            string type = e is TpmEnum ? "enum" : "bitfield";

            TabOut($"}}; // {type} {e.Name}");
        } // GenEnum()
예제 #3
0
파일: TpmTypes.cs 프로젝트: rgl/TSS.MSR
        public bool InheritMarshalingID = false; // for C++ only

        void Init(string specName, string comment, int size, TpmType underlyingType)
        {
            SpecName       = specName;
            Comment        = comment;
            Size           = size;
            UnderlyingType = underlyingType;
        }
예제 #4
0
        /// <remarks> Old style - pre 2020 (TpmRh.TpmRsPw, EccCurve.TpmEccXxx instead of TpmRh.Pw, EccCurve.Xxx) </remarks>
        public static string TransConstantName(string specName, TpmType enclosingType, bool oldStyle = false)
        {
            string name = TpmTypeTranslations.RemoveEnumPrefix(specName, enclosingType.SpecName, oldStyle);

            name = FixupInvalidName(name);
            return(TargetLang.DotNet ? NameToDotNet(name) : name);
        }
예제 #5
0
        } // GenerateHeader()

        void GenEnum(TpmType e, List <TpmNamedConstant> elements)
        {
            WriteComment(e);
            Write($"struct {e.Name} : public TpmEnum<{e.GetFinalUnderlyingType().Name}>");
            TabIn("{");
            Write($"TPM_ENUM_PROLOGUE({e.Name})");

            var enumVals = new Dictionary <string, string>();

            foreach (var elt in elements)
            {
                WriteComment(AsSummary(elt.Comment));
                string delimiter = Separator(elt, elements);
                Write($"{elt.Name} = {elt.Value}{delimiter}");

                // Do not include artificially added named constants into the name conversion maps
                if (elt.SpecName != null)
                {
                    enumVals[elt.Name] = e is TpmEnum?ToHex(elt.NumericValue) : elt.Value;
                }

                // Backward compat
                if (elt.Name == "PW")
                {
                    WriteComment(AsSummary("Deprecated: use PW instead"));
                    Write($"RS_PW [[deprecated(\"Use TPM_RH::PW instead\")]] = {elt.Value},");
                }
            }
            Write($"TPM_ENUM_EPILOGUE({e.Name})");
            TabOut("};");
            EnumMap[e.Name] = enumVals;
        } // GenEnum()
예제 #6
0
        void GenEnum(TpmType e, List <TpmNamedConstant> elements)
        {
            // e.UnderlyingType.GetSize()
            TabIn($"class {e.Name}(TpmEnum): # {e.UnderlyingType.SpecName}");
            WriteComment(e);

            foreach (var v in elements)
            {
                // Skip TPM_RC.H enumerator (an alias hiding SUCCESS value)
                if (v.Name == "H")
                {
                    continue;
                }

                Write("");
                Write($"{v.Name} = {v.Value}");
                WriteComment(v);

                // Backward compat
                if (v.Name == "PW")
                {
                    WriteComment("Deprecated: use PW instead");
                    Write($"RS_PW = {v.Value}");
                }
            }
            string type = e is TpmEnum ? "enum" : "bitfield";

            TabOut($"# {type} {e.Name}");
        } // GenEnum()
예제 #7
0
        public static string GetUnionChoicesList(TpmType t)
        {
            if (!(t is TpmUnion))
            {
                return("");
            }
            var    uniqueFields = (t as TpmUnion).Members.Distinct().ToList();
            string unionList    = string.Join(", ", uniqueFields.ConvertAll(f => f.Type.Name).Distinct());

            return($"One of: {unionList}.");
        }
예제 #8
0
파일: TpmTypes.cs 프로젝트: rgl/TSS.MSR
        public void Add(UnionMember newMem)
        {
            Members.Add(newMem);

            TpmType tdt = newMem.Type.StripTypedefs();

            if (tdt is TpmStruct)
            {
                (tdt as TpmStruct).RegisterContainingUnion(this);
            }
        }
예제 #9
0
        public static string TranslateTypeName(TpmType t)
        {
            var underType = t.StripTypedefs();

            if (underType is TpmValueType)
            {
                return(TargetLang.NameFor(underType.SpecName));
            }

            return(TargetLang.DotNet ? (underType is TpmUnion ? "I" : "") + TypeToDotNet(underType.SpecName)
                                     : underType.SpecName);
        }
예제 #10
0
        static void FixEnumTypeCollisions()
        {
            List <TpmStruct> toAdd = new List <TpmStruct>();

            for (int j = 0; j < TpmTypes.TheTypes.Count; j++)
            {
                TpmType tp = TpmTypes.TheTypes[j];
                if (!(tp is TpmUnion &&
                      tp.SpecName.IsOneOf(new string[] { "TPMU_PUBLIC_ID", "TPMU_SIGNATURE" })))
                {
                    continue;
                }

                // See if we have collisions.
                // Collided member types are converted into derived types by adding selector name to the base
                // type name. Struct that became a base one inherits from all the union interfaces, while
                // a derived struct only inherits from the base one and implements interfaces of the unions,
                // of which it is a member.
                // Base class B provides a union interface implementation only if this union contains a member
                // of type B. If a union U contains members of types derived from B, then B's implementation
                // of U's interface methods just throws NotImplementedException exception.
                TpmUnion u    = (TpmUnion)tp;
                var      dict = new Dictionary <string, UnionMember>();
                foreach (UnionMember m in u.Members)
                {
                    string typeName     = m.Type.SpecName;
                    string selectorName = m.SelectorValue.Name;
                    if (dict.ContainsKey(typeName))
                    {
                        // Collision detected.
                        Debug.WriteLine("Collision in {0} [{1}] -- {2}", u.Name, selectorName, typeName);

                        TpmStruct baseStruct = (TpmStruct)TpmTypes.Lookup(typeName);
                        AddDerivedStruct(baseStruct, m, u,
                                         "Auto-derived from " + baseStruct.SpecName +
                                         " to provide unique GetUnionSelector() implementation");
                        if (dict[typeName] != null)
                        {
                            // Create the derived structure for the first occurrence.
                            AddDerivedStruct(baseStruct, dict[typeName], u);
                            // But do it only once...
                            dict[typeName] = null;
                        }
                    }
                    else
                    {
                        dict.Add(typeName, m);
                    }
                }
            }
        } // FixEnumTypeCollisions()
예제 #11
0
파일: CGenDotNet.cs 프로젝트: rgl/TSS.MSR
        void GenEnum(TpmType e, List <TpmNamedConstant> elements, bool needsNone = false)
        {
            WriteComment(e);
            if (e is TpmBitfield)
            {
                Write("[Flags]");
            }
            Write("[DataContract]");
            Write($"[SpecTypeName(\"{e.SpecName}\")]");
            Write($"public enum {e.Name} : {e.GetFinalUnderlyingType().Name}");
            TabIn("{");

            if (needsNone)
            {
                Write("None = 0,");
            }

            foreach (TpmNamedConstant nc in elements)
            {
                string commaAfterOld = Separator(nc, elements);
                string comma         = nc.Name != nc.OldStyleName ? "," : commaAfterOld;

                WriteComment(nc);
                Write("[EnumMember]");

                string value        = nc.Value,
                       valueComment = "";
                if (nc.SpecValue.Expr != null)
                {
                    // Bitfields keep their member names unchanged, so they do not need the SpecTypeName attr.
                    Write($"[SpecTypeName(\"{nc.SpecName}\")]");

                    uint val = unchecked ((uint)nc.NumericValue);
                    valueComment = Expression.IsNumber(nc.SpecValue.Expr) ? "" : " // 0x" + val.ToString("X");
                    if (val >= unchecked ((uint)(0x90 << 24)))
                    {
                        value = $"unchecked (({e.GetFinalUnderlyingType().Name})({nc.Value}))";
                    }
                }
                Write($"{nc.Name} = {value}{comma}{valueComment}");

                if (nc.Name != nc.OldStyleName)
                {
                    Write($"[Obsolete(\"Use {e.Name}.{nc.Name} instead\")]");
                    Write($"{nc.OldStyleName} = {nc.Value}{commaAfterOld}");
                }
            }
            ;
            TabOut("}");
        } // GenEnum()
예제 #12
0
파일: TpmTypes.cs 프로젝트: rgl/TSS.MSR
        internal static void Add(TpmType t, string insertAfter = null)
        {
            if (TypeIndex.ContainsKey(t.SpecName))
            {
                Debug.WriteLine($"TpmType.Add: Type {t.SpecName} is already defined");
                return;
            }

            if (insertAfter == null)
            {
                TheTypes.Add(t);
            }
            else
            {
                TheTypes.Insert(TheTypes.IndexOf(TheTypes.First(x => x.SpecName == insertAfter)) + 1, t);
            }

            TypeIndex.Add(t.SpecName, t);
            return;
        }
예제 #13
0
파일: TpmTypes.cs 프로젝트: rgl/TSS.MSR
 public UnionMember GetElementOfType(TpmStruct s)
 {
     // First look for the exact type match ...
     foreach (UnionMember m in Members)
     {
         if (m.Type.SpecName == s.SpecName)
         {
             return(m);
         }
     }
     // ... then see if we have a matching typedef or derived type
     foreach (UnionMember m in Members)
     {
         if (m.Type is TpmTypedef)
         {
             TpmType underlyingType = m.Type.StripTypedefs();
             if (underlyingType.SpecName == s.SpecName)
             {
                 return(m);
             }
         }
         else if (m.Type is TpmStruct)
         {
             TpmStruct b = (m.Type as TpmStruct).DerivedFrom;
             while (b != null)
             {
                 if (b.SpecName == s.SpecName)
                 {
                     return(m);
                 }
                 b = b.DerivedFrom;
             }
         }
     }
     return(null);
 }
예제 #14
0
파일: TpmTypes.cs 프로젝트: rgl/TSS.MSR
 public TpmField(string fieldTypeName, string fieldName, string comment)
 {
     Type    = TpmTypes.Lookup(fieldTypeName);
     Name    = fieldName;
     Comment = comment;
 }
예제 #15
0
        /// <summary> Makes constant values specified as arithmetic expressions comply with the current
        /// langauge syntax (adds enum type name qualifiers and type casts when necessary, eliminates
        /// sizeof() operators when unsupported, etc.) </summary>
        public static string TranslateConstExpr(TpmConstExpr ce, TpmEnum enclosingEnum = null)
        {
            var nameDelimiters = new char[] { ' ', ',', '{', '}',
                                              '(', ')', '+', '-', '<', '*', '/', '`' };
            string suffix = TargetLang.Java ? ".toInt()" : "";
            string expr   = ce.Expr;

            string[] tokens         = expr.Split(nameDelimiters);
            bool     sizeofOccurred = false,
                     commentNeeded  = false;

            foreach (string token in tokens)
            {
                if (token.Length == 0)
                {
                    continue;
                }
                if (token == "sizeof")
                {
                    Debug.Assert(!sizeofOccurred);
                    sizeofOccurred = true;
                    continue;
                }
                if (Expression.IsNumber(token))
                {
                    if (token == "00")
                    {
                        Debug.Assert(expr == token);
                        expr = "0";
                    }
                    Debug.Assert(!sizeofOccurred);
                    continue;
                }

                TpmNamedConstant nc = TpmTypes.LookupConstant(token);
                if (enclosingEnum != null && nc?.EnclosingEnum == enclosingEnum)
                {
                    // Members of the enum being processed do not need to be qualified
                    Debug.Assert(token == nc.SpecName);
                    expr = expr.Replace(token, nc.Name + suffix);
                    continue;
                }
                if (!TpmTypes.ContainsConstant(token))
                {
                    // This must be a type name operand of sizeof()
                    Debug.Assert(sizeofOccurred);
                    sizeofOccurred = false;
                    TpmType t = TpmTypes.Lookup(token);
                    if (t is TpmStruct || TargetLang.IsOneOf(Lang.Java, Lang.JS, Lang.Py))
                    {
                        string sizeofExpr = "sizeof(" + token + ")";
                        Debug.Assert(expr.Contains(sizeofExpr));
                        commentNeeded = TargetLang.Py;
                        string origExpr = TargetLang.Py ? "" : $"/*{sizeofExpr}*/";
                        expr = expr.Replace(sizeofExpr, $"0x{t.GetSize():X}{origExpr}");
                    }
                    else if (TargetLang.DotNet)
                    {
                        expr = expr.Replace(token, t.StripTypedefs().Name);
                    }
                }
                else
                {
                    nc = TpmTypes.LookupConstant(token);
                    var translated = nc.QualifiedName + suffix;
                    if (!TargetLang.IsGenerated(nc.EnclosingEnum))
                    {
                        translated = nc.NumericValue.ToString();
                        if (!TargetLang.Py)
                        {
                            translated += "/*" + token + "*/";
                        }
                        else
                        {
                            commentNeeded = true;
                        }
                    }
                    expr = expr.Replace(token, translated);
                }
            } // foreach token

            if (TargetLang.DotNet && expr.Contains("<<"))
            {
                // Shift operator in .Net requires right operand of type 'int' and unsigned left one.
                int curPos = 0;
                expr = expr.Replace(" << ", "<<");
                do
                {
                    int pos = expr.IndexOf("<<", curPos);
                    if (pos == -1)
                    {
                        break;
                    }
                    curPos = pos + 2 + 6; // Add sizes of "<<" and "(uint)"
                    while (char.IsLetterOrDigit(expr[--pos]) || expr[pos] == '.')
                    {
                        continue;
                    }
                    expr = expr.Insert(pos + 1, "(uint)");
                } while (true);
                expr = expr.Replace("<<", " << (int)");
            }

            if (commentNeeded)
            {
                expr += $"  # {ce.Expr}";
            }
            return(expr);
        } // TranslateConstExpr()
예제 #16
0
        /// <summary> Constants and bitfields are represented as classes derived
        /// from TpmEnum, and TpmAttribute correspondingly in Java </summary>
        void GenEnum(TpmType e, List <TpmNamedConstant> elements, int wireSize)
        {
            needsUtil = true;  // Collection needs java.util.*

            WriteComment(e);

            string baseClass = e is TpmEnum ? "TpmEnum" : "TpmAttribute";

            Write($"public final class {e.Name} extends {baseClass}<{e.Name}>");
            TabIn("{");
            WriteComment("Values from enum _N are only intended to be used in case labels of a switch " +
                         "statement using the result of this.asEnum() method as the switch condition. " +
                         "However, their Java names are identical to those of the constants defined in this class further below, " +
                         $"so for any other usage just prepend them with the {e.Name}. qualifier.");
            Write("public enum _N {");
            TabIn();
            foreach (var v in elements)
            {
                WriteComment(v);
                Write($"{v.Name}{Separator(v, elements)}");
            }
            TabOut("}");

            Write($"private static ValueMap<{e.Name}> _ValueMap = new ValueMap<{e.Name}>();");

            WriteComment("These definitions provide mapping of the Java enum constants to their TPM integer values");
            Write($"public static final {e.Name}");
            TabIn();

            foreach (var v in elements)
            {
                // Workaround for multiple enum members with the same value.
                // Conversion from int will never return enumerators in the following if-statement
                string conflict  = e is TpmEnum && ConflictingEnumMember(v.Name, e.Name) ? ", true" : "";
                string delimiter = Separator(v, elements, ",", ";");
                Write($"{v.Name} = new {e.Name}({v.Value}, _N.{v.Name}{conflict}){delimiter}");
            }
            TabOut("");

            // Backward compat
            if (e.Name == "TPM_RH")
            {
                WriteComment("@deprecated Use {@link #PW} instead");
                Write("@Deprecated");
                Write($"public static final {e.Name} RS_PW = new {e.Name}(PW.toInt(), _N.PW, true);", true);
            }

            Write($"public {e.Name} () {{ super(0, _ValueMap); }}", true);
            Write($"public {e.Name} (int value) {{ super(value, _ValueMap); }}", true);
            if (e is TpmBitfield)
            {
                Write($"public {e.Name} ({e.Name}...attrs) {{ super(_ValueMap, attrs); }}", true);
            }
            Write($"public static {e.Name} fromInt (int value) {{ return TpmEnum.fromInt(value, _ValueMap, {e.Name}.class); }}", true);
            Write($"public static {e.Name} fromTpm (byte[] buf) {{ return TpmEnum.fromTpm(buf, _ValueMap, {e.Name}.class); }}", true);
            Write($"public static {e.Name} fromTpm (TpmBuffer buf) {{ return TpmEnum.fromTpm(buf, _ValueMap, {e.Name}.class); }}", true);
            Write($"public {e.Name}._N asEnum() {{ return ({e.Name}._N)NameAsEnum; }}", true);
            Write($"public static Collection<{e.Name}> values() {{ return _ValueMap.values(); }}", true);
            if (e is TpmBitfield)
            {
                Write($"public boolean hasAttr ({ e.Name} attr) {{ return super.hasAttr(attr); }}", true);
                Write($"public {e.Name} maskAttr ({e.Name} attr) {{ return super.maskAttr(attr, _ValueMap, {e.Name}.class); }}", true);
            }

            // Do not include params and bits of a mask of a multibit member of a bitfield
            // into the fromInt() conversion map
            Write($"private {e.Name} (int value, _N nameAsEnum) {{ super(value, nameAsEnum, _ValueMap); }}", true);
            Write($"private {e.Name} (int value, _N nameAsEnum, boolean noConvFromInt) {{ super(value, nameAsEnum, null); }}", true);

            Write("@Override");
            Write($"protected int wireSize() {{ return {wireSize}; }}");

            InsertSnip(e.Name);
            TabOut("}", false);
        } // GenEnum
예제 #17
0
 private void WriteComment(string comment, TpmType t)
 {
     WriteComment(AsSummary(comment) + AsRemark(GetUnionChoicesList(t)));
 }
예제 #18
0
 protected void WriteComment(TpmType t)
 {
     WriteComment(t.Comment, t);
 }
예제 #19
0
파일: TpmTypes.cs 프로젝트: rgl/TSS.MSR
 public TpmType(TpmType src)
 {
     Init(src.SpecName, src.Comment, src.Size, src.UnderlyingType);
 }
예제 #20
0
파일: CGenDotNet.cs 프로젝트: rgl/TSS.MSR
        void GenHandleTable()
        {
            Write("//-----------------------------------------------------------------------------");
            Write("//------------------------- COMMAND INFO -----------------------------------");
            Write("//-----------------------------------------------------------------------------");
            Write("public static class CommandInformation");
            TabIn("{");
            Write("public static CommandInfo[] Info = new CommandInfo[]");
            TabIn("{");
            bool printComma = false;

            foreach (var req in TpmTypes.Get <TpmStruct>().Where(s => s.Info.IsRequest()))
            {
                TpmStruct resp          = GetRespStruct(req);
                string    cmdName       = GetCommandName(req);
                string    transCmdName  = TargetLang.TypeToDotNet(cmdName);
                string    reqStructName = "Tpm2" + transCmdName + "Request";

                // encryptable parms?
                ParmCryptInfo cryptInfo = 0;

                if (req.Fields.Count > req.NumHandles)
                {
                    // find the first field that is not a handle
                    StructField parm0 = req.Fields[req.NumHandles];
                    if (parm0.MarshalType.IsOneOf(MarshalType.LengthOfStruct, MarshalType.ArrayCount))
                    {
                        string typeName = parm0.Type.StripTypedefs().Name;
                        if (typeName == "uint")
                        {
                            cryptInfo |= ParmCryptInfo.EncIn4;
                        }
                        else if (typeName == "ushort")
                        {
                            cryptInfo |= ParmCryptInfo.Enc2In2;
                        }
                    }
                }
                if (resp.Fields.Count > resp.NumHandles)
                {
                    // find the first field that is not a handle
                    StructField parm0 = resp.Fields[resp.NumHandles];
                    if (parm0.MarshalType.IsOneOf(MarshalType.LengthOfStruct, MarshalType.ArrayCount))
                    {
                        string typeName = parm0.Type.StripTypedefs().Name;
                        if (typeName == "uint")
                        {
                            cryptInfo |= ParmCryptInfo.DecOut4;
                        }
                        else if (typeName == "ushort")
                        {
                            cryptInfo |= ParmCryptInfo.DecOut2;
                        }
                    }
                }

                string handleTypeNames = "";
                // types of input handles
                if (req.NumHandles > 0)
                {
                    for (int j = 0; j < req.NumHandles; j++)
                    {
                        StructField hField         = req.Fields[j];
                        string      origHandleType = hField.Type.SpecName;
                        handleTypeNames += origHandleType + " ";
                        TpmType tpx = TpmTypes.Lookup(origHandleType);
                    }
                }
                handleTypeNames = handleTypeNames.TrimEnd(new char[] { ' ' });
                handleTypeNames = "\"" + handleTypeNames + "\"";

                string respTypeId = !resp.Implement ? "EmptyResponse"
                                  : resp.Name;

                WriteComma(ref printComma);
                Write($"new CommandInfo(TpmCc.{transCmdName}, {req.NumHandles}, {resp.NumHandles}, {req.NumAuthHandles}, " +
                      $"typeof({reqStructName}), typeof({respTypeId}), {(uint)cryptInfo}, {handleTypeNames})", false);
            }
            TabOut("};");
            TabOut("}");
        }