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); }
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()
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; }
/// <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); }
} // 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()
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()
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}."); }
public void Add(UnionMember newMem) { Members.Add(newMem); TpmType tdt = newMem.Type.StripTypedefs(); if (tdt is TpmStruct) { (tdt as TpmStruct).RegisterContainingUnion(this); } }
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); }
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()
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()
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; }
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); }
public TpmField(string fieldTypeName, string fieldName, string comment) { Type = TpmTypes.Lookup(fieldTypeName); Name = fieldName; Comment = comment; }
/// <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()
/// <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
private void WriteComment(string comment, TpmType t) { WriteComment(AsSummary(comment) + AsRemark(GetUnionChoicesList(t))); }
protected void WriteComment(TpmType t) { WriteComment(t.Comment, t); }
public TpmType(TpmType src) { Init(src.SpecName, src.Comment, src.Size, src.UnderlyingType); }
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("}"); }