private CodedIndex DecodeIndex(uint value, IndexDetails withDetails) { byte code = 0; uint index = 0; if (withDetails.IsLarge()) { code = (byte)(value & withDetails.Mask); index = (value & ~withDetails.Mask) >> withDetails.BitsToRepresentTag; } else { ushort inMask = (ushort)withDetails.Mask; ushort shortValue = (ushort)value; code = (byte)(value & inMask); index = (ushort)((shortValue & ~inMask) >> withDetails.BitsToRepresentTag); // shift to drop the masked bits } return(new CodedIndex(withDetails.Tables[code], index)); }
private Dictionary <CodedIndexes, IndexDetails> BuildDetailsMap(Dictionary <MetadataTables, int> rowsPerTableData) { IEnumerable <CodedIndexes> values = Enum.GetValues(typeof(CodedIndexes)).Cast <CodedIndexes>(); Dictionary <CodedIndexes, IndexDetails> map = new Dictionary <CodedIndexes, IndexDetails>(); foreach (CodedIndexes current in values) { IndexDetails details = DetermineDetailsForIndexType(current); foreach (MetadataTables table in details.Tables) { if (rowsPerTableData.Keys.Contains(table)) { if (details.MaxRowsInTables < rowsPerTableData[table]) { details.MaxRowsInTables = (uint)rowsPerTableData[table]; } } } map.Add(current, details); } return(map); }
internal MetadataStream(PeCoffFile file, uint address) { _owningFile = file; byte[] contents = file.FileContents; Offset offset = (int)address; offset.Shift(4); // reserved1 = BitConverter.ToUInt32(contents, offset.Shift(4)); offset.Shift(1); // majorVersion = contents[offset.Shift(1)]; offset.Shift(1); // minorVersion = contents[offset.Shift(1)]; _heapOffsetSizes = (HeapOffsetSizes)contents.GetValue(offset.Shift(1)); offset.Shift(1); // reserved2 = contents[offset.Shift(1)]; ulong valid = BitConverter.ToUInt64(contents, offset.Shift(8)); offset.Shift(8); // sorted = BitConverter.ToUInt64(contents, offset.Shift(8)); // Now we need to read the number of rows present in the available tables, we have // had to add the unused tables to the MEtadatTables as mscorlib seems to use one. Not // sure which though. Dictionary <MetadataTables, int> rowsInPresentTables = new Dictionary <MetadataTables, int>(); Array values = Enum.GetValues(typeof(MetadataTables)); for (int i = 0; i < values.Length - 1; i++) { MetadataTables current = (MetadataTables)values.GetValue(i); ulong mask = (ulong)1 << (int)current; if ((mask & valid) == mask) { rowsInPresentTables.Add(current, BitConverter.ToInt32(contents, offset.Shift(4))); } } // build index helper classes for metadata row creation ICodedIndexResolver resolver = new CodedIndexResolver(rowsInPresentTables); IIndexDetails indexDetails = new IndexDetails(rowsInPresentTables, SizeOfStringIndexes, SizeOfBlobIndexes, SizeOfGuidIndexes ); // Following the array of row size we get the actual metadata tables _tables = new MetadataTablesDictionary(rowsInPresentTables.Count); for (int i = 0; i < values.Length; i++) { MetadataTables current = (MetadataTables)values.GetValue(i); if (!rowsInPresentTables.ContainsKey(current)) { continue; } int numRows = rowsInPresentTables[current]; MetadataRow[] rows = new MetadataRow[numRows]; switch (current) { case MetadataTables.Module: for (int j = 0; j < numRows; j++) { rows[j] = new ModuleMetadataTableRow(contents, offset, indexDetails); } break; case MetadataTables.TypeRef: for (int j = 0; j < numRows; j++) { rows[j] = new TypeRefMetadataTableRow(contents, offset, resolver, indexDetails); } break; case MetadataTables.TypeDef: for (int j = 0; j < numRows; j++) { rows[j] = new TypeDefMetadataTableRow(contents, offset, resolver, indexDetails); } break; case MetadataTables.Field: for (int j = 0; j < numRows; j++) { rows[j] = new FieldMetadataTableRow(contents, offset, indexDetails); } break; case MetadataTables.MethodDef: for (int j = 0; j < numRows; j++) { rows[j] = new MethodMetadataTableRow(contents, offset, indexDetails); } break; case MetadataTables.Param: for (int j = 0; j < numRows; j++) { rows[j] = new ParamMetadataTableRow(contents, offset, SizeOfStringIndexes); } break; case MetadataTables.InterfaceImpl: for (int j = 0; j < numRows; j++) { rows[j] = new InterfaceImplMetadataTableRow(contents, offset, resolver, indexDetails); } break; case MetadataTables.MemberRef: for (int j = 0; j < numRows; j++) { rows[j] = new MemberRefMetadataTableRow(contents, offset, resolver, indexDetails); } break; case MetadataTables.Constant: for (int j = 0; j < numRows; j++) { rows[j] = new ConstantMetadataTableRow(contents, offset, resolver, indexDetails); } break; case MetadataTables.CustomAttribute: for (int j = 0; j < numRows; j++) { rows[j] = new CustomAttributeMetadataTableRow(contents, offset, resolver, indexDetails); } break; case MetadataTables.FieldMarshal: for (int j = 0; j < numRows; j++) { rows[j] = new FieldMarshalMetadataTableRow(contents, offset, resolver, indexDetails); } break; case MetadataTables.DeclSecurity: for (int j = 0; j < numRows; j++) { rows[j] = new DeclSecurityMetadataTableRow(contents, offset, resolver, indexDetails); } break; case MetadataTables.ClassLayout: for (int j = 0; j < numRows; j++) { rows[j] = new ClassLayoutMetadataTableRow(contents, offset, indexDetails); } break; case MetadataTables.FieldLayout: for (int j = 0; j < numRows; j++) { rows[j] = new FieldLayoutMetadataTableRow(contents, offset, indexDetails); } break; case MetadataTables.StandAloneSig: for (int j = 0; j < numRows; j++) { rows[j] = new StandAloneSigMetadataTableRow(contents, offset, indexDetails); } break; case MetadataTables.EventMap: for (int j = 0; j < numRows; j++) { rows[j] = new EventMapMetadataTableRow(contents, offset, indexDetails); } break; case MetadataTables.Event: for (int j = 0; j < numRows; j++) { rows[j] = new EventMetadataTableRow(contents, offset, resolver, indexDetails); } break; case MetadataTables.PropertyMap: for (int j = 0; j < numRows; j++) { rows[j] = new PropertyMapMetadataTableRow(contents, offset, indexDetails); } break; case MetadataTables.Property: for (int j = 0; j < numRows; j++) { rows[j] = new PropertyMetadataTableRow(contents, offset, indexDetails); } break; case MetadataTables.MethodSemantics: for (int j = 0; j < numRows; j++) { rows[j] = new MethodSemanticsMetadataTableRow(contents, offset, resolver, indexDetails); } break; case MetadataTables.MethodImpl: for (int j = 0; j < numRows; j++) { rows[j] = new MethodImplMetadataTableRow(contents, offset, resolver, indexDetails); } break; case MetadataTables.ModuleRef: for (int j = 0; j < numRows; j++) { rows[j] = new ModuleRefMetadataTableRow(contents, offset, indexDetails); } break; case MetadataTables.TypeSpec: for (int j = 0; j < numRows; j++) { rows[j] = new TypeSpecMetadataTableRow(contents, offset, indexDetails); } break; case MetadataTables.ImplMap: for (int j = 0; j < numRows; j++) { rows[j] = new ImplMapMetadataTableRow(contents, offset, resolver, indexDetails); } break; case MetadataTables.FieldRVA: for (int j = 0; j < numRows; j++) { rows[j] = new FieldRVAMetadataTableRow(contents, offset, indexDetails); } break; case MetadataTables.Assembly: for (int j = 0; j < numRows; j++) { rows[j] = new AssemblyMetadataTableRow(contents, offset, indexDetails); } break; case MetadataTables.AssemblyProcessor: for (int j = 0; j < numRows; j++) { rows[j] = new AssemblyProcessorMetadataTableRow(contents, offset); } break; case MetadataTables.AssemblyOS: for (int j = 0; j < numRows; j++) { rows[j] = new AssemblyOSMetadataTableRow(contents, offset); } break; case MetadataTables.AssemblyRef: for (int j = 0; j < numRows; j++) { rows[j] = new AssemblyRefMetadataTableRow(contents, offset, indexDetails); } break; case MetadataTables.AssemblyRefProcessor: for (int j = 0; j < numRows; j++) { rows[j] = new AssemblyRefProcessorMetadataTableRow(contents, offset, indexDetails); } break; case MetadataTables.AssemblyRefOS: for (int j = 0; j < numRows; j++) { rows[j] = new AssemblyRefOSMetadataTableRow(contents, offset, indexDetails); } break; case MetadataTables.File: for (int j = 0; j < numRows; j++) { rows[j] = new FileMetadataTableRow(contents, offset, indexDetails); } break; case MetadataTables.ExportedType: for (int j = 0; j < numRows; j++) { rows[j] = new ExportedTypeMetadataTableRow(contents, offset, resolver, indexDetails); } break; case MetadataTables.ManifestResource: for (int j = 0; j < numRows; j++) { rows[j] = new ManifestResourceMetadataTableRow(contents, offset, resolver, indexDetails); } break; case MetadataTables.NestedClass: for (int j = 0; j < numRows; j++) { rows[j] = new NestedClassMetadataTableRow(contents, offset, indexDetails); } break; case MetadataTables.GenericParam: for (int j = 0; j < numRows; j++) { rows[j] = new GenericParamMetadataTableRow(contents, offset, resolver, indexDetails); } break; case MetadataTables.MethodSpec: for (int j = 0; j < numRows; j++) { rows[j] = new MethodSpecMetadataTableRow(contents, offset, resolver, indexDetails); } break; case MetadataTables.GenericParamConstraint: for (int j = 0; j < numRows; j++) { rows[j] = new GenericParamConstraintMetadataTableRow(contents, offset, resolver, indexDetails); } break; } _tables.SetMetadataTable(current, rows); } }
private IndexDetails DetermineDetailsForIndexType(CodedIndexes codedIndex) { IndexDetails details = new IndexDetails(); details.Tables = new List <MetadataTables>(); switch (codedIndex) { case CodedIndexes.HasFieldMarshall: details.Tables.Add(MetadataTables.Field); details.Tables.Add(MetadataTables.Param); details.Mask = 0x01; break; case CodedIndexes.HasSemantics: details.Tables.Add(MetadataTables.Event); details.Tables.Add(MetadataTables.Property); details.Mask = 0x01; break; case CodedIndexes.MethodDefOrRef: details.Tables.Add(MetadataTables.MethodDef); details.Tables.Add(MetadataTables.MemberRef); details.Mask = 0x01; break; case CodedIndexes.MemberForwarded: details.Tables.Add(MetadataTables.Field); details.Tables.Add(MetadataTables.MethodDef); details.Mask = 0x01; break; case CodedIndexes.TypeOrMethodDef: details.Tables.Add(MetadataTables.TypeDef); details.Tables.Add(MetadataTables.MethodDef); details.Mask = 0x01; break; case CodedIndexes.TypeDefOrRef: details.Tables.Add(MetadataTables.TypeDef); details.Tables.Add(MetadataTables.TypeRef); details.Tables.Add(MetadataTables.TypeSpec); details.Mask = 0x03; break; case CodedIndexes.HasConstant: details.Tables.Add(MetadataTables.Field); details.Tables.Add(MetadataTables.Param); details.Tables.Add(MetadataTables.Property); details.Mask = 0x03; break; case CodedIndexes.HasDeclSecurity: details.Tables.Add(MetadataTables.TypeDef); details.Tables.Add(MetadataTables.MethodDef); details.Tables.Add(MetadataTables.Assembly); details.Mask = 0x03; break; case CodedIndexes.Implementation: details.Tables.Add(MetadataTables.File); details.Tables.Add(MetadataTables.AssemblyRef); details.Tables.Add(MetadataTables.ExportedType); details.Mask = 0x03; break; case CodedIndexes.ResolutionScope: details.Tables.Add(MetadataTables.Module); details.Tables.Add(MetadataTables.ModuleRef); details.Tables.Add(MetadataTables.AssemblyRef); details.Tables.Add(MetadataTables.TypeRef); details.Mask = 0x03; break; case CodedIndexes.MemberRefParent: details.Tables.Add(MetadataTables.TypeDef); details.Tables.Add(MetadataTables.TypeRef); details.Tables.Add(MetadataTables.ModuleRef); details.Tables.Add(MetadataTables.MethodDef); details.Tables.Add(MetadataTables.TypeSpec); details.Mask = 0x07; break; case CodedIndexes.CustomAttributeType: details.Tables.Add(MetadataTables.Unused1); details.Tables.Add(MetadataTables.Unused1); details.Tables.Add(MetadataTables.MethodDef); details.Tables.Add(MetadataTables.MemberRef); details.Tables.Add(MetadataTables.Unused1); details.Mask = 0x07; break; case CodedIndexes.HasCustomAttribute: details.Tables.Add(MetadataTables.MethodDef); details.Tables.Add(MetadataTables.Field); details.Tables.Add(MetadataTables.TypeRef); details.Tables.Add(MetadataTables.TypeDef); details.Tables.Add(MetadataTables.Param); details.Tables.Add(MetadataTables.InterfaceImpl); details.Tables.Add(MetadataTables.MemberRef); details.Tables.Add(MetadataTables.Module); details.Tables.Add(MetadataTables.DeclSecurity); details.Tables.Add(MetadataTables.Property); details.Tables.Add(MetadataTables.Event); details.Tables.Add(MetadataTables.StandAloneSig); details.Tables.Add(MetadataTables.ModuleRef); details.Tables.Add(MetadataTables.TypeSpec); details.Tables.Add(MetadataTables.Assembly); details.Tables.Add(MetadataTables.AssemblyRef); details.Tables.Add(MetadataTables.File); details.Tables.Add(MetadataTables.ExportedType); details.Tables.Add(MetadataTables.ManifestResource); details.Tables.Add(MetadataTables.GenericParam); details.Tables.Add(MetadataTables.GenericParamConstraint); details.Tables.Add(MetadataTables.MethodSpec); details.Mask = 0x1F; break; } details.BitsToRepresentTag = details.Mask == 1 ? (byte)1 : (byte)Math.Round(Math.Log(details.Mask, 2), MidpointRounding.AwayFromZero); return(details); }