3 using System.Collections;
5 using System.Reflection;
12 /// flags for the assembly (.corflags)
14 public enum CorFlags {CF_IL_ONLY = 1, CF_32_BITREQUIRED = 2,
15 CF_STRONGNAMESIGNED = 8, CF_TRACKDEBUGDATA = 0x10000 }
18 /// subsystem for the assembly (.subsystem)
20 public enum SubSystem { Native = 1, Windows_GUI = 2,
21 Windows_CUI = 3, OS2_CUI = 5, POSIX_CUI = 7, Native_Windows = 8,
25 /// Hash algorithms for the assembly
27 public enum HashAlgorithm { None, SHA1 }
30 /// Attributes for this assembly
32 public enum AssemAttr { EnableJITCompileTracking = 0x8000,
33 DisableJITCompileOptimizer = 0x4000}
36 /// Method call conventions
39 public enum CallConv { Default, Cdecl, Stdcall, Thiscall,
40 Fastcall, Vararg, Instance = 0x20, Generic = 0x10, InstanceExplicit = 0x60 }
43 /// Type custom modifier
45 public enum CustomModifier { modreq = 0x1F, modopt };
48 /// Attibutes for a class
51 public enum TypeAttr {Private, Public, NestedPublic, NestedPrivate,
52 NestedFamily, NestedAssembly, NestedFamAndAssem, NestedFamOrAssem,
53 SequentialLayout, ExplicitLayout = 0x10, Interface = 0x20,
54 Abstract = 0x80, PublicAbstract = 0x81, Sealed = 0x100,
55 PublicSealed = 0x101, SpecialName = 0x400, RTSpecialName = 0x800,
56 Import = 0x1000, Serializable = 0x2000, UnicodeClass = 0x10000,
57 AutoClass = 0x20000, HasSecurity = 0x40000, BeforeFieldInit = 0x100000,
58 VisibilityMask = 0x07 }
61 /// Attributes for a field
63 public enum FieldAttr {Default, Private, FamAndAssem, Assembly,
64 Family, FamOrAssem, Public, Static = 0x10, PublicStatic = 0x16,
65 Initonly = 0x20, Literal = 0x40, Notserialized = 0x80,
66 SpecialName = 0x200, RTSpecialName = 0x400, HasFieldMarshal = 0x1000 }
69 /// Attributes for a method
71 public enum MethAttr { Default, Private, FamAndAssem, Assembly,
72 Family, FamOrAssem, Public, Static = 0x0010, PublicStatic = 0x16,
73 Final = 0x0020, PublicStaticFinal = 0x36, Virtual = 0x0040,
74 PrivateVirtual, PublicVirtual = 0x0046, HideBySig = 0x0080,
75 NewSlot = 0x0100, Abstract = 0x0400, SpecialName = 0x0800,
76 RTSpecialName = 0x1000, SpecialRTSpecialName = 0x1800,
77 HasSecurity = 0x4000, RequireSecObject = 0x8000}
80 /// Attributes for .pinvokeimpl method declarations
82 public enum PInvokeAttr { nomangle = 1, ansi = 2, unicode = 4, autochar = 6,
83 bestfit_on = 0x0010, bestfit_off = 0x0020, bestfit_mask = 0x0030,
84 lasterr = 0x0040, winapi = 0x0100, cdecl = 0x0200,
85 stdcall = 0x0300, thiscall = 0x0400, fastcall = 0x0500,
86 charmaperror_on = 0x1000, charmaperror_off = 0x2000
90 /// Implementation attributes for a method
92 public enum ImplAttr { IL, Native, Runtime = 0x03, Unmanaged = 0x04,
93 ForwardRef = 0x10, PreserveSig = 0x0080, InternalCall = 0x1000,
94 Synchronised = 0x0020, Synchronized = 0x0020, NoInLining = 0x0008, Optil = 0x0002}
97 /// Modes for a parameter
99 public enum ParamAttr { Default, In, Out, Opt = 16, HasDefault = 0x1000, HasFieldMarshal = 0x2000 }
104 public enum Op { nop, breakOp, ldarg_0, ldarg_1, ldarg_2, ldarg_3,
105 ldloc_0, ldloc_1, ldloc_2, ldloc_3, stloc_0, stloc_1, stloc_2, stloc_3,
106 ldnull = 0x14, ldc_i4_m1, ldc_i4_0, ldc_i4_1, ldc_i4_2, ldc_i4_3,
107 ldc_i4_4, ldc_i4_5, ldc_i4_6, ldc_i4_7, ldc_i4_8, dup = 0x25, pop,
108 ret = 0x2A, ldind_i1 = 0x46, ldind_u1, ldind_i2, ldind_u2, ldind_i4,
109 ldind_u4, ldind_i8, ldind_i, ldind_r4, ldind_r8, ldind_ref, stind_ref,
110 stind_i1, stind_i2, stind_i4, stind_i8, stind_r4, stind_r8, add, sub, mul,
111 div, div_un, rem, rem_un, and, or, xor, shl, shr, shr_un, neg, not,
112 conv_i1, conv_i2, conv_i4, conv_i8, conv_r4, conv_r8, conv_u4, conv_u8,
113 conv_r_un = 0x76, throwOp = 0x7A, conv_ovf_i1_un = 0x82, conv_ovf_i2_un,
114 conv_ovf_i4_un, conv_ovf_i8_un, conf_ovf_u1_un, conv_ovf_u2_un,
115 conv_ovf_u4_un, conv_ovf_u8_un, conv_ovf_i_un, conv_ovf_u_un,
116 ldlen = 0x8E, ldelem_i1 = 0x90, ldelem_u1, ldelem_i2, ldelem_u2,
117 ldelem_i4, ldelem_u4, ldelem_i8, ldelem_i, ldelem_r4, ldelem_r8,
118 ldelem_ref, stelem_i, stelem_i1, stelem_i2, stelem_i4, stelem_i8, stelem_r4 = 0xA0, stelem_r8,
119 stelem_ref, conv_ovf_i1 = 0xb3, conv_ovf_u1, conv_ovf_i2, conv_ovf_u2,
120 conv_ovf_i4, conv_ovf_u4, conv_ovf_i8, conv_ovf_u8, ckfinite = 0xC3,
121 conv_u2 = 0xD1, conv_u1, conv_i, conv_ovf_i, conv_ovf_u, add_ovf,
122 add_ovf_un, mul_ovf, mul_ovf_un, sub_ovf, sub_ovf_un, endfinally,
123 stind_i = 0xDF, conv_u, arglist = 0xFE00, ceq, cgt, cgt_un, clt, clt_un,
124 localloc = 0xFE0F, endfilter = 0xFE11, volatile_ = 0xFE13, tail_,
125 cpblk = 0xFE17, initblk, rethrow = 0xFE1A, refanytype = 0xFE1D, readonly_ = 0xFE1E }
128 /// CIL instructions requiring an integer parameter
130 public enum IntOp {ldarg_s = 0x0E, ldarga_s, starg_s, ldloc_s, ldloca_s,
131 stloc_s, ldc_i4_s = 0x1F, ldc_i4, ldarg = 0xFE09,
132 ldarga, starg, ldloc, ldloca, stloc, unaligned = 0xFE12 }
135 /// CIL instructions requiring a field parameter
137 public enum FieldOp {ldfld = 0x7B, ldflda, stfld, ldsfld, ldsflda,
138 stsfld, ldtoken = 0xD0 }
141 /// CIL instructions requiring a method parameter
143 public enum MethodOp {jmp = 0x27, call, callvirt = 0x6F, newobj = 0x73,
144 ldtoken = 0xD0, ldftn = 0xFE06, ldvirtfn }
147 /// CIL instructions requiring a type parameter
149 public enum TypeOp {cpobj = 0x70, ldobj, castclass = 0x74, isinst,
150 unbox = 0x79, stobj = 0x81, box = 0x8C, newarr,
151 ldelema = 0x8F, refanyval = 0xC2, mkrefany = 0xC6,
152 ldtoken = 0xD0, initobj = 0xFE15, constrained = 0xFE16,
153 sizeOf = 0xFE1C, ldelem = 0xA3, stelem = 0xA4, unbox_any }
156 /// CIL branch instructions
158 public enum BranchOp {
160 br_s = 0x2B, brfalse_s, brtrue_s, beq_s, bge_s, bgt_s,
161 ble_s, blt_s, bne_un_s, bge_un_s, bgt_un_s, ble_un_s, blt_un_s,
163 br = 0x38, brfalse, brtrue, beq, bge, bgt, ble, blt,
164 bne_un, bge_un, bgt_un, ble_un, blt_un,
166 leave = 0xDD, leave_s }
169 /// Index for all the tables in the meta data
171 public enum MDTable { Module, TypeRef, TypeDef, Field = 0x04, Method = 0x06,
172 Param = 0x08, InterfaceImpl, MemberRef, Constant, CustomAttribute,
173 FieldMarshal, DeclSecurity, ClassLayout, FieldLayout, StandAloneSig,
174 EventMap, Event = 0x14, PropertyMap, Property = 0x17, MethodSemantics,
175 MethodImpl, ModuleRef, TypeSpec, ImplMap, FieldRVA, Assembly = 0x20,
176 AssemblyProcessor, AssemblyOS, AssemblyRef, AssemblyRefProcessor,
177 AssemblyRefOS, File, ExportedType, ManifestResource, NestedClass,
178 GenericParam, MethodSpec, GenericParamConstraint }
180 public enum SafeArrayType { int16 = 2, int32, float32, float64,
181 currency, date, bstr, dispatch, error, boolean, variant, unknown,
182 Decimal, int8 = 16, uint8, uint16, uint32, Int = 22, UInt }
184 internal enum CIx { TypeDefOrRef, HasConst, HasCustomAttr, HasFieldMarshal,
185 HasDeclSecurity, MemberRefParent, HasSemantics, MethodDefOrRef,
186 MemberForwarded, Implementation, CustomAttributeType, ResolutionScope,
187 TypeOrMethodDef, MaxCIx }
189 internal enum MapType { eventMap, propertyMap, nestedClass }
191 public enum ValueClass { ValueType, Enum }
193 public enum GenParamType : byte {
194 Var = 0x13, MVar = 0x1E
198 public enum GenericParamAttributes : ushort {
199 VarianceMask = 0x0003,
202 Contravariant = 0x0002,
204 SpecialConstraintMask = 0x001c,
205 ReferenceTypeConstraint = 0x0004,
206 NotNullableValueTypeConstraint = 0x0008,
207 DefaultConstructorConstrait = 0x0010
210 /* Taken from Mono.Cecil */
211 public enum SecurityAction : short {
225 NonCasLinkDemand = 14,
226 NonCasInheritance = 15,
227 LinkDemandChoice = 16,
228 InheritDemandChoice = 17,
234 /**************************************************************************/
236 /// Base class for all Meta Data table elements
239 public abstract class MetaDataElement: IComparable {
240 protected ArrayList customAttributes;
241 private uint row = 0;
242 protected bool done = false;
243 protected MDTable tabIx;
244 protected bool sortTable = false;
246 internal MetaDataElement() { }
257 internal virtual uint GetCodedIx(CIx code) { return 0; }
260 /// Add a custom attribute to this item
262 /// <param name="ctorMeth">the constructor method for this attribute</param>
263 /// <param name="val">the byte value of the parameters</param>
264 public void AddCustomAttribute(Method ctorMeth, byte[] val)
266 if (customAttributes == null) {
267 customAttributes = new ArrayList();
269 customAttributes.Add(new CustomAttribute(this,ctorMeth,val));
273 /// Add a custom attribute to this item
275 /// <param name="ctorMeth">the constructor method for this attribute</param>
276 /// <param name="val">the constant values of the parameters</param>
277 public void AddCustomAttribute(Method ctorMeth, Constant[] cVals)
279 if (customAttributes == null) {
280 customAttributes = new ArrayList();
282 // customAttributes.Add(new CustomAttribute(this,ctorMeth,cVals));
285 internal uint Token()
287 return (((uint)tabIx << 24) | row);
290 internal virtual void BuildTables(MetaData md)
295 internal virtual uint Size(MetaData md)
300 internal virtual void Write(FileImage output) { }
302 internal virtual uint SortKey()
304 throw new PEFileException("Trying to sort table of " + this);
308 internal virtual uint SortKey2()
313 public int CompareTo(object obj)
315 uint otherKey = ((MetaDataElement)obj).SortKey();
316 uint thisKey = SortKey();
318 if (thisKey == otherKey) {
320 otherKey = ((MetaDataElement)obj).SortKey2();
321 thisKey = SortKey2();
322 if (thisKey == otherKey)
324 if (thisKey < otherKey)
328 if (thisKey < otherKey) return -1;
335 /**************************************************************************/
337 /// Layout information for a class (.class [sequential | explicit])
339 internal class ClassLayout : MetaDataElement {
345 internal ClassLayout(int pack, int cSize, ClassDef par)
347 packSize = (ushort)pack;
348 classSize = (uint)cSize;
350 tabIx = MDTable.ClassLayout;
353 internal sealed override uint Size(MetaData md)
355 return 6 + md.TableIndexSize(MDTable.TypeDef);
358 internal sealed override void Write(FileImage output)
360 output.Write(packSize);
361 output.Write(classSize);
362 output.WriteIndex(MDTable.TypeDef,parent.Row);
367 /**************************************************************************/
369 /// Summary description for ConstantElem.
371 internal class ConstantElem : MetaDataElement {
373 MetaDataElement parent;
377 internal ConstantElem(MetaDataElement parent, Constant val)
379 this.parent = parent;
381 tabIx = MDTable.Constant;
385 internal override uint SortKey()
387 return (parent.Row << MetaData.CIxShiftMap[(uint)CIx.HasConst])
388 | parent.GetCodedIx(CIx.HasConst);
391 internal sealed override void BuildTables(MetaData md)
394 valIx = cValue.GetBlobIndex(md);
398 internal void AddToBlob(BinaryWriter bw)
403 internal sealed override uint Size(MetaData md)
405 return 2 + md.CodedIndexSize(CIx.HasConst) + md.BlobIndexSize();
408 internal sealed override void Write(FileImage output)
410 output.Write(cValue.GetTypeIndex());
411 output.Write((byte)0);
412 output.WriteCodedIndex(CIx.HasConst,parent);
413 output.BlobIndex(valIx);
417 /**************************************************************************/
419 /// Descriptor for a Custom Attribute (.custom)
422 public class CustomAttribute : MetaDataElement {
424 private static readonly ushort prolog = 0x0001;
425 MetaDataElement parent;
431 ArrayList names, vals;
433 internal CustomAttribute(MetaDataElement paren, Method constrType,
438 tabIx = MDTable.CustomAttribute;
441 internal CustomAttribute(MetaDataElement paren, Method constrType,
445 tabIx = MDTable.CustomAttribute;
449 internal override uint SortKey()
451 return (parent.Row << MetaData.CIxShiftMap[(uint)CIx.HasCustomAttr])
452 | parent.GetCodedIx(CIx.HasCustomAttr);
455 public void AddFieldOrProp(string name, Constant val)
458 names = new ArrayList();
459 vals = new ArrayList();
465 internal sealed override void BuildTables(MetaData md)
467 BinaryWriter bw = new BinaryWriter(new MemoryStream());
469 md.AddToTable(MDTable.CustomAttribute, this);
470 MemoryStream str = (MemoryStream)bw.BaseStream;
471 valIx = md.AddToBlobHeap(str.ToArray());
474 internal sealed override uint Size(MetaData md)
476 return md.CodedIndexSize(CIx.HasCustomAttr) + md.CodedIndexSize(CIx.CustomAttributeType) + md.BlobIndexSize();
479 internal sealed override void Write(FileImage output)
481 output.WriteCodedIndex(CIx.HasCustomAttr,parent);
482 output.WriteCodedIndex(CIx.CustomAttributeType,type);
483 output.BlobIndex(valIx);
488 /**************************************************************************/
490 /// Descriptor for security permissions for a class or a method
493 public abstract class BaseDeclSecurity : MetaDataElement {
496 MetaDataElement parent;
499 internal BaseDeclSecurity(MetaDataElement paren, ushort act)
503 tabIx = MDTable.DeclSecurity;
506 internal override uint SortKey()
508 return (parent.Row << MetaData.CIxShiftMap[(uint)CIx.HasDeclSecurity])
509 | parent.GetCodedIx(CIx.HasDeclSecurity);
512 internal sealed override uint Size(MetaData md)
514 return 2 + md.CodedIndexSize(CIx.HasDeclSecurity) + md.BlobIndexSize();
517 internal sealed override void BuildTables(MetaData md)
521 BinaryWriter bw = new BinaryWriter (new MemoryStream ());
522 md.AddToTable (MDTable.DeclSecurity, this);
523 MemoryStream str = (MemoryStream)bw.BaseStream;
525 permissionIx = md.AddToBlobHeap(str.ToArray());
530 internal abstract void WriteSig (BinaryWriter bw);
532 internal sealed override void Write(FileImage output)
534 output.Write(action);
535 output.WriteCodedIndex(CIx.HasDeclSecurity,parent);
536 output.BlobIndex(permissionIx);
541 public class DeclSecurity : BaseDeclSecurity {
545 internal DeclSecurity(MetaDataElement paren, ushort act, byte [] val)
551 internal override void WriteSig (BinaryWriter bw)
558 public class DeclSecurity_20 : BaseDeclSecurity {
562 internal DeclSecurity_20 (MetaDataElement paren, ushort act, PermissionSet ps)
568 internal override void WriteSig (BinaryWriter bw)
574 public class PermissionMember {
576 MemberTypes member_type;
581 public PermissionMember (MemberTypes member_type, PEAPI.Type type, string name, object value)
583 this.member_type = member_type;
589 public void Write (BinaryWriter bw)
593 if (member_type == MemberTypes.Field)
594 bw.Write ((byte) 0x53);
597 bw.Write ((byte) 0x54);
599 if (type is PrimitiveType) {
600 bw.Write (type.GetTypeIndex ());
603 bw.Write ((byte) 0x55); //ENUM
605 b = Encoding.UTF8.GetBytes (((ClassRef) type).TypeName ());
606 MetaData.CompressNum ((uint) b.Length, (MemoryStream) bw.BaseStream);
610 b = Encoding.UTF8.GetBytes (name);
611 MetaData.CompressNum ((uint) b.Length, (MemoryStream) bw.BaseStream);
614 ((Constant) value).Write (bw);
619 public class Permission
627 public Permission (PEAPI.Type type, string name)
633 public void AddMember (PEAPI.PermissionMember member)
636 members = new ArrayList ();
638 members.Add (member);
641 public void Write (BinaryWriter bw)
643 byte [] b = Encoding.UTF8.GetBytes (name);
644 MetaData.CompressNum ((uint) b.Length, (MemoryStream) bw.BaseStream);
647 BinaryWriter perm_writer = new BinaryWriter (new MemoryStream (), Encoding.Unicode);
648 MemoryStream str = (MemoryStream) perm_writer.BaseStream;
650 MetaData.CompressNum ((uint) members.Count, str);//number of params
651 foreach (PermissionMember member in members)
652 member.Write (perm_writer);
654 bw.Write ((byte) str.Length); //(optional) parameters length
655 bw.Write (str.ToArray ());
659 public class PermissionSet
661 PEAPI.SecurityAction sec_action;
662 ArrayList permissions;
663 PEAPI.PermissionSet ps;
665 public PermissionSet (PEAPI.SecurityAction sec_action)
667 this.sec_action = sec_action;
670 public void AddPermission (PEAPI.Permission perm)
672 if (permissions == null)
673 permissions = new ArrayList ();
675 permissions.Add (perm);
678 public void Write (BinaryWriter bw)
680 bw.Write ((byte) 0x2e);
681 MetaData.CompressNum ((uint) permissions.Count, (MemoryStream) bw.BaseStream);
683 foreach (Permission perm in permissions)
689 /**************************************************************************/
691 /// Descriptor for layout information for a field
694 public class FieldLayout : MetaDataElement {
699 internal FieldLayout(Field field, uint offset)
702 this.offset = offset;
703 tabIx = MDTable.FieldLayout;
706 internal sealed override uint Size(MetaData md)
708 return 4 + md.TableIndexSize(MDTable.Field);
711 internal sealed override void Write(FileImage output)
713 output.Write(offset);
714 output.WriteIndex(MDTable.Field,field.Row);
719 /*****************************************************************************/
721 /// Marshalling information for a field or param
723 public class FieldMarshal : MetaDataElement {
725 MetaDataElement field;
729 internal FieldMarshal(MetaDataElement field, NativeType nType)
733 tabIx = MDTable.FieldMarshal;
736 internal override uint SortKey()
738 return (field.Row << MetaData.CIxShiftMap[(uint)CIx.HasFieldMarshal])
739 | field.GetCodedIx(CIx.HasFieldMarshal);
742 internal sealed override void BuildTables(MetaData md)
745 ntIx = md.AddToBlobHeap(nt.ToBlob());
749 internal sealed override uint Size(MetaData md)
751 return md.CodedIndexSize(CIx.HasFieldMarshal) + md.BlobIndexSize();
754 internal sealed override void Write(FileImage output)
756 output.WriteCodedIndex(CIx.HasFieldMarshal,field);
757 output.BlobIndex(ntIx);
762 /**************************************************************************/
764 /// Descriptor for the address of a field's value in the PE file
766 public class FieldRVA : MetaDataElement {
771 internal FieldRVA(Field field, DataConstant data)
775 tabIx = MDTable.FieldRVA;
778 internal sealed override void BuildTables(MetaData md)
785 internal sealed override uint Size(MetaData md)
787 return 4 + md.TableIndexSize(MDTable.Field);
790 internal sealed override void Write(FileImage output)
792 output.WriteDataRVA(data.DataOffset);
793 output.WriteIndex(MDTable.Field,field.Row);
798 /**************************************************************************/
800 /// Descriptor for a file referenced in THIS assembly/module (.file)
802 public class FileRef : MetaDataElement {
804 private static readonly uint NoMetaData = 0x1;
805 uint nameIx = 0, hashIx = 0;
807 protected string name;
809 internal FileRef(string name, byte[] hashBytes, bool metaData,
810 bool entryPoint, MetaData md) {
811 if (!metaData) flags = NoMetaData;
812 if (entryPoint) md.SetEntryPoint(this);
814 nameIx = md.AddToStringsHeap(name);
815 hashIx = md.AddToBlobHeap(hashBytes);
816 tabIx = MDTable.File;
819 internal FileRef(uint nameIx, byte[] hashBytes, bool metaData,
820 bool entryPoint, MetaData md) {
821 if (!metaData) flags = NoMetaData;
822 if (entryPoint) md.SetEntryPoint(this);
823 this.nameIx = nameIx;
824 hashIx = md.AddToBlobHeap(hashBytes);
825 tabIx = MDTable.File;
828 internal sealed override uint Size(MetaData md)
830 return 4 + md.StringsIndexSize() + md.BlobIndexSize();
833 internal sealed override void BuildTables(MetaData md)
835 md.AddToTable(MDTable.File,this);
838 internal sealed override void Write(FileImage output)
841 output.StringsIndex(nameIx);
842 output.BlobIndex(hashIx);
845 internal sealed override uint GetCodedIx(CIx code)
848 case (CIx.HasCustomAttr) : return 16;
849 case (CIx.Implementation) : return 0;
855 /**************************************************************************/
857 /// Descriptor for pinvoke information for a method NOT YET IMPLEMENTED
859 public class ImplMap : MetaDataElement {
861 private static readonly ushort NoMangle = 0x01;
866 ModuleRef importScope;
868 internal ImplMap(ushort flag, Method implMeth, string iName, ModuleRef mScope)
873 importScope = mScope;
874 tabIx = MDTable.ImplMap;
875 if (iName == null) flags |= NoMangle;
876 //throw(new NotYetImplementedException("PInvoke "));
879 internal override uint SortKey()
881 return (meth.Row << MetaData.CIxShiftMap[(uint)CIx.MemberForwarded])
882 | meth.GetCodedIx(CIx.MemberForwarded);
885 internal sealed override void BuildTables(MetaData md)
888 iNameIx = md.AddToStringsHeap(importName);
892 internal sealed override uint Size(MetaData md)
894 return 2+ md.CodedIndexSize(CIx.MemberForwarded) +
895 md.StringsIndexSize() + md.TableIndexSize(MDTable.ModuleRef);
898 internal sealed override void Write(FileImage output)
901 output.WriteCodedIndex(CIx.MemberForwarded,meth);
902 output.StringsIndex(iNameIx);
903 output.WriteIndex(MDTable.ModuleRef,importScope.Row);
908 /**************************************************************************/
910 public class GenericParameter : MetaDataElement {
912 MetaDataElement owner;
917 GenericParamAttributes attr;
919 internal GenericParameter (ClassDef owner, MetaData metadata,
920 short index, string name, GenericParamAttributes attr) : this (owner, metadata, index, name, attr, true)
924 internal GenericParameter (MethodDef owner, MetaData metadata,
925 short index, string name, GenericParamAttributes attr) : this (owner, metadata, index, name, attr, true)
929 private GenericParameter (MetaDataElement owner, MetaData metadata,
930 short index, string name, GenericParamAttributes attr, bool nadda) {
932 this.metadata = metadata;
934 tabIx = MDTable.GenericParam;
939 internal override uint SortKey()
941 return (owner.Row << MetaData.CIxShiftMap[(uint)CIx.TypeOrMethodDef])
942 | owner.GetCodedIx(CIx.TypeOrMethodDef);
945 internal override uint SortKey2 ()
950 public void AddConstraint (Type constraint)
952 metadata.AddToTable (MDTable.GenericParamConstraint,
953 new GenericParamConstraint (this, constraint));
956 internal sealed override uint Size(MetaData md)
959 md.CodedIndexSize(CIx.TypeOrMethodDef) +
960 md.StringsIndexSize ());
963 internal sealed override void BuildTables(MetaData md)
966 nameIx = md.AddToStringsHeap(name);
970 internal sealed override void Write(FileImage output)
972 output.Write ((short) index);
973 output.Write ((short) attr);
974 output.WriteCodedIndex(CIx.TypeOrMethodDef, owner);
975 output.StringsIndex (nameIx);
978 internal sealed override uint GetCodedIx(CIx code)
981 case (CIx.HasCustomAttr) : return 19;
988 internal class GenericParamConstraint : MetaDataElement {
990 GenericParameter param;
993 public GenericParamConstraint (GenericParameter param, Type type)
997 tabIx = MDTable.GenericParamConstraint;
1000 internal override uint SortKey()
1005 internal sealed override uint Size(MetaData md)
1007 return (uint) (md.TableIndexSize(MDTable.GenericParam) +
1008 md.CodedIndexSize(CIx.TypeDefOrRef));
1011 internal sealed override void Write(FileImage output)
1013 output.WriteIndex(MDTable.GenericParam, param.Row);
1014 output.WriteCodedIndex(CIx.TypeDefOrRef, type);
1019 internal class MethodSpec : Method {
1022 GenericMethodSig g_sig;
1025 internal MethodSpec (Method meth, GenericMethodSig g_sig) : base ("")
1029 tabIx = MDTable.MethodSpec;
1032 internal override uint GetSigIx (MetaData md)
1034 throw new Exception ("Should not be used.");
1037 public override void AddCallConv (CallConv cconv)
1039 throw new Exception ("Should not be used.");
1042 internal sealed override void BuildTables (MetaData md)
1045 sidx = g_sig.GetSigIx (md);
1049 internal sealed override uint Size (MetaData md)
1051 return (uint) (md.CodedIndexSize(CIx.MethodDefOrRef) +
1052 md.BlobIndexSize ());
1055 internal sealed override void Write (FileImage output)
1057 output.WriteCodedIndex (CIx.MethodDefOrRef, meth);
1058 output.BlobIndex (sidx);
1061 internal sealed override void TypeSig (MemoryStream sig)
1063 throw new Exception ("Should not be used.");
1067 /**************************************************************************/
1069 /// Descriptor for interface implemented by a class
1071 public class InterfaceImpl: MetaDataElement {
1076 internal InterfaceImpl(ClassDef theClass, Class theInterface)
1078 this.theClass = theClass;
1079 this.theInterface = theInterface;
1080 tabIx = MDTable.InterfaceImpl;
1083 internal sealed override uint Size(MetaData md)
1085 return md.TableIndexSize(MDTable.TypeDef) +
1086 md.CodedIndexSize(CIx.TypeDefOrRef);
1089 internal sealed override void Write(FileImage output)
1091 output.WriteIndex(MDTable.TypeDef,theClass.Row);
1092 output.WriteCodedIndex(CIx.TypeDefOrRef,theInterface);
1095 internal sealed override uint GetCodedIx(CIx code) { return 5; }
1097 internal override uint SortKey ()
1099 return (theClass.Row << MetaData.CIxShiftMap[(uint)CIx.TypeDefOrRef])
1100 | theClass.GetCodedIx (CIx.TypeDefOrRef);
1105 /**************************************************************************/
1107 /// Descriptor for resources used in this PE file
1110 public class ManifestResource : MetaDataElement {
1112 public static readonly uint PublicResource = 0x1;
1113 public static readonly uint PrivateResource = 0x2;
1116 MetaDataElement rRef;
1120 byte [] resourceBytes;
1122 public ManifestResource (string name, byte[] resBytes, uint flags)
1124 InitResource (name, flags);
1125 this.resourceBytes = resBytes;
1128 public ManifestResource(string name, uint flags, FileRef fileRef)
1130 InitResource (name, flags);
1134 public ManifestResource(string name, uint flags, FileRef fileRef,
1136 InitResource (name, flags);
1138 fileOffset = fileIx;
1141 public ManifestResource(string name, uint flags, AssemblyRef assemRef)
1143 InitResource (name, flags);
1147 internal ManifestResource (ManifestResource mres)
1149 mrName = mres.mrName;
1152 fileOffset = mres.fileOffset;
1153 resourceBytes = mres.resourceBytes;
1156 private void InitResource (string name, uint flags)
1160 tabIx = MDTable.ManifestResource;
1163 internal sealed override void BuildTables(MetaData md)
1166 md.AddToTable (MDTable.ManifestResource, this);
1167 nameIx = md.AddToStringsHeap(mrName);
1168 if (resourceBytes != null) {
1170 throw new PEFileException ("Manifest Resource has byte value and file reference");
1171 fileOffset = md.AddResource(resourceBytes);
1174 throw new PEFileException ("Manifest Resource has no implementation or value");
1175 rRef.BuildTables (md);
1181 internal sealed override uint Size(MetaData md)
1183 return 8 + md.StringsIndexSize() +
1184 md.CodedIndexSize(CIx.Implementation);
1187 internal sealed override void Write(FileImage output)
1189 output.Write(fileOffset);
1190 output.Write(flags);
1191 output.StringsIndex(nameIx);
1192 output.WriteCodedIndex(CIx.Implementation,rRef);
1195 internal sealed override uint GetCodedIx(CIx code) { return 18; }
1197 public string Name {
1198 get { return mrName; }
1199 set { mrName = value; }
1203 /**************************************************************************/
1205 /// Base class for elements in the PropertyMap, EventMap and
1206 /// NestedClass MetaData tables
1208 public class MapElem : MetaDataElement {
1214 internal MapElem(ClassDef par, uint elIx, MDTable elemTab)
1218 elemTable = elemTab;
1221 internal sealed override uint Size(MetaData md)
1223 return md.TableIndexSize(MDTable.TypeDef) + md.TableIndexSize(elemTable);
1226 internal sealed override void Write(FileImage output)
1228 output.WriteIndex(MDTable.TypeDef,parent.Row);
1229 output.WriteIndex(elemTable,elemIx);
1233 /**************************************************************************/
1235 /// Descriptor for an overriding method (.override)
1237 public class MethodImpl : MetaDataElement {
1240 Method header, body;
1242 internal MethodImpl(ClassDef par, Method decl, Method bod)
1247 tabIx = MDTable.MethodImpl;
1250 internal sealed override uint Size(MetaData md)
1252 return md.TableIndexSize(MDTable.TypeDef) + 2 * md.CodedIndexSize(CIx.MethodDefOrRef);
1255 internal sealed override void Write(FileImage output)
1257 output.WriteIndex(MDTable.TypeDef,parent.Row);
1258 output.WriteCodedIndex(CIx.MethodDefOrRef,body);
1259 output.WriteCodedIndex(CIx.MethodDefOrRef,header);
1264 /**************************************************************************/
1266 /// Descriptor for Property and Event methods
1268 public class MethodSemantics : MetaDataElement {
1270 Feature.MethodType type;
1272 Feature eventOrProp;
1274 internal MethodSemantics(Feature.MethodType mType, MethodDef method, Feature feature)
1278 eventOrProp = feature;
1279 tabIx = MDTable.MethodSemantics;
1282 internal override uint SortKey()
1284 return (eventOrProp.Row << MetaData.CIxShiftMap [(uint)CIx.HasSemantics])
1285 | eventOrProp.GetCodedIx (CIx.HasSemantics);
1288 internal sealed override uint Size(MetaData md)
1290 return 2 + md.TableIndexSize(MDTable.Method) + md.CodedIndexSize(CIx.HasSemantics);
1293 internal sealed override void Write(FileImage output)
1295 output.Write((ushort)type);
1296 output.WriteIndex(MDTable.Method,meth.Row);
1297 output.WriteCodedIndex(CIx.HasSemantics,eventOrProp);
1302 /**************************************************************************/
1304 /// Descriptor for a parameter of a method defined in this assembly/module
1306 public class Param : MetaDataElement {
1311 internal ushort seqNo = 0;
1313 ConstantElem defaultVal;
1315 FieldMarshal marshalInfo;
1318 /// Create a new parameter for a method
1320 /// <param name="mode">param mode (in, out, opt)</param>
1321 /// <param name="parName">parameter name</param>
1322 /// <param name="parType">parameter type</param>
1323 public Param(ParamAttr mode, string parName, Type parType)
1327 parMode = (ushort)mode;
1328 tabIx = MDTable.Param;
1332 /// Add a default value to this parameter
1334 /// <param name="c">the default value for the parameter</param>
1335 public void AddDefaultValue(Constant cVal)
1337 defaultVal = new ConstantElem(this,cVal);
1338 parMode |= (ushort) ParamAttr.HasDefault;
1342 /// Add marshalling information about this parameter
1344 public void AddMarshallInfo(NativeType marshallType)
1346 parMode |= (ushort) ParamAttr.HasFieldMarshal;
1347 marshalInfo = new FieldMarshal(this,marshallType);
1350 internal Type GetParType() { return pType; }
1352 internal sealed override void BuildTables(MetaData md)
1355 nameIx = md.AddToStringsHeap(pName);
1356 if (defaultVal != null) {
1357 md.AddToTable(MDTable.Constant,defaultVal);
1358 defaultVal.BuildTables(md);
1360 if (marshalInfo != null) {
1361 md.AddToTable(MDTable.FieldMarshal,marshalInfo);
1362 marshalInfo.BuildTables(md);
1367 internal void TypeSig(MemoryStream str)
1372 internal sealed override uint Size(MetaData md)
1374 return 4 + md.StringsIndexSize();
1377 internal sealed override void Write(FileImage output)
1379 output.Write(parMode);
1380 output.Write(seqNo);
1381 output.StringsIndex(nameIx);
1384 internal sealed override uint GetCodedIx(CIx code)
1387 case (CIx.HasCustomAttr) : return 4;
1388 case (CIx.HasConst) : return 1;
1389 case (CIx.HasFieldMarshal) : return 1;
1396 /**************************************************************************/
1397 public abstract class Signature : MetaDataElement {
1399 protected uint sigIx;
1401 internal Signature()
1403 tabIx = MDTable.StandAloneSig;
1406 internal sealed override uint Size(MetaData md)
1408 return md.BlobIndexSize();
1411 internal sealed override void Write(FileImage output)
1413 output.BlobIndex(sigIx);
1416 internal sealed override uint GetCodedIx(CIx code) { return (uint)tabIx; }
1420 /**************************************************************************/
1421 public class TypeSpec : MetaDataElement {
1424 internal TypeSpec(Type aType, MetaData md)
1426 MemoryStream sig = new MemoryStream();
1428 sigIx = md.AddToBlobHeap(sig.ToArray());
1429 tabIx = MDTable.TypeSpec;
1432 internal sealed override uint GetCodedIx(CIx code)
1435 case (CIx.TypeDefOrRef) : return 2;
1436 case (CIx.HasCustomAttr) : return 13;
1437 case (CIx.MemberRefParent) : return 4;
1442 internal override uint Size(MetaData md)
1444 return md.BlobIndexSize();
1447 internal sealed override void Write(FileImage output)
1449 //Console.WriteLine("Writing the blob index for a TypeSpec");
1450 output.BlobIndex(sigIx);
1455 /**************************************************************************/
1457 /// Base class for all IL types
1459 public abstract class Type : MetaDataElement {
1460 protected byte typeIndex;
1461 protected TypeSpec typeSpec;
1463 internal Type(byte tyIx) { typeIndex = tyIx; }
1465 internal byte GetTypeIndex() { return typeIndex; }
1466 internal void SetTypeIndex (byte b) { typeIndex = b; }
1468 internal virtual MetaDataElement GetTypeSpec(MetaData md)
1470 if (typeSpec == null) {
1471 typeSpec = new TypeSpec(this,md);
1472 md.AddToTable(MDTable.TypeSpec,typeSpec);
1477 internal virtual void TypeSig(MemoryStream str)
1479 throw(new TypeSignatureException(this.GetType().AssemblyQualifiedName +
1480 " doesn't have a type signature!!"));
1484 public class ClassRefInst : Type {
1487 private bool is_value;
1489 public ClassRefInst (Type type, bool is_value) : base (PrimitiveType.Class.GetTypeIndex ())
1492 this.is_value = is_value;
1494 typeIndex = PrimitiveType.ValueType.GetTypeIndex ();
1495 tabIx = MDTable.TypeSpec;
1498 internal sealed override void TypeSig(MemoryStream str)
1504 /**************************************************************************/
1506 /// The base descriptor for a class
1508 public abstract class Class : Type {
1510 protected int row = 0;
1511 public string name, nameSpace;
1512 protected uint nameIx, nameSpaceIx;
1513 protected MetaData _metaData;
1514 internal Class(string nameSpaceName, string className, MetaData md)
1515 : base(PrimitiveType.Class.GetTypeIndex ())
1517 nameSpace = nameSpaceName;
1519 nameIx = md.AddToStringsHeap(name);
1520 nameSpaceIx = md.AddToStringsHeap(nameSpace);
1524 internal Class(uint nsIx, uint nIx) : base(PrimitiveType.Class.GetTypeIndex ())
1530 internal Class (byte typeIndex) : base (typeIndex)
1532 nameSpace = "Should not be used";
1533 name = "Should not be used";
1536 internal virtual uint TypeDefOrRefToken() { return 0; }
1538 internal virtual void MakeValueClass(ValueClass vClass)
1540 typeIndex = PrimitiveType.ValueType.GetTypeIndex ();
1543 internal virtual string TypeName()
1545 return (nameSpace + "." + name);
1548 internal override MetaDataElement GetTypeSpec(MetaData md)
1554 /**************************************************************************/
1555 // This Class produces entries in the TypeDef table of the MetaData
1556 // in the PE meta data.
1558 // NOTE: Entry 0 in TypeDef table is always the pseudo class <module>
1559 // which is the parent for functions and variables declared a module level
1562 /// The descriptor for a class defined in the IL (.class) in the current assembly/module
1565 public class ClassDef : Class {
1567 private static readonly byte ElementType_Class = 0x12;
1570 ArrayList fields = new ArrayList();
1571 ArrayList methods = new ArrayList();
1573 ArrayList properties;
1574 bool typeIndexChecked = true;
1575 uint fieldIx = 0, methodIx = 0;
1576 byte[] securityActions;
1579 ClassDef parentClass;
1582 internal ClassDef(TypeAttr attrSet, string nsName, string name,
1583 MetaData md) : base(nsName, name, md)
1586 if (! ((nsName == "" && name == "<Module>") || (nsName == "System" && name == "Object")) ) {
1587 superType = metaData.mscorlib.GetSpecialSystemClass(PrimitiveType.Object);
1589 flags = (uint)attrSet;
1590 tabIx = MDTable.TypeDef;
1593 internal void SetSuper(Class sClass)
1596 if (! (sClass is GenericTypeInst))
1597 typeIndexChecked = false;
1600 internal override void MakeValueClass(ValueClass vClass)
1602 if (vClass == ValueClass.Enum)
1603 superType = metaData.mscorlib.EnumType();
1605 superType = metaData.mscorlib.ValueType();
1607 typeIndex = PrimitiveType.ValueType.GetTypeIndex ();
1610 public void SpecialNoSuper()
1616 /// Add an attribute to this class
1618 /// <param name="ta">the attribute to be added</param>
1619 public void AddAttribute(TypeAttr ta)
1625 /// Add an interface that is implemented by this class
1627 /// <param name="iFace">the interface that is implemented</param>
1628 public void AddImplementedInterface(Class iFace)
1630 metaData.AddToTable(MDTable.InterfaceImpl,new InterfaceImpl(this,iFace));
1634 /// Add a named generic type parameter
1636 public GenericParameter AddGenericParameter (short index, string name)
1638 return AddGenericParameter (index, name, 0);
1642 /// Add a named generic type parameter with attributes
1644 public GenericParameter AddGenericParameter (short index, string name, GenericParamAttributes attr)
1646 GenericParameter gp = new GenericParameter (this, metaData, index, name, attr);
1647 metaData.AddToTable (MDTable.GenericParam, gp);
1652 /// Add a field to this class
1654 /// <param name="name">field name</param>
1655 /// <param name="fType">field type</param>
1656 /// <returns>a descriptor for this new field</returns>
1657 public FieldDef AddField(string name, Type fType)
1659 FieldDef field = new FieldDef(name,fType);
1665 /// Add a field to this class
1667 /// <param name="fAtts">attributes for this field</param>
1668 /// <param name="name">field name</param>
1669 /// <param name="fType">field type</param>
1670 /// <returns>a descriptor for this new field</returns>
1671 public FieldDef AddField(FieldAttr fAtts, string name, Type fType)
1673 FieldDef field = new FieldDef(fAtts,name,fType);
1678 public void SetFieldOrder (ArrayList fields)
1680 this.fields = fields;
1684 /// Add a method to this class
1686 /// <param name="name">method name</param>
1687 /// <param name="retType">return type</param>
1688 /// <param name="pars">parameters</param>
1689 /// <returns>a descriptor for this new method</returns>
1690 public MethodDef AddMethod(string name, Type retType, Param[] pars)
1692 // Console.WriteLine("Adding method " + name + " to class " + this.name);
1693 MethodDef meth = new MethodDef(metaData,name,retType, pars);
1699 /// Add a method to this class
1701 /// <param name="mAtts">attributes for this method</param>
1702 /// <param name="iAtts">implementation attributes for this method</param>
1703 /// <param name="name">method name</param>
1704 /// <param name="retType">return type</param>
1705 /// <param name="pars">parameters</param>
1706 /// <returns>a descriptor for this new method</returns>
1707 public MethodDef AddMethod(MethAttr mAtts, ImplAttr iAtts, string name,
1708 Type retType, Param[] pars) {
1709 // Console.WriteLine("Adding method " + name + " to class " + this.name);
1710 MethodDef meth = new MethodDef(metaData,mAtts,iAtts,name,retType,pars);
1716 /// Add an event to this class
1718 /// <param name="name">event name</param>
1719 /// <param name="eType">event type</param>
1720 /// <returns>a descriptor for this new event</returns>
1721 public Event AddEvent(string name, Type eType)
1723 Event e = new Event(name,eType,this);
1724 if (events == null) events = new ArrayList();
1730 /// Add a property to this class
1732 /// <param name="name">property name</param>
1733 /// <param name="propType">property type</param>
1734 /// <returns>a descriptor for this new property</returns>
1735 public Property AddProperty(string name, Type retType, Type[] pars)
1737 Property p = new Property(name, retType, pars, this);
1738 if (properties == null) properties = new ArrayList();
1744 /// Add a nested class to this class
1746 /// <param name="attrSet">attributes for this nested class</param>
1747 /// <param name="nsName">nested name space name</param>
1748 /// <param name="name">nested class name</param>
1749 /// <returns>a descriptor for this new nested class</returns>
1750 public ClassDef AddNestedClass(TypeAttr attrSet, string nsName,
1752 ClassDef nClass = new ClassDef(attrSet,"",name,metaData);
1753 metaData.AddToTable(MDTable.TypeDef,nClass);
1754 metaData.AddToTable(MDTable.NestedClass,new MapElem(nClass,Row,MDTable.TypeDef));
1755 nClass.parentClass = this;
1759 public static bool IsValueType (Class type)
1761 return IsValueType (type.nameSpace, type.name);
1764 public static bool IsEnum (Class type)
1766 return IsEnum (type.nameSpace, type.name);
1769 public static bool IsValueType (string nsName, string name)
1771 return (nsName == "System" && name == "ValueType");
1774 public static bool IsEnum (string nsName, string name)
1776 return (nsName == "System" && name == "Enum");
1780 /// Add a nested class to this class
1782 /// <param name="attrSet">attributes for this nested class</param>
1783 /// <param name="nsName">nested name space name</param>
1784 /// <param name="name">nested class name</param>
1785 /// <param name="sType">super type of this nested class</param>
1786 /// <returns>a descriptor for this new nested class</returns>
1787 public ClassDef AddNestedClass(TypeAttr attrSet, string nsName,
1788 string name, Class sType) {
1789 ClassDef nClass = AddNestedClass (attrSet, nsName, name);
1790 nClass.SetSuper(sType);
1791 if (ClassDef.IsValueType (sType))
1792 nClass.MakeValueClass (ValueClass.ValueType);
1794 if (ClassDef.IsEnum (sType))
1795 nClass.MakeValueClass (ValueClass.Enum);
1797 if (ClassDef.IsValueType (sType) || ClassDef.IsEnum (sType))
1798 nClass.SetTypeIndex (PrimitiveType.ValueType.GetTypeIndex ());
1800 nClass.typeIndexChecked = true;
1805 /// Add layout information for this class. This class must have the
1806 /// sequential or explicit attribute.
1808 /// <param name="packSize">packing size (.pack)</param>
1809 /// <param name="classSize">class size (.size)</param>
1810 public void AddLayoutInfo (int packSize, int classSize)
1812 layout = new ClassLayout(packSize,classSize,this);
1816 /// Use a method as the implementation for another method (.override)
1818 /// <param name="decl">the method to be overridden</param>
1819 /// <param name="body">the implementation to be used</param>
1820 public void AddMethodOverride(Method decl, Method body)
1822 metaData.AddToTable(MDTable.MethodImpl,new MethodImpl(this,decl,body));
1826 /// Add security to this class NOT YET IMPLEMENTED
1828 /// <param name="permissionSet"></param>
1829 public void AddSecurity(byte[] permissionSet)
1831 throw(new NotYetImplementedException("Class security "));
1832 //flags |= HasSecurity;
1833 // securityActions = permissionSet;
1836 //public void AddLineInfo(int row, int col) { }
1838 internal void CheckTypeIndex()
1840 if (typeIndexChecked) return;
1841 if (superType is ClassDef)
1842 ((ClassDef)superType).CheckTypeIndex();
1843 typeIndex = superType.GetTypeIndex();
1844 typeIndexChecked = true;
1847 internal sealed override void BuildTables(MetaData md)
1850 if ((flags & (uint)TypeAttr.Interface) != 0) { superType = null; }
1851 // Console.WriteLine("Building tables for " + name);
1852 if (layout != null) md.AddToTable(MDTable.ClassLayout,layout);
1853 // Console.WriteLine("adding methods " + methods.Count);
1854 methodIx = md.TableIndex(MDTable.Method);
1855 for (int i=0; i < methods.Count; i++) {
1856 md.AddToTable(MDTable.Method,(MetaDataElement)methods[i]);
1857 ((MethodDef)methods[i]).BuildTables(md);
1859 // Console.WriteLine("adding fields");
1860 fieldIx = md.TableIndex(MDTable.Field);
1861 for (int i=0; i < fields.Count; i++) {
1862 md.AddToTable(MDTable.Field,(MetaDataElement)fields[i]);
1863 ((FieldDef)fields[i]).BuildTables(md);
1865 // Console.WriteLine("adding events and properties");
1866 if (events != null) {
1867 for (int i=0; i < events.Count; i++) {
1868 md.AddToTable(MDTable.Event,(Event)events[i]);
1869 ((Event)events[i]).BuildTables(md);
1871 md.AddToTable(MDTable.EventMap,
1872 new MapElem(this,((Event)events[0]).Row,MDTable.Event));
1874 if (properties != null) {
1875 for (int i=0; i < properties.Count; i++) {
1876 md.AddToTable(MDTable.Property,(Property)properties[i]);
1877 ((Property)properties[i]).BuildTables(md);
1879 md.AddToTable(MDTable.PropertyMap,new MapElem(this,
1880 ((Property)properties[0]).Row,MDTable.Property));
1882 // Console.WriteLine("End of building tables");
1886 internal sealed override uint Size(MetaData md)
1888 return 4 + 2 * md.StringsIndexSize() +
1889 md.CodedIndexSize(CIx.TypeDefOrRef) +
1890 md.TableIndexSize(MDTable.Field) +
1891 md.TableIndexSize(MDTable.Method);
1894 internal sealed override void Write(FileImage output)
1896 output.Write(flags);
1897 output.StringsIndex(nameIx);
1898 output.StringsIndex(nameSpaceIx);
1899 //if (superType != null)
1900 // Console.WriteLine("getting coded index for superType of " + name + " = " + superType.GetCodedIx(CIx.TypeDefOrRef));
1901 output.WriteCodedIndex(CIx.TypeDefOrRef,superType);
1902 output.WriteIndex(MDTable.Field,fieldIx);
1903 output.WriteIndex(MDTable.Method,methodIx);
1906 internal sealed override uint TypeDefOrRefToken()
1913 internal sealed override void TypeSig(MemoryStream sig)
1915 if (!typeIndexChecked) CheckTypeIndex();
1916 sig.WriteByte(GetTypeIndex());
1917 MetaData.CompressNum(TypeDefOrRefToken(),sig);
1920 internal sealed override uint GetCodedIx(CIx code)
1923 case (CIx.TypeDefOrRef) : return 0;
1924 case (CIx.HasCustomAttr) : return 3;
1925 case (CIx.HasDeclSecurity) : return 0;
1926 case (CIx.TypeOrMethodDef) : return 0;
1933 /**************************************************************************/
1935 /// Descriptor for a class/interface declared in another module of THIS
1936 /// assembly, or in another assembly.
1938 public class ClassRef : Class, IExternRef, IResolutionScope {
1940 protected IResolutionScope parent;
1941 ExternClass externClass;
1942 protected MetaData metaData;
1944 internal ClassRef(string nsName, string name, MetaData md) : base(nsName, name, md)
1947 tabIx = MDTable.TypeRef;
1951 /// Add a method to this class
1953 /// <param name="name">method name</param>
1954 /// <param name="retType">return type</param>
1955 /// <param name="pars">parameter types</param>
1956 /// <returns>a descriptor for this method</returns>
1957 public MethodRef AddMethod(string name, Type retType, Type[] pars)
1959 return AddMethod (name, retType, pars, 0);
1963 /// Add a method to this class
1965 /// <param name="name">method name</param>
1966 /// <param name="retType">return type</param>
1967 /// <param name="pars">parameter types</param>
1968 /// <param name="gen_param_count">num of generic parameters</param>
1969 /// <returns>a descriptor for this method</returns>
1970 public MethodRef AddMethod (string name, Type retType, Type[] pars, int gen_param_count)
1972 MethodRef meth = new MethodRef (this, name, retType, pars, false, null, gen_param_count);
1973 metaData.AddToTable(MDTable.MemberRef,meth);
1978 /// Add a method to this class
1980 /// <param name="name">method name</param>
1981 /// <param name="retType">return type</param>
1982 /// <param name="pars">parameter types</param>
1983 /// <returns>a descriptor for this method</returns>
1984 public MethodRef AddVarArgMethod(string name, Type retType,
1985 Type[] pars, Type[] optPars)
1987 MethodRef meth = new MethodRef(this,name,retType,pars,true,optPars, 0);
1988 metaData.AddToTable(MDTable.MemberRef,meth);
1993 /// Add a field to this class
1995 /// <param name="name">field name</param>
1996 /// <param name="fType">field type</param>
1997 /// <returns>a descriptor for this field</returns>
1998 public FieldRef AddField(string name, Type fType)
2000 FieldRef field = new FieldRef(this,name,fType);
2001 metaData.AddToTable(MDTable.MemberRef,field);
2005 public ClassRef AddClass (string nsName, string name)
2007 ClassRef aClass = new ClassRef(nsName,name,metaData);
2008 metaData.AddToTable(MDTable.TypeRef,aClass);
2009 aClass.SetParent(this);
2013 public ClassRef AddValueClass (string nsName, string name)
2015 ClassRef aClass = AddClass (nsName, name);
2016 aClass.MakeValueClass (ValueClass.ValueType);
2020 internal void SetParent(IResolutionScope par)
2025 internal override string TypeName()
2027 if ((parent != null) && (parent is AssemblyRef))
2028 return (nameSpace + "." + name + ", " + ((AssemblyRef)parent).TypeName());
2030 return (nameSpace + name);
2033 internal sealed override uint Size(MetaData md)
2035 return md.CodedIndexSize(CIx.ResolutionScope) + 2 *
2036 md.StringsIndexSize();
2039 internal sealed override void Write(FileImage output)
2041 output.WriteCodedIndex(CIx.ResolutionScope,(MetaDataElement) parent);
2042 output.StringsIndex(nameIx);
2043 output.StringsIndex(nameSpaceIx);
2046 internal override sealed uint TypeDefOrRefToken()
2049 cIx = (cIx << 2) | 0x1;
2053 internal override void TypeSig(MemoryStream sig)
2055 sig.WriteByte(GetTypeIndex());
2056 MetaData.CompressNum(TypeDefOrRefToken(),sig);
2059 internal sealed override uint GetCodedIx(CIx code)
2062 case (CIx.TypeDefOrRef) : return 1;
2063 case (CIx.HasCustomAttr) : return 2;
2064 case (CIx.MemberRefParent) : return 1;
2065 case (CIx.ResolutionScope) : return 3;
2072 /**************************************************************************/
2073 public class ExternClassRef : ClassRef {
2075 ExternClass externClass;
2077 internal ExternClassRef(TypeAttr attrs, string nsName, string name,
2078 FileRef declFile, MetaData md) : base(nsName,name,md)
2080 externClass = new ExternClass(attrs,nameSpaceIx,nameIx,declFile);
2081 metaData.AddToTable(MDTable.ExportedType,externClass);
2084 internal ExternClassRef(string name, MetaData md) : base(null,name,md)
2088 public ClassRef AddNestedClass(TypeAttr attrs, string name)
2090 ExternClassRef nestedClass = new ExternClassRef(name,metaData);
2091 externClass = new ExternClass(attrs,0,nameIx,this.externClass);
2092 metaData.AddToTable(MDTable.ExportedType,externClass);
2098 /**************************************************************************/
2100 /// Descriptor for a class defined in another module of THIS assembly
2101 /// and exported (.class extern)
2104 internal class ExternClass : Class {
2106 MetaDataElement parent;
2109 internal ExternClass(TypeAttr attr, uint nsIx, uint nIx,
2110 MetaDataElement paren) : base(nsIx,nIx)
2114 tabIx = MDTable.ExportedType;
2117 internal sealed override uint Size(MetaData md)
2119 return 8 + 2* md.StringsIndexSize() + md.CodedIndexSize(CIx.Implementation);
2122 internal sealed override void Write(FileImage output)
2124 output.Write(flags);
2126 output.StringsIndex(nameIx);
2127 output.StringsIndex(nameSpaceIx);
2128 output.WriteCodedIndex(CIx.Implementation,parent);
2131 internal sealed override uint GetCodedIx(CIx code)
2134 case (CIx.HasCustomAttr) : return 17;
2135 case (CIx.Implementation) : return 2;
2142 public class GenParam : Class {
2145 private string param_name;
2146 private uint sigIx = 0;
2148 public GenParam (int index, string name, GenParamType ptype) : base ((byte) ptype)
2151 this.param_name = name;
2152 tabIx = MDTable.TypeSpec;
2156 get { return index; }
2157 set { index = value; }
2160 public string Name {
2161 get { return param_name; }
2162 set { param_name = value; }
2165 public GenParamType Type {
2166 get { return (GenParamType) GetTypeIndex (); }
2169 internal sealed override void BuildTables (MetaData md)
2173 MemoryStream str = new MemoryStream ();
2175 sigIx = md.AddToBlobHeap (str.ToArray ());
2180 internal sealed override void TypeSig(MemoryStream str)
2183 throw new PEFileException (String.Format ("Unresolved {0} - {1}", (GenParamType) GetTypeIndex (), param_name));
2184 str.WriteByte(typeIndex);
2185 MetaData.CompressNum ((uint) index, str);
2188 internal override uint Size(MetaData md)
2190 return md.BlobIndexSize();
2193 internal sealed override void Write (FileImage output)
2195 output.BlobIndex (sigIx);
2198 internal sealed override uint GetCodedIx(CIx code)
2201 case (CIx.TypeDefOrRef) : return 2;
2202 case (CIx.HasCustomAttr) : return 13;
2203 case (CIx.MemberRefParent) : return 4;
2209 public class GenericTypeInst : Class {
2211 private Type gen_type;
2212 private Type[] gen_param;
2213 bool inTable = false;
2216 public GenericTypeInst (Type gen_type, Type[] gen_param)
2217 : base ((byte) PrimitiveType.GenericInst.GetTypeIndex ())
2219 this.gen_type = gen_type;
2220 this.gen_param = gen_param;
2221 tabIx = MDTable.TypeSpec;
2224 internal override MetaDataElement GetTypeSpec (MetaData md)
2227 md.AddToTable (MDTable.TypeSpec, this);
2234 internal sealed override void TypeSig(MemoryStream str)
2236 str.WriteByte(typeIndex);
2237 gen_type.TypeSig (str);
2238 MetaData.CompressNum ((uint) gen_param.Length, str);
2239 foreach (Type param in gen_param)
2240 param.TypeSig (str);
2243 internal sealed override void BuildTables (MetaData md)
2247 MemoryStream str = new MemoryStream ();
2249 sigIx = md.AddToBlobHeap (str.ToArray ());
2254 internal sealed override uint Size (MetaData md)
2256 return md.BlobIndexSize ();
2259 internal sealed override void Write (FileImage output)
2261 output.BlobIndex (sigIx);
2264 internal sealed override uint GetCodedIx (CIx code)
2267 case (CIx.TypeDefOrRef): return 2;
2268 case (CIx.MemberRefParent): return 4;
2269 case (CIx.HasCustomAttr): return 13;
2275 public class GenericMethodSig {
2277 private Type[] gen_param;
2279 private uint sigIx = 0;
2281 public GenericMethodSig (Type[] gen_param)
2283 this.gen_param = gen_param;
2287 internal void TypeSig (MemoryStream str)
2289 str.WriteByte (0x0A); /* GENERIC_INST */
2290 MetaData.CompressNum ((uint) gen_param.Length, str);
2291 foreach (Type param in gen_param)
2292 param.TypeSig (str);
2295 internal uint GetSigIx (MetaData md)
2300 MemoryStream sig = new MemoryStream();
2302 sigIx = md.AddToBlobHeap (sig.ToArray());
2308 public class Sentinel : Type {
2310 public Sentinel () : base (0x41) { }
2312 internal sealed override void TypeSig(MemoryStream str)
2314 str.WriteByte(typeIndex);
2318 /**************************************************************************/
2320 /// Descriptor for a FunctionPointer type
2323 public class MethPtrType : Type {
2335 /// Create a new function pointer type
2337 /// <param name="meth">the function to be referenced</param>
2338 public MethPtrType (CallConv callconv, Type retType, Type[] pars,
2339 bool varArgMeth, Type[] optPars) : base(0x1B)
2341 this.retType = retType;
2342 callConv = callconv;
2344 this.varArgMeth = varArgMeth;
2345 if (parList != null) numPars = (uint)parList.Length;
2347 optParList = optPars;
2348 if (optParList != null) numOptPars = (uint)optParList.Length;
2349 callConv |= CallConv.Vararg;
2351 tabIx = MDTable.TypeSpec;
2354 internal sealed override void TypeSig(MemoryStream sig)
2356 sig.WriteByte(typeIndex);
2357 // Bootlegged from method ref
2358 sig.WriteByte((byte)callConv);
2359 MetaData.CompressNum (numPars + numOptPars, sig);
2360 retType.TypeSig (sig);
2361 for (int i=0; i < numPars; i++) {
2362 parList[i].TypeSig (sig);
2365 sig.WriteByte (0x41); // Write the sentinel
2366 for (int i=0; i < numOptPars; i++) {
2367 optParList[i].TypeSig (sig);
2372 internal sealed override void BuildTables(MetaData md)
2375 MemoryStream sig = new MemoryStream();
2377 sigIx = md.AddToBlobHeap(sig.ToArray());
2381 internal sealed override uint Size(MetaData md)
2383 return md.BlobIndexSize();
2386 internal sealed override void Write(FileImage output)
2388 output.BlobIndex(sigIx);
2391 internal sealed override uint GetCodedIx(CIx code) { return 0x1B; }
2396 /* Classes for Arrays */
2399 /// The IL Array type
2401 public abstract class Array : Type {
2403 protected Type elemType;
2404 protected MetaData metaData;
2405 protected string cnameSpace, cname;
2407 internal Array(Type eType, byte TypeId) : base(TypeId)
2410 tabIx = MDTable.TypeSpec;
2415 /// Single dimensional array with zero lower bound
2417 public class ZeroBasedArray : Array {
2420 /// Create a new array - elementType[]
2422 /// <param name="elementType">the type of the array elements</param>
2423 public ZeroBasedArray(Type elementType) : base (elementType, PrimitiveType.SZArray.GetTypeIndex ()) { }
2425 internal sealed override void TypeSig(MemoryStream str)
2427 str.WriteByte(typeIndex);
2428 elemType.TypeSig(str);
2434 /// Multi dimensional array with explicit bounds
2436 public class BoundArray : Array {
2442 /// Create a new multi dimensional array type
2443 /// eg. elemType[1..5,3..10,5,,] would be
2444 /// new BoundArray(elemType,5,[1,3,0],[5,10,4])
2446 /// <param name="elementType">the type of the elements</param>
2447 /// <param name="dimensions">the number of dimensions</param>
2448 /// <param name="loBounds">lower bounds of dimensions</param>
2449 /// <param name="sizes">sizes for the dimensions</param>
2450 public BoundArray(Type elementType, uint dimensions, int[] loBounds,
2451 int[] sizes) : base (elementType,0x14)
2453 numDims = dimensions;
2454 lowerBounds = loBounds;
2459 /// Create a new multi dimensional array type
2460 /// eg. elemType[5,10,20] would be new BoundArray(elemType,3,[5,10,20])
2462 /// <param name="elementType">the type of the elements</param>
2463 /// <param name="dimensions">the number of dimensions</param>
2464 /// <param name="size">the sizes of the dimensions</param>
2465 public BoundArray(Type elementType, uint dimensions, int[] size)
2466 : base (elementType,0x14)
2468 numDims = dimensions;
2473 /// Create a new multi dimensional array type
2474 /// eg. elemType[,,] would be new BoundArray(elemType,3)
2476 /// <param name="elementType">the type of the elements</param>
2477 /// <param name="dimensions">the number of dimensions</param>
2478 public BoundArray(Type elementType, uint dimensions)
2479 : base (elementType,0x14)
2481 numDims = dimensions;
2484 internal sealed override void TypeSig(MemoryStream str)
2486 str.WriteByte(typeIndex);
2487 elemType.TypeSig(str);
2488 MetaData.CompressNum(numDims,str);
2489 if ((sizes != null) && (sizes.Length > 0)) {
2491 MetaData.CompressNum((uint)sizes.Length,str);
2492 for (int i=0; i < sizes.Length; i++) {
2493 MetaData.CompressNum((uint)sizes[i],str);
2495 } else str.WriteByte(0);
2496 if ((lowerBounds != null) && (lowerBounds.Length > 0)) {
2497 MetaData.CompressNum((uint)lowerBounds.Length,str);
2498 for (int i=0; i < lowerBounds.Length; i++) {
2499 CompressSignedNum (lowerBounds[i],str);
2501 } else str.WriteByte(0);
2503 private void CompressSignedNum (int val, MemoryStream str)
2505 uint uval = (uint) val;
2512 /* Map the signed number to an unsigned number in two ways.
2514 fval: left-rotated 2's complement representation
2515 sval: map the signed number to unsigned as follows: 0 -> 0, -1 -> 1, 1 -> 2, -2 -> 3, 2 -> 4, ....
2516 the mapping is: x -> 2*|x| - signbit(x)
2518 uint fval = (uval << 1) | sign;
2519 int sval = (val << 1) - sign;
2521 /* An overly clever transformation:
2523 a. sval is used to determine the number of bytes in the compressed representation.
2524 b. fval is truncated to the appropriate number of bits and output using the
2525 normal unsigned-int compressor.
2527 However, or certain values, the truncated fval doesn't carry enough information to round trip.
2529 (fval & 0x3FFF) <= 0x7F => compressor emits 1 byte, not 2 => there is aliasing of values
2531 So, we use full 4 bytes to encode such values.
2533 LAMESPEC: The Microsoft implementation doesn't appear to handle this subtle case.
2534 e.g., it ends up encoding -8192 as the byte 0x01, which decodes to -64
2537 MetaData.CompressNum (fval & 0x7F, str);
2538 else if (sval <= 0x3FFF && (fval & 0x3FFF) > 0x7F)
2539 MetaData.CompressNum (fval & 0x3FFF, str);
2540 else if (sval <= 0x1FFFFFFF && (fval & 0x1FFFFFFF) > 0x3FFF)
2541 MetaData.CompressNum (fval & 0x1FFFFFFF, str);
2543 /* FIXME: number cannot be represented. Report a warning. */
2544 // throw new Exception ("cannot represent signed value" + -val);
2545 MetaData.CompressNum (fval, str);
2552 /* Empty interface for grouping TypeRef's possible ResolutionScope
2553 namely : Module, ModuleRef, AssemblyRef and TypeRef */
2554 public interface IResolutionScope {
2557 /**************************************************************************/
2559 /// Base class for scopes (extended by Module, ModuleRef, Assembly, AssemblyRef)
2561 public abstract class ResolutionScope : MetaDataElement, IResolutionScope {
2563 protected uint nameIx = 0;
2564 protected MetaData metaData;
2565 protected string name;
2567 internal ResolutionScope(string name, MetaData md)
2571 nameIx = md.AddToStringsHeap(name);
2574 internal string GetName() { return name; }
2578 /**************************************************************************/
2580 /// Descriptor for THIS assembly (.assembly)
2582 public class Assembly : ResolutionScope {
2584 ushort majorVer, minorVer, buildNo, revisionNo;
2587 uint keyIx = 0, cultIx = 0;
2588 bool hasPublicKey = false;
2590 internal Assembly(string name, MetaData md) : base(name,md)
2592 tabIx = MDTable.Assembly;
2596 /// Add details about THIS assembly
2598 /// <param name="majVer">Major Version</param>
2599 /// <param name="minVer">Minor Version</param>
2600 /// <param name="bldNo">Build Number</param>
2601 /// <param name="revNo">Revision Number</param>
2602 /// <param name="key">Hash Key</param>
2603 /// <param name="hash">Hash Algorithm</param>
2604 /// <param name="cult">Culture</param>
2605 public void AddAssemblyInfo(int majVer, int minVer, int bldNo, int revNo,
2606 byte[] key, uint hash, string cult)
2608 majorVer = (ushort)majVer;
2609 minorVer = (ushort)minVer;
2610 buildNo = (ushort)bldNo;
2611 revisionNo = (ushort)revNo;
2613 hasPublicKey = (key != null);
2614 keyIx = metaData.AddToBlobHeap(key);
2615 cultIx = metaData.AddToStringsHeap(cult);
2619 /// Add an attribute to THIS assembly
2621 /// <param name="aa">assembly attribute</param>
2622 public void AddAssemblyAttr(AssemAttr aa)
2627 internal sealed override uint Size(MetaData md)
2629 return 16 + md.BlobIndexSize() + 2 * md.StringsIndexSize();
2632 internal sealed override void Write(FileImage output)
2634 // Console.WriteLine("Writing assembly element with nameIx of " + nameIx + " at file offset " + output.Seek(0,SeekOrigin.Current));
2635 output.Write((uint)hashAlgId);
2636 output.Write(majorVer);
2637 output.Write(minorVer);
2638 output.Write(buildNo);
2639 output.Write(revisionNo);
2640 output.Write(flags);
2641 output.BlobIndex(keyIx);
2642 output.StringsIndex(nameIx);
2643 output.StringsIndex(cultIx);
2646 internal sealed override uint GetCodedIx(CIx code)
2649 case (CIx.HasCustomAttr) : return 14;
2650 case (CIx.HasDeclSecurity) : return 2;
2655 internal bool HasPublicKey {
2656 get { return hasPublicKey; }
2660 /**************************************************************************/
2662 /// Descriptor for THIS module
2664 public class Module : ResolutionScope, IExternRef {
2669 internal Module(string name, MetaData md) : base(name,md)
2671 mvid = Guid.NewGuid();
2672 mvidIx = md.AddToGUIDHeap(mvid);
2673 tabIx = MDTable.Module;
2677 get { return mvid; }
2680 public ClassRef AddClass(string nsName, string name)
2682 ClassRef aClass = new ClassRef (nsName, name, metaData);
2683 metaData.AddToTable (MDTable.TypeRef, aClass);
2684 aClass.SetParent (this);
2688 public ClassRef AddValueClass(string nsName, string name)
2690 ClassRef aClass = AddClass (nsName, name);
2691 aClass.MakeValueClass (ValueClass.ValueType);
2695 internal sealed override uint Size(MetaData md)
2697 return 2 + md.StringsIndexSize() + 3 * md.GUIDIndexSize();
2700 internal sealed override void Write(FileImage output)
2702 output.Write((short)0);
2703 output.StringsIndex(nameIx);
2704 output.GUIDIndex(mvidIx);
2705 output.GUIDIndex(0);
2706 output.GUIDIndex(0);
2709 internal sealed override uint GetCodedIx(CIx code)
2712 case (CIx.HasCustomAttr) : return 7;
2713 case (CIx.ResolutionScope) : return 0;
2718 /**************************************************************************/
2720 /// Descriptor for another module in THIS assembly
2722 public class ModuleRef : ResolutionScope, IExternRef {
2724 internal ModuleRef(MetaData md, string name) : base(name,md)
2726 tabIx = MDTable.ModuleRef;
2730 /// Add a class to this external module. This is a class declared in
2731 /// another module of THIS assembly.
2733 /// <param name="nsName">name space name</param>
2734 /// <param name="name">class name</param>
2735 /// <returns>a descriptor for this class in another module</returns>
2736 public ClassRef AddClass(string nsName, string name)
2738 ClassRef aClass = new ClassRef(nsName,name,metaData);
2739 metaData.AddToTable(MDTable.TypeRef,aClass);
2740 aClass.SetParent(this);
2745 /// Make a file descriptor to correspond to this module. The file
2746 /// descriptor will have the same name as the module descriptor
2748 /// <param name="hashBytes">the hash of the file</param>
2749 /// <param name="hasMetaData">the file contains metadata</param>
2750 /// <param name="entryPoint">the program entry point is in this file</param>
2751 /// <returns>a descriptor for the file which contains this module</returns>
2752 public FileRef MakeFile(byte[] hashBytes, bool hasMetaData, bool entryPoint)
2754 FileRef file = new FileRef(nameIx,hashBytes,hasMetaData,entryPoint,metaData);
2755 metaData.AddToTable(MDTable.File,file);
2760 /// Add a value class to this module. This is a class declared in
2761 /// another module of THIS assembly.
2763 /// <param name="nsName">name space name</param>
2764 /// <param name="name">class name</param>
2765 /// <returns></returns>
2766 public ClassRef AddValueClass(string nsName, string name)
2768 ClassRef aClass = new ClassRef(nsName,name,metaData);
2769 metaData.AddToTable(MDTable.TypeRef,aClass);
2770 aClass.SetParent(this);
2771 aClass.MakeValueClass(ValueClass.ValueType);
2776 /// Add a class which is declared public in this external module of
2777 /// THIS assembly. This class will be exported from this assembly.
2778 /// The ilasm syntax for this is .extern class
2780 /// <param name="attrSet">attributes of the class to be exported</param>
2781 /// <param name="nsName">name space name</param>
2782 /// <param name="name">external class name</param>
2783 /// <param name="declFile">the file where the class is declared</param>
2784 /// <param name="isValueClass">is this class a value type?</param>
2785 /// <returns>a descriptor for this external class</returns>
2786 public ExternClassRef AddExternClass(TypeAttr attrSet, string nsName,
2787 string name, FileRef declFile,
2788 bool isValueClass) {
2789 ExternClassRef cRef = new ExternClassRef(attrSet,nsName,name,declFile,metaData);
2790 metaData.AddToTable(MDTable.TypeRef,cRef);
2791 cRef.SetParent(this);
2792 if (isValueClass) cRef.MakeValueClass(ValueClass.ValueType);
2797 /// Add a "global" method in another module
2799 /// <param name="name">method name</param>
2800 /// <param name="retType">return type</param>
2801 /// <param name="pars">method parameter types</param>
2802 /// <returns>a descriptor for this method in anther module</returns>
2803 public MethodRef AddMethod(string name, Type retType, Type[] pars)
2805 MethodRef meth = new MethodRef(this,name,retType,pars,false,null, 0);
2806 metaData.AddToTable(MDTable.MemberRef,meth);
2811 /// Add a vararg method to this class
2813 /// <param name="name">method name</param>
2814 /// <param name="retType">return type</param>
2815 /// <param name="pars">parameter types</param>
2816 /// <param name="optPars">optional param types for this vararg method</param>
2817 /// <returns>a descriptor for this method</returns>
2818 public MethodRef AddVarArgMethod(string name, Type retType,
2819 Type[] pars, Type[] optPars) {
2820 MethodRef meth = new MethodRef(this,name,retType,pars,true,optPars, 0);
2821 metaData.AddToTable(MDTable.MemberRef,meth);
2826 /// Add a field in another module
2828 /// <param name="name">field name</param>
2829 /// <param name="fType">field type</param>
2830 /// <returns>a descriptor for this field in another module</returns>
2831 public FieldRef AddField(string name, Type fType)
2833 FieldRef field = new FieldRef(this,name,fType);
2834 metaData.AddToTable(MDTable.MemberRef,field);
2838 internal sealed override uint Size(MetaData md)
2840 return md.StringsIndexSize();
2843 internal sealed override void Write(FileImage output)
2845 output.StringsIndex(nameIx);
2848 internal sealed override uint GetCodedIx(CIx code)
2851 case (CIx.HasCustomAttr) : return 12;
2852 case (CIx.MemberRefParent) : return 2;
2853 case (CIx.ResolutionScope) : return 1;
2860 #region Classes for Constants
2862 /// Descriptor for a constant value
2864 public abstract class Constant {
2865 protected uint size = 0;
2866 protected Type type;
2867 protected uint blobIndex;
2868 protected bool addedToBlobHeap = false;
2870 internal Constant() { }
2872 internal virtual uint GetBlobIndex(MetaData md) { return 0; }
2874 internal uint GetSize() { return size; }
2876 internal byte GetTypeIndex() { return type.GetTypeIndex(); }
2878 internal virtual void Write(BinaryWriter bw) { }
2882 /// Descriptor for a constant value
2884 public abstract class DataConstant : Constant {
2885 private uint dataOffset = 0;
2887 internal DataConstant() { }
2889 public uint DataOffset {
2890 get { return dataOffset; }
2891 set { dataOffset = value; }
2897 /// Boolean constant
2899 public class BoolConst : Constant {
2903 /// Create a new boolean constant with the value "val"
2905 /// <param name="val">value of this boolean constant</param>
2906 public BoolConst(bool val)
2910 type = PrimitiveType.Boolean;
2913 internal sealed override uint GetBlobIndex(MetaData md)
2915 if (!addedToBlobHeap) {
2916 if (val) blobIndex = md.AddToBlobHeap((sbyte)1);
2917 else blobIndex = md.AddToBlobHeap((sbyte)0);
2918 addedToBlobHeap = true;
2923 internal sealed override void Write(BinaryWriter bw)
2925 if (val) bw.Write((sbyte)1);
2926 else bw.Write((sbyte)0);
2931 public class ByteArrConst : DataConstant {
2934 public ByteArrConst(byte[] val)
2936 type = PrimitiveType.String;
2938 size = (uint)val.Length;
2942 get { return type; }
2943 set { type = value; }
2946 internal sealed override uint GetBlobIndex(MetaData md)
2948 if (!addedToBlobHeap) {
2949 blobIndex = md.AddToBlobHeap(val);
2950 addedToBlobHeap = true;
2955 internal sealed override void Write(BinaryWriter bw)
2962 public class CharConst : Constant {
2965 public CharConst(char val)
2969 type = PrimitiveType.Char;
2972 internal sealed override uint GetBlobIndex(MetaData md)
2974 if (!addedToBlobHeap) {
2975 blobIndex = md.AddToBlobHeap(val);
2976 addedToBlobHeap = true;
2981 internal sealed override void Write(BinaryWriter bw)
2988 public class FloatConst : DataConstant {
2991 public FloatConst(float val)
2995 type = PrimitiveType.Float32;
2998 internal sealed override uint GetBlobIndex(MetaData md)
3000 if (!addedToBlobHeap) {
3001 blobIndex = md.AddToBlobHeap(val);
3002 addedToBlobHeap = true;
3007 internal sealed override void Write(BinaryWriter bw)
3014 public class DoubleConst : DataConstant {
3017 public DoubleConst(double val)
3021 type = PrimitiveType.Float64;
3024 internal sealed override uint GetBlobIndex(MetaData md)
3026 if (!addedToBlobHeap) {
3027 blobIndex = md.AddToBlobHeap(val);
3028 addedToBlobHeap = true;
3033 internal sealed override void Write(BinaryWriter bw)
3040 public class IntConst : DataConstant {
3043 public IntConst(sbyte val)
3047 type = PrimitiveType.Int8;
3050 public IntConst(short val)
3054 type = PrimitiveType.Int16;
3057 public IntConst(int val)
3061 type = PrimitiveType.Int32;
3064 public IntConst(long val)
3068 type = PrimitiveType.Int64;
3071 internal sealed override uint GetBlobIndex(MetaData md)
3073 if (!addedToBlobHeap) {
3075 case (1) : blobIndex = md.AddToBlobHeap((sbyte)val); break;
3076 case (2) : blobIndex = md.AddToBlobHeap((short)val); break;
3077 case (4) : blobIndex = md.AddToBlobHeap((int)val); break;
3078 default : blobIndex = md.AddToBlobHeap(val); break;
3080 addedToBlobHeap = true;
3085 internal sealed override void Write(BinaryWriter bw)
3088 case (1) : bw.Write((sbyte)val); break;
3089 case (2) : bw.Write((short)val); break;
3090 case (4) : bw.Write((int)val); break;
3091 default : bw.Write(val); break;
3097 public class UIntConst : Constant {
3100 public UIntConst(byte val)
3104 type = PrimitiveType.UInt8;
3106 public UIntConst(ushort val)
3110 type = PrimitiveType.UInt16;
3112 public UIntConst(uint val)
3116 type = PrimitiveType.UInt32;
3118 public UIntConst(ulong val)
3122 type = PrimitiveType.UInt64;
3125 internal sealed override uint GetBlobIndex(MetaData md)
3127 if (!addedToBlobHeap) {
3129 case (1) : blobIndex = md.AddToBlobHeap((byte)val); break;
3130 case (2) : blobIndex = md.AddToBlobHeap((ushort)val); break;
3131 case (4) : blobIndex = md.AddToBlobHeap((uint)val); break;
3132 default : blobIndex = md.AddToBlobHeap(val); break;
3134 addedToBlobHeap = true;
3139 internal sealed override void Write(BinaryWriter bw)
3142 case (1) : bw.Write((byte)val); break;
3143 case (2) : bw.Write((ushort)val); break;
3144 case (4) : bw.Write((uint)val); break;
3145 default : bw.Write(val); break;
3151 public class StringConst : DataConstant {
3154 public StringConst(string val)
3157 size = (uint)val.Length; // need to add null ??
3158 type = PrimitiveType.String;
3161 internal sealed override uint GetBlobIndex(MetaData md)
3163 if (!addedToBlobHeap) {
3164 byte [] b = Encoding.Unicode.GetBytes (val);
3165 blobIndex = md.AddToBlobHeap(b);
3166 addedToBlobHeap = true;
3171 internal sealed override void Write(BinaryWriter bw)
3178 public class NullConst : Constant {
3183 type = PrimitiveType.Class;
3186 internal sealed override uint GetBlobIndex(MetaData md)
3188 if (!addedToBlobHeap) {
3189 blobIndex = md.AddToBlobHeap((int)0);
3190 addedToBlobHeap = true;
3195 internal sealed override void Write(BinaryWriter bw)
3202 public class AddressConstant : DataConstant {
3205 public AddressConstant(DataConstant dConst)
3209 type = PrimitiveType.TypedRef;
3212 internal sealed override void Write(BinaryWriter bw)
3214 ((FileImage)bw).WriteDataRVA(data.DataOffset);
3219 public class RepeatedConstant : DataConstant {
3223 public RepeatedConstant(DataConstant dConst, int repeatCount)
3226 repCount = (uint)repeatCount;
3227 int[] sizes = new int[1];
3228 sizes[0] = repeatCount;
3229 type = new BoundArray(type,1,sizes);
3230 size = data.GetSize() * repCount;
3233 internal sealed override void Write(BinaryWriter bw)
3235 for (int i=0; i < repCount; i++) {
3242 public class ArrayConstant : DataConstant {
3243 DataConstant[] dataVals;
3245 public ArrayConstant(DataConstant[] dVals)
3248 for (int i=0; i < dataVals.Length; i++) {
3249 size += dataVals[i].GetSize();
3253 internal sealed override void Write(BinaryWriter bw)
3255 for (int i=0; i < dataVals.Length; i++) {
3256 dataVals[i].Write(bw);
3262 public class ClassType : Constant {
3266 public ClassType(string className)
3269 type = PrimitiveType.ClassType;
3272 public ClassType(Class classDesc)
3275 type = PrimitiveType.ClassType;
3278 internal override void Write(BinaryWriter bw)
3280 if (name == null) name = desc.TypeName();
3288 /**************************************************************************/
3290 /// Descriptor for a custom modifier of a type (modopt or modreq)
3293 public class CustomModifiedType : Type {
3299 /// Create a new custom modifier for a type
3301 /// <param name="type">the type to be modified</param>
3302 /// <param name="cmod">the modifier</param>
3303 /// <param name="cmodType">the type reference to be associated with the type</param>
3304 public CustomModifiedType(Type type, CustomModifier cmod, Class cmodType)
3308 this.cmodType = cmodType;
3311 internal sealed override void TypeSig(MemoryStream str)
3313 str.WriteByte(typeIndex);
3314 MetaData.CompressNum(cmodType.TypeDefOrRefToken(),str);
3320 /**************************************************************************/
3322 /// Base class for Event and Property descriptors
3325 public class Feature : MetaDataElement {
3327 internal enum MethodType : ushort { Setter = 0x01, Getter, Other = 0x04, AddOn = 0x08,
3328 RemoveOn = 0x10, Fire = 0x20 }
3330 private static readonly int INITSIZE = 5;
3331 private static readonly ushort specialName = 0x200;
3332 private static readonly ushort rtSpecialName = 0x400;
3334 protected ClassDef parent;
3335 protected ushort flags = 0;
3336 protected string name;
3337 protected int tide = 0;
3338 protected uint nameIx;
3339 protected MethodSemantics[] methods = new MethodSemantics[INITSIZE];
3341 internal Feature(string name, ClassDef par)
3347 internal void AddMethod(MethodDef meth, MethodType mType)
3349 if (tide >= methods.Length) {
3350 int len = methods.Length;
3351 MethodSemantics[] mTmp = methods;
3352 methods = new MethodSemantics[len * 2];
3353 for (int i=0; i < len; i++) {
3354 methods[i] = mTmp[i];
3357 methods[tide++] = new MethodSemantics(mType,meth,this);
3361 /// Set the specialName attribute for this Event or Property
3363 public void SetSpecialName()
3365 flags |= specialName;
3369 /// Set the RTSpecialName attribute for this Event or Property
3371 public void SetRTSpecialName()
3373 flags |= rtSpecialName;
3378 /**************************************************************************/
3380 /// Descriptor for an event
3382 public class Event : Feature {
3386 internal Event(string name, Type eType, ClassDef parent)
3387 : base(name, parent)
3390 tabIx = MDTable.Event;
3394 /// Add the addon method to this event
3396 /// <param name="addon">the addon method</param>
3397 public void AddAddon(MethodDef addon)
3399 AddMethod(addon,MethodType.AddOn);
3403 /// Add the removeon method to this event
3405 /// <param name="removeOn">the removeon method</param>
3406 public void AddRemoveOn(MethodDef removeOn)
3408 AddMethod(removeOn,MethodType.RemoveOn);
3412 /// Add the fire method to this event
3414 /// <param name="fire">the fire method</param>
3415 public void AddFire(MethodDef fire)
3417 AddMethod(fire,MethodType.Fire);
3421 /// Add another method to this event
3423 /// <param name="other">the method to be added</param>
3424 public void AddOther(MethodDef other)
3426 AddMethod(other,MethodType.Other);
3429 internal sealed override void BuildTables(MetaData md)
3432 nameIx = md.AddToStringsHeap(name);
3433 for (int i=0; i < tide; i++) {
3434 md.AddToTable(MDTable.MethodSemantics,methods[i]);
3439 internal sealed override uint Size(MetaData md)
3441 return 2 + md.StringsIndexSize() + md.CodedIndexSize(CIx.TypeDefOrRef);
3444 internal sealed override void Write(FileImage output)
3446 output.Write(flags);
3447 output.StringsIndex(nameIx);
3448 output.WriteCodedIndex(CIx.TypeDefOrRef,eventType);
3451 internal sealed override uint GetCodedIx(CIx code)
3454 case (CIx.HasCustomAttr) : return 10;
3455 case (CIx.HasSemantics) : return 0;
3462 /**************************************************************************/
3464 /// Descriptor for the Property of a class
3466 public class Property : Feature {
3468 private static readonly byte PropertyTag = 0x8;
3469 private bool instance;
3470 MethodDef getterMeth;
3471 ConstantElem constVal;
3472 uint typeBlobIx = 0;
3477 internal Property(string name, Type retType, Type[] pars, ClassDef parent) : base(name, parent)
3479 returnType = retType;
3481 if (pars != null) numPars = (uint)pars.Length;
3482 tabIx = MDTable.Property;
3486 /// Add a set method to this property
3488 /// <param name="setter">the set method</param>
3489 public void AddSetter(MethodDef setter)
3491 AddMethod(setter,MethodType.Setter);
3495 /// Add a get method to this property
3497 /// <param name="getter">the get method</param>
3498 public void AddGetter(MethodDef getter)
3500 AddMethod(getter,MethodType.Getter);
3501 getterMeth = getter;
3505 /// Add another method to this property
3507 /// <param name="other">the method</param>
3508 public void AddOther(MethodDef other)
3510 AddMethod(other,MethodType.Other);
3514 /// Add an initial value for this property
3516 /// <param name="constVal">the initial value for this property</param>
3517 public void AddInitValue(Constant constVal)
3519 this.constVal = new ConstantElem(this,constVal);
3522 public void SetInstance (bool isInstance)
3524 this.instance = isInstance;
3527 internal sealed override void BuildTables(MetaData md)
3530 nameIx = md.AddToStringsHeap(name);
3531 MemoryStream sig = new MemoryStream();
3532 byte tag = PropertyTag;
3536 MetaData.CompressNum(numPars,sig);
3537 returnType.TypeSig(sig);
3538 for (int i=0; i < numPars; i++) {
3539 parList[i].TypeSig(sig);
3541 typeBlobIx = md.AddToBlobHeap(sig.ToArray());
3542 for (int i=0; i < tide; i++) {
3543 md.AddToTable(MDTable.MethodSemantics,methods[i]);
3545 if (constVal != null) {
3546 md.AddToTable(MDTable.Constant,constVal);
3547 constVal.BuildTables(md);
3552 internal sealed override uint Size(MetaData md)
3554 return 2 + md.StringsIndexSize() + md.BlobIndexSize();
3557 internal sealed override void Write(FileImage output)
3559 output.Write(flags);
3560 output.StringsIndex(nameIx);
3561 output.BlobIndex(typeBlobIx);
3564 internal sealed override uint GetCodedIx(CIx code)
3567 case (CIx.HasCustomAttr) : return 9;
3568 case (CIx.HasConst) : return 2;
3569 case (CIx.HasSemantics) : return 1;
3576 /**************************************************************************/
3578 /// Base class for field/methods (member of a class)
3580 public abstract class Member : MetaDataElement {
3582 protected string name;
3583 protected uint nameIx = 0, sigIx = 0;
3585 internal Member(string memName)
3588 tabIx = MDTable.MemberRef;
3593 /*****************************************************************************/
3595 /// Descriptor for a field of a class
3598 public abstract class Field : Member {
3600 protected static readonly byte FieldSig = 0x6;
3602 protected Type type;
3604 internal Field(string pfName, Type pfType) : base(pfName)
3610 /**************************************************************************/
3612 /// Descriptor for a field defined in a class of THIS assembly/module
3614 public class FieldDef : Field {
3616 //private static readonly uint PInvokeImpl = 0x2000;
3617 private static readonly ushort HasFieldRVA = 0x100;
3618 private static readonly ushort HasDefault = 0x8000;
3621 ConstantElem constVal;
3623 FieldMarshal marshalInfo;
3626 internal FieldDef(string name, Type fType) : base(name,fType)
3628 tabIx = MDTable.Field;
3631 internal FieldDef(FieldAttr attrSet, string name, Type fType) : base(name, fType)
3633 flags = (ushort)attrSet;
3634 tabIx = MDTable.Field;
3638 /// Add an attribute(s) to this field
3640 /// <param name="fa">the attribute(s) to be added</param>
3641 public void AddFieldAttr(FieldAttr fa)
3643 flags |= (ushort)fa;
3647 /// Add a value for this field
3649 /// <param name="val">the value for the field</param>
3650 public void AddValue(Constant val)
3652 constVal = new ConstantElem(this,val);
3653 flags |= HasDefault;
3657 /// Add an initial value for this field (at dataLabel) (.data)
3659 /// <param name="val">the value for the field</param>
3660 /// <param name="repeatVal">the number of repetitions of this value</param>
3661 public void AddDataValue(DataConstant val)
3663 flags |= HasFieldRVA;
3664 rva = new FieldRVA(this,val);
3668 /// Set the offset of the field. Used for sequential or explicit classes.
3671 /// <param name="offs">field offset</param>
3672 public void SetOffset(uint offs)
3674 layout = new FieldLayout(this,offs);
3678 /// Set the marshalling info for a field
3680 /// <param name="mInf"></param>
3681 public void SetMarshalInfo(NativeType marshallType)
3683 flags |= (ushort) FieldAttr.HasFieldMarshal;
3684 marshalInfo = new FieldMarshal(this,marshallType);
3687 internal sealed override void BuildTables(MetaData md)
3690 nameIx = md.AddToStringsHeap(name);
3691 MemoryStream sig = new MemoryStream();
3692 sig.WriteByte(FieldSig);
3694 sigIx = md.AddToBlobHeap(sig.ToArray());
3696 md.AddToTable(MDTable.FieldRVA,rva);
3697 rva.BuildTables(md);
3698 } else if (constVal != null) {
3699 md.AddToTable(MDTable.Constant,constVal);
3700 constVal.BuildTables(md);
3702 if (layout != null) md.AddToTable(MDTable.FieldLayout,layout);
3703 if (marshalInfo != null) {
3704 md.AddToTable(MDTable.FieldMarshal,marshalInfo);
3705 marshalInfo.BuildTables(md);
3710 internal sealed override uint Size(MetaData md)
3712 return 2 + md.StringsIndexSize() + md.BlobIndexSize();
3715 internal sealed override void Write(FileImage output)
3717 output.Write(flags);
3718 output.StringsIndex(nameIx);
3719 output.BlobIndex(sigIx);
3722 internal sealed override uint GetCodedIx(CIx code)
3725 case (CIx.HasConst) : return 0;
3726 case (CIx.HasCustomAttr) : return 1;
3727 case (CIx.HasFieldMarshal) : return 0;
3728 case (CIx.MemberForwarded) : return 0;
3735 /**************************************************************************/
3737 /// Descriptor for a field of a class defined in another assembly/module
3739 public class FieldRef : Field {
3741 MetaDataElement parent;
3743 internal FieldRef(MetaDataElement paren, string name, Type fType) : base(name, fType)
3748 internal sealed override void BuildTables(MetaData md)
3751 nameIx = md.AddToStringsHeap(name);
3752 MemoryStream sig = new MemoryStream();
3753 sig.WriteByte(FieldSig);
3755 sigIx = md.AddToBlobHeap(sig.ToArray());
3759 internal sealed override uint Size(MetaData md)
3761 return md.CodedIndexSize(CIx.MemberRefParent) + md.StringsIndexSize() + md.BlobIndexSize();
3764 internal sealed override void Write(FileImage output)
3766 output.WriteCodedIndex(CIx.MemberRefParent,parent);
3767 output.StringsIndex(nameIx);
3768 output.BlobIndex(sigIx);
3771 internal sealed override uint GetCodedIx(CIx code) { return 6; }
3775 /**************************************************************************/
3777 /// Base class for Method Descriptors
3780 public abstract class Method : Member {
3782 internal Method (string methName) : base (methName)
3785 public abstract void AddCallConv(CallConv cconv);
3786 internal abstract void TypeSig(MemoryStream sig);
3787 internal abstract uint GetSigIx(MetaData md);
3790 /**************************************************************************/
3792 /// Descriptor for a method defined in THIS assembly/module
3796 public class MethodDef : Method {
3798 private static readonly ushort PInvokeImpl = 0x2000;
3799 //private static readonly uint UnmanagedExport = 0x0008;
3800 // private static readonly byte LocalSigByte = 0x7;
3801 uint parIx = 0, textOffset = 0;
3802 private CallConv callConv = CallConv.Default;
3803 private Type retType;
3804 private int gen_param_count;
3807 CILInstructions code;
3808 ArrayList securityActions = new ArrayList();
3812 ushort methFlags = 0, implFlags = 0;
3813 int maxStack = 0, numPars = 0;
3814 bool entryPoint = false;
3816 ArrayList varArgSigList;
3817 ImplMap pinvokeImpl;
3821 internal MethodDef(MetaData md, string name, Type retType, Param[] pars) : base (name)
3823 this.retType = retType;
3826 if (parList != null) numPars = parList.Length;
3827 tabIx = MDTable.Method;
3830 internal MethodDef (MetaData md, MethAttr mAttrSet, ImplAttr iAttrSet, string name,
3831 Type retType, Param [] pars) : this (md, name, retType, pars)
3833 methFlags = (ushort)mAttrSet;
3834 implFlags = (ushort)iAttrSet;
3837 internal Param[] GetPars()
3842 internal override uint GetSigIx(MetaData md)
3844 MemoryStream sig = new MemoryStream();
3846 return md.AddToBlobHeap(sig.ToArray());
3849 public override void AddCallConv(CallConv cconv)
3855 /// Add some attributes to this method descriptor
3857 /// <param name="ma">the attributes to be added</param>
3858 public void AddMethAttribute(MethAttr ma)
3860 methFlags |= (ushort)ma;
3864 /// Add some implementation attributes to this method descriptor
3866 /// <param name="ia">the attributes to be added</param>
3867 public void AddImplAttribute(ImplAttr ia)
3869 implFlags |= (ushort)ia;
3872 public void AddPInvokeInfo(ModuleRef scope, string methName,
3873 PInvokeAttr callAttr) {
3874 pinvokeImpl = new ImplMap((ushort)callAttr,this,methName,scope);
3875 methFlags |= PInvokeImpl;
3879 /// Add a named generic type parameter
3881 public GenericParameter AddGenericParameter (short index, string name)
3883 return AddGenericParameter (index, name, 0);
3887 /// Add a named generic type parameter with attributes
3889 public GenericParameter AddGenericParameter (short index, string name, GenericParamAttributes attr)
3891 GenericParameter gp = new GenericParameter (this, metaData, index, name, attr);
3892 metaData.AddToTable (MDTable.GenericParam, gp);
3898 /// Set the maximum stack height for this method
3900 /// <param name="maxStack">the maximum height of the stack</param>
3901 public void SetMaxStack(int maxStack)
3903 this.maxStack = maxStack;
3907 /// Add local variables to this method
3909 /// <param name="locals">the locals to be added</param>
3910 /// <param name="initLocals">are locals initialised to default values</param>
3911 public void AddLocals(Local[] locals, bool initLocals)
3913 this.locals = locals;
3914 this.initLocals = initLocals;
3917 /* Add Marshal info for return type */
3918 public void AddRetTypeMarshallInfo (NativeType marshallType)
3920 ret_param = new Param (ParamAttr.HasFieldMarshal, "", retType);
3921 ret_param.AddMarshallInfo (marshallType);
3925 /// Mark this method as having an entry point
3927 public void DeclareEntryPoint()
3933 /// Create a code buffer for this method to add the IL instructions to
3935 /// <returns>a buffer for this method's IL instructions</returns>
3936 public CILInstructions CreateCodeBuffer()
3938 code = new CILInstructions(metaData);
3943 /// Make a method reference descriptor for this method to be used
3944 /// as a callsite signature for this vararg method
3946 /// <param name="optPars">the optional pars for the vararg method call</param>
3947 /// <returns></returns>
3948 public MethodRef MakeVarArgSignature(Type[] optPars)
3950 Type[] pars = new Type[numPars];
3951 MethodRef varArgSig;
3952 for (int i=0; i < numPars; i++) {
3953 pars[i] = parList[i].GetParType();
3955 varArgSig = new MethodRef(this,name,retType,pars,true,optPars, 0);
3957 if (varArgSigList == null)
3958 varArgSigList = new ArrayList ();
3959 varArgSigList.Add (varArgSig);
3963 internal sealed override void TypeSig(MemoryStream sig)
3965 sig.WriteByte((byte)callConv);
3966 if ((callConv & CallConv.Generic) == CallConv.Generic)
3967 MetaData.CompressNum ((uint) gen_param_count, sig);
3968 MetaData.CompressNum((uint)numPars,sig);
3969 if (ret_param != null)
3970 ret_param.seqNo = 0;
3971 retType.TypeSig(sig);
3972 for (ushort i=0; i < numPars; i++) {
3973 parList[i].seqNo = (ushort)(i+1);
3974 parList[i].TypeSig(sig);
3978 internal sealed override void BuildTables(MetaData md)
3981 if (pinvokeImpl != null) {
3982 md.AddToTable(MDTable.ImplMap,pinvokeImpl);
3983 pinvokeImpl.BuildTables(md);
3985 if (entryPoint) md.SetEntryPoint(this);
3987 if (locals != null) {
3988 localSig = new LocalSig(locals);
3989 md.AddToTable(MDTable.StandAloneSig,localSig);
3990 localSig.BuildTables(md);
3991 locToken = localSig.Token();
3994 code.CheckCode(locToken,initLocals,maxStack);
3995 textOffset = md.AddCode(code);
3997 nameIx = md.AddToStringsHeap(name);
3998 sigIx = GetSigIx(md);
3999 parIx = md.TableIndex(MDTable.Param);
4000 if (ret_param != null) {
4001 md.AddToTable(MDTable.Param, ret_param);
4002 ret_param.BuildTables(md);
4004 for (int i=0; i < numPars; i++) {
4005 md.AddToTable(MDTable.Param,parList[i]);
4006 parList[i].BuildTables(md);
4008 if (varArgSigList != null) {
4009 foreach (MethodRef varArgSig in varArgSigList) {
4010 md.AddToTable(MDTable.MemberRef,varArgSig);
4011 varArgSig.BuildTables(md);
4014 // Console.WriteLine("method has " + numPars + " parameters");
4018 internal sealed override uint Size(MetaData md)
4020 return 8 + md.StringsIndexSize() + md.BlobIndexSize() + md.TableIndexSize(MDTable.Param);
4023 internal sealed override void Write(FileImage output)
4025 if (ZeroRva ()) output.Write(0);
4026 else output.WriteCodeRVA(textOffset);
4027 output.Write(implFlags);
4028 output.Write(methFlags);
4029 output.StringsIndex(nameIx);
4030 output.BlobIndex(sigIx);
4031 output.WriteIndex(MDTable.Param,parIx);
4034 internal bool ZeroRva ()
4036 return (((methFlags & (ushort)MethAttr.Abstract) != 0) ||
4037 ((implFlags & (ushort)ImplAttr.Runtime) != 0) ||
4038 ((implFlags & (ushort)ImplAttr.InternalCall) != 0) ||
4039 (pinvokeImpl != null)); // TODO: Not entirely true but works for now
4042 internal sealed override uint GetCodedIx(CIx code)
4045 case (CIx.HasCustomAttr) : return 0;
4046 case (CIx.HasDeclSecurity) : return 1;
4047 case (CIx.MemberRefParent) : return 3;
4048 case (CIx.MethodDefOrRef) : return 0;
4049 case (CIx.MemberForwarded) : return 1;
4050 case (CIx.CustomAttributeType) : return 2;
4051 case (CIx.TypeOrMethodDef) : return 1;
4057 /**************************************************************************/
4059 /// Descriptor for a method defined in another assembly/module
4061 public class MethodRef : Method {
4063 private static readonly byte Sentinel = 0x41;
4064 Type[] parList, optParList;
4065 MetaDataElement parent;
4066 uint numPars = 0, numOptPars = 0;
4067 CallConv callConv = CallConv.Default;
4069 int gen_param_count;
4071 internal MethodRef(MetaDataElement paren, string name, Type retType,
4072 Type[] pars, bool varArgMeth, Type[] optPars, int gen_param_count) : base(name)
4076 this.retType = retType;
4077 if (parList != null) numPars = (uint)parList.Length;
4079 optParList = optPars;
4080 if (optParList != null) numOptPars = (uint)optParList.Length;
4081 callConv = CallConv.Vararg;
4083 this.gen_param_count = gen_param_count;
4086 internal override uint GetSigIx(MetaData md)
4088 MemoryStream sig = new MemoryStream();
4090 return md.AddToBlobHeap(sig.ToArray());
4093 public override void AddCallConv(CallConv cconv)
4098 internal sealed override void TypeSig(MemoryStream sig)
4100 sig.WriteByte((byte)callConv);
4101 if ((callConv & CallConv.Generic) == CallConv.Generic)
4102 MetaData.CompressNum ((uint) gen_param_count, sig);
4103 MetaData.CompressNum(numPars+numOptPars,sig);
4104 retType.TypeSig(sig);
4105 for (int i=0; i < numPars; i++) {
4106 parList[i].TypeSig(sig);
4108 if (numOptPars > 0) {
4109 sig.WriteByte(Sentinel);
4110 for (int i=0; i < numOptPars; i++) {
4111 optParList[i].TypeSig(sig);
4116 internal sealed override void BuildTables(MetaData md)
4119 nameIx = md.AddToStringsHeap(name);
4120 sigIx = GetSigIx(md);
4124 internal sealed override uint Size(MetaData md)
4126 return md.CodedIndexSize(CIx.MemberRefParent) + md.StringsIndexSize() + md.BlobIndexSize();
4129 internal sealed override void Write(FileImage output)
4131 output.WriteCodedIndex(CIx.MemberRefParent,parent);
4132 output.StringsIndex(nameIx);
4133 output.BlobIndex(sigIx);
4136 internal sealed override uint GetCodedIx(CIx code)
4139 case (CIx.HasCustomAttr) : return 6;
4140 case (CIx.MethodDefOrRef) : return 1;
4141 case (CIx.CustomAttributeType) : return 3;
4149 /**************************************************************************/
4151 /// Descriptors for native types used for marshalling
4153 public class NativeType {
4154 public static readonly NativeType Void = new NativeType(0x01);
4155 public static readonly NativeType Boolean = new NativeType(0x02);
4156 public static readonly NativeType Int8 = new NativeType(0x03);
4157 public static readonly NativeType UInt8 = new NativeType(0x04);
4158 public static readonly NativeType Int16 = new NativeType(0x05);
4159 public static readonly NativeType UInt16 = new NativeType(0x06);
4160 public static readonly NativeType Int32 = new NativeType(0x07);
4161 public static readonly NativeType UInt32 = new NativeType(0x08);
4162 public static readonly NativeType Int64 = new NativeType(0x09);
4163 public static readonly NativeType UInt64 = new NativeType(0x0A);
4164 public static readonly NativeType Float32 = new NativeType(0x0B);
4165 public static readonly NativeType Float64 = new NativeType(0x0C);
4166 public static readonly NativeType Currency = new NativeType(0x0F);
4167 public static readonly NativeType BStr = new NativeType(0x13);
4168 public static readonly NativeType LPStr = new NativeType(0x14);
4169 public static readonly NativeType LPWStr = new NativeType(0x15);
4170 public static readonly NativeType LPTStr = new NativeType(0x16);
4171 public static readonly NativeType FixedSysString = new NativeType(0x17);
4172 public static readonly NativeType IUnknown = new NativeType(0x19);
4173 public static readonly NativeType IDispatch = new NativeType(0x1A);
4174 public static readonly NativeType Struct = new NativeType(0x1B);
4175 public static readonly NativeType Interface = new NativeType(0x1C);
4176 public static readonly NativeType Int = new NativeType(0x1F);
4177 public static readonly NativeType UInt = new NativeType(0x20);
4178 public static readonly NativeType ByValStr = new NativeType(0x22);
4179 public static readonly NativeType AnsiBStr = new NativeType(0x23);
4180 public static readonly NativeType TBstr = new NativeType(0x24);
4181 public static readonly NativeType VariantBool = new NativeType(0x25);
4182 public static readonly NativeType FuncPtr = new NativeType(0x26);
4183 public static readonly NativeType AsAny = new NativeType(0x28);
4184 public static readonly NativeType LPStruct = new NativeType(0x2b);
4185 public static readonly NativeType Error = new NativeType(0x2d);
4187 protected byte typeIndex;
4189 internal NativeType(byte tyIx) { typeIndex = tyIx; }
4190 internal byte GetTypeIndex() { return typeIndex; }
4192 internal virtual byte[] ToBlob()
4194 byte[] bytes = new byte[1];
4195 bytes[0] = GetTypeIndex();
4201 public class FixedSysString : NativeType {
4205 public FixedSysString (uint size) : base (NativeType.FixedSysString.GetTypeIndex ())
4210 internal override byte [] ToBlob ()
4212 MemoryStream str = new MemoryStream ();
4213 str.WriteByte (GetTypeIndex ());
4214 MetaData.CompressNum (size, str);
4215 return str.ToArray ();
4220 public class NativeArray : NativeType {
4222 NativeType elemType;
4223 int numElem = -1, parNum = -1, elemMult = -1;
4225 public NativeArray(NativeType elemType) : this (elemType, -1, -1, -1)
4227 this.elemType = elemType;
4230 /* public NativeArray(NativeType elemType, int len) : base(0x2A) {
4231 this.elemType = elemType;
4236 public NativeArray(NativeType elemType, int numElem, int parNumForLen, int elemMult) : base(0x2A)
4238 this.elemType = elemType;
4239 this.numElem = numElem;
4240 parNum = parNumForLen;
4241 this.elemMult = elemMult;
4244 public NativeArray(NativeType elemType, int numElem, int parNumForLen)
4245 : this (elemType, numElem, parNumForLen, -1)
4249 internal override byte[] ToBlob()
4251 MemoryStream str = new MemoryStream();
4252 str.WriteByte(GetTypeIndex());
4253 if (elemType == null) str.WriteByte(0x50); // no info (MAX)
4254 else str.WriteByte(elemType.GetTypeIndex());
4256 /* see : mono/metadata/metadata.c:mono_metadata_parse_marshal_spec
4257 * LAMESPEC: Older spec versions say elemMult comes before
4258 * len. Newer spec versions don't talk about elemMult at
4259 * all, but csc still emits it, and it is used to distinguish
4260 * between parNum being 0, and parNum being omitted.
4265 return str.ToArray ();
4267 MetaData.CompressNum((uint) parNum,str);
4268 if (numElem != -1) {
4269 MetaData.CompressNum ((uint) numElem, str);
4271 // <native_type> [ int32 ]
4272 MetaData.CompressNum((uint) elemMult,str);
4273 //else <native_type> [ int32 + int32 ]
4274 } else if (elemMult != -1) {
4275 // When can this occur ?
4276 MetaData.CompressNum (0, str);
4277 MetaData.CompressNum((uint) elemMult,str);
4279 //else <native_type> [ + int32 ]
4281 return str.ToArray();
4286 public class SafeArray : NativeType {
4288 SafeArrayType elemType;
4291 public SafeArray() : base(0x1D)
4295 public SafeArray(SafeArrayType elemType) : base(0x1D)
4297 this.elemType = elemType;
4301 internal override byte[] ToBlob()
4303 byte[] bytes = new byte[hasElemType ? 2 : 1];
4304 bytes[0] = GetTypeIndex();
4306 bytes[1] = (byte)elemType;
4312 public class FixedArray : NativeType {
4314 NativeType elemType;
4317 //public FixedArray(NativeType elemType, int numElems) : base(0x1E) {
4318 public FixedArray(int numElems) : base(0x1E)
4320 //this.elemType = elemType;
4321 numElem = (uint)numElems;
4324 internal override byte[] ToBlob()
4326 MemoryStream str = new MemoryStream();
4327 str.WriteByte(GetTypeIndex());
4328 MetaData.CompressNum(numElem,str);
4330 fixed array [5] lpstr [2]
4331 This format is not supported by ilasm 1.1.4322.2032,
4332 but is supported by 2.0.5125..
4333 ilasm 1.1 only supports "fixed array [5]"
4334 if (elemType == null) str.WriteByte(0x50); // no info (MAX)
4335 else str.WriteByte(elemType.GetTypeIndex());*/
4337 return str.ToArray();
4342 public class CustomMarshaller : NativeType {
4345 string marshallerName;
4348 public CustomMarshaller(string typeNameOrGUID, string marshallerName,
4349 string optCookie) : base(0x2C)
4351 typeName = typeNameOrGUID;
4352 this.marshallerName = marshallerName;
4356 public CustomMarshaller(string marshallerName, string optCookie)
4357 :this (null, marshallerName, optCookie)
4361 internal override byte[] ToBlob()
4363 MemoryStream str = new MemoryStream();
4364 BinaryWriter bw = new BinaryWriter(str,new UTF8Encoding());
4365 bw.Write(GetTypeIndex());
4366 //Native type name & unmanaged type - unused
4367 //See mono/metadata/metadata.c : mono_metadata_parse_marshal_spec
4368 bw.Write ((byte) 0); // Native Type name, unused
4369 bw.Write ((byte) 0); // Unmanaged type, unused
4370 if (marshallerName != null) {
4371 MetaData.CompressNum ((uint)marshallerName.Length, str);
4372 bw.Write(marshallerName.ToCharArray());
4374 bw.Write ((byte) 0);
4376 if (cookie != null) {
4377 MetaData.CompressNum ((uint)cookie.Length, str);
4378 bw.Write(cookie.ToCharArray());
4380 bw.Write ((byte) 0);
4383 return str.ToArray();
4387 /**************************************************************************/
4389 /// Descriptor for the Primitive types defined in IL
4391 public class PrimitiveType : Type {
4393 private string name;
4394 private int systemTypeIndex;
4395 public static int NumSystemTypes = 18;
4397 public static readonly PrimitiveType Void = new PrimitiveType(0x01,"Void",0);
4398 public static readonly PrimitiveType Boolean = new PrimitiveType(0x02,"Boolean",1);
4399 public static readonly PrimitiveType Char = new PrimitiveType(0x03,"Char",2);
4400 public static readonly PrimitiveType Int8 = new PrimitiveType(0x04,"SByte",3);
4401 public static readonly PrimitiveType UInt8 = new PrimitiveType(0x05,"Byte",4);
4402 public static readonly PrimitiveType Int16 = new PrimitiveType(0x06,"Int16",5);
4403 public static readonly PrimitiveType UInt16 = new PrimitiveType(0x07,"UInt16",6);
4404 public static readonly PrimitiveType Int32 = new PrimitiveType(0x08,"Int32",7);
4405 public static readonly PrimitiveType UInt32 = new PrimitiveType(0x09,"UInt32",8);
4406 public static readonly PrimitiveType Int64 = new PrimitiveType(0x0A,"Int64",9);
4407 public static readonly PrimitiveType UInt64 = new PrimitiveType(0x0B,"UInt64",10);
4408 public static readonly PrimitiveType Float32 = new PrimitiveType(0x0C,"Single",11);
4409 public static readonly PrimitiveType Float64 = new PrimitiveType(0x0D,"Double",12);
4410 public static readonly PrimitiveType String = new PrimitiveType(0x0E,"String",13);
4411 internal static readonly PrimitiveType Class = new PrimitiveType(0x12);
4412 internal static readonly PrimitiveType Var = new PrimitiveType(0x13);
4413 internal static readonly PrimitiveType GenericInst = new PrimitiveType(0x15);
4414 public static readonly PrimitiveType TypedRef = new PrimitiveType(0x16,"TypedReference",14);
4415 public static readonly PrimitiveType IntPtr = new PrimitiveType(0x18,"IntPtr",15);
4416 public static readonly PrimitiveType UIntPtr = new PrimitiveType(0x19,"UIntPtr",16);
4417 public static readonly PrimitiveType Object = new PrimitiveType(0x1C,"Object",17);
4418 internal static readonly PrimitiveType ClassType = new PrimitiveType(0x50);
4419 internal static readonly PrimitiveType SZArray = new PrimitiveType(0x1D);
4420 internal static readonly PrimitiveType MVar = new PrimitiveType(0x1E);
4421 internal static readonly PrimitiveType ValueType = new PrimitiveType(0x11, "ValueType", 18);
4422 public static readonly PrimitiveType NativeInt = IntPtr;
4423 public static readonly PrimitiveType NativeUInt = UIntPtr;
4425 internal PrimitiveType(byte typeIx) : base(typeIx) { }
4427 internal PrimitiveType(byte typeIx, string name, int STIx) : base(typeIx)
4430 this.systemTypeIndex = STIx;
4433 internal string GetName() { return name; }
4435 internal int GetSystemTypeIx() { return systemTypeIndex; }
4437 internal sealed override void TypeSig(MemoryStream str)
4439 str.WriteByte(typeIndex);
4442 internal override MetaDataElement GetTypeSpec(MetaData md)
4444 TypeSpec tS = md.GetPrimitiveTypeSpec(systemTypeIndex);
4446 tS = new TypeSpec(this,md);
4447 md.SetPrimitiveTypeSpec(systemTypeIndex,tS);
4448 md.AddToTable(MDTable.TypeSpec,tS);
4455 /**************************************************************************/
4457 /// Descriptor for an pointer (type * or type &)
4459 public abstract class PtrType : Type {
4463 internal PtrType(Type bType, byte typeIx) : base(typeIx)
4466 tabIx = MDTable.TypeSpec;
4469 internal sealed override void TypeSig(MemoryStream str)
4471 str.WriteByte(typeIndex);
4472 baseType.TypeSig(str);
4476 /**************************************************************************/
4478 /// Descriptor for a managed pointer (type & or byref)
4481 public class ManagedPointer : PtrType {
4484 /// Create new managed pointer to baseType
4486 /// <param name="bType">the base type of the pointer</param>
4487 public ManagedPointer(Type baseType) : base(baseType,0x10) { }
4490 /**************************************************************************/
4492 /// Descriptor for an unmanaged pointer (type *)
4494 public class UnmanagedPointer : PtrType {
4497 /// Create a new unmanaged pointer to baseType
4499 /// <param name="baseType">the base type of the pointer</param>
4500 public UnmanagedPointer(Type baseType) : base(baseType, 0x0F) { }
4504 /**************************************************************************/
4506 public interface IExternRef {
4507 ClassRef AddClass(string nsName, string name);
4508 ClassRef AddValueClass(string nsName, string name);
4512 /// A reference to an external assembly (.assembly extern)
4514 public class AssemblyRef : ResolutionScope, IExternRef {
4516 private ushort major, minor, build, revision;
4517 uint flags, keyIx, hashIx, cultIx;
4518 bool hasVersion = false, isKeyToken = false;
4522 internal AssemblyRef(MetaData md, string name) : base(name,md)
4524 tabIx = MDTable.AssemblyRef;
4528 /// Add version information about this external assembly
4530 /// <param name="majVer">Major Version</param>
4531 /// <param name="minVer">Minor Version</param>
4532 /// <param name="bldNo">Build Number</param>
4533 /// <param name="revNo">Revision Number</param>
4534 public void AddVersionInfo(int majVer, int minVer, int bldNo, int revNo)
4536 major = (ushort)majVer;
4537 minor = (ushort)minVer;
4538 build = (ushort)bldNo;
4539 revision = (ushort)revNo;
4544 /// Add the hash value for this external assembly
4546 /// <param name="hash">bytes of the hash value</param>
4547 public void AddHash(byte[] hash)
4549 hashIx = metaData.AddToBlobHeap(hash);
4553 /// Set the culture for this external assembly
4555 /// <param name="cult">the culture string</param>
4556 public void AddCulture(string cult)
4558 cultIx = metaData.AddToStringsHeap(cult);
4563 /// Add the full public key for this external assembly
4565 /// <param name="key">bytes of the public key</param>
4566 public void AddKey(byte[] key)
4568 flags |= 0x0001; // full public key
4570 keyIx = metaData.AddToBlobHeap(key);
4574 /// Add the public key token (low 8 bytes of the public key)
4576 /// <param name="key">low 8 bytes of public key</param>
4577 public void AddKeyToken(byte[] key)
4579 keyIx = metaData.AddToBlobHeap(key);
4585 /// Add a class to this external assembly
4587 /// <param name="nsName">name space name</param>
4588 /// <param name="name">class name</param>
4589 /// <returns></returns>
4590 public virtual ClassRef AddClass(string nsName, string name)
4592 ClassRef aClass = new ClassRef(nsName,name,metaData);
4593 metaData.AddToTable(MDTable.TypeRef,aClass);
4594 aClass.SetParent(this);
4599 /// Add a value class to this external assembly
4601 /// <param name="nsName">name space name</param>
4602 /// <param name="name">class name</param>
4603 /// <returns></returns>
4604 public virtual ClassRef AddValueClass(string nsName, string name)
4606 ClassRef aClass = new ClassRef(nsName,name,metaData);
4607 metaData.AddToTable(MDTable.TypeRef,aClass);
4608 aClass.SetParent(this);
4609 aClass.MakeValueClass(ValueClass.ValueType);
4613 internal string TypeName()
4615 string result = name;
4617 result = result + ", Version=" + major + "." + minor + "." +
4618 build + "." + revision;
4619 if (keyBytes != null) {
4620 string tokenStr = "=";
4621 if (isKeyToken) tokenStr = "Token=";
4622 result = result + ", PublicKey" + tokenStr;
4623 for (int i=0; i < keyBytes.Length; i++) {
4624 result = result + Hex.Byte(keyBytes[i]);
4627 if (culture != null)
4628 result = result + ", Culture=" + culture;
4632 internal sealed override uint Size(MetaData md)
4634 return 12 + 2 * md.StringsIndexSize() + 2 * md.BlobIndexSize();
4637 internal sealed override void Write(FileImage output)
4639 output.Write(major);
4640 output.Write(minor);
4641 output.Write(build);
4642 output.Write(revision);
4643 output.Write(flags);
4644 output.BlobIndex(keyIx);
4645 output.StringsIndex(nameIx);
4646 output.StringsIndex(cultIx);
4647 output.BlobIndex(hashIx);
4650 internal sealed override uint GetCodedIx(CIx code)
4653 case (CIx.ResolutionScope) : return 2;
4654 case (CIx.HasCustomAttr) : return 15;
4655 case (CIx.Implementation) : return 1;
4662 /**************************************************************************/
4664 /// Descriptor for a class defined in System (mscorlib)
4666 internal class SystemClass : ClassRef {
4668 PrimitiveType elemType;
4670 internal SystemClass(PrimitiveType eType, AssemblyRef paren, MetaData md)
4671 : base("System",eType.GetName(),md) {
4676 internal override sealed MetaDataElement GetTypeSpec(MetaData md)
4678 if (typeSpec == null) typeSpec = (TypeSpec)elemType.GetTypeSpec(md);
4683 internal sealed override void TypeSig(MemoryStream str)
4685 str.WriteByte(elemType.GetTypeIndex());
4690 /**************************************************************************/
4692 /// The assembly for mscorlib.
4694 public sealed class MSCorLib : AssemblyRef {
4696 private static readonly int valueTypeIx = 18;
4697 private readonly string systemName = "System";
4698 private Class[] systemClasses = new Class[valueTypeIx+2];
4699 private PrimitiveType[] systemTypes = new PrimitiveType[valueTypeIx];
4700 private TypeSpec[] specialTypeSpecs = new TypeSpec[valueTypeIx];
4701 private static int[] specialNames = {
4702 PrimitiveType.Void.GetName().GetHashCode(),
4703 PrimitiveType.Boolean.GetName().GetHashCode(),
4704 PrimitiveType.Char.GetName().GetHashCode(),
4705 PrimitiveType.Int8.GetName().GetHashCode(),
4706 PrimitiveType.UInt8.GetName().GetHashCode(),
4707 PrimitiveType.Int16.GetName().GetHashCode(),
4708 PrimitiveType.UInt16.GetName().GetHashCode(),
4709 PrimitiveType.Int32.GetName().GetHashCode(),
4710 PrimitiveType.UInt32.GetName().GetHashCode(),
4711 PrimitiveType.Int64.GetName().GetHashCode(),
4712 PrimitiveType.UInt64.GetName().GetHashCode(),
4713 PrimitiveType.Float32.GetName().GetHashCode(),
4714 PrimitiveType.Float64.GetName().GetHashCode(),
4715 PrimitiveType.String.GetName().GetHashCode(),
4716 PrimitiveType.TypedRef.GetName().GetHashCode(),
4717 PrimitiveType.IntPtr.GetName().GetHashCode(),
4718 PrimitiveType.UIntPtr.GetName().GetHashCode(),
4719 PrimitiveType.Object.GetName().GetHashCode(),
4720 PrimitiveType.ValueType.GetName ().GetHashCode(),
4721 "Enum".GetHashCode()
4724 internal MSCorLib(MetaData md) : base(md,"mscorlib")
4726 if (!PEFile.IsMSCorlib)
4727 md.AddToTable(MDTable.AssemblyRef,this);
4728 systemTypes[PrimitiveType.Void.GetSystemTypeIx()] = PrimitiveType.Void;
4729 systemTypes[PrimitiveType.Boolean.GetSystemTypeIx()] = PrimitiveType.Boolean;
4730 systemTypes[PrimitiveType.Char.GetSystemTypeIx()] = PrimitiveType.Char;
4731 systemTypes[PrimitiveType.Int8.GetSystemTypeIx()] = PrimitiveType.Int8;
4732 systemTypes[PrimitiveType.UInt8.GetSystemTypeIx()] = PrimitiveType.UInt8;
4733 systemTypes[PrimitiveType.Int16.GetSystemTypeIx()] = PrimitiveType.Int16;
4734 systemTypes[PrimitiveType.UInt16.GetSystemTypeIx()] = PrimitiveType.UInt16;
4735 systemTypes[PrimitiveType.Int32.GetSystemTypeIx()] = PrimitiveType.Int32;
4736 systemTypes[PrimitiveType.UInt32.GetSystemTypeIx()] = PrimitiveType.UInt32;
4737 systemTypes[PrimitiveType.Int64.GetSystemTypeIx()] = PrimitiveType.Int64;
4738 systemTypes[PrimitiveType.UInt64.GetSystemTypeIx()] = PrimitiveType.UInt64;
4739 systemTypes[PrimitiveType.Float32.GetSystemTypeIx()] = PrimitiveType.Float32;
4740 systemTypes[PrimitiveType.Float64.GetSystemTypeIx()] = PrimitiveType.Float64;
4741 systemTypes[PrimitiveType.IntPtr.GetSystemTypeIx()] = PrimitiveType.IntPtr;
4742 systemTypes[PrimitiveType.UIntPtr.GetSystemTypeIx()] = PrimitiveType.UIntPtr;
4743 systemTypes[PrimitiveType.String.GetSystemTypeIx()] = PrimitiveType.String;
4744 systemTypes[PrimitiveType.Object.GetSystemTypeIx()] = PrimitiveType.Object;
4745 systemTypes[PrimitiveType.TypedRef.GetSystemTypeIx()] = PrimitiveType.TypedRef;
4749 /// Add a class to the mscorlib assembly
4751 /// <param name="nsName">name space name</param>
4752 /// <param name="name">class name</param>
4753 /// <returns></returns>
4754 public override ClassRef AddClass(string nsName, string name)
4756 /* This gets called by !mscorlib, for adding references INTO mscorlib, so
4757 it should be returning ClassRef ..*/
4758 Class aClass = GetSpecialClass(nsName,name);
4759 if (aClass == null) {
4760 aClass = new ClassRef(nsName,name,metaData);
4761 metaData.AddToTable(MDTable.TypeRef,aClass);
4762 if (aClass is ClassRef)
4763 ((ClassRef) aClass).SetParent(this);
4765 //FIXME: Check for !ClassRef here?
4766 return (ClassRef) aClass;
4769 private Class GetSpecialClass(string nsName,string name)
4771 if (nsName.CompareTo(systemName) != 0) return null;
4772 int hash = name.GetHashCode();
4773 for (int i=0; i < specialNames.Length; i++) {
4774 if (hash != specialNames[i])
4776 if (systemClasses[i] == null) {
4777 if (i < valueTypeIx) {
4778 systemClasses[i] = new SystemClass(systemTypes[i],this,metaData);
4779 if ((systemTypes[i] != PrimitiveType.Object) &&
4780 (systemTypes[i] != PrimitiveType.String)) {
4781 systemClasses[i].MakeValueClass(ValueClass.ValueType);
4784 systemClasses[i] = new ClassRef(nsName,name,metaData);
4785 ((ClassRef) systemClasses[i]).SetParent(this);
4786 if (!ClassDef.IsValueType (nsName, name) && !ClassDef.IsEnum (nsName, name))
4787 systemClasses[i].MakeValueClass(ValueClass.ValueType);
4789 metaData.AddToTable(MDTable.TypeRef,systemClasses[i]);
4791 return systemClasses[i];
4796 internal void SetSpecialSystemClass (string nsName, string name, Class aClass)
4798 if (nsName != systemName) return;
4799 int hash = name.GetHashCode ();
4800 for (int i = 0; i < specialNames.Length; i++) {
4801 if (hash != specialNames [i])
4803 if (systemClasses [i] == null) {
4804 systemClasses [i] = aClass;
4809 internal Class GetSpecialSystemClass(PrimitiveType pType)
4811 int ix = pType.GetSystemTypeIx();
4812 if (systemClasses[ix] == null && !PEFile.IsMSCorlib) {
4813 systemClasses[ix] = new SystemClass(pType,this,metaData);
4814 metaData.AddToTable(MDTable.TypeRef,systemClasses[ix]);
4816 return systemClasses[ix];
4819 private ClassRef GetValueClass(string name, int hash)
4821 /* Called by MSCorLib.AddValueClass, which is called by
4822 !mscorlib, for adding ref to value class INTO mscorlib,
4823 so this should be classref */
4824 int ix = valueTypeIx;
4825 if (hash != specialNames[valueTypeIx]) ix++;
4826 if (systemClasses[ix] == null) {
4827 systemClasses[ix] = new ClassRef(systemName,name,metaData);
4828 ((ClassRef) systemClasses[ix]).SetParent(this);
4829 ((ClassRef) systemClasses[ix]).MakeValueClass(ValueClass.ValueType);
4830 metaData.AddToTable(MDTable.TypeRef,systemClasses[ix]);
4832 return (ClassRef) systemClasses[ix];
4835 internal Class ValueType()
4837 if (systemClasses[valueTypeIx] == null && !PEFile.IsMSCorlib) {
4838 ClassRef valType = new ClassRef("System","ValueType",metaData);
4839 valType.SetParent(this);
4840 valType.MakeValueClass(ValueClass.ValueType);
4841 metaData.AddToTable(MDTable.TypeRef,valType);
4842 systemClasses[valueTypeIx] = valType;
4844 return systemClasses[valueTypeIx];
4847 internal Class EnumType()
4849 /* Called by both mscorlib & !mscorlib, so can be
4850 either ClassRef or ClassDef */
4851 //systemClasses [ valueTypeIx + 1] -> System.Enum
4852 if (systemClasses[valueTypeIx + 1] == null && !PEFile.IsMSCorlib) {
4853 ClassRef valType = new ClassRef("System","Enum",metaData);
4854 valType.SetParent(this);
4855 valType.MakeValueClass(ValueClass.Enum);
4856 metaData.AddToTable(MDTable.TypeRef,valType);
4857 systemClasses[valueTypeIx + 1] = valType;
4859 return systemClasses[valueTypeIx + 1];
4863 /// Add a value class to this external assembly
4865 /// <param name="nsName">name space name</param>
4866 /// <param name="name">class name</param>
4867 /// <returns></returns>
4868 public override ClassRef AddValueClass(string nsName, string name)
4870 if (nsName.CompareTo(systemName) == 0) {
4871 int hash = name.GetHashCode();
4872 if ((hash == specialNames[valueTypeIx]) ||
4873 (hash == specialNames[valueTypeIx+1])) {
4874 return GetValueClass(name,hash);
4877 ClassRef aClass = new ClassRef(nsName,name,metaData);
4878 metaData.AddToTable(MDTable.TypeRef,aClass);
4879 aClass.SetParent(this);
4880 aClass.MakeValueClass(ValueClass.ValueType);
4886 /**************************************************************************/
4889 /// Root (20 bytes + UTF-8 Version String + quad align padding)
4890 /// StreamHeaders (8 bytes + null terminated name string + quad align padding)
4892 /// #~ (always present - holds metadata tables)
4893 /// #Strings (always present - holds identifier strings)
4894 /// #US (Userstring heap)
4895 /// #Blob (signature blobs)
4896 /// #GUID (guids for assemblies or Modules)
4898 public class MetaData {
4900 internal static readonly int[] CIxShiftMap = {2,2,5,1,2,3,1,1,1,2,3,2,1};
4901 private static readonly byte StringsHeapMask = 0x1;
4902 private static readonly byte GUIDHeapMask = 0x2;
4903 private static readonly byte BlobHeapMask = 0x4;
4904 private static readonly uint MetaDataSignature = 0x424A5342;
4905 private static readonly uint maxSmlIxSize = 0xFFFF;
4906 private static readonly uint max1BitSmlIx = 0x7FFF;
4907 private static readonly uint max2BitSmlIx = 0x3FFF;
4908 private static readonly uint max3BitSmlIx = 0x1FFF;
4909 private static readonly uint max5BitSmlIx = 0x7FF;
4910 // NOTE: version and stream name strings MUST always be quad padded
4911 #if NET_2_0 || BOOTSTRAP_NET_2_0
4912 private static readonly string version = "v2.0.50727\0\0";
4914 private static readonly string version = "v1.1.4322\0\0\0";
4916 private static readonly char[] tildeName = {'#','~','\0','\0'};
4917 private static readonly char[] stringsName = {'#','S','t','r','i','n','g','s','\0','\0','\0','\0'};
4918 private static readonly char[] usName = {'#','U','S','\0'};
4919 private static readonly char[] guidName = {'#','G','U','I','D','\0','\0','\0'};
4920 private static readonly char[] blobName = {'#','B','l','o','b','\0','\0','\0'};
4921 private static readonly uint MetaDataHeaderSize = 20 + (uint)version.Length;
4922 private static readonly uint TildeHeaderSize = 24;
4923 private static readonly uint StreamHeaderSize = 8;
4924 private static readonly uint numMetaDataTables = (int)MDTable.GenericParamConstraint + 1;
4925 private static readonly uint tildeHeaderSize = 8 + (uint)tildeName.Length;
4927 MetaDataStream strings, us, guid, blob;
4929 MetaDataStream[] streams = new MetaDataStream[5];
4930 uint numStreams = 5;
4931 uint tildeTide = 0, tildePadding = 0, tildeStart = 0;
4932 uint numTables = 0, resourcesSize = 0;
4933 ArrayList[] metaDataTables = new ArrayList[numMetaDataTables];
4934 ArrayList byteCodes = new ArrayList();
4935 uint codeSize = 0, codeStart, byteCodePadding = 0, metaDataSize = 0;
4936 ulong valid = 0, /*sorted = 0x000002003301FA00;*/ sorted = 0;
4937 bool[] largeIx = new bool[numMetaDataTables];
4938 bool[] lgeCIx = new bool[(int)CIx.MaxCIx];
4939 bool largeStrings = false, largeUS = false, largeGUID = false, largeBlob = false;
4940 private FileImage file;
4941 private byte heapSizes = 0;
4942 MetaDataElement entryPoint;
4943 BinaryWriter output;
4944 public MSCorLib mscorlib;
4945 private TypeSpec[] systemTypeSpecs = new TypeSpec[PrimitiveType.NumSystemTypes];
4947 private ArrayList cattr_list;
4948 private ArrayList declsec_list;
4949 ArrayList resources;
4951 internal MetaData(FileImage file)
4953 // tilde = new MetaDataStream(tildeName,false,0);
4955 strings = new MetaDataStream(stringsName,new UTF8Encoding(),true);
4956 us = new MetaDataStream(usName,new UnicodeEncoding(),true);
4957 guid = new MetaDataStream(guidName,false);
4958 blob = new MetaDataStream(blobName,true);
4959 streams[1] = strings;
4963 for (int i=0; i < numMetaDataTables; i++) {
4966 for (int i=0; i < lgeCIx.Length; i++) {
4969 mscorlib = new MSCorLib(this);
4972 internal TypeSpec GetPrimitiveTypeSpec(int ix)
4974 return systemTypeSpecs[ix];
4977 internal void SetPrimitiveTypeSpec(int ix, TypeSpec typeSpec)
4979 systemTypeSpecs[ix] = typeSpec;
4982 internal uint Size()
4984 return metaDataSize;
4987 private void CalcHeapSizes ()
4989 if (strings.LargeIx()) {
4990 largeStrings = true;
4991 heapSizes |= StringsHeapMask;
4993 if (guid.LargeIx()) {
4995 heapSizes |= GUIDHeapMask;
4997 if (blob.LargeIx()) {
4999 heapSizes |= BlobHeapMask;
5002 largeUS = us.LargeIx();
5005 internal void StreamSize(byte mask)
5010 internal uint AddToUSHeap(string str)
5012 if (str == null) return 0;
5013 return us.Add(str,true);
5016 internal uint AddToUSHeap(byte[] str)
5018 if (str == null) return 0;
5019 return us.Add (str, true);
5022 internal uint AddToStringsHeap(string str)
5024 if ((str == null) || (str.CompareTo("") == 0)) return 0;
5025 return strings.Add(str,false);
5028 internal uint AddToGUIDHeap(Guid guidNum)
5030 return guid.Add(guidNum, false);
5033 internal uint AddToBlobHeap(byte[] blobBytes)
5035 if (blobBytes == null) return 0;
5036 return blob.Add(blobBytes, true);
5039 internal uint AddToBlobHeap(byte val)
5041 return blob.Add(val, true);
5044 internal uint AddToBlobHeap(sbyte val)
5046 return blob.Add(val, true);
5049 internal uint AddToBlobHeap(ushort val)
5051 return blob.Add(val, true);
5054 internal uint AddToBlobHeap(short val)
5056 return blob.Add(val, true);
5059 internal uint AddToBlobHeap(uint val)
5061 return blob.Add(val, true);
5064 internal uint AddToBlobHeap(int val)
5066 return blob.Add(val, true);
5069 internal uint AddToBlobHeap(ulong val)
5071 return blob.Add(val, true);
5074 internal uint AddToBlobHeap(long val)
5076 return blob.Add(val, true);
5079 internal uint AddToBlobHeap(float val)
5081 return blob.Add(val, true);
5084 internal uint AddToBlobHeap(double val)
5086 return blob.Add(val, true);
5089 internal uint AddToBlobHeap(string val)
5091 return blob.Add(val,true);
5094 internal void AddCustomAttribute (CustomAttribute cattr)
5096 if (cattr_list == null)
5097 cattr_list = new ArrayList ();
5098 cattr_list.Add (cattr);
5101 internal void AddDeclSecurity (BaseDeclSecurity decl_sec)
5103 if (declsec_list == null)
5104 declsec_list = new ArrayList ();
5105 declsec_list.Add (decl_sec);
5108 private ArrayList GetTable(MDTable tableIx)
5110 int tabIx = (int)tableIx;
5111 if (metaDataTables[tabIx] == null) {
5112 metaDataTables[tabIx] = new ArrayList();
5113 valid |= ((ulong)0x1 << tabIx);
5114 // Console.WriteLine("after creating table " + tableIx + "(" + tabIx + ") valid = " + valid);
5117 return metaDataTables[tabIx];
5120 internal void AddToTable(MDTable tableIx, MetaDataElement elem)
5123 // Console.Out.WriteLine("ERROR - element already in table " + tableIx);
5126 // updates Row field of the element
5127 // Console.WriteLine("Adding element to table " + (uint)tableIx);
5128 ArrayList table = GetTable(tableIx);
5129 elem.Row = (uint)table.Count + 1;
5133 internal uint TableIndex(MDTable tableIx)
5135 if (metaDataTables[(int)tableIx] == null) return 1;
5136 return (uint)metaDataTables[(int)tableIx].Count+1;
5139 internal uint AddCode(CILInstructions byteCode)
5141 byteCodes.Add(byteCode);
5142 uint offset = codeSize + codeStart;
5143 codeSize += byteCode.GetCodeSize();
5147 internal void SetEntryPoint(MetaDataElement ep)
5152 internal uint AddResource(byte[] resBytes)
5154 if (resources == null) resources = new ArrayList ();
5155 resources.Add (resBytes);
5156 uint offset = resourcesSize;
5157 resourcesSize += (uint)resBytes.Length + 4;
5161 internal void AddData(DataConstant cVal)
5163 file.AddInitData(cVal);
5166 internal static void CompressNum(uint val, MemoryStream sig)
5169 sig.WriteByte((byte)val);
5170 } else if (val <= 0x3FFF) {
5171 byte b1 = (byte)((val >> 8) | 0x80);
5172 byte b2 = (byte)(val & FileImage.iByteMask[0]);
5176 byte b1 = (byte)((val >> 24) | 0xC0);
5177 byte b2 = (byte)((val & FileImage.iByteMask[2]) >> 16);
5178 byte b3 = (byte)((val & FileImage.iByteMask[1]) >> 8);;
5179 byte b4 = (byte)(val & FileImage.iByteMask[0]);
5187 internal uint CodeSize()
5189 return codeSize + byteCodePadding;
5192 internal uint GetResourcesSize()
5194 return resourcesSize;
5197 internal uint StringsIndexSize()
5199 if (largeStrings) return 4;
5203 internal uint GUIDIndexSize()
5205 if (largeGUID) return 4;
5209 internal uint USIndexSize()
5211 if (largeUS) return 4;
5215 internal uint BlobIndexSize()
5217 if (largeBlob) return 4;
5221 internal uint CodedIndexSize(CIx code)
5223 if (lgeCIx[(uint)code]) return 4;
5227 internal uint TableIndexSize(MDTable tabIx)
5229 if (largeIx[(uint)tabIx]) return 4;
5233 private void SetIndexSizes()
5235 for (int i=0; i < numMetaDataTables; i++) {
5236 if (metaDataTables[i] == null)
5239 uint count = (uint)metaDataTables[i].Count;
5240 if (count > maxSmlIxSize)
5243 MDTable tabIx = (MDTable)i;
5244 if (count > max5BitSmlIx) {
5245 lgeCIx[(int)CIx.HasCustomAttr] = true;
5247 if (count > max3BitSmlIx) {
5248 if ((tabIx == MDTable.TypeRef) || (tabIx == MDTable.ModuleRef) || (tabIx == MDTable.Method) || (tabIx == MDTable.TypeSpec) || (tabIx == MDTable.Field))
5249 lgeCIx[(int)CIx.CustomAttributeType] = true;
5250 if ((tabIx == MDTable.Method) || (tabIx == MDTable.MemberRef))
5251 lgeCIx[(int)CIx.MemberRefParent] = true;
5253 if (count > max2BitSmlIx) {
5254 if ((tabIx == MDTable.Field) || (tabIx == MDTable.Param) || (tabIx == MDTable.Property))
5255 lgeCIx[(int)CIx.HasConst] = true;
5256 if ((tabIx == MDTable.TypeDef) || (tabIx == MDTable.TypeRef) || (tabIx == MDTable.TypeSpec))
5257 lgeCIx[(int)CIx.TypeDefOrRef] = true;
5258 if ((tabIx == MDTable.TypeDef) || (tabIx == MDTable.Method) || (tabIx == MDTable.Assembly))
5259 lgeCIx[(int)CIx.HasDeclSecurity] = true;
5260 if ((tabIx == MDTable.File) || (tabIx == MDTable.AssemblyRef) || (tabIx == MDTable.ExportedType))
5261 lgeCIx[(int)CIx.Implementation] = true;
5262 if ((tabIx == MDTable.Module) || (tabIx == MDTable.ModuleRef) || (tabIx == MDTable.AssemblyRef) || (tabIx == MDTable.TypeRef))
5263 lgeCIx[(int)CIx.ResolutionScope] = true;
5265 if (count > max1BitSmlIx) {
5266 if ((tabIx == MDTable.Field) || (tabIx == MDTable.Param))
5267 lgeCIx[(int)CIx.HasFieldMarshal] = true;
5268 if ((tabIx == MDTable.Event) || (tabIx == MDTable.Property))
5269 lgeCIx[(int)CIx.HasSemantics] = true;
5270 if ((tabIx == MDTable.Method) || (tabIx == MDTable.MemberRef))
5271 lgeCIx[(int)CIx.MethodDefOrRef] = true;
5272 if ((tabIx == MDTable.Field) || (tabIx == MDTable.Method))
5273 lgeCIx[(int)CIx.MemberForwarded] = true;
5274 if ((tabIx == MDTable.TypeDef) || (tabIx == MDTable.Method))
5275 lgeCIx[(int)CIx.TypeOrMethodDef] = true;
5280 private void SetStreamOffsets()
5282 uint sizeOfHeaders = StreamHeaderSize + (uint)tildeName.Length;
5283 for (int i=1; i < numStreams; i++) {
5284 sizeOfHeaders += streams[i].headerSize();
5286 metaDataSize = MetaDataHeaderSize + sizeOfHeaders;
5287 tildeStart = metaDataSize;
5288 metaDataSize += tildeTide + tildePadding;
5289 for (int i=1; i < numStreams; i++) {
5290 streams[i].Start = metaDataSize;
5291 metaDataSize += streams[i].Size();
5292 streams[i].WriteDetails();
5296 internal void CalcTildeStreamSize()
5299 //tilde.SetIndexSizes(strings.LargeIx(),us.LargeIx(),guid.LargeIx(),blob.LargeIx());
5300 tildeTide = TildeHeaderSize;
5301 tildeTide += 4 * numTables;
5302 //Console.WriteLine("Tilde header + sizes = " + tildeTide);
5303 for (int i=0; i < numMetaDataTables; i++) {
5304 if (metaDataTables[i] != null) {
5305 ArrayList table = metaDataTables[i];
5306 // Console.WriteLine("Meta data table " + i + " at offset " + tildeTide);
5307 tildeTide += (uint)table.Count * ((MetaDataElement)table[0]).Size(this);
5308 // Console.WriteLine("Metadata table " + i + " has size " + table.Count);
5309 // Console.WriteLine("tildeTide = " + tildeTide);
5312 if ((tildeTide % 4) != 0) tildePadding = 4 - (tildeTide % 4);
5313 //Console.WriteLine("tildePadding = " + tildePadding);
5316 internal void WriteTildeStream(FileImage output)
5318 long startTilde = output.Seek(0,SeekOrigin.Current);
5319 output.Write((uint)0); // Reserved
5320 #if NET_2_0 || BOOTSTRAP_NET_2_0
5321 output.Write((byte)2); // MajorVersion
5322 output.Write((byte)0); // MinorVersion
5324 output.Write((byte)1); // MajorVersion
5325 output.Write((byte)0); // MinorVersion
5327 output.Write(heapSizes);
5328 output.Write((byte)1); // Reserved
5329 output.Write(valid);
5330 output.Write(sorted);
5331 for (int i=0; i < numMetaDataTables; i++) {
5332 if (metaDataTables[i] != null) {
5333 uint count = (uint)metaDataTables[i].Count;
5334 output.Write(count);
5337 long tabStart = output.Seek(0,SeekOrigin.Current);
5338 // Console.WriteLine("Starting metaData tables at " + tabStart);
5339 for (int i=0; i < numMetaDataTables; i++) {
5340 if (metaDataTables[i] != null) {
5341 // Console.WriteLine("Starting metaData table " + i + " at " + (output.Seek(0,SeekOrigin.Current) - startTilde));
5342 ArrayList table = metaDataTables[i];
5343 for (int j=0; j < table.Count; j++) {
5344 ((MetaDataElement)table[j]).Write(output);
5348 // Console.WriteLine("Writing padding at " + output.Seek(0,SeekOrigin.Current));
5349 for (int i=0; i < tildePadding; i++) output.Write((byte)0);
5352 private void BuildTable(ArrayList table)
5354 if (table == null) return;
5355 for (int j=0; j < table.Count; j++) {
5356 ((MetaDataElement)table[j]).BuildTables(this);
5360 private void SortTable (ArrayList mTable)
5362 if (mTable == null) return;
5364 for (int i=0; i < mTable.Count; i++) {
5365 ((MetaDataElement)mTable[i]).Row = (uint)i+1;
5369 internal void BuildMetaData(uint codeStartOffset)
5371 codeStart = codeStartOffset;
5372 BuildTable(metaDataTables[(int)MDTable.TypeDef]);
5373 BuildTable(metaDataTables[(int)MDTable.TypeSpec]);
5374 BuildTable(metaDataTables[(int)MDTable.MemberRef]);
5375 #if NET_2_0 || BOOTSTRAP_NET_2_0
5376 BuildTable(metaDataTables[(int)MDTable.GenericParam]);
5377 BuildTable(metaDataTables[(int)MDTable.MethodSpec]);
5378 BuildTable(metaDataTables[(int)MDTable.GenericParamConstraint]);
5380 BuildTable(metaDataTables[(int)MDTable.ManifestResource]);
5382 if (cattr_list != null) {
5383 foreach (CustomAttribute cattr in cattr_list)
5384 cattr.BuildTables (this);
5387 if (declsec_list != null) {
5388 foreach (BaseDeclSecurity decl_sec in declsec_list)
5389 decl_sec.BuildTables (this);
5392 /* for (int i=0; i < metaDataTables.Length; i++) {
5393 ArrayList table = metaDataTables[i];
5394 if (table != null) {
5395 for (int j=0; j < table.Count; j++) {
5396 ((MetaDataElement)table[j]).BuildTables(this);
5403 for (int i=1; i < numStreams; i++) {
5404 streams[i].EndStream();
5406 CalcTildeStreamSize();
5408 byteCodePadding = NumToAlign(codeSize,4);
5409 if (entryPoint != null) file.SetEntryPoint(entryPoint.Token());
5411 // Check ordering of specific tables
5412 // Constant, CustomAttribute, FieldMarshal, DeclSecurity, MethodSemantics
5413 // ImplMap, GenericParam
5414 // Need to load GenericParamConstraint AFTER GenericParam table in correct order
5416 // InterfaceImpl, ClassLayout, FieldLayout, MethodImpl, FieldRVA, NestedClass
5417 // will _ALWAYS_ be in the correct order as embedded in BuildMDTables
5419 SortTable(metaDataTables[(int)MDTable.Constant]);
5420 SortTable(metaDataTables[(int)MDTable.FieldMarshal]);
5421 SortTable(metaDataTables[(int)MDTable.DeclSecurity]);
5422 SortTable(metaDataTables[(int)MDTable.MethodSemantics]);
5423 SortTable(metaDataTables[(int)MDTable.ImplMap]);
5424 #if NET_2_0 || BOOTSTRAP_NET_2_0
5425 if (metaDataTables[(int)MDTable.GenericParam] != null) {
5426 SortTable(metaDataTables[(int)MDTable.GenericParam]);
5427 // Now add GenericParamConstraints
5428 /*for (int i=0; i < metaDataTables[(int)MDTable.GenericParam].Count; i++) {
5429 ((GenericParameter)metaDataTables[(int)MDTable.GenericParam][i]).AddConstraints(this);
5432 SortTable(metaDataTables[(int)MDTable.GenericParamConstraint]);
5434 SortTable(metaDataTables[(int)MDTable.InterfaceImpl]);
5435 SortTable(metaDataTables[(int)MDTable.CustomAttribute]);
5439 internal void WriteByteCodes(FileImage output)
5441 for (int i=0; i < byteCodes.Count; i++) {
5442 ((CILInstructions)byteCodes[i]).Write(output);
5444 for (int i=0; i < byteCodePadding; i++) {
5445 output.Write((byte)0);
5449 internal void WriteResources (FileImage output)
5451 if (resources == null) return;
5452 for (int i = 0; i < resources.Count; i ++) {
5453 byte [] resBytes = (byte []) resources [i];
5454 output.Write ((uint) resBytes.Length);
5455 output.Write (resBytes);
5459 internal void WriteMetaData(FileImage output)
5461 this.output = output;
5462 mdStart = output.Seek(0,SeekOrigin.Current);
5463 // Console.WriteLine("Writing metaData at " + Hex.Long(mdStart));
5464 output.Write(MetaDataSignature);
5465 output.Write((short)1); // Major Version
5466 output.Write((short)1); // Minor Version ECMA = 0, PEFiles = 1
5467 output.Write(0); // Reserved
5468 output.Write(version.Length);
5469 output.Write(version.ToCharArray()); // version string is already zero padded
5470 output.Write((short)0);
5471 output.Write((ushort)numStreams);
5472 // write tilde header
5473 output.Write(tildeStart);
5474 output.Write(tildeTide + tildePadding);
5475 output.Write(tildeName);
5476 for (int i=1; i < numStreams; i++) streams[i].WriteHeader(output);
5477 // Console.WriteLine("Writing tilde stream at " + output.Seek(0,SeekOrigin.Current) + " = " + tildeStart);
5478 WriteTildeStream(output);
5479 for (int i=1; i < numStreams; i++) streams[i].Write(output);
5480 // Console.WriteLine("Finished Writing metaData at " + output.Seek(0,SeekOrigin.Current));
5483 internal bool LargeStringsIndex() { return strings.LargeIx(); }
5484 internal bool LargeGUIDIndex() { return guid.LargeIx(); }
5485 internal bool LargeUSIndex() { return us.LargeIx(); }
5486 internal bool LargeBlobIndex() { return blob.LargeIx(); }
5488 internal bool LargeIx(MDTable tabIx) { return largeIx[(uint)tabIx]; }
5491 private uint NumToAlign(uint val, uint alignVal)
5493 if ((val % alignVal) == 0) return 0;
5494 return alignVal - (val % alignVal);
5497 internal void WriteCodedIndex(CIx code, MetaDataElement elem, FileImage output)
5501 ix = (elem.Row << CIxShiftMap[(uint)code]) | elem.GetCodedIx(code);
5502 // Console.WriteLine("coded index = " + ix + " row = " + elem.Row);
5504 // Console.WriteLine("elem for coded index is null");
5506 if (lgeCIx[(uint)code])
5509 output.Write((ushort)ix);
5514 /**************************************************************************/
5516 /// Stream in the Meta Data (#Strings, #US, #Blob and #GUID)
5519 internal class MetaDataStream : BinaryWriter {
5521 private static readonly uint StreamHeaderSize = 8;
5522 private static uint maxSmlIxSize = 0xFFFF;
5524 private uint start = 0;
5525 uint size = 0, tide = 1;
5526 bool largeIx = false;
5529 Hashtable htable = new Hashtable();
5530 Hashtable btable = new Hashtable (new ByteArrayHashCodeProvider (), new ByteArrayComparer ());
5532 internal MetaDataStream(char[] name, bool addInitByte) : base(new MemoryStream())
5534 if (addInitByte) { Write((byte)0); size = 1; }
5536 sizeOfHeader = StreamHeaderSize + (uint)name.Length;
5539 internal MetaDataStream(char[] name, System.Text.Encoding enc, bool addInitByte) : base(new MemoryStream(),enc)
5541 if (addInitByte) { Write((byte)0); size = 1; }
5543 sizeOfHeader = StreamHeaderSize + (uint)name.Length;
5547 get { return start; }
5548 set { start = value; }
5551 internal uint headerSize()
5553 // Console.WriteLine(name + " stream has headersize of " + sizeOfHeader);
5554 return sizeOfHeader;
5557 internal void SetSize(uint siz)
5562 internal uint Size()
5567 internal bool LargeIx()
5572 internal void WriteDetails()
5574 // Console.WriteLine(name + " - size = " + size);
5577 internal uint Add(string str, bool prependSize)
5579 Object val = htable[str];
5583 htable[str] = index;
5584 char[] arr = str.ToCharArray();
5585 if (prependSize) CompressNum((uint)arr.Length*2+1);
5588 size = (uint)Seek(0,SeekOrigin.Current);
5594 internal uint Add (byte[] str, bool prependSize)
5596 Object val = btable [str];
5600 btable [str] = index;
5601 if (prependSize) CompressNum ((uint) str.Length);
5603 size = (uint) Seek (0, SeekOrigin.Current);
5611 internal uint Add(Guid guid, bool prependSize)
5613 byte [] b = guid.ToByteArray ();
5614 if (prependSize) CompressNum ((uint) b.Length);
5615 Write(guid.ToByteArray());
5616 size =(uint)Seek(0,SeekOrigin.Current);
5620 internal uint Add(byte[] blob)
5623 CompressNum((uint)blob.Length);
5625 size = (uint)Seek(0,SeekOrigin.Current);
5629 internal uint Add(byte val, bool prependSize)
5632 if (prependSize) CompressNum (1);
5634 size = (uint)Seek(0,SeekOrigin.Current);
5638 internal uint Add(sbyte val, bool prependSize)
5641 if (prependSize) CompressNum (1);
5643 size = (uint)Seek(0,SeekOrigin.Current);
5647 internal uint Add(ushort val, bool prependSize)
5650 if (prependSize) CompressNum (2);
5652 size = (uint)Seek(0,SeekOrigin.Current);
5656 internal uint Add(short val, bool prependSize)
5659 if (prependSize) CompressNum (2);
5661 size = (uint)Seek(0,SeekOrigin.Current);
5665 internal uint Add(uint val, bool prependSize)
5668 if (prependSize) CompressNum (4);
5670 size = (uint)Seek(0,SeekOrigin.Current);
5674 internal uint Add(int val, bool prependSize)
5677 if (prependSize) CompressNum (4);
5679 size = (uint)Seek(0,SeekOrigin.Current);
5683 internal uint Add(ulong val, bool prependSize)
5686 if (prependSize) CompressNum (8);
5688 size = (uint)Seek(0,SeekOrigin.Current);
5692 internal uint Add(long val, bool prependSize)
5695 if (prependSize) CompressNum (8);
5697 size = (uint)Seek(0,SeekOrigin.Current);
5701 internal uint Add(float val, bool prependSize)
5704 if (prependSize) CompressNum (4);
5706 size = (uint)Seek(0,SeekOrigin.Current);
5710 internal uint Add(double val, bool prependSize)
5713 if (prependSize) CompressNum (8);
5715 size = (uint)Seek(0,SeekOrigin.Current);
5719 private void CompressNum(uint val)
5723 } else if (val < 0x3FFF) {
5724 byte b1 = (byte)((val >> 8) | 0x80);
5725 byte b2 = (byte)(val & FileImage.iByteMask[0]);
5729 byte b1 = (byte)((val >> 24) | 0xC0);
5730 byte b2 = (byte)((val & FileImage.iByteMask[2]) >> 16);
5731 byte b3 = (byte)((val & FileImage.iByteMask[1]) >> 8);;
5732 byte b4 = (byte)(val & FileImage.iByteMask[0]);
5740 private void QuadAlign()
5742 if ((size % 4) != 0) {
5743 uint pad = 4 - (size % 4);
5745 for (int i=0; i < pad; i++) {
5751 internal void EndStream()
5754 if (size > maxSmlIxSize) {
5759 internal void WriteHeader(BinaryWriter output)
5761 output.Write(start);
5766 internal virtual void Write(BinaryWriter output)
5768 // Console.WriteLine("Writing " + name + " stream at " + output.Seek(0,SeekOrigin.Current) + " = " + start);
5769 MemoryStream str = (MemoryStream)BaseStream;
5770 output.Write(str.ToArray());
5775 /**************************************************************************/
5776 class ByteArrayComparer : IComparer {
5778 public int Compare (object x, object y)
5780 byte [] a = (byte []) x;
5781 byte [] b = (byte []) y;
5784 if (b.Length != len)
5787 for (int i = 0; i < len; ++i)
5794 class ByteArrayHashCodeProvider : IHashCodeProvider {
5796 public int GetHashCode (Object key)
5798 byte [] arr = (byte []) key;
5799 int len = arr.Length;
5802 for (int i = 0; i < len; ++i)
5803 h = (h << 5) - h + arr [i];