static void FixTpm2bStructs() { foreach (var s in TpmTypes.Get <TpmStruct>().Where(s => s.Fields.Count == 2 && s.StripTypedefs().SpecName.StartsWith("TPM2B_"))) { var tagField = s.Fields[0]; var dataField = s.Fields[1]; if (tagField.MarshalType == MarshalType.ArrayCount) { // A TPM2B struct has a byte count as the first member that contains the size of the second member. // The second member can be either a byte buffer or a data structure. In the latter case the type // of the data structure can be obtained from the name of the TPM2B struct. string structName = s.SpecName.Replace("TPM2B_", "TPMS_"); if (!TpmTypes.Contains(structName)) { continue; } dataField = s.Fields[1] = new StructField(structName, dataField.Name, dataField.Comment); } tagField.MarshalType = MarshalType.LengthOfStruct; dataField.MarshalType = MarshalType.SizedStruct; tagField.SizedField = dataField; dataField.SizeTagField = tagField; dataField.Domain = tagField.Domain; } }
public TpmStruct(string typeName, string comment, TpmStruct derivedFrom = null, StructInfo info = null, bool customizedImpl = false) : base(typeName, comment) { Fields = new List <StructField>(); DerivedFrom = derivedFrom; Debug.Assert(DerivedFrom == null || TpmTypes.Contains(DerivedFrom.SpecName)); Info = info ?? new TpmStructInfo(); }
public static List <TpmNamedConstant> GetBifieldElements(TpmBitfield bf) { var elements = new List <TpmNamedConstant>(); foreach (var b in bf.Elements) { if (b.StartBit == b.EndBit) { AddBitfieldElt(elements, b.TranslatedName, 1 << b.StartBit, b.Comment, b.OldStyleName); } else // multibit members of a bitfield { string typeName = b.Name; if (TpmTypes.Contains(typeName)) { // Type typeName defines allowed values for this multi-bit field var e = TpmTypes.Lookup(typeName) as TpmEnum; if (e != null) { foreach (var v in e.Members) { AddBitfieldElt(elements, v.Name, v.NumericValue << b.EndBit, v.Comment); } } } // Multi-bit bitfield 'name' is additionally represented by several enumerators: // name_BIT_MASK - bit mask selecting all bits of the field // name_BIT_OFFSET - offset of the field's low order bit // name_BIT_LENGTH - number of bits in the field string nameBase = b.Name.Contains("_") ? TargetLang.NameToDotNet(b.Name) : b.Name; int len = b.StartBit - b.EndBit + 1; var suff = TargetLang.DotNet ? new string[] { "BitMask", "BitOffset", "BitLength" } : new string[] { "_BIT_MASK", "_BIT_OFFSET", "_BIT_LENGTH" }; AddBitfieldElt(elements, nameBase + suff[0], ((1 << len) - 1) << b.EndBit, b.Comment, null, true); AddBitfieldElt(elements, nameBase + suff[1], b.EndBit, null, null, true); AddBitfieldElt(elements, nameBase + suff[2], len, null, null, true); if (TargetLang.DotNet && bf.Name == "LocalityAttr") { // For backward compatibility for (int i = 0; i < len; ++i) { AddBitfieldElt(elements, $"{nameBase}Bit{i}", 1 << (b.EndBit + i), "", null, true); } } } // multibit members of a bitfield } return(elements); }
public static void AddDerivedStruct(TpmStruct baseStruct, UnionMember curMember, TpmUnion curUnion, string comment = null) { string baseTypeName = baseStruct.SpecName; string newTypeName = baseTypeName + "_" + RemoveEnumPrefix(curMember.SelectorValue.SpecName, curMember.SelectorValue.EnclosingEnum.SpecName); if (!TpmTypes.Contains(newTypeName)) { var newStruct = new TpmStruct(newTypeName, comment ?? "Auto-derived from " + baseTypeName, baseStruct); TpmTypes.Add(newStruct); } var s = (TpmStruct)TpmTypes.Lookup(newTypeName); s.RegisterContainingUnion(curUnion); // Fix up the union field curMember.Type = s; }
/// <remarks> If this method goes into an infinite loop, this usually means that /// the Part 2, or Vendor Specicfic part of the TPM 2.0 spec added a new constant /// value defined not in a table, but rather in a NOTE. In this case this definition /// needs to be manually added into the ImplementationConstants array. </remarks> public static int Eval(string val) { if (IsNumber(val)) { return(Convert.ToInt32(val, val.ToLower().StartsWith("0x") ? 16 : 10)); } if (TpmTypes.ContainsConstant(val)) { return(TpmTypes.LookupConstant(val).NumericValue); } var tokens = Tokenize(val); var ops = new Stack <Operator>(); var values = new Stack <Operand>(); for (int i = 0; i < tokens.Length; ++i) { var tok = tokens[i]; if (tok is Operand) { values.Push((Operand)tok); continue; } var op = (Operator)tok; if (op.Is(OpCode.Sizeof)) { Debug.Assert(tokens.Length > i + 2); string typeName = (tokens[i + 2] as Operand).Value; Debug.Assert(TpmTypes.Contains(typeName)); var e = TpmTypes.Lookup(typeName); // Workaround for _PRIVATE max size values.Push(new Operand(typeName == "_PRIVATE" ? 1024 : e.GetSize())); i += 3; continue; } if (ops.Count == 0 || op.Is(OpCode.LeftParen) || ops.Peek() < op) { Debug.Assert(!op.Is(OpCode.RightParen)); ops.Push(op); continue; } else { do { Operator prevOp = ops.Pop(); if (prevOp.Is(OpCode.LeftParen)) { Debug.Assert(op.Is(OpCode.RightParen)); break; } prevOp.Apply(values); }while (ops.Count > 0 && ops.Peek() >= op); if (!op.Is(OpCode.RightParen)) { ops.Push(op); } } } while (ops.Count > 0) { ops.Pop().Apply(values); } Debug.Assert(values.Count == 1); int res = values.Pop().NumericValue; return(res); }